All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor
@ 2016-12-01  1:06 Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data Marek Vasut
                   ` (13 more replies)
  0 siblings, 14 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Add function which allows fetching the default FCR register setting
from platform data for DM , while retaining old behavior for non-DM
by returning UART_FCRVAL.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
---
V2: If CONFIG_DM_SERIAL and DEBUG_UART are enabled, the ns16550_getfcr()
    can be invoked with NULL plat data . Check for this case and return
    the default UART_FCRVAL then.
V3: It turns out that if DEBUG_UART is defined, $port points directly to
    hardware registers. Add additional ifdef to handle the case where
    debug uart is enabled with DM_SERIAL correctly.
V4: Use UART_FCRVAL in _debug_uart_init() directly
---
 drivers/serial/ns16550.c | 18 ++++++++++++++++--
 include/ns16550.h        |  1 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 6e9b946..3c9f3b0 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -121,6 +121,13 @@ static int ns16550_readb(NS16550_t port, int offset)
 	return serial_in_shift(addr + plat->reg_offset, plat->reg_shift);
 }
 
+static u32 ns16550_getfcr(NS16550_t port)
+{
+	struct ns16550_platdata *plat = port->plat;
+
+	return plat->fcr;
+}
+
 /* We can clean these up once everything is moved to driver model */
 #define serial_out(value, addr)	\
 	ns16550_writeb(com_port, \
@@ -128,6 +135,11 @@ static int ns16550_readb(NS16550_t port, int offset)
 #define serial_in(addr) \
 	ns16550_readb(com_port, \
 		(unsigned char *)addr - (unsigned char *)com_port)
+#else
+static u32 ns16550_getfcr(NS16550_t port)
+{
+	return UART_FCRVAL;
+}
 #endif
 
 int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
@@ -171,7 +183,7 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 	serial_out(0x7, &com_port->mdr1);	/* mode select reset TL16C750*/
 #endif
 	serial_out(UART_MCRVAL, &com_port->mcr);
-	serial_out(UART_FCRVAL, &com_port->fcr);
+	serial_out(ns16550_getfcr(com_port), &com_port->fcr);
 	if (baud_divisor != -1)
 		NS16550_setbrg(com_port, baud_divisor);
 #if defined(CONFIG_OMAP) || \
@@ -192,7 +204,7 @@ void NS16550_reinit(NS16550_t com_port, int baud_divisor)
 	serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
 	NS16550_setbrg(com_port, 0);
 	serial_out(UART_MCRVAL, &com_port->mcr);
-	serial_out(UART_FCRVAL, &com_port->fcr);
+	serial_out(ns16550_getfcr(com_port), &com_port->fcr);
 	NS16550_setbrg(com_port, baud_divisor);
 }
 #endif /* CONFIG_NS16550_MIN_FUNCTIONS */
@@ -420,6 +432,8 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 	}
 
+	plat->fcr = UART_FCRVAL;
+
 	return 0;
 }
 #endif
diff --git a/include/ns16550.h b/include/ns16550.h
index 1311f4c..45fd68b 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -57,6 +57,7 @@ struct ns16550_platdata {
 	int reg_shift;
 	int clock;
 	int reg_offset;
+	u32 fcr;
 };
 
 struct udevice;
-- 
2.10.2

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

* [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-19 21:19   ` [U-Boot] [U-Boot, " Tom Rini
  2016-12-01  1:06 ` [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support Marek Vasut
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Add driver data to each compatible string to identify the type of
the port. Since all the ports in the driver are entirely compatible
with 16550 for now, all are marked with PORT_NS16550. But, there
are ports which have specific quirks, like the JZ4780 UART, which
do not have any DT property to denote the quirks. Instead, Linux
uses the compatible string to discern such ports and enable the
necessary quirks.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
---
 drivers/serial/ns16550.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 3c9f3b0..3130a1d 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -360,6 +360,12 @@ int ns16550_serial_probe(struct udevice *dev)
 	return 0;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+enum {
+	PORT_NS16550 = 0,
+};
+#endif
+
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 {
@@ -453,16 +459,16 @@ const struct dm_serial_ops ns16550_serial_ops = {
  * compatible string to your dts.
  */
 static const struct udevice_id ns16550_serial_ids[] = {
-	{ .compatible = "ns16550" },
-	{ .compatible = "ns16550a" },
-	{ .compatible = "nvidia,tegra20-uart" },
-	{ .compatible = "snps,dw-apb-uart" },
-	{ .compatible = "ti,omap2-uart" },
-	{ .compatible = "ti,omap3-uart" },
-	{ .compatible = "ti,omap4-uart" },
-	{ .compatible = "ti,am3352-uart" },
-	{ .compatible = "ti,am4372-uart" },
-	{ .compatible = "ti,dra742-uart" },
+	{ .compatible = "ns16550",		.data = PORT_NS16550 },
+	{ .compatible = "ns16550a",		.data = PORT_NS16550 },
+	{ .compatible = "nvidia,tegra20-uart",	.data = PORT_NS16550 },
+	{ .compatible = "snps,dw-apb-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,omap2-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,omap3-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,omap4-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,am3352-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,am4372-uart",	.data = PORT_NS16550 },
+	{ .compatible = "ti,dra742-uart",	.data = PORT_NS16550 },
 	{}
 };
 #endif
-- 
2.10.2

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

* [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-03  4:26   ` Simon Glass
  2016-12-19 21:20   ` [U-Boot] [U-Boot, " Tom Rini
  2016-12-01  1:06 ` [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used Marek Vasut
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Add compatibility string for the Ingenic JZ4780 SoC, the necessary
UART enable bit into FCR and register shift. Neither are encoded
in the DTS coming from Linux, so we need to support it this way.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
V2: Drop the reg_shift and move it to OF
---
 drivers/serial/ns16550.c | 5 +++++
 include/ns16550.h        | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 3130a1d..9b423a5 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -363,6 +363,7 @@ int ns16550_serial_probe(struct udevice *dev)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 enum {
 	PORT_NS16550 = 0,
+	PORT_JZ4780,
 };
 #endif
 
@@ -370,6 +371,7 @@ enum {
 int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 {
 	struct ns16550_platdata *plat = dev->platdata;
+	const u32 port_type = dev_get_driver_data(dev);
 	fdt_addr_t addr;
 	struct clk clk;
 	int err;
@@ -439,6 +441,8 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 	}
 
 	plat->fcr = UART_FCRVAL;
+	if (port_type == PORT_JZ4780)
+		plat->fcr |= UART_FCR_UME;
 
 	return 0;
 }
@@ -461,6 +465,7 @@ const struct dm_serial_ops ns16550_serial_ops = {
 static const struct udevice_id ns16550_serial_ids[] = {
 	{ .compatible = "ns16550",		.data = PORT_NS16550 },
 	{ .compatible = "ns16550a",		.data = PORT_NS16550 },
+	{ .compatible = "ingenic,jz4780-uart",	.data = PORT_JZ4780  },
 	{ .compatible = "nvidia,tegra20-uart",	.data = PORT_NS16550 },
 	{ .compatible = "snps,dw-apb-uart",	.data = PORT_NS16550 },
 	{ .compatible = "ti,omap2-uart",	.data = PORT_NS16550 },
diff --git a/include/ns16550.h b/include/ns16550.h
index 45fd68b..7c97036 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -118,6 +118,9 @@ typedef struct NS16550 *NS16550_t;
 #define UART_FCR_RXSR		0x02 /* Receiver soft reset */
 #define UART_FCR_TXSR		0x04 /* Transmitter soft reset */
 
+/* Ingenic JZ47xx specific UART-enable bit. */
+#define UART_FCR_UME		0x10
+
 /*
  * These are the definitions for the Modem Control Register
  */
-- 
2.10.2

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

* [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  4:17   ` Jaehoon Chung
  2016-12-01  5:14   ` Jaehoon Chung
  2016-12-01  1:06 ` [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code Marek Vasut
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

If debug() is not used, then the whole content of debug(...) will
be removed by the preprocessor, which will result in the following
warning. This patch adds __maybe_unused annotation to fix this.

drivers/mmc/mmc.c: In function ?mmc_init?:
drivers/mmc/mmc.c:1685:11: warning: variable ?start? set but not used [-Wunused-but-set-variable]
  unsigned start;

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/mmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d6b7e4f..6e25b67 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1708,7 +1708,7 @@ static int mmc_complete_init(struct mmc *mmc)
 int mmc_init(struct mmc *mmc)
 {
 	int err = 0;
-	unsigned start;
+	__maybe_unused unsigned start;
 #ifdef CONFIG_DM_MMC
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 
-- 
2.10.2

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

* [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (2 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  5:07   ` Jaehoon Chung
  2016-12-01  1:06 ` [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver Marek Vasut
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Add new configuration option CONFIG_MMC_TINY which strips away all
memory allocation within the MMC code and code for handling multiple
cards. This allows extremely space-constrained SPL code use the MMC
framework.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
---
V2: Switch the MMC_TINY option to Kconfig
---
 common/spl/spl_mmc.c     |  6 +++++-
 drivers/mmc/Kconfig      | 15 +++++++++++++++
 drivers/mmc/mmc.c        | 31 ++++++++++++++++++++++++++++++-
 drivers/mmc/mmc_legacy.c | 32 ++++++++++++++++++++++++++++++++
 include/mmc.h            |  1 +
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index a3d6b36..7dfcd0b 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -306,7 +306,11 @@ static int spl_mmc_load_image(struct spl_image_info *spl_image,
 			if (part == 7)
 				part = 0;
 
-			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+			if (CONFIG_IS_ENABLED(MMC_TINY))
+				err = mmc_switch_part(mmc, part);
+			else
+				err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
+
 			if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 				puts("spl: mmc partition switch failed\n");
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 24f4b28..5e84a41 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -26,6 +26,21 @@ config DM_MMC_OPS
 	  option will be removed as soon as all DM_MMC drivers use it, as it
 	  will the only supported behaviour.
 
+config SPL_MMC_TINY
+	bool "Tiny MMC framework in SPL"
+	help
+	  Enable MMC framework tinification support. This option is useful if
+	  if your SPL is extremely size constrained. Heed the warning, enable
+	  this option if and only if you know exactly what you are doing, if
+	  you are reading this help text, you most likely have no idea :-)
+
+	  The MMC framework is reduced to bare minimum to be useful. No malloc
+	  support is needed for the MMC framework operation with this option
+	  enabled. The framework supports exactly one MMC device and exactly
+	  one MMC driver. The MMC driver can be adjusted to avoid any malloc
+	  operations too, which can remove the need for malloc support in SPL
+	  and thus further reduce footprint.
+
 config MSM_SDHCI
 	bool "Qualcomm SDHCI controller"
 	depends on DM_MMC && BLK && DM_MMC_OPS
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6e25b67..19c4225 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -30,6 +30,29 @@ static const unsigned int sd_au_size[] = {
 	SZ_16M / 512,	(SZ_16M + SZ_8M) / 512,	SZ_32M / 512,	SZ_64M / 512,
 };
 
+#if CONFIG_IS_ENABLED(MMC_TINY)
+static struct mmc mmc_static;
+struct mmc *find_mmc_device(int dev_num)
+{
+	return &mmc_static;
+}
+
+void mmc_do_preinit(void)
+{
+	struct mmc *m = &mmc_static;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+	mmc_set_preinit(m, 1);
+#endif
+	if (m->preinit)
+		mmc_start_init(m);
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+	return &mmc->block_dev;
+}
+#endif
+
 #ifndef CONFIG_DM_MMC_OPS
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
@@ -259,7 +282,11 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
 	if (!mmc)
 		return 0;
 
-	err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+	if (CONFIG_IS_ENABLED(MMC_TINY))
+		err = mmc_switch_part(mmc, block_dev->hwpart);
+	else
+		err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
+
 	if (err < 0)
 		return 0;
 
@@ -1804,8 +1831,10 @@ int mmc_initialize(bd_t *bis)
 	initialized = 1;
 
 #ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(MMC_TINY)
 	mmc_list_init();
 #endif
+#endif
 	ret = mmc_probe(bis);
 	if (ret)
 		return ret;
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
index 25361d1..bdf9d98 100644
--- a/drivers/mmc/mmc_legacy.c
+++ b/drivers/mmc/mmc_legacy.c
@@ -13,6 +13,7 @@
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
+#if !CONFIG_IS_ENABLED(MMC_TINY)
 struct mmc *find_mmc_device(int dev_num)
 {
 	struct mmc *m;
@@ -62,6 +63,7 @@ void mmc_do_preinit(void)
 			mmc_start_init(m);
 	}
 }
+#endif
 
 void mmc_list_init(void)
 {
@@ -109,6 +111,35 @@ void print_mmc_devices(char separator)
 void print_mmc_devices(char separator) { }
 #endif
 
+#if CONFIG_IS_ENABLED(MMC_TINY)
+static struct mmc mmc_static = {
+	.dsr_imp		= 0,
+	.dsr			= 0xffffffff,
+	.block_dev = {
+		.if_type	= IF_TYPE_MMC,
+		.removable	= 1,
+		.devnum		= 0,
+		.block_read	= mmc_bread,
+		.block_write	= mmc_bwrite,
+		.block_erase	= mmc_berase,
+		.part_type	= 0,
+	},
+};
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
+{
+	struct mmc *mmc = &mmc_static;
+
+	mmc->cfg = cfg;
+	mmc->priv = priv;
+
+	return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+}
+#else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
 	struct blk_desc *bdesc;
@@ -157,6 +188,7 @@ void mmc_destroy(struct mmc *mmc)
 	/* only freeing memory for now */
 	free(mmc);
 }
+#endif
 
 static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
 {
diff --git a/include/mmc.h b/include/mmc.h
index e815eb3..f39be3c 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -513,6 +513,7 @@ void print_mmc_devices(char separator);
  * @return 0 if there is no MMC device, else the number of devices
  */
 int get_mmc_num(void);
+int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
 		      enum mmc_hwpart_conf_mode mode);
 
-- 
2.10.2

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

* [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (3 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  5:48   ` Jaehoon Chung
  2017-02-12 14:20   ` Andreas Färber
  2016-12-01  1:06 ` [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available Marek Vasut
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add driver for the JZ47xx MSC controller.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
---
 drivers/mmc/Kconfig  |   6 +
 drivers/mmc/Makefile |   1 +
 drivers/mmc/jz_mmc.c | 445 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 452 insertions(+)
 create mode 100644 drivers/mmc/jz_mmc.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 5e84a41..da26743 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -101,6 +101,12 @@ config MMC_UNIPHIER
 	help
 	  This selects support for the SD/MMC Host Controller on UniPhier SoCs.
 
+config JZ47XX_MMC
+	bool "Ingenic JZ47xx SD/MMC Host Controller support"
+	depends on ARCH_JZ47XX
+	help
+	  This selects support for the SD Card Controller on Ingenic JZ47xx SoCs.
+
 config SANDBOX_MMC
 	bool "Sandbox MMC support"
 	depends on MMC && SANDBOX
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index d850758..5f7cca3 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
 obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o
 obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
 obj-$(CONFIG_ROCKCHIP_SDHCI) += rockchip_sdhci.o
+obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
new file mode 100644
index 0000000..95b3367
--- /dev/null
+++ b/drivers/mmc/jz_mmc.c
@@ -0,0 +1,445 @@
+/*
+ * Ingenic JZ MMC driver
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <mach/jz4780.h>
+#include <wait_bit.h>
+
+/* Registers */
+#define MSC_STRPCL			0x000
+#define MSC_STAT			0x004
+#define MSC_CLKRT			0x008
+#define MSC_CMDAT			0x00c
+#define MSC_RESTO			0x010
+#define MSC_RDTO			0x014
+#define MSC_BLKLEN			0x018
+#define MSC_NOB				0x01c
+#define MSC_SNOB			0x020
+#define MSC_IMASK			0x024
+#define MSC_IREG			0x028
+#define MSC_CMD				0x02c
+#define MSC_ARG				0x030
+#define MSC_RES				0x034
+#define MSC_RXFIFO			0x038
+#define MSC_TXFIFO			0x03c
+#define MSC_LPM				0x040
+#define MSC_DMAC			0x044
+#define MSC_DMANDA			0x048
+#define MSC_DMADA			0x04c
+#define MSC_DMALEN			0x050
+#define MSC_DMACMD			0x054
+#define MSC_CTRL2			0x058
+#define MSC_RTCNT			0x05c
+#define MSC_DBG				0x0fc
+
+/* MSC Clock and Control Register (MSC_STRPCL) */
+#define MSC_STRPCL_EXIT_MULTIPLE	BIT(7)
+#define MSC_STRPCL_EXIT_TRANSFER	BIT(6)
+#define MSC_STRPCL_START_READWAIT	BIT(5)
+#define MSC_STRPCL_STOP_READWAIT	BIT(4)
+#define MSC_STRPCL_RESET		BIT(3)
+#define MSC_STRPCL_START_OP		BIT(2)
+#define MSC_STRPCL_CLOCK_CONTROL_STOP	BIT(0)
+#define MSC_STRPCL_CLOCK_CONTROL_START	BIT(1)
+
+/* MSC Status Register (MSC_STAT) */
+#define MSC_STAT_AUTO_CMD_DONE		BIT(31)
+#define MSC_STAT_IS_RESETTING		BIT(15)
+#define MSC_STAT_SDIO_INT_ACTIVE	BIT(14)
+#define MSC_STAT_PRG_DONE		BIT(13)
+#define MSC_STAT_DATA_TRAN_DONE		BIT(12)
+#define MSC_STAT_END_CMD_RES		BIT(11)
+#define MSC_STAT_DATA_FIFO_AFULL	BIT(10)
+#define MSC_STAT_IS_READWAIT		BIT(9)
+#define MSC_STAT_CLK_EN			BIT(8)
+#define MSC_STAT_DATA_FIFO_FULL		BIT(7)
+#define MSC_STAT_DATA_FIFO_EMPTY	BIT(6)
+#define MSC_STAT_CRC_RES_ERR		BIT(5)
+#define MSC_STAT_CRC_READ_ERROR		BIT(4)
+#define MSC_STAT_CRC_WRITE_ERROR	BIT(2)
+#define MSC_STAT_CRC_WRITE_ERROR_NOSTS	BIT(4)
+#define MSC_STAT_TIME_OUT_RES		BIT(1)
+#define MSC_STAT_TIME_OUT_READ		BIT(0)
+
+/* MSC Bus Clock Control Register (MSC_CLKRT) */
+#define MSC_CLKRT_CLK_RATE_MASK		0x7
+
+/* MSC Command Sequence Control Register (MSC_CMDAT) */
+#define MSC_CMDAT_IO_ABORT		BIT(11)
+#define MSC_CMDAT_BUS_WIDTH_1BIT	(0x0 << 9)
+#define MSC_CMDAT_BUS_WIDTH_4BIT	(0x2 << 9)
+#define MSC_CMDAT_DMA_EN		BIT(8)
+#define MSC_CMDAT_INIT			BIT(7)
+#define MSC_CMDAT_BUSY			BIT(6)
+#define MSC_CMDAT_STREAM_BLOCK		BIT(5)
+#define MSC_CMDAT_WRITE			BIT(4)
+#define MSC_CMDAT_DATA_EN		BIT(3)
+#define MSC_CMDAT_RESPONSE_MASK		0x7
+#define MSC_CMDAT_RESPONSE_NONE		0x0 /* No response */
+#define MSC_CMDAT_RESPONSE_R1		0x1 /* Format R1 and R1b */
+#define MSC_CMDAT_RESPONSE_R2		0x2 /* Format R2 */
+#define MSC_CMDAT_RESPONSE_R3		0x3 /* Format R3 */
+#define MSC_CMDAT_RESPONSE_R4		0x4 /* Format R4 */
+#define MSC_CMDAT_RESPONSE_R5		0x5 /* Format R5 */
+#define MSC_CMDAT_RESPONSE_R6		0x6 /* Format R6 */
+
+/* MSC Interrupts Mask Register (MSC_IMASK) */
+#define MSC_IMASK_TIME_OUT_RES		BIT(9)
+#define MSC_IMASK_TIME_OUT_READ		BIT(8)
+#define MSC_IMASK_SDIO			BIT(7)
+#define MSC_IMASK_TXFIFO_WR_REQ		BIT(6)
+#define MSC_IMASK_RXFIFO_RD_REQ		BIT(5)
+#define MSC_IMASK_END_CMD_RES		BIT(2)
+#define MSC_IMASK_PRG_DONE		BIT(1)
+#define MSC_IMASK_DATA_TRAN_DONE	BIT(0)
+
+
+/* MSC Interrupts Status Register (MSC_IREG) */
+#define MSC_IREG_TIME_OUT_RES		BIT(9)
+#define MSC_IREG_TIME_OUT_READ		BIT(8)
+#define MSC_IREG_SDIO			BIT(7)
+#define MSC_IREG_TXFIFO_WR_REQ		BIT(6)
+#define MSC_IREG_RXFIFO_RD_REQ		BIT(5)
+#define MSC_IREG_END_CMD_RES		BIT(2)
+#define MSC_IREG_PRG_DONE		BIT(1)
+#define MSC_IREG_DATA_TRAN_DONE		BIT(0)
+
+struct jz_mmc_priv {
+	struct mmc_config	cfg;
+	void __iomem		*regs;
+	u32			flags;
+/* priv flags */
+#define JZ_MMC_BUS_WIDTH_MASK	0x3
+#define JZ_MMC_BUS_WIDTH_1	0x0
+#define JZ_MMC_BUS_WIDTH_4	0x2
+#define JZ_MMC_BUS_WIDTH_8	0x3
+#define JZ_MMC_SENT_INIT	BIT(2)
+};
+
+static int jz_mmc_clock_rate(void)
+{
+	return 24000000;
+}
+
+static int jz_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+						struct mmc_data *data)
+{
+	struct jz_mmc_priv *priv = mmc->priv;
+	u32 stat, mask, cmdat = 0;
+
+	/* stop the clock */
+	writel(MSC_STRPCL_CLOCK_CONTROL_STOP, priv->regs + MSC_STRPCL);
+
+	wait_for_bit("jzmmc", priv->regs + MSC_STAT,
+		     MSC_STAT_CLK_EN, 0, 10, 0);
+
+	writel(0, priv->regs + MSC_DMAC);
+
+	/* setup command */
+	writel(cmd->cmdidx, priv->regs + MSC_CMD);
+	writel(cmd->cmdarg, priv->regs + MSC_ARG);
+
+	if (data) {
+		/* setup data */
+		cmdat |= MSC_CMDAT_DATA_EN;
+		if (data->flags & MMC_DATA_WRITE)
+			cmdat |= MSC_CMDAT_WRITE;
+
+		writel(data->blocks, priv->regs + MSC_NOB);
+		writel(data->blocksize, priv->regs + MSC_BLKLEN);
+	} else {
+		writel(0, priv->regs + MSC_NOB);
+		writel(0, priv->regs + MSC_BLKLEN);
+	}
+
+	/* setup response */
+	switch (cmd->resp_type) {
+	case MMC_RSP_NONE:
+		break;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1b:
+		cmdat |= MSC_CMDAT_RESPONSE_R1;
+		break;
+	case MMC_RSP_R2:
+		cmdat |= MSC_CMDAT_RESPONSE_R2;
+		break;
+	case MMC_RSP_R3:
+		cmdat |= MSC_CMDAT_RESPONSE_R3;
+		break;
+	default:
+		break;
+	}
+
+	if (cmd->resp_type & MMC_RSP_BUSY)
+		cmdat |= MSC_CMDAT_BUSY;
+
+	/* set init for the first command only */
+	if (!(priv->flags & JZ_MMC_SENT_INIT)) {
+		cmdat |= MSC_CMDAT_INIT;
+		priv->flags |= JZ_MMC_SENT_INIT;
+	}
+
+	cmdat |= (priv->flags & JZ_MMC_BUS_WIDTH_MASK) << 9;
+
+	/* write the data setup */
+	writel(cmdat, priv->regs + MSC_CMDAT);
+
+	/* unmask interrupts */
+	mask = 0xffffffff & ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_TIME_OUT_RES);
+	if (data) {
+		mask &= ~MSC_IMASK_DATA_TRAN_DONE;
+		if (data->flags & MMC_DATA_WRITE) {
+			mask &= ~MSC_IMASK_TXFIFO_WR_REQ;
+		} else {
+			mask &= ~(MSC_IMASK_RXFIFO_RD_REQ |
+				  MSC_IMASK_TIME_OUT_READ);
+		}
+	}
+	writel(mask, priv->regs + MSC_IMASK);
+
+	/* clear interrupts */
+	writel(0xffffffff, priv->regs + MSC_IREG);
+
+	/* start the command (& the clock) */
+	writel(MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START,
+	       priv->regs + MSC_STRPCL);
+
+	/* wait for completion */
+	wait_for_bit("jzmmc", priv->regs + MSC_IREG,
+		     MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES, 1, 1, 0);
+	stat = readl(priv->regs + MSC_IREG);
+	stat &= MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES;
+	writel(stat, priv->regs + MSC_IREG);
+	if (stat & MSC_IREG_TIME_OUT_RES)
+		return -ETIMEDOUT;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		/* read the response */
+		if (cmd->resp_type & MMC_RSP_136) {
+			u16 a, b, c, i;
+			a = readw(priv->regs + MSC_RES);
+			for (i = 0; i < 4; i++) {
+				b = readw(priv->regs + MSC_RES);
+				c = readw(priv->regs + MSC_RES);
+				cmd->response[i] = (a << 24) | (b << 8) |
+						   (c >> 8);
+				a = c;
+			}
+		} else {
+			cmd->response[0] = readw(priv->regs + MSC_RES) << 24;
+			cmd->response[0] |= readw(priv->regs + MSC_RES) << 8;
+			cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff;
+		}
+	}
+
+	if (data && (data->flags & MMC_DATA_WRITE)) {
+		/* write the data */
+		int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4);
+		const void *buf = data->src;
+
+		while (sz--) {
+			u32 val = get_unaligned_le32(buf);
+			wait_for_bit("jzmmc", priv->regs + MSC_IREG,
+				     MSC_IREG_TXFIFO_WR_REQ, 1, 50, 0);
+			writel(val, priv->regs + MSC_TXFIFO);
+			buf += 4;
+		}
+	} else if (data && (data->flags & MMC_DATA_READ)) {
+		/* read the data */
+		int sz = data->blocks * data->blocksize;
+		void *buf = data->dest;
+
+		do {
+			stat = readl(priv->regs + MSC_STAT);
+
+			if (stat & MSC_STAT_TIME_OUT_READ)
+				return -ETIMEDOUT;
+			if (stat & MSC_STAT_CRC_READ_ERROR)
+				return -EILSEQ;
+			if (stat & MSC_STAT_DATA_FIFO_EMPTY) {
+				udelay(10);
+				continue;
+			}
+			do {
+				u32 val = readl(priv->regs + MSC_RXFIFO);
+
+				if (sz == 1)
+					*(u8 *)buf = (u8)val;
+				else if (sz == 2)
+					put_unaligned_le16(val, buf);
+				else if (sz >= 4)
+					put_unaligned_le32(val, buf);
+				buf += 4;
+				sz -= 4;
+				stat = readl(priv->regs + MSC_STAT);
+			} while (!(stat & MSC_STAT_DATA_FIFO_EMPTY));
+		} while (!(stat & MSC_STAT_DATA_TRAN_DONE));
+	}
+
+	return 0;
+}
+
+static void jz_mmc_set_ios(struct mmc *mmc)
+{
+	struct jz_mmc_priv *priv = mmc->priv;
+	u32 real_rate = jz_mmc_clock_rate();
+	u8 clk_div = 0;
+
+	/* calculate clock divide */
+	while ((real_rate > mmc->clock) && (clk_div < 7)) {
+		real_rate >>= 1;
+		clk_div++;
+	}
+	writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
+
+	/* set the bus width for the next command */
+	priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
+	if (mmc->bus_width == 8)
+		priv->flags |= JZ_MMC_BUS_WIDTH_8;
+	else if (mmc->bus_width == 4)
+		priv->flags |= JZ_MMC_BUS_WIDTH_4;
+	else
+		priv->flags |= JZ_MMC_BUS_WIDTH_1;
+}
+
+static int jz_mmc_core_init(struct mmc *mmc)
+{
+	struct jz_mmc_priv *priv = mmc->priv;
+
+	/* Reset */
+	writel(MSC_STRPCL_RESET, priv->regs + MSC_STRPCL);
+
+	wait_for_bit("jzmmc", priv->regs + MSC_STAT,
+		     MSC_STAT_IS_RESETTING, 0, 10, 0);
+
+	/* Maximum timeouts */
+	writel(0xffff, priv->regs + MSC_RESTO);
+	writel(0xffffffff, priv->regs + MSC_RDTO);
+
+	/* Enable low power mode */
+	writel(0x1, priv->regs + MSC_LPM);
+
+	return 0;
+}
+
+static const struct mmc_ops jz_msc_ops = {
+	.send_cmd	= jz_mmc_send_cmd,
+	.set_ios	= jz_mmc_set_ios,
+	.init		= jz_mmc_core_init,
+};
+
+#ifdef CONFIG_MMC_TINY
+static struct jz_mmc_priv jz_mmc_priv_static = {
+	.cfg = {
+		.name = "MSC",
+		.ops = &jz_msc_ops,
+
+		.voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
+				MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
+				MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,
+		.host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
+
+		.f_min = 375000,
+		.f_max = 48000000,
+		.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+	},
+};
+
+int jz_mmc_init(void __iomem *base)
+{
+	struct mmc *mmc;
+
+	jz_mmc_priv_static.regs = base;
+
+	mmc = mmc_create(&jz_mmc_priv_static.cfg, &jz_mmc_priv_static);
+
+	return mmc ? 0 : -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_DM_MMC
+#include <dm.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct jz_mmc_priv *priv = dev_get_priv(dev);
+	const void *fdt = gd->fdt_blob;
+	int node = dev->of_offset;
+	struct mmc_config *cfg;
+	int val;
+
+	priv->regs = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
+	cfg = &priv->cfg;
+
+	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
+	val = fdtdec_get_int(fdt, node, "bus-width", 1);
+	if (val < 0) {
+		printf("error: bus-width property missing\n");
+		return -ENOENT;
+	}
+
+	switch (val) {
+	case 0x8:
+		cfg->host_caps |= MMC_MODE_8BIT;
+	case 0x4:
+		cfg->host_caps |= MMC_MODE_4BIT;
+	case 0x1:
+		break;
+	default:
+		printf("error: invalid bus-width property\n");
+		return -ENOENT;
+	}
+
+	cfg->f_min = 400000;
+	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
+	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+	return 0;
+}
+
+static int jz_mmc_probe(struct udevice *dev)
+{
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+	struct jz_mmc_priv *priv = dev_get_priv(dev);
+	struct mmc_config *cfg = &priv->cfg;
+	struct mmc *mmc;
+
+	cfg->name = "MSC";
+	cfg->ops = &jz_msc_ops;
+
+	mmc = mmc_create(cfg, priv);
+	if (!mmc)
+		return -ENODEV;
+
+	mmc->dev = dev;
+	upriv->mmc = mmc;
+
+	return 0;
+}
+static const struct udevice_id jz_mmc_ids[] = {
+	{ .compatible = "ingenic,jz4780-mmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(jz_mmc_drv) = {
+	.name			= "jz_mmc",
+	.id			= UCLASS_MMC,
+	.of_match		= jz_mmc_ids,
+	.ofdata_to_platdata	= jz_mmc_ofdata_to_platdata,
+	.probe			= jz_mmc_probe,
+	.priv_auto_alloc_size	= sizeof(struct jz_mmc_priv),
+};
+#endif
-- 
2.10.2

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

* [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (4 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  5:07   ` Jaehoon Chung
  2016-12-01  1:06 ` [U-Boot] [PATCH 08/13] gpio: Add JZ47xx GPIO driver Marek Vasut
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Make the spl_mmc_load_image() available globally, so it can be
invoked directly by SPL on extremely space-constrained systems.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
---
 common/spl/spl_mmc.c | 4 ++--
 include/spl.h        | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 7dfcd0b..58b061f 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -272,8 +272,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
 }
 #endif
 
-static int spl_mmc_load_image(struct spl_image_info *spl_image,
-			      struct spl_boot_device *bootdev)
+int spl_mmc_load_image(struct spl_image_info *spl_image,
+		       struct spl_boot_device *bootdev)
 {
 	struct mmc *mmc = NULL;
 	u32 boot_mode;
diff --git a/include/spl.h b/include/spl.h
index e080a82..c727eb7 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -234,4 +234,7 @@ bool spl_was_boot_source(void);
  */
 int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr);
 
+int spl_mmc_load_image(struct spl_image_info *spl_image,
+		       struct spl_boot_device *bootdev);
+
 #endif
-- 
2.10.2

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

* [U-Boot] [PATCH 08/13] gpio: Add JZ47xx GPIO driver
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (5 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 09/13] misc: Add JZ47xx efuse driver Marek Vasut
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add primitive GPIO controller driver for the JZ47xx SoC.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 drivers/gpio/Kconfig       |  8 +++++
 drivers/gpio/Makefile      |  1 +
 drivers/gpio/gpio-jz47xx.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)
 create mode 100644 drivers/gpio/gpio-jz47xx.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8d9ab52..4515883 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -221,4 +221,12 @@ config MPC85XX_GPIO
 
 	  The driver has been tested on MPC85XX, but it is likely that other
 	  PowerQUICC III devices will work as well.
+
+config JZ47XX_GPIO
+	bool "Ingenic JZ47xx GPIO driver"
+	depends on ARCH_JZ47XX
+	default y
+	help
+	  Supports GPIO access on Ingenic JZ47xx SoCs.
+
 endmenu
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8939226..e562022 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -58,3 +58,4 @@ obj-$(CONFIG_MVEBU_GPIO)	+= mvebu_gpio.o
 obj-$(CONFIG_MSM_GPIO)		+= msm_gpio.o
 obj-$(CONFIG_$(SPL_)PCF8575_GPIO)	+= pcf8575_gpio.o
 obj-$(CONFIG_PM8916_GPIO)	+= pm8916_gpio.o
+obj-$(CONFIG_JZ47XX_GPIO)	+= gpio-jz47xx.o
diff --git a/drivers/gpio/gpio-jz47xx.c b/drivers/gpio/gpio-jz47xx.c
new file mode 100644
index 0000000..210120d
--- /dev/null
+++ b/drivers/gpio/gpio-jz47xx.c
@@ -0,0 +1,79 @@
+/*
+ * Ingenic JZ47xx GPIO
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+int gpio_get_value(unsigned gpio)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin);
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	if (value)
+		writel(BIT(pin), gpio_regs + GPIO_PXPAT0S(port));
+	else
+		writel(BIT(pin), gpio_regs + GPIO_PXPAT0C(port));
+
+	return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port));
+
+	return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	writel(BIT(pin), gpio_regs + GPIO_PXINTC(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port));
+	writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port));
+
+	gpio_set_value(gpio, value);
+
+	return 0;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	int port = gpio / 32;
+
+	if (port >= 6)
+		return -EINVAL;
+
+	return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+	return 0;
+}
-- 
2.10.2

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

* [U-Boot] [PATCH 09/13] misc: Add JZ47xx efuse driver
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (6 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 08/13] gpio: Add JZ47xx GPIO driver Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 10/13] mips: Add SPL header Marek Vasut
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add driver for the efuse block in the JZ47xx SOC.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 drivers/misc/Kconfig        |   6 +++
 drivers/misc/Makefile       |   1 +
 drivers/misc/jz4780_efuse.c | 100 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)
 create mode 100644 drivers/misc/jz4780_efuse.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1aae4bc..ed0659b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -83,6 +83,12 @@ config FSL_SEC_MON
 	  Security Monitor can be transitioned on any security failures,
 	  like software violations or hardware security violations.
 
+config JZ4780_EFUSE
+	bool "Ingenic JZ4780 eFUSE support"
+	depends on ARCH_JZ47XX
+	help
+	  This selects support for the eFUSE on Ingenic JZ4780 SoCs.
+
 config MXC_OCOTP
 	bool "Enable MXC OCOTP Driver"
 	help
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9fbb5a7..6904a76 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -51,3 +51,4 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_QFW) += qfw.o
+obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o
diff --git a/drivers/misc/jz4780_efuse.c b/drivers/misc/jz4780_efuse.c
new file mode 100644
index 0000000..e866b46
--- /dev/null
+++ b/drivers/misc/jz4780_efuse.c
@@ -0,0 +1,100 @@
+/*
+ * JZ4780 EFUSE driver
+ *
+ * Copyright (c) 2014 Imagination Technologies
+ * Author: Alex Smith <alex.smith@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <mach/jz4780.h>
+
+#define EFUSE_EFUCTRL			0xd0
+#define EFUSE_EFUCFG			0xd4
+#define EFUSE_EFUSTATE			0xd8
+#define EFUSE_EFUDATA(n)		(0xdc + ((n) * 4))
+
+#define EFUSE_EFUCTRL_RD_EN		BIT(0)
+#define EFUSE_EFUCTRL_LEN_BIT		16
+#define EFUSE_EFUCTRL_LEN_MASK		0x1f
+#define EFUSE_EFUCTRL_ADDR_BIT		21
+#define EFUSE_EFUCTRL_ADDR_MASK		0x1ff
+#define EFUSE_EFUCTRL_CS		BIT(30)
+
+#define EFUSE_EFUCFG_RD_STROBE_BIT	16
+#define EFUSE_EFUCFG_RD_STROBE_MASK	0xf
+#define EFUSE_EFUCFG_RD_ADJ_BIT		20
+#define EFUSE_EFUCFG_RD_ADJ_MASK	0xf
+
+#define EFUSE_EFUSTATE_RD_DONE		BIT(0)
+
+static void jz4780_efuse_read_chunk(size_t addr, size_t count, u8 *buf)
+{
+	void __iomem *regs = (void __iomem *)NEMC_BASE;
+	size_t i;
+	u32 val;
+
+	val = EFUSE_EFUCTRL_RD_EN |
+	      ((count - 1) << EFUSE_EFUCTRL_LEN_BIT) |
+	      (addr << EFUSE_EFUCTRL_ADDR_BIT) |
+	      ((addr > 0x200) ? EFUSE_EFUCTRL_CS : 0);
+	writel(val, regs + EFUSE_EFUCTRL);
+	/* FIXME -- wait_bit() */
+	while (!(readl(regs + EFUSE_EFUSTATE) & EFUSE_EFUSTATE_RD_DONE))
+		;
+
+	if ((count % 4) == 0) {
+		for (i = 0; i < count / 4; i++) {
+			val = readl(regs + EFUSE_EFUDATA(i));
+			put_unaligned(val, (u32 *)(buf + (i * 4)));
+		}
+	} else {
+		val = readl(regs + EFUSE_EFUDATA(0));
+		if (count > 2)
+			buf[2] = (val >> 16) & 0xff;
+		if (count > 1)
+			buf[1] = (val >> 8) & 0xff;
+		buf[0] = val & 0xff;
+	}
+}
+
+static inline int jz4780_efuse_chunk_size(size_t count)
+{
+	if (count >= 32)
+		return 32;
+	else if ((count / 4) > 0)
+		return (count / 4) * 4;
+	else
+		return count % 4;
+}
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf)
+{
+	size_t chunk;
+
+	while (count > 0) {
+		chunk = jz4780_efuse_chunk_size(count);
+		jz4780_efuse_read_chunk(addr, chunk, buf);
+		addr += chunk;
+		buf += chunk;
+		count -= chunk;
+	}
+}
+
+void jz4780_efuse_init(u32 ahb2_rate)
+{
+	void __iomem *regs = (void __iomem *)NEMC_BASE;
+	u32 rd_adj, rd_strobe, tmp;
+
+	rd_adj = (((6500 * (ahb2_rate / 1000000)) / 1000000) + 0xf) / 2;
+	tmp = (((35000 * (ahb2_rate / 1000000)) / 1000000) - 4) - rd_adj;
+	rd_strobe = ((tmp + 0xf) / 2 < 7) ? 7 : (tmp + 0xf) / 2;
+
+	tmp = (rd_adj << EFUSE_EFUCFG_RD_ADJ_BIT) |
+	      (rd_strobe << EFUSE_EFUCFG_RD_STROBE_BIT);
+	writel(tmp, regs + EFUSE_EFUCFG);
+}
-- 
2.10.2

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

* [U-Boot] [PATCH 10/13] mips: Add SPL header
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (7 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 09/13] misc: Add JZ47xx efuse driver Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 11/13] mips: jz47xx: Add JZ4780 SoC support Marek Vasut
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add header with SPL boot mode and type definitions.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/include/asm/spl.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 arch/mips/include/asm/spl.h

diff --git a/arch/mips/include/asm/spl.h b/arch/mips/include/asm/spl.h
new file mode 100644
index 0000000..01baab6
--- /dev/null
+++ b/arch/mips/include/asm/spl.h
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef	_ASM_SPL_H_
+#define	_ASM_SPL_H_
+
+enum {
+	BOOT_DEVICE_RAM,
+	BOOT_DEVICE_MMC1,
+	BOOT_DEVICE_MMC2,
+	BOOT_DEVICE_MMC2_2,
+	BOOT_DEVICE_NAND,
+	BOOT_DEVICE_ONENAND,
+	BOOT_DEVICE_NOR,
+	BOOT_DEVICE_UART,
+	BOOT_DEVICE_SPI,
+	BOOT_DEVICE_USB,
+	BOOT_DEVICE_SATA,
+	BOOT_DEVICE_I2C,
+	BOOT_DEVICE_BOARD,
+	BOOT_DEVICE_NONE
+};
+
+/* Linker symbols. */
+extern char __bss_start[];
+extern ulong __bss_end;
+
+#ifndef CONFIG_DM
+extern gd_t gdata;
+#endif
+
+#endif
-- 
2.10.2

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

* [U-Boot] [PATCH 11/13] mips: jz47xx: Add JZ4780 SoC support
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (8 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 10/13] mips: Add SPL header Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 12/13] mips: jz47xx: Add minimal JZ MMC node Marek Vasut
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add initial support for the Ingenic JZ47xx MIPS SoC.
The DTSI file comes from Linux 4.6 as of revision
78800558d104e003f9ae92e0107f1de39cf9de9f

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/Kconfig                                |   7 +
 arch/mips/Makefile                               |   1 +
 arch/mips/dts/jz4780.dtsi                        | 142 ++++++
 arch/mips/mach-jz47xx/Kconfig                    |  15 +
 arch/mips/mach-jz47xx/Makefile                   |   7 +
 arch/mips/mach-jz47xx/include/mach/jz4780.h      |  99 +++++
 arch/mips/mach-jz47xx/include/mach/jz4780_dram.h | 457 ++++++++++++++++++++
 arch/mips/mach-jz47xx/jz4780/Makefile            |   5 +
 arch/mips/mach-jz47xx/jz4780/jz4780.c            | 135 ++++++
 arch/mips/mach-jz47xx/jz4780/pll.c               | 527 +++++++++++++++++++++++
 arch/mips/mach-jz47xx/jz4780/sdram.c             | 271 ++++++++++++
 arch/mips/mach-jz47xx/jz4780/timer.c             | 238 ++++++++++
 arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds      |  52 +++
 arch/mips/mach-jz47xx/start.S                    |  99 +++++
 include/dt-bindings/clock/jz4780-cgu.h           |  88 ++++
 15 files changed, 2143 insertions(+)
 create mode 100644 arch/mips/dts/jz4780.dtsi
 create mode 100644 arch/mips/mach-jz47xx/Kconfig
 create mode 100644 arch/mips/mach-jz47xx/Makefile
 create mode 100644 arch/mips/mach-jz47xx/include/mach/jz4780.h
 create mode 100644 arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
 create mode 100644 arch/mips/mach-jz47xx/jz4780/Makefile
 create mode 100644 arch/mips/mach-jz47xx/jz4780/jz4780.c
 create mode 100644 arch/mips/mach-jz47xx/jz4780/pll.c
 create mode 100644 arch/mips/mach-jz47xx/jz4780/sdram.c
 create mode 100644 arch/mips/mach-jz47xx/jz4780/timer.c
 create mode 100644 arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
 create mode 100644 arch/mips/mach-jz47xx/start.S
 create mode 100644 include/dt-bindings/clock/jz4780-cgu.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d97930e..40d876f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -75,6 +75,12 @@ config ARCH_ATH79
 	select OF_CONTROL
 	select DM
 
+config ARCH_JZ47XX
+	bool "Support Ingenic JZ47xx"
+	select SUPPORT_SPL
+	select OF_CONTROL
+	select DM
+
 config MACH_PIC32
 	bool "Support Microchip PIC32"
 	select OF_CONTROL
@@ -123,6 +129,7 @@ source "board/micronas/vct/Kconfig"
 source "board/pb1x00/Kconfig"
 source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
+source "arch/mips/mach-jz47xx/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
 
 if MIPS
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index efe7e44..4f0f797 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -15,6 +15,7 @@ libs-y += arch/mips/lib/
 
 machine-$(CONFIG_SOC_AU1X00) += au1x00
 machine-$(CONFIG_ARCH_ATH79) += ath79
+machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
 machine-$(CONFIG_MACH_PIC32) += pic32
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi
new file mode 100644
index 0000000..8f01d36
--- /dev/null
+++ b/arch/mips/dts/jz4780.dtsi
@@ -0,0 +1,142 @@
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4780";
+
+	cpuintc: interrupt-controller {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: interrupt-controller at 10001000 {
+		compatible = "ingenic,jz4780-intc";
+		reg = <0x10001000 0x50>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4780-cgu at 10000000 {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
+
+	uart0: serial at 10030000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10030000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <51>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart1: serial at 10031000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10031000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <50>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart2: serial at 10032000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10032000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <49>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart3: serial at 10033000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10033000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <48>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	uart4: serial at 10034000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10034000 0x100>;
+		reg-shift = <2>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <34>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+		clock-names = "baud", "module";
+
+		status = "disabled";
+	};
+
+	nemc: nemc at 13410000 {
+		compatible = "ingenic,jz4780-nemc";
+		reg = <0x13410000 0x10000>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <1 0 0x1b000000 0x1000000
+			  2 0 0x1a000000 0x1000000
+			  3 0 0x19000000 0x1000000
+			  4 0 0x18000000 0x1000000
+			  5 0 0x17000000 0x1000000
+			  6 0 0x16000000 0x1000000>;
+
+		clocks = <&cgu JZ4780_CLK_NEMC>;
+
+		status = "disabled";
+	};
+
+	bch: bch at 134d0000 {
+		compatible = "ingenic,jz4780-bch";
+		reg = <0x134d0000 0x10000>;
+
+		clocks = <&cgu JZ4780_CLK_BCH>;
+
+		status = "disabled";
+	};
+};
diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
new file mode 100644
index 0000000..cd6944c
--- /dev/null
+++ b/arch/mips/mach-jz47xx/Kconfig
@@ -0,0 +1,15 @@
+menu "Ingenic JZ47xx platforms"
+	depends on ARCH_JZ47XX
+
+config SYS_SOC
+	default "jz47xx"
+
+config SOC_JZ4780
+	bool
+	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_CPU_MIPS32_R2
+	help
+	  Support for Ingenic JZ4780 family SoCs.
+
+endmenu
diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile
new file mode 100644
index 0000000..5eee9ac
--- /dev/null
+++ b/arch/mips/mach-jz47xx/Makefile
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+extra-$(CONFIG_SPL_BUILD)	:= start.o
+
+obj-$(CONFIG_SOC_JZ4780)	+= jz4780/
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780.h b/arch/mips/mach-jz47xx/include/mach/jz4780.h
new file mode 100644
index 0000000..e909a81
--- /dev/null
+++ b/arch/mips/mach-jz47xx/include/mach/jz4780.h
@@ -0,0 +1,99 @@
+/*
+ * JZ4780 definitions
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __JZ4780_H__
+#define __JZ4780_H__
+
+/* AHB0 BUS Devices */
+#define DDRC_BASE	0xb3010000
+
+/* AHB2 BUS Devices */
+#define NEMC_BASE	0xb3410000
+#define BCH_BASE	0xb34d0000
+
+/* APB BUS Devices */
+#define CPM_BASE	0xb0000000
+#define TCU_BASE	0xb0002000
+#define WDT_BASE	0xb0002000
+#define GPIO_BASE	0xb0010000
+#define UART0_BASE	0xb0030000
+#define UART1_BASE	0xb0031000
+#define UART2_BASE	0xb0032000
+#define UART3_BASE	0xb0033000
+#define MSC0_BASE	0xb3450000
+#define MSC1_BASE	0xb3460000
+#define MSC2_BASE	0xb3470000
+
+/*
+ * GPIO
+ */
+/* n = 0,1,2,3,4,5 */
+#define GPIO_PXPIN(n)	(0x00 + (n) * 0x100)
+#define GPIO_PXINT(n)	(0x10 + (n) * 0x100)
+#define GPIO_PXINTS(n)	(0x14 + (n) * 0x100)
+#define GPIO_PXINTC(n)	(0x18 + (n) * 0x100)
+#define GPIO_PXMASK(n)	(0x20 + (n) * 0x100)
+#define GPIO_PXMASKS(n)	(0x24 + (n) * 0x100)
+#define GPIO_PXMASKC(n)	(0x28 + (n) * 0x100)
+#define GPIO_PXPAT1(n)	(0x30 + (n) * 0x100)
+#define GPIO_PXPAT1S(n)	(0x34 + (n) * 0x100)
+#define GPIO_PXPAT1C(n)	(0x38 + (n) * 0x100)
+#define GPIO_PXPAT0(n)	(0x40 + (n) * 0x100)
+#define GPIO_PXPAT0S(n)	(0x44 + (n) * 0x100)
+#define GPIO_PXPAT0C(n)	(0x48 + (n) * 0x100)
+#define GPIO_PXFLG(n)	(0x50 + (n) * 0x100)
+#define GPIO_PXFLGC(n)	(0x54 + (n) * 0x100)
+#define GPIO_PXOEN(n)	(0x60 + (n) * 0x100)
+#define GPIO_PXOENS(n)	(0x64 + (n) * 0x100)
+#define GPIO_PXOENC(n)	(0x68 + (n) * 0x100)
+#define GPIO_PXPEN(n)	(0x70 + (n) * 0x100)
+#define GPIO_PXPENS(n)	(0x74 + (n) * 0x100)
+#define GPIO_PXPENC(n)	(0x78 + (n) * 0x100)
+#define GPIO_PXDS(n)	(0x80 + (n) * 0x100)
+#define GPIO_PXDSS(n)	(0x84 + (n) * 0x100)
+#define GPIO_PXDSC(n)	(0x88 + (n) * 0x100)
+
+/* PLL setup */
+#define JZ4780_APLL_M	1
+#define JZ4780_APLL_N	1
+#define JZ4780_APLL_OD	1
+
+#define JZ4780_MPLL_M	(CONFIG_SYS_MEM_SPEED / CONFIG_SYS_EXTAL * 2)
+#define JZ4780_MPLL_N	2
+#define JZ4780_MPLL_OD	1
+
+#define JZ4780_EPLL_M	(CONFIG_SYS_AUDIO_SPEED * 2 / CONFIG_SYS_EXTAL)
+#define JZ4780_EPLL_N	1
+#define JZ4780_EPLL_OD	2
+
+#define JZ4780_VPLL_M	((888 * 1000000) * 2 / CONFIG_SYS_EXTAL)
+#define JZ4780_VPLL_N	1
+#define JZ4780_VPLL_OD	2
+
+#ifndef __ASSEMBLY__
+
+u32 sdram_size(int bank);
+
+const u32 jz4780_clk_get_efuse_clk(void);
+void jz4780_clk_ungate_ethernet(void);
+void jz4780_clk_ungate_mmc(void);
+void jz4780_clk_ungate_uart(const unsigned int uart);
+
+void jz4780_efuse_read(size_t addr, size_t count, u8 *buf);
+void jz4780_efuse_init(u32 ahb2_rate);
+
+void jz4780_tcu_wdt_start(void);
+
+#ifdef CONFIG_SPL_BUILD
+int jz_mmc_init(void __iomem *base);
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif	/* __JZ4780_H__ */
diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
new file mode 100644
index 0000000..0bcc215
--- /dev/null
+++ b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h
@@ -0,0 +1,457 @@
+/*
+ * JZ4780 DDR initialization - parameters definitions
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Matt Redfearn <matt.redfearn.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __JZ4780_DRAM_H__
+#define __JZ4780_DRAM_H__
+
+/*
+ * DDR
+ */
+#define DDRC_ST				0x0
+#define DDRC_CFG			0x4
+#define DDRC_CTRL			0x8
+#define DDRC_LMR			0xc
+#define DDRC_REFCNT			0x18
+#define DDRC_DQS			0x1c
+#define DDRC_DQS_ADJ			0x20
+#define DDRC_MMAP0			0x24
+#define DDRC_MMAP1			0x28
+#define DDRC_MDELAY			0x2c
+#define DDRC_CKEL			0x30
+#define DDRC_PMEMCTRL0			0x54
+#define DDRC_PMEMCTRL1			0x50
+#define DDRC_PMEMCTRL2			0x58
+#define DDRC_PMEMCTRL3			0x5c
+
+#define DDRC_TIMING(n)			(0x60 + 4 * (n))
+#define DDRC_REMMAP(n)			(0x9c + 4 * (n))
+
+/*
+ * DDR PHY
+ */
+#define DDR_MEM_PHY_BASE		0x20000000
+#define DDR_PHY_OFFSET			0x1000
+
+#define DDRP_PIR			0x4
+#define DDRP_PGCR			0x8
+#define DDRP_PGSR			0xc
+
+#define DDRP_PTR0			0x18
+#define DDRP_PTR1			0x1c
+#define DDRP_PTR2			0x20
+
+#define DDRP_ACIOCR			0x24
+#define DDRP_DXCCR			0x28
+#define DDRP_DSGCR			0x2c
+#define DDRP_DCR			0x30
+
+#define DDRP_DTPR0			0x34
+#define DDRP_DTPR1			0x38
+#define DDRP_DTPR2			0x3c
+#define DDRP_MR0			0x40
+#define DDRP_MR1			0x44
+#define DDRP_MR2			0x48
+#define DDRP_MR3			0x4c
+
+#define DDRP_ODTCR			0x50
+#define DDRP_DTAR			0x54
+#define DDRP_DTDR0			0x58
+#define DDRP_DTDR1			0x5c
+
+#define DDRP_DCUAR			0xc0
+#define DDRP_DCUDR			0xc4
+#define DDRP_DCURR			0xc8
+#define DDRP_DCULR			0xcc
+#define DDRP_DCUGCR			0xd0
+#define DDRP_DCUTPR			0xd4
+#define DDRP_DCUSR0			0xd8
+#define DDRP_DCUSR1			0xdc
+
+#define DDRP_ZQXCR0(n)			(0x180 + ((n) * 0x10))
+#define DDRP_ZQXCR1(n)			(0x184 + ((n) * 0x10))
+#define DDRP_ZQXSR0(n)			(0x188 + ((n) * 0x10))
+#define DDRP_ZQXSR1(n)			(0x18c + ((n) * 0x10))
+
+#define DDRP_DXGCR(n)			(0x1c0 + ((n) * 0x40))
+#define DDRP_DXGSR0(n)			(0x1c4 + ((n) * 0x40))
+#define DDRP_DXGSR1(n)			(0x1c8 + ((n) * 0x40))
+#define DDRP_DXDQSTR(n)			(0x1d4 + ((n) * 0x40))
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN			BIT(7)
+#define DDRC_ST_DPDN			BIT(5)
+#define DDRC_ST_PDN			BIT(4)
+#define DDRC_ST_AREF			BIT(3)
+#define DDRC_ST_SREF			BIT(2)
+#define DDRC_ST_CKE1			BIT(1)
+#define DDRC_ST_CKE0			BIT(0)
+
+/* DDRC Configure Register */
+#define DDRC_CFG_ROW1_BIT		27
+#define DDRC_CFG_ROW1_MASK		(0x7 << DDRC_CFG_ROW1_BIT)
+#define DDRC_CFG_COL1_BIT		24
+#define DDRC_CFG_COL1_MASK		(0x7 << DDRC_CFG_COL1_BIT)
+#define DDRC_CFG_BA1			BIT(23)
+#define DDRC_CFG_IMBA			BIT(22)
+#define DDRC_CFG_BL_8			BIT(21)
+
+#define DDRC_CFG_TYPE_BIT		17
+#define DDRC_CFG_TYPE_MASK		(0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1		(2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR		(3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2		(4 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_LPDDR2		(5 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR3		(6 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ODT_EN			BIT(16)
+
+#define DDRC_CFG_MPRT			BIT(15)
+
+#define DDRC_CFG_ROW_BIT		11
+#define DDRC_CFG_ROW_MASK		(0x7 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_12			(0 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_13			(1 << DDRC_CFG_ROW_BIT)
+#define DDRC_CFG_ROW_14			(2 << DDRC_CFG_ROW_BIT)
+
+#define DDRC_CFG_COL_BIT		8
+#define DDRC_CFG_COL_MASK		(0x7 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_8			(0 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_9			(1 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_10			(2 << DDRC_CFG_COL_BIT)
+#define DDRC_CFG_COL_11			(3 << DDRC_CFG_COL_BIT)
+
+#define DDRC_CFG_CS1EN			BIT(7)
+#define DDRC_CFG_CS0EN			BIT(6)
+#define DDRC_CFG_CL_BIT			2
+#define DDRC_CFG_CL_MASK		(0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3			(0 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_4			(1 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_5			(2 << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_6			(3 << DDRC_CFG_CL_BIT)
+
+#define DDRC_CFG_BA			BIT(1)
+#define DDRC_CFG_DW			BIT(0)
+
+/* DDRC Control Register */
+#define DDRC_CTRL_DFI_RST		BIT(23)
+#define DDRC_CTRL_DLL_RST		BIT(22)
+#define DDRC_CTRL_CTL_RST		BIT(21)
+#define DDRC_CTRL_CFG_RST		BIT(20)
+#define DDRC_CTRL_ACTPD			BIT(15)
+#define DDRC_CTRL_PDT_BIT		12
+#define DDRC_CTRL_PDT_MASK		(0x7 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_DIS		(0 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_8			(1 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_16		(2 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_32		(3 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_64		(4 << DDRC_CTRL_PDT_BIT)
+#define DDRC_CTRL_PDT_128		(5 << DDRC_CTRL_PDT_BIT)
+
+#define DDRC_CTRL_PRET_BIT		8
+#define DDRC_CTRL_PRET_MASK		(0x7 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_DIS		(0 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_8		(1 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_16		(2 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_32		(3 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_64		(4 << DDRC_CTRL_PRET_BIT)
+#define DDRC_CTRL_PRET_128		(5 << DDRC_CTRL_PRET_BIT)
+
+#define DDRC_CTRL_DPD			BIT(6)
+#define DDRC_CTRL_SR			BIT(5)
+#define DDRC_CTRL_UNALIGN		BIT(4)
+#define DDRC_CTRL_ALH			BIT(3)
+#define DDRC_CTRL_RDC			BIT(2)
+#define DDRC_CTRL_CKE			BIT(1)
+#define DDRC_CTRL_RESET			BIT(0)
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT		16
+#define DDRC_LMR_DDR_ADDR_MASK		(0x3fff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT			8
+#define DDRC_LMR_BA_MASK		(0x7 << DDRC_LMR_BA_BIT)
+/* For DDR2 */
+#define DDRC_LMR_BA_MRS			(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS1		(1 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS2		(2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_EMRS3		(3 << DDRC_LMR_BA_BIT)
+/* For mobile DDR */
+#define DDRC_LMR_BA_M_MRS		(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_EMRS		(2 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_M_SR		(1 << DDRC_LMR_BA_BIT)
+/* For Normal DDR1 */
+#define DDRC_LMR_BA_N_MRS		(0 << DDRC_LMR_BA_BIT)
+#define DDRC_LMR_BA_N_EMRS		(1 << DDRC_LMR_BA_BIT)
+
+#define DDRC_LMR_CMD_BIT		4
+#define DDRC_LMR_CMD_MASK		(0x3 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_PREC		(0 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_AUREF		(1 << DDRC_LMR_CMD_BIT)
+#define DDRC_LMR_CMD_LMR		(2 << DDRC_LMR_CMD_BIT)
+
+#define DDRC_LMR_START			BIT(0)
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRTP_BIT		24
+#define DDRC_TIMING1_TRTP_MASK		(0x3f << DDRC_TIMING1_TRTP_BIT)
+#define DDRC_TIMING1_TWTR_BIT		16
+#define DDRC_TIMING1_TWTR_MASK		(0x3f << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_1		(0 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_2		(1 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_3		(2 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWTR_4		(3 << DDRC_TIMING1_TWTR_BIT)
+#define DDRC_TIMING1_TWR_BIT		8
+#define DDRC_TIMING1_TWR_MASK		(0x3f << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_1		(0 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_2		(1 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_3		(2 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_4		(3 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_5		(4 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWR_6		(5 << DDRC_TIMING1_TWR_BIT)
+#define DDRC_TIMING1_TWL_BIT		0
+#define DDRC_TIMING1_TWL_MASK		(0x3f << DDRC_TIMING1_TWL_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TCCD_BIT		24
+#define DDRC_TIMING2_TCCD_MASK		(0x3f << DDRC_TIMING2_TCCD_BIT)
+#define DDRC_TIMING2_TRAS_BIT		16
+#define DDRC_TIMING2_TRAS_MASK		(0x3f << DDRC_TIMING2_TRAS_BIT)
+#define DDRC_TIMING2_TRCD_BIT		8
+#define DDRC_TIMING2_TRCD_MASK		(0x3f << DDRC_TIMING2_TRCD_BIT)
+#define DDRC_TIMING2_TRL_BIT		0
+#define DDRC_TIMING2_TRL_MASK		(0x3f << DDRC_TIMING2_TRL_BIT)
+
+/* DDRC Timing Config Register 3 */
+#define DDRC_TIMING3_ONUM		27
+#define DDRC_TIMING3_TCKSRE_BIT		24
+#define DDRC_TIMING3_TCKSRE_MASK	(0x3f << DDRC_TIMING3_TCKSRE_BIT)
+#define DDRC_TIMING3_TRP_BIT		16
+#define DDRC_TIMING3_TRP_MASK		(0x3f << DDRC_TIMING3_TRP_BIT)
+#define DDRC_TIMING3_TRRD_BIT		8
+#define DDRC_TIMING3_TRRD_MASK		(0x3f << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_DISABLE	(0 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_2		(1 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_3		(2 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRRD_4		(3 << DDRC_TIMING3_TRRD_BIT)
+#define DDRC_TIMING3_TRC_BIT		0
+#define DDRC_TIMING3_TRC_MASK		(0x3f << DDRC_TIMING3_TRC_BIT)
+
+/* DDRC Timing Config Register 4 */
+#define DDRC_TIMING4_TRFC_BIT		24
+#define DDRC_TIMING4_TRFC_MASK		(0x3f << DDRC_TIMING4_TRFC_BIT)
+#define DDRC_TIMING4_TEXTRW_BIT		21
+#define DDRC_TIMING4_TEXTRW_MASK	(0x7 << DDRC_TIMING4_TEXTRW_BIT)
+#define DDRC_TIMING4_TRWCOV_BIT		19
+#define DDRC_TIMING4_TRWCOV_MASK	(0x3 << DDRC_TIMING4_TRWCOV_BIT)
+#define DDRC_TIMING4_TCKE_BIT		16
+#define DDRC_TIMING4_TCKE_MASK		(0x7 << DDRC_TIMING4_TCKE_BIT)
+#define DDRC_TIMING4_TMINSR_BIT		8
+#define DDRC_TIMING4_TMINSR_MASK	(0xf << DDRC_TIMING4_TMINSR_BIT)
+#define DDRC_TIMING4_TXP_BIT		4
+#define DDRC_TIMING4_TXP_MASK		(0x7 << DDRC_TIMING4_TXP_BIT)
+#define DDRC_TIMING4_TMRD_BIT		0
+#define DDRC_TIMING4_TMRD_MASK		(0x3 << DDRC_TIMING4_TMRD_BIT)
+
+/* DDRC Timing Config Register 5 */
+#define DDRC_TIMING5_TCTLUPD_BIT	24
+#define DDRC_TIMING4_TCTLUPD_MASK	(0x3f << DDRC_TIMING5_TCTLUDP_BIT)
+#define DDRC_TIMING5_TRTW_BIT		16
+#define DDRC_TIMING5_TRTW_MASK		(0x3f << DDRC_TIMING5_TRTW_BIT)
+#define DDRC_TIMING5_TRDLAT_BIT		8
+#define DDRC_TIMING5_TRDLAT_MASK	(0x3f << DDRC_TIMING5_TRDLAT_BIT)
+#define DDRC_TIMING5_TWDLAT_BIT		0
+#define DDRC_TIMING5_TWDLAT_MASK	(0x3f << DDRC_TIMING5_TWDLAT_BIT)
+
+/* DDRC Timing Config Register 6 */
+#define DDRC_TIMING6_TXSRD_BIT		24
+#define DDRC_TIMING6_TXSRD_MASK		(0x3f << DDRC_TIMING6_TXSRD_BIT)
+#define DDRC_TIMING6_TFAW_BIT		16
+#define DDRC_TIMING6_TFAW_MASK		(0x3f << DDRC_TIMING6_TFAW_BIT)
+#define DDRC_TIMING6_TCFGW_BIT		8
+#define DDRC_TIMING6_TCFGW_MASK		(0x3f << DDRC_TIMING6_TCFGW_BIT)
+#define DDRC_TIMING6_TCFGR_BIT		0
+#define DDRC_TIMING6_TCFGR_MASK		(0x3f << DDRC_TIMING6_TCFGR_BIT)
+
+/* DDRC  Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT		16
+#define DDRC_REFCNT_CON_MASK		(0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT		8
+#define DDRC_REFCNT_CNT_MASK		(0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT		1
+#define DDRC_REFCNT_CLKDIV_MASK		(0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN		BIT(0)
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR			BIT(29)
+#define DDRC_DQS_READY			BIT(28)
+#define DDRC_DQS_AUTO			BIT(23)
+#define DDRC_DQS_DET			BIT(24)
+#define DDRC_DQS_SRDET			BIT(25)
+#define DDRC_DQS_CLKD_BIT		16
+#define DDRC_DQS_CLKD_MASK		(0x3f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT		8
+#define DDRC_DQS_WDQS_MASK		(0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT		0
+#define DDRC_DQS_RDQS_MASK		(0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT		8
+#define DDRC_DQS_ADJWDQS_MASK		(0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT		0
+#define DDRC_DQS_ADJRDQS_MASK		(0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT		8
+#define DDRC_MMAP_BASE_MASK		(0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT		0
+#define DDRC_MMAP_MASK_MASK		(0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE			(0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M		(0x24 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_128M		(0x28 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_256M		(0x30 << DDRC_MMAP_BASE_BIT)
+
+#define DDRC_MMAP_MASK_64_64		(0xfc << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_128_128		(0xf8 << DDRC_MMAP_MASK_BIT)
+#define DDRC_MMAP_MASK_256_256		(0xf0 << DDRC_MMAP_MASK_BIT)
+
+/* DDRP PHY Initialization Register */
+#define DDRP_PIR_INIT			BIT(0)
+#define DDRP_PIR_DLLSRST		BIT(1)
+#define DDRP_PIR_DLLLOCK		BIT(2)
+#define DDRP_PIR_ZCAL			BIT(3)
+#define DDRP_PIR_ITMSRST		BIT(4)
+#define DDRP_PIR_DRAMRST		BIT(5)
+#define DDRP_PIR_DRAMINT		BIT(6)
+#define DDRP_PIR_QSTRN			BIT(7)
+#define DDRP_PIR_EYETRN			BIT(8)
+#define DDRP_PIR_DLLBYP			BIT(17)
+/* DDRP PHY General Configurate Register */
+#define DDRP_PGCR_ITMDMD		BIT(0)
+#define DDRP_PGCR_DQSCFG		BIT(1)
+#define DDRP_PGCR_DFTCMP		BIT(2)
+#define DDRP_PGCR_DFTLMT_BIT		3
+#define DDRP_PGCR_DTOSEL_BIT		5
+#define DDRP_PGCR_CKEN_BIT		9
+#define DDRP_PGCR_CKDV_BIT		12
+#define DDRP_PGCR_CKINV			BIT(14)
+#define DDRP_PGCR_RANKEN_BIT		18
+#define DDRP_PGCR_ZCKSEL_32		(2 << 22)
+#define DDRP_PGCR_PDDISDX		BIT(24)
+/* DDRP PHY General Status Register */
+#define DDRP_PGSR_IDONE			BIT(0)
+#define DDRP_PGSR_DLDONE		BIT(1)
+#define DDRP_PGSR_ZCDONE		BIT(2)
+#define DDRP_PGSR_DIDONE		BIT(3)
+#define DDRP_PGSR_DTDONE		BIT(4)
+#define DDRP_PGSR_DTERR			BIT(5)
+#define DDRP_PGSR_DTIERR		BIT(6)
+#define DDRP_PGSR_DFTEERR		BIT(7)
+/* DDRP DRAM Configuration Register */
+#define DDRP_DCR_TYPE_BIT		0
+#define DDRP_DCR_TYPE_MASK		(0x7 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_MDDR		(0 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR		(1 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR2		(2 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_DDR3		(3 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_TYPE_LPDDR2		(4 << DDRP_DCR_TYPE_BIT)
+#define DDRP_DCR_DDR8BNK_BIT		3
+#define DDRP_DCR_DDR8BNK_MASK		(1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK		(1 << DDRP_DCR_DDR8BNK_BIT)
+#define DDRP_DCR_DDR8BNK_DIS		(0 << DDRP_DCR_DDR8BNK_BIT)
+
+#define DRP_DTRP1_RTODT			BIT(11)
+
+#define DDRP_DXGCR_DXEN			BIT(0)
+
+#define DDRP_ZQXCR_ZDEN_BIT		28
+#define DDRP_ZQXCR_ZDEN			(1 << DDRP_ZQXCR_ZDEN_BIT)
+#define DDRP_ZQXCR_PULLUP_IMPE_BIT	5
+#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT	0
+
+/* DDR3 Mode Register Set */
+#define DDR3_MR0_BL_BIT			0
+#define DDR3_MR0_BL_MASK		(3 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_8			(0 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_fly			(1 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BL_4			(2 << DDR3_MR0_BL_BIT)
+#define DDR3_MR0_BT_BIT			3
+#define DDR3_MR0_BT_MASK		(1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_SEQ			(0 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_BT_INTER		(1 << DDR3_MR0_BT_BIT)
+#define DDR3_MR0_WR_BIT			9
+
+#define DDR3_MR1_DLL_DISABLE		1
+#define DDR3_MR1_DIC_6			(0 << 5 | 0 << 1)
+#define DDR3_MR1_DIC_7			(0 << 5 | BIT(1))
+#define DDR3_MR1_RTT_DIS		(0 << 9 | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_4			(0 << 9 | 0 << 6 | BIT(2))
+#define DDR3_MR1_RTT_2			(0 << 9 | BIT(6) | 0 << 2)
+#define DDR3_MR1_RTT_6			(0 << 9 | BIT(6) | BIT(2))
+#define DDR3_MR1_RTT_12			(BIT(9) | 0 << 6 | 0 << 2)
+#define DDR3_MR1_RTT_8			(BIT(9) | 0 << 6 | BIT(2))
+
+#define DDR3_MR2_CWL_BIT		3
+
+/* Paramters common to all RAM devices used */
+
+/* Chip Select */
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS0EN	1
+/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */
+#define DDR_CS1EN	0
+
+/* ROW : 12 to 18 row address, 1G only 512MB */
+#define DDR_ROW		15
+/* COL :  8 to 14 column address */
+#define DDR_COL		10
+/* Banks each chip: 0-4bank, 1-8bank */
+#define DDR_BANK8	1
+/* 0 - 16-bit data width, 1 - 32-bit data width */
+#define DDR_DW32	1
+
+/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */
+#define DDR_tREFI	7800
+/* Clock Divider */
+#define DDR_CLK_DIV	1
+
+/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */
+#define DDR_BL		8
+
+/* CAS latency: 5 to 14, tCK */
+#define DDR_CL		6
+/* DDR3 only: CAS Write Latency, 5 to 8 */
+#define DDR_tCWL	(DDR_CL - 1)
+
+/* Structure representing per-RAM type configuration */
+
+struct jz4780_ddr_config {
+	u32	timing[6];	/* Timing1..6 register value */
+
+	/* DDR PHY control */
+	u16	mr0;	/* Mode Register 0 */
+	u16	mr1;	/* Mode Register 1 */
+
+	u32	ptr0;	/* PHY Timing Register 0 */
+	u32	ptr1;	/* PHY Timing Register 1 */
+	u32	ptr2;	/* PHY Timing Register 1 */
+
+	u32	dtpr0;	/* DRAM Timing Parameters Register 0 */
+	u32	dtpr1;	/* DRAM Timing Parameters Register 1 */
+	u32	dtpr2;	/* DRAM Timing Parameters Register 2 */
+
+	u8	pullup;	/* PHY pullup impedance */
+	u8	pulldn;	/* PHY pulldown impedance */
+};
+
+void pll_init(void);
+void sdram_init(void);
+
+#endif	/* __JZ4780_DRAM_H__ */
+
diff --git a/arch/mips/mach-jz47xx/jz4780/Makefile b/arch/mips/mach-jz47xx/jz4780/Makefile
new file mode 100644
index 0000000..683eea6
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y := jz4780.o pll.o sdram.o timer.o
diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c
new file mode 100644
index 0000000..21707cc
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c
@@ -0,0 +1,135 @@
+/*
+ * JZ4780 common routines
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+#include <spl.h>
+
+#ifdef CONFIG_SPL_BUILD
+/* Pointer to the global data structure for SPL */
+DECLARE_GLOBAL_DATA_PTR;
+gd_t gdata __attribute__ ((section(".bss")));
+
+/* NOTE: The SRAM in JZ4780 is too small and full memset() doesn't fit */
+static void bzero(char *dst, u32 len)
+{
+	while (len--)
+		*dst = 0;
+}
+
+void board_init_f(ulong dummy)
+{
+	struct spl_image_info spl_image;
+	struct spl_boot_device bootdev = { .boot_device = BOOT_DEVICE_MMC1 };
+	/* Set global data pointer */
+	gd = &gdata;
+
+	timer_init();
+	pll_init();
+	sdram_init();
+	enable_caches();
+
+	/* Clear the BSS */
+	bzero(__bss_start, (char *)&__bss_end - __bss_start);
+
+	gd->flags |= GD_FLG_SPL_INIT;
+
+	spl_mmc_load_image(&spl_image, &bootdev);
+
+	jump_to_image_no_args(&spl_image);
+}
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+	return MMCSD_MODE_RAW;
+}
+#endif /* CONFIG_SPL_BUILD */
+
+phys_size_t initdram(int board_type)
+{
+	return sdram_size(0) + sdram_size(1);
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
+}
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   Ingenic JZ4780\n");
+	return 0;
+}
+
+/* WDT */
+#define WDT_TDR		0x00
+#define WDT_TCER	0x04
+#define WDT_TCNT	0x08
+#define WDT_TCSR	0x0C
+
+/* Register definition */
+#define WDT_TCSR_PRESCALE_BIT	3
+#define WDT_TCSR_PRESCALE_MASK	(0x7 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1	(0x0 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE4	(0x1 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE16	(0x2 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE64	(0x3 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE256	(0x4 << WDT_TCSR_PRESCALE_BIT)
+  #define WDT_TCSR_PRESCALE1024	(0x5 << WDT_TCSR_PRESCALE_BIT)
+#define WDT_TCSR_EXT_EN		BIT(2)
+#define WDT_TCSR_RTC_EN		BIT(1)
+#define WDT_TCSR_PCK_EN		BIT(0)
+
+#define WDT_TCER_TCEN		BIT(0)
+
+void _machine_restart(void)
+{
+	void __iomem *wdt_regs = (void __iomem *)WDT_BASE;
+
+	mdelay(100);
+
+	/*
+	 * Select the EXTAL as the timer clock input, and make each
+	 * WDT clock tick equal 4 ticks of the system clock.
+	 */
+	writew(WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR);
+
+	/* Reset the WDT counter to zero. */
+	writew(0, wdt_regs + WDT_TCNT);
+
+	/*
+	 * Reset after 4ms
+	 *
+	 *         1 sec    CONFIG_SYS_EXTAL ticks
+	 *  4ms * ------- * ---------------------- = Number of WDT clock ticks
+	 *        1000 ms           1 sec
+	 *
+	 * As noted above the number of system clock ticks have been
+	 * effectively multiplied by 4.  All that's left here for the
+	 * computation of WDT clock ticks is to divide by 1000
+	 * (one thousand).
+	 */
+	writew(CONFIG_SYS_EXTAL / 1000, wdt_regs + WDT_TDR);
+
+	jz4780_tcu_wdt_start();
+
+	/* WDT start */
+	writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER);
+
+	for (;;)
+		;
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/pll.c b/arch/mips/mach-jz47xx/jz4780/pll.c
new file mode 100644
index 0000000..e1eabfa
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/pll.c
@@ -0,0 +1,527 @@
+/*
+ * JZ4780 PLL setup
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+
+#define CPM_CPCCR		0x00
+#define CPM_LCR			0x04
+#define CPM_RSR			0x08
+#define CPM_CPPCR		0x0c
+#define CPM_CPAPCR		0x10
+#define CPM_CPMPCR		0x14
+#define CPM_CPEPCR		0x18
+#define CPM_CPVPCR		0x1c
+#define CPM_CLKGR0		0x20
+#define CPM_OPCR		0x24
+#define CPM_CLKGR1		0x28
+#define CPM_DDCDR		0x2c
+#define CPM_VPUCDR		0x30
+#define CPM_CPSPR		0x34
+#define CPM_CPSPPR		0x38
+#define CPM_USBPCR		0x3c
+#define CPM_USBRDT		0x40
+#define CPM_USBVBFIL		0x44
+#define CPM_USBPCR1		0x48
+#define CPM_USBCDR		0x50
+#define CPM_LPCDR		0x54
+#define CPM_I2SCDR		0x60
+#define CPM_LPCDR1		0x64
+#define CPM_MSCCDR		0x68
+#define CPM_UHCCDR		0x6c
+#define CPM_SSICDR		0x74
+#define CPM_CIMCDR		0x7c
+#define CPM_PCMCDR		0x84
+#define CPM_GPUCDR		0x88
+#define CPM_HDMICDR		0x8c
+#define CPM_I2S1CDR		0xa0
+#define CPM_MSCCDR1		0xa4
+#define CPM_MSCCDR2		0xa8
+#define CPM_BCHCDR		0xac
+#define CPM_SPCR0		0xb8
+#define CPM_SPCR1		0xbc
+#define CPM_CPCSR		0xd4
+#define CPM_PSWCST(n)		((0x4 * (n)) + 0x90)
+
+/* Clock control register */
+#define CPM_CPCCR_SEL_SRC_BIT		30
+#define CPM_CPCCR_SEL_SRC_MASK		(0x3 << CPM_CPCCR_SEL_SRC_BIT)
+#define CPM_SRC_SEL_STOP		0
+#define CPM_SRC_SEL_APLL		1
+#define CPM_SRC_SEL_EXCLK		2
+#define CPM_SRC_SEL_RTCLK		3
+#define CPM_CPCCR_SEL_CPLL_BIT		28
+#define CPM_CPCCR_SEL_CPLL_MASK		(0x3 << CPM_CPCCR_SEL_CPLL_BIT)
+#define CPM_CPCCR_SEL_H0PLL_BIT		26
+#define CPM_CPCCR_SEL_H0PLL_MASK	(0x3 << CPM_CPCCR_SEL_H0PLL_BIT)
+#define CPM_CPCCR_SEL_H2PLL_BIT		24
+#define CPM_CPCCR_SEL_H2PLL_MASK	(0x3 << CPM_CPCCR_SEL_H2PLL_BIT)
+#define CPM_PLL_SEL_STOP		0
+#define CPM_PLL_SEL_SRC			1
+#define CPM_PLL_SEL_MPLL		2
+#define CPM_PLL_SEL_EPLL		3
+#define CPM_CPCCR_CE_CPU		(0x1 << 22)
+#define CPM_CPCCR_CE_AHB0		(0x1 << 21)
+#define CPM_CPCCR_CE_AHB2		(0x1 << 20)
+#define CPM_CPCCR_PDIV_BIT		16
+#define CPM_CPCCR_PDIV_MASK		(0xf << CPM_CPCCR_PDIV_BIT)
+#define CPM_CPCCR_H2DIV_BIT		12
+#define CPM_CPCCR_H2DIV_MASK		(0xf << CPM_CPCCR_H2DIV_BIT)
+#define CPM_CPCCR_H0DIV_BIT		8
+#define CPM_CPCCR_H0DIV_MASK		(0x0f << CPM_CPCCR_H0DIV_BIT)
+#define CPM_CPCCR_L2DIV_BIT		4
+#define CPM_CPCCR_L2DIV_MASK		(0x0f << CPM_CPCCR_L2DIV_BIT)
+#define CPM_CPCCR_CDIV_BIT		0
+#define CPM_CPCCR_CDIV_MASK		(0x0f << CPM_CPCCR_CDIV_BIT)
+
+/* Clock Status register */
+#define CPM_CPCSR_H2DIV_BUSY		BIT(2)
+#define CPM_CPCSR_H0DIV_BUSY		BIT(1)
+#define CPM_CPCSR_CDIV_BUSY		BIT(0)
+
+/* PLL control register */
+#define CPM_CPPCR_PLLST_BIT		0
+#define CPM_CPPCR_PLLST_MASK		(0xff << CPM_CPPCR_PLLST_BIT)
+
+/* XPLL control register */
+#define CPM_CPXPCR_XPLLM_BIT		19
+#define CPM_CPXPCR_XPLLM_MASK		(0x1fff << CPM_CPXPCR_XPLLM_BIT)
+#define CPM_CPXPCR_XPLLN_BIT		13
+#define CPM_CPXPCR_XPLLN_MASK		(0x3f << CPM_CPXPCR_XPLLN_BIT)
+#define CPM_CPXPCR_XPLLOD_BIT		9
+#define CPM_CPXPCR_XPLLOD_MASK		(0xf << CPM_CPXPCR_XPLLOD_BIT)
+#define CPM_CPXPCR_XLOCK		BIT(6)
+#define CPM_CPXPCR_XPLL_ON		BIT(4)
+#define CPM_CPXPCR_XF_MODE		BIT(3)
+#define CPM_CPXPCR_XPLLBP		BIT(1)
+#define CPM_CPXPCR_XPLLEN		BIT(0)
+
+/* CPM scratch protected register */
+#define CPM_CPSPPR_BIT			0
+#define CPM_CPSPPR_MASK			(0xffff << CPM_CPSPPR_BIT)
+
+/* USB parameter control register */
+#define CPM_USBPCR_USB_MODE		BIT(31)  /* 1: OTG, 0: UDC*/
+#define CPM_USBPCR_AVLD_REG		BIT(30)
+#define CPM_USBPCR_IDPULLUP_MASK_BIT	28
+#define CPM_USBPCR_IDPULLUP_MASK_MASK	(0x02 << IDPULLUP_MASK_BIT)
+#define CPM_USBPCR_INCR_MASK		BIT(27)
+#define CPM_USBPCR_CLK12_EN		BIT(26)
+#define CPM_USBPCR_COMMONONN		BIT(25)
+#define CPM_USBPCR_VBUSVLDEXT		BIT(24)
+#define CPM_USBPCR_VBUSVLDEXTSEL	BIT(23)
+#define CPM_USBPCR_POR			BIT(22)
+#define CPM_USBPCR_SIDDQ		BIT(21)
+#define CPM_USBPCR_OTG_DISABLE		BIT(20)
+#define CPM_USBPCR_COMPDISTUNE_BIT	17
+#define CPM_USBPCR_COMPDISTUNE_MASK	(0x07 << COMPDISTUNE_BIT)
+#define CPM_USBPCR_OTGTUNE_BIT		14
+#define CPM_USBPCR_OTGTUNE_MASK		(0x07 << OTGTUNE_BIT)
+#define CPM_USBPCR_SQRXTUNE_BIT		11
+#define CPM_USBPCR_SQRXTUNE_MASK	(0x7x << SQRXTUNE_BIT)
+#define CPM_USBPCR_TXFSLSTUNE_BIT	7
+#define CPM_USBPCR_TXFSLSTUNE_MASK	(0x0f << TXFSLSTUNE_BIT)
+#define CPM_USBPCR_TXPREEMPHTUNE	BIT(6)
+#define CPM_USBPCR_TXRISETUNE_BIT	4
+#define CPM_USBPCR_TXRISETUNE_MASK	(0x03 << TXRISETUNE_BIT)
+#define CPM_USBPCR_TXVREFTUNE_BIT	0
+#define CPM_USBPCR_TXVREFTUNE_MASK	(0x0f << TXVREFTUNE_BIT)
+
+/* DDR memory clock divider register */
+#define CPM_DDRCDR_DCS_BIT		30
+#define CPM_DDRCDR_DCS_MASK		(0x3 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_STOP		(0x0 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_SRC		(0x1 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_DCS_MPLL		(0x2 << CPM_DDRCDR_DCS_BIT)
+#define CPM_DDRCDR_CE_DDR		BIT(29)
+#define CPM_DDRCDR_DDR_BUSY		BIT(28)
+#define CPM_DDRCDR_DDR_STOP		BIT(27)
+#define CPM_DDRCDR_DDRDIV_BIT		0
+#define CPM_DDRCDR_DDRDIV_MASK		(0xf << CPM_DDRCDR_DDRDIV_BIT)
+
+/* USB reset detect timer register */
+#define CPM_USBRDT_VBFIL_LD_EN		BIT(25)
+#define CPM_USBRDT_IDDIG_EN		BIT(24)
+#define CPM_USBRDT_IDDIG_REG		BIT(23)
+#define CPM_USBRDT_USBRDT_BIT		0
+#define CPM_USBRDT_USBRDT_MASK		(0x7fffff << CPM_USBRDT_USBRDT_BIT)
+
+/* USB OTG PHY clock divider register */
+#define CPM_USBCDR_UCS			BIT(31)
+#define CPM_USBCDR_UPCS			BIT(30)
+#define CPM_USBCDR_CEUSB		BIT(29)
+#define CPM_USBCDR_USB_BUSY		BIT(28)
+#define CPM_USBCDR_OTGDIV_BIT		0
+#define CPM_USBCDR_OTGDIV_MASK		(0xff << CPM_USBCDR_OTGDIV_BIT)
+
+/* I2S device clock divider register */
+#define CPM_I2SCDR_I2CS			BIT(31)
+#define CPM_I2SCDR_I2PCS		BIT(30)
+#define CPM_I2SCDR_I2SDIV_BIT		0
+#define CPM_I2SCDR_I2SDIV_MASK		(0x1ff << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD0 pix clock divider register */
+#define CPM_LPCDR_LPCS_BIT		30
+#define CPM_LPCDR_LPCS_MASK		(0x3 << CPM_LPCDR_LPCS_BIT)
+#define CPM_LPCDR_CELCD			BIT(28)
+#define CPM_LPCDR_LCD_BUSY		BIT(27)
+#define CPM_LPCDR_LCD_STOP		BIT(26)
+#define CPM_LPCDR_PIXDIV_BIT		0
+#define CPM_LPCDR_PIXDIV_MASK		(0xff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC clock divider register */
+#define CPM_MSCCDR_MPCS_BIT		30
+#define CPM_MSCCDR_MPCS_MASK		(3 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_STOP		(0x0 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_SRC		(0x1 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_MPCS_MPLL		(0x2 << CPM_MSCCDR_MPCS_BIT)
+#define CPM_MSCCDR_CE			BIT(29)
+#define CPM_MSCCDR_MSC_BUSY		BIT(28)
+#define CPM_MSCCDR_MSC_STOP		BIT(27)
+#define CPM_MSCCDR_MSC_CLK0_SEL		BIT(15)
+#define CPM_MSCCDR_MSCDIV_BIT		0
+#define CPM_MSCCDR_MSCDIV_MASK		(0xff << CPM_MSCCDR_MSCDIV_BIT)
+
+/* UHC 48M clock divider register */
+#define CPM_UHCCDR_UHCS_BIT		30
+#define CPM_UHCCDR_UHCS_MASK		(0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_SRC		(0x0 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_MPLL		(0x1 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_EPLL		(0x2 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_UHCS_OTG		(0x3 << CPM_UHCCDR_UHCS_BIT)
+#define CPM_UHCCDR_CE_UHC		BIT(29)
+#define CPM_UHCCDR_UHC_BUSY		BIT(28)
+#define CPM_UHCCDR_UHC_STOP		BIT(27)
+#define CPM_UHCCDR_UHCDIV_BIT		0
+#define CPM_UHCCDR_UHCDIV_MASK		(0xff << CPM_UHCCDR_UHCDIV_BIT)
+
+/* SSI clock divider register */
+#define CPM_SSICDR_SCS			BIT(31)
+#define CPM_SSICDR_SSIDIV_BIT		0
+#define CPM_SSICDR_SSIDIV_MASK		(0x3f << CPM_SSICDR_SSIDIV_BIT)
+
+/* CIM MCLK clock divider register */
+#define CPM_CIMCDR_CIMDIV_BIT		0
+#define CPM_CIMCDR_CIMDIV_MASK		(0xff << CPM_CIMCDR_CIMDIV_BIT)
+
+/* GPS clock divider register */
+#define CPM_GPSCDR_GPCS			BIT(31)
+#define CPM_GPSCDR_GPSDIV_BIT		0
+#define CPM_GSPCDR_GPSDIV_MASK		(0xf << CPM_GPSCDR_GPSDIV_BIT)
+
+/* PCM device clock divider register */
+#define CPM_PCMCDR_PCMS			BIT(31)
+#define CPM_PCMCDR_PCMPCS		BIT(30)
+#define CPM_PCMCDR_PCMDIV_BIT		0
+#define CPM_PCMCDR_PCMDIV_MASK		(0x1ff << CPM_PCMCDR_PCMDIV_BIT)
+
+/* GPU clock divider register */
+#define CPM_GPUCDR_GPCS			BIT(31)
+#define CPM_GPUCDR_GPUDIV_BIT		0
+#define CPM_GPUCDR_GPUDIV_MASK		(0x7 << CPM_GPUCDR_GPUDIV_BIT)
+
+/* HDMI clock divider register */
+#define CPM_HDMICDR_HPCS_BIT		30
+#define CPM_HDMICDR_HPCS_MASK		(0x3 << CPM_HDMICDR_HPCS_BIT)
+#define CPM_HDMICDR_CEHDMI		BIT(29)
+#define CPM_HDMICDR_HDMI_BUSY		BIT(28)
+#define CPM_HDMICDR_HDMI_STOP		BIT(26)
+#define CPM_HDMICDR_HDMIDIV_BIT		0
+#define CPM_HDMICDR_HDMIDIV_MASK	(0xff << CPM_HDMICDR_HDMIDIV_BIT)
+
+/* Low Power Control Register */
+#define CPM_LCR_PD_SCPU			BIT(31)
+#define CPM_LCR_PD_VPU			BIT(30)
+#define CPM_LCR_PD_GPU			BIT(29)
+#define CPM_LCR_PD_GPS			BIT(28)
+#define CPM_LCR_SCPUS			BIT(27)
+#define CPM_LCR_VPUS			BIT(26)
+#define CPM_LCR_GPUS			BIT(25)
+#define CPM_LCR_GPSS			BIT(24)
+#define CPM_LCR_GPU_IDLE		BIT(20)
+#define CPM_LCR_PST_BIT			8
+#define CPM_LCR_PST_MASK		(0xfff << CPM_LCR_PST_BIT)
+#define CPM_LCR_DOZE_DUTY_BIT		3
+#define CPM_LCR_DOZE_DUTY_MASK		(0x1f << CPM_LCR_DOZE_DUTY_BIT)
+#define CPM_LCR_DOZE_ON			BIT(2)
+#define CPM_LCR_LPM_BIT			0
+#define CPM_LCR_LPM_MASK		(0x3 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_IDLE		(0x0 << CPM_LCR_LPM_BIT)
+#define CPM_LCR_LPM_SLEEP		(0x1 << CPM_LCR_LPM_BIT)
+
+/* Clock Gate Register0 */
+#define CPM_CLKGR0_DDR1			BIT(31)
+#define CPM_CLKGR0_DDR0			BIT(30)
+#define CPM_CLKGR0_IPU			BIT(29)
+#define CPM_CLKGR0_LCD1			BIT(28)
+#define CPM_CLKGR0_LCD			BIT(27)
+#define CPM_CLKGR0_CIM			BIT(26)
+#define CPM_CLKGR0_I2C2			BIT(25)
+#define CPM_CLKGR0_UHC			BIT(24)
+#define CPM_CLKGR0_MAC			BIT(23)
+#define CPM_CLKGR0_GPS			BIT(22)
+#define CPM_CLKGR0_PDMAC		BIT(21)
+#define CPM_CLKGR0_SSI2			BIT(20)
+#define CPM_CLKGR0_SSI1			BIT(19)
+#define CPM_CLKGR0_UART3		BIT(18)
+#define CPM_CLKGR0_UART2		BIT(17)
+#define CPM_CLKGR0_UART1		BIT(16)
+#define CPM_CLKGR0_UART0		BIT(15)
+#define CPM_CLKGR0_SADC			BIT(14)
+#define CPM_CLKGR0_KBC			BIT(13)
+#define CPM_CLKGR0_MSC2			BIT(12)
+#define CPM_CLKGR0_MSC1			BIT(11)
+#define CPM_CLKGR0_OWI			BIT(10)
+#define CPM_CLKGR0_TSSI			BIT(9)
+#define CPM_CLKGR0_AIC			BIT(8)
+#define CPM_CLKGR0_SCC			BIT(7)
+#define CPM_CLKGR0_I2C1			BIT(6)
+#define CPM_CLKGR0_I2C0			BIT(5)
+#define CPM_CLKGR0_SSI0			BIT(4)
+#define CPM_CLKGR0_MSC0			BIT(3)
+#define CPM_CLKGR0_OTG			BIT(2)
+#define CPM_CLKGR0_BCH			BIT(1)
+#define CPM_CLKGR0_NEMC			BIT(0)
+
+/* Clock Gate Register1 */
+#define CPM_CLKGR1_P1			BIT(15)
+#define CPM_CLKGR1_X2D			BIT(14)
+#define CPM_CLKGR1_DES			BIT(13)
+#define CPM_CLKGR1_I2C4			BIT(12)
+#define CPM_CLKGR1_AHB			BIT(11)
+#define CPM_CLKGR1_UART4		BIT(10)
+#define CPM_CLKGR1_HDMI			BIT(9)
+#define CPM_CLKGR1_OTG1			BIT(8)
+#define CPM_CLKGR1_GPVLC		BIT(7)
+#define CPM_CLKGR1_AIC1			BIT(6)
+#define CPM_CLKGR1_COMPRES		BIT(5)
+#define CPM_CLKGR1_GPU			BIT(4)
+#define CPM_CLKGR1_PCM			BIT(3)
+#define CPM_CLKGR1_VPU			BIT(2)
+#define CPM_CLKGR1_TSSI1		BIT(1)
+#define CPM_CLKGR1_I2C3			BIT(0)
+
+/* Oscillator and Power Control Register */
+#define CPM_OPCR_O1ST_BIT		8
+#define CPM_OPCR_O1ST_MASK		(0xff << CPM_OPCR_O1ST_BIT)
+#define CPM_OPCR_SPENDN			BIT(7)
+#define CPM_OPCR_GPSEN			BIT(6)
+#define CPM_OPCR_SPENDH			BIT(5)
+#define CPM_OPCR_O1SE			BIT(4)
+#define CPM_OPCR_ERCS			BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+#define CPM_OPCR_USBM			BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */
+
+/* Reset Status Register */
+#define CPM_RSR_P0R			BIT(2)
+#define CPM_RSR_WR			BIT(1)
+#define CPM_RSR_PR			BIT(0)
+
+/* BCH clock divider register */
+#define CPM_BCHCDR_BPCS_BIT		30
+#define CPM_BCHCDR_BPCS_MASK		(0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_STOP		(0X0 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_SRC_CLK		(0x1 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_MPLL		(0x2 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_BPCS_EPLL		(0x3 << CPM_BCHCDR_BPCS_BIT)
+#define CPM_BCHCDR_CE_BCH		BIT(29)
+#define CPM_BCHCDR_BCH_BUSY		BIT(28)
+#define CPM_BCHCDR_BCH_STOP		BIT(27)
+#define CPM_BCHCDR_BCHCDR_BIT		0
+#define CPM_BCHCDR_BCHCDR_MASK		(0x7 << CPM_BCHCDR_BCHCDR_BIT)
+
+/* CPM scratch pad protected register(CPSPPR) */
+#define CPSPPR_CPSPR_WRITABLE		0x00005a5a
+#define RECOVERY_SIGNATURE		0x1a1a	/* means "RECY" */
+#define RECOVERY_SIGNATURE_SEC		0x800	/* means "RECY" */
+
+#define REBOOT_SIGNATURE		0x3535	/* means reboot */
+
+/* XPLL control register */
+#define XLOCK		(1 << 6)
+#define XPLL_ON		(1 << 4)
+#define XF_MODE		(1 << 3)
+#define XPLLBP		(1 << 1)
+#define XPLLEN		(1 << 0)
+
+enum PLLS {
+	EXTCLK = 0,
+	APLL,
+	MPLL,
+	EPLL,
+	VPLL,
+};
+
+#define M_N_OD(m,n,od)		\
+		((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9))
+
+struct cgu_pll_select {
+	u8	reg;
+	u8	pll;
+	u8	pll_shift;
+};
+
+static void pll_init_one(int pll, int m, int n, int od)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4);
+
+	setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN);
+
+	/* FIXME */
+	while (!(readl(pll_reg) & XPLL_ON))
+		;
+}
+
+static void cpu_mux_select(int pll)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 clk_ctrl;
+	unsigned int selectplls[] = {
+		CPM_PLL_SEL_STOP,
+		CPM_PLL_SEL_SRC,
+		CPM_PLL_SEL_MPLL,
+		CPM_PLL_SEL_EPLL
+	};
+
+	/* Init CPU, L2CACHE, AHB0, AHB2, APB clock */
+	clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 |
+			((6 - 1) << CPM_CPCCR_H2DIV_BIT) |
+			((3 - 1) << CPM_CPCCR_H0DIV_BIT) |
+			((2 - 1) << CPM_CPCCR_L2DIV_BIT) |
+			((1 - 1) << CPM_CPCCR_CDIV_BIT);
+
+	if (CONFIG_SYS_MHZ >= 1000)
+		clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT;
+	else
+		clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT;
+
+	clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl);
+
+	/* FIXME */
+	while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY | CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY));
+
+	clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) |
+		   (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) |
+		   (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT);
+	if (pll == APLL)
+		clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT;
+	else
+		clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT;
+
+	clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl);
+}
+
+static void ddr_mux_select(int pll)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	int selectplls[] = { CPM_DDRCDR_DCS_STOP,
+			     CPM_DDRCDR_DCS_SRC,
+			     CPM_DDRCDR_DCS_MPLL};
+
+	writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (CONFIG_SYS_MEM_DIV - 1),
+	       cpm_regs + CPM_DDCDR);
+
+	while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY)
+		;
+
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0);
+
+	mdelay(200);
+}
+
+static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	unsigned int selectplls[] = {0, 1, 2, 3, 2, 6};
+	int i;
+
+	for (i = 0; i < num; i++)
+		writel(selectplls[cgu[i].pll] << cgu[i].pll_shift,
+		       cpm_regs + cgu[i].reg);
+}
+
+void pll_init(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	struct cgu_pll_select cgu_mux[] = {
+		{ CPM_MSCCDR,  MPLL, 30 },
+		{ CPM_LPCDR,   VPLL, 30 },
+		{ CPM_LPCDR1,  VPLL, 30 },
+		{ CPM_GPUCDR,  MPLL, 30 },
+		{ CPM_HDMICDR, VPLL, 30 },
+		{ CPM_I2SCDR,  EPLL, 30 },
+		{ CPM_BCHCDR,  MPLL, 30 },
+		{ CPM_VPUCDR,  0x1,  30 },
+		{ CPM_UHCCDR,  0x3,  30 },
+		{ CPM_CIMCDR,  0x1,  31 },
+		{ CPM_PCMCDR,  0x5,  29 },
+		{ CPM_SSICDR,  0x3,  30 },
+	};
+
+	/* PLL stable time set to default -- 1ms */
+	clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20);
+
+	pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD);
+	pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD);
+	pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD);
+	pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD);
+
+	cpu_mux_select(MPLL);
+	ddr_mux_select(MPLL);
+	cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux));
+}
+
+const u32 jz4780_clk_get_efuse_clk(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 cpccr = readl(cpm_regs + CPM_CPCCR);
+	u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >>
+			CPM_CPCCR_H2DIV_BIT) + 1;
+	return CONFIG_SYS_MEM_SPEED / ahb2_div;
+}
+
+void jz4780_clk_ungate_ethernet(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC);
+	clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC);
+}
+
+void jz4780_clk_ungate_mmc(void)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 msc_cdr = CONFIG_SYS_MEM_SPEED / 24000000 / 2 - 1;
+	msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE;
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR);
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR1);
+	writel(msc_cdr, cpm_regs + CPM_MSCCDR2);
+
+	/* The wait_for_bit() won't fit, thus unbounded loop here. */
+	while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY)
+		;
+}
+
+void jz4780_clk_ungate_uart(const unsigned int uart)
+{
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	if (uart == 0)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0);
+	else if (uart == 1)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1);
+	else if (uart == 2)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2);
+	else if (uart == 3)
+		clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3);
+	else if (uart == 4)
+		clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4);
+	else
+		printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/sdram.c b/arch/mips/mach-jz47xx/jz4780/sdram.c
new file mode 100644
index 0000000..3467ae6
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/sdram.c
@@ -0,0 +1,271 @@
+/*
+ * JZ4780 DDR initialization
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot
+ * Copyright (c) 2006-2013 Ingenic Semiconductor
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+
+static const u32 get_mem_clk(void)
+{
+	const u32 mpll_out = ((u64)CONFIG_SYS_EXTAL * JZ4780_MPLL_M) /
+			     (JZ4780_MPLL_N * JZ4780_MPLL_OD);
+	return mpll_out / CONFIG_SYS_MEM_DIV;
+}
+
+u32 sdram_size(int cs)
+{
+	u32 dw = DDR_DW32 ? 4 : 2;
+	u32 banks = DDR_BANK8 ? 8 : 4;
+	u32 size = 0;
+
+	if ((cs == 0) && DDR_CS0EN) {
+		size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+		if (DDR_CS1EN && (size > 0x20000000))
+			size = 0x20000000;
+	} else if ((cs == 1) && DDR_CS1EN) {
+		size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
+	}
+
+	return size;
+}
+
+static void ddr_cfg_init(void)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	u32 ddrc_cfg, tmp;
+
+	tmp = DDR_CL;
+	if (tmp)
+		tmp--;
+	if (tmp > 4)
+		tmp = 4;
+
+	ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA |
+		   DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) |
+		   ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) |
+		   (DDR_CS0EN << 6) | (DDR_BANK8 << 1) |
+		   ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) |
+		   (DDR_CS1EN << 7) | (DDR_BANK8 << 23);
+
+	if (DDR_BL > 4)
+		ddrc_cfg |= BIT(21);
+
+	writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG);
+}
+
+static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+	unsigned int count = 0, i;
+	u32 reg, mask;
+
+	writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR);
+
+	writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0);
+	writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1);
+	writel(0, ddr_phy_regs + DDRP_ODTCR);
+	writel(0, ddr_phy_regs + DDRP_MR2);
+
+	writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0);
+	writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1);
+	writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2);
+
+	writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0);
+	writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1);
+	writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2);
+
+	writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) |
+	       (2 << DDRP_PGCR_CKDV_BIT) |
+	       (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT |
+	       DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX,
+	       ddr_phy_regs + DDRP_PGCR);
+
+	for (i = 0; i < 8; i++)
+		clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9);
+
+	count = 0;
+	mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if ((reg == mask) || (reg == 0x1f))
+			break;
+		if (count++ == 10000)
+			hang();
+	}
+
+	/* DQS extension and early set to 1 */
+	clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4);
+
+	/* 500 pull up and 500 pull down */
+	clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4);
+
+	/* Initialise phy */
+	writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST,
+	       ddr_phy_regs + DDRP_PIR);
+
+	count = 0;
+	mask |= DDRP_PGSR_DIDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if ((reg == mask) || (reg == 0x1f))
+			break;
+		if (count++ == 20000)
+			hang();
+	}
+
+	writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR);
+
+	count = 0;
+	mask |= DDRP_PGSR_DTDONE;
+	for (;;) {
+		reg = readl(ddr_phy_regs + DDRP_PGSR);
+		if (reg == mask)
+			break;
+		if (count++ != 50000)
+			continue;
+		reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR;
+		if (reg)
+			hang();
+		count = 0;
+	}
+
+	/* Override impedance */
+	clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff,
+		((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) |
+		((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) |
+		DDRP_ZQXCR_ZDEN);
+}
+
+#define JZBIT(bit) ((bit % 4) * 8)
+#define JZMASK(bit) (0x1f << JZBIT(bit))
+
+static void remap_swap(int a, int b)
+{
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	u32 remmap[2], tmp[2];
+
+	remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4));
+	remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4));
+
+	tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a);
+	tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b);
+
+	remmap[0] &= ~JZMASK(a);
+	remmap[1] &= ~JZMASK(b);
+
+	writel(remmap[0] | (tmp[1] << JZBIT(a)),
+	       ddr_ctl_regs + DDRC_REMMAP(a / 4));
+	writel(remmap[1] | (tmp[0] << JZBIT(b)),
+	       ddr_ctl_regs + DDRC_REMMAP(b / 4));
+}
+
+static void mem_remap(void)
+{
+	u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12;
+	u32 num = DDR_BANK8 ? 3 : 2;
+
+	if (DDR_CS0EN && DDR_CS1EN)
+		num++;
+
+	for (; num > 0; num--)
+		remap_swap(0 + num - 1, start + num - 1);
+}
+
+/* Fetch DRAM config from board file */
+__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+	return NULL;
+}
+
+void sdram_init(void)
+{
+	const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config();
+	void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
+	void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
+	void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
+	u32 mem_clk, tmp, i;
+	u32 mem_base0, mem_base1;
+	u32 mem_mask0, mem_mask1;
+	u32 mem_size0, mem_size1;
+
+	if (!ddr_config)
+		hang();
+
+	/* Reset DLL in DDR PHY */
+	writel(0x3, cpm_regs + 0xd0);
+	mdelay(400);
+	writel(0x1, cpm_regs + 0xd0);
+	mdelay(400);
+
+	/* Enter reset */
+	writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL);
+
+	mem_clk = get_mem_clk();
+
+	tmp = 1000000000 / mem_clk;
+	if (1000000000 % mem_clk)
+		tmp++;
+	tmp = DDR_tREFI / tmp;
+	tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1;
+	if (tmp > 0xff)
+		tmp = 0xff;
+	if (tmp < 1)
+		tmp = 1;
+
+	writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+	writel(0x150000, ddr_phy_regs + DDRP_DTAR);
+	ddr_phy_init(ddr_config);
+
+	writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+	writel(0x0, ddr_ctl_regs + DDRC_CTRL);
+
+	ddr_cfg_init();
+
+	for (i = 0; i < 6; i++)
+		writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i));
+
+	mem_size0 = sdram_size(0);
+	mem_size1 = sdram_size(1);
+
+	if (!mem_size1 && mem_size0 > 0x20000000) {
+		mem_base0 = 0x0;
+		mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+	} else {
+		mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff;
+		mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+	}
+
+	if (mem_size1) {
+		mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
+		mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff;
+	} else {
+		mem_mask1 = 0;
+		mem_base1 = 0xff;
+	}
+
+	writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0,
+	       ddr_ctl_regs + DDRC_MMAP0);
+	writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1,
+	       ddr_ctl_regs + DDRC_MMAP1);
+	writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
+	writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN |
+	       (tmp << DDRC_REFCNT_CON_BIT),
+	       ddr_ctl_regs + DDRC_REFCNT);
+	writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) |
+	       (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1),
+	       ddr_ctl_regs + DDRC_CTRL);
+	mem_remap();
+	clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/timer.c b/arch/mips/mach-jz47xx/jz4780/timer.c
new file mode 100644
index 0000000..a9fc2cb
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/timer.c
@@ -0,0 +1,238 @@
+/*
+ * JZ4780 timer
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <mach/jz4780.h>
+
+#define TCU_TSR		0x1C	/* Timer Stop Register */
+#define TCU_TSSR	0x2C	/* Timer Stop Set Register */
+#define TCU_TSCR	0x3C	/* Timer Stop Clear Register */
+#define TCU_TER		0x10	/* Timer Counter Enable Register */
+#define TCU_TESR	0x14	/* Timer Counter Enable Set Register */
+#define TCU_TECR	0x18	/* Timer Counter Enable Clear Register */
+#define TCU_TFR		0x20	/* Timer Flag Register */
+#define TCU_TFSR	0x24	/* Timer Flag Set Register */
+#define TCU_TFCR	0x28	/* Timer Flag Clear Register */
+#define TCU_TMR		0x30	/* Timer Mask Register */
+#define TCU_TMSR	0x34	/* Timer Mask Set Register */
+#define TCU_TMCR	0x38	/* Timer Mask Clear Register */
+/* n = 0,1,2,3,4,5 */
+#define TCU_TDFR(n)	(0x40 + (n) * 0x10)	/* Timer Data Full Reg */
+#define TCU_TDHR(n)	(0x44 + (n) * 0x10)	/* Timer Data Half Reg */
+#define TCU_TCNT(n)	(0x48 + (n) * 0x10)	/* Timer Counter Reg */
+#define TCU_TCSR(n)	(0x4C + (n) * 0x10)	/* Timer Control Reg */
+
+#define TCU_OSTCNTL	0xe4
+#define TCU_OSTCNTH	0xe8
+#define TCU_OSTCSR	0xec
+#define TCU_OSTCNTHBUF	0xfc
+
+/* Register definitions */
+#define TCU_TCSR_PWM_SD		BIT(9)
+#define TCU_TCSR_PWM_INITL_HIGH	BIT(8)
+#define TCU_TCSR_PWM_EN		BIT(7)
+#define TCU_TCSR_PRESCALE_BIT	3
+#define TCU_TCSR_PRESCALE_MASK	(0x7 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1	(0x0 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE4	(0x1 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE16	(0x2 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE64	(0x3 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE256	(0x4 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_PRESCALE1024	(0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN		BIT(2)
+#define TCU_TCSR_RTC_EN		BIT(1)
+#define TCU_TCSR_PCK_EN		BIT(0)
+
+#define TCU_TER_TCEN5		BIT(5)
+#define TCU_TER_TCEN4		BIT(4)
+#define TCU_TER_TCEN3		BIT(3)
+#define TCU_TER_TCEN2		BIT(2)
+#define TCU_TER_TCEN1		BIT(1)
+#define TCU_TER_TCEN0		BIT(0)
+
+#define TCU_TESR_TCST5		BIT(5)
+#define TCU_TESR_TCST4		BIT(4)
+#define TCU_TESR_TCST3		BIT(3)
+#define TCU_TESR_TCST2		BIT(2)
+#define TCU_TESR_TCST1		BIT(1)
+#define TCU_TESR_TCST0		BIT(0)
+
+#define TCU_TECR_TCCL5		BIT(5)
+#define TCU_TECR_TCCL4		BIT(4)
+#define TCU_TECR_TCCL3		BIT(3)
+#define TCU_TECR_TCCL2		BIT(2)
+#define TCU_TECR_TCCL1		BIT(1)
+#define TCU_TECR_TCCL0		BIT(0)
+
+#define TCU_TFR_HFLAG5		BIT(21)
+#define TCU_TFR_HFLAG4		BIT(20)
+#define TCU_TFR_HFLAG3		BIT(19)
+#define TCU_TFR_HFLAG2		BIT(18)
+#define TCU_TFR_HFLAG1		BIT(17)
+#define TCU_TFR_HFLAG0		BIT(16)
+#define TCU_TFR_FFLAG5		BIT(5)
+#define TCU_TFR_FFLAG4		BIT(4)
+#define TCU_TFR_FFLAG3		BIT(3)
+#define TCU_TFR_FFLAG2		BIT(2)
+#define TCU_TFR_FFLAG1		BIT(1)
+#define TCU_TFR_FFLAG0		BIT(0)
+
+#define TCU_TFSR_HFLAG5		BIT(21)
+#define TCU_TFSR_HFLAG4		BIT(20)
+#define TCU_TFSR_HFLAG3		BIT(19)
+#define TCU_TFSR_HFLAG2		BIT(18)
+#define TCU_TFSR_HFLAG1		BIT(17)
+#define TCU_TFSR_HFLAG0		BIT(16)
+#define TCU_TFSR_FFLAG5		BIT(5)
+#define TCU_TFSR_FFLAG4		BIT(4)
+#define TCU_TFSR_FFLAG3		BIT(3)
+#define TCU_TFSR_FFLAG2		BIT(2)
+#define TCU_TFSR_FFLAG1		BIT(1)
+#define TCU_TFSR_FFLAG0		BIT(0)
+
+#define TCU_TFCR_HFLAG5		BIT(21)
+#define TCU_TFCR_HFLAG4		BIT(20)
+#define TCU_TFCR_HFLAG3		BIT(19)
+#define TCU_TFCR_HFLAG2		BIT(18)
+#define TCU_TFCR_HFLAG1		BIT(17)
+#define TCU_TFCR_HFLAG0		BIT(16)
+#define TCU_TFCR_FFLAG5		BIT(5)
+#define TCU_TFCR_FFLAG4		BIT(4)
+#define TCU_TFCR_FFLAG3		BIT(3)
+#define TCU_TFCR_FFLAG2		BIT(2)
+#define TCU_TFCR_FFLAG1		BIT(1)
+#define TCU_TFCR_FFLAG0		BIT(0)
+
+#define TCU_TMR_HMASK5		BIT(21)
+#define TCU_TMR_HMASK4		BIT(20)
+#define TCU_TMR_HMASK3		BIT(19)
+#define TCU_TMR_HMASK2		BIT(18)
+#define TCU_TMR_HMASK1		BIT(17)
+#define TCU_TMR_HMASK0		BIT(16)
+#define TCU_TMR_FMASK5		BIT(5)
+#define TCU_TMR_FMASK4		BIT(4)
+#define TCU_TMR_FMASK3		BIT(3)
+#define TCU_TMR_FMASK2		BIT(2)
+#define TCU_TMR_FMASK1		BIT(1)
+#define TCU_TMR_FMASK0		BIT(0)
+
+#define TCU_TMSR_HMST5		BIT(21)
+#define TCU_TMSR_HMST4		BIT(20)
+#define TCU_TMSR_HMST3		BIT(19)
+#define TCU_TMSR_HMST2		BIT(18)
+#define TCU_TMSR_HMST1		BIT(17)
+#define TCU_TMSR_HMST0		BIT(16)
+#define TCU_TMSR_FMST5		BIT(5)
+#define TCU_TMSR_FMST4		BIT(4)
+#define TCU_TMSR_FMST3		BIT(3)
+#define TCU_TMSR_FMST2		BIT(2)
+#define TCU_TMSR_FMST1		BIT(1)
+#define TCU_TMSR_FMST0		BIT(0)
+
+#define TCU_TMCR_HMCL5		BIT(21)
+#define TCU_TMCR_HMCL4		BIT(20)
+#define TCU_TMCR_HMCL3		BIT(19)
+#define TCU_TMCR_HMCL2		BIT(18)
+#define TCU_TMCR_HMCL1		BIT(17)
+#define TCU_TMCR_HMCL0		BIT(16)
+#define TCU_TMCR_FMCL5		BIT(5)
+#define TCU_TMCR_FMCL4		BIT(4)
+#define TCU_TMCR_FMCL3		BIT(3)
+#define TCU_TMCR_FMCL2		BIT(2)
+#define TCU_TMCR_FMCL1		BIT(1)
+#define TCU_TMCR_FMCL0		BIT(0)
+
+#define TCU_TSR_WDTS		BIT(16)
+#define TCU_TSR_STOP5		BIT(5)
+#define TCU_TSR_STOP4		BIT(4)
+#define TCU_TSR_STOP3		BIT(3)
+#define TCU_TSR_STOP2		BIT(2)
+#define TCU_TSR_STOP1		BIT(1)
+#define TCU_TSR_STOP0		BIT(0)
+
+#define TCU_TSSR_WDTSS		BIT(16)
+#define TCU_TSSR_STPS5		BIT(5)
+#define TCU_TSSR_STPS4		BIT(4)
+#define TCU_TSSR_STPS3		BIT(3)
+#define TCU_TSSR_STPS2		BIT(2)
+#define TCU_TSSR_STPS1		BIT(1)
+#define TCU_TSSR_STPS0		BIT(0)
+
+#define TCU_TSSR_WDTSC		BIT(16)
+#define TCU_TSSR_STPC5		BIT(5)
+#define TCU_TSSR_STPC4		BIT(4)
+#define TCU_TSSR_STPC3		BIT(3)
+#define TCU_TSSR_STPC2		BIT(2)
+#define TCU_TSSR_STPC1		BIT(1)
+#define TCU_TSSR_STPC0		BIT(0)
+
+#define TER_OSTEN		BIT(15)
+
+#define OSTCSR_CNT_MD		BIT(15)
+#define OSTCSR_SD		BIT(9)
+#define OSTCSR_PRESCALE_16	(0x2 << 3)
+#define OSTCSR_EXT_EN		BIT(2)
+
+int timer_init(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+
+	writel(OSTCSR_SD, regs + TCU_OSTCSR);
+	reset_timer();
+	writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16,
+	       regs + TCU_OSTCSR);
+	writew(TER_OSTEN, regs + TCU_TESR);
+	return 0;
+}
+
+void reset_timer(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+
+	writel(0, regs + TCU_OSTCNTH);
+	writel(0, regs + TCU_OSTCNTL);
+}
+
+static u64 get_timer64(void)
+{
+	void __iomem *regs = (void __iomem *)TCU_BASE;
+	u32 low = readl(regs + TCU_OSTCNTL);
+	u32 high = readl(regs + TCU_OSTCNTHBUF);
+	return ((u64)high << 32) | low;
+}
+
+ulong get_timer(ulong base)
+{
+	return lldiv(get_timer64(), 3000) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+	/* OST count increments@3MHz */
+	u64 end = get_timer64() + ((u64)usec * 3);
+	while (get_timer64() < end)
+		;
+}
+
+unsigned long long get_ticks(void)
+{
+	return get_timer64();
+}
+
+void jz4780_tcu_wdt_start(void)
+{
+	void __iomem *tcu_regs = (void __iomem *)TCU_BASE;
+
+	/* Enable WDT clock */
+	writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR);
+}
diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
new file mode 100644
index 0000000..f6d2d2d
--- /dev/null
+++ b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_ARCH(mips)
+ENTRY(_start)
+SECTIONS
+{
+	.text :
+	{
+		__image_copy_start = .;
+		arch/mips/mach-jz47xx/start.o	(.text*)
+		*(.text*)
+	} >.sram
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+	. = ALIGN(4);
+	__image_copy_end = .;
+
+	.bss : {
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.sbss.*)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(4);
+		__bss_end = .;
+	} >.sdram
+
+	/DISCARD/ : {
+		*(.dynbss)
+		*(.dynstr)
+		*(.dynamic)
+		*(.interp)
+		*(.hash)
+		*(.gnu.*)
+		*(.plt)
+		*(.got.plt)
+		*(.rel.plt)
+		*(.rel.dyn)
+	}
+}
diff --git a/arch/mips/mach-jz47xx/start.S b/arch/mips/mach-jz47xx/start.S
new file mode 100644
index 0000000..9f70596
--- /dev/null
+++ b/arch/mips/mach-jz47xx/start.S
@@ -0,0 +1,99 @@
+/*
+ *  Startup Code for MIPS32 XBURST CPU-core
+ *
+ *  Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#include <asm/cache.h>
+#include <mach/jz4780.h>
+
+	.set noreorder
+
+	.globl _start
+	.text
+_start:
+#ifdef CONFIG_SPL_BUILD
+
+	/* magic value ("MSPL") */
+	.word 0x4d53504c
+
+	/* Invalidate BTB */
+	mfc0	t0, CP0_CONFIG, 7
+	nop
+	ori	t0, 2
+	mtc0	t0, CP0_CONFIG, 7
+	nop
+
+	/*
+	 * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
+	 */
+	li	t0, 0x0040FC04
+	mtc0	t0, CP0_STATUS
+
+	/* CAUSE register */
+	/* IV=1, use the specical interrupt vector (0x200) */
+	li	t1, 0x00800000
+	mtc0	t1, CP0_CAUSE
+
+#ifdef CONFIG_SOC_JZ4780
+	/* enable bridge radical mode */
+	la	t0, CPM_BASE
+	lw	t1, 0x24(t0)
+	ori	t1, t1, 0x22
+	sw	t1, 0x24(t0)
+#endif
+
+	/* Set up stack */
+	li	sp, CONFIG_SPL_STACK
+
+	b		board_init_f
+	 nop
+
+#ifdef CONFIG_SOC_JZ4780
+
+	.globl enable_caches
+	.ent enable_caches
+enable_caches:
+	mtc0	zero, CP0_TAGLO
+	mtc0	zero, CP0_TAGHI
+
+	li	t0, KSEG0
+	addu	t1, t0, CONFIG_SYS_DCACHE_SIZE
+1:
+	cache	INDEX_STORE_TAG_D, 0(t0)
+	bne	t0, t1, 1b
+	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+	li	t0, KSEG0
+	addu	t1, t0, CONFIG_SYS_ICACHE_SIZE
+2:
+	cache	INDEX_STORE_TAG_I, 0(t0)
+	bne	t0, t1, 2b
+	addiu	t0, t0, CONFIG_SYS_CACHELINE_SIZE
+
+	/* Invalidate BTB */
+	mfc0	t0, CP0_CONFIG, 7
+	nop
+	ori	t0, 2
+	mtc0	t0, CP0_CONFIG, 7
+	nop
+
+	/* Enable caches */
+	li	t0, CONF_CM_CACHABLE_NONCOHERENT
+	mtc0	t0, CP0_CONFIG
+	nop
+
+	jr	ra
+	 nop
+
+	.end enable_caches
+
+#endif /* CONFIG_SOC_JZ4780 */
+#endif /* !CONFIG_SPL_BUILD */
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644
index 0000000..467165e
--- /dev/null
+++ b/include/dt-bindings/clock/jz4780-cgu.h
@@ -0,0 +1,88 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK	0
+#define JZ4780_CLK_RTCLK	1
+#define JZ4780_CLK_APLL		2
+#define JZ4780_CLK_MPLL		3
+#define JZ4780_CLK_EPLL		4
+#define JZ4780_CLK_VPLL		5
+#define JZ4780_CLK_OTGPHY	6
+#define JZ4780_CLK_SCLKA	7
+#define JZ4780_CLK_CPUMUX	8
+#define JZ4780_CLK_CPU		9
+#define JZ4780_CLK_L2CACHE	10
+#define JZ4780_CLK_AHB0		11
+#define JZ4780_CLK_AHB2PMUX	12
+#define JZ4780_CLK_AHB2		13
+#define JZ4780_CLK_PCLK		14
+#define JZ4780_CLK_DDR		15
+#define JZ4780_CLK_VPU		16
+#define JZ4780_CLK_I2SPLL	17
+#define JZ4780_CLK_I2S		18
+#define JZ4780_CLK_LCD0PIXCLK	19
+#define JZ4780_CLK_LCD1PIXCLK	20
+#define JZ4780_CLK_MSCMUX	21
+#define JZ4780_CLK_MSC0		22
+#define JZ4780_CLK_MSC1		23
+#define JZ4780_CLK_MSC2		24
+#define JZ4780_CLK_UHC		25
+#define JZ4780_CLK_SSIPLL	26
+#define JZ4780_CLK_SSI		27
+#define JZ4780_CLK_CIMMCLK	28
+#define JZ4780_CLK_PCMPLL	29
+#define JZ4780_CLK_PCM		30
+#define JZ4780_CLK_GPU		31
+#define JZ4780_CLK_HDMI		32
+#define JZ4780_CLK_BCH		33
+#define JZ4780_CLK_NEMC		34
+#define JZ4780_CLK_OTG0		35
+#define JZ4780_CLK_SSI0		36
+#define JZ4780_CLK_SMB0		37
+#define JZ4780_CLK_SMB1		38
+#define JZ4780_CLK_SCC		39
+#define JZ4780_CLK_AIC		40
+#define JZ4780_CLK_TSSI0	41
+#define JZ4780_CLK_OWI		42
+#define JZ4780_CLK_KBC		43
+#define JZ4780_CLK_SADC		44
+#define JZ4780_CLK_UART0	45
+#define JZ4780_CLK_UART1	46
+#define JZ4780_CLK_UART2	47
+#define JZ4780_CLK_UART3	48
+#define JZ4780_CLK_SSI1		49
+#define JZ4780_CLK_SSI2		50
+#define JZ4780_CLK_PDMA		51
+#define JZ4780_CLK_GPS		52
+#define JZ4780_CLK_MAC		53
+#define JZ4780_CLK_SMB2		54
+#define JZ4780_CLK_CIM		55
+#define JZ4780_CLK_LCD		56
+#define JZ4780_CLK_TVE		57
+#define JZ4780_CLK_IPU		58
+#define JZ4780_CLK_DDR0		59
+#define JZ4780_CLK_DDR1		60
+#define JZ4780_CLK_SMB3		61
+#define JZ4780_CLK_TSSI1	62
+#define JZ4780_CLK_COMPRESS	63
+#define JZ4780_CLK_AIC1		64
+#define JZ4780_CLK_GPVLC	65
+#define JZ4780_CLK_OTG1		66
+#define JZ4780_CLK_UART4	67
+#define JZ4780_CLK_AHBMON	68
+#define JZ4780_CLK_SMB4		69
+#define JZ4780_CLK_DES		70
+#define JZ4780_CLK_X2D		71
+#define JZ4780_CLK_CORE1	72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
-- 
2.10.2

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

* [U-Boot] [PATCH 12/13] mips: jz47xx: Add minimal JZ MMC node
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (9 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 11/13] mips: jz47xx: Add JZ4780 SoC support Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2016-12-01  1:06 ` [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform Marek Vasut
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

Add minimal JZ MMC node into the JZ4780 device tree.
This piece is picked from the CI20 Linux repository.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/dts/jz4780.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi
index 8f01d36..b017055 100644
--- a/arch/mips/dts/jz4780.dtsi
+++ b/arch/mips/dts/jz4780.dtsi
@@ -44,6 +44,26 @@
 		#clock-cells = <1>;
 	};
 
+	msc0: msc at 13450000 {
+		compatible = "ingenic,jz4780-mmc";
+		reg = <0x13450000 0x1000>;
+
+		status = "disabled";
+
+		clocks = <&cgu JZ4780_CLK_MSC0>;
+		clock-names = "mmc";
+	};
+
+	msc1: msc at 13460000 {
+		compatible = "ingenic,jz4780-mmc";
+		reg = <0x13460000 0x1000>;
+
+		clocks = <&cgu JZ4780_CLK_MSC1>;
+		clock-names = "mmc";
+
+		status = "disabled";
+	};
+
 	uart0: serial at 10030000 {
 		compatible = "ingenic,jz4780-uart";
 		reg = <0x10030000 0x100>;
-- 
2.10.2

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (10 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 12/13] mips: jz47xx: Add minimal JZ MMC node Marek Vasut
@ 2016-12-01  1:06 ` Marek Vasut
  2017-02-12 11:52   ` Andreas Färber
  2016-12-03  4:26 ` [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Simon Glass
  2016-12-19 21:18 ` [U-Boot] [U-Boot,01/13] " Tom Rini
  13 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2016-12-01  1:06 UTC (permalink / raw)
  To: u-boot

From: Paul Burton <paul.burton@imgtec.com>

Add support for the Creator CI20 platform based on the JZ4780 SoC.
The DTS file comes from Linux 4.6 as of revision
78800558d104e003f9ae92e0107f1de39cf9de9f

So far, there are still a few details which will have to be fixed
once they are fleshed out in Linux:
- pinmux: Thus far, this board just pokes the pinmux registers to
          set the pinmux. For MMC in SPL, this will have to stay.
	  But for full u-boot a proper pinmux driver will have to
	  be added once the pinmux semantics in DT are in mainline
	  Linux.
- ethernet,efuse: DT bindings are missing from mainline Linux.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Paul Burton <paul.burton@imgtec.com>
---
 arch/mips/dts/Makefile        |   1 +
 arch/mips/dts/ci20.dts        | 114 ++++++++++++++
 arch/mips/mach-jz47xx/Kconfig |  11 ++
 board/imgtec/ci20/Kconfig     |  35 +++++
 board/imgtec/ci20/Makefile    |   5 +
 board/imgtec/ci20/README      |  10 ++
 board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
 configs/ci20_defconfig        |  28 ++++
 include/configs/ci20.h        | 105 +++++++++++++
 9 files changed, 663 insertions(+)
 create mode 100644 arch/mips/dts/ci20.dts
 create mode 100644 board/imgtec/ci20/Kconfig
 create mode 100644 board/imgtec/ci20/Makefile
 create mode 100644 board/imgtec/ci20/README
 create mode 100644 board/imgtec/ci20/ci20.c
 create mode 100644 configs/ci20_defconfig
 create mode 100644 include/configs/ci20.h

diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index 30fcc2b..e3473d9 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -9,6 +9,7 @@ dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
 dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
 dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
+dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/mips/dts/ci20.dts b/arch/mips/dts/ci20.dts
new file mode 100644
index 0000000..9dab5e6
--- /dev/null
+++ b/arch/mips/dts/ci20.dts
@@ -0,0 +1,114 @@
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+	compatible = "img,ci20", "ingenic,jz4780";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial3 = &uart3;
+		serial4 = &uart4;
+	};
+
+	chosen {
+		stdout-path = &uart0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x10000000
+		       0x30000000 0x30000000>;
+	};
+};
+
+&ext {
+	clock-frequency = <48000000>;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&nemc {
+	status = "okay";
+
+	nandc: nand-controller at 1 {
+		compatible = "ingenic,jz4780-nand";
+		reg = <1 0 0x1000000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ingenic,bch-controller = <&bch>;
+
+		ingenic,nemc-tAS = <10>;
+		ingenic,nemc-tAH = <5>;
+		ingenic,nemc-tBP = <10>;
+		ingenic,nemc-tAW = <15>;
+		ingenic,nemc-tSTRV = <100>;
+
+		nand at 1 {
+			reg = <1>;
+
+			nand-ecc-step-size = <1024>;
+			nand-ecc-strength = <24>;
+			nand-ecc-mode = "hw";
+			nand-on-flash-bbt;
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <2>;
+				#size-cells = <2>;
+
+				partition at 0 {
+					label = "u-boot-spl";
+					reg = <0x0 0x0 0x0 0x800000>;
+				};
+
+				partition at 0x800000 {
+					label = "u-boot";
+					reg = <0x0 0x800000 0x0 0x200000>;
+				};
+
+				partition at 0xa00000 {
+					label = "u-boot-env";
+					reg = <0x0 0xa00000 0x0 0x200000>;
+				};
+
+				partition at 0xc00000 {
+					label = "boot";
+					reg = <0x0 0xc00000 0x0 0x4000000>;
+				};
+
+				partition at 0x8c00000 {
+					label = "system";
+					reg = <0x0 0x4c00000 0x1 0xfb400000>;
+				};
+			};
+		};
+	};
+};
+
+&bch {
+	status = "okay";
+};
+
+&msc0 {
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	status = "okay";
+};
diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig
index cd6944c..dcaac01 100644
--- a/arch/mips/mach-jz47xx/Kconfig
+++ b/arch/mips/mach-jz47xx/Kconfig
@@ -12,4 +12,15 @@ config SOC_JZ4780
 	help
 	  Support for Ingenic JZ4780 family SoCs.
 
+choice
+	prompt "Board select"
+
+config TARGET_JZ4780_CI20
+	bool "Creator CI20 Reference Board"
+	select SOC_JZ4780
+
+endchoice
+
+source "board/imgtec/ci20/Kconfig"
+
 endmenu
diff --git a/board/imgtec/ci20/Kconfig b/board/imgtec/ci20/Kconfig
new file mode 100644
index 0000000..5613df8
--- /dev/null
+++ b/board/imgtec/ci20/Kconfig
@@ -0,0 +1,35 @@
+if TARGET_JZ4780_CI20
+
+config SYS_BOARD
+	default "ci20"
+
+config SYS_VENDOR
+	default "imgtec"
+
+config SYS_CONFIG_NAME
+	default "ci20"
+
+config SYS_TEXT_BASE
+	default 0x80000000
+
+config JTAG
+	bool
+	default y
+
+config SYS_AUDIO_SPEED
+	int
+	default 768000000
+
+config SYS_EXTAL
+	int
+	default 48000000
+
+config SYS_MEM_DIV
+	int
+	default 3
+
+config SYS_MEM_SPEED
+	int
+	default 1200000000
+
+endif
diff --git a/board/imgtec/ci20/Makefile b/board/imgtec/ci20/Makefile
new file mode 100644
index 0000000..8c00081
--- /dev/null
+++ b/board/imgtec/ci20/Makefile
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y := ci20.o
diff --git a/board/imgtec/ci20/README b/board/imgtec/ci20/README
new file mode 100644
index 0000000..c757d41
--- /dev/null
+++ b/board/imgtec/ci20/README
@@ -0,0 +1,10 @@
+CI20 U-Boot
+
+Installation to an SD card:
+  Repartition your card with an MBR such that the first partition starts at an
+  offset of no less than 270KB. Then install U-Boot SPL & the full U-Boot image
+  to the card like so:
+
+    dd if=spl/u-boot-spl.bin of=/dev/sdX obs=512 seek=1
+    dd if=u-boot.img of=/dev/sdX obs=1K seek=14
+    sync
diff --git a/board/imgtec/ci20/ci20.c b/board/imgtec/ci20/ci20.c
new file mode 100644
index 0000000..bbbad78
--- /dev/null
+++ b/board/imgtec/ci20/ci20.c
@@ -0,0 +1,354 @@
+/*
+ * CI20 setup code
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <mach/jz4780.h>
+#include <mach/jz4780_dram.h>
+
+#define JZ_GPIO(bank, pin)	((32 * (bank)) + (pin))
+
+struct ci20_otp {
+	u32	serial_number;
+	u32	date;
+	u8	manufacturer[2];
+	u8	mac[6];
+} __packed;
+
+static void ci20_mux_eth(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+#ifdef CONFIG_NAND
+	/* setup pins (some already setup for NAND) */
+	writel(0x04030000, gpio_regs + GPIO_PXINTC(0));
+	writel(0x04030000, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x04030000, gpio_regs + GPIO_PXPENS(0));
+#else
+	/* setup pins (as above +NAND CS +RD/WE +SDx +SAx) */
+	writel(0x0dff00ff, gpio_regs + GPIO_PXINTC(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x0dff00ff, gpio_regs + GPIO_PXPENS(0));
+	writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+#endif
+}
+
+static void ci20_mux_jtag(void)
+{
+#ifdef CONFIG_JTAG
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* enable JTAG */
+	writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT0C(0));
+#endif
+}
+
+static void ci20_mux_mmc(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* setup MSC1 pins */
+	writel(0x30f00000, gpio_regs + GPIO_PXINTC(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXMASKC(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPAT1C(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPAT0C(4));
+	writel(0x30f00000, gpio_regs + GPIO_PXPENC(4));
+	jz4780_clk_ungate_mmc();
+}
+
+static void ci20_mux_nand(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* setup pins */
+	writel(0x002c00ff, gpio_regs + GPIO_PXINTC(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXMASKC(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPAT1C(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPAT0C(0));
+	writel(0x002c00ff, gpio_regs + GPIO_PXPENS(0));
+	writel(0x00000003, gpio_regs + GPIO_PXINTC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXMASKC(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1));
+	writel(0x00000003, gpio_regs + GPIO_PXPENS(1));
+
+	/* FRB0_N */
+	gpio_direction_input(32 * 0 + 20);
+	writel(20, gpio_regs + GPIO_PXPENS(0));
+
+	/* disable write protect */
+	gpio_direction_output(JZ_GPIO(5, 22), 1);
+}
+
+static void ci20_mux_uart(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+
+	/* UART0 */
+	writel(0x9, gpio_regs + GPIO_PXINTC(5));
+	writel(0x9, gpio_regs + GPIO_PXMASKC(5));
+	writel(0x9, gpio_regs + GPIO_PXPAT1C(5));
+	writel(0x9, gpio_regs + GPIO_PXPAT0C(5));
+	writel(0x9, gpio_regs + GPIO_PXPENC(5));
+	jz4780_clk_ungate_uart(0);
+
+	/* UART 1 and 2 */
+	jz4780_clk_ungate_uart(1);
+	jz4780_clk_ungate_uart(2);
+
+#ifndef CONFIG_JTAG
+	/* UART3 */
+	writel(1 << 12, gpio_regs + GPIO_PXINTC(3));
+	writel(1 << 12, gpio_regs + GPIO_PXMASKS(3));
+	writel(1 << 12, gpio_regs + GPIO_PXPAT1S(3));
+	writel(1 << 12, gpio_regs + GPIO_PXPAT0C(3));
+	writel(3 << 30, gpio_regs + GPIO_PXINTC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXMASKC(0));
+	writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0));
+	writel(1 << 30, gpio_regs + GPIO_PXPAT0C(0));
+	writel(1 << 31, gpio_regs + GPIO_PXPAT0S(0));
+	jz4780_clk_ungate_uart(3);
+#endif
+
+	/* UART4 */
+	writel(0x100400, gpio_regs + GPIO_PXINTC(2));
+	writel(0x100400, gpio_regs + GPIO_PXMASKC(2));
+	writel(0x100400, gpio_regs + GPIO_PXPAT1S(2));
+	writel(0x100400, gpio_regs + GPIO_PXPAT0C(2));
+	writel(0x100400, gpio_regs + GPIO_PXPENC(2));
+	jz4780_clk_ungate_uart(4);
+}
+
+int board_early_init_f(void)
+{
+	ci20_mux_jtag();
+	ci20_mux_uart();
+
+	ci20_mux_eth();
+	ci20_mux_mmc();
+	ci20_mux_nand();
+
+	/* SYS_POWER_IND high (LED blue, VBUS on) */
+	gpio_direction_output(JZ_GPIO(5, 15), 1);
+
+	/* LEDs off */
+	gpio_direction_output(JZ_GPIO(2, 0), 0);
+	gpio_direction_output(JZ_GPIO(2, 0), 0);
+	gpio_direction_output(JZ_GPIO(2, 0), 0);
+	gpio_direction_output(JZ_GPIO(2, 0), 0);
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	const u32 efuse_clk = jz4780_clk_get_efuse_clk();
+	struct ci20_otp otp;
+	char manufacturer[3];
+
+	/* Read the board OTP data */
+	jz4780_efuse_init(efuse_clk);
+	jz4780_efuse_read(0x18, 16, (u8 *)&otp);
+
+	/* Set MAC address */
+	if (!is_valid_ethaddr(otp.mac)) {
+		/* no MAC assigned, generate one from the unique chip ID */
+		jz4780_efuse_read(0x8, 4, &otp.mac[0]);
+		jz4780_efuse_read(0x12, 2, &otp.mac[4]);
+		otp.mac[0] = (otp.mac[0] | 0x02) & ~0x01;
+	}
+	eth_setenv_enetaddr("ethaddr", otp.mac);
+
+	/* Put other board information into the environment */
+	setenv_ulong("serial#", otp.serial_number);
+	setenv_ulong("board_date", otp.date);
+	manufacturer[0] = otp.manufacturer[0];
+	manufacturer[1] = otp.manufacturer[1];
+	manufacturer[2] = 0;
+	setenv("board_mfr", manufacturer);
+
+	return 0;
+}
+
+#ifdef CONFIG_DRIVER_DM9000
+int board_eth_init(bd_t *bis)
+{
+	/* Enable clock */
+	jz4780_clk_ungate_ethernet();
+
+	/* Enable power (PB25) */
+	gpio_direction_output(JZ_GPIO(1, 25), 1);
+
+	/* Reset (PF12) */
+	mdelay(10);
+	gpio_direction_output(JZ_GPIO(5, 12), 0);
+	mdelay(10);
+	gpio_direction_output(JZ_GPIO(5, 12), 1);
+	mdelay(10);
+
+	return dm9000_initialize(bis);
+}
+#endif /* CONFIG_DRIVER_DM9000 */
+
+static u8 ci20_revision(void)
+{
+	void __iomem *gpio_regs = (void __iomem *)GPIO_BASE;
+	int val;
+
+	gpio_direction_input(82);
+	gpio_direction_input(83);
+
+	/* Enable pullups */
+	writel(BIT(18) | BIT(19), gpio_regs + GPIO_PXPENC(2));
+
+	/* Read PC18/19 for version */
+	val = (!!gpio_get_value(82)) | ((!!gpio_get_value(83)) << 1);
+
+	if (val == 3)	/* Rev 1 boards had no pulldowns - giving 3 */
+		return 1;
+	if (val == 1)	/* Rev 2 boards pulldown port C bit 18 giving 1 */
+		return 2;
+
+	return 0;
+}
+
+/* U-Boot common routines */
+int checkboard(void)
+{
+	printf("Board: Creator CI20 (rev.%d)\n", ci20_revision());
+	return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+int board_mmc_init(bd_t *bd)
+{
+	ci20_mux_mmc();
+	return jz_mmc_init((void __iomem *)MSC0_BASE);
+}
+#endif
+
+static const struct jz4780_ddr_config K4B2G0846Q_48_config = {
+	.timing = {
+		(4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+		(6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+
+		(4 << DDRC_TIMING2_TCCD_BIT) | (15 << DDRC_TIMING2_TRAS_BIT) |
+		(6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+		(4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+		(6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+		(21 << DDRC_TIMING3_TRC_BIT),
+
+		(31 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+		(4 << DDRC_TIMING4_TCKE_BIT) | (9 << DDRC_TIMING4_TMINSR_BIT) |
+		(8 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+		(8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+		(4 << DDRC_TIMING5_TWDLAT_BIT),
+
+		(25 << DDRC_TIMING6_TXSRD_BIT) | (12 << DDRC_TIMING6_TFAW_BIT) |
+		(2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+	},
+
+	/* PHY */
+	/* Mode Register 0 */
+	.mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+	.ptr0 = 0x002000d4,
+	.ptr1 = 0x02230d40,
+	.ptr2 = 0x04013880,
+
+	.dtpr0 = 0x2a8f6690,
+	.dtpr1 = 0x00400860,
+	.dtpr2 = 0x10042a00,
+
+	.pullup = 0x0b,
+	.pulldn = 0x0b,
+};
+
+static const struct jz4780_ddr_config H5TQ2G83CFR_48_config = {
+	.timing = {
+		(4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) |
+		(6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT),
+
+		(4 << DDRC_TIMING2_TCCD_BIT) | (16 << DDRC_TIMING2_TRAS_BIT) |
+		(6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT),
+
+		(4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) |
+		(6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) |
+		(22 << DDRC_TIMING3_TRC_BIT),
+
+		(42 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) |
+		(4 << DDRC_TIMING4_TCKE_BIT) | (7 << DDRC_TIMING4_TMINSR_BIT) |
+		(3 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT),
+
+		(8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) |
+		(4 << DDRC_TIMING5_TWDLAT_BIT),
+
+		(25 << DDRC_TIMING6_TXSRD_BIT) | (20 << DDRC_TIMING6_TFAW_BIT) |
+		(2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT),
+	},
+
+	/* PHY */
+	/* Mode Register 0 */
+	.mr0 = 0x420,
+#ifdef SDRAM_DISABLE_DLL
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE),
+#else
+	.mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS),
+#endif
+
+	.ptr0 = 0x002000d4,
+	.ptr1 = 0x02d30d40,
+	.ptr2 = 0x04013880,
+
+	.dtpr0 = 0x2c906690,
+	.dtpr1 = 0x005608a0,
+	.dtpr2 = 0x10042a00,
+
+	.pullup = 0x0e,
+	.pulldn = 0x0e,
+};
+
+#if (CONFIG_SYS_MHZ != 1200) || (CONFIG_SYS_EXTAL != 48000000)
+#error No DDR configuration for CPU speed
+#endif
+
+const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
+{
+	const int board_revision = ci20_revision();
+
+	if (board_revision == 2)
+		return &K4B2G0846Q_48_config;
+	else /* Fall back to H5TQ2G83CFR RAM */
+		return &H5TQ2G83CFR_48_config;
+}
+#endif
diff --git a/configs/ci20_defconfig b/configs/ci20_defconfig
new file mode 100644
index 0000000..65bb2a0
--- /dev/null
+++ b/configs/ci20_defconfig
@@ -0,0 +1,28 @@
+CONFIG_MIPS=y
+CONFIG_ARCH_JZ47XX=y
+CONFIG_TARGET_JZ4780_CI20=y
+CONFIG_DEFAULT_DEVICE_TREE="ci20"
+CONFIG_SPL=y
+CONFIG_SPL_MMC_TINY=y
+CONFIG_FIT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_DISPLAY_BOARDINFO=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_MMC=y
+CONFIG_DM_MMC=y
+# CONFIG_DM_MMC_OPS is not set
+# CONFIG_BLK is not set
+# CONFIG_SPL_DM_MMC is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_JZ4780_EFUSE=y
+CONFIG_JZ47XX_GPIO=y
+CONFIG_JZ47XX_MMC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_SYS_NS16550=y
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_DCACHE_SIZE=32768
+CONFIG_SYS_ICACHE_SIZE=32768
+CONFIG_SYS_DCACHE_LINE_SIZE=32
+CONFIG_SYS_ICACHE_LINE_SIZE=32
diff --git a/include/configs/ci20.h b/include/configs/ci20.h
new file mode 100644
index 0000000..584abe3
--- /dev/null
+++ b/include/configs/ci20.h
@@ -0,0 +1,105 @@
+/*
+ * CI20 configuration
+ *
+ * Copyright (c) 2013 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_CI20_H__
+#define __CONFIG_CI20_H__
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MISC_INIT_R
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_LZO
+
+/* Ingenic JZ4780 clock configuration. */
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_MHZ			1200
+#define CONFIG_SYS_MIPS_TIMER_FREQ	(CONFIG_SYS_MHZ * 1000000)
+
+/* Memory configuration */
+#define CONFIG_SYS_MONITOR_LEN		(512 * 1024)
+#define CONFIG_SYS_MALLOC_LEN		(64 * 1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN	(128 * 1024)
+
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000 /* cached (KSEG0) address */
+#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
+#define CONFIG_SYS_LOAD_ADDR		0x81000000
+#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
+#define CONFIG_SYS_MEMTEST_START	0x80000000
+#define CONFIG_SYS_MEMTEST_END		0x88000000
+
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+/* NS16550-ish UARTs */
+#define CONFIG_SYS_NS16550_CLK		CONFIG_SYS_EXTAL
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_CONSOLE_MUX
+#define CONFIG_BAUDRATE			115200
+
+/* Ethernet: davicom DM9000 */
+#define CONFIG_DRIVER_DM9000		1
+#define CONFIG_DM9000_BASE		0xb6000000
+#define DM9000_IO			CONFIG_DM9000_BASE
+#define DM9000_DATA			(CONFIG_DM9000_BASE + 2)
+
+/* MMC */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+
+/* Environment */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_ENV_SIZE			(32 << 10)
+#define CONFIG_ENV_OFFSET		((14 + 512) << 10)
+#define CONFIG_ENV_OVERWRITE
+
+/* Command line configuration. */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O buffer size */
+#define CONFIG_SYS_MAXARGS	32		/* Max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+						/* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE			/* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE			/* Command auto complete */
+#define CONFIG_CMDLINE_EDITING			/* Command history etc */
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+
+/* Miscellaneous configuration options */
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20)
+#define CONFIG_BOOTARGS			"console=ttyS0,115200 rw rootwait"
+
+/* SPL */
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+
+#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
+
+#define CONFIG_SPL_TEXT_BASE		0xf4000a00
+#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
+
+#define CONFIG_SPL_BSS_START_ADDR	0xf4004000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
+
+#define CONFIG_SPL_LDSCRIPT		"arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds"
+#define CONFIG_SPL_START_S_PATH		"arch/mips/mach-jz47xx"
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	0x1c	/* 14KB offset */
+
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_USE_TINY_PRINTF
+#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
+#define CONFIG_MMC_TINY
+#undef CONFIG_DM_MMC
+#endif
+
+#endif /* __CONFIG_CI20_H__ */
-- 
2.10.2

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

* [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used
  2016-12-01  1:06 ` [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used Marek Vasut
@ 2016-12-01  4:17   ` Jaehoon Chung
  2016-12-01  5:14   ` Jaehoon Chung
  1 sibling, 0 replies; 41+ messages in thread
From: Jaehoon Chung @ 2016-12-01  4:17 UTC (permalink / raw)
  To: u-boot

On 12/01/2016 10:06 AM, Marek Vasut wrote:
> If debug() is not used, then the whole content of debug(...) will
> be removed by the preprocessor, which will result in the following
> warning. This patch adds __maybe_unused annotation to fix this.
> 
> drivers/mmc/mmc.c: In function ?mmc_init?:
> drivers/mmc/mmc.c:1685:11: warning: variable ?start? set but not used [-Wunused-but-set-variable]
>   unsigned start;
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

I think that is not related to other patches.
So i will this patch into u-boot-mmc. with Tom's Reviewd-by tag.
(And also PATCH[04/13]~PATCH[07/13]) how about? 
I'm doing the build testing now. If you have any other opinion, let me know, plz.

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/mmc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index d6b7e4f..6e25b67 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1708,7 +1708,7 @@ static int mmc_complete_init(struct mmc *mmc)
>  int mmc_init(struct mmc *mmc)
>  {
>  	int err = 0;
> -	unsigned start;
> +	__maybe_unused unsigned start;
>  #ifdef CONFIG_DM_MMC
>  	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
>  
> 

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

* [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code
  2016-12-01  1:06 ` [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code Marek Vasut
@ 2016-12-01  5:07   ` Jaehoon Chung
  0 siblings, 0 replies; 41+ messages in thread
From: Jaehoon Chung @ 2016-12-01  5:07 UTC (permalink / raw)
  To: u-boot

On 12/01/2016 10:06 AM, Marek Vasut wrote:
> Add new configuration option CONFIG_MMC_TINY which strips away all
> memory allocation within the MMC code and code for handling multiple
> cards. This allows extremely space-constrained SPL code use the MMC
> framework.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Applied on u-boot-mmc. Thanks!

Best Regards,
Jaehoon Chung

> ---
> V2: Switch the MMC_TINY option to Kconfig
> ---
>  common/spl/spl_mmc.c     |  6 +++++-
>  drivers/mmc/Kconfig      | 15 +++++++++++++++
>  drivers/mmc/mmc.c        | 31 ++++++++++++++++++++++++++++++-
>  drivers/mmc/mmc_legacy.c | 32 ++++++++++++++++++++++++++++++++
>  include/mmc.h            |  1 +
>  5 files changed, 83 insertions(+), 2 deletions(-)
> 
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index a3d6b36..7dfcd0b 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -306,7 +306,11 @@ static int spl_mmc_load_image(struct spl_image_info *spl_image,
>  			if (part == 7)
>  				part = 0;
>  
> -			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
> +			if (CONFIG_IS_ENABLED(MMC_TINY))
> +				err = mmc_switch_part(mmc, part);
> +			else
> +				err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
> +
>  			if (err) {
>  #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
>  				puts("spl: mmc partition switch failed\n");
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
> index 24f4b28..5e84a41 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -26,6 +26,21 @@ config DM_MMC_OPS
>  	  option will be removed as soon as all DM_MMC drivers use it, as it
>  	  will the only supported behaviour.
>  
> +config SPL_MMC_TINY
> +	bool "Tiny MMC framework in SPL"
> +	help
> +	  Enable MMC framework tinification support. This option is useful if
> +	  if your SPL is extremely size constrained. Heed the warning, enable
> +	  this option if and only if you know exactly what you are doing, if
> +	  you are reading this help text, you most likely have no idea :-)
> +
> +	  The MMC framework is reduced to bare minimum to be useful. No malloc
> +	  support is needed for the MMC framework operation with this option
> +	  enabled. The framework supports exactly one MMC device and exactly
> +	  one MMC driver. The MMC driver can be adjusted to avoid any malloc
> +	  operations too, which can remove the need for malloc support in SPL
> +	  and thus further reduce footprint.
> +
>  config MSM_SDHCI
>  	bool "Qualcomm SDHCI controller"
>  	depends on DM_MMC && BLK && DM_MMC_OPS
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 6e25b67..19c4225 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -30,6 +30,29 @@ static const unsigned int sd_au_size[] = {
>  	SZ_16M / 512,	(SZ_16M + SZ_8M) / 512,	SZ_32M / 512,	SZ_64M / 512,
>  };
>  
> +#if CONFIG_IS_ENABLED(MMC_TINY)
> +static struct mmc mmc_static;
> +struct mmc *find_mmc_device(int dev_num)
> +{
> +	return &mmc_static;
> +}
> +
> +void mmc_do_preinit(void)
> +{
> +	struct mmc *m = &mmc_static;
> +#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
> +	mmc_set_preinit(m, 1);
> +#endif
> +	if (m->preinit)
> +		mmc_start_init(m);
> +}
> +
> +struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
> +{
> +	return &mmc->block_dev;
> +}
> +#endif
> +
>  #ifndef CONFIG_DM_MMC_OPS
>  __weak int board_mmc_getwp(struct mmc *mmc)
>  {
> @@ -259,7 +282,11 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
>  	if (!mmc)
>  		return 0;
>  
> -	err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
> +	if (CONFIG_IS_ENABLED(MMC_TINY))
> +		err = mmc_switch_part(mmc, block_dev->hwpart);
> +	else
> +		err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
> +
>  	if (err < 0)
>  		return 0;
>  
> @@ -1804,8 +1831,10 @@ int mmc_initialize(bd_t *bis)
>  	initialized = 1;
>  
>  #ifndef CONFIG_BLK
> +#if !CONFIG_IS_ENABLED(MMC_TINY)
>  	mmc_list_init();
>  #endif
> +#endif
>  	ret = mmc_probe(bis);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
> index 25361d1..bdf9d98 100644
> --- a/drivers/mmc/mmc_legacy.c
> +++ b/drivers/mmc/mmc_legacy.c
> @@ -13,6 +13,7 @@
>  static struct list_head mmc_devices;
>  static int cur_dev_num = -1;
>  
> +#if !CONFIG_IS_ENABLED(MMC_TINY)
>  struct mmc *find_mmc_device(int dev_num)
>  {
>  	struct mmc *m;
> @@ -62,6 +63,7 @@ void mmc_do_preinit(void)
>  			mmc_start_init(m);
>  	}
>  }
> +#endif
>  
>  void mmc_list_init(void)
>  {
> @@ -109,6 +111,35 @@ void print_mmc_devices(char separator)
>  void print_mmc_devices(char separator) { }
>  #endif
>  
> +#if CONFIG_IS_ENABLED(MMC_TINY)
> +static struct mmc mmc_static = {
> +	.dsr_imp		= 0,
> +	.dsr			= 0xffffffff,
> +	.block_dev = {
> +		.if_type	= IF_TYPE_MMC,
> +		.removable	= 1,
> +		.devnum		= 0,
> +		.block_read	= mmc_bread,
> +		.block_write	= mmc_bwrite,
> +		.block_erase	= mmc_berase,
> +		.part_type	= 0,
> +	},
> +};
> +
> +struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
> +{
> +	struct mmc *mmc = &mmc_static;
> +
> +	mmc->cfg = cfg;
> +	mmc->priv = priv;
> +
> +	return mmc;
> +}
> +
> +void mmc_destroy(struct mmc *mmc)
> +{
> +}
> +#else
>  struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
>  {
>  	struct blk_desc *bdesc;
> @@ -157,6 +188,7 @@ void mmc_destroy(struct mmc *mmc)
>  	/* only freeing memory for now */
>  	free(mmc);
>  }
> +#endif
>  
>  static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
>  {
> diff --git a/include/mmc.h b/include/mmc.h
> index e815eb3..f39be3c 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -513,6 +513,7 @@ void print_mmc_devices(char separator);
>   * @return 0 if there is no MMC device, else the number of devices
>   */
>  int get_mmc_num(void);
> +int mmc_switch_part(struct mmc *mmc, unsigned int part_num);
>  int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
>  		      enum mmc_hwpart_conf_mode mode);
>  
> 

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

* [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available
  2016-12-01  1:06 ` [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available Marek Vasut
@ 2016-12-01  5:07   ` Jaehoon Chung
  0 siblings, 0 replies; 41+ messages in thread
From: Jaehoon Chung @ 2016-12-01  5:07 UTC (permalink / raw)
  To: u-boot

On 12/01/2016 10:06 AM, Marek Vasut wrote:
> Make the spl_mmc_load_image() available globally, so it can be
> invoked directly by SPL on extremely space-constrained systems.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Applied on u-boot-mmc. Thanks!

Best Regards,
Jaehoon Chung

> ---
>  common/spl/spl_mmc.c | 4 ++--
>  include/spl.h        | 3 +++
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index 7dfcd0b..58b061f 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -272,8 +272,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
>  }
>  #endif
>  
> -static int spl_mmc_load_image(struct spl_image_info *spl_image,
> -			      struct spl_boot_device *bootdev)
> +int spl_mmc_load_image(struct spl_image_info *spl_image,
> +		       struct spl_boot_device *bootdev)
>  {
>  	struct mmc *mmc = NULL;
>  	u32 boot_mode;
> diff --git a/include/spl.h b/include/spl.h
> index e080a82..c727eb7 100644
> --- a/include/spl.h
> +++ b/include/spl.h
> @@ -234,4 +234,7 @@ bool spl_was_boot_source(void);
>   */
>  int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr);
>  
> +int spl_mmc_load_image(struct spl_image_info *spl_image,
> +		       struct spl_boot_device *bootdev);
> +
>  #endif
> 

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

* [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used
  2016-12-01  1:06 ` [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used Marek Vasut
  2016-12-01  4:17   ` Jaehoon Chung
@ 2016-12-01  5:14   ` Jaehoon Chung
  1 sibling, 0 replies; 41+ messages in thread
From: Jaehoon Chung @ 2016-12-01  5:14 UTC (permalink / raw)
  To: u-boot

On 12/01/2016 10:06 AM, Marek Vasut wrote:
> If debug() is not used, then the whole content of debug(...) will
> be removed by the preprocessor, which will result in the following
> warning. This patch adds __maybe_unused annotation to fix this.
> 
> drivers/mmc/mmc.c: In function ?mmc_init?:
> drivers/mmc/mmc.c:1685:11: warning: variable ?start? set but not used [-Wunused-but-set-variable]
>   unsigned start;
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>

Applied on u-boot-mmc. Thanks!

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/mmc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index d6b7e4f..6e25b67 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1708,7 +1708,7 @@ static int mmc_complete_init(struct mmc *mmc)
>  int mmc_init(struct mmc *mmc)
>  {
>  	int err = 0;
> -	unsigned start;
> +	__maybe_unused unsigned start;
>  #ifdef CONFIG_DM_MMC
>  	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
>  
> 

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

* [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver
  2016-12-01  1:06 ` [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver Marek Vasut
@ 2016-12-01  5:48   ` Jaehoon Chung
  2017-02-12 14:20   ` Andreas Färber
  1 sibling, 0 replies; 41+ messages in thread
From: Jaehoon Chung @ 2016-12-01  5:48 UTC (permalink / raw)
  To: u-boot

Dear Marek,

On 12/01/2016 10:06 AM, Marek Vasut wrote:
> From: Paul Burton <paul.burton@imgtec.com>
> 
> Add driver for the JZ47xx MSC controller.

I added more comment..Could you check my comments?

> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> Cc: Paul Burton <paul.burton@imgtec.com>
> Cc: Jaehoon Chung <jh80.chung@samsung.com>
> ---
>  drivers/mmc/Kconfig  |   6 +
>  drivers/mmc/Makefile |   1 +
>  drivers/mmc/jz_mmc.c | 445 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 452 insertions(+)
>  create mode 100644 drivers/mmc/jz_mmc.c
> 
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
> index 5e84a41..da26743 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -101,6 +101,12 @@ config MMC_UNIPHIER
>  	help
>  	  This selects support for the SD/MMC Host Controller on UniPhier SoCs.
>  
> +config JZ47XX_MMC
> +	bool "Ingenic JZ47xx SD/MMC Host Controller support"
> +	depends on ARCH_JZ47XX
> +	help
> +	  This selects support for the SD Card Controller on Ingenic JZ47xx SoCs.
> +
>  config SANDBOX_MMC
>  	bool "Sandbox MMC support"
>  	depends on MMC && SANDBOX
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index d850758..5f7cca3 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -57,6 +57,7 @@ obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
>  obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o
>  obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o
>  obj-$(CONFIG_ROCKCHIP_SDHCI) += rockchip_sdhci.o
> +obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
>  
>  ifdef CONFIG_SPL_BUILD
>  obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
> new file mode 100644
> index 0000000..95b3367
> --- /dev/null
> +++ b/drivers/mmc/jz_mmc.c
> @@ -0,0 +1,445 @@
> +/*
> + * Ingenic JZ MMC driver
> + *
> + * Copyright (c) 2013 Imagination Technologies
> + * Author: Paul Burton <paul.burton@imgtec.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <malloc.h>
> +#include <mmc.h>
> +#include <errno.h>
> +#include <asm/io.h>
> +#include <asm/unaligned.h>
> +#include <mach/jz4780.h>
> +#include <wait_bit.h>
> +
> +/* Registers */
> +#define MSC_STRPCL			0x000
> +#define MSC_STAT			0x004
> +#define MSC_CLKRT			0x008
> +#define MSC_CMDAT			0x00c
> +#define MSC_RESTO			0x010
> +#define MSC_RDTO			0x014
> +#define MSC_BLKLEN			0x018
> +#define MSC_NOB				0x01c
> +#define MSC_SNOB			0x020
> +#define MSC_IMASK			0x024
> +#define MSC_IREG			0x028
> +#define MSC_CMD				0x02c
> +#define MSC_ARG				0x030
> +#define MSC_RES				0x034
> +#define MSC_RXFIFO			0x038
> +#define MSC_TXFIFO			0x03c
> +#define MSC_LPM				0x040
> +#define MSC_DMAC			0x044
> +#define MSC_DMANDA			0x048
> +#define MSC_DMADA			0x04c
> +#define MSC_DMALEN			0x050
> +#define MSC_DMACMD			0x054
> +#define MSC_CTRL2			0x058
> +#define MSC_RTCNT			0x05c
> +#define MSC_DBG				0x0fc
> +
> +/* MSC Clock and Control Register (MSC_STRPCL) */
> +#define MSC_STRPCL_EXIT_MULTIPLE	BIT(7)
> +#define MSC_STRPCL_EXIT_TRANSFER	BIT(6)
> +#define MSC_STRPCL_START_READWAIT	BIT(5)
> +#define MSC_STRPCL_STOP_READWAIT	BIT(4)
> +#define MSC_STRPCL_RESET		BIT(3)
> +#define MSC_STRPCL_START_OP		BIT(2)
> +#define MSC_STRPCL_CLOCK_CONTROL_STOP	BIT(0)
> +#define MSC_STRPCL_CLOCK_CONTROL_START	BIT(1)
> +
> +/* MSC Status Register (MSC_STAT) */
> +#define MSC_STAT_AUTO_CMD_DONE		BIT(31)
> +#define MSC_STAT_IS_RESETTING		BIT(15)
> +#define MSC_STAT_SDIO_INT_ACTIVE	BIT(14)
> +#define MSC_STAT_PRG_DONE		BIT(13)
> +#define MSC_STAT_DATA_TRAN_DONE		BIT(12)
> +#define MSC_STAT_END_CMD_RES		BIT(11)
> +#define MSC_STAT_DATA_FIFO_AFULL	BIT(10)
> +#define MSC_STAT_IS_READWAIT		BIT(9)
> +#define MSC_STAT_CLK_EN			BIT(8)
> +#define MSC_STAT_DATA_FIFO_FULL		BIT(7)
> +#define MSC_STAT_DATA_FIFO_EMPTY	BIT(6)
> +#define MSC_STAT_CRC_RES_ERR		BIT(5)
> +#define MSC_STAT_CRC_READ_ERROR		BIT(4)
> +#define MSC_STAT_CRC_WRITE_ERROR	BIT(2)
> +#define MSC_STAT_CRC_WRITE_ERROR_NOSTS	BIT(4)

Does it use the same bit with MSC_STAT_CRC_READ_ERROR?

> +#define MSC_STAT_TIME_OUT_RES		BIT(1)
> +#define MSC_STAT_TIME_OUT_READ		BIT(0)
> +
> +/* MSC Bus Clock Control Register (MSC_CLKRT) */
> +#define MSC_CLKRT_CLK_RATE_MASK		0x7
> +
> +/* MSC Command Sequence Control Register (MSC_CMDAT) */
> +#define MSC_CMDAT_IO_ABORT		BIT(11)
> +#define MSC_CMDAT_BUS_WIDTH_1BIT	(0x0 << 9)
> +#define MSC_CMDAT_BUS_WIDTH_4BIT	(0x2 << 9)
> +#define MSC_CMDAT_DMA_EN		BIT(8)
> +#define MSC_CMDAT_INIT			BIT(7)
> +#define MSC_CMDAT_BUSY			BIT(6)
> +#define MSC_CMDAT_STREAM_BLOCK		BIT(5)
> +#define MSC_CMDAT_WRITE			BIT(4)
> +#define MSC_CMDAT_DATA_EN		BIT(3)
> +#define MSC_CMDAT_RESPONSE_MASK		0x7
> +#define MSC_CMDAT_RESPONSE_NONE		0x0 /* No response */
> +#define MSC_CMDAT_RESPONSE_R1		0x1 /* Format R1 and R1b */
> +#define MSC_CMDAT_RESPONSE_R2		0x2 /* Format R2 */
> +#define MSC_CMDAT_RESPONSE_R3		0x3 /* Format R3 */
> +#define MSC_CMDAT_RESPONSE_R4		0x4 /* Format R4 */
> +#define MSC_CMDAT_RESPONSE_R5		0x5 /* Format R5 */
> +#define MSC_CMDAT_RESPONSE_R6		0x6 /* Format R6 */
> +
> +/* MSC Interrupts Mask Register (MSC_IMASK) */
> +#define MSC_IMASK_TIME_OUT_RES		BIT(9)
> +#define MSC_IMASK_TIME_OUT_READ		BIT(8)
> +#define MSC_IMASK_SDIO			BIT(7)
> +#define MSC_IMASK_TXFIFO_WR_REQ		BIT(6)
> +#define MSC_IMASK_RXFIFO_RD_REQ		BIT(5)
> +#define MSC_IMASK_END_CMD_RES		BIT(2)
> +#define MSC_IMASK_PRG_DONE		BIT(1)
> +#define MSC_IMASK_DATA_TRAN_DONE	BIT(0)
> +
> +
> +/* MSC Interrupts Status Register (MSC_IREG) */
> +#define MSC_IREG_TIME_OUT_RES		BIT(9)
> +#define MSC_IREG_TIME_OUT_READ		BIT(8)
> +#define MSC_IREG_SDIO			BIT(7)
> +#define MSC_IREG_TXFIFO_WR_REQ		BIT(6)
> +#define MSC_IREG_RXFIFO_RD_REQ		BIT(5)
> +#define MSC_IREG_END_CMD_RES		BIT(2)
> +#define MSC_IREG_PRG_DONE		BIT(1)
> +#define MSC_IREG_DATA_TRAN_DONE		BIT(0)
> +
> +struct jz_mmc_priv {
> +	struct mmc_config	cfg;
> +	void __iomem		*regs;
> +	u32			flags;
> +/* priv flags */
> +#define JZ_MMC_BUS_WIDTH_MASK	0x3
> +#define JZ_MMC_BUS_WIDTH_1	0x0
> +#define JZ_MMC_BUS_WIDTH_4	0x2
> +#define JZ_MMC_BUS_WIDTH_8	0x3
> +#define JZ_MMC_SENT_INIT	BIT(2)
> +};
> +
> +static int jz_mmc_clock_rate(void)
> +{
> +	return 24000000;
> +}
> +
> +static int jz_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> +						struct mmc_data *data)
> +{
> +	struct jz_mmc_priv *priv = mmc->priv;
> +	u32 stat, mask, cmdat = 0;
> +
> +	/* stop the clock */
> +	writel(MSC_STRPCL_CLOCK_CONTROL_STOP, priv->regs + MSC_STRPCL);
> +
> +	wait_for_bit("jzmmc", priv->regs + MSC_STAT,
> +		     MSC_STAT_CLK_EN, 0, 10, 0);
> +
> +	writel(0, priv->regs + MSC_DMAC);
> +
> +	/* setup command */
> +	writel(cmd->cmdidx, priv->regs + MSC_CMD);
> +	writel(cmd->cmdarg, priv->regs + MSC_ARG);
> +
> +	if (data) {
> +		/* setup data */
> +		cmdat |= MSC_CMDAT_DATA_EN;
> +		if (data->flags & MMC_DATA_WRITE)
> +			cmdat |= MSC_CMDAT_WRITE;
> +
> +		writel(data->blocks, priv->regs + MSC_NOB);
> +		writel(data->blocksize, priv->regs + MSC_BLKLEN);
> +	} else {
> +		writel(0, priv->regs + MSC_NOB);
> +		writel(0, priv->regs + MSC_BLKLEN);
> +	}
> +
> +	/* setup response */
> +	switch (cmd->resp_type) {
> +	case MMC_RSP_NONE:
> +		break;
> +	case MMC_RSP_R1:
> +	case MMC_RSP_R1b:
> +		cmdat |= MSC_CMDAT_RESPONSE_R1;
> +		break;
> +	case MMC_RSP_R2:
> +		cmdat |= MSC_CMDAT_RESPONSE_R2;
> +		break;
> +	case MMC_RSP_R3:
> +		cmdat |= MSC_CMDAT_RESPONSE_R3;
> +		break;

Can be put MMC_RSP_NONE at here?

> +	default:
> +		break;
> +	}
> +
> +	if (cmd->resp_type & MMC_RSP_BUSY)
> +		cmdat |= MSC_CMDAT_BUSY;
> +
> +	/* set init for the first command only */
> +	if (!(priv->flags & JZ_MMC_SENT_INIT)) {
> +		cmdat |= MSC_CMDAT_INIT;
> +		priv->flags |= JZ_MMC_SENT_INIT;

Is it right?

> +	}
> +
> +	cmdat |= (priv->flags & JZ_MMC_BUS_WIDTH_MASK) << 9;

After priv->flags is set to JZ_MMC_SENT_INIT (BIT(2)), immediately priv->flags & JZ_MMC_BUS_WIDTH_MASK (0x3)
It's meaningless, doesn't?

> +
> +	/* write the data setup */
> +	writel(cmdat, priv->regs + MSC_CMDAT);
> +
> +	/* unmask interrupts */
> +	mask = 0xffffffff & ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_TIME_OUT_RES);

No..it's not readable..mask can be 0.
It seems that first set to all mask without CMD_RES and OUT_RES.
And at below sequence, clearing the bit after checking flags.

Why don't use the setting step, not clearing step?

> +	if (data) {
> +		mask &= ~MSC_IMASK_DATA_TRAN_DONE;
> +		if (data->flags & MMC_DATA_WRITE) {
> +			mask &= ~MSC_IMASK_TXFIFO_WR_REQ;

Then it can be "mask |= MSC_IMASK_TXFIFO_WR_REQ;" 

> +		} else {
> +			mask &= ~(MSC_IMASK_RXFIFO_RD_REQ |
> +				  MSC_IMASK_TIME_OUT_READ);

Ditto.

> +		}
> +	}
> +	writel(mask, priv->regs + MSC_IMASK);
> +
> +	/* clear interrupts */
> +	writel(0xffffffff, priv->regs + MSC_IREG);
> +
> +	/* start the command (& the clock) */
> +	writel(MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START,
> +	       priv->regs + MSC_STRPCL);
> +
> +	/* wait for completion */
> +	wait_for_bit("jzmmc", priv->regs + MSC_IREG,
> +		     MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES, 1, 1, 0);
> +	stat = readl(priv->regs + MSC_IREG);
> +	stat &= MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES;
> +	writel(stat, priv->regs + MSC_IREG);
> +	if (stat & MSC_IREG_TIME_OUT_RES)
> +		return -ETIMEDOUT;
> +
> +	if (cmd->resp_type & MMC_RSP_PRESENT) {
> +		/* read the response */
> +		if (cmd->resp_type & MMC_RSP_136) {
> +			u16 a, b, c, i;
> +			a = readw(priv->regs + MSC_RES);
> +			for (i = 0; i < 4; i++) {
> +				b = readw(priv->regs + MSC_RES);
> +				c = readw(priv->regs + MSC_RES);

a and b and c are same? Why read MSC_RES twice?
Is register value changed?

> +				cmd->response[i] = (a << 24) | (b << 8) |
> +						   (c >> 8);
> +				a = c;
> +			}
> +		} else {
> +			cmd->response[0] = readw(priv->regs + MSC_RES) << 24;
> +			cmd->response[0] |= readw(priv->regs + MSC_RES) << 8;
> +			cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff;

Hmm..I didn't understand this..MSC_RES is 16bit register?
It seems strange..

> +		}
> +	}
> +
> +	if (data && (data->flags & MMC_DATA_WRITE)) {
> +		/* write the data */
> +		int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4);
> +		const void *buf = data->src;
> +
> +		while (sz--) {
> +			u32 val = get_unaligned_le32(buf);
> +			wait_for_bit("jzmmc", priv->regs + MSC_IREG,
> +				     MSC_IREG_TXFIFO_WR_REQ, 1, 50, 0);
> +			writel(val, priv->regs + MSC_TXFIFO);
> +			buf += 4;
> +		}
> +	} else if (data && (data->flags & MMC_DATA_READ)) {
> +		/* read the data */
> +		int sz = data->blocks * data->blocksize;
> +		void *buf = data->dest;
> +
> +		do {
> +			stat = readl(priv->regs + MSC_STAT);
> +
> +			if (stat & MSC_STAT_TIME_OUT_READ)
> +				return -ETIMEDOUT;
> +			if (stat & MSC_STAT_CRC_READ_ERROR)
> +				return -EILSEQ;
> +			if (stat & MSC_STAT_DATA_FIFO_EMPTY) {
> +				udelay(10);
> +				continue;
> +			}
> +			do {
> +				u32 val = readl(priv->regs + MSC_RXFIFO);
> +
> +				if (sz == 1)
> +					*(u8 *)buf = (u8)val;
> +				else if (sz == 2)
> +					put_unaligned_le16(val, buf);
> +				else if (sz >= 4)
> +					put_unaligned_le32(val, buf);
> +				buf += 4;
> +				sz -= 4;
> +				stat = readl(priv->regs + MSC_STAT);
> +			} while (!(stat & MSC_STAT_DATA_FIFO_EMPTY));

Doesn't need to check whether size is zero or not?
And error bit checking for stat?

> +		} while (!(stat & MSC_STAT_DATA_TRAN_DONE));
> +	}
> +
> +	return 0;
> +}
> +
> +static void jz_mmc_set_ios(struct mmc *mmc)
> +{
> +	struct jz_mmc_priv *priv = mmc->priv;
> +	u32 real_rate = jz_mmc_clock_rate();
> +	u8 clk_div = 0;
> +
> +	/* calculate clock divide */
> +	while ((real_rate > mmc->clock) && (clk_div < 7)) {
> +		real_rate >>= 1;
> +		clk_div++;
> +	}
> +	writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
> +
> +	/* set the bus width for the next command */
> +	priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
> +	if (mmc->bus_width == 8)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_8;
> +	else if (mmc->bus_width == 4)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_4;
> +	else
> +		priv->flags |= JZ_MMC_BUS_WIDTH_1;
> +}
> +
> +static int jz_mmc_core_init(struct mmc *mmc)
> +{
> +	struct jz_mmc_priv *priv = mmc->priv;
> +
> +	/* Reset */
> +	writel(MSC_STRPCL_RESET, priv->regs + MSC_STRPCL);
> +
> +	wait_for_bit("jzmmc", priv->regs + MSC_STAT,
> +		     MSC_STAT_IS_RESETTING, 0, 10, 0);
> +
> +	/* Maximum timeouts */
> +	writel(0xffff, priv->regs + MSC_RESTO);
> +	writel(0xffffffff, priv->regs + MSC_RDTO);
> +
> +	/* Enable low power mode */
> +	writel(0x1, priv->regs + MSC_LPM);
> +
> +	return 0;
> +}
> +
> +static const struct mmc_ops jz_msc_ops = {
> +	.send_cmd	= jz_mmc_send_cmd,
> +	.set_ios	= jz_mmc_set_ios,
> +	.init		= jz_mmc_core_init,
> +};
> +
> +#ifdef CONFIG_MMC_TINY
> +static struct jz_mmc_priv jz_mmc_priv_static = {
> +	.cfg = {
> +		.name = "MSC",
> +		.ops = &jz_msc_ops,
> +
> +		.voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
> +				MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
> +				MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,

Really need to set all VDD?

> +		.host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
> +
> +		.f_min = 375000,
> +		.f_max = 48000000,
> +		.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
> +	},
> +};
> +
> +int jz_mmc_init(void __iomem *base)
> +{
> +	struct mmc *mmc;
> +
> +	jz_mmc_priv_static.regs = base;
> +
> +	mmc = mmc_create(&jz_mmc_priv_static.cfg, &jz_mmc_priv_static);
> +
> +	return mmc ? 0 : -ENODEV;
> +}
> +#endif
> +
> +#ifdef CONFIG_DM_MMC
> +#include <dm.h>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
> +{
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	const void *fdt = gd->fdt_blob;
> +	int node = dev->of_offset;
> +	struct mmc_config *cfg;
> +	int val;
> +
> +	priv->regs = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
> +	cfg = &priv->cfg;
> +
> +	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
> +	val = fdtdec_get_int(fdt, node, "bus-width", 1);
> +	if (val < 0) {
> +		printf("error: bus-width property missing\n");
> +		return -ENOENT;
> +	}

Maybe i think this condition doesn't need..
because if buswidth is wrong, it should be returned error at below switch statement.

> +
> +	switch (val) {
> +	case 0x8:
> +		cfg->host_caps |= MMC_MODE_8BIT;
> +	case 0x4:
> +		cfg->host_caps |= MMC_MODE_4BIT;
> +	case 0x1:
> +		break;
> +	default:
> +		printf("error: invalid bus-width property\n");
> +		return -ENOENT;
> +	}
> +
> +	cfg->f_min = 400000;
> +	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
> +	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
> +	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
> +
> +	return 0;
> +}
> +
> +static int jz_mmc_probe(struct udevice *dev)
> +{
> +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	struct mmc_config *cfg = &priv->cfg;
> +	struct mmc *mmc;
> +
> +	cfg->name = "MSC";

I guess...MSC is "Mobile Storage Controller"? Is it new IP for designware?
Just wondering.. :)

Best Regards,
Jaehoon Chung

> +	cfg->ops = &jz_msc_ops;
> +
> +	mmc = mmc_create(cfg, priv);
> +	if (!mmc)
> +		return -ENODEV;
> +
> +	mmc->dev = dev;
> +	upriv->mmc = mmc;
> +
> +	return 0;
> +}
> +static const struct udevice_id jz_mmc_ids[] = {
> +	{ .compatible = "ingenic,jz4780-mmc" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(jz_mmc_drv) = {
> +	.name			= "jz_mmc",
> +	.id			= UCLASS_MMC,
> +	.of_match		= jz_mmc_ids,
> +	.ofdata_to_platdata	= jz_mmc_ofdata_to_platdata,
> +	.probe			= jz_mmc_probe,
> +	.priv_auto_alloc_size	= sizeof(struct jz_mmc_priv),
> +};
> +#endif
> 

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

* [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (11 preceding siblings ...)
  2016-12-01  1:06 ` [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform Marek Vasut
@ 2016-12-03  4:26 ` Simon Glass
  2016-12-19 21:18 ` [U-Boot] [U-Boot,01/13] " Tom Rini
  13 siblings, 0 replies; 41+ messages in thread
From: Simon Glass @ 2016-12-03  4:26 UTC (permalink / raw)
  To: u-boot

On 30 November 2016 at 18:06, Marek Vasut <marex@denx.de> wrote:
> Add function which allows fetching the default FCR register setting
> from platform data for DM , while retaining old behavior for non-DM
> by returning UART_FCRVAL.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> ---
> V2: If CONFIG_DM_SERIAL and DEBUG_UART are enabled, the ns16550_getfcr()
>     can be invoked with NULL plat data . Check for this case and return
>     the default UART_FCRVAL then.
> V3: It turns out that if DEBUG_UART is defined, $port points directly to
>     hardware registers. Add additional ifdef to handle the case where
>     debug uart is enabled with DM_SERIAL correctly.
> V4: Use UART_FCRVAL in _debug_uart_init() directly
> ---
>  drivers/serial/ns16550.c | 18 ++++++++++++++++--
>  include/ns16550.h        |  1 +
>  2 files changed, 17 insertions(+), 2 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

But I think you are missing the 'v4' tag in your email subject.

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

* [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support
  2016-12-01  1:06 ` [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support Marek Vasut
@ 2016-12-03  4:26   ` Simon Glass
  2016-12-19 21:20   ` [U-Boot] [U-Boot, " Tom Rini
  1 sibling, 0 replies; 41+ messages in thread
From: Simon Glass @ 2016-12-03  4:26 UTC (permalink / raw)
  To: u-boot

On 30 November 2016 at 18:06, Marek Vasut <marex@denx.de> wrote:
> Add compatibility string for the Ingenic JZ4780 SoC, the necessary
> UART enable bit into FCR and register shift. Neither are encoded
> in the DTS coming from Linux, so we need to support it this way.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> Cc: Paul Burton <paul.burton@imgtec.com>
> ---
> V2: Drop the reg_shift and move it to OF
> ---
>  drivers/serial/ns16550.c | 5 +++++
>  include/ns16550.h        | 3 +++
>  2 files changed, 8 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [U-Boot,01/13] serial: 16550: Add getfcr accessor
  2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
                   ` (12 preceding siblings ...)
  2016-12-03  4:26 ` [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Simon Glass
@ 2016-12-19 21:18 ` Tom Rini
  13 siblings, 0 replies; 41+ messages in thread
From: Tom Rini @ 2016-12-19 21:18 UTC (permalink / raw)
  To: u-boot

On Thu, Dec 01, 2016 at 02:06:29AM +0100, Marek Vasut wrote:

> Add function which allows fetching the default FCR register setting
> from platform data for DM , while retaining old behavior for non-DM
> by returning UART_FCRVAL.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161219/5a9e136b/attachment.sig>

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

* [U-Boot] [U-Boot, 02/13] serial: 16550: Add port type as driver data
  2016-12-01  1:06 ` [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data Marek Vasut
@ 2016-12-19 21:19   ` Tom Rini
  0 siblings, 0 replies; 41+ messages in thread
From: Tom Rini @ 2016-12-19 21:19 UTC (permalink / raw)
  To: u-boot

On Thu, Dec 01, 2016 at 02:06:30AM +0100, Marek Vasut wrote:

> Add driver data to each compatible string to identify the type of
> the port. Since all the ports in the driver are entirely compatible
> with 16550 for now, all are marked with PORT_NS16550. But, there
> are ports which have specific quirks, like the JZ4780 UART, which
> do not have any DT property to denote the quirks. Instead, Linux
> uses the compatible string to discern such ports and enable the
> necessary quirks.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161219/07c4b3fe/attachment.sig>

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

* [U-Boot] [U-Boot, 03/13] serial: 16550: Add Ingenic JZ4780 support
  2016-12-01  1:06 ` [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support Marek Vasut
  2016-12-03  4:26   ` Simon Glass
@ 2016-12-19 21:20   ` Tom Rini
  1 sibling, 0 replies; 41+ messages in thread
From: Tom Rini @ 2016-12-19 21:20 UTC (permalink / raw)
  To: u-boot

On Thu, Dec 01, 2016 at 02:06:31AM +0100, Marek Vasut wrote:

> Add compatibility string for the Ingenic JZ4780 SoC, the necessary
> UART enable bit into FCR and register shift. Neither are encoded
> in the DTS coming from Linux, so we need to support it this way.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Tom Rini <trini@konsulko.com>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> Cc: Paul Burton <paul.burton@imgtec.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161219/46b743b2/attachment.sig>

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2016-12-01  1:06 ` [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform Marek Vasut
@ 2017-02-12 11:52   ` Andreas Färber
  2017-02-12 11:55     ` Marek Vasut
                       ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 11:52 UTC (permalink / raw)
  To: u-boot

Hi Marek,

Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> From: Paul Burton <paul.burton@imgtec.com>
> 
> Add support for the Creator CI20 platform based on the JZ4780 SoC.
> The DTS file comes from Linux 4.6 as of revision
> 78800558d104e003f9ae92e0107f1de39cf9de9f
> 
> So far, there are still a few details which will have to be fixed
> once they are fleshed out in Linux:
> - pinmux: Thus far, this board just pokes the pinmux registers to
>           set the pinmux. For MMC in SPL, this will have to stay.
> 	  But for full u-boot a proper pinmux driver will have to
> 	  be added once the pinmux semantics in DT are in mainline
> 	  Linux.
> - ethernet,efuse: DT bindings are missing from mainline Linux.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> Cc: Paul Burton <paul.burton@imgtec.com>
> ---
>  arch/mips/dts/Makefile        |   1 +
>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>  board/imgtec/ci20/Kconfig     |  35 +++++
>  board/imgtec/ci20/Makefile    |   5 +
>  board/imgtec/ci20/README      |  10 ++
>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>  configs/ci20_defconfig        |  28 ++++
>  include/configs/ci20.h        | 105 +++++++++++++
>  9 files changed, 663 insertions(+)
>  create mode 100644 arch/mips/dts/ci20.dts
>  create mode 100644 board/imgtec/ci20/Kconfig
>  create mode 100644 board/imgtec/ci20/Makefile
>  create mode 100644 board/imgtec/ci20/README
>  create mode 100644 board/imgtec/ci20/ci20.c
>  create mode 100644 configs/ci20_defconfig
>  create mode 100644 include/configs/ci20.h

I've looked into testing the remainder of this patchset, not seeing a
newer version. You can find my branch here:

https://github.com/afaerber/u-boot/commits/ci20

In particular I fixed the MMC set_ios signature to silence a warning
about the int vs. void return type, which I intend to clean up and submit.

The code compiled okay after some defconfig tweaks, save for a few
unused-variable SPL-only warnings, but testing did not give any output.
Investigating that, it seemed to me
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y was missing for
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR. Some other include options
could be moved into defconfig, too.

CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:

  LD      spl/u-boot-spl
mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
region `.sram'
mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
make[2]: *** [spl/u-boot-spl] Error 1
/home/andreas/OBS/u-boot/Makefile:1342: recipe for target
'spl/u-boot-spl' failed
make[1]: *** [spl/u-boot-spl] Error 2
make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
Makefile:150: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2

I've reviewed all SPL Kconfig options and found three seemingly unneeded
options defaulting to y, but I did not find a way to get this number
down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
even worse (~748). I also tried combining the downstream 4.8.1-built SPL
with the upstream U-Boot (from without
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR), but still no output.

Is this the reason this series is not respun?

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 11:52   ` Andreas Färber
@ 2017-02-12 11:55     ` Marek Vasut
  2017-02-12 12:24       ` Andreas Färber
  2017-02-12 14:14     ` Andreas Färber
  2017-02-14 22:58     ` Tom Rini
  2 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-12 11:55 UTC (permalink / raw)
  To: u-boot

On 02/12/2017 12:52 PM, Andreas F?rber wrote:
> Hi Marek,

Hi!

> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>> From: Paul Burton <paul.burton@imgtec.com>
>>
>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
>> The DTS file comes from Linux 4.6 as of revision
>> 78800558d104e003f9ae92e0107f1de39cf9de9f
>>
>> So far, there are still a few details which will have to be fixed
>> once they are fleshed out in Linux:
>> - pinmux: Thus far, this board just pokes the pinmux registers to
>>           set the pinmux. For MMC in SPL, this will have to stay.
>> 	  But for full u-boot a proper pinmux driver will have to
>> 	  be added once the pinmux semantics in DT are in mainline
>> 	  Linux.
>> - ethernet,efuse: DT bindings are missing from mainline Linux.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>> Cc: Paul Burton <paul.burton@imgtec.com>
>> ---
>>  arch/mips/dts/Makefile        |   1 +
>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>>  board/imgtec/ci20/Kconfig     |  35 +++++
>>  board/imgtec/ci20/Makefile    |   5 +
>>  board/imgtec/ci20/README      |  10 ++
>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>>  configs/ci20_defconfig        |  28 ++++
>>  include/configs/ci20.h        | 105 +++++++++++++
>>  9 files changed, 663 insertions(+)
>>  create mode 100644 arch/mips/dts/ci20.dts
>>  create mode 100644 board/imgtec/ci20/Kconfig
>>  create mode 100644 board/imgtec/ci20/Makefile
>>  create mode 100644 board/imgtec/ci20/README
>>  create mode 100644 board/imgtec/ci20/ci20.c
>>  create mode 100644 configs/ci20_defconfig
>>  create mode 100644 include/configs/ci20.h
> 
> I've looked into testing the remainder of this patchset, not seeing a
> newer version. You can find my branch here:
> 
> https://github.com/afaerber/u-boot/commits/ci20
> 
> In particular I fixed the MMC set_ios signature to silence a warning
> about the int vs. void return type, which I intend to clean up and submit.
> 
> The code compiled okay after some defconfig tweaks, save for a few
> unused-variable SPL-only warnings, but testing did not give any output.
> Investigating that, it seemed to me
> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y was missing for
> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR. Some other include options
> could be moved into defconfig, too.

Hm, so it broke again ? That's kinda sad ...

> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
> 
>   LD      spl/u-boot-spl
> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> region `.sram'
> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
> make[2]: *** [spl/u-boot-spl] Error 1
> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
> 'spl/u-boot-spl' failed
> make[1]: *** [spl/u-boot-spl] Error 2
> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
> Makefile:150: recipe for target 'sub-make' failed
> make: *** [sub-make] Error 2
> 
> I've reviewed all SPL Kconfig options and found three seemingly unneeded
> options defaulting to y, but I did not find a way to get this number
> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
> even worse (~748).

The recommended one was gcc 6.x , again, when I submitted it, I had no
problem. So it seems U-Boot again gained bloat, oh well ...

> I also tried combining the downstream 4.8.1-built SPL
> with the upstream U-Boot (from without
> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR), but still no output.
> 
> Is this the reason this series is not respun?

Eh ? No, the reason is I lack time :) The SPL will give you no output
though, since it is stripped down to bare minimum.

> Regards,
> Andreas
> 


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 11:55     ` Marek Vasut
@ 2017-02-12 12:24       ` Andreas Färber
  2017-02-12 12:53         ` Marek Vasut
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 12:24 UTC (permalink / raw)
  To: u-boot

Am 12.02.2017 um 12:55 schrieb Marek Vasut:
> On 02/12/2017 12:52 PM, Andreas F?rber wrote:
>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
>>
>>   LD      spl/u-boot-spl
>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>> region `.sram'
>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>> make[2]: *** [spl/u-boot-spl] Error 1
>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>> 'spl/u-boot-spl' failed
>> make[1]: *** [spl/u-boot-spl] Error 2
>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>> Makefile:150: recipe for target 'sub-make' failed
>> make: *** [sub-make] Error 2
>>
>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
>> options defaulting to y, but I did not find a way to get this number
>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
>> even worse (~748).
> 
> The recommended one was gcc 6.x , [...]

http://elinux.org/CI20_Dev_Zone#Toolchain

eLinux.org recommends a 2013.11 CodeSourcery toolchain with gcc 4.8.1:

"For compiling u-boot, please use this. u-boot first stage spl has a
size limitation.
And this toolchain manages to generate a binary that is just within the
limit."

Sadly it isn't.

I'm looking into a gcc7 package next, but that'll take a bit.

Cheers,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 12:24       ` Andreas Färber
@ 2017-02-12 12:53         ` Marek Vasut
  2017-02-12 13:24           ` Andreas Färber
  0 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-12 12:53 UTC (permalink / raw)
  To: u-boot

On 02/12/2017 01:24 PM, Andreas F?rber wrote:
> Am 12.02.2017 um 12:55 schrieb Marek Vasut:
>> On 02/12/2017 12:52 PM, Andreas F?rber wrote:
>>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
>>>
>>>   LD      spl/u-boot-spl
>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>> region `.sram'
>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>>> make[2]: *** [spl/u-boot-spl] Error 1
>>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>>> 'spl/u-boot-spl' failed
>>> make[1]: *** [spl/u-boot-spl] Error 2
>>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>>> Makefile:150: recipe for target 'sub-make' failed
>>> make: *** [sub-make] Error 2
>>>
>>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
>>> options defaulting to y, but I did not find a way to get this number
>>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
>>> even worse (~748).
>>
>> The recommended one was gcc 6.x , [...]
> 
> http://elinux.org/CI20_Dev_Zone#Toolchain
> 
> eLinux.org recommends a 2013.11 CodeSourcery toolchain with gcc 4.8.1:

Well probably for some ancient vendoruboot ;-)

> "For compiling u-boot, please use this. u-boot first stage spl has a
> size limitation.
> And this toolchain manages to generate a binary that is just within the
> limit."
> 
> Sadly it isn't.
> 
> I'm looking into a gcc7 package next, but that'll take a bit.

I don't think that's gonna help with U-Boot's bloat. I had to trim down
a lot of things already (ie. the MMC tinification), but it seems U-Boot
is growing and growing.


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 12:53         ` Marek Vasut
@ 2017-02-12 13:24           ` Andreas Färber
  2017-02-12 14:03             ` Marek Vasut
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 13:24 UTC (permalink / raw)
  To: u-boot

Am 12.02.2017 um 13:53 schrieb Marek Vasut:
> On 02/12/2017 01:24 PM, Andreas F?rber wrote:
>> Am 12.02.2017 um 12:55 schrieb Marek Vasut:
>>> On 02/12/2017 12:52 PM, Andreas F?rber wrote:
>>>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
>>>>
>>>>   LD      spl/u-boot-spl
>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>>> region `.sram'
>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>>>> make[2]: *** [spl/u-boot-spl] Error 1
>>>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>>>> 'spl/u-boot-spl' failed
>>>> make[1]: *** [spl/u-boot-spl] Error 2
>>>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>>>> Makefile:150: recipe for target 'sub-make' failed
>>>> make: *** [sub-make] Error 2
>>>>
>>>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
>>>> options defaulting to y, but I did not find a way to get this number
>>>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
>>>> even worse (~748).
>>>
>>> The recommended one was gcc 6.x , [...]
>>
>> http://elinux.org/CI20_Dev_Zone#Toolchain
>>
>> eLinux.org recommends a 2013.11 CodeSourcery toolchain with gcc 4.8.1:
> 
> Well probably for some ancient vendoruboot ;-)

v2013.10 based. ;-)

>> "For compiling u-boot, please use this. u-boot first stage spl has a
>> size limitation.
>> And this toolchain manages to generate a binary that is just within the
>> limit."
>>
>> Sadly it isn't.
>>
>> I'm looking into a gcc7 package next, but that'll take a bit.
> 
> I don't think that's gonna help with U-Boot's bloat. [...]

Yeah, slightly down with GCC 7.0.1, but not much:

  LD      spl/u-boot-spl
mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
region `.sram'
mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 264 bytes
../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
make[2]: *** [spl/u-boot-spl] Error 1
/home/andreas/OBS/u-boot/Makefile:1342: recipe for target
'spl/u-boot-spl' failed
make[1]: *** [spl/u-boot-spl] Error 2
make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
Makefile:150: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2

Cheers,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 13:24           ` Andreas Färber
@ 2017-02-12 14:03             ` Marek Vasut
  2017-06-11 21:45               ` Andreas Färber
  0 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-12 14:03 UTC (permalink / raw)
  To: u-boot

On 02/12/2017 02:24 PM, Andreas F?rber wrote:
> Am 12.02.2017 um 13:53 schrieb Marek Vasut:
>> On 02/12/2017 01:24 PM, Andreas F?rber wrote:
>>> Am 12.02.2017 um 12:55 schrieb Marek Vasut:
>>>> On 02/12/2017 12:52 PM, Andreas F?rber wrote:
>>>>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
>>>>>
>>>>>   LD      spl/u-boot-spl
>>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>>>> region `.sram'
>>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>>>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>>>>> make[2]: *** [spl/u-boot-spl] Error 1
>>>>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>>>>> 'spl/u-boot-spl' failed
>>>>> make[1]: *** [spl/u-boot-spl] Error 2
>>>>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>>>>> Makefile:150: recipe for target 'sub-make' failed
>>>>> make: *** [sub-make] Error 2
>>>>>
>>>>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
>>>>> options defaulting to y, but I did not find a way to get this number
>>>>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
>>>>> even worse (~748).
>>>>
>>>> The recommended one was gcc 6.x , [...]
>>>
>>> http://elinux.org/CI20_Dev_Zone#Toolchain
>>>
>>> eLinux.org recommends a 2013.11 CodeSourcery toolchain with gcc 4.8.1:
>>
>> Well probably for some ancient vendoruboot ;-)
> 
> v2013.10 based. ;-)

Well, that's still reasonably recent for a vendoruboot on mips ...

>>> "For compiling u-boot, please use this. u-boot first stage spl has a
>>> size limitation.
>>> And this toolchain manages to generate a binary that is just within the
>>> limit."
>>>
>>> Sadly it isn't.
>>>
>>> I'm looking into a gcc7 package next, but that'll take a bit.
>>
>> I don't think that's gonna help with U-Boot's bloat. [...]
> 
> Yeah, slightly down with GCC 7.0.1, but not much:

Right, it's the new bloat ...

>   LD      spl/u-boot-spl
> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> region `.sram'
> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 264 bytes
> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
> make[2]: *** [spl/u-boot-spl] Error 1
> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
> 'spl/u-boot-spl' failed
> make[1]: *** [spl/u-boot-spl] Error 2
> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
> Makefile:150: recipe for target 'sub-make' failed
> make: *** [sub-make] Error 2
> 
> Cheers,
> Andreas
> 


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 11:52   ` Andreas Färber
  2017-02-12 11:55     ` Marek Vasut
@ 2017-02-12 14:14     ` Andreas Färber
  2017-02-14 22:58     ` Tom Rini
  2 siblings, 0 replies; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 14:14 UTC (permalink / raw)
  To: u-boot

Am 12.02.2017 um 12:52 schrieb Andreas F?rber:
> Hi Marek,
> 
> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>> From: Paul Burton <paul.burton@imgtec.com>
>>
>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
>> The DTS file comes from Linux 4.6 as of revision
>> 78800558d104e003f9ae92e0107f1de39cf9de9f
>>
>> So far, there are still a few details which will have to be fixed
>> once they are fleshed out in Linux:
>> - pinmux: Thus far, this board just pokes the pinmux registers to
>>           set the pinmux. For MMC in SPL, this will have to stay.
>> 	  But for full u-boot a proper pinmux driver will have to
>> 	  be added once the pinmux semantics in DT are in mainline
>> 	  Linux.
>> - ethernet,efuse: DT bindings are missing from mainline Linux.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>> Cc: Paul Burton <paul.burton@imgtec.com>
>> ---
>>  arch/mips/dts/Makefile        |   1 +
>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>>  board/imgtec/ci20/Kconfig     |  35 +++++
>>  board/imgtec/ci20/Makefile    |   5 +
>>  board/imgtec/ci20/README      |  10 ++
>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>>  configs/ci20_defconfig        |  28 ++++
>>  include/configs/ci20.h        | 105 +++++++++++++
>>  9 files changed, 663 insertions(+)
>>  create mode 100644 arch/mips/dts/ci20.dts
>>  create mode 100644 board/imgtec/ci20/Kconfig
>>  create mode 100644 board/imgtec/ci20/Makefile
>>  create mode 100644 board/imgtec/ci20/README
>>  create mode 100644 board/imgtec/ci20/ci20.c
>>  create mode 100644 configs/ci20_defconfig
>>  create mode 100644 include/configs/ci20.h
> 
> I've looked into testing the remainder of this patchset, not seeing a
> newer version. You can find my branch here:
> 
> https://github.com/afaerber/u-boot/commits/ci20
> 
> In particular I fixed the MMC set_ios signature to silence a warning
> about the int vs. void return type, which I intend to clean up and submit.

Erm, I realized that the MMC driver is among the patches not yet merged,
so it'll have to be fixed in the next respin.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver
  2016-12-01  1:06 ` [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver Marek Vasut
  2016-12-01  5:48   ` Jaehoon Chung
@ 2017-02-12 14:20   ` Andreas Färber
  2017-02-12 14:29     ` Marek Vasut
  1 sibling, 1 reply; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 14:20 UTC (permalink / raw)
  To: u-boot

Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
> new file mode 100644
> index 0000000..95b3367
> --- /dev/null
> +++ b/drivers/mmc/jz_mmc.c
[...]
> +static void jz_mmc_set_ios(struct mmc *mmc)

This needs to return int by now.

> +{
> +	struct jz_mmc_priv *priv = mmc->priv;
> +	u32 real_rate = jz_mmc_clock_rate();
> +	u8 clk_div = 0;
> +
> +	/* calculate clock divide */
> +	while ((real_rate > mmc->clock) && (clk_div < 7)) {
> +		real_rate >>= 1;
> +		clk_div++;
> +	}
> +	writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
> +
> +	/* set the bus width for the next command */
> +	priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
> +	if (mmc->bus_width == 8)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_8;
> +	else if (mmc->bus_width == 4)
> +		priv->flags |= JZ_MMC_BUS_WIDTH_4;
> +	else
> +		priv->flags |= JZ_MMC_BUS_WIDTH_1;

return 0;

> +}
[...]
> +#ifdef CONFIG_MMC_TINY

Shouldn't this rather use something like #if defined(CONFIG_SPL_BUILD)
&& defined(CONFIG_SPL_MMC_TINY) so that we can drop the #define from ci20.h?

> +static struct jz_mmc_priv jz_mmc_priv_static = {
> +	.cfg = {
> +		.name = "MSC",
> +		.ops = &jz_msc_ops,
> +
> +		.voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
> +				MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
> +				MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,
> +		.host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
> +
> +		.f_min = 375000,
> +		.f_max = 48000000,
> +		.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
> +	},
> +};
> +
> +int jz_mmc_init(void __iomem *base)
> +{
> +	struct mmc *mmc;
> +
> +	jz_mmc_priv_static.regs = base;
> +
> +	mmc = mmc_create(&jz_mmc_priv_static.cfg, &jz_mmc_priv_static);
> +
> +	return mmc ? 0 : -ENODEV;
> +}
> +#endif
> +
> +#ifdef CONFIG_DM_MMC

Similarly here !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM_MMC)?

> +#include <dm.h>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
> +{
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	const void *fdt = gd->fdt_blob;
> +	int node = dev->of_offset;
> +	struct mmc_config *cfg;
> +	int val;
> +
> +	priv->regs = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
> +	cfg = &priv->cfg;
> +
> +	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
> +	val = fdtdec_get_int(fdt, node, "bus-width", 1);
> +	if (val < 0) {
> +		printf("error: bus-width property missing\n");
> +		return -ENOENT;
> +	}
> +
> +	switch (val) {
> +	case 0x8:
> +		cfg->host_caps |= MMC_MODE_8BIT;
> +	case 0x4:
> +		cfg->host_caps |= MMC_MODE_4BIT;
> +	case 0x1:
> +		break;
> +	default:
> +		printf("error: invalid bus-width property\n");
> +		return -ENOENT;
> +	}
> +
> +	cfg->f_min = 400000;
> +	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
> +	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
> +	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
> +
> +	return 0;
> +}
> +
> +static int jz_mmc_probe(struct udevice *dev)
> +{
> +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
> +	struct mmc_config *cfg = &priv->cfg;
> +	struct mmc *mmc;
> +
> +	cfg->name = "MSC";
> +	cfg->ops = &jz_msc_ops;
> +
> +	mmc = mmc_create(cfg, priv);
> +	if (!mmc)
> +		return -ENODEV;
> +
> +	mmc->dev = dev;
> +	upriv->mmc = mmc;
> +
> +	return 0;
> +}
> +static const struct udevice_id jz_mmc_ids[] = {
> +	{ .compatible = "ingenic,jz4780-mmc" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(jz_mmc_drv) = {
> +	.name			= "jz_mmc",
> +	.id			= UCLASS_MMC,
> +	.of_match		= jz_mmc_ids,
> +	.ofdata_to_platdata	= jz_mmc_ofdata_to_platdata,
> +	.probe			= jz_mmc_probe,
> +	.priv_auto_alloc_size	= sizeof(struct jz_mmc_priv),
> +};
> +#endif

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver
  2017-02-12 14:20   ` Andreas Färber
@ 2017-02-12 14:29     ` Marek Vasut
  2017-02-12 14:56       ` Andreas Färber
  0 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-12 14:29 UTC (permalink / raw)
  To: u-boot

On 02/12/2017 03:20 PM, Andreas F?rber wrote:
> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
>> new file mode 100644
>> index 0000000..95b3367
>> --- /dev/null
>> +++ b/drivers/mmc/jz_mmc.c
> [...]
>> +static void jz_mmc_set_ios(struct mmc *mmc)
> 
> This needs to return int by now.

Feel free to fix this up and resubmit :)

>> +{
>> +	struct jz_mmc_priv *priv = mmc->priv;
>> +	u32 real_rate = jz_mmc_clock_rate();
>> +	u8 clk_div = 0;
>> +
>> +	/* calculate clock divide */
>> +	while ((real_rate > mmc->clock) && (clk_div < 7)) {
>> +		real_rate >>= 1;
>> +		clk_div++;
>> +	}
>> +	writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT);
>> +
>> +	/* set the bus width for the next command */
>> +	priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK;
>> +	if (mmc->bus_width == 8)
>> +		priv->flags |= JZ_MMC_BUS_WIDTH_8;
>> +	else if (mmc->bus_width == 4)
>> +		priv->flags |= JZ_MMC_BUS_WIDTH_4;
>> +	else
>> +		priv->flags |= JZ_MMC_BUS_WIDTH_1;
> 
> return 0;
> 
>> +}
> [...]
>> +#ifdef CONFIG_MMC_TINY
> 
> Shouldn't this rather use something like #if defined(CONFIG_SPL_BUILD)
> && defined(CONFIG_SPL_MMC_TINY) so that we can drop the #define from ci20.h?
> 
>> +static struct jz_mmc_priv jz_mmc_priv_static = {
>> +	.cfg = {
>> +		.name = "MSC",
>> +		.ops = &jz_msc_ops,
>> +
>> +		.voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
>> +				MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
>> +				MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36,
>> +		.host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
>> +
>> +		.f_min = 375000,
>> +		.f_max = 48000000,
>> +		.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
>> +	},
>> +};
>> +
>> +int jz_mmc_init(void __iomem *base)
>> +{
>> +	struct mmc *mmc;
>> +
>> +	jz_mmc_priv_static.regs = base;
>> +
>> +	mmc = mmc_create(&jz_mmc_priv_static.cfg, &jz_mmc_priv_static);
>> +
>> +	return mmc ? 0 : -ENODEV;
>> +}
>> +#endif
>> +
>> +#ifdef CONFIG_DM_MMC
> 
> Similarly here !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM_MMC)?
> 
>> +#include <dm.h>
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static int jz_mmc_ofdata_to_platdata(struct udevice *dev)
>> +{
>> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
>> +	const void *fdt = gd->fdt_blob;
>> +	int node = dev->of_offset;
>> +	struct mmc_config *cfg;
>> +	int val;
>> +
>> +	priv->regs = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
>> +	cfg = &priv->cfg;
>> +
>> +	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
>> +	val = fdtdec_get_int(fdt, node, "bus-width", 1);
>> +	if (val < 0) {
>> +		printf("error: bus-width property missing\n");
>> +		return -ENOENT;
>> +	}
>> +
>> +	switch (val) {
>> +	case 0x8:
>> +		cfg->host_caps |= MMC_MODE_8BIT;
>> +	case 0x4:
>> +		cfg->host_caps |= MMC_MODE_4BIT;
>> +	case 0x1:
>> +		break;
>> +	default:
>> +		printf("error: invalid bus-width property\n");
>> +		return -ENOENT;
>> +	}
>> +
>> +	cfg->f_min = 400000;
>> +	cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
>> +	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
>> +	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
>> +
>> +	return 0;
>> +}
>> +
>> +static int jz_mmc_probe(struct udevice *dev)
>> +{
>> +	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>> +	struct jz_mmc_priv *priv = dev_get_priv(dev);
>> +	struct mmc_config *cfg = &priv->cfg;
>> +	struct mmc *mmc;
>> +
>> +	cfg->name = "MSC";
>> +	cfg->ops = &jz_msc_ops;
>> +
>> +	mmc = mmc_create(cfg, priv);
>> +	if (!mmc)
>> +		return -ENODEV;
>> +
>> +	mmc->dev = dev;
>> +	upriv->mmc = mmc;
>> +
>> +	return 0;
>> +}
>> +static const struct udevice_id jz_mmc_ids[] = {
>> +	{ .compatible = "ingenic,jz4780-mmc" },
>> +	{ }
>> +};
>> +
>> +U_BOOT_DRIVER(jz_mmc_drv) = {
>> +	.name			= "jz_mmc",
>> +	.id			= UCLASS_MMC,
>> +	.of_match		= jz_mmc_ids,
>> +	.ofdata_to_platdata	= jz_mmc_ofdata_to_platdata,
>> +	.probe			= jz_mmc_probe,
>> +	.priv_auto_alloc_size	= sizeof(struct jz_mmc_priv),
>> +};
>> +#endif
> 
> Regards,
> Andreas
> 


-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver
  2017-02-12 14:29     ` Marek Vasut
@ 2017-02-12 14:56       ` Andreas Färber
  0 siblings, 0 replies; 41+ messages in thread
From: Andreas Färber @ 2017-02-12 14:56 UTC (permalink / raw)
  To: u-boot

Am 12.02.2017 um 15:29 schrieb Marek Vasut:
> On 02/12/2017 03:20 PM, Andreas F?rber wrote:
>> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>>> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
>>> new file mode 100644
>>> index 0000000..95b3367
>>> --- /dev/null
>>> +++ b/drivers/mmc/jz_mmc.c
>> [...]
>>> +static void jz_mmc_set_ios(struct mmc *mmc)
>>
>> This needs to return int by now.
> 
> Feel free to fix this up and resubmit :)

Resubmitting with this trivial change wouldn't resolve Jaehoon's
unanswered code questions from Dec 1 though. ;)

As mentioned elsewhere, my trivial fixup is available for anyone who
wants to test or squash&resubmit:

https://github.com/afaerber/u-boot/commits/ci20

I don't know the Ingenic registers myself, sorry, and am already failing
to resubmit my own unfinished RK3368 series...

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 11:52   ` Andreas Färber
  2017-02-12 11:55     ` Marek Vasut
  2017-02-12 14:14     ` Andreas Färber
@ 2017-02-14 22:58     ` Tom Rini
  2017-02-14 23:03       ` Marek Vasut
  2 siblings, 1 reply; 41+ messages in thread
From: Tom Rini @ 2017-02-14 22:58 UTC (permalink / raw)
  To: u-boot

On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
> Hi Marek,
> 
> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> > From: Paul Burton <paul.burton@imgtec.com>
> > 
> > Add support for the Creator CI20 platform based on the JZ4780 SoC.
> > The DTS file comes from Linux 4.6 as of revision
> > 78800558d104e003f9ae92e0107f1de39cf9de9f
> > 
> > So far, there are still a few details which will have to be fixed
> > once they are fleshed out in Linux:
> > - pinmux: Thus far, this board just pokes the pinmux registers to
> >           set the pinmux. For MMC in SPL, this will have to stay.
> > 	  But for full u-boot a proper pinmux driver will have to
> > 	  be added once the pinmux semantics in DT are in mainline
> > 	  Linux.
> > - ethernet,efuse: DT bindings are missing from mainline Linux.
> > 
> > Signed-off-by: Marek Vasut <marex@denx.de>
> > Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> > Cc: Paul Burton <paul.burton@imgtec.com>
> > ---
> >  arch/mips/dts/Makefile        |   1 +
> >  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
> >  arch/mips/mach-jz47xx/Kconfig |  11 ++
> >  board/imgtec/ci20/Kconfig     |  35 +++++
> >  board/imgtec/ci20/Makefile    |   5 +
> >  board/imgtec/ci20/README      |  10 ++
> >  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
> >  configs/ci20_defconfig        |  28 ++++
> >  include/configs/ci20.h        | 105 +++++++++++++
> >  9 files changed, 663 insertions(+)
> >  create mode 100644 arch/mips/dts/ci20.dts
> >  create mode 100644 board/imgtec/ci20/Kconfig
> >  create mode 100644 board/imgtec/ci20/Makefile
> >  create mode 100644 board/imgtec/ci20/README
> >  create mode 100644 board/imgtec/ci20/ci20.c
> >  create mode 100644 configs/ci20_defconfig
> >  create mode 100644 include/configs/ci20.h
> 
> I've looked into testing the remainder of this patchset, not seeing a
> newer version. You can find my branch here:
> 
> https://github.com/afaerber/u-boot/commits/ci20
[snip]
>   LD      spl/u-boot-spl
> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> region `.sram'
> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes

I can recreate that too here real quick, but can't test out changes on
my Ci20 right now.  Can you try:

diff --git a/include/configs/ci20.h b/include/configs/ci20.h
index 4503adb..9e2ad7b 100644
--- a/include/configs/ci20.h
+++ b/include/configs/ci20.h
@@ -70,10 +70,10 @@
 /* SPL */
 #define CONFIG_SPL_FRAMEWORK
 
-#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
+#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
 
 #define CONFIG_SPL_TEXT_BASE		0xf4000a00
-#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
+#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)
 
 #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
 #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */


Now, off the top of my head I'm only giving myself a 50/50 chance of
having moved the stack address in the correct direction.  And note that
I don't know why we say only max of 2KB for stack, and then ensure we
have 2.5KB of room, but I've shifted 512 bytes from one side to the
other.  And it's quite probable that we should make use having SPL stack
get moved into DDR, but I don't have the memory map handy either (and
based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
should be in DDR space, I don't know if internal memory directly follows
into DDR here or what).

I do want to reiterate that I am eager to have Ci20 be working in
mainline as I have one and I want to figure out how to include it in my
farm, or at least manual testing from time to time.  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170214/dc0a1d45/attachment.sig>

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-14 22:58     ` Tom Rini
@ 2017-02-14 23:03       ` Marek Vasut
  2017-02-14 23:11         ` Tom Rini
  0 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-14 23:03 UTC (permalink / raw)
  To: u-boot

On 02/14/2017 11:58 PM, Tom Rini wrote:
> On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
>> Hi Marek,
>>
>> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>>> From: Paul Burton <paul.burton@imgtec.com>
>>>
>>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
>>> The DTS file comes from Linux 4.6 as of revision
>>> 78800558d104e003f9ae92e0107f1de39cf9de9f
>>>
>>> So far, there are still a few details which will have to be fixed
>>> once they are fleshed out in Linux:
>>> - pinmux: Thus far, this board just pokes the pinmux registers to
>>>           set the pinmux. For MMC in SPL, this will have to stay.
>>> 	  But for full u-boot a proper pinmux driver will have to
>>> 	  be added once the pinmux semantics in DT are in mainline
>>> 	  Linux.
>>> - ethernet,efuse: DT bindings are missing from mainline Linux.
>>>
>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>>> Cc: Paul Burton <paul.burton@imgtec.com>
>>> ---
>>>  arch/mips/dts/Makefile        |   1 +
>>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>>>  board/imgtec/ci20/Kconfig     |  35 +++++
>>>  board/imgtec/ci20/Makefile    |   5 +
>>>  board/imgtec/ci20/README      |  10 ++
>>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>>>  configs/ci20_defconfig        |  28 ++++
>>>  include/configs/ci20.h        | 105 +++++++++++++
>>>  9 files changed, 663 insertions(+)
>>>  create mode 100644 arch/mips/dts/ci20.dts
>>>  create mode 100644 board/imgtec/ci20/Kconfig
>>>  create mode 100644 board/imgtec/ci20/Makefile
>>>  create mode 100644 board/imgtec/ci20/README
>>>  create mode 100644 board/imgtec/ci20/ci20.c
>>>  create mode 100644 configs/ci20_defconfig
>>>  create mode 100644 include/configs/ci20.h
>>
>> I've looked into testing the remainder of this patchset, not seeing a
>> newer version. You can find my branch here:
>>
>> https://github.com/afaerber/u-boot/commits/ci20
> [snip]
>>   LD      spl/u-boot-spl
>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>> region `.sram'
>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
> 
> I can recreate that too here real quick, but can't test out changes on
> my Ci20 right now.  Can you try:
> 
> diff --git a/include/configs/ci20.h b/include/configs/ci20.h
> index 4503adb..9e2ad7b 100644
> --- a/include/configs/ci20.h
> +++ b/include/configs/ci20.h
> @@ -70,10 +70,10 @@
>  /* SPL */
>  #define CONFIG_SPL_FRAMEWORK
>  
> -#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
> +#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
>  
>  #define CONFIG_SPL_TEXT_BASE		0xf4000a00
> -#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
> +#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)

This will not work, the stack is configured at it's limit already.

>  #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
>  #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
> 
> 
> Now, off the top of my head I'm only giving myself a 50/50 chance of
> having moved the stack address in the correct direction.  And note that
> I don't know why we say only max of 2KB for stack, and then ensure we
> have 2.5KB of room, but I've shifted 512 bytes from one side to the
> other.  And it's quite probable that we should make use having SPL stack
> get moved into DDR

You mean the DDR which you init in the SPL ? :)

>, but I don't have the memory map handy either (and
> based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
> should be in DDR space, I don't know if internal memory directly follows
> into DDR here or what).
> 
> I do want to reiterate that I am eager to have Ci20 be working in
> mainline as I have one and I want to figure out how to include it in my
> farm, or at least manual testing from time to time.  Thanks!

Well, these patches were rotting on the list for year or so without
getting any attention, until the point I had to scream on the IRC to get
ANY review comments, multiple times, so I really see a lot of interest
in getting this in, indeed :)

-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-14 23:03       ` Marek Vasut
@ 2017-02-14 23:11         ` Tom Rini
  2017-02-15 20:46           ` Marek Vasut
  0 siblings, 1 reply; 41+ messages in thread
From: Tom Rini @ 2017-02-14 23:11 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 15, 2017 at 12:03:32AM +0100, Marek Vasut wrote:
> On 02/14/2017 11:58 PM, Tom Rini wrote:
> > On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
> >> Hi Marek,
> >>
> >> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> >>> From: Paul Burton <paul.burton@imgtec.com>
> >>>
> >>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
> >>> The DTS file comes from Linux 4.6 as of revision
> >>> 78800558d104e003f9ae92e0107f1de39cf9de9f
> >>>
> >>> So far, there are still a few details which will have to be fixed
> >>> once they are fleshed out in Linux:
> >>> - pinmux: Thus far, this board just pokes the pinmux registers to
> >>>           set the pinmux. For MMC in SPL, this will have to stay.
> >>> 	  But for full u-boot a proper pinmux driver will have to
> >>> 	  be added once the pinmux semantics in DT are in mainline
> >>> 	  Linux.
> >>> - ethernet,efuse: DT bindings are missing from mainline Linux.
> >>>
> >>> Signed-off-by: Marek Vasut <marex@denx.de>
> >>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> >>> Cc: Paul Burton <paul.burton@imgtec.com>
> >>> ---
> >>>  arch/mips/dts/Makefile        |   1 +
> >>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
> >>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
> >>>  board/imgtec/ci20/Kconfig     |  35 +++++
> >>>  board/imgtec/ci20/Makefile    |   5 +
> >>>  board/imgtec/ci20/README      |  10 ++
> >>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
> >>>  configs/ci20_defconfig        |  28 ++++
> >>>  include/configs/ci20.h        | 105 +++++++++++++
> >>>  9 files changed, 663 insertions(+)
> >>>  create mode 100644 arch/mips/dts/ci20.dts
> >>>  create mode 100644 board/imgtec/ci20/Kconfig
> >>>  create mode 100644 board/imgtec/ci20/Makefile
> >>>  create mode 100644 board/imgtec/ci20/README
> >>>  create mode 100644 board/imgtec/ci20/ci20.c
> >>>  create mode 100644 configs/ci20_defconfig
> >>>  create mode 100644 include/configs/ci20.h
> >>
> >> I've looked into testing the remainder of this patchset, not seeing a
> >> newer version. You can find my branch here:
> >>
> >> https://github.com/afaerber/u-boot/commits/ci20
> > [snip]
> >>   LD      spl/u-boot-spl
> >> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> >> region `.sram'
> >> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
> > 
> > I can recreate that too here real quick, but can't test out changes on
> > my Ci20 right now.  Can you try:
> > 
> > diff --git a/include/configs/ci20.h b/include/configs/ci20.h
> > index 4503adb..9e2ad7b 100644
> > --- a/include/configs/ci20.h
> > +++ b/include/configs/ci20.h
> > @@ -70,10 +70,10 @@
> >  /* SPL */
> >  #define CONFIG_SPL_FRAMEWORK
> >  
> > -#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
> > +#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
> >  
> >  #define CONFIG_SPL_TEXT_BASE		0xf4000a00
> > -#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
> > +#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)
> 
> This will not work, the stack is configured at it's limit already.
> 
> >  #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
> >  #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
> > 
> > 
> > Now, off the top of my head I'm only giving myself a 50/50 chance of
> > having moved the stack address in the correct direction.  And note that
> > I don't know why we say only max of 2KB for stack, and then ensure we
> > have 2.5KB of room, but I've shifted 512 bytes from one side to the
> > other.  And it's quite probable that we should make use having SPL stack
> > get moved into DDR
> 
> You mean the DDR which you init in the SPL ? :)

Yes, I mean the DDR which we init in the SPL, after we've init'd it, so
that we can work more comfortably in cramped and constrained spaces.

> >, but I don't have the memory map handy either (and
> > based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
> > should be in DDR space, I don't know if internal memory directly follows
> > into DDR here or what).
> > 
> > I do want to reiterate that I am eager to have Ci20 be working in
> > mainline as I have one and I want to figure out how to include it in my
> > farm, or at least manual testing from time to time.  Thanks!
> 
> Well, these patches were rotting on the list for year or so without
> getting any attention, until the point I had to scream on the IRC to get
> ANY review comments, multiple times, so I really see a lot of interest
> in getting this in, indeed :)

Yeah, I feel bad about not having more time for all of the various
things I'd like to see happen, happen.  But that's why I bought the Ci20
and Ci40 (and some other boards) as a regular person rather than try and
get a freebie.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170214/04cd84c6/attachment.sig>

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-14 23:11         ` Tom Rini
@ 2017-02-15 20:46           ` Marek Vasut
  2017-02-15 21:50             ` Tom Rini
  0 siblings, 1 reply; 41+ messages in thread
From: Marek Vasut @ 2017-02-15 20:46 UTC (permalink / raw)
  To: u-boot

On 02/15/2017 12:11 AM, Tom Rini wrote:
> On Wed, Feb 15, 2017 at 12:03:32AM +0100, Marek Vasut wrote:
>> On 02/14/2017 11:58 PM, Tom Rini wrote:
>>> On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
>>>> Hi Marek,
>>>>
>>>> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>>>>> From: Paul Burton <paul.burton@imgtec.com>
>>>>>
>>>>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
>>>>> The DTS file comes from Linux 4.6 as of revision
>>>>> 78800558d104e003f9ae92e0107f1de39cf9de9f
>>>>>
>>>>> So far, there are still a few details which will have to be fixed
>>>>> once they are fleshed out in Linux:
>>>>> - pinmux: Thus far, this board just pokes the pinmux registers to
>>>>>           set the pinmux. For MMC in SPL, this will have to stay.
>>>>> 	  But for full u-boot a proper pinmux driver will have to
>>>>> 	  be added once the pinmux semantics in DT are in mainline
>>>>> 	  Linux.
>>>>> - ethernet,efuse: DT bindings are missing from mainline Linux.
>>>>>
>>>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>>>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>>>>> Cc: Paul Burton <paul.burton@imgtec.com>
>>>>> ---
>>>>>  arch/mips/dts/Makefile        |   1 +
>>>>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>>>>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>>>>>  board/imgtec/ci20/Kconfig     |  35 +++++
>>>>>  board/imgtec/ci20/Makefile    |   5 +
>>>>>  board/imgtec/ci20/README      |  10 ++
>>>>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>>>>>  configs/ci20_defconfig        |  28 ++++
>>>>>  include/configs/ci20.h        | 105 +++++++++++++
>>>>>  9 files changed, 663 insertions(+)
>>>>>  create mode 100644 arch/mips/dts/ci20.dts
>>>>>  create mode 100644 board/imgtec/ci20/Kconfig
>>>>>  create mode 100644 board/imgtec/ci20/Makefile
>>>>>  create mode 100644 board/imgtec/ci20/README
>>>>>  create mode 100644 board/imgtec/ci20/ci20.c
>>>>>  create mode 100644 configs/ci20_defconfig
>>>>>  create mode 100644 include/configs/ci20.h
>>>>
>>>> I've looked into testing the remainder of this patchset, not seeing a
>>>> newer version. You can find my branch here:
>>>>
>>>> https://github.com/afaerber/u-boot/commits/ci20
>>> [snip]
>>>>   LD      spl/u-boot-spl
>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>>> region `.sram'
>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>>
>>> I can recreate that too here real quick, but can't test out changes on
>>> my Ci20 right now.  Can you try:
>>>
>>> diff --git a/include/configs/ci20.h b/include/configs/ci20.h
>>> index 4503adb..9e2ad7b 100644
>>> --- a/include/configs/ci20.h
>>> +++ b/include/configs/ci20.h
>>> @@ -70,10 +70,10 @@
>>>  /* SPL */
>>>  #define CONFIG_SPL_FRAMEWORK
>>>  
>>> -#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
>>> +#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
>>>  
>>>  #define CONFIG_SPL_TEXT_BASE		0xf4000a00
>>> -#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
>>> +#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)
>>
>> This will not work, the stack is configured at it's limit already.
>>
>>>  #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
>>>  #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
>>>
>>>
>>> Now, off the top of my head I'm only giving myself a 50/50 chance of
>>> having moved the stack address in the correct direction.  And note that
>>> I don't know why we say only max of 2KB for stack, and then ensure we
>>> have 2.5KB of room, but I've shifted 512 bytes from one side to the
>>> other.  And it's quite probable that we should make use having SPL stack
>>> get moved into DDR
>>
>> You mean the DDR which you init in the SPL ? :)
> 
> Yes, I mean the DDR which we init in the SPL, after we've init'd it, so
> that we can work more comfortably in cramped and constrained spaces.

You know, you are still limited by the 14 kiB load limit of the BootROM.
I think there's more than 16 kiB of SRAM total, so there's no real
problem with the stack. The problem is that 14 kiB load limit of the
BootROM, it will NOT LOAD MORE than 14 kiB of code . I tried (because,
well, 14 kiB is too small). IT DOES NOT WORK.

>>> , but I don't have the memory map handy either (and
>>> based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
>>> should be in DDR space, I don't know if internal memory directly follows
>>> into DDR here or what).
>>>
>>> I do want to reiterate that I am eager to have Ci20 be working in
>>> mainline as I have one and I want to figure out how to include it in my
>>> farm, or at least manual testing from time to time.  Thanks!
>>
>> Well, these patches were rotting on the list for year or so without
>> getting any attention, until the point I had to scream on the IRC to get
>> ANY review comments, multiple times, so I really see a lot of interest
>> in getting this in, indeed :)
> 
> Yeah, I feel bad about not having more time for all of the various
> things I'd like to see happen, happen.

You should ! ;-)

> But that's why I bought the Ci20
> and Ci40 (and some other boards) as a regular person rather than try and
> get a freebie.

I feel triggered by this, I also bought the CI20 (and not CI40, because
it wasn't available ... but I will buy one eventually when I feel like
delving into more masochistic stuff ...)

-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-15 20:46           ` Marek Vasut
@ 2017-02-15 21:50             ` Tom Rini
  2017-02-15 22:08               ` Marek Vasut
  0 siblings, 1 reply; 41+ messages in thread
From: Tom Rini @ 2017-02-15 21:50 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 15, 2017 at 09:46:38PM +0100, Marek Vasut wrote:
> On 02/15/2017 12:11 AM, Tom Rini wrote:
> > On Wed, Feb 15, 2017 at 12:03:32AM +0100, Marek Vasut wrote:
> >> On 02/14/2017 11:58 PM, Tom Rini wrote:
> >>> On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
> >>>> Hi Marek,
> >>>>
> >>>> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
> >>>>> From: Paul Burton <paul.burton@imgtec.com>
> >>>>>
> >>>>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
> >>>>> The DTS file comes from Linux 4.6 as of revision
> >>>>> 78800558d104e003f9ae92e0107f1de39cf9de9f
> >>>>>
> >>>>> So far, there are still a few details which will have to be fixed
> >>>>> once they are fleshed out in Linux:
> >>>>> - pinmux: Thus far, this board just pokes the pinmux registers to
> >>>>>           set the pinmux. For MMC in SPL, this will have to stay.
> >>>>> 	  But for full u-boot a proper pinmux driver will have to
> >>>>> 	  be added once the pinmux semantics in DT are in mainline
> >>>>> 	  Linux.
> >>>>> - ethernet,efuse: DT bindings are missing from mainline Linux.
> >>>>>
> >>>>> Signed-off-by: Marek Vasut <marex@denx.de>
> >>>>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> >>>>> Cc: Paul Burton <paul.burton@imgtec.com>
> >>>>> ---
> >>>>>  arch/mips/dts/Makefile        |   1 +
> >>>>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
> >>>>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
> >>>>>  board/imgtec/ci20/Kconfig     |  35 +++++
> >>>>>  board/imgtec/ci20/Makefile    |   5 +
> >>>>>  board/imgtec/ci20/README      |  10 ++
> >>>>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
> >>>>>  configs/ci20_defconfig        |  28 ++++
> >>>>>  include/configs/ci20.h        | 105 +++++++++++++
> >>>>>  9 files changed, 663 insertions(+)
> >>>>>  create mode 100644 arch/mips/dts/ci20.dts
> >>>>>  create mode 100644 board/imgtec/ci20/Kconfig
> >>>>>  create mode 100644 board/imgtec/ci20/Makefile
> >>>>>  create mode 100644 board/imgtec/ci20/README
> >>>>>  create mode 100644 board/imgtec/ci20/ci20.c
> >>>>>  create mode 100644 configs/ci20_defconfig
> >>>>>  create mode 100644 include/configs/ci20.h
> >>>>
> >>>> I've looked into testing the remainder of this patchset, not seeing a
> >>>> newer version. You can find my branch here:
> >>>>
> >>>> https://github.com/afaerber/u-boot/commits/ci20
> >>> [snip]
> >>>>   LD      spl/u-boot-spl
> >>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> >>>> region `.sram'
> >>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
> >>>
> >>> I can recreate that too here real quick, but can't test out changes on
> >>> my Ci20 right now.  Can you try:
> >>>
> >>> diff --git a/include/configs/ci20.h b/include/configs/ci20.h
> >>> index 4503adb..9e2ad7b 100644
> >>> --- a/include/configs/ci20.h
> >>> +++ b/include/configs/ci20.h
> >>> @@ -70,10 +70,10 @@
> >>>  /* SPL */
> >>>  #define CONFIG_SPL_FRAMEWORK
> >>>  
> >>> -#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
> >>> +#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
> >>>  
> >>>  #define CONFIG_SPL_TEXT_BASE		0xf4000a00
> >>> -#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
> >>> +#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)
> >>
> >> This will not work, the stack is configured at it's limit already.
> >>
> >>>  #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
> >>>  #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
> >>>
> >>>
> >>> Now, off the top of my head I'm only giving myself a 50/50 chance of
> >>> having moved the stack address in the correct direction.  And note that
> >>> I don't know why we say only max of 2KB for stack, and then ensure we
> >>> have 2.5KB of room, but I've shifted 512 bytes from one side to the
> >>> other.  And it's quite probable that we should make use having SPL stack
> >>> get moved into DDR
> >>
> >> You mean the DDR which you init in the SPL ? :)
> > 
> > Yes, I mean the DDR which we init in the SPL, after we've init'd it, so
> > that we can work more comfortably in cramped and constrained spaces.
> 
> You know, you are still limited by the 14 kiB load limit of the BootROM.
> I think there's more than 16 kiB of SRAM total, so there's no real
> problem with the stack. The problem is that 14 kiB load limit of the
> BootROM, it will NOT LOAD MORE than 14 kiB of code . I tried (because,
> well, 14 kiB is too small). IT DOES NOT WORK.

Can we use those last 2KiB of SRAM for our stack or does that freak out
the BootROM?  If so, we should tweak the above definitions to set the
hard limit at 14 * SZ_1K and put stack at 0xf4004200 ?  Where is
0xf4008000 in the memory map?

> >>> , but I don't have the memory map handy either (and
> >>> based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
> >>> should be in DDR space, I don't know if internal memory directly follows
> >>> into DDR here or what).
> >>>
> >>> I do want to reiterate that I am eager to have Ci20 be working in
> >>> mainline as I have one and I want to figure out how to include it in my
> >>> farm, or at least manual testing from time to time.  Thanks!
> >>
> >> Well, these patches were rotting on the list for year or so without
> >> getting any attention, until the point I had to scream on the IRC to get
> >> ANY review comments, multiple times, so I really see a lot of interest
> >> in getting this in, indeed :)
> > 
> > Yeah, I feel bad about not having more time for all of the various
> > things I'd like to see happen, happen.
> 
> You should ! ;-)
> 
> > But that's why I bought the Ci20
> > and Ci40 (and some other boards) as a regular person rather than try and
> > get a freebie.
> 
> I feel triggered by this, I also bought the CI20 (and not CI40, because
> it wasn't available ... but I will buy one eventually when I feel like
> delving into more masochistic stuff ...)

Sorry, I was trying to point out that I have this board (and some
others) that I've purchased and would like to have mainline U-Boot on,
but cannot as I have not the time to try and pick them up as project
boards.  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170215/d334395c/attachment.sig>

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-15 21:50             ` Tom Rini
@ 2017-02-15 22:08               ` Marek Vasut
  0 siblings, 0 replies; 41+ messages in thread
From: Marek Vasut @ 2017-02-15 22:08 UTC (permalink / raw)
  To: u-boot

On 02/15/2017 10:50 PM, Tom Rini wrote:
> On Wed, Feb 15, 2017 at 09:46:38PM +0100, Marek Vasut wrote:
>> On 02/15/2017 12:11 AM, Tom Rini wrote:
>>> On Wed, Feb 15, 2017 at 12:03:32AM +0100, Marek Vasut wrote:
>>>> On 02/14/2017 11:58 PM, Tom Rini wrote:
>>>>> On Sun, Feb 12, 2017 at 12:52:45PM +0100, Andreas F?rber wrote:
>>>>>> Hi Marek,
>>>>>>
>>>>>> Am 01.12.2016 um 02:06 schrieb Marek Vasut:
>>>>>>> From: Paul Burton <paul.burton@imgtec.com>
>>>>>>>
>>>>>>> Add support for the Creator CI20 platform based on the JZ4780 SoC.
>>>>>>> The DTS file comes from Linux 4.6 as of revision
>>>>>>> 78800558d104e003f9ae92e0107f1de39cf9de9f
>>>>>>>
>>>>>>> So far, there are still a few details which will have to be fixed
>>>>>>> once they are fleshed out in Linux:
>>>>>>> - pinmux: Thus far, this board just pokes the pinmux registers to
>>>>>>>           set the pinmux. For MMC in SPL, this will have to stay.
>>>>>>> 	  But for full u-boot a proper pinmux driver will have to
>>>>>>> 	  be added once the pinmux semantics in DT are in mainline
>>>>>>> 	  Linux.
>>>>>>> - ethernet,efuse: DT bindings are missing from mainline Linux.
>>>>>>>
>>>>>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>>>>>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>>>>>>> Cc: Paul Burton <paul.burton@imgtec.com>
>>>>>>> ---
>>>>>>>  arch/mips/dts/Makefile        |   1 +
>>>>>>>  arch/mips/dts/ci20.dts        | 114 ++++++++++++++
>>>>>>>  arch/mips/mach-jz47xx/Kconfig |  11 ++
>>>>>>>  board/imgtec/ci20/Kconfig     |  35 +++++
>>>>>>>  board/imgtec/ci20/Makefile    |   5 +
>>>>>>>  board/imgtec/ci20/README      |  10 ++
>>>>>>>  board/imgtec/ci20/ci20.c      | 354 ++++++++++++++++++++++++++++++++++++++++++
>>>>>>>  configs/ci20_defconfig        |  28 ++++
>>>>>>>  include/configs/ci20.h        | 105 +++++++++++++
>>>>>>>  9 files changed, 663 insertions(+)
>>>>>>>  create mode 100644 arch/mips/dts/ci20.dts
>>>>>>>  create mode 100644 board/imgtec/ci20/Kconfig
>>>>>>>  create mode 100644 board/imgtec/ci20/Makefile
>>>>>>>  create mode 100644 board/imgtec/ci20/README
>>>>>>>  create mode 100644 board/imgtec/ci20/ci20.c
>>>>>>>  create mode 100644 configs/ci20_defconfig
>>>>>>>  create mode 100644 include/configs/ci20.h
>>>>>>
>>>>>> I've looked into testing the remainder of this patchset, not seeing a
>>>>>> newer version. You can find my branch here:
>>>>>>
>>>>>> https://github.com/afaerber/u-boot/commits/ci20
>>>>> [snip]
>>>>>>   LD      spl/u-boot-spl
>>>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>>>>> region `.sram'
>>>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>>>>
>>>>> I can recreate that too here real quick, but can't test out changes on
>>>>> my Ci20 right now.  Can you try:
>>>>>
>>>>> diff --git a/include/configs/ci20.h b/include/configs/ci20.h
>>>>> index 4503adb..9e2ad7b 100644
>>>>> --- a/include/configs/ci20.h
>>>>> +++ b/include/configs/ci20.h
>>>>> @@ -70,10 +70,10 @@
>>>>>  /* SPL */
>>>>>  #define CONFIG_SPL_FRAMEWORK
>>>>>  
>>>>> -#define CONFIG_SPL_STACK		0xf4008000 /* only max. 2KB spare! */
>>>>> +#define CONFIG_SPL_STACK		0xf4008200 /* only max. 1.5KB spare! */
>>>>>  
>>>>>  #define CONFIG_SPL_TEXT_BASE		0xf4000a00
>>>>> -#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0xa00)
>>>>> +#define CONFIG_SPL_MAX_SIZE		((14 * 1024) - 0x800)
>>>>
>>>> This will not work, the stack is configured at it's limit already.
>>>>
>>>>>  #define CONFIG_SPL_BSS_START_ADDR	0xf4004000
>>>>>  #define CONFIG_SPL_BSS_MAX_SIZE		0x00002000 /* 512KB, arbitrary */
>>>>>
>>>>>
>>>>> Now, off the top of my head I'm only giving myself a 50/50 chance of
>>>>> having moved the stack address in the correct direction.  And note that
>>>>> I don't know why we say only max of 2KB for stack, and then ensure we
>>>>> have 2.5KB of room, but I've shifted 512 bytes from one side to the
>>>>> other.  And it's quite probable that we should make use having SPL stack
>>>>> get moved into DDR
>>>>
>>>> You mean the DDR which you init in the SPL ? :)
>>>
>>> Yes, I mean the DDR which we init in the SPL, after we've init'd it, so
>>> that we can work more comfortably in cramped and constrained spaces.
>>
>> You know, you are still limited by the 14 kiB load limit of the BootROM.
>> I think there's more than 16 kiB of SRAM total, so there's no real
>> problem with the stack. The problem is that 14 kiB load limit of the
>> BootROM, it will NOT LOAD MORE than 14 kiB of code . I tried (because,
>> well, 14 kiB is too small). IT DOES NOT WORK.
> 
> Can we use those last 2KiB of SRAM for our stack or does that freak out
> the BootROM?

IIRC I tried pretty much everything to squeeze more space out of this
chip and this is the only thing that worked.

> If so, we should tweak the above definitions to set the
> hard limit at 14 * SZ_1K and put stack at 0xf4004200 ?

Be my guest, research the hell out of this ... if you can figure
something out, great.

> Where is 0xf4008000 in the memory map?

RTFM , seriously ...

>>>>> , but I don't have the memory map handy either (and
>>>>> based on the above snippets I'm confused as CONFIG_SPL_BSS_START_ADDR
>>>>> should be in DDR space, I don't know if internal memory directly follows
>>>>> into DDR here or what).
>>>>>
>>>>> I do want to reiterate that I am eager to have Ci20 be working in
>>>>> mainline as I have one and I want to figure out how to include it in my
>>>>> farm, or at least manual testing from time to time.  Thanks!
>>>>
>>>> Well, these patches were rotting on the list for year or so without
>>>> getting any attention, until the point I had to scream on the IRC to get
>>>> ANY review comments, multiple times, so I really see a lot of interest
>>>> in getting this in, indeed :)
>>>
>>> Yeah, I feel bad about not having more time for all of the various
>>> things I'd like to see happen, happen.
>>
>> You should ! ;-)
>>
>>> But that's why I bought the Ci20
>>> and Ci40 (and some other boards) as a regular person rather than try and
>>> get a freebie.
>>
>> I feel triggered by this, I also bought the CI20 (and not CI40, because
>> it wasn't available ... but I will buy one eventually when I feel like
>> delving into more masochistic stuff ...)
> 
> Sorry, I was trying to point out that I have this board (and some
> others) that I've purchased and would like to have mainline U-Boot on,
> but cannot as I have not the time to try and pick them up as project
> boards.  Thanks!

Well, I also don't have the time to keep rebasing this patchset over and
over and over and solving why the hell does it no longer fit AGAIN. So
too bad ...

-- 
Best regards,
Marek Vasut

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-02-12 14:03             ` Marek Vasut
@ 2017-06-11 21:45               ` Andreas Färber
  2017-06-12 19:16                 ` Tom Rini
  0 siblings, 1 reply; 41+ messages in thread
From: Andreas Färber @ 2017-06-11 21:45 UTC (permalink / raw)
  To: u-boot

Am 12.02.2017 um 15:03 schrieb Marek Vasut:
> On 02/12/2017 02:24 PM, Andreas Färber wrote:
>> Am 12.02.2017 um 13:53 schrieb Marek Vasut:
>>> On 02/12/2017 01:24 PM, Andreas Färber wrote:
>>>> Am 12.02.2017 um 12:55 schrieb Marek Vasut:
>>>>> On 02/12/2017 12:52 PM, Andreas Färber wrote:
>>>>>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
>>>>>>
>>>>>>   LD      spl/u-boot-spl
>>>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>>>>>> region `.sram'
>>>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
>>>>>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>>>>>> make[2]: *** [spl/u-boot-spl] Error 1
>>>>>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>>>>>> 'spl/u-boot-spl' failed
>>>>>> make[1]: *** [spl/u-boot-spl] Error 2
>>>>>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>>>>>> Makefile:150: recipe for target 'sub-make' failed
>>>>>> make: *** [sub-make] Error 2
>>>>>>
>>>>>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
>>>>>> options defaulting to y, but I did not find a way to get this number
>>>>>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
>>>>>> even worse (~748).
>>>> I'm looking into a gcc7 package next, but that'll take a bit.
>>>
>>> I don't think that's gonna help with U-Boot's bloat. [...]
>>
>> Yeah, slightly down with GCC 7.0.1, but not much:
> 
> Right, it's the new bloat ...
> 
>>   LD      spl/u-boot-spl
>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
>> region `.sram'
>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 264 bytes
>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
>> make[2]: *** [spl/u-boot-spl] Error 1
>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
>> 'spl/u-boot-spl' failed
>> make[1]: *** [spl/u-boot-spl] Error 2
>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
>> Makefile:150: recipe for target 'sub-make' failed
>> make: *** [sub-make] Error 2

Update: I've rebased the patchset to latest master
(8cb3ce64f936f5dedbcfc1935c5caf31bb682474 / "Merge
git://git.denx.de/u-boot-dm") - BMIPS caused trivial conflicts, and DM
API changes needed to be accounted for.

https://github.com/afaerber/u-boot/commits/ci20

By further disabling CONFIG_SPL_RAW_IMAGE_SUPPORT in the ci20 defconfig
I am now at 344 bytes overflow (gcc 7.1.1):

  LD      spl/u-boot-spl
mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
region `.sram'
mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 344 bytes
../scripts/Makefile.spl:333: recipe for target 'spl/u-boot-spl' failed
make[2]: *** [spl/u-boot-spl] Error 1
/home/andreas/OBS/u-boot/Makefile:1382: recipe for target
'spl/u-boot-spl' failed
make[1]: *** [spl/u-boot-spl] Error 2

By disabling SPL GPIO support and hardcoding a board revision instead of
detecting it via GPIOs, I can get it down to 80 bytes.

By aggressively adding #ifndef CONFIG_SPL_BUILD in ci20.c I'm down to 64
bytes, but not sure if some of that is actually needed for SPL...

Tom, do you see a chance of merging any of the drivers without the whole
board building, so that we can reduce the rebasing work and get a common
base for optimizing?

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)

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

* [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform
  2017-06-11 21:45               ` Andreas Färber
@ 2017-06-12 19:16                 ` Tom Rini
  0 siblings, 0 replies; 41+ messages in thread
From: Tom Rini @ 2017-06-12 19:16 UTC (permalink / raw)
  To: u-boot

On Sun, Jun 11, 2017 at 11:45:48PM +0200, Andreas F채rber wrote:
> Am 12.02.2017 um 15:03 schrieb Marek Vasut:
> > On 02/12/2017 02:24 PM, Andreas F채rber wrote:
> >> Am 12.02.2017 um 13:53 schrieb Marek Vasut:
> >>> On 02/12/2017 01:24 PM, Andreas F채rber wrote:
> >>>> Am 12.02.2017 um 12:55 schrieb Marek Vasut:
> >>>>> On 02/12/2017 12:52 PM, Andreas F채rber wrote:
> >>>>>> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y leads to this error:
> >>>>>>
> >>>>>>   LD      spl/u-boot-spl
> >>>>>> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> >>>>>> region `.sram'
> >>>>>> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 288 bytes
> >>>>>> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
> >>>>>> make[2]: *** [spl/u-boot-spl] Error 1
> >>>>>> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
> >>>>>> 'spl/u-boot-spl' failed
> >>>>>> make[1]: *** [spl/u-boot-spl] Error 2
> >>>>>> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
> >>>>>> Makefile:150: recipe for target 'sub-make' failed
> >>>>>> make: *** [sub-make] Error 2
> >>>>>>
> >>>>>> I've reviewed all SPL Kconfig options and found three seemingly unneeded
> >>>>>> options defaulting to y, but I did not find a way to get this number
> >>>>>> down even a single byte with my GCC 6.3.1, and the recommended 4.8.1 was
> >>>>>> even worse (~748).
> >>>> I'm looking into a gcc7 package next, but that'll take a bit.
> >>>
> >>> I don't think that's gonna help with U-Boot's bloat. [...]
> >>
> >> Yeah, slightly down with GCC 7.0.1, but not much:
> > 
> > Right, it's the new bloat ...
> > 
> >>   LD      spl/u-boot-spl
> >> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> >> region `.sram'
> >> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 264 bytes
> >> ../scripts/Makefile.spl:304: recipe for target 'spl/u-boot-spl' failed
> >> make[2]: *** [spl/u-boot-spl] Error 1
> >> /home/andreas/OBS/u-boot/Makefile:1342: recipe for target
> >> 'spl/u-boot-spl' failed
> >> make[1]: *** [spl/u-boot-spl] Error 2
> >> make[1]: Leaving directory '/home/andreas/OBS/u-boot/ci20'
> >> Makefile:150: recipe for target 'sub-make' failed
> >> make: *** [sub-make] Error 2
> 
> Update: I've rebased the patchset to latest master
> (8cb3ce64f936f5dedbcfc1935c5caf31bb682474 / "Merge
> git://git.denx.de/u-boot-dm") - BMIPS caused trivial conflicts, and DM
> API changes needed to be accounted for.
> 
> https://github.com/afaerber/u-boot/commits/ci20
> 
> By further disabling CONFIG_SPL_RAW_IMAGE_SUPPORT in the ci20 defconfig
> I am now at 344 bytes overflow (gcc 7.1.1):
> 
>   LD      spl/u-boot-spl
> mipsel-suse-linux-ld.bfd: u-boot-spl section `.data' will not fit in
> region `.sram'
> mipsel-suse-linux-ld.bfd: region `.sram' overflowed by 344 bytes
> ../scripts/Makefile.spl:333: recipe for target 'spl/u-boot-spl' failed
> make[2]: *** [spl/u-boot-spl] Error 1
> /home/andreas/OBS/u-boot/Makefile:1382: recipe for target
> 'spl/u-boot-spl' failed
> make[1]: *** [spl/u-boot-spl] Error 2
> 
> By disabling SPL GPIO support and hardcoding a board revision instead of
> detecting it via GPIOs, I can get it down to 80 bytes.
> 
> By aggressively adding #ifndef CONFIG_SPL_BUILD in ci20.c I'm down to 64
> bytes, but not sure if some of that is actually needed for SPL...
> 
> Tom, do you see a chance of merging any of the drivers without the whole
> board building, so that we can reduce the rebasing work and get a common
> base for optimizing?

Yes, I would be agreeable to that, especially if say they can be enabled
also on qemu-mips so we have build but not run time testing and thus
aren't adding dead code.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170612/1aa80c0e/attachment.sig>

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

end of thread, other threads:[~2017-06-12 19:16 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-01  1:06 [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 02/13] serial: 16550: Add port type as driver data Marek Vasut
2016-12-19 21:19   ` [U-Boot] [U-Boot, " Tom Rini
2016-12-01  1:06 ` [U-Boot] [PATCH 03/13] serial: 16550: Add Ingenic JZ4780 support Marek Vasut
2016-12-03  4:26   ` Simon Glass
2016-12-19 21:20   ` [U-Boot] [U-Boot, " Tom Rini
2016-12-01  1:06 ` [U-Boot] [PATCH 04/13] mmc: Fix warning if debug() is not used Marek Vasut
2016-12-01  4:17   ` Jaehoon Chung
2016-12-01  5:14   ` Jaehoon Chung
2016-12-01  1:06 ` [U-Boot] [PATCH 05/13] mmc: Tinification of the mmc code Marek Vasut
2016-12-01  5:07   ` Jaehoon Chung
2016-12-01  1:06 ` [U-Boot] [PATCH 06/13] mmc: Add JZ47xx SD/MMC controller driver Marek Vasut
2016-12-01  5:48   ` Jaehoon Chung
2017-02-12 14:20   ` Andreas Färber
2017-02-12 14:29     ` Marek Vasut
2017-02-12 14:56       ` Andreas Färber
2016-12-01  1:06 ` [U-Boot] [PATCH 07/13] SPL: mmc: Make spl_mmc_load_image available Marek Vasut
2016-12-01  5:07   ` Jaehoon Chung
2016-12-01  1:06 ` [U-Boot] [PATCH 08/13] gpio: Add JZ47xx GPIO driver Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 09/13] misc: Add JZ47xx efuse driver Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 10/13] mips: Add SPL header Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 11/13] mips: jz47xx: Add JZ4780 SoC support Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 12/13] mips: jz47xx: Add minimal JZ MMC node Marek Vasut
2016-12-01  1:06 ` [U-Boot] [PATCH 13/13] mips: jz47xx: Add Creator CI20 platform Marek Vasut
2017-02-12 11:52   ` Andreas Färber
2017-02-12 11:55     ` Marek Vasut
2017-02-12 12:24       ` Andreas Färber
2017-02-12 12:53         ` Marek Vasut
2017-02-12 13:24           ` Andreas Färber
2017-02-12 14:03             ` Marek Vasut
2017-06-11 21:45               ` Andreas Färber
2017-06-12 19:16                 ` Tom Rini
2017-02-12 14:14     ` Andreas Färber
2017-02-14 22:58     ` Tom Rini
2017-02-14 23:03       ` Marek Vasut
2017-02-14 23:11         ` Tom Rini
2017-02-15 20:46           ` Marek Vasut
2017-02-15 21:50             ` Tom Rini
2017-02-15 22:08               ` Marek Vasut
2016-12-03  4:26 ` [U-Boot] [PATCH 01/13] serial: 16550: Add getfcr accessor Simon Glass
2016-12-19 21:18 ` [U-Boot] [U-Boot,01/13] " Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.