* [RFC] Add PowerPC MPC5125 support @ 2014-10-07 14:21 Juergen Borleis 2014-10-07 14:22 ` [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200 Juergen Borleis ` (18 more replies) 0 siblings, 19 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:21 UTC (permalink / raw) To: barebox This is a try to add the MPC5125 SoC to Barebox. This kind of SoC shares some embedded devices with the MPC5200 and the MPC5121/MPC5123 (at least it uses the same names for them) but differs in many annoying details. So this adaption can only be used on a MPC5125 and is completely untested on MPC5121 and MPC5123. Patch "arch/MPC5xxx: fix linker script for MPC5200" tries to repair the linker script for the MPC5200 because the resulting binary image is broken without this change. But I do not really know why it is broken and how to repair it correctly. Comments? At least the existing PSC code for the serial UART can be shared between both SoCs, even if their internals differ. With some re-factoring it is possible to use the main code on both SoCs. The same might be possible with the FEC driver, but needs more effort, because the DMA work differently on both SoCs. I'm not sure if its worth the effort, so I just add a new FEC driver for the MPC5125 with this series. Comments are welcome. Juergen _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 02/19] arch/MPC5xxx: use a mach specific linker script instead of a board specific one Juergen Borleis ` (17 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Without this change the barebox.bin ends up with: 00000000 79 ba 8f 79 00 00 00 00 75 39 6e d1 74 27 00 00 |y..y....u9n.t'..| 00000010 01 00 00 00 00 00 00 00 28 80 ad db 8d c7 a8 67 |........(......g| 00000020 4e 07 00 00 10 00 00 00 2f 63 6f 6e 66 69 67 00 |N......./config.| 00000030 8d c7 a8 68 ff 01 00 00 23 21 2f 62 69 6e 2f 73 |...h....#!/bin/s| 00000040 68 0a 0a 68 6f 73 74 6e 61 6d 65 3d 46 49 58 4d |h..hostname=FIXM| 00000050 45 0a 69 66 20 5b 20 2d 7a 20 22 24 75 73 65 72 |E.if [ -z "$user| 00000060 22 20 5d 3b 20 74 68 65 6e 0a 23 09 75 73 65 72 |" ]; then.#.user| 00000070 3d 0a 66 69 0a 0a 23 20 45 6e 74 65 72 20 4d 41 |=.fi..# Enter MA| [...] which means it starts with the default environment instead of the reset vector area. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/boards/pcm030/barebox.lds.S | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S index 20ac0d8..1332ad1 100644 --- a/arch/ppc/boards/pcm030/barebox.lds.S +++ b/arch/ppc/boards/pcm030/barebox.lds.S @@ -26,7 +26,21 @@ SECTIONS { . = TEXT_BASE; + .text : + { + _text = .; + _stext = .; + arch/ppc/mach-mpc5xxx/start.o (.text) + *(.text*) + *(.got1*) + . = ALIGN(16); + *(.rodata*) + *(.rodata1*) + *(.rodata.str1.4) + } + /* Read-only sections, merged into text segment: */ +/* .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } @@ -50,20 +64,10 @@ SECTIONS .init : { *(.init) } .plt : { *(.plt) } .text : - { - _text = .; - _stext = .; - arch/ppc/mach-mpc5xxx/start.o (.text) - *(.text*) - *(.got1*) - . = ALIGN(16); - *(.rodata*) - *(.rodata1*) - *(.rodata.str1.4) - } .fini : { *(.fini) } =0 .ctors : { *(.ctors) } .dtors : { *(.dtors) } +*/ /* Read-write section, merged into data segment: */ . = (. + 0x0FFF) & 0xFFFFF000; -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 02/19] arch/MPC5xxx: use a mach specific linker script instead of a board specific one 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis 2014-10-07 14:22 ` [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200 Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 03/19] arch/MPC5xxx: replace 'depends on' by 'select' Juergen Borleis ` (16 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox For easier maintenance in the future. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/Makefile | 5 ----- arch/ppc/boards/pcm030/Makefile | 1 - arch/ppc/mach-mpc5xxx/Makefile | 1 + arch/ppc/{boards/pcm030 => mach-mpc5xxx}/barebox.lds.S | 0 4 files changed, 1 insertion(+), 6 deletions(-) rename arch/ppc/{boards/pcm030 => mach-mpc5xxx}/barebox.lds.S (100%) diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index fb9b0b8..d0dd51e 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -64,9 +64,4 @@ endif common-y += $(BOARD) $(CPU) $(MACH) common-y += arch/ppc/lib/ - -ifdef CONFIG_MPC85xx lds-y += $(MACH)/barebox.lds -else -lds-y += $(BOARD)/barebox.lds -endif diff --git a/arch/ppc/boards/pcm030/Makefile b/arch/ppc/boards/pcm030/Makefile index e7d744b..3749605 100644 --- a/arch/ppc/boards/pcm030/Makefile +++ b/arch/ppc/boards/pcm030/Makefile @@ -1,2 +1 @@ obj-y += pcm030.o -extra-y += barebox.lds diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile index c532a6d..bf8d68d 100644 --- a/arch/ppc/mach-mpc5xxx/Makefile +++ b/arch/ppc/mach-mpc5xxx/Makefile @@ -5,6 +5,7 @@ obj-y += speed.o obj-y += traps.o obj-y += time.o extra-y += start.o +extra-y += barebox.lds obj-$(CONFIG_MPC5200) += firmware_sc_task_bestcomm.impl.o obj-$(CONFIG_REGINFO) += reginfo.o diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/mach-mpc5xxx/barebox.lds.S similarity index 100% rename from arch/ppc/boards/pcm030/barebox.lds.S rename to arch/ppc/mach-mpc5xxx/barebox.lds.S -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 03/19] arch/MPC5xxx: replace 'depends on' by 'select' 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis 2014-10-07 14:22 ` [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200 Juergen Borleis 2014-10-07 14:22 ` [PATCH 02/19] arch/MPC5xxx: use a mach specific linker script instead of a board specific one Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 04/19] arch/MPC5xxx: Simplify the calculation Juergen Borleis ` (15 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox This change will simplify the addition of new SOCs. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/Kconfig | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig index 1ecce3a..5eebf2a 100644 --- a/arch/ppc/mach-mpc5xxx/Kconfig +++ b/arch/ppc/mach-mpc5xxx/Kconfig @@ -14,6 +14,7 @@ choice config MACH_PHYCORE_MPC5200B_TINY bool "Phycore mpc5200b tiny" + select MPC5200 help Say Y here if you are using the Phytec Phycore MPC5200B Tiny board aka pcm030. @@ -21,19 +22,15 @@ endchoice config MPC5200 bool - depends on MACH_PHYCORE_MPC5200B_TINY - default y + select ARCH_MPC5200 config ARCH_MPC5200 bool - depends on MACH_PHYCORE_MPC5200B_TINY - default y + select MPC5xxx config MPC5xxx bool - depends on MACH_PHYCORE_MPC5200B_TINY select HAVE_CONFIGURABLE_MEMORY_LAYOUT - default y menu "Board specific settings" -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 04/19] arch/MPC5xxx: Simplify the calculation 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (2 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 03/19] arch/MPC5xxx: replace 'depends on' by 'select' Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 05/19] arch/MPC5xxx: just a format clean up Juergen Borleis ` (14 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/start.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S index 291f625..6a32718 100644 --- a/arch/ppc/mach-mpc5xxx/start.S +++ b/arch/ppc/mach-mpc5xxx/start.S @@ -66,6 +66,7 @@ * Second stage loader entry. When entered here we assume that spr 311 * is set to the current MBAR address. */ +_base: mfspr r4, MBAR b setup_mbar . = EXC_OFF_SYS_RESET @@ -251,9 +252,8 @@ _continue_init: bl calc_source /* Calculate Source Address */ calc_source: - mfspr r4, LR - subi r4, r4, (calc_source - _start) - subi r4, r4, 0x100 + mflr r4 + subi r4, r4, (calc_source - _base) lis r5, __init_size@h /* Size */ ori r5, r5, __init_size@l -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 05/19] arch/MPC5xxx: just a format clean up 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (3 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 04/19] arch/MPC5xxx: Simplify the calculation Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 06/19] arch/MPC5xxx: move away existing files to be able to add a new SoC type Juergen Borleis ` (13 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/start.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S index 6a32718..8402345 100644 --- a/arch/ppc/mach-mpc5xxx/start.S +++ b/arch/ppc/mach-mpc5xxx/start.S @@ -68,7 +68,8 @@ */ _base: mfspr r4, MBAR - b setup_mbar + b setup_mbar + . = EXC_OFF_SYS_RESET .globl _start _start: -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 06/19] arch/MPC5xxx: move away existing files to be able to add a new SoC type 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (4 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 05/19] arch/MPC5xxx: just a format clean up Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 07/19] arch/MPC5xxx: separate architecture's main SoC header file Juergen Borleis ` (12 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/Makefile | 8 ++++---- arch/ppc/mach-mpc5xxx/{cpu.c => cpu-mpc5200.c} | 0 arch/ppc/mach-mpc5xxx/{cpu_init.c => cpu_init-mpc5200.c} | 0 arch/ppc/mach-mpc5xxx/{speed.c => speed-mpc5200.c} | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename arch/ppc/mach-mpc5xxx/{cpu.c => cpu-mpc5200.c} (100%) rename arch/ppc/mach-mpc5xxx/{cpu_init.c => cpu_init-mpc5200.c} (100%) rename arch/ppc/mach-mpc5xxx/{speed.c => speed-mpc5200.c} (100%) diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile index bf8d68d..c8d503e 100644 --- a/arch/ppc/mach-mpc5xxx/Makefile +++ b/arch/ppc/mach-mpc5xxx/Makefile @@ -1,7 +1,7 @@ -obj-y += cpu.o -obj-y += cpu_init.o -obj-y += loadtask.o -obj-y += speed.o +obj-$(CONFIG_MPC5200) += cpu-mpc5200.o +obj-$(CONFIG_MPC5200) += cpu_init-mpc5200.o +obj-$(CONFIG_MPC5200) += loadtask.o +obj-$(CONFIG_MPC5200) += speed-mpc5200.o obj-y += traps.o obj-y += time.o extra-y += start.o diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu-mpc5200.c similarity index 100% rename from arch/ppc/mach-mpc5xxx/cpu.c rename to arch/ppc/mach-mpc5xxx/cpu-mpc5200.c diff --git a/arch/ppc/mach-mpc5xxx/cpu_init.c b/arch/ppc/mach-mpc5xxx/cpu_init-mpc5200.c similarity index 100% rename from arch/ppc/mach-mpc5xxx/cpu_init.c rename to arch/ppc/mach-mpc5xxx/cpu_init-mpc5200.c diff --git a/arch/ppc/mach-mpc5xxx/speed.c b/arch/ppc/mach-mpc5xxx/speed-mpc5200.c similarity index 100% rename from arch/ppc/mach-mpc5xxx/speed.c rename to arch/ppc/mach-mpc5xxx/speed-mpc5200.c -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 07/19] arch/MPC5xxx: separate architecture's main SoC header file 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (5 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 06/19] arch/MPC5xxx: move away existing files to be able to add a new SoC type Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 08/19] arch/MPC5xxx: separate clock functions Juergen Borleis ` (11 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h | 794 +++++++++++++++++++++++++++ arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h | 793 +------------------------- 2 files changed, 798 insertions(+), 789 deletions(-) create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h new file mode 100644 index 0000000..35762a1 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h @@ -0,0 +1,794 @@ +/* + * arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h + * + * Prototypes, etc. for the Motorola MGT5xxx/MPC5xxx + * embedded cpu chips + * + * 2003 (c) MontaVista, Software, Inc. + * Author: Dale Farnsworth <dfarnsworth@mvista.com> + * + * 2003 (C) 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. + * + */ +#ifndef __ASMPPC_MPC5200_H +#define __ASMPPC_MPC5200_H + +/* Processor name */ +#if defined(CONFIG_MPC5200) +#define CPU_ID_STR "MPC5200" +#elif defined(CONFIG_MGT5100) +#define CPU_ID_STR "MGT5100" +#endif + +/* Exception offsets (PowerPC standard) */ +#define EXC_OFF_SYS_RESET 0x0100 +#define _START_OFFSET EXC_OFF_SYS_RESET + +#define CFG_MBAR 0xf0000000 + +/* useful macros for manipulating CSx_START/STOP */ +#if defined(CONFIG_MGT5100) +#define START_REG(start) ((start) >> 15) +#define STOP_REG(start, size) (((start) + (size) - 1) >> 15) +#elif defined(CONFIG_MPC5200) +#define START_REG(start) ((start) >> 16) +#define STOP_REG(start, size) (((start) + (size) - 1) >> 16) +#endif + +/* Internal memory map */ + +#define MPC5XXX_CS0_START (CFG_MBAR + 0x0004) +#define MPC5XXX_CS0_STOP (CFG_MBAR + 0x0008) +#define MPC5XXX_CS1_START (CFG_MBAR + 0x000c) +#define MPC5XXX_CS1_STOP (CFG_MBAR + 0x0010) +#define MPC5XXX_CS2_START (CFG_MBAR + 0x0014) +#define MPC5XXX_CS2_STOP (CFG_MBAR + 0x0018) +#define MPC5XXX_CS3_START (CFG_MBAR + 0x001c) +#define MPC5XXX_CS3_STOP (CFG_MBAR + 0x0020) +#define MPC5XXX_CS4_START (CFG_MBAR + 0x0024) +#define MPC5XXX_CS4_STOP (CFG_MBAR + 0x0028) +#define MPC5XXX_CS5_START (CFG_MBAR + 0x002c) +#define MPC5XXX_CS5_STOP (CFG_MBAR + 0x0030) +#define MPC5XXX_BOOTCS_START (CFG_MBAR + 0x004c) +#define MPC5XXX_BOOTCS_STOP (CFG_MBAR + 0x0050) +#define MPC5XXX_ADDECR (CFG_MBAR + 0x0054) + +#if defined(CONFIG_MGT5100) +#define MPC5XXX_SDRAM_START (CFG_MBAR + 0x0034) +#define MPC5XXX_SDRAM_STOP (CFG_MBAR + 0x0038) +#define MPC5XXX_PCI1_START (CFG_MBAR + 0x003c) +#define MPC5XXX_PCI1_STOP (CFG_MBAR + 0x0040) +#define MPC5XXX_PCI2_START (CFG_MBAR + 0x0044) +#define MPC5XXX_PCI2_STOP (CFG_MBAR + 0x0048) +#elif defined(CONFIG_MPC5200) +#define MPC5XXX_CS6_START (CFG_MBAR + 0x0058) +#define MPC5XXX_CS6_STOP (CFG_MBAR + 0x005c) +#define MPC5XXX_CS7_START (CFG_MBAR + 0x0060) +#define MPC5XXX_CS7_STOP (CFG_MBAR + 0x0064) +#define MPC5XXX_SDRAM_CS0CFG (CFG_MBAR + 0x0034) +#define MPC5XXX_SDRAM_CS1CFG (CFG_MBAR + 0x0038) +#endif + +#define MPC5XXX_SDRAM (CFG_MBAR + 0x0100) +#define MPC5XXX_CDM (CFG_MBAR + 0x0200) +#define MPC5XXX_LPB (CFG_MBAR + 0x0300) +#define MPC5XXX_ICTL (CFG_MBAR + 0x0500) +#define MPC5XXX_GPT (CFG_MBAR + 0x0600) +#define MPC5XXX_GPIO (CFG_MBAR + 0x0b00) +#define MPC5XXX_WU_GPIO (CFG_MBAR + 0x0c00) +#define MPC5XXX_PCI (CFG_MBAR + 0x0d00) +#define MPC5XXX_SPI (CFG_MBAR + 0x0f00) +#define MPC5XXX_USB (CFG_MBAR + 0x1000) +#define MPC5XXX_SDMA (CFG_MBAR + 0x1200) +#define MPC5XXX_XLBARB (CFG_MBAR + 0x1f00) + +#if defined(CONFIG_MGT5100) +#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000) +#define MPC5XXX_PSC2 (CFG_MBAR + 0x2400) +#define MPC5XXX_PSC3 (CFG_MBAR + 0x2800) +#elif defined(CONFIG_MPC5200) +#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000) +#define MPC5XXX_PSC2 (CFG_MBAR + 0x2200) +#define MPC5XXX_PSC3 (CFG_MBAR + 0x2400) +#define MPC5XXX_PSC4 (CFG_MBAR + 0x2600) +#define MPC5XXX_PSC5 (CFG_MBAR + 0x2800) +#define MPC5XXX_PSC6 (CFG_MBAR + 0x2c00) +#endif + +#define MPC5XXX_FEC (CFG_MBAR + 0x3000) +#define MPC5XXX_ATA (CFG_MBAR + 0x3A00) + +#define MPC5XXX_I2C1 (CFG_MBAR + 0x3D00) +#define MPC5XXX_I2C2 (CFG_MBAR + 0x3D40) + +#if defined(CONFIG_MGT5100) +#define MPC5XXX_SRAM (CFG_MBAR + 0x4000) +#define MPC5XXX_SRAM_SIZE (8*1024) +#elif defined(CONFIG_MPC5200) +#define MPC5XXX_SRAM (CFG_MBAR + 0x8000) +#define MPC5XXX_SRAM_SIZE (16*1024) +#endif + +/* SDRAM Controller */ +#define MPC5XXX_SDRAM_MODE (MPC5XXX_SDRAM + 0x0000) +#define MPC5XXX_SDRAM_CTRL (MPC5XXX_SDRAM + 0x0004) +#define MPC5XXX_SDRAM_CONFIG1 (MPC5XXX_SDRAM + 0x0008) +#define MPC5XXX_SDRAM_CONFIG2 (MPC5XXX_SDRAM + 0x000c) +#if defined(CONFIG_MGT5100) +#define MPC5XXX_SDRAM_XLBSEL (MPC5XXX_SDRAM + 0x0010) +#endif +#define MPC5XXX_SDRAM_SDELAY (MPC5XXX_SDRAM + 0x0090) + +/* Clock Distribution Module */ +#define MPC5XXX_CDM_JTAGID (MPC5XXX_CDM + 0x0000) +#define MPC5XXX_CDM_PORCFG (MPC5XXX_CDM + 0x0004) +#define MPC5XXX_CDM_CFG (MPC5XXX_CDM + 0x000c) +#define MPC5XXX_CDM_48_FDC (MPC5XXX_CDM + 0x0010) +#define MPC5XXX_CDM_SRESET (MPC5XXX_CDM + 0x0020) + +/* Local Plus Bus interface */ +#define MPC5XXX_CS0_CFG (MPC5XXX_LPB + 0x0000) +#define MPC5XXX_CS1_CFG (MPC5XXX_LPB + 0x0004) +#define MPC5XXX_CS2_CFG (MPC5XXX_LPB + 0x0008) +#define MPC5XXX_CS3_CFG (MPC5XXX_LPB + 0x000c) +#define MPC5XXX_CS4_CFG (MPC5XXX_LPB + 0x0010) +#define MPC5XXX_CS5_CFG (MPC5XXX_LPB + 0x0014) +#define MPC5XXX_BOOTCS_CFG MPC5XXX_CS0_CFG +#define MPC5XXX_CS_CTRL (MPC5XXX_LPB + 0x0018) +#define MPC5XXX_CS_STATUS (MPC5XXX_LPB + 0x001c) +#if defined(CONFIG_MPC5200) +#define MPC5XXX_CS6_CFG (MPC5XXX_LPB + 0x0020) +#define MPC5XXX_CS7_CFG (MPC5XXX_LPB + 0x0024) +#define MPC5XXX_CS_BURST (MPC5XXX_LPB + 0x0028) +#define MPC5XXX_CS_DEADCYCLE (MPC5XXX_LPB + 0x002c) +#endif + +#if defined(CONFIG_MPC5200) +/* XLB Arbiter registers */ +#define MPC5XXX_XLBARB_CFG (MPC5XXX_XLBARB + 0x40) +#define MPC5XXX_XLBARB_MPRIEN (MPC5XXX_XLBARB + 0x64) +#define MPC5XXX_XLBARB_MPRIVAL (MPC5XXX_XLBARB + 0x68) +#endif + +/* GPIO registers */ +#define MPC5XXX_GPS_PORT_CONFIG (MPC5XXX_GPIO + 0x0000) + +/* Standard GPIO registers (simple, output only and simple interrupt */ +#define MPC5XXX_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004) +#define MPC5XXX_GPIO_ODE (MPC5XXX_GPIO + 0x0008) +#define MPC5XXX_GPIO_DIR (MPC5XXX_GPIO + 0x000c) +#define MPC5XXX_GPIO_DATA_O (MPC5XXX_GPIO + 0x0010) +#define MPC5XXX_GPIO_DATA_I (MPC5XXX_GPIO + 0x0014) +#define MPC5XXX_GPIO_OO_ENABLE (MPC5XXX_GPIO + 0x0018) +#define MPC5XXX_GPIO_OO_DATA (MPC5XXX_GPIO + 0x001C) +#define MPC5XXX_GPIO_SI_ENABLE (MPC5XXX_GPIO + 0x0020) +#define MPC5XXX_GPIO_SI_ODE (MPC5XXX_GPIO + 0x0024) +#define MPC5XXX_GPIO_SI_DIR (MPC5XXX_GPIO + 0x0028) +#define MPC5XXX_GPIO_SI_DATA (MPC5XXX_GPIO + 0x002C) +#define MPC5XXX_GPIO_SI_IEN (MPC5XXX_GPIO + 0x0030) +#define MPC5XXX_GPIO_SI_ITYPE (MPC5XXX_GPIO + 0x0034) +#define MPC5XXX_GPIO_SI_MEN (MPC5XXX_GPIO + 0x0038) +#define MPC5XXX_GPIO_SI_STATUS (MPC5XXX_GPIO + 0x003C) + +/* WakeUp GPIO registers */ +#define MPC5XXX_WU_GPIO_ENABLE (MPC5XXX_WU_GPIO + 0x0000) +#define MPC5XXX_WU_GPIO_ODE (MPC5XXX_WU_GPIO + 0x0004) +#define MPC5XXX_WU_GPIO_DIR (MPC5XXX_WU_GPIO + 0x0008) +#define MPC5XXX_WU_GPIO_DATA_O (MPC5XXX_WU_GPIO + 0x000c) +#define MPC5XXX_WU_GPIO_DATA_I (MPC5XXX_WU_GPIO + 0x0020) + +/* GPIO pins */ +#define GPIO_WKUP_7 0x80000000UL +#define GPIO_PSC6_0 0x10000000UL +#define GPIO_PSC3_9 0x04000000UL +#define GPIO_PSC1_4 0x01000000UL + +/* PCI registers */ +#define MPC5XXX_PCI_CMD (MPC5XXX_PCI + 0x04) +#define MPC5XXX_PCI_CFG (MPC5XXX_PCI + 0x0c) +#define MPC5XXX_PCI_BAR0 (MPC5XXX_PCI + 0x10) +#define MPC5XXX_PCI_BAR1 (MPC5XXX_PCI + 0x14) +#if defined(CONFIG_MGT5100) +#define MPC5XXX_PCI_CTRL (MPC5XXX_PCI + 0x68) +#define MPC5XXX_PCI_VALMSKR (MPC5XXX_PCI + 0x6c) +#define MPC5XXX_PCI_VALMSKW (MPC5XXX_PCI + 0x70) +#define MPC5XXX_PCI_SUBW1 (MPC5XXX_PCI + 0x74) +#define MPC5XXX_PCI_SUBW2 (MPC5XXX_PCI + 0x78) +#define MPC5XXX_PCI_WINCOMMAND (MPC5XXX_PCI + 0x7c) +#elif defined(CONFIG_MPC5200) +#define MPC5XXX_PCI_GSCR (MPC5XXX_PCI + 0x60) +#define MPC5XXX_PCI_TBATR0 (MPC5XXX_PCI + 0x64) +#define MPC5XXX_PCI_TBATR1 (MPC5XXX_PCI + 0x68) +#define MPC5XXX_PCI_TCR (MPC5XXX_PCI + 0x6c) +#define MPC5XXX_PCI_IW0BTAR (MPC5XXX_PCI + 0x70) +#define MPC5XXX_PCI_IW1BTAR (MPC5XXX_PCI + 0x74) +#define MPC5XXX_PCI_IW2BTAR (MPC5XXX_PCI + 0x78) +#define MPC5XXX_PCI_IWCR (MPC5XXX_PCI + 0x80) +#define MPC5XXX_PCI_ICR (MPC5XXX_PCI + 0x84) +#define MPC5XXX_PCI_ISR (MPC5XXX_PCI + 0x88) +#define MPC5XXX_PCI_ARB (MPC5XXX_PCI + 0x8c) +#define MPC5XXX_PCI_CAR (MPC5XXX_PCI + 0xf8) +#endif + +/* Interrupt Controller registers */ +#define MPC5XXX_ICTL_PER_MASK (MPC5XXX_ICTL + 0x0000) +#define MPC5XXX_ICTL_PER_PRIO1 (MPC5XXX_ICTL + 0x0004) +#define MPC5XXX_ICTL_PER_PRIO2 (MPC5XXX_ICTL + 0x0008) +#define MPC5XXX_ICTL_PER_PRIO3 (MPC5XXX_ICTL + 0x000c) +#define MPC5XXX_ICTL_EXT (MPC5XXX_ICTL + 0x0010) +#define MPC5XXX_ICTL_CRIT (MPC5XXX_ICTL + 0x0014) +#define MPC5XXX_ICTL_MAIN_PRIO1 (MPC5XXX_ICTL + 0x0018) +#define MPC5XXX_ICTL_MAIN_PRIO2 (MPC5XXX_ICTL + 0x001c) +#define MPC5XXX_ICTL_STS (MPC5XXX_ICTL + 0x0024) +#define MPC5XXX_ICTL_CRIT_STS (MPC5XXX_ICTL + 0x0028) +#define MPC5XXX_ICTL_MAIN_STS (MPC5XXX_ICTL + 0x002c) +#define MPC5XXX_ICTL_PER_STS (MPC5XXX_ICTL + 0x0030) +#define MPC5XXX_ICTL_BUS_STS (MPC5XXX_ICTL + 0x0038) + +#define NR_IRQS 64 + +/* IRQ mapping - these are our logical IRQ numbers */ +#define MPC5XXX_CRIT_IRQ_NUM 4 +#define MPC5XXX_MAIN_IRQ_NUM 17 +#define MPC5XXX_SDMA_IRQ_NUM 17 +#define MPC5XXX_PERP_IRQ_NUM 23 + +#define MPC5XXX_CRIT_IRQ_BASE 1 +#define MPC5XXX_MAIN_IRQ_BASE (MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM) +#define MPC5XXX_SDMA_IRQ_BASE (MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM) +#define MPC5XXX_PERP_IRQ_BASE (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM) + +#define MPC5XXX_IRQ0 (MPC5XXX_CRIT_IRQ_BASE + 0) +#define MPC5XXX_SLICE_TIMER_0_IRQ (MPC5XXX_CRIT_IRQ_BASE + 1) +#define MPC5XXX_HI_INT_IRQ (MPC5XXX_CRIT_IRQ_BASE + 2) +#define MPC5XXX_CCS_IRQ (MPC5XXX_CRIT_IRQ_BASE + 3) + +#define MPC5XXX_IRQ1 (MPC5XXX_MAIN_IRQ_BASE + 1) +#define MPC5XXX_IRQ2 (MPC5XXX_MAIN_IRQ_BASE + 2) +#define MPC5XXX_IRQ3 (MPC5XXX_MAIN_IRQ_BASE + 3) +#define MPC5XXX_RTC_PINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 5) +#define MPC5XXX_RTC_SINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 6) +#define MPC5XXX_RTC_GPIO_STD_IRQ (MPC5XXX_MAIN_IRQ_BASE + 7) +#define MPC5XXX_RTC_GPIO_WKUP_IRQ (MPC5XXX_MAIN_IRQ_BASE + 8) +#define MPC5XXX_TMR0_IRQ (MPC5XXX_MAIN_IRQ_BASE + 9) +#define MPC5XXX_TMR1_IRQ (MPC5XXX_MAIN_IRQ_BASE + 10) +#define MPC5XXX_TMR2_IRQ (MPC5XXX_MAIN_IRQ_BASE + 11) +#define MPC5XXX_TMR3_IRQ (MPC5XXX_MAIN_IRQ_BASE + 12) +#define MPC5XXX_TMR4_IRQ (MPC5XXX_MAIN_IRQ_BASE + 13) +#define MPC5XXX_TMR5_IRQ (MPC5XXX_MAIN_IRQ_BASE + 14) +#define MPC5XXX_TMR6_IRQ (MPC5XXX_MAIN_IRQ_BASE + 15) +#define MPC5XXX_TMR7_IRQ (MPC5XXX_MAIN_IRQ_BASE + 16) + +#define MPC5XXX_SDMA_IRQ (MPC5XXX_PERP_IRQ_BASE + 0) +#define MPC5XXX_PSC1_IRQ (MPC5XXX_PERP_IRQ_BASE + 1) +#define MPC5XXX_PSC2_IRQ (MPC5XXX_PERP_IRQ_BASE + 2) +#define MPC5XXX_PSC3_IRQ (MPC5XXX_PERP_IRQ_BASE + 3) +#define MPC5XXX_PSC6_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) +#define MPC5XXX_IRDA_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) +#define MPC5XXX_FEC_IRQ (MPC5XXX_PERP_IRQ_BASE + 5) +#define MPC5XXX_USB_IRQ (MPC5XXX_PERP_IRQ_BASE + 6) +#define MPC5XXX_ATA_IRQ (MPC5XXX_PERP_IRQ_BASE + 7) +#define MPC5XXX_PCI_CNTRL_IRQ (MPC5XXX_PERP_IRQ_BASE + 8) +#define MPC5XXX_PCI_SCIRX_IRQ (MPC5XXX_PERP_IRQ_BASE + 9) +#define MPC5XXX_PCI_SCITX_IRQ (MPC5XXX_PERP_IRQ_BASE + 10) +#define MPC5XXX_PSC4_IRQ (MPC5XXX_PERP_IRQ_BASE + 11) +#define MPC5XXX_PSC5_IRQ (MPC5XXX_PERP_IRQ_BASE + 12) +#define MPC5XXX_SPI_MODF_IRQ (MPC5XXX_PERP_IRQ_BASE + 13) +#define MPC5XXX_SPI_SPIF_IRQ (MPC5XXX_PERP_IRQ_BASE + 14) +#define MPC5XXX_I2C1_IRQ (MPC5XXX_PERP_IRQ_BASE + 15) +#define MPC5XXX_I2C2_IRQ (MPC5XXX_PERP_IRQ_BASE + 16) +#define MPC5XXX_MSCAN1_IRQ (MPC5XXX_PERP_IRQ_BASE + 17) +#define MPC5XXX_MSCAN2_IRQ (MPC5XXX_PERP_IRQ_BASE + 18) +#define MPC5XXX_IR_RX_IRQ (MPC5XXX_PERP_IRQ_BASE + 19) +#define MPC5XXX_IR_TX_IRQ (MPC5XXX_PERP_IRQ_BASE + 20) +#define MPC5XXX_XLB_ARB_IRQ (MPC5XXX_PERP_IRQ_BASE + 21) +#define MPC5XXX_BDLC_IRQ (MPC5XXX_PERP_IRQ_BASE + 22) + +/* General Purpose Timers registers */ +#define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0) +#define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4) +#define MPC5XXX_GPT0_STATUS (MPC5XXX_GPT + 0x0C) +#define MPC5XXX_GPT1_ENABLE (MPC5XXX_GPT + 0x10) +#define MPC5XXX_GPT1_COUNTER (MPC5XXX_GPT + 0x14) +#define MPC5XXX_GPT1_STATUS (MPC5XXX_GPT + 0x1C) +#define MPC5XXX_GPT2_ENABLE (MPC5XXX_GPT + 0x20) +#define MPC5XXX_GPT2_COUNTER (MPC5XXX_GPT + 0x24) +#define MPC5XXX_GPT2_STATUS (MPC5XXX_GPT + 0x2C) +#define MPC5XXX_GPT3_ENABLE (MPC5XXX_GPT + 0x30) +#define MPC5XXX_GPT3_COUNTER (MPC5XXX_GPT + 0x34) +#define MPC5XXX_GPT3_STATUS (MPC5XXX_GPT + 0x3C) +#define MPC5XXX_GPT4_ENABLE (MPC5XXX_GPT + 0x40) +#define MPC5XXX_GPT4_COUNTER (MPC5XXX_GPT + 0x44) +#define MPC5XXX_GPT4_STATUS (MPC5XXX_GPT + 0x4C) +#define MPC5XXX_GPT5_ENABLE (MPC5XXX_GPT + 0x50) +#define MPC5XXX_GPT5_STATUS (MPC5XXX_GPT + 0x5C) +#define MPC5XXX_GPT5_COUNTER (MPC5XXX_GPT + 0x54) +#define MPC5XXX_GPT6_ENABLE (MPC5XXX_GPT + 0x60) +#define MPC5XXX_GPT6_COUNTER (MPC5XXX_GPT + 0x64) +#define MPC5XXX_GPT6_STATUS (MPC5XXX_GPT + 0x6C) +#define MPC5XXX_GPT7_ENABLE (MPC5XXX_GPT + 0x70) +#define MPC5XXX_GPT7_COUNTER (MPC5XXX_GPT + 0x74) +#define MPC5XXX_GPT7_STATUS (MPC5XXX_GPT + 0x7C) + +#define MPC5XXX_GPT_GPIO_PIN(status) ((0x00000100 & (status)) >> 8) + +#define MPC5XXX_GPT7_PWMCFG (MPC5XXX_GPT + 0x78) + +/* ATA registers */ +#define MPC5XXX_ATA_HOST_CONFIG (MPC5XXX_ATA + 0x0000) +#define MPC5XXX_ATA_PIO1 (MPC5XXX_ATA + 0x0008) +#define MPC5XXX_ATA_PIO2 (MPC5XXX_ATA + 0x000C) +#define MPC5XXX_ATA_SHARE_COUNT (MPC5XXX_ATA + 0x002C) + +/* I2Cn control register bits */ +#define I2C_EN 0x80 +#define I2C_IEN 0x40 +#define I2C_STA 0x20 +#define I2C_TX 0x10 +#define I2C_TXAK 0x08 +#define I2C_RSTA 0x04 +#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA) + +/* I2Cn status register bits */ +#define I2C_CF 0x80 +#define I2C_AAS 0x40 +#define I2C_BB 0x20 +#define I2C_AL 0x10 +#define I2C_SRW 0x04 +#define I2C_IF 0x02 +#define I2C_RXAK 0x01 + +/* Programmable Serial Controller (PSC) status register bits */ +#define PSC_SR_CDE 0x0080 +#define PSC_SR_RXRDY 0x0100 +#define PSC_SR_RXFULL 0x0200 +#define PSC_SR_TXRDY 0x0400 +#define PSC_SR_TXEMP 0x0800 +#define PSC_SR_OE 0x1000 +#define PSC_SR_PE 0x2000 +#define PSC_SR_FE 0x4000 +#define PSC_SR_RB 0x8000 + +/* PSC Command values */ +#define PSC_RX_ENABLE 0x0001 +#define PSC_RX_DISABLE 0x0002 +#define PSC_TX_ENABLE 0x0004 +#define PSC_TX_DISABLE 0x0008 +#define PSC_SEL_MODE_REG_1 0x0010 +#define PSC_RST_RX 0x0020 +#define PSC_RST_TX 0x0030 +#define PSC_RST_ERR_STAT 0x0040 +#define PSC_RST_BRK_CHG_INT 0x0050 +#define PSC_START_BRK 0x0060 +#define PSC_STOP_BRK 0x0070 + +/* PSC Rx FIFO status bits */ +#define PSC_RX_FIFO_ERR 0x0040 +#define PSC_RX_FIFO_UF 0x0020 +#define PSC_RX_FIFO_OF 0x0010 +#define PSC_RX_FIFO_FR 0x0008 +#define PSC_RX_FIFO_FULL 0x0004 +#define PSC_RX_FIFO_ALARM 0x0002 +#define PSC_RX_FIFO_EMPTY 0x0001 + +/* PSC interrupt mask bits */ +#define PSC_IMR_TXRDY 0x0100 +#define PSC_IMR_RXRDY 0x0200 +#define PSC_IMR_DB 0x0400 +#define PSC_IMR_IPC 0x8000 + +/* PSC input port change bits */ +#define PSC_IPCR_CTS 0x01 +#define PSC_IPCR_DCD 0x02 + +/* PSC mode fields */ +#define PSC_MODE_5_BITS 0x00 +#define PSC_MODE_6_BITS 0x01 +#define PSC_MODE_7_BITS 0x02 +#define PSC_MODE_8_BITS 0x03 +#define PSC_MODE_PAREVEN 0x00 +#define PSC_MODE_PARODD 0x04 +#define PSC_MODE_PARFORCE 0x08 +#define PSC_MODE_PARNONE 0x10 +#define PSC_MODE_ERR 0x20 +#define PSC_MODE_FFULL 0x40 +#define PSC_MODE_RXRTS 0x80 + +#define PSC_MODE_ONE_STOP_5_BITS 0x00 +#define PSC_MODE_ONE_STOP 0x07 +#define PSC_MODE_TWO_STOP 0x0f + + +/* ATA config fields */ +#define MPC5xxx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine + reset */ +#define MPC5xxx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */ +#define MPC5xxx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt + in PIO */ +#define MPC5xxx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports + IORDY protocol */ + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> + +struct mpc5xxx_psc { + volatile u8 mode; /* PSC + 0x00 */ + volatile u8 reserved0[3]; + union { /* PSC + 0x04 */ + volatile u16 status; + volatile u16 clock_select; + } sr_csr; +#define psc_status sr_csr.status +#define psc_clock_select sr_csr.clock_select + volatile u16 reserved1; + volatile u8 command; /* PSC + 0x08 */ + volatile u8 reserved2[3]; + union { /* PSC + 0x0c */ + volatile u8 buffer_8; + volatile u16 buffer_16; + volatile u32 buffer_32; + } buffer; +#define psc_buffer_8 buffer.buffer_8 +#define psc_buffer_16 buffer.buffer_16 +#define psc_buffer_32 buffer.buffer_32 + union { /* PSC + 0x10 */ + volatile u8 ipcr; + volatile u8 acr; + } ipcr_acr; +#define psc_ipcr ipcr_acr.ipcr +#define psc_acr ipcr_acr.acr + volatile u8 reserved3[3]; + union { /* PSC + 0x14 */ + volatile u16 isr; + volatile u16 imr; + } isr_imr; +#define psc_isr isr_imr.isr +#define psc_imr isr_imr.imr + volatile u16 reserved4; + volatile u8 ctur; /* PSC + 0x18 */ + volatile u8 reserved5[3]; + volatile u8 ctlr; /* PSC + 0x1c */ + volatile u8 reserved6[3]; + volatile u16 ccr; /* PSC + 0x20 */ + volatile u8 reserved7[14]; + volatile u8 ivr; /* PSC + 0x30 */ + volatile u8 reserved8[3]; + volatile u8 ip; /* PSC + 0x34 */ + volatile u8 reserved9[3]; + volatile u8 op1; /* PSC + 0x38 */ + volatile u8 reserved10[3]; + volatile u8 op0; /* PSC + 0x3c */ + volatile u8 reserved11[3]; + volatile u32 sicr; /* PSC + 0x40 */ + volatile u8 ircr1; /* PSC + 0x44 */ + volatile u8 reserved12[3]; + volatile u8 ircr2; /* PSC + 0x44 */ + volatile u8 reserved13[3]; + volatile u8 irsdr; /* PSC + 0x4c */ + volatile u8 reserved14[3]; + volatile u8 irmdr; /* PSC + 0x50 */ + volatile u8 reserved15[3]; + volatile u8 irfdr; /* PSC + 0x54 */ + volatile u8 reserved16[3]; + volatile u16 rfnum; /* PSC + 0x58 */ + volatile u16 reserved17; + volatile u16 tfnum; /* PSC + 0x5c */ + volatile u16 reserved18; + volatile u32 rfdata; /* PSC + 0x60 */ + volatile u16 rfstat; /* PSC + 0x64 */ + volatile u16 reserved20; + volatile u8 rfcntl; /* PSC + 0x68 */ + volatile u8 reserved21[5]; + volatile u16 rfalarm; /* PSC + 0x6e */ + volatile u16 reserved22; + volatile u16 rfrptr; /* PSC + 0x72 */ + volatile u16 reserved23; + volatile u16 rfwptr; /* PSC + 0x76 */ + volatile u16 reserved24; + volatile u16 rflrfptr; /* PSC + 0x7a */ + volatile u16 reserved25; + volatile u16 rflwfptr; /* PSC + 0x7e */ + volatile u32 tfdata; /* PSC + 0x80 */ + volatile u16 tfstat; /* PSC + 0x84 */ + volatile u16 reserved26; + volatile u8 tfcntl; /* PSC + 0x88 */ + volatile u8 reserved27[5]; + volatile u16 tfalarm; /* PSC + 0x8e */ + volatile u16 reserved28; + volatile u16 tfrptr; /* PSC + 0x92 */ + volatile u16 reserved29; + volatile u16 tfwptr; /* PSC + 0x96 */ + volatile u16 reserved30; + volatile u16 tflrfptr; /* PSC + 0x9a */ + volatile u16 reserved31; + volatile u16 tflwfptr; /* PSC + 0x9e */ +}; + +struct mpc5xxx_intr { + volatile u32 per_mask; /* INTR + 0x00 */ + volatile u32 per_pri1; /* INTR + 0x04 */ + volatile u32 per_pri2; /* INTR + 0x08 */ + volatile u32 per_pri3; /* INTR + 0x0c */ + volatile u32 ctrl; /* INTR + 0x10 */ + volatile u32 main_mask; /* INTR + 0x14 */ + volatile u32 main_pri1; /* INTR + 0x18 */ + volatile u32 main_pri2; /* INTR + 0x1c */ + volatile u32 reserved1; /* INTR + 0x20 */ + volatile u32 enc_status; /* INTR + 0x24 */ + volatile u32 crit_status; /* INTR + 0x28 */ + volatile u32 main_status; /* INTR + 0x2c */ + volatile u32 per_status; /* INTR + 0x30 */ + volatile u32 reserved2; /* INTR + 0x34 */ + volatile u32 per_error; /* INTR + 0x38 */ +}; + +struct mpc5xxx_gpio { + volatile u32 port_config; /* GPIO + 0x00 */ + volatile u32 simple_gpioe; /* GPIO + 0x04 */ + volatile u32 simple_ode; /* GPIO + 0x08 */ + volatile u32 simple_ddr; /* GPIO + 0x0c */ + volatile u32 simple_dvo; /* GPIO + 0x10 */ + volatile u32 simple_ival; /* GPIO + 0x14 */ + volatile u8 outo_gpioe; /* GPIO + 0x18 */ + volatile u8 reserved1[3]; /* GPIO + 0x19 */ + volatile u8 outo_dvo; /* GPIO + 0x1c */ + volatile u8 reserved2[3]; /* GPIO + 0x1d */ + volatile u8 sint_gpioe; /* GPIO + 0x20 */ + volatile u8 reserved3[3]; /* GPIO + 0x21 */ + volatile u8 sint_ode; /* GPIO + 0x24 */ + volatile u8 reserved4[3]; /* GPIO + 0x25 */ + volatile u8 sint_ddr; /* GPIO + 0x28 */ + volatile u8 reserved5[3]; /* GPIO + 0x29 */ + volatile u8 sint_dvo; /* GPIO + 0x2c */ + volatile u8 reserved6[3]; /* GPIO + 0x2d */ + volatile u8 sint_inten; /* GPIO + 0x30 */ + volatile u8 reserved7[3]; /* GPIO + 0x31 */ + volatile u16 sint_itype; /* GPIO + 0x34 */ + volatile u16 reserved8; /* GPIO + 0x36 */ + volatile u8 gpio_control; /* GPIO + 0x38 */ + volatile u8 reserved9[3]; /* GPIO + 0x39 */ + volatile u8 sint_istat; /* GPIO + 0x3c */ + volatile u8 sint_ival; /* GPIO + 0x3d */ + volatile u8 bus_errs; /* GPIO + 0x3e */ + volatile u8 reserved10; /* GPIO + 0x3f */ +}; + +struct mpc5xxx_sdma { + volatile u32 taskBar; /* SDMA + 0x00 */ + volatile u32 currentPointer; /* SDMA + 0x04 */ + volatile u32 endPointer; /* SDMA + 0x08 */ + volatile u32 variablePointer; /* SDMA + 0x0c */ + + volatile u8 IntVect1; /* SDMA + 0x10 */ + volatile u8 IntVect2; /* SDMA + 0x11 */ + volatile u16 PtdCntrl; /* SDMA + 0x12 */ + + volatile u32 IntPend; /* SDMA + 0x14 */ + volatile u32 IntMask; /* SDMA + 0x18 */ + + volatile u16 tcr_0; /* SDMA + 0x1c */ + volatile u16 tcr_1; /* SDMA + 0x1e */ + volatile u16 tcr_2; /* SDMA + 0x20 */ + volatile u16 tcr_3; /* SDMA + 0x22 */ + volatile u16 tcr_4; /* SDMA + 0x24 */ + volatile u16 tcr_5; /* SDMA + 0x26 */ + volatile u16 tcr_6; /* SDMA + 0x28 */ + volatile u16 tcr_7; /* SDMA + 0x2a */ + volatile u16 tcr_8; /* SDMA + 0x2c */ + volatile u16 tcr_9; /* SDMA + 0x2e */ + volatile u16 tcr_a; /* SDMA + 0x30 */ + volatile u16 tcr_b; /* SDMA + 0x32 */ + volatile u16 tcr_c; /* SDMA + 0x34 */ + volatile u16 tcr_d; /* SDMA + 0x36 */ + volatile u16 tcr_e; /* SDMA + 0x38 */ + volatile u16 tcr_f; /* SDMA + 0x3a */ + + volatile u8 IPR0; /* SDMA + 0x3c */ + volatile u8 IPR1; /* SDMA + 0x3d */ + volatile u8 IPR2; /* SDMA + 0x3e */ + volatile u8 IPR3; /* SDMA + 0x3f */ + volatile u8 IPR4; /* SDMA + 0x40 */ + volatile u8 IPR5; /* SDMA + 0x41 */ + volatile u8 IPR6; /* SDMA + 0x42 */ + volatile u8 IPR7; /* SDMA + 0x43 */ + volatile u8 IPR8; /* SDMA + 0x44 */ + volatile u8 IPR9; /* SDMA + 0x45 */ + volatile u8 IPR10; /* SDMA + 0x46 */ + volatile u8 IPR11; /* SDMA + 0x47 */ + volatile u8 IPR12; /* SDMA + 0x48 */ + volatile u8 IPR13; /* SDMA + 0x49 */ + volatile u8 IPR14; /* SDMA + 0x4a */ + volatile u8 IPR15; /* SDMA + 0x4b */ + volatile u8 IPR16; /* SDMA + 0x4c */ + volatile u8 IPR17; /* SDMA + 0x4d */ + volatile u8 IPR18; /* SDMA + 0x4e */ + volatile u8 IPR19; /* SDMA + 0x4f */ + volatile u8 IPR20; /* SDMA + 0x50 */ + volatile u8 IPR21; /* SDMA + 0x51 */ + volatile u8 IPR22; /* SDMA + 0x52 */ + volatile u8 IPR23; /* SDMA + 0x53 */ + volatile u8 IPR24; /* SDMA + 0x54 */ + volatile u8 IPR25; /* SDMA + 0x55 */ + volatile u8 IPR26; /* SDMA + 0x56 */ + volatile u8 IPR27; /* SDMA + 0x57 */ + volatile u8 IPR28; /* SDMA + 0x58 */ + volatile u8 IPR29; /* SDMA + 0x59 */ + volatile u8 IPR30; /* SDMA + 0x5a */ + volatile u8 IPR31; /* SDMA + 0x5b */ + + volatile u32 res1; /* SDMA + 0x5c */ + volatile u32 res2; /* SDMA + 0x60 */ + volatile u32 res3; /* SDMA + 0x64 */ + volatile u32 MDEDebug; /* SDMA + 0x68 */ + volatile u32 ADSDebug; /* SDMA + 0x6c */ + volatile u32 Value1; /* SDMA + 0x70 */ + volatile u32 Value2; /* SDMA + 0x74 */ + volatile u32 Control; /* SDMA + 0x78 */ + volatile u32 Status; /* SDMA + 0x7c */ + volatile u32 EU00; /* SDMA + 0x80 */ + volatile u32 EU01; /* SDMA + 0x84 */ + volatile u32 EU02; /* SDMA + 0x88 */ + volatile u32 EU03; /* SDMA + 0x8c */ + volatile u32 EU04; /* SDMA + 0x90 */ + volatile u32 EU05; /* SDMA + 0x94 */ + volatile u32 EU06; /* SDMA + 0x98 */ + volatile u32 EU07; /* SDMA + 0x9c */ + volatile u32 EU10; /* SDMA + 0xa0 */ + volatile u32 EU11; /* SDMA + 0xa4 */ + volatile u32 EU12; /* SDMA + 0xa8 */ + volatile u32 EU13; /* SDMA + 0xac */ + volatile u32 EU14; /* SDMA + 0xb0 */ + volatile u32 EU15; /* SDMA + 0xb4 */ + volatile u32 EU16; /* SDMA + 0xb8 */ + volatile u32 EU17; /* SDMA + 0xbc */ + volatile u32 EU20; /* SDMA + 0xc0 */ + volatile u32 EU21; /* SDMA + 0xc4 */ + volatile u32 EU22; /* SDMA + 0xc8 */ + volatile u32 EU23; /* SDMA + 0xcc */ + volatile u32 EU24; /* SDMA + 0xd0 */ + volatile u32 EU25; /* SDMA + 0xd4 */ + volatile u32 EU26; /* SDMA + 0xd8 */ + volatile u32 EU27; /* SDMA + 0xdc */ + volatile u32 EU30; /* SDMA + 0xe0 */ + volatile u32 EU31; /* SDMA + 0xe4 */ + volatile u32 EU32; /* SDMA + 0xe8 */ + volatile u32 EU33; /* SDMA + 0xec */ + volatile u32 EU34; /* SDMA + 0xf0 */ + volatile u32 EU35; /* SDMA + 0xf4 */ + volatile u32 EU36; /* SDMA + 0xf8 */ + volatile u32 EU37; /* SDMA + 0xfc */ +}; + +struct mpc5xxx_i2c { + volatile u32 madr; /* I2Cn + 0x00 */ + volatile u32 mfdr; /* I2Cn + 0x04 */ + volatile u32 mcr; /* I2Cn + 0x08 */ + volatile u32 msr; /* I2Cn + 0x0C */ + volatile u32 mdr; /* I2Cn + 0x10 */ +}; + +struct mpc5xxx_spi { + volatile u8 cr1; /* SPI + 0x0F00 */ + volatile u8 cr2; /* SPI + 0x0F01 */ + volatile u8 reserved1[2]; + volatile u8 brr; /* SPI + 0x0F04 */ + volatile u8 sr; /* SPI + 0x0F05 */ + volatile u8 reserved2[3]; + volatile u8 dr; /* SPI + 0x0F09 */ + volatile u8 reserved3[3]; + volatile u8 pdr; /* SPI + 0x0F0D */ + volatile u8 reserved4[2]; + volatile u8 ddr; /* SPI + 0x0F10 */ +}; + + +struct mpc5xxx_gpt { + volatile u32 emsr; /* GPT + Timer# * 0x10 + 0x00 */ + volatile u32 cir; /* GPT + Timer# * 0x10 + 0x04 */ + volatile u32 pwmcr; /* GPT + Timer# * 0x10 + 0x08 */ + volatile u32 sr; /* GPT + Timer# * 0x10 + 0x0c */ +}; + +struct mpc5xxx_gpt_0_7 { + struct mpc5xxx_gpt gpt0; + struct mpc5xxx_gpt gpt1; + struct mpc5xxx_gpt gpt2; + struct mpc5xxx_gpt gpt3; + struct mpc5xxx_gpt gpt4; + struct mpc5xxx_gpt gpt5; + struct mpc5xxx_gpt gpt6; + struct mpc5xxx_gpt gpt7; +}; + +struct mscan_buffer { + volatile u8 idr[0x8]; /* 0x00 */ + volatile u8 dsr[0x10]; /* 0x08 */ + volatile u8 dlr; /* 0x18 */ + volatile u8 tbpr; /* 0x19 */ /* This register is not applicable for receive buffers */ + volatile u16 rsrv1; /* 0x1A */ + volatile u8 tsrh; /* 0x1C */ + volatile u8 tsrl; /* 0x1D */ + volatile u16 rsrv2; /* 0x1E */ +}; + +struct mpc5xxx_mscan { + volatile u8 canctl0; /* MSCAN + 0x00 */ + volatile u8 canctl1; /* MSCAN + 0x01 */ + volatile u16 rsrv1; /* MSCAN + 0x02 */ + volatile u8 canbtr0; /* MSCAN + 0x04 */ + volatile u8 canbtr1; /* MSCAN + 0x05 */ + volatile u16 rsrv2; /* MSCAN + 0x06 */ + volatile u8 canrflg; /* MSCAN + 0x08 */ + volatile u8 canrier; /* MSCAN + 0x09 */ + volatile u16 rsrv3; /* MSCAN + 0x0A */ + volatile u8 cantflg; /* MSCAN + 0x0C */ + volatile u8 cantier; /* MSCAN + 0x0D */ + volatile u16 rsrv4; /* MSCAN + 0x0E */ + volatile u8 cantarq; /* MSCAN + 0x10 */ + volatile u8 cantaak; /* MSCAN + 0x11 */ + volatile u16 rsrv5; /* MSCAN + 0x12 */ + volatile u8 cantbsel; /* MSCAN + 0x14 */ + volatile u8 canidac; /* MSCAN + 0x15 */ + volatile u16 rsrv6[3]; /* MSCAN + 0x16 */ + volatile u8 canrxerr; /* MSCAN + 0x1C */ + volatile u8 cantxerr; /* MSCAN + 0x1D */ + volatile u16 rsrv7; /* MSCAN + 0x1E */ + volatile u8 canidar0; /* MSCAN + 0x20 */ + volatile u8 canidar1; /* MSCAN + 0x21 */ + volatile u16 rsrv8; /* MSCAN + 0x22 */ + volatile u8 canidar2; /* MSCAN + 0x24 */ + volatile u8 canidar3; /* MSCAN + 0x25 */ + volatile u16 rsrv9; /* MSCAN + 0x26 */ + volatile u8 canidmr0; /* MSCAN + 0x28 */ + volatile u8 canidmr1; /* MSCAN + 0x29 */ + volatile u16 rsrv10; /* MSCAN + 0x2A */ + volatile u8 canidmr2; /* MSCAN + 0x2C */ + volatile u8 canidmr3; /* MSCAN + 0x2D */ + volatile u16 rsrv11; /* MSCAN + 0x2E */ + volatile u8 canidar4; /* MSCAN + 0x30 */ + volatile u8 canidar5; /* MSCAN + 0x31 */ + volatile u16 rsrv12; /* MSCAN + 0x32 */ + volatile u8 canidar6; /* MSCAN + 0x34 */ + volatile u8 canidar7; /* MSCAN + 0x35 */ + volatile u16 rsrv13; /* MSCAN + 0x36 */ + volatile u8 canidmr4; /* MSCAN + 0x38 */ + volatile u8 canidmr5; /* MSCAN + 0x39 */ + volatile u16 rsrv14; /* MSCAN + 0x3A */ + volatile u8 canidmr6; /* MSCAN + 0x3C */ + volatile u8 canidmr7; /* MSCAN + 0x3D */ + volatile u16 rsrv15; /* MSCAN + 0x3E */ + + struct mscan_buffer canrxfg; /* MSCAN + 0x40 */ /* Foreground receive buffer */ + struct mscan_buffer cantxfg; /* MSCAN + 0x60 */ /* Foreground transmit buffer */ + }; + +/* function prototypes */ +void loadtask(int basetask, int tasks); + +/* retrieve configured sdram size connected to a chipselect */ +unsigned long mpc5200_get_sdram_size(unsigned int cs); + +/* configure a local plus bus chip select */ +#define MPC5200_BOOTCS 8 +void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg); + +/* configure bus speeds. Both dividers are relative to xlb clock */ +int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv); + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASMPPC_MPC5200_H */ diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h index f2cae90..2455484 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h @@ -1,793 +1,8 @@ -/* - * arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h - * - * Prototypes, etc. for the Motorola MGT5xxx/MPC5xxx - * embedded cpu chips - * - * 2003 (c) MontaVista, Software, Inc. - * Author: Dale Farnsworth <dfarnsworth@mvista.com> - * - * 2003 (C) 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. - * - */ #ifndef __ASMPPC_MPC5XXX_H #define __ASMPPC_MPC5XXX_H -/* Processor name */ -#if defined(CONFIG_MPC5200) -#define CPU_ID_STR "MPC5200" -#elif defined(CONFIG_MGT5100) -#define CPU_ID_STR "MGT5100" +#if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100) +# include <mach/mpc5200.h> +#else +# error "Undefined Core CPU" #endif - -/* Exception offsets (PowerPC standard) */ -#define EXC_OFF_SYS_RESET 0x0100 -#define _START_OFFSET EXC_OFF_SYS_RESET - -#define CFG_MBAR 0xf0000000 - -/* useful macros for manipulating CSx_START/STOP */ -#if defined(CONFIG_MGT5100) -#define START_REG(start) ((start) >> 15) -#define STOP_REG(start, size) (((start) + (size) - 1) >> 15) -#elif defined(CONFIG_MPC5200) -#define START_REG(start) ((start) >> 16) -#define STOP_REG(start, size) (((start) + (size) - 1) >> 16) -#endif - -/* Internal memory map */ - -#define MPC5XXX_CS0_START (CFG_MBAR + 0x0004) -#define MPC5XXX_CS0_STOP (CFG_MBAR + 0x0008) -#define MPC5XXX_CS1_START (CFG_MBAR + 0x000c) -#define MPC5XXX_CS1_STOP (CFG_MBAR + 0x0010) -#define MPC5XXX_CS2_START (CFG_MBAR + 0x0014) -#define MPC5XXX_CS2_STOP (CFG_MBAR + 0x0018) -#define MPC5XXX_CS3_START (CFG_MBAR + 0x001c) -#define MPC5XXX_CS3_STOP (CFG_MBAR + 0x0020) -#define MPC5XXX_CS4_START (CFG_MBAR + 0x0024) -#define MPC5XXX_CS4_STOP (CFG_MBAR + 0x0028) -#define MPC5XXX_CS5_START (CFG_MBAR + 0x002c) -#define MPC5XXX_CS5_STOP (CFG_MBAR + 0x0030) -#define MPC5XXX_BOOTCS_START (CFG_MBAR + 0x004c) -#define MPC5XXX_BOOTCS_STOP (CFG_MBAR + 0x0050) -#define MPC5XXX_ADDECR (CFG_MBAR + 0x0054) - -#if defined(CONFIG_MGT5100) -#define MPC5XXX_SDRAM_START (CFG_MBAR + 0x0034) -#define MPC5XXX_SDRAM_STOP (CFG_MBAR + 0x0038) -#define MPC5XXX_PCI1_START (CFG_MBAR + 0x003c) -#define MPC5XXX_PCI1_STOP (CFG_MBAR + 0x0040) -#define MPC5XXX_PCI2_START (CFG_MBAR + 0x0044) -#define MPC5XXX_PCI2_STOP (CFG_MBAR + 0x0048) -#elif defined(CONFIG_MPC5200) -#define MPC5XXX_CS6_START (CFG_MBAR + 0x0058) -#define MPC5XXX_CS6_STOP (CFG_MBAR + 0x005c) -#define MPC5XXX_CS7_START (CFG_MBAR + 0x0060) -#define MPC5XXX_CS7_STOP (CFG_MBAR + 0x0064) -#define MPC5XXX_SDRAM_CS0CFG (CFG_MBAR + 0x0034) -#define MPC5XXX_SDRAM_CS1CFG (CFG_MBAR + 0x0038) -#endif - -#define MPC5XXX_SDRAM (CFG_MBAR + 0x0100) -#define MPC5XXX_CDM (CFG_MBAR + 0x0200) -#define MPC5XXX_LPB (CFG_MBAR + 0x0300) -#define MPC5XXX_ICTL (CFG_MBAR + 0x0500) -#define MPC5XXX_GPT (CFG_MBAR + 0x0600) -#define MPC5XXX_GPIO (CFG_MBAR + 0x0b00) -#define MPC5XXX_WU_GPIO (CFG_MBAR + 0x0c00) -#define MPC5XXX_PCI (CFG_MBAR + 0x0d00) -#define MPC5XXX_SPI (CFG_MBAR + 0x0f00) -#define MPC5XXX_USB (CFG_MBAR + 0x1000) -#define MPC5XXX_SDMA (CFG_MBAR + 0x1200) -#define MPC5XXX_XLBARB (CFG_MBAR + 0x1f00) - -#if defined(CONFIG_MGT5100) -#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000) -#define MPC5XXX_PSC2 (CFG_MBAR + 0x2400) -#define MPC5XXX_PSC3 (CFG_MBAR + 0x2800) -#elif defined(CONFIG_MPC5200) -#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000) -#define MPC5XXX_PSC2 (CFG_MBAR + 0x2200) -#define MPC5XXX_PSC3 (CFG_MBAR + 0x2400) -#define MPC5XXX_PSC4 (CFG_MBAR + 0x2600) -#define MPC5XXX_PSC5 (CFG_MBAR + 0x2800) -#define MPC5XXX_PSC6 (CFG_MBAR + 0x2c00) -#endif - -#define MPC5XXX_FEC (CFG_MBAR + 0x3000) -#define MPC5XXX_ATA (CFG_MBAR + 0x3A00) - -#define MPC5XXX_I2C1 (CFG_MBAR + 0x3D00) -#define MPC5XXX_I2C2 (CFG_MBAR + 0x3D40) - -#if defined(CONFIG_MGT5100) -#define MPC5XXX_SRAM (CFG_MBAR + 0x4000) -#define MPC5XXX_SRAM_SIZE (8*1024) -#elif defined(CONFIG_MPC5200) -#define MPC5XXX_SRAM (CFG_MBAR + 0x8000) -#define MPC5XXX_SRAM_SIZE (16*1024) -#endif - -/* SDRAM Controller */ -#define MPC5XXX_SDRAM_MODE (MPC5XXX_SDRAM + 0x0000) -#define MPC5XXX_SDRAM_CTRL (MPC5XXX_SDRAM + 0x0004) -#define MPC5XXX_SDRAM_CONFIG1 (MPC5XXX_SDRAM + 0x0008) -#define MPC5XXX_SDRAM_CONFIG2 (MPC5XXX_SDRAM + 0x000c) -#if defined(CONFIG_MGT5100) -#define MPC5XXX_SDRAM_XLBSEL (MPC5XXX_SDRAM + 0x0010) -#endif -#define MPC5XXX_SDRAM_SDELAY (MPC5XXX_SDRAM + 0x0090) - -/* Clock Distribution Module */ -#define MPC5XXX_CDM_JTAGID (MPC5XXX_CDM + 0x0000) -#define MPC5XXX_CDM_PORCFG (MPC5XXX_CDM + 0x0004) -#define MPC5XXX_CDM_CFG (MPC5XXX_CDM + 0x000c) -#define MPC5XXX_CDM_48_FDC (MPC5XXX_CDM + 0x0010) -#define MPC5XXX_CDM_SRESET (MPC5XXX_CDM + 0x0020) - -/* Local Plus Bus interface */ -#define MPC5XXX_CS0_CFG (MPC5XXX_LPB + 0x0000) -#define MPC5XXX_CS1_CFG (MPC5XXX_LPB + 0x0004) -#define MPC5XXX_CS2_CFG (MPC5XXX_LPB + 0x0008) -#define MPC5XXX_CS3_CFG (MPC5XXX_LPB + 0x000c) -#define MPC5XXX_CS4_CFG (MPC5XXX_LPB + 0x0010) -#define MPC5XXX_CS5_CFG (MPC5XXX_LPB + 0x0014) -#define MPC5XXX_BOOTCS_CFG MPC5XXX_CS0_CFG -#define MPC5XXX_CS_CTRL (MPC5XXX_LPB + 0x0018) -#define MPC5XXX_CS_STATUS (MPC5XXX_LPB + 0x001c) -#if defined(CONFIG_MPC5200) -#define MPC5XXX_CS6_CFG (MPC5XXX_LPB + 0x0020) -#define MPC5XXX_CS7_CFG (MPC5XXX_LPB + 0x0024) -#define MPC5XXX_CS_BURST (MPC5XXX_LPB + 0x0028) -#define MPC5XXX_CS_DEADCYCLE (MPC5XXX_LPB + 0x002c) -#endif - -#if defined(CONFIG_MPC5200) -/* XLB Arbiter registers */ -#define MPC5XXX_XLBARB_CFG (MPC5XXX_XLBARB + 0x40) -#define MPC5XXX_XLBARB_MPRIEN (MPC5XXX_XLBARB + 0x64) -#define MPC5XXX_XLBARB_MPRIVAL (MPC5XXX_XLBARB + 0x68) -#endif - -/* GPIO registers */ -#define MPC5XXX_GPS_PORT_CONFIG (MPC5XXX_GPIO + 0x0000) - -/* Standard GPIO registers (simple, output only and simple interrupt */ -#define MPC5XXX_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004) -#define MPC5XXX_GPIO_ODE (MPC5XXX_GPIO + 0x0008) -#define MPC5XXX_GPIO_DIR (MPC5XXX_GPIO + 0x000c) -#define MPC5XXX_GPIO_DATA_O (MPC5XXX_GPIO + 0x0010) -#define MPC5XXX_GPIO_DATA_I (MPC5XXX_GPIO + 0x0014) -#define MPC5XXX_GPIO_OO_ENABLE (MPC5XXX_GPIO + 0x0018) -#define MPC5XXX_GPIO_OO_DATA (MPC5XXX_GPIO + 0x001C) -#define MPC5XXX_GPIO_SI_ENABLE (MPC5XXX_GPIO + 0x0020) -#define MPC5XXX_GPIO_SI_ODE (MPC5XXX_GPIO + 0x0024) -#define MPC5XXX_GPIO_SI_DIR (MPC5XXX_GPIO + 0x0028) -#define MPC5XXX_GPIO_SI_DATA (MPC5XXX_GPIO + 0x002C) -#define MPC5XXX_GPIO_SI_IEN (MPC5XXX_GPIO + 0x0030) -#define MPC5XXX_GPIO_SI_ITYPE (MPC5XXX_GPIO + 0x0034) -#define MPC5XXX_GPIO_SI_MEN (MPC5XXX_GPIO + 0x0038) -#define MPC5XXX_GPIO_SI_STATUS (MPC5XXX_GPIO + 0x003C) - -/* WakeUp GPIO registers */ -#define MPC5XXX_WU_GPIO_ENABLE (MPC5XXX_WU_GPIO + 0x0000) -#define MPC5XXX_WU_GPIO_ODE (MPC5XXX_WU_GPIO + 0x0004) -#define MPC5XXX_WU_GPIO_DIR (MPC5XXX_WU_GPIO + 0x0008) -#define MPC5XXX_WU_GPIO_DATA_O (MPC5XXX_WU_GPIO + 0x000c) -#define MPC5XXX_WU_GPIO_DATA_I (MPC5XXX_WU_GPIO + 0x0020) - -/* GPIO pins */ -#define GPIO_WKUP_7 0x80000000UL -#define GPIO_PSC6_0 0x10000000UL -#define GPIO_PSC3_9 0x04000000UL -#define GPIO_PSC1_4 0x01000000UL - -/* PCI registers */ -#define MPC5XXX_PCI_CMD (MPC5XXX_PCI + 0x04) -#define MPC5XXX_PCI_CFG (MPC5XXX_PCI + 0x0c) -#define MPC5XXX_PCI_BAR0 (MPC5XXX_PCI + 0x10) -#define MPC5XXX_PCI_BAR1 (MPC5XXX_PCI + 0x14) -#if defined(CONFIG_MGT5100) -#define MPC5XXX_PCI_CTRL (MPC5XXX_PCI + 0x68) -#define MPC5XXX_PCI_VALMSKR (MPC5XXX_PCI + 0x6c) -#define MPC5XXX_PCI_VALMSKW (MPC5XXX_PCI + 0x70) -#define MPC5XXX_PCI_SUBW1 (MPC5XXX_PCI + 0x74) -#define MPC5XXX_PCI_SUBW2 (MPC5XXX_PCI + 0x78) -#define MPC5XXX_PCI_WINCOMMAND (MPC5XXX_PCI + 0x7c) -#elif defined(CONFIG_MPC5200) -#define MPC5XXX_PCI_GSCR (MPC5XXX_PCI + 0x60) -#define MPC5XXX_PCI_TBATR0 (MPC5XXX_PCI + 0x64) -#define MPC5XXX_PCI_TBATR1 (MPC5XXX_PCI + 0x68) -#define MPC5XXX_PCI_TCR (MPC5XXX_PCI + 0x6c) -#define MPC5XXX_PCI_IW0BTAR (MPC5XXX_PCI + 0x70) -#define MPC5XXX_PCI_IW1BTAR (MPC5XXX_PCI + 0x74) -#define MPC5XXX_PCI_IW2BTAR (MPC5XXX_PCI + 0x78) -#define MPC5XXX_PCI_IWCR (MPC5XXX_PCI + 0x80) -#define MPC5XXX_PCI_ICR (MPC5XXX_PCI + 0x84) -#define MPC5XXX_PCI_ISR (MPC5XXX_PCI + 0x88) -#define MPC5XXX_PCI_ARB (MPC5XXX_PCI + 0x8c) -#define MPC5XXX_PCI_CAR (MPC5XXX_PCI + 0xf8) -#endif - -/* Interrupt Controller registers */ -#define MPC5XXX_ICTL_PER_MASK (MPC5XXX_ICTL + 0x0000) -#define MPC5XXX_ICTL_PER_PRIO1 (MPC5XXX_ICTL + 0x0004) -#define MPC5XXX_ICTL_PER_PRIO2 (MPC5XXX_ICTL + 0x0008) -#define MPC5XXX_ICTL_PER_PRIO3 (MPC5XXX_ICTL + 0x000c) -#define MPC5XXX_ICTL_EXT (MPC5XXX_ICTL + 0x0010) -#define MPC5XXX_ICTL_CRIT (MPC5XXX_ICTL + 0x0014) -#define MPC5XXX_ICTL_MAIN_PRIO1 (MPC5XXX_ICTL + 0x0018) -#define MPC5XXX_ICTL_MAIN_PRIO2 (MPC5XXX_ICTL + 0x001c) -#define MPC5XXX_ICTL_STS (MPC5XXX_ICTL + 0x0024) -#define MPC5XXX_ICTL_CRIT_STS (MPC5XXX_ICTL + 0x0028) -#define MPC5XXX_ICTL_MAIN_STS (MPC5XXX_ICTL + 0x002c) -#define MPC5XXX_ICTL_PER_STS (MPC5XXX_ICTL + 0x0030) -#define MPC5XXX_ICTL_BUS_STS (MPC5XXX_ICTL + 0x0038) - -#define NR_IRQS 64 - -/* IRQ mapping - these are our logical IRQ numbers */ -#define MPC5XXX_CRIT_IRQ_NUM 4 -#define MPC5XXX_MAIN_IRQ_NUM 17 -#define MPC5XXX_SDMA_IRQ_NUM 17 -#define MPC5XXX_PERP_IRQ_NUM 23 - -#define MPC5XXX_CRIT_IRQ_BASE 1 -#define MPC5XXX_MAIN_IRQ_BASE (MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM) -#define MPC5XXX_SDMA_IRQ_BASE (MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM) -#define MPC5XXX_PERP_IRQ_BASE (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM) - -#define MPC5XXX_IRQ0 (MPC5XXX_CRIT_IRQ_BASE + 0) -#define MPC5XXX_SLICE_TIMER_0_IRQ (MPC5XXX_CRIT_IRQ_BASE + 1) -#define MPC5XXX_HI_INT_IRQ (MPC5XXX_CRIT_IRQ_BASE + 2) -#define MPC5XXX_CCS_IRQ (MPC5XXX_CRIT_IRQ_BASE + 3) - -#define MPC5XXX_IRQ1 (MPC5XXX_MAIN_IRQ_BASE + 1) -#define MPC5XXX_IRQ2 (MPC5XXX_MAIN_IRQ_BASE + 2) -#define MPC5XXX_IRQ3 (MPC5XXX_MAIN_IRQ_BASE + 3) -#define MPC5XXX_RTC_PINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 5) -#define MPC5XXX_RTC_SINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 6) -#define MPC5XXX_RTC_GPIO_STD_IRQ (MPC5XXX_MAIN_IRQ_BASE + 7) -#define MPC5XXX_RTC_GPIO_WKUP_IRQ (MPC5XXX_MAIN_IRQ_BASE + 8) -#define MPC5XXX_TMR0_IRQ (MPC5XXX_MAIN_IRQ_BASE + 9) -#define MPC5XXX_TMR1_IRQ (MPC5XXX_MAIN_IRQ_BASE + 10) -#define MPC5XXX_TMR2_IRQ (MPC5XXX_MAIN_IRQ_BASE + 11) -#define MPC5XXX_TMR3_IRQ (MPC5XXX_MAIN_IRQ_BASE + 12) -#define MPC5XXX_TMR4_IRQ (MPC5XXX_MAIN_IRQ_BASE + 13) -#define MPC5XXX_TMR5_IRQ (MPC5XXX_MAIN_IRQ_BASE + 14) -#define MPC5XXX_TMR6_IRQ (MPC5XXX_MAIN_IRQ_BASE + 15) -#define MPC5XXX_TMR7_IRQ (MPC5XXX_MAIN_IRQ_BASE + 16) - -#define MPC5XXX_SDMA_IRQ (MPC5XXX_PERP_IRQ_BASE + 0) -#define MPC5XXX_PSC1_IRQ (MPC5XXX_PERP_IRQ_BASE + 1) -#define MPC5XXX_PSC2_IRQ (MPC5XXX_PERP_IRQ_BASE + 2) -#define MPC5XXX_PSC3_IRQ (MPC5XXX_PERP_IRQ_BASE + 3) -#define MPC5XXX_PSC6_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) -#define MPC5XXX_IRDA_IRQ (MPC5XXX_PERP_IRQ_BASE + 4) -#define MPC5XXX_FEC_IRQ (MPC5XXX_PERP_IRQ_BASE + 5) -#define MPC5XXX_USB_IRQ (MPC5XXX_PERP_IRQ_BASE + 6) -#define MPC5XXX_ATA_IRQ (MPC5XXX_PERP_IRQ_BASE + 7) -#define MPC5XXX_PCI_CNTRL_IRQ (MPC5XXX_PERP_IRQ_BASE + 8) -#define MPC5XXX_PCI_SCIRX_IRQ (MPC5XXX_PERP_IRQ_BASE + 9) -#define MPC5XXX_PCI_SCITX_IRQ (MPC5XXX_PERP_IRQ_BASE + 10) -#define MPC5XXX_PSC4_IRQ (MPC5XXX_PERP_IRQ_BASE + 11) -#define MPC5XXX_PSC5_IRQ (MPC5XXX_PERP_IRQ_BASE + 12) -#define MPC5XXX_SPI_MODF_IRQ (MPC5XXX_PERP_IRQ_BASE + 13) -#define MPC5XXX_SPI_SPIF_IRQ (MPC5XXX_PERP_IRQ_BASE + 14) -#define MPC5XXX_I2C1_IRQ (MPC5XXX_PERP_IRQ_BASE + 15) -#define MPC5XXX_I2C2_IRQ (MPC5XXX_PERP_IRQ_BASE + 16) -#define MPC5XXX_MSCAN1_IRQ (MPC5XXX_PERP_IRQ_BASE + 17) -#define MPC5XXX_MSCAN2_IRQ (MPC5XXX_PERP_IRQ_BASE + 18) -#define MPC5XXX_IR_RX_IRQ (MPC5XXX_PERP_IRQ_BASE + 19) -#define MPC5XXX_IR_TX_IRQ (MPC5XXX_PERP_IRQ_BASE + 20) -#define MPC5XXX_XLB_ARB_IRQ (MPC5XXX_PERP_IRQ_BASE + 21) -#define MPC5XXX_BDLC_IRQ (MPC5XXX_PERP_IRQ_BASE + 22) - -/* General Purpose Timers registers */ -#define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0) -#define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4) -#define MPC5XXX_GPT0_STATUS (MPC5XXX_GPT + 0x0C) -#define MPC5XXX_GPT1_ENABLE (MPC5XXX_GPT + 0x10) -#define MPC5XXX_GPT1_COUNTER (MPC5XXX_GPT + 0x14) -#define MPC5XXX_GPT1_STATUS (MPC5XXX_GPT + 0x1C) -#define MPC5XXX_GPT2_ENABLE (MPC5XXX_GPT + 0x20) -#define MPC5XXX_GPT2_COUNTER (MPC5XXX_GPT + 0x24) -#define MPC5XXX_GPT2_STATUS (MPC5XXX_GPT + 0x2C) -#define MPC5XXX_GPT3_ENABLE (MPC5XXX_GPT + 0x30) -#define MPC5XXX_GPT3_COUNTER (MPC5XXX_GPT + 0x34) -#define MPC5XXX_GPT3_STATUS (MPC5XXX_GPT + 0x3C) -#define MPC5XXX_GPT4_ENABLE (MPC5XXX_GPT + 0x40) -#define MPC5XXX_GPT4_COUNTER (MPC5XXX_GPT + 0x44) -#define MPC5XXX_GPT4_STATUS (MPC5XXX_GPT + 0x4C) -#define MPC5XXX_GPT5_ENABLE (MPC5XXX_GPT + 0x50) -#define MPC5XXX_GPT5_STATUS (MPC5XXX_GPT + 0x5C) -#define MPC5XXX_GPT5_COUNTER (MPC5XXX_GPT + 0x54) -#define MPC5XXX_GPT6_ENABLE (MPC5XXX_GPT + 0x60) -#define MPC5XXX_GPT6_COUNTER (MPC5XXX_GPT + 0x64) -#define MPC5XXX_GPT6_STATUS (MPC5XXX_GPT + 0x6C) -#define MPC5XXX_GPT7_ENABLE (MPC5XXX_GPT + 0x70) -#define MPC5XXX_GPT7_COUNTER (MPC5XXX_GPT + 0x74) -#define MPC5XXX_GPT7_STATUS (MPC5XXX_GPT + 0x7C) - -#define MPC5XXX_GPT_GPIO_PIN(status) ((0x00000100 & (status)) >> 8) - -#define MPC5XXX_GPT7_PWMCFG (MPC5XXX_GPT + 0x78) - -/* ATA registers */ -#define MPC5XXX_ATA_HOST_CONFIG (MPC5XXX_ATA + 0x0000) -#define MPC5XXX_ATA_PIO1 (MPC5XXX_ATA + 0x0008) -#define MPC5XXX_ATA_PIO2 (MPC5XXX_ATA + 0x000C) -#define MPC5XXX_ATA_SHARE_COUNT (MPC5XXX_ATA + 0x002C) - -/* I2Cn control register bits */ -#define I2C_EN 0x80 -#define I2C_IEN 0x40 -#define I2C_STA 0x20 -#define I2C_TX 0x10 -#define I2C_TXAK 0x08 -#define I2C_RSTA 0x04 -#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA) - -/* I2Cn status register bits */ -#define I2C_CF 0x80 -#define I2C_AAS 0x40 -#define I2C_BB 0x20 -#define I2C_AL 0x10 -#define I2C_SRW 0x04 -#define I2C_IF 0x02 -#define I2C_RXAK 0x01 - -/* Programmable Serial Controller (PSC) status register bits */ -#define PSC_SR_CDE 0x0080 -#define PSC_SR_RXRDY 0x0100 -#define PSC_SR_RXFULL 0x0200 -#define PSC_SR_TXRDY 0x0400 -#define PSC_SR_TXEMP 0x0800 -#define PSC_SR_OE 0x1000 -#define PSC_SR_PE 0x2000 -#define PSC_SR_FE 0x4000 -#define PSC_SR_RB 0x8000 - -/* PSC Command values */ -#define PSC_RX_ENABLE 0x0001 -#define PSC_RX_DISABLE 0x0002 -#define PSC_TX_ENABLE 0x0004 -#define PSC_TX_DISABLE 0x0008 -#define PSC_SEL_MODE_REG_1 0x0010 -#define PSC_RST_RX 0x0020 -#define PSC_RST_TX 0x0030 -#define PSC_RST_ERR_STAT 0x0040 -#define PSC_RST_BRK_CHG_INT 0x0050 -#define PSC_START_BRK 0x0060 -#define PSC_STOP_BRK 0x0070 - -/* PSC Rx FIFO status bits */ -#define PSC_RX_FIFO_ERR 0x0040 -#define PSC_RX_FIFO_UF 0x0020 -#define PSC_RX_FIFO_OF 0x0010 -#define PSC_RX_FIFO_FR 0x0008 -#define PSC_RX_FIFO_FULL 0x0004 -#define PSC_RX_FIFO_ALARM 0x0002 -#define PSC_RX_FIFO_EMPTY 0x0001 - -/* PSC interrupt mask bits */ -#define PSC_IMR_TXRDY 0x0100 -#define PSC_IMR_RXRDY 0x0200 -#define PSC_IMR_DB 0x0400 -#define PSC_IMR_IPC 0x8000 - -/* PSC input port change bits */ -#define PSC_IPCR_CTS 0x01 -#define PSC_IPCR_DCD 0x02 - -/* PSC mode fields */ -#define PSC_MODE_5_BITS 0x00 -#define PSC_MODE_6_BITS 0x01 -#define PSC_MODE_7_BITS 0x02 -#define PSC_MODE_8_BITS 0x03 -#define PSC_MODE_PAREVEN 0x00 -#define PSC_MODE_PARODD 0x04 -#define PSC_MODE_PARFORCE 0x08 -#define PSC_MODE_PARNONE 0x10 -#define PSC_MODE_ERR 0x20 -#define PSC_MODE_FFULL 0x40 -#define PSC_MODE_RXRTS 0x80 - -#define PSC_MODE_ONE_STOP_5_BITS 0x00 -#define PSC_MODE_ONE_STOP 0x07 -#define PSC_MODE_TWO_STOP 0x0f - -/* ATA config fields */ -#define MPC5xxx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine - reset */ -#define MPC5xxx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */ -#define MPC5xxx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt - in PIO */ -#define MPC5xxx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports - IORDY protocol */ - -#ifndef __ASSEMBLY__ - -#include <linux/types.h> - -struct mpc5xxx_psc { - volatile u8 mode; /* PSC + 0x00 */ - volatile u8 reserved0[3]; - union { /* PSC + 0x04 */ - volatile u16 status; - volatile u16 clock_select; - } sr_csr; -#define psc_status sr_csr.status -#define psc_clock_select sr_csr.clock_select - volatile u16 reserved1; - volatile u8 command; /* PSC + 0x08 */ - volatile u8 reserved2[3]; - union { /* PSC + 0x0c */ - volatile u8 buffer_8; - volatile u16 buffer_16; - volatile u32 buffer_32; - } buffer; -#define psc_buffer_8 buffer.buffer_8 -#define psc_buffer_16 buffer.buffer_16 -#define psc_buffer_32 buffer.buffer_32 - union { /* PSC + 0x10 */ - volatile u8 ipcr; - volatile u8 acr; - } ipcr_acr; -#define psc_ipcr ipcr_acr.ipcr -#define psc_acr ipcr_acr.acr - volatile u8 reserved3[3]; - union { /* PSC + 0x14 */ - volatile u16 isr; - volatile u16 imr; - } isr_imr; -#define psc_isr isr_imr.isr -#define psc_imr isr_imr.imr - volatile u16 reserved4; - volatile u8 ctur; /* PSC + 0x18 */ - volatile u8 reserved5[3]; - volatile u8 ctlr; /* PSC + 0x1c */ - volatile u8 reserved6[3]; - volatile u16 ccr; /* PSC + 0x20 */ - volatile u8 reserved7[14]; - volatile u8 ivr; /* PSC + 0x30 */ - volatile u8 reserved8[3]; - volatile u8 ip; /* PSC + 0x34 */ - volatile u8 reserved9[3]; - volatile u8 op1; /* PSC + 0x38 */ - volatile u8 reserved10[3]; - volatile u8 op0; /* PSC + 0x3c */ - volatile u8 reserved11[3]; - volatile u32 sicr; /* PSC + 0x40 */ - volatile u8 ircr1; /* PSC + 0x44 */ - volatile u8 reserved12[3]; - volatile u8 ircr2; /* PSC + 0x44 */ - volatile u8 reserved13[3]; - volatile u8 irsdr; /* PSC + 0x4c */ - volatile u8 reserved14[3]; - volatile u8 irmdr; /* PSC + 0x50 */ - volatile u8 reserved15[3]; - volatile u8 irfdr; /* PSC + 0x54 */ - volatile u8 reserved16[3]; - volatile u16 rfnum; /* PSC + 0x58 */ - volatile u16 reserved17; - volatile u16 tfnum; /* PSC + 0x5c */ - volatile u16 reserved18; - volatile u32 rfdata; /* PSC + 0x60 */ - volatile u16 rfstat; /* PSC + 0x64 */ - volatile u16 reserved20; - volatile u8 rfcntl; /* PSC + 0x68 */ - volatile u8 reserved21[5]; - volatile u16 rfalarm; /* PSC + 0x6e */ - volatile u16 reserved22; - volatile u16 rfrptr; /* PSC + 0x72 */ - volatile u16 reserved23; - volatile u16 rfwptr; /* PSC + 0x76 */ - volatile u16 reserved24; - volatile u16 rflrfptr; /* PSC + 0x7a */ - volatile u16 reserved25; - volatile u16 rflwfptr; /* PSC + 0x7e */ - volatile u32 tfdata; /* PSC + 0x80 */ - volatile u16 tfstat; /* PSC + 0x84 */ - volatile u16 reserved26; - volatile u8 tfcntl; /* PSC + 0x88 */ - volatile u8 reserved27[5]; - volatile u16 tfalarm; /* PSC + 0x8e */ - volatile u16 reserved28; - volatile u16 tfrptr; /* PSC + 0x92 */ - volatile u16 reserved29; - volatile u16 tfwptr; /* PSC + 0x96 */ - volatile u16 reserved30; - volatile u16 tflrfptr; /* PSC + 0x9a */ - volatile u16 reserved31; - volatile u16 tflwfptr; /* PSC + 0x9e */ -}; - -struct mpc5xxx_intr { - volatile u32 per_mask; /* INTR + 0x00 */ - volatile u32 per_pri1; /* INTR + 0x04 */ - volatile u32 per_pri2; /* INTR + 0x08 */ - volatile u32 per_pri3; /* INTR + 0x0c */ - volatile u32 ctrl; /* INTR + 0x10 */ - volatile u32 main_mask; /* INTR + 0x14 */ - volatile u32 main_pri1; /* INTR + 0x18 */ - volatile u32 main_pri2; /* INTR + 0x1c */ - volatile u32 reserved1; /* INTR + 0x20 */ - volatile u32 enc_status; /* INTR + 0x24 */ - volatile u32 crit_status; /* INTR + 0x28 */ - volatile u32 main_status; /* INTR + 0x2c */ - volatile u32 per_status; /* INTR + 0x30 */ - volatile u32 reserved2; /* INTR + 0x34 */ - volatile u32 per_error; /* INTR + 0x38 */ -}; - -struct mpc5xxx_gpio { - volatile u32 port_config; /* GPIO + 0x00 */ - volatile u32 simple_gpioe; /* GPIO + 0x04 */ - volatile u32 simple_ode; /* GPIO + 0x08 */ - volatile u32 simple_ddr; /* GPIO + 0x0c */ - volatile u32 simple_dvo; /* GPIO + 0x10 */ - volatile u32 simple_ival; /* GPIO + 0x14 */ - volatile u8 outo_gpioe; /* GPIO + 0x18 */ - volatile u8 reserved1[3]; /* GPIO + 0x19 */ - volatile u8 outo_dvo; /* GPIO + 0x1c */ - volatile u8 reserved2[3]; /* GPIO + 0x1d */ - volatile u8 sint_gpioe; /* GPIO + 0x20 */ - volatile u8 reserved3[3]; /* GPIO + 0x21 */ - volatile u8 sint_ode; /* GPIO + 0x24 */ - volatile u8 reserved4[3]; /* GPIO + 0x25 */ - volatile u8 sint_ddr; /* GPIO + 0x28 */ - volatile u8 reserved5[3]; /* GPIO + 0x29 */ - volatile u8 sint_dvo; /* GPIO + 0x2c */ - volatile u8 reserved6[3]; /* GPIO + 0x2d */ - volatile u8 sint_inten; /* GPIO + 0x30 */ - volatile u8 reserved7[3]; /* GPIO + 0x31 */ - volatile u16 sint_itype; /* GPIO + 0x34 */ - volatile u16 reserved8; /* GPIO + 0x36 */ - volatile u8 gpio_control; /* GPIO + 0x38 */ - volatile u8 reserved9[3]; /* GPIO + 0x39 */ - volatile u8 sint_istat; /* GPIO + 0x3c */ - volatile u8 sint_ival; /* GPIO + 0x3d */ - volatile u8 bus_errs; /* GPIO + 0x3e */ - volatile u8 reserved10; /* GPIO + 0x3f */ -}; - -struct mpc5xxx_sdma { - volatile u32 taskBar; /* SDMA + 0x00 */ - volatile u32 currentPointer; /* SDMA + 0x04 */ - volatile u32 endPointer; /* SDMA + 0x08 */ - volatile u32 variablePointer; /* SDMA + 0x0c */ - - volatile u8 IntVect1; /* SDMA + 0x10 */ - volatile u8 IntVect2; /* SDMA + 0x11 */ - volatile u16 PtdCntrl; /* SDMA + 0x12 */ - - volatile u32 IntPend; /* SDMA + 0x14 */ - volatile u32 IntMask; /* SDMA + 0x18 */ - - volatile u16 tcr_0; /* SDMA + 0x1c */ - volatile u16 tcr_1; /* SDMA + 0x1e */ - volatile u16 tcr_2; /* SDMA + 0x20 */ - volatile u16 tcr_3; /* SDMA + 0x22 */ - volatile u16 tcr_4; /* SDMA + 0x24 */ - volatile u16 tcr_5; /* SDMA + 0x26 */ - volatile u16 tcr_6; /* SDMA + 0x28 */ - volatile u16 tcr_7; /* SDMA + 0x2a */ - volatile u16 tcr_8; /* SDMA + 0x2c */ - volatile u16 tcr_9; /* SDMA + 0x2e */ - volatile u16 tcr_a; /* SDMA + 0x30 */ - volatile u16 tcr_b; /* SDMA + 0x32 */ - volatile u16 tcr_c; /* SDMA + 0x34 */ - volatile u16 tcr_d; /* SDMA + 0x36 */ - volatile u16 tcr_e; /* SDMA + 0x38 */ - volatile u16 tcr_f; /* SDMA + 0x3a */ - - volatile u8 IPR0; /* SDMA + 0x3c */ - volatile u8 IPR1; /* SDMA + 0x3d */ - volatile u8 IPR2; /* SDMA + 0x3e */ - volatile u8 IPR3; /* SDMA + 0x3f */ - volatile u8 IPR4; /* SDMA + 0x40 */ - volatile u8 IPR5; /* SDMA + 0x41 */ - volatile u8 IPR6; /* SDMA + 0x42 */ - volatile u8 IPR7; /* SDMA + 0x43 */ - volatile u8 IPR8; /* SDMA + 0x44 */ - volatile u8 IPR9; /* SDMA + 0x45 */ - volatile u8 IPR10; /* SDMA + 0x46 */ - volatile u8 IPR11; /* SDMA + 0x47 */ - volatile u8 IPR12; /* SDMA + 0x48 */ - volatile u8 IPR13; /* SDMA + 0x49 */ - volatile u8 IPR14; /* SDMA + 0x4a */ - volatile u8 IPR15; /* SDMA + 0x4b */ - volatile u8 IPR16; /* SDMA + 0x4c */ - volatile u8 IPR17; /* SDMA + 0x4d */ - volatile u8 IPR18; /* SDMA + 0x4e */ - volatile u8 IPR19; /* SDMA + 0x4f */ - volatile u8 IPR20; /* SDMA + 0x50 */ - volatile u8 IPR21; /* SDMA + 0x51 */ - volatile u8 IPR22; /* SDMA + 0x52 */ - volatile u8 IPR23; /* SDMA + 0x53 */ - volatile u8 IPR24; /* SDMA + 0x54 */ - volatile u8 IPR25; /* SDMA + 0x55 */ - volatile u8 IPR26; /* SDMA + 0x56 */ - volatile u8 IPR27; /* SDMA + 0x57 */ - volatile u8 IPR28; /* SDMA + 0x58 */ - volatile u8 IPR29; /* SDMA + 0x59 */ - volatile u8 IPR30; /* SDMA + 0x5a */ - volatile u8 IPR31; /* SDMA + 0x5b */ - - volatile u32 res1; /* SDMA + 0x5c */ - volatile u32 res2; /* SDMA + 0x60 */ - volatile u32 res3; /* SDMA + 0x64 */ - volatile u32 MDEDebug; /* SDMA + 0x68 */ - volatile u32 ADSDebug; /* SDMA + 0x6c */ - volatile u32 Value1; /* SDMA + 0x70 */ - volatile u32 Value2; /* SDMA + 0x74 */ - volatile u32 Control; /* SDMA + 0x78 */ - volatile u32 Status; /* SDMA + 0x7c */ - volatile u32 EU00; /* SDMA + 0x80 */ - volatile u32 EU01; /* SDMA + 0x84 */ - volatile u32 EU02; /* SDMA + 0x88 */ - volatile u32 EU03; /* SDMA + 0x8c */ - volatile u32 EU04; /* SDMA + 0x90 */ - volatile u32 EU05; /* SDMA + 0x94 */ - volatile u32 EU06; /* SDMA + 0x98 */ - volatile u32 EU07; /* SDMA + 0x9c */ - volatile u32 EU10; /* SDMA + 0xa0 */ - volatile u32 EU11; /* SDMA + 0xa4 */ - volatile u32 EU12; /* SDMA + 0xa8 */ - volatile u32 EU13; /* SDMA + 0xac */ - volatile u32 EU14; /* SDMA + 0xb0 */ - volatile u32 EU15; /* SDMA + 0xb4 */ - volatile u32 EU16; /* SDMA + 0xb8 */ - volatile u32 EU17; /* SDMA + 0xbc */ - volatile u32 EU20; /* SDMA + 0xc0 */ - volatile u32 EU21; /* SDMA + 0xc4 */ - volatile u32 EU22; /* SDMA + 0xc8 */ - volatile u32 EU23; /* SDMA + 0xcc */ - volatile u32 EU24; /* SDMA + 0xd0 */ - volatile u32 EU25; /* SDMA + 0xd4 */ - volatile u32 EU26; /* SDMA + 0xd8 */ - volatile u32 EU27; /* SDMA + 0xdc */ - volatile u32 EU30; /* SDMA + 0xe0 */ - volatile u32 EU31; /* SDMA + 0xe4 */ - volatile u32 EU32; /* SDMA + 0xe8 */ - volatile u32 EU33; /* SDMA + 0xec */ - volatile u32 EU34; /* SDMA + 0xf0 */ - volatile u32 EU35; /* SDMA + 0xf4 */ - volatile u32 EU36; /* SDMA + 0xf8 */ - volatile u32 EU37; /* SDMA + 0xfc */ -}; - -struct mpc5xxx_i2c { - volatile u32 madr; /* I2Cn + 0x00 */ - volatile u32 mfdr; /* I2Cn + 0x04 */ - volatile u32 mcr; /* I2Cn + 0x08 */ - volatile u32 msr; /* I2Cn + 0x0C */ - volatile u32 mdr; /* I2Cn + 0x10 */ -}; - -struct mpc5xxx_spi { - volatile u8 cr1; /* SPI + 0x0F00 */ - volatile u8 cr2; /* SPI + 0x0F01 */ - volatile u8 reserved1[2]; - volatile u8 brr; /* SPI + 0x0F04 */ - volatile u8 sr; /* SPI + 0x0F05 */ - volatile u8 reserved2[3]; - volatile u8 dr; /* SPI + 0x0F09 */ - volatile u8 reserved3[3]; - volatile u8 pdr; /* SPI + 0x0F0D */ - volatile u8 reserved4[2]; - volatile u8 ddr; /* SPI + 0x0F10 */ -}; - - -struct mpc5xxx_gpt { - volatile u32 emsr; /* GPT + Timer# * 0x10 + 0x00 */ - volatile u32 cir; /* GPT + Timer# * 0x10 + 0x04 */ - volatile u32 pwmcr; /* GPT + Timer# * 0x10 + 0x08 */ - volatile u32 sr; /* GPT + Timer# * 0x10 + 0x0c */ -}; - -struct mpc5xxx_gpt_0_7 { - struct mpc5xxx_gpt gpt0; - struct mpc5xxx_gpt gpt1; - struct mpc5xxx_gpt gpt2; - struct mpc5xxx_gpt gpt3; - struct mpc5xxx_gpt gpt4; - struct mpc5xxx_gpt gpt5; - struct mpc5xxx_gpt gpt6; - struct mpc5xxx_gpt gpt7; -}; - -struct mscan_buffer { - volatile u8 idr[0x8]; /* 0x00 */ - volatile u8 dsr[0x10]; /* 0x08 */ - volatile u8 dlr; /* 0x18 */ - volatile u8 tbpr; /* 0x19 */ /* This register is not applicable for receive buffers */ - volatile u16 rsrv1; /* 0x1A */ - volatile u8 tsrh; /* 0x1C */ - volatile u8 tsrl; /* 0x1D */ - volatile u16 rsrv2; /* 0x1E */ -}; - -struct mpc5xxx_mscan { - volatile u8 canctl0; /* MSCAN + 0x00 */ - volatile u8 canctl1; /* MSCAN + 0x01 */ - volatile u16 rsrv1; /* MSCAN + 0x02 */ - volatile u8 canbtr0; /* MSCAN + 0x04 */ - volatile u8 canbtr1; /* MSCAN + 0x05 */ - volatile u16 rsrv2; /* MSCAN + 0x06 */ - volatile u8 canrflg; /* MSCAN + 0x08 */ - volatile u8 canrier; /* MSCAN + 0x09 */ - volatile u16 rsrv3; /* MSCAN + 0x0A */ - volatile u8 cantflg; /* MSCAN + 0x0C */ - volatile u8 cantier; /* MSCAN + 0x0D */ - volatile u16 rsrv4; /* MSCAN + 0x0E */ - volatile u8 cantarq; /* MSCAN + 0x10 */ - volatile u8 cantaak; /* MSCAN + 0x11 */ - volatile u16 rsrv5; /* MSCAN + 0x12 */ - volatile u8 cantbsel; /* MSCAN + 0x14 */ - volatile u8 canidac; /* MSCAN + 0x15 */ - volatile u16 rsrv6[3]; /* MSCAN + 0x16 */ - volatile u8 canrxerr; /* MSCAN + 0x1C */ - volatile u8 cantxerr; /* MSCAN + 0x1D */ - volatile u16 rsrv7; /* MSCAN + 0x1E */ - volatile u8 canidar0; /* MSCAN + 0x20 */ - volatile u8 canidar1; /* MSCAN + 0x21 */ - volatile u16 rsrv8; /* MSCAN + 0x22 */ - volatile u8 canidar2; /* MSCAN + 0x24 */ - volatile u8 canidar3; /* MSCAN + 0x25 */ - volatile u16 rsrv9; /* MSCAN + 0x26 */ - volatile u8 canidmr0; /* MSCAN + 0x28 */ - volatile u8 canidmr1; /* MSCAN + 0x29 */ - volatile u16 rsrv10; /* MSCAN + 0x2A */ - volatile u8 canidmr2; /* MSCAN + 0x2C */ - volatile u8 canidmr3; /* MSCAN + 0x2D */ - volatile u16 rsrv11; /* MSCAN + 0x2E */ - volatile u8 canidar4; /* MSCAN + 0x30 */ - volatile u8 canidar5; /* MSCAN + 0x31 */ - volatile u16 rsrv12; /* MSCAN + 0x32 */ - volatile u8 canidar6; /* MSCAN + 0x34 */ - volatile u8 canidar7; /* MSCAN + 0x35 */ - volatile u16 rsrv13; /* MSCAN + 0x36 */ - volatile u8 canidmr4; /* MSCAN + 0x38 */ - volatile u8 canidmr5; /* MSCAN + 0x39 */ - volatile u16 rsrv14; /* MSCAN + 0x3A */ - volatile u8 canidmr6; /* MSCAN + 0x3C */ - volatile u8 canidmr7; /* MSCAN + 0x3D */ - volatile u16 rsrv15; /* MSCAN + 0x3E */ - - struct mscan_buffer canrxfg; /* MSCAN + 0x40 */ /* Foreground receive buffer */ - struct mscan_buffer cantxfg; /* MSCAN + 0x60 */ /* Foreground transmit buffer */ - }; - -/* function prototypes */ -void loadtask(int basetask, int tasks); - -/* retrieve configured sdram size connected to a chipselect */ -unsigned long mpc5200_get_sdram_size(unsigned int cs); - -/* configure a local plus bus chip select */ -#define MPC5200_BOOTCS 8 -void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg); - -/* configure bus speeds. Both dividers are relative to xlb clock */ -int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv); - -#endif /* __ASSEMBLY__ */ - -#endif /* __ASMPPC_MPC5XXX_H */ -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 08/19] arch/MPC5xxx: separate clock functions 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (6 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 07/19] arch/MPC5xxx: separate architecture's main SoC header file Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 09/19] arch/MPC5xxx: just use macros instead of anonymous digits Juergen Borleis ` (10 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox In order to support the MPC5125 SoC we need a different set of clock functions. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/clocks.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h index 4e1a903..717a85b 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h @@ -1,10 +1,14 @@ #ifndef __ASM_ARCH_CLOCKS_H #define __ASM_ARCH_CLOCKS_H -unsigned long get_bus_clock(void); +/* common clocks */ unsigned long get_cpu_clock(void); +unsigned long get_timebase_clock(void); + +#if defined(CONFIG_MGT5100) || defined(CONFIG_MPC5200) +unsigned long get_bus_clock(void); unsigned long get_ipb_clock(void); unsigned long get_pci_clock(void); -unsigned long get_timebase_clock(void); +#endif #endif /* __ASM_ARCH_CLOCKS_H */ -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/19] arch/MPC5xxx: just use macros instead of anonymous digits 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (7 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 08/19] arch/MPC5xxx: separate clock functions Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 10/19] MPC5xxx/serial: use dedicated I/O functions instead of memory access Juergen Borleis ` (9 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h | 1 + arch/ppc/mach-mpc5xxx/start.S | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h index 35762a1..28dfa6e 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h @@ -37,6 +37,7 @@ #define EXC_OFF_SYS_RESET 0x0100 #define _START_OFFSET EXC_OFF_SYS_RESET +#define DEFAULT_MBAR 0x80000000 #define CFG_MBAR 0xf0000000 /* useful macros for manipulating CSx_START/STOP */ diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S index 8402345..810a5bb 100644 --- a/arch/ppc/mach-mpc5xxx/start.S +++ b/arch/ppc/mach-mpc5xxx/start.S @@ -75,18 +75,18 @@ _base: _start: /* * Reset entry. When entered here we assume that MBAR is at reset default - * 0x80000000. + * DEFAULT_MBAR. */ - lis r4, 0x80000000@h - ori r4, r4, 0x80000000@l + lis r4, DEFAULT_MBAR@h + ori r4, r4, DEFAULT_MBAR@l setup_mbar: /* r4 == current MBAR */ mfmsr r5 /* save msr contents */ - /* Switch MBAR to 0xf0000000 */ - lis r3, 0xf0000000@h - ori r3, r3, 0xf0000000@l + /* Switch MBAR to its new destination */ + lis r3, CFG_MBAR@h + ori r3, r3, CFG_MBAR@l mtspr MBAR, r3 rlwinm r3, r3, 16, 16, 31 stw r3, 0(r4) -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 10/19] MPC5xxx/serial: use dedicated I/O functions instead of memory access 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (8 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 09/19] arch/MPC5xxx: just use macros instead of anonymous digits Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 11/19] MPC5xxx/serial: provide an easier way to share register description Juergen Borleis ` (8 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox This forces the driver to use the hardware synchronized commands. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- drivers/serial/serial_mpc5xxx.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c index 18aca87..9d92fed 100644 --- a/drivers/serial/serial_mpc5xxx.c +++ b/drivers/serial/serial_mpc5xxx.c @@ -32,6 +32,7 @@ #include <common.h> #include <mach/mpc5xxx.h> #include <driver.h> +#include <io.h> #include <init.h> #include <console.h> #include <xfuncs.h> @@ -50,8 +51,8 @@ static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate) /* set up UART divisor */ div = (baseclk + (baudrate/2)) / baudrate; - psc->ctur = (div >> 8) & 0xFF; - psc->ctlr = div & 0xff; + out_8(&psc->ctur, (div >> 8) & 0xFF); + out_8(&psc->ctlr, div & 0xff); return 0; } @@ -69,33 +70,33 @@ static int mpc5xxx_serial_setbaudrate(struct console_device *cdev, int baudrate) static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc) { /* reset PSC */ - psc->command = PSC_SEL_MODE_REG_1; + out_8(&psc->command, PSC_SEL_MODE_REG_1); /* select clock sources */ #if defined(CONFIG_MGT5100) - psc->psc_clock_select = 0xdd00; + out_be16(&psc->psc_clock_select, 0xdd00); #elif defined(CONFIG_MPC5200) - psc->psc_clock_select = 0; + out_be16(&psc->psc_clock_select, 0); #endif /* switch to UART mode */ - psc->sicr = 0; + out_be32(&psc->sicr, 0); /* configure parity, bit length and so on */ #if defined(CONFIG_MGT5100) - psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE; + out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE); #elif defined(CONFIG_MPC5200) - psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; + out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE); #endif - psc->mode = PSC_MODE_ONE_STOP; + out_8(&psc->mode, PSC_MODE_ONE_STOP); /* disable all interrupts */ - psc->psc_imr = 0; + out_be16(&psc->psc_imr, 0); /* reset and enable Rx/Tx */ -// psc->command = PSC_RST_RX; -// psc->command = PSC_RST_TX; - psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; +// out_8(&psc->command, PSC_RST_RX); +// out_8(&psc->command, PSC_RST_TX); + out_8(&psc->command, PSC_RX_ENABLE | PSC_TX_ENABLE); return 0; } @@ -116,10 +117,10 @@ static void mpc5xxx_serial_putc (struct console_device *cdev, const char c) struct mpc5xxx_psc *psc = dev->priv; /* Wait for last character to go. */ - while (!(psc->psc_status & PSC_SR_TXEMP)) + while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP)) ; - psc->psc_buffer_8 = c; + out_8(&psc->psc_buffer_8, c); } static int mpc5xxx_serial_getc (struct console_device *cdev) @@ -128,10 +129,10 @@ static int mpc5xxx_serial_getc (struct console_device *cdev) struct mpc5xxx_psc *psc = dev->priv; /* Wait for a character to arrive. */ - while (!(psc->psc_status & PSC_SR_RXRDY)) + while (!(in_be16(&psc->psc_status) & PSC_SR_RXRDY)) ; - return psc->psc_buffer_8; + return in_8(&psc->psc_buffer_8); } static int mpc5xxx_serial_tstc (struct console_device *cdev) @@ -139,7 +140,7 @@ static int mpc5xxx_serial_tstc (struct console_device *cdev) struct device_d *dev = cdev->dev; struct mpc5xxx_psc *psc = dev->priv; - return (psc->psc_status & PSC_SR_RXRDY); + return in_be16(&psc->psc_status) & PSC_SR_RXRDY; } static int mpc5xxx_serial_probe(struct device_d *dev) -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 11/19] MPC5xxx/serial: provide an easier way to share register description 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (9 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 10/19] MPC5xxx/serial: use dedicated I/O functions instead of memory access Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 12/19] MPC5xxx/serial: use new shared " Juergen Borleis ` (7 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Separate the register definition to be able to add more SoCs to use them. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h | 154 +++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h new file mode 100644 index 0000000..a44d213 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h @@ -0,0 +1,154 @@ +#include <linux/types.h> + +/* Programmable Serial Controller (PSC) status register bits */ +#define PSC_SR_CDE 0x0080 +#define PSC_SR_RXRDY 0x0100 +#define PSC_SR_RXFULL 0x0200 +#define PSC_SR_TXRDY 0x0400 +#define PSC_SR_TXEMP 0x0800 +#define PSC_SR_OE 0x1000 +#define PSC_SR_PE 0x2000 +#define PSC_SR_FE 0x4000 +#define PSC_SR_RB 0x8000 + +/* PSC Command values */ +#define PSC_RX_ENABLE 0x0001 +#define PSC_RX_DISABLE 0x0002 +#define PSC_TX_ENABLE 0x0004 +#define PSC_TX_DISABLE 0x0008 +#define PSC_SEL_MODE_REG_1 0x0010 +#define PSC_RST_RX 0x0020 +#define PSC_RST_TX 0x0030 +#define PSC_RST_ERR_STAT 0x0040 +#define PSC_RST_BRK_CHG_INT 0x0050 +#define PSC_START_BRK 0x0060 +#define PSC_STOP_BRK 0x0070 + +/* PSC Rx FIFO status bits */ +#define PSC_RX_FIFO_ERR 0x0040 +#define PSC_RX_FIFO_UF 0x0020 +#define PSC_RX_FIFO_OF 0x0010 +#define PSC_RX_FIFO_FR 0x0008 +#define PSC_RX_FIFO_FULL 0x0004 +#define PSC_RX_FIFO_ALARM 0x0002 +#define PSC_RX_FIFO_EMPTY 0x0001 + +/* PSC interrupt mask bits */ +#define PSC_IMR_TXRDY 0x0100 +#define PSC_IMR_RXRDY 0x0200 +#define PSC_IMR_DB 0x0400 +#define PSC_IMR_IPC 0x8000 + +/* PSC input port change bits */ +#define PSC_IPCR_CTS 0x01 +#define PSC_IPCR_DCD 0x02 + +/* PSC mode fields */ +#define PSC_MODE_5_BITS 0x00 +#define PSC_MODE_6_BITS 0x01 +#define PSC_MODE_7_BITS 0x02 +#define PSC_MODE_8_BITS 0x03 +#define PSC_MODE_PAREVEN 0x00 +#define PSC_MODE_PARODD 0x04 +#define PSC_MODE_PARFORCE 0x08 +#define PSC_MODE_PARNONE 0x10 +#define PSC_MODE_ERR 0x20 +#define PSC_MODE_FFULL 0x40 +#define PSC_MODE_RXRTS 0x80 + +#define PSC_MODE_ONE_STOP_5_BITS 0x00 +#define PSC_MODE_ONE_STOP 0x07 +#define PSC_MODE_TWO_STOP 0x0f + +struct mpc5xxx_psc { + u8 mode; /* PSC + 0x00 */ + u8 reserved0[3]; + union { /* PSC + 0x04 */ + u16 status; + u16 clock_select; + } sr_csr; +#define psc_status sr_csr.status +#define psc_clock_select sr_csr.clock_select + u16 reserved1; + u8 command; /* PSC + 0x08 */ + u8 reserved2[3]; + union { /* PSC + 0x0c */ + u8 buffer_8; + u16 buffer_16; + u32 buffer_32; + } buffer; +#define psc_buffer_8 buffer.buffer_8 +#define psc_buffer_16 buffer.buffer_16 +#define psc_buffer_32 buffer.buffer_32 + union { /* PSC + 0x10 */ + u8 ipcr; + u8 acr; + } ipcr_acr; +#define psc_ipcr ipcr_acr.ipcr +#define psc_acr ipcr_acr.acr + u8 reserved3[3]; + union { /* PSC + 0x14 */ + u16 isr; + u16 imr; + } isr_imr; +#define psc_isr isr_imr.isr +#define psc_imr isr_imr.imr + u16 reserved4; + u8 ctur; /* PSC + 0x18 */ + u8 reserved5[3]; + u8 ctlr; /* PSC + 0x1c */ + u8 reserved6[3]; + u16 ccr; /* PSC + 0x20 */ + u8 reserved7[14]; + u8 ivr; /* PSC + 0x30 */ + u8 reserved8[3]; + u8 ip; /* PSC + 0x34 */ + u8 reserved9[3]; + u8 op1; /* PSC + 0x38 */ + u8 reserved10[3]; + u8 op0; /* PSC + 0x3c */ + u8 reserved11[3]; + u32 sicr; /* PSC + 0x40 */ + u8 ircr1; /* PSC + 0x44 */ + u8 reserved12[3]; + u8 ircr2; /* PSC + 0x44 */ + u8 reserved13[3]; + u8 irsdr; /* PSC + 0x4c */ + u8 reserved14[3]; + u8 irmdr; /* PSC + 0x50 */ + u8 reserved15[3]; + u8 irfdr; /* PSC + 0x54 */ + u8 reserved16[3]; + u16 rfnum; /* PSC + 0x58 */ + u16 reserved17; + u16 tfnum; /* PSC + 0x5c */ + u16 reserved18; + u32 rfdata; /* PSC + 0x60 */ + u16 rfstat; /* PSC + 0x64 */ + u16 reserved20; + u8 rfcntl; /* PSC + 0x68 */ + u8 reserved21[5]; + u16 rfalarm; /* PSC + 0x6e */ + u16 reserved22; + u16 rfrptr; /* PSC + 0x72 */ + u16 reserved23; + u16 rfwptr; /* PSC + 0x76 */ + u16 reserved24; + u16 rflrfptr; /* PSC + 0x7a */ + u16 reserved25; + u16 rflwfptr; /* PSC + 0x7e */ + u32 tfdata; /* PSC + 0x80 */ + u16 tfstat; /* PSC + 0x84 */ + u16 reserved26; + u8 tfcntl; /* PSC + 0x88 */ + u8 reserved27[5]; + u16 tfalarm; /* PSC + 0x8e */ + u16 reserved28; + u16 tfrptr; /* PSC + 0x92 */ + u16 reserved29; + u16 tfwptr; /* PSC + 0x96 */ + u16 reserved30; + u16 tflrfptr; /* PSC + 0x9a */ + u16 reserved31; + u16 tflwfptr; /* PSC + 0x9e */ +}; -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 12/19] MPC5xxx/serial: use new shared register description 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (10 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 11/19] MPC5xxx/serial: provide an easier way to share register description Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 13/19] MPC5xxx/serial: re-factor the code to share it between MPC5200/MPC5125 Juergen Borleis ` (6 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h | 154 --------------------------- drivers/serial/serial_mpc5xxx.c | 1 + 2 files changed, 1 insertion(+), 154 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h index 28dfa6e..31c0656 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h @@ -352,67 +352,6 @@ #define I2C_IF 0x02 #define I2C_RXAK 0x01 -/* Programmable Serial Controller (PSC) status register bits */ -#define PSC_SR_CDE 0x0080 -#define PSC_SR_RXRDY 0x0100 -#define PSC_SR_RXFULL 0x0200 -#define PSC_SR_TXRDY 0x0400 -#define PSC_SR_TXEMP 0x0800 -#define PSC_SR_OE 0x1000 -#define PSC_SR_PE 0x2000 -#define PSC_SR_FE 0x4000 -#define PSC_SR_RB 0x8000 - -/* PSC Command values */ -#define PSC_RX_ENABLE 0x0001 -#define PSC_RX_DISABLE 0x0002 -#define PSC_TX_ENABLE 0x0004 -#define PSC_TX_DISABLE 0x0008 -#define PSC_SEL_MODE_REG_1 0x0010 -#define PSC_RST_RX 0x0020 -#define PSC_RST_TX 0x0030 -#define PSC_RST_ERR_STAT 0x0040 -#define PSC_RST_BRK_CHG_INT 0x0050 -#define PSC_START_BRK 0x0060 -#define PSC_STOP_BRK 0x0070 - -/* PSC Rx FIFO status bits */ -#define PSC_RX_FIFO_ERR 0x0040 -#define PSC_RX_FIFO_UF 0x0020 -#define PSC_RX_FIFO_OF 0x0010 -#define PSC_RX_FIFO_FR 0x0008 -#define PSC_RX_FIFO_FULL 0x0004 -#define PSC_RX_FIFO_ALARM 0x0002 -#define PSC_RX_FIFO_EMPTY 0x0001 - -/* PSC interrupt mask bits */ -#define PSC_IMR_TXRDY 0x0100 -#define PSC_IMR_RXRDY 0x0200 -#define PSC_IMR_DB 0x0400 -#define PSC_IMR_IPC 0x8000 - -/* PSC input port change bits */ -#define PSC_IPCR_CTS 0x01 -#define PSC_IPCR_DCD 0x02 - -/* PSC mode fields */ -#define PSC_MODE_5_BITS 0x00 -#define PSC_MODE_6_BITS 0x01 -#define PSC_MODE_7_BITS 0x02 -#define PSC_MODE_8_BITS 0x03 -#define PSC_MODE_PAREVEN 0x00 -#define PSC_MODE_PARODD 0x04 -#define PSC_MODE_PARFORCE 0x08 -#define PSC_MODE_PARNONE 0x10 -#define PSC_MODE_ERR 0x20 -#define PSC_MODE_FFULL 0x40 -#define PSC_MODE_RXRTS 0x80 - -#define PSC_MODE_ONE_STOP_5_BITS 0x00 -#define PSC_MODE_ONE_STOP 0x07 -#define PSC_MODE_TWO_STOP 0x0f - - /* ATA config fields */ #define MPC5xxx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */ @@ -426,99 +365,6 @@ #include <linux/types.h> -struct mpc5xxx_psc { - volatile u8 mode; /* PSC + 0x00 */ - volatile u8 reserved0[3]; - union { /* PSC + 0x04 */ - volatile u16 status; - volatile u16 clock_select; - } sr_csr; -#define psc_status sr_csr.status -#define psc_clock_select sr_csr.clock_select - volatile u16 reserved1; - volatile u8 command; /* PSC + 0x08 */ - volatile u8 reserved2[3]; - union { /* PSC + 0x0c */ - volatile u8 buffer_8; - volatile u16 buffer_16; - volatile u32 buffer_32; - } buffer; -#define psc_buffer_8 buffer.buffer_8 -#define psc_buffer_16 buffer.buffer_16 -#define psc_buffer_32 buffer.buffer_32 - union { /* PSC + 0x10 */ - volatile u8 ipcr; - volatile u8 acr; - } ipcr_acr; -#define psc_ipcr ipcr_acr.ipcr -#define psc_acr ipcr_acr.acr - volatile u8 reserved3[3]; - union { /* PSC + 0x14 */ - volatile u16 isr; - volatile u16 imr; - } isr_imr; -#define psc_isr isr_imr.isr -#define psc_imr isr_imr.imr - volatile u16 reserved4; - volatile u8 ctur; /* PSC + 0x18 */ - volatile u8 reserved5[3]; - volatile u8 ctlr; /* PSC + 0x1c */ - volatile u8 reserved6[3]; - volatile u16 ccr; /* PSC + 0x20 */ - volatile u8 reserved7[14]; - volatile u8 ivr; /* PSC + 0x30 */ - volatile u8 reserved8[3]; - volatile u8 ip; /* PSC + 0x34 */ - volatile u8 reserved9[3]; - volatile u8 op1; /* PSC + 0x38 */ - volatile u8 reserved10[3]; - volatile u8 op0; /* PSC + 0x3c */ - volatile u8 reserved11[3]; - volatile u32 sicr; /* PSC + 0x40 */ - volatile u8 ircr1; /* PSC + 0x44 */ - volatile u8 reserved12[3]; - volatile u8 ircr2; /* PSC + 0x44 */ - volatile u8 reserved13[3]; - volatile u8 irsdr; /* PSC + 0x4c */ - volatile u8 reserved14[3]; - volatile u8 irmdr; /* PSC + 0x50 */ - volatile u8 reserved15[3]; - volatile u8 irfdr; /* PSC + 0x54 */ - volatile u8 reserved16[3]; - volatile u16 rfnum; /* PSC + 0x58 */ - volatile u16 reserved17; - volatile u16 tfnum; /* PSC + 0x5c */ - volatile u16 reserved18; - volatile u32 rfdata; /* PSC + 0x60 */ - volatile u16 rfstat; /* PSC + 0x64 */ - volatile u16 reserved20; - volatile u8 rfcntl; /* PSC + 0x68 */ - volatile u8 reserved21[5]; - volatile u16 rfalarm; /* PSC + 0x6e */ - volatile u16 reserved22; - volatile u16 rfrptr; /* PSC + 0x72 */ - volatile u16 reserved23; - volatile u16 rfwptr; /* PSC + 0x76 */ - volatile u16 reserved24; - volatile u16 rflrfptr; /* PSC + 0x7a */ - volatile u16 reserved25; - volatile u16 rflwfptr; /* PSC + 0x7e */ - volatile u32 tfdata; /* PSC + 0x80 */ - volatile u16 tfstat; /* PSC + 0x84 */ - volatile u16 reserved26; - volatile u8 tfcntl; /* PSC + 0x88 */ - volatile u8 reserved27[5]; - volatile u16 tfalarm; /* PSC + 0x8e */ - volatile u16 reserved28; - volatile u16 tfrptr; /* PSC + 0x92 */ - volatile u16 reserved29; - volatile u16 tfwptr; /* PSC + 0x96 */ - volatile u16 reserved30; - volatile u16 tflrfptr; /* PSC + 0x9a */ - volatile u16 reserved31; - volatile u16 tflwfptr; /* PSC + 0x9e */ -}; - struct mpc5xxx_intr { volatile u32 per_mask; /* INTR + 0x00 */ volatile u32 per_pri1; /* INTR + 0x04 */ diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c index 9d92fed..3b83bee 100644 --- a/drivers/serial/serial_mpc5xxx.c +++ b/drivers/serial/serial_mpc5xxx.c @@ -37,6 +37,7 @@ #include <console.h> #include <xfuncs.h> #include <mach/clocks.h> +#include <mach/mpc5xxx_psc.h> static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate) { -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 13/19] MPC5xxx/serial: re-factor the code to share it between MPC5200/MPC5125 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (11 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 12/19] MPC5xxx/serial: use new shared " Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 14/19] arch/MPC5xxx: add MPC5125 SoC support Juergen Borleis ` (5 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox The MPC5200 and MPC5125 PSC units differs in: - register layout and status and control bits - configuration (baudrate, data format) - FIFO handling - clocking Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- drivers/serial/serial_mpc5xxx.c | 84 ++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c index 3b83bee..7cd448c 100644 --- a/drivers/serial/serial_mpc5xxx.c +++ b/drivers/serial/serial_mpc5xxx.c @@ -39,16 +39,66 @@ #include <mach/clocks.h> #include <mach/mpc5xxx_psc.h> -static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate) +static int psc_tx_rdy(struct mpc5xxx_psc *psc) { - unsigned long baseclk; - int div; + return in_be16(&psc->psc_status) & PSC_SR_TXEMP; +} + +static int psc_rx_rdy(struct mpc5xxx_psc *psc) +{ + return in_be16(&psc->psc_status) & PSC_SR_RXRDY; +} + +static void psc_tx_write(struct mpc5xxx_psc *psc, char c) +{ + out_8(&psc->psc_buffer_8, c); +} + +static int psc_rx_read(struct mpc5xxx_psc *psc) +{ + return in_8(&psc->psc_buffer_8); +} + +static unsigned long mpc5xxx_get_base_clock(struct mpc5xxx_psc *psc) +{ +#if defined(CONFIG_MGT5100) + return (CFG_MPC5XXX_CLKIN + 16) / 32; +#elif defined(CONFIG_MPC5200) + return (get_ipb_clock() + 16) / 32; +#else +# error "Unknwon CPU" +#endif +} +static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc) +{ #if defined(CONFIG_MGT5100) - baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32; + out_be16(&psc->psc_clock_select, 0xdd00); #elif defined(CONFIG_MPC5200) - baseclk = (get_ipb_clock() + 16) / 32; + out_be16(&psc->psc_clock_select, 0); +#else +# error "Unknwon CPU" #endif +} + +static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc) +{ +#if defined(CONFIG_MGT5100) + out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE); +#elif defined(CONFIG_MPC5200) + out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE); + out_8(&psc->mode, PSC_MODE_ONE_STOP); +#else +# error "Unknwon CPU" +#endif +} + +static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate) +{ + unsigned long baseclk; + int div; + + baseclk = mpc5xxx_get_base_clock(psc); /* set up UART divisor */ div = (baseclk + (baudrate/2)) / baudrate; @@ -73,23 +123,13 @@ static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc) /* reset PSC */ out_8(&psc->command, PSC_SEL_MODE_REG_1); - /* select clock sources */ -#if defined(CONFIG_MGT5100) - out_be16(&psc->psc_clock_select, 0xdd00); -#elif defined(CONFIG_MPC5200) - out_be16(&psc->psc_clock_select, 0); -#endif + mpc5xxx_select_clock_source(psc); /* switch to UART mode */ out_be32(&psc->sicr, 0); /* configure parity, bit length and so on */ -#if defined(CONFIG_MGT5100) - out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE); -#elif defined(CONFIG_MPC5200) - out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE); -#endif - out_8(&psc->mode, PSC_MODE_ONE_STOP); + mpc5xxx_configure_serial_protocol(psc); /* disable all interrupts */ out_be16(&psc->psc_imr, 0); @@ -118,10 +158,10 @@ static void mpc5xxx_serial_putc (struct console_device *cdev, const char c) struct mpc5xxx_psc *psc = dev->priv; /* Wait for last character to go. */ - while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP)) + while (!psc_tx_rdy(psc)) ; - out_8(&psc->psc_buffer_8, c); + psc_tx_write(psc, c); } static int mpc5xxx_serial_getc (struct console_device *cdev) @@ -130,10 +170,10 @@ static int mpc5xxx_serial_getc (struct console_device *cdev) struct mpc5xxx_psc *psc = dev->priv; /* Wait for a character to arrive. */ - while (!(in_be16(&psc->psc_status) & PSC_SR_RXRDY)) + while (!psc_rx_rdy(psc)) ; - return in_8(&psc->psc_buffer_8); + return psc_rx_read(psc); } static int mpc5xxx_serial_tstc (struct console_device *cdev) @@ -141,7 +181,7 @@ static int mpc5xxx_serial_tstc (struct console_device *cdev) struct device_d *dev = cdev->dev; struct mpc5xxx_psc *psc = dev->priv; - return in_be16(&psc->psc_status) & PSC_SR_RXRDY; + return psc_rx_rdy(psc); } static int mpc5xxx_serial_probe(struct device_d *dev) -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 14/19] arch/MPC5xxx: add MPC5125 SoC support 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (12 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 13/19] MPC5xxx/serial: re-factor the code to share it between MPC5200/MPC5125 Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 15/19] arch/MPC5xxx: add MPC5125 to the build-system Juergen Borleis ` (4 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox The MPC5125 shares most of the internals with the MPC52000 but differs in many details. It also differs from the the MPC5121/MPC5123, so the latter SoCs are not supported yet. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/include/asm/processor.h | 11 + arch/ppc/lib/Makefile | 2 +- arch/ppc/lib/nor-bbu.c | 141 ++++++++++ arch/ppc/mach-mpc5xxx/cpu-mpc5125.c | 174 ++++++++++++ arch/ppc/mach-mpc5xxx/include/mach/bbu.h | 18 ++ arch/ppc/mach-mpc5xxx/include/mach/clocks.h | 9 + arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h | 321 +++++++++++++++++++++++ arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h | 46 ++++ arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h | 6 +- arch/ppc/mach-mpc5xxx/iomux-mpc5125.c | 39 +++ arch/ppc/mach-mpc5xxx/lpc-mpc5125.c | 73 ++++++ arch/ppc/mach-mpc5xxx/sdram-mpc5125.c | 269 +++++++++++++++++++ arch/ppc/mach-mpc5xxx/speed-mpc5125.c | 209 +++++++++++++++ arch/ppc/mach-mpc5xxx/start.S | 99 ++++++- arch/ppc/mach-mpc5xxx/sys-mpc5125.c | 136 ++++++++++ 15 files changed, 1549 insertions(+), 4 deletions(-) create mode 100644 arch/ppc/lib/nor-bbu.c create mode 100644 arch/ppc/mach-mpc5xxx/cpu-mpc5125.c create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/bbu.h create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h create mode 100644 arch/ppc/mach-mpc5xxx/iomux-mpc5125.c create mode 100644 arch/ppc/mach-mpc5xxx/lpc-mpc5125.c create mode 100644 arch/ppc/mach-mpc5xxx/sdram-mpc5125.c create mode 100644 arch/ppc/mach-mpc5xxx/speed-mpc5125.c create mode 100644 arch/ppc/mach-mpc5xxx/sys-mpc5125.c diff --git a/arch/ppc/include/asm/processor.h b/arch/ppc/include/asm/processor.h index e8a9c14..4d5a10f 100644 --- a/arch/ppc/include/asm/processor.h +++ b/arch/ppc/include/asm/processor.h @@ -236,6 +236,16 @@ #define HID1_ASTME (1<<13) /* Address bus streaming mode */ #define HID1_ABE (1<<12) /* Address broadcast enable */ #define HID1_MBDD (1<<6) /* optimized sync instruction */ +#define SPRN_HID2 0x3F3 +#define HID2_LET (1 << 27) +#define HID2_HBE (1 << 18) +#define HID2_IWLCK_000 (0x0 << 13) /* no ways locked */ +#define HID2_IWLCK_001 (0x1 << 13) /* way 0 locked */ +#define HID2_IWLCK_010 (0x2 << 13) /* way 0 through way 1 locked */ +#define HID2_IWLCK_011 (0x3 << 13) /* way 0 through way 2 locked */ +#define HID2_IWLCK_100 (0x4 << 13) /* way 0 through way 3 locked */ +#define HID2_IWLCK_101 (0x5 << 13) /* way 0 through way 4 locked */ +#define HID2_IWLCK_110 (0x6 << 13) /* way 0 through way 5 locked */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #ifndef CONFIG_BOOKE #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ @@ -509,6 +519,7 @@ #define HASH2 SPRN_HASH2 /* Secondary Hash Address Register */ #define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ #define HID1 SPRN_HID1 /* Hardware Implementation Register 1 */ +#define HID2 SPRN_HID2 /* Hardware Implementation Register 2 */ #define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ #define IAC1 SPRN_IAC1 /* Instruction Address Register 1 */ #define IAC2 SPRN_IAC2 /* Instruction Address Register 2 */ diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index ba2f078..99d6225 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_CMD_BOOTM) += ppclinux.o obj-$(CONFIG_MODULES) += module.o obj-y += crtsavres.o obj-y += reloc.o - +obj-$(CONFIG_BAREBOX_UPDATE) += nor-bbu.o diff --git a/arch/ppc/lib/nor-bbu.c b/arch/ppc/lib/nor-bbu.c new file mode 100644 index 0000000..3bdd214 --- /dev/null +++ b/arch/ppc/lib/nor-bbu.c @@ -0,0 +1,141 @@ +/* + * nor-bbu.c - PowerPC generic functions to store barebox into a NOR flash + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * Based on imx-bbu-internal.c + * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * + * 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. + */ + +#include <common.h> +#include <malloc.h> +#include <bbu.h> +#include <mach/bbu.h> +#include <fs.h> +#include <linux/stat.h> +#include <fcntl.h> + +#define BBU_FLAG_ERASE (1 << 0) + +/* Actually write an image to NOR target device */ +static int ppc_bbu_write_device(struct bbu_handler *handler, + struct bbu_data *data, void *buf, int image_len) +{ + int fd, ret; + + fd = open(data->devicefile, O_RDWR | O_CREAT); + if (fd < 0) + return fd; + + if (handler->flags & BBU_FLAG_ERASE) { + debug("%s: unprotecting %s from 0 to 0x%08x\n", __func__, + data->devicefile, image_len); + ret = protect(fd, image_len, 0, 0); + if (ret && ret != -ENOSYS) { + printf("unprotecting %s failed with %s\n", + data->devicefile, strerror(-ret)); + goto err_close; + } + + debug("%s: erasing %s from 0 to 0x%08x\n", __func__, + data->devicefile, image_len); + ret = erase(fd, image_len, 0); + if (ret) { + printf("erasing %s failed with %s\n", data->devicefile, + strerror(-ret)); + goto err_close; + } + } + + ret = write(fd, buf, image_len); + if (ret < 0) + goto err_close; + + if (handler->flags & BBU_FLAG_ERASE) { + debug("%s: protecting %s from 0 to 0x%08x\n", __func__, + data->devicefile, image_len); + ret = protect(fd, image_len, 0, 1); + if (ret && ret != -ENOSYS) { + printf("protecting %s failed with %s\n", + data->devicefile, strerror(-ret)); + } + } + + ret = 0; + +err_close: + close(fd); + + return ret; +} + +static int ppc_bbu_check_prereq(struct bbu_data *data) +{ + struct stat s; + int ret; + + /* + * Check if the given image is a valid one + * FIXME: currently we have no real chance to detect if the image + * we got is a valid image. + */ + + ret = stat(data->devicefile, &s); + if (ret != 0) { + printf("Cannot stat '%s'. Failed with %s\n", data->devicefile, + strerror(-ret)); + return ret; + } + + if (data->len > s.st_size) { + printf("'%s' too large for '%s'\n", data->imagefile, + data->devicefile); + return -EINVAL; + } + + ret = bbu_confirm(data); + if (ret) + return ret; + + return 0; +} + +/* write a regular barebox image into an externally connected NOR flash */ +static int ppc_bbu_nor_update(struct bbu_handler *handler, struct bbu_data *data) +{ + int ret; + + ret = ppc_bbu_check_prereq(data); + if (ret) + return ret; + + return ppc_bbu_write_device(handler, data, data->image, data->len); +} + +int ppc_bbu_nor_register_handler(const char *name, const char *devicefile, + unsigned long flags) +{ + struct bbu_handler *bbu; + int ret; + + bbu = xzalloc(sizeof(*bbu)); + bbu->devicefile = devicefile; + bbu->name = name; + bbu->flags = flags | BBU_FLAG_ERASE; + bbu->handler = ppc_bbu_nor_update; + + ret = bbu_register_handler(bbu); + if (ret) + free(bbu); + + return ret; +} diff --git a/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c b/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c new file mode 100644 index 0000000..512e2a5 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * This code bases partially on: + * (C) Copyright 2007-2010 DENX Software Engineering + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License 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. + */ + +#include <common.h> +#include <init.h> +#include <types.h> +#include <driver.h> +#include <reset_source.h> +#include <asm/processor.h> +#include <mach/mpc5xxx.h> +#include <asm/io.h> + +/* Reset Module */ +struct resetc { + u32 rcwl; + u32 rcwh; + u8 res0[8]; + u32 rsr; + u32 rmr; + u32 rpr; + u32 rcr; + u32 rcer; +}; + +/* RSR - Reset Status Register */ +#define MPC512X_RSR_SWSR (1 << 13) /* software soft reset */ +#define MPC512X_RSR_SWHR (1 << 12) /* software hard reset */ +#define MPC512X_RSR_JHRS (1 << 9) /* jtag hreset */ +#define MPC512X_RSR_JSRS (1 << 8) /* jtag sreset status */ +#define MPC512X_RSR_CSHR (1 << 4) /* checkstop reset status */ +#define MPC512X_RSR_SWRS (1 << 3) /* software watchdog reset status */ +#define MPC512X_RSR_BMRS (1 << 2) /* bus monitop reset status */ +#define MPC512X_RSR_SRS (1 << 1) /* soft reset status */ +#define MPC512X_RSR_HRS (1 << 0) /* hard reset status */ + +/* RMR - Reset Mode Register */ +#define MPC512X_RMR_CSRE (1 << 0) /* checkstop reset enable */ + +/* RCR - Reset Control Register */ +#define MPC512X_RCR_SWHR (1 << 1) /* software hard reset */ +#define MPC512X_RCR_SWSR (1 << 0) /* software soft reset */ + +/* RCER - Reset Control Enable Register */ +#define MPC512X_RCER_CRE (1 << 0) /* software hard reset */ + +static struct resetc * const resetc = (struct resetc *)MPC512X_RESET; + +/* called from assembler in start.S */ +int cpu_init(void) +{ + /* do it very early, because its required for any delay() */ + mpc5125_enable_time_base_counter(); + + /* RMR - Reset Mode Register - enable checkstop reset */ + out_be32(&resetc->rmr, MPC512X_RMR_CSRE); + + /* system performance tweaking */ +#ifdef CONFIG_SYS_ACR_PIPE_DEP + /* Arbiter pipeline depth */ + out_be32(&im->arbiter.acr, + (im->arbiter.acr & ~ACR_PIPE_DEP) | + (CONFIG_SYS_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT) + ); +#endif + +#ifdef CONFIG_SYS_ACR_RPTCNT + /* Arbiter repeat count */ + out_be32(im->arbiter.acr, + (im->arbiter.acr & ~(ACR_RPTCNT)) | + (CONFIG_SYS_ACR_RPTCNT << ACR_RPTCNT_SHIFT) + ); +#endif + +#if 0 + /* Set IPS-CSB divider: IPS = 1/2 CSB */ + ips_div = in_be32(&im->clk.scfr[0]); + ips_div &= ~(SCFR1_IPS_DIV_MASK); + ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT; + out_be32(&im->clk.scfr[0], ips_div); +#endif +#ifdef SCFR1_LPC_DIV + clrsetbits_be32(&im->clk.scfr[0], SCFR1_LPC_DIV_MASK, + SCFR1_LPC_DIV << SCFR1_LPC_DIV_SHIFT); +#endif + return 0; +} + +void __noreturn reset_cpu(unsigned long addr) +{ + unsigned msr; + + /* Interrupts and MMU off */ + __asm__ __volatile__ ("mfmsr %0":"=r" (msr):); + + msr &= ~( MSR_EE | MSR_IR | MSR_DR); + __asm__ __volatile__ ("mtmsr %0"::"r" (msr)); + + /* Enable Reset Control Reg - "RSTE" is the magic word that let us go */ + out_be32(&resetc->rpr, 0x52535445); + + /* Verify Reset Control Reg is enabled */ + while (!(in_be32(&resetc->rcer) & MPC512X_RCER_CRE)) + ; + + udelay(200); + + /* Perform reset */ + out_be32(&resetc->rcr, MPC512X_RCR_SWHR); + + while(1) + ; +} + +/* + * the watchdog is always active after reset. To control it we can + * write to its 'control register' - but only once. So, after disabling it + * there is no way to re-enable it without a hard reset. + * If the user don't want to use the watchdog feature, disable it here + * forever. If the user wants to use it, start to pet it by registering + * the corresponding driver. + * The default timeout value after reset is about 130 seconds. + * This gives us the time to handle the watchdog at a reasonable + * point of initialization time. + */ +static int mpc5125_handle_watchdog(void) +{ + if (IS_ENABLED(CONFIG_WATCHDOG_MPC5125)) + add_generic_device("mpc5125wd", 0, NULL, MPC512X_WDT, + 0x10, IORESOURCE_MEM, NULL); + else + out_be32((void *)(MPC512X_WDT + 4), 0); /* disable it */ + + return 0; +} +device_initcall(mpc5125_handle_watchdog); + +/* detect the reset source after the framework is up and running */ +static int mpc5125_keep_reset_cause(void) +{ + u32 reg; + + reg = in_be32(&resetc->rsr); + if (IS_ENABLED(CONFIG_RESET_SOURCE)) { + if (reg & MPC512X_RSR_HRS) + reset_source_set(RESET_POR); + else if (reg & MPC512X_RSR_SRS) + reset_source_set(RESET_RST); + else if (reg & MPC512X_RSR_SWRS) + reset_source_set(RESET_WDG); + else if (reg & (MPC512X_RSR_JSRS | MPC512X_RSR_JHRS)) + reset_source_set(RESET_JTAG); + else + reset_source_set(RESET_UKWN); + } + out_be32(&resetc->rsr, reg); + + return 0; +} +device_initcall(mpc5125_keep_reset_cause); diff --git a/arch/ppc/mach-mpc5xxx/include/mach/bbu.h b/arch/ppc/mach-mpc5xxx/include/mach/bbu.h new file mode 100644 index 0000000..6727d42 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/bbu.h @@ -0,0 +1,18 @@ +#ifndef __MACH_BBU_H +#define __MACH_BBU_H + +#ifdef CONFIG_BAREBOX_UPDATE + +int ppc_bbu_nor_register_handler(const char *name, const char *devicefile, + unsigned long flags); + +#else /* CONFIG_BAREBOX_UPDATE */ + +static inline int ppc_bbu_nor_register_handler(const char *name, + const char *devicefile, unsigned long flags) +{ + return -ENOSYS; +} +#endif + +#endif /* __MACH_BBU_H */ diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h index 717a85b..87fdbc6 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h @@ -4,6 +4,7 @@ /* common clocks */ unsigned long get_cpu_clock(void); unsigned long get_timebase_clock(void); +void mpc5xxx_enable_psc_clock(unsigned idx); #if defined(CONFIG_MGT5100) || defined(CONFIG_MPC5200) unsigned long get_bus_clock(void); @@ -11,4 +12,12 @@ unsigned long get_ipb_clock(void); unsigned long get_pci_clock(void); #endif +#ifdef CONFIG_SOC_MPC5125 +unsigned long get_ips_clock(void); +unsigned long get_psc_clock(unsigned); +void mpc5125_enable_psc_fifo_clock(void); +void mpc5xxx_enable_fec_clock(unsigned idx); +unsigned long mpc5125_get_psc_clock(unsigned idx); +#endif + #endif /* __ASM_ARCH_CLOCKS_H */ diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h new file mode 100644 index 0000000..ed60f2a --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * 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. + */ + +#ifndef __MPC512X_H__ +#define __MPC512X_H__ + +#include <asm/types.h> +#include <sizes.h> + +/* reset default */ +#define DEFAULT_MBAR 0xff400000 + +/* + * Memory map after reset: + * + * 0x00000000 - 0x007fffff LPB-ROM (when BMS = 0) + * 0x10000000 - 0x13ffffff system main memory area + * 0x30000000 - 0x3001ffff SRAM + * 0x40000000 - 0x400fffff NFC + * 0xff400000 - 0xff4fffff MBAR + IO area + * + * Memory map after _start in start.S run: + * + * 0x00000000 ... 0x7fffffff system main memory area + * 0xf0000000 ... 0xf00fffff MBAR + IO area (1 MiB) + * 0xf0500000 ... 0xff53ffff SRAM (256 kiB) + * 0xf0600000 ... 0xff6fffff NFC (1 MiB) + * 0xfe000000 ... 0xffffffff ROM (32 MiB) + */ + +#define CFG_MBAR 0xf0000000 +#define CFG_ROM_LOC 0xfe000000 +#define CFG_ROM_SZ SZ_8M +#define CFG_SRAM_LOC 0xf0500000 +# define MPC5XXX_SRAM CFG_SRAM_LOC +#define CFG_SRAM_SZ SZ_32K +# define MPC5XXX_SRAM_SIZE CFG_SRAM_SZ +#define CFG_NFC_LOC 0xf0600000 + +#define DEFAULT_DRAM_BASE 0x00000000 + +/* base address is IMMBAR */ +#define MPC512X_RESET (CFG_MBAR + 0x00E00) +#define MPC512X_CLKM (CFG_MBAR + 0x00f00) +#define MPC512X_WDT (CFG_MBAR + 0x00900) +#define MPC512X_FEC1 (CFG_MBAR + 0x02800) +#define MPC512X_FEC2 (CFG_MBAR + 0x04800) +#define MPC512X_DRAMC (CFG_MBAR + 0x09000) +#define MPC512X_IOC (CFG_MBAR + 0x0A000) +#define MPC512X_LPC (CFG_MBAR + 0x10000) +#define MPC512X_PSC0 (CFG_MBAR + 0x11000) +#define MPC512X_PSC1 (CFG_MBAR + 0x11100) +#define MPC512X_PSC2 (CFG_MBAR + 0x11200) +#define MPC512X_PSC3 (CFG_MBAR + 0x11300) +#define MPC512X_PSC4 (CFG_MBAR + 0x11400) +#define MPC512X_PSC5 (CFG_MBAR + 0x11500) +#define MPC512X_PSC6 (CFG_MBAR + 0x11600) +#define MPC512X_PSC7 (CFG_MBAR + 0x11700) +#define MPC512X_PSC8 (CFG_MBAR + 0x11800) +#define MPC512X_PSC9 (CFG_MBAR + 0x11900) +#define MPC512X_FIFOC (CFG_MBAR + 0x11f00) + +/* System reset offset (PowerPC standard) */ +#define EXC_OFF_SYS_RESET 0x0100 +#define _START_OFFSET EXC_OFF_SYS_RESET + +/* some register offsets from the "Local Access Register Memory Map" */ +#define LPBAW_OFFSET 0x20 +#define LPCS0AW_OFFSET 0x24 +#define SRAMBAR_OFFSET 0xc4 +#define NFSCBAR_OFFSET 0xc8 +#define SWCRR_OFFSET 0x0904 +#define CS_CR_OFFSET 0x20 + +#ifndef CFG_HID0_INIT +# define CFG_HID0_INIT HID0_ICE | HID0_ICFI +#endif +#ifndef CFG_HID0_FINAL +# define CFG_HID0_FINAL HID0_ICE +#endif +#ifndef CFG_SYS_HID2 +# define CFG_SYS_HID2 HID2_HBE +#endif + +#ifndef __ASSEMBLY__ + +void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size); +void mpc5125_setup_ram_memory_window(unsigned base, unsigned size); +unsigned mpc5xxx_get_sdram_size(void); +void mpc5125_enable_time_base_counter(void); + +void mpc5125_setup_ram_memory_window(unsigned base, unsigned size); + +enum mpc5125_pinmux_id { + io_control_mem = 0, + io_control_lpc_clk = 4, + io_control_lpc_oe, + io_control_lpc_rw, + io_control_lpc_cs0, + io_control_lpc_ack, + io_control_lpc_ax03 = 9, + io_control_emb_ax02, + io_control_emb_ax01, + io_control_emb_ax00 = 12, + io_control_emb_ad31 = 13, + io_control_emb_ad30, + io_control_emb_ad29, + io_control_emb_ad28, + io_control_emb_ad27, + io_control_emb_ad26, + io_control_emb_ad25, + io_control_emb_ad24, + io_control_emb_ad23, + io_control_emb_ad22, + io_control_emb_ad21, + io_control_emb_ad20, + io_control_emb_ad19, + io_control_emb_ad18, + io_control_emb_ad17, + io_control_emb_ad16, + io_control_emb_ad15, + io_control_emb_ad14, + io_control_emb_ad13, + io_control_emb_ad12, + io_control_emb_ad11, + io_control_emb_ad10 = 34, + io_control_emb_ad9, + io_control_emb_ad8, + io_control_emb_ad7, + io_control_emb_ad6, + io_control_emb_ad5, + io_control_emb_ad4, + io_control_emb_ad3, + io_control_emb_ad2, + io_control_emb_ad1, + io_control_emb_ad0 = 44, + io_control_nfc_ce0 = 45, + io_control_nfc_rb, + io_control_dui_clk, + io_control_dui_de, + io_control_dui_hsync = 49, + io_control_dui_vsync, + io_control_dui_ld0 = 51, + io_control_dui_ld1, + io_control_dui_ld2, + io_control_dui_ld3, + io_control_dui_ld4, + io_control_dui_ld5, + io_control_dui_ld6, + io_control_dui_ld7, + io_control_dui_ld8, + io_control_dui_ld9, + io_control_dui_ld10, + io_control_dui_ld11, + io_control_dui_ld12, + io_control_dui_ld13, + io_control_dui_ld14, + io_control_dui_ld15, + io_control_dui_ld16, + io_control_dui_ld17, + io_control_dui_ld18, + io_control_dui_ld19, + io_control_dui_ld20, + io_control_dui_ld21, + io_control_dui_ld22, + io_control_dui_ld23 = 74, + io_control_i2c2_scl = 75, + io_control_i2c2_sda = 76, + io_control_can1_tx = 77, + io_control_can2_tx = 78, + io_control_i2c1_scl = 79, + io_control_i2c1_sda = 80, +/* No pin control register for can1_rx and can2_rx */ + io_control_fec1_txd2 = 81, + io_control_fec1_txd3, + io_control_fec1_rxd2, + io_control_fec1_rxd3, + io_control_fec1_crs, + io_control_fec1_txerr, + io_control_fec1_rxd1, + io_control_fec1_txd1, + io_control_fec1_mdc, + io_control_fec1_rxerr, + io_control_fec1_mdio, + io_control_fec1_rxd0, + io_control_fec1_txd0, + io_control_fec1_txclk, + io_control_fec1_rxclk, + io_control_fec1_rxdv, + io_control_fec1_txen, + io_control_fec1_col, + io_control_usb1_data0 = 99, + io_control_usb1_data1, + io_control_usb1_data2, + io_control_usb1_data3, + io_control_usb1_data4, + io_control_usb1_data5, + io_control_usb1_data6, + io_control_usb1_data7, + io_control_usb1_stop, + io_control_usb1_clk, + io_control_usb1_next, + io_control_usb1_dir, + io_control_sdhc1_clk = 111, + io_control_sdhc1_cmd, + io_control_sdhc1_d0, + io_control_sdhc1_d1, + io_control_sdhc1_d2, + io_control_sdhc1_d3, + io_control_psc_mclk_in, + io_control_psc0_0 = 118, + io_control_psc0_1, + io_control_psc0_2, + io_control_psc0_3, + io_control_psc0_4, + io_control_psc1_0, + io_control_psc1_1, + io_control_psc1_2, + io_control_psc1_3, + io_control_psc1_4, + io_control_j1850_tx, + io_control_j1850_rx, +}; + +#define MPC5125_ALTF_0 (0x0 << 5) +#define MPC5125_ALTF_1 (0x1 << 5) +#define MPC5125_ALTF_2 (0x2 << 5) +#define MPC5125_ALTF_3 (0x3 << 5) +#define MPC5125_PULL_UP (1 << 4) +#define MPC5125_PULL_DOWN (0 << 4) +#define MPC5125_PUD_ENA (1 << 3) +#define MPC5125_ST_ENA (1 << 2) + +/* + * from the MPC5125 revision 4 (09/2011) datasheet + * Slew rate definition for general IOs: + * - configuration 0: 140/183 ns + * - configuration 1: 19/24 ns + * - configuration 2: 9.8/12 ns + * - configuration 3: 1.4/1.6 ns + */ +#define MPC5125_SLEW_RATE(x) ((x) & 0x03) + +void mpc5125_mux_pin(enum mpc5125_pinmux_id idx, unsigned char mux); + +/* SDRAM commands */ +#define DRAM_CMD_NOP 0x01380000 +#define DRAM_CMD_PCHG_ALL 0x01100400 +#define DRAM_CMD_EM2 0x01020000 +#define DRAM_CMD_EM3 0x01030000 +#define DRAM_CMD_EN_DLL 0x01010000 +#define DRAM_CMD_RFSH 0x01080000 + +#define DDR_COMMAND_CMD_REQ (1 << 24) +#define DDR_COMMAND_CMD_MSR (0 << 16) +#define DDR_COMMAND_CMD_EMR1 (1 << 16) +#define DDR_COMMAND_CMD_EMR2 (2 << 16) +#define DDR_COMMAND_CMD_EMR3 (3 << 16) +#define DDR_COMMAND_RST_DLL (1 << 8) + +struct sdram_prio { + unsigned prioman_config1; + unsigned prioman_config2; + unsigned hiprio_config; + unsigned lut_table0_main_upper; + unsigned lut_table0_main_lower; + unsigned lut_table1_main_upper; + unsigned lut_table1_main_lower; + unsigned lut_table2_main_upper; + unsigned lut_table2_main_lower; + unsigned lut_table3_main_upper; + unsigned lut_table3_main_lower; + unsigned lut_table4_main_upper; + unsigned lut_table4_main_lower; + unsigned lut_table0_alt_upper; + unsigned lut_table0_alt_lower; + unsigned lut_table1_alt_upper; + unsigned lut_table1_alt_lower; + unsigned lut_table2_alt_upper; + unsigned lut_table2_alt_lower; + unsigned lut_table3_alt_upper; + unsigned lut_table3_alt_lower; + unsigned lut_table4_alt_upper; + unsigned lut_table4_alt_lower; +}; + +struct sdram_conf { + struct sdram_prio prio; + unsigned mux_ddr; + unsigned sys_cfg; + unsigned tim_cfg0, tim_cfg1, tim_cfg2; + unsigned size; + const unsigned *cmds; +}; + +void mpc5125_init_sdram(const struct sdram_conf *init_sequence); + +struct lpc_config { + unsigned cs_ale_timing; + unsigned cs_burst; + unsigned cs_dead_cyle; + unsigned cs_hold_cycle; +}; + +void mpc5125_configure_lpc(const struct lpc_config *c); +void mpc5125_setup_cs(unsigned, unsigned, unsigned, unsigned); + +#endif /* __ASSEMBLY__ */ + +#endif /* __MPC512X_H__ */ diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h new file mode 100644 index 0000000..ddac8e5 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h @@ -0,0 +1,46 @@ +#include <linux/types.h> + +/* FEC */ +struct fec { + u32 fec_id; /* FEC_ID register */ + u32 ievent; /* Interrupt event register */ + u32 imask; /* Interrupt mask register */ + u32 reserved_01; + u32 r_des_active; /* Receive ring updated flag */ + u32 x_des_active; /* Transmit ring updated flag */ + u32 reserved_02[3]; + u32 ecntrl; /* Ethernet control register */ + u32 reserved_03[6]; + u32 mii_data; /* MII data register */ + u32 mii_speed; /* MII speed register */ + u32 reserved_04[7]; + u32 mib_control; /* MIB control/status register */ + u32 reserved_05[7]; + u32 r_cntrl; /* Receive control register */ + u32 r_hash; /* Receive hash */ + u32 reserved_06[14]; + u32 x_cntrl; /* Transmit control register */ + u32 reserved_07[7]; + u32 paddr1; /* Physical address low */ + u32 paddr2; /* Physical address high + type field */ + u32 op_pause; /* Opcode + pause duration */ + u32 reserved_08[10]; + u32 iaddr1; /* Upper 32 bits of individual hash table */ + u32 iaddr2; /* Lower 32 bits of individual hash table */ + u32 gaddr1; /* Upper 32 bits of group hash table */ + u32 gaddr2; /* Lower 32 bits of group hash table */ + u32 reserved_09[7]; + u32 x_wmrk; /* Transmit FIFO watermark */ + u32 reserved_10; + u32 r_bound; /* End of RAM */ + u32 r_fstart; /* Receive FIFO start address */ + u32 reserved_11[11]; + u32 r_des_start; /* Beginning of receive descriptor ring */ + u32 x_des_start; /* Pointer to beginning of transmit descriptor ring */ + u32 r_buff_size; /* Receive buffer size */ + u32 reserved_12[26]; + u32 dma_control; /* DMA control for IP bus, AMBA IF + DMA revision */ + u32 reserved_13[2]; + u32 mib[128]; /* MIB Block Counters */ + u32 fifo[256]; /* used by FEC, can only be accessed by DMA */ +}; diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h index 2455484..f5f0a75 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h @@ -1,8 +1,10 @@ -#ifndef __ASMPPC_MPC5XXX_H -#define __ASMPPC_MPC5XXX_H +#ifndef __MACH_MPC5XXX_H +#define __MACH_MPC5XXX_H #if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100) # include <mach/mpc5200.h> #else # error "Undefined Core CPU" #endif + +#endif /* __MACH_MPC5XXX_H */ diff --git a/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c b/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c new file mode 100644 index 0000000..a52010e --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * 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. + */ + +#include <common.h> +#include <init.h> +#include <asm/io.h> +#include <mach/mpc5xxx.h> + +static u8 * const ioc = (u8 * )MPC512X_IOC; + +void mpc5125_mux_pin(enum mpc5125_pinmux_id idx, unsigned char mux) +{ + out_8(&ioc[idx], mux); +} + +#define IOC_GB_OBE (1 << 0) + +static int mpc5125_mux_init(void) +{ + /* + * Note: all default muxed pins/features which are outputs are + * *tristated* after reset. Enable them right now + */ + out_8(&ioc[1], IOC_GB_OBE); + + return 0; +} +coredevice_initcall(mpc5125_mux_init); diff --git a/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c b/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c new file mode 100644 index 0000000..0e602d5 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * 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. + */ + +#include <common.h> +#include <types.h> +#include <mach/mpc5xxx.h> +#include <asm/io.h> + +/* LPC */ +struct lpc { + u32 cs_cfg[8]; /* Chip Select N Configuration Registers + No dedicated entry for CS Boot as == CS0 */ + u32 cs_cr; /* Chip Select Control Register */ + u32 cs_sr; /* Chip Select Status Register */ + u32 cs_bcr; /* Chip Select Burst Control Register */ + u32 cs_dccr; /* Chip Select Deadcycle Control Register */ + u32 cs_hccr; /* Chip Select Holdcycle Control Register */ + u32 altr; /* Address Latch Timing Register */ + u8 res0[0xc8]; + u32 sclpc_psr; /* SCLPC Packet Size Register */ + u32 sclpc_sar; /* SCLPC Start Address Register */ + u32 sclpc_cr; /* SCLPC Control Register */ + u32 sclpc_er; /* SCLPC Enable Register */ + u32 sclpc_nar; /* SCLPC NextAddress Register */ + u32 sclpc_sr; /* SCLPC Status Register */ + u32 sclpc_bdr; /* SCLPC Bytes Done Register */ + u32 emb_scr; /* EMB Share Counter Register */ + u32 emb_pcr; /* EMB Pause Control Register */ + u8 res1[0x1c]; + u32 lpc_fdwr; /* LPC RX/TX FIFO Data Word Register */ + u32 lpc_fsr; /* LPC RX/TX FIFO Status Register */ + u32 lpc_cr; /* LPC RX/TX FIFO Control Register */ + u32 lpc_ar; /* LPC RX/TX FIFO Alarm Register */ +}; + +static struct lpc * const lpc = (struct lpc *)MPC512X_LPC; + +void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size); + +/* setup one CS line at the LPC bus */ +void mpc5125_setup_cs(unsigned cs, unsigned start, unsigned size, unsigned cfg) +{ + /* access window first */ + mpc5125_setup_access_window(cs, start, size); + + /* access method and timing */ + out_be32(&lpc->cs_cfg[cs], cfg); +} + +void mpc5125_configure_lpc(const struct lpc_config *c) +{ + /* enable the LPC feature */ + setbits_be32(&lpc->cs_cr, 0x01000000); + + if (c == NULL) + return; /* keep the defaults */ + + out_be32(&lpc->altr, c->cs_ale_timing); + out_be32(&lpc->cs_bcr, c->cs_burst); + out_be32(&lpc->cs_dccr, c->cs_dead_cyle); + out_be32(&lpc->cs_hccr, c->cs_hold_cycle); +} diff --git a/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c b/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c new file mode 100644 index 0000000..9fc3723 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * This code bases partially on: + * (C) Copyright 2007-2009 DENX Software Engineering + * + * 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. + */ + +#include <common.h> +#include <types.h> +#include <mach/mpc5xxx.h> +#include <asm/io.h> + +/* register description of the MPC5125 memory controller */ +struct mddrc { + u32 ddr_sys_config; + u32 ddr_time_config0; + u32 ddr_time_config1; + u32 ddr_time_config2; + u32 ddr_command; + u32 ddr_compact_command; + u32 self_refresh_cmd_0; + u32 self_refresh_cmd_1; + u32 self_refresh_cmd_2; + u32 self_refresh_cmd_3; + u32 self_refresh_cmd_4; + u32 self_refresh_cmd_5; + u32 self_refresh_cmd_6; + u32 self_refresh_cmd_7; + u32 dqs_config_offset_count; + u32 dqs_config_offset_time; + u32 DQS_delay_status; + u32 res0[0xF]; + u32 prioman_config1; + u32 prioman_config2; + u32 hiprio_config; + u32 lut_table0_main_upper; + u32 lut_table1_main_upper; + u32 lut_table2_main_upper; + u32 lut_table3_main_upper; + u32 lut_table4_main_upper; + u32 lut_table0_main_lower; + u32 lut_table1_main_lower; + u32 lut_table2_main_lower; + u32 lut_table3_main_lower; + u32 lut_table4_main_lower; + u32 lut_table0_alt_upper; + u32 lut_table1_alt_upper; + u32 lut_table2_alt_upper; + u32 lut_table3_alt_upper; + u32 lut_table4_alt_upper; + u32 lut_table0_alt_lower; + u32 lut_table1_alt_lower; + u32 lut_table2_alt_lower; + u32 lut_table3_alt_lower; + u32 lut_table4_alt_lower; + u32 performance_monitor_config; + u32 event_time_counter; + u32 event_time_preset; + u32 performance_monitor1_address_low; + u32 performance_monitor2_address_low; + u32 performance_monitor1_address_hi; + u32 performance_monitor2_address_hi; + u32 res1[2]; + u32 performance_monitor1_read_counter; + u32 performance_monitor2_read_counter; + u32 performance_monitor1_write_counter; + u32 performance_monitor2_write_counter; + u32 granted_ack_counter0; + u32 granted_ack_counter1; + u32 granted_ack_counter2; + u32 granted_ack_counter3; + u32 granted_ack_counter4; + u32 cumulative_wait_counter0; + u32 cumulative_wait_counter1; + u32 cumulative_wait_counter2; + u32 cumulative_wait_counter3; + u32 cumulative_wait_counter4; + u32 summed_priority_counter0; + u32 summed_priority_counter1; + u32 summed_priority_counter2; + u32 summed_priority_counter3; + u32 summed_priority_counter4; +}; + +/* MDDRC SYS CFG and Timing CFG0 Registers */ +#define MDDRC_SYS_CFG_EN 0xF0000000 +#define MDDRC_SYS_CFG_CKE_MASK 0x40000000 +#define MDDRC_SYS_CFG_CMD_MASK 0x10000000 +#define MDDRC_REFRESH_ZERO_MASK 0x0000FFFF + +#define DRAM_DSC_CMD_MODE (1 << 28) +#define DRAM_DSC_CLK_ON (1 << 29) +#define DRAM_DSC_CKE (1 << 30) +#define DRAM_DSC_RST_B (1 << 31) + +static struct mddrc * const dramc = (struct mddrc *)MPC512X_DRAMC; + +static const unsigned char page_addr[16] = { + 10, 11, 11, 12, 12, 13, 13, 14, 14, 24, 24, 25, 25, 26, 17, 28, +}; + +static const unsigned char bank_addr[16] = { + 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, +}; + +static const unsigned char row_addr[8] = { + 16, 16, 16, 16, 16, 16, 15, 14, +}; + +/* note: don't call when already running from SDRAM */ +static unsigned detect_real_memory_size(unsigned slice_count, unsigned full_count) +{ + void *p; + unsigned u, cnt; + + for (u = full_count - 1; u >= slice_count; u--) { + p = (void *)((1 << u) + DEFAULT_DRAM_BASE); + out_8(p, u); + } + + cnt = in_8((void*)DEFAULT_DRAM_BASE); + return 1 << cnt; +} + +/*static*/ const void *fix_main_address(const void *init_sequence) +{ + unsigned linked_address = (unsigned)init_sequence; + unsigned real_address; + + /* FIXME use get_runtime_offset() instead */ + real_address = linked_address - CONFIG_TEXT_BASE; + real_address += CFG_ROM_LOC; + + return (const void *)real_address; +} + +/* + * Note: this function depends on the possibility to map up to + * the full 2 GiB memory area (e.g. special mapping must exist) + */ +/*static*/ unsigned mpc5125_detect_sdram_size(void) +{ + size_t pagei, banki, rowi; + unsigned addr_cnt, slice_count, reg; + const unsigned char *p; + + reg = in_be32(&dramc->ddr_sys_config); + pagei = banki = (reg >> 21) & 0xf; + rowi = (reg >> 25) & 0x7; + + p = fix_main_address(&page_addr[pagei]); + addr_cnt = *p; + p = fix_main_address(&bank_addr[banki]); + addr_cnt += *p; + slice_count = addr_cnt; + p = fix_main_address(&row_addr[rowi]); + addr_cnt += *p; + + /* enable up to the full possible SDRAM access window for size detection */ + mpc5125_setup_ram_memory_window(DEFAULT_DRAM_BASE, 1 << addr_cnt); + return detect_real_memory_size(slice_count, addr_cnt); +} + +/*static */void setup_priority_manager(const struct sdram_conf *init_sequence) +{ + out_be32(&dramc->prioman_config1, init_sequence->prio.prioman_config1); + out_be32(&dramc->prioman_config2, init_sequence->prio.prioman_config2); + out_be32(&dramc->hiprio_config, init_sequence->prio.hiprio_config); + out_be32(&dramc->lut_table0_main_upper, init_sequence->prio.lut_table0_main_upper); + out_be32(&dramc->lut_table0_main_lower, init_sequence->prio.lut_table0_main_lower); + out_be32(&dramc->lut_table1_main_upper, init_sequence->prio.lut_table1_main_upper); + out_be32(&dramc->lut_table1_main_lower, init_sequence->prio.lut_table1_main_lower); + out_be32(&dramc->lut_table2_main_upper, init_sequence->prio.lut_table2_main_upper); + out_be32(&dramc->lut_table2_main_lower, init_sequence->prio.lut_table2_main_lower); + out_be32(&dramc->lut_table3_main_upper, init_sequence->prio.lut_table3_main_upper); + out_be32(&dramc->lut_table3_main_lower, init_sequence->prio.lut_table3_main_lower); + out_be32(&dramc->lut_table4_main_upper, init_sequence->prio.lut_table4_main_upper); + out_be32(&dramc->lut_table4_main_lower, init_sequence->prio.lut_table4_main_lower); + out_be32(&dramc->lut_table0_alt_upper, init_sequence->prio.lut_table0_alt_upper); + out_be32(&dramc->lut_table0_alt_lower, init_sequence->prio.lut_table0_alt_lower); + out_be32(&dramc->lut_table1_alt_upper, init_sequence->prio.lut_table1_alt_upper); + out_be32(&dramc->lut_table1_alt_lower, init_sequence->prio.lut_table1_alt_lower); + out_be32(&dramc->lut_table2_alt_upper, init_sequence->prio.lut_table2_alt_upper); + out_be32(&dramc->lut_table2_alt_lower, init_sequence->prio.lut_table2_alt_lower); + out_be32(&dramc->lut_table3_alt_upper, init_sequence->prio.lut_table3_alt_upper); + out_be32(&dramc->lut_table3_alt_lower, init_sequence->prio.lut_table3_alt_lower); + out_be32(&dramc->lut_table4_alt_upper, init_sequence->prio.lut_table4_alt_upper); + out_be32(&dramc->lut_table4_alt_lower, init_sequence->prio.lut_table4_alt_lower); +} + +/* depends on an enabled core internal timer ('TBEN' in 'SPCR') */ +void mpc5125_low_level_delay(unsigned ticks) +{ + uint64_t timeval = get_ticks(); + + while ((get_ticks() - timeval) < ticks) + ; +} + +#define TICKS_PER_US 50 + +/*static */void startup_dram(const struct sdram_conf *init_sequence) +{ + unsigned reg = init_sequence->sys_cfg & ~DRAM_DSC_CKE; + + /* + * the "enable" combination: DRAM controller out of reset, + * clock enabled, command mode -- BUT leave CKE low for now + */ + reg |= DRAM_DSC_RST_B | DRAM_DSC_CLK_ON | DRAM_DSC_CMD_MODE; + out_be32(&dramc->ddr_sys_config, reg); + + /* maintain 500 microseconds of stable power and clock */ + mpc5125_low_level_delay(500 * TICKS_PER_US); + + /* apply a NOP, it shouldn't harm */ + out_be32(&dramc->ddr_command, DRAM_CMD_NOP); + + /* now assert CKE (high) */ + reg |= DRAM_DSC_CKE; + out_be32(&dramc->ddr_sys_config, reg); +} + +void mpc5125_init_sdram(const struct sdram_conf *init_sequence) +{ + unsigned msize; + const unsigned *cmds; + size_t u; + + init_sequence = fix_main_address(init_sequence); + + mpc5125_mux_pin(io_control_mem, init_sequence->mux_ddr); + startup_dram(init_sequence); + setup_priority_manager(init_sequence); + + /* start to setup the external memory */ + out_be32(&dramc->ddr_time_config0, init_sequence->tim_cfg0 & + MDDRC_REFRESH_ZERO_MASK); + out_be32(&dramc->ddr_time_config1, init_sequence->tim_cfg1); + out_be32(&dramc->ddr_time_config2, init_sequence->tim_cfg2); + + cmds = fix_main_address(&init_sequence->cmds[0]); + + /* Initialize memory with supplied init sequence */ + for (u = 0; u < init_sequence->size; u++) + out_be32(&dramc->ddr_command, cmds[u]); + + /* Start DDRC with final settings */ + out_be32(&dramc->ddr_time_config0, init_sequence->tim_cfg0); + out_be32(&dramc->ddr_sys_config, init_sequence->sys_cfg); + + /* Allow for the DLL to startup before accessing data */ + mpc5125_low_level_delay(1000 * TICKS_PER_US); + + msize = mpc5125_detect_sdram_size(); + + /* size and move the memory to its final destination */ + mpc5125_setup_ram_memory_window(DEFAULT_DRAM_BASE, msize); +} diff --git a/arch/ppc/mach-mpc5xxx/speed-mpc5125.c b/arch/ppc/mach-mpc5xxx/speed-mpc5125.c new file mode 100644 index 0000000..66d0e88 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/speed-mpc5125.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * This code bases partially on: + * (C) Copyright 2000-2009 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License 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. + */ + +#include <common.h> +#include <init.h> +#include <types.h> +#include <asm/io.h> +#include <mach/mpc512x.h> + +/* Clock Module register description */ +struct clkm { + u32 spmr; /* System PLL Mode Register */ + u32 sccr[2]; /* System Clock Control Registers */ + u32 scfr[2]; /* System Clock Frequency Registers */ + u8 res0[4]; + u32 bcr; /* Bread Crumb Register */ + u32 pscccr[12]; /* PSC0-11 Clock Control Registers */ + u32 spccr; /* SPDIF Clock Control Register */ + u32 cccr; /* CFM Clock Control Register */ + u32 dccr; /* DIU Clock Control Register */ + u32 msccr[4]; /* MSCAN1-4 Clock Control Registers */ +}; + +#define SPMR_SPMF 0x0F000000 +#define SPMR_SPMF_SHIFT 24 +#define SPMR_CPMF 0x000F0000 +#define SPMR_CPMF_SHIFT 16 + +#define SCFR1_IPS_DIV_MASK 0x03800000 +#define SCFR1_IPS_DIV_SHIFT 23 + +#define SCFR2_SYS_DIV 0xFC000000 +#define SCFR2_SYS_DIV_SHIFT 26 + +#define SCCR_EN_CLK_FEC1 (1 << 13) +#define SCCR_EN_CLK_FEC2 (1 << 9) + +#define PSCCCR_MCLK_DIV_SHIFT 17 +#define PSCCCR_MCLK_DIV_MASK (0xfffe << PSCCCR_MCLK_DIV_SHIFT) +#define PSCCCR_MCLK_EN (1 << 16) +#define PSCCCR_MCLK_0_SRC_SHIFT 14 +#define PSCCCR_MCLK_0_SRC_MASK (3 << PSCCCR_MCLK_0_SRC_SHIFT) + +static struct clkm * const clkm = (struct clkm *)MPC512X_CLKM; + +unsigned long get_timebase_clock(void) +{ + return CONFIG_SYS_MPC512X_CLKIN; +} + +static const unsigned char spmf_mult[] = { + 68, 1, 12, 16, + 20, 24, 28, 32, + 36, 40, 44, 48, + 52, 56, 60, 64 +}; + +unsigned long get_pll_clk(void) +{ + unsigned reg; + size_t spmf; + + reg = in_be32(&clkm->spmr); + spmf = (reg & SPMR_SPMF) >> SPMR_SPMF_SHIFT; + return get_timebase_clock() * spmf_mult[spmf]; +} + +static const unsigned char sys_dividors[][2] = { + {2, 1}, {5, 2}, {3, 1}, {7, 2}, {4, 1}, + {9, 2}, {5, 1}, {7, 1}, {6, 1}, {8, 1}, + {9, 1}, {11, 1}, {10, 1}, {12, 1}, {13, 1}, + {15, 1}, {14, 1}, {16, 1}, {17, 1}, {19, 1}, + {18, 1}, {20, 1}, {21, 1}, {23, 1}, {22, 1}, + {24, 1}, {25, 1}, {27, 1}, {26, 1}, {28, 1}, + {29, 1}, {31, 1}, {30, 1}, {32, 1}, {33, 1} +}; + +unsigned long get_sys_clk(void) +{ + unsigned reg; + size_t sys_div; + + reg = in_be32(&clkm->scfr[1]); + sys_div = (reg & SCFR2_SYS_DIV) >> SCFR2_SYS_DIV_SHIFT; + return (get_pll_clk() * sys_dividors[sys_div][1]) / sys_dividors[sys_div][0]; +} + +static const unsigned char cpmf_mult[][2] = { + {0, 1}, {0, 1}, /* 0 and 1 are not valid */ + {1, 1}, {3, 2}, + {2, 1}, {5, 2}, + {3, 1}, {7, 2}, + {0, 1}, {0, 1}, /* and all above 7 are not valid too */ + {0, 1}, {0, 1}, + {0, 1}, {0, 1}, + {0, 1}, {0, 1} +}; + +unsigned long get_cpu_clk(void) +{ + unsigned reg; + size_t cpmf; + + reg = in_be32(&clkm->spmr); + cpmf = (reg & SPMR_CPMF) >> SPMR_CPMF_SHIFT; + return ((get_sys_clk() / 2) * cpmf_mult[cpmf][0]) / cpmf_mult[cpmf][1]; +} + +unsigned long get_ips_clock(void) +{ + unsigned reg; + unsigned long ips_div; + + reg = in_be32(&clkm->scfr[0]); + ips_div = (reg & SCFR1_IPS_DIV_MASK) >> SCFR1_IPS_DIV_SHIFT; + if (ips_div == 0) { + /* in case we cannot get a sane IPS divisor, fail gracefully */ + pr_debug("IPS clock: invalid divider setting!\n"); + return 0; + } + + return get_sys_clk() / 2 / ips_div; +} + +unsigned long get_psc_clock(unsigned idx) +{ + unsigned reg, clk; + unsigned long psc_div; + + reg = in_be32(&clkm->pscccr[idx]); + if (!(reg & PSCCCR_MCLK_EN)) + return 0; + + psc_div = (reg & PSCCCR_MCLK_DIV_MASK) >> PSCCCR_MCLK_DIV_SHIFT; + if (psc_div == 0) { + /* in case we cannot get a sane IPS divisor, fail gracefully */ + pr_debug("PSC clock: invalid divider setting!\n"); + return 0; + } + + switch (reg & PSCCCR_MCLK_0_SRC_MASK) { + case 0x0000: + clk = get_ips_clock(); + case 0x4000: + clk = get_timebase_clock(); + default: + pr_debug("PSC clock: unknown source configured: %u\n", + reg & PSCCCR_MCLK_0_SRC_MASK); + return 0; + } + + return clk / (psc_div + 1); +} + +void mpc5125_enable_psc_fifo_clock(void) +{ + setbits_be32(&clkm->sccr[0], 0x8000); +} + +void mpc5xxx_enable_psc_clock(unsigned idx) +{ + /* + * configure the clock for this unit, it + * should run at full sysclock speed (brute force...) + */ + out_be32(&clkm->pscccr[idx], PSCCCR_MCLK_EN); + /* its now save to enable the clock */ + setbits_be32(&clkm->sccr[0], 1 << (27 - idx)); +} + +void mpc5xxx_enable_fec_clock(unsigned idx) +{ + switch (idx) { + case 0: + setbits_be32(&clkm->sccr[0], SCCR_EN_CLK_FEC1); + break; + case 1: + setbits_be32(&clkm->sccr[0], SCCR_EN_CLK_FEC2); + break; + default: + pr_debug("Enabling clock: unknown FEC index: %u\n", idx); + } +} + +static int mpc5125_clks(void) +{ + printf("PLL %lu MHz, CPU %lu MHz, Sys %lu MHz, IPS %lu MHz\n", + get_pll_clk() / 1000000, get_cpu_clk() / 1000000, + get_sys_clk() / 1000000, get_ips_clock() / 1000000); + + return 0; +} +postconsole_initcall(mpc5125_clks); diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S index 810a5bb..aadaa3f 100644 --- a/arch/ppc/mach-mpc5xxx/start.S +++ b/arch/ppc/mach-mpc5xxx/start.S @@ -28,6 +28,7 @@ #include <asm/cache.h> #include <asm/mmu.h> +#include <mach/mpc5xxx.h> /* We don't want the MMU yet. */ @@ -88,7 +89,9 @@ setup_mbar: lis r3, CFG_MBAR@h ori r3, r3, CFG_MBAR@l mtspr MBAR, r3 +#ifndef CONFIG_ARCH_MPC5125 /* MPC5200 only */ rlwinm r3, r3, 16, 16, 31 +#endif stw r3, 0(r4) /* Initialise the MPC5xxx processor core */ @@ -98,7 +101,81 @@ setup_mbar: /* initialize some things that are hard to access from C */ /*--------------------------------------------------------------*/ +#ifdef CONFIG_ARCH_MPC5125 + lis r3, CFG_MBAR@h + ori r3, r3, CFG_MBAR@l + + /* enable the LPC based ROM access in the upper address space */ + lis r0, CFG_ROM_LOC@h + ori r0, r0, (CFG_ROM_LOC + CFG_ROM_SZ - 1)@h + stw r0, LPCS0AW_OFFSET(r3) + + /* just sync the hardware according to the manual */ + lwz r1, LPCS0AW_OFFSET(r3) + isync + + /* + * in order to make the CS0 (instead of the BOOTCS) work, + * we must set the LPC master bit first + */ + lis r1, MPC512X_IOC@h + ori r1, r1, MPC512X_IOC@l + lwz r0, CS_CR_OFFSET(r1) + oris r0, r0, 0x01000000@h + stw r0, CS_CR_OFFSET(r1) + isync + + /* + * when we still run from lower address space, its now time to jump to + * the just enabled upper address space. We need this step in order + * to move the lower ROM window out of the way. + * (but only, if we not run from RAM) + */ + bl 1f +1: mflr r0 + lis r1, CFG_ROM_LOC@h + cmplw r0, r1 + bgt final_destination /* skip if already in upper address space */ + /* + * to detect if we already running from RAM we just check if the + * BootCS setting is equal to the CS0 setting. + */ + lwz r2, LPBAW_OFFSET(r3) + lwz r1, LPCS0AW_OFFSET(r3) + cmplw r1, r2 + beq final_destination /* stay in RAM */ + /* + * Jump into the upper flash memory area + * destination = address of 'final_destination' - TEXT_BASE + CFG_ROM_LOC@h + */ + lis r0, (final_destination - TEXT_BASE + CFG_ROM_LOC)@h + ori r0, r0, (final_destination - TEXT_BASE + CFG_ROM_LOC)@l + mtlr r0 + blr + +final_destination: + /* + * we are now running from the upper address space from flash or + * from lower address space inside RAM. + * Its save now to move away the flash memory access in the lower + * address space. To do so sync both BOOTCS and CS0 settings. + * For the 'inside RAM' case this should not harm. + */ + lwz r1, LPCS0AW_OFFSET(r3) + stw r1, LPBAW_OFFSET(r3) + /* move NFC out of the way */ + lis r0, CFG_NFC_LOC@h + stw r0, NFSCBAR_OFFSET(r3) + + /* move the on-chip SRAM out of the way */ + lis r0, CFG_SRAM_LOC@h + stw r0, SRAMBAR_OFFSET(r3) + + /* just sync the hardware according to the manual */ + lwz r1, SRAMBAR_OFFSET(r3) + isync +#endif /* set up stack in on-chip SRAM */ lis r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@h ori r1, r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@l @@ -116,11 +193,24 @@ setup_mbar: /* r3: IMMR */ bl cpu_init /* run low-level CPU init code (in Flash)*/ +#ifdef CONFIG_ARCH_MPC5125 + bl 1f +1: mflr r0 + lis r9, CFG_ROM_LOC@h + cmplw r0, r9 + blt skip_dram_init /* skip if the RAM is already up and running */ mr r3, r21 +#endif /* r3: BOOTFLAG */ bl initdram /* initialize sdram */ /* r3: End of RAM */ +#ifdef CONFIG_ARCH_MPC5125 +skip_dram_init: + bl mpc5xxx_get_sdram_size + subi r3,r3,1 + /* r3: End of RAM */ +#endif b _continue_init /* * Vector Table @@ -501,7 +591,14 @@ init_5xxx_core: ori r3, r3, CFG_HID0_FINAL@l SYNC mtspr HID0, r3 +#ifdef CONFIG_ARCH_MPC5125 + lis r3, CFG_SYS_HID2@h + ori r3, r3, CFG_SYS_HID2@l + SYNC + mtspr HID2, r3 + sync +#else /* clear all BAT's */ /*--------------------------------------------------------------*/ @@ -570,7 +667,7 @@ init_5xxx_core: /* Done! */ /*--------------------------------------------------------------*/ - +#endif blr /* Cache functions. diff --git a/arch/ppc/mach-mpc5xxx/sys-mpc5125.c b/arch/ppc/mach-mpc5xxx/sys-mpc5125.c new file mode 100644 index 0000000..c537669 --- /dev/null +++ b/arch/ppc/mach-mpc5xxx/sys-mpc5125.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * 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. + */ + +#include <common.h> +#include <init.h> +#include <types.h> +#include <asm/io.h> +#include <mach/mpc5xxx.h> + +struct law { + u32 bar; /* Base Addr Register */ + u32 ar; /* Attributes Register */ +}; + +/* System configuration registers for MPC5125 */ +struct sysconf { + u32 immrbar; + u8 res0[0x1c]; + u32 lpbaw; + u32 lpcsaw[8]; + u8 res1[0x5c]; + struct law ddrlaw; + u8 res3[0x1c]; + u32 srambar; + u32 nfcbar; + u8 res4[0x34]; + u32 spridr; + u32 spcr; +}; + +#define MPC512X_SYSCONF_LPCSAW_START(x) (x & 0xffff0000) +#define MPC512X_SYSCONF_LPCSAW_STOP(x) ((x) >> 16) + +#define MPC512X_SPCR_TBEN 0x00400000 /* E300 core time base unit enable */ + +#define MPC512X_SVR_PART(x) (((x) >> 16) & 0xFFFF) /* Part ID */ +#define MPC512X_SVR_REV(x) (((x) >> 0) & 0xFFFF) /* Revision ID */ + +/* the MPC512x comes in two revisions. Note: these SoCs are not supported yet */ +#define MPC512x_PART_ID 0x8018 +# define MPC512X_5121E 0x0020 +# define MPC512X_5123 0x0030 + +/* the MPC5125 comes in one revisions */ +#define MPC5125_PART_ID 0x8019 +# define MPC512X_SPR_5125 0x0010 + +static struct sysconf * const sysconf = (struct sysconf *)CFG_MBAR; + +/* + * According to MPC5121e RM, configuring local access windows should + * be followed by a dummy read of the config register that was + * modified last and an isync. + */ +static void sync_law(void *addr) +{ + in_be32(addr); +} + +void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size) +{ + unsigned long long u = start; + + u += size; + if (u > 0x100000000) { + pr_err("Size for LPC chipselect %d exceeds address space. Limited!\n", cs); + size = 0x100000000 - start; + } + + out_be32(&sysconf->lpcsaw[cs], + MPC512X_SYSCONF_LPCSAW_START(start) | + MPC512X_SYSCONF_LPCSAW_STOP(start + size - 1)); + sync_law(&sysconf->lpcsaw[cs]); +} + +void mpc5125_setup_ram_memory_window(unsigned base, unsigned size) +{ + out_be32(&sysconf->ddrlaw.bar, base & 0xFFFFF000); + out_be32(&sysconf->ddrlaw.ar, __ilog2(size) - 1); + sync_law(&sysconf->ddrlaw.ar); +} + +unsigned mpc5xxx_get_sdram_size(void) +{ + return 1 << (in_be32(&sysconf->ddrlaw.ar) + 1); +} + +void mpc5125_enable_time_base_counter(void) +{ + setbits_be32(&sysconf->spcr, MPC512X_SPCR_TBEN); +} + +static int mpc5125_check_cpu(void) +{ + unsigned svr; + unsigned pid, rid; + + svr = in_be32(&sysconf->spridr); + pid = MPC512X_SVR_PART(svr); + rid = MPC512X_SVR_REV(svr); + + puts("SoC type: "); + switch (pid) { + case MPC512x_PART_ID: + switch (rid) { + case MPC512X_5121E: + puts("MPC5121e\n"); + break; + case MPC512X_5123: + puts ("MPC5123\n"); + break; + default: + printf("Unknown MPC512x variant: %x\n", rid); + } + break; + case MPC5125_PART_ID: + puts("MPC5125\n"); + break; + default: + printf("Unknown MPC51xx part/variant: %x/%x\n", pid, rid); + } + + return 0; +} +postconsole_initcall(mpc5125_check_cpu); -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 15/19] arch/MPC5xxx: add MPC5125 to the build-system 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (13 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 14/19] arch/MPC5xxx: add MPC5125 SoC support Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 16/19] MPC5xxx/serial: add support for the MPC5125 SoC Juergen Borleis ` (3 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/Makefile | 1 + arch/ppc/mach-mpc5xxx/Kconfig | 8 ++++++++ arch/ppc/mach-mpc5xxx/Makefile | 6 ++++++ arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h | 2 ++ 4 files changed, 17 insertions(+) diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index d0dd51e..74ca401 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -18,6 +18,7 @@ board-$(CONFIG_P1022DS) := freescale-p1022ds board-$(CONFIG_DA923RC) := geip-da923rc machine-$(CONFIG_ARCH_MPC5200) := mpc5xxx +machine-$(CONFIG_ARCH_MPC512X) := mpc5xxx machine-$(CONFIG_ARCH_MPC85XX) := mpc85xx cpu-$(CONFIG_ARCH_MPC85XX) := 85xx diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig index 5eebf2a..a65c21d 100644 --- a/arch/ppc/mach-mpc5xxx/Kconfig +++ b/arch/ppc/mach-mpc5xxx/Kconfig @@ -28,6 +28,14 @@ config ARCH_MPC5200 bool select MPC5xxx +config ARCH_MPC512X + bool + +config SOC_MPC5125 + bool + select MPC5xxx + select ARCH_MPC512X + config MPC5xxx bool select HAVE_CONFIGURABLE_MEMORY_LAYOUT diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile index c8d503e..0c2d830 100644 --- a/arch/ppc/mach-mpc5xxx/Makefile +++ b/arch/ppc/mach-mpc5xxx/Makefile @@ -1,4 +1,10 @@ obj-$(CONFIG_MPC5200) += cpu-mpc5200.o +obj-$(CONFIG_SOC_MPC5125) += cpu-mpc5125.o +obj-$(CONFIG_SOC_MPC5125) += speed-mpc5125.o +obj-$(CONFIG_SOC_MPC5125) += iomux-mpc5125.o +obj-$(CONFIG_SOC_MPC5125) += sdram-mpc5125.o +obj-$(CONFIG_SOC_MPC5125) += sys-mpc5125.o +obj-$(CONFIG_SOC_MPC5125) += lpc-mpc5125.o obj-$(CONFIG_MPC5200) += cpu_init-mpc5200.o obj-$(CONFIG_MPC5200) += loadtask.o obj-$(CONFIG_MPC5200) += speed-mpc5200.o diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h index f5f0a75..d7660e5 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h @@ -3,6 +3,8 @@ #if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100) # include <mach/mpc5200.h> +#elif defined(CONFIG_ARCH_MPC512X) +# include <mach/mpc512x.h> #else # error "Undefined Core CPU" #endif -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 16/19] MPC5xxx/serial: add support for the MPC5125 SoC 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (14 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 15/19] arch/MPC5xxx: add MPC5125 to the build-system Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 17/19] MPC5125/FEC: add another FEC driver " Juergen Borleis ` (2 subsequent siblings) 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h | 98 ++++++++++++++ drivers/serial/Kconfig | 4 +- drivers/serial/serial_mpc5xxx.c | 157 +++++++++++++++++++++++ 3 files changed, 257 insertions(+), 2 deletions(-) diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h index a44d213..839b394 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h @@ -60,6 +60,7 @@ #define PSC_MODE_ONE_STOP 0x07 #define PSC_MODE_TWO_STOP 0x0f +#ifdef CONFIG_MPC5200 struct mpc5xxx_psc { u8 mode; /* PSC + 0x00 */ u8 reserved0[3]; @@ -152,3 +153,100 @@ struct mpc5xxx_psc { u16 reserved31; u16 tflwfptr; /* PSC + 0x9e */ }; +#endif + +#ifdef CONFIG_SOC_MPC5125 +/* PSC definition for MPC5125 */ +struct mpc5xxx_psc { + u8 mode; + u8 res0[3]; + u8 mode2; + u8 res1[3]; + u16 psc_status; + u8 resx[2]; + u8 clock_select; + u8 res2[3]; + u8 command; + u8 res3[3]; + u32 buffer_32; + u8 ipcr; + u8 res4[3]; + u8 acr; + u8 res5[3]; + u16 isr; + u8 res5a[2]; + u16 psc_imr; + u8 res5b[2]; + u8 ctur; + u8 res6[3]; + u8 ctlr; + u8 res7[3]; + u32 ccr; + u32 ac97slots; + u32 ac97cmd; + u32 ac97data; + u8 res8[4]; + u8 ip; + u8 res9[3]; + u8 op1; + u8 res10[3]; + u8 op0; + u8 res11[3]; + u32 sicr; + u8 res12[44]; + u32 tfcmd; + u32 tfalarm; + u32 tfstat; + u32 tfintstat; + u32 tfintmask; + u32 tfcount; + u32 tfwptr; + u32 tfsize; + u8 res13[28]; + union { + u8 buffer_8; + u16 buffer_16; + u32 buffer_32; + } tfdata_buffer; +#define tfdata_8 tfdata_buffer.buffer_8 +#define tfdata_16 tfdata_buffer.buffer_16 +#define tfdata_32 tfdata_buffer.buffer_32 + u32 rfcmd; + u32 rfalarm; + u32 rfstat; + u32 rfintstat; + u32 rfintmask; + u32 rfcount; + u32 rfrptr; + u32 rfsize; + u8 res14[28]; + union { + u8 buffer_8; + u16 buffer_16; + u32 buffer_32; + } rfdata_buffer; +#define rfdata_8 rfdata_buffer.buffer_8 +#define rfdata_16 rfdata_buffer.buffer_16 +#define rfdata_32 rfdata_buffer.buffer_32 +}; + +struct fifoc5125 { + u32 fifoc_cmd; + u32 fifoc_int; + u32 fifoc_dma; + u32 res1; + u32 fifoc_debug; +}; + +/* PSC FIFO Command values */ +#define PSC_FIFO_RESET_SLICE 0x80 +#define PSC_FIFO_ENABLE_SLICE 0x01 + +/* PSC FIFO Controller Command values */ +#define FIFOC_ENABLE_CLOCK_GATE 0x01 +#define FIFOC_DISABLE_CLOCK_GATE 0x00 + +/* PSC FIFO status */ +#define PSC_FIFO_EMPTY 0x01 + +#endif diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 146bf1e..63c0703 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -50,9 +50,9 @@ config DRIVER_SERIAL_EFI_STDIO bool "EFI stdio driver" config DRIVER_SERIAL_MPC5XXX - depends on MPC5200 + depends on ARCH_MPC5XXX default y - bool "MPC5200 serial driver" + bool "MPC5XXX serial driver" config DRIVER_SERIAL_BLACKFIN depends on BLACKFIN diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c index 7cd448c..670c514 100644 --- a/drivers/serial/serial_mpc5xxx.c +++ b/drivers/serial/serial_mpc5xxx.c @@ -39,6 +39,142 @@ #include <mach/clocks.h> #include <mach/mpc5xxx_psc.h> +#ifdef CONFIG_SOC_MPC5125 + +#define MPC512x_PSC_FIFO_EMPTY (1 << 0) + +static struct fifoc5125 * const fifoc = (struct fifoc5125 *)MPC512X_FIFOC; + +struct fifo_adr_pair { + unsigned tsize, toffs; + unsigned rsize, roffs; +}; + +/* describe the FIFO's internal memory layout */ +static const struct fifo_adr_pair mpc5xxx_fifo_addresses[] = { + { + .tsize = 0x04, .toffs = 0x000, + .rsize = 0x04, .roffs = 0x010, + }, { + .tsize = 0x04, .toffs = 0x020, + .rsize = 0x04, .roffs = 0x030, + }, { + .tsize = 0x04, .toffs = 0x040, + .rsize = 0x04, .roffs = 0x050, + }, { + .tsize = 0x04, .toffs = 0x060, + .rsize = 0x04, .roffs = 0x070, + }, { + .tsize = 0x04, .toffs = 0x080, + .rsize = 0x04, .roffs = 0x090, + }, { + .tsize = 0x04, .toffs = 0x0a0, + .rsize = 0x04, .roffs = 0x0b0, + }, { + .tsize = 0x04, .toffs = 0x0c0, + .rsize = 0x04, .roffs = 0x0d0, + }, { + .tsize = 0x04, .toffs = 0x0e0, + .rsize = 0x04, .roffs = 0x0f0, + }, { + .tsize = 0x04, .toffs = 0x100, + .rsize = 0x04, .roffs = 0x110, + }, { + .tsize = 0x04, .toffs = 0x120, + .rsize = 0x04, .roffs = 0x130, + }, +}; + +static unsigned mpc5xxx_get_psc_index(void *p) +{ + /* all PSC offsets differ in 0x100 steps */ + return ((unsigned)p & 0xf00) >> 8; +} + +static void mpc5xxx_fifo_init(struct mpc5xxx_psc *psc) +{ + unsigned idx = mpc5xxx_get_psc_index(psc); + u32 tfsize, rfsize; + + /* + * we must enable the FIFO unit's clock, + * when at least one PSC unit is in use + */ + mpc5125_enable_psc_fifo_clock(); + + /* reset Rx & Tx fifo slice */ + out_be32(&psc->rfcmd, PSC_FIFO_RESET_SLICE); + out_be32(&psc->tfcmd, PSC_FIFO_RESET_SLICE); + + /* disable Tx & Rx FIFO interrupts */ + out_be32(&psc->rfintmask, 0); + out_be32(&psc->tfintmask, 0); + + tfsize = mpc5xxx_fifo_addresses[idx].tsize | + (mpc5xxx_fifo_addresses[idx].toffs << 16); + rfsize = mpc5xxx_fifo_addresses[idx].rsize | + (mpc5xxx_fifo_addresses[idx].roffs << 16); + + out_be32(&psc->tfsize, tfsize); + out_be32(&psc->rfsize, rfsize); + + /* enable Tx & Rx FIFO slice */ + out_be32(&psc->rfcmd, PSC_FIFO_ENABLE_SLICE); + out_be32(&psc->tfcmd, PSC_FIFO_ENABLE_SLICE); + + out_be32(&fifoc->fifoc_cmd, FIFOC_DISABLE_CLOCK_GATE); + __asm__ volatile ("sync"); +} + +static int psc_tx_rdy(struct mpc5xxx_psc *psc) +{ + return in_be32(&psc->tfstat) & MPC512x_PSC_FIFO_EMPTY; +} + +static int psc_rx_rdy(struct mpc5xxx_psc *psc) +{ + return !(in_be32(&psc->rfstat) & MPC512x_PSC_FIFO_EMPTY); +} + +static void psc_tx_write(struct mpc5xxx_psc *psc, char c) +{ + out_8(&psc->tfdata_8, c); +} + +static int psc_rx_read(struct mpc5xxx_psc *psc) +{ + return in_8(&psc->rfdata_8); +} + +static unsigned long mpc5xxx_get_base_clock(struct mpc5xxx_psc *psc) +{ + return (get_ips_clock() + 8) / 16; +} + +static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc) +{ + out_8(&psc->clock_select, 0xdd); +} + +static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc) +{ + out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE); + out_8(&psc->mode2, PSC_MODE_ONE_STOP); +} + +static int mpc5xxx_enable_psc_unit(struct mpc5xxx_psc *psc) +{ + unsigned idx = mpc5xxx_get_psc_index(psc); + + if (idx > ARRAY_SIZE(mpc5xxx_fifo_addresses)) + return -ENODEV; + + mpc5xxx_enable_psc_clock(idx); + return 0; +} + +#else /* CONFIG_MPC512X */ + static int psc_tx_rdy(struct mpc5xxx_psc *psc) { return in_be16(&psc->psc_status) & PSC_SR_TXEMP; @@ -81,6 +217,11 @@ static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc) #endif } +static void mpc5xxx_fifo_init(struct mpc5xxx_psc *psc) +{ + /* nothing to be done here */ +} + static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc) { #if defined(CONFIG_MGT5100) @@ -93,6 +234,14 @@ static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc) #endif } +static int mpc5xxx_enable_psc_unit(struct mpc5xxx_psc *psc) +{ + /* nothing to be done here */ + return 0; +} + +#endif /* !CONFIG_MPC512X */ + static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate) { unsigned long baseclk; @@ -120,11 +269,19 @@ static int mpc5xxx_serial_setbaudrate(struct console_device *cdev, int baudrate) static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc) { + int ret; + + ret = mpc5xxx_enable_psc_unit(psc); + if (ret != 0) + return ret; + /* reset PSC */ out_8(&psc->command, PSC_SEL_MODE_REG_1); mpc5xxx_select_clock_source(psc); + mpc5xxx_fifo_init(psc); + /* switch to UART mode */ out_be32(&psc->sicr, 0); -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 17/19] MPC5125/FEC: add another FEC driver for the MPC5125 SoC 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (15 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 16/19] MPC5xxx/serial: add support for the MPC5125 SoC Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 18/19] MPC5125/WDG: add a watchdog driver Juergen Borleis 2014-10-07 14:22 ` [PATCH 19/19] MPC5125/GPIO: add a generic GPIO driver Juergen Borleis 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox This FEC differs slightly from the one used in the MPC5200. Maybe both can share the most of the code, but I'm not sure if its worth the effort. Note: this is tested on a MPC2125 only. It might work on an MPC5121/MPC5123 as well, but it's untested. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- drivers/net/Kconfig | 5 + drivers/net/Makefile | 1 + drivers/net/fec_mpc5125.c | 690 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/fec_mpc5125.h | 0 include/fec.h | 2 +- 5 files changed, 697 insertions(+), 1 deletion(-) create mode 100644 drivers/net/fec_mpc5125.c create mode 100644 drivers/net/fec_mpc5125.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c99fcc8..f4714f7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -137,6 +137,11 @@ config DRIVER_NET_MPC5200 depends on ARCH_MPC5200 select PHYLIB +config DRIVER_NET_MPC5125 + bool "MPC5125 Ethernet driver" + depends on SOC_MPC5125 + select PHYLIB + config DRIVER_NET_NETX bool "Hilscher Netx ethernet driver" depends on HAS_NETX_ETHER diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1b85778..8912887 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_DRIVER_NET_KS8851_MLL) += ks8851_mll.o obj-$(CONFIG_DRIVER_NET_MACB) += macb.o obj-$(CONFIG_DRIVER_NET_MICREL) += ksz8864rmn.o obj-$(CONFIG_DRIVER_NET_MPC5200) += fec_mpc5200.o +obj-$(CONFIG_DRIVER_NET_MPC5125) += fec_mpc5125.o obj-$(CONFIG_DRIVER_NET_NETX) += netx_eth.o obj-$(CONFIG_DRIVER_NET_ORION) += orion-gbe.o obj-$(CONFIG_DRIVER_NET_RTL8139) += rtl8139.o diff --git a/drivers/net/fec_mpc5125.c b/drivers/net/fec_mpc5125.c new file mode 100644 index 0000000..3d78db6 --- /dev/null +++ b/drivers/net/fec_mpc5125.c @@ -0,0 +1,690 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * Based partially on code of: + * (C) Copyright 2003-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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. + */ +#include <common.h> +#include <init.h> +#include <driver.h> +#include <malloc.h> +#include <xfuncs.h> +#include <net.h> +#include <fec.h> +#include <linux/phy.h> +#include <asm/io.h> +#include <mach/mpc5xxx.h> +#include <mach/clocks.h> + +/* + * Please be aware: + * External phys needs a preamble to synchronize itself into the bit stream. + * This means a '1' bit at the MDIO line for 32 consecutive MDC clocks. + * It might be neccessary to enable the pull up at the MDIO line to force it + * to the '1' state for this purpose + */ + +/* FEC's register description */ +struct fec5125 { + u32 fec_id; + u32 ievent; + u32 imask; + u32 reserved_01; + u32 r_des_active; + u32 x_des_active; + u32 reserved_02[3]; + u32 ecntrl; + u32 reserved_03[6]; + u32 mii_data; + u32 mii_speed; + u32 reserved_04[7]; + u32 mib_control; + u32 reserved_05[7]; + u32 r_cntrl; + u32 r_hash; + u32 reserved_06[14]; + u32 x_cntrl; + u32 reserved_07[7]; + u32 paddr1; + u32 paddr2; + u32 op_pause; + u32 reserved_08[10]; + u32 iaddr1; + u32 iaddr2; + u32 gaddr1; + u32 gaddr2; + u32 reserved_09[7]; + u32 x_wmrk; + u32 reserved_10; + u32 r_bound; + u32 r_fstart; + u32 reserved_11[11]; + u32 r_des_start; + u32 x_des_start; + u32 r_buff_size; + u32 reserved_12[26]; + u32 dma_control; + u32 reserved_13[2]; + u32 mib1[30]; + u32 reserved_14[2]; + u32 mib2[25]; +}; + +/* RBD bits definitions */ +#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ +#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ +#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ +#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ +#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ +#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ +#define FEC_RBD_LG 0x0020 /* Frame length violation */ +#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ +#define FEC_RBD_SH 0x0008 /* Short frame */ +#define FEC_RBD_CR 0x0004 /* CRC error */ +#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ +#define FEC_RBD_TR 0x0001 /* Frame is truncated */ +#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ + FEC_RBD_OV | FEC_RBD_TR) + +/* TBD bits definitions */ +#define FEC_TBD_READY 0x8000 /* Buffer is ready */ +#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ +#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ +#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ +#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ + +/* MII-related definitios */ +#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ +#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ +#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ +#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ +#define FEC_MII_DATA_PA(x) (((x) << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK) +#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ +#define FEC_MII_DATA_RA(x) (((x) << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK) +#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ +#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ + +#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ +#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ + +#define FEC_IEVENT_HBERR 0x80000000 +#define FEC_IEVENT_GRA 0x10000000 +#define FEC_IEVENT_BABT 0x20000000 +#define FEC_IEVENT_MII 0x00800000 +#define FEC_IEVENT_XFIFO_ERROR 0x00040000 +#define FEC_IEVENT_RFIFO_ERROR 0x00020000 + +/* Receive & Transmit Buffer Descriptor definitions */ +struct mpc5125_descriptor { + u16 status; + u16 dlength; + u32 dpointer; +}; + +/* BD Numer definitions */ +#define FEC_TBD_NUM 48 /* The user can adjust this value */ +#define FEC_RBD_NUM 32 /* The user can adjust this value */ + +/* packet size limit */ +#define FEC_MAX_FRAME_LEN 1522 /* recommended default value */ + +/* Buffer size must be evenly divisible by 16 */ +#define FEC_MAX_PKT_SIZE ((FEC_MAX_FRAME_LEN + 0x10) & (~0xf)) + +struct mpc5125_frame { + unsigned char frame[FEC_MAX_PKT_SIZE]; +}; + +struct mpc5125_buff_descs { + struct mpc5125_descriptor rbd[FEC_RBD_NUM]; /* RBD ring */ + struct mpc5125_descriptor tbd[FEC_TBD_NUM]; /* TBD ring */ + struct mpc5125_frame recv_frames[FEC_RBD_NUM]; /* receive buff */ +} ; + +struct mpc5125_fec_priv { + struct fec5125 *eth; + struct mpc5125_buff_descs *bdBase; /* BD rings and recv buffer */ + size_t rdb_idx; /* next receive BD to read */ + size_t tdb_idx; /* next transmit BD to send */ + size_t usedtdb_idx; /* next transmit BD to clean */ + unsigned clean_tbd_cnt; /* the number of available transmit BDs */ + unsigned char frame[FEC_MAX_PKT_SIZE]; + size_t frame_idx; + + phy_interface_t interface; /* transceiver type */ + u32 phy_flags; /* nowhere used ?? */ + unsigned phy_addr; + struct mii_bus miibus; +}; + +static void mpc5125_fec_collect_frame(struct mpc5125_fec_priv *fec, + const void *buf, size_t length) +{ + memcpy(&fec->frame[fec->frame_idx], buf, length - fec->frame_idx); + fec->frame_idx = length; /* FIXME not "+=" here???? */ +} + +static void mpc5125_fec_init_buffer_ring(struct mpc5125_fec_priv *fec) +{ + void *base; + + base = xzalloc(sizeof(struct mpc5125_buff_descs) + 0x1f); + /* this buffer must be quad word aligned */ + base = (void *)((unsigned)base & ~0xf); + + fec->bdBase = base; +} + +static void mpc5125_fec_activate_transmission(struct mpc5125_fec_priv *fec) +{ + /* Activate transmit Buffer Descriptor polling */ + out_be32(&fec->eth->x_des_active, 0x01000000); +} + +static void mpc5125_fec_disable_transmission(struct mpc5125_fec_priv *fec) +{ + /* nothing to be done here */ +} + +static void mpc5125_fec_activate_reception(struct mpc5125_fec_priv *fec) +{ + out_be32(&fec->eth->r_des_active, 0x01000000); +} + +static void mpc5125_fec_disable_reception(struct mpc5125_fec_priv *fec) +{ + /* nothing to be done here */ +} + +static void mpc5125_fec_clear_reception_event(struct mpc5125_fec_priv *fec) +{ + /* nothing to be done here */ +} + +/* keep MII frequency below 2.5 MHz */ +static unsigned mpc5125_fec_limit_mii_clock(void) +{ + u32 reg; + + /* MII clock is 1 / (MII_SPEED x 2) */ + reg = get_ips_clock() + 2500000; + reg /= 5000000; + return reg + 1; +} + +/* MII-interface related functions */ +static int fec5125_miibus_read(struct mii_bus *bus, int phy_addr, int reg_addr) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)bus->priv; + int rc; + + /* clear mii transfer status first */ + out_be32(&fec->eth->ievent, FEC_IEVENT_MII); + /* + * reading from any PHY's register is done by properly + * programming the FEC's MII data register. + */ + out_be32(&fec->eth->mii_data, FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | + FEC_MII_DATA_TA | FEC_MII_DATA_PA(phy_addr) | + FEC_MII_DATA_RA(reg_addr)); + + rc = wait_on_timeout(500 * MSECOND, + in_be32(&fec->eth->ievent) & FEC_IEVENT_MII); + if (rc < 0) { + dev_err(bus->parent, "MDIO read timed out\n"); + return rc; + } + + /* it's now safe to read the PHY's register */ + return in_be32(&fec->eth->mii_data) & FEC_MII_DATA_DATAMSK; +} + +static int fec5125_miibus_write(struct mii_bus *bus, int phy_addr, + int reg_addr, u16 data) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)bus->priv; + int rc; + + /* clear mii transfer status first */ + out_be32(&fec->eth->ievent, FEC_IEVENT_MII); + + out_be32(&fec->eth->mii_data, FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | + FEC_MII_DATA_TA | FEC_MII_DATA_PA(phy_addr) | + FEC_MII_DATA_RA(reg_addr) | data); + + rc = wait_on_timeout(500 * MSECOND, + in_be32(&fec->eth->ievent) & FEC_IEVENT_MII); + if (rc < 0) + dev_err(bus->parent, "MDIO write timed out\n"); + + return rc; +} + +/* initialize the receive buffer descriptors */ +static int mpc5125_fec_rbd_init(struct mpc5125_fec_priv *fec) +{ + size_t ix; + + for (ix = 0; ix < FEC_RBD_NUM; ix++) { + fec->bdBase->rbd[ix].dpointer = (u32)&fec->bdBase->recv_frames[ix]; + fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY; + fec->bdBase->rbd[ix].dlength = 0; + } + + /* let the last buffer descriptor close the ring */ + fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP; + fec->rdb_idx = 0; + + return 0; +} + +/* initialize the transmitt buffer descriptors */ +static void mpc5125_fec_tbd_init(struct mpc5125_fec_priv *fec) +{ + int ix; + + for (ix = 0; ix < FEC_TBD_NUM; ix++) + fec->bdBase->tbd[ix].status = 0; + + /* let the last buffer descriptor close the ring */ + fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP; + + fec->tdb_idx = 0; + fec->usedtdb_idx = 0; + fec->clean_tbd_cnt = FEC_TBD_NUM; +} + +static void mpc5125_fec_rbd_clean(struct mpc5125_fec_priv *fec, + struct mpc5125_descriptor *rbd) +{ + /* Reset buffer descriptor as empty */ + if ((fec->rdb_idx) == (FEC_RBD_NUM - 1)) + rbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); + else + rbd->status = FEC_RBD_EMPTY; + + rbd->dlength = 0; + + /* ensure all written data has hit the memory */ + barrier(); + + /* Now, we have an empty RxBD, restart the engine */ + mpc5125_fec_activate_reception(fec); + + /* Increment BD count */ + fec->rdb_idx = (fec->rdb_idx + 1) % FEC_RBD_NUM; +} + +static void mpc5125_fec_tbd_scrub(struct mpc5125_fec_priv *fec) +{ + struct mpc5125_descriptor *used_tbd; + + /* process all the consumed TBDs */ + while (fec->clean_tbd_cnt < FEC_TBD_NUM) { + used_tbd = &fec->bdBase->tbd[fec->usedtdb_idx]; + if (used_tbd->status & FEC_TBD_READY) { + return; + } + + /* clean this buffer descriptor */ + if (fec->usedtdb_idx == (FEC_TBD_NUM - 1)) + used_tbd->status = FEC_TBD_WRAP; + else + used_tbd->status = 0; + + /* update some indeces for a correct handling of the TBD ring */ + fec->clean_tbd_cnt++; + fec->usedtdb_idx = (fec->usedtdb_idx + 1) % FEC_TBD_NUM; + } + + barrier(); +} + +static int mpc5125_fec_get_ethaddr(struct eth_device *dev, unsigned char *mac) +{ + /* no eeprom */ + return -ENODEV; +} + +static int mpc5125_fec_set_ethaddr(struct eth_device *dev, unsigned char *mac) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv; + u8 currByte; + int byte, bit; + u32 crc = 0xffffffff; + + /* + * The algorithm used is the following: + * we loop on each of the six bytes of the provided address, + * and we compute the CRC by left-shifting the previous + * value by one position, so that each bit in the current + * byte of the address may contribute the calculation. If + * the latter and the MSB in the CRC are different, then + * the CRC value so computed is also ex-ored with the + * "polynomium generator". The current byte of the address + * is also shifted right by one bit at each iteration. + * This is because the CRC generatore in hardware is implemented + * as a shift-register with as many ex-ores as the radixes + * in the polynomium. This suggests that we represent the + * polynomiumm itself as a 32-bit constant. + */ + for (byte = 0; byte < 6; byte++) { + currByte = mac[byte]; + for (bit = 0; bit < 8; bit++) { + if ((currByte & 0x01) ^ (crc & 0x01)) { + crc >>= 1; + crc = crc ^ 0xedb88320; + } else { + crc >>= 1; + } + currByte >>= 1; + } + } + + crc = crc >> 26; + + /* Set individual hash table register */ + if (crc >= 32) { + out_be32(&fec->eth->iaddr1, (1 << (crc - 32))); + out_be32(&fec->eth->iaddr2, 0); + } else { + out_be32(&fec->eth->iaddr1, 0); + out_be32(&fec->eth->iaddr2, (1 << crc)); + } + + /* Set physical address */ + out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) + + (mac[2] << 8) + mac[3]); + out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) + 0x8808); + + return 0; +} + +static int mpc5125_fec_init(struct eth_device *dev) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv; + + /* Initilize both BD rings */ + mpc5125_fec_rbd_init(fec); + mpc5125_fec_tbd_init(fec); + + /* Clear FEC-Lite interrupt event register(IEVENT) */ + out_be32(&fec->eth->ievent, 0xffffffff); + + /* Set interrupt mask register */ + out_be32(&fec->eth->imask, 0x00000000); + + /* Set transmit fifo watermark register(X_WMRK), default = 64 */ + out_be32(&fec->eth->x_wmrk, 0x0); + + /* Setup phy interface mode and max frame length */ + switch (fec->interface) { + case PHY_INTERFACE_MODE_MII: + out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x024); + break; + case PHY_INTERFACE_MODE_RMII: + out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x124); + break; + default: + dev_err(&dev->dev, "Unsupported phy interface mode\n"); + return -EINVAL; + } + + /* Setup MII_SPEED and do not drop the Preamble. */ + out_be32(&fec->eth->mii_speed, (mpc5125_fec_limit_mii_clock()) << 1); + + /* Set Opcode/Pause Duration Register */ + out_be32(&fec->eth->op_pause, 0x00010020); + + /* Set multicast address filter */ + out_be32(&fec->eth->gaddr1, 0x00000000); + out_be32(&fec->eth->gaddr2, 0x00000000); + + /* Half-duplex, heartbeat disabled */ + out_be32(&fec->eth->x_cntrl, 0x00000000); + + /* Enable MIB counters */ + out_be32(&fec->eth->mib_control, 0x0); + + /* Setup recv fifo start and buff size */ + out_be32(&fec->eth->r_fstart, 0x500); + out_be32(&fec->eth->r_buff_size, FEC_MAX_PKT_SIZE); + + /* Setup BD base addresses */ + out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd); + out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd); + + /* DMA Control */ + out_be32(&fec->eth->dma_control, 0xc0000000); + + /* Enable FEC */ + setbits_be32(&fec->eth->ecntrl, 0x00000002); + + return 1; +} + +static int mpc5125_fec_open(struct eth_device *edev) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)edev->priv; + + mpc5125_fec_activate_reception(fec); + + return phy_device_connect(edev, &fec->miibus, fec->phy_addr, NULL, + fec->phy_flags, fec->interface); +} + +static void mpc5125_fec_halt(struct eth_device *dev) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv; + int counter = 0xffff; + + /* mask FEC chip interrupts */ + out_be32(&fec->eth->imask, 0); + + /* issue graceful stop command to the FEC transmitter if necessary */ + setbits_be32(&fec->eth->x_cntrl, 0x00000001); + + /* wait for graceful stop to register */ + while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000))) + ; + + /* Disable the Ethernet Controller */ + clrbits_be32(&fec->eth->ecntrl, 0x00000002); + + /* Issue a reset command to the FEC chip */ + setbits_be32(&fec->eth->ecntrl, 0x1); + + /* wait at least 16 clock cycles */ + udelay(10); +} + +static int mpc5125_fec_send(struct eth_device *dev, void *eth_data, int data_length) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv; + struct mpc5125_descriptor *tbd; + int rc; + + /* Clear Tx BD ring at first */ + mpc5125_fec_tbd_scrub(fec); + + /* Check for valid length of data. */ + if ((data_length > 1500) || (data_length <= 0)) + return -EINVAL; + + /* Check the number of vacant TxBDs. */ + if (fec->clean_tbd_cnt < 1) { + dev_err(&dev->dev, "No available TxBDs ...\n"); + return -ENOMEM; + } + + /* Get the first free TxBD to send the mac header */ + tbd = &fec->bdBase->tbd[fec->tdb_idx]; + fec->clean_tbd_cnt -= 1; + tbd->dlength = data_length; + tbd->dpointer = (u32)eth_data; + tbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; + fec->tdb_idx = (fec->tdb_idx + 1) % FEC_TBD_NUM; + + /* ensure all written data has hit the memory */ + barrier(); + + mpc5125_fec_activate_transmission(fec); + + rc = wait_on_timeout(500 * MSECOND, + !(in_be16(&tbd->status) & FEC_TBD_READY)); + if (rc != 0) { + dev_err(&dev->dev, "Time out while waiting for transmission...\n"); + } else { + dev_dbg(&dev->dev, "sucessfully sent (%hX)\n", in_be16(&tbd->status)); + } + + return rc; +} + +static void mpc5125_fec_debug_rx_header(void *buffer, size_t length) +{ +#ifdef DEBUG_RX_HEADER + int i; + + printf ("recv data length 0x%08x data hdr: ", length); + for (i = 0; i < 14; i++) + printf ("%x ", *((u8*)buffer + i)); + printf("\n"); +#endif +} + +static int mpc5125_fec_recv(struct eth_device *dev) +{ + struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv; + struct mpc5125_descriptor *pRbd = &fec->bdBase->rbd[fec->rdb_idx]; + unsigned long ievent; + int frame_length = 0; + + /* Check if any critical events have happened */ + ievent = in_be32(&fec->eth->ievent); + out_be32(&fec->eth->ievent, ievent); + if (ievent & (FEC_IEVENT_BABT | FEC_IEVENT_XFIFO_ERROR | + FEC_IEVENT_RFIFO_ERROR)) { + /* BABT, Rx/Tx FIFO errors */ + mpc5125_fec_halt(dev); + mpc5125_fec_init(dev); + return 0; + } + + if (ievent & FEC_IEVENT_HBERR) { + /* Heartbeat error */ + setbits_be32(&fec->eth->x_cntrl, 0x00000001); + } + + if (ievent & FEC_IEVENT_GRA) { + /* Graceful stop complete */ + if (in_be32(&fec->eth->x_cntrl) & 0x00000001) { + mpc5125_fec_halt(dev); + clrbits_be32(&fec->eth->x_cntrl, 0x00000001);; + mpc5125_fec_init(dev); + } + } + + if (!(pRbd->status & FEC_RBD_EMPTY)) { + if (!(pRbd->status & FEC_RBD_ERR) && + ((pRbd->dlength - 4) > 14)) { + /* calculate payload size */ + frame_length = pRbd->dlength; + if (pRbd->status & FEC_RBD_LAST) + frame_length -= - 4; + + mpc5125_fec_debug_rx_header((void *)pRbd->dpointer, + pRbd->dlength); + mpc5125_fec_collect_frame(fec, (void *)pRbd->dpointer, + frame_length); + if (pRbd->status & FEC_RBD_LAST) { + /* pass it to upper layers on demand */ + net_receive(dev, fec->frame, frame_length); + fec->frame_idx = 0; + } + } + + /* Reset buffer descriptor as empty */ + mpc5125_fec_rbd_clean(fec, pRbd); + } + + /* Try to fill Buffer Descriptors */ + out_be32(&fec->eth->r_des_active, 0x01000000); + + return frame_length; +} + +static int mpc5125_fec_probe(struct device_d *dev) +{ + struct fec_platform_data *pdata = dev->platform_data; + struct eth_device *edev; + struct mpc5125_fec_priv *fec; + + edev = (struct eth_device *)xmalloc(sizeof(struct eth_device)); + fec = (struct mpc5125_fec_priv *)xmalloc(sizeof(*fec)); + dev->priv = edev; + edev->priv = fec; + edev->open = mpc5125_fec_open; + edev->init = mpc5125_fec_init; + edev->send = mpc5125_fec_send; + edev->recv = mpc5125_fec_recv; + edev->halt = mpc5125_fec_halt; + edev->get_ethaddr = mpc5125_fec_get_ethaddr; + edev->set_ethaddr = mpc5125_fec_set_ethaddr; + edev->parent = dev; + + fec->eth = (struct fec5125 *)dev_request_mem_region(dev, 0); + + mpc5125_fec_init_buffer_ring(fec); + + fec->interface = pdata->xcv_type; + fec->phy_addr = pdata->phy_addr; + + mpc5xxx_enable_fec_clock(dev->id); + + fec->miibus.read = fec5125_miibus_read; + fec->miibus.write = fec5125_miibus_write; + + fec->miibus.priv = fec; + fec->miibus.parent = dev; + + /* do some FEC initialization once */ + + /* Clean up space FEC's MIB... */ + memset(&fec->eth->mib1[0], 0x00, sizeof(fec->eth->mib1)); + memset(&fec->eth->mib2[0], 0x00, sizeof(fec->eth->mib2)); + /* disable all interrupts */ + out_be32(&fec->eth->imask, 0x00000000); + /* init the status by clearing all bits */ + out_be32(&fec->eth->ievent, 0xffffffff); + + mdiobus_register(&fec->miibus); + + eth_register(edev); + return 0; +} + +static void mpc5125_fec_remove(struct device_d *dev) +{ + struct eth_device *edev = dev->priv; + + mpc5125_fec_halt(edev); +} + +static struct driver_d mpc5125_driver = { + .name = "fec_mpc5125", + .probe = mpc5125_fec_probe, + .remove = mpc5125_fec_remove, +}; +device_platform_driver(mpc5125_driver); diff --git a/drivers/net/fec_mpc5125.h b/drivers/net/fec_mpc5125.h new file mode 100644 index 0000000..e69de29 diff --git a/include/fec.h b/include/fec.h index 699761a..8b6fb0e 100644 --- a/include/fec.h +++ b/include/fec.h @@ -25,7 +25,7 @@ /* * Define the phy connected externally for FEC drivers - * (like MPC52xx and i.MX27) + * (like MPC52xx, MPC512x and i.MX27) */ struct fec_platform_data { phy_interface_t xcv_type; -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 18/19] MPC5125/WDG: add a watchdog driver 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (16 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 17/19] MPC5125/FEC: add another FEC driver " Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 2014-10-07 14:22 ` [PATCH 19/19] MPC5125/GPIO: add a generic GPIO driver Juergen Borleis 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox This watchdog is always enabled after reset and can be configured only once. Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- drivers/watchdog/Kconfig | 6 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/mpc5125.c | 148 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 drivers/watchdog/mpc5125.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 7f7b02e..4c57111 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -28,4 +28,10 @@ config WATCHDOG_JZ4740 help Hardware driver for the built-in watchdog timer on Ingenic jz4740 SoCs. +config WATCHDOG_MPC5125 + bool "MPC5125 SoC hardware watchdog" + depends on SOC_MPC5125 + help + Hardware driver for the built-in watchdog timer on MPC5125 SoCs. + endif diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 865fc47..b7aa549 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_WATCHDOG) += wd_core.o obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o obj-$(CONFIG_WATCHDOG_JZ4740) += jz4740.o obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o +obj-$(CONFIG_WATCHDOG_MPC5125) += mpc5125.o diff --git a/drivers/watchdog/mpc5125.c b/drivers/watchdog/mpc5125.c new file mode 100644 index 0000000..7fefa21 --- /dev/null +++ b/drivers/watchdog/mpc5125.c @@ -0,0 +1,148 @@ +/* + * (c) 2014 Juergen Borleis <kernel@pengutronix.de> + * + * 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. + * + * Note: this driver works for the MPC5125. It might work for the + * MPC512X SoCs as well, but is not tested yet. + */ +#include <common.h> +#include <init.h> +#include <io.h> +#include <errno.h> +#include <malloc.h> +#include <watchdog.h> +#include <mach/clocks.h> + +/* WD register description */ +struct wdt { + u32 res0; + u32 swcrr; /* note: read often, write once */ + u32 swcnr; + u16 res1; + u16 swsrr; +}; + +struct mpc5125_wd { + struct watchdog wd; + struct wdt *regs; + bool re_configured; +}; + +#define WDT_SWCRR_GET_SWTC(x) ((x) >> 16) +#define WDT_SWCRR_SET_SWTC(x) ((x) << 16) +#define WDT_SWCRR_SWEN (1 << 2) +#define WDT_SWCRR_SWRI (1 << 1) +#define WDT_SWCRR_SWPR (1 << 0) + +#define MPC5125_WDT_RESET1_MAGIC 0x556c +#define MPC5125_WDT_RESET2_MAGIC 0xaa39 + +#define MPC5125_WDT_PRESCALE 0x10000 + +#define to_mpc5125_wd(h) container_of(h, struct mpc5125_wd, wd) + +static void mpc5125_wd_retrigger(struct mpc5125_wd *wd) +{ + out_be16(&wd->regs->swsrr, 0x556c); + out_be16(&wd->regs->swsrr, 0xaa39); +} + +/* note: setting a new timeout is an irreversible step! */ +static int mpc5125_watchdog_set_timeout(struct watchdog *wd, unsigned timeout) +{ + struct mpc5125_wd *pwd = (struct mpc5125_wd *)to_mpc5125_wd(wd); + unsigned cnt_val, time; + uint64_t new_cnt_val; + u32 swcrr; + + /* + * what does the user wants us to do? + * - just retrigger? + * - or re-programming to a different timout value? + * + * Due to the fact we can program the SWCRR register only once we + * must detect a difference between the given timeout and the time + * which is currently in use to have the latter case. + * If the given timeout is "nealy" the same then currently used, just + * a re-trigger should occure (first case). + */ + swcrr = in_be32(&pwd->regs->swcrr); + cnt_val = WDT_SWCRR_GET_SWTC(swcrr); + + if (swcrr & WDT_SWCRR_SWPR) + time = (cnt_val * MPC5125_WDT_PRESCALE) / get_timebase_clock(); + else + time = cnt_val / get_timebase_clock(); + + if (time != timeout) { + /* it seems the user wants a new timout value */ + if (pwd->re_configured) { + pr_err("Cannot configure the watchdog twice. " + "Still sticked to %u seconds.\n", time); + return -EINVAL; + } + /* + * we always need the prescaler enabled, because without it + * the timeout is far below a second... + */ + new_cnt_val = timeout * get_timebase_clock(); + if (new_cnt_val >= 0xffff0000) { + time = 0xffff0000 / get_timebase_clock(); + pr_err("Invalid timout value. Max value is " + "%u seconds.\n", time); + return -EINVAL; + } + new_cnt_val /= MPC5125_WDT_PRESCALE; + out_be32(&pwd->regs->swcrr, WDT_SWCRR_SET_SWTC(new_cnt_val) | + WDT_SWCRR_SWPR | WDT_SWCRR_SWEN | WDT_SWCRR_SWRI); + pwd->re_configured = true; + } + + mpc5125_wd_retrigger(pwd); + + return 0; +} + +static int mpc5125_wd_probe(struct device_d *dev) +{ + struct mpc5125_wd *priv; + int rc; + + priv = xzalloc(sizeof(struct mpc5125_wd)); + priv->regs = dev_request_mem_region(dev, 0); + priv->wd.set_timeout = mpc5125_watchdog_set_timeout; + + rc = watchdog_register(&priv->wd); + if (rc != 0) + goto on_error; + + dev->priv = priv; + return 0; + +on_error: + free(priv); + return rc; +} + +static void mpc5125_wd_remove(struct device_d *dev) +{ + struct mpc5125_wd *priv= dev->priv; + watchdog_deregister(&priv->wd); + free(priv); +} + +static struct driver_d mpc5125_wd_driver = { + .name = "mpc5125wd", + .probe = mpc5125_wd_probe, + .remove = mpc5125_wd_remove, +}; +device_platform_driver(mpc5125_wd_driver); -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 19/19] MPC5125/GPIO: add a generic GPIO driver 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis ` (17 preceding siblings ...) 2014-10-07 14:22 ` [PATCH 18/19] MPC5125/WDG: add a watchdog driver Juergen Borleis @ 2014-10-07 14:22 ` Juergen Borleis 18 siblings, 0 replies; 20+ messages in thread From: Juergen Borleis @ 2014-10-07 14:22 UTC (permalink / raw) To: barebox The MPC5125 can handle up to 64 GPIOs divided in two units to control them. Note: this driver cannot be used with a MPC521 or MPC5123! Signed-off-by: Juergen Borleis <jbe@pengutronix.de> --- arch/ppc/include/asm/gpio.h | 28 ++++++ arch/ppc/mach-mpc5xxx/Kconfig | 1 + arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h | 2 + drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mpc5125.c | 136 +++++++++++++++++++++++++++ 6 files changed, 174 insertions(+) create mode 100644 arch/ppc/include/asm/gpio.h create mode 100644 drivers/gpio/gpio-mpc5125.c diff --git a/arch/ppc/include/asm/gpio.h b/arch/ppc/include/asm/gpio.h new file mode 100644 index 0000000..63b712d --- /dev/null +++ b/arch/ppc/include/asm/gpio.h @@ -0,0 +1,28 @@ +#ifndef _ARCH_PPC_GPIO_H +#define _ARCH_PPC_GPIO_H + +#ifndef CONFIG_GPIOLIB +#include <mach/gpio.h> +#else /* CONFIG_GPIOLIB */ +#ifdef CONFIG_SOC_MPC5125 +# define ARCH_NR_GPIOS 64 +#else +# error "GPIO count for this architecture is undefined" +#endif + +static inline int gpio_is_valid(int gpio) +{ + if (gpio < 0) + return 0; + if (gpio < ARCH_NR_GPIOS) + return 1; + return 0; +} + +void gpio_set_value(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); +int gpio_direction_output(unsigned gpio, int value); +int gpio_direction_input(unsigned gpio); +#endif /* CONFIG_GPIOLIB */ + +#endif /* _ARCH_PPC_GPIO_H */ diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig index a65c21d..0e969b7 100644 --- a/arch/ppc/mach-mpc5xxx/Kconfig +++ b/arch/ppc/mach-mpc5xxx/Kconfig @@ -35,6 +35,7 @@ config SOC_MPC5125 bool select MPC5xxx select ARCH_MPC512X + select GPIOLIB config MPC5xxx bool diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h index ed60f2a..20df42f 100644 --- a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h +++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h @@ -54,6 +54,8 @@ #define MPC512X_RESET (CFG_MBAR + 0x00E00) #define MPC512X_CLKM (CFG_MBAR + 0x00f00) #define MPC512X_WDT (CFG_MBAR + 0x00900) +#define MPC512X_GPIO1 (CFG_MBAR + 0x01100) +#define MPC512X_GPIO2 (CFG_MBAR + 0x01180) #define MPC512X_FEC1 (CFG_MBAR + 0x02800) #define MPC512X_FEC2 (CFG_MBAR + 0x04800) #define MPC512X_DRAMC (CFG_MBAR + 0x09000) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0ca7df4..e16ff80 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -110,6 +110,12 @@ config GPIO_DESIGNWARE help Say Y or M here to build support for the Synopsys DesignWare APB GPIO block. + +config GPIO_MPC5125 + tristate "PowerPC MPC5125 GPIO driver" + depends on SOC_MPC5125 + help + Say Y here to build support for the MPC5125 GPIO block. endmenu endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 510d146..82206db 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_DESIGNWARE) += gpio-dw.o +obj-$(CONFIG_GPIO_MPC5125) += gpio-mpc5125.o diff --git a/drivers/gpio/gpio-mpc5125.c b/drivers/gpio/gpio-mpc5125.c new file mode 100644 index 0000000..8d1bcb3 --- /dev/null +++ b/drivers/gpio/gpio-mpc5125.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014 Juergen Borleis, Pengutronix + * + * 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. + */ + +#include <common.h> +#include <errno.h> +#include <init.h> +#include <asm/io.h> +#include <gpio.h> +#include <mach/mpc5xxx.h> + +#define GPIO_DIR 0 +#define GPIO_ODR 1 +#define GPIO_DAT 2 +#define GPIO_IER 3 +#define GPIO_IMR 4 +#define GPIO_ICR1 5 +#define GPIO_ICR2 6 + +struct mpc5125_gpio_chip { + u32 __iomem *base; + struct gpio_chip chip; +}; + +static unsigned gpio_no_to_bit(unsigned gpio) +{ + /* + * GPIO0 is the highest bit in the register m( + * regular notation: GPIO0 is register bit 31 + * PPC notation: GPIO0 is register bit 0 + */ + return 1 << (31 - gpio); +} + +static void mpc5125_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip); + + if (value != 0) + setbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio)); + else + clrbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio)); +} + +static int mpc5125_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip); + + clrbits_be32(&mpcgpio->base[GPIO_DIR], gpio_no_to_bit(gpio)); + return 0; +} + +static int mpc5125_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip); + + /* GPIO 0 ... 3 in GPIO unit 1 are input only */ + if (mpcgpio->chip.dev->id == 0 && gpio < 4) { + dev_err(mpcgpio->chip.dev, "GPIO %u is input only\n", gpio); + return -ENODEV; + } + + if (value != 0) + setbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio)); + else + clrbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio)); + setbits_be32(&mpcgpio->base[GPIO_DIR], gpio_no_to_bit(gpio)); + + return 0; +} + +static int mpc5125_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip); + + return in_be32(&mpcgpio->base[GPIO_DAT]) & gpio_no_to_bit(gpio) ? 1 : 0; +} + +static int mpc5125_get_direction(struct gpio_chip *chip, unsigned gpio) +{ + struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip); + + return in_be32(&mpcgpio->base[GPIO_DIR]) & gpio_no_to_bit(gpio) ? + GPIOF_DIR_OUT : GPIOF_DIR_IN; +} + +static struct gpio_ops mpc5125_gpio_ops = { + .direction_input = mpc5125_gpio_direction_input, + .direction_output = mpc5125_gpio_direction_output, + .get = mpc5125_gpio_get_value, + .set = mpc5125_gpio_set_value, + .get_direction = mpc5125_get_direction, +}; + +static int mpc5125_gpio_probe(struct device_d *dev) +{ + struct mpc5125_gpio_chip *mpcgpio; + + mpcgpio = xzalloc(sizeof(*mpcgpio)); + mpcgpio->base = dev_request_mem_region(dev, 0); + mpcgpio->chip.ops = &mpc5125_gpio_ops; + mpcgpio->chip.base = dev->id * 32; + mpcgpio->chip.ngpio = 32; + mpcgpio->chip.dev = dev; + gpiochip_add(&mpcgpio->chip); + + dev_dbg(dev, "probed gpiochip%d with base %d\n", dev->id, mpcgpio->chip.base); + + return 0; +} + +static struct driver_d mpc5125_gpio_driver = { + .name = "mpc5125-gpio", + .probe = mpc5125_gpio_probe, +}; + +static int mpc5125_gpio_add(void) +{ + platform_driver_register(&mpc5125_gpio_driver); + add_generic_device("mpc5125-gpio", 0, NULL, MPC512X_GPIO1, + 0x80, IORESOURCE_MEM, NULL); + add_generic_device("mpc5125-gpio", 1, NULL, MPC512X_GPIO2, + 0x80, IORESOURCE_MEM, NULL); + return 0; +} +coredevice_initcall(mpc5125_gpio_add); -- 2.1.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2014-10-07 14:22 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-10-07 14:21 [RFC] Add PowerPC MPC5125 support Juergen Borleis 2014-10-07 14:22 ` [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200 Juergen Borleis 2014-10-07 14:22 ` [PATCH 02/19] arch/MPC5xxx: use a mach specific linker script instead of a board specific one Juergen Borleis 2014-10-07 14:22 ` [PATCH 03/19] arch/MPC5xxx: replace 'depends on' by 'select' Juergen Borleis 2014-10-07 14:22 ` [PATCH 04/19] arch/MPC5xxx: Simplify the calculation Juergen Borleis 2014-10-07 14:22 ` [PATCH 05/19] arch/MPC5xxx: just a format clean up Juergen Borleis 2014-10-07 14:22 ` [PATCH 06/19] arch/MPC5xxx: move away existing files to be able to add a new SoC type Juergen Borleis 2014-10-07 14:22 ` [PATCH 07/19] arch/MPC5xxx: separate architecture's main SoC header file Juergen Borleis 2014-10-07 14:22 ` [PATCH 08/19] arch/MPC5xxx: separate clock functions Juergen Borleis 2014-10-07 14:22 ` [PATCH 09/19] arch/MPC5xxx: just use macros instead of anonymous digits Juergen Borleis 2014-10-07 14:22 ` [PATCH 10/19] MPC5xxx/serial: use dedicated I/O functions instead of memory access Juergen Borleis 2014-10-07 14:22 ` [PATCH 11/19] MPC5xxx/serial: provide an easier way to share register description Juergen Borleis 2014-10-07 14:22 ` [PATCH 12/19] MPC5xxx/serial: use new shared " Juergen Borleis 2014-10-07 14:22 ` [PATCH 13/19] MPC5xxx/serial: re-factor the code to share it between MPC5200/MPC5125 Juergen Borleis 2014-10-07 14:22 ` [PATCH 14/19] arch/MPC5xxx: add MPC5125 SoC support Juergen Borleis 2014-10-07 14:22 ` [PATCH 15/19] arch/MPC5xxx: add MPC5125 to the build-system Juergen Borleis 2014-10-07 14:22 ` [PATCH 16/19] MPC5xxx/serial: add support for the MPC5125 SoC Juergen Borleis 2014-10-07 14:22 ` [PATCH 17/19] MPC5125/FEC: add another FEC driver " Juergen Borleis 2014-10-07 14:22 ` [PATCH 18/19] MPC5125/WDG: add a watchdog driver Juergen Borleis 2014-10-07 14:22 ` [PATCH 19/19] MPC5125/GPIO: add a generic GPIO driver Juergen Borleis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox