ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch b/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch
new file mode 100644
index 0000000..7ecf544
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0001-sf-fix-out-of-order-calls-for-spi_claim_bus-and-spi_.patch
@@ -0,0 +1,170 @@
+From 909840ef844013379e5ec399c1e76c65d1a6eb1d Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sat, 12 Oct 2013 21:09:47 +0200
+Subject: sf: fix out-of-order calls for spi_claim_bus and spi_release_bus
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_ops.c
++++ b/drivers/mtd/spi/sf_ops.c
+@@ -132,12 +132,6 @@ int spi_flash_write_common(struct spi_fl
+ 	if (buf == NULL)
+ 		timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT;
+ 
+-	ret = spi_claim_bus(flash->spi);
+-	if (ret) {
+-		debug("SF: unable to claim SPI bus\n");
+-		return ret;
+-	}
+-
+ 	ret = spi_flash_cmd_write_enable(flash);
+ 	if (ret < 0) {
+ 		debug("SF: enabling write failed\n");
+@@ -158,8 +152,6 @@ int spi_flash_write_common(struct spi_fl
+ 		return ret;
+ 	}
+ 
+-	spi_release_bus(spi);
+-
+ 	return ret;
+ }
+ 
+@@ -175,12 +167,18 @@ int spi_flash_cmd_erase_ops(struct spi_f
+ 		return -1;
+ 	}
+ 
++	ret = spi_claim_bus(flash->spi);
++	if (ret) {
++		debug("SF: unable to claim SPI bus\n");
++		return ret;
++	}
++
+ 	cmd[0] = flash->erase_cmd;
+ 	while (len) {
+ #ifdef CONFIG_SPI_FLASH_BAR
+ 		ret = spi_flash_bank(flash, offset);
+ 		if (ret < 0)
+-			return ret;
++			goto done;
+ #endif
+ 		spi_flash_addr(offset, cmd);
+ 
+@@ -190,13 +188,16 @@ int spi_flash_cmd_erase_ops(struct spi_f
+ 		ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
+ 		if (ret < 0) {
+ 			debug("SF: erase failed\n");
+-			break;
++			goto done;
+ 		}
+ 
+ 		offset += erase_size;
+ 		len -= erase_size;
+ 	}
+ 
++done:
++	spi_release_bus(flash->spi);
++
+ 	return ret;
+ }
+ 
+@@ -208,6 +209,12 @@ int spi_flash_cmd_write_ops(struct spi_f
+ 	u8 cmd[4];
+ 	int ret = -1;
+ 
++	ret = spi_claim_bus(flash->spi);
++	if (ret) {
++		debug("SF: unable to claim SPI bus\n");
++		return ret;
++	}
++
+ 	page_size = flash->page_size;
+ 
+ 	cmd[0] = CMD_PAGE_PROGRAM;
+@@ -215,7 +222,7 @@ int spi_flash_cmd_write_ops(struct spi_f
+ #ifdef CONFIG_SPI_FLASH_BAR
+ 		ret = spi_flash_bank(flash, offset);
+ 		if (ret < 0)
+-			return ret;
++			goto done;
+ #endif
+ 		byte_addr = offset % page_size;
+ 		chunk_len = min(len - actual, page_size - byte_addr);
+@@ -232,12 +239,15 @@ int spi_flash_cmd_write_ops(struct spi_f
+ 					buf + actual, chunk_len);
+ 		if (ret < 0) {
+ 			debug("SF: write failed\n");
+-			break;
++			goto done;
+ 		}
+ 
+ 		offset += chunk_len;
+ 	}
+ 
++done:
++	spi_release_bus(flash->spi);
++
+ 	return ret;
+ }
+ 
+@@ -247,20 +257,12 @@ int spi_flash_read_common(struct spi_fla
+ 	struct spi_slave *spi = flash->spi;
+ 	int ret;
+ 
+-	ret = spi_claim_bus(flash->spi);
+-	if (ret) {
+-		debug("SF: unable to claim SPI bus\n");
+-		return ret;
+-	}
+-
+ 	ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len);
+ 	if (ret < 0) {
+ 		debug("SF: read cmd failed\n");
+ 		return ret;
+ 	}
+ 
+-	spi_release_bus(spi);
+-
+ 	return ret;
+ }
+ 
+@@ -271,6 +273,12 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 	u32 remain_len, read_len;
+ 	int ret = -1;
+ 
++	ret = spi_claim_bus(flash->spi);
++	if (ret) {
++		debug("SF: unable to claim SPI bus\n");
++		return ret;
++	}
++
+ 	/* Handle memory-mapped SPI */
+ 	if (flash->memory_map) {
+ 		spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP);
+@@ -289,7 +297,7 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 		ret = spi_flash_cmd_bankaddr_write(flash, bank_sel);
+ 		if (ret) {
+ 			debug("SF: fail to set bank%d\n", bank_sel);
+-			return ret;
++			goto done;
+ 		}
+ #endif
+ 		remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset;
+@@ -304,7 +312,7 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 							data, read_len);
+ 		if (ret < 0) {
+ 			debug("SF: read failed\n");
+-			break;
++			goto done;
+ 		}
+ 
+ 		offset += read_len;
+@@ -312,6 +320,9 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 		data += read_len;
+ 	}
+ 
++done:
++	spi_release_bus(flash->spi);
++
+ 	return ret;
+ }
+ 
diff --git a/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch b/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch
new file mode 100644
index 0000000..af2612f
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0002-sf-consistently-use-debug-for-warning-error-messages.patch
@@ -0,0 +1,49 @@
+From bb7df8c6ff30be3786483767d3afb0e77a69a640 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sat, 12 Oct 2013 21:21:18 +0200
+Subject: sf: consistently use debug() for warning/error messages
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -176,8 +176,8 @@ static struct spi_flash *spi_flash_valid
+ 	}
+ 
+ 	if (i == ARRAY_SIZE(spi_flash_params_table)) {
+-		printf("SF: Unsupported flash IDs: ");
+-		printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
++		debug("SF: Unsupported flash IDs: ");
++		debug("manuf %02x, jedec %04x, ext_jedec %04x\n",
+ 		       idcode[0], jedec, ext_jedec);
+ 		return NULL;
+ 	}
+@@ -296,7 +296,7 @@ struct spi_flash *spi_flash_probe(unsign
+ 	/* Setup spi_slave */
+ 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ 	if (!spi) {
+-		printf("SF: Failed to set up slave\n");
++		debug("SF: Failed to set up slave\n");
+ 		return NULL;
+ 	}
+ 
+@@ -310,7 +310,7 @@ struct spi_flash *spi_flash_probe(unsign
+ 	/* Read the ID codes */
+ 	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
+ 	if (ret) {
+-		printf("SF: Failed to get idcodes\n");
++		debug("SF: Failed to get idcodes\n");
+ 		goto err_read_id;
+ 	}
+ 
+@@ -341,8 +341,8 @@ struct spi_flash *spi_flash_probe(unsign
+ #endif
+ #ifndef CONFIG_SPI_FLASH_BAR
+ 	if (flash->size > SPI_FLASH_16MB_BOUN) {
+-		puts("SF: Warning - Only lower 16MiB accessible,");
+-		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
++		debug("SF: Warning - Only lower 16MiB accessible,");
++		debug(" Full access #define CONFIG_SPI_FLASH_BAR\n");
+ 	}
+ #endif
+ 
diff --git a/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch b/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch
new file mode 100644
index 0000000..d47d3df
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0003-sf-move-malloc-of-spi_flash-to-spi_flash_probe.patch
@@ -0,0 +1,110 @@
+From 36b7400465fe2339f1c78274b3fd258ade3a4c00 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sat, 12 Oct 2013 21:30:07 +0200
+Subject: sf: move malloc of spi_flash to spi_flash_probe()
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -153,11 +153,10 @@ static const struct spi_flash_params spi
+ 	 */
+ };
+ 
+-static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
++static int spi_flash_validate_params(struct spi_flash *flash,
+ 		u8 *idcode)
+ {
+ 	const struct spi_flash_params *params;
+-	struct spi_flash *flash;
+ 	int i;
+ 	u16 jedec = idcode[1] << 8 | idcode[2];
+ 	u16 ext_jedec = idcode[3] << 8 | idcode[4];
+@@ -179,20 +178,12 @@ static struct spi_flash *spi_flash_valid
+ 		debug("SF: Unsupported flash IDs: ");
+ 		debug("manuf %02x, jedec %04x, ext_jedec %04x\n",
+ 		       idcode[0], jedec, ext_jedec);
+-		return NULL;
+-	}
+-
+-	flash = malloc(sizeof(*flash));
+-	if (!flash) {
+-		debug("SF: Failed to allocate spi_flash\n");
+-		return NULL;
++		return -1;
+ 	}
+-	memset(flash, '\0', sizeof(*flash));
+ 
+ 	/* Assign spi data */
+-	flash->spi = spi;
+ 	flash->name = params->name;
+-	flash->memory_map = spi->memory_map;
++	flash->memory_map = flash->spi->memory_map;
+ 
+ 	/* Assign spi_flash ops */
+ 	flash->write = spi_flash_cmd_write_ops;
+@@ -239,7 +230,7 @@ static struct spi_flash *spi_flash_valid
+ 		if (spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
+ 					  &curr_bank, 1)) {
+ 			debug("SF: fail to read bank addr register\n");
+-			return NULL;
++			return -1;
+ 		}
+ 		flash->bank_curr = curr_bank;
+ 	} else {
+@@ -254,7 +245,7 @@ static struct spi_flash *spi_flash_valid
+ 		spi_flash_cmd_write_status(flash, 0);
+ #endif
+ 
+-	return flash;
++	return 0;
+ }
+ 
+ #ifdef CONFIG_OF_CONTROL
+@@ -289,15 +280,22 @@ struct spi_flash *spi_flash_probe(unsign
+ 		unsigned int max_hz, unsigned int spi_mode)
+ {
+ 	struct spi_slave *spi;
+-	struct spi_flash *flash = NULL;
++	struct spi_flash *flash;
+ 	u8 idcode[5];
+ 	int ret;
+ 
++	flash = malloc(sizeof(*flash));
++	if (!flash) {
++		debug("SF: Failed to allocate spi_flash\n");
++		return NULL;
++	}
++	memset(flash, 0, sizeof(*flash));
++
+ 	/* Setup spi_slave */
+ 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ 	if (!spi) {
+ 		debug("SF: Failed to set up slave\n");
+-		return NULL;
++		goto err_setup;
+ 	}
+ 
+ 	/* Claim spi bus */
+@@ -320,8 +318,9 @@ struct spi_flash *spi_flash_probe(unsign
+ #endif
+ 
+ 	/* Validate params from spi_flash_params table */
+-	flash = spi_flash_validate_params(spi, idcode);
+-	if (!flash)
++	flash->spi = spi;
++	ret = spi_flash_validate_params(flash, idcode);
++	if (ret)
+ 		goto err_read_id;
+ 
+ #ifdef CONFIG_OF_CONTROL
+@@ -355,6 +354,9 @@ err_read_id:
+ 	spi_release_bus(spi);
+ err_claim_bus:
+ 	spi_free_slave(spi);
++err_setup:
++	free(flash);
++
+ 	return NULL;
+ }
+ 
diff --git a/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch b/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch
new file mode 100644
index 0000000..960085c
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0004-sf-add-slim-probe-funtions-for-SPL.patch
@@ -0,0 +1,80 @@
+From da11da943487e2f724f25d409bcaa1f099637c0b Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 13 Oct 2013 14:56:45 +0200
+Subject: sf: add slim probe funtions for SPL
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -365,3 +365,58 @@ void spi_flash_free(struct spi_flash *fl
+ 	spi_free_slave(flash->spi);
+ 	free(flash);
+ }
++
++#ifdef CONFIG_SPI_SPL_SIMPLE
++int spl_spi_flash_probe(struct spi_flash *flash)
++{
++	struct spi_slave *spi;
++	u8 idcode[5];
++	int ret;
++
++	/* Setup spi_slave */
++	spi = spi_setup_slave(CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS,
++		CONFIG_SPL_SPI_MAX_HZ, CONFIG_SPL_SPI_MODE);
++	if (!spi) {
++		debug("SF: Failed to set up slave\n");
++		return -1;
++	}
++
++	/* Claim spi bus */
++	ret = spi_claim_bus(spi);
++	if (ret) {
++		debug("SF: Failed to claim SPI bus: %d\n", ret);
++		goto err_claim_bus;
++	}
++
++	/* Read the ID codes */
++	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
++	if (ret) {
++		debug("SF: Failed to get idcodes\n");
++		goto err_read_id;
++	}
++
++	/* Validate params from spi_flash_params table */
++	flash->spi = spi;
++	ret = spi_flash_validate_params(flash, idcode);
++	if (ret)
++		goto err_read_id;
++
++	/* Release spi bus */
++	spi_release_bus(spi);
++
++	return 0;
++
++err_read_id:
++	spi_release_bus(spi);
++err_claim_bus:
++	spi_free_slave(spi);
++	flash->spi = NULL;
++
++	return ret;
++}
++
++void spl_spi_flash_free(struct spi_flash *flash)
++{
++	spi_free_slave(flash->spi);
++}
++#endif
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -69,6 +69,9 @@ struct spi_flash *spi_flash_probe(unsign
+ 		unsigned int max_hz, unsigned int spi_mode);
+ void spi_flash_free(struct spi_flash *flash);
+ 
++int spl_spi_flash_probe(struct spi_flash *flash);
++void spl_spi_flash_free(struct spi_flash *flash);
++
+ static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
+ 		size_t len, void *buf)
+ {
diff --git a/package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch b/package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch
new file mode 100644
index 0000000..8000ff0
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0005-sf-make-calculatiom-of-address-bytes-completely-conf.patch
@@ -0,0 +1,134 @@
+From 6fb5f86b094756d94de8abe7425e3d290ff22dd2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 13 Oct 2013 15:09:28 +0200
+Subject: sf: make calculatiom of address bytes completely configurable
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_ops.c
++++ b/drivers/mtd/spi/sf_ops.c
+@@ -15,12 +15,17 @@
+ 
+ #include "sf_internal.h"
+ 
+-static void spi_flash_addr(u32 addr, u8 *cmd)
++static void spi_flash_addr(const struct spi_flash *flash, u32 addr, u8 *cmd)
+ {
+ 	/* cmd[0] is actual command */
+-	cmd[1] = addr >> 16;
+-	cmd[2] = addr >> 8;
+-	cmd[3] = addr >> 0;
++	cmd[1] = addr >> (flash->addr_width * 8 - 8);
++	cmd[2] = addr >> (flash->addr_width * 8 - 16);
++	cmd[3] = addr >> (flash->addr_width * 8 - 24);
++}
++
++static int spi_flash_cmdsz(const struct spi_flash *flash)
++{
++	return 1 + flash->addr_width;
+ }
+ 
+ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
+@@ -158,7 +163,7 @@ int spi_flash_write_common(struct spi_fl
+ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+ {
+ 	u32 erase_size;
+-	u8 cmd[4];
++	u8 cmd[4], cmd_len;
+ 	int ret = -1;
+ 
+ 	erase_size = flash->erase_size;
+@@ -180,12 +185,13 @@ int spi_flash_cmd_erase_ops(struct spi_f
+ 		if (ret < 0)
+ 			goto done;
+ #endif
+-		spi_flash_addr(offset, cmd);
++		spi_flash_addr(flash, offset, cmd);
++		cmd_len = spi_flash_cmdsz(flash);
+ 
+ 		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+ 		      cmd[2], cmd[3], offset);
+ 
+-		ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
++		ret = spi_flash_write_common(flash, cmd, cmd_len, NULL, 0);
+ 		if (ret < 0) {
+ 			debug("SF: erase failed\n");
+ 			goto done;
+@@ -206,7 +212,7 @@ int spi_flash_cmd_write_ops(struct spi_f
+ {
+ 	unsigned long byte_addr, page_size;
+ 	size_t chunk_len, actual;
+-	u8 cmd[4];
++	u8 cmd[4], cmd_len;
+ 	int ret = -1;
+ 
+ 	ret = spi_claim_bus(flash->spi);
+@@ -230,12 +236,13 @@ int spi_flash_cmd_write_ops(struct spi_f
+ 		if (flash->spi->max_write_size)
+ 			chunk_len = min(chunk_len, flash->spi->max_write_size);
+ 
+-		spi_flash_addr(offset, cmd);
++		spi_flash_addr(flash, offset, cmd);
++		cmd_len = spi_flash_cmdsz(flash);
+ 
+ 		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+ 		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+ 
+-		ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
++		ret = spi_flash_write_common(flash, cmd, cmd_len,
+ 					buf + actual, chunk_len);
+ 		if (ret < 0) {
+ 			debug("SF: write failed\n");
+@@ -269,7 +276,7 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+ 		size_t len, void *data)
+ {
+-	u8 cmd[5], bank_sel = 0;
++	u8 cmd[5], cmd_len, bank_sel = 0;
+ 	u32 remain_len, read_len;
+ 	int ret = -1;
+ 
+@@ -288,7 +295,6 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 	}
+ 
+ 	cmd[0] = CMD_READ_ARRAY_FAST;
+-	cmd[4] = 0x00;
+ 
+ 	while (len) {
+ #ifdef CONFIG_SPI_FLASH_BAR
+@@ -306,9 +312,11 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 		else
+ 			read_len = remain_len;
+ 
+-		spi_flash_addr(offset, cmd);
++		spi_flash_addr(flash, offset, cmd);
++		cmd_len = spi_flash_cmdsz(flash);
++		cmd[cmd_len] = 0x00;
+ 
+-		ret = spi_flash_read_common(flash, cmd, sizeof(cmd),
++		ret = spi_flash_read_common(flash, cmd, cmd_len + 1,
+ 							data, read_len);
+ 		if (ret < 0) {
+ 			debug("SF: read failed\n");
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -218,6 +218,9 @@ static int spi_flash_validate_params(str
+ 		flash->poll_cmd = CMD_FLAG_STATUS;
+ #endif
+ 
++	/* Configure default 3-byte addressing */
++	flash->addr_width = 3;
++
+ 	/* Configure the BAR - discover bank cmds and read current bank */
+ #ifdef CONFIG_SPI_FLASH_BAR
+ 	u8 curr_bank = 0;
+--- a/include/spi_flash.h
++++ b/include/spi_flash.h
+@@ -57,6 +57,7 @@ struct spi_flash {
+ #endif
+ 	u8 poll_cmd;
+ 	u8 erase_cmd;
++	u8 addr_width;
+ 
+ 	void *memory_map;
+ 	int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf);
diff --git a/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch b/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch
new file mode 100644
index 0000000..b903114
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0006-sf-add-support-for-4-byte-addressing.patch
@@ -0,0 +1,160 @@
+From 3af3addee645bd81537be1ddee49969f8dfc64ee Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 13 Oct 2013 15:24:56 +0200
+Subject: sf: add support for 4-byte addressing
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_internal.h
++++ b/drivers/mtd/spi/sf_internal.h
+@@ -38,12 +38,14 @@
+ #define CMD_READ_ID			0x9f
+ 
+ /* Bank addr access commands */
+-#ifdef CONFIG_SPI_FLASH_BAR
+-# define CMD_BANKADDR_BRWR		0x17
+-# define CMD_BANKADDR_BRRD		0x16
+-# define CMD_EXTNADDR_WREAR		0xC5
+-# define CMD_EXTNADDR_RDEAR		0xC8
+-#endif
++#define CMD_BANKADDR_BRWR		0x17
++#define CMD_BANKADDR_BRRD		0x16
++#define CMD_EXTNADDR_WREAR		0xC5
++#define CMD_EXTNADDR_RDEAR		0xC8
++
++/* Macronix style 4-byte addressing */
++#define CMD_EN4B			0xb7
++#define CMD_EX4B			0xe9
+ 
+ /* Common status */
+ #define STATUS_WIP			0x01
+--- a/drivers/mtd/spi/sf_ops.c
++++ b/drivers/mtd/spi/sf_ops.c
+@@ -21,6 +21,7 @@ static void spi_flash_addr(const struct
+ 	cmd[1] = addr >> (flash->addr_width * 8 - 8);
+ 	cmd[2] = addr >> (flash->addr_width * 8 - 16);
+ 	cmd[3] = addr >> (flash->addr_width * 8 - 24);
++	cmd[4] = addr >> (flash->addr_width * 8 - 32);
+ }
+ 
+ static int spi_flash_cmdsz(const struct spi_flash *flash)
+@@ -163,7 +164,7 @@ int spi_flash_write_common(struct spi_fl
+ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+ {
+ 	u32 erase_size;
+-	u8 cmd[4], cmd_len;
++	u8 cmd[5], cmd_len;
+ 	int ret = -1;
+ 
+ 	erase_size = flash->erase_size;
+@@ -188,8 +189,8 @@ int spi_flash_cmd_erase_ops(struct spi_f
+ 		spi_flash_addr(flash, offset, cmd);
+ 		cmd_len = spi_flash_cmdsz(flash);
+ 
+-		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+-		      cmd[2], cmd[3], offset);
++		debug("SF: erase %2x %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
++		      cmd[2], cmd[3], cmd[4], offset);
+ 
+ 		ret = spi_flash_write_common(flash, cmd, cmd_len, NULL, 0);
+ 		if (ret < 0) {
+@@ -212,7 +213,7 @@ int spi_flash_cmd_write_ops(struct spi_f
+ {
+ 	unsigned long byte_addr, page_size;
+ 	size_t chunk_len, actual;
+-	u8 cmd[4], cmd_len;
++	u8 cmd[5], cmd_len;
+ 	int ret = -1;
+ 
+ 	ret = spi_claim_bus(flash->spi);
+@@ -239,8 +240,8 @@ int spi_flash_cmd_write_ops(struct spi_f
+ 		spi_flash_addr(flash, offset, cmd);
+ 		cmd_len = spi_flash_cmdsz(flash);
+ 
+-		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+-		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
++		debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x%02x } chunk_len = %zu\n",
++		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], chunk_len);
+ 
+ 		ret = spi_flash_write_common(flash, cmd, cmd_len,
+ 					buf + actual, chunk_len);
+@@ -276,9 +277,13 @@ int spi_flash_read_common(struct spi_fla
+ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+ 		size_t len, void *data)
+ {
+-	u8 cmd[5], cmd_len, bank_sel = 0;
+-	u32 remain_len, read_len;
++	u8 cmd[6], cmd_len;
++	u32 read_len;
+ 	int ret = -1;
++#ifdef CONFIG_SPI_FLASH_BAR
++	u8 bank_sel = 0;
++	u32 remain_len;
++#endif
+ 
+ 	ret = spi_claim_bus(flash->spi);
+ 	if (ret) {
+@@ -305,12 +310,15 @@ int spi_flash_cmd_read_ops(struct spi_fl
+ 			debug("SF: fail to set bank%d\n", bank_sel);
+ 			goto done;
+ 		}
+-#endif
++
+ 		remain_len = (SPI_FLASH_16MB_BOUN * (bank_sel + 1)) - offset;
+ 		if (len < remain_len)
+ 			read_len = len;
+ 		else
+ 			read_len = remain_len;
++#else
++		read_len = len;
++#endif
+ 
+ 		spi_flash_addr(flash, offset, cmd);
+ 		cmd_len = spi_flash_cmdsz(flash);
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -153,6 +153,25 @@ static const struct spi_flash_params spi
+ 	 */
+ };
+ 
++int spi_flash_4byte_set(struct spi_flash *flash, u8 idcode0, int enable)
++{
++	u8 cmd, bankaddr;
++
++	switch (idcode0) {
++	case 0xc2:
++	case 0xef:
++	case 0x1c:
++		/* Macronix style */
++		cmd = enable ? CMD_EN4B : CMD_EX4B;
++		return spi_flash_cmd(flash->spi, cmd, NULL, 0);
++	default:
++		/* Spansion style */
++		cmd = CMD_BANKADDR_BRWR;
++		bankaddr = enable << 7;
++		return spi_flash_cmd_write(flash->spi, &cmd, 1, &bankaddr, 1);
++	}
++}
++
+ static int spi_flash_validate_params(struct spi_flash *flash,
+ 		u8 *idcode)
+ {
+@@ -218,8 +237,18 @@ static int spi_flash_validate_params(str
+ 		flash->poll_cmd = CMD_FLAG_STATUS;
+ #endif
+ 
++#ifndef CONFIG_SPI_FLASH_BAR
++	/* enable 4-byte addressing if the device exceeds 16MiB */
++	if (flash->size > SPI_FLASH_16MB_BOUN) {
++		flash->addr_width = 4;
++		spi_flash_4byte_set(flash, idcode[0], 1);
++	} else {
++		flash->addr_width = 3;
++	}
++#else
+ 	/* Configure default 3-byte addressing */
+ 	flash->addr_width = 3;
++#endif
+ 
+ 	/* Configure the BAR - discover bank cmds and read current bank */
+ #ifdef CONFIG_SPI_FLASH_BAR
diff --git a/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch b/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch
new file mode 100644
index 0000000..04d008f
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0007-sf-add-support-for-EN25QH256.patch
@@ -0,0 +1,17 @@
+From d5aa0d4117a439803a3d074d2745372036d2a1eb Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 13 Oct 2013 15:35:34 +0200
+Subject: sf: add support for EN25QH256
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -53,6 +53,7 @@ static const struct spi_flash_params spi
+ 	{"EN25Q64",	   0x1c3017, 0x0,	64 * 1024,   128,	       SECT_4K},
+ 	{"EN25Q128B",	   0x1c3018, 0x0,       64 * 1024,   256,	             0},
+ 	{"EN25S64",	   0x1c3817, 0x0,	64 * 1024,   128,		     0},
++	{"EN25QH256",	   0x1c7019, 0x0,	64 * 1024,   512,		     0},
+ #endif
+ #ifdef CONFIG_SPI_FLASH_GIGADEVICE	/* GIGADEVICE */
+ 	{"GD25Q64B",	   0xc84017, 0x0,	64 * 1024,   128,	       SECT_4K},
diff --git a/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch b/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch
new file mode 100644
index 0000000..64f80bf
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0008-sf-fix-sector-layout-of-S25FL256S_256K-and-S25FL512S.patch
@@ -0,0 +1,21 @@
+From 5a6d8045190c887c7f65e65fb1bfc8854774c458 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 13 Oct 2013 15:40:07 +0200
+Subject: sf: fix sector layout of S25FL256S_256K and S25FL512S_256K
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -80,9 +80,9 @@ static const struct spi_flash_params spi
+ 	{"S25FL032P",	   0x010215, 0x4d00,    64 * 1024,    64,	             0},
+ 	{"S25FL064P",	   0x010216, 0x4d00,    64 * 1024,   128,	             0},
+ 	{"S25FL128S_64K",  0x012018, 0x4d01,    64 * 1024,   256,		     0},
+-	{"S25FL256S_256K", 0x010219, 0x4d00,    64 * 1024,   512,	             0},
++	{"S25FL256S_256K", 0x010219, 0x4d00,   256 * 1024,   128,	             0},
+ 	{"S25FL256S_64K",  0x010219, 0x4d01,    64 * 1024,   512,	             0},
+-	{"S25FL512S_256K", 0x010220, 0x4d00,    64 * 1024,  1024,	             0},
++	{"S25FL512S_256K", 0x010220, 0x4d00,   256 * 1024,   256,	             0},
+ 	{"S25FL512S_64K",  0x010220, 0x4d01,    64 * 1024,  1024,	             0},
+ #endif
+ #ifdef CONFIG_SPI_FLASH_STMICRO		/* STMICRO */
diff --git a/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch b/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch
new file mode 100644
index 0000000..de6f51b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0009-net-switchlib-add-framework-for-ethernet-switch-driv.patch
@@ -0,0 +1,244 @@
+From 0dff8c753c8929a478357abb38db0d1c1a60ec94 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add framework for ethernet switch drivers
+
+Add a generic framework similar to phylib for ethernet switch
+drivers and devices. This is useful to share the init and
+setup code for switch devices across different boards.
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Cc: Joe Hershberger <joe.hershberger@gmail.com>
+
+--- a/Makefile
++++ b/Makefile
+@@ -280,6 +280,7 @@ LIBS-y += drivers/mtd/ubi/libubi.o
+ LIBS-y += drivers/mtd/spi/libspi_flash.o
+ LIBS-y += drivers/net/libnet.o
+ LIBS-y += drivers/net/phy/libphy.o
++LIBS-y += drivers/net/switch/libswitch.o
+ LIBS-y += drivers/pci/libpci.o
+ LIBS-y += drivers/pcmcia/libpcmcia.o
+ LIBS-y += drivers/power/libpower.o \
+--- /dev/null
++++ b/drivers/net/switch/Makefile
+@@ -0,0 +1,30 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	:= $(obj)libswitch.o
++
++COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++
++COBJS	:= $(COBJS-y)
++SRCS	:= $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++
++all:	$(LIB)
++
++$(LIB):	$(obj).depend $(OBJS)
++	$(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/drivers/net/switch/switch.c
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++
++static struct list_head switch_drivers;
++static struct list_head switch_devices;
++
++void switch_init(void)
++{
++	INIT_LIST_HEAD(&switch_drivers);
++	INIT_LIST_HEAD(&switch_devices);
++
++	board_switch_init();
++}
++
++void switch_driver_register(struct switch_driver *drv)
++{
++	INIT_LIST_HEAD(&drv->list);
++	list_add_tail(&drv->list, &switch_drivers);
++}
++
++int switch_device_register(struct switch_device *dev)
++{
++	struct switch_driver *drv;
++
++	/* Add switch device only, if an adequate driver is registered */
++	list_for_each_entry(drv, &switch_drivers, list) {
++		if (!strcmp(drv->name, dev->name)) {
++			dev->drv = drv;
++
++			INIT_LIST_HEAD(&dev->list);
++			list_add_tail(&dev->list, &switch_devices);
++
++			return 0;
++		}
++	}
++
++	return -1;
++}
++
++struct switch_device *switch_connect(struct mii_dev *bus)
++{
++	struct switch_device *sw;
++	int err;
++
++	list_for_each_entry(sw, &switch_devices, list) {
++		sw->bus = bus;
++
++		err = sw->drv->probe(sw);
++		if (!err)
++			return sw;
++	}
++
++	return NULL;
++}
+--- /dev/null
++++ b/include/switch.h
+@@ -0,0 +1,102 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __SWITCH_H
++#define __SWITCH_H
++
++#include <linux/list.h>
++
++#define SWITCH_NAME_SIZE	32
++
++struct switch_device;
++struct mii_dev;
++
++struct switch_driver {
++	struct list_head list;
++
++	/* Switch device name */
++	const char name[SWITCH_NAME_SIZE];
++
++	/*
++	 * Called to probe the switch chip. Must return 0 if the switch
++	 * chip matches the given switch device/driver combination. Otherwise
++	 * 1 must be returned.
++	 */
++	int (*probe) (struct switch_device *dev);
++
++	/*
++	 * Called to initialize the switch chip.
++	 */
++	void (*setup) (struct switch_device *dev);
++};
++
++struct switch_device {
++	struct list_head list;
++	struct switch_driver *drv;
++
++	/* MII bus the switch chip is connected to */
++	struct mii_dev *bus;
++
++	/* Switch device name */
++	const char name[SWITCH_NAME_SIZE];
++
++	/* Bitmask for board specific setup of used switch ports */
++	u16 port_mask;
++
++	/* Number of switch port that is connected to host CPU */
++	u16 cpu_port;
++};
++
++/*
++ * Board specific switch initialization.
++ *
++ * Called from switch_init to register the board specific switch_device
++ * structure.
++ */
++extern int board_switch_init(void);
++
++/* Initialize switch subsystem */
++#ifdef CONFIG_SWITCH_MULTI
++extern void switch_init(void);
++#else
++static inline void switch_init(void)
++{
++}
++#endif
++
++/* Register a switch driver */
++extern void switch_driver_register(struct switch_driver *drv);
++
++/* Register a switch device */
++extern int switch_device_register(struct switch_device *dev);
++
++/*
++ * Probe the available switch chips and connect the found one
++ * with the given MII bus
++ */
++#ifdef CONFIG_SWITCH_MULTI
++extern struct switch_device *switch_connect(struct mii_dev *bus);
++#else
++static inline struct switch_device *switch_connect(struct mii_dev *bus)
++{
++	return NULL;
++}
++#endif
++
++/*
++ * Setup the given switch device
++ */
++static inline void switch_setup(struct switch_device *dev)
++{
++	if (dev->drv->setup)
++		dev->drv->setup(dev);
++}
++
++/* Init functions for supported Switch drivers */
++
++#endif /* __SWITCH_H */
++
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -10,6 +10,7 @@
+ #include <net.h>
+ #include <miiphy.h>
+ #include <phy.h>
++#include <switch.h>
+ 
+ void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
+ {
+@@ -287,6 +288,8 @@ int eth_initialize(bd_t *bis)
+ 	phy_init();
+ #endif
+ 
++	switch_init();
++
+ 	eth_env_init(bis);
+ 
+ 	/*
diff --git a/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch b/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch
new file mode 100644
index 0000000..8f486e8
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0010-net-switchlib-add-driver-for-Lantiq-PSB697X-switch-f.patch
@@ -0,0 +1,161 @@
+From e2c59cedebf72e4a002134a2932f722b508a5448 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:15 +0200
+Subject: net: switchlib: add driver for Lantiq PSB697X switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -10,6 +10,7 @@ include $(TOPDIR)/config.mk
+ LIB	:= $(obj)libswitch.o
+ 
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
++COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+ 
+ COBJS	:= $(COBJS-y)
+ SRCS	:= $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/psb697x.c
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define PSB697X_CHIPID1		0x2599
++#define PSB697X_PORT_COUNT	7
++
++#define PSB697X_PORT_BASE(p)	(p * 0x20)
++#define PSB697X_REG_PS(p)	(PSB697X_PORT_BASE(p) + 0x00)
++#define PSB697X_REG_PBC(p)	(PSB697X_PORT_BASE(p) + 0x01)
++#define PSB697X_REG_PEC(p)	(PSB697X_PORT_BASE(p) + 0x02)
++
++#define PSB697X_REG_SGC1	0x0E0	/* Switch Global Control Register 1 */
++#define PSB697X_REG_SGC2	0x0E1	/* Switch Global Control Register 2 */
++#define PSB697X_REG_CMH		0x0E2	/* CPU Port & Mirror Control */
++#define PSB697X_REG_MIICR	0x0F5	/* MII Port Control */
++#define PSB697X_REG_CI0		0x100	/* Chip Identifier 0 */
++#define PSB697X_REG_CI1		0x101	/* Chip Identifier 1 */
++#define PSB697X_REG_MIIAC	0x120	/* MII Indirect Access Control */
++#define PSB697X_REG_MIIWD	0x121	/* MII Indirect Write Data */
++#define PSB697X_REG_MIIRD	0x122	/* MII Indirect Read Data */
++
++#define PSB697X_REG_PORT_FLP	(1 << 2)	/* Force link up */
++#define PSB697X_REG_PORT_FLD	(1 << 1)	/* Force link down */
++
++#define PSB697X_REG_SGC2_SE	(1 << 15)	/* Switch enable */
++
++#define PSB697X_REG_CMH_CPN_MASK	0x7
++#define PSB697X_REG_CMH_CPN_SHIFT	5
++
++
++static inline int psb697x_mii_read(struct mii_dev *bus, u16 reg)
++{
++	int ret;
++
++	ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++	return ret;
++}
++
++static inline int psb697x_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++	int ret;
++
++	ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++		reg & 0x1f, val);
++
++	return ret;
++}
++
++static int psb697x_probe(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	int ci1;
++
++	ci1 = psb697x_mii_read(bus, PSB697X_REG_CI1);
++
++	if (ci1 == PSB697X_CHIPID1)
++		return 0;
++
++	return 1;
++}
++
++static void psb697x_setup(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	int i, state;
++
++	/* Enable switch */
++	psb697x_mii_write(bus, PSB697X_REG_SGC2, PSB697X_REG_SGC2_SE);
++
++	/*
++	 * Force 100 Mbps as default value for CPU ports 5 and 6 to get
++	 * full speed.
++	 */
++	psb697x_mii_write(bus, PSB697X_REG_MIICR, 0x0773);
++
++	for (i = 0; i < PSB697X_PORT_COUNT; i++) {
++		state = dev->port_mask & (1 << i);
++
++		/*
++		 * Software workaround from Errata Sheet:
++		 * Force link down and reset internal PHY, keep that state
++		 * for all unconnected ports and disable force link down
++		 * for all connected ports
++		 */
++		psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++			PSB697X_REG_PORT_FLD);
++
++		if (i == dev->cpu_port)
++			/* Force link up for CPU port */
++			psb697x_mii_write(bus, PSB697X_REG_PBC(i),
++				PSB697X_REG_PORT_FLP);
++		else if (state)
++			/* Disable force link down for active LAN ports */
++			psb697x_mii_write(bus, PSB697X_REG_PBC(i), 0);
++	}
++}
++
++static struct switch_driver psb697x_drv = {
++	.name = "psb697x",
++};
++
++void switch_psb697x_init(void)
++{
++	/* For archs with manual relocation */
++	psb697x_drv.probe = psb697x_probe;
++	psb697x_drv.setup = psb697x_setup;
++
++	switch_driver_register(&psb697x_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -17,6 +17,10 @@ void switch_init(void)
+ 	INIT_LIST_HEAD(&switch_drivers);
+ 	INIT_LIST_HEAD(&switch_devices);
+ 
++#if defined(CONFIG_SWITCH_PSB697X)
++	switch_psb697x_init();
++#endif
++
+ 	board_switch_init();
+ }
+ 
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -97,6 +97,7 @@ static inline void switch_setup(struct s
+ }
+ 
+ /* Init functions for supported Switch drivers */
++extern void switch_psb697x_init(void);
+ 
+ #endif /* __SWITCH_H */
+ 
diff --git a/package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch b/package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch
new file mode 100644
index 0000000..a8b142e
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0011-net-switchlib-add-driver-for-Lantiq-ADM6996I-switch-.patch
@@ -0,0 +1,157 @@
+From c291443dc97dadcf0c6afd04688a7d9f79a221b5 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Lantiq ADM6996I switch family
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -11,6 +11,7 @@ LIB	:= $(obj)libswitch.o
+ 
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
++COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
+ 
+ COBJS	:= $(COBJS-y)
+ SRCS	:= $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/adm6996i.c
+@@ -0,0 +1,115 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define ADM6996I_CHIPID0	0x1020
++#define ADM6996I_CHIPID1	0x0007
++#define ADM6996I_PORT_COUNT	6
++
++#define ADM6996I_REG_P0BC	0x001	/* P0 Basic Control */
++#define ADM6996I_REG_P1BC	0x003	/* P1 Basic Control */
++#define ADM6996I_REG_P2BC	0x005	/* P2 Basic Control */
++#define ADM6996I_REG_P3BC	0x007	/* P3 Basic Control */
++#define ADM6996I_REG_P4BC	0x008	/* P4 Basic Control */
++#define ADM6996I_REG_P5BC	0x009	/* P5 Basic Control */
++
++#define ADM6996I_REG_P0EC	0x002	/* P0 Extended Control */
++#define ADM6996I_REG_P1EC	0x002	/* P1 Extended Control */
++#define ADM6996I_REG_P2EC	0x004	/* P2 Extended Control */
++#define ADM6996I_REG_P3EC	0x004	/* P3 Extended Control */
++#define ADM6996I_REG_P4EC	0x006	/* P4 Extended Control */
++#define ADM6996I_REG_P5EC	0x006	/* P5 Extended Control */
++
++#define ADM6996I_REG_SC4	0x012	/* System Control 4 */
++
++#define ADM6996I_REG_CI0	0xA0	/* Chip Identifier 0 */
++#define ADM6996I_REG_CI1	0xA1	/* Chip Identifier 1 */
++
++#define ADM6996I_REG_PXBC_DEFAULT	0x040F
++#define ADM6996I_REG_PXBC_CROSS_EE	(1 << 15)
++#define ADM6996I_REG_PXBC_PD		(1 << 5)
++
++#define ADM6996I_REG_SC4_DEFAULT	0x3600
++#define ADM6996I_REG_SC4_LED_ENABLE	(1 << 1)
++
++#define ADM6996I_REG_CI0_PC_MASK	0xFFF0
++#define ADM6996I_REG_CI0_VN_MASK	0xF
++#define ADM6996I_REG_CI1_PC_MASK	0xF
++
++
++static inline int adm6996i_mii_read(struct mii_dev *bus, u16 reg)
++{
++	int ret;
++
++	ret = bus->read(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE, reg & 0x1f);
++
++	return ret;
++}
++
++static inline int adm6996i_mii_write(struct mii_dev *bus, u16 reg, u16 val)
++{
++	int ret;
++
++	ret = bus->write(bus, (reg >> 5) & 0x1f, MDIO_DEVAD_NONE,
++		reg & 0x1f, val);
++
++	return ret;
++}
++
++static int adm6996i_probe(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	u16 ci0, ci1;
++
++	ci0 = adm6996i_mii_read(bus, ADM6996I_REG_CI0);
++	ci1 = adm6996i_mii_read(bus, ADM6996I_REG_CI1);
++
++	ci0 &= ADM6996I_REG_CI0_PC_MASK;
++	ci1 &= ADM6996I_REG_CI1_PC_MASK;
++
++	if (ci0 == ADM6996I_CHIPID0 && ci1 == ADM6996I_CHIPID1)
++		return 0;
++
++	return 1;
++}
++
++static void adm6996i_setup(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	u16 val;
++
++	/*
++	 * Write default values (Port enable, 100 Mbps, Full Duplex,
++	 * Auto negotiation, Flow control) and enable crossover auto-detect
++	 */
++	val = ADM6996I_REG_PXBC_DEFAULT | ADM6996I_REG_PXBC_CROSS_EE;
++	adm6996i_mii_write(bus, ADM6996I_REG_P0BC, val);
++	adm6996i_mii_write(bus, ADM6996I_REG_P1BC, val);
++	adm6996i_mii_write(bus, ADM6996I_REG_P2BC, val);
++	adm6996i_mii_write(bus, ADM6996I_REG_P3BC, val);
++	adm6996i_mii_write(bus, ADM6996I_REG_P4BC, val);
++	adm6996i_mii_write(bus, ADM6996I_REG_P5BC, val);
++
++	val = ADM6996I_REG_SC4_DEFAULT | ADM6996I_REG_SC4_LED_ENABLE;
++	adm6996i_mii_write(bus, ADM6996I_REG_SC4, val);
++}
++
++static struct switch_driver adm6996i_drv = {
++	.name = "adm6996i",
++};
++
++void switch_adm6996i_init(void)
++{
++	/* For archs with manual relocation */
++	adm6996i_drv.probe = adm6996i_probe;
++	adm6996i_drv.setup = adm6996i_setup;
++
++	switch_driver_register(&adm6996i_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -20,6 +20,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_PSB697X)
+ 	switch_psb697x_init();
+ #endif
++#if defined(CONFIG_SWITCH_ADM6996I)
++	switch_adm6996i_init();
++#endif
+ 
+ 	board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -98,6 +98,7 @@ static inline void switch_setup(struct s
+ 
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
++extern void switch_adm6996i_init(void);
+ 
+ #endif /* __SWITCH_H */
+ 
diff --git a/package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch b/package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch
new file mode 100644
index 0000000..568f9ad
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0012-net-switchlib-add-driver-for-Atheros-AR8216.patch
@@ -0,0 +1,157 @@
+From 1a1d61a2faf0390033a3766559ce0e758e15894e Mon Sep 17 00:00:00 2001
+From: Luka Perkov <openwrt@lukaperkov.net>
+Date: Wed, 29 Aug 2012 22:08:16 +0200
+Subject: net: switchlib: add driver for Atheros AR8216
+
+Signed-off-by: Luka Perkov <openwrt@lukaperkov.net>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -12,6 +12,7 @@ LIB	:= $(obj)libswitch.o
+ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+ COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
++COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o
+ 
+ COBJS	:= $(COBJS-y)
+ SRCS	:= $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/ar8216.c
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <netdev.h>
++
++#define BITS(_s, _n)  (((1UL << (_n)) - 1) << _s)
++
++#define AR8216_REG_CTRL			0x0000
++#define   AR8216_CTRL_REVISION		BITS(0, 8)
++#define   AR8216_CTRL_VERSION		BITS(8, 8)
++
++#define AR8216_PROBE_RETRIES		10
++
++static void split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
++{
++	regaddr >>= 1;
++	*r1 = regaddr & 0x1e;
++
++	regaddr >>= 5;
++	*r2 = regaddr & 0x7;
++
++	regaddr >>= 3;
++	*page = regaddr & 0x1ff;
++}
++
++static int ar8216_mii_read(struct mii_dev *bus, u32 reg)
++{
++	u16 r1, r2, page;
++	u16 lo, hi;
++
++	split_addr(reg, &r1, &r2, &page);
++
++	bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, page);
++	__udelay(1000);
++
++	lo = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1);
++	hi = bus->read(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1);
++
++	return (hi << 16) | lo;
++}
++
++static void ar8216_mii_write(struct mii_dev *bus, u16 reg, u32 val)
++{
++	u16 r1, r2, r3;
++	u16 lo, hi;
++
++	split_addr((u32) reg, &r1, &r2, &r3);
++
++	bus->write(bus, 0x18, MDIO_DEVAD_NONE, 0, r3);
++	__udelay(1000);
++
++	lo = val & 0xffff;
++	hi = (u16) (val >> 16);
++	bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1 + 1, hi);
++	bus->write(bus, 0x10 | r2, MDIO_DEVAD_NONE, r1, lo);
++}
++
++static int ar8216_probe(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	u32 val;
++	u16 id;
++
++	val = ar8216_mii_read(bus, AR8216_REG_CTRL);
++	if (val == ~0)
++		return 1;
++
++	id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION);
++
++	switch (id) {
++		case 0x0101:
++			return 0;
++		default:
++			return 1;
++	}
++}
++
++static void ar8216_setup(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++
++	ar8216_mii_write(bus, 0x200, 0x200);
++	ar8216_mii_write(bus, 0x300, 0x200);
++	ar8216_mii_write(bus, 0x400, 0x200);
++	ar8216_mii_write(bus, 0x500, 0x200);
++	ar8216_mii_write(bus, 0x600, 0x7d);
++	ar8216_mii_write(bus, 0x38, 0xc000050e);
++	ar8216_mii_write(bus, 0x104, 0x4004);
++	ar8216_mii_write(bus, 0x60, 0xffffffff);
++	ar8216_mii_write(bus, 0x64, 0xaaaaaaaa);
++	ar8216_mii_write(bus, 0x68, 0x55555555);
++	ar8216_mii_write(bus, 0x6c, 0x0);
++	ar8216_mii_write(bus, 0x70, 0x41af);
++}
++
++static struct switch_driver ar8216_drv = {
++	.name = "ar8216",
++};
++
++void switch_ar8216_init(void)
++{
++	/* for archs with manual relocation */
++	ar8216_drv.probe = ar8216_probe;
++	ar8216_drv.setup = ar8216_setup;
++
++	switch_driver_register(&ar8216_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -23,6 +23,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_ADM6996I)
+ 	switch_adm6996i_init();
+ #endif
++#if defined(CONFIG_SWITCH_AR8216)
++	switch_ar8216_init();
++#endif
+ 
+ 	board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -99,6 +99,7 @@ static inline void switch_setup(struct s
+ /* Init functions for supported Switch drivers */
+ extern void switch_psb697x_init(void);
+ extern void switch_adm6996i_init(void);
++extern void switch_ar8216_init(void);
+ 
+ #endif /* __SWITCH_H */
+ 
diff --git a/package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch b/package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch
new file mode 100644
index 0000000..72b885a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0013-net-switchlib-add-driver-for-REALTEK-RTL8306.patch
@@ -0,0 +1,375 @@
+From 42cb399df978a33539b95d668b3f973d927cb902 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 17 Dec 2012 23:37:57 +0100
+Subject: net: switchlib: add driver for REALTEK RTL8306
+
+Signed-off-by: Oliver Muth <dr.o.muth@gmx.de>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/drivers/net/switch/Makefile
++++ b/drivers/net/switch/Makefile
+@@ -13,6 +13,7 @@ COBJS-$(CONFIG_SWITCH_MULTI) += switch.o
+ COBJS-$(CONFIG_SWITCH_PSB697X) += psb697x.o
+ COBJS-$(CONFIG_SWITCH_ADM6996I) += adm6996i.o
+ COBJS-$(CONFIG_SWITCH_AR8216) += ar8216.o
++COBJS-$(CONFIG_SWITCH_RTL8306) += rtl8306.o
+ 
+ COBJS	:= $(COBJS-y)
+ SRCS	:= $(COBJS:.o=.c)
+--- /dev/null
++++ b/drivers/net/switch/rtl8306.c
+@@ -0,0 +1,332 @@
++/*
++ * Based on OpenWrt linux driver
++ *
++ * Copyright (C) 2011-2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++#define DEBUG
++#include <common.h>
++#include <malloc.h>
++#include <switch.h>
++#include <miiphy.h>
++
++#define RTL8306_REG_PAGE		16
++#define RTL8306_REG_PAGE_LO		(1 << 15)
++#define RTL8306_REG_PAGE_HI		(1 << 1) /* inverted */
++#define RTL8306_CHIPID			0x5988
++
++#define RTL8306_NUM_VLANS		16
++#define RTL8306_NUM_PORTS		6
++#define RTL8306_PORT_CPU		5
++#define RTL8306_NUM_PAGES		4
++#define RTL8306_NUM_REGS		32
++
++enum {
++	RTL_TYPE_S,
++	RTL_TYPE_SD,
++	RTL_TYPE_SDM,
++};
++
++struct rtl_reg {
++	int page;
++	int phy;
++	int reg;
++	int bits;
++	int shift;
++	int inverted;
++};
++
++enum rtl_regidx {
++	RTL_REG_CHIPID,
++	RTL_REG_CHIPVER,
++	RTL_REG_CHIPTYPE,
++	RTL_REG_CPUPORT,
++
++	RTL_REG_EN_CPUPORT,
++	RTL_REG_EN_TAG_OUT,
++	RTL_REG_EN_TAG_CLR,
++	RTL_REG_EN_TAG_IN,
++	RTL_REG_TRAP_CPU,
++	RTL_REG_TRUNK_PORTSEL,
++	RTL_REG_EN_TRUNK,
++	RTL_REG_RESET,
++	RTL_REG_PHY_RESET,
++	RTL_REG_CPU_LINKUP,
++
++	RTL_REG_VLAN_ENABLE,
++	RTL_REG_VLAN_FILTER,
++	RTL_REG_VLAN_TAG_ONLY,
++	RTL_REG_VLAN_TAG_AWARE,
++#define RTL_VLAN_ENUM(id) \
++	RTL_REG_VLAN##id##_VID, \
++	RTL_REG_VLAN##id##_PORTMASK
++	RTL_VLAN_ENUM(0),
++	RTL_VLAN_ENUM(1),
++	RTL_VLAN_ENUM(2),
++	RTL_VLAN_ENUM(3),
++	RTL_VLAN_ENUM(4),
++	RTL_VLAN_ENUM(5),
++	RTL_VLAN_ENUM(6),
++	RTL_VLAN_ENUM(7),
++	RTL_VLAN_ENUM(8),
++	RTL_VLAN_ENUM(9),
++	RTL_VLAN_ENUM(10),
++	RTL_VLAN_ENUM(11),
++	RTL_VLAN_ENUM(12),
++	RTL_VLAN_ENUM(13),
++	RTL_VLAN_ENUM(14),
++	RTL_VLAN_ENUM(15),
++#define RTL_PORT_ENUM(id) \
++	RTL_REG_PORT##id##_PVID, \
++	RTL_REG_PORT##id##_NULL_VID_REPLACE, \
++	RTL_REG_PORT##id##_NON_PVID_DISCARD, \
++	RTL_REG_PORT##id##_VID_INSERT, \
++	RTL_REG_PORT##id##_TAG_INSERT, \
++	RTL_REG_PORT##id##_LINK, \
++	RTL_REG_PORT##id##_SPEED, \
++	RTL_REG_PORT##id##_NWAY, \
++	RTL_REG_PORT##id##_NRESTART, \
++	RTL_REG_PORT##id##_DUPLEX, \
++	RTL_REG_PORT##id##_RXEN, \
++	RTL_REG_PORT##id##_TXEN, \
++	RTL_REG_PORT##id##_LRNEN
++	RTL_PORT_ENUM(0),
++	RTL_PORT_ENUM(1),
++	RTL_PORT_ENUM(2),
++	RTL_PORT_ENUM(3),
++	RTL_PORT_ENUM(4),
++	RTL_PORT_ENUM(5),
++};
++
++static const struct rtl_reg rtl_regs[] = {
++	[RTL_REG_CHIPID]         = { 0, 4, 30, 16,  0, 0 },
++	[RTL_REG_CHIPVER]        = { 0, 4, 31,  8,  0, 0 },
++	[RTL_REG_CHIPTYPE]       = { 0, 4, 31,  2,  8, 0 },
++
++	/* CPU port number */
++	[RTL_REG_CPUPORT]        = { 2, 4, 21,  3,  0, 0 },
++	/* Enable CPU port function */
++	[RTL_REG_EN_CPUPORT]     = { 3, 2, 21,  1, 15, 1 },
++	/* Enable CPU port tag insertion */
++	[RTL_REG_EN_TAG_OUT]     = { 3, 2, 21,  1, 12, 0 },
++	/* Enable CPU port tag removal */
++	[RTL_REG_EN_TAG_CLR]     = { 3, 2, 21,  1, 11, 0 },
++	/* Enable CPU port tag checking */
++	[RTL_REG_EN_TAG_IN]      = { 0, 4, 21,  1,  7, 0 },
++	[RTL_REG_EN_TRUNK]       = { 0, 0, 19,  1, 11, 1 },
++	[RTL_REG_TRUNK_PORTSEL]  = { 0, 0, 16,  1,  6, 1 },
++	[RTL_REG_RESET]          = { 0, 0, 16,  1, 12, 0 },
++	[RTL_REG_PHY_RESET]	 = { 0, 0,  0,  1, 15, 0 },
++	[RTL_REG_CPU_LINKUP]	 = { 0, 6, 22,  1, 15, 0 },
++	[RTL_REG_TRAP_CPU]       = { 3, 2, 22,  1,  6, 0 },
++
++	[RTL_REG_VLAN_TAG_ONLY]  = { 0, 0, 16,  1,  8, 1 },
++	[RTL_REG_VLAN_FILTER]    = { 0, 0, 16,  1,  9, 1 },
++	[RTL_REG_VLAN_TAG_AWARE] = { 0, 0, 16,  1, 10, 1 },
++	[RTL_REG_VLAN_ENABLE]    = { 0, 0, 18,  1,  8, 1 },
++
++#define RTL_VLAN_REGS(id, phy, page, regofs) \
++	[RTL_REG_VLAN##id##_VID] = { page, phy, 25 + regofs, 12, 0, 0 }, \
++	[RTL_REG_VLAN##id##_PORTMASK] = { page, phy, 24 + regofs, 6, 0, 0 }
++	RTL_VLAN_REGS( 0, 0, 0, 0),
++	RTL_VLAN_REGS( 1, 1, 0, 0),
++	RTL_VLAN_REGS( 2, 2, 0, 0),
++	RTL_VLAN_REGS( 3, 3, 0, 0),
++	RTL_VLAN_REGS( 4, 4, 0, 0),
++	RTL_VLAN_REGS( 5, 0, 1, 2),
++	RTL_VLAN_REGS( 6, 1, 1, 2),
++	RTL_VLAN_REGS( 7, 2, 1, 2),
++	RTL_VLAN_REGS( 8, 3, 1, 2),
++	RTL_VLAN_REGS( 9, 4, 1, 2),
++	RTL_VLAN_REGS(10, 0, 1, 4),
++	RTL_VLAN_REGS(11, 1, 1, 4),
++	RTL_VLAN_REGS(12, 2, 1, 4),
++	RTL_VLAN_REGS(13, 3, 1, 4),
++	RTL_VLAN_REGS(14, 4, 1, 4),
++	RTL_VLAN_REGS(15, 0, 1, 6),
++
++#define REG_PORT_SETTING(port, phy) \
++	[RTL_REG_PORT##port##_SPEED] = { 0, phy, 0, 1, 13, 0 }, \
++	[RTL_REG_PORT##port##_NWAY] = { 0, phy, 0, 1, 12, 0 }, \
++	[RTL_REG_PORT##port##_NRESTART] = { 0, phy, 0, 1, 9, 0 }, \
++	[RTL_REG_PORT##port##_DUPLEX] = { 0, phy, 0, 1, 8, 0 }, \
++	[RTL_REG_PORT##port##_TXEN] = { 0, phy, 24, 1, 11, 0 }, \
++	[RTL_REG_PORT##port##_RXEN] = { 0, phy, 24, 1, 10, 0 }, \
++	[RTL_REG_PORT##port##_LRNEN] = { 0, phy, 24, 1, 9, 0 }, \
++	[RTL_REG_PORT##port##_LINK] = { 0, phy, 1, 1, 2, 0 }, \
++	[RTL_REG_PORT##port##_NULL_VID_REPLACE] = { 0, phy, 22, 1, 12, 0 }, \
++	[RTL_REG_PORT##port##_NON_PVID_DISCARD] = { 0, phy, 22, 1, 11, 0 }, \
++	[RTL_REG_PORT##port##_VID_INSERT] = { 0, phy, 22, 2, 9, 0 }, \
++	[RTL_REG_PORT##port##_TAG_INSERT] = { 0, phy, 22, 2, 0, 0 }
++
++	REG_PORT_SETTING(0, 0),
++	REG_PORT_SETTING(1, 1),
++	REG_PORT_SETTING(2, 2),
++	REG_PORT_SETTING(3, 3),
++	REG_PORT_SETTING(4, 4),
++	REG_PORT_SETTING(5, 6),
++
++#define REG_PORT_PVID(phy, page, regofs) \
++	{ page, phy, 24 + regofs, 4, 12, 0 }
++	[RTL_REG_PORT0_PVID] = REG_PORT_PVID(0, 0, 0),
++	[RTL_REG_PORT1_PVID] = REG_PORT_PVID(1, 0, 0),
++	[RTL_REG_PORT2_PVID] = REG_PORT_PVID(2, 0, 0),
++	[RTL_REG_PORT3_PVID] = REG_PORT_PVID(3, 0, 0),
++	[RTL_REG_PORT4_PVID] = REG_PORT_PVID(4, 0, 0),
++	[RTL_REG_PORT5_PVID] = REG_PORT_PVID(0, 1, 2),
++};
++
++static void rtl_set_page(struct mii_dev *bus, unsigned int page)
++{
++	u16 pgsel;
++
++	BUG_ON(page > RTL8306_NUM_PAGES);
++
++	pgsel = bus->read(bus, 0, MDIO_DEVAD_NONE, RTL8306_REG_PAGE);
++	pgsel &= ~(RTL8306_REG_PAGE_LO | RTL8306_REG_PAGE_HI);
++
++	if (page & (1 << 0))
++		pgsel |= RTL8306_REG_PAGE_LO;
++
++	if (!(page & (1 << 1))) /* bit is inverted */
++		pgsel |= RTL8306_REG_PAGE_HI;
++
++	bus->write(bus, 0, MDIO_DEVAD_NONE, RTL8306_REG_PAGE, pgsel);
++
++}
++
++static __maybe_unused int rtl_w16(struct mii_dev *bus, unsigned int page, unsigned int phy,
++			unsigned int reg, u16 val)
++{
++	rtl_set_page(bus, page);
++
++	bus->write(bus, phy, MDIO_DEVAD_NONE, reg, val);
++	bus->read(bus, phy, MDIO_DEVAD_NONE, reg); /* flush */
++
++	return 0;
++}
++
++static int rtl_r16(struct mii_dev *bus, unsigned int page, unsigned int phy,
++			unsigned int reg)
++{
++	rtl_set_page(bus, page);
++
++	return bus->read(bus, phy, MDIO_DEVAD_NONE, reg);
++}
++
++static u16 rtl_rmw(struct mii_dev *bus, unsigned int page, unsigned int phy,
++			unsigned int reg, u16 mask, u16 val)
++{
++	u16 r;
++
++	rtl_set_page(bus, page);
++
++	r = bus->read(bus, phy, MDIO_DEVAD_NONE, reg);
++	r &= ~mask;
++	r |= val;
++	bus->write(bus, phy, MDIO_DEVAD_NONE, reg, r);
++
++	return bus->read(bus, phy, MDIO_DEVAD_NONE, reg); /* flush */
++}
++
++static int rtl_get(struct mii_dev *bus, enum rtl_regidx s)
++{
++	const struct rtl_reg *r = &rtl_regs[s];
++	u16 val;
++
++	BUG_ON(s >= ARRAY_SIZE(rtl_regs));
++
++	if (r->bits == 0) /* unimplemented */
++		return 0;
++
++	val = rtl_r16(bus, r->page, r->phy, r->reg);
++
++	if (r->shift > 0)
++		val >>= r->shift;
++
++	if (r->inverted)
++		val = ~val;
++
++	val &= (1 << r->bits) - 1;
++
++	return val;
++}
++
++static __maybe_unused int rtl_set(struct mii_dev *bus, enum rtl_regidx s, unsigned int val)
++{
++	const struct rtl_reg *r = &rtl_regs[s];
++	u16 mask = 0xffff;
++
++	BUG_ON(s >= ARRAY_SIZE(rtl_regs));
++
++	if (r->bits == 0) /* unimplemented */
++		return 0;
++
++	if (r->shift > 0)
++		val <<= r->shift;
++
++	if (r->inverted)
++		val = ~val;
++
++	if (r->bits != 16) {
++		mask = (1 << r->bits) - 1;
++		mask <<= r->shift;
++	}
++
++	val &= mask;
++
++	return rtl_rmw(bus, r->page, r->phy, r->reg, mask, val);
++}
++
++static int rtl8306_probe(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++	unsigned int chipid, chipver, chiptype;
++
++	chipid = rtl_get(bus, RTL_REG_CHIPID);
++	chipver = rtl_get(bus, RTL_REG_CHIPVER);
++	chiptype = rtl_get(bus, RTL_REG_CHIPTYPE);
++
++	debug("%s: chipid %x, chipver %x, chiptype %x\n",
++		__func__, chipid, chipver, chiptype);
++
++	if (chipid == RTL8306_CHIPID)
++		return 0;
++
++	return 1;
++}
++
++static void rtl8306_setup(struct switch_device *dev)
++{
++	struct mii_dev *bus = dev->bus;
++
++	/* initialize cpu port settings */
++	rtl_set(bus, RTL_REG_CPUPORT, dev->cpu_port);
++	rtl_set(bus, RTL_REG_EN_CPUPORT, 1);
++
++	/* enable phy 5 link status */
++	rtl_set(bus, RTL_REG_CPU_LINKUP, 1);
++//	rtl_set(bus, RTL_REG_PORT5_TXEN, 1);
++//	rtl_set(bus, RTL_REG_PORT5_RXEN, 1);
++//	rtl_set(bus, RTL_REG_PORT5_LRNEN, 1);
++#ifdef DEBUG
++ debug("%s: CPU link up: %i\n",
++		__func__, rtl_get(bus, RTL_REG_PORT5_LINK));
++#endif
++
++}
++
++static struct switch_driver rtl8306_drv = {
++	.name = "rtl8306",
++};
++
++void switch_rtl8306_init(void)
++{
++	/* For archs with manual relocation */
++	rtl8306_drv.probe = rtl8306_probe;
++	rtl8306_drv.setup = rtl8306_setup;
++
++	switch_driver_register(&rtl8306_drv);
++}
+--- a/drivers/net/switch/switch.c
++++ b/drivers/net/switch/switch.c
+@@ -26,6 +26,9 @@ void switch_init(void)
+ #if defined(CONFIG_SWITCH_AR8216)
+ 	switch_ar8216_init();
+ #endif
++#if defined(CONFIG_SWITCH_RTL8306)
++	switch_rtl8306_init();
++#endif
+ 
+ 	board_switch_init();
+ }
+--- a/include/switch.h
++++ b/include/switch.h
+@@ -100,6 +100,7 @@ static inline void switch_setup(struct s
+ extern void switch_psb697x_init(void);
+ extern void switch_adm6996i_init(void);
+ extern void switch_ar8216_init(void);
++extern void switch_rtl8306_init(void);
+ 
+ #endif /* __SWITCH_H */
+ 
diff --git a/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch b/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
new file mode 100644
index 0000000..cb695ff
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
@@ -0,0 +1,8707 @@
+From 11553b0de8992ded6240d034bd49f561d17bea53 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Thu, 13 Jun 2013 01:18:02 +0200
+Subject: MIPS: add support for Lantiq XWAY SoCs
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/.gitignore
++++ b/.gitignore
+@@ -49,6 +49,13 @@
+ /u-boot.sb
+ /u-boot.bd
+ /u-boot.geany
++/u-boot.bin.lzma
++/u-boot.bin.lzo
++/u-boot.ltq.lzma.norspl
++/u-boot.ltq.lzo.norspl
++/u-boot.ltq.norspl
++/u-boot.lzma.img
++/u-boot.lzo.img
+ 
+ #
+ # Generated files
+--- a/Makefile
++++ b/Makefile
+@@ -435,6 +435,12 @@ $(obj)u-boot.bin:	$(obj)u-boot
+ 		$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+ 		$(BOARD_SIZE_CHECK)
+ 
++$(obj)u-boot.bin.lzma:	$(obj)u-boot.bin
++		cat $< | lzma -9 -f - > $@
++
++$(obj)u-boot.bin.lzo:	$(obj)u-boot.bin
++		cat $< | lzop -9 -f - > $@
++
+ $(obj)u-boot.ldr:	$(obj)u-boot
+ 		$(CREATE_LDR_ENV)
+ 		$(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
+@@ -454,13 +460,23 @@ ifndef CONFIG_SYS_UBOOT_START
+ CONFIG_SYS_UBOOT_START := 0
+ endif
+ 
+-$(obj)u-boot.img:	$(obj)u-boot.bin
+-		$(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
++define GEN_UBOOT_IMAGE
++		$(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
+ 		-O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
+ 		-e $(CONFIG_SYS_UBOOT_START) \
+ 		-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
+ 			sed -e 's/"[	 ]*$$/ for $(BOARD) board"/') \
+ 		-d $< $@
++endef
++
++$(obj)u-boot.img:	$(obj)u-boot.bin
++		$(call GEN_UBOOT_IMAGE,none)
++
++$(obj)u-boot.lzma.img:	$(obj)u-boot.bin.lzma
++		$(call GEN_UBOOT_IMAGE,lzma)
++
++$(obj)u-boot.lzo.img:	$(obj)u-boot.bin.lzo
++		$(call GEN_UBOOT_IMAGE,lzo)
+ 
+ $(obj)u-boot.imx: $(obj)u-boot.bin depend
+ 		$(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
+@@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)s
+ 			conv=notrunc 2>/dev/null
+ 		cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
+ 
++$(obj)u-boot.ltq.sfspl:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++	cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++	cat $(obj)spl/u-boot-spl.bin $< > $@
++
++$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++	cat $(obj)spl/u-boot-spl.bin $< > $@
++
+ ifeq ($(CONFIG_SANDBOX),y)
+ GEN_UBOOT = \
+ 		cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
+--- a/README
++++ b/README
+@@ -468,6 +468,11 @@ The following options need to be configu
+ 			CONF_CM_CACHABLE_CUW
+ 			CONF_CM_CACHABLE_ACCELERATED
+ 
++		CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++		Enable this to use extended cache initialization for recent
++		MIPS CPU cores.
++
+ 		CONFIG_SYS_XWAY_EBU_BOOTCFG
+ 
+ 		Special option for Lantiq XWAY SoCs for booting from NOR flash.
+--- a/arch/mips/config.mk
++++ b/arch/mips/config.mk
+@@ -45,9 +45,13 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M
+ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
+ # to RAM. $28 is always used as gp.
+ #
+-PLATFORM_CPPFLAGS		+= -G 0 -mabicalls -fpic $(ENDIANNESS)
++PF_ABICALLS			?= -mabicalls
++PF_PIC				?= -fpic
++PF_PIE				?= -pie
++
++PLATFORM_CPPFLAGS		+= -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
+ PLATFORM_CPPFLAGS		+= -msoft-float
+ PLATFORM_LDFLAGS		+= -G 0 -static -n -nostdlib $(ENDIANNESS)
+ PLATFORM_RELFLAGS		+= -ffunction-sections -fdata-sections
+-LDFLAGS_FINAL			+= --gc-sections -pie
++LDFLAGS_FINAL			+= --gc-sections $(PF_PIE)
+ OBJCFLAGS			+= --remove-section=.dynsym
+--- a/arch/mips/cpu/mips32/cache.S
++++ b/arch/mips/cpu/mips32/cache.S
+@@ -29,7 +29,11 @@
+  */
+ #define MIPS_MAX_CACHE_SIZE	0x10000
+ 
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++#define INDEX_BASE	0x9fc00000
++#else
+ #define INDEX_BASE	CKSEG0
++#endif
+ 
+ 	.macro	cache_op op addr
+ 	.set	push
+@@ -65,7 +69,11 @@
+  */
+ LEAF(mips_init_icache)
+ 	blez		a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++	mtc0		zero, CP0_ITAGLO
++#else
+ 	mtc0		zero, CP0_TAGLO
++#endif
+ 	/* clear tag to invalidate */
+ 	PTR_LI		t0, INDEX_BASE
+ 	PTR_ADDU	t1, t0, a1
+@@ -90,7 +98,11 @@ LEAF(mips_init_icache)
+  */
+ LEAF(mips_init_dcache)
+ 	blez		a1, 9f
++#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
++	mtc0		zero, CP0_DTAGLO
++#else
+ 	mtc0		zero, CP0_TAGLO
++#endif
+ 	/* clear all tags */
+ 	PTR_LI		t0, INDEX_BASE
+ 	PTR_ADDU	t1, t0, a1
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/Makefile
+@@ -0,0 +1,31 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(SOC).o
++
++COBJS-y	+= cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
++SOBJS-y	+= cgu_init.o mem_init.o
++
++COBJS	:= $(COBJS-y)
++SOBJS	:= $(SOBJS-y)
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all:	$(LIB)
++
++$(LIB):	$(obj).depend $(OBJS)
++	$(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu.c
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_SYS_DDR_MASK		0x0003
++#define LTQ_CGU_SYS_DDR_SHIFT		0
++#define LTQ_CGU_SYS_CPU0_MASK		0x000C
++#define LTQ_CGU_SYS_CPU0_SHIFT		2
++#define LTQ_CGU_SYS_FPI_MASK		0x0040
++#define LTQ_CGU_SYS_FPI_SHIFT		6
++
++struct ltq_cgu_regs {
++	u32	rsvd0;
++	u32	pll0_cfg;	/* PLL0 config */
++	u32	pll1_cfg;	/* PLL1 config */
++	u32	pll2_cfg;	/* PLL2 config */
++	u32	sys;		/* System clock */
++	u32	update;		/* CGU update control */
++	u32	if_clk;		/* Interface clock */
++	u32	osc_con;	/* Update OSC Control */
++	u32	smd;		/* SDRAM Memory Control */
++	u32	rsvd1[3];
++	u32	pcm_cr;		/* PCM control */
++	u32	pci_cr;		/* PCI clock control */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++	(struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++	return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++	u32 ddr_sel;
++	unsigned long clk;
++
++	ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
++					LTQ_CGU_SYS_DDR_SHIFT);
++
++	switch (ddr_sel) {
++	case 0:
++		clk = CLOCK_166_MHZ;
++		break;
++	case 1:
++		clk = CLOCK_133_MHZ;
++		break;
++	case 2:
++		clk = CLOCK_111_MHZ;
++		break;
++	case 3:
++		clk = CLOCK_83_MHZ;
++		break;
++	default:
++		clk = 0;
++		break;
++	}
++
++	return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++	u32 cpu0_sel;
++	unsigned long clk;
++
++	cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
++					LTQ_CGU_SYS_CPU0_SHIFT);
++
++	switch (cpu0_sel) {
++		/* Same as PLL0 output (333,33 MHz) */
++	case 0:
++		clk = CLOCK_333_MHZ;
++		break;
++		/* 1/1 fixed ratio to DDR clock */
++	case 1:
++		clk = ltq_get_io_region_clock();
++		break;
++		/* 1/2 fixed ratio to DDR clock */
++	case 2:
++		clk = ltq_get_io_region_clock() << 1;
++		break;
++	default:
++		clk = 0;
++		break;
++	}
++
++	return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++	u32 fpi_sel;
++	unsigned long clk;
++
++	fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
++					LTQ_CGU_SYS_FPI_SHIFT);
++
++	if (fpi_sel)
++		/* Half the DDR clock */
++		clk = ltq_get_io_region_clock() >> 1;
++	else
++		/* Same as DDR clock */
++		clk = ltq_get_io_region_clock();
++
++	return clk;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/cgu_init.S
+@@ -0,0 +1,142 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ			0x0010
++#define LTQ_RCU_RST_STAT		0x0014
++#define LTQ_RCU_RST_REQ_VALUE		0x40000008
++#define LTQ_RCU_RST_STAT_XTAL_F	0x20000
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG		0x0004	/* PLL0 config */
++#define LTQ_CGU_PLL1_CFG		0x0008	/* PLL1 config */
++#define LTQ_CGU_PLL2_CFG		0x000C	/* PLL2 config */
++#define LTQ_CGU_SYS			0x0010	/* System clock */
++
++/* Valid SYS.CPU0/1 values */
++#define LTQ_CGU_SYS_CPU0_SHIFT		2
++#define LTQ_CGU_SYS_CPU1_SHIFT		4
++#define LTQ_CGU_SYS_CPU_PLL0		0x0
++#define LTQ_CGU_SYS_CPU_DDR_EQUAL	0x1
++#define LTQ_CGU_SYS_CPU_DDR_TWICE	0x2
++
++/* Valid SYS.DDR values */
++#define LTQ_CGU_SYS_DDR_SHIFT		0
++#define LTQ_CGU_SYS_DDR_167_MHZ	0x0
++#define LTQ_CGU_SYS_DDR_133_MHZ	0x1
++#define LTQ_CGU_SYS_DDR_111_MHZ	0x2
++#define LTQ_CGU_SYS_DDR_83_MHZ		0x3
++
++/* Valid SYS.FPI values */
++#define LTQ_CGU_SYS_FPI_SHIFT		6
++#define LTQ_CGU_SYS_FPI_DDR_EQUAL	0x0
++#define LTQ_CGU_SYS_FPI_DDR_HALF	0x1
++
++/* Valid SYS.PPE values */
++#define LTQ_CGU_SYS_PPE_SHIFT		7
++#define LTQ_CGU_SYS_PPE_266_MHZ	0x0
++#define LTQ_CGU_SYS_PPE_240_MHZ	0x1
++#define LTQ_CGU_SYS_PPE_222_MHZ	0x2
++#define LTQ_CGU_SYS_PPE_133_MHZ	0x3
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
++#define LTQ_CGU_SYS_CPU_CONFIG		LTQ_CGU_SYS_CPU_DDR_TWICE
++#define LTQ_CGU_SYS_DDR_CONFIG		LTQ_CGU_SYS_DDR_167_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG		LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG		LTQ_CGU_SYS_PPE_266_MHZ
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
++#define LTQ_CGU_SYS_CPU_CONFIG		LTQ_CGU_SYS_CPU_DDR_EQUAL
++#define LTQ_CGU_SYS_DDR_CONFIG		LTQ_CGU_SYS_DDR_111_MHZ
++#define LTQ_CGU_SYS_FPI_CONFIG		LTQ_CGU_SYS_FPI_DDR_HALF
++#define LTQ_CGU_SYS_PPE_CONFIG		LTQ_CGU_SYS_PPE_133_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE	((LTQ_CGU_SYS_PPE_CONFIG << \
++					LTQ_CGU_SYS_PPE_SHIFT) | \
++				(LTQ_CGU_SYS_FPI_CONFIG << \
++					LTQ_CGU_SYS_FPI_SHIFT) | \
++				(LTQ_CGU_SYS_CPU_CONFIG << \
++					LTQ_CGU_SYS_CPU1_SHIFT) | \
++				(LTQ_CGU_SYS_CPU_CONFIG << \
++					LTQ_CGU_SYS_CPU0_SHIFT) | \
++				LTQ_CGU_SYS_DDR_CONFIG)
++
++/* Reset values for PLL registers for usage with 35.328 MHz crystal */
++#define PLL0_35MHZ_CONFIG	0x9D861059
++#define PLL1_35MHZ_CONFIG	0x1A260CD9
++#define PLL2_35MHZ_CONFIG	0x8000f1e5
++
++/* Reset values for PLL registers for usage with 36 MHz crystal */
++#define PLL0_36MHZ_CONFIG	0x1000125D
++#define PLL1_36MHZ_CONFIG	0x1B1E0C99
++#define PLL2_36MHZ_CONFIG	0x8002f2a1
++
++LEAF(ltq_cgu_init)
++	/* Load current CGU register value */
++	li	t0, (LTQ_CGU_BASE | KSEG1)
++	lw	t1, LTQ_CGU_SYS(t0)
++
++	/* Load target CGU register values */
++	li	t3, LTQ_CGU_SYS_VALUE
++
++	/* Only update registers if values differ */
++	beq	t1, t3, finished
++
++	/*
++	 * Check whether the XTAL_F bit in RST_STAT register is set or not.
++	 * This bit is latched in via pin strapping. If bit is set then
++	 * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
++	 */
++	 li	t1, (LTQ_RCU_BASE | KSEG1)
++	 lw	t2, LTQ_RCU_RST_STAT(t1)
++	 and	t2, t2, LTQ_RCU_RST_STAT_XTAL_F
++	 beq	t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
++
++boot_35mhz:
++	/* Configure PLL for 35.328 MHz */
++	li	t2, PLL0_35MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL0_CFG(t0)
++	li	t2, PLL1_35MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL1_CFG(t0)
++	li	t2, PLL2_35MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL2_CFG(t0)
++
++	b	do_reset
++
++boot_36mhz:
++	/* Configure PLL for 36 MHz */
++	li	t2, PLL0_36MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL0_CFG(t0)
++	li	t2, PLL1_36MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL1_CFG(t0)
++	li	t2, PLL2_36MHZ_CONFIG
++	sw	t2, LTQ_CGU_PLL2_CFG(t0)
++
++do_reset:
++	/* Store new clock config */
++	sw	t3, LTQ_CGU_SYS(t0)
++
++	/* Perform software reset to activate new clock config */
++	li	t2, LTQ_RCU_RST_REQ_VALUE
++	sw	t2, LTQ_RCU_RST_REQ(t1)
++
++wait_reset:
++	b	wait_reset
++
++finished:
++	jr	ra
++
++	END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/chipid.c
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT	28
++#define LTQ_CHIPID_VERSION_MASK		(0xF << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT		12
++#define LTQ_CHIPID_PNUM_MASK		(0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++	u32	manid;		/* Manufacturer identification */
++	u32	chipid;		/* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++	(struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++	enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++	switch (partnum) {
++	case LTQ_SOC_DANUBE:
++		return "Danube";
++	case LTQ_SOC_DANUBE_S:
++		return "Danube-S";
++	case LTQ_SOC_TWINPASS:
++		return "Twinpass";
++	default:
++		printf("Unknown partnum: %x\n", partnum);
++	}
++
++	return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/config.mk
+@@ -0,0 +1,25 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS		:= -mno-abicalls
++PF_PIC			:= -fno-pic
++PF_PIE			:=
++USE_PRIVATE_LIBGCC	:= yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/ebu.c
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define EBU_ADDRSEL_MASK(mask)		((mask & 0xf) << 4)
++#define EBU_ADDRSEL_REGEN		(1 << 0)
++
++#define EBU_CON_WRDIS			(1 << 31)
++#define EBU_CON_AGEN_DEMUX		(0x0 << 24)
++#define EBU_CON_AGEN_MUX		(0x2 << 24)
++#define EBU_CON_SETUP			(1 << 22)
++#define EBU_CON_WAIT_DIS		(0x0 << 20)
++#define EBU_CON_WAIT_ASYNC		(0x1 << 20)
++#define EBU_CON_WAIT_SYNC		(0x2 << 20)
++#define EBU_CON_WINV			(1 << 19)
++#define EBU_CON_PW_8BIT			(0x0 << 16)
++#define EBU_CON_PW_16BIT		(0x1 << 16)
++#define EBU_CON_ALEC(cycles)		((cycles & 0x3) << 14)
++#define EBU_CON_BCGEN_CS		(0x0 << 12)
++#define EBU_CON_BCGEN_INTEL		(0x1 << 12)
++#define EBU_CON_BCGEN_MOTOROLA		(0x2 << 12)
++#define EBU_CON_WAITWRC(cycles)		((cycles & 0x7) << 8)
++#define EBU_CON_WAITRDC(cycles)		((cycles & 0x3) << 6)
++#define EBU_CON_HOLDC(cycles)		((cycles & 0x3) << 4)
++#define EBU_CON_RECOVC(cycles)		((cycles & 0x3) << 2)
++#define EBU_CON_CMULT_1			0x0
++#define EBU_CON_CMULT_4			0x1
++#define EBU_CON_CMULT_8			0x2
++#define EBU_CON_CMULT_16		0x3
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define ebu_region0_enable		1
++#else
++#define ebu_region0_enable		0
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define ebu_region1_enable		1
++#else
++#define ebu_region1_enable		0
++#endif
++
++struct ltq_ebu_regs {
++	u32	clc;
++	u32	rsvd0[3];
++	u32	con;
++	u32	rsvd1[3];
++	u32	addr_sel_0;
++	u32	addr_sel_1;
++	u32	rsvd2[14];
++	u32	con_0;
++	u32	con_1;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++	(struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++	if (ebu_region0_enable) {
++		/*
++		 * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++		 * region control. This supports up to 32 MiB NOR flash in
++		 * bank 0.
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
++			EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
++
++		ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
++			EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++			EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++			EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++			EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++			EBU_CON_CMULT_16);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
++
++	if (ebu_region1_enable) {
++		/*
++		 * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
++		 * region control. This supports NAND flash in bank 1.
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
++			EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
++
++		ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++			EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
++			EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++			EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
++			EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
++			EBU_CON_CMULT_4);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++	return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem.c
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_dc_read(u32 index)
++{
++	return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++	u32 col, row, dc04, dc19, dc20;
++
++	dc04 = ltq_mc_dc_read(4);
++	dc19 = ltq_mc_dc_read(19);
++	dc20 = ltq_mc_dc_read(20);
++
++	row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
++	col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
++
++	return (1 << (row + col)) * 4 * 2;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/mem_init.S
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_GEN_ERRCAUSE		0x0010
++#define LTQ_MC_GEN_ERRADDR		0x0020
++#define LTQ_MC_GEN_CON			0x0060
++#define LTQ_MC_GEN_STAT			0x0070
++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE	0x5
++#define LTQ_MC_GEN_STAT_DLCK_PWRON	0xC
++
++#define LTQ_MC_DDR_DC03_MC_START	0x100
++
++	/* Store given value in MC DDR CCRx register */
++	.macro dc_sw num, val
++	li	t2, \val
++	sw	t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
++	.endm
++
++LEAF(ltq_mem_init)
++	/* Load MC General and MC DDR module base */
++	li	t0, (LTQ_MC_GEN_BASE | KSEG1)
++	li	t1, (LTQ_MC_DDR_BASE | KSEG1)
++
++	/* Clear access error log registers */
++	sw	zero, LTQ_MC_GEN_ERRCAUSE(t0)
++	sw	zero, LTQ_MC_GEN_ERRADDR(t0)
++
++	/* Enable DDR and SRAM module in memory controller */
++	li	t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
++	sw	t2, LTQ_MC_GEN_CON(t0)
++
++	/* Clear start bit of DDR memory controller */
++	sw	zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++	/* Init memory controller registers with values ddr_settings.h */
++	dc_sw	0, MC_DC00_VALUE
++	dc_sw	1, MC_DC01_VALUE
++	dc_sw	2, MC_DC02_VALUE
++	dc_sw	4, MC_DC04_VALUE
++	dc_sw	5, MC_DC05_VALUE
++	dc_sw	6, MC_DC06_VALUE
++	dc_sw	7, MC_DC07_VALUE
++	dc_sw	8, MC_DC08_VALUE
++	dc_sw	9, MC_DC09_VALUE
++
++	dc_sw	10, MC_DC10_VALUE
++	dc_sw	11, MC_DC11_VALUE
++	dc_sw	12, MC_DC12_VALUE
++	dc_sw	13, MC_DC13_VALUE
++	dc_sw	14, MC_DC14_VALUE
++	dc_sw	15, MC_DC15_VALUE
++	dc_sw	16, MC_DC16_VALUE
++	dc_sw	17, MC_DC17_VALUE
++	dc_sw	18, MC_DC18_VALUE
++	dc_sw	19, MC_DC19_VALUE
++
++	dc_sw	20, MC_DC20_VALUE
++	dc_sw	21, MC_DC21_VALUE
++	dc_sw	22, MC_DC22_VALUE
++	dc_sw	23, MC_DC23_VALUE
++	dc_sw	24, MC_DC24_VALUE
++	dc_sw	25, MC_DC25_VALUE
++	dc_sw	26, MC_DC26_VALUE
++	dc_sw	27, MC_DC27_VALUE
++	dc_sw	28, MC_DC28_VALUE
++	dc_sw	29, MC_DC29_VALUE
++
++	dc_sw	30, MC_DC30_VALUE
++	dc_sw	31, MC_DC31_VALUE
++	dc_sw	32, MC_DC32_VALUE
++	dc_sw	33, MC_DC33_VALUE
++	dc_sw	34, MC_DC34_VALUE
++	dc_sw	35, MC_DC35_VALUE
++	dc_sw	36, MC_DC36_VALUE
++	dc_sw	37, MC_DC37_VALUE
++	dc_sw	38, MC_DC38_VALUE
++	dc_sw	39, MC_DC39_VALUE
++
++	dc_sw	40, MC_DC40_VALUE
++	dc_sw	41, MC_DC41_VALUE
++	dc_sw	42, MC_DC42_VALUE
++	dc_sw	43, MC_DC43_VALUE
++	dc_sw	44, MC_DC44_VALUE
++	dc_sw	45, MC_DC45_VALUE
++	dc_sw	46, MC_DC46_VALUE
++
++	/* Set start bit of DDR memory controller */
++	li	t2, LTQ_MC_DDR_DC03_MC_START
++	sw	t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++	/* Wait until DLL has locked and core is ready for data transfers */
++wait_ready:
++	lw	t2, LTQ_MC_GEN_STAT(t0)
++	li	t3, LTQ_MC_GEN_STAT_DLCK_PWRON
++	and	t2, t3
++	bne	t2, t3, wait_ready
++
++finished:
++	jr	ra
++
++	END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/pmu.c
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED		0xFD0C001C
++
++#define LTQ_PMU_PWDCR_TDM		(1 << 25)
++#define LTQ_PMU_PWDCR_PPE_ENET0		(1 << 23)
++#define LTQ_PMU_PWDCR_PPE_ENET1		(1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC		(1 << 21)
++#define LTQ_PMU_PWDCR_DEU		(1 << 20)
++#define LTQ_PMU_PWDCR_UART1		(1 << 17)
++#define LTQ_PMU_PWDCR_SDIO		(1 << 16)
++#define LTQ_PMU_PWDCR_AHB		(1 << 15)
++#define LTQ_PMU_PWDCR_FPI0		(1 << 14)
++#define LTQ_PMU_PWDCR_PPE		(1 << 13)
++#define LTQ_PMU_PWDCR_GPTC		(1 << 12)
++#define LTQ_PMU_PWDCR_LEDC		(1 << 11)
++#define LTQ_PMU_PWDCR_EBU		(1 << 10)
++#define LTQ_PMU_PWDCR_DSL		(1 << 9)
++#define LTQ_PMU_PWDCR_SPI		(1 << 8)
++#define LTQ_PMU_PWDCR_UART0		(1 << 7)
++#define LTQ_PMU_PWDCR_USB		(1 << 6)
++#define LTQ_PMU_PWDCR_DMA		(1 << 5)
++#define LTQ_PMU_PWDCR_FPI1		(1 << 1)
++#define LTQ_PMU_PWDCR_USB_PHY		(1 << 0)
++
++struct ltq_pmu_regs {
++	u32	rsvd0[7];
++	u32	pwdcr;
++	u32	sr;
++	u32	pwdcr1;
++	u32	sr1;
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++	(struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_PM_CORE:
++		val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
++			LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++		break;
++	case LTQ_PM_DMA:
++		val = LTQ_PMU_PWDCR_DMA;
++		break;
++	case LTQ_PM_ETH:
++		val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
++			LTQ_PMU_PWDCR_PPE;
++		break;
++	case LTQ_PM_SPI:
++		val = LTQ_PMU_PWDCR_SPI;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++	const unsigned long timeout = 1000;
++	unsigned long timebase;
++	u32 sr, val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++	timebase = get_timer(0);
++
++	do {
++		sr = ltq_readl(&ltq_pmu_regs->sr);
++		if (~sr & val)
++			return 0;
++	} while (get_timer(timebase) < timeout);
++
++	return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++	return 0;
++}
++
++void ltq_pmu_init(void)
++{
++	u32 set, clr;
++
++	clr = ltq_pm_map(LTQ_PM_CORE);
++	set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++	ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/danube/rcu.c
+@@ -0,0 +1,125 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_SRST		(1 << 30)	/* Global SW Reset */
++#define LTQ_RCU_RD_MC		(1 << 14)	/* Memory Controller */
++#define LTQ_RCU_RD_PCI		(1 << 13)	/* PCI core */
++#define LTQ_RCU_RD_DFE_AFE	(1 << 12)	/* Voice DFE/AFE */
++#define LTQ_RCU_RD_DSL_AFE	(1 << 11)	/* DSL AFE */
++#define LTQ_RCU_RD_SDIO		(1 << 10)	/* SDIO core */
++#define LTQ_RCU_RD_DMA		(1 << 9)	/* DMA core */
++#define LTQ_RCU_RD_PPE		(1 << 8)	/* PPE core */
++#define LTQ_RCU_RD_ARC_DFE	(1 << 7)	/* ARC/DFE core */
++#define LTQ_RCU_RD_AHB		(1 << 6)	/* AHB bus */
++#define LTQ_RCU_RD_ENET_MAC1	(1 << 5)	/* Ethernet MAC1 */
++#define LTQ_RCU_RD_USB		(1 << 4)	/* USB and Phy core */
++#define LTQ_RCU_RD_CPU1		(1 << 3)	/* CPU1 subsystem */
++#define LTQ_RCU_RD_FPI		(1 << 2)	/* FPI bus */
++#define LTQ_RCU_RD_CPU0		(1 << 1)	/* CPU0 subsystem */
++#define LTQ_RCU_RD_HRST		(1 << 0)	/* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT		18
++#define LTQ_RCU_STAT_BOOT_MASK		(0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
++
++struct ltq_rcu_regs {
++	u32	rsvd0[4];
++	u32	req;		/* Reset request */
++	u32	stat;		/* Reset status */
++	u32	usb_cfg;	/* USB configure */
++	u32	rsvd1[2];
++	u32	pci_rdy;	/* PCI boot ready */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++	(struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_RESET_CORE:
++	case LTQ_RESET_SOFT:
++		val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
++		break;
++	case LTQ_RESET_DMA:
++		val = LTQ_RCU_RD_DMA;
++		break;
++	case LTQ_RESET_ETH:
++		val = LTQ_RCU_RD_PPE;
++		break;
++	case LTQ_RESET_HARD:
++		val = LTQ_RCU_RD_HRST;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++	u32 stat;
++	unsigned int bootstrap;
++
++	stat = ltq_readl(&ltq_rcu_regs->stat);
++	bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
++
++	switch (bootstrap) {
++	case 0:
++		return BOOT_NOR_NO_BOOTROM;
++	case 1:
++		return BOOT_NOR;
++	case 2:
++		return BOOT_MII0;
++	case 3:
++		return BOOT_PCI;
++	case 4:
++		return BOOT_UART;
++	case 5:
++		return BOOT_SPI;
++	case 6:
++		return BOOT_NAND;
++	case 7:
++		return BOOT_RMII0;
++	default:
++		return BOOT_UNKNOWN;
++	}
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
+@@ -0,0 +1,34 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)liblantiq-common.o
++
++START	= start.o
++COBJS-y	= cpu.o pmu.o
++COBJS-$(CONFIG_SPL_BUILD) += spl.o
++SOBJS-y	= lowlevel_init.o
++
++COBJS	:= $(COBJS-y)
++SOBJS	:= $(SOBJS-y)
++SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
++START	:= $(addprefix $(obj),$(START))
++
++all:	$(LIB)
++
++$(LIB):	$(obj).depend $(OBJS)
++	$(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++
++static const char ltq_bootsel_strings[][16] = {
++	"NOR",
++	"NOR w/o BootROM",
++	"UART",
++	"UART w/o EEPROM",
++	"SPI",
++	"NAND",
++	"PCI",
++	"MII0",
++	"RMII0",
++	"RGMII1",
++	"unknown",
++};
++
++const char *ltq_boot_select_str(void)
++{	enum ltq_boot_select bootsel = ltq_boot_select();
++
++	if (bootsel > BOOT_UNKNOWN)
++		bootsel = BOOT_UNKNOWN;
++
++	return ltq_bootsel_strings[bootsel];
++}
++
++void ltq_chip_print_info(void)
++{
++	char buf[32];
++
++	printf("SoC:   Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
++		ltq_chip_version_get());
++	printf("CPU:   %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
++	printf("IO:    %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
++	printf("BUS:   %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
++	printf("BOOT:  %s\n", ltq_boot_select_str());
++}
++
++int arch_cpu_init(void)
++{
++	ltq_pmu_init();
++	ltq_ebu_init();
++
++	return 0;
++}
++
++void _machine_restart(void)
++{
++	ltq_reset_activate(LTQ_RESET_CORE);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
+@@ -0,0 +1,20 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <asm/asm.h>
++#include <asm/regdef.h>
++
++NESTED(lowlevel_init, 0, ra)
++	move	t8, ra
++
++	la	t7, ltq_cgu_init
++	jalr	t7
++
++	la	t7, ltq_mem_init
++	jalr	t7
++
++	jr	t8
++	END(lowlevel_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
+@@ -0,0 +1,9 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/pm.h>
++
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
+@@ -0,0 +1,403 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <image.h>
++#include <version.h>
++#include <spi_flash.h>
++#include <linux/compiler.h>
++#include <lzma/LzmaDec.h>
++#include <linux/lzo.h>
++#include <asm/mipsregs.h>
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define spl_has_console		1
++
++#if defined(CONFIG_LTQ_SPL_DEBUG)
++#define spl_has_debug		1
++#else
++#define spl_has_debug		0
++#endif
++
++#else
++#define spl_has_console		0
++#define spl_has_debug		0
++#endif
++
++#define spl_debug(fmt, args...)			\
++	do {					\
++		if (spl_has_debug)		\
++			printf(fmt, ##args);	\
++	} while (0)
++
++#define spl_puts(msg)				\
++	do {					\
++		if (spl_has_console)		\
++			puts(msg);		\
++	} while (0)
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define spl_boot_spi_flash	1
++#else
++#define spl_boot_spi_flash	0
++#ifndef CONFIG_SPL_SPI_BUS
++#define CONFIG_SPL_SPI_BUS	0
++#endif
++#ifndef CONFIG_SPL_SPI_CS
++#define CONFIG_SPL_SPI_CS	0
++#endif
++#ifndef CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_SPL_SPI_MAX_HZ	0
++#endif
++#ifndef CONFIG_SPL_SPI_MODE
++#define CONFIG_SPL_SPI_MODE	0
++#endif
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define spl_boot_nor_flash	1
++#else
++#define spl_boot_nor_flash	0
++#endif
++
++#define spl_sync()	__asm__ __volatile__("sync");
++
++struct spl_image {
++	ulong data_addr;
++	ulong entry_addr;
++	ulong data_size;
++	ulong entry_size;
++	ulong data_crc;
++	u8 comp;
++};
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/* Emulated malloc area needed for LZMA allocator in BSS */
++static u8 *spl_mem_ptr __maybe_unused;
++static size_t spl_mem_size __maybe_unused;
++
++static int spl_is_comp_lzma(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++	return spl->comp == IH_COMP_LZMA;
++#else
++	return 0;
++#endif
++}
++
++static int spl_is_comp_lzo(const struct spl_image *spl)
++{
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++	return spl->comp == IH_COMP_LZO;
++#else
++	return 0;
++#endif
++}
++
++static int spl_is_compressed(const struct spl_image *spl)
++{
++	if (spl_is_comp_lzma(spl))
++		return 1;
++
++	if (spl_is_comp_lzo(spl))
++		return 1;
++
++	return 0;
++}
++
++static void spl_console_init(void)
++{
++	if (!spl_has_console)
++		return;
++
++	gd->flags |= GD_FLG_RELOC;
++	gd->baudrate = CONFIG_BAUDRATE;
++
++	serial_init();
++
++	gd->have_console = 1;
++
++	spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
++		U_BOOT_TIME ")\n");
++}
++
++static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
++{
++	spl_puts("SPL: checking U-Boot image\n");
++
++	if (!image_check_magic(hdr)) {
++		spl_puts("SPL: invalid magic\n");
++		return -1;
++	}
++
++        if (!image_check_hcrc(hdr)) {
++		spl_puts("SPL: invalid header CRC\n");
++		return -1;
++	}
++
++	spl->data_addr += image_get_header_size();
++	spl->entry_addr = image_get_load(hdr);
++	spl->data_size = image_get_data_size(hdr);
++	spl->data_crc = image_get_dcrc(hdr);
++	spl->comp = image_get_comp(hdr);
++
++	spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n",
++		spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
++
++	return 0;
++}
++
++static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
++{
++	ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
++
++	if (dcrc != spl->data_crc) {
++		spl_puts("SPL: invalid data CRC\n");
++		return 0;
++	}
++
++	return 1;
++}
++
++static void *spl_lzma_alloc(void *p, size_t size)
++{
++	u8 *ret;
++
++	if (size > spl_mem_size)
++		return NULL;
++
++	ret = spl_mem_ptr;
++	spl_mem_ptr += size;
++	spl_mem_size -= size;
++
++	return ret;
++}
++
++static void spl_lzma_free(void *p, void *addr)
++{
++}
++
++static int spl_copy_image(struct spl_image *spl)
++{
++	spl_puts("SPL: copying U-Boot to RAM\n");
++
++	memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
++		spl->data_size);
++
++	spl->entry_size = spl->data_size;
++
++	return 0;
++}
++
++static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
++{
++	SRes res;
++	const Byte *prop = (const Byte *) loadaddr;
++	const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
++							sizeof(uint64_t);
++	Byte *dest = (Byte *) spl->entry_addr;
++	SizeT dest_len = 0xFFFFFFFF;
++	SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
++	ELzmaStatus status = 0;
++	ISzAlloc alloc;
++
++	spl_puts("SPL: decompressing U-Boot with LZMA\n");
++
++	alloc.Alloc = spl_lzma_alloc;
++	alloc.Free = spl_lzma_free;
++	spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
++	spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
++
++	res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
++		LZMA_FINISH_ANY, &status, &alloc);
++	if (res != SZ_OK)
++		return 1;
++
++	spl->entry_size = dest_len;
++
++	return 0;
++}
++
++static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
++{
++	size_t len = CONFIG_SYS_LOAD_SIZE;
++	int ret;
++
++	spl_puts("SPL: decompressing U-Boot with LZO\n");
++
++	ret = lzop_decompress(
++		(const unsigned char*) loadaddr, spl->data_size,
++		(unsigned char *) spl->entry_addr, &len);
++
++	spl->entry_size = len;
++
++	return ret;
++}
++
++static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
++{
++	int ret;
++
++	if (spl_is_comp_lzma(spl))
++		ret = spl_uncompress_lzma(spl, loadaddr);
++	else if (spl_is_comp_lzo(spl))
++		ret = spl_uncompress_lzo(spl, loadaddr);
++	else
++		ret = 1;
++
++	return ret;
++}
++
++static int spl_load_spi_flash(struct spl_image *spl)
++{
++	struct spi_flash sf = { 0 };
++	image_header_t hdr;
++	int ret;
++	unsigned long loadaddr;
++
++	/*
++	 * Image format:
++	 *
++	 * - 12 byte non-volatile bootstrap header
++	 * - SPL binary
++	 * - 12 byte non-volatile bootstrap header
++	 * - 64 byte U-Boot mkimage header
++	 * - U-Boot binary
++	 */
++	spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
++
++	spl_puts("SPL: probing SPI flash\n");
++
++	spi_init();
++	ret = spl_spi_flash_probe(&sf);
++	if (ret)
++		return ret;
++
++	spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
++
++	ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
++	if (ret)
++		return ret;
++
++	spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
++
++	ret = spl_parse_image(&hdr, spl);
++	if (ret)
++		return ret;
++
++	if (spl_is_compressed(spl))
++		loadaddr = CONFIG_LOADADDR;
++	else
++		loadaddr = spl->entry_addr;
++
++	spl_puts("SPL: loading U-Boot to RAM\n");
++
++	ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
++				(void *) loadaddr);
++
++	if (!spl_check_data(spl, loadaddr))
++		return -1;
++
++	if (spl_is_compressed(spl))
++		ret = spl_uncompress(spl, loadaddr);
++
++	return ret;
++}
++
++static int spl_load_nor_flash(struct spl_image *spl)
++{
++	const image_header_t *hdr;
++	int ret;
++
++	/*
++	 * Image format:
++	 *
++	 * - SPL binary
++	 * - 64 byte U-Boot mkimage header
++	 * - U-Boot binary
++	 */
++	spl->data_addr = image_copy_end();
++	hdr = (const image_header_t *) image_copy_end();
++
++	spl_debug("SPL: checking image header at address %p\n", hdr);
++
++	ret = spl_parse_image(hdr, spl);
++	if (ret)
++		return ret;
++
++	if (spl_is_compressed(spl))
++		ret = spl_uncompress(spl, spl->data_addr);
++	else
++		ret = spl_copy_image(spl);
++
++	return ret;
++}
++
++static int spl_load(struct spl_image *spl)
++{
++	int ret;
++
++	if (spl_boot_spi_flash)
++		ret = spl_load_spi_flash(spl);
++	else if (spl_boot_nor_flash)
++		ret = spl_load_nor_flash(spl);
++	else
++		ret = 1;
++
++	return ret;
++}
++
++void __noreturn spl_lantiq_init(void)
++{
++	void (*uboot)(void) __noreturn;
++	struct spl_image spl;
++	gd_t gd_data;
++	int ret;
++
++	gd = &gd_data;
++	barrier();
++	memset((void *)gd, 0, sizeof(gd_t));
++
++	spl_console_init();
++
++	spl_debug("SPL: initializing\n");
++
++#if 0
++	spl_debug("CP0_CONFIG:   %08x\n", read_c0_config());
++	spl_debug("CP0_CONFIG1:  %08x\n", read_c0_config1());
++	spl_debug("CP0_CONFIG2:  %08x\n", read_c0_config2());
++	spl_debug("CP0_CONFIG3:  %08x\n", read_c0_config3());
++	spl_debug("CP0_CONFIG6:  %08x\n", read_c0_config6());
++	spl_debug("CP0_CONFIG7:  %08x\n", read_c0_config7());
++	spl_debug("CP0_STATUS:   %08x\n", read_c0_status());
++	spl_debug("CP0_PRID:     %08x\n", read_c0_prid());
++#endif
++
++	board_early_init_f();
++	timer_init();
++
++	memset(&spl, 0, sizeof(spl));
++
++	ret = spl_load(&spl);
++	if (ret)
++		goto hang;
++
++	spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
++	spl_puts("SPL: jumping to U-Boot\n");
++
++	flush_cache(spl.entry_addr, spl.entry_size);
++	spl_sync();
++
++	uboot = (void *) spl.entry_addr;
++	uboot();
++
++hang:
++	spl_puts("SPL: cannot start U-Boot\n");
++
++	for (;;)
++		;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/start.S
+@@ -0,0 +1,143 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/regdef.h>
++#include <asm/mipsregs.h>
++
++#define S_PRIdCoID	16		/* Company ID (R) */
++#define M_PRIdCoID	(0xff << S_PRIdCoID)
++#define S_PRIdImp	8		/* Implementation ID (R) */
++#define M_PRIdImp	(0xff << S_PRIdImp)
++
++#define K_CacheAttrCWTnWA	0	/* Cacheable, write-thru, no write allocate */
++#define K_CacheAttrCWTWA	1	/* Cacheable, write-thru, write allocate */
++#define K_CacheAttrU		2	/* Uncached */
++#define K_CacheAttrC		3	/* Cacheable */
++#define K_CacheAttrCN		3	/* Cacheable, non-coherent */
++#define K_CacheAttrCCE		4	/* Cacheable, coherent, exclusive */
++#define K_CacheAttrCCS		5	/* Cacheable, coherent, shared */
++#define K_CacheAttrCCU		6	/* Cacheable, coherent, update */
++#define K_CacheAttrUA		7	/* Uncached accelerated */
++
++#define S_ConfigK23		28	/* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigK23		(0x7 << S_ConfigK23)
++#define W_ConfigK23		3
++#define S_ConfigKU		25	/* Kuseg coherency algorithm (FM MMU only) (R/W) */
++#define M_ConfigKU		(0x7 << S_ConfigKU)
++#define W_ConfigKU		3
++
++#define S_ConfigMM		18	/* Merge mode (implementation specific) */
++#define M_ConfigMM		(0x1 << S_ConfigMM)
++
++#define S_StatusBEV		22	/* Enable Boot Exception Vectors (R/W) */
++#define M_StatusBEV		(0x1 << S_StatusBEV)
++
++#define S_StatusFR		26	/* Enable 64-bit FPRs (R/W) */
++#define M_StatusFR		(0x1 << S_StatusFR)
++
++#define S_ConfigK0		0	/* Kseg0 coherency algorithm (R/W) */
++#define M_ConfigK0		(0x7 << S_ConfigK0)
++
++#define CONFIG0_MIPS32_64_MSK	0x8000ffff
++#define STATUS_MIPS32_64_MSK	0xfffcffff
++
++#define STATUS_MIPS24K		0
++#define CONFIG0_MIPS24K		((K_CacheAttrCN << S_ConfigK23) |\
++				(K_CacheAttrCN << S_ConfigKU)  |\
++				(M_ConfigMM))
++
++#define STATUS_MIPS34K		0
++#define CONFIG0_MIPS34K		((K_CacheAttrCN << S_ConfigK23) |\
++				(K_CacheAttrCN << S_ConfigKU) |\
++				(M_ConfigMM))
++
++#define STATUS_MIPS32_64	(M_StatusBEV | M_StatusFR)
++#define CONFIG0_MIPS32_64	(K_CacheAttrCN << S_ConfigK0)
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++#define CONFIG0_LANTIQ		(CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ		(STATUS_MIPS24K | STATUS_MIPS32_64)
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++#define CONFIG0_LANTIQ		(CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ		(STATUS_MIPS34K | STATUS_MIPS32_64)
++#endif
++
++
++	.set noreorder
++
++	.globl _start
++	.text
++_start:
++	/* Entry point */
++	b	main
++	 nop
++
++	/* Lantiq SoC Boot config word */
++	.org	0x10
++#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
++	.word	CONFIG_SYS_XWAY_EBU_BOOTCFG
++#else
++	.word	0
++#endif
++	.word	0
++
++	.align	4
++main:
++
++	/* Init Timer */
++	mtc0	zero, CP0_COUNT
++	mtc0	zero, CP0_COMPARE
++
++	/* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
++	mfc0	t0, CP0_CONFIG
++	li	t1, CONFIG0_MIPS32_64_MSK
++	and	t0, t1
++	li	t1, CONFIG0_LANTIQ
++	or	t0, t1
++	mtc0	t0, CP0_CONFIG
++
++	mfc0	t0, CP0_STATUS
++	li	t1, STATUS_MIPS32_64_MSK
++	and	t0, t1
++	li	t1, STATUS_LANTIQ
++	or	t0, t1
++	mtc0	t0, CP0_STATUS
++
++	/* Initialize CGU */
++	la	t9, ltq_cgu_init
++	jalr	t9
++	 nop
++
++	/* Initialize memory controller */
++	la	t9, ltq_mem_init
++	jalr	t9
++	 nop
++
++	/* Initialize caches... */
++	la	t9, mips_cache_reset
++	jalr	t9
++	 nop
++
++	/* Clear BSS */
++	la	t1, __bss_start
++	la	t2, __bss_end
++	sub	t1, 4
++1:
++	addi	t1, 4
++	bltl	t1, t2, 1b
++	 sw	zero, 0(t1)
++
++	/* Setup stack pointer and force alignment on a 16 byte boundary */
++	li	t0, (CONFIG_SPL_STACK_BASE & ~0xF)
++	la	sp, 0(t0)
++
++	la	t9, spl_lantiq_init
++	jr	t9
++	 nop
+--- /dev/null
++++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
++		LENGTH = CONFIG_SPL_MAX_SIZE }
++MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
++		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
++
++OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
++OUTPUT_ARCH(mips)
++ENTRY(_start)
++SECTIONS
++{
++	. = ALIGN(4);
++	.text : {
++		*(.text*)
++	} > .spl_mem
++
++	. = ALIGN(4);
++	.rodata : {
++		*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
++	} > .spl_mem
++
++	. = ALIGN(4);
++	.data : {
++		*(SORT_BY_ALIGNMENT(.data*))
++		*(SORT_BY_ALIGNMENT(.sdata*))
++	} > .spl_mem
++
++	. = ALIGN(4);
++	__image_copy_end = .;
++	uboot_end_data = .;
++
++	.bss : {
++		__bss_start = .;
++		*(.bss*)
++		*(.sbss*)
++		. = ALIGN(4);
++		__bss_end = .;
++	} > .bss_mem
++
++	. = ALIGN(4);
++	__end = .;
++	uboot_end = .;
++}
+--- a/arch/mips/cpu/mips32/start.S
++++ b/arch/mips/cpu/mips32/start.S
+@@ -105,7 +105,7 @@ reset:
+ 	mtc0	zero, CP0_COUNT
+ 	mtc0	zero, CP0_COMPARE
+ 
+-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
++#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
+ 	/* CONFIG0 register */
+ 	li	t0, CONF_CM_UNCACHED
+ 	mtc0	t0, CP0_CONFIG
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/Makefile
+@@ -0,0 +1,32 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(SOC).o
++
++COBJS-y	+= cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
++SOBJS-y	+= cgu_init.o mem_init.o
++SOBJS-y	+= gphy_fw.o
++
++COBJS	:= $(COBJS-y)
++SOBJS	:= $(SOBJS-y)
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all:	$(LIB)
++
++$(LIB):	$(obj).depend $(OBJS)
++	$(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu.c
+@@ -0,0 +1,208 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CGU_PLL1_PLLN_SHIFT		6
++#define LTQ_CGU_PLL1_PLLN_MASK		(0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
++#define LTQ_CGU_PLL1_PLLM_SHIFT		2
++#define LTQ_CGU_PLL1_PLLM_MASK		(0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
++#define LTQ_CGU_PLL1_PLLL		(1 << 1)
++#define LTQ_CGU_PLL1_PLL_EN		1
++
++#define LTQ_CGU_SYS_OCP_SHIFT		0
++#define LTQ_CGU_SYS_OCP_MASK		(0x3 << LTQ_CGU_SYS_OCP_SHIFT)
++#define LTQ_CGU_SYS_CPU_SHIFT		4
++#define LTQ_CGU_SYS_CPU_MASK		(0xF << LTQ_CGU_SYS_CPU_SHIFT)
++
++#define LTQ_CGU_UPDATE			1
++
++#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT	2
++#define LTQ_CGU_IFCLK_GPHY_SEL_MASK	(0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
++
++struct ltq_cgu_regs {
++	u32	rsvd0;
++	u32	pll0_cfg;	/* PLL0 config */
++	u32	pll1_cfg;	/* PLL1 config */
++	u32	sys;		/* System clock */
++	u32	clk_fsr;	/* Clock frequency select */
++	u32	clk_gsr;	/* Clock gating status */
++	u32	clk_gcr0;	/* Clock gating control 0 */
++	u32	clk_gcr1;	/* Clock gating control 1 */
++	u32	update;		/* CGU update control */
++	u32	if_clk;		/* Interface clock */
++	u32	ddr;		/* DDR memory control */
++	u32	ct1_sr;		/* CT status 1 */
++	u32	ct_kval;	/* CT K value */
++	u32	pcm_cr;		/* PCM control */
++	u32	pci_cr;		/* PCI clock control */
++	u32	rsvd1;
++	u32	gphy1_cfg;	/* GPHY1 config */
++	u32	gphy0_cfg;	/* GPHY0 config */
++	u32	rsvd2[6];
++	u32	pll2_cfg;	/* PLL2 config */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++	(struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++	return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++	unsigned int ocp_sel;
++	unsigned long clk, cpu_clk;
++
++	cpu_clk = ltq_get_cpu_clock();
++
++	ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
++			LTQ_CGU_SYS_OCP_SHIFT);
++
++	switch (ocp_sel) {
++	case 0:
++		/* OCP ratio 1 */
++		clk = cpu_clk;
++		break;
++	case 2:
++		/* OCP ratio 2 */
++		clk = cpu_clk / 2;
++		break;
++	case 3:
++		/* OCP ratio 2.5 */
++		clk = (cpu_clk * 2) / 5;
++		break;
++	case 4:
++		/* OCP ratio 3 */
++		clk = cpu_clk / 3;
++		break;
++	default:
++		clk = 0;
++		break;
++	}
++
++	return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++	unsigned int cpu_sel;
++	unsigned long clk;
++
++	cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
++			LTQ_CGU_SYS_CPU_SHIFT);
++
++	switch (cpu_sel) {
++	case 0:
++		clk = CLOCK_600_MHZ;
++		break;
++	case 1:
++		clk = CLOCK_500_MHZ;
++		break;
++	case 2:
++		clk = CLOCK_393_MHZ;
++		break;
++	case 3:
++		clk = CLOCK_333_MHZ;
++		break;
++	case 5:
++	case 6:
++		clk = CLOCK_197_MHZ;
++		break;
++	case 7:
++		clk = CLOCK_166_MHZ;
++		break;
++	case 4:
++	case 8:
++	case 9:
++		clk = CLOCK_125_MHZ;
++		break;
++	default:
++		clk = 0;
++		break;
++	}
++
++	return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++	return ltq_get_io_region_clock();
++}
++
++void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
++{
++	ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
++	ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
++}
++
++static inline int ltq_cgu_pll1_locked(void)
++{
++	u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++
++	return pll1_cfg & LTQ_CGU_PLL1_PLLL;
++}
++
++static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
++{
++	u32 pll1_cfg;
++
++	ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
++	ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++	pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
++	pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
++	pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
++	pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
++	pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
++	ltq_writel(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
++	ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
++
++	__udelay(1000);
++}
++
++/*
++ * From chapter 9 in errata sheet:
++ *
++ * Under certain condition, the PLL1 may failed to enter into lock
++ * status by hardware default N, M setting.
++ *
++ * Since system always starts from PLL0, the system software can run
++ * and re-program the PLL1 settings.
++ */
++static void ltq_cgu_pll1_init(void)
++{
++	unsigned i;
++	const unsigned pll1_m[] = { 1, 2, 3, 4 };
++	const unsigned pll1_n[] = { 21, 32, 43, 54 };
++
++	/* Check if PLL1 has locked with hardware default settings */
++	if (ltq_cgu_pll1_locked())
++		return;
++
++	for (i = 0; i < 4; i++) {
++		ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
++
++		if (ltq_cgu_pll1_locked())
++			goto done;
++	}
++
++done:
++	/* Restart with hardware default values M=5, N=64 */
++	ltq_cgu_pll1_restart(5, 64);
++}
++
++void ltq_pll_init(void)
++{
++	ltq_cgu_pll1_init();
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
+@@ -0,0 +1,119 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* RCU module register */
++#define LTQ_RCU_RST_REQ			0x0010	/* Reset request */
++#define LTQ_RCU_RST_REQ_VALUE		((1 << 14) | (1 << 1))
++
++/* CGU module register */
++#define LTQ_CGU_PLL0_CFG		0x0004	/* PLL0 config */
++#define LTQ_CGU_PLL1_CFG		0x0008	/* PLL1 config */
++#define LTQ_CGU_PLL2_CFG		0x0060	/* PLL2 config */
++#define LTQ_CGU_SYS			0x000C	/* System clock */
++#define LTQ_CGU_CLK_FSR			0x0010	/* Clock frequency select */
++#define LTQ_CGU_UPDATE			0x0020	/* Clock update control */
++
++/* Valid SYS.CPU values */
++#define LTQ_CGU_SYS_CPU_SHIFT		4
++#define LTQ_CGU_SYS_CPU_600_MHZ		0x0
++#define LTQ_CGU_SYS_CPU_500_MHZ		0x1
++#define LTQ_CGU_SYS_CPU_393_MHZ		0x2
++#define LTQ_CGU_SYS_CPU_333_MHZ		0x3
++#define LTQ_CGU_SYS_CPU_197_MHZ		0x5
++#define LTQ_CGU_SYS_CPU_166_MHZ		0x7
++#define LTQ_CGU_SYS_CPU_125_MHZ		0x9
++
++/* Valid SYS.OCP values */
++#define LTQ_CGU_SYS_OCP_SHIFT		0
++#define LTQ_CGU_SYS_OCP_1		0x0
++#define LTQ_CGU_SYS_OCP_2		0x2
++#define LTQ_CGU_SYS_OCP_2_5		0x3
++#define LTQ_CGU_SYS_OCP_3		0x4
++
++/* Valid CLK_FSR.ETH values */
++#define LTQ_CGU_CLK_FSR_ETH_SHIFT	24
++#define LTQ_CGU_CLK_FSR_ETH_50_MHZ	0x0
++#define LTQ_CGU_CLK_FSR_ETH_25_MHZ	0x1
++#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ	0x2
++#define LTQ_CGU_CLK_FSR_ETH_125_MHZ	0x3
++
++/* Valid CLK_FSR.PPE values */
++#define LTQ_CGU_CLK_FSR_PPE_SHIFT	16
++#define LTQ_CGU_CLK_FSR_PPE_500_MHZ	0x0	/* Overclock frequency */
++#define LTQ_CGU_CLK_FSR_PPE_450_MHZ	0x1	/* High frequency */
++#define LTQ_CGU_CLK_FSR_PPE_400_MHZ	0x2	/* Low frequency */
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
++#define LTQ_CGU_SYS_CPU_CONFIG		LTQ_CGU_SYS_CPU_500_MHZ
++#define LTQ_CGU_SYS_OCP_CONFIG		LTQ_CGU_SYS_OCP_2
++#define LTQ_CGU_CLK_FSR_ETH_CONFIG	LTQ_CGU_CLK_FSR_ETH_125_MHZ
++#define LTQ_CGU_CLK_FSR_PPE_CONFIG	LTQ_CGU_CLK_FSR_PPE_450_MHZ
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define LTQ_CGU_SYS_VALUE	((LTQ_CGU_SYS_CPU_CONFIG << \
++					LTQ_CGU_SYS_CPU_SHIFT) | \
++					LTQ_CGU_SYS_OCP_CONFIG)
++
++#define LTQ_CGU_CLK_FSR_VALUE	((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
++					LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
++				(LTQ_CGU_CLK_FSR_PPE_CONFIG << \
++					LTQ_CGU_CLK_FSR_PPE_SHIFT))
++
++	.set noreorder
++
++LEAF(ltq_cgu_init)
++	/* Load current CGU register values */
++	li	t0, (LTQ_CGU_BASE | KSEG1)
++	lw	t1, LTQ_CGU_SYS(t0)
++	lw	t2, LTQ_CGU_CLK_FSR(t0)
++
++	/* Load target CGU register values */
++	li	t3, LTQ_CGU_SYS_VALUE
++	li	t4, LTQ_CGU_CLK_FSR_VALUE
++
++	/* Only update registers if values differ */
++	bne	t1, t3, update
++	 nop
++	beq	t2, t4, finished
++	 nop
++
++update:
++	/* Store target register values */
++	sw	t3, LTQ_CGU_SYS(t0)
++	sw	t4, LTQ_CGU_CLK_FSR(t0)
++
++	/* Perform software reset to activate new clock config */
++#if 0
++	li	t0, (LTQ_RCU_BASE | KSEG1)
++	lw	t1, LTQ_RCU_RST_REQ(t0)
++	or	t1, LTQ_RCU_RST_REQ_VALUE
++	sw	t1, LTQ_RCU_RST_REQ(t0)
++#else
++	li	t1, 1
++	sw	t1, LTQ_CGU_UPDATE(t0)
++#endif
++
++#if 0
++wait_reset:
++	b	wait_reset
++	 nop
++#endif
++
++finished:
++	jr	ra
++	 nop
++
++	END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/chipid.c
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT	28
++#define LTQ_CHIPID_VERSION_MASK		(0x7 << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT		12
++#define LTQ_CHIPID_PNUM_MASK		(0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++	u32	manid;		/* Manufacturer identification */
++	u32	chipid;		/* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++	(struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++	enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++	switch (partnum) {
++	case LTQ_SOC_VRX268:
++	case LTQ_SOC_VRX268_2:
++		return "VRX268";
++	case LTQ_SOC_VRX288:
++	case LTQ_SOC_VRX288_2:
++		return "VRX288";
++	case LTQ_SOC_GRX288:
++	case LTQ_SOC_GRX288_2:
++		return "GRX288";
++	default:
++		printf("Unknown partnum: %x\n", partnum);
++	}
++
++	return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -0,0 +1,30 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS		:= -mno-abicalls
++PF_PIC			:= -fno-pic
++PF_PIE			:=
++USE_PRIVATE_LIBGCC	:= yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_SFSPL
++ALL-y += $(obj)u-boot.ltq.sfspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
++endif
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_DCDC_CLK_SET0_CLK_SEL_P		(1 << 6)
++#define LTQ_DCDC_CLK_SET1_SEL_DIV25		(1 << 5)
++#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE	(1 << 5)
++
++struct ltq_dcdc_regs {
++	u8	b0_coeh;		/* Coefficient b0 */
++	u8	b0_coel;		/* Coefficient b0 */
++	u8	b1_coeh;		/* Coefficient b1 */
++	u8	b1_coel;		/* Coefficient b1 */
++	u8	b2_coeh;		/* Coefficient b2 */
++	u8	b2_coel;		/* Coefficient b2 */
++	u8	clk_set0;		/* Clock setup */
++	u8	clk_set1;		/* Clock setup */
++	u8	pwm_confh;		/* Configure PWM */
++	u8	pwm_confl;		/* Configure PWM */
++	u8	bias_vreg0;		/* Bias and regulator setup */
++	u8	bias_vreg1;		/* Bias and regulator setup */
++	u8	adc_gen0;		/* ADC and general control */
++	u8	adc_gen1;		/* ADC and general control */
++	u8	adc_con0;		/* ADC and general config */
++	u8	adc_con1;		/* ADC and general config */
++	u8	conf_test_ana;		/* not documented */
++	u8	conf_test_dig;		/* not documented */
++	u8	dcdc_status;		/* not documented */
++	u8	pid_status;		/* not documented */
++	u8	duty_cycle;		/* not documented */
++	u8	non_ov_delay;		/* not documented */
++	u8	analog_gain;		/* not documented */
++	u8	duty_cycle_max_sat;	/* not documented */
++	u8	duty_cycle_min_sat;	/* not documented */
++	u8	duty_cycle_max;		/* not documented */
++	u8	duty_cycle_min;		/* not documented */
++	u8	error_max;		/* not documented */
++	u8	error_read;		/* not documented */
++	u8	delay_deglitch;		/* not documented */
++	u8	latch_control;		/* not documented */
++	u8	rsvd[240];
++	u8	osc_conf;		/* OSC general config */
++	u8	osc_stat;		/* OSC general status */
++};
++
++static struct ltq_dcdc_regs *ltq_dcdc_regs =
++	(struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
++
++void ltq_dcdc_init(unsigned int dig_ref)
++{
++	u8 dig_ref_cur, val;
++
++	/* Set duty cycle max sat. to 70/90, enable PID freeze */
++	ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
++	ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
++	val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++	val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++	ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++	/* Program new coefficients */
++	ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
++	ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
++	ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
++	ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
++	ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
++	ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
++	ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
++
++	/* Set duty cycle max sat. to 60/108, disable PID freeze */
++	ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
++	ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
++	val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
++	val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
++	ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
++
++	/* Init clock and DLL settings */
++	val = ltq_readb(&ltq_dcdc_regs->clk_set0);
++	val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
++	ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
++	val = ltq_readb(&ltq_dcdc_regs->clk_set1);
++	val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
++	ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
++	ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
++
++	wmb();
++
++	/* Adapt value of digital reference of DCDC converter */
++	dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
++
++	while (dig_ref_cur != dig_ref) {
++		if (dig_ref >= dig_ref_cur)
++			dig_ref_cur++;
++		else if (dig_ref < dig_ref_cur)
++			dig_ref_cur--;
++
++		ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
++		__udelay(1000);
++	}
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/ebu.c
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define EBU_ADDRSEL_MASK(mask)		((mask & 0xf) << 4)
++#define EBU_ADDRSEL_REGEN		(1 << 0)
++
++#define EBU_CON_WRDIS			(1 << 31)
++#define EBU_CON_AGEN_DEMUX		(0x0 << 24)
++#define EBU_CON_AGEN_MUX		(0x2 << 24)
++#define EBU_CON_SETUP			(1 << 22)
++#define EBU_CON_WAIT_DIS		(0x0 << 20)
++#define EBU_CON_WAIT_ASYNC		(0x1 << 20)
++#define EBU_CON_WAIT_SYNC		(0x2 << 20)
++#define EBU_CON_WINV			(1 << 19)
++#define EBU_CON_PW_8BIT			(0x0 << 16)
++#define EBU_CON_PW_16BIT		(0x1 << 16)
++#define EBU_CON_ALEC(cycles)		((cycles & 0x3) << 14)
++#define EBU_CON_BCGEN_CS		(0x0 << 12)
++#define EBU_CON_BCGEN_INTEL		(0x1 << 12)
++#define EBU_CON_BCGEN_MOTOROLA		(0x2 << 12)
++#define EBU_CON_WAITWRC(cycles)		((cycles & 0x7) << 8)
++#define EBU_CON_WAITRDC(cycles)		((cycles & 0x3) << 6)
++#define EBU_CON_HOLDC(cycles)		((cycles & 0x3) << 4)
++#define EBU_CON_RECOVC(cycles)		((cycles & 0x3) << 2)
++#define EBU_CON_CMULT_1			0x0
++#define EBU_CON_CMULT_4			0x1
++#define EBU_CON_CMULT_8			0x2
++#define EBU_CON_CMULT_16		0x3
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define ebu_region0_enable		1
++#else
++#define ebu_region0_enable		0
++#endif
++
++#if ((CONFIG_SYS_MAX_FLASH_BANKS == 2) && defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) )
++#define ebu_region0_addrsel_mask	3
++#else
++#define ebu_region0_addrsel_mask	1
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH) || ((CONFIG_SYS_MAX_FLASH_BANKS == 2) && defined(CONFIG_LTQ_SUPPORT_NOR_FLASH) )
++#define ebu_region1_enable		1
++#else
++#define ebu_region1_enable		0
++#endif
++
++struct ltq_ebu_regs {
++	u32	clc;
++	u32	rsvd0;
++	u32	id;
++	u32	rsvd1;
++	u32	con;
++	u32	rsvd2[3];
++	u32	addr_sel_0;
++	u32	addr_sel_1;
++	u32	addr_sel_2;
++	u32	addr_sel_3;
++	u32	rsvd3[12];
++	u32	con_0;
++	u32	con_1;
++	u32	con_2;
++	u32	con_3;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++	(struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++	if (ebu_region0_enable) {
++		/*
++		 * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++		 * region control. This supports up to 32 MiB NOR flash in
++		 * bank 0.
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
++			EBU_ADDRSEL_MASK(ebu_region0_addrsel_mask) | EBU_ADDRSEL_REGEN);
++
++		ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
++			EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++			EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++			EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++			EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++			EBU_CON_CMULT_16);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
++
++	if (ebu_region1_enable) {
++		/*
++		 * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
++		 * region control. This supports NAND flash in bank 1. (and  NOR flash in bank 2)
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
++			EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
++
++		if (ebu_region0_addrsel_mask == 1)
++			ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++				EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
++				EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++				EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
++				EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
++				EBU_CON_CMULT_4);
++
++		if (ebu_region0_addrsel_mask == 3)
++			ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++				EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++				EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++				EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++				EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++				EBU_CON_CMULT_16);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++	return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy.c
+@@ -0,0 +1,68 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gphy.h>
++#include <lzma/LzmaTypes.h>
++#include <lzma/LzmaDec.h>
++#include <lzma/LzmaTools.h>
++
++static inline void ltq_gphy_decompress(const void *fw_start, const void *fw_end,
++				ulong dst_addr)
++{
++	const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
++	const ulong addr = CKSEG1ADDR(dst_addr);
++
++	debug("ltq_gphy_decompress: addr %08lx, fw_start %p, fw_end %p\n",
++		addr, fw_start, fw_end);
++
++	SizeT lzma_len = 65536;
++	int ret = lzmaBuffToBuffDecompress(
++	(unsigned char *)addr, &lzma_len,
++	(unsigned char *)fw_start, fw_len);
++}
++
++void ltq_gphy_phy11g_a1x_load(ulong addr)
++{
++	extern ulong __ltq_fw_phy11g_a1x_start;
++	extern ulong __ltq_fw_phy11g_a1x_end;
++
++	ltq_gphy_decompress(&__ltq_fw_phy11g_a1x_start,
++			    &__ltq_fw_phy11g_a1x_end,
++			    addr);
++}
++
++void ltq_gphy_phy11g_a2x_load(ulong addr)
++{
++	extern ulong __ltq_fw_phy11g_a2x_start;
++	extern ulong __ltq_fw_phy11g_a2x_end;
++
++	ltq_gphy_decompress(&__ltq_fw_phy11g_a2x_start,
++			    &__ltq_fw_phy11g_a2x_end,
++			    addr);
++}
++
++void ltq_gphy_phy22f_a1x_load(ulong addr)
++{
++	extern ulong __ltq_fw_phy22f_a1x_start;
++	extern ulong __ltq_fw_phy22f_a1x_end;
++
++	ltq_gphy_decompress(&__ltq_fw_phy22f_a1x_start,
++			    &__ltq_fw_phy22f_a1x_end,
++			    addr);
++}
++
++void ltq_gphy_phy22f_a2x_load(ulong addr)
++{
++	extern ulong __ltq_fw_phy22f_a2x_start;
++	extern ulong __ltq_fw_phy22f_a2x_end;
++
++	ltq_gphy_decompress(&__ltq_fw_phy22f_a2x_start,
++			    &__ltq_fw_phy22f_a2x_end,
++			    addr);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <asm/asm.h>
++
++	.section .rodata.__ltq_fw_phy11g_a1x
++EXPORT(__ltq_fw_phy11g_a1x_start)
++	.incbin "fw_phy11g_a1x.blob"
++EXPORT(__ltq_fw_phy11g_a1x_end)
++
++	.section .rodata.__ltq_fw_phy11g_a2x
++EXPORT(__ltq_fw_phy11g_a2x_start)
++	.incbin "fw_phy11g_a2x.blob"
++EXPORT(__ltq_fw_phy11g_a2x_end)
++
++	.section .rodata.__ltq_fw_phy22f_a1x
++EXPORT(__ltq_fw_phy22f_a1x_start)
++	.incbin "fw_phy22f_a1x.blob"
++EXPORT(__ltq_fw_phy22f_a1x_end)
++
++	.section .rodata.__ltq_fw_phy22f_a2x
++EXPORT(__ltq_fw_phy22f_a2x_start)
++	.incbin "fw_phy22f_a2x.blob"
++EXPORT(__ltq_fw_phy22f_a2x_end)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem.c
+@@ -0,0 +1,57 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define LTQ_CCR03_EIGHT_BANK_MODE	(1 << 0)
++#define LTQ_CCR08_CS_MAP_SHIFT		24
++#define LTQ_CCR08_CS_MAP_MASK		(0x3 << LTQ_CCR08_CS_MAP_SHIFT)
++#define LTQ_CCR11_COLUMN_SIZE_SHIFT	24
++#define LTQ_CCR11_COLUMN_SIZE_MASK	(0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
++#define LTQ_CCR11_ADDR_PINS_MASK	0x7
++#define LTQ_CCR15_MAX_COL_REG_SHIFT	24
++#define LTQ_CCR15_MAX_COL_REG_MASK	(0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
++#define LTQ_CCR16_MAX_ROW_REG_MASK	0xF
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_ccr_read(u32 index)
++{
++	return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++	u32 max_col_reg, max_row_reg, column_size, addr_pins;
++	u32 banks, cs_map;
++	phys_size_t size;
++
++	banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
++
++	cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
++		LTQ_CCR08_CS_MAP_SHIFT;
++
++	column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
++		LTQ_CCR11_COLUMN_SIZE_SHIFT;
++
++	addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
++
++	max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
++		LTQ_CCR15_MAX_COL_REG_SHIFT;
++
++	max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
++
++	/*
++	 * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
++	 *                 * datawidth (bytes)
++	 */
++	size = (2 << (max_col_reg - column_size - 1)) *
++		(2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
++
++	return size;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
+@@ -0,0 +1,233 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_DDR_START		(1 << 8)
++#define LTQ_MC_DDR_DLL_LOCK_IND	1
++
++#define CCS_ALWAYS_LAST			0x0430
++#define CCS_AHBM_CR_BURST_EN		(1 << 2)
++#define CCS_FPIM_CR_BURST_EN		(1 << 1)
++
++#define CCR03_EIGHT_BANK_MODE		(1 << 0)
++
++	/* Store given value in MC DDR CCRx register */
++	.macro ccr_sw num, val
++	li	t1, \val
++	sw	t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
++	.endm
++
++LEAF(ltq_mem_init)
++	/* Load MC DDR module base */
++	li	t0, (LTQ_MC_DDR_BASE | KSEG1)
++
++	/* Put memory controller in inactive mode */
++	sw	zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++	/* Init MC DDR CCR registers with values from ddr_settings.h */
++	ccr_sw	0, MC_CCR00_VALUE
++	ccr_sw	1, MC_CCR01_VALUE
++	ccr_sw	2, MC_CCR02_VALUE
++	ccr_sw	3, MC_CCR03_VALUE
++	ccr_sw	4, MC_CCR04_VALUE
++	ccr_sw	5, MC_CCR05_VALUE
++	ccr_sw	6, MC_CCR06_VALUE
++	ccr_sw	7, MC_CCR07_VALUE
++	ccr_sw	8, MC_CCR08_VALUE
++	ccr_sw	9, MC_CCR09_VALUE
++
++	ccr_sw	10, MC_CCR10_VALUE
++	ccr_sw	11, MC_CCR11_VALUE
++	ccr_sw	12, MC_CCR12_VALUE
++	ccr_sw	13, MC_CCR13_VALUE
++	ccr_sw	14, MC_CCR14_VALUE
++	ccr_sw	15, MC_CCR15_VALUE
++	ccr_sw	16, MC_CCR16_VALUE
++	ccr_sw	17, MC_CCR17_VALUE
++	ccr_sw	18, MC_CCR18_VALUE
++	ccr_sw	19, MC_CCR19_VALUE
++
++	ccr_sw	20, MC_CCR20_VALUE
++	ccr_sw	21, MC_CCR21_VALUE
++	ccr_sw	22, MC_CCR22_VALUE
++	ccr_sw	23, MC_CCR23_VALUE
++	ccr_sw	24, MC_CCR24_VALUE
++	ccr_sw	25, MC_CCR25_VALUE
++	ccr_sw	26, MC_CCR26_VALUE
++	ccr_sw	27, MC_CCR27_VALUE
++	ccr_sw	28, MC_CCR28_VALUE
++	ccr_sw	29, MC_CCR29_VALUE
++
++	ccr_sw	30, MC_CCR30_VALUE
++	ccr_sw	31, MC_CCR31_VALUE
++	ccr_sw	32, MC_CCR32_VALUE
++	ccr_sw	33, MC_CCR33_VALUE
++	ccr_sw	34, MC_CCR34_VALUE
++	ccr_sw	35, MC_CCR35_VALUE
++	ccr_sw	36, MC_CCR36_VALUE
++	ccr_sw	37, MC_CCR37_VALUE
++	ccr_sw	38, MC_CCR38_VALUE
++	ccr_sw	39, MC_CCR39_VALUE
++
++	ccr_sw	40, MC_CCR40_VALUE
++	ccr_sw	41, MC_CCR41_VALUE
++	ccr_sw	42, MC_CCR42_VALUE
++	ccr_sw	43, MC_CCR43_VALUE
++	ccr_sw	44, MC_CCR44_VALUE
++	ccr_sw	45, MC_CCR45_VALUE
++	ccr_sw	46, MC_CCR46_VALUE
++
++	ccr_sw	52, MC_CCR52_VALUE
++	ccr_sw	53, MC_CCR53_VALUE
++	ccr_sw	54, MC_CCR54_VALUE
++	ccr_sw	55, MC_CCR55_VALUE
++	ccr_sw	56, MC_CCR56_VALUE
++	ccr_sw	57, MC_CCR57_VALUE
++	ccr_sw	58, MC_CCR58_VALUE
++	ccr_sw	59, MC_CCR59_VALUE
++
++	ccr_sw	60, MC_CCR60_VALUE
++	ccr_sw	61, MC_CCR61_VALUE
++
++	/* Disable bursts between FPI Master bus and XBAR bus */
++	li	t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
++	li	t5, CCS_AHBM_CR_BURST_EN
++	sw	t5, CCS_ALWAYS_LAST(t4)
++
++	/* Init abort condition for DRAM probe */
++	move	t4, zero
++
++	/*
++	 * Put memory controller in active mode and start initialitation
++	 * sequence for connected DDR-SDRAM device
++	 */
++mc_start:
++	lw	t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++	li	t2, LTQ_MC_DDR_START
++	or	t1, t1, t2
++	sw	t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++	/*
++	 * Wait until DLL has locked and core is ready for data transfers.
++	 * DLL lock indication is in register CCR47 and CCR48
++	 */
++wait_ready:
++	li	t1, LTQ_MC_DDR_DLL_LOCK_IND
++	lw	t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
++	and	t2, t2, t1
++	bne	t1, t2, wait_ready
++
++	lw	t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
++	and	t2, t2, t1
++	bne	t1, t2, wait_ready
++
++#ifdef CONFIG_SYS_DRAM_PROBE
++dram_probe:
++	/* Initialization is finished after the second MC start */
++	bnez	t4, mc_finished
++
++	/*
++	 * Preload register values for CCR03 and CCR11. Initial settings
++	 * are 8-bank mode enabled, 14 use address row bits, 10 used
++	 * column address bits.
++	 */
++	li	t1, CONFIG_SYS_SDRAM_BASE_UC
++	li	t5, MC_CCR03_VALUE
++	li	t6, MC_CCR11_VALUE
++	addi	t4, t4, 1
++
++	/*
++	 * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
++	 * address BA[3]) and read back the value at offset 0. If the resulting
++	 * value is equal to 1 we can skip to the next test. Otherwise
++	 * the 8-bank mode does not work with the current DRAM device,
++	 * thus we need to clear the according bit in register CCR03.
++	 */
++	li	t2, 1
++	sw	t2, 0x0(t1)
++	li	t3, (1 << 13)
++	add	t3, t3, t1
++	sw	zero, 0(t3)
++	lw	t3, 0(t1)
++	bnez	t3, row_col_test
++
++	/* Clear CCR03.EIGHT_BANK_MODE */
++	li	t3, ~CCR03_EIGHT_BANK_MODE
++	and	t5, t5, t3
++
++row_col_test:
++	/*
++	 * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
++	 * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
++	 * represent the difference between max. row address bits (14) and used
++	 * row address bits. Then the read back value at offset 0 indicates
++	 * the useable row address bits with the current DRAM device. This
++	 * value must be set in the CCR11 register.
++	 */
++	sw	zero, 0(t1)
++
++	li	t2, 1
++	li	t3, (1 << 27)
++	add	t3, t3, t1
++	sw	t2, 0(t3)
++
++	li	t2, 2
++	li	t3, (1 << 26)
++	add	t3, t3, t1
++	sw	t2, 0(t3)
++
++	/* Update CCR11.ADDR_PINS */
++	lw	t3, 0(t1)
++	add	t6, t6, t3
++
++	/*
++	 * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
++	 * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
++	 * the difference between max. column address bits (12) and used
++	 * column address bits. Then the read back value at offset 0 indicates
++	 * the useable column address bits with the current DRAM device. This
++	 * value must be set in the CCR11 register.
++	 */
++	sw	zero, 0(t1)
++
++	li	t2, 1
++	li	t3, (1 << 10)
++	add	t3, t3, t1
++	sw	t2, 0(t3)
++
++	li	t2, 2
++	li	t3, (1 << 9)
++	add	t3, t3, t1
++	sw	t2, 0(t3)
++
++	/* Update CCR11.COLUMN_SIZE */
++	lw	t3, 0(t1)
++	sll	t3, t3, 24
++	add	t6, t6, t3
++
++	/* Put memory controller in inactive mode */
++	sw	zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
++
++	/* Update CCR03 and CCR11 and restart memory controller initialiation */
++	sw	t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
++	sw	t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
++	b	mc_start
++
++mc_finished:
++#endif /* CONFIG_SYS_DRAM_PROBE */
++
++	jr	ra
++
++	END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/pmu.c
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED		((1 << 13) | (1 << 4))
++
++#define LTQ_PMU_PWDCR_PCIELOC_EN	(1 << 31)
++#define LTQ_PMU_PWDCR_GPHY		(1 << 30)
++#define LTQ_PMU_PWDCR_PPE_TOP		(1 << 29)
++#define LTQ_PMU_PWDCR_SWITCH		(1 << 28)
++#define LTQ_PMU_PWDCR_USB1		(1 << 27)
++#define LTQ_PMU_PWDCR_USB1_PHY		(1 << 26)
++#define LTQ_PMU_PWDCR_TDM		(1 << 25)
++#define LTQ_PMU_PWDCR_PPE_DPLUS		(1 << 24)
++#define LTQ_PMU_PWDCR_PPE_DPLUM		(1 << 23)
++#define LTQ_PMU_PWDCR_PPE_EMA		(1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC		(1 << 21)
++#define LTQ_PMU_PWDCR_DEU		(1 << 20)
++#define LTQ_PMU_PWDCR_PPE_SLL01		(1 << 19)
++#define LTQ_PMU_PWDCR_PPE_QSB		(1 << 18)
++#define LTQ_PMU_PWDCR_UART1		(1 << 17)
++#define LTQ_PMU_PWDCR_SDIO		(1 << 16)
++#define LTQ_PMU_PWDCR_AHBM		(1 << 15)
++#define LTQ_PMU_PWDCR_FPIM		(1 << 14)
++#define LTQ_PMU_PWDCR_GPTC		(1 << 12)
++#define LTQ_PMU_PWDCR_LEDC		(1 << 11)
++#define LTQ_PMU_PWDCR_EBU		(1 << 10)
++#define LTQ_PMU_PWDCR_DSL		(1 << 9)
++#define LTQ_PMU_PWDCR_SPI		(1 << 8)
++#define LTQ_PMU_PWDCR_USIF		(1 << 7)
++#define LTQ_PMU_PWDCR_USB0		(1 << 6)
++#define LTQ_PMU_PWDCR_DMA		(1 << 5)
++#define LTQ_PMU_PWDCR_DFEV1		(1 << 3)
++#define LTQ_PMU_PWDCR_DFEV0		(1 << 2)
++#define LTQ_PMU_PWDCR_FPIS		(1 << 1)
++#define LTQ_PMU_PWDCR_USB0_PHY		(1 << 0)
++
++struct ltq_pmu_regs {
++	u32	rsvd0[7];
++	u32	pwdcr;		/* Power down control */
++	u32	sr;		/* Power down status */
++	u32	pwdcr1;		/* Power down control 1 */
++	u32	sr1;		/* Power down status 1 */
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++	(struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_PM_CORE:
++		val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
++			LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
++		break;
++	case LTQ_PM_DMA:
++		val = LTQ_PMU_PWDCR_DMA;
++		break;
++	case LTQ_PM_ETH:
++		val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
++			LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
++			LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
++			LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
++			LTQ_PMU_PWDCR_PPE_QSB;
++		break;
++	case LTQ_PM_SPI:
++		val = LTQ_PMU_PWDCR_SPI;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++	const unsigned long timeout = 1000;
++	unsigned long timebase;
++	u32 sr, val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++	timebase = get_timer(0);
++
++	do {
++		sr = ltq_readl(&ltq_pmu_regs->sr);
++		if (~sr & val)
++			return 0;
++	} while (get_timer(timebase) < timeout);
++
++	return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++	return 0;
++}
++
++void ltq_pmu_init(void)
++{
++	u32 set, clr;
++
++	clr = ltq_pm_map(LTQ_PM_CORE);
++	set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++	ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/vrx200/rcu.c
+@@ -0,0 +1,194 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_GPHY0	(1 << 31)	/* GPHY0 */
++#define LTQ_RCU_RD_SRST		(1 << 30)	/* Global SW Reset */
++#define LTQ_RCU_RD_GPHY1	(1 << 29)	/* GPHY1 */
++#define LTQ_RCU_RD_ENMIP2	(1 << 28)	/* Enable NMI of PLL2 */
++#define LTQ_RCU_RD_REG25_PD	(1 << 26)	/* Power down 2.5V regulator */
++#define LTQ_RCU_RD_ENDINIT	(1 << 25)	/* FPI slave bus access */
++#define LTQ_RCU_RD_PPE_ATM_TC	(1 << 23)	/* PPE ATM TC */
++#define LTQ_RCU_RD_PCIE		(1 << 22)	/* PCI-E core */
++#define LTQ_RCU_RD_ETHSW	(1 << 21)	/* Ethernet switch */
++#define LTQ_RCU_RD_DSP_DEN	(1 << 20)	/* Enable DSP JTAG */
++#define LTQ_RCU_RD_TDM		(1 << 19)	/* TDM module interface */
++#define LTQ_RCU_RD_ENMIP1	(1 << 18)	/* Enable NMI of PLL1 */
++#define LTQ_RCU_RD_SWBCK	(1 << 17)	/* Switch backward compat */
++#define LTQ_RCU_RD_HSNAND	(1 << 16)	/* HSNAND controller */
++#define LTQ_RCU_RD_ENMIP0	(1 << 15)	/* Enable NMI of PLL0 */
++#define LTQ_RCU_RD_MC		(1 << 14)	/* Memory Controller */
++#define LTQ_RCU_RD_PCI		(1 << 13)	/* PCI core */
++#define LTQ_RCU_RD_PCIE_PHY	(1 << 12)	/* PCI-E Phy */
++#define LTQ_RCU_RD_DFE_CORE	(1 << 11)	/* DFE core */
++#define LTQ_RCU_RD_SDIO		(1 << 10)	/* SDIO core */
++#define LTQ_RCU_RD_DMA		(1 << 9)	/* DMA core */
++#define LTQ_RCU_RD_PPE		(1 << 8)	/* PPE core */
++#define LTQ_RCU_RD_DFE		(1 << 7)	/* DFE core */
++#define LTQ_RCU_RD_AHB		(1 << 6)	/* AHB bus */
++#define LTQ_RCU_RD_HRST_CFG	(1 << 5)	/* HW reset configuration */
++#define LTQ_RCU_RD_USB		(1 << 4)	/* USB and Phy core */
++#define LTQ_RCU_RD_PPE_DSP	(1 << 3)	/* PPE DSP interface */
++#define LTQ_RCU_RD_FPI		(1 << 2)	/* FPI bus */
++#define LTQ_RCU_RD_CPU		(1 << 1)	/* CPU subsystem */
++#define LTQ_RCU_RD_HRST		(1 << 0)	/* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT		17
++#define LTQ_RCU_STAT_BOOT_MASK		(0xF << LTQ_RCU_STAT_BOOT_SHIFT)
++#define LTQ_RCU_STAT_BOOT_H		(1 << 12)
++
++#define LTQ_RCU_GP_STRAP_CLOCKSOURCE	(1 << 15)
++
++struct ltq_rcu_regs {
++	u32	rsvd0[4];
++	u32	req;		/* Reset request */
++	u32	stat;		/* Reset status */
++	u32	usb0_cfg;	/* USB0 configure */
++	u32	gp_strap;	/* GPIO strapping */
++	u32	gfs_add0;	/* GPHY0 firmware base addr */
++	u32	stat2;		/* SLIC and USB reset status */
++	u32	pci_rdy;	/* PCI boot ready */
++	u32	ppe_conf;	/* PPE ethernet config */
++	u32	pcie_phy_con;	/* PCIE PHY config/status */
++	u32	usb1_cfg;	/* USB1 configure */
++	u32	usb_ana_cfg1a;	/* USB analog config 1a */
++	u32	usb_ana_cfg1b;	/* USB analog config 1b */
++	u32	rsvd1;
++	u32	gf_mdio_add;	/* GPHY0/1 MDIO address */
++	u32	req2;		/* SLIC and USB reset request */
++	u32	ahb_endian;	/* AHB bus endianess */
++	u32	rsvd2[4];
++	u32	gcc;		/* General CPU config */
++	u32	rsvd3;
++	u32	gfs_add1;	/* GPHY1 firmware base addr */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++	(struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_RESET_CORE:
++	case LTQ_RESET_SOFT:
++		val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
++			LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++		break;
++	case LTQ_RESET_DMA:
++		val = LTQ_RCU_RD_DMA;
++		break;
++	case LTQ_RESET_ETH:
++		val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
++		break;
++	case LTQ_RESET_PHY:
++		val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
++		break;
++	case LTQ_RESET_HARD:
++		val = LTQ_RCU_RD_HRST;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++	u32 stat;
++	unsigned int bootstrap;
++
++	/*
++	 * Boot select value is built from bits 20-17 and bit 12.
++	 * The bit sequence is read as 4-2-1-0-3.
++	 */
++	stat = ltq_readl(&ltq_rcu_regs->stat);
++	bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
++		((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
++
++	switch (bootstrap) {
++	case 0:
++		return BOOT_NOR_NO_BOOTROM;
++	case 1:
++		return BOOT_RGMII1;
++	case 2:
++		return BOOT_NOR;
++	case 4:
++		return BOOT_UART_NO_EEPROM;
++	case 6:
++		return BOOT_PCI;
++	case 8:
++		return BOOT_UART;
++	case 10:
++		return BOOT_SPI;
++	case 12:
++		return BOOT_NAND;
++	default:
++		return BOOT_UNKNOWN;
++	}
++}
++
++void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
++{
++	u32 module;
++	void *gfs_add;
++
++	switch (id) {
++	case 0:
++		module = LTQ_RCU_RD_GPHY0;
++		gfs_add = &ltq_rcu_regs->gfs_add0;
++		break;
++	case 1:
++		module = LTQ_RCU_RD_GPHY1;
++		gfs_add = &ltq_rcu_regs->gfs_add1;
++		break;
++	default:
++		BUG();
++	}
++
++	/* Stop and reset GPHY */
++	ltq_setbits(&ltq_rcu_regs->req, module);
++
++	/* Configure firmware and boot address */
++	ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
++
++	/* Start GPHY by releasing reset */
++	ltq_clrbits(&ltq_rcu_regs->req, module);
++}
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/config.h
+@@ -0,0 +1,164 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ *
++ * Common board configuration for Lantiq XWAY Danube family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the Danube ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the Danube ETOP and MAC interface
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the Danube SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ */
++
++#ifndef __DANUBE_CONFIG_H__
++#define __DANUBE_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_DANUBE
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE	CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE		(16 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE		(16 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE	32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 333 MHz
++ * PLL1 clock output is 262.144 MHz
++ */
++#define LTQ_CLK_CPU_333_DDR_167		0	/* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_111_DDR_111		1	/* Base PLL0, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE		LTQ_CLK_CPU_333_DDR_167
++#define CONFIG_SYS_MIPS_TIMER_FREQ	166666667
++#define CONFIG_SYS_HZ			1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS		1
++#define CONFIG_SYS_SDRAM_BASE		0x80000000
++#define CONFIG_SYS_MEMTEST_START	0x81000000
++#define CONFIG_SYS_MEMTEST_END		0x82000000
++#define CONFIG_SYS_LOAD_ADDR		0x81000000
++#define CONFIG_SYS_LOAD_SIZE		(2 * 1024 * 1024)
++#define CONFIG_SYS_INIT_SP_OFFSET	0x4000
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE		0xBE1A0000
++#define CONFIG_SYS_SRAM_SIZE		0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS	2
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS	1
++#define CONFIG_SYS_MAX_FLASH_SECT	256
++#define CONFIG_SYS_FLASH_BASE		0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS	50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_NAND_LANTIQ
++#define CONFIG_SYS_MAX_NAND_DEVICE	1
++#define CONFIG_SYS_NAND_BASE		0xB4000000
++
++#define CONFIG_CMD_NAND
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_DANUBE_ETOP
++
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE		(32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE		(8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE	(8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE	(32 * 1024)
++/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SRAM_BASE + \
++					CONFIG_SPL_MAX_SIZE + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE	  	(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE		(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SPL_BSS_BASE + \
++					CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE		0xa0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SPL_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG	0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define	CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
++
++#endif /* __DANUBE_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/gpio.h
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __DANUBE_GPIO_H__
++#define __DANUBE_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __DANUBE_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/nand.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __DANUBE_NAND_H__
++#define __DANUBE_NAND_H__
++
++struct nand_chip;
++int ltq_nand_init(struct nand_chip *nand);
++
++#endif /* __DANUBE_NAND_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-danube/soc.h
+@@ -0,0 +1,38 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __DANUBE_SOC_H__
++#define __DANUBE_SOC_H__
++
++#define LTQ_ASC0_BASE			0x1E100400
++#define LTQ_SPI_BASE			0x1E100800
++#define LTQ_GPIO_BASE			0x1E100B00
++#define LTQ_SSIO_BASE			0x1E100BB0
++#define LTQ_ASC1_BASE			0x1E100C00
++#define LTQ_DMA_BASE			0x1E104100
++
++#define LTQ_EBU_BASE			0x1E105300
++#define LTQ_EBU_REGION0_BASE		0x10000000
++#define LTQ_EBU_REGION1_BASE		0x14000000
++#define LTQ_EBU_NAND_BASE		(LTQ_EBU_BASE + 0xB0)
++
++#define LTQ_PPE_BASE			0x1E180000
++#define LTQ_PPE_ETOP_BASE		(LTQ_PPE_BASE + 0x11800)
++#define LTQ_PPE_ENET0_BASE		(LTQ_PPE_BASE + 0x11840)
++
++#define LTQ_PMU_BASE			0x1F102000
++#define LTQ_CGU_BASE			0x1F103000
++#define LTQ_MPS_BASE			0x1F107000
++#define LTQ_CHIPID_BASE			(LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE			0x1F203000
++
++#define LTQ_MC_GEN_BASE			0x1F800000
++#define LTQ_MC_SDR_BASE			0x1F800200
++#define LTQ_MC_DDR_BASE			0x1F801000
++#define LTQ_MC_DDR_DC_OFFSET(x)		(x * 0x10)
++
++#endif /* __DANUBE_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -0,0 +1,188 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ *
++ * Common board configuration for Lantiq XWAY VRX200 family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the VRX200 ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the VRX200 internal switch
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the VRX200 SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ *
++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
++ * - build a preloader that runs in the internal SRAM and loads
++ *   the U-Boot from SPI flash into RAM
++ */
++
++#ifndef __VRX200_CONFIG_H__
++#define __VRX200_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_VRX200
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE	CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE		(32 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE		(32 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE	32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0 clock output is 1000 MHz
++ * PLL1 clock output is 393.219 MHz
++ */
++#define LTQ_CLK_CPU_600_DDR_300	0	/* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_600_DDR_200	1	/* Base PLL0, OCP 3 */
++#define LTQ_CLK_CPU_500_DDR_250	2	/* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_500_DDR_200	3	/* Base PLL0, OCP 2.5 */
++#define LTQ_CLK_CPU_333_DDR_167	4	/* Base PLL0, OCP 2 */
++#define LTQ_CLK_CPU_167_DDR_167	5	/* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_125_DDR_125	6	/* Base PLL0, OCP 1 */
++#define LTQ_CLK_CPU_393_DDR_197	7	/* Base PLL1, OCP 2 */
++#define LTQ_CLK_CPU_197_DDR_197	8	/* Base PLL1, OCP 1 */
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE		LTQ_CLK_CPU_500_DDR_250
++#define CONFIG_SYS_MIPS_TIMER_FREQ	250000000
++#define CONFIG_SYS_HZ			1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS		1
++#define CONFIG_SYS_SDRAM_BASE		0x80000000
++#define CONFIG_SYS_SDRAM_BASE_UC	0xa0000000
++#define CONFIG_SYS_MEMTEST_START	0x81000000
++#define CONFIG_SYS_MEMTEST_END		0x82000000
++#define CONFIG_SYS_LOAD_ADDR		0x81000000
++#define CONFIG_SYS_LOAD_SIZE		(2 * 1024 * 1024)
++#define CONFIG_SYS_INIT_SP_OFFSET	(32 * 1024)
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE		0xBE220000
++#define CONFIG_SYS_SRAM_SIZE		0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS	3
++#define CONFIG_LTQ_HAS_GPIO_BANK3
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#ifndef CONFIG_SYS_MAX_FLASH_BANKS
++#define CONFIG_SYS_MAX_FLASH_BANKS	1
++#endif
++#define CONFIG_SYS_MAX_FLASH_SECT	256
++#define CONFIG_SYS_FLASH_BASE		0xB0000000
++#define CONFIG_SYS_FLASH2_BASE		0xB4000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS	50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_NAND_LANTIQ
++#define CONFIG_SYS_MAX_NAND_DEVICE	1
++#define CONFIG_SYS_NAND_BASE		0xB4000000
++
++#define CONFIG_CMD_NAND
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_VRX200_SWITCH
++#define CONFIG_PHY_LANTIQ
++
++#define CONFIG_SYS_RX_ETH_BUFFER	8
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++#define CONFIG_UDP_CHECKSUM
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE		(32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE		(8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE	(8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE	(32 * 1024)
++#define CONFIG_SPL_STACK_BSS_IN_SRAM
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SRAM_BASE + \
++					CONFIG_SPL_MAX_SIZE + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE	  	(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE		(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SPL_BSS_BASE + \
++					CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE		0xA0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SPL_TEXT_BASE		0xBE220000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SPL_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG	0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define	CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
++
++#endif /* __VRX200_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gphy.h
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_GPHY_H__
++#define __VRX200_GPHY_H__
++
++enum ltq_gphy_clk {
++	/* XTAL 36 MHz input */
++	LTQ_GPHY_CLK_36MHZ_XTAL = 1,
++	/* 25 MHz from PLL0 with divider */
++	LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
++	/* derived from PLL2 output (XTAL is 36 MHz) */
++	LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
++	/* 25 MHz Clock from Pin GPIO3 */
++	LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
++};
++
++/*
++ * Load PHY11G firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a1x_load(ulong addr);
++
++/*
++ * Load PHY11G firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy11g_a2x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.1 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a1x_load(ulong addr);
++
++/*
++ * Load PHY22F firmware for VRX200 v1.2 to given RAM address
++ *
++ * Address must be 16k aligned!
++ */
++extern void ltq_gphy_phy22f_a2x_load(ulong addr);
++
++/*
++ * Set clock source of internal GPHYs
++ *
++ * According registers resides in CGU address space. Thus this function
++ * is implemented by the CGU driver.
++ */
++extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
++
++/*
++ * Boot internal GPHY with id from given RAM address
++ *
++ * According registers resides in RCU address space. Thus this function
++ * is implemented by the RCU driver.
++ */
++extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
++
++#endif /* __VRX200_GPHY_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/gpio.h
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_GPIO_H__
++#define __VRX200_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __VRX200_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/nand.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_NAND_H__
++#define __VRX200_NAND_H__
++
++struct nand_chip;
++int ltq_nand_init(struct nand_chip *nand);
++
++#endif /* __VRX200_NAND_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/soc.h
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_SOC_H__
++#define __VRX200_SOC_H__
++
++#define LTQ_ASC0_BASE			0x1E100400
++#define LTQ_SPI_BASE			0x1E100800
++#define LTQ_GPIO_BASE			0x1E100B00
++#define LTQ_SSIO_BASE			0x1E100BB0
++#define LTQ_ASC1_BASE			0x1E100C00
++#define LTQ_DMA_BASE			0x1E104100
++
++#define LTQ_EBU_BASE			0x1E105300
++#define LTQ_EBU_REGION0_BASE		0x10000000
++#define LTQ_EBU_REGION1_BASE		0x14000000
++#define LTQ_EBU_NAND_BASE		(LTQ_EBU_BASE + 0xB0)
++
++#define LTQ_SWITCH_BASE			0x1E108000
++#define LTQ_SWITCH_CORE_BASE		LTQ_SWITCH_BASE
++#define LTQ_SWITCH_TOP_PDI_BASE		LTQ_SWITCH_CORE_BASE
++#define LTQ_SWITCH_BM_PDI_BASE		(LTQ_SWITCH_CORE_BASE + 4 * 0x40)
++#define LTQ_SWITCH_MAC_PDI_0_BASE	(LTQ_SWITCH_CORE_BASE + 4 * 0x900)
++#define LTQ_SWITCH_MAC_PDI_X_BASE(x)	(LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
++#define LTQ_SWITCH_TOPLEVEL_BASE	(LTQ_SWITCH_BASE + 4 * 0xC40)
++#define LTQ_SWITCH_MDIO_PDI_BASE	(LTQ_SWITCH_TOPLEVEL_BASE)
++#define LTQ_SWITCH_MII_PDI_BASE		(LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
++#define LTQ_SWITCH_PMAC_PDI_BASE	(LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
++
++#define LTQ_PMU_BASE			0x1F102000
++#define LTQ_CGU_BASE			0x1F103000
++#define LTQ_DCDC_BASE			0x1F106A00
++#define LTQ_MPS_BASE			0x1F107000
++#define LTQ_CHIPID_BASE			(LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE			0x1F203000
++
++#define LTQ_MC_GLOBAL_BASE		0x1F400000
++#define LTQ_MC_DDR_BASE			0x1F401000
++#define LTQ_MC_DDR_CCR_OFFSET(x)	(x * 0x10)
++
++#endif /* __VRX200_SOC_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-vrx200/switch.h
+@@ -0,0 +1,502 @@
++/*
++ *   Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ *   SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_SWITCH_H__
++#define __VRX200_SWITCH_H__
++
++/* Switch core registers */
++struct vr9_switch_core_regs {
++	__be32 swres;
++	/* TODO: implement registers */
++	__be32 rsvd0[0x3f];
++};
++
++/* Switch buffer management registers */
++struct vr9_switch_bm_regs {
++	struct bm_core {
++		__be32 ram_val3;	/* RAM value 3 */
++		__be32 ram_val2;	/* RAM value 2 */
++		__be32 ram_val1;	/* RAM value 1 */
++		__be32 ram_val0;	/* RAM value 0 */
++		__be32 ram_addr;	/* RAM address */
++		__be32 ram_ctrl;	/* RAM access control */
++		__be32 fsqm_gctrl;	/* Free segment queue global control */
++		__be32 cons_sel;	/* Number of consumed segments */
++		__be32 cons_pkt;	/* Number of consumed packet pointers */
++		__be32 gctrl;		/* Global control */
++		__be32 queue_gctrl;	/* Queue manager global control */
++		/* TODO: implement registers */
++		__be32 rsvd0[0x35];
++	} core;
++
++	struct bm_port {
++		__be32 pcfg;		/* Port config */
++		__be32 rmon_ctrl;	/* RMON control */
++	} port[13];
++
++	__be32 rsvd0[0x66];
++
++	struct bm_queue {
++		__be32 rsvd0;
++		__be32 pqm_rs;		/* Packet queue manager rate shape assignment */
++	} queue[32];
++
++	struct bm_shaper {
++		__be32 ctrl;		/* Rate shaper control */
++		__be32 cbs;		/* Rate shaper committed burst size */
++		__be32 ibs;		/* Rate shaper instantaneous burst size */
++		__be32 cir_ext;		/* Rate shaper rate exponent */
++		__be32 cir_mant;	/* Rate shaper rate mantissa */
++	} shaper[16];
++
++	__be32 rsvd1[0x2a8];
++};
++
++/* Switch parser and classification engine registers */
++struct vr9_switch_pce_regs {
++	struct pce_core {
++		__be32 tbl_key[16];	/* Table key data */
++		__be32 tbl_mask;	/* Table mask */
++		__be32 tbl_val[5];	/* Table value */
++		__be32 tbl_addr;	/* Table entry address */
++		__be32 tbl_ctrl;	/* Table access control */
++		__be32 tbl_stat;	/* Table general status */
++		__be32 age_0;		/* Aging counter config 0 */
++		__be32 age_1;		/* Aging counter config 1 */
++		__be32 pmap_1;		/* Port map (monitoring) */
++		__be32 pmap_2;		/* Port map (multicast) */
++		__be32 pmap_3;		/* Port map (unknown unicast) */
++		__be32 gctrl_0;		/* Global control 0 */
++		__be32 gctrl_1;		/* Global control 1 */
++		__be32 tcm_gctrl;	/* Three-color marker global control */
++		__be32 igmp_ctrl;	/* IGMP control */
++		__be32 igmp_drpm;	/* IGMP default router port map */
++		__be32 igmp_age_0;	/* IGMP aging 0 */
++		__be32 igmp_age_1;	/* IGMP aging 1 */
++		__be32 igmp_stat;	/* IGMP status */
++		__be32 wol_gctrl;	/* Wake-on-LAN control */
++		__be32 wol_da_0;	/* Wake-on-LAN destination address 0 */
++		__be32 wol_da_1;	/* Wake-on-LAN destination address 1 */
++		__be32 wol_da_2;	/* Wake-on-LAN destination address 2 */
++		__be32 wol_pw_0;	/* Wake-on-LAN password 0 */
++		__be32 wol_pw_1;	/* Wake-on-LAN password 1 */
++		__be32 wol_pw_2;	/* Wake-on-LAN password 2 */
++		__be32 ier_0;		/* PCE global interrupt enable 0 */
++		__be32 ier_1;		/* PCE global interrupt enable 1 */
++		__be32 isr_0;		/* PCE global interrupt status 0 */
++		__be32 isr_1;		/* PCE global interrupt status 1 */
++		__be32 parser_stat;	/* Parser status */
++		__be32 rsvd0[0x6];
++	} core;
++
++	__be32 rsvd0[0x10];
++
++	struct pce_port {
++		__be32 pctrl_0;		/* Port control 0 */
++		__be32 pctrl_1;		/* Port control 1 */
++		__be32 pctrl_2;		/* Port control 2 */
++		__be32 pctrl_3;		/* Port control 3 */
++		__be32 wol_ctrl;	/* Wake-on-LAN control */
++		__be32 vlan_ctrl;	/* VLAN control */
++		__be32 def_pvid;	/* Default port VID */
++		__be32 pstat;		/* Port status */
++		__be32 pier;		/* Interrupt enable */
++		__be32 pisr;		/* Interrupt status */
++	} port[13];
++
++	__be32 rsvd1[0x7e];
++
++	struct pce_meter {
++		/* TODO: implement registers */
++		__be32 rsvd0[0x7];
++	} meter[8];
++
++	__be32 rsvd2[0x308];
++};
++
++static inline unsigned int to_pce_tbl_key_id(unsigned int id)
++{
++	BUG_ON(id > 15);
++
++	return 15 - id;
++}
++
++static inline unsigned int to_pce_tbl_value_id(unsigned int id)
++{
++	BUG_ON(id > 4);
++
++	return 4 - id;
++}
++
++/* Switch ethernet MAC registers */
++struct vr9_switch_mac_regs {
++	struct mac_core {
++		__be32 test;		/* MAC test */
++		__be32 pfad_cfg;	/* Pause frame source address config */
++		__be32 pfsa_0;		/* Pause frame source address 0 */
++		__be32 pfsa_1;		/* Pause frame source address 1 */
++		__be32 pfsa_2;		/* Pause frame source address 2 */
++		__be32 flen;		/* Frame length */
++		__be32 vlan_etype_0;	/* VLAN ethertype 0 */
++		__be32 vlan_etype_1;	/* VLAN ethertype 1 */
++		__be32 ier;		/* Interrupt enable */
++		__be32 isr;		/* Interrupt status */
++		__be32 rsvd0[0x36];
++	} core;
++
++	struct mac_port {
++		__be32 pstat;		/* Port status */
++		__be32 pisr;		/* Interrupt status */
++		__be32 pier;		/* Interrupt enable */
++		__be32 ctrl_0;		/* Control 0 */
++		__be32 ctrl_1;		/* Control 1 */
++		__be32 ctrl_2;		/* Control 2 */
++		__be32 ctrl_3;		/* Control 3 */
++		__be32 ctrl_4;		/* Control 4 */
++		__be32 ctrl_5;		/* Control 5 */
++		__be32 rsvd0[0x2];
++		__be32 testen;		/* Test enable */
++	} port[13];
++
++	__be32 rsvd0[0xa4];
++};
++
++/* Switch Fetch DMA registers */
++struct vr9_switch_fdma_regs {
++	struct fdma_core {
++		__be32 ctrl;		/* FDMA control */
++		__be32 stetype;		/* Special tag ethertype control */
++		__be32 vtetype;		/* VLAN tag ethertype control */
++		__be32 stat;		/* FDMA status */
++		__be32 ier;		/* FDMA interrupt enable */
++		__be32 isr;		/* FDMA interrupt status */
++	} core;
++
++	__be32 rsvd0[0x3a];
++
++	struct fdma_port {
++		__be32 pctrl;		/* Port control */
++		__be32 prio;		/* Port priority */
++		__be32 pstat_0;		/* Port status 0 */
++		__be32 pstat_1;		/* Port status 1 */
++		__be32 tstamp_0;	/* Egress time stamp 0 */
++		__be32 tstamp_1;	/* Egress time stamp 1 */
++	} port[13];
++
++	__be32 rsvd1[0x72];
++};
++
++/* Switch Store DMA registers */
++struct vr9_switch_sdma_regs {
++	struct sdma_core {
++		__be32 ctrl;		/* SDMA Control */
++		__be32 fcthr_1;		/* Flow control threshold 1 */
++		__be32 rsvd0;
++		__be32 fcthr_3;		/* Flow control threshold 3 */
++		__be32 fcthr_4;		/* Flow control threshold 4 */
++		__be32 fcthr_5;		/* Flow control threshold 5 */
++		__be32 fcthr_6;		/* Flow control threshold 6 */
++		__be32 fcthr_7;		/* Flow control threshold 7 */
++		__be32 stat_0;		/* SDMA status 0 */
++		__be32 stat_1;		/* SDMA status 1 */
++		__be32 stat_2;		/* SDMA status 2 */
++		__be32 ier;		/* SDMA interrupt enable */
++		__be32 isr;		/* SDMA interrupt status */
++	} core;
++
++	__be32 rsvd0[0x73];
++
++	struct sdma_port {
++		__be32 pctrl;		/* Port control */
++		__be32 prio;		/* Port priority */
++		__be32 pstat_0;		/* Port status 0 */
++		__be32 pstat_1;		/* Port status 1 */
++		__be32 tstamp_0;	/* Ingress time stamp 0 */
++		__be32 tstamp_1;	/* Ingress time stamp 1 */
++	} port[13];
++
++	__be32 rsvd1[0x32];
++};
++
++/* Switch MDIO control and status registers */
++struct vr9_switch_mdio_regs {
++	__be32 glob_ctrl;	/* Global control 0 */
++	__be32 rsvd0[7];
++	__be32 mdio_ctrl;	/* MDIO control */
++	__be32 mdio_read;	/* MDIO read data */
++	__be32 mdio_write;	/* MDIO write data */
++	__be32 mdc_cfg_0;	/* MDC clock configuration 0 */
++	__be32 mdc_cfg_1;	/* MDC clock configuration 1 */
++	__be32 rsvd1[0x3];
++	__be32 phy_addr[6];	/* PHY address port 5..0 */
++	__be32 mdio_stat[6];	/* MDIO PHY polling status port 0..5 */
++	__be32 aneg_eee[6];	/* EEE auto-neg overrides port 0..5 */
++	__be32 rsvd2[0x14];
++};
++
++static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
++{
++	BUG_ON(id > 5);
++
++	return 5 - id;
++}
++
++/* Switch xMII control registers */
++struct vr9_switch_mii_regs {
++	__be32 mii_cfg0;	/* xMII port 0 configuration */
++	__be32 pcdu0;		/* Port 0 clock delay configuration */
++	__be32 mii_cfg1;	/* xMII port 1 configuration */
++	__be32 pcdu1;		/* Port 1 clock delay configuration */
++	__be32 rsvd0[0x6];
++	__be32 mii_cfg5;	/* xMII port 5 configuration */
++	__be32 pcdu5;		/* Port 5 clock delay configuration */
++	__be32 rsvd1[0x14];
++	__be32 rxb_ctl_0;	/* Port 0 receive buffer control */
++	__be32 rxb_ctl_1;	/* Port 1 receive buffer control */
++	__be32 rxb_ctl_5;	/* Port 5 receive buffer control */
++	__be32 rsvd2[0x28];
++	__be32 dbg_ctl;		/* Debug control */
++};
++
++/* Switch Pseudo-MAC registers */
++struct vr9_switch_pmac_regs {
++	__be32 hd_ctl;		/* PMAC header control */
++	__be32 tl;		/* PMAC type/length */
++	__be32 sa1;		/* PMAC source address 1 */
++	__be32 sa2;		/* PMAC source address 2 */
++	__be32 sa3;		/* PMAC source address 3 */
++	__be32 da1;		/* PMAC destination address 1 */
++	__be32 da2;		/* PMAC destination address 2 */
++	__be32 da3;		/* PMAC destination address 3 */
++	__be32 vlan;		/* PMAC VLAN */
++	__be32 rx_ipg;		/* PMAC interpacket gap in RX direction */
++	__be32 st_etype;	/* PMAC special tag ethertype */
++	__be32 ewan;		/* PMAC ethernet WAN group */
++	__be32 ctl;		/* PMAC control */
++	__be32 rsvd0[0x2];
++};
++
++struct vr9_switch_regs {
++	struct vr9_switch_core_regs core;
++	struct vr9_switch_bm_regs bm;
++	struct vr9_switch_pce_regs pce;
++	struct vr9_switch_mac_regs mac;
++	struct vr9_switch_fdma_regs fdma;
++	struct vr9_switch_sdma_regs sdma;
++	struct vr9_switch_mdio_regs mdio;
++	struct vr9_switch_mii_regs mii;
++	struct vr9_switch_pmac_regs pmac;
++};
++
++static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
++						unsigned int id)
++{
++	return &regs->pce.core.tbl_key[to_pce_tbl_key_id(id)];
++}
++
++static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
++						unsigned int id)
++{
++	return &regs->pce.core.tbl_val[to_pce_tbl_value_id(id)];
++}
++
++static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
++					unsigned int id, unsigned int ctrl)
++{
++	struct mac_port *mac = &regs->mac.port[id];
++
++	switch (ctrl) {
++	case 0:
++		return &mac->ctrl_0;
++	case 1:
++		return &mac->ctrl_1;
++	case 2:
++		return &mac->ctrl_2;
++	case 3:
++		return &mac->ctrl_3;
++	case 4:
++		return &mac->ctrl_4;
++	case 5:
++		return &mac->ctrl_5;
++	default:
++		return NULL;
++	}
++}
++
++static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
++					unsigned int id)
++{
++	return &regs->mdio.phy_addr[to_mdio_phyaddr_id(id)];
++}
++
++static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
++					unsigned int id)
++{
++	switch (id) {
++	case 0:
++		return &regs->mii.mii_cfg0;
++	case 1:
++		return &regs->mii.mii_cfg1;
++	case 5:
++		return &regs->mii.mii_cfg5;
++	default:
++		return NULL;
++	}
++}
++
++static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
++					unsigned int id)
++{
++	switch (id) {
++	case 0:
++		return &regs->mii.pcdu0;
++	case 1:
++		return &regs->mii.pcdu1;
++	case 5:
++		return &regs->mii.pcdu5;
++	default:
++		return NULL;
++	}
++}
++
++#define VR9_SWITCH_REG_OFFSET(reg)	(4 * (reg))
++
++#define BUILD_CHECK_VR9_REG(name, offset)	\
++	BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
++
++static inline void build_check_vr9_registers(void)
++{
++	BUILD_CHECK_VR9_REG(core, 0x0);
++	BUILD_CHECK_VR9_REG(bm.core, 0x40);
++	BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
++	BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
++	BUILD_CHECK_VR9_REG(bm.queue, 0x100);
++	BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
++	BUILD_CHECK_VR9_REG(pce.core, 0x438);
++	BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
++	BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
++	BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
++	BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
++	BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
++	BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
++	BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
++	BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
++	BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
++	BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
++	BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
++	BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
++	BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
++	BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
++	BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
++	BUILD_CHECK_VR9_REG(mdio, 0xc40);
++	BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
++	BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
++}
++
++#define BM_GCTRL_F_SRES		1
++
++#define MAC_CTRL0_BM		(1 << 12)
++#define MAC_CTRL0_APADEN	(1 << 11)
++#define MAC_CTRL0_VPAD2EN	(1 << 10)
++#define MAC_CTRL0_VPADEN	(1 << 9)
++#define MAC_CTRL0_PADEN		(1 << 8)
++#define MAC_CTRL0_FCS		(1 << 7)
++#define MAC_CTRL0_FCON_SHIFT	4
++#define MAC_CTRL0_FCON_AUTO	(0x0 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RX	(0x1 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_TX	(0x2 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_RXTX	(0x3 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FCON_NONE	(0x4 << MAC_CTRL0_FCON_SHIFT)
++#define MAC_CTRL0_FDUP_SHIFT	2
++#define MAC_CTRL0_FDUP_AUTO	(0x0 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_EN	(0x1 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_FDUP_DIS	(0x3 << MAC_CTRL0_FDUP_SHIFT)
++#define MAC_CTRL0_GMII_AUTO	0x0
++#define MAC_CTRL0_GMII_MII	0x1
++#define MAC_CTRL0_GMII_GMII	0x2
++#define MAC_CTRL0_GMII_GMII_2G	0x3
++
++#define MAC_CTRL1_DEFERMODE	(1 << 15)
++#define MAC_CTRL1_SHORTPRE	(1 << 8)
++
++#define MAC_CTRL2_MLEN		(1 << 3)
++#define MAC_CTRL2_LCHKL		(1 << 2)
++#define MAC_CTRL2_LCHKS_DIS	0x0
++#define MAC_CTRL2_LCHKS_UNTAG	0x1
++#define MAC_CTRL2_LCHKS_TAG	0x2
++
++#define PHY_ADDR_LNKST_SHIFT	13
++#define PHY_ADDR_LNKST_AUTO	(0x0 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_UP	(0x1 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_LNKST_DOWN	(0x2 << PHY_ADDR_LNKST_SHIFT)
++#define PHY_ADDR_SPEED_SHIFT	11
++#define PHY_ADDR_SPEED_M10	(0x0 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_M100	(0x1 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_G1	(0x2 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_SPEED_AUTO	(0x3 << PHY_ADDR_SPEED_SHIFT)
++#define PHY_ADDR_FDUP_SHIFT	9
++#define PHY_ADDR_FDUP_AUTO	(0x0 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_EN	(0x1 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FDUP_DIS	(0x3 << PHY_ADDR_FDUP_SHIFT)
++#define PHY_ADDR_FCONTX_SHIFT	7
++#define PHY_ADDR_FCONTX_AUTO	(0x0 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_EN	(0x1 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONTX_DIS	(0x3 << PHY_ADDR_FCONTX_SHIFT)
++#define PHY_ADDR_FCONRX_SHIFT	5
++#define PHY_ADDR_FCONRX_AUTO	(0x0 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_EN	(0x1 << PHY_ADDR_FCONRX_SHIFT)
++#define PHY_ADDR_FCONRX_DIS	(0x3 << PHY_ADDR_FCONRX_SHIFT)
++
++#define MII_CFG_RES		(1 << 15)
++#define MII_CFG_EN		(1 << 14)
++#define MII_CFG_LDCLKDIS	(1 << 12)
++#define MII_CFG_MIIRATE_SHIFT	4
++#define MII_CFG_MIIRATE_MASK	(0x7 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M2P5	(0x0 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M25	(0x1 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M125	(0x2 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_M50	(0x3 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIRATE_AUTO	(0x4 << MII_CFG_MIIRATE_SHIFT)
++#define MII_CFG_MIIMODE_MASK	0xf
++#define MII_CFG_MIIMODE_MIIP	0x0
++#define MII_CFG_MIIMODE_MIIM	0x1
++#define MII_CFG_MIIMODE_RMIIP	0x2
++#define MII_CFG_MIIMODE_RMIIM	0x3
++#define MII_CFG_MIIMODE_RGMII	0x4
++
++#define PCDU_RXDLY_SHIFT	7
++#define PCDU_RXDLY_MASK		(0x7 << PCDU_RXDLY_SHIFT)
++#define PCDU_TXDLY_MASK		0x7
++
++#define PMAC_HD_CTL_FC		(1 << 10)
++#define PMAC_HD_CTL_CCRC	(1 << 9)
++#define PMAC_HD_CTL_RST		(1 << 8)
++#define PMAC_HD_CTL_AST		(1 << 7)
++#define PMAC_HD_CTL_RXSH	(1 << 6)
++#define PMAC_HD_CTL_RC		(1 << 4)
++#define PMAC_HD_CTL_AS		(1 << 3)
++#define PMAC_HD_CTL_AC		(1 << 2)
++
++#define PCE_PCTRL_0_IGSTEN	(1 << 11)
++
++#define FDMA_PCTRL_STEN		(1 << 1)
++#define FDMA_PCTRL_EN		(1 << 0)
++
++#define SDMA_PCTRL_EN		(1 << 0)
++
++#define MDIO_GLOB_CTRL_SE	(1 << 15)
++
++#define MDIO_MDC_CFG1_RES	(1 << 15)
++#define MDIO_MDC_CFG1_MCEN	(1 << 8)
++
++#define MDIO_CTRL_MBUSY		(1 << 12)
++#define MDIO_CTRL_OP_READ	(1 << 11)
++#define MDIO_CTRL_OP_WRITE	(1 << 10)
++#define MDIO_CTRL_PHYAD_SHIFT	5
++#define MDIO_CTRL_PHYAD_MASK	(0x1f << MDIO_CTRL_PHYAD_SHIFT)
++#define MDIO_CTRL_REGAD_MASK	0x1f
++
++#endif /* __VRX200_SWITCH_H__ */
+--- a/arch/mips/include/asm/asm.h
++++ b/arch/mips/include/asm/asm.h
+@@ -53,6 +53,7 @@
+ 		.align	2;                              \
+ 		.type	symbol, @function;              \
+ 		.ent	symbol, 0;                      \
++		.section .text.symbol,"x";              \
+ symbol:		.frame	sp, 0, ra
+ 
+ /*
+@@ -62,7 +63,8 @@ symbol:		.frame	sp, 0, ra
+ 		.globl	symbol;                         \
+ 		.align	2;                              \
+ 		.type	symbol, @function;              \
+-		.ent	symbol, 0;                       \
++		.ent	symbol, 0;                      \
++		.section .text.symbol,"x";              \
+ symbol:		.frame	sp, framesize, rpc
+ 
+ /*
+--- /dev/null
++++ b/arch/mips/include/asm/gpio.h
+@@ -0,0 +1,6 @@
++/*
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <asm/arch/gpio.h>
++#include <asm-generic/gpio.h>
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/chipid.h
+@@ -0,0 +1,73 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_CHIPID_H__
++#define __LANTIQ_CHIPID_H__
++
++enum ltq_chip_partnum {
++	LTQ_SOC_UNKNOWN = 0,
++	LTQ_SOC_VRX288_2 = 0x000B,	/* VRX288 v1.2 */
++	LTQ_SOC_VRX268_2 = 0x000C,	/* VRX268 v1.2 */
++	LTQ_SOC_GRX288_2 = 0x000D,	/* GRX288 v1.2 */
++	LTQ_SOC_DANUBE = 0x0129,
++	LTQ_SOC_DANUBE_S = 0x012B,
++	LTQ_SOC_TWINPASS = 0x012D,
++	LTQ_SOC_VRX288 = 0x01C0,	/* VRX288 v1.1 */
++	LTQ_SOC_VRX268 = 0x01C2,	/* VRX268 v1.1 */
++	LTQ_SOC_GRX288 = 0x01C9,	/* GRX288 v1.1 */
++};
++
++extern unsigned int ltq_chip_version_get(void);
++extern unsigned int ltq_chip_partnum_get(void);
++extern const char *ltq_chip_partnum_str(void);
++
++extern void ltq_chip_print_info(void);
++
++#ifdef CONFIG_SOC_XWAY_DANUBE
++static inline int ltq_soc_is_danube(void)
++{
++	return 1;
++}
++#else
++static inline int ltq_soc_is_danube(void)
++{
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_SOC_XWAY_VRX200
++static inline int ltq_soc_is_vrx200(void)
++{
++	return 1;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++	return ltq_chip_version_get() == 1;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++	return ltq_chip_version_get() == 2;
++}
++#else
++static inline int ltq_soc_is_vrx200(void)
++{
++	return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v1(void)
++{
++	return 0;
++}
++
++static inline int ltq_soc_is_vrx200_v2(void)
++{
++	return 0;
++}
++#endif
++
++#endif /* __LANTIQ_CHIPID_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/clk.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ * *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_CLK_H__
++#define __LANTIQ_CLK_H__
++
++/* Symbolic clock speeds */
++enum ltq_clk {
++	CLOCK_83_MHZ = 83333333,
++	CLOCK_111_MHZ = 111111111,
++	CLOCK_125_MHZ = 125000000,
++	CLOCK_133_MHZ = 133333333,
++	CLOCK_166_MHZ = 166666667,
++	CLOCK_197_MHZ = 197000000,
++	CLOCK_333_MHZ = 333333333,
++	CLOCK_393_MHZ = 393219000,
++	CLOCK_500_MHZ = 500000000,
++	CLOCK_600_MHZ = 600000000,
++	CLOCK_1000_MHZ = 1000000000,
++};
++
++extern unsigned long ltq_get_cpu_clock(void);
++extern unsigned long ltq_get_bus_clock(void);
++extern unsigned long ltq_get_io_region_clock(void);
++
++#endif /* __LANTIQ_CLK_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/config.h
+@@ -0,0 +1,164 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_CONFIG_H__
++#define __LANTIQ_CONFIG_H__
++
++/* Memory usage */
++#define CONFIG_SYS_MAXARGS		24
++#define CONFIG_SYS_MALLOC_LEN		1024*1024
++#define CONFIG_SYS_BOOTPARAMS_LEN	128*1024
++
++/* Command line */
++#define CONFIG_SYS_PROMPT		CONFIG_MACH_TYPE " # "
++#define CONFIG_SYS_CBSIZE		512
++#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
++					sizeof(CONFIG_SYS_PROMPT)+16)
++
++#define CONFIG_SYS_HUSH_PARSER
++#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
++
++/*
++ * Enable advanced console features on demand to reduce
++ * flash and RAM footprint
++ */
++#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
++#define CONFIG_SYS_LONGHELP
++#define CONFIG_AUTO_COMPLETE
++#define CONFIG_CMDLINE_EDITING
++#endif
++
++/* SPI flash SPL */
++#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_SPL
++#define CONFIG_SPL_SPI_SUPPORT
++#define CONFIG_SPL_SPI_FLASH_SUPPORT
++#define CONFIG_SPI_SPL_SIMPLE
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SPL
++#endif
++
++/* Common SPL */
++#if defined(CONFIG_SPL)
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SPL_LIBGENERIC_SUPPORT
++#define CONFIG_SPL_GPIO_SUPPORT
++#define CONFIG_SPL_START_S_PATH		\
++		"arch/mips/cpu/mips32/lantiq-common"
++#define CONFIG_SPL_LDSCRIPT		\
++		"arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
++#endif
++
++#if defined(CONFIG_LTQ_SPL_CONSOLE)
++#define CONFIG_SPL_SERIAL_SUPPORT
++#define CONFIG_SPL_LIBCOMMON_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
++#define CONFIG_LZMA
++#define CONFIG_SPL_LZMA_SUPPORT
++#endif
++
++#if defined(CONFIG_LTQ_SPL_COMP_LZO)
++#define CONFIG_LZO
++#define CONFIG_SPL_LZO_SUPPORT
++#endif
++
++/* Basic commands */
++#define CONFIG_CMD_BDI
++#define CONFIG_CMD_EDITENV
++#define CONFIG_CMD_IMI
++#define CONFIG_CMD_MEMORY
++#define CONFIG_CMD_RUN
++#define CONFIG_CMD_SAVEENV
++#define CONFIG_CMD_LOADB
++
++/* Other U-Boot settings */
++#define CONFIG_TIMESTAMP
++
++/* Default environment */
++#define CONFIG_ENV_CONSOLEDEV					\
++	"consoledev=" CONFIG_CONSOLE_DEV "\0"
++
++#define CONFIG_ENV_ADDCONSOLE					\
++	"addconsole=setenv bootargs $bootargs"			\
++	" console=$consoledev,$baudrate\0"
++
++#if defined(CONFIG_NET_DEV)
++#define CONFIG_ENV_NETDEV					\
++	"netdev=" CONFIG_NET_DEV "\0"
++#else
++#define CONFIG_ENV_NETDEV					\
++	"netdev=eth0\0"
++#endif
++
++#define CONFIG_ENV_ADDIP					\
++	"addip=setenv bootargs $bootargs"			\
++	" ip=$ipaddr:$serverip::::$netdev:off\0"
++
++#define CONFIG_ENV_ADDETH					\
++	"addeth=setenv bootargs $bootargs"			\
++	" ethaddr=$ethaddr\0"
++
++#define CONFIG_ENV_ADDMACHTYPE					\
++	"addmachtype=setenv bootargs $bootargs"			\
++	" machtype=" CONFIG_MACH_TYPE "\0"
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_ENV_WRITE_UBOOT_NOR					\
++	"write-uboot-nor="						\
++	"protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
++	"erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && "	\
++	"cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_NOR					\
++	"load-uboot-nor=tftpboot u-boot.bin\0"				\
++	"load-uboot-norspl=tftpboot u-boot.ltq.norspl\0"		\
++	"load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0"	\
++	"load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
++#else
++#define CONFIG_ENV_WRITE_UBOOT_NOR
++#define CONFIG_ENV_LOAD_UBOOT_NOR
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_ENV_SF_PROBE					\
++	"sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " "	\
++	__stringify(CONFIG_ENV_SPI_MAX_HZ) " "			\
++	__stringify(CONFIG_ENV_SPI_MODE) " \0"
++
++#define CONFIG_ENV_WRITE_UBOOT_SF				\
++	"write-uboot-sf="					\
++	"run sf-probe && sf erase 0 +$filesize && "		\
++	"sf write $fileaddr 0 $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_SF					\
++	"load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0"			\
++	"load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0"		\
++	"load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
++#else
++#define CONFIG_ENV_SF_PROBE
++#define CONFIG_ENV_WRITE_UBOOT_SF
++#define CONFIG_ENV_LOAD_UBOOT_SF
++#endif
++
++#define CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_CONSOLEDEV		\
++	CONFIG_ENV_ADDCONSOLE		\
++	CONFIG_ENV_NETDEV		\
++	CONFIG_ENV_ADDIP		\
++	CONFIG_ENV_ADDETH		\
++	CONFIG_ENV_ADDMACHTYPE		\
++	CONFIG_ENV_WRITE_UBOOT_NOR	\
++	CONFIG_ENV_LOAD_UBOOT_NOR	\
++	CONFIG_ENV_SF_PROBE		\
++	CONFIG_ENV_WRITE_UBOOT_SF	\
++	CONFIG_ENV_LOAD_UBOOT_SF
++
++#endif /* __LANTIQ_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/cpu.h
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_CPU_H__
++#define __LANTIQ_CPU_H__
++
++enum ltq_boot_select {
++	BOOT_NOR,
++	BOOT_NOR_NO_BOOTROM,
++	BOOT_UART,
++	BOOT_UART_NO_EEPROM,
++	BOOT_SPI,
++	BOOT_NAND,
++	BOOT_PCI,
++	BOOT_MII0,
++	BOOT_RMII0,
++	BOOT_RGMII1,
++	BOOT_UNKNOWN,
++};
++
++enum ltq_boot_select ltq_boot_select(void);
++const char *ltq_boot_select_str(void);
++
++void ltq_pmu_init(void);
++void ltq_ebu_init(void);
++void ltq_gpio_init(void);
++
++void ltq_pll_init(void);
++void ltq_dcdc_init(unsigned int dig_ref);
++
++#endif /* __LANTIQ_CPU_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/dma.h
+@@ -0,0 +1,94 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_DMA_H__
++#define __LANTIQ_DMA_H__
++
++enum ltq_dma_endianess {
++	LTQ_DMA_ENDIANESS_B0_B1_B2_B3,	/* No byte swapping */
++	LTQ_DMA_ENDIANESS_B1_B0_B3_B2,	/* B0B1B2B3 => B1B0B3B2 */
++	LTQ_DMA_ENDIANESS_B2_B3_B0_B1,	/* B0B1B2B3 => B2B3B0B1 */
++	LTQ_DMA_ENDIANESS_B3_B2_B1_B0,	/* B0B1B2B3 => B3B2B1B0 */
++};
++
++enum ltq_dma_burst_len {
++	LTQ_DMA_BURST_2WORDS = 1,
++	LTQ_DMA_BURST_4WORDS = 2,
++	LTQ_DMA_BURST_8WORDS = 3,
++};
++
++struct ltq_dma_desc {
++	u32 ctl;
++	u32 addr;
++};
++
++struct ltq_dma_channel {
++	struct ltq_dma_device *dev;
++	u8 chan_no;
++	u8 class;
++	u16 num_desc;
++	struct ltq_dma_desc *desc_base;
++	void *mem_base;
++	u32 dma_addr;
++};
++
++struct ltq_dma_device {
++	enum ltq_dma_endianess rx_endian_swap;
++	enum ltq_dma_endianess tx_endian_swap;
++	enum ltq_dma_burst_len rx_burst_len;
++	enum ltq_dma_burst_len tx_burst_len;
++	struct ltq_dma_channel rx_chan;
++	struct ltq_dma_channel tx_chan;
++	u8 port;
++};
++
++/**
++ * Initialize DMA hardware and driver
++ */
++void ltq_dma_init(void);
++
++/**
++ * Register given DMA client context
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_register(struct ltq_dma_device *dev);
++
++/**
++ * Reset and halt all channels related to given DMA client
++ */
++void ltq_dma_reset(struct ltq_dma_device *dev);
++void ltq_dma_enable(struct ltq_dma_device *dev);
++void ltq_dma_disable(struct ltq_dma_device *dev);
++
++/**
++ * Map RX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
++
++/**
++ * Check if new data is available.
++ *
++ * @returns length of received data, 0 otherwise
++ */
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
++
++/**
++ * Map TX DMA descriptor to memory region
++ *
++ * @returns 0 on success, negative value otherwise
++ */
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++			unsigned long timeout);
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++			unsigned long timeout);
++
++#endif /* __LANTIQ_DMA_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/eth.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_ETH_H__
++#define __LANTIQ_ETH_H__
++
++#include <phy.h>
++
++enum LTQ_ETH_PORT_FLAGS {
++	LTQ_ETH_PORT_NONE	= 0,
++	LTQ_ETH_PORT_PHY	= 1,
++	LTQ_ETH_PORT_SWITCH	= (1 << 1),
++	LTQ_ETH_PORT_MAC	= (1 << 2),
++};
++
++struct ltq_eth_port_config {
++	u8 num;
++	u8 phy_addr;
++	u16 flags;
++	phy_interface_t phy_if;
++	u8 rgmii_rx_delay;
++	u8 rgmii_tx_delay;
++};
++
++struct ltq_eth_board_config {
++	const struct ltq_eth_port_config *ports;
++	int num_ports;
++};
++
++extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
++
++#endif /* __LANTIQ_ETH_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/gpio.h
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_GPIO_H__
++#define __LANTIQ_GPIO_H__
++
++enum ltq_gpio_dir {
++	GPIO_DIR_IN = 0,
++	GPIO_DIR_OUT
++};
++
++enum ltq_gpio_od {
++	GPIO_OD_ACTIVE = 0,
++	GPIO_OD_NORMAL
++};
++
++enum ltq_gpio_altsel {
++	GPIO_ALTSEL_CLR = 0,
++	GPIO_ALTSEL_SET
++};
++
++extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
++extern int gpio_set_opendrain(unsigned gpio, int od);
++
++static inline int gpio_to_port(unsigned gpio)
++{
++	return gpio >> 4;
++}
++
++static inline int gpio_to_pin(unsigned gpio)
++{
++	return gpio & 0xF;
++}
++
++static inline int gpio_to_bit(unsigned gpio)
++{
++	return 1 << gpio_to_pin(gpio);
++}
++
++static inline int gpio_to_gpio(unsigned port, unsigned pin)
++{
++	return (port << 4) | (pin & 0xF);
++}
++
++#include <asm-generic/gpio.h>
++
++#endif /* __LANTIQ_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/io.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_IO_H__
++#define __LANTIQ_IO_H__
++
++#include <asm/io.h>
++
++#define ltq_readb(a)		__raw_readb(a)
++#define ltq_writeb(a, v)	__raw_writeb(v, a)
++
++#define ltq_readl(a)		__raw_readl(a)
++#define ltq_writel(a, v)	__raw_writel(v, a)
++
++#define ltq_clrbits(a, clear) \
++	ltq_writel(a, ltq_readl(a) & ~(clear))
++
++#define ltq_setbits(a, set) \
++	ltq_writel(a, ltq_readl(a) | (set))
++
++#define ltq_clrsetbits(a, clear, set) \
++	ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
++
++static inline void ltq_reg_dump(const void *addr, const char *desc)
++{
++	u32 data;
++
++	data = ltq_readl(addr);
++	printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
++		desc, addr, data);
++}
++
++#endif /* __LANTIQ_IO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/pm.h
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_PM_H__
++#define __LANTIQ_PM_H__
++
++enum ltq_pm_modules {
++	LTQ_PM_CORE,
++	LTQ_PM_DMA,
++	LTQ_PM_ETH,
++	LTQ_PM_SPI,
++};
++
++u32 ltq_pm_map(enum ltq_pm_modules module);
++int ltq_pm_enable(enum ltq_pm_modules module);
++int ltq_pm_disable(enum ltq_pm_modules module);
++
++#endif /* __LANTIQ_PM_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/lantiq/reset.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __LANTIQ_RESET_H__
++#define __LANTIQ_RESET_H__
++
++enum ltq_reset_modules {
++	LTQ_RESET_CORE,
++	LTQ_RESET_DMA,
++	LTQ_RESET_ETH,
++	LTQ_RESET_PHY,
++	LTQ_RESET_HARD,
++	LTQ_RESET_SOFT,
++};
++
++extern u32 ltq_reset_map(enum ltq_reset_modules module);
++extern int ltq_reset_activate(enum ltq_reset_modules module);
++extern int ltq_reset_deactivate(enum ltq_reset_modules module);
++
++static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
++{
++	int ret;
++
++	ret = ltq_reset_activate(module);
++	if (ret)
++		return ret;
++
++	__udelay(usec);
++	ret = ltq_reset_deactivate(module);
++
++	return ret;
++}
++
++#endif /* __LANTIQ_RESET_H__ */
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -46,7 +46,10 @@
+ #define CP0_ENTRYLO1 $3
+ #define CP0_CONF $3
+ #define CP0_CONTEXT $4
++#define CP0_CONTEXTCONFIG $4,1
++#define CP0_USERLOCAL $4,1
+ #define CP0_PAGEMASK $5
++#define CP0_PAGEGRAIN $5,1
+ #define CP0_WIRED $6
+ #define CP0_INFO $7
+ #define CP0_BADVADDR $8
+@@ -54,10 +57,19 @@
+ #define CP0_ENTRYHI $10
+ #define CP0_COMPARE $11
+ #define CP0_STATUS $12
++#define CP0_INTCTL $12,1
++#define CP0_SRSCTL $12,2
++#define CP0_SRSMAP $12,3
++#define CP0_SRSHIGH $12,4
+ #define CP0_CAUSE $13
+ #define CP0_EPC $14
+ #define CP0_PRID $15
++#define CP0_EBASE $15,1
+ #define CP0_CONFIG $16
++#define CP0_CONFIG1 $16,1
++#define CP0_CONFIG2 $16,2
++#define CP0_CONFIG3 $16,3
++#define CP0_CONFIG7 $16,7
+ #define CP0_LLADDR $17
+ #define CP0_WATCHLO $18
+ #define CP0_WATCHHI $19
+@@ -70,7 +82,17 @@
+ #define CP0_ECC $26
+ #define CP0_CACHEERR $27
+ #define CP0_TAGLO $28
++#define CP0_ITAGLO $28
++#define CP0_IDATALO $28,1
++#define CP0_DTAGLO $28,2
++#define CP0_DDATALO $28,3
++#define CP0_L23TAGLO $28,4
++#define CP0_L23DATALO $28,5
+ #define CP0_TAGHI $29
++#define CP0_IDATAHI $29,1
++#define CP0_DTAGHI $29,2
++#define CP0_L23TAGHI $29,4
++#define CP0_L23DATAHI $29,5
+ #define CP0_ERROREPC $30
+ #define CP0_DESAVE $31
+ 
+@@ -395,6 +417,12 @@
+ #define  CAUSEF_BD		(_ULCAST_(1)   << 31)
+ 
+ /*
++ * Bits in the coprocessor 0 EBase register.
++ */
++#define EBASEB_CPUNUM		0
++#define EBASEF_CPUNUM		(_ULCAST_(1023))
++
++/*
+  * Bits in the coprocessor 0 config register.
+  */
+ /* Generic bits.  */
+--- a/arch/mips/include/asm/u-boot-mips.h
++++ b/arch/mips/include/asm/u-boot-mips.h
+@@ -23,3 +23,4 @@ static inline unsigned long image_copy_e
+ }
+ 
+ extern int incaip_set_cpuclk(void);
++extern int arch_cpu_init(void);
+--- a/arch/mips/lib/board.c
++++ b/arch/mips/lib/board.c
+@@ -33,6 +33,16 @@ static char *failed = "*** failed ***\n"
+  */
+ const unsigned long mips_io_port_base = -1;
+ 
++int __arch_cpu_init(void)
++{
++	/*
++	 * Nothing to do in this dummy implementation
++	 */
++	return 0;
++}
++int arch_cpu_init(void)
++	__attribute__((weak, alias("__arch_cpu_init")));
++
+ int __board_early_init_f(void)
+ {
+ 	/*
+@@ -106,6 +116,7 @@ static int init_baudrate(void)
+ typedef int (init_fnc_t)(void);
+ 
+ init_fnc_t *init_sequence[] = {
++	arch_cpu_init,
+ 	board_early_init_f,
+ 	timer_init,
+ 	env_init,		/* initialize environment */
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -12,6 +12,7 @@ LIB	:= $(obj)libdma.o
+ COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
+ COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
+ COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
++COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
+ COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
+ 
+ COBJS	:= $(COBJS-y)
+--- /dev/null
++++ b/drivers/dma/lantiq_dma.c
+@@ -0,0 +1,387 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <linux/compiler.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/dma.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/arch/soc.h>
++#include <asm/processor.h>
++
++#define DMA_CTRL_PKTARB			(1 << 31)
++#define DMA_CTRL_MBRSTARB		(1 << 30)
++#define DMA_CTRL_MBRSTCNT_SHIFT		16
++#define DMA_CTRL_MBRSTCNT_MASK		(0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
++#define DMA_CTRL_DRB			(1 << 8)
++#define DMA_CTRL_RESET			(1 << 0)
++
++#define DMA_CPOLL_EN			(1 << 31)
++#define DMA_CPOLL_CNT_SHIFT		4
++#define DMA_CPOLL_CNT_MASK		(0xFFF << DMA_CPOLL_CNT_SHIFT)
++
++#define DMA_CCTRL_TXWGT_SHIFT		16
++#define DMA_CCTRL_TXWGT_MASK		(0x3 << DMA_CCTRL_TXWGT_SHIFT)
++#define DMA_CCTRL_CLASS_SHIFT		9
++#define DMA_CCTRL_CLASS_MASK		(0x3 << DMA_CCTRL_CLASS_SHIFT)
++#define DMA_CCTRL_RST			(1 << 1)
++#define DMA_CCTRL_ONOFF			(1 << 0)
++
++#define DMA_PCTRL_TXBL_SHIFT		4
++#define DMA_PCTRL_TXBL_2WORDS		(1 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_4WORDS		(2 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_TXBL_8WORDS		(3 << DMA_PCTRL_TXBL_SHIFT)
++#define DMA_PCTRL_RXBL_SHIFT		2
++#define DMA_PCTRL_RXBL_2WORDS		(1 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_4WORDS		(2 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_RXBL_8WORDS		(3 << DMA_PCTRL_RXBL_SHIFT)
++#define DMA_PCTRL_TXENDI_SHIFT		10
++#define DMA_PCTRL_TXENDI_MASK		(0x3 << DMA_PCTRL_TXENDI_SHIFT)
++#define DMA_PCTRL_RXENDI_SHIFT		8
++#define DMA_PCTRL_RXENDI_MASK		(0x3 << DMA_PCTRL_RXENDI_SHIFT)
++
++#define DMA_DESC_OWN			(1 << 31)
++#define DMA_DESC_C			(1 << 30)
++#define DMA_DESC_SOP			(1 << 29)
++#define DMA_DESC_EOP			(1 << 28)
++#define DMA_DESC_TX_OFFSET(x)		((x & 0x1f) << 23)
++#define DMA_DESC_RX_OFFSET(x)		((x & 0x3) << 23)
++#define DMA_DESC_LENGTH(x)		(x & 0xffff)
++
++#define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))
++
++struct ltq_dma_regs {
++	u32	clc;		/* Clock control */
++	u32	rsvd0;
++	u32	id;		/* Identification */
++	u32	rsvd1;
++	u32	ctrl;		/* Control */
++	u32	cpoll;		/* Channel polling */
++	u32	cs;		/* Channel select */
++	u32	cctrl;		/* Channel control */
++	u32	cdba;		/* Channel descriptor base address */
++	u32	cdlen;		/* Channel descriptor length */
++	u32	cis;		/* Channel interrupt status */
++	u32	cie;		/* Channel interrupt enable */
++	u32	cgbl;		/* Channel global buffer length */
++	u32	cdptnrd;	/* Current descriptor pointer */
++	u32	rsvd2[2];
++	u32	ps;		/* Port select */
++	u32	pctrl;		/* Port control */
++	u32	rsvd3[43];
++	u32	irnen;		/* Interrupt node enable */
++	u32	irncr;		/* Interrupt node control */
++	u32	irnicr;		/* Interrupt capture */
++};
++
++static struct ltq_dma_regs *ltq_dma_regs =
++	(struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
++
++static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
++{
++	return KSEG0ADDR(dma_addr);
++}
++
++static inline u32 ltq_virt_to_dma_addr(void *addr)
++{
++	return CPHYSADDR(addr);
++}
++
++static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
++{
++	switch (burst_len) {
++	case LTQ_DMA_BURST_2WORDS:
++		return 2 * 4;
++	case LTQ_DMA_BURST_4WORDS:
++		return 4 * 4;
++	case LTQ_DMA_BURST_8WORDS:
++		return 8 * 4;
++	}
++
++	return 0;
++}
++
++static inline void ltq_dma_sync(void)
++{
++	__asm__ __volatile__("sync");
++}
++
++static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
++{
++	unsigned long addr = (unsigned long) ptr;
++
++	flush_dcache_range(addr, addr + size);
++	ltq_dma_sync();
++}
++
++static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
++{
++	unsigned long addr = (unsigned long) ptr;
++
++	invalidate_dcache_range(addr, addr + size);
++}
++
++void ltq_dma_init(void)
++{
++	/* Power up DMA */
++	ltq_pm_enable(LTQ_PM_DMA);
++
++	/* Reset DMA */
++	ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_RESET);
++
++	/* Disable and clear all interrupts */
++	ltq_writel(&ltq_dma_regs->irnen, 0);
++	ltq_writel(&ltq_dma_regs->irncr, 0xFFFFF);
++
++#if 0
++	/* Enable packet arbitration */
++	ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_PKTARB);
++#endif
++
++#if 0
++	/* Enable descriptor read back */
++	ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_DRB);
++#endif
++
++	/* Enable polling for descriptor fetching for all channels */
++	ltq_writel(&ltq_dma_regs->cpoll, DMA_CPOLL_EN |
++		(4 << DMA_CPOLL_CNT_SHIFT));
++}
++
++static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
++{
++	ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++	ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++}
++
++static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
++{
++	ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++	ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
++{
++	ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++	ltq_clrbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
++}
++
++static void ltq_dma_port_init(struct ltq_dma_device *dev)
++{
++	u32 pctrl;
++
++	pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
++	pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
++	pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
++	pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
++
++	ltq_writel(&ltq_dma_regs->ps, dev->port);
++	ltq_writel(&ltq_dma_regs->pctrl, pctrl);
++}
++
++static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
++					struct ltq_dma_channel *chan)
++{
++	size_t size;
++	void *desc_base;
++
++	size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
++			ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
++
++	chan->mem_base = malloc(size);
++	if (!chan->mem_base)
++		return 1;
++
++	memset(chan->mem_base, 0, size);
++	ltq_dma_dcache_wb_inv(chan->mem_base, size);
++
++	desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
++
++	debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
++
++	/* Align descriptor base to 8 bytes */
++	chan->desc_base = (void *) CKSEG1ADDR(desc_base);
++	chan->dma_addr = CPHYSADDR(desc_base);
++	chan->dev = dev;
++
++	debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
++
++	/* Configure hardware with location of descriptor list */
++	ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++	ltq_writel(&ltq_dma_regs->cdba, chan->dma_addr);
++	ltq_writel(&ltq_dma_regs->cdlen, chan->num_desc);
++	ltq_writel(&ltq_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
++		(chan->class << DMA_CCTRL_CLASS_SHIFT));
++	ltq_writel(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
++
++	return 0;
++}
++
++static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
++{
++	ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
++	ltq_writel(&ltq_dma_regs->cdba, 0);
++	ltq_writel(&ltq_dma_regs->cdlen, 0);
++
++	ltq_dma_channel_reset(chan);
++
++	free(chan->mem_base);
++}
++
++int ltq_dma_register(struct ltq_dma_device *dev)
++{
++	int ret;
++
++	ltq_dma_port_init(dev);
++
++	ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
++	if (ret)
++		return ret;
++
++	ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
++	if (ret) {
++		ltq_dma_free_descriptors(&dev->rx_chan);
++		return ret;
++	}
++
++	return 0;
++}
++
++void ltq_dma_reset(struct ltq_dma_device *dev)
++{
++	ltq_dma_channel_reset(&dev->rx_chan);
++	ltq_dma_channel_reset(&dev->tx_chan);
++}
++
++void ltq_dma_enable(struct ltq_dma_device *dev)
++{
++	ltq_dma_channel_enable(&dev->rx_chan);
++	ltq_dma_channel_enable(&dev->tx_chan);
++}
++
++void ltq_dma_disable(struct ltq_dma_device *dev)
++{
++	ltq_dma_channel_disable(&dev->rx_chan);
++	ltq_dma_channel_disable(&dev->tx_chan);
++}
++
++int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
++{
++	struct ltq_dma_channel *chan = &dev->rx_chan;
++	struct ltq_dma_desc *desc = &chan->desc_base[index];
++	u32 dma_addr = ltq_virt_to_dma_addr(data);
++	unsigned int offset;
++
++	offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++	ltq_dma_dcache_inv(data, len);
++
++#if 0
++	printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
++		__func__, index, data, dma_addr, offset, len);
++#endif
++
++
++	desc->addr = dma_addr - offset;
++	desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
++			DMA_DESC_LENGTH(len);
++
++#if 0
++	printf("%s: index %d, desc %p, desc->ctl %08x\n",
++		__func__, index, desc, desc->ctl);
++#endif
++
++	return 0;
++}
++
++int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
++{
++	struct ltq_dma_channel *chan = &dev->rx_chan;
++	struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++#if 0
++	printf("%s: index %d, desc %p, desc->ctl %08x\n",
++		__func__, index, desc, desc->ctl);
++#endif
++
++	if (desc->ctl & DMA_DESC_OWN)
++		return 0;
++
++	if (desc->ctl & DMA_DESC_C)
++		return 1;
++
++	return 0;
++}
++
++int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
++{
++	struct ltq_dma_channel *chan = &dev->rx_chan;
++	struct ltq_dma_desc *desc = &chan->desc_base[index];
++
++	return DMA_DESC_LENGTH(desc->ctl);
++}
++
++int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
++			unsigned long timeout)
++{
++	struct ltq_dma_channel *chan = &dev->tx_chan;
++	struct ltq_dma_desc *desc = &chan->desc_base[index];
++	unsigned int offset;
++	unsigned long timebase = get_timer(0);
++	u32 dma_addr = ltq_virt_to_dma_addr(data);
++
++	while (desc->ctl & DMA_DESC_OWN) {
++		WATCHDOG_RESET();
++
++		if (get_timer(timebase) >= timeout) {
++#if 0
++			printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
++				__func__, index, desc, desc->ctl);
++#endif
++			return -1;
++		}
++	}
++
++	offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
++
++#if 0
++	printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
++		__func__, index, desc, data, dma_addr, offset, len);
++#endif
++
++	ltq_dma_dcache_wb_inv(data, len);
++
++	desc->addr = dma_addr - offset;
++	desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
++			DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
++
++#if 0
++	printf("%s: index %d, desc %p, desc->ctl %08x\n",
++		__func__, index, desc, desc->ctl);
++#endif
++
++	return 0;
++}
++
++int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
++			unsigned long timeout)
++{
++	struct ltq_dma_channel *chan = &dev->tx_chan;
++	struct ltq_dma_desc *desc = &chan->desc_base[index];
++	unsigned long timebase = get_timer(0);
++
++	while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
++		WATCHDOG_RESET();
++
++		if (get_timer(timebase) >= timeout)
++			return -1;
++	}
++
++	return 0;
++}
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -12,6 +12,7 @@ LIB 	:= $(obj)libgpio.o
+ COBJS-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
+ COBJS-$(CONFIG_INTEL_ICH6_GPIO)	+= intel_ich6_gpio.o
+ COBJS-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
++COBJS-$(CONFIG_LANTIQ_GPIO)	+= lantiq_gpio.o
+ COBJS-$(CONFIG_MARVELL_GPIO)	+= mvgpio.o
+ COBJS-$(CONFIG_MARVELL_MFP)	+= mvmfp.o
+ COBJS-$(CONFIG_MXC_GPIO)	+= mxc_gpio.o
+--- /dev/null
++++ b/drivers/gpio/lantiq_gpio.c
+@@ -0,0 +1,329 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/gpio.h>
++#include <asm/lantiq/io.h>
++
++#define SSIO_GPIO_BASE		64
++
++#define SSIO_CON0_SWU		(1 << 31)
++#define SSIO_CON0_RZFL		(1 << 26)
++#define SSIO_CON0_GPHY1_SHIFT	27
++#define SSIO_CON0_GPHY1_CONFIG	((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
++
++#define SSIO_CON1_US_FPI	(2 << 30)
++#define SSIO_CON1_FPID_2HZ	(0 << 23)
++#define SSIO_CON1_FPID_4HZ	(1 << 23)
++#define SSIO_CON1_FPID_8HZ	(2 << 23)
++#define SSIO_CON1_FPID_10HZ	(3 << 23)
++#define SSIO_CON1_FPIS_1_2	(1 << 20)
++#define SSIO_CON1_FPIS_1_32	(2 << 20)
++#define SSIO_CON1_FPIS_1_64	(3 << 20)
++
++#define SSIO_CON1_GPHY2_SHIFT	15
++#define SSIO_CON1_GPHY2_CONFIG	((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
++
++#define SSIO_CON1_GROUP2	(1 << 2)
++#define SSIO_CON1_GROUP1	(1 << 1)
++#define SSIO_CON1_GROUP0	(1 << 0)
++#define SSIO_CON1_GROUP_CONFIG	(0x3)
++
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++#define enable_ssio	1
++#else
++#define enable_ssio	0
++
++#define CONFIG_LTQ_SSIO_GPHY1_MODE	0
++#define CONFIG_LTQ_SSIO_GPHY2_MODE	0
++#define CONFIG_LTQ_SSIO_INIT_VALUE	0
++#endif
++
++#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
++#define SSIO_RZFL_CONFIG	SSIO_CON0_RZFL
++#else
++#define SSIO_RZFL_CONFIG	0
++#endif
++
++struct ltq_gpio_port_regs {
++	__be32	out;
++	__be32	in;
++	__be32	dir;
++	__be32	altsel0;
++	__be32	altsel1;
++	__be32	od;
++	__be32	stoff;
++	__be32	pudsel;
++	__be32	puden;
++	__be32	rsvd1[3];
++};
++
++struct ltq_gpio_regs {
++	u32				rsvd[4];
++	struct ltq_gpio_port_regs	ports[CONFIG_LTQ_GPIO_MAX_BANKS];
++};
++
++struct ltq_gpio3_regs {
++	u32	rsvd0[13];
++	__be32	od;
++	__be32	pudsel;
++	__be32	puden;
++	u32	rsvd1[9];
++	__be32	altsel1;
++	u32	rsvd2[14];
++	__be32	out;
++	__be32	in;
++	__be32	dir;
++	__be32	altsel0;
++};
++
++struct ltq_ssio_regs {
++	__be32	con0;
++	__be32	con1;
++	__be32	cpu0;
++	__be32	cpu1;
++	__be32	ar;
++};
++
++static struct ltq_gpio_regs *ltq_gpio_regs =
++	(struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_gpio3_regs *ltq_gpio3_regs =
++	(struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
++
++static struct ltq_ssio_regs *ltq_ssio_regs =
++	(struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
++
++static int is_gpio_bank3(unsigned int port)
++{
++#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
++	return port == 3;
++#else
++	return 0;
++#endif
++}
++
++static int is_gpio_ssio(unsigned int gpio)
++{
++#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
++	return gpio >= SSIO_GPIO_BASE;
++#else
++	return 0;
++#endif
++}
++
++static inline int ssio_gpio_to_bit(unsigned gpio)
++{
++	return 1 << (gpio - SSIO_GPIO_BASE);
++}
++
++int ltq_gpio_init(void)
++{
++	ltq_writel(&ltq_ssio_regs->ar, 0);
++	ltq_writel(&ltq_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
++	ltq_writel(&ltq_ssio_regs->cpu1, 0);
++	ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_SWU);
++
++	if (enable_ssio) {
++		ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
++			SSIO_RZFL_CONFIG);
++		ltq_writel(&ltq_ssio_regs->con1, SSIO_CON1_US_FPI |
++			SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
++			SSIO_CON1_GROUP_CONFIG);
++	}
++
++	return 0;
++}
++
++int gpio_request(unsigned gpio, const char *label)
++{
++	return 0;
++}
++
++int gpio_free(unsigned gpio)
++{
++	return 0;
++}
++
++int gpio_direction_input(unsigned gpio)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++	const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++	const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++	const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++	if (is_gpio_ssio(gpio))
++		return 0;
++
++	if (is_gpio_bank3(port)) {
++		gpio_od = &ltq_gpio3_regs->od;
++		gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++		gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++		gpio_dir = &ltq_gpio3_regs->dir;
++	}
++
++	/*
++	 * Reset open drain and altsel configs to workaround improper
++	 * reset values or unwanted modifications by BootROM
++	 */
++	ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++	ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++	ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++	/* Switch to input */
++	ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++
++	return 0;
++}
++
++int gpio_direction_output(unsigned gpio, int value)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++	const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++	const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++	const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++	const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++	u32 data = gpio_to_bit(gpio);
++
++	if (is_gpio_ssio(gpio)) {
++		data = ssio_gpio_to_bit(gpio);
++		if (value)
++			ltq_setbits(&ltq_ssio_regs->cpu0, data);
++		else
++			ltq_clrbits(&ltq_ssio_regs->cpu0, data);
++
++		return 0;
++	}
++
++	if (is_gpio_bank3(port)) {
++		gpio_od = &ltq_gpio3_regs->od;
++		gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++		gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++		gpio_dir = &ltq_gpio3_regs->dir;
++		gpio_out = &ltq_gpio3_regs->out;
++	}
++
++	/*
++	 * Reset open drain and altsel configs to workaround improper
++	 * reset values or unwanted modifications by BootROM
++	 */
++	ltq_setbits(gpio_od, data);
++	ltq_clrbits(gpio_altsel0, data);
++	ltq_clrbits(gpio_altsel1, data);
++
++	if (value)
++		ltq_setbits(gpio_out, data);
++	else
++		ltq_clrbits(gpio_out, data);
++
++	/* Switch to output */
++	ltq_setbits(gpio_dir, data);
++
++	return 0;
++}
++
++int gpio_get_value(unsigned gpio)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_in = &ltq_gpio_regs->ports[port].in;
++	u32 data = gpio_to_bit(gpio);
++	u32 val;
++
++	if (is_gpio_ssio(gpio)) {
++		gpio_in = &ltq_ssio_regs->cpu0;
++		data = ssio_gpio_to_bit(gpio);
++	}
++
++	if (is_gpio_bank3(port))
++		gpio_in = &ltq_gpio3_regs->in;
++
++	val = ltq_readl(gpio_in);
++
++	return !!(val & data);
++}
++
++int gpio_set_value(unsigned gpio, int value)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_out = &ltq_gpio_regs->ports[port].out;
++	u32 data = gpio_to_bit(gpio);
++
++	if (is_gpio_ssio(gpio)) {
++		gpio_out = &ltq_ssio_regs->cpu0;
++		data = ssio_gpio_to_bit(gpio);
++	}
++
++	if (is_gpio_bank3(port))
++		gpio_out = &ltq_gpio3_regs->out;
++
++	if (value)
++		ltq_setbits(gpio_out, data);
++	else
++		ltq_clrbits(gpio_out, data);
++
++	return 0;
++}
++
++int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++	const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
++	const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
++	const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
++
++	if (is_gpio_ssio(gpio))
++		return 0;
++
++	if (is_gpio_bank3(port)) {
++		gpio_od = &ltq_gpio3_regs->od;
++		gpio_altsel0 = &ltq_gpio3_regs->altsel0;
++		gpio_altsel1 = &ltq_gpio3_regs->altsel1;
++		gpio_dir = &ltq_gpio3_regs->dir;
++	}
++
++	if (altsel0)
++		ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
++	else
++		ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
++
++	if (altsel1)
++		ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
++	else
++		ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
++
++	if (dir) {
++		ltq_setbits(gpio_od, gpio_to_bit(gpio));
++		ltq_setbits(gpio_dir, gpio_to_bit(gpio));
++	} else {
++		ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++		ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
++	}
++
++	return 0;
++}
++
++int gpio_set_opendrain(unsigned gpio, int od)
++{
++	unsigned port = gpio_to_port(gpio);
++	const void *gpio_od = &ltq_gpio_regs->ports[port].od;
++
++	if (is_gpio_ssio(gpio))
++		return 0;
++
++	if (is_gpio_bank3(port))
++		gpio_od = &ltq_gpio3_regs->od;
++
++	if (od)
++		ltq_setbits(gpio_od, gpio_to_bit(gpio));
++	else
++		ltq_clrbits(gpio_od, gpio_to_bit(gpio));
++
++	return 0;
++}
+--- a/drivers/mtd/cfi_flash.c
++++ b/drivers/mtd/cfi_flash.c
+@@ -161,6 +161,18 @@ u64 flash_read64(void *addr)__attribute_
+ #define flash_read64	__flash_read64
+ #endif
+ 
++static inline void *__flash_swap_addr(unsigned long addr)
++{
++	return (void *) addr;
++}
++
++#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++void *flash_swap_addr(unsigned long addr)
++		__attribute__((weak, alias("__flash_swap_addr")));
++#else
++#define flash_swap_addr	__flash_swap_addr
++#endif
++
+ /*-----------------------------------------------------------------------
+  */
+ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
+@@ -196,7 +208,7 @@ flash_map (flash_info_t * info, flash_se
+ {
+ 	unsigned int byte_offset = offset * info->portwidth;
+ 
+-	return (void *)(info->start[sect] + byte_offset);
++	return flash_swap_addr(info->start[sect] + byte_offset);
+ }
+ 
+ static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -53,6 +53,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na
+ COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
+ COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
+ COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
++COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
+ COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
+ COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
+ COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
+--- /dev/null
++++ b/drivers/mtd/nand/lantiq_nand.c
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <linux/mtd/nand.h>
++#include <linux/compiler.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/nand.h>
++#include <asm/lantiq/io.h>
++
++#define NAND_CON_ECC_ON		(1 << 31)
++#define NAND_CON_LATCH_PRE	(1 << 23)
++#define NAND_CON_LATCH_WP	(1 << 22)
++#define NAND_CON_LATCH_SE	(1 << 21)
++#define NAND_CON_LATCH_CS	(1 << 20)
++#define NAND_CON_LATCH_CLE	(1 << 19)
++#define NAND_CON_LATCH_ALE	(1 << 18)
++#define NAND_CON_OUT_CS1	(1 << 10)
++#define NAND_CON_IN_CS1		(1 << 8)
++#define NAND_CON_PRE_P		(1 << 7)
++#define NAND_CON_WP_P		(1 << 6)
++#define NAND_CON_SE_P		(1 << 5)
++#define NAND_CON_CS_P		(1 << 4)
++#define NAND_CON_CLE_P		(1 << 3)
++#define NAND_CON_ALE_P		(1 << 2)
++#define NAND_CON_CSMUX		(1 << 1)
++#define NAND_CON_NANDM		(1 << 0)
++
++#define NAND_WAIT_WR_C		(1 << 3)
++#define NAND_WAIT_RDBY		(1 << 0)
++
++#define NAND_CMD_ALE		(1 << 2)
++#define NAND_CMD_CLE		(1 << 3)
++#define NAND_CMD_CS		(1 << 4)
++#define NAND_CMD_SE		(1 << 5)
++#define NAND_CMD_WP		(1 << 6)
++#define NAND_CMD_PRE		(1 << 7)
++
++struct ltq_nand_regs {
++	__be32	con;		/* NAND controller control */
++	__be32	wait;		/* NAND Flash Device RD/BY State */
++	__be32	ecc0;		/* NAND Flash ECC Register 0 */
++	__be32	ecc_ac;		/* NAND Flash ECC Register address counter */
++	__be32	ecc_cr;		/* NAND Flash ECC Comparison */
++};
++
++static struct ltq_nand_regs *ltq_nand_regs =
++	(struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
++
++static void ltq_nand_wait_ready(void)
++{
++	while ((ltq_readl(&ltq_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
++		;
++}
++
++static int ltq_nand_dev_ready(struct mtd_info *mtd)
++{
++	u32 data = ltq_readl(&ltq_nand_regs->wait);
++	return data & NAND_WAIT_RDBY;
++}
++
++static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++	if (chip == 0) {
++		ltq_setbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++		ltq_setbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++	} else {
++		ltq_clrbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
++		ltq_clrbits(&ltq_nand_regs->con, NAND_CON_NANDM);
++	}
++}
++
++static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++	struct nand_chip *chip = mtd->priv;
++	unsigned long addr = (unsigned long) chip->IO_ADDR_W;
++
++	if (ctrl & NAND_CTRL_CHANGE) {
++		if (ctrl & NAND_ALE)
++			addr |= NAND_CMD_ALE;
++		else
++			addr &= ~NAND_CMD_ALE;
++
++		if (ctrl & NAND_CLE)
++			addr |= NAND_CMD_CLE;
++		else
++			addr &= ~NAND_CMD_CLE;
++
++		chip->IO_ADDR_W = (void __iomem *) addr;
++	}
++
++	if (cmd != NAND_CMD_NONE) {
++		writeb(cmd, chip->IO_ADDR_W);
++		ltq_nand_wait_ready();
++	}
++}
++
++int ltq_nand_init(struct nand_chip *nand)
++{
++	/* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
++	ltq_writel(&ltq_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
++		NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
++		NAND_CON_CS_P | NAND_CON_CSMUX);
++
++	nand->dev_ready = ltq_nand_dev_ready;
++	nand->select_chip = ltq_nand_select_chip;
++	nand->cmd_ctrl = ltq_nand_cmd_ctrl;
++
++	nand->chip_delay = 30;
++	nand->options = 0;
++	nand->ecc.mode = NAND_ECC_SOFT;
++
++	/* Enable CS bit in address offset */
++	nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
++	nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
++
++	return 0;
++}
++
++__weak int board_nand_init(struct nand_chip *chip)
++{
++	return ltq_nand_init(chip);
++}
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -37,6 +37,8 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-i
+ COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
+ COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
+ COBJS-$(CONFIG_LAN91C96) += lan91c96.o
++COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
++COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
+ COBJS-$(CONFIG_MACB) += macb.o
+ COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+ COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
+--- /dev/null
++++ b/drivers/net/lantiq_danube_etop.c
+@@ -0,0 +1,410 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PPE_ETOP_MDIO_ACC_RA	(1 << 31)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM1	(1 << 2)
++#define LTQ_PPE_ETOP_MDIO_CFG_UMM0	(1 << 1)
++
++#define LTQ_PPE_ETOP_CFG_TCKINV1	(1 << 11)
++#define LTQ_PPE_ETOP_CFG_TCKINV0	(1 << 10)
++#define LTQ_PPE_ETOP_CFG_FEN1		(1 << 9)
++#define LTQ_PPE_ETOP_CFG_FEN0		(1 << 8)
++#define LTQ_PPE_ETOP_CFG_SEN1		(1 << 7)
++#define LTQ_PPE_ETOP_CFG_SEN0		(1 << 6)
++#define LTQ_PPE_ETOP_CFG_TURBO1		(1 << 5)
++#define LTQ_PPE_ETOP_CFG_REMII1		(1 << 4)
++#define LTQ_PPE_ETOP_CFG_OFF1		(1 << 3)
++#define LTQ_PPE_ETOP_CFG_TURBO0		(1 << 2)
++#define LTQ_PPE_ETOP_CFG_REMII0		(1 << 1)
++#define LTQ_PPE_ETOP_CFG_OFF0		(1 << 0)
++
++#define LTQ_PPE_ENET0_MAC_CFG_CGEN	(1 << 11)
++#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX	(1 << 2)
++#define LTQ_PPE_ENET0_MAC_CFG_SPEED	(1 << 1)
++#define LTQ_PPE_ENET0_MAC_CFG_LINK	(1 << 0)
++
++#define LTQ_PPE_ENETS0_CFG_FTUC		(1 << 28)
++
++#define LTQ_ETH_RX_BUFFER_CNT		PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT		8
++#define LTQ_ETH_RX_DATA_SIZE		PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN		2
++
++#define LTQ_MDIO_DRV_NAME		"ltq-mdio"
++#define LTQ_ETH_DRV_NAME		"ltq-eth"
++
++struct ltq_ppe_etop_regs {
++	u32	mdio_cfg;		/* MDIO configuration */
++	u32	mdio_acc;		/* MDIO access */
++	u32	cfg;			/* ETOP configuration */
++	u32	ig_vlan_cos;		/* IG VLAN priority CoS mapping */
++	u32	ig_dscp_cos3;		/* IG DSCP CoS mapping 3 */
++	u32	ig_dscp_cos2;		/* IG DSCP CoS mapping 2 */
++	u32	ig_dscp_cos1;		/* IG DSCP CoS mapping 1 */
++	u32	ig_dscp_cos0;		/* IG DSCP CoS mapping 0 */
++	u32	ig_plen_ctrl;		/* IG frame length control */
++	u32	rsvd0[3];
++	u32	vpid;			/* VLAN protocol ID */
++};
++
++struct ltq_ppe_enet_regs {
++	u32	mac_cfg;		/* MAC configuration */
++	u32	rsvd0[3];
++	u32	ig_cfg;			/* Ingress configuration */
++	u32	ig_pgcnt;		/* Ingress buffer used page count */
++	u32	rsvd1;
++	u32	ig_buf_ctrl;		/* Ingress buffer backpressure ctrl */
++	u32	cos_cfg;		/* Classification configuration */
++	u32	ig_drop;		/* Total ingress drop frames */
++	u32	ig_err;			/* Total ingress error frames */
++	u32	mac_da0;		/* Ingress MAC address 0 */
++	u32	mac_da1;		/* Ingress MAC address 1 */
++	u32	rsvd2[22];
++	u32	pgcnt;			/* Page counter */
++	u32	rsvd3;
++	u32	hf_ctrl;		/* Half duplex control */
++	u32	tx_ctrl;		/* Transmit control */
++	u32	rsvd4;
++	u32	vlcos0;			/* VLAN insertion config CoS 0 */
++	u32	vlcos1;			/* VLAN insertion config CoS 1 */
++	u32	vlcos2;			/* VLAN insertion config CoS 2 */
++	u32	vlcos3;			/* VLAN insertion config CoS 3 */
++	u32	eg_col;			/* Total egress collision frames */
++	u32	eg_drop;		/* Total egress drop frames */
++};
++
++struct ltq_eth_priv {
++	struct ltq_dma_device dma_dev;
++	struct mii_dev *bus;
++	struct eth_device *dev;
++	int rx_num;
++	int tx_num;
++};
++
++struct ltq_mdio_access {
++	union {
++		struct {
++			unsigned ra:1;
++			unsigned rw:1;
++			unsigned rsvd:4;
++			unsigned phya:5;
++			unsigned rega:5;
++			unsigned phyd:16;
++		} reg;
++		u32 val;
++	};
++};
++
++static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
++	(struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
++
++static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
++	(struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
++
++static inline int ltq_mdio_poll(void)
++{
++	struct ltq_mdio_access acc;
++	unsigned cnt = 10000;
++
++	while (likely(cnt--)) {
++		acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++		if (!acc.reg.ra)
++			return 0;
++	}
++
++	return 1;
++}
++
++static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
++				int regnum)
++{
++	struct ltq_mdio_access acc;
++	int ret;
++
++	acc.val = 0;
++	acc.reg.ra = 1;
++	acc.reg.rw = 1;
++	acc.reg.phya = addr;
++	acc.reg.rega = regnum;
++
++	ret = ltq_mdio_poll();
++	if (ret)
++		return ret;
++
++	ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++	ret = ltq_mdio_poll();
++	if (ret)
++		return ret;
++
++	acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
++
++	return acc.reg.phyd;
++}
++
++static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
++				int regnum, u16 val)
++{
++	struct ltq_mdio_access acc;
++	int ret;
++
++	acc.val = 0;
++	acc.reg.ra = 1;
++	acc.reg.rw = 0;
++	acc.reg.phya = addr;
++	acc.reg.rega = regnum;
++	acc.reg.phyd = val;
++
++	ret = ltq_mdio_poll();
++	if (ret)
++		return ret;
++
++	ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
++
++	return 0;
++}
++
++static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
++{
++	u32 da0, da1;
++
++	da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
++		(dev->enetaddr[2] << 8) + dev->enetaddr[3];
++	da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
++
++	ltq_writel(&ltq_ppe_enet0_regs->mac_da0, da0);
++	ltq_writel(&ltq_ppe_enet0_regs->mac_da1, da1);
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++	u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++	/*
++	 * IP header needs
++	 */
++	return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	int i;
++
++	ltq_eth_write_hwaddr(dev);
++
++	for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++		ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++			LTQ_ETH_RX_DATA_SIZE);
++
++	ltq_dma_enable(dma_dev);
++
++	priv->rx_num = 0;
++	priv->tx_num = 0;
++
++	return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++	ltq_dma_reset(dma_dev);
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	int err;
++
++	/* Minimum payload length w/ CRC is 60 bytes */
++	if (length < 60)
++		length = 60;
++
++	err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++	if (err) {
++		puts("NET: timeout on waiting for TX descriptor\n");
++		return -1;
++	}
++
++	priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++	return err;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	u8 *packet;
++	int len;
++
++	if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++		return 0;
++
++#if 0
++	printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++	len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++	packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++	printf("%s: received: packet %p, len %u, rx_num %d\n",
++		__func__, packet, len, priv->rx_num);
++#endif
++
++	if (len)
++		NetReceive(packet, len);
++
++	ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++		LTQ_ETH_RX_DATA_SIZE);
++
++	priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++	return 0;
++}
++
++static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
++{
++	u32 data;
++
++	/* Power up ethernet subsystems */
++	ltq_pm_enable(LTQ_PM_ETH);
++
++	/* Reset ethernet subsystems */
++	ltq_reset_once(LTQ_RESET_ETH, 1);
++
++	/* Disable MDIO auto-detection */
++	ltq_clrbits(&ltq_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
++			LTQ_PPE_ETOP_MDIO_CFG_UMM0);
++
++	/* Enable CRC generation, Full Duplex, 100Mbps, Link up */
++	ltq_writel(&ltq_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
++			LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
++			LTQ_PPE_ENET0_MAC_CFG_SPEED |
++			LTQ_PPE_ENET0_MAC_CFG_LINK);
++
++	/* Reset ETOP cfg and disable all */
++	data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
++
++	/* Enable ENET0, enable store and fetch */
++	data &= ~LTQ_PPE_ETOP_CFG_OFF0;
++	data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
++
++	if (port->phy_if == PHY_INTERFACE_MODE_RMII)
++		data |= LTQ_PPE_ETOP_CFG_REMII0;
++	else
++		data &= ~LTQ_PPE_ETOP_CFG_REMII0;
++
++	ltq_writel(&ltq_ppe_etop_regs->cfg, data);
++
++	/* Set allowed packet length from 64 bytes to 1518 bytes */
++	ltq_writel(&ltq_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
++
++	/* Enable filter for unicast packets */
++	ltq_setbits(&ltq_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++	struct eth_device *dev;
++	struct mii_dev *bus;
++	struct ltq_eth_priv *priv;
++	struct ltq_dma_device *dma_dev;
++	const struct ltq_eth_port_config *port = &board_config->ports[0];
++	struct phy_device *phy;
++	struct switch_device *sw;
++	int ret;
++
++	ltq_dma_init();
++	ltq_eth_hw_init(port);
++
++	dev = calloc(1, sizeof(*dev));
++	if (!dev)
++		return -1;
++
++	priv = calloc(1, sizeof(*priv));
++	if (!priv)
++		return -1;
++
++	bus = mdio_alloc();
++	if (!bus)
++		return -1;
++
++	sprintf(dev->name, LTQ_ETH_DRV_NAME);
++	dev->priv = priv;
++	dev->init = ltq_eth_init;
++	dev->halt = ltq_eth_halt;
++	dev->recv = ltq_eth_recv;
++	dev->send = ltq_eth_send;
++
++	sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++	bus->read = ltq_mdio_read;
++	bus->write = ltq_mdio_write;
++	bus->priv = priv;
++
++	dma_dev = &priv->dma_dev;
++	dma_dev->port = 0;
++	dma_dev->rx_chan.chan_no = 6;
++	dma_dev->rx_chan.class = 3;
++	dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++	dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++	dma_dev->tx_chan.chan_no = 7;
++	dma_dev->tx_chan.class = 3;
++	dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++	dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++	priv->bus = bus;
++	priv->dev = dev;
++
++	ret = ltq_dma_register(dma_dev);
++	if (ret)
++		return ret;
++
++	ret = mdio_register(bus);
++	if (ret)
++		return ret;
++
++	ret = eth_register(dev);
++	if (ret)
++		return ret;
++
++	if (port->flags & LTQ_ETH_PORT_SWITCH) {
++		sw = switch_connect(bus);
++		if (!sw)
++			return -1;
++
++		switch_setup(sw);
++	}
++
++	if (port->flags & LTQ_ETH_PORT_PHY) {
++		phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
++		if (!phy)
++			return -1;
++
++		phy_config(phy);
++	}
++
++	return 0;
++}
+--- /dev/null
++++ b/drivers/net/lantiq_vrx200_switch.c
+@@ -0,0 +1,675 @@
++/*
++ * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <linux/compiler.h>
++#include <asm/gpio.h>
++#include <asm/processor.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/switch.h>
++
++#define LTQ_ETH_RX_BUFFER_CNT		PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT		8
++#define LTQ_ETH_RX_DATA_SIZE		PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN		2
++
++#define LTQ_MDIO_DRV_NAME		"ltq-mdio"
++#define LTQ_ETH_DRV_NAME		"ltq-eth"
++
++#define LTQ_ETHSW_MAX_GMAC		6
++#define LTQ_ETHSW_PMAC			6
++
++struct ltq_mdio_phy_addr_reg {
++	union {
++		struct {
++			unsigned rsvd:1;
++			unsigned lnkst:2;	/* Link status control */
++			unsigned speed:2;	/* Speed control */
++			unsigned fdup:2;	/* Full duplex control */
++			unsigned fcontx:2;	/* Flow control mode TX */
++			unsigned fconrx:2;	/* Flow control mode RX */
++			unsigned addr:5;	/* PHY address */
++		} bits;
++		u16 val;
++	};
++};
++
++enum ltq_mdio_phy_addr_lnkst {
++	LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
++	LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
++	LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
++};
++
++enum ltq_mdio_phy_addr_speed {
++	LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
++	LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
++	LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
++	LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
++};
++
++enum ltq_mdio_phy_addr_fdup {
++	LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
++	LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
++	LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
++};
++
++enum ltq_mdio_phy_addr_fcon {
++	LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
++	LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
++	LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
++};
++
++struct ltq_mii_mii_cfg_reg {
++	union {
++		struct {
++			unsigned res:1;		/* Hardware reset */
++			unsigned en:1;		/* xMII interface enable */
++			unsigned isol:1;	/* xMII interface isolate */
++			unsigned ldclkdis:1;	/* Link down clock disable */
++			unsigned rsvd:1;
++			unsigned crs:2;		/* CRS sensitivity config */
++			unsigned rgmii_ibs:1;	/* RGMII In Band status */
++			unsigned rmii:1;	/* RMII ref clock direction */
++			unsigned miirate:3;	/* xMII interface clock rate */
++			unsigned miimode:4;	/* xMII interface mode */
++		} bits;
++		u16 val;
++	};
++};
++
++enum ltq_mii_mii_cfg_miirate {
++	LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
++	LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
++	LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
++	LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
++	LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
++};
++
++enum ltq_mii_mii_cfg_miimode {
++	LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
++	LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
++	LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
++	LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
++	LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
++};
++
++struct ltq_eth_priv {
++	struct ltq_dma_device dma_dev;
++	struct mii_dev *bus;
++	struct eth_device *dev;
++	struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
++	int rx_num;
++	int tx_num;
++};
++
++static struct vr9_switch_regs *switch_regs =
++	(struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
++
++static inline void vr9_switch_sync(void)
++{
++	__asm__("sync");
++}
++
++static inline int vr9_switch_mdio_is_busy(void)
++{
++	u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
++
++	return mdio_ctrl & MDIO_CTRL_MBUSY;
++}
++
++static inline void vr9_switch_mdio_poll(void)
++{
++	while (vr9_switch_mdio_is_busy())
++		cpu_relax();
++}
++
++static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
++					int regad)
++{
++	u32 mdio_ctrl;
++	int retval;
++
++	mdio_ctrl = MDIO_CTRL_OP_READ |
++		((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++		(regad & MDIO_CTRL_REGAD_MASK);
++
++	vr9_switch_mdio_poll();
++	ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++	vr9_switch_mdio_poll();
++	retval = ltq_readl(&switch_regs->mdio.mdio_read);
++
++	return retval;
++}
++
++static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
++					int regad, u16 val)
++{
++	u32 mdio_ctrl;
++
++	mdio_ctrl = MDIO_CTRL_OP_WRITE |
++		((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++		(regad & MDIO_CTRL_REGAD_MASK);
++
++	vr9_switch_mdio_poll();
++	ltq_writel(&switch_regs->mdio.mdio_write, val);
++	ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
++
++	return 0;
++}
++
++static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
++{
++	struct ltq_mdio_phy_addr_reg phy_addr_reg;
++	struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++	phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++
++	switch (num) {
++	case 0:
++	case 1:
++	case 5:
++		mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++		break;
++	default:
++		mii_cfg_reg.val = 0;
++		break;
++	}
++
++	phy_addr_reg.bits.addr = phydev->addr;
++
++	if (phydev->link)
++		phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
++	else
++		phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++
++	switch (phydev->speed) {
++	case SPEED_1000:
++		phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
++		mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
++		break;
++	case SPEED_100:
++		phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
++		switch (mii_cfg_reg.bits.miimode) {
++		case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
++		case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
++			mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
++			break;
++		default:
++			mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
++			break;
++		}
++		break;
++	default:
++		phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++		mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++		break;
++	}
++
++	if (phydev->duplex == DUPLEX_FULL)
++		phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
++	else
++		phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++
++	ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++	switch (num) {
++	case 0:
++	case 1:
++	case 5:
++		ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++		break;
++	default:
++		break;
++	}
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++	u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++	/*
++	 * IP header needs
++	 */
++	return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	struct phy_device *phydev;
++	int i;
++
++	for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++		phydev = priv->phymap[i];
++		if (!phydev)
++			continue;
++
++		phy_startup(phydev);
++		ltq_eth_gmac_update(phydev, i);
++	}
++
++	for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++		ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++			LTQ_ETH_RX_DATA_SIZE);
++
++	ltq_dma_enable(dma_dev);
++
++	priv->rx_num = 0;
++	priv->tx_num = 0;
++
++	return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	struct phy_device *phydev;
++	int i;
++
++	ltq_dma_reset(dma_dev);
++
++	for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++		phydev = priv->phymap[i];
++		if (!phydev)
++			continue;
++
++		phy_shutdown(phydev);
++		phydev->link = 0;
++		ltq_eth_gmac_update(phydev, i);
++	}
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++
++#if 0
++	printf("%s: packet %p, len %d\n", __func__, packet, length);
++#endif
++
++	ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++	priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++	return 0;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	u8 *packet;
++	int len;
++
++	if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++		return 0;
++
++#if 0
++	printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++	len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++	packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++	printf("%s: received: packet %p, len %u, rx_num %d\n",
++		__func__, packet, len, priv->rx_num);
++#endif
++
++	if (len)
++		NetReceive(packet, len);
++
++	ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++		LTQ_ETH_RX_DATA_SIZE);
++
++	priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++	return 0;
++}
++
++static void ltq_eth_gmac_init(int num)
++{
++	struct ltq_mdio_phy_addr_reg phy_addr_reg;
++	struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++
++	/* Reset PHY status to link down */
++	phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
++	phy_addr_reg.bits.addr = num;
++	phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
++	phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
++	phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
++	ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
++
++	/* Reset and disable MII interface */
++	switch (num) {
++	case 0:
++	case 1:
++	case 5:
++		mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
++		mii_cfg_reg.bits.en = 0;
++		mii_cfg_reg.bits.res = 1;
++		mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
++		ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
++		break;
++	default:
++		break;
++	}
++
++	/*
++	 * - enable frame checksum generation
++	 * - enable padding of short frames
++	 * - disable flow control
++	 */
++	ltq_writel(to_mac_ctrl(switch_regs, num, 0),
++		MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++	vr9_switch_sync();
++}
++
++static void ltq_eth_pmac_init(void)
++{
++	/*
++	 * WAR: buffer congestion:
++	 * - shorten preambel to 1 byte
++	 * - set TX IPG to 7 bytes
++	 */
++#if 1
++	ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
++		MAC_CTRL1_SHORTPRE | 7);
++#endif
++
++	/*
++	 * WAR: systematical concept weakness ACM bug
++	 * - set maximum number of used buffer segments to 254
++	 * - soft-reset BM FSQM
++	 */
++#if 1
++	ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
++	ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++	ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
++#endif
++
++	/*
++	 * WAR: switch MAC drop bug
++	 */
++#if 1
++	ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
++	ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
++	ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
++	ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
++#endif
++
++	/*
++	 * Configure frame header control:
++	 * - enable flow control
++	 * - enable CRC check for packets from DMA to PMAC
++	 * - remove special tag from packets from PMAC to DMA
++	 * - add CRC for packets from DMA to PMAC
++	 */
++	ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
++		PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
++		PMAC_HD_CTL_RC);
++
++#if 1
++	ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
++#endif
++
++	/*
++	 * - enable frame checksum generation
++	 * - enable padding of short frames
++	 * - disable flow control
++	 */
++	ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
++		MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
++
++	vr9_switch_sync();
++}
++
++static void ltq_eth_hw_init(void)
++{
++	int i;
++
++	/* Power up ethernet and switch subsystems */
++	ltq_pm_enable(LTQ_PM_ETH);
++
++	/* Reset ethernet and switch subsystems */
++#if 0
++	ltq_reset_once(LTQ_RESET_ETH, 10);
++#endif
++
++	/* Enable switch macro */
++	ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
++
++	/* Disable MDIO auto-polling for all ports */
++	ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
++
++	/*
++	 * Enable and set MDIO management clock to 2.5 MHz. This is the
++	 * maximum clock for FE PHYs.
++	 * Formula for clock is:
++	 *
++	 *      50 MHz
++	 * x = ----------- - 1
++	 *      2 * f_MDC
++	 */
++	ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
++		MDIO_MDC_CFG1_MCEN | 5);
++
++	vr9_switch_sync();
++
++	/* Init MAC connected to CPU  */
++	ltq_eth_pmac_init();
++
++	/* Init MACs connected to external MII interfaces */
++	for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
++		ltq_eth_gmac_init(i);
++}
++
++static void ltq_eth_port_config(struct ltq_eth_priv *priv,
++					const struct ltq_eth_port_config *port)
++{
++	struct ltq_mii_mii_cfg_reg mii_cfg_reg;
++	struct phy_device *phydev;
++	int setup_gpio = 0;
++
++	switch (port->num) {
++	case 0:	/* xMII0 */
++	case 1:	/* xMII1 */
++		mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++					port->num));
++		mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++		switch (port->phy_if) {
++		case PHY_INTERFACE_MODE_MII:
++			if (port->flags & LTQ_ETH_PORT_PHY)
++				/* MII MAC mode, connected to external PHY */
++				mii_cfg_reg.bits.miimode =
++					LTQ_MII_MII_CFG_MIIMODE_MIIM;
++			else
++				/* MII PHY mode, connected to external MAC */
++				mii_cfg_reg.bits.miimode =
++					LTQ_MII_MII_CFG_MIIMODE_MIIP;
++			setup_gpio = 1;
++			break;
++		case PHY_INTERFACE_MODE_RMII:
++			if (port->flags & LTQ_ETH_PORT_PHY)
++				/* RMII MAC mode, connected to external PHY */
++				mii_cfg_reg.bits.miimode =
++					LTQ_MII_MII_CFG_MIIMODE_RMIIM;
++			else
++				/* RMII PHY mode, connected to external MAC */
++				mii_cfg_reg.bits.miimode =
++					LTQ_MII_MII_CFG_MIIMODE_RMIIP;
++			setup_gpio = 1;
++			break;
++		case PHY_INTERFACE_MODE_RGMII:
++			/* RGMII MAC mode, connected to external PHY */
++			mii_cfg_reg.bits.miimode =
++				LTQ_MII_MII_CFG_MIIMODE_RGMII;
++			setup_gpio = 1;
++
++			/* RGMII clock delays */
++			ltq_writel(to_mii_pcdu(switch_regs, port->num),
++				port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++				port->rgmii_tx_delay);
++			break;
++		default:
++			break;
++		}
++
++		ltq_writel(to_mii_miicfg(switch_regs, port->num),
++			mii_cfg_reg.val);
++		break;
++	case 2:	/* internal GPHY0 */
++	case 3:	/* internal GPHY0 */
++	case 4:	/* internal GPHY1 */
++		switch (port->phy_if) {
++		case PHY_INTERFACE_MODE_MII:
++		case PHY_INTERFACE_MODE_GMII:
++			setup_gpio = 1;
++			break;
++		default:
++			break;
++		}
++		break;
++	case 5:	/* internal GPHY1 or xMII2 */
++		mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
++					port->num));
++		mii_cfg_reg.bits.en = port->flags ? 1 : 0;
++
++		switch (port->phy_if) {
++		case PHY_INTERFACE_MODE_MII:
++			/* MII MAC mode, connected to internal GPHY */
++			mii_cfg_reg.bits.miimode =
++				LTQ_MII_MII_CFG_MIIMODE_MIIM;
++			setup_gpio = 1;
++			break;
++		case PHY_INTERFACE_MODE_RGMII:
++			/* RGMII MAC mode, connected to external PHY */
++			mii_cfg_reg.bits.miimode =
++				LTQ_MII_MII_CFG_MIIMODE_RGMII;
++			setup_gpio = 1;
++
++			/* RGMII clock delays */
++			ltq_writel(to_mii_pcdu(switch_regs, port->num),
++				port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
++				port->rgmii_tx_delay);
++			break;
++		default:
++			break;
++		}
++
++		ltq_writel(to_mii_miicfg(switch_regs, port->num),
++			mii_cfg_reg.val);
++		break;
++	default:
++		break;
++	}
++
++	/* Setup GPIOs for MII with external PHYs/MACs */
++	if (setup_gpio) {
++		/* MII/MDIO */
++		gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++					GPIO_DIR_OUT);
++		/* MII/MDC */
++		gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
++					GPIO_DIR_OUT);
++	}
++
++	/* Connect to internal/external PHYs */
++	if (port->flags & LTQ_ETH_PORT_PHY) {
++		phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
++					port->phy_if);
++		if (phydev)
++			phy_config(phydev);
++
++		priv->phymap[port->num] = phydev;
++	}
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++	struct eth_device *dev;
++	struct mii_dev *bus;
++	struct ltq_eth_priv *priv;
++	struct ltq_dma_device *dma_dev;
++	int i, ret;
++
++	build_check_vr9_registers();
++
++	ltq_dma_init();
++	ltq_eth_hw_init();
++
++	dev = calloc(1, sizeof(struct eth_device));
++	if (!dev)
++		return -1;
++
++	priv = calloc(1, sizeof(struct ltq_eth_priv));
++	if (!priv)
++		return -1;
++
++	bus = mdio_alloc();
++	if (!bus)
++		return -1;
++
++	sprintf(dev->name, LTQ_ETH_DRV_NAME);
++	dev->priv = priv;
++	dev->init = ltq_eth_init;
++	dev->halt = ltq_eth_halt;
++	dev->recv = ltq_eth_recv;
++	dev->send = ltq_eth_send;
++
++	sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++	bus->read = vr9_switch_mdio_read;
++	bus->write = vr9_switch_mdio_write;
++	bus->priv = priv;
++
++	dma_dev = &priv->dma_dev;
++	dma_dev->port = 0;
++	dma_dev->rx_chan.chan_no = 0;
++	dma_dev->rx_chan.class = 0;
++	dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++	dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++	dma_dev->tx_chan.chan_no = 1;
++	dma_dev->tx_chan.class = 0;
++	dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++	dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++	priv->bus = bus;
++	priv->dev = dev;
++
++	ret = ltq_dma_register(dma_dev);
++	if (ret)
++		return -1;
++
++	ret = mdio_register(bus);
++	if (ret)
++		return -1;
++
++	ret = eth_register(dev);
++	if (ret)
++		return -1;
++
++	for (i = 0; i < board_config->num_ports; i++)
++		ltq_eth_port_config(priv, &board_config->ports[i]);
++
++	return 0;
++}
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -20,6 +20,7 @@ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom
+ COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
+ COBJS-$(CONFIG_PHY_ET1011C) += et1011c.o
+ COBJS-$(CONFIG_PHY_ICPLUS) += icplus.o
++COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
+ COBJS-$(CONFIG_PHY_LXT) += lxt.o
+ COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
+ COBJS-$(CONFIG_PHY_MICREL) += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/lantiq.c
+@@ -0,0 +1,238 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define DEBUG
++
++#include <common.h>
++#include <miiphy.h>
++
++#define ADVERTIZE_MPD		(1 << 10)
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/*
++ * Update link status.
++ *
++ * Based on genphy_update_link in phylib.c
++ */
++static int ltq_phy_update_link(struct phy_device *phydev)
++{
++	unsigned int mii_reg;
++
++	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++	/*
++	 * If we already saw the link up, and it hasn't gone down, then
++	 * we don't need to wait for autoneg again
++	 */
++	if (phydev->link && mii_reg & BMSR_LSTATUS)
++		return 0;
++
++	if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
++		phydev->link = 0;
++		return 0;
++	} else {
++		/* Read the link a second time to clear the latched state */
++		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++		if (mii_reg & BMSR_LSTATUS)
++			phydev->link = 1;
++		else
++			phydev->link = 0;
++	}
++
++	return 0;
++}
++
++/*
++ * Update speed and duplex.
++ *
++ * Based on genphy_parse_link in phylib.c
++ */
++static int ltq_phy_parse_link(struct phy_device *phydev)
++{
++	unsigned int mii_reg;
++
++	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
++
++	/* We're using autonegotiation */
++	if (mii_reg & BMSR_ANEGCAPABLE) {
++		u32 lpa = 0;
++		u32 gblpa = 0;
++
++		/* Check for gigabit capability */
++		if (mii_reg & BMSR_ERCAP) {
++			/* We want a list of states supported by
++			 * both PHYs in the link
++			 */
++			gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
++			gblpa &= phy_read(phydev,
++					MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
++		}
++
++		/* Set the baseline so we only have to set them
++		 * if they're different
++		 */
++		phydev->speed = SPEED_10;
++		phydev->duplex = DUPLEX_HALF;
++
++		/* Check the gigabit fields */
++		if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
++			phydev->speed = SPEED_1000;
++
++			if (gblpa & PHY_1000BTSR_1000FD)
++				phydev->duplex = DUPLEX_FULL;
++
++			/* We're done! */
++			return 0;
++		}
++
++		lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
++		lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
++
++		if (lpa & (LPA_100FULL | LPA_100HALF)) {
++			phydev->speed = SPEED_100;
++
++			if (lpa & LPA_100FULL)
++				phydev->duplex = DUPLEX_FULL;
++
++		} else if (lpa & LPA_10FULL)
++			phydev->duplex = DUPLEX_FULL;
++	} else {
++		u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
++
++		phydev->speed = SPEED_10;
++		phydev->duplex = DUPLEX_HALF;
++
++		if (bmcr & BMCR_FULLDPLX)
++			phydev->duplex = DUPLEX_FULL;
++
++		if (bmcr & BMCR_SPEED1000)
++			phydev->speed = SPEED_1000;
++		else if (bmcr & BMCR_SPEED100)
++			phydev->speed = SPEED_100;
++	}
++
++	return 0;
++}
++
++static int ltq_phy_config(struct phy_device *phydev)
++{
++	u16 val;
++
++	/* Advertise as Multi-port device */
++	val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
++	val |= ADVERTIZE_MPD;
++	phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
++
++	genphy_config_aneg(phydev);
++
++	return 0;
++}
++
++static int ltq_phy_startup(struct phy_device *phydev)
++{
++	/*
++	 * Update PHY status immediately without any delays as genphy_startup
++	 * does because VRX200 switch needs to be configured dependent
++	 * on this information.
++	 */
++	ltq_phy_update_link(phydev);
++	ltq_phy_parse_link(phydev);
++
++	debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
++		phydev->addr, phydev->link, phydev->speed, phydev->duplex);
++
++	return 0;
++}
++
++static struct phy_driver xrx_11g_13_driver = {
++	.name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
++	.uid = 0x030260D0,
++	.mask = 0xFFFFFFF0,
++	.features = PHY_GBIT_FEATURES,
++	.config = ltq_phy_config,
++	.startup = ltq_phy_startup,
++	.shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_11g_14_driver = {
++	.name = "Lantiq XWAY XRX PHY11G v1.4 and later",
++	.uid = 0xd565a408,
++	.mask = 0xFFFFFFF8,
++	.features = PHY_GBIT_FEATURES,
++	.config = ltq_phy_config,
++	.startup = ltq_phy_startup,
++	.shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_22f_14_driver = {
++	.name = "Lantiq XWAY XRX PHY22F v1.4 and later",
++	.uid = 0xd565a418,
++	.mask = 0xFFFFFFF8,
++	.features = PHY_BASIC_FEATURES,
++	.config = ltq_phy_config,
++	.startup = ltq_phy_startup,
++	.shutdown = genphy_shutdown,
++};
++
++static struct phy_driver pef7071_driver = {
++	.name = "Lantiq XWAY PEF7071",
++	.uid = 0xd565a400,
++	.mask = 0xFFFFFFF8,
++	.features = PHY_GBIT_FEATURES,
++	.config = ltq_phy_config,
++	.startup = ltq_phy_startup,
++	.shutdown = genphy_shutdown,
++};
++
++static struct phy_driver xrx_genphy_driver = {
++	.name = "Generic PHY at Lantiq XWAY XRX switch",
++	.uid = 0,
++	.mask = 0,
++	.features = 0,
++	.config = genphy_config,
++	.startup = ltq_phy_startup,
++	.shutdown = genphy_shutdown,
++};
++
++int phy_lantiq_init(void)
++{
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++	xrx_11g_13_driver.config = ltq_phy_config;
++	xrx_11g_13_driver.startup = ltq_phy_startup;
++	xrx_11g_13_driver.shutdown = genphy_shutdown;
++	xrx_11g_13_driver.name += gd->reloc_off;
++
++	xrx_11g_14_driver.config = ltq_phy_config;
++	xrx_11g_14_driver.startup = ltq_phy_startup;
++	xrx_11g_14_driver.shutdown = genphy_shutdown;
++	xrx_11g_14_driver.name += gd->reloc_off;
++
++	xrx_22f_14_driver.config = ltq_phy_config;
++	xrx_22f_14_driver.startup = ltq_phy_startup;
++	xrx_22f_14_driver.shutdown = genphy_shutdown;
++	xrx_22f_14_driver.name += gd->reloc_off;
++
++	pef7071_driver.config = ltq_phy_config;
++	pef7071_driver.startup = ltq_phy_startup;
++	pef7071_driver.shutdown = genphy_shutdown;
++	pef7071_driver.name += gd->reloc_off;
++
++	xrx_genphy_driver.config = genphy_config;
++	xrx_genphy_driver.startup = ltq_phy_startup;
++	xrx_genphy_driver.shutdown = genphy_shutdown;
++	xrx_genphy_driver.name += gd->reloc_off;
++#endif
++
++	phy_register(&xrx_11g_13_driver);
++	phy_register(&xrx_11g_14_driver);
++	phy_register(&xrx_22f_14_driver);
++	phy_register(&pef7071_driver);
++	phy_register(&xrx_genphy_driver);
++
++	return 0;
++}
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -16,9 +16,10 @@
+ #include <command.h>
+ #include <miiphy.h>
+ #include <phy.h>
+-#include <errno.h>
+ #include <linux/err.h>
+ 
++DECLARE_GLOBAL_DATA_PTR;
++
+ /* Generic PHY support and helper functions */
+ 
+ /**
+@@ -440,6 +441,16 @@ static LIST_HEAD(phy_drivers);
+ 
+ int phy_init(void)
+ {
++#ifdef CONFIG_NEEDS_MANUAL_RELOC
++	INIT_LIST_HEAD(&phy_drivers);
++
++	genphy_driver.config = genphy_config;
++	genphy_driver.startup = genphy_startup;
++	genphy_driver.shutdown = genphy_shutdown;
++
++	genphy_driver.name += gd->reloc_off;
++#endif
++
+ #ifdef CONFIG_PHY_ATHEROS
+ 	phy_atheros_init();
+ #endif
+@@ -455,6 +466,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_ICPLUS
+ 	phy_icplus_init();
+ #endif
++#ifdef CONFIG_PHY_LANTIQ
++	phy_lantiq_init();
++#endif
+ #ifdef CONFIG_PHY_LXT
+ 	phy_lxt_init();
+ #endif
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -24,6 +24,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se
+ COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
+ COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
+ COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
++COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
+ COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
+ COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
+ COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
+--- a/drivers/serial/serial.c
++++ b/drivers/serial/serial.c
+@@ -160,6 +160,7 @@ serial_initfunc(sa1100_serial_initialize
+ serial_initfunc(sh_serial_initialize);
+ serial_initfunc(arm_dcc_initialize);
+ serial_initfunc(mxs_auart_initialize);
++serial_initfunc(ltq_serial_initialize);
+ 
+ /**
+  * serial_register() - Register serial driver with serial driver core
+@@ -253,6 +254,7 @@ void serial_initialize(void)
+ 	sh_serial_initialize();
+ 	arm_dcc_initialize();
+ 	mxs_auart_initialize();
++	ltq_serial_initialize();
+ 
+ 	serial_assign(default_serial_console()->name);
+ }
+--- /dev/null
++++ b/drivers/serial/serial_lantiq.c
+@@ -0,0 +1,263 @@
++/*
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <serial.h>
++#include <asm/errno.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#if CONFIG_CONSOLE_ASC == 0
++#define LTQ_ASC_BASE			LTQ_ASC0_BASE
++#else
++#define LTQ_ASC_BASE			LTQ_ASC1_BASE
++#endif
++
++#define LTQ_ASC_ID_TXFS_SHIFT		24
++#define LTQ_ASC_ID_TXFS_MASK		(0x3F << LTQ_ASC_ID_TXFS_SHIFT)
++#define LTQ_ASC_ID_RXFS_SHIFT		16
++#define LTQ_ASC_ID_RXFS_MASK		(0x3F << LTQ_ASC_ID_RXFS_SHIFT)
++
++#define LTQ_ASC_MCON_R			(1 << 15)
++#define LTQ_ASC_MCON_FDE		(1 << 9)
++
++#define LTQ_ASC_WHBSTATE_SETREN		(1 << 1)
++#define LTQ_ASC_WHBSTATE_CLRREN		(1 << 0)
++
++#define LTQ_ASC_RXFCON_RXFITL_SHIFT	8
++#define LTQ_ASC_RXFCON_RXFITL_MASK	(0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
++#define LTQ_ASC_RXFCON_RXFITL_RXFFLU	(1 << 1)
++#define LTQ_ASC_RXFCON_RXFITL_RXFEN	(1 << 0)
++
++#define LTQ_ASC_TXFCON_TXFITL_SHIFT	8
++#define LTQ_ASC_TXFCON_TXFITL_MASK	(0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
++#define LTQ_ASC_TXFCON_TXFITL_TXFFLU	(1 << 1)
++#define LTQ_ASC_TXFCON_TXFITL_TXFEN	(1 << 0)
++
++#define LTQ_ASC_FSTAT_TXFREE_SHIFT	24
++#define LTQ_ASC_FSTAT_TXFREE_MASK	(0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_RXFREE_SHIFT	16
++#define LTQ_ASC_FSTAT_RXFREE_MASK	(0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
++#define LTQ_ASC_FSTAT_TXFFL_SHIFT	8
++#define LTQ_ASC_FSTAT_TXFFL_MASK	(0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
++#define LTQ_ASC_FSTAT_RXFFL_MASK	0x3F
++
++#ifdef __BIG_ENDIAN
++#define LTQ_ASC_RBUF_OFFSET		3
++#define LTQ_ASC_TBUF_OFFSET		3
++#else
++#define LTQ_ASC_RBUF_OFFSET		0
++#define LTQ_ASC_TBUF_OFFSET		0
++#endif
++
++struct ltq_asc_regs {
++	u32	clc;
++	u32	pisel;
++	u32	id;
++	u32	rsvd0;
++	u32	mcon;
++	u32	state;
++	u32	whbstate;
++	u32	rsvd1;
++	u8	tbuf[4];
++	u8	rbuf[4];
++	u32	rsvd2[2];
++	u32	abcon;
++	u32	abstat;
++	u32	whbabcon;
++	u32	whbabstat;
++	u32	rxfcon;
++	u32	txfcon;
++	u32	fstat;
++	u32	rsvd3;
++	u32	bg;
++	u32	bg_timer;
++	u32	fdv;
++	u32	pmw;
++	u32	modcon;
++	u32	modstat;
++};
++
++DECLARE_GLOBAL_DATA_PTR;
++
++static struct ltq_asc_regs *ltq_asc_regs =
++	(struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
++
++static int ltq_serial_init(void)
++{
++	/* Set clock divider for normal run mode to 1 and enable module */
++	ltq_writel(&ltq_asc_regs->clc, 0x100);
++
++	/* Reset MCON register */
++	ltq_writel(&ltq_asc_regs->mcon, 0);
++
++	/* Use Port A as receiver input */
++	ltq_writel(&ltq_asc_regs->pisel, 0);
++
++	/* Enable and flush RX/TX FIFOs */
++	ltq_setbits(&ltq_asc_regs->rxfcon,
++		LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
++	ltq_setbits(&ltq_asc_regs->txfcon,
++		LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
++
++	serial_setbrg();
++
++	/* Disable error flags, enable receiver */
++	ltq_writel(&ltq_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
++
++	return 0;
++}
++
++/*
++ *             fdv       asc_clk
++ * Baudrate = ----- * -------------
++ *             512    16 * (bg + 1)
++ */
++static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
++					unsigned long baudrate, u16 *fdv,
++					u16 *bg)
++{
++	const u32 c = asc_clk / (16 * 512);
++	u32 diff1, diff2;
++	u32 bg_calc, br_calc, i;
++
++	diff1 = baudrate;
++	for (i = 512; i > 0; i--) {
++		/* Calc bg for current fdv value */
++		bg_calc = i * c / baudrate;
++
++		/* Impossible baudrate */
++		if (!bg_calc)
++			return;
++
++		/*
++		 * Calc diff to target baudrate dependent on current
++		 * bg and fdv values
++		 */
++		br_calc = i * c / bg_calc;
++		if (br_calc > baudrate)
++			diff2 = br_calc - baudrate;
++		else
++			diff2 = baudrate - br_calc;
++
++		/* Perfect values found */
++		if (diff2 == 0) {
++			*fdv = i;
++			*bg = bg_calc - 1;
++			return;
++		}
++
++		if (diff2 < diff1) {
++			*fdv = i;
++			*bg = bg_calc - 1;
++			diff1 = diff2;
++		}
++	}
++}
++
++static void ltq_serial_setbrg(void)
++{
++	unsigned long asc_clk, baudrate;
++	u16 bg = 0;
++	u16 fdv = 511;
++
++	/* ASC clock is same as FPI clock with CLC.RMS = 1 */
++	asc_clk = ltq_get_bus_clock();
++	baudrate = gd->baudrate;
++
++	/* Calculate FDV and BG values */
++	ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
++
++	/* Disable baudrate generator */
++	ltq_clrbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++
++	/* Enable fractional divider */
++	ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_FDE);
++
++	/* Set fdv and bg values */
++	ltq_writel(&ltq_asc_regs->fdv, fdv);
++	ltq_writel(&ltq_asc_regs->bg, bg);
++
++	/* Enable baudrate generator */
++	ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
++}
++
++static unsigned int ltq_serial_tx_free(void)
++{
++	unsigned int txfree;
++
++	txfree = (ltq_readl(&ltq_asc_regs->fstat) &
++			LTQ_ASC_FSTAT_TXFREE_MASK) >>
++			LTQ_ASC_FSTAT_TXFREE_SHIFT;
++
++	return txfree;
++}
++
++static unsigned int ltq_serial_rx_fill(void)
++{
++	unsigned int rxffl;
++
++	rxffl = ltq_readl(&ltq_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
++
++	return rxffl;
++}
++
++static void ltq_serial_tx(const char c)
++{
++	ltq_writeb(&ltq_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
++}
++
++static u8 ltq_serial_rx(void)
++{
++	return ltq_readb(&ltq_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
++}
++
++static void ltq_serial_putc(const char c)
++{
++	if (c == '\n')
++		ltq_serial_putc('\r');
++
++	while (!ltq_serial_tx_free())
++		;
++
++	ltq_serial_tx(c);
++}
++
++static int ltq_serial_getc(void)
++{
++	while (!ltq_serial_rx_fill())
++		;
++
++	return ltq_serial_rx();
++}
++
++static int ltq_serial_tstc(void)
++{
++	return (0 != ltq_serial_rx_fill());
++}
++
++static struct serial_device ltq_serial_drv = {
++	.name	= "ltq_serial",
++	.start	= ltq_serial_init,
++	.stop	= NULL,
++	.setbrg	= ltq_serial_setbrg,
++	.putc	= ltq_serial_putc,
++	.puts	= default_serial_puts,
++	.getc	= ltq_serial_getc,
++	.tstc	= ltq_serial_tstc,
++};
++
++void ltq_serial_initialize(void)
++{
++	serial_register(&ltq_serial_drv);
++}
++
++__weak struct serial_device *default_serial_console(void)
++{
++	return &ltq_serial_drv;
++}
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -25,6 +25,7 @@ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_s
+ COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+ COBJS-$(CONFIG_ICH_SPI) +=  ich.o
+ COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
++COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
+ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
+ COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
+ COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+--- /dev/null
++++ b/drivers/spi/lantiq_spi.c
+@@ -0,0 +1,666 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <malloc.h>
++#include <watchdog.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_SPI_CLC_RMC_SHIFT		8
++#define LTQ_SPI_CLC_RMC_MASK		(0xFF << LTQ_SPI_CLC_RMC_SHIFT)
++#define LTQ_SPI_CLC_DISS		(1 << 1)
++#define LTQ_SPI_CLC_DISR		1
++
++#define LTQ_SPI_ID_TXFS_SHIFT		24
++#define LTQ_SPI_ID_TXFS_MASK		(0x3F << LTQ_SPI_ID_TXFS_SHIFT)
++#define LTQ_SPI_ID_RXFS_SHIFT		16
++#define LTQ_SPI_ID_RXFS_MASK		(0x3F << LTQ_SPI_ID_RXFS_SHIFT)
++
++#define LTQ_SPI_CON_ENBV		(1 << 22)
++#define LTQ_SPI_CON_BM_SHIFT		16
++#define LTQ_SPI_CON_BM_MASK		(0x1F << LTQ_SPI_CON_BM_SHIFT)
++#define LTQ_SPI_CON_IDLE		(1 << 23)
++#define LTQ_SPI_CON_RUEN		(1 << 12)
++#define LTQ_SPI_CON_AEN			(1 << 10)
++#define LTQ_SPI_CON_REN			(1 << 9)
++#define LTQ_SPI_CON_TEN			(1 << 8)
++#define LTQ_SPI_CON_LB			(1 << 7)
++#define LTQ_SPI_CON_PO			(1 << 6)
++#define LTQ_SPI_CON_PH			(1 << 5)
++#define LTQ_SPI_CON_HB			(1 << 4)
++#define LTQ_SPI_CON_RXOFF		(1 << 1)
++#define LTQ_SPI_CON_TXOFF		1
++
++#define LTQ_SPI_STAT_RXBV_SHIFT		28
++#define LTQ_SPI_STAT_RXBV_MASK		(0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
++#define LTQ_SPI_STAT_BSY		(1 << 13)
++
++#define LTQ_SPI_WHBSTATE_SETMS		(1 << 3)
++#define LTQ_SPI_WHBSTATE_CLRMS		(1 << 2)
++#define LTQ_SPI_WHBSTATE_SETEN		(1 << 1)
++#define LTQ_SPI_WHBSTATE_CLREN		1
++#define LTQ_SPI_WHBSTATE_CLR_ERRORS	0x0F50
++
++#define LTQ_SPI_TXFCON_TXFLU		(1 << 1)
++#define LTQ_SPI_TXFCON_TXFEN		1
++
++#define LTQ_SPI_RXFCON_RXFLU		(1 << 1)
++#define LTQ_SPI_RXFCON_RXFEN		1
++
++#define LTQ_SPI_FSTAT_RXFFL_MASK	0x3f
++#define LTQ_SPI_FSTAT_TXFFL_SHIFT	8
++#define LTQ_SPI_FSTAT_TXFFL_MASK	(0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
++
++#define LTQ_SPI_RXREQ_RXCNT_MASK	0xFFFF
++#define LTQ_SPI_RXCNT_TODO_MASK		0xFFFF
++
++#define LTQ_SPI_GPIO_DIN		16
++#define LTQ_SPI_GPIO_DOUT		17
++#define LTQ_SPI_GPIO_CLK		18
++
++struct ltq_spi_regs {
++	__be32	clc;		/* Clock control */
++	__be32	pisel;		/* Port input select */
++	__be32	id;		/* Identification */
++	__be32	rsvd0;
++	__be32	con;		/* Control */
++	__be32	stat;		/* Status */
++	__be32	whbstate;	/* Write HW modified state */
++	__be32	rsvd1;
++	__be32	tb;		/* Transmit buffer */
++	__be32	rb;		/* Receive buffer */
++	__be32	rsvd2[2];
++	__be32	rxfcon;		/* Recevie FIFO control */
++	__be32	txfcon;		/* Transmit FIFO control */
++	__be32	fstat;		/* FIFO status */
++	__be32	rsvd3;
++	__be32	brt;		/* Baudrate timer */
++	__be32	brstat;		/* Baudrate timer status */
++	__be32	rsvd4[6];
++	__be32	sfcon;		/* Serial frame control */
++	__be32	sfstat;		/* Serial frame status */
++	__be32	rsvd5[2];
++	__be32	gpocon;		/* General purpose output control */
++	__be32	gpostat;	/* General purpose output status */
++	__be32	fgpo;		/* Force general purpose output */
++	__be32	rsvd6;
++	__be32	rxreq;		/* Receive request */
++	__be32	rxcnt;		/* Receive count */
++	__be32	rsvd7[25];
++	__be32	dmacon;		/* DMA control */
++	__be32	rsvd8;
++	__be32	irnen;		/* Interrupt node enable */
++	__be32	irnicr;		/* Interrupt node interrupt capture */
++	__be32	irncr;		/* Interrupt node control */
++};
++
++struct ltq_spi_drv_data {
++	struct ltq_spi_regs __iomem *regs;
++
++	struct spi_slave slave;
++	unsigned int max_hz;
++	unsigned int mode;
++	unsigned int tx_todo;
++	unsigned int rx_todo;
++	unsigned int rx_req;
++	unsigned int bits_per_word;
++	unsigned int speed_hz;
++	const u8 *tx;
++	u8 *rx;
++	int status;
++};
++
++static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave)
++{
++	return container_of(slave, struct ltq_spi_drv_data, slave);
++}
++
++#ifdef CONFIG_SPL_BUILD
++/*
++ * We do not have or want malloc in a SPI flash SPL.
++ * Neither we have to support multiple SPI slaves. Thus we put the
++ * SPI slave context in BSS for SPL builds.
++ */
++static struct ltq_spi_drv_data ltq_spi_slave;
++
++static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
++							unsigned int cs)
++{
++	ltq_spi_slave.slave.bus = bus;
++	ltq_spi_slave.slave.cs = cs;
++
++	return &ltq_spi_slave;
++}
++
++static void ltq_spi_slave_free(struct spi_slave *slave)
++{
++}
++#else
++static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
++							unsigned int cs)
++{
++	return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs);
++}
++
++static void ltq_spi_slave_free(struct spi_slave *slave)
++{
++	struct ltq_spi_drv_data *drv;
++
++	if (slave) {
++		drv = to_ltq_spi_slave(slave);
++		free(drv);
++	}
++}
++#endif
++
++static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv)
++{
++	u32 id = ltq_readl(&drv->regs->id);
++
++	return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
++}
++
++static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv)
++{
++	u32 id = ltq_readl(&drv->regs->id);
++
++	return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
++}
++
++static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv)
++{
++	u32 fstat = ltq_readl(&drv->regs->fstat);
++
++	return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT;
++}
++
++static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv)
++{
++	u32 fstat = ltq_readl(&drv->regs->fstat);
++
++	return fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
++}
++
++static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv)
++{
++	return tx_fifo_size(drv) - tx_fifo_level(drv);
++}
++
++static void hw_power_on(struct ltq_spi_drv_data *drv)
++{
++	u32 clc;
++
++	/* Power-up mdule */
++	ltq_pm_enable(LTQ_PM_SPI);
++
++	/*
++	 * Set clock divider for run mode to 1 to
++	 * run at same frequency as FPI bus
++	 */
++	clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
++	ltq_writel(&drv->regs->clc, clc);
++}
++
++static void hw_reset_fifos(struct ltq_spi_drv_data *drv)
++{
++	u32 val;
++
++	val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
++	ltq_writel(&drv->regs->txfcon, val);
++
++	val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
++	ltq_writel(&drv->regs->rxfcon, val);
++}
++
++static int hw_is_busy(struct ltq_spi_drv_data *drv)
++{
++	u32 stat = ltq_readl(&drv->regs->stat);
++
++	return stat & LTQ_SPI_STAT_BSY;
++}
++
++static void hw_enter_config_mode(struct ltq_spi_drv_data *drv)
++{
++	ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
++}
++
++static void hw_enter_active_mode(struct ltq_spi_drv_data *drv)
++{
++	ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN);
++}
++
++static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv,
++				unsigned int max_speed_hz)
++{
++	unsigned int spi_hz, speed_hz, brt;
++
++	/*
++	 * SPI module clock is derived from FPI bus clock dependent on
++	 * divider value in CLC.RMS which is always set to 1.
++	 *
++	 *                 f_SPI
++	 * baudrate = --------------
++	 *             2 * (BR + 1)
++	 */
++	spi_hz = ltq_get_bus_clock() / 2;
++
++	/* TODO: optimize baudrate calculation */
++	for (brt = 0; brt < 0xFFFF; brt++) {
++		speed_hz = spi_hz / (brt + 1);
++		if (speed_hz <= max_speed_hz)
++			break;
++	}
++
++	ltq_writel(&drv->regs->brt, brt);
++}
++
++static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv,
++					unsigned int bits_per_word)
++{
++	u32 bm;
++
++	/* CON.BM value = bits_per_word - 1 */
++	bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
++
++	ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm);
++}
++
++static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode)
++{
++	u32 con_set = 0, con_clr = 0;
++
++	/*
++	 * SPI mode mapping in CON register:
++	 * Mode CPOL CPHA CON.PO CON.PH
++	 *  0    0    0      0      1
++	 *  1    0    1      0      0
++	 *  2    1    0      1      1
++	 *  3    1    1      1      0
++	 */
++	if (mode & SPI_CPHA)
++		con_clr |= LTQ_SPI_CON_PH;
++	else
++		con_set |= LTQ_SPI_CON_PH;
++
++	if (mode & SPI_CPOL)
++		con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
++	else
++		con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
++
++	/* Set heading control */
++	if (mode & SPI_LSB_FIRST)
++		con_clr |= LTQ_SPI_CON_HB;
++	else
++		con_set |= LTQ_SPI_CON_HB;
++
++	/* Set loopback mode */
++	if (mode & SPI_LOOP)
++		con_set |= LTQ_SPI_CON_LB;
++	else
++		con_clr |= LTQ_SPI_CON_LB;
++
++	ltq_clrsetbits(&drv->regs->con, con_clr, con_set);
++}
++
++static void hw_set_rxtx(struct ltq_spi_drv_data *drv)
++{
++	u32 con;
++
++	/* Configure transmitter and receiver */
++	con = ltq_readl(&drv->regs->con);
++	if (drv->tx)
++		con &= ~LTQ_SPI_CON_TXOFF;
++	else
++		con |= LTQ_SPI_CON_TXOFF;
++
++	if (drv->rx)
++		con &= ~LTQ_SPI_CON_RXOFF;
++	else
++		con |= LTQ_SPI_CON_RXOFF;
++
++	ltq_writel(&drv->regs->con, con);
++}
++
++static void hw_init(struct ltq_spi_drv_data *drv)
++{
++	hw_power_on(drv);
++
++	/* Put controller into config mode */
++	hw_enter_config_mode(drv);
++
++	/* Disable all interrupts */
++	ltq_writel(&drv->regs->irnen, 0);
++
++	/* Clear error flags */
++	ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS);
++
++	/* Enable error checking, disable TX/RX */
++	ltq_writel(&drv->regs->con, LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN |
++			LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN | LTQ_SPI_CON_TXOFF |
++			LTQ_SPI_CON_RXOFF);
++
++	/* Setup default SPI mode */
++	drv->bits_per_word = 8;
++	drv->speed_hz = 0;
++	hw_setup_bits_per_word(drv, drv->bits_per_word);
++	hw_setup_clock_mode(drv, SPI_MODE_0);
++
++	/* Enable master mode and clear error flags */
++	ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS |
++			LTQ_SPI_WHBSTATE_CLR_ERRORS);
++
++	/* Reset GPIO/CS registers */
++	ltq_writel(&drv->regs->gpocon, 0);
++	ltq_writel(&drv->regs->fgpo, 0xFF00);
++
++	/* Enable and flush FIFOs */
++	hw_reset_fifos(drv);
++
++	/* SPI/DIN input */
++	gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++	/* SPI/DOUT output */
++	gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* SPI/CLK output */
++	gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++static void tx_fifo_write(struct ltq_spi_drv_data *drv)
++{
++	const u8 *tx8;
++	const u16 *tx16;
++	const u32 *tx32;
++	u32 data;
++	unsigned int tx_free = tx_fifo_free(drv);
++
++	while (drv->tx_todo && tx_free) {
++		switch (drv->bits_per_word) {
++		case 8:
++			tx8 = drv->tx;
++			data = *tx8;
++			drv->tx_todo--;
++			drv->tx++;
++			break;
++		case 16:
++			tx16 = (u16 *) drv->tx;
++			data = *tx16;
++			drv->tx_todo -= 2;
++			drv->tx += 2;
++			break;
++		case 32:
++			tx32 = (u32 *) drv->tx;
++			data = *tx32;
++			drv->tx_todo -= 4;
++			drv->tx += 4;
++			break;
++		default:
++			return;
++		}
++
++		ltq_writel(&drv->regs->tb, data);
++		tx_free--;
++	}
++}
++
++static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv)
++{
++	u8 *rx8;
++	u16 *rx16;
++	u32 *rx32;
++	u32 data;
++	unsigned int rx_fill = rx_fifo_level(drv);
++
++	while (rx_fill) {
++		data = ltq_readl(&drv->regs->rb);
++
++		switch (drv->bits_per_word) {
++		case 8:
++			rx8 = drv->rx;
++			*rx8 = data;
++			drv->rx_todo--;
++			drv->rx++;
++			break;
++		case 16:
++			rx16 = (u16 *) drv->rx;
++			*rx16 = data;
++			drv->rx_todo -= 2;
++			drv->rx += 2;
++			break;
++		case 32:
++			rx32 = (u32 *) drv->rx;
++			*rx32 = data;
++			drv->rx_todo -= 4;
++			drv->rx += 4;
++			break;
++		default:
++			return;
++		}
++
++		rx_fill--;
++	}
++}
++
++static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv)
++{
++	u32 data, *rx32;
++	u8 *rx8;
++	unsigned int rxbv, shift;
++	unsigned int rx_fill = rx_fifo_level(drv);
++
++	/*
++	 * In RX-only mode the bits per word value is ignored by HW. A value
++	 * of 32 is used instead. Thus all 4 bytes per FIFO must be read.
++	 * If remaining RX bytes are less than 4, the FIFO must be read
++	 * differently. The amount of received and valid bytes is indicated
++	 * by STAT.RXBV register value.
++	 */
++	while (rx_fill) {
++		if (drv->rx_todo < 4) {
++			rxbv = (ltq_readl(&drv->regs->stat) &
++				LTQ_SPI_STAT_RXBV_MASK) >>
++				LTQ_SPI_STAT_RXBV_SHIFT;
++			data = ltq_readl(&drv->regs->rb);
++
++			shift = (rxbv - 1) * 8;
++			rx8 = drv->rx;
++
++			while (rxbv) {
++				*rx8++ = (data >> shift) & 0xFF;
++				rxbv--;
++				shift -= 8;
++				drv->rx_todo--;
++				drv->rx++;
++
++				if (drv->rx_req)
++					drv->rx_req --;
++			}
++		} else {
++			data = ltq_readl(&drv->regs->rb);
++			rx32 = (u32 *) drv->rx;
++
++			*rx32++ = data;
++			drv->rx_todo -= 4;
++			drv->rx += 4;
++
++			if (drv->rx_req >= 4)
++				drv->rx_req -= 4;
++		}
++		rx_fill--;
++	}
++}
++
++static void rx_request(struct ltq_spi_drv_data *drv)
++{
++	unsigned int rxreq, rxreq_max;
++
++	if (drv->rx_req)
++		return;
++
++	/*
++	 * To avoid receive overflows at high clocks it is better to request
++	 * only the amount of bytes that fits into all FIFOs. This value
++	 * depends on the FIFO size implemented in hardware.
++	 */
++	rxreq = drv->rx_todo;
++	rxreq_max = rx_fifo_size(drv) * 4;
++	if (rxreq > rxreq_max)
++		rxreq = rxreq_max;
++
++	drv->rx_req = rxreq;
++	ltq_writel(&drv->regs->rxreq, rxreq);
++}
++
++void spi_init(void)
++{
++}
++
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++				  unsigned int max_hz, unsigned int mode)
++{
++	struct ltq_spi_drv_data *drv;
++
++	if (!spi_cs_is_valid(bus, cs))
++		return NULL;
++
++	drv = ltq_spi_slave_alloc(bus, cs);
++	if (!drv)
++		return NULL;
++
++	drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
++
++	hw_init(drv);
++
++	drv->max_hz = max_hz;
++	drv->mode = mode;
++
++	return &drv->slave;
++}
++
++void spi_free_slave(struct spi_slave *slave)
++{
++	ltq_spi_slave_free(slave);
++}
++
++static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv)
++{
++	const unsigned long timeout = 20000;
++	unsigned long timebase;
++
++	timebase = get_timer(0);
++
++	do {
++		WATCHDOG_RESET();
++
++		if (!hw_is_busy(drv))
++			return 0;
++	} while (get_timer(timebase) < timeout);
++
++	return 1;
++}
++
++int spi_claim_bus(struct spi_slave *slave)
++{
++	struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
++	int ret;
++
++	ret = ltq_spi_wait_ready(drv);
++	if (ret) {
++		debug("cannot claim bus\n");
++		return ret;
++	}
++
++	hw_enter_config_mode(drv);
++	hw_setup_clock_mode(drv, drv->mode);
++	hw_setup_speed_hz(drv, drv->max_hz);
++	hw_setup_bits_per_word(drv, drv->bits_per_word);
++	hw_enter_active_mode(drv);
++
++	return 0;
++}
++
++void spi_release_bus(struct spi_slave *slave)
++{
++	struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
++
++	hw_enter_config_mode(drv);
++}
++
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
++		const void *dout, void *din, unsigned long flags)
++{
++
++	struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
++	int ret = 0;
++
++	if (bitlen % 8)
++		return 1;
++
++	if (!bitlen) {
++		ret = 0;
++		goto done;
++	}
++
++	if (flags & SPI_XFER_BEGIN)
++		spi_cs_activate(slave);
++
++	drv->tx = dout;
++	drv->tx_todo = 0;
++	drv->rx = din;
++	drv->rx_todo = 0;
++	hw_set_rxtx(drv);
++
++	if (drv->tx) {
++		drv->tx_todo = bitlen / 8;
++
++		tx_fifo_write(drv);
++	}
++
++	if (drv->rx) {
++		drv->rx_todo = bitlen / 8;
++
++		if (!drv->tx)
++			rx_request(drv);
++	}
++
++	for (;;) {
++		if (drv->tx) {
++			if (drv->rx && drv->rx_todo)
++				rx_fifo_read_full_duplex(drv);
++
++			if (drv->tx_todo)
++				tx_fifo_write(drv);
++			else
++				goto done;
++		} else if (drv->rx) {
++			if (drv->rx_todo) {
++				rx_fifo_read_half_duplex(drv);
++
++				if (drv->rx_todo)
++					rx_request(drv);
++				else
++					goto done;
++			} else {
++				goto done;
++			}
++		}
++	}
++
++done:
++	ret = ltq_spi_wait_ready(drv);
++
++	drv->rx = NULL;
++	drv->tx = NULL;
++	hw_set_rxtx(drv);
++
++	if (flags & SPI_XFER_END)
++		spi_cs_deactivate(slave);
++
++	return ret;
++}
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -214,6 +214,7 @@ int phy_atheros_init(void);
+ int phy_broadcom_init(void);
+ int phy_davicom_init(void);
+ int phy_et1011c_init(void);
++int phy_lantiq_init(void);
+ int phy_lxt_init(void);
+ int phy_marvell_init(void);
+ int phy_micrel_init(void);
+--- a/spl/Makefile
++++ b/spl/Makefile
+@@ -100,6 +100,8 @@ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += dri
+ LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
+ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
+ LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o
++LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
++LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
+ 
+ ifneq ($(CONFIG_OMAP_COMMON),)
+ LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
+--- a/tools/.gitignore
++++ b/tools/.gitignore
+@@ -2,6 +2,7 @@
+ /envcrc
+ /gen_eth_addr
+ /img2srec
++/ltq-boot-image
+ /kwboot
+ /mkenvimage
+ /mkimage
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -49,6 +49,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo
+ BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
+ BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
+ BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
++BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
+ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
+ BIN_FILES-y += mkenvimage$(SFX)
+ BIN_FILES-y += mkimage$(SFX)
+@@ -95,6 +96,7 @@ OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
+ OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
+ OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
+ OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
++OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
+ OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
+ OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
+ 
+@@ -195,6 +197,10 @@ $(obj)img2srec$(SFX):	$(obj)img2srec.o
+ 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ 	$(HOSTSTRIP) $@
+ 
++$(obj)ltq-boot-image$(SFX):	$(obj)ltq-boot-image.o
++	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
++	$(HOSTSTRIP) $@
++
+ $(obj)xway-swap-bytes$(SFX):	$(obj)xway-swap-bytes.o
+ 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+ 	$(HOSTSTRIP) $@
+--- /dev/null
++++ b/tools/ltq-boot-image.c
+@@ -0,0 +1,315 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <getopt.h>
++#include <compiler.h>
++#include <sys/stat.h>
++
++enum image_types {
++	IMAGE_NONE,
++	IMAGE_SFSPL
++};
++
++/* Lantiq non-volatile bootstrap command IDs */
++enum nvb_cmd_ids {
++	NVB_CMD_DEBUG	= 0x11,
++	NVB_CMD_REGCFG	= 0x22,
++	NVB_CMD_IDWNLD	= 0x33,
++	NVB_CMD_CDWNLD	= 0x44,
++	NVB_CMD_DWNLD	= 0x55,
++	NVB_CMD_IFCFG	= 0x66,
++	NVB_CMD_START	= 0x77
++};
++
++/* Lantiq non-volatile bootstrap command flags */
++enum nvb_cmd_flags {
++	NVB_FLAG_START	= 1,
++	NVB_FLAG_DEC	= (1 << 1),
++	NVB_FLAG_DBG	= (1 << 2),
++	NVB_FLAG_SDBG	= (1 << 3),
++	NVB_FLAG_CFG0	= (1 << 4),
++	NVB_FLAG_CFG1	= (1 << 5),
++	NVB_FLAG_CFG2	= (1 << 6),
++	NVB_FLAG_RST	= (1 << 7)
++};
++
++struct args {
++	enum image_types type;
++	__u32		entry_addr;
++	const char	*uboot_bin;
++	const char	*spl_bin;
++	const char	*out_bin;
++};
++
++static void usage_msg(const char *name)
++{
++	fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
++		name);
++	fprintf(stderr, " Image types:\n"
++			"  sfspl  - SPL + [compressed] U-Boot for SPI flash\n");
++}
++
++static enum image_types parse_image_type(const char *type)
++{
++	if (!type)
++		return IMAGE_NONE;
++
++	if (!strncmp(type, "sfspl", 6))
++		return IMAGE_SFSPL;
++
++	return IMAGE_NONE;
++}
++
++static int parse_args(int argc, char *argv[], struct args *arg)
++{
++	int opt;
++
++	memset(arg, 0, sizeof(*arg));
++
++	while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
++		switch (opt) {
++		case 'h':
++			usage_msg(argv[0]);
++			return 1;
++		case 't':
++			arg->type = parse_image_type(optarg);
++			break;
++		case 'e':
++			arg->entry_addr = strtoul(optarg, NULL, 16);
++			break;
++		case 'u':
++			arg->uboot_bin = optarg;
++			break;
++		case 's':
++			arg->spl_bin = optarg;
++			break;
++		case 'o':
++			arg->out_bin = optarg;
++			break;
++		default:
++			fprintf(stderr, "Invalid option -%c\n", opt);
++			goto parse_error;
++		}
++	}
++
++	if (arg->type == IMAGE_NONE) {
++		fprintf(stderr, "Invalid image type\n");
++		goto parse_error;
++	}
++
++	if (!arg->uboot_bin) {
++		fprintf(stderr, "Missing U-Boot binary\n");
++		goto parse_error;
++	}
++
++	if (!arg->out_bin) {
++		fprintf(stderr, "Missing output binary\n");
++		goto parse_error;
++	}
++
++	if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
++		fprintf(stderr, "Missing SPL binary\n");
++		goto parse_error;
++	}
++
++	return 0;
++
++parse_error:
++	usage_msg(argv[0]);
++	return -1;
++}
++
++static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
++{
++	__u32 cmd;
++	__u16 tag;
++
++	tag = (cmdid << 8) | cmdflags;
++	cmd = (tag << 16) | (0xFFFF - tag);
++
++	return cpu_to_be32(cmd);
++}
++
++static int write_header(int fd, const void *hdr, size_t size)
++{
++	ssize_t n;
++
++	n = write(fd, hdr, size);
++	if (n != size) {
++		fprintf(stderr, "Cannot write header: %s\n",
++			strerror(errno));
++		return -1;
++	}
++
++	return 0;
++}
++
++static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
++{
++	__u32 hdr[3];
++
++	hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
++					NVB_FLAG_SDBG);
++	hdr[1] = cpu_to_be32(size + 4);
++	hdr[2] = cpu_to_be32(addr);
++
++	return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int write_nvb_start_header(int fd, __u32 addr)
++{
++	__u32 hdr[3];
++
++	hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
++	hdr[1] = cpu_to_be32(4);
++	hdr[2] = cpu_to_be32(addr);
++
++	return write_header(fd, hdr, sizeof(hdr));
++}
++
++static int open_input_bin(const char *name, void **ptr, size_t *size)
++{
++	struct stat sbuf;
++	int ret, fd;
++
++	fd = open(name, O_RDONLY | O_BINARY);
++	if (0 > fd) {
++		fprintf(stderr, "Cannot open %s: %s\n", name,
++			strerror(errno));
++		return -1;
++	}
++
++	ret = fstat(fd, &sbuf);
++	if (0 > ret) {
++		fprintf(stderr, "Cannot fstat %s: %s\n", name,
++			strerror(errno));
++		return -1;
++	}
++
++	*ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
++	if (*ptr == MAP_FAILED) {
++		fprintf(stderr, "Cannot mmap %s: %s\n", name,
++			strerror(errno));
++		return -1;
++	}
++
++	*size = sbuf.st_size;
++
++	return fd;
++}
++
++static void close_input_bin(int fd, void *ptr, size_t size)
++{
++	munmap(ptr, size);
++	close(fd);
++}
++
++static int copy_bin(int fd, void *ptr, size_t size)
++{
++	ssize_t n;
++
++	n = write(fd, ptr, size);
++	if (n != size) {
++		fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
++		return -1;
++	}
++
++	return 0;
++}
++
++static int open_output_bin(const char *name)
++{
++	int fd;
++
++	fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
++	if (0 > fd) {
++		fprintf(stderr, "Cannot open %s: %s\n", name,
++			strerror(errno));
++		return -1;
++	}
++
++	return fd;
++}
++
++static int create_sfspl(const struct args *arg)
++{
++	int out_fd, uboot_fd, spl_fd, ret;
++	void *uboot_ptr, *spl_ptr;
++	size_t uboot_size, spl_size;
++
++	out_fd = open_output_bin(arg->out_bin);
++	if (0 > out_fd)
++		goto err;
++
++	spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
++	if (0 > spl_fd)
++		goto err_spl;
++
++	uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
++	if (0 > uboot_fd)
++		goto err_uboot;
++
++	ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
++	if (ret)
++		goto err_write;
++
++	ret = copy_bin(out_fd, spl_ptr, spl_size);
++	if (ret)
++		goto err_write;
++
++	ret = write_nvb_start_header(out_fd, arg->entry_addr);
++	if (ret)
++		goto err_write;
++
++	ret = copy_bin(out_fd, uboot_ptr, uboot_size);
++	if (ret)
++		goto err_write;
++
++	close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++	close_input_bin(spl_fd, spl_ptr, spl_size);
++	close(out_fd);
++
++	return 0;
++
++err_write:
++	close_input_bin(uboot_fd, uboot_ptr, uboot_size);
++err_uboot:
++	close_input_bin(spl_fd, spl_ptr, spl_size);
++err_spl:
++	close(out_fd);
++err:
++	return -1;
++}
++
++int main(int argc, char *argv[])
++{
++	int ret;
++	struct args arg;
++
++	ret = parse_args(argc, argv, &arg);
++	if (ret)
++		goto done;
++
++	switch (arg.type) {
++	case IMAGE_SFSPL:
++		ret = create_sfspl(&arg);
++		break;
++	default:
++		fprintf(stderr, "Image type not implemented\n");
++		ret = -1;
++		break;
++	}
++
++done:
++	if (ret >= 0)
++		return EXIT_SUCCESS;
++
++	return EXIT_FAILURE;
++}
diff --git a/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch b/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch
new file mode 100644
index 0000000..a12d2eb
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch
@@ -0,0 +1,1229 @@
+From 4953294aa8f8b9023e6b5f7f39059706c72d916c Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 9 Dec 2012 17:54:56 +0100
+Subject: MIPS: lantiq: add support for Lantiq XWAY ARX100 SoC family
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/Makefile
+@@ -0,0 +1,31 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(SOC).o
++
++COBJS-y	+= cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
++SOBJS-y	+= cgu_init.o mem_init.o
++
++COBJS	:= $(COBJS-y)
++SOBJS	:= $(SOBJS-y)
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
++
++all:	$(LIB)
++
++$(LIB):	$(obj).depend $(OBJS)
++	$(call cmd_link_o_target, $(OBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/cgu.c
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/clk.h>
++#include <asm/lantiq/io.h>
++
++#define CGU_SYS_DDR_SEL		(1 << 0)
++#define CGU_SYS_CPU_SEL		(1 << 2)
++#define CGU_SYS_SYS_SHIFT	3
++#define CGU_SYS_SYS_MASK	(0x3 << CGU_SYS_SYS_SHIFT)
++#define CGU_SYS_FPI_SEL		(1 << 6)
++#define CGU_SYS_PPE_SEL		(1 << 7)
++
++struct ltq_cgu_regs {
++	u32	rsvd0;
++	__be32	pll0_cfg;	/* PLL0 config */
++	__be32	pll1_cfg;	/* PLL1 config */
++	u32	rsvd2;
++	__be32	sys;		/* System clock */
++	__be32	update;		/* CGU update control */
++	__be32	if_clk;		/* Interface clock */
++	u32	rsvd3;
++	__be32	smd;		/* SDRAM Memory Control */
++	u32	rsvd4;
++	__be32	ct1_sr;		/* CT status 1 */
++	__be32	ct_kval;	/* CT K value */
++	__be32	pcm_cr;		/* PCM control */
++};
++
++static struct ltq_cgu_regs *ltq_cgu_regs =
++	(struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
++
++static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
++{
++	return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
++}
++
++static unsigned long ltq_get_system_clock(void)
++{
++	u32 sys_sel;
++	unsigned long clk;
++
++	sys_sel = ltq_cgu_sys_readl(CGU_SYS_SYS_MASK, CGU_SYS_SYS_SHIFT);
++
++	switch (sys_sel) {
++	case 0:
++		clk = CLOCK_333_MHZ;
++		break;
++	case 2:
++		clk = CLOCK_393_MHZ;
++		break;
++	default:
++		clk = 0;
++		break;
++	}
++
++	return clk;
++}
++
++unsigned long ltq_get_io_region_clock(void)
++{
++	u32 ddr_sel;
++	unsigned long clk;
++
++	ddr_sel = ltq_cgu_sys_readl(1, CGU_SYS_DDR_SEL);
++
++	if (ddr_sel)
++		clk = ltq_get_system_clock() / 3;
++	else
++		clk = ltq_get_system_clock() / 2;
++
++	return clk;
++}
++
++unsigned long ltq_get_cpu_clock(void)
++{
++	u32 cpu_sel;
++	unsigned long clk;
++
++	cpu_sel = ltq_cgu_sys_readl(1, CGU_SYS_CPU_SEL);
++
++	if (cpu_sel)
++		clk = ltq_get_io_region_clock();
++	else
++		clk = ltq_get_system_clock();
++
++	return clk;
++}
++
++unsigned long ltq_get_bus_clock(void)
++{
++	u32 fpi_sel;
++	unsigned long clk;
++
++	fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL);
++
++	if (fpi_sel)
++		clk = ltq_get_io_region_clock() / 2;
++	else
++		clk = ltq_get_io_region_clock();
++
++	return clk;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/cgu_init.S
+@@ -0,0 +1,105 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* CGU module register */
++#define CGU_PLL0_CFG			0x0004	/* PLL0 config */
++#define CGU_PLL1_CFG			0x0008	/* PLL1 config */
++#define CGU_SYS				0x0010	/* System clock */
++#define CGU_UPDATE			0x0014	/* Clock update control */
++
++/* Valid SYS.PPE_SEL values */
++#define CGU_SYS_PPESEL_SHIFT		7
++#define CGU_SYS_PPESEL_250_MHZ		(0x1 << CGU_SYS_PPESEL_SHIFT)
++
++/* Valid SYS.SYS_SEL values */
++#define CGU_SYS_SYSSEL_SHIFT		3
++#define CGU_SYS_SYSSEL_PLL0_333_MHZ	(0x0 << CGU_SYS_SYSSEL_SHIFT)
++#define CGU_SYS_SYSSEL_PLL1_393_MHZ	(0x2 << CGU_SYS_SYSSEL_SHIFT)
++
++/* Valid SYS.CPU_SEL values */
++#define CGU_SYS_CPUSEL_SHIFT		2
++#define CGU_SYS_CPUSEL_EQUAL_SYSCLK	(0x0 << CGU_SYS_CPUSEL_SHIFT)
++#define CGU_SYS_CPUSEL_EQUAL_DDRCLK	(0x1 << CGU_SYS_CPUSEL_SHIFT)
++
++/* Valid SYS.DDR_SEL values */
++#define CGU_SYS_DDRSEL_HALF_SYSCLK	0x0
++#define CGU_SYS_DDRSEL_THIRD_SYSCLK	0x1
++
++#define CGU_UPDATE_UPD			0x1
++
++#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_393_DDR_197)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL1_393_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_SYSCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_HALF_SYSCLK
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_197_DDR_197)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL1_393_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_DDRCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_HALF_SYSCLK
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL0_333_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_SYSCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_HALF_SYSCLK
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_167_DDR_167)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL0_333_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_DDRCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_HALF_SYSCLK
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_131_DDR_131)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL1_393_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_DDRCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_THIRD_SYSCLK
++#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
++#define CGU_SYS_PPESEL_CONFIG		CGU_SYS_PPESEL_250_MHZ
++#define CGU_SYS_SYSSEL_CONFIG		CGU_SYS_SYSSEL_PLL0_333_MHZ
++#define CGU_SYS_CPUSEL_CONFIG		CGU_SYS_CPUSEL_EQUAL_DDRCLK
++#define CGU_SYS_DDRSEL_CONFIG		CGU_SYS_DDRSEL_THIRD_SYSCLK
++#else
++#error "Invalid system clock configuration!"
++#endif
++
++/* Build register values */
++#define CGU_SYS_VALUE		(CGU_SYS_PPESEL_CONFIG | \
++				CGU_SYS_SYSSEL_CONFIG | \
++				CGU_SYS_CPUSEL_CONFIG | \
++				CGU_SYS_DDRSEL_CONFIG)
++
++	.set noreorder
++
++LEAF(ltq_cgu_init)
++	/* Load current CGU register value */
++	li	t0, (LTQ_CGU_BASE | KSEG1)
++	lw	t1, CGU_SYS(t0)
++
++	/* Load target CGU register values */
++	li	t2, CGU_SYS_VALUE
++
++	/* Only update registers if values differ */
++	beq	t1, t2, finished
++	 nop
++
++	/* Store target register values */
++	sw	t2, CGU_SYS(t0)
++
++	/* Trigger CGU update */
++	li	t1, CGU_UPDATE_UPD
++	sw	t1, CGU_UPDATE(t0)
++
++finished:
++	jr	ra
++	 nop
++
++	END(ltq_cgu_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/chipid.c
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_CHIPID_VERSION_SHIFT	28
++#define LTQ_CHIPID_VERSION_MASK		(0xF << LTQ_CHIPID_VERSION_SHIFT)
++#define LTQ_CHIPID_PNUM_SHIFT		12
++#define LTQ_CHIPID_PNUM_MASK		(0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
++
++struct ltq_chipid_regs {
++	u32	manid;		/* Manufacturer identification */
++	u32	chipid;		/* Chip identification */
++};
++
++static struct ltq_chipid_regs *ltq_chipid_regs =
++	(struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
++
++unsigned int ltq_chip_version_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
++}
++
++unsigned int ltq_chip_partnum_get(void)
++{
++	u32 chipid;
++
++	chipid = ltq_readl(&ltq_chipid_regs->chipid);
++
++	return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
++}
++
++const char *ltq_chip_partnum_str(void)
++{
++	enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
++
++	switch (partnum) {
++	case LTQ_SOC_ARX188:
++		return "ARX188";
++	case LTQ_SOC_ARX186:
++	case LTQ_SOC_ARX186_2:
++		return "ARX186";
++	case LTQ_SOC_ARX182:
++		return "ARX182";
++	default:
++		printf("Unknown partnum: %x\n", partnum);
++	}
++
++	return "";
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/config.mk
+@@ -0,0 +1,30 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
++PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
++
++ifdef CONFIG_SPL_BUILD
++PF_ABICALLS		:= -mno-abicalls
++PF_PIC			:= -fno-pic
++PF_PIE			:=
++USE_PRIVATE_LIBGCC	:= yes
++endif
++
++LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
++
++ifndef CONFIG_SPL_BUILD
++ifdef CONFIG_SYS_BOOT_SFSPL
++ALL-y += $(obj)u-boot.ltq.sfspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
++endif
++ifdef CONFIG_SYS_BOOT_NORSPL
++ALL-y += $(obj)u-boot.ltq.norspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
++endif
++endif
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/ebu.c
+@@ -0,0 +1,111 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++#define EBU_ADDRSEL_MASK(mask)		((mask & 0xf) << 4)
++#define EBU_ADDRSEL_REGEN		(1 << 0)
++
++#define EBU_CON_WRDIS			(1 << 31)
++#define EBU_CON_AGEN_DEMUX		(0x0 << 24)
++#define EBU_CON_AGEN_MUX		(0x2 << 24)
++#define EBU_CON_SETUP			(1 << 22)
++#define EBU_CON_WAIT_DIS		(0x0 << 20)
++#define EBU_CON_WAIT_ASYNC		(0x1 << 20)
++#define EBU_CON_WAIT_SYNC		(0x2 << 20)
++#define EBU_CON_WINV			(1 << 19)
++#define EBU_CON_PW_8BIT			(0x0 << 16)
++#define EBU_CON_PW_16BIT		(0x1 << 16)
++#define EBU_CON_ALEC(cycles)		((cycles & 0x3) << 14)
++#define EBU_CON_BCGEN_CS		(0x0 << 12)
++#define EBU_CON_BCGEN_INTEL		(0x1 << 12)
++#define EBU_CON_BCGEN_MOTOROLA		(0x2 << 12)
++#define EBU_CON_WAITWRC(cycles)		((cycles & 0x7) << 8)
++#define EBU_CON_WAITRDC(cycles)		((cycles & 0x3) << 6)
++#define EBU_CON_HOLDC(cycles)		((cycles & 0x3) << 4)
++#define EBU_CON_RECOVC(cycles)		((cycles & 0x3) << 2)
++#define EBU_CON_CMULT_1			0x0
++#define EBU_CON_CMULT_4			0x1
++#define EBU_CON_CMULT_8			0x2
++#define EBU_CON_CMULT_16		0x3
++
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define ebu_region0_enable		1
++#else
++#define ebu_region0_enable		0
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define ebu_region1_enable		1
++#else
++#define ebu_region1_enable		0
++#endif
++
++struct ltq_ebu_regs {
++	u32	clc;
++	u32	rsvd0;
++	u32	id;
++	u32	rsvd1;
++	u32	con;
++	u32	rsvd2[3];
++	u32	addr_sel_0;
++	u32	addr_sel_1;
++	u32	addr_sel_2;
++	u32	addr_sel_3;
++	u32	rsvd3[12];
++	u32	con_0;
++	u32	con_1;
++	u32	con_2;
++	u32	con_3;
++};
++
++static struct ltq_ebu_regs *ltq_ebu_regs =
++	(struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
++
++void ltq_ebu_init(void)
++{
++	if (ebu_region0_enable) {
++		/*
++		 * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
++		 * region control. This supports up to 32 MiB NOR flash in
++		 * bank 0.
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
++			EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
++
++		ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
++			EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
++			EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++			EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
++			EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
++			EBU_CON_CMULT_16);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
++
++	if (ebu_region1_enable) {
++		/*
++		 * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
++		 * region control. This supports NAND flash in bank 1.
++		 */
++		ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
++			EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
++
++		ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
++			EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
++			EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
++			EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
++			EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
++			EBU_CON_CMULT_4);
++	} else
++		ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
++}
++
++void *flash_swap_addr(unsigned long addr)
++{
++	return (void *)(addr ^ 2);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/mem.c
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/soc.h>
++#include <asm/lantiq/io.h>
++
++static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
++
++static inline u32 ltq_mc_dc_read(u32 index)
++{
++	return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
++}
++
++phys_size_t initdram(int board_type)
++{
++	u32 col, row, dc04, dc19, dc20;
++
++	dc04 = ltq_mc_dc_read(4);
++	dc19 = ltq_mc_dc_read(19);
++	dc20 = ltq_mc_dc_read(20);
++
++	row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
++	col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
++
++	return (1 << (row + col)) * 4 * 2;
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/mem_init.S
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <config.h>
++#include <asm/asm.h>
++#include <asm/regdef.h>
++#include <asm/addrspace.h>
++#include <asm/arch/soc.h>
++
++/* Must be configured in BOARDDIR */
++#include <ddr_settings.h>
++
++#define LTQ_MC_GEN_ERRCAUSE		0x0010
++#define LTQ_MC_GEN_ERRADDR		0x0020
++#define LTQ_MC_GEN_CON			0x0060
++#define LTQ_MC_GEN_STAT			0x0070
++#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE	0xD
++#define LTQ_MC_GEN_STAT_DLCK_PWRON	0xC
++
++#define LTQ_MC_DDR_DC03_MC_START	0x100
++
++	/* Store given value in MC DDR CCRx register */
++	.macro dc_sw num, val
++	li	t2, \val
++	sw	t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
++	.endm
++
++LEAF(ltq_mem_init)
++	/* Load MC General and MC DDR module base */
++	li	t0, (LTQ_MC_GEN_BASE | KSEG1)
++	li	t1, (LTQ_MC_DDR_BASE | KSEG1)
++
++	/* Clear access error log registers */
++	sw	zero, LTQ_MC_GEN_ERRCAUSE(t0)
++	sw	zero, LTQ_MC_GEN_ERRADDR(t0)
++
++	/* Enable DDR and SRAM module in memory controller */
++	li	t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
++	sw	t2, LTQ_MC_GEN_CON(t0)
++
++	/* Clear start bit of DDR memory controller */
++	sw	zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++	/* Init memory controller registers with values ddr_settings.h */
++	dc_sw	0, MC_DC00_VALUE
++	dc_sw	1, MC_DC01_VALUE
++	dc_sw	2, MC_DC02_VALUE
++	dc_sw	4, MC_DC04_VALUE
++	dc_sw	5, MC_DC05_VALUE
++	dc_sw	6, MC_DC06_VALUE
++	dc_sw	7, MC_DC07_VALUE
++	dc_sw	8, MC_DC08_VALUE
++	dc_sw	9, MC_DC09_VALUE
++
++	dc_sw	10, MC_DC10_VALUE
++	dc_sw	11, MC_DC11_VALUE
++	dc_sw	12, MC_DC12_VALUE
++	dc_sw	13, MC_DC13_VALUE
++	dc_sw	14, MC_DC14_VALUE
++	dc_sw	15, MC_DC15_VALUE
++	dc_sw	16, MC_DC16_VALUE
++	dc_sw	17, MC_DC17_VALUE
++	dc_sw	18, MC_DC18_VALUE
++	dc_sw	19, MC_DC19_VALUE
++
++	dc_sw	20, MC_DC20_VALUE
++	dc_sw	21, MC_DC21_VALUE
++	dc_sw	22, MC_DC22_VALUE
++	dc_sw	23, MC_DC23_VALUE
++	dc_sw	24, MC_DC24_VALUE
++	dc_sw	25, MC_DC25_VALUE
++	dc_sw	26, MC_DC26_VALUE
++	dc_sw	27, MC_DC27_VALUE
++	dc_sw	28, MC_DC28_VALUE
++	dc_sw	29, MC_DC29_VALUE
++
++	dc_sw	30, MC_DC30_VALUE
++	dc_sw	31, MC_DC31_VALUE
++	dc_sw	32, MC_DC32_VALUE
++	dc_sw	33, MC_DC33_VALUE
++	dc_sw	34, MC_DC34_VALUE
++	dc_sw	35, MC_DC35_VALUE
++	dc_sw	36, MC_DC36_VALUE
++	dc_sw	37, MC_DC37_VALUE
++	dc_sw	38, MC_DC38_VALUE
++	dc_sw	39, MC_DC39_VALUE
++
++	dc_sw	40, MC_DC40_VALUE
++	dc_sw	41, MC_DC41_VALUE
++	dc_sw	42, MC_DC42_VALUE
++	dc_sw	43, MC_DC43_VALUE
++	dc_sw	44, MC_DC44_VALUE
++	dc_sw	45, MC_DC45_VALUE
++	dc_sw	46, MC_DC46_VALUE
++
++	/* Set start bit of DDR memory controller */
++	li	t2, LTQ_MC_DDR_DC03_MC_START
++	sw	t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
++
++	/* Wait until DLL has locked and core is ready for data transfers */
++wait_ready:
++	lw	t2, LTQ_MC_GEN_STAT(t0)
++	li	t3, LTQ_MC_GEN_STAT_DLCK_PWRON
++	and	t2, t3
++	bne	t2, t3, wait_ready
++
++finished:
++	jr	ra
++
++	END(ltq_mem_init)
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/pmu.c
+@@ -0,0 +1,120 @@
++/*
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/pm.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_PMU_PWDCR_RESERVED		0xE00C200C
++
++#define LTQ_PMU_PWDCR_SWITCH		(1 << 28)
++#define LTQ_PMU_PWDCR_USB1		(1 << 27)
++#define LTQ_PMU_PWDCR_USB1_PHY		(1 << 26)
++#define LTQ_PMU_PWDCR_TDM		(1 << 25)
++#define LTQ_PMU_PWDCR_DDR_MEM		(1 << 24)
++#define LTQ_PMU_PWDCR_PPE_DP		(1 << 23)
++#define LTQ_PMU_PWDCR_PPE_EMA		(1 << 22)
++#define LTQ_PMU_PWDCR_PPE_TC		(1 << 21)
++#define LTQ_PMU_PWDCR_DEU		(1 << 20)
++#define LTQ_PMU_PWDCR_UART1		(1 << 17)
++#define LTQ_PMU_PWDCR_SDIO		(1 << 16)
++#define LTQ_PMU_PWDCR_AHB		(1 << 15)
++#define LTQ_PMU_PWDCR_FPI0		(1 << 14)
++#define LTQ_PMU_PWDCR_GPTC		(1 << 12)
++#define LTQ_PMU_PWDCR_LEDC		(1 << 11)
++#define LTQ_PMU_PWDCR_EBU		(1 << 10)
++#define LTQ_PMU_PWDCR_DSL		(1 << 9)
++#define LTQ_PMU_PWDCR_SPI		(1 << 8)
++#define LTQ_PMU_PWDCR_UART0		(1 << 7)
++#define LTQ_PMU_PWDCR_USB		(1 << 6)
++#define LTQ_PMU_PWDCR_DMA		(1 << 5)
++#define LTQ_PMU_PWDCR_PCI		(1 << 4)
++#define LTQ_PMU_PWDCR_FPI1		(1 << 1)
++#define LTQ_PMU_PWDCR_USB0_PHY		(1 << 0)
++
++struct ltq_pmu_regs {
++	u32	rsvd0[7];
++	__be32	pwdcr;
++	__be32	sr;
++};
++
++static struct ltq_pmu_regs *ltq_pmu_regs =
++	(struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
++
++u32 ltq_pm_map(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_PM_CORE:
++		val = LTQ_PMU_PWDCR_DDR_MEM | LTQ_PMU_PWDCR_UART1 |
++			LTQ_PMU_PWDCR_FPI0 | LTQ_PMU_PWDCR_LEDC |
++			LTQ_PMU_PWDCR_EBU;
++		break;
++	case LTQ_PM_DMA:
++		val = LTQ_PMU_PWDCR_DMA;
++		break;
++	case LTQ_PM_ETH:
++		val = LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DP |
++			LTQ_PMU_PWDCR_PPE_EMA | LTQ_PMU_PWDCR_PPE_TC;
++		break;
++	case LTQ_PM_SPI:
++		val = LTQ_PMU_PWDCR_SPI;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_pm_enable(enum ltq_pm_modules module)
++{
++	const unsigned long timeout = 1000;
++	unsigned long timebase;
++	u32 sr, val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
++
++	timebase = get_timer(0);
++
++	do {
++		sr = ltq_readl(&ltq_pmu_regs->sr);
++		if (~sr & val)
++			return 0;
++	} while (get_timer(timebase) < timeout);
++
++	return 1;
++}
++
++int ltq_pm_disable(enum ltq_pm_modules module)
++{
++	u32 val;
++
++	val = ltq_pm_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_pmu_regs->pwdcr, val);
++
++	return 0;
++}
++
++void ltq_pmu_init(void)
++{
++	u32 set, clr;
++
++	clr = ltq_pm_map(LTQ_PM_CORE);
++	set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
++
++	ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
++}
+--- /dev/null
++++ b/arch/mips/cpu/mips32/arx100/rcu.c
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/soc.h>
++
++#define LTQ_RCU_RD_SRST		(1 << 30)	/* Global SW Reset */
++#define LTQ_RCU_RD_USB1		(1 << 28)	/* USB1 MAC and PHY */
++#define LTQ_RCU_RD_REG25_PD	(1 << 26)	/* Power down 2.5V regulator */
++#define LTQ_RCU_RD_PPE_ATM_TC	(1 << 22)	/* PPE ATM TC */
++#define LTQ_RCU_RD_ETHSW	(1 << 21)	/* Ethernet switch */
++#define LTQ_RCU_RD_DSP_DEN	(1 << 20)	/* Enable DSP JTAG */
++#define LTQ_RCU_RD_TDM		(1 << 19)	/* TDM module interface */
++#define LTQ_RCU_RD_MC		(1 << 14)	/* Memory Controller */
++#define LTQ_RCU_RD_PCI		(1 << 13)	/* PCI core */
++#define LTQ_RCU_RD_SDIO		(1 << 10)	/* SDIO core */
++#define LTQ_RCU_RD_DMA		(1 << 9)	/* DMA core */
++#define LTQ_RCU_RD_PPE		(1 << 8)	/* PPE core */
++#define LTQ_RCU_RD_ARC_DFE	(1 << 7)	/* ARC/DFE core */
++#define LTQ_RCU_RD_AHB		(1 << 6)	/* AHB bus */
++#define LTQ_RCU_RD_USB		(1 << 4)	/* USB and Phy core */
++#define LTQ_RCU_RD_FPI		(1 << 2)	/* FPI bus */
++#define LTQ_RCU_RD_CPU0		(1 << 1)	/* CPU0 subsystem */
++#define LTQ_RCU_RD_HRST		(1 << 0)	/* HW reset via HRST pin */
++
++#define LTQ_RCU_STAT_BOOT_SHIFT		17
++#define LTQ_RCU_STAT_BOOT_MASK		(0xf << LTQ_RCU_STAT_BOOT_SHIFT)
++
++struct ltq_rcu_regs {
++	u32	rsvd0[4];
++	__be32	req;		/* Reset request */
++	__be32	stat;		/* Reset status */
++	__be32	usb0_cfg;	/* USB0 config */
++	u32	rsvd1[2];
++	__be32	pci_rdy;	/* PCI boot ready */
++	__be32	ppe_conf;	/* PPE config */
++	u32	rsvd2;
++	__be32	usb1_cfg;	/* USB1 config */
++};
++
++static struct ltq_rcu_regs *ltq_rcu_regs =
++	(struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
++
++u32 ltq_reset_map(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	switch (module) {
++	case LTQ_RESET_CORE:
++	case LTQ_RESET_SOFT:
++		val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU0;
++		break;
++	case LTQ_RESET_DMA:
++		val = LTQ_RCU_RD_DMA;
++		break;
++	case LTQ_RESET_ETH:
++		val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
++		break;
++	case LTQ_RESET_HARD:
++		val = LTQ_RCU_RD_HRST;
++		break;
++	default:
++		val = 0;
++		break;
++	}
++
++	return val;
++}
++
++int ltq_reset_activate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_setbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++int ltq_reset_deactivate(enum ltq_reset_modules module)
++{
++	u32 val;
++
++	val = ltq_reset_map(module);
++	if (unlikely(!val))
++		return 1;
++
++	ltq_clrbits(&ltq_rcu_regs->req, val);
++
++	return 0;
++}
++
++enum ltq_boot_select ltq_boot_select(void)
++{
++	u32 stat;
++	unsigned int bootstrap;
++
++	stat = ltq_readl(&ltq_rcu_regs->stat);
++	bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
++
++	switch (bootstrap) {
++	case 0:
++		return BOOT_NOR_NO_BOOTROM;
++	case 1:
++		return BOOT_RGMII0;
++	case 2:
++		return BOOT_NOR;
++	case 3:
++		return BOOT_MII0;
++	case 5:
++		return BOOT_RMII0;
++	case 6:
++		return BOOT_PCI;
++	case 8:
++		return BOOT_UART;
++	case 10:
++		return BOOT_SPI;
++	default:
++		return BOOT_UNKNOWN;
++	}
++}
+--- a/arch/mips/cpu/mips32/lantiq-common/cpu.c
++++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
+@@ -20,6 +20,7 @@ static const char ltq_bootsel_strings[][
+ 	"PCI",
+ 	"MII0",
+ 	"RMII0",
++	"RGMII0",
+ 	"RGMII1",
+ 	"unknown",
+ };
+--- a/arch/mips/cpu/mips32/lantiq-common/start.S
++++ b/arch/mips/cpu/mips32/lantiq-common/start.S
+@@ -64,6 +64,11 @@
+ #define STATUS_LANTIQ		(STATUS_MIPS24K | STATUS_MIPS32_64)
+ #endif
+ 
++#ifdef CONFIG_SOC_XWAY_ARX100
++#define CONFIG0_LANTIQ		(CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
++#define STATUS_LANTIQ		(STATUS_MIPS34K | STATUS_MIPS32_64)
++#endif
++
+ #ifdef CONFIG_SOC_XWAY_VRX200
+ #define CONFIG0_LANTIQ		(CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
+ #define STATUS_LANTIQ		(STATUS_MIPS34K | STATUS_MIPS32_64)
+--- /dev/null
++++ b/arch/mips/include/asm/arch-arx100/config.h
+@@ -0,0 +1,176 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ *
++ * Common board configuration for Lantiq XWAY ARX100 family
++ *
++ * Use following defines in your board config to enable specific features
++ * and drivers for this SoC:
++ *
++ * CONFIG_LTQ_SUPPORT_UART
++ * - support the Danube ASC/UART interface and console
++ *
++ * CONFIG_LTQ_SUPPORT_NOR_FLASH
++ * - support a parallel NOR flash via the CFI interface in flash bank 0
++ *
++ * CONFIG_LTQ_SUPPORT_ETHERNET
++ * - support the Danube ETOP and MAC interface
++ *
++ * CONFIG_LTQ_SUPPORT_SPI_FLASH
++ * - support the Danube SPI interface and serial flash drivers
++ * - specific SPI flash drivers must be configured separately
++ */
++
++#ifndef __ARX100_CONFIG_H__
++#define __ARX100_CONFIG_H__
++
++/* CPU and SoC type */
++#define CONFIG_SOC_LANTIQ
++#define CONFIG_SOC_XWAY_ARX100
++
++/* Cache configuration */
++#define CONFIG_SYS_MIPS_CACHE_MODE	CONF_CM_CACHABLE_NONCOHERENT
++#define CONFIG_SYS_DCACHE_SIZE		(16 * 1024)
++#define CONFIG_SYS_ICACHE_SIZE		(32 * 1024)
++#define CONFIG_SYS_CACHELINE_SIZE	32
++#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
++
++/*
++ * Supported clock modes
++ * PLL0: rational PLL running at 500 MHz
++ * PLL1: fractional PLL running at 393.219 MHz
++ */
++#define LTQ_CLK_CPU_393_DDR_197		0
++#define LTQ_CLK_CPU_197_DDR_197		1
++#define LTQ_CLK_CPU_333_DDR_167		2
++#define LTQ_CLK_CPU_167_DDR_167		3
++#define LTQ_CLK_CPU_131_DDR_131		4
++#define LTQ_CLK_CPU_111_DDR_111		5
++
++/* CPU speed */
++#define CONFIG_SYS_CLOCK_MODE		LTQ_CLK_CPU_333_DDR_167
++#define CONFIG_SYS_MIPS_TIMER_FREQ	166666667
++#define CONFIG_SYS_HZ			1000
++
++/* RAM */
++#define CONFIG_NR_DRAM_BANKS		1
++#define CONFIG_SYS_SDRAM_BASE		0x80000000
++#define CONFIG_SYS_SDRAM_BASE_UC	0xa0000000
++#define CONFIG_SYS_MEMTEST_START	0x81000000
++#define CONFIG_SYS_MEMTEST_END		0x82000000
++#define CONFIG_SYS_LOAD_ADDR		0x81000000
++#define CONFIG_SYS_LOAD_SIZE		(2 * 1024 * 1024)
++#define CONFIG_SYS_INIT_SP_OFFSET	(32 * 1024)
++
++/* SRAM */
++#define CONFIG_SYS_SRAM_BASE		0xBE1A0000
++#define CONFIG_SYS_SRAM_SIZE		0x10000
++
++/* ASC/UART driver and console */
++#define CONFIG_LANTIQ_SERIAL
++#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
++
++/* GPIO */
++#define CONFIG_LANTIQ_GPIO
++#define CONFIG_LTQ_GPIO_MAX_BANKS	3
++#define CONFIG_LTQ_HAS_GPIO_BANK3
++
++/* FLASH driver */
++#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
++#define CONFIG_SYS_MAX_FLASH_BANKS	1
++#define CONFIG_SYS_MAX_FLASH_SECT	256
++#define CONFIG_SYS_FLASH_BASE		0xB0000000
++#define CONFIG_FLASH_16BIT
++#define CONFIG_SYS_FLASH_CFI
++#define CONFIG_FLASH_CFI_DRIVER
++#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++#define CONFIG_FLASH_SHOW_PROGRESS	50
++#define CONFIG_SYS_FLASH_PROTECTION
++#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
++
++#define CONFIG_CMD_FLASH
++#else
++#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_NOR_FLASH */
++
++#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
++#define CONFIG_LANTIQ_SPI
++#define CONFIG_SPI_FLASH
++
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_NAND_LANTIQ
++#define CONFIG_SYS_MAX_NAND_DEVICE	1
++#define CONFIG_SYS_NAND_BASE		0xB4000000
++
++#define CONFIG_CMD_NAND
++#endif
++
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_LANTIQ_DMA
++#define CONFIG_LANTIQ_ARX100_SWITCH
++
++#define CONFIG_PHYLIB
++#define CONFIG_MII
++#define CONFIG_UDP_CHECKSUM
++
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#endif
++
++#define CONFIG_SPL_MAX_SIZE		(32 * 1024)
++#define CONFIG_SPL_BSS_MAX_SIZE		(8 * 1024)
++#define CONFIG_SPL_STACK_MAX_SIZE	(8 * 1024)
++#define CONFIG_SPL_MALLOC_MAX_SIZE	(32 * 1024)
++#define CONFIG_SPL_STACK_BSS_IN_SRAM
++
++#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SRAM_BASE + \
++					CONFIG_SPL_MAX_SIZE + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE	  	(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET)
++#else
++#define CONFIG_SPL_STACK_BASE		(CONFIG_SYS_SDRAM_BASE + \
++					CONFIG_SYS_INIT_SP_OFFSET + \
++					CONFIG_SPL_STACK_MAX_SIZE - 1)
++#define CONFIG_SPL_BSS_BASE		(CONFIG_SPL_STACK_BASE + 1)
++#define CONFIG_SPL_MALLOC_BASE		(CONFIG_SPL_BSS_BASE + \
++					CONFIG_SPL_BSS_MAX_SIZE)
++#endif
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_SYS_TEXT_BASE		0xA0100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_SYS_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_SFSPL) || defined(CONFIG_SYS_BOOT_NANDSPL)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SPL_TEXT_BASE		0xBE1A0000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SPL_TEXT_BASE		0xB0000000
++#endif
++
++#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_SYS_XWAY_EBU_BOOTCFG	0x688C688C
++#define CONFIG_XWAY_SWAP_BYTES
++#endif
++
++#define	CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
++
++#endif /* __ARX100_CONFIG_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-arx100/gpio.h
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __ARX100_GPIO_H__
++#define __ARX100_GPIO_H__
++
++#include <asm/lantiq/gpio.h>
++
++#endif /* __ARX100_GPIO_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-arx100/nand.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __VRX200_NAND_H__
++#define __VRX200_NAND_H__
++
++struct nand_chip;
++int ltq_nand_init(struct nand_chip *nand);
++
++#endif /* __VRX200_NAND_H__ */
+--- /dev/null
++++ b/arch/mips/include/asm/arch-arx100/soc.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __ARX100_SOC_H__
++#define __ARX100_SOC_H__
++
++#define LTQ_ASC0_BASE			0x1E100400
++#define LTQ_SPI_BASE			0x1E100800
++#define LTQ_GPIO_BASE			0x1E100B00
++#define LTQ_SSIO_BASE			0x1E100BB0
++#define LTQ_ASC1_BASE			0x1E100C00
++#define LTQ_DMA_BASE			0x1E104100
++
++#define LTQ_EBU_BASE			0x1E105300
++#define LTQ_EBU_REGION0_BASE		0x10000000
++#define LTQ_EBU_REGION1_BASE		0x14000000
++#define LTQ_EBU_NAND_BASE		(LTQ_EBU_BASE + 0xB0)
++
++#define LTQ_PPE_BASE			0x1E180000
++#define LTQ_SWITCH_BASE			0x1E108000
++
++#define LTQ_PMU_BASE			0x1F102000
++#define LTQ_CGU_BASE			0x1F103000
++#define LTQ_MPS_BASE			0x1F107000
++#define LTQ_CHIPID_BASE			(LTQ_MPS_BASE + 0x340)
++#define LTQ_RCU_BASE			0x1F203000
++
++#define LTQ_MC_GEN_BASE			0x1F800000
++#define LTQ_MC_SDR_BASE			0x1F800200
++#define LTQ_MC_DDR_BASE			0x1F801000
++#define LTQ_MC_DDR_DC_OFFSET(x)		(x * 0x10)
++
++#endif /* __ARX100_SOC_H__ */
+--- a/arch/mips/include/asm/lantiq/chipid.h
++++ b/arch/mips/include/asm/lantiq/chipid.h
+@@ -15,6 +15,10 @@ enum ltq_chip_partnum {
+ 	LTQ_SOC_DANUBE = 0x0129,
+ 	LTQ_SOC_DANUBE_S = 0x012B,
+ 	LTQ_SOC_TWINPASS = 0x012D,
++	LTQ_SOC_ARX188 = 0x016C,	/* ARX188 */
++	LTQ_SOC_ARX186 = 0x016D,	/* ARX186 v1.1 */
++	LTQ_SOC_ARX186_2 = 0x016E,	/* ARX186 v1.2 */
++	LTQ_SOC_ARX182 = 0x016F,	/* ARX182 */
+ 	LTQ_SOC_VRX288 = 0x01C0,	/* VRX288 v1.1 */
+ 	LTQ_SOC_VRX268 = 0x01C2,	/* VRX268 v1.1 */
+ 	LTQ_SOC_GRX288 = 0x01C9,	/* GRX288 v1.1 */
+@@ -36,6 +40,38 @@ static inline int ltq_soc_is_danube(void
+ {
+ 	return 0;
+ }
++#endif
++
++#ifdef CONFIG_SOC_XWAY_ARX100
++static inline int ltq_soc_is_arx100(void)
++{
++	return 1;
++}
++
++static inline int ltq_soc_is_arx100_v1(void)
++{
++	return ltq_chip_version_get() == 1;
++}
++
++static inline int ltq_soc_is_arx100_v2(void)
++{
++	return ltq_chip_version_get() == 2;
++}
++#else
++static inline int ltq_soc_is_arx100(void)
++{
++	return 0;
++}
++
++static inline int ltq_soc_is_arx100_v1(void)
++{
++	return 0;
++}
++
++static inline int ltq_soc_is_arx100_v2(void)
++{
++	return 0;
++}
+ #endif
+ 
+ #ifdef CONFIG_SOC_XWAY_VRX200
+--- a/arch/mips/include/asm/lantiq/clk.h
++++ b/arch/mips/include/asm/lantiq/clk.h
+@@ -13,9 +13,10 @@ enum ltq_clk {
+ 	CLOCK_83_MHZ = 83333333,
+ 	CLOCK_111_MHZ = 111111111,
+ 	CLOCK_125_MHZ = 125000000,
++	CLOCK_131_MHZ = 131073000,
+ 	CLOCK_133_MHZ = 133333333,
+ 	CLOCK_166_MHZ = 166666667,
+-	CLOCK_197_MHZ = 197000000,
++	CLOCK_197_MHZ = 196609500,
+ 	CLOCK_333_MHZ = 333333333,
+ 	CLOCK_393_MHZ = 393219000,
+ 	CLOCK_500_MHZ = 500000000,
+--- a/arch/mips/include/asm/lantiq/cpu.h
++++ b/arch/mips/include/asm/lantiq/cpu.h
+@@ -17,6 +17,7 @@ enum ltq_boot_select {
+ 	BOOT_PCI,
+ 	BOOT_MII0,
+ 	BOOT_RMII0,
++	BOOT_RGMII0,
+ 	BOOT_RGMII1,
+ 	BOOT_UNKNOWN,
+ };
diff --git a/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch b/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch
new file mode 100644
index 0000000..16e16d0
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0016-net-add-driver-for-Lantiq-XWAY-ARX100-switch.patch
@@ -0,0 +1,546 @@
+From 7288414298b34dcda1216fee1fe38d05ea0027a2 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 17 Dec 2012 23:32:39 +0100
+Subject: net: add driver for Lantiq XWAY ARX100 switch
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/include/asm/arch-arx100/config.h
++++ b/arch/mips/include/asm/arch-arx100/config.h
+@@ -10,17 +10,21 @@
+  * and drivers for this SoC:
+  *
+  * CONFIG_LTQ_SUPPORT_UART
+- * - support the Danube ASC/UART interface and console
++ * - support the ARX100 ASC/UART interface and console
+  *
+  * CONFIG_LTQ_SUPPORT_NOR_FLASH
+  * - support a parallel NOR flash via the CFI interface in flash bank 0
+  *
+  * CONFIG_LTQ_SUPPORT_ETHERNET
+- * - support the Danube ETOP and MAC interface
++ * - support the ARX100 ETOP and MAC interface
+  *
+  * CONFIG_LTQ_SUPPORT_SPI_FLASH
+- * - support the Danube SPI interface and serial flash drivers
++ * - support the ARX100 SPI interface and serial flash drivers
+  * - specific SPI flash drivers must be configured separately
++ *
++ * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
++ * - build a preloader that runs in the internal SRAM and loads
++ *   the U-Boot from SPI flash into RAM
+  */
+ 
+ #ifndef __ARX100_CONFIG_H__
+--- /dev/null
++++ b/arch/mips/include/asm/arch-arx100/switch.h
+@@ -0,0 +1,86 @@
++/*
++ *   Copyright (C) 2012-2013 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++ *
++ *   SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __ARX100_SWITCH_H__
++#define __ARX100_SWITCH_H__
++
++struct ar9_switch_regs {
++	__be32	ps;		/* Port status*/
++	__be32	p0_ctl;		/* Port 0 control */
++	__be32	p1_ctl;		/* Port 1 control */
++	__be32	p2_ctl;		/* Port 2 control */
++	__be32	p0_vlan;	/* Port 0 VLAN control */
++	__be32	p1_vlan;	/* Port 1 VLAN control */
++	__be32	p2_vlan;	/* Port 2 VLAN control */
++	__be32	p0_inctl;	/* Port 0 ingress control */
++	__be32	p1_inctl;	/* Port 1 ingress control */
++	__be32	p2_inctl;	/* Port 2 ingress control */
++	u32	rsvd0[16];
++	__be32	sw_gctl0;	/* Switch global control 0 */
++	__be32	sw_gctl1;	/* Switch global control 1 */
++	__be32	arp;		/* ARP/RARP */
++	__be32	strm_ctl;	/* Storm control */
++	__be32	rgmii_ctl;	/* RGMII/GMII port control */
++	u32	rsvd1[4];
++	__be32	pmac_hd_ctl;	/* PMAC header control */
++	u32	rsvd2[15];
++	__be32	mdio_ctrl;	/* MDIO indirect access control */
++	__be32	mdio_data;	/* MDIO indirect read data */
++};
++
++#define BUILD_CHECK_AR9_REG(name, offset)	\
++	BUILD_BUG_ON(offsetof(struct ar9_switch_regs, name) != (offset))
++
++static inline void build_check_ar9_registers(void)
++{
++	BUILD_CHECK_AR9_REG(sw_gctl0, 0x68);
++	BUILD_CHECK_AR9_REG(rgmii_ctl, 0x78);
++	BUILD_CHECK_AR9_REG(pmac_hd_ctl, 0x8c);
++	BUILD_CHECK_AR9_REG(mdio_ctrl, 0xcc);
++	BUILD_CHECK_AR9_REG(mdio_data, 0xd0);
++}
++
++#define P0_CTL_FLP		(1 << 18)
++#define P0_CTL_FLD		(1 << 17)
++
++#define SW_GCTL0_SE		(1 << 31)
++
++#define RGMII_CTL_P1_SHIFT	10
++#define RGMII_CTL_P1_MASK	(0x3FF << RGMII_CTL_P1_SHIFT)
++#define RGMII_CTL_P0_MASK	0x3FF
++#define RGMII_CTL_P0IS_SHIFT	8
++#define RGMII_CTL_P0IS_RGMII	(0x0 << RGMII_CTL_P0IS_SHIFT)
++#define RGMII_CTL_P0IS_MII	(0x1 << RGMII_CTL_P0IS_SHIFT)
++#define RGMII_CTL_P0IS_REVMII	(0x2 << RGMII_CTL_P0IS_SHIFT)
++#define RGMII_CTL_P0IS_RMII	(0x3 << RGMII_CTL_P0IS_SHIFT)
++#define RGMII_CTL_P0RDLY_SHIFT	6
++#define RGMII_CTL_P0RDLY_0_0	(0x0 << RGMII_CTL_P0RDLY_SHIFT)
++#define RGMII_CTL_P0RDLY_1_5	(0x1 << RGMII_CTL_P0RDLY_SHIFT)
++#define RGMII_CTL_P0RDLY_1_75	(0x2 << RGMII_CTL_P0RDLY_SHIFT)
++#define RGMII_CTL_P0RDLY_2_0	(0x3 << RGMII_CTL_P0RDLY_SHIFT)
++#define RGMII_CTL_P0TDLY_SHIFT	4
++#define RGMII_CTL_P0TDLY_0_0	(0x0 << RGMII_CTL_P0TDLY_SHIFT)
++#define RGMII_CTL_P0TDLY_1_5	(0x1 << RGMII_CTL_P0TDLY_SHIFT)
++#define RGMII_CTL_P0TDLY_1_75	(0x2 << RGMII_CTL_P0TDLY_SHIFT)
++#define RGMII_CTL_P0TDLY_2_0	(0x3 << RGMII_CTL_P0TDLY_SHIFT)
++#define RGMII_CTL_P0SPD_SHIFT	2
++#define RGMII_CTL_P0SPD_10	(0x0 << RGMII_CTL_P0SPD_SHIFT)
++#define RGMII_CTL_P0SPD_100	(0x1 << RGMII_CTL_P0SPD_SHIFT)
++#define RGMII_CTL_P0SPD_1000	(0x2 << RGMII_CTL_P0SPD_SHIFT)
++#define RGMII_CTL_P0DUP_FULL	(1 << 1)
++#define RGMII_CTL_P0FCE_EN	(1 << 0)
++
++#define PMAC_HD_CTL_AC		(1 << 18)
++
++#define MDIO_CTRL_WD_SHIFT	16
++#define MDIO_CTRL_MBUSY		(1 << 15)
++#define MDIO_CTRL_OP_READ	(1 << 11)
++#define MDIO_CTRL_OP_WRITE	(1 << 10)
++#define MDIO_CTRL_PHYAD_SHIFT	5
++#define MDIO_CTRL_PHYAD_MASK	(0x1f << MDIO_CTRL_PHYAD_SHIFT)
++#define MDIO_CTRL_REGAD_MASK	0x1f
++
++#endif /* __ARX100_SWITCH_H__ */
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -38,6 +38,7 @@ COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks86
+ COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
+ COBJS-$(CONFIG_LAN91C96) += lan91c96.o
+ COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
++COBJS-$(CONFIG_LANTIQ_ARX100_SWITCH) += lantiq_arx100_switch.o
+ COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
+ COBJS-$(CONFIG_MACB) += macb.o
+ COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+--- /dev/null
++++ b/drivers/net/lantiq_arx100_switch.c
+@@ -0,0 +1,410 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++#define DEBUG
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <miiphy.h>
++#include <switch.h>
++#include <linux/compiler.h>
++#include <asm/gpio.h>
++#include <asm/processor.h>
++#include <asm/lantiq/io.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/pm.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/dma.h>
++#include <asm/arch/soc.h>
++#include <asm/arch/switch.h>
++
++#define LTQ_ETH_RX_BUFFER_CNT		PKTBUFSRX
++#define LTQ_ETH_TX_BUFFER_CNT		8
++#define LTQ_ETH_RX_DATA_SIZE		PKTSIZE_ALIGN
++#define LTQ_ETH_IP_ALIGN		2
++
++#define LTQ_MDIO_DRV_NAME		"ltq-mdio"
++#define LTQ_ETH_DRV_NAME		"ltq-eth"
++
++#define LTQ_ETHSW_MAX_GMAC		2
++#define LTQ_ETHSW_PMAC			2
++
++struct ltq_eth_priv {
++	struct ltq_dma_device dma_dev;
++	struct mii_dev *bus;
++	struct eth_device *dev;
++	struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
++	int rx_num;
++	int tx_num;
++};
++
++static struct ar9_switch_regs *switch_regs =
++	(struct ar9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
++
++static int ltq_mdio_is_busy(void)
++{
++	u32 mdio_ctrl = ltq_readl(&switch_regs->mdio_ctrl);
++
++	return mdio_ctrl & MDIO_CTRL_MBUSY;
++}
++
++static void ltq_mdio_poll(void)
++{
++	while (ltq_mdio_is_busy())
++		cpu_relax();
++
++	__udelay(1000);
++}
++
++static int ltq_mdio_read(struct mii_dev *bus, int phyad, int devad,
++					int regad)
++{
++	u32 mdio_ctrl;
++	int retval;
++
++	mdio_ctrl = MDIO_CTRL_MBUSY | MDIO_CTRL_OP_READ |
++		((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++		(regad & MDIO_CTRL_REGAD_MASK);
++
++	ltq_mdio_poll();
++	ltq_writel(&switch_regs->mdio_ctrl, mdio_ctrl);
++	ltq_mdio_poll();
++	retval = ltq_readl(&switch_regs->mdio_data);
++	ltq_writel(&switch_regs->mdio_data, 0xFFFF);
++
++	debug("%s: phyad %02x, regad %02x, val %02x\n", __func__, phyad, regad, retval);
++
++	return retval;
++}
++
++static int ltq_mdio_write(struct mii_dev *bus, int phyad, int devad,
++					int regad, u16 val)
++{
++	u32 mdio_ctrl;
++
++	debug("%s: phyad %02x, regad %02x, val %02x\n", __func__, phyad, regad, val);
++
++	mdio_ctrl = (val << MDIO_CTRL_WD_SHIFT) | MDIO_CTRL_MBUSY |
++		MDIO_CTRL_OP_WRITE |
++		((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
++		(regad & MDIO_CTRL_REGAD_MASK);
++
++	ltq_mdio_poll();
++	ltq_writel(&switch_regs->mdio_ctrl, mdio_ctrl);
++
++	return 0;
++}
++
++static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
++{
++}
++
++static inline u8 *ltq_eth_rx_packet_align(int rx_num)
++{
++	u8 *packet = (u8 *) NetRxPackets[rx_num];
++
++	/*
++	 * IP header needs
++	 */
++	return packet + LTQ_ETH_IP_ALIGN;
++}
++
++static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	struct phy_device *phydev;
++	int i;
++
++	for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++		phydev = priv->phymap[i];
++		if (!phydev)
++			continue;
++
++		phy_startup(phydev);
++		ltq_eth_gmac_update(phydev, i);
++	}
++
++	for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
++		ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
++			LTQ_ETH_RX_DATA_SIZE);
++
++	ltq_dma_enable(dma_dev);
++
++	priv->rx_num = 0;
++	priv->tx_num = 0;
++
++	return 0;
++}
++
++static void ltq_eth_halt(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	struct phy_device *phydev;
++	int i;
++
++	ltq_dma_reset(dma_dev);
++
++	for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
++		phydev = priv->phymap[i];
++		if (!phydev)
++			continue;
++
++		phy_shutdown(phydev);
++		phydev->link = 0;
++		ltq_eth_gmac_update(phydev, i);
++	}
++}
++
++static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	int err;
++
++	err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
++	if (err) {
++		puts("NET: timeout on waiting for TX descriptor\n");
++		return -1;
++	}
++
++	priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
++
++	return err;
++}
++
++static int ltq_eth_recv(struct eth_device *dev)
++{
++	struct ltq_eth_priv *priv = dev->priv;
++	struct ltq_dma_device *dma_dev = &priv->dma_dev;
++	u8 *packet;
++	int len;
++
++	if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
++		return 0;
++
++#if 0
++	printf("%s: rx_num %d\n", __func__, priv->rx_num);
++#endif
++
++	len = ltq_dma_rx_length(dma_dev, priv->rx_num);
++	packet = ltq_eth_rx_packet_align(priv->rx_num);
++
++#if 0
++	printf("%s: received: packet %p, len %u, rx_num %d\n",
++		__func__, packet, len, priv->rx_num);
++#endif
++
++	if (len)
++		NetReceive(packet, len);
++
++	ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
++		LTQ_ETH_RX_DATA_SIZE);
++
++	priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
++
++	return 0;
++}
++
++static void ltq_eth_pmac_init(void)
++{
++	/* Add CRC to packets from DMA to PMAC */
++	ltq_setbits(&switch_regs->pmac_hd_ctl, PMAC_HD_CTL_AC);
++
++	/* Force link up */
++	ltq_setbits(&switch_regs->p2_ctl, P0_CTL_FLP);
++}
++
++static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
++{
++	/* Power up ethernet subsystems */
++	ltq_pm_enable(LTQ_PM_ETH);
++
++	/* Enable switch core */
++	ltq_setbits(&switch_regs->sw_gctl0, SW_GCTL0_SE);
++
++	/* MII/MDIO */
++	gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* MII/MDC */
++	gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++
++	ltq_eth_pmac_init();
++}
++
++static void ltq_eth_port_config(struct ltq_eth_priv *priv,
++				const struct ltq_eth_port_config *port)
++{
++	struct phy_device *phydev;
++	struct switch_device *sw;
++	u32 rgmii_ctl;
++	unsigned int port_ctl, port_xmii = 0;
++
++	if (port->num > 1)
++		return;
++
++	rgmii_ctl = ltq_readl(&switch_regs->rgmii_ctl);
++
++	if (port->num == 1)
++		port_ctl = ltq_readl(&switch_regs->p1_ctl);
++	else
++		port_ctl = ltq_readl(&switch_regs->p0_ctl);
++
++	switch (port->phy_if) {
++	case PHY_INTERFACE_MODE_RGMII:
++		port_xmii = RGMII_CTL_P0IS_RGMII;
++
++		switch (port->rgmii_tx_delay) {
++		case 1:
++			port_xmii |= RGMII_CTL_P0TDLY_1_5;
++			break;
++		case 2:
++			port_xmii |= RGMII_CTL_P0TDLY_1_75;
++			break;
++		case 3:
++			port_xmii |= RGMII_CTL_P0TDLY_2_0;
++			break;
++		default:
++			break;
++		}
++
++		switch (port->rgmii_rx_delay) {
++		case 1:
++			port_xmii |= RGMII_CTL_P0RDLY_1_5;
++			break;
++		case 2:
++			port_xmii |= RGMII_CTL_P0RDLY_1_75;
++			break;
++		case 3:
++			port_xmii |= RGMII_CTL_P0RDLY_2_0;
++			break;
++		default:
++			break;
++		}
++
++		if (!(port->flags & LTQ_ETH_PORT_PHY)) {
++			port_xmii |= (RGMII_CTL_P0SPD_1000 |
++					RGMII_CTL_P0DUP_FULL);
++			port_ctl |= P0_CTL_FLP;
++		}
++
++		break;
++	case PHY_INTERFACE_MODE_MII:
++		port_xmii = RGMII_CTL_P0IS_MII;
++
++		if (!(port->flags & LTQ_ETH_PORT_PHY)) {
++			port_xmii |= (RGMII_CTL_P0SPD_100 |
++					RGMII_CTL_P0DUP_FULL);
++			port_ctl |= P0_CTL_FLP;
++		}
++
++		break;
++	default:
++		break;
++	}
++
++	if (port->num == 1) {
++		ltq_writel(&switch_regs->p1_ctl, port_ctl);
++
++		rgmii_ctl &= ~RGMII_CTL_P1_MASK;
++		rgmii_ctl |= (port_xmii << RGMII_CTL_P1_SHIFT);
++	} else {
++		ltq_writel(&switch_regs->p0_ctl, port_ctl);
++
++		rgmii_ctl &= ~RGMII_CTL_P0_MASK;
++		rgmii_ctl |= port_xmii;
++	}
++
++	ltq_writel(&switch_regs->rgmii_ctl, rgmii_ctl);
++
++	/* Connect to external switch */
++	if (port->flags & LTQ_ETH_PORT_SWITCH) {
++		sw = switch_connect(priv->bus);
++		if (sw)
++			switch_setup(sw);
++	}
++
++	/* Connect to internal/external PHYs */
++	if (port->flags & LTQ_ETH_PORT_PHY) {
++		phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
++					port->phy_if);
++		if (phydev)
++			phy_config(phydev);
++
++		priv->phymap[port->num] = phydev;
++	}
++}
++
++int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
++{
++	struct eth_device *dev;
++	struct mii_dev *bus;
++	struct ltq_eth_priv *priv;
++	struct ltq_dma_device *dma_dev;
++	const struct ltq_eth_port_config *port = &board_config->ports[0];
++	int i, ret;
++
++	build_check_ar9_registers();
++
++	ltq_dma_init();
++	ltq_eth_hw_init(port);
++
++	dev = calloc(1, sizeof(*dev));
++	if (!dev)
++		return -1;
++
++	priv = calloc(1, sizeof(*priv));
++	if (!priv)
++		return -1;
++
++	bus = mdio_alloc();
++	if (!bus)
++		return -1;
++
++	sprintf(dev->name, LTQ_ETH_DRV_NAME);
++	dev->priv = priv;
++	dev->init = ltq_eth_init;
++	dev->halt = ltq_eth_halt;
++	dev->recv = ltq_eth_recv;
++	dev->send = ltq_eth_send;
++
++	sprintf(bus->name, LTQ_MDIO_DRV_NAME);
++	bus->read = ltq_mdio_read;
++	bus->write = ltq_mdio_write;
++	bus->priv = priv;
++
++	dma_dev = &priv->dma_dev;
++	dma_dev->port = 0;
++	dma_dev->rx_chan.chan_no = 0;
++	dma_dev->rx_chan.class = 0;
++	dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
++	dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
++	dma_dev->tx_chan.chan_no = 1;
++	dma_dev->tx_chan.class = 0;
++	dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
++	dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
++	dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
++
++	priv->bus = bus;
++	priv->dev = dev;
++
++	ret = ltq_dma_register(dma_dev);
++	if (ret)
++		return ret;
++
++	ret = mdio_register(bus);
++	if (ret)
++		return ret;
++
++	ret = eth_register(dev);
++	if (ret)
++		return ret;
++
++	for (i = 0; i < board_config->num_ports; i++)
++		ltq_eth_port_config(priv, &board_config->ports[i]);
++
++	return 0;
++}
diff --git a/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch b/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch
new file mode 100644
index 0000000..ef6666a
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0017-tools-add-some-helper-tools-for-Lantiq-SoCs.patch
@@ -0,0 +1,477 @@
+From 1da5479d59b39d7931a2b0efabdfa314f6788b6d Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: tools: add some helper tools for Lantiq SoCs
+
+Signed-off-by: Luka Perkov Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/tools/gct.pl
+@@ -0,0 +1,155 @@
++#!/usr/bin/perl
++
++#use strict;
++#use Cwd;
++#use Env;
++
++my $aline;
++my $lineid;
++my $length;
++my $address;
++my @bytes;
++my $addstr;
++my $chsum=0;
++my $count=0;
++my $firstime=1;
++my $i;
++my $currentaddr;
++my $tmp;
++my $holder="";
++my $loadaddr;
++
++if(@ARGV < 2){
++	die("\n Syntax: perl gct.pl uart_ddr_settings.conf u-boot.srec u-boot.asc\n");
++}
++
++open(IN_UART_DDR_SETTINGS, "<$ARGV[0]") || die("failed to open uart_ddr_settings.conf\n");
++open(IN_UART_SREC, "<$ARGV[1]") || die("failed to open u-boot.srec\n");
++open(OUT_UBOOT_ASC, ">$ARGV[2]") || die("failed to open u-boot.asc\n");
++
++$i=0;
++while ($line = <IN_UART_DDR_SETTINGS>){
++	if($line=~/\w/){
++		if($line!~/[;#\*]/){
++			if($i eq 0){
++				printf OUT_UBOOT_ASC ("33333333");
++			}
++			chomp($line);
++			$line=~s/\t//;
++			@array=split(/ +/,$line);
++			$j=0;
++			while(@array[$j]!~/\w/){
++				$j=$j+1;
++			}
++			$addr=@array[$j];
++			$regval=@array[$j+1];
++			$addr=~s/0x//;
++			$regval=~s/0x//;
++			printf OUT_UBOOT_ASC ("%08x%08x",hex($addr),hex($regval));
++			$i=$i+1;
++			if($i eq 8){
++				$i=0;
++				printf OUT_UBOOT_ASC ("\n");
++			}
++		}
++	}
++}
++
++while($i lt 8 && $i gt 0){
++	printf OUT_UBOOT_ASC "00"x8;
++	$i=$i+1;
++}
++
++if($i eq 8){
++	printf OUT_UBOOT_ASC ("\n");
++}
++
++while($aline=<IN_UART_SREC>){
++	$aline=uc($aline);
++	chomp($aline);
++	next if(($aline=~/^S0/) || ($aline=~/^S7/));
++	($lineid, $length, $address, @bytes) = unpack"A2A2A8"."A2"x300, $aline;
++	$length = hex($length);
++	$address = hex($address);
++	$length -=5;
++	$i=0;
++
++	while($length>0){
++		if($firstime==1){
++			$addstr = sprintf("%x", $address);
++			$addstr = "0"x(8-length($addstr)).$addstr;
++			print OUT_UBOOT_ASC $addstr;
++			addchsum($addstr);
++			$firstime=0;
++			$currentaddr=$address;
++			$loadaddr = $addstr;
++		}
++		else{
++			if($count==64){
++				$addstr = sprintf("%x", $currentaddr);
++				$addstr = "0"x(8-length($addstr)).$addstr;
++				print OUT_UBOOT_ASC $addstr;
++				addchsum($addstr);
++				$count=0;
++			}
++#printf("*** %x != %x\n", $address, $currentaddr) if $address != $currentaddr;
++		}
++		if($currentaddr < $address) {
++			print OUT_UBOOT_ASC "00";
++			addchsum("00");
++			$count++;
++			$currentaddr++;
++		}
++		else {
++			while($count<64){
++				$bytes[$i]=~tr/ABCDEF/abcdef/;
++				print OUT_UBOOT_ASC "$bytes[$i]";
++				addchsum($bytes[$i]);
++				$i++;
++				$count++;
++				$currentaddr++;
++				$length--;
++				last if($length==0);
++			}
++		}
++		if($count==64){
++			print OUT_UBOOT_ASC "\n";
++		}
++	}
++}
++if($count != 64){
++	$tmp = "00";
++	for($i=0;$i<(64-$count);$i++){
++		print OUT_UBOOT_ASC "00";
++		addchsum($tmp);
++	}
++	print OUT_UBOOT_ASC "\n";
++}
++
++
++print OUT_UBOOT_ASC "11"x4;
++use integer;
++$chsum=$chsum & 0xffffffff;
++$chsum = sprintf("%X", $chsum);
++$chsum = "0"x(8-length($chsum)).$chsum;
++$chsum =~tr/ABCDEF/abcdef/;
++print OUT_UBOOT_ASC $chsum;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++print OUT_UBOOT_ASC "99"x4;
++print OUT_UBOOT_ASC $loadaddr;
++print OUT_UBOOT_ASC "00"x60;
++print OUT_UBOOT_ASC "\n";
++
++close OUT_UBOOT_ASC;
++
++sub addchsum{
++	my $cc=$_[0];
++	$holder=$holder.$cc;
++	if(length($holder)==8){
++		$holder = hex($holder);
++		$chsum+=$holder;
++		$holder="";
++	}
++}
+--- /dev/null
++++ b/tools/lantiq_bdi_conf.awk
+@@ -0,0 +1,116 @@
++#!/usr/bin/awk -f
++#
++# Copyright (C) 2013 Luka Perkov <luka@openwrt.org>
++# Copyright (C) 2013 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++#
++# Usage:
++#  awk -f lantiq_bdi_conf.awk -v soc=ar9 board=<name> PATH_TO_BOARD/ddr_settings.h
++#
++# Additional information:
++#  http://www.abatron.ch/fileadmin/user_upload/products/pdf/ManGDBR4K-3000.pdf
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++function print_header()
++{
++	print ";                                                                         "
++	print "; Copyright (C) 2013 Luka Perkov <luka@openwrt.org>                       "
++	print "; Copyright (C) 2013 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>    "
++	print ";                                                                         "
++	print "; This file has been generated with lantiq_bdi_conf.awk script.           "
++	print ";                                                                         "
++	print "; SPDX-License-Identifier:	GPL-2.0+                                 "
++	print ";                                                                         "
++	print ""
++}
++
++function init_ar9_prologue()
++{
++	print "WM32 0xBF103010 0x80		; CGU for CPU 333Mhz, DDR 167Mhz"
++	print "WM32 0xBF103014 0x01		; CGU update"
++	print "WM32 0xBF800010 0x0		; Clear error access log register"
++	print "WM32 0xBF800020 0x0		; Clear error access log register"
++	print "WM32 0xBF800060 0xD		; Enable FPI, DDR and SRAM module in memory controller"
++	print "WM32 0xBF801030 0x0		; Clear start bit of DDR memory controller"
++}
++
++function init_ar9_epilogue()
++{
++	print "WM32 0xBE105360 0x4001D7FF	; EBU setup"
++}
++
++function init_ddr1_epilogue()
++{
++	print "WM32 0xBF801030 0x100		; Set start bit of DDR memory controller"
++}
++
++function ar9_target()
++{
++	print "CPUTYPE		M34K"
++	print "ENDIAN		BIG"
++	print "JTAGCLOCK	1"
++	print "BDIMODE		AGENT		; [ LOADONLY, AGENT ]"
++	print "RESET		JTAG		; [ NONE, JTAG, HARD ]"
++	print "POWERUP		100"
++	print "WAKEUP		100"
++	print "BREAKMODE	HARD		; [ SOFT, HARD ]"
++	print  "STEPMODE	SWBP		; [ JTAG, HWBP, SWBP ]"
++	print "VECTOR		CATCH"
++	print  "SCANSUCC	1 5"
++}
++
++function flash_p2601hnfx()
++{
++	print "CHIPTYPE	MIRRORX16"
++	print "CHIPSIZE	0x1000000"
++	print "BUSWIDTH	16"
++}
++
++BEGIN {
++	switch (soc) {
++	case "ar9":
++		reg_base = 0xbf801000
++		print_header()
++		print "[INIT]"
++		init_ar9_prologue()
++		break
++	default:
++		print "Invalid or no value for SoC specified!"
++		exit 1
++	}
++}
++
++/^#define/ {
++	/* DC03 contains MC enable bit and must not be set here */
++	if (tolower($2) != "mc_dc03_value")
++		printf("WM32 0x%x %s\n", reg_base, tolower($3))
++
++	reg_base += 0x10
++}
++
++END {
++	switch (soc) {
++	case "ar9":
++		init_ddr1_epilogue()
++		init_ar9_epilogue()
++		print ""
++		print "[TARGET]"
++		ar9_target()
++		print ""
++		print "[HOST]"
++		print "PROMPT		\"ar9> \""
++		print ""
++		break
++	default:
++	}
++
++	switch (board) {
++	case "p2601hnfx":
++		print "[FLASH]"
++		flash_p2601hnfx()
++		print ""
++		break
++	default:
++	}
++}
+--- /dev/null
++++ b/tools/lantiq_ram_extract_magic.awk
+@@ -0,0 +1,69 @@
++#
++# Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++#
++# Usage:
++# mips-openwrt-linux-objdump -EB -b binary -m mips:isa32r2 -D YOUR_IMAGE_DUMP | awk -f lantiq_ram_extract_magic.awk
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++BEGIN {
++	print "/*                                                                            "
++	print " * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>                     "
++	print " *                                                                            "
++	print " * This file has been generated with lantiq_ram_extract_magic.awk script.     "
++	print " *                                                                            "
++	print " * SPDX-License-Identifier:	GPL-2.0+                                     "
++	print " */                                                                           "
++	print ""
++
++	mc_dc_value=0
++	mc_dc_number=0
++	right_section=0
++	mc_dc_value_print=0
++	mc_dc_number_print=0
++}
++
++/t2,[0-9]+$/ {
++	if (right_section) {
++		split($4, tmp, ",")
++		mc_dc_value=sprintf("%X", tmp[2])
++		mc_dc_value_print=1
++	}
++}
++
++/t2,0x[0-9a-f]+$/ {
++	if (right_section) {
++		split($4, tmp, ",0x")
++		mc_dc_value=sprintf("%s", tmp[2])
++		mc_dc_value=toupper(mc_dc_value)
++		mc_dc_value_print=1
++	}
++}
++
++/t2,[0-9]+\(t1\)$/ {
++	if (right_section) {
++		split($4, tmp, ",")
++		split(tmp[2], tmp, "(")
++		mc_dc_number=tmp[1]/16
++		mc_dc_number_print=1
++	}
++}
++
++{
++	if (right_section && mc_dc_number_print && mc_dc_value_print) {
++		if (mc_dc_number < 10)
++			print "#define MC_DC0" mc_dc_number "_VALUE\t0x" mc_dc_value
++		else
++			print "#define MC_DC" mc_dc_number "_VALUE\t0x" mc_dc_value
++		mc_dc_value_print=0
++		mc_dc_number_print=0
++	}
++
++	if ($4 == "t1,t1,0x1000")
++		right_section=1
++
++
++	if ($4 == "t2,736(t1)")
++		right_section=0
++}
+--- /dev/null
++++ b/tools/lantiq_ram_init_uart.awk
+@@ -0,0 +1,117 @@
++#!/usr/bin/awk -f
++#
++# Copyright (C) 2011-2012 Luka Perkov <luka@openwrt.org>
++# Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++#
++# Usage:
++# awk -f lantiq_ram_init_uart.awk -v soc=<danube|ar9|vr9> PATH_TO_BOARD/ddr_settings.h
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++function print_header()
++{
++	print ";                                                                            "
++	print "; Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>                     "
++	print "; Copyright (C) 2012-2013 Daniel Schwierzeck <daniel.schwierzeck@gmail.com>  "
++	print ";                                                                            "
++	print "; This file has been generated with lantiq_ram_init_uart.awk script.         "
++	print ";                                                                            "
++	print "; SPDX-License-Identifier:	GPL-2.0+                                    "
++	print ""
++}
++
++function mc_danube_prologue()
++{
++	/* Clear access error log registers */
++	print "0xbf800010", "0x0"
++	print "0xbf800020", "0x0"
++
++	/* Enable DDR and SRAM module in memory controller */
++	print "0xbf800060", "0x5"
++
++	/* Clear start bit of DDR memory controller */
++	print "0xbf801030", "0x0"
++}
++
++function mc_ar9_prologue()
++{
++	/* Clear access error log registers */
++	print "0xbf800010", "0x0"
++	print "0xbf800020", "0x0"
++
++	/* Enable FPI, DDR and SRAM module in memory controller */
++	print "0xbf800060", "0xD"
++
++	/* Clear start bit of DDR memory controller */
++	print "0xbf801030", "0x0"
++}
++
++function mc_ddr1_epilogue()
++{
++	/* Set start bit of DDR memory controller */
++	print "0xbf801030", "0x100"
++}
++
++function mc_ddr2_prologue()
++{
++	/* Put memory controller in inactive mode */
++	print "0xbf401070", "0x0"
++}
++
++function mc_ddr2_epilogue(mc_ccr07_value)
++{
++	/* Put memory controller in active mode */
++	mc_ccr07_value = or(mc_ccr07_value, 0x100)
++	printf("0xbf401070 0x%x\n", mc_ccr07_value)
++}
++
++BEGIN {
++	switch (soc) {
++	case "danube":
++		reg_base = 0xbf801000
++		print_header()
++		mc_danube_prologue()
++		break
++	case "ar9":
++		reg_base = 0xbf801000
++		print_header()
++		mc_ar9_prologue()
++		break
++	case "vr9":
++		reg_base = 0xbf401000
++		print_header()
++		mc_ddr2_prologue()
++		break
++	default:
++		print "Invalid or no value for soc specified!"
++		exit 1
++	}
++
++	mc_ccr07_value = 0
++}
++
++/^#define/ {
++	/* CCR07 contains MC enable bit and must not be set here */
++	if (tolower($2) == "mc_ccr07_value")
++		mc_ccr07_value = strtonum($3)
++	if (tolower($2) == "mc_dc03_value")
++		/* CCR07 contains MC enable bit and must not be set here */
++	else
++		printf("0x%x %s\n", reg_base, tolower($3))
++
++	reg_base += 0x10
++}
++
++END {
++	switch (soc) {
++	case "danube":
++	case "ar9":
++		mc_ddr1_epilogue()
++		break
++	case "vr9":
++		mc_ddr2_epilogue(mc_ccr07_value)
++		break
++	default:
++	}
++}
diff --git a/package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch
new file mode 100644
index 0000000..6d1b8dc
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0018-tools-lantiq-add-NAND-SPL-support.patch
@@ -0,0 +1,223 @@
+From 43b9a7c9b903302c56d0a1d292a146dbf4de8e49 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 12 Aug 2013 01:17:08 +0200
+Subject: tools: lantiq: add NAND SPL support
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/tools/ltq-boot-image.c
++++ b/tools/ltq-boot-image.c
+@@ -14,7 +14,8 @@
+ 
+ enum image_types {
+ 	IMAGE_NONE,
+-	IMAGE_SFSPL
++	IMAGE_SFSPL,
++	IMAGE_NANDSPL
+ };
+ 
+ /* Lantiq non-volatile bootstrap command IDs */
+@@ -43,6 +44,8 @@ enum nvb_cmd_flags {
+ struct args {
+ 	enum image_types type;
+ 	__u32		entry_addr;
++	off_t		uboot_offset;
++	unsigned int	page_size;
+ 	const char	*uboot_bin;
+ 	const char	*spl_bin;
+ 	const char	*out_bin;
+@@ -50,10 +53,11 @@ struct args {
+ 
+ static void usage_msg(const char *name)
+ {
+-	fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
++	fprintf(stderr, "%s: [-h] -t type -e entry-addr [-x uboot-offset] [-p page-size] -u uboot-bin [-s spl-bin] -o out-bin\n",
+ 		name);
+ 	fprintf(stderr, " Image types:\n"
+-			"  sfspl  - SPL + [compressed] U-Boot for SPI flash\n");
++			"  sfspl   - SPL + [compressed] U-Boot for SPI flash\n"
++			"  nandspl - SPL + [compressed] U-Boot for NAND flash\n");
+ }
+ 
+ static enum image_types parse_image_type(const char *type)
+@@ -64,6 +68,9 @@ static enum image_types parse_image_type
+ 	if (!strncmp(type, "sfspl", 6))
+ 		return IMAGE_SFSPL;
+ 
++	if (!strncmp(type, "nandspl", 6))
++		return IMAGE_NANDSPL;
++
+ 	return IMAGE_NONE;
+ }
+ 
+@@ -73,7 +80,7 @@ static int parse_args(int argc, char *ar
+ 
+ 	memset(arg, 0, sizeof(*arg));
+ 
+-	while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
++	while ((opt = getopt(argc, argv, "ht:e:x:p:u:s:o:")) != -1) {
+ 		switch (opt) {
+ 		case 'h':
+ 			usage_msg(argv[0]);
+@@ -84,6 +91,12 @@ static int parse_args(int argc, char *ar
+ 		case 'e':
+ 			arg->entry_addr = strtoul(optarg, NULL, 16);
+ 			break;
++		case 'x':
++			arg->uboot_offset = strtoul(optarg, NULL, 16);
++			break;
++		case 'p':
++			arg->page_size = strtoul(optarg, NULL, 10);
++			break;
+ 		case 'u':
+ 			arg->uboot_bin = optarg;
+ 			break;
+@@ -114,11 +127,22 @@ static int parse_args(int argc, char *ar
+ 		goto parse_error;
+ 	}
+ 
+-	if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
++	if ((arg->type == IMAGE_SFSPL || arg->type == IMAGE_NANDSPL) &&
++		!arg->spl_bin) {
+ 		fprintf(stderr, "Missing SPL binary\n");
+ 		goto parse_error;
+ 	}
+ 
++	if (arg->type == IMAGE_NANDSPL && !arg->uboot_offset) {
++		fprintf(stderr, "Missing U-Boot offset\n");
++		goto parse_error;
++	}
++
++	if (arg->type == IMAGE_NANDSPL && !arg->page_size) {
++		fprintf(stderr, "Missing NAND page size\n");
++		goto parse_error;
++	}
++
+ 	return 0;
+ 
+ parse_error:
+@@ -174,6 +198,19 @@ static int write_nvb_start_header(int fd
+ 	return write_header(fd, hdr, sizeof(hdr));
+ }
+ 
++#if 0
++static int write_nvb_regcfg_header(int fd, __u32 addr)
++{
++	__u32 hdr[2];
++
++	hdr[0] = build_nvb_command(NVB_CMD_REGCFG, NVB_FLAG_SDBG |
++					NVB_FLAG_DBG);
++	hdr[1] = cpu_to_be32(addr);
++
++	return write_header(fd, hdr, sizeof(hdr));
++}
++#endif
++
+ static int open_input_bin(const char *name, void **ptr, size_t *size)
+ {
+ 	struct stat sbuf;
+@@ -238,9 +275,37 @@ static int open_output_bin(const char *n
+ 	return fd;
+ }
+ 
+-static int create_sfspl(const struct args *arg)
++static int pad_to_offset(int fd, off_t offset)
+ {
+-	int out_fd, uboot_fd, spl_fd, ret;
++	off_t pos;
++	size_t size;
++	ssize_t n;
++	__u8 *buf;
++
++	pos = lseek(fd, 0, SEEK_CUR);
++	size = offset - pos;
++
++	buf = malloc(size);
++	if (!buf) {
++		fprintf(stderr, "Failed to malloc buffer\n");
++		return -1;
++	}
++
++	memset(buf, 0xff, size);
++	n = write(fd, buf, size);
++	free(buf);
++
++	if (n != size) {
++		fprintf(stderr, "Failed to write pad bytes\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++static int create_spl_image(const struct args *arg)
++{
++	int out_fd, uboot_fd, spl_fd, ret = 0;
+ 	void *uboot_ptr, *spl_ptr;
+ 	size_t uboot_size, spl_size;
+ 
+@@ -256,9 +321,22 @@ static int create_sfspl(const struct arg
+ 	if (0 > uboot_fd)
+ 		goto err_uboot;
+ 
++#if 0
++	ret = write_nvb_regcfg_header(out_fd, 0);
++	if (ret)
++		goto err_write;
++#endif
++
+ 	ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
+ 	if (ret)
+ 		goto err_write;
++#if 0
++	if (arg->page_size) {
++		ret = pad_to_offset(out_fd, arg->page_size);
++		if (ret)
++			goto err_write;
++	}
++#endif
+ 
+ 	ret = copy_bin(out_fd, spl_ptr, spl_size);
+ 	if (ret)
+@@ -268,16 +346,16 @@ static int create_sfspl(const struct arg
+ 	if (ret)
+ 		goto err_write;
+ 
++	if (arg->uboot_offset) {
++		ret = pad_to_offset(out_fd, arg->uboot_offset);
++		if (ret)
++			goto err_write;
++	}
++
+ 	ret = copy_bin(out_fd, uboot_ptr, uboot_size);
+ 	if (ret)
+ 		goto err_write;
+ 
+-	close_input_bin(uboot_fd, uboot_ptr, uboot_size);
+-	close_input_bin(spl_fd, spl_ptr, spl_size);
+-	close(out_fd);
+-
+-	return 0;
+-
+ err_write:
+ 	close_input_bin(uboot_fd, uboot_ptr, uboot_size);
+ err_uboot:
+@@ -285,7 +363,7 @@ err_uboot:
+ err_spl:
+ 	close(out_fd);
+ err:
+-	return -1;
++	return ret;
+ }
+ 
+ int main(int argc, char *argv[])
+@@ -299,7 +377,8 @@ int main(int argc, char *argv[])
+ 
+ 	switch (arg.type) {
+ 	case IMAGE_SFSPL:
+-		ret = create_sfspl(&arg);
++	case IMAGE_NANDSPL:
++		ret = create_spl_image(&arg);
+ 		break;
+ 	default:
+ 		fprintf(stderr, "Image type not implemented\n");
diff --git a/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch b/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch
new file mode 100644
index 0000000..53df7ac
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0019-Makefile-add-Lantiq-NAND-SPL-images.patch
@@ -0,0 +1,46 @@
+From 2e01dc015bc8bb9ca45f369025c342ede990863e Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 12 Aug 2013 01:16:09 +0200
+Subject: Makefile: add Lantiq NAND SPL images
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/.gitignore
++++ b/.gitignore
+@@ -54,6 +54,9 @@
+ /u-boot.ltq.lzma.norspl
+ /u-boot.ltq.lzo.norspl
+ /u-boot.ltq.norspl
++/u-boot.ltq.lzma.nandspl
++/u-boot.ltq.lzo.nandspl
++/u-boot.ltq.nandspl
+ /u-boot.lzma.img
+ /u-boot.lzo.img
+ 
+--- a/Makefile
++++ b/Makefile
+@@ -599,6 +599,24 @@ $(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boo
+ 		$(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
+ 			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
+ 
++$(obj)u-boot.ltq.nandspl:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \
++			-p $(CONFIG_SYS_NAND_PAGE_SIZE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzo.nandspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \
++			-p $(CONFIG_SYS_NAND_PAGE_SIZE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
++$(obj)u-boot.ltq.lzma.nandspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
++		$(obj)tools/ltq-boot-image -t nandspl -e $(CONFIG_SPL_TEXT_BASE) \
++			-x $(CONFIG_SYS_NAND_U_BOOT_OFFS) \
++			-p $(CONFIG_SYS_NAND_PAGE_SIZE) \
++			-s $(obj)spl/u-boot-spl.bin -u $< -o $@
++
+ $(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+ 	cat $(obj)spl/u-boot-spl.bin $< > $@
+ 
diff --git a/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch
new file mode 100644
index 0000000..8d9eca7
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0020-MIPS-lantiq-add-NAND-SPL-support.patch
@@ -0,0 +1,165 @@
+From e17398316e82d8b28217232b4fd6030c65138e74 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 12 Aug 2013 01:18:00 +0200
+Subject: MIPS: lantiq: add NAND SPL support
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/cpu/mips32/lantiq-common/spl.c
++++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
+@@ -8,6 +8,7 @@
+ #include <image.h>
+ #include <version.h>
+ #include <spi_flash.h>
++#include <nand.h>
+ #include <linux/compiler.h>
+ #include <lzma/LzmaDec.h>
+ #include <linux/lzo.h>
+@@ -63,6 +64,18 @@
+ #define spl_boot_nor_flash	0
+ #endif
+ 
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH) && defined(CONFIG_SYS_BOOT_NANDSPL)
++#define spl_boot_nand_flash	1
++#else
++#define spl_boot_nand_flash	0
++#ifndef CONFIG_SYS_NAND_U_BOOT_OFFS
++#define CONFIG_SYS_NAND_U_BOOT_OFFS	0
++#endif
++#ifndef CONFIG_SYS_NAND_PAGE_SIZE
++#define CONFIG_SYS_NAND_PAGE_SIZE	0
++#endif
++#endif
++
+ #define spl_sync()	__asm__ __volatile__("sync");
+ 
+ struct spl_image {
+@@ -337,6 +350,58 @@ static int spl_load_nor_flash(struct spl
+ 	return ret;
+ }
+ 
++static int spl_load_nand_flash(struct spl_image *spl)
++{
++	image_header_t *hdr;
++	int ret;
++	unsigned long loadaddr;
++
++	/*
++	 * Image format:
++	 *
++	 * - 12 byte non-volatile bootstrap header
++	 * - SPL binary
++	 * - 12 byte non-volatile bootstrap header
++	 * - padding bytes up to CONFIG_SYS_NAND_U_BOOT_OFFS
++	 * - 64 byte U-Boot mkimage header
++	 * - U-Boot binary
++	 */
++	spl->data_addr = CONFIG_SYS_NAND_U_BOOT_OFFS;
++
++	spl_puts("SPL: initializing NAND flash\n");
++	nand_init();
++
++	spl_debug("SPL: reading image header at page offset %lx\n",
++		  spl->data_addr);
++
++	hdr = (image_header_t *) CONFIG_LOADADDR;
++	ret = nand_spl_load_image(spl->data_addr,
++				  CONFIG_SYS_NAND_PAGE_SIZE, hdr);
++	if (ret)
++		return ret;
++
++	spl_debug("SPL: checking image header at address %p\n", hdr);
++
++	ret = spl_parse_image(hdr, spl);
++	if (ret)
++		return ret;
++
++	if (spl_is_compressed(spl))
++		loadaddr = CONFIG_LOADADDR;
++	else
++		loadaddr = spl->entry_addr;
++
++	spl_puts("SPL: loading U-Boot to RAM\n");
++
++	ret = nand_spl_load_image(spl->data_addr, spl->data_size,
++				  (void *) loadaddr);
++
++	if (spl_is_compressed(spl))
++		ret = spl_uncompress(spl, loadaddr);
++
++	return ret;
++}
++
+ static int spl_load(struct spl_image *spl)
+ {
+ 	int ret;
+@@ -345,6 +410,8 @@ static int spl_load(struct spl_image *sp
+ 		ret = spl_load_spi_flash(spl);
+ 	else if (spl_boot_nor_flash)
+ 		ret = spl_load_nor_flash(spl);
++	else if (spl_boot_nand_flash)
++		ret = spl_load_nand_flash(spl);
+ 	else
+ 		ret = 1;
+ 
+--- a/arch/mips/include/asm/lantiq/config.h
++++ b/arch/mips/include/asm/lantiq/config.h
+@@ -40,6 +40,26 @@
+ #define CONFIG_SPI_SPL_SIMPLE
+ #endif
+ 
++/*
++ * NAND flash SPL
++ * BOOT CFG 06 only (address cycle based probing, 2KB or 512B page size)
++ */
++#if defined(CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH) && defined(CONFIG_SYS_BOOT_NANDSPL)
++#define CONFIG_SPL
++#define CONFIG_SPL_NAND_SUPPORT
++#define CONFIG_SPL_NAND_DRIVERS
++#define CONFIG_SPL_NAND_SIMPLE
++#define CONFIG_SPL_NAND_ECC
++
++/* use software ECC until driver supports HW ECC */
++#define CONFIG_SPL_NAND_SOFTECC
++#define CONFIG_SYS_NAND_ECCSIZE		256
++#define CONFIG_SYS_NAND_ECCBYTES	3
++#define CONFIG_SYS_NAND_ECCPOS		{40, 41, 42, 43, 44, 45, 46, 47, \
++					48, 49, 50, 51, 52, 53, 54, 55, \
++					56, 57, 58, 59, 60, 61, 62, 63}
++#endif
++
+ #if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
+ #define CONFIG_SPL
+ #endif
+@@ -148,6 +168,21 @@
+ #define CONFIG_ENV_LOAD_UBOOT_SF
+ #endif
+ 
++#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
++#define CONFIG_ENV_WRITE_UBOOT_NAND				\
++	"write-uboot-nand="					\
++	"nand erase 0 $filesize && "				\
++	"nand write $fileaddr 0 $filesize\0"
++
++#define CONFIG_ENV_LOAD_UBOOT_NAND						\
++	"load-uboot-nandspl=tftpboot u-boot.ltq.nandspl\0"			\
++	"load-uboot-nandspl-lzo=tftpboot u-boot.ltq.lzo.nandspl\0"		\
++	"load-uboot-nandspl-lzma=tftpboot u-boot.ltq.lzma.nandspl\0"
++#else
++#define CONFIG_ENV_WRITE_UBOOT_NAND
++#define CONFIG_ENV_LOAD_UBOOT_NAND
++#endif
++
+ #define CONFIG_ENV_LANTIQ_DEFAULTS	\
+ 	CONFIG_ENV_CONSOLEDEV		\
+ 	CONFIG_ENV_ADDCONSOLE		\
+@@ -159,6 +194,8 @@
+ 	CONFIG_ENV_LOAD_UBOOT_NOR	\
+ 	CONFIG_ENV_SF_PROBE		\
+ 	CONFIG_ENV_WRITE_UBOOT_SF	\
+-	CONFIG_ENV_LOAD_UBOOT_SF
++	CONFIG_ENV_LOAD_UBOOT_SF	\
++	CONFIG_ENV_WRITE_UBOOT_NAND	\
++	CONFIG_ENV_LOAD_UBOOT_NAND
+ 
+ #endif /* __LANTIQ_CONFIG_H__ */
diff --git a/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch b/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch
new file mode 100644
index 0000000..8296f2c
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0021-MIPS-vrx200-add-NAND-SPL-support.patch
@@ -0,0 +1,30 @@
+From 7361581a1baaec43058f5b9350c32c7ac4e58064 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Mon, 12 Aug 2013 00:11:16 +0200
+Subject: MIPS: vrx200: add NAND SPL support
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/arch/mips/cpu/mips32/vrx200/config.mk
++++ b/arch/mips/cpu/mips32/vrx200/config.mk
+@@ -27,4 +27,9 @@ ALL-y += $(obj)u-boot.ltq.norspl
+ ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
+ ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
+ endif
++ifdef CONFIG_SYS_BOOT_NANDSPL
++ALL-y += $(obj)u-boot.ltq.nandspl
++ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.nandspl
++ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.nandspl
++endif
+ endif
+--- a/arch/mips/include/asm/arch-vrx200/config.h
++++ b/arch/mips/include/asm/arch-vrx200/config.h
+@@ -167,7 +167,7 @@
+ #define CONFIG_SYS_TEXT_BASE		0xB0000000
+ #endif
+ 
+-#if defined(CONFIG_SYS_BOOT_SFSPL)
++#if defined(CONFIG_SYS_BOOT_SFSPL) || defined(CONFIG_SYS_BOOT_NANDSPL)
+ #define CONFIG_SYS_TEXT_BASE		0x80100000
+ #define CONFIG_SPL_TEXT_BASE		0xBE220000
+ #endif
diff --git a/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-add-default-openwrt-config.patch b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-add-default-openwrt-config.patch
new file mode 100644
index 0000000..20bff44
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-add-default-openwrt-config.patch
@@ -0,0 +1,51 @@
+From 8f584936adad0fca8beece5f55eadcdcd02fad0a Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Sat, 17 Aug 2013 03:44:46 +0200
+Subject: MIPS: lantiq: add default openwrt config
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/include/configs/openwrt-lantiq-common.h
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __OPENWRT_LANTIQ_COMMON_H
++#define __OPENWRT_LANTIQ_COMMON_H
++
++/* Commands */
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_TFTPPUT
++#endif
++
++/* Compression */
++#define CONFIG_LZMA
++
++/* Auto boot */
++#define CONFIG_BOOTDELAY	2
++
++/* Environment */
++#if !defined(CONFIG_SYS_BOOT_RAM)
++#define CONFIG_BOOTCOMMAND \
++	"bootm ${kernel_addr}"
++#endif
++
++/* Ethernet */
++#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
++#define CONFIG_ETHADDR		00:01:02:03:04:05
++#define CONFIG_SERVERIP		192.168.1.2
++#define CONFIG_IPADDR		192.168.1.1
++#endif
++
++/* Unnecessary */
++#undef CONFIG_BOOTM_NETBSD
++#undef CONFIG_BOOTM_PLAN9
++#undef CONFIG_BOOTM_RTEMS
++
++#endif /* __OPENWRT_LANTIQ_COMMON_H */
diff --git a/package/boot/uboot-lantiq/patches/0023-lzma-fixup.patch b/package/boot/uboot-lantiq/patches/0023-lzma-fixup.patch
new file mode 100644
index 0000000..7c15938
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0023-lzma-fixup.patch
@@ -0,0 +1,39 @@
+From: Antonios Vamporakis <ant@area128.com>
+Date: Tue, 31 Dec 2013 01:05:42 +0100
+Subject: [PATCH] lzma: fix buffer bound check error
+
+Variable uncompressedSize references the space available, while outSizeFull is
+the actual expected uncompressed size. Using the wrong value causes LzmaDecode
+to return SZ_ERROR_INPUT_EOF. Problem was introduced in commit afca294. While
+at it add additional debug message.
+
+Signed-off-by: Antonios Vamporakis <ant@area128.com>
+CC: Kees Cook <keescook@chromium.org>
+CC: Simon Glass <sjg@chromium.org>
+CC: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+CC: Luka Perkov <luka@openwrt.org>
+---
+ lib/lzma/LzmaTools.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/lib/lzma/LzmaTools.c
++++ b/lib/lzma/LzmaTools.c
+@@ -102,7 +102,7 @@ int lzmaBuffToBuffDecompress (unsigned c
+         return SZ_ERROR_OUTPUT_EOF;
+ 
+     /* Decompress */
+-    outProcessed = *uncompressedSize;
++    outProcessed = outSizeFull;
+ 
+     WATCHDOG_RESET();
+ 
+@@ -111,6 +111,9 @@ int lzmaBuffToBuffDecompress (unsigned c
+         inStream + LZMA_DATA_OFFSET, &compressedSize,
+         inStream, LZMA_PROPS_SIZE, LZMA_FINISH_END, &state, &g_Alloc);
+     *uncompressedSize = outProcessed;
++
++    debug("LZMA: Uncompresed ................ 0x%zx\n", outProcessed);
++
+     if (res != SZ_OK)  {
+         return res;
+     }
diff --git a/package/boot/uboot-lantiq/patches/0024-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch b/package/boot/uboot-lantiq/patches/0024-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch
new file mode 100644
index 0000000..1f89e54
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0024-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch
@@ -0,0 +1,18 @@
+From 7e2f79bc40b572763a4a1ed69f63aa2eaa6df254 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sun, 20 Oct 2013 19:39:17 +0200
+Subject: Makefile: prepare u-boot-lantiq-v2013.10-openwrt4
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- a/Makefile
++++ b/Makefile
+@@ -8,7 +8,7 @@
+ VERSION = 2013
+ PATCHLEVEL = 10
+ SUBLEVEL =
+-EXTRAVERSION =
++EXTRAVERSION = -openwrt4
+ ifneq "$(SUBLEVEL)" ""
+ U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+ else
diff --git a/package/boot/uboot-lantiq/patches/0025-arx100-cgu-fixes.patch b/package/boot/uboot-lantiq/patches/0025-arx100-cgu-fixes.patch
new file mode 100644
index 0000000..ff2f99c
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0025-arx100-cgu-fixes.patch
@@ -0,0 +1,148 @@
+From patchwork Tue Jan 20 11:28:45 2015
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [OpenWrt-Devel] uboot-lantiq cgu settings for ramboot image
+From: Ben Mulvihill <ben.mulvihill@gmail.com>
+X-Patchwork-Id: 431024
+Message-Id: <1421753325.25187.58.camel@merveille.lan>
+To: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Cc: OpenWrt Development List <openwrt-devel@lists.openwrt.org>
+Date: Tue, 20 Jan 2015 12:28:45 +0100
+
+On Tue, 2015-01-20 at 00:39 +0100, Ben Mulvihill wrote:
+> On Mon, 2015-01-19 at 19:21 +0100, Ben Mulvihill wrote:
+> > On Mon, 2015-01-19 at 16:47 +0100, Daniel Schwierzeck wrote:
+> > > 2015-01-19 15:44 GMT+01:00 Ben Mulvihill <ben.mulvihill@gmail.com>:
+> > > > On Mon, 2015-01-19 at 11:51 +0000, Conor O'Gorman wrote:
+> > > >> On 19/01/15 10:46, Ben Mulvihill wrote:
+> > > >> > Hello,
+> > > >> >
+> > > >> > I am trying to build uboot-lantiq for the BT Home Hub 3A (lantiq
+> > > >> > ar9), and am wondering where to initialise the cgu, in the case
+> > > >> > of a ramboot image for uart booting. Normally the cgu is initialised
+> > > >> > in lowlevel_init, but that code is bypassed in ramboot images. The
+> > > >> > result is that the board boots with the wrong cgu settings, which
+> > > >> > sends the console haywire. So far I have tried two solutions:
+> > > >>
+> > > >> Another option is to try and not change anything. The console is already
+> > > >> configured and running. The ram does need config.
+> > > >>
+> > > >> I was used to seeing the ramboot version running at half clock speed, at
+> > > >> least on danube, previous to ar9.
+> > > >>
+> > > >> Conor
+> > > >
+> > > > Hi Conor,
+> > > >
+> > > > Thanks for the reply. But with the latest uboot-lantiq, not changing
+> > > > anything means that I don't get a usable console. With an older
+> > > > version I do at least get a uboot console, but no linux console when
+> > > > I boot openwrt. Correcting the cgu settings solves both problems.
+> > > >
+> > > 
+> > > could you try this?
+> > > 
+> > > diff --git a/arch/mips/cpu/mips32/arx100/cgu.c
+> > > b/arch/mips/cpu/mips32/arx100/cgu.c
+> > > index 6e71ee7..e0afbda 100644
+> > > --- a/arch/mips/cpu/mips32/arx100/cgu.c
+> > > +++ b/arch/mips/cpu/mips32/arx100/cgu.c
+> > > @@ -95,15 +95,5 @@ unsigned long ltq_get_cpu_clock(void)
+> > > 
+> > >  unsigned long ltq_get_bus_clock(void)
+> > >  {
+> > > -       u32 fpi_sel;
+> > > -       unsigned long clk;
+> > > -
+> > > -       fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL);
+> > > -
+> > > -       if (fpi_sel)
+> > > -               clk = ltq_get_io_region_clock() / 2;
+> > > -       else
+> > > -               clk = ltq_get_io_region_clock();
+> > > -
+> > > -       return clk;
+> > > +       return ltq_get_io_region_clock();
+> > >  }
+> > > 
+> > > the UART driver calculates the baudrate from the FPI bus clock, but
+> > > FPI_SEL is not available on AR9. FPI bus clock is always the same as
+> > > DDR clock, Obviously a copy&paste error from VR9 code ;)
+> > > 
+> > 
+> > No, even with this patch, I still don't get a working console I'm
+> > afraid. If I don't set anything explicitly, the board comes up with
+> > CGU_SYS set to 0x05, ie CGU_SYS_SYSSEL_PLL0_333_MHZ |
+> > CGU_SYS_CPUSEL_EQUAL_DDRCLK | CGU_SYS_DDRSEL_THIRD_SYSCLK.
+> > Is this a valid combination without CGU_SYS_PPESEL_250_MHZ ?
+> > I don't understand what CGU_SYS_PPESEL_250_MHZ does?
+> > The "right setting", as set by the stock uboot, is 0x80.
+> 
+> P.S. There also seems to be a discrepancy between the uboot and
+> linux code. I take it from what you say above that fpi clock, ddr
+> clock and io region clock are all the same. Now if the least 
+> significant bit of CGU_SYS is set, then according to the uboot
+> code - function ltq_get_bus_clock() - their value is one
+> third of the system clock. But according to the linux code
+> - function ltq_ar9_fpi_hz() in arch/mips/lantiq/xway/clk.c -
+> their value in this case is equal to the system clock.
+> 
+> Or am I getting muddled? It's past my bedtime!
+> 
+> 
+
+Some of the bitshifting in arch/mips/cpu/mips32/arx100/cgu.c is 1
+out. A patch along these lines should fix it:
+
+--- a/arch/mips/cpu/mips32/arx100/cgu.c
++++ b/arch/mips/cpu/mips32/arx100/cgu.c
+@@ -10,12 +10,17 @@
+ #include <asm/lantiq/clk.h>
+ #include <asm/lantiq/io.h>
+ 
+-#define CGU_SYS_DDR_SEL		(1 << 0)
+-#define CGU_SYS_CPU_SEL		(1 << 2)
++#define CGU_SYS_DDR_SHIFT	0
++#define CGU_SYS_CPU_SHIFT	2
+ #define CGU_SYS_SYS_SHIFT	3
++#define CGU_SYS_FPI_SHIFT	6
++#define CGU_SYS_PPE_SHIFT	7
++
++#define CGU_SYS_DDR_MASK	(1 << CGU_SYS_DDR_SHIFT)
++#define CGU_SYS_CPU_MASK	(1 << CGU_SYS_CPU_SHIFT)
+ #define CGU_SYS_SYS_MASK	(0x3 << CGU_SYS_SYS_SHIFT)
+-#define CGU_SYS_FPI_SEL		(1 << 6)
+-#define CGU_SYS_PPE_SEL		(1 << 7)
++#define CGU_SYS_FPI_MASK	(1 << CGU_SYS_FPI_SHIFT)
++#define CGU_SYS_PPE_MASK	(1 << CGU_SYS_PPE_SHIFT)
+ 
+ struct ltq_cgu_regs {
+ 	u32	rsvd0;
+@@ -68,7 +73,7 @@ unsigned long ltq_get_io_region_clock(vo
+ 	u32 ddr_sel;
+ 	unsigned long clk;
+ 
+-	ddr_sel = ltq_cgu_sys_readl(1, CGU_SYS_DDR_SEL);
++	ddr_sel = ltq_cgu_sys_readl(CGU_SYS_DDR_MASK, CGU_SYS_DDR_SHIFT);
+ 
+ 	if (ddr_sel)
+ 		clk = ltq_get_system_clock() / 3;
+@@ -83,7 +88,7 @@ unsigned long ltq_get_cpu_clock(void)
+ 	u32 cpu_sel;
+ 	unsigned long clk;
+ 
+-	cpu_sel = ltq_cgu_sys_readl(1, CGU_SYS_CPU_SEL);
++	cpu_sel = ltq_cgu_sys_readl(CGU_SYS_CPU_MASK, CGU_SYS_CPU_SHIFT);
+ 
+ 	if (cpu_sel)
+ 		clk = ltq_get_io_region_clock();
+@@ -98,7 +103,7 @@ unsigned long ltq_get_bus_clock(void)
+ 	u32 fpi_sel;
+ 	unsigned long clk;
+ 
+-	fpi_sel = ltq_cgu_sys_readl(1, CGU_SYS_FPI_SEL);
++	fpi_sel = ltq_cgu_sys_readl(CGU_SYS_FPI_MASK, CGU_SYS_FPI_SHIFT);
+ 
+ 	if (fpi_sel)
+ 		clk = ltq_get_io_region_clock() / 2;
diff --git a/package/boot/uboot-lantiq/patches/0026-no_extern_inline.patch b/package/boot/uboot-lantiq/patches/0026-no_extern_inline.patch
new file mode 100644
index 0000000..70216f2
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0026-no_extern_inline.patch
@@ -0,0 +1,97 @@
+From b11c5d1dc29e81326d1215011d19377737082aeb Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Wed, 1 Jul 2015 16:36:43 +0200
+Subject: [PATCH] MIPS: change 'extern inline' to 'static inline'
+
+The kernel changed it a long time ago. Also this is now broken
+on gcc-5.x.
+
+Reported-by: Andy Kennedy <andy.kennedy@adtran.com>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+---
+ arch/mips/include/asm/io.h     | 12 ++++++------
+ arch/mips/include/asm/system.h |  6 +++---
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/arch/mips/include/asm/io.h
++++ b/arch/mips/include/asm/io.h
+@@ -118,7 +118,7 @@ static inline void set_io_port_base(unsi
+  * Change virtual addresses to physical addresses and vv.
+  * These are trivial on the 1:1 Linux/MIPS mapping
+  */
+-extern inline phys_addr_t virt_to_phys(volatile void * address)
++static inline phys_addr_t virt_to_phys(volatile void * address)
+ {
+ #ifndef CONFIG_64BIT
+ 	return CPHYSADDR(address);
+@@ -127,7 +127,7 @@ extern inline phys_addr_t virt_to_phys(v
+ #endif
+ }
+ 
+-extern inline void * phys_to_virt(unsigned long address)
++static inline void * phys_to_virt(unsigned long address)
+ {
+ #ifndef CONFIG_64BIT
+ 	return (void *)KSEG0ADDR(address);
+@@ -139,7 +139,7 @@ extern inline void * phys_to_virt(unsign
+ /*
+  * IO bus memory addresses are also 1:1 with the physical address
+  */
+-extern inline unsigned long virt_to_bus(volatile void * address)
++static inline unsigned long virt_to_bus(volatile void * address)
+ {
+ #ifndef CONFIG_64BIT
+ 	return CPHYSADDR(address);
+@@ -148,7 +148,7 @@ extern inline unsigned long virt_to_bus(
+ #endif
+ }
+ 
+-extern inline void * bus_to_virt(unsigned long address)
++static inline void * bus_to_virt(unsigned long address)
+ {
+ #ifndef CONFIG_64BIT
+ 	return (void *)KSEG0ADDR(address);
+@@ -166,12 +166,12 @@ extern unsigned long isa_slot_offset;
+ extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+ 
+ #if 0
+-extern inline void *ioremap(unsigned long offset, unsigned long size)
++static inline void *ioremap(unsigned long offset, unsigned long size)
+ {
+ 	return __ioremap(offset, size, _CACHE_UNCACHED);
+ }
+ 
+-extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
++static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+ {
+ 	return __ioremap(offset, size, _CACHE_UNCACHED);
+ }
+--- a/arch/mips/include/asm/system.h
++++ b/arch/mips/include/asm/system.h
+@@ -23,7 +23,7 @@
+ #include <linux/kernel.h>
+ #endif
+ 
+-extern __inline__ void
++static __inline__ void
+ __sti(void)
+ {
+ 	__asm__ __volatile__(
+@@ -47,7 +47,7 @@ __sti(void)
+  * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+  * no nops at all.
+  */
+-extern __inline__ void
++static __inline__ void
+ __cli(void)
+ {
+ 	__asm__ __volatile__(
+@@ -208,7 +208,7 @@ do { \
+  * For 32 and 64 bit operands we can take advantage of ll and sc.
+  * FIXME: This doesn't work for R3000 machines.
+  */
+-extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
++static __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+ {
+ #ifdef CONFIG_CPU_HAS_LLSC
+ 	unsigned long dummy;
diff --git a/package/boot/uboot-lantiq/patches/0027-no_weak_alias.patch b/package/boot/uboot-lantiq/patches/0027-no_weak_alias.patch
new file mode 100644
index 0000000..da519a5
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0027-no_weak_alias.patch
@@ -0,0 +1,26 @@
+From 3422299dc28fa8257677d03cc1253e3c9bf17e9f Mon Sep 17 00:00:00 2001
+From: Jeroen Hofstee <jeroen@myspectrum.nl>
+Date: Thu, 26 Jun 2014 20:18:31 +0200
+Subject: [PATCH] common: main.c: make show_boot_progress __weak
+
+This not only looks a bit better it also prevents a
+warning with W=1 (no previous prototype).
+
+Signed-off-by: Jeroen Hofstee <jeroen@myspectrum.nl>
+Acked-by: Simon Glass <sjg@chromium.org>
+---
+ common/main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/common/main.c
++++ b/common/main.c
+@@ -27,8 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ /*
+  * Board-specific Platform code can reimplement show_boot_progress () if needed
+  */
+-void inline __show_boot_progress (int val) {}
+-void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
++__weak void show_boot_progress(int val) {}
+ 
+ #define MAX_DELAY_STOP_STR 32
+ 
diff --git a/package/boot/uboot-lantiq/patches/0028-gcc-compat.patch b/package/boot/uboot-lantiq/patches/0028-gcc-compat.patch
new file mode 100644
index 0000000..7955429
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0028-gcc-compat.patch
@@ -0,0 +1,852 @@
+From 9b2c282b348dfe966bbba967dc7a45ce817cce50 Mon Sep 17 00:00:00 2001
+From: Tom Rini <trini@konsulko.com>
+Date: Mon, 29 Feb 2016 11:34:15 -0500
+Subject: [PATCH] compiler*.h: sync include/linux/compiler*.h with Linux
+ 4.5-rc6
+
+Copy these from Linux v4.5-rc6 tag.
+
+This is needed so that we can keep up with newer gcc versions.  Note
+that we don't have the uapi/ hierarchy from the kernel so continue to
+use <linux/types.h>
+
+Signed-off-by: Tom Rini <trini@konsulko.com>
+---
+ include/linux/compiler-gcc.h   | 266 ++++++++++++++++++++++++++++++++++------
+ include/linux/compiler-gcc3.h  |  21 ----
+ include/linux/compiler-gcc4.h  |  63 ----------
+ include/linux/compiler-intel.h |  45 +++++++
+ include/linux/compiler.h       | 270 +++++++++++++++++++++++++++++++++++++++--
+ 5 files changed, 534 insertions(+), 131 deletions(-)
+ delete mode 100644 include/linux/compiler-gcc3.h
+ delete mode 100644 include/linux/compiler-gcc4.h
+ create mode 100644 include/linux/compiler-intel.h
+
+diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
+index 9896e54..22ab246 100644
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -5,11 +5,28 @@
+ /*
+  * Common definitions for all gcc versions go here.
+  */
+-
++#define GCC_VERSION (__GNUC__ * 10000		\
++		     + __GNUC_MINOR__ * 100	\
++		     + __GNUC_PATCHLEVEL__)
+ 
+ /* Optimization barrier */
++
+ /* The "volatile" is due to gcc bugs */
+ #define barrier() __asm__ __volatile__("": : :"memory")
++/*
++ * This version is i.e. to prevent dead stores elimination on @ptr
++ * where gcc and llvm may behave differently when otherwise using
++ * normal barrier(): while gcc behavior gets along with a normal
++ * barrier(), llvm needs an explicit input variable to be assumed
++ * clobbered. The issue is as follows: while the inline asm might
++ * access any memory it wants, the compiler could have fit all of
++ * @ptr into memory registers instead, and since @ptr never escaped
++ * from that, it proofed that the inline asm wasn't touching any of
++ * it. This version works well with both compilers, i.e. we're telling
++ * the compiler that the inline asm absolutely may see the contents
++ * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495
++ */
++#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory")
+ 
+ /*
+  * This macro obfuscates arithmetic on a variable address so that gcc
+@@ -29,41 +46,63 @@
+  * the inline assembly constraint from =g to =r, in this particular
+  * case either is valid.
+  */
+-#define RELOC_HIDE(ptr, off)					\
+-  ({ unsigned long __ptr;					\
+-    __asm__ ("" : "=r"(__ptr) : "0"(ptr));		\
+-    (typeof(ptr)) (__ptr + (off)); })
++#define RELOC_HIDE(ptr, off)						\
++({									\
++	unsigned long __ptr;						\
++	__asm__ ("" : "=r"(__ptr) : "0"(ptr));				\
++	(typeof(ptr)) (__ptr + (off));					\
++})
++
++/* Make the optimizer believe the variable can be manipulated arbitrarily. */
++#define OPTIMIZER_HIDE_VAR(var)						\
++	__asm__ ("" : "=r" (var) : "0" (var))
+ 
++#ifdef __CHECKER__
++#define __must_be_array(a)	0
++#else
+ /* &a[0] degrades to a pointer: a different type from an array */
+-#define __must_be_array(a) \
+-  BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
++#define __must_be_array(a)	BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
++#endif
+ 
+ /*
+  * Force always-inline if the user requests it so via the .config,
+  * or if gcc is too old:
+  */
+-#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
++#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) ||		\
+     !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4)
+-# define inline		inline		__attribute__((always_inline))
+-# define __inline__	__inline__	__attribute__((always_inline))
+-# define __inline	__inline	__attribute__((always_inline))
++#define inline		inline		__attribute__((always_inline)) notrace
++#define __inline__	__inline__	__attribute__((always_inline)) notrace
++#define __inline	__inline	__attribute__((always_inline)) notrace
++#else
++/* A lot of inline functions can cause havoc with function tracing */
++#define inline		inline		notrace
++#define __inline__	__inline__	notrace
++#define __inline	__inline	notrace
+ #endif
+ 
+-#define __deprecated			__attribute__((deprecated))
+-#ifndef __packed
+-# define __packed			__attribute__((packed))
+-#endif
+-#define __weak				__attribute__((weak))
++#define __always_inline	inline __attribute__((always_inline))
++#define  noinline	__attribute__((noinline))
++
++#define __deprecated	__attribute__((deprecated))
++#define __packed	__attribute__((packed))
++#define __weak		__attribute__((weak))
++#define __alias(symbol)	__attribute__((alias(#symbol)))
+ 
+ /*
+- * it doesn't make sense on ARM (currently the only user of __naked) to trace
+- * naked functions because then mcount is called without stack and frame pointer
+- * being set up and there is no chance to restore the lr register to the value
+- * before mcount was called.
++ * it doesn't make sense on ARM (currently the only user of __naked)
++ * to trace naked functions because then mcount is called without
++ * stack and frame pointer being set up and there is no chance to
++ * restore the lr register to the value before mcount was called.
++ *
++ * The asm() bodies of naked functions often depend on standard calling
++ * conventions, therefore they must be noinline and noclone.
++ *
++ * GCC 4.[56] currently fail to enforce this, so we must do so ourselves.
++ * See GCC PR44290.
+  */
+-#define __naked				__attribute__((naked)) notrace
++#define __naked		__attribute__((naked)) noinline __noclone notrace
+ 
+-#define __noreturn			__attribute__((noreturn))
++#define __noreturn	__attribute__((noreturn))
+ 
+ /*
+  * From the GCC manual:
+@@ -75,19 +114,170 @@
+  * would be.
+  * [...]
+  */
+-#ifndef __pure
+-# define __pure				__attribute__((pure))
+-#endif
+-#ifndef __aligned
+-# define __aligned(x)			__attribute__((aligned(x)))
+-#endif
+-#define __printf(a,b)			__attribute__((format(printf,a,b)))
+-#define  noinline			__attribute__((noinline))
+-#define __attribute_const__		__attribute__((__const__))
+-#define __maybe_unused			__attribute__((unused))
+-#define __always_unused			__attribute__((unused))
+-
+-#define __gcc_header(x) #x
+-#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
+-#define gcc_header(x) _gcc_header(x)
+-#include gcc_header(__GNUC__)
++#define __pure			__attribute__((pure))
++#define __aligned(x)		__attribute__((aligned(x)))
++#define __printf(a, b)		__attribute__((format(printf, a, b)))
++#define __scanf(a, b)		__attribute__((format(scanf, a, b)))
++#define __attribute_const__	__attribute__((__const__))
++#define __maybe_unused		__attribute__((unused))
++#define __always_unused		__attribute__((unused))
++
++/* gcc version specific checks */
++
++#if GCC_VERSION < 30200
++# error Sorry, your compiler is too old - please upgrade it.
++#endif
++
++#if GCC_VERSION < 30300
++# define __used			__attribute__((__unused__))
++#else
++# define __used			__attribute__((__used__))
++#endif
++
++#ifdef CONFIG_GCOV_KERNEL
++# if GCC_VERSION < 30400
++#   error "GCOV profiling support for gcc versions below 3.4 not included"
++# endif /* __GNUC_MINOR__ */
++#endif /* CONFIG_GCOV_KERNEL */
++
++#if GCC_VERSION >= 30400
++#define __must_check		__attribute__((warn_unused_result))
++#endif
++
++#if GCC_VERSION >= 40000
++
++/* GCC 4.1.[01] miscompiles __weak */
++#ifdef __KERNEL__
++# if GCC_VERSION >= 40100 &&  GCC_VERSION <= 40101
++#  error Your version of gcc miscompiles the __weak directive
++# endif
++#endif
++
++#define __used			__attribute__((__used__))
++#define __compiler_offsetof(a, b)					\
++	__builtin_offsetof(a, b)
++
++#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
++# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
++#endif
++
++#if GCC_VERSION >= 40300
++/* Mark functions as cold. gcc will assume any path leading to a call
++ * to them will be unlikely.  This means a lot of manual unlikely()s
++ * are unnecessary now for any paths leading to the usual suspects
++ * like BUG(), printk(), panic() etc. [but let's keep them for now for
++ * older compilers]
++ *
++ * Early snapshots of gcc 4.3 don't support this and we can't detect this
++ * in the preprocessor, but we can live with this because they're unreleased.
++ * Maketime probing would be overkill here.
++ *
++ * gcc also has a __attribute__((__hot__)) to move hot functions into
++ * a special section, but I don't see any sense in this right now in
++ * the kernel context
++ */
++#define __cold			__attribute__((__cold__))
++
++#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
++
++#ifndef __CHECKER__
++# define __compiletime_warning(message) __attribute__((warning(message)))
++# define __compiletime_error(message) __attribute__((error(message)))
++#endif /* __CHECKER__ */
++#endif /* GCC_VERSION >= 40300 */
++
++#if GCC_VERSION >= 40500
++/*
++ * Mark a position in code as unreachable.  This can be used to
++ * suppress control flow warnings after asm blocks that transfer
++ * control elsewhere.
++ *
++ * Early snapshots of gcc 4.5 don't support this and we can't detect
++ * this in the preprocessor, but we can live with this because they're
++ * unreleased.  Really, we need to have autoconf for the kernel.
++ */
++#define unreachable() __builtin_unreachable()
++
++/* Mark a function definition as prohibited from being cloned. */
++#define __noclone	__attribute__((__noclone__))
++
++#endif /* GCC_VERSION >= 40500 */
++
++#if GCC_VERSION >= 40600
++/*
++ * When used with Link Time Optimization, gcc can optimize away C functions or
++ * variables which are referenced only from assembly code.  __visible tells the
++ * optimizer that something else uses this function or variable, thus preventing
++ * this.
++ */
++#define __visible	__attribute__((externally_visible))
++#endif
++
++
++#if GCC_VERSION >= 40900 && !defined(__CHECKER__)
++/*
++ * __assume_aligned(n, k): Tell the optimizer that the returned
++ * pointer can be assumed to be k modulo n. The second argument is
++ * optional (default 0), so we use a variadic macro to make the
++ * shorthand.
++ *
++ * Beware: Do not apply this to functions which may return
++ * ERR_PTRs. Also, it is probably unwise to apply it to functions
++ * returning extra information in the low bits (but in that case the
++ * compiler should see some alignment anyway, when the return value is
++ * massaged by 'flags = ptr & 3; ptr &= ~3;').
++ */
++#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__)))
++#endif
++
++/*
++ * GCC 'asm goto' miscompiles certain code sequences:
++ *
++ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
++ *
++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
++ *
++ * (asm goto is automatically volatile - the naming reflects this.)
++ */
++#define asm_volatile_goto(x...)	do { asm goto(x); asm (""); } while (0)
++
++#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
++#if GCC_VERSION >= 40400
++#define __HAVE_BUILTIN_BSWAP32__
++#define __HAVE_BUILTIN_BSWAP64__
++#endif
++#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
++#define __HAVE_BUILTIN_BSWAP16__
++#endif
++#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
++
++#if GCC_VERSION >= 50000
++#define KASAN_ABI_VERSION 4
++#elif GCC_VERSION >= 40902
++#define KASAN_ABI_VERSION 3
++#endif
++
++#if GCC_VERSION >= 40902
++/*
++ * Tell the compiler that address safety instrumentation (KASAN)
++ * should not be applied to that function.
++ * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
++ */
++#define __no_sanitize_address __attribute__((no_sanitize_address))
++#endif
++
++#endif	/* gcc version >= 40000 specific checks */
++
++#if !defined(__noclone)
++#define __noclone	/* not needed */
++#endif
++
++#if !defined(__no_sanitize_address)
++#define __no_sanitize_address
++#endif
++
++/*
++ * A trick to suppress uninitialized variable warning without generating any
++ * code
++ */
++#define uninitialized_var(x) x = x
+diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
+deleted file mode 100644
+index 2befe65..0000000
+--- a/include/linux/compiler-gcc3.h
++++ /dev/null
+@@ -1,21 +0,0 @@
+-#ifndef __LINUX_COMPILER_H
+-#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."
+-#endif
+-
+-#if __GNUC_MINOR__ >= 3
+-# define __used			__attribute__((__used__))
+-#else
+-# define __used			__attribute__((__unused__))
+-#endif
+-
+-#if __GNUC_MINOR__ >= 4
+-#define __must_check		__attribute__((warn_unused_result))
+-#endif
+-
+-/*
+- * A trick to suppress uninitialized variable warning without generating any
+- * code
+- */
+-#define uninitialized_var(x) x = x
+-
+-#define __always_inline		inline __attribute__((always_inline))
+diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
+deleted file mode 100644
+index 27d11ca..0000000
+--- a/include/linux/compiler-gcc4.h
++++ /dev/null
+@@ -1,63 +0,0 @@
+-#ifndef __LINUX_COMPILER_H
+-#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
+-#endif
+-
+-/* GCC 4.1.[01] miscompiles __weak */
+-#ifdef __KERNEL__
+-# if __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1
+-#  error Your version of gcc miscompiles the __weak directive
+-# endif
+-#endif
+-
+-#define __used			__attribute__((__used__))
+-#define __must_check 		__attribute__((warn_unused_result))
+-#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
+-#ifndef __always_inline
+-# define __always_inline		inline __attribute__((always_inline))
+-#endif
+-
+-/*
+- * A trick to suppress uninitialized variable warning without generating any
+- * code
+- */
+-#define uninitialized_var(x) x = x
+-
+-#if __GNUC_MINOR__ >= 3
+-/* Mark functions as cold. gcc will assume any path leading to a call
+-   to them will be unlikely.  This means a lot of manual unlikely()s
+-   are unnecessary now for any paths leading to the usual suspects
+-   like BUG(), printk(), panic() etc. [but let's keep them for now for
+-   older compilers]
+-
+-   Early snapshots of gcc 4.3 don't support this and we can't detect this
+-   in the preprocessor, but we can live with this because they're unreleased.
+-   Maketime probing would be overkill here.
+-
+-   gcc also has a __attribute__((__hot__)) to move hot functions into
+-   a special section, but I don't see any sense in this right now in
+-   the kernel context */
+-#define __cold			__attribute__((__cold__))
+-
+-
+-#if __GNUC_MINOR__ >= 5
+-/*
+- * Mark a position in code as unreachable.  This can be used to
+- * suppress control flow warnings after asm blocks that transfer
+- * control elsewhere.
+- *
+- * Early snapshots of gcc 4.5 don't support this and we can't detect
+- * this in the preprocessor, but we can live with this because they're
+- * unreleased.  Really, we need to have autoconf for the kernel.
+- */
+-#define unreachable() __builtin_unreachable()
+-#endif
+-
+-#endif
+-
+-#if __GNUC_MINOR__ > 0
+-#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+-#endif
+-#if __GNUC_MINOR__ >= 4
+-#define __compiletime_warning(message) __attribute__((warning(message)))
+-#define __compiletime_error(message) __attribute__((error(message)))
+-#endif
+diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
+new file mode 100644
+index 0000000..d4c7113
+--- /dev/null
++++ b/include/linux/compiler-intel.h
+@@ -0,0 +1,45 @@
++#ifndef __LINUX_COMPILER_H
++#error "Please don't include <linux/compiler-intel.h> directly, include <linux/compiler.h> instead."
++#endif
++
++#ifdef __ECC
++
++/* Some compiler specific definitions are overwritten here
++ * for Intel ECC compiler
++ */
++
++#include <asm/intrinsics.h>
++
++/* Intel ECC compiler doesn't support gcc specific asm stmts.
++ * It uses intrinsics to do the equivalent things.
++ */
++#undef barrier
++#undef barrier_data
++#undef RELOC_HIDE
++#undef OPTIMIZER_HIDE_VAR
++
++#define barrier() __memory_barrier()
++#define barrier_data(ptr) barrier()
++
++#define RELOC_HIDE(ptr, off)					\
++  ({ unsigned long __ptr;					\
++     __ptr = (unsigned long) (ptr);				\
++    (typeof(ptr)) (__ptr + (off)); })
++
++/* This should act as an optimization barrier on var.
++ * Given that this compiler does not have inline assembly, a compiler barrier
++ * is the best we can do.
++ */
++#define OPTIMIZER_HIDE_VAR(var) barrier()
++
++/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */
++#define __must_be_array(a) 0
++
++#endif
++
++#ifndef __HAVE_BUILTIN_BSWAP16__
++/* icc has this, but it's called _bswap16 */
++#define __HAVE_BUILTIN_BSWAP16__
++#define __builtin_bswap16 _bswap16
++#endif
++
+diff --git a/include/linux/compiler.h b/include/linux/compiler.h
+index 5be3dab..020ad16 100644
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -5,16 +5,24 @@
+ 
+ #ifdef __CHECKER__
+ # define __user		__attribute__((noderef, address_space(1)))
+-# define __kernel	/* default address space */
++# define __kernel	__attribute__((address_space(0)))
+ # define __safe		__attribute__((safe))
+ # define __force	__attribute__((force))
+ # define __nocast	__attribute__((nocast))
+ # define __iomem	__attribute__((noderef, address_space(2)))
++# define __must_hold(x)	__attribute__((context(x,1,1)))
+ # define __acquires(x)	__attribute__((context(x,0,1)))
+ # define __releases(x)	__attribute__((context(x,1,0)))
+ # define __acquire(x)	__context__(x,1)
+ # define __release(x)	__context__(x,-1)
+ # define __cond_lock(x,c)	((c) ? ({ __acquire(x); 1; }) : 0)
++# define __percpu	__attribute__((noderef, address_space(3)))
++# define __pmem		__attribute__((noderef, address_space(5)))
++#ifdef CONFIG_SPARSE_RCU_POINTER
++# define __rcu		__attribute__((noderef, address_space(4)))
++#else
++# define __rcu
++#endif
+ extern void __chk_user_ptr(const volatile void __user *);
+ extern void __chk_io_ptr(const volatile void __iomem *);
+ #else
+@@ -27,20 +35,32 @@ extern void __chk_io_ptr(const volatile void __iomem *);
+ # define __chk_user_ptr(x) (void)0
+ # define __chk_io_ptr(x) (void)0
+ # define __builtin_warning(x, y...) (1)
++# define __must_hold(x)
+ # define __acquires(x)
+ # define __releases(x)
+ # define __acquire(x) (void)0
+ # define __release(x) (void)0
+ # define __cond_lock(x,c) (c)
++# define __percpu
++# define __rcu
++# define __pmem
+ #endif
+ 
++/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
++#define ___PASTE(a,b) a##b
++#define __PASTE(a,b) ___PASTE(a,b)
++
+ #ifdef __KERNEL__
+ 
+ #ifdef __GNUC__
+ #include <linux/compiler-gcc.h>
+ #endif
+ 
++#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__)
++#define notrace __attribute__((hotpatch(0,0)))
++#else
+ #define notrace __attribute__((no_instrument_function))
++#endif
+ 
+ /* Intel compiler defines __GNUC__. So we will overwrite implementations
+  * coming from above header files here
+@@ -49,6 +69,13 @@ extern void __chk_io_ptr(const volatile void __iomem *);
+ # include <linux/compiler-intel.h>
+ #endif
+ 
++/* Clang compiler defines __GNUC__. So we will overwrite implementations
++ * coming from above header files here
++ */
++#ifdef __clang__
++#include <linux/compiler-clang.h>
++#endif
++
+ /*
+  * Generic compiler-dependent macros required for kernel
+  * build go below this comment. Actual compiler/compiler version
+@@ -117,7 +144,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+  */
+ #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
+ #define __trace_if(cond) \
+-	if (__builtin_constant_p((cond)) ? !!(cond) :			\
++	if (__builtin_constant_p(!!(cond)) ? !!(cond) :			\
+ 	({								\
+ 		int ______r;						\
+ 		static struct ftrace_branch_data			\
+@@ -144,6 +171,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+ # define barrier() __memory_barrier()
+ #endif
+ 
++#ifndef barrier_data
++# define barrier_data(ptr) barrier()
++#endif
++
+ /* Unreachable code */
+ #ifndef unreachable
+ # define unreachable() do { } while (1)
+@@ -156,6 +187,135 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+     (typeof(ptr)) (__ptr + (off)); })
+ #endif
+ 
++#ifndef OPTIMIZER_HIDE_VAR
++#define OPTIMIZER_HIDE_VAR(var) barrier()
++#endif
++
++/* Not-quite-unique ID. */
++#ifndef __UNIQUE_ID
++# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
++#endif
++
++#include <linux/types.h>
++
++#define __READ_ONCE_SIZE						\
++({									\
++	switch (size) {							\
++	case 1: *(__u8 *)res = *(volatile __u8 *)p; break;		\
++	case 2: *(__u16 *)res = *(volatile __u16 *)p; break;		\
++	case 4: *(__u32 *)res = *(volatile __u32 *)p; break;		\
++	case 8: *(__u64 *)res = *(volatile __u64 *)p; break;		\
++	default:							\
++		barrier();						\
++		__builtin_memcpy((void *)res, (const void *)p, size);	\
++		barrier();						\
++	}								\
++})
++
++static __always_inline
++void __read_once_size(const volatile void *p, void *res, int size)
++{
++	__READ_ONCE_SIZE;
++}
++
++#ifdef CONFIG_KASAN
++/*
++ * This function is not 'inline' because __no_sanitize_address confilcts
++ * with inlining. Attempt to inline it may cause a build failure.
++ * 	https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
++ * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
++ */
++static __no_sanitize_address __maybe_unused
++void __read_once_size_nocheck(const volatile void *p, void *res, int size)
++{
++	__READ_ONCE_SIZE;
++}
++#else
++static __always_inline
++void __read_once_size_nocheck(const volatile void *p, void *res, int size)
++{
++	__READ_ONCE_SIZE;
++}
++#endif
++
++static __always_inline void __write_once_size(volatile void *p, void *res, int size)
++{
++	switch (size) {
++	case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
++	case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
++	case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
++	case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
++	default:
++		barrier();
++		__builtin_memcpy((void *)p, (const void *)res, size);
++		barrier();
++	}
++}
++
++/*
++ * Prevent the compiler from merging or refetching reads or writes. The
++ * compiler is also forbidden from reordering successive instances of
++ * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the
++ * compiler is aware of some particular ordering.  One way to make the
++ * compiler aware of ordering is to put the two invocations of READ_ONCE,
++ * WRITE_ONCE or ACCESS_ONCE() in different C statements.
++ *
++ * In contrast to ACCESS_ONCE these two macros will also work on aggregate
++ * data types like structs or unions. If the size of the accessed data
++ * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
++ * READ_ONCE() and WRITE_ONCE()  will fall back to memcpy and print a
++ * compile-time warning.
++ *
++ * Their two major use cases are: (1) Mediating communication between
++ * process-level code and irq/NMI handlers, all running on the same CPU,
++ * and (2) Ensuring that the compiler does not  fold, spindle, or otherwise
++ * mutilate accesses that either do not require ordering or that interact
++ * with an explicit memory barrier or atomic instruction that provides the
++ * required ordering.
++ */
++
++#define __READ_ONCE(x, check)						\
++({									\
++	union { typeof(x) __val; char __c[1]; } __u;			\
++	if (check)							\
++		__read_once_size(&(x), __u.__c, sizeof(x));		\
++	else								\
++		__read_once_size_nocheck(&(x), __u.__c, sizeof(x));	\
++	__u.__val;							\
++})
++#define READ_ONCE(x) __READ_ONCE(x, 1)
++
++/*
++ * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
++ * to hide memory access from KASAN.
++ */
++#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
++
++#define WRITE_ONCE(x, val) \
++({							\
++	union { typeof(x) __val; char __c[1]; } __u =	\
++		{ .__val = (__force typeof(x)) (val) }; \
++	__write_once_size(&(x), __u.__c, sizeof(x));	\
++	__u.__val;					\
++})
++
++/**
++ * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering
++ * @cond: boolean expression to wait for
++ *
++ * Equivalent to using smp_load_acquire() on the condition variable but employs
++ * the control dependency of the wait to reduce the barrier on many platforms.
++ *
++ * The control dependency provides a LOAD->STORE order, the additional RMB
++ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order,
++ * aka. ACQUIRE.
++ */
++#define smp_cond_acquire(cond)	do {		\
++	while (!(cond))				\
++		cpu_relax();			\
++	smp_rmb(); /* ctrl + rmb := acquire */	\
++} while (0)
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* __ASSEMBLY__ */
+@@ -228,7 +388,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+ 
+ /*
+  * Rather then using noinline to prevent stack consumption, use
+- * noinline_for_stack instead.  For documentaiton reasons.
++ * noinline_for_stack instead.  For documentation reasons.
+  */
+ #define noinline_for_stack noinline
+ 
+@@ -270,11 +430,28 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+ # define __section(S) __attribute__ ((__section__(#S)))
+ #endif
+ 
++#ifndef __visible
++#define __visible
++#endif
++
++/*
++ * Assume alignment of return value.
++ */
++#ifndef __assume_aligned
++#define __assume_aligned(a, ...)
++#endif
++
++
+ /* Are two types/vars the same type (ignoring qualifiers)? */
+ #ifndef __same_type
+ # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+ #endif
+ 
++/* Is this type a native word size -- useful for atomic operations */
++#ifndef __native_word
++# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
++#endif
++
+ /* Compile time object size, -1 for unknown */
+ #ifndef __compiletime_object_size
+ # define __compiletime_object_size(obj) -1
+@@ -284,7 +461,48 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+ #endif
+ #ifndef __compiletime_error
+ # define __compiletime_error(message)
++/*
++ * Sparse complains of variable sized arrays due to the temporary variable in
++ * __compiletime_assert. Unfortunately we can't just expand it out to make
++ * sparse see a constant array size without breaking compiletime_assert on old
++ * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether.
++ */
++# ifndef __CHECKER__
++#  define __compiletime_error_fallback(condition) \
++	do { ((void)sizeof(char[1 - 2 * condition])); } while (0)
++# endif
+ #endif
++#ifndef __compiletime_error_fallback
++# define __compiletime_error_fallback(condition) do { } while (0)
++#endif
++
++#define __compiletime_assert(condition, msg, prefix, suffix)		\
++	do {								\
++		bool __cond = !(condition);				\
++		extern void prefix ## suffix(void) __compiletime_error(msg); \
++		if (__cond)						\
++			prefix ## suffix();				\
++		__compiletime_error_fallback(__cond);			\
++	} while (0)
++
++#define _compiletime_assert(condition, msg, prefix, suffix) \
++	__compiletime_assert(condition, msg, prefix, suffix)
++
++/**
++ * compiletime_assert - break build and emit msg if condition is false
++ * @condition: a compile-time constant condition to check
++ * @msg:       a message to emit if condition is false
++ *
++ * In tradition of POSIX assert, this macro will break the build if the
++ * supplied condition is *false*, emitting the supplied error message if the
++ * compiler has support to do so.
++ */
++#define compiletime_assert(condition, msg) \
++	_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
++
++#define compiletime_assert_atomic_type(t)				\
++	compiletime_assert(__native_word(t),				\
++		"Need native word sized stores/loads for atomicity.")
+ 
+ /*
+  * Prevent the compiler from merging or refetching accesses.  The compiler
+@@ -293,11 +511,45 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+  * to make the compiler aware of ordering is to put the two invocations of
+  * ACCESS_ONCE() in different C statements.
+  *
+- * This macro does absolutely -nothing- to prevent the CPU from reordering,
+- * merging, or refetching absolutely anything at any time.  Its main intended
+- * use is to mediate communication between process-level code and irq/NMI
+- * handlers, all running on the same CPU.
++ * ACCESS_ONCE will only work on scalar types. For union types, ACCESS_ONCE
++ * on a union member will work as long as the size of the member matches the
++ * size of the union and the size is smaller than word size.
++ *
++ * The major use cases of ACCESS_ONCE used to be (1) Mediating communication
++ * between process-level code and irq/NMI handlers, all running on the same CPU,
++ * and (2) Ensuring that the compiler does not  fold, spindle, or otherwise
++ * mutilate accesses that either do not require ordering or that interact
++ * with an explicit memory barrier or atomic instruction that provides the
++ * required ordering.
++ *
++ * If possible use READ_ONCE()/WRITE_ONCE() instead.
+  */
+-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+-
++#define __ACCESS_ONCE(x) ({ \
++	 __maybe_unused typeof(x) __var = (__force typeof(x)) 0; \
++	(volatile typeof(x) *)&(x); })
++#define ACCESS_ONCE(x) (*__ACCESS_ONCE(x))
++
++/**
++ * lockless_dereference() - safely load a pointer for later dereference
++ * @p: The pointer to load
++ *
++ * Similar to rcu_dereference(), but for situations where the pointed-to
++ * object's lifetime is managed by something other than RCU.  That
++ * "something other" might be reference counting or simple immortality.
++ */
++#define lockless_dereference(p) \
++({ \
++	typeof(p) _________p1 = READ_ONCE(p); \
++	smp_read_barrier_depends(); /* Dependency order vs. p above. */ \
++	(_________p1); \
++})
++
++/* Ignore/forbid kprobes attach on very low level functions marked by this attribute: */
++#ifdef CONFIG_KPROBES
++# define __kprobes	__attribute__((__section__(".kprobes.text")))
++# define nokprobe_inline	__always_inline
++#else
++# define __kprobes
++# define nokprobe_inline	inline
++#endif
+ #endif /* __LINUX_COMPILER_H */
+-- 
+2.7.4
+
diff --git a/package/boot/uboot-lantiq/patches/0029-net-Use_packed_structures-for_networking.patch b/package/boot/uboot-lantiq/patches/0029-net-Use_packed_structures-for_networking.patch
new file mode 100644
index 0000000..f2f7736
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0029-net-Use_packed_structures-for_networking.patch
@@ -0,0 +1,142 @@
+From 704f3acfcf55343043bbed01c5fb0a0094a68e8a Mon Sep 17 00:00:00 2001
+From: Denis Pynkin <denis.pynkin@collabora.com>
+Date: Fri, 21 Jul 2017 19:28:42 +0300
+Subject: [PATCH] net: Use packed structures for networking
+
+PXE boot is broken with GCC 7.1 due option '-fstore-merging' enabled
+by default for '-O2':
+
+BOOTP broadcast 1
+data abort
+pc : [<8ff8bb30>]          lr : [<00004f1f>]
+reloc pc : [<17832b30>]    lr : [<878abf1f>]
+sp : 8f558bc0  ip : 00000000     fp : 8ffef5a4
+r10: 8ffed248  r9 : 8f558ee0     r8 : 8ffef594
+r7 : 0000000e  r6 : 8ffed700     r5 : 00000000  r4 : 8ffed74e
+r3 : 00060101  r2 : 8ffed230     r1 : 8ffed706  r0 : 00000ddd
+Flags: nzcv  IRQs off  FIQs off  Mode SVC_32
+Resetting CPU ...
+
+Core reason is usage of structures for network headers without packed
+attribute.
+
+Reviewed-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
+Acked-by: Joe Hershberger <joe.hershberger@ni.com>
+---
+ include/net.h | 14 +++++++-------
+ net/bootp.h   |  2 +-
+ net/dns.h     |  2 +-
+ net/nfs.h     |  2 +-
+ net/sntp.h    |  2 +-
+ 5 files changed, 11 insertions(+), 11 deletions(-)
+
+--- a/include/net.h
++++ b/include/net.h
+@@ -203,7 +203,7 @@ struct ethernet_hdr {
+ 	uchar		et_dest[6];	/* Destination node		*/
+ 	uchar		et_src[6];	/* Source node			*/
+ 	ushort		et_protlen;	/* Protocol or length		*/
+-};
++} __attribute__((packed));
+ 
+ /* Ethernet header size */
+ #define ETHER_HDR_SIZE	(sizeof(struct ethernet_hdr))
+@@ -219,7 +219,7 @@ struct e802_hdr {
+ 	uchar		et_snap2;
+ 	uchar		et_snap3;
+ 	ushort		et_prot;	/* 802 protocol			*/
+-};
++} __attribute__((packed));
+ 
+ /* 802 + SNAP + ethernet header size */
+ #define E802_HDR_SIZE	(sizeof(struct e802_hdr))
+@@ -233,7 +233,7 @@ struct vlan_ethernet_hdr {
+ 	ushort		vet_vlan_type;	/* PROT_VLAN			*/
+ 	ushort		vet_tag;	/* TAG of VLAN			*/
+ 	ushort		vet_type;	/* protocol type		*/
+-};
++} __attribute__((packed));
+ 
+ /* VLAN Ethernet header size */
+ #define VLAN_ETHER_HDR_SIZE	(sizeof(struct vlan_ethernet_hdr))
+@@ -260,7 +260,7 @@ struct ip_hdr {
+ 	ushort		ip_sum;		/* checksum			*/
+ 	IPaddr_t	ip_src;		/* Source IP address		*/
+ 	IPaddr_t	ip_dst;		/* Destination IP address	*/
+-};
++} __attribute__((packed));
+ 
+ #define IP_OFFS		0x1fff /* ip offset *= 8 */
+ #define IP_FLAGS	0xe000 /* first 3 bits */
+@@ -288,7 +288,7 @@ struct ip_udp_hdr {
+ 	ushort		udp_dst;	/* UDP destination port		*/
+ 	ushort		udp_len;	/* Length of UDP packet		*/
+ 	ushort		udp_xsum;	/* Checksum			*/
+-};
++} __attribute__((packed));
+ 
+ #define IP_UDP_HDR_SIZE		(sizeof(struct ip_udp_hdr))
+ #define UDP_HDR_SIZE		(IP_UDP_HDR_SIZE - IP_HDR_SIZE)
+@@ -327,7 +327,7 @@ struct arp_hdr {
+ 	uchar		ar_tha[];	/* Target hardware address	*/
+ 	uchar		ar_tpa[];	/* Target protocol address	*/
+ #endif /* 0 */
+-};
++} __attribute__((packed));
+ 
+ #define ARP_HDR_SIZE	(8+20)		/* Size assuming ethernet	*/
+ 
+@@ -362,7 +362,7 @@ struct icmp_hdr {
+ 		} frag;
+ 		uchar data[0];
+ 	} un;
+-};
++} __attribute__((packed));
+ 
+ #define ICMP_HDR_SIZE		(sizeof(struct icmp_hdr))
+ #define IP_ICMP_HDR_SIZE	(IP_HDR_SIZE + ICMP_HDR_SIZE)
+--- a/net/bootp.h
++++ b/net/bootp.h
+@@ -49,7 +49,7 @@ struct Bootp_t {
+ 	char		bp_sname[64];	/* Server host name		*/
+ 	char		bp_file[128];	/* Boot file name		*/
+ 	char		bp_vend[OPT_FIELD_SIZE]; /* Vendor information	*/
+-};
++} __attribute__((packed));
+ 
+ #define BOOTP_HDR_SIZE	sizeof(struct Bootp_t)
+ 
+--- a/net/dns.h
++++ b/net/dns.h
+@@ -29,7 +29,7 @@ struct header {
+ 	uint16_t	nauth;		/* Authority PRs */
+ 	uint16_t	nother;		/* Other PRs */
+ 	unsigned char	data[1];	/* Data, variable length */
+-};
++} __attribute__((packed));
+ 
+ extern void DnsStart(void);		/* Begin DNS */
+ 
+--- a/net/sntp.h
++++ b/net/sntp.h
+@@ -51,7 +51,7 @@ struct sntp_pkt_t {
+ 	unsigned long long originate_timestamp;
+ 	unsigned long long receive_timestamp;
+ 	unsigned long long transmit_timestamp;
+-};
++} __attribute__((packed));
+ 
+ extern void SntpStart(void);	/* Begin SNTP */
+ 
+--- a/net/nfs.h
++++ b/net/nfs.h
+@@ -68,7 +68,7 @@ struct rpc_t {
+ 			uint32_t data[19];
+ 		} reply;
+ 	} u;
+-};
++} __attribute__((packed));
+ extern void NfsStart(void);	/* Begin NFS */
+ 
+ 
diff --git a/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch b/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch
new file mode 100644
index 0000000..a934dab
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch
@@ -0,0 +1,57 @@
+From a40a6e16ed76e5e26a0f60226b64c311d4a62c9f Mon Sep 17 00:00:00 2001
+From: Mathias Kresin <dev@kresin.me>
+Date: Sun, 31 Oct 2021 23:04:54 +0100
+Subject: [PATCH] lzma: force 8bit reads
+
+At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the
+assembly of LzmaProps_Decode. While the decission made by the compiler
+looks perfect fine, it triggers some obscure hang on lantiq danube-s
+v1.5 with MX29LV640EB NOR flash chips.
+
+Only if the offset 1 is used, the hang can be observed. Using any other
+offset works fine:
+
+  lwl s0,0(a1) - s0 == 0x6d000080
+  lwl s0,1(a1) - hangs
+  lwl s0,2(a1) - s0 == 0x0080xxxx
+  lwl s0,3(a1) - s0 == 0x80xxxxxx
+
+It isn't clear whether it is a limitation of the flash chip, the EBU or
+something else.
+
+Force 8bit reads to prevent gcc optimizing the read with lwr/lwl
+instructions.
+
+Signed-off-by: Mathias Kresin <dev@kresin.me>
+---
+ lib/lzma/LzmaDec.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/lib/lzma/LzmaDec.c
++++ b/lib/lzma/LzmaDec.c
+@@ -7,6 +7,7 @@
+ #include "LzmaDec.h"
+ 
+ #include <linux/string.h>
++#include <asm/io.h>
+ 
+ #define kNumTopBits 24
+ #define kTopValue ((UInt32)1 << kNumTopBits)
+@@ -703,7 +704,7 @@ static ELzmaDummy LzmaDec_TryDummy(const
+ 
+ static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+ {
+-  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
++  p->code = ((UInt32)readb(&data[1]) << 24) | ((UInt32)readb(&data[2]) << 16) | ((UInt32)readb(&data[3]) << 8) | ((UInt32)readb(&data[4]));
+   p->range = 0xFFFFFFFF;
+   p->needFlush = 0;
+ }
+@@ -929,7 +930,7 @@ SRes LzmaProps_Decode(CLzmaProps *p, con
+   if (size < LZMA_PROPS_SIZE)
+     return SZ_ERROR_UNSUPPORTED;
+   else
+-    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
++    dicSize = readb(&data[1]) | ((UInt32)readb(&data[2]) << 8) | ((UInt32)readb(&data[3]) << 16) | ((UInt32)readb(&data[4]) << 24);
+ 
+   if (dicSize < LZMA_DIC_MIN)
+     dicSize = LZMA_DIC_MIN;
diff --git a/package/boot/uboot-lantiq/patches/0100-MIPS-add-board-support-for-Easy-50712.patch b/package/boot/uboot-lantiq/patches/0100-MIPS-add-board-support-for-Easy-50712.patch
new file mode 100644
index 0000000..9d6dc2d
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0100-MIPS-add-board-support-for-Easy-50712.patch
@@ -0,0 +1,306 @@
+--- /dev/null
++++ b/board/lantiq/easy50712/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy50712/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy50712/ddr_settings.h
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70a
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xc02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x13c
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xd
++#define MC_DC18_VALUE	0x300
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA04
++#define MC_DC21_VALUE	0xd00
++#define MC_DC22_VALUE	0xd0d
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x62
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x2d89
++#define MC_DC30_VALUE	0x8300
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- /dev/null
++++ b/board/lantiq/easy50712/easy50712.c
+@@ -0,0 +1,112 @@
++/*
++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++	/* SPI/CS output (low-active) for serial flash */
++	gpio_direction_output(22, 1);
++
++	/* EBU.FL_CS1 as output for NAND CE */
++	gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A23 as output for NAND CLE */
++	gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A24 as output for NAND ALE */
++	gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++
++	/* enable CLK_OUT2 for external switch */
++	gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++	gpio_init();
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Lantiq ADM6996I switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++	.name = "adm6996i",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	/* Deactivate HRST line to release reset of ADM6996I switch */
++	ltq_reset_once(LTQ_RESET_HARD, 200000);
++
++	/* ADM6996I needs some time to come out of reset */
++	__udelay(50000);
++
++	return switch_device_register(&adm6996i_dev);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++	if (bus)
++		return 0;
++
++	switch (cs) {
++	case 2:
++		return 1;
++	default:
++		return 0;
++	}
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 2:
++		gpio_set_value(22, 0);
++		break;
++	default:
++		break;
++	}
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 2:
++		gpio_set_value(22, 1);
++		break;
++	default:
++		break;
++	}
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -502,6 +502,9 @@ Active  mips        mips32         au1x0
+ Active  mips        mips32         au1x00      -               dbau1x00            dbau1550                             dbau1x00:DBAU1550                                                                                                                 Thomas Lange <thomas@corelatus.se>
+ Active  mips        mips32         au1x00      -               dbau1x00            dbau1550_el                          dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN                                                                                               Thomas Lange <thomas@corelatus.se>
+ Active  mips        mips32         au1x00      -               pb1x00              pb1000                               pb1x00:PB1000                                                                                                                     -
++Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         incaip      -               incaip              incaip                               -                                                                                                                                 Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_100MHz                        incaip:CPU_CLOCK_RATE=100000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_133MHz                        incaip:CPU_CLOCK_RATE=133000000                                                                                                   Wolfgang Denk <wd@denx.de>
+--- /dev/null
++++ b/include/configs/easy50712.h
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"EASY50712"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Lantiq EASY50712 Danube Reference Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_ATMEL		/* Have an AT45DB321D serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH	/* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS		0
++#define CONFIG_ENV_SPI_CS		2
++#define CONFIG_ENV_SPI_MAX_HZ		20000000
++#define CONFIG_ENV_SPI_MODE		0
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(128 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR					\
++	"update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0101-MIPS-add-board-support-for-Easy-80920.patch b/package/boot/uboot-lantiq/patches/0101-MIPS-add-board-support-for-Easy-80920.patch
new file mode 100644
index 0000000..fcc9163
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0101-MIPS-add-board-support-for-Easy-80920.patch
@@ -0,0 +1,379 @@
+--- /dev/null
++++ b/board/lantiq/easy80920/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/lantiq/easy80920/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/lantiq/easy80920/ddr_settings.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000100
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x101
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000300
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x0
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141b42
++#define	MC_CCR42_VALUE	0x141b42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x0
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- /dev/null
++++ b/board/lantiq/easy80920/easy80920.c
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++static void gpio_init(void)
++{
++	/* SPI CS 0.4 to serial flash */
++	gpio_direction_output(10, 1);
++
++	/* EBU.FL_CS1 as output for NAND CE */
++	gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A23 as output for NAND CLE */
++	gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A24 as output for NAND ALE */
++	gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* GPIO 3.0 as input for NAND Ready Busy */
++	gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++	/* GPIO 3.1 as output for NAND Read */
++	gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++	{ 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++	{ 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC3: unused */
++	{ 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++	{ 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FF0000;
++
++	ltq_gphy_phy11g_a1x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++	if (bus)
++		return 0;
++
++	if (cs == 4)
++		return 1;
++
++	return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 4:
++		gpio_set_value(10, 0);
++		break;
++	default:
++		break;
++	}
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 4:
++		gpio_set_value(10, 1);
++		break;
++	default:
++		break;
++	}
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -509,6 +509,11 @@ Active  mips        mips32         incai
+ Active  mips        mips32         incaip      -               incaip              incaip_100MHz                        incaip:CPU_CLOCK_RATE=100000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_133MHz                        incaip:CPU_CLOCK_RATE=133000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_150MHz                        incaip:CPU_CLOCK_RATE=150000000                                                                                                   Wolfgang Denk <wd@denx.de>
++Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nandspl                    easy80920:SYS_BOOT_NANDSPL                                                                                                        Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nor                        easy80920:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_norspl                     easy80920:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_ram                        easy80920:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_sfspl                      easy80920:SYS_BOOT_SFSPL                                                                                                          Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips64         -           -               qemu-mips           qemu_mips64                          qemu-mips64:SYS_BIG_ENDIAN                                                                                                        -
+ Active  mips        mips64         -           -               qemu-mips           qemu_mips64el                        qemu-mips64:SYS_LITTLE_ENDIAN                                                                                                     -
+ Active  nds32       n1213          ag101       AndesTech       adp-ag101           adp-ag101                            -                                                                                                                                 Andes <uboot@andestech.com>
+--- /dev/null
++++ b/include/configs/easy80920.h
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"EASY80920"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Lantiq EASY80920 VRX200 Family Board"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX	/* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH	/* Build SPI flash SPL */
++#define CONFIG_SPL_SPI_BUS		0
++#define CONFIG_SPL_SPI_CS		4
++#define CONFIG_SPL_SPI_MAX_HZ		25000000
++#define CONFIG_SPL_SPI_MODE		0
++
++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH	/* Build NOR flash SPL */
++
++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH	/* Build NAND flash SPL */
++#define CONFIG_SYS_NAND_PAGE_COUNT	128
++#define CONFIG_SYS_NAND_PAGE_SIZE	2048
++#define CONFIG_SYS_NAND_OOBSIZE		64
++#define CONFIG_SYS_NAND_BLOCK_SIZE	(256 * 1024)
++#define CONFIG_SYS_NAND_BAD_BLOCK_POS	NAND_LARGE_BADBLOCK_POS
++#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x4000
++
++#define CONFIG_LTQ_SPL_COMP_LZO
++#define CONFIG_LTQ_SPL_CONSOLE
++
++#define CONFIG_SYS_DRAM_PROBE
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS		CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS		CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE		CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(384 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NORSPL)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#elif defined(CONFIG_SYS_BOOT_NANDSPL)
++#define CONFIG_ENV_IS_IN_NAND
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(256 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR					\
++	"update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF					\
++	"update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NAND					\
++	"update-uboot-nand=run load-uboot-nandspl-lzo write-uboot-nand\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	CONFIG_ENV_UPDATE_UBOOT_SF	\
++	CONFIG_ENV_UPDATE_UBOOT_NAND
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0102-MIPS-add-board-support-for-Arcadyan-ARV4519PW.patch b/package/boot/uboot-lantiq/patches/0102-MIPS-add-board-support-for-Arcadyan-ARV4519PW.patch
new file mode 100644
index 0000000..413061c
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0102-MIPS-add-board-support-for-Arcadyan-ARV4519PW.patch
@@ -0,0 +1,244 @@
+From 9f915cf9550a6234adecaf3031c2b279835e14af Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: MIPS: add board support for Arcadyan ARV4519
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/arv4519pw.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Atheros ar8216 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++	.name = "ar8216",
++	.cpu_port = 0,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv4519pw/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x131
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA04
++#define MC_DC21_VALUE	0x1700
++#define MC_DC22_VALUE	0x1717
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5A
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -502,6 +502,9 @@ Active  mips        mips32         au1x0
+ Active  mips        mips32         au1x00      -               dbau1x00            dbau1550                             dbau1x00:DBAU1550                                                                                                                 Thomas Lange <thomas@corelatus.se>
+ Active  mips        mips32         au1x00      -               dbau1x00            dbau1550_el                          dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN                                                                                               Thomas Lange <thomas@corelatus.se>
+ Active  mips        mips32         au1x00      -               pb1x00              pb1000                               pb1x00:PB1000                                                                                                                     -
++Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_brn                        arv4519pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_nor                        arv4519pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_ram                        arv4519pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/arv4519pw.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV4519PW"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV4519PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Brnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0103-MIPS-add-board-support-for-Arcadyan-ARV7518PW.patch b/package/boot/uboot-lantiq/patches/0103-MIPS-add-board-support-for-Arcadyan-ARV7518PW.patch
new file mode 100644
index 0000000..490ab2d
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0103-MIPS-add-board-support-for-Arcadyan-ARV7518PW.patch
@@ -0,0 +1,244 @@
+From 54a31b334162e8dc2ea891057ddeab42978db8b3 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: MIPS: add board support for Arcadyan ARV7518
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/arv7518pw.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Atheros ar8216 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++	.name = "ar8216",
++	.cpu_port = 0,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7518pw/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x134
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1400
++#define MC_DC22_VALUE	0x1414
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5B
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -505,6 +505,9 @@ Active  mips        mips32         au1x0
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_brn                        arv4519pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_nor                        arv4519pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_ram                        arv4519pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_brn                        arv7518pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_nor                        arv7518pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/arv7518pw.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV7518PW"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV7518PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Brnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0104-MIPS-add-board-support-for-AudioCodes-MP-252.patch b/package/boot/uboot-lantiq/patches/0104-MIPS-add-board-support-for-AudioCodes-MP-252.patch
new file mode 100644
index 0000000..16a44cc
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0104-MIPS-add-board-support-for-AudioCodes-MP-252.patch
@@ -0,0 +1,250 @@
+From 4bacfc80eae768be45f9ddf7588ec55281354648 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel.golle@gmail.com>
+Date: Fri, 8 Mar 2013 13:29:04 +0200
+Subject: MIPS: add board support for AudioCodes MP-252
+
+Signed-off-by: Daniel Golle <dgolle@allnet.de>
+
+--- /dev/null
++++ b/board/audiocodes/acmp252/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/audiocodes/acmp252/acmp252.c
+@@ -0,0 +1,66 @@
++/*
++ * Copyright (C) 2013 Daniel Golle <daniel.golle@gmail.com>
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++	/* Activate reset line of ADM6996I switch */
++	gpio_direction_output(19, 0);
++}
++
++int board_early_init_f(void)
++{
++	gpio_init();
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Lantiq ADM6996I switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++	.name = "adm6996i",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	/* Deactivate reset line of ADM6996I switch */
++	gpio_set_value(19, 1);
++
++	/* ADM6996I needs some time to come out of reset */
++	__udelay(50000);
++
++	return switch_device_register(&adm6996i_dev);
++}
+--- /dev/null
++++ b/board/audiocodes/acmp252/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/audiocodes/acmp252/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x403
++#define MC_DC08_VALUE	0x103
++#define MC_DC09_VALUE	0x80B
++#define MC_DC10_VALUE	0x304
++#define MC_DC11_VALUE	0xD03
++#define MC_DC12_VALUE	0x2C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x13C
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x402
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1700
++#define MC_DC22_VALUE	0x1717
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5C
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x2D93
++#define MC_DC30_VALUE	0x8300
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -508,6 +508,8 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_brn                        arv7518pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_nor                        arv7518pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      audiocodes      acmp252             acmp252_nor                          acmp252:SYS_BOOT_NOR                                                                                                              Daniel Golle <daniel.golle@gmail.com>
++Active  mips        mips32         danube      audiocodes      acmp252             acmp252_ram                          acmp252:SYS_BOOT_RAM                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/acmp252.h
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2013 Daniel Golle <daniel.golle@gmail.com>
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ACMP252"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"AudioCodes MP-252"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0105-MIPS-add-board-support-for-AVM-FritzBox-3370.patch b/package/boot/uboot-lantiq/patches/0105-MIPS-add-board-support-for-AVM-FritzBox-3370.patch
new file mode 100644
index 0000000..d7850e4
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0105-MIPS-add-board-support-for-AVM-FritzBox-3370.patch
@@ -0,0 +1,356 @@
+From 37a95ae4ba75407a26862ece6f48fa68aa6c5c78 Mon Sep 17 00:00:00 2001
+From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: MIPS: add board support for AVM FritzBox 3370
+
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/avm/fb3370/Makefile
+@@ -0,0 +1,28 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/avm/fb3370/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/avm/fb3370/ddr_settings.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000100
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x101
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000300
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x0
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141B42
++#define	MC_CCR42_VALUE	0x141B42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x0
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- /dev/null
++++ b/board/avm/fb3370/fb3370.c
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <spi.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++static void gpio_init(void)
++{
++	/* SPI CS 0.4 to serial flash */
++	gpio_direction_output(10, 1);
++
++	/* EBU.FL_CS1 as output for NAND CE */
++	gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A23 as output for NAND CLE */
++	gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A24 as output for NAND ALE */
++	gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* GPIO 3.0 as input for NAND Ready Busy */
++	gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++	/* GPIO 3.1 as output for NAND Read */
++	gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++	{ 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++	{ 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC3: unused */
++	{ 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++	{ 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FF0000;
++
++	ltq_gphy_phy11g_a1x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++	if (bus)
++		return 0;
++
++	if (cs == 4)
++		return 1;
++
++	return 0;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 4:
++		gpio_set_value(10, 0);
++		break;
++	default:
++		break;
++	}
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++	switch (slave->cs) {
++	case 4:
++		gpio_set_value(10, 1);
++		break;
++	default:
++		break;
++	}
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -517,6 +517,9 @@ Active  mips        mips32         incai
+ Active  mips        mips32         incaip      -               incaip              incaip_100MHz                        incaip:CPU_CLOCK_RATE=100000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_133MHz                        incaip:CPU_CLOCK_RATE=133000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_150MHz                        incaip:CPU_CLOCK_RATE=150000000                                                                                                   Wolfgang Denk <wd@denx.de>
++Active  mips        mips32         vrx200      avm             fb3370              fb3370_eva                           fb3370:SYS_BOOT_EVA                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      avm             fb3370              fb3370_ram                           fb3370:SYS_BOOT_RAM                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      avm             fb3370              fb3370_sfspl                         fb3370:SYS_BOOT_SFSPL                                                                                                             Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nandspl                    easy80920:SYS_BOOT_NANDSPL                                                                                                        Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nor                        easy80920:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_norspl                     easy80920:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/fb3370.h
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"FB3370"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"AVM FritzBox 3370"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART			/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET		/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_SPI_FLASH
++#define CONFIG_SPI_FLASH_MACRONIX		/* Have a MX29LV620 serial flash */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH
++
++#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH	/* Build SPI flash SPL */
++#define CONFIG_LTQ_SPL_COMP_LZO			/* Compress SPL with LZO */
++#define CONFIG_LTQ_SPL_CONSOLE			/* Enable SPL console */
++
++#define CONFIG_SPL_SPI_BUS		0
++#define CONFIG_SPL_SPI_CS		4
++#define CONFIG_SPL_SPI_MAX_HZ		25000000
++#define CONFIG_SPL_SPI_MODE		0
++
++#define CONFIG_SYS_DRAM_PROBE
++
++#define CONFIG_SYS_BOOTM_LEN          0x1000000       /* 16 MB */
++
++/* Environment */
++#define CONFIG_ENV_SPI_BUS		CONFIG_SPL_SPI_BUS
++#define CONFIG_ENV_SPI_CS		CONFIG_SPL_SPI_CS
++#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SPL_SPI_MAX_HZ
++#define CONFIG_ENV_SPI_MODE		CONFIG_SPL_SPI_MODE
++
++#if defined(CONFIG_SYS_BOOT_SFSPL)
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++#if defined(CONFIG_SYS_BOOT_EVA)
++#define CONFIG_SYS_TEXT_BASE		0x80100000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_SF					\
++	"update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_SF
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0106-MIPS-add-board-support-for-Gigaset-SX76X.patch b/package/boot/uboot-lantiq/patches/0106-MIPS-add-board-support-for-Gigaset-SX76X.patch
new file mode 100644
index 0000000..16946e9
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0106-MIPS-add-board-support-for-Gigaset-SX76X.patch
@@ -0,0 +1,249 @@
+From 9e9dec563e4d061e7b34d2d59a89eb05c60f43a7 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: MIPS: add board support for Gigaset SX76X
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/gigaset/sx76x/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/gigaset/sx76x/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/gigaset/sx76x/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x202
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0xF3E
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x300
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA04
++#define MC_DC21_VALUE	0xF00
++#define MC_DC22_VALUE	0xF0F
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x63
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x100
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x514
++#define MC_DC29_VALUE	0x2D89
++#define MC_DC30_VALUE	0x8300
++#define MC_DC31_VALUE	0x2002
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- /dev/null
++++ b/board/gigaset/sx76x/sx76x.c
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2011 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++static void gpio_init(void)
++{
++	/* Activate reset line of ADM6996I switch */
++	gpio_direction_output(19, 0);
++}
++
++int board_early_init_f(void)
++{
++	gpio_init();
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Lantiq ADM6996I switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++	.name = "adm6996i",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	/* Deactivate reset line of ADM6996I switch */
++	gpio_set_value(19, 1);
++
++	/* ADM6996I needs some time to come out of reset */
++	__udelay(50000);
++
++	return switch_device_register(&adm6996i_dev);
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -510,6 +510,8 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_nor                          acmp252:SYS_BOOT_NOR                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_ram                          acmp252:SYS_BOOT_RAM                                                                                                              Daniel Golle <daniel.golle@gmail.com>
++Active  mips        mips32         danube      gigaset         sx76x               gigasx76x_nor                        sx76x:SYS_BOOT_NOR                                                                                                                Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      gigaset         sx76x               gigasx76x_ram                        sx76x:SYS_BOOT_RAM                                                                                                                Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/sx76x.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"GIGASX76X"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Gigaset sx76x"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0107-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch b/package/boot/uboot-lantiq/patches/0107-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch
new file mode 100644
index 0000000..3f77d98
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0107-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch
@@ -0,0 +1,303 @@
+From 3f7be04a148d23cdb5fd320e0e2923983f8bd1f4 Mon Sep 17 00:00:00 2001
+From: Luka Perkov <luka@openwrt.org>
+Date: Tue, 6 Aug 2013 22:51:00 +0200
+Subject: MIPS: add board support for ZyXEL P-2812HNU-Fx
+
+Signed-off-by: Luka Perkov <luka@openwrt.org>
+
+--- /dev/null
++++ b/board/zyxel/p2812hnufx/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/zyxel/p2812hnufx/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/zyxel/p2812hnufx/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * The values have been extracted from original ZyXEL U-Boot.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000100
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x101
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000300
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x0
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141B42
++#define	MC_CCR42_VALUE	0x141B42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x0
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- /dev/null
++++ b/board/zyxel/p2812hnufx/p2812hnufx.c
+@@ -0,0 +1,97 @@
++/*
++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++static void gpio_init(void)
++{
++	/* EBU.FL_CS1 as output for NAND CE */
++	gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A23 as output for NAND CLE */
++	gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A24 as output for NAND ALE */
++	gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* GPIO 3.0 as input for NAND Ready Busy */
++	gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++	/* GPIO 3.1 as output for NAND Read */
++	gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++	{ 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++	{ 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC3: unused */
++	{ 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++	{ 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FF0000;
++
++	ltq_gphy_phy11g_a1x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -527,6 +527,8 @@ Active  mips        mips32         vrx20
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_norspl                     easy80920:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_ram                        easy80920:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_sfspl                      easy80920:SYS_BOOT_SFSPL                                                                                                          Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      zyxel           p2812hnufx          p2812hnufx_nandspl                   p2812hnufx:SYS_BOOT_NANDSPL                                                                                                       Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         vrx200      zyxel           p2812hnufx          p2812hnufx_ram                       p2812hnufx:SYS_BOOT_RAM                                                                                                           Luka Perkov <luka@openwrt.org>
+ Active  mips        mips64         -           -               qemu-mips           qemu_mips64                          qemu-mips64:SYS_BIG_ENDIAN                                                                                                        -
+ Active  mips        mips64         -           -               qemu-mips           qemu_mips64el                        qemu-mips64:SYS_LITTLE_ENDIAN                                                                                                     -
+ Active  nds32       n1213          ag101       AndesTech       adp-ag101           adp-ag101                            -                                                                                                                                 Andes <uboot@andestech.com>
+--- /dev/null
++++ b/include/configs/p2812hnufx.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"P-2812HNU-Fx"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"ZyXEL P-2812HNU-Fx"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART			/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET		/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH		/* Have a K9F1G08U0D NAND flash */
++
++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH	/* Build NAND flash SPL */
++#define CONFIG_LTQ_SPL_COMP_LZO			/* Compress SPL with LZO */
++#define CONFIG_LTQ_SPL_CONSOLE			/* Enable SPL console */
++
++#define CONFIG_SYS_NAND_PAGE_COUNT	64
++#define CONFIG_SYS_NAND_PAGE_SIZE	2048
++#define CONFIG_SYS_NAND_OOBSIZE		64
++#define CONFIG_SYS_NAND_BLOCK_SIZE	(128 * 1024)
++#define CONFIG_SYS_NAND_BAD_BLOCK_POS	NAND_LARGE_BADBLOCK_POS
++#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x4000
++
++#define CONFIG_SYS_DRAM_PROBE
++
++#define CONFIG_SYS_BOOTM_LEN          0x1000000       /* 16 MB */
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NANDSPL)
++#define CONFIG_ENV_IS_IN_NAND
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NAND					\
++	"update-uboot-nand=run load-uboot-nandspl-lzo write-uboot-nand\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NAND
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0108-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch b/package/boot/uboot-lantiq/patches/0108-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch
new file mode 100644
index 0000000..0849305
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0108-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch
@@ -0,0 +1,244 @@
+From fbdbf2ddf2b34d675d53de679c179788b0604c1a Mon Sep 17 00:00:00 2001
+From: Oliver Muth <dr.o.muth@gmx.de>
+Date: Sat, 12 Oct 2013 16:49:53 +0200
+Subject: MIPS: add board support for Arcadyan ARV752DPW
+
+Signed-off-by: Oliver Muth <dr.o.muth@gmx.de>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv752dpw/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv752dpw/arv752dpw.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ * Copyright (C) 2013 Oliver Muth <dr.o.muth@gmx.de>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Realtek rtl8306 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++static struct switch_device rtl8306_dev = {
++	.name = "rtl8306",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&rtl8306_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv752dpw/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv752dpw/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.     
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x134
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1400
++#define MC_DC22_VALUE	0x1414
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5B
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -508,6 +508,9 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_brn                        arv7518pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_nor                        arv7518pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_brn                        arv752dpw:SYS_BOOT_BRN                                                                                                            -
++Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_nor                        arv752dpw:SYS_BOOT_NOR                                                                                                            -
++Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_ram                        arv752dpw:SYS_BOOT_RAM                                                                                                            -
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_nor                          acmp252:SYS_BOOT_NOR                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_ram                          acmp252:SYS_BOOT_RAM                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      gigaset         sx76x               gigasx76x_nor                        sx76x:SYS_BOOT_NOR                                                                                                                Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv752dpw.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV752DPW"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV752DPW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_RTL8306
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Brnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0109-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch b/package/boot/uboot-lantiq/patches/0109-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch
new file mode 100644
index 0000000..29b9648
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0109-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch
@@ -0,0 +1,246 @@
+From 09f411b4d10f10a62f147264121bb853b4649c3e Mon Sep 17 00:00:00 2001
+From: Oliver Muth <dr.o.muth@gmx.de>
+Date: Sat, 12 Oct 2013 16:49:53 +0200
+Subject: MIPS: add board support for Arcadyan ARV752DPW22
+
+Signed-off-by: Oliver Muth <dr.o.muth@gmx.de>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv752dpw22/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv752dpw22/arv752dpw22.c
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ * Copyright (C) 2013 Oliver Muth <dr.o.muth@gmx.de>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Atheros ar8216 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_MII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++	.name = "ar8216",
++	.cpu_port = 0,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv752dpw22/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv752dpw22/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.     
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x134
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1400
++#define MC_DC22_VALUE	0x1414
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5B
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -511,6 +511,9 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_brn                        arv752dpw:SYS_BOOT_BRN                                                                                                            -
+ Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_nor                        arv752dpw:SYS_BOOT_NOR                                                                                                            -
+ Active  mips        mips32         danube      arcadyan        arv752dpw           arv752dpw_ram                        arv752dpw:SYS_BOOT_RAM                                                                                                            -
++Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_brn                      arv752dpw22:SYS_BOOT_BRN                                                                                                          -
++Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_nor                      arv752dpw22:SYS_BOOT_NOR                                                                                                          -
++Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_ram                      arv752dpw22:SYS_BOOT_RAM                                                                                                          -
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_nor                          acmp252:SYS_BOOT_NOR                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_ram                          acmp252:SYS_BOOT_RAM                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      gigaset         sx76x               gigasx76x_nor                        sx76x:SYS_BOOT_NOR                                                                                                                Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv752dpw22.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV752DPW22"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV752DPW22"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(192 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Burnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0110-MIPS-add-board-support-for-Arcadyan-ARV7510PW.patch b/package/boot/uboot-lantiq/patches/0110-MIPS-add-board-support-for-Arcadyan-ARV7510PW.patch
new file mode 100644
index 0000000..902f7b7
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0110-MIPS-add-board-support-for-Arcadyan-ARV7510PW.patch
@@ -0,0 +1,271 @@
+From ba27086a5174130d138d645c2f4a49b08c3f2386 Mon Sep 17 00:00:00 2001
+From: Matti Laakso <malaakso@elisanet.fi>
+Date: Sat, 2 Mar 2013 23:34:00 +0100
+Subject: MIPS: add board support for Arcadyan ARV7510
+
+Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
+Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+
+--- /dev/null
++++ b/board/arcadyan/arv7510pw/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv7510pw/arv7510pw.c
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 2013 Matti Laakso <malaakso@elisanet.fi>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++
++static void gpio_init(void)
++{
++	/* Initialize SSIO GPIOs */
++	gpio_set_altfunc(4, 1, 0, 1);
++	gpio_set_altfunc(5, 1, 0, 1);
++	gpio_set_altfunc(6, 1, 0, 1);
++	ltq_gpio_init();
++
++	/* Power led on */
++	gpio_direction_output(76, 1);
++}
++
++int board_early_init_f(void)
++{
++	gpio_init();
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: ADM6996I */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device adm6996i_dev = {
++	.name = "adm6996i",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	/* Deactivate HRST line to release reset of ADM6996I switch */
++	ltq_reset_once(LTQ_RESET_HARD, 200000);
++
++	/* ADM6996I needs some time to come out of reset */
++	__udelay(50000);
++
++	return switch_device_register(&adm6996i_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7510pw/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7510pw/ddr_settings.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (C) 2013 Matti Laakso <malaakso@elisanet.fi>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x120
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA04
++#define MC_DC21_VALUE	0x1700
++#define MC_DC22_VALUE	0x1717
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x52
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -505,6 +505,9 @@ Active  mips        mips32         au1x0
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_brn                        arv4519pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_nor                        arv4519pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_ram                        arv4519pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_brn                        arv7510pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_nor                        arv7510pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_ram                        arv7510pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_brn                        arv7518pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_nor                        arv7518pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv7510pw.h
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2013 Matti Laakso <malaakso@elisanet.fi>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV7510PW"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV7510PW"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_ADM6996I
++
++/* SSIO */
++#define CONFIG_LTQ_SSIO_SHIFT_REGS
++#define CONFIG_LTQ_SSIO_EDGE_FALLING
++#define CONFIG_LTQ_SSIO_GPHY1_MODE	0
++#define CONFIG_LTQ_SSIO_GPHY2_MODE	0
++#define CONFIG_LTQ_SSIO_INIT_VALUE	0
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Brnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Buffered write broken in ARV7510PW */
++#undef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS		\
++	CONFIG_ENV_LANTIQ_DEFAULTS		\
++	CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"kernel_addr=0xB0060000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0111-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch b/package/boot/uboot-lantiq/patches/0111-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch
new file mode 100644
index 0000000..416f16e
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0111-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch
@@ -0,0 +1,240 @@
+--- /dev/null
++++ b/board/arcadyan/arv7510pw22/arv7510pw22.c
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++	/* Switch on Power LED */
++	gpio_direction_output(2, 0);
++	gpio_set_value(2, 0);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Atheros ar8216 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_NONE },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++	.name = "ar8216",
++	.cpu_port = 0,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&ar8216_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7510pw22/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7510pw22/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.     
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x134
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1400
++#define MC_DC22_VALUE	0x1414
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x5B
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- /dev/null
++++ b/board/arcadyan/arv7510pw22/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -508,6 +508,9 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_brn                        arv7510pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_nor                        arv7510pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_ram                        arv7510pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7510pw22         arv7510pw22_brn                        arv7510pw22:SYS_BOOT_BRN                                                                                                          Álvaro Fernández Rojas <noltari@gmail.com>
++Active  mips        mips32         danube      arcadyan        arv7510pw22         arv7510pw22_nor                        arv7510pw22:SYS_BOOT_NOR                                                                                                          Álvaro Fernández Rojas <noltari@gmail.com>
++Active  mips        mips32         danube      arcadyan        arv7510pw22         arv7510pw22_ram                        arv7510pw22:SYS_BOOT_RAM                                                                                                          Álvaro Fernández Rojas <noltari@gmail.com>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_brn                        arv7518pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_nor                        arv7518pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7518pw           arv7518pw_ram                        arv7518pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv7510pw22.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV7510PW22"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV7510PW22"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Burnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR		\
++	"update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	CONFIG_ENV_UPDATE_UBOOT_NOR	\
++	"kernel_addr=0xB0060000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0112-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch b/package/boot/uboot-lantiq/patches/0112-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch
new file mode 100644
index 0000000..39499fc
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0112-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch
@@ -0,0 +1,307 @@
+--- /dev/null
++++ b/board/arcadyan/vgv7510kw22/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/vgv7510kw22/vgv7510kw22.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++#define GPIO_POWER_GREEN	14
++#define GPIO_POWER_RED	28
++
++static void gpio_init(void)
++{
++	/* Turn on the green power LED */
++	gpio_direction_output(GPIO_POWER_GREEN, 0);
++
++	/* Turn off the red power LED */
++	gpio_direction_output(GPIO_POWER_RED, 1);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++void show_boot_progress(int arg)
++{
++	if (!do_gpio_init)
++		return 0;
++
++	if (arg >= 0) {
++		/* Success - turn off the red power LED and turn on the green power LED */
++		gpio_set_value(GPIO_POWER_RED, 1);
++		gpio_set_value(GPIO_POWER_GREEN, 0);
++	} else {
++		/* Failure - turn off green power LED and turn on red power LED */
++		gpio_set_value(GPIO_POWER_GREEN, 1);
++		gpio_set_value(GPIO_POWER_RED, 0);
++	}
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* unused */
++	{ 0, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* unused */
++	{ 1, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* Internal GPHY0 with 10/100 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII },
++	/* Internal GPHY0 with 10/100 firmware for LAN port 1 */
++	{ 3, 0x12, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII },
++	/* Internal GPHY1 with 10/100 firmware for LAN port 4 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII },
++	/* Internal GPHY1 with 10/100 firmware for LAN port 3 */
++	{ 5, 0x14, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FF0000;
++
++	if (ltq_chip_version_get() == 1)
++		ltq_gphy_phy22f_a1x_load(fw_addr);
++	else
++		ltq_gphy_phy22f_a2x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
+--- /dev/null
++++ b/board/arcadyan/vgv7510kw22/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/vgv7510kw22/ddr_settings.h
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ * Copyright (C) 2016 Mathias Kresin <dev@kresin.me>
++ *
++ * The values have been extracted from original brnboot.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000100
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x100
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000401
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x2040F
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141B42
++#define	MC_CCR42_VALUE	0x141B42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x2040F
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -531,6 +531,9 @@ Active  mips        mips32         incai
+ Active  mips        mips32         incaip      -               incaip              incaip_100MHz                        incaip:CPU_CLOCK_RATE=100000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_133MHz                        incaip:CPU_CLOCK_RATE=133000000                                                                                                   Wolfgang Denk <wd@denx.de>
+ Active  mips        mips32         incaip      -               incaip              incaip_150MHz                        incaip:CPU_CLOCK_RATE=150000000                                                                                                   Wolfgang Denk <wd@denx.de>
++Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_brn                      vgv7510kw22:SYS_BOOT_BRN                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_nor                      vgv7510kw22:SYS_BOOT_NOR                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_ram                      vgv7510kw22:SYS_BOOT_RAM                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_eva                           fb3370:SYS_BOOT_EVA                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_ram                           fb3370:SYS_BOOT_RAM                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_sfspl                         fb3370:SYS_BOOT_SFSPL                                                                                                             Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/vgv7510kw22.h
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"VGV7510KW22"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan VGV7510KW22"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART			/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET		/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH		/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_OVERWRITE		1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(384 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(128 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	"kernel_addr=0xB0080000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0113-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch b/package/boot/uboot-lantiq/patches/0113-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch
new file mode 100644
index 0000000..5185c94
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0113-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch
@@ -0,0 +1,241 @@
+--- /dev/null
++++ b/board/arcadyan/arv8539pw22/Makefile
+@@ -0,0 +1,28 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:     GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB    = $(obj)lib$(BOARD).o
++
++COBJS  = $(BOARD).o
++
++SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS   := $(addprefix $(obj),$(COBJS))
++SOBJS  := $(addprefix $(obj),$(SOBJS))
++
++$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
++
+--- /dev/null
++++ b/board/arcadyan/arv8539pw22/arv8539pw22.c
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (C) 2012 Luka Perkov <luka@openwrt.org>
++ * Copyright (C) 2013 Oliver Muth <dr.o.muth@gmx.de>
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++int board_early_init_f(void)
++{
++       return 0;
++}
++
++int checkboard(void)
++{
++       puts("Board: " CONFIG_BOARD_NAME "\n");
++       ltq_chip_print_info();
++
++       return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++       /* MAC0: Atheros ar8216 switch */
++       { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_MII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++       .ports = eth_port_config,
++       .num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++       return ltq_eth_initialize(&eth_board_config);
++}
++
++static struct switch_device ar8216_dev = {
++       .name = "ar8216",
++       .cpu_port = 0,
++       .port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++       return switch_device_register(&ar8216_dev);
++}
++
+--- /dev/null
++++ b/board/arcadyan/arv8539pw22/config.mk
+@@ -0,0 +1,8 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:     GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
++
+--- /dev/null
++++ b/board/arcadyan/arv8539pw22/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script.     
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#define MC_DC00_VALUE  0x1B1B
++#define MC_DC01_VALUE  0x0
++#define MC_DC02_VALUE  0x0
++#define MC_DC03_VALUE  0x0
++#define MC_DC04_VALUE  0x0
++#define MC_DC05_VALUE  0x200
++#define MC_DC06_VALUE  0x605
++#define MC_DC07_VALUE  0x303
++#define MC_DC08_VALUE  0x102
++#define MC_DC09_VALUE  0x70A
++#define MC_DC10_VALUE  0x203
++#define MC_DC11_VALUE  0xC02
++#define MC_DC12_VALUE  0x1C8
++#define MC_DC13_VALUE  0x1
++#define MC_DC14_VALUE  0x0
++#define MC_DC15_VALUE  0x134
++#define MC_DC16_VALUE  0xC800
++#define MC_DC17_VALUE  0xD
++#define MC_DC18_VALUE  0x301
++#define MC_DC19_VALUE  0x200
++#define MC_DC20_VALUE  0xA03
++#define MC_DC21_VALUE  0x1400
++#define MC_DC22_VALUE  0x1414
++#define MC_DC23_VALUE  0x0
++#define MC_DC24_VALUE  0x5B
++#define MC_DC25_VALUE  0x0
++#define MC_DC26_VALUE  0x0
++#define MC_DC27_VALUE  0x0
++#define MC_DC28_VALUE  0x510
++#define MC_DC29_VALUE  0x4E20
++#define MC_DC30_VALUE  0x8235
++#define MC_DC31_VALUE  0x0
++#define MC_DC32_VALUE  0x0
++#define MC_DC33_VALUE  0x0
++#define MC_DC34_VALUE  0x0
++#define MC_DC35_VALUE  0x0
++#define MC_DC36_VALUE  0x0
++#define MC_DC37_VALUE  0x0
++#define MC_DC38_VALUE  0x0
++#define MC_DC39_VALUE  0x0
++#define MC_DC40_VALUE  0x0
++#define MC_DC41_VALUE  0x0
++#define MC_DC42_VALUE  0x0
++#define MC_DC43_VALUE  0x0
++#define MC_DC44_VALUE  0x0
++#define MC_DC45_VALUE  0x500
++#define MC_DC46_VALUE  0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -520,6 +520,9 @@ Active  mips        mips32         danub
+ Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_brn                      arv752dpw22:SYS_BOOT_BRN                                                                                                          -
+ Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_nor                      arv752dpw22:SYS_BOOT_NOR                                                                                                          -
+ Active  mips        mips32         danube      arcadyan        arv752dpw22         arv752dpw22_ram                      arv752dpw22:SYS_BOOT_RAM                                                                                                          -
++Active  mips        mips32         danube      arcadyan        arv8539pw22         arv8539pw22_brn                      arv8539pw22:SYS_BOOT_BRN                                                                                                          -
++Active  mips        mips32         danube      arcadyan        arv8539pw22         arv8539pw22_nor                      arv8539pw22:SYS_BOOT_NOR                                                                                                          -
++Active  mips        mips32         danube      arcadyan        arv8539pw22         arv8539pw22_ram                      arv8539pw22:SYS_BOOT_RAM                                                                                                          -
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_nor                          acmp252:SYS_BOOT_NOR                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      audiocodes      acmp252             acmp252_ram                          acmp252:SYS_BOOT_RAM                                                                                                              Daniel Golle <daniel.golle@gmail.com>
+ Active  mips        mips32         danube      gigaset         sx76x               gigasx76x_nor                        sx76x:SYS_BOOT_NOR                                                                                                                Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv8539pw22.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2012-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:    GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE       "ARV8539PW22"
++#define CONFIG_IDENT_STRING    " "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME      "Speedport W 504V Typ A"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART                /* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET    /* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH   /* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_AR8216
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET              (192 * 1024)
++#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE                        (8 * 1024)
++#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
++
++/* Burnboot loadable image */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE           0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_OVERWRITE 1
++#endif
++
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE                        115200
++#define CONFIG_CONSOLE_ASC             1
++#define CONFIG_CONSOLE_DEV             "ttyS1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_ENV_UPDATE_UBOOT_NOR            \
++       "update-uboot-nor=run load-uboot-nor write-uboot-nor\0"
++
++#define CONFIG_EXTRA_ENV_SETTINGS      \
++       CONFIG_ENV_LANTIQ_DEFAULTS      \
++       CONFIG_ENV_UPDATE_UBOOT_NOR     \
++       "kernel_addr=0xB0040000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0114-MIPS-add-board-support-for-Arcadyan-VGV7519.patch b/package/boot/uboot-lantiq/patches/0114-MIPS-add-board-support-for-Arcadyan-VGV7519.patch
new file mode 100644
index 0000000..2ac7856
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0114-MIPS-add-board-support-for-Arcadyan-VGV7519.patch
@@ -0,0 +1,290 @@
+--- /dev/null
++++ b/board/arcadyan/vgv7519/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/vgv7519/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/vgv7519/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2016 Mathias Kresin <dev@kresin.me>
++ *
++ * The values have been extracted from original brnboot.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000100
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x100
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000401
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x2040F
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141B42
++#define	MC_CCR42_VALUE	0x141B42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x2040F
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- /dev/null
++++ b/board/arcadyan/vgv7519/vgv7519.c
+@@ -0,0 +1,95 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#include <common.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++#define GPIO_GPHY_RESET	47
++
++static void gpio_init(void)
++{
++	/* Disable reset on external eth PHY */
++	gpio_direction_output(GPIO_GPHY_RESET, 1);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
++	{ 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
++	{ 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC3: unused */
++	{ 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++	{ 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FF0000;
++
++	if (ltq_chip_version_get() == 1)
++		ltq_gphy_phy22f_a1x_load(fw_addr);
++	else
++		ltq_gphy_phy22f_a2x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -537,6 +537,9 @@ Active  mips        mips32         incai
+ Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_brn                      vgv7510kw22:SYS_BOOT_BRN                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_nor                      vgv7510kw22:SYS_BOOT_NOR                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ Active  mips        mips32         vrx200      arcadyan        vgv7510kw22         vgv7510kw22_ram                      vgv7510kw22:SYS_BOOT_RAM                                                                                                           Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++Active  mips        mips32         vrx200      arcadyan        vgv7519             vgv7519_brn                          vgv7519:SYS_BOOT_BRN                                                                                                              Mathias Kresin <dev@kresin.me>
++Active  mips        mips32         vrx200      arcadyan        vgv7519             vgv7519_nor                          vgv7519:SYS_BOOT_NOR                                                                                                              Eddi De Pieri <eddi@depieri.net>
++Active  mips        mips32         vrx200      arcadyan        vgv7519             vgv7519_ram                          vgv7519:SYS_BOOT_RAM                                                                                                              Eddi De Pieri <eddi@depieri.net>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_eva                           fb3370:SYS_BOOT_EVA                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_ram                           fb3370:SYS_BOOT_RAM                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_sfspl                         fb3370:SYS_BOOT_SFSPL                                                                                                             Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/vgv7519.h
+@@ -0,0 +1,64 @@
++/*
++ * This file is released under the terms of GPL v2 and any later version.
++ * See the file COPYING in the root directory of the source tree for details.
++ *
++ * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"VGV7519"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan VGV7519"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++#define CONFIG_SYS_MAX_FLASH_BANKS	2	/* max number of memory banks */
++#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH2_BASE }
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_OVERWRITE		1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(384 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(8 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS \
++	"kernel_addr=0xB0080000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0115-MIPS-add-board-support-for-Arcadyan-ARV7506PW11.patch b/package/boot/uboot-lantiq/patches/0115-MIPS-add-board-support-for-Arcadyan-ARV7506PW11.patch
new file mode 100644
index 0000000..2a7c49c
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0115-MIPS-add-board-support-for-Arcadyan-ARV7506PW11.patch
@@ -0,0 +1,277 @@
+--- /dev/null
++++ b/board/arcadyan/arv7506pw11/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/arcadyan/arv7506pw11/arv7506pw11.c
+@@ -0,0 +1,97 @@
++/*
++ * Copyright (C) 2016 Mathias Kresin <dev@kresin.me>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <switch.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/reset.h>
++#include <asm/lantiq/chipid.h>
++
++#if defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define do_gpio_init	1
++#else
++#define do_gpio_init	0
++#endif
++
++#define GPIO_POWER_GREEN	3
++#define GPIO_POWER_RED	6
++#define GPIO_GPHY_RESET 19
++
++static void gpio_init(void)
++{
++	/* Reset switch to have him in a clean state on reboot */
++	gpio_direction_output(GPIO_GPHY_RESET, 0);
++	udelay(20);
++	gpio_direction_output(GPIO_GPHY_RESET, 1);
++
++	/* Turn on the green power LED */
++	gpio_direction_output(GPIO_POWER_GREEN, 0);
++
++	/* Turn off the red power LED */
++	gpio_direction_output(GPIO_POWER_RED, 1);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++void show_boot_progress(int arg)
++{
++	if (!do_gpio_init)
++		return 0;
++
++	if (arg >= 0) {
++		/* Success - turn off the red power LED and turn on the green power LED */
++		gpio_set_value(GPIO_POWER_RED, 1);
++		gpio_set_value(GPIO_POWER_GREEN, 0);
++	} else {
++		/* Failure - turn off green power LED and turn on red power LED */
++		gpio_set_value(GPIO_POWER_GREEN, 1);
++		gpio_set_value(GPIO_POWER_RED, 0);
++	}
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* MAC0: Realtek rtl8306 switch */
++	{ 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t *bis)
++{
++	return ltq_eth_initialize(&eth_board_config);
++}
++static struct switch_device rtl8306_dev = {
++	.name = "rtl8306",
++	.cpu_port = 5,
++	.port_mask = 0xF,
++};
++
++int board_switch_init(void)
++{
++	return switch_device_register(&rtl8306_dev);
++}
+--- /dev/null
++++ b/board/arcadyan/arv7506pw11/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/arcadyan/arv7506pw11/ddr_settings.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2011-2013 Luka Perkov <luka@openwrt.org>
++ *
++ * This file has been generated with lantiq_ram_extract_magic.awk script. 
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define MC_DC00_VALUE	0x1B1B
++#define MC_DC01_VALUE	0x0
++#define MC_DC02_VALUE	0x0
++#define MC_DC03_VALUE	0x0
++#define MC_DC04_VALUE	0x0
++#define MC_DC05_VALUE	0x200
++#define MC_DC06_VALUE	0x605
++#define MC_DC07_VALUE	0x303
++#define MC_DC08_VALUE	0x102
++#define MC_DC09_VALUE	0x70A
++#define MC_DC10_VALUE	0x203
++#define MC_DC11_VALUE	0xC02
++#define MC_DC12_VALUE	0x1C8
++#define MC_DC13_VALUE	0x1
++#define MC_DC14_VALUE	0x0
++#define MC_DC15_VALUE	0x142
++#define MC_DC16_VALUE	0xC800
++#define MC_DC17_VALUE	0xD
++#define MC_DC18_VALUE	0x301
++#define MC_DC19_VALUE	0x200
++#define MC_DC20_VALUE	0xA03
++#define MC_DC21_VALUE	0x1300
++#define MC_DC22_VALUE	0x1313
++#define MC_DC23_VALUE	0x0
++#define MC_DC24_VALUE	0x68
++#define MC_DC25_VALUE	0x0
++#define MC_DC26_VALUE	0x0
++#define MC_DC27_VALUE	0x0
++#define MC_DC28_VALUE	0x510
++#define MC_DC29_VALUE	0x4E20
++#define MC_DC30_VALUE	0x8235
++#define MC_DC31_VALUE	0x0
++#define MC_DC32_VALUE	0x0
++#define MC_DC33_VALUE	0x0
++#define MC_DC34_VALUE	0x0
++#define MC_DC35_VALUE	0x0
++#define MC_DC36_VALUE	0x0
++#define MC_DC37_VALUE	0x0
++#define MC_DC38_VALUE	0x0
++#define MC_DC39_VALUE	0x0
++#define MC_DC40_VALUE	0x0
++#define MC_DC41_VALUE	0x0
++#define MC_DC42_VALUE	0x0
++#define MC_DC43_VALUE	0x0
++#define MC_DC44_VALUE	0x0
++#define MC_DC45_VALUE	0x500
++#define MC_DC46_VALUE	0x0
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -505,6 +505,9 @@ Active  mips        mips32         au1x0
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_brn                        arv4519pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_nor                        arv4519pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv4519pw           arv4519pw_ram                        arv4519pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
++Active  mips        mips32         danube      arcadyan        arv7506pw11         arv7506pw11_brn                      arv7506pw11:SYS_BOOT_BRN                                                                                                          Mathias Kresin <dev@kresin.me>
++Active  mips        mips32         danube      arcadyan        arv7506pw11         arv7506pw11_nor                      arv7506pw11:SYS_BOOT_NOR                                                                                                          Mathias Kresin <dev@kresin.me>
++Active  mips        mips32         danube      arcadyan        arv7506pw11         arv7506pw11_ram                      arv7506pw11:SYS_BOOT_RAM                                                                                                          Mathias Kresin <dev@kresin.me>
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_brn                        arv7510pw:SYS_BOOT_BRN                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_nor                        arv7510pw:SYS_BOOT_NOR                                                                                                            Luka Perkov <luka@openwrt.org>
+ Active  mips        mips32         danube      arcadyan        arv7510pw           arv7510pw_ram                        arv7510pw:SYS_BOOT_RAM                                                                                                            Luka Perkov <luka@openwrt.org>
+--- /dev/null
++++ b/include/configs/arv7506pw11.h
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (C) 2016 Mathias Kresin <dev@kresin.me>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"ARV7506PW11"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"Arcadyan ARV7506PW11"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART		/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET	/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NOR_FLASH	/* Have a parallel NOR flash */
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* Switch devices */
++#define CONFIG_SWITCH_MULTI
++#define CONFIG_SWITCH_RTL8306
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_BRN)
++#define CONFIG_SYS_TEXT_BASE		0x80002000
++#define CONFIG_SKIP_LOWLEVEL_INIT
++#define CONFIG_SYS_DISABLE_CACHE
++#define CONFIG_ENV_IS_NOWHERE
++#define CONFIG_ENV_OVERWRITE 1
++#elif defined(CONFIG_SYS_BOOT_NOR)
++#define CONFIG_ENV_IS_IN_FLASH
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(256 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(64 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(64 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY Danube */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS	\
++	"kernel_addr=0xB0050000\0"
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/0116-MIPS-add-board-support-for-BT-Home-Hub-5A.patch b/package/boot/uboot-lantiq/patches/0116-MIPS-add-board-support-for-BT-Home-Hub-5A.patch
new file mode 100644
index 0000000..fd709bc
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/0116-MIPS-add-board-support-for-BT-Home-Hub-5A.patch
@@ -0,0 +1,344 @@
+--- /dev/null
++++ b/board/bt/bthomehubv5a/Makefile
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++include $(TOPDIR)/config.mk
++
++LIB	= $(obj)lib$(BOARD).o
++
++COBJS	= $(BOARD).o
++
++SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS	:= $(addprefix $(obj),$(COBJS))
++SOBJS	:= $(addprefix $(obj),$(SOBJS))
++
++$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
++	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- /dev/null
++++ b/board/bt/bthomehubv5a/bthomehubv5a.c
+@@ -0,0 +1,125 @@
++/*
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ * Based on p2812hnufx.c: (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/gpio.h>
++#include <asm/lantiq/eth.h>
++#include <asm/lantiq/chipid.h>
++#include <asm/lantiq/cpu.h>
++#include <asm/arch/gphy.h>
++
++#if defined(CONFIG_SPL_BUILD)
++#define do_gpio_init	1
++#define do_pll_init	1
++#define do_dcdc_init	0
++#elif defined(CONFIG_SYS_BOOT_RAM)
++#define do_gpio_init	1
++#define do_pll_init	0
++#define do_dcdc_init	1
++#else
++#define do_gpio_init	0
++#define do_pll_init	0
++#define do_dcdc_init	1
++#endif
++
++#define GPIO_POWER_GREEN	14
++#define GPIO_POWER_RED	12
++
++static void gpio_init(void)
++{
++	/* EBU.FL_CS1 as output for NAND CE */
++	gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A23 as output for NAND CLE */
++	gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* EBU.FL_A24 as output for NAND ALE */
++	gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++	/* GPIO 3.0 as input for NAND Ready Busy */
++	gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
++	/* GPIO 3.1 as output for NAND Read */
++	gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
++
++	/* Turn on the green power LED */
++	gpio_direction_output(GPIO_POWER_GREEN, 0);
++
++	/* Turn off the red power LED */
++	gpio_direction_output(GPIO_POWER_RED, 1);
++}
++
++int board_early_init_f(void)
++{
++	if (do_gpio_init)
++		gpio_init();
++
++	if (do_pll_init)
++		ltq_pll_init();
++
++	if (do_dcdc_init)
++		ltq_dcdc_init(0x7F);
++
++	return 0;
++}
++
++int checkboard(void)
++{
++	puts("Board: " CONFIG_BOARD_NAME "\n");
++	ltq_chip_print_info();
++
++	return 0;
++}
++
++void show_boot_progress(int arg)
++{
++	if (!do_gpio_init)
++		return 0;
++
++	if (arg >= 0) {
++		/* Success - turn off the red power LED and turn on the green power LED */
++		gpio_set_value(GPIO_POWER_RED, 1);
++		gpio_set_value(GPIO_POWER_GREEN, 0);
++	} else {
++		/* Failure - turn off green power LED and turn on red power LED */
++		gpio_set_value(GPIO_POWER_GREEN, 1);
++		gpio_set_value(GPIO_POWER_RED, 0);
++	}
++
++	return 0;
++}
++
++static const struct ltq_eth_port_config eth_port_config[] = {
++	/* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 3 */
++	{ 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 4 */
++	{ 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++	/* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
++	{ 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC3: unused */
++	{ 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
++	/* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 1 */
++	{ 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
++	/* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
++	{ 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
++};
++
++static const struct ltq_eth_board_config eth_board_config = {
++	.ports = eth_port_config,
++	.num_ports = ARRAY_SIZE(eth_port_config),
++};
++
++int board_eth_init(bd_t * bis)
++{
++	const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
++	const ulong fw_addr = 0x80FE0000;
++
++	ltq_gphy_phy11g_a2x_load(fw_addr);
++
++	ltq_cgu_gphy_clk_src(clk);
++
++	ltq_rcu_gphy_boot(0, fw_addr);
++	ltq_rcu_gphy_boot(1, fw_addr);
++
++	return ltq_eth_initialize(&eth_board_config);
++}
+--- /dev/null
++++ b/board/bt/bthomehubv5a/config.mk
+@@ -0,0 +1,7 @@
++#
++# Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
++#
++# SPDX-License-Identifier:	GPL-2.0+
++#
++
++PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
+--- /dev/null
++++ b/board/bt/bthomehubv5a/ddr_settings.h
+@@ -0,0 +1,70 @@
++/*
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ *
++ * The values have been taken from the HH5A GPL source.
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#define	MC_CCR00_VALUE	0x101
++#define	MC_CCR01_VALUE	0x1000101
++#define	MC_CCR02_VALUE	0x1010000
++#define	MC_CCR03_VALUE	0x101
++#define	MC_CCR04_VALUE	0x1000000
++#define	MC_CCR05_VALUE	0x1000101
++#define	MC_CCR06_VALUE	0x1000100
++#define	MC_CCR07_VALUE	0x1010000
++#define	MC_CCR08_VALUE	0x1000101
++#define	MC_CCR09_VALUE	0x0
++#define	MC_CCR10_VALUE	0x2000100
++#define	MC_CCR11_VALUE	0x2000401
++#define	MC_CCR12_VALUE	0x30000
++#define	MC_CCR13_VALUE	0x202
++#define	MC_CCR14_VALUE	0x7080A0F
++#define	MC_CCR15_VALUE	0x2040F
++#define	MC_CCR16_VALUE	0x40000
++#define	MC_CCR17_VALUE	0x70102
++#define	MC_CCR18_VALUE	0x4020002
++#define	MC_CCR19_VALUE	0x30302
++#define	MC_CCR20_VALUE	0x8000700
++#define	MC_CCR21_VALUE	0x40F020A
++#define	MC_CCR22_VALUE	0x0
++#define	MC_CCR23_VALUE	0xC020000
++#define	MC_CCR24_VALUE	0x4401B04
++#define	MC_CCR25_VALUE	0x0
++#define	MC_CCR26_VALUE	0x0
++#define	MC_CCR27_VALUE	0x6420000
++#define	MC_CCR28_VALUE	0x0
++#define	MC_CCR29_VALUE	0x0
++#define	MC_CCR30_VALUE	0x798
++#define	MC_CCR31_VALUE	0x0
++#define	MC_CCR32_VALUE	0x0
++#define	MC_CCR33_VALUE	0x650000
++#define	MC_CCR34_VALUE	0x200C8
++#define	MC_CCR35_VALUE	0x1D445D
++#define	MC_CCR36_VALUE	0xC8
++#define	MC_CCR37_VALUE	0xC351
++#define	MC_CCR38_VALUE	0x0
++#define	MC_CCR39_VALUE	0x141F04
++#define	MC_CCR40_VALUE	0x142704
++#define	MC_CCR41_VALUE	0x141b42
++#define	MC_CCR42_VALUE	0x141b42
++#define	MC_CCR43_VALUE	0x566504
++#define	MC_CCR44_VALUE	0x566504
++#define	MC_CCR45_VALUE	0x565F17
++#define	MC_CCR46_VALUE	0x565F17
++#define	MC_CCR47_VALUE	0x0
++#define	MC_CCR48_VALUE	0x0
++#define	MC_CCR49_VALUE	0x0
++#define	MC_CCR50_VALUE	0x0
++#define	MC_CCR51_VALUE	0x0
++#define	MC_CCR52_VALUE	0x133
++#define	MC_CCR53_VALUE	0xF3014B27
++#define	MC_CCR54_VALUE	0xF3014B27
++#define	MC_CCR55_VALUE	0xF3014B27
++#define	MC_CCR56_VALUE	0xF3014B27
++#define	MC_CCR57_VALUE	0x7800301
++#define	MC_CCR58_VALUE	0x7800301
++#define	MC_CCR59_VALUE	0x7800301
++#define	MC_CCR60_VALUE	0x7800301
++#define	MC_CCR61_VALUE	0x4
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -546,6 +546,8 @@ Active  mips        mips32         vrx20
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_eva                           fb3370:SYS_BOOT_EVA                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_ram                           fb3370:SYS_BOOT_RAM                                                                                                               Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      avm             fb3370              fb3370_sfspl                         fb3370:SYS_BOOT_SFSPL                                                                                                             Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
++Active  mips        mips32         vrx200      bt              bthomehubv5a        bthomehubv5a_nandspl                 bthomehubv5a:SYS_BOOT_NANDSPL                                                                                                     Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++Active  mips        mips32         vrx200      bt              bthomehubv5a        bthomehubv5a_ram                     bthomehubv5a:SYS_BOOT_RAM                                                                                                         Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nandspl                    easy80920:SYS_BOOT_NANDSPL                                                                                                        Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nor                        easy80920:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+ Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_norspl                     easy80920:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+--- /dev/null
++++ b/include/configs/bthomehubv5a.h
+@@ -0,0 +1,89 @@
++/*
++ * Copyright (C) 2016 Mathias Kresin <openwrt@kresin.me>
++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
++ * Based on p2812hnufx.h: (C) 2013 Luka Perkov <luka@openwrt.org>
++ *
++ * SPDX-License-Identifier:	GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MACH_TYPE	"BTHOMEHUBV5A"
++#define CONFIG_IDENT_STRING	" "CONFIG_MACH_TYPE
++#define CONFIG_BOARD_NAME	"BT Home Hub 5A"
++
++/* Configure SoC */
++#define CONFIG_LTQ_SUPPORT_UART			/* Enable ASC and UART */
++
++#define CONFIG_LTQ_SUPPORT_ETHERNET		/* Enable ethernet */
++
++#define CONFIG_LTQ_SUPPORT_NAND_FLASH		/* Have a ML01G100BHI00 NAND flash */
++#define CONFIG_SYS_NAND_USE_FLASH_BBT
++
++#define CONFIG_LTQ_SUPPORT_SPL_NAND_FLASH	/* Build NAND flash SPL */
++#define CONFIG_SYS_NAND_PAGE_COUNT	64
++#define CONFIG_SYS_NAND_PAGE_SIZE	2048
++#define CONFIG_SYS_NAND_OOBSIZE		64
++#define CONFIG_SYS_NAND_BLOCK_SIZE	(128 * 1024)
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
++
++#define CONFIG_LTQ_SPL_COMP_LZO			/* Compress SPL with LZO */
++#define CONFIG_LTQ_SPL_CONSOLE			/* Enable SPL console */
++#define CONFIG_LTQ_SPL_MC_TUNE
++
++#define CONFIG_SYS_BOOTM_LEN		0x1000000	/* 16 MB */
++
++/* MTD devices */
++#define CONFIG_MTD_PARTITIONS
++#define CONFIG_MTD_DEVICE
++#define CONFIG_CMD_MTDPARTS
++#define MTDIDS_DEFAULT			"nand0=nand-xway"
++#define MTDPARTS_DEFAULT		"mtdparts=nand-xway:0x07e80000@0x100000(UBI)"
++
++/* UBI */
++#define CONFIG_RBTREE
++#define CONFIG_CMD_UBI
++#define CONFIG_CMD_UBIFS
++
++/* Environment */
++#if defined(CONFIG_SYS_BOOT_NANDSPL)
++#define CONFIG_SPL_TPL_OFFS		0x800
++#define CONFIG_SPL_TPL_SIZE		0x5000
++#define CONFIG_SPL_MC_TUNE_OFFS		0x5800
++#define CONFIG_SPL_U_BOOT_OFFS		0x6000
++#define CONFIG_SPL_U_BOOT_SIZE		0x3a000
++
++#define CONFIG_ENV_IS_IN_NAND
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_OFFSET		(640 * 1024)
++#define CONFIG_ENV_SECT_SIZE		(128 * 1024)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_ENV_SIZE			(128 * 1024)
++
++#define CONFIG_LOADADDR			CONFIG_SYS_LOAD_ADDR
++
++/* Console */
++#define CONFIG_LTQ_ADVANCED_CONSOLE
++#define CONFIG_BAUDRATE			115200
++#define CONFIG_CONSOLE_ASC		1
++#define CONFIG_CONSOLE_DEV		"ttyLTQ1"
++
++/* Pull in default board configs for Lantiq XWAY VRX200 */
++#include <asm/lantiq/config.h>
++#include <asm/arch/config.h>
++
++/* Pull in default OpenWrt configs for Lantiq SoC */
++#include "openwrt-lantiq-common.h"
++
++#undef CONFIG_BOOTCOMMAND
++#define CONFIG_BOOTCOMMAND \
++	"mtdparts default; ubi part UBI; ubi read ${loadaddr} kernel; bootm ${loadaddr}"
++
++#define CONFIG_EXTRA_ENV_SETTINGS	\
++	CONFIG_ENV_LANTIQ_DEFAULTS
++
++#endif /* __CONFIG_H */
diff --git a/package/boot/uboot-lantiq/patches/100-portability.patch b/package/boot/uboot-lantiq/patches/100-portability.patch
new file mode 100644
index 0000000..4539e3e
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/100-portability.patch
@@ -0,0 +1,18 @@
+--- a/include/image.h
++++ b/include/image.h
+@@ -17,7 +17,6 @@
+ #define __IMAGE_H__
+ 
+ #include "compiler.h"
+-#include <asm/byteorder.h>
+ 
+ /* Define this to avoid #ifdefs later on */
+ struct lmb;
+@@ -36,6 +35,7 @@ struct lmb;
+ 
+ #include <lmb.h>
+ #include <asm/u-boot.h>
++#include <asm/byteorder.h>
+ #include <command.h>
+ 
+ /* Take notice of the 'ignore' property for hashes */
diff --git a/package/boot/uboot-lantiq/patches/101-fix-crypt-header-clash.patch b/package/boot/uboot-lantiq/patches/101-fix-crypt-header-clash.patch
new file mode 100644
index 0000000..fcb1a3d
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/101-fix-crypt-header-clash.patch
@@ -0,0 +1,172 @@
+Fix header clash with system /usr/include/sha1.h and sha256.h when libmd
+is installed.
+
+Backport of u-boot commit "includes: move openssl headers to include/u-boot"
+https://github.com/u-boot/u-boot/commit/2b9912e6a7df7b1f60beb7942bd0e6fa5f9d0167
+
+--- a/board/gdsys/p1022/controlcenterd-id.c
++++ b/board/gdsys/p1022/controlcenterd-id.c
+@@ -30,7 +30,7 @@
+ #include <i2c.h>
+ #include <mmc.h>
+ #include <tpm.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+ #include <pca9698.h>
+--- a/board/pcs440ep/pcs440ep.c
++++ b/board/pcs440ep/pcs440ep.c
+@@ -13,7 +13,7 @@
+ #include <asm/processor.h>
+ #include <spd_sdram.h>
+ #include <status_led.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <asm/io.h>
+ #include <net.h>
+ #include <ata.h>
+--- a/common/cmd_sha1sum.c
++++ b/common/cmd_sha1sum.c
+@@ -11,7 +11,7 @@
+ #include <common.h>
+ #include <command.h>
+ #include <hash.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ 
+ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ {
+--- a/common/hash.c
++++ b/common/hash.c
+@@ -14,8 +14,8 @@
+ #include <command.h>
+ #include <hw_sha.h>
+ #include <hash.h>
+-#include <sha1.h>
+-#include <sha256.h>
++#include <u-boot/sha1.h>
++#include <u-boot/sha256.h>
+ #include <asm/io.h>
+ #include <asm/errno.h>
+ 
+--- a/common/image-fit.c
++++ b/common/image-fit.c
+@@ -21,7 +21,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ #endif /* !USE_HOSTCC*/
+ 
+ #include <bootstage.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <u-boot/crc.h>
+ #include <u-boot/md5.h>
+ 
+--- a/common/image.c
++++ b/common/image.c
+@@ -34,7 +34,7 @@
+ #endif
+ 
+ #include <u-boot/md5.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <asm/errno.h>
+ #include <asm/io.h>
+ 
+--- a/drivers/crypto/ace_sha.c
++++ b/drivers/crypto/ace_sha.c
+@@ -5,8 +5,8 @@
+  * SPDX-License-Identifier:	GPL-2.0+
+  */
+ #include <common.h>
+-#include <sha256.h>
+-#include <sha1.h>
++#include <u-boot/sha256.h>
++#include <u-boot/sha1.h>
+ #include <asm/errno.h>
+ #include "ace_sha.h"
+ 
+--- /dev/null
++++ b/include/u-boot/sha1.h
+@@ -0,0 +1 @@
++#include "../sha1.h"
+--- /dev/null
++++ b/include/u-boot/sha256.h
+@@ -0,0 +1 @@
++#include "../sha256.h"
+--- a/lib/rsa/rsa-verify.c
++++ b/lib/rsa/rsa-verify.c
+@@ -7,7 +7,7 @@
+ #include <common.h>
+ #include <fdtdec.h>
+ #include <rsa.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <asm/byteorder.h>
+ #include <asm/errno.h>
+ #include <asm/unaligned.h>
+--- a/lib/sha1.c
++++ b/lib/sha1.c
+@@ -36,7 +36,7 @@
+ #include <string.h>
+ #endif /* USE_HOSTCC */
+ #include <watchdog.h>
+-#include "sha1.h"
++#include <u-boot/sha1.h>
+ 
+ /*
+  * 32-bit integer manipulation macros (big endian)
+--- a/lib/sha256.c
++++ b/lib/sha256.c
+@@ -11,7 +11,7 @@
+ #endif /* USE_HOSTCC */
+ #include <watchdog.h>
+ #include <linux/string.h>
+-#include <sha256.h>
++#include <u-boot/sha256.h>
+ 
+ /*
+  * 32-bit integer manipulation macros (big endian)
+--- a/lib/tpm.c
++++ b/lib/tpm.c
+@@ -7,7 +7,7 @@
+ 
+ #include <common.h>
+ #include <stdarg.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <tpm.h>
+ #include <asm/unaligned.h>
+ 
+--- a/tools/imls/imls.c
++++ b/tools/imls/imls.c
+@@ -24,7 +24,7 @@
+ #include <mtd/mtd-user.h>
+ #endif
+ 
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <image.h>
+--- a/tools/mkimage.h
++++ b/tools/mkimage.h
+@@ -18,7 +18,7 @@
+ #include <sys/stat.h>
+ #include <time.h>
+ #include <unistd.h>
+-#include <sha1.h>
++#include <u-boot/sha1.h>
+ #include "fdt_host.h"
+ 
+ #undef MKIMAGE_DEBUG
+--- a/tools/ubsha1.c
++++ b/tools/ubsha1.c
+@@ -13,7 +13,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <sys/stat.h>
+-#include "sha1.h"
++#include <u-boot/sha1.h>
+ 
+ int main (int argc, char **argv)
+ {
diff --git a/package/boot/uboot-lantiq/patches/200-fix-dtc-header-guard.patch b/package/boot/uboot-lantiq/patches/200-fix-dtc-header-guard.patch
new file mode 100644
index 0000000..88d914b
--- /dev/null
+++ b/package/boot/uboot-lantiq/patches/200-fix-dtc-header-guard.patch
@@ -0,0 +1,19 @@
+--- a/include/libfdt_env.h
++++ b/include/libfdt_env.h
+@@ -8,6 +8,7 @@
+ 
+ #ifndef _LIBFDT_ENV_H
+ #define _LIBFDT_ENV_H
++#define LIBFDT_ENV_H
+ 
+ #include "compiler.h"
+ #include "linux/types.h"
+--- a/include/libfdt.h
++++ b/include/libfdt.h
+@@ -1,5 +1,6 @@
+ #ifndef _LIBFDT_H
+ #define _LIBFDT_H
++#define LIBFDT_H
+ /*
+  * libfdt - Flat Device Tree manipulation
+  * Copyright (C) 2006 David Gibson, IBM Corporation.