summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c2
-rw-r--r--drivers/net/ti/cpsw.c154
-rw-r--r--drivers/reset/Kconfig7
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-hsdk.c116
-rw-r--r--drivers/spi/sandbox_spi.c11
-rw-r--r--drivers/spi/spi-uclass.c14
-rw-r--r--drivers/timer/tsc_timer.c5
8 files changed, 235 insertions, 75 deletions
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index e11fbdeed3e..06b06639506 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -234,11 +234,11 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
break;
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
mode = AM65_GMII_SEL_MODE_RGMII;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
mode = AM65_GMII_SEL_MODE_RGMII;
rgmii_id = true;
diff --git a/drivers/net/ti/cpsw.c b/drivers/net/ti/cpsw.c
index 20ddb44dd89..4a990be93e9 100644
--- a/drivers/net/ti/cpsw.c
+++ b/drivers/net/ti/cpsw.c
@@ -19,12 +19,9 @@
#include <phy.h>
#include <asm/arch/cpu.h>
#include <dm.h>
-#include <fdt_support.h>
#include "cpsw_mdio.h"
-DECLARE_GLOBAL_DATA_PTR;
-
#define BITMASK(bits) (BIT(bits) - 1)
#define NUM_DESCS (PKTBUFSRX * 2)
#define PKT_MIN 60
@@ -33,6 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define GIGABITEN BIT(7)
#define FULLDUPLEXEN BIT(0)
#define MIIEN BIT(15)
+#define CTL_EXT_EN BIT(18)
/* DMA Registers */
#define CPDMA_TXCONTROL 0x004
#define CPDMA_RXCONTROL 0x014
@@ -489,6 +487,8 @@ static int cpsw_slave_update_link(struct cpsw_slave *slave,
mac_control |= FULLDUPLEXEN;
if (phy->speed == 100)
mac_control |= MIIEN;
+ if (phy->speed == 10 && phy_interface_is_rgmii(phy))
+ mac_control |= CTL_EXT_EN;
}
if (mac_control == slave->mac_control)
@@ -836,6 +836,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
{
struct phy_device *phydev;
u32 supported = PHY_GBIT_FEATURES;
+ int ret;
phydev = phy_connect(priv->bus,
slave->data->phy_addr,
@@ -846,11 +847,18 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
return -1;
phydev->supported &= supported;
+ if (slave->data->max_speed) {
+ ret = phy_set_supported(phydev, slave->data->max_speed);
+ if (ret)
+ return ret;
+ dev_dbg(priv->dev, "Port %u speed forced to %uMbit\n",
+ slave->slave_num + 1, slave->data->max_speed);
+ }
phydev->advertising = phydev->supported;
#ifdef CONFIG_DM_ETH
- if (slave->data->phy_of_handle)
- phydev->node = offset_to_ofnode(slave->data->phy_of_handle);
+ if (ofnode_valid(slave->data->phy_of_handle))
+ phydev->node = slave->data->phy_of_handle;
#endif
priv->phydev = phydev;
@@ -1038,12 +1046,6 @@ static const struct eth_ops cpsw_eth_ops = {
.stop = cpsw_eth_stop,
};
-static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node)
-{
- return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL,
- false);
-}
-
static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
phy_interface_t phy_mode)
{
@@ -1061,10 +1063,10 @@ static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
break;
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
mode = AM33XX_GMII_SEL_MODE_RGMII;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
mode = AM33XX_GMII_SEL_MODE_RGMII;
rgmii_id = true;
@@ -1176,23 +1178,53 @@ static int cpsw_eth_probe(struct udevice *dev)
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
+static void cpsw_eth_of_parse_slave(struct cpsw_platform_data *data,
+ int slave_index, ofnode subnode)
+{
+ struct ofnode_phandle_args out_args;
+ struct cpsw_slave_data *slave_data;
+ const char *phy_mode;
+ u32 phy_id[2];
+ int ret;
+
+ slave_data = &data->slave_data[slave_index];
+
+ phy_mode = ofnode_read_string(subnode, "phy-mode");
+ if (phy_mode)
+ slave_data->phy_if = phy_get_interface_by_name(phy_mode);
+
+ ret = ofnode_parse_phandle_with_args(subnode, "phy-handle",
+ NULL, 0, 0, &out_args);
+ if (!ret) {
+ slave_data->phy_of_handle = out_args.node;
+
+ ret = ofnode_read_s32(slave_data->phy_of_handle, "reg",
+ &slave_data->phy_addr);
+ if (ret)
+ printf("error: phy addr not found in dt\n");
+ } else {
+ ret = ofnode_read_u32_array(subnode, "phy_id", phy_id, 2);
+ if (ret)
+ printf("error: phy_id read failed\n");
+ }
+
+ slave_data->max_speed = ofnode_read_s32_default(subnode,
+ "max-speed", 0);
+}
+
static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct cpsw_platform_data *data;
struct gpio_desc *mode_gpios;
- const char *phy_mode;
- const void *fdt = gd->fdt_blob;
- int node = dev_of_offset(dev);
- int subnode;
int slave_index = 0;
- int active_slave;
int num_mode_gpios;
+ ofnode subnode;
int ret;
data = calloc(1, sizeof(struct cpsw_platform_data));
pdata->priv_pdata = data;
- pdata->iobase = devfdt_get_addr(dev);
+ pdata->iobase = dev_read_addr(dev);
data->version = CPSW_CTRL_VERSION_2;
data->bd_ram_ofs = CPSW_BD_OFFSET;
data->ale_reg_ofs = CPSW_ALE_OFFSET;
@@ -1203,36 +1235,37 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
pdata->phy_interface = -1;
data->cpsw_base = pdata->iobase;
- data->channels = fdtdec_get_int(fdt, node, "cpdma_channels", -1);
- if (data->channels <= 0) {
+
+ ret = dev_read_s32(dev, "cpdma_channels", &data->channels);
+ if (ret) {
printf("error: cpdma_channels not found in dt\n");
- return -ENOENT;
+ return ret;
}
- data->slaves = fdtdec_get_int(fdt, node, "slaves", -1);
- if (data->slaves <= 0) {
+ ret = dev_read_s32(dev, "slaves", &data->slaves);
+ if (ret) {
printf("error: slaves not found in dt\n");
- return -ENOENT;
+ return ret;
}
data->slave_data = malloc(sizeof(struct cpsw_slave_data) *
data->slaves);
- data->ale_entries = fdtdec_get_int(fdt, node, "ale_entries", -1);
- if (data->ale_entries <= 0) {
+ ret = dev_read_s32(dev, "ale_entries", &data->ale_entries);
+ if (ret) {
printf("error: ale_entries not found in dt\n");
- return -ENOENT;
+ return ret;
}
- data->bd_ram_ofs = fdtdec_get_int(fdt, node, "bd_ram_size", -1);
- if (data->bd_ram_ofs <= 0) {
+ ret = dev_read_u32(dev, "bd_ram_size", &data->bd_ram_ofs);
+ if (ret) {
printf("error: bd_ram_size not found in dt\n");
- return -ENOENT;
+ return ret;
}
- data->mac_control = fdtdec_get_int(fdt, node, "mac_control", -1);
- if (data->mac_control <= 0) {
+ ret = dev_read_u32(dev, "mac_control", &data->mac_control);
+ if (ret) {
printf("error: ale_entries not found in dt\n");
- return -ENOENT;
+ return ret;
}
num_mode_gpios = gpio_get_list_count(dev, "mode-gpios");
@@ -1244,67 +1277,41 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
free(mode_gpios);
}
- active_slave = fdtdec_get_int(fdt, node, "active_slave", 0);
- data->active_slave = active_slave;
+ data->active_slave = dev_read_u32_default(dev, "active_slave", 0);
- fdt_for_each_subnode(subnode, fdt, node) {
- int len;
+ ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
const char *name;
- name = fdt_get_name(fdt, subnode, &len);
+ name = ofnode_get_name(subnode);
if (!strncmp(name, "mdio", 4)) {
- u32 mdio_base;
-
- mdio_base = cpsw_get_addr_by_node(fdt, subnode);
- if (mdio_base == FDT_ADDR_T_NONE) {
+ data->mdio_base = ofnode_get_addr(subnode);
+ if (data->mdio_base == FDT_ADDR_T_NONE) {
pr_err("Not able to get MDIO address space\n");
return -ENOENT;
}
- data->mdio_base = mdio_base;
}
if (!strncmp(name, "slave", 5)) {
- u32 phy_id[2];
-
if (slave_index >= data->slaves)
continue;
- phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL);
- if (phy_mode)
- data->slave_data[slave_index].phy_if =
- phy_get_interface_by_name(phy_mode);
-
- data->slave_data[slave_index].phy_of_handle =
- fdtdec_lookup_phandle(fdt, subnode,
- "phy-handle");
-
- if (data->slave_data[slave_index].phy_of_handle >= 0) {
- data->slave_data[slave_index].phy_addr =
- fdtdec_get_int(gd->fdt_blob,
- data->slave_data[slave_index].phy_of_handle,
- "reg", -1);
- } else {
- fdtdec_get_int_array(fdt, subnode, "phy_id",
- phy_id, 2);
- data->slave_data[slave_index].phy_addr =
- phy_id[1];
- }
+
+ cpsw_eth_of_parse_slave(data, slave_index, subnode);
slave_index++;
}
if (!strncmp(name, "cpsw-phy-sel", 12)) {
- data->gmii_sel = cpsw_get_addr_by_node(fdt, subnode);
+ data->gmii_sel = ofnode_get_addr(subnode);
if (data->gmii_sel == FDT_ADDR_T_NONE) {
pr_err("Not able to get gmii_sel reg address\n");
return -ENOENT;
}
- if (fdt_get_property(fdt, subnode, "rmii-clock-ext",
- NULL))
+ if (ofnode_read_bool(subnode, "rmii-clock-ext"))
data->rmii_clock_external = true;
- data->phy_sel_compat = fdt_getprop(fdt, subnode,
- "compatible", NULL);
+ data->phy_sel_compat = ofnode_read_string(subnode,
+ "compatible");
if (!data->phy_sel_compat) {
pr_err("Not able to get gmii_sel compatible\n");
return -ENOENT;
@@ -1320,15 +1327,16 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
data->slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
}
- ret = ti_cm_get_macid_addr(dev, active_slave, data);
+ ret = ti_cm_get_macid_addr(dev, data->active_slave, data);
if (ret < 0) {
pr_err("cpsw read efuse mac failed\n");
return ret;
}
- pdata->phy_interface = data->slave_data[active_slave].phy_if;
+ pdata->phy_interface = data->slave_data[data->active_slave].phy_if;
if (pdata->phy_interface == -1) {
- debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ debug("%s: Invalid PHY interface '%s'\n", __func__,
+ phy_string_for_interface(pdata->phy_interface));
return -EINVAL;
}
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index cff00820e48..75ccd657997 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -91,6 +91,13 @@ config RESET_ROCKCHIP
though is that some reset signals, like I2C or MISC reset multiple
devices.
+config RESET_HSDK
+ bool "Synopsys HSDK Reset Driver"
+ depends on DM_RESET && TARGET_HSDK
+ default y
+ help
+ This enables the reset controller driver for HSDK board.
+
config RESET_MESON
bool "Reset controller driver for Amlogic Meson SoCs"
depends on DM_RESET && ARCH_MESON
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 8102d8db291..0a044d5d8c8 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_STM32_RESET) += stm32-reset.o
obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
+obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c
new file mode 100644
index 00000000000..213d6c87be1
--- /dev/null
+++ b/drivers/reset/reset-hsdk.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * HSDK SoC Reset Controller driver
+ *
+ * Copyright (C) 2019 Synopsys, Inc. All rights reserved.
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <dm.h>
+#include <linux/iopoll.h>
+#include <reset-uclass.h>
+
+struct hsdk_rst {
+ void __iomem *regs_ctl;
+ void __iomem *regs_rst;
+};
+
+static const u32 rst_map[] = {
+ BIT(16), /* APB_RST */
+ BIT(17), /* AXI_RST */
+ BIT(18), /* ETH_RST */
+ BIT(19), /* USB_RST */
+ BIT(20), /* SDIO_RST */
+ BIT(21), /* HDMI_RST */
+ BIT(22), /* GFX_RST */
+ BIT(25), /* DMAC_RST */
+ BIT(31), /* EBI_RST */
+};
+
+#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map)
+
+#define CGU_SYS_RST_CTRL 0x0
+#define CGU_IP_SW_RESET 0x0
+#define CGU_IP_SW_RESET_DELAY_SHIFT 16
+#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
+#define CGU_IP_SW_RESET_DELAY 0
+#define CGU_IP_SW_RESET_RESET BIT(0)
+#define SW_RESET_TIMEOUT 10000
+
+static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id)
+{
+ writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
+}
+
+static int hsdk_reset_do(struct hsdk_rst *rst)
+{
+ u32 reg;
+
+ reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
+ reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
+ reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
+ reg |= CGU_IP_SW_RESET_RESET;
+ writel(reg, rst->regs_rst + CGU_IP_SW_RESET);
+
+ /* wait till reset bit is back to 0 */
+ return readl_poll_timeout(rst->regs_rst + CGU_IP_SW_RESET, reg,
+ !(reg & CGU_IP_SW_RESET_RESET), SW_RESET_TIMEOUT);
+}
+
+static int hsdk_reset_reset(struct reset_ctl *rst_ctl)
+{
+ struct udevice *dev = rst_ctl->dev;
+ struct hsdk_rst *rst = dev_get_priv(dev);
+
+ if (rst_ctl->id >= HSDK_MAX_RESETS)
+ return -EINVAL;
+
+ debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, rst_ctl,
+ rst_ctl->dev, rst_ctl->id);
+
+ hsdk_reset_config(rst, rst_ctl->id);
+ return hsdk_reset_do(rst);
+}
+
+static int hsdk_reset_noop(struct reset_ctl *rst_ctl)
+{
+ return 0;
+}
+
+static const struct reset_ops hsdk_reset_ops = {
+ .request = hsdk_reset_noop,
+ .free = hsdk_reset_noop,
+ .rst_assert = hsdk_reset_noop,
+ .rst_deassert = hsdk_reset_reset,
+};
+
+static const struct udevice_id hsdk_reset_dt_match[] = {
+ { .compatible = "snps,hsdk-reset" },
+ { },
+};
+
+static int hsdk_reset_probe(struct udevice *dev)
+{
+ struct hsdk_rst *rst = dev_get_priv(dev);
+
+ rst->regs_ctl = dev_remap_addr_index(dev, 0);
+ if (!rst->regs_ctl)
+ return -EINVAL;
+
+ rst->regs_rst = dev_remap_addr_index(dev, 1);
+ if (!rst->regs_rst)
+ return -EINVAL;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(hsdk_reset) = {
+ .name = "hsdk-reset",
+ .id = UCLASS_RESET,
+ .of_match = hsdk_reset_dt_match,
+ .ops = &hsdk_reset_ops,
+ .probe = hsdk_reset_probe,
+ .priv_auto_alloc_size = sizeof(struct hsdk_rst),
+};
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index 16473ec7a0b..6b610ff8231 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -122,11 +122,22 @@ static int sandbox_cs_info(struct udevice *bus, uint cs,
return 0;
}
+static int sandbox_spi_get_mmap(struct udevice *dev, ulong *map_basep,
+ uint *map_sizep, uint *offsetp)
+{
+ *map_basep = 0x1000;
+ *map_sizep = 0x2000;
+ *offsetp = 0x100;
+
+ return 0;
+}
+
static const struct dm_spi_ops sandbox_spi_ops = {
.xfer = sandbox_spi_xfer,
.set_speed = sandbox_spi_set_speed,
.set_mode = sandbox_spi_set_mode,
.cs_info = sandbox_cs_info,
+ .get_mmap = sandbox_spi_get_mmap,
};
static const struct udevice_id sandbox_spi_ids[] = {
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 947516073ea..665611f7e23 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -92,6 +92,20 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
}
+int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
+ uint *offsetp)
+{
+ struct udevice *bus = dev->parent;
+ struct dm_spi_ops *ops = spi_get_ops(bus);
+
+ if (bus->uclass->uc_drv->id != UCLASS_SPI)
+ return -EOPNOTSUPP;
+ if (!ops->get_mmap)
+ return -ENOSYS;
+
+ return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
+}
+
int spi_claim_bus(struct spi_slave *slave)
{
return log_ret(dm_spi_claim_bus(slave->dev));
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index 919caba8a14..637c8ff25a5 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -394,7 +394,7 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count)
static void tsc_timer_ensure_setup(bool early)
{
- if (gd->arch.tsc_base)
+ if (gd->arch.tsc_inited)
return;
gd->arch.tsc_base = rdtsc();
@@ -425,6 +425,7 @@ static void tsc_timer_ensure_setup(bool early)
done:
gd->arch.clock_rate = fast_calibrate * 1000000;
}
+ gd->arch.tsc_inited = true;
}
static int tsc_timer_probe(struct udevice *dev)
@@ -461,6 +462,8 @@ unsigned long notrace timer_early_get_rate(void)
u64 notrace timer_early_get_count(void)
{
+ tsc_timer_ensure_setup(true);
+
return rdtsc() - gd->arch.tsc_base;
}