summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-06-09 09:26:43 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-06-09 09:26:43 +0200
commit760e652a7aca15c3ba67f3e7ad4488d49f7a629a (patch)
tree5ec9c243ed182709876e0b3b5ef307956f9fe46c
parent65aa032d1186e3c3149e6d935d55fd48b6645ac2 (diff)
parent2bd7bb8972f5cf4b39bea46c5e5c6b3acddab8d7 (diff)
downloadbarebox-760e652a7aca15c3ba67f3e7ad4488d49f7a629a.tar.gz
barebox-760e652a7aca15c3ba67f3e7ad4488d49f7a629a.tar.xz
Merge branch 'for-next/mips'
-rw-r--r--arch/mips/configs/dlink-dir-320_defconfig3
-rw-r--r--arch/mips/configs/img-ci20_defconfig11
-rw-r--r--arch/mips/dts/img-ci20.dts15
-rw-r--r--arch/mips/mach-bcm47xx/include/mach/debug_ll.h14
-rw-r--r--arch/mips/mach-xburst/Kconfig1
-rw-r--r--drivers/net/dm9k.c138
6 files changed, 149 insertions, 33 deletions
diff --git a/arch/mips/configs/dlink-dir-320_defconfig b/arch/mips/configs/dlink-dir-320_defconfig
index 4c9a06f2b0..61798bf599 100644
--- a/arch/mips/configs/dlink-dir-320_defconfig
+++ b/arch/mips/configs/dlink-dir-320_defconfig
@@ -2,7 +2,6 @@ CONFIG_BUILTIN_DTB=y
CONFIG_BUILTIN_DTB_NAME="dlink-dir-320"
CONFIG_MACH_MIPS_BCM47XX=y
CONFIG_STACK_SIZE=0x7000
-CONFIG_BROKEN=y
CONFIG_EXPERIMENTAL=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
@@ -35,9 +34,9 @@ CONFIG_CMD_PING=y
CONFIG_CMD_TFTP=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_EDIT=y
+CONFIG_CMD_LOGIN=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
-CONFIG_CMD_LOGIN=y
CONFIG_CMD_PASSWD=y
CONFIG_CMD_READLINE=y
CONFIG_CMD_TIMEOUT=y
diff --git a/arch/mips/configs/img-ci20_defconfig b/arch/mips/configs/img-ci20_defconfig
index 6702c88b65..28319c523f 100644
--- a/arch/mips/configs/img-ci20_defconfig
+++ b/arch/mips/configs/img-ci20_defconfig
@@ -28,15 +28,18 @@ CONFIG_CMD_UIMAGE=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_GETOPT=y
CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_OF_NODE=y
CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
CONFIG_OFDEVICE=y
+CONFIG_DRIVER_NET_DM9K=y
# CONFIG_SPI is not set
-CONFIG_CLOCKSOURCE_DUMMY=y
CONFIG_CLOCKSOURCE_DUMMY_RATE=3500
-CONFIG_DIGEST_SHA1_GENERIC=y
-CONFIG_DIGEST_SHA224_GENERIC=y
-CONFIG_DIGEST_SHA256_GENERIC=y
+CONFIG_FS_TFTP=y
diff --git a/arch/mips/dts/img-ci20.dts b/arch/mips/dts/img-ci20.dts
index f2022dd273..da2a5bf625 100644
--- a/arch/mips/dts/img-ci20.dts
+++ b/arch/mips/dts/img-ci20.dts
@@ -28,6 +28,21 @@
device_type = "memory";
reg = <0x0 0x10000000>;
};
+
+ board {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <>;
+
+ dm9000@16000000 {
+ compatible = "davicom,dm9000";
+ davicom,no-eeprom;
+
+ reg = <0x16000000 1 /* addr */
+ 0x16000002 1>; /* data */
+ };
+ };
};
&uart0 {
diff --git a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
index 9927b4d945..3e74e0f670 100644
--- a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
+++ b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
@@ -24,16 +24,12 @@
#include <io.h>
#include <mach/hardware.h>
-#define rbr 0
-#define lsr 5
-#define LSR_THRE 0x20 /* Xmit holding register empty */
+#define DEBUG_LL_UART_SHIFT 0
-static __inline__ void PUTC_LL(char ch)
-{
- void *base = (void *)DEBUG_LL_UART_ADDR;
+#define DEBUG_LL_UART_CLK (25804800 / 16)
+#define DEBUG_LL_UART_BPS CONFIG_BAUDRATE
+#define DEBUG_LL_UART_DIVISOR (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS)
- while (!(__raw_readb(base + lsr) & LSR_THRE));
- __raw_writeb(ch, base + rbr);
-}
+#include <asm/debug_ll_ns16550.h>
#endif /* __INCLUDE_ARCH_DEBUG_LL_H__ */
diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
index 2598c41cdf..fd106fefe0 100644
--- a/arch/mips/mach-xburst/Kconfig
+++ b/arch/mips/mach-xburst/Kconfig
@@ -27,6 +27,7 @@ config BOARD_RZX50
config BOARD_CI20
bool "Imagination Creator CI20"
select CPU_JZ4780
+ select HAS_DM9000
endchoice
diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index abcb7ee65f..c3c2a8052a 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -48,6 +48,7 @@
# define NCR_FCOL (1 << 4)
# define NCR_FDX (1 << 3)
# define NCR_LBK (3 << 1)
+# define NCR_MAC_LBK (1 << 1)
# define NCR_RST (1 << 0)
#define DM9K_NSR 0x01
@@ -359,6 +360,11 @@ static int dm9k_phy_read(struct mii_bus *bus, int addr, int reg)
struct dm9k *priv = bus->priv;
struct device_d *dev = &bus->dev;
+ /* only internal phy supported by now, so show only one phy on miibus */
+ if (addr != 0) {
+ return 0xffff;
+ }
+
/* Fill the phyxcer register into REG_0C */
dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
dm9k_iow(priv, DM9K_EPCR, 0xc); /* Issue phyxcer read command */
@@ -378,6 +384,11 @@ static int dm9k_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
struct dm9k *priv = bus->priv;
struct device_d *dev = &bus->dev;
+ /* only internal phy supported by now, so show only one phy on miibus */
+ if (addr != 0) {
+ return 0;
+ }
+
/* Fill the phyxcer register into REG_0C */
dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
@@ -462,8 +473,28 @@ static void dm9k_reset(struct dm9k *priv)
struct device_d *dev = priv->miibus.parent;
dev_dbg(dev, "%s\n", __func__);
- dm9k_iow(priv, DM9K_NCR, NCR_RST);
- udelay(1000); /* delay 1ms */
+
+ /* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29
+ * The essential point is that we have to do a double reset, and the
+ * instruction is to set LBK into MAC internal loopback mode.
+ */
+
+ /* Make all GPIO pins outputs */
+ dm9k_iow(priv, DM9K_GPCR, 0x0F);
+ /* Power internal PHY by writing 0 to GPIO0 pin */
+ dm9k_iow(priv, DM9K_GPR, 0);
+
+ dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+ udelay(100); /* Application note says at least 20 us */
+ if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+ dev_err(dev, "dm9000 did not respond to first reset\n");
+
+ dm9k_iow(priv, DM9K_NCR, 0);
+ dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+ udelay(100);
+
+ if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+ dev_err(dev, "dm9000 did not respond to second reset\n");
}
static int dm9k_eth_open(struct eth_device *edev)
@@ -698,17 +729,66 @@ static int dm9k_init_dev(struct eth_device *edev)
return 0;
}
+static int dm9000_setup_buswidth(struct device_d *dev, struct dm9k *priv, uint32_t width)
+{
+ switch (width) {
+ case 1:
+ priv->buswidth = IORESOURCE_MEM_8BIT;
+ break;
+ case 2:
+ priv->buswidth = IORESOURCE_MEM_16BIT;
+ break;
+ case 4:
+ priv->buswidth = IORESOURCE_MEM_32BIT;
+ break;
+ default:
+ dev_err(dev, "Wrong io resource size\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dm9000_parse_dt(struct device_d *dev, struct dm9k *priv)
+{
+ struct device_node *np = dev->device_node;
+ uint32_t prop;
+
+ if (!IS_ENABLED(CONFIG_OFDEVICE) || !np)
+ return -ENODEV;
+
+ if (of_find_property(np, "davicom,no-eeprom", NULL)) {
+ priv->srom = 0;
+ } else {
+ priv->srom = 1;
+ }
+
+ if (of_property_read_u32(np, "reg-io-width", &prop)) {
+ /* Use 8-bit registers by default */
+ prop = 1;
+ }
+
+ return dm9000_setup_buswidth(dev, priv, prop);
+}
+
+static int dm9000_parse_pdata(struct device_d *dev, struct dm9k *priv)
+{
+ struct dm9000_platform_data *pdata = dev->platform_data;
+ uint32_t width;
+
+ priv->srom = pdata->srom;
+
+ width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK;
+
+ return dm9000_setup_buswidth(dev, priv, width);
+}
+
static int dm9k_probe(struct device_d *dev)
{
unsigned io_mode;
struct eth_device *edev;
struct dm9k *priv;
- struct dm9000_platform_data *pdata;
-
- if (!dev->platform_data) {
- dev_err(dev, "No platform_data\n");
- return -ENODEV;
- }
+ int ret;
if (dev->num_resources < 2) {
dev_err(dev, "Need 2 resources base and data");
@@ -717,19 +797,28 @@ static int dm9k_probe(struct device_d *dev)
edev = xzalloc(sizeof(struct eth_device) + sizeof(struct dm9k));
edev->priv = (struct dm9k *)(edev + 1);
+ priv = edev->priv;
- pdata = dev->platform_data;
+ if (dev->platform_data) {
+ ret = dm9000_parse_pdata(dev, priv);
+ } else {
+ ret = dm9000_parse_dt(dev, priv);
+ }
- priv = edev->priv;
+ if (ret)
+ goto err;
- priv->buswidth = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK;
priv->iodata = dev_request_mem_region(dev, 1);
- if (!priv->iodata)
- return -EBUSY;
+ if (!priv->iodata) {
+ ret = -EBUSY;
+ goto err;
+ }
+
priv->iobase = dev_request_mem_region(dev, 0);
- if (!priv->iobase)
- return -EBUSY;
- priv->srom = pdata->srom;
+ if (!priv->iobase) {
+ ret = -EBUSY;
+ goto err;
+ }
edev->init = dm9k_init_dev;
edev->open = dm9k_eth_open;
@@ -747,8 +836,10 @@ static int dm9k_probe(struct device_d *dev)
/* RESET device */
dm9k_reset(priv);
- if(dm9k_check_id(priv))
- return -ENODEV;
+ if (dm9k_check_id(priv)) {
+ ret = -ENODEV;
+ goto err;
+ }
io_mode = dm9k_ior(priv, DM9K_ISR) >> 6;
switch (io_mode) {
@@ -780,10 +871,21 @@ static int dm9k_probe(struct device_d *dev)
eth_register(edev);
return 0;
+
+err:
+ free(edev);
+
+ return ret;
}
+static struct of_device_id dm9000_of_matches[] = {
+ { .compatible = "davicom,dm9000", },
+ { /* sentinel */ }
+};
+
static struct driver_d dm9k_driver = {
.name = "dm9000",
.probe = dm9k_probe,
+ .of_compatible = DRV_OF_COMPAT(dm9000_of_matches),
};
device_platform_driver(dm9k_driver);