* [PATCH 1/5] ARM: i.MX: Add i.MX7 base architecture support
2017-01-19 15:23 [patch v2] i.MX7 support Sascha Hauer
@ 2017-01-19 15:23 ` Sascha Hauer
2017-01-19 15:23 ` [PATCH 2/5] pinmmux: i.MX: add pin mux support for i.MX7 Sascha Hauer
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:23 UTC (permalink / raw)
To: Barebox List; +Cc: Juergen Borleis
From: Juergen Borleis <jbe@pengutronix.de>
Signed-off-by Juergen Borleis <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/boards/imx.rst | 1 +
arch/arm/mach-imx/Kconfig | 4 ++
arch/arm/mach-imx/Makefile | 1 +
arch/arm/mach-imx/boot.c | 70 ++++++++++++++++++++++++
arch/arm/mach-imx/cpu_init.c | 5 ++
arch/arm/mach-imx/imx.c | 6 +++
arch/arm/mach-imx/imx7.c | 75 ++++++++++++++++++++++++++
arch/arm/mach-imx/include/mach/debug_ll.h | 3 ++
arch/arm/mach-imx/include/mach/generic.h | 16 ++++++
arch/arm/mach-imx/include/mach/imx7-regs.h | 24 +++++++++
arch/arm/mach-imx/include/mach/imx7.h | 59 ++++++++++++++++++++
arch/arm/mach-imx/include/mach/imx_cpu_types.h | 1 +
common/Kconfig | 8 +++
include/serial/imx-uart.h | 5 ++
scripts/imx/imx.c | 1 +
15 files changed, 279 insertions(+)
create mode 100644 arch/arm/mach-imx/imx7.c
create mode 100644 arch/arm/mach-imx/include/mach/imx7-regs.h
create mode 100644 arch/arm/mach-imx/include/mach/imx7.h
diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst
index 60cdcf072..b6e65060c 100644
--- a/Documentation/boards/imx.rst
+++ b/Documentation/boards/imx.rst
@@ -20,6 +20,7 @@ The Internal Boot Mode is supported on:
* i.MX51
* i.MX53
* i.MX6
+* i.MX7
With the Internal Boot Mode, the images contain a header which describes
where the binary shall be loaded and started. These headers also contain
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 62e6494c2..ba5a9c445 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -157,6 +157,10 @@ config ARCH_IMX6UL
bool
select ARCH_IMX6
+config ARCH_IMX7
+ bool
+ select CPU_V7
+
config ARCH_VF610
bool
select ARCH_HAS_L2X0
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d0fe7abc0..fc5305f05 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
+obj-$(CONFIG_ARCH_IMX7) += imx7.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/boot.c b/arch/arm/mach-imx/boot.c
index 489306072..72597f5e2 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -25,6 +25,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
+#include <mach/imx7-regs.h>
/* [CTRL][TYPE] */
static const enum bootsource locations[4][4] = {
@@ -346,3 +347,72 @@ void imx6_boot_save_loc(void)
bootsource_set(src);
bootsource_set_instance(instance);
}
+
+#define IMX7_SRC_SBMR1 0x58
+#define IMX7_SRC_SBMR2 0x70
+
+void imx7_get_boot_source(enum bootsource *src, int *instance)
+{
+ void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR);
+ uint32_t sbmr1 = readl(src_base + IMX7_SRC_SBMR1);
+ uint32_t sbmr2 = readl(src_base + IMX7_SRC_SBMR2);
+ int boot_mode;
+
+ /* BMOD[1:0] */
+ boot_mode = (sbmr2 >> 24) & 0x3;
+
+ switch (boot_mode) {
+ case 0: /* Fuses, fall through */
+ case 2: /* internal boot */
+ goto internal_boot;
+ case 1: /* Serial Downloader */
+ *src = BOOTSOURCE_SERIAL;
+ break;
+ case 3: /* reserved */
+ break;
+ };
+
+ return;
+
+internal_boot:
+
+ switch ((sbmr1 >> 12) & 0xf) {
+ case 1:
+ case 2:
+ *src = BOOTSOURCE_MMC;
+ *instance = (sbmr1 >> 10 & 0x3);
+ break;
+ case 3:
+ *src = BOOTSOURCE_NAND;
+ break;
+ case 4:
+ *src = BOOTSOURCE_SPI_NOR,
+ *instance = (sbmr1 >> 9 & 0x7);
+ break;
+ case 6:
+ *src = BOOTSOURCE_SPI; /* Really: qspi */
+ break;
+ case 5:
+ *src = BOOTSOURCE_NOR;
+ break;
+ default:
+ break;
+ }
+
+ /* BOOT_CFG1[7:0] */
+ if (sbmr1 & (1 << 7))
+ *src = BOOTSOURCE_NAND;
+
+ return;
+}
+
+void imx7_boot_save_loc(void)
+{
+ enum bootsource src = BOOTSOURCE_UNKNOWN;
+ int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+
+ imx7_get_boot_source(&src, &instance);
+
+ bootsource_set(src);
+ bootsource_set_instance(instance);
+}
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index 6971d89d9..2b388cad8 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -34,6 +34,11 @@ void imx6_cpu_lowlevel_init(void)
enable_arm_errata_845369_war();
}
+void imx7_cpu_lowlevel_init(void)
+{
+ arm_cpu_lowlevel_init();
+}
+
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 952db007d..907340fc5 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -65,6 +65,10 @@ static int imx_soc_from_dt(void)
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6ul"))
return IMX_CPU_IMX6;
+ if (of_machine_is_compatible("fsl,imx7s"))
+ return IMX_CPU_IMX7;
+ if (of_machine_is_compatible("fsl,imx7d"))
+ return IMX_CPU_IMX7;
if (of_machine_is_compatible("fsl,vf610"))
return IMX_CPU_VF610;
@@ -103,6 +107,8 @@ static int imx_init(void)
ret = imx53_init();
else if (cpu_is_mx6())
ret = imx6_init();
+ else if (cpu_is_mx7())
+ ret = imx7_init();
else if (cpu_is_vf610())
ret = 0;
else
diff --git a/arch/arm/mach-imx/imx7.c b/arch/arm/mach-imx/imx7.c
new file mode 100644
index 000000000..fde66d838
--- /dev/null
+++ b/arch/arm/mach-imx/imx7.c
@@ -0,0 +1,75 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <init.h>
+#include <common.h>
+#include <io.h>
+#include <linux/sizes.h>
+#include <mach/imx7.h>
+#include <mach/generic.h>
+#include <mach/revision.h>
+#include <mach/imx7-regs.h>
+
+void imx7_init_lowlevel(void)
+{
+ void __iomem *aips1 = IOMEM(MX7_AIPS1_CONFIG_BASE_ADDR);
+ void __iomem *aips2 = IOMEM(MX7_AIPS2_CONFIG_BASE_ADDR);
+
+ /*
+ * Set all MPROTx to be non-bufferable, trusted for R/W,
+ * not forced to user-mode.
+ */
+ writel(0x77777777, aips1);
+ writel(0x77777777, aips1 + 0x4);
+ writel(0, aips1 + 0x40);
+ writel(0, aips1 + 0x44);
+ writel(0, aips1 + 0x48);
+ writel(0, aips1 + 0x4c);
+ writel(0, aips1 + 0x50);
+
+ writel(0x77777777, aips2);
+ writel(0x77777777, aips2 + 0x4);
+ writel(0, aips2 + 0x40);
+ writel(0, aips2 + 0x44);
+ writel(0, aips2 + 0x48);
+ writel(0, aips2 + 0x4c);
+ writel(0, aips2 + 0x50);
+}
+
+int imx7_init(void)
+{
+ const char *cputypestr;
+ u32 imx7_silicon_revision;
+
+ imx7_init_lowlevel();
+
+ imx7_boot_save_loc();
+
+ imx7_silicon_revision = imx7_cpu_revision();
+
+ switch (imx7_cpu_type()) {
+ case IMX7_CPUTYPE_IMX7D:
+ cputypestr = "i.MX7d";
+ break;
+ case IMX7_CPUTYPE_IMX7S:
+ cputypestr = "i.MX7s";
+ break;
+ default:
+ cputypestr = "unknown i.MX7";
+ break;
+ }
+
+ imx_set_silicon_revision(cputypestr, imx7_silicon_revision);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index a132f3c16..39d710f7d 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -14,6 +14,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
+#include <mach/imx7-regs.h>
#include <mach/vf610-regs.h>
#include <serial/imx-uart.h>
@@ -44,6 +45,8 @@
#define IMX_DEBUG_SOC MX53
#elif defined CONFIG_DEBUG_IMX6Q_UART
#define IMX_DEBUG_SOC MX6
+#elif defined CONFIG_DEBUG_IMX7D_UART
+#define IMX_DEBUG_SOC MX7
#elif defined CONFIG_DEBUG_VF610_UART
#define IMX_DEBUG_SOC VF610
#else
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 34194509e..73be9ceb5 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -14,12 +14,14 @@ void imx27_boot_save_loc(void);
void imx51_boot_save_loc(void);
void imx53_boot_save_loc(void);
void imx6_boot_save_loc(void);
+void imx7_boot_save_loc(void);
void imx25_get_boot_source(enum bootsource *src, int *instance);
void imx35_get_boot_source(enum bootsource *src, int *instance);
void imx51_get_boot_source(enum bootsource *src, int *instance);
void imx53_get_boot_source(enum bootsource *src, int *instance);
void imx6_get_boot_source(enum bootsource *src, int *instance);
+void imx7_get_boot_source(enum bootsource *src, int *instance);
int imx1_init(void);
int imx21_init(void);
@@ -31,6 +33,7 @@ int imx50_init(void);
int imx51_init(void);
int imx53_init(void);
int imx6_init(void);
+int imx7_init(void);
int imx1_devices_init(void);
int imx21_devices_init(void);
@@ -45,6 +48,7 @@ int imx6_devices_init(void);
void imx5_cpu_lowlevel_init(void);
void imx6_cpu_lowlevel_init(void);
+void imx7_cpu_lowlevel_init(void);
void vf610_cpu_lowlevel_init(void);
/* There's a off-by-one betweem the gpio bank number and the gpiochip */
@@ -174,6 +178,18 @@ extern unsigned int __imx_cpu_type;
# define cpu_is_mx6() (0)
#endif
+#ifdef CONFIG_ARCH_IMX7
+# ifdef imx_cpu_type
+# undef imx_cpu_type
+# define imx_cpu_type __imx_cpu_type
+# else
+# define imx_cpu_type IMX_CPU_IMX7
+# endif
+# define cpu_is_mx7() (imx_cpu_type == IMX_CPU_IMX7)
+#else
+# define cpu_is_mx7() (0)
+#endif
+
#ifdef CONFIG_ARCH_VF610
# ifdef imx_cpu_type
# undef imx_cpu_type
diff --git a/arch/arm/mach-imx/include/mach/imx7-regs.h b/arch/arm/mach-imx/include/mach/imx7-regs.h
new file mode 100644
index 000000000..a96341d6d
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx7-regs.h
@@ -0,0 +1,24 @@
+#ifndef __MACH_IMX7_REGS_H
+#define __MACH_IMX7_REGS_H
+
+#define MX7_AIPS1_BASE_ADDR 0x30000000
+#define MX7_AIPS2_BASE_ADDR 0x30400000
+#define MX7_AIPS3_BASE_ADDR 0x30800000
+
+#define MX7_AIPS1_CONFIG_BASE_ADDR 0x301f0000
+#define MX7_IOMUX_BASE_ADDR 0x30330000
+#define MX7_OCOTP_BASE_ADDR 0x30350000
+#define MX7_ANATOP_BASE_ADDR 0x30360000
+#define MX7_CCM_BASE_ADDR 0x30380000
+#define MX7_SRC_BASE_ADDR 0x30390000
+#define MX7_SCTR_BASE_ADDR 0x306c0000
+#define MX7_UART1_BASE_ADDR 0x30860000
+#define MX7_UART2_BASE_ADDR 0x30870000
+#define MX7_UART3_BASE_ADDR 0x30880000
+#define MX7_UART4_BASE_ADDR 0x30a60000
+#define MX7_UART5_BASE_ADDR 0x30a70000
+#define MX7_UART6_BASE_ADDR 0x30a80000
+#define MX7_UART7_BASE_ADDR 0x30a90000
+#define MX7_AIPS2_CONFIG_BASE_ADDR 0x305f0000
+
+#endif /* __MACH_IMX7_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx7.h b/arch/arm/mach-imx/include/mach/imx7.h
new file mode 100644
index 000000000..851893546
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/imx7.h
@@ -0,0 +1,59 @@
+#ifndef __MACH_IMX7_H
+#define __MACH_IMX7_H
+
+#include <io.h>
+#include <mach/generic.h>
+#include <mach/imx7-regs.h>
+#include <mach/revision.h>
+
+void imx7_init_lowlevel(void);
+
+#define ANADIG_DIGPROG_IMX7 0x800
+
+#define IMX7_CPUTYPE_IMX7S 0x71
+#define IMX7_CPUTYPE_IMX7D 0x72
+
+static inline int __imx7_cpu_type(void)
+{
+ void __iomem *ocotp = IOMEM(MX7_OCOTP_BASE_ADDR);
+
+ if (readl(ocotp + 0x450) & 1)
+ return IMX7_CPUTYPE_IMX7S;
+ else
+ return IMX7_CPUTYPE_IMX7D;
+}
+
+static inline int imx7_cpu_type(void)
+{
+ if (!cpu_is_mx7())
+ return 0;
+
+ return __imx7_cpu_type();
+}
+
+static inline int imx7_cpu_revision(void)
+{
+ if (!cpu_is_mx7())
+ return IMX_CHIP_REV_UNKNOWN;
+
+ /* register value has the format of the IMX_CHIP_REV_* macros */
+ return readl(MX7_ANATOP_BASE_ADDR + ANADIG_DIGPROG_IMX7) & 0xff;
+}
+
+#define DEFINE_MX7_CPU_TYPE(str, type) \
+ static inline int cpu_mx7_is_##str(void) \
+ { \
+ return __imx7_cpu_type() == type; \
+ } \
+ \
+ static inline int cpu_is_##str(void) \
+ { \
+ if (!cpu_is_mx7()) \
+ return 0; \
+ return cpu_mx7_is_##str(); \
+ }
+
+DEFINE_MX7_CPU_TYPE(mx7s, IMX7_CPUTYPE_IMX7S);
+DEFINE_MX7_CPU_TYPE(mx7d, IMX7_CPUTYPE_IMX7D);
+
+#endif /* __MACH_IMX7_H */
\ No newline at end of file
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 50be0b6b5..f95ef6f13 100644
--- a/arch/arm/mach-imx/include/mach/imx_cpu_types.h
+++ b/arch/arm/mach-imx/include/mach/imx_cpu_types.h
@@ -11,6 +11,7 @@
#define IMX_CPU_IMX51 51
#define IMX_CPU_IMX53 53
#define IMX_CPU_IMX6 6
+#define IMX_CPU_IMX7 7
#define IMX_CPU_VF610 610
#endif /* __MACH_IMX_CPU_TYPES_H */
diff --git a/common/Kconfig b/common/Kconfig
index 462c104fd..350e3d49d 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1072,6 +1072,13 @@ config DEBUG_IMX6Q_UART
Say Y here if you want kernel low-level debugging support
on i.MX6Q.
+config DEBUG_IMX7D_UART
+ bool "i.MX7D Debug UART"
+ depends on ARCH_IMX7
+ help
+ Say Y here if you want barebox low-level debugging support
+ on i.MX7D.
+
config DEBUG_VF610_UART
bool "VF610 Debug UART"
depends on ARCH_VF610
@@ -1120,6 +1127,7 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
+ DEBUG_IMX7D_UART || \
DEBUG_VF610_UART
default 1
depends on ARCH_IMX
diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h
index b40044ea4..9cab32f35 100644
--- a/include/serial/imx-uart.h
+++ b/include/serial/imx-uart.h
@@ -175,6 +175,11 @@ static inline void imx6_uart_setup(void __iomem *uartbase)
imx_uart_setup(uartbase, 80000000);
}
+static inline void imx7_uart_setup(void __iomem *uartbase)
+{
+ imx_uart_setup(uartbase, 24000000);
+}
+
static inline void imx_uart_putc(void *base, int c)
{
if (!(readl(base + UCR1) & UCR1_UARTEN))
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
index bf3a42fb2..809d8a7f7 100644
--- a/scripts/imx/imx.c
+++ b/scripts/imx/imx.c
@@ -231,6 +231,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 = "imx7", .header_version = 2, .cpu_type = IMX_CPU_IMX7 },
{ .name = "vf610", .header_version = 2, .cpu_type = IMX_CPU_VF610 },
};
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/5] pinmmux: i.MX: add pin mux support for i.MX7
2017-01-19 15:23 [patch v2] i.MX7 support Sascha Hauer
2017-01-19 15:23 ` [PATCH 1/5] ARM: i.MX: Add i.MX7 base architecture support Sascha Hauer
@ 2017-01-19 15:23 ` Sascha Hauer
2017-01-19 15:23 ` [PATCH 3/5] ARM: i.MX: Add WaRP7 board support Sascha Hauer
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:23 UTC (permalink / raw)
To: Barebox List; +Cc: Juergen Borleis
From: Juergen Borleis <jbe@pengutronix.de>
Signed-off-by Juergen Borleis <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/pinctrl/imx-iomux-v3.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/pinctrl/imx-iomux-v3.c b/drivers/pinctrl/imx-iomux-v3.c
index bc9314083..b5fa23560 100644
--- a/drivers/pinctrl/imx-iomux-v3.c
+++ b/drivers/pinctrl/imx-iomux-v3.c
@@ -24,14 +24,19 @@
#include <pinctrl.h>
#include <malloc.h>
#include <mach/iomux-v3.h>
+#include <mach/generic.h>
struct imx_iomux_v3 {
void __iomem *base;
struct pinctrl_device pinctrl;
+ unsigned int flags;
};
-static void __iomem *iomuxv3_base;
+struct imx_iomux_v3_data {
+ unsigned int flags;
+};
+static void __iomem *iomuxv3_base;
/*
* configures a single pad in the iomuxer
@@ -111,7 +116,7 @@ static int imx_iomux_v3_set_state(struct pinctrl_device *pdev, struct device_nod
if (conf_val & IMX_DT_NO_PAD_CTL)
conf_reg = 0;
- iomux_v3_setup_pad(iomux->base, 0,
+ iomux_v3_setup_pad(iomux->base, iomux->flags,
mux_reg, conf_reg, input_reg,
mux_val, conf_val, input_val);
}
@@ -126,14 +131,18 @@ static struct pinctrl_ops imx_iomux_v3_ops = {
static int imx_pinctrl_dt(struct device_d *dev, void __iomem *base)
{
struct imx_iomux_v3 *iomux;
+ struct imx_iomux_v3_data *drvdata = NULL;
int ret;
+ dev_get_drvdata(dev, (const void **)&drvdata);
iomux = xzalloc(sizeof(*iomux));
iomux->base = base;
iomux->pinctrl.dev = dev;
iomux->pinctrl.ops = &imx_iomux_v3_ops;
+ if (drvdata)
+ iomux->flags = drvdata->flags;
ret = pinctrl_register(&iomux->pinctrl);
if (ret)
@@ -144,23 +153,33 @@ static int imx_pinctrl_dt(struct device_d *dev, void __iomem *base)
static int imx_iomux_v3_probe(struct device_d *dev)
{
+ void __iomem *base;
struct resource *iores;
int ret = 0;
- if (iomuxv3_base)
- return -EBUSY;
-
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
- iomuxv3_base = IOMEM(iores->start);
+ base = IOMEM(iores->start);
+
+ if (!iomuxv3_base)
+ /*
+ * Uh, this works only for the older controllers, not for
+ * i.MX7 which has two iomux controllers. i.MX7 based boards
+ * should not use mxc_iomux_v3_setup_pad anyway.
+ */
+ iomuxv3_base = base;
if (IS_ENABLED(CONFIG_PINCTRL) && dev->device_node)
- ret = imx_pinctrl_dt(dev, iomuxv3_base);
+ ret = imx_pinctrl_dt(dev, base);
return ret;
}
+static struct imx_iomux_v3_data imx_iomux_imx7_lpsr_data = {
+ .flags = ZERO_OFFSET_VALID,
+};
+
static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
{
.compatible = "fsl,imx25-iomuxc",
@@ -172,13 +191,18 @@ static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
.compatible = "fsl,imx53-iomuxc",
}, {
.compatible = "fsl,imx6q-iomuxc",
- }, {
+ }, {
.compatible = "fsl,imx6dl-iomuxc",
}, {
.compatible = "fsl,imx6sx-iomuxc",
}, {
.compatible = "fsl,imx6ul-iomuxc",
}, {
+ .compatible = "fsl,imx7d-iomuxc",
+ }, {
+ .compatible = "fsl,imx7d-iomuxc-lpsr",
+ .data = &imx_iomux_imx7_lpsr_data,
+ }, {
/* sentinel */
}
};
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] ARM: i.MX: Add WaRP7 board support
2017-01-19 15:23 [patch v2] i.MX7 support Sascha Hauer
2017-01-19 15:23 ` [PATCH 1/5] ARM: i.MX: Add i.MX7 base architecture support Sascha Hauer
2017-01-19 15:23 ` [PATCH 2/5] pinmmux: i.MX: add pin mux support for i.MX7 Sascha Hauer
@ 2017-01-19 15:23 ` Sascha Hauer
2017-01-19 15:23 ` [PATCH 4/5] ARM: i.MX7: initialize architected timer Sascha Hauer
2017-01-19 15:23 ` [PATCH 5/5] regulator: Add pfuze driver Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:23 UTC (permalink / raw)
To: Barebox List; +Cc: Juergen Borleis
From: Juergen Borleis <jbe@pengutronix.de>
Signed-off-by Juergen Borleis <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/boards/imx/Element14-WaRP7.rst | 54 +++++++++++++++
arch/arm/boards/Makefile | 1 +
arch/arm/boards/element14-warp7/Makefile | 2 +
arch/arm/boards/element14-warp7/board.c | 35 ++++++++++
| 81 ++++++++++++++++++++++
arch/arm/boards/element14-warp7/lowlevel.c | 48 +++++++++++++
arch/arm/dts/Makefile | 1 +
arch/arm/dts/imx7s-warp.dts | 62 +++++++++++++++++
arch/arm/mach-imx/Kconfig | 5 ++
images/Makefile.imx | 5 ++
10 files changed, 294 insertions(+)
create mode 100644 Documentation/boards/imx/Element14-WaRP7.rst
create mode 100644 arch/arm/boards/element14-warp7/Makefile
create mode 100644 arch/arm/boards/element14-warp7/board.c
create mode 100644 arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg
create mode 100644 arch/arm/boards/element14-warp7/lowlevel.c
create mode 100644 arch/arm/dts/imx7s-warp.dts
diff --git a/Documentation/boards/imx/Element14-WaRP7.rst b/Documentation/boards/imx/Element14-WaRP7.rst
new file mode 100644
index 000000000..d4e5e7991
--- /dev/null
+++ b/Documentation/boards/imx/Element14-WaRP7.rst
@@ -0,0 +1,54 @@
+element14 WaRP7
+===============
+
+This CPU card is based on an NXP i.MX7S SoC.
+
+Supported hardware
+==================
+
+- NXP PMIC PFUZE3000
+- Kingston 08EMCP04-EL3AV100 eMCP (eMMC and LPDDR3 memory in one package)
+ - 8 GiB eMMC Triple-Level cell NAND flash, eMMC standard 5.0 (HS400)
+ - 512 MiB LPDDR3 SDRAM starting at address 0x80000000
+
+Bootstrapping barebox
+=====================
+
+The device boots in internal boot mode from eMMC and is shipped with a
+vendor modified u-boot imximage.
+
+Barebox can be used as a drop-in replacement for the shipped bootloader.
+
+The WaRP7 IO Board has a double DIP switch where switch number two defines the
+boot source of the i.MX7 SoC:
+
+ +-----+
+ | |
+ | | O | <--- on = high level
+ | | | |
+ | O | | <--- off = low level
+ | |
+ | 1 2 |
+ +-----+
+
+Bootsource is the internal eMMC:
+
+ +-----+
+ | |
+ | O | |
+ | | | |
+ | | O | <---- eMMC
+ | |
+ | 1 2 |
+ +-----+
+
+Bootsource is the USB:
+
+ +-----+
+ | |
+ | O O | <---- USB
+ | | | |
+ | | | |
+ | |
+ | 1 2 |
+ +-----+
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index fe5c20932..2f1a79f01 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -140,5 +140,6 @@ obj-$(CONFIG_MACH_ZYLONITE) += zylonite/
obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/
obj-$(CONFIG_MACH_VSCOM_BALTOS) += vscom-baltos/
obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/
+obj-$(CONFIG_MACH_WARP7) += element14-warp7/
obj-$(CONFIG_MACH_VF610_TWR) += freescale-vf610-twr/
obj-$(CONFIG_MACH_ZII_RDU2) += zii-imx6q-rdu2/
diff --git a/arch/arm/boards/element14-warp7/Makefile b/arch/arm/boards/element14-warp7/Makefile
new file mode 100644
index 000000000..01c7a259e
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/element14-warp7/board.c b/arch/arm/boards/element14-warp7/board.c
new file mode 100644
index 000000000..84fc885da
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/board.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <environment.h>
+#include <mach/bbu.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <mach/generic.h>
+#include <linux/sizes.h>
+
+static int warp7_devices_init(void)
+{
+ if (!of_machine_is_compatible("warp,imx7s-warp"))
+ return 0;
+
+ imx6_bbu_internal_mmc_register_handler("mmc", "/dev/mmc2.boot0.barebox",
+ BBU_HANDLER_FLAG_DEFAULT);
+
+ return 0;
+}
+device_initcall(warp7_devices_init);
--git a/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg b/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg
new file mode 100644
index 000000000..a3389218d
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/flash-header-mx7-warp.imxcfg
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 NXP Semiconductors
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Refer docs/README.imxmage for more details about how-to configure
+ * and create imximage boot image
+ *
+ * The syntax is taken as close as possible with the kwbimage
+ */
+
+soc imx7
+loadaddr 0x80000000
+dcdofs 0x400
+
+wm 32 0x30340004 0x4F400005
+
+wm 32 0x30391000 0x00000002
+wm 32 0x307a0000 0x03040008
+wm 32 0x307a0064 0x00200038
+wm 32 0x307a0490 0x00000001
+wm 32 0x307a00d0 0x00350001
+wm 32 0x307a00dc 0x00c3000a
+wm 32 0x307a00e0 0x00010000
+wm 32 0x307a00e4 0x00110006
+wm 32 0x307a00f4 0x0000033f
+wm 32 0x307a0100 0x0a0e110b
+wm 32 0x307a0104 0x00020211
+wm 32 0x307a0108 0x03060708
+wm 32 0x307a010c 0x00a0500c
+wm 32 0x307a0110 0x05020307
+wm 32 0x307a0114 0x02020404
+wm 32 0x307a0118 0x02020003
+wm 32 0x307a011c 0x00000202
+wm 32 0x307a0120 0x00000202
+
+wm 32 0x307a0180 0x00600018
+wm 32 0x307a0184 0x00e00100
+wm 32 0x307a0190 0x02098205
+wm 32 0x307a0194 0x00060303
+wm 32 0x307a01a0 0x80400003
+wm 32 0x307a01a4 0x00100020
+wm 32 0x307a01a8 0x80100004
+
+wm 32 0x307a0200 0x00000015
+wm 32 0x307a0204 0x00161616
+wm 32 0x307a0210 0x00000f0f
+wm 32 0x307a0214 0x04040404
+wm 32 0x307a0218 0x0f0f0404
+
+wm 32 0x307a0240 0x06000600
+wm 32 0x307a0244 0x00000000
+wm 32 0x30391000 0x00000000
+wm 32 0x30790000 0x17421e40
+wm 32 0x30790004 0x10210100
+wm 32 0x30790008 0x00010000
+wm 32 0x30790010 0x0007080c
+wm 32 0x307900b0 0x1010007e
+
+wm 32 0x3079001C 0x01010000
+wm 32 0x3079009c 0x00000d6e
+
+wm 32 0x30790030 0x06060606
+wm 32 0x30790020 0x0a0a0a0a
+wm 32 0x30790050 0x01000008
+wm 32 0x30790050 0x00000008
+wm 32 0x30790018 0x0000000f
+wm 32 0x307900c0 0x0e487304
+wm 32 0x307900c0 0x0e4c7304
+wm 32 0x307900c0 0x0e4c7306
+wm 32 0x307900c0 0x0e4c7304
+
+check 32 while_any_bit_clear 0x307900c4 0x1
+
+wm 32 0x307900c0 0x0e487304
+
+wm 32 0x30384130 0x00000000
+wm 32 0x30340020 0x00000178
+wm 32 0x30384130 0x00000002
+
+check 32 while_any_bit_clear 0x307a0004 0x1
diff --git a/arch/arm/boards/element14-warp7/lowlevel.c b/arch/arm/boards/element14-warp7/lowlevel.c
new file mode 100644
index 000000000..98d8b6436
--- /dev/null
+++ b/arch/arm/boards/element14-warp7/lowlevel.c
@@ -0,0 +1,48 @@
+#define DEBUG
+#include <io.h>
+#include <common.h>
+#include <linux/sizes.h>
+#include <mach/generic.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/debug_ll.h>
+#include <asm/cache.h>
+
+extern char __dtb_imx7s_warp_start[];
+
+static noinline void warp7_start(void)
+{
+ void __iomem *iomuxbase = IOMEM(MX7_IOMUX_BASE_ADDR);
+ void __iomem *uart = IOMEM(MX7_UART1_BASE_ADDR);
+ void __iomem *ccmbase = IOMEM(MX7_CCM_BASE_ADDR);
+ void *fdt;
+
+ writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x8);
+ writel(0x10000000, ccmbase + 0x8000 + 128 * 95);
+ writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x4);
+ writel(0x0, iomuxbase + 0x128);
+ writel(0x0, iomuxbase + 0x12c);
+
+ imx7_uart_setup(uart);
+
+ pbl_set_putc(imx_uart_putc, uart);
+
+ pr_debug("Element14 i.MX7 Warp\n");
+
+ fdt = __dtb_imx7s_warp_start - get_runtime_offset();
+
+ barebox_arm_entry(0x80000000, SZ_512M, fdt);
+}
+
+ENTRY_FUNCTION(start_imx7s_element14_warp7, r0, r1, r2)
+{
+ imx7_cpu_lowlevel_init();
+
+ arm_early_mmu_cache_invalidate();
+
+ relocate_to_current_adr();
+ setup_c();
+ barrier();
+
+ warp7_start();
+}
\ No newline at end of file
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f5fb0cdbb..d77a7b612 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -79,6 +79,7 @@ pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
pbl-dtb-$(CONFIG_MACH_VSCOM_BALTOS) += am335x-baltos-minimal.dtb.o
+pbl-dtb-$(CONFIG_MACH_WARP7) += imx7s-warp.dtb.o
pbl-dtb-$(CONFIG_MACH_VF610_TWR) += vf610-twr.dtb.o
pbl-dtb-$(CONFIG_MACH_ZII_RDU2) += imx6q-zii-rdu2.dtb.o imx6qp-zii-rdu2.dtb.o
diff --git a/arch/arm/dts/imx7s-warp.dts b/arch/arm/dts/imx7s-warp.dts
new file mode 100644
index 000000000..a59823da0
--- /dev/null
+++ b/arch/arm/dts/imx7s-warp.dts
@@ -0,0 +1,62 @@
+/*
+ * 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 <arm/imx7s-warp.dts>
+#include "imx7s.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+
+ environment@0 {
+ compatible = "barebox,environment";
+ device-path = &bareboxenv;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>;
+ };
+};
+
+&usdhc3 {
+ boot0-partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ barebox@0 {
+ label = "barebox";
+ reg = <0x0 0x300000>;
+ };
+
+ bareboxenv: bareboxenv@300000 {
+ label = "bareboxenv";
+ reg = <0x300000 0x0>;
+ };
+ };
+};
+
+/*
+/* The watchdog pinctrl is attached to the wrong iomux controller in
+ * the upstream dts file. This can be removed once we pull in the
+ * corresponding fix from the upstream dts files.
+ */
+&wdog1 {
+ pinctrl-0 = <&pinctrl_wdog_lpsr>;
+};
+
+&iomuxc_lpsr {
+ pinctrl_wdog_lpsr: wdoggrp {
+ fsl,pins = <
+ MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x74
+ >;
+ };
+};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ba5a9c445..0e3c7de3d 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -39,6 +39,7 @@ config ARCH_TEXT_BASE
default 0x4fc00000 if MACH_UDOO
default 0x4fc00000 if MACH_VARISCITE_MX6
default 0x4fc00000 if MACH_PHYTEC_SOM_IMX6
+ default 0x9fc00000 if MACH_WARP7
config ARCH_IMX_IMXIMAGE
bool
@@ -351,6 +352,10 @@ config MACH_CM_FX6
bool "CM FX6"
select ARCH_IMX6
+config MACH_WARP7
+ bool "NXP i.MX7: element 14 WaRP7 Board"
+ select ARCH_IMX7
+
config MACH_VF610_TWR
bool "Freescale VF610 Tower Board"
select ARCH_VF610
diff --git a/images/Makefile.imx b/images/Makefile.imx
index eba6048c6..84f6652ad 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -409,6 +409,11 @@ CFG_start_imx6dl_eltec_hipercam.pblx.imximg = $(board)/eltec-hipercam/flash-head
FILE_barebox-eltec-hipercam.img = start_imx6dl_eltec_hipercam.pblx.imximg
image-$(CONFIG_MACH_ELTEC_HIPERCAM) += barebox-eltec-hipercam.img
+pblx-$(CONFIG_MACH_WARP7) += start_imx7s_element14_warp7
+CFG_start_imx7s_element14_warp7.pblx.imximg = $(board)/element14-warp7/flash-header-mx7-warp.imxcfg
+FILE_barebox-element14-imx7s-warp7.img = start_imx7s_element14_warp7.pblx.imximg
+image-$(CONFIG_MACH_WARP7) += barebox-element14-imx7s-warp7.img
+
pblx-$(CONFIG_MACH_VF610_TWR) += start_vf610_twr
CFG_start_vf610_twr.pblx.imximg = $(board)/freescale-vf610-twr/flash-header-vf610-twr.imxcfg
FILE_barebox-vf610-twr.img = start_vf610_twr.pblx.imximg
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] ARM: i.MX7: initialize architected timer
2017-01-19 15:23 [patch v2] i.MX7 support Sascha Hauer
` (2 preceding siblings ...)
2017-01-19 15:23 ` [PATCH 3/5] ARM: i.MX: Add WaRP7 board support Sascha Hauer
@ 2017-01-19 15:23 ` Sascha Hauer
2017-01-19 15:23 ` [PATCH 5/5] regulator: Add pfuze driver Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:23 UTC (permalink / raw)
To: Barebox List
This is the same that U-Boot does. The registers are not documented.
Without this the architected timer on the i.MX7 does not work.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/imx7.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/arch/arm/mach-imx/imx7.c b/arch/arm/mach-imx/imx7.c
index fde66d838..ca094fe83 100644
--- a/arch/arm/mach-imx/imx7.c
+++ b/arch/arm/mach-imx/imx7.c
@@ -46,6 +46,39 @@ void imx7_init_lowlevel(void)
writel(0, aips2 + 0x50);
}
+#define SC_CNTCR 0x0
+#define SC_CNTSR 0x4
+#define SC_CNTCV1 0x8
+#define SC_CNTCV2 0xc
+#define SC_CNTFID0 0x20
+#define SC_CNTFID1 0x24
+#define SC_CNTFID2 0x28
+#define SC_counterid 0xfcc
+
+#define SC_CNTCR_ENABLE (1 << 0)
+#define SC_CNTCR_HDBG (1 << 1)
+#define SC_CNTCR_FREQ0 (1 << 8)
+#define SC_CNTCR_FREQ1 (1 << 9)
+
+static int imx7_timer_init(void)
+{
+ void __iomem *sctr = IOMEM(MX7_SCTR_BASE_ADDR);
+ unsigned long val, freq;
+
+ freq = 8000000;
+ asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
+
+ writel(freq, sctr + SC_CNTFID0);
+
+ /* Enable system counter */
+ val = readl(sctr + SC_CNTCR);
+ val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
+ val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
+ writel(val, sctr + SC_CNTCR);
+
+ return 0;
+}
+
int imx7_init(void)
{
const char *cputypestr;
@@ -53,6 +86,8 @@ int imx7_init(void)
imx7_init_lowlevel();
+ imx7_timer_init();
+
imx7_boot_save_loc();
imx7_silicon_revision = imx7_cpu_revision();
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] regulator: Add pfuze driver
2017-01-19 15:23 [patch v2] i.MX7 support Sascha Hauer
` (3 preceding siblings ...)
2017-01-19 15:23 ` [PATCH 4/5] ARM: i.MX7: initialize architected timer Sascha Hauer
@ 2017-01-19 15:23 ` Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:23 UTC (permalink / raw)
To: Barebox List
This is not yet a regulator driver, only the register map is
exported as /dev/pfuze* so the registers can be accessed for
debugging purposes.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/regulator/Kconfig | 4 ++
drivers/regulator/Makefile | 1 +
drivers/regulator/pfuze.c | 169 +++++++++++++++++++++++++++++++++++++++++++++
include/mfd/pfuze.h | 6 ++
4 files changed, 180 insertions(+)
create mode 100644 drivers/regulator/pfuze.c
create mode 100644 include/mfd/pfuze.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4b4125254..6a6c6d224 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -16,4 +16,8 @@ config REGULATOR_BCM283X
depends on ARCH_BCM283X
default y
+config REGULATOR_PFUZE
+ bool "Freescale PFUZE100/200/3000 regulator driver"
+ depends on I2C
+
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index a8dd9bd05..ff5daf9a7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_REGULATOR) += core.o
obj-$(CONFIG_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_REGULATOR_BCM283X) += bcm2835.o
+obj-$(CONFIG_REGULATOR_PFUZE) += pfuze.o
\ No newline at end of file
diff --git a/drivers/regulator/pfuze.c b/drivers/regulator/pfuze.c
new file mode 100644
index 000000000..2a5fb715c
--- /dev/null
+++ b/drivers/regulator/pfuze.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2017 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <driver.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <malloc.h>
+#include <of.h>
+#include <regmap.h>
+#include <mfd/pfuze.h>
+
+#include <i2c/i2c.h>
+
+#define DRIVERNAME "pfuze"
+
+#define MC13XXX_NUMREGS 0x3f
+
+struct pfuze {
+ struct device_d *dev;
+ struct regmap *map;
+ struct i2c_client *client;
+ int revision;
+};
+
+struct pfuze_devtype {
+ int (*revision)(struct pfuze*);
+};
+
+#define to_pfuze(a) container_of(a, struct pfuze, cdev)
+
+static struct pfuze *pfuze_dev;
+
+static void(*pfuze_init_callback)(struct regmap *map);
+
+int pfuze_register_init_callback(void(*callback)(struct regmap *map))
+{
+ if (pfuze_init_callback)
+ return -EBUSY;
+
+ pfuze_init_callback = callback;
+
+ if (pfuze_dev)
+ pfuze_init_callback(pfuze_dev->map);
+
+ return 0;
+}
+
+static int pfuze_i2c_reg_read(void *ctx, unsigned int reg, unsigned int *val)
+{
+ struct pfuze *pfuze = ctx;
+ u8 buf[1];
+ int ret;
+
+ ret = i2c_read_reg(pfuze->client, reg, buf, 1);
+ *val = buf[0];
+
+ return ret == 1 ? 0 : ret;
+}
+
+static int pfuze_i2c_reg_write(void *ctx, unsigned int reg, unsigned int val)
+{
+ struct pfuze *pfuze = ctx;
+ u8 buf[] = {
+ val & 0xff,
+ };
+ int ret;
+
+ ret = i2c_write_reg(pfuze->client, reg, buf, 1);
+
+ return ret == 1 ? 0 : ret;
+}
+
+static struct regmap_bus regmap_pfuze_i2c_bus = {
+ .reg_write = pfuze_i2c_reg_write,
+ .reg_read = pfuze_i2c_reg_read,
+};
+
+static const struct regmap_config pfuze_regmap_i2c_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 127,
+};
+
+static int __init pfuze_probe(struct device_d *dev)
+{
+ struct pfuze_devtype *devtype;
+ int ret;
+
+ if (pfuze_dev)
+ return -EBUSY;
+
+ ret = dev_get_drvdata(dev, (const void **)&devtype);
+ if (ret)
+ return ret;
+
+ pfuze_dev = xzalloc(sizeof(*pfuze_dev));
+ pfuze_dev->dev = dev;
+
+ pfuze_dev->client = to_i2c_client(dev);
+ pfuze_dev->map = regmap_init(dev, ®map_pfuze_i2c_bus,
+ pfuze_dev, &pfuze_regmap_i2c_config);
+
+ ret = regmap_register_cdev(pfuze_dev->map, NULL);
+ if (ret)
+ return ret;
+
+ if (pfuze_init_callback)
+ pfuze_init_callback(pfuze_dev->map);
+
+ return 0;
+}
+
+static struct pfuze_devtype pfuze100_devtype = {
+};
+
+static struct pfuze_devtype pfuze200_devtype = {
+};
+
+static struct pfuze_devtype pfuze3000_devtype = {
+};
+
+static struct platform_device_id pfuze_ids[] = {
+ { .name = "pfuze100", .driver_data = (ulong)&pfuze100_devtype, },
+ { .name = "pfuze200", .driver_data = (ulong)&pfuze200_devtype, },
+ { .name = "pfuze3000", .driver_data = (ulong)&pfuze3000_devtype, },
+ { }
+};
+
+static __maybe_unused struct of_device_id pfuze_dt_ids[] = {
+ { .compatible = "fsl,pfuze100", .data = &pfuze100_devtype, },
+ { .compatible = "fsl,pfuze200", .data = &pfuze200_devtype, },
+ { .compatible = "fsl,pfuze3000", .data = &pfuze3000_devtype, },
+ { }
+};
+
+static struct driver_d pfuze_i2c_driver = {
+ .name = "pfuze-i2c",
+ .probe = pfuze_probe,
+ .id_table = pfuze_ids,
+ .of_compatible = DRV_OF_COMPAT(pfuze_dt_ids),
+};
+
+static int __init pfuze_init(void)
+{
+ int ret;
+
+ ret = i2c_driver_register(&pfuze_i2c_driver);
+ if (ret)
+ return ret;
+
+ return 0;
+
+}
+late_initcall(pfuze_init);
diff --git a/include/mfd/pfuze.h b/include/mfd/pfuze.h
new file mode 100644
index 000000000..6045ceec0
--- /dev/null
+++ b/include/mfd/pfuze.h
@@ -0,0 +1,6 @@
+#ifndef __INCLUDE_PFUZE_H
+#define __INCLUDE_PFUZE_H
+
+int pfuze_register_init_callback(void(*callback)(struct regmap *map));
+
+#endif /* __INCLUDE_PFUZE_H */
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread