diff options
106 files changed, 22489 insertions, 2036 deletions
@@ -1,3 +1,134 @@ +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 @@ -67,6 +198,46 @@ 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 @@ -146,6 +317,379 @@ Date: Mon Nov 6 17:06:36 2006 +0100 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 @@ -641,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 @@ -873,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 @@ -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 diff --git a/MAINTAINERS b/MAINTAINERS index d453967..ce20def 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -277,6 +277,8 @@ Daniel Poirot <dan.poirot@windriver.com> Stefan Roese <sr@denx.de> + P3M7448 MPC7448 + uc100 MPC857 TQM85xx MPC8540/8541/8555/8560 @@ -294,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 @@ -340,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: @@ -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} \ @@ -93,7 +93,7 @@ MKCONFIG := $(SRCTREE)/mkconfig export MKCONFIG ifneq ($(OBJTREE),$(SRCTREE)) -REMOTE_BUILD := 1 +REMOTE_BUILD := 1 export REMOTE_BUILD endif @@ -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 @@ -378,8 +378,8 @@ Lite5200_LOWBOOT08_config \ icecube_5200_config \ icecube_5200_LOWBOOT_config \ icecube_5200_LOWBOOT08_config \ -icecube_5200_DDR_config \ -icecube_5200_DDR_LOWBOOT_config \ +icecube_5200_DDR_config \ +icecube_5200_DDR_LOWBOOT_config \ icecube_5200_DDR_LOWBOOT08_config \ icecube_5100_config: unconfig @mkdir -p $(obj)include @@ -458,7 +458,7 @@ prs200_highboot_DDR_config: unconfig @[ -n "$(findstring _SDRAM,$@)" ] || \ { if [ -n "$(findstring mcc200,$@)" ]; \ then \ - echo "... with DDR" ; \ + echo "... with DDR" ; \ else \ if [ -n "$(findstring _DDR,$@)" ];\ then \ @@ -865,9 +865,9 @@ RPXClassic_config: unconfig RPXlite_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc8xx RPXlite -RPXlite_DW_64_config \ -RPXlite_DW_LCD_config \ -RPXlite_DW_64_LCD_config \ +RPXlite_DW_64_config \ +RPXlite_DW_LCD_config \ +RPXlite_DW_64_LCD_config \ RPXlite_DW_NVRAM_config \ RPXlite_DW_NVRAM_64_config \ RPXlite_DW_NVRAM_LCD_config \ @@ -880,12 +880,12 @@ RPXlite_DW_config: unconfig echo "... with 64MHz system clock ..."; \ } @[ -z "$(findstring _LCD,$@)" ] || \ - { echo "#define CONFIG_LCD" >>$(obj)include/config.h ; \ + { echo "#define CONFIG_LCD" >>$(obj)include/config.h ; \ echo "#define CONFIG_NEC_NL6448BC20" >>$(obj)include/config.h ; \ echo "... with LCD display ..."; \ } @[ -z "$(findstring _NVRAM,$@)" ] || \ - { echo "#define CFG_ENV_IS_IN_NVRAM" >>$(obj)include/config.h ; \ + { echo "#define CFG_ENV_IS_IN_NVRAM" >>$(obj)include/config.h ; \ echo "... with ENV in NVRAM ..."; \ } @$(MKCONFIG) -a RPXlite_DW ppc mpc8xx RPXlite_dw @@ -1588,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 ######################################################################### @@ -1727,6 +1751,16 @@ mpc7448hpc2_config: unconfig 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 @@ -1790,7 +1824,7 @@ ap966_config \ ap922_config \ ap922_XA10_config \ ap7_config \ -ap720t_config \ +ap720t_config \ ap920t_config \ ap926ejs_config \ ap946es_config: unconfig @@ -1947,7 +1981,7 @@ cm4008_config : unconfig cm41xx_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t cm41xx NULL ks8695 -gth2_config : unconfig +gth2_config : unconfig @mkdir -p $(obj)include @ >$(obj)include/config.h @echo "#define CONFIG_GTH2 1" >>$(obj)include/config.h @@ -2093,19 +2127,19 @@ tb0229_config: unconfig ######################################################################### ## MIPS32 AU1X00 ######################################################################### -dbau1000_config : unconfig +dbau1000_config : unconfig @mkdir -p $(obj)include @ >$(obj)include/config.h @echo "#define CONFIG_DBAU1000 1" >>$(obj)include/config.h @$(MKCONFIG) -a dbau1x00 mips mips dbau1x00 -dbau1100_config : unconfig +dbau1100_config : unconfig @mkdir -p $(obj)include @ >$(obj)include/config.h @echo "#define CONFIG_DBAU1100 1" >>$(obj)include/config.h @$(MKCONFIG) -a dbau1x00 mips mips dbau1x00 -dbau1500_config : unconfig +dbau1500_config : unconfig @mkdir -p $(obj)include @ >$(obj)include/config.h @echo "#define CONFIG_DBAU1500 1" >>$(obj)include/config.h @@ -2123,7 +2157,7 @@ dbau1550_el_config : unconfig @echo "#define CONFIG_DBAU1550 1" >>$(obj)include/config.h @$(MKCONFIG) -a dbau1x00 mips mips dbau1x00 -pb1000_config : unconfig +pb1000_config : unconfig @mkdir -p $(obj)include @ >$(obj)include/config.h @echo "#define CONFIG_PB1000 1" >>$(obj)include/config.h @@ -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. diff --git a/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c b/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c index f18313d..dcfd83e 100644 --- a/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c +++ b/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c @@ -50,13 +50,13 @@ long int initdram (int board_type) MCFSDRAMC_DACR0 = MCFSDRAMC_DACR_BASE(CFG_SDRAM_BASE0) | MCFSDRAMC_DACR_CASL(1) - | MCFSDRAMC_DACR_CBM(3) + | MCFSDRAMC_DACR_CBM(3) | MCFSDRAMC_DACR_PS_16); MCFSDRAMC_DMR0 = MCFSDRAMC_DMR_BAM_16M | MCFSDRAMC_DMR_V; - MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP; + MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP; *(unsigned short *)(CFG_SDRAM_BASE0) = 0xA5A5; MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_RE; @@ -70,10 +70,10 @@ long int initdram (int board_type) #ifdef CFG_SDRAM_BASE1 MCFSDRAMC_DACR1 = MCFSDRAMC_DACR_BASE(CFG_SDRAM_BASE1) | MCFSDRAMC_DACR_CASL(1) - | MCFSDRAMC_DACR_CBM(3) + | MCFSDRAMC_DACR_CBM(3) | MCFSDRAMC_DACR_PS_16; - MCFSDRAMC_DMR1 = MCFSDRAMC_DMR_BAM_16M + MCFSDRAMC_DMR1 = MCFSDRAMC_DMR_BAM_16M | MCFSDRAMC_DMR_V; MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IP; @@ -82,7 +82,7 @@ long int initdram (int board_type) MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_RE; for (i=0; i < 2000; i++) asm(" nop"); - MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IMRS; + MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IMRS; *(unsigned int *)(CFG_SDRAM_BASE1 + 0x220) = 0xA5A5; size += CFG_SDRAM_SIZE1 * 1024 * 1024; #endif diff --git a/board/BuS/EB+MCF-EV123/VCxK.c b/board/BuS/EB+MCF-EV123/VCxK.c index 4938817..4b46b7c 100644 --- a/board/BuS/EB+MCF-EV123/VCxK.c +++ b/board/BuS/EB+MCF-EV123/VCxK.c @@ -66,7 +66,7 @@ int init_vcxk(void) return 1; } -void vcxk_loadimage(ulong source) +void vcxk_loadimage(ulong source) { int cnt; vcxk_acknowledge_wait(); diff --git a/board/BuS/EB+MCF-EV123/VCxK.h b/board/BuS/EB+MCF-EV123/VCxK.h index 74467ba..f591e5c 100644 --- a/board/BuS/EB+MCF-EV123/VCxK.h +++ b/board/BuS/EB+MCF-EV123/VCxK.h @@ -25,24 +25,24 @@ #define __VCXK_H_ extern int init_vcxk(void); -void vcxk_loadimage(ulong source); +void vcxk_loadimage(ulong source); #define VIDEO_ACKNOWLEDGE_PORT MCFGPTB_GPTPORT -#define VIDEO_ACKNOWLEDGE_DDR MCFGPTB_GPTDDR +#define VIDEO_ACKNOWLEDGE_DDR MCFGPTB_GPTDDR #define VIDEO_ACKNOWLEDGE_PIN 0x0001 -#define VIDEO_ENABLE_PORT MCFGPTB_GPTPORT -#define VIDEO_ENABLE_DDR MCFGPTB_GPTDDR +#define VIDEO_ENABLE_PORT MCFGPTB_GPTPORT +#define VIDEO_ENABLE_DDR MCFGPTB_GPTDDR #define VIDEO_ENABLE_PIN 0x0002 -#define VIDEO_REQUEST_PORT MCFGPTB_GPTPORT -#define VIDEO_REQUEST_DDR MCFGPTB_GPTDDR +#define VIDEO_REQUEST_PORT MCFGPTB_GPTPORT +#define VIDEO_REQUEST_DDR MCFGPTB_GPTDDR #define VIDEO_REQUEST_PIN 0x0004 #define VIDEO_Invert_CFG MCFGPIO_PEPAR #define VIDEO_Invert_IO MCFGPIO_PEPAR_PEPA2 -#define VIDEO_INVERT_PORT MCFGPIO_PORTE -#define VIDEO_INVERT_DDR MCFGPIO_DDRE +#define VIDEO_INVERT_PORT MCFGPIO_PORTE +#define VIDEO_INVERT_DDR MCFGPIO_DDRE #define VIDEO_INVERT_PIN MCFGPIO_PORT2 #endif diff --git a/board/BuS/EB+MCF-EV123/cfm_flash.c b/board/BuS/EB+MCF-EV123/cfm_flash.c index 6ecf0d1..b326384 100644 --- a/board/BuS/EB+MCF-EV123/cfm_flash.c +++ b/board/BuS/EB+MCF-EV123/cfm_flash.c @@ -60,7 +60,7 @@ void cfm_flash_init (flash_info_t * info) MCFCFM_MCR = 0; MCFCFM_CLKD = CFM_CLK; debug ("CFM Clock divider: %ld (%d Hz @ %ld Hz)\n",CFM_CLK,\ - CFG_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\ + CFG_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\ CFG_CLK); MCFCFM_SACC = 0; MCFCFM_DACC = 0; diff --git a/board/BuS/EB+MCF-EV123/flash.c b/board/BuS/EB+MCF-EV123/flash.c index ba76bef..5e2647d 100644 --- a/board/BuS/EB+MCF-EV123/flash.c +++ b/board/BuS/EB+MCF-EV123/flash.c @@ -256,7 +256,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) enable_interrupts (); if (cflag) - icache_enable (); + icache_enable (); return rc; } diff --git a/board/BuS/EB+MCF-EV123/u-boot.lds b/board/BuS/EB+MCF-EV123/u-boot.lds index d790018..ac53245 100644 --- a/board/BuS/EB+MCF-EV123/u-boot.lds +++ b/board/BuS/EB+MCF-EV123/u-boot.lds @@ -34,11 +34,11 @@ SECTIONS .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } + .rela.text : { *(.rela.text) } .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.ctors : { *(.rel.ctors) } diff --git a/board/LEOX/elpt860/u-boot.lds b/board/LEOX/elpt860/u-boot.lds index b09fc33..214752d 100644 --- a/board/LEOX/elpt860/u-boot.lds +++ b/board/LEOX/elpt860/u-boot.lds @@ -43,11 +43,11 @@ SECTIONS .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } + .rela.text : { *(.rela.text) } .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.ctors : { *(.rel.ctors) } diff --git a/board/LEOX/elpt860/u-boot.lds.debug b/board/LEOX/elpt860/u-boot.lds.debug index 6f5af91..17f99eb 100644 --- a/board/LEOX/elpt860/u-boot.lds.debug +++ b/board/LEOX/elpt860/u-boot.lds.debug @@ -43,11 +43,11 @@ SECTIONS .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } + .rela.text : { *(.rela.text) } .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.ctors : { *(.rel.ctors) } diff --git a/board/MAI/AmigaOneG3SE/Makefile b/board/MAI/AmigaOneG3SE/Makefile index cb6ea26..fa28d3b 100644 --- a/board/MAI/AmigaOneG3SE/Makefile +++ b/board/MAI/AmigaOneG3SE/Makefile @@ -30,7 +30,7 @@ endif LIB = $(obj)lib$(BOARD).a COBJS = $(BOARD).o articiaS.o flash.o serial.o smbus.o articiaS_pci.o \ - via686.o i8259.o ../bios_emulator/x86interface.o \ + via686.o i8259.o ../bios_emulator/x86interface.o \ ../bios_emulator/bios.o ../bios_emulator/glue.o \ interrupts.o ps2kbd.o video.o usb_uhci.o enet.o \ ../menu/cmd_menu.o cmd_boota.o nvram.o diff --git a/board/MAI/AmigaOneG3SE/articiaS_pci.c b/board/MAI/AmigaOneG3SE/articiaS_pci.c index 480dae5..45b8195 100644 --- a/board/MAI/AmigaOneG3SE/articiaS_pci.c +++ b/board/MAI/AmigaOneG3SE/articiaS_pci.c @@ -368,11 +368,11 @@ void articiaS_pci_init (void) if (articiaS_init_vga() == -1) { /* If the VGA didn't init and we have stdout set to VGA, reset to serial */ -/* s = getenv("stdout"); */ -/* if (s && strcmp(s, "vga") == 0) */ -/* { */ -/* setenv("stdout", "serial"); */ -/* } */ +/* s = getenv("stdout"); */ +/* if (s && strcmp(s, "vga") == 0) */ +/* { */ +/* setenv("stdout", "serial"); */ +/* } */ } } pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF); diff --git a/board/MAI/AmigaOneG3SE/enet.c b/board/MAI/AmigaOneG3SE/enet.c index d4be889..ad2bcde 100644 --- a/board/MAI/AmigaOneG3SE/enet.c +++ b/board/MAI/AmigaOneG3SE/enet.c @@ -41,57 +41,57 @@ /* 3Com Commands, top 5 bits are command and bottom 11 bits are parameters */ -#define TotalReset (0<<11) -#define SelectWindow (1<<11) -#define StartCoax (2<<11) -#define RxDisable (3<<11) -#define RxEnable (4<<11) -#define RxReset (5<<11) -#define UpStall (6<<11) -#define UpUnstall (6<<11)+1 -#define DownStall (6<<11)+2 -#define DownUnstall (6<<11)+3 -#define RxDiscard (8<<11) -#define TxEnable (9<<11) -#define TxDisable (10<<11) -#define TxReset (11<<11) -#define FakeIntr (12<<11) -#define AckIntr (13<<11) -#define SetIntrEnb (14<<11) -#define SetStatusEnb (15<<11) -#define SetRxFilter (16<<11) -#define SetRxThreshold (17<<11) -#define SetTxThreshold (18<<11) -#define SetTxStart (19<<11) -#define StartDMAUp (20<<11) -#define StartDMADown (20<<11)+1 +#define TotalReset (0<<11) +#define SelectWindow (1<<11) +#define StartCoax (2<<11) +#define RxDisable (3<<11) +#define RxEnable (4<<11) +#define RxReset (5<<11) +#define UpStall (6<<11) +#define UpUnstall (6<<11)+1 +#define DownStall (6<<11)+2 +#define DownUnstall (6<<11)+3 +#define RxDiscard (8<<11) +#define TxEnable (9<<11) +#define TxDisable (10<<11) +#define TxReset (11<<11) +#define FakeIntr (12<<11) +#define AckIntr (13<<11) +#define SetIntrEnb (14<<11) +#define SetStatusEnb (15<<11) +#define SetRxFilter (16<<11) +#define SetRxThreshold (17<<11) +#define SetTxThreshold (18<<11) +#define SetTxStart (19<<11) +#define StartDMAUp (20<<11) +#define StartDMADown (20<<11)+1 #define StatsEnable (21<<11) #define StatsDisable (22<<11) -#define StopCoax (23<<11) -#define SetFilterBit (25<<11) +#define StopCoax (23<<11) +#define SetFilterBit (25<<11) /* The SetRxFilter command accepts the following classes */ -#define RxStation 1 +#define RxStation 1 #define RxMulticast 2 #define RxBroadcast 4 -#define RxProm 8 +#define RxProm 8 /* 3Com status word defnitions */ -#define IntLatch 0x0001 -#define HostError 0x0002 -#define TxComplete 0x0004 -#define TxAvailable 0x0008 -#define RxComplete 0x0010 -#define RxEarly 0x0020 -#define IntReq 0x0040 -#define StatsFull 0x0080 -#define DMADone (1<<8) -#define DownComplete (1<<9) -#define UpComplete (1<<10) -#define DMAInProgress (1<<11) /* DMA controller is still busy.*/ -#define CmdInProgress (1<<12) /* EL3_CMD is still busy.*/ +#define IntLatch 0x0001 +#define HostError 0x0002 +#define TxComplete 0x0004 +#define TxAvailable 0x0008 +#define RxComplete 0x0010 +#define RxEarly 0x0020 +#define IntReq 0x0040 +#define StatsFull 0x0080 +#define DMADone (1<<8) +#define DownComplete (1<<9) +#define UpComplete (1<<10) +#define DMAInProgress (1<<11) /* DMA controller is still busy.*/ +#define CmdInProgress (1<<12) /* EL3_CMD is still busy.*/ /* Polling Registers */ @@ -100,17 +100,17 @@ /* Register window 0 offets */ -#define Wn0EepromCmd 10 /* Window 0: EEPROM command register. */ -#define Wn0EepromData 12 /* Window 0: EEPROM results register. */ +#define Wn0EepromCmd 10 /* Window 0: EEPROM command register. */ +#define Wn0EepromData 12 /* Window 0: EEPROM results register. */ #define IntrStatus 0x0E /* Valid in all windows. */ /* Register window 0 EEPROM bits */ -#define EEPROM_Read 0x80 -#define EEPROM_WRITE 0x40 -#define EEPROM_ERASE 0xC0 -#define EEPROM_EWENB 0x30 /* Enable erasing/writing for 10 msec. */ -#define EEPROM_EWDIS 0x00 /* Disable EWENB before 10 msec timeout. */ +#define EEPROM_Read 0x80 +#define EEPROM_WRITE 0x40 +#define EEPROM_ERASE 0xC0 +#define EEPROM_EWENB 0x30 /* Enable erasing/writing for 10 msec. */ +#define EEPROM_EWDIS 0x00 /* Disable EWENB before 10 msec timeout. */ /* EEPROM locations. */ @@ -129,13 +129,13 @@ /* Register window 1 offsets, the window used in normal operation */ -#define TX_FIFO 0x10 -#define RX_FIFO 0x10 -#define RxErrors 0x14 -#define RxStatus 0x18 +#define TX_FIFO 0x10 +#define RX_FIFOa 0x10 +#define RxErrors 0x14 +#define RxStatus 0x18 #define Timer 0x1A -#define TxStatus 0x1B -#define TxFree 0x1C /* Remaining free bytes in Tx buffer. */ +#define TxStatus 0x1B +#define TxFree 0x1C /* Remaining free bytes in Tx buffer. */ /* Register Window 2 */ @@ -147,47 +147,47 @@ #define Wn3_MAC_Ctrl 6 #define Wn3_Options 8 -#define BFEXT(value, offset, bitcount) \ +#define BFEXT(value, offset, bitcount) \ ((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1)) #define BFINS(lhs, rhs, offset, bitcount) \ - (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \ + (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \ (((rhs) & ((1 << (bitcount)) - 1)) << (offset))) #define RAM_SIZE(v) BFEXT(v, 0, 3) -#define RAM_WIDTH(v) BFEXT(v, 3, 1) -#define RAM_SPEED(v) BFEXT(v, 4, 2) +#define RAM_WIDTH(v) BFEXT(v, 3, 1) +#define RAM_SPEED(v) BFEXT(v, 4, 2) #define ROM_SIZE(v) BFEXT(v, 6, 2) -#define RAM_SPLIT(v) BFEXT(v, 16, 2) +#define RAM_SPLIT(v) BFEXT(v, 16, 2) #define XCVR(v) BFEXT(v, 20, 4) -#define AUTOSELECT(v) BFEXT(v, 24, 1) +#define AUTOSELECT(v) BFEXT(v, 24, 1) /* Register Window 4: Xcvr/media bits */ -#define Wn4_FIFODiag 4 -#define Wn4_NetDiag 6 +#define Wn4_FIFODiag 4 +#define Wn4_NetDiag 6 #define Wn4_PhysicalMgmt 8 -#define Wn4_Media 10 +#define Wn4_Media 10 -#define Media_SQE 0x0008 /* Enable SQE error counting for AUI. */ -#define Media_10TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ -#define Media_Lnk 0x0080 /* Enable just link beat for 100TX/100FX. */ -#define Media_LnkBeat 0x0800 +#define Media_SQE 0x0008 /* Enable SQE error counting for AUI. */ +#define Media_10TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ +#define Media_Lnk 0x0080 /* Enable just link beat for 100TX/100FX. */ +#define Media_LnkBeat 0x0800 /* Register Window 7: Bus Master control */ -#define Wn7_MasterAddr 0 -#define Wn7_MasterLen 6 -#define Wn7_MasterStatus 12 +#define Wn7_MasterAddr 0 +#define Wn7_MasterLen 6 +#define Wn7_MasterStatus 12 /* Boomerang bus master control registers. */ -#define PktStatus 0x20 +#define PktStatus 0x20 #define DownListPtr 0x24 -#define FragAddr 0x28 -#define FragLen 0x2c +#define FragAddr 0x28 +#define FragLen 0x2c #define TxFreeThreshold 0x2f -#define UpPktStatus 0x30 +#define UpPktStatus 0x30 #define UpListPtr 0x38 /* The Rx and Tx descriptor lists. */ diff --git a/board/emk/top5200/top5200.c b/board/emk/top5200/top5200.c index 12acc57..d741e6b 100644 --- a/board/emk/top5200/top5200.c +++ b/board/emk/top5200/top5200.c @@ -190,7 +190,7 @@ void init_ide_reset (void) { debug ("init_ide_reset\n"); - /* Configure PSC1_4 as GPIO output for ATA reset */ + /* Configure PSC1_4 as GPIO output for ATA reset */ *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; } diff --git a/board/esd/cpci5200/cpci5200.c b/board/esd/cpci5200/cpci5200.c index f14331b..a925b84 100644 --- a/board/esd/cpci5200/cpci5200.c +++ b/board/esd/cpci5200/cpci5200.c @@ -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 diff --git a/board/esd/pf5200/pf5200.c b/board/esd/pf5200/pf5200.c index 1f30d45..77e164b 100644 --- a/board/esd/pf5200/pf5200.c +++ b/board/esd/pf5200/pf5200.c @@ -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 diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c index f958b32..700c9d9 100644 --- a/board/icecube/icecube.c +++ b/board/icecube/icecube.c @@ -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 @@ -312,7 +316,7 @@ void init_ide_reset (void) { debug ("init_ide_reset\n"); - /* Configure PSC1_4 as GPIO output for ATA reset */ + /* Configure PSC1_4 as GPIO output for ATA reset */ *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; /* Deassert reset */ @@ -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 diff --git a/board/mpc8349emds/Makefile b/board/mpc8349emds/Makefile index acc9544..5ec7a87 100644 --- a/board/mpc8349emds/Makefile +++ b/board/mpc8349emds/Makefile @@ -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)) diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c index b5ccb53..873bdd0 100644 --- a/board/mpc8349emds/mpc8349emds.c +++ b/board/mpc8349emds/mpc8349emds.c @@ -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 diff --git a/board/mpc8349emds/pci.c b/board/mpc8349emds/pci.c index 63e4405..d6a12b8 100644 --- a/board/mpc8349emds/pci.c +++ b/board/mpc8349emds/pci.c @@ -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 */ diff --git a/board/mpc8349itx/Makefile b/board/mpc8349itx/Makefile new file mode 100644 index 0000000..31bcdb8 --- /dev/null +++ b/board/mpc8349itx/Makefile @@ -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 + +######################################################################### diff --git a/board/mpc8349itx/config.mk b/board/mpc8349itx/config.mk new file mode 100644 index 0000000..2e11311 --- /dev/null +++ b/board/mpc8349itx/config.mk @@ -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 diff --git a/board/mpc8349itx/mpc8349itx.c b/board/mpc8349itx/mpc8349itx.c new file mode 100644 index 0000000..4838e70 --- /dev/null +++ b/board/mpc8349itx/mpc8349itx.c @@ -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 diff --git a/board/mpc8349itx/pci.c b/board/mpc8349itx/pci.c new file mode 100644 index 0000000..e81ad27 --- /dev/null +++ b/board/mpc8349itx/pci.c @@ -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, ®8, sizeof(reg8)) == 0) || + (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, ®8, 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, ®16); + 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, ®16); + 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 */ diff --git a/board/mpc8349itx/u-boot.lds b/board/mpc8349itx/u-boot.lds new file mode 100644 index 0000000..f044c0f --- /dev/null +++ b/board/mpc8349itx/u-boot.lds @@ -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) diff --git a/board/mpc8360emds/Makefile b/board/mpc8360emds/Makefile new file mode 100644 index 0000000..5ec7a87 --- /dev/null +++ b/board/mpc8360emds/Makefile @@ -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 + +######################################################################### diff --git a/board/mpc8360emds/config.mk b/board/mpc8360emds/config.mk new file mode 100644 index 0000000..9ace886 --- /dev/null +++ b/board/mpc8360emds/config.mk @@ -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 diff --git a/board/mpc8360emds/mpc8360emds.c b/board/mpc8360emds/mpc8360emds.c new file mode 100644 index 0000000..ddc1047 --- /dev/null +++ b/board/mpc8360emds/mpc8360emds.c @@ -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 diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c new file mode 100644 index 0000000..15a48dc --- /dev/null +++ b/board/mpc8360emds/pci.c @@ -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, ®16); + 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, ®16); + 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, ®16); + 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 */ diff --git a/board/mpc8360emds/u-boot.lds b/board/mpc8360emds/u-boot.lds new file mode 100644 index 0000000..937c87a --- /dev/null +++ b/board/mpc8360emds/u-boot.lds @@ -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) diff --git a/board/prodrive/p3mx/64460.h b/board/prodrive/p3mx/64460.h new file mode 100644 index 0000000..8bb0ebf --- /dev/null +++ b/board/prodrive/p3mx/64460.h @@ -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__ */ diff --git a/board/prodrive/p3mx/Makefile b/board/prodrive/p3mx/Makefile new file mode 100644 index 0000000..bf74a5a --- /dev/null +++ b/board/prodrive/p3mx/Makefile @@ -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 + +######################################################################### diff --git a/board/prodrive/p3mx/config.mk b/board/prodrive/p3mx/config.mk new file mode 100644 index 0000000..35bf1c1 --- /dev/null +++ b/board/prodrive/p3mx/config.mk @@ -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 diff --git a/board/prodrive/p3mx/eth.h b/board/prodrive/p3mx/eth.h new file mode 100644 index 0000000..aab32d2 --- /dev/null +++ b/board/prodrive/p3mx/eth.h @@ -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__ */ diff --git a/board/prodrive/p3mx/misc.S b/board/prodrive/p3mx/misc.S new file mode 100644 index 0000000..160b1d3 --- /dev/null +++ b/board/prodrive/p3mx/misc.S @@ -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 diff --git a/board/prodrive/p3mx/mpsc.c b/board/prodrive/p3mx/mpsc.c new file mode 100644 index 0000000..da95cfa --- /dev/null +++ b/board/prodrive/p3mx/mpsc.c @@ -0,0 +1,1013 @@ +/* + * (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 DB64460 eval board 2003 by Ingo Assmus <ingo.assmus@keymile.com> + * + ************************************************************************/ + +/* + * mpsc.c - driver for console over the MPSC. + */ + + +#include <common.h> +#include <config.h> +#include <asm/cache.h> + +#include <malloc.h> +#include "mpsc.h" + +#include "mv_regs.h" + +#include "../../Marvell/include/memory.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* Define this if you wish to use the MPSC as a register based UART. + * This will force the serial port to not use the SDMA engine at all. + */ +#undef CONFIG_MPSC_DEBUG_PORT + + +int (*mpsc_putchar) (char ch) = mpsc_putchar_early; +char (*mpsc_getchar) (void) = mpsc_getchar_debug; +int (*mpsc_test_char) (void) = mpsc_test_char_debug; + + +static volatile unsigned int *rx_desc_base = NULL; +static unsigned int rx_desc_index = 0; +static volatile unsigned int *tx_desc_base = NULL; +static unsigned int tx_desc_index = 0; + +/* local function declarations */ +static int galmpsc_connect (int channel, int connect); +static int galmpsc_route_rx_clock (int channel, int brg); +static int galmpsc_route_tx_clock (int channel, int brg); +static int galmpsc_write_config_regs (int mpsc, int mode); +static int galmpsc_config_channel_regs (int mpsc); +static int galmpsc_set_char_length (int mpsc, int value); +static int galmpsc_set_stop_bit_length (int mpsc, int value); +static int galmpsc_set_parity (int mpsc, int value); +static int galmpsc_enter_hunt (int mpsc); +static int galmpsc_set_brkcnt (int mpsc, int value); +static int galmpsc_set_tcschar (int mpsc, int value); +static int galmpsc_set_snoop (int mpsc, int value); +static int galmpsc_shutdown (int mpsc); + +static int galsdma_set_RFT (int channel); +static int galsdma_set_SFM (int channel); +static int galsdma_set_rxle (int channel); +static int galsdma_set_txle (int channel); +static int galsdma_set_burstsize (int channel, unsigned int value); +static int galsdma_set_RC (int channel, unsigned int value); + +static int galbrg_set_CDV (int channel, int value); +static int galbrg_enable (int channel); +static int galbrg_disable (int channel); +static int galbrg_set_clksrc (int channel, int value); +static int galbrg_set_CUV (int channel, int value); + +static void galsdma_enable_rx (void); +static int galsdma_set_mem_space (unsigned int memSpace, + unsigned int memSpaceTarget, + unsigned int memSpaceAttr, + unsigned int baseAddress, + unsigned int size); + + +#define SOFTWARE_CACHE_MANAGEMENT + +#ifdef SOFTWARE_CACHE_MANAGEMENT +#define FLUSH_DCACHE(a,b) if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));} +#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));} +#define INVALIDATE_DCACHE(a,b) if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));} +#else +#define FLUSH_DCACHE(a,b) +#define FLUSH_AND_INVALIDATE_DCACHE(a,b) +#define INVALIDATE_DCACHE(a,b) +#endif + +#ifdef CONFIG_MPSC_DEBUG_PORT +static void mpsc_debug_init (void) +{ + + volatile unsigned int temp; + + /* Clear the CFR (CHR4) */ + /* Write random 'Z' bit (bit 29) of CHR4 to enable debug uart *UNDOCUMENTED FEATURE* */ + temp = GTREGREAD (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP)); + temp &= 0xffffff00; + temp |= BIT29; + GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP), + temp); + + /* Set the Valid bit 'V' (bit 12) and int generation bit 'INT' (bit 15) */ + temp = GTREGREAD (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP)); + temp |= (BIT12 | BIT15); + GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP), + temp); + + /* Set int mask */ + temp = GTREGREAD (GALMPSC_0_INT_MASK); + temp |= BIT6; + GT_REG_WRITE (GALMPSC_0_INT_MASK, temp); +} +#endif + +char mpsc_getchar_debug (void) +{ + volatile int temp; + volatile unsigned int cause; + + cause = GTREGREAD (GALMPSC_0_INT_CAUSE); + while ((cause & BIT6) == 0) { + cause = GTREGREAD (GALMPSC_0_INT_CAUSE); + } + + temp = GTREGREAD (GALMPSC_CHANNELREG_10 + + (CHANNEL * GALMPSC_REG_GAP)); + /* By writing 1's to the set bits, the register is cleared */ + GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (CHANNEL * GALMPSC_REG_GAP), + temp); + GT_REG_WRITE (GALMPSC_0_INT_CAUSE, cause & ~BIT6); + return (temp >> 16) & 0xff; +} + +/* special function for running out of flash. doesn't modify any + * global variables [josh] */ +int mpsc_putchar_early (char ch) +{ + int mpsc = CHANNEL; + int temp = + GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)); + galmpsc_set_tcschar (mpsc, ch); + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), + temp | 0x200); + +#define MAGIC_FACTOR (10*1000000) + + udelay (MAGIC_FACTOR / gd->baudrate); + return 0; +} + +/* This is used after relocation, see serial.c and mpsc_init2 */ +static int mpsc_putchar_sdma (char ch) +{ + volatile unsigned int *p; + unsigned int temp; + + + /* align the descriptor */ + p = tx_desc_base; + memset ((void *) p, 0, 8 * sizeof (unsigned int)); + + /* fill one 64 bit buffer */ + /* word swap, pad with 0 */ + p[4] = 0; /* x */ + p[5] = (unsigned int) ch; /* x */ + + /* CHANGED completely according to GT64260A dox - NTL */ + p[0] = 0x00010001; /* 0 */ + p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* 4 */ + p[2] = 0; /* 8 */ + p[3] = (unsigned int) &p[4]; /* c */ + +#if 0 + p[9] = DESC_FIRST | DESC_LAST; + p[10] = (unsigned int) &p[0]; + p[11] = (unsigned int) &p[12]; +#endif + + FLUSH_DCACHE (&p[0], &p[8]); + + GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF), + (unsigned int) &p[0]); + GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF), + (unsigned int) &p[0]); + + temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF)); + temp |= (TX_DEMAND | TX_STOP); + GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp); + + INVALIDATE_DCACHE (&p[1], &p[2]); + + while (p[1] & DESC_OWNER_BIT) { + udelay (100); + INVALIDATE_DCACHE (&p[1], &p[2]); + } + return 0; +} + +char mpsc_getchar_sdma (void) +{ + static unsigned int done = 0; + volatile char ch; + unsigned int len = 0, idx = 0, temp; + + volatile unsigned int *p; + + + do { + p = &rx_desc_base[rx_desc_index * 8]; + + INVALIDATE_DCACHE (&p[0], &p[1]); + /* Wait for character */ + while (p[1] & DESC_OWNER_BIT) { + udelay (100); + INVALIDATE_DCACHE (&p[0], &p[1]); + } + + /* Handle error case */ + if (p[1] & (1 << 15)) { + printf ("oops, error: %08x\n", p[1]); + + temp = GTREGREAD (GALMPSC_CHANNELREG_2 + + (CHANNEL * GALMPSC_REG_GAP)); + temp |= (1 << 23); + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + + (CHANNEL * GALMPSC_REG_GAP), temp); + + /* Can't poll on abort bit, so we just wait. */ + udelay (100); + + galsdma_enable_rx (); + } + + /* Number of bytes left in this descriptor */ + len = p[0] & 0xffff; + + if (len) { + /* Where to look */ + idx = 5; + if (done > 3) + idx = 4; + if (done > 7) + idx = 7; + if (done > 11) + idx = 6; + + INVALIDATE_DCACHE (&p[idx], &p[idx + 1]); + ch = p[idx] & 0xff; + done++; + } + + if (done < len) { + /* this descriptor has more bytes still + * shift down the char we just read, and leave the + * buffer in place for the next time around + */ + p[idx] = p[idx] >> 8; + FLUSH_DCACHE (&p[idx], &p[idx + 1]); + } + + if (done == len) { + /* nothing left in this descriptor. + * go to next one + */ + p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; + p[0] = 0x00100000; + FLUSH_DCACHE (&p[0], &p[1]); + /* Next descriptor */ + rx_desc_index = (rx_desc_index + 1) % RX_DESC; + done = 0; + } + } while (len == 0); /* galileo bug.. len might be zero */ + + return ch; +} + + +int mpsc_test_char_debug (void) +{ + if ((GTREGREAD (GALMPSC_0_INT_CAUSE) & BIT6) == 0) + return 0; + else { + return 1; + } +} + + +int mpsc_test_char_sdma (void) +{ + volatile unsigned int *p = &rx_desc_base[rx_desc_index * 8]; + + INVALIDATE_DCACHE (&p[1], &p[2]); + + if (p[1] & DESC_OWNER_BIT) + return 0; + else + return 1; +} + +int mpsc_init (int baud) +{ + /* BRG CONFIG */ + galbrg_set_baudrate (CHANNEL, baud); + galbrg_set_clksrc (CHANNEL, 8); /* set source=Tclk */ + galbrg_set_CUV (CHANNEL, 0); /* set up CountUpValue */ + galbrg_enable (CHANNEL); /* Enable BRG */ + + /* Set up clock routing */ + galmpsc_connect (CHANNEL, GALMPSC_CONNECT); /* connect it */ + + galmpsc_route_rx_clock (CHANNEL, CHANNEL); /* chosse BRG0 for Rx */ + galmpsc_route_tx_clock (CHANNEL, CHANNEL); /* chose BRG0 for Tx */ + + /* reset MPSC state */ + galmpsc_shutdown (CHANNEL); + + /* SDMA CONFIG */ + galsdma_set_burstsize (CHANNEL, L1_CACHE_BYTES / 8); /* in 64 bit words (8 bytes) */ + galsdma_set_txle (CHANNEL); + galsdma_set_rxle (CHANNEL); + galsdma_set_RC (CHANNEL, 0xf); + galsdma_set_SFM (CHANNEL); + galsdma_set_RFT (CHANNEL); + + /* MPSC CONFIG */ + galmpsc_write_config_regs (CHANNEL, GALMPSC_UART); + galmpsc_config_channel_regs (CHANNEL); + galmpsc_set_char_length (CHANNEL, GALMPSC_CHAR_LENGTH_8); /* 8 */ + galmpsc_set_parity (CHANNEL, GALMPSC_PARITY_NONE); /* N */ + galmpsc_set_stop_bit_length (CHANNEL, GALMPSC_STOP_BITS_1); /* 1 */ + +#ifdef CONFIG_MPSC_DEBUG_PORT + mpsc_debug_init (); +#endif + + /* COMM_MPSC CONFIG */ +#ifdef SOFTWARE_CACHE_MANAGEMENT + galmpsc_set_snoop (CHANNEL, 0); /* disable snoop */ +#else + galmpsc_set_snoop (CHANNEL, 1); /* enable snoop */ +#endif + + return 0; +} + + +void mpsc_sdma_init (void) +{ + /* Setup SDMA channel0 SDMA_CONFIG_REG*/ + GT_REG_WRITE (SDMA_CONFIG_REG (0), 0x000020ff); + + /* Enable MPSC-Window0 for DRAM Bank 0 */ + if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT, + MV64460_SDMA_DRAM_CS_0_TARGET, + 0, + memoryGetBankBaseAddress(0), + memoryGetBankSize(0)) != true) + printf ("%s: SDMA_Window0 memory setup failed !!! \n", + __FUNCTION__); + + + /* Enable MPSC-Window1 for DRAM Bank 1 */ + if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_1_BIT, + MV64460_SDMA_DRAM_CS_1_TARGET, + 0, + memoryGetBankBaseAddress(1), + memoryGetBankSize(1)) != true) + printf ("%s: SDMA_Window1 memory setup failed !!! \n", + __FUNCTION__); + + + /* Disable MPSC-Window2 */ + if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_2_BIT, + MV64460_SDMA_DRAM_CS_2_TARGET, + 0, + memoryGetBankBaseAddress(2), + memoryGetBankSize(2)) != true) + printf ("%s: SDMA_Window2 memory setup failed !!! \n", + __FUNCTION__); + + + /* Disable MPSC-Window3 */ + if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_3_BIT, + MV64460_SDMA_DRAM_CS_3_TARGET, + 0, + memoryGetBankBaseAddress(3), + memoryGetBankSize(3)) != true) + printf ("%s: SDMA_Window3 memory setup failed !!! \n", + __FUNCTION__); + + /* Setup MPSC0 access mode Window0 full access */ + GT_SET_REG_BITS (MPSC0_ACCESS_PROTECTION_REG, + (MV64460_SDMA_WIN_ACCESS_FULL << + (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2))); + + /* Setup MPSC1 access mode Window1 full access */ + GT_SET_REG_BITS (MPSC1_ACCESS_PROTECTION_REG, + (MV64460_SDMA_WIN_ACCESS_FULL << + (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2))); + + /* Setup MPSC internal address space base address */ + GT_REG_WRITE (CUNIT_INTERNAL_SPACE_BASE_ADDR_REG, CFG_GT_REGS); + + /* no high address remap*/ + GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG0, 0x00); + GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG1, 0x00); + + /* clear interrupt cause register for MPSC (fault register)*/ + GT_REG_WRITE (CUNIT_INTERRUPT_CAUSE_REG, 0x00); +} + + +void mpsc_init2 (void) +{ + int i; + +#ifndef CONFIG_MPSC_DEBUG_PORT + mpsc_putchar = mpsc_putchar_sdma; + mpsc_getchar = mpsc_getchar_sdma; + mpsc_test_char = mpsc_test_char_sdma; +#endif + /* RX descriptors */ + rx_desc_base = (unsigned int *) malloc (((RX_DESC + 1) * 8) * + sizeof (unsigned int)); + + /* align descriptors */ + rx_desc_base = (unsigned int *) + (((unsigned int) rx_desc_base + 32) & 0xFFFFFFF0); + + rx_desc_index = 0; + + memset ((void *) rx_desc_base, 0, + (RX_DESC * 8) * sizeof (unsigned int)); + + for (i = 0; i < RX_DESC; i++) { + rx_desc_base[i * 8 + 3] = (unsigned int) &rx_desc_base[i * 8 + 4]; /* Buffer */ + rx_desc_base[i * 8 + 2] = (unsigned int) &rx_desc_base[(i + 1) * 8]; /* Next descriptor */ + rx_desc_base[i * 8 + 1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* Command & control */ + rx_desc_base[i * 8] = 0x00100000; + } + rx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &rx_desc_base[0]; + + FLUSH_DCACHE (&rx_desc_base[0], &rx_desc_base[RX_DESC * 8]); + GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR + (CHANNEL * GALSDMA_REG_DIFF), + (unsigned int) &rx_desc_base[0]); + + /* TX descriptors */ + tx_desc_base = (unsigned int *) malloc (((TX_DESC + 1) * 8) * + sizeof (unsigned int)); + + /* align descriptors */ + tx_desc_base = (unsigned int *) + (((unsigned int) tx_desc_base + 32) & 0xFFFFFFF0); + + tx_desc_index = -1; + + memset ((void *) tx_desc_base, 0, + (TX_DESC * 8) * sizeof (unsigned int)); + + for (i = 0; i < TX_DESC; i++) { + tx_desc_base[i * 8 + 5] = (unsigned int) 0x23232323; + tx_desc_base[i * 8 + 4] = (unsigned int) 0x23232323; + tx_desc_base[i * 8 + 3] = + (unsigned int) &tx_desc_base[i * 8 + 4]; + tx_desc_base[i * 8 + 2] = + (unsigned int) &tx_desc_base[(i + 1) * 8]; + tx_desc_base[i * 8 + 1] = + DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; + + /* set sbytecnt and shadow byte cnt to 1 */ + tx_desc_base[i * 8] = 0x00010001; + } + tx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &tx_desc_base[0]; + + FLUSH_DCACHE (&tx_desc_base[0], &tx_desc_base[TX_DESC * 8]); + + udelay (100); + + galsdma_enable_rx (); + + return; +} + +int galbrg_set_baudrate (int channel, int rate) +{ + int clock; + + galbrg_disable (channel); /*ok */ + +#ifdef ZUMA_NTL + /* from tclk */ + clock = (CFG_TCLK / (16 * rate)) - 1; +#else + clock = (CFG_TCLK / (16 * rate)) - 1; +#endif + + galbrg_set_CDV (channel, clock); /* set timer Reg. for BRG */ + + galbrg_enable (channel); + + gd->baudrate = rate; + + return 0; +} + +/* ------------------------------------------------------------------ */ + +/* Below are all the private functions that no one else needs */ + +static int galbrg_set_CDV (int channel, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp &= 0xFFFF0000; + temp |= (value & 0x0000FFFF); + GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + + return 0; +} + +static int galbrg_enable (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp |= 0x00010000; + GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + + return 0; +} + +static int galbrg_disable (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp &= 0xFFFEFFFF; + GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + + return 0; +} + +static int galbrg_set_clksrc (int channel, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp &= 0xFFC3FFFF; /* Bit 18 - 21 (MV 64260 18-22) */ + temp |= (value << 18); + GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + return 0; +} + +static int galbrg_set_CUV (int channel, int value) +{ + /* set CountUpValue */ + GT_REG_WRITE (GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value); + + return 0; +} + +#if 0 +static int galbrg_reset (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP)); + temp |= 0x20000; + GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp); + + return 0; +} +#endif + +static int galsdma_set_RFT (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp |= 0x00000001; + GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF), + temp); + + return 0; +} + +static int galsdma_set_SFM (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp |= 0x00000002; + GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF), + temp); + + return 0; +} + +static int galsdma_set_rxle (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp |= 0x00000040; + GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF), + temp); + + return 0; +} + +static int galsdma_set_txle (int channel) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp |= 0x00000080; + GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF), + temp); + + return 0; +} + +static int galsdma_set_RC (int channel, unsigned int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp &= ~0x0000003c; + temp |= (value << 2); + GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF), + temp); + + return 0; +} + +static int galsdma_set_burstsize (int channel, unsigned int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF)); + temp &= 0xFFFFCFFF; + switch (value) { + case 8: + GT_REG_WRITE (GALSDMA_0_CONF_REG + + (channel * GALSDMA_REG_DIFF), + (temp | (0x3 << 12))); + break; + + case 4: + GT_REG_WRITE (GALSDMA_0_CONF_REG + + (channel * GALSDMA_REG_DIFF), + (temp | (0x2 << 12))); + break; + + case 2: + GT_REG_WRITE (GALSDMA_0_CONF_REG + + (channel * GALSDMA_REG_DIFF), + (temp | (0x1 << 12))); + break; + + case 1: + GT_REG_WRITE (GALSDMA_0_CONF_REG + + (channel * GALSDMA_REG_DIFF), + (temp | (0x0 << 12))); + break; + + default: + return -1; + break; + } + + return 0; +} + +static int galmpsc_connect (int channel, int connect) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_ROUTING_REGISTER); + + if ((channel == 0) && connect) + temp &= ~0x00000007; + else if ((channel == 1) && connect) + temp &= ~(0x00000007 << 6); + else if ((channel == 0) && !connect) + temp |= 0x00000007; + else + temp |= (0x00000007 << 6); + + /* Just in case... */ + temp &= 0x3fffffff; + + GT_REG_WRITE (GALMPSC_ROUTING_REGISTER, temp); + + return 0; +} + +static int galmpsc_route_rx_clock (int channel, int brg) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_RxC_ROUTE); + + if (channel == 0) { + temp &= ~0x0000000F; + temp |= brg; + } else { + temp &= ~0x00000F00; + temp |= (brg << 8); + } + + GT_REG_WRITE (GALMPSC_RxC_ROUTE, temp); + + return 0; +} + +static int galmpsc_route_tx_clock (int channel, int brg) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_TxC_ROUTE); + + if (channel == 0) { + temp &= ~0x0000000F; + temp |= brg; + } else { + temp &= ~0x00000F00; + temp |= (brg << 8); + } + + GT_REG_WRITE (GALMPSC_TxC_ROUTE, temp); + + return 0; +} + +static int galmpsc_write_config_regs (int mpsc, int mode) +{ + if (mode == GALMPSC_UART) { + /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */ + GT_REG_WRITE (GALMPSC_MCONF_LOW + (mpsc * GALMPSC_REG_GAP), + 0x000004c4); + + /* Main config reg High (32x Rx/Tx clock mode, width=8bits */ + GT_REG_WRITE (GALMPSC_MCONF_HIGH + (mpsc * GALMPSC_REG_GAP), + 0x024003f8); + /* 22 2222 1111 */ + /* 54 3210 9876 */ + /* 0000 0010 0000 0000 */ + /* 1 */ + /* 098 7654 3210 */ + /* 0000 0011 1111 1000 */ + } else + return -1; + + return 0; +} + +static int galmpsc_config_channel_regs (int mpsc) +{ + GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_3 + (mpsc * GALMPSC_REG_GAP), 1); + GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_6 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_7 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_8 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_9 + (mpsc * GALMPSC_REG_GAP), 0); + GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (mpsc * GALMPSC_REG_GAP), 0); + + galmpsc_set_brkcnt (mpsc, 0x3); + galmpsc_set_tcschar (mpsc, 0xab); + + return 0; +} + +static int galmpsc_set_brkcnt (int mpsc, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP)); + temp &= 0x0000FFFF; + temp |= (value << 16); + GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp); + + return 0; +} + +static int galmpsc_set_tcschar (int mpsc, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP)); + temp &= 0xFFFF0000; + temp |= value; + GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp); + + return 0; +} + +static int galmpsc_set_char_length (int mpsc, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP)); + temp &= 0xFFFFCFFF; + temp |= (value << 12); + GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp); + + return 0; +} + +static int galmpsc_set_stop_bit_length (int mpsc, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP)); + temp &= 0xFFFFBFFF; + temp |= (value << 14); + GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp); + + return 0; +} + +static int galmpsc_set_parity (int mpsc, int value) +{ + unsigned int temp; + + temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)); + if (value != -1) { + temp &= 0xFFF3FFF3; + temp |= ((value << 18) | (value << 2)); + temp |= ((value << 17) | (value << 1)); + } else { + temp &= 0xFFF1FFF1; + } + + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp); + + return 0; +} + +static int galmpsc_enter_hunt (int mpsc) +{ + int temp; + + temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)); + temp |= 0x80000000; + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp); + + while (GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)) & + MPSC_ENTER_HUNT) { + udelay (1); + } + return 0; +} + + +static int galmpsc_shutdown (int mpsc) +{ + unsigned int temp; + + /* cause RX abort (clears RX) */ + temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)); + temp |= MPSC_RX_ABORT | MPSC_TX_ABORT; + temp &= ~MPSC_ENTER_HUNT; + GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp); + + GT_REG_WRITE (GALSDMA_0_COM_REG, 0); + GT_REG_WRITE (GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT); + + /* shut down the MPSC */ + GT_REG_WRITE (GALMPSC_MCONF_LOW, 0); + GT_REG_WRITE (GALMPSC_MCONF_HIGH, 0); + GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), 0); + + udelay (100); + + /* shut down the sdma engines. */ + /* reset config to default */ + GT_REG_WRITE (GALSDMA_0_CONF_REG, 0x000000fc); + + udelay (100); + + /* clear the SDMA current and first TX and RX pointers */ + GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR, 0); + GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR, 0); + GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR, 0); + + udelay (100); + + return 0; +} + +static void galsdma_enable_rx (void) +{ + int temp; + + /* Enable RX processing */ + temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF)); + temp |= RX_ENABLE; + GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp); + + galmpsc_enter_hunt (CHANNEL); +} + +static int galmpsc_set_snoop (int mpsc, int value) +{ + int reg = + mpsc ? MPSC_1_ADDRESS_CONTROL_LOW : + MPSC_0_ADDRESS_CONTROL_LOW; + int temp = GTREGREAD (reg); + + if (value) + temp |= (1 << 6) | (1 << 14) | (1 << 22) | (1 << 30); + else + temp &= ~((1 << 6) | (1 << 14) | (1 << 22) | (1 << 30)); + GT_REG_WRITE (reg, temp); + return 0; +} + +/******************************************************************************* +* galsdma_set_mem_space - Set MV64460 IDMA memory decoding map. +* +* DESCRIPTION: +* the MV64460 SDMA has its own address decoding map that is de-coupled +* from the CPU interface address decoding windows. The SDMA channels +* share four address windows. Each region can be individually configured +* by this function by associating it to a target interface and setting +* base and size values. +* +* NOTE!!! +* The size must be in 64Kbyte granularity. +* The base address must be aligned to the size. +* The size must be a series of 1s followed by a series of zeros +* +* OUTPUT: +* None. +* +* RETURN: +* True for success, false otherwise. +* +*******************************************************************************/ + +static int galsdma_set_mem_space (unsigned int memSpace, + unsigned int memSpaceTarget, + unsigned int memSpaceAttr, + unsigned int baseAddress, unsigned int size) +{ + unsigned int temp; + + if (size == 0) { + GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG, + 1 << memSpace); + return true; + } + + /* The base address must be aligned to the size. */ + if (baseAddress % size != 0) { + return false; + } + if (size < 0x10000) { + return false; + } + + /* Align size and base to 64K */ + baseAddress &= 0xffff0000; + size &= 0xffff0000; + temp = size >> 16; + + /* Checking that the size is a sequence of '1' followed by a + sequence of '0' starting from LSB to MSB. */ + while ((temp > 0) && (temp & 0x1)) { + temp = temp >> 1; + } + + if (temp != 0) { + GT_REG_WRITE (MV64460_CUNIT_BASE_ADDR_REG0 + memSpace * 8, + (baseAddress | memSpaceTarget | memSpaceAttr)); + GT_REG_WRITE ((MV64460_CUNIT_SIZE0 + memSpace * 8), + (size - 1) & 0xffff0000); + GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG, + 1 << memSpace); + } else { + /* An invalid size was specified */ + return false; + } + return true; +} diff --git a/board/prodrive/p3mx/mpsc.h b/board/prodrive/p3mx/mpsc.h new file mode 100644 index 0000000..a03d1cc --- /dev/null +++ b/board/prodrive/p3mx/mpsc.h @@ -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__ */ diff --git a/board/prodrive/p3mx/mv_eth.c b/board/prodrive/p3mx/mv_eth.c new file mode 100644 index 0000000..8203b3c --- /dev/null +++ b/board/prodrive/p3mx/mv_eth.c @@ -0,0 +1,3344 @@ +/* + * (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 + 3 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.c - header file for the polled mode GT ethernet driver + */ +#include <common.h> +#include <net.h> +#include <malloc.h> +#include <miiphy.h> + +#include "mv_eth.h" + +/* enable Debug outputs */ + +#undef DEBUG_MV_ETH + +#ifdef DEBUG_MV_ETH +#define DEBUG +#define DP(x) x +#else +#define DP(x) +#endif + +/* PHY DFCDL Registers */ +#define ETH_PHY_DFCDL_CONFIG0_REG 0x2100 +#define ETH_PHY_DFCDL_CONFIG1_REG 0x2104 +#define ETH_PHY_DFCDL_ADDR_REG 0x2110 +#define ETH_PHY_DFCDL_DATA0_REG 0x2114 + +#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */ +#define PHY_UPDATE_TIMEOUT 10000 + +#undef MV64460_CHECKSUM_OFFLOAD +/************************************************************************* +* The first part is the high level driver of the gigE ethernet ports. * +*************************************************************************/ + +/* Definition for configuring driver */ +/* #define UPDATE_STATS_BY_SOFTWARE */ +#undef MV64460_RX_QUEUE_FILL_ON_TASK + +/* Constants */ +#define MAGIC_ETH_RUNNING 8031971 +#define MV64460_INTERNAL_SRAM_SIZE _256K +#define EXTRA_BYTES 32 +#define WRAP ETH_HLEN + 2 + 4 + 16 +#define BUFFER_MTU dev->mtu + WRAP +#define INT_CAUSE_UNMASK_ALL 0x0007ffff +#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff +#ifdef MV64460_RX_FILL_ON_TASK +#define INT_CAUSE_MASK_ALL 0x00000000 +#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL +#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT +#endif + +/* Read/Write to/from MV64460 internal registers */ +#define MV_REG_READ(offset) my_le32_to_cpu(* (volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset)) +#define MV_REG_WRITE(offset,data) *(volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset) = my_cpu_to_le32 (data) +#define MV_SET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) |= ((unsigned int)my_cpu_to_le32(bits))) +#define MV_RESET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) &= ~((unsigned int)my_cpu_to_le32(bits))) + +#define my_cpu_to_le32(x) my_le32_to_cpu((x)) + +/* Static function declarations */ +static int mv64460_eth_real_open (struct eth_device *eth); +static int mv64460_eth_real_stop (struct eth_device *eth); +static struct net_device_stats *mv64460_eth_get_stats (struct eth_device + *dev); +static void eth_port_init_mac_tables (ETH_PORT eth_port_num); +static void mv64460_eth_update_stat (struct eth_device *dev); +bool db64460_eth_start (struct eth_device *eth); +unsigned int eth_read_mib_counter (ETH_PORT eth_port_num, + unsigned int mib_offset); +int mv64460_eth_receive (struct eth_device *dev); + +int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length); + +int mv_miiphy_read(char *devname, unsigned char phy_addr, + unsigned char phy_reg, unsigned short *value); +int mv_miiphy_write(char *devname, unsigned char phy_addr, + unsigned char phy_reg, unsigned short value); + +int phy_setup_aneg (char *devname, unsigned char addr); + +#ifndef UPDATE_STATS_BY_SOFTWARE +static void mv64460_eth_print_stat (struct eth_device *dev); +#endif +/* Processes a received packet */ +extern void NetReceive (volatile uchar *, int); + +extern unsigned int INTERNAL_REG_BASE_ADDR; + +unsigned long my_le32_to_cpu (unsigned long x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24)); +} + +/************************************************* + *Helper functions - used inside the driver only * + *************************************************/ +#ifdef DEBUG_MV_ETH +void print_globals (struct eth_device *dev) +{ + printf ("Ethernet PRINT_Globals-Debug function\n"); + printf ("Base Address for ETH_PORT_INFO: %08x\n", + (unsigned int) dev->priv); + printf ("Base Address for mv64460_eth_priv: %08x\n", + (unsigned int) &(((ETH_PORT_INFO *) dev->priv)-> + port_private)); + + printf ("GT Internal Base Address: %08x\n", + INTERNAL_REG_BASE_ADDR); + printf ("Base Address for TX-DESCs: %08x Number of allocated Buffers %d\n", + (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE); + printf ("Base Address for RX-DESCs: %08x Number of allocated Buffers %d\n", + (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE); + printf ("Base Address for RX-Buffer: %08x allocated Bytes %d\n", + (unsigned int) ((ETH_PORT_INFO *) dev->priv)-> + p_rx_buffer_base[0], + (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32); + printf ("Base Address for TX-Buffer: %08x allocated Bytes %d\n", + (unsigned int) ((ETH_PORT_INFO *) dev->priv)-> + p_tx_buffer_base[0], + (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32); +} +#endif + +/********************************************************************** + * mv64460_eth_print_phy_status + * + * Prints gigabit ethenret phy status + * + * Input : pointer to ethernet interface network device structure + * Output : N/A + **********************************************************************/ +void mv64460_eth_print_phy_status (struct eth_device *dev) +{ + struct mv64460_eth_priv *port_private; + unsigned int port_num; + ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv; + unsigned int port_status, phy_reg_data; + + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + /* Check Link status on phy */ + eth_port_read_smi_reg (port_num, 1, &phy_reg_data); + if (!(phy_reg_data & 0x20)) { + printf ("Ethernet port changed link status to DOWN\n"); + } else { + port_status = + MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num)); + printf ("Ethernet status port %d: Link up", port_num); + printf (", %s", + (port_status & BIT2) ? "Full Duplex" : "Half Duplex"); + if (port_status & BIT4) + printf (", Speed 1 Gbps"); + else + printf (", %s", + (port_status & BIT5) ? "Speed 100 Mbps" : + "Speed 10 Mbps"); + printf ("\n"); + } +} + +/********************************************************************** + * u-boot entry functions for mv64460_eth + * + **********************************************************************/ +int db64460_eth_probe (struct eth_device *dev) +{ + return ((int) db64460_eth_start (dev)); +} + +int db64460_eth_poll (struct eth_device *dev) +{ + return mv64460_eth_receive (dev); +} + +int db64460_eth_transmit (struct eth_device *dev, volatile void *packet, + int length) +{ + mv64460_eth_xmit (dev, packet, length); + return 0; +} + +void db64460_eth_disable (struct eth_device *dev) +{ + mv64460_eth_stop (dev); +} + +#define DFCDL(write,read) ((write << 6) | read) +unsigned int ethDfcdls[] = { + DFCDL(0,0), DFCDL(1,1), DFCDL(2,2), DFCDL(3,3), + DFCDL(4,4), DFCDL(5,5), DFCDL(6,6), DFCDL(7,7), + DFCDL(8,8), DFCDL(9,9), DFCDL(10,10), DFCDL(11,11), + DFCDL(12,12), DFCDL(13,13), DFCDL(14,14), DFCDL(15,15), + DFCDL(16,16), DFCDL(17,17), DFCDL(18,18), DFCDL(19,19), + DFCDL(20,20), DFCDL(21,21), DFCDL(22,22), DFCDL(23,23), + DFCDL(24,24), DFCDL(25,25), DFCDL(26,26), DFCDL(27,27), + DFCDL(28,28), DFCDL(29,29), DFCDL(30,30), DFCDL(31,31), + DFCDL(32,32), DFCDL(33,33), DFCDL(34,34), DFCDL(35,35), + DFCDL(36,36), DFCDL(37,37), DFCDL(38,38), DFCDL(39,39), + DFCDL(40,40), DFCDL(41,41), DFCDL(42,42), DFCDL(43,43), + DFCDL(44,44), DFCDL(45,45), DFCDL(46,46), DFCDL(47,47), + DFCDL(48,48), DFCDL(49,49), DFCDL(50,50), DFCDL(51,51), + DFCDL(52,52), DFCDL(53,53), DFCDL(54,54), DFCDL(55,55), + DFCDL(56,56), DFCDL(57,57), DFCDL(58,58), DFCDL(59,59), + DFCDL(60,60), DFCDL(61,61), DFCDL(62,62), DFCDL(63,63), +}; + +void mv_eth_phy_init (void) +{ + int i; + + MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0); + + for (i = 0; i < 64; i++) { + MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]); + } + + MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000); +} + +void mv6446x_eth_initialize (bd_t * bis) +{ + struct eth_device *dev; + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + int devnum, x, temp; + char *s, *e, buf[64]; + + /* P3M750 only + * Set RGMII clock drives strength + */ + temp = MV_REG_READ(0x20A0); + temp |= 0x04000080; + MV_REG_WRITE(0x20A0, temp); + + mv_eth_phy_init(); + + for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) { + dev = calloc (sizeof (*dev), 1); + if (!dev) { + printf ("%s: mv_enet%d allocation failure, %s\n", + __FUNCTION__, devnum, "eth_device structure"); + return; + } + + /* must be less than NAMESIZE (16) */ + sprintf (dev->name, "mv_enet%d", devnum); + +#ifdef DEBUG + printf ("Initializing %s\n", dev->name); +#endif + + /* Extract the MAC address from the environment */ + switch (devnum) { + case 0: + s = "ethaddr"; + break; + case 1: + s = "eth1addr"; + break; + case 2: + s = "eth2addr"; + break; + default: /* this should never happen */ + printf ("%s: Invalid device number %d\n", + __FUNCTION__, devnum); + return; + } + + temp = getenv_r (s, buf, sizeof (buf)); + s = (temp > 0) ? buf : NULL; + +#ifdef DEBUG + printf ("Setting MAC %d to %s\n", devnum, s); +#endif + for (x = 0; x < 6; ++x) { + dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + /* ronen - set the MAC addr in the HW */ + eth_port_uc_addr_set (devnum, dev->enetaddr, 0); + + dev->init = (void *) db64460_eth_probe; + dev->halt = (void *) ethernet_phy_reset; + dev->send = (void *) db64460_eth_transmit; + dev->recv = (void *) db64460_eth_poll; + + ethernet_private = calloc (sizeof (*ethernet_private), 1); + dev->priv = (void *)ethernet_private; + if (!ethernet_private) { + printf ("%s: %s allocation failure, %s\n", + __FUNCTION__, dev->name, + "Private Device Structure"); + free (dev); + return; + } + /* start with an zeroed ETH_PORT_INFO */ + memset (ethernet_private, 0, sizeof (ETH_PORT_INFO)); + memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6); + + /* set pointer to memory for stats data structure etc... */ + port_private = calloc (sizeof (*ethernet_private), 1); + ethernet_private->port_private = (void *)port_private; + if (!port_private) { + printf ("%s: %s allocation failure, %s\n", + __FUNCTION__, dev->name, + "Port Private Device Structure"); + + free (ethernet_private); + free (dev); + return; + } + + port_private->stats = + calloc (sizeof (struct net_device_stats), 1); + if (!port_private->stats) { + printf ("%s: %s allocation failure, %s\n", + __FUNCTION__, dev->name, + "Net stat Structure"); + + free (port_private); + free (ethernet_private); + free (dev); + return; + } + memset (ethernet_private->port_private, 0, + sizeof (struct mv64460_eth_priv)); + switch (devnum) { + case 0: + ethernet_private->port_num = ETH_0; + break; + case 1: + ethernet_private->port_num = ETH_1; + break; + case 2: + ethernet_private->port_num = ETH_2; + break; + default: + printf ("Invalid device number %d\n", devnum); + break; + }; + + port_private->port_num = devnum; + /* + * Read MIB counter on the GT in order to reset them, + * then zero all the stats fields in memory + */ + mv64460_eth_update_stat (dev); + memset (port_private->stats, 0, + sizeof (struct net_device_stats)); + /* Extract the MAC address from the environment */ + switch (devnum) { + case 0: + s = "ethaddr"; + break; + case 1: + s = "eth1addr"; + break; + case 2: + s = "eth2addr"; + break; + default: /* this should never happen */ + printf ("%s: Invalid device number %d\n", + __FUNCTION__, devnum); + return; + } + + temp = getenv_r (s, buf, sizeof (buf)); + s = (temp > 0) ? buf : NULL; + +#ifdef DEBUG + printf ("Setting MAC %d to %s\n", devnum, s); +#endif + for (x = 0; x < 6; ++x) { + dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + + DP (printf ("Allocating descriptor and buffer rings\n")); + + ethernet_private->p_rx_desc_area_base[0] = + (ETH_RX_DESC *) memalign (16, + RX_DESC_ALIGNED_SIZE * + MV64460_RX_QUEUE_SIZE + 1); + ethernet_private->p_tx_desc_area_base[0] = + (ETH_TX_DESC *) memalign (16, + TX_DESC_ALIGNED_SIZE * + MV64460_TX_QUEUE_SIZE + 1); + + ethernet_private->p_rx_buffer_base[0] = + (char *) memalign (16, + MV64460_RX_QUEUE_SIZE * + MV64460_TX_BUFFER_SIZE + 1); + ethernet_private->p_tx_buffer_base[0] = + (char *) memalign (16, + MV64460_RX_QUEUE_SIZE * + MV64460_TX_BUFFER_SIZE + 1); + +#ifdef DEBUG_MV_ETH + /* DEBUG OUTPUT prints adresses of globals */ + print_globals (dev); +#endif + eth_register (dev); + + miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write); + } + DP (printf ("%s: exit\n", __FUNCTION__)); + +} + +/********************************************************************** + * mv64460_eth_open + * + * This function is called when openning the network device. The function + * should initialize all the hardware, initialize cyclic Rx/Tx + * descriptors chain and buffers and allocate an IRQ to the network + * device. + * + * Input : a pointer to the network device structure + * / / ronen - changed the output to match net/eth.c needs + * Output : nonzero of success , zero if fails. + * under construction + **********************************************************************/ + +int mv64460_eth_open (struct eth_device *dev) +{ + return (mv64460_eth_real_open (dev)); +} + +/* Helper function for mv64460_eth_open */ +static int mv64460_eth_real_open (struct eth_device *dev) +{ + + unsigned int queue; + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + u32 port_status; + ushort reg_short; + int speed; + int duplex; + int i; + int reg; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + /* ronen - when we update the MAC env params we only update dev->enetaddr + see ./net/eth.c eth_set_enetaddr() */ + memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6); + + port_private = (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + /* Stop RX Queues */ + MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00); + + /* Clear the ethernet port interrupts */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0); + MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0); + + /* Unmask RX buffer and TX end interrupt */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), + INT_CAUSE_UNMASK_ALL); + + /* Unmask phy and link status changes interrupts */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), + INT_CAUSE_UNMASK_ALL_EXT); + + /* Set phy address of the port */ + ethernet_private->port_phy_addr = 0x1 + (port_num << 1); + reg = ethernet_private->port_phy_addr; + + /* Activate the DMA channels etc */ + eth_port_init (ethernet_private); + + /* "Allocate" setup TX rings */ + + for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) { + unsigned int size; + + port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE; + size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE); /*size = no of DESCs times DESC-size */ + ethernet_private->tx_desc_area_size[queue] = size; + + /* first clear desc area completely */ + memset ((void *) ethernet_private->p_tx_desc_area_base[queue], + 0, ethernet_private->tx_desc_area_size[queue]); + + /* initialize tx desc ring with low level driver */ + if (ether_init_tx_desc_ring + (ethernet_private, ETH_Q0, + port_private->tx_ring_size[queue], + MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ , + (unsigned int) ethernet_private-> + p_tx_desc_area_base[queue], + (unsigned int) ethernet_private-> + p_tx_buffer_base[queue]) == false) + printf ("### Error initializing TX Ring\n"); + } + + /* "Allocate" setup RX rings */ + for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) { + unsigned int size; + + /* Meantime RX Ring are fixed - but must be configurable by user */ + port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE; + size = (port_private->rx_ring_size[queue] * + RX_DESC_ALIGNED_SIZE); + ethernet_private->rx_desc_area_size[queue] = size; + + /* first clear desc area completely */ + memset ((void *) ethernet_private->p_rx_desc_area_base[queue], + 0, ethernet_private->rx_desc_area_size[queue]); + if ((ether_init_rx_desc_ring + (ethernet_private, ETH_Q0, + port_private->rx_ring_size[queue], + MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ , + (unsigned int) ethernet_private-> + p_rx_desc_area_base[queue], + (unsigned int) ethernet_private-> + p_rx_buffer_base[queue])) == false) + printf ("### Error initializing RX Ring\n"); + } + + eth_port_start (ethernet_private); + + /* Set maximum receive buffer to 9700 bytes */ + MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num), + (0x5 << 17) | + (MV_REG_READ + (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num)) + & 0xfff1ffff)); + + /* + * Set ethernet MTU for leaky bucket mechanism to 0 - this will + * disable the leaky bucket mechanism . + */ + + MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0); + port_status = MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num)); + +#if defined(CONFIG_PHY_RESET) + /* + * Reset the phy, only if its the first time through + * otherwise, just check the speeds & feeds + */ + if (port_private->first_init == 0) { + port_private->first_init = 1; + ethernet_phy_reset (port_num); + + /* Start/Restart autonegotiation */ + phy_setup_aneg (dev->name, reg); + udelay (1000); + } +#endif /* defined(CONFIG_PHY_RESET) */ + + miiphy_read (dev->name, reg, PHY_BMSR, ®_short); + + /* + * Wait if PHY is capable of autonegotiation and autonegotiation is not complete + */ + if ((reg_short & PHY_BMSR_AUTN_ABLE) + && !(reg_short & PHY_BMSR_AUTN_COMP)) { + puts ("Waiting for PHY auto negotiation to complete"); + i = 0; + while (!(reg_short & PHY_BMSR_AUTN_COMP)) { + /* + * Timeout reached ? + */ + if (i > PHY_AUTONEGOTIATE_TIMEOUT) { + puts (" TIMEOUT !\n"); + break; + } + + if ((i++ % 1000) == 0) { + putc ('.'); + } + udelay (1000); /* 1 ms */ + miiphy_read (dev->name, reg, PHY_BMSR, ®_short); + + } + puts (" done\n"); + udelay (500000); /* another 500 ms (results in faster booting) */ + } + + speed = miiphy_speed (dev->name, reg); + duplex = miiphy_duplex (dev->name, reg); + + printf ("ENET Speed is %d Mbps - %s duplex connection\n", + (int) speed, (duplex == HALF) ? "HALF" : "FULL"); + + port_private->eth_running = MAGIC_ETH_RUNNING; + return 1; +} + +static int mv64460_eth_free_tx_rings (struct eth_device *dev) +{ + unsigned int queue; + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + volatile ETH_TX_DESC *p_tx_curr_desc; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + /* Stop Tx Queues */ + MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num), + 0x0000ff00); + + /* Free TX rings */ + DP (printf ("Clearing previously allocated TX queues... ")); + for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) { + /* Free on TX rings */ + for (p_tx_curr_desc = + ethernet_private->p_tx_desc_area_base[queue]; + ((unsigned int) p_tx_curr_desc <= (unsigned int) + ethernet_private->p_tx_desc_area_base[queue] + + ethernet_private->tx_desc_area_size[queue]); + p_tx_curr_desc = + (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc + + TX_DESC_ALIGNED_SIZE)) { + /* this is inside for loop */ + if (p_tx_curr_desc->return_info != 0) { + p_tx_curr_desc->return_info = 0; + DP (printf ("freed\n")); + } + } + DP (printf ("Done\n")); + } + return 0; +} + +static int mv64460_eth_free_rx_rings (struct eth_device *dev) +{ + unsigned int queue; + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + volatile ETH_RX_DESC *p_rx_curr_desc; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + /* Stop RX Queues */ + MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), + 0x0000ff00); + + /* Free RX rings */ + DP (printf ("Clearing previously allocated RX queues... ")); + for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) { + /* Free preallocated skb's on RX rings */ + for (p_rx_curr_desc = + ethernet_private->p_rx_desc_area_base[queue]; + (((unsigned int) p_rx_curr_desc < + ((unsigned int) ethernet_private-> + p_rx_desc_area_base[queue] + + ethernet_private->rx_desc_area_size[queue]))); + p_rx_curr_desc = + (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc + + RX_DESC_ALIGNED_SIZE)) { + if (p_rx_curr_desc->return_info != 0) { + p_rx_curr_desc->return_info = 0; + DP (printf ("freed\n")); + } + } + DP (printf ("Done\n")); + } + return 0; +} + +/********************************************************************** + * mv64460_eth_stop + * + * This function is used when closing the network device. + * It updates the hardware, + * release all memory that holds buffers and descriptors and release the IRQ. + * Input : a pointer to the device structure + * Output : zero if success , nonzero if fails + *********************************************************************/ + +int mv64460_eth_stop (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + /* Disable all gigE address decoder */ + MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f); + DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__)); + mv64460_eth_real_stop (dev); + + return 0; +}; + +/* Helper function for mv64460_eth_stop */ + +static int mv64460_eth_real_stop (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + mv64460_eth_free_tx_rings (dev); + mv64460_eth_free_rx_rings (dev); + + eth_port_reset (ethernet_private->port_num); + /* Disable ethernet port interrupts */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0); + MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0); + /* Mask RX buffer and TX end interrupt */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0); + /* Mask phy and link status changes interrupts */ + MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0); + MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH, + BIT0 << port_num); + /* Print Network statistics */ +#ifndef UPDATE_STATS_BY_SOFTWARE + /* + * Print statistics (only if ethernet is running), + * then zero all the stats fields in memory + */ + if (port_private->eth_running == MAGIC_ETH_RUNNING) { + port_private->eth_running = 0; + mv64460_eth_print_stat (dev); + } + memset (port_private->stats, 0, sizeof (struct net_device_stats)); +#endif + DP (printf ("\nEthernet stopped ... \n")); + return 0; +} + +/********************************************************************** + * mv64460_eth_start_xmit + * + * This function is queues a packet in the Tx descriptor for + * required port. + * + * Input : skb - a pointer to socket buffer + * dev - a pointer to the required port + * + * Output : zero upon success + **********************************************************************/ + +int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr, + int dataSize) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + PKT_INFO pkt_info; + ETH_FUNC_RET_STATUS status; + struct net_device_stats *stats; + ETH_FUNC_RET_STATUS release_result; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + stats = port_private->stats; + + /* Update packet info data structure */ + pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; /* DMA owned, first last */ + pkt_info.byte_cnt = dataSize; + pkt_info.buf_ptr = (unsigned int) dataPtr; + pkt_info.return_info = 0; + + status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info); + if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) { + printf ("Error on transmitting packet .."); + if (status == ETH_QUEUE_FULL) + printf ("ETH Queue is full. \n"); + if (status == ETH_QUEUE_LAST_RESOURCE) + printf ("ETH Queue: using last available resource. \n"); + return 1; + } + + /* Update statistics and start of transmittion time */ + stats->tx_bytes += dataSize; + stats->tx_packets++; + + /* Check if packet(s) is(are) transmitted correctly (release everything) */ + do { + release_result = + eth_tx_return_desc (ethernet_private, ETH_Q0, + &pkt_info); + switch (release_result) { + case ETH_OK: + DP (printf ("descriptor released\n")); + if (pkt_info.cmd_sts & BIT0) { + printf ("Error in TX\n"); + stats->tx_errors++; + } + break; + case ETH_RETRY: + DP (printf ("transmission still in process\n")); + break; + + case ETH_ERROR: + printf ("routine can not access Tx desc ring\n"); + break; + + case ETH_END_OF_JOB: + DP (printf ("the routine has nothing to release\n")); + break; + default: /* should not happen */ + break; + } + } while (release_result == ETH_OK); + + return 0; /* success */ +} + +/********************************************************************** + * mv64460_eth_receive + * + * This function is forward packets that are received from the port's + * queues toward kernel core or FastRoute them to another interface. + * + * Input : dev - a pointer to the required interface + * max - maximum number to receive (0 means unlimted) + * + * Output : number of served packets + **********************************************************************/ + +int mv64460_eth_receive (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + PKT_INFO pkt_info; + struct net_device_stats *stats; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + stats = port_private->stats; + + while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) == ETH_OK)) { +#ifdef DEBUG_MV_ETH + if (pkt_info.byte_cnt != 0) { + printf ("%s: Received %d byte Packet @ 0x%x\n", + __FUNCTION__, pkt_info.byte_cnt, + pkt_info.buf_ptr); + if(pkt_info.buf_ptr != 0){ + for(i=0; i < pkt_info.byte_cnt; i++){ + if((i % 4) == 0){ + printf("\n0x"); + } + printf("%02x", ((char*)pkt_info.buf_ptr)[i]); + } + printf("\n"); + } + } +#endif + /* Update statistics. Note byte count includes 4 byte CRC count */ + stats->rx_packets++; + stats->rx_bytes += pkt_info.byte_cnt; + + /* + * In case received a packet without first / last bits on OR the error + * summary bit is on, the packets needs to be dropeed. + */ + if (((pkt_info. + cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) != + (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) + || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) { + stats->rx_dropped++; + + printf ("Received packet spread on multiple descriptors\n"); + + /* Is this caused by an error ? */ + if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) { + stats->rx_errors++; + } + + /* free these descriptors again without forwarding them to the higher layers */ + pkt_info.buf_ptr &= ~0x7; /* realign buffer again */ + pkt_info.byte_cnt = 0x0000; /* Reset Byte count */ + + if (eth_rx_return_buff + (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) { + printf ("Error while returning the RX Desc to Ring\n"); + } else { + DP (printf ("RX Desc returned to Ring\n")); + } + /* /free these descriptors again */ + } else { + +/* !!! call higher layer processing */ +#ifdef DEBUG_MV_ETH + printf ("\nNow send it to upper layer protocols (NetReceive) ...\n"); +#endif + /* let the upper layer handle the packet */ + NetReceive ((uchar *) pkt_info.buf_ptr, + (int) pkt_info.byte_cnt); + +/* **************************************************************** */ +/* free descriptor */ + pkt_info.buf_ptr &= ~0x7; /* realign buffer again */ + pkt_info.byte_cnt = 0x0000; /* Reset Byte count */ + DP (printf ("RX: pkt_info.buf_ptr = %x\n", pkt_info.buf_ptr)); + if (eth_rx_return_buff + (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) { + printf ("Error while returning the RX Desc to Ring\n"); + } else { + DP (printf ("RX: Desc returned to Ring\n")); + } + +/* **************************************************************** */ + + } + } + mv64460_eth_get_stats (dev); /* update statistics */ + return 1; +} + +/********************************************************************** + * mv64460_eth_get_stats + * + * Returns a pointer to the interface statistics. + * + * Input : dev - a pointer to the required interface + * + * Output : a pointer to the interface's statistics + **********************************************************************/ + +static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + unsigned int port_num; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + + mv64460_eth_update_stat (dev); + + return port_private->stats; +} + +/********************************************************************** + * mv64460_eth_update_stat + * + * Update the statistics structure in the private data structure + * + * Input : pointer to ethernet interface network device structure + * Output : N/A + **********************************************************************/ + +static void mv64460_eth_update_stat (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + struct net_device_stats *stats; + unsigned int port_num; + volatile unsigned int dummy; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + stats = port_private->stats; + + /* These are false updates */ + stats->rx_packets += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_FRAMES_RECEIVED); + stats->tx_packets += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_FRAMES_SENT); + stats->rx_bytes += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_OCTETS_RECEIVED_LOW); + /* + * Ideally this should be as follows - + * + * stats->rx_bytes += stats->rx_bytes + + * ((unsigned long) ethReadMibCounter (ethernet_private->port_num , + * ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32); + * + * But the unsigned long in PowerPC and MIPS are 32bit. So the next read + * is just a dummy read for proper work of the GigE port + */ + dummy = eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH); + stats->tx_bytes += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_OCTETS_SENT_LOW); + dummy = eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_GOOD_OCTETS_SENT_HIGH); + stats->rx_errors += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_MAC_RECEIVE_ERROR); + + /* Rx dropped is for received packet with CRC error */ + stats->rx_dropped += + (unsigned long) eth_read_mib_counter (ethernet_private-> + port_num, + ETH_MIB_BAD_CRC_EVENT); + stats->multicast += (unsigned long) + eth_read_mib_counter (ethernet_private->port_num, + ETH_MIB_MULTICAST_FRAMES_RECEIVED); + stats->collisions += + (unsigned long) eth_read_mib_counter (ethernet_private-> + port_num, + ETH_MIB_COLLISION) + + (unsigned long) eth_read_mib_counter (ethernet_private-> + port_num, + ETH_MIB_LATE_COLLISION); + /* detailed rx errors */ + stats->rx_length_errors += + (unsigned long) eth_read_mib_counter (ethernet_private-> + port_num, + ETH_MIB_UNDERSIZE_RECEIVED) + + + (unsigned long) eth_read_mib_counter (ethernet_private-> + port_num, + ETH_MIB_OVERSIZE_RECEIVED); + /* detailed tx errors */ +} + +#ifndef UPDATE_STATS_BY_SOFTWARE +/********************************************************************** + * mv64460_eth_print_stat + * + * Update the statistics structure in the private data structure + * + * Input : pointer to ethernet interface network device structure + * Output : N/A + **********************************************************************/ + +static void mv64460_eth_print_stat (struct eth_device *dev) +{ + ETH_PORT_INFO *ethernet_private; + struct mv64460_eth_priv *port_private; + struct net_device_stats *stats; + unsigned int port_num; + + ethernet_private = (ETH_PORT_INFO *) dev->priv; + port_private = + (struct mv64460_eth_priv *) ethernet_private->port_private; + port_num = port_private->port_num; + stats = port_private->stats; + + /* These are false updates */ + printf ("\n### Network statistics: ###\n"); + printf ("--------------------------\n"); + printf (" Packets received: %ld\n", stats->rx_packets); + printf (" Packets send: %ld\n", stats->tx_packets); + printf (" Received bytes: %ld\n", stats->rx_bytes); + printf (" Send bytes: %ld\n", stats->tx_bytes); + if (stats->rx_errors != 0) + printf (" Rx Errors: %ld\n", + stats->rx_errors); + if (stats->rx_dropped != 0) + printf (" Rx dropped (CRC Errors): %ld\n", + stats->rx_dropped); + if (stats->multicast != 0) + printf (" Rx mulicast frames: %ld\n", + stats->multicast); + if (stats->collisions != 0) + printf (" No. of collisions: %ld\n", + stats->collisions); + if (stats->rx_length_errors != 0) + printf (" Rx length errors: %ld\n", + stats->rx_length_errors); +} +#endif + +/************************************************************************** + *network_start - Network Kick Off Routine UBoot + *Inputs : + *Outputs : + **************************************************************************/ + +bool db64460_eth_start (struct eth_device *dev) +{ + return (mv64460_eth_open (dev)); /* calls real open */ +} + +/************************************************************************* +************************************************************************** +************************************************************************** +* The second part is the low level driver of the gigE ethernet ports. * +************************************************************************** +************************************************************************** +*************************************************************************/ +/* + * based on Linux code + * arch/ppc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports + * Copyright (C) 2002 rabeeh@galileo.co.il + + * 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. + * + */ + +/******************************************************************************** + * Marvell's Gigabit Ethernet controller low level driver + * + * DESCRIPTION: + * This file introduce low level API to Marvell's Gigabit Ethernet + * controller. This Gigabit Ethernet Controller driver API controls + * 1) Operations (i.e. port init, start, reset etc'). + * 2) Data flow (i.e. port send, receive etc'). + * Each Gigabit Ethernet port is controlled via ETH_PORT_INFO + * struct. + * This struct includes user configuration information as well as + * driver internal data needed for its operations. + * + * Supported Features: + * - This low level driver is OS independent. Allocating memory for + * the descriptor rings and buffers are not within the scope of + * this driver. + * - The user is free from Rx/Tx queue managing. + * - This low level driver introduce functionality API that enable + * the to operate Marvell's Gigabit Ethernet Controller in a + * convenient way. + * - Simple Gigabit Ethernet port operation API. + * - Simple Gigabit Ethernet port data flow API. + * - Data flow and operation API support per queue functionality. + * - Support cached descriptors for better performance. + * - Enable access to all four DRAM banks and internal SRAM memory + * spaces. + * - PHY access and control API. + * - Port control register configuration API. + * - Full control over Unicast and Multicast MAC configurations. + * + * Operation flow: + * + * Initialization phase + * This phase complete the initialization of the ETH_PORT_INFO + * struct. + * User information regarding port configuration has to be set + * prior to calling the port initialization routine. For example, + * the user has to assign the port_phy_addr field which is board + * depended parameter. + * In this phase any port Tx/Rx activity is halted, MIB counters + * are cleared, PHY address is set according to user parameter and + * access to DRAM and internal SRAM memory spaces. + * + * Driver ring initialization + * Allocating memory for the descriptor rings and buffers is not + * within the scope of this driver. Thus, the user is required to + * allocate memory for the descriptors ring and buffers. Those + * memory parameters are used by the Rx and Tx ring initialization + * routines in order to curve the descriptor linked list in a form + * of a ring. + * Note: Pay special attention to alignment issues when using + * cached descriptors/buffers. In this phase the driver store + * information in the ETH_PORT_INFO struct regarding each queue + * ring. + * + * Driver start + * This phase prepares the Ethernet port for Rx and Tx activity. + * It uses the information stored in the ETH_PORT_INFO struct to + * initialize the various port registers. + * + * Data flow: + * All packet references to/from the driver are done using PKT_INFO + * struct. + * This struct is a unified struct used with Rx and Tx operations. + * This way the user is not required to be familiar with neither + * Tx nor Rx descriptors structures. + * The driver's descriptors rings are management by indexes. + * Those indexes controls the ring resources and used to indicate + * a SW resource error: + * 'current' + * This index points to the current available resource for use. For + * example in Rx process this index will point to the descriptor + * that will be passed to the user upon calling the receive routine. + * In Tx process, this index will point to the descriptor + * that will be assigned with the user packet info and transmitted. + * 'used' + * This index points to the descriptor that need to restore its + * resources. For example in Rx process, using the Rx buffer return + * API will attach the buffer returned in packet info to the + * descriptor pointed by 'used'. In Tx process, using the Tx + * descriptor return will merely return the user packet info with + * the command status of the transmitted buffer pointed by the + * 'used' index. Nevertheless, it is essential to use this routine + * to update the 'used' index. + * 'first' + * This index supports Tx Scatter-Gather. It points to the first + * descriptor of a packet assembled of multiple buffers. For example + * when in middle of Such packet we have a Tx resource error the + * 'curr' index get the value of 'first' to indicate that the ring + * returned to its state before trying to transmit this packet. + * + * Receive operation: + * The eth_port_receive API set the packet information struct, + * passed by the caller, with received information from the + * 'current' SDMA descriptor. + * It is the user responsibility to return this resource back + * to the Rx descriptor ring to enable the reuse of this source. + * Return Rx resource is done using the eth_rx_return_buff API. + * + * Transmit operation: + * The eth_port_send API supports Scatter-Gather which enables to + * send a packet spanned over multiple buffers. This means that + * for each packet info structure given by the user and put into + * the Tx descriptors ring, will be transmitted only if the 'LAST' + * bit will be set in the packet info command status field. This + * API also consider restriction regarding buffer alignments and + * sizes. + * The user must return a Tx resource after ensuring the buffer + * has been transmitted to enable the Tx ring indexes to update. + * + * BOARD LAYOUT + * This device is on-board. No jumper diagram is necessary. + * + * EXTERNAL INTERFACE + * + * Prior to calling the initialization routine eth_port_init() the user + * must set the following fields under ETH_PORT_INFO struct: + * port_num User Ethernet port number. + * port_phy_addr User PHY address of Ethernet port. + * port_mac_addr[6] User defined port MAC address. + * port_config User port configuration value. + * port_config_extend User port config extend value. + * port_sdma_config User port SDMA config value. + * port_serial_control User port serial control value. + * *port_virt_to_phys () User function to cast virtual addr to CPU bus addr. + * *port_private User scratch pad for user specific data structures. + * + * This driver introduce a set of default values: + * PORT_CONFIG_VALUE Default port configuration value + * PORT_CONFIG_EXTEND_VALUE Default port extend configuration value + * PORT_SDMA_CONFIG_VALUE Default sdma control value + * PORT_SERIAL_CONTROL_VALUE Default port serial control value + * + * This driver data flow is done using the PKT_INFO struct which is + * a unified struct for Rx and Tx operations: + * byte_cnt Tx/Rx descriptor buffer byte count. + * l4i_chk CPU provided TCP Checksum. For Tx operation only. + * cmd_sts Tx/Rx descriptor command status. + * buf_ptr Tx/Rx descriptor buffer pointer. + * return_info Tx/Rx user resource return information. + * + * + * EXTERNAL SUPPORT REQUIREMENTS + * + * This driver requires the following external support: + * + * D_CACHE_FLUSH_LINE (address, address offset) + * + * This macro applies assembly code to flush and invalidate cache + * line. + * address - address base. + * address offset - address offset + * + * + * CPU_PIPE_FLUSH + * + * This macro applies assembly code to flush the CPU pipeline. + * + *******************************************************************************/ +/* includes */ + +/* defines */ +/* SDMA command macros */ +#define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \ + MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue)) + +#define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \ + MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\ + (1 << (8 + tx_queue))) + +#define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \ +MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue)) + +#define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \ +MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue))) + +#define CURR_RFD_GET(p_curr_desc, queue) \ + ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue]) + +#define CURR_RFD_SET(p_curr_desc, queue) \ + (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc)) + +#define USED_RFD_GET(p_used_desc, queue) \ + ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue]) + +#define USED_RFD_SET(p_used_desc, queue)\ +(p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc)) + + +#define CURR_TFD_GET(p_curr_desc, queue) \ + ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue]) + +#define CURR_TFD_SET(p_curr_desc, queue) \ + (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc)) + +#define USED_TFD_GET(p_used_desc, queue) \ + ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue]) + +#define USED_TFD_SET(p_used_desc, queue) \ + (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc)) + +#define FIRST_TFD_GET(p_first_desc, queue) \ + ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue]) + +#define FIRST_TFD_SET(p_first_desc, queue) \ + (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc)) + + +/* Macros that save access to desc in order to find next desc pointer */ +#define RX_NEXT_DESC_PTR(p_rx_desc, queue) (ETH_RX_DESC*)(((((unsigned int)p_rx_desc - (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue]) + RX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->rx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue]) + +#define TX_NEXT_DESC_PTR(p_tx_desc, queue) (ETH_TX_DESC*)(((((unsigned int)p_tx_desc - (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue]) + TX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->tx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue]) + +#define LINK_UP_TIMEOUT 100000 +#define PHY_BUSY_TIMEOUT 10000000 + +/* locals */ + +/* PHY routines */ +static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr); +static int ethernet_phy_get (ETH_PORT eth_port_num); + +/* Ethernet Port routines */ +static void eth_set_access_control (ETH_PORT eth_port_num, + ETH_WIN_PARAM * param); +static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble, + ETH_QUEUE queue, int option); +#if 0 /* FIXME */ +static bool eth_port_smc_addr (ETH_PORT eth_port_num, + unsigned char mc_byte, + ETH_QUEUE queue, int option); +static bool eth_port_omc_addr (ETH_PORT eth_port_num, + unsigned char crc8, + ETH_QUEUE queue, int option); +#endif + +static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr, + int byte_count); + +void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl); + + +typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK; +u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank) +{ + u32 result = 0; + u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE); + + if (enable & (1 << bank)) + return 0; + if (bank == BANK0) + result = MV_REG_READ (MV64460_CS_0_BASE_ADDR); + if (bank == BANK1) + result = MV_REG_READ (MV64460_CS_1_BASE_ADDR); + if (bank == BANK2) + result = MV_REG_READ (MV64460_CS_2_BASE_ADDR); + if (bank == BANK3) + result = MV_REG_READ (MV64460_CS_3_BASE_ADDR); + result &= 0x0000ffff; + result = result << 16; + return result; +} + +u32 mv_get_dram_bank_size (MEMORY_BANK bank) +{ + u32 result = 0; + u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE); + + if (enable & (1 << bank)) + return 0; + if (bank == BANK0) + result = MV_REG_READ (MV64460_CS_0_SIZE); + if (bank == BANK1) + result = MV_REG_READ (MV64460_CS_1_SIZE); + if (bank == BANK2) + result = MV_REG_READ (MV64460_CS_2_SIZE); + if (bank == BANK3) + result = MV_REG_READ (MV64460_CS_3_SIZE); + result += 1; + result &= 0x0000ffff; + result = result << 16; + return result; +} + +u32 mv_get_internal_sram_base (void) +{ + u32 result; + + result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR); + result &= 0x0000ffff; + result = result << 16; + return result; +} + +/******************************************************************************* +* eth_port_init - Initialize the Ethernet port driver +* +* DESCRIPTION: +* This function prepares the ethernet port to start its activity: +* 1) Completes the ethernet port driver struct initialization toward port +* start routine. +* 2) Resets the device to a quiescent state in case of warm reboot. +* 3) Enable SDMA access to all four DRAM banks as well as internal SRAM. +* 4) Clean MAC tables. The reset status of those tables is unknown. +* 5) Set PHY address. +* Note: Call this routine prior to eth_port_start routine and after setting +* user values in the user fields of Ethernet port control struct (i.e. +* port_phy_addr). +* +* INPUT: +* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct +* +* OUTPUT: +* See description. +* +* RETURN: +* None. +* +*******************************************************************************/ +static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl) +{ + int queue; + ETH_WIN_PARAM win_param; + + p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE; + p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE; + p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE; + p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE; + + p_eth_port_ctrl->port_rx_queue_command = 0; + p_eth_port_ctrl->port_tx_queue_command = 0; + + /* Zero out SW structs */ + for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) { + CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue); + USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue); + p_eth_port_ctrl->rx_resource_err[queue] = false; + } + + for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) { + CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue); + USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue); + FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue); + p_eth_port_ctrl->tx_resource_err[queue] = false; + } + + eth_port_reset (p_eth_port_ctrl->port_num); + + /* Set access parameters for DRAM bank 0 */ + win_param.win = ETH_WIN0; /* Use Ethernet window 0 */ + win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */ + win_param.attributes = EBAR_ATTR_DRAM_CS0; /* Enable DRAM bank */ +#ifndef CONFIG_NOT_COHERENT_CACHE + win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB; +#endif + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = mv_get_dram_bank_base_addr (BANK0); + win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */ + + /* Set the access control for address window (EPAPR) READ & WRITE */ + eth_set_access_control (p_eth_port_ctrl->port_num, &win_param); + + /* Set access parameters for DRAM bank 1 */ + win_param.win = ETH_WIN1; /* Use Ethernet window 1 */ + win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */ + win_param.attributes = EBAR_ATTR_DRAM_CS1; /* Enable DRAM bank */ +#ifndef CONFIG_NOT_COHERENT_CACHE + win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB; +#endif + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = mv_get_dram_bank_base_addr (BANK1); + win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */ + + /* Set the access control for address window (EPAPR) READ & WRITE */ + eth_set_access_control (p_eth_port_ctrl->port_num, &win_param); + + /* Set access parameters for DRAM bank 2 */ + win_param.win = ETH_WIN2; /* Use Ethernet window 2 */ + win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */ + win_param.attributes = EBAR_ATTR_DRAM_CS2; /* Enable DRAM bank */ +#ifndef CONFIG_NOT_COHERENT_CACHE + win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB; +#endif + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = mv_get_dram_bank_base_addr (BANK2); + win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */ + + /* Set the access control for address window (EPAPR) READ & WRITE */ + eth_set_access_control (p_eth_port_ctrl->port_num, &win_param); + + /* Set access parameters for DRAM bank 3 */ + win_param.win = ETH_WIN3; /* Use Ethernet window 3 */ + win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */ + win_param.attributes = EBAR_ATTR_DRAM_CS3; /* Enable DRAM bank */ +#ifndef CONFIG_NOT_COHERENT_CACHE + win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB; +#endif + win_param.high_addr = 0; + /* Get bank base */ + win_param.base_addr = mv_get_dram_bank_base_addr (BANK3); + win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */ + if (win_param.size == 0) + win_param.enable = 0; + else + win_param.enable = 1; /* Enable the access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */ + + /* Set the access control for address window (EPAPR) READ & WRITE */ + eth_set_access_control (p_eth_port_ctrl->port_num, &win_param); + + /* Set access parameters for Internal SRAM */ + win_param.win = ETH_WIN4; /* Use Ethernet window 0 */ + win_param.target = EBAR_TARGET_CBS; /* Target - Internal SRAM */ + win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0; + win_param.high_addr = 0; + win_param.base_addr = mv_get_internal_sram_base (); /* Get base addr */ + win_param.size = MV64460_INTERNAL_SRAM_SIZE; /* Get bank size */ + win_param.enable = 1; /* Enable the access */ + win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */ + + /* Set the access control for address window (EPAPR) READ & WRITE */ + eth_set_access_control (p_eth_port_ctrl->port_num, &win_param); + + eth_port_init_mac_tables (p_eth_port_ctrl->port_num); + + ethernet_phy_set (p_eth_port_ctrl->port_num, + p_eth_port_ctrl->port_phy_addr); + + return; + +} + +/******************************************************************************* +* eth_port_start - Start the Ethernet port activity. +* +* DESCRIPTION: +* This routine prepares the Ethernet port for Rx and Tx activity: +* 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that +* has been initialized a descriptor's ring (using ether_init_tx_desc_ring +* for Tx and ether_init_rx_desc_ring for Rx) +* 2. Initialize and enable the Ethernet configuration port by writing to +* the port's configuration and command registers. +* 3. Initialize and enable the SDMA by writing to the SDMA's +* configuration and command registers. +* After completing these steps, the ethernet port SDMA can starts to +* perform Rx and Tx activities. +* +* Note: Each Rx and Tx queue descriptor's list must be initialized prior +* to calling this function (use ether_init_tx_desc_ring for Tx queues and +* ether_init_rx_desc_ring for Rx queues). +* +* INPUT: +* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct +* +* OUTPUT: +* Ethernet port is ready to receive and transmit. +* +* RETURN: +* false if the port PHY is not up. +* true otherwise. +* +*******************************************************************************/ +static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl) +{ + int queue; + volatile ETH_TX_DESC *p_tx_curr_desc; + volatile ETH_RX_DESC *p_rx_curr_desc; + unsigned int phy_reg_data; + ETH_PORT eth_port_num = p_eth_port_ctrl->port_num; + + /* Assignment of Tx CTRP of given queue */ + for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) { + CURR_TFD_GET (p_tx_curr_desc, queue); + MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0 + (eth_port_num) + + (4 * queue)), + ((unsigned int) p_tx_curr_desc)); + + } + + /* Assignment of Rx CRDP of given queue */ + for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) { + CURR_RFD_GET (p_rx_curr_desc, queue); + MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0 + (eth_port_num) + + (4 * queue)), + ((unsigned int) p_rx_curr_desc)); + + if (p_rx_curr_desc != NULL) + /* Add the assigned Ethernet address to the port's address table */ + eth_port_uc_addr_set (p_eth_port_ctrl->port_num, + p_eth_port_ctrl->port_mac_addr, + queue); + } + + /* Assign port configuration and command. */ + MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num), + p_eth_port_ctrl->port_config); + + MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num), + p_eth_port_ctrl->port_config_extend); + + MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num), + p_eth_port_ctrl->port_serial_control); + + MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num), + ETH_SERIAL_PORT_ENABLE); + + /* Assign port SDMA configuration */ + MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num), + p_eth_port_ctrl->port_sdma_config); + + MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT + (eth_port_num), 0x3fffffff); + MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG + (eth_port_num), 0x03fffcff); + /* Turn off the port/queue bandwidth limitation */ + MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0); + + /* Enable port Rx. */ + MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num), + p_eth_port_ctrl->port_rx_queue_command); + + /* Check if link is up */ + eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data); + + if (!(phy_reg_data & 0x20)) + return false; + + return true; +} + +/******************************************************************************* +* eth_port_uc_addr_set - This function Set the port Unicast address. +* +* DESCRIPTION: +* This function Set the port Ethernet MAC address. +* +* INPUT: +* ETH_PORT eth_port_num Port number. +* char * p_addr Address to be set +* ETH_QUEUE queue Rx queue number for this MAC address. +* +* OUTPUT: +* Set MAC address low and high registers. also calls eth_port_uc_addr() +* To set the unicast table with the proper information. +* +* RETURN: +* N/A. +* +*******************************************************************************/ +static void eth_port_uc_addr_set (ETH_PORT eth_port_num, + unsigned char *p_addr, ETH_QUEUE queue) +{ + unsigned int mac_h; + unsigned int mac_l; + + mac_l = (p_addr[4] << 8) | (p_addr[5]); + mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | + (p_addr[2] << 8) | (p_addr[3] << 0); + + MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l); + MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h); + + /* Accept frames of this address */ + eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR); + + return; +} + +/******************************************************************************* +* eth_port_uc_addr - This function Set the port unicast address table +* +* DESCRIPTION: +* This function locates the proper entry in the Unicast table for the +* specified MAC nibble and sets its properties according to function +* parameters. +* +* INPUT: +* ETH_PORT eth_port_num Port number. +* unsigned char uc_nibble Unicast MAC Address last nibble. +* ETH_QUEUE queue Rx queue number for this MAC address. +* int option 0 = Add, 1 = remove address. +* +* OUTPUT: +* This function add/removes MAC addresses from the port unicast address +* table. +* +* RETURN: +* true is output succeeded. +* false if option parameter is invalid. +* +*******************************************************************************/ +static bool eth_port_uc_addr (ETH_PORT eth_port_num, + unsigned char uc_nibble, + ETH_QUEUE queue, int option) +{ + unsigned int unicast_reg; + unsigned int tbl_offset; + unsigned int reg_offset; + + /* Locate the Unicast table entry */ + uc_nibble = (0xf & uc_nibble); + tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */ + reg_offset = uc_nibble % 4; /* Entry offset within the above register */ + + switch (option) { + case REJECT_MAC_ADDR: + /* Clear accepts frame bit at specified unicast DA table entry */ + unicast_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + + tbl_offset)); + + unicast_reg &= (0x0E << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + + tbl_offset), unicast_reg); + break; + + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at unicast DA filter table entry */ + unicast_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + + tbl_offset)); + + unicast_reg |= ((0x01 | queue) << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + + tbl_offset), unicast_reg); + + break; + + default: + return false; + } + return true; +} + +#if 0 /* FIXME */ +/******************************************************************************* +* eth_port_mc_addr - Multicast address settings. +* +* DESCRIPTION: +* This API controls the MV device MAC multicast support. +* The MV device supports multicast using two tables: +* 1) Special Multicast Table for MAC addresses of the form +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF). +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast +* Table entries in the DA-Filter table. +* In this case, the function calls eth_port_smc_addr() routine to set the +* Special Multicast Table. +* 2) Other Multicast Table for multicast of another type. A CRC-8bit +* is used as an index to the Other Multicast Table entries in the +* DA-Filter table. +* In this case, the function calculates the CRC-8bit value and calls +* eth_port_omc_addr() routine to set the Other Multicast Table. +* INPUT: +* ETH_PORT eth_port_num Port number. +* unsigned char *p_addr Unicast MAC Address. +* ETH_QUEUE queue Rx queue number for this MAC address. +* int option 0 = Add, 1 = remove address. +* +* OUTPUT: +* See description. +* +* RETURN: +* true is output succeeded. +* false if add_address_table_entry( ) failed. +* +*******************************************************************************/ +static void eth_port_mc_addr (ETH_PORT eth_port_num, + unsigned char *p_addr, + ETH_QUEUE queue, int option) +{ + unsigned int mac_h; + unsigned int mac_l; + unsigned char crc_result = 0; + int mac_array[48]; + int crc[8]; + int i; + + if ((p_addr[0] == 0x01) && + (p_addr[1] == 0x00) && + (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) { + + eth_port_smc_addr (eth_port_num, p_addr[5], queue, option); + } else { + /* Calculate CRC-8 out of the given address */ + mac_h = (p_addr[0] << 8) | (p_addr[1]); + mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) | + (p_addr[4] << 8) | (p_addr[5] << 0); + + for (i = 0; i < 32; i++) + mac_array[i] = (mac_l >> i) & 0x1; + for (i = 32; i < 48; i++) + mac_array[i] = (mac_h >> (i - 32)) & 0x1; + + crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ + mac_array[39] ^ mac_array[35] ^ mac_array[34] ^ + mac_array[31] ^ mac_array[30] ^ mac_array[28] ^ + mac_array[23] ^ mac_array[21] ^ mac_array[19] ^ + mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ + mac_array[12] ^ mac_array[8] ^ mac_array[7] ^ + mac_array[6] ^ mac_array[0]; + + crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ + mac_array[43] ^ mac_array[41] ^ mac_array[39] ^ + mac_array[36] ^ mac_array[34] ^ mac_array[32] ^ + mac_array[30] ^ mac_array[29] ^ mac_array[28] ^ + mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ + mac_array[21] ^ mac_array[20] ^ mac_array[18] ^ + mac_array[17] ^ mac_array[16] ^ mac_array[15] ^ + mac_array[14] ^ mac_array[13] ^ mac_array[12] ^ + mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ + mac_array[0]; + + crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ + mac_array[43] ^ mac_array[42] ^ mac_array[39] ^ + mac_array[37] ^ mac_array[34] ^ mac_array[33] ^ + mac_array[29] ^ mac_array[28] ^ mac_array[25] ^ + mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ + mac_array[15] ^ mac_array[13] ^ mac_array[12] ^ + mac_array[10] ^ mac_array[8] ^ mac_array[6] ^ + mac_array[2] ^ mac_array[1] ^ mac_array[0]; + + crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ + mac_array[43] ^ mac_array[40] ^ mac_array[38] ^ + mac_array[35] ^ mac_array[34] ^ mac_array[30] ^ + mac_array[29] ^ mac_array[26] ^ mac_array[25] ^ + mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ + mac_array[14] ^ mac_array[13] ^ mac_array[11] ^ + mac_array[9] ^ mac_array[7] ^ mac_array[3] ^ + mac_array[2] ^ mac_array[1]; + + crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ + mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ + mac_array[35] ^ mac_array[31] ^ mac_array[30] ^ + mac_array[27] ^ mac_array[26] ^ mac_array[24] ^ + mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ + mac_array[14] ^ mac_array[12] ^ mac_array[10] ^ + mac_array[8] ^ mac_array[4] ^ mac_array[3] ^ + mac_array[2]; + + crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ + mac_array[42] ^ mac_array[40] ^ mac_array[37] ^ + mac_array[36] ^ mac_array[32] ^ mac_array[31] ^ + mac_array[28] ^ mac_array[27] ^ mac_array[25] ^ + mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ + mac_array[15] ^ mac_array[13] ^ mac_array[11] ^ + mac_array[9] ^ mac_array[5] ^ mac_array[4] ^ + mac_array[3]; + + crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ + mac_array[41] ^ mac_array[38] ^ mac_array[37] ^ + mac_array[33] ^ mac_array[32] ^ mac_array[29] ^ + mac_array[28] ^ mac_array[26] ^ mac_array[21] ^ + mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ + mac_array[14] ^ mac_array[12] ^ mac_array[10] ^ + mac_array[6] ^ mac_array[5] ^ mac_array[4]; + + crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ + mac_array[39] ^ mac_array[38] ^ mac_array[34] ^ + mac_array[33] ^ mac_array[30] ^ mac_array[29] ^ + mac_array[27] ^ mac_array[22] ^ mac_array[20] ^ + mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ + mac_array[13] ^ mac_array[11] ^ mac_array[7] ^ + mac_array[6] ^ mac_array[5]; + + for (i = 0; i < 8; i++) + crc_result = crc_result | (crc[i] << i); + + eth_port_omc_addr (eth_port_num, crc_result, queue, option); + } + return; +} + +/******************************************************************************* +* eth_port_smc_addr - Special Multicast address settings. +* +* DESCRIPTION: +* This routine controls the MV device special MAC multicast support. +* The Special Multicast Table for MAC addresses supports MAC of the form +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF). +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast +* Table entries in the DA-Filter table. +* This function set the Special Multicast Table appropriate entry +* according to the argument given. +* +* INPUT: +* ETH_PORT eth_port_num Port number. +* unsigned char mc_byte Multicast addr last byte (MAC DA[7:0] bits). +* ETH_QUEUE queue Rx queue number for this MAC address. +* int option 0 = Add, 1 = remove address. +* +* OUTPUT: +* See description. +* +* RETURN: +* true is output succeeded. +* false if option parameter is invalid. +* +*******************************************************************************/ +static bool eth_port_smc_addr (ETH_PORT eth_port_num, + unsigned char mc_byte, + ETH_QUEUE queue, int option) +{ + unsigned int smc_table_reg; + unsigned int tbl_offset; + unsigned int reg_offset; + + /* Locate the SMC table entry */ + tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */ + reg_offset = mc_byte % 4; /* Entry offset within the above register */ + queue &= 0x7; + + switch (option) { + case REJECT_MAC_ADDR: + /* Clear accepts frame bit at specified Special DA table entry */ + smc_table_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset)); + smc_table_reg &= (0x0E << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg); + break; + + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at specified Special DA table entry */ + smc_table_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset)); + smc_table_reg |= ((0x01 | queue) << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg); + break; + + default: + return false; + } + return true; +} + +/******************************************************************************* +* eth_port_omc_addr - Multicast address settings. +* +* DESCRIPTION: +* This routine controls the MV device Other MAC multicast support. +* The Other Multicast Table is used for multicast of another type. +* A CRC-8bit is used as an index to the Other Multicast Table entries +* in the DA-Filter table. +* The function gets the CRC-8bit value from the calling routine and +* set the Other Multicast Table appropriate entry according to the +* CRC-8 argument given. +* +* INPUT: +* ETH_PORT eth_port_num Port number. +* unsigned char crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1). +* ETH_QUEUE queue Rx queue number for this MAC address. +* int option 0 = Add, 1 = remove address. +* +* OUTPUT: +* See description. +* +* RETURN: +* true is output succeeded. +* false if option parameter is invalid. +* +*******************************************************************************/ +static bool eth_port_omc_addr (ETH_PORT eth_port_num, + unsigned char crc8, + ETH_QUEUE queue, int option) +{ + unsigned int omc_table_reg; + unsigned int tbl_offset; + unsigned int reg_offset; + + /* Locate the OMC table entry */ + tbl_offset = (crc8 / 4) * 4; /* Register offset from OMC table base */ + reg_offset = crc8 % 4; /* Entry offset within the above register */ + queue &= 0x7; + + switch (option) { + case REJECT_MAC_ADDR: + /* Clear accepts frame bit at specified Other DA table entry */ + omc_table_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset)); + omc_table_reg &= (0x0E << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg); + break; + + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at specified Other DA table entry */ + omc_table_reg = + MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset)); + omc_table_reg |= ((0x01 | queue) << (8 * reg_offset)); + + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg); + break; + + default: + return false; + } + return true; +} +#endif + +/******************************************************************************* +* eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables +* +* DESCRIPTION: +* Go through all the DA filter tables (Unicast, Special Multicast & Other +* Multicast) and set each entry to 0. +* +* INPUT: +* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. +* +* OUTPUT: +* Multicast and Unicast packets are rejected. +* +* RETURN: +* None. +* +*******************************************************************************/ +static void eth_port_init_mac_tables (ETH_PORT eth_port_num) +{ + int table_index; + + /* Clear DA filter unicast table (Ex_dFUT) */ + for (table_index = 0; table_index <= 0xC; table_index += 4) + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + table_index), 0); + + for (table_index = 0; table_index <= 0xFC; table_index += 4) { + /* Clear DA filter special multicast table (Ex_dFSMT) */ + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0); + /* Clear DA filter other multicast table (Ex_dFOMT) */ + MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0); + } +} + +/******************************************************************************* +* eth_clear_mib_counters - Clear all MIB counters +* +* DESCRIPTION: +* This function clears all MIB counters of a specific ethernet port. +* A read from the MIB counter will reset the counter. +* +* INPUT: +* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. +* +* OUTPUT: +* After reading all MIB counters, the counters resets. +* +* RETURN: +* MIB counter value. +* +*******************************************************************************/ +static void eth_clear_mib_counters (ETH_PORT eth_port_num) +{ + int i; + unsigned int dummy; + + /* Perform dummy reads from MIB counters */ + for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION; + i += 4) + dummy = MV_REG_READ ((MV64460_ETH_MIB_COUNTERS_BASE + (eth_port_num) + i)); + + return; +} + +/******************************************************************************* +* eth_read_mib_counter - Read a MIB counter +* +* DESCRIPTION: +* This function reads a MIB counter of a specific ethernet port. +* NOTE - If read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, then the +* following read must be from ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH +* register. The same applies for ETH_MIB_GOOD_OCTETS_SENT_LOW and +* ETH_MIB_GOOD_OCTETS_SENT_HIGH +* +* INPUT: +* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. +* unsigned int mib_offset MIB counter offset (use ETH_MIB_... macros). +* +* OUTPUT: +* After reading the MIB counter, the counter resets. +* +* RETURN: +* MIB counter value. +* +*******************************************************************************/ +unsigned int eth_read_mib_counter (ETH_PORT eth_port_num, + unsigned int mib_offset) +{ + return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num) + + mib_offset)); +} + +/******************************************************************************* +* ethernet_phy_set - Set the ethernet port PHY address. +* +* DESCRIPTION: +* This routine set the ethernet port PHY address according to given +* parameter. +* +* INPUT: +* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. +* +* OUTPUT: +* Set PHY Address Register with given PHY address parameter. +* +* RETURN: +* None. +* +*******************************************************************************/ +static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr) +{ + unsigned int reg_data; + + reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG); + + reg_data &= ~(0x1F << (5 * eth_port_num)); + reg_data |= (phy_addr << (5 * eth_port_num)); + + MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data); + + return; +} + +/******************************************************************************* + * ethernet_phy_get - Get the ethernet port PHY address. + * + * DESCRIPTION: + * This routine returns the given ethernet port PHY address. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * + * OUTPUT: + * None. + * + * RETURN: + * PHY address. + * + *******************************************************************************/ +static int ethernet_phy_get (ETH_PORT eth_port_num) +{ + unsigned int reg_data; + + reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG); + + return ((reg_data >> (5 * eth_port_num)) & 0x1f); +} + +/***********************************************************/ +/* (Re)start autonegotiation */ +/***********************************************************/ +int phy_setup_aneg (char *devname, unsigned char addr) +{ + unsigned short ctl, adv; + + /* Setup standard advertise */ + miiphy_read (devname, addr, PHY_ANAR, &adv); + adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | + PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD | + PHY_ANLPAR_10); + miiphy_write (devname, addr, PHY_ANAR, adv); + + miiphy_read (devname, addr, PHY_1000BTCR, &adv); + adv |= (0x0300); + miiphy_write (devname, addr, PHY_1000BTCR, adv); + + /* Start/Restart aneg */ + miiphy_read (devname, addr, PHY_BMCR, &ctl); + ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); + miiphy_write (devname, addr, PHY_BMCR, ctl); + + return 0; +} + +/******************************************************************************* + * ethernet_phy_reset - Reset Ethernet port PHY. + * + * DESCRIPTION: + * This routine utilize the SMI interface to reset the ethernet port PHY. + * The routine waits until the link is up again or link up is timeout. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * + * OUTPUT: + * The ethernet port PHY renew its link. + * + * RETURN: + * None. + * + *******************************************************************************/ +static bool ethernet_phy_reset (ETH_PORT eth_port_num) +{ + unsigned int time_out = 50; + unsigned int phy_reg_data; + + eth_port_read_smi_reg (eth_port_num, 20, &phy_reg_data); + phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */ + eth_port_write_smi_reg (eth_port_num, 20, phy_reg_data); + + /* Reset the PHY */ + eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data); + phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ + eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data); + + /* Poll on the PHY LINK */ + do { + eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data); + + if (time_out-- == 0) + return false; + } + while (!(phy_reg_data & 0x20)); + + return true; +} + +/******************************************************************************* + * eth_port_reset - Reset Ethernet port + * + * DESCRIPTION: + * This routine resets the chip by aborting any SDMA engine activity and + * clearing the MIB counters. The Receiver and the Transmit unit are in + * idle state after this command is performed and the port is disabled. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * + * OUTPUT: + * Channel activity is halted. + * + * RETURN: + * None. + * + *******************************************************************************/ +static void eth_port_reset (ETH_PORT eth_port_num) +{ + unsigned int reg_data; + + /* Stop Tx port activity. Check port Tx activity. */ + reg_data = + MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG + (eth_port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG + (eth_port_num), (reg_data << 8)); + + /* Wait for all Tx activity to terminate. */ + do { + /* Check port cause register that all Tx queues are stopped */ + reg_data = + MV_REG_READ + (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG + (eth_port_num)); + } + while (reg_data & 0xFF); + } + + /* Stop Rx port activity. Check port Rx activity. */ + reg_data = + MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG + (eth_port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG + (eth_port_num), (reg_data << 8)); + + /* Wait for all Rx activity to terminate. */ + do { + /* Check port cause register that all Rx queues are stopped */ + reg_data = + MV_REG_READ + (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG + (eth_port_num)); + } + while (reg_data & 0xFF); + } + + /* Clear all MIB counters */ + eth_clear_mib_counters (eth_port_num); + + /* Reset the Enable bit in the Configuration Register */ + reg_data = + MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG + (eth_port_num)); + reg_data &= ~ETH_SERIAL_PORT_ENABLE; + MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num), + reg_data); + + return; +} + +#if 0 /* Not needed here */ +/******************************************************************************* + * ethernet_set_config_reg - Set specified bits in configuration register. + * + * DESCRIPTION: + * This function sets specified bits in the given ethernet + * configuration register. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * unsigned int value 32 bit value. + * + * OUTPUT: + * The set bits in the value parameter are set in the configuration + * register. + * + * RETURN: + * None. + * + *******************************************************************************/ +static void ethernet_set_config_reg (ETH_PORT eth_port_num, + unsigned int value) +{ + unsigned int eth_config_reg; + + eth_config_reg = + MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num)); + eth_config_reg |= value; + MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num), + eth_config_reg); + + return; +} +#endif + +#if 0 /* FIXME */ +/******************************************************************************* + * ethernet_reset_config_reg - Reset specified bits in configuration register. + * + * DESCRIPTION: + * This function resets specified bits in the given Ethernet + * configuration register. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * unsigned int value 32 bit value. + * + * OUTPUT: + * The set bits in the value parameter are reset in the configuration + * register. + * + * RETURN: + * None. + * + *******************************************************************************/ +static void ethernet_reset_config_reg (ETH_PORT eth_port_num, + unsigned int value) +{ + unsigned int eth_config_reg; + + eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG + (eth_port_num)); + eth_config_reg &= ~value; + MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num), + eth_config_reg); + + return; +} +#endif + +#if 0 /* Not needed here */ +/******************************************************************************* + * ethernet_get_config_reg - Get the port configuration register + * + * DESCRIPTION: + * This function returns the configuration register value of the given + * ethernet port. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * + * OUTPUT: + * None. + * + * RETURN: + * Port configuration register value. + * + *******************************************************************************/ +static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num) +{ + unsigned int eth_config_reg; + + eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG + (eth_port_num)); + return eth_config_reg; +} + +#endif + +/******************************************************************************* + * eth_port_read_smi_reg - Read PHY registers + * + * DESCRIPTION: + * This routine utilize the SMI interface to interact with the PHY in + * order to perform PHY register read. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * unsigned int phy_reg PHY register address offset. + * unsigned int *value Register value buffer. + * + * OUTPUT: + * Write the value of a specified PHY register into given buffer. + * + * RETURN: + * false if the PHY is busy or read data is not in valid state. + * true otherwise. + * + *******************************************************************************/ +static bool eth_port_read_smi_reg (ETH_PORT eth_port_num, + unsigned int phy_reg, unsigned int *value) +{ + unsigned int reg_value; + unsigned int time_out = PHY_BUSY_TIMEOUT; + int phy_addr; + + phy_addr = ethernet_phy_get (eth_port_num); + + /* first check that it is not busy */ + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while (reg_value & ETH_SMI_BUSY); + + /* not busy */ + + MV_REG_WRITE (MV64460_ETH_SMI_REG, + (phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_READ); + + time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */ + + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */ + + /* Wait for the data to update in the SMI register */ +#define PHY_UPDATE_TIMEOUT 10000 + for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++); + + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + + *value = reg_value & 0xffff; + + return true; +} + +int mv_miiphy_read(char *devname, unsigned char phy_addr, + unsigned char phy_reg, unsigned short *value) +{ + unsigned int reg_value; + unsigned int time_out = PHY_BUSY_TIMEOUT; + + /* first check that it is not busy */ + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while (reg_value & ETH_SMI_BUSY); + + /* not busy */ + MV_REG_WRITE (MV64460_ETH_SMI_REG, + (phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_READ); + + time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */ + + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */ + + /* Wait for the data to update in the SMI register */ + for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++); + + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + + *value = reg_value & 0xffff; + + return 0; +} + +/******************************************************************************* + * eth_port_write_smi_reg - Write to PHY registers + * + * DESCRIPTION: + * This routine utilize the SMI interface to interact with the PHY in + * order to perform writes to PHY registers. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * unsigned int phy_reg PHY register address offset. + * unsigned int value Register value. + * + * OUTPUT: + * Write the given value to the specified PHY register. + * + * RETURN: + * false if the PHY is busy. + * true otherwise. + * + *******************************************************************************/ +static bool eth_port_write_smi_reg (ETH_PORT eth_port_num, + unsigned int phy_reg, unsigned int value) +{ + unsigned int reg_value; + unsigned int time_out = PHY_BUSY_TIMEOUT; + int phy_addr; + + phy_addr = ethernet_phy_get (eth_port_num); + + /* first check that it is not busy */ + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while (reg_value & ETH_SMI_BUSY); + + /* not busy */ + MV_REG_WRITE (MV64460_ETH_SMI_REG, + (phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_WRITE | (value & 0xffff)); + return true; +} + +int mv_miiphy_write(char *devname, unsigned char phy_addr, + unsigned char phy_reg, unsigned short value) +{ + unsigned int reg_value; + unsigned int time_out = PHY_BUSY_TIMEOUT; + + /* first check that it is not busy */ + do { + reg_value = MV_REG_READ (MV64460_ETH_SMI_REG); + if (time_out-- == 0) { + return false; + } + } + while (reg_value & ETH_SMI_BUSY); + + /* not busy */ + MV_REG_WRITE (MV64460_ETH_SMI_REG, + (phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_WRITE | (value & 0xffff)); + return 0; +} + +/******************************************************************************* + * eth_set_access_control - Config address decode parameters for Ethernet unit + * + * DESCRIPTION: + * This function configures the address decode parameters for the Gigabit + * Ethernet Controller according the given parameters struct. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum. + * ETH_WIN_PARAM *param Address decode parameter struct. + * + * OUTPUT: + * An access window is opened using the given access parameters. + * + * RETURN: + * None. + * + *******************************************************************************/ +static void eth_set_access_control (ETH_PORT eth_port_num, + ETH_WIN_PARAM * param) +{ + unsigned int access_prot_reg; + + /* Set access control register */ + access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG + (eth_port_num)); + access_prot_reg &= (~(3 << (param->win * 2))); /* clear window permission */ + access_prot_reg |= (param->access_ctrl << (param->win * 2)); + MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num), + access_prot_reg); + + /* Set window Size reg (SR) */ + MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 + + (ETH_SIZE_REG_GAP * param->win)), + (((param->size / 0x10000) - 1) << 16)); + + /* Set window Base address reg (BA) */ + MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)), + (param->target | param->attributes | param->base_addr)); + /* High address remap reg (HARR) */ + if (param->win < 4) + MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 + + (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)), + param->high_addr); + + /* Base address enable reg (BARER) */ + if (param->enable == 1) + MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG, + (1 << param->win)); + else + MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG, + (1 << param->win)); +} + +/******************************************************************************* + * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. + * + * DESCRIPTION: + * This function prepares a Rx chained list of descriptors and packet + * buffers in a form of a ring. The routine must be called after port + * initialization routine and before port start routine. + * The Ethernet SDMA engine uses CPU bus addresses to access the various + * devices in the system (i.e. DRAM). This function uses the ethernet + * struct 'virtual to physical' routine (set by the user) to set the ring + * with physical addresses. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE rx_queue Number of Rx queue. + * int rx_desc_num Number of Rx descriptors + * int rx_buff_size Size of Rx buffer + * unsigned int rx_desc_base_addr Rx descriptors memory area base addr. + * unsigned int rx_buff_base_addr Rx buffer memory area base addr. + * + * OUTPUT: + * The routine updates the Ethernet port control struct with information + * regarding the Rx descriptors and buffers. + * + * RETURN: + * false if the given descriptors memory area is not aligned according to + * Ethernet SDMA specifications. + * true otherwise. + * + *******************************************************************************/ +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) +{ + ETH_RX_DESC *p_rx_desc; + ETH_RX_DESC *p_rx_prev_desc; /* pointer to link with the last descriptor */ + unsigned int buffer_addr; + int ix; /* a counter */ + + p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr; + p_rx_prev_desc = p_rx_desc; + buffer_addr = rx_buff_base_addr; + + /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */ + if (rx_buff_base_addr & 0xF) + return false; + + /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes */ + if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE)) + return false; + + /* Rx buffers must be 64-bit aligned. */ + if ((rx_buff_base_addr + rx_buff_size) & 0x7) + return false; + + /* initialize the Rx descriptors ring */ + for (ix = 0; ix < rx_desc_num; ix++) { + p_rx_desc->buf_size = rx_buff_size; + p_rx_desc->byte_cnt = 0x0000; + p_rx_desc->cmd_sts = + ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT; + p_rx_desc->next_desc_ptr = + ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE; + p_rx_desc->buf_ptr = buffer_addr; + p_rx_desc->return_info = 0x00000000; + D_CACHE_FLUSH_LINE (p_rx_desc, 0); + buffer_addr += rx_buff_size; + p_rx_prev_desc = p_rx_desc; + p_rx_desc = (ETH_RX_DESC *) + ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE); + } + + /* Closing Rx descriptors ring */ + p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr); + D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0); + + /* Save Rx desc pointer to driver struct. */ + CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue); + USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue); + + p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] = + (ETH_RX_DESC *) rx_desc_base_addr; + p_eth_port_ctrl->rx_desc_area_size[rx_queue] = + rx_desc_num * RX_DESC_ALIGNED_SIZE; + + p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue); + + return true; +} + +/******************************************************************************* + * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory. + * + * DESCRIPTION: + * This function prepares a Tx chained list of descriptors and packet + * buffers in a form of a ring. The routine must be called after port + * initialization routine and before port start routine. + * The Ethernet SDMA engine uses CPU bus addresses to access the various + * devices in the system (i.e. DRAM). This function uses the ethernet + * struct 'virtual to physical' routine (set by the user) to set the ring + * with physical addresses. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE tx_queue Number of Tx queue. + * int tx_desc_num Number of Tx descriptors + * int tx_buff_size Size of Tx buffer + * unsigned int tx_desc_base_addr Tx descriptors memory area base addr. + * unsigned int tx_buff_base_addr Tx buffer memory area base addr. + * + * OUTPUT: + * The routine updates the Ethernet port control struct with information + * regarding the Tx descriptors and buffers. + * + * RETURN: + * false if the given descriptors memory area is not aligned according to + * Ethernet SDMA specifications. + * true otherwise. + * + *******************************************************************************/ +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) +{ + + ETH_TX_DESC *p_tx_desc; + ETH_TX_DESC *p_tx_prev_desc; + unsigned int buffer_addr; + int ix; /* a counter */ + + /* save the first desc pointer to link with the last descriptor */ + p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr; + p_tx_prev_desc = p_tx_desc; + buffer_addr = tx_buff_base_addr; + + /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */ + if (tx_buff_base_addr & 0xF) + return false; + + /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes */ + if ((tx_buff_size > TX_BUFFER_MAX_SIZE) + || (tx_buff_size < TX_BUFFER_MIN_SIZE)) + return false; + + /* Initialize the Tx descriptors ring */ + for (ix = 0; ix < tx_desc_num; ix++) { + p_tx_desc->byte_cnt = 0x0000; + p_tx_desc->l4i_chk = 0x0000; + p_tx_desc->cmd_sts = 0x00000000; + p_tx_desc->next_desc_ptr = + ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE; + + p_tx_desc->buf_ptr = buffer_addr; + p_tx_desc->return_info = 0x00000000; + D_CACHE_FLUSH_LINE (p_tx_desc, 0); + buffer_addr += tx_buff_size; + p_tx_prev_desc = p_tx_desc; + p_tx_desc = (ETH_TX_DESC *) + ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE); + + } + /* Closing Tx descriptors ring */ + p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr; + D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0); + /* Set Tx desc pointer in driver struct. */ + CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue); + USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue); + + /* Init Tx ring base and size parameters */ + p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] = + (ETH_TX_DESC *) tx_desc_base_addr; + p_eth_port_ctrl->tx_desc_area_size[tx_queue] = + (tx_desc_num * TX_DESC_ALIGNED_SIZE); + + /* Add the queue to the list of Tx queues of this port */ + p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue); + + return true; +} + +/******************************************************************************* + * eth_port_send - Send an Ethernet packet + * + * DESCRIPTION: + * This routine send a given packet described by p_pktinfo parameter. It + * supports transmitting of a packet spaned over multiple buffers. The + * routine updates 'curr' and 'first' indexes according to the packet + * segment passed to the routine. In case the packet segment is first, + * the 'first' index is update. In any case, the 'curr' index is updated. + * If the routine get into Tx resource error it assigns 'curr' index as + * 'first'. This way the function can abort Tx process of multiple + * descriptors per packet. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE tx_queue Number of Tx queue. + * PKT_INFO *p_pkt_info User packet buffer. + * + * OUTPUT: + * Tx ring 'curr' and 'first' indexes are updated. + * + * RETURN: + * ETH_QUEUE_FULL in case of Tx resource error. + * ETH_ERROR in case the routine can not access Tx desc ring. + * ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource. + * ETH_OK otherwise. + * + *******************************************************************************/ +static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl, + ETH_QUEUE tx_queue, + PKT_INFO * p_pkt_info) +{ + volatile ETH_TX_DESC *p_tx_desc_first; + volatile ETH_TX_DESC *p_tx_desc_curr; + volatile ETH_TX_DESC *p_tx_next_desc_curr; + volatile ETH_TX_DESC *p_tx_desc_used; + unsigned int command_status; + + /* Do not process Tx ring in case of Tx ring resource error */ + if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true) + return ETH_QUEUE_FULL; + + /* Get the Tx Desc ring indexes */ + CURR_TFD_GET (p_tx_desc_curr, tx_queue); + USED_TFD_GET (p_tx_desc_used, tx_queue); + + if (p_tx_desc_curr == NULL) + return ETH_ERROR; + + /* The following parameters are used to save readings from memory */ + p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue); + command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC; + + if (command_status & (ETH_TX_FIRST_DESC)) { + /* Update first desc */ + FIRST_TFD_SET (p_tx_desc_curr, tx_queue); + p_tx_desc_first = p_tx_desc_curr; + } else { + FIRST_TFD_GET (p_tx_desc_first, tx_queue); + command_status |= ETH_BUFFER_OWNED_BY_DMA; + } + + /* Buffers with a payload smaller than 8 bytes must be aligned to 64-bit */ + /* boundary. We use the memory allocated for Tx descriptor. This memory */ + /* located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor. */ + if (p_pkt_info->byte_cnt <= 8) { + printf ("You have failed in the < 8 bytes errata - fixme\n"); /* RABEEH - TBD */ + return ETH_ERROR; + + p_tx_desc_curr->buf_ptr = + (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC; + eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr, + p_pkt_info->byte_cnt); + } else + p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr; + + p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt; + p_tx_desc_curr->return_info = p_pkt_info->return_info; + + if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) { + /* Set last desc with DMA ownership and interrupt enable. */ + p_tx_desc_curr->cmd_sts = command_status | + ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT; + + if (p_tx_desc_curr != p_tx_desc_first) + p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA; + + /* Flush CPU pipe */ + + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0); + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0); + CPU_PIPE_FLUSH; + + /* Apply send command */ + ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num); + + /* Finish Tx packet. Update first desc in case of Tx resource error */ + p_tx_desc_first = p_tx_next_desc_curr; + FIRST_TFD_SET (p_tx_desc_first, tx_queue); + + } else { + p_tx_desc_curr->cmd_sts = command_status; + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0); + } + + /* Check for ring index overlap in the Tx desc ring */ + if (p_tx_next_desc_curr == p_tx_desc_used) { + /* Update the current descriptor */ + CURR_TFD_SET (p_tx_desc_first, tx_queue); + + p_eth_port_ctrl->tx_resource_err[tx_queue] = true; + return ETH_QUEUE_LAST_RESOURCE; + } else { + /* Update the current descriptor */ + CURR_TFD_SET (p_tx_next_desc_curr, tx_queue); + return ETH_OK; + } +} + +/******************************************************************************* + * eth_tx_return_desc - Free all used Tx descriptors + * + * DESCRIPTION: + * This routine returns the transmitted packet information to the caller. + * It uses the 'first' index to support Tx desc return in case a transmit + * of a packet spanned over multiple buffer still in process. + * In case the Tx queue was in "resource error" condition, where there are + * no available Tx resources, the function resets the resource error flag. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE tx_queue Number of Tx queue. + * PKT_INFO *p_pkt_info User packet buffer. + * + * OUTPUT: + * Tx ring 'first' and 'used' indexes are updated. + * + * RETURN: + * ETH_ERROR in case the routine can not access Tx desc ring. + * ETH_RETRY in case there is transmission in process. + * ETH_END_OF_JOB if the routine has nothing to release. + * ETH_OK otherwise. + * + *******************************************************************************/ +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) +{ + volatile ETH_TX_DESC *p_tx_desc_used = NULL; + volatile ETH_TX_DESC *p_tx_desc_first = NULL; + unsigned int command_status; + + /* Get the Tx Desc ring indexes */ + USED_TFD_GET (p_tx_desc_used, tx_queue); + FIRST_TFD_GET (p_tx_desc_first, tx_queue); + + /* Sanity check */ + if (p_tx_desc_used == NULL) + return ETH_ERROR; + + command_status = p_tx_desc_used->cmd_sts; + + /* Still transmitting... */ + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0); + return ETH_RETRY; + } + + /* Stop release. About to overlap the current available Tx descriptor */ + if ((p_tx_desc_used == p_tx_desc_first) && + (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) { + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0); + return ETH_END_OF_JOB; + } + + /* Pass the packet information to the caller */ + p_pkt_info->cmd_sts = command_status; + p_pkt_info->return_info = p_tx_desc_used->return_info; + p_tx_desc_used->return_info = 0; + + /* Update the next descriptor to release. */ + USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue); + + /* Any Tx return cancels the Tx resource error status */ + if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true) + p_eth_port_ctrl->tx_resource_err[tx_queue] = false; + + D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0); + + return ETH_OK; + +} + +/******************************************************************************* + * eth_port_receive - Get received information from Rx ring. + * + * DESCRIPTION: + * This routine returns the received data to the caller. There is no + * data copying during routine operation. All information is returned + * using pointer to packet information struct passed from the caller. + * If the routine exhausts Rx ring resources then the resource error flag + * is set. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE rx_queue Number of Rx queue. + * PKT_INFO *p_pkt_info User packet buffer. + * + * OUTPUT: + * Rx ring current and used indexes are updated. + * + * RETURN: + * ETH_ERROR in case the routine can not access Rx desc ring. + * ETH_QUEUE_FULL if Rx ring resources are exhausted. + * ETH_END_OF_JOB if there is no received data. + * ETH_OK otherwise. + * + *******************************************************************************/ +static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl, + ETH_QUEUE rx_queue, + PKT_INFO * p_pkt_info) +{ + volatile ETH_RX_DESC *p_rx_curr_desc; + volatile ETH_RX_DESC *p_rx_next_curr_desc; + volatile ETH_RX_DESC *p_rx_used_desc; + unsigned int command_status; + + /* Do not process Rx ring in case of Rx ring resource error */ + if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) { + printf ("\nRx Queue is full ...\n"); + return ETH_QUEUE_FULL; + } + + /* Get the Rx Desc ring 'curr and 'used' indexes */ + CURR_RFD_GET (p_rx_curr_desc, rx_queue); + USED_RFD_GET (p_rx_used_desc, rx_queue); + + /* Sanity check */ + if (p_rx_curr_desc == NULL) + return ETH_ERROR; + + /* The following parameters are used to save readings from memory */ + p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue); + command_status = p_rx_curr_desc->cmd_sts; + + /* Nothing to receive... */ + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { +/* DP(printf("Rx: command_status: %08x\n", command_status)); */ + D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0); +/* DP(printf("\nETH_END_OF_JOB ...\n"));*/ + return ETH_END_OF_JOB; + } + + p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET; + p_pkt_info->cmd_sts = command_status; + p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET; + p_pkt_info->return_info = p_rx_curr_desc->return_info; + p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */ + + /* Clean the return info field to indicate that the packet has been */ + /* moved to the upper layers */ + p_rx_curr_desc->return_info = 0; + + /* Update 'curr' in data structure */ + CURR_RFD_SET (p_rx_next_curr_desc, rx_queue); + + /* Rx descriptors resource exhausted. Set the Rx ring resource error flag */ + if (p_rx_next_curr_desc == p_rx_used_desc) + p_eth_port_ctrl->rx_resource_err[rx_queue] = true; + + D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0); + CPU_PIPE_FLUSH; + + return ETH_OK; +} + +/******************************************************************************* + * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring. + * + * DESCRIPTION: + * This routine returns a Rx buffer back to the Rx ring. It retrieves the + * next 'used' descriptor and attached the returned buffer to it. + * In case the Rx ring was in "resource error" condition, where there are + * no available Rx resources, the function resets the resource error flag. + * + * INPUT: + * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct. + * ETH_QUEUE rx_queue Number of Rx queue. + * PKT_INFO *p_pkt_info Information on the returned buffer. + * + * OUTPUT: + * New available Rx resource in Rx descriptor ring. + * + * RETURN: + * ETH_ERROR in case the routine can not access Rx desc ring. + * ETH_OK otherwise. + * + *******************************************************************************/ +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) +{ + volatile ETH_RX_DESC *p_used_rx_desc; /* Where to return Rx resource */ + + /* Get 'used' Rx descriptor */ + USED_RFD_GET (p_used_rx_desc, rx_queue); + + /* Sanity check */ + if (p_used_rx_desc == NULL) + return ETH_ERROR; + + p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr; + p_used_rx_desc->return_info = p_pkt_info->return_info; + p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt; + p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE; /* Reset Buffer size */ + + /* Flush the write pipe */ + CPU_PIPE_FLUSH; + + /* Return the descriptor to DMA ownership */ + p_used_rx_desc->cmd_sts = + ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT; + + /* Flush descriptor and CPU pipe */ + D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0); + CPU_PIPE_FLUSH; + + /* Move the used descriptor pointer to the next descriptor */ + USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue); + + /* Any Rx return cancels the Rx resource error status */ + if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) + p_eth_port_ctrl->rx_resource_err[rx_queue] = false; + + return ETH_OK; +} + +/******************************************************************************* + * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path + * + * DESCRIPTION: + * This routine sets the RX coalescing interrupt mechanism parameter. + * This parameter is a timeout counter, that counts in 64 t_clk + * chunks ; that when timeout event occurs a maskable interrupt + * occurs. + * The parameter is calculated using the tClk of the MV-643xx chip + * , and the required delay of the interrupt in usec. + * + * INPUT: + * ETH_PORT eth_port_num Ethernet port number + * unsigned int t_clk t_clk of the MV-643xx chip in HZ units + * unsigned int delay Delay in usec + * + * OUTPUT: + * Interrupt coalescing mechanism value is set in MV-643xx chip. + * + * RETURN: + * The interrupt coalescing value set in the gigE port. + * + *******************************************************************************/ +#if 0 /* FIXME */ +static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num, + unsigned int t_clk, + unsigned int delay) +{ + unsigned int coal; + + coal = ((t_clk / 1000000) * delay) / 64; + /* Set RX Coalescing mechanism */ + MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num), + ((coal & 0x3fff) << 8) | + (MV_REG_READ + (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num)) + & 0xffc000ff)); + return coal; +} + +#endif +/******************************************************************************* + * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path + * + * DESCRIPTION: + * This routine sets the TX coalescing interrupt mechanism parameter. + * This parameter is a timeout counter, that counts in 64 t_clk + * chunks ; that when timeout event occurs a maskable interrupt + * occurs. + * The parameter is calculated using the t_cLK frequency of the + * MV-643xx chip and the required delay in the interrupt in uSec + * + * INPUT: + * ETH_PORT eth_port_num Ethernet port number + * unsigned int t_clk t_clk of the MV-643xx chip in HZ units + * unsigned int delay Delay in uSeconds + * + * OUTPUT: + * Interrupt coalescing mechanism value is set in MV-643xx chip. + * + * RETURN: + * The interrupt coalescing value set in the gigE port. + * + *******************************************************************************/ +#if 0 /* FIXME */ +static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num, + unsigned int t_clk, + unsigned int delay) +{ + unsigned int coal; + + coal = ((t_clk / 1000000) * delay) / 64; + /* Set TX Coalescing mechanism */ + MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num), + coal << 4); + return coal; +} +#endif + +/******************************************************************************* + * eth_b_copy - Copy bytes from source to destination + * + * DESCRIPTION: + * This function supports the eight bytes limitation on Tx buffer size. + * The routine will zero eight bytes starting from the destination address + * followed by copying bytes from the source address to the destination. + * + * INPUT: + * unsigned int src_addr 32 bit source address. + * unsigned int dst_addr 32 bit destination address. + * int byte_count Number of bytes to copy. + * + * OUTPUT: + * See description. + * + * RETURN: + * None. + * + *******************************************************************************/ +static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr, + int byte_count) +{ + /* Zero the dst_addr area */ + *(unsigned int *) dst_addr = 0x0; + + while (byte_count != 0) { + *(char *) dst_addr = *(char *) src_addr; + dst_addr++; + src_addr++; + byte_count--; + } +} diff --git a/board/prodrive/p3mx/mv_eth.h b/board/prodrive/p3mx/mv_eth.h new file mode 100644 index 0000000..334b049 --- /dev/null +++ b/board/prodrive/p3mx/mv_eth.h @@ -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_ */ diff --git a/board/prodrive/p3mx/mv_regs.h b/board/prodrive/p3mx/mv_regs.h new file mode 100644 index 0000000..068590f --- /dev/null +++ b/board/prodrive/p3mx/mv_regs.h @@ -0,0 +1,1125 @@ +/* + * (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 + */ + +/******************************************************************************** +* gt64460r.h - GT-64460 Internal registers definition file. +* +* DESCRIPTION: +* None. +* +* DEPENDENCIES: +* None. +* +*******************************************************************************/ + +#ifndef __INCmv_regsh +#define __INCmv_regsh + +#define MV64460 + +/* Supported by the Atlantis */ +#define MV64460_INCLUDE_PCI_1 +#define MV64460_INCLUDE_PCI_0_ARBITER +#define MV64460_INCLUDE_PCI_1_ARBITER +#define MV64460_INCLUDE_SNOOP_SUPPORT +#define MV64460_INCLUDE_P2P +#define MV64460_INCLUDE_ETH_PORT_2 +#define MV64460_INCLUDE_CPU_MAPPING +#define MV64460_INCLUDE_MPSC + +/* Not supported features */ +#undef INCLUDE_CNTMR_4_7 +#undef INCLUDE_DMA_4_7 + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* DDR SDRAM BAR and size registers */ + +#define MV64460_CS_0_BASE_ADDR 0x008 +#define MV64460_CS_0_SIZE 0x010 +#define MV64460_CS_1_BASE_ADDR 0x208 +#define MV64460_CS_1_SIZE 0x210 +#define MV64460_CS_2_BASE_ADDR 0x018 +#define MV64460_CS_2_SIZE 0x020 +#define MV64460_CS_3_BASE_ADDR 0x218 +#define MV64460_CS_3_SIZE 0x220 + +/* Devices BAR and size registers */ + +#define MV64460_DEV_CS0_BASE_ADDR 0x028 +#define MV64460_DEV_CS0_SIZE 0x030 +#define MV64460_DEV_CS1_BASE_ADDR 0x228 +#define MV64460_DEV_CS1_SIZE 0x230 +#define MV64460_DEV_CS2_BASE_ADDR 0x248 +#define MV64460_DEV_CS2_SIZE 0x250 +#define MV64460_DEV_CS3_BASE_ADDR 0x038 +#define MV64460_DEV_CS3_SIZE 0x040 +#define MV64460_BOOTCS_BASE_ADDR 0x238 +#define MV64460_BOOTCS_SIZE 0x240 + +/* PCI 0 BAR and size registers */ + +#define MV64460_PCI_0_IO_BASE_ADDR 0x048 +#define MV64460_PCI_0_IO_SIZE 0x050 +#define MV64460_PCI_0_MEMORY0_BASE_ADDR 0x058 +#define MV64460_PCI_0_MEMORY0_SIZE 0x060 +#define MV64460_PCI_0_MEMORY1_BASE_ADDR 0x080 +#define MV64460_PCI_0_MEMORY1_SIZE 0x088 +#define MV64460_PCI_0_MEMORY2_BASE_ADDR 0x258 +#define MV64460_PCI_0_MEMORY2_SIZE 0x260 +#define MV64460_PCI_0_MEMORY3_BASE_ADDR 0x280 +#define MV64460_PCI_0_MEMORY3_SIZE 0x288 + +/* PCI 1 BAR and size registers */ +#define MV64460_PCI_1_IO_BASE_ADDR 0x090 +#define MV64460_PCI_1_IO_SIZE 0x098 +#define MV64460_PCI_1_MEMORY0_BASE_ADDR 0x0a0 +#define MV64460_PCI_1_MEMORY0_SIZE 0x0a8 +#define MV64460_PCI_1_MEMORY1_BASE_ADDR 0x0b0 +#define MV64460_PCI_1_MEMORY1_SIZE 0x0b8 +#define MV64460_PCI_1_MEMORY2_BASE_ADDR 0x2a0 +#define MV64460_PCI_1_MEMORY2_SIZE 0x2a8 +#define MV64460_PCI_1_MEMORY3_BASE_ADDR 0x2b0 +#define MV64460_PCI_1_MEMORY3_SIZE 0x2b8 + +/* SRAM base address */ +#define MV64460_INTEGRATED_SRAM_BASE_ADDR 0x268 + +/* internal registers space base address */ +#define MV64460_INTERNAL_SPACE_BASE_ADDR 0x068 + +/* Enables the CS , DEV_CS , PCI 0 and PCI 1 + windows above */ +#define MV64460_BASE_ADDR_ENABLE 0x278 + +/****************************************/ +/* PCI remap registers */ +/****************************************/ + /* PCI 0 */ +#define MV64460_PCI_0_IO_ADDR_REMAP 0x0f0 +#define MV64460_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8 +#define MV64460_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320 +#define MV64460_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100 +#define MV64460_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328 +#define MV64460_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8 +#define MV64460_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330 +#define MV64460_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300 +#define MV64460_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338 + /* PCI 1 */ +#define MV64460_PCI_1_IO_ADDR_REMAP 0x108 +#define MV64460_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110 +#define MV64460_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340 +#define MV64460_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118 +#define MV64460_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348 +#define MV64460_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310 +#define MV64460_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350 +#define MV64460_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318 +#define MV64460_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358 + +#define MV64460_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0 +#define MV64460_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8 +#define MV64460_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0 +#define MV64460_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8 +#define MV64460_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0 +#define MV64460_CPU_GE_HEADERS_RETARGET_BASE 0x3d8 +#define MV64460_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0 +#define MV64460_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8 + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define MV64460_CPU_CONFIG 0x000 +#define MV64460_CPU_MODE 0x120 +#define MV64460_CPU_MASTER_CONTROL 0x160 +#define MV64460_CPU_CROSS_BAR_CONTROL_LOW 0x150 +#define MV64460_CPU_CROSS_BAR_CONTROL_HIGH 0x158 +#define MV64460_CPU_CROSS_BAR_TIMEOUT 0x168 + +/****************************************/ +/* SMP RegisterS */ +/****************************************/ + +#define MV64460_SMP_WHO_AM_I 0x200 +#define MV64460_SMP_CPU0_DOORBELL 0x214 +#define MV64460_SMP_CPU0_DOORBELL_CLEAR 0x21C +#define MV64460_SMP_CPU1_DOORBELL 0x224 +#define MV64460_SMP_CPU1_DOORBELL_CLEAR 0x22C +#define MV64460_SMP_CPU0_DOORBELL_MASK 0x234 +#define MV64460_SMP_CPU1_DOORBELL_MASK 0x23C +#define MV64460_SMP_SEMAPHOR0 0x244 +#define MV64460_SMP_SEMAPHOR1 0x24c +#define MV64460_SMP_SEMAPHOR2 0x254 +#define MV64460_SMP_SEMAPHOR3 0x25c +#define MV64460_SMP_SEMAPHOR4 0x264 +#define MV64460_SMP_SEMAPHOR5 0x26c +#define MV64460_SMP_SEMAPHOR6 0x274 +#define MV64460_SMP_SEMAPHOR7 0x27c + +/****************************************/ +/* CPU Sync Barrier Register */ +/****************************************/ + +#define MV64460_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0 +#define MV64460_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8 +#define MV64460_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0 +#define MV64460_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8 + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define MV64460_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180 +#define MV64460_CPU_PROTECT_WINDOW_0_SIZE 0x188 +#define MV64460_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190 +#define MV64460_CPU_PROTECT_WINDOW_1_SIZE 0x198 +#define MV64460_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0 +#define MV64460_CPU_PROTECT_WINDOW_2_SIZE 0x1a8 +#define MV64460_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0 +#define MV64460_CPU_PROTECT_WINDOW_3_SIZE 0x1b8 + + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define MV64460_CPU_ERROR_ADDR_LOW 0x070 +#define MV64460_CPU_ERROR_ADDR_HIGH 0x078 +#define MV64460_CPU_ERROR_DATA_LOW 0x128 +#define MV64460_CPU_ERROR_DATA_HIGH 0x130 +#define MV64460_CPU_ERROR_PARITY 0x138 +#define MV64460_CPU_ERROR_CAUSE 0x140 +#define MV64460_CPU_ERROR_MASK 0x148 + +/****************************************/ +/* CPU Interface Debug Registers */ +/****************************************/ + +#define MV64460_PUNIT_SLAVE_DEBUG_LOW 0x360 +#define MV64460_PUNIT_SLAVE_DEBUG_HIGH 0x368 +#define MV64460_PUNIT_MASTER_DEBUG_LOW 0x370 +#define MV64460_PUNIT_MASTER_DEBUG_HIGH 0x378 +#define MV64460_PUNIT_MMASK 0x3e4 + +/****************************************/ +/* Integrated SRAM Registers */ +/****************************************/ + +#define MV64460_SRAM_CONFIG 0x380 +#define MV64460_SRAM_TEST_MODE 0X3F4 +#define MV64460_SRAM_ERROR_CAUSE 0x388 +#define MV64460_SRAM_ERROR_ADDR 0x390 +#define MV64460_SRAM_ERROR_ADDR_HIGH 0X3F8 +#define MV64460_SRAM_ERROR_DATA_LOW 0x398 +#define MV64460_SRAM_ERROR_DATA_HIGH 0x3a0 +#define MV64460_SRAM_ERROR_DATA_PARITY 0x3a8 + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define MV64460_SDRAM_CONFIG 0x1400 +#define MV64460_D_UNIT_CONTROL_LOW 0x1404 +#define MV64460_D_UNIT_CONTROL_HIGH 0x1424 +#define MV64460_D_UNIT_MMASK 0x14B0 +#define MV64460_SDRAM_TIMING_CONTROL_LOW 0x1408 +#define MV64460_SDRAM_TIMING_CONTROL_HIGH 0x140c +#define MV64460_SDRAM_ADDR_CONTROL 0x1410 +#define MV64460_SDRAM_OPEN_PAGES_CONTROL 0x1414 +#define MV64460_SDRAM_OPERATION 0x1418 +#define MV64460_SDRAM_MODE 0x141c +#define MV64460_EXTENDED_DRAM_MODE 0x1420 +#define MV64460_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430 +#define MV64460_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434 +#define MV64460_SDRAM_CROSS_BAR_TIMEOUT 0x1438 +#define MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0 +#define MV64460_SDRAM_DATA_PADS_CALIBRATION 0x14c4 + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define MV64460_SDRAM_ERROR_DATA_LOW 0x1444 +#define MV64460_SDRAM_ERROR_DATA_HIGH 0x1440 +#define MV64460_SDRAM_ERROR_ADDR 0x1450 +#define MV64460_SDRAM_RECEIVED_ECC 0x1448 +#define MV64460_SDRAM_CALCULATED_ECC 0x144c +#define MV64460_SDRAM_ECC_CONTROL 0x1454 +#define MV64460_SDRAM_ECC_ERROR_COUNTER 0x1458 + +/******************************************/ +/* Controlled Delay Line (CDL) Registers */ +/******************************************/ + +#define MV64460_DFCDL_CONFIG0 0x1480 +#define MV64460_DFCDL_CONFIG1 0x1484 +#define MV64460_DLL_WRITE 0x1488 +#define MV64460_DLL_READ 0x148c +#define MV64460_SRAM_ADDR 0x1490 +#define MV64460_SRAM_DATA0 0x1494 +#define MV64460_SRAM_DATA1 0x1498 +#define MV64460_SRAM_DATA2 0x149c +#define MV64460_DFCL_PROBE 0x14a0 + +/******************************************/ +/* Debug Registers */ +/******************************************/ + +#define MV64460_DUNIT_DEBUG_LOW 0x1460 +#define MV64460_DUNIT_DEBUG_HIGH 0x1464 +#define MV64460_DUNIT_MMASK 0X1b40 + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define MV64460_DEVICE_BANK0_PARAMETERS 0x45c +#define MV64460_DEVICE_BANK1_PARAMETERS 0x460 +#define MV64460_DEVICE_BANK2_PARAMETERS 0x464 +#define MV64460_DEVICE_BANK3_PARAMETERS 0x468 +#define MV64460_DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define MV64460_DEVICE_INTERFACE_CONTROL 0x4c0 +#define MV64460_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define MV64460_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define MV64460_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4 + +/****************************************/ +/* Device interrupt registers */ +/****************************************/ + +#define MV64460_DEVICE_INTERRUPT_CAUSE 0x4d0 +#define MV64460_DEVICE_INTERRUPT_MASK 0x4d4 +#define MV64460_DEVICE_ERROR_ADDR 0x4d8 +#define MV64460_DEVICE_ERROR_DATA 0x4dc +#define MV64460_DEVICE_ERROR_PARITY 0x4e0 + +/****************************************/ +/* Device debug registers */ +/****************************************/ + +#define MV64460_DEVICE_DEBUG_LOW 0x4e4 +#define MV64460_DEVICE_DEBUG_HIGH 0x4e8 +#define MV64460_RUNIT_MMASK 0x4f0 + +/****************************************/ +/* PCI Slave Address Decoding registers */ +/****************************************/ + +#define MV64460_PCI_0_CS_0_BANK_SIZE 0xc08 +#define MV64460_PCI_1_CS_0_BANK_SIZE 0xc88 +#define MV64460_PCI_0_CS_1_BANK_SIZE 0xd08 +#define MV64460_PCI_1_CS_1_BANK_SIZE 0xd88 +#define MV64460_PCI_0_CS_2_BANK_SIZE 0xc0c +#define MV64460_PCI_1_CS_2_BANK_SIZE 0xc8c +#define MV64460_PCI_0_CS_3_BANK_SIZE 0xd0c +#define MV64460_PCI_1_CS_3_BANK_SIZE 0xd8c +#define MV64460_PCI_0_DEVCS_0_BANK_SIZE 0xc10 +#define MV64460_PCI_1_DEVCS_0_BANK_SIZE 0xc90 +#define MV64460_PCI_0_DEVCS_1_BANK_SIZE 0xd10 +#define MV64460_PCI_1_DEVCS_1_BANK_SIZE 0xd90 +#define MV64460_PCI_0_DEVCS_2_BANK_SIZE 0xd18 +#define MV64460_PCI_1_DEVCS_2_BANK_SIZE 0xd98 +#define MV64460_PCI_0_DEVCS_3_BANK_SIZE 0xc14 +#define MV64460_PCI_1_DEVCS_3_BANK_SIZE 0xc94 +#define MV64460_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14 +#define MV64460_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94 +#define MV64460_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c +#define MV64460_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c +#define MV64460_PCI_0_P2P_MEM1_BAR_SIZE 0xd20 +#define MV64460_PCI_1_P2P_MEM1_BAR_SIZE 0xda0 +#define MV64460_PCI_0_P2P_I_O_BAR_SIZE 0xd24 +#define MV64460_PCI_1_P2P_I_O_BAR_SIZE 0xda4 +#define MV64460_PCI_0_CPU_BAR_SIZE 0xd28 +#define MV64460_PCI_1_CPU_BAR_SIZE 0xda8 +#define MV64460_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00 +#define MV64460_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80 +#define MV64460_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c +#define MV64460_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c +#define MV64460_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c +#define MV64460_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc +#define MV64460_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48 +#define MV64460_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8 +#define MV64460_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48 +#define MV64460_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8 +#define MV64460_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c +#define MV64460_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc +#define MV64460_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c +#define MV64460_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc +#define MV64460_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04 +#define MV64460_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84 +#define MV64460_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08 +#define MV64460_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88 +#define MV64460_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C +#define MV64460_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C +#define MV64460_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10 +#define MV64460_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90 +#define MV64460_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50 +#define MV64460_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0 +#define MV64460_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50 +#define MV64460_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0 +#define MV64460_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58 +#define MV64460_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8 +#define MV64460_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54 +#define MV64460_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4 +#define MV64460_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54 +#define MV64460_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4 +#define MV64460_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c +#define MV64460_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc +#define MV64460_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60 +#define MV64460_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0 +#define MV64460_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64 +#define MV64460_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4 +#define MV64460_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68 +#define MV64460_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8 +#define MV64460_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c +#define MV64460_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec +#define MV64460_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70 +#define MV64460_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0 +#define MV64460_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74 +#define MV64460_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4 +#define MV64460_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00 +#define MV64460_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80 +#define MV64460_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38 +#define MV64460_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8 +#define MV64460_PCI_0_ADDR_DECODE_CONTROL 0xd3c +#define MV64460_PCI_1_ADDR_DECODE_CONTROL 0xdbc +#define MV64460_PCI_0_HEADERS_RETARGET_CONTROL 0xF40 +#define MV64460_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0 +#define MV64460_PCI_0_HEADERS_RETARGET_BASE 0xF44 +#define MV64460_PCI_1_HEADERS_RETARGET_BASE 0xFc4 +#define MV64460_PCI_0_HEADERS_RETARGET_HIGH 0xF48 +#define MV64460_PCI_1_HEADERS_RETARGET_HIGH 0xFc8 + +/***********************************/ +/* PCI Control Register Map */ +/***********************************/ + +#define MV64460_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20 +#define MV64460_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0 +#define MV64460_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C +#define MV64460_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C +#define MV64460_PCI_0_COMMAND 0xc00 +#define MV64460_PCI_1_COMMAND 0xc80 +#define MV64460_PCI_0_MODE 0xd00 +#define MV64460_PCI_1_MODE 0xd80 +#define MV64460_PCI_0_RETRY 0xc04 +#define MV64460_PCI_1_RETRY 0xc84 +#define MV64460_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04 +#define MV64460_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84 +#define MV64460_PCI_0_MSI_TRIGGER_TIMER 0xc38 +#define MV64460_PCI_1_MSI_TRIGGER_TIMER 0xcb8 +#define MV64460_PCI_0_ARBITER_CONTROL 0x1d00 +#define MV64460_PCI_1_ARBITER_CONTROL 0x1d80 +#define MV64460_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08 +#define MV64460_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88 +#define MV64460_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c +#define MV64460_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c +#define MV64460_PCI_0_CROSS_BAR_TIMEOUT 0x1d04 +#define MV64460_PCI_1_CROSS_BAR_TIMEOUT 0x1d84 +#define MV64460_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18 +#define MV64460_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98 +#define MV64460_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10 +#define MV64460_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90 +#define MV64460_PCI_0_P2P_CONFIG 0x1d14 +#define MV64460_PCI_1_P2P_CONFIG 0x1d94 + +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50 +#define MV64460_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58 + +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0 +#define MV64460_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8 + +/****************************************/ +/* PCI Configuration Access Registers */ +/****************************************/ + +#define MV64460_PCI_0_CONFIG_ADDR 0xcf8 +#define MV64460_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc +#define MV64460_PCI_1_CONFIG_ADDR 0xc78 +#define MV64460_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c +#define MV64460_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34 +#define MV64460_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4 + +/****************************************/ +/* PCI Error Report Registers */ +/****************************************/ + +#define MV64460_PCI_0_SERR_MASK 0xc28 +#define MV64460_PCI_1_SERR_MASK 0xca8 +#define MV64460_PCI_0_ERROR_ADDR_LOW 0x1d40 +#define MV64460_PCI_1_ERROR_ADDR_LOW 0x1dc0 +#define MV64460_PCI_0_ERROR_ADDR_HIGH 0x1d44 +#define MV64460_PCI_1_ERROR_ADDR_HIGH 0x1dc4 +#define MV64460_PCI_0_ERROR_ATTRIBUTE 0x1d48 +#define MV64460_PCI_1_ERROR_ATTRIBUTE 0x1dc8 +#define MV64460_PCI_0_ERROR_COMMAND 0x1d50 +#define MV64460_PCI_1_ERROR_COMMAND 0x1dd0 +#define MV64460_PCI_0_ERROR_CAUSE 0x1d58 +#define MV64460_PCI_1_ERROR_CAUSE 0x1dd8 +#define MV64460_PCI_0_ERROR_MASK 0x1d5c +#define MV64460_PCI_1_ERROR_MASK 0x1ddc + +/****************************************/ +/* PCI Debug Registers */ +/****************************************/ + +#define MV64460_PCI_0_MMASK 0X1D24 +#define MV64460_PCI_1_MMASK 0X1DA4 + +/*********************************************/ +/* PCI Configuration, Function 0, Registers */ +/*********************************************/ + +#define MV64460_PCI_DEVICE_AND_VENDOR_ID 0x000 +#define MV64460_PCI_STATUS_AND_COMMAND 0x004 +#define MV64460_PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define MV64460_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C + +#define MV64460_PCI_SCS_0_BASE_ADDR_LOW 0x010 +#define MV64460_PCI_SCS_0_BASE_ADDR_HIGH 0x014 +#define MV64460_PCI_SCS_1_BASE_ADDR_LOW 0x018 +#define MV64460_PCI_SCS_1_BASE_ADDR_HIGH 0x01C +#define MV64460_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020 +#define MV64460_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024 +#define MV64460_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c +#define MV64460_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030 +#define MV64460_PCI_CAPABILTY_LIST_POINTER 0x034 +#define MV64460_PCI_INTERRUPT_PIN_AND_LINE 0x03C + /* capability list */ +#define MV64460_PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define MV64460_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define MV64460_PCI_VPD_ADDR 0x048 +#define MV64460_PCI_VPD_DATA 0x04c +#define MV64460_PCI_MSI_MESSAGE_CONTROL 0x050 +#define MV64460_PCI_MSI_MESSAGE_ADDR 0x054 +#define MV64460_PCI_MSI_MESSAGE_UPPER_ADDR 0x058 +#define MV64460_PCI_MSI_MESSAGE_DATA 0x05c +#define MV64460_PCI_X_COMMAND 0x060 +#define MV64460_PCI_X_STATUS 0x064 +#define MV64460_PCI_COMPACT_PCI_HOT_SWAP 0x068 + +/***********************************************/ +/* PCI Configuration, Function 1, Registers */ +/***********************************************/ + +#define MV64460_PCI_SCS_2_BASE_ADDR_LOW 0x110 +#define MV64460_PCI_SCS_2_BASE_ADDR_HIGH 0x114 +#define MV64460_PCI_SCS_3_BASE_ADDR_LOW 0x118 +#define MV64460_PCI_SCS_3_BASE_ADDR_HIGH 0x11c +#define MV64460_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120 +#define MV64460_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124 + +/***********************************************/ +/* PCI Configuration, Function 2, Registers */ +/***********************************************/ + +#define MV64460_PCI_DEVCS_0_BASE_ADDR_LOW 0x210 +#define MV64460_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214 +#define MV64460_PCI_DEVCS_1_BASE_ADDR_LOW 0x218 +#define MV64460_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c +#define MV64460_PCI_DEVCS_2_BASE_ADDR_LOW 0x220 +#define MV64460_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 3, Registers */ +/***********************************************/ + +#define MV64460_PCI_DEVCS_3_BASE_ADDR_LOW 0x310 +#define MV64460_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314 +#define MV64460_PCI_BOOT_CS_BASE_ADDR_LOW 0x318 +#define MV64460_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c +#define MV64460_PCI_CPU_BASE_ADDR_LOW 0x220 +#define MV64460_PCI_CPU_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 4, Registers */ +/***********************************************/ + +#define MV64460_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410 +#define MV64460_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414 +#define MV64460_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418 +#define MV64460_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c +#define MV64460_PCI_P2P_I_O_BASE_ADDR 0x420 +#define MV64460_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424 + +/****************************************/ +/* Messaging Unit Registers (I20) */ +/****************************************/ + +#define MV64460_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010 +#define MV64460_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C +#define MV64460_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020 +#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024 +#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028 +#define MV64460_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C +#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030 +#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034 +#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040 +#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044 +#define MV64460_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050 +#define MV64460_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054 +#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060 +#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064 +#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068 +#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C +#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070 +#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074 +#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8 +#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC + +#define MV64460_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090 +#define MV64460_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C +#define MV64460_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0 +#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4 +#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8 +#define MV64460_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC +#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0 +#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4 +#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0 +#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4 +#define MV64460_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0 +#define MV64460_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4 +#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0 +#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4 +#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8 +#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC +#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0 +#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4 +#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078 +#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C + +#define MV64460_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10 +#define MV64460_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C +#define MV64460_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20 +#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24 +#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28 +#define MV64460_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C +#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30 +#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34 +#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40 +#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44 +#define MV64460_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50 +#define MV64460_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54 +#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60 +#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64 +#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68 +#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C +#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70 +#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74 +#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8 +#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC +#define MV64460_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90 +#define MV64460_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98 +#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C +#define MV64460_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0 +#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4 +#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8 +#define MV64460_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC +#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0 +#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4 +#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0 +#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4 +#define MV64460_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0 +#define MV64460_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4 +#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0 +#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4 +#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8 +#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC +#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0 +#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4 +#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78 +#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C + +/****************************************/ +/* Ethernet Unit Registers */ +/****************************************/ + +#define MV64460_ETH_PHY_ADDR_REG 0x2000 +#define MV64460_ETH_SMI_REG 0x2004 +#define MV64460_ETH_UNIT_DEFAULT_ADDR_REG 0x2008 +#define MV64460_ETH_UNIT_DEFAULTID_REG 0x200c +#define MV64460_ETH_UNIT_INTERRUPT_CAUSE_REG 0x2080 +#define MV64460_ETH_UNIT_INTERRUPT_MASK_REG 0x2084 +#define MV64460_ETH_UNIT_INTERNAL_USE_REG 0x24fc +#define MV64460_ETH_UNIT_ERROR_ADDR_REG 0x2094 +#define MV64460_ETH_BAR_0 0x2200 +#define MV64460_ETH_BAR_1 0x2208 +#define MV64460_ETH_BAR_2 0x2210 +#define MV64460_ETH_BAR_3 0x2218 +#define MV64460_ETH_BAR_4 0x2220 +#define MV64460_ETH_BAR_5 0x2228 +#define MV64460_ETH_SIZE_REG_0 0x2204 +#define MV64460_ETH_SIZE_REG_1 0x220c +#define MV64460_ETH_SIZE_REG_2 0x2214 +#define MV64460_ETH_SIZE_REG_3 0x221c +#define MV64460_ETH_SIZE_REG_4 0x2224 +#define MV64460_ETH_SIZE_REG_5 0x222c +#define MV64460_ETH_HEADERS_RETARGET_BASE_REG 0x2230 +#define MV64460_ETH_HEADERS_RETARGET_CONTROL_REG 0x2234 +#define MV64460_ETH_HIGH_ADDR_REMAP_REG_0 0x2280 +#define MV64460_ETH_HIGH_ADDR_REMAP_REG_1 0x2284 +#define MV64460_ETH_HIGH_ADDR_REMAP_REG_2 0x2288 +#define MV64460_ETH_HIGH_ADDR_REMAP_REG_3 0x228c +#define MV64460_ETH_BASE_ADDR_ENABLE_REG 0x2290 +#define MV64460_ETH_ACCESS_PROTECTION_REG(port) (0x2294 + (port<<2)) +#define MV64460_ETH_MIB_COUNTERS_BASE(port) (0x3000 + (port<<7)) +#define MV64460_ETH_PORT_CONFIG_REG(port) (0x2400 + (port<<10)) +#define MV64460_ETH_PORT_CONFIG_EXTEND_REG(port) (0x2404 + (port<<10)) +#define MV64460_ETH_MII_SERIAL_PARAMETRS_REG(port) (0x2408 + (port<<10)) +#define MV64460_ETH_GMII_SERIAL_PARAMETRS_REG(port) (0x240c + (port<<10)) +#define MV64460_ETH_VLAN_ETHERTYPE_REG(port) (0x2410 + (port<<10)) +#define MV64460_ETH_MAC_ADDR_LOW(port) (0x2414 + (port<<10)) +#define MV64460_ETH_MAC_ADDR_HIGH(port) (0x2418 + (port<<10)) +#define MV64460_ETH_SDMA_CONFIG_REG(port) (0x241c + (port<<10)) +#define MV64460_ETH_DSCP_0(port) (0x2420 + (port<<10)) +#define MV64460_ETH_DSCP_1(port) (0x2424 + (port<<10)) +#define MV64460_ETH_DSCP_2(port) (0x2428 + (port<<10)) +#define MV64460_ETH_DSCP_3(port) (0x242c + (port<<10)) +#define MV64460_ETH_DSCP_4(port) (0x2430 + (port<<10)) +#define MV64460_ETH_DSCP_5(port) (0x2434 + (port<<10)) +#define MV64460_ETH_DSCP_6(port) (0x2438 + (port<<10)) +#define MV64460_ETH_PORT_SERIAL_CONTROL_REG(port) (0x243c + (port<<10)) +#define MV64460_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port) (0x2440 + (port<<10)) +#define MV64460_ETH_PORT_STATUS_REG(port) (0x2444 + (port<<10)) +#define MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(port) (0x2448 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_FIXED_PRIORITY(port) (0x244c + (port<<10)) +#define MV64460_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port) (0x2450 + (port<<10)) +#define MV64460_ETH_MAXIMUM_TRANSMIT_UNIT(port) (0x2458 + (port<<10)) +#define MV64460_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port) (0x245c + (port<<10)) +#define MV64460_ETH_INTERRUPT_CAUSE_REG(port) (0x2460 + (port<<10)) +#define MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG(port) (0x2464 + (port<<10)) +#define MV64460_ETH_INTERRUPT_MASK_REG(port) (0x2468 + (port<<10)) +#define MV64460_ETH_INTERRUPT_EXTEND_MASK_REG(port) (0x246c + (port<<10)) +#define MV64460_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + (port<<10)) +#define MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + (port<<10)) +#define MV64460_ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (0x247c + (port<<10)) +#define MV64460_ETH_RX_DISCARDED_FRAMES_COUNTER(port) (0x2484 + (port<<10) +#define MV64460_ETH_PORT_DEBUG_0_REG(port) (0x248c + (port<<10)) +#define MV64460_ETH_PORT_DEBUG_1_REG(port) (0x2490 + (port<<10)) +#define MV64460_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + (port<<10)) +#define MV64460_ETH_INTERNAL_USE_REG(port) (0x24fc + (port<<10)) +#define MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(port) (0x2680 + (port<<10)) +#define MV64460_ETH_CURRENT_SERVED_TX_DESC_PTR(port) (0x2684 + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port) (0x260c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port) (0x261c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port) (0x262c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port) (0x263c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port) (0x264c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port) (0x265c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port) (0x266c + (port<<10)) +#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port) (0x267c + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port) (0x26c0 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port) (0x26c4 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port) (0x26c8 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port) (0x26cc + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port) (0x26d0 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port) (0x26d4 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port) (0x26d8 + (port<<10)) +#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port) (0x26dc + (port<<10)) +#define MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port) (0x2700 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port) (0x2710 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port) (0x2720 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port) (0x2730 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port) (0x2740 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port) (0x2750 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port) (0x2760 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port) (0x2770 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port) (0x2704 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port) (0x2714 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port) (0x2724 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port) (0x2734 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port) (0x2744 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port) (0x2754 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port) (0x2764 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port) (0x2774 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_0_ARBITER_CONFIG(port) (0x2708 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_1_ARBITER_CONFIG(port) (0x2718 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_2_ARBITER_CONFIG(port) (0x2728 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_3_ARBITER_CONFIG(port) (0x2738 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_4_ARBITER_CONFIG(port) (0x2748 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_5_ARBITER_CONFIG(port) (0x2758 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_6_ARBITER_CONFIG(port) (0x2768 + (port<<10)) +#define MV64460_ETH_TX_QUEUE_7_ARBITER_CONFIG(port) (0x2778 + (port<<10)) +#define MV64460_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port) (0x2780 + (port<<10)) +#define MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port) (0x3400 + (port<<10)) +#define MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10)) +#define MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10)) + +/*******************************************/ +/* CUNIT Registers */ +/*******************************************/ + + /* Address Decoding Register Map */ + +#define MV64460_CUNIT_BASE_ADDR_REG0 0xf200 +#define MV64460_CUNIT_BASE_ADDR_REG1 0xf208 +#define MV64460_CUNIT_BASE_ADDR_REG2 0xf210 +#define MV64460_CUNIT_BASE_ADDR_REG3 0xf218 +#define MV64460_CUNIT_SIZE0 0xf204 +#define MV64460_CUNIT_SIZE1 0xf20c +#define MV64460_CUNIT_SIZE2 0xf214 +#define MV64460_CUNIT_SIZE3 0xf21c +#define MV64460_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240 +#define MV64460_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244 +#define MV64460_CUNIT_BASE_ADDR_ENABLE_REG 0xf250 +#define MV64460_MPSC0_ACCESS_PROTECTION_REG 0xf254 +#define MV64460_MPSC1_ACCESS_PROTECTION_REG 0xf258 +#define MV64460_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C + + /* Error Report Registers */ + +#define MV64460_CUNIT_INTERRUPT_CAUSE_REG 0xf310 +#define MV64460_CUNIT_INTERRUPT_MASK_REG 0xf314 +#define MV64460_CUNIT_ERROR_ADDR 0xf318 + + /* Cunit Control Registers */ + +#define MV64460_CUNIT_ARBITER_CONTROL_REG 0xf300 +#define MV64460_CUNIT_CONFIG_REG 0xb40c +#define MV64460_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304 + + /* Cunit Debug Registers */ + +#define MV64460_CUNIT_DEBUG_LOW 0xf340 +#define MV64460_CUNIT_DEBUG_HIGH 0xf344 +#define MV64460_CUNIT_MMASK 0xf380 + + /* Cunit Base Address Enable Window Bits*/ +#define MV64460_CUNIT_BASE_ADDR_WIN_0_BIT 0x0 +#define MV64460_CUNIT_BASE_ADDR_WIN_1_BIT 0x1 +#define MV64460_CUNIT_BASE_ADDR_WIN_2_BIT 0x2 +#define MV64460_CUNIT_BASE_ADDR_WIN_3_BIT 0x3 + + /* MPSCs Clocks Routing Registers */ + +#define MV64460_MPSC_ROUTING_REG 0xb400 +#define MV64460_MPSC_RX_CLOCK_ROUTING_REG 0xb404 +#define MV64460_MPSC_TX_CLOCK_ROUTING_REG 0xb408 + + /* MPSCs Interrupts Registers */ + +#define MV64460_MPSC_CAUSE_REG(port) (0xb804 + (port<<3)) +#define MV64460_MPSC_MASK_REG(port) (0xb884 + (port<<3)) + +#define MV64460_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port<<12)) +#define MV64460_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port<<12)) +#define MV64460_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG1(port) (0x800c + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG2(port) (0x8010 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG3(port) (0x8014 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG4(port) (0x8018 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG5(port) (0x801c + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG6(port) (0x8020 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG7(port) (0x8024 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG8(port) (0x8028 + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG9(port) (0x802c + (port<<12)) +#define MV64460_MPSC_CHANNEL_REG10(port) (0x8030 + (port<<12)) + + /* MPSC0 Registers */ + + +/***************************************/ +/* SDMA Registers */ +/***************************************/ + +#define MV64460_SDMA_CONFIG_REG(channel) (0x4000 + (channel<<13)) +#define MV64460_SDMA_COMMAND_REG(channel) (0x4008 + (channel<<13)) +#define MV64460_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel<<13)) +#define MV64460_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel<<13)) +#define MV64460_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel<<13)) + +#define MV64460_SDMA_CAUSE_REG 0xb800 +#define MV64460_SDMA_MASK_REG 0xb880 + + +/****************************************/ +/* SDMA Address Space Targets */ +/****************************************/ + +#define MV64460_SDMA_DRAM_CS_0_TARGET 0x0e00 +#define MV64460_SDMA_DRAM_CS_1_TARGET 0x0d00 +#define MV64460_SDMA_DRAM_CS_2_TARGET 0x0b00 +#define MV64460_SDMA_DRAM_CS_3_TARGET 0x0700 + +#define MV64460_SDMA_DEV_CS_0_TARGET 0x1e01 +#define MV64460_SDMA_DEV_CS_1_TARGET 0x1d01 +#define MV64460_SDMA_DEV_CS_2_TARGET 0x1b01 +#define MV64460_SDMA_DEV_CS_3_TARGET 0x1701 + +#define MV64460_SDMA_BOOT_CS_TARGET 0x0f00 + +#define MV64460_SDMA_SRAM_TARGET 0x0003 +#define MV64460_SDMA_60X_BUS_TARGET 0x4003 + +#define MV64460_PCI_0_TARGET 0x0003 +#define MV64460_PCI_1_TARGET 0x0004 + + +/* Devices BAR and size registers */ + +#define MV64460_DEV_CS0_BASE_ADDR 0x028 +#define MV64460_DEV_CS0_SIZE 0x030 +#define MV64460_DEV_CS1_BASE_ADDR 0x228 +#define MV64460_DEV_CS1_SIZE 0x230 +#define MV64460_DEV_CS2_BASE_ADDR 0x248 +#define MV64460_DEV_CS2_SIZE 0x250 +#define MV64460_DEV_CS3_BASE_ADDR 0x038 +#define MV64460_DEV_CS3_SIZE 0x040 +#define MV64460_BOOTCS_BASE_ADDR 0x238 +#define MV64460_BOOTCS_SIZE 0x240 + +/* SDMA Window access protection */ +#define MV64460_SDMA_WIN_ACCESS_NOT_ALLOWED 0 +#define MV64460_SDMA_WIN_ACCESS_READ_ONLY 1 +#define MV64460_SDMA_WIN_ACCESS_FULL 2 + +/* BRG Interrupts */ + +#define MV64460_BRG_CONFIG_REG(brg) (0xb200 + (brg<<3)) +#define MV64460_BRG_BAUDE_TUNING_REG(brg) (0xb204 + (brg<<3)) +#define MV64460_BRG_CAUSE_REG 0xb834 +#define MV64460_BRG_MASK_REG 0xb8b4 + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define MV64460_DMA_CHANNEL0_CONTROL 0x840 +#define MV64460_DMA_CHANNEL0_CONTROL_HIGH 0x880 +#define MV64460_DMA_CHANNEL1_CONTROL 0x844 +#define MV64460_DMA_CHANNEL1_CONTROL_HIGH 0x884 +#define MV64460_DMA_CHANNEL2_CONTROL 0x848 +#define MV64460_DMA_CHANNEL2_CONTROL_HIGH 0x888 +#define MV64460_DMA_CHANNEL3_CONTROL 0x84C +#define MV64460_DMA_CHANNEL3_CONTROL_HIGH 0x88C + + +/****************************************/ +/* IDMA Registers */ +/****************************************/ + +#define MV64460_DMA_CHANNEL0_BYTE_COUNT 0x800 +#define MV64460_DMA_CHANNEL1_BYTE_COUNT 0x804 +#define MV64460_DMA_CHANNEL2_BYTE_COUNT 0x808 +#define MV64460_DMA_CHANNEL3_BYTE_COUNT 0x80C +#define MV64460_DMA_CHANNEL0_SOURCE_ADDR 0x810 +#define MV64460_DMA_CHANNEL1_SOURCE_ADDR 0x814 +#define MV64460_DMA_CHANNEL2_SOURCE_ADDR 0x818 +#define MV64460_DMA_CHANNEL3_SOURCE_ADDR 0x81c +#define MV64460_DMA_CHANNEL0_DESTINATION_ADDR 0x820 +#define MV64460_DMA_CHANNEL1_DESTINATION_ADDR 0x824 +#define MV64460_DMA_CHANNEL2_DESTINATION_ADDR 0x828 +#define MV64460_DMA_CHANNEL3_DESTINATION_ADDR 0x82C +#define MV64460_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830 +#define MV64460_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834 +#define MV64460_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838 +#define MV64460_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C +#define MV64460_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870 +#define MV64460_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874 +#define MV64460_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878 +#define MV64460_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C + + /* IDMA Address Decoding Base Address Registers */ + +#define MV64460_DMA_BASE_ADDR_REG0 0xa00 +#define MV64460_DMA_BASE_ADDR_REG1 0xa08 +#define MV64460_DMA_BASE_ADDR_REG2 0xa10 +#define MV64460_DMA_BASE_ADDR_REG3 0xa18 +#define MV64460_DMA_BASE_ADDR_REG4 0xa20 +#define MV64460_DMA_BASE_ADDR_REG5 0xa28 +#define MV64460_DMA_BASE_ADDR_REG6 0xa30 +#define MV64460_DMA_BASE_ADDR_REG7 0xa38 + + /* IDMA Address Decoding Size Address Register */ + +#define MV64460_DMA_SIZE_REG0 0xa04 +#define MV64460_DMA_SIZE_REG1 0xa0c +#define MV64460_DMA_SIZE_REG2 0xa14 +#define MV64460_DMA_SIZE_REG3 0xa1c +#define MV64460_DMA_SIZE_REG4 0xa24 +#define MV64460_DMA_SIZE_REG5 0xa2c +#define MV64460_DMA_SIZE_REG6 0xa34 +#define MV64460_DMA_SIZE_REG7 0xa3C + + /* IDMA Address Decoding High Address Remap and Access + Protection Registers */ + +#define MV64460_DMA_HIGH_ADDR_REMAP_REG0 0xa60 +#define MV64460_DMA_HIGH_ADDR_REMAP_REG1 0xa64 +#define MV64460_DMA_HIGH_ADDR_REMAP_REG2 0xa68 +#define MV64460_DMA_HIGH_ADDR_REMAP_REG3 0xa6C +#define MV64460_DMA_BASE_ADDR_ENABLE_REG 0xa80 +#define MV64460_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70 +#define MV64460_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74 +#define MV64460_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78 +#define MV64460_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c +#define MV64460_DMA_ARBITER_CONTROL 0x860 +#define MV64460_DMA_CROSS_BAR_TIMEOUT 0x8d0 + + /* IDMA Headers Retarget Registers */ + +#define MV64460_DMA_HEADERS_RETARGET_CONTROL 0xa84 +#define MV64460_DMA_HEADERS_RETARGET_BASE 0xa88 + + /* IDMA Interrupt Register */ + +#define MV64460_DMA_INTERRUPT_CAUSE_REG 0x8c0 +#define MV64460_DMA_INTERRUPT_CAUSE_MASK 0x8c4 +#define MV64460_DMA_ERROR_ADDR 0x8c8 +#define MV64460_DMA_ERROR_SELECT 0x8cc + + /* IDMA Debug Register ( for internal use ) */ + +#define MV64460_DMA_DEBUG_LOW 0x8e0 +#define MV64460_DMA_DEBUG_HIGH 0x8e4 +#define MV64460_DMA_SPARE 0xA8C + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define MV64460_TIMER_COUNTER0 0x850 +#define MV64460_TIMER_COUNTER1 0x854 +#define MV64460_TIMER_COUNTER2 0x858 +#define MV64460_TIMER_COUNTER3 0x85C +#define MV64460_TIMER_COUNTER_0_3_CONTROL 0x864 +#define MV64460_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define MV64460_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c + +/****************************************/ +/* Watchdog registers */ +/****************************************/ + +#define MV64460_WATCHDOG_CONFIG_REG 0xb410 +#define MV64460_WATCHDOG_VALUE_REG 0xb414 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define MV64460_I2C_SLAVE_ADDR 0xc000 +#define MV64460_I2C_EXTENDED_SLAVE_ADDR 0xc010 +#define MV64460_I2C_DATA 0xc004 +#define MV64460_I2C_CONTROL 0xc008 +#define MV64460_I2C_STATUS_BAUDE_RATE 0xc00C +#define MV64460_I2C_SOFT_RESET 0xc01c + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define MV64460_GPP_IO_CONTROL 0xf100 +#define MV64460_GPP_LEVEL_CONTROL 0xf110 +#define MV64460_GPP_VALUE 0xf104 +#define MV64460_GPP_INTERRUPT_CAUSE 0xf108 +#define MV64460_GPP_INTERRUPT_MASK0 0xf10c +#define MV64460_GPP_INTERRUPT_MASK1 0xf114 +#define MV64460_GPP_VALUE_SET 0xf118 +#define MV64460_GPP_VALUE_CLEAR 0xf11c + +/****************************************/ +/* Interrupt Controller Registers */ +/****************************************/ + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define MV64460_MAIN_INTERRUPT_CAUSE_LOW 0x004 +#define MV64460_MAIN_INTERRUPT_CAUSE_HIGH 0x00c +#define MV64460_CPU_INTERRUPT0_MASK_LOW 0x014 +#define MV64460_CPU_INTERRUPT0_MASK_HIGH 0x01c +#define MV64460_CPU_INTERRUPT0_SELECT_CAUSE 0x024 +#define MV64460_CPU_INTERRUPT1_MASK_LOW 0x034 +#define MV64460_CPU_INTERRUPT1_MASK_HIGH 0x03c +#define MV64460_CPU_INTERRUPT1_SELECT_CAUSE 0x044 +#define MV64460_INTERRUPT0_MASK_0_LOW 0x054 +#define MV64460_INTERRUPT0_MASK_0_HIGH 0x05c +#define MV64460_INTERRUPT0_SELECT_CAUSE 0x064 +#define MV64460_INTERRUPT1_MASK_0_LOW 0x074 +#define MV64460_INTERRUPT1_MASK_0_HIGH 0x07c +#define MV64460_INTERRUPT1_SELECT_CAUSE 0x084 + +/****************************************/ +/* MPP Interface Registers */ +/****************************************/ + +#define MV64460_MPP_CONTROL0 0xf000 +#define MV64460_MPP_CONTROL1 0xf004 +#define MV64460_MPP_CONTROL2 0xf008 +#define MV64460_MPP_CONTROL3 0xf00c + +/****************************************/ +/* Serial Initialization registers */ +/****************************************/ + +#define MV64460_SERIAL_INIT_LAST_DATA 0xf324 +#define MV64460_SERIAL_INIT_CONTROL 0xf328 +#define MV64460_SERIAL_INIT_STATUS 0xf32c + + +#endif /* __INCgt64460rh */ diff --git a/board/prodrive/p3mx/p3mx.c b/board/prodrive/p3mx/p3mx.c new file mode 100644 index 0000000..6cebd1a --- /dev/null +++ b/board/prodrive/p3mx/p3mx.c @@ -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); + +} diff --git a/board/prodrive/p3mx/pci.c b/board/prodrive/p3mx/pci.c new file mode 100644 index 0000000..137739b --- /dev/null +++ b/board/prodrive/p3mx/pci.c @@ -0,0 +1,1025 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +/* PCI.c - PCI functions */ + + +#include <common.h> +#ifdef CONFIG_PCI +#include <pci.h> + +#ifdef CONFIG_PCI_PNP +void pciauto_config_init(struct pci_controller *hose); +int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar); +#endif + +#include "../../Marvell/include/pci.h" + +#undef DEBUG +#undef IDE_SET_NATIVE_MODE +static unsigned int local_buses[] = { 0, 0 }; + +static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = { + {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 }, + {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 }, +}; + +#ifdef CONFIG_USE_CPCIDVI +typedef struct { + unsigned int base; + unsigned int init; +} GT_CPCIDVI_ROM_T; + +static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0}; +#endif + +#ifdef DEBUG +static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE }; +static void gt_pci_bus_mode_display (PCI_HOST host) +{ + unsigned int mode; + + + mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4; + switch (mode) { + case 0: + printf ("PCI %d bus mode: Conventional PCI\n", host); + break; + case 1: + printf ("PCI %d bus mode: 66 Mhz PCIX\n", host); + break; + case 2: + printf ("PCI %d bus mode: 100 Mhz PCIX\n", host); + break; + case 3: + printf ("PCI %d bus mode: 133 Mhz PCIX\n", host); + break; + default: + printf ("Unknown BUS %d\n", mode); + } +} +#endif + +static const unsigned int pci_p2p_configuration_reg[] = { + PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION +}; + +static const unsigned int pci_configuration_address[] = { + PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS +}; + +static const unsigned int pci_configuration_data[] = { + PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, + PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER +}; + +static const unsigned int pci_error_cause_reg[] = { + PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE +}; + +static const unsigned int pci_arbiter_control[] = { + PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL +}; + +static const unsigned int pci_address_space_en[] = { + PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE +}; + +static const unsigned int pci_snoop_control_base_0_low[] = { + PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW +}; +static const unsigned int pci_snoop_control_top_0[] = { + PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0 +}; + +static const unsigned int pci_access_control_base_0_low[] = { + PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW +}; +static const unsigned int pci_access_control_top_0[] = { + PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0 +}; + +static const unsigned int pci_scs_bank_size[2][4] = { + {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE, + PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE}, + {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE, + PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE} +}; + +static const unsigned int pci_p2p_configuration[] = { + PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION +}; + + +/******************************************************************** +* pciWriteConfigReg - Write to a PCI configuration register +* - Make sure the GT is configured as a master before writing +* to another device on the PCI. +* - The function takes care of Big/Little endian conversion. +* +* +* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec +* (or any other PCI device spec) +* pciDevNum: The device number needs to be addressed. +* +* Configuration Address 0xCF8: +* +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* |congif|Reserved| Bus |Device|Function|Register|00| +* |Enable| |Number|Number| Number | Number | | <=field Name +* +*********************************************************************/ +void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset, + unsigned int pciDevNum, unsigned int data) +{ + volatile unsigned int DataForAddrReg; + unsigned int functionNum; + unsigned int busNum = 0; + unsigned int addr; + + if (pciDevNum > 32) /* illegal device Number */ + return; + if (pciDevNum == SELF) { /* configure our configuration space. */ + pciDevNum = + (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) & + 0x1f; + busNum = GTREGREAD (pci_p2p_configuration_reg[host]) & + 0xff0000; + } + functionNum = regOffset & 0x00000700; + pciDevNum = pciDevNum << 11; + regOffset = regOffset & 0xfc; + DataForAddrReg = + (regOffset | pciDevNum | functionNum | busNum) | BIT31; + GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg); + GT_REG_READ (pci_configuration_address[host], &addr); + if (addr != DataForAddrReg) + return; + GT_REG_WRITE (pci_configuration_data[host], data); +} + +/******************************************************************** +* pciReadConfigReg - Read from a PCI0 configuration register +* - Make sure the GT is configured as a master before reading +* from another device on the PCI. +* - The function takes care of Big/Little endian conversion. +* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI +* spec) +* pciDevNum: The device number needs to be addressed. +* RETURNS: data , if the data == 0xffffffff check the master abort bit in the +* cause register to make sure the data is valid +* +* Configuration Address 0xCF8: +* +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* |congif|Reserved| Bus |Device|Function|Register|00| +* |Enable| |Number|Number| Number | Number | | <=field Name +* +*********************************************************************/ +unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset, + unsigned int pciDevNum) +{ + volatile unsigned int DataForAddrReg; + unsigned int data; + unsigned int functionNum; + unsigned int busNum = 0; + + if (pciDevNum > 32) /* illegal device Number */ + return 0xffffffff; + if (pciDevNum == SELF) { /* configure our configuration space. */ + pciDevNum = + (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) & + 0x1f; + busNum = GTREGREAD (pci_p2p_configuration_reg[host]) & + 0xff0000; + } + functionNum = regOffset & 0x00000700; + pciDevNum = pciDevNum << 11; + regOffset = regOffset & 0xfc; + DataForAddrReg = + (regOffset | pciDevNum | functionNum | busNum) | BIT31; + GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg); + GT_REG_READ (pci_configuration_address[host], &data); + if (data != DataForAddrReg) + return 0xffffffff; + GT_REG_READ (pci_configuration_data[host], &data); + return data; +} + +/******************************************************************** +* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where +* the agent is placed on another Bus. For more +* information read P2P in the PCI spec. +* +* Inputs: unsigned int regOffset - The register offset as it apears in the +* GT spec (or any other PCI device spec). +* unsigned int pciDevNum - The device number needs to be addressed. +* unsigned int busNum - On which bus does the Target agent connect +* to. +* unsigned int data - data to be written. +* +* Configuration Address 0xCF8: +* +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* |congif|Reserved| Bus |Device|Function|Register|01| +* |Enable| |Number|Number| Number | Number | | <=field Name +* +* The configuration Address is configure as type-I (bits[1:0] = '01') due to +* PCI spec referring to P2P. +* +*********************************************************************/ +void pciOverBridgeWriteConfigReg (PCI_HOST host, + unsigned int regOffset, + unsigned int pciDevNum, + unsigned int busNum, unsigned int data) +{ + unsigned int DataForReg; + unsigned int functionNum; + + functionNum = regOffset & 0x00000700; + pciDevNum = pciDevNum << 11; + regOffset = regOffset & 0xff; + busNum = busNum << 16; + if (pciDevNum == SELF) { /* This board */ + DataForReg = (regOffset | pciDevNum | functionNum) | BIT0; + } else { + DataForReg = (regOffset | pciDevNum | functionNum | busNum) | + BIT31 | BIT0; + } + GT_REG_WRITE (pci_configuration_address[host], DataForReg); + GT_REG_WRITE (pci_configuration_data[host], data); +} + + +/******************************************************************** +* pciOverBridgeReadConfigReg - Read from a PCIn configuration register where +* the agent target locate on another PCI bus. +* - Make sure the GT is configured as a master +* before reading from another device on the PCI. +* - The function takes care of Big/Little endian +* conversion. +* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI +* spec). (configuration register offset.) +* pciDevNum: The device number needs to be addressed. +* busNum: the Bus number where the agent is place. +* RETURNS: data , if the data == 0xffffffff check the master abort bit in the +* cause register to make sure the data is valid +* +* Configuration Address 0xCF8: +* +* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number +* |congif|Reserved| Bus |Device|Function|Register|01| +* |Enable| |Number|Number| Number | Number | | <=field Name +* +*********************************************************************/ +unsigned int pciOverBridgeReadConfigReg (PCI_HOST host, + unsigned int regOffset, + unsigned int pciDevNum, + unsigned int busNum) +{ + unsigned int DataForReg; + unsigned int data; + unsigned int functionNum; + + functionNum = regOffset & 0x00000700; + pciDevNum = pciDevNum << 11; + regOffset = regOffset & 0xff; + busNum = busNum << 16; + if (pciDevNum == SELF) { /* This board */ + DataForReg = (regOffset | pciDevNum | functionNum) | BIT31; + } else { /* agent on another bus */ + + DataForReg = (regOffset | pciDevNum | functionNum | busNum) | + BIT0 | BIT31; + } + GT_REG_WRITE (pci_configuration_address[host], DataForReg); + GT_REG_READ (pci_configuration_data[host], &data); + return data; +} + + +/******************************************************************** +* pciGetRegOffset - Gets the register offset for this region config. +* +* INPUT: Bus, Region - The bus and region we ask for its base address. +* OUTPUT: N/A +* RETURNS: PCI register base address +*********************************************************************/ +static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region) +{ + switch (host) { + case PCI_HOST0: + switch (region) { + case PCI_IO: + return PCI_0I_O_LOW_DECODE_ADDRESS; + case PCI_REGION0: + return PCI_0MEMORY0_LOW_DECODE_ADDRESS; + case PCI_REGION1: + return PCI_0MEMORY1_LOW_DECODE_ADDRESS; + case PCI_REGION2: + return PCI_0MEMORY2_LOW_DECODE_ADDRESS; + case PCI_REGION3: + return PCI_0MEMORY3_LOW_DECODE_ADDRESS; + } + case PCI_HOST1: + switch (region) { + case PCI_IO: + return PCI_1I_O_LOW_DECODE_ADDRESS; + case PCI_REGION0: + return PCI_1MEMORY0_LOW_DECODE_ADDRESS; + case PCI_REGION1: + return PCI_1MEMORY1_LOW_DECODE_ADDRESS; + case PCI_REGION2: + return PCI_1MEMORY2_LOW_DECODE_ADDRESS; + case PCI_REGION3: + return PCI_1MEMORY3_LOW_DECODE_ADDRESS; + } + } + return PCI_0MEMORY0_LOW_DECODE_ADDRESS; +} + +static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region) +{ + switch (host) { + case PCI_HOST0: + switch (region) { + case PCI_IO: + return PCI_0I_O_ADDRESS_REMAP; + case PCI_REGION0: + return PCI_0MEMORY0_ADDRESS_REMAP; + case PCI_REGION1: + return PCI_0MEMORY1_ADDRESS_REMAP; + case PCI_REGION2: + return PCI_0MEMORY2_ADDRESS_REMAP; + case PCI_REGION3: + return PCI_0MEMORY3_ADDRESS_REMAP; + } + case PCI_HOST1: + switch (region) { + case PCI_IO: + return PCI_1I_O_ADDRESS_REMAP; + case PCI_REGION0: + return PCI_1MEMORY0_ADDRESS_REMAP; + case PCI_REGION1: + return PCI_1MEMORY1_ADDRESS_REMAP; + case PCI_REGION2: + return PCI_1MEMORY2_ADDRESS_REMAP; + case PCI_REGION3: + return PCI_1MEMORY3_ADDRESS_REMAP; + } + } + return PCI_0MEMORY0_ADDRESS_REMAP; +} + +/******************************************************************** +* pciGetBaseAddress - Gets the base address of a PCI. +* - If the PCI size is 0 then this base address has no meaning!!! +* +* +* INPUT: Bus, Region - The bus and region we ask for its base address. +* OUTPUT: N/A +* RETURNS: PCI base address. +*********************************************************************/ +unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region) +{ + unsigned int regBase; + unsigned int regEnd; + unsigned int regOffset = pciGetRegOffset (host, region); + + GT_REG_READ (regOffset, ®Base); + GT_REG_READ (regOffset + 8, ®End); + + if (regEnd <= regBase) + return 0xffffffff; /* ERROR !!! */ + + regBase = regBase << 16; + return regBase; +} + +bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase, + unsigned int bankBase, unsigned int bankLength) +{ + unsigned int low = 0xfff; + unsigned int high = 0x0; + unsigned int regOffset = pciGetRegOffset (host, region); + unsigned int remapOffset = pciGetRemapOffset (host, region); + + if (bankLength != 0) { + low = (bankBase >> 16) & 0xffff; + high = ((bankBase + bankLength) >> 16) - 1; + } + + GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */ + GT_REG_WRITE (regOffset + 8, high); + + if (bankLength != 0) { /* must do AFTER writing maps */ + GT_REG_WRITE (remapOffset, remapBase >> 16); /* sorry, 32 bits only. + dont support upper 32 + in this driver */ + } + return true; +} + +unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region) +{ + unsigned int low; + unsigned int regOffset = pciGetRegOffset (host, region); + + GT_REG_READ (regOffset, &low); + return (low & 0xffff) << 16; +} + +unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region) +{ + unsigned int low, high; + unsigned int regOffset = pciGetRegOffset (host, region); + + GT_REG_READ (regOffset, &low); + GT_REG_READ (regOffset + 8, &high); + return ((high & 0xffff) + 1) << 16; +} + + +/* ronen - 7/Dec/03*/ +/******************************************************************** +* gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS. +* Inputs: one of the PCI BAR +*********************************************************************/ +void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR) +{ + RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR); +} + +void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR) +{ + SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR); +} + +/******************************************************************** +* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave. +* +* Inputs: base and size of PCI SCS +*********************************************************************/ +void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank, + unsigned int pciDramBase, unsigned int pciDramSize) +{ + /*ronen different function for 3rd bank. */ + unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8; + + pciDramBase = pciDramBase & 0xfffff000; + pciDramBase = pciDramBase | (pciReadConfigReg (host, + PCI_SCS_0_BASE_ADDRESS + + offset, + SELF) & 0x00000fff); + pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF, + pciDramBase); + if (pciDramSize == 0) + pciDramSize++; + GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1); + gtPciEnableInternalBAR (host, bank); +} + +/******************************************************************** +* pciSetRegionFeatures - This function modifys one of the 8 regions with +* feature bits given as an input. +* - Be advised to check the spec before modifying them. +* Inputs: PCI_PROTECT_REGION region - one of the eight regions. +* unsigned int features - See file: pci.h there are defintion for those +* region features. +* unsigned int baseAddress - The region base Address. +* unsigned int topAddress - The region top Address. +* Returns: false if one of the parameters is erroneous true otherwise. +*********************************************************************/ +bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region, + unsigned int features, unsigned int baseAddress, + unsigned int regionLength) +{ + unsigned int accessLow; + unsigned int accessHigh; + unsigned int accessTop = baseAddress + regionLength; + + if (regionLength == 0) { /* close the region. */ + pciDisableAccessRegion (host, region); + return true; + } + /* base Address is store is bits [11:0] */ + accessLow = (baseAddress & 0xfff00000) >> 20; + /* All the features are update according to the defines in pci.h (to be on + the safe side we disable bits: [11:0] */ + accessLow = accessLow | (features & 0xfffff000); + /* write to the Low Access Region register */ + GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region, + accessLow); + + accessHigh = (accessTop & 0xfff00000) >> 20; + + /* write to the High Access Region register */ + GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, + accessHigh - 1); + return true; +} + +/******************************************************************** +* pciDisableAccessRegion - Disable The given Region by writing MAX size +* to its low Address and MIN size to its high Address. +* +* Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled. +* Returns: N/A. +*********************************************************************/ +void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region) +{ + /* writing back the registers default values. */ + GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region, + 0x01001fff); + GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0); +} + +/******************************************************************** +* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism. +* +* Inputs: N/A +* Returns: true. +*********************************************************************/ +bool pciArbiterEnable (PCI_HOST host) +{ + unsigned int regData; + + GT_REG_READ (pci_arbiter_control[host], ®Data); + GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31); + return true; +} + +/******************************************************************** +* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism. +* +* Inputs: N/A +* Returns: true +*********************************************************************/ +bool pciArbiterDisable (PCI_HOST host) +{ + unsigned int regData; + + GT_REG_READ (pci_arbiter_control[host], ®Data); + GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff); + return true; +} + +/******************************************************************** +* pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low) +* +* Inputs: PCI_AGENT_PRIO internalAgent - priotity for internal agent. +* PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent. +* PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent. +* PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent. +* PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent. +* PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent. +* PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent. +* Returns: true +*********************************************************************/ +bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent, + PCI_AGENT_PRIO externalAgent0, + PCI_AGENT_PRIO externalAgent1, + PCI_AGENT_PRIO externalAgent2, + PCI_AGENT_PRIO externalAgent3, + PCI_AGENT_PRIO externalAgent4, + PCI_AGENT_PRIO externalAgent5) +{ + unsigned int regData; + unsigned int writeData; + + GT_REG_READ (pci_arbiter_control[host], ®Data); + writeData = (internalAgent << 7) + (externalAgent0 << 8) + + (externalAgent1 << 9) + (externalAgent2 << 10) + + (externalAgent3 << 11) + (externalAgent4 << 12) + + (externalAgent5 << 13); + regData = (regData & 0xffffc07f) | writeData; + GT_REG_WRITE (pci_arbiter_control[host], regData & regData); + return true; +} + +/******************************************************************** +* pciParkingDisable - Park on last option disable, with this function you can +* disable the park on last mechanism for each agent. +* disabling this option for all agents results parking +* on the internal master. +* +* Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent. +* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent. +* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent. +* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent. +* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent. +* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent. +* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent. +* Returns: true +*********************************************************************/ +bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent, + PCI_AGENT_PARK externalAgent0, + PCI_AGENT_PARK externalAgent1, + PCI_AGENT_PARK externalAgent2, + PCI_AGENT_PARK externalAgent3, + PCI_AGENT_PARK externalAgent4, + PCI_AGENT_PARK externalAgent5) +{ + unsigned int regData; + unsigned int writeData; + + GT_REG_READ (pci_arbiter_control[host], ®Data); + writeData = (internalAgent << 14) + (externalAgent0 << 15) + + (externalAgent1 << 16) + (externalAgent2 << 17) + + (externalAgent3 << 18) + (externalAgent4 << 19) + + (externalAgent5 << 20); + regData = (regData & ~(0x7f << 14)) | writeData; + GT_REG_WRITE (pci_arbiter_control[host], regData); + return true; +} + +/******************************************************************** +* pciEnableBrokenAgentDetection - A master is said to be broken if it fails to +* respond to grant assertion within a window specified in +* the input value: 'brokenValue'. +* +* Inputs: unsigned char brokenValue - A value which limits the Master to hold the +* grant without asserting frame. +* Returns: Error for illegal broken value otherwise true. +*********************************************************************/ +bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue) +{ + unsigned int data; + unsigned int regData; + + if (brokenValue > 0xf) + return false; /* brokenValue must be 4 bit */ + data = brokenValue << 3; + GT_REG_READ (pci_arbiter_control[host], ®Data); + regData = (regData & 0xffffff87) | data; + GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1); + return true; +} + +/******************************************************************** +* pciDisableBrokenAgentDetection - This function disable the Broken agent +* Detection mechanism. +* NOTE: This operation may cause a dead lock on the +* pci0 arbitration. +* +* Inputs: N/A +* Returns: true. +*********************************************************************/ +bool pciDisableBrokenAgentDetection (PCI_HOST host) +{ + unsigned int regData; + + GT_REG_READ (pci_arbiter_control[host], ®Data); + regData = regData & 0xfffffffd; + GT_REG_WRITE (pci_arbiter_control[host], regData); + return true; +} + +/******************************************************************** +* pciP2PConfig - This function set the PCI_n P2P configurate. +* For more information on the P2P read PCI spec. +* +* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower +* Boundry. +* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper +* Boundry. +* unsigned int busNum - The CPI bus number to which the PCI interface +* is connected. +* unsigned int devNum - The PCI interface's device number. +* +* Returns: true. +*********************************************************************/ +bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow, + unsigned int SecondBusHigh, + unsigned int busNum, unsigned int devNum) +{ + unsigned int regData; + + regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | + ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); + GT_REG_WRITE (pci_p2p_configuration[host], regData); + return true; +} + +/******************************************************************** +* pciSetRegionSnoopMode - This function modifys one of the 4 regions which +* supports Cache Coherency in the PCI_n interface. +* Inputs: region - One of the four regions. +* snoopType - There is four optional Types: +* 1. No Snoop. +* 2. Snoop to WT region. +* 3. Snoop to WB region. +* 4. Snoop & Invalidate to WB region. +* baseAddress - Base Address of this region. +* regionLength - Region length. +* Returns: false if one of the parameters is wrong otherwise return true. +*********************************************************************/ +bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region, + PCI_SNOOP_TYPE snoopType, + unsigned int baseAddress, + unsigned int regionLength) +{ + unsigned int snoopXbaseAddress; + unsigned int snoopXtopAddress; + unsigned int data; + unsigned int snoopHigh = baseAddress + regionLength; + + if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB)) + return false; + snoopXbaseAddress = + pci_snoop_control_base_0_low[host] + 0x10 * region; + snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region; + if (regionLength == 0) { /* closing the region */ + GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff); + GT_REG_WRITE (snoopXtopAddress, 0); + return true; + } + baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */ + data = (baseAddress >> 20) | snoopType << 12; + GT_REG_WRITE (snoopXbaseAddress, data); + snoopHigh = (snoopHigh & 0xfff00000) >> 20; + GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1); + return true; +} + +static int gt_read_config_dword (struct pci_controller *hose, + pci_dev_t dev, int offset, u32 * value) +{ + int bus = PCI_BUS (dev); + + if ((bus == local_buses[0]) || (bus == local_buses[1])) { + *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset, + PCI_DEV (dev)); + } else { + *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose-> + cfg_addr, offset, + PCI_DEV (dev), bus); + } + + return 0; +} + +static int gt_write_config_dword (struct pci_controller *hose, + pci_dev_t dev, int offset, u32 value) +{ + int bus = PCI_BUS (dev); + + if ((bus == local_buses[0]) || (bus == local_buses[1])) { + pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset, + PCI_DEV (dev), value); + } else { + pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr, + offset, PCI_DEV (dev), bus, + value); + } + return 0; +} + + +static void gt_setup_ide (struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *entry) +{ + static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 }; + u32 bar_response, bar_value; + int bar; + + for (bar = 0; bar < 6; bar++) { + /*ronen different function for 3rd bank. */ + unsigned int offset = + (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8; + + pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset, + 0x0); + pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset, + &bar_response); + + pciauto_region_allocate (bar_response & + PCI_BASE_ADDRESS_SPACE_IO ? hose-> + pci_io : hose->pci_mem, ide_bar[bar], + &bar_value); + + pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + bar * 4, + bar_value); + } +} + +#ifdef CONFIG_USE_CPCIDVI +static void gt_setup_cpcidvi (struct pci_controller *hose, + pci_dev_t dev, struct pci_config_table *entry) +{ + u32 bar_value, pci_response; + + pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response); + pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff); + pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pci_response); + pciauto_region_allocate (hose->pci_mem, 0x01000000, &bar_value); + pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, (bar_value & 0xffffff00)); + pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, 0x0); + pciauto_region_allocate (hose->pci_mem, 0x40000, &bar_value); + pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, (bar_value & 0xffffff00) | 0x01); + gt_cpcidvi_rom.base = bar_value & 0xffffff00; + gt_cpcidvi_rom.init = 1; +} + +unsigned char gt_cpcidvi_in8(unsigned int offset) +{ + unsigned char data; + + if (gt_cpcidvi_rom.init == 0) { + return(0); + } + data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base); + return(data); +} + +void gt_cpcidvi_out8(unsigned int offset, unsigned char data) +{ + unsigned int off; + + if (gt_cpcidvi_rom.init == 0) { + return; + } + off = data; + off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base; + in8(off); + return; +} +#endif + +/* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */ +/* and is curently not called *. */ +#if 0 +static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev) +{ + unsigned char pin, irq; + + pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin); + + if (pin == 1) { /* only allow INT A */ + irq = pci_irq_swizzle[(PCI_HOST) hose-> + cfg_addr][PCI_DEV (dev)]; + if (irq) + pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq); + } +} +#endif + +struct pci_config_table gt_config_table[] = { +#ifdef CONFIG_USE_CPCIDVI + {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030, PCI_CLASS_DISPLAY_VGA, + PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_cpcidvi}, +#endif + {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, + PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide}, + {} +}; + +struct pci_controller pci0_hose = { +/* fixup_irq: gt_fixup_irq, */ + config_table:gt_config_table, +}; + +struct pci_controller pci1_hose = { +/* fixup_irq: gt_fixup_irq, */ + config_table:gt_config_table, +}; + +void pci_init_board (void) +{ + unsigned int command; +#ifdef CONFIG_PCI_PNP + unsigned int bar; +#endif +#ifdef DEBUG + gt_pci_bus_mode_display (PCI_HOST0); +#endif +#ifdef CONFIG_USE_CPCIDVI + gt_cpcidvi_rom.init = 0; + gt_cpcidvi_rom.base = 0; +#endif + + pci0_hose.config_table = gt_config_table; + pci1_hose.config_table = gt_config_table; + +#ifdef CONFIG_USE_CPCIDVI + gt_config_table[0].config_device = gt_setup_cpcidvi; +#endif + gt_config_table[1].config_device = gt_setup_ide; + + pci0_hose.first_busno = 0; + pci0_hose.last_busno = 0xff; + local_buses[0] = pci0_hose.first_busno; + + /* PCI memory space */ + pci_set_region (pci0_hose.regions + 0, + CFG_PCI0_0_MEM_SPACE, + CFG_PCI0_0_MEM_SPACE, + CFG_PCI0_MEM_SIZE, PCI_REGION_MEM); + + /* PCI I/O space */ + pci_set_region (pci0_hose.regions + 1, + CFG_PCI0_IO_SPACE_PCI, + CFG_PCI0_IO_SPACE, CFG_PCI0_IO_SIZE, PCI_REGION_IO); + + pci_set_ops (&pci0_hose, + pci_hose_read_config_byte_via_dword, + pci_hose_read_config_word_via_dword, + gt_read_config_dword, + pci_hose_write_config_byte_via_dword, + pci_hose_write_config_word_via_dword, + gt_write_config_dword); + pci0_hose.region_count = 2; + + pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0; + + pci_register_hose (&pci0_hose); + pciArbiterDisable(PCI_HOST0); /* on PMC modules no arbiter is used */ + pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1); + command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF); + command |= PCI_COMMAND_MASTER; + pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command); + command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF); + command |= PCI_COMMAND_MEMORY; + pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command); + +#ifdef CONFIG_PCI_PNP + pciauto_config_init(&pci0_hose); + pciauto_region_allocate(pci0_hose.pci_io, 0x400, &bar); +#endif +#ifdef CONFIG_PCI_SCAN_SHOW + printf("PCI: Bus Dev VenId DevId Class Int\n"); +#endif + pci0_hose.last_busno = pci_hose_scan_bus (&pci0_hose, pci0_hose.first_busno); + +#ifdef DEBUG + gt_pci_bus_mode_display (PCI_HOST1); +#endif + pci1_hose.first_busno = pci0_hose.last_busno + 1; + pci1_hose.last_busno = 0xff; + pci1_hose.current_busno = pci1_hose.first_busno; + local_buses[1] = pci1_hose.first_busno; + + /* PCI memory space */ + pci_set_region (pci1_hose.regions + 0, + CFG_PCI1_0_MEM_SPACE, + CFG_PCI1_0_MEM_SPACE, + CFG_PCI1_MEM_SIZE, PCI_REGION_MEM); + + /* PCI I/O space */ + pci_set_region (pci1_hose.regions + 1, + CFG_PCI1_IO_SPACE_PCI, + CFG_PCI1_IO_SPACE, CFG_PCI1_IO_SIZE, PCI_REGION_IO); + + pci_set_ops (&pci1_hose, + pci_hose_read_config_byte_via_dword, + pci_hose_read_config_word_via_dword, + gt_read_config_dword, + pci_hose_write_config_byte_via_dword, + pci_hose_write_config_word_via_dword, + gt_write_config_dword); + + pci1_hose.region_count = 2; + + pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1; + + pci_register_hose (&pci1_hose); + + pciArbiterEnable (PCI_HOST1); + pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1); + + command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF); + command |= PCI_COMMAND_MASTER; + pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command); + +#ifdef CONFIG_PCI_PNP + pciauto_config_init(&pci1_hose); + pciauto_region_allocate(pci1_hose.pci_io, 0x400, &bar); +#endif + pci1_hose.last_busno = pci_hose_scan_bus (&pci1_hose, pci1_hose.first_busno); + + command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF); + command |= PCI_COMMAND_MEMORY; + pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command); + +} +#endif /* of CONFIG_PCI */ diff --git a/board/prodrive/p3mx/ppc_error_no.h b/board/prodrive/p3mx/ppc_error_no.h new file mode 100644 index 0000000..53687c8 --- /dev/null +++ b/board/prodrive/p3mx/ppc_error_no.h @@ -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 diff --git a/board/prodrive/p3mx/sdram_init.c b/board/prodrive/p3mx/sdram_init.c new file mode 100644 index 0000000..176252e --- /dev/null +++ b/board/prodrive/p3mx/sdram_init.c @@ -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); +} diff --git a/board/prodrive/p3mx/serial.c b/board/prodrive/p3mx/serial.c new file mode 100644 index 0000000..ba32ac1 --- /dev/null +++ b/board/prodrive/p3mx/serial.c @@ -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 */ diff --git a/board/prodrive/p3mx/serial.h b/board/prodrive/p3mx/serial.h new file mode 100644 index 0000000..c7fc8c1 --- /dev/null +++ b/board/prodrive/p3mx/serial.h @@ -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__ */ diff --git a/board/prodrive/p3mx/u-boot.lds b/board/prodrive/p3mx/u-boot.lds new file mode 100644 index 0000000..d89eb6c --- /dev/null +++ b/board/prodrive/p3mx/u-boot.lds @@ -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 = .); +} diff --git a/board/tqm834x/pci.c b/board/tqm834x/pci.c index 5a23e6c..d896f17 100644 --- a/board/tqm834x/pci.c +++ b/board/tqm834x/pci.c @@ -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); diff --git a/board/tqm834x/tqm834x.c b/board/tqm834x/tqm834x.c index 41b34cc..36d901f 100644 --- a/board/tqm834x/tqm834x.c +++ b/board/tqm834x/tqm834x.c @@ -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; diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 1d92bb3..0e3d56f 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -79,7 +79,7 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * be either an ELF image or a raw binary. Will attempt to setup the * bootline and other parameters correctly. * ====================================================================== */ -int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { unsigned long addr; /* Address of image */ unsigned long bootaddr; /* Address to put the bootline */ @@ -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 */ diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index c543bb5..45cfde2 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -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 @@ -151,7 +174,7 @@ int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ addr = simple_strtoul(argv[2], NULL, 16); alen = 1; - for(j = 0; j < 8; j++) { + for (j = 0; j < 8; j++) { if (argv[2][j] == '.') { alen = argv[2][j+1] - '0'; if (alen > 4) { @@ -159,9 +182,8 @@ 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; - } } /* @@ -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++) { @@ -256,17 +278,16 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ addr = simple_strtoul(argv[2], NULL, 16); alen = 1; - for(j = 0; j < 8; j++) { + for (j = 0; j < 8; j++) { if (argv[2][j] == '.') { alen = argv[2][j+1] - '0'; - if(alen > 4) { + if (alen > 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } break; - } else if (argv[2][j] == '\0') { + } else if (argv[2][j] == '\0') break; - } } /* @@ -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). @@ -303,9 +322,9 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif #if 0 - for(timeout = 0; timeout < 10; timeout++) { + for (timeout = 0; timeout < 10; timeout++) { udelay(2000); - if(i2c_probe(chip) == 0) + if (i2c_probe(chip) == 0) break; } #endif @@ -346,17 +365,16 @@ int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ addr = simple_strtoul(argv[2], NULL, 16); alen = 1; - for(j = 0; j < 8; j++) { + for (j = 0; j < 8; j++) { if (argv[2][j] == '.') { alen = argv[2][j+1] - '0'; - if(alen > 4) { + if (alen > 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } break; - } else if (argv[2][j] == '\0') { + } else if (argv[2][j] == '\0') break; - } } /* @@ -371,19 +389,16 @@ 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) { + while (count-- > 0) { + if (i2c_read(chip, addr, alen, &byte, 1) != 0) err++; - } crc = crc32 (crc, &byte, 1); addr++; } - if(err > 0) - { + if (err > 0) puts ("Error reading the chip,\n"); - } else { + else printf ("%08lx\n", crc); - } return 0; } @@ -441,17 +456,16 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) */ addr = simple_strtoul(argv[2], NULL, 16); alen = 1; - for(j = 0; j < 8; j++) { + for (j = 0; j < 8; j++) { if (argv[2][j] == '.') { alen = argv[2][j+1] - '0'; - if(alen > 4) { + if (alen > 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } break; - } else if (argv[2][j] == '\0') { + } else if (argv[2][j] == '\0') break; - } } } @@ -461,17 +475,16 @@ 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 (" ? "); @@ -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++) { + 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 @@ -601,7 +613,7 @@ int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ addr = simple_strtoul(argv[2], NULL, 16); alen = 1; - for(j = 0; j < 8; j++) { + for (j = 0; j < 8; j++) { if (argv[2][j] == '.') { alen = argv[2][j+1] - '0'; if (alen > 4) { @@ -609,9 +621,8 @@ 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; - } } /* @@ -619,24 +630,21 @@ int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ 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) { + while (1) { + if (i2c_read(chip, addr, alen, bytes, length) != 0) puts ("Error reading the chip.\n"); - } udelay(delay); } @@ -671,7 +679,7 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ chip = simple_strtoul(argv[1], NULL, 16); - if(i2c_read(chip, 0, 1, data, sizeof(data)) != 0) { + if (i2c_read(chip, 0, 1, data, sizeof(data)) != 0) { puts ("No SDRAM Serial Presence Detect found.\n"); return 1; } @@ -680,7 +688,7 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) for (j = 0; j < 63; j++) { cksum += data[j]; } - if(cksum != data[63]) { + if (cksum != data[63]) { printf ("WARNING: Configuration data checksum failure:\n" " is 0x%02x, calculated 0x%02x\n", data[63], cksum); @@ -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; @@ -744,17 +749,16 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) default: puts ("unknown\n"); break; } printf("SDRAM width (primary) %d\n", data[13] & 0x7F); - if((data[13] & 0x80) != 0) { + if ((data[13] & 0x80) != 0) { printf(" (second bank) %d\n", 2 * (data[13] & 0x7F)); } - if(data[14] != 0) { + 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]); @@ -852,18 +856,18 @@ int do_sdram ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) (data[35] & 0x80) ? '-' : '+', (data[35] >> 4) & 0x07, data[35] & 0x0F); puts ("Manufacturer's JEDEC ID "); - for(j = 64; j <= 71; j++) + for (j = 64; j <= 71; j++) printf("%02X ", data[j]); putc ('\n'); printf("Manufacturing Location %02X\n", data[72]); puts ("Manufacturer's Part Number "); - for(j = 73; j <= 90; j++) + for (j = 73; j <= 90; j++) printf("%02X ", data[j]); putc ('\n'); printf("Revision Code %02X %02X\n", data[91], data[92]); printf("Manufacturing Date %02X %02X\n", data[93], data[94]); puts ("Assembly Serial Number "); - for(j = 95; j <= 98; j++) + for (j = 95; j <= 98; j++) printf("%02X ", data[j]); putc ('\n'); printf("Speed rating PC%d\n", @@ -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 */ diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 7286726..b011b5e 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -684,178 +684,182 @@ extern int nand_write_oob(struct nand_chip *nand, size_t ofs, size_t len, size_t *retlen, const u_char *buf); -int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - int rcode = 0; - - switch (argc) { - case 0: - case 1: - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 2: - if (strcmp(argv[1],"info") == 0) { - int i; + int rcode = 0; - putc ('\n'); + switch (argc) { + case 0: + case 1: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + case 2: + if (strcmp (argv[1], "info") == 0) { + int i; - for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) { - if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) - continue; /* list only known devices */ - printf ("Device %d: ", i); - nand_print(&nand_dev_desc[i]); - } - return 0; + putc ('\n'); - } else if (strcmp(argv[1],"device") == 0) { - if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d: ", curr_device); - nand_print(&nand_dev_desc[curr_device]); - return 0; + for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) { + if (nand_dev_desc[i].ChipID == + NAND_ChipID_UNKNOWN) + continue; /* list only known devices */ + printf ("Device %d: ", i); + nand_print (&nand_dev_desc[i]); + } + return 0; - } else if (strcmp(argv[1],"bad") == 0) { - if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) { - puts ("\nno devices available\n"); - return 1; - } - printf ("\nDevice %d bad blocks:\n", curr_device); - nand_print_bad(&nand_dev_desc[curr_device]); - return 0; + } else if (strcmp (argv[1], "device") == 0) { + if ((curr_device < 0) + || (curr_device >= CFG_MAX_NAND_DEVICE)) { + puts ("\nno devices available\n"); + return 1; + } + printf ("\nDevice %d: ", curr_device); + nand_print (&nand_dev_desc[curr_device]); + return 0; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - case 3: - if (strcmp(argv[1],"device") == 0) { - int dev = (int)simple_strtoul(argv[2], NULL, 10); + } else if (strcmp (argv[1], "bad") == 0) { + if ((curr_device < 0) + || (curr_device >= CFG_MAX_NAND_DEVICE)) { + puts ("\nno devices available\n"); + return 1; + } + printf ("\nDevice %d bad blocks:\n", curr_device); + nand_print_bad (&nand_dev_desc[curr_device]); + return 0; - printf ("\nDevice %d: ", dev); - if (dev >= CFG_MAX_NAND_DEVICE) { - puts ("unknown device\n"); - return 1; } - nand_print(&nand_dev_desc[dev]); - /*nand_print (dev);*/ + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + case 3: + if (strcmp (argv[1], "device") == 0) { + int dev = (int) simple_strtoul (argv[2], NULL, 10); - if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { - return 1; - } + printf ("\nDevice %d: ", dev); + if (dev >= CFG_MAX_NAND_DEVICE) { + puts ("unknown device\n"); + return 1; + } + nand_print (&nand_dev_desc[dev]); + /*nand_print (dev); */ + + if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) { + return 1; + } - curr_device = dev; + curr_device = dev; - puts ("... is now current device\n"); + puts ("... is now current device\n"); - return 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; + return 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); + ret = nand_legacy_erase (nand, off, size, 1); - printf("%s\n", ret ? "ERROR" : "OK"); + printf ("%s\n", ret ? "ERROR" : "OK"); - return ret; - } + return ret; + } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - default: - /* at least 4 args */ - - if (strncmp(argv[1], "read", 4) == 0 || - strncmp(argv[1], "write", 5) == 0) { - ulong addr = simple_strtoul(argv[2], NULL, 16); - ulong off = simple_strtoul(argv[3], NULL, 16); - ulong size = simple_strtoul(argv[4], NULL, 16); - int cmd = (strncmp(argv[1], "read", 4) == 0) ? + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + default: + /* at least 4 args */ + + if (strncmp (argv[1], "read", 4) == 0 || + strncmp (argv[1], "write", 5) == 0) { + ulong addr = simple_strtoul (argv[2], NULL, 16); + ulong off = simple_strtoul (argv[3], NULL, 16); + ulong size = simple_strtoul (argv[4], NULL, 16); + int cmd = (strncmp (argv[1], "read", 4) == 0) ? NANDRW_READ : NANDRW_WRITE; - int ret, total; - char* cmdtail = strchr(argv[1], '.'); - - if (cmdtail && !strncmp(cmdtail, ".oob", 2)) { - /* read out-of-band data */ - if (cmd & NANDRW_READ) { - ret = nand_read_oob(nand_dev_desc + curr_device, - off, size, (size_t *)&total, - (u_char*)addr); - } - else { - ret = nand_write_oob(nand_dev_desc + curr_device, - off, size, (size_t *)&total, - (u_char*)addr); + int ret, total; + char *cmdtail = strchr (argv[1], '.'); + + if (cmdtail && !strncmp (cmdtail, ".oob", 2)) { + /* read out-of-band data */ + if (cmd & NANDRW_READ) { + ret = nand_read_oob (nand_dev_desc + curr_device, + off, size, (size_t *) & total, + (u_char *) addr); + } 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)) + cmd |= NANDRW_JFFS2; /* skip bad blocks */ + else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) { + cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ + if (cmd & NANDRW_READ) + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ } - return ret; - } - 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) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ - } #ifdef SXNI855T - /* need ".e" same as ".j" for compatibility with older units */ - else if (cmdtail && !strcmp(cmdtail, ".e")) - cmd |= NANDRW_JFFS2; /* skip bad blocks */ + /* need ".e" same as ".j" for compatibility with older units */ + else if (cmdtail && !strcmp (cmdtail, ".e")) + cmd |= NANDRW_JFFS2; /* skip bad blocks */ #endif #ifdef CFG_NAND_SKIP_BAD_DOT_I - /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ - /* ".i" for image -> read skips bad block (no 0xff) */ - else if (cmdtail && !strcmp(cmdtail, ".i")) { - cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ - if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ - } + /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */ + /* ".i" for image -> read skips bad block (no 0xff) */ + else if (cmdtail && !strcmp (cmdtail, ".i")) { + cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ + if (cmd & NANDRW_READ) + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + } #endif /* CFG_NAND_SKIP_BAD_DOT_I */ - else if (cmdtail) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } + else if (cmdtail) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - printf ("\nNAND %s: device %d offset %ld, size %ld ...\n", - (cmd & NANDRW_READ) ? "read" : "write", - curr_device, off, size); + printf ("\nNAND %s: device %d offset %ld, size %ld ...\n", + (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", - ret ? "ERROR" : "OK"); + printf (" %d bytes %s: %s\n", total, + (cmd & NANDRW_READ) ? "read" : "written", + ret ? "ERROR" : "OK"); - return ret; - } 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); - int ret; + return ret; + } 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); + int ret; - printf ("\nNAND erase: device %d offset %ld, size %ld ...\n", - curr_device, off, size); + printf ("\nNAND erase: device %d offset %ld, size %ld ...\n", + curr_device, off, size); - ret = nand_legacy_erase (nand_dev_desc + curr_device, - off, size, clean); + ret = nand_legacy_erase (nand_dev_desc + curr_device, + off, size, clean); - printf("%s\n", ret ? "ERROR" : "OK"); + printf ("%s\n", ret ? "ERROR" : "OK"); - return ret; - } else { - printf ("Usage:\n%s\n", cmdtp->usage); - rcode = 1; - } + return ret; + } else { + printf ("Usage:\n%s\n", cmdtp->usage); + rcode = 1; + } - return rcode; - } + return rcode; + } } U_BOOT_CMD( diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c index fc3b092..ca45ca0 100644 --- a/cpu/74xx_7xx/cpu.c +++ b/cpu/74xx_7xx/cpu.c @@ -164,6 +164,10 @@ int checkcpu (void) str = "MPC7410"; break; + case CPU_7448: + str = "MPC7448"; + break; + case CPU_7450: str = "MPC7450"; break; @@ -241,7 +245,7 @@ soft_restart(unsigned long addr) void do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - ulong addr; + ulong addr; /* flush and disable I/D cache */ __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3"); __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5"); diff --git a/cpu/74xx_7xx/start.S b/cpu/74xx_7xx/start.S index 1fc0fe6..1143038 100644 --- a/cpu/74xx_7xx/start.S +++ b/cpu/74xx_7xx/start.S @@ -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 diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c index 6b6f828..813aa79 100644 --- a/cpu/mpc5xxx/cpu.c +++ b/cpu/mpc5xxx/cpu.c @@ -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 diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile index b2a6b3e..4b9dcc8 100644 --- a/cpu/mpc83xx/Makefile +++ b/cpu/mpc83xx/Makefile @@ -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)) diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 20bba6c..1b51078 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -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 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 PVR_8349_REV11: + 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 */ diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index 6ed0992..e5725fb 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -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; } diff --git a/cpu/mpc83xx/i2c.c b/cpu/mpc83xx/i2c.c deleted file mode 100644 index 70450f9..0000000 --- a/cpu/mpc83xx/i2c.c +++ /dev/null @@ -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 */ diff --git a/cpu/mpc83xx/interrupts.c b/cpu/mpc83xx/interrupts.c index 5a0babf..bb1fe1a 100644 --- a/cpu/mpc83xx/interrupts.c +++ b/cpu/mpc83xx/interrupts.c @@ -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; diff --git a/cpu/mpc83xx/qe_io.c b/cpu/mpc83xx/qe_io.c new file mode 100644 index 0000000..ebe3487 --- /dev/null +++ b/cpu/mpc83xx/qe_io.c @@ -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 */ diff --git a/cpu/mpc83xx/resetvec.S b/cpu/mpc83xx/resetvec.S deleted file mode 100644 index 3dfcd0d..0000000 --- a/cpu/mpc83xx/resetvec.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .resetvec,"ax" -#ifndef FIXME -#if 0 - b _start_e500 -#endif -#endif diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 48624fe..0d93f2e 100644 --- a/cpu/mpc83xx/spd_sdram.c +++ b/cpu/mpc83xx/spd_sdram.c @@ -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) { - clks++; - } + 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; + } + + /* 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; } - 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 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"); - return 0; - } + caslat = __ilog2(spd.cas_lat); - tmp = 20000 / (((spd.clk_cycle & 0xF0) >> 4) * 10 - + (spd.clk_cycle & 0x0f)); - debug("DDR:Module maximum data rate is: %dMhz\n", tmp); - - 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 */ - 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; - 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"); + if (caslat > 6 ) { + printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n", + spd.cas_lat); return 0; } + max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10 + + (spd.clk_cycle & 0x0f)); + max_data_rate = max_bus_clk * 2; + + 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 = caslat - 2; + else if (spd.clk_cycle2 == 0x60) + 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,144 +363,143 @@ 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 2: - tmp = 0x50; /* 1.5 */ - break; - case 3: - tmp = 0x20; /* 2.0 */ - break; - case 4: - tmp = 0x60; /* 2.5 */ - break; - case 5: - tmp = 0x30; /* 3.0 */ - break; - default: - puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n"); - return 0; + switch (caslat) { + case 1: + ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */ + break; + case 2: + ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */ + break; + case 3: + ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */ + break; + case 4: + ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */ + break; + default: + 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); - break; - case 0x01: - case 0x81: - tmp = picos_to_clk(3900000); - break; - case 0x02: - case 0x82: - tmp = picos_to_clk(7800000); - break; - case 0x03: - case 0x83: - tmp = picos_to_clk(31300000); - break; - case 0x04: - case 0x84: - tmp = picos_to_clk(62500000); - break; - case 0x05: - case 0x85: - tmp = picos_to_clk(125000000); - break; - default: - tmp = 0x512; - break; + switch (spd.refresh) { + case 0x00: + case 0x80: + refresh_clk = picos_to_clk(15625000); + break; + case 0x01: + case 0x81: + refresh_clk = picos_to_clk(3900000); + break; + case 0x02: + case 0x82: + refresh_clk = picos_to_clk(7800000); + break; + case 0x03: + case 0x83: + refresh_clk = picos_to_clk(31300000); + break; + case 0x04: + case 0x84: + refresh_clk = picos_to_clk(62500000); + break; + case 0x05: + case 0x85: + refresh_clk = picos_to_clk(125000000); + break; + default: + refresh_clk = 0x512; + break; } /* * 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); + udelay(600); /* - * 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); - - /* - * Figure out the settings for the sdram_cfg register. Build up - * the entire register in 'tmp' before writing since the write into + * Figure out the settings for the sdram_cfg register. Build up + * 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); - } - - /* write pattern to it and flush */ - *p = (unsigned int)0xdeadbeef; - - if (((unsigned int)p & 0x1c) == 0x1c) { - ppcDcbf((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"); - /* 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); diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c index ad6b3f6..7e53b1e 100644 --- a/cpu/mpc83xx/speed.c +++ b/cpu/mpc83xx/speed.c @@ -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> @@ -53,38 +48,38 @@ typedef enum { typedef struct { mult_t core_csb_ratio; - mult_t vco_divider; + mult_t vco_divider; } corecnf_t; corecnf_t corecnf_tab[] = { - { _byp, _byp}, /* 0x00 */ - { _byp, _byp}, /* 0x01 */ - { _byp, _byp}, /* 0x02 */ - { _byp, _byp}, /* 0x03 */ - { _byp, _byp}, /* 0x04 */ - { _byp, _byp}, /* 0x05 */ - { _byp, _byp}, /* 0x06 */ - { _byp, _byp}, /* 0x07 */ - { _1x, _x2}, /* 0x08 */ - { _1x, _x4}, /* 0x09 */ - { _1x, _x8}, /* 0x0A */ - { _1x, _x8}, /* 0x0B */ - {_1_5x, _x2}, /* 0x0C */ - {_1_5x, _x4}, /* 0x0D */ - {_1_5x, _x8}, /* 0x0E */ - {_1_5x, _x8}, /* 0x0F */ - { _2x, _x2}, /* 0x10 */ - { _2x, _x4}, /* 0x11 */ - { _2x, _x8}, /* 0x12 */ - { _2x, _x8}, /* 0x13 */ - {_2_5x, _x2}, /* 0x14 */ - {_2_5x, _x4}, /* 0x15 */ - {_2_5x, _x8}, /* 0x16 */ - {_2_5x, _x8}, /* 0x17 */ - { _3x, _x2}, /* 0x18 */ - { _3x, _x4}, /* 0x19 */ - { _3x, _x8}, /* 0x1A */ - { _3x, _x8}, /* 0x1B */ + {_byp, _byp}, /* 0x00 */ + {_byp, _byp}, /* 0x01 */ + {_byp, _byp}, /* 0x02 */ + {_byp, _byp}, /* 0x03 */ + {_byp, _byp}, /* 0x04 */ + {_byp, _byp}, /* 0x05 */ + {_byp, _byp}, /* 0x06 */ + {_byp, _byp}, /* 0x07 */ + {_1x, _x2}, /* 0x08 */ + {_1x, _x4}, /* 0x09 */ + {_1x, _x8}, /* 0x0A */ + {_1x, _x8}, /* 0x0B */ + {_1_5x, _x2}, /* 0x0C */ + {_1_5x, _x4}, /* 0x0D */ + {_1_5x, _x8}, /* 0x0E */ + {_1_5x, _x8}, /* 0x0F */ + {_2x, _x2}, /* 0x10 */ + {_2x, _x4}, /* 0x11 */ + {_2x, _x8}, /* 0x12 */ + {_2x, _x8}, /* 0x13 */ + {_2_5x, _x2}, /* 0x14 */ + {_2_5x, _x4}, /* 0x15 */ + {_2_5x, _x8}, /* 0x16 */ + {_2_5x, _x8}, /* 0x17 */ + {_3x, _x2}, /* 0x18 */ + {_3x, _x4}, /* 0x19 */ + {_3x, _x8}, /* 0x1A */ + {_3x, _x8}, /* 0x1B */ }; /* ----------------------------------------------------------------- */ @@ -92,91 +87,64 @@ corecnf_t corecnf_tab[] = { /* * */ -int get_clocks (void) +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; + u8 spmf; + u8 clkin_div; u32 sccr; u32 corecnf_tab_index; - u8 corepll; + u8 corepll; 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 ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) +#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 */ + clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT); - /* 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; + 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 } - 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); - } + 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,12 +266,20 @@ 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)) ) { + if (corecnf_tab_index > (sizeof(corecnf_tab) / sizeof(corecnf_t))) { /* corecnf_tab_index is too high, possibly worng value */ return -11; } @@ -309,7 +296,7 @@ int get_clocks (void) core_clk = 2 * csb_clk; break; case _2_5x: - core_clk = ( 5 * csb_clk) / 2; + core_clk = (5 * csb_clk) / 2; break; case _3x: core_clk = 3 * csb_clk; @@ -319,46 +306,69 @@ int get_clocks (void) return -12; } - gd->csb_clk = csb_clk ; - gd->tsec1_clk = tsec1_clk ; - gd->tsec2_clk = tsec2_clk ; - gd->core_clk = core_clk ; +#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->usbmph_clk = usbmph_clk; - gd->usbdr_clk = usbdr_clk ; - gd->i2c_clk = i2c_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; - + gd->usbdr_clk = usbdr_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; +#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; + } /******************************************** * get_bus_freq * return system bus freq in Hz *********************************************/ -ulong get_bus_freq (ulong dummy) +ulong get_bus_freq(ulong dummy) { return gd->csb_clk; } -int print_clock_conf (void) +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); - 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(" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000); + printf(" Core: %4d MHz\n", gd->core_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); + 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; } diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 6e02cce..0f27bb6 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -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) diff --git a/cpu/mpc83xx/traps.c b/cpu/mpc83xx/traps.c index 44345af..152fa73 100644 --- a/cpu/mpc83xx/traps.c +++ b/cpu/mpc83xx/traps.c @@ -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) */ /* diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 447383f..9c5c910 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -340,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; diff --git a/doc/README.mpc8360emds b/doc/README.mpc8360emds new file mode 100644 index 0000000..c87469f --- /dev/null +++ b/doc/README.mpc8360emds @@ -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. diff --git a/drivers/fsl_i2c.c b/drivers/fsl_i2c.c index 65c2743..c929096 100644 --- a/drivers/fsl_i2c.c +++ b/drivers/fsl_i2c.c @@ -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); - - /* set clock */ - writeb(0x3f, &I2C->fdr); - - /* set default filter */ - writeb(0x10, &I2C->dfsrr); - - /* write slave address */ - writeb(slaveadd, &I2C->adr); - - /* clear status register */ - writeb(0x0, &I2C->sr); - - /* start I2C controller */ - writeb(I2C_CR_MEN, &I2C->cr); + volatile struct fsl_i2c *dev; + + dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET); + + 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 */ + +#ifdef CFG_I2C2_OFFSET + dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET); + + 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 */ diff --git a/drivers/nand/nand_base.c b/drivers/nand/nand_base.c index 2e3fcdf..7fdf57b 100644 --- a/drivers/nand/nand_base.c +++ b/drivers/nand/nand_base.c @@ -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 += (HZ * 400) / 1000; + timeo = (CFG_HZ * 400) / 1000; else - timeo += (HZ * 20) / 1000; + timeo = (CFG_HZ * 20) / 1000; if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) this->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); @@ -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) diff --git a/drivers/qe/Makefile b/drivers/qe/Makefile new file mode 100644 index 0000000..4844181 --- /dev/null +++ b/drivers/qe/Makefile @@ -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 + +######################################################################### diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c new file mode 100644 index 0000000..5f20962 --- /dev/null +++ b/drivers/qe/qe.c @@ -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 */ diff --git a/drivers/qe/qe.h b/drivers/qe/qe.h new file mode 100644 index 0000000..f7f8ed0 --- /dev/null +++ b/drivers/qe/qe.h @@ -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__ */ diff --git a/drivers/qe/uccf.c b/drivers/qe/uccf.c new file mode 100644 index 0000000..c5477e0 --- /dev/null +++ b/drivers/qe/uccf.c @@ -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, ®_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 */ diff --git a/drivers/qe/uccf.h b/drivers/qe/uccf.h new file mode 100644 index 0000000..1ff9e1d --- /dev/null +++ b/drivers/qe/uccf.h @@ -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__ */ diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c new file mode 100644 index 0000000..f640c81 --- /dev/null +++ b/drivers/qe/uec.c @@ -0,0 +1,1266 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. + * + * Dave Liu <daveliu@freescale.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 "net.h" +#include "malloc.h" +#include "asm/errno.h" +#include "asm/io.h" +#include "asm/immap_qe.h" +#include "qe.h" +#include "uccf.h" +#include "uec.h" +#include "uec_phy.h" + +#if defined(CONFIG_QE) + +#ifdef CONFIG_UEC_ETH1 +static uec_info_t eth1_uec_info = { + .uf_info = { + .ucc_num = CFG_UEC1_UCC_NUM, + .rx_clock = CFG_UEC1_RX_CLK, + .tx_clock = CFG_UEC1_TX_CLK, + .eth_type = CFG_UEC1_ETH_TYPE, + }, + .num_threads_tx = UEC_NUM_OF_THREADS_4, + .num_threads_rx = UEC_NUM_OF_THREADS_4, + .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, + .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, + .tx_bd_ring_len = 16, + .rx_bd_ring_len = 16, + .phy_address = CFG_UEC1_PHY_ADDR, + .enet_interface = CFG_UEC1_INTERFACE_MODE, +}; +#endif +#ifdef CONFIG_UEC_ETH2 +static uec_info_t eth2_uec_info = { + .uf_info = { + .ucc_num = CFG_UEC2_UCC_NUM, + .rx_clock = CFG_UEC2_RX_CLK, + .tx_clock = CFG_UEC2_TX_CLK, + .eth_type = CFG_UEC2_ETH_TYPE, + }, + .num_threads_tx = UEC_NUM_OF_THREADS_4, + .num_threads_rx = UEC_NUM_OF_THREADS_4, + .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, + .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, + .tx_bd_ring_len = 16, + .rx_bd_ring_len = 16, + .phy_address = CFG_UEC2_PHY_ADDR, + .enet_interface = CFG_UEC2_INTERFACE_MODE, +}; +#endif + +static int uec_mac_enable(uec_private_t *uec, comm_dir_e mode) +{ + uec_t *uec_regs; + u32 maccfg1; + + if (!uec) { + printf("%s: uec not initial\n", __FUNCTION__); + return -EINVAL; + } + uec_regs = uec->uec_regs; + + maccfg1 = in_be32(&uec_regs->maccfg1); + + if (mode & COMM_DIR_TX) { + maccfg1 |= MACCFG1_ENABLE_TX; + out_be32(&uec_regs->maccfg1, maccfg1); + uec->mac_tx_enabled = 1; + } + + if (mode & COMM_DIR_RX) { + maccfg1 |= MACCFG1_ENABLE_RX; + out_be32(&uec_regs->maccfg1, maccfg1); + uec->mac_rx_enabled = 1; + } + + return 0; +} + +static int uec_mac_disable(uec_private_t *uec, comm_dir_e mode) +{ + uec_t *uec_regs; + u32 maccfg1; + + if (!uec) { + printf("%s: uec not initial\n", __FUNCTION__); + return -EINVAL; + } + uec_regs = uec->uec_regs; + + maccfg1 = in_be32(&uec_regs->maccfg1); + + if (mode & COMM_DIR_TX) { + maccfg1 &= ~MACCFG1_ENABLE_TX; + out_be32(&uec_regs->maccfg1, maccfg1); + uec->mac_tx_enabled = 0; + } + + if (mode & COMM_DIR_RX) { + maccfg1 &= ~MACCFG1_ENABLE_RX; + out_be32(&uec_regs->maccfg1, maccfg1); + uec->mac_rx_enabled = 0; + } + + return 0; +} + +static int uec_graceful_stop_tx(uec_private_t *uec) +{ + ucc_fast_t *uf_regs; + u32 cecr_subblock; + u32 ucce; + + if (!uec || !uec->uccf) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + + uf_regs = uec->uccf->uf_regs; + + /* Clear the grace stop event */ + out_be32(&uf_regs->ucce, UCCE_GRA); + + /* Issue host command */ + cecr_subblock = + ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num); + qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, + (u8)QE_CR_PROTOCOL_ETHERNET, 0); + + /* Wait for command to complete */ + do { + ucce = in_be32(&uf_regs->ucce); + } while (! (ucce & UCCE_GRA)); + + uec->grace_stopped_tx = 1; + + return 0; +} + +static int uec_graceful_stop_rx(uec_private_t *uec) +{ + u32 cecr_subblock; + u8 ack; + + if (!uec) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + + if (!uec->p_rx_glbl_pram) { + printf("%s: No init rx global parameter\n", __FUNCTION__); + return -EINVAL; + } + + /* Clear acknowledge bit */ + ack = uec->p_rx_glbl_pram->rxgstpack; + ack &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; + uec->p_rx_glbl_pram->rxgstpack = ack; + + /* Keep issuing cmd and checking ack bit until it is asserted */ + do { + /* Issue host command */ + cecr_subblock = + ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num); + qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, + (u8)QE_CR_PROTOCOL_ETHERNET, 0); + ack = uec->p_rx_glbl_pram->rxgstpack; + } while (! (ack & GRACEFUL_STOP_ACKNOWLEDGE_RX )); + + uec->grace_stopped_rx = 1; + + return 0; +} + +static int uec_restart_tx(uec_private_t *uec) +{ + u32 cecr_subblock; + + if (!uec || !uec->uec_info) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + + cecr_subblock = + ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num); + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, + (u8)QE_CR_PROTOCOL_ETHERNET, 0); + + uec->grace_stopped_tx = 0; + + return 0; +} + +static int uec_restart_rx(uec_private_t *uec) +{ + u32 cecr_subblock; + + if (!uec || !uec->uec_info) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + + cecr_subblock = + ucc_fast_get_qe_cr_subblock(uec->uec_info->uf_info.ucc_num); + qe_issue_cmd(QE_RESTART_RX, cecr_subblock, + (u8)QE_CR_PROTOCOL_ETHERNET, 0); + + uec->grace_stopped_rx = 0; + + return 0; +} + +static int uec_open(uec_private_t *uec, comm_dir_e mode) +{ + ucc_fast_private_t *uccf; + + if (!uec || !uec->uccf) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + uccf = uec->uccf; + + /* check if the UCC number is in range. */ + if (uec->uec_info->uf_info.ucc_num >= UCC_MAX_NUM) { + printf("%s: ucc_num out of range.\n", __FUNCTION__); + return -EINVAL; + } + + /* Enable MAC */ + uec_mac_enable(uec, mode); + + /* Enable UCC fast */ + ucc_fast_enable(uccf, mode); + + /* RISC microcode start */ + if ((mode & COMM_DIR_TX) && uec->grace_stopped_tx) { + uec_restart_tx(uec); + } + if ((mode & COMM_DIR_RX) && uec->grace_stopped_rx) { + uec_restart_rx(uec); + } + + return 0; +} + +static int uec_stop(uec_private_t *uec, comm_dir_e mode) +{ + ucc_fast_private_t *uccf; + + if (!uec || !uec->uccf) { + printf("%s: No handle passed.\n", __FUNCTION__); + return -EINVAL; + } + uccf = uec->uccf; + + /* check if the UCC number is in range. */ + if (uec->uec_info->uf_info.ucc_num >= UCC_MAX_NUM) { + printf("%s: ucc_num out of range.\n", __FUNCTION__); + return -EINVAL; + } + /* Stop any transmissions */ + if ((mode & COMM_DIR_TX) && !uec->grace_stopped_tx) { + uec_graceful_stop_tx(uec); + } + /* Stop any receptions */ + if ((mode & COMM_DIR_RX) && !uec->grace_stopped_rx) { + uec_graceful_stop_rx(uec); + } + + /* Disable the UCC fast */ + ucc_fast_disable(uec->uccf, mode); + + /* Disable the MAC */ + uec_mac_disable(uec, mode); + + return 0; +} + +static int uec_set_mac_duplex(uec_private_t *uec, int duplex) +{ + uec_t *uec_regs; + u32 maccfg2; + + if (!uec) { + printf("%s: uec not initial\n", __FUNCTION__); + return -EINVAL; + } + uec_regs = uec->uec_regs; + + if (duplex == DUPLEX_HALF) { + maccfg2 = in_be32(&uec_regs->maccfg2); + maccfg2 &= ~MACCFG2_FDX; + out_be32(&uec_regs->maccfg2, maccfg2); + } + + if (duplex == DUPLEX_FULL) { + maccfg2 = in_be32(&uec_regs->maccfg2); + maccfg2 |= MACCFG2_FDX; + out_be32(&uec_regs->maccfg2, maccfg2); + } + + return 0; +} + +static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode) +{ + enet_interface_e enet_if_mode; + uec_info_t *uec_info; + uec_t *uec_regs; + u32 upsmr; + u32 maccfg2; + + if (!uec) { + printf("%s: uec not initial\n", __FUNCTION__); + return -EINVAL; + } + + uec_info = uec->uec_info; + uec_regs = uec->uec_regs; + enet_if_mode = if_mode; + + maccfg2 = in_be32(&uec_regs->maccfg2); + maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK; + + upsmr = in_be32(&uec->uccf->uf_regs->upsmr); + upsmr &= ~(UPSMR_RPM | UPSMR_TBIM | UPSMR_R10M | UPSMR_RMM); + + switch (enet_if_mode) { + case ENET_100_MII: + case ENET_10_MII: + maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; + break; + case ENET_1000_GMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; + break; + case ENET_1000_TBI: + maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; + upsmr |= UPSMR_TBIM; + break; + case ENET_1000_RTBI: + maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; + upsmr |= (UPSMR_RPM | UPSMR_TBIM); + break; + case ENET_1000_RGMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; + upsmr |= UPSMR_RPM; + break; + case ENET_100_RGMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; + upsmr |= UPSMR_RPM; + break; + case ENET_10_RGMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; + upsmr |= (UPSMR_RPM | UPSMR_R10M); + break; + case ENET_100_RMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; + upsmr |= UPSMR_RMM; + break; + case ENET_10_RMII: + maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; + upsmr |= (UPSMR_R10M | UPSMR_RMM); + break; + default: + return -EINVAL; + break; + } + out_be32(&uec_regs->maccfg2, maccfg2); + out_be32(&uec->uccf->uf_regs->upsmr, upsmr); + + return 0; +} + +static int init_mii_management_configuration(uec_t *uec_regs) +{ + uint timeout = 0x1000; + u32 miimcfg = 0; + + miimcfg = in_be32(&uec_regs->miimcfg); + miimcfg |= MIIMCFG_MNGMNT_CLC_DIV_INIT_VALUE; + out_be32(&uec_regs->miimcfg, miimcfg); + + /* Wait until the bus is free */ + while ((in_be32(&uec_regs->miimcfg) & MIIMIND_BUSY) && timeout--); + if (timeout <= 0) { + printf("%s: The MII Bus is stuck!", __FUNCTION__); + return -ETIMEDOUT; + } + + return 0; +} + +static int init_phy(struct eth_device *dev) +{ + uec_private_t *uec; + uec_t *uec_regs; + struct uec_mii_info *mii_info; + struct phy_info *curphy; + int err; + + uec = (uec_private_t *)dev->priv; + uec_regs = uec->uec_regs; + + uec->oldlink = 0; + uec->oldspeed = 0; + uec->oldduplex = -1; + + mii_info = malloc(sizeof(*mii_info)); + if (!mii_info) { + printf("%s: Could not allocate mii_info", dev->name); + return -ENOMEM; + } + memset(mii_info, 0, sizeof(*mii_info)); + + mii_info->speed = SPEED_1000; + mii_info->duplex = DUPLEX_FULL; + mii_info->pause = 0; + mii_info->link = 1; + + mii_info->advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Full); + mii_info->autoneg = 1; + mii_info->mii_id = uec->uec_info->phy_address; + mii_info->dev = dev; + + mii_info->mdio_read = &read_phy_reg; + mii_info->mdio_write = &write_phy_reg; + + uec->mii_info = mii_info; + + if (init_mii_management_configuration(uec_regs)) { + printf("%s: The MII Bus is stuck!", dev->name); + err = -1; + goto bus_fail; + } + + /* get info for this PHY */ + curphy = get_phy_info(uec->mii_info); + if (!curphy) { + printf("%s: No PHY found", dev->name); + err = -1; + goto no_phy; + } + + mii_info->phyinfo = curphy; + + /* Run the commands which initialize the PHY */ + if (curphy->init) { + err = curphy->init(uec->mii_info); + if (err) + goto phy_init_fail; + } + + return 0; + +phy_init_fail: +no_phy: +bus_fail: + free(mii_info); + return err; +} + +static void adjust_link(struct eth_device *dev) +{ + uec_private_t *uec = (uec_private_t *)dev->priv; + uec_t *uec_regs; + struct uec_mii_info *mii_info = uec->mii_info; + + extern void change_phy_interface_mode(struct eth_device *dev, + enet_interface_e mode); + uec_regs = uec->uec_regs; + + if (mii_info->link) { + /* Now we make sure that we can be in full duplex mode. + * If not, we operate in half-duplex mode. */ + if (mii_info->duplex != uec->oldduplex) { + if (!(mii_info->duplex)) { + uec_set_mac_duplex(uec, DUPLEX_HALF); + printf("%s: Half Duplex\n", dev->name); + } else { + uec_set_mac_duplex(uec, DUPLEX_FULL); + printf("%s: Full Duplex\n", dev->name); + } + uec->oldduplex = mii_info->duplex; + } + + if (mii_info->speed != uec->oldspeed) { + switch (mii_info->speed) { + case 1000: + break; + case 100: + printf ("switching to rgmii 100\n"); + /* change phy to rgmii 100 */ + change_phy_interface_mode(dev, + ENET_100_RGMII); + /* change the MAC interface mode */ + uec_set_mac_if_mode(uec,ENET_100_RGMII); + break; + case 10: + printf ("switching to rgmii 10\n"); + /* change phy to rgmii 10 */ + change_phy_interface_mode(dev, + ENET_10_RGMII); + /* change the MAC interface mode */ + uec_set_mac_if_mode(uec,ENET_10_RGMII); + break; + default: + printf("%s: Ack,Speed(%d)is illegal\n", + dev->name, mii_info->speed); + break; + } + + printf("%s: Speed %dBT\n", dev->name, mii_info->speed); + uec->oldspeed = mii_info->speed; + } + + if (!uec->oldlink) { + printf("%s: Link is up\n", dev->name); + uec->oldlink = 1; + } + + } else { /* if (mii_info->link) */ + if (uec->oldlink) { + printf("%s: Link is down\n", dev->name); + uec->oldlink = 0; + uec->oldspeed = 0; + uec->oldduplex = -1; + } + } +} + +static void phy_change(struct eth_device *dev) +{ + uec_private_t *uec = (uec_private_t *)dev->priv; + uec_t *uec_regs; + int result = 0; + + uec_regs = uec->uec_regs; + + /* Delay 5s to give the PHY a chance to change the register state */ + udelay(5000000); + + /* Update the link, speed, duplex */ + result = uec->mii_info->phyinfo->read_status(uec->mii_info); + + /* Adjust the interface according to speed */ + if ((0 == result) || (uec->mii_info->link == 0)) { + adjust_link(dev); + } +} + +static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr) +{ + uec_t *uec_regs; + u32 mac_addr1; + u32 mac_addr2; + + if (!uec) { + printf("%s: uec not initial\n", __FUNCTION__); + return -EINVAL; + } + + uec_regs = uec->uec_regs; + + /* if a station address of 0x12345678ABCD, perform a write to + MACSTNADDR1 of 0xCDAB7856, + MACSTNADDR2 of 0x34120000 */ + + mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \ + (mac_addr[3] << 8) | (mac_addr[2]); + out_be32(&uec_regs->macstnaddr1, mac_addr1); + + mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000; + out_be32(&uec_regs->macstnaddr2, mac_addr2); + + return 0; +} + +static int uec_convert_threads_num(uec_num_of_threads_e threads_num, + int *threads_num_ret) +{ + int num_threads_numerica; + + switch (threads_num) { + case UEC_NUM_OF_THREADS_1: + num_threads_numerica = 1; + break; + case UEC_NUM_OF_THREADS_2: + num_threads_numerica = 2; + break; + case UEC_NUM_OF_THREADS_4: + num_threads_numerica = 4; + break; + case UEC_NUM_OF_THREADS_6: + num_threads_numerica = 6; + break; + case UEC_NUM_OF_THREADS_8: + num_threads_numerica = 8; + break; + default: + printf("%s: Bad number of threads value.", + __FUNCTION__); + return -EINVAL; + } + + *threads_num_ret = num_threads_numerica; + + return 0; +} + +static void uec_init_tx_parameter(uec_private_t *uec, int num_threads_tx) +{ + uec_info_t *uec_info; + u32 end_bd; + u8 bmrx = 0; + int i; + + uec_info = uec->uec_info; + + /* Alloc global Tx parameter RAM page */ + uec->tx_glbl_pram_offset = qe_muram_alloc( + sizeof(uec_tx_global_pram_t), + UEC_TX_GLOBAL_PRAM_ALIGNMENT); + uec->p_tx_glbl_pram = (uec_tx_global_pram_t *) + qe_muram_addr(uec->tx_glbl_pram_offset); + + /* Zero the global Tx prameter RAM */ + memset(uec->p_tx_glbl_pram, 0, sizeof(uec_tx_global_pram_t)); + + /* Init global Tx parameter RAM */ + + /* TEMODER, RMON statistics disable, one Tx queue */ + out_be16(&uec->p_tx_glbl_pram->temoder, TEMODER_INIT_VALUE); + + /* SQPTR */ + uec->send_q_mem_reg_offset = qe_muram_alloc( + sizeof(uec_send_queue_qd_t), + UEC_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); + uec->p_send_q_mem_reg = (uec_send_queue_mem_region_t *) + qe_muram_addr(uec->send_q_mem_reg_offset); + out_be32(&uec->p_tx_glbl_pram->sqptr, uec->send_q_mem_reg_offset); + + /* Setup the table with TxBDs ring */ + end_bd = (u32)uec->p_tx_bd_ring + (uec_info->tx_bd_ring_len - 1) + * SIZEOFBD; + out_be32(&uec->p_send_q_mem_reg->sqqd[0].bd_ring_base, + (u32)(uec->p_tx_bd_ring)); + out_be32(&uec->p_send_q_mem_reg->sqqd[0].last_bd_completed_address, + end_bd); + + /* Scheduler Base Pointer, we have only one Tx queue, no need it */ + out_be32(&uec->p_tx_glbl_pram->schedulerbasepointer, 0); + + /* TxRMON Base Pointer, TxRMON disable, we don't need it */ + out_be32(&uec->p_tx_glbl_pram->txrmonbaseptr, 0); + + /* TSTATE, global snooping, big endian, the CSB bus selected */ + bmrx = BMR_INIT_VALUE; + out_be32(&uec->p_tx_glbl_pram->tstate, ((u32)(bmrx) << BMR_SHIFT)); + + /* IPH_Offset */ + for (i = 0; i < MAX_IPH_OFFSET_ENTRY; i++) { + out_8(&uec->p_tx_glbl_pram->iphoffset[i], 0); + } + + /* VTAG table */ + for (i = 0; i < UEC_TX_VTAG_TABLE_ENTRY_MAX; i++) { + out_be32(&uec->p_tx_glbl_pram->vtagtable[i], 0); + } + + /* TQPTR */ + uec->thread_dat_tx_offset = qe_muram_alloc( + num_threads_tx * sizeof(uec_thread_data_tx_t) + + 32 *(num_threads_tx == 1), UEC_THREAD_DATA_ALIGNMENT); + + uec->p_thread_data_tx = (uec_thread_data_tx_t *) + qe_muram_addr(uec->thread_dat_tx_offset); + out_be32(&uec->p_tx_glbl_pram->tqptr, uec->thread_dat_tx_offset); +} + +static void uec_init_rx_parameter(uec_private_t *uec, int num_threads_rx) +{ + u8 bmrx = 0; + int i; + uec_82xx_address_filtering_pram_t *p_af_pram; + + /* Allocate global Rx parameter RAM page */ + uec->rx_glbl_pram_offset = qe_muram_alloc( + sizeof(uec_rx_global_pram_t), UEC_RX_GLOBAL_PRAM_ALIGNMENT); + uec->p_rx_glbl_pram = (uec_rx_global_pram_t *) + qe_muram_addr(uec->rx_glbl_pram_offset); + + /* Zero Global Rx parameter RAM */ + memset(uec->p_rx_glbl_pram, 0, sizeof(uec_rx_global_pram_t)); + + /* Init global Rx parameter RAM */ + /* REMODER, Extended feature mode disable, VLAN disable, + LossLess flow control disable, Receive firmware statisic disable, + Extended address parsing mode disable, One Rx queues, + Dynamic maximum/minimum frame length disable, IP checksum check + disable, IP address alignment disable + */ + out_be32(&uec->p_rx_glbl_pram->remoder, REMODER_INIT_VALUE); + + /* RQPTR */ + uec->thread_dat_rx_offset = qe_muram_alloc( + num_threads_rx * sizeof(uec_thread_data_rx_t), + UEC_THREAD_DATA_ALIGNMENT); + uec->p_thread_data_rx = (uec_thread_data_rx_t *) + qe_muram_addr(uec->thread_dat_rx_offset); + out_be32(&uec->p_rx_glbl_pram->rqptr, uec->thread_dat_rx_offset); + + /* Type_or_Len */ + out_be16(&uec->p_rx_glbl_pram->typeorlen, 3072); + + /* RxRMON base pointer, we don't need it */ + out_be32(&uec->p_rx_glbl_pram->rxrmonbaseptr, 0); + + /* IntCoalescingPTR, we don't need it, no interrupt */ + out_be32(&uec->p_rx_glbl_pram->intcoalescingptr, 0); + + /* RSTATE, global snooping, big endian, the CSB bus selected */ + bmrx = BMR_INIT_VALUE; + out_8(&uec->p_rx_glbl_pram->rstate, bmrx); + + /* MRBLR */ + out_be16(&uec->p_rx_glbl_pram->mrblr, MAX_RXBUF_LEN); + + /* RBDQPTR */ + uec->rx_bd_qs_tbl_offset = qe_muram_alloc( + sizeof(uec_rx_bd_queues_entry_t) + \ + sizeof(uec_rx_prefetched_bds_t), + UEC_RX_BD_QUEUES_ALIGNMENT); + uec->p_rx_bd_qs_tbl = (uec_rx_bd_queues_entry_t *) + qe_muram_addr(uec->rx_bd_qs_tbl_offset); + + /* Zero it */ + memset(uec->p_rx_bd_qs_tbl, 0, sizeof(uec_rx_bd_queues_entry_t) + \ + sizeof(uec_rx_prefetched_bds_t)); + out_be32(&uec->p_rx_glbl_pram->rbdqptr, uec->rx_bd_qs_tbl_offset); + out_be32(&uec->p_rx_bd_qs_tbl->externalbdbaseptr, + (u32)uec->p_rx_bd_ring); + + /* MFLR */ + out_be16(&uec->p_rx_glbl_pram->mflr, MAX_FRAME_LEN); + /* MINFLR */ + out_be16(&uec->p_rx_glbl_pram->minflr, MIN_FRAME_LEN); + /* MAXD1 */ + out_be16(&uec->p_rx_glbl_pram->maxd1, MAX_DMA1_LEN); + /* MAXD2 */ + out_be16(&uec->p_rx_glbl_pram->maxd2, MAX_DMA2_LEN); + /* ECAM_PTR */ + out_be32(&uec->p_rx_glbl_pram->ecamptr, 0); + /* L2QT */ + out_be32(&uec->p_rx_glbl_pram->l2qt, 0); + /* L3QT */ + for (i = 0; i < 8; i++) { + out_be32(&uec->p_rx_glbl_pram->l3qt[i], 0); + } + + /* VLAN_TYPE */ + out_be16(&uec->p_rx_glbl_pram->vlantype, 0x8100); + /* TCI */ + out_be16(&uec->p_rx_glbl_pram->vlantci, 0); + + /* Clear PQ2 style address filtering hash table */ + p_af_pram = (uec_82xx_address_filtering_pram_t *) \ + uec->p_rx_glbl_pram->addressfiltering; + + p_af_pram->iaddr_h = 0; + p_af_pram->iaddr_l = 0; + p_af_pram->gaddr_h = 0; + p_af_pram->gaddr_l = 0; +} + +static int uec_issue_init_enet_rxtx_cmd(uec_private_t *uec, + int thread_tx, int thread_rx) +{ + uec_init_cmd_pram_t *p_init_enet_param; + u32 init_enet_param_offset; + uec_info_t *uec_info; + int i; + int snum; + u32 init_enet_offset; + u32 entry_val; + u32 command; + u32 cecr_subblock; + + uec_info = uec->uec_info; + + /* Allocate init enet command parameter */ + uec->init_enet_param_offset = qe_muram_alloc( + sizeof(uec_init_cmd_pram_t), 4); + init_enet_param_offset = uec->init_enet_param_offset; + uec->p_init_enet_param = (uec_init_cmd_pram_t *) + qe_muram_addr(uec->init_enet_param_offset); + + /* Zero init enet command struct */ + memset((void *)uec->p_init_enet_param, 0, sizeof(uec_init_cmd_pram_t)); + + /* Init the command struct */ + p_init_enet_param = uec->p_init_enet_param; + p_init_enet_param->resinit0 = ENET_INIT_PARAM_MAGIC_RES_INIT0; + p_init_enet_param->resinit1 = ENET_INIT_PARAM_MAGIC_RES_INIT1; + p_init_enet_param->resinit2 = ENET_INIT_PARAM_MAGIC_RES_INIT2; + p_init_enet_param->resinit3 = ENET_INIT_PARAM_MAGIC_RES_INIT3; + p_init_enet_param->resinit4 = ENET_INIT_PARAM_MAGIC_RES_INIT4; + p_init_enet_param->largestexternallookupkeysize = 0; + + p_init_enet_param->rgftgfrxglobal |= ((u32)uec_info->num_threads_rx) + << ENET_INIT_PARAM_RGF_SHIFT; + p_init_enet_param->rgftgfrxglobal |= ((u32)uec_info->num_threads_tx) + << ENET_INIT_PARAM_TGF_SHIFT; + + /* Init Rx global parameter pointer */ + p_init_enet_param->rgftgfrxglobal |= uec->rx_glbl_pram_offset | + (u32)uec_info->riscRx; + + /* Init Rx threads */ + for (i = 0; i < (thread_rx + 1); i++) { + if ((snum = qe_get_snum()) < 0) { + printf("%s can not get snum\n", __FUNCTION__); + return -ENOMEM; + } + + if (i==0) { + init_enet_offset = 0; + } else { + init_enet_offset = qe_muram_alloc( + sizeof(uec_thread_rx_pram_t), + UEC_THREAD_RX_PRAM_ALIGNMENT); + } + + entry_val = ((u32)snum << ENET_INIT_PARAM_SNUM_SHIFT) | + init_enet_offset | (u32)uec_info->riscRx; + p_init_enet_param->rxthread[i] = entry_val; + } + + /* Init Tx global parameter pointer */ + p_init_enet_param->txglobal = uec->tx_glbl_pram_offset | + (u32)uec_info->riscTx; + + /* Init Tx threads */ + for (i = 0; i < thread_tx; i++) { + if ((snum = qe_get_snum()) < 0) { + printf("%s can not get snum\n", __FUNCTION__); + return -ENOMEM; + } + + init_enet_offset = qe_muram_alloc(sizeof(uec_thread_tx_pram_t), + UEC_THREAD_TX_PRAM_ALIGNMENT); + + entry_val = ((u32)snum << ENET_INIT_PARAM_SNUM_SHIFT) | + init_enet_offset | (u32)uec_info->riscTx; + p_init_enet_param->txthread[i] = entry_val; + } + + __asm__ __volatile__("sync"); + + /* Issue QE command */ + command = QE_INIT_TX_RX; + cecr_subblock = ucc_fast_get_qe_cr_subblock( + uec->uec_info->uf_info.ucc_num); + qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, + init_enet_param_offset); + + return 0; +} + +static int uec_startup(uec_private_t *uec) +{ + uec_info_t *uec_info; + ucc_fast_info_t *uf_info; + ucc_fast_private_t *uccf; + ucc_fast_t *uf_regs; + uec_t *uec_regs; + int num_threads_tx; + int num_threads_rx; + u32 utbipar; + enet_interface_e enet_interface; + u32 length; + u32 align; + qe_bd_t *bd; + u8 *buf; + int i; + + if (!uec || !uec->uec_info) { + printf("%s: uec or uec_info not initial\n", __FUNCTION__); + return -EINVAL; + } + + uec_info = uec->uec_info; + uf_info = &(uec_info->uf_info); + + /* Check if Rx BD ring len is illegal */ + if ((uec_info->rx_bd_ring_len < UEC_RX_BD_RING_SIZE_MIN) || \ + (uec_info->rx_bd_ring_len % UEC_RX_BD_RING_SIZE_ALIGNMENT)) { + printf("%s: Rx BD ring len must be multiple of 4, and > 8.\n", + __FUNCTION__); + return -EINVAL; + } + + /* Check if Tx BD ring len is illegal */ + if (uec_info->tx_bd_ring_len < UEC_TX_BD_RING_SIZE_MIN) { + printf("%s: Tx BD ring length must not be smaller than 2.\n", + __FUNCTION__); + return -EINVAL; + } + + /* Check if MRBLR is illegal */ + if ((MAX_RXBUF_LEN == 0) || (MAX_RXBUF_LEN % UEC_MRBLR_ALIGNMENT)) { + printf("%s: max rx buffer length must be mutliple of 128.\n", + __FUNCTION__); + return -EINVAL; + } + + /* Both Rx and Tx are stopped */ + uec->grace_stopped_rx = 1; + uec->grace_stopped_tx = 1; + + /* Init UCC fast */ + if (ucc_fast_init(uf_info, &uccf)) { + printf("%s: failed to init ucc fast\n", __FUNCTION__); + return -ENOMEM; + } + + /* Save uccf */ + uec->uccf = uccf; + + /* Convert the Tx threads number */ + if (uec_convert_threads_num(uec_info->num_threads_tx, + &num_threads_tx)) { + return -EINVAL; + } + + /* Convert the Rx threads number */ + if (uec_convert_threads_num(uec_info->num_threads_rx, + &num_threads_rx)) { + return -EINVAL; + } + + uf_regs = uccf->uf_regs; + + /* UEC register is following UCC fast registers */ + uec_regs = (uec_t *)(&uf_regs->ucc_eth); + + /* Save the UEC register pointer to UEC private struct */ + uec->uec_regs = uec_regs; + + /* Init UPSMR, enable hardware statistics (UCC) */ + out_be32(&uec->uccf->uf_regs->upsmr, UPSMR_INIT_VALUE); + + /* Init MACCFG1, flow control disable, disable Tx and Rx */ + out_be32(&uec_regs->maccfg1, MACCFG1_INIT_VALUE); + + /* Init MACCFG2, length check, MAC PAD and CRC enable */ + out_be32(&uec_regs->maccfg2, MACCFG2_INIT_VALUE); + + /* Setup MAC interface mode */ + uec_set_mac_if_mode(uec, uec_info->enet_interface); + + /* Setup MII master clock source */ + qe_set_mii_clk_src(uec_info->uf_info.ucc_num); + + /* Setup UTBIPAR */ + utbipar = in_be32(&uec_regs->utbipar); + utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK; + enet_interface = uec->uec_info->enet_interface; + if (enet_interface == ENET_1000_TBI || + enet_interface == ENET_1000_RTBI) { + utbipar |= (uec_info->phy_address + uec_info->uf_info.ucc_num) + << UTBIPAR_PHY_ADDRESS_SHIFT; + } else { + utbipar |= (0x10 + uec_info->uf_info.ucc_num) + << UTBIPAR_PHY_ADDRESS_SHIFT; + } + + out_be32(&uec_regs->utbipar, utbipar); + + /* Allocate Tx BDs */ + length = ((uec_info->tx_bd_ring_len * SIZEOFBD) / + UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) * + UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; + if ((uec_info->tx_bd_ring_len * SIZEOFBD) % + UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) { + length += UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; + } + + align = UEC_TX_BD_RING_ALIGNMENT; + uec->tx_bd_ring_offset = (u32)malloc((u32)(length + align)); + if (uec->tx_bd_ring_offset != 0) { + uec->p_tx_bd_ring = (u8 *)((uec->tx_bd_ring_offset + align) + & ~(align - 1)); + } + + /* Zero all of Tx BDs */ + memset((void *)(uec->tx_bd_ring_offset), 0, length + align); + + /* Allocate Rx BDs */ + length = uec_info->rx_bd_ring_len * SIZEOFBD; + align = UEC_RX_BD_RING_ALIGNMENT; + uec->rx_bd_ring_offset = (u32)(malloc((u32)(length + align))); + if (uec->rx_bd_ring_offset != 0) { + uec->p_rx_bd_ring = (u8 *)((uec->rx_bd_ring_offset + align) + & ~(align - 1)); + } + + /* Zero all of Rx BDs */ + memset((void *)(uec->rx_bd_ring_offset), 0, length + align); + + /* Allocate Rx buffer */ + length = uec_info->rx_bd_ring_len * MAX_RXBUF_LEN; + align = UEC_RX_DATA_BUF_ALIGNMENT; + uec->rx_buf_offset = (u32)malloc(length + align); + if (uec->rx_buf_offset != 0) { + uec->p_rx_buf = (u8 *)((uec->rx_buf_offset + align) + & ~(align - 1)); + } + + /* Zero all of the Rx buffer */ + memset((void *)(uec->rx_buf_offset), 0, length + align); + + /* Init TxBD ring */ + bd = (qe_bd_t *)uec->p_tx_bd_ring; + uec->txBd = bd; + + for (i = 0; i < uec_info->tx_bd_ring_len; i++) { + BD_DATA_CLEAR(bd); + BD_STATUS_SET(bd, 0); + BD_LENGTH_SET(bd, 0); + bd ++; + } + BD_STATUS_SET((--bd), TxBD_WRAP); + + /* Init RxBD ring */ + bd = (qe_bd_t *)uec->p_rx_bd_ring; + uec->rxBd = bd; + buf = uec->p_rx_buf; + for (i = 0; i < uec_info->rx_bd_ring_len; i++) { + BD_DATA_SET(bd, buf); + BD_LENGTH_SET(bd, 0); + BD_STATUS_SET(bd, RxBD_EMPTY); + buf += MAX_RXBUF_LEN; + bd ++; + } + BD_STATUS_SET((--bd), RxBD_WRAP | RxBD_EMPTY); + + /* Init global Tx parameter RAM */ + uec_init_tx_parameter(uec, num_threads_tx); + + /* Init global Rx parameter RAM */ + uec_init_rx_parameter(uec, num_threads_rx); + + /* Init ethernet Tx and Rx parameter command */ + if (uec_issue_init_enet_rxtx_cmd(uec, num_threads_tx, + num_threads_rx)) { + printf("%s issue init enet cmd failed\n", __FUNCTION__); + return -ENOMEM; + } + + return 0; +} + +static int uec_init(struct eth_device* dev, bd_t *bd) +{ + uec_private_t *uec; + int err; + + uec = (uec_private_t *)dev->priv; + + if (uec->the_first_run == 0) { + /* Set up the MAC address */ + if (dev->enetaddr[0] & 0x01) { + printf("%s: MacAddress is multcast address\n", + __FUNCTION__); + return -EINVAL; + } + uec_set_mac_address(uec, dev->enetaddr); + uec->the_first_run = 1; + } + + err = uec_open(uec, COMM_DIR_RX_AND_TX); + if (err) { + printf("%s: cannot enable UEC device\n", dev->name); + return err; + } + + return 0; +} + +static void uec_halt(struct eth_device* dev) +{ + uec_private_t *uec = (uec_private_t *)dev->priv; + uec_stop(uec, COMM_DIR_RX_AND_TX); +} + +static int uec_send(struct eth_device* dev, volatile void *buf, int len) +{ + uec_private_t *uec; + ucc_fast_private_t *uccf; + volatile qe_bd_t *bd; + volatile u16 status; + int i; + int result = 0; + + uec = (uec_private_t *)dev->priv; + uccf = uec->uccf; + bd = uec->txBd; + + /* Find an empty TxBD */ + for (i = 0; BD_STATUS(bd) & TxBD_READY; i++) { + if (i > 0x100000) { + printf("%s: tx buffer not ready\n", dev->name); + return result; + } + } + + /* Init TxBD */ + BD_DATA_SET(bd, buf); + BD_LENGTH_SET(bd, len); + status = BD_STATUS(bd); + status &= BD_WRAP; + status |= (TxBD_READY | TxBD_LAST); + BD_STATUS_SET(bd, status); + + /* Tell UCC to transmit the buffer */ + ucc_fast_transmit_on_demand(uccf); + + /* Wait for buffer to be transmitted */ + status = BD_STATUS(bd); + for (i = 0; status & TxBD_READY; i++) { + if (i > 0x100000) { + printf("%s: tx error\n", dev->name); + return result; + } + status = BD_STATUS(bd); + } + + /* Ok, the buffer be transimitted */ + BD_ADVANCE(bd, status, uec->p_tx_bd_ring); + uec->txBd = bd; + result = 1; + + return result; +} + +static int uec_recv(struct eth_device* dev) +{ + uec_private_t *uec = dev->priv; + volatile qe_bd_t *bd; + volatile u16 status; + u16 len; + u8 *data; + + bd = uec->rxBd; + status = BD_STATUS(bd); + + while (!(status & RxBD_EMPTY)) { + if (!(status & RxBD_ERROR)) { + data = BD_DATA(bd); + len = BD_LENGTH(bd); + NetReceive(data, len); + } else { + printf("%s: Rx error\n", dev->name); + } + status &= BD_CLEAN; + BD_LENGTH_SET(bd, 0); + BD_STATUS_SET(bd, status | RxBD_EMPTY); + BD_ADVANCE(bd, status, uec->p_rx_bd_ring); + status = BD_STATUS(bd); + } + uec->rxBd = bd; + + return 1; +} + +int uec_initialize(int index) +{ + struct eth_device *dev; + int i; + uec_private_t *uec; + uec_info_t *uec_info; + int err; + + dev = (struct eth_device *)malloc(sizeof(struct eth_device)); + if (!dev) + return 0; + memset(dev, 0, sizeof(struct eth_device)); + + /* Allocate the UEC private struct */ + uec = (uec_private_t *)malloc(sizeof(uec_private_t)); + if (!uec) { + return -ENOMEM; + } + memset(uec, 0, sizeof(uec_private_t)); + + /* Init UEC private struct, they come from board.h */ + if (index == 0) { +#ifdef CONFIG_UEC_ETH1 + uec_info = ð1_uec_info; +#endif + } else if (index == 1) { +#ifdef CONFIG_UEC_ETH2 + uec_info = ð2_uec_info; +#endif + } else { + printf("%s: index is illegal.\n", __FUNCTION__); + return -EINVAL; + } + + uec->uec_info = uec_info; + + sprintf(dev->name, "FSL UEC%d", index); + dev->iobase = 0; + dev->priv = (void *)uec; + dev->init = uec_init; + dev->halt = uec_halt; + dev->send = uec_send; + dev->recv = uec_recv; + + /* Clear the ethnet address */ + for (i = 0; i < 6; i++) + dev->enetaddr[i] = 0; + + eth_register(dev); + + err = uec_startup(uec); + if (err) { + printf("%s: Cannot configure net device, aborting.",dev->name); + return err; + } + + err = init_phy(dev); + if (err) { + printf("%s: Cannot initialize PHY, aborting.\n", dev->name); + return err; + } + + phy_change(dev); + + return 1; +} +#endif /* CONFIG_QE */ diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h new file mode 100644 index 0000000..0495026 --- /dev/null +++ b/drivers/qe/uec.h @@ -0,0 +1,716 @@ +/* + * 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 __UEC_H__ +#define __UEC_H__ + +#define MAX_TX_THREADS 8 +#define MAX_RX_THREADS 8 +#define MAX_TX_QUEUES 8 +#define MAX_RX_QUEUES 8 +#define MAX_PREFETCHED_BDS 4 +#define MAX_IPH_OFFSET_ENTRY 8 +#define MAX_ENET_INIT_PARAM_ENTRIES_RX 9 +#define MAX_ENET_INIT_PARAM_ENTRIES_TX 8 + +/* UEC UPSMR (Protocol Specific Mode Register) + */ +#define UPSMR_ECM 0x04000000 /* Enable CAM Miss */ +#define UPSMR_HSE 0x02000000 /* Hardware Statistics Enable */ +#define UPSMR_PRO 0x00400000 /* Promiscuous */ +#define UPSMR_CAP 0x00200000 /* CAM polarity */ +#define UPSMR_RSH 0x00100000 /* Receive Short Frames */ +#define UPSMR_RPM 0x00080000 /* Reduced Pin Mode interfaces */ +#define UPSMR_R10M 0x00040000 /* RGMII/RMII 10 Mode */ +#define UPSMR_RLPB 0x00020000 /* RMII Loopback Mode */ +#define UPSMR_TBIM 0x00010000 /* Ten-bit Interface Mode */ +#define UPSMR_RMM 0x00001000 /* RMII/RGMII Mode */ +#define UPSMR_CAM 0x00000400 /* CAM Address Matching */ +#define UPSMR_BRO 0x00000200 /* Broadcast Address */ +#define UPSMR_RES1 0x00002000 /* Reserved feild - must be 1 */ + +#define UPSMR_INIT_VALUE (UPSMR_HSE | UPSMR_RES1) + +/* UEC MACCFG1 (MAC Configuration 1 Register) + */ +#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control Rx */ +#define MACCFG1_FLOW_TX 0x00000010 /* Flow Control Tx */ +#define MACCFG1_ENABLE_SYNCHED_RX 0x00000008 /* Enable Rx Sync */ +#define MACCFG1_ENABLE_RX 0x00000004 /* Enable Rx */ +#define MACCFG1_ENABLE_SYNCHED_TX 0x00000002 /* Enable Tx Sync */ +#define MACCFG1_ENABLE_TX 0x00000001 /* Enable Tx */ + +#define MACCFG1_INIT_VALUE (0) + +/* UEC MACCFG2 (MAC Configuration 2 Register) + */ +#define MACCFG2_PREL 0x00007000 +#define MACCFG2_PREL_SHIFT (31 - 19) +#define MACCFG2_PREL_MASK 0x0000f000 +#define MACCFG2_SRP 0x00000080 +#define MACCFG2_STP 0x00000040 +#define MACCFG2_RESERVED_1 0x00000020 /* must be set */ +#define MACCFG2_LC 0x00000010 /* Length Check */ +#define MACCFG2_MPE 0x00000008 +#define MACCFG2_FDX 0x00000001 /* Full Duplex */ +#define MACCFG2_FDX_MASK 0x00000001 +#define MACCFG2_PAD_CRC 0x00000004 +#define MACCFG2_CRC_EN 0x00000002 +#define MACCFG2_PAD_AND_CRC_MODE_NONE 0x00000000 +#define MACCFG2_PAD_AND_CRC_MODE_CRC_ONLY 0x00000002 +#define MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC 0x00000004 +#define MACCFG2_INTERFACE_MODE_NIBBLE 0x00000100 +#define MACCFG2_INTERFACE_MODE_BYTE 0x00000200 +#define MACCFG2_INTERFACE_MODE_MASK 0x00000300 + +#define MACCFG2_INIT_VALUE (MACCFG2_PREL | MACCFG2_RESERVED_1 | \ + MACCFG2_LC | MACCFG2_PAD_CRC | MACCFG2_FDX) + +/* UEC Event Register +*/ +#define UCCE_MPD 0x80000000 +#define UCCE_SCAR 0x40000000 +#define UCCE_GRA 0x20000000 +#define UCCE_CBPR 0x10000000 +#define UCCE_BSY 0x08000000 +#define UCCE_RXC 0x04000000 +#define UCCE_TXC 0x02000000 +#define UCCE_TXE 0x01000000 +#define UCCE_TXB7 0x00800000 +#define UCCE_TXB6 0x00400000 +#define UCCE_TXB5 0x00200000 +#define UCCE_TXB4 0x00100000 +#define UCCE_TXB3 0x00080000 +#define UCCE_TXB2 0x00040000 +#define UCCE_TXB1 0x00020000 +#define UCCE_TXB0 0x00010000 +#define UCCE_RXB7 0x00008000 +#define UCCE_RXB6 0x00004000 +#define UCCE_RXB5 0x00002000 +#define UCCE_RXB4 0x00001000 +#define UCCE_RXB3 0x00000800 +#define UCCE_RXB2 0x00000400 +#define UCCE_RXB1 0x00000200 +#define UCCE_RXB0 0x00000100 +#define UCCE_RXF7 0x00000080 +#define UCCE_RXF6 0x00000040 +#define UCCE_RXF5 0x00000020 +#define UCCE_RXF4 0x00000010 +#define UCCE_RXF3 0x00000008 +#define UCCE_RXF2 0x00000004 +#define UCCE_RXF1 0x00000002 +#define UCCE_RXF0 0x00000001 + +#define UCCE_TXB (UCCE_TXB7 | UCCE_TXB6 | UCCE_TXB5 | UCCE_TXB4 | \ + UCCE_TXB3 | UCCE_TXB2 | UCCE_TXB1 | UCCE_TXB0) +#define UCCE_RXB (UCCE_RXB7 | UCCE_RXB6 | UCCE_RXB5 | UCCE_RXB4 | \ + UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0) +#define UCCE_RXF (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 | UCCE_RXF4 | \ + UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0) +#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY | \ + UCCE_RXC | UCCE_TXC | UCCE_TXE) + +/* UEC TEMODR Register +*/ +#define TEMODER_SCHEDULER_ENABLE 0x2000 +#define TEMODER_IP_CHECKSUM_GENERATE 0x0400 +#define TEMODER_PERFORMANCE_OPTIMIZATION_MODE1 0x0200 +#define TEMODER_RMON_STATISTICS 0x0100 +#define TEMODER_NUM_OF_QUEUES_SHIFT (15-15) + +#define TEMODER_INIT_VALUE 0xc000 + +/* UEC REMODR Register +*/ +#define REMODER_RX_RMON_STATISTICS_ENABLE 0x00001000 +#define REMODER_RX_EXTENDED_FEATURES 0x80000000 +#define REMODER_VLAN_OPERATION_TAGGED_SHIFT (31-9 ) +#define REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT (31-10) +#define REMODER_RX_QOS_MODE_SHIFT (31-15) +#define REMODER_RMON_STATISTICS 0x00001000 +#define REMODER_RX_EXTENDED_FILTERING 0x00000800 +#define REMODER_NUM_OF_QUEUES_SHIFT (31-23) +#define REMODER_DYNAMIC_MAX_FRAME_LENGTH 0x00000008 +#define REMODER_DYNAMIC_MIN_FRAME_LENGTH 0x00000004 +#define REMODER_IP_CHECKSUM_CHECK 0x00000002 +#define REMODER_IP_ADDRESS_ALIGNMENT 0x00000001 + +#define REMODER_INIT_VALUE 0 + +/* BMRx - Bus Mode Register */ +#define BMR_GLB 0x20 +#define BMR_BO_BE 0x10 +#define BMR_DTB_SECONDARY_BUS 0x02 +#define BMR_BDB_SECONDARY_BUS 0x01 + +#define BMR_SHIFT 24 +#define BMR_INIT_VALUE (BMR_GLB | BMR_BO_BE) + +/* UEC UCCS (Ethernet Status Register) + */ +#define UCCS_BPR 0x02 +#define UCCS_PAU 0x02 +#define UCCS_MPD 0x01 + +/* UEC MIIMCFG (MII Management Configuration Register) + */ +#define MIIMCFG_RESET_MANAGEMENT 0x80000000 +#define MIIMCFG_NO_PREAMBLE 0x00000010 +#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) +#define MIIMCFG_CLOCK_DIVIDE_MASK 0x0000000f +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006 +#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007 + +#define MIIMCFG_MNGMNT_CLC_DIV_INIT_VALUE \ + MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 + +/* UEC MIIMCOM (MII Management Command Register) + */ +#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */ +#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */ + +/* UEC MIIMADD (MII Management Address Register) + */ +#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) +#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) + +/* UEC MIIMCON (MII Management Control Register) + */ +#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) +#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) + +/* UEC MIIMIND (MII Management Indicator Register) + */ +#define MIIMIND_NOT_VALID 0x00000004 +#define MIIMIND_SCAN 0x00000002 +#define MIIMIND_BUSY 0x00000001 + +/* UEC UTBIPAR (Ten Bit Interface Physical Address Register) + */ +#define UTBIPAR_PHY_ADDRESS_SHIFT (31 - 31) +#define UTBIPAR_PHY_ADDRESS_MASK 0x0000001f + +/* UEC UESCR (Ethernet Statistics Control Register) + */ +#define UESCR_AUTOZ 0x8000 +#define UESCR_CLRCNT 0x4000 +#define UESCR_MAXCOV_SHIFT (15 - 7) +#define UESCR_SCOV_SHIFT (15 - 15) + +/****** Tx data struct collection ******/ +/* Tx thread data, each Tx thread has one this struct. +*/ +typedef struct uec_thread_data_tx { + u8 res0[136]; +} __attribute__ ((packed)) uec_thread_data_tx_t; + +/* Tx thread parameter, each Tx thread has one this struct. +*/ +typedef struct uec_thread_tx_pram { + u8 res0[64]; +} __attribute__ ((packed)) uec_thread_tx_pram_t; + +/* Send queue queue-descriptor, each Tx queue has one this QD +*/ +typedef struct uec_send_queue_qd { + u32 bd_ring_base; /* pointer to BD ring base address */ + u8 res0[0x8]; + u32 last_bd_completed_address; /* last entry in BD ring */ + u8 res1[0x30]; +} __attribute__ ((packed)) uec_send_queue_qd_t; + +/* Send queue memory region */ +typedef struct uec_send_queue_mem_region { + uec_send_queue_qd_t sqqd[MAX_TX_QUEUES]; +} __attribute__ ((packed)) uec_send_queue_mem_region_t; + +/* Scheduler struct +*/ +typedef struct uec_scheduler { + u16 cpucount0; /* CPU packet counter */ + u16 cpucount1; /* CPU packet counter */ + u16 cecount0; /* QE packet counter */ + u16 cecount1; /* QE packet counter */ + u16 cpucount2; /* CPU packet counter */ + u16 cpucount3; /* CPU packet counter */ + u16 cecount2; /* QE packet counter */ + u16 cecount3; /* QE packet counter */ + u16 cpucount4; /* CPU packet counter */ + u16 cpucount5; /* CPU packet counter */ + u16 cecount4; /* QE packet counter */ + u16 cecount5; /* QE packet counter */ + u16 cpucount6; /* CPU packet counter */ + u16 cpucount7; /* CPU packet counter */ + u16 cecount6; /* QE packet counter */ + u16 cecount7; /* QE packet counter */ + u32 weightstatus[MAX_TX_QUEUES]; /* accumulated weight factor */ + u32 rtsrshadow; /* temporary variable handled by QE */ + u32 time; /* temporary variable handled by QE */ + u32 ttl; /* temporary variable handled by QE */ + u32 mblinterval; /* max burst length interval */ + u16 nortsrbytetime; /* normalized value of byte time in tsr units */ + u8 fracsiz; + u8 res0[1]; + u8 strictpriorityq; /* Strict Priority Mask register */ + u8 txasap; /* Transmit ASAP register */ + u8 extrabw; /* Extra BandWidth register */ + u8 oldwfqmask; /* temporary variable handled by QE */ + u8 weightfactor[MAX_TX_QUEUES]; /**< weight factor for queues */ + u32 minw; /* temporary variable handled by QE */ + u8 res1[0x70-0x64]; +} __attribute__ ((packed)) uec_scheduler_t; + +/* Tx firmware counters +*/ +typedef struct uec_tx_firmware_statistics_pram { + u32 sicoltx; /* single collision */ + u32 mulcoltx; /* multiple collision */ + u32 latecoltxfr; /* late collision */ + u32 frabortduecol; /* frames aborted due to tx collision */ + u32 frlostinmactxer; /* frames lost due to internal MAC error tx */ + u32 carriersenseertx; /* carrier sense error */ + u32 frtxok; /* frames transmitted OK */ + u32 txfrexcessivedefer; + u32 txpkts256; /* total packets(including bad) 256~511 B */ + u32 txpkts512; /* total packets(including bad) 512~1023B */ + u32 txpkts1024; /* total packets(including bad) 1024~1518B */ + u32 txpktsjumbo; /* total packets(including bad) >1024 */ +} __attribute__ ((packed)) uec_tx_firmware_statistics_pram_t; + +/* Tx global parameter table +*/ +typedef struct uec_tx_global_pram { + u16 temoder; + u8 res0[0x38-0x02]; + u32 sqptr; + u32 schedulerbasepointer; + u32 txrmonbaseptr; + u32 tstate; + u8 iphoffset[MAX_IPH_OFFSET_ENTRY]; + u32 vtagtable[0x8]; + u32 tqptr; + u8 res2[0x80-0x74]; +} __attribute__ ((packed)) uec_tx_global_pram_t; + + +/****** Rx data struct collection ******/ +/* Rx thread data, each Rx thread has one this struct. +*/ +typedef struct uec_thread_data_rx { + u8 res0[40]; +} __attribute__ ((packed)) uec_thread_data_rx_t; + +/* Rx thread parameter, each Rx thread has one this struct. +*/ +typedef struct uec_thread_rx_pram { + u8 res0[128]; +} __attribute__ ((packed)) uec_thread_rx_pram_t; + +/* Rx firmware counters +*/ +typedef struct uec_rx_firmware_statistics_pram { + u32 frrxfcser; /* frames with crc error */ + u32 fraligner; /* frames with alignment error */ + u32 inrangelenrxer; /* in range length error */ + u32 outrangelenrxer; /* out of range length error */ + u32 frtoolong; /* frame too long */ + u32 runt; /* runt */ + u32 verylongevent; /* very long event */ + u32 symbolerror; /* symbol error */ + u32 dropbsy; /* drop because of BD not ready */ + u8 res0[0x8]; + u32 mismatchdrop; /* drop because of MAC filtering */ + u32 underpkts; /* total frames less than 64 octets */ + u32 pkts256; /* total frames(including bad)256~511 B */ + u32 pkts512; /* total frames(including bad)512~1023 B */ + u32 pkts1024; /* total frames(including bad)1024~1518 B */ + u32 pktsjumbo; /* total frames(including bad) >1024 B */ + u32 frlossinmacer; + u32 pausefr; /* pause frames */ + u8 res1[0x4]; + u32 removevlan; + u32 replacevlan; + u32 insertvlan; +} __attribute__ ((packed)) uec_rx_firmware_statistics_pram_t; + +/* Rx interrupt coalescing entry, each Rx queue has one this entry. +*/ +typedef struct uec_rx_interrupt_coalescing_entry { + u32 maxvalue; + u32 counter; +} __attribute__ ((packed)) uec_rx_interrupt_coalescing_entry_t; + +typedef struct uec_rx_interrupt_coalescing_table { + uec_rx_interrupt_coalescing_entry_t entry[MAX_RX_QUEUES]; +} __attribute__ ((packed)) uec_rx_interrupt_coalescing_table_t; + +/* RxBD queue entry, each Rx queue has one this entry. +*/ +typedef struct uec_rx_bd_queues_entry { + u32 bdbaseptr; /* BD base pointer */ + u32 bdptr; /* BD pointer */ + u32 externalbdbaseptr; /* external BD base pointer */ + u32 externalbdptr; /* external BD pointer */ +} __attribute__ ((packed)) uec_rx_bd_queues_entry_t; + +/* Rx global paramter table +*/ +typedef struct uec_rx_global_pram { + u32 remoder; /* ethernet mode reg. */ + u32 rqptr; /* base pointer to the Rx Queues */ + u32 res0[0x1]; + u8 res1[0x20-0xC]; + u16 typeorlen; + u8 res2[0x1]; + u8 rxgstpack; /* ack on GRACEFUL STOP RX command */ + u32 rxrmonbaseptr; /* Rx RMON statistics base */ + u8 res3[0x30-0x28]; + u32 intcoalescingptr; /* Interrupt coalescing table pointer */ + u8 res4[0x36-0x34]; + u8 rstate; + u8 res5[0x46-0x37]; + u16 mrblr; /* max receive buffer length reg. */ + u32 rbdqptr; /* RxBD parameter table description */ + u16 mflr; /* max frame length reg. */ + u16 minflr; /* min frame length reg. */ + u16 maxd1; /* max dma1 length reg. */ + u16 maxd2; /* max dma2 length reg. */ + u32 ecamptr; /* external CAM address */ + u32 l2qt; /* VLAN priority mapping table. */ + u32 l3qt[0x8]; /* IP priority mapping table. */ + u16 vlantype; /* vlan type */ + u16 vlantci; /* default vlan tci */ + u8 addressfiltering[64];/* address filtering data structure */ + u32 exfGlobalParam; /* extended filtering global parameters */ + u8 res6[0x100-0xC4]; /* Initialize to zero */ +} __attribute__ ((packed)) uec_rx_global_pram_t; + +#define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 + + +/****** UEC common ******/ +/* UCC statistics - hardware counters +*/ +typedef struct uec_hardware_statistics { + u32 tx64; + u32 tx127; + u32 tx255; + u32 rx64; + u32 rx127; + u32 rx255; + u32 txok; + u16 txcf; + u32 tmca; + u32 tbca; + u32 rxfok; + u32 rxbok; + u32 rbyt; + u32 rmca; + u32 rbca; +} __attribute__ ((packed)) uec_hardware_statistics_t; + +/* InitEnet command parameter +*/ +typedef struct uec_init_cmd_pram { + u8 resinit0; + u8 resinit1; + u8 resinit2; + u8 resinit3; + u16 resinit4; + u8 res1[0x1]; + u8 largestexternallookupkeysize; + u32 rgftgfrxglobal; + u32 rxthread[MAX_ENET_INIT_PARAM_ENTRIES_RX]; /* rx threads */ + u8 res2[0x38 - 0x30]; + u32 txglobal; /* tx global */ + u32 txthread[MAX_ENET_INIT_PARAM_ENTRIES_TX]; /* tx threads */ + u8 res3[0x1]; +} __attribute__ ((packed)) uec_init_cmd_pram_t; + +#define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) +#define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) + +#define ENET_INIT_PARAM_RISC_MASK 0x0000003f +#define ENET_INIT_PARAM_PTR_MASK 0x00ffffc0 +#define ENET_INIT_PARAM_SNUM_MASK 0xff000000 +#define ENET_INIT_PARAM_SNUM_SHIFT 24 + +#define ENET_INIT_PARAM_MAGIC_RES_INIT0 0x06 +#define ENET_INIT_PARAM_MAGIC_RES_INIT1 0x30 +#define ENET_INIT_PARAM_MAGIC_RES_INIT2 0xff +#define ENET_INIT_PARAM_MAGIC_RES_INIT3 0x00 +#define ENET_INIT_PARAM_MAGIC_RES_INIT4 0x0400 + +/* structure representing 82xx Address Filtering Enet Address in PRAM +*/ +typedef struct uec_82xx_enet_address { + u8 res1[0x2]; + u16 h; /* address (MSB) */ + u16 m; /* address */ + u16 l; /* address (LSB) */ +} __attribute__ ((packed)) uec_82xx_enet_address_t; + +/* structure representing 82xx Address Filtering PRAM +*/ +typedef struct uec_82xx_address_filtering_pram { + u32 iaddr_h; /* individual address filter, high */ + u32 iaddr_l; /* individual address filter, low */ + u32 gaddr_h; /* group address filter, high */ + u32 gaddr_l; /* group address filter, low */ + uec_82xx_enet_address_t taddr; + uec_82xx_enet_address_t paddr[4]; + u8 res0[0x40-0x38]; +} __attribute__ ((packed)) uec_82xx_address_filtering_pram_t; + +/* Buffer Descriptor +*/ +typedef struct buffer_descriptor { + u16 status; + u16 len; + u32 data; +} __attribute__ ((packed)) qe_bd_t, *p_bd_t; + +#define SIZEOFBD sizeof(qe_bd_t) + +/* Common BD flags +*/ +#define BD_WRAP 0x2000 +#define BD_INT 0x1000 +#define BD_LAST 0x0800 +#define BD_CLEAN 0x3000 + +/* TxBD status flags +*/ +#define TxBD_READY 0x8000 +#define TxBD_PADCRC 0x4000 +#define TxBD_WRAP BD_WRAP +#define TxBD_INT BD_INT +#define TxBD_LAST BD_LAST +#define TxBD_TXCRC 0x0400 +#define TxBD_DEF 0x0200 +#define TxBD_PP 0x0100 +#define TxBD_LC 0x0080 +#define TxBD_RL 0x0040 +#define TxBD_RC 0x003C +#define TxBD_UNDERRUN 0x0002 +#define TxBD_TRUNC 0x0001 + +#define TxBD_ERROR (TxBD_UNDERRUN | TxBD_TRUNC) + +/* RxBD status flags +*/ +#define RxBD_EMPTY 0x8000 +#define RxBD_OWNER 0x4000 +#define RxBD_WRAP BD_WRAP +#define RxBD_INT BD_INT +#define RxBD_LAST BD_LAST +#define RxBD_FIRST 0x0400 +#define RxBD_CMR 0x0200 +#define RxBD_MISS 0x0100 +#define RxBD_BCAST 0x0080 +#define RxBD_MCAST 0x0040 +#define RxBD_LG 0x0020 +#define RxBD_NO 0x0010 +#define RxBD_SHORT 0x0008 +#define RxBD_CRCERR 0x0004 +#define RxBD_OVERRUN 0x0002 +#define RxBD_IPCH 0x0001 + +#define RxBD_ERROR (RxBD_LG | RxBD_NO | RxBD_SHORT | \ + RxBD_CRCERR | RxBD_OVERRUN) + +/* BD access macros +*/ +#define BD_STATUS(_bd) (((p_bd_t)(_bd))->status) +#define BD_STATUS_SET(_bd, _val) (((p_bd_t)(_bd))->status = _val) +#define BD_LENGTH(_bd) (((p_bd_t)(_bd))->len) +#define BD_LENGTH_SET(_bd, _val) (((p_bd_t)(_bd))->len = _val) +#define BD_DATA_CLEAR(_bd) (((p_bd_t)(_bd))->data = 0) +#define BD_IS_DATA(_bd) (((p_bd_t)(_bd))->data) +#define BD_DATA(_bd) ((u8 *)(((p_bd_t)(_bd))->data)) +#define BD_DATA_SET(_bd, _data) (((p_bd_t)(_bd))->data = (u32)(_data)) +#define BD_ADVANCE(_bd,_status,_base) \ + (((_status) & BD_WRAP) ? (_bd) = ((p_bd_t)(_base)) : ++(_bd)) + +/* Rx Prefetched BDs +*/ +typedef struct uec_rx_prefetched_bds { + qe_bd_t bd[MAX_PREFETCHED_BDS]; /* prefetched bd */ +} __attribute__ ((packed)) uec_rx_prefetched_bds_t; + +/* Alignments + */ +#define UEC_RX_GLOBAL_PRAM_ALIGNMENT 64 +#define UEC_TX_GLOBAL_PRAM_ALIGNMENT 64 +#define UEC_THREAD_RX_PRAM_ALIGNMENT 128 +#define UEC_THREAD_TX_PRAM_ALIGNMENT 64 +#define UEC_THREAD_DATA_ALIGNMENT 256 +#define UEC_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT 32 +#define UEC_SCHEDULER_ALIGNMENT 4 +#define UEC_TX_STATISTICS_ALIGNMENT 4 +#define UEC_RX_STATISTICS_ALIGNMENT 4 +#define UEC_RX_INTERRUPT_COALESCING_ALIGNMENT 4 +#define UEC_RX_BD_QUEUES_ALIGNMENT 8 +#define UEC_RX_PREFETCHED_BDS_ALIGNMENT 128 +#define UEC_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 +#define UEC_RX_BD_RING_ALIGNMENT 32 +#define UEC_TX_BD_RING_ALIGNMENT 32 +#define UEC_MRBLR_ALIGNMENT 128 +#define UEC_RX_BD_RING_SIZE_ALIGNMENT 4 +#define UEC_TX_BD_RING_SIZE_MEMORY_ALIGNMENT 32 +#define UEC_RX_DATA_BUF_ALIGNMENT 64 + +#define UEC_VLAN_PRIORITY_MAX 8 +#define UEC_IP_PRIORITY_MAX 64 +#define UEC_TX_VTAG_TABLE_ENTRY_MAX 8 +#define UEC_RX_BD_RING_SIZE_MIN 8 +#define UEC_TX_BD_RING_SIZE_MIN 2 + +/* Ethernet speed +*/ +typedef enum enet_speed { + ENET_SPEED_10BT, /* 10 Base T */ + ENET_SPEED_100BT, /* 100 Base T */ + ENET_SPEED_1000BT /* 1000 Base T */ +} enet_speed_e; + +/* Ethernet Address Type. +*/ +typedef enum enet_addr_type { + ENET_ADDR_TYPE_INDIVIDUAL, + ENET_ADDR_TYPE_GROUP, + ENET_ADDR_TYPE_BROADCAST +} enet_addr_type_e; + +/* TBI / MII Set Register +*/ +typedef enum enet_tbi_mii_reg { + ENET_TBI_MII_CR = 0x00, + ENET_TBI_MII_SR = 0x01, + ENET_TBI_MII_ANA = 0x04, + ENET_TBI_MII_ANLPBPA = 0x05, + ENET_TBI_MII_ANEX = 0x06, + ENET_TBI_MII_ANNPT = 0x07, + ENET_TBI_MII_ANLPANP = 0x08, + ENET_TBI_MII_EXST = 0x0F, + ENET_TBI_MII_JD = 0x10, + ENET_TBI_MII_TBICON = 0x11 +} enet_tbi_mii_reg_e; + +/* UEC number of threads +*/ +typedef enum uec_num_of_threads { + UEC_NUM_OF_THREADS_1 = 0x1, /* 1 */ + UEC_NUM_OF_THREADS_2 = 0x2, /* 2 */ + UEC_NUM_OF_THREADS_4 = 0x0, /* 4 */ + UEC_NUM_OF_THREADS_6 = 0x3, /* 6 */ + UEC_NUM_OF_THREADS_8 = 0x4 /* 8 */ +} uec_num_of_threads_e; + +/* UEC ethernet interface type +*/ +typedef enum enet_interface { + ENET_10_MII, + ENET_10_RMII, + ENET_10_RGMII, + ENET_100_MII, + ENET_100_RMII, + ENET_100_RGMII, + ENET_1000_GMII, + ENET_1000_RGMII, + ENET_1000_TBI, + ENET_1000_RTBI +} enet_interface_e; + +/* UEC initialization info struct +*/ +typedef struct uec_info { + ucc_fast_info_t uf_info; + uec_num_of_threads_e num_threads_tx; + uec_num_of_threads_e num_threads_rx; + qe_risc_allocation_e riscTx; + qe_risc_allocation_e riscRx; + u16 rx_bd_ring_len; + u16 tx_bd_ring_len; + u8 phy_address; + enet_interface_e enet_interface; +} uec_info_t; + +/* UEC driver initialized info +*/ +#define MAX_RXBUF_LEN 1536 +#define MAX_FRAME_LEN 1518 +#define MIN_FRAME_LEN 64 +#define MAX_DMA1_LEN 1520 +#define MAX_DMA2_LEN 1520 + +/* UEC driver private struct +*/ +typedef struct uec_private { + uec_info_t *uec_info; + ucc_fast_private_t *uccf; + struct eth_device *dev; + uec_t *uec_regs; + /* enet init command parameter */ + uec_init_cmd_pram_t *p_init_enet_param; + u32 init_enet_param_offset; + /* Rx and Tx paramter */ + uec_rx_global_pram_t *p_rx_glbl_pram; + u32 rx_glbl_pram_offset; + uec_tx_global_pram_t *p_tx_glbl_pram; + u32 tx_glbl_pram_offset; + uec_send_queue_mem_region_t *p_send_q_mem_reg; + u32 send_q_mem_reg_offset; + uec_thread_data_tx_t *p_thread_data_tx; + u32 thread_dat_tx_offset; + uec_thread_data_rx_t *p_thread_data_rx; + u32 thread_dat_rx_offset; + uec_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; + u32 rx_bd_qs_tbl_offset; + /* BDs specific */ + u8 *p_tx_bd_ring; + u32 tx_bd_ring_offset; + u8 *p_rx_bd_ring; + u32 rx_bd_ring_offset; + u8 *p_rx_buf; + u32 rx_buf_offset; + volatile qe_bd_t *txBd; + volatile qe_bd_t *rxBd; + /* Status */ + int mac_tx_enabled; + int mac_rx_enabled; + int grace_stopped_tx; + int grace_stopped_rx; + int the_first_run; + /* PHY specific */ + struct uec_mii_info *mii_info; + int oldspeed; + int oldduplex; + int oldlink; +} uec_private_t; + +#endif /* __UEC_H__ */ diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c new file mode 100644 index 0000000..76fd388 --- /dev/null +++ b/drivers/qe/uec_phy.c @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2005 Freescale Semiconductor, Inc. + * + * Author: Shlomi Gridish + * + * Description: UCC GETH Driver -- PHY handling + * Driver for UEC on QE + * Based on 8260_io/fcc_enet.c + * + * 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 "net.h" +#include "malloc.h" +#include "asm/errno.h" +#include "asm/immap_qe.h" +#include "asm/io.h" +#include "qe.h" +#include "uccf.h" +#include "uec.h" +#include "uec_phy.h" +#include "miiphy.h" + +#if defined(CONFIG_QE) + +#define UEC_VERBOSE_DEBUG +#define ugphy_printk(format, arg...) \ + printf(format "\n", ## arg) + +#define ugphy_dbg(format, arg...) \ + ugphy_printk(format , ## arg) +#define ugphy_err(format, arg...) \ + ugphy_printk(format , ## arg) +#define ugphy_info(format, arg...) \ + ugphy_printk(format , ## arg) +#define ugphy_warn(format, arg...) \ + ugphy_printk(format , ## arg) + +#ifdef UEC_VERBOSE_DEBUG +#define ugphy_vdbg ugphy_dbg +#else +#define ugphy_vdbg(ugeth, fmt, args...) do { } while (0) +#endif /* UEC_VERBOSE_DEBUG */ + +static void config_genmii_advert (struct uec_mii_info *mii_info); +static void genmii_setup_forced (struct uec_mii_info *mii_info); +static void genmii_restart_aneg (struct uec_mii_info *mii_info); +static int gbit_config_aneg (struct uec_mii_info *mii_info); +static int genmii_config_aneg (struct uec_mii_info *mii_info); +static int genmii_update_link (struct uec_mii_info *mii_info); +static int genmii_read_status (struct uec_mii_info *mii_info); +u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); +void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); + +/* Write value to the PHY for this device to the register at regnum, */ +/* waiting until the write is done before it returns. All PHY */ +/* configuration has to be done through the TSEC1 MIIM regs */ +void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int value) +{ + uec_private_t *ugeth = (uec_private_t *) dev->priv; + uec_t *ug_regs; + enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; + u32 tmp_reg; + + ug_regs = ugeth->uec_regs; + + /* Stop the MII management read cycle */ + out_be32 (&ug_regs->miimcom, 0); + /* Setting up the MII Mangement Address Register */ + tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; + out_be32 (&ug_regs->miimadd, tmp_reg); + + /* Setting up the MII Mangement Control Register with the value */ + out_be32 (&ug_regs->miimcon, (u32) value); + + /* Wait till MII management write is complete */ + while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); + + udelay (100000); +} + +/* Reads from register regnum in the PHY for device dev, */ +/* returning the value. Clears miimcom first. All PHY */ +/* configuration has to be done through the TSEC1 MIIM regs */ +int read_phy_reg (struct eth_device *dev, int mii_id, int regnum) +{ + uec_private_t *ugeth = (uec_private_t *) dev->priv; + uec_t *ug_regs; + enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; + u32 tmp_reg; + u16 value; + + ug_regs = ugeth->uec_regs; + + /* Setting up the MII Mangement Address Register */ + tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; + out_be32 (&ug_regs->miimadd, tmp_reg); + + /* Perform an MII management read cycle */ + out_be32 (&ug_regs->miimcom, 0); + out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); + + /* Wait till MII management write is complete */ + while ((in_be32 (&ug_regs->miimind)) & + (MIIMIND_NOT_VALID | MIIMIND_BUSY)); + + udelay (100000); + + /* Read MII management status */ + value = (u16) in_be32 (&ug_regs->miimstat); + if (value == 0xffff) + ugphy_warn + ("read wrong value : mii_id %d,mii_reg %d, base %08x", + mii_id, mii_reg, (u32) & (ug_regs->miimcfg)); + + return (value); +} + +void mii_clear_phy_interrupt (struct uec_mii_info *mii_info) +{ + if (mii_info->phyinfo->ack_interrupt) + mii_info->phyinfo->ack_interrupt (mii_info); +} + +void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, + u32 interrupts) +{ + mii_info->interrupts = interrupts; + if (mii_info->phyinfo->config_intr) + mii_info->phyinfo->config_intr (mii_info); +} + +/* Writes MII_ADVERTISE with the appropriate values, after + * sanitizing advertise to make sure only supported features + * are advertised + */ +static void config_genmii_advert (struct uec_mii_info *mii_info) +{ + u32 advertise; + u16 adv; + + /* Only allow advertising what this PHY supports */ + mii_info->advertising &= mii_info->phyinfo->features; + advertise = mii_info->advertising; + + /* Setup standard advertisement */ + adv = phy_read (mii_info, PHY_ANAR); + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); + if (advertise & ADVERTISED_10baseT_Half) + adv |= ADVERTISE_10HALF; + if (advertise & ADVERTISED_10baseT_Full) + adv |= ADVERTISE_10FULL; + if (advertise & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + phy_write (mii_info, PHY_ANAR, adv); +} + +static void genmii_setup_forced (struct uec_mii_info *mii_info) +{ + u16 ctrl; + u32 features = mii_info->phyinfo->features; + + ctrl = phy_read (mii_info, PHY_BMCR); + + ctrl &= ~(PHY_BMCR_DPLX | PHY_BMCR_100_MBPS | + PHY_BMCR_1000_MBPS | PHY_BMCR_AUTON); + ctrl |= PHY_BMCR_RESET; + + switch (mii_info->speed) { + case SPEED_1000: + if (features & (SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full)) { + ctrl |= PHY_BMCR_1000_MBPS; + break; + } + mii_info->speed = SPEED_100; + case SPEED_100: + if (features & (SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full)) { + ctrl |= PHY_BMCR_100_MBPS; + break; + } + mii_info->speed = SPEED_10; + case SPEED_10: + if (features & (SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full)) + break; + default: /* Unsupported speed! */ + ugphy_err ("%s: Bad speed!", mii_info->dev->name); + break; + } + + phy_write (mii_info, PHY_BMCR, ctrl); +} + +/* Enable and Restart Autonegotiation */ +static void genmii_restart_aneg (struct uec_mii_info *mii_info) +{ + u16 ctl; + + ctl = phy_read (mii_info, PHY_BMCR); + ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); + phy_write (mii_info, PHY_BMCR, ctl); +} + +static int gbit_config_aneg (struct uec_mii_info *mii_info) +{ + u16 adv; + u32 advertise; + + if (mii_info->autoneg) { + /* Configure the ADVERTISE register */ + config_genmii_advert (mii_info); + advertise = mii_info->advertising; + + adv = phy_read (mii_info, MII_1000BASETCONTROL); + adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | + MII_1000BASETCONTROL_HALFDUPLEXCAP); + if (advertise & SUPPORTED_1000baseT_Half) + adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; + if (advertise & SUPPORTED_1000baseT_Full) + adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; + phy_write (mii_info, MII_1000BASETCONTROL, adv); + + /* Start/Restart aneg */ + genmii_restart_aneg (mii_info); + } else + genmii_setup_forced (mii_info); + + return 0; +} + +static int marvell_config_aneg (struct uec_mii_info *mii_info) +{ + /* The Marvell PHY has an errata which requires + * that certain registers get written in order + * to restart autonegotiation */ + phy_write (mii_info, PHY_BMCR, PHY_BMCR_RESET); + + phy_write (mii_info, 0x1d, 0x1f); + phy_write (mii_info, 0x1e, 0x200c); + phy_write (mii_info, 0x1d, 0x5); + phy_write (mii_info, 0x1e, 0); + phy_write (mii_info, 0x1e, 0x100); + + gbit_config_aneg (mii_info); + + return 0; +} + +static int genmii_config_aneg (struct uec_mii_info *mii_info) +{ + if (mii_info->autoneg) { + config_genmii_advert (mii_info); + genmii_restart_aneg (mii_info); + } else + genmii_setup_forced (mii_info); + + return 0; +} + +static int genmii_update_link (struct uec_mii_info *mii_info) +{ + u16 status; + + /* Do a fake read */ + phy_read (mii_info, PHY_BMSR); + + /* Read link and autonegotiation status */ + status = phy_read (mii_info, PHY_BMSR); + if ((status & PHY_BMSR_LS) == 0) + mii_info->link = 0; + else + mii_info->link = 1; + + /* If we are autonegotiating, and not done, + * return an error */ + if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP)) + return -EAGAIN; + + return 0; +} + +static int genmii_read_status (struct uec_mii_info *mii_info) +{ + u16 status; + int err; + + /* Update the link, but return if there + * was an error */ + err = genmii_update_link (mii_info); + if (err) + return err; + + if (mii_info->autoneg) { + status = phy_read (mii_info, PHY_ANLPAR); + + if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) + mii_info->speed = SPEED_100; + else + mii_info->speed = SPEED_10; + mii_info->pause = 0; + } + /* On non-aneg, we assume what we put in BMCR is the speed, + * though magic-aneg shouldn't prevent this case from occurring + */ + + return 0; +} + +static int marvell_read_status (struct uec_mii_info *mii_info) +{ + u16 status; + int err; + + /* Update the link, but return if there + * was an error */ + err = genmii_update_link (mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int speed; + + status = phy_read (mii_info, MII_M1011_PHY_SPEC_STATUS); + + /* Get the duplexity */ + if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + + /* Get the speed */ + speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; + switch (speed) { + case MII_M1011_PHY_SPEC_STATUS_1000: + mii_info->speed = SPEED_1000; + break; + case MII_M1011_PHY_SPEC_STATUS_100: + mii_info->speed = SPEED_100; + break; + default: + mii_info->speed = SPEED_10; + break; + } + mii_info->pause = 0; + } + + return 0; +} + +static int marvell_ack_interrupt (struct uec_mii_info *mii_info) +{ + /* Clear the interrupts by reading the reg */ + phy_read (mii_info, MII_M1011_IEVENT); + + return 0; +} + +static int marvell_config_intr (struct uec_mii_info *mii_info) +{ + if (mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); + else + phy_write (mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); + + return 0; +} + +static int dm9161_init (struct uec_mii_info *mii_info) +{ + /* Reset the PHY */ + phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) | + PHY_BMCR_RESET); + /* PHY and MAC connect */ + phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) & + ~PHY_BMCR_ISO); +#ifdef CONFIG_RMII_MODE + phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_RMII_INIT); +#else + phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); +#endif + config_genmii_advert (mii_info); + /* Start/restart aneg */ + genmii_config_aneg (mii_info); + /* Delay to wait the aneg compeleted */ + udelay (3000000); + + return 0; +} + +static int dm9161_config_aneg (struct uec_mii_info *mii_info) +{ + return 0; +} + +static int dm9161_read_status (struct uec_mii_info *mii_info) +{ + u16 status; + int err; + + /* Update the link, but return if there was an error */ + err = genmii_update_link (mii_info); + if (err) + return err; + /* If the link is up, read the speed and duplex + If we aren't autonegotiating assume speeds are as set */ + if (mii_info->autoneg && mii_info->link) { + status = phy_read (mii_info, MII_DM9161_SCSR); + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) + mii_info->speed = SPEED_100; + else + mii_info->speed = SPEED_10; + + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + } + + return 0; +} + +static int dm9161_ack_interrupt (struct uec_mii_info *mii_info) +{ + /* Clear the interrupt by reading the reg */ + phy_read (mii_info, MII_DM9161_INTR); + + return 0; +} + +static int dm9161_config_intr (struct uec_mii_info *mii_info) +{ + if (mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); + else + phy_write (mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); + + return 0; +} + +static void dm9161_close (struct uec_mii_info *mii_info) +{ +} + +static struct phy_info phy_info_dm9161 = { + .phy_id = 0x0181b880, + .phy_id_mask = 0x0ffffff0, + .name = "Davicom DM9161E", + .init = dm9161_init, + .config_aneg = dm9161_config_aneg, + .read_status = dm9161_read_status, + .close = dm9161_close, +}; + +static struct phy_info phy_info_dm9161a = { + .phy_id = 0x0181b8a0, + .phy_id_mask = 0x0ffffff0, + .name = "Davicom DM9161A", + .features = MII_BASIC_FEATURES, + .init = dm9161_init, + .config_aneg = dm9161_config_aneg, + .read_status = dm9161_read_status, + .ack_interrupt = dm9161_ack_interrupt, + .config_intr = dm9161_config_intr, + .close = dm9161_close, +}; + +static struct phy_info phy_info_marvell = { + .phy_id = 0x01410c00, + .phy_id_mask = 0xffffff00, + .name = "Marvell 88E11x1", + .features = MII_GBIT_FEATURES, + .config_aneg = &marvell_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, +}; + +static struct phy_info phy_info_genmii = { + .phy_id = 0x00000000, + .phy_id_mask = 0x00000000, + .name = "Generic MII", + .features = MII_BASIC_FEATURES, + .config_aneg = genmii_config_aneg, + .read_status = genmii_read_status, +}; + +static struct phy_info *phy_info[] = { + &phy_info_dm9161, + &phy_info_dm9161a, + &phy_info_marvell, + &phy_info_genmii, + NULL +}; + +u16 phy_read (struct uec_mii_info *mii_info, u16 regnum) +{ + return mii_info->mdio_read (mii_info->dev, mii_info->mii_id, regnum); +} + +void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val) +{ + mii_info->mdio_write (mii_info->dev, mii_info->mii_id, regnum, val); +} + +/* Use the PHY ID registers to determine what type of PHY is attached + * to device dev. return a struct phy_info structure describing that PHY + */ +struct phy_info *get_phy_info (struct uec_mii_info *mii_info) +{ + u16 phy_reg; + u32 phy_ID; + int i; + struct phy_info *theInfo = NULL; + + /* Grab the bits from PHYIR1, and put them in the upper half */ + phy_reg = phy_read (mii_info, PHY_PHYIDR1); + phy_ID = (phy_reg & 0xffff) << 16; + + /* Grab the bits from PHYIR2, and put them in the lower half */ + phy_reg = phy_read (mii_info, PHY_PHYIDR2); + phy_ID |= (phy_reg & 0xffff); + + /* loop through all the known PHY types, and find one that */ + /* matches the ID we read from the PHY. */ + for (i = 0; phy_info[i]; i++) + if (phy_info[i]->phy_id == + (phy_ID & phy_info[i]->phy_id_mask)) { + theInfo = phy_info[i]; + break; + } + + /* This shouldn't happen, as we have generic PHY support */ + if (theInfo == NULL) { + ugphy_info ("UEC: PHY id %x is not supported!", phy_ID); + return NULL; + } else { + ugphy_info ("UEC: PHY is %s (%x)", theInfo->name, phy_ID); + } + + return theInfo; +} + +void marvell_phy_interface_mode (struct eth_device *dev, + enet_interface_e mode) +{ + uec_private_t *uec = (uec_private_t *) dev->priv; + struct uec_mii_info *mii_info; + + if (!uec->mii_info) { + printf ("%s: the PHY not intialized\n", __FUNCTION__); + return; + } + mii_info = uec->mii_info; + + if (mode == ENET_100_RGMII) { + phy_write (mii_info, 0x00, 0x9140); + phy_write (mii_info, 0x1d, 0x001f); + phy_write (mii_info, 0x1e, 0x200c); + phy_write (mii_info, 0x1d, 0x0005); + phy_write (mii_info, 0x1e, 0x0000); + phy_write (mii_info, 0x1e, 0x0100); + phy_write (mii_info, 0x09, 0x0e00); + phy_write (mii_info, 0x04, 0x01e1); + phy_write (mii_info, 0x00, 0x9140); + phy_write (mii_info, 0x00, 0x1000); + udelay (100000); + phy_write (mii_info, 0x00, 0x2900); + phy_write (mii_info, 0x14, 0x0cd2); + phy_write (mii_info, 0x00, 0xa100); + phy_write (mii_info, 0x09, 0x0000); + phy_write (mii_info, 0x1b, 0x800b); + phy_write (mii_info, 0x04, 0x05e1); + phy_write (mii_info, 0x00, 0xa100); + phy_write (mii_info, 0x00, 0x2100); + udelay (1000000); + } else if (mode == ENET_10_RGMII) { + phy_write (mii_info, 0x14, 0x8e40); + phy_write (mii_info, 0x1b, 0x800b); + phy_write (mii_info, 0x14, 0x0c82); + phy_write (mii_info, 0x00, 0x8100); + udelay (1000000); + } +} + +void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode) +{ +#ifdef CONFIG_PHY_MODE_NEED_CHANGE + marvell_phy_interface_mode (dev, mode); +#endif +} +#endif /* CONFIG_QE */ diff --git a/drivers/qe/uec_phy.h b/drivers/qe/uec_phy.h new file mode 100644 index 0000000..9bd926d --- /dev/null +++ b/drivers/qe/uec_phy.h @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2005 Freescale Semiconductor, Inc. + * + * Author: Shlomi Gridish <gridish@freescale.com> + * + * Description: UCC ethernet driver -- PHY handling + * Driver for UEC on QE + * Based on 8260_io/fcc_enet.c + * + * 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. + * + */ +#ifndef __UEC_PHY_H__ +#define __UEC_PHY_H__ + +#define MII_end ((u32)-2) +#define MII_read ((u32)-1) + +#define MIIMIND_BUSY 0x00000001 +#define MIIMIND_NOTVALID 0x00000004 + +#define UGETH_AN_TIMEOUT 2000 + +/* 1000BT control (Marvell & BCM54xx at least) */ +#define MII_1000BASETCONTROL 0x09 +#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200 +#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100 + +/* Cicada Extended Control Register 1 */ +#define MII_CIS8201_EXT_CON1 0x17 +#define MII_CIS8201_EXTCON1_INIT 0x0000 + +/* Cicada Interrupt Mask Register */ +#define MII_CIS8201_IMASK 0x19 +#define MII_CIS8201_IMASK_IEN 0x8000 +#define MII_CIS8201_IMASK_SPEED 0x4000 +#define MII_CIS8201_IMASK_LINK 0x2000 +#define MII_CIS8201_IMASK_DUPLEX 0x1000 +#define MII_CIS8201_IMASK_MASK 0xf000 + +/* Cicada Interrupt Status Register */ +#define MII_CIS8201_ISTAT 0x1a +#define MII_CIS8201_ISTAT_STATUS 0x8000 +#define MII_CIS8201_ISTAT_SPEED 0x4000 +#define MII_CIS8201_ISTAT_LINK 0x2000 +#define MII_CIS8201_ISTAT_DUPLEX 0x1000 + +/* Cicada Auxiliary Control/Status Register */ +#define MII_CIS8201_AUX_CONSTAT 0x1c +#define MII_CIS8201_AUXCONSTAT_INIT 0x0004 +#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 +#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 +#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 +#define MII_CIS8201_AUXCONSTAT_100 0x0008 + +/* 88E1011 PHY Status Register */ +#define MII_M1011_PHY_SPEC_STATUS 0x11 +#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000 +#define MII_M1011_PHY_SPEC_STATUS_100 0x4000 +#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000 +#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000 +#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800 +#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400 + +#define MII_M1011_IEVENT 0x13 +#define MII_M1011_IEVENT_CLEAR 0x0000 + +#define MII_M1011_IMASK 0x12 +#define MII_M1011_IMASK_INIT 0x6400 +#define MII_M1011_IMASK_CLEAR 0x0000 + +#define MII_DM9161_SCR 0x10 +#define MII_DM9161_SCR_INIT 0x0610 +#define MII_DM9161_SCR_RMII_INIT 0x0710 + +/* DM9161 Specified Configuration and Status Register */ +#define MII_DM9161_SCSR 0x11 +#define MII_DM9161_SCSR_100F 0x8000 +#define MII_DM9161_SCSR_100H 0x4000 +#define MII_DM9161_SCSR_10F 0x2000 +#define MII_DM9161_SCSR_10H 0x1000 + +/* DM9161 Interrupt Register */ +#define MII_DM9161_INTR 0x15 +#define MII_DM9161_INTR_PEND 0x8000 +#define MII_DM9161_INTR_DPLX_MASK 0x0800 +#define MII_DM9161_INTR_SPD_MASK 0x0400 +#define MII_DM9161_INTR_LINK_MASK 0x0200 +#define MII_DM9161_INTR_MASK 0x0100 +#define MII_DM9161_INTR_DPLX_CHANGE 0x0010 +#define MII_DM9161_INTR_SPD_CHANGE 0x0008 +#define MII_DM9161_INTR_LINK_CHANGE 0x0004 +#define MII_DM9161_INTR_INIT 0x0000 +#define MII_DM9161_INTR_STOP \ +(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ + | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) + +/* DM9161 10BT Configuration/Status */ +#define MII_DM9161_10BTCSR 0x12 +#define MII_DM9161_10BTCSR_INIT 0x7800 + +#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ + SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | \ + SUPPORTED_100baseT_Full | \ + SUPPORTED_Autoneg | \ + SUPPORTED_TP | \ + SUPPORTED_MII) + +#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ + SUPPORTED_1000baseT_Half | \ + SUPPORTED_1000baseT_Full) + +#define MII_READ_COMMAND 0x00000001 + +#define MII_INTERRUPT_DISABLED 0x0 +#define MII_INTERRUPT_ENABLED 0x1 + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 + +/* Duplex, half or full. */ +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 + +/* Indicates what features are supported by the interface. */ +#define SUPPORTED_10baseT_Half (1 << 0) +#define SUPPORTED_10baseT_Full (1 << 1) +#define SUPPORTED_100baseT_Half (1 << 2) +#define SUPPORTED_100baseT_Full (1 << 3) +#define SUPPORTED_1000baseT_Half (1 << 4) +#define SUPPORTED_1000baseT_Full (1 << 5) +#define SUPPORTED_Autoneg (1 << 6) +#define SUPPORTED_TP (1 << 7) +#define SUPPORTED_AUI (1 << 8) +#define SUPPORTED_MII (1 << 9) +#define SUPPORTED_FIBRE (1 << 10) +#define SUPPORTED_BNC (1 << 11) +#define SUPPORTED_10000baseT_Full (1 << 12) + +#define ADVERTISED_10baseT_Half (1 << 0) +#define ADVERTISED_10baseT_Full (1 << 1) +#define ADVERTISED_100baseT_Half (1 << 2) +#define ADVERTISED_100baseT_Full (1 << 3) +#define ADVERTISED_1000baseT_Half (1 << 4) +#define ADVERTISED_1000baseT_Full (1 << 5) +#define ADVERTISED_Autoneg (1 << 6) +#define ADVERTISED_TP (1 << 7) +#define ADVERTISED_AUI (1 << 8) +#define ADVERTISED_MII (1 << 9) +#define ADVERTISED_FIBRE (1 << 10) +#define ADVERTISED_BNC (1 << 11) +#define ADVERTISED_10000baseT_Full (1 << 12) + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Taken from mii_if_info and sungem_phy.h */ +struct uec_mii_info { + /* Information about the PHY type */ + /* And management functions */ + struct phy_info *phyinfo; + + struct eth_device *dev; + + /* forced speed & duplex (no autoneg) + * partner speed & duplex & pause (autoneg) + */ + int speed; + int duplex; + int pause; + + /* The most recently read link state */ + int link; + + /* Enabled Interrupts */ + u32 interrupts; + + u32 advertising; + int autoneg; + int mii_id; + + /* private data pointer */ + /* For use by PHYs to maintain extra state */ + void *priv; + + /* Provided by ethernet driver */ + int (*mdio_read) (struct eth_device * dev, int mii_id, int reg); + void (*mdio_write) (struct eth_device * dev, int mii_id, int reg, + int val); +}; + +/* struct phy_info: a structure which defines attributes for a PHY + * + * id will contain a number which represents the PHY. During + * startup, the driver will poll the PHY to find out what its + * UID--as defined by registers 2 and 3--is. The 32-bit result + * gotten from the PHY will be ANDed with phy_id_mask to + * discard any bits which may change based on revision numbers + * unimportant to functionality + * + * There are 6 commands which take a ugeth_mii_info structure. + * Each PHY must declare config_aneg, and read_status. + */ +struct phy_info { + u32 phy_id; + char *name; + unsigned int phy_id_mask; + u32 features; + + /* Called to initialize the PHY */ + int (*init) (struct uec_mii_info * mii_info); + + /* Called to suspend the PHY for power */ + int (*suspend) (struct uec_mii_info * mii_info); + + /* Reconfigures autonegotiation (or disables it) */ + int (*config_aneg) (struct uec_mii_info * mii_info); + + /* Determines the negotiated speed and duplex */ + int (*read_status) (struct uec_mii_info * mii_info); + + /* Clears any pending interrupts */ + int (*ack_interrupt) (struct uec_mii_info * mii_info); + + /* Enables or disables interrupts */ + int (*config_intr) (struct uec_mii_info * mii_info); + + /* Clears up any memory if needed */ + void (*close) (struct uec_mii_info * mii_info); +}; + +struct phy_info *get_phy_info (struct uec_mii_info *mii_info); +void write_phy_reg (struct eth_device *dev, int mii_id, int regnum, + int value); +int read_phy_reg (struct eth_device *dev, int mii_id, int regnum); +void mii_clear_phy_interrupt (struct uec_mii_info *mii_info); +void mii_configure_phy_interrupt (struct uec_mii_info *mii_info, + u32 interrupts); +#endif /* __UEC_PHY_H__ */ diff --git a/drivers/tsec.c b/drivers/tsec.c index 400e593..2524e4f 100644 --- a/drivers/tsec.c +++ b/drivers/tsec.c @@ -610,11 +610,10 @@ static void adjust_link(struct eth_device *dev) regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) | MACCFG2_MII); - /* If We're in reduced mode, we need - * to say whether we're 10 or 100 MB. + /* Set R100 bit in all modes although + * it is only used in RGMII mode */ - if ((priv->speed == 100) - && (priv->flags & TSEC_REDUCED)) + if (priv->speed == 100) regs->ecntrl |= ECNTRL_R100; else regs->ecntrl &= ~(ECNTRL_R100); @@ -816,6 +815,7 @@ struct phy_info phy_info_M88E1111S = { {0x1d, 0x5, NULL}, {0x1e, 0x0, NULL}, {0x1e, 0x100, NULL}, + {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */ {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, @@ -1110,10 +1110,8 @@ struct phy_info phy_info_dp83865 = { }; struct phy_info *phy_info[] = { -#if 0 - &phy_info_cis8201, -#endif &phy_info_cis8204, + &phy_info_cis8201, &phy_info_M88E1011S, &phy_info_M88E1111S, &phy_info_M88E1145, diff --git a/drivers/tsec.h b/drivers/tsec.h index 4aa331c..cee3003 100644 --- a/drivers/tsec.h +++ b/drivers/tsec.h @@ -30,7 +30,7 @@ #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) #define TSEC_BASE_ADDR (CFG_IMMR + CFG_TSEC1_OFFSET) #elif defined(CONFIG_MPC83XX) - #define TSEC_BASE_ADDR (CFG_IMMRBAR + CFG_TSEC1_OFFSET) + #define TSEC_BASE_ADDR (CFG_IMMR + CFG_TSEC1_OFFSET) #endif diff --git a/include/74xx_7xx.h b/include/74xx_7xx.h index 7cd2f10..8eccac8 100644 --- a/include/74xx_7xx.h +++ b/include/74xx_7xx.h @@ -111,6 +111,7 @@ typedef enum __cpu_t { CPU_750CX, CPU_750FX, CPU_750GX, CPU_7400, CPU_7410, + CPU_7448, CPU_7450, CPU_7455, CPU_7457, CPU_7447A, CPU_7448, CPU_UNKNOWN} cpu_t; diff --git a/include/asm-ppc/e300.h b/include/asm-ppc/e300.h index 908007c..79dcae4 100644 --- a/include/asm-ppc/e300.h +++ b/include/asm-ppc/e300.h @@ -12,6 +12,8 @@ #define PVR_83xx 0x80830000 #define PVR_8349_REV10 (PVR_83xx | 0x0010) #define PVR_8349_REV11 (PVR_83xx | 0x0011) +#define PVR_8360_REV10 (PVR_83xx | 0x0020) +#define PVR_8360_REV11 (PVR_83xx | 0x0020) /* * Hardware Implementation-Dependent Register 0 (HID0) diff --git a/include/asm-ppc/fsl_i2c.h b/include/asm-ppc/fsl_i2c.h index 76b1c43..4f71341 100644 --- a/include/asm-ppc/fsl_i2c.h +++ b/include/asm-ppc/fsl_i2c.h @@ -83,8 +83,4 @@ typedef struct fsl_i2c { u8 res6[0xE8]; } fsl_i2c_t; - -#define I2C_READ 1 -#define I2C_WRITE 0 - #endif /* _ASM_I2C_H_ */ diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index 166afbe..5f0f0b4 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -55,17 +55,29 @@ typedef struct global_data { #if defined(CONFIG_MPC83XX) /* There are other clocks in the MPC83XX */ 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 /* CONFIG_MPC8349 */ + u32 core_clk; + u32 i2c1_clk; + u32 i2c2_clk; u32 enc_clk; u32 lbiu_clk; u32 lclk_clk; u32 ddr_clk; u32 pci_clk; +#if defined(CONFIG_QE) + u32 qe_clk; + u32 brg_clk; + uint mp_alloc_base; + uint mp_alloc_top; +#endif /* CONFIG_QE */ +#if defined (CONFIG_MPC8360) + u32 ddr_sec_clk; +#endif /* CONFIG_MPC8360 */ #endif #if defined(CONFIG_MPC5xxx) unsigned long ipb_clk; diff --git a/include/asm-ppc/i2c.h b/include/asm-ppc/i2c.h deleted file mode 100644 index 1680d3a..0000000 --- a/include/asm-ppc/i2c.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Freescale I2C Controller - * - * This software may be used and distributed according to the - * terms of the GNU Public License, Version 2, incorporated - * herein by reference. - * - * Copyright 2004 Freescale Semiconductor. - * (C) Copyright 2003, Motorola, Inc. - * author: Eran Liberty (liberty@freescale.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _ASM_I2C_H_ -#define _ASM_I2C_H_ - -#include <asm/types.h> - -typedef struct i2c -{ - u8 adr; /**< I2C slave address */ -#define I2C_ADR 0xFE -#define I2C_ADR_SHIFT 1 -#define I2C_ADR_RES ~(I2C_ADR) - u8 res0[3]; - u8 fdr; /**< I2C frequency divider register */ -#define IC2_FDR 0x3F -#define IC2_FDR_SHIFT 0 -#define IC2_FDR_RES ~(IC2_FDR) - u8 res1[3]; - u8 cr; /**< I2C control redister */ -#define I2C_CR_MEN 0x80 -#define I2C_CR_MIEN 0x40 -#define I2C_CR_MSTA 0x20 -#define I2C_CR_MTX 0x10 -#define I2C_CR_TXAK 0x08 -#define I2C_CR_RSTA 0x04 -#define I2C_CR_BCST 0x01 - u8 res2[3]; - u8 sr; /**< I2C status register */ -#define I2C_SR_MCF 0x80 -#define I2C_SR_MAAS 0x40 -#define I2C_SR_MBB 0x20 -#define I2C_SR_MAL 0x10 -#define I2C_SR_BCSTM 0x08 -#define I2C_SR_SRW 0x04 -#define I2C_SR_MIF 0x02 -#define I2C_SR_RXAK 0x01 - u8 res3[3]; - u8 dr; /**< I2C data register */ -#define I2C_DR 0xFF -#define I2C_DR_SHIFT 0 -#define I2C_DR_RES ~(I2C_DR) - u8 res4[3]; - u8 dfsrr; /**< I2C digital filter sampling rate register */ -#define I2C_DFSRR 0x3F -#define I2C_DFSRR_SHIFT 0 -#define I2C_DFSRR_RES ~(I2C_DR) - u8 res5[3]; - u8 res6[0xE8]; -} i2c_t; - -#ifndef CFG_HZ -#error CFG_HZ is not defined in /include/configs/${BOARD}.h -#endif -#define I2C_TIMEOUT (CFG_HZ/4) - -#ifndef CFG_IMMRBAR -#error CFG_IMMRBAR is not defined in /include/configs/${BOARD}.h -#endif - -#ifndef CFG_I2C_OFFSET -#error CFG_I2C_OFFSET is not defined in /include/configs/${BOARD}.h -#endif - -#if defined(CONFIG_MPC8349EMDS) || defined(CONFIG_TQM834X) -/* - * MPC8349 have two i2c bus - */ -extern i2c_t * mpc8349_i2c; -#define I2C mpc8349_i2c -#else -#define I2C ((i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET)) -#endif - -#define I2C_READ 1 -#define I2C_WRITE 0 - -#endif /* _ASM_I2C_H_ */ diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h index c2b4c5c..43cde5e 100644 --- a/include/asm-ppc/immap_83xx.h +++ b/include/asm-ppc/immap_83xx.h @@ -1,75 +1,116 @@ /* - * MPC8349 Internal Memory Map - * Copyright (c) 2004 Freescale Semiconductor. - * Eran Liberty (liberty@freescale.com) + * (C) Copyright 2004-2006 Freescale Semiconductor, Inc. + * + * MPC83xx Internal Memory Map + * + * History : + * 20060601: Daveliu (daveliu@freescale.com) + * TanyaJiang (tanya.jiang@freescale.com) + * Unified variable names for mpc83xx + * 2005 : Mandy Lavi (mandy.lavi@freescale.com) + * support for mpc8360e + * 2004 : Eran Liberty (liberty@freescale.com) + * Initialized for mpc8349 + * based on: + * MPC8260 Internal Memory Map + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) + * MPC85xx Internal Memory Map + * Copyright(c) 2002,2003 Motorola Inc. + * Xianghua Xiao (x.xiao@motorola.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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 * - * based on: - * - MPC8260 Internal Memory Map - * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) - * - MPC85xx Internal Memory Map - * Copyright(c) 2002,2003 Motorola Inc. - * Xianghua Xiao (x.xiao@motorola.com) */ -#ifndef __IMMAP_8349__ -#define __IMMAP_8349__ +#ifndef __IMMAP_83xx__ +#define __IMMAP_83xx__ +#include <config.h> #include <asm/types.h> -#include <asm/i2c.h> +#include <asm/fsl_i2c.h> /* * Local Access Window. */ -typedef struct law8349 { - u32 bar; /* LBIU local access window base address register */ +typedef struct law83xx { + u32 bar; /* LBIU local access window base address register */ /* Identifies the 20 most-significant address bits of the base of local * access window n. The specified base address should be aligned to the * window size, as defined by LBLAWARn[SIZE]. */ -#define LAWBAR_BAR 0xFFFFF000 +#define LAWBAR_BAR 0xFFFFF000 #define LAWBAR_RES ~(LAWBAR_BAR) - u32 ar; /* LBIU local access window attribute register */ -} law8349_t; + u32 ar; /* LBIU local access window attribute register */ +} law83xx_t; /* * System configuration registers. */ -typedef struct sysconf8349 { - u32 immrbar; /* Internal memory map base address register */ +typedef struct sysconf83xx { + u32 immrbar; /* Internal memory map base address register */ u8 res0[0x04]; - u32 altcbar; /* Alternate configuration base address register */ + u32 altcbar; /* Alternate configuration base address register */ /* Identifies the12 most significant address bits of an alternate base * address used for boot sequencer configuration accesses. */ #define ALTCBAR_BASE_ADDR 0xFFF00000 -#define ALTCBAR_RES ~(ALTCBAR_BASE_ADDR) /* Reserved. Write has no effect, read returns 0. */ +#define ALTCBAR_RES ~(ALTCBAR_BASE_ADDR) /* Reserved. Write has no effect, read returns 0. */ u8 res1[0x14]; - law8349_t lblaw[4]; /* LBIU local access window */ + law83xx_t lblaw[4]; /* LBIU local access window */ u8 res2[0x20]; - law8349_t pcilaw[2]; /* PCI local access window */ + law83xx_t pcilaw[2]; /* PCI local access window */ u8 res3[0x30]; - law8349_t ddrlaw[2]; /* DDR local access window */ + law83xx_t ddrlaw[2]; /* DDR local access window */ u8 res4[0x50]; - u32 sgprl; /* System General Purpose Register Low */ - u32 sgprh; /* System General Purpose Register High */ - u32 spridr; /* System Part and Revision ID Register */ -#define SPRIDR_PARTID 0xFFFF0000 /* Part Identification. */ -#define SPRIDR_REVID 0x0000FFFF /* Revision Identification. */ + u32 sgprl; /* System General Purpose Register Low */ + u32 sgprh; /* System General Purpose Register High */ + u32 spridr; /* System Part and Revision ID Register */ +#define SPRIDR_PARTID 0xFFFF0000 /* Part Identification. */ +#define SPRIDR_REVID 0x0000FFFF /* Revision Identification. */ u8 res5[0x04]; - u32 spcr; /* System Priority Configuration Register */ -#define SPCR_PCIHPE 0x10000000 /* PCI Highest Priority Enable. */ -#define SPCR_PCIPR 0x03000000 /* PCI bridge system bus request priority. */ -#define SPCR_TBEN 0x00400000 /* E300 PowerPC core time base unit enable. */ -#define SPCR_COREPR 0x00300000 /* E300 PowerPC Core system bus request priority. */ -#define SPCR_TSEC1DP 0x00003000 /* TSEC1 data priority. */ -#define SPCR_TSEC1BDP 0x00000C00 /* TSEC1 buffer descriptor priority. */ -#define SPCR_TSEC1EP 0x00000300 /* TSEC1 emergency priority. */ -#define SPCR_TSEC2DP 0x00000030 /* TSEC2 data priority. */ -#define SPCR_TSEC2BDP 0x0000000C /* TSEC2 buffer descriptor priority. */ -#define SPCR_TSEC2EP 0x00000003 /* TSEC2 emergency priority. */ + u32 spcr; /* System Priority Configuration Register */ +#define SPCR_PCIHPE 0x10000000 /* PCI Highest Priority Enable. */ +#define SPCR_PCIHPE_SHIFT (31-3) +#define SPCR_PCIPR 0x03000000 /* PCI bridge system bus request priority. */ +#define SPCR_PCIPR_SHIFT (31-7) +#define SPCR_OPT 0x00800000 /* Optimize */ +#define SPCR_TBEN 0x00400000 /* E300 PowerPC core time base unit enable. */ +#define SPCR_TBEN_SHIFT (31-9) +#define SPCR_COREPR 0x00300000 /* E300 PowerPC Core system bus request priority. */ +#define SPCR_COREPR_SHIFT (31-11) +#if defined (CONFIG_MPC8349) +#define SPCR_TSEC1DP 0x00003000 /* TSEC1 data priority. */ +#define SPCR_TSEC1DP_SHIFT (31-19) +#define SPCR_TSEC1BDP 0x00000C00 /* TSEC1 buffer descriptor priority. */ +#define SPCR_TSEC1BDP_SHIFT (31-21) +#define SPCR_TSEC1EP 0x00000300 /* TSEC1 emergency priority. */ +#define SPCR_TSEC1EP_SHIFT (31-23) +#define SPCR_TSEC2DP 0x00000030 /* TSEC2 data priority. */ +#define SPCR_TSEC2DP_SHIFT (31-27) +#define SPCR_TSEC2BDP 0x0000000C /* TSEC2 buffer descriptor priority. */ +#define SPCR_TSEC2BDP_SHIFT (31-29) +#define SPCR_TSEC2EP 0x00000003 /* TSEC2 emergency priority. */ +#define SPCR_TSEC2EP_SHIFT (31-31) #define SPCR_RES ~(SPCR_PCIHPE | SPCR_PCIPR | SPCR_TBEN | SPCR_COREPR \ | SPCR_TSEC1DP | SPCR_TSEC1BDP | SPCR_TSEC1EP \ | SPCR_TSEC2DP | SPCR_TSEC2BDP | SPCR_TSEC2EP) - u32 sicrl; /* System General Purpose Register Low */ +#elif defined (CONFIG_MPC8360) +#define SPCR_RES ~(SPCR_PCIHPE|SPCR_PCIPR|SPCR_OPT|SPCR_TBEN|SPCR_COREPR) +#endif + u32 sicrl; /* System General Purpose Register Low */ +#if defined (CONFIG_MPC8349) #define SICRL_LDP_A 0x80000000 #define SICRL_USB1 0x40000000 #define SICRL_USB0 0x20000000 @@ -91,8 +132,18 @@ typedef struct sysconf8349 { | SICRL_GPIO1_D | SICRL_GPIO1_E | SICRL_GPIO1_F \ | SICRL_GPIO1_G | SICRL_GPIO1_H | SICRL_GPIO1_I \ | SICRL_GPIO1_J | SICRL_GPIO1_K | SICRL_GPIO1_L ) - u32 sicrh; /* System General Purpose Register High */ +#elif defined (CONFIG_MPC8360) +#define SICRL_LDP_A 0xC0000000 +#define SICRL_LCLK_1 0x10000000 +#define SICRL_LCLK_2 0x08000000 +#define SICRL_SRCID_A 0x03000000 +#define SICRL_IRQ_CKSTP_A 0x00C00000 +#define SICRL_RES ~(SICRL_LDP_A | SICRL_LCLK_1 | SICRL_LCLK_2 | \ + SICRL_SRCID_A | SICRL_IRQ_CKSTP_A) +#endif + u32 sicrh; /* System General Purpose Register High */ #define SICRH_DDR 0x80000000 +#if defined (CONFIG_MPC8349) #define SICRH_TSEC1_A 0x10000000 #define SICRH_TSEC1_B 0x08000000 #define SICRH_TSEC1_C 0x04000000 @@ -117,7 +168,7 @@ typedef struct sysconf8349 { #define SICRH_GPIO2_H 0x00000060 #define SICRH_TSOBI1 0x00000002 #define SICRH_TSOBI2 0x00000001 -#define SICRh_RES ~( SICRH_DDR | SICRH_TSEC1_A | SICRH_TSEC1_B \ +#define SICRH_RES ~( SICRH_DDR | SICRH_TSEC1_A | SICRH_TSEC1_B \ | SICRH_TSEC1_C | SICRH_TSEC1_D | SICRH_TSEC1_E \ | SICRH_TSEC1_F | SICRH_TSEC2_A | SICRH_TSEC2_B \ | SICRH_TSEC2_C | SICRH_TSEC2_D | SICRH_TSEC2_E \ @@ -126,207 +177,256 @@ typedef struct sysconf8349 { | SICRH_GPIO2_D | SICRH_GPIO2_E | SICRH_GPIO2_F \ | SICRH_GPIO2_G | SICRH_GPIO2_H | SICRH_TSOBI1 \ | SICRH_TSOBI2) +#elif defined (CONFIG_MPC8360) +#define SICRH_SECONDARY_DDR 0x40000000 +#define SICRH_SDDROE 0x02000000 /* SDDRIOE bit from reset configuration word high. */ +#define SICRH_UC1EOBI 0x00000004 /* UCC1 Ethernet Output Buffer Impedance. */ +#define SICRH_UC2E1OBI 0x00000002 /* UCC2 Ethernet pin option 1 Output Buffer Impedance. */ +#define SICRH_UC2E2OBI 0x00000001 /* UCC2 Ethernet pin option 2 Output Buffer Impedance. */ +#define SICRH_RES ~(SICRH_DDR | SICRH_SECONDARY_DDR | SICRH_SDDROE | \ + SICRH_UC2E1OBI | SICRH_UC2E2OBI | SICRH_UC2E2OBI) +#endif u8 res6[0xE4]; -} sysconf8349_t; +} sysconf83xx_t; /* * Watch Dog Timer (WDT) Registers */ -typedef struct wdt8349 { +typedef struct wdt83xx { u8 res0[4]; - u32 swcrr; /* System watchdog control register */ - u32 swcnr; /* System watchdog count register */ + u32 swcrr; /* System watchdog control register */ + u32 swcnr; /* System watchdog count register */ #define SWCNR_SWCN 0x0000FFFF Software Watchdog Count Field. #define SWCNR_RES ~(SWCNR_SWCN) u8 res1[2]; - u16 swsrr; /* System watchdog service register */ + u16 swsrr; /* System watchdog service register */ +#define SWSRR_WS 0x0000FFFF /* Software Watchdog Service Field. */ u8 res2[0xF0]; -} wdt8349_t; +} wdt83xx_t; /* * RTC/PIT Module Registers */ -typedef struct rtclk8349 { - u32 cnr; /* control register */ -#define CNR_CLEN 0x00000080 /* Clock Enable Control Bit */ -#define CNR_CLIN 0x00000040 /* Input Clock Control Bit */ -#define CNR_AIM 0x00000002 /* Alarm Interrupt Mask Bit */ -#define CNR_SIM 0x00000001 /* Second Interrupt Mask Bit */ -#define CNR_RES ~(CNR_CLEN | CNR_CLIN | CNR_AIM | CNR_SIM) - u32 ldr; /* load register */ - u32 psr; /* prescale register */ - u32 ctr; /* register */ - u32 evr; /* event register */ -#define RTEVR_SIF 0x00000001 /* Second Interrupt Flag Bit */ -#define RTEVR_AIF 0x00000002 /* Alarm Interrupt Flag Bit */ -#define RTEVR_RES ~(EVR_SIF | EVR_AIF) - u32 alr; /* alarm register */ +typedef struct rtclk83xx { + u32 cnr; /* control register */ +#define CNR_CLEN 0x00000080 /* Clock Enable Control Bit */ +#define CNR_CLIN 0x00000040 /* Input Clock Control Bit */ +#define CNR_AIM 0x00000002 /* Alarm Interrupt Mask Bit */ +#define CNR_SIM 0x00000001 /* Second Interrupt Mask Bit */ +#define CNR_RES ~(CNR_CLEN | CNR_CLIN | CNR_AIM | CNR_SIM) + u32 ldr; /* load register */ +#define LDR_CLDV 0xFFFFFFFF /* Contains the 32-bit value to be + * loaded in a 32-bit RTC counter.*/ + u32 psr; /* prescale register */ +#define PSR_PRSC 0xFFFFFFFF /* RTC Prescaler bits. */ + u32 ctr; /* Counter value field register */ +#define CRT_CNTV 0xFFFFFFFF /* RTC Counter value field. */ + u32 evr; /* event register */ +#define RTEVR_SIF 0x00000001 /* Second Interrupt Flag Bit */ +#define RTEVR_AIF 0x00000002 /* Alarm Interrupt Flag Bit */ +#define RTEVR_RES ~(RTEVR_SIF | RTEVR_AIF) +#define PTEVR_PIF 0x00000001 /* Periodic interrupt flag bit. */ +#define PTEVR_RES ~(PTEVR_PIF) + u32 alr; /* alarm register */ u8 res0[0xE8]; -} rtclk8349_t; +} rtclk83xx_t; /* * Global timper module */ -typedef struct gtm8349 { - u8 cfr1; /* Timer1/2 Configuration */ -#define CFR1_PCAS 0x80 /* Pair Cascade mode */ -#define CFR1_BCM 0x40 /* Backward compatible mode */ -#define CFR1_STP2 0x20 /* Stop timer */ -#define CFR1_RST2 0x10 /* Reset timer */ -#define CFR1_GM2 0x08 /* Gate mode for pin 2 */ -#define CFR1_GM1 0x04 /* Gate mode for pin 1 */ -#define CFR1_STP1 0x02 /* Stop timer */ -#define CFR1_RST1 0x01 /* Reset timer */ - u8 res0[3]; - u8 cfr2; /* Timer3/4 Configuration */ -#define CFR2_PCAS 0x80 /* Pair Cascade mode */ -#define CFR2_SCAS 0x40 /* Super Cascade mode */ -#define CFR2_STP4 0x20 /* Stop timer */ -#define CFR2_RST4 0x10 /* Reset timer */ -#define CFR2_GM4 0x08 /* Gate mode for pin 4 */ -#define CFR2_GM3 0x04 /* Gate mode for pin 3 */ -#define CFR2_STP3 0x02 /* Stop timer */ -#define CFR2_RST3 0x01 /* Reset timer */ - u8 res1[10]; - u16 mdr1; /* Timer1 Mode Register */ -#define MDR_SPS 0xff00 /* Secondary Prescaler value */ -#define MDR_CE 0x00c0 /* Capture edge and enable interrupt */ -#define MDR_OM 0x0020 /* Output mode */ -#define MDR_ORI 0x0010 /* Output reference interrupt enable */ -#define MDR_FRR 0x0008 /* Free run/restart */ -#define MDR_ICLK 0x0006 /* Input clock source for the timer */ -#define MDR_GE 0x0001 /* Gate enable */ - u16 mdr2; /* Timer2 Mode Register */ - u16 rfr1; /* Timer1 Reference Register */ - u16 rfr2; /* Timer2 Reference Register */ - u16 cpr1; /* Timer1 Capture Register */ - u16 cpr2; /* Timer2 Capture Register */ - u16 cnr1; /* Timer1 Counter Register */ - u16 cnr2; /* Timer2 Counter Register */ - u16 mdr3; /* Timer3 Mode Register */ - u16 mdr4; /* Timer4 Mode Register */ - u16 rfr3; /* Timer3 Reference Register */ - u16 rfr4; /* Timer4 Reference Register */ - u16 cpr3; /* Timer3 Capture Register */ - u16 cpr4; /* Timer4 Capture Register */ - u16 cnr3; /* Timer3 Counter Register */ - u16 cnr4; /* Timer4 Counter Register */ - u16 evr1; /* Timer1 Event Register */ - u16 evr2; /* Timer2 Event Register */ - u16 evr3; /* Timer3 Event Register */ - u16 evr4; /* Timer4 Event Register */ -#define GTEVR_REF 0x0002 /* Output reference event */ -#define GTEVR_CAP 0x0001 /* Counter Capture event */ +typedef struct gtm83xx { + u8 cfr1; /* Timer1/2 Configuration */ +#define CFR1_PCAS 0x80 /* Pair Cascade mode */ +#define CFR1_BCM 0x40 /* Backward compatible mode */ +#define CFR1_STP2 0x20 /* Stop timer */ +#define CFR1_RST2 0x10 /* Reset timer */ +#define CFR1_GM2 0x08 /* Gate mode for pin 2 */ +#define CFR1_GM1 0x04 /* Gate mode for pin 1 */ +#define CFR1_STP1 0x02 /* Stop timer */ +#define CFR1_RST1 0x01 /* Reset timer */ +#define CFR1_RES ~(CFR1_PCAS | CFR1_STP2 | CFR1_RST2 | CFR1_GM2 |\ + CFR1_GM1 | CFR1_STP1 | CFR1_RST1) + u8 res0[3]; + u8 cfr2; /* Timer3/4 Configuration */ +#define CFR2_PCAS 0x80 /* Pair Cascade mode */ +#define CFR2_SCAS 0x40 /* Super Cascade mode */ +#define CFR2_STP4 0x20 /* Stop timer */ +#define CFR2_RST4 0x10 /* Reset timer */ +#define CFR2_GM4 0x08 /* Gate mode for pin 4 */ +#define CFR2_GM3 0x04 /* Gate mode for pin 3 */ +#define CFR2_STP3 0x02 /* Stop timer */ +#define CFR2_RST3 0x01 /* Reset timer */ + u8 res1[10]; + u16 mdr1; /* Timer1 Mode Register */ +#define MDR_SPS 0xff00 /* Secondary Prescaler value */ +#define MDR_CE 0x00c0 /* Capture edge and enable interrupt */ +#define MDR_OM 0x0020 /* Output mode */ +#define MDR_ORI 0x0010 /* Output reference interrupt enable */ +#define MDR_FRR 0x0008 /* Free run/restart */ +#define MDR_ICLK 0x0006 /* Input clock source for the timer */ +#define MDR_GE 0x0001 /* Gate enable */ + u16 mdr2; /* Timer2 Mode Register */ + u16 rfr1; /* Timer1 Reference Register */ + u16 rfr2; /* Timer2 Reference Register */ + u16 cpr1; /* Timer1 Capture Register */ + u16 cpr2; /* Timer2 Capture Register */ + u16 cnr1; /* Timer1 Counter Register */ + u16 cnr2; /* Timer2 Counter Register */ + u16 mdr3; /* Timer3 Mode Register */ + u16 mdr4; /* Timer4 Mode Register */ + u16 rfr3; /* Timer3 Reference Register */ + u16 rfr4; /* Timer4 Reference Register */ + u16 cpr3; /* Timer3 Capture Register */ + u16 cpr4; /* Timer4 Capture Register */ + u16 cnr3; /* Timer3 Counter Register */ + u16 cnr4; /* Timer4 Counter Register */ + u16 evr1; /* Timer1 Event Register */ + u16 evr2; /* Timer2 Event Register */ + u16 evr3; /* Timer3 Event Register */ + u16 evr4; /* Timer4 Event Register */ +#define GTEVR_REF 0x0002 /* Output reference event */ +#define GTEVR_CAP 0x0001 /* Counter Capture event */ #define GTEVR_RES ~(EVR_CAP|EVR_REF) - u16 psr1; /* Timer1 Prescaler Register */ - u16 psr2; /* Timer2 Prescaler Register */ - u16 psr3; /* Timer3 Prescaler Register */ - u16 psr4; /* Timer4 Prescaler Register */ - u8 res[0xC0]; -} gtm8349_t; + u16 psr1; /* Timer1 Prescaler Register */ + u16 psr2; /* Timer2 Prescaler Register */ + u16 psr3; /* Timer3 Prescaler Register */ + u16 psr4; /* Timer4 Prescaler Register */ +#define GTPSR_PPS 0x00FF /* Primary Prescaler Bits. */ +#define GTPSR_RES ~(GTPSR_PPS) + u8 res[0xC0]; +} gtm83xx_t; /* * Integrated Programmable Interrupt Controller */ -typedef struct ipic8349 { - u32 sicfr; /* System Global Interrupt Configuration Register (SICFR) */ -#define SICFR_HPI 0x7f000000 /* Highest Priority Interrupt */ -#define SICFR_MPSB 0x00400000 /* Mixed interrupts Priority Scheme for group B */ -#define SICFR_MPSA 0x00200000 /* Mixed interrupts Priority Scheme for group A */ -#define SICFR_IPSD 0x00080000 /* Internal interrupts Priority Scheme for group D */ -#define SICFR_IPSA 0x00010000 /* Internal interrupts Priority Scheme for group A */ -#define SICFR_HPIT 0x00000300 /* HPI priority position IPIC output interrupt Type */ +typedef struct ipic83xx { + u32 sicfr; /* System Global Interrupt Configuration Register (SICFR) */ +#define SICFR_HPI 0x7f000000 /* Highest Priority Interrupt */ +#define SICFR_MPSB 0x00400000 /* Mixed interrupts Priority Scheme for group B */ +#define SICFR_MPSA 0x00200000 /* Mixed interrupts Priority Scheme for group A */ +#define SICFR_IPSD 0x00080000 /* Internal interrupts Priority Scheme for group D */ +#define SICFR_IPSA 0x00010000 /* Internal interrupts Priority Scheme for group A */ +#define SICFR_HPIT 0x00000300 /* HPI priority position IPIC output interrupt Type */ #define SICFR_RES ~(SICFR_HPI|SICFR_MPSB|SICFR_MPSA|SICFR_IPSD|SICFR_IPSA|SICFR_HPIT) - u32 sivcr; /* System Global Interrupt Vector Register (SIVCR) */ -#define SICVR_IVECX 0xfc000000 /* Interrupt vector (for CE compatibility purpose only not used in 8349 IPIC implementation) */ -#define SICVR_IVEC 0x0000007f /* Interrupt vector */ + u32 sivcr; /* System Global Interrupt Vector Register (SIVCR) */ +#define SICVR_IVECX 0xfc000000 /* Interrupt vector (for CE compatibility purpose only not used in 8349 IPIC implementation) */ +#define SICVR_IVEC 0x0000007f /* Interrupt vector */ #define SICVR_RES ~(SICVR_IVECX|SICVR_IVEC) - u32 sipnr_h; /* System Internal Interrupt Pending Register - High (SIPNR_H) */ -#define SIIH_TSEC1TX 0x80000000 /* TSEC1 Tx interrupt */ -#define SIIH_TSEC1RX 0x40000000 /* TSEC1 Rx interrupt */ + u32 sipnr_h; /* System Internal Interrupt Pending Register - High (SIPNR_H) */ +#if defined (CONFIG_MPC8349) +#define SIIH_TSEC1TX 0x80000000 /* TSEC1 Tx interrupt */ +#define SIIH_TSEC1RX 0x40000000 /* TSEC1 Rx interrupt */ #define SIIH_TSEC1ER 0x20000000 /* TSEC1 Eror interrupt */ -#define SIIH_TSEC2TX 0x10000000 /* TSEC2 Tx interrupt */ -#define SIIH_TSEC2RX 0x08000000 /* TSEC2 Rx interrupt */ +#define SIIH_TSEC2TX 0x10000000 /* TSEC2 Tx interrupt */ +#define SIIH_TSEC2RX 0x08000000 /* TSEC2 Rx interrupt */ #define SIIH_TSEC2ER 0x04000000 /* TSEC2 Eror interrupt */ #define SIIH_USB2DR 0x02000000 /* USB2 DR interrupt */ -#define SIIH_USB2MPH 0x01000000 /* USB2 MPH interrupt */ +#define SIIH_USB2MPH 0x01000000 /* USB2 MPH interrupt */ +#endif +#if defined (CONFIG_MPC8360) +#define SIIH_H_QE_H 0x80000000 /* QE high interrupt */ +#define SIIH_H_QE_L 0x40000000 /* QE low interrupt */ +#endif #define SIIH_UART1 0x00000080 /* UART1 interrupt */ #define SIIH_UART2 0x00000040 /* UART2 interrupt */ #define SIIH_SEC 0x00000020 /* SEC interrupt */ #define SIIH_I2C1 0x00000004 /* I2C1 interrupt */ -#define SIIH_I2C2 0x00000002 /* I2C1 interrupt */ +#define SIIH_I2C2 0x00000002 /* I2C2 interrupt */ +#if defined (CONFIG_MPC8349) #define SIIH_SPI 0x00000001 /* SPI interrupt */ #define SIIH_RES ~(SIIH_TSEC1TX | SIIH_TSEC1RX | SIIH_TSEC1ER \ | SIIH_TSEC2TX | SIIH_TSEC2RX | SIIH_TSEC2ER \ | SIIH_USB2DR | SIIH_USB2MPH | SIIH_UART1 \ | SIIH_UART2 | SIIH_SEC | SIIH_I2C1 \ | SIIH_I2C2 | SIIH_SPI) - u32 sipnr_l; /* System Internal Interrupt Pending Register - Low (SIPNR_L) */ -#define SIIL_RTCS 0x80000000 /* RTC SECOND interrupt */ -#define SIIL_PIT 0x40000000 /* PIT interrupt */ -#define SIIL_PCI1 0x20000000 /* PCI1 interrupt */ -#define SIIL_PCI2 0x10000000 /* PCI2 interrupt */ -#define SIIL_RTCA 0x08000000 /* RTC ALARM interrupt */ -#define SIIL_MU 0x04000000 /* Message Unit interrupt */ -#define SIIL_SBA 0x02000000 /* System Bus Arbiter interrupt */ -#define SIIL_DMA 0x01000000 /* DMA interrupt */ -#define SIIL_GTM4 0x00800000 /* GTM4 interrupt */ -#define SIIL_GTM8 0x00400000 /* GTM8 interrupt */ -#define SIIL_GPIO1 0x00200000 /* GPIO1 interrupt */ -#define SIIL_GPIO2 0x00100000 /* GPIO2 interrupt */ -#define SIIL_DDR 0x00080000 /* DDR interrupt */ -#define SIIL_LBC 0x00040000 /* LBC interrupt */ -#define SIIL_GTM2 0x00020000 /* GTM2 interrupt */ -#define SIIL_GTM6 0x00010000 /* GTM6 interrupt */ -#define SIIL_PMC 0x00008000 /* PMC interrupt */ -#define SIIL_GTM3 0x00000800 /* GTM3 interrupt */ -#define SIIL_GTM7 0x00000400 /* GTM7 interrupt */ -#define SIIL_GTM1 0x00000020 /* GTM1 interrupt */ -#define SIIL_GTM5 0x00000010 /* GTM5 interrupt */ -#define SIIL_DPTC 0x00000001 /* DPTC interrupt (!!! Invisible for user !!!) */ +#endif +#if defined (CONFIG_MPC8360) +#define SIIH_RES ~(SIIH_H_QE_H | SIIH_H_QE_L | SIIH_H_UART1 | \ + SIIH_H_UART2| SIIH_H_SEC | SIIH_H_I2C1 |SIIH_H_I2C2) +#endif + u32 sipnr_l; /* System Internal Interrupt Pending Register - Low (SIPNR_L) */ +#define SIIL_RTCS 0x80000000 /* RTC SECOND interrupt */ +#define SIIL_PIT 0x40000000 /* PIT interrupt */ +#define SIIL_PCI1 0x20000000 /* PCI1 interrupt */ +#if defined (CONFIG_MPC8349) +#define SIIL_PCI2 0x10000000 /* PCI2 interrupt */ +#endif +#define SIIL_RTCA 0x08000000 /* RTC ALARM interrupt */ +#define SIIL_MU 0x04000000 /* Message Unit interrupt */ +#define SIIL_SBA 0x02000000 /* System Bus Arbiter interrupt */ +#define SIIL_DMA 0x01000000 /* DMA interrupt */ +#define SIIL_GTM4 0x00800000 /* GTM4 interrupt */ +#define SIIL_GTM8 0x00400000 /* GTM8 interrupt */ +#if defined (CONFIG_MPC8349) +#define SIIL_GPIO1 0x00200000 /* GPIO1 interrupt */ +#define SIIL_GPIO2 0x00100000 /* GPIO2 interrupt */ +#endif +#if defined (CONFIG_MPC8360) +#define SIIL_QEP 0x00200000 /* QE ports interrupt */ +#define SIIL_SDDR 0x00100000 /* SDDR interrupt */ +#endif +#define SIIL_DDR 0x00080000 /* DDR interrupt */ +#define SIIL_LBC 0x00040000 /* LBC interrupt */ +#define SIIL_GTM2 0x00020000 /* GTM2 interrupt */ +#define SIIL_GTM6 0x00010000 /* GTM6 interrupt */ +#define SIIL_PMC 0x00008000 /* PMC interrupt */ +#define SIIL_GTM3 0x00000800 /* GTM3 interrupt */ +#define SIIL_GTM7 0x00000400 /* GTM7 interrupt */ +#define SIIL_GTM1 0x00000020 /* GTM1 interrupt */ +#define SIIL_GTM5 0x00000010 /* GTM5 interrupt */ +#define SIIL_DPTC 0x00000001 /* DPTC interrupt (!!! Invisible for user !!!) */ +#if defined (CONFIG_MPC8349) #define SIIL_RES ~(SIIL_RTCS | SIIL_PIT | SIIL_PCI1 | SIIL_PCI2 \ | SIIL_RTCA | SIIL_MU | SIIL_SBA | SIIL_DMA \ | SIIL_GTM4 | SIIL_GTM8 | SIIL_GPIO1 | SIIL_GPIO2 \ | SIIL_DDR | SIIL_LBC | SIIL_GTM2 | SIIL_GTM6 \ | SIIL_PMC |SIIL_GTM3 | SIIL_GTM7 | SIIL_GTM1 \ | SIIL_GTM5 |SIIL_DPTC ) - u32 siprr_a; /* System Internal Interrupt Group A Priority Register (PRR) */ - u8 res0[8]; - u32 siprr_d; /* System Internal Interrupt Group D Priority Register (PRR) */ - u32 simsr_h; /* System Internal Interrupt Mask Register - High (SIIH) */ - u32 simsr_l; /* System Internal Interrupt Mask Register - Low (SIIL) */ - u8 res1[4]; - u32 sepnr; /* System External Interrupt Pending Register (SEI) */ - u32 smprr_a; /* System Mixed Interrupt Group A Priority Register (PRR) */ - u32 smprr_b; /* System Mixed Interrupt Group B Priority Register (PRR) */ -#define PRR_0 0xe0000000 /* Priority Register, Position 0 programming */ -#define PRR_1 0x1c000000 /* Priority Register, Position 1 programming */ -#define PRR_2 0x03800000 /* Priority Register, Position 2 programming */ -#define PRR_3 0x00700000 /* Priority Register, Position 3 programming */ -#define PRR_4 0x0000e000 /* Priority Register, Position 4 programming */ -#define PRR_5 0x00001c00 /* Priority Register, Position 5 programming */ -#define PRR_6 0x00000380 /* Priority Register, Position 6 programming */ -#define PRR_7 0x00000070 /* Priority Register, Position 7 programming */ +#endif +#if defined (CONFIG_MPC8360) +#define SIIL_RES ~(SIIL_RTCS |SIIL_PIT |SIIL_PCI1 |SIIL_RTCALR \ + |SIIL_MU |SIIL_SBA |SIIL_DMA |SIIL_GTM4 |SIIL_GTM8 \ + |SIIL_QEP | SIIL_SDDR| SIIL_DDR |SIIL_LBC |SIIL_GTM2 \ + |SIIL_GTM6 |SIIL_PMC |SIIL_GTM3 |SIIL_GTM7 |SIIL_GTM1 \ + |SIIL_GTM5 ) +#endif + u32 siprr_a; /* System Internal Interrupt Group A Priority Register (PRR) */ + u8 res0[8]; + u32 siprr_d; /* System Internal Interrupt Group D Priority Register (PRR) */ + u32 simsr_h; /* System Internal Interrupt Mask Register - High (SIIH) */ + u32 simsr_l; /* System Internal Interrupt Mask Register - Low (SIIL) */ + u8 res1[4]; + u32 sepnr; /* System External Interrupt Pending Register (SEI) */ + u32 smprr_a; /* System Mixed Interrupt Group A Priority Register (PRR) */ + u32 smprr_b; /* System Mixed Interrupt Group B Priority Register (PRR) */ +#define PRR_0 0xe0000000 /* Priority Register, Position 0 programming */ +#define PRR_1 0x1c000000 /* Priority Register, Position 1 programming */ +#define PRR_2 0x03800000 /* Priority Register, Position 2 programming */ +#define PRR_3 0x00700000 /* Priority Register, Position 3 programming */ +#define PRR_4 0x0000e000 /* Priority Register, Position 4 programming */ +#define PRR_5 0x00001c00 /* Priority Register, Position 5 programming */ +#define PRR_6 0x00000380 /* Priority Register, Position 6 programming */ +#define PRR_7 0x00000070 /* Priority Register, Position 7 programming */ #define PRR_RES ~(PRR_0|PRR_1|PRR_2|PRR_3|PRR_4|PRR_5|PRR_6|PRR_7) - u32 semsr; /* System External Interrupt Mask Register (SEI) */ -#define SEI_IRQ0 0x80000000 /* IRQ0 external interrupt */ -#define SEI_IRQ1 0x40000000 /* IRQ1 external interrupt */ -#define SEI_IRQ2 0x20000000 /* IRQ2 external interrupt */ -#define SEI_IRQ3 0x10000000 /* IRQ3 external interrupt */ -#define SEI_IRQ4 0x08000000 /* IRQ4 external interrupt */ -#define SEI_IRQ5 0x04000000 /* IRQ5 external interrupt */ -#define SEI_IRQ6 0x02000000 /* IRQ6 external interrupt */ -#define SEI_IRQ7 0x01000000 /* IRQ7 external interrupt */ -#define SEI_SIRQ0 0x00008000 /* SIRQ0 external interrupt */ + u32 semsr; /* System External Interrupt Mask Register (SEI) */ +#define SEI_IRQ0 0x80000000 /* IRQ0 external interrupt */ +#define SEI_IRQ1 0x40000000 /* IRQ1 external interrupt */ +#define SEI_IRQ2 0x20000000 /* IRQ2 external interrupt */ +#define SEI_IRQ3 0x10000000 /* IRQ3 external interrupt */ +#define SEI_IRQ4 0x08000000 /* IRQ4 external interrupt */ +#define SEI_IRQ5 0x04000000 /* IRQ5 external interrupt */ +#define SEI_IRQ6 0x02000000 /* IRQ6 external interrupt */ +#define SEI_IRQ7 0x01000000 /* IRQ7 external interrupt */ +#define SEI_SIRQ0 0x00008000 /* SIRQ0 external interrupt */ #define SEI_RES ~( SEI_IRQ0 | SEI_IRQ1 | SEI_IRQ2 | SEI_IRQ3 \ | SEI_IRQ4 | SEI_IRQ5 | SEI_IRQ6 | SEI_IRQ7 \ | SEI_SIRQ0) - u32 secnr; /* System External Interrupt Control Register (SECNR) */ -#define SECNR_MIXB0T 0xc0000000 /* MIXB0 priority position IPIC output interrupt type */ -#define SECNR_MIXB1T 0x30000000 /* MIXB1 priority position IPIC output interrupt type */ -#define SECNR_MIXA0T 0x00c00000 /* MIXA0 priority position IPIC output interrupt type */ -#define SECNR_SYSA1T 0x00300000 /* MIXA1 priority position IPIC output interrupt type */ + u32 secnr; /* System External Interrupt Control Register (SECNR) */ +#define SECNR_MIXB0T 0xc0000000 /* MIXB0 priority position IPIC output interrupt type */ +#define SECNR_MIXB1T 0x30000000 /* MIXB1 priority position IPIC output interrupt type */ +#define SECNR_MIXA0T 0x00c00000 /* MIXA0 priority position IPIC output interrupt type */ +#define SECNR_SYSA1T 0x00300000 /* MIXA1 priority position IPIC output interrupt type */ #define SECNR_EDI0 0x00008000 /* IRQ0 external interrupt edge/level detect */ #define SECNR_EDI1 0x00004000 /* IRQ1 external interrupt edge/level detect */ #define SECNR_EDI2 0x00002000 /* IRQ2 external interrupt edge/level detect */ @@ -339,176 +439,238 @@ typedef struct ipic8349 { | SECNR_SYSA1T | SECNR_EDI0 | SECNR_EDI1 \ | SECNR_EDI2 | SECNR_EDI3 | SECNR_EDI4 \ | SECNR_EDI5 | SECNR_EDI6 | SECNR_EDI7) - u32 sersr; /* System Error Status Register (SERR) */ - u32 sermr; /* System Error Mask Register (SERR) */ -#define SERR_IRQ0 0x80000000 /* IRQ0 MCP request */ -#define SERR_WDT 0x40000000 /* WDT MCP request */ -#define SERR_SBA 0x20000000 /* SBA MCP request */ -#define SERR_DDR 0x10000000 /* DDR MCP request */ -#define SERR_LBC 0x08000000 /* LBC MCP request */ -#define SERR_PCI1 0x04000000 /* PCI1 MCP request */ -#define SERR_PCI2 0x02000000 /* PCI2 MCP request */ -#define SERR_MU 0x01000000 /* MU MCP request */ -#define SERR_RNC 0x00010000 /* MU MCP request (!!! Non-visible for users !!!) */ + u32 sersr; /* System Error Status Register (SERR) */ + u32 sermr; /* System Error Mask Register (SERR) */ +#define SERR_IRQ0 0x80000000 /* IRQ0 MCP request */ +#define SERR_WDT 0x40000000 /* WDT MCP request */ +#define SERR_SBA 0x20000000 /* SBA MCP request */ +#if defined (CONFIG_MPC8349) +#define SERR_DDR 0x10000000 /* DDR MCP request */ +#define SERR_LBC 0x08000000 /* LBC MCP request */ +#define SERR_PCI1 0x04000000 /* PCI1 MCP request */ +#define SERR_PCI2 0x02000000 /* PCI2 MCP request */ +#endif +#if defined (CONFIG_MPC8360) +#define SERR_CIEE 0x10000000 /* CIEE MCP request */ +#define SERR_CMEE 0x08000000 /* CMEEMCP request */ +#define SERR_PCI 0x04000000 /* PCI MCP request */ +#endif +#define SERR_MU 0x01000000 /* MU MCP request */ +#define SERR_RNC 0x00010000 /* MU MCP request (!!! Non-visible for users !!!) */ +#if defined (CONFIG_MPC8349) #define SERR_RES ~( SERR_IRQ0 | SERR_WDT | SERR_SBA | SERR_DDR \ |SERR_LBC | SERR_PCI1 | SERR_PCI2 | SERR_MU \ |SERR_RNC ) - u32 sercr; /* System Error Control Register (SERCR) */ -#define SERCR_MCPR 0x00000001 /* MCP Route */ +#elif defined (CONFIG_MPC8360) +#define SERR_RES ~( SERR_IRQ0|SERR_WDT |SERR_SBA |SERR_CIEE\ + |SERR_CMEE|SERR_PCI|SERR_MU) +#endif + u32 sercr; /* System Error Control Register (SERCR) */ +#define SERCR_MCPR 0x00000001 /* MCP Route */ #define SERCR_RES ~(SERCR_MCPR) - u8 res2[4]; - u32 sifcr_h; /* System Internal Interrupt Force Register - High (SIIH) */ - u32 sifcr_l; /* System Internal Interrupt Force Register - Low (SIIL) */ - u32 sefcr; /* System External Interrupt Force Register (SEI) */ - u32 serfr; /* System Error Force Register (SERR) */ - u8 res3[0xA0]; -} ipic8349_t; + u8 res2[4]; + u32 sifcr_h; /* System Internal Interrupt Force Register - High (SIIH) */ + u32 sifcr_l; /* System Internal Interrupt Force Register - Low (SIIL) */ + u32 sefcr; /* System External Interrupt Force Register (SEI) */ + u32 serfr; /* System Error Force Register (SERR) */ + u32 scvcr; /* System Critical Interrupt Vector Register */ +#define SCVCR_CVECX 0xFC000000 /* Backward (MPC8260) compatible + critical interrupt vector. */ +#define SCVCR_CVEC 0x0000007F /* Critical interrupt vector */ +#define SCVCR_RES ~(SCVCR_CVECX|SCVCR_CVEC) + u32 smvcr; /* System Management Interrupt Vector Register */ +#define SMVCR_CVECX 0xFC000000 /* Backward (MPC8260) compatible + critical interrupt vector. */ +#define SMVCR_CVEC 0x0000007F /* Critical interrupt vector */ +#define SMVCR_RES ~(SMVCR_CVECX|SMVCR_CVEC) + u8 res3[0x98]; +} ipic83xx_t; /* * System Arbiter Registers */ -typedef struct arbiter8349 { - u32 acr; /* Arbiter Configuration Register */ -#define ACR_COREDIS 0x10000000 /* Core disable. */ -#define ACR_PIPE_DEP 0x00070000 /* Pipeline depth (number of outstanding transactions). */ -#define ACR_PCI_RPTCNT 0x00007000 /* PCI repeat count. */ -#define ACR_RPTCNT 0x00000700 /* Repeat count. */ -#define ACR_APARK 0x00000030 /* Address parking. */ -#define ACR_PARKM 0x0000000F /* Parking master. */ +typedef struct arbiter83xx { + u32 acr; /* Arbiter Configuration Register */ +#define ACR_COREDIS 0x10000000 /* Core disable. */ +#define ACR_COREDIS_SHIFT (31-7) +#define ACR_PIPE_DEP 0x00070000 /* Pipeline depth (number of outstanding transactions). */ +#define ACR_PIPE_DEP_SHIFT (31-15) +#define ACR_PCI_RPTCNT 0x00007000 /* PCI repeat count. */ +#define ACR_PCI_RPTCNT_SHIFT (31-19) +#define ACR_RPTCNT 0x00000700 /* Repeat count. */ +#define ACR_RPTCNT_SHIFT (31-23) +#define ACR_APARK 0x00000030 /* Address parking. */ +#define ACR_APARK_SHIFT (31-27) +#define ACR_PARKM 0x0000000F /* Parking master. */ +#define ACR_PARKM_SHIFT (31-31) #define ACR_RES ~(ACR_COREDIS|ACR_PIPE_DEP|ACR_PCI_RPTCNT|ACR_RPTCNT|ACR_APARK|ACR_PARKM) - u32 atr; /* Arbiter Timers Register */ -#define ATR_DTO 0x00FF0000 /* Data time out. */ -#define ATR_ATO 0x000000FF /* Address time out. */ + u32 atr; /* Arbiter Timers Register */ +#define ATR_DTO 0x00FF0000 /* Data time out. */ +#define ATR_ATO 0x000000FF /* Address time out. */ #define ATR_RES ~(ATR_DTO|ATR_ATO) u8 res[4]; - u32 aer; /* Arbiter Event Register (AE)*/ - u32 aidr; /* Arbiter Interrupt Definition Register (AE) */ - u32 amr; /* Arbiter Mask Register (AE) */ - u32 aeatr; /* Arbiter Event Attributes Register */ -#define AEATR_EVENT 0x07000000 /* Event type. */ -#define AEATR_MSTR_ID 0x001F0000 /* Master Id. */ -#define AEATR_TBST 0x00000800 /* Transfer burst. */ -#define AEATR_TSIZE 0x00000700 /* Transfer Size. */ -#define AEATR_TTYPE 0x0000001F /* Transfer Type. */ + u32 aer; /* Arbiter Event Register (AE) */ + u32 aidr; /* Arbiter Interrupt Definition Register (AE) */ + u32 amr; /* Arbiter Mask Register (AE) */ + u32 aeatr; /* Arbiter Event Attributes Register */ +#define AEATR_EVENT 0x07000000 /* Event type. */ +#define AEATR_MSTR_ID 0x001F0000 /* Master Id. */ +#define AEATR_TBST 0x00000800 /* Transfer burst. */ +#define AEATR_TSIZE 0x00000700 /* Transfer Size. */ +#define AEATR_TTYPE 0x0000001F /* Transfer Type. */ #define AEATR_RES ~(AEATR_EVENT|AEATR_MSTR_ID|AEATR_TBST|AEATR_TSIZE|AEATR_TTYPE) - u32 aeadr; /* Arbiter Event Address Register */ - u32 aerr; /* Arbiter Event Response Register (AE)*/ -#define AE_ETEA 0x00000020 /* Transfer error. */ -#define AE_RES_ 0x00000010 /* Reserved transfer type. */ -#define AE_ECW 0x00000008 /* External control word transfer type. */ -#define AE_AO 0x00000004 /* Address Only transfer type. */ -#define AE_DTO 0x00000002 /* Data time out. */ -#define AE_ATO 0x00000001 /* Address time out. */ + u32 aeadr; /* Arbiter Event Address Register */ + u32 aerr; /* Arbiter Event Response Register (AE) */ +#define AE_ETEA 0x00000020 /* Transfer error. */ +#define AE_RES_ 0x00000010 /* Reserved transfer type. */ +#define AE_ECW 0x00000008 /* External control word transfer type. */ +#define AE_AO 0x00000004 /* Address Only transfer type. */ +#define AE_DTO 0x00000002 /* Data time out. */ +#define AE_ATO 0x00000001 /* Address time out. */ #define AE_RSRV ~(AE_ETEA|AE_RES_|AE_ECW|AE_AO|AE_DTO|AE_ATO) u8 res1[0xDC]; -} arbiter8349_t; +} arbiter83xx_t; /* * Reset Module */ -typedef struct reset8349 { - u32 rcwl; /* RCWL Register */ +typedef struct reset83xx { + u32 rcwl; /* RCWL Register */ #define RCWL_LBIUCM 0x80000000 /* LBIUCM */ #define RCWL_LBIUCM_SHIFT 31 #define RCWL_DDRCM 0x40000000 /* DDRCM */ #define RCWL_DDRCM_SHIFT 30 +#if defined (CONFIG_MPC8349) #define RCWL_SVCOD 0x30000000 /* SVCOD */ -#define RCWL_SPMF 0x0f000000 /* SPMF */ -#define RCWL_SPMF_SHIFT 24 +#endif +#define RCWL_SPMF 0x0f000000 /* SPMF */ +#define RCWL_SPMF_SHIFT 24 #define RCWL_COREPLL 0x007F0000 /* COREPLL */ #define RCWL_COREPLL_SHIFT 16 #define RCWL_CEVCOD 0x000000C0 /* CEVCOD */ #define RCWL_CEPDF 0x00000020 /* CEPDF */ +#define RCWL_CEPDF_SHIFT 5 #define RCWL_CEPMF 0x0000001F /* CEPMF */ -#define RCWL_RES ~(RCWL_BIUCM|RCWL_DDRCM|RCWL_SVCOD|RCWL_SPMF|RCWL_COREPLL|RCWL_CEVCOD|RCWL_CEPDF|RCWL_CEPMF) - u32 rcwh; /* RCHL Register */ +#define RCWL_CEPMF_SHIFT 0 +#if defined (CONFIG_MPC8349) +#define RCWL_RES ~(RCWL_LBIUCM|RCWL_DDRCM|RCWL_SVCOD|RCWL_SPMF|RCWL_COREPLL|RCWL_CEVCOD|RCWL_CEPDF|RCWL_CEPMF) +#elif defined (CONFIG_MPC8360) +#define RCWL_RES ~(RCWL_LBIUCM|RCWL_DDRCM|RCWL_SPMF|RCWL_COREPLL|RCWL_CEPDF|RCWL_CEPMF) +#endif + u32 rcwh; /* RCHL Register */ #define RCWH_PCIHOST 0x80000000 /* PCIHOST */ #define RCWH_PCIHOST_SHIFT 31 +#if defined (CONFIG_MPC8349) #define RCWH_PCI64 0x40000000 /* PCI64 */ #define RCWH_PCI1ARB 0x20000000 /* PCI1ARB */ #define RCWH_PCI2ARB 0x10000000 /* PCI2ARB */ +#elif defined (CONFIG_MPC8360) +#define RCWH_PCIARB 0x20000000 /* PCI internal arbiter mode. */ +#define RCWH_PCICKDRV 0x10000000 /* PCI clock output drive. */ +#endif #define RCWH_COREDIS 0x08000000 /* COREDIS */ -#define RCWH_BMS 0x04000000 /* BMS */ +#define RCWH_BMS 0x04000000 /* BMS */ #define RCWH_BOOTSEQ 0x03000000 /* BOOTSEQ */ -#define RCWH_SWEN 0x00800000 /* SWEN */ +#define RCWH_SWEN 0x00800000 /* SWEN */ #define RCWH_ROMLOC 0x00700000 /* ROMLOC */ +#if defined (CONFIG_MPC8349) #define RCWH_TSEC1M 0x0000c000 /* TSEC1M */ #define RCWH_TSEC2M 0x00003000 /* TSEC2M */ -#define RCWH_TPR 0x00000100 /* TPR */ -#define RCWH_TLE 0x00000008 /* TLE */ -#define RCWH_LALE 0x00000004 /* LALE */ +#define RCWH_TPR 0x00000100 /* TPR */ +#elif defined (CONFIG_MPC8360) +#define RCWH_SDDRIOE 0x00000010 /* Secondary DDR IO Enable. */ +#endif +#define RCWH_TLE 0x00000008 /* TLE */ +#define RCWH_LALE 0x00000004 /* LALE */ +#if defined (CONFIG_MPC8349) #define RCWH_RES ~(RCWH_PCIHOST | RCWH_PCI64 | RCWH_PCI1ARB \ | RCWH_PCI2ARB | RCWH_COREDIS | RCWH_BMS \ | RCWH_BOOTSEQ | RCWH_SWEN | RCWH_ROMLOC \ | RCWH_TSEC1M | RCWH_TSEC2M | RCWH_TPR \ | RCWH_TLE | RCWH_LALE) - u8 res0[8]; - u32 rsr; /* Reset status Register */ -#define RSR_RSTSRC 0xE0000000 /* Reset source */ +#elif defined (CONFIG_MPC8360) +#define RCWH_RES ~(RCWH_PCIHOST|RCWH_PCIARB|RCWH_PCICKDRV \ + |RCWH_COREDIS|RCWH_BMS|RCWH_BOOTSEQ|RCWH_SWEN \ + |RCWH_SDDRIOE |RCWH_TLE) +#endif + u8 res0[8]; + u32 rsr; /* Reset status Register */ +#define RSR_RSTSRC 0xE0000000 /* Reset source */ #define RSR_RSTSRC_SHIFT 29 -#define RSR_BSF 0x00010000 /* Boot seq. fail */ -#define RSR_BSF_SHIFT 16 -#define RSR_SWSR 0x00002000 /* software soft reset */ -#define RSR_SWSR_SHIFT 13 -#define RSR_SWHR 0x00001000 /* software hard reset */ -#define RSR_SWHR_SHIFT 12 -#define RSR_JHRS 0x00000200 /* jtag hreset */ -#define RSR_JHRS_SHIFT 9 -#define RSR_JSRS 0x00000100 /* jtag sreset status */ -#define RSR_JSRS_SHIFT 8 -#define RSR_CSHR 0x00000010 /* checkstop reset status */ -#define RSR_CSHR_SHIFT 4 -#define RSR_SWRS 0x00000008 /* software watchdog reset status */ -#define RSR_SWRS_SHIFT 3 -#define RSR_BMRS 0x00000004 /* bus monitop reset status */ -#define RSR_BMRS_SHIFT 2 -#define RSR_SRS 0x00000002 /* soft reset status */ -#define RSR_SRS_SHIFT 1 -#define RSR_HRS 0x00000001 /* hard reset status */ -#define RSR_HRS_SHIFT 0 +#define RSR_BSF 0x00010000 /* Boot seq. fail */ +#define RSR_BSF_SHIFT 16 +#define RSR_SWSR 0x00002000 /* software soft reset */ +#define RSR_SWSR_SHIFT 13 +#define RSR_SWHR 0x00001000 /* software hard reset */ +#define RSR_SWHR_SHIFT 12 +#define RSR_JHRS 0x00000200 /* jtag hreset */ +#define RSR_JHRS_SHIFT 9 +#define RSR_JSRS 0x00000100 /* jtag sreset status */ +#define RSR_JSRS_SHIFT 8 +#define RSR_CSHR 0x00000010 /* checkstop reset status */ +#define RSR_CSHR_SHIFT 4 +#define RSR_SWRS 0x00000008 /* software watchdog reset status */ +#define RSR_SWRS_SHIFT 3 +#define RSR_BMRS 0x00000004 /* bus monitop reset status */ +#define RSR_BMRS_SHIFT 2 +#define RSR_SRS 0x00000002 /* soft reset status */ +#define RSR_SRS_SHIFT 1 +#define RSR_HRS 0x00000001 /* hard reset status */ +#define RSR_HRS_SHIFT 0 #define RSR_RES ~(RSR_RSTSRC | RSR_BSF | RSR_SWSR | RSR_SWHR | RSR_JHRS | RSR_JSRS | RSR_CSHR | RSR_SWRS | RSR_BMRS | RSR_SRS | RSR_HRS) - u32 rmr; /* Reset mode Register */ -#define RMR_CSRE 0x00000001 /* checkstop reset enable */ -#define RMR_CSRE_SHIFT 0 + u32 rmr; /* Reset mode Register */ +#define RMR_CSRE 0x00000001 /* checkstop reset enable */ +#define RMR_CSRE_SHIFT 0 #define RMR_RES ~(RMR_CSRE) - u32 rpr; /* Reset protection Register */ - u32 rcr; /* Reset Control Register */ -#define RCR_SWHR 0x00000002 /* software hard reset */ -#define RCR_SWSR 0x00000001 /* software soft reset */ + u32 rpr; /* Reset protection Register */ + u32 rcr; /* Reset Control Register */ +#define RCR_SWHR 0x00000002 /* software hard reset */ +#define RCR_SWSR 0x00000001 /* software soft reset */ #define RCR_RES ~(RCR_SWHR | RCR_SWSR) - u32 rcer; /* Reset Control Enable Register */ -#define RCER_CRE 0x00000001 /* software hard reset */ + u32 rcer; /* Reset Control Enable Register */ +#define RCER_CRE 0x00000001 /* software hard reset */ #define RCER_RES ~(RCER_CRE) - u8 res1[0xDC]; -} reset8349_t; + u8 res1[0xDC]; +} reset83xx_t; -typedef struct clk8349 { - u32 spmr; /* system PLL mode Register */ +typedef struct clk83xx { + u32 spmr; /* system PLL mode Register */ #define SPMR_LBIUCM 0x80000000 /* LBIUCM */ #define SPMR_DDRCM 0x40000000 /* DDRCM */ +#if defined (CONFIG_MPC8349) #define SPMR_SVCOD 0x30000000 /* SVCOD */ -#define SPMR_SPMF 0x0F000000 /* SPMF */ -#define SPMR_CKID 0x00800000 /* CKID */ +#endif +#define SPMR_SPMF 0x0F000000 /* SPMF */ +#define SPMR_CKID 0x00800000 /* CKID */ #define SPMR_CKID_SHIFT 23 #define SPMR_COREPLL 0x007F0000 /* COREPLL */ #define SPMR_CEVCOD 0x000000C0 /* CEVCOD */ #define SPMR_CEPDF 0x00000020 /* CEPDF */ #define SPMR_CEPMF 0x0000001F /* CEPMF */ +#if defined (CONFIG_MPC8349) #define SPMR_RES ~(SPMR_LBIUCM | SPMR_DDRCM | SPMR_SVCOD \ | SPMR_SPMF | SPMR_CKID | SPMR_COREPLL \ | SPMR_CEVCOD | SPMR_CEPDF | SPMR_CEPMF) - u32 occr; /* output clock control Register */ +#elif defined (CONFIG_MPC8360) +#define SPMR_RES ~(SPMR_LBIUCM | SPMR_DDRCM | SPMR_SPMF \ + | SPMR_CKID | SPMR_COREPLL | SPMR_CEVCOD \ + | SPMR_CEPDF | SPMR_CEPMF) +#endif + u32 occr; /* output clock control Register */ #define OCCR_PCICOE0 0x80000000 /* PCICOE0 */ #define OCCR_PCICOE1 0x40000000 /* PCICOE1 */ #define OCCR_PCICOE2 0x20000000 /* PCICOE2 */ +#if defined (CONFIG_MPC8349) #define OCCR_PCICOE3 0x10000000 /* PCICOE3 */ #define OCCR_PCICOE4 0x08000000 /* PCICOE4 */ #define OCCR_PCICOE5 0x04000000 /* PCICOE5 */ #define OCCR_PCICOE6 0x02000000 /* PCICOE6 */ #define OCCR_PCICOE7 0x01000000 /* PCICOE7 */ +#endif #define OCCR_PCICD0 0x00800000 /* PCICD0 */ #define OCCR_PCICD1 0x00400000 /* PCICD1 */ #define OCCR_PCICD2 0x00200000 /* PCICD2 */ +#if defined (CONFIG_MPC8349) #define OCCR_PCICD3 0x00100000 /* PCICD3 */ #define OCCR_PCICD4 0x00080000 /* PCICD4 */ #define OCCR_PCICD5 0x00040000 /* PCICD5 */ @@ -522,72 +684,253 @@ typedef struct clk8349 { | OCCR_PCICD1 | OCCR_PCICD2 | OCCR_PCICD3 \ | OCCR_PCICD4 | OCCR_PCICD5 | OCCR_PCICD6 \ | OCCR_PCICD7 | OCCR_PCI1CR | OCCR_PCI2CR ) - u32 sccr; /* system clock control Register */ -#define SCCR_TSEC1CM 0xc0000000 /* TSEC1CM */ +#endif +#if defined (CONFIG_MPC8360) +#define OCCR_PCICR 0x00000002 /* PCI clock rate */ +#define OCCR_RES ~(OCCR_PCICOE0|OCCR_PCICOE1|OCCR_PCICOE2 \ + |OCCR_PCICD0|OCCR_PCICD1|OCCR_PCICD2|OCCR_PCICR ) +#endif + u32 sccr; /* system clock control Register */ +#if defined (CONFIG_MPC8349) +#define SCCR_TSEC1CM 0xc0000000 /* TSEC1CM */ #define SCCR_TSEC1CM_SHIFT 30 -#define SCCR_TSEC2CM 0x30000000 /* TSEC2CM */ +#define SCCR_TSEC2CM 0x30000000 /* TSEC2CM */ #define SCCR_TSEC2CM_SHIFT 28 -#define SCCR_ENCCM 0x03000000 /* ENCCM */ +#endif +#define SCCR_ENCCM 0x03000000 /* ENCCM */ #define SCCR_ENCCM_SHIFT 24 -#define SCCR_USBMPHCM 0x00c00000 /* USBMPHCM */ +#if defined (CONFIG_MPC8349) +#define SCCR_USBMPHCM 0x00c00000 /* USBMPHCM */ #define SCCR_USBMPHCM_SHIFT 22 -#define SCCR_USBDRCM 0x00300000 /* USBDRCM */ +#define SCCR_USBDRCM 0x00300000 /* USBDRCM */ #define SCCR_USBDRCM_SHIFT 20 -#define SCCR_PCICM 0x00010000 /* PCICM */ +#endif +#define SCCR_PCICM 0x00010000 /* PCICM */ +#if defined (CONFIG_MPC8349) #define SCCR_RES ~( SCCR_TSEC1CM | SCCR_TSEC2CM | SCCR_ENCCM \ | SCCR_USBMPHCM | SCCR_USBDRCM | SCCR_PCICM) - u8 res0[0xF4]; -} clk8349_t; +#endif +#if defined (CONFIG_MPC8360) +#define SCCR_RES ~(SCCR_ENCCM | SCCR_PCICM) +#endif + u8 res0[0xF4]; +} clk83xx_t; /* * Power Management Control Module */ -typedef struct pmc8349 { - u32 pmccr; /* PMC Configuration Register */ -#define PMCCR_SLPEN 0x00000001 /* System Low Power Enable */ -#define PMCCR_DLPEN 0x00000002 /* DDR SDRAM Low Power Enable */ -#define PMCCR_RES ~(PMCCR_SLPEN | PMCCR_DLPEN) - u32 pmcer; /* PMC Event Register */ -#define PMCER_PMCI 0x00000001 /* PMC Interrupt */ +typedef struct pmc83xx { + u32 pmccr; /* PMC Configuration Register */ +#define PMCCR_SLPEN 0x00000001 /* System Low Power Enable */ +#define PMCCR_DLPEN 0x00000002 /* DDR SDRAM Low Power Enable */ +#if defined (CONFIG_MPC8360) +#define PMCCR_SDLPEN 0x00000004 /* Secondary DDR SDRAM Low Power Enable */ +#define PMCCR_RES ~(PMCCR_SLPEN | PMCCR_DLPEN | PMCCR_SDLPEN) +#elif defined (CONFIG_MPC8349) +#define PMCCR_RES ~(PMCCR_SLPEN | PMCCR_DLPEN) +#endif + u32 pmcer; /* PMC Event Register */ +#define PMCER_PMCI 0x00000001 /* PMC Interrupt */ #define PMCER_RES ~(PMCER_PMCI) - u32 pmcmr; /* PMC Mask Register */ -#define PMCMR_PMCIE 0x0001 /* PMC Interrupt Enable */ + u32 pmcmr; /* PMC Mask Register */ +#define PMCMR_PMCIE 0x0001 /* PMC Interrupt Enable */ #define PMCMR_RES ~(PMCMR_PMCIE) u8 res0[0xF4]; -} pmc8349_t; - +} pmc83xx_t; +#if defined (CONFIG_MPC8349) /* * general purpose I/O module */ -typedef struct gpio8349 { - u32 dir; /* direction register */ - u32 odr; /* open drain register */ - u32 dat; /* data register */ - u32 ier; /* interrupt event register */ - u32 imr; /* interrupt mask register */ - u32 icr; /* external interrupt control register */ +typedef struct gpio83xx { + u32 dir; /* direction register */ + u32 odr; /* open drain register */ + u32 dat; /* data register */ + u32 ier; /* interrupt event register */ + u32 imr; /* interrupt mask register */ + u32 icr; /* external interrupt control register */ u8 res0[0xE8]; -} gpio8349_t; +} gpio83xx_t; +#endif + +#if defined (CONFIG_MPC8360) +/* + * QE Ports Interrupts Registers + */ +typedef struct qepi83xx { + u8 res0[0xC]; + u32 qepier; /* QE Ports Interrupt Event Register */ +#define QEPIER_PA15 0x80000000 +#define QEPIER_PA16 0x40000000 +#define QEPIER_PA29 0x20000000 +#define QEPIER_PA30 0x10000000 +#define QEPIER_PB3 0x08000000 +#define QEPIER_PB5 0x04000000 +#define QEPIER_PB12 0x02000000 +#define QEPIER_PB13 0x01000000 +#define QEPIER_PB26 0x00800000 +#define QEPIER_PB27 0x00400000 +#define QEPIER_PC27 0x00200000 +#define QEPIER_PC28 0x00100000 +#define QEPIER_PC29 0x00080000 +#define QEPIER_PD12 0x00040000 +#define QEPIER_PD13 0x00020000 +#define QEPIER_PD16 0x00010000 +#define QEPIER_PD17 0x00008000 +#define QEPIER_PD26 0x00004000 +#define QEPIER_PD27 0x00002000 +#define QEPIER_PE12 0x00001000 +#define QEPIER_PE13 0x00000800 +#define QEPIER_PE24 0x00000400 +#define QEPIER_PE25 0x00000200 +#define QEPIER_PE26 0x00000100 +#define QEPIER_PE27 0x00000080 +#define QEPIER_PE31 0x00000040 +#define QEPIER_PF20 0x00000020 +#define QEPIER_PG31 0x00000010 +#define QEPIER_RES ~(QEPIER_PA15|QEPIER_PA16|QEPIER_PA29|QEPIER_PA30|QEPIER_PB3 \ + |QEPIER_PB5|QEPIER_PB12|QEPIER_PB13|QEPIER_PB26|QEPIER_PB27 \ + |QEPIER_PC27|QEPIER_PC28|QEPIER_PC29|QEPIER_PD12|QEPIER_PD13 \ + |QEPIER_PD16|QEPIER_PD17|QEPIER_PD26|QEPIER_PD27|QEPIER_PE12 \ + |QEPIER_PE13|QEPIER_PE24|QEPIER_PE25|QEPIER_PE26|QEPIER_PE27 \ + |QEPIER_PE31|QEPIER_PF20|QEPIER_PG31) + u32 qepimr; /* QE Ports Interrupt Mask Register */ +#define QEPIMR_PA15 0x80000000 +#define QEPIMR_PA16 0x40000000 +#define QEPIMR_PA29 0x20000000 +#define QEPIMR_PA30 0x10000000 +#define QEPIMR_PB3 0x08000000 +#define QEPIMR_PB5 0x04000000 +#define QEPIMR_PB12 0x02000000 +#define QEPIMR_PB13 0x01000000 +#define QEPIMR_PB26 0x00800000 +#define QEPIMR_PB27 0x00400000 +#define QEPIMR_PC27 0x00200000 +#define QEPIMR_PC28 0x00100000 +#define QEPIMR_PC29 0x00080000 +#define QEPIMR_PD12 0x00040000 +#define QEPIMR_PD13 0x00020000 +#define QEPIMR_PD16 0x00010000 +#define QEPIMR_PD17 0x00008000 +#define QEPIMR_PD26 0x00004000 +#define QEPIMR_PD27 0x00002000 +#define QEPIMR_PE12 0x00001000 +#define QEPIMR_PE13 0x00000800 +#define QEPIMR_PE24 0x00000400 +#define QEPIMR_PE25 0x00000200 +#define QEPIMR_PE26 0x00000100 +#define QEPIMR_PE27 0x00000080 +#define QEPIMR_PE31 0x00000040 +#define QEPIMR_PF20 0x00000020 +#define QEPIMR_PG31 0x00000010 +#define QEPIMR_RES ~(QEPIMR_PA15|QEPIMR_PA16|QEPIMR_PA29|QEPIMR_PA30|QEPIMR_PB3 \ + |QEPIMR_PB5|QEPIMR_PB12|QEPIMR_PB13|QEPIMR_PB26|QEPIMR_PB27 \ + |QEPIMR_PC27|QEPIMR_PC28|QEPIMR_PC29|QEPIMR_PD12|QEPIMR_PD13 \ + |QEPIMR_PD16|QEPIMR_PD17|QEPIMR_PD26|QEPIMR_PD27|QEPIMR_PE12 \ + |QEPIMR_PE13|QEPIMR_PE24|QEPIMR_PE25|QEPIMR_PE26|QEPIMR_PE27 \ + |QEPIMR_PE31|QEPIMR_PF20|QEPIMR_PG31) + u32 qepicr; /* QE Ports Interrupt Control Register */ +#define QEPICR_PA15 0x80000000 +#define QEPICR_PA16 0x40000000 +#define QEPICR_PA29 0x20000000 +#define QEPICR_PA30 0x10000000 +#define QEPICR_PB3 0x08000000 +#define QEPICR_PB5 0x04000000 +#define QEPICR_PB12 0x02000000 +#define QEPICR_PB13 0x01000000 +#define QEPICR_PB26 0x00800000 +#define QEPICR_PB27 0x00400000 +#define QEPICR_PC27 0x00200000 +#define QEPICR_PC28 0x00100000 +#define QEPICR_PC29 0x00080000 +#define QEPICR_PD12 0x00040000 +#define QEPICR_PD13 0x00020000 +#define QEPICR_PD16 0x00010000 +#define QEPICR_PD17 0x00008000 +#define QEPICR_PD26 0x00004000 +#define QEPICR_PD27 0x00002000 +#define QEPICR_PE12 0x00001000 +#define QEPICR_PE13 0x00000800 +#define QEPICR_PE24 0x00000400 +#define QEPICR_PE25 0x00000200 +#define QEPICR_PE26 0x00000100 +#define QEPICR_PE27 0x00000080 +#define QEPICR_PE31 0x00000040 +#define QEPICR_PF20 0x00000020 +#define QEPICR_PG31 0x00000010 +#define QEPICR_RES ~(QEPICR_PA15|QEPICR_PA16|QEPICR_PA29|QEPICR_PA30|QEPICR_PB3 \ + |QEPICR_PB5|QEPICR_PB12|QEPICR_PB13|QEPICR_PB26|QEPICR_PB27 \ + |QEPICR_PC27|QEPICR_PC28|QEPICR_PC29|QEPICR_PD12|QEPICR_PD13 \ + |QEPICR_PD16|QEPICR_PD17|QEPICR_PD26|QEPICR_PD27|QEPICR_PE12 \ + |QEPICR_PE13|QEPICR_PE24|QEPICR_PE25|QEPICR_PE26|QEPICR_PE27 \ + |QEPICR_PE31|QEPICR_PF20|QEPICR_PG31) + u8 res1[0xE8]; +} qepi83xx_t; + +/* + * general purpose I/O module + */ +typedef struct gpio_n { + u32 podr; /* Open Drain Register */ + u32 pdat; /* Data Register */ + u32 dir1; /* direction register 1 */ + u32 dir2; /* direction register 2 */ + u32 ppar1; /* Pin Assignment Register 1 */ + u32 ppar2; /* Pin Assignment Register 2 */ +} gpio_n_t; + +typedef struct gpio83xx { + gpio_n_t ioport[0x7]; + u8 res0[0x358]; +} gpio83xx_t; + +/* + * QE Secondary Bus Access Windows + */ + +typedef struct qesba83xx { + u32 lbmcsar; /* Local bus memory controller start address */ +#define LBMCSAR_SA 0x000FFFFF /* 20 most-significant bits of the start address */ +#define LBMCSAR_RES ~(LBMCSAR_SA) + u32 sdmcsar; /* Secondary DDR memory controller start address */ +#define SDMCSAR_SA 0x000FFFFF /* 20 most-significant bits of the start address */ +#define SDMCSAR_RES ~(SDMCSAR_SA) + u8 res0[0x38]; + u32 lbmcear; /* Local bus memory controller end address */ +#define LBMCEAR_EA 0x000FFFFF /* 20 most-significant bits of the end address */ +#define LBMCEAR_RES ~(LBMCEAR_EA) + u32 sdmcear; /* Secondary DDR memory controller end address */ +#define SDMCEAR_EA 0x000FFFFF /* 20 most-significant bits of the end address */ +#define SDMCEAR_RES ~(SDMCEAR_EA) + u8 res1[0x38]; + u32 lbmcar; /* Local bus memory controller attributes */ +#define LBMCAR_WEN 0x00000001 /* Forward transactions to the QE local bus */ +#define LBMCAR_RES ~(LBMCAR_WEN) + u32 sdmcar; /* Secondary DDR memory controller attributes */ +#define SDMCAR_WEN 0x00000001 /* Forward transactions to the second DDR bus */ +#define SDMCAR_RES ~(SDMCAR_WEN) + u8 res2[0x778]; +} qesba83xx_t; +#endif /* * DDR Memory Controller Memory Map */ -typedef struct ddr_cs_bnds{ +typedef struct ddr_cs_bnds { u32 csbnds; #define CSBNDS_SA 0x00FF0000 -#define CSBNDS_SA_SHIFT 8 +#define CSBNDS_SA_SHIFT 8 #define CSBNDS_EA 0x000000FF -#define CSBNDS_EA_SHIFT 24 - u8 res0[4]; +#define CSBNDS_EA_SHIFT 24 + u8 res0[4]; } ddr_cs_bnds_t; -typedef struct ddr8349{ - ddr_cs_bnds_t csbnds[4]; /**< Chip Select x Memory Bounds */ +typedef struct ddr83xx { + ddr_cs_bnds_t csbnds[4]; /**< Chip Select x Memory Bounds */ u8 res0[0x60]; - u32 cs_config[4]; /**< Chip Select x Configuration */ -#define CSCONFIG_EN 0x80000000 -#define CSCONFIG_AP 0x00800000 + u32 cs_config[4]; /**< Chip Select x Configuration */ +#define CSCONFIG_EN 0x80000000 +#define CSCONFIG_AP 0x00800000 #define CSCONFIG_ROW_BIT 0x00000700 #define CSCONFIG_ROW_BIT_12 0x00000000 #define CSCONFIG_ROW_BIT_13 0x00000100 @@ -598,7 +941,7 @@ typedef struct ddr8349{ #define CSCONFIG_COL_BIT_10 0x00000002 #define CSCONFIG_COL_BIT_11 0x00000003 u8 res1[0x78]; - u32 timing_cfg_1; /**< SDRAM Timing Configuration 1 */ + u32 timing_cfg_1; /**< SDRAM Timing Configuration 1 */ #define TIMING_CFG1_PRETOACT 0x70000000 #define TIMING_CFG1_PRETOACT_SHIFT 28 #define TIMING_CFG1_ACTTOPRE 0x0F000000 @@ -610,70 +953,70 @@ typedef struct ddr8349{ #define TIMING_CFG1_REFREC 0x0000F000 #define TIMING_CFG1_REFREC_SHIFT 12 #define TIMING_CFG1_WRREC 0x00000700 -#define TIMING_CFG1_WRREC_SHIFT 8 +#define TIMING_CFG1_WRREC_SHIFT 8 #define TIMING_CFG1_ACTTOACT 0x00000070 #define TIMING_CFG1_ACTTOACT_SHIFT 4 #define TIMING_CFG1_WRTORD 0x00000007 #define TIMING_CFG1_WRTORD_SHIFT 0 -#define TIMING_CFG1_CASLAT_20 0x00030000 /* CAS latency = 2.0 */ -#define TIMING_CFG1_CASLAT_25 0x00040000 /* CAS latency = 2.5 */ +#define TIMING_CFG1_CASLAT_20 0x00030000 /* CAS latency = 2.0 */ +#define TIMING_CFG1_CASLAT_25 0x00040000 /* CAS latency = 2.5 */ - u32 timing_cfg_2; /**< SDRAM Timing Configuration 2 */ -#define TIMING_CFG2_CPO 0x0F000000 -#define TIMING_CFG2_CPO_SHIFT 24 -#define TIMING_CFG2_ACSM 0x00080000 + u32 timing_cfg_2; /**< SDRAM Timing Configuration 2 */ +#define TIMING_CFG2_CPO 0x0F000000 +#define TIMING_CFG2_CPO_SHIFT 24 +#define TIMING_CFG2_ACSM 0x00080000 #define TIMING_CFG2_WR_DATA_DELAY 0x00001C00 -#define TIMING_CFG2_WR_DATA_DELAY_SHIFT 10 -#define TIMING_CFG2_CPO_DEF 0x00000000 /* default (= CASLAT + 1) */ +#define TIMING_CFG2_WR_DATA_DELAY_SHIFT 10 +#define TIMING_CFG2_CPO_DEF 0x00000000 /* default (= CASLAT + 1) */ - u32 sdram_cfg; /**< SDRAM Control Configuration */ + u32 sdram_cfg; /**< SDRAM Control Configuration */ #define SDRAM_CFG_MEM_EN 0x80000000 -#define SDRAM_CFG_SREN 0x40000000 +#define SDRAM_CFG_SREN 0x40000000 #define SDRAM_CFG_ECC_EN 0x20000000 -#define SDRAM_CFG_RD_EN 0x10000000 +#define SDRAM_CFG_RD_EN 0x10000000 #define SDRAM_CFG_SDRAM_TYPE 0x03000000 #define SDRAM_CFG_SDRAM_TYPE_SHIFT 24 #define SDRAM_CFG_DYN_PWR 0x00200000 -#define SDRAM_CFG_32_BE 0x00080000 -#define SDRAM_CFG_8_BE 0x00040000 -#define SDRAM_CFG_NCAP 0x00020000 -#define SDRAM_CFG_2T_EN 0x00008000 +#define SDRAM_CFG_32_BE 0x00080000 +#define SDRAM_CFG_8_BE 0x00040000 +#define SDRAM_CFG_NCAP 0x00020000 +#define SDRAM_CFG_2T_EN 0x00008000 #define SDRAM_CFG_SDRAM_TYPE_DDR 0x02000000 u8 res2[4]; - u32 sdram_mode; /**< SDRAM Mode Configuration */ + u32 sdram_mode; /**< SDRAM Mode Configuration */ #define SDRAM_MODE_ESD 0xFFFF0000 #define SDRAM_MODE_ESD_SHIFT 16 #define SDRAM_MODE_SD 0x0000FFFF -#define SDRAM_MODE_SD_SHIFT 0 -#define DDR_MODE_EXT_MODEREG 0x4000 /* select extended mode reg */ -#define DDR_MODE_EXT_OPMODE 0x3FF8 /* operating mode, mask */ -#define DDR_MODE_EXT_OP_NORMAL 0x0000 /* normal operation */ -#define DDR_MODE_QFC 0x0004 /* QFC / compatibility, mask */ -#define DDR_MODE_QFC_COMP 0x0000 /* compatible to older SDRAMs */ -#define DDR_MODE_WEAK 0x0002 /* weak drivers */ -#define DDR_MODE_DLL_DIS 0x0001 /* disable DLL */ -#define DDR_MODE_CASLAT 0x0070 /* CAS latency, mask */ -#define DDR_MODE_CASLAT_15 0x0010 /* CAS latency 1.5 */ -#define DDR_MODE_CASLAT_20 0x0020 /* CAS latency 2 */ -#define DDR_MODE_CASLAT_25 0x0060 /* CAS latency 2.5 */ -#define DDR_MODE_CASLAT_30 0x0030 /* CAS latency 3 */ -#define DDR_MODE_BTYPE_SEQ 0x0000 /* sequential burst */ -#define DDR_MODE_BTYPE_ILVD 0x0008 /* interleaved burst */ -#define DDR_MODE_BLEN_2 0x0001 /* burst length 2 */ -#define DDR_MODE_BLEN_4 0x0002 /* burst length 4 */ -#define DDR_REFINT_166MHZ_7US 1302 /* exact value for 7.8125 µs */ -#define DDR_BSTOPRE 256 /* use 256 cycles as a starting point */ -#define DDR_MODE_MODEREG 0x0000 /* select mode register */ +#define SDRAM_MODE_SD_SHIFT 0 +#define DDR_MODE_EXT_MODEREG 0x4000 /* select extended mode reg */ +#define DDR_MODE_EXT_OPMODE 0x3FF8 /* operating mode, mask */ +#define DDR_MODE_EXT_OP_NORMAL 0x0000 /* normal operation */ +#define DDR_MODE_QFC 0x0004 /* QFC / compatibility, mask */ +#define DDR_MODE_QFC_COMP 0x0000 /* compatible to older SDRAMs */ +#define DDR_MODE_WEAK 0x0002 /* weak drivers */ +#define DDR_MODE_DLL_DIS 0x0001 /* disable DLL */ +#define DDR_MODE_CASLAT 0x0070 /* CAS latency, mask */ +#define DDR_MODE_CASLAT_15 0x0010 /* CAS latency 1.5 */ +#define DDR_MODE_CASLAT_20 0x0020 /* CAS latency 2 */ +#define DDR_MODE_CASLAT_25 0x0060 /* CAS latency 2.5 */ +#define DDR_MODE_CASLAT_30 0x0030 /* CAS latency 3 */ +#define DDR_MODE_BTYPE_SEQ 0x0000 /* sequential burst */ +#define DDR_MODE_BTYPE_ILVD 0x0008 /* interleaved burst */ +#define DDR_MODE_BLEN_2 0x0001 /* burst length 2 */ +#define DDR_MODE_BLEN_4 0x0002 /* burst length 4 */ +#define DDR_REFINT_166MHZ_7US 1302 /* exact value for 7.8125 µs */ +#define DDR_BSTOPRE 256 /* use 256 cycles as a starting point */ +#define DDR_MODE_MODEREG 0x0000 /* select mode register */ u8 res3[8]; - u32 sdram_interval; /**< SDRAM Interval Configuration */ + u32 sdram_interval; /**< SDRAM Interval Configuration */ #define SDRAM_INTERVAL_REFINT 0x3FFF0000 #define SDRAM_INTERVAL_REFINT_SHIFT 16 #define SDRAM_INTERVAL_BSTOPRE 0x00003FFF -#define SDRAM_INTERVAL_BSTOPRE_SHIFT 0 - u8 res9[8]; - u32 sdram_clk_cntl; +#define SDRAM_INTERVAL_BSTOPRE_SHIFT 0 + u8 res9[8]; + u32 sdram_clk_cntl; #define DDR_SDRAM_CLK_CNTL_SS_EN 0x80000000 #define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_025 0x01000000 #define DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05 0x02000000 @@ -683,37 +1026,37 @@ typedef struct ddr8349{ u8 res4[0xCCC]; u32 data_err_inject_hi; /**< Memory Data Path Error Injection Mask High */ u32 data_err_inject_lo; /**< Memory Data Path Error Injection Mask Low */ - u32 ecc_err_inject; /**< Memory Data Path Error Injection Mask ECC */ + u32 ecc_err_inject; /**< Memory Data Path Error Injection Mask ECC */ #define ECC_ERR_INJECT_EMB (0x80000000>>22) /* ECC Mirror Byte */ #define ECC_ERR_INJECT_EIEN (0x80000000>>23) /* Error Injection Enable */ #define ECC_ERR_INJECT_EEIM (0xff000000>>24) /* ECC Erroe Injection Enable */ #define ECC_ERR_INJECT_EEIM_SHIFT 0 u8 res5[0x14]; - u32 capture_data_hi; /**< Memory Data Path Read Capture High */ - u32 capture_data_lo; /**< Memory Data Path Read Capture Low */ - u32 capture_ecc; /**< Memory Data Path Read Capture ECC */ + u32 capture_data_hi; /**< Memory Data Path Read Capture High */ + u32 capture_data_lo; /**< Memory Data Path Read Capture Low */ + u32 capture_ecc; /**< Memory Data Path Read Capture ECC */ #define CAPTURE_ECC_ECE (0xff000000>>24) #define CAPTURE_ECC_ECE_SHIFT 0 u8 res6[0x14]; - u32 err_detect; /**< Memory Error Detect */ -#define ECC_ERROR_DETECT_MME (0x80000000>>0) /* Multiple Memory Errors */ + u32 err_detect; /**< Memory Error Detect */ +#define ECC_ERROR_DETECT_MME (0x80000000>>0) /* Multiple Memory Errors */ #define ECC_ERROR_DETECT_MBE (0x80000000>>28) /* Multiple-Bit Error */ #define ECC_ERROR_DETECT_SBE (0x80000000>>29) /* Single-Bit ECC Error Pickup */ #define ECC_ERROR_DETECT_MSE (0x80000000>>31) /* Memory Select Error */ - u32 err_disable; /**< Memory Error Disable */ + u32 err_disable; /**< Memory Error Disable */ #define ECC_ERROR_DISABLE_MBED (0x80000000>>28) /* Multiple-Bit ECC Error Disable */ #define ECC_ERROR_DISABLE_SBED (0x80000000>>29) /* Sinle-Bit ECC Error disable */ #define ECC_ERROR_DISABLE_MSED (0x80000000>>31) /* Memory Select Error Disable */ #define ECC_ERROR_ENABLE ~(ECC_ERROR_DISABLE_MSED|ECC_ERROR_DISABLE_SBED|ECC_ERROR_DISABLE_MBED) - u32 err_int_en; /**< Memory Error Interrupt Enable */ + u32 err_int_en; /**< Memory Error Interrupt Enable */ #define ECC_ERR_INT_EN_MBEE (0x80000000>>28) /* Multiple-Bit ECC Error Interrupt Enable */ #define ECC_ERR_INT_EN_SBEE (0x80000000>>29) /* Single-Bit ECC Error Interrupt Enable */ #define ECC_ERR_INT_EN_MSEE (0x80000000>>31) /* Memory Select Error Interrupt Enable */ #define ECC_ERR_INT_DISABLE ~(ECC_ERR_INT_EN_MBEE|ECC_ERR_INT_EN_SBEE|ECC_ERR_INT_EN_MSEE) u32 capture_attributes; /**< Memory Error Attributes Capture */ -#define ECC_CAPT_ATTR_BNUM (0xe0000000>>1) /* Data Beat Num */ +#define ECC_CAPT_ATTR_BNUM (0xe0000000>>1) /* Data Beat Num */ #define ECC_CAPT_ATTR_BNUM_SHIFT 28 -#define ECC_CAPT_ATTR_TSIZ (0xc0000000>>6) /* Transaction Size */ +#define ECC_CAPT_ATTR_TSIZ (0xc0000000>>6) /* Transaction Size */ #define ECC_CAPT_ATTR_TSIZ_FOUR_DW 0 #define ECC_CAPT_ATTR_TSIZ_ONE_DW 1 #define ECC_CAPT_ATTR_TSIZ_TWO_DW 2 @@ -738,209 +1081,207 @@ typedef struct ddr8349{ #define ECC_CAPT_ATTR_TTYP_R_M_W 0x3 #define ECC_CAPT_ATTR_TTYP_SHIFT 12 #define ECC_CAPT_ATTR_VLD (0x80000000>>31) /* Valid */ - u32 capture_address; /**< Memory Error Address Capture */ + u32 capture_address; /**< Memory Error Address Capture */ u32 capture_ext_address;/**< Memory Error Extended Address Capture */ - u32 err_sbe; /**< Memory Single-Bit ECC Error Management */ -#define ECC_ERROR_MAN_SBET (0xff000000>>8) /* Single-Bit Error Threshold 0..255*/ + u32 err_sbe; /**< Memory Single-Bit ECC Error Management */ +#define ECC_ERROR_MAN_SBET (0xff000000>>8) /* Single-Bit Error Threshold 0..255 */ #define ECC_ERROR_MAN_SBET_SHIFT 16 -#define ECC_ERROR_MAN_SBEC (0xff000000>>24) /* Single Bit Error Counter 0..255*/ +#define ECC_ERROR_MAN_SBEC (0xff000000>>24) /* Single Bit Error Counter 0..255 */ #define ECC_ERROR_MAN_SBEC_SHIFT 0 u8 res7[0xA4]; u32 debug_reg; u8 res8[0xFC]; -} ddr8349_t; +} ddr83xx_t; /* * I2C1 Controller */ - /* * DUART */ -typedef struct duart8349{ +typedef struct duart83xx { u8 urbr_ulcr_udlb; /**< combined register for URBR, UTHR and UDLB */ - u8 uier_udmb; /**< combined register for UIER and UDMB */ + u8 uier_udmb; /**< combined register for UIER and UDMB */ u8 uiir_ufcr_uafr; /**< combined register for UIIR, UFCR and UAFR */ - u8 ulcr; /**< line control register */ - u8 umcr; /**< MODEM control register */ - u8 ulsr; /**< line status register */ - u8 umsr; /**< MODEM status register */ - u8 uscr; /**< scratch register */ + u8 ulcr; /**< line control register */ + u8 umcr; /**< MODEM control register */ + u8 ulsr; /**< line status register */ + u8 umsr; /**< MODEM status register */ + u8 uscr; /**< scratch register */ u8 res0[8]; - u8 udsr; /**< DMA status register */ + u8 udsr; /**< DMA status register */ u8 res1[3]; u8 res2[0xEC]; -} duart8349_t; +} duart83xx_t; /* * Local Bus Controller Registers */ -typedef struct lbus_bank{ - u32 br; /**< Base Register */ - u32 or; /**< Base Register */ +typedef struct lbus_bank { + u32 br; /**< Base Register */ + u32 or; /**< Base Register */ } lbus_bank_t; -typedef struct lbus8349 { +typedef struct lbus83xx { lbus_bank_t bank[8]; u8 res0[0x28]; - u32 mar; /**< UPM Address Register */ + u32 mar; /**< UPM Address Register */ u8 res1[0x4]; - u32 mamr; /**< UPMA Mode Register */ - u32 mbmr; /**< UPMB Mode Register */ - u32 mcmr; /**< UPMC Mode Register */ + u32 mamr; /**< UPMA Mode Register */ + u32 mbmr; /**< UPMB Mode Register */ + u32 mcmr; /**< UPMC Mode Register */ u8 res2[0x8]; - u32 mrtpr; /**< Memory Refresh Timer Prescaler Register */ - u32 mdr; /**< UPM Data Register */ + u32 mrtpr; /**< Memory Refresh Timer Prescaler Register */ + u32 mdr; /**< UPM Data Register */ u8 res3[0x8]; - u32 lsdmr; /**< SDRAM Mode Register */ + u32 lsdmr; /**< SDRAM Mode Register */ u8 res4[0x8]; - u32 lurt; /**< UPM Refresh Timer */ - u32 lsrt; /**< SDRAM Refresh Timer */ + u32 lurt; /**< UPM Refresh Timer */ + u32 lsrt; /**< SDRAM Refresh Timer */ u8 res5[0x8]; - u32 ltesr; /**< Transfer Error Status Register */ - u32 ltedr; /**< Transfer Error Disable Register */ - u32 lteir; /**< Transfer Error Interrupt Register */ - u32 lteatr; /**< Transfer Error Attributes Register */ - u32 ltear; /**< Transfer Error Address Register */ + u32 ltesr; /**< Transfer Error Status Register */ + u32 ltedr; /**< Transfer Error Disable Register */ + u32 lteir; /**< Transfer Error Interrupt Register */ + u32 lteatr; /**< Transfer Error Attributes Register */ + u32 ltear; /**< Transfer Error Address Register */ u8 res6[0xC]; - u32 lbcr; /**< Configuration Register */ + u32 lbcr; /**< Configuration Register */ #define LBCR_LDIS 0x80000000 -#define LBCR_LDIS_SHIFT 31 +#define LBCR_LDIS_SHIFT 31 #define LBCR_BCTLC 0x00C00000 #define LBCR_BCTLC_SHIFT 22 #define LBCR_LPBSE 0x00020000 #define LBCR_LPBSE_SHIFT 17 #define LBCR_EPAR 0x00010000 -#define LBCR_EPAR_SHIFT 16 +#define LBCR_EPAR_SHIFT 16 #define LBCR_BMT 0x0000FF00 -#define LBCR_BMT_SHIFT 8 - u32 lcrr; /**< Clock Ratio Register */ +#define LBCR_BMT_SHIFT 8 + u32 lcrr; /**< Clock Ratio Register */ #define LCRR_DBYP 0x80000000 -#define LCRR_DBYP_SHIFT 31 +#define LCRR_DBYP_SHIFT 31 #define LCRR_BUFCMDC 0x30000000 #define LCRR_BUFCMDC_SHIFT 28 #define LCRR_ECL 0x03000000 -#define LCRR_ECL_SHIFT 24 +#define LCRR_ECL_SHIFT 24 #define LCRR_EADC 0x00030000 -#define LCRR_EADC_SHIFT 16 +#define LCRR_EADC_SHIFT 16 #define LCRR_CLKDIV 0x0000000F #define LCRR_CLKDIV_SHIFT 0 - u8 res7[0x28]; u8 res8[0xF00]; -} lbus8349_t; +} lbus83xx_t; +#if defined (CONFIG_MPC8349) /* * Serial Peripheral Interface */ -typedef struct spi8349 -{ +typedef struct spi83xx { u32 mode; /**< mode register */ u32 event; /**< event register */ u32 mask; /**< mask register */ u32 com; /**< command register */ u8 res0[0x10]; - u32 tx; /**< transmit register */ - u32 rx; /**< receive register */ + u32 tx; /**< transmit register */ + u32 rx; /**< receive register */ u8 res1[0xD8]; -} spi8349_t; - +} spi83xx_t; +#endif /* * DMA/Messaging Unit */ -typedef struct dma8349 { - u32 res0[0xC]; /* 0x0-0x29 reseverd */ - u32 omisr; /* 0x30 Outbound message interrupt status register */ - u32 omimr; /* 0x34 Outbound message interrupt mask register */ - u32 res1[0x6]; /* 0x38-0x49 reserved */ - - u32 imr0; /* 0x50 Inbound message register 0 */ - u32 imr1; /* 0x54 Inbound message register 1 */ - u32 omr0; /* 0x58 Outbound message register 0 */ - u32 omr1; /* 0x5C Outbound message register 1 */ - - u32 odr; /* 0x60 Outbound doorbell register */ - u32 res2; /* 0x64-0x67 reserved */ - u32 idr; /* 0x68 Inbound doorbell register */ - u32 res3[0x5]; /* 0x6C-0x79 reserved */ - - u32 imisr; /* 0x80 Inbound message interrupt status register */ - u32 imimr; /* 0x84 Inbound message interrupt mask register */ - u32 res4[0x1E]; /* 0x88-0x99 reserved */ - - u32 dmamr0; /* 0x100 DMA 0 mode register */ - u32 dmasr0; /* 0x104 DMA 0 status register */ - u32 dmacdar0; /* 0x108 DMA 0 current descriptor address register */ - u32 res5; /* 0x10C reserved */ - u32 dmasar0; /* 0x110 DMA 0 source address register */ - u32 res6; /* 0x114 reserved */ - u32 dmadar0; /* 0x118 DMA 0 destination address register */ - u32 res7; /* 0x11C reserved */ - u32 dmabcr0; /* 0x120 DMA 0 byte count register */ - u32 dmandar0; /* 0x124 DMA 0 next descriptor address register */ - u32 res8[0x16]; /* 0x128-0x179 reserved */ - - u32 dmamr1; /* 0x180 DMA 1 mode register */ - u32 dmasr1; /* 0x184 DMA 1 status register */ - u32 dmacdar1; /* 0x188 DMA 1 current descriptor address register */ - u32 res9; /* 0x18C reserved */ - u32 dmasar1; /* 0x190 DMA 1 source address register */ - u32 res10; /* 0x194 reserved */ - u32 dmadar1; /* 0x198 DMA 1 destination address register */ - u32 res11; /* 0x19C reserved */ - u32 dmabcr1; /* 0x1A0 DMA 1 byte count register */ - u32 dmandar1; /* 0x1A4 DMA 1 next descriptor address register */ - u32 res12[0x16];/* 0x1A8-0x199 reserved */ - - u32 dmamr2; /* 0x200 DMA 2 mode register */ - u32 dmasr2; /* 0x204 DMA 2 status register */ - u32 dmacdar2; /* 0x208 DMA 2 current descriptor address register */ - u32 res13; /* 0x20C reserved */ - u32 dmasar2; /* 0x210 DMA 2 source address register */ - u32 res14; /* 0x214 reserved */ - u32 dmadar2; /* 0x218 DMA 2 destination address register */ - u32 res15; /* 0x21C reserved */ - u32 dmabcr2; /* 0x220 DMA 2 byte count register */ - u32 dmandar2; /* 0x224 DMA 2 next descriptor address register */ - u32 res16[0x16];/* 0x228-0x279 reserved */ - - u32 dmamr3; /* 0x280 DMA 3 mode register */ - u32 dmasr3; /* 0x284 DMA 3 status register */ - u32 dmacdar3; /* 0x288 DMA 3 current descriptor address register */ - u32 res17; /* 0x28C reserved */ - u32 dmasar3; /* 0x290 DMA 3 source address register */ - u32 res18; /* 0x294 reserved */ - u32 dmadar3; /* 0x298 DMA 3 destination address register */ - u32 res19; /* 0x29C reserved */ - u32 dmabcr3; /* 0x2A0 DMA 3 byte count register */ - u32 dmandar3; /* 0x2A4 DMA 3 next descriptor address register */ - - u32 dmagsr; /* 0x2A8 DMA general status register */ - u32 res20[0x15];/* 0x2AC-0x2FF reserved */ -} dma8349_t; +typedef struct dma83xx { + u32 res0[0xC]; /* 0x0-0x29 reseverd */ + u32 omisr; /* 0x30 Outbound message interrupt status register */ + u32 omimr; /* 0x34 Outbound message interrupt mask register */ + u32 res1[0x6]; /* 0x38-0x49 reserved */ + + u32 imr0; /* 0x50 Inbound message register 0 */ + u32 imr1; /* 0x54 Inbound message register 1 */ + u32 omr0; /* 0x58 Outbound message register 0 */ + u32 omr1; /* 0x5C Outbound message register 1 */ + + u32 odr; /* 0x60 Outbound doorbell register */ + u32 res2; /* 0x64-0x67 reserved */ + u32 idr; /* 0x68 Inbound doorbell register */ + u32 res3[0x5]; /* 0x6C-0x79 reserved */ + + u32 imisr; /* 0x80 Inbound message interrupt status register */ + u32 imimr; /* 0x84 Inbound message interrupt mask register */ + u32 res4[0x1E]; /* 0x88-0x99 reserved */ + + u32 dmamr0; /* 0x100 DMA 0 mode register */ + u32 dmasr0; /* 0x104 DMA 0 status register */ + u32 dmacdar0; /* 0x108 DMA 0 current descriptor address register */ + u32 res5; /* 0x10C reserved */ + u32 dmasar0; /* 0x110 DMA 0 source address register */ + u32 res6; /* 0x114 reserved */ + u32 dmadar0; /* 0x118 DMA 0 destination address register */ + u32 res7; /* 0x11C reserved */ + u32 dmabcr0; /* 0x120 DMA 0 byte count register */ + u32 dmandar0; /* 0x124 DMA 0 next descriptor address register */ + u32 res8[0x16]; /* 0x128-0x179 reserved */ + + u32 dmamr1; /* 0x180 DMA 1 mode register */ + u32 dmasr1; /* 0x184 DMA 1 status register */ + u32 dmacdar1; /* 0x188 DMA 1 current descriptor address register */ + u32 res9; /* 0x18C reserved */ + u32 dmasar1; /* 0x190 DMA 1 source address register */ + u32 res10; /* 0x194 reserved */ + u32 dmadar1; /* 0x198 DMA 1 destination address register */ + u32 res11; /* 0x19C reserved */ + u32 dmabcr1; /* 0x1A0 DMA 1 byte count register */ + u32 dmandar1; /* 0x1A4 DMA 1 next descriptor address register */ + u32 res12[0x16]; /* 0x1A8-0x199 reserved */ + + u32 dmamr2; /* 0x200 DMA 2 mode register */ + u32 dmasr2; /* 0x204 DMA 2 status register */ + u32 dmacdar2; /* 0x208 DMA 2 current descriptor address register */ + u32 res13; /* 0x20C reserved */ + u32 dmasar2; /* 0x210 DMA 2 source address register */ + u32 res14; /* 0x214 reserved */ + u32 dmadar2; /* 0x218 DMA 2 destination address register */ + u32 res15; /* 0x21C reserved */ + u32 dmabcr2; /* 0x220 DMA 2 byte count register */ + u32 dmandar2; /* 0x224 DMA 2 next descriptor address register */ + u32 res16[0x16]; /* 0x228-0x279 reserved */ + + u32 dmamr3; /* 0x280 DMA 3 mode register */ + u32 dmasr3; /* 0x284 DMA 3 status register */ + u32 dmacdar3; /* 0x288 DMA 3 current descriptor address register */ + u32 res17; /* 0x28C reserved */ + u32 dmasar3; /* 0x290 DMA 3 source address register */ + u32 res18; /* 0x294 reserved */ + u32 dmadar3; /* 0x298 DMA 3 destination address register */ + u32 res19; /* 0x29C reserved */ + u32 dmabcr3; /* 0x2A0 DMA 3 byte count register */ + u32 dmandar3; /* 0x2A4 DMA 3 next descriptor address register */ + + u32 dmagsr; /* 0x2A8 DMA general status register */ + u32 res20[0x15]; /* 0x2AC-0x2FF reserved */ +} dma83xx_t; /* DMAMRn bits */ -#define DMA_CHANNEL_START (0x00000001) /* Bit - DMAMRn CS */ -#define DMA_CHANNEL_TRANSFER_MODE_DIRECT (0x00000004) /* Bit - DMAMRn CTM */ -#define DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN (0x00001000) /* Bit - DMAMRn SAHE */ -#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_1B (0x00000000) /* 2Bit- DMAMRn SAHTS 1byte */ -#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_2B (0x00004000) /* 2Bit- DMAMRn SAHTS 2bytes */ -#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_4B (0x00008000) /* 2Bit- DMAMRn SAHTS 4bytes */ -#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B (0x0000c000) /* 2Bit- DMAMRn SAHTS 8bytes */ -#define DMA_CHANNEL_SNOOP (0x00010000) /* Bit - DMAMRn DMSEN */ +#define DMA_CHANNEL_START (0x00000001) /* Bit - DMAMRn CS */ +#define DMA_CHANNEL_TRANSFER_MODE_DIRECT (0x00000004) /* Bit - DMAMRn CTM */ +#define DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN (0x00001000) /* Bit - DMAMRn SAHE */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_1B (0x00000000) /* 2Bit- DMAMRn SAHTS 1byte */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_2B (0x00004000) /* 2Bit- DMAMRn SAHTS 2bytes */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_4B (0x00008000) /* 2Bit- DMAMRn SAHTS 4bytes */ +#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B (0x0000c000) /* 2Bit- DMAMRn SAHTS 8bytes */ +#define DMA_CHANNEL_SNOOP (0x00010000) /* Bit - DMAMRn DMSEN */ /* DMASRn bits */ -#define DMA_CHANNEL_BUSY (0x00000004) /* Bit - DMASRn CB */ -#define DMA_CHANNEL_TRANSFER_ERROR (0x00000080) /* Bit - DMASRn TE */ +#define DMA_CHANNEL_BUSY (0x00000004) /* Bit - DMASRn CB */ +#define DMA_CHANNEL_TRANSFER_ERROR (0x00000080) /* Bit - DMASRn TE */ /* * PCI Software Configuration Registers */ -typedef struct pciconf8349 { - u32 config_address; +typedef struct pciconf83xx { + u32 config_address; #define PCI_CONFIG_ADDRESS_EN 0x80000000 #define PCI_CONFIG_ADDRESS_BN_SHIFT 16 #define PCI_CONFIG_ADDRESS_BN_MASK 0x00ff0000 @@ -952,235 +1293,788 @@ typedef struct pciconf8349 { #define PCI_CONFIG_ADDRESS_RN_MASK 0x000000fc u32 config_data; u32 int_ack; - u8 res[116]; -} pciconf8349_t; + u8 res[116]; +} pciconf83xx_t; /* * PCI Outbound Translation Register */ typedef struct pci_outbound_window { - u32 potar; - u8 res0[4]; - u32 pobar; - u8 res1[4]; - u32 pocmr; - u8 res2[4]; -} pot8349_t; + u32 potar; + u8 res0[4]; + u32 pobar; + u8 res1[4]; + u32 pocmr; + u8 res2[4]; +} pot83xx_t; + /* * Sequencer */ -typedef struct ios8349 { - pot8349_t pot[6]; +typedef struct ios83xx { + pot83xx_t pot[6]; #define POTAR_TA_MASK 0x000fffff -#define POBAR_BA_MASK 0x000fffff -#define POCMR_EN 0x80000000 -#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */ -#define POCMR_SE 0x20000000 /* streaming enable */ -#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2*/ -#define POCMR_CM_MASK 0x000fffff -#define POCMR_CM_4G 0x00000000 -#define POCMR_CM_2G 0x00080000 -#define POCMR_CM_1G 0x000C0000 -#define POCMR_CM_512M 0x000E0000 -#define POCMR_CM_256M 0x000F0000 -#define POCMR_CM_128M 0x000F8000 -#define POCMR_CM_64M 0x000FC000 -#define POCMR_CM_32M 0x000FE000 -#define POCMR_CM_16M 0x000FF000 -#define POCMR_CM_8M 0x000FF800 -#define POCMR_CM_4M 0x000FFC00 -#define POCMR_CM_2M 0x000FFE00 -#define POCMR_CM_1M 0x000FFF00 -#define POCMR_CM_512K 0x000FFF80 -#define POCMR_CM_256K 0x000FFFC0 -#define POCMR_CM_128K 0x000FFFE0 -#define POCMR_CM_64K 0x000FFFF0 -#define POCMR_CM_32K 0x000FFFF8 -#define POCMR_CM_16K 0x000FFFFC -#define POCMR_CM_8K 0x000FFFFE -#define POCMR_CM_4K 0x000FFFFF - u8 res0[0x60]; - u32 pmcr; - u8 res1[4]; - u32 dtcr; - u8 res2[4]; -} ios8349_t; +#define POBAR_BA_MASK 0x000fffff +#define POCMR_EN 0x80000000 +#define POCMR_IO 0x40000000 /* 0--memory space 1--I/O space */ +#define POCMR_SE 0x20000000 /* streaming enable */ +#define POCMR_DST 0x10000000 /* 0--PCI1 1--PCI2 */ +#define POCMR_CM_MASK 0x000fffff +#define POCMR_CM_4G 0x00000000 +#define POCMR_CM_2G 0x00080000 +#define POCMR_CM_1G 0x000C0000 +#define POCMR_CM_512M 0x000E0000 +#define POCMR_CM_256M 0x000F0000 +#define POCMR_CM_128M 0x000F8000 +#define POCMR_CM_64M 0x000FC000 +#define POCMR_CM_32M 0x000FE000 +#define POCMR_CM_16M 0x000FF000 +#define POCMR_CM_8M 0x000FF800 +#define POCMR_CM_4M 0x000FFC00 +#define POCMR_CM_2M 0x000FFE00 +#define POCMR_CM_1M 0x000FFF00 +#define POCMR_CM_512K 0x000FFF80 +#define POCMR_CM_256K 0x000FFFC0 +#define POCMR_CM_128K 0x000FFFE0 +#define POCMR_CM_64K 0x000FFFF0 +#define POCMR_CM_32K 0x000FFFF8 +#define POCMR_CM_16K 0x000FFFFC +#define POCMR_CM_8K 0x000FFFFE +#define POCMR_CM_4K 0x000FFFFF + u8 res0[0x60]; + u32 pmcr; + u8 res1[4]; + u32 dtcr; + u8 res2[4]; +} ios83xx_t; /* * PCI Controller Control and Status Registers */ -typedef struct pcictrl8349 { - u32 esr; +typedef struct pcictrl83xx { + u32 esr; #define ESR_MERR 0x80000000 #define ESR_APAR 0x00000400 -#define ESR_PCISERR 0x00000200 -#define ESR_MPERR 0x00000100 -#define ESR_TPERR 0x00000080 -#define ESR_NORSP 0x00000040 -#define ESR_TABT 0x00000020 - u32 ecdr; +#define ESR_PCISERR 0x00000200 +#define ESR_MPERR 0x00000100 +#define ESR_TPERR 0x00000080 +#define ESR_NORSP 0x00000040 +#define ESR_TABT 0x00000020 + u32 ecdr; #define ECDR_APAR 0x00000400 -#define ECDR_PCISERR 0x00000200 -#define ECDR_MPERR 0x00000100 -#define ECDR_TPERR 0x00000080 -#define ECDR_NORSP 0x00000040 -#define ECDR_TABT 0x00000020 +#define ECDR_PCISERR 0x00000200 +#define ECDR_MPERR 0x00000100 +#define ECDR_TPERR 0x00000080 +#define ECDR_NORSP 0x00000040 +#define ECDR_TABT 0x00000020 u32 eer; #define EER_APAR 0x00000400 -#define EER_PCISERR 0x00000200 -#define EER_MPERR 0x00000100 -#define EER_TPERR 0x00000080 -#define EER_NORSP 0x00000040 -#define EER_TABT 0x00000020 - u32 eatcr; -#define EATCR_ERRTYPR_MASK 0x70000000 -#define EATCR_ERRTYPR_APR 0x00000000 /* address parity error */ -#define EATCR_ERRTYPR_WDPR 0x10000000 /* write data parity error */ -#define EATCR_ERRTYPR_RDPR 0x20000000 /* read data parity error */ -#define EATCR_ERRTYPR_MA 0x30000000 /* master abort */ -#define EATCR_ERRTYPR_TA 0x40000000 /* target abort */ -#define EATCR_ERRTYPR_SE 0x50000000 /* system error indication received */ -#define EATCR_ERRTYPR_PEA 0x60000000 /* parity error indication received on a read */ -#define EATCR_ERRTYPR_PEW 0x70000000 /* parity error indication received on a write */ +#define EER_PCISERR 0x00000200 +#define EER_MPERR 0x00000100 +#define EER_TPERR 0x00000080 +#define EER_NORSP 0x00000040 +#define EER_TABT 0x00000020 + u32 eatcr; +#define EATCR_ERRTYPR_MASK 0x70000000 +#define EATCR_ERRTYPR_APR 0x00000000 /* address parity error */ +#define EATCR_ERRTYPR_WDPR 0x10000000 /* write data parity error */ +#define EATCR_ERRTYPR_RDPR 0x20000000 /* read data parity error */ +#define EATCR_ERRTYPR_MA 0x30000000 /* master abort */ +#define EATCR_ERRTYPR_TA 0x40000000 /* target abort */ +#define EATCR_ERRTYPR_SE 0x50000000 /* system error indication received */ +#define EATCR_ERRTYPR_PEA 0x60000000 /* parity error indication received on a read */ +#define EATCR_ERRTYPR_PEW 0x70000000 /* parity error indication received on a write */ #define EATCR_BN_MASK 0x0f000000 /* beat number */ -#define EATCR_BN_1st 0x00000000 -#define EATCR_BN_2ed 0x01000000 -#define EATCR_BN_3rd 0x02000000 -#define EATCR_BN_4th 0x03000000 -#define EATCR_BN_5th 0x0400000 -#define EATCR_BN_6th 0x05000000 -#define EATCR_BN_7th 0x06000000 -#define EATCR_BN_8th 0x07000000 -#define EATCR_BN_9th 0x08000000 +#define EATCR_BN_1st 0x00000000 +#define EATCR_BN_2ed 0x01000000 +#define EATCR_BN_3rd 0x02000000 +#define EATCR_BN_4th 0x03000000 +#define EATCR_BN_5th 0x0400000 +#define EATCR_BN_6th 0x05000000 +#define EATCR_BN_7th 0x06000000 +#define EATCR_BN_8th 0x07000000 +#define EATCR_BN_9th 0x08000000 #define EATCR_TS_MASK 0x00300000 /* transaction size */ -#define EATCR_TS_4 0x00000000 -#define EATCR_TS_1 0x00100000 -#define EATCR_TS_2 0x00200000 -#define EATCR_TS_3 0x00300000 -#define EATCR_ES_MASK 0x000f0000 /* error source */ -#define EATCR_ES_EM 0x00000000 /* external master */ -#define EATCR_ES_DMA 0x00050000 -#define EATCR_CMD_MASK 0x0000f000 -#define EATCR_HBE_MASK 0x00000f00 /* PCI high byte enable*/ -#define EATCR_BE_MASK 0x000000f0 /* PCI byte enable */ -#define EATCR_HPB 0x00000004 /* high parity bit */ -#define EATCR_PB 0x00000002 /* parity bit*/ -#define EATCR_VI 0x00000001 /* error information valid */ - u32 eacr; - u32 eeacr; - u32 edlcr; - u32 edhcr; - u32 gcr; - u32 ecr; - u32 gsr; - u8 res0[12]; - u32 pitar2; - u8 res1[4]; - u32 pibar2; - u32 piebar2; - u32 piwar2; - u8 res2[4]; - u32 pitar1; - u8 res3[4]; - u32 pibar1; - u32 piebar1; - u32 piwar1; - u8 res4[4]; - u32 pitar0; - u8 res5[4]; - u32 pibar0; - u8 res6[4]; - u32 piwar0; - u8 res7[132]; +#define EATCR_TS_4 0x00000000 +#define EATCR_TS_1 0x00100000 +#define EATCR_TS_2 0x00200000 +#define EATCR_TS_3 0x00300000 +#define EATCR_ES_MASK 0x000f0000 /* error source */ +#define EATCR_ES_EM 0x00000000 /* external master */ +#define EATCR_ES_DMA 0x00050000 +#define EATCR_CMD_MASK 0x0000f000 +#if defined (CONFIG_MPC8349) +#define EATCR_HBE_MASK 0x00000f00 /* PCI high byte enable */ +#endif +#define EATCR_BE_MASK 0x000000f0 /* PCI byte enable */ +#if defined (CONFIG_MPC8349) +#define EATCR_HPB 0x00000004 /* high parity bit */ +#endif +#define EATCR_PB 0x00000002 /* parity bit */ +#define EATCR_VI 0x00000001 /* error information valid */ + u32 eacr; + u32 eeacr; +#if defined (CONFIG_MPC8349) + u32 edlcr; + u32 edhcr; +#elif defined (CONFIG_MPC8360) + u32 edcr; /* was edlcr */ + u8 res_edcr[0x4]; +#endif + u32 gcr; + u32 ecr; + u32 gsr; + u8 res0[12]; + u32 pitar2; + u8 res1[4]; + u32 pibar2; + u32 piebar2; + u32 piwar2; + u8 res2[4]; + u32 pitar1; + u8 res3[4]; + u32 pibar1; + u32 piebar1; + u32 piwar1; + u8 res4[4]; + u32 pitar0; + u8 res5[4]; + u32 pibar0; + u8 res6[4]; + u32 piwar0; + u8 res7[132]; #define PITAR_TA_MASK 0x000fffff #define PIBAR_MASK 0xffffffff #define PIEBAR_EBA_MASK 0x000fffff #define PIWAR_EN 0x80000000 #define PIWAR_PF 0x20000000 -#define PIWAR_RTT_MASK 0x000f0000 -#define PIWAR_RTT_NO_SNOOP 0x00040000 +#define PIWAR_RTT_MASK 0x000f0000 +#define PIWAR_RTT_NO_SNOOP 0x00040000 #define PIWAR_RTT_SNOOP 0x00050000 -#define PIWAR_WTT_MASK 0x0000f000 -#define PIWAR_WTT_NO_SNOOP 0x00004000 +#define PIWAR_WTT_MASK 0x0000f000 +#define PIWAR_WTT_NO_SNOOP 0x00004000 #define PIWAR_WTT_SNOOP 0x00005000 -#define PIWAR_IWS_MASK 0x0000003F -#define PIWAR_IWS_4K 0x0000000B -#define PIWAR_IWS_8K 0x0000000C -#define PIWAR_IWS_16K 0x0000000D -#define PIWAR_IWS_32K 0x0000000E -#define PIWAR_IWS_64K 0x0000000F -#define PIWAR_IWS_128K 0x00000010 -#define PIWAR_IWS_256K 0x00000011 -#define PIWAR_IWS_512K 0x00000012 -#define PIWAR_IWS_1M 0x00000013 -#define PIWAR_IWS_2M 0x00000014 -#define PIWAR_IWS_4M 0x00000015 -#define PIWAR_IWS_8M 0x00000016 -#define PIWAR_IWS_16M 0x00000017 -#define PIWAR_IWS_32M 0x00000018 -#define PIWAR_IWS_64M 0x00000019 -#define PIWAR_IWS_128M 0x0000001A -#define PIWAR_IWS_256M 0x0000001B -#define PIWAR_IWS_512M 0x0000001C -#define PIWAR_IWS_1G 0x0000001D -#define PIWAR_IWS_2G 0x0000001E -} pcictrl8349_t; +#define PIWAR_IWS_MASK 0x0000003F +#define PIWAR_IWS_4K 0x0000000B +#define PIWAR_IWS_8K 0x0000000C +#define PIWAR_IWS_16K 0x0000000D +#define PIWAR_IWS_32K 0x0000000E +#define PIWAR_IWS_64K 0x0000000F +#define PIWAR_IWS_128K 0x00000010 +#define PIWAR_IWS_256K 0x00000011 +#define PIWAR_IWS_512K 0x00000012 +#define PIWAR_IWS_1M 0x00000013 +#define PIWAR_IWS_2M 0x00000014 +#define PIWAR_IWS_4M 0x00000015 +#define PIWAR_IWS_8M 0x00000016 +#define PIWAR_IWS_16M 0x00000017 +#define PIWAR_IWS_32M 0x00000018 +#define PIWAR_IWS_64M 0x00000019 +#define PIWAR_IWS_128M 0x0000001A +#define PIWAR_IWS_256M 0x0000001B +#define PIWAR_IWS_512M 0x0000001C +#define PIWAR_IWS_1G 0x0000001D +#define PIWAR_IWS_2G 0x0000001E +} pcictrl83xx_t; +#if defined (CONFIG_MPC8349) /* * USB */ -typedef struct usb8349 { +typedef struct usb83xx { u8 fixme[0x2000]; -} usb8349_t; +} usb83xx_t; /* * TSEC */ -typedef struct tsec8349 { +typedef struct tsec83xx { u8 fixme[0x1000]; -} tsec8349_t; +} tsec83xx_t; +#endif /* * Security */ -typedef struct security8349 { +typedef struct security83xx { u8 fixme[0x10000]; -} security8349_t; +} security83xx_t; + +#if defined (CONFIG_MPC8360) +/* + * iram + */ +typedef struct iram83xx { + u32 iadd; /* I-RAM address register */ + u32 idata; /* I-RAM data register */ + u8 res0[0x78]; +} iram83xx_t; + +/* + * Interrupt Controller + */ +typedef struct irq83xx { + u32 cicr; /* QE system interrupt configuration */ + u32 civec; /* QE system interrupt vector register */ + u32 cripnr; /* QE RISC interrupt pending register */ + u32 cipnr; /* QE system interrupt pending register */ + u32 cipxcc; /* QE interrupt priority register */ + u32 cipycc; /* QE interrupt priority register */ + u32 cipwcc; /* QE interrupt priority register */ + u32 cipzcc; /* QE interrupt priority register */ + u32 cimr; /* QE system interrupt mask register */ + u32 crimr; /* QE RISC interrupt mask register */ + u32 cicnr; /* QE system interrupt control register */ + u8 res0[0x4]; + u32 ciprta; /* QE system interrupt priority register for RISC tasks A */ + u32 ciprtb; /* QE system interrupt priority register for RISC tasks B */ + u8 res1[0x4]; + u32 cricr; /* QE system RISC interrupt control */ + u8 res2[0x20]; + u32 chivec; /* QE high system interrupt vector */ + u8 res3[0x1C]; +} irq83xx_t; + +/* + * Communications Processor + */ +typedef struct cp83xx { + u32 cecr; /* QE command register */ + u32 ceccr; /* QE controller configuration register */ + u32 cecdr; /* QE command data register */ + u8 res0[0xA]; + u16 ceter; /* QE timer event register */ + u8 res1[0x2]; + u16 cetmr; /* QE timers mask register */ + u32 cetscr; /* QE time-stamp timer control register */ + u32 cetsr1; /* QE time-stamp register 1 */ + u32 cetsr2; /* QE time-stamp register 2 */ + u8 res2[0x8]; + u32 cevter; /* QE virtual tasks event register */ + u32 cevtmr; /* QE virtual tasks mask register */ + u16 cercr; /* QE RAM control register */ + u8 res3[0x2]; + u8 res4[0x24]; + u16 ceexe1; /* QE external request 1 event register */ + u8 res5[0x2]; + u16 ceexm1; /* QE external request 1 mask register */ + u8 res6[0x2]; + u16 ceexe2; /* QE external request 2 event register */ + u8 res7[0x2]; + u16 ceexm2; /* QE external request 2 mask register */ + u8 res8[0x2]; + u16 ceexe3; /* QE external request 3 event register */ + u8 res9[0x2]; + u16 ceexm3; /* QE external request 3 mask register */ + u8 res10[0x2]; + u16 ceexe4; /* QE external request 4 event register */ + u8 res11[0x2]; + u16 ceexm4; /* QE external request 4 mask register */ + u8 res12[0x2]; + u8 res13[0x280]; +} cp83xx_t; + +/* + * QE Multiplexer + */ + +typedef struct qmx83xx { + u32 cmxgcr; /* CMX general clock route register */ + u32 cmxsi1cr_l; /* CMX SI1 clock route low register */ + u32 cmxsi1cr_h; /* CMX SI1 clock route high register */ + u32 cmxsi1syr; /* CMX SI1 SYNC route register */ + u32 cmxucr1; /* CMX UCC1, UCC3 clock route register */ + u32 cmxucr2; /* CMX UCC5, UCC7 clock route register */ + u32 cmxucr3; /* CMX UCC2, UCC4 clock route register */ + u32 cmxucr4; /* CMX UCC6, UCC8 clock route register */ + u32 cmxupcr; /* CMX UPC clock route register */ + u8 res0[0x1C]; +} qmx83xx_t; + +/* +* QE Timers +*/ + +typedef struct qet83xx { + u8 gtcfr1; /* Timer 1 and Timer 2 global configuration register */ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3 and timer 4 global configuration register */ + u8 res1[0xB]; + u16 gtmdr1; /* Timer 1 mode register */ + u16 gtmdr2; /* Timer 2 mode register */ + u16 gtrfr1; /* Timer 1 reference register */ + u16 gtrfr2; /* Timer 2 reference register */ + u16 gtcpr1; /* Timer 1 capture register */ + u16 gtcpr2; /* Timer 2 capture register */ + u16 gtcnr1; /* Timer 1 counter */ + u16 gtcnr2; /* Timer 2 counter */ + u16 gtmdr3; /* Timer 3 mode register */ + u16 gtmdr4; /* Timer 4 mode register */ + u16 gtrfr3; /* Timer 3 reference register */ + u16 gtrfr4; /* Timer 4 reference register */ + u16 gtcpr3; /* Timer 3 capture register */ + u16 gtcpr4; /* Timer 4 capture register */ + u16 gtcnr3; /* Timer 3 counter */ + u16 gtcnr4; /* Timer 4 counter */ + u16 gtevr1; /* Timer 1 event register */ + u16 gtevr2; /* Timer 2 event register */ + u16 gtevr3; /* Timer 3 event register */ + u16 gtevr4; /* Timer 4 event register */ + u16 gtps; /* Timer 1 prescale register */ + u8 res2[0x46]; +} qet83xx_t; + +/* +* spi +*/ + +typedef struct spi83xx { + u8 res0[0x20]; + u32 spmode; /* SPI mode register */ + u8 res1[0x2]; + u8 spie; /* SPI event register */ + u8 res2[0x1]; + u8 res3[0x2]; + u8 spim; /* SPI mask register */ + u8 res4[0x1]; + u8 res5[0x1]; + u8 spcom; /* SPI command register */ + u8 res6[0x2]; + u32 spitd; /* SPI transmit data register (cpu mode) */ + u32 spird; /* SPI receive data register (cpu mode) */ + u8 res7[0x8]; +} spi83xx_t; + +/* +* mcc +*/ + +typedef struct mcc83xx { + u32 mcce; /* MCC event register */ + u32 mccm; /* MCC mask register */ + u32 mccf; /* MCC configuration register */ + u32 merl; /* MCC emergency request level register */ + u8 res0[0xF0]; +} mcc83xx_t; + +/* +* brg +*/ + +typedef struct brg83xx { + u32 brgc1; /* BRG1 configuration register */ + u32 brgc2; /* BRG2 configuration register */ + u32 brgc3; /* BRG3 configuration register */ + u32 brgc4; /* BRG4 configuration register */ + u32 brgc5; /* BRG5 configuration register */ + u32 brgc6; /* BRG6 configuration register */ + u32 brgc7; /* BRG7 configuration register */ + u32 brgc8; /* BRG8 configuration register */ + u32 brgc9; /* BRG9 configuration register */ + u32 brgc10; /* BRG10 configuration register */ + u32 brgc11; /* BRG11 configuration register */ + u32 brgc12; /* BRG12 configuration register */ + u32 brgc13; /* BRG13 configuration register */ + u32 brgc14; /* BRG14 configuration register */ + u32 brgc15; /* BRG15 configuration register */ + u32 brgc16; /* BRG16 configuration register */ + u8 res0[0x40]; +} brg83xx_t; + +/* +* USB +*/ + +typedef struct usb83xx { + u8 usmod; /* USB mode register */ + u8 usadd; /* USB address register */ + u8 uscom; /* USB command register */ + u8 res0[0x1]; + u16 usep0; /* USB endpoint register 0 */ + u16 usep1; /* USB endpoint register 1 */ + u16 usep2; /* USB endpoint register 2 */ + u16 usep3; /* USB endpoint register 3 */ + u8 res1[0x4]; + u16 usber; /* USB event register */ + u8 res2[0x2]; + u16 usbmr; /* USB mask register */ + u8 res3[0x1]; + u8 usbs; /* USB status register */ + u32 ussft; /* USB start of frame timer */ + u8 res4[0x24]; +} usb83xx_t; + +/* +* SI +*/ + +typedef struct si1_83xx { + u16 siamr1; /* SI1 TDMA mode register */ + u16 sibmr1; /* SI1 TDMB mode register */ + u16 sicmr1; /* SI1 TDMC mode register */ + u16 sidmr1; /* SI1 TDMD mode register */ + u8 siglmr1_h; /* SI1 global mode register high */ + u8 res0[0x1]; + u8 sicmdr1_h; /* SI1 command register high */ + u8 res2[0x1]; + u8 sistr1_h; /* SI1 status register high */ + u8 res3[0x1]; + u16 sirsr1_h; /* SI1 RAM shadow address register high */ + u8 sitarc1; /* SI1 RAM counter Tx TDMA */ + u8 sitbrc1; /* SI1 RAM counter Tx TDMB */ + u8 sitcrc1; /* SI1 RAM counter Tx TDMC */ + u8 sitdrc1; /* SI1 RAM counter Tx TDMD */ + u8 sirarc1; /* SI1 RAM counter Rx TDMA */ + u8 sirbrc1; /* SI1 RAM counter Rx TDMB */ + u8 sircrc1; /* SI1 RAM counter Rx TDMC */ + u8 sirdrc1; /* SI1 RAM counter Rx TDMD */ + u8 res4[0x8]; + u16 siemr1; /* SI1 TDME mode register 16 bits */ + u16 sifmr1; /* SI1 TDMF mode register 16 bits */ + u16 sigmr1; /* SI1 TDMG mode register 16 bits */ + u16 sihmr1; /* SI1 TDMH mode register 16 bits */ + u8 siglmg1_l; /* SI1 global mode register low 8 bits */ + u8 res5[0x1]; + u8 sicmdr1_l; /* SI1 command register low 8 bits */ + u8 res6[0x1]; + u8 sistr1_l; /* SI1 status register low 8 bits */ + u8 res7[0x1]; + u16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits */ + u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */ + u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */ + u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */ + u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */ + u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */ + u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */ + u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */ + u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */ + u8 res8[0x8]; + u32 siml1; /* SI1 multiframe limit register */ + u8 siedm1; /* SI1 extended diagnostic mode register */ + u8 res9[0xBB]; +} si1_83xx_t; + +/* +* SI Routing Tables +*/ + +typedef struct sir83xx { + u8 tx[0x400]; + u8 rx[0x400]; + u8 res0[0x800]; +} sir83xx_t; + +/* +* ucc +*/ + +typedef struct uslow { + u32 gumr_l; /* UCCx general mode register (low) */ + u32 gumr_h; /* UCCx general mode register (high) */ + u16 upsmr; /* UCCx protocol-specific mode register */ + u8 res0[0x2]; + u16 utodr; /* UCCx transmit on demand register */ + u16 udsr; /* UCCx data synchronization register */ + u16 ucce; /* UCCx event register */ + u8 res1[0x2]; + u16 uccm; /* UCCx mask register */ + u8 res2[0x1]; + u8 uccs; /* UCCx status register */ + u8 res3[0x1E8]; +} uslow_t; + +typedef struct ufast { + u32 gumr; /* UCCx general mode register */ + u32 upsmr; /* UCCx protocol-specific mode register */ + u16 utodr; /* UCCx transmit on demand register */ + u8 res0[0x2]; + u16 udsr; /* UCCx data synchronization register */ + u8 res1[0x2]; + u32 ucce; /* UCCx event register */ + u32 uccm; /* UCCx mask register. */ + u8 uccs; /* UCCx status register */ + u8 res2[0x7]; + u32 urfb; /* UCC receive FIFO base */ + u16 urfs; /* UCC receive FIFO size */ + u8 res3[0x2]; + u16 urfet; /* UCC receive FIFO emergency threshold */ + u16 urfset; /* UCC receive FIFO special emergency threshold */ + u32 utfb; /* UCC transmit FIFO base */ + u16 utfs; /* UCC transmit FIFO size */ + u8 res4[0x2]; + u16 utfet; /* UCC transmit FIFO emergency threshold */ + u8 res5[0x2]; + u16 utftt; /* UCC transmit FIFO transmit threshold */ + u8 res6[0x2]; + u16 utpt; /* UCC transmit polling timer */ + u32 urtry; /* UCC retry counter register */ + u8 res7[0x4C]; + u8 guemr; /* UCC general extended mode register */ + u8 res8[0x3]; + u8 res9[0x6C]; + u32 maccfg1; /* Mac configuration register #1 */ + u32 maccfg2; /* Mac configuration register #2 */ + u16 ipgifg; /* Interframe gap register */ + u8 res10[0x2]; + u32 hafdup; /* Half-duplex register */ + u8 res11[0xC]; + u32 emtr; /* Ethernet MAC test register */ + u32 miimcfg; /* MII mgmt configuration register */ + u32 miimcom; /* MII mgmt command register */ + u32 miimadd; /* MII mgmt address register */ + u32 miimcon; /* MII mgmt control register */ + u32 miistat; /* MII mgmt status register */ + u32 miimnd; /* MII mgmt indication register */ + u32 ifctl; /* Interface control register */ + u32 ifstat; /* Interface status register */ + u32 macstnaddr1; /* Station address part 1 register */ + u32 macstnaddr2; /* Station address part 2 register */ + u8 res12[0x8]; + u32 uempr; /* UCC Ethernet MAC parameter register */ + u32 utbipa; /* UCC TBI address */ + u16 uescr; /* UCC Ethernet statistics control register */ + u8 res13[0x26]; + u32 tx64; /* Transmit and receive 64-byte frame counter */ + u32 tx127; /* Transmit and receive 65- to 127-byte frame counter */ + u32 tx255; /* Transmit and receive 128- to 255-byte frame counter */ + u32 rx64; /* Receive and receive 64-byte frame counter */ + u32 rx127; /* Receive and receive 65- to 127-byte frame counter */ + u32 rx255; /* Receive and receive 128- to 255-byte frame counter */ + u32 txok; /* Transmit good bytes counter */ + u32 txcf; /* Transmit control frame counter */ + u32 tmca; /* Transmit multicast control frame counter */ + u32 tbca; /* Transmit broadcast packet counter */ + u32 rxfok; /* Receive frame OK counter */ + u32 rbyt; /* Receive good and bad bytes counter */ + u32 rxbok; /* Receive bytes OK counter */ + u32 rmca; /* Receive multicast packet counter */ + u32 rbca; /* Receive broadcast packet counter */ + u32 scar; /* Statistics carry register */ + u32 scam; /* Statistics carry mask register */ + u8 res14[0x3C]; +} ufast_t; + +typedef struct ucc83xx { + union { + uslow_t slow; + ufast_t fast; + }; +} ucc83xx_t; + +/* +* MultiPHY UTOPIA POS Controllers +*/ + +typedef struct upc83xx { + u32 upgcr; /* UTOPIA/POS general configuration register */ +#define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ +#define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ +#define UPGCR_RMS 0x20000000 /* Receive master/slave mode */ +#define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing: */ +#define UPGCR_DIAG 0x01000000 /* Diagnostic mode */ + u32 uplpa; /* UTOPIA/POS last PHY address */ + u32 uphec; /* ATM HEC register */ + u32 upuc; /* UTOPIA/POS UCC configuration */ + u32 updc1; /* UTOPIA/POS device 1 configuration */ + u32 updc2; /* UTOPIA/POS device 2 configuration */ + u32 updc3; /* UTOPIA/POS device 3 configuration */ + u32 updc4; /* UTOPIA/POS device 4 configuration */ + u32 upstpa; /* UTOPIA/POS STPA threshold */ + u8 res0[0xC]; + u32 updrs1_h; /* UTOPIA/POS device 1 rate select */ + u32 updrs1_l; /* UTOPIA/POS device 1 rate select */ + u32 updrs2_h; /* UTOPIA/POS device 2 rate select */ + u32 updrs2_l; /* UTOPIA/POS device 2 rate select */ + u32 updrs3_h; /* UTOPIA/POS device 3 rate select */ + u32 updrs3_l; /* UTOPIA/POS device 3 rate select */ + u32 updrs4_h; /* UTOPIA/POS device 4 rate select */ + u32 updrs4_l; /* UTOPIA/POS device 4 rate select */ + u32 updrp1; /* UTOPIA/POS device 1 receive priority low */ + u32 updrp2; /* UTOPIA/POS device 2 receive priority low */ + u32 updrp3; /* UTOPIA/POS device 3 receive priority low */ + u32 updrp4; /* UTOPIA/POS device 4 receive priority low */ + u32 upde1; /* UTOPIA/POS device 1 event */ + u32 upde2; /* UTOPIA/POS device 2 event */ + u32 upde3; /* UTOPIA/POS device 3 event */ + u32 upde4; /* UTOPIA/POS device 4 event */ + u16 uprp1; + u16 uprp2; + u16 uprp3; + u16 uprp4; + u8 res1[0x8]; + u16 uptirr1_0; /* Device 1 transmit internal rate 0 */ + u16 uptirr1_1; /* Device 1 transmit internal rate 1 */ + u16 uptirr1_2; /* Device 1 transmit internal rate 2 */ + u16 uptirr1_3; /* Device 1 transmit internal rate 3 */ + u16 uptirr2_0; /* Device 2 transmit internal rate 0 */ + u16 uptirr2_1; /* Device 2 transmit internal rate 1 */ + u16 uptirr2_2; /* Device 2 transmit internal rate 2 */ + u16 uptirr2_3; /* Device 2 transmit internal rate 3 */ + u16 uptirr3_0; /* Device 3 transmit internal rate 0 */ + u16 uptirr3_1; /* Device 3 transmit internal rate 1 */ + u16 uptirr3_2; /* Device 3 transmit internal rate 2 */ + u16 uptirr3_3; /* Device 3 transmit internal rate 3 */ + u16 uptirr4_0; /* Device 4 transmit internal rate 0 */ + u16 uptirr4_1; /* Device 4 transmit internal rate 1 */ + u16 uptirr4_2; /* Device 4 transmit internal rate 2 */ + u16 uptirr4_3; /* Device 4 transmit internal rate 3 */ + u32 uper1; /* Device 1 port enable register */ + u32 uper2; /* Device 2 port enable register */ + u32 uper3; /* Device 3 port enable register */ + u32 uper4; /* Device 4 port enable register */ + u8 res2[0x150]; +} upc83xx_t; + +/* +* SDMA +*/ + +typedef struct sdma83xx { + u32 sdsr; /* Serial DMA status register */ + u32 sdmr; /* Serial DMA mode register */ + u32 sdtr1; /* SDMA system bus threshold register */ + u32 sdtr2; /* SDMA secondary bus threshold register */ + u32 sdhy1; /* SDMA system bus hysteresis register */ + u32 sdhy2; /* SDMA secondary bus hysteresis register */ + u32 sdta1; /* SDMA system bus address register */ + u32 sdta2; /* SDMA secondary bus address register */ + u32 sdtm1; /* SDMA system bus MSNUM register */ + u32 sdtm2; /* SDMA secondary bus MSNUM register */ + u8 res0[0x10]; + u32 sdaqr; /* SDMA address bus qualify register */ + u32 sdaqmr; /* SDMA address bus qualify mask register */ + u8 res1[0x4]; + u32 sdwbcr; /* SDMA CAM entries base register */ + u8 res2[0x38]; +} sdma83xx_t; + +/* +* Debug Space +*/ + +typedef struct dbg83xx { + u32 bpdcr; /* Breakpoint debug command register */ + u32 bpdsr; /* Breakpoint debug status register */ + u32 bpdmr; /* Breakpoint debug mask register */ + u32 bprmrr0; /* Breakpoint request mode risc register 0 */ + u32 bprmrr1; /* Breakpoint request mode risc register 1 */ + u8 res0[0x8]; + u32 bprmtr0; /* Breakpoint request mode trb register 0 */ + u32 bprmtr1; /* Breakpoint request mode trb register 1 */ + u8 res1[0x8]; + u32 bprmir; /* Breakpoint request mode immediate register */ + u32 bprmsr; /* Breakpoint request mode serial register */ + u32 bpemr; /* Breakpoint exit mode register */ + u8 res2[0x48]; +} dbg83xx_t; + +/* +* RISC Special Registers (Trap and Breakpoint) +*/ + +typedef struct rsp83xx { + u8 fixme[0x100]; +} rsp83xx_t; +#endif typedef struct immap { - sysconf8349_t sysconf; /* System configuration */ - wdt8349_t wdt; /* Watch Dog Timer (WDT) Registers */ - rtclk8349_t rtc; /* Real Time Clock Module Registers */ - rtclk8349_t pit; /* Periodic Interval Timer */ - gtm8349_t gtm[2]; /* Global Timers Module */ - ipic8349_t ipic; /* Integrated Programmable Interrupt Controller */ - arbiter8349_t arbiter; /* System Arbiter Registers */ - reset8349_t reset; /* Reset Module */ - clk8349_t clk; /* System Clock Module */ - pmc8349_t pmc; /* Power Management Control Module */ - gpio8349_t pgio[2]; /* general purpose I/O module */ + sysconf83xx_t sysconf; /* System configuration */ + wdt83xx_t wdt; /* Watch Dog Timer (WDT) Registers */ + rtclk83xx_t rtc; /* Real Time Clock Module Registers */ + rtclk83xx_t pit; /* Periodic Interval Timer */ + gtm83xx_t gtm[2]; /* Global Timers Module */ + ipic83xx_t ipic; /* Integrated Programmable Interrupt Controller */ + arbiter83xx_t arbiter; /* System Arbiter Registers */ + reset83xx_t reset; /* Reset Module */ + clk83xx_t clk; /* System Clock Module */ + pmc83xx_t pmc; /* Power Management Control Module */ +#if defined (CONFIG_MPC8349) + gpio83xx_t pgio[2]; /* general purpose I/O module */ +#elif defined (CONFIG_MPC8360) + qepi83xx_t qepi; /* QE Ports Interrupts Registers */ +#endif u8 res0[0x200]; +#if defined (CONFIG_MPC8360) + u8 DLL_LBDDR[0x100]; +#endif u8 DDL_DDR[0x100]; u8 DDL_LBIU[0x100]; +#if defined (CONFIG_MPC8349) u8 res1[0xE00]; - ddr8349_t ddr; /* DDR Memory Controller Memory */ - i2c_t i2c[2]; /* I2C1 Controller */ +#elif defined (CONFIG_MPC8360) + u8 res1[0x200]; + gpio83xx_t gpio; /* General purpose I/O module */ + qesba83xx_t qesba; /* QE Secondary Bus Access Windows */ +#endif + ddr83xx_t ddr; /* DDR Memory Controller Memory */ + fsl_i2c_t i2c[2]; /* I2C Controllers */ u8 res2[0x1300]; - duart8349_t duart[2];/* DUART */ + duart83xx_t duart[2]; /* DUART */ +#if defined (CONFIG_MPC8349) u8 res3[0x900]; - lbus8349_t lbus; /* Local Bus Controller Registers */ + lbus83xx_t lbus; /* Local Bus Controller Registers */ u8 res4[0x1000]; - spi8349_t spi; /* Serial Peripheral Interface */ + spi83xx_t spi; /* Serial Peripheral Interface */ u8 res5[0xF00]; - dma8349_t dma; /* DMA */ - pciconf8349_t pci_conf[2]; /* PCI Software Configuration Registers */ - ios8349_t ios; /* Sequencer */ - pcictrl8349_t pci_ctrl[2]; /* PCI Controller Control and Status Registers */ +#elif defined (CONFIG_MPC8360) + u8 res3[0x900]; + lbus83xx_t lbus; /* Local Bus Controller */ + u8 res4[0x2000]; +#endif + dma83xx_t dma; /* DMA */ +#if defined (CONFIG_MPC8349) + pciconf83xx_t pci_conf[2]; /* PCI Software Configuration Registers */ + ios83xx_t ios; /* Sequencer */ + pcictrl83xx_t pci_ctrl[2]; /* PCI Controller Control and Status Registers */ u8 res6[0x19900]; - usb8349_t usb; - tsec8349_t tsec[2]; + usb83xx_t usb; + tsec83xx_t tsec[2]; u8 res7[0xA000]; - security8349_t security; + security83xx_t security; +#elif defined (CONFIG_MPC8360) + pciconf83xx_t pci_conf[1]; /* PCI Software Configuration Registers */ + u8 res_5[128]; + ios83xx_t ios; /* Sequencer (IOS) */ + pcictrl83xx_t pci_ctrl[1]; /* PCI Controller Control and Status Registers */ + u8 res6[0x4A00]; + ddr83xx_t ddr_secondary; /* Secondary DDR Memory Controller Memory Map */ + u8 res7[0x22000]; + security83xx_t security; + u8 res8[0xC0000]; + iram83xx_t iram; /* IRAM */ + irq83xx_t irq; /* Interrupt Controller */ + cp83xx_t cp; /* Communications Processor */ + qmx83xx_t qmx; /* QE Multiplexer */ + qet83xx_t qet; /* QE Timers */ + spi83xx_t spi[0x2]; /* spi */ + mcc83xx_t mcc; /* mcc */ + brg83xx_t brg; /* brg */ + usb83xx_t usb; /* USB */ + si1_83xx_t si1; /* SI */ + u8 res9[0x800]; + sir83xx_t sir; /* SI Routing Tables */ + ucc83xx_t ucc1; /* ucc1 */ + ucc83xx_t ucc3; /* ucc3 */ + ucc83xx_t ucc5; /* ucc5 */ + ucc83xx_t ucc7; /* ucc7 */ + u8 res10[0x600]; + upc83xx_t upc1; /* MultiPHY UTOPIA POS Controller 1 */ + ucc83xx_t ucc2; /* ucc2 */ + ucc83xx_t ucc4; /* ucc4 */ + ucc83xx_t ucc6; /* ucc6 */ + ucc83xx_t ucc8; /* ucc8 */ + u8 res11[0x600]; + upc83xx_t upc2; /* MultiPHY UTOPIA POS Controller 2 */ + sdma83xx_t sdma; /* SDMA */ + dbg83xx_t dbg; /* Debug Space */ + rsp83xx_t rsp[0x2]; /* RISC Special Registers (Trap and Breakpoint) */ + u8 res12[0x300]; + u8 res13[0x3A00]; + u8 res14[0x8000]; /* 0x108000 - 0x110000 */ + u8 res15[0xC000]; /* 0x110000 - 0x11C000 Multi-user RAM */ + u8 res16[0x24000]; /* 0x11C000 - 0x140000 */ + u8 res17[0xC0000]; /* 0x140000 - 0x200000 */ +#endif } immap_t; -#endif /* __IMMAP_8349__ */ +#endif /* __IMMAP_83xx__ */ diff --git a/include/asm-ppc/immap_qe.h b/include/asm-ppc/immap_qe.h new file mode 100644 index 0000000..f385032 --- /dev/null +++ b/include/asm-ppc/immap_qe.h @@ -0,0 +1,550 @@ +/* + * QUICC Engine (QE) Internal Memory Map. + * The Internal Memory Map for devices with QE on them. This + * is the superset of all QE devices (8360, etc.). + * + * Copyright (c) 2006 Freescale Semiconductor, Inc. + * Author: Shlomi Gridih <gridish@freescale.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __IMMAP_QE_H__ +#define __IMMAP_QE_H__ + +/* QE I-RAM +*/ +typedef struct qe_iram { + u32 iadd; /* I-RAM Address Register */ + u32 idata; /* I-RAM Data Register */ + u8 res0[0x78]; +} __attribute__ ((packed)) qe_iram_t; + +/* QE Interrupt Controller +*/ +typedef struct qe_ic { + u32 qicr; + u32 qivec; + u32 qripnr; + u32 qipnr; + u32 qipxcc; + u32 qipycc; + u32 qipwcc; + u32 qipzcc; + u32 qimr; + u32 qrimr; + u32 qicnr; + u8 res0[0x4]; + u32 qiprta; + u32 qiprtb; + u8 res1[0x4]; + u32 qricr; + u8 res2[0x20]; + u32 qhivec; + u8 res3[0x1C]; +} __attribute__ ((packed)) qe_ic_t; + +/* Communications Processor +*/ +typedef struct cp_qe { + u32 cecr; /* QE command register */ + u32 ceccr; /* QE controller configuration register */ + u32 cecdr; /* QE command data register */ + u8 res0[0xA]; + u16 ceter; /* QE timer event register */ + u8 res1[0x2]; + u16 cetmr; /* QE timers mask register */ + u32 cetscr; /* QE time-stamp timer control register */ + u32 cetsr1; /* QE time-stamp register 1 */ + u32 cetsr2; /* QE time-stamp register 2 */ + u8 res2[0x8]; + u32 cevter; /* QE virtual tasks event register */ + u32 cevtmr; /* QE virtual tasks mask register */ + u16 cercr; /* QE RAM control register */ + u8 res3[0x2]; + u8 res4[0x24]; + u16 ceexe1; /* QE external request 1 event register */ + u8 res5[0x2]; + u16 ceexm1; /* QE external request 1 mask register */ + u8 res6[0x2]; + u16 ceexe2; /* QE external request 2 event register */ + u8 res7[0x2]; + u16 ceexm2; /* QE external request 2 mask register */ + u8 res8[0x2]; + u16 ceexe3; /* QE external request 3 event register */ + u8 res9[0x2]; + u16 ceexm3; /* QE external request 3 mask register */ + u8 res10[0x2]; + u16 ceexe4; /* QE external request 4 event register */ + u8 res11[0x2]; + u16 ceexm4; /* QE external request 4 mask register */ + u8 res12[0x2]; + u8 res13[0x280]; +} __attribute__ ((packed)) cp_qe_t; + +/* QE Multiplexer +*/ +typedef struct qe_mux { + u32 cmxgcr; /* CMX general clock route register */ + u32 cmxsi1cr_l; /* CMX SI1 clock route low register */ + u32 cmxsi1cr_h; /* CMX SI1 clock route high register */ + u32 cmxsi1syr; /* CMX SI1 SYNC route register */ + u32 cmxucr1; /* CMX UCC1, UCC3 clock route register */ + u32 cmxucr2; /* CMX UCC5, UCC7 clock route register */ + u32 cmxucr3; /* CMX UCC2, UCC4 clock route register */ + u32 cmxucr4; /* CMX UCC6, UCC8 clock route register */ + u32 cmxupcr; /* CMX UPC clock route register */ + u8 res0[0x1C]; +} __attribute__ ((packed)) qe_mux_t; + +/* QE Timers +*/ +typedef struct qe_timers { + u8 gtcfr1; /* Timer 1 2 global configuration register */ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3 4 global configuration register */ + u8 res1[0xB]; + u16 gtmdr1; /* Timer 1 mode register */ + u16 gtmdr2; /* Timer 2 mode register */ + u16 gtrfr1; /* Timer 1 reference register */ + u16 gtrfr2; /* Timer 2 reference register */ + u16 gtcpr1; /* Timer 1 capture register */ + u16 gtcpr2; /* Timer 2 capture register */ + u16 gtcnr1; /* Timer 1 counter */ + u16 gtcnr2; /* Timer 2 counter */ + u16 gtmdr3; /* Timer 3 mode register */ + u16 gtmdr4; /* Timer 4 mode register */ + u16 gtrfr3; /* Timer 3 reference register */ + u16 gtrfr4; /* Timer 4 reference register */ + u16 gtcpr3; /* Timer 3 capture register */ + u16 gtcpr4; /* Timer 4 capture register */ + u16 gtcnr3; /* Timer 3 counter */ + u16 gtcnr4; /* Timer 4 counter */ + u16 gtevr1; /* Timer 1 event register */ + u16 gtevr2; /* Timer 2 event register */ + u16 gtevr3; /* Timer 3 event register */ + u16 gtevr4; /* Timer 4 event register */ + u16 gtps; /* Timer 1 prescale register */ + u8 res2[0x46]; +} __attribute__ ((packed)) qe_timers_t; + +/* BRG +*/ +typedef struct qe_brg { + u32 brgc1; /* BRG1 configuration register */ + u32 brgc2; /* BRG2 configuration register */ + u32 brgc3; /* BRG3 configuration register */ + u32 brgc4; /* BRG4 configuration register */ + u32 brgc5; /* BRG5 configuration register */ + u32 brgc6; /* BRG6 configuration register */ + u32 brgc7; /* BRG7 configuration register */ + u32 brgc8; /* BRG8 configuration register */ + u32 brgc9; /* BRG9 configuration register */ + u32 brgc10; /* BRG10 configuration register */ + u32 brgc11; /* BRG11 configuration register */ + u32 brgc12; /* BRG12 configuration register */ + u32 brgc13; /* BRG13 configuration register */ + u32 brgc14; /* BRG14 configuration register */ + u32 brgc15; /* BRG15 configuration register */ + u32 brgc16; /* BRG16 configuration register */ + u8 res0[0x40]; +} __attribute__ ((packed)) qe_brg_t; + +/* SPI +*/ +typedef struct spi { + u8 res0[0x20]; + u32 spmode; /* SPI mode register */ + u8 res1[0x2]; + u8 spie; /* SPI event register */ + u8 res2[0x1]; + u8 res3[0x2]; + u8 spim; /* SPI mask register */ + u8 res4[0x1]; + u8 res5[0x1]; + u8 spcom; /* SPI command register */ + u8 res6[0x2]; + u32 spitd; /* SPI transmit data register (cpu mode) */ + u32 spird; /* SPI receive data register (cpu mode) */ + u8 res7[0x8]; +} __attribute__ ((packed)) spi_t; + +/* SI +*/ +typedef struct si1 { + u16 siamr1; /* SI1 TDMA mode register */ + u16 sibmr1; /* SI1 TDMB mode register */ + u16 sicmr1; /* SI1 TDMC mode register */ + u16 sidmr1; /* SI1 TDMD mode register */ + u8 siglmr1_h; /* SI1 global mode register high */ + u8 res0[0x1]; + u8 sicmdr1_h; /* SI1 command register high */ + u8 res2[0x1]; + u8 sistr1_h; /* SI1 status register high */ + u8 res3[0x1]; + u16 sirsr1_h; /* SI1 RAM shadow address register high */ + u8 sitarc1; /* SI1 RAM counter Tx TDMA */ + u8 sitbrc1; /* SI1 RAM counter Tx TDMB */ + u8 sitcrc1; /* SI1 RAM counter Tx TDMC */ + u8 sitdrc1; /* SI1 RAM counter Tx TDMD */ + u8 sirarc1; /* SI1 RAM counter Rx TDMA */ + u8 sirbrc1; /* SI1 RAM counter Rx TDMB */ + u8 sircrc1; /* SI1 RAM counter Rx TDMC */ + u8 sirdrc1; /* SI1 RAM counter Rx TDMD */ + u8 res4[0x8]; + u16 siemr1; /* SI1 TDME mode register 16 bits */ + u16 sifmr1; /* SI1 TDMF mode register 16 bits */ + u16 sigmr1; /* SI1 TDMG mode register 16 bits */ + u16 sihmr1; /* SI1 TDMH mode register 16 bits */ + u8 siglmg1_l; /* SI1 global mode register low 8 bits */ + u8 res5[0x1]; + u8 sicmdr1_l; /* SI1 command register low 8 bits */ + u8 res6[0x1]; + u8 sistr1_l; /* SI1 status register low 8 bits */ + u8 res7[0x1]; + u16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits */ + u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */ + u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */ + u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */ + u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */ + u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */ + u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */ + u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */ + u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */ + u8 res8[0x8]; + u32 siml1; /* SI1 multiframe limit register */ + u8 siedm1; /* SI1 extended diagnostic mode register */ + u8 res9[0xBB]; +} __attribute__ ((packed)) si1_t; + +/* SI Routing Tables +*/ +typedef struct sir { + u8 tx[0x400]; + u8 rx[0x400]; + u8 res0[0x800]; +} __attribute__ ((packed)) sir_t; + +/* USB Controller. +*/ +typedef struct usb_ctlr { + u8 usb_usmod; + u8 usb_usadr; + u8 usb_uscom; + u8 res1[1]; + u16 usb_usep1; + u16 usb_usep2; + u16 usb_usep3; + u16 usb_usep4; + u8 res2[4]; + u16 usb_usber; + u8 res3[2]; + u16 usb_usbmr; + u8 res4[1]; + u8 usb_usbs; + u16 usb_ussft; + u8 res5[2]; + u16 usb_usfrn; + u8 res6[0x22]; +} __attribute__ ((packed)) usb_t; + +/* MCC +*/ +typedef struct mcc { + u32 mcce; /* MCC event register */ + u32 mccm; /* MCC mask register */ + u32 mccf; /* MCC configuration register */ + u32 merl; /* MCC emergency request level register */ + u8 res0[0xF0]; +} __attribute__ ((packed)) mcc_t; + +/* QE UCC Slow +*/ +typedef struct ucc_slow { + u32 gumr_l; /* UCCx general mode register (low) */ + u32 gumr_h; /* UCCx general mode register (high) */ + u16 upsmr; /* UCCx protocol-specific mode register */ + u8 res0[0x2]; + u16 utodr; /* UCCx transmit on demand register */ + u16 udsr; /* UCCx data synchronization register */ + u16 ucce; /* UCCx event register */ + u8 res1[0x2]; + u16 uccm; /* UCCx mask register */ + u8 res2[0x1]; + u8 uccs; /* UCCx status register */ + u8 res3[0x24]; + u16 utpt; + u8 guemr; /* UCC general extended mode register */ + u8 res4[0x200 - 0x091]; +} __attribute__ ((packed)) ucc_slow_t; + +typedef struct ucc_ethernet { + u32 maccfg1; /* mac configuration reg. 1 */ + u32 maccfg2; /* mac configuration reg. 2 */ + u32 ipgifg; /* interframe gap reg. */ + u32 hafdup; /* half-duplex reg. */ + u8 res1[0x10]; + u32 miimcfg; /* MII management configuration reg */ + u32 miimcom; /* MII management command reg */ + u32 miimadd; /* MII management address reg */ + u32 miimcon; /* MII management control reg */ + u32 miimstat; /* MII management status reg */ + u32 miimind; /* MII management indication reg */ + u32 ifctl; /* interface control reg */ + u32 ifstat; /* interface statux reg */ + u32 macstnaddr1; /* mac station address part 1 reg */ + u32 macstnaddr2; /* mac station address part 2 reg */ + u8 res2[0x8]; + u32 uempr; /* UCC Ethernet Mac parameter reg */ + u32 utbipar; /* UCC tbi address reg */ + u16 uescr; /* UCC Ethernet statistics control reg */ + u8 res3[0x180 - 0x15A]; + u32 tx64; /* Total number of frames (including bad + * frames) transmitted that were exactly + * of the minimal length (64 for un tagged, + * 68 for tagged, or with length exactly + * equal to the parameter MINLength */ + u32 tx127; /* Total number of frames (including bad + * frames) transmitted that were between + * MINLength (Including FCS length==4) + * and 127 octets */ + u32 tx255; /* Total number of frames (including bad + * frames) transmitted that were between + * 128 (Including FCS length==4) and 255 + * octets */ + u32 rx64; /* Total number of frames received including + * bad frames that were exactly of the + * mninimal length (64 bytes) */ + u32 rx127; /* Total number of frames (including bad + * frames) received that were between + * MINLength (Including FCS length==4) + * and 127 octets */ + u32 rx255; /* Total number of frames (including + * bad frames) received that were between + * 128 (Including FCS length==4) and 255 + * octets */ + u32 txok; /* Total number of octets residing in frames + * that where involved in succesfull + * transmission */ + u16 txcf; /* Total number of PAUSE control frames + * transmitted by this MAC */ + u8 res4[0x2]; + u32 tmca; /* Total number of frames that were transmitted + * succesfully with the group address bit set + * that are not broadcast frames */ + u32 tbca; /* Total number of frames transmitted + * succesfully that had destination address + * field equal to the broadcast address */ + u32 rxfok; /* Total number of frames received OK */ + u32 rxbok; /* Total number of octets received OK */ + u32 rbyt; /* Total number of octets received including + * octets in bad frames. Must be implemented + * in HW because it includes octets in frames + * that never even reach the UCC */ + u32 rmca; /* Total number of frames that were received + * succesfully with the group address bit set + * that are not broadcast frames */ + u32 rbca; /* Total number of frames received succesfully + * that had destination address equal to the + * broadcast address */ + u32 scar; /* Statistics carry register */ + u32 scam; /* Statistics caryy mask register */ + u8 res5[0x200 - 0x1c4]; +} __attribute__ ((packed)) uec_t; + +/* QE UCC Fast +*/ +typedef struct ucc_fast { + u32 gumr; /* UCCx general mode register */ + u32 upsmr; /* UCCx protocol-specific mode register */ + u16 utodr; /* UCCx transmit on demand register */ + u8 res0[0x2]; + u16 udsr; /* UCCx data synchronization register */ + u8 res1[0x2]; + u32 ucce; /* UCCx event register */ + u32 uccm; /* UCCx mask register. */ + u8 uccs; /* UCCx status register */ + u8 res2[0x7]; + u32 urfb; /* UCC receive FIFO base */ + u16 urfs; /* UCC receive FIFO size */ + u8 res3[0x2]; + u16 urfet; /* UCC receive FIFO emergency threshold */ + u16 urfset; /* UCC receive FIFO special emergency + * threshold */ + u32 utfb; /* UCC transmit FIFO base */ + u16 utfs; /* UCC transmit FIFO size */ + u8 res4[0x2]; + u16 utfet; /* UCC transmit FIFO emergency threshold */ + u8 res5[0x2]; + u16 utftt; /* UCC transmit FIFO transmit threshold */ + u8 res6[0x2]; + u16 utpt; /* UCC transmit polling timer */ + u8 res7[0x2]; + u32 urtry; /* UCC retry counter register */ + u8 res8[0x4C]; + u8 guemr; /* UCC general extended mode register */ + u8 res9[0x100 - 0x091]; + uec_t ucc_eth; +} __attribute__ ((packed)) ucc_fast_t; + +/* QE UCC +*/ +typedef struct ucc_common { + u8 res1[0x90]; + u8 guemr; + u8 res2[0x200 - 0x091]; +} __attribute__ ((packed)) ucc_common_t; + +typedef struct ucc { + union { + ucc_slow_t slow; + ucc_fast_t fast; + ucc_common_t common; + }; +} __attribute__ ((packed)) ucc_t; + +/* MultiPHY UTOPIA POS Controllers (UPC) +*/ +typedef struct upc { + u32 upgcr; /* UTOPIA/POS general configuration register */ + u32 uplpa; /* UTOPIA/POS last PHY address */ + u32 uphec; /* ATM HEC register */ + u32 upuc; /* UTOPIA/POS UCC configuration */ + u32 updc1; /* UTOPIA/POS device 1 configuration */ + u32 updc2; /* UTOPIA/POS device 2 configuration */ + u32 updc3; /* UTOPIA/POS device 3 configuration */ + u32 updc4; /* UTOPIA/POS device 4 configuration */ + u32 upstpa; /* UTOPIA/POS STPA threshold */ + u8 res0[0xC]; + u32 updrs1_h; /* UTOPIA/POS device 1 rate select */ + u32 updrs1_l; /* UTOPIA/POS device 1 rate select */ + u32 updrs2_h; /* UTOPIA/POS device 2 rate select */ + u32 updrs2_l; /* UTOPIA/POS device 2 rate select */ + u32 updrs3_h; /* UTOPIA/POS device 3 rate select */ + u32 updrs3_l; /* UTOPIA/POS device 3 rate select */ + u32 updrs4_h; /* UTOPIA/POS device 4 rate select */ + u32 updrs4_l; /* UTOPIA/POS device 4 rate select */ + u32 updrp1; /* UTOPIA/POS device 1 receive priority low */ + u32 updrp2; /* UTOPIA/POS device 2 receive priority low */ + u32 updrp3; /* UTOPIA/POS device 3 receive priority low */ + u32 updrp4; /* UTOPIA/POS device 4 receive priority low */ + u32 upde1; /* UTOPIA/POS device 1 event */ + u32 upde2; /* UTOPIA/POS device 2 event */ + u32 upde3; /* UTOPIA/POS device 3 event */ + u32 upde4; /* UTOPIA/POS device 4 event */ + u16 uprp1; + u16 uprp2; + u16 uprp3; + u16 uprp4; + u8 res1[0x8]; + u16 uptirr1_0; /* Device 1 transmit internal rate 0 */ + u16 uptirr1_1; /* Device 1 transmit internal rate 1 */ + u16 uptirr1_2; /* Device 1 transmit internal rate 2 */ + u16 uptirr1_3; /* Device 1 transmit internal rate 3 */ + u16 uptirr2_0; /* Device 2 transmit internal rate 0 */ + u16 uptirr2_1; /* Device 2 transmit internal rate 1 */ + u16 uptirr2_2; /* Device 2 transmit internal rate 2 */ + u16 uptirr2_3; /* Device 2 transmit internal rate 3 */ + u16 uptirr3_0; /* Device 3 transmit internal rate 0 */ + u16 uptirr3_1; /* Device 3 transmit internal rate 1 */ + u16 uptirr3_2; /* Device 3 transmit internal rate 2 */ + u16 uptirr3_3; /* Device 3 transmit internal rate 3 */ + u16 uptirr4_0; /* Device 4 transmit internal rate 0 */ + u16 uptirr4_1; /* Device 4 transmit internal rate 1 */ + u16 uptirr4_2; /* Device 4 transmit internal rate 2 */ + u16 uptirr4_3; /* Device 4 transmit internal rate 3 */ + u32 uper1; /* Device 1 port enable register */ + u32 uper2; /* Device 2 port enable register */ + u32 uper3; /* Device 3 port enable register */ + u32 uper4; /* Device 4 port enable register */ + u8 res2[0x150]; +} __attribute__ ((packed)) upc_t; + +/* SDMA +*/ +typedef struct sdma { + u32 sdsr; /* Serial DMA status register */ + u32 sdmr; /* Serial DMA mode register */ + u32 sdtr1; /* SDMA system bus threshold register */ + u32 sdtr2; /* SDMA secondary bus threshold register */ + u32 sdhy1; /* SDMA system bus hysteresis register */ + u32 sdhy2; /* SDMA secondary bus hysteresis register */ + u32 sdta1; /* SDMA system bus address register */ + u32 sdta2; /* SDMA secondary bus address register */ + u32 sdtm1; /* SDMA system bus MSNUM register */ + u32 sdtm2; /* SDMA secondary bus MSNUM register */ + u8 res0[0x10]; + u32 sdaqr; /* SDMA address bus qualify register */ + u32 sdaqmr; /* SDMA address bus qualify mask register */ + u8 res1[0x4]; + u32 sdwbcr; /* SDMA CAM entries base register */ + u8 res2[0x38]; +} __attribute__ ((packed)) sdma_t; + +/* Debug Space +*/ +typedef struct dbg { + u32 bpdcr; /* Breakpoint debug command register */ + u32 bpdsr; /* Breakpoint debug status register */ + u32 bpdmr; /* Breakpoint debug mask register */ + u32 bprmrr0; /* Breakpoint request mode risc register 0 */ + u32 bprmrr1; /* Breakpoint request mode risc register 1 */ + u8 res0[0x8]; + u32 bprmtr0; /* Breakpoint request mode trb register 0 */ + u32 bprmtr1; /* Breakpoint request mode trb register 1 */ + u8 res1[0x8]; + u32 bprmir; /* Breakpoint request mode immediate register */ + u32 bprmsr; /* Breakpoint request mode serial register */ + u32 bpemr; /* Breakpoint exit mode register */ + u8 res2[0x48]; +} __attribute__ ((packed)) dbg_t; + +/* RISC Special Registers (Trap and Breakpoint) +*/ +typedef struct rsp { + u8 fixme[0x100]; +} __attribute__ ((packed)) rsp_t; + +typedef struct qe_immap { + qe_iram_t iram; /* I-RAM */ + qe_ic_t ic; /* Interrupt Controller */ + cp_qe_t cp; /* Communications Processor */ + qe_mux_t qmx; /* QE Multiplexer */ + qe_timers_t qet; /* QE Timers */ + spi_t spi[0x2]; /* spi */ + mcc_t mcc; /* mcc */ + qe_brg_t brg; /* brg */ + usb_t usb; /* USB */ + si1_t si1; /* SI */ + u8 res11[0x800]; + sir_t sir; /* SI Routing Tables */ + ucc_t ucc1; /* ucc1 */ + ucc_t ucc3; /* ucc3 */ + ucc_t ucc5; /* ucc5 */ + ucc_t ucc7; /* ucc7 */ + u8 res12[0x600]; + upc_t upc1; /* MultiPHY UTOPIA POS Controller 1 */ + ucc_t ucc2; /* ucc2 */ + ucc_t ucc4; /* ucc4 */ + ucc_t ucc6; /* ucc6 */ + ucc_t ucc8; /* ucc8 */ + u8 res13[0x600]; + upc_t upc2; /* MultiPHY UTOPIA POS Controller 2 */ + sdma_t sdma; /* SDMA */ + dbg_t dbg; /* Debug Space */ + rsp_t rsp[0x2]; /* RISC Special Registers + * (Trap and Breakpoint) */ + u8 res14[0x300]; + u8 res15[0x3A00]; + u8 res16[0x8000]; /* 0x108000 - 0x110000 */ + u8 muram[0xC000]; /* 0x110000 - 0x11C000 Multi-user RAM */ + u8 res17[0x24000]; /* 0x11C000 - 0x140000 */ + u8 res18[0xC0000]; /* 0x140000 - 0x200000 */ +} __attribute__ ((packed)) qe_map_t; + +extern qe_map_t *qe_immr; + +#endif /* __IMMAP_QE_H__ */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 388dea4..6619686 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -749,6 +749,7 @@ #define PVR_405EP_RB 0x51210950 #define PVR_440SP_RA 0x53221850 #define PVR_440SP_RB 0x53221891 +#define PVR_440SP_RC 0x53221892 #define PVR_440SPe_RA 0x53421890 #define PVR_440SPe_RB 0x53421891 #define PVR_601 0x00010000 diff --git a/include/common.h b/include/common.h index ac78d1c..982d6a8 100644 --- a/include/common.h +++ b/include/common.h @@ -402,6 +402,11 @@ void ppcSync(void); void ppcDcbz(unsigned long value); #endif +#if defined (CONFIG_MPC83XX) +void ppcDWload(unsigned int *addr, unsigned int *ret); +void ppcDWstore(unsigned int *addr, unsigned int *value); +#endif + /* $(CPU)/cpu.c */ int checkcpu (void); int checkicache (void); diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index 1152f83..0d38254 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -172,6 +172,19 @@ #undef CFG_IPBSPEED_133 /* define for 133MHz speed */ #endif #endif /* CONFIG_MPC5200 */ + +/* pass open firmware flat tree */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 + +/* maximum size of the flat tree (8K) */ +#define OF_FLAT_TREE_MAX_SIZE 8192 + +#define OF_CPU "PowerPC,5200@0" +#define OF_SOC "soc5200@f0000000" +#define OF_TBCLK (bd->bi_busfreq / 8) +#define OF_STDOUT_PATH "/soc5200@f0000000/serial@2000" + /* * I2C configuration */ diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index 66f1646..5bed2d0 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -36,6 +36,7 @@ */ #define CONFIG_E300 1 /* E300 Family */ #define CONFIG_MPC83XX 1 /* MPC83XX family */ +#define CONFIG_MPC834X 1 /* MPC834X family */ #define CONFIG_MPC8349 1 /* MPC8349 specific */ #define CONFIG_MPC8349EMDS 1 /* MPC8349EMDS board specific */ @@ -59,9 +60,20 @@ #endif #endif +#define CFG_SCCR_INIT (SCCR_DEFAULT & (~SCCR_CLK_MASK)) +#define CFG_SCCR_TSEC1CM SCCR_TSEC1CM_1 /* TSEC1 clock setting */ +#define CFG_SCCR_TSEC2CM SCCR_TSEC2CM_1 /* TSEC2 clock setting */ +#define CFG_SCCR_ENCCM SCCR_ENCCM_3 /* ENC clock setting */ +#define CFG_SCCR_USBCM SCCR_USBCM_3 /* USB clock setting */ +#define CFG_SCCR_VAL ( CFG_SCCR_INIT \ + | CFG_SCCR_TSEC1CM \ + | CFG_SCCR_TSEC2CM \ + | CFG_SCCR_ENCCM \ + | CFG_SCCR_USBCM ) + #define CONFIG_BOARD_EARLY_INIT_F /* call board_pre_init */ -#define CFG_IMMRBAR 0xE0000000 +#define CFG_IMMR 0xE0000000 #undef CFG_DRAM_TEST /* memory test, takes time */ #define CFG_MEMTEST_START 0x00000000 /* memtest region */ @@ -299,8 +311,8 @@ #define CFG_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} -#define CFG_NS16550_COM1 (CFG_IMMRBAR+0x4500) -#define CFG_NS16550_COM2 (CFG_IMMRBAR+0x4600) +#define CFG_NS16550_COM1 (CFG_IMMR+0x4500) +#define CFG_NS16550_COM2 (CFG_IMMR+0x4600) /* Use the HUSH parser */ #define CFG_HUSH_PARSER @@ -308,20 +320,35 @@ #define CFG_PROMPT_HUSH_PS2 "> " #endif +/* pass open firmware flat tree */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 + +/* maximum size of the flat tree (8K) */ +#define OF_FLAT_TREE_MAX_SIZE 8192 + +#define OF_CPU "PowerPC,8349@0" +#define OF_SOC "soc8349@e0000000" +#define OF_TBCLK (bd->bi_busfreq / 4) +#define OF_STDOUT_PATH "/soc8349@e0000000/serial@4500" + /* I2C */ #define CONFIG_HARD_I2C /* I2C with hardware support*/ #undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CONFIG_FSL_I2C +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE #define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ #define CFG_I2C_SLAVE 0x7F -#define CFG_I2C_NOPROBES {0x69} /* Don't probe these addrs */ +#define CFG_I2C_NOPROBES {{0,0x69}} /* Don't probe these addrs */ #define CFG_I2C_OFFSET 0x3000 #define CFG_I2C2_OFFSET 0x3100 /* TSEC */ #define CFG_TSEC1_OFFSET 0x24000 -#define CFG_TSEC1 (CFG_IMMRBAR+CFG_TSEC1_OFFSET) +#define CFG_TSEC1 (CFG_IMMR+CFG_TSEC1_OFFSET) #define CFG_TSEC2_OFFSET 0x25000 -#define CFG_TSEC2 (CFG_IMMRBAR+CFG_TSEC2_OFFSET) +#define CFG_TSEC2 (CFG_IMMR+CFG_TSEC2_OFFSET) /* USB */ #define CFG_USE_MPC834XSYS_USB_PHY 1 /* Use SYS board PHY */ @@ -615,8 +642,8 @@ #endif /* IMMRBAR @ 0xE0000000, PCI IO @ 0xE2000000 & BCSR @ 0xE2400000 */ -#define CFG_IBAT5L (CFG_IMMRBAR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CFG_IBAT5U (CFG_IMMRBAR | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_IBAT5L (CFG_IMMR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT5U (CFG_IMMR | BATU_BL_256M | BATU_VS | BATU_VP) /* SDRAM @ 0xF0000000, stack in DCACHE 0xFDF00000 & FLASH @ 0xFE000000 */ #define CFG_IBAT6L (0xF0000000 | BATL_PP_10 | BATL_MEMCOHERENCE) @@ -666,11 +693,11 @@ #define CONFIG_ETH1ADDR 00:E0:0C:00:7E:21 #endif -#define CONFIG_IPADDR 192.168.205.5 +#define CONFIG_IPADDR 192.168.1.253 #define CONFIG_HOSTNAME mpc8349emds -#define CONFIG_ROOTPATH /opt/eldk/ppc_6xx -#define CONFIG_BOOTFILE /tftpboot/tqm83xx/uImage +#define CONFIG_ROOTPATH /nfsroot/rootfs +#define CONFIG_BOOTFILE uImage #define CONFIG_SERVERIP 192.168.1.1 #define CONFIG_GATEWAYIP 192.168.1.1 @@ -703,14 +730,31 @@ "bootm ${kernel_addr} ${ramdisk_addr}\0" \ "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \ "bootm\0" \ - "rootpath=/opt/eldk/ppc_6xx\0" \ - "bootfile=/tftpboot/mpc8349emds/uImage\0" \ "load=tftp 100000 /tftpboot/mpc8349emds/u-boot.bin\0" \ "update=protect off fe000000 fe03ffff; " \ "era fe000000 fe03ffff; cp.b 100000 fe000000 ${filesize}\0" \ "upd=run load;run update\0" \ + "fdtaddr=400000\0" \ + "fdtfile=mpc8349emds.dtb\0" \ "" +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr - $fdtaddr" + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr" + #define CONFIG_BOOTCOMMAND "run flash_self" #endif /* __CONFIG_H */ diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h new file mode 100644 index 0000000..cbdbb29 --- /dev/null +++ b/include/configs/MPC8349ITX.h @@ -0,0 +1,804 @@ +/* + * 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 + */ + +/* + MPC8349E-mITX board configuration file + + Memory map: + + 0x0000_0000-0x0FFF_FFFF DDR SDRAM (256 MB) + 0x8000_0000-0x9FFF_FFFF PCI1 memory space (512 MB) + 0xA000_0000-0xBFFF_FFFF PCI2 memory space (512 MB) + 0xE000_0000-0xEFFF_FFFF IMMR (1 MB) + 0xE200_0000-0xE2FF_FFFF PCI1 I/O space (16 MB) + 0xE300_0000-0xE3FF_FFFF PCI2 I/O space (16 MB) + 0xF000_0000-0xF000_FFFF Compact Flash + 0xF001_0000-0xF001_FFFF Local bus expansion slot + 0xF800_0000-0xF801_FFFF GBE L2 Switch VSC7385 + 0xFF00_0000-0xFF7F_FFFF Alternative bank of Flash memory (8MB) + 0xFF80_0000-0xFFFF_FFFF Boot Flash (8 MB) + + I2C address list: + Align. Board + Bus Addr Part No. Description Length Location + ---------------------------------------------------------------- + I2C0 0x50 M24256-BWMN6P Board EEPROM 2 U64 + + I2C1 0x20 PCF8574 I2C Expander 0 U8 + I2C1 0x21 PCF8574 I2C Expander 0 U10 + I2C1 0x38 PCF8574A I2C Expander 0 U8 + I2C1 0x39 PCF8574A I2C Expander 0 U10 + I2C1 0x51 (DDR) DDR EEPROM 1 U1 + I2C1 0x68 DS1339 RTC 1 U68 + + Note that a given board has *either* a pair of 8574s or a pair of 8574As. +*/ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#undef DEBUG + +/* + * High Level Configuration Options + */ +#define CONFIG_MPC834X /* MPC834x family (8343, 8347, 8349) */ +#define CONFIG_MPC8349 /* MPC8349 specific */ + +#define CONFIG_PCI + +#define CONFIG_COMPACT_FLASH /* The CF card interface on the back of the board */ +#define CONFIG_RTC_DS1337 + +/* I2C */ +#define CONFIG_HARD_I2C + +#ifdef CONFIG_HARD_I2C + +#define CONFIG_MISC_INIT_F +#define CONFIG_MISC_INIT_R + +#define CONFIG_FSL_I2C +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE +#define CFG_I2C_OFFSET 0x3000 +#define CFG_I2C2_OFFSET 0x3100 +#define CFG_SPD_BUS_NUM 1 /* The I2C bus for SPD */ + +#define CFG_I2C_8574_ADDR1 0x20 /* I2C1, PCF8574 */ +#define CFG_I2C_8574_ADDR2 0x21 /* I2C1, PCF8574 */ +#define CFG_I2C_8574A_ADDR1 0x38 /* I2C1, PCF8574A */ +#define CFG_I2C_8574A_ADDR2 0x39 /* I2C1, PCF8574A */ +#define CFG_I2C_EEPROM_ADDR 0x50 /* I2C0, Board EEPROM */ +#define CFG_I2C_RTC_ADDR 0x68 /* I2C1, DS1339 RTC*/ +#define SPD_EEPROM_ADDRESS 0x51 /* I2C1, DDR */ + +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* Don't probe these addresses: */ +#define CFG_I2C_NOPROBES {{1, CFG_I2C_8574_ADDR1}, \ + {1, CFG_I2C_8574_ADDR2}, \ + {1, CFG_I2C_8574A_ADDR1}, \ + {1, CFG_I2C_8574A_ADDR2}} +/* Bit definitions for the 8574[A] I2C expander */ +#define I2C_8574_REVISION 0x03 /* Board revision, 00=0.0, 01=0.1, 10=1.0 */ +#define I2C_8574_CF 0x08 /* 1=Compact flash absent, 0=present */ +#define I2C_8574_MPCICLKRN 0x10 /* MiniPCI Clk Run */ +#define I2C_8574_PCI66 0x20 /* 0=33MHz PCI, 1=66MHz PCI */ +#define I2C_8574_FLASHSIDE 0x40 /* 0=Reset vector from U4, 1=from U7*/ + +#undef CONFIG_SOFT_I2C + +#endif + +#define CONFIG_TSEC_ENET /* tsec ethernet support */ +#define CONFIG_ENV_OVERWRITE + +#define PCI_66M +#ifdef PCI_66M +#define CONFIG_83XX_CLKIN 66666666 /* in Hz */ +#else +#define CONFIG_83XX_CLKIN 33333333 /* in Hz */ +#endif + +#ifndef CONFIG_SYS_CLK_FREQ +#ifdef PCI_66M +#define CONFIG_SYS_CLK_FREQ 66666666 +#else +#define CONFIG_SYS_CLK_FREQ 33333333 +#endif +#endif + +#define CFG_IMMR 0xE0000000 /* The IMMR is relocated to here */ + +#undef CFG_DRAM_TEST /* memory test, takes time */ +#define CFG_MEMTEST_START 0x00003000 /* memtest region */ +#define CFG_MEMTEST_END 0x07100000 /* only has 128M */ + +/* + * DDR Setup + */ +#undef CONFIG_DDR_ECC /* only for ECC DDR module */ +#undef CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */ +#define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ + +/* + * 32-bit data path mode. + * + * Please note that using this mode for devices with the real density of 64-bit + * effectively reduces the amount of available memory due to the effect of + * wrapping around while translating address to row/columns, for example in the + * 256MB module the upper 128MB get aliased with contents of the lower + * 128MB); normally this define should be used for devices with real 32-bit + * data path. + */ +#undef CONFIG_DDR_32BIT + +#define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ +#define CFG_SDRAM_BASE CFG_DDR_BASE +#define CFG_DDR_SDRAM_BASE CFG_DDR_BASE +#undef CONFIG_DDR_2T_TIMING +#define CFG_83XX_DDR_USES_CS0 + +#ifndef CONFIG_SPD_EEPROM +/* + * Manually set up DDR parameters + */ + #define CFG_DDR_SIZE 256 /* Mb */ + #define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10) + + #define CFG_DDR_TIMING_1 0x26242321 + #define CFG_DDR_TIMING_2 0x00000800 /* P9-45, may need tuning */ +#endif + +/* FLASH on the Local Bus */ +#define CFG_FLASH_CFI /* use the Common Flash Interface */ +#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CFG_FLASH_BASE 0xFE000000 /* start of FLASH */ +#define CFG_FLASH_SIZE 16 /* FLASH size in MB */ +#define CFG_FLASH_EMPTY_INFO + +#define CFG_BR0_PRELIM (CFG_FLASH_BASE | BR_PS_16 | BR_V) +#define CFG_OR0_PRELIM ((~(CFG_FLASH_SIZE - 1) << 20) | OR_UPM_XAM | \ + OR_GPCM_CSNT | OR_GPCM_ACS_0b11 | OR_GPCM_XACS | OR_GPCM_SCY_15 | \ + OR_GPCM_TRLX | OR_GPCM_EHTR | OR_GPCM_EAD) +#define CFG_LBLAWBAR0_PRELIM CFG_FLASH_BASE /* Window base at flash base */ +#define CFG_LBLAWAR0_PRELIM 0x80000017 /* 16Mb window bytes */ + +/* VSC7385 on the Local Bus */ +#define CFG_VSC7385_BASE 0xF8000000 /* start of VSC7385 */ + +#define CFG_BR1_PRELIM (CFG_VSC7385_BASE | BR_PS_8 | BR_V) +#define CFG_OR1_PRELIM (0xFFFE0000 /* 128KB */ | \ + OR_GPCM_CSNT | OR_GPCM_XACS | OR_GPCM_SCY_15 | \ + OR_GPCM_SETA | OR_GPCM_TRLX | OR_GPCM_EHTR | OR_GPCM_EAD) + +#define CFG_LBLAWBAR1_PRELIM CFG_VSC7385_BASE /* Access window base at VSC7385 base */ +#define CFG_LBLAWAR1_PRELIM 0x80000010 /* Access window size 128K */ + +#define CFG_MAX_FLASH_BANKS 2 /* number of banks */ +#define CFG_MAX_FLASH_SECT 135 /* sectors per device */ + +#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE, CFG_FLASH_BASE + 0x800000} + +#undef CFG_FLASH_CHECKSUM +#define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CFG_LED_BASE 0xF9000000 /* start of LED and Board ID */ +#define CFG_BR2_PRELIM (CFG_LED_BASE | BR_PS_8 | BR_V) +#define CFG_OR2_PRELIM (0xFFE00000 /* 2MB */ | \ + OR_GPCM_CSNT | OR_GPCM_ACS_0b11 | OR_GPCM_XACS | \ + OR_GPCM_SCY_9 | \ + OR_GPCM_TRLX | OR_GPCM_EHTR | OR_GPCM_EAD) + +#ifdef CONFIG_COMPACT_FLASH + +#define CFG_CF_BASE 0xF0000000 + +#define CFG_BR3_PRELIM (CFG_CF_BASE | BR_PS_16 | BR_MS_UPMA | BR_V) +#define CFG_OR3_PRELIM (OR_UPM_AM | OR_UPM_BI) + +#define CFG_LBLAWBAR2_PRELIM CFG_CF_BASE /* Window base at flash base + LED & Board ID */ +#define CFG_LBLAWAR2_PRELIM 0x8000000F /* 64K bytes */ + +#undef CONFIG_IDE_RESET +#undef CONFIG_IDE_PREINIT + +#define CFG_IDE_MAXBUS 1 +#define CFG_IDE_MAXDEVICE 1 + +#define CFG_ATA_IDE0_OFFSET 0x0000 +#define CFG_ATA_BASE_ADDR CFG_CF_BASE +#define CFG_ATA_DATA_OFFSET 0x0000 +#define CFG_ATA_REG_OFFSET 0 +#define CFG_ATA_ALT_OFFSET 0x0200 +#define CFG_ATA_STRIDE 2 + +#define ATA_RESET_TIME 1 /* If a CF card is not inserted, time out quickly */ + +#endif + +#define CONFIG_DOS_PARTITION + +#define CFG_MID_FLASH_JUMP 0x7F000000 +#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ + + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +#define CFG_RAMBOOT +#else +#undef CFG_RAMBOOT +#endif + +#define CONFIG_L1_INIT_RAM +#define CFG_INIT_RAM_LOCK +#define CFG_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ +#define CFG_INIT_RAM_END 0x1000 /* End of used area in RAM*/ + +#define CFG_GBL_DATA_SIZE 0x100 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET + +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */ + +/* + * Local Bus LCRR and LBCR regs + * LCRR: DLL bypass, Clock divider is 4 + * External Local Bus rate is + * CLKIN * HRCWL_CSB_TO_CLKIN / HRCWL_LCL_BUS_TO_SCB_CLK / LCRR_CLKDIV + */ +#define CFG_LCRR (LCRR_DBYP | LCRR_CLKDIV_4) +#define CFG_LBC_LBCR 0x00000000 + +#undef CFG_LB_SDRAM /* if board has SRDAM on local bus */ + +#ifdef CFG_LB_SDRAM +/*local bus BR2, OR2 definition for SDRAM if soldered on the ADS board*/ +/* + * Base Register 2 and Option Register 2 configure SDRAM. + * The SDRAM base address, CFG_LBC_SDRAM_BASE, is 0xf0000000. + * + * For BR2, need: + * Base address of 0xf0000000 = BR[0:16] = 1111 0000 0000 0000 0 + * port-size = 32-bits = BR2[19:20] = 11 + * no parity checking = BR2[21:22] = 00 + * SDRAM for MSEL = BR2[24:26] = 011 + * Valid = BR[31] = 1 + * + * 0 4 8 12 16 20 24 28 + * 1111 0000 0000 0000 0001 1000 0110 0001 = F0001861 + */ + +#define CFG_LBC_SDRAM_BASE 0xf0000000 /* Localbus SDRAM */ +#define CFG_LBC_SDRAM_SIZE 64 /* LBC SDRAM is 64MB */ + +#define CFG_LBLAWBAR2_PRELIM 0xF0000000 +#define CFG_LBLAWAR2_PRELIM 0x80000019 /* 64M */ + +#define CFG_BR2_PRELIM (CFG_LBC_SDRAM_BASE | BR_PS_32 | BR_MS_SDRAM | BR_V) +#define CFG_OR2_PRELIM (0xFC000000 /* 64 MB */ | \ + OR_SDRAM_XAM | \ + ((9 - 7) << OR_SDRAM_COLS_SHIFT) | \ + ((13 - 9) << OR_SDRAM_ROWS_SHIFT) | \ + OR_SDRAM_EAD) + +#define CFG_LBC_LSRT 0x32000000 /* LB sdram refresh timer, about 6us */ +#define CFG_LBC_MRTPR 0x20000000 /* LB refresh timer prescal, 266MHz/32*/ + +/* + * LSDMR masks + */ +#define CFG_LBC_LSDMR_RFEN (1 << (31 - 1)) +#define CFG_LBC_LSDMR_BSMA1516 (3 << (31 - 10)) +#define CFG_LBC_LSDMR_BSMA1617 (4 << (31 - 10)) +#define CFG_LBC_LSDMR_RFCR5 (3 << (31 - 16)) +#define CFG_LBC_LSDMR_RFCR8 (5 << (31 - 16)) +#define CFG_LBC_LSDMR_RFCR16 (7 << (31 - 16)) +#define CFG_LBC_LSDMR_PRETOACT3 (3 << (31 - 19)) +#define CFG_LBC_LSDMR_PRETOACT6 (5 << (31 - 19)) +#define CFG_LBC_LSDMR_PRETOACT7 (7 << (31 - 19)) +#define CFG_LBC_LSDMR_ACTTORW3 (3 << (31 - 22)) +#define CFG_LBC_LSDMR_ACTTORW7 (7 << (31 - 22)) +#define CFG_LBC_LSDMR_ACTTORW6 (6 << (31 - 22)) +#define CFG_LBC_LSDMR_BL8 (1 << (31 - 23)) +#define CFG_LBC_LSDMR_WRC2 (2 << (31 - 27)) +#define CFG_LBC_LSDMR_WRC3 (3 << (31 - 27)) +#define CFG_LBC_LSDMR_WRC4 (0 << (31 - 27)) +#define CFG_LBC_LSDMR_BUFCMD (1 << (31 - 29)) +#define CFG_LBC_LSDMR_CL3 (3 << (31 - 31)) + +#define CFG_LBC_LSDMR_OP_NORMAL (0 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ARFRSH (1 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_SRFRSH (2 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_MRW (3 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PRECH (4 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PCHALL (5 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ACTBNK (6 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_RWINV (7 << (31 - 4)) + +#define CFG_LBC_LSDMR_COMMON ( CFG_LBC_LSDMR_RFEN \ + | CFG_LBC_LSDMR_BSMA1516 \ + | CFG_LBC_LSDMR_RFCR8 \ + | CFG_LBC_LSDMR_PRETOACT6 \ + | CFG_LBC_LSDMR_ACTTORW3 \ + | CFG_LBC_LSDMR_BL8 \ + | CFG_LBC_LSDMR_WRC3 \ + | CFG_LBC_LSDMR_CL3 \ + ) + +/* + * SDRAM Controller configuration sequence. + */ +#define CFG_LBC_LSDMR_1 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_PCHALL) +#define CFG_LBC_LSDMR_2 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_3 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_4 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_MRW) +#define CFG_LBC_LSDMR_5 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_NORMAL) +#endif + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE 1 +#define CFG_NS16550_CLK get_bus_freq(0) + +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CFG_NS16550_COM1 (CFG_IMMR + 0x4500) +#define CFG_NS16550_COM2 (CFG_IMMR + 0x4600) + +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* pass open firmware flat tree */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 + +/* maximum size of the flat tree (8K) */ +#define OF_FLAT_TREE_MAX_SIZE 8192 + +#define OF_CPU "PowerPC,8349@0" +#define OF_SOC "soc8349@e0000000" +#define OF_TBCLK (bd->bi_busfreq / 4) +#define OF_STDOUT_PATH "/soc8349@e0000000/serial@4500" + +#ifdef CONFIG_PCI + +#define CONFIG_MPC83XX_PCI2 + +/* + * General PCI + * Addresses are mapped 1-1. + */ +#define CFG_PCI1_MEM_BASE 0x80000000 +#define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE +#define CFG_PCI1_MEM_SIZE 0x10000000 /* 256M */ +#define CFG_PCI1_MMIO_BASE (CFG_PCI1_MEM_BASE + CFG_PCI1_MEM_SIZE) +#define CFG_PCI1_MMIO_PHYS CFG_PCI1_MMIO_BASE +#define CFG_PCI1_MMIO_SIZE 0x10000000 /* 256M */ +#define CFG_PCI1_IO_BASE 0x00000000 +#define CFG_PCI1_IO_PHYS 0xE2000000 +#define CFG_PCI1_IO_SIZE 0x01000000 /* 16M */ + +#ifdef CONFIG_MPC83XX_PCI2 +#define CFG_PCI2_MEM_BASE (CFG_PCI1_MMIO_BASE + CFG_PCI1_MMIO_SIZE) +#define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE +#define CFG_PCI2_MEM_SIZE 0x10000000 /* 256M */ +#define CFG_PCI2_MMIO_BASE (CFG_PCI2_MEM_BASE + CFG_PCI2_MEM_SIZE) +#define CFG_PCI2_MMIO_PHYS CFG_PCI2_MMIO_BASE +#define CFG_PCI2_MMIO_SIZE 0x10000000 /* 256M */ +#define CFG_PCI2_IO_BASE 0x00000000 +#define CFG_PCI2_IO_PHYS (CFG_PCI1_IO_PHYS + CFG_PCI1_IO_SIZE) +#define CFG_PCI2_IO_SIZE 0x01000000 /* 16M */ +#endif + +#define _IO_BASE 0x00000000 /* points to PCI I/O space */ + +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#ifdef CONFIG_RTL8139 +/* This macro is used by RTL8139 but not defined in PPC architecture */ +#define KSEG1ADDR(x) (x) +#endif + +#ifndef CONFIG_PCI_PNP + #define PCI_ENET0_IOADDR 0x00000000 + #define PCI_ENET0_MEMADDR CFG_PCI2_MEM_BASE + #define PCI_IDSEL_NUMBER 0x0f /* IDSEL = AD15 */ +#endif + +#define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ + +#endif + +/* TSEC */ + +#ifdef CONFIG_TSEC_ENET + +#ifndef CONFIG_NET_MULTI +#define CONFIG_NET_MULTI +#endif + +#define CONFIG_MII +#define CONFIG_PHY_GIGE /* In case CFG_CMD_MII is specified */ + +#define CONFIG_MPC83XX_TSEC1 + +#ifdef CONFIG_MPC83XX_TSEC1 +#define CONFIG_MPC83XX_TSEC1_NAME "TSEC0" +#define CFG_TSEC1_OFFSET 0x24000 +#define TSEC1_PHY_ADDR 0x1c /* VSC8201 uses address 0x1c */ +#define TSEC1_PHYIDX 0 +#endif + +#ifdef CONFIG_MPC83XX_TSEC2 +#define CONFIG_MPC83XX_TSEC2_NAME "TSEC1" +#define CFG_TSEC2_OFFSET 0x25000 +#define CONFIG_UNKNOWN_TSEC /* TSEC2 is proprietary */ +#define TSEC2_PHY_ADDR 4 +#define TSEC2_PHYIDX 0 +#endif + +#define CONFIG_ETHPRIME "Freescale TSEC" + +#endif + + +/* + * Environment + */ +#ifndef CFG_RAMBOOT + #define CFG_ENV_IS_IN_FLASH + #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) + #define CFG_ENV_SECT_SIZE 0x20000 /* 128K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 +#else + #define CFG_NO_FLASH /* Flash is not usable now */ + #define CFG_ENV_IS_NOWHERE /* Store ENV in memory only */ + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) + #define CFG_ENV_SIZE 0x2000 +#endif + +#define CONFIG_LOADS_ECHO /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE /* allow baudrate change */ + +/* CONFIG_COMMANDS */ + +#ifdef CONFIG_COMPACT_FLASH +#define CONFIG_COMMANDS_CF (CFG_CMD_IDE | CFG_CMD_FAT) +#else +#define CONFIG_COMMANDS_CF 0 +#endif + +#ifdef CONFIG_PCI +#define CONFIG_COMMANDS_PCI CFG_CMD_PCI +#else +#define CONFIG_COMMANDS_PCI 0 +#endif + +#ifdef CONFIG_HARD_I2C +#define CONFIG_COMMANDS_I2C CFG_CMD_I2C +#else +#define CONFIG_COMMANDS_I2C 0 +#endif + +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CONFIG_COMMANDS_CF | \ + CFG_CMD_NET | \ + CFG_CMD_PING | \ + CONFIG_COMMANDS_I2C | \ + CONFIG_COMMANDS_PCI | \ + CFG_CMD_SDRAM | \ + CFG_CMD_DATE | \ + CFG_CMD_CACHE | \ + CFG_CMD_IRQ) +#include <cmd_confdefs.h> + +/* Watchdog */ + +#undef CONFIG_WATCHDOG /* watchdog disabled */ +#ifdef CONFIG_WATCHDOG +#define CFG_WATCHDOG_VALUE 0xFFFFFFC3 +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_LOAD_ADDR 0x2000000 /* default load address */ +#define CFG_PROMPT "MPC8349E-mITX> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else + #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif + +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ + +/* Cache Configuration */ +#define CFG_DCACHE_SIZE 32768 +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /* log2 of the above value */ +#endif + +#define CFG_RCWH_PCIHOST 0x80000000 /* PCIHOST */ + +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_4X1 |\ + HRCWL_VCO_1X2 |\ + HRCWL_CORE_TO_CSB_2X1) + +#ifdef PCI_64BIT +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_64_BIT_PCI |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_PCI2_ARBITER_DISABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0X00000100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT |\ + HRCWH_TSEC1M_IN_GMII |\ + HRCWH_TSEC2M_IN_GMII ) +#else +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_32_BIT_PCI |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_PCI2_ARBITER_DISABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0XFFF00100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT |\ + HRCWH_TSEC1M_IN_GMII |\ + HRCWH_TSEC2M_IN_GMII ) +#endif + +/* System performance */ +#define CFG_ACR_PIPE_DEP 3 /* Arbiter pipeline depth (0-3) */ +#define CFG_ACR_RPTCNT 3 /* Arbiter repeat count (0-7) */ +#define CFG_SPCR_TSEC1EP 3 /* TSEC1 emergency priority (0-3) */ +#define CFG_SPCR_TSEC2EP 3 /* TSEC2 emergency priority (0-3) */ +#define CFG_SCCR_TSEC1CM 1 /* TSEC1 clock mode (0-3) */ +#define CFG_SCCR_TSEC2CM 1 /* TSEC2 & I2C0 clock mode (0-3) */ +#define CFG_ACR_RPTCNT 3 /* Arbiter repeat count */ + +/* System IO Config */ +#define CFG_SICRH SICRH_TSOBI1 /* Needed for gigabit to work on TSEC 1 */ +#define CFG_SICRL (SICRL_LDP_A | SICRL_USB1) + +#define CFG_HID0_INIT 0x000000000 + +#define CFG_HID0_FINAL CFG_HID0_INIT + +#define CFG_HID2 HID2_HBE + +/* DDR @ 0x00000000 */ +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) + +/* PCI @ 0x80000000 */ +#ifdef CONFIG_PCI +#define CFG_IBAT1L (CFG_PCI1_MEM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT1U (CFG_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_IBAT2L (CFG_PCI1_MMIO_BASE | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT2U (CFG_PCI1_MMIO_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#else +#define CFG_IBAT1L 0 +#define CFG_IBAT1U 0 +#define CFG_IBAT2L 0 +#define CFG_IBAT2U 0 +#endif + +#ifdef CONFIG_MPC83XX_PCI2 +#define CFG_IBAT3L (CFG_PCI2_MEM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT3U (CFG_PCI2_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_IBAT4L (CFG_PCI2_MMIO_BASE | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT4U (CFG_PCI2_MMIO_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#else +#define CFG_IBAT3L 0 +#define CFG_IBAT3U 0 +#define CFG_IBAT4L 0 +#define CFG_IBAT4U 0 +#endif + +/* IMMRBAR @ 0xE0000000, PCI IO @ 0xE2000000 & BCSR @ 0xE2400000 */ +#define CFG_IBAT5L (CFG_IMMR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT5U (CFG_IMMR | BATU_BL_256M | BATU_VS | BATU_VP) + +/* SDRAM @ 0xF0000000, stack in DCACHE 0xFDF00000 & FLASH @ 0xFE000000 */ +#define CFG_IBAT6L (0xF0000000 | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT6U (0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP) + +#define CFG_IBAT7L 0 +#define CFG_IBAT7U 0 + +#define CFG_DBAT0L CFG_IBAT0L +#define CFG_DBAT0U CFG_IBAT0U +#define CFG_DBAT1L CFG_IBAT1L +#define CFG_DBAT1U CFG_IBAT1U +#define CFG_DBAT2L CFG_IBAT2L +#define CFG_DBAT2U CFG_IBAT2U +#define CFG_DBAT3L CFG_IBAT3L +#define CFG_DBAT3U CFG_IBAT3U +#define CFG_DBAT4L CFG_IBAT4L +#define CFG_DBAT4U CFG_IBAT4U +#define CFG_DBAT5L CFG_IBAT5L +#define CFG_DBAT5U CFG_IBAT5U +#define CFG_DBAT6L CFG_IBAT6L +#define CFG_DBAT6U CFG_IBAT6U +#define CFG_DBAT7L CFG_IBAT7L +#define CFG_DBAT7U CFG_IBAT7U + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed of kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + + +/* + * Environment Configuration + */ +#define CONFIG_ENV_OVERWRITE + +#ifdef CONFIG_MPC83XX_TSEC1 +#define CONFIG_ETHADDR 00:E0:0C:00:8C:01 +#endif + +#ifdef CONFIG_MPC83XX_TSEC2 +#define CONFIG_HAS_ETH1 +#define CONFIG_ETH1ADDR 00:E0:0C:00:8C:02 +#endif + +#if 1 +#define CONFIG_IPADDR 10.82.19.159 +#define CONFIG_SERVERIP 10.82.48.106 +#define CONFIG_GATEWAYIP 10.82.19.254 +#define CONFIG_NETMASK 255.255.252.0 +#define CONFIG_NETDEV eth0 + +#define CONFIG_HOSTNAME mpc8349emitx +#define CONFIG_ROOTPATH /nfsroot0/u/timur/itx-ltib/rootfs +#define CONFIG_BOOTFILE timur/uImage + +#define CONFIG_UBOOTPATH timur/u-boot.bin +#else +#define CONFIG_IPADDR 192.168.1.253 +#define CONFIG_SERVERIP 192.168.1.1 +#define CONFIG_GATEWAYIP 192.168.1.1 +#define CONFIG_NETMASK 255.255.252.0 +#define CONFIG_NETDEV eth0 + +#define CONFIG_HOSTNAME mpc8349emitx +#define CONFIG_ROOTPATH /nfsroot/rootfs +#define CONFIG_BOOTFILE uImage + +#define CONFIG_UBOOTPATH u-boot.bin +#endif + +#define CONFIG_UBOOTSTART fe700000 +#define CONFIG_UBOOTEND fe77ffff + +#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */ + +#define CONFIG_BAUDRATE 115200 + +#undef CONFIG_BOOTCOMMAND +#ifdef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTDELAY 6 +#else +#define CONFIG_BOOTDELAY -1 /* -1 disables auto-boot */ +#endif + +#define XMK_STR(x) #x +#define MK_STR(x) XMK_STR(x) + +#define CONFIG_BOOTARGS \ + "root=/dev/nfs rw" \ + " nfsroot=" MK_STR(CONFIG_SERVERIP) ":" MK_STR(CONFIG_ROOTPATH) \ + " ip=" MK_STR(CONFIG_IPADDR) ":" MK_STR(CONFIG_SERVERIP) ":" \ + MK_STR(CONFIG_GATEWAYIP) ":" MK_STR(CONFIG_NETMASK) ":" \ + MK_STR(CONFIG_HOSTNAME) ":" MK_STR(CONFIG_NETDEV) ":off" \ + " console=ttyS0," MK_STR(CONFIG_BAUDRATE) + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=" MK_STR(CONFIG_NETDEV) "\0" \ + "tftpflash=tftpboot $loadaddr " MK_STR(CONFIG_UBOOTPATH) "; " \ + "erase " MK_STR(CONFIG_UBOOTSTART) " " MK_STR(CONFIG_UBOOTEND) "; " \ + "cp.b $loadaddr " MK_STR(CONFIG_UBOOTSTART) " $filesize; " \ + "cmp.b $loadaddr " MK_STR(CONFIG_UBOOTSTART) " $filesize\0" \ + "tftpupdate=tftpboot $loadaddr " MK_STR(CONFIG_UBOOTPATH) "; " \ + "protect off FEF00000 FEF7FFFF; " \ + "erase FEF00000 FEF7FFFF; " \ + "cp.b $loadaddr FEF00000 $filesize; " \ + "protect on FEF00000 FEF7FFFF; " \ + "cmp.b $loadaddr FEF00000 $filesize\0" \ + "tftplinux=tftpboot $loadaddr $bootfile; bootm\0" \ + "copyuboot=erase " MK_STR(CONFIG_UBOOTSTART) " " MK_STR(CONFIG_UBOOTEND) "; " \ + "cp.b fef00000 " MK_STR(CONFIG_UBOOTSTART) " 80000\0" \ + "fdtaddr=400000\0" \ + "fdtfile=mpc8349emitx.dtb\0" \ + "" + +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr - $fdtaddr" + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr" + + +#undef MK_STR +#undef XMK_STR + +#endif diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h new file mode 100644 index 0000000..8ad6551 --- /dev/null +++ b/include/configs/MPC8360EMDS.h @@ -0,0 +1,635 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. + * + * Dave Liu <daveliu@freescale.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#undef DEBUG + +/* + * High Level Configuration Options + */ +#define CONFIG_E300 1 /* E300 family */ +#define CONFIG_QE 1 /* Has QE */ +#define CONFIG_MPC83XX 1 /* MPC83XX family */ +#define CONFIG_MPC8360 1 /* MPC8360 CPU specific */ +#define CONFIG_MPC8360EMDS 1 /* MPC8360EMDS board specific */ + +/* + * System Clock Setup + */ +#ifdef CONFIG_PCISLAVE +#define CONFIG_83XX_PCICLK 66000000 /* in HZ */ +#else +#define CONFIG_83XX_CLKIN 66000000 /* in Hz */ +#endif + +#ifndef CONFIG_SYS_CLK_FREQ +#define CONFIG_SYS_CLK_FREQ 66000000 +#endif + +/* + * Hardware Reset Configuration Word + */ +#define CFG_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_1X1 |\ + HRCWL_CSB_TO_CLKIN_4X1 |\ + HRCWL_VCO_1X2 |\ + HRCWL_CE_PLL_VCO_DIV_4 |\ + HRCWL_CE_PLL_DIV_1X1 |\ + HRCWL_CE_TO_PLL_1X6 |\ + HRCWL_CORE_TO_CSB_2X1) + +#ifdef CONFIG_PCISLAVE +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_AGENT |\ + HRCWH_PCI1_ARBITER_DISABLE |\ + HRCWH_PCICKDRV_DISABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0XFFF00100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT) +#else +#define CFG_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_PCICKDRV_ENABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0X00000100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT) +#endif + +/* + * System IO Config + */ +#define CFG_SICRH 0x00000000 +#define CFG_SICRL 0x40000000 + +#define CONFIG_BOARD_EARLY_INIT_F /* call board_pre_init */ + +/* + * IMMR new address + */ +#define CFG_IMMR 0xE0000000 + +/* + * DDR Setup + */ +#define CFG_DDR_BASE 0x00000000 /* DDR is system memory */ +#define CFG_SDRAM_BASE CFG_DDR_BASE +#define CFG_DDR_SDRAM_BASE CFG_DDR_BASE + +#define CFG_83XX_DDR_USES_CS0 + +#undef CONFIG_DDR_ECC /* only for ECC DDR module */ +#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ + +#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ +#if defined(CONFIG_SPD_EEPROM) +/* + * Determine DDR configuration from I2C interface. + */ +#define SPD_EEPROM_ADDRESS 0x52 /* DDR SODIMM */ +#else +/* + * Manually set up DDR parameters + */ +#define CFG_DDR_SIZE 256 /* MB */ +#define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_9) +#define CFG_DDR_TIMING_1 0x37344321 /* tCL-tRCD-tRP-tRAS=2.5-3-3-7 */ +#define CFG_DDR_TIMING_2 0x00000800 /* may need tuning */ +#define CFG_DDR_CONTROL 0x42008000 /* Self refresh,2T timing */ +#define CFG_DDR_MODE 0x20000162 /* DLL,normal,seq,4/2.5 */ +#define CFG_DDR_INTERVAL 0x045b0100 /* page mode */ +#endif + +/* + * Memory test + */ +#undef CFG_DRAM_TEST /* memory test, takes time */ +#define CFG_MEMTEST_START 0x00000000 /* memtest region */ +#define CFG_MEMTEST_END 0x00100000 + +/* + * The reserved memory + */ + +#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ + +#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) +#define CFG_RAMBOOT +#else +#undef CFG_RAMBOOT +#endif + +#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CFG_MALLOC_LEN (128 * 1024) /* Reserved for malloc */ + +/* + * Initial RAM Base Address Setup + */ +#define CFG_INIT_RAM_LOCK 1 +#define CFG_INIT_RAM_ADDR 0xE6000000 /* Initial RAM address */ +#define CFG_INIT_RAM_END 0x1000 /* End of used area in RAM */ +#define CFG_GBL_DATA_SIZE 0x100 /* num bytes initial data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) + +/* + * Local Bus Configuration & Clock Setup + */ +#define CFG_LCRR (LCRR_DBYP | LCRR_CLKDIV_4) +#define CFG_LBC_LBCR 0x00000000 + +/* + * FLASH on the Local Bus + */ +#define CFG_FLASH_CFI /* use the Common Flash Interface */ +#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ +#define CFG_FLASH_SIZE 16 /* FLASH size is 16M */ + +#define CFG_LBLAWBAR0_PRELIM CFG_FLASH_BASE /* Window base at flash base */ +#define CFG_LBLAWAR0_PRELIM 0x80000018 /* 32MB window size */ + +#define CFG_BR0_PRELIM (CFG_FLASH_BASE | /* Flash Base address */ \ + (2 << BR_PS_SHIFT) | /* 16 bit port size */ \ + BR_V) /* valid */ +#define CFG_OR0_PRELIM 0xfe006ff7 /* 16MB Flash size */ + +#define CFG_MAX_FLASH_BANKS 1 /* number of banks */ +#define CFG_MAX_FLASH_SECT 128 /* sectors per device */ + +#undef CFG_FLASH_CHECKSUM + +/* + * BCSR on the Local Bus + */ +#define CFG_BCSR 0xF8000000 +#define CFG_LBLAWBAR1_PRELIM CFG_BCSR /* Access window base at BCSR base */ +#define CFG_LBLAWAR1_PRELIM 0x8000000E /* Access window size 32K */ + +#define CFG_BR1_PRELIM (CFG_BCSR|0x00000801) /* Port size=8bit, MSEL=GPCM */ +#define CFG_OR1_PRELIM 0xFFFFE9f7 /* length 32K */ + +/* + * SDRAM on the Local Bus + */ +#define CFG_LBC_SDRAM_BASE 0xF0000000 /* SDRAM base address */ +#define CFG_LBC_SDRAM_SIZE 64 /* LBC SDRAM is 64MB */ + +#define CFG_LB_SDRAM /* if board has SRDAM on local bus */ + +#ifdef CFG_LB_SDRAM +#define CFG_LBLAWBAR2_PRELIM CFG_LBC_SDRAM_BASE +#define CFG_LBLAWAR2_PRELIM 0x80000019 /* 64MB */ + +/*local bus BR2, OR2 definition for SDRAM if soldered on the EPB board */ +/* + * Base Register 2 and Option Register 2 configure SDRAM. + * The SDRAM base address, CFG_LBC_SDRAM_BASE, is 0xf0000000. + * + * For BR2, need: + * Base address of 0xf0000000 = BR[0:16] = 1111 0000 0000 0000 0 + * port size = 32-bits = BR2[19:20] = 11 + * no parity checking = BR2[21:22] = 00 + * SDRAM for MSEL = BR2[24:26] = 011 + * Valid = BR[31] = 1 + * + * 0 4 8 12 16 20 24 28 + * 1111 0000 0000 0000 0001 1000 0110 0001 = f0001861 + * + * CFG_LBC_SDRAM_BASE should be masked and OR'ed into + * the top 17 bits of BR2. + */ + +#define CFG_BR2_PRELIM 0xf0001861 /*Port size=32bit, MSEL=SDRAM */ + +/* + * The SDRAM size in MB, CFG_LBC_SDRAM_SIZE, is 64. + * + * For OR2, need: + * 64MB mask for AM, OR2[0:7] = 1111 1100 + * XAM, OR2[17:18] = 11 + * 9 columns OR2[19-21] = 010 + * 13 rows OR2[23-25] = 100 + * EAD set for extra time OR[31] = 1 + * + * 0 4 8 12 16 20 24 28 + * 1111 1100 0000 0000 0110 1001 0000 0001 = fc006901 + */ + +#define CFG_OR2_PRELIM 0xfc006901 + +#define CFG_LBC_LSRT 0x32000000 /* LB sdram refresh timer, about 6us */ +#define CFG_LBC_MRTPR 0x20000000 /* LB refresh timer prescal, 266MHz/32 */ + +/* + * LSDMR masks + */ +#define CFG_LBC_LSDMR_OP_NORMAL (0 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ARFRSH (1 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_SRFRSH (2 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_MRW (3 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PRECH (4 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_PCHALL (5 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_ACTBNK (6 << (31 - 4)) +#define CFG_LBC_LSDMR_OP_RWINV (7 << (31 - 4)) + +#define CFG_LBC_LSDMR_COMMON 0x0063b723 + +/* + * SDRAM Controller configuration sequence. + */ +#define CFG_LBC_LSDMR_1 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_PCHALL) +#define CFG_LBC_LSDMR_2 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_3 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_ARFRSH) +#define CFG_LBC_LSDMR_4 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_MRW) +#define CFG_LBC_LSDMR_5 ( CFG_LBC_LSDMR_COMMON \ + | CFG_LBC_LSDMR_OP_NORMAL) + +#endif + +/* + * Windows to access PIB via local bus + */ +#define CFG_LBLAWBAR3_PRELIM 0xf8008000 /* windows base 0xf8008000 */ +#define CFG_LBLAWAR3_PRELIM 0x8000000f /* windows size 64KB */ + +/* + * CS4 on Local Bus, to PIB + */ +#define CFG_BR4_PRELIM 0xf8008801 /* CS4 base address at 0xf8008000 */ +#define CFG_OR4_PRELIM 0xffffe9f7 /* size 32KB, port size 8bit, GPCM */ + +/* + * CS5 on Local Bus, to PIB + */ +#define CFG_BR5_PRELIM 0xf8010801 /* CS5 base address at 0xf8010000 */ +#define CFG_OR5_PRELIM 0xffffe9f7 /* size 32KB, port size 8bit, GPCM */ + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#undef CONFIG_SERIAL_SOFTWARE_FIFO +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE 1 +#define CFG_NS16550_CLK get_bus_freq(0) + +#define CFG_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} + +#define CFG_NS16550_COM1 (CFG_IMMR+0x4500) +#define CFG_NS16550_COM2 (CFG_IMMR+0x4600) + +/* Use the HUSH parser */ +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + +/* pass open firmware flat tree */ +#define CONFIG_OF_FLAT_TREE 1 +#define CONFIG_OF_BOARD_SETUP 1 + +/* maximum size of the flat tree (8K) */ +#define OF_FLAT_TREE_MAX_SIZE 8192 + +#define OF_CPU "PowerPC,8360@0" +#define OF_SOC "soc8360@e0000000" +#define OF_TBCLK (bd->bi_busfreq / 4) +#define OF_STDOUT_PATH "/soc8360@e0000000/serial@4500" + +/* I2C */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CONFIG_FSL_I2C +#define CFG_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F +#define CFG_I2C_NOPROBES {0x52} /* Don't probe these addrs */ +#define CFG_I2C_OFFSET 0x3000 +#define CFG_I2C2_OFFSET 0x3100 + +/* + * Config on-board RTC + */ +#define CONFIG_RTC_DS1374 /* use ds1374 rtc via i2c */ +#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */ + +/* + * General PCI + * Addresses are mapped 1-1. + */ +#define CFG_PCI_MEM_BASE 0x80000000 +#define CFG_PCI_MEM_PHYS CFG_PCI_MEM_BASE +#define CFG_PCI_MEM_SIZE 0x10000000 /* 256M */ +#define CFG_PCI_MMIO_BASE 0x90000000 +#define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE +#define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ +#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_PHYS 0xE0300000 +#define CFG_PCI_IO_SIZE 0x100000 /* 1M */ + +#define CFG_PCI_SLV_MEM_LOCAL CFG_SDRAM_BASE +#define CFG_PCI_SLV_MEM_BUS 0x00000000 +#define CFG_PCI_SLV_MEM_SIZE 0x80000000 + + +#ifdef CONFIG_PCI + +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#undef CONFIG_EEPRO100 +#undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ +#define CFG_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ + +#endif /* CONFIG_PCI */ + + +#ifndef CONFIG_NET_MULTI +#define CONFIG_NET_MULTI 1 +#endif + +/* + * QE UEC ethernet configuration + */ +#define CONFIG_UEC_ETH +#define CONFIG_ETHPRIME "Freescale GETH" +#define CONFIG_PHY_MODE_NEED_CHANGE + +#define CONFIG_UEC_ETH1 /* GETH1 */ + +#ifdef CONFIG_UEC_ETH1 +#define CFG_UEC1_UCC_NUM 0 /* UCC1 */ +#define CFG_UEC1_RX_CLK QE_CLK_NONE +#define CFG_UEC1_TX_CLK QE_CLK9 +#define CFG_UEC1_ETH_TYPE GIGA_ETH +#define CFG_UEC1_PHY_ADDR 0 +#define CFG_UEC1_INTERFACE_MODE ENET_1000_GMII +#endif + +#define CONFIG_UEC_ETH2 /* GETH2 */ + +#ifdef CONFIG_UEC_ETH2 +#define CFG_UEC2_UCC_NUM 1 /* UCC2 */ +#define CFG_UEC2_RX_CLK QE_CLK_NONE +#define CFG_UEC2_TX_CLK QE_CLK4 +#define CFG_UEC2_ETH_TYPE GIGA_ETH +#define CFG_UEC2_PHY_ADDR 1 +#define CFG_UEC2_INTERFACE_MODE ENET_1000_GMII +#endif + +/* + * Environment + */ + +#ifndef CFG_RAMBOOT + #define CFG_ENV_IS_IN_FLASH 1 + #define CFG_ENV_ADDR (CFG_MONITOR_BASE + 0x40000) + #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */ + #define CFG_ENV_SIZE 0x2000 +#else + #define CFG_NO_FLASH 1 /* Flash is not usable now */ + #define CFG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ + #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) + #define CFG_ENV_SIZE 0x2000 +#endif + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +#if defined(CFG_RAMBOOT) +#if defined(CONFIG_PCI) +#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_ASKENV \ + | CFG_CMD_PCI \ + | CFG_CMD_I2C) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_LOADS)) +#else +#define CONFIG_COMMANDS ((CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_ASKENV \ + | CFG_CMD_I2C) \ + & \ + ~(CFG_CMD_ENV \ + | CFG_CMD_LOADS)) +#endif +#else +#if defined(CONFIG_PCI) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PCI \ + | CFG_CMD_PING \ + | CFG_CMD_ASKENV \ + | CFG_CMD_I2C) +#else +#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ + | CFG_CMD_PING \ + | CFG_CMD_ASKENV \ + | CFG_CMD_I2C ) +#endif +#endif + +#include <cmd_confdefs.h> + +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_LOAD_ADDR 0x2000000 /* default load address */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else + #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif + +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/* + * Core HID Setup + */ +#define CFG_HID0_INIT 0x000000000 +#define CFG_HID0_FINAL HID0_ENABLE_MACHINE_CHECK +#define CFG_HID2 HID2_HBE + +/* + * Cache Config + */ +#define CFG_DCACHE_SIZE 32768 +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value */ +#endif + +/* + * MMU Setup + */ + +/* DDR: cache cacheable */ +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT0L CFG_IBAT0L +#define CFG_DBAT0U CFG_IBAT0U + +/* IMMRBAR & PCI IO: cache-inhibit and guarded */ +#define CFG_IBAT1L (CFG_IMMR | BATL_PP_10 | \ + BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT1U (CFG_IMMR | BATU_BL_4M | BATU_VS | BATU_VP) +#define CFG_DBAT1L CFG_IBAT1L +#define CFG_DBAT1U CFG_IBAT1U + +/* BCSR: cache-inhibit and guarded */ +#define CFG_IBAT2L (CFG_BCSR | BATL_PP_10 | \ + BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT2U (CFG_BCSR | BATU_BL_128K | BATU_VS | BATU_VP) +#define CFG_DBAT2L CFG_IBAT2L +#define CFG_DBAT2U CFG_IBAT2U + +/* FLASH: icache cacheable, but dcache-inhibit and guarded */ +#define CFG_IBAT3L (CFG_FLASH_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT3U (CFG_FLASH_BASE | BATU_BL_32M | BATU_VS | BATU_VP) +#define CFG_DBAT3L (CFG_FLASH_BASE | BATL_PP_10 | \ + BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT3U CFG_IBAT3U + +/* Local bus SDRAM: cacheable */ +#define CFG_IBAT4L (CFG_LBC_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT4U (CFG_LBC_SDRAM_BASE | BATU_BL_64M | BATU_VS | BATU_VP) +#define CFG_DBAT4L CFG_IBAT4L +#define CFG_DBAT4U CFG_IBAT4U + +/* Stack in dcache: cacheable, no memory coherence */ +#define CFG_IBAT5L (CFG_INIT_RAM_ADDR | BATL_PP_10) +#define CFG_IBAT5U (CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP) +#define CFG_DBAT5L CFG_IBAT5L +#define CFG_DBAT5U CFG_IBAT5U + +#ifdef CONFIG_PCI +/* PCI MEM space: cacheable */ +#define CFG_IBAT6L (CFG_PCI_MEM_PHYS | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT6U (CFG_PCI_MEM_PHYS | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT6L CFG_IBAT6L +#define CFG_DBAT6U CFG_IBAT6U +/* PCI MMIO space: cache-inhibit and guarded */ +#define CFG_IBAT7L (CFG_PCI_MMIO_PHYS | BATL_PP_10 | \ + BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT7U (CFG_PCI_MMIO_PHYS | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT7L CFG_IBAT7L +#define CFG_DBAT7U CFG_IBAT7U +#else +#define CFG_IBAT6L (0) +#define CFG_IBAT6U (0) +#define CFG_IBAT7L (0) +#define CFG_IBAT7U (0) +#define CFG_DBAT6L CFG_IBAT6L +#define CFG_DBAT6U CFG_IBAT6U +#define CFG_DBAT7L CFG_IBAT7L +#define CFG_DBAT7U CFG_IBAT7U +#endif + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed of kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/* + * Environment Configuration + */ + +#define CONFIG_ENV_OVERWRITE + +#if defined(CONFIG_UEC_ETH) +#define CONFIG_ETHADDR 00:04:9f:ef:01:01 +#define CONFIG_HAS_ETH1 +#define CONFIG_ETH1ADDR 00:04:9f:ef:01:02 +#endif + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */ + +#define CONFIG_BOOTDELAY 6 /* -1 disables auto-boot */ +#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "consoledev=ttyS0\0" \ + "ramdiskaddr=1000000\0" \ + "ramdiskfile=ramfs.83xx\0" \ + "fdtaddr=400000\0" \ + "fdtfile=mpc8349emds.dtb\0" \ + "" + +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr - $fdtaddr" + +#define CONFIG_RAMBOOTCOMMAND \ + "setenv bootargs root=/dev/ram rw " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp $ramdiskaddr $ramdiskfile;" \ + "tftp $loadaddr $bootfile;" \ + "tftp $fdtaddr $fdtfile;" \ + "bootm $loadaddr $ramdiskaddr $fdtaddr" + + +#define CONFIG_BOOTCOMMAND CONFIG_NFSBOOTCOMMAND + +#endif /* __CONFIG_H */ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 4bbee97..728083b 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -37,10 +37,11 @@ #define CONFIG_E300 1 /* E300 Family */ #define CONFIG_MPC83XX 1 /* MPC83XX family */ #define CONFIG_MPC834X 1 /* MPC834X specific */ +#define CONFIG_MPC8349 1 /* MPC8349 specific */ #define CONFIG_TQM834X 1 /* TQM834X board specific */ /* IMMR Base Addres Register, use Freescale default: 0xff400000 */ -#define CFG_IMMRBAR 0xff400000 +#define CFG_IMMR 0xff400000 /* System clock. Primary input clock when in PCI host mode */ #define CONFIG_83XX_CLKIN 66666000 /* 66,666 MHz */ @@ -56,6 +57,17 @@ */ #define CFG_LCRR (LCRR_DBYP | LCRR_CLKDIV_8) +#define CFG_SCCR_INIT (SCCR_DEFAULT & (~SCCR_CLK_MASK)) +#define CFG_SCCR_TSEC1CM SCCR_TSEC1CM_1 /* TSEC1 clock setting */ +#define CFG_SCCR_TSEC2CM SCCR_TSEC2CM_1 /* TSEC2 clock setting */ +#define CFG_SCCR_ENCCM SCCR_ENCCM_3 /* ENC clock setting */ +#define CFG_SCCR_USBCM SCCR_USBCM_3 /* USB clock setting */ +#define CFG_SCCR_VAL ( CFG_SCCR_INIT \ + | CFG_SCCR_TSEC1CM \ + | CFG_SCCR_TSEC2CM \ + | CFG_SCCR_ENCCM \ + | CFG_SCCR_USBCM ) + /* board pre init: do not call, nothing to do */ #undef CONFIG_BOARD_EARLY_INIT_F @@ -83,6 +95,7 @@ #define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ #undef CFG_FLASH_CHECKSUM #define CFG_FLASH_BASE 0x80000000 /* start of FLASH */ +#define CFG_FLASH_SIZE 8 /* FLASH size in MB */ /* buffered writes in the AMD chip set is not supported yet */ #undef CFG_FLASH_USE_BUFFER_WRITE @@ -197,14 +210,15 @@ extern int tqm834x_num_flash_banks; #define CFG_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} -#define CFG_NS16550_COM1 (CFG_IMMRBAR + 0x4500) -#define CFG_NS16550_COM2 (CFG_IMMRBAR + 0x4600) +#define CFG_NS16550_COM1 (CFG_IMMR + 0x4500) +#define CFG_NS16550_COM2 (CFG_IMMR + 0x4600) /* * I2C */ #define CONFIG_HARD_I2C /* I2C with hardware support */ #undef CONFIG_SOFT_I2C /* I2C bit-banged */ +#define CONFIG_FSL_I2C #define CFG_I2C_SPEED 400000 /* I2C speed: 400KHz */ #define CFG_I2C_SLAVE 0x7F /* slave address */ #define CFG_I2C_OFFSET 0x3000 @@ -235,9 +249,9 @@ extern int tqm834x_num_flash_banks; #define CONFIG_MII #define CFG_TSEC1_OFFSET 0x24000 -#define CFG_TSEC1 (CFG_IMMRBAR + CFG_TSEC1_OFFSET) +#define CFG_TSEC1 (CFG_IMMR + CFG_TSEC1_OFFSET) #define CFG_TSEC2_OFFSET 0x25000 -#define CFG_TSEC2 (CFG_IMMRBAR + CFG_TSEC2_OFFSET) +#define CFG_TSEC2 (CFG_IMMR + CFG_TSEC2_OFFSET) #if defined(CONFIG_TSEC_ENET) @@ -460,8 +474,8 @@ extern int tqm834x_num_flash_banks; #endif /* IMMRBAR */ -#define CFG_IBAT6L (CFG_IMMRBAR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CFG_IBAT6U (CFG_IMMRBAR | BATU_BL_1M | BATU_VS | BATU_VP) +#define CFG_IBAT6L (CFG_IMMR | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_IBAT6U (CFG_IMMR | BATU_BL_1M | BATU_VS | BATU_VP) /* FLASH */ #define CFG_IBAT7L (CFG_FLASH_BASE | BATL_PP_10 | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) diff --git a/include/configs/p3mx.h b/include/configs/p3mx.h new file mode 100644 index 0000000..262e9d6 --- /dev/null +++ b/include/configs/p3mx.h @@ -0,0 +1,450 @@ +/* + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * Based on original work by + * Roel Loeffen, (C) Copyright 2006 Prodrive B.V. + * + * 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.h - configuration for Prodrive P3M750 & P3M7448 boards + * + * The defines: + * CONFIG_P3M750 or + * CONFIG_P3M7448 + * are written into include/config.h by the "make xxx_config" command + ***********************************************************************/ +#ifndef __CONFIG_H +#define __CONFIG_H + +/*----------------------------------------------------------------------- + * High Level Configuration Options + *----------------------------------------------------------------------*/ +#define CONFIG_P3Mx /* used for both board versions */ + +#if defined (CONFIG_P3M750) +#define CONFIG_750FX /* 750GL/GX/FX */ +#define CFG_BOARD_NAME "P3M750" +#define CFG_BUS_HZ 100000000 +#define CFG_BUS_CLK CFG_BUS_HZ +#define CFG_TCLK 100000000 +#elif defined (CONFIG_P3M7448) +#define CONFIG_74xx +#define CFG_BOARD_NAME "P3M7448" +#define CFG_BUS_HZ 133333333 +#define CFG_BUS_CLK CFG_BUS_HZ +#define CFG_TCLK 133333333 +#endif +#define CFG_GT_DUAL_CPU /* also for JTAG even with one cpu */ + +/* which initialization functions to call for this board */ +#define CFG_BOARD_ASM_INIT 1 +#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ +#define CONFIG_BOARD_EARLY_INIT_R 1 /* Call board_early_init_f */ +#define CONFIG_MISC_INIT_R 1 /* Call misc_init_r() */ +#define CONFIG_ADD_RAM_INFO 1 /* Print additional info */ + +/*----------------------------------------------------------------------- + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + *----------------------------------------------------------------------*/ +#define CFG_SDRAM_BASE 0x00000000 +#ifdef CONFIG_P3M750 +#define CFG_SDRAM1_BASE 0x10000000 /* each 256 MByte */ +#endif + +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#if defined (CONFIG_P3M750) +#define CFG_FLASH_BASE 0xff800000 /* start of flash banks */ +#define CFG_BOOT_SIZE _8M /* boot flash */ +#elif defined (CONFIG_P3M7448) +#define CFG_FLASH_BASE 0xff000000 /* start of flash banks */ +#define CFG_BOOT_SIZE _16M /* boot flash */ +#endif +#define CFG_BOOT_SPACE CFG_FLASH_BASE /* BOOT_CS0 flash 0 */ +#define CFG_MONITOR_BASE 0xfff00000 +#define CFG_RESET_ADDRESS 0xfff00100 +#define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc */ +#define CFG_MISC_REGION_BASE 0xf0000000 + +#define CFG_DFL_GT_REGS 0xf1000000 /* boot time GT_REGS */ +#define CFG_GT_REGS 0xf1000000 /* GT Registers are mapped here */ +#define CFG_INT_SRAM_BASE 0x42000000 /* GT offers 256k internal SRAM */ + +/*----------------------------------------------------------------------- + * Initial RAM & stack pointer (placed in internal SRAM) + *----------------------------------------------------------------------*/ + /* + * When locking data in cache you should point the CFG_INIT_RAM_ADDRESS + * To an unused memory region. The stack will remain in cache until RAM + * is initialized +*/ +#undef CFG_INIT_RAM_LOCK +#define CFG_INIT_RAM_ADDR 0x42000000 +#define CFG_INIT_RAM_END 0x1000 +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for init data */ +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) + + +/*----------------------------------------------------------------------- + * Serial Port + *----------------------------------------------------------------------*/ +#define CONFIG_MPSC /* MV64460 Serial */ +#define CONFIG_MPSC_PORT 0 +#define CONFIG_BAUDRATE 115200 /* console baudrate */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/*----------------------------------------------------------------------- + * Ethernet + *----------------------------------------------------------------------*/ +/* Change the default ethernet port, use this define (options: 0, 1, 2) */ +#define CFG_ETH_PORT ETH_0 +#define CONFIG_NET_MULTI +#define MV_ETH_DEVS 2 +#define CONFIG_PHY_RESET 1 /* reset phy upon startup */ +#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ + +/*----------------------------------------------------------------------- + * FLASH related + *----------------------------------------------------------------------*/ +#define CFG_FLASH_CFI /* The flash is CFI compatible */ +#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */ +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ +#define CFG_FLASH_PROTECTION 1 /* use hardware flash protection */ +#define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ + +#define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */ +#if defined (CONFIG_P3M750) +#define CFG_ENV_SECT_SIZE 0x20000 /* one sector (1 device)*/ +#elif defined (CONFIG_P3M7448) +#define CFG_ENV_SECT_SIZE 0x40000 /* two sectors (2 devices parallel */ +#endif +#define CFG_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ +#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) + +/*----------------------------------------------------------------------- + * DDR SDRAM + *----------------------------------------------------------------------*/ +#define CONFIG_MV64460_ECC + +/*----------------------------------------------------------------------- + * I2C + *----------------------------------------------------------------------*/ +#define CFG_I2C_SPEED 100000 /* I2C speed default */ + +/* I2C RTC */ +#define CONFIG_RTC_M41T11 1 +#define CFG_I2C_RTC_ADDR 0x68 +#define CFG_M41T11_BASE_YEAR 1900 /* play along with linux */ + +/*----------------------------------------------------------------------- + * PCI stuff + *----------------------------------------------------------------------*/ +#define PCI_HOST_ADAPTER 0 /* configure ar pci adapter */ +#define PCI_HOST_FORCE 1 /* configure as pci host */ +#define PCI_HOST_AUTO 2 /* detected via arbiter enable */ + +#define CONFIG_PCI /* include pci support */ +#define CONFIG_PCI_HOST PCI_HOST_FORCE /* select pci host function */ +#define CONFIG_PCI_PNP /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW /* show devices on bus */ + +/* PCI MEMORY MAP section */ +#define CFG_PCI0_MEM_BASE 0x80000000 +#define CFG_PCI0_MEM_SIZE _128M +#define CFG_PCI1_MEM_BASE 0x88000000 +#define CFG_PCI1_MEM_SIZE _128M + +#define CFG_PCI0_0_MEM_SPACE (CFG_PCI0_MEM_BASE) +#define CFG_PCI1_0_MEM_SPACE (CFG_PCI1_MEM_BASE) + +/* PCI I/O MAP section */ +#define CFG_PCI0_IO_BASE 0xfa000000 +#define CFG_PCI0_IO_SIZE _16M +#define CFG_PCI1_IO_BASE 0xfb000000 +#define CFG_PCI1_IO_SIZE _16M + +#define CFG_PCI0_IO_SPACE (CFG_PCI0_IO_BASE) +#define CFG_PCI0_IO_SPACE_PCI 0x00000000 +#define CFG_PCI1_IO_SPACE (CFG_PCI1_IO_BASE) +#define CFG_PCI1_IO_SPACE_PCI 0x00000000 + +#define CFG_ISA_IO_BASE_ADDRESS (CFG_PCI0_IO_BASE) + +#define CFG_PCI_IDSEL 0x30 + +#undef CONFIG_BOOTARGS +#define CONFIG_EXTRA_ENV_SETTINGS_COMMON \ + "netdev=eth0\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath}\0" \ + "ramargs=setenv bootargs root=/dev/ram rw\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ + ":${hostname}:${netdev}:off panic=1\0" \ + "addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\ + "flash_nfs=run nfsargs addip addtty;" \ + "bootm ${kernel_addr}\0" \ + "flash_self=run ramargs addip addtty;" \ + "bootm ${kernel_addr} ${ramdisk_addr}\0" \ + "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \ + "bootm\0" \ + "rootpath=/opt/eldk/ppc_6xx\0" \ + "u-boot=p3mx/u-boot/u-boot.bin\0" \ + "load=tftp 100000 ${u-boot}\0" \ + "update=protect off fff00000 fff3ffff;era fff00000 fff3ffff;" \ + "cp.b 100000 fff00000 40000;" \ + "setenv filesize;saveenv\0" \ + "upd=run load;run update\0" \ + "serverip=11.0.0.152\0" + +#if defined (CONFIG_P3M750) +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_EXTRA_ENV_SETTINGS_COMMON \ + "hostname=p3m750\0" \ + "bootfile=/tftpboot/p3mx/vxWorks.st\0" \ + "kernel_addr=fc000000\0" \ + "ramdisk_addr=fc180000\0" \ + "vxfile=p3m750/vxWorks\0" \ + "vxuser=ddg\0" \ + "vxpass=ddg\0" \ + "vxtarget=target\0" \ + "vxflags=0x8\0" \ + "vxargs=setenv bootargs mgi(0,0)host:${vxfile} h=${serverip} " \ + "e=${ipaddr} u=${vxuser} pw=${vxpass} tn=${vxtarget} " \ + "f=${vxflags}\0" +#elif defined (CONFIG_P3M7448) +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_EXTRA_ENV_SETTINGS_COMMON \ + "hostname=p3m7448\0" +#endif + +#if defined (CONFIG_P3M750) +#define CONFIG_BOOTCOMMAND "tftp;run vxargs;bootvx" +#elif defined (CONFIG_P3M7448) +#define CONFIG_BOOTCOMMAND " " +#endif + +#define CONFIG_BOOTDELAY 3 /* autoboot after 5 seconds */ +#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | \ + CONFIG_BOOTP_BOOTFILESIZE) +#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ + CFG_CMD_ASKENV | \ + CFG_CMD_DATE | \ + CFG_CMD_DIAG | \ + CFG_CMD_ELF | \ + CFG_CMD_I2C | \ + CFG_CMD_IRQ | \ + CFG_CMD_MII | \ + CFG_CMD_NET | \ + CFG_CMD_NFS | \ + CFG_CMD_PING | \ + CFG_CMD_REGINFO | \ + CFG_CMD_PCI | \ + CFG_CMD_CACHE | \ + CFG_CMD_SDRAM) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +/*----------------------------------------------------------------------- + * Miscellaneous configurable options + *----------------------------------------------------------------------*/ +#define CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " + +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ + +#define CFG_LOAD_ADDR 0x08000000 /* default load address */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_LOOPW 1 /* enable loopw command */ +#define CONFIG_MX_CYCLIC 1 /* enable mdc/mwc commands */ +#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */ +#define CONFIG_VERSION_VARIABLE 1 /* include version env variable */ + +/*----------------------------------------------------------------------- + * Marvell MV64460 config settings + *----------------------------------------------------------------------*/ +/* Reset values for Port behavior (8bit/ 32bit, etc.) only corrected device width */ +#if defined (CONFIG_P3M750) +#define CFG_BOOT_PAR 0x8FDFF87F /* 16 bit flash, disable burst*/ +#elif defined (CONFIG_P3M7448) +#define CFG_BOOT_PAR 0x8FEFFFFF /* 32 bit flash, burst enabled */ +#endif + +/* + * MPP[0] Serial Port 0 TxD TxD OUT Connected to P14 (buffered) + * MPP[1] Serial Port 0 RxD RxD IN Connected to P14 (buffered) + * MPP[2] NC + * MPP[3] Serial Port 1 TxD TxD OUT Connected to P14 (buffered) + * MPP[4] PCI Monarch# GPIO IN Connected to P12 + * MPP[5] Serial Port 1 RxD RxD IN Connected to P14 (buffered) + * MPP[6] PMC Carrier Interrupt 0 Int IN Connected to P14 + * MPP[7] PMC Carrier Interrupt 1 Int IN Connected to P14 + * MPP[8] Reserved Do not use + * MPP[9] Reserved Do not use + * MPP[10] Reserved Do not use + * MPP[11] Reserved Do not use + * MPP[12] Phy 0 Interrupt Int IN + * MPP[13] Phy 1 Interrupt Int IN + * MPP[14] NC + * MPP[15] NC + * MPP[16] PCI Interrupt C Int IN Connected to P11 + * MPP[17] PCI Interrupt D Int IN Connected to P11 + * MPP[18] Watchdog NMI# GPIO IN Connected to MPP[24] + * MPP[19] Watchdog Expired# WDE OUT Connected to rst logic + * MPP[20] Watchdog Status WD_STS IN Read back of rst by watchdog + * MPP[21] NC + * MPP[22] GP LED Green GPIO OUT + * MPP[23] GP LED Red GPIO OUT + * MPP[24] Watchdog NMI# Int OUT + * MPP[25] NC + * MPP[26] NC + * MPP[27] PCI Interrupt A Int IN Connected to P11 + * MPP[28] NC + * MPP[29] PCI Interrupt B Int IN Connected to P11 + * MPP[30] Module reset GPIO OUT Board reset + * MPP[31] PCI EReady GPIO IN Connected to P12 + */ +#define CFG_MPP_CONTROL_0 0x00303022 +#define CFG_MPP_CONTROL_1 0x00000000 +#define CFG_MPP_CONTROL_2 0x00004000 +#define CFG_MPP_CONTROL_3 0x00000004 +#define CFG_GPP_LEVEL_CONTROL 0x280730D0 + +/*---------------------------------------------------------------------- + * Initial BAT mappings + */ + +/* NOTES: + * 1) GUARDED and WRITE_THRU not allowed in IBATS + * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT + */ +/* SDRAM */ +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT0L (CFG_SDRAM_BASE | BATL_PP_RW | BATL_GUARDEDSTORAGE | BATL_CACHEINHIBIT) +#define CFG_DBAT0U CFG_IBAT0U + +/* init ram */ +#define CFG_IBAT1L (CFG_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE) +#define CFG_IBAT1U (CFG_INIT_RAM_ADDR | BATU_BL_256K | BATU_VS | BATU_VP) +#define CFG_DBAT1L CFG_IBAT1L +#define CFG_DBAT1U CFG_IBAT1U + +/* PCI0, PCI1 in one BAT */ +#define CFG_IBAT2L BATL_NO_ACCESS +#define CFG_IBAT2U CFG_DBAT2U +#define CFG_DBAT2L (CFG_PCI0_MEM_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE) +#define CFG_DBAT2U (CFG_PCI0_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) + +/* GT regs, bootrom, all the devices, PCI I/O */ +#define CFG_IBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW) +#define CFG_IBAT3U (CFG_MISC_REGION_BASE | BATU_VS | BATU_VP | BATU_BL_256M) +#define CFG_DBAT3L (CFG_MISC_REGION_BASE | BATL_CACHEINHIBIT | BATL_PP_RW | BATL_GUARDEDSTORAGE) +#define CFG_DBAT3U CFG_IBAT3U + +#define CFG_IBAT4L (CFG_SDRAM1_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT4U (CFG_SDRAM1_BASE | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT4L (CFG_SDRAM1_BASE | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT4U CFG_IBAT4U + +/* set rest out of range for Linux !!!!!!!!!!! */ + +/* IBAT5 and DBAT5 */ +#define CFG_IBAT5L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT5U (0x20000000 | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT5L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT5U CFG_IBAT5U + +/* IBAT6 and DBAT6 */ +#define CFG_IBAT6L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT6U (0x20000000 | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT6L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT6U CFG_IBAT6U + +/* IBAT7 and DBAT7 */ +#define CFG_IBAT7L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CFG_IBAT7U (0x20000000 | BATU_BL_256M | BATU_VS | BATU_VP) +#define CFG_DBAT7L (0x20000000 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CFG_DBAT7U CFG_IBAT7U + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8<<20) /* Initial Memory map for Linux */ +#define CFG_VXWORKS_MAC_PTR 0x42010000 /* use some memory in SRAM that's not used!!! */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 /* For all MPC74xx CPUs */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * L2CR setup -- make sure this is right for your board! + * look in include/mpc74xx.h for the defines used here + */ +#define CFG_L2 + +#if defined (CONFIG_750CX) || defined (CONFIG_750FX) +#define L2_INIT 0 +#else +#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \ + L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT) +#endif + +#define L2_ENABLE (L2_INIT | L2CR_L2E) + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/i2c.h b/include/i2c.h index 6d39080..a8f729a 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -82,4 +82,49 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); uchar i2c_reg_read (uchar chip, uchar reg); void i2c_reg_write(uchar chip, uchar reg, uchar val); +/* + * Functions for setting the current I2C bus and its speed + */ + +/* + * i2c_set_bus_num: + * + * Change the active I2C bus. Subsequent read/write calls will + * go to this one. + * + * bus - bus index, zero based + * + * Returns: 0 on success, not 0 on failure + * + */ +int i2c_set_bus_num(unsigned int bus); + +/* + * i2c_get_bus_num: + * + * Returns index of currently active I2C bus. Zero-based. + */ + +unsigned int i2c_get_bus_num(void); + +/* + * i2c_set_bus_speed: + * + * Change the speed of the active I2C bus + * + * speed - bus speed in Hz + * + * Returns: 0 on success, not 0 on failure + * + */ +int i2c_set_bus_speed(unsigned int); + +/* + * i2c_get_bus_speed: + * + * Returns speed of currently active I2C bus in Hz + */ + +unsigned int i2c_get_bus_speed(void); + #endif /* _I2C_H_ */ diff --git a/include/ioports.h b/include/ioports.h index d7e19e1..cfba667 100644 --- a/include/ioports.h +++ b/include/ioports.h @@ -53,3 +53,13 @@ typedef struct { * like the table in the 8260UM (and in the hymod manuals). */ extern const iop_conf_t iop_conf_tab[4][32]; + +typedef struct { + unsigned char port; + unsigned char pin; + int dir; + int open_drain; + int assign; +} qe_iop_conf_t; + +#define QE_IOP_TAB_END (-1) diff --git a/include/mpc83xx.h b/include/mpc83xx.h index ea40bad3..03dd0ca 100644 --- a/include/mpc83xx.h +++ b/include/mpc83xx.h @@ -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. @@ -8,16 +8,6 @@ * 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 */ /* @@ -29,6 +19,7 @@ #ifndef __MPC83XX_H__ #define __MPC83XX_H__ +#include <config.h> #if defined(CONFIG_E300) #include <asm/e300.h> #endif @@ -85,6 +76,33 @@ #define LBLAWBAR3 0x0038 #define LBLAWAR3 0x003C +/* + * The device ID and revision numbers + */ +#define SPR_8349E_REV10 0x80300100 +#define SPR_8349_REV10 0x80310100 +#define SPR_8347E_REV10_TBGA 0x80320100 +#define SPR_8347_REV10_TBGA 0x80330100 +#define SPR_8347E_REV10_PBGA 0x80340100 +#define SPR_8347_REV10_PBGA 0x80350100 +#define SPR_8343E_REV10 0x80360100 +#define SPR_8343_REV10 0x80370100 + +#define SPR_8349E_REV11 0x80300101 +#define SPR_8349_REV11 0x80310101 +#define SPR_8347E_REV11_TBGA 0x80320101 +#define SPR_8347_REV11_TBGA 0x80330101 +#define SPR_8347E_REV11_PBGA 0x80340101 +#define SPR_8347_REV11_PBGA 0x80350101 +#define SPR_8343E_REV11 0x80360101 +#define SPR_8343_REV11 0x80370101 + +#define SPR_8360E_REV10 0x80480010 +#define SPR_8360_REV10 0x80490010 +#define SPR_8360E_REV11 0x80480011 +#define SPR_8360_REV11 0x80490011 +#define SPR_8360E_REV12 0x80480012 +#define SPR_8360_REV12 0x80490012 /* * Base Registers & Option Registers @@ -116,9 +134,17 @@ #define BR_MS_UPMA 0x00000080 /* UPMA */ #define BR_MS_UPMB 0x000000A0 /* UPMB */ #define BR_MS_UPMC 0x000000C0 /* UPMC */ +#if defined (CONFIG_MPC8360) +#define BR_ATOM 0x0000000C +#define BR_ATOM_SHIFT 2 +#endif #define BR_V 0x00000001 #define BR_V_SHIFT 0 +#if defined (CONFIG_MPC8349) #define BR_RES ~(BR_BA|BR_PS|BR_DECC|BR_WP|BR_MSEL|BR_V) +#elif defined (CONFIG_MPC8360) +#define BR_RES ~(BR_BA|BR_PS|BR_DECC|BR_WP|BR_MSEL|BR_ATOM|BR_V) +#endif #define OR0 0x5004 #define OR1 0x500C @@ -201,14 +227,21 @@ #define HRCWH_PCI_AGENT 0x00000000 #define HRCWH_PCI_HOST 0x80000000 +#if defined (CONFIG_MPC8349) #define HRCWH_32_BIT_PCI 0x00000000 #define HRCWH_64_BIT_PCI 0x40000000 +#endif #define HRCWH_PCI1_ARBITER_DISABLE 0x00000000 #define HRCWH_PCI1_ARBITER_ENABLE 0x20000000 +#if defined (CONFIG_MPC8349) #define HRCWH_PCI2_ARBITER_DISABLE 0x00000000 #define HRCWH_PCI2_ARBITER_ENABLE 0x10000000 +#elif defined (CONFIG_MPC8360) +#define HRCWH_PCICKDRV_DISABLE 0x00000000 +#define HRCWH_PCICKDRV_ENABLE 0x10000000 +#endif #define HRCWH_CORE_DISABLE 0x08000000 #define HRCWH_CORE_ENABLE 0x00000000 @@ -225,11 +258,14 @@ #define HRCWH_ROM_LOC_DDR_SDRAM 0x00000000 #define HRCWH_ROM_LOC_PCI1 0x00100000 +#if defined (CONFIG_MPC8349) #define HRCWH_ROM_LOC_PCI2 0x00200000 +#endif #define HRCWH_ROM_LOC_LOCAL_8BIT 0x00500000 #define HRCWH_ROM_LOC_LOCAL_16BIT 0x00600000 #define HRCWH_ROM_LOC_LOCAL_32BIT 0x00700000 +#if defined (CONFIG_MPC8349) #define HRCWH_TSEC1M_IN_RGMII 0x00000000 #define HRCWH_TSEC1M_IN_RTBI 0x00004000 #define HRCWH_TSEC1M_IN_GMII 0x00008000 @@ -239,10 +275,22 @@ #define HRCWH_TSEC2M_IN_RTBI 0x00001000 #define HRCWH_TSEC2M_IN_GMII 0x00002000 #define HRCWH_TSEC2M_IN_TBI 0x00003000 +#endif + +#if defined (CONFIG_MPC8360) +#define HRCWH_SECONDARY_DDR_DISABLE 0x00000000 +#define HRCWH_SECONDARY_DDR_ENABLE 0x00000010 +#endif #define HRCWH_BIG_ENDIAN 0x00000000 #define HRCWH_LITTLE_ENDIAN 0x00000008 +#define HRCWH_LALE_NORMAL 0x00000000 +#define HRCWH_LALE_EARLY 0x00000004 + +#define HRCWH_LDP_SET 0x00000000 +#define HRCWH_LDP_CLEAR 0x00000002 + /* * Hard Reset Configration Word - Low */ @@ -281,6 +329,47 @@ #define HRCWL_CORE_TO_CSB_2_5X1 0x00050000 #define HRCWL_CORE_TO_CSB_3X1 0x00060000 +#if defined (CONFIG_MPC8360) +#define HRCWL_CE_PLL_VCO_DIV_4 0x00000000 +#define HRCWL_CE_PLL_VCO_DIV_8 0x00000040 +#define HRCWL_CE_PLL_VCO_DIV_2 0x00000080 + +#define HRCWL_CE_PLL_DIV_1X1 0x00000000 +#define HRCWL_CE_PLL_DIV_2X1 0x00000020 + +#define HRCWL_CE_TO_PLL_1X16_ 0x00000000 +#define HRCWL_CE_TO_PLL_1X2 0x00000002 +#define HRCWL_CE_TO_PLL_1X3 0x00000003 +#define HRCWL_CE_TO_PLL_1X4 0x00000004 +#define HRCWL_CE_TO_PLL_1X5 0x00000005 +#define HRCWL_CE_TO_PLL_1X6 0x00000006 +#define HRCWL_CE_TO_PLL_1X7 0x00000007 +#define HRCWL_CE_TO_PLL_1X8 0x00000008 +#define HRCWL_CE_TO_PLL_1X9 0x00000009 +#define HRCWL_CE_TO_PLL_1X10 0x0000000A +#define HRCWL_CE_TO_PLL_1X11 0x0000000B +#define HRCWL_CE_TO_PLL_1X12 0x0000000C +#define HRCWL_CE_TO_PLL_1X13 0x0000000D +#define HRCWL_CE_TO_PLL_1X14 0x0000000E +#define HRCWL_CE_TO_PLL_1X15 0x0000000F +#define HRCWL_CE_TO_PLL_1X16 0x00000010 +#define HRCWL_CE_TO_PLL_1X17 0x00000011 +#define HRCWL_CE_TO_PLL_1X18 0x00000012 +#define HRCWL_CE_TO_PLL_1X19 0x00000013 +#define HRCWL_CE_TO_PLL_1X20 0x00000014 +#define HRCWL_CE_TO_PLL_1X21 0x00000015 +#define HRCWL_CE_TO_PLL_1X22 0x00000016 +#define HRCWL_CE_TO_PLL_1X23 0x00000017 +#define HRCWL_CE_TO_PLL_1X24 0x00000018 +#define HRCWL_CE_TO_PLL_1X25 0x00000019 +#define HRCWL_CE_TO_PLL_1X26 0x0000001A +#define HRCWL_CE_TO_PLL_1X27 0x0000001B +#define HRCWL_CE_TO_PLL_1X28 0x0000001C +#define HRCWL_CE_TO_PLL_1X29 0x0000001D +#define HRCWL_CE_TO_PLL_1X30 0x0000001E +#define HRCWL_CE_TO_PLL_1X31 0x0000001F +#endif + /* * LCRR - Clock Ratio Register (10.3.1.16) */ @@ -310,4 +399,31 @@ #define LCRR_CLKDIV_8 0x00000008 #define LCRR_CLKDIV_SHIFT 0 +/* + * SCCR-System Clock Control Register + */ +#define SCCR_TSEC1CM_0 0x00000000 +#define SCCR_TSEC1CM_1 0x40000000 +#define SCCR_TSEC1CM_2 0x80000000 +#define SCCR_TSEC1CM_3 0xC0000000 +#define SCCR_TSEC2CM_0 0x00000000 +#define SCCR_TSEC2CM_1 0x10000000 +#define SCCR_TSEC2CM_2 0x20000000 +#define SCCR_TSEC2CM_3 0x30000000 +#define SCCR_ENCCM_0 0x00000000 +#define SCCR_ENCCM_1 0x01000000 +#define SCCR_ENCCM_2 0x02000000 +#define SCCR_ENCCM_3 0x03000000 +#define SCCR_USBCM_0 0x00000000 +#define SCCR_USBCM_1 0x00500000 +#define SCCR_USBCM_2 0x00A00000 +#define SCCR_USBCM_3 0x00F00000 + +#define SCCR_CLK_MASK ( SCCR_TSEC1CM_3 \ + | SCCR_TSEC2CM_3 \ + | SCCR_ENCCM_3 \ + | SCCR_USBCM_3 ) + +#define SCCR_DEFAULT 0xFFFFFFFF + #endif /* __MPC83XX_H__ */ diff --git a/include/ppc440.h b/include/ppc440.h index 407daae..50f4ec4 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -1350,26 +1350,26 @@ #if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX) #define UIC2_DCR_BASE 0xe0 -#define uic2sr (UIC0_DCR_BASE+0x0) /* UIC2 status-Read Clear */ -#define uic2srs (UIC0_DCR_BASE+0x1) /* UIC2 status-Read Set */ -#define uic2er (UIC0_DCR_BASE+0x2) /* UIC2 enable */ -#define uic2cr (UIC0_DCR_BASE+0x3) /* UIC2 critical */ -#define uic2pr (UIC0_DCR_BASE+0x4) /* UIC2 polarity */ -#define uic2tr (UIC0_DCR_BASE+0x5) /* UIC2 triggering */ -#define uic2msr (UIC0_DCR_BASE+0x6) /* UIC2 masked status */ -#define uic2vr (UIC0_DCR_BASE+0x7) /* UIC2 vector */ -#define uic2vcr (UIC0_DCR_BASE+0x8) /* UIC2 vector configuration */ +#define uic2sr (UIC2_DCR_BASE+0x0) /* UIC2 status-Read Clear */ +#define uic2srs (UIC2_DCR_BASE+0x1) /* UIC2 status-Read Set */ +#define uic2er (UIC2_DCR_BASE+0x2) /* UIC2 enable */ +#define uic2cr (UIC2_DCR_BASE+0x3) /* UIC2 critical */ +#define uic2pr (UIC2_DCR_BASE+0x4) /* UIC2 polarity */ +#define uic2tr (UIC2_DCR_BASE+0x5) /* UIC2 triggering */ +#define uic2msr (UIC2_DCR_BASE+0x6) /* UIC2 masked status */ +#define uic2vr (UIC2_DCR_BASE+0x7) /* UIC2 vector */ +#define uic2vcr (UIC2_DCR_BASE+0x8) /* UIC2 vector configuration */ #define UIC3_DCR_BASE 0xf0 -#define uic3sr (UIC1_DCR_BASE+0x0) /* UIC3 status-Read Clear */ -#define uic3srs (UIC0_DCR_BASE+0x1) /* UIC3 status-Read Set */ -#define uic3er (UIC1_DCR_BASE+0x2) /* UIC3 enable */ -#define uic3cr (UIC1_DCR_BASE+0x3) /* UIC3 critical */ -#define uic3pr (UIC1_DCR_BASE+0x4) /* UIC3 polarity */ -#define uic3tr (UIC1_DCR_BASE+0x5) /* UIC3 triggering */ -#define uic3msr (UIC1_DCR_BASE+0x6) /* UIC3 masked status */ -#define uic3vr (UIC1_DCR_BASE+0x7) /* UIC3 vector */ -#define uic3vcr (UIC1_DCR_BASE+0x8) /* UIC3 vector configuration */ +#define uic3sr (UIC3_DCR_BASE+0x0) /* UIC3 status-Read Clear */ +#define uic3srs (UIC3_DCR_BASE+0x1) /* UIC3 status-Read Set */ +#define uic3er (UIC3_DCR_BASE+0x2) /* UIC3 enable */ +#define uic3cr (UIC3_DCR_BASE+0x3) /* UIC3 critical */ +#define uic3pr (UIC3_DCR_BASE+0x4) /* UIC3 polarity */ +#define uic3tr (UIC3_DCR_BASE+0x5) /* UIC3 triggering */ +#define uic3msr (UIC3_DCR_BASE+0x6) /* UIC3 masked status */ +#define uic3vr (UIC3_DCR_BASE+0x7) /* UIC3 vector */ +#define uic3vcr (UIC3_DCR_BASE+0x8) /* UIC3 vector configuration */ #endif /* CONFIG_440SPE */ #if defined(CONFIG_440GX) diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 844bbc9..a11d3c0 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -511,7 +511,7 @@ void board_init_f (ulong bootflag) bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */ #endif #if defined(CONFIG_MPC83XX) - bd->bi_immrbar = CFG_IMMRBAR; + bd->bi_immrbar = CFG_IMMR; #endif #if defined(CONFIG_MPC8220) bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */ @@ -521,17 +521,17 @@ void board_init_f (ulong bootflag) bd->bi_pevfreq = gd->pev_clk; bd->bi_flbfreq = gd->flb_clk; - /* store bootparam to sram (backward compatible), here? */ - { - u32 *sram = (u32 *)CFG_SRAM_BASE; - *sram++ = gd->ram_size; - *sram++ = gd->bus_clk; - *sram++ = gd->inp_clk; - *sram++ = gd->cpu_clk; - *sram++ = gd->vco_clk; - *sram++ = gd->flb_clk; - *sram++ = 0xb8c3ba11; /* boot signature */ - } + /* store bootparam to sram (backward compatible), here? */ + { + u32 *sram = (u32 *)CFG_SRAM_BASE; + *sram++ = gd->ram_size; + *sram++ = gd->bus_clk; + *sram++ = gd->inp_clk; + *sram++ = gd->cpu_clk; + *sram++ = gd->vco_clk; + *sram++ = gd->flb_clk; + *sram++ = 0xb8c3ba11; /* boot signature */ + } #endif bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */ @@ -55,6 +55,7 @@ extern int skge_initialize(bd_t*); extern int tsi108_eth_initialize(bd_t*); extern int tsec_initialize(bd_t*, int, char *); extern int npe_initialize(bd_t *); +extern int uec_initialize(int); static struct eth_device *eth_devices, *eth_current; @@ -143,13 +144,10 @@ int eth_initialize(bd_t *bis) miiphy_init(); #endif -#ifdef CONFIG_DB64360 +#if defined(CONFIG_DB64360) || defined(CONFIG_CPCI750) mv6436x_eth_initialize(bis); #endif -#ifdef CONFIG_CPCI750 - mv6436x_eth_initialize(bis); -#endif -#ifdef CONFIG_DB64460 +#if defined(CONFIG_DB64460) || defined(CONFIG_P3Mx) mv6446x_eth_initialize(bis); #endif #if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) && !defined(CONFIG_AP1000) @@ -197,6 +195,12 @@ int eth_initialize(bd_t *bis) tsec_initialize(bis, 3, CONFIG_MPC83XX_TSEC4_NAME); # endif #endif +#if defined(CONFIG_UEC_ETH1) + uec_initialize(0); +#endif +#if defined(CONFIG_UEC_ETH2) + uec_initialize(1); +#endif #if defined(CONFIG_MPC86XX_TSEC1) tsec_initialize(bis, 0, CONFIG_MPC86XX_TSEC1_NAME); #endif |