* [PATCH v2 04/28] i.MX: scripts: Add "vf610" soc to imx-image
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Needed in order to support Vybrid SoCs.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
scripts/imx/imx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index c8ee309..bd48321 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -223,6 +223,7 @@ static struct soc_type socs[] = {
{ .name = "imx51", .header_version = 1, .cpu_type = IMX_CPU_IMX51 },
{ .name = "imx53", .header_version = 2, .cpu_type = IMX_CPU_IMX53 },
{ .name = "imx6", .header_version = 2, .cpu_type = IMX_CPU_IMX6 },
+ { .name = "vf610", .header_version = 2, .cpu_type = IMX_CPU_VF610 },
};
static int do_soc(struct config_data *data, int argc, char *argv[])
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH v2 01/28] i.MX: Add primitive functions for VF610 family
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Add very basic functions to support VF610 family.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
arch/arm/mach-imx/Kconfig | 10 ++++++++++
arch/arm/mach-imx/cpu_init.c | 5 +++++
arch/arm/mach-imx/imx.c | 4 ++++
arch/arm/mach-imx/include/mach/generic.h | 13 +++++++++++++
arch/arm/mach-imx/include/mach/imx_cpu_types.h | 1 +
5 files changed, 33 insertions(+)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index f23af99..cfbaaa2 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -149,6 +149,16 @@ config ARCH_IMX6SX
select OFTREE
select COMMON_CLK_OF_PROVIDER
+config ARCH_VF610
+ bool
+ select ARCH_HAS_L2X0
+ select ARCH_HAS_FEC_IMX
+ select CPU_V7
+ select PINCTRL
+ select OFTREE
+ select COMMON_CLK
+ select COMMON_CLK_OF_PROVIDER
+
config IMX_MULTI_BOARDS
bool "Allow multiple boards to be selected"
select HAVE_PBL_MULTI_IMAGES
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index 7603883..6971d89 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -33,3 +33,8 @@ void imx6_cpu_lowlevel_init(void)
enable_arm_errata_794072_war();
enable_arm_errata_845369_war();
}
+
+void vf610_cpu_lowlevel_init(void)
+{
+ arm_cpu_lowlevel_init();
+}
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 5ab6afc..eb2adcd 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -63,6 +63,8 @@ static int imx_soc_from_dt(void)
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6qp"))
return IMX_CPU_IMX6;
+ if (of_machine_is_compatible("fsl,vf610"))
+ return IMX_CPU_VF610;
return 0;
}
@@ -99,6 +101,8 @@ static int imx_init(void)
ret = imx53_init();
else if (cpu_is_mx6())
ret = imx6_init();
+ else if (cpu_is_vf610())
+ ret = 0;
else
return -EINVAL;
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 7c275df..3419450 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -45,6 +45,7 @@ int imx6_devices_init(void);
void imx5_cpu_lowlevel_init(void);
void imx6_cpu_lowlevel_init(void);
+void vf610_cpu_lowlevel_init(void);
/* There's a off-by-one betweem the gpio bank number and the gpiochip */
/* range e.g. GPIO_1_5 is gpio 5 under linux */
@@ -173,6 +174,18 @@ extern unsigned int __imx_cpu_type;
# define cpu_is_mx6() (0)
#endif
+#ifdef CONFIG_ARCH_VF610
+# ifdef imx_cpu_type
+# undef imx_cpu_type
+# define imx_cpu_type __imx_cpu_type
+# else
+# define imx_cpu_type IMX_CPU_VF610
+# endif
+# define cpu_is_vf610() (imx_cpu_type == IMX_CPU_VF610)
+#else
+# define cpu_is_vf610() (0)
+#endif
+
#define cpu_is_mx23() (0)
#define cpu_is_mx28() (0)
diff --git a/arch/arm/mach-imx/include/mach/imx_cpu_types.h b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
index 8472488..50be0b6 100644
--- a/arch/arm/mach-imx/include/mach/imx_cpu_types.h
+++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
@@ -11,5 +11,6 @@
#define IMX_CPU_IMX51 51
#define IMX_CPU_IMX53 53
#define IMX_CPU_IMX6 6
+#define IMX_CPU_VF610 610
#endif /* __MACH_IMX_CPU_TYPES_H */
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH v2 00/28] Vybrid support in Barebox
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
Hi everyone,
It took me a bit more than a month, but I finally put together a
second version (for v1 see [1]) of the Vybrid support patchset.
Some highlights of this version:
- Various code/commit arrangement feedback for v1 is addressed
- Added commit to move all of the i.MX clock code to drivers/clk
(Sascha, we'd probably have to coordinate with your i.MX6ul
patches on this one)
- I2C commit split in two
- clock tree is reconciled with Linux code, since having a custom
version of it proved to be difficult to compare agains Linux's
implementation
- GPIO driver (tested on a custom Vybrid board)
- FEC support (tested on a custom Vybrid board)
Any feedback is, as always, very much appreciated.
Thank you,
Andrey Smirnov
[1] http://lists.infradead.org/pipermail/barebox/2016-October/028225.html
Andrey Smirnov (28):
i.MX: Add primitive functions for VF610 family
i.MX: Add register definitions for VF610 SoC
i.MX: Add DEBUG_LL hooks for VF610
i.MX: scripts: Add "vf610" soc to imx-image
i.MX: Add support for VF610 Tower board
pinctrl: Add provisions to control GPIO pin direction
i.MX: Add pinctrl driver for VF610
clk: Port clock dependency resolution code
clk: Port of_clk_set_defaults()
i.MX: Move clk code from 'mach-imx' to 'drivers'
i.MX: clk: Port imx_clk_gate2_cgr()
i.MX: clk: Add IMX_PLLV3_USB_VF610 support
i.MX: clk: Port imx_check_clocks()
i.MX: clk: Port imx_clk_mux_flags from Linux
i.MX: Add VF610 clock tree initialization code
vf610: Give enet_osc explicit "enet_ext" name
i.MX: Add 'lpuart' serial driver
i.MX: i2c: Use read/write adapter functions
i.MX: i2c: Add Vybrid support
i.MX: esdhc: Do not rely on CPU type for quirks
i.MX: esdhc: Request "per" clock explicitly
i.MX: Kconfig: Enable OCOTP on Vybrid
i.MX: ocotp: Remove unused #define
i.MX: ocotp: Account for shadow memory gaps
i.MX: ocotp: Add Vybrid support
i.MX: fec: Enable all clocks specified for FEC
i.MX: fec: Add support for Vybrid variant
gpio: Add GPIO driver for Vybrid
arch/arm/boards/Makefile | 1 +
arch/arm/boards/freescale-vf610-twr/Makefile | 3 +
.../flash-header-vf610-twr.imxcfg | 278 +++++++++++
arch/arm/boards/freescale-vf610-twr/lowlevel.c | 45 ++
arch/arm/dts/Makefile | 1 +
arch/arm/dts/vf610-twr.dts | 18 +
arch/arm/mach-imx/Kconfig | 16 +-
arch/arm/mach-imx/Makefile | 23 +-
arch/arm/mach-imx/clk-gate-exclusive.c | 103 ----
arch/arm/mach-imx/clk-gate2.c | 145 ------
arch/arm/mach-imx/clk-imx1.c | 121 -----
arch/arm/mach-imx/clk-imx21.c | 196 --------
arch/arm/mach-imx/clk-imx25.c | 200 --------
arch/arm/mach-imx/clk-imx27.c | 270 ----------
arch/arm/mach-imx/clk-imx31.c | 146 ------
arch/arm/mach-imx/clk-imx35.c | 219 ---------
arch/arm/mach-imx/clk-imx5.c | 533 --------------------
arch/arm/mach-imx/clk-imx6.c | 541 ---------------------
arch/arm/mach-imx/clk-imx6sx.c | 483 ------------------
arch/arm/mach-imx/clk-pfd.c | 148 ------
arch/arm/mach-imx/clk-pllv1.c | 95 ----
arch/arm/mach-imx/clk-pllv2.c | 230 ---------
arch/arm/mach-imx/clk-pllv3.c | 326 -------------
arch/arm/mach-imx/clk.h | 104 ----
arch/arm/mach-imx/cpu_init.c | 5 +
arch/arm/mach-imx/imx.c | 4 +
arch/arm/mach-imx/include/mach/clock-vf610.h | 171 +++++++
arch/arm/mach-imx/include/mach/debug_ll.h | 27 +-
arch/arm/mach-imx/include/mach/generic.h | 13 +
arch/arm/mach-imx/include/mach/imx_cpu_types.h | 1 +
arch/arm/mach-imx/include/mach/iomux-vf610.h | 226 +++++++++
arch/arm/mach-imx/include/mach/vf610-regs.h | 110 +++++
arch/arm/mach-imx/ocotp.c | 51 +-
common/Kconfig | 10 +-
drivers/clk/Makefile | 3 +-
drivers/clk/clk-conf.c | 144 ++++++
drivers/clk/clk.c | 91 +++-
drivers/clk/imx/Makefile | 21 +
drivers/clk/imx/clk-gate-exclusive.c | 103 ++++
drivers/clk/imx/clk-gate2.c | 147 ++++++
drivers/clk/imx/clk-imx1.c | 121 +++++
drivers/clk/imx/clk-imx21.c | 196 ++++++++
drivers/clk/imx/clk-imx25.c | 200 ++++++++
drivers/clk/imx/clk-imx27.c | 270 ++++++++++
drivers/clk/imx/clk-imx31.c | 146 ++++++
drivers/clk/imx/clk-imx35.c | 219 +++++++++
drivers/clk/imx/clk-imx5.c | 533 ++++++++++++++++++++
drivers/clk/imx/clk-imx6.c | 541 +++++++++++++++++++++
drivers/clk/imx/clk-imx6sx.c | 483 ++++++++++++++++++
drivers/clk/imx/clk-pfd.c | 148 ++++++
drivers/clk/imx/clk-pllv1.c | 95 ++++
drivers/clk/imx/clk-pllv2.c | 230 +++++++++
drivers/clk/imx/clk-pllv3.c | 329 +++++++++++++
drivers/clk/imx/clk-vf610.c | 443 +++++++++++++++++
drivers/clk/imx/clk.c | 21 +
drivers/clk/imx/clk.h | 123 +++++
drivers/gpio/Kconfig | 3 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-vf610.c | 181 +++++++
drivers/i2c/busses/i2c-imx.c | 225 ++++++---
drivers/mci/imx-esdhc.c | 123 ++++-
drivers/net/fec_imx.c | 74 ++-
drivers/net/fec_imx.h | 10 +-
drivers/pinctrl/Kconfig | 5 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-vf610.c | 167 +++++++
drivers/pinctrl/pinctrl.c | 45 ++
drivers/serial/Kconfig | 5 +
drivers/serial/Makefile | 1 +
drivers/serial/serial_lpuart.c | 217 +++++++++
images/Makefile.imx | 5 +
include/linux/clk/clk-conf.h | 14 +
include/pinctrl.h | 21 +
include/serial/lpuart.h | 281 +++++++++++
scripts/imx/imx.c | 1 +
75 files changed, 6870 insertions(+), 3980 deletions(-)
create mode 100644 arch/arm/boards/freescale-vf610-twr/Makefile
create mode 100644 arch/arm/boards/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
create mode 100644 arch/arm/boards/freescale-vf610-twr/lowlevel.c
create mode 100644 arch/arm/dts/vf610-twr.dts
delete mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c
delete mode 100644 arch/arm/mach-imx/clk-gate2.c
delete mode 100644 arch/arm/mach-imx/clk-imx1.c
delete mode 100644 arch/arm/mach-imx/clk-imx21.c
delete mode 100644 arch/arm/mach-imx/clk-imx25.c
delete mode 100644 arch/arm/mach-imx/clk-imx27.c
delete mode 100644 arch/arm/mach-imx/clk-imx31.c
delete mode 100644 arch/arm/mach-imx/clk-imx35.c
delete mode 100644 arch/arm/mach-imx/clk-imx5.c
delete mode 100644 arch/arm/mach-imx/clk-imx6.c
delete mode 100644 arch/arm/mach-imx/clk-imx6sx.c
delete mode 100644 arch/arm/mach-imx/clk-pfd.c
delete mode 100644 arch/arm/mach-imx/clk-pllv1.c
delete mode 100644 arch/arm/mach-imx/clk-pllv2.c
delete mode 100644 arch/arm/mach-imx/clk-pllv3.c
delete mode 100644 arch/arm/mach-imx/clk.h
create mode 100644 arch/arm/mach-imx/include/mach/clock-vf610.h
create mode 100644 arch/arm/mach-imx/include/mach/iomux-vf610.h
create mode 100644 arch/arm/mach-imx/include/mach/vf610-regs.h
create mode 100644 drivers/clk/clk-conf.c
create mode 100644 drivers/clk/imx/Makefile
create mode 100644 drivers/clk/imx/clk-gate-exclusive.c
create mode 100644 drivers/clk/imx/clk-gate2.c
create mode 100644 drivers/clk/imx/clk-imx1.c
create mode 100644 drivers/clk/imx/clk-imx21.c
create mode 100644 drivers/clk/imx/clk-imx25.c
create mode 100644 drivers/clk/imx/clk-imx27.c
create mode 100644 drivers/clk/imx/clk-imx31.c
create mode 100644 drivers/clk/imx/clk-imx35.c
create mode 100644 drivers/clk/imx/clk-imx5.c
create mode 100644 drivers/clk/imx/clk-imx6.c
create mode 100644 drivers/clk/imx/clk-imx6sx.c
create mode 100644 drivers/clk/imx/clk-pfd.c
create mode 100644 drivers/clk/imx/clk-pllv1.c
create mode 100644 drivers/clk/imx/clk-pllv2.c
create mode 100644 drivers/clk/imx/clk-pllv3.c
create mode 100644 drivers/clk/imx/clk-vf610.c
create mode 100644 drivers/clk/imx/clk.c
create mode 100644 drivers/clk/imx/clk.h
create mode 100644 drivers/gpio/gpio-vf610.c
create mode 100644 drivers/pinctrl/pinctrl-vf610.c
create mode 100644 drivers/serial/serial_lpuart.c
create mode 100644 include/linux/clk/clk-conf.h
create mode 100644 include/serial/lpuart.h
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH v2 07/28] i.MX: Add pinctrl driver for VF610
From: Andrey Smirnov @ 2016-11-09 16:13 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
In-Reply-To: <1478708056-7875-1-git-send-email-andrew.smirnov@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pinctrl/Kconfig | 5 ++
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-vf610.c | 167 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-vf610.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 5c69928..12fff4f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -77,4 +77,9 @@ config PINCTRL_TEGRA_XUSB
source drivers/pinctrl/mvebu/Kconfig
+config PINCTRL_VF610
+ bool
+ default y if ARCH_VF610
+ help
+ Pinmux controller found on Vybrid VF610 family of SoCs
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index af9b30d..9450dbb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
+obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
diff --git a/drivers/pinctrl/pinctrl-vf610.c b/drivers/pinctrl/pinctrl-vf610.c
new file mode 100644
index 0000000..b479bf2
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-vf610.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016 Zodiac Inflight Innovation
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <pinctrl.h>
+#include <malloc.h>
+#include <gpio.h>
+
+enum {
+ PINCTRL_VF610_MUX_LINE_SIZE = 20,
+ PINCTRL_VF610_MUX_SHIFT = 20,
+
+ PINCTRL_VF610_IBE = 1 << 0,
+ PINCTRL_VF610_OBE = 1 << 1,
+ PINCTRL_VF610_xBE = 0b11,
+};
+
+struct pinctrl_vf610 {
+ void __iomem *base;
+ struct pinctrl_device pinctrl;
+};
+
+static int pinctrl_vf610_set_state(struct pinctrl_device *pdev,
+ struct device_node *np)
+{
+ const __be32 *list;
+ int npins, size, i;
+
+ struct pinctrl_vf610 *iomux =
+ container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+ list = of_get_property(np, "fsl,pins", &size);
+ if (!list)
+ return -EINVAL;
+
+ if (!size || size % PINCTRL_VF610_MUX_LINE_SIZE) {
+ dev_err(pdev->dev, "Invalid fsl,pins property in %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ npins = size / PINCTRL_VF610_MUX_LINE_SIZE;
+
+ for (i = 0; i < npins; i++) {
+ u32 mux_reg = be32_to_cpu(*list++);
+ u32 input_reg = be32_to_cpu(*list++);
+ u32 mux_val = be32_to_cpu(*list++);
+ u32 input_val = be32_to_cpu(*list++);
+ u32 conf_val = be32_to_cpu(*list++);
+
+ writel(mux_val << PINCTRL_VF610_MUX_SHIFT | conf_val,
+ iomux->base + mux_reg);
+
+ if (input_reg)
+ writel(input_val, iomux->base + input_reg);
+ }
+
+ return 0;
+}
+
+static int pinctrl_vf610_set_direction(struct pinctrl_device *pdev,
+ unsigned int pin, bool input)
+{
+ u32 pad_cr;
+ const u32 off = pin * sizeof(u32);
+ struct pinctrl_vf610 *iomux =
+ container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+ pad_cr = readl(iomux->base + off);
+
+ if (input) {
+ pad_cr |= PINCTRL_VF610_IBE;
+ pad_cr &= ~PINCTRL_VF610_OBE;
+ } else {
+ pad_cr &= ~PINCTRL_VF610_IBE;
+ pad_cr |= PINCTRL_VF610_OBE;
+ }
+
+ writel(pad_cr, iomux->base + off);
+
+ return 0;
+}
+
+static int pinctrl_vf610_get_direction(struct pinctrl_device *pdev,
+ unsigned int pin)
+{
+ const u32 off = pin * sizeof(u32);
+ struct pinctrl_vf610 *iomux =
+ container_of(pdev, struct pinctrl_vf610, pinctrl);
+
+ const u32 pad_cr = readl(iomux->base + off);
+
+ switch (pad_cr & PINCTRL_VF610_xBE) {
+ case PINCTRL_VF610_IBE:
+ return GPIOF_DIR_IN;
+ case PINCTRL_VF610_OBE:
+ return GPIOF_DIR_OUT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static struct pinctrl_ops pinctrl_vf610_ops = {
+ .set_state = pinctrl_vf610_set_state,
+ .set_direction = pinctrl_vf610_set_direction,
+ .get_direction = pinctrl_vf610_get_direction,
+};
+
+static int pinctrl_vf610_probe(struct device_d *dev)
+{
+ int ret;
+ struct resource *io;
+ struct pinctrl_vf610 *iomux;
+
+ iomux = xzalloc(sizeof(*iomux));
+
+ io = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(io))
+ return PTR_ERR(io);
+
+ iomux->base = IOMEM(io->start);
+ iomux->pinctrl.dev = dev;
+ iomux->pinctrl.ops = &pinctrl_vf610_ops;
+ iomux->pinctrl.base = 0;
+ iomux->pinctrl.npins = ARCH_NR_GPIOS;
+
+ ret = pinctrl_register(&iomux->pinctrl);
+ if (ret)
+ free(iomux);
+
+ return ret;
+}
+
+static __maybe_unused struct of_device_id pinctrl_vf610_dt_ids[] = {
+ { .compatible = "fsl,vf610-iomuxc", },
+ { /* sentinel */ }
+};
+
+static struct driver_d pinctrl_vf610_driver = {
+ .name = "vf610-pinctrl",
+ .probe = pinctrl_vf610_probe,
+ .of_compatible = DRV_OF_COMPAT(pinctrl_vf610_dt_ids),
+};
+
+static int pinctrl_vf610_init(void)
+{
+ return platform_driver_register(&pinctrl_vf610_driver);
+}
+postcore_initcall(pinctrl_vf610_init);
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: Designware MAC reset timeout after Linux reboot
From: Ian Abbott @ 2016-11-09 14:10 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
In-Reply-To: <d728234e-959a-c21d-7df1-b530355425de@mev.co.uk>
On 08/11/16 12:13, Ian Abbott wrote:
> On 08/11/16 08:08, Sascha Hauer wrote:
>> Hi Ian,
>>
>> On Mon, Nov 07, 2016 at 05:56:51PM +0000, Ian Abbott wrote:
>>> Perhaps the timeout isn't waiting long enough. If I interrupt the 'ifup
>>> eth0' command and display the approriate 'Bus_Mode' register
>>> (0xff703000)
>>> with the 'md' command, the DMAMAC_SRST bit (bit 0) is no longer set:
>>>
>>> barebox@xxxx:/ md -l 0xff703000+4
>>> ff703000: 00020100
>>
>> The timeout is 10ms, this should be way enough. The return value of
>> dwc_ether_init() is not checked, so the driver happily continues with
>> further register writes, I assume there must be something that clears
>> this bit afterwards, either directly or indirectly.
>
> The bit is supposed to clear itself, but I guess something else could be
> clearing it too.
>
> The code to reset the MAC DMA controller in Linux kernel 4.1 is
> dwmac1000_dma_init() in
> "drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c". In Linux kernel
> 4.6, the function is dwmac_dma_reset() in "dwmac_lib.c". In both cases,
> the code to reset the DMA controller is basically as follows:
>
> u32 value = readl(ioaddr + DMA_BUS_MODE);
> int limit;
>
> /* DMA SW reset */
> value |= DMA_BUS_MODE_SFT_RESET;
> writel(value, ioaddr + DMA_BUS_MODE);
> limit = 10;
> while (limit--) {
> if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
> break;
> mdelay(10);
> }
> if (limit < 0)
> return -EBUSY;
>
> It's interesting that it only bothers to check for reset completion
> every 10 ms (timing out after 100 ms), so it must be expecting it to
> take a while!
>
> I'll experiment with the timeout on my board to see if the bit ever
> clears itself.
>
The problem seems to be related to some other problems I've been having
with the Ethernet on this prototype board, which is something to do with
the PHY chip's passive support components (inductors, capacitors, etc.)
This problem manifests as lower-than-expected 'iperf' times when the
Ethernet port is plugged into certain models of Ethernet switch.
I experimented with the timeout in mac_reset() in designware.c, setting
it to 1 second, and printing out a debug message with the time taken for
the reset to complete.
After 20 trials of rebooting from Linux to barebox and issuing the 'ifup
eth0' command, I got a pretty random spread of times between 29.3 and
850.2 ms, with a mean of 312.5 ms. (It looks like a pretty linear
distribution. Some other stats: Q1: 141.4 ms, Median: 240.1 ms, Q3:
480.2 ms, SD: 211.9 ms.)
I ran another trial with the is_timeout() call replaced with
is_timeout_non_interruptible() and got a similar random spread of times
(but smaller than the first trial) from 11.4 ms to 654.6 ms, with a mean
of 266.2 ms.
Both of those trials were performed with the Ethernet port connected to
a 1000 Base-T Ethernet switch.
Now here's the kicker.... If I plug it into a different brand of 1000
Base-T Ethernet switch, the mac_reset() times (after rebooting from
Linux) are more like 360 ns (not ms!). If I plug it into a 100 Base-T
switch, the times are more more like 900 ns to 2300 ns. If I disconnect
it completely, the times are about 360 ns.
For comparison, after running 'ifup eth0' after powering up into
barebox, the mac_reset() times are about 360 ns independent of what the
Ethernet port is plugged into.
I'm still not sure what state my Linux kernel is leaving the Ethernet
controller and PHY in following a reboot, but I'm reasonably confident
the problem is related to the PHY hardware components on my board.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Fwd: boot kernel with append device tree
From: Alex Vazquez @ 2016-11-09 8:41 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
In-Reply-To: <20161108072936.beuncvhpwxuhumkg@pengutronix.de>
Hi Sascha!
I have tested the patch with the version (2016.03.0) and now it works correctly.
Thanks!
Regards!
2016-11-08 8:29 GMT+01:00 Sascha Hauer <s.hauer@pengutronix.de>:
> On Mon, Nov 07, 2016 at 12:01:25PM +0100, Alex Vazquez wrote:
>> > Is CONFIG_OFTREE enabled in your build?
>> Yes.
>
> Ok, could you please try the following patch? Another possibility would
> be to disable CONFIG_OFTREE, but it would be good if you could test the
> patch anyway since the same bug is still present in current master.
>
> Sascha
>
> ----------------------------------8<--------------------------------
>
> From 500e5f87f9943958fa4662e29261a0abb4df24d9 Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Date: Tue, 8 Nov 2016 08:23:17 +0100
> Subject: [PATCH] ARM: Fix appended device tree when CONFIG_OFTREE is enabled
>
> When CONFIG_OFTREE is enabled the appended device tree is unflattened
> and put into data->of_root_node, but there it is never used again.
> To actually use the appended device tree put it into data->oftree
> instead.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/lib/bootm.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index 28b4f4a..8977d08 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -244,12 +244,21 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
> }
>
> if (IS_BUILTIN(CONFIG_OFTREE)) {
> - data->of_root_node = of_unflatten_dtb(oftree);
> - if (!data->of_root_node) {
> + struct device_node *root;
> +
> + root = of_unflatten_dtb(oftree);
> + if (!root) {
> pr_err("unable to unflatten devicetree\n");
> ret = -EINVAL;
> goto err_free;
> }
> + data->oftree = of_get_fixed_tree(root);
> + if (!data->oftree) {
> + pr_err("Unable to get fixed tree\n");
> + ret = -EINVAL;
> + goto err_free;
> + }
> +
> free(oftree);
> } else {
> data->oftree = oftree;
> --
> 2.10.1
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Configure RAM size on iMX53 board
From: Sascha Hauer @ 2016-11-09 6:41 UTC (permalink / raw)
To: Jose Luis Zabalza; +Cc: barebox
In-Reply-To: <CAKZffXFjLerW8jK2m82znqH+Mc_9X9C4s7SVJHGyHdnV0R0q_Q@mail.gmail.com>
On Wed, Nov 09, 2016 at 05:23:10AM +0100, Jose Luis Zabalza wrote:
> There is no form of detection. UBoot (a very old version) don't use
> any CS1 address, except with the memtest command.
> If memtest command is executed with 512MB version, UBoot hangs, as expected.
> I set the mem kernel parameter using a environment variable and kernel
> can reach CS1 memory.
Then you could drop the CS1 setup from the DCD table and do the same.
You can then create a command or similar which initializes the CS1
memory and registers the new memory bank.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Configure RAM size on iMX53 board
From: Jose Luis Zabalza @ 2016-11-09 4:23 UTC (permalink / raw)
To: barebox
In-Reply-To: <20161108212434.gvlq5fy6vrbn2en5@pengutronix.de>
There is no form of detection. UBoot (a very old version) don't use
any CS1 address, except with the memtest command.
If memtest command is executed with 512MB version, UBoot hangs, as expected.
I set the mem kernel parameter using a environment variable and kernel
can reach CS1 memory.
2016-11-08 22:24 GMT+01:00 Sascha Hauer <s.hauer@pengutronix.de>:
> On Tue, Nov 08, 2016 at 09:51:36PM +0100, Jose Luis Zabalza wrote:
>> > So you have 512MiB on each chip select, so I assume that on the 512MiB
>> > board variants CS1 is not equipped.
>>
>> Yes, it is.
>>
>> >In that case you can in lowlevel.c
>> > test if you find SDRAM on CS1 and if not, disable the chip select
>> > completely in the SDRAM controller.
>>
>> OK. But how ? I enable CS0 and CS1 on DCD table. Is there any way to
>> tell barebox not to use CS1 ?
>>
>> > I am not sure how you can detect if there's SDRAM on CS1. I've seen
>> > situations in which the board just hangs if you access non existent RAM
>> > areas.
>>
>> I have tried it, but I have not be able to implement a code for
>> autodetect. If the code write or read a value on a position without
>> physical chip, the microcontroller hangs. ????
>>
>> But it's not a problem. A solution is configure both CS and MMU. If
>> bootloader don't access to high positions, there is not problem. After
>> I set a environment variable with memory size and the mem kernel
>> parameter (or ATAG) does the rest.
>
> You said that both board variants work with the same U-Boot binary, how
> does it work there? Is there some detection mechanism or is it only some
> environment variable that you have to set manually?
>
> Sascha
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
--
jlz.3008 a t gmail.com
Linux Counter 172551
https://linuxcounter.net/cert/172551.png
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Configure RAM size on iMX53 board
From: Sascha Hauer @ 2016-11-08 21:24 UTC (permalink / raw)
To: Jose Luis Zabalza; +Cc: barebox
In-Reply-To: <CAKZffXG5CG9R8e4xoMdP6DFJq42ng5EQqwmhafikNn6HNzuedQ@mail.gmail.com>
On Tue, Nov 08, 2016 at 09:51:36PM +0100, Jose Luis Zabalza wrote:
> > So you have 512MiB on each chip select, so I assume that on the 512MiB
> > board variants CS1 is not equipped.
>
> Yes, it is.
>
> >In that case you can in lowlevel.c
> > test if you find SDRAM on CS1 and if not, disable the chip select
> > completely in the SDRAM controller.
>
> OK. But how ? I enable CS0 and CS1 on DCD table. Is there any way to
> tell barebox not to use CS1 ?
>
> > I am not sure how you can detect if there's SDRAM on CS1. I've seen
> > situations in which the board just hangs if you access non existent RAM
> > areas.
>
> I have tried it, but I have not be able to implement a code for
> autodetect. If the code write or read a value on a position without
> physical chip, the microcontroller hangs. ????
>
> But it's not a problem. A solution is configure both CS and MMU. If
> bootloader don't access to high positions, there is not problem. After
> I set a environment variable with memory size and the mem kernel
> parameter (or ATAG) does the rest.
You said that both board variants work with the same U-Boot binary, how
does it work there? Is there some detection mechanism or is it only some
environment variable that you have to set manually?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Configure RAM size on iMX53 board
From: Jose Luis Zabalza @ 2016-11-08 20:51 UTC (permalink / raw)
To: barebox
In-Reply-To: <20161108075317.j4xkf7zpkdfyt5y3@pengutronix.de>
> So you have 512MiB on each chip select, so I assume that on the 512MiB
> board variants CS1 is not equipped.
Yes, it is.
>In that case you can in lowlevel.c
> test if you find SDRAM on CS1 and if not, disable the chip select
> completely in the SDRAM controller.
OK. But how ? I enable CS0 and CS1 on DCD table. Is there any way to
tell barebox not to use CS1 ?
> I am not sure how you can detect if there's SDRAM on CS1. I've seen
> situations in which the board just hangs if you access non existent RAM
> areas.
I have tried it, but I have not be able to implement a code for
autodetect. If the code write or read a value on a position without
physical chip, the microcontroller hangs. ????
But it's not a problem. A solution is configure both CS and MMU. If
bootloader don't access to high positions, there is not problem. After
I set a environment variable with memory size and the mem kernel
parameter (or ATAG) does the rest.
So, I have to make sure Barebox don't reach CS1 memory positions. That is all.
Thanks for your help. See you later.
--
jlz.3008 a t gmail.com
Linux Counter 172551
https://linuxcounter.net/cert/172551.png
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH] clk: add clock command completion
From: Sascha Hauer @ 2016-11-08 17:34 UTC (permalink / raw)
To: Barebox List
This adds tab completion for the clk_* commands.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/clk.c | 5 +++++
drivers/clk/clk.c | 22 ++++++++++++++++++++++
include/linux/clk.h | 4 ++++
3 files changed, 31 insertions(+)
diff --git a/commands/clk.c b/commands/clk.c
index f862c45..47159dd 100644
--- a/commands/clk.c
+++ b/commands/clk.c
@@ -25,6 +25,7 @@ BAREBOX_CMD_START(clk_enable)
BAREBOX_CMD_DESC("enable a clock")
BAREBOX_CMD_OPTS("CLK")
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
+ BAREBOX_CMD_COMPLETE(clk_name_complete)
BAREBOX_CMD_END
static int do_clk_disable(int argc, char *argv[])
@@ -48,6 +49,7 @@ BAREBOX_CMD_START(clk_disable)
BAREBOX_CMD_DESC("disable a clock")
BAREBOX_CMD_OPTS("CLK")
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
+ BAREBOX_CMD_COMPLETE(clk_name_complete)
BAREBOX_CMD_END
static int do_clk_set_rate(int argc, char *argv[])
@@ -77,6 +79,7 @@ BAREBOX_CMD_START(clk_set_rate)
BAREBOX_CMD_OPTS("CLK HZ")
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
BAREBOX_CMD_HELP(cmd_clk_set_rate_help)
+ BAREBOX_CMD_COMPLETE(clk_name_complete)
BAREBOX_CMD_END
static int do_clk_get_rate(int argc, char *argv[])
@@ -130,6 +133,7 @@ BAREBOX_CMD_START(clk_get_rate)
BAREBOX_CMD_OPTS("[-s VARNAME] CLK")
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
BAREBOX_CMD_HELP(cmd_clk_get_rate_help)
+ BAREBOX_CMD_COMPLETE(clk_name_complete)
BAREBOX_CMD_END
static int do_clk_dump(int argc, char *argv[])
@@ -187,4 +191,5 @@ BAREBOX_CMD_START(clk_set_parent)
BAREBOX_CMD_DESC("set parent of a clock")
BAREBOX_CMD_OPTS("CLK PARENT")
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
+ BAREBOX_CMD_COMPLETE(clk_name_complete)
BAREBOX_CMD_END
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 630a84d..15e424d 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -17,6 +17,8 @@
#include <common.h>
#include <errno.h>
#include <malloc.h>
+#include <stringlist.h>
+#include <complete.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -508,3 +510,23 @@ void clk_dump(int verbose)
dump_one(c, verbose, 0);
}
}
+
+int clk_name_complete(struct string_list *sl, char *instr)
+{
+ struct clk *c;
+ int len;
+
+ if (!instr)
+ instr = "";
+
+ len = strlen(instr);
+
+ list_for_each_entry(c, &clks, list) {
+ if (strncmp(instr, c->name, len))
+ continue;
+
+ string_list_add_asprintf(sl, "%s ", c->name);
+ }
+
+ return COMPLETE_CONTINUE;
+}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7a0ee11..8cb9731 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -362,4 +362,8 @@ static inline int of_clk_init(struct device_node *root,
}
#endif
+struct string_list;
+
+int clk_name_complete(struct string_list *sl, char *instr);
+
#endif
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 7/7] ARM: i.MX6 esdctl: Add i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 19 +++++++++++++++++++
arch/arm/mach-imx/include/mach/esdctl.h | 1 +
2 files changed, 20 insertions(+)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 106e648..ffe708f 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -377,6 +377,11 @@ static __maybe_unused struct imx_esdctl_data imx6q_data = {
.add_mem = imx6_mmdc_add_mem,
};
+static __maybe_unused struct imx_esdctl_data imx6ul_data = {
+ .base0 = 0x80000000,
+ .add_mem = imx6_mmdc_add_mem,
+};
+
static struct platform_device_id imx_esdctl_ids[] = {
#ifdef CONFIG_ARCH_IMX1
{
@@ -427,6 +432,9 @@ static struct platform_device_id imx_esdctl_ids[] = {
static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
{
+ .compatible = "fsl,imx6ul-mmdc",
+ .data = &imx6ul_data
+ }, {
.compatible = "fsl,imx6q-mmdc",
.data = &imx6q_data
}, {
@@ -589,3 +597,14 @@ void __noreturn imx6q_barebox_entry(void *boarddata)
barebox_arm_entry(0x10000000, size, boarddata);
}
+
+void __noreturn imx6ul_barebox_entry(void *boarddata)
+{
+ u64 size_cs0 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 0);
+ u64 size_cs1 = imx6_mmdc_sdram_size((void *)MX6_MMDC_P0_BASE_ADDR, 1);
+ u64 total = size_cs0 + size_cs1;
+
+ resource_size_t size = min(total, (u64)IMX6_MAX_SDRAM_SIZE);
+
+ barebox_arm_entry(0x80000000, size, boarddata);
+}
diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h
index cf8d89d..66dcc89 100644
--- a/arch/arm/mach-imx/include/mach/esdctl.h
+++ b/arch/arm/mach-imx/include/mach/esdctl.h
@@ -136,6 +136,7 @@ void __noreturn imx35_barebox_entry(void *boarddata);
void __noreturn imx51_barebox_entry(void *boarddata);
void __noreturn imx53_barebox_entry(void *boarddata);
void __noreturn imx6q_barebox_entry(void *boarddata);
+void __noreturn imx6ul_barebox_entry(void *boarddata);
void imx_esdctl_disable(void);
#endif
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 4/7] pinmux: imx-iomux-v3: Add i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/pinctrl/imx-iomux-v3.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pinctrl/imx-iomux-v3.c b/drivers/pinctrl/imx-iomux-v3.c
index 92fac18..4b3f033 100644
--- a/drivers/pinctrl/imx-iomux-v3.c
+++ b/drivers/pinctrl/imx-iomux-v3.c
@@ -207,6 +207,8 @@ static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
}, {
.compatible = "fsl,imx6sx-iomuxc",
}, {
+ .compatible = "fsl,imx6ul-iomuxc",
+ }, {
/* sentinel */
}
};
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 2/7] ARM: i.MX6ul: Add clock support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Nearly identical to Linux-4.8 clock support, only some unnecessary
clocks skipped.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/clk-imx6ul.c | 426 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 427 insertions(+)
create mode 100644 arch/arm/mach-imx/clk-imx6ul.c
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 0763944..9922fed 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -14,6 +14,7 @@ pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
+obj-$(CONFIG_ARCH_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_IMX_OCOTP) += ocotp.o
diff --git a/arch/arm/mach-imx/clk-imx6ul.c b/arch/arm/mach-imx/clk-imx6ul.c
new file mode 100644
index 0000000..72b5fa2
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6ul.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+
+#include "clk.h"
+
+#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
+#define CCDR 0x4
+
+static const char *pll_bypass_src_sels[] = { "osc", "dummy", };
+static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
+static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
+static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
+static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
+static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
+static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
+static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
+static const char *ca7_secondary_sels[] = { "pll2_pfd2_396m", "pll2_bus", };
+static const char *step_sels[] = { "osc", "ca7_secondary_sel", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *axi_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[] = {"periph", "axi_alt_sel", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", };
+static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *bch_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *gpmi_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd0_720m", };
+static const char *spdif_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", };
+static const char *sai_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", };
+static const char *lcdif_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *sim_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", };
+static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
+static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
+static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
+static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", "dummy", };
+static const char *ecspi_sels[] = { "pll3_60m", "osc", };
+static const char *uart_sels[] = { "pll3_80m", "osc", };
+static const char *perclk_sels[] = { "ipg", "osc", };
+static const char *lcdif_sels[] = { "lcdif_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *sim_sels[] = { "sim_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+
+static struct clk *clks[IMX6UL_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static int const clks_init_on[] __initconst = {
+ IMX6UL_CLK_AIPSTZ1, IMX6UL_CLK_AIPSTZ2, IMX6UL_CLK_AIPSTZ3,
+ IMX6UL_CLK_AXI, IMX6UL_CLK_ARM, IMX6UL_CLK_ROM,
+ IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG,
+};
+
+static struct clk_div_table clk_enet_ref_table[] = {
+ { .val = 0, .div = 20, },
+ { .val = 1, .div = 10, },
+ { .val = 2, .div = 5, },
+ { .val = 3, .div = 4, },
+ { }
+};
+
+static int imx6_ccm_probe(struct device_d *dev)
+{
+ struct resource *iores;
+ void __iomem *base, *anatop_base, *ccm_base;
+ int i;
+ struct device_node *ccm_node = dev->device_node;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ ccm_base = IOMEM(iores->start);
+
+ base = anatop_base;
+
+ clks[IMX6UL_CLK_DUMMY] = clk_fixed("dummy", 0);
+
+ base = IOMEM(MX6_ANATOP_BASE_ADDR);
+
+ clks[IMX6UL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+ clks[IMX6UL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+ clks[IMX6UL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
+ clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
+ clks[IMX6UL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
+ clks[IMX6UL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
+ clks[IMX6UL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
+ clks[IMX6UL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
+ clks[IMX6UL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
+
+ clks[IMX6UL_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
+ clks[IMX6UL_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
+ clks[IMX6UL_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
+ clks[IMX6UL_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
+ clks[IMX6UL_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
+ clks[IMX6UL_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
+ clks[IMX6UL_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
+ clks[IMX6UL_CLK_CSI_SEL] = imx_clk_mux_p("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
+
+ /* Do not bypass PLLs initially */
+ clk_set_parent(clks[IMX6UL_PLL1_BYPASS], clks[IMX6UL_CLK_PLL1]);
+ clk_set_parent(clks[IMX6UL_PLL2_BYPASS], clks[IMX6UL_CLK_PLL2]);
+ clk_set_parent(clks[IMX6UL_PLL3_BYPASS], clks[IMX6UL_CLK_PLL3]);
+ clk_set_parent(clks[IMX6UL_PLL4_BYPASS], clks[IMX6UL_CLK_PLL4]);
+ clk_set_parent(clks[IMX6UL_PLL5_BYPASS], clks[IMX6UL_CLK_PLL5]);
+ clk_set_parent(clks[IMX6UL_PLL6_BYPASS], clks[IMX6UL_CLK_PLL6]);
+ clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]);
+
+ clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1);
+ clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
+ clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
+ clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
+ clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
+ clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
+ clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
+
+ /*
+ * Bit 20 is the reserved and read-only bit, we do this only for:
+ * - Do nothing for usbphy clk_enable/disable
+ * - Keep refcount when do usbphy clk_enable/disable, in that case,
+ * the clk framework many need to enable/disable usbphy's parent
+ */
+ clks[IMX6UL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
+ clks[IMX6UL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
+
+ /*
+ * usbphy*_gate needs to be on after system boots up, and software
+ * never needs to control it anymore.
+ */
+ clks[IMX6UL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+ clks[IMX6UL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+ /* name parent_name reg idx */
+ clks[IMX6UL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clks[IMX6UL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clks[IMX6UL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clks[IMX6UL_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3);
+ clks[IMX6UL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clks[IMX6UL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clks[IMX6UL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clks[IMX6UL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ clks[IMX6UL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
+ base + 0xe0, 0, 2, clk_enet_ref_table);
+ clks[IMX6UL_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
+ base + 0xe0, 2, 2, clk_enet_ref_table);
+
+ clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20);
+ clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+ clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
+
+ /* name parent_name mult div */
+ clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+
+ base = ccm_base;
+
+ clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels));
+ clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels));
+ clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels));
+ clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels));
+ clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+ clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels));
+ clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels));
+ clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels));
+ clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels));
+ clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels));
+ clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels));
+ clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
+ clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
+ clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels));
+ clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels));
+ clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
+ clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
+ clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels));
+ clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels));
+ clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
+ clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels));
+ clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+
+ clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+ clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+
+ clks[IMX6UL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clks[IMX6UL_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
+ clks[IMX6UL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "qspi1_sel", 2, 7);
+ clks[IMX6UL_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "qspi1_sel", 1, 7);
+
+ clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3);
+ clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3);
+ clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3);
+ clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
+ clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6);
+ clks[IMX6UL_CLK_GPMI_PODF] = imx_clk_divider("gpmi_podf", "gpmi_sel", base + 0x24, 22, 3);
+ clks[IMX6UL_CLK_BCH_PODF] = imx_clk_divider("bch_podf", "bch_sel", base + 0x24, 19, 3);
+ clks[IMX6UL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clks[IMX6UL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clks[IMX6UL_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6);
+ clks[IMX6UL_CLK_SAI3_PRED] = imx_clk_divider("sai3_pred", "sai3_sel", base + 0x28, 22, 3);
+ clks[IMX6UL_CLK_SAI3_PODF] = imx_clk_divider("sai3_podf", "sai3_pred", base + 0x28, 16, 6);
+ clks[IMX6UL_CLK_SAI1_PRED] = imx_clk_divider("sai1_pred", "sai1_sel", base + 0x28, 6, 3);
+ clks[IMX6UL_CLK_SAI1_PODF] = imx_clk_divider("sai1_podf", "sai1_pred", base + 0x28, 0, 6);
+ clks[IMX6UL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
+ clks[IMX6UL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
+ clks[IMX6UL_CLK_SAI2_PRED] = imx_clk_divider("sai2_pred", "sai2_sel", base + 0x2c, 6, 3);
+ clks[IMX6UL_CLK_SAI2_PODF] = imx_clk_divider("sai2_podf", "sai2_pred", base + 0x2c, 0, 6);
+ clks[IMX6UL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clks[IMX6UL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clks[IMX6UL_CLK_SIM_PODF] = imx_clk_divider("sim_podf", "sim_pre_sel", base + 0x34, 12, 3);
+ clks[IMX6UL_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6);
+ clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3);
+ clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
+
+ clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ /* CCGR0 */
+ clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0);
+ clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2);
+ clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4);
+ clks[IMX6UL_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
+ clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
+ clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
+ clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
+ clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
+ clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
+ clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
+ clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt2_bus", "perclk", base + 0x68, 24);
+ clks[IMX6UL_CLK_GPT2_SERIAL] = imx_clk_gate2("gpt2_serial", "perclk", base + 0x68, 26);
+ clks[IMX6UL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28);
+ clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28);
+ clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
+
+ /* CCGR1 */
+ clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
+ clks[IMX6UL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2);
+ clks[IMX6UL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4);
+ clks[IMX6UL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6);
+ clks[IMX6UL_CLK_ADC2] = imx_clk_gate2("adc2", "ipg", base + 0x6c, 8);
+ clks[IMX6UL_CLK_UART3_IPG] = imx_clk_gate2("uart3_ipg", "ipg", base + 0x6c, 10);
+ clks[IMX6UL_CLK_UART3_SERIAL] = imx_clk_gate2("uart3_serial", "uart_podf", base + 0x6c, 10);
+ clks[IMX6UL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
+ clks[IMX6UL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
+ clks[IMX6UL_CLK_ADC1] = imx_clk_gate2("adc1", "ipg", base + 0x6c, 16);
+ clks[IMX6UL_CLK_GPT1_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20);
+ clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22);
+ clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24);
+ clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24);
+
+ /* CCGR2 */
+ clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2);
+ clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
+ clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
+ clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
+ clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
+ clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14);
+ clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
+ clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30);
+
+ /* CCGR3 */
+ clks[IMX6UL_CLK_UART5_IPG] = imx_clk_gate2("uart5_ipg", "ipg", base + 0x74, 2);
+ clks[IMX6UL_CLK_UART5_SERIAL] = imx_clk_gate2("uart5_serial", "uart_podf", base + 0x74, 2);
+ clks[IMX6UL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4);
+ clks[IMX6UL_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "ahb", base + 0x74, 4);
+ clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6);
+ clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6);
+ clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10);
+ clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
+ clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
+ clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
+ clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24);
+ clks[IMX6UL_CLK_AXI] = imx_clk_gate("axi", "axi_podf", base + 0x74, 28);
+
+ /* CCGR4 */
+ clks[IMX6UL_CLK_PER_BCH] = imx_clk_gate2("per_bch", "bch_podf", base + 0x78, 12);
+ clks[IMX6UL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
+ clks[IMX6UL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
+ clks[IMX6UL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
+ clks[IMX6UL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
+ clks[IMX6UL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "bch_podf", base + 0x78, 24);
+ clks[IMX6UL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "gpmi_podf", base + 0x78, 26);
+ clks[IMX6UL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc_podf", base + 0x78, 28);
+ clks[IMX6UL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "bch_podf", base + 0x78, 30);
+
+ /* CCGR5 */
+ clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0);
+ clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8);
+ clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10);
+ clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clks[IMX6UL_CLK_UART1_IPG] = imx_clk_gate2("uart1_ipg", "ipg", base + 0x7c, 24);
+ clks[IMX6UL_CLK_UART1_SERIAL] = imx_clk_gate2("uart1_serial", "uart_podf", base + 0x7c, 24);
+ clks[IMX6UL_CLK_UART7_IPG] = imx_clk_gate2("uart7_ipg", "ipg", base + 0x7c, 26);
+ clks[IMX6UL_CLK_UART7_SERIAL] = imx_clk_gate2("uart7_serial", "uart_podf", base + 0x7c, 26);
+
+ /* CCGR6 */
+ clks[IMX6UL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clks[IMX6UL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clks[IMX6UL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clks[IMX6UL_CLK_SIM1] = imx_clk_gate2("sim1", "sim_sel", base + 0x80, 6);
+ clks[IMX6UL_CLK_SIM2] = imx_clk_gate2("sim2", "sim_sel", base + 0x80, 8);
+ clks[IMX6UL_CLK_EIM] = imx_clk_gate2("eim", "eim_slow_podf", base + 0x80, 10);
+ clks[IMX6UL_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16);
+ clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14);
+ clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14);
+ clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20);
+ clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24);
+ clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26);
+ clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
+ clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30);
+
+ /* mask handshake of mmdc */
+ writel(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+ /*
+ * Lower the AHB clock rate before changing the parent clock source,
+ * as AHB clock rate can NOT be higher than 133MHz, but its parent
+ * will be switched from 396MHz PFD to 528MHz PLL in order to increase
+ * AXI clock rate, so we need to lower AHB rate first to make sure at
+ * any time, AHB rate is <= 133MHz.
+ */
+ clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000);
+
+ /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+ clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
+ clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]);
+ clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]);
+ clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]);
+
+ /* Make sure AHB rate is 132MHz */
+ clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000);
+
+ /* set perclk to from OSC */
+ clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]);
+
+ clk_set_rate(clks[IMX6UL_CLK_ENET_REF], 50000000);
+ clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000);
+ clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000);
+
+ /* keep all the clks on just for bringup */
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
+ clk_enable(clks[clks_init_on[i]]);
+
+ if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+ clk_enable(clks[IMX6UL_CLK_USBPHY1_GATE]);
+ clk_enable(clks[IMX6UL_CLK_USBPHY2_GATE]);
+ }
+
+ clk_set_parent(clks[IMX6UL_CLK_CAN_SEL], clks[IMX6UL_CLK_PLL3_60M]);
+ clk_set_parent(clks[IMX6UL_CLK_SIM_PRE_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
+
+ clk_set_parent(clks[IMX6UL_CLK_ENFC_SEL], clks[IMX6UL_CLK_PLL2_PFD2]);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
+ {
+ .compatible = "fsl,imx6ul-ccm",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d imx6_ccm_driver = {
+ .probe = imx6_ccm_probe,
+ .name = "imx6-ccm",
+ .of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids),
+};
+
+static int imx6_ccm_init(void)
+{
+ return platform_driver_register(&imx6_ccm_driver);
+}
+core_initcall(imx6_ccm_init);
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 3/7] ARM: i.MX6 gpt: Add i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/clocksource.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index b6873a7..8d00bbb 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -152,6 +152,9 @@ static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = {
.compatible = "fsl,imx6dl-gpt",
.data = ®s_imx31,
}, {
+ .compatible = "fsl,imx6ul-gpt",
+ .data = ®s_imx31,
+ }, {
/* sentinel */
}
};
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 6/7] ARM: i.MX: ocotp: Add i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/ocotp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 3acec7f..e1d0c25 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -510,6 +510,9 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
.compatible = "fsl,imx6sl-ocotp",
.data = &imx6sl_ocotp_data,
}, {
+ .compatible = "fsl,imx6ul-ocotp",
+ .data = &imx6q_ocotp_data,
+ }, {
/* sentinel */
}
};
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 1/7] ARM: i.MX: beginning i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 4 ++++
arch/arm/mach-imx/imx.c | 2 ++
arch/arm/mach-imx/imx6.c | 3 +++
arch/arm/mach-imx/include/mach/imx6.h | 2 ++
4 files changed, 11 insertions(+)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index a80bc6b..b315f7d 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -149,6 +149,10 @@ config ARCH_IMX6SX
select OFTREE
select COMMON_CLK_OF_PROVIDER
+config ARCH_IMX6UL
+ bool
+ select ARCH_IMX6
+
config IMX_MULTI_BOARDS
bool "Allow multiple boards to be selected"
select HAVE_DEFAULT_ENVIRONMENT_NEW
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 5ab6afc..1d3f18c 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -63,6 +63,8 @@ static int imx_soc_from_dt(void)
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6qp"))
return IMX_CPU_IMX6;
+ if (of_machine_is_compatible("fsl,imx6ul"))
+ return IMX_CPU_IMX6;
return 0;
}
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 18509a7..b242230 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -179,6 +179,9 @@ int imx6_init(void)
case IMX6_CPUTYPE_IMX6SX:
cputypestr = "i.MX6 SoloX";
break;
+ case IMX6_CPUTYPE_IMX6UL:
+ cputypestr = "i.MX6 UltraLite";
+ break;
default:
cputypestr = "unknown i.MX6";
break;
diff --git a/arch/arm/mach-imx/include/mach/imx6.h b/arch/arm/mach-imx/include/mach/imx6.h
index e8ffa47..1d70d39 100644
--- a/arch/arm/mach-imx/include/mach/imx6.h
+++ b/arch/arm/mach-imx/include/mach/imx6.h
@@ -14,6 +14,7 @@ void imx6_init_lowlevel(void);
#define IMX6_CPUTYPE_IMX6SX 0x462
#define IMX6_CPUTYPE_IMX6D 0x263
#define IMX6_CPUTYPE_IMX6Q 0x463
+#define IMX6_CPUTYPE_IMX6UL 0x164
#define SCU_CONFIG 0x04
@@ -66,5 +67,6 @@ DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
+DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
#endif /* __MACH_IMX6_H */
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
This series adds i.MX6ul support. The only new thing really added is
the clock support, the rest is mainly adding compatible strings for
the different drivers.
Sascha
----------------------------------------------------------------
Sascha Hauer (7):
ARM: i.MX: beginning i.MX6ul support
ARM: i.MX6ul: Add clock support
ARM: i.MX6 gpt: Add i.MX6ul support
pinmux: imx-iomux-v3: Add i.MX6ul support
serial: i.MX: Add i.MX6ul support
ARM: i.MX: ocotp: Add i.MX6ul support
ARM: i.MX6 esdctl: Add i.MX6ul support
arch/arm/mach-imx/Kconfig | 4 +
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/clk-imx6ul.c | 426 ++++++++++++++++++++++++++++++++
arch/arm/mach-imx/clocksource.c | 3 +
arch/arm/mach-imx/esdctl.c | 19 ++
arch/arm/mach-imx/imx.c | 2 +
arch/arm/mach-imx/imx6.c | 3 +
arch/arm/mach-imx/include/mach/esdctl.h | 1 +
arch/arm/mach-imx/include/mach/imx6.h | 2 +
arch/arm/mach-imx/ocotp.c | 3 +
drivers/pinctrl/imx-iomux-v3.c | 2 +
drivers/serial/serial_imx.c | 3 +
12 files changed, 469 insertions(+)
create mode 100644 arch/arm/mach-imx/clk-imx6ul.c
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* [PATCH 5/7] serial: i.MX: Add i.MX6ul support
From: Sascha Hauer @ 2016-11-08 17:19 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108171907.20726-1-s.hauer@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/serial/serial_imx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index f140310..2b1e5e0 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -287,6 +287,9 @@ static __maybe_unused struct of_device_id imx_serial_dt_ids[] = {
.compatible = "fsl,imx21-uart",
.data = &imx21_data,
}, {
+ .compatible = "fsl,imx6ul-uart",
+ .data = &imx21_data,
+ }, {
/* sentinel */
}
};
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH] ARM: i.MX: OCOTP: Add functions to access fuses field wise
From: Sascha Hauer @ 2016-11-08 13:43 UTC (permalink / raw)
To: Barebox List
Add functions to access the OCOTP fuses field wise, similar to what has
been done for the IIM. Also add a i.MX6 fusemap header file.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/include/mach/imx6-fusemap.h | 63 ++++++++++++++++++++++++++
arch/arm/mach-imx/include/mach/ocotp.h | 20 +++++++++
arch/arm/mach-imx/ocotp.c | 65 +++++++++++++++++++++++++++
3 files changed, 148 insertions(+)
create mode 100644 arch/arm/mach-imx/include/mach/imx6-fusemap.h
create mode 100644 arch/arm/mach-imx/include/mach/ocotp.h
diff --git a/arch/arm/mach-imx/include/mach/imx6-fusemap.h b/arch/arm/mach-imx/include/mach/imx6-fusemap.h
new file mode 100644
index 0000000..5fdd904
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx6-fusemap.h
@@ -0,0 +1,63 @@
+#ifndef __MACH_IMX_IMX6_OCOTP_H
+#define __MACH_IMX_IMX6_OCOTP_H
+
+#include <mach/ocotp.h>
+
+#define IMX6_OCOTP_TESTER_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(0) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_BOOT_CFG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(2) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_MEM_TRIM_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(4) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_SJC_RESP_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_MAC_ADDR_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(8) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_GP1_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(10) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_GP2_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(12) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_SRK_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(14) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_ANALOG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(18) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_MISC_CONF_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
+
+/* 0 <= n <= 1 */
+#define IMX6_OCOTP_UNIQUE_ID(n) (OCOTP_WORD(0x410 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_SI_REV (OCOTP_WORD(0x430) | OCOTP_BIT(16) | OCOTP_WIDTH(4))
+#define IMX6_OCOTP_NUM_CORES (OCOTP_WORD(0x430) | OCOTP_BIT(20) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_SATA_RST_SRC (OCOTP_WORD(0x430) | OCOTP_BIT(24) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_MLB_DISABLE (OCOTP_WORD(0x430) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_VPU_DISABLE (OCOTP_WORD(0x440) | OCOTP_BIT(15) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_SPEED_GRADING (OCOTP_WORD(0x440) | OCOTP_BIT(16) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_BOOT_CFG1 (OCOTP_WORD(0x450) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_BOOT_CFG2 (OCOTP_WORD(0x450) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_BOOT_CFG3 (OCOTP_WORD(0x450) | OCOTP_BIT(16) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_BOOT_CFG4 (OCOTP_WORD(0x450) | OCOTP_BIT(24) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_SEC_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_DIR_BT_DIS (OCOTP_WORD(0x460) | OCOTP_BIT(3) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_BT_FUSE_SEL (OCOTP_WORD(0x460) | OCOTP_BIT(4) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_DDR3_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_HDCP (OCOTP_WORD(0x460) | OCOTP_BIT(16) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_SJC_DISABLE (OCOTP_WORD(0x460) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_WDOG_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(21) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_JTAG_SMODE (OCOTP_WORD(0x460) | OCOTP_BIT(22) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_KTE (OCOTP_WORD(0x460) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_JTAG_HEO (OCOTP_WORD(0x460) | OCOTP_BIT(27) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_TZASC_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(28) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_SDMMC_HYS_EN (OCOTP_WORD(0x460) | OCOTP_BIT(29) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_eMMC_RESET_EN (OCOTP_WORD(0x460) | OCOTP_BIT(30) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_NAND_READ_CMD_CODE1 (OCOTP_WORD(0x470) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_NAND_READ_CMD_CODE2 (OCOTP_WORD(0x470) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
+#define IMX6_OCOTP_BT_LPB_POLARITY (OCOTP_WORD(0x470) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_LPB_BOOT (OCOTP_WORD(0x470) | OCOTP_BIT(21) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_MMC_DLL_DLY (OCOTP_WORD(0x470) | OCOTP_BIT(24) | OCOTP_WIDTH(7))
+#define IMX6_OCOTP_TEMPERATURE_GRADE (OCOTP_WORD(0x480) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
+#define IMX6_OCOTP_POWER_GATE_CORES (OCOTP_WORD(0x4d0) | OCOTP_BIT(31) | OCOTP_WIDTH(1))
+#define IMX6_OCOTP_USB_VID (OCOTP_WORD(0x4f0) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
+#define IMX6_OCOTP_USB_PID (OCOTP_WORD(0x4f0) | OCOTP_BIT(16) | OCOTP_WIDTH(16))
+/* 0 <= n <= 7 */
+#define IMX6_OCOTP_SRK_HASH(n) (OCOTP_WORD(0x580 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_SJC_RESP_31_0 (OCOTP_WORD(0x600) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_SJC_RESP_55_32 (OCOTP_WORD(0x610) | OCOTP_BIT(0) | OCOTP_WIDTH(24))
+#define IMX6_OCOTP_MAC_ADDR_31_0 (OCOTP_WORD(0x620) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_MAC_ADDR_47_32 (OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
+#define IMX6_OCOTP_GP1 (OCOTP_WORD(0x660) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_GP2 (OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
+#define IMX6_OCOTP_PAD_SETTINGS (OCOTP_WORD(0x6d0) | OCOTP_BIT(0) | OCOTP_WIDTH(6))
+#define IMX6DQ_OCOTP_TEST_PORT_DISABLE (OCOTP_WORD(0x6e0) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
+#define IMX6SDL_OCOTP_FIELD_RETURN (OCOTP_WORD(0x6e0) | OCOTP_BIT(0) | OCOTP_WIDTH(1))
+
+#endif /* __MACH_IMX_IMX6_OCOTP_H */
diff --git a/arch/arm/mach-imx/include/mach/ocotp.h b/arch/arm/mach-imx/include/mach/ocotp.h
new file mode 100644
index 0000000..430bc75
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/ocotp.h
@@ -0,0 +1,20 @@
+#ifndef __MACH_IMX_OCOTP_H
+#define __MACH_IMX_OCOTP_H
+
+#define OCOTP_WORD_MASK_WIDTH 8
+#define OCOTP_WORD_MASK_SHIFT 0
+#define OCOTP_WORD(n) ((((n) - 0x400) >> 4) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1))
+
+#define OCOTP_BIT_MASK_WIDTH 5
+#define OCOTP_BIT_MASK_SHIFT (OCOTP_WORD_MASK_SHIFT + OCOTP_WORD_MASK_WIDTH)
+#define OCOTP_BIT(n) (((n) & ((1 << OCOTP_BIT_MASK_WIDTH) - 1)) << OCOTP_BIT_MASK_SHIFT)
+
+#define OCOTP_WIDTH_MASK_WIDTH 5
+#define OCOTP_WIDTH_MASK_SHIFT (OCOTP_BIT_MASK_SHIFT + OCOTP_BIT_MASK_WIDTH)
+#define OCOTP_WIDTH(n) ((((n) - 1) & ((1 << OCOTP_WIDTH_MASK_WIDTH) - 1)) << OCOTP_WIDTH_MASK_SHIFT)
+
+int imx_ocotp_read_field(uint32_t field, unsigned *value);
+int imx_ocotp_write_field(uint32_t field, unsigned value);
+int imx_ocotp_permanent_write(int enable);
+
+#endif /* __MACH_IMX_OCOTP_H */
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 17b944b..3acec7f 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -28,6 +28,7 @@
#include <clock.h>
#include <regmap.h>
#include <linux/clk.h>
+#include <mach/ocotp.h>
/*
* a single MAC address reference has the form
@@ -87,6 +88,8 @@ struct ocotp_priv {
struct regmap_config map_config;
};
+static struct ocotp_priv *imx_ocotp;
+
static int imx6_ocotp_set_timing(struct ocotp_priv *priv)
{
u32 clk_rate;
@@ -282,6 +285,66 @@ static int imx_ocotp_reg_write(void *ctx, unsigned int reg, unsigned int val)
return 0;
}
+static void imx_ocotp_field_decode(uint32_t field, unsigned *word,
+ unsigned *bit, unsigned *mask)
+{
+ unsigned width;
+
+ *word = ((field >> OCOTP_WORD_MASK_SHIFT) & ((1 << OCOTP_WORD_MASK_WIDTH) - 1)) * 4;
+ *bit = (field >> OCOTP_BIT_MASK_SHIFT) & ((1 << OCOTP_BIT_MASK_WIDTH) - 1);
+ width = ((field >> OCOTP_WIDTH_MASK_SHIFT) & ((1 << OCOTP_WIDTH_MASK_WIDTH) - 1)) + 1;
+ *mask = (1 << width) - 1;
+}
+
+int imx_ocotp_read_field(uint32_t field, unsigned *value)
+{
+ unsigned word, bit, mask, val;
+ int ret;
+
+ imx_ocotp_field_decode(field, &word, &bit, &mask);
+
+ ret = imx_ocotp_reg_read(imx_ocotp, word, &val);
+ if (ret)
+ return ret;
+
+ val >>= bit;
+ val &= mask;
+
+ dev_dbg(&imx_ocotp->dev, "%s: word: 0x%x bit: %d mask: 0x%x val: 0x%x\n",
+ __func__, word, bit, mask, val);
+
+ *value = val;
+
+ return 0;
+}
+
+int imx_ocotp_write_field(uint32_t field, unsigned value)
+{
+ unsigned word, bit, mask;
+ int ret;
+
+ imx_ocotp_field_decode(field, &word, &bit, &mask);
+
+ value &= mask;
+ value <<= bit;
+
+ ret = imx_ocotp_reg_write(imx_ocotp, word, value);
+ if (ret)
+ return ret;
+
+ dev_dbg(&imx_ocotp->dev, "%s: word: 0x%x bit: %d mask: 0x%x val: 0x%x\n",
+ __func__, word, bit, mask, value);
+
+ return 0;
+}
+
+int imx_ocotp_permanent_write(int enable)
+{
+ imx_ocotp->permanent_write_enable = enable;
+
+ return 0;
+}
+
static uint32_t inc_offset(uint32_t offset)
{
if ((offset & 0x3) == 0x3)
@@ -412,6 +475,8 @@ static int imx_ocotp_probe(struct device_d *dev)
if (ret)
return ret;
+ imx_ocotp = priv;
+
if (IS_ENABLED(CONFIG_IMX_OCOTP_WRITE)) {
dev_add_param_bool(&(priv->dev), "permanent_write_enable",
NULL, NULL, &priv->permanent_write_enable, NULL);
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH] serial: i.MX uart: Allow DTE mode in lowlevel code
From: Sascha Hauer @ 2016-11-08 13:42 UTC (permalink / raw)
To: Barebox List
Some consoles must be configured for DTE mode. Allow to set this
in lowlevel code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
include/serial/imx-uart.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h
index 901b26a..b40044e 100644
--- a/include/serial/imx-uart.h
+++ b/include/serial/imx-uart.h
@@ -146,6 +146,15 @@ static inline void imx_uart_setup(void __iomem *uartbase,
writel(UCR1_UARTEN, uartbase + UCR1);
}
+static inline void imx_uart_set_dte(void __iomem *uartbase)
+{
+ u32 ufcr;
+
+ ufcr = readl(uartbase + UFCR);
+ ufcr |= UFCR_DCEDTE;
+ writel(ufcr, uartbase + UFCR);
+}
+
static inline void imx50_uart_setup(void __iomem *uartbase)
{
imx_uart_setup(uartbase, 66666666);
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 2/2] of: of_find_path: Add support for new partition binding
From: Sascha Hauer @ 2016-11-08 13:41 UTC (permalink / raw)
To: Barebox List
In-Reply-To: <20161108134149.3811-1-s.hauer@pengutronix.de>
The partitions now may be in a subnode of the actual device node.
Eventually go another step up in the hierarchy if required.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/of/of_path.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
index 8e1931f..1f5106d 100644
--- a/drivers/of/of_path.c
+++ b/drivers/of/of_path.c
@@ -56,7 +56,12 @@ static int __of_find_path(struct device_node *node, const char *part, char **out
dev = of_find_device_by_node_path(node->full_name);
if (!dev) {
- dev = of_find_device_by_node_path(node->parent->full_name);
+ struct device_node *devnode = node->parent;
+
+ if (of_device_is_compatible(devnode, "fixed-partitions"))
+ devnode = devnode->parent;
+
+ dev = of_find_device_by_node_path(devnode->full_name);
if (!dev)
return -ENODEV;
}
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* [PATCH 1/2] of: partitions: Support new binding
From: Sascha Hauer @ 2016-11-08 13:41 UTC (permalink / raw)
To: Barebox List
The new binding recommends to put the partitions into a subnode
with compatible "fixed-partitions". Add support for this binding.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/of/partition.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index b6621f7..bdf5945 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -80,6 +80,13 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node)
return -EINVAL;
for_each_child_of_node(node, n) {
+ if (of_device_is_compatible(n, "fixed-partitions")) {
+ node = n;
+ break;
+ }
+ }
+
+ for_each_child_of_node(node, n) {
of_parse_partition(cdev, n);
}
--
2.10.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related
* Re: Designware MAC reset timeout after Linux reboot
From: Ian Abbott @ 2016-11-08 12:25 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
In-Reply-To: <20161108085957.qqvl2ojnllll6hjn@pengutronix.de>
On 08/11/16 08:59, Steffen Trumtrar wrote:
> Hi!
>
> On Mon, Nov 07, 2016 at 05:56:51PM +0000, Ian Abbott wrote:
>> Hi everyone,
>>
>> I'm using barebox 2016.10.0 with some custom BSP patches for my Cyclone V
>> socfpga based board. I've noticed that after issuing a reboot in Linux,
>> followed by an 'ifup eth0' command in barebox, I get a "eth0: MAC reset
>> timeout" error, which causes dwc_ether_init() to bail out early. My Linux
>> kernel is Linux 4.1.17, plus LTSI-4.1.17 patches, plus Altera patches from
>> linux-socfpga kernel branch socfpga-4.1.22-ltsi, in that order (git rebase
>> is a wonderful thing!).
>>
>
> FYI: I just tested on a Socrates board with Linux 4.9-rc3 and barebox 2016.08.0
> and can not reproduce your problem. Does that always happen or just sometimes?
It always happens on my board. I could try reproducing it on a Socrates
board. I have a couple of Socrates version 1.2 boards and a Socrates
2.0 board, so I could try and reproduce the problem if I find time to
set it up.
My board is actually a prototype. The PHY clock was originally wired up
to completely the wrong pin on the FPGA (since it was based on an older
NiosII based design). It has been surgically altered so the PHY clock
is on a different wrong pin, but at least the new pin is clocked at the
correct frequency. This may or may not be related to my problem, but
the PHY seems to work OK before bringing up the MAC controller - miitool
shows it manages to establish a link at the physical level.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
* Re: Designware MAC reset timeout after Linux reboot
From: Ian Abbott @ 2016-11-08 12:13 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
In-Reply-To: <20161108080856.qyorpnvj4serg6ym@pengutronix.de>
On 08/11/16 08:08, Sascha Hauer wrote:
> Hi Ian,
>
> On Mon, Nov 07, 2016 at 05:56:51PM +0000, Ian Abbott wrote:
>> Hi everyone,
>>
>> I'm using barebox 2016.10.0 with some custom BSP patches for my Cyclone V
>> socfpga based board. I've noticed that after issuing a reboot in Linux,
>> followed by an 'ifup eth0' command in barebox, I get a "eth0: MAC reset
>> timeout" error, which causes dwc_ether_init() to bail out early. My Linux
>> kernel is Linux 4.1.17, plus LTSI-4.1.17 patches, plus Altera patches from
>> linux-socfpga kernel branch socfpga-4.1.22-ltsi, in that order (git rebase
>> is a wonderful thing!).
>>
>> Socfpga has two Ethernet MAC controllers. Like several other Cyclone V
>> boards, my board's device tree disables the first one (&gmac0) and aliases
>> ethernet0 to the second one (&gmac1).
>>
>> I don't need the ethernet to work to boot Linux, and Linux manages to
>> reinitialize the ethernet okay, so it's more of a inconvenience to me than a
>> show-stopper - I just need to power-cycle the board if I want ethernet
>> access in barebox.
>
> Have you searched in the Linux code what it does differently so that it
> can successfully reset the MAC?
The Linux code paths are more convoluted, including calls into the reset
manager. I found the code that resets the MAC DMA controller though -
see below....
>> I am aware of Trent Piepho's patch (commit
>> f0ae0c33f52ced89da080673ca89a3c5f2ea70e6) which brings the PHY out of
>> power-down mode before resetting the MAC DMA controller. In fact, the PHY
>> doesn't seem to be in power-down mode in my case, as the value read from the
>> MII_BMCR in phy_resume() is 0x1140 (BMCR_ANENABLE | BMCR_FULLDPLX |
>> BMCR_SPEED1000).
>>
>> There must be something else stopping the software reset of the MAC
>> completing successfully, but I'm not sure what. The Cyclone V Hard
>> Processor System Technical Reference Manual says this about the MAC DMA
>> software reset bit:
>>
>> | Note: * The Software reset system is driven only by this bit. *
>> | The reset operation is completed only when all resets in all
>> | active clock domains are de-asserted. Therefore, it is
>> | essential that all the PHY inputs clocks (applicable for the
>> | selected PHY interface) are present for the software reset
>> | completion.
>>
>> Perhaps the timeout isn't waiting long enough. If I interrupt the 'ifup
>> eth0' command and display the approriate 'Bus_Mode' register (0xff703000)
>> with the 'md' command, the DMAMAC_SRST bit (bit 0) is no longer set:
>>
>> barebox@xxxx:/ md -l 0xff703000+4
>> ff703000: 00020100
>
> The timeout is 10ms, this should be way enough. The return value of
> dwc_ether_init() is not checked, so the driver happily continues with
> further register writes, I assume there must be something that clears
> this bit afterwards, either directly or indirectly.
The bit is supposed to clear itself, but I guess something else could be
clearing it too.
The code to reset the MAC DMA controller in Linux kernel 4.1 is
dwmac1000_dma_init() in
"drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c". In Linux kernel
4.6, the function is dwmac_dma_reset() in "dwmac_lib.c". In both cases,
the code to reset the DMA controller is basically as follows:
u32 value = readl(ioaddr + DMA_BUS_MODE);
int limit;
/* DMA SW reset */
value |= DMA_BUS_MODE_SFT_RESET;
writel(value, ioaddr + DMA_BUS_MODE);
limit = 10;
while (limit--) {
if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
break;
mdelay(10);
}
if (limit < 0)
return -EBUSY;
It's interesting that it only bothers to check for reset completion
every 10 ms (timing out after 100 ms), so it must be expecting it to
take a while!
I'll experiment with the timeout on my board to see if the bit ever
clears itself.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=-
-=( Web: http://www.mev.co.uk/ )=-
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox