diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ti/am65-cpsw-nuss.c | 2 | ||||
-rw-r--r-- | drivers/net/ti/cpsw.c | 154 | ||||
-rw-r--r-- | drivers/reset/Kconfig | 7 | ||||
-rw-r--r-- | drivers/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/reset/reset-hsdk.c | 116 | ||||
-rw-r--r-- | drivers/spi/sandbox_spi.c | 11 | ||||
-rw-r--r-- | drivers/spi/spi-uclass.c | 14 | ||||
-rw-r--r-- | drivers/timer/tsc_timer.c | 5 |
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; } |