diff --git a/CHANGELOG b/CHANGELOG index ff386c9c3a..6e26105c2a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,443 @@ +commit 638dd1458bbdc2a55d4b9e25c5c4e1f838a5dc72 +Author: Sergei Poselenov +Date: Tue Feb 27 12:40:16 2007 +0300 + + MCC200 update - add LCD Progress Indicator + +commit 6c7cac8c4fce0ea2bf8e15ed8658d87974155b44 +Author: Stefan Roese +Date: Thu Feb 22 07:43:34 2007 +0100 + + [PATCH] get_dev() now unconditionally uses manual relocation + + Since the relocation fix is not included yet and we're not sure how + it will be added, this patch removes code that required relocation + to be fixed for now. + + Signed-off-by: Stefan Roese + +commit 8274ec0bd01d2feb2c7f095eba78d42ea009798b +Author: Stefan Roese +Date: Thu Feb 22 07:40:23 2007 +0100 + + [PATCH] Change systemace driver to select 8 & 16bit mode + + As suggested by Grant Likely this patch enables the Xilinx SystemACE + driver to select 8 or 16bit mode upon startup. + + Signed-off-by: Stefan Roese + +commit 3a197b2fe49d6fa03978e60af2394efe9c70b527 +Author: Haiying Wang +Date: Wed Feb 21 16:52:31 2007 +0100 + + [PATCH v3] Add sync to ensure flash_write_cmd is fully finished + + Some CPUs like PPC, BLACKFIN need sync() to ensure cfi flash write command + is fully finished. The sync() is defined in each CPU's io.h file. For + those CPUs which do not need sync for now, a dummy sync() is defined in + their io.h as well. + + Signed-off-by: Haiying Wang + +commit da04995c7dc6772013a9a0dc5c767f190c402478 +Author: Stefan Roese +Date: Wed Feb 21 13:44:34 2007 +0100 + + [PATCH] Fix problem in systemace driver (ace_writew instead of ace_write) + + Signed-off-by: Stefan Roese + +commit 751bb57107d78978ae08e697c3deba816f5be091 +Author: Stefan Roese +Date: Tue Feb 20 13:21:57 2007 +0100 + + [PATCH] Fix relocation problem with "new" get_dev() function + + This patch enables the "new" get_dev() function for block devices + introduced by Grant Likely to be used on systems that still suffer + from the relocation problems (manual relocation neede because of + problems with linker script). + + Hopefully we can resolve this relocation issue soon for all platform + so we don't need this additional code anymore. + + Signed-off-by: Stefan Roese + +commit d93e2212f962668b3dce091ff5edc33f2347fe37 +Author: Stefan Roese +Date: Tue Feb 20 13:17:42 2007 +0100 + + [PATCH] Update SystemACE driver for 16bit access + + This patch removes some problems when the Xilinx SystemACE driver + is used with 16bit access on an big endian platform (like the + AMCC Katmai). + + Signed-off-by: Stefan Roese + +commit 874bb7b88fe9b4648e1288a387af2e31014a72f3 +Author: Stefan Roese +Date: Tue Feb 20 13:15:40 2007 +0100 + + [PATCH] Clean up Katmai (440SPe) linker script + + Signed-off-by: Stefan Roese + +commit 4745acaa1a603b67f6b9b7970365ebadd7d6586f +Author: Stefan Roese +Date: Tue Feb 20 10:57:08 2007 +0100 + + [PATCH] Add support for the AMCC Katmai (440SPe) eval board + + Signed-off-by: Stefan Roese + +commit 0dc018ece13effc689e47479ea9ebf1c98a507f5 +Author: Stefan Roese +Date: Tue Feb 20 10:51:26 2007 +0100 + + [PATCH] I2C: Add support for multiple I2C busses for RTC & DTT + + This patch switches to the desired I2C bus when the date/dtt + commands are called. This can be configured using the + CFG_RTC_BUS_NUM and/or CFG_DTT_BUS_NUM defines. + + Signed-off-by: Stefan Roese + +commit 4037ed3b63923cfcec27f784a89057c3cbabcedb +Author: Stefan Roese +Date: Tue Feb 20 10:43:34 2007 +0100 + + [PATCH] PPC4xx: Add 440SP(e) DDR2 SPD DIMM support + + This patch adds support for the DDR2 controller used on the + 440SP and 440SPe. It is tested on the Katmai (440SPe) eval + board and works fine with the following DIMM modules: + + - Corsair CM2X512-5400C4 (512MByte per DIMM) + - Kingston ValueRAM KVR667D2N5/512 (512MByte per DIMM) + - Kingston ValueRAM KVR667D2N5K2/2G (1GByte per DIMM) + + This patch also adds the nice functionality to dynamically + create the TLB entries for the SDRAM (tlb.c). So we should + never run into such problems with wrong (too short) TLB + initialization again on these platforms. + + Signed-off-by: Stefan Roese + +commit 36d830c9830379045f5daa9f542ac1c990c70068 +Author: Stefan Roese +Date: Tue Feb 20 10:35:42 2007 +0100 + + [PATCH] PPC4xx: Split 4xx SPD SDRAM init routines into 2 files + + Since the existing 4xx SPD SDRAM initialization routines for the + 405 SDRAM controller and the 440 DDR controller don't have much in + common this patch splits both drivers into different files. + + This is in preparation for the 440 DDR2 controller support (440SP/e). + + Signed-off-by: Stefan Roese + +commit 79b2d0bb2eae09602448f7a7cb56530d2f31e6c6 +Author: Stefan Roese +Date: Tue Feb 20 10:27:08 2007 +0100 + + [PATCH] PPC4xx: Add support for multiple I2C busses + + This patch adds support for multiple I2C busses on the PPC4xx + platforms. Define CONFIG_I2C_MULTI_BUS in the board config file + to make use of this feature. + + It also merges the 405 and 440 i2c header files into one common + file 4xx_i2c.h. + + Also the 4xx i2c reset procedure is reworked since I experienced + some problems with the first access on the 440SPe Katmai board. + + Signed-off-by: Stefan Roese + +commit eb867a76238fb38e952c37871b16d0d7fd61c95f +Author: Grant Likely +Date: Tue Feb 20 09:05:45 2007 +0100 + + [PATCH 9_9] Use "void *" not "unsigned long *" for block dev read_write buffer pointers + + Block device read/write is anonymous data; there is no need to use a + typed pointer. void * is fine. Also add a hook for block_read functions + + Signed-off-by: Grant Likely + +commit 53758fa20e935cc87eeb0519ed365df753a6f289 +Author: Grant Likely +Date: Tue Feb 20 09:05:38 2007 +0100 + + [PATCH 8_9] Add block_write hook to block_dev_desc_t + + Preparation for future patches which support block device writing + + Signed-off-by: Grant Likely + +commit f4852ebe6ca946a509667eb68be42026f837be76 +Author: Grant Likely +Date: Tue Feb 20 09:05:31 2007 +0100 + + [PATCH 7_9] Replace ace_readw_ace_writeb functions with macros + + Register read/write does not need to be wrapped in a full function. The + patch replaces them with macros. + + Signed-off-by: Grant Likely + +commit 3a8ce9af6fcb5744a7851b4440c07688acc40844 +Author: Grant Likely +Date: Tue Feb 20 09:05:23 2007 +0100 + + [PATCH 6_9] Move common_cmd_ace.c to drivers_systemace.c + + The code in this file is not a command; it is a device driver. Put it in + the correct place. There are zero functional changes in this patch, it + only moves the file. + + Signed-off-by: Grant Likely + +commit 984618f3e7794c783ec8d1511e74c6ee2d69bfe4 +Author: Grant Likely +Date: Tue Feb 20 09:05:16 2007 +0100 + + [PATCH 5_9] Whitespace fixup on common_cmd_ace.c (using Lindent) + + This patch is in preparation of additional changes to the sysace driver. + May as well take this opportunity to fixup the inconsistent whitespace since + this file is about to undergo major changes anyway. + + There are zero functional changes in this patch. It only cleans up the + the whitespace. + + Signed-off-by: Grant Likely + +commit 80ba981d940471fe7e539e64fa3d2bd80002beda +Author: Grant Likely +Date: Tue Feb 20 09:05:07 2007 +0100 + + [PATCH 4_4] Remove local implementation of isprint() in ft_build.c + + isprint is already defined in ctype.c + + Signed-off-by: Grant Likely + +commit c95c4280d751ca078c2ff58228d2f2b44ccf0600 +Author: Grant Likely +Date: Tue Feb 20 09:05:00 2007 +0100 + + [PATCH 3_9] Move buffer print code from md command to common function + + Printing a buffer is a darn useful thing. Move the buffer print code + into print_buffer() in lib_generic/ + + Signed-off-by: Grant Likely + +commit 99b0f0fd3fbf2572ae1a7723dd90cffc8e85130a +Author: Grant Likely +Date: Tue Feb 20 09:04:52 2007 +0100 + + [PATCH 2_4] Use config.h, not xparameters.h, for xilinx targets + + Change the xilinx device drivers and board code to include config.h + instead of xparameters.h directly. config.h always includes the + correct xparameters file. This change reduces the posibility of + including the wrong file when adding a new xilinx board port + + Signed-off-by: Grant Likely + +commit 735dd97b1b20e777d059c7b389fe9d70cd3f80c7 +Author: Grant Likely +Date: Tue Feb 20 09:04:34 2007 +0100 + + [PATCH 1_4] Merge common get_dev() routines for block devices + + Each of the filesystem drivers duplicate the get_dev routine. This change + merges them into a single function in part.c + + Signed-off-by: Grant Likely + +commit f5fcc3c20b65554e98a165542c36ee0c610a2d81 +Author: Wolfgang Denk +Date: Mon Feb 19 23:09:51 2007 +0100 + + MCC200: Software Updater: allow both "ramdisk" and "filesystem" types + as root file system images. + +commit 489c696ae7211218961d159e43e722d74c36fcbc +Author: Sergei Poselenov +Date: Wed Feb 14 14:30:28 2007 +0300 + + MCC200: Extensions to Software Update Mechanism + + Update / extend Software Update Mechanism for MCC200 board: + + - Add support for rootfs image added. The environment variables + "rootfs_st" and "rootfs_nd" can be used to override the default + values of the image start and end. + - Remove excessive key check code. + - Code cleanup. + +commit 4be23a12f23f1372634edc3215137b09768b7949 +Author: Stefan Roese +Date: Mon Feb 19 08:23:15 2007 +0100 + + [PATCH] Update Sequoia EBC configuration (NOR FLASH) + + As spotted by Matthias Fuchs, the READY input should not be + enabled for the NOR FLASH on the Sequoia board. + + Signed-off-by: Stefan Roese + +commit 497d012e5be0194e1084073d0081eb1a844796b2 +Author: Gary Jennejohn +Date: Mon Feb 12 13:11:50 2007 +0100 + + LPC2292: patch from Siemens. + +commit b0b1a920aebead0d44146e73676ae9d80fffc8e2 +Author: Stefan Roese +Date: Sat Feb 10 08:49:31 2007 +0100 + + [PATCH] Add missing p3mx.h file to repository (ups) + + Signed-off-by: Stefan Roese + +commit 53d4a4983fb9b3ae5f7b2f10c599aca2b1b4034a +Author: Bartlomiej Sieka +Date: Fri Feb 9 10:45:42 2007 +0100 + + [Motion-PRO] Preliminary support for the Motion-PRO board. + +commit 5a753f98c6a01bd1c61a9a3f95e8329a35f62994 +Author: Stefan Roese +Date: Wed Feb 7 16:51:08 2007 +0100 + + [PATCH] Update some AMCC 4xx board config files (set initrd_high) + + Some boards that can have more than 768MBytes of SDRAM need to + set "initrd_high", so that the initrd can be accessed by the + Linux kernel. + + Signed-off-by: Stefan Roese + +commit 7372ca68227930d03cffa548310524cad5b96733 +Author: Stefan Roese +Date: Fri Feb 2 12:44:22 2007 +0100 + + [PATCH] Correctly display PCI arbiter en-/disabled on some 4xx boards + + Previously the strapping DCR/SDR was read to determine if the internal PCI + arbiter is enabled or not. This strapping bit can be overridden, so now + the current status is read from the correct DCR/SDR register. + + Signed-off-by: Stefan Roese + +commit 2aa54f651a42d198673318f07a20c89a43e4d197 +Author: Stefan Roese +Date: Fri Feb 2 12:42:08 2007 +0100 + + [PATCH] Change configuration output of Sycamore, Yellowstone & Rainier + + Signed-off-by: Stefan Roese + +commit 23744d6b5bf17592eb6a0ef4f318f6089f55993b +Author: Stefan Roese +Date: Thu Feb 1 13:22:41 2007 +0100 + + [PATCH] Remove PCI-PNP configuration from Sequoia/Rainier config file + + When PCI PNP is enabled the pci pnp configuration routine is called + which sets the PCI_CACHE_SIZE_LINE to 8. This seems to generate some + problems with some PCI cards. For now disable the PCI PNP configuration. + + Signed-off-by: Stefan Roese + +commit 2902fadade3be7659467e8d074048c6b7068f5c0 +Author: Stefan Roese +Date: Wed Jan 31 16:56:10 2007 +0100 + + [PATCH] Update 440EPx/440GRx cpu detection + + Signed-off-by: Stefan Roese + +commit d5ea287b02a6945c3977410e364a879dd1a555c8 +Author: Stefan Roese +Date: Wed Jan 31 16:38:04 2007 +0100 + + [PATCH] Update esd cpci5200 files + + Signed-off-by: Reinhard Arlt + +commit 8b7d1f0ab7d7c4fe3160bbf74a7e9690d9f3a3ab +Author: Stefan Roese +Date: Wed Jan 31 16:37:34 2007 +0100 + + [PATCH] Add support for esd mecp5200 board + + Signed-off-by: Reinhard Arlt + +commit 71a4e5fda8b60044ab9f46069fa1cfa26bdd07ff +Author: Stefan Roese +Date: Wed Jan 31 12:38:50 2007 +0100 + + [PATCH] Remove unneccessary yellowstone board config file + + Signed-off-by: Stefan Roese + +commit e802594b6fa1b166308820c276b96dc0d7cc731c +Author: Stefan Roese +Date: Tue Jan 30 17:06:10 2007 +0100 + + [PATCH] Update Sequoia (440EPx) config file + + The config file now handles the 2nd target, the Rainier (440GRx) + evaluation board better. Additionally the PPC input clock was + adjusted to match the correct value of 33.0 MHz. + + Signed-off-by: Stefan Roese + +commit 700200c67e73b83751418abe7815840dca8fd6cb +Author: Stefan Roese +Date: Tue Jan 30 17:04:19 2007 +0100 + + [PATCH] Merge Yosemite & Yellowstone board ports + + Now the AMCC eval boards Yosemite (440EP) and Yellowstone (440GR) + share one config file and all board specific files. This way we + don't have to maintain two different sets of files for nearly + identical boards. + + Signed-off-by: Stefan Roese + +commit 1bbf5eae322f5f1f6427ecc3ac13a0cb7dba8ad6 +Author: Stefan Roese +Date: Tue Jan 30 15:01:49 2007 +0100 + + [PATCH] Update Prodrive SCPU (PDNB3 variant) board + + SCPU doesn't use redundant environment in flash. + + Signed-off-by: Stefan Roese + +commit 6304430ed642ea8fa15c9e5af965ac2e033eec45 +Author: Stefan Roese +Date: Tue Jan 30 12:51:07 2007 +0100 + + [PATCH] alpr: Update alpr board config file + + Signed-off-by: Stefan Roese + +commit f8db84f132b1e335f20f96138a1f09ed97b08664 +Author: Wolfgang Denk +Date: Tue Jan 30 00:50:40 2007 +0100 + + LPC2292 SODIMM port coding style cleanup. + commit 6bd2447ee47ee23c18d2b3c7ccd5a20f7626f5b3 Author: Gary Jennejohn Date: Wed Jan 24 12:16:56 2007 +0100 diff --git a/MAINTAINERS b/MAINTAINERS index f90c5a65ff..1d0a8dfdb3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -288,6 +288,7 @@ Stefan Roese bamboo PPC440EP bunbinga PPC405EP ebony PPC440GP + katmai PPC440SPe ocotea PPC440GX p3p440 PPC440GP pcs440ep PPC440EP diff --git a/MAKEALL b/MAKEALL index b83f642939..8431b3ea53 100755 --- a/MAKEALL +++ b/MAKEALL @@ -82,15 +82,15 @@ LIST_4xx=" \ CRAYL1 csb272 csb472 DASA_SIM \ DP405 DU405 ebony ERIC \ EXBITGEN G2000 HH405 HUB405 \ - JSE KAREF luan METROBOX \ - MIP405 MIP405T ML2 ml300 \ - ocotea OCRTC ORSG p3p440 \ - PCI405 pcs440ep PIP405 PLU405 \ - PMC405 PPChameleonEVB sbc405 sc3 \ - sequoia sequoia_nand taishan VOH405 \ - VOM405 W7OLMC W7OLMG walnut \ - WUH405 XPEDITE1K yellowstone yosemite \ - yucca \ + JSE KAREF katmai luan \ + METROBOX MIP405 MIP405T ML2 \ + ml300 ocotea OCRTC ORSG \ + p3p440 PCI405 pcs440ep PIP405 \ + PLU405 PMC405 PPChameleonEVB sbc405 \ + sc3 sequoia sequoia_nand taishan \ + VOH405 VOM405 W7OLMC W7OLMG \ + walnut WUH405 XPEDITE1K yellowstone \ + yosemite yucca \ " ######################################################################### diff --git a/Makefile b/Makefile index 0aeaf2df67..358d1817c9 100644 --- a/Makefile +++ b/Makefile @@ -1095,6 +1095,9 @@ JSE_config: unconfig KAREF_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx karef sandburst +katmai_config: unconfig + @$(MKCONFIG) $(@:_config=) ppc ppc4xx katmai amcc + luan_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx luan amcc diff --git a/README b/README index ecfd1f82f0..15428643ed 100644 --- a/README +++ b/README @@ -1347,6 +1347,16 @@ The following options need to be configured: If defined, then this indicates the I2C bus number for DDR SPD. If not defined, then U-Boot assumes that SPD is on I2C bus 0. + CFG_RTC_BUS_NUM + + If defined, then this indicates the I2C bus number for the RTC. + If not defined, then U-Boot assumes that RTC is on I2C bus 0. + + CFG_DTT_BUS_NUM + + If defined, then this indicates the I2C bus number for the DTT. + If not defined, then U-Boot assumes that DTT is on I2C bus 0. + CONFIG_FSL_I2C Define this option if you want to use Freescale's I2C driver in diff --git a/board/amcc/katmai/Makefile b/board/amcc/katmai/Makefile new file mode 100644 index 0000000000..d06a402d17 --- /dev/null +++ b/board/amcc/katmai/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2007 +# 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 cmd_katmai.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 $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend *~ + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/amcc/katmai/cmd_katmai.c b/board/amcc/katmai/cmd_katmai.c new file mode 100644 index 0000000000..684f6a5863 --- /dev/null +++ b/board/amcc/katmai/cmd_katmai.c @@ -0,0 +1,267 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@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 +#include +#include +#include + +static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + uchar chip; + ulong data; + int nbytes; + extern char console_buffer[]; + + char sysClock[4]; + char cpuClock[4]; + char plbClock[4]; + char pcixClock[4]; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (strcmp(argv[2], "prom0") == 0) + chip = IIC0_BOOTPROM_ADDR; + else + chip = IIC0_ALT_BOOTPROM_ADDR; + + do { + printf("enter sys clock frequency 33 or 66 Mhz or quit to abort\n"); + nbytes = readline (" ? "); + + if (strcmp(console_buffer, "quit") == 0) + return 0; + + if ((strcmp(console_buffer, "33") != 0) & + (strcmp(console_buffer, "66") != 0)) + nbytes=0; + + strcpy(sysClock, console_buffer); + + } while (nbytes == 0); + + do { + if (strcmp(sysClock, "66") == 0) { + printf("enter cpu clock frequency 400, 533 Mhz or quit to abort\n"); + } else { +#ifdef CONFIG_STRESS + printf("enter cpu clock frequency 400, 500, 533, 667 Mhz or quit to abort\n"); +#else + printf("enter cpu clock frequency 400, 500, 533 Mhz or quit to abort\n"); +#endif + } + nbytes = readline (" ? "); + + if (strcmp(console_buffer, "quit") == 0) + return 0; + + if (strcmp(sysClock, "66") == 0) { + if ((strcmp(console_buffer, "400") != 0) & + (strcmp(console_buffer, "533") != 0) +#ifdef CONFIG_STRESS + & (strcmp(console_buffer, "667") != 0) +#endif + ) { + nbytes = 0; + } + } else { + if ((strcmp(console_buffer, "400") != 0) & + (strcmp(console_buffer, "500") != 0) & + (strcmp(console_buffer, "533") != 0) +#ifdef CONFIG_STRESS + & (strcmp(console_buffer, "667") != 0) +#endif + ) { + nbytes = 0; + } + } + + strcpy(cpuClock, console_buffer); + + } while (nbytes == 0); + + if (strcmp(cpuClock, "500") == 0) + strcpy(plbClock, "166"); + else if (strcmp(cpuClock, "533") == 0) + strcpy(plbClock, "133"); + else { + do { + if (strcmp(cpuClock, "400") == 0) + printf("enter plb clock frequency 100, 133 Mhz or quit to abort\n"); + +#ifdef CONFIG_STRESS + if (strcmp(cpuClock, "667") == 0) + printf("enter plb clock frequency 133, 166 Mhz or quit to abort\n"); + +#endif + nbytes = readline (" ? "); + + if (strcmp(console_buffer, "quit") == 0) + return 0; + + if (strcmp(cpuClock, "400") == 0) { + if ((strcmp(console_buffer, "100") != 0) & + (strcmp(console_buffer, "133") != 0)) + nbytes = 0; + } +#ifdef CONFIG_STRESS + if (strcmp(cpuClock, "667") == 0) { + if ((strcmp(console_buffer, "133") != 0) & + (strcmp(console_buffer, "166") != 0)) + nbytes = 0; + } +#endif + strcpy(plbClock, console_buffer); + + } while (nbytes == 0); + } + + do { + printf("enter Pci-X clock frequency 33, 66, 100 or 133 Mhz or quit to abort\n"); + nbytes = readline (" ? "); + + if (strcmp(console_buffer, "quit") == 0) + return 0; + + if ((strcmp(console_buffer, "33") != 0) & + (strcmp(console_buffer, "66") != 0) & + (strcmp(console_buffer, "100") != 0) & + (strcmp(console_buffer, "133") != 0)) { + nbytes = 0; + } + strcpy(pcixClock, console_buffer); + + } while (nbytes == 0); + + printf("\nsys clk = %sMhz\n", sysClock); + printf("cpu clk = %sMhz\n", cpuClock); + printf("plb clk = %sMhz\n", plbClock); + printf("Pci-X clk = %sMhz\n", pcixClock); + + do { + printf("\npress [y] to write I2C bootstrap \n"); + printf("or [n] to abort. \n"); + printf("Don't forget to set board switches \n"); + printf("according to your choice before re-starting \n"); + printf("(refer to 440spe_uboot_kit_um_1_01.pdf) \n"); + + nbytes = readline (" ? "); + if (strcmp(console_buffer, "n") == 0) + return 0; + + } while (nbytes == 0); + + if (strcmp(sysClock, "33") == 0) { + if ((strcmp(cpuClock, "400") == 0) & + (strcmp(plbClock, "100") == 0)) + data = 0x8678c206; + + if ((strcmp(cpuClock, "400") == 0) & + (strcmp(plbClock, "133") == 0)) + data = 0x8678c2c6; + + if ((strcmp(cpuClock, "500") == 0)) + data = 0x8778f2c6; + + if ((strcmp(cpuClock, "533") == 0)) + data = 0x87790252; + +#ifdef CONFIG_STRESS + if ((strcmp(cpuClock, "667") == 0) & + (strcmp(plbClock, "133") == 0)) + data = 0x87794256; + + if ((strcmp(cpuClock, "667") == 0) & + (strcmp(plbClock, "166") == 0)) + data = 0x87794206; + +#endif + } + if (strcmp(sysClock, "66") == 0) { + if ((strcmp(cpuClock, "400") == 0) & + (strcmp(plbClock, "100") == 0)) + data = 0x84706206; + + if ((strcmp(cpuClock, "400") == 0) & + (strcmp(plbClock, "133") == 0)) + data = 0x847062c6; + + if ((strcmp(cpuClock, "533") == 0)) + data = 0x85708206; + +#ifdef CONFIG_STRESS + if ((strcmp(cpuClock, "667") == 0) & + (strcmp(plbClock, "133") == 0)) + data = 0x8570a256; + + if ((strcmp(cpuClock, "667") == 0) & + (strcmp(plbClock, "166") == 0)) + data = 0x8570a206; + +#endif + } + +#ifdef DEBUG + printf(" pin strap0 to write in i2c = %x\n", data); +#endif /* DEBUG */ + + if (i2c_write(chip, 0, 1, (uchar *)&data, 4) != 0) + printf("Error writing strap0 in %s\n", argv[2]); + + if (strcmp(pcixClock, "33") == 0) + data = 0x00000701; + + if (strcmp(pcixClock, "66") == 0) + data = 0x00000601; + + if (strcmp(pcixClock, "100") == 0) + data = 0x00000501; + + if (strcmp(pcixClock, "133") == 0) + data = 0x00000401; + + if (strcmp(plbClock, "166") == 0) + data |= 0x05950000; + else + data |= 0x05A50000; + +#ifdef DEBUG + printf(" pin strap1 to write in i2c = %x\n", data); +#endif /* DEBUG */ + + udelay(1000); + if (i2c_write(chip, 4, 1, (uchar *)&data, 4) != 0) + printf("Error writing strap1 in %s\n", argv[2]); + + return 0; +} + +U_BOOT_CMD( + bootstrap, 3, 1, do_bootstrap, + "bootstrap - program the serial device strap\n", + "wrclk [prom0|prom1] - program the serial device strap\n" + ); diff --git a/board/amcc/katmai/config.mk b/board/amcc/katmai/config.mk new file mode 100644 index 0000000000..115c1aed05 --- /dev/null +++ b/board/amcc/katmai/config.mk @@ -0,0 +1,38 @@ +# +# (C) Copyright 2006 +# 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 +# + +# +# AMCC 440SPe Evaluation (Katmai) board +# + +TEXT_BASE = 0xfffc0000 + +PLATFORM_CPPFLAGS += -DCONFIG_440=1 + +ifeq ($(debug),1) +PLATFORM_CPPFLAGS += -DDEBUG +endif + +ifeq ($(dbcr),1) +PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000 +endif diff --git a/board/amcc/katmai/init.S b/board/amcc/katmai/init.S new file mode 100644 index 0000000000..f5900bcb7b --- /dev/null +++ b/board/amcc/katmai/init.S @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * Copyright (C) 2002 Scott McNutt + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/************************************************************************** + * TLB TABLE + * + * This table is used by the cpu boot code to setup the initial tlb + * entries. Rather than make broad assumptions in the cpu source tree, + * this table lets each board set things up however they like. + * + * Pointer to the table is returned in r1 + * + *************************************************************************/ + + .section .bootpg,"ax" + +/************************************************************************** + * TLB table for revA + *************************************************************************/ + .globl tlbtabA +tlbtabA: + tlbtab_start + tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G) + + /* + * TLB entries for SDRAM are not needed on this platform. + * They are dynamically generated in the SPD DDR(2) detection + * routine. + */ + + tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I) + tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbtab_end + +/************************************************************************** + * TLB table for revB + * + * Notice: revB of the 440SPe chip is very strict about PLB real addresses + * and ranges to be mapped for config space: it seems to only work with + * d_nnnn_nnnn range (hangs the core upon config transaction attempts when + * set otherwise) while revA uses c_nnnn_nnnn. + *************************************************************************/ + .globl tlbtabB +tlbtabB: + tlbtab_start + tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G) + + /* + * TLB entries for SDRAM are not needed on this platform. + * They are dynamically generated in the SPD DDR(2) detection + * routine. + */ + + tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I) + + tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_ACE_BASE, SZ_1K, 0xE0000000, 4,AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I) + + tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I) + tlbtab_end diff --git a/board/amcc/katmai/katmai.c b/board/amcc/katmai/katmai.c new file mode 100644 index 0000000000..8704925a9c --- /dev/null +++ b/board/amcc/katmai/katmai.c @@ -0,0 +1,514 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@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 +#include +#include +#include +#include + +#include "katmai.h" +#include "../cpu/ppc4xx/440spe_pcie.h" + +#undef PCIE_ENDPOINT +/* #define PCIE_ENDPOINT 1 */ + +int ppc440spe_init_pcie_rootport(int port); +void ppc440spe_setup_pcie(struct pci_controller *hose, int port); + +int board_early_init_f (void) +{ + unsigned long mfr; + unsigned long pfc; + + /*----------------------------------------------------------------------+ + * Interrupt controller setup for the Katmai 440SPe Evaluation board. + *-----------------------------------------------------------------------+ + *-----------------------------------------------------------------------+ + * Interrupt | Source | Pol. | Sensi.| Crit. | + *-----------+-----------------------------------+-------+-------+-------+ + * IRQ 00 | UART0 | High | Level | Non | + * IRQ 01 | UART1 | High | Level | Non | + * IRQ 02 | IIC0 | High | Level | Non | + * IRQ 03 | IIC1 | High | Level | Non | + * IRQ 04 | PCI0X0 MSG IN | High | Level | Non | + * IRQ 05 | PCI0X0 CMD Write | High | Level | Non | + * IRQ 06 | PCI0X0 Power Mgt | High | Level | Non | + * IRQ 07 | PCI0X0 VPD Access | Rising| Edge | Non | + * IRQ 08 | PCI0X0 MSI level 0 | High | Lvl/ed| Non | + * IRQ 09 | External IRQ 15 - (PCI-Express) | pgm H | Pgm | Non | + * IRQ 10 | UIC2 Non-critical Int. | NA | NA | Non | + * IRQ 11 | UIC2 Critical Interrupt | NA | NA | Crit | + * IRQ 12 | PCI Express MSI Level 0 | Rising| Edge | Non | + * IRQ 13 | PCI Express MSI Level 1 | Rising| Edge | Non | + * IRQ 14 | PCI Express MSI Level 2 | Rising| Edge | Non | + * IRQ 15 | PCI Express MSI Level 3 | Rising| Edge | Non | + * IRQ 16 | UIC3 Non-critical Int. | NA | NA | Non | + * IRQ 17 | UIC3 Critical Interrupt | NA | NA | Crit | + * IRQ 18 | External IRQ 14 - (PCI-Express) | Pgm | Pgm | Non | + * IRQ 19 | DMA Channel 0 FIFO Full | High | Level | Non | + * IRQ 20 | DMA Channel 0 Stat FIFO | High | Level | Non | + * IRQ 21 | DMA Channel 1 FIFO Full | High | Level | Non | + * IRQ 22 | DMA Channel 1 Stat FIFO | High | Level | Non | + * IRQ 23 | I2O Inbound Doorbell | High | Level | Non | + * IRQ 24 | Inbound Post List FIFO Not Empt | High | Level | Non | + * IRQ 25 | I2O Region 0 LL PLB Write | High | Level | Non | + * IRQ 26 | I2O Region 1 LL PLB Write | High | Level | Non | + * IRQ 27 | I2O Region 0 HB PLB Write | High | Level | Non | + * IRQ 28 | I2O Region 1 HB PLB Write | High | Level | Non | + * IRQ 29 | GPT Down Count Timer | Rising| Edge | Non | + * IRQ 30 | UIC1 Non-critical Int. | NA | NA | Non | + * IRQ 31 | UIC1 Critical Interrupt | NA | NA | Crit. | + *------------------------------------------------------------------------ + * IRQ 32 | Ext. IRQ 13 - (PCI-Express) |pgm (H)|pgm/Lvl| Non | + * IRQ 33 | MAL Serr | High | Level | Non | + * IRQ 34 | MAL Txde | High | Level | Non | + * IRQ 35 | MAL Rxde | High | Level | Non | + * IRQ 36 | DMC CE or DMC UE | High | Level | Non | + * IRQ 37 | EBC or UART2 | High |Lvl Edg| Non | + * IRQ 38 | MAL TX EOB | High | Level | Non | + * IRQ 39 | MAL RX EOB | High | Level | Non | + * IRQ 40 | PCIX0 MSI Level 1 | High |Lvl Edg| Non | + * IRQ 41 | PCIX0 MSI level 2 | High |Lvl Edg| Non | + * IRQ 42 | PCIX0 MSI level 3 | High |Lvl Edg| Non | + * IRQ 43 | L2 Cache | Risin | Edge | Non | + * IRQ 44 | GPT Compare Timer 0 | Risin | Edge | Non | + * IRQ 45 | GPT Compare Timer 1 | Risin | Edge | Non | + * IRQ 46 | GPT Compare Timer 2 | Risin | Edge | Non | + * IRQ 47 | GPT Compare Timer 3 | Risin | Edge | Non | + * IRQ 48 | GPT Compare Timer 4 | Risin | Edge | Non | + * IRQ 49 | Ext. IRQ 12 - PCI-X |pgm/Fal|pgm/Lvl| Non | + * IRQ 50 | Ext. IRQ 11 - |pgm (H)|pgm/Lvl| Non | + * IRQ 51 | Ext. IRQ 10 - |pgm (H)|pgm/Lvl| Non | + * IRQ 52 | Ext. IRQ 9 |pgm (H)|pgm/Lvl| Non | + * IRQ 53 | Ext. IRQ 8 |pgm (H)|pgm/Lvl| Non | + * IRQ 54 | DMA Error | High | Level | Non | + * IRQ 55 | DMA I2O Error | High | Level | Non | + * IRQ 56 | Serial ROM | High | Level | Non | + * IRQ 57 | PCIX0 Error | High | Edge | Non | + * IRQ 58 | Ext. IRQ 7- |pgm (H)|pgm/Lvl| Non | + * IRQ 59 | Ext. IRQ 6- |pgm (H)|pgm/Lvl| Non | + * IRQ 60 | EMAC0 Interrupt | High | Level | Non | + * IRQ 61 | EMAC0 Wake-up | High | Level | Non | + * IRQ 62 | Reserved | High | Level | Non | + * IRQ 63 | XOR | High | Level | Non | + *----------------------------------------------------------------------- + * IRQ 64 | PE0 AL | High | Level | Non | + * IRQ 65 | PE0 VPD Access | Risin | Edge | Non | + * IRQ 66 | PE0 Hot Reset Request | Risin | Edge | Non | + * IRQ 67 | PE0 Hot Reset Request | Falli | Edge | Non | + * IRQ 68 | PE0 TCR | High | Level | Non | + * IRQ 69 | PE0 BusMaster VCO | Falli | Edge | Non | + * IRQ 70 | PE0 DCR Error | High | Level | Non | + * IRQ 71 | Reserved | N/A | N/A | Non | + * IRQ 72 | PE1 AL | High | Level | Non | + * IRQ 73 | PE1 VPD Access | Risin | Edge | Non | + * IRQ 74 | PE1 Hot Reset Request | Risin | Edge | Non | + * IRQ 75 | PE1 Hot Reset Request | Falli | Edge | Non | + * IRQ 76 | PE1 TCR | High | Level | Non | + * IRQ 77 | PE1 BusMaster VCO | Falli | Edge | Non | + * IRQ 78 | PE1 DCR Error | High | Level | Non | + * IRQ 79 | Reserved | N/A | N/A | Non | + * IRQ 80 | PE2 AL | High | Level | Non | + * IRQ 81 | PE2 VPD Access | Risin | Edge | Non | + * IRQ 82 | PE2 Hot Reset Request | Risin | Edge | Non | + * IRQ 83 | PE2 Hot Reset Request | Falli | Edge | Non | + * IRQ 84 | PE2 TCR | High | Level | Non | + * IRQ 85 | PE2 BusMaster VCO | Falli | Edge | Non | + * IRQ 86 | PE2 DCR Error | High | Level | Non | + * IRQ 87 | Reserved | N/A | N/A | Non | + * IRQ 88 | External IRQ(5) | Progr | Progr | Non | + * IRQ 89 | External IRQ 4 - Ethernet | Progr | Progr | Non | + * IRQ 90 | External IRQ 3 - PCI-X | Progr | Progr | Non | + * IRQ 91 | External IRQ 2 - PCI-X | Progr | Progr | Non | + * IRQ 92 | External IRQ 1 - PCI-X | Progr | Progr | Non | + * IRQ 93 | External IRQ 0 - PCI-X | Progr | Progr | Non | + * IRQ 94 | Reserved | N/A | N/A | Non | + * IRQ 95 | Reserved | N/A | N/A | Non | + *----------------------------------------------------------------------- + * IRQ 96 | PE0 INTA | High | Level | Non | + * IRQ 97 | PE0 INTB | High | Level | Non | + * IRQ 98 | PE0 INTC | High | Level | Non | + * IRQ 99 | PE0 INTD | High | Level | Non | + * IRQ 100 | PE1 INTA | High | Level | Non | + * IRQ 101 | PE1 INTB | High | Level | Non | + * IRQ 102 | PE1 INTC | High | Level | Non | + * IRQ 103 | PE1 INTD | High | Level | Non | + * IRQ 104 | PE2 INTA | High | Level | Non | + * IRQ 105 | PE2 INTB | High | Level | Non | + * IRQ 106 | PE2 INTC | High | Level | Non | + * IRQ 107 | PE2 INTD | Risin | Edge | Non | + * IRQ 108 | PCI Express MSI Level 4 | Risin | Edge | Non | + * IRQ 109 | PCI Express MSI Level 5 | Risin | Edge | Non | + * IRQ 110 | PCI Express MSI Level 6 | Risin | Edge | Non | + * IRQ 111 | PCI Express MSI Level 7 | Risin | Edge | Non | + * IRQ 116 | PCI Express MSI Level 12 | Risin | Edge | Non | + * IRQ 112 | PCI Express MSI Level 8 | Risin | Edge | Non | + * IRQ 113 | PCI Express MSI Level 9 | Risin | Edge | Non | + * IRQ 114 | PCI Express MSI Level 10 | Risin | Edge | Non | + * IRQ 115 | PCI Express MSI Level 11 | Risin | Edge | Non | + * IRQ 117 | PCI Express MSI Level 13 | Risin | Edge | Non | + * IRQ 118 | PCI Express MSI Level 14 | Risin | Edge | Non | + * IRQ 119 | PCI Express MSI Level 15 | Risin | Edge | Non | + * IRQ 120 | PCI Express MSI Level 16 | Risin | Edge | Non | + * IRQ 121 | PCI Express MSI Level 17 | Risin | Edge | Non | + * IRQ 122 | PCI Express MSI Level 18 | Risin | Edge | Non | + * IRQ 123 | PCI Express MSI Level 19 | Risin | Edge | Non | + * IRQ 124 | PCI Express MSI Level 20 | Risin | Edge | Non | + * IRQ 125 | PCI Express MSI Level 21 | Risin | Edge | Non | + * IRQ 126 | PCI Express MSI Level 22 | Risin | Edge | Non | + * IRQ 127 | PCI Express MSI Level 23 | Risin | Edge | Non | + *-----------+-----------------------------------+-------+-------+-------+ */ + /*-------------------------------------------------------------------------+ + * Put UICs in PowerPC440SPemode. + * Initialise UIC registers. Clear all interrupts. Disable all interrupts. + * Set critical interrupt values. Set interrupt polarities. Set interrupt + * trigger levels. Make bit 0 High priority. Clear all interrupts again. + *------------------------------------------------------------------------*/ + mtdcr (uic3sr, 0xffffffff); /* Clear all interrupts */ + mtdcr (uic3er, 0x00000000); /* disable all interrupts */ + mtdcr (uic3cr, 0x00000000); /* Set Critical / Non Critical interrupts: */ + mtdcr (uic3pr, 0xffffffff); /* Set Interrupt Polarities*/ + mtdcr (uic3tr, 0x001fffff); /* Set Interrupt Trigger Levels */ + mtdcr (uic3vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ + mtdcr (uic3sr, 0x00000000); /* clear all interrupts*/ + mtdcr (uic3sr, 0xffffffff); /* clear all interrupts*/ + + + mtdcr (uic2sr, 0xffffffff); /* Clear all interrupts */ + mtdcr (uic2er, 0x00000000); /* disable all interrupts*/ + mtdcr (uic2cr, 0x00000000); /* Set Critical / Non Critical interrupts*/ + mtdcr (uic2pr, 0xebebebff); /* Set Interrupt Polarities*/ + mtdcr (uic2tr, 0x74747400); /* Set Interrupt Trigger Levels */ + mtdcr (uic2vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ + mtdcr (uic2sr, 0x00000000); /* clear all interrupts */ + mtdcr (uic2sr, 0xffffffff); /* clear all interrupts */ + + mtdcr (uic1sr, 0xffffffff); /* Clear all interrupts*/ + mtdcr (uic1er, 0x00000000); /* disable all interrupts*/ + mtdcr (uic1cr, 0x00000000); /* Set Critical / Non Critical interrupts*/ + mtdcr (uic1pr, 0xffffffff); /* Set Interrupt Polarities */ + mtdcr (uic1tr, 0x001f8040); /* Set Interrupt Trigger Levels*/ + mtdcr (uic1vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ + mtdcr (uic1sr, 0x00000000); /* clear all interrupts*/ + mtdcr (uic1sr, 0xffffffff); /* clear all interrupts*/ + + mtdcr (uic0sr, 0xffffffff); /* Clear all interrupts */ + mtdcr (uic0er, 0x00000000); /* disable all interrupts excepted cascade to be checked */ + mtdcr (uic0cr, 0x00104001); /* Set Critical / Non Critical interrupts*/ + mtdcr (uic0pr, 0xffffffff); /* Set Interrupt Polarities*/ + mtdcr (uic0tr, 0x010f0004); /* Set Interrupt Trigger Levels */ + mtdcr (uic0vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ + mtdcr (uic0sr, 0x00000000); /* clear all interrupts*/ + mtdcr (uic0sr, 0xffffffff); /* clear all interrupts*/ + +/* SDR0_MFR should be part of Ethernet init */ + mfsdr (sdr_mfr, mfr); + mfr &= ~SDR0_MFR_ECS_MASK; +/* mtsdr(sdr_mfr, mfr); */ + + /* + * Setup GPIO signalling per defines in katmai.h + */ + pfc = PFC0_KATMAI; + mtsdr(SDR0_PFC0, pfc); + + out32(GPIO0_OR_ADDR, GPIO_OR_KATMAI); + out32(GPIO0_ODR_ADDR, GPIO_ODR_KATMAI); + out32(GPIO0_TCR_ADDR, GPIO_TCR_KATMAI); + + return 0; +} + +int checkboard (void) +{ + char *s = getenv("serial#"); + + printf("Board: Katmai - AMCC 440SPe Evaluation Board"); + if (s != NULL) { + puts(", serial# "); + puts(s); + } + putc('\n'); + + return 0; +} + +#if defined(CFG_DRAM_TEST) +int testdram (void) +{ + uint *pstart = (uint *) 0x00000000; + uint *pend = (uint *) 0x08000000; + uint *p; + + 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; + } + } + + 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; + } + } + return 0; +} +#endif + +/************************************************************************* + * pci_pre_init + * + * This routine is called just prior to registering the hose and gives + * the board the opportunity to check things. Returning a value of zero + * indicates that things are bad & PCI initialization should be aborted. + * + * Different boards may wish to customize the pci controller structure + * (add regions, override default access routines, etc) or perform + * certain pre-initialization actions. + * + ************************************************************************/ +#if defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) +int pci_pre_init(struct pci_controller * hose ) +{ + unsigned long strap; + + /*-------------------------------------------------------------------+ + * The katmai board is always configured as the host & requires the + * PCI arbiter to be enabled. + *-------------------------------------------------------------------*/ + mfsdr(sdr_sdstp1, strap); + if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ) { + printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap); + return 0; + } + + return 1; +} +#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */ + +/************************************************************************* + * pci_target_init + * + * The bootstrap configuration provides default settings for the pci + * inbound map (PIM). But the bootstrap config choices are limited and + * may not be sufficient for a given board. + * + ************************************************************************/ +#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) +void pci_target_init(struct pci_controller * hose ) +{ + DECLARE_GLOBAL_DATA_PTR; + + /*-------------------------------------------------------------------+ + * Disable everything + *-------------------------------------------------------------------*/ + out32r( PCIX0_PIM0SA, 0 ); /* disable */ + out32r( PCIX0_PIM1SA, 0 ); /* disable */ + out32r( PCIX0_PIM2SA, 0 ); /* disable */ + out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */ + + /*-------------------------------------------------------------------+ + * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 + * strapping options to not support sizes such as 128/256 MB. + *-------------------------------------------------------------------*/ + out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE ); + out32r( PCIX0_PIM0LAH, 0 ); + out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 ); + out32r( PCIX0_BAR0, 0 ); + + /*-------------------------------------------------------------------+ + * Program the board's subsystem id/vendor id + *-------------------------------------------------------------------*/ + out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID ); + out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID ); + + out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY ); +} +#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */ + +#if defined(CONFIG_PCI) +/************************************************************************* + * is_pci_host + * + * This routine is called to determine if a pci scan should be + * performed. With various hardware environments (especially cPCI and + * PPMC) it's insufficient to depend on the state of the arbiter enable + * bit in the strap register, or generic host/adapter assumptions. + * + * Rather than hard-code a bad assumption in the general 440 code, the + * 440 pci code requires the board to decide at runtime. + * + * Return 0 for adapter mode, non-zero for host (monarch) mode. + * + * + ************************************************************************/ +int is_pci_host(struct pci_controller *hose) +{ + /* The katmai board is always configured as host. */ + return 1; +} + +static struct pci_controller pcie_hose[3] = {{0},{0},{0}}; + +void pcie_setup_hoses(void) +{ + struct pci_controller *hose; + int i, bus; + + /* + * assume we're called after the PCIX hose is initialized, which takes + * bus ID 0 and therefore start numbering PCIe's from 1. + */ + bus = 1; + for (i = 0; i <= 2; i++) { +#ifdef PCIE_ENDPOINT + if (ppc440spe_init_pcie_endport(i)) { +#else + if (ppc440spe_init_pcie_rootport(i)) { +#endif + printf("PCIE%d: initialization failed\n", i); + continue; + } + + hose = &pcie_hose[i]; + hose->first_busno = bus; + hose->last_busno = bus; + bus++; + + /* setup mem resource */ + pci_set_region(hose->regions + 0, + CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE, + CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE, + CFG_PCIE_MEMSIZE, + PCI_REGION_MEM + ); + hose->region_count = 1; + pci_register_hose(hose); + +#ifdef PCIE_ENDPOINT + ppc440spe_setup_pcie_endpoint(hose, i); + /* + * Reson for no scanning is endpoint can not generate + * upstream configuration accesses. + */ +#else + ppc440spe_setup_pcie_rootpoint(hose, i); + /* + * Config access can only go down stream + */ + hose->last_busno = pci_hose_scan(hose); +#endif + } +} +#endif /* defined(CONFIG_PCI) */ + +int misc_init_f (void) +{ + uint reg; +#if defined(CONFIG_STRESS) + uint i ; + uint disp; +#endif + + /* minimal init for PCIe */ +#if 0 /* test-only: test endpoint at some time, for now rootpoint only */ + /* pci express 0 Endpoint Mode */ + mfsdr(SDR0_PE0DLPSET, reg); + reg &= (~0x00400000); + mtsdr(SDR0_PE0DLPSET, reg); +#else + /* pci express 0 Rootpoint Mode */ + mfsdr(SDR0_PE0DLPSET, reg); + reg |= 0x00400000; + mtsdr(SDR0_PE0DLPSET, reg); +#endif + /* pci express 1 Rootpoint Mode */ + mfsdr(SDR0_PE1DLPSET, reg); + reg |= 0x00400000; + mtsdr(SDR0_PE1DLPSET, reg); + /* pci express 2 Rootpoint Mode */ + mfsdr(SDR0_PE2DLPSET, reg); + reg |= 0x00400000; + mtsdr(SDR0_PE2DLPSET, reg); + +#if defined(CONFIG_STRESS) + /* + * All this setting done by linux only needed by stress an charac. test + * procedure + * PCIe 1 Rootpoint PCIe2 Endpoint + * PCIe 0 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level + */ + for (i=0,disp=0; i<8; i++,disp+=3) { + mfsdr(SDR0_PE0HSSSET1L0+disp, reg); + reg |= 0x33000000; + mtsdr(SDR0_PE0HSSSET1L0+disp, reg); + } + + /*PCIe 1 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */ + for (i=0,disp=0; i<4; i++,disp+=3) { + mfsdr(SDR0_PE1HSSSET1L0+disp, reg); + reg |= 0x33000000; + mtsdr(SDR0_PE1HSSSET1L0+disp, reg); + } + + /*PCIE 2 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */ + for (i=0,disp=0; i<4; i++,disp+=3) { + mfsdr(SDR0_PE2HSSSET1L0+disp, reg); + reg |= 0x33000000; + mtsdr(SDR0_PE2HSSSET1L0+disp, reg); + } + + reg = 0x21242222; + mtsdr(SDR0_PE2UTLSET1, reg); + reg = 0x11000000; + mtsdr(SDR0_PE2UTLSET2, reg); + /* pci express 1 Endpoint Mode */ + reg = 0x00004000; + mtsdr(SDR0_PE2DLPSET, reg); + + mtsdr(SDR0_UART1, 0x2080005a); /* patch for TG */ +#endif + + return 0; +} + +#ifdef CONFIG_POST +/* + * Returns 1 if keys pressed to start the power-on long-running tests + * Called from board_init_f(). + */ +int post_hotkeys_pressed(void) +{ + return (ctrlc()); +} +#endif diff --git a/board/amcc/katmai/katmai.h b/board/amcc/katmai/katmai.h new file mode 100644 index 0000000000..9d5b793f13 --- /dev/null +++ b/board/amcc/katmai/katmai.h @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@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 + */ + +#ifndef __KATMAI_H_ +#define __KATMAI_H_ + +/*---------------------------------------------------------------------------- + * XX + * XXXX XX XXX XXX XXXX + * XX XX XX XX XX XX + * XX XXX XX XX XX XX XX + * XX XX XXXXX XX XX XX + * XXXX XX XXXX XXXX + * XXXX + * + * The 440SPe provices 32 bits of GPIO. By default all GPIO pins + * are disabled, and must be explicitly enabled by setting a + * bit in the SDR0_PFC0 indirect DCR. Each GPIO maps 1-to-1 with the + * corresponding bit in the SDR0_PFC0 register (note that bit numbers + * reflect the PowerPC convention where bit 0 is the most-significant + * bit). + * + * Katmai specific: + * RS232_RX_EN# is held HIGH during reset by hardware, keeping the + * RS232_CTS, DSR & DCD signals coming from the MAX3411 (U26) in + * Hi-Z condition. This prevents contention between the MAX3411 (U26) + * and 74CBTLV3125PG (U2) during reset. + * + * RS232_RX_EN# is connected as GPIO pin 30. Once the processor + * is released from reset, this pin must be configured as an output and + * then driven high to enable the receive signals from the UART transciever. + *----------------------------------------------------------------------------*/ +#define GPIO_ENABLE(gpio) (0x80000000 >> (gpio)) + +#define PFC0_KATMAI GPIO_ENABLE(30) +#define GPIO_OR_KATMAI GPIO_ENABLE(30) /* Drive all outputs low except GPIO 30 */ +#define GPIO_TCR_KATMAI GPIO_ENABLE(30) +#define GPIO_ODR_KATMAI 0 /* Disable open drain for all outputs */ + +#define GPIO0_OR_ADDR (CFG_PERIPHERAL_BASE + 0x700) +#define GPIO0_TCR_ADDR (CFG_PERIPHERAL_BASE + 0x704) +#define GPIO0_ODR_ADDR (CFG_PERIPHERAL_BASE + 0x718) +#define GPIO0_IR_ADDR (CFG_PERIPHERAL_BASE + 0x71C) + +#endif /* __KATMAI_H_ */ diff --git a/board/amcc/katmai/u-boot.lds b/board/amcc/katmai/u-boot.lds new file mode 100644 index 0000000000..bf8fc5d3da --- /dev/null +++ b/board/amcc/katmai/u-boot.lds @@ -0,0 +1,141 @@ +/* + * (C) Copyright 2004 + * 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 + */ + +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 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + .bootpg 0xFFFFF000 : + { + cpu/ppc4xx/start.o (.bootpg) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .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/ppc4xx/start.o (.text) + board/amcc/katmai/init.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .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 = .); +} diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index a7114eb074..a0fac7fe5a 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -23,7 +23,7 @@ #include #include -#include <405gp_i2c.h> +#include <4xx_i2c.h> #include #include #include diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 5cd342332f..001fd68da4 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "auto_update.h" @@ -71,8 +72,6 @@ extern int transfer_pic(unsigned char, unsigned char *, int, int); extern int flash_sect_erase(ulong, ulong); extern int flash_sect_protect (int, ulong, ulong); extern int flash_write (char *, ulong, ulong); -/* change char* to void* to shutup the compiler */ -extern block_dev_desc_t *get_dev (char*, int); #if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY) /* references to names in cmd_nand.c */ diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c index 36bb7ce2c7..17e3568941 100644 --- a/board/esd/cpci750/cpci750.c +++ b/board/esd/cpci750/cpci750.c @@ -366,12 +366,12 @@ int misc_init_r () dcache_lock (); #endif if (flash_info[3].size < CFG_FLASH_INCREMENT) { - unsigned int flash_offset; + unsigned int flash_offset; unsigned int l; flash_offset = CFG_FLASH_INCREMENT - flash_info[3].size; for (l = 0; l < CFG_MAX_FLASH_SECT; l++) { - if (flash_info[3].start[l] != 0) { + if (flash_info[3].start[l] != 0) { flash_info[3].start[l] += flash_offset; } } @@ -503,7 +503,7 @@ static void move64 (unsigned long long *src, unsigned long long *dest) { asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */ "stfd 0, 0(4)" /* *dest = fpr0 */ - : : : "fr0"); /* Clobbers fr0 */ + : : : "fr0"); /* Clobbers fr0 */ return; } @@ -581,9 +581,9 @@ int mem_test_data (void) move64 (&(pattern[i]), pmem); move64 (pmem, &temp64); - /* hi = (temp64>>32) & 0xffffffff; */ - /* lo = temp64 & 0xffffffff; */ - /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */ + /* hi = (temp64>>32) & 0xffffffff; */ + /* lo = temp64 & 0xffffffff; */ + /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */ hi = (pattern[i] >> 32) & 0xffffffff; lo = pattern[i] & 0xffffffff; @@ -856,11 +856,11 @@ int testdram (void) } #endif /* CFG_DRAM_TEST */ -/* ronen - the below functions are used by the bootm function */ +/* ronen - the below functions are used by the bootm function */ /* - we map the base register to fbe00000 (same mapping as in the LSP) */ /* - we turn off the RX gig dmas - to prevent the dma from overunning */ -/* the kernel data areas. */ -/* - we diable and invalidate the icache and dcache. */ +/* the kernel data areas. */ +/* - we diable and invalidate the icache and dcache. */ void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc) { u32 temp; @@ -911,13 +911,11 @@ int do_show_cfg(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) GT_REG_READ(0x3d4, &reset_sample_high); printf("Reset configuration 0x%08x 0x%08x\n", reset_sample_low, reset_sample_high); - return(0); + return(0); } - U_BOOT_CMD( show_cfg, 1, 1, do_show_cfg, "show_cfg- Show Marvell strapping register\n", "Show Marvell strapping register (ResetSampleLow ResetSampleHigh)\n" ); - diff --git a/board/esd/du405/du405.c b/board/esd/du405/du405.c index a019ce4215..69432138d3 100644 --- a/board/esd/du405/du405.c +++ b/board/esd/du405/du405.c @@ -25,7 +25,7 @@ #include "du405.h" #include #include -#include <405gp_i2c.h> +#include <4xx_i2c.h> #include DECLARE_GLOBAL_DATA_PTR; diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index 12091fd782..faa01bd308 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CFG_HUSH_PARSER #include @@ -94,21 +95,23 @@ char *aufile[AU_MAXFILES] = { /* sizes of flash areas for each file */ long ausize[AU_MAXFILES] = { (AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST, - (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST, - (AU_FL_ROOTFS_ND + 1) - AU_FL_ROOTFS_ST + (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST, + (AU_FL_ROOTFS_ND + 1) - AU_FL_ROOTFS_ST, }; /* array of flash areas start and end addresses */ struct flash_layout aufl_layout[AU_MAXFILES] = { - {AU_FL_FIRMWARE_ST, AU_FL_FIRMWARE_ND,}, - {AU_FL_KERNEL_ST, AU_FL_KERNEL_ND,}, - {AU_FL_ROOTFS_ST, AU_FL_ROOTFS_ND,} + { AU_FL_FIRMWARE_ST, AU_FL_FIRMWARE_ND, }, + { AU_FL_KERNEL_ST, AU_FL_KERNEL_ND, }, + { AU_FL_ROOTFS_ST, AU_FL_ROOTFS_ND, }, }; +ulong totsize; + /* where to load files into memory */ #define LOAD_ADDR ((unsigned char *)0x00200000) -/* the app is the largest image */ +/* the root file system is the largest image */ #define MAX_LOADSZ ausize[IDX_ROOTFS] /*i2c address of the keypad status*/ @@ -128,9 +131,12 @@ extern int i2c_read (unsigned char, unsigned int, int , unsigned char* , int); extern int flash_sect_erase(ulong, ulong); extern int flash_sect_protect (int, ulong, ulong); extern int flash_write (char *, ulong, ulong); -/* change char* to void* to shutup the compiler */ -extern block_dev_desc_t *get_dev (char*, int); extern int u_boot_hush_start(void); +#ifdef CONFIG_PROGRESSBAR +extern void show_progress(int, int); +extern void lcd_puts (char *); +extern void lcd_enable(void); +#endif int au_check_cksum_valid(int idx, long nbytes) { @@ -169,10 +175,12 @@ int au_check_header_valid(int idx, long nbytes) #endif if (nbytes < sizeof(*hdr)) { printf ("Image %s bad header SIZE\n", aufile[idx]); + ausize[idx] = 0; return -1; } if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); + ausize[idx] = 0; return -1; } /* check the hdr CRC */ @@ -181,20 +189,26 @@ int au_check_header_valid(int idx, long nbytes) if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { printf ("Image %s bad header checksum\n", aufile[idx]); + ausize[idx] = 0; return -1; } hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); + ausize[idx] = 0; return -1; } if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); + ausize[idx] = 0; return -1; } - if ((idx == IDX_ROOTFS) && (hdr->ih_type != IH_TYPE_RAMDISK)) { + if ((idx == IDX_ROOTFS) && + ( (hdr->ih_type != IH_TYPE_RAMDISK) || (hdr->ih_type != IH_TYPE_FILESYSTEM) ) + ) { printf ("Image %s wrong type\n", aufile[idx]); + ausize[idx] = 0; return -1; } /* recycle checksum */ @@ -202,13 +216,17 @@ int au_check_header_valid(int idx, long nbytes) /* for kernel and app the image header must also fit into flash */ if (idx != IDX_FIRMWARE) checksum += sizeof(*hdr); + /* check the size does not exceed space in flash. HUSH scripts */ - /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { printf ("Image %s is bigger than FLASH\n", aufile[idx]); + ausize[idx] = 0; return -1; } - return 0; + /* Update with the real filesize */ + ausize[idx] = (idx == IDX_FIRMWARE ? checksum + sizeof(*hdr) : checksum); + + return checksum; /* return size to be written to flash */ } int au_do_update(int idx, long sz) @@ -253,6 +271,10 @@ int au_do_update(int idx, long sz) debug ("flash_sect_erase(%lx, %lx);\n", start, end); flash_sect_erase(start, end); wait_ms(100); +#ifdef CONFIG_PROGRESSBAR + show_progress(end - start, totsize); +#endif + /* strip the header - except for the kernel and ramdisk */ if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { addr = (char *)hdr; @@ -277,9 +299,13 @@ int au_do_update(int idx, long sz) return -1; } - /* check the dcrc of the copy */ +#ifdef CONFIG_PROGRESSBAR + show_progress(nbytes, totsize); +#endif + + /* check the data CRC of the copy */ if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { - printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]); + printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]); return -1; } @@ -299,7 +325,7 @@ int do_auto_update(void) { block_dev_desc_t *stor_dev; long sz; - int i, res, bitmap_first, cnt, old_ctrlc, got_ctrlc; + int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc; char *env; long start, end; uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0}; @@ -318,6 +344,7 @@ int do_auto_update(void) (keypad_status1[1] != keypad_status2[1])) { return 0; } + au_usb_stor_curr_dev = -1; /* start USB */ if (usb_stop() < 0) { @@ -402,23 +429,50 @@ int do_auto_update(void) old_ctrlc = disable_ctrlc(0); bitmap_first = 0; - /* just loop thru all the possible files */ + + /* validate the images first */ for (i = 0; i < AU_MAXFILES; i++) { + ulong imsize; /* just read the header */ sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, sizeof(image_header_t)); if (sz <= 0 || sz < sizeof(image_header_t)) { debug ("%s not found\n", aufile[i]); + ausize[i] = 0; continue; } - if (au_check_header_valid(i, sz) < 0) { + /* au_check_header_valid() updates ausize[] */ + if ((imsize = au_check_header_valid(i, sz)) < 0) { debug ("%s header not valid\n", aufile[i]); continue; } - sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ); + /* totsize accounts for image size and flash erase size */ + totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start)); + } + +#ifdef CONFIG_PROGRESSBAR + if (totsize) { + lcd_puts(" Update in progress\n"); + lcd_enable(); + } +#endif + + /* just loop thru all the possible files */ + for (i = 0; i < AU_MAXFILES && totsize; i++) { + if (!ausize[i]) { + continue; + } + sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]); + debug ("read %s sz %ld hdr %d\n", aufile[i], sz, sizeof(image_header_t)); + + if (sz != ausize[i]) { + printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz); + continue; + } + if (sz <= 0 || sz <= sizeof(image_header_t)) { debug ("%s not found\n", aufile[i]); continue; @@ -451,6 +505,16 @@ int do_auto_update(void) usb_stop(); /* restore the old state */ disable_ctrlc(old_ctrlc); +#ifdef CONFIG_PROGRESSBAR + if (totsize) { + if (!res) { + lcd_puts("\n Update completed\n"); + } else { + lcd_puts("\n Update error\n"); + } + lcd_enable(); + } +#endif return 0; } #endif /* CONFIG_AUTO_UPDATE */ diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c index b2625160a5..98b86d1834 100644 --- a/board/mcc200/lcd.c +++ b/board/mcc200/lcd.c @@ -24,13 +24,13 @@ #ifdef CONFIG_LCD -#define SWAPPED_LCD +#undef SWAPPED_LCD /* For the previous h/w version */ /* * The name of the device used for communication * with the PSoC. */ #define PSOC_PSC MPC5XXX_PSC2 -#define PSOC_BAUD 500000UL +#define PSOC_BAUD 230400UL #define RTS_ASSERT 1 #define RTS_NEGATE 0 @@ -181,10 +181,35 @@ void lcd_enable (void) udelay (PSOC_WAIT_TIME); } if (!retries) { - printf ("%s Error: PSoC doesn't respond on " + printf ("%s Warning: PSoC doesn't respond on " "RTS NEGATE\n", __FUNCTION__); } return; } +#ifdef CONFIG_PROGRESSBAR + +#define FONT_WIDTH 8 /* the same as VIDEO_FONT_WIDTH in video_font.h */ +void show_progress (int size, int tot) +{ + int cnt; + int i; + static int rc = 0; + + rc += size; + + cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot; + + rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH); + + for (i = 0; i < cnt; i++) { + lcd_putc(0xdc); + } + + if (cnt) { + lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */ + } +} + +#endif #endif /* CONFIG_LCD */ diff --git a/board/motionpro/motionpro.c b/board/motionpro/motionpro.c index 95576ed56b..d60d23332b 100644 --- a/board/motionpro/motionpro.c +++ b/board/motionpro/motionpro.c @@ -141,11 +141,12 @@ long int initdram (int board_type) dramsize = 0; /* set SDRAM CS0 size according to the amount of RAM found */ - if (dramsize > 0) + if (dramsize > 0) { *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1; - else + } else { *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ + } /* let SDRAM CS1 start right after CS0 and disable it */ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; diff --git a/board/mpl/common/memtst.c b/board/mpl/common/memtst.c index ff1190ab21..1d28513d87 100644 --- a/board/mpl/common/memtst.c +++ b/board/mpl/common/memtst.c @@ -48,7 +48,7 @@ int testdram (void) #include #include -#include <405gp_i2c.h> +#include <4xx_i2c.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c index 34f328999d..4b1c1c0669 100644 --- a/board/mpl/mip405/mip405.c +++ b/board/mpl/mip405/mip405.c @@ -65,7 +65,7 @@ #include #include "mip405.h" #include -#include <405gp_i2c.h> +#include <4xx_i2c.h> #include #include "../common/common_util.h" #include @@ -73,9 +73,6 @@ DECLARE_GLOBAL_DATA_PTR; -extern block_dev_desc_t * scsi_get_dev(int dev); -extern block_dev_desc_t * ide_get_dev(int dev); - #undef SDRAM_DEBUG #define ENABLE_ECC /* for ecc boards */ #define FALSE 0 diff --git a/board/prodrive/p3mx/p3mx.h b/board/prodrive/p3mx/p3mx.h index 91071e9209..1caae6b9c1 100644 --- a/board/prodrive/p3mx/p3mx.h +++ b/board/prodrive/p3mx/p3mx.h @@ -31,4 +31,3 @@ #define LED_ORANGE 4 #endif /* __P3MX_H__ */ - diff --git a/board/sandburst/common/ppc440gx_i2c.c b/board/sandburst/common/ppc440gx_i2c.c index 859dd7afe5..1e3dffb1ee 100644 --- a/board/sandburst/common/ppc440gx_i2c.c +++ b/board/sandburst/common/ppc440gx_i2c.c @@ -27,13 +27,8 @@ */ #include #include -#if defined(CONFIG_440) -# include <440_i2c.h> -#else -# include <405gp_i2c.h> -#endif +#include <4xx_i2c.h> #include -#include <440_i2c.h> #include #include "ppc440gx_i2c.h" diff --git a/board/sandburst/common/ppc440gx_i2c.h b/board/sandburst/common/ppc440gx_i2c.h index cd4fc86661..10000f5ba9 100644 --- a/board/sandburst/common/ppc440gx_i2c.h +++ b/board/sandburst/common/ppc440gx_i2c.h @@ -27,11 +27,7 @@ */ #include #include -#if defined(CONFIG_440) -# include <440_i2c.h> -#else -# include <405gp_i2c.h> -#endif +#include <4xx_i2c.h> #include #ifdef CONFIG_HARD_I2C diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index d2c8d44a79..f4074aecb1 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -203,7 +203,6 @@ extern int flash_write (char *, ulong, ulong); /* change char* to void* to shutup the compiler */ extern int i2c_write_multiple (uchar, uint, int, void *, int); extern int i2c_read_multiple (uchar, uint, int, void *, int); -extern block_dev_desc_t *get_dev (char*, int); extern int u_boot_hush_start(void); int diff --git a/board/xilinx/ml300/Makefile b/board/xilinx/ml300/Makefile index 02c22fbef1..05ad23524f 100644 --- a/board/xilinx/ml300/Makefile +++ b/board/xilinx/ml300/Makefile @@ -28,7 +28,7 @@ $(shell mkdir -p $(obj)../xilinx_enet) $(shell mkdir -p $(obj)../xilinx_iic) endif -INCS := -I../ml300 -I../common -I../xilinx_enet -I../xilinx_iic +INCS := -I../common -I../xilinx_enet -I../xilinx_iic CFLAGS += $(INCS) HOST_CFLAGS += $(INCS) diff --git a/board/xilinx/ml300/ml300.c b/board/xilinx/ml300/ml300.c index dad562f1c7..60f0bc24e7 100644 --- a/board/xilinx/ml300/ml300.c +++ b/board/xilinx/ml300/ml300.c @@ -38,9 +38,9 @@ * */ +#include #include #include -#include "xparameters.h" #ifdef CFG_ENV_IS_IN_EEPROM extern void convert_env(void); diff --git a/board/xilinx/ml300/serial.c b/board/xilinx/ml300/serial.c index c204b88e41..9b03f89eff 100644 --- a/board/xilinx/ml300/serial.c +++ b/board/xilinx/ml300/serial.c @@ -40,8 +40,7 @@ #include #include #include -#include -#include "xparameters.h" +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c index b30e897669..f159cb6e39 100644 --- a/board/xilinx/xilinx_enet/emac_adapter.c +++ b/board/xilinx/xilinx_enet/emac_adapter.c @@ -37,9 +37,9 @@ * ******************************************************************************/ +#include #include #include -#include "xparameters.h" #include "xemac.h" #if defined(XPAR_EMAC_0_DEVICE_ID) diff --git a/board/xilinx/xilinx_enet/xemac.h b/board/xilinx/xilinx_enet/xemac.h index ed704bf29b..584cb7ac51 100644 --- a/board/xilinx/xilinx_enet/xemac.h +++ b/board/xilinx/xilinx_enet/xemac.h @@ -257,9 +257,9 @@ /***************************** Include Files *********************************/ +#include #include "xbasic_types.h" #include "xstatus.h" -#include "xparameters.h" #include "xpacket_fifo_v1_00_b.h" /* Uses v1.00b of Packet Fifo */ #include "xdma_channel.h" diff --git a/board/xilinx/xilinx_enet/xemac_g.c b/board/xilinx/xilinx_enet/xemac_g.c index 9340f911f8..d9851574f7 100644 --- a/board/xilinx/xilinx_enet/xemac_g.c +++ b/board/xilinx/xilinx_enet/xemac_g.c @@ -43,7 +43,7 @@ * *******************************************************************/ -#include "xparameters.h" +#include #include "xemac.h" /* diff --git a/board/xilinx/xilinx_iic/iic_adapter.c b/board/xilinx/xilinx_iic/iic_adapter.c index 163fe1511d..37dce03916 100644 --- a/board/xilinx/xilinx_iic/iic_adapter.c +++ b/board/xilinx/xilinx_iic/iic_adapter.c @@ -37,10 +37,10 @@ * ******************************************************************************/ +#include #include #include #include -#include "xparameters.h" #ifdef CFG_ENV_IS_IN_EEPROM #include diff --git a/common/Makefile b/common/Makefile index 0106088e24..6f81c4abcf 100644 --- a/common/Makefile +++ b/common/Makefile @@ -27,8 +27,7 @@ LIB = $(obj)libcommon.a AOBJS = -COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ - cmd_ace.o cmd_autoscript.o \ +COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \ cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \ cmd_cache.o cmd_console.o \ cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \ diff --git a/common/cmd_ace.c b/common/cmd_ace.c deleted file mode 100644 index b6d61057fd..0000000000 --- a/common/cmd_ace.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2004 Picture Elements, Inc. - * Stephen Williams (XXXXXXXXXXXXXXXX) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form 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 - */ -#ident "$Id:$" - -/* - * The Xilinx SystemACE chip support is activated by defining - * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE - * to set the base address of the device. This code currently - * assumes that the chip is connected via a byte-wide bus. - * - * The CONFIG_SYSTEMACE also adds to fat support the device class - * "ace" that allows the user to execute "fatls ace 0" and the - * like. This works by making the systemace_get_dev function - * available to cmd_fat.c:get_dev and filling in a block device - * description that has all the bits needed for FAT support to - * read sectors. - * - * According to Xilinx technical support, before accessing the - * SystemACE CF you need to set the following control bits: - * FORCECFGMODE : 1 - * CFGMODE : 0 - * CFGSTART : 0 - */ - -# include -# include -# include -# include -# include - -#ifdef CONFIG_SYSTEMACE - -/* - * The ace_readw and writew functions read/write 16bit words, but the - * offset value is the BYTE offset as most used in the Xilinx - * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined - * to be the base address for the chip, usually in the local - * peripheral bus. - */ -static unsigned ace_readw(unsigned offset) -{ -#if (CFG_SYSTEMACE_WIDTH == 8) - u16 temp; - -#if !defined(__BIG_ENDIAN) - temp =((u16)readb(CFG_SYSTEMACE_BASE+offset) << 8); - temp |= (u16)readb(CFG_SYSTEMACE_BASE+offset+1); -#else - temp = (u16)readb(CFG_SYSTEMACE_BASE+offset); - temp |=((u16)readb(CFG_SYSTEMACE_BASE+offset+1) << 8); -#endif - return temp; -#else - return readw(CFG_SYSTEMACE_BASE+offset); -#endif -} - -static void ace_writew(unsigned val, unsigned offset) -{ -#if (CFG_SYSTEMACE_WIDTH == 8) -#if !defined(__BIG_ENDIAN) - writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset); - writeb((u8)val, CFG_SYSTEMACE_BASE+offset+1); -#else - writeb((u8)val, CFG_SYSTEMACE_BASE+offset); - writeb((u8)(val>>8), CFG_SYSTEMACE_BASE+offset+1); -#endif -#else - writew(val, CFG_SYSTEMACE_BASE+offset); -#endif -} - -/* */ - -static unsigned long systemace_read(int dev, - unsigned long start, - unsigned long blkcnt, - unsigned long *buffer); - -static block_dev_desc_t systemace_dev = {0}; - -static int get_cf_lock(void) -{ - int retry = 10; - - /* CONTROLREG = LOCKREG */ - unsigned val=ace_readw(0x18); - val|=0x0002; - ace_writew((val&0xffff), 0x18); - - /* Wait for MPULOCK in STATUSREG[15:0] */ - while (! (ace_readw(0x04) & 0x0002)) { - - if (retry < 0) - return -1; - - udelay(100000); - retry -= 1; - } - - return 0; -} - -static void release_cf_lock(void) -{ - unsigned val=ace_readw(0x18); - val&=~(0x0002); - ace_writew((val&0xffff), 0x18); -} - -block_dev_desc_t * systemace_get_dev(int dev) -{ - /* The first time through this, the systemace_dev object is - not yet initialized. In that case, fill it in. */ - if (systemace_dev.blksz == 0) { - systemace_dev.if_type = IF_TYPE_UNKNOWN; - systemace_dev.dev = 0; - systemace_dev.part_type = PART_TYPE_UNKNOWN; - systemace_dev.type = DEV_TYPE_HARDDISK; - systemace_dev.blksz = 512; - systemace_dev.removable = 1; - systemace_dev.block_read = systemace_read; - - init_part(&systemace_dev); - - } - - return &systemace_dev; -} - -/* - * This function is called (by dereferencing the block_read pointer in - * the dev_desc) to read blocks of data. The return value is the - * number of blocks read. A zero return indicates an error. - */ -static unsigned long systemace_read(int dev, - unsigned long start, - unsigned long blkcnt, - unsigned long *buffer) -{ - int retry; - unsigned blk_countdown; - unsigned char*dp = (unsigned char*)buffer; - unsigned val; - - if (get_cf_lock() < 0) { - unsigned status = ace_readw(0x04); - - /* If CFDETECT is false, card is missing. */ - if (! (status&0x0010)) { - printf("** CompactFlash card not present. **\n"); - return 0; - } - - printf("**** ACE locked away from me (STATUSREG=%04x)\n", status); - return 0; - } - -#ifdef DEBUG_SYSTEMACE - printf("... systemace read %lu sectors at %lu\n", blkcnt, start); -#endif - - retry = 2000; - for (;;) { - val = ace_readw(0x04); - - /* If CFDETECT is false, card is missing. */ - if (! (val & 0x0010)) { - printf("**** ACE CompactFlash not found.\n"); - release_cf_lock(); - return 0; - } - - /* If RDYFORCMD, then we are ready to go. */ - if (val & 0x0100) - break; - - if (retry < 0) { - printf("**** SystemACE not ready.\n"); - release_cf_lock(); - return 0; - } - - udelay(1000); - retry -= 1; - } - - /* The SystemACE can only transfer 256 sectors at a time, so - limit the current chunk of sectors. The blk_countdown - variable is the number of sectors left to transfer. */ - - blk_countdown = blkcnt; - while (blk_countdown > 0) { - unsigned trans = blk_countdown; - - if (trans > 256) trans = 256; - -#ifdef DEBUG_SYSTEMACE - printf("... transfer %lu sector in a chunk\n", trans); -#endif - /* Write LBA block address */ - ace_writew((start>> 0) & 0xffff, 0x10); - ace_writew((start>>16) & 0x00ff, 0x12); - - /* NOTE: in the Write Sector count below, a count of 0 - causes a transfer of 256, so &0xff gives the right - value for whatever transfer count we want. */ - - /* Write sector count | ReadMemCardData. */ - ace_writew((trans&0xff) | 0x0300, 0x14); - - /* Reset the configruation controller */ - val = ace_readw(0x18); - val|=0x0080; - ace_writew(val, 0x18); - - retry = trans * 16; - while (retry > 0) { - int idx; - - /* Wait for buffer to become ready. */ - while (! (ace_readw(0x04) & 0x0020)) { - udelay(100); - } - - /* Read 16 words of 2bytes from the sector buffer. */ - for (idx = 0 ; idx < 16 ; idx += 1) { - unsigned short val = ace_readw(0x40); - *dp++ = val & 0xff; - *dp++ = (val>>8) & 0xff; - } - - retry -= 1; - } - - /* Clear the configruation controller reset */ - val = ace_readw(0x18); - val&=~0x0080; - ace_writew(val, 0x18); - - /* Count the blocks we transfer this time. */ - start += trans; - blk_countdown -= trans; - } - - release_cf_lock(); - - return blkcnt; -} -#endif /* CONFIG_SYSTEMACE */ diff --git a/common/cmd_date.c b/common/cmd_date.c index 84932f7568..33d2e5661e 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -44,6 +45,11 @@ int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { struct rtc_time tm; int rcode = 0; + int old_bus; + + /* switch to correct I2C bus */ + old_bus = I2C_GET_BUS(); + I2C_SET_BUS(CFG_RTC_BUS_NUM); switch (argc) { case 2: /* set date & time */ @@ -56,7 +62,7 @@ int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* insert new date & time */ if (mk_date (argv[1], &tm) != 0) { puts ("## Bad date format\n"); - return 1; + break; } /* and write to RTC */ rtc_set (&tm); @@ -71,11 +77,15 @@ int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) "unknown " : RELOC(weekdays[tm.tm_wday]), tm.tm_hour, tm.tm_min, tm.tm_sec); - return 0; + break; default: printf ("Usage:\n%s\n", cmdtp->usage); rcode = 1; } + + /* switch back to original I2C bus */ + I2C_SET_BUS(old_bus); + return rcode; } diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c index 9db64e9e3d..4f7b049d79 100644 --- a/common/cmd_dtt.c +++ b/common/cmd_dtt.c @@ -28,19 +28,27 @@ #if (CONFIG_COMMANDS & CFG_CMD_DTT) #include +#include int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i; unsigned char sensors[] = CONFIG_DTT_SENSORS; + int old_bus; + + /* switch to correct I2C bus */ + old_bus = I2C_GET_BUS(); + I2C_SET_BUS(CFG_DTT_BUS_NUM); /* * Loop through sensors, read * temperature, and output it. */ - for (i = 0; i < sizeof (sensors); i++) { + for (i = 0; i < sizeof (sensors); i++) printf ("DTT%d: %i C\n", i + 1, dtt_get_temp (sensors[i])); - } + + /* switch back to original I2C bus */ + I2C_SET_BUS(old_bus); return 0; } /* do_dtt() */ diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index 5db42f2b0d..94bd9b61e6 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -33,6 +33,7 @@ * Ext2fs support */ #include +#include #if (CONFIG_COMMANDS & CFG_CMD_EXT2) #include @@ -57,41 +58,6 @@ #define PRINTF(fmt,args...) #endif -static block_dev_desc_t *get_dev (char* ifname, int dev) -{ -#if (CONFIG_COMMANDS & CFG_CMD_IDE) - if (strncmp(ifname,"ide",3)==0) { - extern block_dev_desc_t * ide_get_dev(int dev); - return((dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev)); - } -#endif -#if (CONFIG_COMMANDS & CFG_CMD_SCSI) - if (strncmp(ifname,"scsi",4)==0) { - extern block_dev_desc_t * scsi_get_dev(int dev); - return((dev >= CFG_SCSI_MAXDEVICE) ? NULL : scsi_get_dev(dev)); - } -#endif -#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) - if (strncmp(ifname,"usb",3)==0) { - extern block_dev_desc_t * usb_stor_get_dev(int dev); - return((dev >= USB_MAX_STOR_DEV) ? NULL : usb_stor_get_dev(dev)); - } -#endif -#if defined(CONFIG_MMC) - if (strncmp(ifname,"mmc",3)==0) { - extern block_dev_desc_t * mmc_get_dev(int dev); - return((dev >= 1) ? NULL : mmc_get_dev(dev)); - } -#endif -#if defined(CONFIG_SYSTEMACE) - if (strcmp(ifname,"ace")==0) { - extern block_dev_desc_t * systemace_get_dev(int dev); - return((dev >= 1) ? NULL : systemace_get_dev(dev)); - } -#endif - return(NULL); -} - int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = "/"; @@ -106,7 +72,7 @@ int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(1); } dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); + dev_desc = get_dev(argv[1],dev); if (dev_desc == NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); @@ -210,7 +176,7 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); + dev_desc = get_dev(argv[1],dev); if (dev_desc==NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); return(1); diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 6844c103f2..afaf299569 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -29,6 +29,7 @@ #include #include #include +#include #if (CONFIG_COMMANDS & CFG_CMD_FAT) @@ -37,42 +38,6 @@ #include -block_dev_desc_t *get_dev (char* ifname, int dev) -{ -#if (CONFIG_COMMANDS & CFG_CMD_IDE) - if (strncmp(ifname,"ide",3)==0) { - extern block_dev_desc_t * ide_get_dev(int dev); - return(ide_get_dev(dev)); - } -#endif -#if (CONFIG_COMMANDS & CFG_CMD_SCSI) - if (strncmp(ifname,"scsi",4)==0) { - extern block_dev_desc_t * scsi_get_dev(int dev); - return(scsi_get_dev(dev)); - } -#endif -#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) - if (strncmp(ifname,"usb",3)==0) { - extern block_dev_desc_t * usb_stor_get_dev(int dev); - return(usb_stor_get_dev(dev)); - } -#endif -#if defined(CONFIG_MMC) - if (strncmp(ifname,"mmc",3)==0) { - extern block_dev_desc_t * mmc_get_dev(int dev); - return(mmc_get_dev(dev)); - } -#endif -#if defined(CONFIG_SYSTEMACE) - if (strcmp(ifname,"ace")==0) { - extern block_dev_desc_t * systemace_get_dev(int dev); - return(systemace_get_dev(dev)); - } -#endif - return NULL; -} - - int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { long size; diff --git a/common/cmd_ide.c b/common/cmd_ide.c index a4155029a7..2e185cc441 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -31,20 +31,26 @@ #include #include #include + #if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA) # include #endif + #ifdef CONFIG_8xx # include #endif + #ifdef CONFIG_MPC5xxx #include #endif + #include #include + #ifdef CONFIG_STATUS_LED # include #endif + #ifndef __PPC__ #include #ifdef __MIPS__ @@ -182,7 +188,7 @@ static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len #ifdef CONFIG_ATAPI static void atapi_inquiry(block_dev_desc_t *dev_desc); -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); +ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer); #endif @@ -697,7 +703,7 @@ void ide_init (void) block_dev_desc_t * ide_get_dev(int dev) { - return ((block_dev_desc_t *)&ide_dev_desc[dev]); + return (dev < CFG_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL; } @@ -1227,7 +1233,7 @@ static void ide_ident (block_dev_desc_t *dev_desc) /* ------------------------------------------------------------------------- */ -ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char c; @@ -1347,7 +1353,7 @@ IDE_READ_E: /* ------------------------------------------------------------------------- */ -ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char c; @@ -2009,7 +2015,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) #define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ #define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE /* max blocks */ -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char ccb[12]; /* Command descriptor block */ diff --git a/common/cmd_mem.c b/common/cmd_mem.c index d0fae6b24c..fcbb0236d2 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -92,8 +92,9 @@ static ulong base_address = 0; int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, length; - ulong i, nbytes, linebytes; - u_char *cp; +#if defined(CONFIG_HAS_DATAFLASH) + ulong nbytes, linebytes; +#endif int size; int rc = 0; @@ -128,6 +129,7 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) length = simple_strtoul(argv[2], NULL, 16); } +#if defined(CONFIG_HAS_DATAFLASH) /* Print the lines. * * We buffer all read data, so we can make sure data is read only @@ -136,64 +138,25 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) nbytes = length * size; do { char linebuf[DISP_LINE_LEN]; - uint *uip = (uint *)linebuf; - ushort *usp = (ushort *)linebuf; - u_char *ucp = (u_char *)linebuf; -#ifdef CONFIG_HAS_DATAFLASH - int rc; -#endif - printf("%08lx:", addr); + void* p; linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; -#ifdef CONFIG_HAS_DATAFLASH - if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){ - /* if outside dataflash */ - /*if (rc != 1) { - dataflash_perror (rc); - return (1); - }*/ - for (i=0; i 0x7e)) - putc ('.'); - else - printf("%c", *cp); - cp++; - } - putc ('\n'); nbytes -= linebytes; + addr += linebytes; if (ctrlc()) { rc = 1; break; } } while (nbytes > 0); +#else + /* Print the lines. */ + print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size); + addr += size*length; +#endif dp_last_addr = addr; dp_last_length = length; diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index 508ffcbdac..09c86e66d7 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -35,6 +35,7 @@ #include #include #include +#include #ifndef CONFIG_DOS_PARTITION #error DOS partition support must be selected @@ -48,41 +49,6 @@ #define PRINTF(fmt,args...) #endif -static block_dev_desc_t *get_dev (char* ifname, int dev) -{ -#if (CONFIG_COMMANDS & CFG_CMD_IDE) - if (strncmp(ifname,"ide",3)==0) { - extern block_dev_desc_t * ide_get_dev(int dev); - return((dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev)); - } -#endif -#if (CONFIG_COMMANDS & CFG_CMD_SCSI) - if (strncmp(ifname,"scsi",4)==0) { - extern block_dev_desc_t * scsi_get_dev(int dev); - return((dev >= CFG_SCSI_MAXDEVICE) ? NULL : scsi_get_dev(dev)); - } -#endif -#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) - if (strncmp(ifname,"usb",3)==0) { - extern block_dev_desc_t * usb_stor_get_dev(int dev); - return((dev >= USB_MAX_STOR_DEV) ? NULL : usb_stor_get_dev(dev)); - } -#endif -#if defined(CONFIG_MMC) - if (strncmp(ifname,"mmc",3)==0) { - extern block_dev_desc_t * mmc_get_dev(int dev); - return((dev >= 1) ? NULL : mmc_get_dev(dev)); - } -#endif -#if defined(CONFIG_SYSTEMACE) - if (strcmp(ifname,"ace")==0) { - extern block_dev_desc_t * systemace_get_dev(int dev); - return((dev >= 1) ? NULL : systemace_get_dev(dev)); - } -#endif - return NULL; -} - int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = "/"; @@ -97,7 +63,7 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); + dev_desc = get_dev(argv[1],dev); if (dev_desc == NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); @@ -196,7 +162,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc=get_dev(argv[1],dev); + dev_desc = get_dev(argv[1],dev); if (dev_desc==NULL) { printf ("\n** Block device %s %d not supported\n", argv[1], dev); return 1; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index cc08743d5d..da36ed9e1d 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -74,7 +74,7 @@ void scsi_setup_inquiry(ccb * pccb); void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); -ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer); +ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer); /********************************************************************************* @@ -194,7 +194,7 @@ void scsi_init(void) block_dev_desc_t * scsi_get_dev(int dev) { - return((block_dev_desc_t *)&scsi_dev_desc[dev]); + return (dev < CFG_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL; } @@ -424,7 +424,7 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */ -ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer) +ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer) { ulong start,blks, buf_addr; unsigned short smallblks; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 28c05aa20e..904df7159f 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -28,6 +28,7 @@ #include #include #include +#include #if (CONFIG_COMMANDS & CFG_CMD_USB) diff --git a/common/ft_build.c b/common/ft_build.c index 980e40f55d..5a0575e89a 100644 --- a/common/ft_build.c +++ b/common/ft_build.c @@ -29,6 +29,7 @@ #include #include +#include #undef DEBUG @@ -180,11 +181,6 @@ void ft_finalize_tree(struct ft_cxt *cxt) { bph->dt_strings_size = cxt->p_end - cxt->p; } -static inline int isprint(int c) -{ - return c >= 0x20 && c <= 0x7e; -} - static int is_printable_string(const void *data, int len) { const char *s = data; diff --git a/common/usb_storage.c b/common/usb_storage.c index 06ea99b2f1..196ceb7359 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -56,6 +56,7 @@ #if (CONFIG_COMMANDS & CFG_CMD_USB) +#include #include #ifdef CONFIG_USB_STORAGE @@ -168,13 +169,13 @@ static struct us_data usb_stor[USB_MAX_STOR_DEV]; int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc); int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss); -unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer); +unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer); struct usb_device * usb_get_dev_index(int index); void uhci_show_temp_int_td(void); block_dev_desc_t *usb_stor_get_dev(int index) { - return &usb_dev_desc[index]; + return (index < USB_MAX_STOR_DEV) ? &usb_dev_desc[index] : NULL; } @@ -940,7 +941,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor, #define USB_MAX_READ_BLK 20 -unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer) +unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer) { unsigned long start,blks, buf_addr; unsigned short smallblks; diff --git a/cpu/ppc4xx/40x_spd_sdram.c b/cpu/ppc4xx/40x_spd_sdram.c new file mode 100644 index 0000000000..19c4f764e3 --- /dev/null +++ b/cpu/ppc4xx/40x_spd_sdram.c @@ -0,0 +1,469 @@ +/* + * cpu/ppc4xx/40x_spd_sdram.c + * This SPD SDRAM detection code supports IBM/AMCC PPC44x cpu with a + * SDRAM controller. Those are all current 405 PPC's. + * + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com + * + * Based on code by: + * + * Kenneth Johansson ,Ericsson AB. + * kenneth.johansson@etx.ericsson.se + * + * hacked up by bill hunter. fixed so we could run before + * serial_init and console_init. previous version avoided this by + * running out of cache memory during serial/console init, then running + * this code later. + * + * (C) Copyright 2002 + * Jun Gu, Artesyn Technology, jung@artesyncp.com + * Support for AMCC 440 based on OpenBIOS draminit.c from IBM. + * + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@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 +#include +#include +#include + +#if defined(CONFIG_SPD_EEPROM) && !defined(CONFIG_440) + +/* + * Set default values + */ +#ifndef CFG_I2C_SPEED +#define CFG_I2C_SPEED 50000 +#endif + +#ifndef CFG_I2C_SLAVE +#define CFG_I2C_SLAVE 0xFE +#endif + +#define ONE_BILLION 1000000000 + +#define SDRAM0_CFG_DCE 0x80000000 +#define SDRAM0_CFG_SRE 0x40000000 +#define SDRAM0_CFG_PME 0x20000000 +#define SDRAM0_CFG_MEMCHK 0x10000000 +#define SDRAM0_CFG_REGEN 0x08000000 +#define SDRAM0_CFG_ECCDD 0x00400000 +#define SDRAM0_CFG_EMDULR 0x00200000 +#define SDRAM0_CFG_DRW_SHIFT (31-6) +#define SDRAM0_CFG_BRPF_SHIFT (31-8) + +#define SDRAM0_TR_CASL_SHIFT (31-8) +#define SDRAM0_TR_PTA_SHIFT (31-13) +#define SDRAM0_TR_CTP_SHIFT (31-15) +#define SDRAM0_TR_LDF_SHIFT (31-17) +#define SDRAM0_TR_RFTA_SHIFT (31-29) +#define SDRAM0_TR_RCD_SHIFT (31-31) + +#define SDRAM0_RTR_SHIFT (31-15) +#define SDRAM0_ECCCFG_SHIFT (31-11) + +/* SDRAM0_CFG enable macro */ +#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT ) + +#define SDRAM0_BXCR_SZ_MASK 0x000e0000 +#define SDRAM0_BXCR_AM_MASK 0x0000e000 + +#define SDRAM0_BXCR_SZ_SHIFT (31-14) +#define SDRAM0_BXCR_AM_SHIFT (31-18) + +#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) ) +#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) ) + +#ifdef CONFIG_SPDDRAM_SILENT +# define SPD_ERR(x) do { return 0; } while (0) +#else +# define SPD_ERR(x) do { printf(x); return(0); } while (0) +#endif + +#define sdram_HZ_to_ns(hertz) (1000000000/(hertz)) + +/* function prototypes */ +int spd_read(uint addr); + + +/* + * This function is reading data from the DIMM module EEPROM over the SPD bus + * and uses that to program the sdram controller. + * + * This works on boards that has the same schematics that the AMCC walnut has. + * + * Input: null for default I2C spd functions or a pointer to a custom function + * returning spd_data. + */ + +long int spd_sdram(int(read_spd)(uint addr)) +{ + int tmp,row,col; + int total_size,bank_size,bank_code; + int ecc_on; + int mode; + int bank_cnt; + + int sdram0_pmit=0x07c00000; +#ifndef CONFIG_405EP /* not on PPC405EP */ + int sdram0_besr0=-1; + int sdram0_besr1=-1; + int sdram0_eccesr=-1; +#endif + int sdram0_ecccfg; + + int sdram0_rtr=0; + int sdram0_tr=0; + + int sdram0_b0cr; + int sdram0_b1cr; + int sdram0_b2cr; + int sdram0_b3cr; + + int sdram0_cfg=0; + + int t_rp; + int t_rcd; + int t_ras; + int t_rc; + int min_cas; + + PPC405_SYS_INFO sys_info; + unsigned long bus_period_x_10; + + /* + * get the board info + */ + get_sys_info(&sys_info); + bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); + + if (read_spd == 0){ + read_spd=spd_read; + /* + * Make sure I2C controller is initialized + * before continuing. + */ + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + } + + /* Make shure we are using SDRAM */ + if (read_spd(2) != 0x04) { + SPD_ERR("SDRAM - non SDRAM memory module found\n"); + } + + /* ------------------------------------------------------------------ + * configure memory timing register + * + * data from DIMM: + * 27 IN Row Precharge Time ( t RP) + * 29 MIN RAS to CAS Delay ( t RCD) + * 127 Component and Clock Detail ,clk0-clk3, junction temp, CAS + * -------------------------------------------------------------------*/ + + /* + * first figure out which cas latency mode to use + * use the min supported mode + */ + + tmp = read_spd(127) & 0x6; + if (tmp == 0x02) { /* only cas = 2 supported */ + min_cas = 2; +/* t_ck = read_spd(9); */ +/* t_ac = read_spd(10); */ + } else if (tmp == 0x04) { /* only cas = 3 supported */ + min_cas = 3; +/* t_ck = read_spd(9); */ +/* t_ac = read_spd(10); */ + } else if (tmp == 0x06) { /* 2,3 supported, so use 2 */ + min_cas = 2; +/* t_ck = read_spd(23); */ +/* t_ac = read_spd(24); */ + } else { + SPD_ERR("SDRAM - unsupported CAS latency \n"); + } + + /* get some timing values, t_rp,t_rcd,t_ras,t_rc + */ + t_rp = read_spd(27); + t_rcd = read_spd(29); + t_ras = read_spd(30); + t_rc = t_ras + t_rp; + + /* The following timing calcs subtract 1 before deviding. + * this has effect of using ceiling instead of floor rounding, + * and also subtracting 1 to convert number to reg value + */ + /* set up CASL */ + sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT; + /* set up PTA */ + sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT; + /* set up CTP */ + tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3; + if (tmp < 1) + tmp = 1; + sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT; + /* set LDF = 2 cycles, reg value = 1 */ + sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT; + /* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */ + tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3; + if (tmp < 0) + tmp = 0; + if (tmp > 6) + tmp = 6; + sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT; + /* set RCD = t_rcd/bus_period*/ + sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ; + + + /*------------------------------------------------------------------ + * configure RTR register + * -------------------------------------------------------------------*/ + row = read_spd(3); + col = read_spd(4); + tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */ + switch (tmp) { + case 0x00: + tmp = 15625; + break; + case 0x01: + tmp = 15625 / 4; + break; + case 0x02: + tmp = 15625 / 2; + break; + case 0x03: + tmp = 15625 * 2; + break; + case 0x04: + tmp = 15625 * 4; + break; + case 0x05: + tmp = 15625 * 8; + break; + default: + SPD_ERR("SDRAM - Bad refresh period \n"); + } + /* convert from nsec to bus cycles */ + tmp = (tmp * 10) / bus_period_x_10; + sdram0_rtr = (tmp & 0x3ff8) << SDRAM0_RTR_SHIFT; + + /*------------------------------------------------------------------ + * determine the number of banks used + * -------------------------------------------------------------------*/ + /* byte 7:6 is module data width */ + if (read_spd(7) != 0) + SPD_ERR("SDRAM - unsupported module width\n"); + tmp = read_spd(6); + if (tmp < 32) + SPD_ERR("SDRAM - unsupported module width\n"); + else if (tmp < 64) + bank_cnt = 1; /* one bank per sdram side */ + else if (tmp < 73) + bank_cnt = 2; /* need two banks per side */ + else if (tmp < 161) + bank_cnt = 4; /* need four banks per side */ + else + SPD_ERR("SDRAM - unsupported module width\n"); + + /* byte 5 is the module row count (refered to as dimm "sides") */ + tmp = read_spd(5); + if (tmp == 1) + ; + else if (tmp==2) + bank_cnt *= 2; + else if (tmp==4) + bank_cnt *= 4; + else + bank_cnt = 8; /* 8 is an error code */ + + if (bank_cnt > 4) /* we only have 4 banks to work with */ + SPD_ERR("SDRAM - unsupported module rows for this width\n"); + + /* now check for ECC ability of module. We only support ECC + * on 32 bit wide devices with 8 bit ECC. + */ + if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) { + sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT; + ecc_on = 1; + } else { + sdram0_ecccfg = 0; + ecc_on = 0; + } + + /*------------------------------------------------------------------ + * calculate total size + * -------------------------------------------------------------------*/ + /* calculate total size and do sanity check */ + tmp = read_spd(31); + total_size = 1 << 22; /* total_size = 4MB */ + /* now multiply 4M by the smallest device row density */ + /* note that we don't support asymetric rows */ + while (((tmp & 0x0001) == 0) && (tmp != 0)) { + total_size = total_size << 1; + tmp = tmp >> 1; + } + total_size *= read_spd(5); /* mult by module rows (dimm sides) */ + + /*------------------------------------------------------------------ + * map rows * cols * banks to a mode + * -------------------------------------------------------------------*/ + + switch (row) { + case 11: + switch (col) { + case 8: + mode=4; /* mode 5 */ + break; + case 9: + case 10: + mode=0; /* mode 1 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + case 12: + switch (col) { + case 8: + mode=3; /* mode 4 */ + break; + case 9: + case 10: + mode=1; /* mode 2 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + case 13: + switch (col) { + case 8: + mode=5; /* mode 6 */ + break; + case 9: + case 10: + if (read_spd(17) == 2) + mode = 6; /* mode 7 */ + else + mode = 2; /* mode 3 */ + break; + case 11: + mode = 2; /* mode 3 */ + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + break; + default: + SPD_ERR("SDRAM - unsupported mode\n"); + } + + /*------------------------------------------------------------------ + * using the calculated values, compute the bank + * config register values. + * -------------------------------------------------------------------*/ + sdram0_b1cr = 0; + sdram0_b2cr = 0; + sdram0_b3cr = 0; + + /* compute the size of each bank */ + bank_size = total_size / bank_cnt; + /* convert bank size to bank size code for ppc4xx + by takeing log2(bank_size) - 22 */ + tmp = bank_size; /* start with tmp = bank_size */ + bank_code = 0; /* and bank_code = 0 */ + while (tmp > 1) { /* this takes log2 of tmp */ + bank_code++; /* and stores result in bank_code */ + tmp = tmp >> 1; + } /* bank_code is now log2(bank_size) */ + bank_code -= 22; /* subtract 22 to get the code */ + + tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1; + sdram0_b0cr = (bank_size * 0) | tmp; +#ifndef CONFIG_405EP /* not on PPC405EP */ + if (bank_cnt > 1) + sdram0_b2cr = (bank_size * 1) | tmp; + if (bank_cnt > 2) + sdram0_b1cr = (bank_size * 2) | tmp; + if (bank_cnt > 3) + sdram0_b3cr = (bank_size * 3) | tmp; +#else + /* PPC405EP chip only supports two SDRAM banks */ + if (bank_cnt > 1) + sdram0_b1cr = (bank_size * 1) | tmp; + if (bank_cnt > 2) + total_size = 2 * bank_size; +#endif + + /* + * enable sdram controller DCE=1 + * enable burst read prefetch to 32 bytes BRPF=2 + * leave other functions off + */ + + /*------------------------------------------------------------------ + * now that we've done our calculations, we are ready to + * program all the registers. + * -------------------------------------------------------------------*/ + +#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) + /* disable memcontroller so updates work */ + mtsdram0( mem_mcopt1, 0 ); + +#ifndef CONFIG_405EP /* not on PPC405EP */ + mtsdram0( mem_besra , sdram0_besr0 ); + mtsdram0( mem_besrb , sdram0_besr1 ); + mtsdram0( mem_ecccf , sdram0_ecccfg ); + mtsdram0( mem_eccerr, sdram0_eccesr ); +#endif + mtsdram0( mem_rtr , sdram0_rtr ); + mtsdram0( mem_pmit , sdram0_pmit ); + mtsdram0( mem_mb0cf , sdram0_b0cr ); + mtsdram0( mem_mb1cf , sdram0_b1cr ); +#ifndef CONFIG_405EP /* not on PPC405EP */ + mtsdram0( mem_mb2cf , sdram0_b2cr ); + mtsdram0( mem_mb3cf , sdram0_b3cr ); +#endif + mtsdram0( mem_sdtr1 , sdram0_tr ); + + /* SDRAM have a power on delay, 500 micro should do */ + udelay(500); + sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR; + if (ecc_on) + sdram0_cfg |= SDRAM0_CFG_MEMCHK; + mtsdram0(mem_mcopt1, sdram0_cfg); + + return (total_size); +} + +int spd_read(uint addr) +{ + uchar data[2]; + + if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0) + return (int)data[0]; + else + return 0; +} + +#endif /* CONFIG_SPD_EEPROM */ diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/44x_spd_ddr.c similarity index 77% rename from cpu/ppc4xx/spd_sdram.c rename to cpu/ppc4xx/44x_spd_ddr.c index c24456bea8..32d44dbe56 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/44x_spd_ddr.c @@ -1,4 +1,8 @@ /* + * cpu/ppc4xx/44x_spd_ddr.c + * This SPD DDR detection code supports IBM/AMCC PPC44x cpu with a + * DDR controller. Those are 440GP/GX/EP/GR. + * * (C) Copyright 2001 * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com * @@ -43,7 +47,9 @@ #include #include -#ifdef CONFIG_SPD_EEPROM +#if defined(CONFIG_SPD_EEPROM) && \ + (defined(CONFIG_440GP) || defined(CONFIG_440GX) || \ + defined(CONFIG_440EP) || defined(CONFIG_440GR)) /* * Set default values @@ -58,414 +64,6 @@ #define ONE_BILLION 1000000000 -#ifndef CONFIG_440 /* for 405 WALNUT/SYCAMORE/BUBINGA boards */ - -#define SDRAM0_CFG_DCE 0x80000000 -#define SDRAM0_CFG_SRE 0x40000000 -#define SDRAM0_CFG_PME 0x20000000 -#define SDRAM0_CFG_MEMCHK 0x10000000 -#define SDRAM0_CFG_REGEN 0x08000000 -#define SDRAM0_CFG_ECCDD 0x00400000 -#define SDRAM0_CFG_EMDULR 0x00200000 -#define SDRAM0_CFG_DRW_SHIFT (31-6) -#define SDRAM0_CFG_BRPF_SHIFT (31-8) - -#define SDRAM0_TR_CASL_SHIFT (31-8) -#define SDRAM0_TR_PTA_SHIFT (31-13) -#define SDRAM0_TR_CTP_SHIFT (31-15) -#define SDRAM0_TR_LDF_SHIFT (31-17) -#define SDRAM0_TR_RFTA_SHIFT (31-29) -#define SDRAM0_TR_RCD_SHIFT (31-31) - -#define SDRAM0_RTR_SHIFT (31-15) -#define SDRAM0_ECCCFG_SHIFT (31-11) - -/* SDRAM0_CFG enable macro */ -#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT ) - -#define SDRAM0_BXCR_SZ_MASK 0x000e0000 -#define SDRAM0_BXCR_AM_MASK 0x0000e000 - -#define SDRAM0_BXCR_SZ_SHIFT (31-14) -#define SDRAM0_BXCR_AM_SHIFT (31-18) - -#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) ) -#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) ) - -#ifdef CONFIG_SPDDRAM_SILENT -# define SPD_ERR(x) do { return 0; } while (0) -#else -# define SPD_ERR(x) do { printf(x); return(0); } while (0) -#endif - -#define sdram_HZ_to_ns(hertz) (1000000000/(hertz)) - -/* function prototypes */ -int spd_read(uint addr); - - -/* - * This function is reading data from the DIMM module EEPROM over the SPD bus - * and uses that to program the sdram controller. - * - * This works on boards that has the same schematics that the AMCC walnut has. - * - * Input: null for default I2C spd functions or a pointer to a custom function - * returning spd_data. - */ - -long int spd_sdram(int(read_spd)(uint addr)) -{ - int tmp,row,col; - int total_size,bank_size,bank_code; - int ecc_on; - int mode; - int bank_cnt; - - int sdram0_pmit=0x07c00000; -#ifndef CONFIG_405EP /* not on PPC405EP */ - int sdram0_besr0=-1; - int sdram0_besr1=-1; - int sdram0_eccesr=-1; -#endif - int sdram0_ecccfg; - - int sdram0_rtr=0; - int sdram0_tr=0; - - int sdram0_b0cr; - int sdram0_b1cr; - int sdram0_b2cr; - int sdram0_b3cr; - - int sdram0_cfg=0; - - int t_rp; - int t_rcd; - int t_ras; - int t_rc; - int min_cas; - - PPC405_SYS_INFO sys_info; - unsigned long bus_period_x_10; - - /* - * get the board info - */ - get_sys_info(&sys_info); - bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); - - if (read_spd == 0){ - read_spd=spd_read; - /* - * Make sure I2C controller is initialized - * before continuing. - */ - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); - } - - /* Make shure we are using SDRAM */ - if (read_spd(2) != 0x04) { - SPD_ERR("SDRAM - non SDRAM memory module found\n"); - } - - /* ------------------------------------------------------------------ - * configure memory timing register - * - * data from DIMM: - * 27 IN Row Precharge Time ( t RP) - * 29 MIN RAS to CAS Delay ( t RCD) - * 127 Component and Clock Detail ,clk0-clk3, junction temp, CAS - * -------------------------------------------------------------------*/ - - /* - * first figure out which cas latency mode to use - * use the min supported mode - */ - - tmp = read_spd(127) & 0x6; - if (tmp == 0x02) { /* only cas = 2 supported */ - min_cas = 2; -/* t_ck = read_spd(9); */ -/* t_ac = read_spd(10); */ - } else if (tmp == 0x04) { /* only cas = 3 supported */ - min_cas = 3; -/* t_ck = read_spd(9); */ -/* t_ac = read_spd(10); */ - } else if (tmp == 0x06) { /* 2,3 supported, so use 2 */ - min_cas = 2; -/* t_ck = read_spd(23); */ -/* t_ac = read_spd(24); */ - } else { - SPD_ERR("SDRAM - unsupported CAS latency \n"); - } - - /* get some timing values, t_rp,t_rcd,t_ras,t_rc - */ - t_rp = read_spd(27); - t_rcd = read_spd(29); - t_ras = read_spd(30); - t_rc = t_ras + t_rp; - - /* The following timing calcs subtract 1 before deviding. - * this has effect of using ceiling instead of floor rounding, - * and also subtracting 1 to convert number to reg value - */ - /* set up CASL */ - sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT; - /* set up PTA */ - sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT; - /* set up CTP */ - tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3; - if (tmp < 1) - tmp = 1; - sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT; - /* set LDF = 2 cycles, reg value = 1 */ - sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT; - /* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */ - tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3; - if (tmp < 0) - tmp = 0; - if (tmp > 6) - tmp = 6; - sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT; - /* set RCD = t_rcd/bus_period*/ - sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ; - - - /*------------------------------------------------------------------ - * configure RTR register - * -------------------------------------------------------------------*/ - row = read_spd(3); - col = read_spd(4); - tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */ - switch (tmp) { - case 0x00: - tmp = 15625; - break; - case 0x01: - tmp = 15625 / 4; - break; - case 0x02: - tmp = 15625 / 2; - break; - case 0x03: - tmp = 15625 * 2; - break; - case 0x04: - tmp = 15625 * 4; - break; - case 0x05: - tmp = 15625 * 8; - break; - default: - SPD_ERR("SDRAM - Bad refresh period \n"); - } - /* convert from nsec to bus cycles */ - tmp = (tmp * 10) / bus_period_x_10; - sdram0_rtr = (tmp & 0x3ff8) << SDRAM0_RTR_SHIFT; - - /*------------------------------------------------------------------ - * determine the number of banks used - * -------------------------------------------------------------------*/ - /* byte 7:6 is module data width */ - if (read_spd(7) != 0) - SPD_ERR("SDRAM - unsupported module width\n"); - tmp = read_spd(6); - if (tmp < 32) - SPD_ERR("SDRAM - unsupported module width\n"); - else if (tmp < 64) - bank_cnt = 1; /* one bank per sdram side */ - else if (tmp < 73) - bank_cnt = 2; /* need two banks per side */ - else if (tmp < 161) - bank_cnt = 4; /* need four banks per side */ - else - SPD_ERR("SDRAM - unsupported module width\n"); - - /* byte 5 is the module row count (refered to as dimm "sides") */ - tmp = read_spd(5); - if (tmp == 1) - ; - else if (tmp==2) - bank_cnt *= 2; - else if (tmp==4) - bank_cnt *= 4; - else - bank_cnt = 8; /* 8 is an error code */ - - if (bank_cnt > 4) /* we only have 4 banks to work with */ - SPD_ERR("SDRAM - unsupported module rows for this width\n"); - - /* now check for ECC ability of module. We only support ECC - * on 32 bit wide devices with 8 bit ECC. - */ - if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) { - sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT; - ecc_on = 1; - } else { - sdram0_ecccfg = 0; - ecc_on = 0; - } - - /*------------------------------------------------------------------ - * calculate total size - * -------------------------------------------------------------------*/ - /* calculate total size and do sanity check */ - tmp = read_spd(31); - total_size = 1 << 22; /* total_size = 4MB */ - /* now multiply 4M by the smallest device row density */ - /* note that we don't support asymetric rows */ - while (((tmp & 0x0001) == 0) && (tmp != 0)) { - total_size = total_size << 1; - tmp = tmp >> 1; - } - total_size *= read_spd(5); /* mult by module rows (dimm sides) */ - - /*------------------------------------------------------------------ - * map rows * cols * banks to a mode - * -------------------------------------------------------------------*/ - - switch (row) { - case 11: - switch (col) { - case 8: - mode=4; /* mode 5 */ - break; - case 9: - case 10: - mode=0; /* mode 1 */ - break; - default: - SPD_ERR("SDRAM - unsupported mode\n"); - } - break; - case 12: - switch (col) { - case 8: - mode=3; /* mode 4 */ - break; - case 9: - case 10: - mode=1; /* mode 2 */ - break; - default: - SPD_ERR("SDRAM - unsupported mode\n"); - } - break; - case 13: - switch (col) { - case 8: - mode=5; /* mode 6 */ - break; - case 9: - case 10: - if (read_spd(17) == 2) - mode = 6; /* mode 7 */ - else - mode = 2; /* mode 3 */ - break; - case 11: - mode = 2; /* mode 3 */ - break; - default: - SPD_ERR("SDRAM - unsupported mode\n"); - } - break; - default: - SPD_ERR("SDRAM - unsupported mode\n"); - } - - /*------------------------------------------------------------------ - * using the calculated values, compute the bank - * config register values. - * -------------------------------------------------------------------*/ - sdram0_b1cr = 0; - sdram0_b2cr = 0; - sdram0_b3cr = 0; - - /* compute the size of each bank */ - bank_size = total_size / bank_cnt; - /* convert bank size to bank size code for ppc4xx - by takeing log2(bank_size) - 22 */ - tmp = bank_size; /* start with tmp = bank_size */ - bank_code = 0; /* and bank_code = 0 */ - while (tmp > 1) { /* this takes log2 of tmp */ - bank_code++; /* and stores result in bank_code */ - tmp = tmp >> 1; - } /* bank_code is now log2(bank_size) */ - bank_code -= 22; /* subtract 22 to get the code */ - - tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1; - sdram0_b0cr = (bank_size * 0) | tmp; -#ifndef CONFIG_405EP /* not on PPC405EP */ - if (bank_cnt > 1) - sdram0_b2cr = (bank_size * 1) | tmp; - if (bank_cnt > 2) - sdram0_b1cr = (bank_size * 2) | tmp; - if (bank_cnt > 3) - sdram0_b3cr = (bank_size * 3) | tmp; -#else - /* PPC405EP chip only supports two SDRAM banks */ - if (bank_cnt > 1) - sdram0_b1cr = (bank_size * 1) | tmp; - if (bank_cnt > 2) - total_size = 2 * bank_size; -#endif - - /* - * enable sdram controller DCE=1 - * enable burst read prefetch to 32 bytes BRPF=2 - * leave other functions off - */ - - /*------------------------------------------------------------------ - * now that we've done our calculations, we are ready to - * program all the registers. - * -------------------------------------------------------------------*/ - -#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) - /* disable memcontroller so updates work */ - mtsdram0( mem_mcopt1, 0 ); - -#ifndef CONFIG_405EP /* not on PPC405EP */ - mtsdram0( mem_besra , sdram0_besr0 ); - mtsdram0( mem_besrb , sdram0_besr1 ); - mtsdram0( mem_ecccf , sdram0_ecccfg ); - mtsdram0( mem_eccerr, sdram0_eccesr ); -#endif - mtsdram0( mem_rtr , sdram0_rtr ); - mtsdram0( mem_pmit , sdram0_pmit ); - mtsdram0( mem_mb0cf , sdram0_b0cr ); - mtsdram0( mem_mb1cf , sdram0_b1cr ); -#ifndef CONFIG_405EP /* not on PPC405EP */ - mtsdram0( mem_mb2cf , sdram0_b2cr ); - mtsdram0( mem_mb3cf , sdram0_b3cr ); -#endif - mtsdram0( mem_sdtr1 , sdram0_tr ); - - /* SDRAM have a power on delay, 500 micro should do */ - udelay(500); - sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR; - if (ecc_on) - sdram0_cfg |= SDRAM0_CFG_MEMCHK; - mtsdram0(mem_mcopt1, sdram0_cfg); - - return (total_size); -} - -int spd_read(uint addr) -{ - uchar data[2]; - - if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0) - return (int)data[0]; - else - return 0; -} - -#else /* CONFIG_440 */ - /*----------------------------------------------------------------------------- | Memory Controller Options 0 +-----------------------------------------------------------------------------*/ @@ -1825,7 +1423,4 @@ void program_ecc (unsigned long num_bytes) SDRAM_CFG0_MCHK_CHK); } } - -#endif /* CONFIG_440 */ - #endif /* CONFIG_SPD_EEPROM */ diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c new file mode 100644 index 0000000000..ab421196b9 --- /dev/null +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -0,0 +1,2759 @@ +/* + * cpu/ppc4xx/44x_spd_ddr2.c + * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a + * DDR2 controller (non Denali Core). Those are 440SP/SPe. + * + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * COPYRIGHT AMCC CORPORATION 2004 + * + * 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 + * + */ + +/* define DEBUG for debugging output (obviously ;-)) */ +#if 0 +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_SPD_EEPROM) && \ + (defined(CONFIG_440SP) || defined(CONFIG_440SPE)) + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define SDRAM_DDR1 1 +#define SDRAM_DDR2 2 +#define SDRAM_NONE 0 + +#define MAXDIMMS 2 +#define MAXRANKS 4 +#define MAXBXCF 4 +#define MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */ + +#define ONE_BILLION 1000000000 + +#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d)) + +#if defined(DEBUG) +static void ppc440sp_sdram_register_dump(void); +#endif + +/*-----------------------------------------------------------------------------+ + * Defines + *-----------------------------------------------------------------------------*/ +/* Defines for the Read Cycle Delay test */ +#define NUMMEMTESTS 8 +#define NUMMEMWORDS 8 + +/* Private Structure Definitions */ + +/* enum only to ease code for cas latency setting */ +typedef enum ddr_cas_id { + DDR_CAS_2 = 20, + DDR_CAS_2_5 = 25, + DDR_CAS_3 = 30, + DDR_CAS_4 = 40, + DDR_CAS_5 = 50 +} ddr_cas_id_t; + +/*-----------------------------------------------------------------------------+ + * Prototypes + *-----------------------------------------------------------------------------*/ +static unsigned long sdram_memsize(void); +void program_tlb(u32 start, u32 size); +static void get_spd_info(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_mem_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_frequency(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_rank_number(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void check_voltage_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_memory_queue(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_codt(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_mode(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks, + ddr_cas_id_t *selected_cas); +static void program_tr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_rtr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_bxcf(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_copt1(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_initplr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks, + ddr_cas_id_t selected_cas); +static unsigned long is_ecc_enabled(void); +static void program_ecc(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); +static void program_ecc_addr(unsigned long start_address, + unsigned long num_bytes); + +#ifdef HARD_CODED_DQS /* calibration test with hardvalues */ +static void test(void); +#else +static void DQS_calibration_process(void); +#endif +static void program_DQS_calibration(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); + +static u32 mfdcr_any(u32 dcr) +{ + u32 val; + + switch (dcr) { + case SDRAM_R0BAS + 0: + val = mfdcr(SDRAM_R0BAS + 0); + break; + case SDRAM_R0BAS + 1: + val = mfdcr(SDRAM_R0BAS + 1); + break; + case SDRAM_R0BAS + 2: + val = mfdcr(SDRAM_R0BAS + 2); + break; + case SDRAM_R0BAS + 3: + val = mfdcr(SDRAM_R0BAS + 3); + break; + default: + printf("DCR %d not defined in case statement!!!\n", dcr); + val = 0; /* just to satisfy the compiler */ + } + + return val; +} + +static void mtdcr_any(u32 dcr, u32 val) +{ + switch (dcr) { + case SDRAM_R0BAS + 0: + mtdcr(SDRAM_R0BAS + 0, val); + break; + case SDRAM_R0BAS + 1: + mtdcr(SDRAM_R0BAS + 1, val); + break; + case SDRAM_R0BAS + 2: + mtdcr(SDRAM_R0BAS + 2, val); + break; + case SDRAM_R0BAS + 3: + mtdcr(SDRAM_R0BAS + 3, val); + break; + default: + printf("DCR %d not defined in case statement!!!\n", dcr); + } +} + +static void wait_ddr_idle(void) +{ + u32 val; + + do { + mfsdram(SDRAM_MCSTAT, val); + } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT); +} + +static unsigned char spd_read(uchar chip, uint addr) +{ + unsigned char data[2]; + + if (i2c_probe(chip) == 0) + if (i2c_read(chip, addr, 1, data, 1) == 0) + return data[0]; + + return 0; +} + +/*-----------------------------------------------------------------------------+ + * sdram_memsize + *-----------------------------------------------------------------------------*/ +static unsigned long sdram_memsize(void) +{ + unsigned long mem_size; + unsigned long mcopt2; + unsigned long mcstat; + unsigned long mb0cf; + unsigned long sdsz; + unsigned long i; + + mem_size = 0; + + mfsdram(SDRAM_MCOPT2, mcopt2); + mfsdram(SDRAM_MCSTAT, mcstat); + + /* DDR controller must be enabled and not in self-refresh. */ + /* Otherwise memsize is zero. */ + if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE) + && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT) + && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK)) + == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) { + for (i = 0; i < 4; i++) { + mfsdram(SDRAM_MB0CF + (i << 2), mb0cf); + /* Banks enabled */ + if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { + sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK; + + switch(sdsz) { + case SDRAM_RXBAS_SDSZ_8: + mem_size+=8; + break; + case SDRAM_RXBAS_SDSZ_16: + mem_size+=16; + break; + case SDRAM_RXBAS_SDSZ_32: + mem_size+=32; + break; + case SDRAM_RXBAS_SDSZ_64: + mem_size+=64; + break; + case SDRAM_RXBAS_SDSZ_128: + mem_size+=128; + break; + case SDRAM_RXBAS_SDSZ_256: + mem_size+=256; + break; + case SDRAM_RXBAS_SDSZ_512: + mem_size+=512; + break; + case SDRAM_RXBAS_SDSZ_1024: + mem_size+=1024; + break; + case SDRAM_RXBAS_SDSZ_2048: + mem_size+=2048; + break; + case SDRAM_RXBAS_SDSZ_4096: + mem_size+=4096; + break; + default: + mem_size=0; + break; + } + } + } + } + + mem_size *= 1024 * 1024; + return(mem_size); +} + +/*-----------------------------------------------------------------------------+ + * initdram. Initializes the 440SP Memory Queue and DDR SDRAM controller. + * Note: This routine runs from flash with a stack set up in the chip's + * sram space. It is important that the routine does not require .sbss, .bss or + * .data sections. It also cannot call routines that require these sections. + *-----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------- + * Function: initdram + * Description: Configures SDRAM memory banks for DDR operation. + * Auto Memory Configuration option reads the DDR SDRAM EEPROMs + * via the IIC bus and then configures the DDR SDRAM memory + * banks appropriately. If Auto Memory Configuration is + * not used, it is assumed that no DIMM is plugged + *-----------------------------------------------------------------------------*/ +long int initdram(int board_type) +{ + unsigned char spd0[MAX_SPD_BYTES]; + unsigned char spd1[MAX_SPD_BYTES]; + unsigned char *dimm_spd[MAXDIMMS]; + unsigned long dimm_populated[MAXDIMMS]; + unsigned char iic0_dimm_addr[MAXDIMMS]; + unsigned long num_dimm_banks; /* on board dimm banks */ + unsigned long val; + ddr_cas_id_t selected_cas; + unsigned long dram_size = 0; + + num_dimm_banks = sizeof(iic0_dimm_addr); + + /*------------------------------------------------------------------ + * Set up an array of SPD matrixes. + *-----------------------------------------------------------------*/ + dimm_spd[0] = spd0; + dimm_spd[1] = spd1; + + /*------------------------------------------------------------------ + * Set up an array of iic0 dimm addresses. + *-----------------------------------------------------------------*/ + iic0_dimm_addr[0] = IIC0_DIMM0_ADDR; + iic0_dimm_addr[1] = IIC0_DIMM1_ADDR; + + /*------------------------------------------------------------------ + * Reset the DDR-SDRAM controller. + *-----------------------------------------------------------------*/ + mtsdr(SDR0_SRST, 0x00200000); + mtsdr(SDR0_SRST, 0x00000000); + + /* + * Make sure I2C controller is initialized + * before continuing. + */ + + /* switch to correct I2C bus */ + I2C_SET_BUS(CFG_SPD_BUS_NUM); + i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /*------------------------------------------------------------------ + * Clear out the serial presence detect buffers. + * Perform IIC reads from the dimm. Fill in the spds. + * Check to see if the dimm slots are populated + *-----------------------------------------------------------------*/ + get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Check the memory type for the dimms plugged. + *-----------------------------------------------------------------*/ + check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Check the frequency supported for the dimms plugged. + *-----------------------------------------------------------------*/ + check_frequency(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Check the total rank number. + *-----------------------------------------------------------------*/ + check_rank_number(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Check the voltage type for the dimms plugged. + *-----------------------------------------------------------------*/ + check_voltage_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Program SDRAM controller options 2 register + * Except Enabling of the memory controller. + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT2, val); + mtsdram(SDRAM_MCOPT2, + (val & + ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_PMEN_MASK | + SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_XSRP_MASK | + SDRAM_MCOPT2_ISIE_MASK)) + | (SDRAM_MCOPT2_SREN_ENTER | SDRAM_MCOPT2_PMEN_DISABLE | + SDRAM_MCOPT2_IPTR_IDLE | SDRAM_MCOPT2_XSRP_ALLOW | + SDRAM_MCOPT2_ISIE_ENABLE)); + + /*------------------------------------------------------------------ + * Program SDRAM controller options 1 register + * Note: Does not enable the memory controller. + *-----------------------------------------------------------------*/ + program_copt1(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Set the SDRAM Controller On Die Termination Register + *-----------------------------------------------------------------*/ + program_codt(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Program SDRAM refresh register. + *-----------------------------------------------------------------*/ + program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Program SDRAM mode register. + *-----------------------------------------------------------------*/ + program_mode(dimm_populated, iic0_dimm_addr, num_dimm_banks, &selected_cas); + + /*------------------------------------------------------------------ + * Set the SDRAM Write Data/DM/DQS Clock Timing Reg + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_WRDTR, val); + mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) | + (SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV)); + + /*------------------------------------------------------------------ + * Set the SDRAM Clock Timing Register + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_CLKTR, val); + mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_0_DEG); + + /*------------------------------------------------------------------ + * Program the BxCF registers. + *-----------------------------------------------------------------*/ + program_bxcf(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Program SDRAM timing registers. + *-----------------------------------------------------------------*/ + program_tr(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Set the Extended Mode register + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MEMODE, val); + mtsdram(SDRAM_MEMODE, + (val & ~(SDRAM_MEMODE_DIC_MASK | SDRAM_MEMODE_DLL_MASK | + SDRAM_MEMODE_RTT_MASK | SDRAM_MEMODE_DQS_MASK)) | + (SDRAM_MEMODE_DIC_NORMAL | SDRAM_MEMODE_DLL_ENABLE + | SDRAM_MEMODE_RTT_75OHM | SDRAM_MEMODE_DQS_ENABLE)); + + /*------------------------------------------------------------------ + * Program Initialization preload registers. + *-----------------------------------------------------------------*/ + program_initplr(dimm_populated, iic0_dimm_addr, num_dimm_banks, + selected_cas); + + /*------------------------------------------------------------------ + * Delay to ensure 200usec have elapsed since reset. + *-----------------------------------------------------------------*/ + udelay(400); + + /*------------------------------------------------------------------ + * Set the memory queue core base addr. + *-----------------------------------------------------------------*/ + program_memory_queue(dimm_populated, iic0_dimm_addr, num_dimm_banks); + + /*------------------------------------------------------------------ + * Program SDRAM controller options 2 register + * Enable the memory controller. + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT2, val); + mtsdram(SDRAM_MCOPT2, + (val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK | + SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) | + (SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE)); + + /*------------------------------------------------------------------ + * Wait for SDRAM_CFG0_DC_EN to complete. + *-----------------------------------------------------------------*/ + do { + mfsdram(SDRAM_MCSTAT, val); + } while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP); + + /* get installed memory size */ + dram_size = sdram_memsize(); + + /* and program tlb entries for this size (dynamic) */ + program_tlb(0, dram_size); + +#if 1 /* TODO: ECC support will come later */ + /*------------------------------------------------------------------ + * If ecc is enabled, initialize the parity bits. + *-----------------------------------------------------------------*/ + program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks); +#endif + + /*------------------------------------------------------------------ + * DQS calibration. + *-----------------------------------------------------------------*/ + program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks); + +#ifdef DEBUG + ppc440sp_sdram_register_dump(); +#endif + + return dram_size; +} + +static void get_spd_info(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long dimm_found; + unsigned char num_of_bytes; + unsigned char total_size; + + dimm_found = FALSE; + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + num_of_bytes = 0; + total_size = 0; + + num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); + debug("\nspd_read(0x%x) returned %d\n", + iic0_dimm_addr[dimm_num], num_of_bytes); + total_size = spd_read(iic0_dimm_addr[dimm_num], 1); + debug("spd_read(0x%x) returned %d\n", + iic0_dimm_addr[dimm_num], total_size); + + if ((num_of_bytes != 0) && (total_size != 0)) { + dimm_populated[dimm_num] = TRUE; + dimm_found = TRUE; + debug("DIMM slot %lu: populated\n", dimm_num); + } else { + dimm_populated[dimm_num] = FALSE; + debug("DIMM slot %lu: Not populated\n", dimm_num); + } + } + + if (dimm_found == FALSE) { + printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); + hang(); + } +} + +#ifdef CONFIG_ADD_RAM_INFO +void board_add_ram_info(int use_default) +{ + if (is_ecc_enabled()) + puts(" (ECC enabled)"); + else + puts(" (ECC not enabled)"); +} +#endif + +/*------------------------------------------------------------------ + * For the memory DIMMs installed, this routine verifies that they + * really are DDR specific DIMMs. + *-----------------------------------------------------------------*/ +static void check_mem_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long dimm_type; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] == TRUE) { + dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); + switch (dimm_type) { + case 1: + printf("ERROR: Standard Fast Page Mode DRAM DIMM detected in " + "slot %d.\n", (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 2: + printf("ERROR: EDO DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 3: + printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 4: + printf("ERROR: SDRAM DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 5: + printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 6: + printf("ERROR: SGRAM DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + case 7: + debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num); + dimm_populated[dimm_num] = SDRAM_DDR1; + break; + case 8: + debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num); + dimm_populated[dimm_num] = SDRAM_DDR2; + break; + default: + printf("ERROR: Unknown DIMM detected in slot %d.\n", + (unsigned int)dimm_num); + printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n"); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + } + } + } + for (dimm_num = 1; dimm_num < num_dimm_banks; dimm_num++) { + if ((dimm_populated[dimm_num-1] != SDRAM_NONE) + && (dimm_populated[dimm_num] != SDRAM_NONE) + && (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) { + printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n"); + hang(); + } + } +} + +/*------------------------------------------------------------------ + * For the memory DIMMs installed, this routine verifies that + * frequency previously calculated is supported. + *-----------------------------------------------------------------*/ +static void check_frequency(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long tcyc_reg; + unsigned long cycle_time; + unsigned long calc_cycle_time; + unsigned long sdram_freq; + unsigned long sdr_ddrpll; + PPC440_SYS_INFO board_cfg; + + /*------------------------------------------------------------------ + * Get the board configuration info. + *-----------------------------------------------------------------*/ + get_sys_info(&board_cfg); + + mfsdr(sdr_ddr0, sdr_ddrpll); + sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll)); + + /* + * calc_cycle_time is calculated from DDR frequency set by board/chip + * and is expressed in multiple of 10 picoseconds + * to match the way DIMM cycle time is calculated below. + */ + calc_cycle_time = MULDIV64(ONE_BILLION, 100, sdram_freq); + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); + /* + * Byte 9, Cycle time for CAS Latency=X, is split into two nibbles: + * the higher order nibble (bits 4-7) designates the cycle time + * to a granularity of 1ns; + * the value presented by the lower order nibble (bits 0-3) + * has a granularity of .1ns and is added to the value designated + * by the higher nibble. In addition, four lines of the lower order + * nibble are assigned to support +.25,+.33, +.66 and +.75. + */ + /* Convert from hex to decimal */ + if ((tcyc_reg & 0x0F) == 0x0D) + cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 75; + else if ((tcyc_reg & 0x0F) == 0x0C) + cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 66; + else if ((tcyc_reg & 0x0F) == 0x0B) + cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 33; + else if ((tcyc_reg & 0x0F) == 0x0A) + cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 25; + else + cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + + ((tcyc_reg & 0x0F)*10); + + if (cycle_time > (calc_cycle_time + 10)) { + /* + * the provided sdram cycle_time is too small + * for the available DIMM cycle_time. + * The additionnal 100ps is here to accept a small incertainty. + */ + printf("ERROR: DRAM DIMM detected with cycle_time %d ps in " + "slot %d \n while calculated cycle time is %d ps.\n", + (unsigned int)(cycle_time*10), + (unsigned int)dimm_num, + (unsigned int)(calc_cycle_time*10)); + printf("Replace the DIMM, or change DDR frequency via " + "strapping bits.\n\n"); + hang(); + } + } + } +} + +/*------------------------------------------------------------------ + * For the memory DIMMs installed, this routine verifies two + * ranks/banks maximum are availables. + *-----------------------------------------------------------------*/ +static void check_rank_number(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long dimm_rank; + unsigned long total_rank = 0; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + dimm_rank = spd_read(iic0_dimm_addr[dimm_num], 5); + if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) + dimm_rank = (dimm_rank & 0x0F) +1; + else + dimm_rank = dimm_rank & 0x0F; + + + if (dimm_rank > MAXRANKS) { + printf("ERROR: DRAM DIMM detected with %d ranks in " + "slot %d is not supported.\n", dimm_rank, dimm_num); + printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + } else + total_rank += dimm_rank; + } + if (total_rank > MAXRANKS) { + printf("ERROR: DRAM DIMM detected with a total of %d ranks " + "for all slots.\n", (unsigned int)total_rank); + printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS); + printf("Remove one of the DIMM modules.\n\n"); + hang(); + } + } +} + +/*------------------------------------------------------------------ + * only support 2.5V modules. + * This routine verifies this. + *-----------------------------------------------------------------*/ +static void check_voltage_type(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long voltage_type; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); + switch (voltage_type) { + case 0x00: + printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); + printf("This DIMM is 5.0 Volt/TTL.\n"); + printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", + (unsigned int)dimm_num); + hang(); + break; + case 0x01: + printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); + printf("This DIMM is LVTTL.\n"); + printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", + (unsigned int)dimm_num); + hang(); + break; + case 0x02: + printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); + printf("This DIMM is 1.5 Volt.\n"); + printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", + (unsigned int)dimm_num); + hang(); + break; + case 0x03: + printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); + printf("This DIMM is 3.3 Volt/TTL.\n"); + printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", + (unsigned int)dimm_num); + hang(); + break; + case 0x04: + /* 2.5 Voltage only for DDR1 */ + break; + case 0x05: + /* 1.8 Voltage only for DDR2 */ + break; + default: + printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); + printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", + (unsigned int)dimm_num); + hang(); + break; + } + } + } +} + +/*-----------------------------------------------------------------------------+ + * program_copt1. + *-----------------------------------------------------------------------------*/ +static void program_copt1(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long mcopt1; + unsigned long ecc_enabled; + unsigned long ecc = 0; + unsigned long data_width = 0; + unsigned long dimm_32bit; + unsigned long dimm_64bit; + unsigned long registered = 0; + unsigned long attribute = 0; + unsigned long buf0, buf1; /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */ + unsigned long bankcount; + unsigned long ddrtype; + unsigned long val; + + ecc_enabled = TRUE; + dimm_32bit = FALSE; + dimm_64bit = FALSE; + buf0 = FALSE; + buf1 = FALSE; + + /*------------------------------------------------------------------ + * Set memory controller options reg 1, SDRAM_MCOPT1. + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT1, val); + mcopt1 = val & ~(SDRAM_MCOPT1_MCHK_MASK | SDRAM_MCOPT1_RDEN_MASK | + SDRAM_MCOPT1_PMU_MASK | SDRAM_MCOPT1_DMWD_MASK | + SDRAM_MCOPT1_UIOS_MASK | SDRAM_MCOPT1_BCNT_MASK | + SDRAM_MCOPT1_DDR_TYPE_MASK | SDRAM_MCOPT1_RWOO_MASK | + SDRAM_MCOPT1_WOOO_MASK | SDRAM_MCOPT1_DCOO_MASK | + SDRAM_MCOPT1_DREF_MASK); + + mcopt1 |= SDRAM_MCOPT1_QDEP; + mcopt1 |= SDRAM_MCOPT1_PMU_OPEN; + mcopt1 |= SDRAM_MCOPT1_RWOO_DISABLED; + mcopt1 |= SDRAM_MCOPT1_WOOO_DISABLED; + mcopt1 |= SDRAM_MCOPT1_DCOO_DISABLED; + mcopt1 |= SDRAM_MCOPT1_DREF_NORMAL; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + /* test ecc support */ + ecc = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 11); + if (ecc != 0x02) /* ecc not supported */ + ecc_enabled = FALSE; + + /* test bank count */ + bankcount = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 17); + if (bankcount == 0x04) /* bank count = 4 */ + mcopt1 |= SDRAM_MCOPT1_4_BANKS; + else /* bank count = 8 */ + mcopt1 |= SDRAM_MCOPT1_8_BANKS; + + /* test DDR type */ + ddrtype = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2); + /* test for buffered/unbuffered, registered, differential clocks */ + registered = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 20); + attribute = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 21); + + /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */ + if (dimm_num == 0) { + if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ + mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; + if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ + mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; + if (registered == 1) { /* DDR2 always buffered */ + /* TODO: what about above comments ? */ + mcopt1 |= SDRAM_MCOPT1_RDEN; + buf0 = TRUE; + } else { + /* TODO: the mask 0x02 doesn't match Samsung def for byte 21. */ + if ((attribute & 0x02) == 0x00) { + /* buffered not supported */ + buf0 = FALSE; + } else { + mcopt1 |= SDRAM_MCOPT1_RDEN; + buf0 = TRUE; + } + } + } + else if (dimm_num == 1) { + if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ + mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; + if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ + mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; + if (registered == 1) { + /* DDR2 always buffered */ + mcopt1 |= SDRAM_MCOPT1_RDEN; + buf1 = TRUE; + } else { + if ((attribute & 0x02) == 0x00) { + /* buffered not supported */ + buf1 = FALSE; + } else { + mcopt1 |= SDRAM_MCOPT1_RDEN; + buf1 = TRUE; + } + } + } + + /* Note that for DDR2 the byte 7 is reserved, but OK to keep code as is. */ + data_width = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 6) + + (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 7)) << 8); + + switch (data_width) { + case 72: + case 64: + dimm_64bit = TRUE; + break; + case 40: + case 32: + dimm_32bit = TRUE; + break; + default: + printf("WARNING: Detected a DIMM with a data width of %d bits.\n", + data_width); + printf("Only DIMMs with 32 or 64 bit DDR-SDRAM widths are supported.\n"); + break; + } + } + } + + /* verify matching properties */ + if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) { + if (buf0 != buf1) { + printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n"); + hang(); + } + } + + if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) { + printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n"); + hang(); + } + else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) { + mcopt1 |= SDRAM_MCOPT1_DMWD_64; + } else if ((dimm_64bit == FALSE) && (dimm_32bit == TRUE)) { + mcopt1 |= SDRAM_MCOPT1_DMWD_32; + } else { + printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n"); + hang(); + } + + if (ecc_enabled == TRUE) + mcopt1 |= SDRAM_MCOPT1_MCHK_GEN; + else + mcopt1 |= SDRAM_MCOPT1_MCHK_NON; + + mtsdram(SDRAM_MCOPT1, mcopt1); +} + +/*-----------------------------------------------------------------------------+ + * program_codt. + *-----------------------------------------------------------------------------*/ +static void program_codt(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long codt; + unsigned long modt0 = 0; + unsigned long modt1 = 0; + unsigned long modt2 = 0; + unsigned long modt3 = 0; + unsigned char dimm_num; + unsigned char dimm_rank; + unsigned char total_rank = 0; + unsigned char total_dimm = 0; + unsigned char dimm_type = 0; + unsigned char firstSlot = 0; + + /*------------------------------------------------------------------ + * Set the SDRAM Controller On Die Termination Register + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_CODT, codt); + codt |= (SDRAM_CODT_IO_NMODE + & (~SDRAM_CODT_DQS_SINGLE_END + & ~SDRAM_CODT_CKSE_SINGLE_END + & ~SDRAM_CODT_FEEBBACK_RCV_SINGLE_END + & ~SDRAM_CODT_FEEBBACK_DRV_SINGLE_END)); + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + dimm_rank = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 5); + if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) { + dimm_rank = (dimm_rank & 0x0F) + 1; + dimm_type = SDRAM_DDR2; + } else { + dimm_rank = dimm_rank & 0x0F; + dimm_type = SDRAM_DDR1; + } + + total_rank += dimm_rank; + total_dimm ++; + if ((dimm_num == 0) && (total_dimm == 1)) + firstSlot = TRUE; + else + firstSlot = FALSE; + } + } + if (dimm_type == SDRAM_DDR2) { + codt |= SDRAM_CODT_DQS_1_8_V_DDR2; + if ((total_dimm == 1) && (firstSlot == TRUE)) { + if (total_rank == 1) { + codt |= 0x00800000; + modt0 = 0x01000000; + modt1 = 0x00000000; + modt2 = 0x00000000; + modt3 = 0x00000000; + } + if (total_rank == 2) { + codt |= 0x02800000; + modt0 = 0x06000000; + modt1 = 0x01800000; + modt2 = 0x00000000; + modt3 = 0x00000000; + } + } else { + if (total_rank == 1) { + codt |= 0x00800000; + modt0 = 0x01000000; + modt1 = 0x00000000; + modt2 = 0x00000000; + modt3 = 0x00000000; + } + if (total_rank == 2) { + codt |= 0x02800000; + modt0 = 0x06000000; + modt1 = 0x01800000; + modt2 = 0x00000000; + modt3 = 0x00000000; + } + } + if (total_dimm == 2) { + if (total_rank == 2) { + codt |= 0x08800000; + modt0 = 0x18000000; + modt1 = 0x00000000; + modt2 = 0x01800000; + modt3 = 0x00000000; + } + if (total_rank == 4) { + codt |= 0x2a800000; + modt0 = 0x18000000; + modt1 = 0x18000000; + modt2 = 0x01800000; + modt3 = 0x01800000; + } + } + } else { + codt |= SDRAM_CODT_DQS_2_5_V_DDR1; + modt0 = 0x00000000; + modt1 = 0x00000000; + modt2 = 0x00000000; + modt3 = 0x00000000; + + if (total_dimm == 1) { + if (total_rank == 1) + codt |= 0x00800000; + if (total_rank == 2) + codt |= 0x02800000; + } + if (total_dimm == 2) { + if (total_rank == 2) + codt |= 0x08800000; + if (total_rank == 4) + codt |= 0x2a800000; + } + } + + debug("nb of dimm %d\n", total_dimm); + debug("nb of rank %d\n", total_rank); + if (total_dimm == 1) + debug("dimm in slot %d\n", firstSlot); + + mtsdram(SDRAM_CODT, codt); + mtsdram(SDRAM_MODT0, modt0); + mtsdram(SDRAM_MODT1, modt1); + mtsdram(SDRAM_MODT2, modt2); + mtsdram(SDRAM_MODT3, modt3); +} + +/*-----------------------------------------------------------------------------+ + * program_initplr. + *-----------------------------------------------------------------------------*/ +static void program_initplr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks, + ddr_cas_id_t selected_cas) +{ + unsigned long MR_CAS_value = 0; + + /****************************************************** + ** Assumption: if more than one DIMM, all DIMMs are the same + ** as already checked in check_memory_type + ******************************************************/ + + if ((dimm_populated[0] == SDRAM_DDR1) || (dimm_populated[1] == SDRAM_DDR1)) { + mtsdram(SDRAM_INITPLR0, 0x81B80000); + mtsdram(SDRAM_INITPLR1, 0x81900400); + mtsdram(SDRAM_INITPLR2, 0x81810000); + mtsdram(SDRAM_INITPLR3, 0xff800162); + mtsdram(SDRAM_INITPLR4, 0x81900400); + mtsdram(SDRAM_INITPLR5, 0x86080000); + mtsdram(SDRAM_INITPLR6, 0x86080000); + mtsdram(SDRAM_INITPLR7, 0x81000062); + } else if ((dimm_populated[0] == SDRAM_DDR2) || (dimm_populated[1] == SDRAM_DDR2)) { + switch (selected_cas) { + /* + * The CAS latency is a field of the Mode Reg + * that need to be set from caller input. + * CAS bits in Mode Reg are starting at bit 4 at least for the Micron DDR2 + * this is the reason of the shift. + */ + case DDR_CAS_3: + MR_CAS_value = 3 << 4; + break; + case DDR_CAS_4: + MR_CAS_value = 4 << 4; + break; + case DDR_CAS_5: + MR_CAS_value = 5 << 4; + break; + default: + printf("ERROR: ucode error on selected_cas value %d", (unsigned char)selected_cas); + hang(); + break; + } + + mtsdram(SDRAM_INITPLR0, 0xB5380000); /* NOP */ + mtsdram(SDRAM_INITPLR1, 0x82100400); /* precharge 8 DDR clock cycle */ + mtsdram(SDRAM_INITPLR2, 0x80820000); /* EMR2 */ + mtsdram(SDRAM_INITPLR3, 0x80830000); /* EMR3 */ + mtsdram(SDRAM_INITPLR4, 0x80810000); /* EMR DLL ENABLE */ + mtsdram(SDRAM_INITPLR5, 0x80800502 | MR_CAS_value); /* MR w/ DLL reset */ + mtsdram(SDRAM_INITPLR6, 0x82100400); /* precharge 8 DDR clock cycle */ + mtsdram(SDRAM_INITPLR7, 0x8a080000); /* Refresh 50 DDR clock cycle */ + mtsdram(SDRAM_INITPLR8, 0x8a080000); /* Refresh 50 DDR clock cycle */ + mtsdram(SDRAM_INITPLR9, 0x8a080000); /* Refresh 50 DDR clock cycle */ + mtsdram(SDRAM_INITPLR10, 0x8a080000); /* Refresh 50 DDR clock cycle */ + mtsdram(SDRAM_INITPLR11, 0x80800402 | MR_CAS_value); /* MR w/o DLL reset */ + mtsdram(SDRAM_INITPLR12, 0x80810380); /* EMR OCD Default */ + mtsdram(SDRAM_INITPLR13, 0x80810000); /* EMR OCD Exit */ + } else { + printf("ERROR: ucode error as unknown DDR type in program_initplr"); + hang(); + } +} + +/*------------------------------------------------------------------ + * This routine programs the SDRAM_MMODE register. + * the selected_cas is an output parameter, that will be passed + * by caller to call the above program_initplr( ) + *-----------------------------------------------------------------*/ +static void program_mode(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks, + ddr_cas_id_t *selected_cas) +{ + unsigned long dimm_num; + unsigned long sdram_ddr1; + unsigned long t_wr_ns; + unsigned long t_wr_clk; + unsigned long cas_bit; + unsigned long cas_index; + unsigned long sdram_freq; + unsigned long ddr_check; + unsigned long mmode; + unsigned long tcyc_reg; + unsigned long cycle_2_0_clk; + unsigned long cycle_2_5_clk; + unsigned long cycle_3_0_clk; + unsigned long cycle_4_0_clk; + unsigned long cycle_5_0_clk; + unsigned long max_2_0_tcyc_ns_x_100; + unsigned long max_2_5_tcyc_ns_x_100; + unsigned long max_3_0_tcyc_ns_x_100; + unsigned long max_4_0_tcyc_ns_x_100; + unsigned long max_5_0_tcyc_ns_x_100; + unsigned long cycle_time_ns_x_100[3]; + PPC440_SYS_INFO board_cfg; + unsigned char cas_2_0_available; + unsigned char cas_2_5_available; + unsigned char cas_3_0_available; + unsigned char cas_4_0_available; + unsigned char cas_5_0_available; + unsigned long sdr_ddrpll; + + /*------------------------------------------------------------------ + * Get the board configuration info. + *-----------------------------------------------------------------*/ + get_sys_info(&board_cfg); + + mfsdr(sdr_ddr0, sdr_ddrpll); + sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1); + + /*------------------------------------------------------------------ + * Handle the timing. We need to find the worst case timing of all + * the dimm modules installed. + *-----------------------------------------------------------------*/ + t_wr_ns = 0; + cas_2_0_available = TRUE; + cas_2_5_available = TRUE; + cas_3_0_available = TRUE; + cas_4_0_available = TRUE; + cas_5_0_available = TRUE; + max_2_0_tcyc_ns_x_100 = 10; + max_2_5_tcyc_ns_x_100 = 10; + max_3_0_tcyc_ns_x_100 = 10; + max_4_0_tcyc_ns_x_100 = 10; + max_5_0_tcyc_ns_x_100 = 10; + sdram_ddr1 = TRUE; + + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + /* If a dimm is installed in a particular slot ... */ + if (dimm_populated[dimm_num] != SDRAM_NONE) { + if (dimm_populated[dimm_num] == SDRAM_DDR1) + sdram_ddr1 = TRUE; + else + sdram_ddr1 = FALSE; + + /* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /* not used in this loop. */ + cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); + + /* For a particular DIMM, grab the three CAS values it supports */ + for (cas_index = 0; cas_index < 3; cas_index++) { + switch (cas_index) { + case 0: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); + break; + case 1: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23); + break; + default: + tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25); + break; + } + + if ((tcyc_reg & 0x0F) >= 10) { + if ((tcyc_reg & 0x0F) == 0x0D) { + /* Convert from hex to decimal */ + cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + 75; + } else { + printf("ERROR: SPD reported Tcyc is incorrect for DIMM " + "in slot %d\n", (unsigned int)dimm_num); + hang(); + } + } else { + /* Convert from hex to decimal */ + cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + + ((tcyc_reg & 0x0F)*10); + } + } + + /* The rest of this routine determines if CAS 2.0, 2.5, 3.0, 4.0 and 5.0 are */ + /* supported for a particular DIMM. */ + cas_index = 0; + + if (sdram_ddr1) { + /* + * DDR devices use the following bitmask for CAS latency: + * Bit 7 6 5 4 3 2 1 0 + * TBD 4.0 3.5 3.0 2.5 2.0 1.5 1.0 + */ + if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_4_0_available = FALSE; + } + + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_3_0_available = FALSE; + } + + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_2_5_available = FALSE; + } + + if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_2_0_available = FALSE; + } + } else { + /* + * DDR2 devices use the following bitmask for CAS latency: + * Bit 7 6 5 4 3 2 1 0 + * TBD 6.0 5.0 4.0 3.0 2.0 TBD TBD + */ + if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_5_0_available = FALSE; + } + + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_4_0_available = FALSE; + } + + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + cas_index++; + } else { + if (cas_index != 0) + cas_index++; + cas_3_0_available = FALSE; + } + } + } + } + + /*------------------------------------------------------------------ + * Set the SDRAM mode, SDRAM_MMODE + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MMODE, mmode); + mmode = mmode & ~(SDRAM_MMODE_WR_MASK | SDRAM_MMODE_DCL_MASK); + + cycle_2_0_clk = MULDIV64(ONE_BILLION, 100, max_2_0_tcyc_ns_x_100); + cycle_2_5_clk = MULDIV64(ONE_BILLION, 100, max_2_5_tcyc_ns_x_100); + cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100); + cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100); + cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100); + + if (sdram_ddr1 == TRUE) { /* DDR1 */ + if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR1_2_0_CLK; + *selected_cas = DDR_CAS_2; + } else if ((cas_2_5_available == TRUE) && (sdram_freq <= cycle_2_5_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR1_2_5_CLK; + *selected_cas = DDR_CAS_2_5; + } else if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR1_3_0_CLK; + *selected_cas = DDR_CAS_3; + } else { + printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n"); + printf("Only DIMMs DDR1 with CAS latencies of 2.0, 2.5, and 3.0 are supported.\n"); + printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n"); + hang(); + } + } else { /* DDR2 */ + if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR2_3_0_CLK; + *selected_cas = DDR_CAS_3; + } else if ((cas_4_0_available == TRUE) && (sdram_freq <= cycle_4_0_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR2_4_0_CLK; + *selected_cas = DDR_CAS_4; + } else if ((cas_5_0_available == TRUE) && (sdram_freq <= cycle_5_0_clk)) { + mmode |= SDRAM_MMODE_DCL_DDR2_5_0_CLK; + *selected_cas = DDR_CAS_5; + } else { + printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n"); + printf("Only DIMMs DDR2 with CAS latencies of 3.0, 4.0, and 5.0 are supported.\n"); + printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n"); + hang(); + } + } + + if (sdram_ddr1 == TRUE) + mmode |= SDRAM_MMODE_WR_DDR1; + else { + + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + /* If a dimm is installed in a particular slot ... */ + if (dimm_populated[dimm_num] != SDRAM_NONE) + t_wr_ns = max(t_wr_ns, + spd_read(iic0_dimm_addr[dimm_num], 36) >> 2); + } + + /* + * convert from nanoseconds to ddr clocks + * round up if necessary + */ + t_wr_clk = MULDIV64(sdram_freq, t_wr_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_wr_clk, t_wr_ns); + if (sdram_freq != ddr_check) + t_wr_clk++; + + switch (t_wr_clk) { + case 0: + case 1: + case 2: + case 3: + mmode |= SDRAM_MMODE_WR_DDR2_3_CYC; + break; + case 4: + mmode |= SDRAM_MMODE_WR_DDR2_4_CYC; + break; + case 5: + mmode |= SDRAM_MMODE_WR_DDR2_5_CYC; + break; + default: + mmode |= SDRAM_MMODE_WR_DDR2_6_CYC; + break; + } + } + + mtsdram(SDRAM_MMODE, mmode); +} + +/*-----------------------------------------------------------------------------+ + * program_rtr. + *-----------------------------------------------------------------------------*/ +static void program_rtr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + PPC440_SYS_INFO board_cfg; + unsigned long max_refresh_rate; + unsigned long dimm_num; + unsigned long refresh_rate_type; + unsigned long refresh_rate; + unsigned long rint; + unsigned long sdram_freq; + unsigned long sdr_ddrpll; + unsigned long val; + + /*------------------------------------------------------------------ + * Get the board configuration info. + *-----------------------------------------------------------------*/ + get_sys_info(&board_cfg); + + /*------------------------------------------------------------------ + * Set the SDRAM Refresh Timing Register, SDRAM_RTR + *-----------------------------------------------------------------*/ + mfsdr(sdr_ddr0, sdr_ddrpll); + sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll)); + + max_refresh_rate = 0; + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + + refresh_rate_type = spd_read(iic0_dimm_addr[dimm_num], 12); + refresh_rate_type &= 0x7F; + switch (refresh_rate_type) { + case 0: + refresh_rate = 15625; + break; + case 1: + refresh_rate = 3906; + break; + case 2: + refresh_rate = 7812; + break; + case 3: + refresh_rate = 31250; + break; + case 4: + refresh_rate = 62500; + break; + case 5: + refresh_rate = 125000; + break; + default: + refresh_rate = 0; + printf("ERROR: DIMM %d unsupported refresh rate/type.\n", + (unsigned int)dimm_num); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + break; + } + + max_refresh_rate = max(max_refresh_rate, refresh_rate); + } + } + + rint = MULDIV64(sdram_freq, max_refresh_rate, ONE_BILLION); + mfsdram(SDRAM_RTR, val); + mtsdram(SDRAM_RTR, (val & ~SDRAM_RTR_RINT_MASK) | + (SDRAM_RTR_RINT_ENCODE(rint))); +} + +/*------------------------------------------------------------------ + * This routine programs the SDRAM_TRx registers. + *-----------------------------------------------------------------*/ +static void program_tr(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long sdram_ddr1; + unsigned long t_rp_ns; + unsigned long t_rcd_ns; + unsigned long t_rrd_ns; + unsigned long t_ras_ns; + unsigned long t_rc_ns; + unsigned long t_rfc_ns; + unsigned long t_wpc_ns; + unsigned long t_wtr_ns; + unsigned long t_rpc_ns; + unsigned long t_rp_clk; + unsigned long t_rcd_clk; + unsigned long t_rrd_clk; + unsigned long t_ras_clk; + unsigned long t_rc_clk; + unsigned long t_rfc_clk; + unsigned long t_wpc_clk; + unsigned long t_wtr_clk; + unsigned long t_rpc_clk; + unsigned long sdtr1, sdtr2, sdtr3; + unsigned long ddr_check; + unsigned long sdram_freq; + unsigned long sdr_ddrpll; + + PPC440_SYS_INFO board_cfg; + + /*------------------------------------------------------------------ + * Get the board configuration info. + *-----------------------------------------------------------------*/ + get_sys_info(&board_cfg); + + mfsdr(sdr_ddr0, sdr_ddrpll); + sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll)); + + /*------------------------------------------------------------------ + * Handle the timing. We need to find the worst case timing of all + * the dimm modules installed. + *-----------------------------------------------------------------*/ + t_rp_ns = 0; + t_rrd_ns = 0; + t_rcd_ns = 0; + t_ras_ns = 0; + t_rc_ns = 0; + t_rfc_ns = 0; + t_wpc_ns = 0; + t_wtr_ns = 0; + t_rpc_ns = 0; + sdram_ddr1 = TRUE; + + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + /* If a dimm is installed in a particular slot ... */ + if (dimm_populated[dimm_num] != SDRAM_NONE) { + if (dimm_populated[dimm_num] == SDRAM_DDR2) + sdram_ddr1 = TRUE; + else + sdram_ddr1 = FALSE; + + t_rcd_ns = max(t_rcd_ns, spd_read(iic0_dimm_addr[dimm_num], 29) >> 2); + t_rrd_ns = max(t_rrd_ns, spd_read(iic0_dimm_addr[dimm_num], 28) >> 2); + t_rp_ns = max(t_rp_ns, spd_read(iic0_dimm_addr[dimm_num], 27) >> 2); + t_ras_ns = max(t_ras_ns, spd_read(iic0_dimm_addr[dimm_num], 30)); + t_rc_ns = max(t_rc_ns, spd_read(iic0_dimm_addr[dimm_num], 41)); + t_rfc_ns = max(t_rfc_ns, spd_read(iic0_dimm_addr[dimm_num], 42)); + } + } + + /*------------------------------------------------------------------ + * Set the SDRAM Timing Reg 1, SDRAM_TR1 + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_SDTR1, sdtr1); + sdtr1 &= ~(SDRAM_SDTR1_LDOF_MASK | SDRAM_SDTR1_RTW_MASK | + SDRAM_SDTR1_WTWO_MASK | SDRAM_SDTR1_RTRO_MASK); + + /* default values */ + sdtr1 |= SDRAM_SDTR1_LDOF_2_CLK; + sdtr1 |= SDRAM_SDTR1_RTW_2_CLK; + + /* normal operations */ + sdtr1 |= SDRAM_SDTR1_WTWO_0_CLK; + sdtr1 |= SDRAM_SDTR1_RTRO_1_CLK; + + mtsdram(SDRAM_SDTR1, sdtr1); + + /*------------------------------------------------------------------ + * Set the SDRAM Timing Reg 2, SDRAM_TR2 + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_SDTR2, sdtr2); + sdtr2 &= ~(SDRAM_SDTR2_RCD_MASK | SDRAM_SDTR2_WTR_MASK | + SDRAM_SDTR2_XSNR_MASK | SDRAM_SDTR2_WPC_MASK | + SDRAM_SDTR2_RPC_MASK | SDRAM_SDTR2_RP_MASK | + SDRAM_SDTR2_RRD_MASK); + + /* + * convert t_rcd from nanoseconds to ddr clocks + * round up if necessary + */ + t_rcd_clk = MULDIV64(sdram_freq, t_rcd_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rcd_clk, t_rcd_ns); + if (sdram_freq != ddr_check) + t_rcd_clk++; + + switch (t_rcd_clk) { + case 0: + case 1: + sdtr2 |= SDRAM_SDTR2_RCD_1_CLK; + break; + case 2: + sdtr2 |= SDRAM_SDTR2_RCD_2_CLK; + break; + case 3: + sdtr2 |= SDRAM_SDTR2_RCD_3_CLK; + break; + case 4: + sdtr2 |= SDRAM_SDTR2_RCD_4_CLK; + break; + default: + sdtr2 |= SDRAM_SDTR2_RCD_5_CLK; + break; + } + + if (sdram_ddr1 == TRUE) { /* DDR1 */ + if (sdram_freq < 200000000) { + sdtr2 |= SDRAM_SDTR2_WTR_1_CLK; + sdtr2 |= SDRAM_SDTR2_WPC_2_CLK; + sdtr2 |= SDRAM_SDTR2_RPC_2_CLK; + } else { + sdtr2 |= SDRAM_SDTR2_WTR_2_CLK; + sdtr2 |= SDRAM_SDTR2_WPC_3_CLK; + sdtr2 |= SDRAM_SDTR2_RPC_2_CLK; + } + } else { /* DDR2 */ + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + /* If a dimm is installed in a particular slot ... */ + if (dimm_populated[dimm_num] != SDRAM_NONE) { + t_wpc_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 36) >> 2); + t_wtr_ns = max(t_wtr_ns, spd_read(iic0_dimm_addr[dimm_num], 37) >> 2); + t_rpc_ns = max(t_rpc_ns, spd_read(iic0_dimm_addr[dimm_num], 38) >> 2); + } + } + + /* + * convert from nanoseconds to ddr clocks + * round up if necessary + */ + t_wpc_clk = MULDIV64(sdram_freq, t_wpc_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_wpc_clk, t_wpc_ns); + if (sdram_freq != ddr_check) + t_wpc_clk++; + + switch (t_wpc_clk) { + case 0: + case 1: + case 2: + sdtr2 |= SDRAM_SDTR2_WPC_2_CLK; + break; + case 3: + sdtr2 |= SDRAM_SDTR2_WPC_3_CLK; + break; + case 4: + sdtr2 |= SDRAM_SDTR2_WPC_4_CLK; + break; + case 5: + sdtr2 |= SDRAM_SDTR2_WPC_5_CLK; + break; + default: + sdtr2 |= SDRAM_SDTR2_WPC_6_CLK; + break; + } + + /* + * convert from nanoseconds to ddr clocks + * round up if necessary + */ + t_wtr_clk = MULDIV64(sdram_freq, t_wtr_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_wtr_clk, t_wtr_ns); + if (sdram_freq != ddr_check) + t_wtr_clk++; + + switch (t_wtr_clk) { + case 0: + case 1: + sdtr2 |= SDRAM_SDTR2_WTR_1_CLK; + break; + case 2: + sdtr2 |= SDRAM_SDTR2_WTR_2_CLK; + break; + case 3: + sdtr2 |= SDRAM_SDTR2_WTR_3_CLK; + break; + default: + sdtr2 |= SDRAM_SDTR2_WTR_4_CLK; + break; + } + + /* + * convert from nanoseconds to ddr clocks + * round up if necessary + */ + t_rpc_clk = MULDIV64(sdram_freq, t_rpc_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rpc_clk, t_rpc_ns); + if (sdram_freq != ddr_check) + t_rpc_clk++; + + switch (t_rpc_clk) { + case 0: + case 1: + case 2: + sdtr2 |= SDRAM_SDTR2_RPC_2_CLK; + break; + case 3: + sdtr2 |= SDRAM_SDTR2_RPC_3_CLK; + break; + default: + sdtr2 |= SDRAM_SDTR2_RPC_4_CLK; + break; + } + } + + /* default value */ + sdtr2 |= SDRAM_SDTR2_XSNR_16_CLK; + + /* + * convert t_rrd from nanoseconds to ddr clocks + * round up if necessary + */ + t_rrd_clk = MULDIV64(sdram_freq, t_rrd_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rrd_clk, t_rrd_ns); + if (sdram_freq != ddr_check) + t_rrd_clk++; + + if (t_rrd_clk == 3) + sdtr2 |= SDRAM_SDTR2_RRD_3_CLK; + else + sdtr2 |= SDRAM_SDTR2_RRD_2_CLK; + + /* + * convert t_rp from nanoseconds to ddr clocks + * round up if necessary + */ + t_rp_clk = MULDIV64(sdram_freq, t_rp_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rp_clk, t_rp_ns); + if (sdram_freq != ddr_check) + t_rp_clk++; + + switch (t_rp_clk) { + case 0: + case 1: + case 2: + case 3: + sdtr2 |= SDRAM_SDTR2_RP_3_CLK; + break; + case 4: + sdtr2 |= SDRAM_SDTR2_RP_4_CLK; + break; + case 5: + sdtr2 |= SDRAM_SDTR2_RP_5_CLK; + break; + case 6: + sdtr2 |= SDRAM_SDTR2_RP_6_CLK; + break; + default: + sdtr2 |= SDRAM_SDTR2_RP_7_CLK; + break; + } + + mtsdram(SDRAM_SDTR2, sdtr2); + + /*------------------------------------------------------------------ + * Set the SDRAM Timing Reg 3, SDRAM_TR3 + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_SDTR3, sdtr3); + sdtr3 &= ~(SDRAM_SDTR3_RAS_MASK | SDRAM_SDTR3_RC_MASK | + SDRAM_SDTR3_XCS_MASK | SDRAM_SDTR3_RFC_MASK); + + /* + * convert t_ras from nanoseconds to ddr clocks + * round up if necessary + */ + t_ras_clk = MULDIV64(sdram_freq, t_ras_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_ras_clk, t_ras_ns); + if (sdram_freq != ddr_check) + t_ras_clk++; + + sdtr3 |= SDRAM_SDTR3_RAS_ENCODE(t_ras_clk); + + /* + * convert t_rc from nanoseconds to ddr clocks + * round up if necessary + */ + t_rc_clk = MULDIV64(sdram_freq, t_rc_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rc_clk, t_rc_ns); + if (sdram_freq != ddr_check) + t_rc_clk++; + + sdtr3 |= SDRAM_SDTR3_RC_ENCODE(t_rc_clk); + + /* default xcs value */ + sdtr3 |= SDRAM_SDTR3_XCS; + + /* + * convert t_rfc from nanoseconds to ddr clocks + * round up if necessary + */ + t_rfc_clk = MULDIV64(sdram_freq, t_rfc_ns, ONE_BILLION); + ddr_check = MULDIV64(ONE_BILLION, t_rfc_clk, t_rfc_ns); + if (sdram_freq != ddr_check) + t_rfc_clk++; + + sdtr3 |= SDRAM_SDTR3_RFC_ENCODE(t_rfc_clk); + + mtsdram(SDRAM_SDTR3, sdtr3); +} + +/*-----------------------------------------------------------------------------+ + * program_bxcf. + *-----------------------------------------------------------------------------*/ +static void program_bxcf(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long num_col_addr; + unsigned long num_ranks; + unsigned long num_banks; + unsigned long mode; + unsigned long ind_rank; + unsigned long ind; + unsigned long ind_bank; + unsigned long bank_0_populated; + + /*------------------------------------------------------------------ + * Set the BxCF regs. First, wipe out the bank config registers. + *-----------------------------------------------------------------*/ + mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF); + mtdcr(SDRAMC_CFGDATA, 0x00000000); + mtdcr(SDRAMC_CFGADDR, SDRAM_MB1CF); + mtdcr(SDRAMC_CFGDATA, 0x00000000); + mtdcr(SDRAMC_CFGADDR, SDRAM_MB2CF); + mtdcr(SDRAMC_CFGDATA, 0x00000000); + mtdcr(SDRAMC_CFGADDR, SDRAM_MB3CF); + mtdcr(SDRAMC_CFGDATA, 0x00000000); + + mode = SDRAM_BXCF_M_BE_ENABLE; + + bank_0_populated = 0; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); + num_ranks = spd_read(iic0_dimm_addr[dimm_num], 5); + if ((spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) + num_ranks = (num_ranks & 0x0F) +1; + else + num_ranks = num_ranks & 0x0F; + + num_banks = spd_read(iic0_dimm_addr[dimm_num], 17); + + for (ind_bank = 0; ind_bank < 2; ind_bank++) { + if (num_banks == 4) + ind = 0; + else + ind = 5; + switch (num_col_addr) { + case 0x08: + mode |= (SDRAM_BXCF_M_AM_0 + ind); + break; + case 0x09: + mode |= (SDRAM_BXCF_M_AM_1 + ind); + break; + case 0x0A: + mode |= (SDRAM_BXCF_M_AM_2 + ind); + break; + case 0x0B: + mode |= (SDRAM_BXCF_M_AM_3 + ind); + break; + case 0x0C: + mode |= (SDRAM_BXCF_M_AM_4 + ind); + break; + default: + printf("DDR-SDRAM: DIMM %d BxCF configuration.\n", + (unsigned int)dimm_num); + printf("ERROR: Unsupported value for number of " + "column addresses: %d.\n", (unsigned int)num_col_addr); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + } + } + + if ((dimm_populated[dimm_num] != SDRAM_NONE)&& (dimm_num ==1)) + bank_0_populated = 1; + + for (ind_rank = 0; ind_rank < num_ranks; ind_rank++) { + mtdcr(SDRAMC_CFGADDR, SDRAM_MB0CF + ((dimm_num + bank_0_populated + ind_rank) << 2)); + mtdcr(SDRAMC_CFGDATA, mode); + } + } + } +} + +/*------------------------------------------------------------------ + * program memory queue. + *-----------------------------------------------------------------*/ +static void program_memory_queue(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long dimm_num; + unsigned long rank_base_addr; + unsigned long rank_reg; + unsigned long rank_size_bytes; + unsigned long rank_size_id; + unsigned long num_ranks; + unsigned long baseadd_size; + unsigned long i; + unsigned long bank_0_populated = 0; + + /*------------------------------------------------------------------ + * Reset the rank_base_address. + *-----------------------------------------------------------------*/ + rank_reg = SDRAM_R0BAS; + + rank_base_addr = 0x00000000; + + for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { + if (dimm_populated[dimm_num] != SDRAM_NONE) { + num_ranks = spd_read(iic0_dimm_addr[dimm_num], 5); + if ((spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) + num_ranks = (num_ranks & 0x0F) + 1; + else + num_ranks = num_ranks & 0x0F; + + rank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); + + /*------------------------------------------------------------------ + * Set the sizes + *-----------------------------------------------------------------*/ + baseadd_size = 0; + rank_size_bytes = 1024 * 1024 * rank_size_id; + switch (rank_size_id) { + case 0x02: + baseadd_size |= SDRAM_RXBAS_SDSZ_8; + break; + case 0x04: + baseadd_size |= SDRAM_RXBAS_SDSZ_16; + break; + case 0x08: + baseadd_size |= SDRAM_RXBAS_SDSZ_32; + break; + case 0x10: + baseadd_size |= SDRAM_RXBAS_SDSZ_64; + break; + case 0x20: + baseadd_size |= SDRAM_RXBAS_SDSZ_128; + break; + case 0x40: + baseadd_size |= SDRAM_RXBAS_SDSZ_256; + break; + case 0x80: + baseadd_size |= SDRAM_RXBAS_SDSZ_512; + break; + default: + printf("DDR-SDRAM: DIMM %d memory queue configuration.\n", + (unsigned int)dimm_num); + printf("ERROR: Unsupported value for the banksize: %d.\n", + (unsigned int)rank_size_id); + printf("Replace the DIMM module with a supported DIMM.\n\n"); + hang(); + } + + if ((dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_num == 1)) + bank_0_populated = 1; + + for (i = 0; i < num_ranks; i++) { + mtdcr_any(rank_reg+i+dimm_num+bank_0_populated, + (rank_base_addr & SDRAM_RXBAS_SDBA_MASK) | + baseadd_size); + rank_base_addr += rank_size_bytes; + } + } + } +} + +/*-----------------------------------------------------------------------------+ + * is_ecc_enabled. + *-----------------------------------------------------------------------------*/ +static unsigned long is_ecc_enabled(void) +{ + unsigned long dimm_num; + unsigned long ecc; + unsigned long val; + + ecc = 0; + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) { + mfsdram(SDRAM_MCOPT1, val); + ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val)); + } + + return(ecc); +} + +/*-----------------------------------------------------------------------------+ + * program_ecc. + *-----------------------------------------------------------------------------*/ +static void program_ecc(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long mcopt1; + unsigned long mcopt2; + unsigned long mcstat; + unsigned long dimm_num; + unsigned long ecc; + + ecc = 0; + /* loop through all the DIMM slots on the board */ + for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) { + /* If a dimm is installed in a particular slot ... */ + if (dimm_populated[dimm_num] != SDRAM_NONE) + ecc = max(ecc, spd_read(iic0_dimm_addr[dimm_num], 11)); + } + if (ecc == 0) + return; + + mfsdram(SDRAM_MCOPT1, mcopt1); + mfsdram(SDRAM_MCOPT2, mcopt2); + + if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) { + /* DDR controller must be enabled and not in self-refresh. */ + mfsdram(SDRAM_MCSTAT, mcstat); + if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE) + && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT) + && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK)) + == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) { + + program_ecc_addr(0, sdram_memsize()); + } + } + + return; +} + +/*-----------------------------------------------------------------------------+ + * program_ecc_addr. + *-----------------------------------------------------------------------------*/ +static void program_ecc_addr(unsigned long start_address, + unsigned long num_bytes) +{ + unsigned long current_address; + unsigned long end_address; + unsigned long address_increment; + unsigned long mcopt1; + + current_address = start_address; + mfsdram(SDRAM_MCOPT1, mcopt1); + if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) { + mtsdram(SDRAM_MCOPT1, + (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN); + sync(); + eieio(); + wait_ddr_idle(); + + /* ECC bit set method for non-cached memory */ + if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) + address_increment = 4; + else + address_increment = 8; + end_address = current_address + num_bytes; + + while (current_address < end_address) { + *((unsigned long *)current_address) = 0x00000000; + current_address += address_increment; + } + sync(); + eieio(); + wait_ddr_idle(); + + mtsdram(SDRAM_MCOPT1, + (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK); + sync(); + eieio(); + wait_ddr_idle(); + } +} + +/*-----------------------------------------------------------------------------+ + * program_DQS_calibration. + *-----------------------------------------------------------------------------*/ +static void program_DQS_calibration(unsigned long *dimm_populated, + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks) +{ + unsigned long val; + +#ifdef HARD_CODED_DQS /* calibration test with hardvalues */ + mtsdram(SDRAM_RQDC, 0x80000037); + mtsdram(SDRAM_RDCC, 0x40000000); + mtsdram(SDRAM_RFDC, 0x000001DF); + + test(); +#else + /*------------------------------------------------------------------ + * Program RDCC register + * Read sample cycle auto-update enable + *-----------------------------------------------------------------*/ + + /* + * Modified for the Katmai platform: with some DIMMs, the DDR2 + * controller automatically selects the T2 read cycle, but this + * proves unreliable. Go ahead and force the DDR2 controller + * to use the T4 sample and disable the automatic update of the + * RDSS field. + */ + mfsdram(SDRAM_RDCC, val); + mtsdram(SDRAM_RDCC, + (val & ~(SDRAM_RDCC_RDSS_MASK | SDRAM_RDCC_RSAE_MASK)) + | (SDRAM_RDCC_RDSS_T4 | SDRAM_RDCC_RSAE_DISABLE)); + + /*------------------------------------------------------------------ + * Program RQDC register + * Internal DQS delay mechanism enable + *-----------------------------------------------------------------*/ + mtsdram(SDRAM_RQDC, (SDRAM_RQDC_RQDE_ENABLE|SDRAM_RQDC_RQFD_ENCODE(0x38))); + + /*------------------------------------------------------------------ + * Program RFDC register + * Set Feedback Fractional Oversample + * Auto-detect read sample cycle enable + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_RFDC, val); + mtsdram(SDRAM_RFDC, + (val & ~(SDRAM_RFDC_ARSE_MASK | SDRAM_RFDC_RFOS_MASK | + SDRAM_RFDC_RFFD_MASK)) + | (SDRAM_RFDC_ARSE_ENABLE | SDRAM_RFDC_RFOS_ENCODE(0) | + SDRAM_RFDC_RFFD_ENCODE(0))); + + DQS_calibration_process(); +#endif +} + +static u32 short_mem_test(void) +{ + u32 *membase; + u32 bxcr_num; + u32 bxcf; + int i; + int j; + u32 test[NUMMEMTESTS][NUMMEMWORDS] = { + {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000}, + {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555}, + {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA}, + {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A}, + {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5}, + {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA}, + {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, + 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} }; + + for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) { + mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf); + + /* Banks enabled */ + if ((bxcf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { + + /* Bank is enabled */ + membase = (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num))); + + /*------------------------------------------------------------------ + * Run the short memory test. + *-----------------------------------------------------------------*/ + for (i = 0; i < NUMMEMTESTS; i++) { + for (j = 0; j < NUMMEMWORDS; j++) { + membase[j] = test[i][j]; + ppcDcbf((u32)&(membase[j])); + } + sync(); + for (j = 0; j < NUMMEMWORDS; j++) { + if (membase[j] != test[i][j]) { + ppcDcbf((u32)&(membase[j])); + break; + } + ppcDcbf((u32)&(membase[j])); + } + sync(); + if (j < NUMMEMWORDS) + break; + } + if (i < NUMMEMTESTS) + break; + } /* if bank enabled */ + } /* for bxcf_num */ + + return bxcr_num; +} + +#ifndef HARD_CODED_DQS +/*-----------------------------------------------------------------------------+ + * DQS_calibration_process. + *-----------------------------------------------------------------------------*/ +static void DQS_calibration_process(void) +{ + unsigned long ecc_temp; + unsigned long rfdc_reg; + unsigned long rffd; + unsigned long rqdc_reg; + unsigned long rqfd; + unsigned long bxcr_num; + unsigned long val; + long rqfd_average; + long rffd_average; + long max_start; + long min_end; + unsigned long begin_rqfd[MAXRANKS]; + unsigned long begin_rffd[MAXRANKS]; + unsigned long end_rqfd[MAXRANKS]; + unsigned long end_rffd[MAXRANKS]; + char window_found; + unsigned long dlycal; + unsigned long dly_val; + unsigned long max_pass_length; + unsigned long current_pass_length; + unsigned long current_fail_length; + unsigned long current_start; + long max_end; + unsigned char fail_found; + unsigned char pass_found; + + /*------------------------------------------------------------------ + * Test to determine the best read clock delay tuning bits. + * + * Before the DDR controller can be used, the read clock delay needs to be + * set. This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD]. + * This value cannot be hardcoded into the program because it changes + * depending on the board's setup and environment. + * To do this, all delay values are tested to see if they + * work or not. By doing this, you get groups of fails with groups of + * passing values. The idea is to find the start and end of a passing + * window and take the center of it to use as the read clock delay. + * + * A failure has to be seen first so that when we hit a pass, we know + * that it is truely the start of the window. If we get passing values + * to start off with, we don't know if we are at the start of the window. + * + * The code assumes that a failure will always be found. + * If a failure is not found, there is no easy way to get the middle + * of the passing window. I guess we can pretty much pick any value + * but some values will be better than others. Since the lowest speed + * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed), + * from experimentation it is safe to say you will always have a failure. + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT1, ecc_temp); + ecc_temp &= SDRAM_MCOPT1_MCHK_MASK; + mfsdram(SDRAM_MCOPT1, val); + mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | + SDRAM_MCOPT1_MCHK_NON); + + max_start = 0; + min_end = 0; + begin_rqfd[0] = 0; + begin_rffd[0] = 0; + begin_rqfd[1] = 0; + begin_rffd[1] = 0; + end_rqfd[0] = 0; + end_rffd[0] = 0; + end_rqfd[1] = 0; + end_rffd[1] = 0; + window_found = FALSE; + + max_pass_length = 0; + max_start = 0; + max_end = 0; + current_pass_length = 0; + current_fail_length = 0; + current_start = 0; + window_found = FALSE; + fail_found = FALSE; + pass_found = FALSE; + + /* first fix RQDC[RQFD] to an average of 80 degre phase shift to find RFDC[RFFD] */ + /* rqdc_reg = mfsdram(SDRAM_RQDC) & ~(SDRAM_RQDC_RQFD_MASK); */ + + /* + * get the delay line calibration register value + */ + mfsdram(SDRAM_DLCR, dlycal); + dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2; + + for (rffd = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) { + mfsdram(SDRAM_RFDC, rfdc_reg); + rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK); + + /*------------------------------------------------------------------ + * Set the timing reg for the test. + *-----------------------------------------------------------------*/ + mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd)); + + /* do the small memory test */ + bxcr_num = short_mem_test(); + + /*------------------------------------------------------------------ + * See if the rffd value passed. + *-----------------------------------------------------------------*/ + if (bxcr_num == MAXBXCF) { + if (fail_found == TRUE) { + pass_found = TRUE; + if (current_pass_length == 0) + current_start = rffd; + + current_fail_length = 0; + current_pass_length++; + + if (current_pass_length > max_pass_length) { + max_pass_length = current_pass_length; + max_start = current_start; + max_end = rffd; + } + } + } else { + current_pass_length = 0; + current_fail_length++; + + if (current_fail_length >= (dly_val >> 2)) { + if (fail_found == FALSE) { + fail_found = TRUE; + } else if (pass_found == TRUE) { + window_found = TRUE; + break; + } + } + } + } /* for rffd */ + + + /*------------------------------------------------------------------ + * Set the average RFFD value + *-----------------------------------------------------------------*/ + rffd_average = ((max_start + max_end) >> 1); + + if (rffd_average < 0) + rffd_average = 0; + + if (rffd_average > SDRAM_RFDC_RFFD_MAX) + rffd_average = SDRAM_RFDC_RFFD_MAX; + /* now fix RFDC[RFFD] found and find RQDC[RQFD] */ + mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average)); + + max_pass_length = 0; + max_start = 0; + max_end = 0; + current_pass_length = 0; + current_fail_length = 0; + current_start = 0; + window_found = FALSE; + fail_found = FALSE; + pass_found = FALSE; + + for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) { + mfsdram(SDRAM_RQDC, rqdc_reg); + rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK); + + /*------------------------------------------------------------------ + * Set the timing reg for the test. + *-----------------------------------------------------------------*/ + mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd)); + + /* do the small memory test */ + bxcr_num = short_mem_test(); + + /*------------------------------------------------------------------ + * See if the rffd value passed. + *-----------------------------------------------------------------*/ + if (bxcr_num == MAXBXCF) { + if (fail_found == TRUE) { + pass_found = TRUE; + if (current_pass_length == 0) + current_start = rqfd; + + current_fail_length = 0; + current_pass_length++; + + if (current_pass_length > max_pass_length) { + max_pass_length = current_pass_length; + max_start = current_start; + max_end = rqfd; + } + } + } else { + current_pass_length = 0; + current_fail_length++; + + if (fail_found == FALSE) { + fail_found = TRUE; + } else if (pass_found == TRUE) { + window_found = TRUE; + break; + } + } + } + + /*------------------------------------------------------------------ + * Make sure we found the valid read passing window. Halt if not + *-----------------------------------------------------------------*/ + if (window_found == FALSE) { + printf("ERROR: Cannot determine a common read delay for the " + "DIMM(s) installed.\n"); + debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); + hang(); + } + + rqfd_average = ((max_start + max_end) >> 1); + + if (rqfd_average < 0) + rqfd_average = 0; + + if (rqfd_average > SDRAM_RQDC_RQFD_MAX) + rqfd_average = SDRAM_RQDC_RQFD_MAX; + + /*------------------------------------------------------------------ + * Restore the ECC variable to what it originally was + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT1, val); + mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | ecc_temp); + + mtsdram(SDRAM_RQDC, + (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) | + SDRAM_RQDC_RQFD_ENCODE(rqfd_average)); + + mfsdram(SDRAM_DLCR, val); + debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val); + mfsdram(SDRAM_RQDC, val); + debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val); + mfsdram(SDRAM_RFDC, val); + debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val); +} +#else /* calibration test with hardvalues */ +/*-----------------------------------------------------------------------------+ + * DQS_calibration_process. + *-----------------------------------------------------------------------------*/ +static void test(void) +{ + unsigned long dimm_num; + unsigned long ecc_temp; + unsigned long i, j; + unsigned long *membase; + unsigned long bxcf[MAXRANKS]; + unsigned long val; + char window_found; + char begin_found[MAXDIMMS]; + char end_found[MAXDIMMS]; + char search_end[MAXDIMMS]; + unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = { + {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000}, + {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555}, + {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA}, + {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A}, + {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5}, + {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA}, + {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, + 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55} }; + + /*------------------------------------------------------------------ + * Test to determine the best read clock delay tuning bits. + * + * Before the DDR controller can be used, the read clock delay needs to be + * set. This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD]. + * This value cannot be hardcoded into the program because it changes + * depending on the board's setup and environment. + * To do this, all delay values are tested to see if they + * work or not. By doing this, you get groups of fails with groups of + * passing values. The idea is to find the start and end of a passing + * window and take the center of it to use as the read clock delay. + * + * A failure has to be seen first so that when we hit a pass, we know + * that it is truely the start of the window. If we get passing values + * to start off with, we don't know if we are at the start of the window. + * + * The code assumes that a failure will always be found. + * If a failure is not found, there is no easy way to get the middle + * of the passing window. I guess we can pretty much pick any value + * but some values will be better than others. Since the lowest speed + * we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed), + * from experimentation it is safe to say you will always have a failure. + *-----------------------------------------------------------------*/ + mfsdram(SDRAM_MCOPT1, ecc_temp); + ecc_temp &= SDRAM_MCOPT1_MCHK_MASK; + mfsdram(SDRAM_MCOPT1, val); + mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | + SDRAM_MCOPT1_MCHK_NON); + + window_found = FALSE; + begin_found[0] = FALSE; + end_found[0] = FALSE; + search_end[0] = FALSE; + begin_found[1] = FALSE; + end_found[1] = FALSE; + search_end[1] = FALSE; + + for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) { + mfsdram(SDRAM_MB0CF + (bxcr_num << 2), bxcf[bxcr_num]); + + /* Banks enabled */ + if ((bxcf[dimm_num] & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) { + + /* Bank is enabled */ + membase = + (unsigned long*)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+dimm_num))); + + /*------------------------------------------------------------------ + * Run the short memory test. + *-----------------------------------------------------------------*/ + for (i = 0; i < NUMMEMTESTS; i++) { + for (j = 0; j < NUMMEMWORDS; j++) { + membase[j] = test[i][j]; + ppcDcbf((u32)&(membase[j])); + } + sync(); + for (j = 0; j < NUMMEMWORDS; j++) { + if (membase[j] != test[i][j]) { + ppcDcbf((u32)&(membase[j])); + break; + } + ppcDcbf((u32)&(membase[j])); + } + sync(); + if (j < NUMMEMWORDS) + break; + } + + /*------------------------------------------------------------------ + * See if the rffd value passed. + *-----------------------------------------------------------------*/ + if (i < NUMMEMTESTS) { + if ((end_found[dimm_num] == FALSE) && + (search_end[dimm_num] == TRUE)) { + end_found[dimm_num] = TRUE; + } + if ((end_found[0] == TRUE) && + (end_found[1] == TRUE)) + break; + } else { + if (begin_found[dimm_num] == FALSE) { + begin_found[dimm_num] = TRUE; + search_end[dimm_num] = TRUE; + } + } + } else { + begin_found[dimm_num] = TRUE; + end_found[dimm_num] = TRUE; + } + } + + if ((begin_found[0] == TRUE) && (begin_found[1] == TRUE)) + window_found = TRUE; + + /*------------------------------------------------------------------ + * Make sure we found the valid read passing window. Halt if not + *-----------------------------------------------------------------*/ + if (window_found == FALSE) { + printf("ERROR: Cannot determine a common read delay for the " + "DIMM(s) installed.\n"); + hang(); + } + + /*------------------------------------------------------------------ + * Restore the ECC variable to what it originally was + *-----------------------------------------------------------------*/ + mtsdram(SDRAM_MCOPT1, + (ppcMfdcr_sdram(SDRAM_MCOPT1) & ~SDRAM_MCOPT1_MCHK_MASK) + | ecc_temp); +} +#endif + +#if defined(DEBUG) +static void ppc440sp_sdram_register_dump(void) +{ + unsigned int sdram_reg; + unsigned int sdram_data; + unsigned int dcr_data; + + printf("\n Register Dump:\n"); + sdram_reg = SDRAM_MCSTAT; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MCSTAT = 0x%08X", sdram_data); + sdram_reg = SDRAM_MCOPT1; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MCOPT1 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MCOPT2; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MCOPT2 = 0x%08X", sdram_data); + sdram_reg = SDRAM_MODT0; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MODT0 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MODT1; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MODT1 = 0x%08X", sdram_data); + sdram_reg = SDRAM_MODT2; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MODT2 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MODT3; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MODT3 = 0x%08X", sdram_data); + sdram_reg = SDRAM_CODT; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_CODT = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_VVPR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_VVPR = 0x%08X", sdram_data); + sdram_reg = SDRAM_OPARS; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_OPARS = 0x%08X\n", sdram_data); + /* + * OPAR2 is only used as a trigger register. + * No data is contained in this register, and reading or writing + * to is can cause bad things to happen (hangs). Just skip it + * and report NA + * sdram_reg = SDRAM_OPAR2; + * mfsdram(sdram_reg, sdram_data); + * printf(" SDRAM_OPAR2 = 0x%08X\n", sdram_data); + */ + printf(" SDRAM_OPART = N/A "); + sdram_reg = SDRAM_RTR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_RTR = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MB0CF; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MB0CF = 0x%08X", sdram_data); + sdram_reg = SDRAM_MB1CF; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MB1CF = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MB2CF; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MB2CF = 0x%08X", sdram_data); + sdram_reg = SDRAM_MB3CF; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MB3CF = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR0; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR0 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR1; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR1 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR2; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR2 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR3; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR3 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR4; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR4 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR5; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR5 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR6; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR6 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR7; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR7 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR8; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR8 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR9; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR9 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR10; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR10 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR11; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR11 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR12; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR12 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR13; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR13 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_INITPLR14; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR14 = 0x%08X", sdram_data); + sdram_reg = SDRAM_INITPLR15; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_INITPLR15 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_RQDC; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_RQDC = 0x%08X", sdram_data); + sdram_reg = SDRAM_RFDC; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_RFDC = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_RDCC; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_RDCC = 0x%08X", sdram_data); + sdram_reg = SDRAM_DLCR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_DLCR = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_CLKTR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_CLKTR = 0x%08X", sdram_data); + sdram_reg = SDRAM_WRDTR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_WRDTR = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_SDTR1; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_SDTR1 = 0x%08X", sdram_data); + sdram_reg = SDRAM_SDTR2; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_SDTR2 = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_SDTR3; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_SDTR3 = 0x%08X", sdram_data); + sdram_reg = SDRAM_MMODE; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MMODE = 0x%08X\n", sdram_data); + sdram_reg = SDRAM_MEMODE; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_MEMODE = 0x%08X", sdram_data); + sdram_reg = SDRAM_ECCCR; + mfsdram(sdram_reg, sdram_data); + printf(" SDRAM_ECCCR = 0x%08X\n\n", sdram_data); + + dcr_data = mfdcr(SDRAM_R0BAS); + printf(" MQ0_B0BAS = 0x%08X", dcr_data); + dcr_data = mfdcr(SDRAM_R1BAS); + printf(" MQ1_B0BAS = 0x%08X\n", dcr_data); + dcr_data = mfdcr(SDRAM_R2BAS); + printf(" MQ2_B0BAS = 0x%08X", dcr_data); + dcr_data = mfdcr(SDRAM_R3BAS); + printf(" MQ3_B0BAS = 0x%08X\n", dcr_data); +} +#endif +#endif /* CONFIG_SPD_EEPROM */ diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index baecf70352..96f0f62eb6 100644 --- a/cpu/ppc4xx/Makefile +++ b/cpu/ppc4xx/Makefile @@ -31,7 +31,8 @@ COBJS = 405gp_pci.o 4xx_enet.o \ bedbug_405.o commproc.o \ cpu.o cpu_init.o i2c.o interrupts.o \ miiphy.o ndfc.o sdram.o serial.o \ - spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \ + 40x_spd_sdram.o 44x_spd_ddr.o 44x_spd_ddr2.o speed.o \ + tlb.o traps.o usb_ohci.o usbdev.o \ 440spe_pcie.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index ae24591087..82ae4434b0 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -314,7 +314,7 @@ cpu_init_f (void) #endif #if defined (CFG_EBC_CFG) - mtebc(epcr, CFG_EBC_CFG); + mtebc(EBC0_CFG, CFG_EBC_CFG); #endif #if defined(CONFIG_WATCHDOG) diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 7db1cd8046..0b056a15de 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -1,91 +1,100 @@ -/*****************************************************************************/ -/* I2C Bus interface initialisation and I2C Commands */ -/* for PPC405GP */ -/* Author : AS HARNOIS */ -/* Date : 13.Dec.00 */ -/*****************************************************************************/ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * based on work by Anne Sophie Harnois + * + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ #include #include -#if defined(CONFIG_440) -# include <440_i2c.h> -#else -# include <405gp_i2c.h> -#endif +#include <4xx_i2c.h> #include +#include #ifdef CONFIG_HARD_I2C DECLARE_GLOBAL_DATA_PTR; -#define IIC_OK 0 -#define IIC_NOK 1 -#define IIC_NOK_LA 2 /* Lost arbitration */ -#define IIC_NOK_ICT 3 /* Incomplete transfer */ -#define IIC_NOK_XFRA 4 /* Transfer aborted */ -#define IIC_NOK_DATA 5 /* No data in buffer */ -#define IIC_NOK_TOUT 6 /* Transfer timeout */ +#if defined(CONFIG_I2C_MULTI_BUS) +/* Initialize the bus pointer to whatever one the SPD EEPROM is on. + * Default is bus 0. This is necessary because the DDR initialization + * runs from ROM, and we can't switch buses because we can't modify + * the global variables. + */ +#ifdef CFG_SPD_BUS_NUM +static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM; +#else +static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +#endif +#endif /* CONFIG_I2C_MULTI_BUS */ -#define IIC_TIMEOUT 1 /* 1 seconde */ - - -static void _i2c_bus_reset (void) +static void _i2c_bus_reset(void) { - int i, status; + int i; + u8 dc; /* Reset status register */ /* write 1 in SCMP and IRQA to clear these fields */ - out8 (IIC_STS, 0x0A); + out_8((u8 *)IIC_STS, 0x0A); /* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */ - out8 (IIC_EXTSTS, 0x8F); - __asm__ volatile ("eieio"); + out_8((u8 *)IIC_EXTSTS, 0x8F); - /* - * Get current state, reset bus - * only if no transfers are pending. - */ - i = 10; - do { - /* Get status */ - status = in8 (IIC_STS); - udelay (500); /* 500us */ - i--; - } while ((status & IIC_STS_PT) && (i > 0)); - /* Soft reset controller */ - status = in8 (IIC_XTCNTLSS); - out8 (IIC_XTCNTLSS, (status | IIC_XTCNTLSS_SRST)); - __asm__ volatile ("eieio"); + /* Place chip in the reset state */ + out_8((u8 *)IIC_XTCNTLSS, IIC_XTCNTLSS_SRST); - /* make sure where in initial state, data hi, clock hi */ - out8 (IIC_DIRECTCNTL, 0xC); - for (i = 0; i < 10; i++) { - if ((in8 (IIC_DIRECTCNTL) & 0x3) != 0x3) { - /* clock until we get to known state */ - out8 (IIC_DIRECTCNTL, 0x8); /* clock lo */ - udelay (100); /* 100us */ - out8 (IIC_DIRECTCNTL, 0xC); /* clock hi */ - udelay (100); /* 100us */ - } else { - break; + /* Check if bus is free */ + dc = in_8((u8 *)IIC_DIRECTCNTL); + if (!DIRCTNL_FREE(dc)){ + /* Try to set bus free state */ + out_8((u8 *)IIC_DIRECTCNTL, IIC_DIRCNTL_SDAC | IIC_DIRCNTL_SCC); + + /* Wait until we regain bus control */ + for (i = 0; i < 100; ++i) { + dc = in_8((u8 *)IIC_DIRECTCNTL); + if (DIRCTNL_FREE(dc)) + break; + + /* Toggle SCL line */ + dc ^= IIC_DIRCNTL_SCC; + out_8((u8 *)IIC_DIRECTCNTL, dc); + udelay(10); + dc ^= IIC_DIRCNTL_SCC; + out_8((u8 *)IIC_DIRECTCNTL, dc); } } - /* send start condition */ - out8 (IIC_DIRECTCNTL, 0x4); - udelay (1000); /* 1ms */ - /* send stop condition */ - out8 (IIC_DIRECTCNTL, 0xC); - udelay (1000); /* 1ms */ - /* Unreset controller */ - out8 (IIC_XTCNTLSS, (status & ~IIC_XTCNTLSS_SRST)); - udelay (1000); /* 1ms */ + + /* Remove reset */ + out_8((u8 *)IIC_XTCNTLSS, 0); } -void i2c_init (int speed, int slaveadd) +void i2c_init(int speed, int slaveadd) { sys_info_t sysInfo; unsigned long freqOPB; int val, divisor; + int bus; #ifdef CFG_I2C_INIT_BOARD /* call board specific i2c bus reset routine before accessing the */ @@ -94,101 +103,100 @@ void i2c_init (int speed, int slaveadd) i2c_init_board(); #endif - /* Handle possible failed I2C state */ - /* FIXME: put this into i2c_init_board()? */ - _i2c_bus_reset (); + for (bus = 0; bus < CFG_MAX_I2C_BUS; bus++) { + I2C_SET_BUS(bus); - /* clear lo master address */ - out8 (IIC_LMADR, 0); + /* Handle possible failed I2C state */ + /* FIXME: put this into i2c_init_board()? */ + _i2c_bus_reset(); - /* clear hi master address */ - out8 (IIC_HMADR, 0); + /* clear lo master address */ + out_8((u8 *)IIC_LMADR, 0); - /* clear lo slave address */ - out8 (IIC_LSADR, 0); + /* clear hi master address */ + out_8((u8 *)IIC_HMADR, 0); - /* clear hi slave address */ - out8 (IIC_HSADR, 0); + /* clear lo slave address */ + out_8((u8 *)IIC_LSADR, 0); - /* Clock divide Register */ - /* get OPB frequency */ - get_sys_info (&sysInfo); - freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv; - /* set divisor according to freqOPB */ - divisor = (freqOPB - 1) / 10000000; - if (divisor == 0) - divisor = 1; - out8 (IIC_CLKDIV, divisor); + /* clear hi slave address */ + out_8((u8 *)IIC_HSADR, 0); - /* no interrupts */ - out8 (IIC_INTRMSK, 0); + /* Clock divide Register */ + /* get OPB frequency */ + get_sys_info(&sysInfo); + freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv; + /* set divisor according to freqOPB */ + divisor = (freqOPB - 1) / 10000000; + if (divisor == 0) + divisor = 1; + out_8((u8 *)IIC_CLKDIV, divisor); - /* clear transfer count */ - out8 (IIC_XFRCNT, 0); + /* no interrupts */ + out_8((u8 *)IIC_INTRMSK, 0); - /* clear extended control & stat */ - /* write 1 in SRC SRS SWC SWS to clear these fields */ - out8 (IIC_XTCNTLSS, 0xF0); + /* clear transfer count */ + out_8((u8 *)IIC_XFRCNT, 0); - /* Mode Control Register - Flush Slave/Master data buffer */ - out8 (IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); - __asm__ volatile ("eieio"); + /* clear extended control & stat */ + /* write 1 in SRC SRS SWC SWS to clear these fields */ + out_8((u8 *)IIC_XTCNTLSS, 0xF0); + /* Mode Control Register + Flush Slave/Master data buffer */ + out_8((u8 *)IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); - val = in8(IIC_MDCNTL); - __asm__ volatile ("eieio"); + val = in_8((u8 *)IIC_MDCNTL); - /* Ignore General Call, slave transfers are ignored, - disable interrupts, exit unknown bus state, enable hold - SCL - 100kHz normaly or FastMode for 400kHz and above - */ + /* Ignore General Call, slave transfers are ignored, + * disable interrupts, exit unknown bus state, enable hold + * SCL 100kHz normaly or FastMode for 400kHz and above + */ - val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL; - if( speed >= 400000 ){ - val |= IIC_MDCNTL_FSM; + val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL; + if (speed >= 400000) + val |= IIC_MDCNTL_FSM; + out_8((u8 *)IIC_MDCNTL, val); + + /* clear control reg */ + out_8((u8 *)IIC_CNTL, 0x00); } - out8 (IIC_MDCNTL, val); - - /* clear control reg */ - out8 (IIC_CNTL, 0x00); - __asm__ volatile ("eieio"); + /* set to SPD bus as default bus upon powerup */ + I2C_SET_BUS(CFG_SPD_BUS_NUM); } /* - This code tries to use the features of the 405GP i2c - controller. It will transfer up to 4 bytes in one pass - on the loop. It only does out8(lbz) to the buffer when it - is possible to do out16(lhz) transfers. - - cmd_type is 0 for write 1 for read. - - addr_len can take any value from 0-255, it is only limited - by the char, we could make it larger if needed. If it is - 0 we skip the address write cycle. - - Typical case is a Write of an addr followd by a Read. The - IBM FAQ does not cover this. On the last byte of the write - we don't set the creg CHT bit, and on the first bytes of the - read we set the RPST bit. - - It does not support address only transfers, there must be - a data part. If you want to write the address yourself, put - it in the data pointer. - - It does not support transfer to/from address 0. - - It does not check XFRCNT. -*/ -static -int i2c_transfer(unsigned char cmd_type, - unsigned char chip, - unsigned char addr[], - unsigned char addr_len, - unsigned char data[], - unsigned short data_len ) + * This code tries to use the features of the 405GP i2c + * controller. It will transfer up to 4 bytes in one pass + * on the loop. It only does out_8((u8 *)lbz) to the buffer when it + * is possible to do out16(lhz) transfers. + * + * cmd_type is 0 for write 1 for read. + * + * addr_len can take any value from 0-255, it is only limited + * by the char, we could make it larger if needed. If it is + * 0 we skip the address write cycle. + * + * Typical case is a Write of an addr followd by a Read. The + * IBM FAQ does not cover this. On the last byte of the write + * we don't set the creg CHT bit, and on the first bytes of the + * read we set the RPST bit. + * + * It does not support address only transfers, there must be + * a data part. If you want to write the address yourself, put + * it in the data pointer. + * + * It does not support transfer to/from address 0. + * + * It does not check XFRCNT. + */ +static int i2c_transfer(unsigned char cmd_type, + unsigned char chip, + unsigned char addr[], + unsigned char addr_len, + unsigned char data[], + unsigned short data_len) { unsigned char* ptr; int reading; @@ -198,97 +206,88 @@ int i2c_transfer(unsigned char cmd_type, int i; uchar creg; - if( data == 0 || data_len == 0 ){ - /*Don't support data transfer of no length or to address 0*/ + if (data == 0 || data_len == 0) { + /* Don't support data transfer of no length or to address 0 */ printf( "i2c_transfer: bad call\n" ); return IIC_NOK; } - if( addr && addr_len ){ + if (addr && addr_len) { ptr = addr; cnt = addr_len; reading = 0; - }else{ + } else { ptr = data; cnt = data_len; reading = cmd_type; } - /*Clear Stop Complete Bit*/ - out8(IIC_STS,IIC_STS_SCMP); + /* Clear Stop Complete Bit */ + out_8((u8 *)IIC_STS, IIC_STS_SCMP); /* Check init */ - i=10; + i = 10; do { /* Get status */ - status = in8(IIC_STS); - __asm__ volatile("eieio"); + status = in_8((u8 *)IIC_STS); i--; - } while ((status & IIC_STS_PT) && (i>0)); + } while ((status & IIC_STS_PT) && (i > 0)); if (status & IIC_STS_PT) { result = IIC_NOK_TOUT; return(result); } - /*flush the Master/Slave Databuffers*/ - out8(IIC_MDCNTL, ((in8(IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB)); - /*need to wait 4 OPB clocks? code below should take that long*/ + /* flush the Master/Slave Databuffers */ + out_8((u8 *)IIC_MDCNTL, ((in_8((u8 *)IIC_MDCNTL))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB)); + /* need to wait 4 OPB clocks? code below should take that long */ /* 7-bit adressing */ - out8(IIC_HMADR,0); - out8(IIC_LMADR, chip); - __asm__ volatile("eieio"); + out_8((u8 *)IIC_HMADR, 0); + out_8((u8 *)IIC_LMADR, chip); tran = 0; result = IIC_OK; creg = 0; - while ( tran != cnt && (result == IIC_OK)) { + while (tran != cnt && (result == IIC_OK)) { int bc,j; /* Control register = - Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start, - Transfer is a sequence of transfers - */ + * Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start, + * Transfer is a sequence of transfers + */ creg |= IIC_CNTL_PT; - bc = (cnt - tran) > 4 ? 4 : - cnt - tran; - creg |= (bc-1)<<4; - /* if the real cmd type is write continue trans*/ - if ( (!cmd_type && (ptr == addr)) || ((tran+bc) != cnt) ) + bc = (cnt - tran) > 4 ? 4 : cnt - tran; + creg |= (bc - 1) << 4; + /* if the real cmd type is write continue trans */ + if ((!cmd_type && (ptr == addr)) || ((tran + bc) != cnt)) creg |= IIC_CNTL_CHT; if (reading) creg |= IIC_CNTL_READ; - else { - for(j=0; j0)); + } while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR) && (i > 0)); if (status & IIC_STS_ERR) { result = IIC_NOK; - status = in8 (IIC_EXTSTS); + status = in_8((u8 *)IIC_EXTSTS); /* Lost arbitration? */ if (status & IIC_EXTSTS_LA) result = IIC_NOK_LA; @@ -306,34 +305,32 @@ int i2c_transfer(unsigned char cmd_type, /* Are there data in buffer */ if (status & IIC_STS_MDBS) { /* - even if we have data we have to wait 4OPB clocks - for it to hit the front of the FIFO, after that - we can just read. We should check XFCNT here and - if the FIFO is full there is no need to wait. - */ - udelay (1); - for(j=0;jed (i.e. there was a chip at that address which * drove the data line low). */ - return(i2c_transfer (1, chip << 1, 0,0, buf, 1) != 0); + return (i2c_transfer(1, chip << 1, 0,0, buf, 1) != 0); } -int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len) { uchar xaddr[4]; int ret; - if ( alen > 4 ) { + if (alen > 4) { printf ("I2C read: addr len %d not supported\n", alen); return 1; } - if ( alen > 0 ) { + if (alen > 0) { xaddr[0] = (addr >> 24) & 0xFF; xaddr[1] = (addr >> 16) & 0xFF; xaddr[2] = (addr >> 8) & 0xFF; @@ -378,10 +375,10 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) * still be one byte because the extra address bits are * hidden in the chip address. */ - if( alen > 0 ) + if (alen > 0) chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW); #endif - if( (ret = i2c_transfer( 1, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) { + if ((ret = i2c_transfer(1, chip<<1, &xaddr[4-alen], alen, buffer, len)) != 0) { if (gd->have_console) printf( "I2c read: failed %d\n", ret); return 1; @@ -389,16 +386,17 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) return 0; } -int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len) { uchar xaddr[4]; - if ( alen > 4 ) { + if (alen > 4) { printf ("I2C write: addr len %d not supported\n", alen); return 1; } - if ( alen > 0 ) { + + if (alen > 0) { xaddr[0] = (addr >> 24) & 0xFF; xaddr[1] = (addr >> 16) & 0xFF; xaddr[2] = (addr >> 8) & 0xFF; @@ -417,11 +415,11 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) * still be one byte because the extra address bits are * hidden in the chip address. */ - if( alen > 0 ) + if (alen > 0) chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW); #endif - return (i2c_transfer( 0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0); + return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0); } /*----------------------------------------------------------------------- @@ -433,7 +431,7 @@ uchar i2c_reg_read(uchar i2c_addr, uchar reg) i2c_read(i2c_addr, reg, 1, &buf, 1); - return(buf); + return (buf); } /*----------------------------------------------------------------------- @@ -443,4 +441,38 @@ void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) { i2c_write(i2c_addr, reg, 1, &val, 1); } + +#if defined(CONFIG_I2C_MULTI_BUS) +/* + * Functions for multiple I2C bus handling + */ +unsigned int i2c_get_bus_num(void) +{ + return i2c_bus_num; +} + +int i2c_set_bus_num(unsigned int bus) +{ + if (bus >= CFG_MAX_I2C_BUS) + return -1; + + i2c_bus_num = bus; + + return 0; +} + +/* TODO: add 100/400k switching */ +unsigned int i2c_get_bus_speed(void) +{ + return CFG_I2C_SPEED; +} + +int i2c_set_bus_speed(unsigned int speed) +{ + if (speed != CFG_I2C_SPEED) + return -1; + + return 0; +} +#endif /* CONFIG_I2C_MULTI_BUS */ #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 2d16a83420..06220c3439 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -331,7 +331,7 @@ void get_sys_info (sys_info_t * sysInfo) unsigned long m; unsigned long prbdv0; -#if defined(CONFIG_440SPE) +#if defined(CONFIG_YUCCA) unsigned long sys_freq; unsigned long sys_per=0; unsigned long msr; @@ -348,7 +348,7 @@ void get_sys_info (sys_info_t * sysInfo) /*-------------------------------------------------------------------------+ | Calculate the system clock speed from the period. +-------------------------------------------------------------------------*/ - sys_freq=(ONE_BILLION/sys_per)*1000; + sys_freq = (ONE_BILLION / sys_per) * 1000; #endif /* Extract configured divisors */ @@ -385,17 +385,17 @@ void get_sys_info (sys_info_t * sysInfo) m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB; /* Now calculate the individual clocks */ -#if defined(CONFIG_440SPE) +#if defined(CONFIG_YUCCA) sysInfo->freqVCOMhz = (m * sys_freq) ; #else - sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1); + sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m >> 1); #endif sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA; sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0; sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv; sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv; -#if defined(CONFIG_440SPE) +#if defined(CONFIG_YUCCA) /* Determine PCI Clock Period */ pci_clock_per = determine_pci_clock_per(); sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000; @@ -408,7 +408,7 @@ void get_sys_info (sys_info_t * sysInfo) #endif -#if defined(CONFIG_440SPE) +#if defined(CONFIG_YUCCA) unsigned long determine_sysper(void) { unsigned int fpga_clocking_reg; @@ -583,7 +583,6 @@ unsigned long determine_sysper(void) } return(sys_per); - } /*-------------------------------------------------------------------------+ diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 8e000d3092..200f7b31ad 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -1856,3 +1856,60 @@ pll_wait: /* execution will continue from the poweron */ /* vector of 0xfffffffc */ #endif /* CONFIG_405EP */ + +#if defined(CONFIG_440) +#define function_prolog(func_name) .text; \ + .align 2; \ + .globl func_name; \ + func_name: +#define function_epilog(func_name) .type func_name,@function; \ + .size func_name,.-func_name + +/*----------------------------------------------------------------------------+ +| mttlb3. ++----------------------------------------------------------------------------*/ + function_prolog(mttlb3) + TLBWE(4,3,2) + blr + function_epilog(mttlb3) + +/*----------------------------------------------------------------------------+ +| mftlb3. ++----------------------------------------------------------------------------*/ + function_prolog(mftlb3) + TLBRE(3,3,2) + blr + function_epilog(mftlb3) + +/*----------------------------------------------------------------------------+ +| mttlb2. ++----------------------------------------------------------------------------*/ + function_prolog(mttlb2) + TLBWE(4,3,1) + blr + function_epilog(mttlb2) + +/*----------------------------------------------------------------------------+ +| mftlb2. ++----------------------------------------------------------------------------*/ + function_prolog(mftlb2) + TLBRE(3,3,1) + blr + function_epilog(mftlb2) + +/*----------------------------------------------------------------------------+ +| mttlb1. ++----------------------------------------------------------------------------*/ + function_prolog(mttlb1) + TLBWE(4,3,0) + blr + function_epilog(mttlb1) + +/*----------------------------------------------------------------------------+ +| mftlb1. ++----------------------------------------------------------------------------*/ + function_prolog(mftlb1) + TLBRE(3,3,0) + blr + function_epilog(mftlb1) +#endif /* CONFIG_440 */ diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c new file mode 100644 index 0000000000..e26e6d4020 --- /dev/null +++ b/cpu/ppc4xx/tlb.c @@ -0,0 +1,184 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@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 + +#if defined(CONFIG_440) + +#include +#include +#include +#include + +typedef struct region { + unsigned long base; + unsigned long size; + unsigned long tlb_word2_i_value; +} region_t; + +static int add_tlb_entry(unsigned long base_addr, + unsigned long tlb_word0_size_value, + unsigned long tlb_word2_i_value) +{ + int i; + unsigned long tlb_word0_value; + unsigned long tlb_word1_value; + unsigned long tlb_word2_value; + + /* First, find the index of a TLB entry not being used */ + for (i=0; i= PPC4XX_TLB_SIZE) + return -1; + + /* Second, create the TLB entry */ + tlb_word0_value = TLB_WORD0_EPN_ENCODE(base_addr) | TLB_WORD0_V_ENABLE | + TLB_WORD0_TS_0 | tlb_word0_size_value; + tlb_word1_value = TLB_WORD1_RPN_ENCODE(base_addr) | TLB_WORD1_ERPN_ENCODE(0); + tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE | + TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE | + TLB_WORD2_W_DISABLE | tlb_word2_i_value | + TLB_WORD2_M_DISABLE | TLB_WORD2_G_DISABLE | + TLB_WORD2_E_DISABLE | TLB_WORD2_UX_ENABLE | + TLB_WORD2_UW_ENABLE | TLB_WORD2_UR_ENABLE | + TLB_WORD2_SX_ENABLE | TLB_WORD2_SW_ENABLE | + TLB_WORD2_SR_ENABLE; + + /* Wait for all memory accesses to complete */ + sync(); + + /* Third, add the TLB entries */ + mttlb1(i, tlb_word0_value); + mttlb2(i, tlb_word1_value); + mttlb3(i, tlb_word2_value); + + /* Execute an ISYNC instruction so that the new TLB entry takes effect */ + asm("isync"); + + return 0; +} + +static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size, + unsigned long tlb_word2_i_value) +{ + int rc; + int tlb_i; + + tlb_i = tlb_word2_i_value; + while (mem_size != 0) { + rc = 0; + /* Add the TLB entries in to map the region. */ + if (((base_addr & TLB_256MB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_256MB_SIZE)) { + /* Add a 256MB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256MB, tlb_i)) == 0) { + mem_size -= TLB_256MB_SIZE; + base_addr += TLB_256MB_SIZE; + } + } else if (((base_addr & TLB_16MB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_16MB_SIZE)) { + /* Add a 16MB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16MB, tlb_i)) == 0) { + mem_size -= TLB_16MB_SIZE; + base_addr += TLB_16MB_SIZE; + } + } else if (((base_addr & TLB_1MB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_1MB_SIZE)) { + /* Add a 1MB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1MB, tlb_i)) == 0) { + mem_size -= TLB_1MB_SIZE; + base_addr += TLB_1MB_SIZE; + } + } else if (((base_addr & TLB_256KB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_256KB_SIZE)) { + /* Add a 256KB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256KB, tlb_i)) == 0) { + mem_size -= TLB_256KB_SIZE; + base_addr += TLB_256KB_SIZE; + } + } else if (((base_addr & TLB_64KB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_64KB_SIZE)) { + /* Add a 64KB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_64KB, tlb_i)) == 0) { + mem_size -= TLB_64KB_SIZE; + base_addr += TLB_64KB_SIZE; + } + } else if (((base_addr & TLB_16KB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_16KB_SIZE)) { + /* Add a 16KB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16KB, tlb_i)) == 0) { + mem_size -= TLB_16KB_SIZE; + base_addr += TLB_16KB_SIZE; + } + } else if (((base_addr & TLB_4KB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_4KB_SIZE)) { + /* Add a 4KB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_4KB, tlb_i)) == 0) { + mem_size -= TLB_4KB_SIZE; + base_addr += TLB_4KB_SIZE; + } + } else if (((base_addr & TLB_1KB_ALIGN_MASK) == base_addr) && + (mem_size >= TLB_1KB_SIZE)) { + /* Add a 1KB TLB entry */ + if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1KB, tlb_i)) == 0) { + mem_size -= TLB_1KB_SIZE; + base_addr += TLB_1KB_SIZE; + } + } else { + printf("ERROR: no TLB size exists for the base address 0x%0X.\n", + base_addr); + } + + if (rc != 0) + printf("ERROR: no TLB entries available for the base addr 0x%0X.\n", + base_addr); + } + + return; +} + +/* + * Program one (or multiple) TLB entries for one memory region + * + * Common usage for boards with SDRAM DIMM modules to dynamically + * configure the TLB's for the SDRAM + */ +void program_tlb(u32 start, u32 size) +{ + region_t region_array; + + region_array.base = start; + region_array.size = size; + region_array.tlb_word2_i_value = TLB_WORD2_I_ENABLE; /* disable cache (for now) */ + + /* Call the routine to add in the tlb entries for the memory regions */ + program_tlb_addr(region_array.base, region_array.size, + region_array.tlb_word2_i_value); + + return; +} + +#endif /* CONFIG_440 */ diff --git a/cpu/pxa/mmc.c b/cpu/pxa/mmc.c index f7020eec95..0fbaa162fa 100644 --- a/cpu/pxa/mmc.c +++ b/cpu/pxa/mmc.c @@ -37,7 +37,7 @@ static block_dev_desc_t mmc_dev; block_dev_desc_t * mmc_get_dev(int dev) { - return ((block_dev_desc_t *)&mmc_dev); + return (dev == 0) ? &mmc_dev : NULL; } /* @@ -363,7 +363,7 @@ mmc_write(uchar *src, ulong dst, int size) ulong /****************************************************/ -mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst) +mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) /****************************************************/ { int mmc_block_size = MMC_BLOCK_SIZE; diff --git a/disk/part.c b/disk/part.c index 2255e726cf..9e8bd4fb88 100644 --- a/disk/part.c +++ b/disk/part.c @@ -24,6 +24,7 @@ #include #include #include +#include #undef PART_DEBUG @@ -33,6 +34,58 @@ #define PRINTF(fmt,args...) #endif +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ + (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ + (CONFIG_COMMANDS & CFG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) ) + +struct block_drvr { + char *name; + block_dev_desc_t* (*get_dev)(int dev); +}; + +static const struct block_drvr block_drvr[] = { +#if (CONFIG_COMMANDS & CFG_CMD_IDE) + { .name = "ide", .get_dev = ide_get_dev, }, +#endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) + { .name = "scsi", .get_dev = scsi_get_dev, }, +#endif +#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) + { .name = "usb", .get_dev = usb_stor_get_dev, }, +#endif +#if defined(CONFIG_MMC) + { .name = "mmc", .get_dev = mmc_get_dev, }, +#endif +#if defined(CONFIG_SYSTEMACE) + { .name = "ace", .get_dev = systemace_get_dev, }, +#endif + { }, +}; + +DECLARE_GLOBAL_DATA_PTR; + +block_dev_desc_t *get_dev(char* ifname, int dev) +{ + const struct block_drvr *drvr = block_drvr; + block_dev_desc_t* (*reloc_get_dev)(int dev); + + while (drvr->name) { + reloc_get_dev = drvr->get_dev + gd->reloc_off; + if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0) + return reloc_get_dev(dev); + drvr++; + } + return NULL; +} +#else +block_dev_desc_t *get_dev(char* ifname, int dev) +{ + return NULL; +} +#endif + #if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ (CONFIG_COMMANDS & CFG_CMD_USB) || \ diff --git a/drivers/Makefile b/drivers/Makefile index 5a369df2c4..fffc22a5e1 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -44,7 +44,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.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 ahci.o \ + status_led.o sym53c8xx.o systemace.o ahci.o \ ti_pci1410a.o tigon3.o tsec.o \ usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \ videomodes.o w83c553f.o \ diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index 696f9a47ad..5579a1efc1 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #ifdef CFG_FLASH_CFI_DRIVER @@ -931,27 +932,18 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd, cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.cp = cword.c; -#ifdef CONFIG_BLACKFIN - asm("ssync;"); -#endif break; case FLASH_CFI_16BIT: debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp, cmd, cword.w, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.wp = cword.w; -#ifdef CONFIG_BLACKFIN - asm("ssync;"); -#endif break; case FLASH_CFI_32BIT: debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp, cmd, cword.l, info->chipwidth << CFI_FLASH_SHIFT_WIDTH); *addr.lp = cword.l; -#ifdef CONFIG_BLACKFIN - asm("ssync;"); -#endif break; case FLASH_CFI_64BIT: #ifdef DEBUG @@ -966,11 +958,11 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset } #endif *addr.llp = cword.ll; -#ifdef CONFIG_BLACKFIN - asm("ssync;"); -#endif break; } + + /* Ensure all the instructions are fully finished */ + sync(); } static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect) diff --git a/drivers/systemace.c b/drivers/systemace.c new file mode 100644 index 0000000000..3848d9c59c --- /dev/null +++ b/drivers/systemace.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + * Stephen Williams (XXXXXXXXXXXXXXXX) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form 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 + */ + +/* + * The Xilinx SystemACE chip support is activated by defining + * CONFIG_SYSTEMACE to turn on support, and CFG_SYSTEMACE_BASE + * to set the base address of the device. This code currently + * assumes that the chip is connected via a byte-wide bus. + * + * The CONFIG_SYSTEMACE also adds to fat support the device class + * "ace" that allows the user to execute "fatls ace 0" and the + * like. This works by making the systemace_get_dev function + * available to cmd_fat.c:get_dev and filling in a block device + * description that has all the bits needed for FAT support to + * read sectors. + * + * According to Xilinx technical support, before accessing the + * SystemACE CF you need to set the following control bits: + * FORCECFGMODE : 1 + * CFGMODE : 0 + * CFGSTART : 0 + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_SYSTEMACE + +/* + * The ace_readw and writew functions read/write 16bit words, but the + * offset value is the BYTE offset as most used in the Xilinx + * datasheet for the SystemACE chip. The CFG_SYSTEMACE_BASE is defined + * to be the base address for the chip, usually in the local + * peripheral bus. + */ +#if (CFG_SYSTEMACE_WIDTH == 8) +#if !defined(__BIG_ENDIAN) +#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)<<8) | \ + (readb(CFG_SYSTEMACE_BASE+off+1))) +#define ace_writew(val, off) {writeb(val>>8, CFG_SYSTEMACE_BASE+off); \ + writeb(val, CFG_SYSTEMACE_BASE+off+1);} +#else +#define ace_readw(off) ((readb(CFG_SYSTEMACE_BASE+off)) | \ + (readb(CFG_SYSTEMACE_BASE+off+1)<<8)) +#define ace_writew(val, off) {writeb(val, CFG_SYSTEMACE_BASE+off); \ + writeb(val>>8, CFG_SYSTEMACE_BASE+off+1);} +#endif +#else +#define ace_readw(off) (in16(CFG_SYSTEMACE_BASE+off)) +#define ace_writew(val, off) (out16(CFG_SYSTEMACE_BASE+off,val)) +#endif + +/* */ + +static unsigned long systemace_read(int dev, unsigned long start, + unsigned long blkcnt, void *buffer); + +static block_dev_desc_t systemace_dev = { 0 }; + +static int get_cf_lock(void) +{ + int retry = 10; + + /* CONTROLREG = LOCKREG */ + unsigned val = ace_readw(0x18); + val |= 0x0002; + ace_writew((val & 0xffff), 0x18); + + /* Wait for MPULOCK in STATUSREG[15:0] */ + while (!(ace_readw(0x04) & 0x0002)) { + + if (retry < 0) + return -1; + + udelay(100000); + retry -= 1; + } + + return 0; +} + +static void release_cf_lock(void) +{ + unsigned val = ace_readw(0x18); + val &= ~(0x0002); + ace_writew((val & 0xffff), 0x18); +} + +block_dev_desc_t *systemace_get_dev(int dev) +{ + /* The first time through this, the systemace_dev object is + not yet initialized. In that case, fill it in. */ + if (systemace_dev.blksz == 0) { + systemace_dev.if_type = IF_TYPE_UNKNOWN; + systemace_dev.dev = 0; + systemace_dev.part_type = PART_TYPE_UNKNOWN; + systemace_dev.type = DEV_TYPE_HARDDISK; + systemace_dev.blksz = 512; + systemace_dev.removable = 1; + systemace_dev.block_read = systemace_read; + + /* + * Ensure the correct bus mode (8/16 bits) gets enabled + */ + ace_writew(CFG_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0); + + init_part(&systemace_dev); + + } + + return &systemace_dev; +} + +/* + * This function is called (by dereferencing the block_read pointer in + * the dev_desc) to read blocks of data. The return value is the + * number of blocks read. A zero return indicates an error. + */ +static unsigned long systemace_read(int dev, unsigned long start, + unsigned long blkcnt, void *buffer) +{ + int retry; + unsigned blk_countdown; + unsigned char *dp = buffer; + unsigned val; + + if (get_cf_lock() < 0) { + unsigned status = ace_readw(0x04); + + /* If CFDETECT is false, card is missing. */ + if (!(status & 0x0010)) { + printf("** CompactFlash card not present. **\n"); + return 0; + } + + printf("**** ACE locked away from me (STATUSREG=%04x)\n", + status); + return 0; + } +#ifdef DEBUG_SYSTEMACE + printf("... systemace read %lu sectors at %lu\n", blkcnt, start); +#endif + + retry = 2000; + for (;;) { + val = ace_readw(0x04); + + /* If CFDETECT is false, card is missing. */ + if (!(val & 0x0010)) { + printf("**** ACE CompactFlash not found.\n"); + release_cf_lock(); + return 0; + } + + /* If RDYFORCMD, then we are ready to go. */ + if (val & 0x0100) + break; + + if (retry < 0) { + printf("**** SystemACE not ready.\n"); + release_cf_lock(); + return 0; + } + + udelay(1000); + retry -= 1; + } + + /* The SystemACE can only transfer 256 sectors at a time, so + limit the current chunk of sectors. The blk_countdown + variable is the number of sectors left to transfer. */ + + blk_countdown = blkcnt; + while (blk_countdown > 0) { + unsigned trans = blk_countdown; + + if (trans > 256) + trans = 256; + +#ifdef DEBUG_SYSTEMACE + printf("... transfer %lu sector in a chunk\n", trans); +#endif + /* Write LBA block address */ + ace_writew((start >> 0) & 0xffff, 0x10); + ace_writew((start >> 16) & 0x0fff, 0x12); + + /* NOTE: in the Write Sector count below, a count of 0 + causes a transfer of 256, so &0xff gives the right + value for whatever transfer count we want. */ + + /* Write sector count | ReadMemCardData. */ + ace_writew((trans & 0xff) | 0x0300, 0x14); + + /* Reset the configruation controller */ + val = ace_readw(0x18); + val |= 0x0080; + ace_writew(val, 0x18); + + retry = trans * 16; + while (retry > 0) { + int idx; + + /* Wait for buffer to become ready. */ + while (!(ace_readw(0x04) & 0x0020)) { + udelay(100); + } + + /* Read 16 words of 2bytes from the sector buffer. */ + for (idx = 0; idx < 16; idx += 1) { + unsigned short val = ace_readw(0x40); + *dp++ = val & 0xff; + *dp++ = (val >> 8) & 0xff; + } + + retry -= 1; + } + + /* Clear the configruation controller reset */ + val = ace_readw(0x18); + val &= ~0x0080; + ace_writew(val, 0x18); + + /* Count the blocks we transfer this time. */ + start += trans; + blk_countdown -= trans; + } + + release_cf_lock(); + + return blkcnt; +} +#endif /* CONFIG_SYSTEMACE */ diff --git a/dtt/adm1021.c b/dtt/adm1021.c index 14c38f0a83..9f65cfb274 100644 --- a/dtt/adm1021.c +++ b/dtt/adm1021.c @@ -144,12 +144,15 @@ dtt_init (void) unsigned char sensors[] = CONFIG_DTT_SENSORS; const char *const header = "DTT: "; + /* switch to correct I2C bus */ + I2C_SET_BUS(CFG_DTT_BUS_NUM); + for (i = 0; i < sizeof(sensors); i++) { - if (_dtt_init(sensors[i]) != 0) - printf ("%s%d FAILED INIT\n", header, i+1); - else - printf ("%s%d is %i C\n", header, i+1, - dtt_get_temp(sensors[i])); + if (_dtt_init(sensors[i]) != 0) + printf ("%s%d FAILED INIT\n", header, i+1); + else + printf ("%s%d is %i C\n", header, i+1, + dtt_get_temp(sensors[i])); } return (0); diff --git a/include/405gp_i2c.h b/include/405gp_i2c.h deleted file mode 100644 index 5a9a497536..0000000000 --- a/include/405gp_i2c.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _405gp_i2c_h_ -#define _405gp_i2c_h_ - -#define I2C_REGISTERS_BASE_ADDRESS 0xEF600500 -#define IIC_MDBUF (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF) -#define IIC_SDBUF (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF) -#define IIC_LMADR (I2C_REGISTERS_BASE_ADDRESS+IICLMADR) -#define IIC_HMADR (I2C_REGISTERS_BASE_ADDRESS+IICHMADR) -#define IIC_CNTL (I2C_REGISTERS_BASE_ADDRESS+IICCNTL) -#define IIC_MDCNTL (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL) -#define IIC_STS (I2C_REGISTERS_BASE_ADDRESS+IICSTS) -#define IIC_EXTSTS (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS) -#define IIC_LSADR (I2C_REGISTERS_BASE_ADDRESS+IICLSADR) -#define IIC_HSADR (I2C_REGISTERS_BASE_ADDRESS+IICHSADR) -#define IIC_CLKDIV (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV) -#define IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK) -#define IIC_XFRCNT (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT) -#define IIC_XTCNTLSS (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS) -#define IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL) - -/* MDCNTL Register Bit definition */ -#define IIC_MDCNTL_HSCL 0x01 -#define IIC_MDCNTL_EUBS 0x02 -#define IIC_MDCNTL_EINT 0x04 -#define IIC_MDCNTL_ESM 0x08 -#define IIC_MDCNTL_FSM 0x10 -#define IIC_MDCNTL_EGC 0x20 -#define IIC_MDCNTL_FMDB 0x40 -#define IIC_MDCNTL_FSDB 0x80 - -/* CNTL Register Bit definition */ -#define IIC_CNTL_PT 0x01 -#define IIC_CNTL_READ 0x02 -#define IIC_CNTL_CHT 0x04 -#define IIC_CNTL_RPST 0x08 -/* bit 2/3 for Transfer count*/ -#define IIC_CNTL_AMD 0x40 -#define IIC_CNTL_HMT 0x80 - -/* STS Register Bit definition */ -#define IIC_STS_PT 0X01 -#define IIC_STS_IRQA 0x02 -#define IIC_STS_ERR 0X04 -#define IIC_STS_SCMP 0x08 -#define IIC_STS_MDBF 0x10 -#define IIC_STS_MDBS 0X20 -#define IIC_STS_SLPR 0x40 -#define IIC_STS_SSS 0x80 - -/* EXTSTS Register Bit definition */ -#define IIC_EXTSTS_XFRA 0X01 -#define IIC_EXTSTS_ICT 0X02 -#define IIC_EXTSTS_LA 0X04 - -/* XTCNTLSS Register Bit definition */ -#define IIC_XTCNTLSS_SRST 0x01 -#define IIC_XTCNTLSS_EPI 0x02 -#define IIC_XTCNTLSS_SDBF 0x04 -#define IIC_XTCNTLSS_SBDD 0x08 -#define IIC_XTCNTLSS_SWS 0x10 -#define IIC_XTCNTLSS_SWC 0x20 -#define IIC_XTCNTLSS_SRS 0x40 -#define IIC_XTCNTLSS_SRC 0x80 -#endif diff --git a/include/440_i2c.h b/include/440_i2c.h deleted file mode 100644 index 0c2bf36273..0000000000 --- a/include/440_i2c.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _440_i2c_h_ -#define _440_i2c_h_ - -#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -#define I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000700) -#else -#define I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000400) -#endif /*CONFIG_440EP CONFIG_440GR*/ - -#define I2C_REGISTERS_BASE_ADDRESS I2C_BASE_ADDR -#define IIC_MDBUF (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF) -#define IIC_SDBUF (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF) -#define IIC_LMADR (I2C_REGISTERS_BASE_ADDRESS+IICLMADR) -#define IIC_HMADR (I2C_REGISTERS_BASE_ADDRESS+IICHMADR) -#define IIC_CNTL (I2C_REGISTERS_BASE_ADDRESS+IICCNTL) -#define IIC_MDCNTL (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL) -#define IIC_STS (I2C_REGISTERS_BASE_ADDRESS+IICSTS) -#define IIC_EXTSTS (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS) -#define IIC_LSADR (I2C_REGISTERS_BASE_ADDRESS+IICLSADR) -#define IIC_HSADR (I2C_REGISTERS_BASE_ADDRESS+IICHSADR) -#define IIC_CLKDIV (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV) -#define IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK) -#define IIC_XFRCNT (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT) -#define IIC_XTCNTLSS (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS) -#define IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL) - -/* MDCNTL Register Bit definition */ -#define IIC_MDCNTL_HSCL 0x01 -#define IIC_MDCNTL_EUBS 0x02 -#define IIC_MDCNTL_EINT 0x04 -#define IIC_MDCNTL_ESM 0x08 -#define IIC_MDCNTL_FSM 0x10 -#define IIC_MDCNTL_EGC 0x20 -#define IIC_MDCNTL_FMDB 0x40 -#define IIC_MDCNTL_FSDB 0x80 - -/* CNTL Register Bit definition */ -#define IIC_CNTL_PT 0x01 -#define IIC_CNTL_READ 0x02 -#define IIC_CNTL_CHT 0x04 -#define IIC_CNTL_RPST 0x08 -/* bit 2/3 for Transfer count*/ -#define IIC_CNTL_AMD 0x40 -#define IIC_CNTL_HMT 0x80 - -/* STS Register Bit definition */ -#define IIC_STS_PT 0X01 -#define IIC_STS_IRQA 0x02 -#define IIC_STS_ERR 0X04 -#define IIC_STS_SCMP 0x08 -#define IIC_STS_MDBF 0x10 -#define IIC_STS_MDBS 0X20 -#define IIC_STS_SLPR 0x40 -#define IIC_STS_SSS 0x80 - -/* EXTSTS Register Bit definition */ -#define IIC_EXTSTS_XFRA 0X01 -#define IIC_EXTSTS_ICT 0X02 -#define IIC_EXTSTS_LA 0X04 - -/* XTCNTLSS Register Bit definition */ -#define IIC_XTCNTLSS_SRST 0x01 -#define IIC_XTCNTLSS_EPI 0x02 -#define IIC_XTCNTLSS_SDBF 0x04 -#define IIC_XTCNTLSS_SBDD 0x08 -#define IIC_XTCNTLSS_SWS 0x10 -#define IIC_XTCNTLSS_SWC 0x20 -#define IIC_XTCNTLSS_SRS 0x40 -#define IIC_XTCNTLSS_SRC 0x80 -#endif diff --git a/include/4xx_i2c.h b/include/4xx_i2c.h new file mode 100644 index 0000000000..66b7997419 --- /dev/null +++ b/include/4xx_i2c.h @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@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 + */ + +#ifndef _4xx_i2c_h_ +#define _4xx_i2c_h_ + +#define IIC_OK 0 +#define IIC_NOK 1 +#define IIC_NOK_LA 2 /* Lost arbitration */ +#define IIC_NOK_ICT 3 /* Incomplete transfer */ +#define IIC_NOK_XFRA 4 /* Transfer aborted */ +#define IIC_NOK_DATA 5 /* No data in buffer */ +#define IIC_NOK_TOUT 6 /* Transfer timeout */ + +#define IIC_TIMEOUT 1 /* 1 second */ + +#if defined(CONFIG_I2C_MULTI_BUS) +#define I2C_BUS_OFFS (i2c_bus_num * 0x100) +#else +#define I2C_BUS_OFFS (0x000) +#endif /* CONFIG_I2C_MULTI_BUS */ + +#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) +#define I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000700 + I2C_BUS_OFFS) +#elif defined(CONFIG_440) +/* all remaining 440 variants */ +#define I2C_BASE_ADDR (CFG_PERIPHERAL_BASE + 0x00000400 + I2C_BUS_OFFS) +#else +/* all 405 variants */ +#define I2C_BASE_ADDR (0xEF600500 + I2C_BUS_OFFS) +#endif + +#define I2C_REGISTERS_BASE_ADDRESS I2C_BASE_ADDR +#define IIC_MDBUF (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF) +#define IIC_SDBUF (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF) +#define IIC_LMADR (I2C_REGISTERS_BASE_ADDRESS+IICLMADR) +#define IIC_HMADR (I2C_REGISTERS_BASE_ADDRESS+IICHMADR) +#define IIC_CNTL (I2C_REGISTERS_BASE_ADDRESS+IICCNTL) +#define IIC_MDCNTL (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL) +#define IIC_STS (I2C_REGISTERS_BASE_ADDRESS+IICSTS) +#define IIC_EXTSTS (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS) +#define IIC_LSADR (I2C_REGISTERS_BASE_ADDRESS+IICLSADR) +#define IIC_HSADR (I2C_REGISTERS_BASE_ADDRESS+IICHSADR) +#define IIC_CLKDIV (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV) +#define IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK) +#define IIC_XFRCNT (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT) +#define IIC_XTCNTLSS (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS) +#define IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL) + +/* MDCNTL Register Bit definition */ +#define IIC_MDCNTL_HSCL 0x01 +#define IIC_MDCNTL_EUBS 0x02 +#define IIC_MDCNTL_EINT 0x04 +#define IIC_MDCNTL_ESM 0x08 +#define IIC_MDCNTL_FSM 0x10 +#define IIC_MDCNTL_EGC 0x20 +#define IIC_MDCNTL_FMDB 0x40 +#define IIC_MDCNTL_FSDB 0x80 + +/* CNTL Register Bit definition */ +#define IIC_CNTL_PT 0x01 +#define IIC_CNTL_READ 0x02 +#define IIC_CNTL_CHT 0x04 +#define IIC_CNTL_RPST 0x08 +/* bit 2/3 for Transfer count*/ +#define IIC_CNTL_AMD 0x40 +#define IIC_CNTL_HMT 0x80 + +/* STS Register Bit definition */ +#define IIC_STS_PT 0x01 +#define IIC_STS_IRQA 0x02 +#define IIC_STS_ERR 0x04 +#define IIC_STS_SCMP 0x08 +#define IIC_STS_MDBF 0x10 +#define IIC_STS_MDBS 0x20 +#define IIC_STS_SLPR 0x40 +#define IIC_STS_SSS 0x80 + +/* EXTSTS Register Bit definition */ +#define IIC_EXTSTS_XFRA 0x01 +#define IIC_EXTSTS_ICT 0x02 +#define IIC_EXTSTS_LA 0x04 + +/* XTCNTLSS Register Bit definition */ +#define IIC_XTCNTLSS_SRST 0x01 +#define IIC_XTCNTLSS_EPI 0x02 +#define IIC_XTCNTLSS_SDBF 0x04 +#define IIC_XTCNTLSS_SBDD 0x08 +#define IIC_XTCNTLSS_SWS 0x10 +#define IIC_XTCNTLSS_SWC 0x20 +#define IIC_XTCNTLSS_SRS 0x40 +#define IIC_XTCNTLSS_SRC 0x80 + +/* IICx_DIRECTCNTL register */ +#define IIC_DIRCNTL_SDAC 0x08 +#define IIC_DIRCNTL_SCC 0x04 +#define IIC_DIRCNTL_MSDA 0x02 +#define IIC_DIRCNTL_MSC 0x01 + +#define DIRCTNL_FREE(v) (((v) & 0x0f) == 0x0f) +#endif diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 648a10dd92..47c18e7e86 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -29,6 +29,10 @@ #include #endif /* XXX###XXX */ +static inline void sync(void) +{ +} + /* * Generic virtual read/write. Note that we don't support half-word * read/writes. We define __arch_*[bl] here, and leave __arch_*w diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h index e86c456ae1..3c0d569233 100644 --- a/include/asm-avr32/io.h +++ b/include/asm-avr32/io.h @@ -89,4 +89,8 @@ static __inline__ void * phys_to_virt(unsigned long address) #endif /* __KERNEL__ */ +static inline void sync(void) +{ +} + #endif /* __ASM_AVR32_IO_H */ diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h index e5b388e262..fc27194a42 100644 --- a/include/asm-blackfin/io.h +++ b/include/asm-blackfin/io.h @@ -25,6 +25,11 @@ #ifndef _BLACKFIN_IO_H #define _BLACKFIN_IO_H +static inline void sync(void) +{ + __asm__ __volatile__ asm("ssync" : : : "memory"); +} + #ifdef __KERNEL__ #include diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 85d44aaa15..e64d788fa7 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -201,4 +201,8 @@ __OUTS(b) __OUTS(w) __OUTS(l) +static inline void sync(void) +{ +} + #endif diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index 79a9626b55..7bbdefba76 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h @@ -1 +1,8 @@ -/* */ +#ifndef __ASM_M68K_IO_H_ +#define __ASM_M68K_IO_H_ + +static inline void sync(void) +{ +} + +#endif /* __ASM_M68K_IO_H_ */ diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h index 33590454cf..1c77ade4f1 100644 --- a/include/asm-microblaze/io.h +++ b/include/asm-microblaze/io.h @@ -125,4 +125,8 @@ io_outsl (unsigned long port, const void *src, unsigned long count) #define ioremap_writethrough(physaddr, size) (physaddr) #define ioremap_fullcache(physaddr, size) (physaddr) +static inline void sync(void) +{ +} + #endif /* __MICROBLAZE_IO_H__ */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 857fb0302c..cd4d5dc9d9 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -447,4 +447,8 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); #define dma_cache_wback(start,size) _dma_cache_wback(start,size) #define dma_cache_inv(start,size) _dma_cache_inv(start,size) +static inline void sync(void) +{ +} + #endif /* _ASM_IO_H */ diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h index 07499d966d..d77695abb9 100644 --- a/include/asm-nios/io.h +++ b/include/asm-nios/io.h @@ -97,4 +97,8 @@ static inline void outsl (unsigned long port, const void *src, unsigned long cou while (count--) outl (*p++, port); } +static inline void sync(void) +{ +} + #endif /* __ASM_NIOS_IO_H_ */ diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h index 0fab53bf0e..5bb5322952 100644 --- a/include/asm-nios2/io.h +++ b/include/asm-nios2/io.h @@ -24,7 +24,10 @@ #ifndef __ASM_NIOS2_IO_H_ #define __ASM_NIOS2_IO_H_ -#define sync() asm volatile ("sync" : : : "memory"); +static inline void sync(void) +{ + __asm__ __volatile__ ("sync" : : : "memory"); +} extern unsigned char inb (unsigned char *port); extern unsigned short inw (unsigned short *port); diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 8e5fe113cb..bbc9ba0be6 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -95,8 +95,15 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); * Acts as a barrier to ensure all previous I/O accesses have * completed before any further ones are issued. */ -#define eieio() __asm__ __volatile__ ("eieio" : : : "memory"); -#define sync() __asm__ __volatile__ ("sync" : : : "memory"); +static inline void eieio(void) +{ + __asm__ __volatile__ ("eieio" : : : "memory"); +} + +static inline void sync(void) +{ + __asm__ __volatile__ ("sync" : : : "memory"); +} /* Enforce in-order execution of data I/O. * No distinction between read/write on PPC; use eieio for all three. diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 914f28b461..b226825ee2 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -335,41 +335,6 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); * instructions. */ -#define TLB_LO 1 -#define TLB_HI 0 - -#define TLB_DATA TLB_LO -#define TLB_TAG TLB_HI - -/* Tag portion */ - -#define TLB_EPN_MASK 0xFFFFFC00 /* Effective Page Number */ -#define TLB_PAGESZ_MASK 0x00000380 -#define TLB_PAGESZ(x) (((x) & 0x7) << 7) -#define PAGESZ_1K 0 -#define PAGESZ_4K 1 -#define PAGESZ_16K 2 -#define PAGESZ_64K 3 -#define PAGESZ_256K 4 -#define PAGESZ_1M 5 -#define PAGESZ_4M 6 -#define PAGESZ_16M 7 -#define TLB_VALID 0x00000040 /* Entry is valid */ - -/* Data portion */ - -#define TLB_RPN_MASK 0xFFFFFC00 /* Real Page Number */ -#define TLB_PERM_MASK 0x00000300 -#define TLB_EX 0x00000200 /* Instruction execution allowed */ -#define TLB_WR 0x00000100 /* Writes permitted */ -#define TLB_ZSEL_MASK 0x000000F0 -#define TLB_ZSEL(x) (((x) & 0xF) << 4) -#define TLB_ATTR_MASK 0x0000000F -#define TLB_W 0x00000008 /* Caching is write-through */ -#define TLB_I 0x00000004 /* Caching is inhibited */ -#define TLB_M 0x00000002 /* Memory is coherent */ -#define TLB_G 0x00000001 /* Memory is guarded from prefetch */ - /* * e500 support */ @@ -482,7 +447,162 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); #define LAWAR_SIZE_16G (LAWAR_SIZE_BASE+23) #define LAWAR_SIZE_32G (LAWAR_SIZE_BASE+24) -#ifdef CONFIG_440SPE +#ifdef CONFIG_440 +/* General */ +#define TLB_VALID 0x00000200 + +/* Supported page sizes */ + +#define SZ_1K 0x00000000 +#define SZ_4K 0x00000010 +#define SZ_16K 0x00000020 +#define SZ_64K 0x00000030 +#define SZ_256K 0x00000040 +#define SZ_1M 0x00000050 +#define SZ_16M 0x00000070 +#define SZ_256M 0x00000090 + +/* Storage attributes */ +#define SA_W 0x00000800 /* Write-through */ +#define SA_I 0x00000400 /* Caching inhibited */ +#define SA_M 0x00000200 /* Memory coherence */ +#define SA_G 0x00000100 /* Guarded */ +#define SA_E 0x00000080 /* Endian */ + +/* Access control */ +#define AC_X 0x00000024 /* Execute */ +#define AC_W 0x00000012 /* Write */ +#define AC_R 0x00000009 /* Read */ + +/* Some handy macros */ + +#define EPN(e) ((e) & 0xfffffc00) +#define TLB0(epn,sz) ((EPN((epn)) | (sz) | TLB_VALID )) +#define TLB1(rpn,erpn) (((rpn) & 0xfffffc00) | (erpn)) +#define TLB2(a) ((a) & 0x00000fbf) + +#define tlbtab_start\ + mflr r1 ;\ + bl 0f ; + +#define tlbtab_end\ + .long 0, 0, 0 ;\ +0: mflr r0 ;\ + mtlr r1 ;\ + blr ; + +#define tlbentry(epn,sz,rpn,erpn,attr)\ + .long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr) + +/*----------------------------------------------------------------------------+ +| TLB specific defines. ++----------------------------------------------------------------------------*/ +#define TLB_256MB_ALIGN_MASK 0xF0000000 +#define TLB_16MB_ALIGN_MASK 0xFF000000 +#define TLB_1MB_ALIGN_MASK 0xFFF00000 +#define TLB_256KB_ALIGN_MASK 0xFFFC0000 +#define TLB_64KB_ALIGN_MASK 0xFFFF0000 +#define TLB_16KB_ALIGN_MASK 0xFFFFC000 +#define TLB_4KB_ALIGN_MASK 0xFFFFF000 +#define TLB_1KB_ALIGN_MASK 0xFFFFFC00 +#define TLB_256MB_SIZE 0x10000000 +#define TLB_16MB_SIZE 0x01000000 +#define TLB_1MB_SIZE 0x00100000 +#define TLB_256KB_SIZE 0x00040000 +#define TLB_64KB_SIZE 0x00010000 +#define TLB_16KB_SIZE 0x00004000 +#define TLB_4KB_SIZE 0x00001000 +#define TLB_1KB_SIZE 0x00000400 + +#define TLB_WORD0_EPN_MASK 0xFFFFFC00 +#define TLB_WORD0_EPN_ENCODE(n) (((unsigned long)(n))&0xFFFFFC00) +#define TLB_WORD0_EPN_DECODE(n) (((unsigned long)(n))&0xFFFFFC00) +#define TLB_WORD0_V_MASK 0x00000200 +#define TLB_WORD0_V_ENABLE 0x00000200 +#define TLB_WORD0_V_DISABLE 0x00000000 +#define TLB_WORD0_TS_MASK 0x00000100 +#define TLB_WORD0_TS_1 0x00000100 +#define TLB_WORD0_TS_0 0x00000000 +#define TLB_WORD0_SIZE_MASK 0x000000F0 +#define TLB_WORD0_SIZE_1KB 0x00000000 +#define TLB_WORD0_SIZE_4KB 0x00000010 +#define TLB_WORD0_SIZE_16KB 0x00000020 +#define TLB_WORD0_SIZE_64KB 0x00000030 +#define TLB_WORD0_SIZE_256KB 0x00000040 +#define TLB_WORD0_SIZE_1MB 0x00000050 +#define TLB_WORD0_SIZE_16MB 0x00000070 +#define TLB_WORD0_SIZE_256MB 0x00000090 +#define TLB_WORD0_TPAR_MASK 0x0000000F +#define TLB_WORD0_TPAR_ENCODE(n) ((((unsigned long)(n))&0x0F)<<0) +#define TLB_WORD0_TPAR_DECODE(n) ((((unsigned long)(n))>>0)&0x0F) + +#define TLB_WORD1_RPN_MASK 0xFFFFFC00 +#define TLB_WORD1_RPN_ENCODE(n) (((unsigned long)(n))&0xFFFFFC00) +#define TLB_WORD1_RPN_DECODE(n) (((unsigned long)(n))&0xFFFFFC00) +#define TLB_WORD1_PAR1_MASK 0x00000300 +#define TLB_WORD1_PAR1_ENCODE(n) ((((unsigned long)(n))&0x03)<<8) +#define TLB_WORD1_PAR1_DECODE(n) ((((unsigned long)(n))>>8)&0x03) +#define TLB_WORD1_PAR1_0 0x00000000 +#define TLB_WORD1_PAR1_1 0x00000100 +#define TLB_WORD1_PAR1_2 0x00000200 +#define TLB_WORD1_PAR1_3 0x00000300 +#define TLB_WORD1_ERPN_MASK 0x0000000F +#define TLB_WORD1_ERPN_ENCODE(n) ((((unsigned long)(n))&0x0F)<<0) +#define TLB_WORD1_ERPN_DECODE(n) ((((unsigned long)(n))>>0)&0x0F) + +#define TLB_WORD2_PAR2_MASK 0xC0000000 +#define TLB_WORD2_PAR2_ENCODE(n) ((((unsigned long)(n))&0x03)<<30) +#define TLB_WORD2_PAR2_DECODE(n) ((((unsigned long)(n))>>30)&0x03) +#define TLB_WORD2_PAR2_0 0x00000000 +#define TLB_WORD2_PAR2_1 0x40000000 +#define TLB_WORD2_PAR2_2 0x80000000 +#define TLB_WORD2_PAR2_3 0xC0000000 +#define TLB_WORD2_U0_MASK 0x00008000 +#define TLB_WORD2_U0_ENABLE 0x00008000 +#define TLB_WORD2_U0_DISABLE 0x00000000 +#define TLB_WORD2_U1_MASK 0x00004000 +#define TLB_WORD2_U1_ENABLE 0x00004000 +#define TLB_WORD2_U1_DISABLE 0x00000000 +#define TLB_WORD2_U2_MASK 0x00002000 +#define TLB_WORD2_U2_ENABLE 0x00002000 +#define TLB_WORD2_U2_DISABLE 0x00000000 +#define TLB_WORD2_U3_MASK 0x00001000 +#define TLB_WORD2_U3_ENABLE 0x00001000 +#define TLB_WORD2_U3_DISABLE 0x00000000 +#define TLB_WORD2_W_MASK 0x00000800 +#define TLB_WORD2_W_ENABLE 0x00000800 +#define TLB_WORD2_W_DISABLE 0x00000000 +#define TLB_WORD2_I_MASK 0x00000400 +#define TLB_WORD2_I_ENABLE 0x00000400 +#define TLB_WORD2_I_DISABLE 0x00000000 +#define TLB_WORD2_M_MASK 0x00000200 +#define TLB_WORD2_M_ENABLE 0x00000200 +#define TLB_WORD2_M_DISABLE 0x00000000 +#define TLB_WORD2_G_MASK 0x00000100 +#define TLB_WORD2_G_ENABLE 0x00000100 +#define TLB_WORD2_G_DISABLE 0x00000000 +#define TLB_WORD2_E_MASK 0x00000080 +#define TLB_WORD2_E_ENABLE 0x00000080 +#define TLB_WORD2_E_DISABLE 0x00000000 +#define TLB_WORD2_UX_MASK 0x00000020 +#define TLB_WORD2_UX_ENABLE 0x00000020 +#define TLB_WORD2_UX_DISABLE 0x00000000 +#define TLB_WORD2_UW_MASK 0x00000010 +#define TLB_WORD2_UW_ENABLE 0x00000010 +#define TLB_WORD2_UW_DISABLE 0x00000000 +#define TLB_WORD2_UR_MASK 0x00000008 +#define TLB_WORD2_UR_ENABLE 0x00000008 +#define TLB_WORD2_UR_DISABLE 0x00000000 +#define TLB_WORD2_SX_MASK 0x00000004 +#define TLB_WORD2_SX_ENABLE 0x00000004 +#define TLB_WORD2_SX_DISABLE 0x00000000 +#define TLB_WORD2_SW_MASK 0x00000002 +#define TLB_WORD2_SW_ENABLE 0x00000002 +#define TLB_WORD2_SW_DISABLE 0x00000000 +#define TLB_WORD2_SR_MASK 0x00000001 +#define TLB_WORD2_SR_ENABLE 0x00000001 +#define TLB_WORD2_SR_DISABLE 0x00000000 + /*----------------------------------------------------------------------------+ | Following instructions are not available in Book E mode of the GNU assembler. +----------------------------------------------------------------------------*/ @@ -516,11 +636,15 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); #define MBAR_INST .long 0x7c000000|\ (854<<1) -/*----------------------------------------------------------------------------+ -| Following instruction is not available in PPC405 mode of the GNU assembler. -+----------------------------------------------------------------------------*/ -#define TLBRE(rt,ra,ws) .long 0x7c000000|\ - (rt<<21)|(ra<<16)|(ws<<11)|(946<<1) +#ifndef __ASSEMBLY__ +/* Prototypes */ +void mttlb1(unsigned long index, unsigned long value); +void mttlb2(unsigned long index, unsigned long value); +void mttlb3(unsigned long index, unsigned long value); +unsigned long mftlb1(unsigned long index); +unsigned long mftlb2(unsigned long index); +unsigned long mftlb3(unsigned long index); +#endif /* __ASSEMBLY__ */ -#endif +#endif /* CONFIG_440 */ #endif /* _PPC_MMU_H_ */ diff --git a/include/common.h b/include/common.h index 982d6a8637..b162dbd7cf 100644 --- a/include/common.h +++ b/include/common.h @@ -187,6 +187,7 @@ void hang (void) __attribute__ ((noreturn)); long int initdram (int); int display_options (void); void print_size (ulong, const char *); +int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen); /* common/main.c */ void main_loop (void); diff --git a/include/configs/katmai.h b/include/configs/katmai.h new file mode 100644 index 0000000000..c750e14656 --- /dev/null +++ b/include/configs/katmai.h @@ -0,0 +1,415 @@ +/* + * (C) Copyright 2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2004 Paul Reynolds + * + * 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 + */ + +/************************************************************************ + * katmai.h - configuration for AMCC Katmai (440SPe) + ***********************************************************************/ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/*----------------------------------------------------------------------- + * High Level Configuration Options + *----------------------------------------------------------------------*/ +#define CONFIG_KATMAI 1 /* Board is Katmai */ +#define CONFIG_4xx 1 /* ... PPC4xx family */ +#define CONFIG_440 1 /* ... PPC440 family */ +#define CONFIG_440SPE 1 /* Specifc SPe support */ +#undef CFG_DRAM_TEST /* Disable-takes long time */ +#define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */ + +#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ +#define CONFIG_MISC_INIT_F 1 /* Use misc_init_f() */ +#define CONFIG_ADD_RAM_INFO 1 /* Print additional info */ +#undef CONFIG_SHOW_BOOT_PROGRESS + +/*----------------------------------------------------------------------- + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + *----------------------------------------------------------------------*/ +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (512 * 1024) /* Reserve 512 kB for malloc */ + +#define CFG_SDRAM_BASE 0x00000000 /* _must_ be 0 */ +#define CFG_FLASH_BASE 0xff000000 /* start of FLASH */ +#define CFG_MONITOR_BASE TEXT_BASE +#define CFG_PERIPHERAL_BASE 0xa0000000 /* internal peripherals */ +#define CFG_ISRAM_BASE 0x90000000 /* internal SRAM */ + +#define CFG_PCI_MEMBASE 0x80000000 /* mapped PCI memory */ +#define CFG_PCI_BASE 0xd0000000 /* internal PCI regs */ +#define CFG_PCI_TARGBASE CFG_PCI_MEMBASE + +#define CFG_PCIE_MEMBASE 0xb0000000 /* mapped PCIe memory */ +#define CFG_PCIE_MEMSIZE 0x01000000 +#define CFG_PCIE_BASE 0xe0000000 /* PCIe UTL regs */ + +#define CFG_PCIE0_CFGBASE 0xc0000000 +#define CFG_PCIE0_XCFGBASE 0xc0000400 +#define CFG_PCIE1_CFGBASE 0xc0001000 +#define CFG_PCIE1_XCFGBASE 0xc0001400 +#define CFG_PCIE2_CFGBASE 0xc0002000 +#define CFG_PCIE2_XCFGBASE 0xc0002400 + +/* System RAM mapped to PCI space */ +#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE +#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE +#define CONFIG_PCI_SYS_MEM_SIZE (1024 * 1024 * 1024) + +#define CFG_ACE_BASE 0xe0000000 /* Xilinx ACE controller - Compact Flash */ + +/*----------------------------------------------------------------------- + * Initial RAM & stack pointer (placed in internal SRAM) + *----------------------------------------------------------------------*/ +#define CFG_TEMP_STACK_OCM 1 +#define CFG_OCM_DATA_ADDR CFG_ISRAM_BASE +#define CFG_INIT_RAM_ADDR CFG_ISRAM_BASE /* Initial RAM address */ +#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */ +#define CFG_GBL_DATA_SIZE 128 /* num bytes initial data */ + +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_POST_WORD_ADDR (CFG_GBL_DATA_OFFSET - 0x4) +#define CFG_INIT_SP_OFFSET CFG_POST_WORD_ADDR + +/*----------------------------------------------------------------------- + * Serial Port + *----------------------------------------------------------------------*/ +#define CONFIG_SERIAL_MULTI 1 +#undef CONFIG_UART1_CONSOLE +#undef CFG_EXT_SERIAL_CLOCK +#define CONFIG_BAUDRATE 115200 +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} + +/*----------------------------------------------------------------------- + * DDR SDRAM + *----------------------------------------------------------------------*/ +#define CONFIG_SPD_EEPROM 1 /* Use SPD EEPROM for setup */ +#define SPD_EEPROM_ADDRESS {0x51, 0x52} /* SPD i2c spd addresses */ +#define IIC0_DIMM0_ADDR 0x51 +#define IIC0_DIMM1_ADDR 0x52 +#undef CONFIG_STRESS +#undef ENABLE_ECC + +/*----------------------------------------------------------------------- + * I2C + *----------------------------------------------------------------------*/ +#define CONFIG_HARD_I2C 1 /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CFG_I2C_SPEED 100000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE +#define CFG_SPD_BUS_NUM 0 /* The I2C bus for SPD */ + +#define IIC0_BOOTPROM_ADDR 0x50 +#define IIC0_ALT_BOOTPROM_ADDR 0x54 + +#define CFG_I2C_MULTI_EEPROMS +#define CFG_I2C_EEPROM_ADDR (0x50) +#define CFG_I2C_EEPROM_ADDR_LEN 1 +#define CFG_EEPROM_PAGE_WRITE_ENABLE +#define CFG_EEPROM_PAGE_WRITE_BITS 3 +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 + +/* I2C RTC */ +#define CONFIG_RTC_M41T11 1 +#define CFG_RTC_BUS_NUM 1 /* The I2C bus for RTC */ +#define CFG_I2C_RTC_ADDR 0x68 +#define CFG_M41T11_BASE_YEAR 1900 /* play along with linux */ + +/* I2C DTT */ +#define CONFIG_DTT_ADM1021 1 /* ADM1021 temp sensor support */ +#define CFG_DTT_BUS_NUM 1 /* The I2C bus for DTT */ +/* + * standard dtt sensor configuration - bottom bit will determine local or + * remote sensor of the ADM1021, the rest determines index into + * CFG_DTT_ADM1021 array below. + */ +#define CONFIG_DTT_SENSORS { 0, 1 } + +/* + * ADM1021 temp sensor configuration (see dtt/adm1021.c for details). + * there will be one entry in this array for each two (dummy) sensors in + * CONFIG_DTT_SENSORS. + * + * For Katmai board: + * - only one ADM1021 + * - i2c addr 0x18 + * - conversion rate 0x02 = 0.25 conversions/second + * - ALERT ouput disabled + * - local temp sensor enabled, min set to 0 deg, max set to 85 deg + * - remote temp sensor enabled, min set to 0 deg, max set to 85 deg + */ +#define CFG_DTT_ADM1021 { { 0x18, 0x02, 0, 1, 0, 85, 1, 0, 58} } + +/*----------------------------------------------------------------------- + * Environment + *----------------------------------------------------------------------*/ +#define CFG_ENV_IS_IN_FLASH 1 /* Environment uses flash */ + +#define CONFIG_PREBOOT "echo;" \ + "echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \ + "echo" + +#undef CONFIG_BOOTARGS + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "hostname=katmai\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\ + "flash_nfs=run nfsargs addip addtty;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip addtty;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \ + "bootm\0" \ + "rootpath=/opt/eldk/ppc_4xx\0" \ + "bootfile=katmai/uImage\0" \ + "kernel_addr=fff10000\0" \ + "ramdisk_addr=fff20000\0" \ + "initrd_high=30000000\0" \ + "load=tftp 200000 katmai/u-boot.bin\0" \ + "update=protect off fffc0000 ffffffff;era fffc0000 ffffffff;" \ + "cp.b ${fileaddr} fffc0000 ${filesize};" \ + "setenv filesize;saveenv\0" \ + "upd=run load;run update\0" \ + "kozio=bootm ffc60000\0" \ + "" +#define CONFIG_BOOTCOMMAND "run flash_self" + +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CFG_CMD_ASKENV | \ + CFG_CMD_EEPROM | \ + CFG_CMD_DATE | \ + CFG_CMD_DHCP | \ + CFG_CMD_DIAG | \ + CFG_CMD_DTT | \ + CFG_CMD_ELF | \ + CFG_CMD_EXT2 | \ + CFG_CMD_FAT | \ + CFG_CMD_I2C | \ + CFG_CMD_IRQ | \ + CFG_CMD_MII | \ + CFG_CMD_NET | \ + CFG_CMD_NFS | \ + CFG_CMD_PCI | \ + CFG_CMD_PING | \ + CFG_CMD_REGINFO | \ + CFG_CMD_SDRAM) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +#define CONFIG_IBM_EMAC4_V4 1 /* 440SPe has this EMAC version */ +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_PHY_ADDR 1 /* PHY address, See schematics */ +#define CONFIG_HAS_ETH0 +#define CONFIG_PHY_RESET 1 /* reset phy upon startup */ +#define CONFIG_PHY_RESET_DELAY 1000 +#define CONFIG_CIS8201_PHY 1 /* Enable 'special' RGMII mode for Cicada phy */ +#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ +#define CFG_RX_ETH_BUFFER 32 /* Number of ethernet rx buffers & descriptors */ + +#define CONFIG_NETCONSOLE /* include NetConsole support */ +#define CONFIG_NET_MULTI /* needed for NetConsole */ + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_LOOPW 1 /* enable loopw command */ +#define CONFIG_MX_CYCLIC 1 /* enable mdc/mwc commands */ +#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */ +#define CONFIG_VERSION_VARIABLE 1 /* include version env variable */ + +#define CFG_4xx_RESET_TYPE 0x2 /* use chip reset on this board */ + +/*----------------------------------------------------------------------- + * FLASH related + *----------------------------------------------------------------------*/ +#define CFG_FLASH_CFI +#define CFG_FLASH_CFI_DRIVER +#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ + +#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} +#define CFG_MAX_FLASH_BANKS 1 /* number of banks */ +#define CFG_MAX_FLASH_SECT 1024 /* sectors per device */ + +#undef CFG_FLASH_CHECKSUM +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#define CFG_ENV_SECT_SIZE 0x20000 /* size of one complete sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE-CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ + +/* Address and size of Redundant Environment Sector */ +#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR-CFG_ENV_SECT_SIZE) +#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) + +/*----------------------------------------------------------------------- + * PCI stuff + *----------------------------------------------------------------------- + */ +/* General PCI */ +#define CONFIG_PCI /* include pci support */ +#define CONFIG_PCI_PNP 1 /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW 1 /* show pci devices on startup */ +#undef CONFIG_PCI_CONFIG_HOST_BRIDGE + +/* Board-specific PCI */ +#define CFG_PCI_PRE_INIT 1 /* enable board pci_pre_init() */ +#define CFG_PCI_TARGET_INIT /* let board init pci target */ +#undef CFG_PCI_MASTER_INIT + +#define CFG_PCI_SUBSYS_VENDORID 0x1014 /* IBM */ +#define CFG_PCI_SUBSYS_DEVICEID 0xcafe /* Whatever */ +/* #define CFG_PCI_SUBSYS_ID CFG_PCI_SUBSYS_DEVICEID */ + +/* + * NETWORK Support (PCI): + */ +/* Support for Intel 82557/82559/82559ER chips. */ +#define CONFIG_EEPRO100 + +/*----------------------------------------------------------------------- + * Xilinx System ACE support + *----------------------------------------------------------------------*/ +#define CONFIG_SYSTEMACE 1 /* Enable SystemACE support */ +#define CFG_SYSTEMACE_WIDTH 16 /* Data bus width is 16 */ +#define CFG_SYSTEMACE_BASE CFG_ACE_BASE +#define CONFIG_DOS_PARTITION 1 + +/*----------------------------------------------------------------------- + * External Bus Controller (EBC) Setup + *----------------------------------------------------------------------*/ + +/* Memory Bank 0 (Flash) initialization */ +#define CFG_EBC_PB0AP (EBC_BXAP_BME_DISABLED | \ + EBC_BXAP_TWT_ENCODE(7) | \ + EBC_BXAP_BCE_DISABLE | \ + EBC_BXAP_BCT_2TRANS | \ + EBC_BXAP_CSN_ENCODE(0) | \ + EBC_BXAP_OEN_ENCODE(0) | \ + EBC_BXAP_WBN_ENCODE(0) | \ + EBC_BXAP_WBF_ENCODE(0) | \ + EBC_BXAP_TH_ENCODE(0) | \ + EBC_BXAP_RE_DISABLED | \ + EBC_BXAP_SOR_DELAYED | \ + EBC_BXAP_BEM_WRITEONLY | \ + EBC_BXAP_PEN_DISABLED) +#define CFG_EBC_PB0CR (EBC_BXCR_BAS_ENCODE(CFG_FLASH_BASE) | \ + EBC_BXCR_BS_16MB | \ + EBC_BXCR_BU_RW | \ + EBC_BXCR_BW_16BIT) + +/* Memory Bank 1 (Xilinx System ACE controller) initialization */ +#define CFG_EBC_PB1AP 0x7F8FFE80 +#define CFG_EBC_PB1CR (EBC_BXCR_BAS_ENCODE(CFG_ACE_BASE) | \ + EBC_BXCR_BS_1MB | \ + EBC_BXCR_BU_RW | \ + EBC_BXCR_BW_16BIT) + +/*------------------------------------------------------------------------- + * Initialize EBC CONFIG - + * Keep the Default value, but the bit PDT which has to be set to 1 ?TBC + * default value : 0x07C00000 - 0 0 000 1 1 1 1 1 0000 0 00000 000000000000 + *-------------------------------------------------------------------------*/ +#define CFG_EBC_CFG (EBC_CFG_LE_UNLOCK | \ + EBC_CFG_PTD_ENABLE | \ + EBC_CFG_RTC_16PERCLK | \ + EBC_CFG_ATC_PREVIOUS | \ + EBC_CFG_DTC_PREVIOUS | \ + EBC_CFG_CTC_PREVIOUS | \ + EBC_CFG_OEO_PREVIOUS | \ + EBC_CFG_EMC_DEFAULT | \ + EBC_CFG_PME_DISABLE | \ + EBC_CFG_PR_16) + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /*Initial Memory map for Linux*/ +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_DCACHE_SIZE 8192 /* For AMCC 405 CPUs */ +#define CFG_CACHELINE_SIZE 32 /* ... */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +#endif /* __CONFIG_H */ diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index f60973b26d..621a81c9c5 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -265,6 +265,7 @@ */ #if !defined(CONFIG_PRS200) #define CONFIG_LCD 1 +#define CONFIG_PROGRESSBAR 1 #endif #if defined(CONFIG_LCD) diff --git a/include/configs/mecp5200.h b/include/configs/mecp5200.h index ccb0293329..0c1029426c 100644 --- a/include/configs/mecp5200.h +++ b/include/configs/mecp5200.h @@ -88,10 +88,10 @@ /* USB */ #if 0 #define CONFIG_USB_OHCI -#define ADD_USB_CMD CFG_CMD_USB | CFG_CMD_FAT +#define ADD_USB_CMD CFG_CMD_USB | CFG_CMD_FAT #define CONFIG_USB_STORAGE #else -#define ADD_USB_CMD 0 +#define ADD_USB_CMD 0 #endif /* @@ -100,7 +100,7 @@ #define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ CFG_CMD_EEPROM | \ CFG_CMD_FAT | \ - CFG_CMD_EXT2 | \ + CFG_CMD_EXT2 | \ CFG_CMD_I2C | \ CFG_CMD_IDE | \ CFG_CMD_BSP | \ @@ -110,11 +110,11 @@ #include #if (TEXT_BASE == 0xFF000000) /* Boot low with 16 MB Flash */ -# define CFG_LOWBOOT 1 +# define CFG_LOWBOOT 1 # define CFG_LOWBOOT16 1 #endif #if (TEXT_BASE == 0xFF800000) /* Boot low with 8 MB Flash */ -# define CFG_LOWBOOT 1 +# define CFG_LOWBOOT 1 # define CFG_LOWBOOT08 1 #endif @@ -131,20 +131,20 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ - "flash_vxworks0=run ata_vxworks_args;setenv loadaddr ff000000;bootvx\0" \ - "flash_vxworks1=run ata_vxworks_args;setenv loadaddr ff200000:bootvx\0" \ - "net_vxworks=tftp $(loadaddr) $(image);run vxworks_args;bootvx\0" \ - "vxworks_args=setenv bootargs fec(0,0)$(host):$(image) h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script)\0" \ - "ata_vxworks_args=setenv bootargs /ata0/vxWorks h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script) o=fec0 \0" \ - "loadaddr=01000000\0" \ - "serverip=192.168.2.99\0" \ - "gatewayip=10.0.0.79\0" \ - "user=mu\0" \ - "target=mecp5200.esd\0" \ - "script=mecp5200.bat\0" \ - "image=/tftpboot/vxWorks_mecp5200\0" \ - "ipaddr=10.0.13.196\0" \ - "netmask=255.255.0.0\0" \ + "flash_vxworks0=run ata_vxworks_args;setenv loadaddr ff000000;bootvx\0" \ + "flash_vxworks1=run ata_vxworks_args;setenv loadaddr ff200000:bootvx\0" \ + "net_vxworks=tftp $(loadaddr) $(image);run vxworks_args;bootvx\0" \ + "vxworks_args=setenv bootargs fec(0,0)$(host):$(image) h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script)\0" \ + "ata_vxworks_args=setenv bootargs /ata0/vxWorks h=$(serverip) e=$(ipaddr) g=$(gatewayip) u=$(user) $(pass) tn=$(target) s=$(script) o=fec0 \0" \ + "loadaddr=01000000\0" \ + "serverip=192.168.2.99\0" \ + "gatewayip=10.0.0.79\0" \ + "user=mu\0" \ + "target=mecp5200.esd\0" \ + "script=mecp5200.bat\0" \ + "image=/tftpboot/vxWorks_mecp5200\0" \ + "ipaddr=10.0.13.196\0" \ + "netmask=255.255.0.0\0" \ "" #define CONFIG_BOOTCOMMAND "run flash_vxworks0" @@ -171,12 +171,12 @@ #define CFG_I2C_EEPROM_ADDR_LEN 2 #define CFG_EEPROM_PAGE_WRITE_BITS 5 #define CFG_EEPROM_PAGE_WRITE_DELAY_MS 20 -#define CFG_I2C_MULTI_EEPROMS 1 +#define CFG_I2C_MULTI_EEPROMS 1 /* * Flash configuration */ #define CFG_FLASH_BASE 0xFFC00000 -#define CFG_FLASH_SIZE 0x00400000 +#define CFG_FLASH_SIZE 0x00400000 #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x003E0000) #define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ #define CFG_MAX_FLASH_SECT 512 @@ -200,15 +200,15 @@ #define CONFIG_ENV_OVERWRITE 1 #endif -#define CFG_FLASH_CFI_DRIVER 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_PROTECTION 1 /* use hardware protection */ +#define CFG_FLASH_CFI_DRIVER 1 /* Flash is CFI conformant */ +#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ +#define CFG_FLASH_PROTECTION 1 /* use hardware protection */ #if 0 #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #endif -#define CFG_FLASH_INCREMENT 0x00400000 /* size of flash bank */ +#define CFG_FLASH_INCREMENT 0x00400000 /* size of flash bank */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } -#define CFG_FLASH_EMPTY_INFO 1 /* show if bank is empty */ +#define CFG_FLASH_EMPTY_INFO 1 /* show if bank is empty */ /* @@ -272,7 +272,7 @@ #define CFG_LOAD_ADDR 0x100000 /* default load address */ -#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ #define CFG_VXWORKS_MAC_PTR 0x00000000 /* Pass Ethernet MAC to VxWorks */ @@ -339,7 +339,7 @@ /* Offset for alternate registers */ #define CFG_ATA_ALT_OFFSET (0x005C) -/* Interval between registers */ -#define CFG_ATA_STRIDE 4 +/* Interval between registers */ +#define CFG_ATA_STRIDE 4 #endif /* __CONFIG_H */ diff --git a/include/configs/sequoia.h b/include/configs/sequoia.h index 098aa3f0a6..29f3b408d2 100644 --- a/include/configs/sequoia.h +++ b/include/configs/sequoia.h @@ -391,7 +391,7 @@ #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CFG_NAND_CS 3 /* NAND chip connected to CSx */ /* Memory Bank 0 (NOR-FLASH) initialization */ -#define CFG_EBC_PB0AP 0x03017300 +#define CFG_EBC_PB0AP 0x03017200 #define CFG_EBC_PB0CR (CFG_FLASH | 0xda000) /* Memory Bank 3 (NAND-FLASH) initialization */ @@ -400,7 +400,7 @@ #else #define CFG_NAND_CS 0 /* NAND chip connected to CSx */ /* Memory Bank 3 (NOR-FLASH) initialization */ -#define CFG_EBC_PB3AP 0x03017300 +#define CFG_EBC_PB3AP 0x03017200 #define CFG_EBC_PB3CR (CFG_FLASH | 0xda000) /* Memory Bank 0 (NAND-FLASH) initialization */ diff --git a/include/i2c.h b/include/i2c.h index a8f729afe0..54c6f9fbc6 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -46,6 +46,16 @@ */ #define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ +#if defined(CONFIG_I2C_MULTI_BUS) +#define CFG_MAX_I2C_BUS 2 +#define I2C_GET_BUS() i2c_get_bus_num() +#define I2C_SET_BUS(a) i2c_set_bus_num(a) +#else +#define CFG_MAX_I2C_BUS 1 +#define I2C_GET_BUS() 0 +#define I2C_SET_BUS(a) +#endif + /* * Initialization, must be called once on start up, may be called * repeatedly to change the speed and slave addresses. diff --git a/include/ide.h b/include/ide.h index dfef32f267..6976a6c319 100644 --- a/include/ide.h +++ b/include/ide.h @@ -48,8 +48,8 @@ typedef ulong lbaint_t; * Function Prototypes */ -void ide_init (void); -ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); -ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); +void ide_init(void); +ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer); +ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, void *buffer); #endif /* _IDE_H */ diff --git a/include/part.h b/include/part.h index 318aa3cb3f..29c03205f2 100644 --- a/include/part.h +++ b/include/part.h @@ -22,6 +22,7 @@ */ #ifndef _PART_H #define _PART_H + #include typedef struct block_dev_desc { @@ -43,7 +44,11 @@ typedef struct block_dev_desc { unsigned long (*block_read)(int dev, unsigned long start, lbaint_t blkcnt, - unsigned long *buffer); + void *buffer); + unsigned long (*block_write)(int dev, + unsigned long start, + lbaint_t blkcnt, + const void *buffer); }block_dev_desc_t; /* Interface types: */ @@ -83,6 +88,14 @@ typedef struct disk_partition { uchar type[32]; /* string type description */ } disk_partition_t; +/* Misc _get_dev functions */ +block_dev_desc_t* get_dev(char* ifname, int dev); +block_dev_desc_t* ide_get_dev(int dev); +block_dev_desc_t* scsi_get_dev(int dev); +block_dev_desc_t* usb_stor_get_dev(int dev); +block_dev_desc_t* mmc_get_dev(int dev); +block_dev_desc_t* systemace_get_dev(int dev); + /* disk/part.c */ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); void print_part (block_dev_desc_t *dev_desc); diff --git a/include/ppc405.h b/include/ppc405.h index e475fa54cd..a49912cabb 100644 --- a/include/ppc405.h +++ b/include/ppc405.h @@ -240,6 +240,7 @@ #define pbesr0 0x21 /* periph bus error status reg 0 */ #define pbesr1 0x22 /* periph bus error status reg 1 */ #define epcr 0x23 /* external periph control reg */ +#define EBC0_CFG 0x23 /* external bus configuration reg */ #ifdef CONFIG_405EP /****************************************************************************** diff --git a/include/ppc440.h b/include/ppc440.h index 91cff414af..c24f5b7ab1 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -533,9 +533,12 @@ #define SDRAM_MCSTAT_MIC_MASK 0x80000000 /* Memory init status mask */ #define SDRAM_MCSTAT_MIC_NOTCOMP 0x00000000 /* Mem init not complete */ #define SDRAM_MCSTAT_MIC_COMP 0x80000000 /* Mem init complete */ -#define SDRAM_MCSTAT_SRMS_MASK 0x80000000 /* Mem self refresh stat mask */ +#define SDRAM_MCSTAT_SRMS_MASK 0x40000000 /* Mem self refresh stat mask */ #define SDRAM_MCSTAT_SRMS_NOT_SF 0x00000000 /* Mem not in self refresh */ -#define SDRAM_MCSTAT_SRMS_SF 0x80000000 /* Mem in self refresh */ +#define SDRAM_MCSTAT_SRMS_SF 0x40000000 /* Mem in self refresh */ +#define SDRAM_MCSTAT_IDLE_MASK 0x20000000 /* Mem self refresh stat mask */ +#define SDRAM_MCSTAT_IDLE_NOT 0x00000000 /* Mem contr not idle */ +#define SDRAM_MCSTAT_IDLE 0x20000000 /* Mem contr idle */ /*-----------------------------------------------------------------------------+ | Memory Controller Options 1 @@ -730,6 +733,7 @@ #define SDRAM_WRDTR_LLWP_1_CYC 0x00000000 #define SDRAM_WRDTR_WTR_MASK 0x0E000000 #define SDRAM_WRDTR_WTR_0_DEG 0x06000000 +#define SDRAM_WRDTR_WTR_90_DEG_ADV 0x04000000 #define SDRAM_WRDTR_WTR_180_DEG_ADV 0x02000000 #define SDRAM_WRDTR_WTR_270_DEG_ADV 0x00000000 @@ -847,6 +851,7 @@ #define pbear 0x20 /* periph bus error addr reg */ #define pbesr 0x21 /* periph bus error status reg */ #define xbcfg 0x23 /* external bus configuration reg */ +#define EBC0_CFG 0x23 /* external bus configuration reg */ #define xbcid 0x24 /* external bus core id reg */ #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ diff --git a/lib_generic/display_options.c b/lib_generic/display_options.c index 512e8980d9..5ddd94fd5a 100644 --- a/lib_generic/display_options.c +++ b/lib_generic/display_options.c @@ -21,7 +21,10 @@ * MA 02111-1307 USA */ +#include #include +#include +#include int display_options (void) { @@ -65,3 +68,70 @@ void print_size (ulong size, const char *s) } printf (" %cB%s", c, s); } + +/* + * Print data buffer in hex and ascii form to the terminal. + * + * data reads are buffered so that each memory address is only read once. + * Useful when displaying the contents of volatile registers. + * + * parameters: + * addr: Starting address to display at start of line + * data: pointer to data buffer + * width: data value width. May be 1, 2, or 4. + * count: number of values to display + * linelen: Number of values to print per line; specify 0 for default length + */ +#define MAX_LINE_LENGTH_BYTES (64) +#define DEFAULT_LINE_LENGTH_BYTES (16) +int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen) +{ + uint8_t linebuf[MAX_LINE_LENGTH_BYTES]; + uint32_t *uip = (void*)linebuf; + uint16_t *usp = (void*)linebuf; + uint8_t *ucp = (void*)linebuf; + int i; + + if (linelen*width > MAX_LINE_LENGTH_BYTES) + linelen = MAX_LINE_LENGTH_BYTES / width; + if (linelen < 1) + linelen = DEFAULT_LINE_LENGTH_BYTES / width; + + while (count) { + printf("%08lx:", addr); + + /* check for overflow condition */ + if (count < linelen) + linelen = count; + + /* Copy from memory into linebuf and print hex values */ + for (i = 0; i < linelen; i++) { + if (width == 4) { + uip[i] = *(volatile uint32_t *)data; + printf(" %08x", uip[i]); + } else if (width == 2) { + usp[i] = *(volatile uint16_t *)data; + printf(" %04x", usp[i]); + } else { + ucp[i] = *(volatile uint8_t *)data; + printf(" %02x", ucp[i]); + } + data += width; + } + + /* Print data in ASCII characters */ + puts(" "); + for (i = 0; i < linelen * width; i++) + putc(isprint(ucp[i]) && (ucp[i] < 0x80) ? ucp[i] : '.'); + putc ('\n'); + + /* update references */ + addr += linelen * width; + count -= linelen; + + if (ctrlc()) + return -1; + } + + return 0; +}