summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/netgear-rn2120
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/netgear-rn2120')
-rw-r--r--arch/arm/boards/netgear-rn2120/Makefile2
-rw-r--r--arch/arm/boards/netgear-rn2120/board.c88
-rw-r--r--arch/arm/boards/netgear-rn2120/kwbimage.cfg7
-rw-r--r--arch/arm/boards/netgear-rn2120/lowlevel.c41
4 files changed, 138 insertions, 0 deletions
diff --git a/arch/arm/boards/netgear-rn2120/Makefile b/arch/arm/boards/netgear-rn2120/Makefile
new file mode 100644
index 0000000000..01c7a259e9
--- /dev/null
+++ b/arch/arm/boards/netgear-rn2120/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/netgear-rn2120/board.c b/arch/arm/boards/netgear-rn2120/board.c
new file mode 100644
index 0000000000..caf106af50
--- /dev/null
+++ b/arch/arm/boards/netgear-rn2120/board.c
@@ -0,0 +1,88 @@
+#include <clock.h>
+#include <init.h>
+#include <of.h>
+#include <gpio.h>
+#include <printk.h>
+#include <linux/kernel.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+
+static int rn2120_init(void)
+{
+ /*
+ * This is the machine type that the kernel shipped by Netgear is using.
+ * It's wrong but a given fact.
+ */
+ armlinux_set_architecture(MACH_TYPE_ARMADA_XP_DB);
+
+ return 0;
+}
+device_initcall(rn2120_init);
+
+struct hdpower {
+ unsigned gpio_detect;
+ unsigned gpio_power;
+ unsigned gpio_led;
+};
+
+/*
+ * It would be nice to have this abstracted in the device tree, but currently
+ * this isn't the case.
+ */
+static struct hdpower rn2120_hdpower[] = {
+ {
+ /* sata 1 */
+ .gpio_detect = 32,
+ .gpio_power = 24,
+ .gpio_led = 31,
+ }, {
+ /* sata 2 */
+ .gpio_detect = 33,
+ .gpio_power = 25,
+ .gpio_led = 40,
+ }, {
+ /* sata 3 */
+ .gpio_detect = 34,
+ .gpio_power = 26,
+ .gpio_led = 44,
+ }, {
+ /* sata 4 */
+ .gpio_detect = 35,
+ .gpio_power = 28,
+ .gpio_led = 47,
+ },
+};
+
+static int rn2120_hddetect(void)
+{
+ int i;
+
+ if (!of_machine_is_compatible("netgear,readynas-2120"))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(rn2120_hdpower); ++i) {
+ int ret;
+ ret = gpio_direction_input(rn2120_hdpower[i].gpio_detect);
+ if (ret) {
+ pr_err("Failure to detect hd%d (%d)\n", i, ret);
+ continue;
+ }
+
+ ret = gpio_get_value(rn2120_hdpower[i].gpio_detect);
+ if (ret) {
+ /* no disk present */
+ gpio_direction_output(rn2120_hdpower[i].gpio_power, 0);
+ } else {
+ pr_info("Detected presence of disk #%d\n", i + 1);
+ /* make a pause after powering up 2 disks */
+ if (i && !(i & 1)) {
+ pr_info("Delay power up\n");
+ mdelay(7000);
+ }
+
+ gpio_direction_output(rn2120_hdpower[i].gpio_power, 1);
+ }
+ }
+ return 0;
+}
+device_initcall(rn2120_hddetect);
diff --git a/arch/arm/boards/netgear-rn2120/kwbimage.cfg b/arch/arm/boards/netgear-rn2120/kwbimage.cfg
new file mode 100644
index 0000000000..a6f0aa6d3d
--- /dev/null
+++ b/arch/arm/boards/netgear-rn2120/kwbimage.cfg
@@ -0,0 +1,7 @@
+VERSION 1
+BOOT_FROM nand
+DESTADDR 00000000
+EXECADDR 00000000
+NAND_BLKSZ 00020000
+NAND_BADBLK_LOCATION 01
+BINARY binary.0 0000005b 00000068
diff --git a/arch/arm/boards/netgear-rn2120/lowlevel.c b/arch/arm/boards/netgear-rn2120/lowlevel.c
new file mode 100644
index 0000000000..29c8b43c44
--- /dev/null
+++ b/arch/arm/boards/netgear-rn2120/lowlevel.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * 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 <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/io.h>
+#include <mach/lowlevel.h>
+
+extern char __dtb_armada_xp_rn2120_bb_start[];
+
+ENTRY_FUNCTION(start_netgear_rn2120, r0, r1, r2)
+{
+ void *fdt;
+
+ arm_cpu_lowlevel_init();
+
+ /*
+ * This is necessary to allow the machine to draw more power. Probably
+ * connected to a TI TPS65251. Without this resetting a phy makes the
+ * SoC reset.
+ * This is effectively gpio_direction_output(42, 1);
+ */
+ writel((1 << 10) | readl((void *)0xd0018140), (void *)0xd0018140);
+ writel(~(1 << 10) & readl((void *)0xd0018144), (void *)0xd0018144);
+
+ fdt = __dtb_armada_xp_rn2120_bb_start -
+ get_runtime_offset();
+
+ mvebu_barebox_entry(fdt);
+}