diff options
Diffstat (limited to 'package/boot/uboot-lantiq')
47 files changed, 19245 insertions, 0 deletions
diff --git a/package/boot/uboot-lantiq/Makefile b/package/boot/uboot-lantiq/Makefile new file mode 100644 index 0000000..99b101f --- /dev/null +++ b/package/boot/uboot-lantiq/Makefile @@ -0,0 +1,383 @@ +# +# Copyright (C) 2012-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=u-boot +PKG_VERSION:=2013.10 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:= \ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_MD5SUM:=a076a044b64371edc52f7e562b13f6b2 +PKG_TARGETS:=bin + +PKG_LICENSE:=GPL-2.0 GPL-2.0+ +PKG_LICENSE_FILES:=Licenses/README + +PKG_BUILD_PARALLEL:=1 + +FIRMWARE_LANTIQ_SOURCE:=$(TOPDIR)/target/linux/lantiq/files/firmware/lantiq + +include $(INCLUDE_DIR)/package.mk + +define uboot/Default + TITLE:= + SOC:= + DDR_SETTINGS:= + IMAGE:= + DEPS:= +endef + +define uboot/arv4519pw_ram + TITLE:=U-Boot for Arcadyan arv4519pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv4519pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv4519pw_nor + TITLE:=U-Boot for Arcadyan arv4519pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv4519pw_brn + TITLE:=U-Boot for Arcadyan arv4519pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4519PW +endef + +define uboot/arv7510pw_ram + TITLE:=U-Boot for Arcadyan arv7510pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7510pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw_nor + TITLE:=U-Boot for Arcadyan arv7510pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw_brn + TITLE:=U-Boot for Arcadyan arv7510pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV4510PW +endef + +define uboot/arv7510pw22_ram + TITLE:=U-Boot for Arcadyan arv7510pw22 (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7510pw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7510pw22_nor + TITLE:=U-Boot for Arcadyan arv7510pw22 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7510pw22_brn + TITLE:=U-Boot for Arcadyan arv7510pw22 (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7510PW22 +endef + +define uboot/arv7518pw_ram + TITLE:=U-Boot for Arcadyan arv7518pw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv7518pw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv7518pw_nor + TITLE:=U-Boot for Arcadyan arv7518pw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv7518pw_brn + TITLE:=U-Boot for Arcadyan arv7518pw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV7518PW +endef + +define uboot/arv752dpw_ram + TITLE:=U-Boot for Arcadyan arv752dpw (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv752dpw/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw_nor + TITLE:=U-Boot for Arcadyan arv752dpw (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw_brn + TITLE:=U-Boot for Arcadyan arv752dpw (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW +endef + +define uboot/arv752dpw22_ram + TITLE:=U-Boot for Arcadyan arv752dpw22 (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv752dpw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv752dpw22_nor + TITLE:=U-Boot for Arcadyan arv752dpw22 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv752dpw22_brn + TITLE:=U-Boot for Arcadyan arv752dpw22 (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV752DPW22 +endef + +define uboot/arv8539pw22_ram + TITLE:=U-Boot for Speedport W 504V Typ A (RAM) + SOC:=danube + DDR_SETTINGS:=board/arcadyan/arv8539pw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/arv8539pw22_nor + TITLE:=U-Boot for Speedport W 504V Typ A (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/arv8539pw22_brn + TITLE:=U-Boot for Speedport W 504V Typ A (BRN) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ARV8539PW22 +endef + +define uboot/gigasx76x_ram + TITLE:=U-Boot for Siemens Gigaset sx76x (RAM) + SOC:=danube + DDR_SETTINGS:=board/gigaset/sx76x/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_GIGASX76X +endef + +define uboot/gigasx76x_nor + TITLE:=U-Boot for Siemens Gigaset sx76x (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_GIGASX76X +endef + +define uboot/acmp252_ram + TITLE:=U-Boot for AudioCodes MP-252 (RAM) + SOC:=danube + DDR_SETTINGS:=board/audiocodes/acmp252/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_ACMP252 +endef + +define uboot/acmp252_nor + TITLE:=U-Boot for AudioCodes MP-252 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_ACMP252 +endef + +define uboot/easy50712_ram + TITLE:=U-Boot for Lantiq EASY50712 (RAM) + SOC:=danube + DDR_SETTINGS:=board/lantiq/easy50712/ddr_settings.h + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy50712_nor + TITLE:=U-Boot for Lantiq EASY50712 (NOR) + SOC:=danube + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy50712_norspl + TITLE:=U-Boot for Lantiq EASY50712 (NOR SPL) + SOC:=danube + IMAGE:=u-boot.ltq.lzo.norspl + DEPS:=@TARGET_lantiq_xway_EASY50712 +endef + +define uboot/easy80920_ram + TITLE:=U-Boot for Lantiq EASY80920 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/lantiq/easy80920/ddr_settings.h + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_nor + TITLE:=U-Boot for Lantiq EASY80920 (NOR) + SOC:=vr9 + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_norspl + TITLE:=U-Boot for Lantiq EASY80920 (NOR SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.norspl + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/easy80920_sfspl + TITLE:=U-Boot for Lantiq EASY80920 (SPI SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.sfspl + DEPS:=@(TARGET_lantiq_xrx200_EASY80920NOR||TARGET_lantiq_xrx200_EASY80920NAND) +endef + +define uboot/fb3370_eva + TITLE:=U-Boot for AVM FRITZ3370 (EVA) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/fb3370_ram + TITLE:=U-Boot for AVM FRITZ3370 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/avm/fb3370/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/fb3370_sfspl + TITLE:=U-Boot for AVM FRITZ3370 (SPI SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.sfspl + DEPS:=@TARGET_lantiq_xrx200_FRITZ3370 +endef + +define uboot/p2812hnufx_ram + TITLE:=U-Boot for ZyXEL P-2812HNU-Fx (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/zyxel/p2812hnufx/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_P2812HNUF1||@TARGET_lantiq_xrx200_P2812HNUF3 +endef + +define uboot/p2812hnufx_nandspl + TITLE:=U-Boot for ZyXEL P-2812HNU-Fx (NAND SPL) + SOC:=vr9 + IMAGE:=u-boot.ltq.lzo.nandspl + DEPS:=@TARGET_lantiq_xrx200_P2812HNUF1||@TARGET_lantiq_xrx200_P2812HNUF3 +endef + +define uboot/vgv7510kw22_brn + TITLE:=U-Boot for Arcadyan VGV7510KW22 (BRN) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +define uboot/vgv7510kw22_nor + TITLE:=U-Boot for Arcadyan VGV7510KW22 (NOR) + SOC:=vr9 + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +define uboot/vgv7510kw22_ram + TITLE:=U-Boot for Arcadyan VGV7510KW22 (RAM) + SOC:=vr9 + DDR_SETTINGS:=board/arcadyan/vgv7510kw22/ddr_settings.h + DEPS:=@TARGET_lantiq_xrx200_VGV7510KW22NOR||@TARGET_lantiq_xrx200_VGV7510KW22BRN +endef + +UBOOTS:= \ + arv4519pw_ram arv4519pw_nor arv4519pw_brn \ + arv7510pw_ram arv7510pw_nor arv7510pw_brn \ + arv7510pw22_ram arv7510pw22_nor arv7510pw22_brn \ + arv7518pw_ram arv7518pw_nor arv7518pw_brn \ + arv752dpw_ram arv752dpw_nor arv752dpw_brn \ + arv752dpw22_ram arv752dpw22_nor arv752dpw22_brn \ + arv8539pw22_brn arv8539pw22_nor arv8539pw22_ram \ + gigasx76x_ram gigasx76x_nor \ + acmp252_ram acmp252_nor \ + easy50712_ram easy50712_nor easy50712_norspl \ + easy80920_ram easy80920_nor easy80920_norspl easy80920_sfspl \ + fb3370_eva fb3370_ram fb3370_sfspl \ + p2812hnufx_ram p2812hnufx_nandspl \ + vgv7510kw22_brn vgv7510kw22_nor vgv7510kw22_ram + +define Package/uboot/template +define Package/uboot-lantiq-$(1) + SECTION:=boot + CATEGORY:=Boot Loaders + DEPENDS:=$(3) + TITLE:=$(2) + URL:=http://www.denx.de/wiki/U-Boot + VARIANT:=$(1) + MAINTAINER:=Luka Perkov <luka@openwrt.org> +endef +endef + +define BuildUBootPackage + $(eval $(uboot/Default)) + $(eval $(uboot/$(1))) + DEPS:=$(uboot/$(1)/DEPS) + $(call Package/uboot/template,$(1),$(TITLE),$(DEPS)) +endef + +define CopyVR9Firmware + $(CP) $(FIRMWARE_LANTIQ_SOURCE)/vr9_phy$(1)_a$(2)x.bin \ + $(PKG_BUILD_DIR)/arch/mips/cpu/mips32/vrx200/fw_phy$(1)_a$(2)x.blob +endef + +define Build/Prepare + $(call Build/Prepare/Default) + mkdir -p $(PKG_BUILD_DIR)/arch/mips/cpu/mips32/vrx200/ + $(call CopyVR9Firmware,11g,1) + $(call CopyVR9Firmware,11g,2) + $(call CopyVR9Firmware,22f,1) + $(call CopyVR9Firmware,22f,2) +endef + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR) $(BUILD_VARIANT)_config +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE=$(TARGET_CROSS) +endef + +define Package/uboot/install/default + $(CP) \ + $(PKG_BUILD_DIR)/$(2) \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.img +endef + +define Package/uboot/install/uart + awk -f $(PKG_BUILD_DIR)/tools/lantiq_ram_init_uart.awk \ + -v soc=$(2) $(PKG_BUILD_DIR)/$(3) \ + > $(PKG_BUILD_DIR)/ddr_settings + perl $(PKG_BUILD_DIR)/tools/gct.pl \ + $(PKG_BUILD_DIR)/ddr_settings $(PKG_BUILD_DIR)/u-boot.srec \ + $(BIN_DIR)/uboot-$(BOARD)-$(1)/openwrt-$(BOARD)-$(1)-u-boot.asc + endef + +define Package/uboot/install/template +define Package/uboot-lantiq-$(1)/install + $(call Package/uboot/install/default,$(1),$(if $(IMAGE),$(IMAGE),u-boot.bin)) + $(if $(DDR_SETTINGS), \ + $(call Package/uboot/install/uart,$(1),$(SOC),$(DDR_SETTINGS)) \ + ) +endef +endef + +$(foreach u,$(UBOOTS), \ + $(eval $(call BuildUBootPackage,$(u))) \ + $(eval $(call Package/uboot/install/template,$(u))) \ + $(eval $(call BuildPackage,uboot-lantiq-$(u))) \ +) diff --git a/package/boot/uboot-lantiq/README b/package/boot/uboot-lantiq/README new file mode 100644 index 0000000..44ed2bb --- /dev/null +++ b/package/boot/uboot-lantiq/README @@ -0,0 +1,6 @@ +# How to refresh patches + +$ git clone git@github.com:danielschwierzeck/u-boot-lantiq.git +$ mkdir -p $OPENWRT_ROOT/packages/boot/uboot-lantiq/patches +$ cd u-boot-lantiq.git +$ git format-patch -p -k --no-renames --no-binary -o $OPENWRT_ROOT/package/boot/uboot-lantiq/patches v2013.10..u-boot-lantiq-v2013.10-openwrtN 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..4c01ad0 --- /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@openwrt.org> ++ * ++ * 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..ef6eb1a --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch @@ -0,0 +1,9339 @@ +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(<q_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(<q_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(<q_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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_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(<q_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(<q_rcu_regs->req, val); ++ ++ return 0; ++} ++ ++enum ltq_boot_select ltq_boot_select(void) ++{ ++ u32 stat; ++ unsigned int bootstrap; ++ ++ stat = ltq_readl(<q_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; ++ 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(<q_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(<q_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK); ++ ltq_setbits(<q_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT); ++} ++ ++static inline int ltq_cgu_pll1_locked(void) ++{ ++ u32 pll1_cfg = ltq_readl(<q_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(<q_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN); ++ ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE); ++ ++ pll1_cfg = ltq_readl(<q_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(<q_cgu_regs->pll1_cfg, pll1_cfg); ++ ltq_setbits(<q_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(<q_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(<q_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(<q_dcdc_regs->duty_cycle_max_sat, 0x5A); ++ ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x46); ++ val = ltq_readb(<q_dcdc_regs->conf_test_dig); ++ val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE; ++ ltq_writeb(<q_dcdc_regs->conf_test_dig, val); ++ ++ /* Program new coefficients */ ++ ltq_writeb(<q_dcdc_regs->b0_coeh, 0x00); ++ ltq_writeb(<q_dcdc_regs->b0_coel, 0x00); ++ ltq_writeb(<q_dcdc_regs->b1_coeh, 0xFF); ++ ltq_writeb(<q_dcdc_regs->b1_coel, 0xE6); ++ ltq_writeb(<q_dcdc_regs->b2_coeh, 0x00); ++ ltq_writeb(<q_dcdc_regs->b2_coel, 0x1B); ++ ltq_writeb(<q_dcdc_regs->non_ov_delay, 0x8B); ++ ++ /* Set duty cycle max sat. to 60/108, disable PID freeze */ ++ ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x6C); ++ ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x3C); ++ val = ltq_readb(<q_dcdc_regs->conf_test_dig); ++ val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE; ++ ltq_writeb(<q_dcdc_regs->conf_test_dig, val); ++ ++ /* Init clock and DLL settings */ ++ val = ltq_readb(<q_dcdc_regs->clk_set0); ++ val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P; ++ ltq_writeb(<q_dcdc_regs->clk_set0, val); ++ val = ltq_readb(<q_dcdc_regs->clk_set1); ++ val |= LTQ_DCDC_CLK_SET1_SEL_DIV25; ++ ltq_writeb(<q_dcdc_regs->clk_set1, val); ++ ltq_writeb(<q_dcdc_regs->pwm_confh, 0xF9); ++ ++ wmb(); ++ ++ /* Adapt value of digital reference of DCDC converter */ ++ dig_ref_cur = ltq_readb(<q_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(<q_dcdc_regs->bias_vreg1, dig_ref_cur); ++ __udelay(1000); ++ } ++} +--- /dev/null ++++ b/arch/mips/cpu/mips32/vrx200/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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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,58 @@ ++/* ++ * 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> ++ ++static inline void ltq_gphy_copy(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_copy: addr %08lx, fw_start %p, fw_end %p\n", ++ addr, fw_start, fw_end); ++ ++ memcpy((void *) addr, 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_copy(&__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_copy(&__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_copy(&__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_copy(&__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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_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(<q_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(<q_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(<q_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 = <q_rcu_regs->gfs_add0; ++ break; ++ case 1: ++ module = LTQ_RCU_RD_GPHY1; ++ gfs_add = <q_rcu_regs->gfs_add1; ++ break; ++ default: ++ BUG(); ++ } ++ ++ /* Stop and reset GPHY */ ++ ltq_setbits(<q_rcu_regs->req, module); ++ ++ /* Configure firmware and boot address */ ++ ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000)); ++ ++ /* Start GPHY by releasing reset */ ++ ltq_clrbits(<q_rcu_regs->req, module); ++} +--- /dev/null ++++ b/arch/mips/include/asm/arch-danube/config.h +@@ -0,0 +1,163 @@ ++/* ++ * 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_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,184 @@ ++/* ++ * 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_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) ++#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_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 ®s->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 ®s->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 = ®s->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 ®s->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 ®s->mii.mii_cfg0; ++ case 1: ++ return ®s->mii.mii_cfg1; ++ case 5: ++ return ®s->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 ®s->mii.pcdu0; ++ case 1: ++ return ®s->mii.pcdu1; ++ case 5: ++ return ®s->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 */ +--- /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(ð_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; ++ } ++} +--- /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(ð_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 +@@ -502,10 +502,17 @@ 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> + Active mips mips32 incaip - incaip incaip_150MHz incaip:CPU_CLOCK_RATE=150000000 Wolfgang Denk <wd@denx.de> ++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> +--- 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(<q_dma_regs->ctrl, DMA_CTRL_RESET); ++ ++ /* Disable and clear all interrupts */ ++ ltq_writel(<q_dma_regs->irnen, 0); ++ ltq_writel(<q_dma_regs->irncr, 0xFFFFF); ++ ++#if 0 ++ /* Enable packet arbitration */ ++ ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_PKTARB); ++#endif ++ ++#if 0 ++ /* Enable descriptor read back */ ++ ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_DRB); ++#endif ++ ++ /* Enable polling for descriptor fetching for all channels */ ++ ltq_writel(<q_dma_regs->cpoll, DMA_CPOLL_EN | ++ (4 << DMA_CPOLL_CNT_SHIFT)); ++} ++ ++static void ltq_dma_channel_reset(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_RST); ++} ++ ++static void ltq_dma_channel_enable(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF); ++} ++ ++static void ltq_dma_channel_disable(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_clrbits(<q_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(<q_dma_regs->ps, dev->port); ++ ltq_writel(<q_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(<q_dma_regs->cs, chan->chan_no); ++ ltq_writel(<q_dma_regs->cdba, chan->dma_addr); ++ ltq_writel(<q_dma_regs->cdlen, chan->num_desc); ++ ltq_writel(<q_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) | ++ (chan->class << DMA_CCTRL_CLASS_SHIFT)); ++ ltq_writel(<q_dma_regs->cctrl, DMA_CCTRL_RST); ++ ++ return 0; ++} ++ ++static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan) ++{ ++ ltq_writel(<q_dma_regs->cs, chan->chan_no); ++ ltq_writel(<q_dma_regs->cdba, 0); ++ ltq_writel(<q_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(<q_ssio_regs->ar, 0); ++ ltq_writel(<q_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE); ++ ltq_writel(<q_ssio_regs->cpu1, 0); ++ ltq_writel(<q_ssio_regs->con0, SSIO_CON0_SWU); ++ ++ if (enable_ssio) { ++ ltq_writel(<q_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG | ++ SSIO_RZFL_CONFIG); ++ ltq_writel(<q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ const void *gpio_out = <q_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(<q_ssio_regs->cpu0, data); ++ else ++ ltq_clrbits(<q_ssio_regs->cpu0, data); ++ ++ return 0; ++ } ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_gpio3_regs->dir; ++ gpio_out = <q_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 = <q_gpio_regs->ports[port].in; ++ u32 data = gpio_to_bit(gpio); ++ u32 val; ++ ++ if (is_gpio_ssio(gpio)) { ++ gpio_in = <q_ssio_regs->cpu0; ++ data = ssio_gpio_to_bit(gpio); ++ } ++ ++ if (is_gpio_bank3(port)) ++ gpio_in = <q_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 = <q_gpio_regs->ports[port].out; ++ u32 data = gpio_to_bit(gpio); ++ ++ if (is_gpio_ssio(gpio)) { ++ gpio_out = <q_ssio_regs->cpu0; ++ data = ssio_gpio_to_bit(gpio); ++ } ++ ++ if (is_gpio_bank3(port)) ++ gpio_out = <q_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 = <q_gpio_regs->ports[port].od; ++ const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0; ++ const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1; ++ const void *gpio_dir = <q_gpio_regs->ports[port].dir; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) { ++ gpio_od = <q_gpio3_regs->od; ++ gpio_altsel0 = <q_gpio3_regs->altsel0; ++ gpio_altsel1 = <q_gpio3_regs->altsel1; ++ gpio_dir = <q_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 = <q_gpio_regs->ports[port].od; ++ ++ if (is_gpio_ssio(gpio)) ++ return 0; ++ ++ if (is_gpio_bank3(port)) ++ gpio_od = <q_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(<q_nand_regs->wait) & NAND_WAIT_WR_C) == 0) ++ ; ++} ++ ++static int ltq_nand_dev_ready(struct mtd_info *mtd) ++{ ++ u32 data = ltq_readl(<q_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(<q_nand_regs->con, NAND_CON_NANDM); ++ ltq_setbits(<q_nand_regs->con, NAND_CON_LATCH_CS); ++ } else { ++ ltq_clrbits(<q_nand_regs->con, NAND_CON_LATCH_CS); ++ ltq_clrbits(<q_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(<q_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(<q_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(<q_ppe_etop_regs->mdio_acc, acc.val); ++ ++ ret = ltq_mdio_poll(); ++ if (ret) ++ return ret; ++ ++ acc.val = ltq_readl(<q_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(<q_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(<q_ppe_enet0_regs->mac_da0, da0); ++ ltq_writel(<q_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(<q_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(<q_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(<q_ppe_etop_regs->cfg, data); ++ ++ /* Set allowed packet length from 64 bytes to 1518 bytes */ ++ ltq_writel(<q_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518); ++ ++ /* Enable filter for unicast packets */ ++ ltq_setbits(<q_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 = 0xFFFFFFFF, ++ .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(<q_asc_regs->clc, 0x100); ++ ++ /* Reset MCON register */ ++ ltq_writel(<q_asc_regs->mcon, 0); ++ ++ /* Use Port A as receiver input */ ++ ltq_writel(<q_asc_regs->pisel, 0); ++ ++ /* Enable and flush RX/TX FIFOs */ ++ ltq_setbits(<q_asc_regs->rxfcon, ++ LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN); ++ ltq_setbits(<q_asc_regs->txfcon, ++ LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN); ++ ++ serial_setbrg(); ++ ++ /* Disable error flags, enable receiver */ ++ ltq_writel(<q_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(<q_asc_regs->mcon, LTQ_ASC_MCON_R); ++ ++ /* Enable fractional divider */ ++ ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_FDE); ++ ++ /* Set fdv and bg values */ ++ ltq_writel(<q_asc_regs->fdv, fdv); ++ ltq_writel(<q_asc_regs->bg, bg); ++ ++ /* Enable baudrate generator */ ++ ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R); ++} ++ ++static unsigned int ltq_serial_tx_free(void) ++{ ++ unsigned int txfree; ++ ++ txfree = (ltq_readl(<q_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(<q_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK; ++ ++ return rxffl; ++} ++ ++static void ltq_serial_tx(const char c) ++{ ++ ltq_writeb(<q_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c); ++} ++ ++static u8 ltq_serial_rx(void) ++{ ++ return ltq_readb(<q_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(<q_serial_drv); ++} ++ ++__weak struct serial_device *default_serial_console(void) ++{ ++ return <q_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 <q_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; ++} +--- /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" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.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 */ +--- /dev/null ++++ b/include/configs/easy80920.h +@@ -0,0 +1,92 @@ ++/* ++ * 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_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) ++#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" ++ ++/* Commands */ ++#define CONFIG_CMD_PING ++ ++/* Pull in default board configs for Lantiq XWAY VRX200 */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.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_EXTRA_ENV_SETTINGS \ ++ CONFIG_ENV_LANTIQ_DEFAULTS \ ++ CONFIG_ENV_UPDATE_UBOOT_NOR \ ++ CONFIG_ENV_UPDATE_UBOOT_SF ++ ++#endif /* __CONFIG_H */ +--- 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..acda83c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0015-MIPS-lantiq-add-support-for-Lantiq-XWAY-ARX100-SoC-f.patch @@ -0,0 +1,1228 @@ +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(<q_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(<q_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(<q_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(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE | ++ EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE | ++ EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN); ++ ++ ltq_writel(<q_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(<q_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(<q_pmu_regs->pwdcr, val); ++ ++ timebase = get_timer(0); ++ ++ do { ++ sr = ltq_readl(<q_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(<q_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(<q_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(<q_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(<q_rcu_regs->req, val); ++ ++ return 0; ++} ++ ++enum ltq_boot_select ltq_boot_select(void) ++{ ++ u32 stat; ++ unsigned int bootstrap; ++ ++ stat = ltq_readl(<q_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,175 @@ ++/* ++ * 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_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..471c902 --- /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; ++ loff_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, loff_t offset) + { +- int out_fd, uboot_fd, spl_fd, ret; ++ loff_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..6c9f14b --- /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 +@@ -164,7 +164,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-easy80920-add-support-for-NAND-SPL.patch b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch new file mode 100644 index 0000000..8e1d5bd --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0022-MIPS-lantiq-easy80920-add-support-for-NAND-SPL.patch @@ -0,0 +1,61 @@ +From 6fa1c350fa19a054371eccef84e4885cfdd6a2d7 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Mon, 19 Aug 2013 18:11:31 +0200 +Subject: MIPS: lantiq: easy80920: add support for NAND SPL + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/boards.cfg ++++ b/boards.cfg +@@ -509,6 +509,7 @@ 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> +--- a/include/configs/easy80920.h ++++ b/include/configs/easy80920.h +@@ -31,6 +31,14 @@ + + #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 + +@@ -57,6 +65,11 @@ + #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 +@@ -84,9 +97,13 @@ + #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_SF \ ++ CONFIG_ENV_UPDATE_UBOOT_NAND + + #endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch b/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch new file mode 100644 index 0000000..3b50c98 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0023-MIPS-lantiq-add-default-openwrt-config.patch @@ -0,0 +1,50 @@ +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,39 @@ ++/* ++ * 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 ++#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/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch b/package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch new file mode 100644 index 0000000..5afe427 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0024-MIPS-lantiq-easy50712-add-openwrt-lantiq-common.h.patch @@ -0,0 +1,26 @@ +From ac6896098d9dd62a248340e6a090574399e1fd87 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Mon, 19 Aug 2013 18:46:47 +0200 +Subject: MIPS: lantiq: easy50712: add openwrt-lantiq-common.h + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/include/configs/easy50712.h ++++ b/include/configs/easy50712.h +@@ -62,13 +62,13 @@ + #define CONFIG_CONSOLE_ASC 1 + #define CONFIG_CONSOLE_DEV "ttyLTQ1" + +-/* Commands */ +-#define CONFIG_CMD_PING +- + /* 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" + diff --git a/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch b/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch new file mode 100644 index 0000000..2f9fd59 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0025-MIPS-lantiq-easy80920-add-openwrt-lantiq-common.h.patch @@ -0,0 +1,26 @@ +From 7afbe4633773905ef94a8404510fb5a459926000 Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Mon, 19 Aug 2013 18:11:57 +0200 +Subject: MIPS: lantiq: easy80920: add openwrt-lantiq-common.h + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- a/include/configs/easy80920.h ++++ b/include/configs/easy80920.h +@@ -84,13 +84,13 @@ + #define CONFIG_CONSOLE_ASC 1 + #define CONFIG_CONSOLE_DEV "ttyLTQ1" + +-/* Commands */ +-#define CONFIG_CMD_PING +- + /* 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" + diff --git a/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch new file mode 100644 index 0000000..51738e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0026-MIPS-add-board-support-for-Arcadyan-ARV4519.patch @@ -0,0 +1,242 @@ +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(ð_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,67 @@ ++/* ++ * 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 */ ++ ++/* 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/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch new file mode 100644 index 0000000..21e6a2c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0027-MIPS-add-board-support-for-Arcadyan-ARV7518.patch @@ -0,0 +1,242 @@ +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(ð_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,67 @@ ++/* ++ * 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 */ ++ ++/* 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/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch new file mode 100644 index 0000000..00820f8 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0028-MIPS-add-board-support-for-AudioCodes-MP-252.patch @@ -0,0 +1,248 @@ +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(ð_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,60 @@ ++/* ++ * 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 */ ++ ++/* 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/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch b/package/boot/uboot-lantiq/patches/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch new file mode 100644 index 0000000..77014e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0029-MIPS-add-board-support-for-AVM-FritzBox-3370.patch @@ -0,0 +1,354 @@ +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(ð_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,78 @@ ++/* ++ * 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 ++ ++/* 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/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch b/package/boot/uboot-lantiq/patches/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch new file mode 100644 index 0000000..96737fa --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0030-MIPS-add-board-support-for-Gigaset-SX76X.patch @@ -0,0 +1,247 @@ +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(ð_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,59 @@ ++/* ++ * 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 */ ++ ++/* 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/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch b/package/boot/uboot-lantiq/patches/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch new file mode 100644 index 0000000..ba63b2c --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0031-MIPS-add-board-support-for-ZTE-ZXHN-H367N.patch @@ -0,0 +1,307 @@ +From 0597056e2ba19ea783ef5c3d14c75c4722740e48 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Sun, 10 Mar 2013 17:59:56 +0100 +Subject: MIPS: add board support for ZTE ZXHN H367N + +Signed-off-by: Luka Perkov <luka@openwrt.org> + +--- /dev/null ++++ b/board/zte/zxhnh367n/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/zte/zxhnh367n/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/zte/zxhnh367n/ddr_settings.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org> ++ * ++ * The values have been extracted from original ZTE U-Boot. ++ * ++ * 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 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 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/zte/zxhnh367n/zxhnh367n.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 WANoE port */ ++ { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII }, ++ /* GMAC1: unused */ ++ { 1, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE }, ++ /* GMAC2: internal GPHY0 with 10/100 firmware for LAN port 1 */ ++ { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC3: internal GPHY0 with 10/100 firmware for LAN port 2 */ ++ { 3, 0x12, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC4: internal GPHY1 with 10/100 firmware for LAN port 3 */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_MII }, ++ /* GMAC5: internal GPHY1 with 10/100 firmware for LAN port 4 */ ++ { 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; ++ ++ 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(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -527,6 +527,9 @@ 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 zte zxhnh367n zxhnh367n_nandspl zxhnh367n:SYS_BOOT_NANDSPL Luka Perkov <luka@openwrt.org> ++Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_ram zxhnh367n:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> ++Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_zte zxhnh367n:SYS_BOOT_ZTE 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/zxhnh367n.h +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013 Luka Perkov <luka@openwrt.org> ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ZXHN H367N" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZTE ZXHN H367N" ++ ++/* 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 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 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_SYS_DRAM_PROBE ++ ++/* 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 (256 * 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_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#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_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/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch b/package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch new file mode 100644 index 0000000..eb77f96 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0032-MIPS-add-board-support-for-ZTE-ZXV10-H201L.patch @@ -0,0 +1,251 @@ +From 2473526cf879ead429c6aa1fb7fb77ed3407baaa Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Sun, 9 Dec 2012 17:35:09 +0100 +Subject: MIPS: add board support for ZTE ZXV10 H201L + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/zte/zxv10h201l/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/zte/zxv10h201l/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/zte/zxv10h201l/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * The values have been extracted from original ZTE U-Boot. ++ * ++ * 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 0x307 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x103 ++#define MC_DC09_VALUE 0x80B ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xE02 ++#define MC_DC12_VALUE 0x2C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x100 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xF ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1600 ++#define MC_DC22_VALUE 0x1616 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5D ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x5FB ++#define MC_DC29_VALUE 0x35DF ++#define MC_DC30_VALUE 0x99E9 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zte/zxv10h201l/zxv10h201l.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2012 Daniel Schwierzeck, daniel.schwierzeck@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) ++{ ++ 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(ð_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); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -496,6 +496,9 @@ Active mips mips32 - + Active mips mips32 - micronas vct vct_premium_onenand vct:VCT_PREMIUM,VCT_ONENAND - + Active mips mips32 - micronas vct vct_premium_onenand_small vct:VCT_PREMIUM,VCT_ONENAND,VCT_SMALL_IMAGE - + Active mips mips32 - micronas vct vct_premium_small vct:VCT_PREMIUM,VCT_SMALL_IMAGE - ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov <luka@openwrt.org> + Active mips mips32 au1x00 - dbau1x00 dbau1000 dbau1x00:DBAU1000 Thomas Lange <thomas@corelatus.se> + Active mips mips32 au1x00 - dbau1x00 dbau1100 dbau1x00:DBAU1100 Thomas Lange <thomas@corelatus.se> + Active mips mips32 au1x00 - dbau1x00 dbau1500 dbau1x00:DBAU1500 Thomas Lange <thomas@corelatus.se> +--- /dev/null ++++ b/include/configs/zxv10h201l.h +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (C) 2011 Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "ZXV10 H201L" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZTE ZXV10 H201L" ++ ++/* 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_SPL_NOR_FLASH /* Build NOR flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++/* 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 (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 ++ ++#if defined(CONFIG_SYS_BOOT_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#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 Danube */ ++#include <asm/lantiq/config.h> ++#include <asm/arch/config.h> ++ ++#if defined(CONFIG_SYS_BOOT_ZTE) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#endif ++ ++/* 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/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch b/package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch new file mode 100644 index 0000000..38d7856 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0033-MIPS-add-board-support-for-ZyXEL-P-661HNU-Fx.patch @@ -0,0 +1,304 @@ +From a18f994f373db4467a4680f83ead997c8122908e Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Wed, 22 May 2013 17:48:08 +0200 +Subject: MIPS: add board support for ZyXEL P-661HNU-Fx + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/zyxel/p661hnufx/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/p661hnufx/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/p661hnufx/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * The values have been extracted from original ZyXEL U-Boot. ++ * ++ * 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 0x307 ++#define MC_DC07_VALUE 0x303 ++#define MC_DC08_VALUE 0x103 ++#define MC_DC09_VALUE 0x80B ++#define MC_DC10_VALUE 0x203 ++#define MC_DC11_VALUE 0xE02 ++#define MC_DC12_VALUE 0x2C8 ++#define MC_DC13_VALUE 0x1 ++#define MC_DC14_VALUE 0x0 ++#define MC_DC15_VALUE 0x100 ++#define MC_DC16_VALUE 0xC800 ++#define MC_DC17_VALUE 0xF ++#define MC_DC18_VALUE 0x301 ++#define MC_DC19_VALUE 0x200 ++#define MC_DC20_VALUE 0xA04 ++#define MC_DC21_VALUE 0x1600 ++#define MC_DC22_VALUE 0x1616 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x5D ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x5FB ++#define MC_DC29_VALUE 0x35DF ++#define MC_DC30_VALUE 0x99E9 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zyxel/p661hnufx/p661hnufx.c +@@ -0,0 +1,102 @@ ++/* ++ * Copyright (C) 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 0.4 to serial flash */ ++ gpio_direction_output(10, 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: Lantiq Tantos switch */ ++ { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII }, ++ /* MAC1: unused */ ++ { 1, 0x0, LTQ_ETH_PORT_NONE, 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(ð_board_config); ++} ++ ++static struct switch_device psb697x_dev = { ++ .name = "psb697x", ++ .cpu_port = 5, ++ .port_mask = 0xF, ++}; ++ ++int board_switch_init(void) ++{ ++ printf("%s\n", __func__); ++ ++#if 0 ++ ltq_reset_once(LTQ_RESET_HARD, 200000); ++ __udelay(50000); ++#endif ++ ++ return switch_device_register(&psb697x_dev); ++} ++ ++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 +@@ -499,6 +499,9 @@ Active mips mips32 - + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_ram p661hnufx:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_sfspl p661hnufx:SYS_BOOT_SFSPL Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p661hnufx p661hnufx_zyxel p661hnufx:SYS_BOOT_ZYXEL Luka Perkov <luka@openwrt.org> + Active mips mips32 au1x00 - dbau1x00 dbau1000 dbau1x00:DBAU1000 Thomas Lange <thomas@corelatus.se> + Active mips mips32 au1x00 - dbau1x00 dbau1100 dbau1x00:DBAU1100 Thomas Lange <thomas@corelatus.se> + Active mips mips32 au1x00 - dbau1x00 dbau1500 dbau1x00:DBAU1500 Thomas Lange <thomas@corelatus.se> +--- /dev/null ++++ b/include/configs/p661hnufx.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "P-661HNU-Fx" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZyXEL P-661HNU-Fx" ++ ++/* 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 /* Supports Macronix serial flash */ ++#define CONFIG_SPI_FLASH_4BYTE_MODE ++ ++#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 ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_PSB697X ++ ++/* 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 (512 * 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 ++ ++#if defined(CONFIG_SYS_BOOT_ZYXEL) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#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 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_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/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch b/package/boot/uboot-lantiq/patches/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch new file mode 100644 index 0000000..2cf66e4 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0034-MIPS-add-board-support-for-ZyXEL-P-2601HN-Fx.patch @@ -0,0 +1,242 @@ +From 4bfa74583bc938d2da41f255f22baa1845332893 Mon Sep 17 00:00:00 2001 +From: Luka Perkov <luka@openwrt.org> +Date: Tue, 12 Mar 2013 01:42:46 +0100 +Subject: MIPS: add board support for ZyXEL P-2601HN-Fx + +Signed-off-by: Luka Perkov <luka@openwrt.org> + +--- /dev/null ++++ b/board/zyxel/p2601hnfx/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/p2601hnfx/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/p2601hnfx/ddr_settings.h +@@ -0,0 +1,55 @@ ++/* ++ * 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_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 0x306 ++#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 0x144 ++#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 0x1900 ++#define MC_DC22_VALUE 0x1919 ++#define MC_DC23_VALUE 0x0 ++#define MC_DC24_VALUE 0x66 ++#define MC_DC25_VALUE 0x0 ++#define MC_DC26_VALUE 0x0 ++#define MC_DC27_VALUE 0x0 ++#define MC_DC28_VALUE 0x50A ++#define MC_DC29_VALUE 0x2D65 ++#define MC_DC30_VALUE 0x81B1 ++#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 0x600 ++#define MC_DC46_VALUE 0x0 +--- /dev/null ++++ b/board/zyxel/p2601hnfx/p2601hnfx.c +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2013 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: 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(ð_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); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -499,6 +499,10 @@ Active mips mips32 - + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_nor zxv10h201l:SYS_BOOT_NOR Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_ram zxv10h201l:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zte zxv10h201l zxv10h201l_zte zxv10h201l:SYS_BOOT_ZTE Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_nor p2601hnfx:SYS_BOOT_NOR Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_norspl p2601hnfx:SYS_BOOT_NORSPL Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_ram p2601hnfx:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> ++Active mips mips32 arx100 zyxel p2601hnfx p2601hnfx_zyxel p2601hnfx:SYS_BOOT_ZYXEL Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_ram p661hnufx:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_sfspl p661hnufx:SYS_BOOT_SFSPL Luka Perkov <luka@openwrt.org> + Active mips mips32 arx100 zyxel p661hnufx p661hnufx_zyxel p661hnufx:SYS_BOOT_ZYXEL Luka Perkov <luka@openwrt.org> +--- /dev/null ++++ b/include/configs/p2601hnfx.h +@@ -0,0 +1,67 @@ ++/* ++ * 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-2601HN-Fx" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "ZyXEL P-2601HN-Fx" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_NOR_FLASH /* Have a parallel NOR flash */ ++ ++#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++#define CONFIG_LTQ_SPL_COMP_LZO /* Compress SPL with LZO */ ++#define CONFIG_LTQ_SPL_CONSOLE /* Enable SPL console */ ++ ++/* 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) ++#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 (128 * 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_ZYXEL) ++#define CONFIG_SYS_TEXT_BASE 0x80800000 ++#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 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 \ ++ "kernel_addr=0xB0040000\0" ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch b/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch new file mode 100644 index 0000000..3a0d8a6 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0035-MIPS-add-board-support-for-ZyXEL-P-2812HNU-Fx.patch @@ -0,0 +1,301 @@ +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(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -540,6 +540,8 @@ Active mips mips32 vrx20 + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_nandspl zxhnh367n:SYS_BOOT_NANDSPL Luka Perkov <luka@openwrt.org> + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_ram zxhnh367n:SYS_BOOT_RAM Luka Perkov <luka@openwrt.org> + Active mips mips32 vrx200 zte zxhnh367n zxhnh367n_zte zxhnh367n:SYS_BOOT_ZTE Luka Perkov <luka@openwrt.org> ++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,67 @@ ++/* ++ * 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 ++ ++/* 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/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch b/package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch new file mode 100644 index 0000000..a9cc6d9 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0036-MIPS-add-board-support-for-Arcadyan-Easybox-904.patch @@ -0,0 +1,277 @@ +From 60856fa8f9866f292df740ea98752a70738eb59a Mon Sep 17 00:00:00 2001 +From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +Date: Fri, 9 Aug 2013 18:11:07 +0200 +Subject: MIPS: add board support for Arcadyan Easybox 904 + +Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> + +--- /dev/null ++++ b/board/arcadyan/easybox904/Makefile +@@ -0,0 +1,27 @@ ++# ++# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.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/arcadyan/easybox904/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/easybox904/ddr_settings.h +@@ -0,0 +1,68 @@ ++/* ++ * 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 0x1000000 ++#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 0x4401503 ++#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 0x1536B0 ++#define MC_CCR36_VALUE 0xC8 ++#define MC_CCR37_VALUE 0xC351 ++#define MC_CCR38_VALUE 0x0 ++#define MC_CCR39_VALUE 0x142404 ++#define MC_CCR40_VALUE 0x142604 ++#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 0x7C00301 ++#define MC_CCR58_VALUE 0x7C00301 ++#define MC_CCR59_VALUE 0x7C00301 ++#define MC_CCR60_VALUE 0x7C00301 ++#define MC_CCR61_VALUE 0x4 +--- /dev/null ++++ b/board/arcadyan/easybox904/easybox904.c +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (C) 2012-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 ++#else ++#define do_gpio_init 0 ++#define do_pll_init 0 ++#define do_dcdc_init 1 ++#endif ++ ++static inline 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: ??? */ ++ { 0, 0x0, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC1: ??? */ ++ { 1, 0x1, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC2: ??? */ ++ { 2, 0x11, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC3: unused */ ++ { 3, 0x0, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_NONE }, ++ /* GMAC4: internal GPHY1 with 10/100/1000 firmware for WANoE port */ ++ { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII }, ++ /* GMAC5: ??? */ ++ { 5, 0x5, LTQ_ETH_PORT_NONE, LTQ_ETH_PORT_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) ++{ ++ const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0; ++ const ulong fw_ge_addr = 0x80FE0000; ++ ++ ltq_gphy_phy11g_a2x_load(fw_ge_addr); ++ ++ ltq_cgu_gphy_clk_src(clk); ++ ++ ltq_rcu_gphy_boot(0, fw_ge_addr); ++ ltq_rcu_gphy_boot(1, fw_ge_addr); ++ ++ return ltq_eth_initialize(ð_board_config); ++} +--- a/boards.cfg ++++ b/boards.cfg +@@ -529,6 +529,7 @@ 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 easybox904 easybox904_ram easybox904:SYS_BOOT_RAM Daniel Schwierzeck <daniel.schwierzeck@gmail.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/easybox904.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++#define CONFIG_MACH_TYPE "EASYBOX904" ++#define CONFIG_IDENT_STRING " "CONFIG_MACH_TYPE ++#define CONFIG_BOARD_NAME "Arcadyan EasyBox 904" ++ ++/* Configure SoC */ ++#define CONFIG_LTQ_SUPPORT_UART /* Enable ASC and UART */ ++ ++#define CONFIG_LTQ_SUPPORT_ETHERNET /* Enable ethernet */ ++ ++#define CONFIG_LTQ_SUPPORT_NAND_FLASH ++ ++#define CONFIG_SYS_DRAM_PROBE ++ ++/* Environment */ ++#define CONFIG_ENV_IS_NOWHERE ++ ++#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 ++ ++#endif /* __CONFIG_H */ diff --git a/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch b/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch new file mode 100644 index 0000000..676ef12 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0037-MIPS-add-board-support-for-Arcadyan-ARV752DPW.patch @@ -0,0 +1,242 @@ +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(ð_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 +@@ -518,6 +518,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,67 @@ ++/* ++ * 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 */ ++ ++/* Switch devices */ ++#define CONFIG_SWITCH_MULTI ++#define CONFIG_SWITCH_RTL8206 ++ ++/* 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/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch b/package/boot/uboot-lantiq/patches/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch new file mode 100644 index 0000000..2cf0e95 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0038-MIPS-add-board-support-for-Arcadyan-ARV752DPW22.patch @@ -0,0 +1,244 @@ +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(ð_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 +@@ -521,6 +521,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,68 @@ ++/* ++ * 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 */ ++ ++/* 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/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch b/package/boot/uboot-lantiq/patches/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch new file mode 100644 index 0000000..76f8955 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0039-MIPS-add-board-support-for-Arcadyan-ARV7510.patch @@ -0,0 +1,269 @@ +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(ð_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 +@@ -515,6 +515,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,75 @@ ++/* ++ * 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 */ ++ ++/* 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/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch b/package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch new file mode 100644 index 0000000..f866921 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-MIPS-add-board-support-for-Arcadyan-ARV7510PW22.patch @@ -0,0 +1,238 @@ +--- /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(ð_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 +@@ -518,6 +518,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,67 @@ ++/* ++ * 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 */ ++ ++/* 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/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch b/package/boot/uboot-lantiq/patches/0041-Makefile-prepare-u-boot-lantiq-v2013.10-openwrt4.patch new file mode 100644 index 0000000..1f89e54 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-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/0041-lzma-fixup.patch b/package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch new file mode 100644 index 0000000..5b16758 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0041-lzma-fixup.patch @@ -0,0 +1,44 @@ +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(-) + +diff --git a/lib/lzma/LzmaTools.c b/lib/lzma/LzmaTools.c +index 0aec2f9..90d31cd 100644 +--- a/lib/lzma/LzmaTools.c ++++ b/lib/lzma/LzmaTools.c +@@ -102,7 +102,7 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, + return SZ_ERROR_OUTPUT_EOF; + + /* Decompress */ +- outProcessed = *uncompressedSize; ++ outProcessed = outSizeFull; + + WATCHDOG_RESET(); + +@@ -111,6 +111,9 @@ int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize, + 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; + } +-- +1.8.3.2 + diff --git a/package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch b/package/boot/uboot-lantiq/patches/0042-arx100-cgu-fixes.patch new file mode 100644 index 0000000..8ca6a1e --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0042-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 2015-01-20 11:57:22.000000000 +0100 ++++ b/arch/mips/cpu/mips32/arx100/cgu.c 2015-01-20 12:00:15.000000000 +0100 +@@ -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/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch b/package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch new file mode 100644 index 0000000..adb894f --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0043-MIPS-add-board-support-for-Arcadyan-VGV7510KW22.patch @@ -0,0 +1,346 @@ +--- /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,136 @@ ++/* ++ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@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 ++ ++#define GPIO_POWER_GREEN 14 ++ ++static void gpio_init(void) ++{ ++ /* SPI CS 0.4 to serial flash */ ++ gpio_direction_output(10, 1); ++ ++ /* Turn on the green power LED */ ++ gpio_direction_output(GPIO_POWER_GREEN, 0); ++ gpio_set_value(GPIO_POWER_GREEN, 0); ++} ++ ++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[] = { ++ /* 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(ð_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; ++ } ++} +--- /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> ++ * Based on code by: ++ * Daniel Schwierzeck, daniel.schwierzeck@googlemail.com ++ * and Lantiq Deutschland GmbH ++ * ++ * 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 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 +@@ -542,6 +542,9 @@ + 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 easybox904 easybox904_ram easybox904:SYS_BOOT_RAM Daniel Schwierzeck <daniel.schwierzeck@gmail.com> ++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,78 @@ ++/* ++ * 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_LTQ_SUPPORT_SPI_FLASH ++#define CONFIG_SPI_FLASH_MACRONIX /* Have a MX29GL128EL parallel 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_LTQ_SUPPORT_SPL_NOR_FLASH /* Build NOR flash SPL */ ++ ++#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_BRN) ++#define CONFIG_SYS_TEXT_BASE 0x80002000 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++#define CONFIG_SYS_DISABLE_CACHE ++#define CONFIG_ENV_IS_NOWHERE ++#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/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch b/package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch new file mode 100644 index 0000000..5cc71b6 --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0044-MIPS-add-board-support-for-Arcadyan-ARV8539PW22.patch @@ -0,0 +1,240 @@ +--- /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(ð_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 +@@ -553,6 +553,9 @@ Active mips mips32 danube arcadyan arv752dpw + 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,68 @@ ++/* ++ * 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 */ ++ ++/* 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 */ + |