From: Masahiro Yamada <yamada.masahiro@socionext.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 9/9] reset: uniphier: add reset controller driver for UniPhier SoCs
Date: Sat, 8 Oct 2016 13:25:31 +0900 [thread overview]
Message-ID: <1475900731-10998-10-git-send-email-yamada.masahiro@socionext.com> (raw)
In-Reply-To: <1475900731-10998-1-git-send-email-yamada.masahiro@socionext.com>
This is the initial commit for UniPhier reset controller driver.
Most code was ported from Linux.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
arch/arm/Kconfig | 1 +
drivers/reset/Kconfig | 9 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-uniphier.c | 376 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 387 insertions(+)
create mode 100644 drivers/reset/reset-uniphier.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f55d5b2..861b86e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -813,6 +813,7 @@ config ARCH_UNIPHIER
select DM_GPIO
select DM_I2C
select DM_MMC
+ select DM_RESET
select DM_SERIAL
select DM_USB
select OF_CONTROL
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 4fcc0d9..c42b0bc 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -34,4 +34,13 @@ config TEGRA186_RESET
Enable support for manipulating Tegra's on-SoC reset signals via IPC
requests to the BPMP (Boot and Power Management Processor).
+config RESET_UNIPHIER
+ bool "Reset controller driver for UniPhier SoCs"
+ depends on ARCH_UNIPHIER
+ default y
+ help
+ Support for reset controllers on UniPhier SoCs.
+ Say Y if you want to control reset signals provided by System Control
+ block, Media I/O block, Peripheral Block.
+
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 5d4ea3d..5c4305c 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset.o
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset-test.o
obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
+obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
new file mode 100644
index 0000000..29c4d4d
--- /dev/null
+++ b/drivers/reset/reset-uniphier.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <reset-uclass.h>
+#include <dm/device.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+struct uniphier_reset_data {
+ unsigned int id;
+ unsigned int reg;
+ unsigned int bit;
+ unsigned int flags;
+#define UNIPHIER_RESET_ACTIVE_LOW BIT(0)
+};
+
+#define UNIPHIER_RESET_ID_END (unsigned int)(-1)
+
+#define UNIPHIER_RESET_END \
+ { .id = UNIPHIER_RESET_ID_END }
+
+#define UNIPHIER_RESET(_id, _reg, _bit) \
+ { \
+ .id = (_id), \
+ .reg = (_reg), \
+ .bit = (_bit), \
+ }
+
+#define UNIPHIER_RESETX(_id, _reg, _bit) \
+ { \
+ .id = (_id), \
+ .reg = (_reg), \
+ .bit = (_bit), \
+ .flags = UNIPHIER_RESET_ACTIVE_LOW, \
+ }
+
+/* System reset data */
+#define UNIPHIER_SLD3_SYS_RESET_STDMAC(id) \
+ UNIPHIER_RESETX((id), 0x2000, 10)
+
+#define UNIPHIER_LD11_SYS_RESET_STDMAC(id) \
+ UNIPHIER_RESETX((id), 0x200c, 8)
+
+#define UNIPHIER_PRO4_SYS_RESET_GIO(id) \
+ UNIPHIER_RESETX((id), 0x2000, 6)
+
+#define UNIPHIER_LD20_SYS_RESET_GIO(id) \
+ UNIPHIER_RESETX((id), 0x200c, 5)
+
+#define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch) \
+ UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17)
+
+const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = {
+ UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* Ether, HSC, MIO */
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
+ UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, MIO, RLE */
+ UNIPHIER_PRO4_SYS_RESET_GIO(12), /* Ether, SATA, USB3 */
+ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
+ UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
+ UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC */
+ UNIPHIER_PRO4_SYS_RESET_GIO(12), /* PCIe, USB3 */
+ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
+ UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
+ UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, RLE */
+ UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
+ UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+ UNIPHIER_RESETX(16, 0x2014, 4), /* USB30-PHY0 */
+ UNIPHIER_RESETX(17, 0x2014, 0), /* USB30-PHY1 */
+ UNIPHIER_RESETX(18, 0x2014, 2), /* USB30-PHY2 */
+ UNIPHIER_RESETX(20, 0x2014, 5), /* USB31-PHY0 */
+ UNIPHIER_RESETX(21, 0x2014, 1), /* USB31-PHY1 */
+ UNIPHIER_RESETX(28, 0x2014, 12), /* SATA */
+ UNIPHIER_RESET(29, 0x2014, 8), /* SATA-PHY (active high) */
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
+ UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC, MIO */
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
+ UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC */
+ UNIPHIER_LD20_SYS_RESET_GIO(12), /* PCIe, USB3 */
+ UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */
+ UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */
+ UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */
+ UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */
+ UNIPHIER_RESET_END,
+};
+
+/* Media I/O reset data */
+#define UNIPHIER_MIO_RESET_SD(id, ch) \
+ UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 0)
+
+#define UNIPHIER_MIO_RESET_SD_BRIDGE(id, ch) \
+ UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 26)
+
+#define UNIPHIER_MIO_RESET_EMMC_HW_RESET(id, ch) \
+ UNIPHIER_RESETX((id), 0x80 + 0x200 * (ch), 0)
+
+#define UNIPHIER_MIO_RESET_USB2(id, ch) \
+ UNIPHIER_RESETX((id), 0x114 + 0x200 * (ch), 0)
+
+#define UNIPHIER_MIO_RESET_USB2_BRIDGE(id, ch) \
+ UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 24)
+
+#define UNIPHIER_MIO_RESET_DMAC(id) \
+ UNIPHIER_RESETX((id), 0x110, 17)
+
+const struct uniphier_reset_data uniphier_mio_reset_data[] = {
+ UNIPHIER_MIO_RESET_SD(0, 0),
+ UNIPHIER_MIO_RESET_SD(1, 1),
+ UNIPHIER_MIO_RESET_SD(2, 2),
+ UNIPHIER_MIO_RESET_SD_BRIDGE(3, 0),
+ UNIPHIER_MIO_RESET_SD_BRIDGE(4, 1),
+ UNIPHIER_MIO_RESET_SD_BRIDGE(5, 2),
+ UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1),
+ UNIPHIER_MIO_RESET_DMAC(7),
+ UNIPHIER_MIO_RESET_USB2(8, 0),
+ UNIPHIER_MIO_RESET_USB2(9, 1),
+ UNIPHIER_MIO_RESET_USB2(10, 2),
+ UNIPHIER_MIO_RESET_USB2(11, 3),
+ UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0),
+ UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1),
+ UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2),
+ UNIPHIER_MIO_RESET_USB2_BRIDGE(15, 3),
+ UNIPHIER_RESET_END,
+};
+
+/* Peripheral reset data */
+#define UNIPHIER_PERI_RESET_UART(id, ch) \
+ UNIPHIER_RESETX((id), 0x114, 19 + (ch))
+
+#define UNIPHIER_PERI_RESET_I2C(id, ch) \
+ UNIPHIER_RESETX((id), 0x114, 5 + (ch))
+
+#define UNIPHIER_PERI_RESET_FI2C(id, ch) \
+ UNIPHIER_RESETX((id), 0x114, 24 + (ch))
+
+const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
+ UNIPHIER_PERI_RESET_UART(0, 0),
+ UNIPHIER_PERI_RESET_UART(1, 1),
+ UNIPHIER_PERI_RESET_UART(2, 2),
+ UNIPHIER_PERI_RESET_UART(3, 3),
+ UNIPHIER_PERI_RESET_I2C(4, 0),
+ UNIPHIER_PERI_RESET_I2C(5, 1),
+ UNIPHIER_PERI_RESET_I2C(6, 2),
+ UNIPHIER_PERI_RESET_I2C(7, 3),
+ UNIPHIER_PERI_RESET_I2C(8, 4),
+ UNIPHIER_RESET_END,
+};
+
+const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
+ UNIPHIER_PERI_RESET_UART(0, 0),
+ UNIPHIER_PERI_RESET_UART(1, 1),
+ UNIPHIER_PERI_RESET_UART(2, 2),
+ UNIPHIER_PERI_RESET_UART(3, 3),
+ UNIPHIER_PERI_RESET_FI2C(4, 0),
+ UNIPHIER_PERI_RESET_FI2C(5, 1),
+ UNIPHIER_PERI_RESET_FI2C(6, 2),
+ UNIPHIER_PERI_RESET_FI2C(7, 3),
+ UNIPHIER_PERI_RESET_FI2C(8, 4),
+ UNIPHIER_PERI_RESET_FI2C(9, 5),
+ UNIPHIER_PERI_RESET_FI2C(10, 6),
+ UNIPHIER_RESET_END,
+};
+
+/* core implementaton */
+struct uniphier_reset_priv {
+ void __iomem *base;
+ const struct uniphier_reset_data *data;
+};
+
+static int uniphier_reset_request(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int uniphier_reset_free(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int uniphier_reset_update(struct reset_ctl *reset_ctl, int assert)
+{
+ struct uniphier_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ unsigned long id = reset_ctl->id;
+ const struct uniphier_reset_data *p;
+
+ for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) {
+ u32 mask, val;
+
+ if (p->id != id)
+ continue;
+
+ val = readl(priv->base + p->reg);
+
+ if (p->flags & UNIPHIER_RESET_ACTIVE_LOW)
+ assert = !assert;
+
+ mask = BIT(p->bit);
+
+ if (assert)
+ val |= mask;
+ else
+ val &= ~mask;
+
+ writel(val, priv->base + p->reg);
+
+ return 0;
+ }
+
+ dev_err(priv->dev, "reset_id=%lu was not handled\n", id);
+ return -EINVAL;
+}
+
+static int uniphier_reset_assert(struct reset_ctl *reset_ctl)
+{
+ return uniphier_reset_update(reset_ctl, 1);
+}
+
+static int uniphier_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ return uniphier_reset_update(reset_ctl, 0);
+}
+
+static const struct reset_ops uniphier_reset_ops = {
+ .request = uniphier_reset_request,
+ .free = uniphier_reset_free,
+ .rst_assert = uniphier_reset_assert,
+ .rst_deassert = uniphier_reset_deassert,
+};
+
+static int uniphier_reset_probe(struct udevice *dev)
+{
+ struct uniphier_reset_priv *priv = dev_get_priv(dev);
+ fdt_addr_t addr;
+
+ addr = dev_get_addr(dev->parent);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->base = devm_ioremap(dev, addr, SZ_4K);
+ if (!priv->base)
+ return -ENOMEM;
+
+ priv->data = (void *)dev_get_driver_data(dev);
+
+ return 0;
+}
+
+static const struct udevice_id uniphier_reset_match[] = {
+ /* System reset */
+ {
+ .compatible = "socionext,uniphier-sld3-reset",
+ .data = (ulong)uniphier_sld3_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld4-reset",
+ .data = (ulong)uniphier_sld3_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro4-reset",
+ .data = (ulong)uniphier_pro4_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-sld8-reset",
+ .data = (ulong)uniphier_sld3_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro5-reset",
+ .data = (ulong)uniphier_pro5_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pxs2-reset",
+ .data = (ulong)uniphier_pxs2_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld11-reset",
+ .data = (ulong)uniphier_ld11_sys_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld20-reset",
+ .data = (ulong)uniphier_ld20_sys_reset_data,
+ },
+ /* Media I/O reset */
+ {
+ .compatible = "socionext,uniphier-sld3-mio-clock",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld4-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro4-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-sld8-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro5-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pxs2-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld11-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld20-mio-reset",
+ .data = (ulong)uniphier_mio_reset_data,
+ },
+ /* Peripheral reset */
+ {
+ .compatible = "socionext,uniphier-ld4-peri-reset",
+ .data = (ulong)uniphier_ld4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro4-peri-reset",
+ .data = (ulong)uniphier_pro4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-sld8-peri-reset",
+ .data = (ulong)uniphier_ld4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pro5-peri-reset",
+ .data = (ulong)uniphier_pro4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-pxs2-peri-reset",
+ .data = (ulong)uniphier_pro4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld11-peri-reset",
+ .data = (ulong)uniphier_pro4_peri_reset_data,
+ },
+ {
+ .compatible = "socionext,uniphier-ld20-peri-reset",
+ .data = (ulong)uniphier_pro4_peri_reset_data,
+ },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(uniphier_reset) = {
+ .name = "uniphier-reset",
+ .id = UCLASS_RESET,
+ .of_match = uniphier_reset_match,
+ .probe = uniphier_reset_probe,
+ .priv_auto_alloc_size = sizeof(struct uniphier_reset_priv),
+ .ops = &uniphier_reset_ops,
+};
--
1.9.1
next prev parent reply other threads:[~2016-10-08 4:25 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-08 4:25 [U-Boot] [PATCH 0/9] ARM: uniphier: UniPhier updates for v2016.11-rc2 Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 1/9] ARM: uniphier: enable SSC for DPLL (DRAM PLL) on LD11 SoC Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 2/9] ARM: uniphier: update DRAM init code for LD20 SoC (2nd) Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 3/9] ARM: uniphier: add work-around for VBO noise problem Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 4/9] ARM: uniphier: fix typos in a comment block Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 5/9] ARM: uniphier: enable CONFIG_SYS_NO_FLASH if no CONFIG_MICRO_SUPPORT_CARD Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 6/9] ARM: uniphier: define CONFIG_SMC911X along with CONFIG_MICRO_SUPPORT_CARD Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 7/9] ARM: uniphier: insert udelay() just before support_card_reset_deassert() Masahiro Yamada
2016-10-08 4:25 ` [U-Boot] [PATCH 8/9] reset: declare fdtdec_phandle_args as struct to fix warning Masahiro Yamada
2016-10-08 5:03 ` Masahiro Yamada
2016-10-13 0:03 ` Simon Glass
2016-10-08 4:25 ` Masahiro Yamada [this message]
2016-10-10 1:07 ` [U-Boot] [PATCH 0/9] ARM: uniphier: UniPhier updates for v2016.11-rc2 Masahiro Yamada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1475900731-10998-10-git-send-email-yamada.masahiro@socionext.com \
--to=yamada.masahiro@socionext.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.