9
0
Fork 0

Merge branch 'for-next/marvell'

Conflicts:
	arch/arm/Makefile
This commit is contained in:
Sascha Hauer 2013-06-02 12:37:01 +02:00
commit 89fd7e44db
54 changed files with 3581 additions and 1 deletions

2
.gitignore vendored
View File

@ -39,6 +39,8 @@ barebox.ubl
barebox.zynq
barebox.uimage
barebox.map
barebox.kwb
barebox.kwbuart
barebox-flash-image
System.map
Module.symvers

View File

@ -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

View File

@ -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

View File

@ -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) $@

View File

@ -0,0 +1 @@
obj-y += board.o

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#endif /* __CONFIG_H */

View File

@ -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

View File

@ -0,0 +1 @@
obj-y += board.c

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#endif /* __CONFIG_H */

View File

@ -0,0 +1,5 @@
VERSION 1
BOOT_FROM nand
NAND_BLKSZ 00020000
NAND_BADBLK_LOCATION 01
BINARY globalscale-mirabox-binary.0 0000005b 00000068

View File

@ -0,0 +1 @@
obj-y += board.o

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#endif /* __CONFIG_H */

View File

@ -0,0 +1,3 @@
VERSION 1
BOOT_FROM spi
BINARY marvell-armada-xp-gp-binary.0 0000005b 00000068

View File

@ -0,0 +1 @@
obj-y += board.o

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#endif /* __CONFIG_H */

View File

@ -0,0 +1,3 @@
VERSION 1
BOOT_FROM spi
BINARY plathome-openblocks-ax3-binary.0 0000005b 00000068

View File

@ -0,0 +1 @@
obj-y += board.c

View File

@ -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 */

View File

@ -0,0 +1,4 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#endif /* __CONFIG_H */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

124
arch/arm/mach-mvebu/Kconfig Normal file
View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);
}

145
arch/arm/mach-mvebu/dove.c Normal file
View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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
scripts/.gitignore vendored
View File

@ -2,6 +2,8 @@ bareboxenv
bin2c
gen_netx_image
kallsyms
kwbimage
kwboot
mk-am35xx-spi-image
mkimage
mkublheader

View File

@ -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

1496
scripts/kwbimage.c Normal file

File diff suppressed because it is too large Load Diff

730
scripts/kwboot.c Normal file
View File

@ -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;
}