9
0
Fork 0
barebox/arch/arm/boards/highbank/init.c

143 lines
3.2 KiB
C

/*
* Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
*
* GPLv2 only
*/
#include <common.h>
#include <init.h>
#include <asm/armlinux.h>
#include <asm/system_info.h>
#include <generated/mach-types.h>
#include <mach/devices.h>
#include <mach/hardware.h>
#include <mach/sysregs.h>
#include <environment.h>
#include <partition.h>
#include <sizes.h>
#include <io.h>
#include <of.h>
#define FIRMWARE_DTB_BASE 0x1000
#define HB_OPP_VERSION 0
struct fdt_header *fdt = NULL;
static int hb_fixup(struct device_node *root, void *unused)
{
struct device_node *node;
u32 reg = readl(sregs_base + HB_SREG_A9_PWRDOM_DATA);
u32 *opp_table = (u32 *)HB_SYSRAM_OPP_TABLE_BASE;
u32 dtb_table[2*10];
u32 i;
u32 num_opps;
__be32 latency;
if (!(reg & HB_PWRDOM_STAT_SATA)) {
for_each_compatible_node(node, NULL, "calxeda,hb-ahci")
of_set_property(node, "status", "disabled",
sizeof("disabled"), 1);
}
if (!(reg & HB_PWRDOM_STAT_EMMC)) {
for_each_compatible_node(node, NULL, "calxeda,hb-sdhci")
of_set_property(node, "status", "disabled",
sizeof("disabled"), 1);
}
if ((opp_table[0] >> 16) != HB_OPP_VERSION)
return 0;
node = of_find_node_by_path("/cpus/cpu@0");
if (!node)
return 0;
num_opps = opp_table[0] & 0xff;
for (i = 0; i < num_opps; i++) {
dtb_table[2 * i] = cpu_to_be32(opp_table[3 + 3 * i]);
dtb_table[2 * i + 1] = cpu_to_be32(opp_table[2 + 3 * i]);
}
latency = cpu_to_be32(opp_table[1]);
of_set_property(node, "transition-latency", &latency, 4, 1);
of_set_property(node, "operating-points", dtb_table, 8 * num_opps, 1);
return 0;
}
static int highbank_mem_init(void)
{
struct device_node *root, *np;
int ret;
/* load by the firmware at 0x1000 */
fdt = IOMEM(FIRMWARE_DTB_BASE);
root = of_unflatten_dtb(fdt);
if (!root) {
pr_warn("no dtb found at 0x1000 use default configuration\n");
fdt = NULL;
goto not_found;
}
of_set_root_node(root);
np = of_find_node_by_path("/memory");
if (!np) {
pr_warn("no memory node use default configuration\n");
goto not_found;
}
ret = of_add_memory(np, true);
if (ret) {
pr_warn("memory node: probe failed use default configuration\n");
goto not_found;
}
pr_info("highbank: dtb probed memory size\n");
return 0;
not_found:
highbank_add_ddram(4089 << 20);
return 0;
}
mem_initcall(highbank_mem_init);
static int highbank_devices_init(void)
{
of_register_fixup(hb_fixup, NULL);
if (!fdt) {
highbank_register_gpio(0);
highbank_register_gpio(1);
highbank_register_gpio(2);
highbank_register_gpio(3);
highbank_register_ahci();
highbank_register_xgmac(0);
highbank_register_xgmac(1);
} else {
fdt = of_get_fixed_tree(NULL);
add_mem_device("dtb", (unsigned long)fdt, be32_to_cpu(fdt->totalsize),
IORESOURCE_MEM_WRITEABLE);
devfs_add_partition("ram0", FIRMWARE_DTB_BASE, SZ_64K, DEVFS_PARTITION_FIXED, "firmware-dtb");
}
devfs_add_partition("nvram", 0x00000, SZ_16K, DEVFS_PARTITION_FIXED, "env0");
return 0;
}
device_initcall(highbank_devices_init);
static int highbank_console_init(void)
{
barebox_set_model("Calxeda Highbank");
barebox_set_hostname("highbank");
highbank_register_uart();
return 0;
}
console_initcall(highbank_console_init);