186 lines
5.9 KiB
C
186 lines
5.9 KiB
C
/*
|
|
* Copyright (C) 2015 Jan Luebbe <jluebbe@lasnet.de>
|
|
*
|
|
* This file is part of barebox.
|
|
* See file CREDITS for list of people who contributed to this project.
|
|
*
|
|
* 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 <init.h>
|
|
#include <io.h>
|
|
#include <globalvar.h>
|
|
#include <gpio.h>
|
|
#include <envfs.h>
|
|
#include <fs.h>
|
|
#include <fcntl.h>
|
|
#include <libfile.h>
|
|
#include <net.h>
|
|
|
|
#include <linux/sizes.h>
|
|
#include <asm/armlinux.h>
|
|
|
|
#define PINMUX0 0x01c40000
|
|
#define PINMUX1 0x01c40004
|
|
#define PINMUX1_I2C BIT(7)
|
|
|
|
#define VDD3P3V_PWDN (0x01c40048)
|
|
|
|
#include <platform_data/eth-davinci-emac.h>
|
|
|
|
#define EMAC_BASE_ADDR 0x01C80000
|
|
#define EMAC_WRAPPER_BASE_ADDR 0x01C81000
|
|
#define EMAC_WRAPPER_RAM_ADDR 0x01C82000
|
|
#define EMAC_MDIO_BASE_ADDR 0x01C84000
|
|
|
|
static struct resource dm644x_emac_resources[] = {
|
|
{
|
|
.start = EMAC_BASE_ADDR,
|
|
.end = EMAC_BASE_ADDR + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
}, {
|
|
.start = EMAC_WRAPPER_BASE_ADDR,
|
|
.end = EMAC_WRAPPER_BASE_ADDR + 0xfff,
|
|
.flags = IORESOURCE_MEM,
|
|
}, {
|
|
.start = EMAC_MDIO_BASE_ADDR,
|
|
.end = EMAC_MDIO_BASE_ADDR + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
}, {
|
|
.start = EMAC_WRAPPER_RAM_ADDR,
|
|
.end = EMAC_WRAPPER_RAM_ADDR + 0x1fff, /* 8kB */
|
|
.flags = IORESOURCE_MEM,
|
|
}
|
|
};
|
|
|
|
static struct davinci_emac_platform_data dm644x_emac_pdata = {
|
|
.force_link = false,
|
|
.interface_rmii = false,
|
|
.phy_addr = 1,
|
|
};
|
|
|
|
static struct device_d dm644x_emac_device = {
|
|
.id = DEVICE_ID_DYNAMIC,
|
|
.name = "davinci_emac",
|
|
.num_resources = ARRAY_SIZE(dm644x_emac_resources),
|
|
.resource = dm644x_emac_resources,
|
|
.platform_data = &dm644x_emac_pdata,
|
|
};
|
|
|
|
static void sysmobts_config_eeprom(const char *compatible) {
|
|
struct device_node *node;
|
|
|
|
node = of_find_node_by_path("/i2c/eeprom@50");
|
|
if (!node) {
|
|
pr_err("can't find eeprom node to configure\n");
|
|
return;
|
|
}
|
|
of_set_property(node, "compatible", compatible, strlen(compatible)+1, 1);
|
|
of_device_enable(node);
|
|
}
|
|
|
|
static void sysmobts_board_detect(void)
|
|
{
|
|
int board_ver, board_cfg;
|
|
char variant[4];
|
|
|
|
board_ver = gpio_get_value(15);
|
|
board_ver |= gpio_get_value(16) << 1;
|
|
board_ver |= gpio_get_value(17) << 2;
|
|
|
|
board_cfg = gpio_get_value(10);
|
|
board_cfg |= gpio_get_value(11) << 1;
|
|
board_cfg |= gpio_get_value(12) << 3;
|
|
board_cfg |= gpio_get_value(13) << 4;
|
|
board_cfg |= gpio_get_value(14) << 5;
|
|
|
|
variant[0] = 'A' + board_ver;
|
|
variant[1] = '.';
|
|
variant[2] = '0' + board_cfg;
|
|
variant[3] = '\0';
|
|
|
|
globalvar_add_simple("board.variant", variant);
|
|
|
|
printf("detected 'sysmobts_v2 %s'\n", variant);
|
|
|
|
/* enable the correct eeprom */
|
|
if (board_ver <= 2) {
|
|
sysmobts_config_eeprom("24c02");
|
|
} else {
|
|
sysmobts_config_eeprom("24c64");
|
|
}
|
|
}
|
|
|
|
static int sysmobts_set_ethaddr(void)
|
|
{
|
|
char addr[6];
|
|
int fd, ret;
|
|
|
|
fd = open("/dev/eeprom0", O_RDONLY);
|
|
if (fd < 0) {
|
|
ret = fd;
|
|
goto err;
|
|
}
|
|
|
|
ret = read_full(fd, addr, 6);
|
|
if (ret < 0)
|
|
goto err_open;
|
|
|
|
eth_register_ethaddr(0, addr);
|
|
|
|
ret = 0;
|
|
|
|
err_open:
|
|
close(fd);
|
|
err:
|
|
if (ret)
|
|
pr_err("can't read eeprom /dev/eeprom0 (%s)\n", strerror(ret));
|
|
|
|
return ret;
|
|
}
|
|
|
|
#define MACH_TYPE_SYSMOBTS_V2 3758
|
|
|
|
static void sysmobts_devices_shutdown(void)
|
|
{
|
|
writel(readl(PINMUX1) | PINMUX1_I2C, PINMUX1);
|
|
}
|
|
postdevshutdown_exitcall(sysmobts_devices_shutdown);
|
|
|
|
static int sysmobts_coredevices_init(void)
|
|
{
|
|
writel(0, VDD3P3V_PWDN);
|
|
|
|
writel(0x8000000f, PINMUX0);
|
|
writel(0x00050187, PINMUX1);
|
|
|
|
writel(readl(PINMUX1) & ~PINMUX1_I2C, PINMUX1);
|
|
|
|
sysmobts_board_detect();
|
|
|
|
return 0;
|
|
}
|
|
coredevice_initcall(sysmobts_coredevices_init);
|
|
|
|
static int sysmobts_devices_init(void)
|
|
{
|
|
sysmobts_set_ethaddr();
|
|
platform_device_register(&dm644x_emac_device);
|
|
|
|
defaultenv_append_directory(defaultenv_sysmobts);
|
|
|
|
armlinux_set_architecture(MACH_TYPE_SYSMOBTS_V2);
|
|
|
|
return 0;
|
|
}
|
|
device_initcall(sysmobts_devices_init);
|