summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/sata_sil.c11
-rw-r--r--drivers/ata/sata_sil.h6
-rw-r--r--drivers/clk/owl/clk_owl.c9
-rw-r--r--drivers/clk/owl/clk_owl.h2
-rw-r--r--drivers/core/dump.c55
-rw-r--r--drivers/gpio/Kconfig20
-rw-r--r--drivers/gpio/gpio-uclass.c46
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/dwmac_s700.c67
-rw-r--r--drivers/net/phy/Kconfig9
-rw-r--r--drivers/net/phy/realtek.c55
-rw-r--r--drivers/net/smc911x.c60
13 files changed, 319 insertions, 29 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 6896fa8771..d5ba94c172 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -27,7 +27,11 @@
#include "sata_sil.h"
+#ifdef CONFIG_DM_PCI
+#define virt_to_bus(devno, v) dm_pci_virt_to_mem(devno, (void *) (v))
+#else
#define virt_to_bus(devno, v) pci_virt_to_mem(devno, (void *) (v))
+#endif
/* just compatible ahci_ops */
struct sil_ops {
@@ -608,13 +612,18 @@ static int sil_init_sata(struct udevice *uc_dev, int dev)
/* Save the private struct to block device struct */
#if !CONFIG_IS_ENABLED(BLK)
sata_dev_desc[dev].priv = (void *)sata;
+ sata->devno = sata_info.devno;
#else
priv->sil_sata_desc[dev] = sata;
priv->port_num = dev;
+#ifdef CONFIG_DM_PCI
+ sata->devno = uc_dev->parent;
+#else
+ sata->devno = sata_info.devno;
+#endif /* CONFIG_DM_PCI */
#endif
sata->id = dev;
sata->port = port;
- sata->devno = sata_info.devno;
sprintf(sata->name, "SATA#%d", dev);
sil_cmd_soft_reset(sata);
tmp = readl(port + PORT_SSTATUS);
diff --git a/drivers/ata/sata_sil.h b/drivers/ata/sata_sil.h
index ef41e8259a..a300c0c388 100644
--- a/drivers/ata/sata_sil.h
+++ b/drivers/ata/sata_sil.h
@@ -21,7 +21,11 @@ struct sil_sata {
u16 pio;
u16 mwdma;
u16 udma;
- pci_dev_t devno;
+#ifdef CONFIG_DM_PCI
+ struct udevice *devno;
+#else
+ pci_dev_t devno;
+#endif
int wcache;
int flush;
int flush_ext;
diff --git a/drivers/clk/owl/clk_owl.c b/drivers/clk/owl/clk_owl.c
index 9715fce162..1999c87a33 100644
--- a/drivers/clk/owl/clk_owl.c
+++ b/drivers/clk/owl/clk_owl.c
@@ -87,6 +87,11 @@ int owl_clk_enable(struct clk *clk)
/* Enable UART3 interface clock */
setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART3);
break;
+ case CLK_RMII_REF:
+ case CLK_ETHERNET:
+ setbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_ETH);
+ setbits_le32(priv->base + CMU_ETHERNETPLL, 5);
+ break;
default:
return -EINVAL;
}
@@ -112,6 +117,10 @@ int owl_clk_disable(struct clk *clk)
/* Disable UART3 interface clock */
clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_UART3);
break;
+ case CLK_RMII_REF:
+ case CLK_ETHERNET:
+ clrbits_le32(priv->base + CMU_DEVCLKEN1, CMU_DEVCLKEN1_ETH);
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/clk/owl/clk_owl.h b/drivers/clk/owl/clk_owl.h
index cf896bdb98..a01f81a6a7 100644
--- a/drivers/clk/owl/clk_owl.h
+++ b/drivers/clk/owl/clk_owl.h
@@ -62,6 +62,4 @@ struct owl_clk_priv {
#define CMU_DEVCLKEN1_UART5 BIT(21)
#define CMU_DEVCLKEN1_UART3 BIT(11)
-#define CMU_DEVCLKEN1_ETH_S700 BIT(23)
-
#endif
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index cb8a25b9ad..6debaf97a1 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -97,7 +97,7 @@ void dm_dump_uclass(void)
}
}
-void dm_dump_drivers(void)
+void dm_dump_driver_compat(void)
{
struct driver *d = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
@@ -120,3 +120,56 @@ void dm_dump_drivers(void)
printf("%-20.20s %s\n", "", match->compatible);
}
}
+
+void dm_dump_drivers(void)
+{
+ struct driver *d = ll_entry_start(struct driver, driver);
+ const int n_ents = ll_entry_count(struct driver, driver);
+ struct driver *entry;
+ struct udevice *udev;
+ struct uclass *uc;
+ int i;
+
+ puts("Driver uid uclass Devices\n");
+ puts("----------------------------------------------------------\n");
+
+ for (entry = d; entry < d + n_ents; entry++) {
+ uclass_get(entry->id, &uc);
+
+ printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id,
+ uc ? uc->uc_drv->name : "<no uclass>");
+
+ if (!uc) {
+ puts("\n");
+ continue;
+ }
+
+ i = 0;
+ uclass_foreach_dev(udev, uc) {
+ if (udev->driver != entry)
+ continue;
+ if (i)
+ printf("%-51.51s", "");
+
+ printf("%-25.25s\n", udev->name);
+ i++;
+ }
+ if (!i)
+ puts("<none>\n");
+ }
+}
+
+void dm_dump_static_driver_info(void)
+{
+ struct driver_info *drv = ll_entry_start(struct driver_info,
+ driver_info);
+ const int n_ents = ll_entry_count(struct driver_info, driver_info);
+ struct driver_info *entry;
+
+ puts("Driver Address\n");
+ puts("---------------------------------\n");
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ printf("%-25.25s @%08lx\n", entry->name,
+ (ulong)map_to_sysmem(entry->platdata));
+ }
+}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index af608b7b0e..0e8ad9530d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -46,6 +46,26 @@ config GPIO_HOG
is a mechanism providing automatic GPIO request and config-
uration as part of the gpio-controller's driver probe function.
+config DM_GPIO_LOOKUP_LABEL
+ bool "Enable searching for gpio labelnames"
+ depends on DM_GPIO
+ help
+ This option enables searching for gpio names in
+ the defined gpio labels, if the search for the
+ gpio bank name failed. This makes sense if you use
+ different gpios on different hardware versions
+ for the same functionality in board code.
+
+config SPL_DM_GPIO_LOOKUP_LABEL
+ bool "Enable searching for gpio labelnames"
+ depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT
+ help
+ This option enables searching for gpio names in
+ the defined gpio labels, if the search for the
+ gpio bank name failed. This makes sense if you use
+ different gpios on different hardware versions
+ for the same functionality in board code.
+
config ALTERA_PIO
bool "Altera PIO driver"
depends on DM_GPIO
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index f016532354..ab17fa8a5d 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -68,6 +68,45 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
return ret ? ret : -ENOENT;
}
+#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
+/**
+ * dm_gpio_lookup_label() - look for name in gpio device
+ *
+ * search in uc_priv, if there is a gpio with labelname same
+ * as name.
+ *
+ * @name: name which is searched
+ * @uc_priv: gpio_dev_priv pointer.
+ * @offset: gpio offset within the device
+ * @return: 0 if found, -ENOENT if not.
+ */
+static int dm_gpio_lookup_label(const char *name,
+ struct gpio_dev_priv *uc_priv, ulong *offset)
+{
+ int len;
+ int i;
+
+ *offset = -1;
+ len = strlen(name);
+ for (i = 0; i < uc_priv->gpio_count; i++) {
+ if (!uc_priv->name[i])
+ continue;
+ if (!strncmp(name, uc_priv->name[i], len)) {
+ *offset = i;
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+#else
+static int
+dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
+ ulong *offset)
+{
+ return -ENOENT;
+}
+#endif
+
int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
{
struct gpio_dev_priv *uc_priv = NULL;
@@ -96,6 +135,13 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
if (!strict_strtoul(name + len, 10, &offset))
break;
}
+
+ /*
+ * if we did not found a gpio through its bank
+ * name, we search for a valid gpio label.
+ */
+ if (!dm_gpio_lookup_label(name, uc_priv, &offset))
+ break;
}
if (!dev)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1566b3bda1..ec3fb49832 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -238,6 +238,13 @@ config ETH_DESIGNWARE_SOCFPGA
Altera system manager to correctly interface with the PHY.
This code handles those SoC specifics.
+config ETH_DESIGNWARE_S700
+ bool "Actins S700 glue driver for Synopsys Designware Ethernet MAC"
+ depends on DM_ETH && ETH_DESIGNWARE
+ help
+ This provides glue layer to use Synopsys Designware Ethernet MAC
+ present on Actions S700 SoC.
+
config ETHOC
bool "OpenCores 10/100 Mbps Ethernet MAC"
help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 383ed1c64f..1ecdc40b8f 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_CS8900) += cs8900.o
obj-$(CONFIG_TULIP) += dc2114x.o
obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
+obj-$(CONFIG_ETH_DESIGNWARE_S700) += dwmac_s700.o
obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
obj-$(CONFIG_DNET) += dnet.o
obj-$(CONFIG_DM_ETH_PHY) += eth-phy-uclass.o
diff --git a/drivers/net/dwmac_s700.c b/drivers/net/dwmac_s700.c
new file mode 100644
index 0000000000..9d3f3ac5d9
--- /dev/null
+++ b/drivers/net/dwmac_s700.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Amit Singh Tomar <amittomer25@gmail.com>
+ *
+ * Actions DWMAC specific glue layer
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <clk.h>
+#include <phy.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+#include "designware.h"
+#include <asm/arch-owl/regs_s700.h>
+#include <linux/bitops.h>
+
+/* pin control for MAC */
+#define RMII_TXD01_MFP_CTL0 (0x0 << 16)
+#define RMII_RXD01_MFP_CTL0 (0x0 << 8)
+#define RMII_TXEN_TXER_MFP_CTL0 (0x0 << 13)
+#define RMII_REF_CLK_MFP_CTL0 (0x0 << 6)
+#define CLKO_25M_EN_MFP_CTL3 BIT(30)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void dwmac_board_setup(void)
+{
+ clrbits_le32(MFP_CTL0, (RMII_TXD01_MFP_CTL0 | RMII_RXD01_MFP_CTL0 |
+ RMII_TXEN_TXER_MFP_CTL0 | RMII_REF_CLK_MFP_CTL0));
+
+ setbits_le32(MFP_CTL3, CLKO_25M_EN_MFP_CTL3);
+}
+
+static int dwmac_s700_probe(struct udevice *dev)
+{
+ dwmac_board_setup();
+
+ /* This is undocumented, phy interface select register */
+ writel(0x4, 0xe024c0a0);
+
+ return designware_eth_probe(dev);
+}
+
+static int dwmac_s700_ofdata_to_platdata(struct udevice *dev)
+{
+ return designware_eth_ofdata_to_platdata(dev);
+}
+
+static const struct udevice_id dwmac_s700_ids[] = {
+ {.compatible = "actions,s700-ethernet"},
+ { }
+};
+
+U_BOOT_DRIVER(dwmac_s700) = {
+ .name = "dwmac_s700",
+ .id = UCLASS_ETH,
+ .of_match = dwmac_s700_ids,
+ .ofdata_to_platdata = dwmac_s700_ofdata_to_platdata,
+ .probe = dwmac_s700_probe,
+ .ops = &designware_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index b0bd762ac3..4e1a93be22 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -235,6 +235,15 @@ config RTL8211F_PHY_FORCE_EEE_RXC_ON
Default n, which means that the PHY state is not changed. To work
around the issues, change this setting to y.
+config RTL8201F_PHY_S700_RMII_TIMINGS
+ bool "Ethernet PHY RTL8201F: adjust RMII Tx Interface timings"
+ depends on PHY_REALTEK
+ help
+ This provides an option to configure specific timing requirements (needed
+ for proper PHY operations) for the PHY module present on ACTION SEMI S700
+ based cubieboard7. Exact timing requiremnets seems to be SoC specific
+ (and it's undocumented) that comes from vendor code itself.
+
config PHY_SMSC
bool "Microchip(SMSC) Ethernet PHYs support"
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index b4612c1cfd..b1b1fa5080 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -14,6 +14,7 @@
#define PHY_RTL8211x_FORCE_MASTER BIT(1)
#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3)
+#define PHY_RTL8201F_S700_RMII_TIMINGS BIT(4)
#define PHY_AUTONEGOTIATE_TIMEOUT 5000
@@ -60,6 +61,15 @@
#define MIIM_RTL8211F_RX_DELAY 0x8
#define MIIM_RTL8211F_LCR 0x10
+#define RTL8201F_RMSR 0x10
+
+#define RMSR_RX_TIMING_SHIFT BIT(2)
+#define RMSR_RX_TIMING_MASK GENMASK(7, 4)
+#define RMSR_RX_TIMING_VAL 0x4
+#define RMSR_TX_TIMING_SHIFT BIT(3)
+#define RMSR_TX_TIMING_MASK GENMASK(11, 8)
+#define RMSR_TX_TIMING_VAL 0x5
+
static int rtl8211f_phy_extread(struct phy_device *phydev, int addr,
int devaddr, int regnum)
{
@@ -114,6 +124,15 @@ static int rtl8211f_probe(struct phy_device *phydev)
return 0;
}
+static int rtl8210f_probe(struct phy_device *phydev)
+{
+#ifdef CONFIG_RTL8201F_PHY_S700_RMII_TIMINGS
+ phydev->flags |= PHY_RTL8201F_S700_RMII_TIMINGS;
+#endif
+
+ return 0;
+}
+
/* RealTek RTL8211x */
static int rtl8211x_config(struct phy_device *phydev)
{
@@ -159,6 +178,29 @@ static int rtl8211x_config(struct phy_device *phydev)
return 0;
}
+/* RealTek RTL8201F */
+static int rtl8201f_config(struct phy_device *phydev)
+{
+ unsigned int reg;
+
+ if (phydev->flags & PHY_RTL8201F_S700_RMII_TIMINGS) {
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+ 7);
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR);
+ reg &= ~(RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK);
+ /* Set the needed Rx/Tx Timings for proper PHY operation */
+ reg |= (RMSR_RX_TIMING_VAL << RMSR_RX_TIMING_SHIFT)
+ | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT);
+ phy_write(phydev, MDIO_DEVAD_NONE, RTL8201F_RMSR, reg);
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+ 0);
+ }
+
+ genphy_config_aneg(phydev);
+
+ return 0;
+}
+
static int rtl8211f_config(struct phy_device *phydev)
{
u16 reg;
@@ -398,12 +440,25 @@ static struct phy_driver RTL8211F_driver = {
.writeext = &rtl8211f_phy_extwrite,
};
+/* Support for RTL8201F PHY */
+static struct phy_driver RTL8201F_driver = {
+ .name = "RealTek RTL8201F 10/100Mbps Ethernet",
+ .uid = 0x1cc816,
+ .mask = 0xffffff,
+ .features = PHY_BASIC_FEATURES,
+ .probe = &rtl8210f_probe,
+ .config = &rtl8201f_config,
+ .startup = &rtl8211e_startup,
+ .shutdown = &genphy_shutdown,
+};
+
int phy_realtek_init(void)
{
phy_register(&RTL8211B_driver);
phy_register(&RTL8211E_driver);
phy_register(&RTL8211F_driver);
phy_register(&RTL8211DN_driver);
+ phy_register(&RTL8201F_driver);
return 0;
}
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 9d2790e561..053ff9f4ff 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -187,6 +187,26 @@ static void smc911x_handle_mac_address(struct smc911x_priv *priv)
printf(DRIVERNAME ": MAC %pM\n", m);
}
+static bool smc911x_read_mac_address(struct smc911x_priv *priv)
+{
+ u32 addrh, addrl;
+
+ /* address is obtained from optional eeprom */
+ addrh = smc911x_get_mac_csr(priv, ADDRH);
+ addrl = smc911x_get_mac_csr(priv, ADDRL);
+ if (addrl == 0xffffffff && addrh == 0x0000ffff)
+ return false;
+
+ priv->enetaddr[0] = addrl;
+ priv->enetaddr[1] = addrl >> 8;
+ priv->enetaddr[2] = addrl >> 16;
+ priv->enetaddr[3] = addrl >> 24;
+ priv->enetaddr[4] = addrh;
+ priv->enetaddr[5] = addrh >> 8;
+
+ return true;
+}
+
static int smc911x_eth_phy_read(struct smc911x_priv *priv,
u8 phy, u8 reg, u16 *val)
{
@@ -471,7 +491,6 @@ static int smc911x_recv(struct eth_device *dev)
int smc911x_initialize(u8 dev_num, int base_addr)
{
- unsigned long addrl, addrh;
struct smc911x_priv *priv;
int ret;
@@ -489,18 +508,8 @@ int smc911x_initialize(u8 dev_num, int base_addr)
goto err_detect;
}
- addrh = smc911x_get_mac_csr(priv, ADDRH);
- addrl = smc911x_get_mac_csr(priv, ADDRL);
- if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) {
- /* address is obtained from optional eeprom */
- priv->enetaddr[0] = addrl;
- priv->enetaddr[1] = addrl >> 8;
- priv->enetaddr[2] = addrl >> 16;
- priv->enetaddr[3] = addrl >> 24;
- priv->enetaddr[4] = addrh;
- priv->enetaddr[5] = addrh >> 8;
+ if (smc911x_read_mac_address(priv))
memcpy(priv->dev.enetaddr, priv->enetaddr, 6);
- }
priv->dev.init = smc911x_init;
priv->dev.halt = smc911x_halt;
@@ -565,6 +574,19 @@ static int smc911x_recv(struct udevice *dev, int flags, uchar **packetp)
return ret ? ret : -EAGAIN;
}
+static int smc911x_read_rom_hwaddr(struct udevice *dev)
+{
+ struct smc911x_priv *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ if (!smc911x_read_mac_address(priv))
+ return -ENODEV;
+
+ memcpy(pdata->enetaddr, priv->enetaddr, sizeof(pdata->enetaddr));
+
+ return 0;
+}
+
static int smc911x_bind(struct udevice *dev)
{
return device_set_name(dev, dev->name);
@@ -573,7 +595,6 @@ static int smc911x_bind(struct udevice *dev)
static int smc911x_probe(struct udevice *dev)
{
struct smc911x_priv *priv = dev_get_priv(dev);
- unsigned long addrh, addrl;
int ret;
/* Try to detect chip. Will fail if not present. */
@@ -581,17 +602,7 @@ static int smc911x_probe(struct udevice *dev)
if (ret)
return ret;
- addrh = smc911x_get_mac_csr(priv, ADDRH);
- addrl = smc911x_get_mac_csr(priv, ADDRL);
- if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) {
- /* address is obtained from optional eeprom */
- priv->enetaddr[0] = addrl;
- priv->enetaddr[1] = addrl >> 8;
- priv->enetaddr[2] = addrl >> 16;
- priv->enetaddr[3] = addrl >> 24;
- priv->enetaddr[4] = addrh;
- priv->enetaddr[5] = addrh >> 8;
- }
+ smc911x_read_rom_hwaddr(dev);
return 0;
}
@@ -612,6 +623,7 @@ static const struct eth_ops smc911x_ops = {
.send = smc911x_send,
.recv = smc911x_recv,
.stop = smc911x_stop,
+ .read_rom_hwaddr = smc911x_read_rom_hwaddr,
};
static const struct udevice_id smc911x_ids[] = {