Merge branch 'for-next/marvell'
Conflicts: arch/arm/Makefile
This commit is contained in:
commit
89fd7e44db
|
@ -39,6 +39,8 @@ barebox.ubl
|
|||
barebox.zynq
|
||||
barebox.uimage
|
||||
barebox.map
|
||||
barebox.kwb
|
||||
barebox.kwbuart
|
||||
barebox-flash-image
|
||||
System.map
|
||||
Module.symvers
|
||||
|
|
2
Makefile
2
Makefile
|
@ -970,7 +970,7 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
|
|||
.tmp_kallsyms* common/barebox_default_env* barebox.ldr \
|
||||
scripts/bareboxenv-target barebox-flash-image \
|
||||
Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
|
||||
barebox.uimage barebox.spi
|
||||
barebox.uimage barebox.spi barebox.kwb barebox.kwbuart
|
||||
|
||||
# Directories & files removed with 'make mrproper'
|
||||
MRPROPER_DIRS += include/config include2 usr/include
|
||||
|
|
|
@ -79,6 +79,12 @@ config ARCH_IMX
|
|||
select WATCHDOG_IMX_RESET_SOURCE
|
||||
select HAS_DEBUG_LL
|
||||
|
||||
config ARCH_MVEBU
|
||||
bool "Marvell EBU platforms"
|
||||
select COMMON_CLK
|
||||
select CLKDEV_LOOKUP
|
||||
select HAS_DEBUG_LL
|
||||
|
||||
config ARCH_MXS
|
||||
bool "Freescale i.MX23/28 (mxs) based"
|
||||
select GENERIC_GPIO
|
||||
|
@ -161,6 +167,7 @@ source arch/arm/mach-ep93xx/Kconfig
|
|||
source arch/arm/mach-highbank/Kconfig
|
||||
source arch/arm/mach-imx/Kconfig
|
||||
source arch/arm/mach-mxs/Kconfig
|
||||
source arch/arm/mach-mvebu/Kconfig
|
||||
source arch/arm/mach-netx/Kconfig
|
||||
source arch/arm/mach-nomadik/Kconfig
|
||||
source arch/arm/mach-omap/Kconfig
|
||||
|
|
|
@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_EP93XX) := ep93xx
|
|||
machine-$(CONFIG_ARCH_HIGHBANK) := highbank
|
||||
machine-$(CONFIG_ARCH_IMX) := imx
|
||||
machine-$(CONFIG_ARCH_MXS) := mxs
|
||||
machine-$(CONFIG_ARCH_MVEBU) := mvebu
|
||||
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
|
||||
machine-$(CONFIG_ARCH_NETX) := netx
|
||||
machine-$(CONFIG_ARCH_OMAP) := omap
|
||||
|
@ -70,6 +71,7 @@ machine-$(CONFIG_ARCH_ZYNQ) := zynq
|
|||
|
||||
# Board directory name. This list is sorted alphanumerically
|
||||
# by CONFIG_* macro name.
|
||||
|
||||
board-$(CONFIG_MACH_A9M2410) += a9m2410
|
||||
board-$(CONFIG_MACH_A9M2440) += a9m2440
|
||||
board-$(CONFIG_MACH_ANIMEO_IP) += animeo_ip
|
||||
|
@ -110,12 +112,15 @@ board-$(CONFIG_MACH_FREESCALE_MX51_PDK) += freescale-mx51-pdk
|
|||
board-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += freescale-mx53-loco
|
||||
board-$(CONFIG_MACH_FREESCALE_MX53_SMD) += freescale-mx53-smd
|
||||
board-$(CONFIG_MACH_GE863) += telit-evk-pro3
|
||||
board-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += globalscale-guruplug
|
||||
board-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += globalscale-mirabox
|
||||
board-$(CONFIG_MACH_GUF_CUPID) += guf-cupid
|
||||
board-$(CONFIG_MACH_GUF_VINCELL) += guf-vincell
|
||||
board-$(CONFIG_MACH_HIGHBANK) += highbank
|
||||
board-$(CONFIG_MACH_IMX21ADS) += imx21ads
|
||||
board-$(CONFIG_MACH_IMX233_OLINUXINO) += imx233-olinuxino
|
||||
board-$(CONFIG_MACH_IMX27ADS) += imx27ads
|
||||
board-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += marvell-armada-xp-gp
|
||||
board-$(CONFIG_MACH_MINI2440) += friendlyarm-mini2440
|
||||
board-$(CONFIG_MACH_MINI6410) += friendlyarm-mini6410
|
||||
board-$(CONFIG_MACH_MIOA701) += mioa701
|
||||
|
@ -138,6 +143,7 @@ board-$(CONFIG_MACH_PCM038) += pcm038
|
|||
board-$(CONFIG_MACH_PCM043) += pcm043
|
||||
board-$(CONFIG_MACH_PCM049) += pcm049
|
||||
board-$(CONFIG_MACH_PCM051) += pcm051
|
||||
board-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += plathome-openblocks-ax3
|
||||
board-$(CONFIG_MACH_PM9261) += pm9261
|
||||
board-$(CONFIG_MACH_PM9263) += pm9263
|
||||
board-$(CONFIG_MACH_PM9G45) += pm9g45
|
||||
|
@ -149,6 +155,7 @@ board-$(CONFIG_MACH_SABRELITE) += freescale-mx6-sabrelite
|
|||
board-$(CONFIG_MACH_SABRESD) += freescale-mx6-sabresd
|
||||
board-$(CONFIG_MACH_SAMA5D3XEK) += sama5d3xek
|
||||
board-$(CONFIG_MACH_SCB9328) += scb9328
|
||||
board-$(CONFIG_MACH_SOLIDRUN_CUBOX) += solidrun-cubox
|
||||
board-$(CONFIG_MACH_TINY210) += friendlyarm-tiny210
|
||||
board-$(CONFIG_MACH_TINY6410) += friendlyarm-tiny6410
|
||||
board-$(CONFIG_MACH_TNY_A9260) += tny-a926x
|
||||
|
@ -265,6 +272,27 @@ ifeq ($(CONFIG_ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE),y)
|
|||
KBUILD_IMAGE := barebox.imx
|
||||
endif
|
||||
|
||||
KWBIMAGE_OPTS = \
|
||||
-c -i $(srctree)/$(BOARD)/kwbimage.cfg -d $(TEXT_BASE) -e $(TEXT_BASE)
|
||||
|
||||
quiet_cmd_kwbimage = KWB $@
|
||||
cmd_kwbimage = scripts/kwbimage -p $< $(KWBIMAGE_OPTS) -o $@ || \
|
||||
echo "WARNING: Couldn't create KWB image due to previous errors."
|
||||
|
||||
quiet_cmd_kwbimage_uart = KWBUART $@
|
||||
cmd_kwbimage_uart = scripts/kwbimage -m uart -p $< $(KWBIMAGE_OPTS) -o $@ || \
|
||||
echo "WARNING Couldn't create KWB image due to previous errors."
|
||||
|
||||
barebox.kwb: $(KBUILD_BINARY) FORCE
|
||||
$(call if_changed,kwbimage)
|
||||
|
||||
barebox.kwbuart: $(KBUILD_BINARY) FORCE
|
||||
$(call if_changed,kwbimage_uart)
|
||||
|
||||
ifeq ($(CONFIG_ARCH_MVEBU),y)
|
||||
KBUILD_IMAGE := barebox.kwb barebox.kwbuart
|
||||
endif
|
||||
|
||||
pbl := arch/arm/pbl
|
||||
$(pbl)/zbarebox.S $(pbl)/zbarebox.bin $(pbl)/zbarebox: barebox.bin FORCE
|
||||
$(Q)$(MAKE) $(build)=$(pbl) $@
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
obj-y += board.o
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* empty */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,27 @@
|
|||
VERSION 0
|
||||
BOOT_FROM nand
|
||||
NAND_ECCMODE default
|
||||
NAND_PAGESZ 00000800
|
||||
DATA ffd100e0 1b1b9b9b
|
||||
DATA ffd01400 43000c30
|
||||
DATA ffd01404 37543000
|
||||
DATA ffd01408 22125451
|
||||
DATA ffd0140c 00000a33
|
||||
DATA ffd01410 000000cc
|
||||
DATA ffd01414 00000000
|
||||
DATA ffd01418 00000000
|
||||
DATA ffd0141c 00000c52
|
||||
DATA ffd01420 00000040
|
||||
DATA ffd01424 0000f17f
|
||||
DATA ffd01428 00085520
|
||||
DATA ffd0147c 00008552
|
||||
DATA ffd01500 00000000
|
||||
DATA ffd01504 0ffffff1
|
||||
DATA ffd01508 10000000
|
||||
DATA ffd0150c 0ffffff5
|
||||
DATA ffd01514 00000000
|
||||
DATA ffd0151c 00000000
|
||||
DATA ffd01494 00030000
|
||||
DATA ffd01498 00000000
|
||||
DATA ffd0149c 0000e803
|
||||
DATA ffd01480 00000001
|
|
@ -0,0 +1 @@
|
|||
obj-y += board.c
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* empty */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,5 @@
|
|||
VERSION 1
|
||||
BOOT_FROM nand
|
||||
NAND_BLKSZ 00020000
|
||||
NAND_BADBLK_LOCATION 01
|
||||
BINARY globalscale-mirabox-binary.0 0000005b 00000068
|
|
@ -0,0 +1 @@
|
|||
obj-y += board.o
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* empty */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,3 @@
|
|||
VERSION 1
|
||||
BOOT_FROM spi
|
||||
BINARY marvell-armada-xp-gp-binary.0 0000005b 00000068
|
|
@ -0,0 +1 @@
|
|||
obj-y += board.o
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* empty */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,3 @@
|
|||
VERSION 1
|
||||
BOOT_FROM spi
|
||||
BINARY plathome-openblocks-ax3-binary.0 0000005b 00000068
|
|
@ -0,0 +1 @@
|
|||
obj-y += board.c
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* empty */
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -0,0 +1,37 @@
|
|||
VERSION 0
|
||||
BOOT_FROM spi
|
||||
DATA d0020104 00000000
|
||||
DATA d0800020 00022430
|
||||
DATA d0800030 00022430
|
||||
DATA d0800050 911500c3
|
||||
DATA d0800060 646602c4
|
||||
DATA d0800190 c2003053
|
||||
DATA d08001c0 34f4a187
|
||||
DATA d0800650 000f0121
|
||||
DATA d0800660 04040200
|
||||
DATA d0800080 00000000
|
||||
DATA d0800090 00080000
|
||||
DATA d08000f0 c0000000
|
||||
DATA d08001a0 20c0c009
|
||||
DATA d0800280 010e0202
|
||||
DATA d0800760 00000000
|
||||
DATA d0800770 0000000a
|
||||
DATA d0800140 20004044
|
||||
DATA d08001d0 133c2339
|
||||
DATA d08001e0 07700330
|
||||
DATA d08001f0 00000033
|
||||
DATA d0800200 0011311c
|
||||
DATA d0800210 00300000
|
||||
DATA d0800240 80000000
|
||||
DATA d0800510 010e0101
|
||||
DATA d0800230 2028006a
|
||||
DATA d0800e10 00280062
|
||||
DATA d0800e20 00280062
|
||||
DATA d0800e30 00280062
|
||||
DATA d0800100 000d0001
|
||||
DATA d0800110 200d0001
|
||||
DATA d0020104 00000000
|
||||
DATA d0020104 00000000
|
||||
DATA d0020104 00000000
|
||||
DATA d0020104 00000000
|
||||
DATA d0020104 00000000
|
|
@ -0,0 +1,6 @@
|
|||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_ARCH_KIRKWOOD=y
|
||||
CONFIG_TEXT_BASE=0x2000000
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
|
@ -0,0 +1,8 @@
|
|||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_CMD_LOADY=y
|
||||
CONFIG_CMD_LOADS=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
|
@ -0,0 +1,10 @@
|
|||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_ARCH_ARMADA_XP=y
|
||||
CONFIG_MACH_MARVELL_ARMADA_XP_GP=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_CMD_LOADY=y
|
||||
CONFIG_CMD_LOADS=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
|
@ -0,0 +1,9 @@
|
|||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_ARCH_ARMADA_XP=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_CMD_LOADY=y
|
||||
CONFIG_CMD_LOADS=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
|
@ -0,0 +1,9 @@
|
|||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_ARCH_DOVE=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_CMD_LOADY=y
|
||||
CONFIG_CMD_LOADS=y
|
||||
CONFIG_CMD_RESET=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_DRIVER_SERIAL_NS16550=y
|
|
@ -39,6 +39,14 @@ config CPU_ARM926T
|
|||
Say Y if you want support for the ARM926T processor.
|
||||
Otherwise, say N.
|
||||
|
||||
# Feroceon
|
||||
config CPU_FEROCEON
|
||||
bool
|
||||
select CPU_32v5
|
||||
help
|
||||
This is a Marvell implementation of an ARMv5TE compatible
|
||||
ARM core, used in the Marvell Kirkwood SoC family.
|
||||
|
||||
# ARMv6
|
||||
config CPU_V6
|
||||
bool
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
if ARCH_MVEBU
|
||||
|
||||
config ARCH_TEXT_BASE
|
||||
hex
|
||||
default 0x2000000 if MACH_PLATHOME_OPENBLOCKS_AX3
|
||||
default 0x2000000 if MACH_GLOBALSCALE_MIRABOX
|
||||
default 0x2000000 if MACH_GLOBALSCALE_GURUPLUG
|
||||
default 0x2000000 if MACH_MARVELL_ARMADA_XP_GP
|
||||
default 0x2000000 if MACH_SOLIDRUN_CUBOX
|
||||
|
||||
config BOARDINFO
|
||||
default "PlatHome OpenBlocks AX3" if MACH_PLATHOME_OPENBLOCKS_AX3
|
||||
default "Globalscale Mirabox" if MACH_GLOBALSCALE_MIRABOX
|
||||
default "Globalscale Guruplug" if MACH_GLOBALSCALE_GURUPLUG
|
||||
default "Marvell Armada XP GP" if MACH_MARVELL_ARMADA_XP_GP
|
||||
default "SolidRun CuBox" if MACH_SOLIDRUN_CUBOX
|
||||
|
||||
choice
|
||||
prompt "Marvell EBU Processor"
|
||||
|
||||
config ARCH_ARMADA_370
|
||||
bool "Armada 370"
|
||||
select CPU_V7
|
||||
select CLOCKSOURCE_MVEBU
|
||||
|
||||
config ARCH_ARMADA_XP
|
||||
bool "Armada XP"
|
||||
select CPU_V7
|
||||
select CLOCKSOURCE_MVEBU
|
||||
|
||||
config ARCH_DOVE
|
||||
bool "Dove 88AP510"
|
||||
select CPU_V7
|
||||
select CLOCKSOURCE_ORION
|
||||
|
||||
config ARCH_KIRKWOOD
|
||||
bool "Kirkwood"
|
||||
select CPU_FEROCEON
|
||||
select CLOCKSOURCE_ORION
|
||||
|
||||
endchoice
|
||||
|
||||
#
|
||||
# Armada 370 SoC boards
|
||||
#
|
||||
|
||||
if ARCH_ARMADA_370
|
||||
|
||||
choice
|
||||
prompt "Armada 370 Board Type"
|
||||
|
||||
config MACH_GLOBALSCALE_MIRABOX
|
||||
bool "Globalscale Mirabox"
|
||||
|
||||
endchoice
|
||||
|
||||
endif # ARCH_ARMADA_370
|
||||
|
||||
#
|
||||
# Armada XP SoC boards
|
||||
#
|
||||
|
||||
if ARCH_ARMADA_XP
|
||||
|
||||
choice
|
||||
prompt "Armada XP Board Type"
|
||||
|
||||
config MACH_PLATHOME_OPENBLOCKS_AX3
|
||||
bool "PlatHome OpenBlocks AX3"
|
||||
|
||||
config MACH_MARVELL_ARMADA_XP_GP
|
||||
bool "Marvell Armada XP GP"
|
||||
|
||||
endchoice
|
||||
|
||||
endif # ARCH_ARMADA_XP
|
||||
|
||||
#
|
||||
# Dove 88AP510 SoC boards
|
||||
#
|
||||
|
||||
if ARCH_DOVE
|
||||
|
||||
choice
|
||||
prompt "Dove 88AP510 Board Type"
|
||||
|
||||
config MACH_SOLIDRUN_CUBOX
|
||||
bool "SolidRun CuBox"
|
||||
|
||||
endchoice
|
||||
|
||||
endif # ARCH_DOVE
|
||||
|
||||
#
|
||||
# Kirkwood SoC boards
|
||||
#
|
||||
|
||||
if ARCH_KIRKWOOD
|
||||
|
||||
choice
|
||||
prompt "Kirkwood Board Type"
|
||||
|
||||
config MACH_GLOBALSCALE_GURUPLUG
|
||||
bool "Guruplug"
|
||||
|
||||
endchoice
|
||||
|
||||
endif # ARCH_KIRKWOOD
|
||||
|
||||
#
|
||||
# Common options
|
||||
#
|
||||
|
||||
config MVEBU_CONSOLE_UART
|
||||
int "UART number for console"
|
||||
default 0
|
||||
range 0 1 if ARCH_ARMADA_370
|
||||
range 0 1 if ARCH_ARMADA_XP
|
||||
range 0 3 if ARCH_DOVE
|
||||
range 0 1 if ARCH_KIRKWOOD
|
||||
help
|
||||
Select the UART number the barebox console will sit on.
|
||||
|
||||
endif # ARCH_MVEBU
|
|
@ -0,0 +1,6 @@
|
|||
lwl-y += lowlevel.o
|
||||
obj-y += common.o
|
||||
obj-$(CONFIG_ARCH_ARMADA_370) += armada-370-xp.o
|
||||
obj-$(CONFIG_ARCH_ARMADA_XP) += armada-370-xp.o
|
||||
obj-$(CONFIG_ARCH_DOVE) += dove.o
|
||||
obj-$(CONFIG_ARCH_KIRKWOOD) += kirkwood.o
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <ns16550.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <asm/memory.h>
|
||||
#include <mach/armada-370-xp-regs.h>
|
||||
|
||||
#define CONSOLE_UART_BASE \
|
||||
ARMADA_370_XP_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
|
||||
|
||||
static struct clk *tclk;
|
||||
|
||||
static inline void armada_370_xp_memory_find(unsigned long *phys_base,
|
||||
unsigned long *phys_size)
|
||||
{
|
||||
int cs;
|
||||
|
||||
*phys_base = ~0;
|
||||
*phys_size = 0;
|
||||
|
||||
for (cs = 0; cs < 4; cs++) {
|
||||
u32 base = readl(ARMADA_370_XP_SDRAM_BASE + DDR_BASE_CSn(cs));
|
||||
u32 ctrl = readl(ARMADA_370_XP_SDRAM_BASE + DDR_SIZE_CSn(cs));
|
||||
|
||||
/* Skip non-enabled CS */
|
||||
if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
|
||||
continue;
|
||||
|
||||
base &= DDR_BASE_CS_LOW_MASK;
|
||||
if (base < *phys_base)
|
||||
*phys_base = base;
|
||||
*phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct NS16550_plat uart_plat = {
|
||||
.shift = 2,
|
||||
};
|
||||
|
||||
static int armada_370_xp_add_uart(void)
|
||||
{
|
||||
uart_plat.clock = clk_get_rate(tclk);
|
||||
if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
|
||||
(unsigned int)CONSOLE_UART_BASE, 32,
|
||||
IORESOURCE_MEM_32BIT, &uart_plat))
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMADA_370)
|
||||
static int armada_370_init_clocks(void)
|
||||
{
|
||||
u32 val = readl(ARMADA_370_XP_SAR_BASE + SAR_LOW);
|
||||
unsigned int rate;
|
||||
|
||||
/*
|
||||
* On Armada 370, the TCLK frequency can be either
|
||||
* 166 Mhz or 200 Mhz
|
||||
*/
|
||||
if ((val & SAR_TCLK_FREQ) == SAR_TCLK_FREQ)
|
||||
rate = 200000000;
|
||||
else
|
||||
rate = 166000000;
|
||||
|
||||
tclk = clk_fixed("tclk", rate);
|
||||
return clk_register_clkdev(tclk, NULL, "mvebu-timer");
|
||||
}
|
||||
#define armada_370_xp_init_clocks() armada_370_init_clocks()
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMADA_XP)
|
||||
static int armada_xp_init_clocks(void)
|
||||
{
|
||||
/* On Armada XP, the TCLK frequency is always 250 Mhz */
|
||||
tclk = clk_fixed("tclk", 250000000);
|
||||
return clk_register_clkdev(tclk, NULL, "mvebu-timer");
|
||||
}
|
||||
#define armada_370_xp_init_clocks() armada_xp_init_clocks()
|
||||
#endif
|
||||
|
||||
static int armada_370_xp_init_soc(void)
|
||||
{
|
||||
unsigned long phys_base, phys_size;
|
||||
|
||||
armada_370_xp_init_clocks();
|
||||
add_generic_device("mvebu-timer", DEVICE_ID_SINGLE, NULL,
|
||||
(unsigned int)ARMADA_370_XP_TIMER_BASE, 0x30,
|
||||
IORESOURCE_MEM, NULL);
|
||||
armada_370_xp_memory_find(&phys_base, &phys_size);
|
||||
arm_add_mem_device("ram0", phys_base, phys_size);
|
||||
armada_370_xp_add_uart();
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(armada_370_xp_init_soc);
|
||||
|
||||
void __noreturn reset_cpu(unsigned long addr)
|
||||
{
|
||||
writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x60);
|
||||
writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x64);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
EXPORT_SYMBOL(reset_cpu);
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <io.h>
|
||||
#include <sizes.h>
|
||||
#include <asm/barebox-arm.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
/*
|
||||
* All MVEBU SoCs start with internal registers at 0xd0000000.
|
||||
* To get more contiguous address space and as Linux expects them
|
||||
* there, we remap them early to 0xf1000000.
|
||||
*
|
||||
* There is no way to determine internal registers base address
|
||||
* safely later on, as the remap register itself is within the
|
||||
* internal registers.
|
||||
*/
|
||||
#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000
|
||||
#define MVEBU_BRIDGE_REG_BASE 0x20000
|
||||
#define DEVICE_INTERNAL_BASE_ADDR (MVEBU_BRIDGE_REG_BASE + 0x80)
|
||||
|
||||
static void mvebu_remap_registers(void)
|
||||
{
|
||||
writel(MVEBU_REMAP_INT_REG_BASE,
|
||||
IOMEM(MVEBU_BOOTUP_INT_REG_BASE) + DEVICE_INTERNAL_BASE_ADDR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determining the actual memory size is highly SoC dependent,
|
||||
* but for all SoCs RAM starts at 0x00000000. Therefore, we start
|
||||
* with a minimal memory setup of 64M and probe correct memory size
|
||||
* later.
|
||||
*/
|
||||
#define MVEBU_BOOTUP_MEMORY_BASE 0x00000000
|
||||
#define MVEBU_BOOTUP_MEMORY_SIZE SZ_64M
|
||||
|
||||
void __naked __noreturn mvebu_barebox_entry(void)
|
||||
{
|
||||
mvebu_remap_registers();
|
||||
barebox_arm_entry(MVEBU_BOOTUP_MEMORY_BASE,
|
||||
MVEBU_BOOTUP_MEMORY_SIZE, 0);
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <ns16550.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <asm/memory.h>
|
||||
#include <mach/dove-regs.h>
|
||||
|
||||
#define CONSOLE_UART_BASE DOVE_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
|
||||
|
||||
static struct clk *tclk;
|
||||
|
||||
static inline void dove_remap_mc_regs(void)
|
||||
{
|
||||
void __iomem *mcboot = IOMEM(DOVE_BOOTUP_MC_REGS);
|
||||
uint32_t val;
|
||||
|
||||
/* remap ahb slave base */
|
||||
val = readl(DOVE_CPU_CTRL) & 0xffff0000;
|
||||
val |= (DOVE_REMAP_MC_REGS & 0xffff0000) >> 16;
|
||||
writel(val, DOVE_CPU_CTRL);
|
||||
|
||||
/* remap axi bridge address */
|
||||
val = readl(DOVE_AXI_CTRL) & 0x007fffff;
|
||||
val |= DOVE_REMAP_MC_REGS & 0xff800000;
|
||||
writel(val, DOVE_AXI_CTRL);
|
||||
|
||||
/* remap memory controller base address */
|
||||
val = readl(mcboot + SDRAM_REGS_BASE_DECODE) & 0x0000ffff;
|
||||
val |= DOVE_REMAP_MC_REGS & 0xffff0000;
|
||||
writel(val, mcboot + SDRAM_REGS_BASE_DECODE);
|
||||
}
|
||||
|
||||
static inline void dove_memory_find(unsigned long *phys_base,
|
||||
unsigned long *phys_size)
|
||||
{
|
||||
int n;
|
||||
|
||||
*phys_base = ~0;
|
||||
*phys_size = 0;
|
||||
|
||||
for (n = 0; n < 2; n++) {
|
||||
uint32_t map = readl(DOVE_SDRAM_BASE + SDRAM_MAPn(n));
|
||||
uint32_t base, size;
|
||||
|
||||
/* skip disabled areas */
|
||||
if ((map & SDRAM_MAP_VALID) != SDRAM_MAP_VALID)
|
||||
continue;
|
||||
|
||||
base = map & SDRAM_START_MASK;
|
||||
if (base < *phys_base)
|
||||
*phys_base = base;
|
||||
|
||||
/* real size is encoded as ld(2^(16+length)) */
|
||||
size = (map & SDRAM_LENGTH_MASK) >> SDRAM_LENGTH_SHIFT;
|
||||
*phys_size += 1 << (16 + size);
|
||||
}
|
||||
}
|
||||
|
||||
static struct NS16550_plat uart_plat = {
|
||||
.shift = 2,
|
||||
};
|
||||
|
||||
static int dove_add_uart(void)
|
||||
{
|
||||
uart_plat.clock = clk_get_rate(tclk);
|
||||
if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
|
||||
(unsigned int)CONSOLE_UART_BASE, 32,
|
||||
IORESOURCE_MEM_32BIT, &uart_plat))
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dove TCLK sample-at-reset configuation
|
||||
*
|
||||
* SAR0[24:23] : TCLK frequency
|
||||
* 0 = 166 MHz
|
||||
* 1 = 125 MHz
|
||||
* others reserved.
|
||||
*/
|
||||
static int dove_init_clocks(void)
|
||||
{
|
||||
uint32_t strap, sar = readl(DOVE_SAR_BASE + SAR0);
|
||||
unsigned int rate;
|
||||
|
||||
strap = (sar & TCLK_FREQ_MASK) >> TCLK_FREQ_SHIFT;
|
||||
switch (strap) {
|
||||
case 0:
|
||||
rate = 166666667;
|
||||
break;
|
||||
case 1:
|
||||
rate = 125000000;
|
||||
break;
|
||||
default:
|
||||
panic("Unknown TCLK strapping %d\n", strap);
|
||||
}
|
||||
|
||||
tclk = clk_fixed("tclk", rate);
|
||||
return clk_register_clkdev(tclk, NULL, "orion-timer");
|
||||
}
|
||||
|
||||
static int dove_init_soc(void)
|
||||
{
|
||||
unsigned long phys_base, phys_size;
|
||||
|
||||
dove_remap_mc_regs();
|
||||
dove_init_clocks();
|
||||
add_generic_device("orion-timer", DEVICE_ID_SINGLE, NULL,
|
||||
(unsigned int)DOVE_TIMER_BASE, 0x30,
|
||||
IORESOURCE_MEM, NULL);
|
||||
dove_memory_find(&phys_base, &phys_size);
|
||||
arm_add_mem_device("ram0", phys_base, phys_size);
|
||||
dove_add_uart();
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(dove_init_soc);
|
||||
|
||||
void __noreturn reset_cpu(unsigned long addr)
|
||||
{
|
||||
/* enable and assert RSTOUTn */
|
||||
writel(SOFT_RESET_OUT_EN, DOVE_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
|
||||
writel(SOFT_RESET_EN, DOVE_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
EXPORT_SYMBOL(reset_cpu);
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MVEBU_ARMADA_370_XP_REGS_H
|
||||
#define __MACH_MVEBU_ARMADA_370_XP_REGS_H
|
||||
|
||||
#include <mach/common.h>
|
||||
|
||||
#define ARMADA_370_XP_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
|
||||
#define ARMADA_370_XP_UART_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x12000)
|
||||
#define ARMADA_370_XP_UARTn_BASE(n) \
|
||||
(ARMADA_370_XP_UART_BASE + ((n) * 0x100))
|
||||
|
||||
#define ARMADA_370_XP_SYSCTL_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x18200)
|
||||
#define ARMADA_370_XP_SAR_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x18230)
|
||||
#define SAR_LOW 0x00
|
||||
#define SAR_TCLK_FREQ BIT(20)
|
||||
#define SAR_HIGH 0x04
|
||||
|
||||
#define ARMADA_370_XP_SDRAM_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x20000)
|
||||
#define DDR_BASE_CS 0x180
|
||||
#define DDR_BASE_CSn(n) (DDR_BASE_CS + ((n) * 0x8))
|
||||
#define DDR_BASE_CS_HIGH_MASK 0x0000000f
|
||||
#define DDR_BASE_CS_LOW_MASK 0xff000000
|
||||
#define DDR_SIZE_CS 0x184
|
||||
#define DDR_SIZE_CSn(n) (DDR_SIZE_CS + ((n) * 0x8))
|
||||
#define DDR_SIZE_ENABLED BIT(0)
|
||||
#define DDR_SIZE_CS_MASK 0x0000001c
|
||||
#define DDR_SIZE_CS_SHIFT 2
|
||||
#define DDR_SIZE_MASK 0xff000000
|
||||
|
||||
#define ARMADA_370_XP_TIMER_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x20300)
|
||||
|
||||
#endif /* __MACH_MVEBU_DOVE_REGS_H */
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_COMMON_H__
|
||||
#define __MACH_COMMON_H__
|
||||
|
||||
#define MVEBU_REMAP_INT_REG_BASE 0xf1000000
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_DEBUG_LL_H__
|
||||
#define __MACH_DEBUG_LL_H__
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#define UART_BASE 0xf1012000
|
||||
#define UARTn_BASE(n) (UART_BASE + ((n) * 0x100))
|
||||
#define UART_THR 0x00
|
||||
#define UART_LSR 0x14
|
||||
#define LSR_THRE BIT(5)
|
||||
|
||||
#define EARLY_UART UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
|
||||
|
||||
static inline void PUTC_LL(char c)
|
||||
{
|
||||
/* Wait until there is space in the FIFO */
|
||||
while (!(readl(EARLY_UART + UART_LSR) & LSR_THRE))
|
||||
;
|
||||
|
||||
/* Send the character */
|
||||
writel(c, EARLY_UART + UART_THR);
|
||||
|
||||
/* Wait to make sure it hits the line */
|
||||
while (!(readl(EARLY_UART + UART_LSR) & LSR_THRE))
|
||||
;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MVEBU_DOVE_REGS_H
|
||||
#define __MACH_MVEBU_DOVE_REGS_H
|
||||
|
||||
#include <mach/common.h>
|
||||
|
||||
/*
|
||||
* Even after MVEBU SoC internal register base remap. Dove MC
|
||||
* registers are still at 0xd0800000. We remap it right after
|
||||
* internal registers to 0xf1800000.
|
||||
*/
|
||||
#define DOVE_BOOTUP_MC_REGS 0xd0800000
|
||||
#define DOVE_REMAP_MC_REGS 0xf1800000
|
||||
|
||||
#define DOVE_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
|
||||
#define DOVE_MC_REGS_BASE IOMEM(DOVE_REMAP_MC_REGS)
|
||||
|
||||
#define DOVE_UART_BASE (DOVE_INT_REGS_BASE + 0x12000)
|
||||
#define DOVE_UARTn_BASE(n) (DOVE_UART_BASE + ((n) * 0x100))
|
||||
|
||||
#define DOVE_BRIDGE_BASE (DOVE_INT_REGS_BASE + 0x20000)
|
||||
#define INT_REGS_BASE_MAP 0x080
|
||||
#define BRIDGE_RSTOUT_MASK 0x108
|
||||
#define SOFT_RESET_OUT_EN BIT(2)
|
||||
#define BRIDGE_SYS_SOFT_RESET 0x10c
|
||||
#define SOFT_RESET_EN BIT(0)
|
||||
#define DOVE_TIMER_BASE (DOVE_INT_REGS_BASE + 0x20300)
|
||||
|
||||
#define DOVE_SAR_BASE (DOVE_INT_REGS_BASE + 0xd0214)
|
||||
#define SAR0 0x000
|
||||
#define TCLK_FREQ_SHIFT 23
|
||||
#define TCLK_FREQ_MASK (0x3 << TCLK_FREQ_SHIFT)
|
||||
#define SAR1 0x004
|
||||
|
||||
#define DOVE_AXI_CTRL (DOVE_INT_REGS_BASE + 0xd0224)
|
||||
#define DOVE_CPU_CTRL (DOVE_INT_REGS_BASE + 0xd025c)
|
||||
|
||||
#define DOVE_SDRAM_BASE (DOVE_MC_REGS_BASE)
|
||||
#define SDRAM_REGS_BASE_DECODE 0x010
|
||||
#define SDRAM_MAPn(n) (0x100 + ((n) * 0x10))
|
||||
#define SDRAM_START_MASK (0x1ff << 23)
|
||||
#define SDRAM_LENGTH_SHIFT 16
|
||||
#define SDRAM_LENGTH_MASK (0x00f << SDRAM_LENGTH_SHIFT)
|
||||
#define SDRAM_ADDRESS_MASK (0x1ff << 7)
|
||||
#define SDRAM_MAP_VALID BIT(0)
|
||||
|
||||
#endif /* __MACH_MVEBU_DOVE_REGS_H */
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MVEBU_DOVE_H
|
||||
#define __MACH_MVEBU_DOVE_H
|
||||
|
||||
int dove_add_uart(int num);
|
||||
void __naked __noreturn dove_barebox_entry(void);
|
||||
|
||||
#endif /* __MACH_MVEBU_DOVE_H */
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MVEBU_KIRKWOOD_REGS_H
|
||||
#define __MACH_MVEBU_KIRKWOOD_REGS_H
|
||||
|
||||
#include <mach/common.h>
|
||||
|
||||
#define KIRKWOOD_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
|
||||
|
||||
#define KIRKWOOD_SDRAM_BASE (KIRKWOOD_INT_REGS_BASE + 0x00000)
|
||||
#define DDR_BASE_CS 0x1500
|
||||
#define DDR_BASE_CSn(n) (DDR_BASE_CS + ((n) * 0x8))
|
||||
#define DDR_BASE_CS_HIGH_MASK 0x0000000f
|
||||
#define DDR_BASE_CS_LOW_MASK 0xff000000
|
||||
#define DDR_SIZE_CS 0x1504
|
||||
#define DDR_SIZE_CSn(n) (DDR_SIZE_CS + ((n) * 0x8))
|
||||
#define DDR_SIZE_ENABLED BIT(0)
|
||||
#define DDR_SIZE_CS_MASK 0x1c
|
||||
#define DDR_SIZE_CS_SHIFT 2
|
||||
#define DDR_SIZE_MASK 0xff000000
|
||||
|
||||
#define KIRKWOOD_SAR_BASE (KIRKWOOD_INT_REGS_BASE + 0x10030)
|
||||
#define SAR_TCLK_FREQ BIT(21)
|
||||
|
||||
#define KIRKWOOD_UART_BASE (KIRKWOOD_INT_REGS_BASE + 0x12000)
|
||||
#define KIRKWOOD_UARTn_BASE(n) (KIRKWOOD_UART_BASE + ((n) * 0x100))
|
||||
|
||||
#define KIRKWOOD_BRIDGE_BASE (KIRKWOOD_INT_REGS_BASE + 0x20000)
|
||||
#define BRIDGE_RSTOUT_MASK 0x108
|
||||
#define SOFT_RESET_OUT_EN BIT(2)
|
||||
#define BRIDGE_SYS_SOFT_RESET 0x10c
|
||||
#define SOFT_RESET_EN BIT(0)
|
||||
|
||||
#define KIRKWOOD_TIMER_BASE (KIRKWOOD_INT_REGS_BASE + 0x20300)
|
||||
|
||||
#endif /* __MACH_MVEBU_KIRKWOOD_REGS_H */
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_KIRKWOOD_H
|
||||
#define __MACH_KIRKWOOD_H
|
||||
|
||||
int kirkwood_add_uart0(void);
|
||||
void __naked __noreturn kirkwood_barebox_entry(void);
|
||||
|
||||
#endif /* __MACH_KIRKWOOD_H */
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_LOWLEVEL_H__
|
||||
#define __MACH_LOWLEVEL_H__
|
||||
|
||||
void mvebu_barebox_entry(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MACH_MVEBU_H
|
||||
#define __MACH_MVEBU_H
|
||||
|
||||
int mvebu_add_uart0(void);
|
||||
void __naked __noreturn mvebu_barebox_entry(void);
|
||||
|
||||
#endif /* __MACH_MVEBU_H */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <ns16550.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <asm/memory.h>
|
||||
#include <mach/kirkwood-regs.h>
|
||||
|
||||
#define CONSOLE_UART_BASE KIRKWOOD_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
|
||||
|
||||
static struct clk *tclk;
|
||||
|
||||
static inline void kirkwood_memory_find(unsigned long *phys_base,
|
||||
unsigned long *phys_size)
|
||||
{
|
||||
int cs;
|
||||
|
||||
*phys_base = ~0;
|
||||
*phys_size = 0;
|
||||
|
||||
for (cs = 0; cs < 4; cs++) {
|
||||
u32 base = readl(KIRKWOOD_SDRAM_BASE + DDR_BASE_CSn(cs));
|
||||
u32 ctrl = readl(KIRKWOOD_SDRAM_BASE + DDR_SIZE_CSn(cs));
|
||||
|
||||
/* Skip non-enabled CS */
|
||||
if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
|
||||
continue;
|
||||
|
||||
base &= DDR_BASE_CS_LOW_MASK;
|
||||
if (base < *phys_base)
|
||||
*phys_base = base;
|
||||
*phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct NS16550_plat uart_plat = {
|
||||
.shift = 2,
|
||||
};
|
||||
|
||||
static int kirkwood_add_uart(void)
|
||||
{
|
||||
uart_plat.clock = clk_get_rate(tclk);
|
||||
if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
|
||||
(unsigned int)CONSOLE_UART_BASE, 32,
|
||||
IORESOURCE_MEM_32BIT, &uart_plat))
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kirkwood_init_clocks(void)
|
||||
{
|
||||
u32 val = readl(KIRKWOOD_SAR_BASE);
|
||||
unsigned int rate;
|
||||
|
||||
/*
|
||||
* On Kirkwood, the TCLK frequency can be either
|
||||
* 166 Mhz or 200 Mhz
|
||||
*/
|
||||
if ((val & SAR_TCLK_FREQ) == SAR_TCLK_FREQ)
|
||||
rate = 166666667;
|
||||
else
|
||||
rate = 200000000;
|
||||
|
||||
tclk = clk_fixed("tclk", rate);
|
||||
return clk_register_clkdev(tclk, NULL, "orion-timer");
|
||||
}
|
||||
|
||||
static int kirkwood_init_soc(void)
|
||||
{
|
||||
unsigned long phys_base, phys_size;
|
||||
|
||||
kirkwood_init_clocks();
|
||||
add_generic_device("orion-timer", DEVICE_ID_SINGLE, NULL,
|
||||
(unsigned int)KIRKWOOD_TIMER_BASE, 0x30,
|
||||
IORESOURCE_MEM, NULL);
|
||||
kirkwood_memory_find(&phys_base, &phys_size);
|
||||
arm_add_mem_device("ram0", phys_base, phys_size);
|
||||
kirkwood_add_uart();
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(kirkwood_init_soc);
|
||||
|
||||
void __noreturn reset_cpu(unsigned long addr)
|
||||
{
|
||||
writel(SOFT_RESET_OUT_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
|
||||
writel(SOFT_RESET_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
|
||||
for(;;)
|
||||
;
|
||||
}
|
||||
EXPORT_SYMBOL(reset_cpu);
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2013
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <sizes.h>
|
||||
#include <asm/barebox-arm.h>
|
||||
#include <asm/barebox-arm-head.h>
|
||||
#include <mach/lowlevel.h>
|
||||
|
||||
void __naked barebox_arm_reset_vector(void)
|
||||
{
|
||||
arm_cpu_lowlevel_init();
|
||||
mvebu_barebox_entry();
|
||||
}
|
|
@ -14,6 +14,14 @@ config CLOCKSOURCE_CLPS711X
|
|||
bool
|
||||
depends on ARCH_CLPS711X
|
||||
|
||||
config CLOCKSOURCE_MVEBU
|
||||
bool
|
||||
depends on ARCH_MVEBU
|
||||
|
||||
config CLOCKSOURCE_NOMADIK
|
||||
bool
|
||||
depends on ARM
|
||||
|
||||
config CLOCKSOURCE_ORION
|
||||
bool
|
||||
depends on ARCH_MVEBU
|
||||
|
|
|
@ -2,4 +2,6 @@ obj-$(CONFIG_AMBA_SP804) += amba-sp804.o
|
|||
obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_MVEBU) += mvebu.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o
|
||||
obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <clock.h>
|
||||
#include <linux/clk.h>
|
||||
#include <io.h>
|
||||
|
||||
#define TIMER_CTRL_OFF 0x0000
|
||||
#define TIMER0_EN 0x0001
|
||||
#define TIMER0_RELOAD_EN 0x0002
|
||||
#define TIMER0_25MHZ 0x0800
|
||||
#define TIMER0_DIV(div) ((div) << 19)
|
||||
#define TIMER1_EN 0x0004
|
||||
#define TIMER1_RELOAD_EN 0x0008
|
||||
#define TIMER1_25MHZ 0x1000
|
||||
#define TIMER1_DIV(div) ((div) << 22)
|
||||
#define TIMER_EVENTS_STATUS 0x0004
|
||||
#define TIMER0_CLR_MASK (~0x1)
|
||||
#define TIMER1_CLR_MASK (~0x100)
|
||||
#define TIMER0_RELOAD_OFF 0x0010
|
||||
#define TIMER0_VAL_OFF 0x0014
|
||||
#define TIMER1_RELOAD_OFF 0x0018
|
||||
#define TIMER1_VAL_OFF 0x001c
|
||||
|
||||
#define TIMER_DIVIDER_SHIFT 5
|
||||
|
||||
static __iomem void *timer_base;
|
||||
|
||||
uint64_t mvebu_clocksource_read(void)
|
||||
{
|
||||
return __raw_readl(timer_base + TIMER0_VAL_OFF);
|
||||
}
|
||||
|
||||
static struct clocksource cs = {
|
||||
.read = mvebu_clocksource_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 10,
|
||||
};
|
||||
|
||||
static int mvebu_timer_probe(struct device_d *dev)
|
||||
{
|
||||
struct clk *tclk;
|
||||
u32 val;
|
||||
|
||||
timer_base = dev_request_mem_region(dev, 0);
|
||||
|
||||
tclk = clk_get(dev, "tclk");
|
||||
|
||||
val = __raw_readl(timer_base + TIMER_CTRL_OFF);
|
||||
val &= ~TIMER0_25MHZ;
|
||||
__raw_writel(val, timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
__raw_writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
|
||||
__raw_writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
|
||||
|
||||
val = __raw_readl(timer_base + TIMER_CTRL_OFF);
|
||||
val |= TIMER0_EN | TIMER0_RELOAD_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
|
||||
__raw_writel(val, timer_base + TIMER_CTRL_OFF);
|
||||
|
||||
cs.mult = clocksource_hz2mult(clk_get_rate(tclk), cs.shift);
|
||||
|
||||
init_clock(&cs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct driver_d mvebu_timer_driver = {
|
||||
.name = "mvebu-timer",
|
||||
.probe = mvebu_timer_probe,
|
||||
};
|
||||
|
||||
static int mvebu_timer_init(void)
|
||||
{
|
||||
return platform_driver_register(&mvebu_timer_driver);
|
||||
}
|
||||
postcore_initcall(mvebu_timer_init);
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright
|
||||
* (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <clock.h>
|
||||
#include <linux/clk.h>
|
||||
#include <io.h>
|
||||
|
||||
#define TIMER_CTRL 0x00
|
||||
#define TIMER0_EN BIT(0)
|
||||
#define TIMER0_RELOAD_EN BIT(1)
|
||||
#define TIMER1_EN BIT(2)
|
||||
#define TIMER1_RELOAD_EN BIT(3)
|
||||
#define TIMER0_RELOAD 0x10
|
||||
#define TIMER0_VAL 0x14
|
||||
#define TIMER1_RELOAD 0x18
|
||||
#define TIMER1_VAL 0x1c
|
||||
|
||||
static __iomem void *timer_base;
|
||||
|
||||
static uint64_t orion_clocksource_read(void)
|
||||
{
|
||||
return __raw_readl(timer_base + TIMER0_VAL);
|
||||
}
|
||||
|
||||
static struct clocksource clksrc = {
|
||||
.read = orion_clocksource_read,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 10,
|
||||
};
|
||||
|
||||
static int orion_timer_probe(struct device_d *dev)
|
||||
{
|
||||
struct clk *tclk;
|
||||
uint32_t val;
|
||||
|
||||
timer_base = dev_request_mem_region(dev, 0);
|
||||
tclk = clk_get(dev, "tclk");
|
||||
|
||||
/* setup TIMER0 as free-running clock source */
|
||||
__raw_writel(~0, timer_base + TIMER0_VAL);
|
||||
__raw_writel(~0, timer_base + TIMER0_RELOAD);
|
||||
val = __raw_readl(timer_base + TIMER_CTRL);
|
||||
__raw_writel(val | TIMER0_EN | TIMER0_RELOAD_EN,
|
||||
timer_base + TIMER_CTRL);
|
||||
|
||||
clksrc.mult = clocksource_hz2mult(clk_get_rate(tclk), clksrc.shift);
|
||||
init_clock(&clksrc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct driver_d orion_timer_driver = {
|
||||
.name = "orion-timer",
|
||||
.probe = orion_timer_probe,
|
||||
};
|
||||
|
||||
static int orion_timer_init(void)
|
||||
{
|
||||
return platform_driver_register(&orion_timer_driver);
|
||||
}
|
||||
postcore_initcall(orion_timer_init);
|
|
@ -2,6 +2,8 @@ bareboxenv
|
|||
bin2c
|
||||
gen_netx_image
|
||||
kallsyms
|
||||
kwbimage
|
||||
kwboot
|
||||
mk-am35xx-spi-image
|
||||
mkimage
|
||||
mkublheader
|
||||
|
|
|
@ -8,6 +8,7 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms
|
|||
hostprogs-y += bin2c
|
||||
hostprogs-y += mkimage
|
||||
hostprogs-y += bareboxenv
|
||||
hostprogs-$(CONFIG_ARCH_MVEBU) += kwbimage kwboot
|
||||
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
|
||||
hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-am35xx-spi-image
|
||||
hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
* Boot a Marvell SoC, with Xmodem over UART0.
|
||||
* supports Kirkwood, Dove, Armada 370, Armada XP
|
||||
*
|
||||
* (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
|
||||
*
|
||||
* References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
|
||||
* Integrated Controller: Functional Specifications" December 2,
|
||||
* 2008. Chapter 24.2 "BootROM Firmware".
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <libgen.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <termios.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
* Marvell BootROM UART Sensing
|
||||
*/
|
||||
|
||||
static unsigned char kwboot_msg_boot[] = {
|
||||
0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
|
||||
};
|
||||
|
||||
static unsigned char kwboot_msg_debug[] = {
|
||||
0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
|
||||
};
|
||||
|
||||
#define KWBOOT_MSG_REQ_DELAY 1000 /* ms */
|
||||
#define KWBOOT_MSG_RSP_TIMEO 1000 /* ms */
|
||||
|
||||
/*
|
||||
* Xmodem Transfers
|
||||
*/
|
||||
|
||||
#define SOH 1 /* sender start of block header */
|
||||
#define EOT 4 /* sender end of block transfer */
|
||||
#define ACK 6 /* target block ack */
|
||||
#define NAK 21 /* target block negative ack */
|
||||
#define CAN 24 /* target/sender transfer cancellation */
|
||||
|
||||
struct kwboot_block {
|
||||
uint8_t soh;
|
||||
uint8_t pnum;
|
||||
uint8_t _pnum;
|
||||
uint8_t data[128];
|
||||
uint8_t csum;
|
||||
} __attribute((packed));
|
||||
|
||||
#define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
|
||||
|
||||
static int kwboot_verbose;
|
||||
|
||||
static void
|
||||
kwboot_printv(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (kwboot_verbose) {
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__spinner(void)
|
||||
{
|
||||
const char seq[] = { '-', '\\', '|', '/' };
|
||||
const int div = 8;
|
||||
static int state, bs;
|
||||
|
||||
if (state % div == 0) {
|
||||
fputc(bs, stdout);
|
||||
fputc(seq[state / div % sizeof(seq)], stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
bs = '\b';
|
||||
state++;
|
||||
}
|
||||
|
||||
static void
|
||||
kwboot_spinner(void)
|
||||
{
|
||||
if (kwboot_verbose)
|
||||
__spinner();
|
||||
}
|
||||
|
||||
static void
|
||||
__progress(int pct, char c)
|
||||
{
|
||||
const int width = 70;
|
||||
static const char *nl = "";
|
||||
static int pos;
|
||||
|
||||
if (pos % width == 0)
|
||||
printf("%s%3d %% [", nl, pct);
|
||||
|
||||
fputc(c, stdout);
|
||||
|
||||
nl = "]\n";
|
||||
pos++;
|
||||
|
||||
if (pct == 100) {
|
||||
while (pos++ < width)
|
||||
fputc(' ', stdout);
|
||||
fputs(nl, stdout);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
kwboot_progress(int _pct, char c)
|
||||
{
|
||||
static int pct;
|
||||
|
||||
if (_pct != -1)
|
||||
pct = _pct;
|
||||
|
||||
if (kwboot_verbose)
|
||||
__progress(pct, c);
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
|
||||
{
|
||||
int rc, nfds;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
ssize_t n;
|
||||
|
||||
rc = -1;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = timeo * 1000;
|
||||
if (tv.tv_usec > 1000000) {
|
||||
tv.tv_sec += tv.tv_usec / 1000000;
|
||||
tv.tv_usec %= 1000000;
|
||||
}
|
||||
|
||||
do {
|
||||
nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
|
||||
if (nfds < 0)
|
||||
goto out;
|
||||
if (!nfds) {
|
||||
errno = ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
n = read(fd, buf, len);
|
||||
if (n < 0)
|
||||
goto out;
|
||||
|
||||
buf = (char *)buf + n;
|
||||
len -= n;
|
||||
} while (len > 0);
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_tty_send(int fd, const void *buf, size_t len)
|
||||
{
|
||||
int rc;
|
||||
ssize_t n;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
rc = -1;
|
||||
|
||||
do {
|
||||
n = write(fd, buf, len);
|
||||
if (n < 0)
|
||||
goto out;
|
||||
|
||||
buf = (char *)buf + n;
|
||||
len -= n;
|
||||
} while (len > 0);
|
||||
|
||||
rc = tcdrain(fd);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_tty_send_char(int fd, unsigned char c)
|
||||
{
|
||||
return kwboot_tty_send(fd, &c, 1);
|
||||
}
|
||||
|
||||
static speed_t
|
||||
kwboot_tty_speed(int baudrate)
|
||||
{
|
||||
switch (baudrate) {
|
||||
case 115200:
|
||||
return B115200;
|
||||
case 57600:
|
||||
return B57600;
|
||||
case 38400:
|
||||
return B38400;
|
||||
case 19200:
|
||||
return B19200;
|
||||
case 9600:
|
||||
return B9600;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_open_tty(const char *path, speed_t speed)
|
||||
{
|
||||
int rc, fd;
|
||||
struct termios tio;
|
||||
|
||||
rc = -1;
|
||||
|
||||
fd = open(path, O_RDWR|O_NOCTTY|O_NDELAY);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
|
||||
memset(&tio, 0, sizeof(tio));
|
||||
|
||||
tio.c_iflag = 0;
|
||||
tio.c_cflag = CREAD|CLOCAL|CS8;
|
||||
|
||||
tio.c_cc[VMIN] = 1;
|
||||
tio.c_cc[VTIME] = 10;
|
||||
|
||||
cfsetospeed(&tio, speed);
|
||||
cfsetispeed(&tio, speed);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &tio);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = fd;
|
||||
out:
|
||||
if (rc < 0) {
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_bootmsg(int tty, void *msg)
|
||||
{
|
||||
int rc;
|
||||
char c;
|
||||
|
||||
if (msg == NULL)
|
||||
kwboot_printv("Please reboot the target into UART boot mode...");
|
||||
else
|
||||
kwboot_printv("Sending boot message. Please reboot the target...");
|
||||
|
||||
do {
|
||||
rc = tcflush(tty, TCIOFLUSH);
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
rc = kwboot_tty_send(tty, msg, 8);
|
||||
if (rc) {
|
||||
usleep(KWBOOT_MSG_REQ_DELAY * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO);
|
||||
|
||||
kwboot_spinner();
|
||||
|
||||
} while (rc || c != NAK);
|
||||
|
||||
kwboot_printv("\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_debugmsg(int tty, void *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
kwboot_printv("Sending debug message. Please reboot the target...");
|
||||
|
||||
do {
|
||||
char buf[16];
|
||||
|
||||
rc = tcflush(tty, TCIOFLUSH);
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
rc = kwboot_tty_send(tty, msg, 8);
|
||||
if (rc) {
|
||||
usleep(KWBOOT_MSG_REQ_DELAY * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = kwboot_tty_recv(tty, buf, 16, KWBOOT_MSG_RSP_TIMEO);
|
||||
|
||||
kwboot_spinner();
|
||||
|
||||
} while (rc);
|
||||
|
||||
kwboot_printv("\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
|
||||
size_t size, int pnum)
|
||||
{
|
||||
const size_t blksz = sizeof(block->data);
|
||||
size_t n;
|
||||
int i;
|
||||
|
||||
block->pnum = pnum;
|
||||
block->_pnum = ~block->pnum;
|
||||
|
||||
n = size < blksz ? size : blksz;
|
||||
memcpy(&block->data[0], data, n);
|
||||
memset(&block->data[n], 0, blksz - n);
|
||||
|
||||
block->csum = 0;
|
||||
for (i = 0; i < n; i++)
|
||||
block->csum += block->data[i];
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_xm_sendblock(int fd, struct kwboot_block *block)
|
||||
{
|
||||
int rc, retries;
|
||||
char c;
|
||||
|
||||
retries = 16;
|
||||
do {
|
||||
rc = kwboot_tty_send(fd, block, sizeof(*block));
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
do {
|
||||
rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
|
||||
if (rc)
|
||||
break;
|
||||
|
||||
if (c != ACK && c!= NAK && c != CAN)
|
||||
printf("%c", c);
|
||||
|
||||
} while (c != ACK && c != NAK && c != CAN);
|
||||
|
||||
if (c != ACK)
|
||||
kwboot_progress(-1, '+');
|
||||
|
||||
} while (c == NAK && retries-- > 0);
|
||||
|
||||
rc = -1;
|
||||
|
||||
switch (c) {
|
||||
case ACK:
|
||||
rc = 0;
|
||||
break;
|
||||
case NAK:
|
||||
errno = EBADMSG;
|
||||
break;
|
||||
case CAN:
|
||||
errno = ECANCELED;
|
||||
break;
|
||||
default:
|
||||
errno = EPROTO;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_xmodem(int tty, const void *_data, size_t size)
|
||||
{
|
||||
const uint8_t *data = _data;
|
||||
int rc, pnum, N, err;
|
||||
|
||||
pnum = 1;
|
||||
N = 0;
|
||||
|
||||
kwboot_printv("Sending boot image...\n");
|
||||
|
||||
do {
|
||||
struct kwboot_block block;
|
||||
int n;
|
||||
|
||||
n = kwboot_xm_makeblock(&block,
|
||||
data + N, size - N,
|
||||
pnum++);
|
||||
if (n < 0)
|
||||
goto can;
|
||||
|
||||
if (!n)
|
||||
break;
|
||||
|
||||
rc = kwboot_xm_sendblock(tty, &block);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
N += n;
|
||||
kwboot_progress(N * 100 / size, '.');
|
||||
} while (1);
|
||||
|
||||
rc = kwboot_tty_send_char(tty, EOT);
|
||||
|
||||
out:
|
||||
return rc;
|
||||
|
||||
can:
|
||||
err = errno;
|
||||
kwboot_tty_send_char(tty, CAN);
|
||||
errno = err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_term_pipe(int in, int out, char *quit, int *s)
|
||||
{
|
||||
ssize_t nin, nout;
|
||||
char _buf[128], *buf = _buf;
|
||||
|
||||
nin = read(in, buf, sizeof(buf));
|
||||
if (nin < 0)
|
||||
return -1;
|
||||
|
||||
if (quit) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nin; i++) {
|
||||
if (*buf == quit[*s]) {
|
||||
(*s)++;
|
||||
if (!quit[*s])
|
||||
return 0;
|
||||
buf++;
|
||||
nin--;
|
||||
} else
|
||||
while (*s > 0) {
|
||||
nout = write(out, quit, *s);
|
||||
if (nout <= 0)
|
||||
return -1;
|
||||
(*s) -= nout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (nin > 0) {
|
||||
nout = write(out, buf, nin);
|
||||
if (nout <= 0)
|
||||
return -1;
|
||||
nin -= nout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kwboot_terminal(int tty)
|
||||
{
|
||||
int rc, in, s;
|
||||
char *quit = "\34c";
|
||||
struct termios otio, tio;
|
||||
|
||||
rc = -1;
|
||||
|
||||
in = STDIN_FILENO;
|
||||
if (isatty(in)) {
|
||||
rc = tcgetattr(in, &otio);
|
||||
if (!rc) {
|
||||
tio = otio;
|
||||
cfmakeraw(&tio);
|
||||
rc = tcsetattr(in, TCSANOW, &tio);
|
||||
}
|
||||
if (rc) {
|
||||
perror("tcsetattr");
|
||||
goto out;
|
||||
}
|
||||
|
||||
kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
|
||||
quit[0]|0100, quit[1]);
|
||||
} else
|
||||
in = -1;
|
||||
|
||||
rc = 0;
|
||||
s = 0;
|
||||
|
||||
do {
|
||||
fd_set rfds;
|
||||
int nfds = 0;
|
||||
|
||||
FD_SET(tty, &rfds);
|
||||
nfds = nfds < tty ? tty : nfds;
|
||||
|
||||
if (in >= 0) {
|
||||
FD_SET(in, &rfds);
|
||||
nfds = nfds < in ? in : nfds;
|
||||
}
|
||||
|
||||
nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
|
||||
if (nfds < 0)
|
||||
break;
|
||||
|
||||
if (FD_ISSET(tty, &rfds)) {
|
||||
rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(in, &rfds)) {
|
||||
rc = kwboot_term_pipe(in, tty, quit, &s);
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
} while (quit[s] != 0);
|
||||
|
||||
tcsetattr(in, TCSANOW, &otio);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void *
|
||||
kwboot_mmap_image(const char *path, size_t *size, int prot)
|
||||
{
|
||||
int rc, fd, flags;
|
||||
struct stat st;
|
||||
void *img;
|
||||
|
||||
rc = -1;
|
||||
fd = -1;
|
||||
img = NULL;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
goto out;
|
||||
|
||||
rc = fstat(fd, &st);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED;
|
||||
|
||||
img = mmap(NULL, st.st_size, prot, flags, fd, 0);
|
||||
if (img == MAP_FAILED) {
|
||||
img = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
*size = st.st_size;
|
||||
out:
|
||||
if (rc && img) {
|
||||
munmap(img, st.st_size);
|
||||
img = NULL;
|
||||
}
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
static void
|
||||
kwboot_usage(FILE *stream, char *progname)
|
||||
{
|
||||
fprintf(stream,
|
||||
"Usage: %s [-d | -b <image> | -D <image> ] [ -t ] [-B <baud> ] <TTY>\n",
|
||||
progname);
|
||||
fprintf(stream, "\n");
|
||||
fprintf(stream,
|
||||
" -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
|
||||
fprintf(stream,
|
||||
" -D <image>: boot <image> without preamble (Dove)\n");
|
||||
fprintf(stream, " -d: enter debug mode\n");
|
||||
fprintf(stream, "\n");
|
||||
fprintf(stream, " -t: mini terminal\n");
|
||||
fprintf(stream, "\n");
|
||||
fprintf(stream, " -B <baud>: set baud rate\n");
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *ttypath, *imgpath;
|
||||
int rv, rc, tty, term;
|
||||
void *bootmsg;
|
||||
void *debugmsg;
|
||||
void *img;
|
||||
size_t size;
|
||||
speed_t speed;
|
||||
|
||||
rv = 1;
|
||||
tty = -1;
|
||||
bootmsg = NULL;
|
||||
debugmsg = NULL;
|
||||
imgpath = NULL;
|
||||
img = NULL;
|
||||
term = 0;
|
||||
size = 0;
|
||||
speed = B115200;
|
||||
|
||||
kwboot_verbose = isatty(STDOUT_FILENO);
|
||||
|
||||
do {
|
||||
int c = getopt(argc, argv, "hb:dtB:D:");
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'b':
|
||||
bootmsg = kwboot_msg_boot;
|
||||
imgpath = optarg;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
bootmsg = NULL;
|
||||
imgpath = optarg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
debugmsg = kwboot_msg_debug;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
term = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
speed = kwboot_tty_speed(atoi(optarg));
|
||||
if (speed == -1)
|
||||
goto usage;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
rv = 0;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (!bootmsg && !term && !debugmsg)
|
||||
goto usage;
|
||||
|
||||
if (argc - optind < 1)
|
||||
goto usage;
|
||||
|
||||
ttypath = argv[optind++];
|
||||
|
||||
tty = kwboot_open_tty(ttypath, speed);
|
||||
if (tty < 0) {
|
||||
perror(ttypath);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (imgpath) {
|
||||
img = kwboot_mmap_image(imgpath, &size, PROT_READ);
|
||||
if (!img) {
|
||||
perror(imgpath);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (debugmsg) {
|
||||
rc = kwboot_debugmsg(tty, debugmsg);
|
||||
if (rc) {
|
||||
perror("debugmsg");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
rc = kwboot_bootmsg(tty, bootmsg);
|
||||
if (rc) {
|
||||
perror("bootmsg");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (img) {
|
||||
rc = kwboot_xmodem(tty, img, size);
|
||||
if (rc) {
|
||||
perror("xmodem");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (term) {
|
||||
rc = kwboot_terminal(tty);
|
||||
if (rc && !(errno == EINTR)) {
|
||||
perror("terminal");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
out:
|
||||
if (tty >= 0)
|
||||
close(tty);
|
||||
|
||||
if (img)
|
||||
munmap(img, size);
|
||||
|
||||
return rv;
|
||||
|
||||
usage:
|
||||
kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
|
||||
goto out;
|
||||
}
|
Loading…
Reference in New Issue