summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/cache/Kconfig25
-rw-r--r--drivers/cache/Makefile4
-rw-r--r--drivers/cache/cache-l2x0.c76
-rw-r--r--drivers/cache/cache-uclass.c24
-rw-r--r--drivers/cache/sandbox_cache.c34
-rw-r--r--drivers/clk/rockchip/clk_rk3036.c6
-rw-r--r--drivers/clk/rockchip/clk_rk3128.c6
-rw-r--r--drivers/clk/rockchip/clk_rk3188.c8
-rw-r--r--drivers/clk/rockchip/clk_rk322x.c6
-rw-r--r--drivers/clk/rockchip/clk_rk3288.c8
-rw-r--r--drivers/clk/rockchip/clk_rk3328.c8
-rw-r--r--drivers/clk/rockchip/clk_rk3368.c6
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c6
-rw-r--r--drivers/clk/rockchip/clk_rv1108.c6
-rw-r--r--drivers/dma/ti/k3-udma.c35
-rw-r--r--drivers/firmware/ti_sci.c13
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/rk_gpio.c3
-rw-r--r--drivers/i2c/mvtwsi.c11
-rw-r--r--drivers/i2c/rk_i2c.c6
-rw-r--r--drivers/mmc/Kconfig20
-rw-r--r--drivers/mmc/dw_mmc.c38
-rw-r--r--drivers/mmc/fsl_esdhc.c41
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c4
-rw-r--r--drivers/mmc/sdhci.c188
-rw-r--r--drivers/mtd/nand/raw/davinci_nand.c39
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/gmac_rockchip.c18
-rw-r--r--drivers/net/mscc_eswitch/Kconfig7
-rw-r--r--drivers/net/mscc_eswitch/Makefile5
-rw-r--r--drivers/net/mscc_eswitch/luton_switch.c415
-rw-r--r--drivers/net/mscc_eswitch/ocelot_switch.c434
-rw-r--r--drivers/net/mscc_eswitch/serval_switch.c703
-rw-r--r--drivers/net/ti/davinci_emac.c55
-rw-r--r--drivers/pinctrl/pinctrl-uclass.c3
-rw-r--r--drivers/pwm/rk_pwm.c2
-rw-r--r--drivers/ram/rockchip/dmc-rk3368.c12
-rw-r--r--drivers/ram/rockchip/sdram_rk3128.c6
-rw-r--r--drivers/ram/rockchip/sdram_rk3188.c14
-rw-r--r--drivers/ram/rockchip/sdram_rk322x.c16
-rw-r--r--drivers/ram/rockchip/sdram_rk3288.c14
-rw-r--r--drivers/ram/rockchip/sdram_rk3328.c6
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c12
-rw-r--r--drivers/reset/reset-rockchip.c2
-rw-r--r--drivers/serial/serial_rockchip.c2
-rw-r--r--drivers/sound/rockchip_sound.c2
-rw-r--r--drivers/spi/Kconfig2
-rw-r--r--drivers/spi/rk_spi.c167
-rw-r--r--drivers/sysreset/sysreset_rockchip.c6
-rw-r--r--drivers/timer/rockchip_timer.c2
-rw-r--r--drivers/usb/gadget/f_rockusb.c2
-rw-r--r--drivers/usb/host/Kconfig5
-rw-r--r--drivers/usb/host/ohci-da8xx.c138
-rw-r--r--drivers/usb/host/ohci-hcd.c2
-rw-r--r--drivers/usb/musb/musb_hcd.c6
-rw-r--r--drivers/video/rockchip/rk3288_hdmi.c6
-rw-r--r--drivers/video/rockchip/rk3288_mipi.c10
-rw-r--r--drivers/video/rockchip/rk3288_vop.c6
-rw-r--r--drivers/video/rockchip/rk3399_hdmi.c6
-rw-r--r--drivers/video/rockchip/rk3399_mipi.c10
-rw-r--r--drivers/video/rockchip/rk3399_vop.c2
-rw-r--r--drivers/video/rockchip/rk_edp.c6
-rw-r--r--drivers/video/rockchip/rk_hdmi.c5
-rw-r--r--drivers/video/rockchip/rk_lvds.c6
-rw-r--r--drivers/video/rockchip/rk_mipi.c9
-rw-r--r--drivers/video/rockchip/rk_vop.c7
-rw-r--r--drivers/video/rockchip/rk_vop.h2
-rw-r--r--drivers/watchdog/Kconfig4
70 files changed, 2142 insertions, 623 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index e6702eced46..96ff4f566ab 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -14,6 +14,8 @@ source "drivers/block/Kconfig"
source "drivers/bootcount/Kconfig"
+source "drivers/cache/Kconfig"
+
source "drivers/clk/Kconfig"
source "drivers/cpu/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a7bba3ed564..0a00096332b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += block/
obj-y += board/
obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
+obj-y += cache/
obj-$(CONFIG_CPU) += cpu/
obj-y += crypto/
obj-$(CONFIG_FASTBOOT) += fastboot/
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
new file mode 100644
index 00000000000..24def7ac0fe
--- /dev/null
+++ b/drivers/cache/Kconfig
@@ -0,0 +1,25 @@
+#
+# Cache controllers
+#
+
+menu "Cache Controller drivers"
+
+config CACHE
+ bool "Enable Driver Model for Cache controllers"
+ depends on DM
+ help
+ Enable driver model for cache controllers that are found on
+ most CPU's. Cache is memory that the CPU can access directly and
+ is usually located on the same chip. This uclass can be used for
+ configuring settings that be found from a device tree file.
+
+config L2X0_CACHE
+ tristate "PL310 cache driver"
+ select CACHE
+ depends on ARM
+ help
+ This driver is for the PL310 cache controller commonly found on
+ ARMv7(32-bit) devices. The driver configures the cache settings
+ found in the device tree.
+
+endmenu
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
new file mode 100644
index 00000000000..9deb961d91f
--- /dev/null
+++ b/drivers/cache/Makefile
@@ -0,0 +1,4 @@
+
+obj-$(CONFIG_CACHE) += cache-uclass.o
+obj-$(CONFIG_SANDBOX) += sandbox_cache.o
+obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o
diff --git a/drivers/cache/cache-l2x0.c b/drivers/cache/cache-l2x0.c
new file mode 100644
index 00000000000..67c752d076f
--- /dev/null
+++ b/drivers/cache/cache-l2x0.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation <www.intel.com>
+ */
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+
+#include <asm/io.h>
+#include <asm/pl310.h>
+
+static void l2c310_of_parse_and_init(struct udevice *dev)
+{
+ u32 tag[3] = { 0, 0, 0 };
+ u32 saved_reg, prefetch;
+ struct pl310_regs *regs = (struct pl310_regs *)dev_read_addr(dev);
+
+ /* Disable the L2 Cache */
+ clrbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
+
+ saved_reg = readl(&regs->pl310_aux_ctrl);
+ if (!dev_read_u32(dev, "prefetch-data", &prefetch)) {
+ if (prefetch)
+ saved_reg |= L310_AUX_CTRL_DATA_PREFETCH_MASK;
+ else
+ saved_reg &= ~L310_AUX_CTRL_DATA_PREFETCH_MASK;
+ }
+
+ if (!dev_read_u32(dev, "prefetch-instr", &prefetch)) {
+ if (prefetch)
+ saved_reg |= L310_AUX_CTRL_INST_PREFETCH_MASK;
+ else
+ saved_reg &= ~L310_AUX_CTRL_INST_PREFETCH_MASK;
+ }
+
+ saved_reg |= dev_read_bool(dev, "arm,shared-override");
+ writel(saved_reg, &regs->pl310_aux_ctrl);
+
+ saved_reg = readl(&regs->pl310_tag_latency_ctrl);
+ if (!dev_read_u32_array(dev, "arm,tag-latency", tag, 3))
+ saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
+ L310_LATENCY_CTRL_WR(tag[1] - 1) |
+ L310_LATENCY_CTRL_SETUP(tag[2] - 1);
+ writel(saved_reg, &regs->pl310_tag_latency_ctrl);
+
+ saved_reg = readl(&regs->pl310_data_latency_ctrl);
+ if (!dev_read_u32_array(dev, "arm,data-latency", tag, 3))
+ saved_reg |= L310_LATENCY_CTRL_RD(tag[0] - 1) |
+ L310_LATENCY_CTRL_WR(tag[1] - 1) |
+ L310_LATENCY_CTRL_SETUP(tag[2] - 1);
+ writel(saved_reg, &regs->pl310_data_latency_ctrl);
+
+ /* Enable the L2 cache */
+ setbits_le32(&regs->pl310_ctrl, L2X0_CTRL_EN);
+}
+
+static int l2x0_probe(struct udevice *dev)
+{
+ l2c310_of_parse_and_init(dev);
+
+ return 0;
+}
+
+
+static const struct udevice_id l2x0_ids[] = {
+ { .compatible = "arm,pl310-cache" },
+ {}
+};
+
+U_BOOT_DRIVER(pl310_cache) = {
+ .name = "pl310_cache",
+ .id = UCLASS_CACHE,
+ .of_match = l2x0_ids,
+ .probe = l2x0_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/cache/cache-uclass.c b/drivers/cache/cache-uclass.c
new file mode 100644
index 00000000000..97ce0249a4a
--- /dev/null
+++ b/drivers/cache/cache-uclass.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <cache.h>
+#include <dm.h>
+
+int cache_get_info(struct udevice *dev, struct cache_info *info)
+{
+ struct cache_ops *ops = cache_get_ops(dev);
+
+ if (!ops->get_info)
+ return -ENOSYS;
+
+ return ops->get_info(dev, info);
+}
+
+UCLASS_DRIVER(cache) = {
+ .id = UCLASS_CACHE,
+ .name = "cache",
+ .post_bind = dm_scan_fdt_dev,
+};
diff --git a/drivers/cache/sandbox_cache.c b/drivers/cache/sandbox_cache.c
new file mode 100644
index 00000000000..14cc6b0c0ac
--- /dev/null
+++ b/drivers/cache/sandbox_cache.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <cache.h>
+#include <dm.h>
+#include <errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_get_info(struct udevice *dev, struct cache_info *info)
+{
+ info->base = 0x11223344;
+
+ return 0;
+}
+
+static const struct cache_ops sandbox_cache_ops = {
+ .get_info = sandbox_get_info,
+};
+
+static const struct udevice_id sandbox_cache_ids[] = {
+ { .compatible = "sandbox,cache" },
+ { }
+};
+
+U_BOOT_DRIVER(cache_sandbox) = {
+ .name = "cache_sandbox",
+ .id = UCLASS_CACHE,
+ .of_match = sandbox_cache_ids,
+ .ops = &sandbox_cache_ops,
+};
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 9c4e8901e80..9bf9cedaf8c 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -9,9 +9,9 @@
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3036.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3036.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3036-cru.h>
#include <linux/log2.h>
diff --git a/drivers/clk/rockchip/clk_rk3128.c b/drivers/clk/rockchip/clk_rk3128.c
index 7da785abc67..efda8c830b0 100644
--- a/drivers/clk/rockchip/clk_rk3128.c
+++ b/drivers/clk/rockchip/clk_rk3128.c
@@ -9,9 +9,9 @@
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3128.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3128.h>
+#include <asm/arch-rockchip/hardware.h>
#include <bitfield.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3128-cru.h>
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index db7479a2375..9bb9959c9d3 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -12,10 +12,10 @@
#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3188.h>
-#include <asm/arch/grf_rk3188.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3188.h>
+#include <asm/arch-rockchip/grf_rk3188.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dt-bindings/clock/rk3188-cru.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c
index 46a569c9ecd..48ed14b2aff 100644
--- a/drivers/clk/rockchip/clk_rk322x.c
+++ b/drivers/clk/rockchip/clk_rk322x.c
@@ -9,9 +9,9 @@
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk322x.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk322x.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3228-cru.h>
#include <linux/log2.h>
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index 930c99f4d9f..375d7f8acbb 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -13,10 +13,10 @@
#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index 106621fe7cf..a89e2ecc4ad 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -9,10 +9,10 @@
#include <dm.h>
#include <errno.h>
#include <syscon.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3328.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/grf_rk3328.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3328.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3328.h>
#include <asm/io.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3328-cru.h>
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
index 9492cc2a36e..89cbae59c5e 100644
--- a/drivers/clk/rockchip/clk_rk3368.c
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -13,9 +13,9 @@
#include <mapmem.h>
#include <syscon.h>
#include <bitfield.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3368.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3368.h>
+#include <asm/arch-rockchip/hardware.h>
#include <asm/io.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3368-cru.h>
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index cab2bd99433..93a652e5ff4 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -13,9 +13,9 @@
#include <syscon.h>
#include <bitfield.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3399.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3399-cru.h>
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
index 914e2f4b214..3ebb007fab3 100644
--- a/drivers/clk/rockchip/clk_rv1108.c
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -11,9 +11,9 @@
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rv1108.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1108.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rv1108-cru.h>
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index f78a01aa8f8..a5fc7809bc4 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -575,14 +575,6 @@ static int udma_get_tchan(struct udma_chan *uc)
pr_debug("chan%d: got tchan%d\n", uc->id, uc->tchan->id);
- if (udma_is_chan_running(uc)) {
- dev_warn(ud->dev, "chan%d: tchan%d is running!\n", uc->id,
- uc->tchan->id);
- udma_stop(uc);
- if (udma_is_chan_running(uc))
- dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
- }
-
return 0;
}
@@ -602,14 +594,6 @@ static int udma_get_rchan(struct udma_chan *uc)
pr_debug("chan%d: got rchan%d\n", uc->id, uc->rchan->id);
- if (udma_is_chan_running(uc)) {
- dev_warn(ud->dev, "chan%d: rchan%d is running!\n", uc->id,
- uc->rchan->id);
- udma_stop(uc);
- if (udma_is_chan_running(uc))
- dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
- }
-
return 0;
}
@@ -652,14 +636,6 @@ static int udma_get_chan_pair(struct udma_chan *uc)
pr_debug("chan%d: got t/rchan%d pair\n", uc->id, chan_id);
- if (udma_is_chan_running(uc)) {
- dev_warn(ud->dev, "chan%d: t/rchan%d pair is running!\n",
- uc->id, chan_id);
- udma_stop(uc);
- if (udma_is_chan_running(uc))
- dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
- }
-
return 0;
}
@@ -1071,6 +1047,15 @@ static int udma_alloc_chan_resources(struct udma_chan *uc)
}
}
+ if (udma_is_chan_running(uc)) {
+ dev_warn(ud->dev, "chan%d: is running!\n", uc->id);
+ udma_stop(uc);
+ if (udma_is_chan_running(uc)) {
+ dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+ goto err_free_res;
+ }
+ }
+
/* PSI-L pairing */
ret = udma_navss_psil_pair(ud, uc->src_thread, uc->dst_thread);
if (ret) {
@@ -1492,7 +1477,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata)
u32 tc_ring_id;
int ret;
- if (!metadata)
+ if (metadata)
packet_data = *((struct ti_udma_drv_packet_data *)metadata);
if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 1196ce07123..303aa6a6311 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -158,7 +158,7 @@ static inline int ti_sci_get_response(struct ti_sci_info *info,
int ret;
/* Receive the response */
- ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_ms);
+ ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_ms * 1000);
if (ret) {
dev_err(info->dev, "%s: Message receive failed. ret = %d\n",
__func__, ret);
@@ -257,7 +257,8 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
info = handle_to_ti_sci_info(handle);
- xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION, 0x0,
+ xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
(u32 *)&hdr, sizeof(struct ti_sci_msg_hdr),
sizeof(*rev_info));
if (IS_ERR(xfer)) {
@@ -499,8 +500,8 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
info = handle_to_ti_sci_info(handle);
- /* Response is expected, so need of any flags */
- xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE, 0,
+ xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
@@ -2574,8 +2575,8 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
info = handle_to_ti_sci_info(handle);
- xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET,
- TISCI_MSG_FWL_CHANGE_OWNER,
+ xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_CHANGE_OWNER,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
(u32 *)&req, sizeof(req), sizeof(*resp));
if (IS_ERR(xfer)) {
ret = PTR_ERR(xfer);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b3e4ecc50e1..684ca9d868f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -351,7 +351,7 @@ config MPC8XXX_GPIO
config MT7621_GPIO
bool "MediaTek MT7621 GPIO driver"
- depends on DM_GPIO && ARCH_MT7620
+ depends on DM_GPIO && SOC_MT7628
default y
help
Say yes here to support MediaTek MT7621 compatible GPIOs.
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 21df2277176..3d96678a45a 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -12,7 +12,8 @@
#include <linux/errno.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/gpio.h>
#include <dm/pinctrl.h>
#include <dt-bindings/clock/rk3288-cru.h>
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 74ac0a4aa78..0a2dafcec6c 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -271,6 +271,17 @@ static int twsi_wait(struct mvtwsi_registers *twsi, int expected_status,
do {
control = readl(&twsi->control);
if (control & MVTWSI_CONTROL_IFLG) {
+ /*
+ * On Armada 38x it seems that the controller works as
+ * if it first set the MVTWSI_CONTROL_IFLAG in the
+ * control register and only after that it changed the
+ * status register.
+ * This sometimes caused weird bugs which only appeared
+ * on selected I2C speeds and even then only sometimes.
+ * We therefore add here a simple ndealy(100), which
+ * seems to fix this weird bug.
+ */
+ ndelay(100);
status = readl(&twsi->status);
if (status == expected_status)
return 0;
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index f9a5796b96b..cdd94bb05a9 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -12,9 +12,9 @@
#include <errno.h>
#include <i2c.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/i2c.h>
-#include <asm/arch/periph.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/i2c.h>
+#include <asm/arch-rockchip/periph.h>
#include <dm/pinctrl.h>
#include <linux/sizes.h>
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index c34dd5d1879..c23299ea962 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -78,6 +78,12 @@ config SUPPORT_EMMC_RPMB
Enable support for reading, writing and programming the
key for the Replay Protection Memory Block partition in eMMC.
+config SUPPORT_EMMC_BOOT
+ bool "Support some additional features of the eMMC boot partitions"
+ help
+ Enable support for eMMC boot partitions. This also enables
+ extensions within the mmc command.
+
config MMC_IO_VOLTAGE
bool "Support IO voltage configuration"
help
@@ -385,6 +391,20 @@ config MMC_SDHCI_SDMA
This enables support for the SDMA (Single Operation DMA) defined
in the SD Host Controller Standard Specification Version 1.00 .
+config MMC_SDHCI_ADMA
+ bool "Support SDHCI ADMA2"
+ depends on MMC_SDHCI
+ help
+ This enables support for the ADMA (Advanced DMA) defined
+ in the SD Host Controller Standard Specification Version 3.00
+
+config SPL_MMC_SDHCI_ADMA
+ bool "Support SDHCI ADMA2 in SPL"
+ depends on MMC_SDHCI
+ help
+ This enables support for the ADMA (Advanced DMA) defined
+ in the SD Host Controller Standard Specification Version 3.00 in SPL.
+
config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 93a836eac36..1992d611821 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -74,15 +74,15 @@ static void dwmci_prepare_data(struct dwmci_host *host,
dwmci_set_idma_desc(cur_idmac, flags, cnt,
(ulong)bounce_buffer + (i * PAGE_SIZE));
+ cur_idmac++;
if (blk_cnt <= 8)
break;
blk_cnt -= 8;
- cur_idmac++;
i++;
} while(1);
data_end = (ulong)cur_idmac;
- flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
+ flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN));
ctrl = dwmci_readl(host, DWMCI_CTRL);
ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
@@ -114,22 +114,40 @@ static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
return 0;
}
+static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
+{
+ unsigned int timeout;
+
+ timeout = size * 8 * 1000; /* counting in bits and msec */
+ timeout *= 2; /* wait twice as long */
+ timeout /= mmc->clock;
+ timeout /= mmc->bus_width;
+ timeout /= mmc->ddr_mode ? 2 : 1;
+ timeout = (timeout < 1000) ? 1000 : timeout;
+
+ return timeout;
+}
+
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
{
+ struct mmc *mmc = host->mmc;
int ret = 0;
- u32 timeout = 240000;
- u32 mask, size, i, len = 0;
+ u32 timeout, mask, size, i, len = 0;
u32 *buf = NULL;
ulong start = get_timer(0);
u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
RX_WMARK_SHIFT) + 1) * 2;
- size = data->blocksize * data->blocks / 4;
+ size = data->blocksize * data->blocks;
if (data->flags == MMC_DATA_READ)
buf = (unsigned int *)data->dest;
else
buf = (unsigned int *)data->src;
+ timeout = dwmci_get_timeout(mmc, size);
+
+ size /= 4;
+
for (;;) {
mask = dwmci_readl(host, DWMCI_RINTSTS);
/* Error during data transfer. */
@@ -252,14 +270,20 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
} else {
if (data->flags == MMC_DATA_READ) {
- bounce_buffer_start(&bbstate, (void*)data->dest,
+ ret = bounce_buffer_start(&bbstate,
+ (void*)data->dest,
data->blocksize *
data->blocks, GEN_BB_WRITE);
} else {
- bounce_buffer_start(&bbstate, (void*)data->src,
+ ret = bounce_buffer_start(&bbstate,
+ (void*)data->src,
data->blocksize *
data->blocks, GEN_BB_READ);
}
+
+ if (ret)
+ return ret;
+
dwmci_prepare_data(host, data, cur_idmac,
bbstate.bounce_buffer);
}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 9e34557d165..1b7de74a72d 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -297,6 +297,13 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
return -ETIMEDOUT;
}
+ } else {
+#ifdef CONFIG_DM_GPIO
+ if (dm_gpio_is_valid(&priv->wp_gpio) && dm_gpio_get_value(&priv->wp_gpio)) {
+ printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
+ return -ETIMEDOUT;
+ }
+#endif
}
esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
@@ -614,18 +621,31 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
#else
int pre_div = 2;
#endif
- int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
int sdhc_clk = priv->sdhc_clk;
uint clk;
+ /*
+ * For ddr mode, usdhc need to enable DDR mode first, after select
+ * this DDR mode, usdhc will automatically divide the usdhc clock
+ */
+ if (mmc->ddr_mode) {
+ writel(readl(&regs->mixctrl) | MIX_CTRL_DDREN, &regs->mixctrl);
+ sdhc_clk >>= 1;
+ }
+
if (clock < mmc->cfg->f_min)
clock = mmc->cfg->f_min;
- while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
- pre_div *= 2;
+ if (sdhc_clk / 16 > clock) {
+ for (; pre_div < 256; pre_div *= 2)
+ if ((sdhc_clk / pre_div) <= (clock * 16))
+ break;
+ } else
+ pre_div = 1;
- while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div < 16)
- div++;
+ for (div = 1; div <= 16; div++)
+ if ((sdhc_clk / (div * pre_div)) <= clock)
+ break;
pre_div >>= 1;
div -= 1;
@@ -1489,14 +1509,15 @@ static int fsl_esdhc_probe(struct udevice *dev)
#endif
}
- priv->wp_enable = 1;
-
+ if (dev_read_prop(dev, "fsl,wp-controller", NULL)) {
+ priv->wp_enable = 1;
+ } else {
+ priv->wp_enable = 0;
#ifdef CONFIG_DM_GPIO
- ret = gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
+ gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
GPIOD_IS_IN);
- if (ret)
- priv->wp_enable = 0;
#endif
+ }
priv->vs18_enable = 0;
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index bf2d83a52c5..b2a1201631a 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -13,8 +13,8 @@
#include <pwrseq.h>
#include <syscon.h>
#include <asm/gpio.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/periph.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/periph.h>
#include <linux/err.h>
struct rockchip_mmc_plat {
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index cdeba914f95..e2bb90abbdf 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -67,17 +67,123 @@ static void sdhci_transfer_pio(struct sdhci_host *host, struct mmc_data *data)
}
}
-static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
- unsigned int start_addr)
+#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
+static void sdhci_adma_desc(struct sdhci_host *host, char *buf, u16 len,
+ bool end)
+{
+ struct sdhci_adma_desc *desc;
+ u8 attr;
+
+ desc = &host->adma_desc_table[host->desc_slot];
+
+ attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
+ if (!end)
+ host->desc_slot++;
+ else
+ attr |= ADMA_DESC_ATTR_END;
+
+ desc->attr = attr;
+ desc->len = len;
+ desc->reserved = 0;
+ desc->addr_lo = (dma_addr_t)buf;
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+ desc->addr_hi = (u64)buf >> 32;
+#endif
+}
+
+static void sdhci_prepare_adma_table(struct sdhci_host *host,
+ struct mmc_data *data)
+{
+ uint trans_bytes = data->blocksize * data->blocks;
+ uint desc_count = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN);
+ int i = desc_count;
+ char *buf;
+
+ host->desc_slot = 0;
+
+ if (data->flags & MMC_DATA_READ)
+ buf = data->dest;
+ else
+ buf = (char *)data->src;
+
+ while (--i) {
+ sdhci_adma_desc(host, buf, ADMA_MAX_LEN, false);
+ buf += ADMA_MAX_LEN;
+ trans_bytes -= ADMA_MAX_LEN;
+ }
+
+ sdhci_adma_desc(host, buf, trans_bytes, true);
+
+ flush_cache((dma_addr_t)host->adma_desc_table,
+ ROUND(desc_count * sizeof(struct sdhci_adma_desc),
+ ARCH_DMA_MINALIGN));
+}
+#elif defined(CONFIG_MMC_SDHCI_SDMA)
+static void sdhci_prepare_adma_table(struct sdhci_host *host,
+ struct mmc_data *data)
+{}
+#endif
+#if (defined(CONFIG_MMC_SDHCI_SDMA) || CONFIG_IS_ENABLED(MMC_SDHCI_ADMA))
+static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
+ int *is_aligned, int trans_bytes)
{
- unsigned int stat, rdy, mask, timeout, block = 0;
- bool transfer_done = false;
-#ifdef CONFIG_MMC_SDHCI_SDMA
unsigned char ctrl;
+
+ if (data->flags == MMC_DATA_READ)
+ host->start_addr = (dma_addr_t)data->dest;
+ else
+ host->start_addr = (dma_addr_t)data->src;
+
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_DMA_MASK;
+ if (host->flags & USE_ADMA64)
+ ctrl |= SDHCI_CTRL_ADMA64;
+ else if (host->flags & USE_ADMA)
+ ctrl |= SDHCI_CTRL_ADMA32;
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
+ if (host->flags & USE_SDMA) {
+ if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
+ (host->start_addr & 0x7) != 0x0) {
+ *is_aligned = 0;
+ host->start_addr = (unsigned long)aligned_buffer;
+ if (data->flags != MMC_DATA_READ)
+ memcpy(aligned_buffer, data->src, trans_bytes);
+ }
+
+#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
+ /*
+ * Always use this bounce-buffer when
+ * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
+ */
+ *is_aligned = 0;
+ host->start_addr = (unsigned long)aligned_buffer;
+ if (data->flags != MMC_DATA_READ)
+ memcpy(aligned_buffer, data->src, trans_bytes);
+#endif
+ sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
+
+ } else if (host->flags & (USE_ADMA | USE_ADMA64)) {
+ sdhci_prepare_adma_table(host, data);
+
+ sdhci_writel(host, (u32)host->adma_addr, SDHCI_ADMA_ADDRESS);
+ if (host->flags & USE_ADMA64)
+ sdhci_writel(host, (u64)host->adma_addr >> 32,
+ SDHCI_ADMA_ADDRESS_HI);
+ }
+
+ flush_cache(host->start_addr, ROUND(trans_bytes, ARCH_DMA_MINALIGN));
+}
+#else
+static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
+ int *is_aligned, int trans_bytes)
+{}
#endif
+static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data)
+{
+ dma_addr_t start_addr = host->start_addr;
+ unsigned int stat, rdy, mask, timeout, block = 0;
+ bool transfer_done = false;
timeout = 1000000;
rdy = SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL;
@@ -104,14 +210,17 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
continue;
}
}
-#ifdef CONFIG_MMC_SDHCI_SDMA
- if (!transfer_done && (stat & SDHCI_INT_DMA_END)) {
+ if ((host->flags & USE_DMA) && !transfer_done &&
+ (stat & SDHCI_INT_DMA_END)) {
sdhci_writel(host, SDHCI_INT_DMA_END, SDHCI_INT_STATUS);
- start_addr &= ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
- start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
- sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
+ if (host->flags & USE_SDMA) {
+ start_addr &=
+ ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
+ start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
+ sdhci_writel(host, start_addr,
+ SDHCI_DMA_ADDRESS);
+ }
}
-#endif
if (timeout-- > 0)
udelay(10);
else {
@@ -149,10 +258,11 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
int ret = 0;
int trans_bytes = 0, is_aligned = 1;
u32 mask, flags, mode;
- unsigned int time = 0, start_addr = 0;
+ unsigned int time = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
ulong start = get_timer(0);
+ host->start_addr = 0;
/* Timeout unit - ms */
static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
@@ -218,33 +328,11 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
if (data->flags == MMC_DATA_READ)
mode |= SDHCI_TRNS_READ;
-#ifdef CONFIG_MMC_SDHCI_SDMA
- if (data->flags == MMC_DATA_READ)
- start_addr = (unsigned long)data->dest;
- else
- start_addr = (unsigned long)data->src;
- if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
- (start_addr & 0x7) != 0x0) {
- is_aligned = 0;
- start_addr = (unsigned long)aligned_buffer;
- if (data->flags != MMC_DATA_READ)
- memcpy(aligned_buffer, data->src, trans_bytes);
+ if (host->flags & USE_DMA) {
+ mode |= SDHCI_TRNS_DMA;
+ sdhci_prepare_dma(host, data, &is_aligned, trans_bytes);
}
-#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
- /*
- * Always use this bounce-buffer when
- * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
- */
- is_aligned = 0;
- start_addr = (unsigned long)aligned_buffer;
- if (data->flags != MMC_DATA_READ)
- memcpy(aligned_buffer, data->src, trans_bytes);
-#endif
-
- sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
- mode |= SDHCI_TRNS_DMA;
-#endif
sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
data->blocksize),
SDHCI_BLOCK_SIZE);
@@ -255,12 +343,6 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
}
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
-#ifdef CONFIG_MMC_SDHCI_SDMA
- if (data) {
- trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
- flush_cache(start_addr, trans_bytes);
- }
-#endif
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
start = get_timer(0);
do {
@@ -286,7 +368,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
ret = -1;
if (!ret && data)
- ret = sdhci_transfer_data(host, data, start_addr);
+ ret = sdhci_transfer_data(host, data);
if (host->quirks & SDHCI_QUIRK_WAIT_SEND_CMD)
udelay(1000);
@@ -570,6 +652,24 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
__func__);
return -EINVAL;
}
+
+ host->flags |= USE_SDMA;
+#endif
+#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
+ if (!(caps & SDHCI_CAN_DO_ADMA2)) {
+ printf("%s: Your controller doesn't support SDMA!!\n",
+ __func__);
+ return -EINVAL;
+ }
+ host->adma_desc_table = (struct sdhci_adma_desc *)
+ memalign(ARCH_DMA_MINALIGN, ADMA_TABLE_SZ);
+
+ host->adma_addr = (dma_addr_t)host->adma_desc_table;
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+ host->flags |= USE_ADMA64;
+#else
+ host->flags |= USE_ADMA;
+#endif
#endif
if (host->quirks & SDHCI_QUIRK_REG32_RW)
host->version =
diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c
index e6a84a52b42..cfa9b535c8a 100644
--- a/drivers/mtd/nand/raw/davinci_nand.c
+++ b/drivers/mtd/nand/raw/davinci_nand.c
@@ -730,43 +730,6 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd)
return __raw_readl(&davinci_emif_regs->nandfsr) & 0x1;
}
-static void nand_flash_init(void)
-{
- /* This is for DM6446 EVM and *very* similar. DO NOT GROW THIS!
- * Instead, have your board_init() set EMIF timings, based on its
- * knowledge of the clocks and what devices are hooked up ... and
- * don't even do that unless no UBL handled it.
- */
-#ifdef CONFIG_SOC_DM644X
- u_int32_t acfg1 = 0x3ffffffc;
-
- /*------------------------------------------------------------------*
- * NAND FLASH CHIP TIMEOUT @ 459 MHz *
- * *
- * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz *
- * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns *
- * *
- *------------------------------------------------------------------*/
- acfg1 = 0
- | (0 << 31) /* selectStrobe */
- | (0 << 30) /* extWait */
- | (1 << 26) /* writeSetup 10 ns */
- | (3 << 20) /* writeStrobe 40 ns */
- | (1 << 17) /* writeHold 10 ns */
- | (1 << 13) /* readSetup 10 ns */
- | (5 << 7) /* readStrobe 60 ns */
- | (1 << 4) /* readHold 10 ns */
- | (3 << 2) /* turnAround ?? ns */
- | (0 << 0) /* asyncSize 8-bit bus */
- ;
-
- __raw_writel(acfg1, &davinci_emif_regs->ab1cr); /* CS2 */
-
- /* NAND flash on CS2 */
- __raw_writel(0x00000101, &davinci_emif_regs->nandfcr);
-#endif
-}
-
void davinci_nand_init(struct nand_chip *nand)
{
#if defined CONFIG_KEYSTONE_RBL_NAND
@@ -820,8 +783,6 @@ void davinci_nand_init(struct nand_chip *nand)
nand->write_buf = nand_davinci_write_buf;
nand->dev_ready = nand_davinci_dev_ready;
-
- nand_flash_init();
}
int board_nand_init(struct nand_chip *chip) __attribute__((weak));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 6e436b56abf..64cdc58f92c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -269,7 +269,7 @@ config MACB_ZYNQ
config MT7628_ETH
bool "MediaTek MT7628 Ethernet Interface"
- depends on ARCH_MT7620
+ depends on SOC_MT7628
help
The MediaTek MT7628 ethernet interface is used on MT7628 and
MT7688 based boards.
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index c01ae758c76..26a61211750 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -11,15 +11,15 @@
#include <phy.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/periph.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/grf_rk322x.h>
-#include <asm/arch/grf_rk3288.h>
-#include <asm/arch/grf_rk3328.h>
-#include <asm/arch/grf_rk3368.h>
-#include <asm/arch/grf_rk3399.h>
-#include <asm/arch/grf_rv1108.h>
+#include <asm/arch-rockchip/periph.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk322x.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3328.h>
+#include <asm/arch-rockchip/grf_rk3368.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/grf_rv1108.h>
#include <dm/pinctrl.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include "designware.h"
diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
index 6359d0b6101..80dd22f98b7 100644
--- a/drivers/net/mscc_eswitch/Kconfig
+++ b/drivers/net/mscc_eswitch/Kconfig
@@ -29,3 +29,10 @@ config MSCC_SERVALT_SWITCH
select PHYLIB
help
This driver supports the Servalt network switch device.
+
+config MSCC_SERVAL_SWITCH
+ bool "Serval switch driver"
+ depends on DM_ETH && ARCH_MSCC
+ select PHYLIB
+ help
+ This driver supports the Serval network switch device.
diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index bffd8ec77b0..02f39a76bb0 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -1,5 +1,6 @@
-obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
-obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
+obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_xfer.o mscc_mac_table.o
+obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o
obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o
+obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o
diff --git a/drivers/net/mscc_eswitch/luton_switch.c b/drivers/net/mscc_eswitch/luton_switch.c
index 6667614966d..94852b06e74 100644
--- a/drivers/net/mscc_eswitch/luton_switch.c
+++ b/drivers/net/mscc_eswitch/luton_switch.c
@@ -15,10 +15,21 @@
#include <net.h>
#include <wait_bit.h>
-#include "mscc_miim.h"
#include "mscc_xfer.h"
#include "mscc_mac_table.h"
+#define GCB_MIIM_MII_STATUS 0x0
+#define GCB_MIIM_STAT_BUSY BIT(3)
+#define GCB_MIIM_MII_CMD 0x8
+#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
+#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
+#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
+#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
+#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
+#define GCB_MIIM_MII_CMD_VLD BIT(31)
+#define GCB_MIIM_DATA 0xC
+#define GCB_MIIM_DATA_ERROR (0x2 << 16)
+
#define ANA_PORT_VLAN_CFG(x) (0x00 + 0x80 * (x))
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
#define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18)
@@ -136,61 +147,53 @@
#define PGID_UNICAST 29
#define PGID_SRC 80
-enum luton_target {
- PORT0,
- PORT1,
- PORT2,
- PORT3,
- PORT4,
- PORT5,
- PORT6,
- PORT7,
- PORT8,
- PORT9,
- PORT10,
- PORT11,
- PORT12,
- PORT13,
- PORT14,
- PORT15,
- PORT16,
- PORT17,
- PORT18,
- PORT19,
- PORT20,
- PORT21,
- PORT22,
- PORT23,
- SYS,
+static const char * const regs_names[] = {
+ "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
+ "port8", "port9", "port10", "port11", "port12", "port13", "port14",
+ "port15", "port16", "port17", "port18", "port19", "port20", "port21",
+ "port22", "port23",
+ "sys", "ana", "rew", "gcb", "qs", "hsio",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 24
+
+enum luton_ctrl_regs {
+ SYS = MAX_PORT,
ANA,
REW,
GCB,
QS,
- HSIO,
- TARGET_MAX,
+ HSIO
};
-#define MAX_PORT (PORT23 - PORT0 + 1)
+#define MIN_INT_PORT 0
+#define PORT10 10
+#define PORT11 11
+#define MAX_INT_PORT 12
+#define MIN_EXT_PORT MAX_INT_PORT
+#define MAX_EXT_PORT MAX_PORT
-#define MIN_INT_PORT PORT0
-#define MAX_INT_PORT (PORT11 - PORT0 + 1)
-#define MIN_EXT_PORT PORT12
-#define MAX_EXT_PORT MAX_PORT
+#define LUTON_MIIM_BUS_COUNT 2
-enum luton_mdio_target {
- MIIM,
- TARGET_MDIO_MAX,
+struct luton_phy_port_t {
+ size_t phy_addr;
+ struct mii_dev *bus;
+ u8 serdes_index;
+ u8 phy_mode;
};
-enum luton_phy_id {
- INTERNAL,
- EXTERNAL,
- NUM_PHY,
+struct luton_private {
+ void __iomem *regs[REGS_NAMES_COUNT];
+ struct mii_dev *bus[LUTON_MIIM_BUS_COUNT];
+ struct luton_phy_port_t ports[MAX_PORT];
};
-struct luton_private {
- void __iomem *regs[TARGET_MAX];
- struct mii_dev *bus[NUM_PHY];
+struct mscc_miim_dev {
+ void __iomem *regs;
+ phys_addr_t miim_base;
+ unsigned long miim_size;
+ struct mii_dev *bus;
};
static const unsigned long luton_regs_qs[] = {
@@ -207,53 +210,85 @@ static const unsigned long luton_regs_ana_table[] = {
[MSCC_ANA_TABLES_MACACCESS] = 0x11b8,
};
-static struct mscc_miim_dev miim[NUM_PHY];
+static struct mscc_miim_dev miim[LUTON_MIIM_BUS_COUNT];
+static int miim_count = -1;
-static struct mii_dev *luton_mdiobus_init(struct udevice *dev,
- int mdiobus_id)
+static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
+{
+ return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
+ GCB_MIIM_STAT_BUSY, false, 250, false);
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ u32 val;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+ miim->regs + GCB_MIIM_MII_CMD);
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ val = readl(miim->regs + GCB_MIIM_DATA);
+ if (val & GCB_MIIM_DATA_ERROR) {
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = val & 0xFFFF;
+ out:
+ return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret < 0)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+ GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+ out:
+ return ret;
+}
+
+static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
+ unsigned long miim_size)
{
- unsigned long phy_size[NUM_PHY];
- phys_addr_t phy_base[NUM_PHY];
- struct ofnode_phandle_args phandle;
- ofnode eth_node, node, mdio_node;
- struct resource res;
struct mii_dev *bus;
- fdt32_t faddr;
- int i;
bus = mdio_alloc();
if (!bus)
return NULL;
- /* gather only the first mdio bus */
- eth_node = dev_read_first_subnode(dev);
- node = ofnode_first_subnode(eth_node);
- ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
- &phandle);
- mdio_node = ofnode_get_parent(phandle.node);
-
- for (i = 0; i < TARGET_MDIO_MAX; i++) {
- if (ofnode_read_resource(mdio_node, i, &res)) {
- pr_err("%s: get OF resource failed\n", __func__);
- return NULL;
- }
-
- faddr = cpu_to_fdt32(res.start);
- phy_base[i] = ofnode_translate_address(mdio_node, &faddr);
- phy_size[i] = res.end - res.start;
- }
+ ++miim_count;
+ sprintf(bus->name, "miim-bus%d", miim_count);
- strcpy(bus->name, "miim-internal");
- miim[mdiobus_id].regs = ioremap(phy_base[mdiobus_id],
- phy_size[mdiobus_id]);
- bus->priv = &miim[mdiobus_id];
+ miim[miim_count].regs = ioremap(miim_base, miim_size);
+ miim[miim_count].miim_base = miim_base;
+ miim[miim_count].miim_size = miim_size;
+ bus->priv = &miim[miim_count];
bus->read = mscc_miim_read;
bus->write = mscc_miim_write;
if (mdio_register(bus))
return NULL;
- else
- return bus;
+
+ miim[miim_count].bus = bus;
+ return bus;
}
static void luton_stop(struct udevice *dev)
@@ -324,10 +359,10 @@ static void luton_gmii_port_init(struct luton_private *priv, int port)
writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
ANA_PORT_VLAN_CFG_POP_CNT(1) |
MAC_VID,
- priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0));
+ priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
/* Enable switching to/from port */
- setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0),
+ setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
SYS_SWITCH_PORT_MODE_PORT_ENA);
}
@@ -346,10 +381,10 @@ static void luton_port_init(struct luton_private *priv, int port)
writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
ANA_PORT_VLAN_CFG_POP_CNT(1) |
MAC_VID,
- priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0));
+ priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
/* Enable switching to/from port */
- setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0),
+ setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
SYS_SWITCH_PORT_MODE_PORT_ENA);
}
@@ -393,35 +428,34 @@ static void luton_ext_port_init(struct luton_private *priv, int port)
writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
ANA_PORT_VLAN_CFG_POP_CNT(1) |
MAC_VID,
- priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0));
+ priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
/* Enable switching to/from port */
- setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port - PORT0),
+ setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
SYS_SWITCH_PORT_MODE_PORT_ENA);
}
-static void serdes6g_write(struct luton_private *priv, u32 addr)
+static void serdes6g_write(void __iomem *base, u32 addr)
{
u32 data;
writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
HSIO_MCB_SERDES6G_CFG_ADDR(addr),
- priv->regs[HSIO] + HSIO_MCB_SERDES6G_CFG);
+ base + HSIO_MCB_SERDES6G_CFG);
do {
- data = readl(priv->regs[HSIO] + HSIO_MCB_SERDES6G_CFG);
+ data = readl(base + HSIO_MCB_SERDES6G_CFG);
} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
-
- mdelay(100);
}
-static void serdes6g_cfg(struct luton_private *priv)
+static void serdes6g_setup(void __iomem *base, uint32_t addr,
+ phy_interface_t interface)
{
writel(HSIO_RCOMP_CFG_CFG0_MODE_SEL(0x3) |
HSIO_RCOMP_CFG_CFG0_RUN_CAL,
- priv->regs[HSIO] + HSIO_RCOMP_CFG_CFG0);
+ base + HSIO_RCOMP_CFG_CFG0);
- while (readl(priv->regs[HSIO] + HSIO_RCOMP_STATUS) &
+ while (readl(base + HSIO_RCOMP_STATUS) &
HSIO_RCOMP_STATUS_BUSY)
;
@@ -430,50 +464,64 @@ static void serdes6g_cfg(struct luton_private *priv)
HSIO_SERDES6G_ANA_CFG_OB_CFG_POST0(0x10) |
HSIO_SERDES6G_ANA_CFG_OB_CFG_POL |
HSIO_SERDES6G_ANA_CFG_OB_CFG_ENA1V_MODE,
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_OB_CFG);
+ base + HSIO_SERDES6G_ANA_CFG_OB_CFG);
writel(HSIO_SERDES6G_ANA_CFG_OB_CFG1_LEV(0x18) |
HSIO_SERDES6G_ANA_CFG_OB_CFG1_ENA_CAS(0x1),
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_OB_CFG1);
+ base + HSIO_SERDES6G_ANA_CFG_OB_CFG1);
writel(HSIO_SERDES6G_ANA_CFG_IB_CFG_RESISTOR_CTRL(0xc) |
HSIO_SERDES6G_ANA_CFG_IB_CFG_VBCOM(0x4) |
HSIO_SERDES6G_ANA_CFG_IB_CFG_VBAC(0x5) |
HSIO_SERDES6G_ANA_CFG_IB_CFG_RT(0xf) |
HSIO_SERDES6G_ANA_CFG_IB_CFG_RF(0x4),
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG);
+ base + HSIO_SERDES6G_ANA_CFG_IB_CFG);
writel(HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST |
HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSDC |
HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSAC |
HSIO_SERDES6G_ANA_CFG_IB_CFG1_ANEG_MODE |
HSIO_SERDES6G_ANA_CFG_IB_CFG1_CHF |
HSIO_SERDES6G_ANA_CFG_IB_CFG1_C(0x4),
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG1);
+ base + HSIO_SERDES6G_ANA_CFG_IB_CFG1);
writel(HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_ANA(0x5) |
HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_HYST(0x5) |
HSIO_SERDES6G_ANA_CFG_DES_CFG_MBTR_CTRL(0x2) |
HSIO_SERDES6G_ANA_CFG_DES_CFG_PHS_CTRL(0x6),
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_DES_CFG);
+ base + HSIO_SERDES6G_ANA_CFG_DES_CFG);
writel(HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_ENA |
HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_CTRL_DATA(0x78),
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_PLL_CFG);
+ base + HSIO_SERDES6G_ANA_CFG_PLL_CFG);
writel(HSIO_SERDES6G_ANA_CFG_COMMON_CFG_IF_MODE(0x30) |
HSIO_SERDES6G_ANA_CFG_COMMON_CFG_ENA_LANE,
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
+ base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
/*
* There are 4 serdes6g, configure all except serdes6g0, therefore
* the address is b1110
*/
- serdes6g_write(priv, 0xe);
+ serdes6g_write(base, addr);
- writel(readl(priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG) |
+ writel(readl(base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG) |
HSIO_SERDES6G_ANA_CFG_COMMON_CFG_SYS_RST,
- priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
- serdes6g_write(priv, 0xe);
+ base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
+ serdes6g_write(base, addr);
- clrbits_le32(priv->regs[HSIO] + HSIO_SERDES6G_ANA_CFG_IB_CFG1,
+ clrbits_le32(base + HSIO_SERDES6G_ANA_CFG_IB_CFG1,
HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST);
writel(HSIO_SERDES6G_DIG_CFG_MISC_CFG_LANE_RST,
- priv->regs[HSIO] + HSIO_SERDES6G_DIG_CFG_MISC_CFG);
- serdes6g_write(priv, 0xe);
+ base + HSIO_SERDES6G_DIG_CFG_MISC_CFG);
+ serdes6g_write(base, addr);
+}
+
+static void serdes_setup(struct luton_private *priv)
+{
+ size_t mask;
+ int i = 0;
+
+ for (i = 0; i < MAX_PORT; ++i) {
+ if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
+ continue;
+
+ mask = BIT(priv->ports[i].serdes_index);
+ serdes6g_setup(priv->regs[HSIO], mask, priv->ports[i].phy_mode);
+ }
}
static int luton_switch_init(struct luton_private *priv)
@@ -495,8 +543,8 @@ static int luton_switch_init(struct luton_private *priv)
setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
SYS_SYSTEM_RST_CORE_ENA);
- /* Setup the Serdes6g macros */
- serdes6g_cfg(priv);
+ /* Setup the Serdes macros */
+ serdes_setup(priv);
return 0;
}
@@ -525,7 +573,7 @@ static int luton_initialize(struct luton_private *priv)
writel(2000000000 / 4,
priv->regs[SYS] + SYS_FRM_AGING);
- for (i = PORT0; i < MAX_PORT; i++) {
+ for (i = 0; i < MAX_PORT; i++) {
if (i < PORT10)
luton_gmii_port_init(priv, i);
else
@@ -608,56 +656,51 @@ static int luton_recv(struct udevice *dev, int flags, uchar **packetp)
return byte_cnt;
}
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+ int i = 0;
+
+ for (i = 0; i < LUTON_MIIM_BUS_COUNT; ++i)
+ if (miim[i].miim_base == base && miim[i].miim_size == size)
+ return miim[i].bus;
+
+ return NULL;
+}
+
+static void add_port_entry(struct luton_private *priv, size_t index,
+ size_t phy_addr, struct mii_dev *bus,
+ u8 serdes_index, u8 phy_mode)
+{
+ priv->ports[index].phy_addr = phy_addr;
+ priv->ports[index].bus = bus;
+ priv->ports[index].serdes_index = serdes_index;
+ priv->ports[index].phy_mode = phy_mode;
+}
+
static int luton_probe(struct udevice *dev)
{
struct luton_private *priv = dev_get_priv(dev);
- int i;
-
- struct {
- enum luton_target id;
- char *name;
- } reg[] = {
- { PORT0, "port0" },
- { PORT1, "port1" },
- { PORT2, "port2" },
- { PORT3, "port3" },
- { PORT4, "port4" },
- { PORT5, "port5" },
- { PORT6, "port6" },
- { PORT7, "port7" },
- { PORT8, "port8" },
- { PORT9, "port9" },
- { PORT10, "port10" },
- { PORT11, "port11" },
- { PORT12, "port12" },
- { PORT13, "port13" },
- { PORT14, "port14" },
- { PORT15, "port15" },
- { PORT16, "port16" },
- { PORT17, "port17" },
- { PORT18, "port18" },
- { PORT19, "port19" },
- { PORT20, "port20" },
- { PORT21, "port21" },
- { PORT22, "port22" },
- { PORT23, "port23" },
- { SYS, "sys" },
- { ANA, "ana" },
- { REW, "rew" },
- { GCB, "gcb" },
- { QS, "qs" },
- { HSIO, "hsio" },
- };
+ int i, ret;
+ struct resource res;
+ fdt32_t faddr;
+ phys_addr_t addr_base;
+ unsigned long addr_size;
+ ofnode eth_node, node, mdio_node;
+ size_t phy_addr;
+ struct mii_dev *bus;
+ struct ofnode_phandle_args phandle;
+ struct phy_device *phy;
if (!priv)
return -EINVAL;
- for (i = 0; i < ARRAY_SIZE(reg); i++) {
- priv->regs[reg[i].id] = dev_remap_addr_name(dev, reg[i].name);
- if (!priv->regs[reg[i].id]) {
+ /* Get registers and map them to the private structure */
+ for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+ priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+ if (!priv->regs[i]) {
debug
("Error can't get regs base addresses for %s\n",
- reg[i].name);
+ regs_names[i]);
return -ENOMEM;
}
}
@@ -666,7 +709,7 @@ static int luton_probe(struct udevice *dev)
writel(0, priv->regs[GCB] + GCB_DEVCPU_RST_SOFT_CHIP_RST);
/* Ports with ext phy don't need to reset clk */
- for (i = PORT0; i < MAX_INT_PORT; i++) {
+ for (i = 0; i < MAX_INT_PORT; i++) {
if (i < PORT10)
clrbits_le32(priv->regs[i] + DEV_GMII_PORT_MODE_CLK,
DEV_GMII_PORT_MODE_CLK_PHY_RST);
@@ -680,20 +723,76 @@ static int luton_probe(struct udevice *dev)
GCB_MISC_STAT_PHY_READY, true, 500, false))
return -EACCES;
- priv->bus[INTERNAL] = luton_mdiobus_init(dev, INTERNAL);
- for (i = 0; i < MAX_INT_PORT; i++) {
- phy_connect(priv->bus[INTERNAL], i, dev,
- PHY_INTERFACE_MODE_NONE);
+ /* Initialize miim buses */
+ memset(&miim, 0x0, sizeof(miim) * LUTON_MIIM_BUS_COUNT);
+
+ /* iterate all the ports and find out on which bus they are */
+ i = 0;
+ eth_node = dev_read_first_subnode(dev);
+ for (node = ofnode_first_subnode(eth_node);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ if (ofnode_read_resource(node, 0, &res))
+ return -ENOMEM;
+ i = res.start;
+
+ ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
+ 0, 0, &phandle);
+ if (ret)
+ continue;
+
+ /* Get phy address on mdio bus */
+ if (ofnode_read_resource(phandle.node, 0, &res))
+ return -ENOMEM;
+ phy_addr = res.start;
+
+ /* Get mdio node */
+ mdio_node = ofnode_get_parent(phandle.node);
+
+ if (ofnode_read_resource(mdio_node, 0, &res))
+ return -ENOMEM;
+ faddr = cpu_to_fdt32(res.start);
+
+ addr_base = ofnode_translate_address(mdio_node, &faddr);
+ addr_size = res.end - res.start;
+
+ /* If the bus is new then create a new bus */
+ if (!get_mdiobus(addr_base, addr_size))
+ priv->bus[miim_count] =
+ serval_mdiobus_init(addr_base, addr_size);
+
+ /* Connect mdio bus with the port */
+ bus = get_mdiobus(addr_base, addr_size);
+
+ /* Get serdes info */
+ ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
+ 3, 0, &phandle);
+ if (ret)
+ add_port_entry(priv, i, phy_addr, bus, 0xff, 0xff);
+ else
+ add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
+ phandle.args[2]);
+ }
+
+ for (i = 0; i < MAX_PORT; i++) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ phy = phy_connect(priv->ports[i].bus,
+ priv->ports[i].phy_addr, dev,
+ PHY_INTERFACE_MODE_NONE);
+ if (phy && i >= MAX_INT_PORT)
+ board_phy_config(phy);
}
/*
* coma_mode is need on only one phy, because all the other phys
* will be affected.
*/
- mscc_miim_write(priv->bus[INTERNAL], 0, 0, 31, 0x10);
- mscc_miim_write(priv->bus[INTERNAL], 0, 0, 14, 0x800);
- mscc_miim_write(priv->bus[INTERNAL], 0, 0, 31, 0);
+ mscc_miim_write(priv->ports[0].bus, 0, 0, 31, 0x10);
+ mscc_miim_write(priv->ports[0].bus, 0, 0, 14, 0x800);
+ mscc_miim_write(priv->ports[0].bus, 0, 0, 31, 0);
return 0;
}
@@ -703,7 +802,7 @@ static int luton_remove(struct udevice *dev)
struct luton_private *priv = dev_get_priv(dev);
int i;
- for (i = 0; i < NUM_PHY; i++) {
+ for (i = 0; i < LUTON_MIIM_BUS_COUNT; i++) {
mdio_unregister(priv->bus[i]);
mdio_free(priv->bus[i]);
}
diff --git a/drivers/net/mscc_eswitch/ocelot_switch.c b/drivers/net/mscc_eswitch/ocelot_switch.c
index 815c2da2646..5c7e6961be4 100644
--- a/drivers/net/mscc_eswitch/ocelot_switch.c
+++ b/drivers/net/mscc_eswitch/ocelot_switch.c
@@ -15,7 +15,6 @@
#include <net.h>
#include <wait_bit.h>
-#include "mscc_miim.h"
#include "mscc_xfer.h"
#include "mscc_mac_table.h"
@@ -26,6 +25,20 @@
#define PHY_STAT 0x4
#define PHY_STAT_SUPERVISOR_COMPLETE BIT(0)
+#define GCB_MIIM_MII_STATUS 0x0
+#define GCB_MIIM_STAT_BUSY BIT(3)
+#define GCB_MIIM_MII_CMD 0x8
+#define GCB_MIIM_MII_CMD_SCAN BIT(0)
+#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
+#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
+#define GCB_MIIM_MII_CMD_SINGLE_SCAN BIT(3)
+#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
+#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
+#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
+#define GCB_MIIM_MII_CMD_VLD BIT(31)
+#define GCB_MIIM_DATA 0xC
+#define GCB_MIIM_DATA_ERROR (0x3 << 16)
+
#define ANA_PORT_VLAN_CFG(x) (0x7000 + 0x100 * (x))
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
#define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18)
@@ -33,6 +46,41 @@
#define ANA_PORT_PORT_CFG_RECV_ENA BIT(6)
#define ANA_PGID(x) (0x8c00 + 4 * (x))
+#define HSIO_ANA_SERDES1G_DES_CFG 0x4c
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x) ((x) << 1)
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x) ((x) << 5)
+#define HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_IB_CFG 0x50
+#define HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x) ((x) << 6)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP BIT(9)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV BIT(11)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM BIT(13)
+#define HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x) ((x) << 24)
+#define HSIO_ANA_SERDES1G_OB_CFG 0x54
+#define HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x) ((x) << 4)
+#define HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x) ((x) << 10)
+#define HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_OB_CFG_SLP(x) ((x) << 17)
+#define HSIO_ANA_SERDES1G_SER_CFG 0x58
+#define HSIO_ANA_SERDES1G_COMMON_CFG 0x5c
+#define HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE BIT(0)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE BIT(18)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST BIT(31)
+#define HSIO_ANA_SERDES1G_PLL_CFG 0x60
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA BIT(7)
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2 BIT(21)
+#define HSIO_DIG_SERDES1G_DFT_CFG0 0x68
+#define HSIO_DIG_SERDES1G_MISC_CFG 0x7c
+#define HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST BIT(0)
+#define HSIO_MCB_SERDES1G_CFG 0x88
+#define HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT BIT(31)
+#define HSIO_MCB_SERDES1G_CFG_ADDR(x) (x)
+#define HSIO_HW_CFGSTAT_HW_CFG 0x10c
+
#define SYS_FRM_AGING 0x574
#define SYS_FRM_AGING_ENA BIT(20)
@@ -83,49 +131,58 @@
#define QS_INJ_GRP_CFG_BYTE_SWAP BIT(0)
#define IFH_INJ_BYPASS BIT(31)
-#define IFH_TAG_TYPE_C 0
-#define MAC_VID 1
+#define IFH_TAG_TYPE_C 0
+#define MAC_VID 1
#define CPU_PORT 11
-#define INTERNAL_PORT_MSK 0xF
+#define INTERNAL_PORT_MSK 0x2FF
#define IFH_LEN 4
#define ETH_ALEN 6
-#define PGID_BROADCAST 13
-#define PGID_UNICAST 14
-#define PGID_SRC 80
+#define PGID_BROADCAST 13
+#define PGID_UNICAST 14
+#define PGID_SRC 80
-enum ocelot_target {
- ANA,
- QS,
- QSYS,
+static const char * const regs_names[] = {
+ "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
+ "port8", "port9", "port10", "sys", "rew", "qs", "hsio", "qsys", "ana",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 11
+
+enum ocelot_ctrl_regs {
+ SYS = MAX_PORT,
REW,
- SYS,
+ QS,
HSIO,
- PORT0,
- PORT1,
- PORT2,
- PORT3,
- TARGET_MAX,
+ QSYS,
+ ANA,
};
-#define MAX_PORT (PORT3 - PORT0)
+#define OCELOT_MIIM_BUS_COUNT 2
-enum ocelot_mdio_target {
- MIIM,
- PHY,
- TARGET_MDIO_MAX,
+struct ocelot_phy_port_t {
+ size_t phy_addr;
+ struct mii_dev *bus;
+ u8 serdes_index;
+ u8 phy_mode;
};
-enum ocelot_phy_id {
- INTERNAL,
- EXTERNAL,
- NUM_PHY,
+struct ocelot_private {
+ void __iomem *regs[REGS_NAMES_COUNT];
+ struct mii_dev *bus[OCELOT_MIIM_BUS_COUNT];
+ struct ocelot_phy_port_t ports[MAX_PORT];
};
-struct ocelot_private {
- void __iomem *regs[TARGET_MAX];
- struct mii_dev *bus[NUM_PHY];
+struct mscc_miim_dev {
+ void __iomem *regs;
+ phys_addr_t miim_base;
+ unsigned long miim_size;
+ struct mii_dev *bus;
};
+static struct mscc_miim_dev miim[OCELOT_MIIM_BUS_COUNT];
+static int miim_count = -1;
+
static const unsigned long ocelot_regs_qs[] = {
[MSCC_QS_XTR_RD] = 0x8,
[MSCC_QS_XTR_FLUSH] = 0x18,
@@ -140,65 +197,95 @@ static const unsigned long ocelot_regs_ana_table[] = {
[MSCC_ANA_TABLES_MACACCESS] = 0x8b3c,
};
-static struct mscc_miim_dev miim[NUM_PHY];
-
static void mscc_phy_reset(void)
{
- writel(0, miim[INTERNAL].phy_regs + PHY_CFG);
+ writel(0, BASE_DEVCPU_GCB + PERF_PHY_CFG + PHY_CFG);
writel(PHY_CFG_RST | PHY_CFG_COMMON_RST
- | PHY_CFG_ENA, miim[INTERNAL].phy_regs + PHY_CFG);
- if (wait_for_bit_le32(miim[INTERNAL].phy_regs + PHY_STAT,
- PHY_STAT_SUPERVISOR_COMPLETE,
+ | PHY_CFG_ENA, BASE_DEVCPU_GCB + PERF_PHY_CFG + PHY_CFG);
+ if (wait_for_bit_le32((const void *)(BASE_DEVCPU_GCB + PERF_PHY_CFG) +
+ PHY_STAT, PHY_STAT_SUPERVISOR_COMPLETE,
true, 2000, false)) {
pr_err("Timeout in phy reset\n");
}
}
-/* For now only setup the internal mdio bus */
-static struct mii_dev *ocelot_mdiobus_init(struct udevice *dev)
+static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
+{
+ return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
+ GCB_MIIM_STAT_BUSY, false, 250, false);
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ u32 val;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+ miim->regs + GCB_MIIM_MII_CMD);
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ val = readl(miim->regs + GCB_MIIM_DATA);
+ if (val & GCB_MIIM_DATA_ERROR) {
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = val & 0xFFFF;
+ out:
+ return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret < 0)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+ GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+ out:
+ return ret;
+}
+
+static struct mii_dev *ocelot_mdiobus_init(phys_addr_t miim_base,
+ unsigned long miim_size)
{
- unsigned long phy_size[TARGET_MAX];
- phys_addr_t phy_base[TARGET_MAX];
- struct ofnode_phandle_args phandle;
- ofnode eth_node, node, mdio_node;
- struct resource res;
struct mii_dev *bus;
- fdt32_t faddr;
- int i;
bus = mdio_alloc();
if (!bus)
return NULL;
- /* gathered only the first mdio bus */
- eth_node = dev_read_first_subnode(dev);
- node = ofnode_first_subnode(eth_node);
- ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
- &phandle);
- mdio_node = ofnode_get_parent(phandle.node);
-
- for (i = 0; i < TARGET_MDIO_MAX; i++) {
- if (ofnode_read_resource(mdio_node, i, &res)) {
- pr_err("%s: get OF resource failed\n", __func__);
- return NULL;
- }
- faddr = cpu_to_fdt32(res.start);
- phy_base[i] = ofnode_translate_address(mdio_node, &faddr);
- phy_size[i] = res.end - res.start;
- }
+ ++miim_count;
+ sprintf(bus->name, "miim-bus%d", miim_count);
- strcpy(bus->name, "miim-internal");
- miim[INTERNAL].phy_regs = ioremap(phy_base[PHY], phy_size[PHY]);
- miim[INTERNAL].regs = ioremap(phy_base[MIIM], phy_size[MIIM]);
- bus->priv = &miim[INTERNAL];
+ miim[miim_count].regs = ioremap(miim_base, miim_size);
+ miim[miim_count].miim_base = miim_base;
+ miim[miim_count].miim_size = miim_size;
+ bus->priv = &miim[miim_count];
bus->read = mscc_miim_read;
bus->write = mscc_miim_write;
if (mdio_register(bus))
return NULL;
- else
- return bus;
+
+ miim[miim_count].bus = bus;
+ return bus;
}
__weak void mscc_switch_reset(void)
@@ -291,13 +378,87 @@ static void ocelot_port_init(struct ocelot_private *priv, int port)
/* Make VLAN aware for CPU traffic */
writel(ANA_PORT_VLAN_CFG_AWARE_ENA | ANA_PORT_VLAN_CFG_POP_CNT(1) |
- MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(port - PORT0));
+ MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
/* Enable the port in the core */
- setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(port - PORT0),
+ setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(port),
QSYS_SWITCH_PORT_MODE_PORT_ENA);
}
+static void serdes1g_write(void __iomem *base, u32 addr)
+{
+ u32 data;
+
+ writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
+ HSIO_MCB_SERDES1G_CFG_ADDR(addr),
+ base + HSIO_MCB_SERDES1G_CFG);
+
+ do {
+ data = readl(base + HSIO_MCB_SERDES1G_CFG);
+ } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
+}
+
+static void serdes1g_setup(void __iomem *base, uint32_t addr,
+ phy_interface_t interface)
+{
+ writel(0x34, base + HSIO_HW_CFGSTAT_HW_CFG);
+
+ writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
+ writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
+ writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(11) |
+ HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(0) |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
+ HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
+ base + HSIO_ANA_SERDES1G_IB_CFG);
+ writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
+ HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
+ HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
+ HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
+ base + HSIO_ANA_SERDES1G_DES_CFG);
+ writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
+ HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
+ HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
+ HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
+ HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
+ base + HSIO_ANA_SERDES1G_OB_CFG);
+ writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE,
+ base + HSIO_ANA_SERDES1G_COMMON_CFG);
+ writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
+ HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(200) |
+ HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
+ base + HSIO_ANA_SERDES1G_PLL_CFG);
+ writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
+ base + HSIO_DIG_SERDES1G_MISC_CFG);
+
+ serdes1g_write(base, addr);
+
+ writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
+ base + HSIO_ANA_SERDES1G_COMMON_CFG);
+ serdes1g_write(base, addr);
+
+ writel(0x0, base + HSIO_DIG_SERDES1G_MISC_CFG);
+ serdes1g_write(base, addr);
+}
+
+static void serdes_setup(struct ocelot_private *priv)
+{
+ size_t mask;
+ int i = 0;
+
+ for (i = 0; i < MAX_PORT; ++i) {
+ if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
+ continue;
+
+ mask = BIT(priv->ports[i].serdes_index);
+ serdes1g_setup(priv->regs[HSIO], mask,
+ priv->ports[i].phy_mode);
+ }
+}
+
static int ocelot_switch_init(struct ocelot_private *priv)
{
/* Reset switch & memories */
@@ -315,6 +476,7 @@ static int ocelot_switch_init(struct ocelot_private *priv)
setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
SYS_SYSTEM_RST_CORE_ENA);
+ serdes_setup(priv);
return 0;
}
@@ -331,7 +493,7 @@ static int ocelot_initialize(struct ocelot_private *priv)
* Put fron ports in "port isolation modes" - i.e. they cant send
* to other ports - via the PGID sorce masks.
*/
- for (i = 0; i <= MAX_PORT; i++)
+ for (i = 0; i < MAX_PORT; i++)
writel(0, priv->regs[ANA] + ANA_PGID(PGID_SRC + i));
/* Flush queues */
@@ -341,7 +503,7 @@ static int ocelot_initialize(struct ocelot_private *priv)
writel(SYS_FRM_AGING_ENA | (20000000 / 65),
priv->regs[SYS] + SYS_FRM_AGING);
- for (i = PORT0; i <= PORT3; i++)
+ for (i = 0; i < MAX_PORT; i++)
ocelot_port_init(priv, i);
ocelot_cpu_capture_setup(priv);
@@ -433,43 +595,119 @@ static int ocelot_recv(struct udevice *dev, int flags, uchar **packetp)
return byte_cnt;
}
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+ int i = 0;
+
+ for (i = 0; i < OCELOT_MIIM_BUS_COUNT; ++i)
+ if (miim[i].miim_base == base && miim[i].miim_size == size)
+ return miim[i].bus;
+
+ return NULL;
+}
+
+static void add_port_entry(struct ocelot_private *priv, size_t index,
+ size_t phy_addr, struct mii_dev *bus,
+ u8 serdes_index, u8 phy_mode)
+{
+ priv->ports[index].phy_addr = phy_addr;
+ priv->ports[index].bus = bus;
+ priv->ports[index].serdes_index = serdes_index;
+ priv->ports[index].phy_mode = phy_mode;
+}
+
+static int external_bus(struct ocelot_private *priv, size_t port_index)
+{
+ return priv->ports[port_index].serdes_index != 0xff;
+}
+
static int ocelot_probe(struct udevice *dev)
{
struct ocelot_private *priv = dev_get_priv(dev);
- int ret, i;
+ int i, ret;
+ struct resource res;
+ fdt32_t faddr;
+ phys_addr_t addr_base;
+ unsigned long addr_size;
+ ofnode eth_node, node, mdio_node;
+ size_t phy_addr;
+ struct mii_dev *bus;
+ struct ofnode_phandle_args phandle;
+ struct phy_device *phy;
+
+ if (!priv)
+ return -EINVAL;
- struct {
- enum ocelot_target id;
- char *name;
- } reg[] = {
- { SYS, "sys" },
- { REW, "rew" },
- { QSYS, "qsys" },
- { ANA, "ana" },
- { QS, "qs" },
- { HSIO, "hsio" },
- { PORT0, "port0" },
- { PORT1, "port1" },
- { PORT2, "port2" },
- { PORT3, "port3" },
- };
-
- for (i = 0; i < ARRAY_SIZE(reg); i++) {
- priv->regs[reg[i].id] = dev_remap_addr_name(dev, reg[i].name);
- if (!priv->regs[reg[i].id]) {
- pr_err
- ("Error %d: can't get regs base addresses for %s\n",
- ret, reg[i].name);
+ for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+ priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+ if (!priv->regs[i]) {
+ debug
+ ("Error can't get regs base addresses for %s\n",
+ regs_names[i]);
return -ENOMEM;
}
}
- priv->bus[INTERNAL] = ocelot_mdiobus_init(dev);
+ /* Initialize miim buses */
+ memset(&miim, 0x0, sizeof(struct mscc_miim_dev) *
+ OCELOT_MIIM_BUS_COUNT);
+
+ /* iterate all the ports and find out on which bus they are */
+ i = 0;
+ eth_node = dev_read_first_subnode(dev);
+ for (node = ofnode_first_subnode(eth_node); ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ if (ofnode_read_resource(node, 0, &res))
+ return -ENOMEM;
+ i = res.start;
+
+ ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
+ &phandle);
+
+ /* Get phy address on mdio bus */
+ if (ofnode_read_resource(phandle.node, 0, &res))
+ return -ENOMEM;
+ phy_addr = res.start;
+
+ /* Get mdio node */
+ mdio_node = ofnode_get_parent(phandle.node);
+
+ if (ofnode_read_resource(mdio_node, 0, &res))
+ return -ENOMEM;
+ faddr = cpu_to_fdt32(res.start);
+
+ addr_base = ofnode_translate_address(mdio_node, &faddr);
+ addr_size = res.end - res.start;
+
+ /* If the bus is new then create a new bus */
+ if (!get_mdiobus(addr_base, addr_size))
+ priv->bus[miim_count] =
+ ocelot_mdiobus_init(addr_base, addr_size);
+
+ /* Connect mdio bus with the port */
+ bus = get_mdiobus(addr_base, addr_size);
+
+ /* Get serdes info */
+ ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
+ 3, 0, &phandle);
+ if (ret)
+ add_port_entry(priv, i, phy_addr, bus, 0xff, 0xff);
+ else
+ add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
+ phandle.args[2]);
+ }
+
mscc_phy_reset();
- for (i = 0; i < 4; i++) {
- phy_connect(priv->bus[INTERNAL], i, dev,
- PHY_INTERFACE_MODE_NONE);
+ for (i = 0; i < MAX_PORT; i++) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ phy = phy_connect(priv->ports[i].bus,
+ priv->ports[i].phy_addr, dev,
+ PHY_INTERFACE_MODE_NONE);
+ if (phy && external_bus(priv, i))
+ board_phy_config(phy);
}
return 0;
@@ -480,7 +718,7 @@ static int ocelot_remove(struct udevice *dev)
struct ocelot_private *priv = dev_get_priv(dev);
int i;
- for (i = 0; i < NUM_PHY; i++) {
+ for (i = 0; i < OCELOT_MIIM_BUS_COUNT; i++) {
mdio_unregister(priv->bus[i]);
mdio_free(priv->bus[i]);
}
diff --git a/drivers/net/mscc_eswitch/serval_switch.c b/drivers/net/mscc_eswitch/serval_switch.c
new file mode 100644
index 00000000000..2559f5d0cd1
--- /dev/null
+++ b/drivers/net/mscc_eswitch/serval_switch.c
@@ -0,0 +1,703 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <fdt_support.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <miiphy.h>
+#include <net.h>
+#include <wait_bit.h>
+
+#include "mscc_xfer.h"
+#include "mscc_mac_table.h"
+
+#define GCB_MIIM_MII_STATUS 0x0
+#define GCB_MIIM_STAT_BUSY BIT(3)
+#define GCB_MIIM_MII_CMD 0x8
+#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
+#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
+#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
+#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
+#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
+#define GCB_MIIM_MII_CMD_VLD BIT(31)
+#define GCB_MIIM_DATA 0xC
+#define GCB_MIIM_DATA_ERROR (0x2 << 16)
+
+#define ANA_PORT_VLAN_CFG(x) (0xc000 + 0x100 * (x))
+#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
+#define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18)
+#define ANA_PORT_PORT_CFG(x) (0xc070 + 0x100 * (x))
+#define ANA_PORT_PORT_CFG_RECV_ENA BIT(6)
+#define ANA_PGID(x) (0x9c00 + 4 * (x))
+
+#define HSIO_ANA_SERDES1G_DES_CFG 0x3c
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x) ((x) << 1)
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x) ((x) << 5)
+#define HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_IB_CFG 0x40
+#define HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x) ((x) << 6)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP BIT(9)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV BIT(11)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM BIT(13)
+#define HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x) ((x) << 19)
+#define HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x) ((x) << 24)
+#define HSIO_ANA_SERDES1G_OB_CFG 0x44
+#define HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x) ((x) << 4)
+#define HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x) ((x) << 10)
+#define HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_OB_CFG_SLP(x) ((x) << 17)
+#define HSIO_ANA_SERDES1G_SER_CFG 0x48
+#define HSIO_ANA_SERDES1G_COMMON_CFG 0x4c
+#define HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE BIT(0)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE BIT(18)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST BIT(31)
+#define HSIO_ANA_SERDES1G_PLL_CFG 0x50
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA BIT(7)
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2 BIT(21)
+#define HSIO_DIG_SERDES1G_DFT_CFG0 0x58
+#define HSIO_DIG_SERDES1G_MISC_CFG 0x6c
+#define HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST BIT(0)
+#define HSIO_MCB_SERDES1G_CFG 0x74
+#define HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT BIT(31)
+#define HSIO_MCB_SERDES1G_CFG_ADDR(x) (x)
+
+#define SYS_FRM_AGING 0x584
+#define SYS_FRM_AGING_ENA BIT(20)
+#define SYS_SYSTEM_RST_CFG 0x518
+#define SYS_SYSTEM_RST_MEM_INIT BIT(5)
+#define SYS_SYSTEM_RST_MEM_ENA BIT(6)
+#define SYS_SYSTEM_RST_CORE_ENA BIT(7)
+#define SYS_PORT_MODE(x) (0x524 + 0x4 * (x))
+#define SYS_PORT_MODE_INCL_INJ_HDR(x) ((x) << 4)
+#define SYS_PORT_MODE_INCL_XTR_HDR(x) ((x) << 2)
+#define SYS_PAUSE_CFG(x) (0x65c + 0x4 * (x))
+#define SYS_PAUSE_CFG_PAUSE_ENA BIT(0)
+
+#define QSYS_SWITCH_PORT_MODE(x) (0x15a34 + 0x4 * (x))
+#define QSYS_SWITCH_PORT_MODE_PORT_ENA BIT(13)
+#define QSYS_EGR_NO_SHARING 0x15a9c
+#define QSYS_QMAP 0x15adc
+
+/* Port registers */
+#define DEV_CLOCK_CFG 0x0
+#define DEV_CLOCK_CFG_LINK_SPEED_1000 1
+#define DEV_MAC_ENA_CFG 0x10
+#define DEV_MAC_ENA_CFG_RX_ENA BIT(4)
+#define DEV_MAC_ENA_CFG_TX_ENA BIT(0)
+#define DEV_MAC_IFG_CFG 0x24
+#define DEV_MAC_IFG_CFG_TX_IFG(x) ((x) << 8)
+#define DEV_MAC_IFG_CFG_RX_IFG2(x) ((x) << 4)
+#define DEV_MAC_IFG_CFG_RX_IFG1(x) (x)
+#define PCS1G_CFG 0x3c
+#define PCS1G_MODE_CFG_SGMII_MODE_ENA BIT(0)
+#define PCS1G_MODE_CFG 0x40
+#define PCS1G_SD_CFG 0x44
+#define PCS1G_ANEG_CFG 0x48
+#define PCS1G_ANEG_CFG_ADV_ABILITY(x) ((x) << 16)
+
+#define QS_XTR_GRP_CFG(x) (4 * (x))
+#define QS_XTR_GRP_CFG_MODE(x) ((x) << 2)
+#define QS_XTR_GRP_CFG_BYTE_SWAP BIT(0)
+#define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
+#define QS_INJ_GRP_CFG_MODE(x) ((x) << 2)
+#define QS_INJ_GRP_CFG_BYTE_SWAP BIT(0)
+
+#define IFH_INJ_BYPASS BIT(31)
+#define IFH_TAG_TYPE_C 0
+#define MAC_VID 1
+#define CPU_PORT 11
+#define INTERNAL_PORT_MSK 0xFF
+#define IFH_LEN 4
+#define ETH_ALEN 6
+#define PGID_BROADCAST 13
+#define PGID_UNICAST 14
+
+static const char *const regs_names[] = {
+ "port0", "port1", "port2", "port3", "port4", "port5", "port6",
+ "port7", "port8", "port9", "port10",
+ "ana", "qs", "qsys", "rew", "sys", "hsio",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 11
+
+enum serval_ctrl_regs {
+ ANA = MAX_PORT,
+ QS,
+ QSYS,
+ REW,
+ SYS,
+ HSIO,
+};
+
+#define SERVAL_MIIM_BUS_COUNT 2
+
+struct serval_phy_port_t {
+ size_t phy_addr;
+ struct mii_dev *bus;
+ u8 serdes_index;
+ u8 phy_mode;
+};
+
+struct serval_private {
+ void __iomem *regs[REGS_NAMES_COUNT];
+ struct mii_dev *bus[SERVAL_MIIM_BUS_COUNT];
+ struct serval_phy_port_t ports[MAX_PORT];
+};
+
+struct mscc_miim_dev {
+ void __iomem *regs;
+ phys_addr_t miim_base;
+ unsigned long miim_size;
+ struct mii_dev *bus;
+};
+
+static const unsigned long serval_regs_qs[] = {
+ [MSCC_QS_XTR_RD] = 0x8,
+ [MSCC_QS_XTR_FLUSH] = 0x18,
+ [MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
+ [MSCC_QS_INJ_WR] = 0x2c,
+ [MSCC_QS_INJ_CTRL] = 0x34,
+};
+
+static const unsigned long serval_regs_ana_table[] = {
+ [MSCC_ANA_TABLES_MACHDATA] = 0x9b34,
+ [MSCC_ANA_TABLES_MACLDATA] = 0x9b38,
+ [MSCC_ANA_TABLES_MACACCESS] = 0x9b3c,
+};
+
+static struct mscc_miim_dev miim[SERVAL_MIIM_BUS_COUNT];
+static int miim_count = -1;
+
+static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
+{
+ return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
+ GCB_MIIM_STAT_BUSY, false, 250, false);
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ u32 val;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+ miim->regs + GCB_MIIM_MII_CMD);
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ val = readl(miim->regs + GCB_MIIM_DATA);
+ if (val & GCB_MIIM_DATA_ERROR) {
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = val & 0xFFFF;
+ out:
+ return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret < 0)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+ GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+ out:
+ return ret;
+}
+
+static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
+ unsigned long miim_size)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus)
+ return NULL;
+
+ ++miim_count;
+ sprintf(bus->name, "miim-bus%d", miim_count);
+
+ miim[miim_count].regs = ioremap(miim_base, miim_size);
+ miim[miim_count].miim_base = miim_base;
+ miim[miim_count].miim_size = miim_size;
+ bus->priv = &miim[miim_count];
+ bus->read = mscc_miim_read;
+ bus->write = mscc_miim_write;
+
+ if (mdio_register(bus))
+ return NULL;
+
+ miim[miim_count].bus = bus;
+ return bus;
+}
+
+static void serval_cpu_capture_setup(struct serval_private *priv)
+{
+ int i;
+
+ /* map the 8 CPU extraction queues to CPU port 11 */
+ writel(0, priv->regs[QSYS] + QSYS_QMAP);
+
+ for (i = 0; i <= 1; i++) {
+ /*
+ * Do byte-swap and expect status after last data word
+ * Extraction: Mode: manual extraction) | Byte_swap
+ */
+ writel(QS_XTR_GRP_CFG_MODE(1) | QS_XTR_GRP_CFG_BYTE_SWAP,
+ priv->regs[QS] + QS_XTR_GRP_CFG(i));
+ /*
+ * Injection: Mode: manual extraction | Byte_swap
+ */
+ writel(QS_INJ_GRP_CFG_MODE(1) | QS_INJ_GRP_CFG_BYTE_SWAP,
+ priv->regs[QS] + QS_INJ_GRP_CFG(i));
+ }
+
+ for (i = 0; i <= 1; i++)
+ /* Enable IFH insertion/parsing on CPU ports */
+ writel(SYS_PORT_MODE_INCL_INJ_HDR(1) |
+ SYS_PORT_MODE_INCL_XTR_HDR(1),
+ priv->regs[SYS] + SYS_PORT_MODE(CPU_PORT + i));
+ /*
+ * Setup the CPU port as VLAN aware to support switching frames
+ * based on tags
+ */
+ writel(ANA_PORT_VLAN_CFG_AWARE_ENA | ANA_PORT_VLAN_CFG_POP_CNT(1) |
+ MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(CPU_PORT));
+
+ /* Disable learning (only RECV_ENA must be set) */
+ writel(ANA_PORT_PORT_CFG_RECV_ENA,
+ priv->regs[ANA] + ANA_PORT_PORT_CFG(CPU_PORT));
+
+ /* Enable switching to/from cpu port */
+ setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(CPU_PORT),
+ QSYS_SWITCH_PORT_MODE_PORT_ENA);
+
+ /* No pause on CPU port - not needed (off by default) */
+ clrbits_le32(priv->regs[SYS] + SYS_PAUSE_CFG(CPU_PORT),
+ SYS_PAUSE_CFG_PAUSE_ENA);
+
+ setbits_le32(priv->regs[QSYS] + QSYS_EGR_NO_SHARING, BIT(CPU_PORT));
+}
+
+static void serval_port_init(struct serval_private *priv, int port)
+{
+ void __iomem *regs = priv->regs[port];
+
+ /* Enable PCS */
+ writel(PCS1G_MODE_CFG_SGMII_MODE_ENA, regs + PCS1G_CFG);
+
+ /* Disable Signal Detect */
+ writel(0, regs + PCS1G_SD_CFG);
+
+ /* Enable MAC RX and TX */
+ writel(DEV_MAC_ENA_CFG_RX_ENA | DEV_MAC_ENA_CFG_TX_ENA,
+ regs + DEV_MAC_ENA_CFG);
+
+ /* Clear sgmii_mode_ena */
+ writel(0, regs + PCS1G_MODE_CFG);
+
+ /*
+ * Clear sw_resolve_ena(bit 0) and set adv_ability to
+ * something meaningful just in case
+ */
+ writel(PCS1G_ANEG_CFG_ADV_ABILITY(0x20), regs + PCS1G_ANEG_CFG);
+
+ /* Set MAC IFG Gaps */
+ writel(DEV_MAC_IFG_CFG_TX_IFG(5) | DEV_MAC_IFG_CFG_RX_IFG1(5) |
+ DEV_MAC_IFG_CFG_RX_IFG2(1), regs + DEV_MAC_IFG_CFG);
+
+ /* Set link speed and release all resets */
+ writel(DEV_CLOCK_CFG_LINK_SPEED_1000, regs + DEV_CLOCK_CFG);
+
+ /* Make VLAN aware for CPU traffic */
+ writel(ANA_PORT_VLAN_CFG_AWARE_ENA | ANA_PORT_VLAN_CFG_POP_CNT(1) |
+ MAC_VID, priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
+
+ /* Enable the port in the core */
+ setbits_le32(priv->regs[QSYS] + QSYS_SWITCH_PORT_MODE(port),
+ QSYS_SWITCH_PORT_MODE_PORT_ENA);
+}
+
+static void serdes_write(void __iomem *base, u32 addr)
+{
+ u32 data;
+
+ writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
+ HSIO_MCB_SERDES1G_CFG_ADDR(addr),
+ base + HSIO_MCB_SERDES1G_CFG);
+
+ do {
+ data = readl(base + HSIO_MCB_SERDES1G_CFG);
+ } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
+
+ mdelay(100);
+}
+
+static void serdes1g_setup(void __iomem *base, uint32_t addr,
+ phy_interface_t interface)
+{
+ writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
+ writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
+ writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(11) |
+ HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(0) |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
+ HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
+ base + HSIO_ANA_SERDES1G_IB_CFG);
+ writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
+ HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
+ HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
+ HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
+ base + HSIO_ANA_SERDES1G_DES_CFG);
+ writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
+ HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
+ HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
+ HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
+ HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
+ base + HSIO_ANA_SERDES1G_OB_CFG);
+ writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE,
+ base + HSIO_ANA_SERDES1G_COMMON_CFG);
+ writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
+ HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(200) |
+ HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
+ base + HSIO_ANA_SERDES1G_PLL_CFG);
+ writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
+ base + HSIO_DIG_SERDES1G_MISC_CFG);
+ serdes_write(base, addr);
+
+ writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
+ base + HSIO_ANA_SERDES1G_COMMON_CFG);
+ serdes_write(base, addr);
+
+ writel(0x0, base + HSIO_DIG_SERDES1G_MISC_CFG);
+ serdes_write(base, addr);
+}
+
+static void serdes_setup(struct serval_private *priv)
+{
+ size_t mask;
+ int i = 0;
+
+ for (i = 0; i < MAX_PORT; ++i) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ mask = BIT(priv->ports[i].serdes_index);
+ serdes1g_setup(priv->regs[HSIO], mask,
+ priv->ports[i].phy_mode);
+ }
+}
+
+static int serval_switch_init(struct serval_private *priv)
+{
+ /* Reset switch & memories */
+ writel(SYS_SYSTEM_RST_MEM_ENA | SYS_SYSTEM_RST_MEM_INIT,
+ priv->regs[SYS] + SYS_SYSTEM_RST_CFG);
+
+ if (wait_for_bit_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
+ SYS_SYSTEM_RST_MEM_INIT, false, 2000, false)) {
+ pr_err("Timeout in memory reset\n");
+ return -EIO;
+ }
+
+ /* Enable switch core */
+ setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
+ SYS_SYSTEM_RST_CORE_ENA);
+
+ serdes_setup(priv);
+
+ return 0;
+}
+
+static int serval_initialize(struct serval_private *priv)
+{
+ int ret, i;
+
+ /* Initialize switch memories, enable core */
+ ret = serval_switch_init(priv);
+ if (ret)
+ return ret;
+
+ /* Flush queues */
+ mscc_flush(priv->regs[QS], serval_regs_qs);
+
+ /* Setup frame ageing - "2 sec" - The unit is 6.5us on serval */
+ writel(SYS_FRM_AGING_ENA | (20000000 / 65),
+ priv->regs[SYS] + SYS_FRM_AGING);
+
+ for (i = 0; i < MAX_PORT; i++)
+ serval_port_init(priv, i);
+
+ serval_cpu_capture_setup(priv);
+
+ debug("Ports enabled\n");
+
+ return 0;
+}
+
+static int serval_write_hwaddr(struct udevice *dev)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ mscc_mac_table_add(priv->regs[ANA], serval_regs_ana_table,
+ pdata->enetaddr, PGID_UNICAST);
+
+ writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
+
+ return 0;
+}
+
+static int serval_start(struct udevice *dev)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const unsigned char mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff };
+ int ret;
+
+ ret = serval_initialize(priv);
+ if (ret)
+ return ret;
+
+ /* Set MAC address tables entries for CPU redirection */
+ mscc_mac_table_add(priv->regs[ANA], serval_regs_ana_table, mac,
+ PGID_BROADCAST);
+
+ writel(BIT(CPU_PORT) | INTERNAL_PORT_MSK,
+ priv->regs[ANA] + ANA_PGID(PGID_BROADCAST));
+
+ /* It should be setup latter in serval_write_hwaddr */
+ mscc_mac_table_add(priv->regs[ANA], serval_regs_ana_table,
+ pdata->enetaddr, PGID_UNICAST);
+
+ writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
+ return 0;
+}
+
+static void serval_stop(struct udevice *dev)
+{
+ writel(ICPU_RESET_CORE_RST_PROTECT, BASE_CFG + ICPU_RESET);
+ writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_DEVCPU_GCB + PERF_SOFT_RST);
+}
+
+static int serval_send(struct udevice *dev, void *packet, int length)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ u32 ifh[IFH_LEN];
+ u32 *buf = packet;
+
+ /*
+ * Generate the IFH for frame injection
+ *
+ * The IFH is a 128bit-value
+ * bit 127: bypass the analyzer processing
+ * bit 57-67: destination mask
+ * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
+ * bit 20-27: cpu extraction queue mask
+ * bit 16: tag type 0: C-tag, 1: S-tag
+ * bit 0-11: VID
+ */
+ ifh[0] = IFH_INJ_BYPASS;
+ ifh[1] = (0x07);
+ ifh[2] = (0x7f) << 25;
+ ifh[3] = (IFH_TAG_TYPE_C << 16);
+
+ return mscc_send(priv->regs[QS], serval_regs_qs,
+ ifh, IFH_LEN, buf, length);
+}
+
+static int serval_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ u32 *rxbuf = (u32 *)net_rx_packets[0];
+ int byte_cnt = 0;
+
+ byte_cnt = mscc_recv(priv->regs[QS], serval_regs_qs, rxbuf, IFH_LEN,
+ false);
+
+ *packetp = net_rx_packets[0];
+
+ return byte_cnt;
+}
+
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+ int i = 0;
+
+ for (i = 0; i < SERVAL_MIIM_BUS_COUNT; ++i)
+ if (miim[i].miim_base == base && miim[i].miim_size == size)
+ return miim[i].bus;
+
+ return NULL;
+}
+
+static void add_port_entry(struct serval_private *priv, size_t index,
+ size_t phy_addr, struct mii_dev *bus,
+ u8 serdes_index, u8 phy_mode)
+{
+ priv->ports[index].phy_addr = phy_addr;
+ priv->ports[index].bus = bus;
+ priv->ports[index].serdes_index = serdes_index;
+ priv->ports[index].phy_mode = phy_mode;
+}
+
+static int serval_probe(struct udevice *dev)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ int i, ret;
+ struct resource res;
+ fdt32_t faddr;
+ phys_addr_t addr_base;
+ unsigned long addr_size;
+ ofnode eth_node, node, mdio_node;
+ size_t phy_addr;
+ struct mii_dev *bus;
+ struct ofnode_phandle_args phandle;
+ struct phy_device *phy;
+
+ if (!priv)
+ return -EINVAL;
+
+ /* Get registers and map them to the private structure */
+ for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+ priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+ if (!priv->regs[i]) {
+ debug
+ ("Error can't get regs base addresses for %s\n",
+ regs_names[i]);
+ return -ENOMEM;
+ }
+ }
+
+ /* Initialize miim buses */
+ memset(&miim, 0x0, sizeof(miim) * SERVAL_MIIM_BUS_COUNT);
+
+ /* iterate all the ports and find out on which bus they are */
+ i = 0;
+ eth_node = dev_read_first_subnode(dev);
+ for (node = ofnode_first_subnode(eth_node);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ if (ofnode_read_resource(node, 0, &res))
+ return -ENOMEM;
+ i = res.start;
+
+ ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
+ 0, 0, &phandle);
+ if (ret)
+ continue;
+
+ /* Get phy address on mdio bus */
+ if (ofnode_read_resource(phandle.node, 0, &res))
+ return -ENOMEM;
+ phy_addr = res.start;
+
+ /* Get mdio node */
+ mdio_node = ofnode_get_parent(phandle.node);
+
+ if (ofnode_read_resource(mdio_node, 0, &res))
+ return -ENOMEM;
+ faddr = cpu_to_fdt32(res.start);
+
+ addr_base = ofnode_translate_address(mdio_node, &faddr);
+ addr_size = res.end - res.start;
+
+ /* If the bus is new then create a new bus */
+ if (!get_mdiobus(addr_base, addr_size))
+ priv->bus[miim_count] =
+ serval_mdiobus_init(addr_base, addr_size);
+
+ /* Connect mdio bus with the port */
+ bus = get_mdiobus(addr_base, addr_size);
+
+ /* Get serdes info */
+ ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
+ 3, 0, &phandle);
+ if (ret)
+ return -ENOMEM;
+
+ add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
+ phandle.args[2]);
+ }
+
+ for (i = 0; i < MAX_PORT; i++) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ phy = phy_connect(priv->ports[i].bus,
+ priv->ports[i].phy_addr, dev,
+ PHY_INTERFACE_MODE_NONE);
+ if (phy)
+ board_phy_config(phy);
+ }
+
+ return 0;
+}
+
+static int serval_remove(struct udevice *dev)
+{
+ struct serval_private *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < SERVAL_MIIM_BUS_COUNT; i++) {
+ mdio_unregister(priv->bus[i]);
+ mdio_free(priv->bus[i]);
+ }
+
+ return 0;
+}
+
+static const struct eth_ops serval_ops = {
+ .start = serval_start,
+ .stop = serval_stop,
+ .send = serval_send,
+ .recv = serval_recv,
+ .write_hwaddr = serval_write_hwaddr,
+};
+
+static const struct udevice_id mscc_serval_ids[] = {
+ {.compatible = "mscc,vsc7418-switch"},
+ { /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(serval) = {
+ .name = "serval-switch",
+ .id = UCLASS_ETH,
+ .of_match = mscc_serval_ids,
+ .probe = serval_probe,
+ .remove = serval_remove,
+ .ops = &serval_ops,
+ .priv_auto_alloc_size = sizeof(struct serval_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/ti/davinci_emac.c b/drivers/net/ti/davinci_emac.c
index bb879d8d4fe..9d539849739 100644
--- a/drivers/net/ti/davinci_emac.c
+++ b/drivers/net/ti/davinci_emac.c
@@ -816,55 +816,12 @@ int davinci_emac_initialize(void)
phy_id |= tmp & 0x0000ffff;
- switch (phy_id) {
-#ifdef PHY_KSZ8873
- case PHY_KSZ8873:
- sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
- active_phy_addr[i]);
- phy[i].init = ksz8873_init_phy;
- phy[i].is_phy_connected = ksz8873_is_phy_connected;
- phy[i].get_link_speed = ksz8873_get_link_speed;
- phy[i].auto_negotiate = ksz8873_auto_negotiate;
- break;
-#endif
-#ifdef PHY_LXT972
- case PHY_LXT972:
- sprintf(phy[i].name, "LXT972 @ 0x%02x",
- active_phy_addr[i]);
- phy[i].init = lxt972_init_phy;
- phy[i].is_phy_connected = lxt972_is_phy_connected;
- phy[i].get_link_speed = lxt972_get_link_speed;
- phy[i].auto_negotiate = lxt972_auto_negotiate;
- break;
-#endif
-#ifdef PHY_DP83848
- case PHY_DP83848:
- sprintf(phy[i].name, "DP83848 @ 0x%02x",
- active_phy_addr[i]);
- phy[i].init = dp83848_init_phy;
- phy[i].is_phy_connected = dp83848_is_phy_connected;
- phy[i].get_link_speed = dp83848_get_link_speed;
- phy[i].auto_negotiate = dp83848_auto_negotiate;
- break;
-#endif
-#ifdef PHY_ET1011C
- case PHY_ET1011C:
- sprintf(phy[i].name, "ET1011C @ 0x%02x",
- active_phy_addr[i]);
- phy[i].init = gen_init_phy;
- phy[i].is_phy_connected = gen_is_phy_connected;
- phy[i].get_link_speed = et1011c_get_link_speed;
- phy[i].auto_negotiate = gen_auto_negotiate;
- break;
-#endif
- default:
- sprintf(phy[i].name, "GENERIC @ 0x%02x",
- active_phy_addr[i]);
- phy[i].init = gen_init_phy;
- phy[i].is_phy_connected = gen_is_phy_connected;
- phy[i].get_link_speed = gen_get_link_speed;
- phy[i].auto_negotiate = gen_auto_negotiate;
- }
+ sprintf(phy[i].name, "GENERIC @ 0x%02x",
+ active_phy_addr[i]);
+ phy[i].init = gen_init_phy;
+ phy[i].is_phy_connected = gen_is_phy_connected;
+ phy[i].get_link_speed = gen_get_link_speed;
+ phy[i].auto_negotiate = gen_auto_negotiate;
debug("Ethernet PHY: %s\n", phy[i].name);
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 0e6c559d5ef..f01bc77a576 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -116,6 +116,9 @@ static int pinconfig_post_bind(struct udevice *dev)
ofnode node;
int ret;
+ if (!dev_of_valid(dev))
+ return 0;
+
dev_for_each_subnode(node, dev) {
if (pre_reloc_only &&
!ofnode_pre_reloc(node))
diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c
index 9994cbafbff..88db294cf14 100644
--- a/drivers/pwm/rk_pwm.c
+++ b/drivers/pwm/rk_pwm.c
@@ -12,7 +12,7 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/pwm.h>
+#include <asm/arch-rockchip/pwm.h>
#include <power/regulator.h>
struct rk_pwm_priv {
diff --git a/drivers/ram/rockchip/dmc-rk3368.c b/drivers/ram/rockchip/dmc-rk3368.c
index 8d1b9faacc0..92f584fadcb 100644
--- a/drivers/ram/rockchip/dmc-rk3368.c
+++ b/drivers/ram/rockchip/dmc-rk3368.c
@@ -12,12 +12,12 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3368.h>
-#include <asm/arch/grf_rk3368.h>
-#include <asm/arch/ddr_rk3368.h>
-#include <asm/arch/sdram.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3368.h>
+#include <asm/arch-rockchip/grf_rk3368.h>
+#include <asm/arch-rockchip/ddr_rk3368.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
struct dram_info {
struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_rk3128.c b/drivers/ram/rockchip/sdram_rk3128.c
index df7b9887033..bfabc22a7d8 100644
--- a/drivers/ram/rockchip/sdram_rk3128.c
+++ b/drivers/ram/rockchip/sdram_rk3128.c
@@ -7,9 +7,9 @@
#include <dm.h>
#include <ram.h>
#include <syscon.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/grf_rk3128.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3128.h>
+#include <asm/arch-rockchip/sdram_common.h>
struct dram_info {
struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_rk3188.c b/drivers/ram/rockchip/sdram_rk3188.c
index fdd500aa472..00e52ec949e 100644
--- a/drivers/ram/rockchip/sdram_rk3188.c
+++ b/drivers/ram/rockchip/sdram_rk3188.c
@@ -15,13 +15,13 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3188.h>
-#include <asm/arch/ddr_rk3188.h>
-#include <asm/arch/grf_rk3188.h>
-#include <asm/arch/pmu_rk3188.h>
-#include <asm/arch/sdram.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3188.h>
+#include <asm/arch-rockchip/ddr_rk3188.h>
+#include <asm/arch-rockchip/grf_rk3188.h>
+#include <asm/arch-rockchip/pmu_rk3188.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
#include <linux/err.h>
struct chan_info {
diff --git a/drivers/ram/rockchip/sdram_rk322x.c b/drivers/ram/rockchip/sdram_rk322x.c
index 53835a9cd08..c596523d4ff 100644
--- a/drivers/ram/rockchip/sdram_rk322x.c
+++ b/drivers/ram/rockchip/sdram_rk322x.c
@@ -11,14 +11,14 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk322x.h>
-#include <asm/arch/grf_rk322x.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/sdram_rk322x.h>
-#include <asm/arch/timer.h>
-#include <asm/arch/uart.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk322x.h>
+#include <asm/arch-rockchip/grf_rk322x.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram_rk322x.h>
+#include <asm/arch-rockchip/timer.h>
+#include <asm/arch-rockchip/uart.h>
+#include <asm/arch-rockchip/sdram_common.h>
#include <asm/types.h>
#include <linux/err.h>
diff --git a/drivers/ram/rockchip/sdram_rk3288.c b/drivers/ram/rockchip/sdram_rk3288.c
index d1e52d84e7a..6bb025a851a 100644
--- a/drivers/ram/rockchip/sdram_rk3288.c
+++ b/drivers/ram/rockchip/sdram_rk3288.c
@@ -15,13 +15,13 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/ddr_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
-#include <asm/arch/pmu_rk3288.h>
-#include <asm/arch/sdram.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3288.h>
+#include <asm/arch-rockchip/ddr_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/pmu_rk3288.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
#include <linux/err.h>
#include <power/regulator.h>
#include <power/rk8xx_pmic.h>
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index e8b234d8665..f4e0b184470 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -7,9 +7,9 @@
#include <dm.h>
#include <ram.h>
#include <syscon.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/grf_rk3328.h>
-#include <asm/arch/sdram_common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3328.h>
+#include <asm/arch-rockchip/sdram_common.h>
struct dram_info {
struct ram_info info;
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 94dd01156a7..05ec5fc28d7 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -13,12 +13,12 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/sdram_common.h>
-#include <asm/arch/sdram_rk3399.h>
-#include <asm/arch/cru_rk3399.h>
-#include <asm/arch/grf_rk3399.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rk3399.h>
+#include <asm/arch-rockchip/cru_rk3399.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
#include <linux/err.h>
#include <time.h>
diff --git a/drivers/reset/reset-rockchip.c b/drivers/reset/reset-rockchip.c
index af071340495..3871fc00d07 100644
--- a/drivers/reset/reset-rockchip.c
+++ b/drivers/reset/reset-rockchip.c
@@ -7,7 +7,7 @@
#include <dm.h>
#include <reset-uclass.h>
#include <linux/io.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/hardware.h>
#include <dm/lists.h>
/*
* Each reg has 16 bits reset signal for devices
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index 35fefd74c69..b1718f72d1b 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -9,7 +9,7 @@
#include <dt-structs.h>
#include <ns16550.h>
#include <serial.h>
-#include <asm/arch/clock.h>
+#include <asm/arch-rockchip/clock.h>
#if defined(CONFIG_ROCKCHIP_RK3188)
struct rockchip_uart_platdata {
diff --git a/drivers/sound/rockchip_sound.c b/drivers/sound/rockchip_sound.c
index e7fb9fb1646..a092dbc4458 100644
--- a/drivers/sound/rockchip_sound.c
+++ b/drivers/sound/rockchip_sound.c
@@ -13,7 +13,7 @@
#include <i2s.h>
#include <misc.h>
#include <sound.h>
-#include <asm/arch/periph.h>
+#include <asm/arch-rockchip/periph.h>
#include <dm/pinctrl.h>
static int rockchip_sound_setup(struct udevice *dev)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index fb794adae72..2830f765877 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -133,7 +133,7 @@ config MPC8XX_SPI
config MT7621_SPI
bool "MediaTek MT7621 SPI driver"
- depends on ARCH_MT7620
+ depends on SOC_MT7628
help
Enable the MT7621 SPI driver. This driver can be used to access
the SPI NOR flash on platforms embedding this Ralink / MediaTek
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index 14437c0a9af..a68553b75bf 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -2,6 +2,8 @@
/*
* spi driver for rockchip
*
+ * (C) 2019 Theobroma Systems Design und Consulting GmbH
+ *
* (C) Copyright 2015 Google, Inc
*
* (C) Copyright 2008-2013 Rockchip Electronics
@@ -16,14 +18,19 @@
#include <spi.h>
#include <linux/errno.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/periph.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/periph.h>
#include <dm/pinctrl.h>
#include "rk_spi.h"
/* Change to 1 to output registers at the start of each transaction */
#define DEBUG_RK_SPI 0
+struct rockchip_spi_params {
+ /* RXFIFO overruns and TXFIFO underruns stop the master clock */
+ bool master_manages_fifo;
+};
+
struct rockchip_spi_platdata {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3288_spi of_plat;
@@ -40,11 +47,8 @@ struct rockchip_spi_priv {
unsigned int max_freq;
unsigned int mode;
ulong last_transaction_us; /* Time of last transaction end */
- u8 bits_per_word; /* max 16 bits per word */
- u8 n_bytes;
unsigned int speed_hz;
unsigned int last_speed_hz;
- unsigned int tmode;
uint input_rate;
};
@@ -130,8 +134,13 @@ static void spi_cs_activate(struct udevice *dev, uint cs)
if (plat->deactivate_delay_us && priv->last_transaction_us) {
ulong delay_us; /* The delay completed so far */
delay_us = timer_get_us() - priv->last_transaction_us;
- if (delay_us < plat->deactivate_delay_us)
- udelay(plat->deactivate_delay_us - delay_us);
+ if (delay_us < plat->deactivate_delay_us) {
+ ulong additional_delay_us =
+ plat->deactivate_delay_us - delay_us;
+ debug("%s: delaying by %ld us\n",
+ __func__, additional_delay_us);
+ udelay(additional_delay_us);
+ }
}
debug("activate cs%u\n", cs);
@@ -263,8 +272,6 @@ static int rockchip_spi_probe(struct udevice *bus)
}
priv->input_rate = ret;
debug("%s: rate = %u\n", __func__, priv->input_rate);
- priv->bits_per_word = 8;
- priv->tmode = TMOD_TR; /* Tx & Rx */
return 0;
}
@@ -274,28 +281,10 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct rockchip_spi_priv *priv = dev_get_priv(bus);
struct rockchip_spi *regs = priv->regs;
- u8 spi_dfs, spi_tf;
uint ctrlr0;
/* Disable the SPI hardware */
- rkspi_enable_chip(regs, 0);
-
- switch (priv->bits_per_word) {
- case 8:
- priv->n_bytes = 1;
- spi_dfs = DFS_8BIT;
- spi_tf = HALF_WORD_OFF;
- break;
- case 16:
- priv->n_bytes = 2;
- spi_dfs = DFS_16BIT;
- spi_tf = HALF_WORD_ON;
- break;
- default:
- debug("%s: unsupported bits: %dbits\n", __func__,
- priv->bits_per_word);
- return -EPROTONOSUPPORT;
- }
+ rkspi_enable_chip(regs, false);
if (priv->speed_hz != priv->last_speed_hz)
rkspi_set_clk(priv, priv->speed_hz);
@@ -304,7 +293,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
/* Data Frame Size */
- ctrlr0 |= spi_dfs << DFS_SHIFT;
+ ctrlr0 |= DFS_8BIT << DFS_SHIFT;
/* set SPI mode 0..3 */
if (priv->mode & SPI_CPOL)
@@ -325,7 +314,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
ctrlr0 |= FBM_MSB << FBM_SHIFT;
/* Byte and Halfword Transform */
- ctrlr0 |= spi_tf << HALF_WORD_TX_SHIFT;
+ ctrlr0 |= HALF_WORD_OFF << HALF_WORD_TX_SHIFT;
/* Rxd Sample Delay */
ctrlr0 |= 0 << RXDSD_SHIFT;
@@ -334,7 +323,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
ctrlr0 |= FRF_SPI << FRF_SHIFT;
/* Tx and Rx mode */
- ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
+ ctrlr0 |= TMOD_TR << TMOD_SHIFT;
writel(ctrlr0, &regs->ctrlr0);
@@ -351,6 +340,83 @@ static int rockchip_spi_release_bus(struct udevice *dev)
return 0;
}
+static inline int rockchip_spi_16bit_reader(struct udevice *dev,
+ u8 **din, int *len)
+{
+ struct udevice *bus = dev->parent;
+ const struct rockchip_spi_params * const data =
+ (void *)dev_get_driver_data(bus);
+ struct rockchip_spi_priv *priv = dev_get_priv(bus);
+ struct rockchip_spi *regs = priv->regs;
+ const u32 saved_ctrlr0 = readl(&regs->ctrlr0);
+#if defined(DEBUG)
+ u32 statistics_rxlevels[33] = { };
+#endif
+ u32 frames = *len / 2;
+ u8 *in = (u8 *)(*din);
+ u32 max_chunk_size = SPI_FIFO_DEPTH;
+
+ if (!frames)
+ return 0;
+
+ /*
+ * If we know that the hardware will manage RXFIFO overruns
+ * (i.e. stop the SPI clock until there's space in the FIFO),
+ * we the allow largest possible chunk size that can be
+ * represented in CTRLR1.
+ */
+ if (data && data->master_manages_fifo)
+ max_chunk_size = 0x10000;
+
+ // rockchip_spi_configure(dev, mode, size)
+ rkspi_enable_chip(regs, false);
+ clrsetbits_le32(&regs->ctrlr0,
+ TMOD_MASK << TMOD_SHIFT,
+ TMOD_RO << TMOD_SHIFT);
+ /* 16bit data frame size */
+ clrsetbits_le32(&regs->ctrlr0, DFS_MASK, DFS_16BIT);
+
+ /* Update caller's context */
+ const u32 bytes_to_process = 2 * frames;
+ *din += bytes_to_process;
+ *len -= bytes_to_process;
+
+ /* Process our frames */
+ while (frames) {
+ u32 chunk_size = min(frames, max_chunk_size);
+
+ frames -= chunk_size;
+
+ writew(chunk_size - 1, &regs->ctrlr1);
+ rkspi_enable_chip(regs, true);
+
+ do {
+ u32 rx_level = readw(&regs->rxflr);
+#if defined(DEBUG)
+ statistics_rxlevels[rx_level]++;
+#endif
+ chunk_size -= rx_level;
+ while (rx_level--) {
+ u16 val = readw(regs->rxdr);
+ *in++ = val & 0xff;
+ *in++ = val >> 8;
+ }
+ } while (chunk_size);
+
+ rkspi_enable_chip(regs, false);
+ }
+
+#if defined(DEBUG)
+ debug("%s: observed rx_level during processing:\n", __func__);
+ for (int i = 0; i <= 32; ++i)
+ if (statistics_rxlevels[i])
+ debug("\t%2d: %d\n", i, statistics_rxlevels[i]);
+#endif
+ /* Restore the original transfer setup and return error-free. */
+ writel(saved_ctrlr0, &regs->ctrlr0);
+ return 0;
+}
+
static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
@@ -362,7 +428,7 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
const u8 *out = dout;
u8 *in = din;
int toread, towrite;
- int ret;
+ int ret = 0;
debug("%s: dout=%p, din=%p, len=%x, flags=%lx\n", __func__, dout, din,
len, flags);
@@ -373,8 +439,18 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
if (flags & SPI_XFER_BEGIN)
spi_cs_activate(dev, slave_plat->cs);
+ /*
+ * To ensure fast loading of firmware images (e.g. full U-Boot
+ * stage, ATF, Linux kernel) from SPI flash, we optimise the
+ * case of read-only transfers by using the full 16bits of each
+ * FIFO element.
+ */
+ if (!out)
+ ret = rockchip_spi_16bit_reader(dev, &in, &len);
+
+ /* This is the original 8bit reader/writer code */
while (len > 0) {
- int todo = min(len, 0xffff);
+ int todo = min(len, 0x10000);
rkspi_enable_chip(regs, false);
writel(todo - 1, &regs->ctrlr1);
@@ -397,9 +473,18 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
toread--;
}
}
- ret = rkspi_wait_till_not_busy(regs);
- if (ret)
- break;
+
+ /*
+ * In case that there's a transmit-component, we need to wait
+ * until the control goes idle before we can disable the SPI
+ * control logic (as this will implictly flush the FIFOs).
+ */
+ if (out) {
+ ret = rkspi_wait_till_not_busy(regs);
+ if (ret)
+ break;
+ }
+
len -= todo;
}
@@ -446,10 +531,16 @@ static const struct dm_spi_ops rockchip_spi_ops = {
*/
};
+const struct rockchip_spi_params rk3399_spi_params = {
+ .master_manages_fifo = true,
+};
+
static const struct udevice_id rockchip_spi_ids[] = {
{ .compatible = "rockchip,rk3288-spi" },
- { .compatible = "rockchip,rk3368-spi" },
- { .compatible = "rockchip,rk3399-spi" },
+ { .compatible = "rockchip,rk3368-spi",
+ .data = (ulong)&rk3399_spi_params },
+ { .compatible = "rockchip,rk3399-spi",
+ .data = (ulong)&rk3399_spi_params },
{ }
};
diff --git a/drivers/sysreset/sysreset_rockchip.c b/drivers/sysreset/sysreset_rockchip.c
index 93d7cfe463a..0fc6b683f2b 100644
--- a/drivers/sysreset/sysreset_rockchip.c
+++ b/drivers/sysreset/sysreset_rockchip.c
@@ -8,9 +8,9 @@
#include <errno.h>
#include <sysreset.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3328.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3328.h>
+#include <asm/arch-rockchip/hardware.h>
#include <linux/err.h>
int rockchip_sysreset_request(struct udevice *dev, enum sysreset_t type)
diff --git a/drivers/timer/rockchip_timer.c b/drivers/timer/rockchip_timer.c
index 69019740b0d..54956e557a1 100644
--- a/drivers/timer/rockchip_timer.c
+++ b/drivers/timer/rockchip_timer.c
@@ -7,7 +7,7 @@
#include <dm.h>
#include <dm/ofnode.h>
#include <mapmem.h>
-#include <asm/arch/timer.h>
+#include <asm/arch-rockchip/timer.h>
#include <dt-structs.h>
#include <timer.h>
#include <asm/io.h>
diff --git a/drivers/usb/gadget/f_rockusb.c b/drivers/usb/gadget/f_rockusb.c
index e81eb164b0d..f3d24772cde 100644
--- a/drivers/usb/gadget/f_rockusb.c
+++ b/drivers/usb/gadget/f_rockusb.c
@@ -15,7 +15,7 @@
#include <linux/compiler.h>
#include <version.h>
#include <g_dnl.h>
-#include <asm/arch/f_rockusb.h>
+#include <asm/arch-rockchip/f_rockusb.h>
static inline struct f_rockusb *func_to_rockusb(struct usb_function *f)
{
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1c2212f547b..b1188bcbf52 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -246,6 +246,11 @@ config USB_OHCI_GENERIC
---help---
Enables support for generic OHCI controller.
+config USB_OHCI_DA8XX
+ bool "Support for da850 OHCI USB controller"
+ help
+ Enable support for the da850 USB controller.
+
endif # USB_OHCI_HCD
config USB_UHCI_HCD
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 47ad3f34d5a..e8a495fde59 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -4,9 +4,54 @@
*/
#include <common.h>
-
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/ofnode.h>
+#include <generic-phy.h>
+#include <reset.h>
+#include "ohci.h"
#include <asm/arch/da8xx-usb.h>
+struct da8xx_ohci {
+ ohci_t ohci;
+ struct clk *clocks; /* clock list */
+ struct phy phy;
+ int clock_count; /* number of clock in clock list */
+};
+
+static int usb_phy_on(void)
+{
+ unsigned long timeout;
+
+ clrsetbits_le32(&davinci_syscfg_regs->cfgchip2,
+ (CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN |
+ CFGCHIP2_OTGPWRDN | CFGCHIP2_OTGMODE |
+ CFGCHIP2_REFFREQ | CFGCHIP2_USB1PHYCLKMUX),
+ (CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN |
+ CFGCHIP2_PHY_PLLON | CFGCHIP2_REFFREQ_24MHZ |
+ CFGCHIP2_USB2PHYCLKMUX | CFGCHIP2_USB1SUSPENDM));
+
+ /* wait until the usb phy pll locks */
+ timeout = get_timer(0);
+ while (get_timer(timeout) < 10) {
+ if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD)
+ return 1;
+ }
+
+ /* USB phy was not turned on */
+ return 0;
+}
+
+static void usb_phy_off(void)
+{
+ /* Power down the on-chip PHY. */
+ clrsetbits_le32(&davinci_syscfg_regs->cfgchip2,
+ CFGCHIP2_PHY_PLLON | CFGCHIP2_USB1SUSPENDM,
+ CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN |
+ CFGCHIP2_RESET);
+}
+
int usb_cpu_init(void)
{
/* enable psc for usb2.0 */
@@ -37,3 +82,94 @@ int usb_cpu_init_fail(void)
{
return usb_cpu_stop();
}
+
+#if CONFIG_IS_ENABLED(DM_USB)
+static int ohci_da8xx_probe(struct udevice *dev)
+{
+ struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
+ struct da8xx_ohci *priv = dev_get_priv(dev);
+ int i, err, ret, clock_nb;
+
+ err = 0;
+ priv->clock_count = 0;
+ clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
+ if (clock_nb > 0) {
+ priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
+ GFP_KERNEL);
+ if (!priv->clocks)
+ return -ENOMEM;
+
+ for (i = 0; i < clock_nb; i++) {
+ err = clk_get_by_index(dev, i, &priv->clocks[i]);
+ if (err < 0)
+ break;
+
+ err = clk_enable(&priv->clocks[i]);
+ if (err) {
+ dev_err(dev, "failed to enable clock %d\n", i);
+ clk_free(&priv->clocks[i]);
+ goto clk_err;
+ }
+ priv->clock_count++;
+ }
+ } else if (clock_nb != -ENOENT) {
+ dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb);
+ return clock_nb;
+ }
+
+ err = usb_cpu_init();
+
+ if (err)
+ goto clk_err;
+
+ err = ohci_register(dev, regs);
+ if (err)
+ goto phy_err;
+
+ return 0;
+
+phy_err:
+ ret = usb_cpu_stop();
+ if (ret)
+ dev_err(dev, "failed to shutdown usb phy\n");
+
+clk_err:
+ ret = clk_release_all(priv->clocks, priv->clock_count);
+ if (ret)
+ dev_err(dev, "failed to disable all clocks\n");
+
+ return err;
+}
+
+static int ohci_da8xx_remove(struct udevice *dev)
+{
+ struct da8xx_ohci *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = ohci_deregister(dev);
+ if (ret)
+ return ret;
+
+ ret = usb_cpu_stop();
+ if (ret)
+ return ret;
+
+ return clk_release_all(priv->clocks, priv->clock_count);
+}
+
+static const struct udevice_id da8xx_ohci_ids[] = {
+ { .compatible = "ti,da830-ohci" },
+ { }
+};
+
+U_BOOT_DRIVER(ohci_generic) = {
+ .name = "ohci-da8xx",
+ .id = UCLASS_USB,
+ .of_match = da8xx_ohci_ids,
+ .probe = ohci_da8xx_probe,
+ .remove = ohci_da8xx_remove,
+ .ops = &ohci_usb_ops,
+ .priv_auto_alloc_size = sizeof(struct da8xx_ohci),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 3b6f889f7b7..2b0df88f49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1545,10 +1545,8 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
return -1;
}
-#if 0
mdelay(10);
/* ohci_dump_status(ohci); */
-#endif
timeout = USB_TIMEOUT_MS(pipe);
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 2ee0f23b7ed..1f2805270aa 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -327,9 +327,7 @@ static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
csr = readw(&musbr->txcsr);
csr |= MUSB_CSR0_TXPKTRDY;
-#if !defined(CONFIG_SOC_DM365)
csr |= MUSB_CSR0_H_DIS_PING;
-#endif
writew(csr, &musbr->txcsr);
result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
if (result < 0)
@@ -352,9 +350,7 @@ static int ctrlreq_out_status_phase(struct usb_device *dev)
/* Set the StatusPkt bit */
csr = readw(&musbr->txcsr);
csr |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_H_STATUSPKT);
-#if !defined(CONFIG_SOC_DM365)
csr |= MUSB_CSR0_H_DIS_PING;
-#endif
writew(csr, &musbr->txcsr);
/* Wait until TXPKTRDY bit is cleared */
@@ -372,9 +368,7 @@ static int ctrlreq_in_status_phase(struct usb_device *dev)
/* Set the StatusPkt bit and ReqPkt bit */
csr = MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
-#if !defined(CONFIG_SOC_DM365)
csr |= MUSB_CSR0_H_DIS_PING;
-#endif
writew(csr, &musbr->txcsr);
result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
index eb3692c3871..315d3adf275 100644
--- a/drivers/video/rockchip/rk3288_hdmi.c
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -13,9 +13,9 @@
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/grf_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
#include <power/regulator.h>
#include "rk_hdmi.h"
diff --git a/drivers/video/rockchip/rk3288_mipi.c b/drivers/video/rockchip/rk3288_mipi.c
index d268b465148..7c4a4cc53b0 100644
--- a/drivers/video/rockchip/rk3288_mipi.c
+++ b/drivers/video/rockchip/rk3288_mipi.c
@@ -14,14 +14,14 @@
#include "rk_mipi.h"
#include <syscon.h>
#include <asm/gpio.h>
-#include <asm/hardware.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <linux/kernel.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
-#include <asm/arch/rockchip_mipi_dsi.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/rockchip_mipi_dsi.h>
#define MHz 1000000
diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c
index 7e953a628c1..0f91dab1f25 100644
--- a/drivers/video/rockchip/rk3288_vop.c
+++ b/drivers/video/rockchip/rk3288_vop.c
@@ -11,10 +11,10 @@
#include <regmap.h>
#include <syscon.h>
#include <video.h>
-#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/grf_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/hardware.h>
#include "rk_vop.h"
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/video/rockchip/rk3399_hdmi.c b/drivers/video/rockchip/rk3399_hdmi.c
index b75efe6fc32..a62be983275 100644
--- a/drivers/video/rockchip/rk3399_hdmi.c
+++ b/drivers/video/rockchip/rk3399_hdmi.c
@@ -13,9 +13,9 @@
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/grf_rk3399.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
#include <power/regulator.h>
#include "rk_hdmi.h"
diff --git a/drivers/video/rockchip/rk3399_mipi.c b/drivers/video/rockchip/rk3399_mipi.c
index bb9007bf363..a93b73400be 100644
--- a/drivers/video/rockchip/rk3399_mipi.c
+++ b/drivers/video/rockchip/rk3399_mipi.c
@@ -14,14 +14,14 @@
#include "rk_mipi.h"
#include <syscon.h>
#include <asm/gpio.h>
-#include <asm/hardware.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <linux/kernel.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3399.h>
-#include <asm/arch/grf_rk3399.h>
-#include <asm/arch/rockchip_mipi_dsi.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3399.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/rockchip_mipi_dsi.h>
/* Select mipi dsi source, big or little vop */
static int rk_mipi_dsi_source_select(struct udevice *dev)
diff --git a/drivers/video/rockchip/rk3399_vop.c b/drivers/video/rockchip/rk3399_vop.c
index 7a02221ae0b..81c122d7a9e 100644
--- a/drivers/video/rockchip/rk3399_vop.c
+++ b/drivers/video/rockchip/rk3399_vop.c
@@ -10,7 +10,7 @@
#include <dm.h>
#include <regmap.h>
#include <video.h>
-#include <asm/hardware.h>
+#include <asm/arch-rockchip/hardware.h>
#include <asm/io.h>
#include "rk_vop.h"
diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c
index e0741076324..4330725a251 100644
--- a/drivers/video/rockchip/rk_edp.c
+++ b/drivers/video/rockchip/rk_edp.c
@@ -14,9 +14,9 @@
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/edp_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/edp_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
#include <dt-bindings/clock/rk3288-cru.h>
#define MAX_CR_LOOP 5
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index 13d07ee3048..51931ceefae 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -14,10 +14,9 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/gpio.h>
-#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
#include "rk_hdmi.h"
#include "rk_vop.h" /* for rk_vop_probe_regulators */
diff --git a/drivers/video/rockchip/rk_lvds.c b/drivers/video/rockchip/rk_lvds.c
index f0a528c0d6d..cf5c0439b1a 100644
--- a/drivers/video/rockchip/rk_lvds.c
+++ b/drivers/video/rockchip/rk_lvds.c
@@ -12,9 +12,9 @@
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/lvds_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/lvds_rk3288.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include <dt-bindings/video/rk3288.h>
diff --git a/drivers/video/rockchip/rk_mipi.c b/drivers/video/rockchip/rk_mipi.c
index 4f1a0f3a5f7..bcd039b7bc6 100644
--- a/drivers/video/rockchip/rk_mipi.c
+++ b/drivers/video/rockchip/rk_mipi.c
@@ -14,14 +14,13 @@
#include "rk_mipi.h"
#include <syscon.h>
#include <asm/gpio.h>
-#include <asm/hardware.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <linux/kernel.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3399.h>
-#include <asm/arch/grf_rk3399.h>
-#include <asm/arch/rockchip_mipi_dsi.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3399.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/rockchip_mipi_dsi.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index faf4f24db04..b56c3f336c9 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -13,11 +13,10 @@
#include <syscon.h>
#include <video.h>
#include <asm/gpio.h>
-#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/edp_rk3288.h>
-#include <asm/arch/vop_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/edp_rk3288.h>
+#include <asm/arch-rockchip/vop_rk3288.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <power/regulator.h>
diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h
index 828974d394f..8fa2f389390 100644
--- a/drivers/video/rockchip/rk_vop.h
+++ b/drivers/video/rockchip/rk_vop.h
@@ -6,7 +6,7 @@
#ifndef __RK_VOP_H__
#define __RK_VOP_H__
-#include <asm/arch/vop_rk3288.h>
+#include <asm/arch-rockchip/vop_rk3288.h>
struct rk_vop_priv {
void *grf;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3bce0aa0b87..f909d40f455 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -55,7 +55,7 @@ config WDT
help
Enable driver model for watchdog timer. At the moment the API
is very simple and only supports four operations:
- start, restart, stop and reset (expire immediately).
+ start, stop, reset and expire_now (expire immediately).
What exactly happens when the timer expires is up to a particular
device/driver.
@@ -143,7 +143,7 @@ config WDT_AT91
config WDT_MT7621
bool "MediaTek MT7621 watchdog timer support"
- depends on WDT && ARCH_MT7620
+ depends on WDT && SOC_MT7628
help
Select this to enable Ralink / Mediatek watchdog timer,
which can be found on some MediaTek chips.