Merge /home/roy/CVS/7448/Open_Source/u-boot.git.dev

This commit is contained in:
roy zang 2006-12-04 23:57:35 +08:00 committed by Zang Tiefei
commit d3bb5ec198
154 changed files with 26499 additions and 4360 deletions

777
CHANGELOG
View file

@ -1,3 +1,737 @@
commit 8d9a8610b8256331132227e9e6585c6bd5742787
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Thu Nov 30 01:54:07 2006 +0100
Code cleanup. Update CHANGELOG.
commit 726e90aacf0b1ecb0e7055be574622fbe3e450ba
Author: Grant Likely <grant.likely@secretlab.ca>
Date: Wed Nov 29 16:23:42 2006 +0100
[PATCH] [MPC52xx] Use IPB bus frequency for SOC peripherals
The soc node of the mpc52xx needs to be loaded with the IPB bus frequency,
not the XLB frequency.
This patch depends on the previous patches for MPC52xx device tree support
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
commit 1eac2a71417b6675b11aace72102a2e7fde8f5c6
Author: Stefan Roese <sr@denx.de>
Date: Wed Nov 29 15:42:37 2006 +0100
[PATCH] Add support for Prodrive P3M750 & P3M7448 (P3Mx) boards
This patch adds support for the Prodrive P3M750 (PPC750 & MV64460)
and the P3M7448 (MPC7448 & MV64460) PMC modules. Both modules are
quite similar and share the same board directory "prodrive/p3mx"
and the same config file "p3mx.h".
Signed-off-by: Stefan Roese <sr@denx.de>
commit 1bdd46832aeb569f5e04b1f20f64318525b6525a
Author: Stefan Roese <sr@denx.de>
Date: Wed Nov 29 12:53:15 2006 +0100
[PATCH] common/cmd_elf.c: Enable loadaddr as parameter in bootvx command
In the bootvx command the load address was only read from the env
variable "loadaddr" and not optionally passed as paramter as described
in the help. This is fixed with this patch. The behaviour is now the
same as in the bootelf command.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 4e26f1074c3ac1bd8fd094f0dc4a1c4a0b15a592
Author: Stefan Roese <sr@denx.de>
Date: Wed Nov 29 12:03:57 2006 +0100
[PATCH] include/ppc440.h minor error affecting interrupts
Fixed include/ppc440.c for UIC address Bug
Corrects bug affecting the addresses for the universal interrupt
controller UIC2 and UIC3 on the PPC440 Epx, GRx, and SPE chips.
Signed-off-by: Jeff Mann <mannj@embeddedplanet.com>
Signed-off-by: Stefan Roese <sr@denx.de>
commit 1939d969443ccf316cab2bf32ab1027d4db5ba1a
Author: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Tue Nov 28 16:17:27 2006 -0600
Make fsl-i2c not conflict with SOFT I2C
Signed-off-by: Timur Tabi <timur@freescale.com>
commit 14198bf768fdc958e3c1afd2404e5262208e98d7
Author: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Tue Nov 28 16:17:18 2006 -0600
Fix I2C master address initialization.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit cf3d045e51ca8dcc6cf759827140861d6ac25c04
Author: Kim Phillips <kim.phillips@freescale.com>
Date: Tue Nov 28 23:31:19 2006 -0600
Assign maintainers for mpc8349emds and mpc8360emds
Dave for mpc8360emds, and me for mpc8349emds.
commit 1aa934c81b77f2080d3ca4b226eab67b17a33961
Author: Kim Phillips <kim.phillips@freescale.com>
Date: Tue Nov 28 23:28:33 2006 -0600
Eliminate gcc 4 'used uninitialized' warnings in drivers/qe/uccf.c
give initial values for reg_num, shift, p_cmxucr in ucc_set_clk_src
since they are passed by reference to ucc_get_cmxucr_reg and assigned.
commit e857a5bdb3954b896c0920cb9d8d2b1b9c107ce5
Author: Timur Tabi <timur@freescale.com>
Date: Tue Nov 28 12:09:35 2006 -0600
mpc83xx: Miscellaneous code style fixes
Implement various code style fixes and similar changes.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit e59581c56ab5d6e0207ddac3b2c1d55cb36ec706
Author: Stefan Roese <sr@denx.de>
Date: Tue Nov 28 17:55:49 2006 +0100
[PATCH] Enable the IceCube/lite5200 variants to pass a device tree to Linux.
This patch adds the code and configuration necessary to boot with an
arch/powerpc Linux kernel.
Signed-off-by: Grant Likely <grant.likely@gmail.com>
Acked-by: Jon Loeliger <jdl@freescale.com>
commit e732faec95a83cb468b4850ae807c8301dde8f6a
Author: Stefan Roese <sr@denx.de>
Date: Tue Nov 28 16:09:24 2006 +0100
[PATCH] PPC4xx: 440SP Rev. C detection added
Signed-off-by: Stefan Roese <sr@denx.de>
commit e7f3e9ff01fbd7fa72eb42a9675fbed6bc4736b0
Author: Stefan Roese <sr@denx.de>
Date: Tue Nov 28 11:04:45 2006 +0100
[PATCH] nand: Fix patch merge problem
Signed-off-by: Stefan Roese <sr@denx.de>
commit 4f4b602ec7524a032bdf3c6d28c7f525a4a67eaa
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Mon Nov 27 22:53:53 2006 +0100
Update CHANGELOG
commit f6e495f54cdb8fe340b9c03deab40ad746d52fae
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 17:43:25 2006 +0100
[PATCH] 4xx_enet.c: Correct the setting of zmiifer register
Patch below corrects the setting of the zmiifer register, it was
overwritting the register rather than ORing the settings.
Signed-off-by: Neil Wilson <NWilson@airspan.com>
Signed-off-by: Stefan Roese <sr@denx.de>
commit d1a72545296800b7e219f93104ad5836f0003d66
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 17:34:10 2006 +0100
[PATCH] Select NAND embedded environment from board configuration
The current NAND Bootloader setup forces the environment
variables to be in line with the bootloader. This change
enables the configuration to be made in the board include
file instead so that it can be individually enabled.
Signed-off-by: Nick Spence <nick.spence@freescale.com>
Signed-off-by: Stefan Roese <sr@denx.de>
commit 15784862857c3c2214498defcfed84ff137fb81e
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 17:22:19 2006 +0100
[PATCH] nand_wait() timeout fixes
Two fixes for the nand_wait() function in
drivers/nand/nand_base.c:
1. Use correct timeouts. The original timeouts in Linux
source are 400ms and 20ms not 40s and 20s
2. Return correct error value in case of timeout. 0 is
interpreted as OK.
Signed-off-by: Rui Sousa <rui.sousa@laposte.net>
Signed-off-by: Stefan Roese <sr@denx.de>
commit da5553b095bf04f4f109ad7e565dae3aba47b230
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 17:04:06 2006 +0100
[PATCH] Allow CONFIG_OF_FLAT_TREE to boot a non-arch/powerpc kernel
This patch allows an arch/ppc kernel to be booted by just passing 1 or 2
arguments to bootm. It removes the getenv("disable_of") test that used
to be used for this purpose.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Jon Loeliger <jdl@freescale.com>
commit a9398e018593782c5fa7d0741955fc1256b34c1e
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Mon Nov 27 15:32:42 2006 +0100
Minor code cleanup. Update CHANGELOG.
commit 1729b92cde575476684bffe819d0b7791b57bff2
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 14:52:04 2006 +0100
[PATCH] 4xx: Fix problem with board specific reset code (now for real)
Signed-off-by: Stefan Roese <sr@denx.de>
commit cc5ee8a92a0e3ca6f727af71b8fd206460c7afd7
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 14:49:51 2006 +0100
[PATCH] alpr: remove unused board specific flash driver
Signed-off-by: Stefan Roese <sr@denx.de>
commit 1f94d162e2b5f0edc28d9fb11482502c44d218e1
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 14:48:41 2006 +0100
[PATCH] 4xx: Fix problem with board specific reset code
Signed-off-by: Stefan Roese <sr@denx.de>
commit ec0c2ec725aec9524a177a77ce75559e644a931a
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 14:46:06 2006 +0100
[PATCH] Remove testing 4xx enet PHY setup
Signed-off-by: Stefan Roese <sr@denx.de>
commit 1c2ce2262069510f31c7d3fd7efd3d58b8c0c148
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 27 14:12:17 2006 +0100
[PATCH] Update Prodrive ALPR board support (440GX)
Signed-off-by: Stefan Roese <sr@denx.de>
commit 78d620ebb5871d252270dedfad60c6568993b780
Author: Wolfgang Denk <wd@atlas.denx.de>
Date: Thu Nov 23 22:58:58 2006 +0100
Updates for TQM5200 modules:
- fix off-by-one error in board/tqm5200/cam5200_flash.c error message
- simplify "udate" definitions
commit 2053283304eeddf250d109e6791eb6fa4cad14f7
Author: Stefan Roese <sr@denx.de>
Date: Wed Nov 22 13:20:50 2006 +0100
[PATCH] PPC4xx start.S: Fix for processor errata
Fixed cpu/ppc4xx/start.S for 440EPx Errata: further corrects PPC440EPx
errata 1.12: 440_33 by moving patch up in code.
Signed-off-by: Jeff Mann <mannj@embeddedplanet.com>
Signed-off-by: Stefan Roese <sr@denx.de>
commit 4ef6251403f637841000e0fef9e832aa01339822
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 20 20:39:52 2006 +0100
[PATCH] Update AMCC Sequoia config file to support 64MByte NOR FLASH
Signed-off-by: Stefan Roese <sr@denx.de>
commit e4bbd8da164b976d38616bd9c69c5e86e193cdf0
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Mon Nov 20 10:28:30 2006 +0100
Update CHANGELOG
commit 260421a21e934a68d31fb6125b0fbd2631a8ca20
Author: Stefan Roese <sr@denx.de>
Date: Mon Nov 13 13:55:24 2006 +0100
[PATCH] CFI driver AMD Command Set Top boot geometry reversal, etc. [Updated]
* Adds support for AMD command set Top Boot flash geometry reversal
* Adds support for reading JEDEC Manufacturer ID and Device ID
* Adds support for displaying command set, manufacturer id and
device ids (flinfo)
* Makes flinfo output to be consistent when CFG_FLASH_EMPTY_INFO defined
* Removes outdated change history (refer to git log instead)
Signed-off-by: Tolunay Orkun <listmember@orkun.us>
Signed-off-by: Stefan Roese <sr@denx.de>
commit b21b511d4c50408f4853f46f06b601272196223f
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Sun Nov 12 21:13:23 2006 +0100
Update CHANGELOG
commit ce3f1a40c507afbab06c5eb58ccdc6713eda3245
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Sat Nov 11 22:48:22 2006 +0100
Disable the watchdog in the default config for the V38B board.
commit 44a47e6db2694841211f1c8fdbafd36992e9cd1a
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Sat Nov 11 22:43:00 2006 +0100
Change the GPIO pin multiplexing configuration for V38B. The USB GPIO pin
group is enabled for USB earlier (in cpu_init_f() instead of
usb_lowlevel_init()).
commit 91650b3e4de688038d4f71279c44858e3e2c6870
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Mon Nov 6 17:06:36 2006 +0100
Sequential accesses to non-existent memory must be synchronized,
at least on G2 cores.
This fixes get_ram_size() problems on MPC5200 Rev. B boards.
commit be5e61815d5a1fac290ce9c0ef09cb6a8e4288fa
Author: Timur Tabi <timur@freescale.com>
Date: Fri Nov 3 19:15:00 2006 -0600
mpc83xx: Update 83xx to use fsl_i2c.c
Update the 83xx tree to use I2C support in drivers/fsl_i2c.c. Delete
cpu/mpc83xx/i2c.c, include/asm-ppc/i2c.h, and all references to those files.
Added multiple I2C bus support to fsl_i2c.c.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit d239d74b1c937984bc519083a8e7de373a390f06
Author: Timur Tabi <timur@freescale.com>
Date: Fri Nov 3 12:00:28 2006 -0600
mpc83xx: Replace CFG_IMMRBAR with CFG_IMMR
Replace all instances of CFG_IMMRBAR with CFG_IMMR, so that the 83xx
tree matches the other 8xxx trees.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit f7fb2e703ec9688541416962724adff70a7322cb
Author: Kim Phillips <kim.phillips@freescale.com>
Date: Thu Nov 2 19:47:11 2006 -0600
mpc83xx: Lindent and clean up cpu/mpc83xx/speed.c
commit 90f30a710a3c619b5405860a686c4ddfc495d4b6
Author: Dave Liu <daveliu@freescale.com>
Date: Thu Nov 2 18:05:50 2006 -0600
mpc83xx: Fix the incorrect dcbz operation
The 834x rev1.x silicon has one CPU5 errata.
The issue is when the data cache locked with
HID0[DLOCK], the dcbz instruction looks like no-op inst.
The right behavior of the data cache is when the data cache
Locked with HID0[DLOCK], the dcbz instruction allocates
new tags in cache.
The 834x rev3.0 and later and 8360 have not this bug inside.
So, when 834x rev3.0/8360 are working with ECC, the dcbz
instruction will corrupt the stack in cache, the processor will
checkstop reset.
However, the 834x rev1.x can work with ECC with these code,
because the sillicon has this cache bug. The dcbz will not
corrupt the stack in cache.
Really, it is the fault code running on fault sillicon.
This patch fix the incorrect dcbz operation. Instead of
CPU FP writing to initialise the ECC.
CHANGELOG:
* Fix the incorrect dcbz operation instead of CPU FP
writing to initialise the ECC memory. Otherwise, it
will corrupt the stack in cache, The processor will checkstop
reset.
Signed-off-by: Dave Liu <daveliu@freescale.com>
commit bf0b542d6773a5a1cbce77691f009b06d9aeb57d
Author: Kim Phillips <kim.phillips@freescale.com>
Date: Wed Nov 1 00:10:40 2006 -0600
mpc83xx: add OF_FLAT_TREE bits to 83xx boards
add ft_pci_setup, OF_CPU, OF_SOC, OF_TBCLK, and
STDOUT_PATH configuration bits to mpc8349emds,
mpc8349itx, and mpc8360emds board code.
redo environment to use bootm with the fdtaddr
for booting ARCH=powerpc kernels by default,
and provide default fdtaddr values.
commit 48041365b3420589ad464ebc7752e0053538b729
Author: Kim Phillips <kim.phillips@freescale.com>
Date: Wed Nov 1 00:07:25 2006 -0600
mpc83xx: change ft code to modify local-mac-address property
Update 83xx OF code to update local-mac-address properties
for ethernet instead of the obsolete 'address' property.
commit 9ca880a250870a7d55754291b5591d2b5fe89b54
Author: Timur Tabi <timur@freescale.com>
Date: Tue Oct 31 21:23:16 2006 -0600
mpc83xx: Fix dual I2C support for the MPC8349ITX, MPC8349EMDS, TQM834x, and MPC8360EMDS
This patch also adds an improved I2C set_speed(), which handles all clock
frequencies.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit ac4b5622ce050b5ee1e154b98df630d778661632
Author: Dave Liu <daveliu@freescale.com>
Date: Tue Oct 31 19:54:59 2006 -0600
mpc83xx: add the README.mpc8360emds
add doc/README.mpc8360emds to accompany the new board support
commit 7737d5c658c606f999dfbe3e86b0fed49e5c50ef
Author: Dave Liu <daveliu@freescale.com>
Date: Fri Nov 3 12:11:15 2006 -0600
mpc83xx: add QE ethernet support
this patch adds support for the QUICC Engine based UCC gigabit ethernet device.
commit 5f8204394e39bbe8cd9f08b8f8d145b6c01f7c73
Author: Dave Liu <daveliu@freescale.com>
Date: Fri Nov 3 19:33:44 2006 -0600
mpc83xx: Add MPC8360EMDS basic board support
Add support for the Freescale MPC8360EMDS board.
Includes DDR, DUART, Local Bus, PCI.
commit 23892e49352de74f7fac36ff90bb1be143d195e3
Author: Dave Liu <daveliu@freescale.com>
Date: Tue Oct 31 19:30:40 2006 -0600
mpc83xx: add the QUICC Engine (QE) immap file
common QE immap file. Also required for 8360.
commit b701652a4992bdcc62fb1a6038a85beef9e55da4
Author: Dave Liu <daveliu@freescale.com>
Date: Tue Oct 31 19:25:38 2006 -0600
mpc83xx: Add 8360 specifics to 83xx immap
Mainly add QE device dependencies, with appropriate 8360 protection.
Lindent also run.
commit 988833324a7fda482c8ac3ca23eb539f8232e404
Author: Timur Tabi <timur@freescale.com>
Date: Tue Oct 31 19:14:41 2006 -0600
mpc83xx: Fix PCI, USB, bootargs for MPC8349E-mITX
PREREQUISITE PATCHES:
* This patch can only be applied after the following patches have been applied:
1) DNX#2006092142000015 "Add support for the MPC8349E-mITX 1/2"
2) DNX#2006092142000024 "Add support for the MPC8349E-mITX 2/2"
CHANGELOG:
* For the 8349E-mITX, fix some size values in pci_init_board(), enable
the clock for the 2nd USB board (Linux kernel will hang otherwise),
and fix the CONFIG_BOOTARGS macro.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit 2ad6b513b31070bd0c003792ed1c3e7f5d740357
Author: Timur Tabi <timur@freescale.com>
Date: Tue Oct 31 18:44:42 2006 -0600
mpc83xx: Add support for the MPC8349E-mITX
PREREQUISITE PATCHES:
* This patch can only be applied after the following patches have been applied:
1) DNX#2006090742000024 "Add support for multiple I2C buses"
2) DNX#2006090742000033 "Multi-bus I2C implementation of MPC834x"
3) DNX#2006091242000041 "Additional MPC8349 support for multibus i2c"
4) DNX#2006091242000078 "Add support for variable flash memory sizes on 83xx systems"
5) DNX#2006091242000069 "Add support for Errata DDR6 on MPC 834x systems"
CHANGELOG:
* Add support for the Freescale MPC8349E-mITX reference design platform.
The second TSEC (Vitesse 7385 switch) is not supported at this time.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit 183da6d9b446cc12123455844ad1187e2375626f
Author: Ben Warren <bwarren@qstreams.com>
Date: Tue Sep 12 10:15:53 2006 -0400
Additional MPC8349 support for multibus i2c
Hello,
Here is a patch for a file that was accidentally left out of a previous
attempt.
It accompanies the patch with ticket DNX#2006090742000024
CHANGELOG:
Change PCI initialization to use new multi-bus I2C API.
regards,
Ben
commit b24f119d672b709d153ff2ac091d4aa63ec6877d
Author: Ben Warren <bwarren@qstreams.com>
Date: Thu Sep 7 16:51:04 2006 -0400
Multi-bus I2C implementation of MPC834x
Hello,
Attached is a patch implementing multiple I2C buses on the MPC834x CPU
family and the MPC8349EMDS board in particular.
This patch requires Patch 1 (Add support for multiple I2C buses).
Testing was performed on a 533MHz board.
/*** Note: This patch replaces ticket DNX#2006083042000027 ***/
Signed-off-by: Ben Warren <bwarren@qstreams.com>
CHANGELOG:
Implemented driver-level code to support two I2C buses on the
MPC834x CPU family and the MPC8349EMDS board. Available I2C bus speeds
are 50kHz, 100kHz and 400kHz on each bus.
regards,
Ben
commit bb99ad6d8257bf828f150d40f507b30d80a4a7ae
Author: Ben Warren <bwarren@qstreams.com>
Date: Thu Sep 7 16:50:54 2006 -0400
Add support for multiple I2C buses
Hello,
Attached is a patch providing support for multiple I2C buses at the
command level. The second part of the patch includes an implementation
for the MPC834x CPU and MPC8349EMDS board.
/*** Note: This patch replaces ticket DNX#2006083042000018 ***/
Signed-off-by: Ben Warren <bwarren@qstreams.com>
Overview:
1. Include new 'i2c' command (based on USB implementation) using
CONFIG_I2C_CMD_TREE.
2. Allow multiple buses by defining CONFIG_I2C_MULTI_BUS. Note that
the commands to change bus number and speed are only available under the
new 'i2c' command mentioned in the first bullet.
3. The option CFG_I2C_NOPROBES has been expanded to work in multi-bus
systems. When CONFIG_I2C_MULTI_BUS is used, this option takes the form
of an array of bus-device pairs. Otherwise, it is an array of uchar.
CHANGELOG:
Added new 'i2c' master command for all I2C interaction. This is
conditionally compiled with CONFIG_I2C_CMD_TREE. New commands added for
setting I2C bus speed as well as changing the active bus if the board
has more than one (conditionally compiled with
CONFIG_I2C_MULTI_BUS). Updated NOPROBE logic to handle multiple buses.
Updated README.
regards,
Ben
commit bed85caf872714ebf53013967a695c9d63acfc68
Author: Timur Tabi <timur@freescale.com>
Date: Tue Oct 31 18:13:36 2006 -0600
mpc83xx: Add support for Errata DDR6 on MPC 834x systems
CHANGELOG:
* Errata DDR6, which affects all current MPC 834x processors, lists changes
required to maintain compatibility with various types of DDR memory. This
patch implements those changes.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit afd6e470f639883002c7c59d562690a5cb0f4865
Author: Timur Tabi <timur@freescale.com>
Date: Wed Oct 25 18:45:23 2006 -0500
mpc83xx: fix TQM build by defining a CFG_FLASH_SIZE for it
commit 31068b7c4abeefcb2c8fd4fbeccc8ec6c6d0475a
Author: Timur Tabi <timur@freescale.com>
Date: Tue Aug 22 17:07:00 2006 -0500
mpc83xx: Add support for variable flash memory sizes on 83xx systems
CHANGELOG:
* On 83xx systems, use the CFG_FLASH_SIZE macro to program the LBC local access
window registers, instead of using a hard-coded value of 8MB.
Signed-off-by: Timur Tabi <timur@freescale.com>
commit 2fc34ae66e73fa7841d1a006dc1b5dcbc1f78965
Author: Tanya Jiang <tanya.jiang@freescale.com>
Date: Thu Aug 3 18:38:13 2006 +0800
mpc83xx: Unified TQM834x variable names with 83xx and consolidated macros
Unified TQM834x variable names with 83xx and consolidated macro
in preparation for the 8360 and other upcoming 83xx devices.
Signed-off-by: Tanya Jiang <tanya.jiang@freescale.com>
commit f6eda7f80ccc13d658020268c507d7173cf2e8aa
Author: Dave Liu <daveliu@freescale.com>
Date: Wed Oct 25 14:41:21 2006 -0500
mpc83xx: Changed to unified mpx83xx names and added common 83xx changes
Incorporated the common unified variable names and the changes in preparation
for releasing mpc8360 patches.
Signed-off-by: Dave Liu <daveliu@freescale.com>
commit 3894c46c27c64891f93ac04edde86a9fa9758d92
Author: Tanya Jiang <tanya.jiang@freescale.com>
Date: Thu Aug 3 18:36:02 2006 +0800
mpc83xx: Fix missing build for mpc8349emds pci.c
Make pci build for mpc8349emds
Signed-off-by: Tanya Jiang <tanya.jiang@freescale.com>
commit 09a81ff740b29deea1e2ab08a3c2ac136c2e6219
Author: Tanya Jiang <tanya.jiang@freescale.com>
Date: Thu Aug 3 18:39:49 2006 +0800
mpc83xx: Removed unused file resetvec.S for mpc83xx cpu
Removed unused file resetvec.S for mpc83xx cpu
Signed-off-by: Tanya Jiang <tanya.jiang@freescale.com>
commit 04f899fc465c3e44f2b55ecc70618f5696fc0ddf
Author: Nick Spence <Nick.Spence@freescale.com>
Date: Sat Sep 30 00:32:59 2006 -0700
NAND Flash verify across block boundaries
This patch addresses a problem when CONFIG_MTD_NAND_VERIFY_WRITE is
defined
and the write crosses a block boundary. The pointer to the verification
buffer (bufstart) is not being updated to reflect the starting of the
new
block so the verification of the second block fails.
CHANGELOG:
* Fix NAND FLASH page verification across block boundaries
commit f484dc791a3932537213c43c654cc1295c64b84c
Author: Nick Spence <nick.spence@freescale.com>
Date: Thu Sep 7 07:39:46 2006 -0700
Added RGMII support to the TSECs and Marvell 881111 Phy
Added a phy initialization to adjust the RGMII RX and TX timing
Always set the R100 bit in 100 BaseT mode regardless of the TSEC mode
Signed-off-by: Nick Spence <nick.spence@freescale.com>
commit c59200443072353044aa4bf737a5a60f9a9af231
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Thu Nov 2 15:15:01 2006 +0100
Release U-Boot 1.1.6
commit 25721b5cec2be4bce79cfade17ec8f6aa1e67526
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Wed Nov 1 02:04:38 2006 +0100
Finish up support for MarelV38B board
- add watchdog support
- enable GPIO_WKUP_7 pin for input
- code cleanup
commit ffa150bc90c943ca265170bd1be3f293674dd5c7
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Wed Nov 1 01:45:46 2006 +0100
- Fix issues related to the use of ELDK 4 when compiling for MarelV38B:
* remove warnings when compiling ethaddr.c
* adjust linker script (fixes a crash resulting from incorrect
definition of __u_boot_cmd_start)
- Some MarelV38B code cleanup.
commit dae80f3caf9754a6dd3ddf3cf903d0c46cbd4385
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Wed Nov 1 01:38:16 2006 +0100
- Add MPC5XXX register definition MPC5XXX_WU_GPIO_DATA_I and change the
MPC5XXX_WU_GPIO_DATA macro to MPC5XXX_WU_GPIO_DATA_O (per MPC5200 User's
Manual). Replace the uses of MPC5XXX_WU_GPIO_DATA with
MPC5XXX_WU_GPIO_DATA_O for affected boards.
- Add defintions for some MPC5XXX GPIO pins.
commit 82d9c9ec29a1bec1b03ba616425ebaed231072c8
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Wed Nov 1 01:34:29 2006 +0100
Changed MarelV38B board make target to lowercase. Config file cleanup.
commit 1954be6e9c9421b45d0a9d05b10356acc7563150
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Sun Oct 29 01:03:51 2006 +0200
@ -451,6 +1185,34 @@ Date: Tue Oct 10 17:02:22 2006 -0500
Fix whitespace and 80-col issues.
commit 5c912cb1c31266c66ca59b36f9b6f87296421d75
Author: Stefan Roese <sr@denx.de>
Date: Sat Oct 7 11:36:51 2006 +0200
CFG_NAND_QUIET_TEST added to not warn upon missing NAND device
Patch by Stefan Roese, 07 Oct 2006
commit 5bc528fa4da751d472397b308137238a6465afd2
Author: Stefan Roese <sr@denx.de>
Date: Sat Oct 7 11:35:25 2006 +0200
Update ALPR code (NAND support working now)
Patch by Stefan Roese, 07 Oct 2006
commit 77d5034847d328753b80c46b83f960a14a26f40e
Author: Stefan Roese <sr@denx.de>
Date: Sat Oct 7 11:33:03 2006 +0200
Remove compile warnings in fpga code
Patch by Stefan Roese, 07 Oct 2006
commit f3443867e90d2979a7dd1c65b0d537777e1f9850
Author: Stefan Roese <sr@denx.de>
Date: Sat Oct 7 11:30:52 2006 +0200
Add CONFIG_BOARD_RESET to configure board specific reset function
Patch by Stefan Roese, 07 Oct 2006
commit f55df18187e7a45cb73fec4370d12135e6691ae1
Author: John Traill <john.traill@freescale.com>
Date: Fri Sep 29 08:23:12 2006 +0100
@ -683,6 +1445,21 @@ Date: Wed Aug 16 10:54:09 2006 -0500
Signed-off-by: Matthew McClintock <msm@freescale.com>
commit 899620c2d66d4eef3b2a0034d062e71d45d886c9
Author: Stefan Roese <sr@denx.de>
Date: Tue Aug 15 14:22:35 2006 +0200
Add initial support for the ALPR board from Prodrive
NAND needs some additional testing
Patch by Heiko Schocher, 15 Aug 2006
commit f0ff4692ff3372dec55074a8eb444943ab095abb
Author: Stefan Roese <sr@denx.de>
Date: Tue Aug 15 14:15:51 2006 +0200
Add FPGA Altera Cyclone 2 support
Patch by Heiko Schocher, 15 Aug 2006
commit fecf1c7e4de1b2779edc18742b91c22bdc32b68b
Author: Jon Loeliger <jdl@freescale.com>
Date: Mon Aug 14 15:33:38 2006 -0500

View file

@ -465,3 +465,8 @@ N: James MacAulay
E: james.macaulay@amirix.com
D: Suppport for Amirix AP1000
W: www.amirix.com
N: Timur Tabi
E: timur@freescale.com
D: Support for MPC8349E-mITX
W: www.freescale.com

View file

@ -277,10 +277,13 @@ Daniel Poirot <dan.poirot@windriver.com>
Stefan Roese <sr@denx.de>
P3M7448 MPC7448
uc100 MPC857
TQM85xx MPC8540/8541/8555/8560
alpr PPC440GX
bamboo PPC440EP
bunbinga PPC405EP
ebony PPC440GP
@ -293,6 +296,8 @@ Stefan Roese <sr@denx.de>
yellowstone PPC440GR
yosemite PPC440EP
P3M750 PPC750FX/GX/GL
Yusdi Santoso <yusdi_santoso@adaptec.com>
HIDDEN_DRAGON MPC8241/MPC8245
@ -339,6 +344,18 @@ John Zhan <zhanz@sinovee.com>
svm_sc8xx MPC8xx
Timur Tabi <timur@freescale.com>
MPC8349E-mITX MPC8349
Kim Phillips <kim.phillips@freescale.com>
MPC8349EMDS MPC8349
Dave Liu <daveliu@freescale.com>
MPC8360EMDS MPC8360
-------------------------------------------------------------------------
Unknown / orphaned boards:

40
MAKEALL
View file

@ -74,21 +74,21 @@ LIST_8xx=" \
#########################################################################
LIST_4xx=" \
ADCIOP AP1000 AR405 ASH405 \
bamboo bubinga CANBT CMS700 \
CPCI2DP CPCI405 CPCI4052 CPCI405AB \
CPCI405DT CPCI440 CPCIISER4 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 sequoia sequoia_nand \
VOH405 VOM405 W7OLMC W7OLMG \
walnut WUH405 XPEDITE1K yellowstone \
yosemite yucca bamboo \
ADCIOP alpr AP1000 AR405 \
ASH405 bamboo bubinga CANBT \
CMS700 CPCI2DP CPCI405 CPCI4052 \
CPCI405AB CPCI405DT CPCI440 CPCIISER4 \
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 sequoia \
sequoia_nand VOH405 VOM405 W7OLMC \
W7OLMG walnut WUH405 XPEDITE1K \
yellowstone yosemite yucca \
"
#########################################################################
@ -130,7 +130,7 @@ LIST_8260=" \
#########################################################################
LIST_83xx=" \
TQM834x MPC8349EMDS \
TQM834x MPC8349EMDS MPC8349ITX MPC8360EMDS \
"
@ -150,12 +150,14 @@ LIST_85xx=" \
#########################################################################
LIST_74xx=" \
DB64360 DB64460 EVB64260 mpc7448hpc2 \
P3G4 PCIPPC2 PCIPPC6 ZUMA \
DB64360 DB64460 EVB64260 P3G4 \
p3m7448 PCIPPC2 PCIPPC6 ZUMA \
mpc7448hpc2
"
LIST_7xx=" \
BAB7xx CPCI750 ELPPC ppmc7xx \
BAB7xx CPCI750 ELPPC p3m750 \
ppmc7xx \
"
LIST_ppc="${LIST_5xx} ${LIST_5xxx} \

View file

@ -174,9 +174,6 @@ endif
ifeq ($(CPU),ppc4xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc83xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
@ -206,6 +203,9 @@ LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
endif
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
@ -984,6 +984,9 @@ xtract_4xx = $(subst _25,,$(subst _33,,$(subst _BA,,$(subst _ME,,$(subst _HI,,$(
ADCIOP_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx adciop esd
alpr_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx alpr prodrive
AP1000_config:unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx ap1000 amirix
@ -1585,15 +1588,39 @@ r5200_config : unconfig
## MPC83xx Systems
#########################################################################
MPC8349ADS_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc mpc83xx mpc8349ads
TQM834x_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc mpc83xx tqm834x
MPC8349EMDS_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc mpc83xx mpc8349emds
MPC8360EMDS_config \
MPC8360EMDS_HOST_33_config \
MPC8360EMDS_HOST_66_config \
MPC8360EMDS_SLAVE_config: unconfig
@echo "" >include/config.h ; \
if [ "$(findstring _HOST_,$@)" ] ; then \
echo -n "... PCI HOST " ; \
echo "#define CONFIG_PCI" >>include/config.h ; \
fi ; \
if [ "$(findstring _SLAVE_,$@)" ] ; then \
echo "...PCI SLAVE 66M" ; \
echo "#define CONFIG_PCI" >>include/config.h ; \
echo "#define CONFIG_PCISLAVE" >>include/config.h ; \
fi ; \
if [ "$(findstring _33_,$@)" ] ; then \
echo -n "...33M ..." ; \
echo "#define PCI_33M" >>include/config.h ; \
fi ; \
if [ "$(findstring _66_,$@)" ] ; then \
echo -n "...66M..." ; \
echo "#define PCI_66M" >>include/config.h ; \
fi ;
@$(MKCONFIG) -a MPC8360EMDS ppc mpc83xx mpc8360emds
MPC8349ITX_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc mpc83xx mpc8349itx
#########################################################################
## MPC85xx Systems
#########################################################################
@ -1719,11 +1746,21 @@ EVB64260_750CX_config: unconfig
@$(MKCONFIG) EVB64260 ppc 74xx_7xx evb64260
mpc7448hpc2_config: unconfig
@./mkconfig $(@:_config=) ppc 74xx_7xx mpc7448hpc2
@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2
P3G4_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx evb64260
p3m750_config \
p3m7448_config: unconfig
@mkdir -p $(obj)include
@if [ "$(findstring 750_,$@)" ] ; then \
echo "#define CONFIG_P3M750" >>$(obj)include/config.h ; \
else \
echo "#define CONFIG_P3M7448" >>$(obj)include/config.h ; \
fi
@$(MKCONFIG) -a p3mx ppc 74xx_7xx p3mx prodrive
PCIPPC2_config \
PCIPPC6_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx pcippc2

61
README
View file

@ -1207,7 +1207,12 @@ The following options need to be configured:
clock chips. See common/cmd_i2c.c for a description of the
command line interface.
CONFIG_HARD_I2C selects the CPM hardware driver for I2C.
CONFIG_I2C_CMD_TREE is a recommended option that places
all I2C commands under a single 'i2c' root command. The
older 'imm', 'imd', 'iprobe' etc. commands are considered
deprecated and may disappear in the future.
CONFIG_HARD_I2C selects a hardware I2C controller.
CONFIG_SOFT_I2C configures u-boot to use a software (aka
bit-banging) driver instead of CPM or similar hardware
@ -1312,6 +1317,42 @@ The following options need to be configured:
in u-boot bd_info structure based on u-boot environment
variable "i2cfast". (see also i2cfast)
CONFIG_I2C_MULTI_BUS
This option allows the use of multiple I2C buses, each of which
must have a controller. At any point in time, only one bus is
active. To switch to a different bus, use the 'i2c dev' command.
Note that bus numbering is zero-based.
CFG_I2C_NOPROBES
This option specifies a list of I2C devices that will be skipped
when the 'i2c probe' command is issued (or 'iprobe' using the legacy
command). If CONFIG_I2C_MULTI_BUS is set, specify a list of bus-device
pairs. Otherwise, specify a 1D array of device addresses
e.g.
#undef CONFIG_I2C_MULTI_BUS
#define CFG_I2C_NOPROBES {0x50,0x68}
will skip addresses 0x50 and 0x68 on a board with one I2C bus
#define CONFIG_I2C_MULTI_BUS
#define CFG_I2C_MULTI_NOPROBES {{0,0x50},{0,0x68},{1,0x54}}
will skip addresses 0x50 and 0x68 on bus 0 and address 0x54 on bus 1
CFG_SPD_BUS_NUM
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.
CONFIG_FSL_I2C
Define this option if you want to use Freescale's I2C driver in
drivers/fsl_i2c.c.
- SPI Support: CONFIG_SPI
Enables SPI driver (so far only tested with
@ -2209,6 +2250,24 @@ Low Level (hardware related) configuration options:
CFG_POCMR2_MASK_ATTRIB: (MPC826x only)
Overrides the default PCI memory map in cpu/mpc8260/pci.c if set.
- CONFIG_SPD_EEPROM
Get DDR timing information from an I2C EEPROM. Common with pluggable
memory modules such as SODIMMs
SPD_EEPROM_ADDRESS
I2C address of the SPD EEPROM
- CFG_SPD_BUS_NUM
If SPD EEPROM is on an I2C bus other than the first one, specify here.
Note that the value must resolve to something your driver can deal with.
- CFG_83XX_DDR_USES_CS0
Only for 83xx systems. If specified, then DDR should be configured
using CS0 and CS1 instead of CS2 and CS3.
- CFG_83XX_DDR_USES_CS0
Only for 83xx systems. If specified, then DDR should be configured
using CS0 and CS1 instead of CS2 and CS3.
- CONFIG_ETHER_ON_FEC[12]
Define to enable FEC[12] on a 8xx series processor.

View file

@ -130,7 +130,7 @@
/* Register window 1 offsets, the window used in normal operation */
#define TX_FIFO 0x10
#define RX_FIFO 0x10
#define RX_FIFOa 0x10
#define RxErrors 0x14
#define RxStatus 0x18
#define Timer 0x1A

View file

@ -552,3 +552,9 @@ void hw_watchdog_reset(void)
}
#endif
void board_reset(void)
{
/* give reset to BCSR */
*(unsigned char *)(CFG_BCSR_BASE | 0x06) = 0x09;
}

View file

@ -548,3 +548,9 @@ void hw_watchdog_reset(void)
}
#endif
void board_reset(void)
{
/* give reset to BCSR */
*(unsigned char *)(CFG_BCSR_BASE | 0x06) = 0x09;
}

View file

@ -191,8 +191,7 @@ static struct pci_controller hose;
extern void pci_mpc5xxx_init(struct pci_controller *);
void pci_init_board(void
) {
void pci_init_board(void) {
pci_mpc5xxx_init(&hose);
}
#endif

View file

@ -191,8 +191,7 @@ static struct pci_controller hose;
extern void pci_mpc5xxx_init(struct pci_controller *);
void pci_init_board(void
) {
void pci_init_board(void) {
pci_mpc5xxx_init(&hose);
}
#endif

View file

@ -29,6 +29,10 @@
#include <pci.h>
#include <asm/processor.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
#if defined(CONFIG_LITE5200B)
#include "mt46v32m16.h"
#else
@ -332,3 +336,11 @@ void ide_set_reset (int idereset)
}
}
#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup(void *blob, bd_t *bd)
{
ft_cpu_setup(blob, bd);
}
#endif

View file

@ -27,6 +27,7 @@
#include <common.h>
#include <mpc5xxx.h>
#include <pci.h>
#include <asm/processor.h>
/* Two MT48LC8M32B2 for 32 MB */
/* #include "mt48lc8m32b2-6-7.h" */
@ -98,6 +99,7 @@ long int initdram (int board_type)
{
ulong dramsize = 0;
ulong dramsize2 = 0;
uint svr, pvr;
#ifndef CFG_RAMBOOT
ulong test1, test2;
@ -192,6 +194,22 @@ long int initdram (int board_type)
#endif /* CFG_RAMBOOT */
/*
* On MPC5200B we need to set the special configuration delay in the
* DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
* Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
*
* "The SDelay should be written to a value of 0x00000004. It is
* required to account for changes caused by normal wafer processing
* parameters."
*/
svr = get_svr();
pvr = get_pvr();
if ((SVR_MJREV(svr) >= 2) && (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
*(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
__asm__ volatile ("sync");
}
return dramsize + dramsize2;
}

View file

@ -23,26 +23,30 @@
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
LIB = $(obj)lib$(BOARD).a
OBJS = $(BOARD).o tsi108_init.o
COBJS := $(BOARD).o tsi108_init.o
SOBJS := asm_init.o
SOBJS = asm_init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): .depend $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
clean:
rm -f $(SOBJS) $(OBJS)
.PHONY: distclean
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude .depend
sinclude ($obj).depend
#########################################################################

View file

@ -1,4 +1,4 @@
/*****************************************************************************
/*
* (C) Copyright 2004-05; Tundra Semiconductor Corp.
*
* Added automatic detect of SDC settings
@ -19,9 +19,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
****************************************************************************/
*/
/*----------------------------------------------------------------------------
/*
* FILENAME: asm_init.s
*
* Originator: Alex Bounine
@ -29,7 +29,7 @@
* DESCRIPTION:
* Initialization code for the Tundra Tsi108 bridge chip
*
*---------------------------------------------------------------------------*/
*/
#include <config.h>
#include <version.h>
@ -40,7 +40,7 @@
#include <tsi108.h>
/*===========================================================================
/*
* Build Configuration Options
*/
@ -48,7 +48,7 @@
/* #define SDC_HARDCODED_INIT config SDRAM controller with hardcoded values */
/* #define SDC_AUTOPRECH_EN enable SDRAM auto precharge */
/* ===========================================================================
/*
* Hardcoded SDC settings
*/
@ -65,24 +65,24 @@
#endif /* SDC_HARDCODED_INIT */
/*---------------------------------------------------------------------------
/*
CPU Configuration:
CPU Address and Data Parity enables.
#define CPU_AP
#define CPU_DP
*/
===========================================================================
Macros
!!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
expected to work correctly for the CSR space within 32KB range.
LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
These macros are absolutely identical except their names. This difference
is provided intentionally for better readable code.
-------------------------------------------------------------------------*/
/*
* Macros
* !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are
* expected to work correctly for the CSR space within 32KB range.
*
* LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant.
* These macros are absolutely identical except their names. This difference
* is provided intentionally for better readable code.
*/
#define LOAD_PTR(reg,const32) \
addis reg,r0,const32@h; ori reg,reg,const32@l
@ -90,8 +90,9 @@
#define LOAD_U32(reg,const32) \
addis reg,r0,const32@h; ori reg,reg,const32@l
/* LOADMEM initializes a register with the contents of a specified 32-bit memory
location, usually a CSR value.*/
/* LOADMEM initializes a register with the contents of a specified 32-bit
* memory location, usually a CSR value.
*/
#define LOAD_MEM(reg,addr32) \
addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)
@ -102,37 +103,30 @@ sdc_clk_sync:
.long 0, 0, 6, 10, 8, 6, 5, 4 /* nSec */
#endif
/*===========================================================================
board_asm_init() - early initialization function. Coded to be portable to
dual-CPU configuration.
Checks CPU number and performs board HW initialization if called for CPU0.
Registers used: r3,r4,r5,r6,r19,r29
===========================================================================
---------------------------------------------------------------------------
NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
and the rest of the board. Current implementation demonstrates two
possible ways to identify CPU number:
- for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
- for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
---------------------------------------------------------------------------*/
/*
* board_asm_init() - early initialization function. Coded to be portable to
* dual-CPU configuration.
* Checks CPU number and performs board HW initialization if called for CPU0.
* Registers used: r3,r4,r5,r6,r19,r29
*
* NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108
* and the rest of the board. Current implementation demonstrates two
* possible ways to identify CPU number:
* - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM.
* - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108.
*/
.globl board_asm_init
board_asm_init:
mflr r19 /* Save LR to be able return later. */
bl icache_enable /* Enable icache to reduce reads from flash. */
/* Initialize pointer to Tsi108 register space
-------------------------------------------------------------------------*/
/* Initialize pointer to Tsi108 register space */
LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */
ori r4,r29,TSI108_PB_REG_OFFSET
/*-------------------------------------------------------------------------
Check Processor Version Number */
/* Check Processor Version Number */
mfspr r3, PVR
rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */
@ -140,10 +134,10 @@ board_asm_init:
cmpli 0,0,r3,0x8000 /* MPC74xx */
bne cont_brd_init
/* ------------------------------------------
For MPC744x/5x enable extended BATs[4-7]
Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
to disable prefetch
/*
* For MPC744x/5x enable extended BATs[4-7]
* Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1
* to disable prefetch
*/
mfspr r5, HID0
@ -167,11 +161,10 @@ board_asm_init:
isync
sync
#if(1) /* def CONFIG_DUAL_CPU
-------------------------------------------------------------------------
For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
/* def CONFIG_DUAL_CPU
* For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number.
*/
#if(1)
mfspr r3,1014 /* read MSSCR0 */
rlwinm. r3,r3,27,31,31 /* get processor ID number */
mtspr SPRN_PIR,r3 /* Save CPU ID */
@ -182,33 +175,29 @@ board_asm_init:
cont_brd_init:
/* An alternative method of checking the processor number (in addition
to configuration using MSSCR0[ID] bit on MPC74xx).
Good for IBM PPC750FX/GX.
* to configuration using MSSCR0[ID] bit on MPC74xx).
* Good for IBM PPC750FX/GX.
*/
lwz r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */
rlwinm. r3,r3,24,31,31 /* get processor ID number */
bne init_done
#else
cont_brd_init:
#endif /* CONFIG_DUAL_CPU */
/* Initialize Tsi108 chip
---------------------------------------------------------------------------
*/
/* Initialize Tsi108 chip */
do_tsi108_init:
/*--------------------------------------------------------------------------
Adjust HLP/Flash parameters. By default after reset the HLP port is set
to support slow devices. Better performance can be achived when an optimal
parameters are used for specific EPROM device.
NOTE: This should be performed ASAP for the emulation platform because
it has 5MHz HLP clocking.
/*
* Adjust HLP/Flash parameters. By default after reset the HLP port is
* set to support slow devices. Better performance can be achived when
* an optimal parameters are used for specific EPROM device.
* NOTE: This should be performed ASAP for the emulation platform
* because it has 5MHz HLP clocking.
*/
#ifdef CONFIG_TSI108EMU
@ -221,28 +210,25 @@ do_tsi108_init:
sync
#endif
/* -------------------------------------------------------------------------
* Initialize PB interface.
*/
/* Initialize PB interface. */
ori r4,r29,TSI108_PB_REG_OFFSET
#if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE)
/* Relocate (if required) Tsi108 registers. Set new value for PB_REG_BAR:
/* Relocate (if required) Tsi108 registers. Set new value for
* PB_REG_BAR:
* Note we are in the 32-bit address mode.
*/
LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* value for PB_REG_BAR: BA + EN*/
LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* PB_REG_BAR: BA + EN */
stw r5,PB_REG_BAR(r4)
andis. r29,r5,0xFFFF
sync
ori r4,r29,TSI108_PB_REG_OFFSET
#endif
/* Set PB Slave configuration register */
/* LOAD_U32(r5,0x000024C7) value for PB_SCR: TEA enabled,AACK delay = 7 */
LOAD_U32(r5,0x00002481) /* value for PB_SCR: TEA enabled,AACK delay = 1 */
LOAD_U32(r5,0x00002481) /* PB_SCR: TEA enabled,AACK delay = 1 */
lwz r3, PB_RSR(r4) /* get PB bus mode */
xori r3,r3,0x0001 /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */
rlwimi r5,r3,14,17,17 /* for MPX: set DTI_MODE bit */
@ -257,10 +243,7 @@ do_tsi108_init:
ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */
#endif
andc r5,r5,r3 /* Clear the masked bit fields */
/* ori r5,r5,0x0040 Set pipeline depth 4
ori r5,r5,0x0080 Set pipeline depth 8
ori r5,r5,0x0020 !!!avb Testing: set pipeline depth 2 */
ori r5,r5,0x0001
ori r5,r5,0x0001 /* Set pipeline depth */
stw r5,PB_ARB_CTRL(r4)
#if (0) /* currently using the default settings for PBM after reset */
@ -274,9 +257,9 @@ do_tsi108_init:
#endif
/* Disable or enable PVT based on processor bus frequency
1. Read CG_PWRUP_STATUS register field bits 18,17,16
2. See if the value is < or > 133mhz (18:16 = 100)
3. If > enable PVT
* 1. Read CG_PWRUP_STATUS register field bits 18,17,16
* 2. See if the value is < or > 133mhz (18:16 = 100)
* 3. If > enable PVT
*/
LOAD_U32(r3,0xC0002234)
@ -293,9 +276,7 @@ do_tsi108_init:
sync
#endif
/*---------------------------------------------------------------------------
Initialize SDRAM controller.
----------------------------------------------------------------------------*/
/* Initialize SDRAM controller. */
sdc_init:
@ -337,7 +318,8 @@ get_nsec:
#ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */
/* First read the CG_PWRUP_STATUS register to get the
memory speed from bits 22,21,20 */
* memory speed from bits 22,21,20
*/
LOAD_U32(r3,0xC0002234)
lwz r3,0(r3)
@ -348,9 +330,9 @@ get_nsec:
cmpi 0,0,r3,0x0005
bne check_for_200mhz
/* set values for 166 Mhz memory speed */
/* Set refresh rate and timing parameters */
/* set values for 166 Mhz memory speed
* Set refresh rate and timing parameters
*/
LOAD_U32(r5,0x00000515)
stw r5,SD_REFRESH(r4)
LOAD_U32(r5,0x03073368)
@ -386,9 +368,9 @@ check_for_200mhz:
cmpi 0,0,r3,0x0006
bne set_default_values
/* set values for 200Mhz memory speed */
/* Set refresh rate and timing parameters */
/* set values for 200Mhz memory speed
* Set refresh rate and timing parameters
*/
LOAD_U32(r5,0x0000061a)
stw r5,SD_REFRESH(r4)
LOAD_U32(r5,0x03083348)
@ -449,11 +431,8 @@ set_default_values:
LOAD_U32(r5,VAL_SD_D1_BAR)
stw r5,SD_D1_BAR(r4)
sync
#else /* !SDC_HARDCODED_INIT */
bl tsi108_sdram_spd /* automatically detect SDC settings */
#endif /* SDC_HARDCODED_INIT */
sdc_init_done:
@ -481,43 +460,47 @@ sdc_init_done:
wait_init_complete:
lwz r5,SD_STATUS(r4)
andi. r5,r5,0x0001
beq wait_init_complete /* wait until SDRAM initialization is complete */
/* wait until SDRAM initialization is complete */
beq wait_init_complete
/*---------------------------------------------------------------------------
Map SDRAM into the processor bus address space
---------------------------------------------------------------------------*/
/* Map SDRAM into the processor bus address space */
ori r4,r29,TSI108_PB_REG_OFFSET
/* Setup BARs associated with direct path PB<->SDRAM */
/* PB_SDRAM_BAR1:
provides a direct path to the main system memory (cacheable SDRAM) */
* provides a direct path to the main system memory (cacheable SDRAM)
*/
LOAD_U32(r5, 0x00000011) /* BA=0,Size=512MB, ENable, No Addr.Translation */
/* BA=0,Size=512MB, ENable, No Addr.Translation */
LOAD_U32(r5, 0x00000011)
stw r5,PB_SDRAM_BAR1(r4)
sync
/* Make sure that PB_SDRAM_BAR1 decoder is set
(to allow following immediate read from SDRAM) */
* (to allow following immediate read from SDRAM)
*/
lwz r5,PB_SDRAM_BAR1(r4)
sync
/* PB_SDRAM_BAR2:
provides non-cacheable alias (via the direct path) to main system memory.
Size = 512MB, ENable, Addr.Translation - ON,
BA = 0x0_40000000, TA = 0x0_00000000 */
* provides non-cacheable alias (via the direct path) to main
* system memory.
* Size = 512MB, ENable, Addr.Translation - ON,
* BA = 0x0_40000000, TA = 0x0_00000000
*/
LOAD_U32(r5, 0x40010011)
stw r5,PB_SDRAM_BAR2(r4)
sync
/* Make sure that PB_SDRAM_BAR2 decoder is set
(to allow following immediate read from SDRAM) */
* (to allow following immediate read from SDRAM)
*/
lwz r5,PB_SDRAM_BAR2(r4)
sync
init_done:
/* All done. Restore LR and return. */
@ -525,11 +508,11 @@ init_done:
blr
#if (0)
/*===========================================================================
init_cpu1
This routine enables CPU1 on the dual-processor system.
===========================================================================*/
/*
* init_cpu1
* This routine enables CPU1 on the dual-processor system.
* Now there is only one processor in the system
*/
.global enable_cpu1
enable_cpu1:
@ -545,11 +528,10 @@ enable_cpu1:
blr
#endif
/*===========================================================================
enable_EI
Enable CPU core external interrupt
===========================================================================*/
/*
* enable_EI
* Enable CPU core external interrupt
*/
.global enable_EI
enable_EI:
@ -558,11 +540,10 @@ enable_EI:
mtmsr r3
blr
/*===========================================================================
disable_EI
Disable CPU core external interrupt
===========================================================================*/
/*
* disable_EI
* Disable CPU core external interrupt
*/
.global disable_EI
disable_EI:
@ -573,11 +554,7 @@ disable_EI:
blr
#ifdef ENABLE_SDRAM_ECC
/*===========================================================================
enable_ECC
enables SDRAM ECC
===========================================================================*/
/* enables SDRAM ECC */
.global enable_ECC
enable_ECC:
@ -587,17 +564,15 @@ enable_ECC:
stw r3,SD_ECC_CTRL(r4)
blr
/*===========================================================================
clear_ECC_err
Clears all pending SDRAM ECC errors
(normally after SDRAM scrubbing/initialization)
===========================================================================*/
/*
* clear_ECC_err
* Clears all pending SDRAM ECC errors
* (normally after SDRAM scrubbing/initialization)
*/
.global clear_ECC_err
clear_ECC_err:
ori r4,r29,TSI108_SD_REG_OFFSET
/* lwz r3,SD_INT_STATUS(r4) Read SDRAM ECC Control Register */
ori r3,r0,0x0030 /* ECC_UE_INT + ECC_CE_INT bits */
stw r3,SD_INT_STATUS(r4)
blr
@ -606,10 +581,7 @@ clear_ECC_err:
#ifndef SDC_HARDCODED_INIT
/********************************************************************
* SDRAM SPD Support
*/
/* SDRAM SPD Support */
#define SD_I2C_CTRL1 (0x400)
#define SD_I2C_CTRL2 (0x404)
#define SD_I2C_RD_DATA (0x408)
@ -682,14 +654,14 @@ refresh_rates: /* in nSec */
.long 62500 /* Extended 4x (0x84) */
.long 125000 /* Extended 8x (0x85) */
/*===========================================================================
/*
* tsi108_sdram_spd
*
* Inittializes SDRAM Controller using DDR2 DIMM Serial Presence Detect data
* Uses registers: r4 - SDC base address (not changed)
* r9 - SDC clocking period in nSec
* Changes registers: r3,r5,r6,r7,r8,r10,r11
*==========================================================================*/
*/
tsi108_sdram_spd:
@ -698,9 +670,7 @@ tsi108_sdram_spd:
do_first_dimm:
/**************************************
* Program Refresh Rate Register
*/
/* Program Refresh Rate Register */
READ_SPD(12) /* get Refresh Rate */
beq check_next_slot
@ -718,9 +688,7 @@ do_first_dimm:
stw r5,SD_REFRESH(r4) /* Set refresh rate */
sync
/**************************************
* Program SD Timing Register
*/
/* Program SD Timing Register */
li r7, 0 /* clear r7 prior parameter collection */
@ -768,7 +736,8 @@ set_tras:
READ_SPD(29) /* Get tRCD */
beq spd_read_fail
rlwinm r3,r3,30,2,31/* right shift tRCD by 2 bits as per DDR2 spec */
/* right shift tRCD by 2 bits as per DDR2 spec */
rlwinm r3,r3,30,2,31
divwu r6,r3,r9
mullw r8,r6,r9
subf. r8,r8,r3
@ -829,17 +798,14 @@ set_trfc:
stw r7,SD_TIMING(r4)
sync
/*=====================================================================
/*
* The following two registers are set on per-DIMM basis.
* The SD_REFRESH and SD_TIMING settings are common for both DIMMS
*=====================================================================
*/
do_each_dimm:
/*****************************************
* Program SDRAM DIMM Control Register
*/
/* Program SDRAM DIMM Control Register */
li r7, 0 /* clear r7 prior parameter collection */
@ -897,9 +863,7 @@ set_dimm_ctrl:
sync
/********************************************
* Program SDRAM DIMMx Base Address Register
*/
/* Program SDRAM DIMMx Base Address Register */
set_dimm_bar:
READ_SPD(5) /* get # of Ranks */
@ -952,4 +916,3 @@ err_hung: /* hang here for debugging */
b err_hung
#endif /* !SDC_HARDCODED_INIT */

View file

@ -57,7 +57,6 @@ void after_reloc(ulong dest_addr)
/*
* Check Board Identity:
*
* report board type
*/
@ -90,387 +89,6 @@ long int initdram(int board_type)
return dram_size (board_type);
}
/* DRAM check routines copied from gw8260 */
#if defined (CFG_DRAM_TEST)
/*********************************************************************/
/* NAME: move64() - moves a double word (64-bit) */
/* */
/* DESCRIPTION: */
/* this function performs a double word move from the data at */
/* the source pointer to the location at the destination pointer. */
/* */
/* INPUTS: */
/* unsigned long long *src - pointer to data to move */
/* */
/* OUTPUTS: */
/* unsigned long long *dest - pointer to locate to move data */
/* */
/* RETURNS: */
/* None */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* May cloober fr0. */
/* */
/*********************************************************************/
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 */
return;
}
#if defined (CFG_DRAM_TEST_DATA)
unsigned long long pattern[] = {
0xaaaaaaaaaaaaaaaaULL,
0xccccccccccccccccULL,
0xf0f0f0f0f0f0f0f0ULL,
0xff00ff00ff00ff00ULL,
0xffff0000ffff0000ULL,
0xffffffff00000000ULL,
0x00000000ffffffffULL,
0x0000ffff0000ffffULL,
0x00ff00ff00ff00ffULL,
0x0f0f0f0f0f0f0f0fULL,
0x3333333333333333ULL,
0x5555555555555555ULL
};
/*********************************************************************/
/* NAME: mem_test_data() - test data lines for shorts and opens */
/* */
/* DESCRIPTION: */
/* Tests data lines for shorts and opens by forcing adjacent data */
/* to opposite states. Because the data lines could be routed in */
/* an arbitrary manner the must ensure test patterns ensure that */
/* every case is tested. By using the following series of binary */
/* patterns every combination of adjacent bits is test regardless */
/* of routing. */
/* */
/* ...101010101010101010101010 */
/* ...110011001100110011001100 */
/* ...111100001111000011110000 */
/* ...111111110000000011111111 */
/* */
/* Carrying this out, gives us six hex patterns as follows: */
/* */
/* 0xaaaaaaaaaaaaaaaa */
/* 0xcccccccccccccccc */
/* 0xf0f0f0f0f0f0f0f0 */
/* 0xff00ff00ff00ff00 */
/* 0xffff0000ffff0000 */
/* 0xffffffff00000000 */
/* */
/* The number test patterns will always be given by: */
/* */
/* log(base 2)(number data bits) = log2 (64) = 6 */
/* */
/* To test for short and opens to other signals on our boards. we */
/* simply */
/* test with the 1's complemnt of the paterns as well. */
/* */
/* OUTPUTS: */
/* Displays failing test pattern */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* Assumes only one one SDRAM bank */
/* */
/*********************************************************************/
int mem_test_data(void)
{
unsigned long long *pmem = (unsigned long long *)CFG_MEMTEST_START;
unsigned long long temp64;
int num_patterns = sizeof(pattern) / sizeof(pattern[0]);
int i;
unsigned int hi, lo;
for (i = 0; i < num_patterns; i++) {
move64(&(pattern[i]), pmem);
move64(pmem, &temp64);
/* hi = (temp64>>32) & 0xffffffff; */
/* lo = temp64 & 0xffffffff; */
/* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
hi = (pattern[i] >> 32) & 0xffffffff;
lo = pattern[i] & 0xffffffff;
/* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
if (temp64 != pattern[i]) {
printf("\n Data Test Failed, pattern 0x%08x%08x",
hi, lo);
return 1;
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_DATA */
#if defined (CFG_DRAM_TEST_ADDRESS)
/*********************************************************************/
/* NAME: mem_test_address() - test address lines */
/* */
/* DESCRIPTION: */
/* This function performs a test to verify that each word im */
/* memory is uniquly addressable. The test sequence is as follows: */
/* */
/* 1) write the address of each word to each word. */
/* 2) verify that each location equals its address */
/* */
/* OUTPUTS: */
/* Displays failing test pattern and address */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_test_address(void)
{
volatile unsigned int *pmem =
(volatile unsigned int *)CFG_MEMTEST_START;
const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 4;
unsigned int i;
/* write address to each location */
for (i = 0; i < size; i++) {
pmem[i] = i;
}
/* verify each loaction */
for (i = 0; i < size; i++) {
if (pmem[i] != i) {
printf("\n Address Test Failed at 0x%x", i);
return 1;
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_ADDRESS */
#if defined (CFG_DRAM_TEST_WALK)
/*********************************************************************/
/* NAME: mem_march() - memory march */
/* */
/* DESCRIPTION: */
/* Marches up through memory. At each location verifies rmask if */
/* read = 1. At each location write wmask if write = 1. Displays */
/* failing address and pattern. */
/* */
/* INPUTS: */
/* volatile unsigned long long * base - start address of test */
/* unsigned int size - number of dwords(64-bit) to test */
/* unsigned long long rmask - read verify mask */
/* unsigned long long wmask - wrtie verify mask */
/* short read - verifies rmask if read = 1 */
/* short write - writes wmask if write = 1 */
/* */
/* OUTPUTS: */
/* Displays failing test pattern and address */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_march(volatile unsigned long long *base,
unsigned int size,
unsigned long long rmask,
unsigned long long wmask, short read, short write)
{
unsigned int i;
unsigned long long temp;
unsigned int hitemp, lotemp, himask, lomask;
for (i = 0; i < size; i++) {
if (read != 0) {
/* temp = base[i]; */
move64((unsigned long long *)&(base[i]), &temp);
if (rmask != temp) {
hitemp = (temp >> 32) & 0xffffffff;
lotemp = temp & 0xffffffff;
himask = (rmask >> 32) & 0xffffffff;
lomask = rmask & 0xffffffff;
printf("\n Walking one's test failed: \
address = 0x%08x," "\n\texpected \
0x%08x%08x, found 0x%08x%08x", i << 3,\
himask, lomask, hitemp, lotemp);
return 1;
}
}
if (write != 0) {
/* base[i] = wmask; */
move64(&wmask, (unsigned long long *)&(base[i]));
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_WALK */
/*********************************************************************/
/* NAME: mem_test_walk() - a simple walking ones test */
/* */
/* DESCRIPTION: */
/* Performs a walking ones through entire physical memory. The */
/* test uses as series of memory marches, mem_march(), to verify */
/* and write the test patterns to memory. The test sequence is as */
/* follows: */
/* 1) march writing 0000...0001 */
/* 2) march verifying 0000...0001 , writing 0000...0010 */
/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
/* the write mask equals 1000...0000 */
/* 4) march verifying 1000...0000 */
/* The test fails if any of the memory marches return a failure. */
/* */
/* OUTPUTS: */
/* Displays which pass on the memory test is executing */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_test_walk(void)
{
unsigned long long mask;
volatile unsigned long long *pmem =
(volatile unsigned long long *)CFG_MEMTEST_START;
const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 8;
unsigned int i;
mask = 0x01;
printf("Initial Pass");
mem_march(pmem, size, 0x0, 0x1, 0, 1);
printf("\b\b\b\b\b\b\b\b\b\b\b\b");
printf(" ");
printf(" ");
printf("\b\b\b\b\b\b\b\b\b\b\b\b");
for (i = 0; i < 63; i++) {
printf("Pass %2d", i + 2);
if (mem_march(pmem, size, mask, mask << 1, 1, 1) != 0) {
/*printf("mask: 0x%x, pass: %d, ", mask, i); */
return 1;
}
mask = mask << 1;
printf("\b\b\b\b\b\b\b");
}
printf("Last Pass");
if (mem_march(pmem, size, 0, mask, 0, 1) != 0) {
/* printf("mask: 0x%x", mask); */
return 1;
}
printf("\b\b\b\b\b\b\b\b\b");
printf(" ");
printf("\b\b\b\b\b\b\b\b\b");
return 0;
}
/*********************************************************************/
/* NAME: testdram() - calls any enabled memory tests */
/* */
/* DESCRIPTION: */
/* Runs memory tests if the environment test variables are set to */
/* 'y'. */
/* */
/* INPUTS: */
/* testdramdata - If set to 'y', data test is run. */
/* testdramaddress - If set to 'y', address test is run. */
/* testdramwalk - If set to 'y', walking ones test is run */
/* */
/* OUTPUTS: */
/* None */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int testdram(void)
{
char *s;
int rundata, runaddress, runwalk;
s = getenv("testdramdata");
rundata = (s && (*s == 'y')) ? 1 : 0;
s = getenv("testdramaddress");
runaddress = (s && (*s == 'y')) ? 1 : 0;
s = getenv("testdramwalk");
runwalk = (s && (*s == 'y')) ? 1 : 0;
/* rundata = 1; */
/* runaddress = 0; */
/* runwalk = 0; */
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
printf("Testing RAM from 0x%08x to 0x%08x ... \
(don't panic... that will take a moment !!!!)\n", \
CFG_MEMTEST_START, CFG_MEMTEST_END);
}
#ifdef CFG_DRAM_TEST_DATA
if (rundata == 1) {
printf("Test DATA ... ");
if (mem_test_data () == 1) {
printf("failed \n");
return 1;
} else
printf("ok \n");
}
#endif
#ifdef CFG_DRAM_TEST_ADDRESS
if (runaddress == 1) {
printf("Test ADDRESS ... ");
if (mem_test_address () == 1) {
printf("failed \n");
return 1;
} else
printf("ok \n");
}
#endif
#ifdef CFG_DRAM_TEST_WALK
if (runwalk == 1) {
printf("Test WALKING ONEs ... ");
if (mem_test_walk() == 1) {
printf("failed \n");
return 1;
} else
printf("ok \n");
}
#endif
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
printf("passed\n");
}
return 0;
}
#endif /* CFG_DRAM_TEST */
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup (void *blob, bd_t *bd)

View file

@ -145,26 +145,27 @@ int board_early_init_f(void)
ulong i;
gd->mem_clk = 0;
i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
i = (i >> 20) & 0x07;
i = in32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
CG_PWRUP_STATUS);
i = (i >> 20) & 0x07; /* Get GD PLL multiplier */
switch (i) {
case 0:
case 0: /* external clock */
printf ("Using external clock\n");
break;
case 1:
case 1: /* system clock */
gd->mem_clk = gd->bus_clk;
break;
case 4:
case 5:
case 6:
case 4: /* 133 MHz */
case 5: /* 166 MHz */
case 6: /* 200 MHz */
gd->mem_clk = pb_clk_sel[i] * 1000000;
break;
default:
printf ("Invalid DDR2 clock setting\n");
return -1;
}
printf("BUS! %d MHz\n", get_board_bus_clk() / 1000000);
printf("MEM! %d MHz\n", gd->mem_clk / 1000000);
printf ("BUS: %d MHz\n", get_board_bus_clk() / 1000000);
printf ("MEM: %d MHz\n", gd->mem_clk / 1000000);
return 0;
}
@ -228,7 +229,7 @@ int board_early_init_r(void)
__asm__ __volatile__ ("sync");
/* Base addresses for Cs0, CS1, CS2, CS3 */
/* Base addresses for CS0, CS1, CS2, CS3 */
out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
0x00000000);
@ -338,10 +339,9 @@ int board_early_init_r(void)
temp = get_cpu_type ();
if ((CPU_750FX == temp) || (CPU_750GX == temp)) {
if ((CPU_750FX == temp) || (CPU_750GX == temp))
out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_MCMD,
0x00009955);
}
#endif /* DISABLE_PBM */
#ifdef CONFIG_PCI
@ -350,8 +350,8 @@ int board_early_init_r(void)
*/
/* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0_UPPER,
0);
out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
PCI_PFAB_BAR0_UPPER, 0);
__asm__ __volatile__ ("sync");
out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0,
@ -360,8 +360,8 @@ int board_early_init_r(void)
/* Set Bus Number for the attached PCI/X bus (we will use 0 for NB) */
temp =
in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
temp = in32(CFG_TSI108_CSR_BASE +
TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
temp &= ~0xFF00; /* Clear the BUS_NUM field */
@ -510,8 +510,8 @@ int board_early_init_r(void)
#ifdef ENABLE_PCI_CSR_BAR
/* open if required access to Tsi108 CSRs from the PCI/X bus */
/* enable BAR0 on the PCI/X bus */
reg_val =
in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
reg_val = in32(CFG_TSI108_CSR_BASE +
TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
reg_val |= 0x02;
out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR,
reg_val);
@ -595,8 +595,10 @@ int misc_init_r(void)
* Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D = 0.5%
*/
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0x002e0044); /* D = 0.25% */
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1, 0x00000039); /* BWADJ */
out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
0x002e0044); /* D = 0.25% */
out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1,
0x00000039); /* BWADJ */
/* Initialize PLL0: CG_PB_CLKO */
/* Detect PB clock freq. */
@ -610,7 +612,8 @@ int misc_init_r(void)
/* Wait and set SSEN for both PLL0 and 1 */
udelay (1000);
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0x802e0044); /* D=0.25% */
out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
0x802e0044); /* D=0.25% */
out32 (CFG_TSI108_CSR_BASE +
TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
0x80000000 | pll0_config[i].ctrl0);

View file

@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS := $(BOARD).o
COBJS := $(BOARD).o pci.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))

View file

@ -33,6 +33,10 @@
#if defined(CONFIG_SPD_EEPROM)
#include <spd_sdram.h>
#endif
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
int fixed_sdram(void);
void sdram_init(void);
@ -59,7 +63,7 @@ int board_early_init_f (void)
long int initdram (int board_type)
{
volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
volatile immap_t *im = (immap_t *)CFG_IMMR;
u32 msize = 0;
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
@ -96,7 +100,7 @@ long int initdram (int board_type)
************************************************************************/
int fixed_sdram(void)
{
volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
volatile immap_t *im = (immap_t *)CFG_IMMR;
u32 msize = 0;
u32 ddr_size;
u32 ddr_size_log2;
@ -167,8 +171,8 @@ int checkboard (void)
void sdram_init(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile lbus8349_t *lbc= &immap->lbus;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile lbus83xx_t *lbc= &immap->lbus;
uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE;
puts("\n SDRAM on Local Bus: ");
@ -245,8 +249,8 @@ void sdram_init(void)
*/
void ecc_print_status(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ddr83xx_t *ddr = &immap->ddr;
printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
@ -320,8 +324,8 @@ void ecc_print_status(void)
int do_ecc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ddr83xx_t *ddr = &immap->ddr;
volatile u32 val;
u64 *addr, count, val64;
register u64 *i;
@ -564,3 +568,23 @@ U_BOOT_CMD(
" - re-inits memory"
);
#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
#ifdef CONFIG_PCI
ft_pci_setup(blob, bd);
#endif
ft_cpu_setup(blob, bd);
p = ft_get_prop(blob, "/memory/reg", &len);
if (p != NULL) {
*p++ = cpu_to_be32(bd->bi_memstart);
*p = cpu_to_be32(bd->bi_memsize);
}
}
#endif

View file

@ -68,12 +68,13 @@ static struct pci_controller pci_hose[] = {
void
pib_init(void)
{
u8 val8;
u8 val8, orig_i2c_bus;
/*
* Assign PIB PMC slot to desired PCI bus
*/
mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET);
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
/* Switch temporarily to I2C bus #2 */
orig_i2c_bus = i2c_get_bus_num();
i2c_set_bus_num(1);
val8 = 0;
i2c_write(0x23, 0x6, 1, &val8, 1);
@ -118,6 +119,8 @@ pib_init(void)
printf("PCI1: 32-bit on PMC1, PMC2\n");
printf("PCI2: 32-bit on PMC3\n");
#endif
/* Reset to original I2C bus */
i2c_set_bus_num(orig_i2c_bus);
}
/**************************************************************************
@ -130,18 +133,18 @@ void
pci_init_board(void)
{
volatile immap_t * immr;
volatile clk8349_t * clk;
volatile law8349_t * pci_law;
volatile pot8349_t * pci_pot;
volatile pcictrl8349_t * pci_ctrl;
volatile pciconf8349_t * pci_conf;
volatile clk83xx_t * clk;
volatile law83xx_t * pci_law;
volatile pot83xx_t * pci_pot;
volatile pcictrl83xx_t * pci_ctrl;
volatile pciconf83xx_t * pci_conf;
u16 reg16;
u32 reg32;
u32 dev;
struct pci_controller * hose;
immr = (immap_t *)CFG_IMMRBAR;
clk = (clk8349_t *)&immr->clk;
immr = (immap_t *)CFG_IMMR;
clk = (clk83xx_t *)&immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
@ -254,8 +257,8 @@ pci_init_board(void)
hose->region_count = 4;
pci_setup_indirect(hose,
(CFG_IMMRBAR+0x8300),
(CFG_IMMRBAR+0x8304));
(CFG_IMMR+0x8300),
(CFG_IMMR+0x8304));
pci_register_hose(hose);
@ -350,8 +353,8 @@ pci_init_board(void)
hose->region_count = 4;
pci_setup_indirect(hose,
(CFG_IMMRBAR+0x8380),
(CFG_IMMRBAR+0x8384));
(CFG_IMMR+0x8380),
(CFG_IMMR+0x8384));
pci_register_hose(hose);
@ -379,4 +382,26 @@ pci_init_board(void)
}
#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[0].first_busno;
p[1] = pci_hose[0].last_busno;
}
#ifdef CONFIG_MPC83XX_PCI2
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[1].first_busno;
p[1] = pci_hose[1].last_busno;
}
#endif
}
#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */

48
board/mpc8349itx/Makefile Normal file
View file

@ -0,0 +1,48 @@
#
# Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
#
# 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 pci.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS)
$(AR) crv $@ $(OBJS)
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,33 @@
#
# Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
#
# 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
#
#
# MPC8349ITX
#
TEXT_BASE = 0xFEF00000
ifneq ($(OBJTREE),$(SRCTREE))
# We are building u-boot in a separate directory, use generated
# .lds script from OBJTREE directory.
LDSCRIPT := $(OBJTREE)/board/$(BOARDDIR)/u-boot.lds
endif

View file

@ -0,0 +1,477 @@
/*
* Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <ioports.h>
#include <mpc83xx.h>
#include <i2c.h>
#include <spd.h>
#include <miiphy.h>
#ifdef CONFIG_PCI
#include <asm/mpc8349_pci.h>
#include <pci.h>
#endif
#ifdef CONFIG_SPD_EEPROM
#include <spd_sdram.h>
#else
#include <asm/mmu.h>
#endif
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
#ifndef CONFIG_SPD_EEPROM
/*************************************************************************
* fixed sdram init -- doesn't use serial presence detect.
************************************************************************/
int fixed_sdram(void)
{
volatile immap_t *im = (immap_t *) CFG_IMMR;
u32 ddr_size; /* The size of RAM, in bytes */
u32 ddr_size_log2 = 0;
for (ddr_size = CFG_DDR_SIZE * 0x100000; ddr_size > 1; ddr_size >>= 1) {
if (ddr_size & 1) {
return -1;
}
ddr_size_log2++;
}
im->sysconf.ddrlaw[0].ar =
LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
im->sysconf.ddrlaw[0].bar = (CFG_DDR_SDRAM_BASE >> 12) & 0xfffff;
/* Only one CS0 for DDR */
im->ddr.csbnds[0].csbnds = 0x0000000f;
im->ddr.cs_config[0] = CFG_DDR_CONFIG;
debug("cs0_bnds = 0x%08x\n", im->ddr.csbnds[0].csbnds);
debug("cs0_config = 0x%08x\n", im->ddr.cs_config[0]);
debug("DDR:bar=0x%08x\n", im->sysconf.ddrlaw[0].bar);
debug("DDR:ar=0x%08x\n", im->sysconf.ddrlaw[0].ar);
im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;/* Was "2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT" */
im->ddr.sdram_cfg = SDRAM_CFG_SREN | SDRAM_CFG_SDRAM_TYPE_DDR;
im->ddr.sdram_mode =
(0x0000 << SDRAM_MODE_ESD_SHIFT) | (0x0032 << SDRAM_MODE_SD_SHIFT);
im->ddr.sdram_interval =
(0x0410 << SDRAM_INTERVAL_REFINT_SHIFT) | (0x0100 <<
SDRAM_INTERVAL_BSTOPRE_SHIFT);
im->ddr.sdram_clk_cntl =
DDR_SDRAM_CLK_CNTL_SS_EN | DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05;
udelay(200);
im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
debug("DDR:timing_cfg_1=0x%08x\n", im->ddr.timing_cfg_1);
debug("DDR:timing_cfg_2=0x%08x\n", im->ddr.timing_cfg_2);
debug("DDR:sdram_mode=0x%08x\n", im->ddr.sdram_mode);
debug("DDR:sdram_interval=0x%08x\n", im->ddr.sdram_interval);
debug("DDR:sdram_cfg=0x%08x\n", im->ddr.sdram_cfg);
return CFG_DDR_SIZE;
}
#endif
#ifdef CONFIG_PCI
/*
* Initialize PCI Devices, report devices found
*/
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_mpc83xxmitx_config_table[] = {
{
PCI_ANY_ID,
PCI_ANY_ID,
PCI_ANY_ID,
PCI_ANY_ID,
0x0f,
PCI_ANY_ID,
pci_cfgfunc_config_device,
{
PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}
},
{}
}
#endif
volatile static struct pci_controller hose[] = {
{
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc83xxmitx_config_table,
#endif
},
{
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc83xxmitx_config_table,
#endif
}
};
#endif /* CONFIG_PCI */
/* If MPC8349E-mITX is soldered with SDRAM, then initialize it. */
void sdram_init(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile lbus83xx_t *lbc = &immap->lbus;
#if defined(CFG_BR2_PRELIM) \
&& defined(CFG_OR2_PRELIM) \
&& defined(CFG_LBLAWBAR2_PRELIM) \
&& defined(CFG_LBLAWAR2_PRELIM) \
&& !defined(CONFIG_COMPACT_FLASH)
uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE;
puts("\n SDRAM on Local Bus: ");
print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
/*
* Setup SDRAM Base and Option Registers, already done in cpu_init.c
*/
/*setup mtrpt, lsrt and lbcr for LB bus */
lbc->lbcr = CFG_LBC_LBCR;
lbc->mrtpr = CFG_LBC_MRTPR;
lbc->lsrt = CFG_LBC_LSRT;
asm("sync");
/*
* Configure the SDRAM controller Machine Mode register.
*/
lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation */
lbc->lsdmr = CFG_LBC_LSDMR_1; /*0x68636733; precharge all the banks */
asm("sync");
*sdram_addr = 0xff;
udelay(100);
lbc->lsdmr = CFG_LBC_LSDMR_2; /*0x48636733; auto refresh */
asm("sync");
*sdram_addr = 0xff; /*1 time*/
udelay(100);
*sdram_addr = 0xff; /*2 times*/
udelay(100);
*sdram_addr = 0xff; /*3 times*/
udelay(100);
*sdram_addr = 0xff; /*4 times*/
udelay(100);
*sdram_addr = 0xff; /*5 times*/
udelay(100);
*sdram_addr = 0xff; /*6 times*/
udelay(100);
*sdram_addr = 0xff; /*7 times*/
udelay(100);
*sdram_addr = 0xff; /*8 times*/
udelay(100);
lbc->lsdmr = CFG_LBC_LSDMR_4; /*0x58636733;mode register write operation */
asm("sync");
*sdram_addr = 0xff;
udelay(100);
lbc->lsdmr = CFG_LBC_LSDMR_5; /*0x40636733;normal operation */
asm("sync");
*sdram_addr = 0xff;
udelay(100);
#else
puts("SDRAM on Local Bus is NOT available!\n");
#ifdef CFG_BR2_PRELIM
lbc->bank[2].br = CFG_BR2_PRELIM;
lbc->bank[2].or = CFG_OR2_PRELIM;
#endif
#ifdef CFG_BR3_PRELIM
lbc->bank[3].br = CFG_BR3_PRELIM;
lbc->bank[3].or = CFG_OR3_PRELIM;
#endif
#endif
}
long int initdram(int board_type)
{
volatile immap_t *im = (immap_t *) CFG_IMMR;
u32 msize = 0;
#ifdef CONFIG_DDR_ECC
volatile ddr83xx_t *ddr = &im->ddr;
#endif
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
return -1;
/* DDR SDRAM - Main SODIMM */
im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
#ifdef CONFIG_SPD_EEPROM
msize = spd_sdram();
#else
msize = fixed_sdram();
#endif
#ifdef CONFIG_DDR_ECC
if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
/* Unlike every other board, on the 83xx spd_sdram() returns
megabytes instead of just bytes. That's why we need to
multiple by 1MB when calling ddr_enable_ecc(). */
ddr_enable_ecc(msize * 1048576);
#endif
/*
* Initialize SDRAM if it is on local bus.
*/
sdram_init();
puts(" DDR RAM: ");
/* return total bus SDRAM size(bytes) -- DDR */
return msize * 1024 * 1024;
}
int checkboard(void)
{
puts("Board: Freescale MPC8349E-mITX\n");
return 0;
}
/*
* Implement a work-around for a hardware problem with compact
* flash.
*
* Program the UPM if compact flash is enabled.
*/
int misc_init_f(void)
{
volatile u32 *vsc7385_cpuctrl;
/* 0x1c0c0 is the VSC7385 CPU Control (CPUCTRL) Register. The power up
default of VSC7385 L1_IRQ and L2_IRQ requests are active high. That
means it is 0 when the IRQ is not active. This makes the wire-AND
logic always assert IRQ7 to CPU even if there is no request from the
switch. Since the compact flash and the switch share the same IRQ,
the Linux kernel will think that the compact flash is requesting irq
and get stuck when it tries to clear the IRQ. Thus we need to set
the L2_IRQ0 and L2_IRQ1 to active low.
The following code sets the L1_IRQ and L2_IRQ polarity to active low.
Without this code, compact flash will not work in Linux because
unlike U-Boot, Linux uses the IRQ, so this code is necessary if we
don't enable compact flash for U-Boot.
*/
vsc7385_cpuctrl = (volatile u32 *)(CFG_VSC7385_BASE + 0x1c0c0);
*vsc7385_cpuctrl |= 0x0c;
#ifdef CONFIG_COMPACT_FLASH
/* UPM Table Configuration Code */
static uint UPMATable[] = {
0xcffffc00, 0x0fffff00, 0x0fafff00, 0x0fafff00,
0x0faffd00, 0x0faffc04, 0x0ffffc00, 0x3ffffc01,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfff7fc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
0xcffffc00, 0x0fffff00, 0x0ff3ff00, 0x0ff3ff00,
0x0ff3fe00, 0x0ffffc00, 0x3ffffc05, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01
};
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile lbus83xx_t *lbus = &immap->lbus;
lbus->bank[3].br = CFG_BR3_PRELIM;
lbus->bank[3].or = CFG_OR3_PRELIM;
/* Program the MAMR. RFEN=0, OP=00, UWPL=1, AM=000, DS=01, G0CL=000,
GPL4=0, RLF=0001, WLF=0001, TLF=0001, MAD=000000
*/
lbus->mamr = 0x08404440;
upmconfig(0, UPMATable, sizeof(UPMATable) / sizeof(UPMATable[0]));
puts("UPMA: Configured for compact flash\n");
#endif
return 0;
}
/*
* Make sure the EEPROM has the HRCW correctly programmed.
* Make sure the RTC is correctly programmed.
*
* The MPC8349E-mITX can be configured to load the HRCW from
* EEPROM instead of flash. This is controlled via jumpers
* LGPL0, 1, and 3. Normally, these jumpers are set to 000 (all
* jumpered), but if they're set to 001 or 010, then the HRCW is
* read from the "I2C EEPROM".
*
* This function makes sure that the I2C EEPROM is programmed
* correctly.
*/
int misc_init_r(void)
{
int rc = 0;
#ifdef CONFIG_HARD_I2C
unsigned int orig_bus = i2c_get_bus_num();;
u8 i2c_data;
#ifdef CFG_I2C_RTC_ADDR
u8 ds1339_data[17];
#endif
#ifdef CFG_I2C_EEPROM_ADDR
static u8 eeprom_data[] = /* HRCW data */
{
0xaa, 0x55, 0xaa,
0x7c, 0x02, 0x40, 0x05, 0x04, 0x00, 0x00,
0x7c, 0x02, 0x41, 0xb4, 0x60, 0xa0, 0x00,
};
u8 data[sizeof(eeprom_data)];
#endif
printf("Board revision: ");
i2c_set_bus_num(1);
if (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
printf("%u.%u (PCF8475A)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
else if (i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
printf("%u.%u (PCF8475)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
else {
printf("Unknown\n");
rc = 1;
}
#ifdef CFG_I2C_EEPROM_ADDR
i2c_set_bus_num(0);
if (i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {
if (memcmp(data, eeprom_data, sizeof(data)) != 0) {
if (i2c_write
(CFG_I2C_EEPROM_ADDR, 0, 2, eeprom_data,
sizeof(eeprom_data)) != 0) {
puts("Failure writing the HRCW to EEPROM via I2C.\n");
rc = 1;
}
}
} else {
puts("Failure reading the HRCW from EEPROM via I2C.\n");
rc = 1;
}
#endif
#ifdef CFG_I2C_RTC_ADDR
i2c_set_bus_num(1);
if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data, sizeof(ds1339_data))
== 0) {
/* Work-around for MPC8349E-mITX bug #13601.
If the RTC does not contain valid register values, the DS1339
Linux driver will not work.
*/
/* Make sure status register bits 6-2 are zero */
ds1339_data[0x0f] &= ~0x7c;
/* Check for a valid day register value */
ds1339_data[0x03] &= ~0xf8;
if (ds1339_data[0x03] == 0) {
ds1339_data[0x03] = 1;
}
/* Check for a valid date register value */
ds1339_data[0x04] &= ~0xc0;
if ((ds1339_data[0x04] == 0) ||
((ds1339_data[0x04] & 0x0f) > 9) ||
(ds1339_data[0x04] >= 0x32)) {
ds1339_data[0x04] = 1;
}
/* Check for a valid month register value */
ds1339_data[0x05] &= ~0x60;
if ((ds1339_data[0x05] == 0) ||
((ds1339_data[0x05] & 0x0f) > 9) ||
((ds1339_data[0x05] >= 0x13)
&& (ds1339_data[0x05] <= 0x19))) {
ds1339_data[0x05] = 1;
}
/* Enable Oscillator and rate select */
ds1339_data[0x0e] = 0x1c;
/* Work-around for MPC8349E-mITX bug #13330.
Ensure that the RTC control register contains the value 0x1c.
This affects SATA performance.
*/
if (i2c_write
(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data,
sizeof(ds1339_data))) {
puts("Failure writing to the RTC via I2C.\n");
rc = 1;
}
} else {
puts("Failure reading from the RTC via I2C.\n");
rc = 1;
}
#endif
i2c_set_bus_num(orig_bus);
#endif
return rc;
}
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
#ifdef CONFIG_PCI
ft_pci_setup(blob, bd);
#endif
ft_cpu_setup(blob, bd);
p = ft_get_prop(blob, "/memory/reg", &len);
if (p != NULL) {
*p++ = cpu_to_be32(bd->bi_memstart);
*p = cpu_to_be32(bd->bi_memsize);
}
}
#endif

357
board/mpc8349itx/pci.c Normal file
View file

@ -0,0 +1,357 @@
/*
* Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#ifdef CONFIG_PCI
#include <asm/mmu.h>
#include <asm/global_data.h>
#include <pci.h>
#include <asm/mpc8349_pci.h>
#include <i2c.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
/* System RAM mapped to PCI space */
#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_mpc8349itx_config_table[] = {
{
PCI_ANY_ID,
PCI_ANY_ID,
PCI_ANY_ID,
PCI_ANY_ID,
PCI_IDSEL_NUMBER,
PCI_ANY_ID,
pci_cfgfunc_config_device,
{
PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}
},
{}
};
#endif
static struct pci_controller pci_hose[] = {
{
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc8349itx_config_table,
#endif
},
{
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc8349itx_config_table,
#endif
}
};
/**************************************************************************
* pci_init_board()
*
* NOTICE: PCI2 is not currently supported
*
*/
void pci_init_board(void)
{
volatile immap_t *immr;
volatile clk83xx_t *clk;
volatile law83xx_t *pci_law;
volatile pot83xx_t *pci_pot;
volatile pcictrl83xx_t *pci_ctrl;
volatile pciconf83xx_t *pci_conf;
u8 reg8;
u16 reg16;
u32 reg32;
u32 dev;
struct pci_controller *hose;
immr = (immap_t *) CFG_IMMR;
clk = (clk83xx_t *) & immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
pci_conf = immr->pci_conf;
hose = &pci_hose[0];
/*
* Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
*/
reg32 = clk->occr;
udelay(2000);
#ifdef CONFIG_HARD_I2C
i2c_set_bus_num(1);
/* Read the PCI_M66EN jumper setting */
if ((i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0) ||
(i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0)) {
if (reg8 & I2C_8574_PCI66)
clk->occr = 0xff000000; /* 66 MHz PCI */
else
clk->occr = 0xff600001; /* 33 MHz PCI */
} else {
clk->occr = 0xff600001; /* 33 MHz PCI */
}
#else
clk->occr = 0xff000000; /* 66 MHz PCI */
#endif
udelay(2000);
/*
* Release PCI RST Output signal
*/
pci_ctrl[0].gcr = 0;
udelay(2000);
pci_ctrl[0].gcr = 1;
#ifdef CONFIG_MPC83XX_PCI2
pci_ctrl[1].gcr = 0;
udelay(2000);
pci_ctrl[1].gcr = 1;
#endif
/* We need to wait at least a 1sec based on PCI specs */
{
int i;
for (i = 0; i < 1000; i++)
udelay(1000);
}
/*
* Configure PCI Local Access Windows
*/
pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_32M;
/*
* Configure PCI Outbound Translation Windows
*/
/* PCI1 mem space - prefetch */
pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | POCMR_CM_256M;
/* PCI1 IO space */
pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[1].pocmr = POCMR_EN | POCMR_IO | POCMR_CM_16M;
/* PCI1 mmio - non-prefetch mem space */
pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[2].pocmr = POCMR_EN | POCMR_CM_256M;
/*
* Configure PCI Inbound Translation Windows
*/
/* we need RAM mapped to PCI space for the devices to
* access main memory */
pci_ctrl[0].pitar1 = 0x0;
pci_ctrl[0].pibar1 = 0x0;
pci_ctrl[0].piebar1 = 0x0;
pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
hose->first_busno = 0;
hose->last_busno = 0xff;
/* PCI memory prefetch space */
pci_set_region(hose->regions + 0,
CFG_PCI1_MEM_BASE,
CFG_PCI1_MEM_PHYS,
CFG_PCI1_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
/* PCI memory space */
pci_set_region(hose->regions + 1,
CFG_PCI1_MMIO_BASE,
CFG_PCI1_MMIO_PHYS, CFG_PCI1_MMIO_SIZE, PCI_REGION_MEM);
/* PCI IO space */
pci_set_region(hose->regions + 2,
CFG_PCI1_IO_BASE,
CFG_PCI1_IO_PHYS, CFG_PCI1_IO_SIZE, PCI_REGION_IO);
/* System memory space */
pci_set_region(hose->regions + 3,
CONFIG_PCI_SYS_MEM_BUS,
CONFIG_PCI_SYS_MEM_PHYS,
gd->ram_size, PCI_REGION_MEM | PCI_REGION_MEMORY);
hose->region_count = 4;
pci_setup_indirect(hose,
(CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
pci_register_hose(hose);
/*
* Write to Command register
*/
reg16 = 0xff;
dev = PCI_BDF(hose->first_busno, 0, 0);
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
/*
* Hose scan.
*/
hose->last_busno = pci_hose_scan(hose);
#ifdef CONFIG_MPC83XX_PCI2
hose = &pci_hose[1];
/*
* Configure PCI Outbound Translation Windows
*/
/* PCI2 mem space - prefetch */
pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | POCMR_CM_256M;
/* PCI2 IO space */
pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | POCMR_CM_16M;
/* PCI2 mmio - non-prefetch mem space */
pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_CM_256M;
/*
* Configure PCI Inbound Translation Windows
*/
/* we need RAM mapped to PCI space for the devices to
* access main memory */
pci_ctrl[1].pitar1 = 0x0;
pci_ctrl[1].pibar1 = 0x0;
pci_ctrl[1].piebar1 = 0x0;
pci_ctrl[1].piwar1 =
PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
(__ilog2(gd->ram_size) - 1);
hose->first_busno = pci_hose[0].last_busno + 1;
hose->last_busno = 0xff;
/* PCI memory prefetch space */
pci_set_region(hose->regions + 0,
CFG_PCI2_MEM_BASE,
CFG_PCI2_MEM_PHYS,
CFG_PCI2_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
/* PCI memory space */
pci_set_region(hose->regions + 1,
CFG_PCI2_MMIO_BASE,
CFG_PCI2_MMIO_PHYS, CFG_PCI2_MMIO_SIZE, PCI_REGION_MEM);
/* PCI IO space */
pci_set_region(hose->regions + 2,
CFG_PCI2_IO_BASE,
CFG_PCI2_IO_PHYS, CFG_PCI2_IO_SIZE, PCI_REGION_IO);
/* System memory space */
pci_set_region(hose->regions + 3,
CONFIG_PCI_SYS_MEM_BUS,
CONFIG_PCI_SYS_MEM_PHYS,
gd->ram_size, PCI_REGION_MEM | PCI_REGION_MEMORY);
hose->region_count = 4;
pci_setup_indirect(hose,
(CFG_IMMR + 0x8380), (CFG_IMMR + 0x8384));
pci_register_hose(hose);
/*
* Write to Command register
*/
reg16 = 0xff;
dev = PCI_BDF(hose->first_busno, 0, 0);
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
/*
* Hose scan.
*/
hose->last_busno = pci_hose_scan(hose);
#endif
}
#endif /* CONFIG_PCI */
#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[0].first_busno;
p[1] = pci_hose[0].last_busno;
}
#ifdef CONFIG_MPC83XX_PCI2
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
if (p != NULL) {
p[0] = pci_hose[1].first_busno;
p[1] = pci_hose[1].last_busno;
}
#endif
}
#endif /* CONFIG_OF_FLAT_TREE */

120
board/mpc8349itx/u-boot.lds Normal file
View file

@ -0,0 +1,120 @@
/*
* Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
*
* 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)
SECTIONS
{
/* 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/mpc83xx/start.o (.text)
*(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_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(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}
ENTRY(_start)

View file

@ -0,0 +1,50 @@
#
# (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
#
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS := $(BOARD).o pci.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS)
$(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
#########################################################################

View file

@ -0,0 +1,28 @@
#
# (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
#
#
# MPC8360EMDS
#
TEXT_BASE = 0xFE000000

View file

@ -0,0 +1,657 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on board/mpc8349emds/mpc8349emds.c
*
* 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.
*/
#include <common.h>
#include <ioports.h>
#include <mpc83xx.h>
#include <i2c.h>
#include <spd.h>
#include <miiphy.h>
#include <command.h>
#if defined(CONFIG_PCI)
#include <pci.h>
#endif
#if defined(CONFIG_SPD_EEPROM)
#include <spd_sdram.h>
#else
#include <asm/mmu.h>
#endif
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
const qe_iop_conf_t qe_iop_conf_tab[] = {
/* GETH1 */
{0, 3, 1, 0, 1}, /* TxD0 */
{0, 4, 1, 0, 1}, /* TxD1 */
{0, 5, 1, 0, 1}, /* TxD2 */
{0, 6, 1, 0, 1}, /* TxD3 */
{1, 6, 1, 0, 3}, /* TxD4 */
{1, 7, 1, 0, 1}, /* TxD5 */
{1, 9, 1, 0, 2}, /* TxD6 */
{1, 10, 1, 0, 2}, /* TxD7 */
{0, 9, 2, 0, 1}, /* RxD0 */
{0, 10, 2, 0, 1}, /* RxD1 */
{0, 11, 2, 0, 1}, /* RxD2 */
{0, 12, 2, 0, 1}, /* RxD3 */
{0, 13, 2, 0, 1}, /* RxD4 */
{1, 1, 2, 0, 2}, /* RxD5 */
{1, 0, 2, 0, 2}, /* RxD6 */
{1, 4, 2, 0, 2}, /* RxD7 */
{0, 7, 1, 0, 1}, /* TX_EN */
{0, 8, 1, 0, 1}, /* TX_ER */
{0, 15, 2, 0, 1}, /* RX_DV */
{0, 16, 2, 0, 1}, /* RX_ER */
{0, 0, 2, 0, 1}, /* RX_CLK */
{2, 9, 1, 0, 3}, /* GTX_CLK - CLK10 */
{2, 8, 2, 0, 1}, /* GTX125 - CLK9 */
/* GETH2 */
{0, 17, 1, 0, 1}, /* TxD0 */
{0, 18, 1, 0, 1}, /* TxD1 */
{0, 19, 1, 0, 1}, /* TxD2 */
{0, 20, 1, 0, 1}, /* TxD3 */
{1, 2, 1, 0, 1}, /* TxD4 */
{1, 3, 1, 0, 2}, /* TxD5 */
{1, 5, 1, 0, 3}, /* TxD6 */
{1, 8, 1, 0, 3}, /* TxD7 */
{0, 23, 2, 0, 1}, /* RxD0 */
{0, 24, 2, 0, 1}, /* RxD1 */
{0, 25, 2, 0, 1}, /* RxD2 */
{0, 26, 2, 0, 1}, /* RxD3 */
{0, 27, 2, 0, 1}, /* RxD4 */
{1, 12, 2, 0, 2}, /* RxD5 */
{1, 13, 2, 0, 3}, /* RxD6 */
{1, 11, 2, 0, 2}, /* RxD7 */
{0, 21, 1, 0, 1}, /* TX_EN */
{0, 22, 1, 0, 1}, /* TX_ER */
{0, 29, 2, 0, 1}, /* RX_DV */
{0, 30, 2, 0, 1}, /* RX_ER */
{0, 31, 2, 0, 1}, /* RX_CLK */
{2, 2, 1, 0, 2}, /* GTX_CLK = CLK10 */
{2, 3, 2, 0, 1}, /* GTX125 - CLK4 */
{0, 1, 3, 0, 2}, /* MDIO */
{0, 2, 1, 0, 1}, /* MDC */
{0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */
};
int board_early_init_f(void)
{
volatile u8 *bcsr = (volatile u8 *)CFG_BCSR;
/* Enable flash write */
bcsr[0xa] &= ~0x04;
return 0;
}
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif
int fixed_sdram(void);
void sdram_init(void);
long int initdram(int board_type)
{
volatile immap_t *im = (immap_t *) CFG_IMMR;
u32 msize = 0;
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
return -1;
/* DDR SDRAM - Main SODIMM */
im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
#if defined(CONFIG_SPD_EEPROM)
msize = spd_sdram();
#else
msize = fixed_sdram();
#endif
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
/*
* Initialize DDR ECC byte
*/
ddr_enable_ecc(msize * 1024 * 1024);
#endif
/*
* Initialize SDRAM if it is on local bus.
*/
sdram_init();
puts(" DDR RAM: ");
/* return total bus SDRAM size(bytes) -- DDR */
return (msize * 1024 * 1024);
}
#if !defined(CONFIG_SPD_EEPROM)
/*************************************************************************
* fixed sdram init -- doesn't use serial presence detect.
************************************************************************/
int fixed_sdram(void)
{
volatile immap_t *im = (immap_t *) CFG_IMMR;
u32 msize = 0;
u32 ddr_size;
u32 ddr_size_log2;
msize = CFG_DDR_SIZE;
for (ddr_size = msize << 20, ddr_size_log2 = 0;
(ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
if (ddr_size & 1) {
return -1;
}
}
im->sysconf.ddrlaw[0].ar =
LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
#if (CFG_DDR_SIZE != 256)
#warning Currenly any ddr size other than 256 is not supported
#endif
im->ddr.csbnds[0].csbnds = 0x00000007;
im->ddr.csbnds[1].csbnds = 0x0008000f;
im->ddr.cs_config[0] = CFG_DDR_CONFIG;
im->ddr.cs_config[1] = CFG_DDR_CONFIG;
im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
im->ddr.sdram_cfg = CFG_DDR_CONTROL;
im->ddr.sdram_mode = CFG_DDR_MODE;
im->ddr.sdram_interval = CFG_DDR_INTERVAL;
udelay(200);
im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
return msize;
}
#endif /*!CFG_SPD_EEPROM */
int checkboard(void)
{
puts("Board: Freescale MPC8360EMDS\n");
return 0;
}
/*
* if MPC8360EMDS is soldered with SDRAM
*/
#if defined(CFG_BR2_PRELIM) \
&& defined(CFG_OR2_PRELIM) \
&& defined(CFG_LBLAWBAR2_PRELIM) \
&& defined(CFG_LBLAWAR2_PRELIM)
/*
* Initialize SDRAM memory on the Local Bus.
*/
void sdram_init(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile lbus83xx_t *lbc = &immap->lbus;
uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE;
puts("\n SDRAM on Local Bus: ");
print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
/*
* Setup SDRAM Base and Option Registers, already done in cpu_init.c
*/
/*setup mtrpt, lsrt and lbcr for LB bus */
lbc->lbcr = CFG_LBC_LBCR;
lbc->mrtpr = CFG_LBC_MRTPR;
lbc->lsrt = CFG_LBC_LSRT;
asm("sync");
/*
* Configure the SDRAM controller Machine Mode Register.
*/
lbc->lsdmr = CFG_LBC_LSDMR_5; /* Normal Operation */
lbc->lsdmr = CFG_LBC_LSDMR_1; /* Precharge All Banks */
asm("sync");
*sdram_addr = 0xff;
udelay(100);
/*
* We need do 8 times auto refresh operation.
*/
lbc->lsdmr = CFG_LBC_LSDMR_2;
asm("sync");
*sdram_addr = 0xff; /* 1 times */
udelay(100);
*sdram_addr = 0xff; /* 2 times */
udelay(100);
*sdram_addr = 0xff; /* 3 times */
udelay(100);
*sdram_addr = 0xff; /* 4 times */
udelay(100);
*sdram_addr = 0xff; /* 5 times */
udelay(100);
*sdram_addr = 0xff; /* 6 times */
udelay(100);
*sdram_addr = 0xff; /* 7 times */
udelay(100);
*sdram_addr = 0xff; /* 8 times */
udelay(100);
/* Mode register write operation */
lbc->lsdmr = CFG_LBC_LSDMR_4;
asm("sync");
*(sdram_addr + 0xcc) = 0xff;
udelay(100);
/* Normal operation */
lbc->lsdmr = CFG_LBC_LSDMR_5 | 0x40000000;
asm("sync");
*sdram_addr = 0xff;
udelay(100);
}
#else
void sdram_init(void)
{
puts("SDRAM on Local Bus is NOT available!\n");
}
#endif
#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
/*
* ECC user commands
*/
void ecc_print_status(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ddr83xx_t *ddr = &immap->ddr;
printf("\nECC mode: %s\n\n",
(ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
/* Interrupts */
printf("Memory Error Interrupt Enable:\n");
printf(" Multiple-Bit Error Interrupt Enable: %d\n",
(ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
printf(" Single-Bit Error Interrupt Enable: %d\n",
(ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
printf(" Memory Select Error Interrupt Enable: %d\n\n",
(ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
/* Error disable */
printf("Memory Error Disable:\n");
printf(" Multiple-Bit Error Disable: %d\n",
(ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
printf(" Sinle-Bit Error Disable: %d\n",
(ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
printf(" Memory Select Error Disable: %d\n\n",
(ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
/* Error injection */
printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
ddr->data_err_inject_hi, ddr->data_err_inject_lo);
printf("Memory Data Path Error Injection Mask ECC:\n");
printf(" ECC Mirror Byte: %d\n",
(ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
printf(" ECC Injection Enable: %d\n",
(ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
printf(" ECC Error Injection Mask: 0x%02x\n\n",
ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
/* SBE counter/threshold */
printf("Memory Single-Bit Error Management (0..255):\n");
printf(" Single-Bit Error Threshold: %d\n",
(ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
printf(" Single-Bit Error Counter: %d\n\n",
(ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
/* Error detect */
printf("Memory Error Detect:\n");
printf(" Multiple Memory Errors: %d\n",
(ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
printf(" Multiple-Bit Error: %d\n",
(ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
printf(" Single-Bit Error: %d\n",
(ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
printf(" Memory Select Error: %d\n\n",
(ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
/* Capture data */
printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
ddr->capture_data_hi, ddr->capture_data_lo);
printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
ddr->capture_ecc & CAPTURE_ECC_ECE);
printf("Memory Error Attributes Capture:\n");
printf(" Data Beat Number: %d\n",
(ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
ECC_CAPT_ATTR_BNUM_SHIFT);
printf(" Transaction Size: %d\n",
(ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
ECC_CAPT_ATTR_TSIZ_SHIFT);
printf(" Transaction Source: %d\n",
(ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
ECC_CAPT_ATTR_TSRC_SHIFT);
printf(" Transaction Type: %d\n",
(ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
ECC_CAPT_ATTR_TTYP_SHIFT);
printf(" Error Information Valid: %d\n\n",
ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
}
int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile ddr83xx_t *ddr = &immap->ddr;
volatile u32 val;
u64 *addr;
u32 count;
register u64 *i;
u32 ret[2];
u32 pattern[2];
u32 writeback[2];
/* The pattern is written into memory to generate error */
pattern[0] = 0xfedcba98UL;
pattern[1] = 0x76543210UL;
/* After injecting error, re-initialize the memory with the value */
writeback[0] = 0x01234567UL;
writeback[1] = 0x89abcdefUL;
if (argc > 4) {
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
if (argc == 2) {
if (strcmp(argv[1], "status") == 0) {
ecc_print_status();
return 0;
} else if (strcmp(argv[1], "captureclear") == 0) {
ddr->capture_address = 0;
ddr->capture_data_hi = 0;
ddr->capture_data_lo = 0;
ddr->capture_ecc = 0;
ddr->capture_attributes = 0;
return 0;
}
}
if (argc == 3) {
if (strcmp(argv[1], "sbecnt") == 0) {
val = simple_strtoul(argv[2], NULL, 10);
if (val > 255) {
printf("Incorrect Counter value, "
"should be 0..255\n");
return 1;
}
val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
ddr->err_sbe = val;
return 0;
} else if (strcmp(argv[1], "sbethr") == 0) {
val = simple_strtoul(argv[2], NULL, 10);
if (val > 255) {
printf("Incorrect Counter value, "
"should be 0..255\n");
return 1;
}
val = (val << ECC_ERROR_MAN_SBET_SHIFT);
val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
ddr->err_sbe = val;
return 0;
} else if (strcmp(argv[1], "errdisable") == 0) {
val = ddr->err_disable;
if (strcmp(argv[2], "+sbe") == 0) {
val |= ECC_ERROR_DISABLE_SBED;
} else if (strcmp(argv[2], "+mbe") == 0) {
val |= ECC_ERROR_DISABLE_MBED;
} else if (strcmp(argv[2], "+mse") == 0) {
val |= ECC_ERROR_DISABLE_MSED;
} else if (strcmp(argv[2], "+all") == 0) {
val |= (ECC_ERROR_DISABLE_SBED |
ECC_ERROR_DISABLE_MBED |
ECC_ERROR_DISABLE_MSED);
} else if (strcmp(argv[2], "-sbe") == 0) {
val &= ~ECC_ERROR_DISABLE_SBED;
} else if (strcmp(argv[2], "-mbe") == 0) {
val &= ~ECC_ERROR_DISABLE_MBED;
} else if (strcmp(argv[2], "-mse") == 0) {
val &= ~ECC_ERROR_DISABLE_MSED;
} else if (strcmp(argv[2], "-all") == 0) {
val &= ~(ECC_ERROR_DISABLE_SBED |
ECC_ERROR_DISABLE_MBED |
ECC_ERROR_DISABLE_MSED);
} else {
printf("Incorrect err_disable field\n");
return 1;
}
ddr->err_disable = val;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
return 0;
} else if (strcmp(argv[1], "errdetectclr") == 0) {
val = ddr->err_detect;
if (strcmp(argv[2], "mme") == 0) {
val |= ECC_ERROR_DETECT_MME;
} else if (strcmp(argv[2], "sbe") == 0) {
val |= ECC_ERROR_DETECT_SBE;
} else if (strcmp(argv[2], "mbe") == 0) {
val |= ECC_ERROR_DETECT_MBE;
} else if (strcmp(argv[2], "mse") == 0) {
val |= ECC_ERROR_DETECT_MSE;
} else if (strcmp(argv[2], "all") == 0) {
val |= (ECC_ERROR_DETECT_MME |
ECC_ERROR_DETECT_MBE |
ECC_ERROR_DETECT_SBE |
ECC_ERROR_DETECT_MSE);
} else {
printf("Incorrect err_detect field\n");
return 1;
}
ddr->err_detect = val;
return 0;
} else if (strcmp(argv[1], "injectdatahi") == 0) {
val = simple_strtoul(argv[2], NULL, 16);
ddr->data_err_inject_hi = val;
return 0;
} else if (strcmp(argv[1], "injectdatalo") == 0) {
val = simple_strtoul(argv[2], NULL, 16);
ddr->data_err_inject_lo = val;
return 0;
} else if (strcmp(argv[1], "injectecc") == 0) {
val = simple_strtoul(argv[2], NULL, 16);
if (val > 0xff) {
printf("Incorrect ECC inject mask, "
"should be 0x00..0xff\n");
return 1;
}
val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
ddr->ecc_err_inject = val;
return 0;
} else if (strcmp(argv[1], "inject") == 0) {
val = ddr->ecc_err_inject;
if (strcmp(argv[2], "en") == 0)
val |= ECC_ERR_INJECT_EIEN;
else if (strcmp(argv[2], "dis") == 0)
val &= ~ECC_ERR_INJECT_EIEN;
else
printf("Incorrect command\n");
ddr->ecc_err_inject = val;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
return 0;
} else if (strcmp(argv[1], "mirror") == 0) {
val = ddr->ecc_err_inject;
if (strcmp(argv[2], "en") == 0)
val |= ECC_ERR_INJECT_EMB;
else if (strcmp(argv[2], "dis") == 0)
val &= ~ECC_ERR_INJECT_EMB;
else
printf("Incorrect command\n");
ddr->ecc_err_inject = val;
return 0;
}
}
if (argc == 4) {
if (strcmp(argv[1], "testdw") == 0) {
addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
count = simple_strtoul(argv[3], NULL, 16);
if ((u32) addr % 8) {
printf("Address not alligned on "
"double word boundary\n");
return 1;
}
disable_interrupts();
for (i = addr; i < addr + count; i++) {
/* enable injects */
ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
/* write memory location injecting errors */
ppcDWstore((u32 *) i, pattern);
__asm__ __volatile__("sync");
/* disable injects */
ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
/* read data, this generates ECC error */
ppcDWload((u32 *) i, ret);
__asm__ __volatile__("sync");
/* re-initialize memory, double word write the location again,
* generates new ECC code this time */
ppcDWstore((u32 *) i, writeback);
__asm__ __volatile__("sync");
}
enable_interrupts();
return 0;
}
if (strcmp(argv[1], "testword") == 0) {
addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
count = simple_strtoul(argv[3], NULL, 16);
if ((u32) addr % 8) {
printf("Address not alligned on "
"double word boundary\n");
return 1;
}
disable_interrupts();
for (i = addr; i < addr + count; i++) {
/* enable injects */
ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
/* write memory location injecting errors */
*(u32 *) i = 0xfedcba98UL;
__asm__ __volatile__("sync");
/* sub double word write,
* bus will read-modify-write,
* generates ECC error */
*((u32 *) i + 1) = 0x76543210UL;
__asm__ __volatile__("sync");
/* disable injects */
ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
__asm__ __volatile__("sync");
__asm__ __volatile__("isync");
/* re-initialize memory,
* double word write the location again,
* generates new ECC code this time */
ppcDWstore((u32 *) i, writeback);
__asm__ __volatile__("sync");
}
enable_interrupts();
return 0;
}
}
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
}
U_BOOT_CMD(ecc, 4, 0, do_ecc,
"ecc - support for DDR ECC features\n",
"status - print out status info\n"
"ecc captureclear - clear capture regs data\n"
"ecc sbecnt <val> - set Single-Bit Error counter\n"
"ecc sbethr <val> - set Single-Bit Threshold\n"
"ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n"
" [-|+]sbe - Single-Bit Error\n"
" [-|+]mbe - Multiple-Bit Error\n"
" [-|+]mse - Memory Select Error\n"
" [-|+]all - all errors\n"
"ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
" mme - Multiple Memory Errors\n"
" sbe - Single-Bit Error\n"
" mbe - Multiple-Bit Error\n"
" mse - Memory Select Error\n"
" all - all errors\n"
"ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n"
"ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n"
"ecc injectecc <ecc> - set ECC Error Injection Mask\n"
"ecc inject <en|dis> - enable/disable error injection\n"
"ecc mirror <en|dis> - enable/disable mirror byte\n"
"ecc testdw <addr> <cnt> - test mem region with double word access:\n"
" - enables injects\n"
" - writes pattern injecting errors with double word access\n"
" - disables injects\n"
" - reads pattern back with double word access, generates error\n"
" - re-inits memory\n"
"ecc testword <addr> <cnt> - test mem region with word access:\n"
" - enables injects\n"
" - writes pattern injecting errors with word access\n"
" - writes pattern with word access, generates error\n"
" - disables injects\n" " - re-inits memory");
#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
#ifdef CONFIG_PCI
ft_pci_setup(blob, bd);
#endif
ft_cpu_setup(blob, bd);
p = ft_get_prop(blob, "/memory/reg", &len);
if (p != NULL) {
*p++ = cpu_to_be32(bd->bi_memstart);
*p = cpu_to_be32(bd->bi_memsize);
}
}
#endif

313
board/mpc8360emds/pci.c Normal file
View file

@ -0,0 +1,313 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* 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.
*/
/*
* PCI Configuration space access support for MPC83xx PCI Bridge
*/
#include <asm/mmu.h>
#include <asm/io.h>
#include <common.h>
#include <pci.h>
#include <i2c.h>
#include <asm/fsl_i2c.h>
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_PCI)
#define PCI_FUNCTION_CONFIG 0x44
#define PCI_FUNCTION_CFG_LOCK 0x20
/*
* Initialize PCI Devices, report devices found
*/
#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_mpc83xxemds_config_table[] = {
{
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
pci_cfgfunc_config_device,
{PCI_ENET0_IOADDR,
PCI_ENET0_MEMADDR,
PCI_COMMON_MEMORY | PCI_COMMAND_MASTER}
},
{}
}
#endif
static struct pci_controller hose[] = {
{
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc83xxemds_config_table,
#endif
},
};
/**********************************************************************
* pci_init_board()
*********************************************************************/
void pci_init_board(void)
#ifdef CONFIG_PCISLAVE
{
u16 reg16;
volatile immap_t *immr;
volatile law83xx_t *pci_law;
volatile pot83xx_t *pci_pot;
volatile pcictrl83xx_t *pci_ctrl;
volatile pciconf83xx_t *pci_conf;
immr = (immap_t *) CFG_IMMR;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
pci_conf = immr->pci_conf;
/*
* Configure PCI Inbound Translation Windows
*/
pci_ctrl[0].pitar0 = 0x0;
pci_ctrl[0].pibar0 = 0x0;
pci_ctrl[0].piwar0 = PIWAR_EN | PIWAR_RTT_SNOOP |
PIWAR_WTT_SNOOP | PIWAR_IWS_4K;
pci_ctrl[0].pitar1 = 0x0;
pci_ctrl[0].pibar1 = 0x0;
pci_ctrl[0].piebar1 = 0x0;
pci_ctrl[0].piwar1 &= ~PIWAR_EN;
pci_ctrl[0].pitar2 = 0x0;
pci_ctrl[0].pibar2 = 0x0;
pci_ctrl[0].piebar2 = 0x0;
pci_ctrl[0].piwar2 &= ~PIWAR_EN;
hose[0].first_busno = 0;
hose[0].last_busno = 0xff;
pci_setup_indirect(&hose[0],
(CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
reg16 = 0xff;
pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_STATUS, 0xffff);
pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
PCI_LATENCY_TIMER, 0x80);
/*
* Unlock configuration lock in PCI function configuration register.
*/
pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_FUNCTION_CONFIG, &reg16);
reg16 &= ~(PCI_FUNCTION_CFG_LOCK);
pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
PCI_FUNCTION_CONFIG, reg16);
printf("Enabled PCI 32bit Agent Mode\n");
}
#else
{
volatile immap_t *immr;
volatile clk83xx_t *clk;
volatile law83xx_t *pci_law;
volatile pot83xx_t *pci_pot;
volatile pcictrl83xx_t *pci_ctrl;
volatile pciconf83xx_t *pci_conf;
u8 val8, orig_i2c_bus;
u16 reg16;
u32 val32;
u32 dev;
immr = (immap_t *) CFG_IMMR;
clk = (clk83xx_t *) & immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
pci_conf = immr->pci_conf;
/*
* Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
*/
val32 = clk->occr;
udelay(2000);
#if defined(PCI_66M)
clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
printf("PCI clock is 66MHz\n");
#elif defined(PCI_33M)
clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |
OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 | OCCR_PCICR;
printf("PCI clock is 33MHz\n");
#else
clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
printf("PCI clock is 66MHz\n");
#endif
udelay(2000);
/*
* Configure PCI Local Access Windows
*/
pci_law[0].bar = CFG_PCI_MEM_PHYS & LAWBAR_BAR;
pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
pci_law[1].bar = CFG_PCI_IO_PHYS & LAWBAR_BAR;
pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_1M;
/*
* Configure PCI Outbound Translation Windows
*/
/* PCI mem space - prefetch */
pci_pot[0].potar = (CFG_PCI_MEM_BASE >> 12) & POTAR_TA_MASK;
pci_pot[0].pobar = (CFG_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[0].pocmr =
POCMR_EN | POCMR_SE | (POCMR_CM_256M & POCMR_CM_MASK);
/* PCI mmio - non-prefetch mem space */
pci_pot[1].potar = (CFG_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[1].pobar = (CFG_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[1].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
/* PCI IO space */
pci_pot[2].potar = (CFG_PCI_IO_BASE >> 12) & POTAR_TA_MASK;
pci_pot[2].pobar = (CFG_PCI_IO_PHYS >> 12) & POBAR_BA_MASK;
pci_pot[2].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
/*
* Configure PCI Inbound Translation Windows
*/
pci_ctrl[0].pitar1 = (CFG_PCI_SLV_MEM_LOCAL >> 12) & PITAR_TA_MASK;
pci_ctrl[0].pibar1 = (CFG_PCI_SLV_MEM_BUS >> 12) & PIBAR_MASK;
pci_ctrl[0].piebar1 = 0x0;
pci_ctrl[0].piwar1 =
PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
PIWAR_IWS_2G;
/*
* Assign PIB PMC slot to desired PCI bus
*/
/* Switch temporarily to I2C bus #2 */
orig_i2c_bus = i2c_get_bus_num();
i2c_set_bus_num(1);
val8 = 0;
i2c_write(0x23, 0x6, 1, &val8, 1);
i2c_write(0x23, 0x7, 1, &val8, 1);
val8 = 0xff;
i2c_write(0x23, 0x2, 1, &val8, 1);
i2c_write(0x23, 0x3, 1, &val8, 1);
val8 = 0;
i2c_write(0x26, 0x6, 1, &val8, 1);
val8 = 0x34;
i2c_write(0x26, 0x7, 1, &val8, 1);
val8 = 0xf3; /*PMC1, PMC2, PMC3 slot to PCI bus */
i2c_write(0x26, 0x2, 1, &val8, 1);
val8 = 0xff;
i2c_write(0x26, 0x3, 1, &val8, 1);
val8 = 0;
i2c_write(0x27, 0x6, 1, &val8, 1);
i2c_write(0x27, 0x7, 1, &val8, 1);
val8 = 0xff;
i2c_write(0x27, 0x2, 1, &val8, 1);
val8 = 0xef;
i2c_write(0x27, 0x3, 1, &val8, 1);
asm("eieio");
/* Reset to original I2C bus */
i2c_set_bus_num(orig_i2c_bus);
/*
* Release PCI RST Output signal
*/
udelay(2000);
pci_ctrl[0].gcr = 1;
udelay(2000);
hose[0].first_busno = 0;
hose[0].last_busno = 0xff;
/* PCI memory prefetch space */
pci_set_region(hose[0].regions + 0,
CFG_PCI_MEM_BASE,
CFG_PCI_MEM_PHYS,
CFG_PCI_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
/* PCI memory space */
pci_set_region(hose[0].regions + 1,
CFG_PCI_MMIO_BASE,
CFG_PCI_MMIO_PHYS, CFG_PCI_MMIO_SIZE, PCI_REGION_MEM);
/* PCI IO space */
pci_set_region(hose[0].regions + 2,
CFG_PCI_IO_BASE,
CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
/* System memory space */
pci_set_region(hose[0].regions + 3,
CFG_PCI_SLV_MEM_LOCAL,
CFG_PCI_SLV_MEM_BUS,
CFG_PCI_SLV_MEM_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
hose[0].region_count = 4;
pci_setup_indirect(&hose[0],
(CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
pci_register_hose(hose);
/*
* Write command register
*/
reg16 = 0xff;
dev = PCI_BDF(0, 0, 0);
pci_hose_read_config_word(&hose[0], dev, PCI_COMMAND, &reg16);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
pci_hose_write_config_word(&hose[0], dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
*/
pci_hose_write_config_word(&hose[0], dev, PCI_STATUS, 0xffff);
pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80);
pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08);
printf("PCI 32bit bus on PMC1 & PMC2 & PMC3\n");
/*
* Hose scan.
*/
hose->last_busno = pci_hose_scan(hose);
}
#endif /* CONFIG_PCISLAVE */
#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
if (p != NULL) {
p[0] = hose[0].first_busno;
p[1] = hose[0].last_busno;
}
}
#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */

View file

@ -0,0 +1,123 @@
/*
* (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
*/
OUTPUT_ARCH(powerpc)
SECTIONS
{
/* 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/mpc83xx/start.o (.text)
*(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
*(.eh_frame)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_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(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}
ENTRY(_start)

View file

@ -0,0 +1,51 @@
#
# (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
#
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS = $(BOARD).o fpga.o nand.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(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
#########################################################################

328
board/prodrive/alpr/alpr.c Normal file
View file

@ -0,0 +1,328 @@
/*
* (C) Copyright 2006
* 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 <common.h>
#include <asm/processor.h>
#include <spd_sdram.h>
#include <ppc4xx_enet.h>
#include <miiphy.h>
DECLARE_GLOBAL_DATA_PTR;
extern int alpr_fpga_init(void);
int board_early_init_f (void)
{
/*-------------------------------------------------------------------------
* Initialize EBC CONFIG
*-------------------------------------------------------------------------*/
mtebc(xbcfg, EBC_CFG_LE_UNLOCK |
EBC_CFG_PTD_DISABLE | EBC_CFG_RTC_64PERCLK |
EBC_CFG_ATC_PREVIOUS | EBC_CFG_DTC_PREVIOUS |
EBC_CFG_CTC_PREVIOUS | EBC_CFG_EMC_NONDEFAULT |
EBC_CFG_PME_DISABLE | EBC_CFG_PR_32);
/*--------------------------------------------------------------------
* Setup the interrupt controller polarities, triggers, etc.
*-------------------------------------------------------------------*/
mtdcr (uic0sr, 0xffffffff); /* clear all */
mtdcr (uic0er, 0x00000000); /* disable all */
mtdcr (uic0cr, 0x00000009); /* SMI & UIC1 crit are critical */
mtdcr (uic0pr, 0xfffffe03); /* per manual */
mtdcr (uic0tr, 0x01c00000); /* per manual */
mtdcr (uic0vr, 0x00000001); /* int31 highest, base=0x000 */
mtdcr (uic0sr, 0xffffffff); /* clear all */
mtdcr (uic1sr, 0xffffffff); /* clear all */
mtdcr (uic1er, 0x00000000); /* disable all */
mtdcr (uic1cr, 0x00000000); /* all non-critical */
mtdcr (uic1pr, 0xffffe0ff); /* per ref-board manual */
mtdcr (uic1tr, 0x00ffc000); /* per ref-board manual */
mtdcr (uic1vr, 0x00000001); /* int31 highest, base=0x000 */
mtdcr (uic1sr, 0xffffffff); /* clear all */
mtdcr (uic2sr, 0xffffffff); /* clear all */
mtdcr (uic2er, 0x00000000); /* disable all */
mtdcr (uic2cr, 0x00000000); /* all non-critical */
mtdcr (uic2pr, 0xffffffff); /* per ref-board manual */
mtdcr (uic2tr, 0x00ff8c0f); /* per ref-board manual */
mtdcr (uic2vr, 0x00000001); /* int31 highest, base=0x000 */
mtdcr (uic2sr, 0xffffffff); /* clear all */
mtdcr (uicb0sr, 0xfc000000); /* clear all */
mtdcr (uicb0er, 0x00000000); /* disable all */
mtdcr (uicb0cr, 0x00000000); /* all non-critical */
mtdcr (uicb0pr, 0xfc000000); /* */
mtdcr (uicb0tr, 0x00000000); /* */
mtdcr (uicb0vr, 0x00000001); /* */
/* Setup GPIO/IRQ multiplexing */
mtsdr(sdr_pfc0, 0x01a03e00);
return 0;
}
int last_stage_init(void)
{
unsigned short reg;
/*
* Configure LED's of both Marvell 88E1111 PHY's
*
* This has to be done after the 4xx ethernet driver is loaded,
* so "last_stage_init()" is the right place.
*/
miiphy_read("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, &reg);
reg |= 0x0001;
miiphy_write("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, reg);
miiphy_read("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, &reg);
reg |= 0x0001;
miiphy_write("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, reg);
return 0;
}
static int board_rev(void)
{
int rev;
u32 pfc0;
/* Setup GPIO14 & 15 as GPIO */
mfsdr(sdr_pfc0, pfc0);
pfc0 |= CFG_GPIO_REV0 | CFG_GPIO_REV1;
mtsdr(sdr_pfc0, pfc0);
/* Setup as input */
out32(GPIO0_TCR, in32(GPIO0_TCR) & ~(CFG_GPIO_REV0 | CFG_GPIO_REV0));
out32(GPIO0_ODR, in32(GPIO0_ODR) & ~(CFG_GPIO_REV0 | CFG_GPIO_REV0));
rev = (in32(GPIO0_IR) >> 16) & 0x3;
/* Setup GPIO14 & 15 as non GPIO again */
mfsdr(sdr_pfc0, pfc0);
pfc0 &= ~(CFG_GPIO_REV0 | CFG_GPIO_REV1);
mtsdr(sdr_pfc0, pfc0);
return rev;
}
int checkboard (void)
{
char *s = getenv ("serial#");
printf ("Board: ALPR");
if (s != NULL) {
puts (", serial# ");
puts (s);
}
printf(" (Rev. %d)\n", board_rev());
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 ocotea 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;
}
/* FPGA Init */
alpr_fpga_init ();
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 )
{
/*--------------------------------------------------------------------------+
* 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 | PCI_COMMAND_MASTER);
}
#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
/*************************************************************************
* 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.
*
*
************************************************************************/
#if defined(CONFIG_PCI)
static void wait_for_pci_ready(void)
{
/*
* Configure EREADY as input
*/
out32(GPIO0_TCR, in32(GPIO0_TCR) & ~CFG_GPIO_EREADY);
udelay(1000);
for (;;) {
if (in32(GPIO0_IR) & CFG_GPIO_EREADY)
return;
}
}
int is_pci_host(struct pci_controller *hose)
{
wait_for_pci_ready();
return 1; /* return 1 for host controller */
}
#endif /* defined(CONFIG_PCI) */
/*************************************************************************
* pci_master_init
*
************************************************************************/
#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
void pci_master_init(struct pci_controller *hose)
{
/*--------------------------------------------------------------------------+
| PowerPC440 PCI Master configuration.
| Map PLB/processor addresses to PCI memory space.
| PLB address 0xA0000000-0xCFFFFFFF ==> PCI address 0x80000000-0xCFFFFFFF
| Use byte reversed out routines to handle endianess.
| Make this region non-prefetchable.
+--------------------------------------------------------------------------*/
out32r( PCIX0_POM0SA, 0 ); /* disable */
out32r( PCIX0_POM1SA, 0 ); /* disable */
out32r( PCIX0_POM2SA, 0 ); /* disable */
out32r(PCIX0_POM0LAL, CFG_PCI_MEMBASE); /* PMM0 Local Address */
out32r(PCIX0_POM0LAH, 0x00000003); /* PMM0 Local Address */
out32r(PCIX0_POM0PCIAL, CFG_PCI_MEMBASE); /* PMM0 PCI Low Address */
out32r(PCIX0_POM0PCIAH, 0x00000000); /* PMM0 PCI High Address */
out32r(PCIX0_POM0SA, ~(0x10000000 - 1) | 1); /* 256MB + enable region */
out32r(PCIX0_POM1LAL, CFG_PCI_MEMBASE2); /* PMM0 Local Address */
out32r(PCIX0_POM1LAH, 0x00000003); /* PMM0 Local Address */
out32r(PCIX0_POM1PCIAL, CFG_PCI_MEMBASE2); /* PMM0 PCI Low Address */
out32r(PCIX0_POM1PCIAH, 0x00000000); /* PMM0 PCI High Address */
out32r(PCIX0_POM1SA, ~(0x10000000 - 1) | 1); /* 256MB + enable region */
}
#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
#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

View file

@ -0,0 +1,44 @@
#
# (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
#
#
# AMCC 440GX Reference Platform (Ocotea) board
#
#TEXT_BASE = 0xFFFE0000
ifeq ($(ramsym),1)
TEXT_BASE = 0x07FD0000
else
TEXT_BASE = 0xFFFC0000
endif
PLATFORM_CPPFLAGS += -DCONFIG_440=1
ifeq ($(debug),1)
PLATFORM_CPPFLAGS += -DDEBUG
endif
ifeq ($(dbcr),1)
PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
endif

257
board/prodrive/alpr/fpga.c Normal file
View file

@ -0,0 +1,257 @@
/*
* (C) Copyright 2006
* Heiko Schocher, DENX Software Engineering, hs@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
*
*/
/*
* Altera FPGA configuration support for the ALPR computer from prodrive
*/
#include <common.h>
#include <altera.h>
#include <ACEX1K.h>
#include <command.h>
#include <asm-ppc/processor.h>
#include <ppc440.h>
#include "fpga.h"
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_FPGA)
#ifdef FPGA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
static unsigned long regval;
#define SET_GPIO_REG_0(reg, bit) { \
regval = in32(reg); \
regval &= ~(0x80000000 >> bit); \
out32(reg, regval); \
}
#define SET_GPIO_REG_1(reg, bit) { \
regval = in32(reg); \
regval |= (0x80000000 >> bit); \
out32(reg, regval); \
}
#define SET_GPIO_0(bit) SET_GPIO_REG_0(GPIO0_OR, bit)
#define SET_GPIO_1(bit) SET_GPIO_REG_1(GPIO0_OR, bit)
#define FPGA_PRG (0x80000000 >> CFG_GPIO_PROG_EN)
#define FPGA_CONFIG (0x80000000 >> CFG_GPIO_CONFIG)
#define FPGA_DATA (0x80000000 >> CFG_GPIO_DATA)
#define FPGA_CLK (0x80000000 >> CFG_GPIO_CLK)
#define OLD_VAL (FPGA_PRG | FPGA_CONFIG)
#define SET_FPGA(data) out32(GPIO0_OR, data)
#define FPGA_WRITE_1 { \
SET_FPGA(OLD_VAL | 0 | FPGA_DATA); /* set data to 1 */ \
SET_FPGA(OLD_VAL | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
#define FPGA_WRITE_0 { \
SET_FPGA(OLD_VAL | 0 | 0 ); /* set data to 0 */ \
SET_FPGA(OLD_VAL | FPGA_CLK | 0 );} /* set data to 1 */
/* Plattforminitializations */
/* Here we have to set the FPGA Chain */
/* PROGRAM_PROG_EN = HIGH */
/* PROGRAM_SEL_DPR = LOW */
int fpga_pre_fn (int cookie)
{
unsigned long reg;
reg = in32(GPIO0_IR);
/* Enable the FPGA Chain */
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_PROG_EN);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_PROG_EN);
SET_GPIO_1(CFG_GPIO_PROG_EN);
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_SEL_DPR);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_SEL_DPR);
SET_GPIO_0((CFG_GPIO_SEL_DPR));
/* initialize the GPIO Pins */
/* output */
SET_GPIO_0(CFG_GPIO_CLK);
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_CLK);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CLK);
/* output */
SET_GPIO_0(CFG_GPIO_DATA);
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_DATA);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_DATA);
/* First we set STATUS to 0 then as an input */
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_STATUS);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_STATUS);
SET_GPIO_0(CFG_GPIO_STATUS);
SET_GPIO_REG_0(GPIO0_TCR, CFG_GPIO_STATUS);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_STATUS);
/* output */
SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_CONFIG);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CONFIG);
SET_GPIO_0(CFG_GPIO_CONFIG);
/* input */
SET_GPIO_0(CFG_GPIO_CON_DON);
SET_GPIO_REG_0(GPIO0_TCR, CFG_GPIO_CON_DON);
SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CON_DON);
/* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
SET_GPIO_0(CFG_GPIO_CONFIG);
return FPGA_SUCCESS;
}
/* Set the state of CONFIG Pin */
int fpga_config_fn (int assert_config, int flush, int cookie)
{
if (assert_config) {
SET_GPIO_1(CFG_GPIO_CONFIG);
} else {
SET_GPIO_0(CFG_GPIO_CONFIG);
}
return FPGA_SUCCESS;
}
/* Returns the state of STATUS Pin */
int fpga_status_fn (int cookie)
{
unsigned long reg;
reg = in32(GPIO0_IR);
if (reg &= (0x80000000 >> CFG_GPIO_STATUS)) {
PRINTF("STATUS = HIGH\n");
return FPGA_FAIL;
}
PRINTF("STATUS = LOW\n");
return FPGA_SUCCESS;
}
/* Returns the state of CONF_DONE Pin */
int fpga_done_fn (int cookie)
{
unsigned long reg;
reg = in32(GPIO0_IR);
if (reg &= (0x80000000 >> CFG_GPIO_CON_DON)) {
PRINTF("CONF_DON = HIGH\n");
return FPGA_FAIL;
}
PRINTF("CONF_DON = LOW\n");
return FPGA_SUCCESS;
}
/* writes the complete buffer to the FPGA
writing the complete buffer in one function is much faster,
then calling it for every bit */
int fpga_write_fn (void *buf, size_t len, int flush, int cookie)
{
size_t bytecount = 0;
unsigned char *data = (unsigned char *) buf;
unsigned char val=0;
int i;
int len_40 = len / 40;
while (bytecount < len) {
val = data[bytecount++];
i = 8;
do {
if (val & 0x01) {
FPGA_WRITE_1;
} else {
FPGA_WRITE_0;
}
val >>= 1;
i --;
} while (i > 0);
#ifdef CFG_FPGA_PROG_FEEDBACK
if (bytecount % len_40 == 0) {
putc ('.'); /* let them know we are alive */
#ifdef CFG_FPGA_CHECK_CTRLC
if (ctrlc ())
return FPGA_FAIL;
#endif
}
#endif
}
return FPGA_SUCCESS;
}
/* called, when programming is aborted */
int fpga_abort_fn (int cookie)
{
SET_GPIO_1((CFG_GPIO_SEL_DPR));
return FPGA_SUCCESS;
}
/* called, when programming was succesful */
int fpga_post_fn (int cookie)
{
return fpga_abort_fn (cookie);
}
/* Note that these are pointers to code that is in Flash. They will be
* relocated at runtime.
*/
Altera_CYC2_Passive_Serial_fns fpga_fns = {
fpga_pre_fn,
fpga_config_fn,
fpga_status_fn,
fpga_done_fn,
fpga_write_fn,
fpga_abort_fn,
fpga_post_fn
};
Altera_desc fpga[CONFIG_FPGA_COUNT] = {
{Altera_CYC2,
passive_serial,
Altera_EP2C35_SIZE,
(void *) &fpga_fns,
NULL,
0}
};
/*
* Initialize the fpga. Return 1 on success, 0 on failure.
*/
int alpr_fpga_init (void)
{
int i;
PRINTF ("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n", __FUNCTION__, __LINE__, gd->reloc_off);
fpga_init (gd->reloc_off);
for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
PRINTF ("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
fpga_add (fpga_altera, &fpga[i]);
}
return 1;
}
#endif

103
board/prodrive/alpr/init.S Normal file
View file

@ -0,0 +1,103 @@
/*
* (C) Copyright 2006
* 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 <ppc_asm.tmpl>
#include <config.h>
/* 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 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"
.globl tlbtab
tlbtab:
tlbtab_start
tlbentry( 0xff000000, SZ_16M, 0xff000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I )
tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I )
tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
/* PCI */
tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 3, AC_R|AC_W|SA_G|SA_I )
tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 3, AC_R|AC_W|SA_G|SA_I )
tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 3, AC_R|AC_W|SA_G|SA_I )
/* NAND */
tlbentry( CFG_NAND_BASE, SZ_4K, CFG_NAND_BASE, 1, AC_R|AC_W|AC_X|SA_G|SA_I )
tlbtab_end

173
board/prodrive/alpr/nand.c Normal file
View file

@ -0,0 +1,173 @@
/*
* (C) Copyright 2006
* Heiko Schocher, DENX Software Engineering, hs@denx.de
*
* (C) Copyright 2006
* 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 <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include <asm/processor.h>
#include <nand.h>
struct alpr_ndfc_regs {
u8 cmd[4];
u8 addr_wait;
u8 term;
u8 dummy;
u8 dummy2;
u8 data;
};
static u8 hwctl;
static struct alpr_ndfc_regs *alpr_ndfc = NULL;
#define readb(addr) (u8)(*(volatile u8 *)(addr))
#define writeb(d,addr) *(volatile u8 *)(addr) = ((u8)(d))
/*
* The ALPR has a NAND Flash Controller (NDFC) that handles all accesses to
* the NAND devices. The NDFC has command, address and data registers that
* when accessed will set up the NAND flash pins appropriately. We'll use the
* hwcontrol function to save the configuration in a global variable.
* We can then use this information in the read and write functions to
* determine which NDFC register to access.
*
* There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte).
*/
static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch (cmd) {
case NAND_CTL_SETCLE:
hwctl |= 0x1;
break;
case NAND_CTL_CLRCLE:
hwctl &= ~0x1;
break;
case NAND_CTL_SETALE:
hwctl |= 0x2;
break;
case NAND_CTL_CLRALE:
hwctl &= ~0x2;
break;
case NAND_CTL_SETNCE:
break;
case NAND_CTL_CLRNCE:
writeb(0x00, &(alpr_ndfc->term));
break;
}
}
static void alpr_nand_write_byte(struct mtd_info *mtd, u_char byte)
{
struct nand_chip *nand = mtd->priv;
if (hwctl & 0x1)
/*
* IO_ADDR_W used as CMD[i] reg to support multiple NAND
* chips.
*/
writeb(byte, nand->IO_ADDR_W);
else if (hwctl & 0x2) {
writeb(byte, &(alpr_ndfc->addr_wait));
} else
writeb(byte, &(alpr_ndfc->data));
}
static u_char alpr_nand_read_byte(struct mtd_info *mtd)
{
return readb(&(alpr_ndfc->data));
}
static void alpr_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
struct nand_chip *nand = mtd->priv;
int i;
for (i = 0; i < len; i++) {
if (hwctl & 0x1)
/*
* IO_ADDR_W used as CMD[i] reg to support multiple NAND
* chips.
*/
writeb(buf[i], nand->IO_ADDR_W);
else if (hwctl & 0x2)
writeb(buf[i], &(alpr_ndfc->addr_wait));
else
writeb(buf[i], &(alpr_ndfc->data));
}
}
static void alpr_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
int i;
for (i = 0; i < len; i++) {
buf[i] = readb(&(alpr_ndfc->data));
}
}
static int alpr_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
{
int i;
for (i = 0; i < len; i++)
if (buf[i] != readb(&(alpr_ndfc->data)))
return i;
return 0;
}
static int alpr_nand_dev_ready(struct mtd_info *mtd)
{
volatile u_char val;
/*
* Blocking read to wait for NAND to be ready
*/
val = readb(&(alpr_ndfc->addr_wait));
/*
* Return always true
*/
return 1;
}
void board_nand_init(struct nand_chip *nand)
{
alpr_ndfc = (struct alpr_ndfc_regs *)CFG_NAND_BASE;
nand->eccmode = NAND_ECC_SOFT;
/* Reference hardware control function */
nand->hwcontrol = alpr_nand_hwcontrol;
/* Set command delay time */
nand->write_byte = alpr_nand_write_byte;
nand->read_byte = alpr_nand_read_byte;
nand->write_buf = alpr_nand_write_buf;
nand->read_buf = alpr_nand_read_buf;
nand->verify_buf = alpr_nand_verify_buf;
nand->dev_ready = alpr_nand_dev_ready;
}
#endif

View file

@ -0,0 +1,157 @@
/*
* (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 :
{
/* WARNING - the following is hand-optimized to fit within */
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/ppc4xx/start.o (.text)
board/prodrive/alpr/init.o (.text)
cpu/ppc4xx/kgdb.o (.text)
cpu/ppc4xx/traps.o (.text)
cpu/ppc4xx/interrupts.o (.text)
cpu/ppc4xx/serial.o (.text)
cpu/ppc4xx/cpu_init.o (.text)
cpu/ppc4xx/speed.o (.text)
common/dlmalloc.o (.text)
lib_generic/crc32.o (.text)
lib_ppc/extable.o (.text)
lib_generic/zlib.o (.text)
/* . = env_offset;*/
/* common/environment.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 = .);
}

View file

@ -48,6 +48,7 @@ void flash_print_info(flash_info_t *info)
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("ST "); break;
case FLASH_MAN_EXCEL: printf ("Excel Semiconductor "); break;
default: printf ("Unknown Vendor "); break;
}
@ -156,6 +157,9 @@ static ulong flash_get_size(vu_long *addr, flash_info_t *info)
case (CFG_FLASH_WORD_SIZE)SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
case (CFG_FLASH_WORD_SIZE)STM_MANUFACT:
info->flash_id = FLASH_MAN_STM;
break;
case (CFG_FLASH_WORD_SIZE)EXCEL_MANUFACT:
info->flash_id = FLASH_MAN_EXCEL;
break;

View file

@ -0,0 +1,52 @@
/*
* (C) Copyright 2003
* Ingo Assmus <ingo.assmus@keymile.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* main board support/init for the Galileo Eval board DB64460.
*/
#ifndef __64460_H__
#define __64460_H__
/* CPU Configuration bits */
#define CPU_CONF_ADDR_MISS_EN (1 << 8)
#define CPU_CONF_SINGLE_CPU (1 << 11)
#define CPU_CONF_ENDIANESS (1 << 12)
#define CPU_CONF_PIPELINE (1 << 13)
#define CPU_CONF_STOP_RETRY (1 << 17)
#define CPU_CONF_MULTI_DECODE (1 << 18)
#define CPU_CONF_DP_VALID (1 << 19)
#define CPU_CONF_PERR_PROP (1 << 22)
#define CPU_CONF_AACK_DELAY_2 (1 << 25)
#define CPU_CONF_AP_VALID (1 << 26)
#define CPU_CONF_REMAP_WR_DIS (1 << 27)
/* CPU Master Control bits */
#define CPU_MAST_CTL_ARB_EN (1 << 8)
#define CPU_MAST_CTL_MASK_BR_1 (1 << 9)
#define CPU_MAST_CTL_M_WR_TRIG (1 << 10)
#define CPU_MAST_CTL_M_RD_TRIG (1 << 11)
#define CPU_MAST_CTL_CLEAN_BLK (1 << 12)
#define CPU_MAST_CTL_FLUSH_BLK (1 << 13)
#endif /* __64460_H__ */

View file

@ -0,0 +1,55 @@
#
# (C) Copyright 2002-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
#
include $(TOPDIR)/config.mk
ifneq ($(OBJTREE),$(SRCTREE))
$(shell mkdir -p $(obj)../../Marvell/common)
endif
LIB = $(obj)lib$(BOARD).a
SOBJS = misc.o
COBJS = $(BOARD).o mpsc.o mv_eth.o pci.o sdram_init.o serial.o \
../../Marvell/common/i2c.o ../../Marvell/common/memory.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend *~
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,28 @@
#
# (C) Copyright 2002-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
#
#
# p3mx boards (P3M750 & P3M7448)
#
TEXT_BASE = 0xfff00000

43
board/prodrive/p3mx/eth.h Normal file
View file

@ -0,0 +1,43 @@
/*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* 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
*/
/*
* eth.h - header file for the polled mode GT ethernet driver
*/
#ifndef __EVB64360_ETH_H__
#define __EVB64360_ETH_H__
#include <asm/types.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <common.h>
int db64360_eth0_poll(void);
int db64360_eth0_transmit(unsigned int s, volatile char *p);
void db64360_eth0_disable(void);
bool network_start(bd_t *bis);
#endif /* __EVB64360_ETH_H__ */

245
board/prodrive/p3mx/misc.S Normal file
View file

@ -0,0 +1,245 @@
#include <config.h>
#include <74xx_7xx.h>
#include "version.h"
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include "../../Marvell/include/mv_gen_reg.h"
#ifdef CONFIG_ECC
/* Galileo specific asm code for initializing ECC */
.globl board_relocate_rom
board_relocate_rom:
mflr r7
/* update the location of the GT registers */
lis r11, CFG_GT_REGS@h
/* if we're using ECC, we must use the DMA engine to copy ourselves */
bl start_idma_transfer_0
bl wait_for_idma_0
bl stop_idma_engine_0
mtlr r7
blr
.globl board_init_ecc
board_init_ecc:
mflr r7
/* NOTE: r10 still contains the location we've been relocated to
* which happens to be TOP_OF_RAM - CFG_MONITOR_LEN */
/* now that we're running from ram, init the rest of main memory
* for ECC use */
lis r8, CFG_MONITOR_LEN@h
ori r8, r8, CFG_MONITOR_LEN@l
divw r3, r10, r8
/* set up the counter, and init the starting address */
mtctr r3
li r12, 0
/* bytes per transfer */
mr r5, r8
about_to_init_ecc:
1: mr r3, r12
mr r4, r12
bl start_idma_transfer_0
bl wait_for_idma_0
bl stop_idma_engine_0
add r12, r12, r8
bdnz 1b
mtlr r7
blr
/* r3: dest addr
* r4: source addr
* r5: byte count
* r11: gt regbase
* trashes: r6, r5
*/
start_idma_transfer_0:
/* set the byte count, including the OWN bit */
mr r6, r11
ori r6, r6, CHANNEL0_DMA_BYTE_COUNT
stwbrx r5, 0, (r6)
/* set the source address */
mr r6, r11
ori r6, r6, CHANNEL0_DMA_SOURCE_ADDRESS
stwbrx r4, 0, (r6)
/* set the dest address */
mr r6, r11
ori r6, r6, CHANNEL0_DMA_DESTINATION_ADDRESS
stwbrx r3, 0, (r6)
/* set the next record pointer */
li r5, 0
mr r6, r11
ori r6, r6, CHANNEL0NEXT_RECORD_POINTER
stwbrx r5, 0, (r6)
/* set the low control register */
/* bit 9 is NON chained mode, bit 31 is new style descriptors.
bit 12 is channel enable */
ori r5, r5, (1 << 12) | (1 << 12) | (1 << 11)
/* 15 shifted by 16 (oris) == bit 31 */
oris r5, r5, (1 << 15)
mr r6, r11
ori r6, r6, CHANNEL0CONTROL
stwbrx r5, 0, (r6)
blr
/* this waits for the bytecount to return to zero, indicating
* that the trasfer is complete */
wait_for_idma_0:
mr r5, r11
lis r6, 0xff
ori r6, r6, 0xffff
ori r5, r5, CHANNEL0_DMA_BYTE_COUNT
1: lwbrx r4, 0, (r5)
and. r4, r4, r6
bne 1b
blr
/* this turns off channel 0 of the idma engine */
stop_idma_engine_0:
/* shut off the DMA engine */
li r5, 0
mr r6, r11
ori r6, r6, CHANNEL0CONTROL
stwbrx r5, 0, (r6)
blr
#endif
#ifdef CFG_BOARD_ASM_INIT
/* NOTE: trashes r3-r7 */
.globl board_asm_init
board_asm_init:
/* just move the GT registers to where they belong */
lis r3, CFG_DFL_GT_REGS@h
ori r3, r3, CFG_DFL_GT_REGS@l
lis r4, CFG_GT_REGS@h
ori r4, r4, CFG_GT_REGS@l
li r5, INTERNAL_SPACE_DECODE
/* test to see if we've already moved */
lwbrx r6, r5, r4
andi. r6, r6, 0xffff
/* check loading of R7 is: 0x0F80 should: 0xf800: DONE */
/* rlwinm r7, r4, 8, 16, 31
rlwinm r7, r4, 12, 16, 31 */ /* original */
rlwinm r7, r4, 16, 16, 31
/* -----------------------------------------------------*/
cmp cr0, r7, r6
beqlr
/* nope, have to move the registers */
lwbrx r6, r5, r3
andis. r6, r6, 0xffff
or r6, r6, r7
stwbrx r6, r5, r3
/* now, poll for the change */
1: lwbrx r7, r5, r4
cmp cr0, r7, r6
bne 1b
lis r3, CFG_INT_SRAM_BASE@h
ori r3, r3, CFG_INT_SRAM_BASE@l
rlwinm r3, r3, 16, 16, 31
lis r4, CFG_GT_REGS@h
ori r4, r4, CFG_GT_REGS@l
li r5, INTEGRATED_SRAM_BASE_ADDR
stwbrx r3, r5, r4
2: lwbrx r6, r5, r4
cmp cr0, r3, r6
bne 2b
/* done! */
blr
#endif
/* For use of the debug LEDs */
.global led_on0_relocated
led_on0_relocated:
xor r21, r21, r21
xor r18, r18, r18
lis r18, 0xFC80
ori r18, r18, 0x8000
/* stw r21, 0x0(r18) */
sync
blr
.global led_off0_relocated
led_off0_relocated:
xor r21, r21, r21
xor r18, r18, r18
lis r18, 0xFC81
ori r18, r18, 0x4000
/* stw r21, 0x0(r18) */
sync
blr
.global led_on0
led_on0:
xor r18, r18, r18
lis r18, 0x1c80
ori r18, r18, 0x8000
/* stw r18, 0x0(r18) */
sync
blr
.global led_off0
led_off0:
xor r18, r18, r18
lis r18, 0x1c81
ori r18, r18, 0x4000
/* stw r18, 0x0(r18) */
sync
blr
.global led_on1
led_on1:
xor r18, r18, r18
lis r18, 0x1c80
ori r18, r18, 0xc000
/* stw r18, 0x0(r18) */
sync
blr
.global led_off1
led_off1:
xor r18, r18, r18
lis r18, 0x1c81
ori r18, r18, 0x8000
/* stw r18, 0x0(r18) */
sync
blr
.global led_on2
led_on2:
xor r18, r18, r18
lis r18, 0x1c81
ori r18, r18, 0x0000
/* stw r18, 0x0(r18) */
sync
blr
.global led_off2
led_off2:
xor r18, r18, r18
lis r18, 0x1c81
ori r18, r18, 0xc000
/* stw r18, 0x0(r18) */
sync
blr

1013
board/prodrive/p3mx/mpsc.c Normal file

File diff suppressed because it is too large Load diff

156
board/prodrive/p3mx/mpsc.h Normal file
View file

@ -0,0 +1,156 @@
/*
* (C) Copyright 2001
* John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
*
* 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
*/
/*************************************************************************
* changes for Marvell DB64360 eval board 2003 by Ingo Assmus <ingo.assmus@keymile.com>
*
************************************************************************/
/*
* mpsc.h - header file for MPSC in uart mode (console driver)
*/
#ifndef __MPSC_H__
#define __MPSC_H__
/* include actual Galileo defines */
#include "../../Marvell/include/mv_gen_reg.h"
/* driver related defines */
int mpsc_init(int baud);
void mpsc_sdma_init(void);
void mpsc_init2(void);
int galbrg_set_baudrate(int channel, int rate);
int mpsc_putchar_early(char ch);
char mpsc_getchar_debug(void);
int mpsc_test_char_debug(void);
int mpsc_test_char_sdma(void);
extern int (*mpsc_putchar)(char ch);
extern char (*mpsc_getchar)(void);
extern int (*mpsc_test_char)(void);
#define CHANNEL CONFIG_MPSC_PORT
#define TX_DESC 5
#define RX_DESC 20
#define DESC_FIRST 0x00010000
#define DESC_LAST 0x00020000
#define DESC_OWNER_BIT 0x80000000
#define TX_DEMAND 0x00800000
#define TX_STOP 0x00010000
#define RX_ENABLE 0x00000080
#define SDMA_RX_ABORT (1 << 15)
#define SDMA_TX_ABORT (1 << 31)
#define MPSC_TX_ABORT (1 << 7)
#define MPSC_RX_ABORT (1 << 23)
#define MPSC_ENTER_HUNT (1 << 31)
/* MPSC defines */
#define GALMPSC_CONNECT 0x1
#define GALMPSC_DISCONNECT 0x0
#define GALMPSC_UART 0x1
#define GALMPSC_STOP_BITS_1 0x0
#define GALMPSC_STOP_BITS_2 0x1
#define GALMPSC_CHAR_LENGTH_8 0x3
#define GALMPSC_CHAR_LENGTH_7 0x2
#define GALMPSC_PARITY_ODD 0x0
#define GALMPSC_PARITY_EVEN 0x2
#define GALMPSC_PARITY_MARK 0x3
#define GALMPSC_PARITY_SPACE 0x1
#define GALMPSC_PARITY_NONE -1
#define GALMPSC_SERIAL_MULTIPLEX SERIAL_PORT_MULTIPLEX /* 0xf010 */
#define GALMPSC_ROUTING_REGISTER MAIN_ROUTING_REGISTER /* 0xb400 */
#define GALMPSC_RxC_ROUTE RECEIVE_CLOCK_ROUTING_REGISTER /* 0xb404 */
#define GALMPSC_TxC_ROUTE TRANSMIT_CLOCK_ROUTING_REGISTER /* 0xb408 */
#define GALMPSC_MCONF_LOW MPSC0_MAIN_CONFIGURATION_LOW /* 0x8000 */
#define GALMPSC_MCONF_HIGH MPSC0_MAIN_CONFIGURATION_HIGH /* 0x8004 */
#define GALMPSC_PROTOCONF_REG MPSC0_PROTOCOL_CONFIGURATION /* 0x8008 */
#define GALMPSC_REG_GAP 0x1000
#define GALMPSC_MCONF_CHREG_BASE CHANNEL0_REGISTER1 /* 0x800c */
#define GALMPSC_CHANNELREG_1 CHANNEL0_REGISTER1 /* 0x800c */
#define GALMPSC_CHANNELREG_2 CHANNEL0_REGISTER2 /* 0x8010 */
#define GALMPSC_CHANNELREG_3 CHANNEL0_REGISTER3 /* 0x8014 */
#define GALMPSC_CHANNELREG_4 CHANNEL0_REGISTER4 /* 0x8018 */
#define GALMPSC_CHANNELREG_5 CHANNEL0_REGISTER5 /* 0x801c */
#define GALMPSC_CHANNELREG_6 CHANNEL0_REGISTER6 /* 0x8020 */
#define GALMPSC_CHANNELREG_7 CHANNEL0_REGISTER7 /* 0x8024 */
#define GALMPSC_CHANNELREG_8 CHANNEL0_REGISTER8 /* 0x8028 */
#define GALMPSC_CHANNELREG_9 CHANNEL0_REGISTER9 /* 0x802c */
#define GALMPSC_CHANNELREG_10 CHANNEL0_REGISTER10 /* 0x8030 */
#define GALMPSC_CHANNELREG_11 CHANNEL0_REGISTER11 /* 0x8034 */
#define GALSDMA_COMMAND_FIRST (1 << 16)
#define GALSDMA_COMMAND_LAST (1 << 17)
#define GALSDMA_COMMAND_ENABLEINT (1 << 23)
#define GALSDMA_COMMAND_AUTO (1 << 30)
#define GALSDMA_COMMAND_OWNER (1 << 31)
#define GALSDMA_RX 0
#define GALSDMA_TX 1
/* CHANNEL2 should be CHANNEL1, according to documentation,
* but to work with the current GTREGS file...
*/
#define GALSDMA_0_CONF_REG CHANNEL0_CONFIGURATION_REGISTER /* 0x4000 */
#define GALSDMA_1_CONF_REG CHANNEL2_CONFIGURATION_REGISTER /* 0x6000 */
#define GALSDMA_0_COM_REG CHANNEL0_COMMAND_REGISTER /* 0x4008 */
#define GALSDMA_1_COM_REG CHANNEL2_COMMAND_REGISTER /* 0x6008 */
#define GALSDMA_0_CUR_RX_PTR CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER /* 0x4810 */
#define GALSDMA_0_CUR_TX_PTR CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER /* 0x4c10 */
#define GALSDMA_0_FIR_TX_PTR CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER /* 0x4c14 */
#define GALSDMA_1_CUR_RX_PTR CHANNEL2_CURRENT_RX_DESCRIPTOR_POINTER /* 0x6810 */
#define GALSDMA_1_CUR_TX_PTR CHANNEL2_CURRENT_TX_DESCRIPTOR_POINTER /* 0x6c10 */
#define GALSDMA_1_FIR_TX_PTR CHANNEL2_FIRST_TX_DESCRIPTOR_POINTER /* 0x6c14 */
#define GALSDMA_REG_DIFF 0x2000
/* WRONG in gt64260R.h */
#define GALSDMA_INT_CAUSE 0xb800 /* SDMA_CAUSE */
#define GALSDMA_INT_MASK 0xb880 /* SDMA_MASK */
#define GALMPSC_0_INT_CAUSE 0xb804
#define GALMPSC_0_INT_MASK 0xb884
#define GALSDMA_MODE_UART 0
#define GALSDMA_MODE_BISYNC 1
#define GALSDMA_MODE_HDLC 2
#define GALSDMA_MODE_TRANSPARENT 3
#define GALBRG_0_CONFREG BRG0_CONFIGURATION_REGISTER /* 0xb200 */
#define GALBRG_REG_GAP 0x0008
#define GALBRG_0_BTREG BRG0_BAUDE_TUNING_REGISTER /* 0xb204 */
#endif /* __MPSC_H__ */

3344
board/prodrive/p3mx/mv_eth.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,840 @@
/*
* (C) Copyright 2003
* Ingo Assmus <ingo.assmus@keymile.com>
*
* based on - Driver for MV64460X ethernet ports
* Copyright (C) 2002 rabeeh@galileo.co.il
*
* 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
*/
/*
* mv_eth.h - header file for the polled mode GT ethernet driver
*/
#ifndef __DB64460_ETH_H__
#define __DB64460_ETH_H__
#include <asm/types.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <common.h>
#include <net.h>
#include "mv_regs.h"
#include "ppc_error_no.h"
#include "../../Marvell/include/core.h"
/*************************************************************************
**************************************************************************
**************************************************************************
* The first part is the high level driver of the gigE ethernet ports. *
**************************************************************************
**************************************************************************
*************************************************************************/
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* In case not using SG on Tx, define MAX_SKB_FRAGS as 0 */
#ifndef MAX_SKB_FRAGS
#define MAX_SKB_FRAGS 0
#endif
/* Port attributes */
/*#define MAX_RX_QUEUE_NUM 8*/
/*#define MAX_TX_QUEUE_NUM 8*/
#define MAX_RX_QUEUE_NUM 1
#define MAX_TX_QUEUE_NUM 1
/* Use one TX queue and one RX queue */
#define MV64460_TX_QUEUE_NUM 1
#define MV64460_RX_QUEUE_NUM 1
/*
* Number of RX / TX descriptors on RX / TX rings.
* Note that allocating RX descriptors is done by allocating the RX
* ring AND a preallocated RX buffers (skb's) for each descriptor.
* The TX descriptors only allocates the TX descriptors ring,
* with no pre allocated TX buffers (skb's are allocated by higher layers.
*/
/* Default TX ring size is 10 descriptors */
#ifdef CONFIG_MV64460_ETH_TXQUEUE_SIZE
#define MV64460_TX_QUEUE_SIZE CONFIG_MV64460_ETH_TXQUEUE_SIZE
#else
#define MV64460_TX_QUEUE_SIZE 4
#endif
/* Default RX ring size is 4 descriptors */
#ifdef CONFIG_MV64460_ETH_RXQUEUE_SIZE
#define MV64460_RX_QUEUE_SIZE CONFIG_MV64460_ETH_RXQUEUE_SIZE
#else
#define MV64460_RX_QUEUE_SIZE 4
#endif
#ifdef CONFIG_RX_BUFFER_SIZE
#define MV64460_RX_BUFFER_SIZE CONFIG_RX_BUFFER_SIZE
#else
#define MV64460_RX_BUFFER_SIZE 1600
#endif
#ifdef CONFIG_TX_BUFFER_SIZE
#define MV64460_TX_BUFFER_SIZE CONFIG_TX_BUFFER_SIZE
#else
#define MV64460_TX_BUFFER_SIZE 1600
#endif
/*
* Network device statistics. Akin to the 2.0 ether stats but
* with byte counters.
*/
struct net_device_stats
{
unsigned long rx_packets; /* total packets received */
unsigned long tx_packets; /* total packets transmitted */
unsigned long rx_bytes; /* total bytes received */
unsigned long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long rx_dropped; /* no space in linux buffers */
unsigned long tx_dropped; /* no space available in linux */
unsigned long multicast; /* multicast packets received */
unsigned long collisions;
/* detailed rx_errors: */
unsigned long rx_length_errors;
unsigned long rx_over_errors; /* receiver ring buff overflow */
unsigned long rx_crc_errors; /* recved pkt with crc error */
unsigned long rx_frame_errors; /* recv'd frame alignment error */
unsigned long rx_fifo_errors; /* recv'r fifo overrun */
unsigned long rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors;
unsigned long tx_carrier_errors;
unsigned long tx_fifo_errors;
unsigned long tx_heartbeat_errors;
unsigned long tx_window_errors;
/* for cslip etc */
unsigned long rx_compressed;
unsigned long tx_compressed;
};
/* Private data structure used for ethernet device */
struct mv64460_eth_priv {
unsigned int port_num;
struct net_device_stats *stats;
/* to buffer area aligned */
char * p_eth_tx_buffer[MV64460_TX_QUEUE_SIZE+1]; /*pointers to alligned tx buffs in memory space */
char * p_eth_rx_buffer[MV64460_RX_QUEUE_SIZE+1]; /*pointers to allinged rx buffs in memory space */
/* Size of Tx Ring per queue */
unsigned int tx_ring_size [MAX_TX_QUEUE_NUM];
/* Size of Rx Ring per queue */
unsigned int rx_ring_size [MAX_RX_QUEUE_NUM];
/* Magic Number for Ethernet running */
unsigned int eth_running;
int first_init;
};
int mv64460_eth_init (struct eth_device *dev);
int mv64460_eth_stop (struct eth_device *dev);
int mv64460_eth_start_xmit (struct eth_device*, volatile void* packet, int length);
/* return db64460_eth0_poll(); */
int mv64460_eth_open (struct eth_device *dev);
/*************************************************************************
**************************************************************************
**************************************************************************
* The second part is the low level driver of the gigE ethernet ports. *
**************************************************************************
**************************************************************************
*************************************************************************/
/********************************************************************************
* Header File for : MV-643xx network interface header
*
* DESCRIPTION:
* This header file contains macros typedefs and function declaration for
* the Marvell Gig Bit Ethernet Controller.
*
* DEPENDENCIES:
* None.
*
*******************************************************************************/
#ifdef CONFIG_SPECIAL_CONSISTENT_MEMORY
#ifdef CONFIG_MV64460_SRAM_CACHEABLE
/* In case SRAM is cacheable but not cache coherent */
#define D_CACHE_FLUSH_LINE(addr, offset) \
{ \
__asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
}
#else
/* In case SRAM is cache coherent or non-cacheable */
#define D_CACHE_FLUSH_LINE(addr, offset) ;
#endif
#else
#ifdef CONFIG_NOT_COHERENT_CACHE
/* In case of descriptors on DDR but not cache coherent */
#define D_CACHE_FLUSH_LINE(addr, offset) \
{ \
__asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
}
#else
/* In case of descriptors on DDR and cache coherent */
#define D_CACHE_FLUSH_LINE(addr, offset) ;
#endif /* CONFIG_NOT_COHERENT_CACHE */
#endif /* CONFIG_SPECIAL_CONSISTENT_MEMORY */
#define CPU_PIPE_FLUSH \
{ \
__asm__ __volatile__ ("eieio"); \
}
/* defines */
/* Default port configuration value */
#define PORT_CONFIG_VALUE \
ETH_UNICAST_NORMAL_MODE | \
ETH_DEFAULT_RX_QUEUE_0 | \
ETH_DEFAULT_RX_ARP_QUEUE_0 | \
ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP | \
ETH_RECEIVE_BC_IF_IP | \
ETH_RECEIVE_BC_IF_ARP | \
ETH_CAPTURE_TCP_FRAMES_DIS | \
ETH_CAPTURE_UDP_FRAMES_DIS | \
ETH_DEFAULT_RX_TCP_QUEUE_0 | \
ETH_DEFAULT_RX_UDP_QUEUE_0 | \
ETH_DEFAULT_RX_BPDU_QUEUE_0
/* Default port extend configuration value */
#define PORT_CONFIG_EXTEND_VALUE \
ETH_SPAN_BPDU_PACKETS_AS_NORMAL | \
ETH_PARTITION_DISABLE
/* Default sdma control value */
#ifdef CONFIG_NOT_COHERENT_CACHE
#define PORT_SDMA_CONFIG_VALUE \
ETH_RX_BURST_SIZE_16_64BIT | \
GT_ETH_IPG_INT_RX(0) | \
ETH_TX_BURST_SIZE_16_64BIT;
#else
#define PORT_SDMA_CONFIG_VALUE \
ETH_RX_BURST_SIZE_4_64BIT | \
GT_ETH_IPG_INT_RX(0) | \
ETH_TX_BURST_SIZE_4_64BIT;
#endif
#define GT_ETH_IPG_INT_RX(value) \
((value & 0x3fff) << 8)
/* Default port serial control value */
#define PORT_SERIAL_CONTROL_VALUE \
ETH_FORCE_LINK_PASS | \
ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \
ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
ETH_ADV_SYMMETRIC_FLOW_CTRL | \
ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
ETH_FORCE_BP_MODE_NO_JAM | \
BIT9 | \
ETH_DO_NOT_FORCE_LINK_FAIL | \
ETH_RETRANSMIT_16_ETTEMPTS | \
ETH_ENABLE_AUTO_NEG_SPEED_GMII | \
ETH_DTE_ADV_0 | \
ETH_DISABLE_AUTO_NEG_BYPASS | \
ETH_AUTO_NEG_NO_CHANGE | \
ETH_MAX_RX_PACKET_1552BYTE | \
ETH_CLR_EXT_LOOPBACK | \
ETH_SET_FULL_DUPLEX_MODE | \
ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX;
#define RX_BUFFER_MAX_SIZE 0xFFFF
#define TX_BUFFER_MAX_SIZE 0xFFFF /* Buffer are limited to 64k */
#define RX_BUFFER_MIN_SIZE 0x8
#define TX_BUFFER_MIN_SIZE 0x8
/* Tx WRR confoguration macros */
#define PORT_MAX_TRAN_UNIT 0x24 /* MTU register (default) 9KByte */
#define PORT_MAX_TOKEN_BUCKET_SIZE 0x_fFFF /* PMTBS register (default) */
#define PORT_TOKEN_RATE 1023 /* PTTBRC register (default) */
/* MAC accepet/reject macros */
#define ACCEPT_MAC_ADDR 0
#define REJECT_MAC_ADDR 1
/* Size of a Tx/Rx descriptor used in chain list data structure */
#define RX_DESC_ALIGNED_SIZE 0x20
#define TX_DESC_ALIGNED_SIZE 0x20
/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
#define TX_BUF_OFFSET_IN_DESC 0x18
/* Buffer offset from buffer pointer */
#define RX_BUF_OFFSET 0x2
/* Gap define */
#define ETH_BAR_GAP 0x8
#define ETH_SIZE_REG_GAP 0x8
#define ETH_HIGH_ADDR_REMAP_REG_GAP 0x4
#define ETH_PORT_ACCESS_CTRL_GAP 0x4
/* Gigabit Ethernet Unit Global Registers */
/* MIB Counters register definitions */
#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
#define ETH_MIB_FRAMES_64_OCTETS 0x20
#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
#define ETH_MIB_GOOD_FRAMES_SENT 0x40
#define ETH_MIB_EXCESSIVE_COLLISION 0x44
#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
#define ETH_MIB_FC_SENT 0x54
#define ETH_MIB_GOOD_FC_RECEIVED 0x58
#define ETH_MIB_BAD_FC_RECEIVED 0x5c
#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
#define ETH_MIB_OVERSIZE_RECEIVED 0x68
#define ETH_MIB_JABBER_RECEIVED 0x6c
#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
#define ETH_MIB_BAD_CRC_EVENT 0x74
#define ETH_MIB_COLLISION 0x78
#define ETH_MIB_LATE_COLLISION 0x7c
/* Port serial status reg (PSR) */
#define ETH_INTERFACE_GMII_MII 0
#define ETH_INTERFACE_PCM BIT0
#define ETH_LINK_IS_DOWN 0
#define ETH_LINK_IS_UP BIT1
#define ETH_PORT_AT_HALF_DUPLEX 0
#define ETH_PORT_AT_FULL_DUPLEX BIT2
#define ETH_RX_FLOW_CTRL_DISABLED 0
#define ETH_RX_FLOW_CTRL_ENBALED BIT3
#define ETH_GMII_SPEED_100_10 0
#define ETH_GMII_SPEED_1000 BIT4
#define ETH_MII_SPEED_10 0
#define ETH_MII_SPEED_100 BIT5
#define ETH_NO_TX 0
#define ETH_TX_IN_PROGRESS BIT7
#define ETH_BYPASS_NO_ACTIVE 0
#define ETH_BYPASS_ACTIVE BIT8
#define ETH_PORT_NOT_AT_PARTITION_STATE 0
#define ETH_PORT_AT_PARTITION_STATE BIT9
#define ETH_PORT_TX_FIFO_NOT_EMPTY 0
#define ETH_PORT_TX_FIFO_EMPTY BIT10
/* These macros describes the Port configuration reg (Px_cR) bits */
#define ETH_UNICAST_NORMAL_MODE 0
#define ETH_UNICAST_PROMISCUOUS_MODE BIT0
#define ETH_DEFAULT_RX_QUEUE_0 0
#define ETH_DEFAULT_RX_QUEUE_1 BIT1
#define ETH_DEFAULT_RX_QUEUE_2 BIT2
#define ETH_DEFAULT_RX_QUEUE_3 (BIT2 | BIT1)
#define ETH_DEFAULT_RX_QUEUE_4 BIT3
#define ETH_DEFAULT_RX_QUEUE_5 (BIT3 | BIT1)
#define ETH_DEFAULT_RX_QUEUE_6 (BIT3 | BIT2)
#define ETH_DEFAULT_RX_QUEUE_7 (BIT3 | BIT2 | BIT1)
#define ETH_DEFAULT_RX_ARP_QUEUE_0 0
#define ETH_DEFAULT_RX_ARP_QUEUE_1 BIT4
#define ETH_DEFAULT_RX_ARP_QUEUE_2 BIT5
#define ETH_DEFAULT_RX_ARP_QUEUE_3 (BIT5 | BIT4)
#define ETH_DEFAULT_RX_ARP_QUEUE_4 BIT6
#define ETH_DEFAULT_RX_ARP_QUEUE_5 (BIT6 | BIT4)
#define ETH_DEFAULT_RX_ARP_QUEUE_6 (BIT6 | BIT5)
#define ETH_DEFAULT_RX_ARP_QUEUE_7 (BIT6 | BIT5 | BIT4)
#define ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP 0
#define ETH_REJECT_BC_IF_NOT_IP_OR_ARP BIT7
#define ETH_RECEIVE_BC_IF_IP 0
#define ETH_REJECT_BC_IF_IP BIT8
#define ETH_RECEIVE_BC_IF_ARP 0
#define ETH_REJECT_BC_IF_ARP BIT9
#define ETH_TX_AM_NO_UPDATE_ERROR_SUMMARY BIT12
#define ETH_CAPTURE_TCP_FRAMES_DIS 0
#define ETH_CAPTURE_TCP_FRAMES_EN BIT14
#define ETH_CAPTURE_UDP_FRAMES_DIS 0
#define ETH_CAPTURE_UDP_FRAMES_EN BIT15
#define ETH_DEFAULT_RX_TCP_QUEUE_0 0
#define ETH_DEFAULT_RX_TCP_QUEUE_1 BIT16
#define ETH_DEFAULT_RX_TCP_QUEUE_2 BIT17
#define ETH_DEFAULT_RX_TCP_QUEUE_3 (BIT17 | BIT16)
#define ETH_DEFAULT_RX_TCP_QUEUE_4 BIT18
#define ETH_DEFAULT_RX_TCP_QUEUE_5 (BIT18 | BIT16)
#define ETH_DEFAULT_RX_TCP_QUEUE_6 (BIT18 | BIT17)
#define ETH_DEFAULT_RX_TCP_QUEUE_7 (BIT18 | BIT17 | BIT16)
#define ETH_DEFAULT_RX_UDP_QUEUE_0 0
#define ETH_DEFAULT_RX_UDP_QUEUE_1 BIT19
#define ETH_DEFAULT_RX_UDP_QUEUE_2 BIT20
#define ETH_DEFAULT_RX_UDP_QUEUE_3 (BIT20 | BIT19)
#define ETH_DEFAULT_RX_UDP_QUEUE_4 (BIT21
#define ETH_DEFAULT_RX_UDP_QUEUE_5 (BIT21 | BIT19)
#define ETH_DEFAULT_RX_UDP_QUEUE_6 (BIT21 | BIT20)
#define ETH_DEFAULT_RX_UDP_QUEUE_7 (BIT21 | BIT20 | BIT19)
#define ETH_DEFAULT_RX_BPDU_QUEUE_0 0
#define ETH_DEFAULT_RX_BPDU_QUEUE_1 BIT22
#define ETH_DEFAULT_RX_BPDU_QUEUE_2 BIT23
#define ETH_DEFAULT_RX_BPDU_QUEUE_3 (BIT23 | BIT22)
#define ETH_DEFAULT_RX_BPDU_QUEUE_4 BIT24
#define ETH_DEFAULT_RX_BPDU_QUEUE_5 (BIT24 | BIT22)
#define ETH_DEFAULT_RX_BPDU_QUEUE_6 (BIT24 | BIT23)
#define ETH_DEFAULT_RX_BPDU_QUEUE_7 (BIT24 | BIT23 | BIT22)
/* These macros describes the Port configuration extend reg (Px_cXR) bits*/
#define ETH_CLASSIFY_EN BIT0
#define ETH_SPAN_BPDU_PACKETS_AS_NORMAL 0
#define ETH_SPAN_BPDU_PACKETS_TO_RX_QUEUE_7 BIT1
#define ETH_PARTITION_DISABLE 0
#define ETH_PARTITION_ENABLE BIT2
/* Tx/Rx queue command reg (RQCR/TQCR)*/
#define ETH_QUEUE_0_ENABLE BIT0
#define ETH_QUEUE_1_ENABLE BIT1
#define ETH_QUEUE_2_ENABLE BIT2
#define ETH_QUEUE_3_ENABLE BIT3
#define ETH_QUEUE_4_ENABLE BIT4
#define ETH_QUEUE_5_ENABLE BIT5
#define ETH_QUEUE_6_ENABLE BIT6
#define ETH_QUEUE_7_ENABLE BIT7
#define ETH_QUEUE_0_DISABLE BIT8
#define ETH_QUEUE_1_DISABLE BIT9
#define ETH_QUEUE_2_DISABLE BIT10
#define ETH_QUEUE_3_DISABLE BIT11
#define ETH_QUEUE_4_DISABLE BIT12
#define ETH_QUEUE_5_DISABLE BIT13
#define ETH_QUEUE_6_DISABLE BIT14
#define ETH_QUEUE_7_DISABLE BIT15
/* These macros describes the Port Sdma configuration reg (SDCR) bits */
#define ETH_RIFB BIT0
#define ETH_RX_BURST_SIZE_1_64BIT 0
#define ETH_RX_BURST_SIZE_2_64BIT BIT1
#define ETH_RX_BURST_SIZE_4_64BIT BIT2
#define ETH_RX_BURST_SIZE_8_64BIT (BIT2 | BIT1)
#define ETH_RX_BURST_SIZE_16_64BIT BIT3
#define ETH_BLM_RX_NO_SWAP BIT4
#define ETH_BLM_RX_BYTE_SWAP 0
#define ETH_BLM_TX_NO_SWAP BIT5
#define ETH_BLM_TX_BYTE_SWAP 0
#define ETH_DESCRIPTORS_BYTE_SWAP BIT6
#define ETH_DESCRIPTORS_NO_SWAP 0
#define ETH_TX_BURST_SIZE_1_64BIT 0
#define ETH_TX_BURST_SIZE_2_64BIT BIT22
#define ETH_TX_BURST_SIZE_4_64BIT BIT23
#define ETH_TX_BURST_SIZE_8_64BIT (BIT23 | BIT22)
#define ETH_TX_BURST_SIZE_16_64BIT BIT24
/* These macros describes the Port serial control reg (PSCR) bits */
#define ETH_SERIAL_PORT_DISABLE 0
#define ETH_SERIAL_PORT_ENABLE BIT0
#define ETH_FORCE_LINK_PASS BIT1
#define ETH_DO_NOT_FORCE_LINK_PASS 0
#define ETH_ENABLE_AUTO_NEG_FOR_DUPLX 0
#define ETH_DISABLE_AUTO_NEG_FOR_DUPLX BIT2
#define ETH_ENABLE_AUTO_NEG_FOR_FLOW_CTRL 0
#define ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL BIT3
#define ETH_ADV_NO_FLOW_CTRL 0
#define ETH_ADV_SYMMETRIC_FLOW_CTRL BIT4
#define ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX 0
#define ETH_FORCE_FC_MODE_TX_PAUSE_DIS BIT5
#define ETH_FORCE_BP_MODE_NO_JAM 0
#define ETH_FORCE_BP_MODE_JAM_TX BIT7
#define ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR BIT8
#define ETH_FORCE_LINK_FAIL 0
#define ETH_DO_NOT_FORCE_LINK_FAIL BIT10
#define ETH_RETRANSMIT_16_ETTEMPTS 0
#define ETH_RETRANSMIT_FOREVER BIT11
#define ETH_DISABLE_AUTO_NEG_SPEED_GMII BIT13
#define ETH_ENABLE_AUTO_NEG_SPEED_GMII 0
#define ETH_DTE_ADV_0 0
#define ETH_DTE_ADV_1 BIT14
#define ETH_DISABLE_AUTO_NEG_BYPASS 0
#define ETH_ENABLE_AUTO_NEG_BYPASS BIT15
#define ETH_AUTO_NEG_NO_CHANGE 0
#define ETH_RESTART_AUTO_NEG BIT16
#define ETH_MAX_RX_PACKET_1518BYTE 0
#define ETH_MAX_RX_PACKET_1522BYTE BIT17
#define ETH_MAX_RX_PACKET_1552BYTE BIT18
#define ETH_MAX_RX_PACKET_9022BYTE (BIT18 | BIT17)
#define ETH_MAX_RX_PACKET_9192BYTE BIT19
#define ETH_MAX_RX_PACKET_9700BYTE (BIT19 | BIT17)
#define ETH_SET_EXT_LOOPBACK BIT20
#define ETH_CLR_EXT_LOOPBACK 0
#define ETH_SET_FULL_DUPLEX_MODE BIT21
#define ETH_SET_HALF_DUPLEX_MODE 0
#define ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX BIT22
#define ETH_DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
#define ETH_SET_GMII_SPEED_TO_10_100 0
#define ETH_SET_GMII_SPEED_TO_1000 BIT23
#define ETH_SET_MII_SPEED_TO_10 0
#define ETH_SET_MII_SPEED_TO_100 BIT24
/* SMI reg */
#define ETH_SMI_BUSY BIT28 /* 0 - Write, 1 - Read */
#define ETH_SMI_READ_VALID BIT27 /* 0 - Write, 1 - Read */
#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read operation */
#define ETH_SMI_OPCODE_READ BIT26 /* Operation is in progress */
/* SDMA command status fields macros */
/* Tx & Rx descriptors status */
#define ETH_ERROR_SUMMARY (BIT0)
/* Tx & Rx descriptors command */
#define ETH_BUFFER_OWNED_BY_DMA (BIT31)
/* Tx descriptors status */
#define ETH_LC_ERROR (0 )
#define ETH_UR_ERROR (BIT1 )
#define ETH_RL_ERROR (BIT2 )
#define ETH_LLC_SNAP_FORMAT (BIT9 )
/* Rx descriptors status */
#define ETH_CRC_ERROR (0 )
#define ETH_OVERRUN_ERROR (BIT1 )
#define ETH_MAX_FRAME_LENGTH_ERROR (BIT2 )
#define ETH_RESOURCE_ERROR ((BIT2 | BIT1))
#define ETH_VLAN_TAGGED (BIT19)
#define ETH_BPDU_FRAME (BIT20)
#define ETH_TCP_FRAME_OVER_IP_V_4 (0 )
#define ETH_UDP_FRAME_OVER_IP_V_4 (BIT21)
#define ETH_OTHER_FRAME_TYPE (BIT22)
#define ETH_LAYER_2_IS_ETH_V_2 (BIT23)
#define ETH_FRAME_TYPE_IP_V_4 (BIT24)
#define ETH_FRAME_HEADER_OK (BIT25)
#define ETH_RX_LAST_DESC (BIT26)
#define ETH_RX_FIRST_DESC (BIT27)
#define ETH_UNKNOWN_DESTINATION_ADDR (BIT28)
#define ETH_RX_ENABLE_INTERRUPT (BIT29)
#define ETH_LAYER_4_CHECKSUM_OK (BIT30)
/* Rx descriptors byte count */
#define ETH_FRAME_FRAGMENTED (BIT2)
/* Tx descriptors command */
#define ETH_LAYER_4_CHECKSUM_FIRST_DESC (BIT10)
#define ETH_FRAME_SET_TO_VLAN (BIT15)
#define ETH_TCP_FRAME (0 )
#define ETH_UDP_FRAME (BIT16)
#define ETH_GEN_TCP_UDP_CHECKSUM (BIT17)
#define ETH_GEN_IP_V_4_CHECKSUM (BIT18)
#define ETH_ZERO_PADDING (BIT19)
#define ETH_TX_LAST_DESC (BIT20)
#define ETH_TX_FIRST_DESC (BIT21)
#define ETH_GEN_CRC (BIT22)
#define ETH_TX_ENABLE_INTERRUPT (BIT23)
#define ETH_AUTO_MODE (BIT30)
/* Address decode parameters */
/* Ethernet Base Address Register bits */
#define EBAR_TARGET_DRAM 0x00000000
#define EBAR_TARGET_DEVICE 0x00000001
#define EBAR_TARGET_CBS 0x00000002
#define EBAR_TARGET_PCI0 0x00000003
#define EBAR_TARGET_PCI1 0x00000004
#define EBAR_TARGET_CUNIT 0x00000005
#define EBAR_TARGET_AUNIT 0x00000006
#define EBAR_TARGET_GUNIT 0x00000007
/* Window attributes */
#define EBAR_ATTR_DRAM_CS0 0x00000E00
#define EBAR_ATTR_DRAM_CS1 0x00000D00
#define EBAR_ATTR_DRAM_CS2 0x00000B00
#define EBAR_ATTR_DRAM_CS3 0x00000700
/* DRAM Target interface */
#define EBAR_ATTR_DRAM_NO_CACHE_COHERENCY 0x00000000
#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WT 0x00001000
#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WB 0x00002000
/* Device Bus Target interface */
#define EBAR_ATTR_DEVICE_DEVCS0 0x00001E00
#define EBAR_ATTR_DEVICE_DEVCS1 0x00001D00
#define EBAR_ATTR_DEVICE_DEVCS2 0x00001B00
#define EBAR_ATTR_DEVICE_DEVCS3 0x00001700
#define EBAR_ATTR_DEVICE_BOOTCS3 0x00000F00
/* PCI Target interface */
#define EBAR_ATTR_PCI_BYTE_SWAP 0x00000000
#define EBAR_ATTR_PCI_NO_SWAP 0x00000100
#define EBAR_ATTR_PCI_BYTE_WORD_SWAP 0x00000200
#define EBAR_ATTR_PCI_WORD_SWAP 0x00000300
#define EBAR_ATTR_PCI_NO_SNOOP_NOT_ASSERT 0x00000000
#define EBAR_ATTR_PCI_NO_SNOOP_ASSERT 0x00000400
#define EBAR_ATTR_PCI_IO_SPACE 0x00000000
#define EBAR_ATTR_PCI_MEMORY_SPACE 0x00000800
#define EBAR_ATTR_PCI_REQ64_FORCE 0x00000000
#define EBAR_ATTR_PCI_REQ64_SIZE 0x00001000
/* CPU 60x bus or internal SRAM interface */
#define EBAR_ATTR_CBS_SRAM_BLOCK0 0x00000000
#define EBAR_ATTR_CBS_SRAM_BLOCK1 0x00000100
#define EBAR_ATTR_CBS_SRAM 0x00000000
#define EBAR_ATTR_CBS_CPU_BUS 0x00000800
/* Window access control */
#define EWIN_ACCESS_NOT_ALLOWED 0
#define EWIN_ACCESS_READ_ONLY BIT0
#define EWIN_ACCESS_FULL (BIT1 | BIT0)
#define EWIN0_ACCESS_MASK 0x0003
#define EWIN1_ACCESS_MASK 0x000C
#define EWIN2_ACCESS_MASK 0x0030
#define EWIN3_ACCESS_MASK 0x00C0
/* typedefs */
typedef enum _eth_port
{
ETH_0 = 0,
ETH_1 = 1,
ETH_2 = 2
}ETH_PORT;
typedef enum _eth_func_ret_status
{
ETH_OK, /* Returned as expected. */
ETH_ERROR, /* Fundamental error. */
ETH_RETRY, /* Could not process request. Try later. */
ETH_END_OF_JOB, /* Ring has nothing to process. */
ETH_QUEUE_FULL, /* Ring resource error. */
ETH_QUEUE_LAST_RESOURCE /* Ring resources about to exhaust. */
}ETH_FUNC_RET_STATUS;
typedef enum _eth_queue
{
ETH_Q0 = 0,
ETH_Q1 = 1,
ETH_Q2 = 2,
ETH_Q3 = 3,
ETH_Q4 = 4,
ETH_Q5 = 5,
ETH_Q6 = 6,
ETH_Q7 = 7
} ETH_QUEUE;
typedef enum _addr_win
{
ETH_WIN0,
ETH_WIN1,
ETH_WIN2,
ETH_WIN3,
ETH_WIN4,
ETH_WIN5
} ETH_ADDR_WIN;
typedef enum _eth_target
{
ETH_TARGET_DRAM ,
ETH_TARGET_DEVICE,
ETH_TARGET_CBS ,
ETH_TARGET_PCI0 ,
ETH_TARGET_PCI1
}ETH_TARGET;
typedef struct _eth_rx_desc
{
unsigned short byte_cnt ; /* Descriptor buffer byte count */
unsigned short buf_size ; /* Buffer size */
unsigned int cmd_sts ; /* Descriptor command status */
unsigned int next_desc_ptr; /* Next descriptor pointer */
unsigned int buf_ptr ; /* Descriptor buffer pointer */
unsigned int return_info ; /* User resource return information */
} ETH_RX_DESC;
typedef struct _eth_tx_desc
{
unsigned short byte_cnt ; /* Descriptor buffer byte count */
unsigned short l4i_chk ; /* CPU provided TCP Checksum */
unsigned int cmd_sts ; /* Descriptor command status */
unsigned int next_desc_ptr; /* Next descriptor pointer */
unsigned int buf_ptr ; /* Descriptor buffer pointer */
unsigned int return_info ; /* User resource return information */
} ETH_TX_DESC;
/* Unified struct for Rx and Tx operations. The user is not required to */
/* be familier with neither Tx nor Rx descriptors. */
typedef struct _pkt_info
{
unsigned short byte_cnt ; /* Descriptor buffer byte count */
unsigned short l4i_chk ; /* Tx CPU provided TCP Checksum */
unsigned int cmd_sts ; /* Descriptor command status */
unsigned int buf_ptr ; /* Descriptor buffer pointer */
unsigned int return_info ; /* User resource return information */
} PKT_INFO;
typedef struct _eth_win_param
{
ETH_ADDR_WIN win; /* Window number. See ETH_ADDR_WIN enum */
ETH_TARGET target; /* System targets. See ETH_TARGET enum */
unsigned short attributes; /* BAR attributes. See above macros. */
unsigned int base_addr; /* Window base address in unsigned int form */
unsigned int high_addr; /* Window high address in unsigned int form */
unsigned int size; /* Size in MBytes. Must be % 64Kbyte. */
bool enable; /* Enable/disable access to the window. */
unsigned short access_ctrl; /* Access ctrl register. see above macros */
} ETH_WIN_PARAM;
/* Ethernet port specific infomation */
typedef struct _eth_port_ctrl
{
ETH_PORT port_num; /* User Ethernet port number */
int port_phy_addr; /* User phy address of Ethrnet port */
unsigned char port_mac_addr[6]; /* User defined port MAC address. */
unsigned int port_config; /* User port configuration value */
unsigned int port_config_extend; /* User port config extend value */
unsigned int port_sdma_config; /* User port SDMA config value */
unsigned int port_serial_control; /* User port serial control value */
unsigned int port_tx_queue_command; /* Port active Tx queues summary */
unsigned int port_rx_queue_command; /* Port active Rx queues summary */
/* User function to cast virtual address to CPU bus address */
unsigned int (*port_virt_to_phys)(unsigned int addr);
/* User scratch pad for user specific data structures */
void *port_private;
bool rx_resource_err[MAX_RX_QUEUE_NUM]; /* Rx ring resource error flag */
bool tx_resource_err[MAX_TX_QUEUE_NUM]; /* Tx ring resource error flag */
/* Tx/Rx rings managment indexes fields. For driver use */
/* Next available Rx resource */
volatile ETH_RX_DESC *p_rx_curr_desc_q[MAX_RX_QUEUE_NUM];
/* Returning Rx resource */
volatile ETH_RX_DESC *p_rx_used_desc_q[MAX_RX_QUEUE_NUM];
/* Next available Tx resource */
volatile ETH_TX_DESC *p_tx_curr_desc_q[MAX_TX_QUEUE_NUM];
/* Returning Tx resource */
volatile ETH_TX_DESC *p_tx_used_desc_q[MAX_TX_QUEUE_NUM];
/* An extra Tx index to support transmit of multiple buffers per packet */
volatile ETH_TX_DESC *p_tx_first_desc_q[MAX_TX_QUEUE_NUM];
/* Tx/Rx rings size and base variables fields. For driver use */
volatile ETH_RX_DESC *p_rx_desc_area_base[MAX_RX_QUEUE_NUM];
unsigned int rx_desc_area_size[MAX_RX_QUEUE_NUM];
char *p_rx_buffer_base[MAX_RX_QUEUE_NUM];
volatile ETH_TX_DESC *p_tx_desc_area_base[MAX_TX_QUEUE_NUM];
unsigned int tx_desc_area_size[MAX_TX_QUEUE_NUM];
char *p_tx_buffer_base[MAX_TX_QUEUE_NUM];
} ETH_PORT_INFO;
/* ethernet.h API list */
/* Port operation control routines */
static void eth_port_init (ETH_PORT_INFO *p_eth_port_ctrl);
static void eth_port_reset(ETH_PORT eth_port_num);
static bool eth_port_start(ETH_PORT_INFO *p_eth_port_ctrl);
/* Port MAC address routines */
static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
unsigned char *p_addr,
ETH_QUEUE queue);
#if 0 /* FIXME */
static void eth_port_mc_addr (ETH_PORT eth_port_num,
unsigned char *p_addr,
ETH_QUEUE queue,
int option);
#endif
/* PHY and MIB routines */
static bool ethernet_phy_reset(ETH_PORT eth_port_num);
static bool eth_port_write_smi_reg(ETH_PORT eth_port_num,
unsigned int phy_reg,
unsigned int value);
static bool eth_port_read_smi_reg(ETH_PORT eth_port_num,
unsigned int phy_reg,
unsigned int* value);
static void eth_clear_mib_counters(ETH_PORT eth_port_num);
/* Port data flow control routines */
static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE tx_queue,
PKT_INFO *p_pkt_info);
static ETH_FUNC_RET_STATUS eth_tx_return_desc(ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE tx_queue,
PKT_INFO *p_pkt_info);
static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE rx_queue,
PKT_INFO *p_pkt_info);
static ETH_FUNC_RET_STATUS eth_rx_return_buff(ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE rx_queue,
PKT_INFO *p_pkt_info);
static bool ether_init_tx_desc_ring(ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE tx_queue,
int tx_desc_num,
int tx_buff_size,
unsigned int tx_desc_base_addr,
unsigned int tx_buff_base_addr);
static bool ether_init_rx_desc_ring(ETH_PORT_INFO *p_eth_port_ctrl,
ETH_QUEUE rx_queue,
int rx_desc_num,
int rx_buff_size,
unsigned int rx_desc_base_addr,
unsigned int rx_buff_base_addr);
#endif /* MV64460_ETH_ */

File diff suppressed because it is too large Load diff

809
board/prodrive/p3mx/p3mx.c Normal file
View file

@ -0,0 +1,809 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* Based on original work by
* Roel Loeffen, (C) Copyright 2006 Prodrive B.V.
* Josh Huber, (C) Copyright 2001 Mission Critical Linux, Inc.
*
* 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
*
* modifications for the DB64360 eval board based by Ingo.Assmus@keymile.com
* modifications for the cpci750 by reinhard.arlt@esd-electronics.com
* modifications for the P3M750 by roel.loeffen@prodrive.nl
*/
/*
* p3m750.c - main board support/init for the Prodrive p3m750/p3m7448.
*/
#include <common.h>
#include <74xx_7xx.h>
#include "../../Marvell/include/memory.h"
#include "../../Marvell/include/pci.h"
#include "../../Marvell/include/mv_gen_reg.h"
#include <net.h>
#include <i2c.h>
#include "eth.h"
#include "mpsc.h"
#include "64460.h"
#include "mv_regs.h"
DECLARE_GLOBAL_DATA_PTR;
#undef DEBUG
/*#define DEBUG */
#ifdef CONFIG_PCI
#define MAP_PCI
#endif /* of CONFIG_PCI */
#ifdef DEBUG
#define DP(x) x
#else
#define DP(x)
#endif
extern void flush_data_cache (void);
extern void invalidate_l1_instruction_cache (void);
extern flash_info_t flash_info[];
/* ------------------------------------------------------------------------- */
/* this is the current GT register space location */
/* it starts at CFG_DFL_GT_REGS but moves later to CFG_GT_REGS */
/* Unfortunately, we cant change it while we are in flash, so we initialize it
* to the "final" value. This means that any debug_led calls before
* board_early_init_f wont work right (like in cpu_init_f).
* See also my_remap_gt_regs below. (NTL)
*/
void board_prebootm_init (void);
unsigned int INTERNAL_REG_BASE_ADDR = CFG_GT_REGS;
int display_mem_map (void);
/* ------------------------------------------------------------------------- */
/*
* This is a version of the GT register space remapping function that
* doesn't touch globals (meaning, it's ok to run from flash.)
*
* Unfortunately, this has the side effect that a writable
* INTERNAL_REG_BASE_ADDR is impossible. Oh well.
*/
void my_remap_gt_regs (u32 cur_loc, u32 new_loc)
{
u32 temp;
/* check and see if it's already moved */
temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE));
if ((temp & 0xffff) == new_loc >> 16)
return;
temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) &
0xffff0000) | (new_loc >> 16);
out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp);
while (GTREGREAD (INTERNAL_SPACE_DECODE) != temp);
}
#ifdef CONFIG_PCI
static void gt_pci_config (void)
{
unsigned int stat;
unsigned int val = 0x00fff864; /* DINK32: BusNum 23:16, DevNum 15:11, */
/* FuncNum 10:8, RegNum 7:2 */
/*
* In PCIX mode devices provide their own bus and device numbers.
* We query the Discovery II's
* config registers by writing ones to the bus and device.
* We then update the Virtual register with the correct value for the
* bus and device.
*/
if ((GTREGREAD (PCI_0_MODE) & (BIT4 | BIT5)) != 0) { /* if PCI-X */
GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val);
GT_REG_READ (PCI_0_CONFIG_DATA_VIRTUAL_REG, &stat);
GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val);
GT_REG_WRITE (PCI_0_CONFIG_DATA_VIRTUAL_REG,
(stat & 0xffff0000) | CFG_PCI_IDSEL);
}
if ((GTREGREAD (PCI_1_MODE) & (BIT4 | BIT5)) != 0) { /* if PCI-X */
GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val);
GT_REG_READ (PCI_1_CONFIG_DATA_VIRTUAL_REG, &stat);
GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val);
GT_REG_WRITE (PCI_1_CONFIG_DATA_VIRTUAL_REG,
(stat & 0xffff0000) | CFG_PCI_IDSEL);
}
/* Enable master */
PCI_MASTER_ENABLE (0, SELF);
PCI_MASTER_ENABLE (1, SELF);
/* Enable PCI0/1 Mem0 and IO 0 disable all others */
GT_REG_READ (BASE_ADDR_ENABLE, &stat);
stat |= (1 << 11) | (1 << 12) | (1 << 13) | (1 << 16) | (1 << 17) |
(1 << 18);
stat &= ~((1 << 9) | (1 << 10) | (1 << 14) | (1 << 15));
GT_REG_WRITE (BASE_ADDR_ENABLE, stat);
/* ronen:
* add write to pci remap registers for 64460.
* in 64360 when writing to pci base go and overide remap automaticaly,
* in 64460 it doesn't
*/
GT_REG_WRITE (PCI_0_IO_BASE_ADDR, CFG_PCI0_IO_SPACE >> 16);
GT_REG_WRITE (PCI_0I_O_ADDRESS_REMAP, CFG_PCI0_IO_SPACE_PCI >> 16);
GT_REG_WRITE (PCI_0_IO_SIZE, (CFG_PCI0_IO_SIZE - 1) >> 16);
GT_REG_WRITE (PCI_0_MEMORY0_BASE_ADDR, CFG_PCI0_MEM_BASE >> 16);
GT_REG_WRITE (PCI_0MEMORY0_ADDRESS_REMAP, CFG_PCI0_MEM_BASE >> 16);
GT_REG_WRITE (PCI_0_MEMORY0_SIZE, (CFG_PCI0_MEM_SIZE - 1) >> 16);
GT_REG_WRITE (PCI_1_IO_BASE_ADDR, CFG_PCI1_IO_SPACE >> 16);
GT_REG_WRITE (PCI_1I_O_ADDRESS_REMAP, CFG_PCI1_IO_SPACE_PCI >> 16);
GT_REG_WRITE (PCI_1_IO_SIZE, (CFG_PCI1_IO_SIZE - 1) >> 16);
GT_REG_WRITE (PCI_1_MEMORY0_BASE_ADDR, CFG_PCI1_MEM_BASE >> 16);
GT_REG_WRITE (PCI_1MEMORY0_ADDRESS_REMAP, CFG_PCI1_MEM_BASE >> 16);
GT_REG_WRITE (PCI_1_MEMORY0_SIZE, (CFG_PCI1_MEM_SIZE - 1) >> 16);
/* PCI interface settings */
/* Timeout set to retry forever */
GT_REG_WRITE (PCI_0TIMEOUT_RETRY, 0x0);
GT_REG_WRITE (PCI_1TIMEOUT_RETRY, 0x0);
/* ronen - enable only CS0 and Internal reg!! */
GT_REG_WRITE (PCI_0BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe);
GT_REG_WRITE (PCI_1BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe);
/* ronen:
* update the pci internal registers base address.
*/
#ifdef MAP_PCI
for (stat = 0; stat <= PCI_HOST1; stat++)
pciWriteConfigReg (stat,
PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
SELF, CFG_GT_REGS);
#endif
}
#endif
/* Setup CPU interface paramaters */
static void gt_cpu_config (void)
{
cpu_t cpu = get_cpu_type ();
ulong tmp;
/* cpu configuration register */
tmp = GTREGREAD (CPU_CONFIGURATION);
/* set the SINGLE_CPU bit see MV64460 */
#ifndef CFG_GT_DUAL_CPU /* SINGLE_CPU seems to cause JTAG problems */
tmp |= CPU_CONF_SINGLE_CPU;
#endif
tmp &= ~CPU_CONF_AACK_DELAY_2;
tmp |= CPU_CONF_DP_VALID;
tmp |= CPU_CONF_AP_VALID;
tmp |= CPU_CONF_PIPELINE;
GT_REG_WRITE (CPU_CONFIGURATION, tmp); /* Marvell (VXWorks) writes 0x20220FF */
/* CPU master control register */
tmp = GTREGREAD (CPU_MASTER_CONTROL);
tmp |= CPU_MAST_CTL_ARB_EN;
if ((cpu == CPU_7400) ||
(cpu == CPU_7410) || (cpu == CPU_7455) || (cpu == CPU_7450)) {
tmp |= CPU_MAST_CTL_CLEAN_BLK;
tmp |= CPU_MAST_CTL_FLUSH_BLK;
} else {
/* cleanblock must be cleared for CPUs
* that do not support this command (603e, 750)
* see Res#1 */
tmp &= ~CPU_MAST_CTL_CLEAN_BLK;
tmp &= ~CPU_MAST_CTL_FLUSH_BLK;
}
GT_REG_WRITE (CPU_MASTER_CONTROL, tmp);
}
/*
* board_early_init_f.
*
* set up gal. device mappings, etc.
*/
int board_early_init_f (void)
{
/* set up the GT the way the kernel wants it
* the call to move the GT register space will obviously
* fail if it has already been done, but we're going to assume
* that if it's not at the power-on location, it's where we put
* it last time. (huber)
*/
my_remap_gt_regs (CFG_DFL_GT_REGS, CFG_GT_REGS);
#ifdef CONFIG_PCI
gt_pci_config ();
#endif
/* mask all external interrupt sources */
GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_LOW, 0);
GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_HIGH, 0);
/* new in >MV6436x */
GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_LOW, 0);
GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_HIGH, 0);
/* --------------------- */
GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
/* Device and Boot bus settings
*/
memoryMapDeviceSpace(DEVICE0, 0, 0);
GT_REG_WRITE(DEVICE_BANK0PARAMETERS, 0);
memoryMapDeviceSpace(DEVICE1, 0, 0);
GT_REG_WRITE(DEVICE_BANK1PARAMETERS, 0);
memoryMapDeviceSpace(DEVICE2, 0, 0);
GT_REG_WRITE(DEVICE_BANK2PARAMETERS, 0);
memoryMapDeviceSpace(DEVICE3, 0, 0);
GT_REG_WRITE(DEVICE_BANK3PARAMETERS, 0);
GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_BOOT_PAR);
gt_cpu_config();
/* MPP setup */
GT_REG_WRITE (MPP_CONTROL0, CFG_MPP_CONTROL_0);
GT_REG_WRITE (MPP_CONTROL1, CFG_MPP_CONTROL_1);
GT_REG_WRITE (MPP_CONTROL2, CFG_MPP_CONTROL_2);
GT_REG_WRITE (MPP_CONTROL3, CFG_MPP_CONTROL_3);
GT_REG_WRITE (GPP_LEVEL_CONTROL, CFG_GPP_LEVEL_CONTROL);
return 0;
}
/* various things to do after relocation */
int misc_init_r ()
{
u8 val;
icache_enable ();
#ifdef CFG_L2
l2cache_enable ();
#endif
#ifdef CONFIG_MPSC
mpsc_sdma_init ();
mpsc_init2 ();
#endif
/*
* Enable trickle changing in RTC upon powerup
* No diode, 250 ohm series resistor
*/
val = 0xa5;
i2c_write(CFG_I2C_RTC_ADDR, 8, 1, &val, 1);
return 0;
}
int board_early_init_r(void)
{
/* now relocate the debug serial driver */
mpsc_putchar += gd->reloc_off;
mpsc_getchar += gd->reloc_off;
mpsc_test_char += gd->reloc_off;
return 0;
}
void after_reloc (ulong dest_addr, gd_t * gd)
{
memoryMapDeviceSpace (BOOT_DEVICE, CFG_BOOT_SPACE, CFG_BOOT_SIZE);
/* display_mem_map(); */
/* now, jump to the main U-Boot board init code */
board_init_r (gd, dest_addr);
/* NOTREACHED */
}
/*
* Check Board Identity:
* right now, assume borad type. (there is just one...after all)
*/
int checkboard (void)
{
char *s = getenv("serial#");
printf("Board: %s", CFG_BOARD_NAME);
if (s != NULL) {
puts(", serial# ");
puts(s);
}
putc('\n');
return (0);
}
/* utility functions */
void debug_led (int led, int mode)
{
}
int display_mem_map (void)
{
int i, j;
unsigned int base, size, width;
/* SDRAM */
printf ("SD (DDR) RAM\n");
for (i = 0; i <= BANK3; i++) {
base = memoryGetBankBaseAddress (i);
size = memoryGetBankSize (i);
if (size != 0)
printf ("BANK%d: base - 0x%08x\tsize - %dM bytes\n",
i, base, size >> 20);
}
#ifdef CONFIG_PCI
/* CPU's PCI windows */
for (i = 0; i <= PCI_HOST1; i++) {
printf ("\nCPU's PCI %d windows\n", i);
base = pciGetSpaceBase (i, PCI_IO);
size = pciGetSpaceSize (i, PCI_IO);
printf (" IO: base - 0x%08x\tsize - %dM bytes\n", base,
size >> 20);
/* ronen currently only first PCI MEM is used 3 */
for (j = 0; j <= PCI_REGION0; j++) {
base = pciGetSpaceBase (i, j);
size = pciGetSpaceSize (i, j);
printf ("MEMORY %d: base - 0x%08x\tsize - %dM bytes\n",
j, base, size >> 20);
}
}
#endif /* of CONFIG_PCI */
/* Bootrom */
base = memoryGetDeviceBaseAddress (BOOT_DEVICE); /* Boot */
size = memoryGetDeviceSize (BOOT_DEVICE);
width = memoryGetDeviceWidth (BOOT_DEVICE) * 8;
printf (" BOOT: base - 0x%08x size - %dM bytes\twidth - %d bits\t- FLASH\n",
base, size >> 20, width);
return (0);
}
/* DRAM check routines copied from gw8260 */
#if defined (CFG_DRAM_TEST)
/*********************************************************************/
/* NAME: move64() - moves a double word (64-bit) */
/* */
/* DESCRIPTION: */
/* this function performs a double word move from the data at */
/* the source pointer to the location at the destination pointer. */
/* */
/* INPUTS: */
/* unsigned long long *src - pointer to data to move */
/* */
/* OUTPUTS: */
/* unsigned long long *dest - pointer to locate to move data */
/* */
/* RETURNS: */
/* None */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* May cloober fr0. */
/* */
/*********************************************************************/
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 */
return;
}
#if defined (CFG_DRAM_TEST_DATA)
unsigned long long pattern[] = {
0xaaaaaaaaaaaaaaaaULL,
0xccccccccccccccccULL,
0xf0f0f0f0f0f0f0f0ULL,
0xff00ff00ff00ff00ULL,
0xffff0000ffff0000ULL,
0xffffffff00000000ULL,
0x00000000ffffffffULL,
0x0000ffff0000ffffULL,
0x00ff00ff00ff00ffULL,
0x0f0f0f0f0f0f0f0fULL,
0x3333333333333333ULL,
0x5555555555555555ULL
};
/*********************************************************************/
/* NAME: mem_test_data() - test data lines for shorts and opens */
/* */
/* DESCRIPTION: */
/* Tests data lines for shorts and opens by forcing adjacent data */
/* to opposite states. Because the data lines could be routed in */
/* an arbitrary manner the must ensure test patterns ensure that */
/* every case is tested. By using the following series of binary */
/* patterns every combination of adjacent bits is test regardless */
/* of routing. */
/* */
/* ...101010101010101010101010 */
/* ...110011001100110011001100 */
/* ...111100001111000011110000 */
/* ...111111110000000011111111 */
/* */
/* Carrying this out, gives us six hex patterns as follows: */
/* */
/* 0xaaaaaaaaaaaaaaaa */
/* 0xcccccccccccccccc */
/* 0xf0f0f0f0f0f0f0f0 */
/* 0xff00ff00ff00ff00 */
/* 0xffff0000ffff0000 */
/* 0xffffffff00000000 */
/* */
/* The number test patterns will always be given by: */
/* */
/* log(base 2)(number data bits) = log2 (64) = 6 */
/* */
/* To test for short and opens to other signals on our boards. we */
/* simply */
/* test with the 1's complemnt of the paterns as well. */
/* */
/* OUTPUTS: */
/* Displays failing test pattern */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* Assumes only one one SDRAM bank */
/* */
/*********************************************************************/
int mem_test_data (void)
{
unsigned long long *pmem = (unsigned long long *) CFG_MEMTEST_START;
unsigned long long temp64 = 0;
int num_patterns = sizeof (pattern) / sizeof (pattern[0]);
int i;
unsigned int hi, lo;
for (i = 0; i < num_patterns; i++) {
move64 (&(pattern[i]), pmem);
move64 (pmem, &temp64);
/* hi = (temp64>>32) & 0xffffffff; */
/* lo = temp64 & 0xffffffff; */
/* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
hi = (pattern[i] >> 32) & 0xffffffff;
lo = pattern[i] & 0xffffffff;
/* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
if (temp64 != pattern[i]) {
printf ("\n Data Test Failed, pattern 0x%08x%08x",
hi, lo);
return 1;
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_DATA */
#if defined (CFG_DRAM_TEST_ADDRESS)
/*********************************************************************/
/* NAME: mem_test_address() - test address lines */
/* */
/* DESCRIPTION: */
/* This function performs a test to verify that each word im */
/* memory is uniquly addressable. The test sequence is as follows: */
/* */
/* 1) write the address of each word to each word. */
/* 2) verify that each location equals its address */
/* */
/* OUTPUTS: */
/* Displays failing test pattern and address */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_test_address (void)
{
volatile unsigned int *pmem =
(volatile unsigned int *) CFG_MEMTEST_START;
const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 4;
unsigned int i;
/* write address to each location */
for (i = 0; i < size; i++)
pmem[i] = i;
/* verify each loaction */
for (i = 0; i < size; i++) {
if (pmem[i] != i) {
printf ("\n Address Test Failed at 0x%x", i);
return 1;
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_ADDRESS */
#if defined (CFG_DRAM_TEST_WALK)
/*********************************************************************/
/* NAME: mem_march() - memory march */
/* */
/* DESCRIPTION: */
/* Marches up through memory. At each location verifies rmask if */
/* read = 1. At each location write wmask if write = 1. Displays */
/* failing address and pattern. */
/* */
/* INPUTS: */
/* volatile unsigned long long * base - start address of test */
/* unsigned int size - number of dwords(64-bit) to test */
/* unsigned long long rmask - read verify mask */
/* unsigned long long wmask - wrtie verify mask */
/* short read - verifies rmask if read = 1 */
/* short write - writes wmask if write = 1 */
/* */
/* OUTPUTS: */
/* Displays failing test pattern and address */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_march (volatile unsigned long long *base,
unsigned int size,
unsigned long long rmask,
unsigned long long wmask, short read, short write)
{
unsigned int i;
unsigned long long temp = 0;
unsigned int hitemp, lotemp, himask, lomask;
for (i = 0; i < size; i++) {
if (read != 0) {
/* temp = base[i]; */
move64 ((unsigned long long *) &(base[i]), &temp);
if (rmask != temp) {
hitemp = (temp >> 32) & 0xffffffff;
lotemp = temp & 0xffffffff;
himask = (rmask >> 32) & 0xffffffff;
lomask = rmask & 0xffffffff;
printf ("\n Walking one's test failed: address = 0x%08x," "\n\texpected 0x%08x%08x, found 0x%08x%08x", i << 3, himask, lomask, hitemp, lotemp);
return 1;
}
}
if (write != 0) {
/* base[i] = wmask; */
move64 (&wmask, (unsigned long long *) &(base[i]));
}
}
return 0;
}
#endif /* CFG_DRAM_TEST_WALK */
/*********************************************************************/
/* NAME: mem_test_walk() - a simple walking ones test */
/* */
/* DESCRIPTION: */
/* Performs a walking ones through entire physical memory. The */
/* test uses as series of memory marches, mem_march(), to verify */
/* and write the test patterns to memory. The test sequence is as */
/* follows: */
/* 1) march writing 0000...0001 */
/* 2) march verifying 0000...0001 , writing 0000...0010 */
/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
/* the write mask equals 1000...0000 */
/* 4) march verifying 1000...0000 */
/* The test fails if any of the memory marches return a failure. */
/* */
/* OUTPUTS: */
/* Displays which pass on the memory test is executing */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int mem_test_walk (void)
{
unsigned long long mask;
volatile unsigned long long *pmem =
(volatile unsigned long long *) CFG_MEMTEST_START;
const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 8;
unsigned int i;
mask = 0x01;
printf ("Initial Pass");
mem_march (pmem, size, 0x0, 0x1, 0, 1);
printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
printf (" ");
printf (" ");
printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
for (i = 0; i < 63; i++) {
printf ("Pass %2d", i + 2);
if (mem_march (pmem, size, mask, mask << 1, 1, 1) != 0) {
/*printf("mask: 0x%x, pass: %d, ", mask, i); */
return 1;
}
mask = mask << 1;
printf ("\b\b\b\b\b\b\b");
}
printf ("Last Pass");
if (mem_march (pmem, size, 0, mask, 0, 1) != 0) {
/* printf("mask: 0x%x", mask); */
return 1;
}
printf ("\b\b\b\b\b\b\b\b\b");
printf (" ");
printf ("\b\b\b\b\b\b\b\b\b");
return 0;
}
/*********************************************************************/
/* NAME: testdram() - calls any enabled memory tests */
/* */
/* DESCRIPTION: */
/* Runs memory tests if the environment test variables are set to */
/* 'y'. */
/* */
/* INPUTS: */
/* testdramdata - If set to 'y', data test is run. */
/* testdramaddress - If set to 'y', address test is run. */
/* testdramwalk - If set to 'y', walking ones test is run */
/* */
/* OUTPUTS: */
/* None */
/* */
/* RETURNS: */
/* 0 - Passed test */
/* 1 - Failed test */
/* */
/* RESTRICTIONS/LIMITATIONS: */
/* */
/* */
/*********************************************************************/
int testdram (void)
{
char *s;
int rundata = 0;
int runaddress = 0;
int runwalk = 0;
#ifdef CFG_DRAM_TEST_DATA
s = getenv ("testdramdata");
rundata = (s && (*s == 'y')) ? 1 : 0;
#endif
#ifdef CFG_DRAM_TEST_ADDRESS
s = getenv ("testdramaddress");
runaddress = (s && (*s == 'y')) ? 1 : 0;
#endif
#ifdef CFG_DRAM_TEST_WALK
s = getenv ("testdramwalk");
runwalk = (s && (*s == 'y')) ? 1 : 0;
#endif
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1))
printf ("Testing RAM from 0x%08x to 0x%08x ... "
"(don't panic... that will take a moment !!!!)\n",
CFG_MEMTEST_START, CFG_MEMTEST_END);
#ifdef CFG_DRAM_TEST_DATA
if (rundata == 1) {
printf ("Test DATA ... ");
if (mem_test_data () == 1) {
printf ("failed \n");
return 1;
} else
printf ("ok \n");
}
#endif
#ifdef CFG_DRAM_TEST_ADDRESS
if (runaddress == 1) {
printf ("Test ADDRESS ... ");
if (mem_test_address () == 1) {
printf ("failed \n");
return 1;
} else
printf ("ok \n");
}
#endif
#ifdef CFG_DRAM_TEST_WALK
if (runwalk == 1) {
printf ("Test WALKING ONEs ... ");
if (mem_test_walk () == 1) {
printf ("failed \n");
return 1;
} else
printf ("ok \n");
}
#endif
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1))
printf ("passed\n");
return 0;
}
#endif /* CFG_DRAM_TEST */
/* 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. */
void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc)
{
u32 temp;
temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE));
if ((temp & 0xffff) == new_loc >> 16)
return;
temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) &
0xffff0000) | (new_loc >> 16);
out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp);
while ((WORD_SWAP (*((volatile unsigned int *) (NONE_CACHEABLE |
new_loc |
(INTERNAL_SPACE_DECODE)))))
!= temp);
}

1025
board/prodrive/p3mx/pci.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,164 @@
/*
* (C) Copyright 2003
* Ingo Assmus <ingo.assmus@keymile.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* BK Id: SCCS/s.errno.h 1.9 06/05/01 21:45:21 paulus
*/
#ifndef _MV_PPC_ERRNO_H
#define _MV_PPC_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK 58 /* File locking deadlock error */
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
/* Should never be seen by user programs */
#define ERESTARTSYS 512
#define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
#define _LAST_ERRNO 515
#endif

View file

@ -0,0 +1,434 @@
/*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* 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
*/
/*************************************************************************
* adaption for the Marvell DB64460 Board
* Ingo Assmus (ingo.assmus@keymile.com)
*************************************************************************/
/* sdram_init.c - automatic memory sizing */
#include <common.h>
#include <74xx_7xx.h>
#include "../../Marvell/include/memory.h"
#include "../../Marvell/include/pci.h"
#include "../../Marvell/include/mv_gen_reg.h"
#include <net.h>
#include "eth.h"
#include "mpsc.h"
#include "../../Marvell/common/i2c.h"
#include "64460.h"
#include "mv_regs.h"
DECLARE_GLOBAL_DATA_PTR;
#undef DEBUG
#define MAP_PCI
#ifdef DEBUG
#define DP(x) x
#else
#define DP(x)
#endif
int set_dfcdlInit (void); /* setup delay line of Mv64460 */
int mvDmaIsChannelActive (int);
int mvDmaSetMemorySpace (ulong, ulong, ulong, ulong, ulong);
int mvDmaTransfer (int, ulong, ulong, ulong, ulong);
#define D_CACHE_FLUSH_LINE(addr, offset) \
{ \
__asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
}
int memory_map_bank (unsigned int bankNo,
unsigned int bankBase, unsigned int bankLength)
{
#ifdef MAP_PCI
PCI_HOST host;
#endif
#ifdef DEBUG
if (bankLength > 0) {
printf ("mapping bank %d at %08x - %08x\n",
bankNo, bankBase, bankBase + bankLength - 1);
} else {
printf ("unmapping bank %d\n", bankNo);
}
#endif
memoryMapBank (bankNo, bankBase, bankLength);
#ifdef MAP_PCI
for (host = PCI_HOST0; host <= PCI_HOST1; host++) {
const int features =
PREFETCH_ENABLE |
DELAYED_READ_ENABLE |
AGGRESSIVE_PREFETCH |
READ_LINE_AGGRESSIVE_PREFETCH |
READ_MULTI_AGGRESSIVE_PREFETCH |
MAX_BURST_4 | PCI_NO_SWAP;
pciMapMemoryBank (host, bankNo, bankBase, bankLength);
pciSetRegionSnoopMode (host, bankNo, PCI_SNOOP_WB, bankBase,
bankLength);
pciSetRegionFeatures (host, bankNo, features, bankBase,
bankLength);
}
#endif
return 0;
}
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'. Some (not all) hardware errors are detected:
* - short between address lines
* - short between data lines
*/
long int dram_size (long int *base, long int maxsize)
{
volatile long int *addr, *b = base;
long int cnt, val, save1, save2;
#define STARTVAL (1<<20) /* start test at 1M */
for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long);
cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
save1 = *addr; /* save contents of addr */
save2 = *b; /* save contents of base */
*addr = cnt; /* write cnt to addr */
*b = 0; /* put null at base */
/* check at base address */
if ((*b) != 0) {
*addr = save1; /* restore *addr */
*b = save2; /* restore *b */
return (0);
}
val = *addr; /* read *addr */
val = *addr; /* read *addr */
*addr = save1;
*b = save2;
if (val != cnt) {
DP (printf
("Found %08x at Address %08x (failure)\n",
(unsigned int) val, (unsigned int) addr));
/* fix boundary condition.. STARTVAL means zero */
if (cnt == STARTVAL / sizeof (long))
cnt = 0;
return (cnt * sizeof (long));
}
}
return maxsize;
}
#define SDRAM_NORMAL 0x0
#define SDRAM_PRECHARGE_ALL 0x1
#define SDRAM_REFRESH_ALL 0x2
#define SDRAM_MODE_REG_SETUP 0x3
#define SDRAM_XTEN_MODE_REG_SETUP 0x4
#define SDRAM_NOP 0x5
#define SDRAM_SELF_REFRESH 0x7
long int initdram (int board_type)
{
int tmp;
int start;
ulong size;
ulong memSpaceAttr;
ulong dest;
/* first disable all banks */
memory_map_bank(0, 0, 0);
memory_map_bank(1, 0, 0);
memory_map_bank(2, 0, 0);
memory_map_bank(3, 0, 0);
/* calibrate delay lines */
set_dfcdlInit();
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_NOP); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* SDRAM controller configuration */
#ifdef CONFIG_MV64460_ECC
GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58201400); /* 0x1400 */
#else
GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58200400); /* 0x1400 */
#endif
GT_REG_WRITE(MV64460_D_UNIT_CONTROL_LOW, 0xC3000540); /* 0x1404 */
GT_REG_WRITE(MV64460_D_UNIT_CONTROL_HIGH, 0x0300F777); /* 0x1424 */
GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_LOW, 0x01712220); /* 0x1408 */
GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_HIGH, 0x0000005D); /* 0x140C */
GT_REG_WRITE(MV64460_SDRAM_ADDR_CONTROL, 0x00000012); /* 0x1410 */
GT_REG_WRITE(MV64460_SDRAM_OPEN_PAGES_CONTROL, 0x00000001); /* 0x1414 */
/* SDRAM drive strength */
GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000000); /* 0x14C0 */
GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000008); /* 0x14C0 */
GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000000); /* 0x14C4 */
GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000008); /* 0x14C4 */
/* setup SDRAM device registers */
/* precharge all */
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* enable DLL */
GT_REG_WRITE(MV64460_EXTENDED_DRAM_MODE, 0x00000000); /* 0x1420 */
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_XTEN_MODE_REG_SETUP); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* reset DLL */
GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000132); /* 0x141C */
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* precharge all */
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* wait for 2 auto refresh commands */
udelay(20);
/* un-reset DLL */
GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000032); /* 0x141C */
GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
do {
tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
} while(tmp != 0x0);
/* wait 200 cycles */
udelay(2); /* FIXME make this dynamic for the system clock */
/* SDRAM init done */
memory_map_bank(0, CFG_SDRAM_BASE, (256 << 20));
#ifdef CFG_SDRAM1_BASE
memory_map_bank(1, CFG_SDRAM1_BASE, (256 << 20));
#endif
/* DUNIT_MMASK: enable SnoopHitEn bit to avoid errata CPU-#4
*/
tmp = GTREGREAD(MV64460_D_UNIT_MMASK); /* 0x14B0 */
GT_REG_WRITE(MV64460_D_UNIT_MMASK, tmp | 0x2);
start = (0 << 20);
#ifdef CONFIG_P3M750
size = (512 << 20);
#elif defined (CONFIG_P3M7448)
size = (128 << 20);
#endif
#ifdef CONFIG_MV64460_ECC
memSpaceAttr = ((~(BIT0 << 0)) & 0xf) << 8;
mvDmaSetMemorySpace (0, 0, memSpaceAttr, start, size);
for (dest = start; dest < start + size; dest += _8M) {
mvDmaTransfer (0, start, dest, _8M,
BIT8 /*DMA_DTL_128BYTES */ |
BIT3 /*DMA_HOLD_SOURCE_ADDR */ |
BIT11 /*DMA_BLOCK_TRANSFER_MODE */ );
while (mvDmaIsChannelActive (0));
}
#endif
return (size);
}
void board_add_ram_info(int use_default)
{
u32 val;
puts(" (CL=");
switch ((GTREGREAD(MV64460_SDRAM_MODE) >> 4) & 0x7) {
case 0x2:
puts("2");
break;
case 0x3:
puts("3");
break;
case 0x5:
puts("1.5");
break;
case 0x6:
puts("2.5");
break;
}
val = GTREGREAD(MV64460_SDRAM_CONFIG);
puts(", ECC ");
if (val & 0x00001000)
puts("enabled)");
else
puts("not enabled)");
}
/*
* mvDmaIsChannelActive - Check if IDMA channel is active
*
* channel = IDMA channel number from 0 to 7
*/
int mvDmaIsChannelActive (int channel)
{
ulong data;
data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * channel);
if (data & BIT14) /* activity status */
return 1;
return 0;
}
/*
* mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding
* map.
*
* memSpace = IDMA memory window number from 0 to 7
* trg_if = Target interface:
* 0x0 DRAM
* 0x1 Device Bus
* 0x2 Integrated SDRAM (or CPU bus 60x only)
* 0x3 PCI0
* 0x4 PCI1
* attr = IDMA attributes (see MV datasheet)
* base_addr = Sets up memory window for transfers
*
*/
int mvDmaSetMemorySpace (ulong memSpace,
ulong trg_if,
ulong attr, ulong base_addr, ulong size)
{
ulong temp;
/* The base address must be aligned to the size. */
if (base_addr % size != 0)
return 0;
if (size >= 0x10000) { /* 64K */
size &= 0xffff0000;
base_addr = (base_addr & 0xffff0000);
/* Set the new attributes */
GT_REG_WRITE (MV64460_DMA_BASE_ADDR_REG0 + memSpace * 8,
(base_addr | trg_if | attr));
GT_REG_WRITE ((MV64460_DMA_SIZE_REG0 + memSpace * 8),
(size - 1) & 0xffff0000);
temp = GTREGREAD (MV64460_DMA_BASE_ADDR_ENABLE_REG);
GT_REG_WRITE (DMA_BASE_ADDR_ENABLE_REG,
(temp & ~(BIT0 << memSpace)));
return 1;
}
return 0;
}
/*
* mvDmaTransfer - Transfer data from src_addr to dst_addr on one of the 4
* DMA channels.
*
* channel = IDMA channel number from 0 to 3
* destAddr = Destination address
* sourceAddr = Source address
* size = Size in bytes
* command = See MV datasheet
*
*/
int mvDmaTransfer (int channel, ulong sourceAddr,
ulong destAddr, ulong size, ulong command)
{
ulong engOffReg = 0; /* Engine Offset Register */
if (size > 0xffff)
command = command | BIT31; /* DMA_16M_DESCRIPTOR_MODE */
command = command | ((command >> 6) & 0x7);
engOffReg = channel * 4;
GT_REG_WRITE (MV64460_DMA_CHANNEL0_BYTE_COUNT + engOffReg, size);
GT_REG_WRITE (MV64460_DMA_CHANNEL0_SOURCE_ADDR + engOffReg, sourceAddr);
GT_REG_WRITE (MV64460_DMA_CHANNEL0_DESTINATION_ADDR + engOffReg, destAddr);
command = command |
BIT12 | /* DMA_CHANNEL_ENABLE */
BIT9; /* DMA_NON_CHAIN_MODE */
/* Activate DMA channel By writting to mvDmaControlRegister */
GT_REG_WRITE (MV64460_DMA_CHANNEL0_CONTROL + engOffReg, command);
return 1;
}
/****************************************************************************************
* SDRAM INIT *
* This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
* This procedure fits only the Atlantis *
* *
***************************************************************************************/
/****************************************************************************************
* DFCDL initialize MV643xx Design Considerations *
* *
***************************************************************************************/
int set_dfcdlInit (void)
{
int i;
/* Values from MV64460 User Manual */
unsigned int dfcdl_tbl[] = { 0x00000000, 0x00000001, 0x00000042, 0x00000083,
0x000000c4, 0x00000105, 0x00000146, 0x00000187,
0x000001c8, 0x00000209, 0x0000024a, 0x0000028b,
0x000002cc, 0x0000030d, 0x0000034e, 0x0000038f,
0x000003d0, 0x00000411, 0x00000452, 0x00000493,
0x000004d4, 0x00000515, 0x00000556, 0x00000597,
0x000005d8, 0x00000619, 0x0000065a, 0x0000069b,
0x000006dc, 0x0000071d, 0x0000075e, 0x0000079f,
0x000007e0, 0x00000821, 0x00000862, 0x000008a3,
0x000008e4, 0x00000925, 0x00000966, 0x000009a7,
0x000009e8, 0x00000a29, 0x00000a6a, 0x00000aab,
0x00000aec, 0x00000b2d, 0x00000b6e, 0x00000baf,
0x00000bf0, 0x00000c31, 0x00000c72, 0x00000cb3,
0x00000cf4, 0x00000d35, 0x00000d76, 0x00000db7,
0x00000df8, 0x00000e39, 0x00000e7a, 0x00000ebb,
0x00000efc, 0x00000f3d, 0x00000f7e, 0x00000fbf };
for (i = 0; i < 64; i++)
GT_REG_WRITE (SRAM_DATA0, dfcdl_tbl[i]);
GT_REG_WRITE (DFCDL_CONFIG0, 0x00300000); /* enable dynamic delay line updating */
return (0);
}

View file

@ -0,0 +1,107 @@
/*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* modified for marvell db64360 eval board by
* Ingo Assmus <ingo.assmus@keymile.com>
*
* modified for cpci750 board by
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* serial.c - serial support for esd cpci750 board
*/
/* supports the MPSC */
#include <common.h>
#include <command.h>
#include "../../Marvell/include/memory.h"
#include "serial.h"
#include "mpsc.h"
DECLARE_GLOBAL_DATA_PTR;
int serial_init (void)
{
mpsc_init (gd->baudrate);
return (0);
}
void serial_putc (const char c)
{
if (c == '\n')
mpsc_putchar ('\r');
mpsc_putchar (c);
}
int serial_getc (void)
{
return mpsc_getchar ();
}
int serial_tstc (void)
{
return mpsc_test_char ();
}
void serial_setbrg (void)
{
galbrg_set_baudrate (CONFIG_MPSC_PORT, gd->baudrate);
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
void kgdb_serial_init (void)
{
}
void putDebugChar (int c)
{
serial_putc (c);
}
void putDebugStr (const char *str)
{
serial_puts (str);
}
int getDebugChar (void)
{
return serial_getc ();
}
void kgdb_interruptible (int yes)
{
return;
}
#endif /* CFG_CMD_KGDB */

View file

@ -0,0 +1,89 @@
/*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* modified for marvell db64360 eval board by
* Ingo Assmus <ingo.assmus@keymile.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* serial.h - mostly useful for DUART serial_init in serial.c */
#ifndef __SERIAL_H__
#define __SERIAL_H__
#if 0
#define B230400 1
#define B115200 2
#define B57600 4
#define B38400 82
#define B19200 163
#define B9600 24
#define B4800 651
#define B2400 1302
#define B1200 2604
#define B600 5208
#define B300 10417
#define B150 20833
#define B110 28409
#define BDEFAULT B115200
/* this stuff is important to initialize
the DUART channels */
#define Scale 0x01L /* distance between port addresses */
#define COM1 0x000003f8 /* Keyboard */
#define COM2 0x000002f8 /* Host */
/* Port Definitions relative to base COM port addresses */
#define DataIn (0x00*Scale) /* data input port */
#define DataOut (0x00*Scale) /* data output port */
#define BaudLsb (0x00*Scale) /* baud rate divisor least significant byte */
#define BaudMsb (0x01*Scale) /* baud rate divisor most significant byte */
#define Ier (0x01*Scale) /* interrupt enable register */
#define Iir (0x02*Scale) /* interrupt identification register */
#define Lcr (0x03*Scale) /* line control register */
#define Mcr (0x04*Scale) /* modem control register */
#define Lsr (0x05*Scale) /* line status register */
#define Msr (0x06*Scale) /* modem status register */
/* Bit Definitions for above ports */
#define LcrDlab 0x80 /* b7: enable baud rate divisor registers */
#define LcrDflt 0x03 /* b6-0: no parity, 1 stop, 8 data */
#define McrRts 0x02 /* b1: request to send (I am ready to xmit) */
#define McrDtr 0x01 /* b0: data terminal ready (I am alive ready to rcv) */
#define McrDflt (McrRts|McrDtr)
#define LsrTxD 0x6000 /* b5: transmit holding register empty (i.e. xmit OK!)*/
/* b6: transmitter empty */
#define LsrRxD 0x0100 /* b0: received data ready (i.e. got a byte!) */
#define MsrRi 0x0040 /* b6: ring indicator (other guy is ready to rcv) */
#define MsrDsr 0x0020 /* b5: data set ready (other guy is alive ready to rcv */
#define MsrCts 0x0010 /* b4: clear to send (other guy is ready to rcv) */
#define IerRda 0xf /* b0: Enable received data available interrupt */
#endif
#endif /* __SERIAL_H__ */

View file

@ -0,0 +1,138 @@
/*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
*/
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
{
/* 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/74xx_7xx/start.o (.text)
/* store the environment in a seperate sector in the boot flash */
/* . = env_offset; */
/* common/environment.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 = .);
}

View file

@ -759,7 +759,7 @@ unsigned long flash_init(void)
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
i, size_b[i], size_b[i] << 20);
i+1, size_b[i], size_b[i] << 20);
flash_info[i].sector_count = -1;
flash_info[i].size = 0;
}

View file

@ -289,7 +289,7 @@ int checkboard (void)
#elif defined(CONFIG_TB5200)
# define CARRIER_NAME "TB5200"
#elif defined(CONFIG_CAM5200)
# define CARRIER_NAME "Cam5200"
# define CARRIER_NAME "CAM5200"
#elif defined(CONFIG_FO300)
# define CARRIER_NAME "FO300"
#else

View file

@ -69,17 +69,17 @@ void
pci_init_board(void)
{
volatile immap_t * immr;
volatile clk8349_t * clk;
volatile law8349_t * pci_law;
volatile pot8349_t * pci_pot;
volatile pcictrl8349_t * pci_ctrl;
volatile pciconf8349_t * pci_conf;
volatile clk83xx_t * clk;
volatile law83xx_t * pci_law;
volatile pot83xx_t * pci_pot;
volatile pcictrl83xx_t * pci_ctrl;
volatile pciconf83xx_t * pci_conf;
u16 reg16;
u32 reg32;
struct pci_controller * hose;
immr = (immap_t *)CFG_IMMRBAR;
clk = (clk8349_t *)&immr->clk;
immr = (immap_t *)CFG_IMMR;
clk = (clk83xx_t *)&immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
@ -186,8 +186,8 @@ pci_init_board(void)
hose->region_count = 3;
pci_setup_indirect(hose,
(CFG_IMMRBAR+0x8300),
(CFG_IMMRBAR+0x8304));
(CFG_IMMR+0x8300),
(CFG_IMMR+0x8304));
pci_register_hose(hose);

View file

@ -69,7 +69,7 @@ static void set_cs_config(short cs, long config);
static void set_ddr_config(void);
/* Local variable */
static volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
static volatile immap_t *im = (immap_t *)CFG_IMMR;
/**************************************************************************
* Board initialzation after relocation to RAM. Used to detect the number
@ -147,7 +147,7 @@ int checkboard (void)
volatile immap_t * immr;
u32 w, f;
immr = (immap_t *)CFG_IMMRBAR;
immr = (immap_t *)CFG_IMMR;
if (!(immr->reset.rcwh & RCWH_PCIHOST)) {
printf("PCI: NOT in host mode..?!\n");
return 0;

View file

@ -41,7 +41,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
cmd_usb.o cmd_vfd.o \
command.o console.o devices.o dlmalloc.o docecc.o \
command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o \
environment.o env_common.o \
env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
env_nvram.o env_nowhere.o \

View file

@ -50,15 +50,20 @@ int altera_load( Altera_desc *desc, void *buf, size_t bsize )
{
int ret_val = FPGA_FAIL; /* assume a failure */
if (!altera_validate (desc, __FUNCTION__)) {
if (!altera_validate (desc, (char *)__FUNCTION__)) {
printf ("%s: Invalid device descriptor\n", __FUNCTION__);
} else {
switch (desc->family) {
case Altera_ACEX1K:
case Altera_CYC2:
#if (CONFIG_FPGA & CFG_ACEX1K)
PRINTF ("%s: Launching the ACEX1K Loader...\n",
__FUNCTION__);
ret_val = ACEX1K_load (desc, buf, bsize);
#elif (CONFIG_FPGA & CFG_CYCLON2)
PRINTF ("%s: Launching the CYCLON II Loader...\n",
__FUNCTION__);
ret_val = CYC2_load (desc, buf, bsize);
#else
printf ("%s: No support for ACEX1K devices.\n",
__FUNCTION__);
@ -78,7 +83,7 @@ int altera_dump( Altera_desc *desc, void *buf, size_t bsize )
{
int ret_val = FPGA_FAIL; /* assume a failure */
if (!altera_validate (desc, __FUNCTION__)) {
if (!altera_validate (desc, (char *)__FUNCTION__)) {
printf ("%s: Invalid device descriptor\n", __FUNCTION__);
} else {
switch (desc->family) {
@ -106,13 +111,16 @@ int altera_info( Altera_desc *desc )
{
int ret_val = FPGA_FAIL;
if (altera_validate (desc, __FUNCTION__)) {
if (altera_validate (desc, (char *)__FUNCTION__)) {
printf ("Family: \t");
switch (desc->family) {
case Altera_ACEX1K:
printf ("ACEX1K\n");
break;
/* Add new family types here */
case Altera_CYC2:
printf ("CYCLON II\n");
break;
default:
printf ("Unknown family type, %d\n", desc->family);
}
@ -147,8 +155,11 @@ int altera_info( Altera_desc *desc )
printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
switch (desc->family) {
case Altera_ACEX1K:
case Altera_CYC2:
#if (CONFIG_FPGA & CFG_ACEX1K)
ACEX1K_info (desc);
#elif (CONFIG_FPGA & CFG_CYCLON2)
CYC2_info (desc);
#else
/* just in case */
printf ("%s: No support for ACEX1K devices.\n",
@ -176,7 +187,7 @@ int altera_reloc( Altera_desc *desc, ulong reloc_offset)
{
int ret_val = FPGA_FAIL; /* assume a failure */
if (!altera_validate (desc, __FUNCTION__)) {
if (!altera_validate (desc, (char *)__FUNCTION__)) {
printf ("%s: Invalid device descriptor\n", __FUNCTION__);
} else {
switch (desc->family) {
@ -186,6 +197,14 @@ int altera_reloc( Altera_desc *desc, ulong reloc_offset)
#else
printf ("%s: No support for ACEX devices.\n",
__FUNCTION__);
#endif
break;
case Altera_CYC2:
#if (CONFIG_FPGA & CFG_CYCLON2)
ret_val = CYC2_reloc (desc, reloc_offset);
#else
printf ("%s: No support for CYCLON II devices.\n",
__FUNCTION__);
#endif
break;
/* Add new family types here */

View file

@ -833,10 +833,6 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
printf ("ERROR: flat device tree size does not agree with image\n");
return;
}
} else if (getenv("disable_of") == NULL) {
printf ("ERROR: bootm needs flat device tree as third argument\n");
return;
}
#endif
if (!data) {
@ -913,23 +909,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
SHOW_BOOT_PROGRESS (15);
#ifndef CONFIG_OF_FLAT_TREE
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
#endif
/*
* Linux Kernel Parameters:
* r3: ptr to board info data
* r4: initrd_start or 0 if no initrd
* r5: initrd_end - unused if r4 is 0
* r6: Start of command line string
* r7: End of command line string
*/
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
#else /* CONFIG_OF_FLAT_TREE */
#ifdef CONFIG_OF_FLAT_TREE
/* move of_flat_tree if needed */
if (of_data) {
ulong of_start, of_len;
@ -948,30 +932,36 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
of_start, of_start + of_len - 1);
memmove ((void *)of_start, (void *)of_data, of_len);
}
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
#endif
/*
* Linux Kernel Parameters:
* Linux Kernel Parameters (passing board info data):
* r3: ptr to board info data
* r4: initrd_start or 0 if no initrd
* r5: initrd_end - unused if r4 is 0
* r6: Start of command line string
* r7: End of command line string
*/
#ifdef CONFIG_OF_FLAT_TREE
if (!of_flat_tree) /* no device tree; boot old style */
#endif
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
/* does not return */
#ifdef CONFIG_OF_FLAT_TREE
/*
* Linux Kernel Parameters (passing device tree):
* r3: ptr to OF flat tree, followed by the board info data
* r4: physical pointer to the kernel itself
* r5: NULL
* r6: NULL
* r7: NULL
*/
if (getenv("disable_of") != NULL)
(*kernel) ((bd_t *)of_flat_tree, initrd_start, initrd_end,
cmd_start, cmd_end);
else {
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
}
#endif /* CONFIG_OF_FLAT_TREE */
#endif
}
#endif /* CONFIG_PPC */

View file

@ -96,12 +96,10 @@ int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
* If we don't know where the image is then we're done.
*/
if ((tmp = getenv ("loadaddr")) != NULL) {
addr = simple_strtoul (tmp, NULL, 16);
} else {
puts ("No load address provided\n");
return 1;
}
if (argc < 2)
addr = load_addr;
else
addr = simple_strtoul (argv[1], NULL, 16);
#if (CONFIG_COMMANDS & CFG_CMD_NET)
/* Check to see if we need to tftp the image ourselves before starting */

View file

@ -55,6 +55,7 @@ static int fpga_get_op (char *opstr);
#define FPGA_LOAD 1
#define FPGA_LOADB 2
#define FPGA_DUMP 3
#define FPGA_LOADMK 4
/* Convert bitstream data and load into the fpga */
int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
@ -251,6 +252,23 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
rc = fpga_loadbitstream(dev, fpga_data, data_size);
break;
case FPGA_LOADMK:
{
image_header_t header;
image_header_t *hdr = &header;
ulong data;
memmove (&header, (char *)fpga_data, sizeof(image_header_t));
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
puts ("Bad Magic Number\n");
return 1;
}
data = ((ulong)fpga_data + sizeof(image_header_t));
data_size = ntohl(hdr->ih_size);
rc = fpga_load (dev, (void *)data, data_size);
}
break;
case FPGA_DUMP:
rc = fpga_dump (dev, fpga_data, data_size);
break;
@ -282,6 +300,8 @@ static int fpga_get_op (char *opstr)
op = FPGA_LOADB;
} else if (!strcmp ("load", opstr)) {
op = FPGA_LOAD;
} else if (!strcmp ("loadmk", opstr)) {
op = FPGA_LOADMK;
} else if (!strcmp ("dump", opstr)) {
op = FPGA_DUMP;
}
@ -299,5 +319,6 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
"\tinfo\tlist known device information\n"
"\tload\tLoad device from memory buffer\n"
"\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
"\tloadmk\tLoad device generated with mkimage\n"
"\tdump\tLoad device to memory buffer\n");
#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */

View file

@ -101,8 +101,31 @@ static uchar i2c_mm_last_chip;
static uint i2c_mm_last_addr;
static uint i2c_mm_last_alen;
/* If only one I2C bus is present, the list of devices to ignore when
* the probe command is issued is represented by a 1D array of addresses.
* When multiple buses are present, the list is an array of bus-address
* pairs. The following macros take care of this */
#if defined(CFG_I2C_NOPROBES)
#if defined(CONFIG_I2C_MULTI_BUS)
static struct
{
uchar bus;
uchar addr;
} i2c_no_probes[] = CFG_I2C_NOPROBES;
#define GET_BUS_NUM i2c_get_bus_num()
#define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b))
#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a))
#define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr
#else /* single bus */
static uchar i2c_no_probes[] = CFG_I2C_NOPROBES;
#define GET_BUS_NUM 0
#define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */
#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a))
#define NO_PROBE_ADDR(i) i2c_no_probes[(i)]
#endif /* CONFIG_MULTI_BUS */
#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
#endif
static int
@ -159,10 +182,9 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
break;
} else if (argv[2][j] == '\0') {
} else if (argv[2][j] == '\0')
break;
}
}
/*
* If another parameter, it is the length to display.
@ -185,9 +207,9 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
if(i2c_read(chip, addr, alen, linebuf, linebytes) != 0) {
if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
puts ("Error reading the chip.\n");
} else {
else {
printf("%04x:", addr);
cp = linebuf;
for (j=0; j<linebytes; j++) {
@ -264,10 +286,9 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
break;
} else if (argv[2][j] == '\0') {
} else if (argv[2][j] == '\0')
break;
}
}
/*
* Value to write is always specified.
@ -277,16 +298,14 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
/*
* Optional count
*/
if(argc == 5) {
if (argc == 5)
count = simple_strtoul(argv[4], NULL, 16);
} else {
else
count = 1;
}
while (count-- > 0) {
if(i2c_write(chip, addr++, alen, &byte, 1) != 0) {
if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
puts ("Error writing the chip.\n");
}
/*
* Wait for the write to complete. The write can take
* up to 10mSec (we allow a little more time).
@ -354,10 +373,9 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
break;
} else if (argv[2][j] == '\0') {
} else if (argv[2][j] == '\0')
break;
}
}
/*
* Count is always specified
@ -372,18 +390,15 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
crc = 0;
err = 0;
while (count-- > 0) {
if(i2c_read(chip, addr, alen, &byte, 1) != 0) {
if (i2c_read(chip, addr, alen, &byte, 1) != 0)
err++;
}
crc = crc32 (crc, &byte, 1);
addr++;
}
if (err > 0)
{
puts ("Error reading the chip,\n");
} else {
else
printf ("%08lx\n", crc);
}
return 0;
}
@ -449,11 +464,10 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
return 1;
}
break;
} else if (argv[2][j] == '\0') {
} else if (argv[2][j] == '\0')
break;
}
}
}
/*
* Print the address, followed by value. Then accept input for
@ -461,18 +475,17 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
*/
do {
printf("%08lx:", addr);
if(i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) {
if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
puts ("\nError reading the chip,\n");
} else {
else {
data = cpu_to_be32(data);
if(size == 1) {
if (size == 1)
printf(" %02lx", (data >> 24) & 0x000000FF);
} else if(size == 2) {
else if (size == 2)
printf(" %04lx", (data >> 16) & 0x0000FFFF);
} else {
else
printf(" %08lx", data);
}
}
nbytes = readline (" ? ");
if (nbytes == 0) {
@ -488,19 +501,17 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
#endif
}
#ifdef CONFIG_BOOT_RETRY_TIME
else if (nbytes == -2) {
else if (nbytes == -2)
break; /* timed out, exit the command */
}
#endif
else {
char *endp;
data = simple_strtoul(console_buffer, &endp, 16);
if(size == 1) {
if (size == 1)
data = data << 24;
} else if(size == 2) {
else if (size == 2)
data = data << 16;
}
data = be32_to_cpu(data);
nbytes = endp - console_buffer;
if (nbytes) {
@ -510,9 +521,8 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
*/
reset_cmd_timeout();
#endif
if(i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) {
if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
puts ("Error writing the chip.\n");
}
#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
#endif
@ -538,14 +548,15 @@ int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int j;
#if defined(CFG_I2C_NOPROBES)
int k, skip;
#endif
uchar bus = GET_BUS_NUM;
#endif /* NOPROBES */
puts ("Valid chip addresses:");
for (j = 0; j < 128; j++) {
#if defined(CFG_I2C_NOPROBES)
skip = 0;
for (k = 0; k < sizeof(i2c_no_probes); k++){
if (j == i2c_no_probes[k]){
for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {
skip = 1;
break;
}
@ -553,16 +564,17 @@ int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (skip)
continue;
#endif
if(i2c_probe(j) == 0) {
if (i2c_probe(j) == 0)
printf(" %02X", j);
}
}
putc ('\n');
#if defined(CFG_I2C_NOPROBES)
puts ("Excluded chip addresses:");
for( k = 0; k < sizeof(i2c_no_probes); k++ )
printf(" %02X", i2c_no_probes[k] );
for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
if (COMPARE_BUS(bus,k))
printf(" %02X", NO_PROBE_ADDR(k));
}
putc ('\n');
#endif
@ -609,34 +621,30 @@ int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
break;
} else if (argv[2][j] == '\0') {
} else if (argv[2][j] == '\0')
break;
}
}
/*
* Length is the number of objects, not number of bytes.
*/
length = 1;
length = simple_strtoul(argv[3], NULL, 16);
if(length > sizeof(bytes)) {
if (length > sizeof(bytes))
length = sizeof(bytes);
}
/*
* The delay time (uSec) is optional.
*/
delay = 1000;
if (argc > 3) {
if (argc > 3)
delay = simple_strtoul(argv[4], NULL, 10);
}
/*
* Run the loop...
*/
while (1) {
if(i2c_read(chip, addr, alen, bytes, length) != 0) {
if (i2c_read(chip, addr, alen, bytes, length) != 0)
puts ("Error reading the chip.\n");
}
udelay(delay);
}
@ -696,17 +704,15 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
default: puts ("unknown\n"); break;
}
puts ("Row address bits ");
if((data[3] & 0x00F0) == 0) {
if ((data[3] & 0x00F0) == 0)
printf("%d\n", data[3] & 0x0F);
} else {
else
printf("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F);
}
puts ("Column address bits ");
if((data[4] & 0x00F0) == 0) {
if ((data[4] & 0x00F0) == 0)
printf("%d\n", data[4] & 0x0F);
} else {
else
printf("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F);
}
printf("Module rows %d\n", data[5]);
printf("Module data width %d bits\n", (data[7] << 8) | data[6]);
puts ("Interface signal levels ");
@ -729,11 +735,10 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
case 2: puts ("ECC\n"); break;
default: puts ("unknown\n"); break;
}
if((data[12] & 0x80) == 0) {
if ((data[12] & 0x80) == 0)
puts ("No self refresh, rate ");
} else {
else
puts ("Self refresh, rate ");
}
switch(data[12] & 0x7F) {
case 0: puts ("15.625uS\n"); break;
case 1: puts ("3.9uS\n"); break;
@ -751,11 +756,10 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (data[14] != 0) {
printf("EDC width %d\n",
data[14] & 0x7F);
if((data[14] & 0x80) != 0) {
if ((data[14] & 0x80) != 0)
printf(" (second bank) %d\n",
2 * (data[14] & 0x7F));
}
}
printf("Min clock delay, back-to-back random column addresses %d\n",
data[15]);
puts ("Burst length(s) ");
@ -873,6 +877,74 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
#endif /* CFG_CMD_SDRAM */
#if defined(CONFIG_I2C_CMD_TREE)
#if defined(CONFIG_I2C_MULTI_BUS)
int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
int bus_idx, ret=0;
if (argc == 1)
/* querying current setting */
printf("Current bus is %d\n", i2c_get_bus_num());
else {
bus_idx = simple_strtoul(argv[1], NULL, 10);
printf("Setting bus to %d\n", bus_idx);
ret = i2c_set_bus_num(bus_idx);
if (ret)
printf("Failure changing bus number (%d)\n", ret);
}
return ret;
}
#endif /* CONFIG_I2C_MULTI_BUS */
int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
int speed, ret=0;
if (argc == 1)
/* querying current speed */
printf("Current bus speed=%d\n", i2c_get_bus_speed());
else {
speed = simple_strtoul(argv[1], NULL, 10);
printf("Setting bus speed to %d Hz\n", speed);
ret = i2c_set_bus_speed(speed);
if (ret)
printf("Failure changing bus speed (%d)\n", ret);
}
return ret;
}
int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
#if defined(CONFIG_I2C_MULTI_BUS)
if (!strncmp(argv[1], "de", 2))
return do_i2c_bus_num(cmdtp, flag, --argc, ++argv);
#endif /* CONFIG_I2C_MULTI_BUS */
if (!strncmp(argv[1], "sp", 2))
return do_i2c_bus_speed(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "md", 2))
return do_i2c_md(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "mm", 2))
return do_i2c_mm(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "mw", 2))
return do_i2c_mw(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "nm", 2))
return do_i2c_nm(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "cr", 2))
return do_i2c_crc(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "pr", 2))
return do_i2c_probe(cmdtp, flag, --argc, ++argv);
if (!strncmp(argv[1], "lo", 2))
return do_i2c_loop(cmdtp, flag, --argc, ++argv);
#if (CONFIG_COMMANDS & CFG_CMD_SDRAM)
if (!strncmp(argv[1], "sd", 2))
return do_sdram(cmdtp, flag, --argc, ++argv);
#endif /* CFG_CMD_SDRAM */
else
printf ("Usage:\n%s\n", cmdtp->usage);
return 0;
}
#endif /* CONFIG_I2C_CMD_TREE */
/***************************************************/
@ -930,4 +1002,26 @@ U_BOOT_CMD(
" (valid chip values 50..57)\n"
);
#endif
#if defined(CONFIG_I2C_CMD_TREE)
U_BOOT_CMD(
i2c, 6, 1, do_i2c,
"i2c - I2C sub-system\n",
#if defined(CONFIG_I2C_MULTI_BUS)
"dev [dev] - show or set current I2C bus\n"
#endif /* CONFIG_I2C_MULTI_BUS */
"i2c speed [speed] - show or set I2C bus speed\n"
"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
"i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n"
"i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
"i2c probe - show devices on the I2C bus\n"
"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
#if (CONFIG_COMMANDS & CFG_CMD_SDRAM)
"i2c sdram chip - print SDRAM configuration information\n"
#endif /* CFG_CMD_SDRAM */
);
#endif /* CONFIG_I2C_CMD_TREE */
#endif /* CFG_CMD_I2C */

View file

@ -700,7 +700,8 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
putc ('\n');
for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) {
if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
if (nand_dev_desc[i].ChipID ==
NAND_ChipID_UNKNOWN)
continue; /* list only known devices */
printf ("Device %d: ", i);
nand_print (&nand_dev_desc[i]);
@ -708,7 +709,8 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
} else if (strcmp (argv[1], "device") == 0) {
if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
if ((curr_device < 0)
|| (curr_device >= CFG_MAX_NAND_DEVICE)) {
puts ("\nno devices available\n");
return 1;
}
@ -717,7 +719,8 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
} else if (strcmp (argv[1], "bad") == 0) {
if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
if ((curr_device < 0)
|| (curr_device >= CFG_MAX_NAND_DEVICE)) {
puts ("\nno devices available\n");
return 1;
}
@ -749,15 +752,14 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
puts ("... is now current device\n");
return 0;
}
else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
} else if (strcmp (argv[1], "erase") == 0
&& strcmp (argv[2], "clean") == 0) {
struct nand_chip *nand = &nand_dev_desc[curr_device];
ulong off = 0;
ulong size = nand->totlen;
int ret;
printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
curr_device, off, size);
printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size);
ret = nand_legacy_erase (nand, off, size, 1);
@ -787,15 +789,13 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ret = nand_read_oob (nand_dev_desc + curr_device,
off, size, (size_t *) & total,
(u_char *) addr);
}
else {
} else {
ret = nand_write_oob (nand_dev_desc + curr_device,
off, size, (size_t *) & total,
(u_char *) addr);
}
return ret;
}
else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
} else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2))
cmd |= NANDRW_JFFS2; /* skip bad blocks */
else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) {
cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
@ -825,8 +825,10 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
(cmd & NANDRW_READ) ? "read" : "write",
curr_device, off, size);
ret = nand_legacy_rw(nand_dev_desc + curr_device, cmd, off, size,
(size_t *)&total, (u_char*)addr);
ret = nand_legacy_rw (nand_dev_desc + curr_device,
cmd, off, size,
(size_t *) & total,
(u_char *) addr);
printf (" %d bytes %s: %s\n", total,
(cmd & NANDRW_READ) ? "read" : "written",
@ -836,8 +838,10 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
} else if (strcmp (argv[1], "erase") == 0 &&
(argc == 4 || strcmp ("clean", argv[2]) == 0)) {
int clean = argc == 5;
ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
ulong off =
simple_strtoul (argv[2 + clean], NULL, 16);
ulong size =
simple_strtoul (argv[3 + clean], NULL, 16);
int ret;
printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",

305
common/cyclon2.c Normal file
View file

@ -0,0 +1,305 @@
/*
* (C) Copyright 2006
* Heiko Schocher, hs@denx.de
* Based on ACE1XK.c
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h> /* core U-Boot definitions */
#include <altera.h>
#include <ACEX1K.h> /* ACEX device family */
#if (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2))
/* Define FPGA_DEBUG to get debug printf's */
#ifdef FPGA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* Note: The assumption is that we cannot possibly run fast enough to
* overrun the device (the Slave Parallel mode can free run at 50MHz).
* If there is a need to operate slower, define CONFIG_FPGA_DELAY in
* the board config file to slow things down.
*/
#ifndef CONFIG_FPGA_DELAY
#define CONFIG_FPGA_DELAY()
#endif
#ifndef CFG_FPGA_WAIT
#define CFG_FPGA_WAIT CFG_HZ/10 /* 100 ms */
#endif
static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize );
static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
/* static int CYC2_ps_info( Altera_desc *desc ); */
static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset );
/* ------------------------------------------------------------------------- */
/* CYCLON2 Generic Implementation */
int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
switch (desc->iface) {
case passive_serial:
PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
ret_val = CYC2_ps_load (desc, buf, bsize);
break;
/* Add new interface types here */
default:
printf ("%s: Unsupported interface type, %d\n",
__FUNCTION__, desc->iface);
}
return ret_val;
}
int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
switch (desc->iface) {
case passive_serial:
PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
ret_val = CYC2_ps_dump (desc, buf, bsize);
break;
/* Add new interface types here */
default:
printf ("%s: Unsupported interface type, %d\n",
__FUNCTION__, desc->iface);
}
return ret_val;
}
int CYC2_info( Altera_desc *desc )
{
return FPGA_SUCCESS;
}
int CYC2_reloc (Altera_desc * desc, ulong reloc_offset)
{
int ret_val = FPGA_FAIL; /* assume a failure */
if (desc->family != Altera_CYC2) {
printf ("%s: Unsupported family type, %d\n",
__FUNCTION__, desc->family);
return FPGA_FAIL;
} else
switch (desc->iface) {
case passive_serial:
ret_val = CYC2_ps_reloc (desc, reloc_offset);
break;
/* Add new interface types here */
default:
printf ("%s: Unsupported interface type, %d\n",
__FUNCTION__, desc->iface);
}
return ret_val;
}
/* ------------------------------------------------------------------------- */
/* CYCLON2 Passive Serial Generic Implementation */
static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
int ret = 0;
PRINTF ("%s: start with interface functions @ 0x%p\n",
__FUNCTION__, fn);
if (fn) {
int cookie = desc->cookie; /* make a local copy */
unsigned long ts; /* timestamp */
PRINTF ("%s: Function Table:\n"
"ptr:\t0x%p\n"
"struct: 0x%p\n"
"config:\t0x%p\n"
"status:\t0x%p\n"
"write:\t0x%p\n"
"done:\t0x%p\n\n",
__FUNCTION__, &fn, fn, fn->config, fn->status,
fn->write, fn->done);
#ifdef CFG_FPGA_PROG_FEEDBACK
printf ("Loading FPGA Device %d...", cookie);
#endif
/*
* Run the pre configuration function if there is one.
*/
if (*fn->pre) {
(*fn->pre) (cookie);
}
/* Establish the initial state */
(*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */
udelay(2); /* T_cfg > 2us */
/* Wait for nSTATUS to be asserted */
ts = get_timer (0); /* get current time */
do {
CONFIG_FPGA_DELAY ();
if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
puts ("** Timeout waiting for STATUS to go high.\n");
(*fn->abort) (cookie);
return FPGA_FAIL;
}
} while (!(*fn->status) (cookie));
/* Get ready for the burn */
CONFIG_FPGA_DELAY ();
ret = (*fn->write) (buf, bsize, TRUE, cookie);
if (ret) {
puts ("** Write failed.\n");
(*fn->abort) (cookie);
return FPGA_FAIL;
}
#ifdef CFG_FPGA_PROG_FEEDBACK
puts(" OK? ...");
#endif
CONFIG_FPGA_DELAY ();
#ifdef CFG_FPGA_PROG_FEEDBACK
putc (' '); /* terminate the dotted line */
#endif
/*
* Checking FPGA's CONF_DONE signal - correctly booted ?
*/
if ( ! (*fn->done) (cookie) ) {
puts ("** Booting failed! CONF_DONE is still deasserted.\n");
(*fn->abort) (cookie);
return (FPGA_FAIL);
}
#ifdef CFG_FPGA_PROG_FEEDBACK
puts(" OK\n");
#endif
ret_val = FPGA_SUCCESS;
#ifdef CFG_FPGA_PROG_FEEDBACK
if (ret_val == FPGA_SUCCESS) {
puts ("Done.\n");
}
else {
puts ("Fail.\n");
}
#endif
(*fn->post) (cookie);
} else {
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
}
return ret_val;
}
static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
{
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
printf ("%s: Passive Serial Dumping is unavailable\n",
__FUNCTION__);
return FPGA_FAIL;
}
static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Altera_CYC2_Passive_Serial_fns *fn_r, *fn =
(Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns);
if (fn) {
ulong addr;
/* Get the relocated table address */
addr = (ulong) fn + reloc_offset;
fn_r = (Altera_CYC2_Passive_Serial_fns *) addr;
if (!fn_r->relocated) {
if (memcmp (fn_r, fn,
sizeof (Altera_CYC2_Passive_Serial_fns))
== 0) {
/* good copy of the table, fix the descriptor pointer */
desc->iface_fns = fn_r;
} else {
PRINTF ("%s: Invalid function table at 0x%p\n",
__FUNCTION__, fn_r);
return FPGA_FAIL;
}
PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__,
desc);
addr = (ulong) (fn->pre) + reloc_offset;
fn_r->pre = (Altera_pre_fn) addr;
addr = (ulong) (fn->config) + reloc_offset;
fn_r->config = (Altera_config_fn) addr;
addr = (ulong) (fn->status) + reloc_offset;
fn_r->status = (Altera_status_fn) addr;
addr = (ulong) (fn->done) + reloc_offset;
fn_r->done = (Altera_done_fn) addr;
addr = (ulong) (fn->write) + reloc_offset;
fn_r->write = (Altera_write_fn) addr;
addr = (ulong) (fn->abort) + reloc_offset;
fn_r->abort = (Altera_abort_fn) addr;
addr = (ulong) (fn->post) + reloc_offset;
fn_r->post = (Altera_post_fn) addr;
fn_r->relocated = TRUE;
} else {
/* this table has already been moved */
/* XXX - should check to see if the descriptor is correct */
desc->iface_fns = fn_r;
}
ret_val = FPGA_SUCCESS;
} else {
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
}
return ret_val;
}
#endif /* (CONFIG_FPGA & (CFG_ALTERA | CFG_CYCLON2)) */

View file

@ -139,7 +139,7 @@ static int fpga_dev_info( int devnum )
printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc );
ret_val = xilinx_info( desc->devdesc );
#else
fpga_no_sup( __FUNCTION__, "Xilinx devices" );
fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
#endif
break;
case fpga_altera:
@ -178,7 +178,7 @@ int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off )
#if CONFIG_FPGA & CFG_FPGA_XILINX
ret_val = xilinx_reloc( desc, reloc_off );
#else
fpga_no_sup( __FUNCTION__, "Xilinx devices" );
fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
#endif
break;
case fpga_altera:
@ -271,7 +271,7 @@ int fpga_load( int devnum, void *buf, size_t bsize )
#if CONFIG_FPGA & CFG_FPGA_XILINX
ret_val = xilinx_load( desc->devdesc, buf, bsize );
#else
fpga_no_sup( __FUNCTION__, "Xilinx devices" );
fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
#endif
break;
case fpga_altera:
@ -304,7 +304,7 @@ int fpga_dump( int devnum, void *buf, size_t bsize )
#if CONFIG_FPGA & CFG_FPGA_XILINX
ret_val = xilinx_dump( desc->devdesc, buf, bsize );
#else
fpga_no_sup( __FUNCTION__, "Xilinx devices" );
fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
#endif
break;
case fpga_altera:

View file

@ -21,6 +21,16 @@
* MA 02111-1307 USA
*/
#include <config.h>
#ifdef __PPC__
/*
* At least on G2 PowerPC cores, sequential accesses to non-existent
* memory must be synchronized.
*/
# include <asm/io.h> /* for sync() */
#else
# define sync() /* nothing */
#endif
/*
* Check memory range for valid RAM. A simple memory test determines
@ -38,20 +48,27 @@ long get_ram_size(volatile long *base, long maxsize)
for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
sync ();
save[i++] = *addr;
sync ();
*addr = ~cnt;
}
addr = base;
sync ();
save[i] = *addr;
sync ();
*addr = 0;
sync ();
if ((val = *addr) != 0) {
/* Restore the original data before leaving the function.
*/
sync ();
*addr = save[i];
for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
addr = base + cnt;
sync ();
*addr = save[--i];
}
return (0);

View file

@ -164,6 +164,14 @@ int checkcpu (void)
str = "MPC7410";
break;
case CPU_7447A:
str = "MPC7447A";
break;
case CPU_7448:
str = "MPC7448";
break;
case CPU_7450:
str = "MPC7450";
break;
@ -176,14 +184,6 @@ int checkcpu (void)
str = "MPC7457";
break;
case CPU_7447A:
str = "MPC7447A";
break;
case CPU_7448:
str = "MPC7448";
break;
default:
printf("Unknown CPU -- PVR: 0x%08x\n", pvr);
return -1;

View file

@ -52,7 +52,8 @@ static const int hid1_multipliers_x_10[] = {
0 /* 1111 - off */
};
static const int hid1_7447A_multipliers_x_10[] = {
/* PLL_CFG[0:4] table for cpu 7448/7447A/7455/7457 */
static const int hid1_74xx_multipliers_x_10[] = {
115, /* 00000 - 11.5x */
170, /* 00001 - 17x */
75, /* 00010 - 7.5x */
@ -66,7 +67,7 @@ static const int hid1_7447A_multipliers_x_10[] = {
65, /* 01010 - 6.5x */
130, /* 01011 - 13x */
85, /* 01100 - 8.5x */
240, /* 01101 - 13x */
240, /* 01101 - 24x */
95, /* 01110 - 9.5x */
90, /* 01111 - 9x */
30, /* 10000 - 3x */
@ -126,32 +127,30 @@ int get_clocks (void)
{
ulong clock = 0;
#ifdef CFG_CONFIG_BUS_CLK
gd->bus_clk = get_board_bus_clk();
#ifdef CFG_BUS_CLK
gd->bus_clk = CFG_BUS_CLK; /* bus clock is a fixed frequency */
#else
gd->bus_clk = CFG_BUS_CLK;
gd->bus_clk = get_board_bus_clk (); /* bus clock is configurable */
#endif
/* calculate the clock frequency based upon the CPU type */
switch (get_cpu_type()) {
case CPU_7447A:
case CPU_7448:
clock = (gd->bus_clk / 10) * hid1_7447A_multipliers_x_10[(get_hid1 () >> 12) & 0x1F];
break;
case CPU_7455:
case CPU_7457:
/*
* It is assumed that the PLL_EXT line is zero.
* Make sure division is done before multiplication to prevent 32-bit
* arithmetic overflows which will cause a negative number
*/
clock = (gd->bus_clk / 10) * hid1_multipliers_x_10[(get_hid1 () >> 13) & 0xF];
clock = (gd->bus_clk / 10) *
hid1_74xx_multipliers_x_10[(get_hid1 () >> 12) & 0x1F];
break;
case CPU_750GX:
case CPU_750FX:
clock = gd->bus_clk * hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
clock = gd->bus_clk *
hid1_fx_multipliers_x_10[get_hid1 () >> 27] / 10;
break;
case CPU_7450:
@ -168,7 +167,8 @@ int get_clocks (void)
* Make sure division is done before multiplication to prevent 32-bit
* arithmetic overflows which will cause a negative number
*/
clock = (gd->bus_clk / 10) * hid1_multipliers_x_10[get_hid1 () >> 28];
clock = (gd->bus_clk / 10) *
hid1_multipliers_x_10[get_hid1 () >> 28];
break;
case CPU_UNKNOWN:

View file

@ -44,7 +44,8 @@
#if !defined(CONFIG_DB64360) && \
!defined(CONFIG_DB64460) && \
!defined(CONFIG_CPCI750)
!defined(CONFIG_CPCI750) && \
!defined(CONFIG_P3Mx)
#include <galileo/gt64260R.h>
#endif
@ -270,7 +271,7 @@ in_flash:
* gt-regs BAT can be reused after board_init_f calls
* board_early_init_f (EVB only).
*/
#if !defined(CONFIG_BAB7xx) && !defined(CONFIG_ELPPC)
#if !defined(CONFIG_BAB7xx) && !defined(CONFIG_ELPPC) && !defined(CONFIG_P3Mx)
/* enable address translation */
bl enable_addr_trans
sync
@ -757,7 +758,8 @@ in_ram:
defined(CONFIG_DB64360) || \
defined(CONFIG_DB64460) || \
defined(CONFIG_CPCI750) || \
defined(CONFIG_PPMC7XX)
defined(CONFIG_PPMC7XX) || \
defined(CONFIG_P3Mx)
mr r4, r9 /* Use RAM copy of the global data */
#endif
bl after_reloc

View file

@ -31,6 +31,10 @@
#include <mpc5xxx.h>
#include <asm/processor.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
int checkcpu (void)
@ -102,3 +106,26 @@ unsigned long get_tbclk (void)
}
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_OF_FLAT_TREE
void
ft_cpu_setup(void *blob, bd_t *bd)
{
u32 *p;
int len;
/* Core XLB bus frequency */
p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(bd->bi_busfreq);
/* SOC peripherals use the IPB bus frequency */
p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len);
if (p != NULL)
*p = cpu_to_be32(bd->bi_ipbfreq);
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@3000/mac-address", &len);
if (p != NULL)
memcpy(p, bd->bi_enetaddr, 6);
}
#endif

View file

@ -27,9 +27,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o
START = start.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
i2c.o spd_sdram.o
spd_sdram.o qe_io.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))

View file

@ -1,5 +1,5 @@
/*
* Copyright 2004 Freescale Semiconductor, Inc.
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@ -18,11 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
/*
@ -43,35 +38,140 @@ DECLARE_GLOBAL_DATA_PTR;
int checkcpu(void)
{
volatile immap_t *immr;
ulong clock = gd->cpu_clk;
u32 pvr = get_pvr();
u32 spridr;
char buf[32];
immr = (immap_t *)CFG_IMMR;
if ((pvr & 0xFFFF0000) != PVR_83xx) {
puts("Not MPC83xx Family!!!\n");
return -1;
}
puts("CPU: MPC83xx, ");
switch(pvr) {
case PVR_8349_REV10:
spridr = immr->sysconf.spridr;
puts("CPU: ");
switch(spridr) {
case SPR_8349E_REV10:
case SPR_8349E_REV11:
puts("MPC8349E, ");
break;
case PVR_8349_REV11:
case SPR_8349_REV10:
case SPR_8349_REV11:
puts("MPC8349, ");
break;
case SPR_8347E_REV10_TBGA:
case SPR_8347E_REV11_TBGA:
case SPR_8347E_REV10_PBGA:
case SPR_8347E_REV11_PBGA:
puts("MPC8347E, ");
break;
case SPR_8347_REV10_TBGA:
case SPR_8347_REV11_TBGA:
case SPR_8347_REV10_PBGA:
case SPR_8347_REV11_PBGA:
puts("MPC8347, ");
break;
case SPR_8343E_REV10:
case SPR_8343E_REV11:
puts("MPC8343E, ");
break;
case SPR_8343_REV10:
case SPR_8343_REV11:
puts("MPC8343, ");
break;
case SPR_8360E_REV10:
case SPR_8360E_REV11:
case SPR_8360E_REV12:
puts("MPC8360E, ");
break;
case SPR_8360_REV10:
case SPR_8360_REV11:
case SPR_8360_REV12:
puts("MPC8360, ");
break;
default:
puts("Rev: Unknown\n");
return -1; /* Not sure what this is */
}
printf("Rev: %d.%d at %s MHz\n", (pvr & 0xf0) >> 4,
(pvr & 0x0f), strmhz(buf, clock));
#if defined(CONFIG_MPC8349)
printf("Rev: %02x at %s MHz\n", (spridr & 0x0000FFFF)>>4 |(spridr & 0x0000000F), strmhz(buf, clock));
#else
printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock));
#endif
return 0;
}
/*
* Program a UPM with the code supplied in the table.
*
* The 'dummy' variable is used to increment the MAD. 'dummy' is
* supposed to be a pointer to the memory of the device being
* programmed by the UPM. The data in the MDR is written into
* memory and the MAD is incremented every time there's a read
* from 'dummy'. Unfortunately, the current prototype for this
* function doesn't allow for passing the address of this
* device, and changing the prototype will break a number lots
* of other code, so we need to use a round-about way of finding
* the value for 'dummy'.
*
* The value can be extracted from the base address bits of the
* Base Register (BR) associated with the specific UPM. To find
* that BR, we need to scan all 8 BRs until we find the one that
* has its MSEL bits matching the UPM we want. Once we know the
* right BR, we can extract the base address bits from it.
*
* The MxMR and the BR and OR of the chosen bank should all be
* configured before calling this function.
*
* Parameters:
* upm: 0=UPMA, 1=UPMB, 2=UPMC
* table: Pointer to an array of values to program
* size: Number of elements in the array. Must be 64 or less.
*/
void upmconfig (uint upm, uint *table, uint size)
{
hang(); /* FIXME: upconfig() needed? */
#if defined(CONFIG_MPC834X)
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile lbus83xx_t *lbus = &immap->lbus;
volatile uchar *dummy = NULL;
const u32 msel = (upm + 4) << BR_MSEL_SHIFT; /* What the MSEL field in BRn should be */
volatile u32 *mxmr = &lbus->mamr + upm; /* Pointer to mamr, mbmr, or mcmr */
uint i;
/* Scan all the banks to determine the base address of the device */
for (i = 0; i < 8; i++) {
if ((lbus->bank[i].br & BR_MSEL) == msel) {
dummy = (uchar *) (lbus->bank[i].br & BR_BA);
break;
}
}
if (!dummy) {
printf("Error: %s() could not find matching BR\n", __FUNCTION__);
hang();
}
/* Set the OP field in the MxMR to "write" and the MAD field to 000000 */
*mxmr = (*mxmr & 0xCFFFFFC0) | 0x10000000;
for (i = 0; i < size; i++) {
lbus->mdr = table[i];
__asm__ __volatile__ ("sync");
*dummy; /* Write the value to memory and increment MAD */
__asm__ __volatile__ ("sync");
}
/* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */
*mxmr &= 0xCFFFFFC0;
#else
printf("Error: %s() not defined for this configuration.\n", __FUNCTION__);
hang();
#endif
}
@ -83,7 +183,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
ulong addr;
#endif
volatile immap_t *immap = (immap_t *) CFG_IMMRBAR;
volatile immap_t *immap = (immap_t *) CFG_IMMR;
#ifdef MPC83xx_RESET
/* Interrupts and MMU off */
@ -150,9 +250,21 @@ unsigned long get_tbclk(void)
#if defined(CONFIG_WATCHDOG)
void watchdog_reset (void)
{
hang(); /* FIXME: implement watchdog_reset()? */
#ifdef CONFIG_MPC834X
int re_enable = disable_interrupts();
/* Reset the 83xx watchdog */
volatile immap_t *immr = (immap_t *) CFG_IMMR;
immr->wdt.swsrr = 0x556c;
immr->wdt.swsrr = 0xaa39;
if (re_enable)
enable_interrupts ();
#else
hang();
#endif
}
#endif /* CONFIG_WATCHDOG */
#endif
#if defined(CONFIG_OF_FLAT_TREE)
void
@ -180,12 +292,12 @@ ft_cpu_setup(void *blob, bd_t *bd)
*p = cpu_to_be32(clock);
#ifdef CONFIG_MPC83XX_TSEC1
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len);
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len);
memcpy(p, bd->bi_enetaddr, 6);
#endif
#ifdef CONFIG_MPC83XX_TSEC2
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len);
p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len);
memcpy(p, bd->bi_enet1addr, 6);
#endif
}
@ -194,8 +306,8 @@ ft_cpu_setup(void *blob, bd_t *bd)
#if defined(CONFIG_DDR_ECC)
void dma_init(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile dma8349_t *dma = &immap->dma;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile dma83xx_t *dma = &immap->dma;
volatile u32 status = swab32(dma->dmasr0);
volatile u32 dmamr0 = swab32(dma->dmamr0);
@ -225,8 +337,8 @@ void dma_init(void)
uint dma_check(void)
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile dma8349_t *dma = &immap->dma;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile dma83xx_t *dma = &immap->dma;
volatile u32 status = swab32(dma->dmasr0);
volatile u32 byte_count = swab32(dma->dmabcr0);
@ -244,8 +356,8 @@ uint dma_check(void)
int dma_xfer(void *dest, u32 count, void *src)
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile dma8349_t *dma = &immap->dma;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile dma83xx_t *dma = &immap->dma;
volatile u32 dmamr0;
/* initialize DMASARn, DMADAR and DMAABCRn */

View file

@ -1,5 +1,5 @@
/*
* Copyright 2004 Freescale Semiconductor, Inc.
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@ -18,11 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
#include <common.h>
@ -31,6 +26,30 @@
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_QE
extern qe_iop_conf_t qe_iop_conf_tab[];
extern void qe_config_iopin(u8 port, u8 pin, int dir,
int open_drain, int assign);
extern void qe_init(uint qe_base);
extern void qe_reset(void);
static void config_qe_ioports(void)
{
u8 port, pin;
int dir, open_drain, assign;
int i;
for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) {
port = qe_iop_conf_tab[i].port;
pin = qe_iop_conf_tab[i].pin;
dir = qe_iop_conf_tab[i].dir;
open_drain = qe_iop_conf_tab[i].open_drain;
assign = qe_iop_conf_tab[i].assign;
qe_config_iopin(port, pin, dir, open_drain, assign);
}
}
#endif
/*
* Breathe some life into the CPU...
*
@ -46,6 +65,37 @@ void cpu_init_f (volatile immap_t * im)
/* Clear initial global data */
memset ((void *) gd, 0, sizeof (gd_t));
/* system performance tweaking */
#ifdef CFG_ACR_PIPE_DEP
/* Arbiter pipeline depth */
im->arbiter.acr = (im->arbiter.acr & ~ACR_PIPE_DEP) | (3 << ACR_PIPE_DEP_SHIFT);
#endif
#ifdef CFG_SPCR_TSEC1EP
/* TSEC1 Emergency priority */
im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_TSEC1EP) | (3 << SPCR_TSEC1EP_SHIFT);
#endif
#ifdef CFG_SPCR_TSEC2EP
/* TSEC2 Emergency priority */
im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_TSEC2EP) | (3 << SPCR_TSEC2EP_SHIFT);
#endif
#ifdef CFG_SCCR_TSEC1CM
/* TSEC1 clock mode */
im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC1CM) | (1 << SCCR_TSEC1CM_SHIFT);
#endif
#ifdef CFG_SCCR_TSEC2CM
/* TSEC2 & I2C1 clock mode */
im->clk.sccr = (im->clk.sccr & ~SCCR_TSEC2CM) | (1 << SCCR_TSEC2CM_SHIFT);
#endif
#ifdef CFG_ACR_RPTCNT
/* Arbiter repeat count */
im->arbiter.acr = ((im->arbiter.acr & ~(ACR_RPTCNT)) | (3 << ACR_RPTCNT_SHIFT));
#endif
/* RSR - Reset Status Register - clear all status (4.6.1.3) */
gd->reset_status = im->reset.rsr;
im->reset.rsr = ~(RSR_RES);
@ -69,6 +119,10 @@ void cpu_init_f (volatile immap_t * im)
#ifdef CFG_SICRL
im->sysconf.sicrl = CFG_SICRL;
#endif
#ifdef CONFIG_QE
/* Config QE ioports */
config_qe_ioports();
#endif
/*
* Memory Controller:
@ -157,12 +211,12 @@ void cpu_init_f (volatile immap_t * im)
#endif
}
/*
* Initialize higher level parts of CPU like time base and timers.
*/
int cpu_init_r (void)
{
#ifdef CONFIG_QE
uint qe_base = CFG_IMMR + 0x00100000; /* QE immr base */
qe_init(qe_base);
qe_reset();
#endif
return 0;
}

View file

@ -1,253 +0,0 @@
/*
* (C) Copyright 2003,Motorola Inc.
* Xianghua Xiao <x.xiao@motorola.com>
* Adapted for Motorola 85xx chip.
*
* (C) Copyright 2003
* Gleb Natapov <gnatapov@mrv.com>
* Some bits are taken from linux driver writen by adrian@humboldt.co.uk
*
* Hardware I2C driver for MPC107 PCI bridge.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
#include <common.h>
#include <command.h>
#include <asm/io.h>
#ifdef CONFIG_HARD_I2C
#include <i2c.h>
#include <asm/i2c.h>
#if defined(CONFIG_MPC8349EMDS) || defined(CONFIG_TQM834X)
i2c_t * mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET);
#endif
void
i2c_init(int speed, int slaveadd)
{
/* stop I2C controller */
writeb(0x00 , &I2C->cr);
/* set clock */
writeb(0x3f, &I2C->fdr);
/* set default filter */
writeb(0x10,&I2C->dfsrr);
/* write slave address */
writeb(slaveadd, &I2C->adr);
/* clear status register */
writeb(0x00, &I2C->sr);
/* start I2C controller */
writeb(I2C_CR_MEN, &I2C->cr);
}
static __inline__ int
i2c_wait4bus (void)
{
ulong timeval = get_timer (0);
while (readb(&I2C->sr) & I2C_SR_MBB) {
if (get_timer (timeval) > I2C_TIMEOUT) {
return -1;
}
}
return 0;
}
static __inline__ int
i2c_wait (int write)
{
u32 csr;
ulong timeval = get_timer(0);
do {
csr = readb(&I2C->sr);
if (!(csr & I2C_SR_MIF))
continue;
writeb(0x0, &I2C->sr);
if (csr & I2C_SR_MAL) {
debug("i2c_wait: MAL\n");
return -1;
}
if (!(csr & I2C_SR_MCF)) {
debug("i2c_wait: unfinished\n");
return -1;
}
if (write == I2C_WRITE && (csr & I2C_SR_RXAK)) {
debug("i2c_wait: No RXACK\n");
return -1;
}
return 0;
} while (get_timer (timeval) < I2C_TIMEOUT);
debug("i2c_wait: timed out\n");
return -1;
}
static __inline__ int
i2c_write_addr (u8 dev, u8 dir, int rsta)
{
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX |
(rsta?I2C_CR_RSTA:0),
&I2C->cr);
writeb((dev << 1) | dir, &I2C->dr);
if (i2c_wait (I2C_WRITE) < 0)
return 0;
return 1;
}
static __inline__ int
__i2c_write (u8 *data, int length)
{
int i;
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
&I2C->cr);
for (i=0; i < length; i++) {
writeb(data[i], &I2C->dr);
if (i2c_wait (I2C_WRITE) < 0)
break;
}
return i;
}
static __inline__ int
__i2c_read (u8 *data, int length)
{
int i;
writeb(I2C_CR_MEN | I2C_CR_MSTA |
((length == 1) ? I2C_CR_TXAK : 0),
&I2C->cr);
/* dummy read */
readb(&I2C->dr);
for (i=0; i < length; i++) {
if (i2c_wait (I2C_READ) < 0)
break;
/* Generate ack on last next to last byte */
if (i == length - 2)
writeb(I2C_CR_MEN | I2C_CR_MSTA |
I2C_CR_TXAK,
&I2C->cr);
/* Generate stop on last byte */
if (i == length - 1)
writeb(I2C_CR_MEN | I2C_CR_TXAK, &I2C->cr);
data[i] = readb(&I2C->dr);
}
return i;
}
int
i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
{
int i = 0;
u8 *a = (u8*)&addr;
if (i2c_wait4bus () < 0)
goto exit;
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
goto exit;
if (__i2c_write (&a[4 - alen], alen) != alen)
goto exit;
if (i2c_write_addr (dev, I2C_READ, 1) == 0)
goto exit;
i = __i2c_read (data, length);
exit:
writeb(I2C_CR_MEN, &I2C->cr);
return !(i == length);
}
int
i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
{
int i = 0;
u8 *a = (u8*)&addr;
if (i2c_wait4bus () < 0)
goto exit;
if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
goto exit;
if (__i2c_write (&a[4 - alen], alen) != alen)
goto exit;
i = __i2c_write (data, length);
exit:
writeb(I2C_CR_MEN, &I2C->cr);
return !(i == length);
}
int i2c_probe (uchar chip)
{
int tmp;
/*
* Try to read the first location of the chip. The underlying
* driver doesn't appear to support sending just the chip address
* and looking for an <ACK> back.
*/
udelay(10000);
return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
}
uchar i2c_reg_read (uchar i2c_addr, uchar reg)
{
uchar buf[1];
i2c_read (i2c_addr, reg, 1, buf, 1);
return (buf[0]);
}
void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
{
i2c_write (i2c_addr, reg, 1, &val, 1);
}
#endif /* CONFIG_HARD_I2C */

View file

@ -21,13 +21,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 22-Oct-00
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
#include <common.h>
@ -45,7 +38,7 @@ struct irq_action {
int interrupt_init_cpu (unsigned *decrementer_count)
{
volatile immap_t *immr = (immap_t *) CFG_IMMRBAR;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
*decrementer_count = (gd->bus_clk / 4) / CFG_HZ;

85
cpu/mpc83xx/qe_io.c Normal file
View file

@ -0,0 +1,85 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on source code of Shlomi Gridish
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "common.h"
#include "asm/errno.h"
#include "asm/io.h"
#include "asm/immap_83xx.h"
#if defined(CONFIG_QE)
#define NUM_OF_PINS 32
void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign)
{
u32 pin_2bit_mask;
u32 pin_2bit_dir;
u32 pin_2bit_assign;
u32 pin_1bit_mask;
u32 tmp_val;
volatile immap_t *im = (volatile immap_t *)CFG_IMMR;
volatile gpio83xx_t *par_io =(volatile gpio83xx_t *)&im->gpio;
/* Caculate pin location and 2bit mask and dir */
pin_2bit_mask = (u32)(0x3 << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2));
pin_2bit_dir = (u32)(dir << (NUM_OF_PINS-(pin%(NUM_OF_PINS/2)+1)*2));
/* Setup the direction */
tmp_val = (pin > (NUM_OF_PINS/2) - 1) ? \
in_be32(&par_io->ioport[port].dir2) :
in_be32(&par_io->ioport[port].dir1);
if (pin > (NUM_OF_PINS/2) -1) {
out_be32(&par_io->ioport[port].dir2, ~pin_2bit_mask & tmp_val);
out_be32(&par_io->ioport[port].dir2, pin_2bit_dir | tmp_val);
} else {
out_be32(&par_io->ioport[port].dir1, ~pin_2bit_mask & tmp_val);
out_be32(&par_io->ioport[port].dir1, pin_2bit_dir | tmp_val);
}
/* Calculate pin location for 1bit mask */
pin_1bit_mask = (u32)(1 << (NUM_OF_PINS - (pin+1)));
/* Setup the open drain */
tmp_val = in_be32(&par_io->ioport[port].podr);
if (open_drain) {
out_be32(&par_io->ioport[port].podr, pin_1bit_mask | tmp_val);
} else {
out_be32(&par_io->ioport[port].podr, ~pin_1bit_mask & tmp_val);
}
/* Setup the assignment */
tmp_val = (pin > (NUM_OF_PINS/2) - 1) ?
in_be32(&par_io->ioport[port].ppar2):
in_be32(&par_io->ioport[port].ppar1);
pin_2bit_assign = (u32)(assign
<< (NUM_OF_PINS - (pin%(NUM_OF_PINS/2)+1)*2));
/* Clear and set 2 bits mask */
if (pin > (NUM_OF_PINS/2) - 1) {
out_be32(&par_io->ioport[port].ppar2, ~pin_2bit_mask & tmp_val);
out_be32(&par_io->ioport[port].ppar2, pin_2bit_assign | tmp_val);
} else {
out_be32(&par_io->ioport[port].ppar1, ~pin_2bit_mask & tmp_val);
out_be32(&par_io->ioport[port].ppar1, pin_2bit_assign | tmp_val);
}
}
#endif /* CONFIG_QE */

View file

@ -1,6 +0,0 @@
.section .resetvec,"ax"
#ifndef FIXME
#if 0
b _start_e500
#endif
#endif

View file

@ -1,8 +1,10 @@
/*
* (C) Copyright 2006 Freescale Semiconductor, Inc.
*
* (C) Copyright 2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Copyright 2004 Freescale Semiconductor.
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao (X.Xiao@motorola.com)
*
@ -23,11 +25,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
#include <common.h>
@ -39,7 +36,9 @@
#ifdef CONFIG_SPD_EEPROM
#if defined(CONFIG_DDR_ECC)
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
extern void dma_init(void);
extern uint dma_check(void);
extern int dma_xfer(void *dest, uint count, void *src);
@ -52,16 +51,16 @@ extern int dma_xfer(void *dest, uint count, void *src);
/*
* Convert picoseconds into clock cycles (rounding up if needed).
*/
int
picos_to_clk(int picos)
{
unsigned int ddr_bus_clk;
int clks;
clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
ddr_bus_clk = gd->ddr_clk >> 1;
clks = picos / ((1000000000 / ddr_bus_clk) * 1000);
if (picos % ((1000000000 / ddr_bus_clk) * 1000) != 0)
clks++;
}
return clks;
}
@ -103,33 +102,72 @@ static void spd_debug(spd_eeprom_t *spd)
long int spd_sdram()
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
volatile law8349_t *ecm = &immap->sysconf.ddrlaw[0];
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ddr83xx_t *ddr = &immap->ddr;
volatile law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
spd_eeprom_t spd;
unsigned tmp, tmp1;
unsigned int memsize;
unsigned int law_size;
unsigned char caslat;
unsigned int trfc, trfc_clk, trfc_low;
unsigned char caslat, caslat_ctrl;
unsigned char burstlen;
unsigned int max_bus_clk;
unsigned int max_data_rate, effective_data_rate;
unsigned int ddrc_clk;
unsigned int refresh_clk;
unsigned sdram_cfg;
unsigned int ddrc_ecc_enable;
/* Read SPD parameters with I2C */
CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
#ifdef SPD_DEBUG
spd_debug(&spd);
#endif
/* Check the memory type */
if (spd.mem_type != SPD_MEMTYPE_DDR) {
printf("DDR: Module mem type is %02X\n", spd.mem_type);
return 0;
}
/* Check the number of physical bank */
if (spd.nrows > 2) {
puts("DDR:Only two chip selects are supported on ADS.\n");
printf("DDR: The number of physical bank is %02X\n", spd.nrows);
return 0;
}
if (spd.nrow_addr < 12
|| spd.nrow_addr > 14
|| spd.ncol_addr < 8
|| spd.ncol_addr > 11) {
puts("DDR:Row or Col number unsupported.\n");
/* Check if the number of row of the module is in the range of DDRC */
if (spd.nrow_addr < 12 || spd.nrow_addr > 14) {
printf("DDR: Row number is out of range of DDRC, row=%02X\n",
spd.nrow_addr);
return 0;
}
/* Check if the number of col of the module is in the range of DDRC */
if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
printf("DDR: Col number is out of range of DDRC, col=%02X\n",
spd.ncol_addr);
return 0;
}
/* Setup DDR chip select register */
#ifdef CFG_83XX_DDR_USES_CS0
ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1;
ddr->cs_config[0] = ( 1 << 31
| (spd.nrow_addr - 12) << 8
| (spd.ncol_addr - 8) );
debug("\n");
debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds);
debug("cs0_config = 0x%08x\n",ddr->cs_config[0]);
if (spd.nrows == 2) {
ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8)
| ((banksize(spd.row_dens) >> 23) - 1) );
ddr->cs_config[1] = ( 1<<31
| (spd.nrow_addr-12) << 8
| (spd.ncol_addr-8) );
debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds);
debug("cs1_config = 0x%08x\n",ddr->cs_config[1]);
}
#else
ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1;
ddr->cs_config[2] = ( 1 << 31
| (spd.nrow_addr - 12) << 8
@ -147,6 +185,7 @@ long int spd_sdram()
debug("cs3_bnds = 0x%08x\n",ddr->csbnds[3].csbnds);
debug("cs3_config = 0x%08x\n",ddr->cs_config[3]);
}
#endif
if (spd.mem_type != 0x07) {
puts("No DDR module found!\n");
@ -172,55 +211,135 @@ long int spd_sdram()
debug("DDR:ar=0x%08x\n", ecm->ar);
/*
* find the largest CAS
* Find the largest CAS by locating the highest 1 bit
* in the spd.cas_lat field. Translate it to a DDR
* controller field value:
*
* CAS Lat DDR I Ctrl
* Clocks SPD Bit Value
* -------+--------+---------
* 1.0 0 001
* 1.5 1 010
* 2.0 2 011
* 2.5 3 100
* 3.0 4 101
* 3.5 5 110
* 4.0 6 111
*/
if(spd.cas_lat & 0x40) {
caslat = 7;
} else if (spd.cas_lat & 0x20) {
caslat = 6;
} else if (spd.cas_lat & 0x10) {
caslat = 5;
} else if (spd.cas_lat & 0x08) {
caslat = 4;
} else if (spd.cas_lat & 0x04) {
caslat = 3;
} else if (spd.cas_lat & 0x02) {
caslat = 2;
} else if (spd.cas_lat & 0x01) {
caslat = 1;
} else {
puts("DDR:no valid CAS Latency information.\n");
caslat = __ilog2(spd.cas_lat);
if (caslat > 6 ) {
printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n",
spd.cas_lat);
return 0;
}
tmp = 20000 / (((spd.clk_cycle & 0xF0) >> 4) * 10
max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10
+ (spd.clk_cycle & 0x0f));
debug("DDR:Module maximum data rate is: %dMhz\n", tmp);
max_data_rate = max_bus_clk * 2;
tmp1 = get_bus_freq(0) / 1000000;
if (tmp1 < 230 && tmp1 >= 90 && tmp >= 230) {
/* 90~230 range, treated as DDR 200 */
if (spd.clk_cycle3 == 0xa0)
caslat -= 2;
else if(spd.clk_cycle2 == 0xa0)
caslat--;
} else if (tmp1 < 280 && tmp1 >= 230 && tmp >= 280) {
/* 230-280 range, treated as DDR 266 */
debug("DDR:Module maximum data rate is: %dMhz\n", max_data_rate);
ddrc_clk = gd->ddr_clk / 1000000;
if (max_data_rate >= 390) { /* it is DDR 400 */
if (ddrc_clk <= 410 && ddrc_clk > 350) {
/* DDR controller clk at 350~410 */
effective_data_rate = 400; /* 5ns */
caslat = caslat;
} else if (ddrc_clk <= 350 && ddrc_clk > 280) {
/* DDR controller clk at 280~350 */
effective_data_rate = 333; /* 6ns */
if (spd.clk_cycle2 == 0x60)
caslat = caslat - 1;
else
caslat = caslat;
} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
/* DDR controller clk at 230~280 */
effective_data_rate = 266; /* 7.5ns */
if (spd.clk_cycle3 == 0x75)
caslat -= 2;
else if (spd.clk_cycle2 == 0x75)
caslat--;
} else if (tmp1 < 350 && tmp1 >= 280 && tmp >= 350) {
/* 280~350 range, treated as DDR 333 */
if (spd.clk_cycle3 == 0x60)
caslat -= 2;
caslat = caslat - 2;
else if (spd.clk_cycle2 == 0x60)
caslat--;
} else if (tmp1 < 90 || tmp1 >= 350) {
/* DDR rate out-of-range */
puts("DDR:platform frequency is not fit for DDR rate\n");
return 0;
caslat = caslat - 1;
else
caslat = caslat;
} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
/* DDR controller clk at 90~230 */
effective_data_rate = 200; /* 10ns */
if (spd.clk_cycle3 == 0x75)
caslat = caslat - 2;
else if (spd.clk_cycle2 == 0x60)
caslat = caslat - 1;
else
caslat = caslat;
}
} else if (max_data_rate >= 323) { /* it is DDR 333 */
if (ddrc_clk <= 350 && ddrc_clk > 280) {
/* DDR controller clk at 280~350 */
effective_data_rate = 333; /* 6ns */
caslat = caslat;
} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
/* DDR controller clk at 230~280 */
effective_data_rate = 266; /* 7.5ns */
if (spd.clk_cycle2 == 0x75)
caslat = caslat - 1;
else
caslat = caslat;
} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
/* DDR controller clk at 90~230 */
effective_data_rate = 200; /* 10ns */
if (spd.clk_cycle3 == 0xa0)
caslat = caslat - 2;
else if (spd.clk_cycle2 == 0x75)
caslat = caslat - 1;
else
caslat = caslat;
}
} else if (max_data_rate >= 256) { /* it is DDR 266 */
if (ddrc_clk <= 350 && ddrc_clk > 280) {
/* DDR controller clk at 280~350 */
printf("DDR: DDR controller freq is more than "
"max data rate of the module\n");
return 0;
} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
/* DDR controller clk at 230~280 */
effective_data_rate = 266; /* 7.5ns */
caslat = caslat;
} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
/* DDR controller clk at 90~230 */
effective_data_rate = 200; /* 10ns */
if (spd.clk_cycle2 == 0xa0)
caslat = caslat - 1;
}
} else if (max_data_rate >= 190) { /* it is DDR 200 */
if (ddrc_clk <= 350 && ddrc_clk > 230) {
/* DDR controller clk at 230~350 */
printf("DDR: DDR controller freq is more than "
"max data rate of the module\n");
return 0;
} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
/* DDR controller clk at 90~230 */
effective_data_rate = 200; /* 10ns */
caslat = caslat;
}
}
debug("DDR:Effective data rate is: %dMhz\n", effective_data_rate);
debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat);
/*
* Errata DDR6 work around: input enable 2 cycles earlier.
* including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
*/
if (caslat == 2)
ddr->debug_reg = 0x201c0000; /* CL=2 */
else if (caslat == 3)
ddr->debug_reg = 0x202c0000; /* CL=2.5 */
else if (caslat == 4)
ddr->debug_reg = 0x202c0000; /* CL=3.0 */
__asm__ __volatile__ ("sync");
debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);
/*
* note: caslat must also be programmed into ddr->sdram_mode
@ -229,16 +348,14 @@ long int spd_sdram()
* note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,
* use conservative value here.
*/
trfc = spd.trfc * 1000; /* up to ps */
trfc_clk = picos_to_clk(trfc);
trfc_low = (trfc_clk - 8) & 0xf;
caslat_ctrl = (caslat + 1) & 0x07; /* see as above */
ddr->timing_cfg_1 =
(((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |
((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) |
((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) |
((caslat & 0x07) << 16 ) |
(trfc_low << 12 ) |
((caslat_ctrl & 0x07) << 16 ) |
(((picos_to_clk(spd.trfc * 1000) - 8) & 0x0f) << 12 ) |
( 0x300 ) |
((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1);
@ -246,65 +363,73 @@ long int spd_sdram()
debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1);
debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
/* Setup init value, but not enable */
ddr->sdram_cfg = 0x42000000;
/*
* Only DDR I is supported
* DDR I and II have different mode-register-set definition
/* Check DIMM data bus width */
if (spd.dataw_lsb == 0x20) {
burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
printf("\n DDR DIMM: data bus width is 32 bit");
} else {
burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */
printf("\n DDR DIMM: data bus width is 64 bit");
}
/* Is this an ECC DDR chip? */
if (spd.config == 0x02)
printf(" with ECC\n");
else
printf(" without ECC\n");
/* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus,
Burst type is sequential
*/
switch (caslat) {
case 1:
ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */
break;
case 2:
tmp = 0x50; /* 1.5 */
ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */
break;
case 3:
tmp = 0x20; /* 2.0 */
ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */
break;
case 4:
tmp = 0x60; /* 2.5 */
break;
case 5:
tmp = 0x30; /* 3.0 */
ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */
break;
default:
puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n");
printf("DDR:only CL 1.5, 2.0, 2.5, 3.0 is supported\n");
return 0;
}
#if defined (CONFIG_DDR_32BIT)
/* set burst length to 8 for 32-bit data path */
tmp |= 0x03;
#else
/* set burst length to 4 - default for 64-bit data path */
tmp |= 0x02;
#endif
ddr->sdram_mode = tmp;
debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
switch (spd.refresh) {
case 0x00:
case 0x80:
tmp = picos_to_clk(15625000);
refresh_clk = picos_to_clk(15625000);
break;
case 0x01:
case 0x81:
tmp = picos_to_clk(3900000);
refresh_clk = picos_to_clk(3900000);
break;
case 0x02:
case 0x82:
tmp = picos_to_clk(7800000);
refresh_clk = picos_to_clk(7800000);
break;
case 0x03:
case 0x83:
tmp = picos_to_clk(31300000);
refresh_clk = picos_to_clk(31300000);
break;
case 0x04:
case 0x84:
tmp = picos_to_clk(62500000);
refresh_clk = picos_to_clk(62500000);
break;
case 0x05:
case 0x85:
tmp = picos_to_clk(125000000);
refresh_clk = picos_to_clk(125000000);
break;
default:
tmp = 0x512;
refresh_clk = 0x512;
break;
}
@ -312,78 +437,69 @@ long int spd_sdram()
* Set BSTOPRE to 0x100 for page mode
* If auto-charge is used, set BSTOPRE = 0
*/
ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100;
debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);
/*
* Is this an ECC DDR chip?
/* SS_EN = 0, source synchronous disable
* CLK_ADJST = 0, MCK/MCK# is launched aligned with addr/cmd
*/
#if defined(CONFIG_DDR_ECC)
if (spd.config == 0x02) {
/* disable error detection */
ddr->err_disable = ~ECC_ERROR_ENABLE;
ddr->sdram_clk_cntl = 0x00000000;
debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);
/* set single bit error threshold to maximum value,
* reset counter to zero */
ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
(0 << ECC_ERROR_MAN_SBEC_SHIFT);
}
debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
#endif
asm("sync;isync");
udelay(500);
/*
* SS_EN=1,
* CLK_ADJST = 2-MCK/MCK_B, is lauched 1/2 of one SDRAM
* clock cycle after address/command
*/
/*ddr->sdram_clk_cntl = 0x82000000;*/
ddr->sdram_clk_cntl = (DDR_SDRAM_CLK_CNTL_SS_EN|DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05);
udelay(600);
/*
* Figure out the settings for the sdram_cfg register. Build up
* the entire register in 'tmp' before writing since the write into
* the value in 'sdram_cfg' before writing since the write into
* the register will actually enable the memory controller, and all
* settings must be done before enabling.
*
* sdram_cfg[0] = 1 (ddr sdram logic enable)
* sdram_cfg[1] = 1 (self-refresh-enable)
* sdram_cfg[6:7] = 2 (SDRAM type = DDR SDRAM)
* sdram_cfg[12] = 0 (32_BE =0 , 64 bit bus mode)
* sdram_cfg[13] = 0 (8_BE =0, 4-beat bursts)
*/
tmp = 0xc2000000;
sdram_cfg = 0xC2000000;
#if defined (CONFIG_DDR_32BIT)
/* in 32-Bit mode burst len is 8 beats */
tmp |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE);
#endif
/*
* sdram_cfg[3] = RD_EN - registered DIMM enable
* A value of 0x26 indicates micron registered DIMMS (micron.com)
*/
if (spd.mod_attr == 0x26) {
tmp |= 0x10000000;
}
/* sdram_cfg[3] = RD_EN - registered DIMM enable */
if (spd.mod_attr & 0x02)
sdram_cfg |= 0x10000000;
/* The DIMM is 32bit width */
if (spd.dataw_lsb == 0x20)
sdram_cfg |= 0x000C0000;
ddrc_ecc_enable = 0;
#if defined(CONFIG_DDR_ECC)
/*
* If the user wanted ECC (enabled via sdram_cfg[2])
*/
/* Enable ECC with sdram_cfg[2] */
if (spd.config == 0x02) {
tmp |= SDRAM_CFG_ECC_EN;
sdram_cfg |= 0x20000000;
ddrc_ecc_enable = 1;
/* disable error detection */
ddr->err_disable = ~ECC_ERROR_ENABLE;
/* set single bit error threshold to maximum value,
* reset counter to zero */
ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
(0 << ECC_ERROR_MAN_SBEC_SHIFT);
}
debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
#endif
printf(" DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF");
#if defined(CONFIG_DDR_2T_TIMING)
/*
* Enable 2T timing by setting sdram_cfg[16].
*/
tmp |= SDRAM_CFG_2T_EN;
sdram_cfg |= SDRAM_CFG_2T_EN;
#endif
ddr->sdram_cfg = tmp;
/* Enable controller, and GO! */
ddr->sdram_cfg = sdram_cfg;
asm("sync;isync");
udelay(500);
@ -392,8 +508,7 @@ long int spd_sdram()
}
#endif /* CONFIG_SPD_EEPROM */
#if defined(CONFIG_DDR_ECC)
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
/*
* Use timebase counter, get_timer() is not availabe
* at this point of initialization yet.
@ -429,74 +544,48 @@ static __inline__ unsigned long get_tbms (void)
/* #define CONFIG_DDR_ECC_INIT_VIA_DMA */
void ddr_enable_ecc(unsigned int dram_size)
{
uint *p;
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile ddr83xx_t *ddr= &immap->ddr;
unsigned long t_start, t_end;
register u64 *p;
register uint size;
unsigned int pattern[2];
#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
uint i;
#endif
debug("Initialize a Cachline in DRAM\n");
icache_enable();
#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
/* Initialise DMA for direct Transfers */
dma_init();
#endif
t_start = get_tbms();
pattern[0] = 0xdeadbeef;
pattern[1] = 0xdeadbeef;
#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
debug("DDR init: Cache flush method\n");
for (p = 0; p < (uint *)(dram_size); p++) {
if (((unsigned int)p & 0x1f) == 0) {
ppcDcbz((unsigned long) p);
}
/* write pattern to cache and flush */
*p = (unsigned int)0xdeadbeef;
if (((unsigned int)p & 0x1c) == 0x1c) {
ppcDcbf((unsigned long) p);
}
debug("ddr init: CPU FP write method\n");
size = dram_size;
for (p = 0; p < (u64*)(size); p++) {
ppcDWstore((u32*)p, pattern);
}
__asm__ __volatile__ ("sync");
#else
printf("DDR init: DMA method\n");
for (p = 0; p < (uint *)(8 * 1024); p++) {
/* zero one data cache line */
if (((unsigned int)p & 0x1f) == 0) {
ppcDcbz((unsigned long)p);
debug("ddr init: DMA method\n");
size = 0x2000;
for (p = 0; p < (u64*)(size); p++) {
ppcDWstore((u32*)p, pattern);
}
__asm__ __volatile__ ("sync");
/* write pattern to it and flush */
*p = (unsigned int)0xdeadbeef;
if (((unsigned int)p & 0x1c) == 0x1c) {
ppcDcbf((unsigned long)p);
}
}
/* 8K */
dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
/* 16K */
dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
/* 32K */
dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
/* 64K */
dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
/* 128k */
dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
/* 256k */
dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
/* 512k */
dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
/* 1M */
dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
/* 2M */
dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
/* 4M */
dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
/* Initialise DMA for direct transfer */
dma_init();
/* Start DMA to transfer */
dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */
dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */
dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */
dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */
dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */
dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */
dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */
dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);

View file

@ -2,7 +2,7 @@
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Copyright 2004 Freescale Semiconductor, Inc.
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@ -21,11 +21,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
#include <common.h>
@ -94,7 +89,7 @@ corecnf_t corecnf_tab[] = {
*/
int get_clocks(void)
{
volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
volatile immap_t *im = (immap_t *) CFG_IMMR;
u32 pci_sync_in;
u8 spmf;
u8 clkin_div;
@ -104,79 +99,52 @@ int get_clocks (void)
u32 lcrr;
u32 csb_clk;
#if defined(CONFIG_MPC8349)
u32 tsec1_clk;
u32 tsec2_clk;
u32 core_clk;
u32 usbmph_clk;
u32 usbdr_clk;
u32 i2c_clk;
#endif
u32 core_clk;
u32 i2c1_clk;
u32 i2c2_clk;
u32 enc_clk;
u32 lbiu_clk;
u32 lclk_clk;
u32 ddr_clk;
#if defined (CONFIG_MPC8360)
u32 qepmf;
u32 qepdf;
u32 ddr_sec_clk;
u32 qe_clk;
u32 brg_clk;
#endif
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
return -1;
#ifndef CFG_HRCW_HIGH
# error "CFG_HRCW_HIGH must be defined in board config file"
#endif /* CFG_HCWD_HIGH */
#if (CFG_HRCW_HIGH & HRCWH_PCI_HOST)
# ifndef CONFIG_83XX_CLKIN
# error "In PCI Host Mode, CONFIG_83XX_CLKIN must be defined in board config file"
# endif /* CONFIG_83XX_CLKIN */
# ifdef CONFIG_83XX_PCICLK
# warning "In PCI Host Mode, CONFIG_83XX_PCICLK in board config file is igonred"
# endif /* CONFIG_83XX_PCICLK */
/* PCI Host Mode */
if (!(im->reset.rcwh & RCWH_PCIHOST)) {
/* though RCWH_PCIHOST is defined in CFG_HRCW_HIGH
* the im->reset.rcwhr PCI Host Mode is disabled
* FIXME: findout if there is a way to issue some warning */
return -2;
}
if (im->clk.spmr & SPMR_CKID) {
/* PCI Clock is half CONFIG_83XX_CLKIN */
pci_sync_in = CONFIG_83XX_CLKIN / 2;
}
else {
pci_sync_in = CONFIG_83XX_CLKIN;
}
#else /* (CFG_HRCW_HIGH & HRCWH_PCI_HOST) */
# ifdef CONFIG_83XX_CLKIN
# warning "In PCI Agent Mode, CONFIG_83XX_CLKIN in board config file is igonred"
# endif /* CONFIG_83XX_CLKIN */
# ifndef CONFIG_83XX_PCICLK
# error "In PCI Agent Mode, CONFIG_83XX_PCICLK must be defined in board config file"
# endif /* CONFIG_83XX_PCICLK */
/* PCI Agent Mode */
if (im->reset.rcwh & RCWH_PCIHOST) {
/* though RCWH_PCIHOST is not defined in CFG_HRCW_HIGH
* the im->reset.rcwhr PCI Host Mode is enabled */
return -3;
}
pci_sync_in = CONFIG_83XX_PCICLK;
#endif /* (CFG_HRCW_HIGH | RCWH_PCIHOST) */
/* we have up to date pci_sync_in */
spmf = ((im->reset.rcwl & RCWL_SPMF) >> RCWL_SPMF_SHIFT);
clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT);
if ((im->reset.rcwl & RCWL_LBIUCM) || (im->reset.rcwl & RCWL_DDRCM)) {
csb_clk = (pci_sync_in * spmf * (1 + clkin_div)) / 2;
}
else {
csb_clk = pci_sync_in * spmf * (1 + clkin_div);
if (im->reset.rcwh & HRCWH_PCI_HOST) {
#if defined(CONFIG_83XX_CLKIN)
pci_sync_in = CONFIG_83XX_CLKIN / (1 + clkin_div);
#else
pci_sync_in = 0xDEADBEEF;
#endif
} else {
#if defined(CONFIG_83XX_PCICLK)
pci_sync_in = CONFIG_83XX_PCICLK;
#else
pci_sync_in = 0xDEADBEEF;
#endif
}
spmf = ((im->reset.rcwl & RCWL_SPMF) >> RCWL_SPMF_SHIFT);
csb_clk = pci_sync_in * (1 + clkin_div) * spmf;
sccr = im->clk.sccr;
#if defined(CONFIG_MPC8349)
switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
case 0:
tsec1_clk = 0;
@ -212,25 +180,8 @@ int get_clocks (void)
/* unkown SCCR_TSEC2CM value */
return -5;
}
i2c_clk = tsec2_clk;
switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
case 0:
enc_clk = 0;
break;
case 1:
enc_clk = csb_clk;
break;
case 2:
enc_clk = csb_clk / 2;
break;
case 3:
enc_clk = csb_clk / 3;
break;
default:
/* unkown SCCR_ENCCM value */
return -6;
}
i2c1_clk = tsec2_clk;
switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
case 0:
@ -268,14 +219,42 @@ int get_clocks (void)
return -8;
}
if (usbmph_clk != 0
&& usbdr_clk != 0
&& usbmph_clk != usbdr_clk ) {
/* if USB MPH clock is not disabled and USB DR clock is not disabled than USB MPH & USB DR must have the same rate */
if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
/* if USB MPH clock is not disabled and
* USB DR clock is not disabled then
* USB MPH & USB DR must have the same rate
*/
return -9;
}
#endif
#if defined (CONFIG_MPC8360)
i2c1_clk = csb_clk;
#endif
i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
lbiu_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT));
switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
case 0:
enc_clk = 0;
break;
case 1:
enc_clk = csb_clk;
break;
case 2:
enc_clk = csb_clk / 2;
break;
case 3:
enc_clk = csb_clk / 3;
break;
default:
/* unkown SCCR_ENCCM value */
return -6;
}
#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360)
lbiu_clk = csb_clk *
(1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT));
#else
#error Unknown MPC83xx chip
#endif
lcrr = (im->lbus.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT;
switch (lcrr) {
case 2:
@ -287,10 +266,18 @@ int get_clocks (void)
/* unknown lcrr */
return -10;
}
ddr_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_DDRCM) >> RCWL_DDRCM_SHIFT));
#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360)
ddr_clk = csb_clk *
(1 + ((im->reset.rcwl & RCWL_DDRCM) >> RCWL_DDRCM_SHIFT));
corepll = (im->reset.rcwl & RCWL_COREPLL) >> RCWL_COREPLL_SHIFT;
#if defined (CONFIG_MPC8360)
ddr_sec_clk = csb_clk * (1 +
((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT));
#endif
#else
#error Unknown MPC83xx chip
#endif
corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5);
if (corecnf_tab_index > (sizeof(corecnf_tab) / sizeof(corecnf_t))) {
/* corecnf_tab_index is too high, possibly worng value */
@ -319,22 +306,36 @@ int get_clocks (void)
return -12;
}
#if defined (CONFIG_MPC8360)
qepmf = (im->reset.rcwl & RCWL_CEPMF) >> RCWL_CEPMF_SHIFT;
qepdf = (im->reset.rcwl & RCWL_CEPDF) >> RCWL_CEPDF_SHIFT;
qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
brg_clk = qe_clk / 2;
#endif
gd->csb_clk = csb_clk;
#if defined(CONFIG_MPC8349)
gd->tsec1_clk = tsec1_clk;
gd->tsec2_clk = tsec2_clk;
gd->core_clk = core_clk ;
gd->usbmph_clk = usbmph_clk;
gd->usbdr_clk = usbdr_clk;
gd->i2c_clk = i2c_clk ;
#endif
gd->core_clk = core_clk;
gd->i2c1_clk = i2c1_clk;
gd->i2c2_clk = i2c2_clk;
gd->enc_clk = enc_clk;
gd->lbiu_clk = lbiu_clk;
gd->lclk_clk = lclk_clk;
gd->ddr_clk = ddr_clk;
gd->pci_clk = pci_sync_in;
#if defined (CONFIG_MPC8360)
gd->ddr_sec_clk = ddr_sec_clk;
gd->qe_clk = qe_clk;
gd->brg_clk = brg_clk;
#endif
gd->cpu_clk = gd->core_clk;
gd->bus_clk = gd->lbiu_clk;
gd->bus_clk = gd->csb_clk;
return 0;
}
/********************************************
@ -351,14 +352,23 @@ int print_clock_conf (void)
printf("Clock configuration:\n");
printf(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000);
printf(" Core: %4d MHz\n", gd->core_clk / 1000000);
debug(" Local Bus Controller:%4d MHz\n",gd->lbiu_clk/1000000);
#if defined (CONFIG_MPC8360)
printf(" QE: %4d MHz\n", gd->qe_clk / 1000000);
#endif
printf(" Local Bus Controller:%4d MHz\n", gd->lbiu_clk / 1000000);
printf(" Local Bus: %4d MHz\n", gd->lclk_clk / 1000000);
debug(" DDR: %4d MHz\n",gd->ddr_clk/1000000);
debug(" I2C: %4d MHz\n",gd->i2c_clk/1000000);
debug(" TSEC1: %4d MHz\n",gd->tsec1_clk/1000000);
debug(" TSEC2: %4d MHz\n",gd->tsec2_clk/1000000);
debug(" USB MPH: %4d MHz\n",gd->usbmph_clk/1000000);
debug(" USB DR: %4d MHz\n",gd->usbdr_clk/1000000);
printf(" DDR: %4d MHz\n", gd->ddr_clk / 1000000);
#if defined (CONFIG_MPC8360)
printf(" DDR Secondary: %4d MHz\n", gd->ddr_sec_clk / 1000000);
#endif
printf(" SEC: %4d MHz\n", gd->enc_clk / 1000000);
printf(" I2C1: %4d MHz\n", gd->i2c1_clk / 1000000);
printf(" I2C2: %4d MHz\n", gd->i2c2_clk / 1000000);
#if defined(CONFIG_MPC8349)
printf(" TSEC1: %4d MHz\n", gd->tsec1_clk / 1000000);
printf(" TSEC2: %4d MHz\n", gd->tsec2_clk / 1000000);
printf(" USB MPH: %4d MHz\n", gd->usbmph_clk / 1000000);
printf(" USB DR: %4d MHz\n", gd->usbdr_clk / 1000000);
#endif
return 0;
}

View file

@ -2,7 +2,7 @@
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de>
* Copyright 2004 Freescale Semiconductor, Inc.
* Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved.
*
* See file CREDITS for list of people who contributed to this
* project.
@ -104,9 +104,9 @@ version_string:
#ifndef CONFIG_DEFAULT_IMMR
#error CONFIG_DEFAULT_IMMR must be defined
#endif /* CFG_DEFAULT_IMMR */
#ifndef CFG_IMMRBAR
#define CFG_IMMRBAR CONFIG_DEFAULT_IMMR
#endif /* CFG_IMMRBAR */
#ifndef CFG_IMMR
#define CFG_IMMR CONFIG_DEFAULT_IMMR
#endif /* CFG_IMMR */
/*
* After configuration, a system reset exception is executed using the
@ -152,8 +152,8 @@ boot_cold: /* time t 3 */
nop
boot_warm: /* time t 5 */
mfmsr r5 /* save msr contents */
lis r3, CFG_IMMRBAR@h
ori r3, r3, CFG_IMMRBAR@l
lis r3, CFG_IMMR@h
ori r3, r3, CFG_IMMR@l
stw r3, IMMRBAR(r4)
/* Initialise the E300 processor core */
@ -226,7 +226,7 @@ in_flash:
GET_GOT /* initialize GOT access */
/* r3: IMMR */
lis r3, CFG_IMMRBAR@h
lis r3, CFG_IMMR@h
/* run low-level CPU init code (in Flash)*/
bl cpu_init_f
@ -446,7 +446,7 @@ init_e300_core: /* time t 10 */
mtspr SRR1, r3 /* Make SRR1 match MSR */
lis r3, CFG_IMMRBAR@h
lis r3, CFG_IMMR@h
#if defined(CONFIG_WATCHDOG)
/* Initialise the Wathcdog values and reset it (if req) */
/*------------------------------------------------------*/
@ -870,6 +870,18 @@ ppcDcbz:
dcbz r0,r3
blr
.globl ppcDWstore
ppcDWstore:
lfd 1, 0(r4)
stfd 1, 0(r3)
blr
.globl ppcDWload
ppcDWload:
lfd 1, 0(r3)
stfd 1, 0(r4)
blr
/*-------------------------------------------------------------------*/
/*
@ -1189,7 +1201,7 @@ map_flash_by_law1:
/* When booting from ROM (Flash or EPROM), clear the */
/* Address Mask in OR0 so ROM appears everywhere */
/*----------------------------------------------------*/
lis r3, (CFG_IMMRBAR)@h /* r3 <= CFG_IMMRBAR */
lis r3, (CFG_IMMR)@h /* r3 <= CFG_IMMR */
lwz r4, OR0@l(r3)
li r5, 0x7fff /* r5 <= 0x00007FFFF */
and r4, r4, r5
@ -1214,8 +1226,15 @@ map_flash_by_law1:
lis r4, (CFG_FLASH_BASE)@h
ori r4, r4, (CFG_FLASH_BASE)@l
stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CFG_FLASH_BASE */
lis r4, (0x80000016)@h
ori r4, r4, (0x80000016)@l
/* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR1 */
lis r4, (0x80000012)@h
ori r4, r4, (0x80000012)@l
li r5, CFG_FLASH_SIZE
1: srawi. r5, r5, 1 /* r5 = r5 >> 1 */
addi r4, r4, 1
bne 1b
stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= 8MB Flash Size */
blr
@ -1234,17 +1253,23 @@ remap_flash_by_law0:
stw r5, BR0(r3) /* r5 <= (CFG_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */
lwz r4, OR0(r3)
lis r5, 0xFF80 /* 8M */
lis r5, ~((CFG_FLASH_SIZE << 4) - 1)
or r4, r4, r5
stw r4, OR0(r3) /* OR0 <= OR0 | 0xFF800000 */
stw r4, OR0(r3)
lis r4, (CFG_FLASH_BASE)@h
ori r4, r4, (CFG_FLASH_BASE)@l
stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CFG_FLASH_BASE */
lis r4, (0x80000016)@h
ori r4, r4, (0x80000016)@l
stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= 8MB Flash Size */
/* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR0 */
lis r4, (0x80000012)@h
ori r4, r4, (0x80000012)@l
li r5, CFG_FLASH_SIZE
1: srawi. r5, r5, 1 /* r5 = r5 >> 1 */
addi r4, r4, 1
bne 1b
stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= Flash Size */
xor r4, r4, r4
stw r4, LBLAWBAR1(r3)

View file

@ -1,5 +1,8 @@
/*
* linux/arch/ppc/kernel/traps.c
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -15,19 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Change log:
*
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Modified by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras (paulus@cs.anu.edu.au)
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* 20050101: Eran Liberty (liberty@freescale.com)
* Initial file creating (porting from 85XX & 8260)
*/
/*

View file

@ -475,7 +475,11 @@ void pci_440_init (struct pci_controller *hose)
pci_set_region(hose->regions + reg_num++,
CFG_PCI_TARGBASE,
CFG_PCI_MEMBASE,
#ifdef CFG_PCI_MEMSIZE
CFG_PCI_MEMSIZE,
#else
0x10000000,
#endif
PCI_REGION_MEM );
#if defined(CONFIG_PCI_SYS_MEM_BUS) && defined(CONFIG_PCI_SYS_MEM_PHYS) && \

View file

@ -264,10 +264,10 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
bis->bi_phymode[3] = BI_PHYMODE_ZMII;
break;
case 2:
zmiifer = ZMII_FER_SMII << ZMII_FER_V(0);
zmiifer = ZMII_FER_SMII << ZMII_FER_V(1);
zmiifer = ZMII_FER_SMII << ZMII_FER_V(2);
zmiifer = ZMII_FER_SMII << ZMII_FER_V(3);
zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0);
zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1);
zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2);
zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3);
bis->bi_phymode[0] = BI_PHYMODE_ZMII;
bis->bi_phymode[1] = BI_PHYMODE_ZMII;
bis->bi_phymode[2] = BI_PHYMODE_ZMII;
@ -470,8 +470,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#else
if ((devnum == 0) || (devnum == 1)) {
out32 (ZMII_FER, (ZMII_FER_SMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
}
else { /* ((devnum == 2) || (devnum == 3)) */
} else { /* ((devnum == 2) || (devnum == 3)) */
out32 (ZMII_FER, ZMII_FER_MDI << ZMII_FER_V (devnum));
out32 (RGMII_FER, ((RGMII_FER_RGMII << RGMII_FER_V (2)) |
(RGMII_FER_RGMII << RGMII_FER_V (3))));
@ -561,22 +560,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
* otherwise, just check the speeds & feeds
*/
if (hw_p->first_init == 0) {
#if defined(CONFIG_88E1111_CLK_DELAY)
/*
* On some boards (e.g. ALPR) the Marvell 88E1111 PHY needs
* the "RGMII transmit timing control" and "RGMII receive
* timing control" bits set, so that Gbit communication works
* without problems.
* Also set the "Transmitter disable" to 1 to enable the
* transmitter.
* After setting these bits a soft-reset must occur for this
* change to become active.
*/
miiphy_read (dev->name, reg, 0x14, &reg_short);
reg_short |= (1 << 7) | (1 << 1) | (1 << 0);
miiphy_write (dev->name, reg, 0x14, reg_short);
#endif
#if defined(CONFIG_M88E1111_PHY) /* test-only: merge with CONFIG_88E1111_CLK_DELAY !!! */
#if defined(CONFIG_M88E1111_PHY)
miiphy_write (dev->name, reg, 0x14, 0x0ce3);
miiphy_write (dev->name, reg, 0x18, 0x4101);
miiphy_write (dev->name, reg, 0x09, 0x0e00);
@ -808,7 +792,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
hw_p->rx_ready[i] = -1;
#if 0
printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) rx[i].data_ptr);
printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) hw_p->rx[i].data_ptr);
#endif
}

View file

@ -41,6 +41,10 @@
DECLARE_GLOBAL_DATA_PTR;
#endif
#if defined(CONFIG_BOARD_RESET)
void board_reset(void);
#endif
#if defined(CONFIG_440)
#define FREQ_EBC (sys_info.freqEPB)
#else
@ -336,6 +340,10 @@ int checkcpu (void)
puts("SP Rev. B");
break;
case PVR_440SP_RC:
puts("SP Rev. C");
break;
case PVR_440SPe_RA:
puts("SPe Rev. A");
break;
@ -422,23 +430,19 @@ int ppc440spe_revB() {
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#if defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)
/*give reset to BCSR*/
*(unsigned char*)(CFG_BCSR_BASE | 0x06) = 0x09;
#if defined(CONFIG_BOARD_RESET)
board_reset();
#else
#if defined(CFG_4xx_RESET_TYPE)
mtspr(dbcr0, CFG_4xx_RESET_TYPE << 28);
#else
/*
* Initiate system reset in debug control register DBCR
*/
__asm__ __volatile__("lis 3, 0x3000" ::: "r3");
#if defined(CONFIG_440)
__asm__ __volatile__("mtspr 0x134, 3");
#else
__asm__ __volatile__("mtspr 0x3f2, 3");
#endif
mtspr(dbcr0, 0x30000000);
#endif /* defined(CFG_4xx_RESET_TYPE) */
#endif /* defined(CONFIG_BOARD_RESET) */
#endif/* defined(CONFIG_YOSEMITE) || defined(CONFIG_YELLOWSTONE)*/
return 1;
}

View file

@ -320,6 +320,10 @@ cpu_init_f (void)
val |= 0xb8000000; /* generate system reset after 1.34 seconds */
#else
val |= 0xf0000000; /* generate system reset after 2.684 seconds */
#endif
#if defined(CFG_4xx_RESET_TYPE)
val &= ~0x30000000; /* clear WRC bits */
val |= CFG_4xx_RESET_TYPE << 28; /* set board specific WRC type */
#endif
mtspr(tcr, val);

View file

@ -351,6 +351,14 @@ long int initdram(int board_type)
int i;
int tr1_bank1;
#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
/*
* Soft-reset SDRAM controller.
*/
mtsdr(sdr_srst, SDR0_SRST_DMC);
mtsdr(sdr_srst, 0x00000000);
#endif
for (i=0; i<N_MB0CF; i++) {
/*
* Disable memory controller.

View file

@ -204,6 +204,18 @@ _start_440:
mfspr r1,mcsr
mtspr mcsr,r1
#endif
/*----------------------------------------------------------------*/
/* CCR0 init */
/*----------------------------------------------------------------*/
/* Disable store gathering & broadcast, guarantee inst/data
* cache block touch, force load/store alignment
* (see errata 1.12: 440_33)
*/
lis r1,0x0030 /* store gathering & broadcast disable */
ori r1,r1,0x6000 /* cache touch */
mtspr ccr0,r1
/*----------------------------------------------------------------*/
/* Initialize debug */
/*----------------------------------------------------------------*/
@ -225,17 +237,6 @@ _start_440:
mtspr dbsr,r1 /* Clear all valid bits */
skip_debug_init:
/*----------------------------------------------------------------*/
/* CCR0 init */
/*----------------------------------------------------------------*/
/* Disable store gathering & broadcast, guarantee inst/data
* cache block touch, force load/store alignment
* (see errata 1.12: 440_33)
*/
lis r1,0x0030 /* store gathering & broadcast disable */
ori r1,r1,0x6000 /* cache touch */
mtspr ccr0,r1
#if defined (CONFIG_440SPE)
/*----------------------------------------------------------------+
| Initialize Core Configuration Reg1.

View file

@ -39,7 +39,6 @@ The mapping is:
0xff00_0000 0xff80_0000 FLASH (boot flash) 8M
0xff80_0000 0xffff_ffff FLASH (second half flash) 8M
Using Flash
-----------
@ -67,16 +66,13 @@ it into the secondary bank:
erase ff000000 ff080000
cp.b 10000 ff000000 80000
After copying the image into the second bank of flash, be sure to toggle
SW3[4] on board before resetting the board in order to set the
secondary bank as the boot-bank.
Board Switches
----------------------
Most switches on the board should not be changed. The most frequent
user-settable switches on the board are used to configure
the flash banks and determining the PCI frequency.
@ -111,7 +107,6 @@ SW2[1-6]: CPU core frequency
This table shows only a subset of available frequency options; see the CPU
hardware specifications for more information.
SW2[7-8]: Bus Protocol and CPU Reset Option
7
@ -124,7 +119,6 @@ SW2[7-8]: Bus Protocol and CPU Reset Option
SW2=0 TSI108 can cause CPU reset
SW2=1 TSI108 can not cause CPU reset
SW3[1-8] system options
123
@ -167,7 +161,6 @@ SW4[1-3]: System bus frequency
SW4=110 200 only for MPC7448
others reserved
SW4[4-6]: DDR2 SDRAM frequency
Bus Frequency (MHz)
@ -179,7 +172,6 @@ SW4[4-6]: DDR2 SDRAM frequency
SW4=110 200
others reserved
SW4[7-8]: PCI/PCI-X frequency control
7
-

126
doc/README.mpc8360emds Normal file
View file

@ -0,0 +1,126 @@
Freescale MPC8360EMDS Board
-----------------------------------------
1. Board Switches and Jumpers
1.0 There are four Dual-In-Line Packages(DIP) Switches on MPC8360EMDS board
For some reason, the HW designers describe the switch settings
in terms of 0 and 1, and then map that to physical switches where
the label "On" refers to logic 0 and "Off" is logic 1.
Switch bits are numbered 1 through, like, 4 6 8 or 10, but the
bits may contribute to signals that are numbered based at 0,
and some of those signals may be high-bit-number-0 too. Heed
well the names and labels and do not get confused.
"Off" == 1
"On" == 0
SW18 is switch 18 as silk-screened onto the board.
SW4[8] is the bit labled 8 on Switch 4.
SW2[1:6] refers to bits labeled 1 through 6 in order on switch 2.
SW3[7:1] refers to bits labeled 7 through 1 in order on switch 3.
SW3[1:8]= 0000_0001 refers to bits labeled 1 through 6 is set as "On"
and bits labeled 8 is set as "Off".
1.1 For the MPC8360E PB PROTO Board
First, make sure the board default setting is consistent with the
document shipped with your board. Then apply the following setting:
SW3[1-8]= 0000_0100 (HRCW setting value is performed on local bus)
SW4[1-8]= 0011_0000 (Flash boot on local bus)
SW9[1-8]= 0110_0110 (PCI Mode enabled. HRCW is read from FLASH)
SW10[1-8]= 0000_1000 (core PLL setting)
SW11[1-8]= 0000_0100 (SW11 is on the another side of the board)
JP6 1-2
on board Oscillator: 66M
2. Memory Map
2.1. The memory map should look pretty much like this:
0x0000_0000 0x7fff_ffff DDR 2G
0x8000_0000 0x8fff_ffff PCI MEM prefetch 256M
0x9000_0000 0x9fff_ffff PCI MEM non-prefetch 256M
0xc000_0000 0xdfff_ffff Empty 512M
0xe000_0000 0xe01f_ffff Int Mem Reg Space 2M
0xe020_0000 0xe02f_ffff Empty 1M
0xe030_0000 0xe03f_ffff PCI IO 1M
0xe040_0000 0xefff_ffff Empty 252M
0xf000_0000 0xf3ff_ffff Local Bus SDRAM 64M
0xf400_0000 0xf7ff_ffff Empty 64M
0xf800_0000 0xf800_7fff BCSR on CS1 32K
0xf800_8000 0xf800_ffff PIB CS4 32K
0xf801_0000 0xf801_7fff PIB CS5 32K
0xfe00_0000 0xfeff_ffff FLASH on CS0 16M
3. Definitions
3.1 Explanation of NEW definitions in:
include/configs/MPC8360EMDS.h
CONFIG_MPC83XX MPC83xx family for both MPC8349 and MPC8360
CONFIG_MPC8360 MPC8360 specific
CONFIG_MPC8360EMDS MPC8360EMDS board specific
4. Compilation
Assuming you're using BASH shell:
export CROSS_COMPILE=your-cross-compile-prefix
cd u-boot
make distclean
make MPC8360EMDS_config
make
MPC8360 support PCI in host and slave mode.
To make u-boot support PCI host 66M :
1) DIP SW support PCI mode as described in Section 1.1.
2) Make MPC8360EMDS_HOST_66_config
To make u-boot support PCI host 33M :
1) DIP SW setting is similar as Section 1.1, except for SW3[4] is 1
2) Make MPC8360EMDS_HOST_33_config
To make u-boot support PCI slave 66M :
1) DIP SW setting is similar as Section 1.1, except for SW9[3] is 1
2) Make MPC8360EMDS_SLAVE_config
5. Downloading and Flashing Images
5.0 Download over serial line using Kermit:
loadb
[Drop to kermit:
^\c
send <u-boot-bin-image>
c
]
Or via tftp:
tftp 10000 u-boot.bin
5.1 Reflash U-boot Image using U-boot
tftp 20000 u-boot.bin
protect off fef00000 fef3ffff
erase fef00000 fef3ffff
cp.b 20000 fef00000 xxxx
or
cp.b 20000 fef00000 3ffff
You have to supply the correct byte count with 'xxxx' from the TFTP result log.
Maybe 3ffff will work too, that corresponds to the erased sectors.
6. Notes
1) The console baudrate for MPC8360EMDS is 115200bps.

View file

@ -4,14 +4,12 @@
*
* Copyright (C) 2003, 2006 Arabella Software Ltd.
* Yuli Barcohen <yuli@arabellasw.com>
* Modified to work with AMD flashes
* Added support for byte lanes swap
* Added support for 32-bit chips consisting of two 16-bit devices
* (for example, S70GL256M00)
*
* Copyright (C) 2004
* Ed Okerson
* Modified to work with little-endian systems.
*
* Copyright (C) 2006
* Tolunay Orkun <listmember@orkun.us>
*
* See file CREDITS for list of people who contributed to this
* project.
@ -31,17 +29,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* History
* 01/20/2004 - combined variants of original driver.
* 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
* 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
* 01/27/2004 - Little endian support Ed Okerson
*
* Tested Architectures
* Port Width Chip Width # of banks Flash Chip Board
* 32 16 1 28F128J3 seranoa/eagle
* 64 16 1 28F128J3 seranoa/falcon
*
*/
/* The DEBUG define must be before common to enable debugging */
@ -60,21 +47,16 @@
* This file implements a Common Flash Interface (CFI) driver for U-Boot.
* The width of the port and the width of the chips are determined at initialization.
* These widths are used to calculate the address for access CFI data structures.
* It has been tested on an Intel Strataflash implementation and AMD 29F016D.
*
* References
* JEDEC Standard JESD68 - Common Flash Interface (CFI)
* JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
* Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
* Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
* AMD CFI Specification, Release 2.0 December 1, 2001
* AMD/Spansion Application Note: Migration from Single-byte to Three-byte
* Device IDs, Publication Number 25538 Revision A, November 8, 2001
*
* TODO
*
* Use Primary Extended Query table (PRI) and Alternate Algorithm Query
* Table (ALT) to determine if protection is available
*
* Add support for other command sets Use the PRI and ALT to determine command set
* Verify erase and program timeouts.
*/
#if defined(__LITTLE_ENDIAN) && !defined(CFG_FLASH_CFI_SWAP)
@ -124,6 +106,10 @@
#define AMD_ADDR_START ((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
#define AMD_ADDR_ACK ((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA)
#define FLASH_OFFSET_MANUFACTURER_ID 0x00
#define FLASH_OFFSET_DEVICE_ID 0x01
#define FLASH_OFFSET_DEVICE_ID2 0x0E
#define FLASH_OFFSET_DEVICE_ID3 0x0F
#define FLASH_OFFSET_CFI 0x55
#define FLASH_OFFSET_CFI_RESP 0x10
#define FLASH_OFFSET_PRIMARY_VENDOR 0x13
@ -145,9 +131,6 @@
#define FLASH_OFFSET_USER_PROTECTION 0x85
#define FLASH_OFFSET_INTEL_PROTECTION 0x81
#define FLASH_MAN_CFI 0x01000000
#define CFI_CMDSET_NONE 0
#define CFI_CMDSET_INTEL_EXTENDED 1
#define CFI_CMDSET_AMD_STANDARD 2
@ -157,13 +140,11 @@
#define CFI_CMDSET_MITSU_EXTENDED 257
#define CFI_CMDSET_SST 258
#ifdef CFG_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
# undef FLASH_CMD_RESET
# define FLASH_CMD_RESET AMD_CMD_RESET /* use AMD-Reset instead */
#endif
typedef union {
unsigned char c;
unsigned short w;
@ -178,7 +159,7 @@ typedef union {
volatile unsigned long long *llp;
} cfiptr_t;
#define NUM_ERASE_REGIONS 4
#define NUM_ERASE_REGIONS 4 /* max. number of erase regions */
/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
#ifdef CFG_MAX_FLASH_BANKS_DETECT
@ -210,6 +191,7 @@ static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
static void flash_read_jedec_ids (flash_info_t * info);
static int flash_detect_cfi (flash_info_t * info);
static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
@ -317,7 +299,7 @@ ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
}
/*-----------------------------------------------------------------------
* read a long word by picking the least significant byte of each maiximum
* read a long word by picking the least significant byte of each maximum
* port size word. Swap for ppc format.
*/
ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
@ -539,14 +521,42 @@ void flash_print_info (flash_info_t * info)
(info->portwidth << 3), (info->chipwidth << 3));
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
printf (" ");
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
printf ("Intel Standard");
break;
case CFI_CMDSET_INTEL_EXTENDED:
printf ("Intel Extended");
break;
case CFI_CMDSET_AMD_STANDARD:
printf ("AMD Standard");
break;
case CFI_CMDSET_AMD_EXTENDED:
printf ("AMD Extended");
break;
default:
printf ("Unknown (%d)", info->vendor);
break;
}
printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
info->manufacturer_id, info->device_id);
if (info->device_id == 0x7E) {
printf("%04X", info->device_id2);
}
printf ("\n Erase timeout: %ld ms, write timeout: %ld ms\n",
info->erase_blk_tout,
info->write_tout,
info->write_tout);
if (info->buffer_size > 1) {
printf (" Buffer write timeout: %ld ms, buffer size: %d bytes\n",
info->buffer_write_tout,
info->buffer_size);
}
puts (" Sector Start Addresses:");
puts ("\n Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n");
#ifdef CFG_FLASH_EMPTY_INFO
int k;
int size;
@ -570,18 +580,15 @@ void flash_print_info (flash_info_t * info)
}
}
if ((i % 5) == 0)
printf ("\n");
/* print empty and read-only info */
printf (" %08lX%s%s",
printf (" %08lX %c %s ",
info->start[i],
erased ? " E" : " ",
erased ? 'E' : ' ',
info->protect[i] ? "RO" : " ");
#else /* ! CFG_FLASH_EMPTY_INFO */
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX %s ",
info->start[i], info->protect[i] ? " (RO)" : " ");
info->start[i],
info->protect[i] ? "RO" : " ");
#endif
}
putc ('\n');
@ -1090,6 +1097,55 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uc
return retval;
}
/*-----------------------------------------------------------------------
* read jedec ids from device and set corresponding fields in info struct
*
* Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
*
*/
static void flash_read_jedec_ids (flash_info_t * info)
{
info->manufacturer_id = 0;
info->device_id = 0;
info->device_id2 = 0;
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
udelay(1000); /* some flash are slow to respond */
info->manufacturer_id = flash_read_uchar (info,
FLASH_OFFSET_MANUFACTURER_ID);
info->device_id = flash_read_uchar (info,
FLASH_OFFSET_DEVICE_ID);
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
flash_unlock_seq(info, 0);
flash_write_cmd(info, 0, AMD_ADDR_START, FLASH_CMD_READ_ID);
udelay(1000); /* some flash are slow to respond */
info->manufacturer_id = flash_read_uchar (info,
FLASH_OFFSET_MANUFACTURER_ID);
info->device_id = flash_read_uchar (info,
FLASH_OFFSET_DEVICE_ID);
if (info->device_id == 0x7E) {
/* AMD 3-byte (expanded) device ids */
info->device_id2 = flash_read_uchar (info,
FLASH_OFFSET_DEVICE_ID2);
info->device_id2 <<= 8;
info->device_id2 |= flash_read_uchar (info,
FLASH_OFFSET_DEVICE_ID3);
}
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
break;
default:
break;
}
}
/*-----------------------------------------------------------------------
* detect if flash is compatible with the Common Flash Interface (CFI)
* http://www.jedec.org/download/search/jesd68.pdf
@ -1140,15 +1196,31 @@ ulong flash_get_size (ulong base, int banknum)
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
int geometry_reversed = 0;
info->ext_addr = 0;
info->cfi_version = 0;
#ifdef CFG_FLASH_PROTECTION
int ext_addr;
info->legacy_unlock = 0;
#endif
info->start[0] = base;
if (flash_detect_cfi (info)) {
info->vendor = flash_read_ushort (info, 0, FLASH_OFFSET_PRIMARY_VENDOR);
info->vendor = flash_read_ushort (info, 0,
FLASH_OFFSET_PRIMARY_VENDOR);
flash_read_jedec_ids (info);
flash_write_cmd (info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
num_erase_regions = flash_read_uchar (info,
FLASH_OFFSET_NUM_ERASE_REGIONS);
info->ext_addr = flash_read_ushort (info, 0,
FLASH_OFFSET_EXT_QUERY_T_P_ADDR);
if (info->ext_addr) {
info->cfi_version = (ushort) flash_read_uchar (info,
info->ext_addr + 3) << 8;
info->cfi_version |= (ushort) flash_read_uchar (info,
info->ext_addr + 4);
}
#ifdef DEBUG
flash_printqry (info, 0);
#endif
@ -1159,26 +1231,46 @@ ulong flash_get_size (ulong base, int banknum)
info->cmd_reset = FLASH_CMD_RESET;
#ifdef CFG_FLASH_PROTECTION
/* read legacy lock/unlock bit from intel flash */
ext_addr = flash_read_ushort (info, 0,
FLASH_OFFSET_EXT_QUERY_T_P_ADDR);
info->legacy_unlock =
flash_read_uchar (info, ext_addr + 5) & 0x08;
if (info->ext_addr) {
info->legacy_unlock = flash_read_uchar (info,
info->ext_addr + 5) & 0x08;
}
#endif
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
info->cmd_reset = AMD_CMD_RESET;
/* check if flash geometry needs reversal */
if (num_erase_regions <= 1)
break;
/* reverse geometry if top boot part */
if (info->cfi_version < 0x3131) {
/* CFI < 1.1, try to guess from device id */
if ((info->device_id & 0x80) != 0) {
geometry_reversed = 1;
}
break;
}
/* CFI >= 1.1, deduct from top/bottom flag */
/* note: ext_addr is valid since cfi_version > 0 */
if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
geometry_reversed = 1;
}
break;
}
debug ("manufacturer is %d\n", info->vendor);
debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
debug ("device id is 0x%x\n", info->device_id);
debug ("device id2 is 0x%x\n", info->device_id2);
debug ("cfi version is 0x%04x\n", info->cfi_version);
size_ratio = info->portwidth / info->chipwidth;
/* if the chip is x8/x16 reduce the ratio by half */
if ((info->interface == FLASH_CFI_X8X16)
&& (info->chipwidth == FLASH_CFI_BY8)) {
size_ratio >>= 1;
}
num_erase_regions = flash_read_uchar (info, FLASH_OFFSET_NUM_ERASE_REGIONS);
debug ("size_ratio %d port %d bits chip %d bits\n",
size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
@ -1191,6 +1283,11 @@ ulong flash_get_size (ulong base, int banknum)
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
if (geometry_reversed)
tmp = flash_read_long (info, 0,
FLASH_OFFSET_ERASE_REGIONS +
(num_erase_regions - 1 - i) * 4);
else
tmp = flash_read_long (info, 0,
FLASH_OFFSET_ERASE_REGIONS +
i * 4);

View file

@ -28,29 +28,52 @@
#include <asm/fsl_i2c.h> /* HW definitions */
#define I2C_TIMEOUT (CFG_HZ / 4)
#define I2C ((struct fsl_i2c *)(CFG_IMMR + CFG_I2C_OFFSET))
#define I2C_READ_BIT 1
#define I2C_WRITE_BIT 0
/* 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
static volatile struct fsl_i2c *i2c_dev[2] = {
(struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET),
#ifdef CFG_I2C2_OFFSET
(struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET)
#endif
};
void
i2c_init(int speed, int slaveadd)
{
/* stop I2C controller */
writeb(0x0, &I2C->cr);
volatile struct fsl_i2c *dev;
/* set clock */
writeb(0x3f, &I2C->fdr);
dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);
/* set default filter */
writeb(0x10, &I2C->dfsrr);
writeb(0, &dev->cr); /* stop I2C controller */
writeb(0x3F, &dev->fdr); /* set bus speed */
writeb(0x3F, &dev->dfsrr); /* set default filter */
writeb(slaveadd << 1, &dev->adr); /* write slave address */
writeb(0x0, &dev->sr); /* clear status register */
writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */
/* write slave address */
writeb(slaveadd, &I2C->adr);
#ifdef CFG_I2C2_OFFSET
dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET);
/* clear status register */
writeb(0x0, &I2C->sr);
/* start I2C controller */
writeb(I2C_CR_MEN, &I2C->cr);
writeb(0, &dev->cr); /* stop I2C controller */
writeb(0x3F, &dev->fdr); /* set bus speed */
writeb(0x3F, &dev->dfsrr); /* set default filter */
writeb(slaveadd, &dev->adr); /* write slave address */
writeb(0x0, &dev->sr); /* clear status register */
writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */
#endif /* CFG_I2C2_OFFSET */
}
static __inline__ int
@ -58,7 +81,7 @@ i2c_wait4bus(void)
{
ulong timeval = get_timer(0);
while (readb(&I2C->sr) & I2C_SR_MBB) {
while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
if (get_timer(timeval) > I2C_TIMEOUT) {
return -1;
}
@ -74,11 +97,11 @@ i2c_wait(int write)
ulong timeval = get_timer(0);
do {
csr = readb(&I2C->sr);
csr = readb(&i2c_dev[i2c_bus_num]->sr);
if (!(csr & I2C_SR_MIF))
continue;
writeb(0x0, &I2C->sr);
writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
if (csr & I2C_SR_MAL) {
debug("i2c_wait: MAL\n");
@ -90,7 +113,7 @@ i2c_wait(int write)
return -1;
}
if (write == I2C_WRITE && (csr & I2C_SR_RXAK)) {
if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
debug("i2c_wait: No RXACK\n");
return -1;
}
@ -107,11 +130,11 @@ i2c_write_addr (u8 dev, u8 dir, int rsta)
{
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
| (rsta ? I2C_CR_RSTA : 0),
&I2C->cr);
&i2c_dev[i2c_bus_num]->cr);
writeb((dev << 1) | dir, &I2C->dr);
writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
if (i2c_wait(I2C_WRITE) < 0)
if (i2c_wait(I2C_WRITE_BIT) < 0)
return 0;
return 1;
@ -123,12 +146,12 @@ __i2c_write(u8 *data, int length)
int i;
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
&I2C->cr);
&i2c_dev[i2c_bus_num]->cr);
for (i = 0; i < length; i++) {
writeb(data[i], &I2C->dr);
writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
if (i2c_wait(I2C_WRITE) < 0)
if (i2c_wait(I2C_WRITE_BIT) < 0)
break;
}
@ -141,25 +164,25 @@ __i2c_read(u8 *data, int length)
int i;
writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
&I2C->cr);
&i2c_dev[i2c_bus_num]->cr);
/* dummy read */
readb(&I2C->dr);
readb(&i2c_dev[i2c_bus_num]->dr);
for (i = 0; i < length; i++) {
if (i2c_wait(I2C_READ) < 0)
if (i2c_wait(I2C_READ_BIT) < 0)
break;
/* Generate ack on last next to last byte */
if (i == length - 2)
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
&I2C->cr);
&i2c_dev[i2c_bus_num]->cr);
/* Generate stop on last byte */
if (i == length - 1)
writeb(I2C_CR_MEN | I2C_CR_TXAK, &I2C->cr);
writeb(I2C_CR_MEN | I2C_CR_TXAK, &i2c_dev[i2c_bus_num]->cr);
data[i] = readb(&I2C->dr);
data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
}
return i;
@ -172,13 +195,13 @@ i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
u8 *a = (u8*)&addr;
if (i2c_wait4bus() >= 0
&& i2c_write_addr(dev, I2C_WRITE, 0) != 0
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
&& __i2c_write(&a[4 - alen], alen) == alen
&& i2c_write_addr(dev, I2C_READ, 1) != 0) {
&& i2c_write_addr(dev, I2C_READ_BIT, 1) != 0) {
i = __i2c_read(data, length);
}
writeb(I2C_CR_MEN, &I2C->cr);
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
if (i == length)
return 0;
@ -193,12 +216,12 @@ i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
u8 *a = (u8*)&addr;
if (i2c_wait4bus() >= 0
&& i2c_write_addr(dev, I2C_WRITE, 0) != 0
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
&& __i2c_write(&a[4 - alen], alen) == alen) {
i = __i2c_write(data, length);
}
writeb(I2C_CR_MEN, &I2C->cr);
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
if (i == length)
return 0;
@ -237,5 +260,34 @@ i2c_reg_write(uchar i2c_addr, uchar reg, uchar val)
i2c_write(i2c_addr, reg, 1, &val, 1);
}
int i2c_set_bus_num(unsigned int bus)
{
#ifdef CFG_I2C2_OFFSET
if (bus > 1) {
#else
if (bus > 0) {
#endif
return -1;
}
i2c_bus_num = bus;
return 0;
}
int i2c_set_bus_speed(unsigned int speed)
{
return -1;
}
unsigned int i2c_get_bus_num(void)
{
return i2c_bus_num;
}
unsigned int i2c_get_bus_speed(void)
{
return 0;
}
#endif /* CONFIG_HARD_I2C */
#endif /* CONFIG_FSL_I2C */

View file

@ -838,9 +838,9 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
unsigned long timeo;
if (state == FL_ERASING)
timeo = CFG_HZ * 400;
timeo = (CFG_HZ * 400) / 1000;
else
timeo = CFG_HZ * 20;
timeo = (CFG_HZ * 20) / 1000;
if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
@ -852,7 +852,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
while (1) {
if (get_timer(0) > timeo) {
printf("Timeout!");
return 0;
return 0x01;
}
if (this->dev_ready) {
@ -1713,6 +1713,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
goto out;
}
*retlen = written;
bufstart = (u_char*) &buf[written];
ofs = autoplace ? mtd->oobavail : mtd->oobsize;
if (eccbuf)
@ -2407,7 +2408,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
if (!nand_flash_ids[i].name) {
#ifndef CFG_NAND_QUIET_TEST
printk (KERN_WARNING "No NAND device found!!!\n");
#endif
this->select_chip(mtd, -1);
return 1;
}

43
drivers/qe/Makefile Normal file
View file

@ -0,0 +1,43 @@
#
# Copyright (C) 2006 Freescale Semiconductor, Inc.
#
# 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)qe.a
COBJS := qe.o uccf.o uec.o uec_phy.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
all: $(LIB)
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

254
drivers/qe/qe.c Normal file
View file

@ -0,0 +1,254 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on source code of Shlomi Gridish
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "common.h"
#include "asm/errno.h"
#include "asm/io.h"
#include "asm/immap_qe.h"
#include "qe.h"
#if defined(CONFIG_QE)
qe_map_t *qe_immr = NULL;
static qe_snum_t snums[QE_NUM_OF_SNUM];
void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
{
u32 cecr;
if (cmd == QE_RESET) {
out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG));
} else {
out_be32(&qe_immr->cp.cecdr, cmd_data);
out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd));
}
/* Wait for the QE_CR_FLG to clear */
do {
cecr = in_be32(&qe_immr->cp.cecr);
} while (cecr & QE_CR_FLG);
return;
}
uint qe_muram_alloc(uint size, uint align)
{
DECLARE_GLOBAL_DATA_PTR;
uint retloc;
uint align_mask, off;
uint savebase;
align_mask = align - 1;
savebase = gd->mp_alloc_base;
if ((off = (gd->mp_alloc_base & align_mask)) != 0)
gd->mp_alloc_base += (align - off);
if ((off = size & align_mask) != 0)
size += (align - off);
if ((gd->mp_alloc_base + size) >= gd->mp_alloc_top) {
gd->mp_alloc_base = savebase;
printf("%s: ran out of ram.\n", __FUNCTION__);
}
retloc = gd->mp_alloc_base;
gd->mp_alloc_base += size;
memset((void *)&qe_immr->muram[retloc], 0, size);
__asm__ __volatile__("sync");
return retloc;
}
void *qe_muram_addr(uint offset)
{
return (void *)&qe_immr->muram[offset];
}
static void qe_sdma_init(void)
{
volatile sdma_t *p;
uint sdma_buffer_base;
p = (volatile sdma_t *)&qe_immr->sdma;
/* All of DMA transaction in bus 1 */
out_be32(&p->sdaqr, 0);
out_be32(&p->sdaqmr, 0);
/* Allocate 2KB temporary buffer for sdma */
sdma_buffer_base = qe_muram_alloc(2048, 64);
out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
/* Clear sdma status */
out_be32(&p->sdsr, 0x03000000);
/* Enable global mode on bus 1, and 2KB buffer size */
out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
}
static u8 thread_snum[QE_NUM_OF_SNUM] = {
0x04, 0x05, 0x0c, 0x0d,
0x14, 0x15, 0x1c, 0x1d,
0x24, 0x25, 0x2c, 0x2d,
0x34, 0x35, 0x88, 0x89,
0x98, 0x99, 0xa8, 0xa9,
0xb8, 0xb9, 0xc8, 0xc9,
0xd8, 0xd9, 0xe8, 0xe9
};
static void qe_snums_init(void)
{
int i;
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
snums[i].state = QE_SNUM_STATE_FREE;
snums[i].num = thread_snum[i];
}
}
int qe_get_snum(void)
{
int snum = -EBUSY;
int i;
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
if (snums[i].state == QE_SNUM_STATE_FREE) {
snums[i].state = QE_SNUM_STATE_USED;
snum = snums[i].num;
break;
}
}
return snum;
}
void qe_put_snum(u8 snum)
{
int i;
for (i = 0; i < QE_NUM_OF_SNUM; i++) {
if (snums[i].num == snum) {
snums[i].state = QE_SNUM_STATE_FREE;
break;
}
}
}
void qe_init(uint qe_base)
{
DECLARE_GLOBAL_DATA_PTR;
/* Init the QE IMMR base */
qe_immr = (qe_map_t *)qe_base;
gd->mp_alloc_base = QE_DATAONLY_BASE;
gd->mp_alloc_top = gd->mp_alloc_base + QE_DATAONLY_SIZE;
qe_sdma_init();
qe_snums_init();
}
void qe_reset(void)
{
qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
(u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
}
void qe_assign_page(uint snum, uint para_ram_base)
{
u32 cecr;
out_be32(&qe_immr->cp.cecdr, para_ram_base);
out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
| QE_CR_FLG | QE_ASSIGN_PAGE);
/* Wait for the QE_CR_FLG to clear */
do {
cecr = in_be32(&qe_immr->cp.cecr);
} while (cecr & QE_CR_FLG );
return;
}
/*
* brg: 0~15 as BRG1~BRG16
rate: baud rate
* BRG input clock comes from the BRGCLK (internal clock generated from
the QE clock, it is one-half of the QE clock), If need the clock source
from CLKn pin, we have te change the function.
*/
#define BRG_CLK (gd->brg_clk)
int qe_set_brg(uint brg, uint rate)
{
DECLARE_GLOBAL_DATA_PTR;
volatile uint *bp;
u32 divisor;
int div16 = 0;
if (brg >= QE_NUM_OF_BRGS)
return -EINVAL;
bp = (uint *)&qe_immr->brg.brgc1;
bp += brg;
divisor = (BRG_CLK / rate);
if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
div16 = 1;
divisor /= 16;
}
*bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
__asm__ __volatile__("sync");
if (div16) {
*bp |= QE_BRGC_DIV16;
__asm__ __volatile__("sync");
}
return 0;
}
/* Set ethernet MII clock master
*/
int qe_set_mii_clk_src(int ucc_num)
{
u32 cmxgcr;
/* check if the UCC number is in range. */
if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
printf("%s: ucc num not in ranges\n", __FUNCTION__);
return -EINVAL;
}
cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
return 0;
}
#endif /* CONFIG_QE */

237
drivers/qe/qe.h Normal file
View file

@ -0,0 +1,237 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on source code of Shlomi Gridish
*
* 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 __QE_H__
#define __QE_H__
#include "common.h"
#define QE_NUM_OF_SNUM 28
#define QE_NUM_OF_BRGS 16
#define UCC_MAX_NUM 8
#define QE_DATAONLY_BASE (uint)(128)
#define QE_DATAONLY_SIZE ((uint)(0xc000) - QE_DATAONLY_BASE)
/* QE threads SNUM
*/
typedef enum qe_snum_state {
QE_SNUM_STATE_USED, /* used */
QE_SNUM_STATE_FREE /* free */
} qe_snum_state_e;
typedef struct qe_snum {
u8 num; /* snum */
qe_snum_state_e state; /* state */
} qe_snum_t;
/* QE RISC allocation
*/
typedef enum qe_risc_allocation {
QE_RISC_ALLOCATION_RISC1 = 1, /* RISC 1 */
QE_RISC_ALLOCATION_RISC2 = 2, /* RISC 2 */
QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3 /* RISC 1 or RISC 2 */
} qe_risc_allocation_e;
/* QE CECR commands for UCC fast.
*/
#define QE_CR_FLG 0x00010000
#define QE_RESET 0x80000000
#define QE_INIT_TX_RX 0x00000000
#define QE_INIT_RX 0x00000001
#define QE_INIT_TX 0x00000002
#define QE_ENTER_HUNT_MODE 0x00000003
#define QE_STOP_TX 0x00000004
#define QE_GRACEFUL_STOP_TX 0x00000005
#define QE_RESTART_TX 0x00000006
#define QE_SWITCH_COMMAND 0x00000007
#define QE_SET_GROUP_ADDRESS 0x00000008
#define QE_INSERT_CELL 0x00000009
#define QE_ATM_TRANSMIT 0x0000000a
#define QE_CELL_POOL_GET 0x0000000b
#define QE_CELL_POOL_PUT 0x0000000c
#define QE_IMA_HOST_CMD 0x0000000d
#define QE_ATM_MULTI_THREAD_INIT 0x00000011
#define QE_ASSIGN_PAGE 0x00000012
#define QE_START_FLOW_CONTROL 0x00000014
#define QE_STOP_FLOW_CONTROL 0x00000015
#define QE_ASSIGN_PAGE_TO_DEVICE 0x00000016
#define QE_GRACEFUL_STOP_RX 0x0000001a
#define QE_RESTART_RX 0x0000001b
/* QE CECR Sub Block Code - sub block code of QE command.
*/
#define QE_CR_SUBBLOCK_INVALID 0x00000000
#define QE_CR_SUBBLOCK_USB 0x03200000
#define QE_CR_SUBBLOCK_UCCFAST1 0x02000000
#define QE_CR_SUBBLOCK_UCCFAST2 0x02200000
#define QE_CR_SUBBLOCK_UCCFAST3 0x02400000
#define QE_CR_SUBBLOCK_UCCFAST4 0x02600000
#define QE_CR_SUBBLOCK_UCCFAST5 0x02800000
#define QE_CR_SUBBLOCK_UCCFAST6 0x02a00000
#define QE_CR_SUBBLOCK_UCCFAST7 0x02c00000
#define QE_CR_SUBBLOCK_UCCFAST8 0x02e00000
#define QE_CR_SUBBLOCK_UCCSLOW1 0x00000000
#define QE_CR_SUBBLOCK_UCCSLOW2 0x00200000
#define QE_CR_SUBBLOCK_UCCSLOW3 0x00400000
#define QE_CR_SUBBLOCK_UCCSLOW4 0x00600000
#define QE_CR_SUBBLOCK_UCCSLOW5 0x00800000
#define QE_CR_SUBBLOCK_UCCSLOW6 0x00a00000
#define QE_CR_SUBBLOCK_UCCSLOW7 0x00c00000
#define QE_CR_SUBBLOCK_UCCSLOW8 0x00e00000
#define QE_CR_SUBBLOCK_MCC1 0x03800000
#define QE_CR_SUBBLOCK_MCC2 0x03a00000
#define QE_CR_SUBBLOCK_MCC3 0x03000000
#define QE_CR_SUBBLOCK_IDMA1 0x02800000
#define QE_CR_SUBBLOCK_IDMA2 0x02a00000
#define QE_CR_SUBBLOCK_IDMA3 0x02c00000
#define QE_CR_SUBBLOCK_IDMA4 0x02e00000
#define QE_CR_SUBBLOCK_HPAC 0x01e00000
#define QE_CR_SUBBLOCK_SPI1 0x01400000
#define QE_CR_SUBBLOCK_SPI2 0x01600000
#define QE_CR_SUBBLOCK_RAND 0x01c00000
#define QE_CR_SUBBLOCK_TIMER 0x01e00000
#define QE_CR_SUBBLOCK_GENERAL 0x03c00000
/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command.
*/
#define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */
#define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00
#define QE_CR_PROTOCOL_ATM_POS 0x0A
#define QE_CR_PROTOCOL_ETHERNET 0x0C
#define QE_CR_PROTOCOL_L2_SWITCH 0x0D
#define QE_CR_PROTOCOL_SHIFT 6
/* QE ASSIGN PAGE command
*/
#define QE_CR_ASSIGN_PAGE_SNUM_SHIFT 17
/* Communication Direction.
*/
typedef enum comm_dir {
COMM_DIR_NONE = 0,
COMM_DIR_RX = 1,
COMM_DIR_TX = 2,
COMM_DIR_RX_AND_TX = 3
} comm_dir_e;
/* Clocks and BRG's
*/
typedef enum qe_clock {
QE_CLK_NONE = 0,
QE_BRG1, /* Baud Rate Generator 1 */
QE_BRG2, /* Baud Rate Generator 2 */
QE_BRG3, /* Baud Rate Generator 3 */
QE_BRG4, /* Baud Rate Generator 4 */
QE_BRG5, /* Baud Rate Generator 5 */
QE_BRG6, /* Baud Rate Generator 6 */
QE_BRG7, /* Baud Rate Generator 7 */
QE_BRG8, /* Baud Rate Generator 8 */
QE_BRG9, /* Baud Rate Generator 9 */
QE_BRG10, /* Baud Rate Generator 10 */
QE_BRG11, /* Baud Rate Generator 11 */
QE_BRG12, /* Baud Rate Generator 12 */
QE_BRG13, /* Baud Rate Generator 13 */
QE_BRG14, /* Baud Rate Generator 14 */
QE_BRG15, /* Baud Rate Generator 15 */
QE_BRG16, /* Baud Rate Generator 16 */
QE_CLK1, /* Clock 1 */
QE_CLK2, /* Clock 2 */
QE_CLK3, /* Clock 3 */
QE_CLK4, /* Clock 4 */
QE_CLK5, /* Clock 5 */
QE_CLK6, /* Clock 6 */
QE_CLK7, /* Clock 7 */
QE_CLK8, /* Clock 8 */
QE_CLK9, /* Clock 9 */
QE_CLK10, /* Clock 10 */
QE_CLK11, /* Clock 11 */
QE_CLK12, /* Clock 12 */
QE_CLK13, /* Clock 13 */
QE_CLK14, /* Clock 14 */
QE_CLK15, /* Clock 15 */
QE_CLK16, /* Clock 16 */
QE_CLK17, /* Clock 17 */
QE_CLK18, /* Clock 18 */
QE_CLK19, /* Clock 19 */
QE_CLK20, /* Clock 20 */
QE_CLK21, /* Clock 21 */
QE_CLK22, /* Clock 22 */
QE_CLK23, /* Clock 23 */
QE_CLK24, /* Clock 24 */
QE_CLK_DUMMY
} qe_clock_e;
/* QE CMXGCR register
*/
#define QE_CMXGCR_MII_ENET_MNG_MASK 0x00007000
#define QE_CMXGCR_MII_ENET_MNG_SHIFT 12
/* QE CMXUCR registers
*/
#define QE_CMXUCR_TX_CLK_SRC_MASK 0x0000000F
/* QE BRG configuration register
*/
#define QE_BRGC_ENABLE 0x00010000
#define QE_BRGC_DIVISOR_SHIFT 1
#define QE_BRGC_DIVISOR_MAX 0xFFF
#define QE_BRGC_DIV16 1
/* QE SDMA registers
*/
#define QE_SDSR_BER1 0x02000000
#define QE_SDSR_BER2 0x01000000
#define QE_SDMR_GLB_1_MSK 0x80000000
#define QE_SDMR_ADR_SEL 0x20000000
#define QE_SDMR_BER1_MSK 0x02000000
#define QE_SDMR_BER2_MSK 0x01000000
#define QE_SDMR_EB1_MSK 0x00800000
#define QE_SDMR_ER1_MSK 0x00080000
#define QE_SDMR_ER2_MSK 0x00040000
#define QE_SDMR_CEN_MASK 0x0000E000
#define QE_SDMR_SBER_1 0x00000200
#define QE_SDMR_SBER_2 0x00000200
#define QE_SDMR_EB1_PR_MASK 0x000000C0
#define QE_SDMR_ER1_PR 0x00000008
#define QE_SDMR_CEN_SHIFT 13
#define QE_SDMR_EB1_PR_SHIFT 6
#define QE_SDTM_MSNUM_SHIFT 24
#define QE_SDEBCR_BA_MASK 0x01FFFFFF
void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign);
void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data);
uint qe_muram_alloc(uint size, uint align);
void *qe_muram_addr(uint offset);
int qe_get_snum(void);
void qe_put_snum(u8 snum);
void qe_init(uint qe_base);
void qe_reset(void);
void qe_assign_page(uint snum, uint para_ram_base);
int qe_set_brg(uint brg, uint rate);
int qe_set_mii_clk_src(int ucc_num);
#endif /* __QE_H__ */

404
drivers/qe/uccf.c Normal file
View file

@ -0,0 +1,404 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on source code of Shlomi Gridish
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "common.h"
#include "malloc.h"
#include "asm/errno.h"
#include "asm/io.h"
#include "asm/immap_qe.h"
#include "qe.h"
#include "uccf.h"
#if defined(CONFIG_QE)
void ucc_fast_transmit_on_demand(ucc_fast_private_t *uccf)
{
out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
}
u32 ucc_fast_get_qe_cr_subblock(int ucc_num)
{
switch (ucc_num) {
case 0: return QE_CR_SUBBLOCK_UCCFAST1;
case 1: return QE_CR_SUBBLOCK_UCCFAST2;
case 2: return QE_CR_SUBBLOCK_UCCFAST3;
case 3: return QE_CR_SUBBLOCK_UCCFAST4;
case 4: return QE_CR_SUBBLOCK_UCCFAST5;
case 5: return QE_CR_SUBBLOCK_UCCFAST6;
case 6: return QE_CR_SUBBLOCK_UCCFAST7;
case 7: return QE_CR_SUBBLOCK_UCCFAST8;
default: return QE_CR_SUBBLOCK_INVALID;
}
}
static void ucc_get_cmxucr_reg(int ucc_num, volatile u32 **p_cmxucr,
u8 *reg_num, u8 *shift)
{
switch (ucc_num) {
case 0: /* UCC1 */
*p_cmxucr = &(qe_immr->qmx.cmxucr1);
*reg_num = 1;
*shift = 16;
break;
case 2: /* UCC3 */
*p_cmxucr = &(qe_immr->qmx.cmxucr1);
*reg_num = 1;
*shift = 0;
break;
case 4: /* UCC5 */
*p_cmxucr = &(qe_immr->qmx.cmxucr2);
*reg_num = 2;
*shift = 16;
break;
case 6: /* UCC7 */
*p_cmxucr = &(qe_immr->qmx.cmxucr2);
*reg_num = 2;
*shift = 0;
break;
case 1: /* UCC2 */
*p_cmxucr = &(qe_immr->qmx.cmxucr3);
*reg_num = 3;
*shift = 16;
break;
case 3: /* UCC4 */
*p_cmxucr = &(qe_immr->qmx.cmxucr3);
*reg_num = 3;
*shift = 0;
break;
case 5: /* UCC6 */
*p_cmxucr = &(qe_immr->qmx.cmxucr4);
*reg_num = 4;
*shift = 16;
break;
case 7: /* UCC8 */
*p_cmxucr = &(qe_immr->qmx.cmxucr4);
*reg_num = 4;
*shift = 0;
break;
default:
break;
}
}
static int ucc_set_clk_src(int ucc_num, qe_clock_e clock, comm_dir_e mode)
{
volatile u32 *p_cmxucr = NULL;
u8 reg_num = 0;
u8 shift = 0;
u32 clockBits;
u32 clockMask;
int source = -1;
/* check if the UCC number is in range. */
if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0))
return -EINVAL;
if (! ((mode == COMM_DIR_RX) || (mode == COMM_DIR_TX))) {
printf("%s: bad comm mode type passed\n", __FUNCTION__);
return -EINVAL;
}
ucc_get_cmxucr_reg(ucc_num, &p_cmxucr, &reg_num, &shift);
switch (reg_num) {
case 1:
switch (clock) {
case QE_BRG1: source = 1; break;
case QE_BRG2: source = 2; break;
case QE_BRG7: source = 3; break;
case QE_BRG8: source = 4; break;
case QE_CLK9: source = 5; break;
case QE_CLK10: source = 6; break;
case QE_CLK11: source = 7; break;
case QE_CLK12: source = 8; break;
case QE_CLK15: source = 9; break;
case QE_CLK16: source = 10; break;
default: source = -1; break;
}
break;
case 2:
switch (clock) {
case QE_BRG5: source = 1; break;
case QE_BRG6: source = 2; break;
case QE_BRG7: source = 3; break;
case QE_BRG8: source = 4; break;
case QE_CLK13: source = 5; break;
case QE_CLK14: source = 6; break;
case QE_CLK19: source = 7; break;
case QE_CLK20: source = 8; break;
case QE_CLK15: source = 9; break;
case QE_CLK16: source = 10; break;
default: source = -1; break;
}
break;
case 3:
switch (clock) {
case QE_BRG9: source = 1; break;
case QE_BRG10: source = 2; break;
case QE_BRG15: source = 3; break;
case QE_BRG16: source = 4; break;
case QE_CLK3: source = 5; break;
case QE_CLK4: source = 6; break;
case QE_CLK17: source = 7; break;
case QE_CLK18: source = 8; break;
case QE_CLK7: source = 9; break;
case QE_CLK8: source = 10; break;
case QE_CLK16: source = 11; break;
default: source = -1; break;
}
break;
case 4:
switch (clock) {
case QE_BRG13: source = 1; break;
case QE_BRG14: source = 2; break;
case QE_BRG15: source = 3; break;
case QE_BRG16: source = 4; break;
case QE_CLK5: source = 5; break;
case QE_CLK6: source = 6; break;
case QE_CLK21: source = 7; break;
case QE_CLK22: source = 8; break;
case QE_CLK7: source = 9; break;
case QE_CLK8: source = 10; break;
case QE_CLK16: source = 11; break;
default: source = -1; break;
}
break;
default:
source = -1;
break;
}
if (source == -1) {
printf("%s: Bad combination of clock and UCC\n", __FUNCTION__);
return -ENOENT;
}
clockBits = (u32) source;
clockMask = QE_CMXUCR_TX_CLK_SRC_MASK;
if (mode == COMM_DIR_RX) {
clockBits <<= 4; /* Rx field is 4 bits to left of Tx field */
clockMask <<= 4; /* Rx field is 4 bits to left of Tx field */
}
clockBits <<= shift;
clockMask <<= shift;
out_be32(p_cmxucr, (in_be32(p_cmxucr) & ~clockMask) | clockBits);
return 0;
}
static uint ucc_get_reg_baseaddr(int ucc_num)
{
uint base = 0;
/* check if the UCC number is in range */
if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
printf("%s: the UCC num not in ranges\n", __FUNCTION__);
return 0;
}
switch (ucc_num) {
case 0: base = 0x00002000; break;
case 1: base = 0x00003000; break;
case 2: base = 0x00002200; break;
case 3: base = 0x00003200; break;
case 4: base = 0x00002400; break;
case 5: base = 0x00003400; break;
case 6: base = 0x00002600; break;
case 7: base = 0x00003600; break;
default: break;
}
base = (uint)qe_immr + base;
return base;
}
void ucc_fast_enable(ucc_fast_private_t *uccf, comm_dir_e mode)
{
ucc_fast_t *uf_regs;
u32 gumr;
uf_regs = uccf->uf_regs;
/* Enable reception and/or transmission on this UCC. */
gumr = in_be32(&uf_regs->gumr);
if (mode & COMM_DIR_TX) {
gumr |= UCC_FAST_GUMR_ENT;
uccf->enabled_tx = 1;
}
if (mode & COMM_DIR_RX) {
gumr |= UCC_FAST_GUMR_ENR;
uccf->enabled_rx = 1;
}
out_be32(&uf_regs->gumr, gumr);
}
void ucc_fast_disable(ucc_fast_private_t *uccf, comm_dir_e mode)
{
ucc_fast_t *uf_regs;
u32 gumr;
uf_regs = uccf->uf_regs;
/* Disable reception and/or transmission on this UCC. */
gumr = in_be32(&uf_regs->gumr);
if (mode & COMM_DIR_TX) {
gumr &= ~UCC_FAST_GUMR_ENT;
uccf->enabled_tx = 0;
}
if (mode & COMM_DIR_RX) {
gumr &= ~UCC_FAST_GUMR_ENR;
uccf->enabled_rx = 0;
}
out_be32(&uf_regs->gumr, gumr);
}
int ucc_fast_init(ucc_fast_info_t *uf_info, ucc_fast_private_t **uccf_ret)
{
ucc_fast_private_t *uccf;
ucc_fast_t *uf_regs;
if (!uf_info)
return -EINVAL;
if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
printf("%s: Illagal UCC number!\n", __FUNCTION__);
return -EINVAL;
}
uccf = (ucc_fast_private_t *)malloc(sizeof(ucc_fast_private_t));
if (!uccf) {
printf("%s: No memory for UCC fast data structure!\n",
__FUNCTION__);
return -ENOMEM;
}
memset(uccf, 0, sizeof(ucc_fast_private_t));
/* Save fast UCC structure */
uccf->uf_info = uf_info;
uccf->uf_regs = (ucc_fast_t *)ucc_get_reg_baseaddr(uf_info->ucc_num);
if (uccf->uf_regs == NULL) {
printf("%s: No memory map for UCC fast controller!\n",
__FUNCTION__);
return -ENOMEM;
}
uccf->enabled_tx = 0;
uccf->enabled_rx = 0;
uf_regs = uccf->uf_regs;
uccf->p_ucce = (u32 *) &(uf_regs->ucce);
uccf->p_uccm = (u32 *) &(uf_regs->uccm);
/* Init GUEMR register, UCC both Rx and Tx is Fast protocol */
out_8(&uf_regs->guemr, UCC_GUEMR_SET_RESERVED3 | UCC_GUEMR_MODE_FAST_RX
| UCC_GUEMR_MODE_FAST_TX);
/* Set GUMR, disable UCC both Rx and Tx, Ethernet protocol */
out_be32(&uf_regs->gumr, UCC_FAST_GUMR_ETH);
/* Set the Giga ethernet VFIFO stuff */
if (uf_info->eth_type == GIGA_ETH) {
/* Allocate memory for Tx Virtual Fifo */
uccf->ucc_fast_tx_virtual_fifo_base_offset =
qe_muram_alloc(UCC_GETH_UTFS_GIGA_INIT,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
/* Allocate memory for Rx Virtual Fifo */
uccf->ucc_fast_rx_virtual_fifo_base_offset =
qe_muram_alloc(UCC_GETH_URFS_GIGA_INIT +
UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
/* utfb, urfb are offsets from MURAM base */
out_be32(&uf_regs->utfb,
uccf->ucc_fast_tx_virtual_fifo_base_offset);
out_be32(&uf_regs->urfb,
uccf->ucc_fast_rx_virtual_fifo_base_offset);
/* Set Virtual Fifo registers */
out_be16(&uf_regs->urfs, UCC_GETH_URFS_GIGA_INIT);
out_be16(&uf_regs->urfet, UCC_GETH_URFET_GIGA_INIT);
out_be16(&uf_regs->urfset, UCC_GETH_URFSET_GIGA_INIT);
out_be16(&uf_regs->utfs, UCC_GETH_UTFS_GIGA_INIT);
out_be16(&uf_regs->utfet, UCC_GETH_UTFET_GIGA_INIT);
out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_GIGA_INIT);
}
/* Set the Fast ethernet VFIFO stuff */
if (uf_info->eth_type == FAST_ETH) {
/* Allocate memory for Tx Virtual Fifo */
uccf->ucc_fast_tx_virtual_fifo_base_offset =
qe_muram_alloc(UCC_GETH_UTFS_INIT,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
/* Allocate memory for Rx Virtual Fifo */
uccf->ucc_fast_rx_virtual_fifo_base_offset =
qe_muram_alloc(UCC_GETH_URFS_INIT +
UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD,
UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
/* utfb, urfb are offsets from MURAM base */
out_be32(&uf_regs->utfb,
uccf->ucc_fast_tx_virtual_fifo_base_offset);
out_be32(&uf_regs->urfb,
uccf->ucc_fast_rx_virtual_fifo_base_offset);
/* Set Virtual Fifo registers */
out_be16(&uf_regs->urfs, UCC_GETH_URFS_INIT);
out_be16(&uf_regs->urfet, UCC_GETH_URFET_INIT);
out_be16(&uf_regs->urfset, UCC_GETH_URFSET_INIT);
out_be16(&uf_regs->utfs, UCC_GETH_UTFS_INIT);
out_be16(&uf_regs->utfet, UCC_GETH_UTFET_INIT);
out_be16(&uf_regs->utftt, UCC_GETH_UTFTT_INIT);
}
/* Rx clock routing */
if (uf_info->rx_clock != QE_CLK_NONE) {
if (ucc_set_clk_src(uf_info->ucc_num,
uf_info->rx_clock, COMM_DIR_RX)) {
printf("%s: Illegal value for parameter 'RxClock'.\n",
__FUNCTION__);
return -EINVAL;
}
}
/* Tx clock routing */
if (uf_info->tx_clock != QE_CLK_NONE) {
if (ucc_set_clk_src(uf_info->ucc_num,
uf_info->tx_clock, COMM_DIR_TX)) {
printf("%s: Illegal value for parameter 'TxClock'.\n",
__FUNCTION__);
return -EINVAL;
}
}
/* Clear interrupt mask register to disable all of interrupts */
out_be32(&uf_regs->uccm, 0x0);
/* Writing '1' to clear all of envents */
out_be32(&uf_regs->ucce, 0xffffffff);
*uccf_ret = uccf;
return 0;
}
#endif /* CONFIG_QE */

130
drivers/qe/uccf.h Normal file
View file

@ -0,0 +1,130 @@
/*
* Copyright (C) 2006 Freescale Semiconductor, Inc.
*
* Dave Liu <daveliu@freescale.com>
* based on source code of Shlomi Gridish
*
* 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 __UCCF_H__
#define __UCCF_H__
#include "common.h"
#include "qe.h"
/* Fast or Giga ethernet
*/
typedef enum enet_type {
FAST_ETH,
GIGA_ETH,
} enet_type_e;
/* General UCC Extended Mode Register
*/
#define UCC_GUEMR_MODE_MASK_RX 0x02
#define UCC_GUEMR_MODE_MASK_TX 0x01
#define UCC_GUEMR_MODE_FAST_RX 0x02
#define UCC_GUEMR_MODE_FAST_TX 0x01
#define UCC_GUEMR_MODE_SLOW_RX 0x00
#define UCC_GUEMR_MODE_SLOW_TX 0x00
#define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 must be set 1 */
/* General UCC FAST Mode Register
*/
#define UCC_FAST_GUMR_TCI 0x20000000
#define UCC_FAST_GUMR_TRX 0x10000000
#define UCC_FAST_GUMR_TTX 0x08000000
#define UCC_FAST_GUMR_CDP 0x04000000
#define UCC_FAST_GUMR_CTSP 0x02000000
#define UCC_FAST_GUMR_CDS 0x01000000
#define UCC_FAST_GUMR_CTSS 0x00800000
#define UCC_FAST_GUMR_TXSY 0x00020000
#define UCC_FAST_GUMR_RSYN 0x00010000
#define UCC_FAST_GUMR_RTSM 0x00002000
#define UCC_FAST_GUMR_REVD 0x00000400
#define UCC_FAST_GUMR_ENR 0x00000020
#define UCC_FAST_GUMR_ENT 0x00000010
/* GUMR [MODE] bit maps
*/
#define UCC_FAST_GUMR_HDLC 0x00000000
#define UCC_FAST_GUMR_QMC 0x00000002
#define UCC_FAST_GUMR_UART 0x00000004
#define UCC_FAST_GUMR_BISYNC 0x00000008
#define UCC_FAST_GUMR_ATM 0x0000000a
#define UCC_FAST_GUMR_ETH 0x0000000c
/* Transmit On Demand (UTORD)
*/
#define UCC_SLOW_TOD 0x8000
#define UCC_FAST_TOD 0x8000
/* Fast Ethernet (10/100 Mbps)
*/
#define UCC_GETH_URFS_INIT 512 /* Rx virtual FIFO size */
#define UCC_GETH_URFET_INIT 256 /* 1/2 urfs */
#define UCC_GETH_URFSET_INIT 384 /* 3/4 urfs */
#define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size */
#define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */
#define UCC_GETH_UTFTT_INIT 128
/* Gigabit Ethernet (1000 Mbps)
*/
#define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual FIFO size */
#define UCC_GETH_URFET_GIGA_INIT 2048/*1024*/ /* 1/2 urfs */
#define UCC_GETH_URFSET_GIGA_INIT 3072/*1536*/ /* 3/4 urfs */
#define UCC_GETH_UTFS_GIGA_INIT 8192/*2048*/ /* Tx virtual FIFO size */
#define UCC_GETH_UTFET_GIGA_INIT 4096/*1024*/ /* 1/2 utfs */
#define UCC_GETH_UTFTT_GIGA_INIT 0x400/*0x40*/ /* */
/* UCC fast alignment
*/
#define UCC_FAST_RX_ALIGN 4
#define UCC_FAST_MRBLR_ALIGNMENT 4
#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT 8
/* Sizes
*/
#define UCC_FAST_RX_VIRTUAL_FIFO_SIZE_PAD 8
/* UCC fast structure.
*/
typedef struct ucc_fast_info {
int ucc_num;
qe_clock_e rx_clock;
qe_clock_e tx_clock;
enet_type_e eth_type;
} ucc_fast_info_t;
typedef struct ucc_fast_private {
ucc_fast_info_t *uf_info;
ucc_fast_t *uf_regs; /* a pointer to memory map of UCC regs */
u32 *p_ucce; /* a pointer to the event register */
u32 *p_uccm; /* a pointer to the mask register */
int enabled_tx; /* whether UCC is enabled for Tx (ENT) */
int enabled_rx; /* whether UCC is enabled for Rx (ENR) */
u32 ucc_fast_tx_virtual_fifo_base_offset;
u32 ucc_fast_rx_virtual_fifo_base_offset;
} ucc_fast_private_t;
void ucc_fast_transmit_on_demand(ucc_fast_private_t *uccf);
u32 ucc_fast_get_qe_cr_subblock(int ucc_num);
void ucc_fast_enable(ucc_fast_private_t *uccf, comm_dir_e mode);
void ucc_fast_disable(ucc_fast_private_t *uccf, comm_dir_e mode);
int ucc_fast_init(ucc_fast_info_t *uf_info, ucc_fast_private_t **uccf_ret);
#endif /* __UCCF_H__ */

Some files were not shown because too many files have changed in this diff Show more