mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* Add i.MX6 SoloX support
@ 2014-11-26 16:29 Sascha Hauer
  2014-11-26 16:29 ` [PATCH 01/11] mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx Sascha Hauer
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

This morning Robert came along with a i.MX6 SoloX Sabresdb board, time
for me to add barebox support for it. This series adds support for the
i.MX6sx SoC and the Sabresdb board. The i.MX6sx turned out to be
good-natured, so here's support for it.

Sascha

----------------------------------------------------------------
Sascha Hauer (11):
      mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx
      mci: imx-esdhc: Add i.MX6sl compatible
      serial: i.MX: Use "per" clk
      net: fec_imx: Add i.MX6sx compatible entry
      imx-usb-loader: Add i.MX6sx support
      pinctrl: Add i.MX6sx compatible entry
      ARM: i.MX: ocotp: Fix MAC address provider for unaligned addresses
      ARM: i.MX: ocotp: Add i.MX6sx compatible entry
      ARM: i.MX: Add i.MX6sx support
      ARM: i.MX: Add i.MX6sx sabresdb support
      ARM: i.MX: update imx_v7_defconfig

 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/freescale-mx6sx-sabresdb/Makefile  |   3 +
 arch/arm/boards/freescale-mx6sx-sabresdb/board.c   | 249 +++++++++++
 .../flash-header-mx6sx-sabresdb.imxcfg             |  75 ++++
 .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  68 +++
 arch/arm/configs/imx_v7_defconfig                  |  12 +-
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/imx6sx-sdb.dts                        |  92 ++++
 arch/arm/dts/imx6sx.dtsi                           |  12 +
 arch/arm/mach-imx/Kconfig                          |   9 +
 arch/arm/mach-imx/Makefile                         |   1 +
 arch/arm/mach-imx/clk-imx6sx.c                     | 481 +++++++++++++++++++++
 arch/arm/mach-imx/imx.c                            |   2 +
 arch/arm/mach-imx/imx6.c                           |   3 +
 arch/arm/mach-imx/include/mach/imx6.h              |   6 +
 arch/arm/mach-imx/ocotp.c                          |  31 +-
 drivers/mci/imx-esdhc.c                            |   7 +-
 drivers/net/fec_imx.c                              |   3 +
 drivers/pinctrl/imx-iomux-v3.c                     |   2 +
 drivers/serial/serial_imx.c                        |   2 +-
 images/Makefile.imx                                |   5 +
 scripts/imx/imx-usb-loader.c                       |   7 +
 22 files changed, 1055 insertions(+), 17 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/Makefile
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/board.c
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
 create mode 100644 arch/arm/dts/imx6sx-sdb.dts
 create mode 100644 arch/arm/dts/imx6sx.dtsi
 create mode 100644 arch/arm/mach-imx/clk-imx6sx.c

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/11] mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 02/11] mci: imx-esdhc: Add i.MX6sl compatible Sascha Hauer
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

The reset default of this register has changed on i.MX6sx. Explicitly
write the value we want to have to make it work on i.MX6sx.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mci/imx-esdhc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 487cd41..5ac58c3 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -474,8 +474,9 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
 	/* Set the initial clock speed */
 	set_sysctl(mci, 400000);
 
-	/* Disable the BRR and BWR bits in IRQSTAT */
-	esdhc_clrbits32(regs + SDHCI_INT_ENABLE, IRQSTATEN_BRR | IRQSTATEN_BWR);
+	writel(IRQSTATEN_CC | IRQSTATEN_TC | IRQSTATEN_CINT | IRQSTATEN_CTOE |
+			IRQSTATEN_CCE | IRQSTATEN_CEBE | IRQSTATEN_CIE | IRQSTATEN_DTOE |
+			IRQSTATEN_DCE | IRQSTATEN_DEBE | IRQSTATEN_DINT, regs + SDHCI_INT_ENABLE);
 
 	/* Put the PROCTL reg back to the default */
 	esdhc_write32(regs + SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 02/11] mci: imx-esdhc: Add i.MX6sl compatible
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
  2014-11-26 16:29 ` [PATCH 01/11] mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 03/11] serial: i.MX: Use "per" clk Sascha Hauer
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Which will also be used for the i.MX6sx.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mci/imx-esdhc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 5ac58c3..239cd37 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -607,6 +607,8 @@ static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = {
 	}, {
 		.compatible = "fsl,imx6q-usdhc",
 	}, {
+		.compatible = "fsl,imx6sl-usdhc",
+	}, {
 		/* sentinel */
 	}
 };
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 03/11] serial: i.MX: Use "per" clk
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
  2014-11-26 16:29 ` [PATCH 01/11] mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx Sascha Hauer
  2014-11-26 16:29 ` [PATCH 02/11] mci: imx-esdhc: Add i.MX6sl compatible Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 04/11] net: fec_imx: Add i.MX6sx compatible entry Sascha Hauer
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Which is the correct clock for the baud rate.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/serial/serial_imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index e379f29..21189cb 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -324,7 +324,7 @@ static int imx_serial_probe(struct device_d *dev)
 	cdev = &priv->cdev;
 	dev->priv = priv;
 
-	priv->clk = clk_get(dev, NULL);
+	priv->clk = clk_get(dev, "per");
 	if (IS_ERR(priv->clk)) {
 		ret = PTR_ERR(priv->clk);
 		goto err_free;
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 04/11] net: fec_imx: Add i.MX6sx compatible entry
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (2 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 03/11] serial: i.MX: Use "per" clk Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 05/11] imx-usb-loader: Add i.MX6sx support Sascha Hauer
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec_imx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 4ed5e8e..a2852ed 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -772,6 +772,9 @@ static __maybe_unused struct of_device_id imx_fec_dt_ids[] = {
 	}, {
 		.compatible = "fsl,imx6q-fec",
 		.data = FEC_TYPE_IMX6,
+	},  {
+		.compatible = "fsl,imx6sx-fec",
+		.data = FEC_TYPE_IMX6,
 	}, {
 		/* sentinel */
 	}
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 05/11] imx-usb-loader: Add i.MX6sx support
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (3 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 04/11] net: fec_imx: Add i.MX6sx compatible entry Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 06/11] pinctrl: Add i.MX6sx compatible entry Sascha Hauer
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Not much to do here, only add the Product ID.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 scripts/imx/imx-usb-loader.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
index c86260c..94b3763 100644
--- a/scripts/imx/imx-usb-loader.c
+++ b/scripts/imx/imx-usb-loader.c
@@ -103,6 +103,13 @@ struct mach_id imx_ids[] = {
 		.header_type = HDR_MX53,
 		.mode = MODE_HID,
 		.max_transfer = 1024,
+	},   {
+		.vid = 0x15a2,
+		.pid = 0x0071,
+		.name = "i.MX6 SoloX",
+		.header_type = HDR_MX53,
+		.mode = MODE_HID,
+		.max_transfer = 1024,
 	}, {
 		.vid = 0x15a2,
 		.pid = 0x0041,
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 06/11] pinctrl: Add i.MX6sx compatible entry
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (4 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 05/11] imx-usb-loader: Add i.MX6sx support Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 07/11] ARM: i.MX: ocotp: Fix MAC address provider for unaligned addresses Sascha Hauer
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

To let the driver probe on i.MX6sx.

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 5dfcde6..62a352b 100644
--- a/drivers/pinctrl/imx-iomux-v3.c
+++ b/drivers/pinctrl/imx-iomux-v3.c
@@ -199,6 +199,8 @@ static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
 	},  {
 		.compatible = "fsl,imx6dl-iomuxc",
 	}, {
+		.compatible = "fsl,imx6sx-iomuxc",
+	}, {
 		/* sentinel */
 	}
 };
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 07/11] ARM: i.MX: ocotp: Fix MAC address provider for unaligned addresses
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (5 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 06/11] pinctrl: Add i.MX6sx compatible entry Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 08/11] ARM: i.MX: ocotp: Add i.MX6sx compatible entry Sascha Hauer
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

The current algorithm assumes the MAC address starts at a 4 byte
aligned address. Unfortunately this is not always the case. On the
i.MX6sx the MAC Address for the second FEC starts at offset 0x632.
The register space for the fuse map has holes, only the 16 byte
aligned words contain data. This means we have to skip the holes.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/ocotp.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 837500f..419821b 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -320,6 +320,14 @@ static struct file_operations imx6_ocotp_ops = {
 	.lseek	= dev_lseek_default,
 };
 
+static uint32_t inc_offset(uint32_t offset)
+{
+	if ((offset & 0x3) == 0x3)
+		return offset + 0xd;
+	else
+		return offset + 1;
+}
+
 static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
 {
 	char mac[6];
@@ -336,21 +344,24 @@ static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
 
 	while (len >= MAC_ADDRESS_PROPLEN) {
 		struct device_node *rnode;
-		uint32_t phandle, offset, value;
+		uint32_t phandle, offset;
 
 		phandle = be32_to_cpup(prop++);
 
 		rnode = of_find_node_by_phandle(phandle);
 		offset = be32_to_cpup(prop++);
 
-		value = readl(base + offset + 0x10);
-		mac[0] = (value >> 8);
-		mac[1] = value;
-		value = readl(base + offset);
-		mac[2] = value >> 24;
-		mac[3] = value >> 16;
-		mac[4] = value >> 8;
-		mac[5] = value;
+		mac[5] = readb(base + offset);
+		offset = inc_offset(offset);
+		mac[4] = readb(base + offset);
+		offset = inc_offset(offset);
+		mac[3] = readb(base + offset);
+		offset = inc_offset(offset);
+		mac[2] = readb(base + offset);
+		offset = inc_offset(offset);
+		mac[1] = readb(base + offset);
+		offset = inc_offset(offset);
+		mac[0] = readb(base + offset);
 
 		of_eth_register_ethaddr(rnode, mac);
 
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 08/11] ARM: i.MX: ocotp: Add i.MX6sx compatible entry
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (6 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 07/11] ARM: i.MX: ocotp: Fix MAC address provider for unaligned addresses Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 09/11] ARM: i.MX: Add i.MX6sx support Sascha Hauer
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/ocotp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 419821b..dd509d6 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -454,6 +454,8 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
 	{
 		.compatible = "fsl,imx6q-ocotp",
 	}, {
+		.compatible = "fsl,imx6sx-ocotp",
+	}, {
 		/* sentinel */
 	}
 };
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 09/11] ARM: i.MX: Add i.MX6sx support
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (7 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 08/11] ARM: i.MX: ocotp: Add i.MX6sx compatible entry Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 16:29 ` [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support Sascha Hauer
  2014-11-26 16:29 ` [PATCH 11/11] ARM: i.MX: update imx_v7_defconfig Sascha Hauer
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Add some cpu type defines and clock support. The clock support
is very different from other i.MX variants, so it's a separate
file, like done in the kernel.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/dts/imx6sx.dtsi              |  12 +
 arch/arm/mach-imx/Kconfig             |   5 +
 arch/arm/mach-imx/Makefile            |   1 +
 arch/arm/mach-imx/clk-imx6sx.c        | 481 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/imx.c               |   2 +
 arch/arm/mach-imx/imx6.c              |   3 +
 arch/arm/mach-imx/include/mach/imx6.h |   6 +
 7 files changed, 510 insertions(+)
 create mode 100644 arch/arm/dts/imx6sx.dtsi
 create mode 100644 arch/arm/mach-imx/clk-imx6sx.c

diff --git a/arch/arm/dts/imx6sx.dtsi b/arch/arm/dts/imx6sx.dtsi
new file mode 100644
index 0000000..5a8ee46
--- /dev/null
+++ b/arch/arm/dts/imx6sx.dtsi
@@ -0,0 +1,12 @@
+/ {
+	aliases {
+		pwm0 = &pwm1;
+		pwm1 = &pwm2;
+		pwm2 = &pwm3;
+		pwm3 = &pwm4;
+		pwm4 = &pwm5;
+		pwm5 = &pwm6;
+		pwm6 = &pwm7;
+		pwm7 = &pwm8;
+	};
+};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index a6263cb..dadbdeb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -177,6 +177,11 @@ config ARCH_IMX6
 	select CPU_V7
 	select PINCTRL_IMX_IOMUX_V3
 
+config ARCH_IMX6SX
+	bool
+	select ARCH_IMX6
+	select COMMON_CLK_OF_PROVIDER
+
 config IMX_MULTI_BOARDS
 	bool "Allow multiple boards to be selected"
 	select HAVE_DEFAULT_ENVIRONMENT_NEW
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index b811c13..048cac5 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o clk-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 clk-imx6.o
 lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
+obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_IMX_OCOTP)	+= ocotp.o
 obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
new file mode 100644
index 0000000..e88e240
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6sx.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2014 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 <dt-bindings/clock/imx6sx-clock.h>
+#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 <linux/clk.h>
+#include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
+
+#include "clk.h"
+#include "common.h"
+
+#define CCDR    0x4
+#define BM_CCM_CCDR_MMDC_CH0_MASK       (0x2 << 16)
+
+static const char *step_sels[]		= { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[]	= { "pll1_sys", "step", };
+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 *ocram_sels[]		= { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
+static const char *gpu_axi_sels[]	= { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", };
+static const char *gpu_core_sels[]	= { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", };
+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 *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_di1_sels[]	= { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", };
+static const char *pcie_axi_sels[]	= { "axi", "ahb", };
+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 *perclk_sels[]	= { "ipg", "osc", };
+static const char *usdhc_sels[]		= { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vid_sels[]		= { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", };
+static const char *uart_sels[]		= { "pll3_80m", "osc", };
+static const char *qspi2_sels[]		= { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", };
+static const char *enet_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", };
+static const char *enet_sels[]		= { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *m4_pre_sels[]	= { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", };
+static const char *m4_sels[]		= { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *eim_slow_sels[]	= { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *ecspi_sels[]		= { "pll3_60m", "osc", };
+static const char *lcdif1_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", };
+static const char *lcdif1_sels[]	= { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *lcdif2_pre_sels[]	= { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", };
+static const char *lcdif2_sels[]	= { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", };
+static const char *display_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", };
+static const char *csi_sels[]		= { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *cko1_sels[]		= {
+	"pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
+	"dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix",
+	"epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div",
+};
+static const char *cko2_sels[]		= {
+	"dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck",
+	"ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core",
+	"lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core",
+	"usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy",
+	"dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial",
+	"spdif", "asrc", "dummy",
+};
+static const char *cko_sels[] = { "cko1", "cko2", };
+static const char *lvds_sels[]	= {
+	"arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div",
+	"dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2",
+};
+static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
+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 struct clk *clks[IMX6SX_CLK_CLK_END];
+static struct clk_onecell_data clk_data;
+
+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 struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ }
+};
+
+static struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static int imx6sx_ccm_probe(struct device_d *dev)
+{
+	void __iomem *base, *anatop_base, *ccm_base;
+	struct device_node *ccm_node = dev->device_node;
+
+	clks[IMX6SX_CLK_DUMMY] = clk_fixed("dummy", 0);
+
+	anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
+	ccm_base = dev_request_mem_region(dev, 0);
+	if (IS_ERR(ccm_base))
+		return PTR_ERR(ccm_base);
+
+	base = anatop_base;
+
+	clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+	clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
+
+	/*                                    type               name    parent_name        base         div_mask */
+	clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS,     "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
+	clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
+	clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll3", "pll3_bypass_src", base + 0x10, 0x3);
+	clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
+	clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV,      "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
+	clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET,    "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
+	clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll7", "pll7_bypass_src", base + 0x20, 0x3);
+
+	clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
+	clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
+	clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
+	clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
+	clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
+	clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
+	clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
+
+	/* Do not bypass PLLs initially */
+	clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]);
+	clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]);
+	clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]);
+	clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]);
+	clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]);
+	clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]);
+	clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]);
+
+	clks[IMX6SX_CLK_PLL1_SYS]      = imx_clk_gate("pll1_sys",      "pll1_bypass", base + 0x00, 13);
+	clks[IMX6SX_CLK_PLL2_BUS]      = imx_clk_gate("pll2_bus",      "pll2_bypass", base + 0x30, 13);
+	clks[IMX6SX_CLK_PLL3_USB_OTG]  = imx_clk_gate("pll3_usb_otg",  "pll3_bypass", base + 0x10, 13);
+	clks[IMX6SX_CLK_PLL4_AUDIO]    = imx_clk_gate("pll4_audio",    "pll4_bypass", base + 0x70, 13);
+	clks[IMX6SX_CLK_PLL5_VIDEO]    = imx_clk_gate("pll5_video",    "pll5_bypass", base + 0xa0, 13);
+	clks[IMX6SX_CLK_PLL6_ENET]     = imx_clk_gate("pll6_enet",     "pll6_bypass", base + 0xe0, 13);
+	clks[IMX6SX_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 may need to enable/disable usbphy's parent
+	 */
+	clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg",  base + 0x10, 20);
+	clks[IMX6SX_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[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
+	clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
+
+	/* FIXME 100Mhz is used for pcie ref for all imx6 pcie, excepted imx6q */
+	clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5);
+	clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+	clks[IMX6SX_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
+			base + 0xe0, 0, 2, clk_enet_ref_table);
+	clks[IMX6SX_CLK_ENET2_REF] = imx_clk_divider_table("enet2_ref", "pll6_enet",
+			base + 0xe0, 2, 2, clk_enet_ref_table);
+	clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
+
+	clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
+	clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21);
+
+	/*                                       name              parent_name     reg           idx */
+	clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
+	clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
+	clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus",     base + 0x100, 2);
+	clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus",     base + 0x100, 3);
+	clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0,  0);
+	clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0,  1);
+	clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0,  2);
+	clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0,  3);
+
+	/*                                                name         parent_name       mult div */
+	clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1,   2);
+	clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1,   4);
+	clks[IMX6SX_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1,   6);
+	clks[IMX6SX_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1,   8);
+	clks[IMX6SX_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1,   2);
+	clks[IMX6SX_CLK_GPT_3M]    = imx_clk_fixed_factor("gpt_3m",    "osc",            1,   8);
+
+	clks[IMX6SX_CLK_PLL4_POST_DIV]  = imx_clk_divider_table("pll4_post_div", "pll4_audio",
+				base + 0x70, 19, 2, post_div_table);
+	clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
+				base + 0x170, 15, 1);
+	clks[IMX6SX_CLK_PLL5_POST_DIV]  = imx_clk_divider_table("pll5_post_div", "pll5_video",
+				base + 0xa0, 19, 2, post_div_table);
+	clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
+				base + 0x170, 30, 2, video_div_table);
+
+	/*                                                name                reg           shift   width   parent_names       num_parents */
+	clks[IMX6SX_CLK_LVDS1_SEL]          = imx_clk_mux("lvds1_sel",        base + 0x160, 0,      5,      lvds_sels,         ARRAY_SIZE(lvds_sels));
+
+	base = ccm_base;
+
+	/*                                                name                reg           shift   width   parent_names       num_parents */
+	clks[IMX6SX_CLK_STEP]               = imx_clk_mux("step",             base + 0xc,   8,      1,      step_sels,         ARRAY_SIZE(step_sels));
+	clks[IMX6SX_CLK_PLL1_SW]            = imx_clk_mux("pll1_sw",          base + 0xc,   2,      1,      pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
+	clks[IMX6SX_CLK_OCRAM_SEL]          = imx_clk_mux("ocram_sel",        base + 0x14,  6,      2,      ocram_sels,        ARRAY_SIZE(ocram_sels));
+	clks[IMX6SX_CLK_PERIPH_PRE]         = imx_clk_mux("periph_pre",       base + 0x18,  18,     2,      periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));
+	clks[IMX6SX_CLK_PERIPH2_PRE]        = imx_clk_mux("periph2_pre",      base + 0x18,  21,     2,      periph2_pre_sels,   ARRAY_SIZE(periph2_pre_sels));
+	clks[IMX6SX_CLK_PERIPH_CLK2_SEL]    = imx_clk_mux("periph_clk2_sel",  base + 0x18,  12,     2,      periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6SX_CLK_PERIPH2_CLK2_SEL]   = imx_clk_mux("periph2_clk2_sel", base + 0x18,  20,     1,      periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+	clks[IMX6SX_CLK_PCIE_AXI_SEL]       = imx_clk_mux("pcie_axi_sel",     base + 0x18,  10,     1,      pcie_axi_sels,     ARRAY_SIZE(pcie_axi_sels));
+	clks[IMX6SX_CLK_GPU_AXI_SEL]        = imx_clk_mux("gpu_axi_sel",      base + 0x18,  8,      2,      gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
+	clks[IMX6SX_CLK_GPU_CORE_SEL]       = imx_clk_mux("gpu_core_sel",     base + 0x18,  4,      2,      gpu_core_sels,     ARRAY_SIZE(gpu_core_sels));
+	clks[IMX6SX_CLK_EIM_SLOW_SEL]       = imx_clk_mux("eim_slow_sel",     base + 0x1c,  29,     2,      eim_slow_sels,     ARRAY_SIZE(eim_slow_sels));
+	clks[IMX6SX_CLK_USDHC1_SEL]         = imx_clk_mux("usdhc1_sel",       base + 0x1c,  16,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC2_SEL]         = imx_clk_mux("usdhc2_sel",       base + 0x1c,  17,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC3_SEL]         = imx_clk_mux("usdhc3_sel",       base + 0x1c,  18,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_USDHC4_SEL]         = imx_clk_mux("usdhc4_sel",       base + 0x1c,  19,     1,      usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SX_CLK_QSPI1_SEL]          = imx_clk_mux_p("qspi1_sel", base + 0x1c,  7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels));
+	clks[IMX6SX_CLK_PERCLK_SEL]         = imx_clk_mux("perclk_sel",       base + 0x1c,  6,      1,      perclk_sels,       ARRAY_SIZE(perclk_sels));
+	clks[IMX6SX_CLK_VID_SEL]            = imx_clk_mux("vid_sel",          base + 0x20,  21,     3,      vid_sels,          ARRAY_SIZE(vid_sels));
+	clks[IMX6SX_CLK_UART_SEL]           = imx_clk_mux("uart_sel",         base + 0x24,  6,      1,      uart_sels,         ARRAY_SIZE(uart_sels));
+	clks[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_mux_p("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels));
+	clks[IMX6SX_CLK_ENET_PRE_SEL]       = imx_clk_mux("enet_pre_sel",     base + 0x34,  15,     3,      enet_pre_sels,     ARRAY_SIZE(enet_pre_sels));
+	clks[IMX6SX_CLK_ENET_SEL]           = imx_clk_mux("enet_sel",         base + 0x34,  9,      3,      enet_sels,         ARRAY_SIZE(enet_sels));
+	clks[IMX6SX_CLK_M4_PRE_SEL]         = imx_clk_mux("m4_pre_sel",       base + 0x34,  6,      3,      m4_pre_sels,       ARRAY_SIZE(m4_pre_sels));
+	clks[IMX6SX_CLK_M4_SEL]             = imx_clk_mux("m4_sel",           base + 0x34,  0,      3,      m4_sels,           ARRAY_SIZE(m4_sels));
+	clks[IMX6SX_CLK_ECSPI_SEL]          = imx_clk_mux("ecspi_sel",        base + 0x38,  18,     1,      ecspi_sels,        ARRAY_SIZE(ecspi_sels));
+	clks[IMX6SX_CLK_LCDIF2_PRE_SEL]     = imx_clk_mux("lcdif2_pre_sel",   base + 0x38,  6,      3,      lcdif2_pre_sels,   ARRAY_SIZE(lcdif2_pre_sels));
+	clks[IMX6SX_CLK_LCDIF2_SEL]         = imx_clk_mux("lcdif2_sel",       base + 0x38,  0,      3,      lcdif2_sels,       ARRAY_SIZE(lcdif2_sels));
+	clks[IMX6SX_CLK_DISPLAY_SEL]        = imx_clk_mux("display_sel",      base + 0x3c,  14,     2,      display_sels,      ARRAY_SIZE(display_sels));
+	clks[IMX6SX_CLK_CSI_SEL]            = imx_clk_mux("csi_sel",          base + 0x3c,  9,      2,      csi_sels,          ARRAY_SIZE(csi_sels));
+	clks[IMX6SX_CLK_CKO1_SEL]           = imx_clk_mux("cko1_sel",         base + 0x60,  0,      4,      cko1_sels,         ARRAY_SIZE(cko1_sels));
+	clks[IMX6SX_CLK_CKO2_SEL]           = imx_clk_mux("cko2_sel",         base + 0x60,  16,     5,      cko2_sels,         ARRAY_SIZE(cko2_sels));
+	clks[IMX6SX_CLK_CKO]                = imx_clk_mux("cko",              base + 0x60,  8,      1,      cko_sels,          ARRAY_SIZE(cko_sels));
+
+	clks[IMX6SX_CLK_LDB_DI1_DIV_SEL]    = imx_clk_mux_p("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
+	clks[IMX6SX_CLK_LDB_DI0_DIV_SEL]    = imx_clk_mux_p("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
+	clks[IMX6SX_CLK_LDB_DI1_SEL]        = imx_clk_mux_p("ldb_di1_sel",     base + 0x2c, 12, 3, ldb_di1_sels,      ARRAY_SIZE(ldb_di1_sels));
+	clks[IMX6SX_CLK_LDB_DI0_SEL]        = imx_clk_mux_p("ldb_di0_sel",     base + 0x2c, 9,  3, ldb_di0_sels,      ARRAY_SIZE(ldb_di0_sels));
+	clks[IMX6SX_CLK_LCDIF1_PRE_SEL]     = imx_clk_mux_p("lcdif1_pre_sel",  base + 0x38, 15, 3, lcdif1_pre_sels,   ARRAY_SIZE(lcdif1_pre_sels));
+	clks[IMX6SX_CLK_LCDIF1_SEL]         = imx_clk_mux_p("lcdif1_sel",      base + 0x38, 9,  3, lcdif1_sels,       ARRAY_SIZE(lcdif1_sels));
+
+	/*                                                    name              parent_name          reg          shift width */
+	clks[IMX6SX_CLK_PERIPH_CLK2]        = imx_clk_divider("periph_clk2",    "periph_clk2_sel",   base + 0x14, 27,   3);
+	clks[IMX6SX_CLK_PERIPH2_CLK2]       = imx_clk_divider("periph2_clk2",   "periph2_clk2_sel",  base + 0x14, 0,    3);
+	clks[IMX6SX_CLK_IPG]                = imx_clk_divider("ipg",            "ahb",               base + 0x14, 8,    2);
+	clks[IMX6SX_CLK_GPU_CORE_PODF]      = imx_clk_divider("gpu_core_podf",  "gpu_core_sel",      base + 0x18, 29,   3);
+	clks[IMX6SX_CLK_GPU_AXI_PODF]       = imx_clk_divider("gpu_axi_podf",   "gpu_axi_sel",       base + 0x18, 26,   3);
+	clks[IMX6SX_CLK_LCDIF1_PODF]        = imx_clk_divider("lcdif1_podf",    "lcdif1_pred",       base + 0x18, 23,   3);
+	clks[IMX6SX_CLK_QSPI1_PODF]         = imx_clk_divider("qspi1_podf",     "qspi1_sel",         base + 0x1c, 26,   3);
+	clks[IMX6SX_CLK_EIM_SLOW_PODF]      = imx_clk_divider("eim_slow_podf",  "eim_slow_sel",      base + 0x1c, 23,   3);
+	clks[IMX6SX_CLK_LCDIF2_PODF]        = imx_clk_divider("lcdif2_podf",    "lcdif2_pred",       base + 0x1c, 20,   3);
+	clks[IMX6SX_CLK_PERCLK]             = imx_clk_divider("perclk",         "perclk_sel",        base + 0x1c, 0,    6);
+	clks[IMX6SX_CLK_VID_PODF]           = imx_clk_divider("vid_podf",       "vid_sel",           base + 0x20, 24,   2);
+	clks[IMX6SX_CLK_USDHC4_PODF]        = imx_clk_divider("usdhc4_podf",    "usdhc4_sel",        base + 0x24, 22,   3);
+	clks[IMX6SX_CLK_USDHC3_PODF]        = imx_clk_divider("usdhc3_podf",    "usdhc3_sel",        base + 0x24, 19,   3);
+	clks[IMX6SX_CLK_USDHC2_PODF]        = imx_clk_divider("usdhc2_podf",    "usdhc2_sel",        base + 0x24, 16,   3);
+	clks[IMX6SX_CLK_USDHC1_PODF]        = imx_clk_divider("usdhc1_podf",    "usdhc1_sel",        base + 0x24, 11,   3);
+	clks[IMX6SX_CLK_UART_PODF]          = imx_clk_divider("uart_podf",      "uart_sel",          base + 0x24, 0,    6);
+	clks[IMX6SX_CLK_QSPI2_PRED]         = imx_clk_divider("qspi2_pred",     "qspi2_sel",         base + 0x2c, 18,   3);
+	clks[IMX6SX_CLK_QSPI2_PODF]         = imx_clk_divider("qspi2_podf",     "qspi2_pred",        base + 0x2c, 21,   6);
+	clks[IMX6SX_CLK_ENET_PODF]          = imx_clk_divider("enet_podf",      "enet_pre_sel",      base + 0x34, 12,   3);
+	clks[IMX6SX_CLK_M4_PODF]            = imx_clk_divider("m4_podf",        "m4_sel",            base + 0x34, 3,    3);
+	clks[IMX6SX_CLK_ECSPI_PODF]         = imx_clk_divider("ecspi_podf",     "ecspi_sel",         base + 0x38, 19,   6);
+	clks[IMX6SX_CLK_LCDIF1_PRED]        = imx_clk_divider("lcdif1_pred",    "lcdif1_pre_sel",    base + 0x38, 12,   3);
+	clks[IMX6SX_CLK_LCDIF2_PRED]        = imx_clk_divider("lcdif2_pred",    "lcdif2_pre_sel",    base + 0x38, 3,    3);
+	clks[IMX6SX_CLK_DISPLAY_PODF]       = imx_clk_divider("display_podf",   "display_sel",       base + 0x3c, 16,   3);
+	clks[IMX6SX_CLK_CSI_PODF]           = imx_clk_divider("csi_podf",       "csi_sel",           base + 0x3c, 11,   3);
+	clks[IMX6SX_CLK_CKO1_PODF]          = imx_clk_divider("cko1_podf",      "cko1_sel",          base + 0x60, 4,    3);
+	clks[IMX6SX_CLK_CKO2_PODF]          = imx_clk_divider("cko2_podf",      "cko2_sel",          base + 0x60, 21,   3);
+
+	clks[IMX6SX_CLK_LDB_DI0_DIV_3_5]    = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[IMX6SX_CLK_LDB_DI0_DIV_7]      = imx_clk_fixed_factor("ldb_di0_div_7",   "ldb_di0_sel", 1, 7);
+	clks[IMX6SX_CLK_LDB_DI1_DIV_3_5]    = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[IMX6SX_CLK_LDB_DI1_DIV_7]      = imx_clk_fixed_factor("ldb_di1_div_7",   "ldb_di1_sel", 1, 7);
+
+	/*                                               name        reg          shift width busy: reg,   shift parent_names       num_parents */
+	clks[IMX6SX_CLK_PERIPH]       = imx_clk_busy_mux("periph",   base + 0x14, 25,   1,    base + 0x48, 5,    periph_sels,       ARRAY_SIZE(periph_sels));
+	clks[IMX6SX_CLK_PERIPH2]      = imx_clk_busy_mux("periph2",  base + 0x14, 26,   1,    base + 0x48, 3,    periph2_sels,      ARRAY_SIZE(periph2_sels));
+	/*                                                   name             parent_name    reg          shift width busy: reg,   shift */
+	clks[IMX6SX_CLK_OCRAM_PODF]   = imx_clk_busy_divider("ocram_podf",    "ocram_sel",   base + 0x14, 16,   3,    base + 0x48, 0);
+	clks[IMX6SX_CLK_AHB]          = imx_clk_busy_divider("ahb",           "periph",      base + 0x14, 10,   3,    base + 0x48, 1);
+	clks[IMX6SX_CLK_MMDC_PODF]    = imx_clk_busy_divider("mmdc_podf",     "periph2",     base + 0x14, 3,    3,    base + 0x48, 2);
+	clks[IMX6SX_CLK_ARM]          = imx_clk_busy_divider("arm",           "pll1_sw",     base + 0x10, 0,    3,    base + 0x48, 16);
+
+	/*                                            name             parent_name          reg         shift */
+	/* CCGR0 */
+	clks[IMX6SX_CLK_AIPS_TZ1]     = imx_clk_gate2("aips_tz1",      "ahb",               base + 0x68, 0);
+	clks[IMX6SX_CLK_AIPS_TZ2]     = imx_clk_gate2("aips_tz2",      "ahb",               base + 0x68, 2);
+	clks[IMX6SX_CLK_APBH_DMA]     = imx_clk_gate2("apbh_dma",      "usdhc3",            base + 0x68, 4);
+	clks[IMX6SX_CLK_CAAM_MEM]     = imx_clk_gate2("caam_mem",      "ahb",               base + 0x68, 8);
+	clks[IMX6SX_CLK_CAAM_ACLK]    = imx_clk_gate2("caam_aclk",     "ahb",               base + 0x68, 10);
+	clks[IMX6SX_CLK_CAAM_IPG]     = imx_clk_gate2("caam_ipg",      "ipg",               base + 0x68, 12);
+	clks[IMX6SX_CLK_DCIC1]        = imx_clk_gate2("dcic1",         "display_podf",      base + 0x68, 24);
+	clks[IMX6SX_CLK_DCIC2]        = imx_clk_gate2("dcic2",         "display_podf",      base + 0x68, 26);
+	clks[IMX6SX_CLK_AIPS_TZ3]     = imx_clk_gate2("aips_tz3",      "ahb",               base + 0x68, 30);
+
+	/* CCGR1 */
+	clks[IMX6SX_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",        "ecspi_podf",        base + 0x6c, 0);
+	clks[IMX6SX_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_podf",        base + 0x6c, 2);
+	clks[IMX6SX_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_podf",        base + 0x6c, 4);
+	clks[IMX6SX_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_podf",        base + 0x6c, 6);
+	clks[IMX6SX_CLK_ECSPI5]       = imx_clk_gate2("ecspi5",        "ecspi_podf",        base + 0x6c, 8);
+	clks[IMX6SX_CLK_EPIT1]        = imx_clk_gate2("epit1",         "perclk",            base + 0x6c, 12);
+	clks[IMX6SX_CLK_EPIT2]        = imx_clk_gate2("epit2",         "perclk",            base + 0x6c, 14);
+	clks[IMX6SX_CLK_WAKEUP]       = imx_clk_gate2("wakeup",        "ipg",               base + 0x6c, 18);
+	clks[IMX6SX_CLK_GPT_BUS]      = imx_clk_gate2("gpt_bus",       "perclk",            base + 0x6c, 20);
+	clks[IMX6SX_CLK_GPT_SERIAL]   = imx_clk_gate2("gpt_serial",    "perclk",            base + 0x6c, 22);
+	clks[IMX6SX_CLK_GPU]          = imx_clk_gate2("gpu",           "gpu_core_podf",     base + 0x6c, 26);
+
+	/* CCGR2 */
+	clks[IMX6SX_CLK_CSI]          = imx_clk_gate2("csi",           "csi_podf",          base + 0x70, 2);
+	clks[IMX6SX_CLK_I2C1]         = imx_clk_gate2("i2c1",          "perclk",            base + 0x70, 6);
+	clks[IMX6SX_CLK_I2C2]         = imx_clk_gate2("i2c2",          "perclk",            base + 0x70, 8);
+	clks[IMX6SX_CLK_I2C3]         = imx_clk_gate2("i2c3",          "perclk",            base + 0x70, 10);
+	clks[IMX6SX_CLK_OCOTP]        = imx_clk_gate2("ocotp",         "ipg",               base + 0x70, 12);
+	clks[IMX6SX_CLK_IOMUXC]       = imx_clk_gate2("iomuxc",        "lcdif1_podf",       base + 0x70, 14);
+	clks[IMX6SX_CLK_IPMUX1]       = imx_clk_gate2("ipmux1",        "ahb",               base + 0x70, 16);
+	clks[IMX6SX_CLK_IPMUX2]       = imx_clk_gate2("ipmux2",        "ahb",               base + 0x70, 18);
+	clks[IMX6SX_CLK_IPMUX3]       = imx_clk_gate2("ipmux3",        "ahb",               base + 0x70, 20);
+	clks[IMX6SX_CLK_TZASC1]       = imx_clk_gate2("tzasc1",        "mmdc_podf",         base + 0x70, 22);
+	clks[IMX6SX_CLK_LCDIF_APB]    = imx_clk_gate2("lcdif_apb",     "display_podf",      base + 0x70, 28);
+	clks[IMX6SX_CLK_PXP_AXI]      = imx_clk_gate2("pxp_axi",       "display_podf",      base + 0x70, 30);
+
+	/* CCGR3 */
+	clks[IMX6SX_CLK_M4]           = imx_clk_gate2("m4",            "m4_podf",           base + 0x74, 2);
+	clks[IMX6SX_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x74, 4);
+	clks[IMX6SX_CLK_ENET_AHB]     = imx_clk_gate2("enet_ahb",      "enet_sel",          base + 0x74, 4);
+	clks[IMX6SX_CLK_DISPLAY_AXI]  = imx_clk_gate2("display_axi",   "display_podf",      base + 0x74, 6);
+	clks[IMX6SX_CLK_LCDIF2_PIX]   = imx_clk_gate2("lcdif2_pix",    "lcdif2_sel",        base + 0x74, 8);
+	clks[IMX6SX_CLK_LCDIF1_PIX]   = imx_clk_gate2("lcdif1_pix",    "lcdif1_sel",        base + 0x74, 10);
+	clks[IMX6SX_CLK_LDB_DI0]      = imx_clk_gate2("ldb_di0",       "ldb_di0_div_sel",   base + 0x74, 12);
+	clks[IMX6SX_CLK_QSPI1]        = imx_clk_gate2("qspi1",         "qspi1_podf",        base + 0x74, 14);
+	clks[IMX6SX_CLK_MLB]          = imx_clk_gate2("mlb",           "ahb",               base + 0x74, 18);
+	clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast",  "mmdc_podf",         base + 0x74, 20);
+	clks[IMX6SX_CLK_MMDC_P0_IPG]  = imx_clk_gate2("mmdc_p0_ipg",   "ipg",               base + 0x74, 24);
+	clks[IMX6SX_CLK_OCRAM]        = imx_clk_gate2("ocram",         "ocram_podf",        base + 0x74, 28);
+
+	/* CCGR4 */
+	clks[IMX6SX_CLK_PCIE_AXI]     = imx_clk_gate2("pcie_axi",      "display_podf",      base + 0x78, 0);
+	clks[IMX6SX_CLK_QSPI2]        = imx_clk_gate2("qspi2",         "qspi2_podf",        base + 0x78, 10);
+	clks[IMX6SX_CLK_PER1_BCH]     = imx_clk_gate2("per1_bch",      "usdhc3",            base + 0x78, 12);
+	clks[IMX6SX_CLK_PER2_MAIN]    = imx_clk_gate2("per2_main",     "ahb",               base + 0x78, 14);
+	clks[IMX6SX_CLK_PWM1]         = imx_clk_gate2("pwm1",          "perclk",            base + 0x78, 16);
+	clks[IMX6SX_CLK_PWM2]         = imx_clk_gate2("pwm2",          "perclk",            base + 0x78, 18);
+	clks[IMX6SX_CLK_PWM3]         = imx_clk_gate2("pwm3",          "perclk",            base + 0x78, 20);
+	clks[IMX6SX_CLK_PWM4]         = imx_clk_gate2("pwm4",          "perclk",            base + 0x78, 22);
+	clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
+	clks[IMX6SX_CLK_GPMI_BCH]     = imx_clk_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
+	clks[IMX6SX_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "qspi2_podf",        base + 0x78, 28);
+	clks[IMX6SX_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
+
+	/* CCGR5 */
+	clks[IMX6SX_CLK_ROM]          = imx_clk_gate2("rom",           "ahb",               base + 0x7c, 0);
+	clks[IMX6SX_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
+	clks[IMX6SX_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
+	clks[IMX6SX_CLK_UART_IPG]     = imx_clk_gate2("uart_ipg",      "ipg",               base + 0x7c, 24);
+	clks[IMX6SX_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",   "uart_podf",         base + 0x7c, 26);
+	clks[IMX6SX_CLK_SAI1_IPG]     = imx_clk_gate2("sai1_ipg",      "ipg",               base + 0x7c, 28);
+	clks[IMX6SX_CLK_SAI2_IPG]     = imx_clk_gate2("sai2_ipg",      "ipg",               base + 0x7c, 30);
+
+	/* CCGR6 */
+	clks[IMX6SX_CLK_USBOH3]       = imx_clk_gate2("usboh3",        "ipg",               base + 0x80, 0);
+	clks[IMX6SX_CLK_USDHC1]       = imx_clk_gate2("usdhc1",        "usdhc1_podf",       base + 0x80, 2);
+	clks[IMX6SX_CLK_USDHC2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
+	clks[IMX6SX_CLK_USDHC3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
+	clks[IMX6SX_CLK_USDHC4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
+	clks[IMX6SX_CLK_EIM_SLOW]     = imx_clk_gate2("eim_slow",      "eim_slow_podf",     base + 0x80, 10);
+	clks[IMX6SX_CLK_PWM8]         = imx_clk_gate2("pwm8",          "perclk",            base + 0x80, 16);
+	clks[IMX6SX_CLK_VADC]         = imx_clk_gate2("vadc",          "vid_podf",          base + 0x80, 20);
+	clks[IMX6SX_CLK_GIS]          = imx_clk_gate2("gis",           "display_podf",      base + 0x80, 22);
+	clks[IMX6SX_CLK_I2C4]         = imx_clk_gate2("i2c4",          "perclk",            base + 0x80, 24);
+	clks[IMX6SX_CLK_PWM5]         = imx_clk_gate2("pwm5",          "perclk",            base + 0x80, 26);
+	clks[IMX6SX_CLK_PWM6]         = imx_clk_gate2("pwm6",          "perclk",            base + 0x80, 28);
+	clks[IMX6SX_CLK_PWM7]         = imx_clk_gate2("pwm7",          "perclk",            base + 0x80, 30);
+
+	clks[IMX6SX_CLK_CKO1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
+	clks[IMX6SX_CLK_CKO2]         = imx_clk_gate("cko2",           "cko2_podf",         base + 0x60, 24);
+
+	/* 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);
+
+	if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
+		clk_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+		clk_enable(clks[IMX6SX_CLK_USBPHY2_GATE]);
+	}
+
+	return 0;
+};
+
+static int imx6sx_clocks_init(void)
+{
+	if (!of_machine_is_compatible("fsl,imx6sx"))
+		return 0;
+
+	/* Set the default 132MHz for EIM module */
+	clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+	clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000);
+
+	/* set parent clock for LCDIF1 pixel clock */
+	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]);
+	clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]);
+
+	/*
+	 * Init enet system AHB clock, set to 200Mhz
+	 * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
+	 */
+	clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]);
+	clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]);
+	clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000);
+	clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000);
+	clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000);
+
+	/* Set parent clock for vadc */
+	clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]);
+
+	/* Update gpu clock from default 528M to 720M */
+	clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+	clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+
+	return 0;
+}
+coredevice_initcall(imx6sx_clocks_init);
+
+static __maybe_unused struct of_device_id imx6sx_ccm_dt_ids[] = {
+	{
+		.compatible = "fsl,imx6sx-ccm",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d imx6sx_ccm_driver = {
+	.probe	= imx6sx_ccm_probe,
+	.name	= "imx6-ccm",
+	.of_compatible = DRV_OF_COMPAT(imx6sx_ccm_dt_ids),
+};
+
+static int imx6sx_ccm_init(void)
+{
+	return platform_driver_register(&imx6sx_ccm_driver);
+}
+core_initcall(imx6sx_ccm_init);
diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c
index 2166369..374ee35 100644
--- a/arch/arm/mach-imx/imx.c
+++ b/arch/arm/mach-imx/imx.c
@@ -57,6 +57,8 @@ static int imx_soc_from_dt(void)
 		return IMX_CPU_IMX6;
 	if (of_machine_is_compatible("fsl,imx6dl"))
 		return IMX_CPU_IMX6;
+	if (of_machine_is_compatible("fsl,imx6sx"))
+		return IMX_CPU_IMX6;
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index ec5e141..c5cae6e 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -161,6 +161,9 @@ int imx6_init(void)
 	case IMX6_CPUTYPE_IMX6S:
 		cputypestr = "i.MX6 Solo";
 		break;
+	case IMX6_CPUTYPE_IMX6SX:
+		cputypestr = "i.MX6 SoloX";
+		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 1898d81..3b75421 100644
--- a/arch/arm/mach-imx/include/mach/imx6.h
+++ b/arch/arm/mach-imx/include/mach/imx6.h
@@ -11,6 +11,7 @@ void imx6_init_lowlevel(void);
 
 #define IMX6_CPUTYPE_IMX6S	0x161
 #define IMX6_CPUTYPE_IMX6DL	0x261
+#define IMX6_CPUTYPE_IMX6SX	0x462
 #define IMX6_CPUTYPE_IMX6D	0x263
 #define IMX6_CPUTYPE_IMX6Q	0x463
 
@@ -67,4 +68,9 @@ static inline int cpu_is_mx6q(void)
 	return imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q;
 }
 
+static inline int cpu_is_mx6sx(void)
+{
+	return imx6_cpu_type() == IMX6_CPUTYPE_IMX6SX;
+}
+
 #endif /* __MACH_IMX6_H */
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (8 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 09/11] ARM: i.MX: Add i.MX6sx support Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  2014-11-26 17:06   ` Lucas Stach
  2014-11-26 16:29 ` [PATCH 11/11] ARM: i.MX: update imx_v7_defconfig Sascha Hauer
  10 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

This adds support for the Freescale i.MX6sx sabresdb board.

Tested are:

- UART
- The three SD card slots
- USB host
- USB otg (host and device mode)
- FEC (both)

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/freescale-mx6sx-sabresdb/Makefile  |   3 +
 arch/arm/boards/freescale-mx6sx-sabresdb/board.c   | 249 +++++++++++++++++++++
 .../flash-header-mx6sx-sabresdb.imxcfg             |  75 +++++++
 .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  68 ++++++
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/imx6sx-sdb.dts                        |  92 ++++++++
 arch/arm/mach-imx/Kconfig                          |   4 +
 images/Makefile.imx                                |   5 +
 9 files changed, 498 insertions(+)
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/Makefile
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/board.c
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
 create mode 100644 arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
 create mode 100644 arch/arm/dts/imx6sx-sdb.dts

diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index fb257fb..9961ca8 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_MACH_REALQ7)			+= datamodul-edm-qmx6/
 obj-$(CONFIG_MACH_RPI)				+= raspberry-pi/
 obj-$(CONFIG_MACH_SABRELITE)			+= freescale-mx6-sabrelite/
 obj-$(CONFIG_MACH_SABRESD)			+= freescale-mx6-sabresd/
+obj-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB)	+= freescale-mx6sx-sabresdb/
 obj-$(CONFIG_MACH_SAMA5D3XEK)			+= sama5d3xek/
 obj-$(CONFIG_MACH_SAMA5D3_XPLAINED)		+= sama5d3_xplained/
 obj-$(CONFIG_MACH_SAMA5D4_XPLAINED)		+= sama5d4_xplained/
diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/Makefile b/arch/arm/boards/freescale-mx6sx-sabresdb/Makefile
new file mode 100644
index 0000000..cc4078f
--- /dev/null
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/Makefile
@@ -0,0 +1,3 @@
+obj-y += board.o flash-header-mx6sx-sabresdb.dcd.o
+extra-y += flash-header-mx6sx-sabresdb.dcd.S flash-header-mx6sx-sabresdb.dcd
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/board.c b/arch/arm/boards/freescale-mx6sx-sabresdb/board.c
new file mode 100644
index 0000000..c21b43d
--- /dev/null
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/board.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+#define pr_fmt(fmt) "imx6sx-sdb: " fmt
+
+#include <environment.h>
+#include <partition.h>
+#include <common.h>
+#include <sizes.h>
+#include <gpio.h>
+#include <init.h>
+#include <io.h>
+#include <mfd/imx6q-iomuxc-gpr.h>
+#include <generated/mach-types.h>
+#include <linux/clk.h>
+#include <i2c/i2c.h>
+
+#include <asm/armlinux.h>
+
+#include <mach/devices-imx6.h>
+#include <mach/imx6-regs.h>
+#include <mach/iomux-mx6.h>
+#include <mach/generic.h>
+#include <mach/imx6.h>
+#include <mach/bbu.h>
+
+#define PFUZE100_DEVICEID	0x0
+#define PFUZE100_REVID		0x3
+#define PFUZE100_FABID		0x4
+
+#define PFUZE100_SW1ABVOL	0x20
+#define PFUZE100_SW1ABSTBY	0x21
+#define PFUZE100_SW1ABCONF	0x24
+#define PFUZE100_SW1CVOL	0x2e
+#define PFUZE100_SW1CSTBY	0x2f
+#define PFUZE100_SW1CCONF	0x32
+#define PFUZE100_SW1ABC_SETP(x)	((x - 3000) / 250)
+#define PFUZE100_VGEN5CTL	0x70
+
+/* set all switches APS in normal and PFM mode in standby */
+static int imx6sx_sdb_setup_pmic_mode(struct i2c_client *client, int chip)
+{
+	unsigned char offset, i, switch_num, value;
+
+	if (!chip) {
+		/* pfuze100 */
+		switch_num = 6;
+		offset = 0x31;
+	} else {
+		/* pfuze200 */
+		switch_num = 4;
+		offset = 0x38;
+	}
+
+	value = 0xc;
+	if (i2c_write_reg(client, 0x23, &value, 1) < 0)
+		return -EIO;
+
+	for (i = 0; i < switch_num - 1; i++)
+		if (i2c_write_reg(client, offset + i * 7, &value, 1) < 0)
+			return -EIO;
+
+	return 0;
+}
+
+static int imx6sx_sdb_setup_pmic_voltages(void)
+{
+	unsigned char value, rev_id = 0;
+	struct i2c_adapter *adapter = NULL;
+	struct i2c_client client;
+	int addr = -1, bus = 0;
+
+	if (!of_machine_is_compatible("fsl,imx6sx-sdb"))
+		return 0;
+
+	/* I2C2 bus (2-1 = 1 in barebox numbering) */
+	bus = 0;
+
+	/* PFUZE100 device address is 0x08 */
+	addr = 0x08;
+
+	adapter = i2c_get_adapter(bus);
+	if (!adapter)
+		return -ENODEV;
+
+	client.adapter = adapter;
+	client.addr = addr;
+
+	if (i2c_read_reg(&client, PFUZE100_DEVICEID, &value, 1) < 0)
+		goto err_out;
+	if (i2c_read_reg(&client, PFUZE100_REVID, &rev_id, 1) < 0)
+		goto err_out;
+
+	pr_info("Found PFUZE100! deviceid 0x%x, revid 0x%x\n", value, rev_id);
+
+	if (imx6sx_sdb_setup_pmic_mode(&client, value & 0xf))
+		goto err_out;
+
+	/* set SW1AB standby volatage 0.975V */
+	if (i2c_read_reg(&client, PFUZE100_SW1ABSTBY, &value, 1) < 0)
+		goto err_out;
+
+	value &= ~0x3f;
+	value |= PFUZE100_SW1ABC_SETP(9750);
+	if (i2c_write_reg(&client, PFUZE100_SW1ABSTBY, &value, 1) < 0)
+		goto err_out;
+
+	/* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
+	if (i2c_read_reg(&client, PFUZE100_SW1ABCONF, &value, 1) < 0)
+		goto err_out;
+
+	value &= ~0xc0;
+	value |= 0x40;
+	if (i2c_write_reg(&client, PFUZE100_SW1ABCONF, &value, 1) < 0)
+		goto err_out;
+
+
+	/* set SW1C standby volatage 0.975V */
+	if (i2c_read_reg(&client, PFUZE100_SW1CSTBY, &value, 1) < 0)
+		goto err_out;
+
+	value &= ~0x3f;
+	value |= PFUZE100_SW1ABC_SETP(9750);
+	if (i2c_write_reg(&client, PFUZE100_SW1CSTBY, &value, 1) < 0)
+		goto err_out;
+
+
+	/* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */
+	if (i2c_read_reg(&client, PFUZE100_SW1CCONF, &value, 1) < 0)
+		goto err_out;
+
+	value &= ~0xc0;
+	value |= 0x40;
+	if (i2c_write_reg(&client, PFUZE100_SW1CCONF, &value, 1) < 0)
+		goto err_out;
+
+	/* Enable power of VGEN5 3V3, needed for SD3 */
+	if (i2c_read_reg(&client, PFUZE100_VGEN5CTL, &value, 1) < 0)
+		goto err_out;
+
+	value &= ~0x1F;
+	value |= 0x1F;
+	if (i2c_write_reg(&client, PFUZE100_VGEN5CTL, &value, 1) < 0)
+		goto err_out;
+
+	return 0;
+
+err_out:
+	pr_err("Setting up PMIC failed\n");
+
+	return -EIO;
+}
+fs_initcall(imx6sx_sdb_setup_pmic_voltages);
+
+int ar8031_phy_fixup(struct phy_device *phydev)
+{
+	/*
+	 * Enable 1.8V(SEL_1P5_1P8_POS_REG) on
+	 * Phy control debug reg 0
+	 */
+	phy_write(phydev, 0x1d, 0x1f);
+	phy_write(phydev, 0x1e, 0x8);
+
+	/* rgmii tx clock delay enable */
+	phy_write(phydev, 0x1d, 0x05);
+	phy_write(phydev, 0x1e, 0x100);
+
+	return 0;
+}
+
+#define PHY_ID_AR8031	0x004dd074
+#define AR_PHY_ID_MASK	0xffffffff
+
+static int imx6sx_sdb_setup_fec(void)
+{
+	void __iomem *gprbase = (void *)MX6_IOMUXC_BASE_ADDR + 0x4000;
+	uint32_t val;
+	struct clk *clk;
+
+	phy_register_fixup_for_uid(PHY_ID_AR8031, AR_PHY_ID_MASK,
+			ar8031_phy_fixup);
+
+	/* Active high for ncp692 */
+	gpio_direction_output(IMX_GPIO_NR(4, 16), 1);
+
+	clk = clk_lookup("enet_ptp_25m");
+	if (IS_ERR(clk))
+		goto err;
+
+	clk_enable(clk);
+
+	clk = clk_lookup("enet_ref");
+	if (IS_ERR(clk))
+		goto err;
+	clk_enable(clk);
+
+	clk = clk_lookup("enet2_ref_125m");
+	if (IS_ERR(clk))
+		goto err;
+
+	clk_enable(clk);
+
+	val = readl(gprbase + IOMUXC_GPR1);
+	/* Use 125M anatop loopback REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/
+	val &= ~(1 << 13);
+	val &= ~(1 << 17);
+	/* Use 125M anatop loopback REF_CLK1 for ENET2, clear gpr1[14], gpr1[18]*/
+	val &= ~(1 << 14);
+	val &= ~(1 << 18);
+	writel(val, gprbase + IOMUXC_GPR1);
+
+	/* Enable the ENET power, active low */
+	gpio_direction_output(IMX_GPIO_NR(2, 6), 0);
+
+	/* Reset AR8031 PHY */
+	gpio_direction_output(IMX_GPIO_NR(2, 7), 0);
+	udelay(500);
+	gpio_set_value(IMX_GPIO_NR(2, 7), 1);
+
+	return 0;
+err:
+	pr_err("Setting up DFEC\n");
+
+	return -EIO;
+}
+
+static int imx6sx_sdb_coredevices_init(void)
+{
+	if (!of_machine_is_compatible("fsl,imx6sx-sdb"))
+		return 0;
+
+	imx6sx_sdb_setup_fec();
+
+	imx6_bbu_internal_mmc_register_handler("sd", "/dev/mmc3",
+			BBU_HANDLER_FLAG_DEFAULT);
+
+	return 0;
+}
+console_initcall(imx6sx_sdb_coredevices_init);
diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg b/arch/arm/boards/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
new file mode 100644
index 0000000..a96b3e7
--- /dev/null
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
@@ -0,0 +1,75 @@
+loadaddr 0x80000000
+soc imx6
+dcdofs 0x400
+
+wm 32 0x020c4068 0xffffffff
+wm 32 0x020c406c 0xffffffff
+wm 32 0x020c4070 0xffffffff
+wm 32 0x020c4074 0xffffffff
+wm 32 0x020c4078 0xffffffff
+wm 32 0x020c407c 0xffffffff
+wm 32 0x020c4080 0xffffffff
+wm 32 0x020c4084 0xffffffff
+
+wm 32 0x020e0618 0x000c0000
+wm 32 0x020e05fc 0x00000000
+wm 32 0x020e032c 0x00000030
+
+wm 32 0x020e0300 0x00000030
+wm 32 0x020e02fc 0x00000030
+wm 32 0x020e05f4 0x00000030
+wm 32 0x020e0340 0x00000030
+
+wm 32 0x020e0320 0x00000000
+wm 32 0x020e0310 0x00000030
+wm 32 0x020e0314 0x00000030
+wm 32 0x020e0614 0x00000030
+wm 32 0x020e05f8 0x00020000
+wm 32 0x020e0330 0x00000030
+wm 32 0x020e0334 0x00000030
+wm 32 0x020e0338 0x00000030
+wm 32 0x020e033c 0x00000030
+wm 32 0x020e0608 0x00020000
+wm 32 0x020e060c 0x00000030
+wm 32 0x020e0610 0x00000030
+wm 32 0x020e061c 0x00000030
+wm 32 0x020e0620 0x00000030
+wm 32 0x020e02ec 0x00000030
+wm 32 0x020e02f0 0x00000030
+wm 32 0x020e02f4 0x00000030
+wm 32 0x020e02f8 0x00000030
+wm 32 0x021b0800 0xa1390003
+wm 32 0x021b080c 0x00270025
+wm 32 0x021b0810 0x001b001e
+wm 32 0x021b083c 0x4144013c
+wm 32 0x021b0840 0x01300128
+wm 32 0x021b0848 0x4044464a
+wm 32 0x021b0850 0x3a383c34
+wm 32 0x021b081c 0x33333333
+wm 32 0x021b0820 0x33333333
+wm 32 0x021b0824 0x33333333
+wm 32 0x021b0828 0x33333333
+wm 32 0x021b08b8 0x00000800
+wm 32 0x021b0004 0x0002002d
+wm 32 0x021b0008 0x00333030
+wm 32 0x021b000c 0x676b52f3
+wm 32 0x021b0010 0xb66d8b63
+wm 32 0x021b0014 0x01ff00db
+wm 32 0x021b0018 0x00011740
+wm 32 0x021b001c 0x00008000
+wm 32 0x021b002c 0x000026d2
+wm 32 0x021b0030 0x006b1023
+wm 32 0x021b0040 0x0000005f
+wm 32 0x021b0000 0x84190000
+wm 32 0x021b001c 0x04008032
+wm 32 0x021b001c 0x00008033
+wm 32 0x021b001c 0x00068031
+wm 32 0x021b001c 0x05208030
+wm 32 0x021b001c 0x04008040
+wm 32 0x021b0020 0x00000800
+wm 32 0x021b0818 0x00011117
+wm 32 0x021b001c 0x00000000
+wm 32 0x021b083c 0x41400138
+wm 32 0x021b0840 0x012c011c
+wm 32 0x021b0848 0x3c3c4044
+wm 32 0x021b0850 0x34343638
diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
new file mode 100644
index 0000000..33f3700
--- /dev/null
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 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 <debug_ll.h>
+#include <common.h>
+#include <sizes.h>
+#include <mach/generic.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+
+static inline void setup_uart(void)
+{
+	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
+	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
+	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
+
+	writel(0xffffffff, ccmbase + 0x68);
+	writel(0xffffffff, ccmbase + 0x6c);
+	writel(0xffffffff, ccmbase + 0x70);
+	writel(0xffffffff, ccmbase + 0x74);
+	writel(0xffffffff, ccmbase + 0x78);
+	writel(0xffffffff, ccmbase + 0x7c);
+	writel(0xffffffff, ccmbase + 0x80);
+
+	writel(0x0, iomuxbase + 0x24);
+	writel(0x1b0b1, iomuxbase + 0x036C);
+	writel(0x0, iomuxbase + 0x28);
+	writel(0x1b0b1, iomuxbase + 0x0370);
+
+	writel(0x00000000, uartbase + 0x80);
+	writel(0x00004027, uartbase + 0x84);
+	writel(0x00000784, uartbase + 0x88);
+	writel(0x00000a81, uartbase + 0x90);
+	writel(0x0000002b, uartbase + 0x9c);
+	writel(0x0001b0b0, uartbase + 0xb0);
+	writel(0x0000047f, uartbase + 0xa4);
+	writel(0x0000c34f, uartbase + 0xa8);
+	writel(0x00000001, uartbase + 0x80);
+
+	putc_ll('>');
+}
+
+extern char __dtb_imx6sx_sdb_start[];
+
+ENTRY_FUNCTION(start_imx6sx_sabresdb, r0, r1, r2)
+{
+	void *fdt;
+
+	imx6_cpu_lowlevel_init();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
+	fdt = __dtb_imx6sx_sdb_start - get_runtime_offset();
+
+	barebox_arm_entry(0x80000000, SZ_1G, fdt);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9404474..9981073 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -35,6 +35,7 @@ pbl-dtb-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o
 pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o
 pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o
 pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o
+pbl-dtb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += imx6sx-sdb.dtb.o
 pbl-dtb-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += socfpga_cyclone5_socrates.dtb.o
 pbl-dtb-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += socfpga_cyclone5_sockit.dtb.o
 pbl-dtb-$(CONFIG_MACH_SOLIDRUN_CUBOX) += dove-cubox-bb.dtb.o
diff --git a/arch/arm/dts/imx6sx-sdb.dts b/arch/arm/dts/imx6sx-sdb.dts
new file mode 100644
index 0000000..fbf098b
--- /dev/null
+++ b/arch/arm/dts/imx6sx-sdb.dts
@@ -0,0 +1,92 @@
+/*
+ * 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/imx6sx-sdb.dts>
+#include "imx6sx.dtsi"
+
+/ {
+	chosen {
+		environment@0 {
+			compatible = "barebox,environment";
+			device-path = &usdhc4, "partname:barebox-environment";
+		};
+	};
+};
+
+&fec1 {
+	phy-handle = <&phy1>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		phy1: phy@1 {
+			reg = <1>;
+		};
+
+		phy2: phy@2 {
+			reg = <2>;
+		};
+	};
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rgmii";
+	status = "okay";
+	phy-handle = <&phy2>;
+};
+
+&ocotp {
+	barebox,provide-mac-address = <&fec1 0x620 &fec2 0x632>;
+};
+
+&usdhc4 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	partition@0 {
+		label = "barebox-environment";
+		reg = <0x80000 0x20000>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	imx6x-sdb {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16	0x17059 /* PERI_3V3 */
+				MX6SX_PAD_ENET2_COL__GPIO2_IO_6		0x17059 /* ENET PHY Power */
+				MX6SX_PAD_ENET2_CRS__GPIO2_IO_7		0x17059 /* AR8031 PHY Reset. */
+				MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M	0x17059 /* Phy 25M Clock */
+			>;
+		};
+
+		pinctrl_enet2: enet2grp {
+			fsl,pins = <
+				MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC	0xa0b1
+				MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0	0xa0b1
+				MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1	0xa0b1
+				MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2	0xa0b1
+				MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3	0xa0b1
+				MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN	0xa0b1
+				MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK	0x3081
+				MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0	0x3081
+				MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1	0x3081
+				MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2	0x3081
+				MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3	0x3081
+				MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN	0x3081
+			>;
+		};
+	};
+};
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index dadbdeb..1ba448f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -301,6 +301,10 @@ config MACH_SABRESD
 	bool "Freescale i.MX6 SabreSD"
 	select ARCH_IMX6
 
+config MACH_FREESCALE_IMX6SX_SABRESDB
+	bool "Freescale i.MX6sx SabreSDB"
+	select ARCH_IMX6SX
+
 config MACH_NITROGEN6X
 	bool "BoundaryDevices Nitrogen6x"
 	select ARCH_IMX6
diff --git a/images/Makefile.imx b/images/Makefile.imx
index 2b85560..fd7f725 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -155,6 +155,11 @@ CFG_start_imx6q_sabresd.pblx.imximg = $(board)/freescale-mx6-sabresd/flash-heade
 FILE_barebox-freescale-imx6q-sabresd.img = start_imx6q_sabresd.pblx.imximg
 image-$(CONFIG_MACH_SABRESD) += barebox-freescale-imx6q-sabresd.img
 
+pblx-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += start_imx6sx_sabresdb
+CFG_start_imx6sx_sabresdb.pblx.imximg = $(board)/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
+FILE_barebox-freescale-imx6sx-sabresdb.img = start_imx6sx_sabresdb.pblx.imximg
+image-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += barebox-freescale-imx6sx-sabresdb.img
+
 pblx-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_imx6dl_hummingboard
 CFG_start_imx6dl_hummingboard.pblx.imximg = $(board)/solidrun-microsom/flash-header-solidrun-hummingboard.imxcfg
 FILE_barebox-solidrun-imx6dl-hummingboard.img = start_imx6dl_hummingboard.pblx.imximg
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 11/11] ARM: i.MX: update imx_v7_defconfig
  2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
                   ` (9 preceding siblings ...)
  2014-11-26 16:29 ` [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support Sascha Hauer
@ 2014-11-26 16:29 ` Sascha Hauer
  10 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-26 16:29 UTC (permalink / raw)
  To: barebox

Enable support for the i.MX6sx sabresdb and the KaRo Tx6x.
The sabresdb needs regulator support, so enable this aswell.
Also enable usbserial support.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/configs/imx_v7_defconfig | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig
index 7076ecd..a921c90 100644
--- a/arch/arm/configs/imx_v7_defconfig
+++ b/arch/arm/configs/imx_v7_defconfig
@@ -13,8 +13,10 @@ CONFIG_MACH_GUF_SANTARO=y
 CONFIG_MACH_REALQ7=y
 CONFIG_MACH_GK802=y
 CONFIG_MACH_TQMA6X=y
+CONFIG_MACH_TX6X=y
 CONFIG_MACH_SABRELITE=y
 CONFIG_MACH_SABRESD=y
+CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB=y
 CONFIG_MACH_NITROGEN6X=y
 CONFIG_MACH_SOLIDRUN_MICROSOM=y
 CONFIG_MACH_EMBEST_RIOTBOARD=y
@@ -46,6 +48,7 @@ CONFIG_LONGHELP=y
 CONFIG_CMD_IOMEM=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_BOOTM_SHOW_TYPE=y
 CONFIG_CMD_BOOTM_VERBOSE=y
 CONFIG_CMD_BOOTM_INITRD=y
@@ -94,6 +97,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_LED=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_LED_TRIGGER=y
+CONFIG_CMD_USBGADGET=y
 CONFIG_CMD_WD=y
 CONFIG_CMD_BAREBOX_UPDATE=y
 CONFIG_CMD_OF_NODE=y
@@ -103,7 +107,6 @@ CONFIG_CMD_TIME=y
 CONFIG_NET=y
 CONFIG_NET_NETCONSOLE=y
 CONFIG_NET_RESOLV=y
-CONFIG_OFDEVICE=y
 CONFIG_OF_BAREBOX_DRIVERS=y
 CONFIG_DRIVER_NET_FEC_IMX=y
 CONFIG_AT803X_PHY=y
@@ -111,9 +114,6 @@ CONFIG_MICREL_PHY=y
 CONFIG_NET_USB=y
 CONFIG_NET_USB_ASIX=y
 CONFIG_NET_USB_SMSC95XX=y
-CONFIG_DRIVER_SPI_IMX=y
-CONFIG_I2C=y
-CONFIG_I2C_IMX=y
 CONFIG_MTD=y
 CONFIG_MTD_RAW_DEVICE=y
 CONFIG_MTD_DATAFLASH=y
@@ -137,6 +137,7 @@ CONFIG_USB_ULPI=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DFU=y
+CONFIG_USB_GADGET_SERIAL=y
 CONFIG_VIDEO=y
 CONFIG_DRIVER_VIDEO_IMX_IPUV3=y
 CONFIG_DRIVER_VIDEO_IMX_IPUV3_LVDS=y
@@ -146,7 +147,6 @@ CONFIG_DRIVER_VIDEO_EDID=y
 CONFIG_MCI=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_IMX_ESDHC=y
-CONFIG_MFD_MC13XXX=y
 CONFIG_MFD_MC34704=y
 CONFIG_MFD_MC9SDZ60=y
 CONFIG_MFD_STMPE=y
@@ -162,6 +162,8 @@ CONFIG_PWM=y
 CONFIG_PWM_IMX=y
 CONFIG_MXS_APBH_DMA=y
 CONFIG_GPIO_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_TFTP=y
 CONFIG_FS_NFS=y
-- 
2.1.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support
  2014-11-26 16:29 ` [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support Sascha Hauer
@ 2014-11-26 17:06   ` Lucas Stach
  2014-11-27 10:26     ` Sascha Hauer
  0 siblings, 1 reply; 14+ messages in thread
From: Lucas Stach @ 2014-11-26 17:06 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Am Mittwoch, den 26.11.2014, 17:29 +0100 schrieb Sascha Hauer:
> This adds support for the Freescale i.MX6sx sabresdb board.
> 
> Tested are:
> 
> - UART
> - The three SD card slots
> - USB host
> - USB otg (host and device mode)
> - FEC (both)
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---

[...]

> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index dadbdeb..1ba448f 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -301,6 +301,10 @@ config MACH_SABRESD
>  	bool "Freescale i.MX6 SabreSD"
>  	select ARCH_IMX6
>  
> +config MACH_FREESCALE_IMX6SX_SABRESDB
> +	bool "Freescale i.MX6sx SabreSDB"
> +	select ARCH_IMX6SX
> +

It seems you need to bash the PFUZE in the board startup code to get the
board to operate correctly. So this should select both I2C and I2C_IMX.

>  config MACH_NITROGEN6X
>  	bool "BoundaryDevices Nitrogen6x"
>  	select ARCH_IMX6
> diff --git a/images/Makefile.imx b/images/Makefile.imx
> index 2b85560..fd7f725 100644
> --- a/images/Makefile.imx
> +++ b/images/Makefile.imx
> @@ -155,6 +155,11 @@ CFG_start_imx6q_sabresd.pblx.imximg = $(board)/freescale-mx6-sabresd/flash-heade
>  FILE_barebox-freescale-imx6q-sabresd.img = start_imx6q_sabresd.pblx.imximg
>  image-$(CONFIG_MACH_SABRESD) += barebox-freescale-imx6q-sabresd.img
>  
> +pblx-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += start_imx6sx_sabresdb
> +CFG_start_imx6sx_sabresdb.pblx.imximg = $(board)/freescale-mx6sx-sabresdb/flash-header-mx6sx-sabresdb.imxcfg
> +FILE_barebox-freescale-imx6sx-sabresdb.img = start_imx6sx_sabresdb.pblx.imximg
> +image-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += barebox-freescale-imx6sx-sabresdb.img
> +
>  pblx-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += start_imx6dl_hummingboard
>  CFG_start_imx6dl_hummingboard.pblx.imximg = $(board)/solidrun-microsom/flash-header-solidrun-hummingboard.imxcfg
>  FILE_barebox-solidrun-imx6dl-hummingboard.img = start_imx6dl_hummingboard.pblx.imximg

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support
  2014-11-26 17:06   ` Lucas Stach
@ 2014-11-27 10:26     ` Sascha Hauer
  0 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2014-11-27 10:26 UTC (permalink / raw)
  To: Lucas Stach; +Cc: barebox

On Wed, Nov 26, 2014 at 06:06:09PM +0100, Lucas Stach wrote:
> Am Mittwoch, den 26.11.2014, 17:29 +0100 schrieb Sascha Hauer:
> > This adds support for the Freescale i.MX6sx sabresdb board.
> > 
> > Tested are:
> > 
> > - UART
> > - The three SD card slots
> > - USB host
> > - USB otg (host and device mode)
> > - FEC (both)
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> 
> [...]
> 
> > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> > index dadbdeb..1ba448f 100644
> > --- a/arch/arm/mach-imx/Kconfig
> > +++ b/arch/arm/mach-imx/Kconfig
> > @@ -301,6 +301,10 @@ config MACH_SABRESD
> >  	bool "Freescale i.MX6 SabreSD"
> >  	select ARCH_IMX6
> >  
> > +config MACH_FREESCALE_IMX6SX_SABRESDB
> > +	bool "Freescale i.MX6sx SabreSDB"
> > +	select ARCH_IMX6SX
> > +
> 
> It seems you need to bash the PFUZE in the board startup code to get the
> board to operate correctly. So this should select both I2C and I2C_IMX.

Oh, right. Did that.

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	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-11-27 10:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-26 16:29 Add i.MX6 SoloX support Sascha Hauer
2014-11-26 16:29 ` [PATCH 01/11] mci: imx-esdhc: Fix Interrupt enable register for i.MX6sx Sascha Hauer
2014-11-26 16:29 ` [PATCH 02/11] mci: imx-esdhc: Add i.MX6sl compatible Sascha Hauer
2014-11-26 16:29 ` [PATCH 03/11] serial: i.MX: Use "per" clk Sascha Hauer
2014-11-26 16:29 ` [PATCH 04/11] net: fec_imx: Add i.MX6sx compatible entry Sascha Hauer
2014-11-26 16:29 ` [PATCH 05/11] imx-usb-loader: Add i.MX6sx support Sascha Hauer
2014-11-26 16:29 ` [PATCH 06/11] pinctrl: Add i.MX6sx compatible entry Sascha Hauer
2014-11-26 16:29 ` [PATCH 07/11] ARM: i.MX: ocotp: Fix MAC address provider for unaligned addresses Sascha Hauer
2014-11-26 16:29 ` [PATCH 08/11] ARM: i.MX: ocotp: Add i.MX6sx compatible entry Sascha Hauer
2014-11-26 16:29 ` [PATCH 09/11] ARM: i.MX: Add i.MX6sx support Sascha Hauer
2014-11-26 16:29 ` [PATCH 10/11] ARM: i.MX: Add i.MX6sx sabresdb support Sascha Hauer
2014-11-26 17:06   ` Lucas Stach
2014-11-27 10:26     ` Sascha Hauer
2014-11-26 16:29 ` [PATCH 11/11] ARM: i.MX: update imx_v7_defconfig Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox