summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-09-26 11:39:23 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-09-26 14:07:14 +0200
commit0a2070b8fe51c93d640c96b29f09adcb001ecd77 (patch)
tree79ff8816487687d4dd9a82bcba21d0271d9b2e72 /arch/arm/boards
parent458fb8e646e72b33204f6669cb63880ed4629f94 (diff)
downloadbarebox-0a2070b8fe51c93d640c96b29f09adcb001ecd77.tar.gz
barebox-0a2070b8fe51c93d640c96b29f09adcb001ecd77.tar.xz
ARM: AM33xx: Add AFI GF board support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/boards')
-rw-r--r--arch/arm/boards/Makefile1
-rw-r--r--arch/arm/boards/afi-gf/Makefile3
-rw-r--r--arch/arm/boards/afi-gf/board.c50
-rw-r--r--arch/arm/boards/afi-gf/config.h22
-rw-r--r--arch/arm/boards/afi-gf/defaultenv-gf/boot/sd11
-rw-r--r--arch/arm/boards/afi-gf/defaultenv-gf/init/automount15
-rw-r--r--arch/arm/boards/afi-gf/defaultenv-gf/network/eth118
-rw-r--r--arch/arm/boards/afi-gf/lowlevel.c266
8 files changed, 386 insertions, 0 deletions
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index 122f5cde5e..ebc5f7d5df 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -1,4 +1,5 @@
# keep sorted by CONFIG_* macro name.
+obj-$(CONFIG_MACH_AFI_GF) += afi-gf/
obj-$(CONFIG_MACH_ANIMEO_IP) += animeo_ip/
obj-$(CONFIG_MACH_ARCHOSG9) += archosg9/
obj-$(CONFIG_MACH_AT91SAM9260EK) += at91sam9260ek/
diff --git a/arch/arm/boards/afi-gf/Makefile b/arch/arm/boards/afi-gf/Makefile
new file mode 100644
index 0000000000..399a4b8cc0
--- /dev/null
+++ b/arch/arm/boards/afi-gf/Makefile
@@ -0,0 +1,3 @@
+lwl-y += lowlevel.o
+obj-y += board.o
+bbenv-y += defaultenv-gf
diff --git a/arch/arm/boards/afi-gf/board.c b/arch/arm/boards/afi-gf/board.c
new file mode 100644
index 0000000000..dfcb579f24
--- /dev/null
+++ b/arch/arm/boards/afi-gf/board.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <string.h>
+#include <init.h>
+#include <sizes.h>
+#include <envfs.h>
+#include <bootsource.h>
+#include <asm/armlinux.h>
+#include <mach/bbu.h>
+#include <mach/am33xx-generic.h>
+
+static int board_console_init(void)
+{
+ if (!of_machine_is_compatible("afi,gf"))
+ return 0;
+
+ switch (bootsource_get()) {
+ default:
+ case BOOTSOURCE_SPI:
+ of_device_enable_path("/chosen/environment-spi");
+ break;
+ case BOOTSOURCE_MMC:
+ omap_set_bootmmc_devname("mmc0");
+ break;
+ }
+
+ defaultenv_append_directory(defaultenv_gf);
+ am33xx_register_ethaddr(0, 0);
+ am33xx_register_ethaddr(1, 1);
+ barebox_set_hostname("gf");
+ am33xx_bbu_spi_nor_mlo_register_handler("MLO.spi", "/dev/m25p0.mlo");
+ am33xx_bbu_spi_nor_register_handler("spi", "/dev/m25p0.boot");
+
+ return 0;
+}
+coredevice_initcall(board_console_init);
diff --git a/arch/arm/boards/afi-gf/config.h b/arch/arm/boards/afi-gf/config.h
new file mode 100644
index 0000000000..aeeda3695b
--- /dev/null
+++ b/arch/arm/boards/afi-gf/config.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd b/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd
new file mode 100644
index 0000000000..dce060542a
--- /dev/null
+++ b/arch/arm/boards/afi-gf/defaultenv-gf/boot/sd
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+if [ "$1" = menu ]; then
+ boot-menu-add-entry "$0" "kernel & rootfs on SD card"
+ exit
+fi
+
+global.bootm.image=/boot/uImage
+global.bootm.oftree=/boot/oftree
+#global.bootm.initrd=<path to initrd>
+global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
diff --git a/arch/arm/boards/afi-gf/defaultenv-gf/init/automount b/arch/arm/boards/afi-gf/defaultenv-gf/init/automount
new file mode 100644
index 0000000000..c67bd1ba50
--- /dev/null
+++ b/arch/arm/boards/afi-gf/defaultenv-gf/init/automount
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+if [ "$1" = menu ]; then
+ init-menu-add-entry "$0" "Automountpoints"
+ exit
+fi
+
+# automount tftp server based on $eth1.serverip
+
+mkdir -p /mnt/tftp
+automount /mnt/tftp 'ifup eth1 && mount -t tftp $eth1.serverip /mnt/tftp'
+
+# eth0 is on the mezzanine board
+mkdir -p /mnt/tftp-eth0
+automount /mnt/tftp-eth0 'ifup eth0 && mount -t tftp $eth0.serverip /mnt/tftp'
diff --git a/arch/arm/boards/afi-gf/defaultenv-gf/network/eth1 b/arch/arm/boards/afi-gf/defaultenv-gf/network/eth1
new file mode 100644
index 0000000000..1ed3017e96
--- /dev/null
+++ b/arch/arm/boards/afi-gf/defaultenv-gf/network/eth1
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# ip setting (static/dhcp)
+ip=dhcp
+global.dhcp.vendor_id=barebox-${global.hostname}
+
+# static setup used if ip=static
+ipaddr=
+netmask=
+gateway=
+serverip=
+
+# MAC address if needed
+#ethaddr=xx:xx:xx:xx:xx:xx
+
+# put code to discover eth1 (i.e. 'usb') to /env/network/eth0-discover
+
+exit 0
diff --git a/arch/arm/boards/afi-gf/lowlevel.c b/arch/arm/boards/afi-gf/lowlevel.c
new file mode 100644
index 0000000000..fdc340c057
--- /dev/null
+++ b/arch/arm/boards/afi-gf/lowlevel.c
@@ -0,0 +1,266 @@
+#include <init.h>
+#include <sizes.h>
+#include <io.h>
+#include <asm/armlinux.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <linux/bitops.h>
+#include <mach/am33xx-generic.h>
+#include <mach/am33xx-silicon.h>
+#include <mach/am33xx-clock.h>
+#include <mach/sdrc.h>
+#include <mach/sys_info.h>
+#include <mach/syslib.h>
+#include <mach/am33xx-mux.h>
+#include <mach/wdt.h>
+#include <debug_ll.h>
+
+/* AM335X EMIF Register values */
+#define VTP_CTRL_READY (0x1 << 5)
+#define VTP_CTRL_ENABLE (0x1 << 6)
+#define VTP_CTRL_LOCK_EN (0x1 << 4)
+#define VTP_CTRL_START_EN (0x1)
+#define DDR2_RATIO 0x80 /* for mDDR */ //
+#define CMD_FORCE 0x00 /* common #def */
+#define CMD_DELAY 0x00
+
+#define EMIF_READ_LATENCY 0x05 // (CL + 2 - 1)
+#define EMIF_TIM1 0x04447289 //
+#define EMIF_TIM2 0x10160580 //
+#define EMIF_TIM3 0x000000E7 // check tREFI
+#define EMIF_SDCFG 0x0 \
+ | (1 << 29) /* reg_sdram_type = 1 (LPDDR1) */ \
+ | (0 << 27) /* reg_ibank_pos = 0 */ \
+ | (0 << 24) /* reg_ddr_term = 0? */ \
+ | (0 << 23) /* reg_ddr2_ddqs = 0 (single ended DQS for LPDDR) */ \
+ | (0 << 21) /* reg_dyn_odt = 0 (only used for DDR3) */ \
+ | (0 << 20) /* reg_ddr_disable_dll = 0 */ \
+ | (1 << 18) /* reg_sdram_drive = 1? (1/2 for LPDDR) */ \
+ | (0 << 16) /* reg_cwl = 0 (only for DDR3) */ \
+ | (1 << 14) /* reg_narrow_mode = 1 (AM335x is always 16 bit) */ \
+ | (3 << 10) /* reg_cl = 3 */ \
+ | (5 << 7) /* reg_rowsize = 5 (unused?, 14 row bits) */ \
+ | (2 << 4) /* reg_ibank = 2 (4 banks) */ \
+ | (0 << 3) /* reg_ebank = 0 */ \
+ | (3 << 0) /* reg_pagesize = 3? (11 column bits = 2048 words) */
+#define EMIF_SDREF 0x00000618 //
+#define DDR2_DLL_LOCK_DIFF 0x0
+#define DDR2_RD_DQS 0x40 //
+#define DDR2_WR_DQS 0x2 //
+#define DDR2_PHY_WRLVL 0x00
+#define DDR2_PHY_GATELVL 0x00
+#define DDR2_PHY_FIFO_WE 0x110 //
+#define DDR2_PHY_WR_DATA 0x40 //
+
+#define DDR2_INVERT_CLKOUT 0x0 //
+#define PHY_RANK0_DELAY 0x1 //
+#define PHY_DLL_LOCK_DIFF 0x0
+#define DDR_IOCTRL_VALUE 0x18B //
+
+static void board_data_macro_config(int dataMacroNum)
+{
+ u32 BaseAddrOffset = 0x00;
+
+ if (dataMacroNum == 1)
+ BaseAddrOffset = 0xA4;
+
+ __raw_writel(((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
+ |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)),
+ (AM33XX_DATA0_RD_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_RD_DQS>>2,
+ (AM33XX_DATA0_RD_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
+ __raw_writel(((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
+ |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)),
+ (AM33XX_DATA0_WR_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_WR_DQS>>2,
+ (AM33XX_DATA0_WR_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
+ __raw_writel(((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
+ |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)),
+ (AM33XX_DATA0_WRLVL_INIT_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_PHY_WRLVL>>2,
+ (AM33XX_DATA0_WRLVL_INIT_RATIO_1 + BaseAddrOffset));
+ __raw_writel(((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
+ |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)),
+ (AM33XX_DATA0_GATELVL_INIT_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_PHY_GATELVL>>2,
+ (AM33XX_DATA0_GATELVL_INIT_RATIO_1 + BaseAddrOffset));
+ __raw_writel(((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
+ |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)),
+ (AM33XX_DATA0_FIFO_WE_SLAVE_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_PHY_FIFO_WE>>2,
+ (AM33XX_DATA0_FIFO_WE_SLAVE_RATIO_1 + BaseAddrOffset));
+ __raw_writel(((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
+ |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)),
+ (AM33XX_DATA0_WR_DATA_SLAVE_RATIO_0 + BaseAddrOffset));
+ __raw_writel(DDR2_PHY_WR_DATA>>2,
+ (AM33XX_DATA0_WR_DATA_SLAVE_RATIO_1 + BaseAddrOffset));
+ __raw_writel(PHY_DLL_LOCK_DIFF,
+ (AM33XX_DATA0_DLL_LOCK_DIFF_0 + BaseAddrOffset));
+}
+
+static void board_cmd_macro_config(void)
+{
+ __raw_writel(DDR2_RATIO, AM33XX_CMD0_CTRL_SLAVE_RATIO_0);
+ __raw_writel(CMD_FORCE, AM33XX_CMD0_CTRL_SLAVE_FORCE_0);
+ __raw_writel(CMD_DELAY, AM33XX_CMD0_CTRL_SLAVE_DELAY_0);
+ __raw_writel(DDR2_DLL_LOCK_DIFF, AM33XX_CMD0_DLL_LOCK_DIFF_0);
+ __raw_writel(DDR2_INVERT_CLKOUT, AM33XX_CMD0_INVERT_CLKOUT_0);
+
+ __raw_writel(DDR2_RATIO, AM33XX_CMD1_CTRL_SLAVE_RATIO_0);
+ __raw_writel(CMD_FORCE, AM33XX_CMD1_CTRL_SLAVE_FORCE_0);
+ __raw_writel(CMD_DELAY, AM33XX_CMD1_CTRL_SLAVE_DELAY_0);
+ __raw_writel(DDR2_DLL_LOCK_DIFF, AM33XX_CMD1_DLL_LOCK_DIFF_0);
+ __raw_writel(DDR2_INVERT_CLKOUT, AM33XX_CMD1_INVERT_CLKOUT_0);
+
+ __raw_writel(DDR2_RATIO, AM33XX_CMD2_CTRL_SLAVE_RATIO_0);
+ __raw_writel(CMD_FORCE, AM33XX_CMD2_CTRL_SLAVE_FORCE_0);
+ __raw_writel(CMD_DELAY, AM33XX_CMD2_CTRL_SLAVE_DELAY_0);
+ __raw_writel(DDR2_DLL_LOCK_DIFF, AM33XX_CMD2_DLL_LOCK_DIFF_0);
+ __raw_writel(DDR2_INVERT_CLKOUT, AM33XX_CMD2_INVERT_CLKOUT_0);
+}
+
+static void board_config_vtp(void)
+{
+ __raw_writel(__raw_readl(AM33XX_VTP0_CTRL_REG) | VTP_CTRL_ENABLE,
+ AM33XX_VTP0_CTRL_REG);
+ __raw_writel(__raw_readl(AM33XX_VTP0_CTRL_REG) & (~VTP_CTRL_START_EN),
+ AM33XX_VTP0_CTRL_REG);
+ __raw_writel(__raw_readl(AM33XX_VTP0_CTRL_REG) | VTP_CTRL_START_EN,
+ AM33XX_VTP0_CTRL_REG);
+
+ /* Poll for READY */
+ while ((__raw_readl(AM33XX_VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
+}
+
+static void board_config_emif_ddr(void)
+{
+ u32 i;
+
+ /*Program EMIF0 CFG Registers*/
+ __raw_writel(EMIF_READ_LATENCY, AM33XX_EMIF4_0_REG(DDR_PHY_CTRL_1));
+ __raw_writel(EMIF_READ_LATENCY, AM33XX_EMIF4_0_REG(DDR_PHY_CTRL_1_SHADOW));
+ __raw_writel(EMIF_READ_LATENCY, AM33XX_EMIF4_0_REG(DDR_PHY_CTRL_2));
+ __raw_writel(EMIF_TIM1, AM33XX_EMIF4_0_REG(SDRAM_TIM_1));
+ __raw_writel(EMIF_TIM1, AM33XX_EMIF4_0_REG(SDRAM_TIM_1_SHADOW));
+ __raw_writel(EMIF_TIM2, AM33XX_EMIF4_0_REG(SDRAM_TIM_2));
+ __raw_writel(EMIF_TIM2, AM33XX_EMIF4_0_REG(SDRAM_TIM_2_SHADOW));
+ __raw_writel(EMIF_TIM3, AM33XX_EMIF4_0_REG(SDRAM_TIM_3));
+ __raw_writel(EMIF_TIM3, AM33XX_EMIF4_0_REG(SDRAM_TIM_3_SHADOW));
+
+ __raw_writel(EMIF_SDCFG, AM33XX_EMIF4_0_REG(SDRAM_CONFIG));
+ __raw_writel(EMIF_SDCFG, AM33XX_EMIF4_0_REG(SDRAM_CONFIG2));
+
+ __raw_writel(0x00004650, AM33XX_EMIF4_0_REG(SDRAM_REF_CTRL));
+ __raw_writel(0x00004650, AM33XX_EMIF4_0_REG(SDRAM_REF_CTRL_SHADOW));
+
+ for (i = 0; i < 5000; i++) {
+
+ }
+
+ __raw_writel(EMIF_SDREF, AM33XX_EMIF4_0_REG(SDRAM_REF_CTRL));
+ __raw_writel(EMIF_SDREF, AM33XX_EMIF4_0_REG(SDRAM_REF_CTRL_SHADOW));
+
+ __raw_writel(EMIF_SDCFG, AM33XX_EMIF4_0_REG(SDRAM_CONFIG));
+ __raw_writel(EMIF_SDCFG, AM33XX_EMIF4_0_REG(SDRAM_CONFIG2));
+}
+
+static void board_config_ddr(void)
+{
+ am33xx_enable_ddr_clocks();
+
+ board_config_vtp();
+
+ board_cmd_macro_config();
+ board_data_macro_config(0);
+ board_data_macro_config(1);
+
+ __raw_writel(PHY_RANK0_DELAY, AM33XX_DATA0_RANK0_DELAYS_0);
+ __raw_writel(PHY_RANK0_DELAY, AM33XX_DATA1_RANK0_DELAYS_0);
+
+ __raw_writel(DDR_IOCTRL_VALUE, AM33XX_DDR_CMD0_IOCTRL);
+ __raw_writel(DDR_IOCTRL_VALUE, AM33XX_DDR_CMD1_IOCTRL);
+ __raw_writel(DDR_IOCTRL_VALUE, AM33XX_DDR_CMD2_IOCTRL);
+ __raw_writel(DDR_IOCTRL_VALUE, AM33XX_DDR_DATA0_IOCTRL);
+ __raw_writel(DDR_IOCTRL_VALUE, AM33XX_DDR_DATA1_IOCTRL);
+
+ __raw_writel(__raw_readl(AM33XX_DDR_IO_CTRL) | BIT(28), AM33XX_DDR_IO_CTRL);
+ __raw_writel(__raw_readl(AM33XX_DDR_CKE_CTRL) | BIT(0), AM33XX_DDR_CKE_CTRL);
+
+ board_config_emif_ddr();
+}
+
+static const struct module_pin_mux board_can_pin_mux[] = {
+ {OFFSET(mii1_txd3), (MODE(1) | PULLUP_EN)}, /* dcan0_tx_mux0 */
+ {OFFSET(mii1_txd2), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* dcan0_rx_mux0 */
+ {OFFSET(mcasp0_aclkr), (MODE(7) | PULLUP_EN)}, /* gpio3[18] / DCAN0_LBK */
+ {-1},
+};
+
+extern char __dtb_am335x_afi_gf_start[];
+
+/**
+ * @brief The basic entry point for board initialization.
+ *
+ * This is called as part of machine init (after arch init).
+ * This is again called with stack in SRAM, so not too many
+ * constructs possible here.
+ *
+ * @return void
+ */
+static noinline int gf_sram_init(void)
+{
+ void *fdt;
+
+ fdt = __dtb_am335x_afi_gf_start;
+
+ /* WDT1 is already running when the bootloader gets control
+ * Disable it to avoid "random" resets
+ */
+ __raw_writel(WDT_DISABLE_CODE1, AM33XX_WDT_REG(WSPR));
+ while(__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0);
+ __raw_writel(WDT_DISABLE_CODE2, AM33XX_WDT_REG(WSPR));
+ while(__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0);
+
+ /* Setup the PLLs and the clocks for the peripherals */
+ am33xx_pll_init(MPUPLL_M_500, 24, DDRPLL_M_200);
+
+ board_config_ddr();
+
+ /*
+ * FIXME configure CAN pinmux early to avoid driving the bus
+ * with the low by default pins.
+ */
+ configure_module_pin_mux(board_can_pin_mux);
+
+ am33xx_uart_soft_reset((void *)AM33XX_UART2_BASE);
+ am33xx_enable_uart2_pin_mux();
+ omap_uart_lowlevel_init((void *)AM33XX_UART2_BASE);
+ putc_ll('>');
+
+ barebox_arm_entry(0x80000000, SZ_256M, fdt);
+}
+
+ENTRY_FUNCTION(start_am33xx_afi_gf_sram, bootinfo, r1, r2)
+{
+ am33xx_save_bootinfo((void *)bootinfo);
+
+ /*
+ * Setup C environment, the board init code uses global variables.
+ * Stackpointer has already been initialized by the ROM code.
+ */
+ relocate_to_current_adr();
+ setup_c();
+
+ gf_sram_init();
+}
+
+ENTRY_FUNCTION(start_am33xx_afi_gf_sdram, r0, r1, r2)
+{
+ void *fdt;
+
+ fdt = __dtb_am335x_afi_gf_start - get_runtime_offset();
+
+ putc_ll('>');
+
+ barebox_arm_entry(0x80000000, SZ_256M, fdt);
+}