Update u-boot from SPF11.1.CSU1 to SPF11.4.CS
Fixes up all the rejects:
./arch/arm/dts/Makefile
Caused by an endif added by us to support booting with a single
DTS.
./board/qca/arm/common/board_init.c
./board/qca/arm/common/cmd_bootqca.c
./board/qca/arm/common/fdt_fixup.c
Caused by fixups added by us.
./drivers/net/ipq807x/ipq807x_uniphy.c
Qcom a typo
if (condition);
We fixed it by removing the semicolon
They fixed it by removing the if and it's body
Took their version
./include/configs/ipq807x.h
CONFIG_SILENT_CONSOLE is conditionally set by us, so ignoring
this change.
./lib/fdtdec.c
Qcom added support for compressed DTBS if CONFIG_OF_COMBINE is
defined. We've removed this support previously, so dropping the whole
change.
Change-Id: I2c2a834e81dfc0cd0f2157ef105ee55fe2abdee0
diff --git a/Kconfig b/Kconfig
index 00d5217..55b6d37 100644
--- a/Kconfig
+++ b/Kconfig
@@ -104,6 +104,9 @@
config SUPPORT_SPL
bool
+config COMPRESSED_DTB_BASE
+ hex
+
config SUPPORT_TPL
bool
diff --git a/Makefile b/Makefile
index dd3ae42..aa81aad 100644
--- a/Makefile
+++ b/Makefile
@@ -556,6 +556,12 @@
include/config/auto.conf: ;
endif # $(dot-config)
+ifndef DTBLDSCRIPT
+ ifeq ($(wildcard $(DTBLDSCRIPT)),)
+ DTBLDSCRIPT := $(srctree)/arch/$(ARCH)/dts/combined_dtb.lds
+ endif
+endif
+
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
else
@@ -700,6 +706,9 @@
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
+ifneq ($(CONFIG_COMPRESSED_DTB_BASE),)
+compressed_dtb-dirs := arch/$(ARCH)/dts/compressed_dtb
+endif
# Add GCC lib
ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y)
@@ -805,6 +814,17 @@
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
endif
+
+ifneq ($(CONFIG_COMPRESSED_DTB_BASE),)
+LDFLAGS_dtb_combine += $(LDFLAGS_FINAL)
+COMPRESS_DTB_BASE = $(shell printf "0x%x" $$(( $(CONFIG_SYS_TEXT_BASE) - $(CONFIG_COMPRESSED_DTB_MAX_SIZE))))
+LDFLAGS_dtb_combine += -Ttext $(COMPRESS_DTB_BASE)
+
+# Normal objcopy without filter the sections
+quiet_cmd_nobjcopy = OBJCOPY $@
+cmd_nobjcopy = $(OBJCOPY) --gap-fill=0xff -O binary $< $@
+endif
+
# Normally we fill empty space with 0xff
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
@@ -891,6 +911,11 @@
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
$(BOARD_SIZE_CHECK)
+ifneq ($(CONFIG_COMPRESSED_DTB_BASE),)
+dtb_combined.bin: dtb_combined FORCE
+ $(call if_changed,nobjcopy)
+endif
+
quiet_cmd_mkheader = MKHEADER $@
cmd_mkheader = $(PYTHON) tools/mkheader.py $(CONFIG_SYS_TEXT_BASE) $(CONFIG_IPQ_APPSBL_IMG_TYPE) $< $@
@@ -1205,6 +1230,23 @@
--start-group $(u-boot-main) --end-group \
$(PLATFORM_LIBS) -Map u-boot.map
+ifneq ($(CONFIG_COMPRESSED_DTB_BASE),)
+# Rule to link combined_dtb.lds
+quiet_cmd_dtb_combined__ ?= LD $@
+ cmd_dtb_combined__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_dtb_combine) -o dtb_combined \
+ -T combined_dtb.lds $(u-boot-init) \
+ --start-group arch/$(ARCH)/dts/built-in.o --end-group \
+ $(PLATFORM_LIBS) -Map dtb_combined.map
+
+combine_dtb_Linker: combined_dtb.lds
+ $(call if_changed,dtb_combined__)
+
+compress_dtb: combine_dtb_Linker dtb_combined.bin $(compressed_dtb-dirs)
+ cp arch/$(ARCH)/dts/compressed_dtb/dtbcombined.o arch/$(ARCH)/dts/built-in.o
+else
+compress_dtb:
+endif
+
quiet_cmd_smap = GEN common/system_map.o
cmd_smap = \
smap=`$(call SYSTEM_MAP,u-boot) | \
@@ -1212,7 +1254,7 @@
$(CC) $(c_flags) -DSYSTEM_MAP="\"$${smap}\"" \
-c $(srctree)/common/system_map.c -o common/system_map.o
-u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds
+u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds compress_dtb
$(call if_changed,u-boot__)
ifeq ($(CONFIG_KALLSYMS),y)
$(call cmd,smap)
@@ -1229,10 +1271,16 @@
# make menuconfig etc.
# Error messages still appears in the original language
+
PHONY += $(u-boot-dirs)
$(u-boot-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
+ifneq ($(CONFIG_COMPRESSED_DTB_BASE),)
+$(compressed_dtb-dirs): prepare scripts
+ $(Q)$(MAKE) $(build)=$@
+endif
+
tools: prepare
# The "tools" are needed early
$(filter-out tools, $(u-boot-dirs)): tools
@@ -1347,6 +1395,13 @@
u-boot.lds: $(LDSCRIPT) prepare FORCE
$(call if_changed_dep,cpp_lds)
+quiet_cmd_cpp_dtb_lds = LDS $@
+cmd_cpp_dtb_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
+ -D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $<
+
+combined_dtb.lds: $(DTBLDSCRIPT) prepare FORCE
+ $(call if_changed_dep,cpp_dtb_lds)
+
spl/u-boot-spl.bin: spl/u-boot-spl
@:
spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 20956d9..6efc192 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -883,6 +883,7 @@
source "board/hisilicon/hikey/Kconfig"
source "board/imx31_phycore/Kconfig"
source "board/ipq40xx/Kconfig"
+source "board/ipq5018/Kconfig"
source "board/ipq6018/Kconfig"
source "board/ipq806x/Kconfig"
source "board/ipq807x/Kconfig"
diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c
index de2472d..5fbe668 100644
--- a/arch/arm/cpu/armv7/qca/common/scm.c
+++ b/arch/arm/cpu/armv7/qca/common/scm.c
@@ -450,8 +450,12 @@
if (is_scm_armv8())
{
struct qca_scm_desc desc = {0};
-
+#ifdef CONFIG_ARCH_IPQ5018
+ desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP);
+ desc.args[1] = 0x800;
+#else
desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP);
+#endif
desc.args[0] = *((unsigned int *)buf);
ret = scm_call_64(svc_id, cmd_id, &desc);
@@ -546,6 +550,85 @@
return ret;
}
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+int qti_scm_otp(u32 peripheral)
+{
+ int ret;
+
+ if (is_scm_armv8())
+ {
+ struct qca_scm_desc desc = {0};
+
+ desc.arginfo = QCA_SCM_ARGS(1);
+ desc.args[0] = peripheral;
+
+ ret = scm_call_64(SCM_SVC_PIL, SCM_CMD_OTP, &desc);
+ }
+ else
+ {
+ u32 cmd = peripheral;
+
+ ret = scm_call(SCM_SVC_PIL, SCM_CMD_OTP, &cmd, sizeof(cmd),
+ NULL, 0);
+ }
+
+ return ret;
+}
+
+int qti_scm_pas_init_image(u32 peripheral, u32 addr)
+{
+ int ret;
+
+ if (is_scm_armv8())
+ {
+ struct qca_scm_desc desc = {0};
+
+ desc.arginfo = QCA_SCM_ARGS(2, SCM_VAL, SCM_IO_WRITE);
+ desc.args[0] = peripheral;
+ desc.args[1] = addr;
+
+ ret = scm_call_64(SCM_SVC_PIL, SCM_PAS_INIT_IMAGE_CMD, &desc);
+ }
+ else
+ {
+ struct {
+ u32 proc;
+ u32 image_addr;
+ } request;
+ request.proc = peripheral;
+ request.image_addr = addr;
+ ret = scm_call(SCM_SVC_PIL, SCM_PAS_INIT_IMAGE_CMD, &request,
+ sizeof(request), NULL, 0);
+ }
+
+ return ret;
+}
+
+int qti_pas_and_auth_reset(u32 peripheral)
+{
+ int ret;
+ u32 cmd = peripheral;
+
+ if (is_scm_armv8())
+ {
+ struct qca_scm_desc desc = {0};
+
+ desc.arginfo = QCA_SCM_ARGS(1);
+ desc.args[0] = peripheral;
+
+ ret = scm_call_64(SCM_SVC_PIL, SCM_PAS_AUTH_AND_RESET_CMD, &desc);
+ }
+ else
+ {
+ ret = scm_call(SCM_SVC_PIL, SCM_PAS_AUTH_AND_RESET_CMD, &cmd, sizeof(cmd),
+ NULL, 0);
+ }
+
+ return ret;
+}
+#endif
+
#else
int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len)
{
@@ -570,6 +653,19 @@
}
#endif
+int qca_scm_call_crypto_v8(u32 svc_id, u32 cmd_id, u32 *addr, u32 val)
+{
+ int ret = 0;
+ struct qca_scm_desc desc = {0};
+
+ desc.arginfo = QCA_SCM_ARGS(2, SCM_RW_OP, SCM_VAL);
+
+ desc.args[0] = (u32)addr;
+ desc.args[1] = val;
+ ret = scm_call_64(svc_id, cmd_id, &desc);
+ return ret;
+}
+
int qca_scm_call_write(u32 svc_id, u32 cmd_id, u32 *addr, u32 val)
{
int ret = 0;
@@ -623,6 +719,18 @@
return ret;
}
+int qca_scm_crypto(int cmd_id, void *req_ptr, uint32_t req_size)
+{
+ int ret;
+ if (is_scm_armv8())
+ ret = qca_scm_call_crypto_v8(SCM_SVC_CRYPTO, cmd_id,
+ (u32 *)req_ptr, req_size);
+ else
+ ret = -ENOTSUPP;
+
+ return ret;
+}
+
int qca_scm_dload(unsigned int magic_cookie)
{
int ret;
diff --git a/arch/arm/cpu/armv7/qca/common/smem.c b/arch/arm/cpu/armv7/qca/common/smem.c
index 2f00e21..de0dd78 100644
--- a/arch/arm/cpu/armv7/qca/common/smem.c
+++ b/arch/arm/cpu/armv7/qca/common/smem.c
@@ -528,7 +528,7 @@
return 0; /* alt partition not available */
}
-
+#ifdef CONFIG_CMD_NAND
/*
* get nand block size by device id.
* dev_id is 0 for parallel nand.
@@ -542,16 +542,20 @@
return mtd->erasesize;
}
-
+#endif
/*
* get flash block size based on partition name.
*/
static inline uint32_t get_flash_block_size(char *name,
qca_smem_flash_info_t *smem)
{
+#ifdef CONFIG_CMD_NAND
return (get_which_flash_param(name) == 1) ?
get_nand_block_size(is_spi_nand_available())
: smem->flash_block_size;
+#else
+ return smem->flash_block_size;
+#endif
}
#define part_which_flash(p) (((p)->attr & 0xff000000) >> 24)
@@ -559,9 +563,13 @@
static inline uint32_t get_part_block_size(struct smem_ptn *p,
qca_smem_flash_info_t *sfi)
{
+#ifdef CONFIG_CMD_NAND
return (part_which_flash(p) == 1) ?
get_nand_block_size(is_spi_nand_available())
: sfi->flash_block_size;
+#else
+ return sfi->flash_block_size;
+#endif
}
void qca_set_part_entry(char *name, qca_smem_flash_info_t *smem,
@@ -598,6 +606,52 @@
}
/*
+ * smem_getpart_from_offset - retreive partition start and size for given offset
+ * belongs to.
+ * @part_name: offset for which part start and size needed
+ * @start: location where the start offset is to be stored
+ * @size: location where the size is to be stored
+ *
+ * Returns 0 at success or -ENOENT otherwise.
+ */
+int smem_getpart_from_offset(uint32_t offset, uint32_t *start, uint32_t *size)
+{
+ unsigned i;
+ qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
+ struct smem_ptn *p;
+ uint32_t bsize;
+
+ for (i = 0; i < smem_ptable.len; i++) {
+ p = &smem_ptable.parts[i];
+ *start = p->start;
+ bsize = get_part_block_size(p, sfi);
+
+ if (p->size == (~0u)) {
+ /*
+ * Partition size is 'till end of device', calculate
+ * appropriately
+ */
+#ifdef CONFIG_CMD_NAND
+ *size = (nand_info[get_device_id_by_part(p)].size /
+ bsize) - p->start;
+#else
+ *size = 0;
+ bsize = bsize;
+#endif
+ } else {
+ *size = p->size;
+ }
+ *start = *start * bsize;
+ *size = *size * bsize;
+ if (*start <= offset && *start + *size > offset) {
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+
+}
+/*
* smem_getpart - retreive partition start and size
* @part_name: partition name
* @start: location where the start offset is to be stored
@@ -631,8 +685,13 @@
* Partition size is 'till end of device', calculate
* appropriately
*/
+#ifdef CONFIG_CMD_NAND
*size = (nand_info[get_device_id_by_part(p)].size /
bsize) - p->start;
+#else
+ *size = 0;
+ bsize = bsize;
+#endif
} else {
*size = p->size;
}
@@ -905,8 +964,12 @@
* Partition size is 'till end of device', calculate
* appropriately
*/
+#ifdef CONFIG_CMD_NAND
psize = (nand_info[get_device_id_by_part(p)].size
- (((loff_t)p->start) * bsize));
+#else
+ psize = 0;
+#endif
} else {
psize = ((loff_t)p->size) * bsize;
}
@@ -977,8 +1040,12 @@
* Partition size is 'till end of device', calculate
* appropriately
*/
+#ifdef CONFIG_CMD_NAND
psize = nand_info[get_device_id_by_part(p)].size
- (((loff_t)p->start) * bsize);
+#else
+ psize = 0;
+#endif
} else {
psize = ((loff_t)p->size) * bsize;
}
@@ -1226,8 +1293,12 @@
* Partition size is 'till end of device', calculate
* appropriately
*/
+#ifdef CONFIG_CMD_NAND
psize = nand_info[get_device_id_by_part(p)].size
- (((loff_t)p->start) * bsize);
+#else
+ psize = 0;
+#endif
} else {
psize = ((loff_t)p->size) * bsize;
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 675577c..83f6665 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -36,18 +36,17 @@
ipq807x-hk08.dtb \
ipq807x-hk09.dtb \
ipq807x-hk10.dtb \
+ ipq807x-hk14.dtb \
ipq807x-hk11-c1.dtb \
ipq807x-ac01.dtb \
- ipq807x-ac02.dtb \
ipq807x-ac03.dtb \
ipq807x-ac04.dtb \
ipq807x-oak02.dtb \
- ipq807x-oak03.dtb \
ipq807x-hk01-c2.dtb \
- ipq807x-hk01-c3.dtb \
ipq807x-hk01-c4.dtb \
ipq807x-hk01-c5.dtb \
- ipq807x-hk10-c2.dtb
+ ipq807x-hk10-c2.dtb \
+ ipq807x-db-hk02.dtb
endif
dtb-$(CONFIG_ARCH_IPQ806x) += ipq806x-ap148.dtb \
ipq806x-ap160.dtb \
@@ -71,10 +70,35 @@
ipq40xx-dk01-s1.dtb \
ipq40xx-dk06-c1.dtb
-dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb
+ifneq ($(CONFIG_IPQ_TINY),y)
+dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb \
+ ipq5018-mp02.1.dtb \
+ ipq5018-mp03.1-c2.dtb \
+ ipq5018-mp03.1-c3.dtb \
+ ipq5018-mp03.3.dtb \
+ ipq5018-mp03.3-c2.dtb \
+ ipq5018-mp03.3-c3.dtb \
+ ipq5018-mp03.4-c1.dtb \
+ ipq5018-mp03.4-c2.dtb \
+ ipq5018-mp03.6-c1.dtb \
+ ipq5018-mp03.6-c2.dtb \
+ ipq5018-mp03.5-c1.dtb \
+ ipq5018-mp03.5-c2.dtb \
+ ipq5018-db-mp02.1.dtb \
+ ipq5018-db-mp03.1.dtb \
+ ipq5018-db-mp03.1-c2.dtb \
+ ipq5018-db-mp03.3.dtb \
+ ipq5018-db-mp03.3-c2.dtb \
+ ipq5018-tb-mp04.dtb \
+ ipq5018-mp03.1.dtb
+else
+dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-db-mp02.1.dtb \
+ ipq5018-mp02.1.dtb \
+ ipq5018-mp03.1.dtb \
+ ipq5018-db-mp03.1.dtb
+endif
dtb-$(CONFIG_ARCH_IPQ6018) += ipq6018-cp01-c1.dtb \
- ipq6018-cp01-c3.dtb \
ipq6018-cp02-c1.dtb \
ipq6018-cp03-c1.dtb \
ipq6018-db-cp01.dtb \
diff --git a/arch/arm/dts/compressed_dtb/Makefile b/arch/arm/dts/compressed_dtb/Makefile
new file mode 100644
index 0000000..6bbae06
--- /dev/null
+++ b/arch/arm/dts/compressed_dtb/Makefile
@@ -0,0 +1,13 @@
+$(obj)/dtbcombined.S: $(obj)/../../../../dtb_combined.bin
+ gzip -k --best $(obj)/../../../../dtb_combined.bin
+ echo ".section .dtb.combine_blob,\"a\"" > $(obj)/dtbcombined.S
+ echo '.balign 16' >> $(obj)/dtbcombined.S
+ echo ".global __dtb_blob_begin" >> $(obj)/dtbcombined.S
+ echo "__dtb_blob_begin:" >> $(obj)/dtbcombined.S
+ echo '.incbin "$(obj)/../../../../dtb_combined.bin.gz"' >> $(obj)/dtbcombined.S
+ echo '.balign 16' >> $(obj)/dtbcombined.S
+ echo ".global __dtb_blob_end" >> $(obj)/dtbcombined.S
+ echo "__dtb_blob_end:" >> $(obj)/dtbcombined.S
+ echo ".word 0" >> $(obj)/dtbcombined.S
+
+obj-y := dtbcombined.o
diff --git a/arch/arm/dts/ipq5018-db-mp02.1.dts b/arch/arm/dts/ipq5018-db-mp02.1.dts
new file mode 100644
index 0000000..95f4e6a
--- /dev/null
+++ b/arch/arm/dts/ipq5018-db-mp02.1.dts
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018/DB-MP02.1";
+ compatible = "qca,ipq5018", "qca,ipq5018-db-mp02.1";
+ machid = <0x1040003>;
+ config_name = "config@db-mp02.1";
+
+ aliases {
+ console = "/serial@78AF000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_mux_uart_rx {
+ gpio = <20>;
+ func = <0>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_mux_uart_tx {
+ gpio = <21>;
+ func = <0>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_rx {
+ gpio = <28>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <29>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <30>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <4>;
+ 8033_gpio = <26>;
+ };
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-db-mp03.1-c2.dts b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts
new file mode 100644
index 0000000..88bfab0
--- /dev/null
+++ b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-db-mp03.1.dts"
+/ {
+ model ="QCA, IPQ5018/DB-MP03.1-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.1-c2";
+ machid = <0x1040104>;
+ config_name = "config@db-mp03.1-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-db-mp03.1.dts b/arch/arm/dts/ipq5018-db-mp03.1.dts
new file mode 100644
index 0000000..aa2c3e9
--- /dev/null
+++ b/arch/arm/dts/ipq5018-db-mp03.1.dts
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018/DB-MP03.1";
+ compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.1";
+ machid = <0x1040004>;
+ config_name = "config@db-mp03.1";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b7000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_clk {
+ gpio = <9>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ ssphy = <1>;
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ mac_pwr = <0xaa545>;
+ s17c_switch_enable = <1>;
+ switch_port_count = <4>;
+ switch_phy_address = <0 1 2 3>;
+ switch_gpio = <39>;
+ };
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-db-mp03.3-c2.dts b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts
new file mode 100644
index 0000000..db66c53
--- /dev/null
+++ b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-db-mp03.3.dts"
+/ {
+ model ="QCA, IPQ5018/DB-MP03.3-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.3-c2";
+ machid = <0x1040105>;
+ config_name = "config@db-mp03.3-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-db-mp03.3.dts b/arch/arm/dts/ipq5018-db-mp03.3.dts
new file mode 100644
index 0000000..443ebff
--- /dev/null
+++ b/arch/arm/dts/ipq5018-db-mp03.3.dts
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018/DB-MP03.3";
+ compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.3";
+ machid = <0x1040005>;
+ config_name = "config@db-mp03.3";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b6000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@80000000";
+ pci1 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@80000000 {
+ status = "ok";
+ perst_gpio = <18>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ phy_external_link = <0>;
+ mac_pwr = <0xaa545>;
+ s17c_switch_enable = <1>;
+ switch_port_count = <4>;
+ switch_phy_address = <0 1 2 3>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <0x1c>;
+ napa_gpio = <39>;
+ };
+ };
+};
diff --git a/arch/arm/dts/ipq5018-emulation.dts b/arch/arm/dts/ipq5018-emulation.dts
new file mode 100644
index 0000000..b0fe1d4
--- /dev/null
+++ b/arch/arm/dts/ipq5018-emulation.dts
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-EMULATION";
+ compatible = "qca,ipq5018", "qca,ipq5018-emulation";
+ machid = <0x0F040000>;
+ config_name = "config@emulation-c2";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b6000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@80000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ oe = <GPIO_OE_DISABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ oe = <GPIO_OE_DISABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ oe = <GPIO_OE_DISABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ oe = <GPIO_OE_DISABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ oe = <GPIO_OE_DISABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@80000000 {
+ status = "ok";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ timer {
+ gpt_freq_hz = <240000>;
+ };
+
+ gmac_cfg {
+ gmac_count = <2>;
+ ext_mdio_gpio = <1>;
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ phy_interface_mode = <2>;
+ phy_name = "IPQ MDIO0";
+ };
+
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <1>;
+ phy_interface_mode = <2>;
+ phy_name = "IPQ MDIO1";
+ mac_pwr0 = <0x00080000>;
+ mac_pwr1 = <0x00040000>;
+ s17c_switch_enable = <0>;
+ };
+ };
+
+ gmac_gpio{};
+
+ xhci@8a00000 {
+ qcom,emulation = <1>;
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-mp02.1.dts b/arch/arm/dts/ipq5018-mp02.1.dts
new file mode 100644
index 0000000..ff1d553
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp02.1.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-MP02.1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp02.1";
+ machid = <0x8040000>;
+ config_name = "config@mp02.1";
+
+ aliases {
+ console = "/serial@78AF000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_mux_uart_rx {
+ gpio = <20>;
+ func = <0>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_mux_uart_tx {
+ gpio = <21>;
+ func = <0>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_rx {
+ gpio = <28>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <29>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <30>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <4>;
+ 8033_gpio = <26>;
+ };
+ };
+};
diff --git a/arch/arm/dts/ipq5018-mp03.1-c2.dts b/arch/arm/dts/ipq5018-mp03.1-c2.dts
new file mode 100644
index 0000000..b4a5270
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.1-c2.dts
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-mp03.1.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.1-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.1-c2";
+ machid = <0x8040101>;
+ config_name = "config@mp03.1-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-mp03.1-c3.dts b/arch/arm/dts/ipq5018-mp03.1-c3.dts
new file mode 100644
index 0000000..eb2e8ea
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.1-c3.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-mp03.1.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.1-C3";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.1-c3";
+ machid = <0x8040201>;
+ config_name = "config@mp03.1-c3";
+
+ gmac_cfg {
+ gmac2_cfg {
+ /delete-property/s17c_switch_enable;
+ /delete-property/switch_port_count;
+ /delete-property/switch_gpio;
+ /delete-property/mac_pwr;
+ /delete-property/switch_phy_address;
+ phy_address = <0x1c>;
+ napa_gpio = <39>;
+ };
+ };
+};
diff --git a/arch/arm/dts/ipq5018-mp03.1.dts b/arch/arm/dts/ipq5018-mp03.1.dts
new file mode 100644
index 0000000..fe9d12e
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.1.dts
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-MP03.1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.1";
+ machid = <0x8040001>;
+ config_name = "config@mp03.1";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b7000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_clk {
+ gpio = <9>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ ssphy = <1>;
+ usb_pwr_gpio = <24>;
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ mac_pwr = <0xaa545>;
+ s17c_switch_enable = <1>;
+ switch_port_count = <4>;
+ switch_phy_address = <0 1 2 3>;
+ switch_gpio = <39>;
+ };
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-mp03.3-c2.dts b/arch/arm/dts/ipq5018-mp03.3-c2.dts
new file mode 100644
index 0000000..3fc3681
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.3-c2.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "ipq5018-mp03.3.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.3-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.3-c2";
+ machid = <0x8040102>;
+ config_name = "config@mp03.3-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-mp03.3-c3.dts b/arch/arm/dts/ipq5018-mp03.3-c3.dts
new file mode 100644
index 0000000..b360a20
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.3-c3.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "ipq5018-mp03.3.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.3-C3";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.3-c3";
+ machid = <0x8040202>;
+ config_name = "config@mp03.3-c3";
+
+ /delete-node/ pci@a0000000;
+ /delete-node/ xhci@8a00000;
+};
diff --git a/arch/arm/dts/ipq5018-mp03.3.dts b/arch/arm/dts/ipq5018-mp03.3.dts
new file mode 100644
index 0000000..9254919
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.3.dts
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-MP03.3";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.3";
+ machid = <0x8040002>;
+ config_name = "config@mp03.3";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b7000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@80000000";
+ pci1 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_clk {
+ gpio = <9>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@80000000 {
+ status = "ok";
+ perst_gpio = <18>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ usb_pwr_gpio = <24>;
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ phy_external_link = <0>;
+ mac_pwr = <0xaa545>;
+ s17c_switch_enable = <1>;
+ switch_port_count = <4>;
+ switch_phy_address = <0 1 2 3>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <0x1c>;
+ napa_gpio = <39>;
+ };
+
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-mp03.4-c1.dts b/arch/arm/dts/ipq5018-mp03.4-c1.dts
new file mode 100644
index 0000000..a122c46
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.4-c1.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-mp03.3.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.4-C1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.4-c1";
+ machid = <0x8040005>;
+ config_name = "config@mp03.4-c1";
+};
diff --git a/arch/arm/dts/ipq5018-mp03.4-c2.dts b/arch/arm/dts/ipq5018-mp03.4-c2.dts
new file mode 100644
index 0000000..e9e0bc3
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.4-c2.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-mp03.3-c2.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.4-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.4-c2";
+ machid = <0x8040105>;
+ config_name = "config@mp03.4-c2";
+};
diff --git a/arch/arm/dts/ipq5018-mp03.5-c1.dts b/arch/arm/dts/ipq5018-mp03.5-c1.dts
new file mode 100644
index 0000000..45ee452
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.5-c1.dts
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-MP03.5-C1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.5-c1";
+ machid = <0x8040004>;
+ config_name = "config@mp03.5-c1";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b6000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci0 = "/pci@80000000";
+ pci1 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_clk {
+ gpio = <9>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@80000000 {
+ status = "ok";
+ perst_gpio = <18>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ usb_pwr_gpio = <24>;
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <0x1c>;
+ napa_gpio = <39>;
+ };
+
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-mp03.5-c2.dts b/arch/arm/dts/ipq5018-mp03.5-c2.dts
new file mode 100644
index 0000000..d3390fb
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.5-c2.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "ipq5018-mp03.5-c1.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.5-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.5-c2";
+ machid = <0x8040104>;
+ config_name = "config@mp03.5-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-mp03.6-c1.dts b/arch/arm/dts/ipq5018-mp03.6-c1.dts
new file mode 100644
index 0000000..03456de
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.6-c1.dts
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "ipq5018-soc.dtsi"
+/ {
+ model ="QCA, IPQ5018-MP03.6-C1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.6-c1";
+ machid = <0x8040003>;
+ config_name = "config@mp03.6-c1";
+
+ aliases {
+ console = "/serial@78AF000";
+ mmc = "/sdhci@7804000";
+ i2c0 = "/i2c@78b6000";
+ gmac_gpio = "/gmac_gpio";
+ usb0 = "/xhci@8a00000";
+ pci1 = "/pci@a0000000";
+ nand = "/nand-controller@79B0000";
+ };
+
+ console: serial@78AF000 {
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "okay";
+ nand_gpio {
+ qspi_dat3 {
+ gpio = <4>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat2 {
+ gpio = <5>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat1 {
+ gpio = <6>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_dat0 {
+ gpio = <7>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_cs_n {
+ gpio = <8>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ qspi_clk {
+ gpio = <9>;
+ func = <2>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci0: pci@80000000 {
+ status = "ok";
+ perst_gpio = <18>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <18>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ pci1: pci@a0000000 {
+ status = "ok";
+ perst_gpio = <15>;
+ mode = "fixed";
+ pci_gpio {
+ pci_rst {
+ gpio = <15>;
+ func = <0>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OD_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ usb0: xhci@8a00000 {
+ usb_pwr_gpio = <24>;
+ usb_gpio {
+ pwr_gpio {
+ gpio = <24>;
+ func = <0>;
+ pull = <GPIO_PULL_UP>;
+ oe = <GPIO_OE_ENABLE>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ gmac_cfg {
+ ext_mdio_gpio = <36 37>;
+ gephy_led = <46>;
+
+ gmac1_cfg {
+ unit = <0>;
+ base = <0x39C00000>;
+ phy_address = <7>;
+ };
+ gmac2_cfg {
+ unit = <1>;
+ base = <0x39D00000>;
+ phy_address = <0x1c>;
+ napa_gpio = <39>;
+ };
+
+ };
+
+};
diff --git a/arch/arm/dts/ipq5018-mp03.6-c2.dts b/arch/arm/dts/ipq5018-mp03.6-c2.dts
new file mode 100644
index 0000000..a527e1b
--- /dev/null
+++ b/arch/arm/dts/ipq5018-mp03.6-c2.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include "ipq5018-mp03.6-c1.dts"
+/ {
+ model ="QCA, IPQ5018-MP03.6-C2";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.6-c2";
+ machid = <0x8040103>;
+ config_name = "config@mp03.6-c2";
+
+ mmc: sdhci@7804000 {
+ compatible = "qcom,sdhci-msm";
+ status = "okay";
+ mmc_gpio {
+ emmc_dat3 {
+ gpio = <4>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat2 {
+ gpio = <5>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat1 {
+ gpio = <6>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_dat0 {
+ gpio = <7>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_cmd{
+ gpio = <8>;
+ func = <1>;
+ pull = <GPIO_PULL_UP>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ emmc_clk{
+ gpio = <9>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ od_en = <GPIO_OD_DISABLE>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/ipq5018-soc.dtsi b/arch/arm/dts/ipq5018-soc.dtsi
new file mode 100644
index 0000000..6579252
--- /dev/null
+++ b/arch/arm/dts/ipq5018-soc.dtsi
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/qcom/gpio-ipq5018.h>
+
+/ {
+
+ serial@78AF000 {
+ compatible = "qca,ipq-uartdm";
+ reg = <0x78af000 0x200>;
+ m_value = <0x24>;
+ n_value = <0xC31A>;
+ d_value = <0xC2F6>;
+ bit_rate = <0xff>;
+ status = "disabled";
+ };
+
+ timer {
+ gcnt_cntcv_lo = <0x4a2000>;
+ gcnt_cntcv_hi = <0x4a2004>;
+ gpt_freq_hz = <24000000>;
+ timer_load_val = <0x00FFFFFF 0xFFFFFFFF>;
+ };
+
+ spi {
+ compatible = "qcom,spi-qup-v2.7.0";
+ wr_pipe_0 = <4>;
+ rd_pipe_0 = <5>;
+ status = "ok";
+ spi_gpio {
+ blsp0_spi_clk {
+ gpio = <10>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_ENABLE>;
+ drvstr = <GPIO_2MA>;
+ };
+ blsp0_spi_mosi {
+ gpio = <11>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ oe = <GPIO_OE_ENABLE>;
+ drvstr = <GPIO_2MA>;
+ };
+ blsp0_spi_miso {
+ gpio = <12>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_2MA>;
+ };
+ blsp0_spi_cs {
+ gpio = <13>;
+ func = <1>;
+ oe = <GPIO_OE_ENABLE>;
+ drvstr = <GPIO_2MA>;
+ };
+ };
+ };
+
+ nand: nand-controller@79B0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qpic-nand-v2.1.1";
+ reg = <0x79B0000 0x10000>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@78b7000 {
+ compatible = "qcom,qup-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x78b7000 0x600>;
+ clock-frequency = <400000>;
+
+ i2c_gpio {
+ i2c_scl {
+ gpio = <25>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ };
+
+ i2c_sda{
+ gpio = <26>;
+ func = <3>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ };
+ };
+ };
+
+ xhci@8a00000 {
+ compatible = "qca,dwc3-ipq";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x8a00000 0xe000>;
+ };
+
+ pci@80000000 {
+ compatible = "qcom,ipq5018-pcie";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0xf1d
+ 0x78000 0x3000
+ 0x80000F20 0xa8
+ 0x80001000 0x1000
+ 0x80300000 0xd00000
+ 0x80100000 0x100000
+ 0x01875004 0x40
+ 0x7e000 0x800>;
+ reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
+ "axi_conf", "pci_rst", "pci_phy";
+ gen3 = <1>;
+ lane = <1>;
+ status = "disabled";
+ skip_phy_int = <1>;
+ };
+
+ pci@a0000000 {
+ compatible = "qcom,ipq5018-pcie";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xa0000000 0xf1d
+ 0x80000 0x3000
+ 0xa0000F20 0xa8
+ 0xa0001000 0x1000
+ 0xa0300000 0xd00000
+ 0xa0100000 0x100000
+ 0x01876004 0x40
+ 0x86000 0x1000>;
+ reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars",
+ "axi_conf", "pci_rst", "pci_phy";
+ gen3 = <1>;
+ lane = <2>;
+ status = "disabled";
+ skip_phy_int = <1>;
+ };
+};
diff --git a/arch/arm/dts/ipq5018-sod.dts b/arch/arm/dts/ipq5018-sod.dts
new file mode 100644
index 0000000..38402d8
--- /dev/null
+++ b/arch/arm/dts/ipq5018-sod.dts
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+#include "skeleton.dtsi"
+#include <dt-bindings/qcom/gpio-ipq5018.h>
+/ {
+ model ="QCA, IPQ5018-MP03.1";
+ compatible = "qca,ipq5018", "qca,ipq5018-mp03.1";
+ machid = <0x8040001>;
+ config_name = "config@mp03.1";
+
+ serial@78AF000 {
+ compatible = "qca,ipq-uartdm";
+ reg = <0x78af000 0x200>;
+ m_value = <0x24>;
+ n_value = <0xC31A>;
+ d_value = <0xC2F6>;
+ bit_rate = <0xff>;
+ status = "ok";
+ serial_gpio {
+ blsp0_uart_rx {
+ gpio = <20>;
+ func = <1>;
+ pull = <GPIO_PULL_DOWN>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ blsp0_uart_tx {
+ gpio = <21>;
+ func = <1>;
+ pull = <GPIO_NO_PULL>;
+ drvstr = <GPIO_8MA>;
+ od_en = <GPIO_OD_DISABLE>;
+ };
+ };
+ };
+
+ timer {
+ gcnt_cntcv_lo = <0x4a2000>;
+ gcnt_cntcv_hi = <0x4a2004>;
+ gpt_freq_hz = <24000000>;
+ timer_load_val = <0x00FFFFFF 0xFFFFFFFF>;
+ };
+
+ aliases {
+ console = "/serial@78AF000";
+ };
+
+
+};
diff --git a/arch/arm/dts/ipq5018-tb-mp04.dts b/arch/arm/dts/ipq5018-tb-mp04.dts
new file mode 100644
index 0000000..4f610c6
--- /dev/null
+++ b/arch/arm/dts/ipq5018-tb-mp04.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ipq5018-mp03.3.dts"
+/ {
+ model ="QCA, IPQ5018-TB-MP04";
+ compatible = "qca,ipq5018", "qca,ipq5018-tb-mp04";
+ machid = <0x1040006>;
+ config_name = "config@tb-mp04";
+};
diff --git a/arch/arm/dts/ipq6018-cp01-c3.dts b/arch/arm/dts/ipq6018-cp01-c3.dts
deleted file mode 100644
index 5ec79ae..0000000
--- a/arch/arm/dts/ipq6018-cp01-c3.dts
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-#include "ipq6018-soc.dtsi"
-/ {
- machid = <0x8030002>;
- config_name = "config@cp01-c3";
-
- aliases {
- console = "/serial@78B1000";
- pci0 = "/pci@20000000";
- usb0 = "/xhci@8a00000";
- usb1 = "/xhci@7000000";
- i2c1 = "/i2c@78ba000";
- i2c0 = "/i2c@78b7000";
- };
- i2c0: i2c@78b7000 {
- compatible = "qcom,qup-i2c";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x78b7000 0x600>;
- clock-frequency = <400000>;
-
- i2c_gpio {
- gpio1 {
- gpio = <42>;
- func = <2>;
- pull = <GPIO_PULL_UP>;
- drvstr = <GPIO_8MA>;
- oe = <GPIO_OE_ENABLE>;
- };
-
- gpio2 {
- gpio = <43>;
- func = <2>;
- pull = <GPIO_PULL_UP>;
- drvstr = <GPIO_8MA>;
- oe = <GPIO_OE_ENABLE>;
- };
- };
- };
- ess-switch {
- switch_mac_mode = <PORT_WRAPPER_PSGMII>;
- switch_mac_mode1 = <PORT_WRAPPER_SGMII_PLUS>;
- napa_gpio = <77>;
- napa_gpio_cnt = <1>;
- malibu_gpio = <75>;
- malibu_gpio_cnt = <1>;
- mdc_mdio_gpio = <64 65>;
- port_phyinfo {
- port@0 {
- phy_address = <0>;
- phy_type = <MALIBU_PHY_TYPE>;
- };
- port@1 {
- phy_address = <1>;
- phy_type = <MALIBU_PHY_TYPE>;
- };
- port@2 {
- phy_address = <2>;
- phy_type = <MALIBU_PHY_TYPE>;
- };
- port@3 {
- phy_address = <3>;
- phy_type = <MALIBU_PHY_TYPE>;
- };
- port@4 {
- phy_address = <24>;
- phy_type = <QCA8081_PHY_TYPE>;
- };
- };
- };
-};
diff --git a/arch/arm/dts/ipq6018-soc.dtsi b/arch/arm/dts/ipq6018-soc.dtsi
index 17ce853..52f7e6a 100644
--- a/arch/arm/dts/ipq6018-soc.dtsi
+++ b/arch/arm/dts/ipq6018-soc.dtsi
@@ -22,6 +22,9 @@
reg = <0x78B1000 0x200>;
id = <4>;
bit_rate = <0xff>;
+ m_value = <36>;
+ n_value = <15625>;
+ d_value = <15625>;
serial_gpio {
gpio1 {
gpio = <44>;
diff --git a/arch/arm/dts/ipq807x-hk01-c3.dts b/arch/arm/dts/ipq807x-hk01-c3.dts
deleted file mode 100644
index 5c1050a..0000000
--- a/arch/arm/dts/ipq807x-hk01-c3.dts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-#include "ipq807x-soc.dtsi"
-#include <dt-bindings/qcom/gpio-ipq807x.h>
-/ {
- machid = <0x08010200>;
- config_name = "config@hk01.c3";
-
- aliases {
- console = "/serial@78B3000";
- uart2 = "/serial@78B0000";
- i2c0 = "/i2c@78b6000";
- pci0 = "/pci@20000000";
- pci1 = "/pci@10000000";
- mmc = "/sdhci@07824000";
- };
- ess-switch {
- switch_mac_mode = <0x0>;
- switch_mac_mode1 = <0xFF>;
- switch_mac_mode2 = <0x2>;
- aquantia_port = <5>;
- aquantia_gpio = <44>;
- };
-};
-
diff --git a/arch/arm/dts/ipq807x-hk01.dts b/arch/arm/dts/ipq807x-hk01.dts
index 7d0afcb..19eb620 100644
--- a/arch/arm/dts/ipq807x-hk01.dts
+++ b/arch/arm/dts/ipq807x-hk01.dts
@@ -16,7 +16,7 @@
#include <dt-bindings/qcom/gpio-ipq807x.h>
/ {
machid = <0x08010000>;
- config_name = "config@hk01";
+ config_name = "config@hk01", "config@hk01.c1";
aliases {
console = "/serial@78B3000";
diff --git a/arch/arm/dts/ipq807x-hk05.dts b/arch/arm/dts/ipq807x-hk05.dts
deleted file mode 100644
index 88a5a3d..0000000
--- a/arch/arm/dts/ipq807x-hk05.dts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-#include "ipq807x-soc.dtsi"
-#include <dt-bindings/qcom/gpio-ipq807x.h>
-/ {
- machid = <0x080100002>;
- config_name = "config@hk05";
-
- aliases {
- console = "/serial@78B3000";
- i2c0 = "/i2c@78b6000";
- pci0 = "/pci@20000000";
- pci1 = "/pci@10000000";
- };
-};
-
diff --git a/arch/arm/dts/ipq807x-hk10.dts b/arch/arm/dts/ipq807x-hk10.dts
index c9d3f7d..7c47d22 100644
--- a/arch/arm/dts/ipq807x-hk10.dts
+++ b/arch/arm/dts/ipq807x-hk10.dts
@@ -28,9 +28,11 @@
ess-switch {
switch_mac_mode = <0x0>;
switch_mac_mode1 = <0x2>;
- switch_mac_mode2 = <0x6>;
+ switch_mac_mode2 = <0x7>;
aquantia_port = <4>;
aquantia_gpio = <44>;
+ sfp_port = <5>;
+ sfp_gpio = <59>;
port_phyinfo {
port@0 {
phy_address = <0>;
@@ -52,6 +54,10 @@
phy_address = <7>;
phy_type = <3>;
};
+ port@5 {
+ phy_address = <30>;
+ phy_type = <5>;
+ };
};
};
};
diff --git a/arch/arm/dts/ipq807x-ac02.dts b/arch/arm/dts/ipq807x-hk14.dts
similarity index 74%
rename from arch/arm/dts/ipq807x-ac02.dts
rename to arch/arm/dts/ipq807x-hk14.dts
index d9b186c..581af01 100644
--- a/arch/arm/dts/ipq807x-ac02.dts
+++ b/arch/arm/dts/ipq807x-hk14.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 - 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016 - 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,8 +15,8 @@
#include "ipq807x-soc.dtsi"
#include <dt-bindings/qcom/gpio-ipq807x.h>
/ {
- machid = <0x0801000A>;
- config_name = "config@ac02";
+ machid = <0x08010012>;
+ config_name = "config@hk14";
aliases {
console = "/serial@78B3000";
@@ -24,11 +24,11 @@
pci0 = "/pci@20000000";
};
ess-switch {
- switch_mac_mode = <0x0>;
- switch_mac_mode1 = <0x6>;
- switch_mac_mode2 = <0x6>;
- napa_gpio = <25 44>;
- napa_gpio_cnt = <2>;
+ switch_mac_mode = <0x5>;
+ switch_mac_mode1 = <0xFF>;
+ switch_mac_mode2 = <0x2>;
+ aquantia_port = <5>;
+ aquantia_gpio = <44>;
port_phyinfo {
port@0 {
phy_address = <0>;
@@ -47,13 +47,14 @@
phy_type = <1>;
};
port@4 {
- phy_address = <24>;
- phy_type = <2>;
+ phy_address = <4>;
+ phy_type = <1>;
};
port@5 {
- phy_address = <28>;
- phy_type = <2>;
+ phy_address = <7>;
+ phy_type = <3>;
};
+
};
};
};
diff --git a/arch/arm/dts/ipq807x-oak03.dts b/arch/arm/dts/ipq807x-oak03.dts
deleted file mode 100644
index b594972..0000000
--- a/arch/arm/dts/ipq807x-oak03.dts
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016 - 2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/dts-v1/;
-#include "ipq807x-soc.dtsi"
-#include <dt-bindings/qcom/gpio-ipq807x.h>
-/ {
- machid = <0x0801000D>;
- config_name = "config@oak03";
-
- aliases {
- console = "/serial@78B3000";
- uart2 = "/serial@78B0000";
- i2c0 = "/i2c@78b6000";
- pci0 = "/pci@20000000";
- pci1 = "/pci@10000000";
- mmc = "/sdhci@07824000";
- };
- ess-switch {
- switch_mac_mode = <0x0>;
- switch_mac_mode1 = <0xFF>;
- switch_mac_mode2 = <0x2>;
- aquantia_port = <5>;
- aquantia_gpio = <44>;
- };
-
-};
-
diff --git a/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h
new file mode 100644
index 0000000..cf73988
--- /dev/null
+++ b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ATHRS17_PHY_H
+#define _ATHRS17_PHY_H
+
+/*****************/
+/* PHY Registers */
+/*****************/
+#define ATHR_PHY_CONTROL 0
+#define ATHR_PHY_STATUS 1
+#define ATHR_PHY_ID1 2
+#define ATHR_PHY_ID2 3
+#define ATHR_AUTONEG_ADVERT 4
+#define ATHR_LINK_PARTNER_ABILITY 5
+#define ATHR_AUTONEG_EXPANSION 6
+#define ATHR_NEXT_PAGE_TRANSMIT 7
+#define ATHR_LINK_PARTNER_NEXT_PAGE 8
+#define ATHR_1000BASET_CONTROL 9
+#define ATHR_1000BASET_STATUS 10
+#define ATHR_PHY_SPEC_CONTROL 16
+#define ATHR_PHY_SPEC_STATUS 17
+#define ATHR_DEBUG_PORT_ADDRESS 29
+#define ATHR_DEBUG_PORT_DATA 30
+
+/* ATHR_PHY_CONTROL fields */
+#define ATHR_CTRL_SOFTWARE_RESET 0x8000
+#define ATHR_CTRL_SPEED_LSB 0x2000
+#define ATHR_CTRL_AUTONEGOTIATION_ENABLE 0x1000
+#define ATHR_CTRL_RESTART_AUTONEGOTIATION 0x0200
+#define ATHR_CTRL_SPEED_FULL_DUPLEX 0x0100
+#define ATHR_CTRL_SPEED_MSB 0x0040
+
+#define ATHR_RESET_DONE(phy_control) \
+ (((phy_control) & (ATHR_CTRL_SOFTWARE_RESET)) == 0)
+
+/* Phy status fields */
+#define ATHR_STATUS_AUTO_NEG_DONE 0x0020
+
+#define ATHR_AUTONEG_DONE(ip_phy_status) \
+ (((ip_phy_status) & \
+ (ATHR_STATUS_AUTO_NEG_DONE)) == \
+ (ATHR_STATUS_AUTO_NEG_DONE))
+
+/* Link Partner ability */
+#define ATHR_LINK_100BASETX_FULL_DUPLEX 0x0100
+#define ATHR_LINK_100BASETX 0x0080
+#define ATHR_LINK_10BASETX_FULL_DUPLEX 0x0040
+#define ATHR_LINK_10BASETX 0x0020
+
+/* Advertisement register. */
+#define ATHR_ADVERTISE_NEXT_PAGE 0x8000
+#define ATHR_ADVERTISE_ASYM_PAUSE 0x0800
+#define ATHR_ADVERTISE_PAUSE 0x0400
+#define ATHR_ADVERTISE_100FULL 0x0100
+#define ATHR_ADVERTISE_100HALF 0x0080
+#define ATHR_ADVERTISE_10FULL 0x0040
+#define ATHR_ADVERTISE_10HALF 0x0020
+
+#define ATHR_ADVERTISE_ALL (ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE | \
+ ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL | \
+ ATHR_ADVERTISE_100HALF | ATHR_ADVERTISE_100FULL)
+
+/* 1000BASET_CONTROL */
+#define ATHR_ADVERTISE_1000FULL 0x0200
+
+/* Phy Specific status fields */
+#define ATHER_STATUS_LINK_MASK 0xC000
+#define ATHER_STATUS_LINK_SHIFT 14
+#define ATHER_STATUS_FULL_DEPLEX 0x2000
+#define ATHR_STATUS_LINK_PASS 0x0400
+#define ATHR_STATUS_RESOVLED 0x0800
+
+/*phy debug port register */
+#define ATHER_DEBUG_SERDES_REG 5
+
+/* Serdes debug fields */
+#define ATHER_SERDES_BEACON 0x0100
+
+/* S17 CSR Registers */
+
+#define S17_ENABLE_CPU_BROADCAST (1 << 26)
+
+#define S17_PHY_LINK_CHANGE_REG 0x4
+#define S17_PHY_LINK_UP 0x400
+#define S17_PHY_LINK_DOWN 0x800
+#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000
+#define S17_PHY_LINK_SPEED_CHANGE 0x4000
+#define S17_PHY_LINK_INTRS (PHY_LINK_UP | PHY_LINK_DOWN | PHY_LINK_DUPLEX_CHANGE | PHY_LINK_SPEED_CHANGE)
+
+#define S17_MASK_CTRL_REG 0x0000
+#define S17_P0PAD_MODE_REG 0x0004
+#define S17_P5PAD_MODE_REG 0x0008
+#define S17_P6PAD_MODE_REG 0x000c
+#define S17_PWS_REG 0x0010
+#define S17_GLOBAL_INT0_REG 0x0020
+#define S17_GLOBAL_INT1_REG 0x0024
+#define S17_GLOBAL_INTMASK0 0x0028
+#define S17_GLOBAL_INTMASK1 0x002c
+#define S17_MODULE_EN_REG 0x0030
+#define S17_MIB_REG 0x0034
+#define S17_INTF_HIADDR_REG 0x0038
+#define S17_MDIO_CTRL_REG 0x003c
+#define S17_BIST_CTRL_REG 0x0040
+#define S17_BIST_REC_REG 0x0044
+#define S17_SERVICE_REG 0x0048
+#define S17_LED_CTRL0_REG 0x0050
+#define S17_LED_CTRL1_REG 0x0054
+#define S17_LED_CTRL2_REG 0x0058
+#define S17_LED_CTRL3_REG 0x005c
+#define S17_MACADDR0_REG 0x0060
+#define S17_MACADDR1_REG 0x0064
+#define S17_MAX_FRAME_SIZE_REG 0x0078
+#define S17_P0STATUS_REG 0x007c
+#define S17_P1STATUS_REG 0x0080
+#define S17_P2STATUS_REG 0x0084
+#define S17_P3STATUS_REG 0x0088
+#define S17_P4STATUS_REG 0x008c
+#define S17_P5STATUS_REG 0x0090
+#define S17_P6STATUS_REG 0x0094
+#define S17_HDRCTRL_REG 0x0098
+#define S17_P0HDRCTRL_REG 0x009c
+#define S17_P1HDRCTRL_REG 0x00A0
+#define S17_P2HDRCTRL_REG 0x00a4
+#define S17_P3HDRCTRL_REG 0x00a8
+#define S17_P4HDRCTRL_REG 0x00ac
+#define S17_P5HDRCTRL_REG 0x00b0
+#define S17_P6HDRCTRL_REG 0x00b4
+#define S17_SGMII_CTRL_REG 0x00e0
+#define S17_MAC_PWR_REG 0x00e4
+#define S17_EEE_CTRL_REG 0x0100
+
+/* ACL Registers */
+#define S17_ACL_FUNC0_REG 0x0400
+#define S17_ACL_FUNC1_REG 0x0404
+#define S17_ACL_FUNC2_REG 0x0408
+#define S17_ACL_FUNC3_REG 0x040c
+#define S17_ACL_FUNC4_REG 0x0410
+#define S17_ACL_FUNC5_REG 0x0414
+#define S17_PRIVATE_IP_REG 0x0418
+#define S17_P0VLAN_CTRL0_REG 0x0420
+#define S17_P0VLAN_CTRL1_REG 0x0424
+#define S17_P1VLAN_CTRL0_REG 0x0428
+#define S17_P1VLAN_CTRL1_REG 0x042c
+#define S17_P2VLAN_CTRL0_REG 0x0430
+#define S17_P2VLAN_CTRL1_REG 0x0434
+#define S17_P3VLAN_CTRL0_REG 0x0438
+#define S17_P3VLAN_CTRL1_REG 0x043c
+#define S17_P4VLAN_CTRL0_REG 0x0440
+#define S17_P4VLAN_CTRL1_REG 0x0444
+#define S17_P5VLAN_CTRL0_REG 0x0448
+#define S17_P5VLAN_CTRL1_REG 0x044c
+#define S17_P6VLAN_CTRL0_REG 0x0450
+#define S17_P6VLAN_CTRL1_REG 0x0454
+
+/* Table Lookup Registers */
+#define S17_ATU_DATA0_REG 0x0600
+#define S17_ATU_DATA1_REG 0x0604
+#define S17_ATU_DATA2_REG 0x0608
+#define S17_ATU_FUNC_REG 0x060C
+#define S17_VTU_FUNC0_REG 0x0610
+#define S17_VTU_FUNC1_REG 0x0614
+#define S17_ARL_CTRL_REG 0x0618
+#define S17_GLOFW_CTRL0_REG 0x0620
+#define S17_GLOFW_CTRL1_REG 0x0624
+#define S17_GLOLEARN_LIMIT_REG 0x0628
+#define S17_TOS_PRIMAP_REG0 0x0630
+#define S17_TOS_PRIMAP_REG1 0x0634
+#define S17_TOS_PRIMAP_REG2 0x0638
+#define S17_TOS_PRIMAP_REG3 0x063c
+#define S17_TOS_PRIMAP_REG4 0x0640
+#define S17_TOS_PRIMAP_REG5 0x0644
+#define S17_TOS_PRIMAP_REG6 0x0648
+#define S17_TOS_PRIMAP_REG7 0x064c
+#define S17_VLAN_PRIMAP_REG0 0x0650
+#define S17_LOOP_CHECK_REG 0x0654
+#define S17_P0LOOKUP_CTRL_REG 0x0660
+#define S17_P0PRI_CTRL_REG 0x0664
+#define S17_P0LEARN_LMT_REG 0x0668
+#define S17_P1LOOKUP_CTRL_REG 0x066c
+#define S17_P1PRI_CTRL_REG 0x0670
+#define S17_P1LEARN_LMT_REG 0x0674
+#define S17_P2LOOKUP_CTRL_REG 0x0678
+#define S17_P2PRI_CTRL_REG 0x067c
+#define S17_P2LEARN_LMT_REG 0x0680
+#define S17_P3LOOKUP_CTRL_REG 0x0684
+#define S17_P3PRI_CTRL_REG 0x0688
+#define S17_P3LEARN_LMT_REG 0x068c
+#define S17_P4LOOKUP_CTRL_REG 0x0690
+#define S17_P4PRI_CTRL_REG 0x0694
+#define S17_P4LEARN_LMT_REG 0x0698
+#define S17_P5LOOKUP_CTRL_REG 0x069c
+#define S17_P5PRI_CTRL_REG 0x06a0
+#define S17_P5LEARN_LMT_REG 0x06a4
+#define S17_P6LOOKUP_CTRL_REG 0x06a8
+#define S17_P6PRI_CTRL_REG 0x06ac
+#define S17_P6LEARN_LMT_REG 0x06b0
+#define S17_GLO_TRUNK_CTRL0_REG 0x0700
+#define S17_GLO_TRUNK_CTRL1_REG 0x0704
+#define S17_GLO_TRUNK_CTRL2_REG 0x0708
+
+/* Queue Management Registers */
+#define S17_PORT0_HOL_CTRL0 0x0970
+#define S17_PORT0_HOL_CTRL1 0x0974
+#define S17_PORT1_HOL_CTRL0 0x0978
+#define S17_PORT1_HOL_CTRL1 0x097c
+#define S17_PORT2_HOL_CTRL0 0x0980
+#define S17_PORT2_HOL_CTRL1 0x0984
+#define S17_PORT3_HOL_CTRL0 0x0988
+#define S17_PORT3_HOL_CTRL1 0x098c
+#define S17_PORT4_HOL_CTRL0 0x0990
+#define S17_PORT4_HOL_CTRL1 0x0994
+#define S17_PORT5_HOL_CTRL0 0x0998
+#define S17_PORT5_HOL_CTRL1 0x099c
+#define S17_PORT6_HOL_CTRL0 0x09a0
+#define S17_PORT6_HOL_CTRL1 0x09a4
+
+/* Port flow control registers */
+#define S17_P0_FLCTL_REG 0x09b0
+#define S17_P1_FLCTL_REG 0x09b4
+#define S17_P2_FLCTL_REG 0x09b8
+#define S17_P3_FLCTL_REG 0x09bc
+#define S17_P4_FLCTL_REG 0x09c0
+#define S17_P5_FLCTL_REG 0x09c4
+
+/* Packet Edit registers */
+#define S17_PKT_EDIT_CTRL 0x0c00
+#define S17_P0Q_REMAP_REG0 0x0c40
+#define S17_P0Q_REMAP_REG1 0x0c44
+#define S17_P1Q_REMAP_REG0 0x0c48
+#define S17_P2Q_REMAP_REG0 0x0c4c
+#define S17_P3Q_REMAP_REG0 0x0c50
+#define S17_P4Q_REMAP_REG0 0x0c54
+#define S17_P5Q_REMAP_REG0 0x0c58
+#define S17_P5Q_REMAP_REG1 0x0c5c
+#define S17_P6Q_REMAP_REG0 0x0c60
+#define S17_P6Q_REMAP_REG1 0x0c64
+#define S17_ROUTER_VID0 0x0c70
+#define S17_ROUTER_VID1 0x0c74
+#define S17_ROUTER_VID2 0x0c78
+#define S17_ROUTER_VID3 0x0c7c
+#define S17_ROUTER_EG_VLAN_MODE 0x0c80
+
+/* L3 Registers */
+#define S17_HROUTER_CTRL_REG 0x0e00
+#define S17_HROUTER_PBCTRL0_REG 0x0e04
+#define S17_HROUTER_PBCTRL1_REG 0x0e08
+#define S17_HROUTER_PBCTRL2_REG 0x0e0c
+#define S17_WCMP_HASH_TABLE0_REG 0x0e10
+#define S17_WCMP_HASH_TABLE1_REG 0x0e14
+#define S17_WCMP_HASH_TABLE2_REG 0x0e18
+#define S17_WCMP_HASH_TABLE3_REG 0x0e1c
+#define S17_WCMP_NHOP_TABLE0_REG 0x0e20
+#define S17_WCMP_NHOP_TABLE1_REG 0x0e24
+#define S17_WCMP_NHOP_TABLE2_REG 0x0e28
+#define S17_WCMP_NHOP_TABLE3_REG 0x0e2c
+#define S17_ARP_ENTRY_CTRL_REG 0x0e30
+#define S17_ARP_USECNT_REG 0x0e34
+#define S17_HNAT_CTRL_REG 0x0e38
+#define S17_NAPT_ENTRY_CTRL0_REG 0x0e3c
+#define S17_NAPT_ENTRY_CTRL1_REG 0x0e40
+#define S17_NAPT_USECNT_REG 0x0e44
+#define S17_ENTRY_EDIT_DATA0_REG 0x0e48
+#define S17_ENTRY_EDIT_DATA1_REG 0x0e4c
+#define S17_ENTRY_EDIT_DATA2_REG 0x0e50
+#define S17_ENTRY_EDIT_DATA3_REG 0x0e54
+#define S17_ENTRY_EDIT_CTRL_REG 0x0e58
+#define S17_HNAT_PRIVATE_IP_REG 0x0e5c
+
+/* MIB counters */
+#define S17_MIB_PORT0 0x1000
+#define S17_MIB_PORT1 0x1100
+#define S17_MIB_PORT2 0x1200
+#define S17_MIB_PORT3 0x1300
+#define S17_MIB_PORT4 0x1400
+#define S17_MIB_PORT5 0x1500
+#define S17_MIB_PORT6 0x1600
+
+#define S17_MIB_COUNTER_ENABLE (1 << 0)
+#define S17_MIB_NON_CLEAR (1 << 20)
+
+#define S17_MIB_RXBROAD 0x0
+#define S17_MIB_RXPAUSE 0x4
+#define S17_MIB_RXMULTI 0x8
+#define S17_MIB_RXFCSERR 0xC
+#define S17_MIB_RXALIGNERR 0x10
+#define S17_MIB_RXUNDERSIZE 0x14
+#define S17_MIB_RXFRAG 0x18
+#define S17_MIB_RX64B 0x1C
+#define S17_MIB_RX128B 0x20
+#define S17_MIB_RX256B 0x24
+#define S17_MIB_RX512B 0x28
+#define S17_MIB_RX1024B 0x2C
+#define S17_MIB_RX1518B 0x30
+#define S17_MIB_RXMAXB 0x34
+#define S17_MIB_RXTOOLONG 0x38
+#define S17_MIB_RXBYTE1 0x3C
+#define S17_MIB_RXBYTE2 0x40
+#define S17_MIB_RXOVERFLOW 0x4C
+#define S17_MIB_FILTERED 0x50
+#define S17_MIB_TXBROAD 0x54
+#define S17_MIB_TXPAUSE 0x58
+#define S17_MIB_TXMULTI 0x5C
+#define S17_MIB_TXUNDERRUN 0x60
+#define S17_MIB_TX64B 0x64
+#define S17_MIB_TX128B 0x68
+#define S17_MIB_TX256B 0x6c
+#define S17_MIB_TX512B 0x70
+#define S17_MIB_TX1024B 0x74
+#define S17_MIB_TX1518B 0x78
+#define S17_MIB_TXMAXB 0x7C
+#define S17_MIB_TXOVERSIZE 0x80
+#define S17_MIB_TXBYTE1 0x84
+#define S17_MIB_TXBYTE2 0x88
+#define S17_MIB_TXCOL 0x8C
+#define S17_MIB_TXABORTCOL 0x90
+#define S17_MIB_TXMULTICOL 0x94
+#define S17_MIB_TXSINGLECOL 0x98
+#define S17_MIB_TXEXCDEFER 0x9C
+#define S17_MIB_TXDEFER 0xA0
+#define S17_MIB_TXLATECOL 0xA4
+
+/* Register fields */
+#define S17_CHIPID_V1_0 0x1201
+#define S17_CHIPID_V1_1 0x1202
+
+#define S17_MASK_CTRL_SOFT_RET (1 << 31)
+
+#define S17_GLOBAL_INT0_ACL_INI_INT (1<<29)
+#define S17_GLOBAL_INT0_LOOKUP_INI_INT (1<<28)
+#define S17_GLOBAL_INT0_QM_INI_INT (1<<27)
+#define S17_GLOBAL_INT0_MIB_INI_INT (1<<26)
+#define S17_GLOBAL_INT0_OFFLOAD_INI_INT (1<<25)
+#define S17_GLOBAL_INT0_HARDWARE_INI_DONE (1<<24)
+
+#define S17_GLOBAL_INITIALIZED_STATUS \
+ ( \
+ S17_GLOBAL_INT0_ACL_INI_INT | \
+ S17_GLOBAL_INT0_LOOKUP_INI_INT | \
+ S17_GLOBAL_INT0_QM_INI_INT | \
+ S17_GLOBAL_INT0_MIB_INI_INT | \
+ S17_GLOBAL_INT0_OFFLOAD_INI_INT | \
+ S17_GLOBAL_INT0_HARDWARE_INI_DONE \
+ )
+
+#define S17_MAC0_MAC_MII_RXCLK_SEL (1 << 0)
+#define S17_MAC0_MAC_MII_TXCLK_SEL (1 << 1)
+#define S17_MAC0_MAC_MII_EN (1 << 2)
+#define S17_MAC0_MAC_GMII_RXCLK_SEL (1 << 4)
+#define S17_MAC0_MAC_GMII_TXCLK_SEL (1 << 5)
+#define S17_MAC0_MAC_GMII_EN (1 << 6)
+#define S17_MAC0_SGMII_EN (1 << 7)
+#define S17_MAC0_PHY_MII_RXCLK_SEL (1 << 8)
+#define S17_MAC0_PHY_MII_TXCLK_SEL (1 << 9)
+#define S17_MAC0_PHY_MII_EN (1 << 10)
+#define S17_MAC0_PHY_MII_PIPE_SEL (1 << 11)
+#define S17_MAC0_PHY_GMII_RXCLK_SEL (1 << 12)
+#define S17_MAC0_PHY_GMII_TXCLK_SEL (1 << 13)
+#define S17_MAC0_PHY_GMII_EN (1 << 14)
+#define S17_MAC0_RGMII_RXCLK_SHIFT 20
+#define S17_MAC0_RGMII_TXCLK_SHIFT 22
+#define S17_MAC0_RGMII_RXCLK_DELAY (1 << 24)
+#define S17_MAC0_RGMII_TXCLK_DELAY (1 << 25)
+#define S17_MAC0_RGMII_EN (1 << 26)
+
+#define S17_MAC5_MAC_MII_RXCLK_SEL (1 << 0)
+#define S17_MAC5_MAC_MII_TXCLK_SEL (1 << 1)
+#define S17_MAC5_MAC_MII_EN (1 << 2)
+#define S17_MAC5_PHY_MII_RXCLK_SEL (1 << 8)
+#define S17_MAC5_PHY_MII_TXCLK_SEL (1 << 9)
+#define S17_MAC5_PHY_MII_EN (1 << 10)
+#define S17_MAC5_PHY_MII_PIPE_SEL (1 << 11)
+#define S17_MAC5_RGMII_RXCLK_SHIFT 20
+#define S17_MAC5_RGMII_TXCLK_SHIFT 22
+#define S17_MAC5_RGMII_RXCLK_DELAY (1 << 24)
+#define S17_MAC5_RGMII_TXCLK_DELAY (1 << 25)
+#define S17_MAC5_RGMII_EN (1 << 26)
+
+#define S17_MAC6_MAC_MII_RXCLK_SEL (1 << 0)
+#define S17_MAC6_MAC_MII_TXCLK_SEL (1 << 1)
+#define S17_MAC6_MAC_MII_EN (1 << 2)
+#define S17_MAC6_MAC_GMII_RXCLK_SEL (1 << 4)
+#define S17_MAC6_MAC_GMII_TXCLK_SEL (1 << 5)
+#define S17_MAC6_MAC_GMII_EN (1 << 6)
+#define S17_MAC6_SGMII_EN (1 << 7)
+#define S17_MAC6_PHY_MII_RXCLK_SEL (1 << 8)
+#define S17_MAC6_PHY_MII_TXCLK_SEL (1 << 9)
+#define S17_MAC6_PHY_MII_EN (1 << 10)
+#define S17_MAC6_PHY_MII_PIPE_SEL (1 << 11)
+#define S17_MAC6_PHY_GMII_RXCLK_SEL (1 << 12)
+#define S17_MAC6_PHY_GMII_TXCLK_SEL (1 << 13)
+#define S17_MAC6_PHY_GMII_EN (1 << 14)
+#define S17_PHY4_GMII_EN (1 << 16)
+#define S17_PHY4_RGMII_EN (1 << 17)
+#define S17_PHY4_MII_EN (1 << 18)
+#define S17_MAC6_RGMII_RXCLK_SHIFT 20
+#define S17_MAC6_RGMII_TXCLK_SHIFT 22
+#define S17_MAC6_RGMII_RXCLK_DELAY (1 << 24)
+#define S17_MAC6_RGMII_TXCLK_DELAY (1 << 25)
+#define S17_MAC6_RGMII_EN (1 << 26)
+
+#define S17_SPEED_10M (0 << 0)
+#define S17_SPEED_100M (1 << 0)
+#define S17_SPEED_1000M (2 << 0)
+#define S17_TXMAC_EN (1 << 2)
+#define S17_RXMAC_EN (1 << 3)
+#define S17_TX_FLOW_EN (1 << 4)
+#define S17_RX_FLOW_EN (1 << 5)
+#define S17_DUPLEX_FULL (1 << 6)
+#define S17_DUPLEX_HALF (0 << 6)
+#define S17_TX_HALF_FLOW_EN (1 << 7)
+#define S17_LINK_EN (1 << 9)
+#define S17_FLOW_LINK_EN (1 << 12)
+#define S17_PORT_STATUS_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \
+ S17_RXMAC_EN | S17_TX_FLOW_EN | \
+ S17_RX_FLOW_EN | S17_DUPLEX_FULL | \
+ S17_TX_HALF_FLOW_EN)
+
+#define S17_PORT_STATUS_AZ_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \
+ S17_RXMAC_EN | S17_TX_FLOW_EN | \
+ S17_RX_FLOW_EN | S17_DUPLEX_FULL)
+
+
+#define S17_HDRLENGTH_SEL (1 << 16)
+#define S17_HDR_VALUE 0xAAAA
+
+#define S17_TXHDR_MODE_NO 0
+#define S17_TXHDR_MODE_MGM 1
+#define S17_TXHDR_MODE_ALL 2
+#define S17_RXHDR_MODE_NO (0 << 2)
+#define S17_RXHDR_MODE_MGM (1 << 2)
+#define S17_RXHDR_MODE_ALL (2 << 2)
+
+#define S17_CPU_PORT_EN (1 << 10)
+#define S17_PPPOE_REDIR_EN (1 << 8)
+#define S17_MIRROR_PORT_SHIFT 4
+#define S17_IGMP_COPY_EN (1 << 3)
+#define S17_RIP_COPY_EN (1 << 2)
+#define S17_EAPOL_REDIR_EN (1 << 0)
+
+#define S17_IGMP_JOIN_LEAVE_DP_SHIFT 24
+#define S17_BROAD_DP_SHIFT 16
+#define S17_MULTI_FLOOD_DP_SHIFT 8
+#define S17_UNI_FLOOD_DP_SHIFT 0
+#define S17_IGMP_JOIN_LEAVE_DPALL (0x7f << S17_IGMP_JOIN_LEAVE_DP_SHIFT)
+#define S17_BROAD_DPALL (0x7f << S17_BROAD_DP_SHIFT)
+#define S17_MULTI_FLOOD_DPALL (0x7f << S17_MULTI_FLOOD_DP_SHIFT)
+#define S17_UNI_FLOOD_DPALL (0x7f << S17_UNI_FLOOD_DP_SHIFT)
+
+#define S17_PWS_CHIP_AR8327 (1 << 30)
+#define S17c_PWS_SERDES_ANEG_DISABLE (1 << 7)
+
+/* S17_PHY_CONTROL fields */
+#define S17_CTRL_SOFTWARE_RESET 0x8000
+#define S17_CTRL_SPEED_LSB 0x2000
+#define S17_CTRL_AUTONEGOTIATION_ENABLE 0x1000
+#define S17_CTRL_RESTART_AUTONEGOTIATION 0x0200
+#define S17_CTRL_SPEED_FULL_DUPLEX 0x0100
+#define S17_CTRL_SPEED_MSB 0x0040
+
+/* For EEE_CTRL_REG */
+#define S17_LPI_DISABLE_P1 (1 << 4)
+#define S17_LPI_DISABLE_P2 (1 << 6)
+#define S17_LPI_DISABLE_P3 (1 << 8)
+#define S17_LPI_DISABLE_P4 (1 << 10)
+#define S17_LPI_DISABLE_P5 (1 << 12)
+#define S17_LPI_DISABLE_ALL 0x1550
+
+/* For MMD register control */
+#define S17_MMD_FUNC_ADDR (0 << 14)
+#define S17_MMD_FUNC_DATA (1 << 14)
+#define S17_MMD_FUNC_DATA_2 (2 << 14)
+#define S17_MMD_FUNC_DATA_3 (3 << 14)
+
+/* For phyInfo_t azFeature */
+#define S17_8023AZ_PHY_ENABLED (1 << 0)
+#define S17_8023AZ_PHY_LINKED (1 << 1)
+
+/* Queue Management registe fields */
+#define S17_HOL_CTRL0_LAN 0x2a008888 /* egress priority 8, eg_portq = 0x2a */
+#define S17_HOL_CTRL0_WAN 0x2a666666 /* egress priority 6, eg_portq = 0x2a */
+#define S17_HOL_CTRL1_DEFAULT 0xc6 /* enable HOL control */
+
+/* Packet Edit register fields */
+#define S17_ROUTER_EG_UNMOD 0x0 /* unmodified */
+#define S17_ROUTER_EG_WOVLAN 0x1 /* without VLAN */
+#define S17_ROUTER_EG_WVLAN 0x2 /* with VLAN */
+#define S17_ROUTER_EG_UNTOUCH 0x3 /* untouched */
+#define S17_ROUTER_EG_MODE_DEFAULT 0x01111111 /* all ports without VLAN */
+
+#define S17_RESET_DONE(phy_control) \
+ (((phy_control) & (S17_CTRL_SOFTWARE_RESET)) == 0)
+
+/* Phy status fields */
+#define S17_STATUS_AUTO_NEG_DONE 0x0020
+
+#define S17_AUTONEG_DONE(ip_phy_status) \
+ (((ip_phy_status) & \
+ (S17_STATUS_AUTO_NEG_DONE)) == \
+ (S17_STATUS_AUTO_NEG_DONE))
+
+/* Link Partner ability */
+#define S17_LINK_100BASETX_FULL_DUPLEX 0x0100
+#define S17_LINK_100BASETX 0x0080
+#define S17_LINK_10BASETX_FULL_DUPLEX 0x0040
+#define S17_LINK_10BASETX 0x0020
+
+/* Advertisement register. */
+#define S17_ADVERTISE_NEXT_PAGE 0x8000
+#define S17_ADVERTISE_ASYM_PAUSE 0x0800
+#define S17_ADVERTISE_PAUSE 0x0400
+#define S17_ADVERTISE_100FULL 0x0100
+#define S17_ADVERTISE_100HALF 0x0080
+#define S17_ADVERTISE_10FULL 0x0040
+#define S17_ADVERTISE_10HALF 0x0020
+
+#define S17_ADVERTISE_ALL (S17_ADVERTISE_ASYM_PAUSE | S17_ADVERTISE_PAUSE | \
+ S17_ADVERTISE_10HALF | S17_ADVERTISE_10FULL | \
+ S17_ADVERTISE_100HALF | S17_ADVERTISE_100FULL)
+
+/* 1000BASET_CONTROL */
+#define S17_ADVERTISE_1000FULL 0x0200
+
+/* Phy Specific status fields */
+#define S17_STATUS_LINK_MASK 0xC000
+#define S17_STATUS_LINK_SHIFT 14
+#define S17_STATUS_FULL_DEPLEX 0x2000
+#define S17_STATUS_LINK_PASS 0x0400
+#define S17_STATUS_RESOLVED 0x0800
+#define S17_STATUS_LINK_10M 0
+#define S17_STATUS_LINK_100M 1
+#define S17_STATUS_LINK_1000M 2
+
+#define S17_GLOBAL_INT_PHYMASK (1 << 15)
+
+#define S17_PHY_LINK_UP 0x400
+#define S17_PHY_LINK_DOWN 0x800
+#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000
+#define S17_PHY_LINK_SPEED_CHANGE 0x4000
+
+/* For Port flow control registers */
+#define S17_PORT_FLCTL_XON_DEFAULT (0x3a << 16)
+#define S17_PORT_FLCTL_XOFF_DEFAULT (0x4a)
+
+/* Module enable Register */
+#define S17_MODULE_L3_EN (1 << 2)
+#define S17_MODULE_ACL_EN (1 << 1)
+#define S17_MODULE_MIB_EN (1 << 0)
+
+/* MIB Function Register 1 */
+#define S17_MIB_FUNC_ALL (3 << 24)
+#define S17_MIB_CPU_KEEP (1 << 20)
+#define S17_MIB_BUSY (1 << 17)
+#define S17_MIB_AT_HALF_EN (1 << 16)
+#define S17_MIB_TIMER_DEFAULT 0x100
+
+#define S17_MAC_MAX 7
+
+/* MAC power selector bit definitions */
+#define S17_RGMII0_1_8V (1 << 19)
+#define S17_RGMII1_1_8V (1 << 18)
+
+/* SGMII_CTRL bit definitions */
+#define S17c_SGMII_EN_LCKDT (1 << 0)
+#define S17c_SGMII_EN_PLL (1 << 1)
+#define S17c_SGMII_EN_RX (1 << 2)
+#define S17c_SGMII_EN_TX (1 << 3)
+#define S17c_SGMII_EN_SD (1 << 4)
+#define S17c_SGMII_BW_HIGH (1 << 6)
+#define S17c_SGMII_SEL_CLK125M (1 << 7)
+#define S17c_SGMII_TXDR_CTRL_600mV (1 << 10)
+#define S17c_SGMII_CDR_BW_8 (3 << 13)
+#define S17c_SGMII_DIS_AUTO_LPI_25M (1 << 16)
+#define S17c_SGMII_MODE_CTRL_SGMII_PHY (1 << 22)
+#define S17c_SGMII_PAUSE_SG_TX_EN_25M (1 << 24)
+#define S17c_SGMII_ASYM_PAUSE_25M (1 << 25)
+#define S17c_SGMII_PAUSE_25M (1 << 26)
+#define S17c_SGMII_HALF_DUPLEX_25M (1 << 30)
+#define S17c_SGMII_FULL_DUPLEX_25M (1 << 31)
+
+#ifndef BOOL
+#define BOOL int
+#endif
+
+/*add feature define here*/
+
+#ifdef CONFIG_AR7242_S17_PHY
+#undef HEADER_REG_CONF
+#undef HEADER_EN
+#endif
+int athrs17_init_switch(void);
+void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg);
+void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg);
+void athrs17_vlan_config(void);
+#endif
+
+
diff --git a/arch/arm/include/asm/arch-ipq5018/clk.h b/arch/arm/include/asm/arch-ipq5018/clk.h
new file mode 100644
index 0000000..4e553d4
--- /dev/null
+++ b/arch/arm/include/asm/arch-ipq5018/clk.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015-2016, 2018-2020 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef IPQ5018_CLK_H
+#define IPQ5018_CLK_H
+
+#define CLK_ENABLE 0x1
+/* I2C clocks configuration */
+#ifdef CONFIG_IPQ5018_I2C
+
+#define GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR 0x1804004
+#define GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR_SRC_SEL (1 << 8)
+#define GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR_SRC_DIV (0x1F << 0)
+
+#define GCC_BLSP1_QUP3_I2C_APPS_CMD_RCGR 0x1804000
+#define GCC_BLSP1_QUP3_I2C_APPS_CBCR 0x1804010
+
+#define CMD_UPDATE 0x1
+#define ROOT_EN 0x2
+
+
+void i2c_clock_config(void);
+#endif
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+#define GCC_BTSS_LPO_CBCR 0x181C004
+void enable_btss_lpo_clk(void);
+#endif
+
+#endif /*IPQ5018_CLK_H*/
diff --git a/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h
new file mode 100644
index 0000000..f93bca4
--- /dev/null
+++ b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h
@@ -0,0 +1,640 @@
+/*
+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _IPQ5018_GMAC_H
+#define _IPQ5018_GMAC_H
+#include <common.h>
+#include <net.h>
+#include <configs/ipq5018.h>
+
+#define QCA808X_MII_ADDR_C45 (1<<30)
+#define QCA808X_REG_C45_ADDRESS(dev_type, reg_num) \
+ (QCA808X_MII_ADDR_C45 | \
+ ((dev_type & 0x1f) << 16) | \
+ (reg_num & 0xffff))
+#define MPGE_PHY_MMD1_DAC 0x8100
+#define MPGE_PHY_MMD1_NUM 0x1
+#define MPGE_PHY_MMD1_DAC_MASK 0xff00
+#define PHY_DAC(val) (val<<8)
+#define MPGE_PHY_DEBUG_EDAC 0x4380
+
+#define LINK_UP 0x400
+#define LINK(_data) (_data & LINK_UP)? "Up" : "Down"
+#define DUPLEX(_data) (_data & 0x2000)?\
+ "Full duplex" : "Half duplex"
+#define SPEED(_data) ((_data & 0xC000) >> 12)
+#define SPEED_1000M (1 << 3)
+#define SPEED_100M (1 << 2)
+
+#define GEPHY 0x004DD0C0
+#define S17C_VERSION 0x1302
+#define QCA_8337 0x004DD036
+
+#define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ)
+#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ)
+#define CONFIG_PHYRESET_TIMEOUT (3 * CONFIG_SYS_HZ)
+#define CONFIG_AUTONEG_TIMEOUT (5 * CONFIG_SYS_HZ)
+/* MAC configuration register definitions */
+#define FRAMEBURSTENABLE (1 << 21)
+#define MII_PORTSELECT (1 << 15)
+#define FES_100 (1 << 14)
+#define DISABLERXOWN (1 << 13)
+#define FULLDPLXMODE (1 << 11)
+#define RXENABLE (1 << 2)
+#define TXENABLE (1 << 3)
+#define DW_DMA_BASE_OFFSET (0x1000)
+
+/* Poll demand definitions */
+#define POLL_DATA (0x0)
+
+/* Descriptior related definitions */
+#define MAC_MAX_FRAME_SZ (1600)
+
+/*
+ * txrx_status definitions
+ */
+
+/* tx status bits definitions */
+#define DESC_TXSTS_OWNBYDMA (1 << 31)
+#define DESC_TXSTS_TXINT (1 << 30)
+#define DESC_TXSTS_TXLAST (1 << 29)
+#define DESC_TXSTS_TXFIRST (1 << 28)
+#define DESC_TXSTS_TXCRCDIS (1 << 27)
+
+#define DESC_TXSTS_TXPADDIS (1 << 26)
+#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22)
+#define DESC_TXSTS_TXRINGEND (1 << 21)
+#define DESC_TXSTS_TXCHAIN (1 << 20)
+#define DESC_TXSTS_MSK (0x1FFFF << 0)
+
+/* rx status bits definitions */
+#define DESC_RXSTS_OWNBYDMA (1 << 31)
+#define DESC_RXSTS_DAFILTERFAIL (1 << 30)
+#define DESC_RXSTS_FRMLENMSK (0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT (16)
+
+#define DESC_RXSTS_ERROR (1 << 15)
+#define DESC_RXSTS_RXTRUNCATED (1 << 14)
+#define DESC_RXSTS_SAFILTERFAIL (1 << 13)
+#define DESC_RXSTS_RXIPC_GIANTFRAME (1 << 12)
+#define DESC_RXSTS_RXDAMAGED (1 << 11)
+#define DESC_RXSTS_RXVLANTAG (1 << 10)
+#define DESC_RXSTS_RXFIRST (1 << 9)
+#define DESC_RXSTS_RXLAST (1 << 8)
+#define DESC_RXSTS_RXIPC_GIANT (1 << 7)
+#define DESC_RXSTS_RXCOLLISION (1 << 6)
+#define DESC_RXSTS_RXFRAMEETHER (1 << 5)
+#define DESC_RXSTS_RXWATCHDOG (1 << 4)
+#define DESC_RXSTS_RXMIIERROR (1 << 3)
+#define DESC_RXSTS_RXDRIBBLING (1 << 2)
+#define DESC_RXSTS_RXCRC (1 << 1)
+
+/*
+ * dmamac_cntl definitions
+ */
+
+/* tx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_TXCTRL_SIZE1MASK (0x1FFF << 0)
+#define DESC_TXCTRL_SIZE1SHFT (0)
+#define DESC_TXCTRL_SIZE2MASK (0x1FFF << 16)
+#define DESC_TXCTRL_SIZE2SHFT (16)
+
+#else
+
+#define DESC_TXCTRL_TXINT (1 << 31)
+#define DESC_TXCTRL_TXLAST (1 << 30)
+#define DESC_TXCTRL_TXFIRST (1 << 29)
+#define DESC_TXCTRL_TXCHECKINSCTRL (3 << 27)
+#define DESC_TXCTRL_TXCRCDIS (1 << 26)
+#define DESC_TXCTRL_TXRINGEND (1 << 25)
+#define DESC_TXCTRL_TXCHAIN (1 << 24)
+
+#define DESC_TXCTRL_SIZE1MASK (0x7FF << 0)
+#define DESC_TXCTRL_SIZE1SHFT (0)
+#define DESC_TXCTRL_SIZE2MASK (0x7FF << 11)
+#define DESC_TXCTRL_SIZE2SHFT (11)
+
+#endif
+
+/* rx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_RXCTRL_RXINTDIS (1 << 31)
+#define DESC_RXCTRL_RXRINGEND (1 << 15)
+#define DESC_RXCTRL_RXCHAIN (1 << 14)
+
+#define DESC_RXCTRL_SIZE1MASK (0x1FFF << 0)
+#define DESC_RXCTRL_SIZE1SHFT (0)
+#define DESC_RXCTRL_SIZE2MASK (0x1FFF << 16)
+#define DESC_RXCTRL_SIZE2SHFT (16)
+
+#else
+
+#define DESC_RXCTRL_RXINTDIS (1 << 31)
+#define DESC_RXCTRL_RXRINGEND (1 << 25)
+#define DESC_RXCTRL_RXCHAIN (1 << 24)
+
+#define DESC_RXCTRL_SIZE1MASK (0x7FF << 0)
+#define DESC_RXCTRL_SIZE1SHFT (0)
+#define DESC_RXCTRL_SIZE2MASK (0x7FF << 11)
+#define DESC_RXCTRL_SIZE2SHFT (11)
+
+#endif
+
+/* Speed specific definitions */
+#define NETDEV_TX_BUSY (1)
+
+/* Duplex mode specific definitions */
+#define HALF_DUPLEX (1)
+#define FULL_DUPLEX (2)
+
+/* Bus mode register definitions */
+#define FIXEDBURST (1 << 16)
+#define PRIORXTX_41 (3 << 14)
+#define PRIORXTX_31 (2 << 14)
+#define PRIORXTX_21 (1 << 14)
+#define PRIORXTX_11 (0 << 14)
+#define BURST_1 (1 << 8)
+#define BURST_2 (2 << 8)
+#define BURST_4 (4 << 8)
+#define BURST_8 (8 << 8)
+#define BURST_16 (16 << 8)
+#define BURST_32 (32 << 8)
+#define RXHIGHPRIO (1 << 1)
+#define DMAMAC_SRST (1 << 0)
+#define DMA_ARB (1 << 1)
+#define DESC_SKIP_LEN_0 (0 << 2)
+#define DMA_INT_DISABLE (0 << 0)
+/* Operation mode definitions */
+#define STOREFORWARD (1 << 21)
+#define FLUSHTXFIFO (1 << 20)
+#define TXSTART (1 << 13)
+#define TXSECONDFRAME (1 << 2)
+#define RXSTART (1 << 1)
+#define RX_THRESHOLD_128 (3 << 3)
+#define OP_SECOND_FRAME (1 << 2)
+
+/* GMAC config definitions */
+#define FES_PORT_SPEED (1 << 14)
+#define MII_PORT_SELECT (1 << 15)
+#define SGMII_PORT_SELECT (0 << 15)
+#define FRAME_BURST_ENABLE (1 << 21)
+#define JABBER_DISABLE (1 << 22)
+#define JUMBO_FRAME_ENABLE (1 << 20)
+#define HALF_DUPLEX_ENABLE (0 << 11)
+#define FULL_DUPLEX_ENABLE (1 << 11)
+#define TX_ENABLE (1 << 3)
+#define RX_ENABLE (1 << 2)
+#define RX_IPC_OFFLOAD (1 << 10)
+
+/* GMAC Fram filter definitions */
+#define GMAC_FRAME_RX_ALL (1 << 31)
+#define PROMISCUOUS_MODE_ON (1 << 0)
+#define DISABLE_BCAST_FRAMES (1 << 5)
+
+/* DMA Flow control definitions */
+#define FULL_3KB (1 << 10)
+#define HW_FLW_CNTL_ENABLE (1 << 8)
+
+/* GMAC Flow control definitions */
+#define RX_FLW_CNTL_ENABLE (1 << 2)
+#define TX_FLW_CNTL_ENABLE (1 << 1)
+
+
+/* Descriptor definitions */
+#define TX_END_OF_RING (1 << 21)
+#define RX_END_OF_RING (1 << 15)
+
+#define NO_OF_TX_DESC 8
+#define NO_OF_RX_DESC PKTBUFSRX
+#define MAX_WAIT 1000
+
+#define CACHE_LINE_SIZE (CONFIG_SYS_CACHELINE_SIZE)
+
+#define VLAN_ETH_FRAME_LEN 1518
+#define ETH_ZLEN 60
+#define ETH_HLEN 12
+#define ETH_FCS_LEN 4
+#define VLAN_HLEN 4
+#define NET_IP_ALIGN 2
+
+#define ETHERNET_EXTRA (NET_IP_ALIGN + 2 * CACHE_LINE_SIZE)
+#define ETH_MAX_FRAME_LEN (VLAN_ETH_FRAME_LEN + \
+ ETH_FCS_LEN + \
+ ((4 - NET_IP_ALIGN) & 0x3))
+typedef struct
+{
+ volatile u32 status; /* Status */
+ volatile u32 length; /* Buffer 1 and Buffer 2 length */
+ volatile u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */
+ volatile u32 data1; /* This holds virtual address of buffer1, not used by DMA */
+ /* Following is used only by driver */
+ volatile u32 extstatus; /* Extended status of a Rx Descriptor */
+ volatile u32 reserved1; /* Reserved word */
+ volatile u32 timestamplow; /* Lower 32 bits of the 64 bit timestamp value */
+ volatile u32 timestamphigh; /* Higher 32 bits of the 64 bit timestamp value */
+} ipq_gmac_desc_t ;
+
+#define IPQ5018_GMAC_PORT 2
+#define IPQ5018_PHY_MAX 1
+
+struct ipq_eth_dev {
+ uint phy_address;
+ uint no_of_phys;
+ uint interface;
+ uint sw_configured;
+ uint speed;
+ uint duplex;
+ uint phy_configured;
+ uint mac_unit;
+ uint phy_type;
+ uint mac_ps;
+ uint ipq_swith;
+ uint phy_external_link;
+ int link_printed;
+ u32 padding;
+ ipq_gmac_desc_t *desc_tx[NO_OF_TX_DESC];
+ ipq_gmac_desc_t *desc_rx[NO_OF_RX_DESC];
+ uint next_tx;
+ uint next_rx;
+ int txdesc_count;
+ int rxdesc_count;
+ struct eth_mac_regs *mac_regs_p;
+ struct eth_dma_regs *dma_regs_p;
+ struct eth_device *dev;
+ struct phy_ops *ops;
+ const char phy_name[MDIO_NAME_LEN];
+ struct ipq_forced_mode *forced_params;
+ ipq_gmac_board_cfg_t *gmac_board_cfg;
+} __attribute__ ((aligned(8)));
+
+struct eth_mac_regs {
+ u32 conf; /* 0x00 */
+ u32 framefilt; /* 0x04 */
+ u32 hashtablehigh; /* 0x08 */
+ u32 hashtablelow; /* 0x0c */
+ u32 miiaddr; /* 0x10 */
+ u32 miidata; /* 0x14 */
+ u32 flowcontrol; /* 0x18 */
+ u32 vlantag; /* 0x1c */
+ u32 version; /* 0x20 */
+ u8 reserved_1[20]; /* 0x24 -- 0x37 */
+ u32 intreg; /* 0x38 */
+ u32 intmask; /* 0x3c */
+ u32 macaddr0hi; /* 0x40 */
+ u32 macaddr0lo; /* 0x44 */
+};
+
+struct eth_dma_regs {
+ u32 busmode; /* 0x00 */
+ u32 txpolldemand; /* 0x04 */
+ u32 rxpolldemand; /* 0x08 */
+ u32 rxdesclistaddr; /* 0x0c */
+ u32 txdesclistaddr; /* 0x10 */
+ u32 status; /* 0x14 */
+ u32 opmode; /* 0x18 */
+ u32 intenable; /* 0x1c */
+ u8 reserved[40]; /* 0x20 -- 0x47 */
+ u32 currhosttxdesc; /* 0x48 */
+ u32 currhostrxdesc; /* 0x4c */
+ u32 currhosttxbuffaddr; /* 0x50 */
+ u32 currhostrxbuffaddr; /* 0x54 */
+};
+
+void gmac_reset(void);
+void gmacsec_reset(void);
+void ipq_gmac_common_init(ipq_gmac_board_cfg_t *cfg);
+int ipq_gmac_init(ipq_gmac_board_cfg_t *cfg);
+
+enum DmaDescriptorStatus { /* status word of DMA descriptor */
+ DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */
+
+ DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */
+
+ DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */
+ DescFrameLengthShift = 16,
+
+ DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */
+ /* DE || OE || IPC || LC || RWT || RE || CE */
+ DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */
+ DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */
+ DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */
+ DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */
+ DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */
+ DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */
+ DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */
+ DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */
+ DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */
+ DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
+ DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */
+ DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */
+ DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */
+ DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */
+
+ DescRxEXTsts = 0x00000001, /* Extended Status Available (RDES4) 0 */
+
+ DescTxIntEnable = 0x40000000, /* (IC)Tx - interrupt on completion 30 */
+ DescTxLast = 0x20000000, /* (LS)Tx - Last segment of the frame 29 */
+ DescTxFirst = 0x10000000, /* (FS)Tx - First segment of the frame 28 */
+ DescTxDisableCrc = 0x08000000, /* (DC)Tx - Add CRC disabled (first segment only) 27 */
+ DescTxDisablePadd = 0x04000000, /* (DP)disable padding, added by - reyaz 26 */
+
+ DescTxCisMask = 0x00c00000, /* Tx checksum offloading control mask 23:22 */
+ DescTxCisBypass = 0x00000000, /* Checksum bypass */
+ DescTxCisIpv4HdrCs = 0x00400000, /* IPv4 header checksum */
+ DescTxCisTcpOnlyCs = 0x00800000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present*/
+ DescTxCisTcpPseudoCs = 0x00c00000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */
+
+ TxDescEndOfRing = 0x00200000, /* (TER)End of descriptors ring 21 */
+ TxDescChain = 0x00100000, /* (TCH)Second buffer address is chain address 20 */
+
+ DescRxChkBit0 = 0x00000001, /* () Rx - Rx Payload Checksum Error 0 */
+ DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */
+ DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
+
+ DescRxTSavail = 0x00000080, /* Time stamp available 7 */
+ DescRxFrameType = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
+
+ DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */
+ DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */
+ DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */
+ DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */
+ DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */
+ DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */
+ DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */
+ DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */
+ DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */
+
+ DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */
+ DescTxCollShift = 3,
+
+ DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */
+ DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */
+ DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */
+
+ /*
+ * This explains the RDES1/TDES1 bits layout
+ * ------------------------------------------------------------------------
+ * RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 |
+ * ------------------------------------------------------------------------
+ */
+ /* DmaDescriptorLength length word of DMA descriptor */
+
+
+ RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */
+ RxDescEndOfRing = 0x00008000, /* (TER)End of descriptors ring 15 */
+ RxDescChain = 0x00004000, /* (TCH)Second buffer address is chain address 14 */
+
+ /* DescSize2Mask = 0x1FFF0000, */ /* (TBS2) Buffer 2 size 28:16 */
+ /* DescSize2Shift = 16, */
+ DescSize1Mask = 0x00001FFF, /* (TBS1) Buffer 1 size 12:0 */
+ DescSize1Shift = 0,
+
+
+ /*
+ * This explains the RDES4 Extended Status bits layout
+ * ----------------------------------------------------------------------
+ * RDES4 | Extended Status |
+ * ----------------------------------------------------------------------
+ */
+ DescRxPtpAvail = 0x00004000, /* PTP snapshot available 14 */
+ DescRxPtpVer = 0x00002000, /* When set indicates IEEE1584 Version 2 (else Ver1) 13 */
+ DescRxPtpFrameType = 0x00001000, /* PTP frame type Indicates PTP sent over ethernet 12 */
+ DescRxPtpMessageType = 0x00000F00, /* Message Type 11:8 */
+ DescRxPtpNo = 0x00000000, /* 0000 => No PTP message received */
+ DescRxPtpSync = 0x00000100, /* 0001 => Sync (all clock types) received */
+ DescRxPtpFollowUp = 0x00000200, /* 0010 => Follow_Up (all clock types) received */
+ DescRxPtpDelayReq = 0x00000300, /* 0011 => Delay_Req (all clock types) received */
+ DescRxPtpDelayResp = 0x00000400, /* 0100 => Delay_Resp (all clock types) received */
+ DescRxPtpPdelayReq = 0x00000500, /* 0101 => Pdelay_Req (in P to P tras clk) or Announce in Ord and Bound clk */
+ DescRxPtpPdelayResp = 0x00000600, /* 0110 => Pdealy_Resp(in P to P trans clk) or Management in Ord and Bound clk */
+ DescRxPtpPdelayRespFP = 0x00000700, /* 0111 => Pdealy_Resp_Follow_Up (in P to P trans clk) or Signaling in Ord and Bound clk */
+ DescRxPtpIPV6 = 0x00000080, /* Received Packet is in IPV6 Packet 7 */
+ DescRxPtpIPV4 = 0x00000040, /* Received Packet is in IPV4 Packet 6 */
+
+ DescRxChkSumBypass = 0x00000020, /* When set indicates checksum offload engine 5
+ * is bypassed */
+ DescRxIpPayloadError = 0x00000010, /* When set indicates 16bit IP payload CS is in error 4 */
+ DescRxIpHeaderError = 0x00000008, /* When set indicates 16bit IPV4 header CS is in 3
+ * error or IP datagram version is not consistent
+ * with Ethernet type value */
+ DescRxIpPayloadType = 0x00000007, /* Indicate the type of payload encapsulated 2:0
+ * in IPdatagram processed by COE (Rx) */
+ DescRxIpPayloadUnknown = 0x00000000, /* Unknown or didnot process IP payload */
+ DescRxIpPayloadUDP = 0x00000001, /* UDP */
+ DescRxIpPayloadTCP = 0x00000002, /* TCP */
+ DescRxIpPayloadICMP = 0x00000003, /* ICMP */
+
+};
+
+/**********************************************************
+ * GMAC DMA registers
+ * For Pci based system address is BARx + GmaDmaBase
+ * For any other system translation is done accordingly
+ **********************************************************/
+
+enum DmaRegisters
+{
+ DmaBusMode = 0x0000, /* CSR0 - Bus Mode Register */
+ DmaTxPollDemand = 0x0004, /* CSR1 - Transmit Poll Demand Register */
+ DmaRxPollDemand = 0x0008, /* CSR2 - Receive Poll Demand Register */
+ DmaRxBaseAddr = 0x000C, /* CSR3 - Receive Descriptor list base address */
+ DmaTxBaseAddr = 0x0010, /* CSR4 - Transmit Descriptor list base address */
+ DmaStatus = 0x0014, /* CSR5 - Dma status Register */
+ DmaControl = 0x0018, /* CSR6 - Dma Operation Mode Register */
+ DmaInterrupt = 0x001C, /* CSR7 - Interrupt enable */
+ DmaMissedFr = 0x0020, /* CSR8 - Missed Frame & Buffer overflow Counter*/
+ DmaTxCurrDesc = 0x0048, /* - Current host Tx Desc Register */
+ DmaRxCurrDesc = 0x004C, /* - Current host Rx Desc Register */
+ DmaTxCurrAddr = 0x0050, /* CSR20- Current host transmit buffer address */
+ DmaRxCurrAddr = 0x0054, /* CSR21- Current host receive buffer address */
+};
+
+/**********************************************************
+ * DMA Engine registers Layout
+ **********************************************************/
+
+/* DmaBusMode = 0x0000, CSR0 - Bus Mode */
+enum DmaBusModeReg
+{ /* Bit description Bits R/W Reset value */
+ DmaFixedBurstEnable = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, INCR8 or INCR16 16 RW */
+ DmaFixedBurstDisable = 0x00000000, /* SINGLE, INCR 0 */
+ DmaTxPriority = 0x08000000,
+
+ DmaTxPriorityRatio11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 15:14 RW 00 */
+ DmaTxPriorityRatio21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */
+ DmaTxPriorityRatio31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */
+ DmaTxPriorityRatio41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */
+
+ DmaBurstLengthx8 = 0x01000000, /* When set mutiplies the PBL by 8 24 RW 0 */
+
+ DmaBurstLength256 = 0x01002000, /*(DmaBurstLengthx8 | DmaBurstLength32) = 256 [24] 13:8 */
+ DmaBurstLength128 = 0x01001000, /*(DmaBurstLengthx8 | DmaBurstLength16) = 128 [24] 13:8 */
+ DmaBurstLength64 = 0x01000800, /*(DmaBurstLengthx8 | DmaBurstLength8) = 64 [24] 13:8 */
+ DmaBurstLength32 = 0x00002000, /* (PBL) programmable Dma burst length = 32 13:8 RW */
+ DmaBurstLength16 = 0x00001000, /* Dma burst length = 16 */
+ DmaBurstLength8 = 0x00000800, /* Dma burst length = 8 */
+ DmaBurstLength4 = 0x00000400, /* Dma burst length = 4 */
+ DmaBurstLength2 = 0x00000200, /* Dma burst length = 2 */
+ DmaBurstLength1 = 0x00000100, /* Dma burst length = 1 */
+ DmaBurstLength0 = 0x00000000, /* Dma burst length = 0 00 */
+
+ DmaDescriptor8Words = 0x00000080, /* Enh Descriptor works 1 => 8 word descriptor 7 0 */
+ DmaDescriptor4Words = 0x00000000, /* Enh Descriptor works 0 => 4 word descriptor 7 0 */
+
+ DmaDescriptorSkip16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) 6:2 RW */
+ DmaDescriptorSkip8 = 0x00000020, /* between two unchained descriptors */
+ DmaDescriptorSkip4 = 0x00000010,
+ DmaDescriptorSkip2 = 0x00000008,
+ DmaDescriptorSkip1 = 0x00000004,
+ DmaDescriptorSkip0 = 0x00000000,
+
+ DmaArbitRr = 0x00000000, /* (DA) DMA RR arbitration 1 RW 0 */
+ DmaArbitPr = 0x00000002, /* Rx has priority over Tx */
+
+ DmaResetOn = 0x00000001, /* (SWR)Software Reset DMA engine 0 RW */
+ DmaResetOff = 0x00000000, /* 0 */
+};
+
+/* DmaStatus = 0x0014, CSR5 - Dma status Register */
+enum DmaStatusReg
+{
+ /* Bit 28 27 and 26 indicate whether the interrupt due to PMT GMACMMC or GMAC LINE Remaining bits are DMA interrupts */
+ GmacPmtIntr = 0x10000000, /* (GPI)Gmac subsystem interrupt 28 RO 0 */
+ GmacMmcIntr = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt 27 RO 0 */
+ GmacLineIntfIntr = 0x04000000, /* Line interface interrupt 26 RO 0 */
+
+ DmaErrorBit2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc. access 25 RO 0 */
+ DmaErrorBit1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfr 24 RO 0 */
+ DmaErrorBit0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA 23 RO 0 */
+
+ DmaTxState = 0x00700000, /* (TS)Transmit process state 22:20 RO */
+ DmaTxStopped = 0x00000000, /* Stopped - Reset or Stop Tx Command issued 000 */
+ DmaTxFetching = 0x00100000, /* Running - fetching the Tx descriptor */
+ DmaTxWaiting = 0x00200000, /* Running - waiting for status */
+ DmaTxReading = 0x00300000, /* Running - reading the data from host memory */
+ DmaTxSuspended = 0x00600000, /* Suspended - Tx Descriptor unavailabe */
+ DmaTxClosing = 0x00700000, /* Running - closing Rx descriptor */
+
+ DmaRxState = 0x000E0000, /* (RS)Receive process state 19:17 RO */
+ DmaRxStopped = 0x00000000, /* Stopped - Reset or Stop Rx Command issued 000 */
+ DmaRxFetching = 0x00020000, /* Running - fetching the Rx descriptor */
+ DmaRxWaiting = 0x00060000, /* Running - waiting for packet */
+ DmaRxSuspended = 0x00080000, /* Suspended - Rx Descriptor unavailable */
+ DmaRxClosing = 0x000A0000, /* Running - closing descriptor */
+ DmaRxQueuing = 0x000E0000, /* Running - queuing the recieve frame into host memory */
+
+ DmaIntNormal = 0x00010000, /* (NIS)Normal interrupt summary 16 RW 0 */
+ DmaIntAbnormal = 0x00008000, /* (AIS)Abnormal interrupt summary 15 RW 0 */
+
+ DmaIntEarlyRx = 0x00004000, /* Early receive interrupt (Normal) RW 0 */
+ DmaIntBusError = 0x00002000, /* Fatal bus error (Abnormal) RW 0 */
+ DmaIntEarlyTx = 0x00000400, /* Early transmit interrupt (Abnormal) RW 0 */
+ DmaIntRxWdogTO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) RW 0 */
+ DmaIntRxStopped = 0x00000100, /* Receive process stopped (Abnormal) RW 0 */
+ DmaIntRxNoBuffer = 0x00000080, /* Receive buffer unavailable (Abnormal) RW 0 */
+ DmaIntRxCompleted = 0x00000040, /* Completion of frame reception (Normal) RW 0 */
+ DmaIntTxUnderflow = 0x00000020, /* Transmit underflow (Abnormal) RW 0 */
+ DmaIntRcvOverflow = 0x00000010, /* Receive Buffer overflow interrupt RW 0 */
+ DmaIntTxJabberTO = 0x00000008, /* Transmit Jabber Timeout (Abnormal) RW 0 */
+ DmaIntTxNoBuffer = 0x00000004, /* Transmit buffer unavailable (Normal) RW 0 */
+ DmaIntTxStopped = 0x00000002, /* Transmit process stopped (Abnormal) RW 0 */
+ DmaIntTxCompleted = 0x00000001, /* Transmit completed (Normal) RW 0 */
+};
+
+/* DmaControl = 0x0018, CSR6 - Dma Operation Mode Register */
+enum DmaControlReg
+{
+ DmaDisableDropTcpCs = 0x04000000, /* (DT) Dis. drop. of tcp/ip CS error frames 26 RW 0 */
+
+ DmaStoreAndForward = 0x00200000, /* (SF)Store and forward 21 RW 0 */
+ DmaFlushTxFifo = 0x00100000, /* (FTF)Tx FIFO controller is reset to default 20 RW 0 */
+
+ DmaTxThreshCtrl = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16:14 RW */
+ DmaTxThreshCtrl16 = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16 16:14 RW */
+ DmaTxThreshCtrl24 = 0x00018000, /* (TTC)Controls thre Threh of MTL tx Fifo 24 16:14 RW */
+ DmaTxThreshCtrl32 = 0x00014000, /* (TTC)Controls thre Threh of MTL tx Fifo 32 16:14 RW */
+ DmaTxThreshCtrl40 = 0x00010000, /* (TTC)Controls thre Threh of MTL tx Fifo 40 16:14 RW */
+ DmaTxThreshCtrl256 = 0x0000c000, /* (TTC)Controls thre Threh of MTL tx Fifo 256 16:14 RW */
+ DmaTxThreshCtrl192 = 0x00008000, /* (TTC)Controls thre Threh of MTL tx Fifo 192 16:14 RW */
+ DmaTxThreshCtrl128 = 0x00004000, /* (TTC)Controls thre Threh of MTL tx Fifo 128 16:14 RW */
+ DmaTxThreshCtrl64 = 0x00000000, /* (TTC)Controls thre Threh of MTL tx Fifo 64 16:14 RW 000 */
+
+ DmaTxStart = 0x00002000, /* (ST)Start/Stop transmission 13 RW 0 */
+
+ DmaRxFlowCtrlDeact = 0x00401800, /* (RFD)Rx flow control deact. threhold [22] 12:11 RW */
+ DmaRxFlowCtrlDeact1K = 0x00000000, /* (RFD)Rx flow control deact. threhold (1kbytes) [22] 12:11 RW 00 */
+ DmaRxFlowCtrlDeact2K = 0x00000800, /* (RFD)Rx flow control deact. threhold (2kbytes) [22] 12:11 RW */
+ DmaRxFlowCtrlDeact3K = 0x00001000, /* (RFD)Rx flow control deact. threhold (3kbytes) [22] 12:11 RW */
+ DmaRxFlowCtrlDeact4K = 0x00001800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22] 12:11 RW */
+ DmaRxFlowCtrlDeact5K = 0x00400000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22] 12:11 RW */
+ DmaRxFlowCtrlDeact6K = 0x00400800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22] 12:11 RW */
+ DmaRxFlowCtrlDeact7K = 0x00401000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22] 12:11 RW */
+
+ DmaRxFlowCtrlAct = 0x00800600, /* (RFA)Rx flow control Act. threshold [23] 10:09 RW */
+ DmaRxFlowCtrlAct1K = 0x00000000, /* (RFA)Rx flow control Act. threshold (1kbytes) [23] 10:09 RW 00 */
+ DmaRxFlowCtrlAct2K = 0x00000200, /* (RFA)Rx flow control Act. threshold (2kbytes) [23] 10:09 RW */
+ DmaRxFlowCtrlAct3K = 0x00000400, /* (RFA)Rx flow control Act. threshold (3kbytes) [23] 10:09 RW */
+ DmaRxFlowCtrlAct4K = 0x00000600, /* (RFA)Rx flow control Act. threshold (4kbytes) [23] 10:09 RW */
+ DmaRxFlowCtrlAct5K = 0x00800000, /* (RFA)Rx flow control Act. threshold (5kbytes) [23] 10:09 RW */
+ DmaRxFlowCtrlAct6K = 0x00800200, /* (RFA)Rx flow control Act. threshold (6kbytes) [23] 10:09 RW */
+ DmaRxFlowCtrlAct7K = 0x00800400, /* (RFA)Rx flow control Act. threshold (7kbytes) [23] 10:09 RW */
+
+ DmaRxThreshCtrl = 0x00000018, /* (RTC)Controls thre Threh of MTL rx Fifo 4:3 RW */
+ DmaRxThreshCtrl64 = 0x00000000, /* (RTC)Controls thre Threh of MTL tx Fifo 64 4:3 RW */
+ DmaRxThreshCtrl32 = 0x00000008, /* (RTC)Controls thre Threh of MTL tx Fifo 32 4:3 RW */
+ DmaRxThreshCtrl96 = 0x00000010, /* (RTC)Controls thre Threh of MTL tx Fifo 96 4:3 RW */
+ DmaRxThreshCtrl128 = 0x00000018, /* (RTC)Controls thre Threh of MTL tx Fifo 128 4:3 RW */
+
+ DmaEnHwFlowCtrl = 0x00000100, /* (EFC)Enable HW flow control 8 RW */
+ DmaDisHwFlowCtrl = 0x00000000, /* Disable HW flow control 0 */
+
+ DmaFwdErrorFrames = 0x00000080, /* (FEF)Forward error frames 7 RW 0 */
+ DmaFwdUnderSzFrames = 0x00000040, /* (FUF)Forward undersize frames 6 RW 0 */
+ DmaTxSecondFrame = 0x00000004, /* (OSF)Operate on second frame 4 RW 0 */
+ DmaRxStart = 0x00000002, /* (SR)Start/Stop reception 1 RW 0 */
+};
+
+/* GmacFlowControl = 0x0018, Flow control Register Layout */
+enum GmacFlowControlReg
+{
+ GmacPauseTimeMask = 0xFFFF0000, /* (PT) PAUSE TIME field in the control frame 31:16 RW 0000 */
+ GmacPauseTimeShift = 16,
+ DmaDisableFlushRxFrames = 0x01000000,
+
+ GmacPauseLowThresh = 0x00000030,
+ GmacPauseLowThresh3 = 0x00000030, /* (PLT)thresh for pause tmr 256 slot time 5:4 RW */
+ GmacPauseLowThresh2 = 0x00000020, /* 144 slot time */
+ GmacPauseLowThresh1 = 0x00000010, /* 28 slot time */
+ GmacPauseLowThresh0 = 0x00000000, /* 4 slot time 000 */
+
+ GmacUnicastPauseFrame = 0x00000008,
+ GmacUnicastPauseFrameOn = 0x00000008, /* (UP)Detect pause frame with unicast addr. 3 RW */
+ GmacUnicastPauseFrameOff = 0x00000000, /* Detect only pause frame with multicast addr. 0 */
+
+ GmacRxFlowControl = 0x00000004,
+ GmacRxFlowControlEnable = 0x00000004, /* (RFE)Enable Rx flow control 2 RW */
+ GmacRxFlowControlDisable = 0x00000000, /* Disable Rx flow control 0 */
+
+ GmacTxFlowControl = 0x00000002,
+ GmacTxFlowControlEnable = 0x00000002, /* (TFE)Enable Tx flow control 1 RW */
+ GmacTxFlowControlDisable = 0x00000000, /* Disable flow control 0 */
+
+ GmacFlowControlBackPressure = 0x00000001,
+ GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */
+};
+
+#endif
+
diff --git a/arch/arm/include/asm/arch-ipq6018/clk.h b/arch/arm/include/asm/arch-ipq6018/clk.h
index 5d545d4..e33a064 100644
--- a/arch/arm/include/asm/arch-ipq6018/clk.h
+++ b/arch/arm/include/asm/arch-ipq6018/clk.h
@@ -14,6 +14,8 @@
#ifndef IPQ6018_CLK_H
#define IPQ6018_CLK_H
+#include <asm/arch-qca-common/uart.h>
+
/* I2C clocks configuration */
#ifdef CONFIG_IPQ6018_I2C
@@ -31,4 +33,42 @@
void i2c_clock_config(void);
#endif
+#define GCC_BLSP1_UART1_BCR 0x1802038
+#define GCC_BLSP1_UART2_BCR 0x1803028
+#define GCC_BLSP1_UART3_BCR 0x1804028
+#define GCC_BLSP1_UART4_BCR 0x1805028
+#define GCC_BLSP1_UART5_BCR 0x1806028
+#define GCC_BLSP1_UART6_BCR 0x1807028
+
+#define GCC_BLSP1_UART_BCR(id) ((id < 1) ? \
+ (GCC_BLSP1_UART1_BCR):\
+ (GCC_BLSP1_UART1_BCR + (0x1000 * id) - 0x10))
+
+#define GCC_BLSP1_UART_APPS_CBCR(id) (GCC_BLSP1_UART_BCR(id) + 0x04)
+#define GCC_BLSP1_UART_APPS_CMD_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x0C)
+#define GCC_BLSP1_UART_APPS_CFG_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x10)
+#define GCC_BLSP1_UART_APPS_M(id) (GCC_BLSP1_UART_BCR(id) + 0x14)
+#define GCC_BLSP1_UART_APPS_N(id) (GCC_BLSP1_UART_BCR(id) + 0x18)
+#define GCC_BLSP1_UART_APPS_D(id) (GCC_BLSP1_UART_BCR(id) + 0x1C)
+
+#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000
+#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700
+#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F
+
+#define GCC_UART_CFG_RCGR_MODE_SHIFT 12
+#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8
+#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0
+
+#define UART_RCGR_SRC_SEL 0x1
+#define UART_RCGR_SRC_DIV 0x0
+#define UART_RCGR_MODE 0x2
+#define UART_CMD_RCGR_UPDATE 0x1
+#define UART_CBCR_CLK_ENABLE 0x1
+
+#define NOT_2D(two_d) (~two_d)
+#define NOT_N_MINUS_M(n,m) (~(n - m))
+#define CLOCK_UPDATE_TIMEOUT_US 1000
+
+int uart_clock_config(struct ipq_serial_platdata *plat);
+
#endif /*IPQ6018_CLK_H*/
diff --git a/arch/arm/include/asm/arch-qca-common/qca_common.h b/arch/arm/include/asm/arch-qca-common/qca_common.h
index 534abc6..9f39f7e 100644
--- a/arch/arm/include/asm/arch-qca-common/qca_common.h
+++ b/arch/arm/include/asm/arch-qca-common/qca_common.h
@@ -107,6 +107,7 @@
int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg);
int is_secondary_core_off(unsigned int cpuid);
int smem_read_cpu_count(void);
+int get_soc_hw_version(void);
struct dumpinfo_t{
char name[16]; /* use only file name in 8.3 format */
diff --git a/arch/arm/include/asm/arch-qca-common/qpic_nand.h b/arch/arm/include/asm/arch-qca-common/qpic_nand.h
index 642c3bd..5a5c7b2 100644
--- a/arch/arm/include/asm/arch-qca-common/qpic_nand.h
+++ b/arch/arm/include/asm/arch-qca-common/qpic_nand.h
@@ -112,6 +112,7 @@
#define NAND_FLASH_SPI_CFG NAND_REG(0x70C0)
#define NAND_SPI_NUM_ADDR_CYCLES NAND_REG(0x70C4)
#define NAND_SPI_BUSY_CHECK_WAIT_CNT NAND_REG(0x70C8)
+#define NAND_QSPI_MSTR_CONFIG NAND_REG(0x7f60)
/* Register mask & shift value used in SPI transfer mode */
#define SPI_TRANSFER_MODE_1X 0x1
@@ -280,6 +281,7 @@
*/
#define FLASH_SPI_NAND_FR_ADDR 0xB0
#define FLASH_SPI_NAND_FR_ECC_ENABLE (1 << 4)
+#define FLASH_SPI_NAND_FR_BUFF_ENABLE (1 << 3)
#define FLASH_SPI_NAND_FR_QUAD_ENABLE 0x1
/* According to GigaDevice data sheet Status Register(0xC0) is:
* _________________________________________________
@@ -559,6 +561,7 @@
QCA_QPIC_V2_1_1,
};
+extern unsigned int qpic_frequency, qpic_phase;
/* result type */
typedef enum {
diff --git a/arch/arm/include/asm/arch-qca-common/scm.h b/arch/arm/include/asm/arch-qca-common/scm.h
index 4bbe13f..fa7024e 100644
--- a/arch/arm/include/asm/arch-qca-common/scm.h
+++ b/arch/arm/include/asm/arch-qca-common/scm.h
@@ -21,6 +21,7 @@
#define SCM_SVC_SSD 0x7
#define SCM_SVC_FUSE 0x8
#define SCM_SVC_PWR 0x9
+#define SCM_SVC_CRYPTO 0xA
#define SCM_SVC_CP 0xC
#define SCM_SVC_DCVS 0xD
#define SCM_SVC_TZSCHEDULER 0xFC
@@ -33,6 +34,12 @@
#define SCM_SVC_ID_SHIFT 0xA
#define IS_CALL_AVAIL_CMD 0x1
+#ifdef CONFIG_IPQ_BT_SUPPORT
+#define SCM_PAS_INIT_IMAGE_CMD 0x1
+#define SCM_PAS_AUTH_AND_RESET_CMD 0x5
+#define SCM_CMD_OTP 0x15
+#endif
+
/* scm_v8 */
#define SCM_VAL 0x0
#define SCM_IO_READ 0x1
@@ -117,6 +124,7 @@
int qca_scm_usb_mode_write(u32, u32);
int qca_scm_call_write(u32, u32, u32 *, u32);
int qca_scm_call_read(u32, u32, u32 *, u32 *);
+int qca_scm_crypto(int, void *, u32);
int qca_scm_sdi(void);
int qca_scm_dload(u32);
int qca_scm_fuseipq(u32, u32, void *, size_t);
@@ -128,6 +136,11 @@
#ifdef CONFIG_IPQ_TZT
int qca_scm(u32 svc_id, u32 cmd_id, u32 ownr_id, u32 *addr, u32 len);
#endif
+#ifdef CONFIG_IPQ_BT_SUPPORT
+int qti_scm_otp(u32 peripheral);
+int qti_scm_pas_init_image(u32 peripheral, u32 addr);
+int qti_pas_and_auth_reset(u32 peripheral);
+#endif
#define MAX_QCA_SCM_RETS 3
#define MAX_QCA_SCM_ARGS 10
#define SCM_READ_OP 1
diff --git a/arch/arm/include/asm/arch-qca-common/smem.h b/arch/arm/include/asm/arch-qca-common/smem.h
index 3eaf6da..17b2ae5 100644
--- a/arch/arm/include/asm/arch-qca-common/smem.h
+++ b/arch/arm/include/asm/arch-qca-common/smem.h
@@ -61,6 +61,7 @@
uint32_t *flash_block_size,
uint32_t *flash_density);
int smem_getpart(char *name, uint32_t *start, uint32_t *size);
+int smem_getpart_from_offset(uint32_t offset, uint32_t *start, uint32_t *size);
int getpart_offset_size(char *part_name, uint32_t *offset, uint32_t *size);
unsigned int smem_get_board_machtype(void);
uint32_t get_nand_block_size(uint8_t dev_id);
diff --git a/arch/arm/include/asm/arch-qca-common/uart.h b/arch/arm/include/asm/arch-qca-common/uart.h
index f1c6474..cf9e839 100644
--- a/arch/arm/include/asm/arch-qca-common/uart.h
+++ b/arch/arm/include/asm/arch-qca-common/uart.h
@@ -88,6 +88,7 @@
int m_value;
int n_value;
int d_value;
+ int gpio_node;
};
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
index 0b35248..c92b76b 100644
--- a/arch/arm/include/asm/mach-types.h
+++ b/arch/arm/include/asm/mach-types.h
@@ -1142,7 +1142,18 @@
#define MACH_TYPE_IPQ40XX_AP_DK04_1_C6 0x8010501
#define MACH_TYPE_IPQ6018_AP_CP01_C1 0x8030000
#define MACH_TYPE_IPQ6018_AP_CP01_C2 0x8030001
+#define MACH_TYPE_IPQ6018_AP_CP01_C3 0x8030002
#define MACH_TYPE_IPQ6018_AP_CP01_C4 0x8030003
+#define MACH_TYPE_IPQ5018_AP_MP02_1 0x8040000
+#define MACH_TYPE_IPQ5018_DB_MP02_1 0X1040003
+#define MACH_TYPE_IPQ807x_AP_HK01_C1 0x8010000
+#define MACH_TYPE_IPQ807x_AP_HK01_C3 0x8010200
+#define MACH_TYPE_IPQ807x_AP_AC01 0x8010009
+#define MACH_TYPE_IPQ807x_AP_AC02 0x801000A
+#define MACH_TYPE_IPQ807x_AP_OAK03 0x801000D
+#define MACH_TYPE_IPQ807x_AP_HK01_C6 0x8010500
+#define MACH_TYPE_IPQ807x_AP_HK12_C1 0x8010013
+#define MACH_TYPE_IPQ807x_AP_HK10_C2 0x801010E
#ifdef CONFIG_ARCH_EBSA110
# ifdef machine_arch_type
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index f3db7b5..7a0fb58 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -6,7 +6,8 @@
#
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \
- _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o
+ _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o \
+ _uldivmod.o
ifdef CONFIG_CPU_V7M
obj-y += vectors_m.o crt0.o
diff --git a/board/ipq5018/Kconfig b/board/ipq5018/Kconfig
new file mode 100644
index 0000000..e1a56bc
--- /dev/null
+++ b/board/ipq5018/Kconfig
@@ -0,0 +1,54 @@
+if ARCH_IPQ5018
+
+config SYS_CPU
+ default "ipq5018"
+
+config SYS_BOARD
+ default "ipq5018"
+
+config SYS_VENDOR
+ default "qca/arm"
+
+config SYS_CONFIG_NAME
+ default "ipq5018"
+
+config IPQ5018_I2C
+ bool "Enable i2c support for ipq5018"
+
+config USB_XHCI_IPQ
+ bool "Enable usb support for ipq5018"
+
+config PCI_IPQ
+ bool "Enable pci support for ipq5018"
+
+config MMC_FLASH
+ bool "Enable MMC flash support for ipq5018"
+
+config IPQ_TZT
+ bool "Enable TZ test command for ipq5018"
+
+config UBI_WRITE
+ bool "Enable ubi volume write command for ipq5018"
+
+config QPIC_SERIAL
+ bool "Enable QPIC serial spi nand for ipq5018"
+
+config IPQ_TINY
+ bool "Enable Tiny support for ipq5018"
+
+config IPQ_MTD_NOR
+ bool "Register nor in MTD framework for ipq5018"
+
+config IPQ_TINY_SPI_NOR
+ bool "This config helps to update spi-nor related updated in ipq5018"
+
+config NAND_FLASH
+ bool "Enable NAND driver for ipq5018"
+
+config GEPHY
+ bool "Enable Internel GEPHY for ipq5018"
+
+config ART_COMPRESSED
+ bool "Enable uncompress support for ipq5018"
+
+endif
diff --git a/board/qca/arm/common/board_init.c b/board/qca/arm/common/board_init.c
index c4d932b..c0d994c 100644
--- a/board/qca/arm/common/board_init.c
+++ b/board/qca/arm/common/board_init.c
@@ -25,10 +25,11 @@
#include <cp_board.h>
#include <blkdev.h>
DECLARE_GLOBAL_DATA_PTR;
-
+#ifdef CONFIG_ENV_IS_IN_NAND
extern int nand_env_device;
extern env_t *nand_env_ptr;
extern char *nand_env_name_spec;
+#endif
extern char *sf_env_name_spec;
extern int nand_saveenv(void);
extern int sf_saveenv(void);
@@ -144,12 +145,16 @@
#ifndef CONFIG_ENV_IS_NOWHERE
switch (sfi->flash_type) {
+#ifdef CONFIG_ENV_IS_IN_NAND
case SMEM_BOOT_NAND_FLASH:
case SMEM_BOOT_QSPI_NAND_FLASH:
nand_env_device = CONFIG_NAND_FLASH_INFO_IDX;
break;
+#endif
case SMEM_BOOT_SPI_FLASH:
+#ifdef CONFIG_ENV_IS_IN_NAND
nand_env_device = CONFIG_SPI_FLASH_INFO_IDX;
+#endif
break;
case SMEM_BOOT_MMC_FLASH:
case SMEM_BOOT_NO_FLASH:
@@ -182,10 +187,12 @@
break;
#ifdef CONFIG_QCA_MMC
case SMEM_BOOT_MMC_FLASH:
- case SMEM_BOOT_NO_FLASH:
board_env_range = CONFIG_ENV_SIZE_MAX;
break;
#endif
+ case SMEM_BOOT_NO_FLASH:
+ board_env_range = CONFIG_ENV_SIZE_MAX;
+ break;
default:
printf("BUG: unsupported flash type : %d\n", sfi->flash_type);
BUG();
@@ -202,14 +209,22 @@
env_name_spec = mmc_env_name_spec;
#endif
} else {
+#ifdef CONFIG_ENV_IS_IN_NAND
saveenv = nand_saveenv;
env_ptr = nand_env_ptr;
env_name_spec = nand_env_name_spec;
+#else
+ saveenv = sf_saveenv;
+ env_name_spec = sf_env_name_spec;
+
+#endif
}
#endif
- ret = ipq_board_usb_init();
- if (ret < 0) {
- printf("WARN: ipq_board_usb_init failed\n");
+ if (sfi->flash_type != SMEM_BOOT_NO_FLASH) {
+ ret = ipq_board_usb_init();
+ if (ret < 0) {
+ printf("WARN: ipq_board_usb_init failed\n");
+ }
}
aquantia_phy_reset_init();
@@ -345,11 +360,17 @@
}
#endif
+__weak int get_soc_hw_version(void)
+{
+ return 0;
+}
+
int board_late_init(void)
{
unsigned int machid;
uint32_t flash_type;
uint32_t soc_ver_major, soc_ver_minor;
+ uint32_t soc_hw_version;
int ret;
char *s = NULL;
@@ -377,6 +398,10 @@
setenv_ulong("soc_version_major", (unsigned long)soc_ver_major);
setenv_ulong("soc_version_minor", (unsigned long)soc_ver_minor);
}
+
+ soc_hw_version = get_soc_hw_version();
+ if (soc_hw_version)
+ setenv_hex("soc_hw_version", (unsigned long)soc_hw_version);
#ifdef CONFIG_FLASH_PROTECT
board_flash_protect();
#endif
diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c
index 245786b..418e837 100644
--- a/board/qca/arm/common/cmd_bootqca.c
+++ b/board/qca/arm/common/cmd_bootqca.c
@@ -204,40 +204,54 @@
* or board name based config is used.
*/
+#ifdef CONFIG_ARCH_IPQ806x
int soc_version = 0;
+#endif
+ int i, strings_count;
const char *config = getenv("config_name");
if (config) {
printf("Manual device tree config selected!\n");
strlcpy(dtb_config_name, config, sizeof(dtb_config_name));
- } else {
- config = fdt_getprop(gd->fdt_blob, 0, "config_name", NULL);
+ if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) {
+ snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n",
+ addr, dtb_config_name);
+ return 0;
+ }
- if(config == NULL) {
+ } else {
+ strings_count = fdt_count_strings(gd->fdt_blob, 0, "config_name");
+
+ if (!strings_count) {
printf("Failed to get config_name\n");
return -1;
}
- snprintf((char *)dtb_config_name,
- sizeof(dtb_config_name), "%s", config);
+ for (i = 0; i < strings_count; i++) {
+ fdt_get_string_index(gd->fdt_blob, 0, "config_name",
+ i, &config);
- ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
+ snprintf((char *)dtb_config_name,
+ sizeof(dtb_config_name), "%s", config);
+
#ifdef CONFIG_ARCH_IPQ806x
- if(SOCINFO_VERSION_MAJOR(soc_version) >= 2) {
- snprintf(dtb_config_name + strlen("config@"),
- sizeof(dtb_config_name) - strlen("config@"),
- "v%d.0-%s",
- SOCINFO_VERSION_MAJOR(soc_version),
- config + strlen("config@"));
- }
+ ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
+ if(SOCINFO_VERSION_MAJOR(soc_version) >= 2) {
+ snprintf(dtb_config_name + strlen("config@"),
+ sizeof(dtb_config_name) - strlen("config@"),
+ "v%d.0-%s",
+ SOCINFO_VERSION_MAJOR(soc_version),
+ config + strlen("config@"));
+ }
#endif
+ if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) {
+ snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n",
+ addr, dtb_config_name);
+ return 0;
+ }
+ }
}
- if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) {
- snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n",
- addr, dtb_config_name);
- return 0;
- }
printf("Config not available\n");
snprintf(rcmd, rcmd_size, "bootm 0x%x\n", addr);
return 0;
@@ -473,6 +487,7 @@
kernel_img_info.kernel_load_addr = request;
if (ipq_fs_on_nand) {
+#ifdef CONFIG_CMD_UBI
/*
* The kernel will be available inside a UBI volume
*/
@@ -513,6 +528,7 @@
kernel_img_info.kernel_load_size =
(unsigned int)ubi_get_volume_size("kernel");
+#endif
#ifdef CONFIG_QCA_MMC
} else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH ||
((sfi->flash_type == SMEM_BOOT_SPI_FLASH) &&
diff --git a/board/qca/arm/common/cmd_runmulticore.c b/board/qca/arm/common/cmd_runmulticore.c
index e9e51a7..b175162 100644
--- a/board/qca/arm/common/cmd_runmulticore.c
+++ b/board/qca/arm/common/cmd_runmulticore.c
@@ -58,6 +58,16 @@
bring_secondary_core_down(state);
}
+static void disable_console(void)
+{
+ gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
+}
+
+static void enable_console(void)
+{
+ gd->flags &= ~(GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE);
+}
+
int do_runmulticore(cmd_tbl_t *cmdtp,
int flag, int argc, char *const argv[])
{
@@ -109,6 +119,7 @@
for (i = 1; i < argc; i++) {
printf("Scheduling Core %d\n", i);
delay = 0;
+ disable_console();
ret = bring_sec_core_up(i, (unsigned int)secondary_cpu_init,
(unsigned int)&(core[i - 1]));
if (ret) {
@@ -121,6 +132,7 @@
if (!(core[i - 1].cpu_up)) {
panic("Can't bringup core %d\n",i);
}
+ enable_console();
core_status |= (BIT(i - 1));
core_on_status |= (BIT(i - 1));
diff --git a/board/qca/arm/common/cmd_tzt.c b/board/qca/arm/common/cmd_tzt.c
index 4dc8d84..10e943f 100644
--- a/board/qca/arm/common/cmd_tzt.c
+++ b/board/qca/arm/common/cmd_tzt.c
@@ -117,6 +117,7 @@
u32 img_addr;
u32 img_size;
u32 args[MAX_QCA_SCM_ARGS + 1];
+ int ret;
/* at least two arguments should be there */
if (argc < 2)
@@ -133,15 +134,24 @@
args[0] = QCA_SCM_ARGS(2, SCM_IO_WRITE);
args[1] = TZT_LOAD_ADDR;
args[2] = TZT_LOAD_SIZE;
- qca_scm(SCM_SVC_APP_MGR, REGION_NOTIFICATION_ID,
+ ret = qca_scm(SCM_SVC_APP_MGR, REGION_NOTIFICATION_ID,
SCM_OWNR_QSEE_OS, args, 3);
+ if (ret) {
+ printf("tzt load failed ret = %d\n", ret);
+ return -1;
+ }
args[0] = QCA_SCM_ARGS(3);
args[1] = MDT_SIZE;
args[2] = img_size - MDT_SIZE;
args[3] = img_addr;
- qca_scm(SCM_SVC_EXTERNAL, LOAD_TZTESTEXEC_IMG_ID,
+ ret = qca_scm(SCM_SVC_EXTERNAL, LOAD_TZTESTEXEC_IMG_ID,
SCM_OWNR_QSEE_OS, args, 4);
+ if (ret) {
+ printf("tzt load failed ret = %d\n", ret);
+ return -1;
+ }
+
tzt_loaded = 1;
return 0;
}
diff --git a/board/qca/arm/common/crashdump.c b/board/qca/arm/common/crashdump.c
index a3efdfc..b7b4097 100644
--- a/board/qca/arm/common/crashdump.c
+++ b/board/qca/arm/common/crashdump.c
@@ -97,6 +97,8 @@
int cur_page_data_len;
int write_size;
unsigned char temp_data[MAX_NAND_PAGE_SIZE];
+ uint32_t part_start;
+ uint32_t part_size;
};
#ifdef CONFIG_QCA_SPI
@@ -118,8 +120,9 @@
};
#endif
-
+#ifdef CONFIG_MTD_DEVICE
static struct crashdump_flash_nand_cxt crashdump_nand_cnxt;
+#endif
#ifdef CONFIG_QCA_SPI
static struct spi_flash *crashdump_spi_flash;
static struct crashdump_flash_spi_cxt crashdump_flash_spi_cnxt;
@@ -275,13 +278,18 @@
while (static_enum_count < 3) {
ret_val = qca_wdt_scm_extract_tlv_info(scm_tlv_msg,
&cur_type, &cur_size);
- if (!ret_val && cur_type == QCA_WDT_LOG_DUMP_TYPE_UNAME ){
+ if (ret_val)
+ return ret_val;
+
+ switch (cur_type) {
+ case QCA_WDT_LOG_DUMP_TYPE_UNAME:
crashdump_data->uname_length = cur_size;
ret_val = qca_wdt_scm_extract_tlv_data(scm_tlv_msg,
crashdump_data->uname, cur_size);
crashdump_tlv_count++;
static_enum_count++;
- }else if (!ret_val && cur_type == QCA_WDT_LOG_DUMP_TYPE_DMESG){
+ break;
+ case QCA_WDT_LOG_DUMP_TYPE_DMESG:
ret_val = qca_wdt_scm_extract_tlv_data(scm_tlv_msg,
(unsigned char *)&tlv_info,
cur_size);
@@ -291,7 +299,8 @@
}
crashdump_tlv_count++;
static_enum_count++;
- }else if (!ret_val && cur_type == QCA_WDT_LOG_DUMP_TYPE_LEVEL1_PT){
+ break;
+ case QCA_WDT_LOG_DUMP_TYPE_LEVEL1_PT:
ret_val = qca_wdt_scm_extract_tlv_data(scm_tlv_msg,(unsigned char *)&tlv_info,cur_size);
if (!ret_val) {
crashdump_data->pt_start =(unsigned char *)(uintptr_t)tlv_info.start;
@@ -299,12 +308,18 @@
}
crashdump_tlv_count++;
static_enum_count++;
- }
- else if(!ret_val && cur_type == QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD) {
+ break;
+ case QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD:
tlv_size = (cur_size + QCA_WDT_SCM_TLV_TYPE_LEN_SIZE);
scm_tlv_msg->cur_msg_buffer_pos += tlv_size;
+ break;
+ default:
+ printf("%s: invalid dump type\n", __func__);
+ ret_val = -EINVAL;
+ goto err;
}
}
+err:
return ret_val;
}
@@ -714,8 +729,16 @@
printf("\nHit any key within 10s to stop dump activity...");
while (!tstc()) { /* while no incoming data */
if (get_timer_masked() >= etime) {
- if (do_dumpqca_data(dump_level) == CMD_RET_FAILURE)
- printf("Crashdump saving failed!\n");
+ if (getenv("dump_minimal_and_full")) {
+ /* dump minidump and full dump*/
+ if (do_dumpqca_data(MINIMAL_DUMP) == CMD_RET_FAILURE)
+ printf("Minidump saving failed!\n");
+ if (do_dumpqca_data(FULL_DUMP) == CMD_RET_FAILURE)
+ printf("Crashdump saving failed!\n");
+ } else {
+ if (do_dumpqca_data(dump_level) == CMD_RET_FAILURE)
+ printf("Crashdump saving failed!\n");
+ }
break;
}
}
@@ -726,6 +749,98 @@
reset:
reset_board();
}
+#ifdef CONFIG_MTD_DEVICE
+
+/*
+* NAND flash check and write. Before writing into the nand flash
+* this function checks if the block is non-bad, and skips if bad. While
+* skipping, there is also possiblity of crossing the partition and corrupting
+* next partition with crashdump data. So this function also checks whether
+* offset is within the partition, where the configured offset belongs.
+*
+* Returns 0 on succes and 1 otherwise
+*/
+static int check_and_write_crashdump_nand_flash(
+ struct crashdump_flash_nand_cxt *nand_cnxt,
+ nand_info_t *nand, unsigned char *data,
+ unsigned int req_size)
+{
+ nand_erase_options_t nand_erase_options;
+ uint32_t part_start = nand_cnxt->part_start;
+ uint32_t part_end = nand_cnxt->part_start + nand_cnxt->part_size;
+ unsigned int remaining_len = req_size;
+ unsigned int write_length, data_offset = 0;
+ loff_t skipoff, skipoff_cmp, *offset;
+ int ret = 0;
+ static int first_erase = 1;
+
+ offset = &nand_cnxt->cur_crashdump_offset;
+
+ memset(&nand_erase_options, 0, sizeof(nand_erase_options));
+ nand_erase_options.length = nand->erasesize;
+
+ while (remaining_len)
+ {
+
+ skipoff = *offset - (*offset & (nand->erasesize - 1));
+ skipoff_cmp = skipoff;
+
+ for (; skipoff < part_end; skipoff += nand->erasesize) {
+ if (nand_block_isbad(nand, skipoff)) {
+ printf("Skipping bad block at 0x%llx\n", skipoff);
+ continue;
+ }
+ else
+ break;
+ }
+ if (skipoff_cmp != skipoff)
+ *offset = skipoff;
+
+ if(part_start > *offset || ((*offset + remaining_len) >= part_end)) {
+ printf("Failure: Attempt to write in next partition\n");
+ return 1;
+ }
+
+ if((*offset & (nand->erasesize - 1)) == 0 || first_erase){
+ nand_erase_options.offset = *offset;
+
+ ret = nand_erase_opts(&nand_info[0],
+ &nand_erase_options);
+ if (ret)
+ return ret;
+ first_erase = 0;
+ }
+
+ if( remaining_len > nand->erasesize) {
+
+ skipoff = (*offset & (nand->erasesize - 1));
+
+ write_length = (skipoff != 0) ? (nand->erasesize - skipoff)
+ : (nand->erasesize);
+
+ ret = nand_write(nand, *offset, &write_length,
+ data + data_offset);
+
+ if (ret)
+ return ret;
+
+ remaining_len -= write_length;
+ *offset += write_length;
+ data_offset += write_length;
+ }
+ else {
+
+ ret = nand_write(nand, *offset, &remaining_len,
+ data + data_offset);
+
+ *offset += remaining_len;
+ remaining_len = 0;
+ }
+ }
+
+ return ret;
+
+}
/*
* Init function for NAND flash writing. It intializes its own context
@@ -734,10 +849,14 @@
int init_crashdump_nand_flash_write(void *cnxt, loff_t offset,
unsigned int total_size)
{
- nand_erase_options_t nand_erase_options;
struct crashdump_flash_nand_cxt *nand_cnxt = cnxt;
int ret;
+ ret = smem_getpart_from_offset(offset, &nand_cnxt->part_start,
+ &nand_cnxt->part_size);
+ if (ret)
+ return ret;
+
nand_cnxt->start_crashdump_offset = offset;
nand_cnxt->cur_crashdump_offset = offset;
nand_cnxt->cur_page_data_len = 0;
@@ -748,16 +867,6 @@
return -ENOMEM;
}
- memset(&nand_erase_options, 0, sizeof(nand_erase_options));
-
- nand_erase_options.length = total_size;
- nand_erase_options.offset = offset;
-
- ret = nand_erase_opts(&nand_info[0],
- &nand_erase_options);
- if (ret)
- return ret;
-
return 0;
}
@@ -782,9 +891,11 @@
0xFF, remaining_bytes);
cur_nand_write_len = nand_cnxt->write_size;
- ret_val = nand_write(&nand_info[0],
- nand_cnxt->cur_crashdump_offset,
- &cur_nand_write_len, nand_cnxt->temp_data);
+
+ ret_val = check_and_write_crashdump_nand_flash(nand_cnxt,
+ &nand_info[0], nand_cnxt->temp_data,
+ cur_nand_write_len);
+
}
return ret_val;
@@ -832,15 +943,14 @@
memcpy(nand_cnxt->temp_data + nand_cnxt->cur_page_data_len, data,
remaining_len_cur_page);
- ret_val = nand_write(&nand_info[0], nand_cnxt->cur_crashdump_offset,
- &cur_nand_write_len,
- nand_cnxt->temp_data);
+ ret_val = check_and_write_crashdump_nand_flash(nand_cnxt,
+ &nand_info[0], nand_cnxt->temp_data,
+ cur_nand_write_len);
if (ret_val)
return ret_val;
cur_data_pos += remaining_len_cur_page;
- nand_cnxt->cur_crashdump_offset += cur_nand_write_len;
/*
* Calculate the write length in multiple of page length and do the nand
@@ -850,17 +960,16 @@
nand_cnxt->write_size) * nand_cnxt->write_size;
if (cur_nand_write_len > 0) {
- ret_val = nand_write(&nand_info[0],
- nand_cnxt->cur_crashdump_offset,
- &cur_nand_write_len,
- cur_data_pos);
+ ret_val = check_and_write_crashdump_nand_flash(nand_cnxt,
+ &nand_info[0], cur_data_pos,
+ cur_nand_write_len);
if (ret_val)
return ret_val;
+
}
cur_data_pos += cur_nand_write_len;
- nand_cnxt->cur_crashdump_offset += cur_nand_write_len;
/* Store the remaining data in temp data */
remaining_bytes = data + size - cur_data_pos;
@@ -871,7 +980,7 @@
return 0;
}
-
+#endif
#ifdef CONFIG_QCA_SPI
/* Init function for SPI NOR flash writing. It erases the required sectors */
int init_crashdump_spi_flash_write(void *cnxt,
@@ -1113,11 +1222,13 @@
*/
if (((flash_type == SMEM_BOOT_NAND_FLASH) ||
(flash_type == SMEM_BOOT_QSPI_NAND_FLASH))) {
+#ifdef CONFIG_MTD_DEVICE
crashdump_cnxt = (void *)&crashdump_nand_cnxt;
crashdump_flash_write_init = init_crashdump_nand_flash_write;
crashdump_flash_write = crashdump_nand_flash_write_data;
crashdump_flash_write_deinit =
deinit_crashdump_nand_flash_write;
+#endif
#ifdef CONFIG_QCA_SPI
} else if (flash_type == SMEM_BOOT_SPI_FLASH) {
if (!crashdump_spi_flash) {
@@ -1227,22 +1338,24 @@
tlv_msg.len = CONFIG_TLV_DUMP_SIZE;
ret_val = qca_wdt_extract_crashdump_data(&tlv_msg, &g_crashdump_data);
-
- if (!ret_val) {
- if (getenv("dump_to_flash")) {
- ret_val = qca_wdt_write_crashdump_data(&g_crashdump_data,
- flash_type, crashdump_offset);
- } else {
- dump_func(MINIMAL_DUMP);
- }
- }
-
if (ret_val) {
- printf("crashdump data writing in flash failure\n");
- return -EPERM;
+ printf("%s: crashdump extraction failed\n", __func__);
+ return ret_val;
}
- printf("crashdump data writing in flash successful\n");
+ if (getenv("dump_to_flash")) {
+ ret_val = qca_wdt_write_crashdump_data(&g_crashdump_data,
+ flash_type,
+ crashdump_offset);
+ if (ret_val) {
+ printf("crashdump data writing in flash failure\n");
+ return -EPERM;
+ }
+
+ printf("crashdump data writing in flash successful\n");
+ } else {
+ dump_func(MINIMAL_DUMP);
+ }
return 0;
}
diff --git a/board/qca/arm/common/env.c b/board/qca/arm/common/env.c
index 3050b82..5fab9a5 100644
--- a/board/qca/arm/common/env.c
+++ b/board/qca/arm/common/env.c
@@ -18,10 +18,10 @@
#ifdef CONFIG_SDHCI_SUPPORT
#include <sdhci.h>
#endif
-
+#ifdef CONFIG_ENV_IS_IN_NAND
extern void nand_env_relocate_spec(void);
extern int nand_env_init(void);
-
+#endif
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
extern void sf_env_relocate_spec(void);
extern int sf_env_init(void);
@@ -58,7 +58,9 @@
ret = mmc_env_init();
#endif
} else {
+#ifdef CONFIG_ENV_IS_IN_NAND
ret = nand_env_init();
+#endif
}
return ret;
@@ -85,7 +87,9 @@
mmc_env_relocate_spec();
#endif
} else {
+#ifdef CONFIG_ENV_IS_IN_NAND
nand_env_relocate_spec();
+#endif
}
};
@@ -125,3 +129,27 @@
return ret;
}
#endif
+
+void set_platform_specific_default_env(void)
+{
+ uint32_t soc_ver_major, soc_ver_minor, soc_version;
+ uint32_t machid;
+ uint32_t soc_hw_version;
+ int ret;
+
+ machid = smem_get_board_platform_type();
+ if (machid != 0)
+ setenv_addr("machid", (void *)machid);
+
+ soc_hw_version = get_soc_hw_version();
+ if (soc_hw_version)
+ setenv_hex("soc_hw_version", (unsigned long)soc_hw_version);
+
+ ret = ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
+ if (!ret) {
+ soc_ver_major = SOCINFO_VERSION_MAJOR(soc_version);
+ soc_ver_minor = SOCINFO_VERSION_MINOR(soc_version);
+ setenv_ulong("soc_version_major", (unsigned long)soc_ver_major);
+ setenv_ulong("soc_version_minor", (unsigned long)soc_ver_minor);
+ }
+}
diff --git a/board/qca/arm/common/ethaddr.c b/board/qca/arm/common/ethaddr.c
index cd7af73..4809f4c 100644
--- a/board/qca/arm/common/ethaddr.c
+++ b/board/qca/arm/common/ethaddr.c
@@ -19,7 +19,18 @@
#include <asm/arch-qca-common/smem.h>
#include <asm/arch-qca-common/qca_common.h>
#include <sdhci.h>
-
+#ifdef CONFIG_IPQ_TINY_SPI_NOR
+#include <spi.h>
+#include <spi_flash.h>
+#endif
+#if defined(CONFIG_ART_COMPRESSED) && \
+ (defined(CONFIG_GZIP) || defined(CONFIG_LZMA))
+#ifndef CONFIG_COMPRESSED_LOAD_ADDR
+#define CONFIG_COMPRESSED_LOAD_ADDR CONFIG_SYS_LOAD_ADDR
+#endif
+#include <mapmem.h>
+#include <lzma/LzmaTools.h>
+#endif
#ifdef CONFIG_QCA_MMC
#ifndef CONFIG_SDHCI_SUPPORT
extern qca_mmc mmc_host;
@@ -46,6 +57,15 @@
struct mmc *mmc;
char mmc_blks[512];
#endif
+#ifdef CONFIG_IPQ_TINY_SPI_NOR
+ struct spi_flash *flash = NULL;
+#if defined(CONFIG_ART_COMPRESSED) && (defined(CONFIG_GZIP) || defined(CONFIG_LZMA))
+ void *load_buf, *image_buf;
+ unsigned long img_size;
+ unsigned long desMaxSize;
+#endif
+#endif
+
if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) {
if (qca_smem_flash_info.flash_type == SMEM_BOOT_SPI_FLASH)
flash_type = CONFIG_SPI_FLASH_INFO_IDX;
@@ -70,8 +90,50 @@
art_offset =
((loff_t) qca_smem_flash_info.flash_block_size * start_blocks);
+#ifdef CONFIG_IPQ_TINY_SPI_NOR
+ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+ if (flash == NULL){
+ printf("No SPI flash device found\n");
+ ret = -1;
+ } else {
+#if defined(CONFIG_ART_COMPRESSED) && (defined(CONFIG_GZIP) || defined(CONFIG_LZMA))
+ image_buf = map_sysmem(CONFIG_COMPRESSED_LOAD_ADDR, 0);
+ load_buf = map_sysmem(CONFIG_COMPRESSED_LOAD_ADDR + 0x100000, 0);
+ img_size = qca_smem_flash_info.flash_block_size * size_blocks;
+ desMaxSize = 0x100000;
+ ret = spi_flash_read(flash, art_offset, img_size, image_buf);
+ if (ret == 0) {
+ ret = -1;
+#ifdef CONFIG_GZIP
+ ret = gunzip(load_buf, desMaxSize, image_buf, &img_size);
+#endif
+#ifdef CONFIG_LZMA
+ if (ret != 0)
+ ret = lzmaBuffToBuffDecompress(load_buf,
+ (SizeT *)&desMaxSize,
+ image_buf,
+ (SizeT)img_size);
+#endif
+ if (ret == 0) {
+ memcpy(enetaddr, load_buf, length);
+ } else {
+ printf("Invalid compression type..\n");
+ ret = -1;
+ }
+ }
+#else
+ ret = spi_flash_read(flash, art_offset, length, enetaddr);
+#endif
+ }
+ /*
+ * Avoid unused warning
+ */
+ (void)flash_type;
+#else
ret = nand_read(&nand_info[flash_type],
art_offset, &length, enetaddr);
+#endif
if (ret < 0)
printf("ART partition read failed..\n");
#ifdef CONFIG_QCA_MMC
diff --git a/board/qca/arm/common/fdt_fixup.c b/board/qca/arm/common/fdt_fixup.c
index 197105c..ae754a3 100644
--- a/board/qca/arm/common/fdt_fixup.c
+++ b/board/qca/arm/common/fdt_fixup.c
@@ -16,9 +16,13 @@
#include <asm/arch-qca-common/scm.h>
#include <jffs2/load_kernel.h>
#include <fdtdec.h>
+#include <stdlib.h>
+#include "fdt_info.h"
+
#include <led_control.h>
#include <cp_board.h>
#include <bootconfig.h>
+
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_IPQ_FDT_FIXUP
@@ -164,7 +168,162 @@
}
#endif /* RPM_VERSION */
}
+#ifdef CONFIG_IPQ_TINY
+#define OFFSET_NOT_SPECIFIED (~0llu)
+struct reg_cell {
+ unsigned int r0;
+ unsigned int r1;
+};
+extern int fdt_del_partitions(void *blob, int parent_offset);
+
+int parse_nor_partition(const char *const partdef,
+ const char **ret,
+ struct part_info **retpart);
+
+void free_parse(struct list_head *head);
+
+static void ipq_nor_fdt_fixup(void *blob, struct flash_node_info *ni)
+{
+ int parent_offset;
+ struct part_info *part, *pPartInfo;
+ struct reg_cell cell;
+ int off, ndepth = 0;
+ int part_num, ret, newoff;
+ char buf[64];
+ int offset = 0;
+ struct list_head *pentry;
+ LIST_HEAD(tmp_list);
+ const char *pMtdparts = getenv("mtdparts");
+
+ if (!pMtdparts)
+ return;
+
+ for (; ni->compat; ni++) {
+ parent_offset = fdt_node_offset_by_compatible(
+ blob, -1, ni->compat);
+ if (parent_offset != -FDT_ERR_NOTFOUND)
+ break;
+ }
+
+ if (parent_offset == -FDT_ERR_NOTFOUND){
+ printf(" compatible not found \n");
+ return;
+ }
+
+ ret = fdt_del_partitions(blob, parent_offset);
+ if (ret < 0)
+ return;
+
+ /*
+ * Check if it is nand {}; subnode, adjust
+ * the offset in this case
+ */
+ off = fdt_next_node(blob, parent_offset, &ndepth);
+ if (off > 0 && ndepth == 1)
+ parent_offset = off;
+
+ if (strncmp(pMtdparts, "mtdparts=", 9) == 0) {
+ pMtdparts += 9;
+ pMtdparts = strchr(pMtdparts, ':');
+ pMtdparts++;
+ } else {
+ printf("mtdparts variable doesn't start with 'mtdparts='\n");
+ return;
+ }
+
+ part_num = 0;
+
+ while (pMtdparts && (*pMtdparts != '\0') && (*pMtdparts != ';')) {
+ if ((parse_nor_partition(pMtdparts, &pMtdparts, &pPartInfo) != 0))
+ break;
+
+ /* calculate offset when not specified */
+ if (pPartInfo->offset == OFFSET_NOT_SPECIFIED)
+ pPartInfo->offset = offset;
+ else
+ offset = pPartInfo->offset;
+
+ offset += pPartInfo->size;
+ /* partition is ok, add it to the list */
+ list_add_tail(&pPartInfo->link, &tmp_list);
+ }
+ list_for_each_prev(pentry, &tmp_list) {
+
+ part = list_entry(pentry, struct part_info, link);
+
+ debug("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
+ part_num, part->name, part->size,
+ part->offset, part->mask_flags);
+
+ snprintf(buf, sizeof(buf), "partition@%llx", part->offset);
+add_sub:
+ ret = fdt_add_subnode(blob, parent_offset, buf);
+ if (ret == -FDT_ERR_NOSPACE) {
+ ret = fdt_increase_size(blob, 512);
+ if (!ret)
+ goto add_sub;
+ else
+ goto err_size;
+ } else if (ret < 0) {
+ printf("Can't add partition node: %s\n",
+ fdt_strerror(ret));
+ return;
+ }
+ newoff = ret;
+
+ /* Check MTD_WRITEABLE_CMD flag */
+ if (pPartInfo->mask_flags & 1) {
+add_ro:
+ ret = fdt_setprop(blob, newoff, "read_only", NULL, 0);
+ if (ret == -FDT_ERR_NOSPACE) {
+ ret = fdt_increase_size(blob, 512);
+ if (!ret)
+ goto add_ro;
+ else
+ goto err_size;
+ } else if (ret < 0)
+ goto err_prop;
+ }
+
+ cell.r0 = cpu_to_fdt32(part->offset);
+ cell.r1 = cpu_to_fdt32(part->size);
+add_reg:
+ ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell));
+ if (ret == -FDT_ERR_NOSPACE) {
+ ret = fdt_increase_size(blob, 512);
+ if (!ret)
+ goto add_reg;
+ else
+ goto err_size;
+ } else if (ret < 0)
+ goto err_prop;
+
+add_label:
+ ret = fdt_setprop_string(blob, newoff, "label", part->name);
+ if (ret == -FDT_ERR_NOSPACE) {
+ ret = fdt_increase_size(blob, 512);
+ if (!ret)
+ goto add_label;
+ else
+ goto err_size;
+ } else if (ret < 0)
+ goto err_prop;
+
+ part_num++;
+ }
+ goto remove_list;
+err_size:
+ printf("Can't increase blob size: %s\n", fdt_strerror(ret));
+ goto remove_list;
+err_prop:
+ printf("Can't add property: %s\n", fdt_strerror(ret));
+ goto remove_list;
+remove_list:
+ free_parse(&tmp_list);
+ return;
+}
+#else
void ipq_fdt_fixup_mtdparts(void *blob, struct flash_node_info *ni)
{
struct mtd_device *dev;
@@ -193,6 +352,7 @@
}
}
}
+#endif
void ipq_fdt_mem_rsvd_fixup(void *blob)
{
@@ -242,9 +402,13 @@
/* Set the dload_status to DLOAD_DISABLE */
nodeoff = fdt_path_offset(blob, "/soc/qca,scm_restart_reason");
if (nodeoff < 0) {
- debug("fdt-fixup: unable to find compatible node\n");
- return;
+ nodeoff = fdt_path_offset(blob, "/qti,scm_restart_reason");
+ if (nodeoff < 0) {
+ debug("fdt-fixup: unable to find compatible node\n");
+ return;
+ }
}
+
ret = fdt_setprop(blob, nodeoff, "dload_status", &dload, sizeof(dload));
if (ret != 0) {
debug("fdt-fixup: unable to find compatible node\n");
@@ -489,60 +653,148 @@
}
#ifdef CONFIG_IPQ_FDT_FIXUP
+/* setenv fdteditnum <num> - here <num> represents number of envs to parse
+ * Note: without setting 'fdteditnum' fdtedit envs will not parsed
+ *
+ * fdtedit<num> <node>%<property>%<node_value> - dts patching env format
+ * here '%' is separator; <num> can be between 1 to 99;
+ *
+ * 1. To change add/change a particular property of a node:
+ * setenv fdtedit0 <node_path>%<property>%<value>
+ *
+ * This can be used to add properties which doesn't have any value associated
+ * eg: qca,secure; property of q6v5_wcss@CD00000 node can be added as:
+ * setenv fdtedit0 /soc/q6v5_wcss@CD00000/%qca,secure%1
+ * other eg:
+ * fdtedit0=/soc/q6v5_wcss@CD00000%qca,sec-reset-cmd%0x19
+ * fdtedit1=/soc/usb3@8A00000/dwc3@8A00000%dr_mode%?peripheral
+ * fdtedit2=/soc/qcom,gadget_diag@0/%status%?ok
+ *
+ * 2. To delete a property of a node:
+ * setenv fdtedit0 <node_path>%delete%<property>
+ * example:
+ * fdtedit0=/soc/q6v5_wcss@CD00000%delete%?qca,secure
+ *
+ * The last param in both add or delete case, if it is a string, it should
+ * start with '?' else if it is a number, it can be put directly.
+ * check above examples for reference.
+ *
+ * 3. To add 32bit or 64bit array values:
+ * setenv fdtedit0 <node_path>%<bit_value>?<num_values>?<property_name>%<value1>?<value2>?<value3>?..
+ * <bit_value> can be 32 / 64; <num_values> is number of array elements
+ * to be patched; <property_name> is the actual name of the property to
+ * be patched; each array value has to be separated by '?'
+ * for reg = <addr> <size>; <num_values> is 2 in this case
+ * example:
+ * setenv fdtedit0 /soc/dbm@0x8AF8000/%32?2?reg%0x8AF8000?0x500
+ * setenv fdtedit1 /soc/pci@20000000/%32?2?bus-range%0xee?0xee
+ * setenv fdtedit2 /soc/usb3@8A00000/%32?4?reg%0x8AF8600?0x200?0x8A00000?0xcb00
+ * setenv fdtedit3 /reserved-memory/tzapp@49B00000/%64?2?reg%0x49A00000?0x500000
+ */
void parse_fdt_fixup(char* buf, void *blob)
{
- int nodeoff, value, ret;
- char *node, *property, *node_value;
- bool str = true;
+ int nodeoff, value, ret, num_values, i;
+ char *node, *property, *node_value, *sliced_string;
+ bool if_string = true, bit32 = true;
+ u32 *values32;
+ u64 *values64;
+ /* env is split into <node>%<property>%<node_value>. '%' is separator */
node = strsep(&buf, "%");
property = strsep(&buf, "%");
node_value = strsep(&buf, "%");
- debug("node: %s, property: %s, node_value: %s\n",
- node, property, node_value);
+ debug("node: %s property: %s node_value: %s\n", node, property, node_value);
+ /* if '?' is present then node_value is string;
+ * else, node_value is 32bit value
+ */
if (node_value && node_value[0] != '?') {
- str = false;
+ if_string = false;
value = simple_strtoul(node_value, NULL, 10);
} else {
+ /* skip '?' */
node_value++;
}
nodeoff = fdt_path_offset(blob, node);
if (nodeoff < 0) {
- printf("%s: unable to find node '%s'\n",
- __func__, node);
+ printf("%s: unable to find node '%s'\n", __func__, node);
return;
}
if (!strncmp(property, "delete", strlen("delete"))) {
+ /* handle property deletes */
ret = fdt_delprop(blob, nodeoff, node_value);
if (ret) {
- printf("%s: unable to delete %s\n",
- __func__, node_value);
+ printf("%s: unable to delete %s\n", __func__, node_value);
return;
}
- } else if (!str) {
- ret = fdt_setprop_u32(blob, nodeoff, property,
- value);
+ } else if (!strncmp(property, "32", strlen("32")) || !strncmp(property, "64", strlen("64"))) {
+ /* if property name starts with '32' or '64', then it is used
+ * for patching array of 32bit / 64bit values correspondingly.
+ * 32bit patching is usually used to patch reg = <addr> <size>;
+ * but could also be used to patch multiple addresses & sizes
+ * <property> = <addr1> <size1> <addr2> <size2> ..
+ * 64bit patching is usually used to patch reserved memory nodes
+ */
+ sliced_string = strsep(&property, "?");
+ if (simple_strtoul(sliced_string, NULL, 10) == 64)
+ bit32 = false;
+
+ /* get the number of array values */
+ sliced_string = strsep(&property, "?");
+ num_values = simple_strtoul(sliced_string, NULL, 10);
+
+ if (bit32 == true) {
+ values32 = malloc(num_values * sizeof(u32));
+
+ for (i = 0; i < num_values; i++) {
+ sliced_string = strsep(&node_value, "?");
+ values32[i] = cpu_to_fdt32(simple_strtoul(sliced_string, NULL, 10));
+ }
+
+ ret = fdt_setprop(blob, nodeoff, property, values32, num_values * sizeof(u32));
+ if (ret) {
+ printf("%s: failed to set prop %s\n", __func__, property);
+ return;
+ }
+ } else {
+ values64 = malloc(num_values * sizeof(u64));
+
+ for (i = 0; i < num_values; i++) {
+ sliced_string = strsep(&node_value, "?");
+ values64[i] = cpu_to_fdt64(simple_strtoul(sliced_string, NULL, 10));
+ }
+
+ ret = fdt_setprop(blob, nodeoff, property, values64, num_values * sizeof(u64));
+ if (ret) {
+ printf("%s: failed to set prop %s\n", __func__, property);
+ return;
+ }
+ }
+ } else if (!if_string) {
+ /* handle 32bit integer value patching */
+ ret = fdt_setprop_u32(blob, nodeoff, property, value);
if (ret) {
- printf("%s: failed to set prop %s\n",
- __func__, property);
+ printf("%s: failed to set prop %s\n", __func__, property);
return;
}
} else {
+ /* handle string value patching
+ * usually used to patch status = "ok"; status = "disabled";
+ */
ret = fdt_setprop(blob, nodeoff, property,
node_value,
(strlen(node_value) + 1));
if (ret) {
- printf("%s: failed to set prop %s\n",
- __func__, property);
+ printf("%s: failed to set prop %s\n", __func__, property);
return;
}
}
}
+/* check parse_fdt_fixup for detailed explanation */
void ipq_fdt_fixup(void *blob)
{
int i, fdteditnum;
@@ -593,11 +845,6 @@
return;
}
-__weak void fdt_fixup_set_dload_dis(void *blob)
-{
- return;
-}
-
__weak void fdt_fixup_set_dload_warm_reset(void *blob)
{
return;
@@ -618,6 +865,62 @@
return;
}
+__weak void fdt_fixup_art_format(void *blob)
+{
+ return;
+}
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+__weak void fdt_fixup_bt_running(void *blob)
+{
+ return;
+}
+#endif
+
+__weak void fdt_fixup_bt_debug(void *blob)
+{
+ return;
+}
+
+__weak void fdt_fixup_qpic(void *blob)
+{
+ return;
+}
+
+void set_mtdids(void)
+{
+ char mtdids[256];
+
+ if (getenv("mtdids") != NULL) {
+ /* mtdids env is already set, nothing to do */
+ return;
+ }
+
+ qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
+ if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
+ if (get_which_flash_param("rootfs") ||
+ ((sfi->flash_secondary_type == SMEM_BOOT_NAND_FLASH) ||
+ (sfi->flash_secondary_type == SMEM_BOOT_QSPI_NAND_FLASH))) {
+
+ snprintf(mtdids, sizeof(mtdids),
+ "nand%d=nand%d,nand%d=" QCA_SPI_NOR_DEVICE,
+ is_spi_nand_available(),
+ is_spi_nand_available(),
+ CONFIG_SPI_FLASH_INFO_IDX);
+ } else {
+
+ snprintf(mtdids, sizeof(mtdids), "nand%d="
+ QCA_SPI_NOR_DEVICE, CONFIG_SPI_FLASH_INFO_IDX);
+
+ }
+ setenv("mtdids", mtdids);
+ } else if (((sfi->flash_type == SMEM_BOOT_NAND_FLASH) ||
+ (sfi->flash_type == SMEM_BOOT_QSPI_NAND_FLASH))) {
+
+ snprintf(mtdids, sizeof(mtdids), "nand0=nand0");
+ setenv("mtdids", mtdids);
+ }
+}
void fdt_fixup_read_qfprom(void *blob)
{
@@ -800,21 +1103,30 @@
uint32_t flash_type;
char *s;
char *mtdparts = NULL;
+ char *addparts = NULL;
char parts_str[4096];
int len = sizeof(parts_str), ret;
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
int activepart = 0;
+#ifdef CONFIG_IPQ_TINY
+ struct flash_node_info nodes[] = {
+ { "n25q128a11", MTD_DEV_TYPE_NAND,
+ CONFIG_IPQ_SPI_NOR_INFO_IDX }
+ };
+#else
struct flash_node_info nodes[] = {
{ "qcom,msm-nand", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,qcom_nand", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ebi2-nandc-bam-v1.5.0", MTD_DEV_TYPE_NAND, 0 },
{ "qcom,ebi2-nandc-bam-v2.1.1", MTD_DEV_TYPE_NAND, 0 },
+ { "qcom,ipq8074-nand", MTD_DEV_TYPE_NAND, 0 },
{ "spinand,mt29f", MTD_DEV_TYPE_NAND, 1 },
{ "n25q128a11", MTD_DEV_TYPE_NAND,
CONFIG_IPQ_SPI_NOR_INFO_IDX },
{ "s25fl256s1", MTD_DEV_TYPE_NAND, 1 },
{ NULL, 0, -1 }, /* Terminator */
};
+#endif
/* force memory to 256MB if boardID is 002007 */
struct custdata cd;
@@ -867,12 +1179,23 @@
if (mtdparts) {
qca_smem_part_to_mtdparts(mtdparts,len);
if (mtdparts[0] != '\0') {
+ addparts = getenv("addmtdparts");
+ if (addparts) {
+ debug("addmtdparts = %s\n", addparts);
+ strlcat(mtdparts, ",", sizeof(parts_str));
+ strlcat(mtdparts, addparts, sizeof(parts_str));
+ }
debug("mtdparts = %s\n", mtdparts);
setenv("mtdparts", mtdparts);
}
+ set_mtdids();
debug("MTDIDS: %s\n", getenv("mtdids"));
+#ifdef CONFIG_IPQ_TINY
+ ipq_nor_fdt_fixup(blob, nodes);
+#else
ipq_fdt_fixup_mtdparts(blob, nodes);
+#endif
}
/* Add "flash_type" to root node of the devicetree*/
@@ -902,6 +1225,7 @@
fdt_fixup_cpr(blob);
fdt_fixup_cpus_node(blob);
fdt_low_memory_fixup(blob);
+ fdt_fixup_qpic(blob);
fdt_fixup_read_qfprom(blob);
fdt_fixup_add_signatures(blob);
@@ -913,7 +1237,7 @@
fdt_fixup_set_dload_warm_reset(blob);
s = getenv("dload_dis");
if (s)
- fdt_fixup_set_dload_dis(blob);
+ ipq_fdt_mem_rsvd_fixup(blob);
s = getenv("qce_fixed_key");
if (s)
fdt_fixup_set_qce_fixed_key(blob);
@@ -922,6 +1246,19 @@
fdt_fixup_set_qca_cold_reboot_enable(blob);
fdt_fixup_wcss_rproc_for_atf(blob);
}
+ s = getenv("bt_debug");
+ if (s) {
+ fdt_fixup_bt_debug(blob);
+ }
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+ fdt_fixup_bt_running(blob);
+#endif
+ /*
+ || This features fixup compressed_art in
+ || dts if its 16M profile build.
+ */
+ fdt_fixup_art_format(blob);
#ifdef CONFIG_QCA_MMC
board_mmc_deinit();
diff --git a/board/qca/arm/ipq40xx/ipq40xx.c b/board/qca/arm/ipq40xx/ipq40xx.c
index 247aef2..61bd3ee 100644
--- a/board/qca/arm/ipq40xx/ipq40xx.c
+++ b/board/qca/arm/ipq40xx/ipq40xx.c
@@ -37,6 +37,9 @@
#define DLOAD_MAGIC_COOKIE 0x10
#define TCSR_USB_HSPHY_DEVICE_MODE 0x00C700E7
+
+#define TCSR_SOC_HW_VERSION_REG 0x194D000
+
DECLARE_GLOBAL_DATA_PTR;
#define CPU0_APCS_SAW2_VCTL 0x0b089014
@@ -788,3 +791,7 @@
return;
}
+int get_soc_hw_version(void)
+{
+ return readl(TCSR_SOC_HW_VERSION_REG);
+}
diff --git a/board/qca/arm/ipq5018/Makefile b/board/qca/arm/ipq5018/Makefile
new file mode 100644
index 0000000..ea342f2
--- /dev/null
+++ b/board/qca/arm/ipq5018/Makefile
@@ -0,0 +1,6 @@
+ccflags-y += -I$(srctree)/board/qca/arm/ipq5018
+cppflags-y += -I$(srctree)/board/qca/arm/ipq5018
+obj-y := ipq5018.o
+obj-y += clock.o
+obj-$(CONFIG_IPQ_BT_SUPPORT) += bt_ipc.o
+
diff --git a/board/qca/arm/ipq5018/bt.h b/board/qca/arm/ipq5018/bt.h
new file mode 100644
index 0000000..bb54444
--- /dev/null
+++ b/board/qca/arm/ipq5018/bt.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _BT_H
+#define _BT_H
+
+#include <asm/atomic.h>
+
+#define PAS_ID 0xC
+#define CMD_ID 0x14
+#define BT_M0_WARM_RST_ORIDE 0x0
+#define BT_M0_WARM_RST 0x4
+
+#define IOCTL_IPC_BOOT 0xBE
+#define IPC_TX_QSIZE 0x20
+
+#define TO_APPS_ADDR(a) (btmem->virt + (int)(uintptr_t)a)
+#define TO_BT_ADDR(a) (a - btmem->virt)
+#define IPC_LBUF_SZ(w, x, y, z) (((TO_BT_ADDR((void *)w) + w->x) - w->y) / w->z)
+
+#define IPC_MSG_HDR_SZ (4u)
+#define IPC_MSG_PLD_SZ (40u)
+#define IPC_TOTAL_MSG_SZ (IPC_MSG_HDR_SZ + IPC_MSG_PLD_SZ)
+
+#define IPC_LMSG_MASK (0x8000u)
+#define IPC_RACK_MASK (0x4000u)
+#define IPC_PKT_TYPE_MASK (0x0300u)
+#define IPC_MSG_ID_MASK (0x00FFu)
+
+#define IPC_LMSG_TYPE ((uint16_t) IPC_LMSG_MASK)
+#define IPC_SMSG_TYPE ((uint16_t) 0x0000u)
+#define IPC_REQ_ACK ((uint16_t) IPC_RACK_MASK)
+#define IPC_NO_ACK ((uint16_t) 0x0000u)
+#define IPC_PKT_TYPE_CUST ((uint16_t) 0x0000u)
+#define IPC_PKT_TYPE_HCI ((uint16_t) 0x0100u)
+#define IPC_PKT_TYPE_AUDIO ((uint16_t) 0x0200u)
+#define IPC_PKT_TYPE_RFU (IPC_PKT_TYPE_MASK)
+
+#define IPC_LMSG_SHIFT (15u)
+#define IPC_RACK_SHIFT (14u)
+#define IPC_PKT_TYPE_SHIFT (8u)
+
+#define GET_NO_OF_BLOCKS(a, b) ((a + b - 1) / b)
+
+#define GET_RX_INDEX_FROM_BUF(x, y) ((x - btmem->rx_ctxt->lring_buf) / y)
+
+#define GET_TX_INDEX_FROM_BUF(x, y) ((x - btmem->tx_ctxt->lring_buf) / y)
+
+#define IS_RX_MEM_NON_CONTIGIOUS(pBuf, len, sz) \
+ ((pBuf + len) > \
+ (btmem->rx_ctxt->lring_buf + \
+ (sz * btmem->rx_ctxt->lmsg_buf_cnt)))
+
+/** Message header format.
+ *
+ * ---------------------------------------------------------------
+ * BitPos | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 - 0 |
+ * ---------------------------------------------------------------
+ * Field | Long Msg |rAck| RFU | PktType | msgID |
+ * ---------------------------------------------------------------
+ *
+ * - Long Msg :
+ *
+ * - reqAck : This is interpreted by receiver for sending acknowledegement
+ * to sender i.e. send a ack IPC interrupt if set.
+ * Use @ref IS_REQ_ACK or @ref IS_NO_ACK
+ * to determine ack is requested or not.
+ *
+ * - RFU : Reserved for future use.
+ *
+ * - pktType :
+ *
+ * - msgID : Contains unique message ID within a Category.
+ * Use @ref IPC_GET_MSG_ID to get message ID.
+ */
+#define IPC_ConstructMsgHeader(msgID, reqAck, pktType, longMsg) \
+ (((uint8_t) longMsg << IPC_LMSG_SHIFT) | \
+ ((uint8_t) reqAck << IPC_RACK_SHIFT) | \
+ ((uint16_t) pktType << IPC_PKT_TYPE_SHIFT) | msgID)
+
+#define IPC_GET_PKT_TYPE(hdr) \
+ ((enum ipc_pkt_type)((hdr & IPC_PKT_TYPE_MASK) >> IPC_PKT_TYPE_SHIFT))
+
+#define IS_LONG_MSG(hdr) ((hdr & IPC_LMSG_MASK) == IPC_LMSG_TYPE)
+#define IS_SHORT_MSG(hdr) ((hdr & IPC_LMSG_MASK) == IPC_SMSG_TYPE)
+
+#define IS_REQ_ACK(hdr) ((hdr & IPC_RACK_MASK) == IPC_REQ_ACK)
+#define IS_NO_ACK(hdr) ((hdr & IPC_RACK_MASK) == IPC_NO_ACK)
+
+#define IS_HCI_PKT(hdr) ((hdr & IPC_PKT_TYPE_MASK) == IPC_PKT_TYPE_HCI)
+#define IS_CUST_PKT(hdr) ((hdr & IPC_PKT_TYPE_MASK) == IPC_PKT_TYPE_CUST)
+
+#define IPC_GET_MSG_ID(hdr) ((uint8_t)(hdr & IPC_MSG_ID_MASK))
+
+#define IPC_CMD_IPC_STOP (0x01)
+#define IPC_CMD_SWITCH_TO_UART (0x02)
+#define IPC_CMD_PREPARE_DUMP (0x03)
+#define IPC_CMD_COLLECT_DUMP (0x04)
+#define IPC_CMD_IPC_START (0x05)
+
+#define BT_RAM_START 0x7000000
+#define BT_RAM_PATCH 0x7020250
+#define BT_RAM_SIZE 0x58000
+#define SYSCON 0x0B111000
+
+/*-------------------------------------------------------------------------
+ * Type Declarations
+ * ------------------------------------------------------------------------
+ */
+
+enum ipc_pkt_type {
+ IPC_CUST_PKT,
+ IPC_HCI_PKT,
+ IPC_AUDIO_PKT,
+ IPC_PKT_MAX
+};
+
+struct long_msg_info {
+ uint16_t smsg_free_cnt;
+ uint16_t lmsg_free_cnt;
+ uint8_t ridx;
+ uint8_t widx;
+};
+
+struct ipc_aux_ptr {
+ uint32_t len;
+ uint32_t buf;
+};
+
+struct ring_buffer {
+ uint16_t msg_hdr;
+ uint16_t len;
+
+ union {
+ uint8_t smsg_data[IPC_MSG_PLD_SZ];
+ uint32_t lmsg_data;
+ } payload;
+};
+
+struct ring_buffer_info {
+ uint32_t rbuf;
+ uint8_t ring_buf_cnt;
+ uint8_t ridx;
+ uint8_t widx;
+ uint8_t tidx;
+ uint32_t next;
+};
+
+struct context_info {
+ uint16_t TotalMemorySize;
+ uint8_t lmsg_buf_cnt;
+ uint8_t smsg_buf_cnt;
+ struct ring_buffer_info sring_buf_info;
+ uint32_t sring_buf;
+ uint32_t lring_buf;
+ uint32_t reserved;
+};
+
+
+struct bt_mem {
+ phys_addr_t phys;
+ phys_addr_t reloc;
+ void __iomem *virt;
+ size_t size;
+ struct context_info *tx_ctxt;
+ struct context_info *rx_ctxt;
+ struct long_msg_info lmsg_ctxt;
+};
+
+struct bt_ipc {
+ uint32_t regmap;
+ int offset;
+ int bit;
+ int irq;
+ atomic_t tx_q_cnt;
+};
+
+struct bt_descriptor {
+ void __iomem *warm_reset;
+ struct bt_ipc ipc;
+ struct bt_mem btmem;
+ int (*sendmsg_cb)(struct bt_descriptor *, unsigned char *, int);
+ void (*recvmsg_cb)(struct bt_descriptor *, unsigned char *, int);
+ atomic_t state;
+ atomic_t tx_in_progress;
+ unsigned char *buf;
+ uint32_t len;
+};
+
+struct ipc_intent {
+ uint8_t *buf;
+ uint16_t len;
+};
+
+extern int bt_ipc_sendmsg(struct bt_descriptor *btDesc, unsigned char *buf, int len );
+extern void bt_ipc_init(struct bt_descriptor *btDesc);
+extern void bt_ipc_worker(struct bt_descriptor *btDesc);
+extern int bt_running;
+#endif /* _BT_H */
diff --git a/board/qca/arm/ipq5018/bt_ipc.c b/board/qca/arm/ipq5018/bt_ipc.c
new file mode 100644
index 0000000..18caf82
--- /dev/null
+++ b/board/qca/arm/ipq5018/bt_ipc.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <asm/atomic.h>
+#include <asm-generic/atomic-long.h>
+
+#include <linux/ctype.h>
+#include "bt.h"
+
+#include <common.h>
+#include <memalign.h>
+
+#include <linux/err.h>
+
+static void *bt_ipc_alloc_lmsg(struct bt_descriptor *btDesc, uint32_t len,
+ struct ipc_aux_ptr *aux_ptr, uint8_t *is_lbuf_full)
+{
+ uint8_t idx;
+ uint8_t blks;
+ uint8_t blks_consumed;
+ struct bt_mem *btmem = &btDesc->btmem;
+ uint32_t lsz = IPC_LBUF_SZ(btmem->tx_ctxt, TotalMemorySize, lring_buf,
+ lmsg_buf_cnt);
+
+ if (btmem->tx_ctxt->lring_buf == 0) {
+ printf("no long message buffer not initialized\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ blks = GET_NO_OF_BLOCKS(len, lsz);
+
+ if (!btmem->lmsg_ctxt.lmsg_free_cnt ||
+ (blks > btmem->lmsg_ctxt.lmsg_free_cnt))
+ return ERR_PTR(-EAGAIN);
+
+ idx = btmem->lmsg_ctxt.widx;
+
+ if ((btmem->lmsg_ctxt.widx + blks) > btmem->tx_ctxt->lmsg_buf_cnt) {
+ blks_consumed = btmem->tx_ctxt->lmsg_buf_cnt - idx;
+ aux_ptr->len = len - (blks_consumed * lsz);
+ aux_ptr->buf = btmem->tx_ctxt->lring_buf;
+ }
+
+ btmem->lmsg_ctxt.widx = (btmem->lmsg_ctxt.widx + blks) %
+ btmem->tx_ctxt->lmsg_buf_cnt;
+
+ btmem->lmsg_ctxt.lmsg_free_cnt -= blks;
+
+ if (btmem->lmsg_ctxt.lmsg_free_cnt <=
+ ((btmem->tx_ctxt->lmsg_buf_cnt * 20) / 100))
+ *is_lbuf_full = 1;
+
+ return (TO_APPS_ADDR(btmem->tx_ctxt->lring_buf) + (idx * lsz));
+}
+
+static struct ring_buffer_info *bt_ipc_get_tx_rbuf(struct bt_descriptor *btDesc,
+ uint8_t *is_sbuf_full)
+{
+ uint8_t idx;
+ struct ring_buffer_info *rinfo;
+ struct bt_mem *btmem = &btDesc->btmem;
+
+ for (rinfo = &(btmem->tx_ctxt->sring_buf_info); rinfo != NULL;
+ rinfo = (struct ring_buffer_info *)(uintptr_t)(rinfo->next)) {
+ idx = (rinfo->widx + 1) % (btmem->tx_ctxt->smsg_buf_cnt);
+
+ if (idx != rinfo->tidx) {
+ btmem->lmsg_ctxt.smsg_free_cnt--;
+
+ if (btmem->lmsg_ctxt.smsg_free_cnt <=
+ ((btmem->tx_ctxt->smsg_buf_cnt * 20) / 100))
+ *is_sbuf_full = 1;
+
+ return rinfo;
+ }
+ }
+
+ return ERR_PTR(-EAGAIN);
+}
+
+int bt_ipc_send_msg(struct bt_descriptor *btDesc, uint16_t msg_hdr,
+ const uint8_t *pData, uint16_t len, bool dequeue)
+{
+ int ret = 0;
+ struct bt_mem *btmem = &btDesc->btmem;
+ struct ring_buffer_info *rinfo;
+ struct ring_buffer *rbuf;
+ uint8_t is_lbuf_full = 0;
+ uint8_t is_sbuf_full = 0;
+ struct ipc_aux_ptr aux_ptr;
+ void *lmsg_data;
+
+ rinfo = bt_ipc_get_tx_rbuf(btDesc, &is_sbuf_full);
+ if (IS_ERR(rinfo)) {
+ printf("short msg buf full, queuing msg[%d]\n",
+ atomic_read(&btDesc->ipc.tx_q_cnt));
+ ret = PTR_ERR(rinfo);
+ return ret;
+ }
+
+ rbuf = &((struct ring_buffer *)(TO_APPS_ADDR(
+ rinfo->rbuf)))[rinfo->widx];
+ rbuf->msg_hdr = msg_hdr;
+ rbuf->len = len;
+
+ if (len > IPC_MSG_PLD_SZ) {
+ rbuf->msg_hdr = rbuf->msg_hdr | IPC_LMSG_MASK;
+
+ aux_ptr.len = 0;
+ aux_ptr.buf = 0;
+
+ lmsg_data = bt_ipc_alloc_lmsg(btDesc, len,
+ &aux_ptr, &is_lbuf_full);
+
+ if (IS_ERR(lmsg_data)) {
+ printf("long msg buf full, queuing msg[%d]\n",
+ atomic_read(&btDesc->ipc.tx_q_cnt));
+ ret = PTR_ERR(lmsg_data);
+ return ret;
+ }
+
+ memcpy_toio(lmsg_data, pData,
+ (len - aux_ptr.len));
+
+ if (aux_ptr.buf) {
+ memcpy_toio(TO_APPS_ADDR(aux_ptr.buf),
+ (pData + (len - aux_ptr.len)), aux_ptr.len);
+ }
+
+ rbuf->payload.lmsg_data = TO_BT_ADDR(lmsg_data);
+ } else {
+ memcpy_toio(rbuf->payload.smsg_data, pData, len);
+ }
+
+ if (is_sbuf_full || is_lbuf_full)
+ rbuf->msg_hdr = rbuf->msg_hdr | IPC_RACK_MASK;
+
+ rinfo->widx = (rinfo->widx + 1) % btmem->tx_ctxt->smsg_buf_cnt;
+
+ writel( BIT(btDesc->ipc.bit), btDesc->ipc.regmap+ btDesc->ipc.offset);
+
+ return ret;
+}
+
+static
+void bt_ipc_free_lmsg(struct bt_descriptor *btDesc, uint32_t lmsg, uint16_t len)
+{
+ uint8_t idx;
+ uint8_t blks;
+ struct bt_mem *btmem = &btDesc->btmem;
+ uint32_t lsz = IPC_LBUF_SZ(btmem->tx_ctxt, TotalMemorySize, lring_buf,
+ lmsg_buf_cnt);
+
+ idx = GET_TX_INDEX_FROM_BUF(lmsg, lsz);
+
+ if (idx != btmem->lmsg_ctxt.ridx)
+ return;
+
+ blks = GET_NO_OF_BLOCKS(len, lsz);
+
+ btmem->lmsg_ctxt.ridx = (btmem->lmsg_ctxt.ridx + blks) %
+ btmem->tx_ctxt->lmsg_buf_cnt;
+
+ btmem->lmsg_ctxt.lmsg_free_cnt += blks;
+}
+
+static void bt_ipc_cust_msg(struct bt_descriptor *btDesc, uint8_t msgid)
+{
+ struct bt_mem *btmem = &btDesc->btmem;
+ uint16_t msg_hdr = 0;
+ int ret;
+
+ msg_hdr |= msgid;
+
+ switch (msgid) {
+ case IPC_CMD_IPC_STOP:
+ printf("BT IPC Stopped, gracefully stopping APSS IPC\n");
+ break;
+ case IPC_CMD_SWITCH_TO_UART:
+ printf("Configured UART, Swithing BT to debug mode\n");
+ break;
+ case IPC_CMD_PREPARE_DUMP:
+ printf("IPQ crashed, inform BT to prepare dump\n");
+ break;
+ case IPC_CMD_COLLECT_DUMP:
+ printf("BT Crashed, gracefully stopping IPC\n");
+ return;
+ case IPC_CMD_IPC_START:
+ btmem->tx_ctxt = (struct context_info *)((void *)
+ btmem->rx_ctxt + btmem->rx_ctxt->TotalMemorySize);
+ btmem->lmsg_ctxt.widx = 0;
+ btmem->lmsg_ctxt.ridx = 0;
+ btmem->lmsg_ctxt.smsg_free_cnt = btmem->tx_ctxt->smsg_buf_cnt;
+ btmem->lmsg_ctxt.lmsg_free_cnt = btmem->tx_ctxt->lmsg_buf_cnt;
+ atomic_set(&btDesc->state, 1);
+
+ printf("BT IPC Started, starting APSS IPC\n");
+ return;
+ default:
+ printf("invalid custom message\n");
+ return;
+ }
+
+ if (unlikely(!atomic_read(&btDesc->state))) {
+ printf("BT IPC not initialized, no message sent\n");
+ return;
+ }
+
+ atomic_set(&btDesc->state, 0);
+
+ ret = bt_ipc_send_msg(btDesc, msg_hdr, NULL, 0, true);
+ if (ret)
+ printf("err: sending message\n");
+}
+
+static bool bt_ipc_process_peer_msgs(struct bt_descriptor *btDesc,
+ struct ring_buffer_info *rinfo, uint8_t *pRxMsgCount)
+{
+ struct bt_mem *btmem = &btDesc->btmem;
+ struct ring_buffer *rbuf;
+ uint8_t ridx, lbuf_idx;
+ uint8_t blks_consumed;
+ struct ipc_aux_ptr aux_ptr;
+ enum ipc_pkt_type pktType = IPC_CUST_PKT;
+ bool ackReqd = false;
+ uint8_t *rxbuf = NULL;
+ uint32_t lsz = IPC_LBUF_SZ(btmem->rx_ctxt, TotalMemorySize, lring_buf,
+ lmsg_buf_cnt);
+
+ ridx = rinfo->ridx;
+
+ rbuf = &((struct ring_buffer *)(TO_APPS_ADDR(
+ btmem->rx_ctxt->sring_buf_info.rbuf)))[ridx];
+
+ while (ridx != rinfo->widx) {
+ memset(&aux_ptr, 0, sizeof(struct ipc_aux_ptr));
+
+ rbuf = &((struct ring_buffer *)(TO_APPS_ADDR(
+ btmem->rx_ctxt->sring_buf_info.rbuf)))[ridx];
+
+ if (IS_LONG_MSG(rbuf->msg_hdr)) {
+ rxbuf = TO_APPS_ADDR(rbuf->payload.lmsg_data);
+
+ if (IS_RX_MEM_NON_CONTIGIOUS(rbuf->payload.lmsg_data,
+ rbuf->len, lsz)) {
+
+ lbuf_idx = GET_RX_INDEX_FROM_BUF(
+ rbuf->payload.lmsg_data, lsz);
+
+ blks_consumed = btmem->rx_ctxt->lmsg_buf_cnt -
+ lbuf_idx;
+ aux_ptr.len = rbuf->len - (blks_consumed * lsz);
+ aux_ptr.buf = btmem->rx_ctxt->lring_buf;
+ }
+ } else {
+ rxbuf = rbuf->payload.smsg_data;
+ }
+
+ if (IS_REQ_ACK(rbuf->msg_hdr))
+ ackReqd = true;
+
+ pktType = IPC_GET_PKT_TYPE(rbuf->msg_hdr);
+
+ switch (pktType) {
+ case IPC_HCI_PKT:
+ btDesc->buf = kzalloc(rbuf->len, GFP_ATOMIC);
+ if (!btDesc->buf)
+ return -ENOMEM;
+
+ memcpy_fromio(btDesc->buf, rxbuf, (rbuf->len - aux_ptr.len));
+
+ if (aux_ptr.buf)
+ memcpy_fromio(btDesc->buf + (rbuf->len - aux_ptr.len),
+ TO_APPS_ADDR(aux_ptr.buf), aux_ptr.len);
+
+ btDesc->len = rbuf->len;
+ atomic_set(&btDesc->tx_in_progress, 0);
+ break;
+ case IPC_CUST_PKT:
+ bt_ipc_cust_msg(btDesc, IPC_GET_MSG_ID(rbuf->msg_hdr));
+ break;
+ case IPC_AUDIO_PKT:
+ break;
+ default:
+ break;
+ }
+
+ ridx = (ridx + 1) % rinfo->ring_buf_cnt;
+ }
+
+ rinfo->ridx = ridx;
+
+ return ackReqd;
+}
+
+static void bt_ipc_process_ack(struct bt_descriptor *btDesc)
+{
+ struct ring_buffer_info *rinfo;
+ struct bt_mem *btmem = &btDesc->btmem;
+
+ for (rinfo = &btmem->tx_ctxt->sring_buf_info; rinfo != NULL;
+ rinfo = (struct ring_buffer_info *)(uintptr_t)(rinfo->next)) {
+ uint8_t tidx = rinfo->tidx;
+ struct ring_buffer *rbuf = (struct ring_buffer *)
+ TO_APPS_ADDR(rinfo->rbuf);
+
+ while (tidx != rinfo->ridx) {
+ if (IS_LONG_MSG(rbuf[tidx].msg_hdr)) {
+ bt_ipc_free_lmsg(btDesc,
+ rbuf[tidx].payload.lmsg_data,
+ rbuf[tidx].len);
+ }
+
+ tidx = (tidx + 1) % btmem->tx_ctxt->smsg_buf_cnt;
+ btmem->lmsg_ctxt.smsg_free_cnt++;
+ }
+
+ rinfo->tidx = tidx;
+ }
+}
+
+int bt_ipc_sendmsg(struct bt_descriptor *btDesc, unsigned char *buf, int len)
+{
+ int ret;
+ uint16_t msg_hdr = 0x100;
+
+ if (unlikely(!atomic_read(&btDesc->state))) {
+ printf("BT IPC not initialized, no message sent\n");
+ return -ENODEV;
+ }
+
+ atomic_set(&btDesc->tx_in_progress, 1);
+ ret = bt_ipc_send_msg(btDesc, msg_hdr, (uint8_t *)buf, (uint16_t)len,
+ true);
+ if (ret)
+ printf("err: sending message\n");
+
+ return ret;
+}
+
+void bt_ipc_worker(struct bt_descriptor *btDesc)
+{
+ struct ring_buffer_info *rinfo;
+
+ struct bt_mem *btmem = &btDesc->btmem;
+ bool ackReqd = false;
+
+ if (unlikely(!atomic_read(&btDesc->state))) {
+ btmem->rx_ctxt = (struct context_info *)(btmem->virt + 0xe000);
+ if (btmem->rx_ctxt->sring_buf_info.widx != 0x1)
+ return;
+ }
+ else
+ bt_ipc_process_ack(btDesc);
+
+ for (rinfo = &(btmem->rx_ctxt->sring_buf_info); rinfo != NULL;
+ rinfo = (struct ring_buffer_info *)(uintptr_t)(rinfo->next)) {
+ if (bt_ipc_process_peer_msgs(btDesc, rinfo,
+ &btmem->rx_ctxt->smsg_buf_cnt)) {
+ ackReqd = true;
+ }
+ }
+
+ if (ackReqd) {
+ writel( BIT(btDesc->ipc.bit), btDesc->ipc.regmap+ btDesc->ipc.offset);
+ }
+
+}
+
+void bt_ipc_init(struct bt_descriptor *btDesc)
+{
+ struct bt_mem *btmem;
+
+ btmem = &btDesc->btmem;
+ btmem->phys = BT_RAM_START;
+ btmem->reloc = BT_RAM_START;
+ btmem->size = BT_RAM_SIZE;
+ btmem->virt = (void __iomem *)BT_RAM_START;
+
+ btDesc->ipc.regmap = SYSCON;
+ btDesc->ipc.offset = 8;
+ btDesc->ipc.bit = 23;
+ atomic_set(&btDesc->state, 0);
+ atomic_set(&btDesc->tx_in_progress, 0);
+}
diff --git a/board/qca/arm/ipq5018/clock.c b/board/qca/arm/ipq5018/clock.c
new file mode 100644
index 0000000..247dc79
--- /dev/null
+++ b/board/qca/arm/ipq5018/clock.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015-2016, 2018-2019 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/arch-ipq5018/clk.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#ifdef CONFIG_IPQ5018_I2C
+void i2c_clock_config(void)
+{
+ int cfg;
+
+ /* Configure qup1_i2c_apps_clk_src */
+ cfg = (GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR_SRC_SEL |
+ GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR_SRC_DIV);
+ writel(cfg, GCC_BLSP1_QUP3_I2C_APPS_CFG_RCGR);
+
+ writel(CMD_UPDATE, GCC_BLSP1_QUP3_I2C_APPS_CMD_RCGR);
+ mdelay(100);
+ writel(ROOT_EN, GCC_BLSP1_QUP3_I2C_APPS_CMD_RCGR);
+
+ /* Configure CBCR */
+ writel(CLK_ENABLE, GCC_BLSP1_QUP3_I2C_APPS_CBCR);
+}
+#endif
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+void enable_btss_lpo_clk(void)
+{
+ writel(CLK_ENABLE, GCC_BTSS_LPO_CBCR);
+}
+#endif
diff --git a/board/qca/arm/ipq5018/ipq5018.c b/board/qca/arm/ipq5018/ipq5018.c
new file mode 100644
index 0000000..01b4d44
--- /dev/null
+++ b/board/qca/arm/ipq5018/ipq5018.c
@@ -0,0 +1,1987 @@
+/*
+* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <common.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <environment.h>
+#include <fdtdec.h>
+#include <asm/arch-qca-common/gpio.h>
+#include <asm/arch-qca-common/uart.h>
+#include <asm/arch-qca-common/scm.h>
+#include <asm/arch-qca-common/iomap.h>
+#include <ipq5018.h>
+#ifdef CONFIG_QCA_MMC
+#include <mmc.h>
+#include <sdhci.h>
+#endif
+#ifdef CONFIG_USB_XHCI_IPQ
+#include <usb.h>
+#endif
+#ifdef CONFIG_QPIC_NAND
+#include <asm/arch-qca-common/qpic_nand.h>
+#endif
+#ifdef CONFIG_IPQ_BT_SUPPORT
+#include <malloc.h>
+#include "bt.h"
+#include "bt_binary_array.h"
+#include <linux/compat.h>
+#endif
+
+#define DLOAD_MAGIC_COOKIE 0x10
+
+#define TCSR_SOC_HW_VERSION_REG 0x194D000
+
+ipq_gmac_board_cfg_t gmac_cfg[CONFIG_IPQ_NO_MACS];
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_QCA_MMC
+struct sdhci_host mmc_host;
+#endif
+
+#ifdef CONFIG_MTD_DEVICE
+extern int ipq_spi_init(u16);
+#endif
+
+extern void ppe_uniphy_set_forceMode(void);
+extern void ppe_uniphy_refclk_set(void);
+
+unsigned int qpic_frequency = 0, qpic_phase = 0;
+
+const char *rsvd_node = "/reserved-memory";
+const char *del_node[] = {"uboot",
+ "sbl",
+ NULL};
+const add_node_t add_fdt_node[] = {{}};
+
+struct dumpinfo_t dumpinfo_n[] = {
+ /* TZ stores the DDR physical address at which it stores the
+ * APSS regs, UTCM copy dump. We will have the TZ IMEM
+ * IMEM Addr at which the DDR physical address is stored as
+ * the start
+ * --------------------
+ * | DDR phy (start) | ----> ------------------------
+ * -------------------- | APSS regsave (8k) |
+ * ------------------------
+ * | |
+ * | UTCM copy |
+ * | (192k) |
+ * | |
+ * ------------------------
+ * | |
+ * | BTRAM Copy |
+ * | (352k) |
+ * | |
+ * ------------------------
+ */
+ { "EBICS0.BIN", 0x40000000, 0x10000000, 0 },
+ /*
+ * The below 3 config enable compress crash dump support.
+ * the RAM region will be split in 3 section and collect based on the
+ * config as given below. NOT SUPPORT IN TINY_NOR profile.
+ * Note : EBICS2.BIN start and size varies dynamically based on RAM size.
+ * basically it's seconds half of ram region.
+ */
+#ifndef CONFIG_IPQ_TINY
+ { "EBICS2.BIN", 0x60000000, 0x20000000, 0, 0, 0, 0, 1 },
+ { "EBICS1.BIN", CONFIG_UBOOT_END_ADDR, 0x10000000, 0, 0, 0, 0, 1 },
+ { "EBICS0.BIN", 0x40000000, CONFIG_QCA_UBOOT_OFFSET, 0, 0, 0, 0, 1 },
+#endif
+ { "IMEM.BIN", 0x08600000, 0x00001000, 0 },
+ { "NSSUTCM.BIN", 0x08600658, 0x00030000, 0, 1, 0x2000 },
+ { "BTRAM.BIN", 0x08600658, 0x00058000, 0, 1, 0x00032000 },
+ { "UNAME.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "CPU_INFO.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "DMESG.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "PT.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "WLAN_MOD.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+};
+int dump_entries_n = ARRAY_SIZE(dumpinfo_n);
+
+struct dumpinfo_t dumpinfo_s[] = {
+ { "EBICS_S0.BIN", 0x40000000, 0xAC00000, 0 },
+ { "EBICS_S1.BIN", CONFIG_TZ_END_ADDR, 0x10000000, 0 },
+#ifndef CONFIG_IPQ_TINY
+ { "EBICS_S2.BIN", CONFIG_TZ_END_ADDR, 0x10000000, 0, 0, 0, 0, 1 },
+ { "EBICS_S1.BIN", CONFIG_UBOOT_END_ADDR, 0x200000, 0, 0, 0, 0, 1 },
+ { "EBICS_S0.BIN", 0x40000000, CONFIG_QCA_UBOOT_OFFSET, 0, 0, 0, 0, 1 },
+#endif
+ { "IMEM.BIN", 0x08600000, 0x00001000, 0 },
+ { "NSSUTCM.BIN", 0x08600658, 0x00030000, 0, 1, 0x2000 },
+ { "BTRAM.BIN", 0x08600658, 0x00058000, 0, 1, 0x00032000 },
+ { "UNAME.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "CPU_INFO.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "DMESG.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "PT.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+ { "WLAN_MOD.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP },
+};
+int dump_entries_s = ARRAY_SIZE(dumpinfo_s);
+u32 *tz_wonce = (u32 *)CONFIG_IPQ5018_TZ_WONCE_4_ADDR;
+
+void uart1_configure_mux(void)
+{
+ unsigned long cfg_rcgr;
+
+ cfg_rcgr = readl(GCC_BLSP1_UART1_APPS_CFG_RCGR);
+ /* Clear mode, src sel, src div */
+ cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK |
+ GCC_UART_CFG_RCGR_SRCSEL_MASK |
+ GCC_UART_CFG_RCGR_SRCDIV_MASK);
+
+ cfg_rcgr |= ((UART1_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
+ & GCC_UART_CFG_RCGR_SRCSEL_MASK);
+
+ cfg_rcgr |= ((UART1_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
+ & GCC_UART_CFG_RCGR_SRCDIV_MASK);
+
+ cfg_rcgr |= ((UART1_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
+ & GCC_UART_CFG_RCGR_MODE_MASK);
+
+ writel(cfg_rcgr, GCC_BLSP1_UART1_APPS_CFG_RCGR);
+}
+
+void uart1_set_rate_mnd(unsigned int m,
+ unsigned int n, unsigned int two_d)
+{
+ writel(m, GCC_BLSP1_UART1_APPS_M);
+ writel(n, GCC_BLSP1_UART1_APPS_N);
+ writel(two_d, GCC_BLSP1_UART1_APPS_D);
+}
+
+void reset_board(void)
+{
+ run_command("reset", 0);
+}
+
+void uart1_toggle_clock(void)
+{
+ unsigned long cbcr_val;
+
+ cbcr_val = readl(GCC_BLSP1_UART1_APPS_CBCR);
+ cbcr_val |= UART1_CBCR_CLK_ENABLE;
+ writel(cbcr_val, GCC_BLSP1_UART1_APPS_CBCR);
+}
+
+int uart1_trigger_update(void)
+{
+ unsigned long cmd_rcgr;
+ int timeout = 0;
+
+ cmd_rcgr = readl(GCC_BLSP1_UART1_APPS_CMD_RCGR);
+ cmd_rcgr |= UART1_CMD_RCGR_UPDATE | UART1_CMD_RCGR_ROOT_EN;
+ writel(cmd_rcgr, GCC_BLSP1_UART1_APPS_CMD_RCGR);
+
+ while (readl(GCC_BLSP1_UART1_APPS_CMD_RCGR) & UART1_CMD_RCGR_UPDATE) {
+ if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
+ printf("Timeout waiting for UART1 clock update\n");
+ return -ETIMEDOUT;
+ udelay(1);
+ }
+ }
+ uart1_toggle_clock();
+ return 0;
+}
+
+int uart1_clock_config(struct ipq_serial_platdata *plat)
+{
+
+ uart1_configure_mux();
+ uart1_set_rate_mnd(plat->m_value,
+ plat->n_value,
+ plat->d_value);
+ return uart1_trigger_update();
+}
+
+void qca_serial_init(struct ipq_serial_platdata *plat)
+{
+ int ret;
+
+ if (plat->gpio_node < 0) {
+ printf("serial_init: unable to find gpio node \n");
+ return;
+ }
+ qca_gpio_init(plat->gpio_node);
+ ret = uart1_clock_config(plat);
+ if (ret)
+ printf("UART clock config failed %d \n", ret);
+}
+
+/*
+ * Set the uuid in bootargs variable for mounting rootfilesystem
+ */
+#ifdef CONFIG_QCA_MMC
+int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, bool gpt_flag)
+{
+ int ret, len;
+ block_dev_desc_t *blk_dev;
+ disk_partition_t disk_info;
+
+ blk_dev = mmc_get_dev(mmc_host.dev_num);
+ if (!blk_dev) {
+ printf("Invalid block device name\n");
+ return -EINVAL;
+ }
+
+ if (buflen <= 0 || buflen > MAX_BOOT_ARGS_SIZE)
+ return -EINVAL;
+
+#ifdef CONFIG_PARTITION_UUIDS
+ ret = get_partition_info_efi_by_name(blk_dev,
+ part_name, &disk_info);
+ if (ret) {
+ printf("bootipq: unsupported partition name %s\n",part_name);
+ return -EINVAL;
+ }
+ if ((len = strlcpy(boot_args, "root=PARTUUID=", buflen)) >= buflen)
+ return -EINVAL;
+#else
+ if ((len = strlcpy(boot_args, "rootfsname=", buflen)) >= buflen)
+ return -EINVAL;
+#endif
+ boot_args += len;
+ buflen -= len;
+
+#ifdef CONFIG_PARTITION_UUIDS
+ if ((len = strlcpy(boot_args, disk_info.uuid, buflen)) >= buflen)
+ return -EINVAL;
+#else
+ if ((len = strlcpy(boot_args, part_name, buflen)) >= buflen)
+ return -EINVAL;
+#endif
+ boot_args += len;
+ buflen -= len;
+
+ if (gpt_flag && strlcpy(boot_args, " gpt", buflen) >= buflen)
+ return -EINVAL;
+
+ return 0;
+}
+#else
+int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, bool gpt_flag)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_QCA_MMC
+void emmc_clock_config(void)
+{
+ /* Enable root clock generator */
+ writel(readl(GCC_SDCC1_APPS_CBCR)|0x1, GCC_SDCC1_APPS_CBCR);
+ /* Add 10us delay for CLK_OFF to get cleared */
+ udelay(10);
+ writel(readl(GCC_SDCC1_AHB_CBCR)|0x1, GCC_SDCC1_AHB_CBCR);
+ /* PLL0 - 192Mhz */
+ writel(0x20B, GCC_SDCC1_APPS_CFG_RCGR);
+ /* Delay for clock operation complete */
+ udelay(10);
+ writel(0x1, GCC_SDCC1_APPS_M);
+ /* check this M, N D value while debugging
+ * because as per clock tool the actual M, N, D
+ * values are M=1, N=FA, D=F9
+ */
+ writel(0xFC, GCC_SDCC1_APPS_N);
+ writel(0xFD, GCC_SDCC1_APPS_D);
+ /* Delay for clock operation complete */
+ udelay(10);
+ /* Update APPS_CMD_RCGR to reflect source selection */
+ writel(readl(GCC_SDCC1_APPS_CMD_RCGR)|0x1, GCC_SDCC1_APPS_CMD_RCGR);
+ /* Add 10us delay for clock update to complete */
+ udelay(10);
+}
+
+void mmc_iopad_config(struct sdhci_host *host)
+{
+ u32 val;
+ val = sdhci_readb(host, SDHCI_VENDOR_IOPAD);
+ /*set bit 15 & 16*/
+ val |= 0x18000;
+ writel(val, host->ioaddr + SDHCI_VENDOR_IOPAD);
+}
+
+void sdhci_bus_pwr_off(struct sdhci_host *host)
+{
+ u32 val;
+
+ val = sdhci_readb(host, SDHCI_HOST_CONTROL);
+ sdhci_writeb(host,(val & (~SDHCI_POWER_ON)), SDHCI_POWER_CONTROL);
+}
+
+__weak void board_mmc_deinit(void)
+{
+ /*since we do not have misc register in ipq5018
+ * so simply return from this function
+ */
+ return;
+}
+
+void emmc_clock_reset(void)
+{
+ writel(0x1, GCC_SDCC1_BCR);
+ udelay(10);
+ writel(0x0, GCC_SDCC1_BCR);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+ int node, gpio_node;
+ int ret = 0;
+ qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
+ node = fdt_path_offset(gd->fdt_blob, "mmc");
+ if (node < 0) {
+ printf("sdhci: Node Not found, skipping initialization\n");
+ return -1;
+ }
+
+ gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "mmc_gpio");
+ qca_gpio_init(gpio_node);
+
+ mmc_host.ioaddr = (void *)MSM_SDC1_SDHCI_BASE;
+ mmc_host.voltages = MMC_VDD_165_195;
+ mmc_host.version = SDHCI_SPEC_300;
+ mmc_host.cfg.part_type = PART_TYPE_EFI;
+ mmc_host.quirks = SDHCI_QUIRK_BROKEN_VOLTAGE;
+
+ emmc_clock_reset();
+ udelay(10);
+ emmc_clock_config();
+
+ if (add_sdhci(&mmc_host, 200000000, 400000)) {
+ printf("add_sdhci fail!\n");
+ return -1;
+ }
+
+ if (!ret && sfi->flash_type == SMEM_BOOT_MMC_FLASH) {
+ ret = board_mmc_env_init(mmc_host);
+ }
+
+ return ret;
+}
+#else
+int board_mmc_init(bd_t *bis)
+{
+ return 0;
+}
+#endif
+
+__weak int ipq_get_tz_version(char *version_name, int buf_size)
+{
+ return 1;
+}
+
+int apps_iscrashed(void)
+{
+ u32 *dmagic = (u32 *)CONFIG_IPQ5018_DMAGIC_ADDR;
+
+ if (*dmagic == DLOAD_MAGIC_COOKIE)
+ return 1;
+
+ return 0;
+}
+
+static void __fixup_usb_device_mode(void *blob)
+{
+ parse_fdt_fixup("/soc/usb3@8A00000/dwc3@8A00000%dr_mode%?peripheral", blob);
+ parse_fdt_fixup("/soc/usb3@8A00000/dwc3@8A00000%maximum-speed%?high-speed", blob);
+}
+
+static void fdt_fixup_diag_gadget(void *blob)
+{
+ __fixup_usb_device_mode(blob);
+ parse_fdt_fixup("/soc/qcom,gadget_diag@0%status%?ok", blob);
+}
+
+void ipq_fdt_fixup_usb_device_mode(void *blob)
+{
+ const char *usb_cfg;
+
+ usb_cfg = getenv("usb_mode");
+ if (!usb_cfg)
+ return;
+
+ if (!strncmp(usb_cfg, "peripheral", sizeof("peripheral")))
+ __fixup_usb_device_mode(blob);
+ else if (!strncmp(usb_cfg, "diag_gadget", sizeof("diag_gadget")))
+ fdt_fixup_diag_gadget(blob);
+ else
+ printf("%s: invalid param for usb_mode\n", __func__);
+}
+
+void ipq_fdt_fixup_socinfo(void *blob)
+{
+ uint32_t cpu_type;
+ uint32_t soc_version, soc_version_major, soc_version_minor;
+ int nodeoff, ret;
+
+ nodeoff = fdt_path_offset(blob, "/");
+
+ if (nodeoff < 0) {
+ printf("ipq: fdt fixup cannot find root node\n");
+ return;
+ }
+
+ ret = ipq_smem_get_socinfo_cpu_type(&cpu_type);
+ if (!ret) {
+ ret = fdt_setprop(blob, nodeoff, "cpu_type",
+ &cpu_type, sizeof(cpu_type));
+ if (ret)
+ printf("%s: cannot set cpu type %d\n", __func__, ret);
+ } else {
+ printf("%s: cannot get socinfo\n", __func__);
+ }
+
+ ret = ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
+ if (!ret) {
+ soc_version_major = SOCINFO_VERSION_MAJOR(soc_version);
+ soc_version_minor = SOCINFO_VERSION_MINOR(soc_version);
+
+ ret = fdt_setprop(blob, nodeoff, "soc_version_major",
+ &soc_version_major,
+ sizeof(soc_version_major));
+ if (ret)
+ printf("%s: cannot set soc_version_major %d\n",
+ __func__, soc_version_major);
+
+ ret = fdt_setprop(blob, nodeoff, "soc_version_minor",
+ &soc_version_minor,
+ sizeof(soc_version_minor));
+ if (ret)
+ printf("%s: cannot set soc_version_minor %d\n",
+ __func__, soc_version_minor);
+ } else {
+ printf("%s: cannot get soc version\n", __func__);
+ }
+ return;
+}
+
+void fdt_fixup_auto_restart(void *blob)
+{
+ const char *paniconwcssfatal;
+
+ paniconwcssfatal = getenv("paniconwcssfatal");
+
+ if (!paniconwcssfatal)
+ return;
+
+ if (strncmp(paniconwcssfatal, "1", sizeof("1"))) {
+ printf("fixup_auto_restart: invalid variable 'paniconwcssfatal'");
+ } else {
+ parse_fdt_fixup("/soc/q6v5_wcss@CD00000%delete%?qca,auto-restart", blob);
+ }
+ return;
+}
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+int bt_running;
+
+unsigned char hci_reset[] =
+{0x01, 0x03, 0x0c, 0x00};
+
+unsigned char adv_data[] =
+{0x01, 0X08, 0X20, 0X20, 0X1F, 0X0A, 0X09, 0X71,
+ 0X75, 0X61, 0X6c, 0X63, 0X6f, 0X6d, 0X6d, 0X00,
+ 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
+ 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
+ 0X00, 0X00, 0X00, 0X00};
+
+unsigned char set_interval[] =
+{0X01, 0X06, 0X20, 0X0F, 0X20, 0X00, 0X20, 0X00,
+ 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
+ 0X00, 0X07, 0X00};
+
+unsigned char start_beacon[] =
+{0x01, 0x0A, 0x20, 0x01, 0x01};
+
+struct hci_cmd{
+ unsigned char* data;
+ unsigned int len;
+};
+
+struct hci_cmd hci_cmds[] = {
+ { hci_reset, sizeof(hci_reset) },
+ { adv_data, sizeof(adv_data) },
+ { set_interval, sizeof(set_interval) },
+ { start_beacon, sizeof(start_beacon) },
+};
+
+int wait_for_bt_event(struct bt_descriptor *btDesc, u8 bt_wait)
+{
+ int val, timeout = 0;
+
+ do{
+ udelay(10);
+ bt_ipc_worker(btDesc);
+
+ if (bt_wait == BT_WAIT_FOR_START)
+ val = !atomic_read(&btDesc->state);
+ else
+ val = atomic_read(&btDesc->tx_in_progress);
+
+ if (timeout++ >= BT_TIMEOUT_US/10) {
+ printf(" %s timed out \n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ } while (val);
+
+ return 0;
+}
+
+static int initialize_nvm(struct bt_descriptor *btDesc,
+ void *fileaddr, u32 filesize)
+{
+ unsigned char *buffer = fileaddr;
+ int bytes_read = 0, bytes_consumed = 0, ret;
+ HCI_Packet_t *hci_packet = NULL;
+
+ while(bytes_consumed < filesize )
+ {
+ bytes_read = (filesize - bytes_consumed) > NVM_SEGMENT_SIZE ?
+ NVM_SEGMENT_SIZE : filesize - bytes_consumed;
+ /* Constructing a HCI Packet to write NVM Segments to BTSS */
+ hci_packet = (HCI_Packet_t*)malloc(sizeof(HCI_Packet_t) +
+ NVM_SEGMENT_SIZE);
+
+ if(!hci_packet)
+ {
+ printf("Cannot allocate memory to HCI Packet \n");
+ return -ENOMEM;
+ }
+
+ /* Initializing HCI Packet Header */
+ hci_packet->HCIPacketType = ptHCICommandPacket;
+
+ /* Populating TLV Request Packet in HCI */
+ LE_UNALIGNED(&(hci_packet->HCIPayload.opcode), TLV_REQ_OPCODE);
+ LE_UNALIGNED(&(hci_packet->HCIPayload.parameter_total_length),
+ (bytes_read + DATA_REMAINING_LENGTH));
+ hci_packet->HCIPayload.command_request = TLV_COMMAND_REQUEST;
+ hci_packet->HCIPayload.tlv_segment_length = bytes_read;
+ memcpy(hci_packet->HCIPayload.tlv_segment_data, buffer,
+ bytes_read);
+
+ bt_ipc_sendmsg(btDesc, (u8*)hci_packet,
+ sizeof(HCI_Packet_t) + bytes_read);
+
+ free(hci_packet);
+ bytes_consumed += bytes_read;
+ buffer = fileaddr + bytes_consumed;
+
+ ret = wait_for_bt_event(btDesc, BT_WAIT_FOR_TX_COMPLETE);
+ if(ret || *((u8 *)btDesc->buf + TLV_RESPONSE_STATUS_INDEX) != 0)
+ {
+ printf( "\n NVM download failed\n");
+ if (!ret) {
+ kfree(btDesc->buf);
+ btDesc->buf = NULL;
+ }
+ return -EINVAL;
+ }
+ kfree(btDesc->buf);
+ btDesc->buf = NULL;
+ }
+
+ printf("NVM download successful \n");
+ bt_ipc_worker(btDesc);
+ return 0;
+}
+
+int send_bt_hci_cmds(struct bt_descriptor *btDesc)
+{
+ int ret, i;
+ int count = sizeof hci_cmds/ sizeof(struct hci_cmd);
+
+ for (i = 0; i < count; i++) {
+ bt_ipc_sendmsg(btDesc, hci_cmds[i].data, hci_cmds[i].len);
+
+ ret = wait_for_bt_event(btDesc, BT_WAIT_FOR_TX_COMPLETE);
+ if (ret)
+ return ret;
+
+ /*btDesc->buf will have response data with length btDesc->len*/
+ kfree(btDesc->buf);
+ btDesc->buf = NULL;
+ }
+ return 0;
+}
+
+int bt_init(void)
+{
+ struct bt_descriptor *btDesc;
+ int ret;
+
+ btDesc = kzalloc(sizeof(*btDesc), GFP_KERNEL);
+ if (!btDesc)
+ return -ENOMEM;
+
+ bt_ipc_init(btDesc);
+
+ enable_btss_lpo_clk();
+ ret = qti_scm_pas_init_image(PAS_ID, (u32)bt_fw_patchmdt);
+ if (ret) {
+ printf("patch auth failed\n");
+ return ret;
+ }
+
+ printf("patch authenticated successfully\n");
+
+ memcpy((void*)BT_RAM_PATCH, (void*)bt_fw_patchb02,
+ sizeof bt_fw_patchb02);
+
+ ret = qti_pas_and_auth_reset(PAS_ID);
+
+ if (ret) {
+ printf("BT out of reset failed\n");
+ return ret;
+ }
+
+ ret = wait_for_bt_event(btDesc, BT_WAIT_FOR_START);
+ if (ret)
+ return ret;
+
+ ret = initialize_nvm(btDesc, (void*)mpnv10bin, sizeof mpnv10bin);
+ if (ret)
+ return ret;
+
+ ret = wait_for_bt_event(btDesc, BT_WAIT_FOR_START);
+ if (ret)
+ return ret;
+
+ send_bt_hci_cmds(btDesc);
+
+ bt_running = 1;
+ return 0;
+}
+
+void fdt_fixup_bt_running(void *blob)
+{
+ if (bt_running) {
+ parse_fdt_fixup("/soc/bt@7000000%qcom,bt-running%1", blob);
+ }
+}
+#endif
+
+void reset_crashdump(void)
+{
+ unsigned int ret = 0;
+ qca_scm_sdi();
+ ret = qca_scm_dload(CLEAR_MAGIC);
+ if (ret)
+ printf ("Error in reseting the Magic cookie\n");
+ return;
+}
+
+void psci_sys_reset(void)
+{
+ __invoke_psci_fn_smc(0x84000009, 0, 0, 0);
+}
+
+void qti_scm_pshold(void)
+{
+ int ret;
+
+ ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_PSHOLD, NULL, 0, NULL, 0);
+
+ if (ret != 0)
+ writel(0, GCNT_PSHOLD);
+}
+
+void reset_cpu(unsigned long a)
+{
+ reset_crashdump();
+ if (is_scm_armv8()) {
+ psci_sys_reset();
+ } else {
+ qti_scm_pshold();
+ }
+ while(1);
+}
+
+#ifdef CONFIG_QPIC_NAND
+void qpic_set_clk_rate(unsigned int clk_rate, int blk_type, int req_clk_src_type)
+{
+ switch (blk_type) {
+ case QPIC_IO_MACRO_CLK:
+ /* select the clk source for IO_PAD_MACRO
+ * clk source wil be either XO = 24MHz. or GPLL0 = 800MHz.
+ */
+ if (req_clk_src_type == XO_CLK_SRC) {
+ /* default XO clock will enabled
+ * i.e XO clock = 24MHz.
+ * so div value will 0.
+ * Input clock to IO_MACRO will be divided by 4 by default
+ * by hardware and then taht clock will be go on bus.
+ * i.e 24/4MHz = 6MHz i.e 6MHz will go onto the bus.
+ */
+ writel(0x0, GCC_QPIC_IO_MACRO_CFG_RCGR);
+
+ } else if (req_clk_src_type == GPLL0_CLK_SRC) {
+ /* selct GPLL0 clock source 800MHz
+ * so 800/4 = 200MHz.
+ * Input clock to IO_MACRO will be divided by 4 by default
+ * by hardware and then that clock will be go on bus.
+ * i.e 200/4MHz = 50MHz i.e 50MHz will go onto the bus.
+ */
+ if (clk_rate == IO_MACRO_CLK_320_MHZ)
+ writel(0x104, GCC_QPIC_IO_MACRO_CFG_RCGR);
+ else if (clk_rate == IO_MACRO_CLK_266_MHZ)
+ writel(0x105, GCC_QPIC_IO_MACRO_CFG_RCGR);
+ else if (clk_rate == IO_MACRO_CLK_228_MHZ)
+ writel(0x106, GCC_QPIC_IO_MACRO_CFG_RCGR);
+ else if (clk_rate == IO_MACRO_CLK_100_MHZ)
+ writel(0x10F, GCC_QPIC_IO_MACRO_CFG_RCGR);
+ else if (clk_rate == IO_MACRO_CLK_200_MHZ)
+ writel(0x107, GCC_QPIC_IO_MACRO_CFG_RCGR);
+
+ } else {
+ printf("wrong clk src selection requested.\n");
+ }
+
+ /* Enablle update bit to update the new configuration */
+ writel((UPDATE_EN | readl(GCC_QPIC_IO_MACRO_CMD_RCGR)),
+ GCC_QPIC_IO_MACRO_CMD_RCGR);
+
+ /* Enable the QPIC_IO_MACRO_CLK */
+ writel(0x1, GCC_QPIC_IO_MACRO_CBCR);
+
+ break;
+ case QPIC_CORE_CLK:
+ /* To DO if needed for QPIC core clock setting */
+ break;
+ default:
+ printf("wrong qpic block type\n");
+ break;
+ }
+}
+#endif
+
+void board_nand_init(void)
+{
+#ifdef CONFIG_QPIC_SERIAL
+ /* check for nand node in dts
+ * if nand node in dts is disabled then
+ * simply return from here without
+ * initializing
+ */
+ int node;
+ node = fdt_path_offset(gd->fdt_blob, "/nand-controller");
+ if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) {
+ printf("QPIC: disabled, skipping initialization\n");
+ } else {
+ qpic_nand_init(NULL);
+ }
+#endif
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+ bt_init();
+#endif
+#ifdef CONFIG_QCA_SPI
+ int gpio_node;
+ gpio_node = fdt_path_offset(gd->fdt_blob, "/spi/spi_gpio");
+ if (gpio_node >= 0) {
+ qca_gpio_init(gpio_node);
+#ifdef CONFIG_MTD_DEVICE
+ ipq_spi_init(CONFIG_IPQ_SPI_NOR_INFO_IDX);
+#endif
+ }
+#endif
+}
+
+void enable_caches(void)
+{
+ qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
+ smem_get_boot_flash(&sfi->flash_type,
+ &sfi->flash_index,
+ &sfi->flash_chip_select,
+ &sfi->flash_block_size,
+ &sfi->flash_density);
+ icache_enable();
+ /*Skips dcache_enable during JTAG recovery */
+ if (sfi->flash_type)
+ dcache_enable();
+}
+
+void disable_caches(void)
+{
+ icache_disable();
+ dcache_disable();
+}
+
+unsigned long timer_read_counter(void)
+{
+ return 0;
+}
+
+static void set_ext_mdio_gpio(int node)
+{
+ unsigned int mdio_gpio[2] = {0};
+ int status = -1;
+ unsigned int *mdio_gpio_base;
+
+ status = fdtdec_get_int_array(gd->fdt_blob,
+ node,
+ "ext_mdio_gpio",
+ mdio_gpio,
+ 2);
+ if (status >= 0) {
+ /* mdc */
+ mdio_gpio_base =
+ (unsigned int *)GPIO_CONFIG_ADDR(mdio_gpio[0]);
+ writel(0x7, mdio_gpio_base);
+ /* mdio */
+ mdio_gpio_base =
+ (unsigned int *)GPIO_CONFIG_ADDR(mdio_gpio[1]);
+ writel(0x7, mdio_gpio_base);
+ }
+}
+
+static void reset_napa_phy_gpio(int gpio)
+{
+ unsigned int *napa_gpio_base;
+
+ napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+ writel(0x203, napa_gpio_base);
+ writel(0x0, GPIO_IN_OUT_ADDR(gpio));
+ mdelay(500);
+ writel(0x2, GPIO_IN_OUT_ADDR(gpio));
+}
+
+static void reset_8033_phy_gpio(int gpio)
+{
+ unsigned int *phy_8033_gpio_base;
+
+ ppe_uniphy_refclk_set();
+ phy_8033_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+ writel(0x2C1, phy_8033_gpio_base);
+ writel(0x0, GPIO_IN_OUT_ADDR(gpio));
+ mdelay(500);
+ writel(0x2, GPIO_IN_OUT_ADDR(gpio));
+}
+
+static void reset_s17c_switch_gpio(int gpio)
+{
+ unsigned int *switch_gpio_base =
+ (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+/*
+ * Set ref clock 25MHZ and enable Force mode
+ */
+ ppe_uniphy_refclk_set();
+ ppe_uniphy_set_forceMode();
+
+ writel(0x203, switch_gpio_base);
+ writel(0x0, GPIO_IN_OUT_ADDR(gpio));
+ mdelay(500);
+ writel(0x2, GPIO_IN_OUT_ADDR(gpio));
+}
+
+static void cmn_blk_clk_set(void)
+{
+ /* GMN block */
+ writel(0x1, GCC_CMN_BLK_AHB_CBCR);
+ mdelay(20);
+ writel(0x1, GCC_CMN_BLK_SYS_CBCR);
+ mdelay(20);
+}
+
+static void uniphy_clk_set(void)
+{
+ writel(0x1, GCC_UNIPHY_AHB_CBCR);
+ mdelay(20);
+ writel(0x1, GCC_UNIPHY_SYS_CBCR);
+ mdelay(20);
+ writel(0x1, GCC_UNIPHY_RX_CBCR);
+ mdelay(20);
+ writel(0x1, GCC_UNIPHY_TX_CBCR);
+ mdelay(20);
+
+}
+
+static void gephy_uniphy_clock_disable(void)
+{
+ u32 reg_val = 0;
+
+ reg_val = readl(GCC_GEPHY_RX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GEPHY_RX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_GEPHY_TX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GEPHY_TX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_UNIPHY_RX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_UNIPHY_RX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_UNIPHY_TX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_UNIPHY_TX_CBCR);
+ mdelay(20);
+
+}
+
+static void gmac_clock_disable(void)
+{
+ u32 reg_val = 0;
+
+ reg_val = readl(GCC_GMAC0_RX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GMAC0_RX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_GMAC0_TX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GMAC0_TX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_GMAC1_RX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GMAC1_RX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_GMAC1_TX_CBCR);
+ reg_val &= ~GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GMAC1_TX_CBCR);
+ mdelay(20);
+
+}
+
+static void gmac_clk_src_init(void)
+{
+ u32 reg_val, iGmac_id, iTxRx;
+
+ /*select source of GMAC*/
+ reg_val = readl(GCC_GMAC0_RX_CFG_RCGR);
+ reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK;
+ reg_val |= GCC_GMAC0_RX_SRC_SEL_GEPHY_TX;
+ writel(reg_val, GCC_GMAC0_RX_CFG_RCGR);
+
+ reg_val = readl(GCC_GMAC0_TX_CFG_RCGR);
+ reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK;
+ reg_val |= GCC_GMAC0_TX_SRC_SEL_GEPHY_TX;
+ writel(reg_val, GCC_GMAC0_TX_CFG_RCGR);
+
+ reg_val = readl(GCC_GMAC1_RX_CFG_RCGR);
+ reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK;
+ reg_val |= GCC_GMAC1_RX_SRC_SEL_UNIPHY_RX;
+ writel(reg_val, GCC_GMAC1_RX_CFG_RCGR);
+
+ reg_val = readl(GCC_GMAC1_TX_CFG_RCGR);
+ reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK;
+ reg_val |= GCC_GMAC1_TX_SRC_SEL_UNIPHY_TX;
+ writel(reg_val, GCC_GMAC1_TX_CFG_RCGR);
+
+ /* update above clock configuration */
+ for (iGmac_id = 0; iGmac_id < 2; ++iGmac_id) {
+ for (iTxRx = 0; iTxRx < 2; ++iTxRx){
+ reg_val = 0;
+ reg_val = readl(GCC_GMAC0_RX_CMD_RCGR +
+ (iTxRx * 8) + (iGmac_id * 0x10));
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_RX_CMD_RCGR +
+ (iTxRx * 8) + (iGmac_id * 0x10));
+ }
+ }
+ reg_val = readl(GCC_GMAC_CFG_RCGR);
+ reg_val = 0x209;
+ writel(reg_val, GCC_GMAC_CFG_RCGR);
+
+ reg_val = readl(GCC_GMAC_CMD_RCGR);
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC_CMD_RCGR);
+}
+
+static void gephy_reset(void)
+{
+ u32 reg_val;
+
+ reg_val = readl(GCC_GEPHY_BCR);
+ writel(reg_val | (GCC_GEPHY_BCR_BLK_ARES),
+ GCC_GEPHY_BCR);
+ mdelay(20);
+ writel(reg_val & (~GCC_GEPHY_BCR_BLK_ARES),
+ GCC_GEPHY_BCR);
+ reg_val = readl(GCC_GEPHY_MISC);
+ writel(reg_val | (GCC_GEPHY_MISC_ARES),
+ GCC_GEPHY_MISC);
+ mdelay(20);
+ writel(reg_val & (~GCC_GEPHY_MISC_ARES),
+ GCC_GEPHY_MISC);
+}
+
+static void uniphy_reset(void)
+{
+ u32 reg_val;
+
+ reg_val = readl(GCC_UNIPHY_BCR);
+ writel(reg_val | (GCC_UNIPHY_BCR_BLK_ARES),
+ GCC_UNIPHY_BCR);
+ mdelay(20);
+ writel(reg_val & (~GCC_UNIPHY_BCR_BLK_ARES),
+ GCC_UNIPHY_BCR);
+}
+
+static void gmac_reset(void)
+{
+ u32 reg_val;
+
+ reg_val = readl(GCC_GMAC0_BCR);
+ writel(reg_val | (GCC_GMAC0_BCR_BLK_ARES),
+ GCC_GMAC0_BCR);
+ mdelay(20);
+ writel(reg_val & (~GCC_GMAC0_BCR_BLK_ARES),
+ GCC_GMAC0_BCR);
+
+ reg_val = readl(GCC_GMAC1_BCR);
+ writel(reg_val | (GCC_GMAC1_BCR_BLK_ARES),
+ GCC_GMAC1_BCR);
+ mdelay(200);
+ writel(reg_val & (~GCC_GMAC1_BCR_BLK_ARES),
+ GCC_GMAC1_BCR);
+
+}
+
+static void cmn_clock_init (void)
+{
+ u32 reg_val = 0;
+#ifdef INTERNAL_96MHZ
+ reg_val = readl(CMN_BLK_PLL_SRC_ADDR);
+ reg_val = ((reg_val & PLL_CTRL_SRC_MASK) |
+ (CMN_BLK_PLL_SRC_SEL_FROM_REG << 0x8));
+ writel(reg_val, CMN_BLK_PLL_SRC_ADDR);
+ reg_val = readl(CMN_BLK_ADDR + 4);
+ reg_val = (reg_val & PLL_REFCLK_DIV_MASK) | PLL_REFCLK_DIV_2;
+ writel(reg_val, CMN_BLK_ADDR + 0x4);
+#else
+ reg_val = readl(CMN_BLK_ADDR + 4);
+ reg_val = (reg_val & FREQUENCY_MASK) | INTERNAL_48MHZ_CLOCK;
+ writel(reg_val, CMN_BLK_ADDR + 0x4);
+#endif
+ reg_val = readl(CMN_BLK_ADDR);
+ reg_val = reg_val | 0x40;
+ writel(reg_val, CMN_BLK_ADDR);
+ mdelay(1);
+ reg_val = reg_val & (~0x40);
+ writel(reg_val, CMN_BLK_ADDR);
+ mdelay(1);
+ writel(0xbf, CMN_BLK_ADDR);
+ mdelay(1);
+ writel(0xff, CMN_BLK_ADDR);
+ mdelay(1);
+}
+
+static void cmnblk_enable(void)
+{
+ u32 reg_val;
+
+ reg_val = readl(TCSR_ETH_LDO_RDY_REG);
+ reg_val |= ETH_LDO_RDY;
+ writel(reg_val, TCSR_ETH_LDO_RDY_REG);
+}
+
+static void cmnblk_check_state(void)
+{
+ u32 reg_val, times = 20;
+
+ while(times--)
+ {
+ reg_val = readl(CMN_PLL_PLL_LOCKED_REG);
+ if(reg_val & CMN_PLL_LOCKED) {
+ printf("cmbblk is stable %x\n",
+ reg_val);
+ break;
+ }
+ mdelay(10);
+ }
+ if(!times) {
+ printf("200ms have been over %x\n",
+ readl(CMN_PLL_PLL_LOCKED_REG));
+ }
+}
+
+static void gcc_clock_enable(void)
+{
+ u32 reg_val;
+
+ reg_val = readl(GCC_MDIO0_BASE + 0x4);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_MDIO0_BASE + 0x4);
+
+ reg_val = readl(GCC_MDIO0_BASE + 0x14);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_MDIO0_BASE + 0x14);
+
+ reg_val = readl(GCC_GMAC0_SYS_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_SYS_CBCR);
+
+ reg_val = readl(GCC_GMAC0_PTP_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_PTP_CBCR);
+
+ reg_val = readl(GCC_GMAC0_CFG_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_CFG_CBCR);
+
+ reg_val = readl(GCC_GMAC1_SYS_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC1_SYS_CBCR);
+
+ reg_val = readl(GCC_GMAC1_PTP_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC1_PTP_CBCR);
+
+ reg_val = readl(GCC_GMAC1_CFG_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC1_CFG_CBCR);
+
+ reg_val = readl(GCC_GMAC0_RX_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_RX_CBCR);
+
+ reg_val = readl(GCC_GMAC0_TX_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC0_TX_CBCR);
+
+ reg_val = readl(GCC_GMAC1_RX_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC1_RX_CBCR);
+
+ reg_val = readl(GCC_GMAC1_TX_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_GMAC1_TX_CBCR);
+
+ reg_val = readl(GCC_SNOC_GMAC0_AHB_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_SNOC_GMAC0_AHB_CBCR);
+
+ reg_val = readl(GCC_SNOC_GMAC1_AHB_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_SNOC_GMAC1_AHB_CBCR);
+
+ reg_val = readl(GCC_SNOC_GMAC0_AXI_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_SNOC_GMAC0_AXI_CBCR);
+
+ reg_val = readl(GCC_SNOC_GMAC1_AXI_CBCR);
+ reg_val |= 0x1;
+ writel(reg_val, GCC_SNOC_GMAC1_AXI_CBCR);
+}
+
+static void ethernet_clock_enable(void)
+{
+ cmn_blk_clk_set();
+ uniphy_clk_set();
+ gephy_uniphy_clock_disable();
+ gmac_clock_disable();
+ gmac_clk_src_init();
+ cmn_clock_init();
+ cmnblk_enable();
+ cmnblk_check_state();
+ gephy_reset();
+ uniphy_reset();
+ gmac_reset();
+ gcc_clock_enable();
+}
+
+static void enable_gephy_led(int gpio)
+{
+ unsigned int *led_gpio_base =
+ (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+
+ writel(0xc5, led_gpio_base);
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int status;
+ int led_gpio;
+ int gmac_cfg_node = 0, offset = 0;
+ int loop = 0;
+ int switch_gpio = 0;
+ unsigned int tmp_phy_array[8] = {0};
+
+ gmac_cfg_node = fdt_path_offset(gd->fdt_blob, "/gmac_cfg");
+ if (gmac_cfg_node >= 0) {
+ /*
+ * Clock enable
+ */
+ ethernet_clock_enable();
+ led_gpio = fdtdec_get_uint(gd->fdt_blob,
+ gmac_cfg_node, "gephy_led", 0);
+ if (led_gpio)
+ enable_gephy_led(led_gpio);
+
+ set_ext_mdio_gpio(gmac_cfg_node);
+
+ for (offset = fdt_first_subnode(gd->fdt_blob, gmac_cfg_node);
+ offset > 0;
+ offset = fdt_next_subnode(gd->fdt_blob, offset) , loop++) {
+
+ gmac_cfg[loop].base = fdtdec_get_uint(gd->fdt_blob,
+ offset, "base", 0);
+
+ gmac_cfg[loop].unit = fdtdec_get_uint(gd->fdt_blob,
+ offset, "unit", 0);
+
+ gmac_cfg[loop].phy_addr = fdtdec_get_uint(gd->fdt_blob,
+ offset, "phy_address", 0);
+
+ gmac_cfg[loop].phy_interface_mode = fdtdec_get_uint(gd->fdt_blob,
+ offset, "phy_interface_mode", 0);
+
+ gmac_cfg[loop].phy_external_link = fdtdec_get_uint(gd->fdt_blob,
+ offset, "phy_external_link", 0);
+
+ gmac_cfg[loop].phy_napa_gpio = fdtdec_get_uint(gd->fdt_blob,
+ offset, "napa_gpio", 0);
+ if (gmac_cfg[loop].phy_napa_gpio){
+ reset_napa_phy_gpio(gmac_cfg[loop].phy_napa_gpio);
+ }
+ gmac_cfg[loop].phy_8033_gpio = fdtdec_get_uint(gd->fdt_blob,
+ offset, "8033_gpio", 0);
+ if (gmac_cfg[loop].phy_8033_gpio){
+ reset_8033_phy_gpio(gmac_cfg[loop].phy_8033_gpio);
+ }
+ switch_gpio = fdtdec_get_uint(gd->fdt_blob, offset, "switch_gpio", 0);
+ if (switch_gpio) {
+ reset_s17c_switch_gpio(switch_gpio);
+ }
+ gmac_cfg[loop].phy_type = fdtdec_get_uint(gd->fdt_blob,
+ offset, "phy_type", -1);
+
+ gmac_cfg[loop].mac_pwr = fdtdec_get_uint(gd->fdt_blob,
+ offset, "mac_pwr", 0);
+
+ gmac_cfg[loop].ipq_swith = fdtdec_get_uint(gd->fdt_blob,
+ offset, "s17c_switch_enable", 0);
+ if (gmac_cfg[loop].ipq_swith) {
+ gmac_cfg[loop].switch_port_count = fdtdec_get_uint(
+ gd->fdt_blob,
+ offset, "switch_port_count", 0);
+
+ fdtdec_get_int_array(gd->fdt_blob, offset, "switch_phy_address",
+ tmp_phy_array, gmac_cfg[loop].switch_port_count);
+
+ for(int inner_loop = 0; inner_loop < gmac_cfg[loop].switch_port_count;
+ inner_loop++){
+ gmac_cfg[loop].switch_port_phy_address[inner_loop] =
+ (char)tmp_phy_array[inner_loop];
+ }
+ }
+ }
+ }
+
+ if (loop < CONFIG_IPQ_NO_MACS)
+ gmac_cfg[loop].unit = -1;
+
+ status = ipq_gmac_init(gmac_cfg);
+
+ return status;
+}
+
+void set_flash_secondary_type(qca_smem_flash_info_t *smem)
+{
+ return;
+};
+
+#ifdef CONFIG_USB_XHCI_IPQ
+void board_usb_deinit(int id)
+{
+ int nodeoff, ssphy, gpio_node;
+ char node_name[8];
+
+ if(readl(EUD_EUD_EN2))
+ /*
+ * Eud enable skipping deinit part
+ */
+ return;
+
+ snprintf(node_name, sizeof(node_name), "usb%d", id);
+ nodeoff = fdt_path_offset(gd->fdt_blob, node_name);
+ if (fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0))
+ return;
+
+ ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0);
+ /* Enable USB PHY Power down */
+ setbits_le32(QUSB2PHY_BASE + 0xA4, 0x0);
+ /* Disable clocks */
+ writel(0x0, GCC_USB0_PHY_CFG_AHB_CBCR);
+ writel(0x4220, GCC_USB0_MASTER_CBCR);
+ writel(0x0, GCC_SYS_NOC_USB0_AXI_CBCR);
+ writel(0x0, GCC_USB0_SLEEP_CBCR);
+ writel(0x0, GCC_USB0_MOCK_UTMI_CBCR);
+ writel(0x0, GCC_USB0_AUX_CBCR);
+ writel(0x0, GCC_USB0_LFPS_CBCR);
+ /* GCC_QUSB2_0_PHY_BCR */
+ set_mdelay_clearbits_le32(GCC_QUSB2_0_PHY_BCR, 0x1, 10);
+ /* GCC_USB0_PHY_BCR */
+ if (ssphy)
+ set_mdelay_clearbits_le32(GCC_USB0_PHY_BCR, 0x1, 10);
+ /* GCC Reset USB BCR */
+ set_mdelay_clearbits_le32(GCC_USB0_BCR, 0x1, 10);
+ /* Deselect the usb phy mux */
+ if (ssphy)
+ writel(0x0, TCSR_USB_PCIE_SEL);
+
+ /* skip gpio pull config if bt_debug is enabled */
+ if(getenv("bt_debug"))
+ return;
+
+ /* deinit USB power GPIO for drive 5V */
+ gpio_node = fdt_subnode_offset(gd->fdt_blob, nodeoff, "usb_gpio");
+ if (gpio_node >= 0){
+ gpio_node = fdt_first_subnode(gd->fdt_blob, gpio_node);
+ if (gpio_node > 0) {
+ int gpio = fdtdec_get_uint(gd->fdt_blob,
+ gpio_node, "gpio", 0);
+ unsigned int *gpio_base =
+ (unsigned int *)GPIO_CONFIG_ADDR(gpio);
+ int usb_pwr_gpio = fdtdec_get_int(gd->fdt_blob, nodeoff, "usb_pwr_gpio", 0);
+ writel(0xC1, gpio_base);
+ gpio_set_value(usb_pwr_gpio, GPIO_OUT_LOW);
+ }
+ }
+
+}
+
+static void usb_clock_init(int id, int ssphy)
+{
+ int cfg;
+
+ /* select usb phy mux */
+ if (ssphy)
+ writel(0x1, TCSR_USB_PCIE_SEL);
+
+ /* Configure usb0_master_clk_src */
+ cfg = (GCC_USB0_MASTER_CFG_RCGR_SRC_SEL |
+ GCC_USB0_MASTER_CFG_RCGR_SRC_DIV);
+ writel(cfg, GCC_USB0_MASTER_CFG_RCGR);
+ writel(CMD_UPDATE, GCC_USB0_MASTER_CMD_RCGR);
+ mdelay(100);
+ writel(ROOT_EN, GCC_USB0_MASTER_CMD_RCGR);
+
+ /* Configure usb0_mock_utmi_clk_src */
+ cfg = (GCC_USB_MOCK_UTMI_SRC_SEL |
+ GCC_USB_MOCK_UTMI_SRC_DIV);
+ writel(cfg, GCC_USB0_MOCK_UTMI_CFG_RCGR);
+ writel(GCC_USB_MOCK_UTMI_CLK_DIV, GCC_USB0_MOCK_UTMI_CBCR);
+ writel(CMD_UPDATE, GCC_USB0_MOCK_UTMI_CMD_RCGR);
+ mdelay(100);
+ writel(ROOT_EN, GCC_USB0_MOCK_UTMI_CMD_RCGR);
+
+ /* Configure usb0_aux_clk_src */
+ cfg = (GCC_USB0_AUX_CFG_SRC_SEL |
+ GCC_USB0_AUX_CFG_SRC_DIV);
+ writel(cfg, GCC_USB0_AUX_CFG_RCGR);
+ writel(CMD_UPDATE, GCC_USB0_AUX_CMD_RCGR);
+ mdelay(100);
+ writel(ROOT_EN, GCC_USB0_AUX_CMD_RCGR);
+
+ /* Configure usb0_lfps_cmd_rcgr */
+ cfg = (GCC_USB0_LFPS_CFG_SRC_SEL |
+ GCC_USB0_LFPS_CFG_SRC_DIV);
+ writel(cfg, GCC_USB0_LFPS_CFG_RCGR);
+ writel(LFPS_M, GCC_USB0_LFPS_M);
+ writel(LFPS_N, GCC_USB0_LFPS_N);
+ writel(LFPS_D, GCC_USB0_LFPS_D);
+ writel(readl(GCC_USB0_LFPS_CFG_RCGR) | GCC_USB0_LFPS_MODE,
+ GCC_USB0_LFPS_CFG_RCGR);
+ writel(CMD_UPDATE, GCC_USB0_LFPS_CMD_RCGR);
+ mdelay(100);
+ writel(ROOT_EN, GCC_USB0_LFPS_CMD_RCGR);
+
+ /* Configure CBCRs */
+ writel(CLK_DISABLE, GCC_SYS_NOC_USB0_AXI_CBCR);
+ writel(CLK_ENABLE, GCC_SYS_NOC_USB0_AXI_CBCR);
+ writel((readl(GCC_USB0_MASTER_CBCR) | CLK_ENABLE),
+ GCC_USB0_MASTER_CBCR);
+ writel(CLK_ENABLE, GCC_USB0_SLEEP_CBCR);
+ writel((GCC_USB_MOCK_UTMI_CLK_DIV | CLK_ENABLE),
+ GCC_USB0_MOCK_UTMI_CBCR);
+ writel(CLK_DISABLE, GCC_USB0_PIPE_CBCR);
+ writel(CLK_ENABLE, GCC_USB0_PHY_CFG_AHB_CBCR);
+ writel(CLK_ENABLE, GCC_USB0_AUX_CBCR);
+ writel(CLK_ENABLE, GCC_USB0_LFPS_CBCR);
+}
+
+static void usb_init_hsphy(void __iomem *phybase, int ssphy)
+{
+ if (!ssphy) {
+ /*Enable utmi instead of pipe*/
+ writel((readl(USB30_GENERAL_CFG) | PIPE_UTMI_CLK_DIS), USB30_GENERAL_CFG);
+
+ udelay(100);
+
+ writel((readl(USB30_GENERAL_CFG) | PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW), USB30_GENERAL_CFG);
+
+ udelay(100);
+
+ writel((readl(USB30_GENERAL_CFG) & ~PIPE_UTMI_CLK_DIS), USB30_GENERAL_CFG);
+ }
+ /* Disable USB PHY Power down */
+ setbits_le32(phybase + 0xA4, 0x1);
+ /* Enable override ctrl */
+ writel(UTMI_PHY_OVERRIDE_EN, phybase + USB_PHY_CFG0);
+ /* Enable POR*/
+ writel(POR_EN, phybase + USB_PHY_UTMI_CTRL5);
+ udelay(15);
+ /* Configure frequency select value*/
+ writel(FREQ_SEL, phybase + USB_PHY_FSEL_SEL);
+ /* Configure refclk frequency */
+ writel(COMMONONN | FSEL | RETENABLEN,
+ phybase + USB_PHY_HS_PHY_CTRL_COMMON0);
+ /* select refclk source */
+ writel(CLKCORE, phybase + USB_PHY_REFCLK_CTRL);
+ /* select ATERESET*/
+ writel(POR_EN & ATERESET, phybase + USB_PHY_UTMI_CTRL5);
+ writel(USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN,
+ phybase + USB_PHY_HS_PHY_CTRL2);
+ writel(0x0, phybase + USB_PHY_UTMI_CTRL5);
+ writel(USB2_SUSPEND_N | USB2_UTMI_CLK_EN,
+ phybase + USB_PHY_HS_PHY_CTRL2);
+ /* Disable override ctrl */
+ writel(0x0, phybase + USB_PHY_CFG0);
+}
+
+static void usb_init_ssphy(void __iomem *phybase)
+{
+ writel(CLK_ENABLE, GCC_USB0_PHY_CFG_AHB_CBCR);
+ writel(CLK_ENABLE, GCC_USB0_PIPE_CBCR);
+ udelay(100);
+ /*set frequency initial value*/
+ writel(0x1cb9, phybase + SSCG_CTRL_REG_4);
+ writel(0x023a, phybase + SSCG_CTRL_REG_5);
+ /*set spectrum spread count*/
+ writel(0xd360, phybase + SSCG_CTRL_REG_3);
+ /*set fstep*/
+ writel(0x1, phybase + SSCG_CTRL_REG_1);
+ writel(0xeb, phybase + SSCG_CTRL_REG_2);
+ return;
+}
+
+static void usb_init_phy(int index, int ssphy)
+{
+ void __iomem *boot_clk_ctl, *usb_bcr, *qusb2_phy_bcr;
+
+ boot_clk_ctl = (u32 *)GCC_USB_0_BOOT_CLOCK_CTL;
+ usb_bcr = (u32 *)GCC_USB0_BCR;
+ qusb2_phy_bcr = (u32 *)GCC_QUSB2_0_PHY_BCR;
+
+ /* Disable USB Boot Clock */
+ clrbits_le32(boot_clk_ctl, 0x0);
+
+ /* GCC Reset USB BCR */
+ set_mdelay_clearbits_le32(usb_bcr, 0x1, 10);
+
+ if (ssphy)
+ setbits_le32(GCC_USB0_PHY_BCR, 0x1);
+ setbits_le32(qusb2_phy_bcr, 0x1);
+ udelay(1);
+ /* Config user control register */
+ writel(0x4004010, USB30_GUCTL);
+ writel(0x4945920, USB30_FLADJ);
+ if (ssphy)
+ clrbits_le32(GCC_USB0_PHY_BCR, 0x1);
+ clrbits_le32(qusb2_phy_bcr, 0x1);
+ udelay(30);
+
+ if (ssphy)
+ usb_init_ssphy((u32 *)USB3PHY_APB_BASE);
+ usb_init_hsphy((u32 *)QUSB2PHY_BASE, ssphy);
+}
+
+int ipq_board_usb_init(void)
+{
+ int i, nodeoff, ssphy, gpio_node, usb_pwr_gpio;
+ char node_name[8];
+
+ if(readl(EUD_EUD_EN2)) {
+ printf("USB: EUD Enable, skipping initialization\n");
+ return 0;
+ }
+
+ for (i=0; i<CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+ snprintf(node_name, sizeof(node_name), "usb%d", i);
+ nodeoff = fdt_path_offset(gd->fdt_blob, node_name);
+ if (nodeoff < 0){
+ printf("USB: Node Not found, skipping initialization\n");
+ return 0;
+ }
+
+ ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0);
+ if (!fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) {
+
+ usb_clock_init(i, ssphy);
+ usb_init_phy(i, ssphy);
+ }else {
+ /* Config user control register */
+ writel(0x0C804010, USB30_GUCTL);
+ }
+ }
+ /* skip gpio pull config if bt_debug is enabled */
+ if(!getenv("bt_debug")){
+ /* USB power GPIO for drive 5V */
+ gpio_node =
+ fdt_subnode_offset(gd->fdt_blob, nodeoff, "usb_gpio");
+ if (gpio_node >= 0) {
+ qca_gpio_init(gpio_node);
+ usb_pwr_gpio = fdtdec_get_int(gd->fdt_blob, nodeoff, "usb_pwr_gpio", 0);
+ gpio_set_value(usb_pwr_gpio, GPIO_OUT_HIGH);
+ }
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PCI_IPQ
+static void pcie_v2_clock_init(int lane)
+{
+#ifdef CONFIG_PCI
+ u32 reg_val;
+ void __iomem *base;
+
+ /*single lane*/
+ /* Enable SYS_NOC clock */
+ if (lane == 1) {
+ base = (void __iomem *)GCC_PCIE1_BOOT_CLOCK_CTL;
+ writel(CLK_ENABLE, GCC_SYS_NOC_PCIE1_AXI_CBCR);
+ mdelay(1);
+ /* Configure pcie1_aux_clk_src */
+ writel((GCC_PCIE1_AUX_CFG_RCGR_SRC_SEL |
+ GCC_PCIE1_AUX_CFG_RCGR_SRC_DIV),
+ base + PCIE_AUX_CFG_RCGR);
+ mdelay(1);
+ reg_val = readl(base + PCIE_AUX_CMD_RCGR);
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, base + PCIE_AUX_CMD_RCGR);
+
+ /* Configure pcie1_axi_clk_src */
+ writel((GCC_PCIE1_AXI_CFG_RCGR_SRC_SEL |
+ GCC_PCIE1_AXI_CFG_RCGR_SRC_DIV),
+ base + PCIE_AXI_CFG_RCGR);
+ mdelay(1);
+ reg_val = readl(base + PCIE_AXI_CMD_RCGR);
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, base + PCIE_AXI_CMD_RCGR);
+ } else { /*double lane*/
+ base = (void __iomem *)GCC_PCIE0_BOOT_CLOCK_CTL;
+ writel(CLK_ENABLE, GCC_SYS_NOC_PCIE0_AXI_CBCR);
+ mdelay(1);
+ /* Configure pcie1_aux_clk_src */
+ writel((GCC_PCIE0_AUX_CFG_RCGR_SRC_SEL |
+ GCC_PCIE0_AUX_CFG_RCGR_SRC_DIV),
+ base + PCIE_AUX_CFG_RCGR);
+ mdelay(1);
+ reg_val = readl(base + PCIE_AUX_CMD_RCGR);
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, base + PCIE_AUX_CMD_RCGR);
+
+ /* Configure pcie1_axi_clk_src */
+ writel((GCC_PCIE0_AXI_CFG_RCGR_SRC_SEL |
+ GCC_PCIE0_AXI_CFG_RCGR_SRC_DIV),
+ base + PCIE_AXI_CFG_RCGR);
+ mdelay(1);
+ reg_val = readl(base + PCIE_AXI_CMD_RCGR);
+ reg_val &= ~0x1;
+ reg_val |= 0x1;
+ writel(reg_val, base + PCIE_AXI_CMD_RCGR);
+ }
+ mdelay(1);
+ reg_val= readl(base + PCIE_AXI_M_CBCR);
+ reg_val |= CLK_ENABLE;
+ writel(reg_val, base + PCIE_AXI_M_CBCR);
+
+ mdelay(1);
+ reg_val = readl(base + PCIE_AXI_S_CBCR);
+ reg_val |= CLK_ENABLE;
+ writel(reg_val, base + PCIE_AXI_S_CBCR);
+
+ mdelay(1);
+ writel(CLK_ENABLE, base + PCIE_AHB_CBCR);
+
+ mdelay(1);
+ writel(CLK_ENABLE, base + PCIE_AUX_CBCR);
+
+ mdelay(1);
+ writel(CLK_ENABLE, base + PCIE_AXI_S_BRIDGE_CBCR);
+
+ mdelay(1);
+ reg_val= readl(base + PCIE_PIPE_CBCR);
+ reg_val |= CLK_ENABLE;
+ writel(reg_val, base + PCIE_PIPE_CBCR);
+ mdelay(1);
+#endif
+ return;
+}
+
+static void pcie_v2_clock_deinit(int lane)
+{
+#ifdef CONFIG_PCI
+ void __iomem *base;
+
+ /*single lane*/
+ if (lane == 1) {
+ base = (void __iomem *)GCC_PCIE1_BOOT_CLOCK_CTL;
+ writel(0x0, GCC_SYS_NOC_PCIE1_AXI_CBCR);
+ } else { /*double lane*/
+ base = (void __iomem *)GCC_PCIE0_BOOT_CLOCK_CTL;
+ writel(0x0, GCC_SYS_NOC_PCIE0_AXI_CBCR);
+ }
+ mdelay (5);
+ writel(0x0, base + PCIE_AHB_CBCR);
+ writel(0x0, base + PCIE_AXI_M_CBCR);
+ writel(0x0, base + PCIE_AXI_S_CBCR);
+ writel(0x0, base + PCIE_AUX_CBCR);
+ writel(0x0, base + PCIE_PIPE_CBCR);
+ writel(0x0, base + PCIE_AXI_S_BRIDGE_CBCR);
+#endif
+ return;
+}
+
+static void pcie_phy_init(u32 reg_base, int mode, int lane)
+{
+ for (int i = 0; i < lane; ++i) {
+ /*set frequency initial value*/
+ writel(0x1cb9, (reg_base + (i * 0x800)) + SSCG_CTRL_REG_4);
+ writel(0x023a, (reg_base + (i * 0x800)) + SSCG_CTRL_REG_5);
+ /*set spectrum spread count*/
+ writel(0x1360, (reg_base + (i * 0x800)) + SSCG_CTRL_REG_3);
+ if (mode == 1) {
+ /*set fstep*/
+ writel(0x0, (reg_base + (i * 0x800)) +
+ SSCG_CTRL_REG_1);
+ writel(0x0, (reg_base + (i * 0x800)) +
+ SSCG_CTRL_REG_2);
+ } else {
+ /*set fstep*/
+ writel(0x1, (reg_base + (i * 0x800)) +
+ SSCG_CTRL_REG_1);
+ writel(0xeb, (reg_base + (i * 0x800)) +
+ SSCG_CTRL_REG_2);
+ /*set FLOOP initial value*/
+ writel(0x3f9, (reg_base + (i * 0x800)) +
+ CDR_CTRL_REG_4);
+ writel(0x1c9, (reg_base + (i * 0x800)) +
+ CDR_CTRL_REG_5);
+ /*set upper boundary level*/
+ writel(0x419, (reg_base + (i * 0x800)) +
+ CDR_CTRL_REG_2);
+ /*set fixed offset*/
+ writel(0x200, (reg_base + (i * 0x800)) +
+ CDR_CTRL_REG_1);
+ }
+ }
+}
+
+static void pcie_reset(int lane)
+{
+ u32 reg_val;
+ void __iomem *base;
+
+ /*single lane*/
+ if (lane == 1)
+ base = (void __iomem *)GCC_PCIE1_BOOT_CLOCK_CTL;
+ else /*double lane*/
+ base = (void __iomem *)GCC_PCIE0_BOOT_CLOCK_CTL;
+
+ reg_val = readl(base + PCIE_BCR);
+ writel(reg_val | GCC_PCIE_BCR_ENABLE,
+ (base + PCIE_BCR));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_BCR_ENABLE),
+ (base + PCIE_BCR));
+
+ reg_val = readl(base + PCIE_PHY_BCR);
+ writel(reg_val | GCC_PCIE_BLK_ARES,
+ (base + PCIE_PHY_BCR));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_BLK_ARES),
+ (base + PCIE_PHY_BCR));
+
+ reg_val = readl(base + PCIE_PHY_PHY_BCR);
+ writel(reg_val | GCC_PCIE_BLK_ARES,
+ (base + PCIE_PHY_PHY_BCR));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_BLK_ARES),
+ (base + PCIE_PHY_PHY_BCR));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_PIPE_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_PIPE_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_SLEEP_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_SLEEP_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_CORE_STICKY_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_CORE_STICKY_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_AXI_MASTER_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_AXI_MASTER_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_AXI_SLAVE_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_AXI_SLAVE_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCIE_AHB_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCIE_AHB_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCI_AXI_MASTER_STICKY_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCI_AXI_MASTER_STICKY_ARES),
+ (base + PCIE_MISC_RESET));
+
+ reg_val = readl(base + PCIE_MISC_RESET);
+ writel(reg_val | GCC_PCI_AXI_SLAVE_STICKY_ARES,
+ (base + PCIE_MISC_RESET));
+ mdelay(1);
+ writel(reg_val & (~GCC_PCI_AXI_SLAVE_STICKY_ARES),
+ (base + PCIE_MISC_RESET));
+}
+
+void board_pci_init(int id)
+{
+ int node, gpio_node, mode = 0;
+ struct fdt_resource pci_phy;
+ char name[16];
+ int err, lane;
+
+ snprintf(name, sizeof(name), "pci%d", id);
+ node = fdt_path_offset(gd->fdt_blob, name);
+ if (node < 0) {
+ printf("Could not find PCI in device tree\n");
+ return;
+ }
+
+ err = fdt_get_named_resource(gd->fdt_blob, node,
+ "reg", "reg-names", "pci_phy",&pci_phy);
+ if (err < 0)
+ return;
+
+ if (!strcmp(fdt_getprop(gd->fdt_blob, node, "mode", NULL), "fixed")){
+ mode = 1;
+ }
+ lane = fdtdec_get_int(gd->fdt_blob, node, "lane", 0);
+
+ gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio");
+ if (gpio_node >= 0)
+ qca_gpio_init(gpio_node);
+
+ pcie_reset(lane);
+ pcie_v2_clock_init(lane);
+ pcie_phy_init(pci_phy.start, mode, lane);
+
+ return;
+}
+
+void board_pci_deinit()
+{
+ int node, gpio_node, i, lane, err;
+ char name[16];
+ struct fdt_resource parf;
+ struct fdt_resource pci_phy;
+
+ for (i = 0; i < PCI_MAX_DEVICES; i++) {
+ snprintf(name, sizeof(name), "pci%d", i);
+ node = fdt_path_offset(gd->fdt_blob, name);
+ if (node < 0) {
+ printf("Could not find PCI in device tree\n");
+ continue;
+ }
+ err = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", "parf",
+ &parf);
+ writel(0x0, parf.start + 0x358);
+ writel(0x1, parf.start + 0x40);
+ err = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", "pci_phy",
+ &pci_phy);
+ if (err < 0)
+ continue;
+
+ writel(0x1, pci_phy.start + 800);
+ writel(0x0, pci_phy.start + 804);
+ gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio");
+ if (gpio_node >= 0)
+ qca_gpio_deinit(gpio_node);
+
+ lane = fdtdec_get_int(gd->fdt_blob, node, "lane", 0);
+ pcie_v2_clock_deinit(lane);
+ }
+
+ return ;
+}
+#endif
+
+void fdt_fixup_qpic(void *blob)
+{
+ int node_off, ret;
+ const char *qpic_node = {"/soc/qpic-nand@79b0000"};
+
+ /* This fixup is for qpic io_macro_clk
+ * frequency & phase value
+ */
+ node_off = fdt_path_offset(blob, qpic_node);
+ if (node_off < 0) {
+ printf("%s: QPIC: unable to find node '%s'\n",
+ __func__, qpic_node);
+ return;
+ }
+
+ ret = fdt_setprop_u32(blob, node_off, "qcom,iomacromax_clk", qpic_frequency);
+ if (ret) {
+ printf("%s : Unable to set property 'qcom,iomacromax_clk'\n",__func__);
+ return;
+ }
+
+ ret = fdt_setprop_u32(blob, node_off, "qcom,phase", qpic_phase);
+ if (ret) {
+ printf("%s : Unable to set property 'qcom,phase'\n",__func__);
+ return;
+ }
+}
+
+void fdt_fixup_bt_debug(void *blob)
+{
+ int node, phandle;
+ char node_name[32];
+
+ if ((gd->bd->bi_arch_number == MACH_TYPE_IPQ5018_AP_MP02_1) ||
+ (gd->bd->bi_arch_number == MACH_TYPE_IPQ5018_DB_MP02_1)) {
+ node = fdt_path_offset(blob, "/soc/pinctrl@1000000/btss_pins");
+ if (node >= 0) {
+ phandle = fdtdec_get_int(blob, node, "phandle", 0);
+ snprintf(node_name,
+ sizeof(node_name),
+ "%s%d",
+ "/soc/bt@7000000%pinctrl-0%",
+ phandle);
+ parse_fdt_fixup("/soc/bt@7000000%pinctrl-names%?btss_pins", blob);
+ parse_fdt_fixup(node_name, blob);
+ }
+ parse_fdt_fixup("/soc/mdio@90000/%delete%status", blob);
+ parse_fdt_fixup("/soc/mdio@90000/%status%?disabled", blob);
+ }
+ parse_fdt_fixup("/soc/serial@78b0000/%status%?ok", blob);
+ parse_fdt_fixup("/soc/usb3@8A00000/%delete%device-power-gpio", blob);
+}
+
+#ifdef CONFIG_IPQ_TINY
+void fdt_fixup_art_format(void *blob)
+{
+ int nodeoffset;
+ nodeoffset = fdt_path_offset(blob, "/");
+ fdt_add_subnode(blob, nodeoffset, "compressed_art");
+
+}
+#endif
+
+void run_tzt(void *address)
+{
+ execute_tzt(address);
+}
+
+void fdt_fixup_set_dload_warm_reset(void *blob)
+{
+ int nodeoff, ret;
+ uint32_t setval = 1;
+
+ nodeoff = fdt_path_offset(blob, "/soc/qca,scm_restart_reason");
+ if (nodeoff < 0) {
+ nodeoff = fdt_path_offset(blob, "/qti,scm_restart_reason");
+ if (nodeoff < 0) {
+ printf("fixup_set_dload: unable to find scm_restart_reason node\n");
+ return;
+ }
+ }
+
+ ret = fdt_setprop_u32(blob, nodeoff, "dload_status", setval);
+ if (ret)
+ printf("fixup_set_dload: 'dload_status' not set");
+
+ ret = fdt_setprop_u32(blob, nodeoff, "dload_warm_reset", setval);
+ if (ret)
+ printf("fixup_set_dload: 'dload_warm_reset' not set");
+}
+
+#ifdef CONFIG_SMP_CMD_SUPPORT
+int is_secondary_core_off(unsigned int cpuid)
+{
+ int err;
+
+ err = __invoke_psci_fn_smc(ARM_PSCI_TZ_FN_AFFINITY_INFO, cpuid, 0, 0);
+
+ return err;
+}
+
+void bring_secondary_core_down(unsigned int state)
+{
+ __invoke_psci_fn_smc(ARM_PSCI_TZ_FN_CPU_OFF, state, 0, 0);
+}
+
+int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg)
+{
+ int err;
+
+ err = __invoke_psci_fn_smc(ARM_PSCI_TZ_FN_CPU_ON, cpuid, entry, arg);
+ if (err) {
+ printf("Enabling CPU%d via psci failed!\n", cpuid);
+ return -1;
+ }
+
+ printf("Enabled CPU%d via psci successfully!\n", cpuid);
+ return 0;
+}
+#endif
+
+int get_soc_hw_version(void)
+{
+ return readl(TCSR_SOC_HW_VERSION_REG);
+}
+
+void sdi_disable(void)
+{
+ qca_scm_sdi();
+}
diff --git a/board/qca/arm/ipq5018/ipq5018.h b/board/qca/arm/ipq5018/ipq5018.h
new file mode 100644
index 0000000..b6e5c0f
--- /dev/null
+++ b/board/qca/arm/ipq5018/ipq5018.h
@@ -0,0 +1,647 @@
+/*
+* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#ifndef _IPQ5018_CDP_H_
+#define _IPQ5018_CDP_H_
+
+#include <configs/ipq5018.h>
+#include <asm/u-boot.h>
+#include <asm/arch-qca-common/qca_common.h>
+#include "phy.h"
+
+/*
+ * Eud register
+ */
+#define EUD_EUD_EN2 0x0005A000
+
+#define MSM_SDC1_BASE 0x7800000
+#define MSM_SDC1_SDHCI_BASE 0x7804000
+
+#define GCC_MDIO0_BASE 0x1858000
+#define GCC_GMAC_CFG_RCGR 0x01868084
+#define GCC_GMAC_CMD_RCGR 0x01868080
+#define GCC_GMAC_BASE 0x01868000
+
+
+#define GCC_GMAC_CFG_RCGR_SRC_SEL_MASK 0x700
+#define GCC_GMAC0_RX_SRC_SEL_GEPHY_TX 0x200
+#define GCC_GMAC0_TX_SRC_SEL_GEPHY_TX 0x100
+#define GCC_GMAC1_RX_SRC_SEL_UNIPHY_RX 0x100
+#define GCC_GMAC1_TX_SRC_SEL_UNIPHY_TX 0x100
+#define CMN_PLL_PLL_LOCKED_REG 0x9B064
+#define CMN_PLL_PLL_LOCKED_SIZE 0x4
+#define CMN_PLL_LOCKED 0x4
+
+/*
+ * CMN BLK clock
+ */
+#define GCC_CMN_BLK_AHB_CBCR 0x01856308
+#define GCC_CMN_BLK_SYS_CBCR 0x0185630C
+#define CMN_BLK_ADDR 0x0009B780
+#define CMN_BLK_SIZE 0x100
+#define FREQUENCY_MASK 0xfffffdf0
+#define INTERNAL_48MHZ_CLOCK 0x7
+
+#define CMN_BLK_PLL_SRC_ADDR 0x0009B028
+#define PLL_CTRL_SRC_MASK 0xfffffcff
+#define PLL_REFCLK_DIV_MASK 0xfffffe0f
+#define PLL_REFCLK_DIV_2 0x20
+#define CMN_BLK_PLL_SRC_SEL_FROM_REG 0x0
+#define CMN_BLK_PLL_SRC_SEL_FROM_LOGIC 0x1
+#define CMN_BLK_PLL_SRC_SEL_FROM_PCS 0x2
+#define TCSR_ETH_LDO_RDY_REG 0x19475C4
+#define TCSR_ETH_LDO_RDY_SIZE 0x4
+#define ETH_LDO_RDY 0x1
+
+/*
+ * GEPHY Block Register
+ */
+#define GCC_GEPHY_BCR 0x01856000
+#define GCC_GEPHY_MISC 0x01856004
+#define GCC_GEPHY_RX_CBCR 0x01856010
+#define GCC_GEPHY_TX_CBCR 0x01856014
+#define GCC_GEPHY_BCR_BLK_ARES 0x1
+#define GCC_GEPHY_MISC_ARES 0xf
+
+/*
+ * UNIPHY Block Register
+ */
+#define GCC_UNIPHY_BCR 0x01856100
+#define GCC_UNIPHY_AHB_CBCR 0x01856108
+#define GCC_UNIPHY_SYS_CBCR 0x0185610C
+#define GCC_UNIPHY_BCR_BLK_ARES 0x1
+#define GCC_UNIPHY_MISC_ARES 0x32
+#define GCC_UNIPHY_RX_CBCR 0x01856110
+#define GCC_UNIPHY_TX_CBCR 0x01856114
+
+/* GMAC0 GCC clock */
+#define GCC_GMAC0_RX_CMD_RCGR 0x01868020
+#define GCC_GMAC0_RX_CFG_RCGR 0x01868024
+#define GCC_GMAC0_TX_CMD_RCGR 0x01868028
+#define GCC_GMAC0_TX_CFG_RCGR 0x0186802C
+#define GCC_GMAC0_RX_MISC 0x01868420
+#define GCC_GMAC0_TX_MISC 0x01868424
+#define GCC_GMAC0_MISC 0x01868428
+#define GCC_GMAC0_BCR 0x01819000
+#define GCC_SNOC_GMAC0_AXI_CBCR 0x01826084
+#define GCC_SNOC_GMAC0_AHB_CBCR 0x018260A0
+#define GCC_GMAC0_PTP_CBCR 0x01868300
+#define GCC_GMAC0_CFG_CBCR 0x01868304
+#define GCC_GMAC0_SYS_CBCR 0x01868190
+#define GCC_GMAC0_RX_CBCR 0x01868240
+#define GCC_GMAC0_TX_CBCR 0x01868244
+#define GCC_GMAC0_BCR_BLK_ARES 0x1
+
+/* GMAC1 GCC Clock */
+#define GCC_GMAC1_RX_CMD_RCGR 0x01868030
+#define GCC_GMAC1_RX_CFG_RCGR 0x01868034
+#define GCC_GMAC1_TX_CMD_RCGR 0x01868038
+#define GCC_GMAC1_TX_CFG_RCGR 0x0186803C
+#define GCC_GMAC1_RX_MISC 0x01868430
+#define GCC_GMAC1_TX_MISC 0x01868434
+#define GCC_GMAC1_MISC 0x01868438
+#define GCC_GMAC1_BCR 0x01819100
+#define GCC_SNOC_GMAC1_AXI_CBCR 0x01826088
+#define GCC_SNOC_GMAC1_AHB_CBCR 0x018260A4
+#define GCC_GMAC1_SYS_CBCR 0x01868310
+#define GCC_GMAC1_PTP_CBCR 0x01868320
+#define GCC_GMAC1_CFG_CBCR 0x01868324
+#define GCC_GMAC1_RX_CBCR 0x01868248
+#define GCC_GMAC1_TX_CBCR 0x0186824C
+#define GCC_GMAC1_BCR_BLK_ARES 0x1
+
+#define GCC_CBCR_CLK_ENABLE 0x1
+
+/*
+ * GCC-SDCC Registers
+ */
+
+#define GCC_SDCC1_BCR 0x01842000
+#define GCC_SDCC1_APPS_CMD_RCGR 0x01842004
+#define GCC_SDCC1_APPS_CFG_RCGR 0x01842008
+#define GCC_SDCC1_APPS_M 0x0184200C
+#define GCC_SDCC1_APPS_N 0x01842010
+#define GCC_SDCC1_APPS_D 0x01842014
+#define GCC_SDCC1_APPS_CBCR 0x01842018
+#define GCC_SDCC1_AHB_CBCR 0x0184201C
+
+/*
+ * GCC-QPIC Registers
+ */
+#define GCC_QPIC_IO_MACRO_CBCR 0x0185701C
+#define GCC_QPIC_CBCR_ADDR 0x01857020
+#define GCC_QPIC_AHB_CBCR_ADDR 0x01857024
+#define GCC_QPIC_SLEEP_CBCR 0x01857028
+#define QPIC_CBCR_VAL 0x80004FF1
+#define GCC_QPIC_IO_MACRO_CMD_RCGR 0x01857010
+#define GCC_QPIC_IO_MACRO_CFG_RCGR 0x01857014
+#define IO_MACRO_CLK_320_MHZ 320000000
+#define IO_MACRO_CLK_266_MHZ 266000000
+#define IO_MACRO_CLK_228_MHZ 228000000
+#define IO_MACRO_CLK_200_MHZ 200000000
+#define IO_MACRO_CLK_100_MHZ 100000000
+#define IO_MACRO_CLK_24MHZ 24000000
+#define QPIC_IO_MACRO_CLK 0
+#define QPIC_CORE_CLK 1
+#define XO_CLK_SRC 2
+#define GPLL0_CLK_SRC 3
+#define FB_CLK_BIT (1 << 4)
+#define UPDATE_EN 0x1
+
+/* UART 1 */
+#define GCC_BLSP1_UART1_BCR 0x01802038
+#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203C
+#define GCC_BLSP1_UART1_APPS_CMD_RCGR 0x01802044
+#define GCC_BLSP1_UART1_APPS_CFG_RCGR 0x01802048
+#define GCC_BLSP1_UART1_APPS_M 0x0180204C
+#define GCC_BLSP1_UART1_APPS_N 0x01802050
+#define GCC_BLSP1_UART1_APPS_D 0x01802054
+
+/* UART 2 */
+#define GCC_BLSP1_UART2_BCR 0x01803028
+#define GCC_BLSP1_UART2_APPS_CBCR 0x0180302C
+#define GCC_BLSP1_UART2_APPS_CMD_RCGR 0x01803034
+#define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038
+#define GCC_BLSP1_UART2_APPS_M 0x0180303C
+#define GCC_BLSP1_UART2_APPS_N 0x01803040
+#define GCC_BLSP1_UART2_APPS_D 0x01803044
+
+#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000
+#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700
+#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F
+
+#define GCC_UART_CFG_RCGR_MODE_SHIFT 12
+#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8
+#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0
+
+#define UART1_RCGR_SRC_SEL 0x1
+#define UART1_RCGR_SRC_DIV 0x0
+#define UART1_RCGR_MODE 0x2
+#define UART1_CMD_RCGR_UPDATE 0x1
+#define UART1_CMD_RCGR_ROOT_EN 0x2
+#define UART1_CBCR_CLK_ENABLE 0x1
+
+/* USB Registers */
+#define GCC_SYS_NOC_USB0_AXI_CBCR 0x1826040
+
+#define TCSR_USB_PCIE_SEL 0x01947540
+
+#define GCC_USB0_MASTER_CBCR 0x183E000
+#define GCC_USB0_SLEEP_CBCR 0x183E004
+#define GCC_USB0_MOCK_UTMI_CBCR 0x183E008
+#define GCC_USB0_MASTER_CMD_RCGR 0x183E00C
+#define GCC_USB0_MASTER_CFG_RCGR 0x183E010
+#define GCC_USB0_MASTER_M 0x183E014
+#define GCC_USB0_MASTER_N 0x183E018
+#define GCC_USB0_MASTER_D 0x183E01C
+#define GCC_USB0_MOCK_UTMI_CMD_RCGR 0x183E020
+#define GCC_USB0_MOCK_UTMI_CFG_RCGR 0x183E024
+#define GCC_USB0_MOCK_UTMI_M 0x183E028
+#define GCC_USB0_MOCK_UTMI_N 0x183E02C
+#define GCC_USB0_MOCK_UTMI_D 0x183E030
+#define GCC_USB0_PHY_BCR 0x183E034
+#define GCC_USB0_PIPE_CBCR 0x183E040
+#define GCC_USB0_AUX_CBCR 0x183E044
+#define GCC_USB0_PHY_PIPE_MISC 0x183E048
+#define GCC_USB0_EUD_AT_CBCR 0x183E04C
+#define GCC_USB0_LFPS_CBCR 0x183E050
+#define GCC_USB0_AUX_CMD_RCGR 0x183E05C
+#define GCC_USB0_AUX_CFG_RCGR 0x183E060
+#define GCC_USB0_BCR 0x183E070
+#define GCC_USB0_PHY_CFG_AHB_CBCR 0x183E080
+#define GCC_USB0_LFPS_CMD_RCGR 0x183E090
+#define GCC_USB0_LFPS_CFG_RCGR 0x183E094
+#define GCC_USB0_LFPS_M 0x183E098
+#define GCC_USB0_LFPS_N 0x183E09C
+#define GCC_USB0_LFPS_D 0x183E0A0
+
+#define GCC_USB_0_BOOT_CLOCK_CTL 0x1840000
+#define GCC_QUSB2_0_PHY_BCR 0x1841030
+
+#define USB30_GENERAL_CFG 0x8AF8808
+#define USB30_GUCTL 0x8A0C12C
+#define USB30_FLADJ 0x8A0C630
+#define GUCTL 0x700C12C
+#define FLADJ 0x700C630
+
+#define PIPE_UTMI_CLK_SEL 0x1
+#define PIPE3_PHYSTATUS_SW (0x1 << 3)
+#define PIPE_UTMI_CLK_DIS (0x1 << 8)
+
+#define QUSB2PHY_BASE 0x5b000
+
+#define GCC_USB0_LFPS_CFG_SRC_SEL (0x1 << 8)
+#define GCC_USB0_LFPS_CFG_SRC_DIV (0x1f << 0)
+#define LFPS_M 0x1
+#define LFPS_N 0xfe
+#define LFPS_D 0xfd
+#define GCC_USB0_LFPS_MODE (0x2 << 12)
+
+#define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE (2 << 12)
+#define GCC_USB0_AUX_CFG_SRC_SEL (0 << 8)
+#define GCC_USB0_AUX_CFG_SRC_DIV (0x17 << 0)
+
+#define AUX_M 0x0
+#define AUX_N 0x0
+#define AUX_D 0x0
+
+#define SW_COLLAPSE_ENABLE (1 << 0)
+#define SW_OVERRIDE_ENABLE (1 << 2)
+
+
+#define GCC_USB0_MASTER_CFG_RCGR_SRC_SEL (1 << 8)
+#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV (0x7 << 0)
+
+#define GCC_USB_MOCK_UTMI_SRC_SEL (1 << 8)
+#define GCC_USB_MOCK_UTMI_SRC_DIV (0x13 << 0)
+#define GCC_USB_MOCK_UTMI_CLK_DIV (0x1 << 16)
+
+#define GCC_QUSB2_1_PHY_BCR 0x1841040
+
+#define USB3PHY_APB_BASE 0x5d000
+
+#define USB3_PHY_POWER_DOWN_CONTROL 0x804
+#define QSERDES_COM_SYSCLK_EN_SEL 0xac
+#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x34
+#define QSERDES_COM_CLK_SELECT 0x174
+#define QSERDES_COM_BG_TRIM 0x70
+#define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x440
+#define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
+#define QSERDES_COM_HSCLK_SEL 0x178
+#define QSERDES_COM_CMN_CONFIG 0x194
+#define QSERDES_COM_PLL_IVCO 0x048
+#define QSERDES_COM_SYS_CLK_CTRL 0x3c
+#define QSERDES_COM_DEC_START_MODE0 0xd0
+#define QSERDES_COM_DIV_FRAC_START1_MODE0 0xdc
+#define QSERDES_COM_DIV_FRAC_START2_MODE0 0xe0
+#define QSERDES_COM_DIV_FRAC_START3_MODE0 0xe4
+#define QSERDES_COM_CP_CTRL_MODE0 0x78
+#define QSERDES_COM_PLL_RCTRL_MODE0 0x84
+#define QSERDES_COM_PLL_CCTRL_MODE0 0x90
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
+#define QSERDES_COM_LOCK_CMP1_MODE0 0x4c
+#define QSERDES_COM_LOCK_CMP2_MODE0 0x50
+#define QSERDES_COM_LOCK_CMP3_MODE0 0x54
+#define QSERDES_COM_CORE_CLK_EN 0x18c
+#define QSERDES_COM_LOCK_CMP_CFG 0xcc
+#define QSERDES_COM_VCO_TUNE_MAP 0x128
+#define QSERDES_COM_BG_TIMER 0x0c
+#define QSERDES_COM_SSC_EN_CENTER 0x10
+#define QSERDES_COM_SSC_PER1 0x1c
+#define QSERDES_COM_SSC_PER2 0x20
+#define QSERDES_COM_SSC_ADJ_PER1 0x14
+#define QSERDES_COM_SSC_ADJ_PER2 0x18
+#define QSERDES_COM_SSC_STEP_SIZE1 0x24
+#define QSERDES_COM_SSC_STEP_SIZE2 0x28
+#define QSERDES_RX_UCDR_SO_GAIN 0x410
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x4d8
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x4dc
+#define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x4e0
+#define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL 0x508
+#define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x50c
+#define QSERDES_RX_SIGDET_CNTRL 0x514
+#define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x51c
+#define QSERDES_RX_SIGDET_ENABLES 0x510
+#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_D 0x268
+#define QSERDES_TX_RCV_DETECT_LVL_2 0x2ac
+#define QSERDES_TX_LANE_MODE 0x294
+#define PCS_TXDEEMPH_M6DB_V0 0x824
+#define PCS_TXDEEMPH_M3P5DB_V0 0x828
+#define PCS_FLL_CNTRL2 0x8c8
+#define PCS_FLL_CNTRL1 0x8c4
+#define PCS_FLL_CNT_VAL_L 0x8cc
+#define PCS_FLL_CNT_VAL_H_TOL 0x8d0
+#define PCS_FLL_MAN_CODE 0x8d4
+#define PCS_LOCK_DETECT_CONFIG1 0x880
+#define PCS_LOCK_DETECT_CONFIG2 0x884
+#define PCS_LOCK_DETECT_CONFIG3 0x888
+#define PCS_POWER_STATE_CONFIG2 0x864
+#define PCS_RXEQTRAINING_WAIT_TIME 0x8b8
+#define PCS_RXEQTRAINING_RUN_TIME 0x8bc
+#define PCS_LFPS_TX_ECSTART_EQTLOCK 0x8b0
+#define PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x8a0
+#define PCS_TSYNC_RSYNC_TIME 0x88c
+#define PCS_RCVR_DTCT_DLY_P1U2_L 0x870
+#define PCS_RCVR_DTCT_DLY_P1U2_H 0x874
+#define PCS_RCVR_DTCT_DLY_U3_L 0x878
+#define PCS_RCVR_DTCT_DLY_U3_H 0x87c
+#define PCS_RX_SIGDET_LVL 0x9d8
+#define USB3_PCS_TXDEEMPH_M6DB_V0 0x824
+#define USB3_PCS_TXDEEMPH_M3P5DB_V0 0x828
+#define QSERDES_RX_SIGDET_ENABLES 0x510
+#define USB3_PHY_START_CONTROL 0x808
+#define USB3_PHY_SW_RESET 0x800
+
+#define CMD_UPDATE 0x1
+#define ROOT_EN 0x2
+#define CLK_DISABLE 0x0
+#define NOC_HANDSHAKE_FSM_EN (1 << 15)
+
+#define set_mdelay_clearbits_le32(addr, value, delay) \
+ setbits_le32(addr, value); \
+ mdelay(delay); \
+ clrbits_le32(addr, value); \
+/*
+ * PCIE Register
+ */
+#define GCC_SYS_NOC_PCIE0_AXI_CBCR 0x01826048
+#define GCC_SYS_NOC_PCIE1_AXI_CBCR 0x0182604C
+
+#define GCC_PCIE_BCR_ENABLE (1 << 0)
+#define GCC_PCIE_BLK_ARES (1 << 0)
+#define GCC_PCIE_PIPE_ARES (1 << 0)
+#define GCC_PCIE_SLEEP_ARES (1 << 1)
+#define GCC_PCIE_CORE_STICKY_ARES (1 << 2)
+#define GCC_PCIE_AXI_MASTER_ARES (1 << 3)
+#define GCC_PCIE_AXI_SLAVE_ARES (1 << 4)
+#define GCC_PCIE_AHB_ARES (1 << 5)
+#define GCC_PCI_AXI_MASTER_STICKY_ARES (1 << 6)
+#define GCC_PCI_AXI_SLAVE_STICKY_ARES (1 << 7)
+
+#define GCC_PCIE0_BOOT_CLOCK_CTL 0x01875000
+#define GCC_PCIE0_BCR 0x01875004
+#define GCC_PCIE0_AXI_M_CBCR 0x01875008
+#define GCC_PCIE0_AXI_S_CBCR 0x0187500C
+#define GCC_PCIE0_AHB_CBCR 0x01875010
+#define GCC_PCIE0_PHY_PIPE_MISC 0x0187501C
+#define GCC_PCIE0_AUX_CBCR 0x01875014
+#define GCC_PCIE0_PIPE_CBCR 0x01875018
+#define GCC_PCIE0_PHY_PIPE_MISC 0x0187501C
+#define GCC_PCIE0_AUX_CMD_RCGR 0x01875020
+#define GCC_PCIE0_AUX_CFG_RCGR 0x01875024
+#define GCC_PCIE0_PHY_BCR 0x01875038
+#define GCC_PCIE0PHY_PHY_BCR 0x0187503C
+#define GCC_PCIE0_MISC_RESET 0x01875040
+#define GCC_PCIE0_AXI_S_BRIDGE_CBCR 0x01875048
+#define GCC_PCIE0_AXI_CMD_RCGR 0x01875050
+#define GCC_PCIE0_AXI_CFG_RCGR 0x01875054
+#define GCC_PCIE0_LINK_DOWN_BCR 0x018750A8
+#define GCC_PCIE0_AUX_CFG_RCGR_SRC_SEL (0 << 8)
+#define GCC_PCIE0_AUX_CFG_RCGR_SRC_DIV 0x17
+#define GCC_PCIE0_AXI_CFG_RCGR_SRC_SEL (2 << 8)
+#define GCC_PCIE0_AXI_CFG_RCGR_SRC_DIV 0x9
+
+
+#define GCC_PCIE1_BOOT_CLOCK_CTL 0x01876000
+#define GCC_PCIE1_BCR 0x01876004
+#define GCC_PCIE1_AXI_M_CBCR 0x01876008
+#define GCC_PCIE1_AXI_S_CBCR 0x0187600C
+#define GCC_PCIE1_AHB_CBCR 0x01876010
+#define GCC_PCIE1_AUX_CBCR 0x01876014
+#define GCC_PCIE1_PIPE_CBCR 0x01876018
+#define GCC_PCIE1_PHY_PIPE_MISC 0x0187601C
+#define GCC_PCIE1_AUX_CMD_RCGR 0x01876020
+#define GCC_PCIE1_AUX_CFG_RCGR 0x01876024
+#define GCC_PCIE1_PHY_BCR 0x01876038
+#define GCC_PCIE1PHY_PHY_BCR 0x0187603C
+#define GCC_PCIE1_MISC_RESET 0x01876040
+#define GCC_PCIE1_LINK_DOWN_BCR 0x01876044
+#define GCC_PCIE1_AXI_S_BRIDGE_CBCR 0x01876048
+#define GCC_PCIE1_AXI_CMD_RCGR 0x01876050
+#define GCC_PCIE1_AXI_CFG_RCGR 0x01876054
+#define GCC_PCIE1_AUX_CFG_RCGR_SRC_SEL (0 << 8)
+#define GCC_PCIE1_AUX_CFG_RCGR_SRC_DIV 0x17
+#define GCC_PCIE1_AXI_CFG_RCGR_SRC_SEL (1 << 8)
+#define GCC_PCIE1_AXI_CFG_RCGR_SRC_DIV 0x7
+
+#define PCIE_BCR 0x4
+#define PCIE_AXI_M_CBCR 0x8
+#define PCIE_AXI_S_CBCR 0xC
+#define PCIE_AHB_CBCR 0x10
+#define PCIE_AUX_CBCR 0x14
+#define PCIE_PIPE_CBCR 0x18
+#define PCIE_AUX_CMD_RCGR 0x20
+#define PCIE_AUX_CFG_RCGR 0x24
+#define PCIE_PHY_BCR 0x38
+#define PCIE_PHY_PHY_BCR 0x3c
+#define PCIE_MISC_RESET 0x40
+#define PCIE_AXI_S_BRIDGE_CBCR 0x48
+#define PCIE_AXI_CMD_RCGR 0x50
+#define PCIE_AXI_CFG_RCGR 0x54
+
+#define NOT_2D(two_d) (~two_d)
+#define NOT_N_MINUS_M(n,m) (~(n - m))
+#define CLOCK_UPDATE_TIMEOUT_US 1000
+
+#define KERNEL_AUTH_CMD 0x13
+#define SCM_CMD_SEC_AUTH 0x15
+
+#define ARM_PSCI_TZ_FN_BASE 0x84000000
+#define ARM_PSCI_TZ_FN(n) (ARM_PSCI_TZ_FN_BASE + (n))
+
+#define ARM_PSCI_TZ_FN_CPU_OFF ARM_PSCI_TZ_FN(2)
+#define ARM_PSCI_TZ_FN_CPU_ON ARM_PSCI_TZ_FN(3)
+#define ARM_PSCI_TZ_FN_AFFINITY_INFO ARM_PSCI_TZ_FN(4)
+
+#define CLK_ENABLE 0x1
+
+#define SSCG_CTRL_REG_1 0x9c
+#define SSCG_CTRL_REG_2 0xa0
+#define SSCG_CTRL_REG_3 0xa4
+#define SSCG_CTRL_REG_4 0xa8
+#define SSCG_CTRL_REG_5 0xac
+#define SSCG_CTRL_REG_6 0xb0
+#define CDR_CTRL_REG_1 0x80
+#define CDR_CTRL_REG_2 0x84
+#define CDR_CTRL_REG_3 0x88
+#define CDR_CTRL_REG_4 0x8C
+#define CDR_CTRL_REG_5 0x90
+#define CDR_CTRL_REG_6 0x94
+#define CDR_CTRL_REG_7 0x98
+
+#define USB_PHY_CFG0 0x94
+#define USB_PHY_UTMI_CTRL5 0x50
+#define USB_PHY_FSEL_SEL 0xB8
+#define USB_PHY_HS_PHY_CTRL_COMMON0 0x54
+#define USB_PHY_REFCLK_CTRL 0xA0
+#define USB_PHY_HS_PHY_CTRL2 0x64
+#define USB_PHY_UTMI_CTRL0 0x3c
+
+#define UTMI_PHY_OVERRIDE_EN (1 << 1)
+#define POR_EN (1 << 1)
+#define FREQ_SEL (1 << 0)
+#define COMMONONN (1 << 7)
+#define FSEL (1 << 4)
+#define RETENABLEN (1 << 3)
+#define USB2_SUSPEND_N_SEL (1 << 3)
+#define USB2_SUSPEND_N (1 << 2)
+#define USB2_UTMI_CLK_EN (1 << 1)
+#define CLKCORE (1 << 1)
+#define ATERESET ~(1 << 0)
+
+unsigned int __invoke_psci_fn_smc(unsigned int, unsigned int,
+ unsigned int, unsigned int);
+
+#define S17C_MAX_PORT 4
+
+typedef struct {
+ u32 base;
+ int unit;
+ int phy_addr;
+ int phy_interface_mode;
+ int phy_napa_gpio;
+ int phy_8033_gpio;
+ int phy_type;
+ u32 mac_pwr;
+ int ipq_swith;
+ int phy_external_link;
+ int switch_port_count;
+ int switch_port_phy_address[S17C_MAX_PORT];
+ const char phy_name[MDIO_NAME_LEN];
+} ipq_gmac_board_cfg_t;
+
+extern ipq_gmac_board_cfg_t gmac_cfg[];
+
+static inline int gmac_cfg_is_valid(ipq_gmac_board_cfg_t *cfg)
+{
+ /*
+ * 'cfg' is valid if and only if
+ * unit number is non-negative and less than CONFIG_IPQ_NO_MACS.
+ */
+ return ((cfg >= &gmac_cfg[0]) &&
+ (cfg < &gmac_cfg[CONFIG_IPQ_NO_MACS]) &&
+ (cfg->unit >= 0) && (cfg->unit < CONFIG_IPQ_NO_MACS));
+}
+
+extern void ipq_gmac_common_init(ipq_gmac_board_cfg_t *cfg);
+extern int ipq_gmac_init(ipq_gmac_board_cfg_t *cfg);
+
+#ifdef CONFIG_PCI_IPQ
+void board_pci_init(int id);
+#endif
+
+struct smem_ram_ptn {
+ char name[16];
+ unsigned long long start;
+ unsigned long long size;
+
+ /* RAM Partition attribute: READ_ONLY, READWRITE etc. */
+ unsigned attr;
+
+ /* RAM Partition category: EBI0, EBI1, IRAM, IMEM */
+ unsigned category;
+
+ /* RAM Partition domain: APPS, MODEM, APPS & MODEM (SHARED) etc. */
+ unsigned domain;
+
+ /* RAM Partition type: system, bootloader, appsboot, apps etc. */
+ unsigned type;
+
+ /* reserved for future expansion without changing version number */
+ unsigned reserved2, reserved3, reserved4, reserved5;
+} __attribute__ ((__packed__));
+
+__weak void aquantia_phy_reset_init_done(void) {}
+__weak void aquantia_phy_reset_init(void) {}
+__weak void qgic_init(void) {}
+__weak void handle_noc_err(void) {}
+__weak void board_pcie_clock_init(int id) {}
+
+struct smem_ram_ptable {
+ #define _SMEM_RAM_PTABLE_MAGIC_1 0x9DA5E0A8
+ #define _SMEM_RAM_PTABLE_MAGIC_2 0xAF9EC4E2
+ unsigned magic[2];
+ unsigned version;
+ unsigned reserved1;
+ unsigned len;
+ unsigned buf;
+ struct smem_ram_ptn parts[32];
+} __attribute__ ((__packed__));
+
+int smem_ram_ptable_init(struct smem_ram_ptable *smem_ram_ptable);
+void reset_crashdump(void);
+void reset_board(void);
+void qpic_clk_enbale(void);
+int ipq_get_tz_version(char *version_name, int buf_size);
+void ipq_fdt_fixup_socinfo(void *blob);
+void qpic_set_clk_rate(unsigned int clk_rate, int blk_type,
+ int req_clk_src_type);
+
+extern const char *rsvd_node;
+extern const char *del_node[];
+extern const add_node_t add_fdt_node[];
+
+typedef enum {
+ SMEM_SPINLOCK_ARRAY = 7,
+ SMEM_AARM_PARTITION_TABLE = 9,
+ SMEM_HW_SW_BUILD_ID = 137,
+ SMEM_USABLE_RAM_PARTITION_TABLE = 402,
+ SMEM_POWER_ON_STATUS_INFO = 403,
+ SMEM_MACHID_INFO_LOCATION = 425,
+ SMEM_IMAGE_VERSION_TABLE = 469,
+ SMEM_BOOT_FLASH_TYPE = 498,
+ SMEM_BOOT_FLASH_INDEX = 499,
+ SMEM_BOOT_FLASH_CHIP_SELECT = 500,
+ SMEM_BOOT_FLASH_BLOCK_SIZE = 501,
+ SMEM_BOOT_FLASH_DENSITY = 502,
+ SMEM_BOOT_DUALPARTINFO = 503,
+ SMEM_PARTITION_TABLE_OFFSET = 504,
+ SMEM_SPI_FLASH_ADDR_LEN = 505,
+ SMEM_FIRST_VALID_TYPE = SMEM_SPINLOCK_ARRAY,
+ SMEM_LAST_VALID_TYPE = SMEM_SPI_FLASH_ADDR_LEN,
+ SMEM_MAX_SIZE = SMEM_SPI_FLASH_ADDR_LEN + 1,
+} smem_mem_type_t;
+
+#ifdef CONFIG_IPQ_BT_SUPPORT
+#define NVM_SEGMENT_SIZE 243
+#define TLV_REQ_OPCODE 0xFC00
+#define TLV_COMMAND_REQUEST 0x1E
+#define DATA_REMAINING_LENGTH 2
+#define TLV_RESPONSE_PACKET_SIZE 8
+#define TLV_RESPONSE_STATUS_INDEX 6
+
+#define PACKED_STRUCT __attribute__((__packed__))
+
+#define LE_UNALIGNED(x, y) \
+{ \
+ ((u8 *)(x))[0] = ((u8)(((u32)(y)) & 0xFF)); \
+ ((u8 *)(x))[1] = ((u8)((((u32)(y)) >> 8) & 0xFF)); \
+}
+
+typedef enum
+{
+ ptHCICommandPacket = 0x01, /* Simple HCI Command Packet */
+ ptHCIACLDataPacket = 0x02, /* HCI ACL Data Packet Type. */
+ ptHCISCODataPacket = 0x03, /* HCI SCO Data Packet Type. */
+ ptHCIeSCODataPacket= 0x03, /* HCI eSCO Data Packet Type. */
+ ptHCIEventPacket = 0x04, /* HCI Event Packet Type. */
+ ptHCIAdditional = 0x05 /* Starting Point for Additional*/
+} HCI_PacketType_t;
+
+typedef struct _tlv_download_req
+{
+ u16 opcode;
+ u8 parameter_total_length;
+ u8 command_request;
+ u8 tlv_segment_length;
+ u8 tlv_segment_data[0];
+
+} PACKED_STRUCT tlv_download_req;
+
+typedef struct _tagHCI_Packet_t
+{
+ u8 HCIPacketType;
+ tlv_download_req HCIPayload;
+} PACKED_STRUCT HCI_Packet_t;
+
+typedef enum {
+ BT_WAIT_FOR_START = 0,
+ BT_WAIT_FOR_TX_COMPLETE = 1,
+ BT_WAIT_FOR_STOP = 2,
+} bt_wait;
+
+#define BT_TIMEOUT_US 500000
+
+int bt_init(void);
+#endif
+#endif /* _IPQ5018_CDP_H_ */
diff --git a/board/qca/arm/ipq6018/clock.c b/board/qca/arm/ipq6018/clock.c
index 92beb06..71497fd 100644
--- a/board/qca/arm/ipq6018/clock.c
+++ b/board/qca/arm/ipq6018/clock.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch-ipq6018/clk.h>
+#include <asm/errno.h>
#ifdef CONFIG_IPQ6018_I2C
void i2c_clock_config(void)
@@ -34,3 +35,67 @@
}
#endif
+static void uart_configure_mux(u8 id)
+{
+ unsigned long cfg_rcgr;
+
+ cfg_rcgr = readl(GCC_BLSP1_UART_APPS_CFG_RCGR(id));
+ /* Clear mode, src sel, src div */
+ cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK |
+ GCC_UART_CFG_RCGR_SRCSEL_MASK |
+ GCC_UART_CFG_RCGR_SRCDIV_MASK);
+
+ cfg_rcgr |= ((UART_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
+ & GCC_UART_CFG_RCGR_SRCSEL_MASK);
+
+ cfg_rcgr |= ((UART_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
+ & GCC_UART_CFG_RCGR_SRCDIV_MASK);
+
+ cfg_rcgr |= ((UART_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
+ & GCC_UART_CFG_RCGR_MODE_MASK);
+
+ writel(cfg_rcgr, GCC_BLSP1_UART_APPS_CFG_RCGR(id));
+}
+
+static int uart_trigger_update(u8 id)
+{
+ unsigned long cmd_rcgr;
+ int timeout = 0;
+
+ cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id));
+ cmd_rcgr |= UART_CMD_RCGR_UPDATE;
+ writel(cmd_rcgr, GCC_BLSP1_UART_APPS_CMD_RCGR(id));
+
+ while (readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)) & UART_CMD_RCGR_UPDATE) {
+ if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
+ printf("Timeout waiting for UART clock update\n");
+ return -ETIMEDOUT;
+ }
+ udelay(1);
+ }
+ cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id));
+ return 0;
+}
+
+int uart_clock_config(struct ipq_serial_platdata *plat)
+{
+ unsigned long cbcr_val;
+ int ret;
+
+ uart_configure_mux(plat->port_id);
+
+ writel(plat->m_value, GCC_BLSP1_UART_APPS_M(plat->port_id));
+ writel(NOT_N_MINUS_M(plat->n_value, plat->m_value),
+ GCC_BLSP1_UART_APPS_N(plat->port_id));
+ writel(NOT_2D(plat->d_value), GCC_BLSP1_UART_APPS_D(plat->port_id));
+
+ ret = uart_trigger_update(plat->port_id);
+ if (ret)
+ return ret;
+
+ cbcr_val = readl(GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
+ cbcr_val |= UART_CBCR_CLK_ENABLE;
+ writel(cbcr_val, GCC_BLSP1_UART_APPS_CBCR(plat->port_id));
+ return 0;
+}
+
diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c
index d272a37..dfe61f9 100644
--- a/board/qca/arm/ipq6018/ipq6018.c
+++ b/board/qca/arm/ipq6018/ipq6018.c
@@ -31,6 +31,9 @@
#define DLOAD_MAGIC_COOKIE 0x10
#define DLOAD_DISABLED 0x40
+
+#define TCSR_SOC_HW_VERSION_REG 0x194D000
+
DECLARE_GLOBAL_DATA_PTR;
struct sdhci_host mmc_host;
extern int ipq6018_edma_init(void *cfg);
@@ -109,99 +112,25 @@
int dump_entries_s = ARRAY_SIZE(dumpinfo_s);
u32 *tz_wonce = (u32 *)CONFIG_IPQ6018_TZ_WONCE_4_ADDR;
-
-void uart2_configure_mux(void)
-{
- unsigned long cfg_rcgr;
-
- cfg_rcgr = readl(GCC_BLSP1_UART2_APPS_CFG_RCGR);
- /* Clear mode, src sel, src div */
- cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK |
- GCC_UART_CFG_RCGR_SRCSEL_MASK |
- GCC_UART_CFG_RCGR_SRCDIV_MASK);
-
- cfg_rcgr |= ((UART2_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT)
- & GCC_UART_CFG_RCGR_SRCSEL_MASK);
-
- cfg_rcgr |= ((UART2_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT)
- & GCC_UART_CFG_RCGR_SRCDIV_MASK);
-
- cfg_rcgr |= ((UART2_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT)
- & GCC_UART_CFG_RCGR_MODE_MASK);
-
- writel(cfg_rcgr, GCC_BLSP1_UART2_APPS_CFG_RCGR);
-}
-
-void uart2_set_rate_mnd(unsigned int m,
- unsigned int n, unsigned int two_d)
-{
- writel(m, GCC_BLSP1_UART2_APPS_M);
- writel(NOT_N_MINUS_M(n, m), GCC_BLSP1_UART2_APPS_N);
- writel(NOT_2D(two_d), GCC_BLSP1_UART2_APPS_D);
-}
-
-int uart2_trigger_update(void)
-{
- unsigned long cmd_rcgr;
- int timeout = 0;
-
- cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR);
- cmd_rcgr |= UART2_CMD_RCGR_UPDATE;
- writel(cmd_rcgr, GCC_BLSP1_UART2_APPS_CMD_RCGR);
-
- while (readl(GCC_BLSP1_UART2_APPS_CMD_RCGR) & UART2_CMD_RCGR_UPDATE) {
- if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) {
- printf("Timeout waiting for UART2 clock update\n");
- return -ETIMEDOUT;
- }
- udelay(1);
- }
- cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR);
- return 0;
-}
-
-void uart2_toggle_clock(void)
-{
- unsigned long cbcr_val;
-
- cbcr_val = readl(GCC_BLSP1_UART2_APPS_CBCR);
- cbcr_val |= UART2_CBCR_CLK_ENABLE;
- writel(cbcr_val, GCC_BLSP1_UART2_APPS_CBCR);
-}
-
-void uart2_clock_config(unsigned int m,
- unsigned int n, unsigned int two_d)
-{
- uart2_configure_mux();
- uart2_set_rate_mnd(m, n, two_d);
- uart2_trigger_update();
- uart2_toggle_clock();
-}
+#define BLSP1_UART0_BASE 0x078AF000
+#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000)
void qca_serial_init(struct ipq_serial_platdata *plat)
{
- int node, uart2_node;
+ int ret;
- writel(1, GCC_BLSP1_UART1_APPS_CBCR);
-
- node = fdt_path_offset(gd->fdt_blob, "/serial@78B1000/serial_gpio");
- if (node < 0) {
- printf("Could not find serial_gpio node\n");
+ if (plat->gpio_node < 0) {
+ printf("serial_init: unable to find gpio node \n");
return;
}
- if (plat->port_id == 1) {
- uart2_node = fdt_path_offset(gd->fdt_blob, "uart2");
- if (uart2_node < 0) {
- printf("Could not find uart2 node\n");
- return;
- }
- node = fdt_subnode_offset(gd->fdt_blob,
- uart2_node, "serial_gpio");
- uart2_clock_config(plat->m_value, plat->n_value, plat->d_value);
- writel(1, GCC_BLSP1_UART2_APPS_CBCR);
- }
- qca_gpio_init(node);
+ qca_gpio_init(plat->gpio_node);
+ plat->port_id = UART_PORT_ID(plat->reg_base);
+ ret = uart_clock_config(plat);
+ if (ret)
+ printf("UART clock config failed %d \n", ret);
+
+ return;
}
int do_pmic_reset()
@@ -844,11 +773,6 @@
printf("%s: invalid param for usb_mode\n", __func__);
}
-void fdt_fixup_set_dload_dis(void *blob)
-{
- parse_fdt_fixup("/soc/qca,scm_restart_reason%dload_status%1", blob);
-}
-
void enable_caches(void)
{
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
@@ -1127,7 +1051,7 @@
for (i = 0; i < mdc_mdio_gpio_cnt; i++) {
if (mdc_mdio_gpio[i] >=0) {
mdc_mdio_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(mdc_mdio_gpio[i]);
- writel(0x7, mdc_mdio_gpio_base);
+ writel(0xC7, mdc_mdio_gpio_base);
}
}
}
@@ -1397,6 +1321,7 @@
switch (machid)
{
case MACH_TYPE_IPQ6018_AP_CP01_C2:
+ case MACH_TYPE_IPQ6018_AP_CP01_C3:
return MACH_TYPE_IPQ6018_AP_CP01_C1;
case MACH_TYPE_IPQ6018_AP_CP01_C4:
return MACH_TYPE_IPQ6018_AP_CP01_C1;
@@ -1415,6 +1340,9 @@
case MACH_TYPE_IPQ6018_AP_CP01_C2:
config = "config@cp01-c2";
break;
+ case MACH_TYPE_IPQ6018_AP_CP01_C3:
+ config = "config@cp01-c3";
+ break;
case MACH_TYPE_IPQ6018_AP_CP01_C4:
config = "config@cp01-c4";
break;
@@ -1449,3 +1377,8 @@
parse_fdt_fixup("/soc/qcom_q6v5_wcss@CD00000%qcom,nosecure%1", blob);
parse_fdt_fixup("/soc/qcom_q6v5_wcss@CD00000%qca,wcss-aon-reset-seq%1", blob);
}
+
+int get_soc_hw_version(void)
+{
+ return readl(TCSR_SOC_HW_VERSION_REG);
+}
diff --git a/board/qca/arm/ipq6018/ipq6018.h b/board/qca/arm/ipq6018/ipq6018.h
index 85cb3f7..c02fb9b 100644
--- a/board/qca/arm/ipq6018/ipq6018.h
+++ b/board/qca/arm/ipq6018/ipq6018.h
@@ -59,35 +59,9 @@
#define SDCC1_N_VAL 0xFC
#define SDCC1_D_VAL 0xFD
-#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c
#define GCC_SDCC1_BCR 0x01842000
#define GCC_SDCC1_AHB_CBCR 0x0184201C
-#define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038
-#define GCC_BLSP1_UART2_APPS_M 0x0180303C
-#define GCC_BLSP1_UART2_APPS_N 0x01803040
-#define GCC_BLSP1_UART2_APPS_D 0x01803044
-#define GCC_BLSP1_UART2_APPS_CMD_RCGR 0x01803034
-#define GCC_BLSP1_UART2_APPS_CBCR 0x0180302C
-
-#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000
-#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700
-#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F
-
-#define GCC_UART_CFG_RCGR_MODE_SHIFT 12
-#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8
-#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0
-
-#define UART2_RCGR_SRC_SEL 0x1
-#define UART2_RCGR_SRC_DIV 0x0
-#define UART2_RCGR_MODE 0x2
-#define UART2_CMD_RCGR_UPDATE 0x1
-#define UART2_CBCR_CLK_ENABLE 0x1
-
-#define NOT_2D(two_d) (~two_d)
-#define NOT_N_MINUS_M(n,m) (~(n - m))
-#define CLOCK_UPDATE_TIMEOUT_US 1000
-
#define CLOCK_UPDATE_TIMEOUT_US 1000
#define KERNEL_AUTH_CMD 0x1E
#define SCM_CMD_SEC_AUTH 0x1F
diff --git a/board/qca/arm/ipq807x/ipq807x.c b/board/qca/arm/ipq807x/ipq807x.c
index 713d221..a47aef1 100644
--- a/board/qca/arm/ipq807x/ipq807x.c
+++ b/board/qca/arm/ipq807x/ipq807x.c
@@ -59,6 +59,9 @@
#define NOC_ERR_CLR_REG 0xb0002a0
#define DLOAD_MAGIC_COOKIE 0x10
+
+#define TCSR_SOC_HW_VERSION_REG 0x194D000
+
DECLARE_GLOBAL_DATA_PTR;
#define GCNT_PSHOLD 0x004AB000
@@ -1259,6 +1262,66 @@
}
#endif
+unsigned int get_dts_machid(unsigned int machid)
+{
+ switch (machid)
+ {
+ case MACH_TYPE_IPQ807x_AP_HK01_C3:
+ case MACH_TYPE_IPQ807x_AP_HK01_C6:
+ case MACH_TYPE_IPQ807x_AP_OAK03:
+ return MACH_TYPE_IPQ807x_AP_HK01_C1;
+ case MACH_TYPE_IPQ807x_AP_AC02:
+ return MACH_TYPE_IPQ807x_AP_AC01;
+ case MACH_TYPE_IPQ807x_AP_HK12_C1:
+ return MACH_TYPE_IPQ807x_AP_HK10_C2;
+ default:
+ return machid;
+ }
+}
+
+void ipq_uboot_fdt_fixup(void)
+{
+ int ret, len;
+ char *config = NULL;
+
+ switch (gd->bd->bi_arch_number)
+ {
+ case MACH_TYPE_IPQ807x_AP_HK01_C3:
+ config = "config@hk01.c3";
+ break;
+ case MACH_TYPE_IPQ807x_AP_HK01_C6:
+ config = "config@hk01.c6";
+ break;
+ case MACH_TYPE_IPQ807x_AP_HK12_C1:
+ config = "config@hk12";
+ break;
+ case MACH_TYPE_IPQ807x_AP_AC02:
+ config = "config@ac02";
+ break;
+ case MACH_TYPE_IPQ807x_AP_OAK03:
+ config = "config@oak03";
+ break;
+ }
+
+ if (config != NULL)
+ {
+ len = fdt_totalsize(gd->fdt_blob) + strlen(config) + 1;
+
+ /*
+ * Open in place with a new length.
+ */
+ ret = fdt_open_into(gd->fdt_blob, (void *)gd->fdt_blob, len);
+ if (ret)
+ printf("uboot-fdt-fixup: Cannot expand FDT: %s\n", fdt_strerror(ret));
+
+ ret = fdt_setprop((void *)gd->fdt_blob, 0, "config_name",
+ config, (strlen(config)+1));
+ if (ret)
+ printf("uboot-fdt-fixup: unable to set config_name(%d)\n", ret);
+ }
+ return;
+}
+
void ipq_fdt_fixup_socinfo(void *blob)
{
uint32_t cpu_type;
@@ -1551,15 +1614,17 @@
void fdt_fixup_set_dload_warm_reset(void *blob)
{
int nodeoff, ret;
- const char *dload_node = {"/soc/qca,scm_restart_reason"};
uint32_t setval = 1;
- nodeoff = fdt_path_offset(blob, dload_node);
+ nodeoff = fdt_path_offset(blob, "/soc/qca,scm_restart_reason");
if (nodeoff < 0) {
- printf("fixup_set_dload: unable to find node '%s'\n",
- dload_node);
- return;
+ nodeoff = fdt_path_offset(blob, "/qti,scm_restart_reason");
+ if (nodeoff < 0) {
+ printf("fixup_set_dload: unable to find scm_restart_reason node\n");
+ return;
+ }
}
+
ret = fdt_setprop_u32(blob, nodeoff, "dload_status", setval);
if (ret)
printf("fixup_set_dload: 'dload_status' not set");
@@ -1725,20 +1790,6 @@
execute_tzt(address);
}
-void set_platform_specific_default_env(void)
-{
- uint32_t soc_ver_major, soc_ver_minor, soc_version;
- int ret;
-
- ret = ipq_smem_get_socinfo_version((uint32_t *)&soc_version);
- if (!ret) {
- soc_ver_major = SOCINFO_VERSION_MAJOR(soc_version);
- soc_ver_minor = SOCINFO_VERSION_MINOR(soc_version);
- setenv_ulong("soc_version_major", (unsigned long)soc_ver_major);
- setenv_ulong("soc_version_minor", (unsigned long)soc_ver_minor);
- }
-}
-
void sdi_disable(void)
{
qca_scm_sdi();
@@ -1819,3 +1870,8 @@
qgic_dist_init();
qgic_cpu_init();
}
+
+int get_soc_hw_version(void)
+{
+ return readl(TCSR_SOC_HW_VERSION_REG);
+}
diff --git a/common/board_f.c b/common/board_f.c
index 9c2e1aa..26b1e64 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -842,12 +842,15 @@
#endif
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
+#ifdef CONFIG_COMPRESSED_DTB_BASE
+ initf_pre_malloc,
+#endif
fdtdec_setup,
#endif
+ initf_malloc,
#ifdef CONFIG_TRACE
trace_early_init,
#endif
- initf_malloc,
initf_console_record,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
/* TODO: can this go into arch_cpu_init()? */
diff --git a/common/cmd_aes.c b/common/cmd_aes.c
index 76da3ef..6ae6ecd 100644
--- a/common/cmd_aes.c
+++ b/common/cmd_aes.c
@@ -13,9 +13,149 @@
#include <malloc.h>
#include <asm/byteorder.h>
#include <linux/compiler.h>
+#include <asm/arch-qca-common/scm.h>
+#include <errno.h>
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_CMD_AES_256
+enum tz_crypto_service_aes_cmd_t {
+ TZ_CRYPTO_SERVICE_AES_ENC_ID = 0x7,
+ TZ_CRYPTO_SERVICE_AES_DEC_ID = 0x8,
+};
+
+enum tz_crypto_service_aes_type_t {
+ TZ_CRYPTO_SERVICE_AES_SHK = 0x1,
+ TZ_CRYPTO_SERVICE_AES_PHK = 0x2,
+ TZ_CRYPTO_SERVICE_AES_TYPE_MAX,
+
+};
+
+enum tz_crypto_service_aes_mode_t {
+ TZ_CRYPTO_SERVICE_AES_ECB = 0x0,
+ TZ_CRYPTO_SERVICE_AES_CBC = 0x1,
+ TZ_CRYPTO_SERVICE_AES_MODE_MAX,
+};
+
+struct crypto_aes_req_data_t {
+ uint64_t type;
+ uint64_t mode;
+ uint64_t req_buf;
+ uint64_t req_len;
+ uint64_t ivdata;
+ uint64_t iv_len;
+ uint64_t resp_buf;
+ uint64_t resp_len;
+};
+
+/**
+ * do_aes_256() - Handle the "aes" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
+static int do_aes_256(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ uint64_t src_addr, dst_addr, ivdata;
+ uint64_t req_len, iv_len, resp_len, type, mode;
+ struct crypto_aes_req_data_t *req_ptr = NULL;
+ int cmd_id = -1;
+ int ret = CMD_RET_USAGE;
+
+ if (argc != 10)
+ return ret;
+
+ if (!strncmp(argv[1], "enc", 3))
+ cmd_id = TZ_CRYPTO_SERVICE_AES_ENC_ID;
+ else if (!strncmp(argv[1], "dec", 3))
+ cmd_id = TZ_CRYPTO_SERVICE_AES_DEC_ID;
+ else
+ return ret;
+
+ type = simple_strtoul(argv[2], NULL, 16);
+ if (type >= TZ_CRYPTO_SERVICE_AES_TYPE_MAX) {
+ printf("unkown type specified, use 0x1 - SHK, 0x2 - PHK\n");
+ goto err;
+ }
+
+ mode = simple_strtoul(argv[3], NULL, 16);
+ if (mode >= TZ_CRYPTO_SERVICE_AES_MODE_MAX) {
+ printf("unkown mode specified, use 0x0 - ECB, 0x1 - CBC\n");
+ goto err;
+ }
+
+ src_addr = simple_strtoull(argv[4], NULL, 16);
+ req_len = simple_strtoul(argv[5], NULL, 16);
+ if (req_len <= 0 || (req_len % 16) != 0) {
+ printf("Invalid request buffer length, length "
+ "should be multiple of AES block size (16)\n");
+ goto err;
+ }
+
+ ivdata = simple_strtoull(argv[6], NULL, 16);
+ iv_len = simple_strtoul(argv[7], NULL, 16);
+ if (iv_len != 16) {
+ printf("Error: iv length should be equal to AES block size (16)\n");
+ goto err;
+ }
+
+ dst_addr = simple_strtoull(argv[8], NULL, 16);
+ resp_len = simple_strtoul(argv[9], NULL, 16);
+ if (resp_len < req_len) {
+ printf("Error: response buffer cannot be less then request buffer\n");
+ goto err;
+ }
+
+ req_ptr = (struct crypto_aes_req_data_t *)memalign(ARCH_DMA_MINALIGN,
+ sizeof(struct crypto_aes_req_data_t));
+ if (!req_ptr) {
+ printf("Error allocating memory");
+ return -ENOMEM;
+ }
+
+ req_ptr->type = type;
+ req_ptr->mode = mode;
+ req_ptr->req_buf = (uint64_t)src_addr;
+ req_ptr->req_len = req_len;
+ req_ptr->ivdata = (mode == TZ_CRYPTO_SERVICE_AES_CBC) ? (uint64_t)ivdata : 0;
+ req_ptr->iv_len = iv_len;
+ req_ptr->resp_buf = (uint64_t)dst_addr;
+ req_ptr->resp_len = resp_len;
+ ret = qca_scm_crypto(cmd_id, (void *)req_ptr,
+ sizeof(struct crypto_aes_req_data_t));
+
+ if (req_ptr)
+ free(req_ptr);
+
+ if (ret) {
+ printf("Scm call failed with error code: %d\n", ret);
+ return ret;
+ }
+ return 0;
+
+err:
+ if (req_ptr)
+ free(req_ptr);
+ return CMD_RET_USAGE;
+}
+
+/***************************************************/
+U_BOOT_CMD(
+ aes_256, 10, 1, do_aes_256,
+ "AES 256 CBC/ECB encryption/decryption",
+ "Encryption: echo enc <type> <mode> <plain data address> <plain data len>"
+ "<iv data address> <iv len> <response buf address> <response buf len>"
+ "Decryption: echo dec <type> <mode> <Encrypted buf address> <encrypted"
+ "buf len> <iv data address> <iv len> <response buf address> <response buf len>"
+);
+#endif
+
+
+#ifdef CONFIG_CMD_AES_128
/**
* do_aes() - Handle the "aes" command-line command
* @cmdtp: Command data struct pointer
@@ -87,3 +227,4 @@
"AES 128 CBC encryption",
aes_help_text
);
+#endif
diff --git a/common/cmd_flashwrite.c b/common/cmd_flashwrite.c
index 6e2be1a..50aeb3d 100644
--- a/common/cmd_flashwrite.c
+++ b/common/cmd_flashwrite.c
@@ -202,8 +202,9 @@
#endif
disk_partition_t disk_info = {0};
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
+#ifdef CONFIG_CMD_NAND
nand_info_t *nand = &nand_info[CONFIG_NAND_FLASH_INFO_IDX];
-
+#endif
if (strcmp(argv[0], "flash") == 0)
flash_cmd = 1;
@@ -350,7 +351,7 @@
}
if (flash_cmd) {
-
+#ifdef CONFIG_CMD_NAND
if (((flash_type == SMEM_BOOT_NAND_FLASH) ||
(flash_type == SMEM_BOOT_QSPI_NAND_FLASH))) {
@@ -358,7 +359,7 @@
if (adj_size)
file_size = file_size + (nand->writesize - adj_size);
}
-
+#endif
if (flash_type == SMEM_BOOT_MMC_FLASH) {
if (disk_info.blksz) {
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 380db53..ca7c9fc 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -809,6 +809,27 @@
index_partitions();
}
+#ifdef CONFIG_IPQ_TINY
+int parse_nor_partition(const char *const partdef,
+ const char **ret, struct part_info **retpart)
+{
+ return part_parse(partdef, ret, retpart);
+}
+
+void free_parse(struct list_head *head)
+{
+ struct list_head *entry, *n;
+ struct part_info *dev_tmp;
+
+ /* clean devices list */
+ list_for_each_safe(entry, n, head) {
+ dev_tmp = list_entry(entry, struct part_info, link);
+ list_del(entry);
+ free(dev_tmp);
+ }
+}
+#endif
+
/**
* Parse device type, name and mtd-id. If syntax is ok allocate memory and
* return pointer to the device structure.
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 69345db..14fae9c 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -19,6 +19,8 @@
#include <asm/io.h>
#include <dm/device-internal.h>
+DECLARE_GLOBAL_DATA_PTR;
+
static struct spi_flash *flash;
/*
@@ -265,6 +267,7 @@
int ret = 1;
int dev = 0;
loff_t offset, len, maxsize;
+ unsigned long sram_end = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
if (argc < 3)
return -1;
@@ -283,6 +286,16 @@
argv[0], flash->size);
return 1;
}
+ /* Validate DDR region address */
+ if ((addr < CONFIG_SYS_SDRAM_BASE) || (addr > (sram_end - 1))) {
+ puts("Invalid RAM address \n");
+ return 1;
+ }
+
+ if ((addr + len) > sram_end) {
+ puts("No space available\n");
+ return 1;
+ }
buf = map_physmem(addr, len, MAP_WRBACK);
if (!buf) {
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index b5bb051..5a77be4 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -3261,17 +3261,34 @@
}
}
+#ifdef CONFIG_COMPRESSED_DTB_BASE
+unsigned long malloc_base;
+
+int initf_pre_malloc(void)
+{
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+ assert(gd->malloc_base); /* Set up by crt0.S */
+ malloc_base = gd->malloc_base;
+ gd->malloc_limit = CONFIG_COMPRESSED_DTB_MAX_SIZE;
+ gd->malloc_base = CONFIG_COMPRESSED_DTB_BASE - CONFIG_COMPRESSED_DTB_MAX_SIZE;
+ gd->malloc_ptr = 0;
+#endif
+ return 0;
+}
+#endif
+
int initf_malloc(void)
{
#ifdef CONFIG_SYS_MALLOC_F_LEN
assert(gd->malloc_base); /* Set up by crt0.S */
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
+#ifdef CONFIG_COMPRESSED_DTB_BASE
+ gd->malloc_base = malloc_base;
+#endif
gd->malloc_ptr = 0;
#endif
-
return 0;
}
-
/*
History:
diff --git a/common/env_fat.c b/common/env_fat.c
index d79d864..32ba497 100644
--- a/common/env_fat.c
+++ b/common/env_fat.c
@@ -76,12 +76,18 @@
void env_relocate_spec(void)
{
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+ char *buf = NULL;
block_dev_desc_t *dev_desc = NULL;
disk_partition_t info;
int dev, part;
int err;
+ buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!buf) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
+ goto err_env_relocate;
+ }
+
part = get_device_and_partition(FAT_ENV_INTERFACE,
FAT_ENV_DEVICE_AND_PART,
&dev_desc, &info, 1);
@@ -103,8 +109,11 @@
}
env_import(buf, 1);
+ free(buf);
return;
err_env_relocate:
set_default_env(NULL);
+ if (buf)
+ free(buf);
}
diff --git a/common/env_mmc.c b/common/env_mmc.c
index 12f60ca..16aadcb 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -139,15 +139,21 @@
int mmc_saveenv(void)
{
- ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
u32 offset;
int ret, copy = 0;
const char *errmsg;
+ env_t *env_new = (env_t *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!env_new) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
+ return 1;
+ }
+
errmsg = init_mmc_for_env(mmc);
if (errmsg) {
printf("%s\n", errmsg);
+ free(env_new);
return 1;
}
@@ -184,6 +190,7 @@
fini:
fini_mmc_for_env(mmc);
+ free(env_new);
return ret;
}
#endif /* CONFIG_CMD_SAVEENV */
@@ -298,12 +305,17 @@
void mmc_env_relocate_spec(void)
{
#if !defined(ENV_IS_EMBEDDED)
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
struct mmc *mmc;
u32 offset;
int ret;
int dev = CONFIG_SYS_MMC_ENV_DEV;
- const char *errmsg;
+ const char *errmsg = NULL;
+ char *buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!buf) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
+ ret = 1;
+ goto err;
+ }
#ifdef CONFIG_SPL_BUILD
dev = 0;
@@ -336,6 +348,8 @@
err:
if (ret)
set_default_env(errmsg);
+ if (buf)
+ free(buf);
#endif
}
#endif /* CONFIG_ENV_OFFSET_REDUND */
diff --git a/common/env_nand.c b/common/env_nand.c
index d1f617a..3481a73 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -183,7 +183,6 @@
int nand_saveenv(void)
{
int ret = 0;
- ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
int env_idx = 0;
struct env_location location[] = {
{
@@ -204,13 +203,22 @@
#endif
};
-
- if (CONFIG_ENV_RANGE > board_env_size)
+ env_t *env_new = (env_t *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!env_new) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
return 1;
+ }
+
+ if (CONFIG_ENV_RANGE > board_env_size) {
+ free(env_new);
+ return 1;
+ }
ret = env_export(env_new);
- if (ret)
+ if (ret) {
+ free(env_new);
return ret;
+ }
#ifdef CONFIG_ENV_OFFSET_REDUND
env_new->flags = ++env_flags; /* increase the serial */
@@ -221,6 +229,7 @@
if (!ret) {
/* preset other copy for next write */
gd->env_valid = gd->env_valid == 2 ? 1 : 2;
+ free(env_new);
return ret;
}
@@ -230,7 +239,7 @@
printf("Warning: primary env write failed,"
" redundancy is lost!\n");
#endif
-
+ free(env_new);
return ret;
}
#endif /* CMD_SAVEENV */
@@ -385,7 +394,13 @@
{
#if !defined(ENV_IS_EMBEDDED)
int ret;
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+ char *buf = NULL;
+ buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!buf) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
+ set_default_env(NULL);
+ return;
+ }
#if defined(CONFIG_ENV_OFFSET_OOB)
ret = get_nand_env_oob(&nand_info[nand_env_device], &nand_env_oob_offset);
@@ -397,6 +412,7 @@
printf("Found Environment offset in OOB..\n");
} else {
set_default_env("!no env offset in OOB");
+ free(buf);
return;
}
#endif
@@ -404,10 +420,12 @@
ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
if (ret) {
set_default_env("!readenv() failed");
+ free(buf);
return;
}
env_import(buf, 1);
+ free(buf);
#endif /* ! ENV_IS_EMBEDDED */
}
#endif /* CONFIG_ENV_OFFSET_REDUND */
diff --git a/common/env_sf.c b/common/env_sf.c
index 21c2327..cbf0bc8 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -52,14 +52,12 @@
u32 saved_size, saved_offset, sector = 1;
int ret;
+ env_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+ CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
if (!env_flash) {
- env_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
- CONFIG_SF_DEFAULT_CS,
- CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
- if (!env_flash) {
- set_default_env("!spi_flash_probe() failed");
- return 1;
- }
+ set_default_env("!spi_flash_probe() failed");
+ return 1;
}
ret = env_export(&env_new);
@@ -226,14 +224,12 @@
int ret = 1;
env_t env_new;
+ env_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
+ CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
if (!env_flash) {
- env_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
- CONFIG_SF_DEFAULT_CS,
- CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
- if (!env_flash) {
- set_default_env("!spi_flash_probe() failed");
- return 1;
- }
+ set_default_env("!spi_flash_probe() failed");
+ return 1;
}
/* Is the sector larger than the env (i.e. embedded) */
diff --git a/common/env_ubi.c b/common/env_ubi.c
index e611199..50178a9 100644
--- a/common/env_ubi.c
+++ b/common/env_ubi.c
@@ -81,14 +81,21 @@
#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
int saveenv(void)
{
- ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
int ret;
+ env_t *env_new = (env_t *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE)
+ if (!env_new) {
+ printf("Error: Cannot allocate %d bytes\n", CONFIG_ENV_SIZE);
+ return 1;
+ }
ret = env_export(env_new);
- if (ret)
+ if (ret) {
+ free(env_new);
return ret;
+ }
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
+ free(env_new);
printf("\n** Cannot find mtd partition \"%s\"\n",
CONFIG_ENV_UBI_PART);
return 1;
@@ -96,11 +103,13 @@
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
CONFIG_ENV_SIZE)) {
+ free(env_new);
printf("\n** Unable to write env to %s:%s **\n",
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
return 1;
}
+ free(env_new);
puts("done\n");
return 0;
}
@@ -172,12 +181,20 @@
#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
void env_relocate_spec(void)
{
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+
+ char *buf = NULL;
+ buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
+ if (!buf) {
+ printf("Error: Cannot allocate %d bytes\n");
+ set_default_env(NULL);
+ return;
+ }
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
printf("\n** Cannot find mtd partition \"%s\"\n",
CONFIG_ENV_UBI_PART);
set_default_env(NULL);
+ free(buf);
return;
}
@@ -185,9 +202,11 @@
printf("\n** Unable to read env from %s:%s **\n",
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
set_default_env(NULL);
+ free(buf);
return;
}
env_import(buf, 1);
+ free(buf);
}
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
diff --git a/configs/ipq5018_defconfig b/configs/ipq5018_defconfig
new file mode 100644
index 0000000..b10406f
--- /dev/null
+++ b/configs/ipq5018_defconfig
@@ -0,0 +1,335 @@
+CONFIG_ARM=y
+CONFIG_HAS_VBAR=y
+CONFIG_CPU_V7=y
+CONFIG_ARCH_IPQ5018=y
+CONFIG_SYS_MALLOC_F_LEN=0x400
+CONFIG_SYS_MALLOC_F=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_FIT_SIGNATURE is not set
+CONFIG_SYS_EXTRA_OPTIONS=""
+CONFIG_SYS_PROMPT="IPQ5018# "
+
+#
+# Tiny support
+#
+# CONFIG_IPQ_TINY is not set
+
+#
+# Info commands
+#
+CONFIG_CMD_BDI=y
+CONFIG_CMD_CONSOLE=y
+
+#
+# Boot commands
+#
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_RUN=y
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+
+#
+# Environment commands
+#
+CONFIG_CMD_EXPORTENV=y
+CONFIG_CMD_IMPORTENV=y
+CONFIG_CMD_EDITENV=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_ENV_EXISTS=y
+
+#
+# Memory commands
+#
+CONFIG_CMD_MEMORY=y
+CONFIG_CMD_CRC32=y
+# CONFIG_LOOPW is not set
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_MX_CYCLIC is not set
+# CONFIG_CMD_MEMINFO is not set
+
+#
+# Device access commands
+#
+
+CONFIG_CMD_DM=y
+# CONFIG_CMD_DEMO is not set
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_FLASH=y
+# CONFIG_CMD_NAND is not set
+# CONFIG_CMD_SF is not set
+# CONFIG_CMD_SPI is not set
+# CONFIG_CMD_I2C is not set
+# CONFIG_CMD_USB is not set
+CONFIG_CMD_FPGA=y
+
+#
+# Shell scripting commands
+#
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ITEST=y
+CONFIG_CMD_SOURCE=y
+CONFIG_CMD_SETEXPR=y
+
+#
+# Network commands
+#
+
+#
+# Network PHY
+#
+CONFIG_QCA8081_PHY=y
+
+CONFIG_CMD_NET=y
+# CONFIG_CMD_TFTPPUT is not set
+# CONFIG_CMD_TFTPSRV is not set
+# CONFIG_CMD_RARP is not set
+# CONFIG_CMD_DHCP is not set
+CONFIG_CMD_NFS=y
+# CONFIG_CMD_PING is not set
+# CONFIG_CMD_CDP is not set
+# CONFIG_CMD_SNTP is not set
+# CONFIG_CMD_DNS is not set
+# CONFIG_CMD_LINK_LOCAL is not set
+
+#
+# Misc commands
+#
+# CONFIG_CMD_TIME is not set
+CONFIG_CMD_MISC=y
+CONFIG_CMD_PART=y
+CONFIG_PARTITION_UUIDS=y
+# CONFIG_CMD_TIMER is not set
+CONFIG_IPQ_TZT=y
+CONFIG_UBI_WRITE=y
+#
+# Boot timing
+#
+# CONFIG_BOOTSTAGE is not set
+CONFIG_BOOTSTAGE_USER_COUNT=20
+CONFIG_BOOTSTAGE_STASH_ADDR=0
+CONFIG_BOOTSTAGE_STASH_SIZE=4096
+
+#
+# Power commands
+#
+
+#
+# Security commands
+#
+CONFIG_SUPPORT_OF_CONTROL=y
+
+#
+# Device Tree Control
+#
+CONFIG_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
+# CONFIG_OF_EMBED is not set
+CONFIG_NET=y
+# CONFIG_NET_RANDOM_ETHADDR is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_DM=y
+CONFIG_DM_WARN=y
+CONFIG_DM_DEVICE_REMOVE=y
+CONFIG_DM_STDIO=y
+CONFIG_DM_SEQ_ALIAS=y
+# CONFIG_REGMAP is not set
+# CONFIG_DEVRES is not set
+CONFIG_SIMPLE_BUS=y
+# CONFIG_CLK is not set
+# CONFIG_CPU is not set
+
+#
+# Hardware crypto devices
+#
+# CONFIG_FSL_CAAM is not set
+
+#
+# Demo for driver model
+#
+# CONFIG_DM_DEMO is not set
+
+#
+# DFU support
+#
+# CONFIG_DFU_TFTP is not set
+
+#
+# GPIO Support
+#
+# CONFIG_LPC32XX_GPIO is not set
+# CONFIG_VYBRID_GPIO is not set
+
+#
+# I2C support
+#
+# CONFIG_DM_I2C_COMPAT is not set
+# CONFIG_CROS_EC_KEYB is not set
+CONFIG_IPQ5018_I2C=y
+
+#
+# LED Support
+#
+# CONFIG_LED is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_CROS_EC is not set
+# CONFIG_FSL_SEC_MON is not set
+# CONFIG_PCA9551_LED is not set
+# CONFIG_RESET is not set
+
+#
+# MMC Host controller Support
+#
+# CONFIG_DM_MMC is not set
+CONFIG_MMC_FLASH=y
+
+#
+# NAND Device Support
+#
+# CONFIG_NAND_DENALI is not set
+# CONFIG_NAND_VF610_NFC is not set
+# CONFIG_NAND_PXA3XX is not set
+
+#
+# Generic NAND options
+#
+CONFIG_NAND_FLASH=y
+
+#
+# Serial NAND
+#
+CONFIG_QPIC_SERIAL=y
+
+#
+# SPI Flash Support
+
+#
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DM_ETH is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_IPQ_MTD_NOR is not set
+# CONFIG_IPQ_TINY_SPI_NOR is not set
+
+#
+# PCI
+#
+# CONFIG_DM_PCI is not set
+CONFIG_PCI_IPQ=y
+
+#
+# Pin controllers
+#
+# CONFIG_PINCTRL is not set
+
+#
+# Power
+#
+# CONFIG_DM_PMIC is not set
+# CONFIG_DM_REGULATOR is not set
+# CONFIG_RAM is not set
+
+#
+# Real Time Clock
+#
+# CONFIG_DM_RTC is not set
+
+#
+# Serial drivers
+#
+CONFIG_REQUIRE_SERIAL_CONSOLE=y
+# CONFIG_DEBUG_UART is not set
+
+#
+
+# Sound support
+#
+# CONFIG_SOUND is not set
+
+#
+# SPI Support
+#
+# CONFIG_FSL_ESPI is not set
+# CONFIG_TI_QSPI is not set
+# CONFIG_DM_THERMAL is not set
+
+#
+# TPM support
+#
+
+#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_IPQ=y
+
+#
+# Graphics support
+#
+# CONFIG_VIDEO_VESA is not set
+# CONFIG_VIDEO_LCD_ANX9804 is not set
+# CONFIG_VIDEO_LCD_SSD2828 is not set
+# CONFIG_DISPLAY_PORT is not set
+# CONFIG_VIDEO_TEGRA124 is not set
+# CONFIG_VIDEO_BRIDGE is not set
+# CONFIG_PHYS_TO_BUS is not set
+
+#
+# File systems
+#
+
+#
+# Library routines
+
+#
+# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
+CONFIG_HAVE_PRIVATE_LIBGCC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_SYS_HZ=1000
+# CONFIG_SYS_VSNPRINTF is not set
+CONFIG_REGEX=y
+# CONFIG_LIB_RAND is not set
+# CONFIG_CMD_DHRYSTONE is not set
+# CONFIG_RSA is not set
+# CONFIG_TPM is not set
+
+#
+# Hashing Support
+#
+# CONFIG_SHA1 is not set
+# CONFIG_SHA256 is not set
+# CONFIG_SHA_HW_ACCEL is not set
+
+#
+# Compression Support
+#
+# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
+# CONFIG_ERRNO_STR is not set
+# CONFIG_UNIT_TEST is not set
+
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_HAS_THUMB2=y
diff --git a/configs/ipq5018_tiny_debug_defconfig b/configs/ipq5018_tiny_debug_defconfig
new file mode 100644
index 0000000..f699473
--- /dev/null
+++ b/configs/ipq5018_tiny_debug_defconfig
@@ -0,0 +1,342 @@
+CONFIG_ARM=y
+CONFIG_HAS_VBAR=y
+CONFIG_CPU_V7=y
+CONFIG_ARCH_IPQ5018=y
+CONFIG_SYS_MALLOC_F_LEN=0x400
+CONFIG_SYS_MALLOC_F=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_FIT_SIGNATURE is not set
+CONFIG_SYS_EXTRA_OPTIONS=""
+CONFIG_SYS_PROMPT="IPQ5018# "
+
+#
+# Tiny support
+#
+CONFIG_IPQ_TINY=y
+
+#
+# Info commands
+#
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+
+#
+# Boot commands
+#
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_RUN=y
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+
+#
+# Environment commands
+#
+CONFIG_CMD_EXPORTENV=y
+CONFIG_CMD_IMPORTENV=y
+# CONFIG_CMD_EDITENV is not set
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_ENV_EXISTS=y
+
+#
+# Memory commands
+#
+CONFIG_CMD_MEMORY=y
+CONFIG_CMD_CRC32=y
+# CONFIG_LOOPW is not set
+# CONFIG_CMD_MEMTEST is not set
+# CONFIG_CMD_MX_CYCLIC is not set
+# CONFIG_CMD_MEMINFO is not set
+
+#
+# Device access commands
+#
+
+# CONFIG_CMD_DM is not set
+# CONFIG_CMD_DEMO is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_NAND is not set
+# CONFIG_CMD_SF is not set
+# CONFIG_CMD_SPI is not set
+# CONFIG_CMD_I2C is not set
+# CONFIG_CMD_USB is not set
+# CONFIG_CMD_FPGA is not set
+
+#
+# Shell scripting commands
+#
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_ITEST is not set
+CONFIG_CMD_SOURCE=y
+# CONFIG_CMD_SETEXPR is not set
+
+#
+# Network commands
+#
+CONFIG_CMD_NET=y
+# CONFIG_CMD_TFTPPUT is not set
+# CONFIG_CMD_TFTPSRV is not set
+# CONFIG_CMD_RARP is not set
+# CONFIG_CMD_DHCP is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_PING is not set
+# CONFIG_CMD_CDP is not set
+# CONFIG_CMD_SNTP is not set
+# CONFIG_CMD_DNS is not set
+# CONFIG_CMD_LINK_LOCAL is not set
+
+#
+# Misc commands
+#
+# CONFIG_CMD_TIME is not set
+CONFIG_CMD_MISC=y
+# CONFIG_CMD_PART is not set
+# CONFIG_PARTITION_UUIDS is not set
+# CONFIG_CMD_TIMER is not set
+# CONFIG_IPQ_TZT is not set
+# CONFIG_UBI_WRITE is not set
+#
+# Boot timing
+#
+# CONFIG_BOOTSTAGE is not set
+CONFIG_BOOTSTAGE_USER_COUNT=20
+CONFIG_BOOTSTAGE_STASH_ADDR=0
+CONFIG_BOOTSTAGE_STASH_SIZE=4096
+
+#
+# Power commands
+#
+
+#
+# Security commands
+#
+CONFIG_SUPPORT_OF_CONTROL=y
+
+#
+# Device Tree Control
+#
+CONFIG_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
+# CONFIG_OF_EMBED is not set
+CONFIG_NET=y
+# CONFIG_NET_RANDOM_ETHADDR is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_DM=y
+CONFIG_DM_WARN=y
+CONFIG_DM_DEVICE_REMOVE=y
+CONFIG_DM_STDIO=y
+CONFIG_DM_SEQ_ALIAS=y
+# CONFIG_REGMAP is not set
+# CONFIG_DEVRES is not set
+CONFIG_SIMPLE_BUS=y
+# CONFIG_CLK is not set
+# CONFIG_CPU is not set
+
+#
+# Hardware crypto devices
+#
+# CONFIG_FSL_CAAM is not set
+
+#
+# Demo for driver model
+#
+# CONFIG_DM_DEMO is not set
+
+#
+# DFU support
+#
+# CONFIG_DFU_TFTP is not set
+
+#
+# GPIO Support
+#
+# CONFIG_LPC32XX_GPIO is not set
+# CONFIG_VYBRID_GPIO is not set
+
+#
+# I2C support
+#
+# CONFIG_DM_I2C_COMPAT is not set
+# CONFIG_CROS_EC_KEYB is not set
+# CONFIG_IPQ5018_I2C is not set
+
+#
+# LED Support
+#
+# CONFIG_LED is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_CROS_EC is not set
+# CONFIG_FSL_SEC_MON is not set
+# CONFIG_PCA9551_LED is not set
+# CONFIG_RESET is not set
+
+#
+# MMC Host controller Support
+#
+# CONFIG_DM_MMC is not set
+# CONFIG_MMC_FLASH is not set
+
+#
+# NAND Device Support
+#
+# CONFIG_NAND_DENALI is not set
+# CONFIG_NAND_VF610_NFC is not set
+# CONFIG_NAND_PXA3XX is not set
+
+#
+# Generic NAND options
+#
+CONFIG_NAND_FLASH=y
+
+#
+# Serial NAND
+#
+CONFIG_QPIC_SERIAL=y
+
+#
+# SPI Flash Support
+
+#
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DM_ETH is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_IPQ_MTD_NOR is not set
+CONFIG_IPQ_TINY_SPI_NOR=y
+
+#
+# PCI
+#
+# CONFIG_DM_PCI is not set
+# CONFIG_PCI_IPQ is not set
+
+#
+# Pin controllers
+#
+# CONFIG_PINCTRL is not set
+
+#
+# Power
+#
+# CONFIG_DM_PMIC is not set
+# CONFIG_DM_REGULATOR is not set
+# CONFIG_RAM is not set
+
+#
+# Real Time Clock
+#
+# CONFIG_DM_RTC is not set
+
+#
+# Serial drivers
+#
+CONFIG_REQUIRE_SERIAL_CONSOLE=y
+# CONFIG_DEBUG_UART is not set
+
+#
+
+# Sound support
+#
+# CONFIG_SOUND is not set
+
+#
+# SPI Support
+#
+# CONFIG_FSL_ESPI is not set
+# CONFIG_TI_QSPI is not set
+# CONFIG_DM_THERMAL is not set
+
+#
+# TPM support
+#
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_DM_USB is not set
+# CONFIG_USB_XHCI_IPQ is not set
+
+#
+# Graphics support
+#
+# CONFIG_VIDEO_VESA is not set
+# CONFIG_VIDEO_LCD_ANX9804 is not set
+# CONFIG_VIDEO_LCD_SSD2828 is not set
+# CONFIG_DISPLAY_PORT is not set
+# CONFIG_VIDEO_TEGRA124 is not set
+# CONFIG_VIDEO_BRIDGE is not set
+# CONFIG_PHYS_TO_BUS is not set
+
+#
+# File systems
+#
+
+#
+# Ethernet PHY
+#
+CONFIG_QCA8033_PHY=y
+
+#
+# Library routines
+
+#
+# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
+CONFIG_HAVE_PRIVATE_LIBGCC=y
+# CONFIG_USE_PRIVATE_LIBGCC is not set
+CONFIG_SYS_HZ=1000
+# CONFIG_SYS_VSNPRINTF is not set
+CONFIG_REGEX=y
+# CONFIG_LIB_RAND is not set
+# CONFIG_CMD_DHRYSTONE is not set
+# CONFIG_RSA is not set
+# CONFIG_TPM is not set
+
+#
+# Hashing Support
+#
+# CONFIG_SHA1 is not set
+# CONFIG_SHA256 is not set
+# CONFIG_SHA_HW_ACCEL is not set
+
+#
+# Compression Support
+#
+# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
+# CONFIG_ERRNO_STR is not set
+# CONFIG_UNIT_TEST is not set
+
+#
+# Thumb2 mode support
+#
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_HAS_THUMB2=y
+
+#
+# ART uncompression support
+#
+CONFIG_ART_COMPRESSED=y
diff --git a/configs/ipq5018_tiny_defconfig b/configs/ipq5018_tiny_defconfig
new file mode 100644
index 0000000..40cf113
--- /dev/null
+++ b/configs/ipq5018_tiny_defconfig
@@ -0,0 +1,342 @@
+CONFIG_ARM=y
+CONFIG_HAS_VBAR=y
+CONFIG_CPU_V7=y
+CONFIG_ARCH_IPQ5018=y
+CONFIG_SYS_MALLOC_F_LEN=0x400
+CONFIG_SYS_MALLOC_F=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+# CONFIG_FIT_SIGNATURE is not set
+CONFIG_SYS_EXTRA_OPTIONS=""
+CONFIG_SYS_PROMPT="IPQ5018# "
+
+#
+# Tiny support
+#
+CONFIG_IPQ_TINY=y
+
+#
+# Info commands
+#
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+
+#
+# Boot commands
+#
+# CONFIG_CMD_BOOTD is not set
+CONFIG_CMD_BOOTM=y
+# CONFIG_CMD_GO is not set
+CONFIG_CMD_RUN=y
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_XIMG is not set
+
+#
+# Environment commands
+#
+CONFIG_CMD_EXPORTENV=y
+CONFIG_CMD_IMPORTENV=y
+# CONFIG_CMD_EDITENV is not set
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_ENV_EXISTS=y
+
+#
+# Memory commands
+#
+CONFIG_CMD_MEMORY=y
+CONFIG_CMD_CRC32=y
+# CONFIG_LOOPW is not set
+# CONFIG_CMD_MEMTEST is not set
+# CONFIG_CMD_MX_CYCLIC is not set
+# CONFIG_CMD_MEMINFO is not set
+
+#
+# Device access commands
+#
+
+# CONFIG_CMD_DM is not set
+# CONFIG_CMD_DEMO is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_NAND is not set
+# CONFIG_CMD_SF is not set
+# CONFIG_CMD_SPI is not set
+# CONFIG_CMD_I2C is not set
+# CONFIG_CMD_USB is not set
+# CONFIG_CMD_FPGA is not set
+
+#
+# Shell scripting commands
+#
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_ITEST is not set
+CONFIG_CMD_SOURCE=y
+# CONFIG_CMD_SETEXPR is not set
+
+#
+# Network commands
+#
+CONFIG_CMD_NET=y
+# CONFIG_CMD_TFTPPUT is not set
+# CONFIG_CMD_TFTPSRV is not set
+# CONFIG_CMD_RARP is not set
+# CONFIG_CMD_DHCP is not set
+# CONFIG_CMD_NFS is not set
+# CONFIG_CMD_PING is not set
+# CONFIG_CMD_CDP is not set
+# CONFIG_CMD_SNTP is not set
+# CONFIG_CMD_DNS is not set
+# CONFIG_CMD_LINK_LOCAL is not set
+
+#
+# Misc commands
+#
+# CONFIG_CMD_TIME is not set
+CONFIG_CMD_MISC=y
+# CONFIG_CMD_PART is not set
+# CONFIG_PARTITION_UUIDS is not set
+# CONFIG_CMD_TIMER is not set
+# CONFIG_IPQ_TZT is not set
+# CONFIG_UBI_WRITE is not set
+#
+# Boot timing
+#
+# CONFIG_BOOTSTAGE is not set
+CONFIG_BOOTSTAGE_USER_COUNT=20
+CONFIG_BOOTSTAGE_STASH_ADDR=0
+CONFIG_BOOTSTAGE_STASH_SIZE=4096
+
+#
+# Power commands
+#
+
+#
+# Security commands
+#
+CONFIG_SUPPORT_OF_CONTROL=y
+
+#
+# Device Tree Control
+#
+CONFIG_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
+# CONFIG_OF_EMBED is not set
+CONFIG_NET=y
+# CONFIG_NET_RANDOM_ETHADDR is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_DM=y
+CONFIG_DM_WARN=y
+CONFIG_DM_DEVICE_REMOVE=y
+CONFIG_DM_STDIO=y
+CONFIG_DM_SEQ_ALIAS=y
+# CONFIG_REGMAP is not set
+# CONFIG_DEVRES is not set
+CONFIG_SIMPLE_BUS=y
+# CONFIG_CLK is not set
+# CONFIG_CPU is not set
+
+#
+# Hardware crypto devices
+#
+# CONFIG_FSL_CAAM is not set
+
+#
+# Demo for driver model
+#
+# CONFIG_DM_DEMO is not set
+
+#
+# DFU support
+#
+# CONFIG_DFU_TFTP is not set
+
+#
+# GPIO Support
+#
+# CONFIG_LPC32XX_GPIO is not set
+# CONFIG_VYBRID_GPIO is not set
+
+#
+# I2C support
+#
+# CONFIG_DM_I2C_COMPAT is not set
+# CONFIG_CROS_EC_KEYB is not set
+# CONFIG_IPQ5018_I2C is not set
+
+#
+# LED Support
+#
+# CONFIG_LED is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_CROS_EC is not set
+# CONFIG_FSL_SEC_MON is not set
+# CONFIG_PCA9551_LED is not set
+# CONFIG_RESET is not set
+
+#
+# MMC Host controller Support
+#
+# CONFIG_DM_MMC is not set
+# CONFIG_MMC_FLASH is not set
+
+#
+# NAND Device Support
+#
+# CONFIG_NAND_DENALI is not set
+# CONFIG_NAND_VF610_NFC is not set
+# CONFIG_NAND_PXA3XX is not set
+
+#
+# Generic NAND options
+#
+# CONFIG_NAND_FLASH is not set
+
+#
+# Serial NAND
+#
+# CONFIG_QPIC_SERIAL is not set
+
+#
+# SPI Flash Support
+
+#
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DM_ETH is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_IPQ_MTD_NOR is not set
+CONFIG_IPQ_TINY_SPI_NOR=y
+
+#
+# PCI
+#
+# CONFIG_DM_PCI is not set
+# CONFIG_PCI_IPQ is not set
+
+#
+# Pin controllers
+#
+# CONFIG_PINCTRL is not set
+
+#
+# Power
+#
+# CONFIG_DM_PMIC is not set
+# CONFIG_DM_REGULATOR is not set
+# CONFIG_RAM is not set
+
+#
+# Real Time Clock
+#
+# CONFIG_DM_RTC is not set
+
+#
+# Serial drivers
+#
+CONFIG_REQUIRE_SERIAL_CONSOLE=y
+# CONFIG_DEBUG_UART is not set
+
+#
+
+# Sound support
+#
+# CONFIG_SOUND is not set
+
+#
+# SPI Support
+#
+# CONFIG_FSL_ESPI is not set
+# CONFIG_TI_QSPI is not set
+# CONFIG_DM_THERMAL is not set
+
+#
+# TPM support
+#
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_DM_USB is not set
+# CONFIG_USB_XHCI_IPQ is not set
+
+#
+# Graphics support
+#
+# CONFIG_VIDEO_VESA is not set
+# CONFIG_VIDEO_LCD_ANX9804 is not set
+# CONFIG_VIDEO_LCD_SSD2828 is not set
+# CONFIG_DISPLAY_PORT is not set
+# CONFIG_VIDEO_TEGRA124 is not set
+# CONFIG_VIDEO_BRIDGE is not set
+# CONFIG_PHYS_TO_BUS is not set
+
+#
+# File systems
+#
+
+#
+# Ethernet PHY
+#
+CONFIG_QCA8033_PHY=y
+
+#
+# Library routines
+
+#
+# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
+CONFIG_HAVE_PRIVATE_LIBGCC=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_SYS_HZ=1000
+# CONFIG_SYS_VSNPRINTF is not set
+CONFIG_REGEX=y
+# CONFIG_LIB_RAND is not set
+# CONFIG_CMD_DHRYSTONE is not set
+# CONFIG_RSA is not set
+# CONFIG_TPM is not set
+
+#
+# Hashing Support
+#
+# CONFIG_SHA1 is not set
+# CONFIG_SHA256 is not set
+# CONFIG_SHA_HW_ACCEL is not set
+
+#
+# Compression Support
+#
+# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
+# CONFIG_ERRNO_STR is not set
+# CONFIG_UNIT_TEST is not set
+
+#
+# Thumb2 mode support
+#
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_HAS_THUMB2=y
+
+#
+# ART uncompression support
+#
+CONFIG_ART_COMPRESSED=y
diff --git a/configs/ipq6018_defconfig b/configs/ipq6018_defconfig
index e3396ed..8b83a56 100644
--- a/configs/ipq6018_defconfig
+++ b/configs/ipq6018_defconfig
@@ -293,7 +293,7 @@
#
# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
CONFIG_HAVE_PRIVATE_LIBGCC=y
-# CONFIG_USE_PRIVATE_LIBGCC is not set
+CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_HZ=1000
# CONFIG_SYS_VSNPRINTF is not set
CONFIG_REGEX=y
@@ -313,5 +313,6 @@
# Compression Support
#
# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
# CONFIG_ERRNO_STR is not set
# CONFIG_UNIT_TEST is not set
diff --git a/configs/ipq6018_tiny_defconfig b/configs/ipq6018_tiny_defconfig
index e4dee21..30758e2 100644
--- a/configs/ipq6018_tiny_defconfig
+++ b/configs/ipq6018_tiny_defconfig
@@ -293,7 +293,7 @@
#
# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
CONFIG_HAVE_PRIVATE_LIBGCC=y
-# CONFIG_USE_PRIVATE_LIBGCC is not set
+CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_HZ=1000
# CONFIG_SYS_VSNPRINTF is not set
CONFIG_REGEX=y
diff --git a/configs/ipq807x_defconfig b/configs/ipq807x_defconfig
index 70b4183..6fa49f5 100644
--- a/configs/ipq807x_defconfig
+++ b/configs/ipq807x_defconfig
@@ -292,7 +292,7 @@
#
# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
CONFIG_HAVE_PRIVATE_LIBGCC=y
-# CONFIG_USE_PRIVATE_LIBGCC is not set
+CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_HZ=1000
# CONFIG_SYS_VSNPRINTF is not set
# CONFIG_REGEX is not set
@@ -312,5 +312,6 @@
# Compression Support
#
# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
# CONFIG_ERRNO_STR is not set
# CONFIG_UNIT_TEST is not set
diff --git a/configs/ipq807x_tiny_defconfig b/configs/ipq807x_tiny_defconfig
index becb277..b79e5da 100644
--- a/configs/ipq807x_tiny_defconfig
+++ b/configs/ipq807x_tiny_defconfig
@@ -292,7 +292,7 @@
#
# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set
CONFIG_HAVE_PRIVATE_LIBGCC=y
-# CONFIG_USE_PRIVATE_LIBGCC is not set
+CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_HZ=1000
# CONFIG_SYS_VSNPRINTF is not set
# CONFIG_REGEX is not set
@@ -312,7 +312,8 @@
# Compression Support
#
# CONFIG_LZ4 is not set
+CONFIG_LZMA=y
# CONFIG_ERRNO_STR is not set
# CONFIG_UNIT_TEST is not set
CONFIG_HAS_THUMB2=y
-CONFIG_SYS_THUMB_BUILD=y
\ No newline at end of file
+CONFIG_SYS_THUMB_BUILD=y
diff --git a/disk/part.c b/disk/part.c
index 909712e..7fe2e7d 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -20,6 +20,9 @@
#define PRINTF(fmt,args...)
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef HAVE_BLOCK_DEVICE
struct block_drvr {
char *name;
block_dev_desc_t* (*get_dev)(int dev);
@@ -55,9 +58,6 @@
{ },
};
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef HAVE_BLOCK_DEVICE
static block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
{
const struct block_drvr *drvr = block_drvr;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 766be9c..eab03ba 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -272,7 +272,8 @@
dst += cur * mmc->read_bl_len;
} while (blocks_todo > 0);
#if !defined(CONFIG_SYS_DCACHE_OFF)
- flush_cache((unsigned long)dst, blkcnt * mmc->read_bl_len);
+ flush_cache((unsigned long)dst - ( blkcnt * mmc->read_bl_len),
+ blkcnt * mmc->read_bl_len);
#endif
return blkcnt;
diff --git a/drivers/mtd/ipq_spi_flash.c b/drivers/mtd/ipq_spi_flash.c
index 573fd61..21e2fe2 100644
--- a/drivers/mtd/ipq_spi_flash.c
+++ b/drivers/mtd/ipq_spi_flash.c
@@ -132,7 +132,7 @@
int ipq_spi_init(u16 idx)
{
struct spi_flash *flash;
- int ret;
+ int ret = 0;
struct mtd_info *mtd;
flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
@@ -165,14 +165,14 @@
mtd->_write_oob = ipq_spi_write_oob;
mtd->_block_isbad = ipq_spi_block_isbad;
mtd->_block_markbad = ipq_spi_block_markbad;
-
+#ifdef CONFIG_MTD_DEVICE
if ((ret = nand_register(idx)) < 0) {
spi_print("Failed to register with MTD subsystem\n");
return ret;
}
-
+#endif
spi_print("page_size: 0x%x, sector_size: 0x%x, size: 0x%x\n",
flash->page_size, flash->sector_size, flash->size);
- return 0;
+ return ret;
}
diff --git a/drivers/mtd/nand/qpic_nand.c b/drivers/mtd/nand/qpic_nand.c
index 59904c9..2d0aee0 100644
--- a/drivers/mtd/nand/qpic_nand.c
+++ b/drivers/mtd/nand/qpic_nand.c
@@ -115,10 +115,120 @@
.check_quad_config = false,
.name = "MT29F1G01ABBFDWB-IT",
},
+ {
+ .id = { 0xef, 0xbc },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 1024,
+ .spare_size = 64,
+ .density = 0x08000000,
+ .otp_region = 0x5000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 4,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = true,
+ .name = "W25N01JW",
+ },
+ {
+ .id = { 0xc8, 0x11 },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 1024,
+ .spare_size = 64,
+ .density = 0x08000000,
+ .otp_region = 0x2000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 4,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = false,
+ .name = "F50D1G41LB(2M)",
+ },
+ {
+ .id = { 0xc8, 0x41 },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 2048,
+ .spare_size = 128,
+ .density = 0x08000000,
+ .otp_region = 0x2000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 8,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = true,
+ .name = "GD5F1GQ5REYIG",
+ },
+ {
+ .id = { 0xc8, 0x21 },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 1024,
+ .spare_size = 64,
+ .density = 0x08000000,
+ .otp_region = 0x2000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 4,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = true,
+ .name = "GD5F1GQ5REYIH",
+ },
+ {
+ .id = { 0xef, 0xbf },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 2048,
+ .spare_size = 64,
+ .density = 0x10000000,
+ .otp_region = 0x2000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 4,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = true,
+ .name = "W25N02JWZEIF",
+ },
+ {
+ .id = { 0xc2, 0x92 },
+ .page_size = 2048,
+ .erase_blk_size = 0x00020000,
+ .pgs_per_blk = 64,
+ .no_of_blocks = 1024,
+ .spare_size = 64,
+ .density = 0x08000000,
+ .otp_region = 0x2000,
+ .no_of_addr_cycle = 0x3,
+ .num_bits_ecc_correctability = 4,
+ .timing_mode_support = 0,
+ .quad_mode = true,
+ .check_quad_config = true,
+ .name = "MX35UF1GE4AC",
+ },
};
struct qpic_serial_nand_params *serial_params;
#define MICRON_DEVICE_ID 0x152c152c
+#define WINBOND_DEVICE_ID 0x0021bcef
#define CMD3_MASK 0xfff0ffff
+/*
+ * An array holding the fixed pattern to compare with
+ * training pattern.
+ */
+static const unsigned int training_block_64[] = {
+ 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
+ 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
+ 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
+ 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
+};
+#define TRAINING_PART_OFFSET 0x3c00000
+#define MAXIMUM_ALLOCATED_TRAINING_BLOCK 4
+#define TOTAL_NUM_PHASE 7
#endif
struct cmd_element ce_array[100]
@@ -769,9 +879,9 @@
mtd->ecc_strength = 8;
else
mtd->ecc_strength = 4;
- printf("Serial NAND device Manufature:%s\n",serial_params->name);
- printf("Device Size:%d MiB, Page size:%d, Spare Size:%d\n",
- (int)(dev->density >> 20), dev->page_size, mtd->oobsize);
+ printf("Serial NAND device Manufacturer:%s\n",serial_params->name);
+ printf("Device Size:%d MiB, Page size:%d, Spare Size:%d, ECC:%d-bit\n",
+ (int)(dev->density >> 20), dev->page_size, mtd->oobsize, mtd->ecc_strength);
}
#endif
@@ -1008,10 +1118,9 @@
* Feature value will get updated in [15:8]
*/
nand_ret = qpic_nand_read_reg(NAND_FLASH_FEATURES, 0);
-#ifdef QPIC_DEBUG_SERIAL
- printf("NAND Feature Register Addr:0x%02x and Val:0x%08x\n",
+
+ qspi_debug("NAND Feature Register Addr:0x%02x and Val:0x%08x\n",
ftr_addr,nand_ret);
-#endif
err:
return nand_ret;
@@ -1130,6 +1239,7 @@
uint32_t status = 0x0;
struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd);
uint32_t cmd3_val = NAND_FLASH_DEV_CMD3_VAL;
+
/* For micron device the READ_CACHE_SEQ command is different than
* Giga device. for Giga 0x31 and for Micron 0x30.
* so based on id update the command configuration register
@@ -1139,6 +1249,7 @@
cmd3_val = (NAND_FLASH_DEV_CMD3_VAL & CMD3_MASK);
writel(cmd3_val, SPI_NAND_DEV_CMD3);
}
+
/* Get the block protection status*/
status = qpic_serial_get_feature(mtd, FLASH_SPI_NAND_BLK_PROCT_ADDR);
if (status < 0) {
@@ -1147,8 +1258,8 @@
}
if ((status >> 8) & FLASH_SPI_NAND_BLK_PROCT_ENABLE) {
- printf("%s: Block protection is enabled\n",__func__);
- printf("%s: Issuing set feature command to disable it.\n",__func__);
+ qspi_debug("%s: Block protection is enabled\n",__func__);
+ qspi_debug("%s: Issuing set feature command to disable it.\n",__func__);
status = qpic_serial_set_feature(mtd, FLASH_SPI_NAND_BLK_PROCT_ADDR,
FLASH_SPI_NAND_BLK_PROCT_DISABLE);
@@ -1169,9 +1280,9 @@
__func__);
return -QPIC_SERIAL_ERROR;
} else
- printf("%s : Block protection Disabled.\n",__func__);
+ qspi_debug("%s : Block protection Disabled.\n",__func__);
} else
- printf("%s: Block protection Disabled on Power on.\n",__func__);
+ qspi_debug("%s: Block protection Disabled on Power on.\n",__func__);
/* Get Internal ECC status */
status = qpic_serial_get_feature(mtd, FLASH_SPI_NAND_FR_ADDR);
@@ -1181,7 +1292,7 @@
}
if ((status >> 8) & FLASH_SPI_NAND_FR_ECC_ENABLE) {
- printf("%s : Internal ECC enabled, disabling internal ECC\n",__func__);
+ qspi_debug("%s : Internal ECC enabled, disabling internal ECC\n",__func__);
status &= ~(FLASH_SPI_NAND_FR_ECC_ENABLE);
status = qpic_serial_set_feature(mtd, FLASH_SPI_NAND_FR_ADDR,
@@ -1201,13 +1312,13 @@
}
if ((status >> 8) & FLASH_SPI_NAND_FR_ECC_ENABLE) {
- pr_info("%s: Failed to disabled device internal ECC\n",
+ printf("%s: Failed to disabled device internal ECC\n",
__func__);
return -QPIC_SERIAL_ERROR;
} else
- printf("%s : Internal ECC disabled.\n",__func__);
+ qspi_debug("%s : Internal ECC disabled.\n",__func__);
} else
- printf("%s : Internal ECC disabled on power on.\n",__func__);
+ qspi_debug("%s : Internal ECC disabled on power on.\n",__func__);
/* Enable QUAD mode if device supported. Check this condition only
* if dev->quad_mode = true , means device will support Quad mode
@@ -1230,17 +1341,17 @@
}
if (!((status >> 8) & FLASH_SPI_NAND_FR_QUAD_ENABLE)) {
- printf("%s : Quad bit not enabled.\n",__func__);
- printf("%s : Issuning set feature command to enable it.\n",
+ qspi_debug("%s : Quad bit not enabled.\n",__func__);
+ qspi_debug("%s : Issuning set feature command to enable it.\n",
__func__);
-
/* Enable quad bit */
status = qpic_serial_set_feature(mtd, FLASH_SPI_NAND_FR_ADDR,
FLASH_SPI_NAND_FR_QUAD_ENABLE);
if (status < 0) {
- printf("%s : Error in enabling Quad bit.\n",__func__);
- return status;
+ printf("%s : Error in enabling Quad bit.\n",__func__);
+ return status;
}
+
/* Read status again to know wether Quad bit enabled or not */
status = qpic_serial_get_feature(mtd, FLASH_SPI_NAND_FR_ADDR);
if (status < 0) {
@@ -1249,19 +1360,42 @@
}
if (!((status >> 8) & FLASH_SPI_NAND_FR_QUAD_ENABLE)) {
- printf("%s:Quad mode not enabled,so use x1 Mode.\n",
+ qspi_debug("%s:Quad mode not enabled,so use x1 Mode.\n",
__func__);
dev->quad_mode = false;
- return 0;
} else {
- printf("%s: Quad mode enabled. using X4 mode\n",__func__);
- return 0;
+ qspi_debug("%s: Quad mode enabled. using X4 mode\n",__func__);
}
} else {
- printf("%s: Quad mode enabled on Opwer on.\n",__func__);
- return 0;
+ qspi_debug("%s: Quad mode enabled on Opwer on.\n",__func__);
}
}
+
+ if (dev->id == WINBOND_DEVICE_ID) {
+ status = qpic_serial_get_feature(mtd, FLASH_SPI_NAND_FR_ADDR);
+ if (status < 0) {
+ printf("%s : Error in getting feature.\n",__func__);
+ return status;
+ }
+
+ if (!((status >> 8) & FLASH_SPI_NAND_FR_BUFF_ENABLE)) {
+ qspi_debug("%s :continous buffer mode disabled\n",
+ __func__);
+ qspi_debug("%s : Issuing set feature command to enable it\n",
+ __func__);
+ status = qpic_serial_set_feature(mtd, FLASH_SPI_NAND_FR_ADDR,
+ (FLASH_SPI_NAND_FR_BUFF_ENABLE | (status >> 8)));
+ if (status < 0) {
+ printf("%s : Error in disabling continous buffer bit.\n",
+ __func__);
+ return status;
+ }
+ } else {
+ qspi_debug("%s : continous buffer mode enabled on power on\n",
+ __func__);
+ }
+ }
+
return 0;
}
#endif
@@ -1404,28 +1538,71 @@
{
uint32_t xfer_start = NAND_XFR_STEPS_V1_5_20;
int i;
+ unsigned int default_clk_rate;
- /* Enabel QPIC CLK*/
- qpic_clk_enbale();
+ int num_desc = 0;
+ struct cmd_element *cmd_list_ptr = ce_array;
+ struct cmd_element *cmd_list_ptr_start = ce_array;
- /* Configure the NAND_FLASH_SPI_CFG to load the timer CLK_CNTR_INIT_VAL_VEC
- * value, enable the LOAD_CLK_CNTR_INIT_EN bit and enable SPI_CFG mode.
- */
- writel(0x0, NAND_FLASH_SPI_CFG);
+ unsigned int val;
- /* Make bit-28 of NAND_FLASH_SPI_CFG register to load
- * CLK_CNTR_INIT_VAL_VEC into IO Macro clock generation
- * registers is its not worked then,
- * check with this val 0x1DB6C00D
+ val = readl(NAND_QSPI_MSTR_CONFIG);
+
+#if defined(QSPI_IO_MACRO_DEFAULT_CLK_320MHZ) && !defined(CONFIG_QSPI_SERIAL_TRAINING)
+ default_clk_rate = IO_MACRO_CLK_320_MHZ;
+ val &= ~FB_CLK_BIT;
+#else
+ default_clk_rate = IO_MACRO_CLK_200_MHZ;
+ val |= FB_CLK_BIT;
+#endif
+ if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) {
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_QSPI_MSTR_CONFIG,
+ (uint32_t)val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)0, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)SPI_CFG_VAL, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN;
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ bam_add_one_desc(&bam,
+ CMD_PIPE_INDEX,
+ (unsigned char*)cmd_list_ptr_start,
+ ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
+ BAM_DESC_CMD_FLAG);
+ num_desc++;
+
+ /* Notify BAM HW about the newly added descriptors */
+ bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc);
+ } else {
+ writel(val, NAND_QSPI_MSTR_CONFIG);
+ writel(0x0, NAND_FLASH_SPI_CFG);
+ writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG);
+ val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN;
+ writel(val, NAND_FLASH_SPI_CFG);
+ }
+
+ num_desc = 0;
+
+ /* set the FB_CLK_BIT of register QPIC_QSPI_MSTR_CONFIG
+ * to by pass the serial training. if this FB_CLK_BIT
+ * bit enabled then , we can apply upto maximum 200MHz
+ * input to IO_MACRO_BLOCK.
*/
- writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG);
- /*Change LOAD_CLK_CNTR_INIT_EN to generate a pulse,
- * with CLK_CNTR_INIT_VAL_VEC loaded and SPI_CFG enabled
- * If not worked then,
- * Check with this val 0xDB6C00D
- */
- writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN),
- NAND_FLASH_SPI_CFG);
+ qpic_set_clk_rate(default_clk_rate, QPIC_IO_MACRO_CLK,
+ GPLL0_CLK_SRC);
+
+ /*qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK,
+ XO_CLK_SRC);*/
/* According to HPG Setting Xfer steps and spi_num_addr_cycles
* is part of initialization flow before reset.However these
@@ -1464,9 +1641,31 @@
/* No of address cycle is same for Giga device & Micron so
* configure no of address cycle now.
*/
- writel(SPI_NUM_ADDR_CYCLES, NAND_SPI_NUM_ADDR_CYCLES);
+ if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) {
+ cmd_list_ptr = ce_array;
+ bam_add_cmd_element(cmd_list_ptr, NAND_SPI_NUM_ADDR_CYCLES,
+ (uint32_t)SPI_NUM_ADDR_CYCLES, CE_WRITE_TYPE);
- writel(SPI_BUSY_CHECK_WAIT_CNT, NAND_SPI_BUSY_CHECK_WAIT_CNT);
+ cmd_list_ptr++;
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_SPI_BUSY_CHECK_WAIT_CNT,
+ (uint32_t)SPI_BUSY_CHECK_WAIT_CNT, CE_WRITE_TYPE);
+
+ cmd_list_ptr++;
+
+ bam_add_one_desc(&bam,
+ CMD_PIPE_INDEX,
+ (unsigned char*)cmd_list_ptr_start,
+ ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
+ BAM_DESC_CMD_FLAG);
+ num_desc++;
+
+ /* Notify BAM HW about the newly added descriptors */
+ bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc);
+ } else {
+ writel(SPI_NUM_ADDR_CYCLES, NAND_SPI_NUM_ADDR_CYCLES);
+ writel(SPI_BUSY_CHECK_WAIT_CNT, NAND_SPI_BUSY_CHECK_WAIT_CNT);
+ }
}
#endif
static int qpic_nand_reset(struct mtd_info *mtd)
@@ -2993,8 +3192,8 @@
}
if (uncorrectable_err_cws) {
- nand_ret = qpic_nand_check_erased_page(mtd, page, (ops_datbuf + (j * mtd->writesize)),
- ops_oobbuf + j * 64,
+ nand_ret = qpic_nand_check_erased_page(mtd, page + j, (ops_datbuf + (j * mtd->writesize)),
+ ops_oobbuf,
uncorrectable_err_cws,
&max_bitflips);
if (nand_ret < 0)
@@ -3361,7 +3560,6 @@
start_page = ((to >> chip->page_shift));
num_pages = qpic_get_read_page_count(mtd, ops, to);
-
while (1) {
if (num_pages > MAX_MULTI_PAGE) {
@@ -3758,6 +3956,7 @@
* to do it again here.
*/
cfg.addr0 = page << 16;
+ cfg.addr1 = (page >> 16) & 0xffff;
cfg.cmd = 0xA;
cfg.cmd |= (QPIC_SPI_WP_SET | QPIC_SPI_HOLD_SET |
QPIC_SPI_TRANSFER_MODE_X1);
@@ -3915,6 +4114,324 @@
chip->scan_bbt = qpic_nand_scan_bbt_nop;
}
+#ifdef CONFIG_QSPI_SERIAL_TRAINING
+static void qpic_reg_write_bam(unsigned int reg, unsigned int val)
+{
+ int num_desc = 0;
+ struct cmd_element *cmd_list_ptr = ce_array;
+ struct cmd_element *cmd_list_ptr_start = ce_array;
+
+ bam_add_cmd_element(cmd_list_ptr, reg,
+ (uint32_t)val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ bam_add_one_desc(&bam,
+ CMD_PIPE_INDEX,
+ (unsigned char*)cmd_list_ptr_start,
+ ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
+ BAM_DESC_CMD_FLAG);
+ num_desc++;
+
+ /* Notify BAM HW about the newly added descriptors */
+ bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc);
+}
+static void qpic_set_phase(int phase)
+{
+ int spi_flash_cfg_val = 0x0;
+
+ int num_desc = 0;
+ struct cmd_element *cmd_list_ptr = ce_array;
+ struct cmd_element *cmd_list_ptr_start = ce_array;
+
+ if (phase < 1 || phase > 7) {
+ printf("%s : wrong phase value\n", __func__);
+ return;
+ }
+ /* get the current value of NAND_FLASH_SPI_CFG register */
+ spi_flash_cfg_val = readl(NAND_FLASH_SPI_CFG);
+ /* set SPI_LOAD_CLK_CNTR_INIT_EN bit */
+ spi_flash_cfg_val |= SPI_LOAD_CLK_CNTR_INIT_EN;
+
+ if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) {
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ spi_flash_cfg_val &= 0xf000ffff;
+ /* write the phase value for all the line */
+ spi_flash_cfg_val |= ((phase << 16) | (phase << 19) |
+ (phase << 22) | (phase << 25));
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+ /* clear the SPI_LOAD_CLK_CNTR_INIT_EN bit to load the required
+ * phase value
+ */
+ spi_flash_cfg_val &= ~SPI_LOAD_CLK_CNTR_INIT_EN;
+
+ bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG,
+ (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE);
+ cmd_list_ptr++;
+
+ bam_add_one_desc(&bam,
+ CMD_PIPE_INDEX,
+ (unsigned char*)cmd_list_ptr_start,
+ ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
+ BAM_DESC_CMD_FLAG);
+ num_desc++;
+
+ /* Notify BAM HW about the newly added descriptors */
+ bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc);
+ } else {
+ writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG);
+
+ spi_flash_cfg_val &= 0xf000ffff;
+ /* write the phase value for all the line */
+ spi_flash_cfg_val |= ((phase << 16) | (phase << 19) |
+ (phase << 22) | (phase << 25));
+ writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG);
+
+ /* clear the SPI_LOAD_CLK_CNTR_INIT_EN bit to load the required
+ * phase value
+ */
+ spi_flash_cfg_val &= ~SPI_LOAD_CLK_CNTR_INIT_EN;
+ writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG);
+ }
+}
+
+static bool IsEven(int num)
+{
+ return (!(num & 1));
+}
+
+static int qpic_find_most_appropriate_phase(u8 *phase_table, int phase_count)
+{
+ int cnt = 0, i;
+ int phase = 0x0;
+ u8 phase_ranges[TOTAL_NUM_PHASE] = {'\0'};
+
+ /*currently we are considering continious 3 phase will
+ * pass and tke the middle one out of passed three phase.
+ * if all 7 phase passed so return middle phase i.e 4
+ */
+ phase_count -= 2;
+ for (i = 0; i < phase_count; i++) {
+ if ((phase_table[i] + 1 == phase_table[i + 1]) &&
+ (phase_table[i + 1] + 1 == phase_table[i + 2])) {
+ phase_ranges[cnt++] = phase_table[i + 1];
+ }
+ }
+
+ /* filter out middle phase
+ * if cnt is odd then one middle phase
+ * if cnt is even then two middile phase
+ * so select lower one
+ */
+ if (IsEven(cnt)) {
+ phase = phase_ranges[cnt/2 - 1];
+ } else {
+ phase = phase_ranges[cnt/2];
+ }
+
+ return phase;
+}
+
+static int qpic_execute_serial_training(struct mtd_info *mtd)
+{
+ struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd);
+ struct nand_chip *chip = MTD_NAND_CHIP(mtd);
+
+ unsigned int start, blk_cnt = 0;
+ unsigned int offset, pageno, curr_freq;
+ int i;
+ unsigned int io_macro_freq_tbl[] = {24000000, 100000000, 200000000, 320000000};
+
+ unsigned char *data_buff, trained_phase[TOTAL_NUM_PHASE] = {'\0'};
+ int phase, phase_cnt, clk_src;
+ int training_seq_cnt = 4;
+ int index = 3, ret, phase_failed=0;
+ u32 start_blocks;
+ u32 size_blocks;
+ loff_t training_offset;
+
+ ret = smem_getpart("0:TRAINING", &start_blocks, &size_blocks);
+ if (ret < 0) {
+ printf("Serial Training part offset not found.\n");
+ return -EIO;
+ }
+
+ training_offset = ((loff_t) mtd->erasesize * start_blocks);
+
+ start = (training_offset >> chip->phys_erase_shift);
+ offset = (start << chip->phys_erase_shift);
+ pageno = (offset >> chip->page_shift);
+
+ clk_src = GPLL0_CLK_SRC;
+ /* At 50Mhz frequency check the bad blocks, if training
+ * blocks is not bad then only start training else operate
+ * at 50Mhz with bypassing software serial traning.
+ */
+ while (qpic_nand_block_isbad(mtd, offset)) {
+ /* block is bad skip this block and goto next
+ * block
+ */
+ training_offset += mtd->erasesize;
+ start = (training_offset >> chip->phys_erase_shift);
+ offset = (start << chip->phys_erase_shift);
+ pageno = (offset >> chip->page_shift);
+ blk_cnt++;
+ if (blk_cnt == MAXIMUM_ALLOCATED_TRAINING_BLOCK)
+ break;
+ }
+
+ if (blk_cnt == MAXIMUM_ALLOCATED_TRAINING_BLOCK) {
+ printf("All training blocks are bad skipping serial training\n");
+ ret = -EIO;
+ goto err;
+ }
+
+ ret = qpic_nand_blk_erase(mtd, pageno);
+ if (ret) {
+ printf("error in erasing training block @%x\n",offset);
+ ret = -EIO;
+ goto err;
+ }
+
+ data_buff = (unsigned char *)malloc(mtd->writesize);
+ if (!data_buff) {
+ printf("Errorn in allocating memory.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+ /* prepare clean buffer */
+ memset(data_buff, 0xff, mtd->writesize);
+ for (i = 0; i < mtd->writesize; i += sizeof(training_block_64))
+ memcpy(data_buff + i, training_block_64, sizeof(training_block_64));
+
+ /*write training data to flash */
+ ret = NANDC_RESULT_SUCCESS;
+ struct mtd_oob_ops ops;
+
+ /* write this dumy byte in spare area to avoid bam
+ * transaction error while writing.
+ */
+ memset(dev->pad_oob, 0xFF, dev->oob_per_page);
+
+ ops.mode = MTD_OPS_AUTO_OOB;
+ ops.len = mtd->writesize;
+ ops.retlen = 0;
+ ops.ooblen = dev->oob_per_page;
+ ops.oobretlen = 0;
+ ops.ooboffs = 0;
+ ops.datbuf = (uint8_t *)data_buff;
+ ops.oobbuf = (uint8_t *)dev->pad_oob;
+
+ /* write should be only once */
+ ret = qpic_nand_write_page(mtd, pageno, NAND_CFG, &ops);
+ if (ret) {
+ printf("Error in writing training data..\n");
+ goto free;
+ }
+ /* After write verify the the data with read @ lower frequency
+ * after that only start serial tarining @ higher frequency
+ */
+ memset(data_buff, 0xff, mtd->writesize);
+ ops.datbuf = (uint8_t *)data_buff;
+
+ ret = qpic_nand_read_page(mtd, pageno, NAND_CFG, &ops);
+ if (ret) {
+ printf("%s : Read training data failed before training start\n",__func__);
+ goto free;
+ }
+
+ /* compare original data and read data */
+ for (i = 0; i < mtd->writesize; i += sizeof(training_block_64)) {
+ if (memcmp(data_buff + i, training_block_64, sizeof(training_block_64))) {
+ printf("Training data read failed @ lower frequency\n");
+ goto free;
+ }
+ }
+
+ /* disable feed back clock bit to start serial training */
+ qpic_reg_write_bam(NAND_QSPI_MSTR_CONFIG,
+ (~FB_CLK_BIT & readl(NAND_QSPI_MSTR_CONFIG)));
+
+ /* start serial training here */
+ curr_freq = io_macro_freq_tbl[index];
+rettry:
+ phase = 1;
+ phase_cnt = 0;
+
+ /* set frequency, start from higer frequency */
+ if (curr_freq == IO_MACRO_CLK_24MHZ)
+ clk_src = XO_CLK_SRC;
+ qpic_set_clk_rate(curr_freq, QPIC_IO_MACRO_CLK, clk_src);
+
+ do {
+ /* set the phase */
+ qpic_set_phase(phase);
+
+ memset(data_buff, 0, mtd->writesize);
+ ops.datbuf = (uint8_t *)data_buff;
+
+ ret = qpic_nand_read_page(mtd, pageno, NAND_CFG, &ops);
+ if (ret) {
+ printf("%s : Read training data failed.\n",__func__);
+ goto free;
+ }
+ /* compare original data and read data */
+ for (i = 0; i < mtd->writesize; i += sizeof(training_block_64)) {
+ if (memcmp(data_buff + i, training_block_64, sizeof(training_block_64))) {
+ phase_failed++;
+ break;
+ }
+ }
+ if (i == mtd->writesize)
+ trained_phase[phase_cnt++] = phase;
+ /*printf("%s : Found good phase %d\n",__func__,phase);*/
+
+ } while (phase++ < TOTAL_NUM_PHASE);
+
+ if (phase_cnt) {
+ /* Get the appropriate phase */
+ phase = qpic_find_most_appropriate_phase(trained_phase, phase_cnt);
+ qpic_set_phase(phase);
+
+ /* update freq & phase to patch to the kernel */
+ qpic_frequency = curr_freq;
+ qpic_phase = phase;
+ } else {
+ /* lower the the clock frequency
+ * and try again
+ */
+ curr_freq = io_macro_freq_tbl[--index];
+ printf("Retry with lower frequency @:%d\n",curr_freq);
+ if (--training_seq_cnt)
+ goto rettry;
+
+ /* Training failed */
+ printf("%s : Serial training failed\n",__func__);
+ ret = -EIO;
+ goto free;
+ }
+
+ /* if phase_failed == 7 it means serial traing failed
+ * on all the phase. so now we have to go via line by line
+ * i.e first check for MISO_0, with all the phase value i.e
+ * 1-7 and then MISO_1 and so on.
+ * NOTE: But this is the worse case , and it this type of senario
+ * will not come. if it will come then go with this design.
+ * ======To DO=====
+ */
+free:
+ free(data_buff);
+err:
+ return ret;
+}
+#endif
+
static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg)
@@ -3971,27 +4488,10 @@
return;
}
-#ifdef CONFIG_QPIC_SERIAL
-
- qpic_spi_init(mtd);
-
- /* Read the Hardware Version register */
- hw_ver = readl(NAND_VERSION);
- /* Only maintain major number */
- hw_ver >>= 28;
- if (hw_ver >= QCA_QPIC_V2_1_1) {
- printf("QPIC controller support serial NAND\n");
- } else {
- printf("%s : Qpic controller not support serial NAND\n",
- __func__);
- return;
- }
-
#ifdef CONFIG_PAGE_SCOPE_MULTI_PAGE_READ
config.pipes.status_pipe = NAND_BAM_STATUS_PIPE;
config.pipes.status_pipe_grp = NAND_BAM_STATUS_PIPE_GRP;
#endif
-#endif
config.pipes.read_pipe = DATA_PRODUCER_PIPE;
config.pipes.write_pipe = DATA_CONSUMER_PIPE;
config.pipes.cmd_pipe = CMD_PIPE;
@@ -4007,6 +4507,21 @@
qpic_bam_init(&config);
+#ifdef CONFIG_QPIC_SERIAL
+ qpic_spi_init(mtd);
+
+ /* Read the Hardware Version register */
+ hw_ver = readl(NAND_VERSION);
+ /* Only maintain major number */
+ hw_ver >>= 28;
+ if (hw_ver >= QCA_QPIC_V2_1_1) {
+ printf("QPIC controller support serial NAND\n");
+ } else {
+ printf("%s : Qpic controller not support serial NAND\n",
+ __func__);
+ return;
+ }
+#endif
ret = qpic_nand_reset(mtd);
if (ret < 0)
return;
@@ -4103,6 +4618,36 @@
dev->tmp_oobbuf = buf;
buf += mtd->oobsize;
+#ifdef CONFIG_QSPI_SERIAL_TRAINING
+ /* start serial training here */
+ ret = qpic_execute_serial_training(mtd);
+ if (ret) {
+ printf("Error in serial training.\n");
+ printf("switch back to 50MHz with feed back clock bit enabled\n");
+ if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) {
+ qpic_reg_write_bam(NAND_QSPI_MSTR_CONFIG,
+ (FB_CLK_BIT | readl(NAND_QSPI_MSTR_CONFIG)));
+ qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK,
+ GPLL0_CLK_SRC);
+ qpic_reg_write_bam(NAND_FLASH_SPI_CFG, 0x0);
+ qpic_reg_write_bam(NAND_FLASH_SPI_CFG, SPI_CFG_VAL);
+ qpic_reg_write_bam(NAND_FLASH_SPI_CFG,
+ (SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN));
+
+ } else {
+ writel((FB_CLK_BIT | readl(NAND_QSPI_MSTR_CONFIG)),
+ NAND_QSPI_MSTR_CONFIG);
+
+ qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK,
+ GPLL0_CLK_SRC);
+
+ writel(0x0, NAND_FLASH_SPI_CFG);
+ writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG);
+ writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN),
+ NAND_FLASH_SPI_CFG);
+ }
+ }
+#endif
/* Register with MTD subsystem. */
ret = nand_register(CONFIG_QPIC_NAND_NAND_INFO_IDX);
if (ret < 0) {
diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
index 4608cba..d35aed2 100644
--- a/drivers/mtd/spi/sf_params.c
+++ b/drivers/mtd/spi/sf_params.c
@@ -37,6 +37,8 @@
{"GD25LQ32", 0xc86016, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K},
{"GD25Q128", 0xc84018, 0x0, 64 * 1024, 256, RD_NORM, SECT_4K},
{"GD25Q256", 0xc84019, 0x0, 64 * 1024, 512, RD_NORM, SECT_4K},
+ {"GD25LB128D", 0xc86018, 0x0, 4 * 1024, 4096, RD_NORM, SECT_4K},
+ {"GD25LB256E", 0xc86719, 0x0, 4 * 1024, 8192, RD_NORM, SECT_4K},
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
{"IS25LP032", 0x9d6016, 0x0, 64 * 1024, 64, RD_NORM, 0},
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3270843..ee3de33 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -87,7 +87,11 @@
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_ppe.o
obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_uniphy.o
obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_gmac.o
+obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_uniphy.o
+obj-$(CONFIG_IPQ5018_MDIO) += ipq5018/ipq5018_mdio.o
+obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/athrs17_phy.o
obj-$(CONFIG_IPQ_MDIO) += ipq_common/ipq_mdio.o
+obj-$(CONFIG_GEPHY) += ipq_common/ipq_gephy.o
obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o
obj-$(CONFIG_QCA8033_PHY) += ipq_common/ipq_qca8033.o
obj-$(CONFIG_QCA8081_PHY) += ipq_common/ipq_qca8081.o
diff --git a/drivers/net/ipq5018/athrs17_phy.c b/drivers/net/ipq5018/athrs17_phy.c
new file mode 100644
index 0000000..dbc514f
--- /dev/null
+++ b/drivers/net/ipq5018/athrs17_phy.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Manage the atheros ethernet PHY.
+ *
+ * All definitions in this file are operating system independent!
+ */
+
+#include <common.h>
+#include <asm/arch-ipq5018/athrs17_phy.h>
+
+/*
+ * Externel Common mdio read, PHY Name : IPQ MDIO1
+ */
+
+extern int ipq_mdio_write(int mii_id,
+ int regnum, u16 value);
+extern int ipq_mdio_read(int mii_id,
+ int regnum, ushort *data);
+
+/******************************************************************************
+ * FUNCTION DESCRIPTION: Read switch internal register.
+ * Switch internal register is accessed through the
+ * MDIO interface. MDIO access is only 16 bits wide so
+ * it needs the two time access to complete the internal
+ * register access.
+ * INPUT : register address
+ * OUTPUT : Register value
+ *
+ *****************************************************************************/
+static uint32_t
+athrs17_reg_read(uint32_t reg_addr)
+{
+ uint32_t reg_word_addr;
+ uint32_t phy_addr, reg_val;
+ uint16_t phy_val;
+ uint16_t tmp_val;
+ uint8_t phy_reg;
+
+ /* change reg_addr to 16-bit word address, 32-bit aligned */
+ reg_word_addr = (reg_addr & 0xfffffffc) >> 1;
+
+ /* configure register high address */
+ phy_addr = 0x18;
+ phy_reg = 0x0;
+ phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */
+ ipq_mdio_write(phy_addr, phy_reg, phy_val);
+ /*
+ * For some registers such as MIBs, since it is read/clear, we should
+ * read the lower 16-bit register then the higher one
+ */
+
+ /* read register in lower address */
+ phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
+ phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
+ ipq_mdio_read(phy_addr, phy_reg, &phy_val);
+
+ /* read register in higher address */
+ reg_word_addr++;
+ phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
+ phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
+ ipq_mdio_read(phy_addr, phy_reg, &tmp_val);
+ reg_val = (tmp_val << 16 | phy_val);
+
+ return reg_val;
+}
+
+/******************************************************************************
+ * FUNCTION DESCRIPTION: Write switch internal register.
+ * Switch internal register is accessed through the
+ * MDIO interface. MDIO access is only 16 bits wide so
+ * it needs the two time access to complete the internal
+ * register access.
+ * INPUT : register address, value to be written
+ * OUTPUT : NONE
+ *
+ *****************************************************************************/
+static void
+athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val)
+{
+ uint32_t reg_word_addr;
+ uint32_t phy_addr;
+ uint16_t phy_val;
+ uint8_t phy_reg;
+
+ /* change reg_addr to 16-bit word address, 32-bit aligned */
+ reg_word_addr = (reg_addr & 0xfffffffc) >> 1;
+
+ /* configure register high address */
+ phy_addr = 0x18;
+ phy_reg = 0x0;
+ phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */
+ ipq_mdio_write(phy_addr, phy_reg, phy_val);
+
+ /*
+ * For some registers such as ARL and VLAN, since they include BUSY bit
+ * in lower address, we should write the higher 16-bit register then the
+ * lower one
+ */
+
+ /* read register in higher address */
+ reg_word_addr++;
+ phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
+ phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
+ phy_val = (uint16_t) ((reg_val >> 16) & 0xffff);
+ ipq_mdio_write(phy_addr, phy_reg, phy_val);
+
+ /* write register in lower address */
+ reg_word_addr--;
+ phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */
+ phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */
+ phy_val = (uint16_t) (reg_val & 0xffff);
+ ipq_mdio_write(phy_addr, phy_reg, phy_val);
+}
+
+/*********************************************************************
+ * FUNCTION DESCRIPTION: V-lan configuration given by Switch team
+ Vlan 1:PHY0,1,2,3 and Mac 6 of s17c
+ Vlan 2:PHY4 and Mac 0 of s17c
+ * INPUT : NONE
+ * OUTPUT: NONE
+ *********************************************************************/
+void athrs17_vlan_config(void)
+{
+ athrs17_reg_write(S17_P0LOOKUP_CTRL_REG, 0x00140020);
+ athrs17_reg_write(S17_P0VLAN_CTRL0_REG, 0x20001);
+
+ athrs17_reg_write(S17_P1LOOKUP_CTRL_REG, 0x0014005c);
+ athrs17_reg_write(S17_P1VLAN_CTRL0_REG, 0x10001);
+
+ athrs17_reg_write(S17_P2LOOKUP_CTRL_REG, 0x0014005a);
+ athrs17_reg_write(S17_P2VLAN_CTRL0_REG, 0x10001);
+
+ athrs17_reg_write(S17_P3LOOKUP_CTRL_REG, 0x00140056);
+ athrs17_reg_write(S17_P3VLAN_CTRL0_REG, 0x10001);
+
+ athrs17_reg_write(S17_P4LOOKUP_CTRL_REG, 0x0014004e);
+ athrs17_reg_write(S17_P4VLAN_CTRL0_REG, 0x10001);
+
+ athrs17_reg_write(S17_P5LOOKUP_CTRL_REG, 0x00140001);
+ athrs17_reg_write(S17_P5VLAN_CTRL0_REG, 0x20001);
+
+ athrs17_reg_write(S17_P6LOOKUP_CTRL_REG, 0x0014001e);
+ athrs17_reg_write(S17_P6VLAN_CTRL0_REG, 0x10001);
+ printf("%s ...done\n", __func__);
+}
+
+/*******************************************************************
+* FUNCTION DESCRIPTION: Reset S17 register
+* INPUT: NONE
+* OUTPUT: NONE
+*******************************************************************/
+int athrs17_init_switch(void)
+{
+ uint32_t data;
+ uint32_t i = 0;
+
+ /* Reset the switch before initialization */
+ athrs17_reg_write(S17_MASK_CTRL_REG, S17_MASK_CTRL_SOFT_RET);
+ do {
+ udelay(10);
+ data = athrs17_reg_read(S17_MASK_CTRL_REG);
+ i++;
+ if (i == 10){
+ printf("QCA_8337: Failed to reset\n");
+ return -1;
+ }
+ } while (data & S17_MASK_CTRL_SOFT_RET);
+
+ i = 0;
+
+ do {
+ udelay(10);
+ data = athrs17_reg_read(S17_GLOBAL_INT0_REG);
+ i++;
+ if (i == 10)
+ return -1;
+ } while ((data & S17_GLOBAL_INITIALIZED_STATUS) != S17_GLOBAL_INITIALIZED_STATUS);
+
+ return 0;
+}
+
+/*********************************************************************
+ * FUNCTION DESCRIPTION: Configure S17 register
+ * INPUT : NONE
+ * OUTPUT: NONE
+ *********************************************************************/
+void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ athrs17_reg_write(S17_MAC_PWR_REG, gmac_cfg->mac_pwr);
+
+ athrs17_reg_write(S17_P0STATUS_REG, (S17_SPEED_1000M |
+ S17_TXMAC_EN |
+ S17_RXMAC_EN |
+ S17_DUPLEX_FULL));
+
+ athrs17_reg_write(S17_GLOFW_CTRL1_REG, (S17_IGMP_JOIN_LEAVE_DPALL |
+ S17_BROAD_DPALL |
+ S17_MULTI_FLOOD_DPALL |
+ S17_UNI_FLOOD_DPALL));
+
+ athrs17_reg_write(S17_P5PAD_MODE_REG, S17_MAC0_RGMII_RXCLK_DELAY);
+
+ athrs17_reg_write(S17_P0PAD_MODE_REG, (S17_MAC0_RGMII_EN |
+ S17_MAC0_RGMII_TXCLK_DELAY |
+ S17_MAC0_RGMII_RXCLK_DELAY |
+ (0x1 << S17_MAC0_RGMII_TXCLK_SHIFT) |
+ (0x2 << S17_MAC0_RGMII_RXCLK_SHIFT)));
+
+ printf("%s: complete\n", __func__);
+}
+
+/*********************************************************************
+ * FUNCTION DESCRIPTION: Configure S17 register
+ * INPUT : NONE
+ * OUTPUT: NONE
+ *********************************************************************/
+void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ uint32_t reg_val;
+
+ athrs17_reg_write(S17_P6STATUS_REG, (S17_SPEED_1000M |
+ S17_TXMAC_EN |
+ S17_RXMAC_EN |
+ S17_DUPLEX_FULL));
+
+ athrs17_reg_write(S17_MAC_PWR_REG, gmac_cfg->mac_pwr);
+ reg_val = athrs17_reg_read(S17_P6PAD_MODE_REG);
+ athrs17_reg_write(S17_P6PAD_MODE_REG, (reg_val | S17_MAC6_SGMII_EN));
+
+ athrs17_reg_write(S17_PWS_REG, 0x2613a0);
+
+ athrs17_reg_write(S17_SGMII_CTRL_REG,(S17c_SGMII_EN_PLL |
+ S17c_SGMII_EN_RX |
+ S17c_SGMII_EN_TX |
+ S17c_SGMII_EN_SD |
+ S17c_SGMII_BW_HIGH |
+ S17c_SGMII_SEL_CLK125M |
+ S17c_SGMII_TXDR_CTRL_600mV |
+ S17c_SGMII_CDR_BW_8 |
+ S17c_SGMII_DIS_AUTO_LPI_25M |
+ S17c_SGMII_MODE_CTRL_SGMII_PHY |
+ S17c_SGMII_PAUSE_SG_TX_EN_25M |
+ S17c_SGMII_ASYM_PAUSE_25M |
+ S17c_SGMII_PAUSE_25M |
+ S17c_SGMII_HALF_DUPLEX_25M |
+ S17c_SGMII_FULL_DUPLEX_25M));
+
+ athrs17_reg_write(S17_MODULE_EN_REG, S17_MIB_COUNTER_ENABLE);
+}
+
+struct athrs17_regmap {
+ uint32_t start;
+ uint32_t end;
+};
+
+struct athrs17_regmap regmap[] = {
+ { 0x000, 0x0e4 },
+ { 0x100, 0x168 },
+ { 0x200, 0x270 },
+ { 0x400, 0x454 },
+ { 0x600, 0x718 },
+ { 0x800, 0xb70 },
+ { 0xC00, 0xC80 },
+ { 0x1100, 0x11a7 },
+ { 0x1200, 0x12a7 },
+ { 0x1300, 0x13a7 },
+ { 0x1400, 0x14a7 },
+ { 0x1600, 0x16a7 },
+};
+
+int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(regmap); i++) {
+ uint32_t reg;
+ struct athrs17_regmap *section = ®map[i];
+
+ for (reg = section->start; reg <= section->end; reg += sizeof(uint32_t)) {
+ uint32_t val = athrs17_reg_read(reg);
+ printf("%03zx: %08zx\n", reg, val);
+ }
+ }
+
+ return 0;
+};
+U_BOOT_CMD(
+ ar8xxx_dump, 1, 1, do_ar8xxx_dump,
+ "Dump ar8xxx registers",
+ "\n - print all ar8xxx registers\n"
+);
+
+/*********************************************************************
+ *
+ * FUNCTION DESCRIPTION: This function invokes RGMII,
+ * SGMII switch init routines.
+ * INPUT : ipq_gmac_board_cfg_t *
+ * OUTPUT: NONE
+ *
+**********************************************************************/
+int ipq_athrs17_init(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ int ret;
+
+ if (gmac_cfg == NULL)
+ return -1;
+
+ ret = athrs17_init_switch();
+ if (ret != -1) {
+ athrs17_reg_init(gmac_cfg);
+ athrs17_reg_init_lan(gmac_cfg);
+ athrs17_vlan_config();
+ printf ("S17c init done\n");
+ }
+
+ return ret;
+}
diff --git a/drivers/net/ipq5018/ipq5018_gmac.c b/drivers/net/ipq5018/ipq5018_gmac.c
new file mode 100644
index 0000000..76f552d
--- /dev/null
+++ b/drivers/net/ipq5018/ipq5018_gmac.c
@@ -0,0 +1,870 @@
+/*
+* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#include <common.h>
+#include <net.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <phy.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include "ipq_phy.h"
+#include <asm/arch-ipq5018/ipq5018_gmac.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ipq_info printf
+#define ipq_dbg printf
+#define DESC_SIZE (sizeof(ipq_gmac_desc_t))
+#define DESC_FLUSH_SIZE (((DESC_SIZE + (CONFIG_SYS_CACHELINE_SIZE - 1)) \
+ / CONFIG_SYS_CACHELINE_SIZE) * \
+ (CONFIG_SYS_CACHELINE_SIZE))
+
+static struct ipq_eth_dev *ipq_gmac_macs[IPQ5018_GMAC_PORT];
+
+uchar ipq_def_enetaddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
+phy_info_t *phy_info[IPQ5018_PHY_MAX] = {0};
+
+extern int ipq_mdio_read(int mii_id, int regnum, ushort *data);
+extern int ipq_mdio_write(int mii_id, int regnum, u16 value);
+extern int ipq5018_mdio_write(int mii_id, int regnum, u16 value);
+extern int ipq5018_mdio_read(int mii_id, int regnum, ushort *data);
+extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
+extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id);
+extern int ipq_gephy_phy_init(struct phy_ops **ops, u32 phy_id);
+extern int ipq_sw_mdio_init(const char *);
+extern int ipq5018_sw_mdio_init(const char *);
+extern void ppe_uniphy_mode_set(uint32_t mode);
+extern int ipq_athrs17_init(ipq_gmac_board_cfg_t *gmac_cfg);
+
+static int ipq_eth_wr_macaddr(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = (struct eth_mac_regs *)priv->mac_regs_p;
+ u32 macid_lo, macid_hi;
+ u8 *mac_id = &dev->enetaddr[0];
+
+ macid_lo = mac_id[0] + (mac_id[1] << 8) +
+ (mac_id[2] << 16) + (mac_id[3] << 24);
+ macid_hi = mac_id[4] + (mac_id[5] << 8);
+
+ writel(macid_hi, &mac_p->macaddr0hi);
+ writel(macid_lo, &mac_p->macaddr0lo);
+
+ return 0;
+}
+
+static void ipq_mac_reset(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
+ u32 val;
+
+ writel(DMAMAC_SRST, &dma_reg->busmode);
+ do {
+ udelay(10);
+ val = readl(&dma_reg->busmode);
+ } while (val & DMAMAC_SRST);
+
+}
+
+static void ipq_eth_mac_cfg(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_reg = (struct eth_mac_regs *)priv->mac_regs_p;
+ uint speed = 0;
+ uint ipq_mac_cfg = 0;
+ uint ipq_mac_framefilter = 0;
+
+ ipq_mac_framefilter = PROMISCUOUS_MODE_ON;
+
+ if (priv->mac_unit) {
+ if (priv->phy_type == QCA8081_1_1_PHY || priv->phy_type == QCA8033_PHY)
+ speed = priv->speed;
+
+ ipq_mac_cfg |= (FRAME_BURST_ENABLE | JUMBO_FRAME_ENABLE | JABBER_DISABLE |
+ TX_ENABLE | RX_ENABLE | FULL_DUPLEX_ENABLE | speed);
+
+ writel(ipq_mac_cfg, &mac_reg->conf);
+ } else {
+ ipq_mac_cfg |= (priv->speed | FULL_DUPLEX_ENABLE | FRAME_BURST_ENABLE |
+ TX_ENABLE | RX_ENABLE);
+ writel(ipq_mac_cfg, &mac_reg->conf);
+ }
+
+ writel(ipq_mac_framefilter, &mac_reg->framefilt);
+
+}
+
+static void ipq_eth_dma_cfg(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
+ uint ipq_dma_bus_mode;
+ uint ipq_dma_op_mode;
+
+ ipq_dma_op_mode = DmaStoreAndForward | DmaRxThreshCtrl128 |
+ DmaTxSecondFrame;
+ ipq_dma_bus_mode = DmaFixedBurstEnable | DmaBurstLength16 |
+ DmaDescriptorSkip0 | DmaDescriptor8Words |
+ DmaArbitPr;
+
+ writel(ipq_dma_bus_mode, &dma_reg->busmode);
+ writel(ipq_dma_op_mode, &dma_reg->opmode);
+}
+
+static void ipq_eth_flw_cntl_cfg(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_reg = (struct eth_mac_regs *)priv->mac_regs_p;
+ struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
+ uint ipq_dma_flw_cntl;
+ uint ipq_mac_flw_cntl;
+
+ ipq_dma_flw_cntl = DmaRxFlowCtrlAct3K | DmaRxFlowCtrlDeact4K |
+ DmaEnHwFlowCtrl;
+ ipq_mac_flw_cntl = GmacRxFlowControl | GmacTxFlowControl | 0xFFFF0000;
+
+ setbits_le32(&dma_reg->opmode, ipq_dma_flw_cntl);
+ setbits_le32(&mac_reg->flowcontrol, ipq_mac_flw_cntl);
+}
+
+static int ipq_gmac_alloc_fifo(int ndesc, ipq_gmac_desc_t **fifo)
+{
+ int i;
+ void *addr;
+
+ addr = memalign((CONFIG_SYS_CACHELINE_SIZE),
+ (ndesc * DESC_FLUSH_SIZE));
+
+ for (i = 0; i < ndesc; i++) {
+ fifo[i] = (ipq_gmac_desc_t *)((unsigned long)addr +
+ (i * DESC_FLUSH_SIZE));
+ if (fifo[i] == NULL) {
+ ipq_info("Can't allocate desc fifos\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int ipq_gmac_rx_desc_setup(struct ipq_eth_dev *priv)
+{
+ struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
+ ipq_gmac_desc_t *rxdesc;
+ int i;
+
+ for (i = 0; i < NO_OF_RX_DESC; i++) {
+ rxdesc = priv->desc_rx[i];
+ rxdesc->length |= ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
+ DescSize1Mask);
+ rxdesc->buffer1 = virt_to_phys(net_rx_packets[i]);
+ rxdesc->data1 = (unsigned long)priv->desc_rx[(i + 1) %
+ NO_OF_RX_DESC];
+
+ rxdesc->extstatus = 0;
+ rxdesc->reserved1 = 0;
+ rxdesc->timestamplow = 0;
+ rxdesc->timestamphigh = 0;
+ rxdesc->status = DescOwnByDma;
+
+
+ flush_dcache_range((unsigned long)rxdesc,
+ (unsigned long)rxdesc + DESC_SIZE);
+
+ }
+ /* Assign Descriptor base address to dmadesclist addr reg */
+ writel((uint)priv->desc_rx[0], &dma_reg->rxdesclistaddr);
+
+ return 0;
+}
+
+static int ipq_gmac_tx_rx_desc_ring(struct ipq_eth_dev *priv)
+{
+ int i;
+ ipq_gmac_desc_t *desc;
+
+ if (ipq_gmac_alloc_fifo(NO_OF_TX_DESC, priv->desc_tx))
+ return -1;
+
+ for (i = 0; i < NO_OF_TX_DESC; i++) {
+ desc = priv->desc_tx[i];
+ memset(desc, 0, DESC_SIZE);
+
+ desc->status =
+ (i == (NO_OF_TX_DESC - 1)) ? TxDescEndOfRing : 0;
+
+ desc->status |= TxDescChain;
+
+ desc->data1 = (unsigned long)priv->desc_tx[(i + 1) %
+ NO_OF_TX_DESC ];
+
+ flush_dcache_range((unsigned long)desc,
+ (unsigned long)desc + DESC_SIZE);
+
+ }
+
+ if (ipq_gmac_alloc_fifo(NO_OF_RX_DESC, priv->desc_rx))
+ return -1;
+
+ for (i = 0; i < NO_OF_RX_DESC; i++) {
+ desc = priv->desc_rx[i];
+ memset(desc, 0, DESC_SIZE);
+ desc->length =
+ (i == (NO_OF_RX_DESC - 1)) ? RxDescEndOfRing : 0;
+ desc->length |= RxDescChain;
+
+ desc->data1 = (unsigned long)priv->desc_rx[(i + 1) %
+ NO_OF_RX_DESC];
+
+ flush_dcache_range((unsigned long)desc,
+ (unsigned long)desc + DESC_SIZE);
+
+ }
+
+ priv->next_tx = 0;
+ priv->next_rx = 0;
+
+ return 0;
+}
+
+static inline void ipq_gmac_give_to_dma(ipq_gmac_desc_t *fr)
+{
+ fr->status |= DescOwnByDma;
+}
+
+static inline u32 ipq_gmac_owned_by_dma(ipq_gmac_desc_t *fr)
+{
+ return (fr->status & DescOwnByDma);
+}
+
+static inline u32 ipq_gmac_is_desc_empty(ipq_gmac_desc_t *fr)
+{
+ return ((fr->length & DescSize1Mask) == 0);
+}
+
+static void ipq5018_gmac0_speed_clock_set(int speed_clock1,
+ int speed_clock2, int gmacid)
+{
+ int iTxRx;
+ uint32_t reg_value;
+ /*
+ * iTxRx indicates Tx and RX register
+ * 0 = Rx and 1 = Tx
+ */
+ for (iTxRx = 0; iTxRx < 2; ++iTxRx){
+ /* gcc port first clock divider */
+ reg_value = 0;
+ reg_value = readl(GCC_GMAC0_RX_CFG_RCGR +
+ (iTxRx * 8) + (gmacid * 0x10));
+ reg_value &= ~0x1f;
+ reg_value |= speed_clock1;
+ writel(reg_value, GCC_GMAC0_RX_CFG_RCGR +
+ (iTxRx * 8) + (gmacid * 0x10));
+ /* gcc port second clock divider */
+ reg_value = 0;
+ reg_value = readl(GCC_GMAC0_RX_MISC +
+ (iTxRx * 4) + (gmacid * 0x10));
+ reg_value &= ~0xf;
+ reg_value |= speed_clock2;
+ writel(reg_value, GCC_GMAC0_RX_MISC +
+ (iTxRx * 4) + (gmacid * 0x10));
+ /* update above clock configuration */
+ reg_value = 0;
+ reg_value = readl(GCC_GMAC0_RX_CMD_RCGR +
+ (iTxRx * 8) + (gmacid * 0x10));
+ reg_value &= ~0x1;
+ reg_value |= 0x1;
+ writel(reg_value, GCC_GMAC0_RX_CMD_RCGR +
+ (iTxRx * 8) + (gmacid * 0x10));
+ }
+}
+
+static void ipq5018_enable_gephy(void)
+{
+ uint32_t reg_val;
+
+ reg_val = readl(GCC_GEPHY_RX_CBCR);
+ reg_val |= GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GEPHY_RX_CBCR);
+ mdelay(20);
+
+ reg_val = readl(GCC_GEPHY_TX_CBCR);
+ reg_val |= GCC_CBCR_CLK_ENABLE;
+ writel(reg_val, GCC_GEPHY_TX_CBCR);
+ mdelay(20);
+}
+
+static int ipq5018_s17c_Link_Update(struct ipq_eth_dev *priv)
+{
+ uint16_t phy_data;
+ int status = 1;
+
+ for(int i = 0;
+ i < priv->gmac_board_cfg->switch_port_count; ++i){
+ phy_data = ipq_mdio_read(
+ priv->gmac_board_cfg->switch_port_phy_address[i],
+ 0x11,
+ NULL);
+
+ if (phy_data == 0x50)
+ continue;
+
+ /* Atleast one port should be link up*/
+ if (phy_data & LINK_UP)
+ status = 0;
+
+ printf("Port%d %s ", i + 1, LINK(phy_data));
+
+ switch(SPEED(phy_data)){
+ case SPEED_1000M:
+ printf("Speed :1000M ");
+ break;
+ case SPEED_100M:
+ printf("Speed :100M ");
+ break;
+ default:
+ printf("Speed :10M ");
+ }
+
+ printf ("%s \n", DUPLEX(phy_data));
+ }
+ return status;
+}
+
+static int ipq5018_phy_link_update(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ u8 status = 1;
+ struct phy_ops *phy_get_ops;
+ fal_port_speed_t speed;
+ fal_port_duplex_t duplex;
+ char *lstatus[] = {"up", "Down"};
+ char *dp[] = {"Half", "Full"};
+ int speed_clock1 = 0, speed_clock2 = 0;
+ int mode = PORT_WRAPPER_SGMII0_RGMII4;
+
+ phy_get_ops = priv->ops;
+
+ if (priv->ipq_swith) {
+ speed_clock1 = 1;
+ speed_clock2 = 0;
+ status = ipq5018_s17c_Link_Update(priv);
+ }
+
+ if (phy_get_ops != NULL &&
+ phy_get_ops->phy_get_link_status != NULL &&
+ phy_get_ops->phy_get_speed != NULL &&
+ phy_get_ops->phy_get_duplex != NULL){
+
+ status = phy_get_ops->phy_get_link_status(priv->mac_unit,
+ priv->phy_address);
+ phy_get_ops->phy_get_speed(priv->mac_unit,
+ priv->phy_address, &speed);
+ phy_get_ops->phy_get_duplex(priv->mac_unit,
+ priv->phy_address, &duplex);
+
+ switch (speed) {
+ case FAL_SPEED_10:
+ speed_clock1 = 9;
+ speed_clock2 = 9;
+ priv->speed = MII_PORT_SELECT;
+ printf ("eth%d %s Speed :%d %s duplex\n",
+ priv->mac_unit,
+ lstatus[status], speed,
+ dp[duplex]);
+ break;
+ case FAL_SPEED_100:
+ priv->speed = MII_PORT_SELECT | FES_PORT_SPEED;
+ speed_clock1 = 9;
+ speed_clock2 = 0;
+ printf ("eth%d %s Speed :%d %s duplex\n",
+ priv->mac_unit,
+ lstatus[status], speed,
+ dp[duplex]);
+ break;
+ case FAL_SPEED_1000:
+ priv->speed = SGMII_PORT_SELECT;
+ speed_clock1 = 1;
+ speed_clock2 = 0;
+ printf ("eth%d %s Speed :%d %s duplex\n",
+ priv->mac_unit,
+ lstatus[status], speed,
+ dp[duplex]);
+ break;
+ case FAL_SPEED_2500:
+ priv->speed = SGMII_PORT_SELECT;
+ mode = PORT_WRAPPER_SGMII_PLUS;
+ speed_clock1 = 1;
+ speed_clock2 = 0;
+ printf ("eth%d %s Speed :%d %s duplex\n",
+ priv->mac_unit,
+ lstatus[status], speed,
+ dp[duplex]);
+ break;
+ default:
+ printf("Unknown speed\n");
+ break;
+ }
+ }
+
+ if (status) {
+ /* No PHY link is alive */
+ if (priv->ipq_swith == 0 && phy_get_ops == NULL)
+ printf("Link status/Get speed/Get duplex not mapped\n");
+ return -1;
+ }
+
+ if (priv->mac_unit){
+ ppe_uniphy_mode_set(mode);
+ } else {
+ ipq5018_enable_gephy();
+ }
+
+ ipq5018_gmac0_speed_clock_set(speed_clock1, speed_clock2, priv->mac_unit);
+
+ return 0;
+}
+
+int ipq_eth_init(struct eth_device *dev, bd_t *this)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p;
+ u32 data;
+
+ if(ipq5018_phy_link_update(dev) < 0) {
+ return -1;
+ }
+
+ priv->next_rx = 0;
+ priv->next_tx = 0;
+
+ ipq_mac_reset(dev);
+ ipq_eth_wr_macaddr(dev);
+
+ /* DMA, MAC configuration for Synopsys GMAC */
+ ipq_eth_dma_cfg(dev);
+ ipq_eth_mac_cfg(dev);
+ ipq_eth_flw_cntl_cfg(dev);
+
+ /* clear all pending interrupts if any */
+ data = readl(&dma_reg->status);
+ writel(data, &dma_reg->status);
+
+ /* Setup Rx fifos and assign base address to */
+ ipq_gmac_rx_desc_setup(priv);
+
+ writel((uint)priv->desc_tx[0], &dma_reg->txdesclistaddr);
+ setbits_le32(&dma_reg->opmode, (RXSTART));
+ setbits_le32(&dma_reg->opmode, (TXSTART));
+
+ return 1;
+}
+
+static int ipq_eth_send(struct eth_device *dev, void *packet, int length)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_p = (struct eth_dma_regs *)priv->dma_regs_p;
+ ipq_gmac_desc_t *txdesc = priv->desc_tx[priv->next_tx];
+ int i;
+
+ invalidate_dcache_range((unsigned long)txdesc,
+ (unsigned long)txdesc + DESC_FLUSH_SIZE);
+
+ /* Check if the dma descriptor is still owned by DMA */
+ if (ipq_gmac_owned_by_dma(txdesc)) {
+ ipq_info("BUG: Tx descriptor is owned by DMA %p\n", txdesc);
+ return NETDEV_TX_BUSY;
+ }
+
+ txdesc->length |= ((length <<DescSize1Shift) & DescSize1Mask);
+ txdesc->status |= (DescTxFirst | DescTxLast | DescTxIntEnable);
+ txdesc->buffer1 = virt_to_phys(packet);
+ ipq_gmac_give_to_dma(txdesc);
+
+ flush_dcache_range((unsigned long)txdesc,
+ (unsigned long)txdesc + DESC_SIZE);
+
+ flush_dcache_range((unsigned long)(txdesc->buffer1),
+ (unsigned long)(txdesc->buffer1) + PKTSIZE_ALIGN);
+
+ /* Start the transmission */
+ writel(POLL_DATA, &dma_p->txpolldemand);
+
+ for (i = 0; i < MAX_WAIT; i++) {
+
+ udelay(10);
+
+ invalidate_dcache_range((unsigned long)txdesc,
+ (unsigned long)txdesc + DESC_FLUSH_SIZE);
+
+ if (!ipq_gmac_owned_by_dma(txdesc))
+ break;
+ }
+
+ if (i == MAX_WAIT) {
+ ipq_info("Tx Timed out\n");
+ }
+
+ /* reset the descriptors */
+ txdesc->status = (priv->next_tx == (NO_OF_TX_DESC - 1)) ?
+ TxDescEndOfRing : 0;
+ txdesc->status |= TxDescChain;
+ txdesc->length = 0;
+ txdesc->buffer1 = 0;
+
+ priv->next_tx = (priv->next_tx + 1) % NO_OF_TX_DESC;
+
+ txdesc->data1 = (unsigned long)priv->desc_tx[priv->next_tx];
+
+
+ flush_dcache_range((unsigned long)txdesc,
+ (unsigned long)txdesc + DESC_SIZE);
+
+ return 0;
+}
+
+static int ipq_eth_recv(struct eth_device *dev)
+{
+ struct ipq_eth_dev *priv = dev->priv;
+ struct eth_dma_regs *dma_p = (struct eth_dma_regs *)priv->dma_regs_p;
+ int length = 0;
+ ipq_gmac_desc_t *rxdesc = priv->desc_rx[priv->next_rx];
+ uint status;
+
+ invalidate_dcache_range((unsigned long)(priv->desc_rx[0]),
+ (unsigned long)(priv->desc_rx[NO_OF_RX_DESC - 1]) +
+ DESC_FLUSH_SIZE);
+
+ for (rxdesc = priv->desc_rx[priv->next_rx];
+ !ipq_gmac_owned_by_dma(rxdesc);
+ rxdesc = priv->desc_rx[priv->next_rx]) {
+
+ status = rxdesc->status;
+ length = ((status & DescFrameLengthMask) >>
+ DescFrameLengthShift);
+
+ invalidate_dcache_range(
+ (unsigned long)(net_rx_packets[priv->next_rx]),
+ (unsigned long)(net_rx_packets[priv->next_rx]) +
+ PKTSIZE_ALIGN);
+ net_process_received_packet(net_rx_packets[priv->next_rx], length - 4);
+
+ rxdesc->length = ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
+ DescSize1Mask);
+
+ rxdesc->length |= (priv->next_rx == (NO_OF_RX_DESC - 1)) ?
+ RxDescEndOfRing : 0;
+ rxdesc->length |= RxDescChain;
+
+ rxdesc->buffer1 = virt_to_phys(net_rx_packets[priv->next_rx]);
+
+ priv->next_rx = (priv->next_rx + 1) % NO_OF_RX_DESC;
+
+ rxdesc->data1 = (unsigned long)priv->desc_rx[priv->next_rx];
+
+ rxdesc->extstatus = 0;
+ rxdesc->reserved1 = 0;
+ rxdesc->timestamplow = 0;
+ rxdesc->timestamphigh = 0;
+ rxdesc->status = DescOwnByDma;
+
+ flush_dcache_range((unsigned long)rxdesc,
+ (unsigned long)rxdesc + DESC_SIZE);
+
+ writel(POLL_DATA, &dma_p->rxpolldemand);
+ }
+
+ return length;
+}
+
+static void ipq_eth_halt(struct eth_device *dev)
+{
+ if (dev->state != ETH_STATE_ACTIVE)
+ return;
+ /* reset the mac */
+ ipq_mac_reset(dev);
+}
+
+static int QCA8337_switch_init(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ for (int port = 0;
+ port < gmac_cfg->switch_port_count;
+ ++port) {
+ u32 phy_val;
+ /* phy powerdown */
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ 0x0,
+ 0x0800
+ );
+ phy_val = ipq_mdio_read(
+ gmac_cfg->switch_port_phy_address[port],
+ 0x3d,
+ NULL
+ );
+ phy_val &= ~0x0040;
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ 0x3d,
+ phy_val
+ );
+ /*
+ * PHY will stop the tx clock for a while when link is down
+ * en_anychange debug port 0xb bit13 = 0 //speed up link down tx_clk
+ * sel_rst_80us debug port 0xb bit10 = 0 //speed up speed mode change to 2'b10 tx_clk
+ */
+ phy_val = ipq_mdio_read(
+ gmac_cfg->switch_port_phy_address[port],
+ 0xb,
+ NULL
+ );
+ phy_val &= ~0x2400;
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ 0xb,
+ phy_val
+ );
+ mdelay(100);
+ }
+ if (ipq_athrs17_init(gmac_cfg) != 0){
+ printf("QCA_8337 switch init failed \n");
+ return 0;
+ }
+ for (int port = 0;
+ port < gmac_cfg->switch_port_count;
+ ++port) {
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM
+ );
+ /* phy reg 0x9, b10,1 = Prefer multi-port device (master) */
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ MII_CTRL1000,
+ (0x0400|ADVERTISE_1000FULL)
+ );
+ ipq_mdio_write(
+ gmac_cfg->switch_port_phy_address[port],
+ MII_BMCR,
+ BMCR_RESET | BMCR_ANENABLE
+ );
+ mdelay(100);
+ }
+ return 1;
+}
+
+static void gephy_mdac_edac_config(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ uint16_t phy_data;
+ uint32_t phy_dac = PHY_DAC(0x10);
+ uint32_t C45_id = QCA808X_REG_C45_ADDRESS(MPGE_PHY_MMD1_NUM,
+ MPGE_PHY_MMD1_DAC);
+ /*set mdac value*/
+ phy_data = ipq5018_mdio_read(
+ gmac_cfg->phy_addr,
+ C45_id,
+ NULL
+ );
+ phy_data &= ~(MPGE_PHY_MMD1_DAC_MASK);
+ ipq5018_mdio_write(
+ gmac_cfg->phy_addr,
+ C45_id,
+ (phy_data | phy_dac)
+ );
+ mdelay(1);
+ /*set edac value*/
+ phy_data = ipq5018_mdio_read(
+ gmac_cfg->phy_addr,
+ MPGE_PHY_DEBUG_EDAC,
+ NULL
+ );
+ phy_data &= ~(MPGE_PHY_MMD1_DAC_MASK);
+ ipq5018_mdio_write(
+ gmac_cfg->phy_addr,
+ MPGE_PHY_DEBUG_EDAC,
+ (phy_data | phy_dac)
+ );
+ mdelay(1);
+}
+
+static void mdio_init(void)
+{
+ if(ipq5018_sw_mdio_init("IPQ MDIO0"))
+ printf("MDIO Failed to init for GMAC0\n");
+
+ if(ipq_sw_mdio_init("IPQ MDIO1"))
+ printf("MDIO Failed to init for GMAC1\n");
+}
+
+int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
+{
+ struct eth_device *dev[CONFIG_IPQ_NO_MACS];
+ uchar enet_addr[CONFIG_IPQ_NO_MACS * 6];
+ int i;
+ uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2;
+ int ret;
+ memset(enet_addr, 0, sizeof(enet_addr));
+
+ /* Mdio init */
+ mdio_init();
+
+ /* Getting the MAC address from ART partition */
+ ret = get_eth_mac_address(enet_addr, CONFIG_IPQ_NO_MACS);
+
+ for (i = 0; gmac_cfg_is_valid(gmac_cfg); gmac_cfg++, i++) {
+
+ dev[i] = malloc(sizeof(struct eth_device));
+ if (dev[i] == NULL)
+ goto init_failed;
+
+ ipq_gmac_macs[i] = malloc(sizeof(struct ipq_eth_dev));
+ if (ipq_gmac_macs[i] == NULL)
+ goto init_failed;
+
+ memset(dev[i], 0, sizeof(struct eth_device));
+ memset(ipq_gmac_macs[i], 0, sizeof(struct ipq_eth_dev));
+
+ dev[i]->iobase = gmac_cfg->base;
+ dev[i]->init = ipq_eth_init;
+ dev[i]->halt = ipq_eth_halt;
+ dev[i]->recv = ipq_eth_recv;
+ dev[i]->send = ipq_eth_send;
+ dev[i]->write_hwaddr = ipq_eth_wr_macaddr;
+ dev[i]->priv = (void *) ipq_gmac_macs[i];
+ /*
+ * Setting the Default MAC address
+ * if the MAC read from ART partition is invalid
+ */
+ if ((ret < 0) ||
+ (!is_valid_ethaddr(&enet_addr[i * 6]))) {
+ memcpy(&dev[i]->enetaddr[0], ipq_def_enetaddr, 6);
+ dev[i]->enetaddr[5] = dev[i]->enetaddr[5] + i;
+ } else {
+ memcpy(&dev[i]->enetaddr[0], &enet_addr[i * 6], 6);
+ }
+
+ ipq_info("MAC%x addr:%x:%x:%x:%x:%x:%x\n",
+ gmac_cfg->unit, dev[i]->enetaddr[0],
+ dev[i]->enetaddr[1],
+ dev[i]->enetaddr[2],
+ dev[i]->enetaddr[3],
+ dev[i]->enetaddr[4],
+ dev[i]->enetaddr[5]);
+
+ snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", i);
+
+ ipq_gmac_macs[i]->dev = dev[i];
+ ipq_gmac_macs[i]->mac_unit = gmac_cfg->unit;
+ ipq_gmac_macs[i]->mac_regs_p =
+ (struct eth_mac_regs *)(gmac_cfg->base);
+ ipq_gmac_macs[i]->dma_regs_p =
+ (struct eth_dma_regs *)(gmac_cfg->base + DW_DMA_BASE_OFFSET);
+ ipq_gmac_macs[i]->phy_address = gmac_cfg->phy_addr;
+ ipq_gmac_macs[i]->gmac_board_cfg = gmac_cfg;
+ ipq_gmac_macs[i]->interface = gmac_cfg->phy_interface_mode;
+ ipq_gmac_macs[i]->phy_type = gmac_cfg->phy_type;
+ ipq_gmac_macs[i]->phy_external_link = gmac_cfg->phy_external_link;
+
+ snprintf((char *)ipq_gmac_macs[i]->phy_name,
+ sizeof(ipq_gmac_macs[i]->phy_name), "IPQ MDIO%d", i);
+
+ if (gmac_cfg->unit){
+ phy_chip_id1 = ipq_mdio_read(
+ ipq_gmac_macs[i]->phy_address,
+ QCA_PHY_ID1,
+ NULL);
+ phy_chip_id2 = ipq_mdio_read(
+ ipq_gmac_macs[i]->phy_address,
+ QCA_PHY_ID2,
+ NULL);
+ phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
+ } else {
+ phy_chip_id1 = ipq5018_mdio_read(
+ ipq_gmac_macs[i]->phy_address,
+ QCA_PHY_ID1,
+ NULL);
+ phy_chip_id2 = ipq5018_mdio_read(
+ ipq_gmac_macs[i]->phy_address,
+ QCA_PHY_ID2,
+ NULL);
+ phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
+ }
+ switch(phy_chip_id) {
+#ifdef CONFIG_QCA8081_PHY
+ /* NAPA PHY For GMAC1 */
+ case QCA8081_PHY:
+ case QCA8081_1_1_PHY:
+ ipq_gmac_macs[i]->phy_type = QCA8081_1_1_PHY;
+ ipq_qca8081_phy_init(
+ &ipq_gmac_macs[i]->ops,
+ ipq_gmac_macs[i]->phy_address);
+ break;
+#endif
+ /* Internel GEPHY only for GMAC0 */
+ case GEPHY:
+ ipq_gmac_macs[i]->phy_type = GEPHY;
+ ipq_gephy_phy_init(
+ &ipq_gmac_macs[i]->ops,
+ ipq_gmac_macs[i]->phy_address);
+ if(ipq_gmac_macs[i]->phy_external_link)
+ gephy_mdac_edac_config(gmac_cfg);
+ break;
+#ifdef CONFIG_QCA8033_PHY
+ /* 1G PHY */
+ case QCA8033_PHY:
+ ipq_gmac_macs[i]->phy_type = QCA8033_PHY;
+ ipq_qca8033_phy_init(
+ &ipq_gmac_macs[i]->ops,
+ ipq_gmac_macs[i]->phy_address);
+ break;
+#endif
+ case QCA_8337:
+ if(gmac_cfg->ipq_swith){
+ ipq_gmac_macs[i]->ipq_swith =
+ QCA8337_switch_init(gmac_cfg);
+ }
+ break;
+ default:
+ printf("GMAC%d:Invalid PHY ID \n", i);
+ break;
+ }
+ /* Initialize 8337 switch */
+ if (gmac_cfg->ipq_swith &&
+ ipq_gmac_macs[i]->phy_external_link &&
+ !ipq_gmac_macs[i]->ipq_swith){
+ ipq_gmac_macs[i]->ipq_swith =
+ QCA8337_switch_init(gmac_cfg);
+ }
+ /* Tx/Rx Descriptor initialization */
+ if (ipq_gmac_tx_rx_desc_ring(dev[i]->priv) == -1)
+ goto init_failed;
+
+ eth_register(dev[i]);
+ }
+ return 0;
+
+init_failed:
+ for (i = 0; i < IPQ5018_GMAC_PORT; i++) {
+ if (dev[i]) {
+ free(dev[i]);
+ }
+ if (ipq_gmac_macs[i])
+ free(ipq_gmac_macs[i]);
+ }
+
+ return -ENOMEM;
+}
+
diff --git a/drivers/net/ipq5018/ipq5018_mdio.c b/drivers/net/ipq5018/ipq5018_mdio.c
new file mode 100644
index 0000000..8f4bf24
--- /dev/null
+++ b/drivers/net/ipq5018/ipq5018_mdio.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+
+#include <common.h>
+#include <command.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/io.h>
+#include <errno.h>
+#include "ipq5018_mdio.h"
+
+struct ipq5018_mdio_data {
+ struct mii_bus *bus;
+ int phy_irq[PHY_MAX_ADDR];
+};
+
+static int ipq5018_mdio_wait_busy(void)
+{
+ int i;
+ u32 busy;
+ for (i = 0; i < IPQ5018_MDIO_RETRY; i++) {
+ udelay(IPQ5018_MDIO_DELAY);
+ busy = readl(IPQ5018_MDIO_BASE +
+ MDIO_CTRL_4_REG) &
+ MDIO_CTRL_4_ACCESS_BUSY;
+
+ if (!busy)
+ return 0;
+ udelay(IPQ5018_MDIO_DELAY);
+ }
+ printf("%s: MDIO operation timed out\n",
+ __func__);
+ return -ETIMEDOUT;
+}
+
+int ipq5018_mdio_write(int mii_id, int regnum, u16 value)
+{
+ u32 cmd;
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+
+
+ if (regnum & MII_ADDR_C45) {
+ unsigned int mmd = (regnum >> 16) & 0x1F;
+ unsigned int reg = regnum & 0xFFFF;
+
+ writel(CTRL_0_REG_C45_DEFAULT_VALUE,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG);
+
+ /* Issue the phy address and reg */
+ writel((mii_id << 8) | mmd,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG);
+
+ writel(reg, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG);
+
+ /* issue read command */
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR;
+
+ writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG);
+
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+ } else {
+ writel(CTRL_0_REG_DEFAULT_VALUE,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG);
+
+ /* Issue the phy addreass and reg */
+ writel((mii_id << 8 | regnum),
+ IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG);
+ }
+
+ /* Issue a write data */
+ writel(value, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG);
+
+ if (regnum & MII_ADDR_C45) {
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_WRITE ;
+ } else {
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_WRITE ;
+ }
+
+ writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG);
+ /* Wait for write complete */
+
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+int ipq5018_mdio_read(int mii_id, int regnum, ushort *data)
+{
+ u32 val,cmd;
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+
+ if (regnum & MII_ADDR_C45) {
+
+ unsigned int mmd = (regnum >> 16) & 0x1F;
+ unsigned int reg = regnum & 0xFFFF;
+
+ writel(CTRL_0_REG_C45_DEFAULT_VALUE,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG);
+
+ /* Issue the phy address and reg */
+ writel((mii_id << 8) | mmd,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG);
+
+
+ writel(reg, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG);
+
+ /* issue read command */
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR;
+ } else {
+
+ writel(CTRL_0_REG_DEFAULT_VALUE,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG);
+
+ /* Issue the phy address and reg */
+ writel((mii_id << 8 | regnum ) ,
+ IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG);
+
+ /* issue read command */
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_READ ;
+ }
+
+ /* issue read command */
+ writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG);
+
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+
+
+ if (regnum & MII_ADDR_C45) {
+ cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_READ;
+ writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG);
+
+ if (ipq5018_mdio_wait_busy())
+ return -ETIMEDOUT;
+ }
+
+ /* Read data */
+ val = readl(IPQ5018_MDIO_BASE + MDIO_CTRL_3_REG);
+
+ if (data != NULL)
+ *data = val;
+
+ return val;
+}
+
+int ipq5018_phy_write(struct mii_dev *bus,
+ int addr, int dev_addr,
+ int regnum, ushort value)
+{
+ return ipq5018_mdio_write(addr, regnum, value);
+}
+
+int ipq5018_phy_read(struct mii_dev *bus,
+ int addr, int dev_addr, int regnum)
+{
+ return ipq5018_mdio_read(addr, regnum, NULL);
+}
+
+int ipq5018_sw_mdio_init(const char *name)
+{
+ struct mii_dev *bus = mdio_alloc();
+ if(!bus) {
+ printf("Failed to allocate IPQ5018 MDIO bus\n");
+ return -1;
+ }
+ bus->read = ipq5018_phy_read;
+ bus->write = ipq5018_phy_write;
+ bus->reset = NULL;
+ snprintf(bus->name, MDIO_NAME_LEN, name);
+ return mdio_register(bus);
+}
+
+static int do_ipq5018_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char op[2];
+ unsigned int addr = 0, reg = 0;
+ unsigned short data = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ op[0] = argv[1][0];
+ if (strlen(argv[1]) > 1)
+ op[1] = argv[1][1];
+ else
+ op[1] = '\0';
+
+ if (argc >= 3)
+ addr = simple_strtoul(argv[2], NULL, 16);
+ if (argc >= 4)
+ reg = simple_strtoul(argv[3], NULL, 16);
+ if (argc >= 5)
+ data = simple_strtoul(argv[4], NULL, 16);
+
+ if (op[0] == 'r') {
+ data = ipq5018_mdio_read(addr, reg, NULL);
+ printf("0x%x\n", data);
+ } else if (op[0] == 'w') {
+ ipq5018_mdio_write(addr, reg, data);
+ } else {
+ return CMD_RET_USAGE;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ ipq5018_mdio, 5, 1, do_ipq5018_mdio,
+ "IPQ5018 mdio utility commands",
+ "ipq5018_mdio read <addr> <reg> - read IPQ5018 MDIO PHY <addr> register <reg>\n"
+ "ipq5018_mdio write <addr> <reg> <data> - write IPQ5018 MDIO PHY <addr> register <reg>\n"
+ "Addr and/or reg may be ranges, e.g. 0-7."
+);
diff --git a/drivers/net/ipq5018/ipq5018_mdio.h b/drivers/net/ipq5018/ipq5018_mdio.h
new file mode 100644
index 0000000..857dfe1
--- /dev/null
+++ b/drivers/net/ipq5018/ipq5018_mdio.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+#ifndef _IPQ5018_MDIO_H
+#define _IPQ5018_MDIO_H
+
+#define IPQ5018_MDIO_BASE 0x88000
+#define MDIO_CTRL_0_REG 0x40
+#define MDIO_CTRL_1_REG 0x44
+#define MDIO_CTRL_2_REG 0x48
+#define MDIO_CTRL_3_REG 0x4c
+#define MDIO_CTRL_4_REG 0x50
+#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16)
+#define MDIO_CTRL_4_ACCESS_START (1 << 8)
+#define MDIO_CTRL_4_ACCESS_CODE_READ 0
+#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1
+#define MDIO_CTRL_4_ACCESS_CODE_C45_ADDR 0
+#define MDIO_CTRL_4_ACCESS_CODE_C45_WRITE 1
+#define MDIO_CTRL_4_ACCESS_CODE_C45_READ 2
+#define CTRL_0_REG_DEFAULT_VALUE 0x1500F
+#ifdef MDIO_12_5_MHZ
+#define CTRL_0_REG_C45_DEFAULT_VALUE 0x15107
+#else
+#define CTRL_0_REG_C45_DEFAULT_VALUE 0x1510F
+#endif
+#define IPQ5018_MDIO_RETRY 1000
+#define IPQ5018_MDIO_DELAY 5
+#endif /* End _IPQ5018_MDIO_H */
diff --git a/drivers/net/ipq5018/ipq5018_uniphy.c b/drivers/net/ipq5018/ipq5018_uniphy.c
new file mode 100644
index 0000000..7daeec0
--- /dev/null
+++ b/drivers/net/ipq5018/ipq5018_uniphy.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <net.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <phy.h>
+#include <net.h>
+#include <miiphy.h>
+#include "ipq5018_uniphy.h"
+#include "ipq_phy.h"
+
+static uint32_t cur_mode;
+
+static int ppe_uniphy_calibration(void)
+{
+ int retries = 100, calibration_done = 0;
+ uint32_t reg_value = 0;
+
+ while(calibration_done != UNIPHY_CALIBRATION_DONE) {
+ mdelay(1);
+ if (retries-- == 0) {
+ printf("uniphy callibration time out!\n");
+ return -1;
+ }
+ reg_value = readl(PPE_UNIPHY_BASE + PPE_UNIPHY_OFFSET_CALIB_4);
+ calibration_done = (reg_value >> 0x7) & 0x1;
+ }
+
+ return 0;
+}
+
+static void ppe_gcc_uniphy_soft_reset(void)
+{
+ uint32_t reg_value;
+
+ reg_value = readl(GCC_UNIPHY0_MISC);
+
+ reg_value |= GCC_UNIPHY_SGMII_SOFT_RESET;
+
+ writel(reg_value, GCC_UNIPHY0_MISC);
+
+ udelay(500);
+
+ reg_value &= ~GCC_UNIPHY_SGMII_SOFT_RESET;
+
+ writel(reg_value, GCC_UNIPHY0_MISC);
+}
+
+static void ppe_uniphy_sgmii_mode_set(uint32_t mode)
+{
+ uint32_t phy_mode = 0x70;
+ writel(UNIPHY_MISC2_REG_SGMII_MODE,
+ PPE_UNIPHY_BASE + UNIPHY_MISC2_REG_OFFSET);
+
+ writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
+ UNIPHY_PLL_RESET_REG_OFFSET);
+ mdelay(10);
+ writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
+ UNIPHY_PLL_RESET_REG_OFFSET);
+ mdelay(10);
+
+ writel(0x0, GCC_UNIPHY_RX_CBCR);
+ udelay(500);
+ writel(0x0, GCC_UNIPHY_TX_CBCR);
+ udelay(500);
+ writel(0x0, GCC_GMAC1_RX_CBCR);
+ udelay(500);
+ writel(0x0, GCC_GMAC1_TX_CBCR);
+ udelay(500);
+
+ switch (mode) {
+ case PORT_WRAPPER_SGMII_FIBER:
+ writel(UNIPHY_SG_MODE, PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL);
+ break;
+
+ case PORT_WRAPPER_SGMII0_RGMII4:
+ case PORT_WRAPPER_SGMII1_RGMII4:
+ case PORT_WRAPPER_SGMII4_RGMII4:
+ writel((UNIPHY_SG_MODE | UNIPHY_PSGMII_MAC_MODE),
+ PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL);
+ break;
+
+ case PORT_WRAPPER_SGMII_PLUS:
+ writel((UNIPHY_SG_PLUS_MODE | UNIPHY_PSGMII_MAC_MODE),
+ PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL);
+ phy_mode = 0x30;
+ break;
+
+ default:
+ printf("SGMII Config. wrongly");
+ break;
+ }
+ if ((cur_mode == PORT_WRAPPER_SGMII_PLUS) ||
+ (mode == PORT_WRAPPER_SGMII_PLUS)){
+ cur_mode = mode;
+ ppe_gcc_uniphy_soft_reset();
+ }
+
+ writel(phy_mode, PPE_UNIPHY_BASE + PPE_UNIPHY_ALLREG_DEC_MISC2);
+
+ writel(0x1, GCC_UNIPHY_RX_CBCR);
+ udelay(500);
+ writel(0x1, GCC_UNIPHY_TX_CBCR);
+ udelay(500);
+ writel(0x1, GCC_GMAC1_RX_CBCR);
+ udelay(500);
+ writel(0x1, GCC_GMAC1_TX_CBCR);
+ udelay(500);
+
+ ppe_uniphy_calibration();
+}
+
+void ppe_uniphy_mode_set(uint32_t mode)
+{
+ /*
+ * SGMII and SHMII plus confugure in same function
+ */
+ ppe_uniphy_sgmii_mode_set(mode);
+}
+
+void ppe_uniphy_set_forceMode(void)
+{
+ uint32_t reg_value;
+
+ reg_value = readl(PPE_UNIPHY_BASE + UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4);
+ reg_value |= UNIPHY_FORCE_SPEED_25M;
+
+ writel(reg_value, PPE_UNIPHY_BASE + UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4);
+
+}
+
+void ppe_uniphy_refclk_set(void)
+{
+/*
+ * This function drive the uniphy ref clock
+ * DEC_REFCLKOUTPUTCONTROLREGISTERS
+ * Its is configured as 25 MHZ
+ */
+
+ u32 reg_val = readl(PPE_UNIPHY_BASE | UNIPHY_REF_CLK_CTRL_REG);
+ reg_val |= 0x2;
+ writel(reg_val, PPE_UNIPHY_BASE | UNIPHY_REF_CLK_CTRL_REG);
+ mdelay(200);
+}
diff --git a/drivers/net/ipq5018/ipq5018_uniphy.h b/drivers/net/ipq5018/ipq5018_uniphy.h
new file mode 100644
index 0000000..da08281
--- /dev/null
+++ b/drivers/net/ipq5018/ipq5018_uniphy.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _IPQ5018_UNIPHY_H_
+#define _IPQ5018_UNIPHY_H
+
+#define PPE_UNIPHY_INSTANCE0 0
+
+#define GCC_UNIPHY_RX_CBCR 0x01856110
+#define GCC_UNIPHY_TX_CBCR 0x01856114
+
+#define GCC_GMAC1_RX_CBCR 0x01868248
+#define GCC_GMAC1_TX_CBCR 0x0186824C
+
+#define GCC_UNIPHY0_MISC 0x01856104
+
+#define PPE_UNIPHY_OFFSET_CALIB_4 0x1E0
+#define UNIPHY_CALIBRATION_DONE 0x1
+
+#define GCC_UNIPHY_PSGMII_SOFT_RESET 0x3ff2
+#define GCC_UNIPHY_SGMII_SOFT_RESET 0x32
+
+#define PPE_UNIPHY_BASE 0x00098000
+#define PPE_UNIPHY_MODE_CONTROL 0x46C
+#define PPE_UNIPHY_ALLREG_DEC_MISC2 0x218
+#define UNIPHY_XPCS_MODE (1 << 12)
+#define UNIPHY_SG_PLUS_MODE (1 << 11)
+#define UNIPHY_SG_MODE (1 << 10)
+#define UNIPHY_CH0_PSGMII_QSGMII (1 << 9)
+#define UNIPHY_CH0_QSGMII_SGMII (1 << 8)
+#define UNIPHY_PSGMII_MAC_MODE (1 << 5)
+#define UNIPHY_CH4_CH1_0_SGMII (1 << 2)
+#define UNIPHY_CH1_CH0_SGMII (1 << 1)
+#define UNIPHY_CH0_ATHR_CSCO_MODE_25M (1 << 0)
+
+#define UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4 0x480
+#define UNIPHY_FORCE_SPEED_25M (1 << 3)
+
+#define UNIPHY_REF_CLK_CTRL_REG 0x74
+
+#define UNIPHY_INSTANCE_LINK_DETECT 0x570
+
+#define UNIPHY_MISC2_REG_OFFSET 0x218
+#define UNIPHY_MISC2_REG_SGMII_MODE 0x30
+#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50
+
+#define UNIPHY_MISC2_REG_VALUE 0x70
+
+#define UNIPHY_PLL_RESET_REG_OFFSET 0x780
+#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf
+#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff
+
+void ppe_uniphy_mode_set(uint32_t mode);
+void ppe_uniphy_set_forceMode(void);
+void ppe_uniphy_refclk_set(void);
+#endif
diff --git a/drivers/net/ipq6018/ipq6018_ppe.h b/drivers/net/ipq6018/ipq6018_ppe.h
index b7a2877..cd8130e 100644
--- a/drivers/net/ipq6018/ipq6018_ppe.h
+++ b/drivers/net/ipq6018/ipq6018_ppe.h
@@ -200,9 +200,9 @@
#define IPQ6018_PPE_PORT_QCOM1 0x1
#define IPQ6018_PPE_PORT_QCOM2 0x2
#define IPQ6018_PPE_PORT_QCOM3 0x3
-#define IPQ6018_PPE_PORT_QCOM4 0x4
-#define IPQ6018_PPE_PORT_XGMAC1 0x5
-#define IPQ6018_PPE_PORT_XGMAC2 0x6
+#define IPQ6018_PPE_PORT_QCOM4 0x6
+#define IPQ6018_PPE_PORT_XGMAC1 0x4
+#define IPQ6018_PPE_PORT_XGMAC2 0x5
#define IPQ6018_PPE_PORT_CRYPTO1 0x7
#define IPQ6018_PPE_PORT_BRIDGE_CTRL_PROMISC_EN 0x20000
#define IPQ6018_PPE_PORT_BRIDGE_CTRL_TXMAC_EN 0x10000
diff --git a/drivers/net/ipq807x/ipq807x_uniphy.c b/drivers/net/ipq807x/ipq807x_uniphy.c
index e5d955a..1a22cf2 100644
--- a/drivers/net/ipq807x/ipq807x_uniphy.c
+++ b/drivers/net/ipq807x/ipq807x_uniphy.c
@@ -237,9 +237,6 @@
reg_value &= ~SS5;
reg_value |= SS6 | SS13 | DUPLEX_MODE;
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
- if (uniphy_index == PPE_UNIPHY_INSTANCE2) {
- ipq_mdio_write(0x7, ((1<<30) | (4<<16) | 0xc441), 8);
- }
}
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
diff --git a/drivers/net/ipq_common/ipq_gephy.c b/drivers/net/ipq_common/ipq_gephy.c
new file mode 100644
index 0000000..90b1c13
--- /dev/null
+++ b/drivers/net/ipq_common/ipq_gephy.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+#include <common.h>
+#include <net.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <phy.h>
+#include "ipq_gephy.h"
+#include "ipq_phy.h"
+
+extern int ipq5018_mdio_read(int mii_id,
+ int regnum, ushort *data);
+extern int ipq5018_mdio_write(int mii_id,
+ int regnum, u16 data);
+
+u16 gephy_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id)
+{
+ return ipq5018_mdio_read(phy_id, reg_id, NULL);
+}
+
+u16 gephy_phy_reg_write(u32 dev_id, u32 phy_id, u32 reg_id, u16 value)
+{
+ return ipq5018_mdio_write(phy_id, reg_id, value);
+}
+
+u8 gephy_phy_get_link_status(u32 dev_id, u32 phy_id)
+{
+ u16 phy_data;
+ phy_data = gephy_phy_reg_read(dev_id,
+ phy_id, GEPHY_PHY_SPEC_STATUS);
+ if (phy_data & GEPHY_STATUS_LINK_PASS)
+ return 0;
+
+ return 1;
+}
+
+u32 gephy_phy_get_duplex(u32 dev_id, u32 phy_id, fal_port_duplex_t *duplex)
+{
+ u16 phy_data;
+
+ phy_data = gephy_phy_reg_read(dev_id, phy_id,
+ GEPHY_PHY_SPEC_STATUS);
+
+ /*
+ * Read duplex
+ */
+ if (phy_data & GEPHY_STATUS_FULL_DUPLEX)
+ *duplex = FAL_FULL_DUPLEX;
+ else
+ *duplex = FAL_HALF_DUPLEX;
+
+ return 0;
+}
+
+u32 gephy_phy_get_speed(u32 dev_id, u32 phy_id, fal_port_speed_t *speed)
+{
+ u16 phy_data;
+
+ phy_data = gephy_phy_reg_read(dev_id,
+ phy_id, GEPHY_PHY_SPEC_STATUS);
+
+ switch (phy_data & GEPHY_STATUS_SPEED_MASK) {
+ case GEPHY_STATUS_SPEED_2500MBS:
+ *speed = FAL_SPEED_2500;
+ break;
+ case GEPHY_STATUS_SPEED_1000MBS:
+ *speed = FAL_SPEED_1000;
+ break;
+ case GEPHY_STATUS_SPEED_100MBS:
+ *speed = FAL_SPEED_100;
+ break;
+ case GEPHY_STATUS_SPEED_10MBS:
+ *speed = FAL_SPEED_10;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int ipq_gephy_phy_init(struct phy_ops **ops, u32 phy_id)
+{
+ u16 phy_data;
+ struct phy_ops *gephy_ops;
+
+ gephy_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
+ if (!gephy_ops)
+ return -ENOMEM;
+ gephy_ops->phy_get_link_status = gephy_phy_get_link_status;
+ gephy_ops->phy_get_speed = gephy_phy_get_speed;
+ gephy_ops->phy_get_duplex = gephy_phy_get_duplex;
+ *ops = gephy_ops;
+
+ phy_data = gephy_phy_reg_read(0x0, phy_id, GEPHY_PHY_ID1);
+ printf ("PHY ID1: 0x%x\n", phy_data);
+ phy_data = gephy_phy_reg_read(0x0, phy_id, GEPHY_PHY_ID2);
+ printf ("PHY ID2: 0x%x\n", phy_data);
+
+ /*enable vga when init napa to fix 8023az issue*/
+ phy_data = gephy_phy_reg_read(0x0, phy_id, QCA808X_8023AZ_ENABLE_VGA);
+ phy_data &= (~QCA808X_PHY_8023AZ_AFE_CTRL_MASK);
+ phy_data |= QCA808X_PHY_8023AZ_AFE_EN;
+ phy_data = gephy_phy_reg_write(0x0, phy_id, QCA808X_8023AZ_ENABLE_VGA, phy_data);
+ if (phy_data != 0)
+ return phy_data;
+
+ /*special configuration for AZ under 1G speed mode*/
+ phy_data = QCA808X_PHY_MMD3_AZ_TRAINING_VAL;
+ phy_data = gephy_phy_reg_write(0x0, phy_id, QCA808X_AZ_CONFIG_UNDER_1G_SPEED,
+ phy_data);
+ return phy_data;
+}
diff --git a/drivers/net/ipq_common/ipq_gephy.h b/drivers/net/ipq_common/ipq_gephy.h
new file mode 100644
index 0000000..1491bfd
--- /dev/null
+++ b/drivers/net/ipq_common/ipq_gephy.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+
+#ifndef _IPQ_GEPHY_H_
+#define _IPQ_GEPHY_H_
+
+/* PHY Registers */
+#define GEPHY_PHY_CONTROL 0
+#define GEPHY_PHY_STATUS 1
+#define GEPHY_PHY_SPEC_STATUS 17
+
+#define GEPHY_PHY_ID1 2
+#define GEPHY_PHY_ID2 3
+#define GEPHY_AUTONEG_ADVERT 4
+#define GEPHY_LINK_PARTNER_ABILITY 5
+#define GEPHY_1000BASET_CONTROL 9
+#define GEPHY_1000BASET_STATUS 10
+#define GEPHY_MMD_CTRL_REG 13
+#define GEPHY_MMD_DATA_REG 14
+#define GEPHY_EXTENDED_STATUS 15
+#define GEPHY_PHY_SPEC_CONTROL 16
+#define GEPHY_PHY_INTR_MASK 18
+#define GEPHY_PHY_INTR_STATUS 19
+#define GEPHY_PHY_CDT_CONTROL 22
+#define GEPHY_DEBUG_PORT_ADDRESS 29
+#define GEPHY_DEBUG_PORT_DATA 30
+
+#define GEPHY_STATUS_LINK_PASS 0x0400
+
+#define GEPHY_STATUS_FULL_DUPLEX 0x2000
+
+#define GEPHY_STATUS_SPEED_MASK 0x380
+#define GEPHY_STATUS_SPEED_2500MBS 0x200
+#define GEPHY_STATUS_SPEED_1000MBS 0x100
+#define GEPHY_STATUS_SPEED_100MBS 0x80
+#define GEPHY_STATUS_SPEED_10MBS 0x0000
+
+#define QCA808X_PHY_MMD3_AZ_TRAINING_VAL 0x1c32
+#define QCA808X_PHY_MMD3_NUM 3
+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007
+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008
+#define QCA808X_PHY_8023AZ_AFE_CTRL_MASK 0x01f0
+#define QCA808X_PHY_8023AZ_AFE_EN 0x0090
+#define QCA808X_MII_ADDR_C45 (1<<30)
+#define QCA808X_REG_C45_ADDRESS(dev_type, reg_num) (QCA808X_MII_ADDR_C45 | \
+ ((dev_type & 0x1f) << 16) | (reg_num & 0xffff))
+#define QCA808X_8023AZ_ENABLE_VGA QCA808X_REG_C45_ADDRESS(QCA808X_PHY_MMD3_NUM, \
+ QCA808X_PHY_MMD3_ADDR_CLD_CTRL7)
+#define QCA808X_AZ_CONFIG_UNDER_1G_SPEED QCA808X_REG_C45_ADDRESS(QCA808X_PHY_MMD3_NUM, \
+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL)
+
+#endif /* _GEPHY_PHY_H_ */
diff --git a/drivers/net/ipq_common/ipq_phy.h b/drivers/net/ipq_common/ipq_phy.h
index 9439e6c..653df90 100755
--- a/drivers/net/ipq_common/ipq_phy.h
+++ b/drivers/net/ipq_common/ipq_phy.h
@@ -104,6 +104,7 @@
QCA8081_PHY_TYPE = 2,
AQ_PHY_TYPE = 3,
QCA8033_PHY_TYPE = 4,
+ SFP_PHY_TYPE = 5,
};
typedef struct {
diff --git a/drivers/pci/pci_ipq.c b/drivers/pci/pci_ipq.c
index b57fba3..f9f8ba2 100644
--- a/drivers/pci/pci_ipq.c
+++ b/drivers/pci/pci_ipq.c
@@ -625,6 +625,7 @@
int is_gen3;
int linkup;
int version;
+ int skip_phy_init;
};
static void ipq_pcie_write_mask(uint32_t addr,
@@ -1130,11 +1131,13 @@
if (err < 0)
goto err;
pcie->is_gen3 = 1;
- }
+ }
} else {
goto err;
}
}
+ pcie->skip_phy_init =
+ fdtdec_get_int(fdt, node, "skip_phy_int", 0);
}
rst_gpio = fdtdec_get_int(fdt, node, "perst_gpio", 0);
if (rst_gpio <= 0) {
@@ -1333,17 +1336,18 @@
void pcie_phy_v2_init(struct ipq_pcie *pcie)
{
- const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq;
- int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq);
+ if (!pcie->skip_phy_init) {
+ const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq;
+ int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq);
- for (i = 0; i < size; i++) {
- if (regs[i].reg_offset == PCIE_PHY_DELAY_MS)
- mdelay(regs[i].val);
- else
- writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset);
+ for (i = 0; i < size; i++) {
+ if (regs[i].reg_offset == PCIE_PHY_DELAY_MS)
+ mdelay(regs[i].val);
+ else
+ writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset);
+ }
+ mdelay(5);
}
-
- mdelay(5);
return;
}
diff --git a/drivers/serial/qca_uart.c b/drivers/serial/qca_uart.c
index 49fc066..77acd78 100644
--- a/drivers/serial/qca_uart.c
+++ b/drivers/serial/qca_uart.c
@@ -453,6 +453,8 @@
plat->n_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "n_value", -1);
plat->d_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "d_value", -1);
+ plat->gpio_node = fdt_subnode_offset(gd->fdt_blob, dev->of_offset, "serial_gpio");
+
return 0;
}
@@ -559,6 +561,7 @@
uart2.n_value = fdtdec_get_int(gd->fdt_blob, node, "n_value", -1);
uart2.d_value = fdtdec_get_int(gd->fdt_blob, node, "d_value", -1);
+ uart2.gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "serial_gpio");
ipq_serial_init(&uart2, uart2.reg_base);
}
diff --git a/include/configs/ipq40xx.h b/include/configs/ipq40xx.h
index 45a1941..b133658 100644
--- a/include/configs/ipq40xx.h
+++ b/include/configs/ipq40xx.h
@@ -195,7 +195,6 @@
* Cache flush and invalidation based on L1 cache, so the cache line
* size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_CMD_CACHE
#define CONFIG_QCA_BAM 1
/*
diff --git a/include/configs/ipq5018.h b/include/configs/ipq5018.h
new file mode 100644
index 0000000..8dc6aec
--- /dev/null
+++ b/include/configs/ipq5018.h
@@ -0,0 +1,429 @@
+/*
+* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#ifndef _IPQ5018_H
+#define _IPQ5018_H
+
+#ifndef DO_DEPS_ONLY
+#include <generated/asm-offsets.h>
+#endif
+
+#define CONFIG_IPQ5018
+#undef CONFIG_QCA_DISABLE_SCM
+#define CONFIG_SPI_FLASH_CYPRESS
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_SYS_CACHELINE_SIZE 64
+#define CONFIG_IPQ_NO_RELOC
+
+#define CONFIG_SYS_VSNPRINTF
+
+/*
+ * Enable Early and Late init
+ * This config needs for secondary boot and to set BADOFF5E
+ * This config also need for spi-nor boot,
+ * set size and offset of hlos and rootfs
+*/
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_LATE_INIT
+
+#define CONFIG_IPQ5018_UART
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_BOOTM_LEN 0x4000000
+
+#define CONFIG_ENV_SIZE_MAX (256 << 10) /* 256 KB */
+
+/*
+* PSCI Calls enable
+*/
+#define CONFIG_ARMV7_PSCI
+
+/*
+ * Enable Flashwrite command
+ */
+#define CONFIG_CMD_FLASHWRITE
+
+/*
+ * Enable Env overwrite support
+ */
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * select serial console configuration
+*/
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_SYS_DEVICE_NULLDEV
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
+ 115200}
+
+#define CONFIG_SYS_CBSIZE (512 * 2) /* Console I/O Buffer Size */
+/*
+
+ svc_sp --> --------------
+ irq_sp --> | |
+ fiq_sp --> | |
+ bd --> | |
+ gd --> | |
+ pgt --> | |
+ malloc --> | |
+ text_base --> |------------|
+*/
+
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE -\
+ CONFIG_SYS_MALLOC_LEN - CONFIG_ENV_SIZE -\
+ GENERATED_BD_INFO_SIZE)
+
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+
+#define TLMM_BASE 0x01000000
+#define GPIO_CONFIG_ADDR(x) (TLMM_BASE + (x)*0x1000)
+#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE + 0x4 + (x)*0x1000)
+
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+#define CONFIG_SYS_TEXT_BASE 0x4A920000
+#define CONFIG_SYS_SDRAM_SIZE 0x10000000
+#define CONFIG_MAX_RAM_BANK_SIZE CONFIG_SYS_SDRAM_SIZE
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + (64 << 20))
+
+#define QCA_KERNEL_START_ADDR CONFIG_SYS_SDRAM_BASE
+#define QCA_DRAM_KERNEL_SIZE CONFIG_SYS_SDRAM_SIZE
+#define QCA_BOOT_PARAMS_ADDR (QCA_KERNEL_START_ADDR + 0x100)
+
+#define CONFIG_OF_COMBINE 1
+
+
+#define CONFIG_QCA_SMEM_BASE 0x4AB00000
+
+#define CONFIG_IPQ_FDT_HIGH 0x4A400000
+#define CONFIG_ENV_IS_IN_SPI_FLASH 1
+#define CONFIG_ENV_SECT_SIZE (64 * 1024)
+
+#define CONFIG_QCA_UBOOT_OFFSET 0xA800000
+#define CONFIG_UBOOT_END_ADDR 0x4AA00000
+
+/*
+* IPQ_TFTP_MIN_ADDR: Starting address of Linux HLOS region.
+* CONFIG_TZ_END_ADDR: Ending address of Trust Zone and starting
+* address of WLAN Area.
+* TFTP file can only be written in Linux HLOS region and WLAN AREA.
+*/
+#define IPQ_TFTP_MIN_ADDR (CONFIG_SYS_SDRAM_BASE + (16 << 20))
+#define CONFIG_TZ_END_ADDR (CONFIG_SYS_SDRAM_BASE + (88 << 21))
+#define CONFIG_SYS_SDRAM_END ((long long)CONFIG_SYS_SDRAM_BASE + gd->ram_size)
+
+#ifndef __ASSEMBLY__
+#include <compiler.h>
+extern loff_t board_env_offset;
+extern loff_t board_env_range;
+extern loff_t board_env_size;
+#endif
+
+#define CONFIG_IPQ5018_ENV 1
+#define CONFIG_ENV_OFFSET board_env_offset
+#define CONFIG_ENV_SIZE CONFIG_ENV_SIZE_MAX
+#define CONFIG_ENV_RANGE board_env_range
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE_MAX + (500 << 10))
+
+/*
+ * NAND Flash Configs
+*/
+
+/* CONFIG_QPIC_NAND: QPIC NAND in BAM mode
+ * CONFIG_IPQ_NAND: QPIC NAND in FIFO/block mode.
+ * BAM is enabled by default.
+ */
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_SYS_NAND_SELF_INIT
+
+#ifdef CONFIG_NAND_FLASH
+#define CONFIG_CMD_NAND
+#define CONFIG_ENV_IS_IN_NAND 1
+#define CONFIG_QPIC_NAND
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_CMD_NAND_YAFFS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#endif
+
+#ifdef CONFIG_QPIC_SERIAL
+#ifdef QSPI_SERIAL_DEBUG /* QSPI DEBUG */
+#define qspi_debug(fmt,args...) printf (fmt ,##args)
+#else
+#define qspi_debug(fmt,args...)
+#endif /* QSPI DEBUG */
+#define CONFIG_PAGE_SCOPE_MULTI_PAGE_READ
+#define CONFIG_QSPI_SERIAL_TRAINING
+#endif
+
+/*
+* SPI Flash Configs
+*/
+#define CONFIG_QCA_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_GIGADEVICE
+#define CONFIG_SPI_FLASH_SPANSION
+#define CONFIG_SF_DEFAULT_BUS 0
+#define CONFIG_SF_DEFAULT_CS 0
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED (48 * 1000 * 1000)
+#define CONFIG_SPI_FLASH_BAR 1
+#define CONFIG_SPI_FLASH_USE_4K_SECTORS
+#define CONFIG_IPQ_4B_ADDR_SWITCH_REQD
+
+#define CONFIG_QUP_SPI_USE_DMA 1
+#define CONFIG_QCA_BAM 1
+
+/*
+ * MMC configs
+ */
+#ifdef CONFIG_MMC_FLASH
+#define CONFIG_QCA_MMC
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SDHCI
+#define CONFIG_SDHCI_QCA
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_SDHCI_SUPPORT
+#define CONFIG_MMC_ADMA
+#define CONFIG_EFI_PARTITION
+/*
+* eMMC controller support only 4-bit
+* force SDHC driver to 4-bit mode
+*/
+#define CONFIG_MMC_FORCE_CAP_4BIT_BUSWIDTH
+#endif
+
+/*
+* I2C Enable
+*/
+#ifdef CONFIG_IPQ5018_I2C
+#define CONFIG_SYS_I2C_QUP
+#define CONFIG_CMD_I2C
+#define CONFIG_DM_I2C
+#endif
+
+/*
+* GMAC Enable
+*/
+
+#define CONFIG_IPQ5018_GMAC
+#define CONFIG_IPQ5018_MDIO
+
+#define CONFIG_NET_RETRY_COUNT 5
+#define CONFIG_SYS_RX_ETH_BUFFER 16
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_MII
+#define CONFIG_IPADDR 192.168.10.10
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_SERVERIP 192.168.10.19
+#define CONFIG_CMD_TFTPPUT
+#define CONFIG_IPQ_MDIO 1
+#define CONFIG_IPQ_ETH_INIT_DEFER
+#define CONFIG_IPQ_NO_MACS 2
+
+/*
+ * GEPHY
+ */
+#define CONFIG_GEPHY
+
+/*
+ * USB Support
+ */
+#ifdef CONFIG_USB_XHCI_IPQ
+#define CONFIG_USB_XHCI
+#define CONFIG_USB_XHCI_DWC3
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+
+/*
+ * USB crashdump collection
+ */
+#define CONFIG_FS_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_FAT
+
+/*
+ * Block Device & Disk Partition Config
+ */
+#define HAVE_BLOCK_DEVICE
+#define CONFIG_DOS_PARTITION
+#endif
+
+/*
+ * PCIE Enable
+ */
+#define PCI_MAX_DEVICES 2
+#if defined(CONFIG_PCI_IPQ)
+#define CONFIG_PCI
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI_SCAN_SHOW
+#endif
+
+/*
+* Expose SPI driver as a pseudo NAND driver to make use
+* of U-Boot's MTD framework.
+*/
+#define CONFIG_SYS_MAX_NAND_DEVICE CONFIG_IPQ_MAX_NAND_DEVICE + \
+ CONFIG_IPQ_MAX_SPI_DEVICE
+
+#define CONFIG_IPQ_MAX_NAND_DEVICE 1
+#define CONFIG_IPQ_MAX_SPI_DEVICE 1
+
+#define CONFIG_QPIC_NAND_NAND_INFO_IDX 0
+#define CONFIG_IPQ_SPI_NOR_INFO_IDX 1
+
+#define CONFIG_NAND_FLASH_INFO_IDX CONFIG_QPIC_NAND_NAND_INFO_IDX
+#define CONFIG_SPI_FLASH_INFO_IDX CONFIG_IPQ_SPI_NOR_INFO_IDX
+
+#define QCA_SPI_NOR_DEVICE "spi0.0"
+
+/*
+* U-Boot Env Configs
+*/
+#define CONFIG_OF_LIBFDT 1
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_CMD_XIMG
+
+/* MTEST */
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE + 0x1300000
+#define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + 0x100
+
+/* NSS firmware loaded using bootm */
+#define CONFIG_BOOTCOMMAND "bootipq"
+#define CONFIG_BOOTARGS "console=ttyMSM0,115200n8"
+#define QCA_ROOT_FS_PART_NAME "rootfs"
+
+#define CONFIG_BOOTDELAY 5
+
+#define NUM_ALT_PARTITION 16
+
+#ifdef CONFIG_IPQ_TINY
+/* undef gzip lib */
+#undef CONFIG_GZIP
+#undef CONFIG_ZLIB
+
+#else
+#define CONFIG_CMD_BOOTZ
+
+/* Multicore CPU support */
+#define CONFIG_SMP_CMD_SUPPORT
+
+/* Mii command support */
+#define CONFIG_CMD_MII
+
+/* compress crash dump support */
+#define CONFIG_CMD_ZIP
+#define CONFIG_GZIP_COMPRESSED
+
+/* Enable DTB compress */
+#define CONFIG_COMPRESSED_DTB_MAX_SIZE 0x40000
+#define CONFIG_COMPRESSED_DTB_BASE CONFIG_SYS_TEXT_BASE -\
+ CONFIG_COMPRESSED_DTB_MAX_SIZE
+#endif
+
+#define CONFIG_FDT_FIXUP_PARTITIONS
+
+#define CONFIG_IPQ_FDT_FIXUP
+/*
+* Below Configs need to be updated after enabling reset_crashdump
+* Included now to avoid build failure
+*/
+#define CONFIG_OF_BOARD_SETUP
+
+#ifdef CONFIG_OF_BOARD_SETUP
+#define DLOAD_DISABLE 0x1
+#define SET_MAGIC 0x1
+#define CLEAR_MAGIC 0x0
+#define SCM_CMD_TZ_CONFIG_HW_FOR_RAM_DUMP_ID 0x9
+#define SCM_CMD_TZ_FORCE_DLOAD_ID 0x10
+#define SCM_CMD_TZ_PSHOLD 0x16
+#define BOOT_VERSION 0
+#define TZ_VERSION 1
+#endif
+
+
+#define CONFIG_IPQ5018_TZ_WONCE_4_ADDR 0x193d010
+/*
+* CRASH DUMP ENABLE
+*/
+#define CONFIG_QCA_APPSBL_DLOAD
+#define CONFIG_IPQ5018_DMAGIC_ADDR 0x193D100
+#ifdef CONFIG_QCA_APPSBL_DLOAD
+
+#undef CONFIG_NET_RETRY_COUNT
+#define CONFIG_NET_RETRY_COUNT 500
+
+#define IPQ_TEMP_DUMP_ADDR 0x44000000
+#endif
+
+#define CONFIG_QCA_KERNEL_CRASHDUMP_ADDRESS *((unsigned int *)0x08600658)
+#define CONFIG_CPU_CONTEXT_DUMP_SIZE 4096
+#define TLV_BUF_OFFSET 1012 * 1024
+#define CONFIG_TLV_DUMP_SIZE 12 * 1024
+
+/* L1 cache line size is 64 bytes, L2 cache line size is 128 bytes
+* Cache flush and invalidation based on L1 cache, so the cache line
+* size is configured to 64 */
+#define CONFIG_SYS_CACHELINE_SIZE 64
+
+/*
+ * UBI write command
+ */
+#ifdef CONFIG_UBI_WRITE
+#define CONFIG_CMD_UBI
+#define CONFIG_RBTREE
+#define IPQ_UBI_VOL_WRITE_SUPPORT
+#endif
+
+#undef CONFIG_BOOTM_NETBSD
+#undef CONFIG_BOOTM_PLAN9
+#undef CONFIG_BOOTM_RTEMS
+#undef CONFIG_BOOTM_VXWORKS
+
+#ifdef CONFIG_ART_COMPRESSED
+/*
+ * This location use to keep comprssed data for
+ * uncompress process.
+ * default location is CONFIG_SYS_LOAD_ADDR if not defined.
+ */
+#define CONFIG_COMPRESSED_LOAD_ADDR (CONFIG_SYS_LOAD_ADDR + (1 << 22))
+#endif
+
+#ifdef CONFIG_SMP_CMD_SUPPORT
+#define NR_CPUS 2
+#endif
+
+/*
+ * 96 MHz
+ */
+
+#define INTERNAL_96MHZ
+
+/*#define CONFIG_IPQ_BT_SUPPORT*/
+
+#endif /* _IPQ5018_H */
diff --git a/include/configs/ipq6018.h b/include/configs/ipq6018.h
index ab51e46..99456a5 100644
--- a/include/configs/ipq6018.h
+++ b/include/configs/ipq6018.h
@@ -363,7 +363,6 @@
* Cache flush and invalidation based on L1 cache, so the cache line
* size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_CMD_CACHE
/*#define CONFIG_SYS_DCACHE_OFF*/
/* Enabling this flag will report any L2 errors.
diff --git a/include/configs/ipq806x.h b/include/configs/ipq806x.h
index 4db1850..616efb6 100644
--- a/include/configs/ipq806x.h
+++ b/include/configs/ipq806x.h
@@ -346,7 +346,6 @@
* Cache flush and invalidation based on L1 cache, so the cache line
* size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_CMD_CACHE
/*#define CONFIG_SYS_DCACHE_OFF*/
/* Enabling this flag will report any L2 errors.
diff --git a/include/configs/ipq807x.h b/include/configs/ipq807x.h
index 70ccde1..126a81a 100644
--- a/include/configs/ipq807x.h
+++ b/include/configs/ipq807x.h
@@ -28,6 +28,9 @@
* #define CONFIG_RUMI
*/
+#define CONFIG_CMD_AES
+#define CONFIG_CMD_AES_256
+
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_IPQ_NO_RELOC
#define CONFIG_BOARD_LATE_INIT
@@ -341,7 +344,6 @@
* Cache flush and invalidation based on L1 cache, so the cache line
* size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64
-#define CONFIG_CMD_CACHE
/* Enabling this flag will report any L2 errors.
* By default we are disabling it */
diff --git a/include/dt-bindings/qcom/gpio-ipq5018.h b/include/dt-bindings/qcom/gpio-ipq5018.h
new file mode 100644
index 0000000..1744a16
--- /dev/null
+++ b/include/dt-bindings/qcom/gpio-ipq5018.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+
+#ifndef __DT_BINDINGS_IPQ5018_GPIO_H__
+#define __DT_BINDINGS_IPQ5018_GPIO_H__
+
+/* GPIO TLMM: Direction */
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+/* GPIO TLMM: Output value */
+#define GPIO_OUT_LOW 0
+#define GPIO_OUT_HIGH 1
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+/* GPIO TLMM: Status */
+#define GPIO_OE_DISABLE 0
+#define GPIO_OE_ENABLE 1
+
+/* GPIO OD */
+#define GPIO_OD_ENABLE 1
+#define GPIO_OD_DISABLE 0
+
+/* GPIO SR */
+#define GPIO_SR_ENABLE 1
+#define GPIO_SR_DISABLE 0
+
+/* GPIO PULLUP RES */
+#define GPIO_PULL_RES0 0
+#define GPIO_PULL_RES1 1
+#define GPIO_PULL_RES2 2
+#define GPIO_PULL_RES3 3
+
+#endif
+
diff --git a/include/malloc.h b/include/malloc.h
index f20e4d3..e5c6561 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -909,6 +909,9 @@
/* Set up pre-relocation malloc() ready for use */
int initf_malloc(void);
+# ifdef CONFIG_COMPRESSED_DTB_BASE
+int initf_pre_malloc(void);
+# endif
/* Public routines */
/* Simple versions which can be used when space is tight */
diff --git a/include/net.h b/include/net.h
index f7039e3..b1a9bc22 100644
--- a/include/net.h
+++ b/include/net.h
@@ -278,7 +278,7 @@
u8 et_dest[6]; /* Destination node */
u8 et_src[6]; /* Source node */
u16 et_protlen; /* Protocol or length */
-};
+} __attribute__((packed));
/* Ethernet header size */
#define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr))
@@ -296,7 +296,7 @@
u8 et_snap2;
u8 et_snap3;
u16 et_prot; /* 802 protocol */
-};
+} __attribute__((packed));
/* 802 + SNAP + ethernet header size */
#define E802_HDR_SIZE (sizeof(struct e802_hdr))
@@ -310,7 +310,7 @@
u16 vet_vlan_type; /* PROT_VLAN */
u16 vet_tag; /* TAG of VLAN */
u16 vet_type; /* protocol type */
-};
+} __attribute__((packed));
/* VLAN Ethernet header size */
#define VLAN_ETHER_HDR_SIZE (sizeof(struct vlan_ethernet_hdr))
@@ -337,7 +337,7 @@
u16 ip_sum; /* checksum */
struct in_addr ip_src; /* Source IP address */
struct in_addr ip_dst; /* Destination IP address */
-};
+} __attribute__((packed));
#define IP_OFFS 0x1fff /* ip offset *= 8 */
#define IP_FLAGS 0xe000 /* first 3 bits */
@@ -365,7 +365,7 @@
u16 udp_dst; /* UDP destination port */
u16 udp_len; /* Length of UDP packet */
u16 udp_xsum; /* Checksum */
-};
+} __attribute__((packed));
#define IP_UDP_HDR_SIZE (sizeof(struct ip_udp_hdr))
#define UDP_HDR_SIZE (IP_UDP_HDR_SIZE - IP_HDR_SIZE)
@@ -404,7 +404,7 @@
u8 ar_tha[]; /* Target hardware address */
u8 ar_tpa[]; /* Target protocol address */
#endif /* 0 */
-};
+} __attribute__((packed));
#define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */
@@ -439,7 +439,7 @@
} frag;
u8 data[0];
} un;
-};
+} __attribute__((packed));
#define ICMP_HDR_SIZE (sizeof(struct icmp_hdr))
#define IP_ICMP_HDR_SIZE (IP_HDR_SIZE + ICMP_HDR_SIZE)
diff --git a/lib/Kconfig b/lib/Kconfig
index 9d580e4..ff53702 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -127,6 +127,14 @@
frame format currently (2015) implemented in the Linux kernel
(generated by 'lz4 -l'). The two formats are incompatible.
+config LZMA
+ bool "Enable LZMA decompression support"
+ help
+ If this option is set, support for LZMA compressed images
+ is included. The LZMA algorithm can run in-place as long as the
+ compressed image is loaded to the end of the output buffer, and
+ trades high compression ratios and fairly fast decompression speed.
+
endmenu
config ERRNO_STR
diff --git a/net/bootp.h b/net/bootp.h
index fcb0a64..567340e 100644
--- a/net/bootp.h
+++ b/net/bootp.h
@@ -49,7 +49,7 @@
char bp_sname[64]; /* Server host name */
char bp_file[128]; /* Boot file name */
char bp_vend[OPT_FIELD_SIZE]; /* Vendor information */
-};
+} __attribute__((packed));
#define BOOTP_HDR_SIZE sizeof(struct bootp_hdr)
diff --git a/net/dns.h b/net/dns.h
index c4e96af..c55a5c1 100644
--- a/net/dns.h
+++ b/net/dns.h
@@ -29,7 +29,7 @@
uint16_t nauth; /* Authority PRs */
uint16_t nother; /* Other PRs */
unsigned char data[1]; /* Data, variable length */
-};
+} __attribute__((packed));
void dns_start(void); /* Begin DNS */
diff --git a/net/nfs.h b/net/nfs.h
index d69b422..09b387e 100644
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -68,7 +68,7 @@
uint32_t data[19];
} reply;
} u;
-};
+} __attribute__((packed));
void nfs_start(void); /* Begin NFS */
diff --git a/net/sntp.h b/net/sntp.h
index 6a9c6bb..c38bcee 100644
--- a/net/sntp.h
+++ b/net/sntp.h
@@ -51,7 +51,7 @@
unsigned long long originate_timestamp;
unsigned long long receive_timestamp;
unsigned long long transmit_timestamp;
-};
+} __attribute__((packed));
void sntp_start(void); /* Begin SNTP */
diff --git a/tools/pack.py b/tools/pack.py
index 8dea6c3..b5fbce0 100644
--- a/tools/pack.py
+++ b/tools/pack.py
@@ -87,6 +87,16 @@
image_type = "all"
memory_size = "default"
lk = "false"
+skip_4k_nand = "false"
+atf = "false"
+qcn6122 = "false"
+tiny_16m = "false"
+
+# Note: ipq806x didn't expose any relevant version */
+soc_hw_version_ipq40xx = { 0x20050100 };
+soc_hw_version_ipq807x = { 0x200D0100, 0x200D0101, 0x200D0102, 0x200D0200 };
+soc_hw_version_ipq6018 = { 0x20170100 };
+soc_hw_version_ipq5018 = { 0x20180100, 0x20180101 };
#
# Python 2.6 and earlier did not have OrderedDict use the backport
@@ -429,6 +439,25 @@
self.append('if test "$%s" = "%s"; then\n' % (var, value),
fatal=False)
+ def start_if_or(self, var, val_list):
+ """Generate code, to check an environment variable.
+
+ var -- string, variable to check
+ value -- string, the list of values to compare with
+ """
+
+ n_val = len(val_list)
+ item = 1
+ cmd_str = "if "
+ for val in val_list:
+ cmd_str = cmd_str + str('test "$%s" = "%s"' % (var, val))
+ #cmd_str = cmd_str + "\"$" + var + "\"" + "=" + "\"" + val + "\""
+ if item <= (n_val - 1):
+ cmd_str = cmd_str + " || "
+ item = item + 1
+
+ self.append('%s; then\n' % cmd_str, fatal=False)
+
def end_if(self):
"""Generate code, to end if statement."""
@@ -594,7 +623,6 @@
def __gen_flash_script_cdt(self, entries, partition, flinfo, script):
global ARCH_NAME
for section in entries:
-
machid = int(section.find(".//machid").text, 0)
machid = "%x" % machid
board = section.find(".//board").text
@@ -711,10 +739,254 @@
script.end_if()
return 1
+ def __gen_flash_script_wififw_ubi_volume(self, entries, fw_filename, wifi_fw_type, script):
+
+ machid_list = []
+ for section in entries:
+
+ wififw_type = section.find('.//wififw_type')
+ if wififw_type == None:
+ continue
+ wififw_type = str(section.find(".//wififw_type").text)
+
+ if str(wifi_fw_type) != str(wififw_type):
+ continue
+
+ machid = int(section.find(".//machid").text, 0)
+ machid = "%x" % machid
+
+ machid_list.append(machid)
+
+ script.start_if_or("machid", machid_list)
+ script.start_activity("Flashing " + fw_filename[:-13] + ":")
+ script.imxtract(fw_filename[:-13] + "-" + sha1(fw_filename))
+
+ rootfs_info = self.__get_part_info("rootfs")
+ rootfs_offset = rootfs_info.offset
+ rootfs_len = rootfs_info.length
+
+ wifi_fw_cmd = "setenv mtdids nand0=nand0\n"
+ wifi_fw_cmd += "setenv mtdparts mtdparts=nand0:0x%x@0x%x(rootfs)\n" % (rootfs_len,rootfs_offset)
+ wifi_fw_cmd += "ubi part rootfs\n"
+ img_size = self.__get_img_size(fw_filename)
+ wifi_fw_cmd += "ubi write $fileaddr wifi_fw %x" % img_size
+ script.append(wifi_fw_cmd, fatal=False)
+
+ #Enable the below lines for debugging purpose
+ """
+ script.append("mtdparts", fatal=False)
+ script.append("ubi info layout", fatal=False)
+ """
+
+ script.finish_activity()
+ script.end_if()
+
+ return 1
+
+ def __gen_flash_script_wififw(self, entries, partition, filename, wifi_fw_type, flinfo, script):
+
+ machid_list = []
+ for section in entries:
+
+ wififw_type = section.find('.//wififw_type')
+ if wififw_type == None:
+ continue
+ wififw_type = str(section.find(".//wififw_type").text)
+
+ if str(wifi_fw_type) != str(wififw_type):
+ continue
+
+ machid = int(section.find(".//machid").text, 0)
+ machid = "%x" % machid
+
+ machid_list.append(machid)
+
+ img_size = self.__get_img_size(filename)
+ part_info = self.__get_part_info(partition)
+
+ section_label = partition.split(":")
+ if len(section_label) != 1:
+ section_conf = section_label[1]
+ else:
+ section_conf = section_label[0]
+ section_conf = section_conf.lower()
+
+ if self.flinfo.type == 'nand':
+ size = roundup(img_size, flinfo.pagesize)
+ tr = ' | tr \"\\000\" \"\\377\"'
+
+ if self.flinfo.type == 'emmc':
+ size = roundup(img_size, flinfo.blocksize)
+ tr = ''
+
+ if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
+ pad_size = size - img_size
+ filename_abs = os.path.join(self.images_dname, filename)
+ filename_abs_pad = filename_abs + ".padded"
+ cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
+ ret = subprocess.call(cmd, shell=True)
+ if ret != 0:
+ error("failed to copy image")
+ cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
+ cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
+ ret = subprocess.call(cmd, shell=True)
+ if ret != 0:
+ error("failed to create padded image from script")
+
+ if self.flinfo.type != "emmc":
+ if part_info == None:
+ if self.flinfo.type == 'norplusnand':
+ if count > 2:
+ error("More than 2 NAND images for NOR+NAND is not allowed")
+ elif img_size > part_info.length:
+ print "img size is larger than part. len in '%s'" % section_conf
+ return 0
+ else:
+ if part_info != None:
+ if (img_size > 0):
+ if img_size > (part_info.length * self.flinfo.blocksize):
+ print "img size is larger than part. len in '%s'" % section_conf
+ return 0
+
+ if part_info == None and self.flinfo.type != 'norplusnand':
+ print "Flash type is norplusemmc"
+ return 1
+
+ script.start_if_or("machid", machid_list)
+ script.start_activity("Flashing %s:" % ( filename[:-13] ))
+
+ if img_size > 0:
+ filename_pad = filename + ".padded"
+ if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
+ script.imxtract(filename[:-13] + "-" + sha1(filename_pad))
+ else:
+ script.imxtract(filename[:-13] + "-" + sha1(filename))
+
+ part_size = Pack.norplusnand_rootfs_img_size
+ if part_info == None:
+ if self.flinfo.type == 'norplusnand':
+ offset = count * Pack.norplusnand_rootfs_img_size
+ script.nand_write(offset, part_size, img_size, spi_nand)
+ count = count + 1
+ else:
+ if part_info.which_flash == 0:
+ offset = part_info.offset
+ script.erase(offset, part_info.length)
+ script.write(offset, img_size)
+ else:
+ offset = part_info.offset
+ script.nand_write(offset, part_info.length, img_size, spi_nand)
+
+ script.finish_activity()
+ script.end_if()
+
+ return 1
+
+ def __gen_flash_script_bootldr(self, entries, partition, flinfo, script):
+ for section in entries:
+
+ machid = int(section.find(".//machid").text, 0)
+ machid = "%x" % machid
+ board = section.find(".//board").text
+ memory = section.find(".//memory").text
+ tiny_image = section.find('.//tiny_image')
+
+ if tiny_image == None:
+ continue
+
+ if memory_size != "default":
+ filename = "bootldr1_" + board + "_" + memory + "_LM" + memory_size + ".mbn"
+ else:
+ filename = "bootldr1_" + board + "_" + memory + ".mbn"
+
+ img_size = self.__get_img_size(filename)
+ part_info = self.__get_part_info(partition)
+
+ section_label = partition.split(":")
+ if len(section_label) != 1:
+ section_conf = section_label[1]
+ else:
+ section_conf = section_label[0]
+
+ section_conf = section_conf.lower()
+
+ if self.flinfo.type == 'nand':
+ size = roundup(img_size, flinfo.pagesize)
+ tr = ' | tr \"\\000\" \"\\377\"'
+
+ if self.flinfo.type == 'emmc':
+ size = roundup(img_size, flinfo.blocksize)
+ tr = ''
+
+ if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
+ pad_size = size - img_size
+ filename_abs = os.path.join(self.images_dname, filename)
+ filename_abs_pad = filename_abs + ".padded"
+ cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
+ ret = subprocess.call(cmd, shell=True)
+ if ret != 0:
+ error("failed to copy image")
+ cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
+ cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
+ ret = subprocess.call(cmd, shell=True)
+ if ret != 0:
+ error("failed to create padded image from script")
+
+ if self.flinfo.type != "emmc":
+ if part_info == None:
+ if self.flinfo.type == 'norplusnand':
+ if count > 2:
+ error("More than 2 NAND images for NOR+NAND is not allowed")
+ elif img_size > part_info.length:
+ print "img size is larger than part. len in '%s'" % section_conf
+ return 0
+ else:
+ if part_info != None:
+ if (img_size > 0):
+ if img_size > (part_info.length * self.flinfo.blocksize):
+ print "img size is larger than part. len in '%s'" % section_conf
+ return 0
+
+ if part_info == None and self.flinfo.type != 'norplusnand':
+ print "Flash type is norplusemmc"
+ continue
+
+ if machid:
+ script.start_if("machid", machid)
+
+ script.start_activity("Flashing bootldr1-%s_%s:" % ( board, memory ))
+ if img_size > 0:
+ filename_pad = filename + ".padded"
+ if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
+ script.imxtract("bootldr1_" + board + "_" + memory + "-" + sha1(filename_pad))
+ else:
+ script.imxtract("bootldr1_" + board + "_" + memory + "-" + sha1(filename))
+
+ part_size = Pack.norplusnand_rootfs_img_size
+ if part_info == None:
+ if self.flinfo.type == 'norplusnand':
+ offset = count * Pack.norplusnand_rootfs_img_size
+ script.nand_write(offset, part_size, img_size, spi_nand)
+ count = count + 1
+ else:
+ if part_info.which_flash == 0:
+ offset = part_info.offset
+ script.erase(offset, part_info.length)
+ script.write(offset, img_size)
+ else:
+ offset = part_info.offset
+ script.nand_write(offset, part_info.length, img_size, spi_nand)
+
+ script.finish_activity()
+
+ if machid:
+ script.end_if()
+
+ return 1
def __gen_flash_script_image(self, filename, soc_version, file_exists, machid, partition, flinfo, script):
- global IF_HK10
+ global IF_QCN9000
img_size = 0
if file_exists == 1:
@@ -774,8 +1046,8 @@
if machid:
script.start_if("machid", machid)
- if section_conf == "mibib" and IF_HK10:
- section_conf = "mibib_hk10"
+ if section_conf == "mibib" and IF_QCN9000:
+ section_conf = "mibib_qcn9000"
if section_conf == "qsee":
section_conf = "tz"
elif section_conf == "appsbl":
@@ -787,8 +1059,8 @@
section_conf = "ubi"
elif section_conf == "wififw" and self.flash_type in ["nand", "nand-4k", "nand-audio", "nand-audio-4k", "norplusnand", "norplusnand-4k"]:
section_conf = "wififw_ubi"
- if IF_HK10:
- section_conf = "wififw_ubi_hk10"
+ if IF_QCN9000:
+ section_conf = "wififw_ubi_qcn9000"
if soc_version:
section_conf = section_conf + "_v" + str(soc_version)
@@ -840,7 +1112,7 @@
return 1
- def __gen_flash_script(self, script, flinfo, root):
+ def __gen_flash_script(self, script, flinfo, root, testmachid=False):
"""Generate the script to flash the images.
info -- ConfigParser object, containing image flashing info
@@ -849,19 +1121,22 @@
global MODE
global SRC_DIR
global ARCH_NAME
- global IF_HK10
+ global IF_QCN9000
diff_files = ""
count = 0
soc_version = 0
diff_soc_ver_files = 0
file_exists = 1
+ wifi_fw_type = ""
+ wifi_fw_type_min = ""
+ wifi_fw_type_max = ""
if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
else:
- if IF_HK10:
- srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition-hk10.xml"
+ if IF_QCN9000:
+ srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition-qcn9000.xml"
else:
srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
@@ -878,6 +1153,53 @@
parts_length = len(parts)
entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
+ # Note: Skipping validation for ipq806x. It didn't expose any relevant ID. */
+ if ARCH_NAME == "ipq40xx":
+ soc_hw_versions = soc_hw_version_ipq40xx
+ if ARCH_NAME == "ipq807x" or ARCH_NAME == "ipq807x_64":
+ soc_hw_versions = soc_hw_version_ipq807x
+ if ARCH_NAME == "ipq6018" or ARCH_NAME == "ipq6018_64":
+ soc_hw_versions = soc_hw_version_ipq6018
+ if ARCH_NAME == "ipq5018" or ARCH_NAME == "ipq5018_64":
+ soc_hw_versions = soc_hw_version_ipq5018
+
+ chip_count = 0
+ for soc_hw_version in soc_hw_versions:
+ chip_count = chip_count + 1
+ if chip_count == 1:
+ script.script.append('if test -n $soc_hw_version')
+ script.script.append('; then\n')
+ script.script.append('if test "$soc_hw_version" = "%x" ' % soc_hw_version)
+ else:
+ script.script.append('|| test "$soc_hw_version" = "%x" ' % soc_hw_version)
+ if chip_count >= 1:
+ script.script.append('; then\n')
+ script.script.append('echo \'soc_hw_version : Validation success\'\n')
+ script.script.append('else\n')
+ script.script.append('echo \'soc_hw_version : did not match, aborting upgrade\'\n')
+ script.script.append('exit 1\n')
+ script.script.append('fi\n')
+ script.script.append('else\n')
+ script.script.append('echo \'soc_hw_version : unknown, skipping validation\'\n')
+ script.script.append('fi\n')
+
+ if testmachid:
+ machid_count = 0
+ for section in entries:
+ machid = int(section.find(".//machid").text, 0)
+ machid = "%x" % machid
+ machid_count = machid_count + 1
+ if machid_count == 1:
+ script.script.append('if test "$machid" = "%s" ' % machid)
+ else:
+ script.script.append('|| test "$machid" = "%s" ' % machid)
+ if machid_count >= 1:
+ script.script.append('; then\n')
+ script.script.append('echo \'machid : Validation success\'\n')
+ script.script.append('else\n')
+ script.script.append('echo \'machid : unknown, aborting upgrade\'\n')
+ script.script.append('exit 1\n')
+ script.script.append('fi\n')
first = False
section = None
part_index = 0
@@ -941,17 +1263,21 @@
try:
diff_soc_ver_files = section.attrib['diff_soc_ver_files']
except KeyError, e:
- try:
- if image_type == "all" or section.attrib['image_type'] == image_type:
- filename = section.attrib['filename']
- if lk == "true" and "u-boot" in filename:
- filename = filename.replace("u-boot", "lkboot")
- partition = section.attrib['label']
- if filename == "":
- continue
- except KeyError, e:
- print "Skipping partition '%s'" % section.attrib['label']
- pass
+ if (qcn6122 == "true" or tiny_16m == "true") and 'wififw_type_min' in section.attrib:
+ wifi_fw_type_min = section.attrib['wififw_type_min']
+ wifi_fw_type_max = section.attrib['wififw_type_max']
+ else:
+ try:
+ if image_type == "all" or section.attrib['image_type'] == image_type:
+ filename = section.attrib['filename']
+ if filename == "":
+ continue
+ partition = section.attrib['label']
+ if lk == "true" and "u-boot" in filename:
+ filename = filename.replace("u-boot", "lkboot")
+ except KeyError, e:
+ print "Skipping partition '%s'" % section.attrib['label']
+ pass
if diff_files == "true":
try:
@@ -983,6 +1309,13 @@
except KeyError, e:
continue
+ if partition == "0:BOOTLDR1":
+ if image_type == "all" or section.attrib['image_type'] == image_type:
+ ret = self.__gen_flash_script_bootldr(entries, partition, flinfo, script)
+ if ret == 0:
+ return 0
+ continue
+
if ARCH_NAME == "ipq806x":
# Get Layout
try:
@@ -994,10 +1327,26 @@
error("invalid layout in '%s'" % section)
if flinfo.type != "emmc":
-
img = section.find('img_name')
- if img != None and 'soc_version' in img.attrib:
+ if img != None and 'wififw_type' in img.attrib and (qcn6122 == "true" or tiny_16m == "true"):
+ imgs = section.findall('img_name')
+ try:
+ for img in imgs:
+ filename = img.text
+ if 'optional' in img.attrib:
+ if not os.path.exists(os.path.join(self.images_dname, filename)):
+ continue
+ wifi_fw_type = img.get('wififw_type')
+ ret = self.__gen_flash_script_wififw(entries, partition, filename, wifi_fw_type, flinfo, script)
+ if ret == 0:
+ return 0
+ wifi_fw_type = ""
+ continue
+ except KeyError, e:
+ continue
+
+ if img != None and 'soc_version' in img.attrib:
imgs = section.findall('img_name')
try:
for img in imgs:
@@ -1016,7 +1365,35 @@
except KeyError, e:
continue
+ imgs = section.findall('img_name')
+ for img in imgs:
+ memory_attr = img.get('memory')
+ if memory_attr != None and memory_attr == memory_size:
+ filename = img.text;
+
+ atf_image = img.get('atf')
+ if atf_image != None and atf == "true":
+ filename = img.text;
+
else:
+ if wifi_fw_type_min:
+ partition = section.attrib['label']
+
+ for fw_type in range(int(wifi_fw_type_min), int(wifi_fw_type_max) + 1):
+ if image_type == "all" or section.attrib['image_type'] == image_type:
+ filename = section.attrib['filename_img' + str(fw_type)]
+ if filename == "":
+ continue
+ wifi_fw_type = str(fw_type)
+ ret = self.__gen_flash_script_wififw(entries, partition, filename, wifi_fw_type, flinfo, script)
+ if ret == 0:
+ return 0
+ wifi_fw_type = ""
+
+ wifi_fw_type_min = ""
+ wifi_fw_type_max = "" # Clear for next partition
+ continue
+
if diff_soc_ver_files:
try:
for version in range(1, int(diff_soc_ver_files)+1):
@@ -1025,7 +1402,7 @@
partition = section.attrib['label']
if filename == "":
continue
- if section.attrib['optional']:
+ if 'optional' in section.attrib:
if not os.path.exists(os.path.join(self.images_dname, filename)):
file_exists = 0
ret = self.__gen_flash_script_image(filename, version, file_exists, machid, partition, flinfo, script)
@@ -1038,11 +1415,31 @@
print "Skipping partition '%s'" % section.attrib['label']
pass
+ if section != None and filename != "" and section.get('filename_mem' + memory_size) != None:
+ filename = section.get('filename_mem' + memory_size)
+
+ if section != None and atf == "true" and section.get('filename_atf') != None:
+ filename = section.get('filename_atf')
+
if filename != "":
ret = self.__gen_flash_script_image(filename, soc_version, file_exists, machid, partition, flinfo, script)
if ret == 0:
return 0
+ if self.flash_type in [ "nand", "nand-4k", "norplusnand", "norplusnand-4k" ] and partition == "rootfs" and qcn6122 == "true":
+
+ fw_imgs = section.findall('img_name')
+ for fw_img in fw_imgs:
+ wifi_fw_type = fw_img.get('wififw_type')
+ if wifi_fw_type != None:
+ fw_filename = fw_img.text
+ if fw_filename != "":
+ ret = self.__gen_flash_script_wififw_ubi_volume(entries, fw_filename, wifi_fw_type, script)
+ if ret == 0:
+ return 0
+ wifi_fw_type = ""
+ continue
+
return 1
def __gen_script_cdt(self, images, flinfo, root, section_conf, partition):
@@ -1089,9 +1486,59 @@
if image_info not in images:
images.append(image_info)
- def __gen_script_append_images(self, filename, soc_version, images, flinfo, root, section_conf, partition):
+ def __gen_script_bootldr(self, images, flinfo, root, section_conf, partition):
+ global ARCH_NAME
- global HK10
+ entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
+
+ for section in entries:
+
+ board = section.find(".//board").text
+ tiny_image = section.find('.//tiny_image')
+
+ if tiny_image == None:
+ continue
+
+ if ARCH_NAME != "ipq806x":
+ try:
+ memory = section.find(".//memory").text
+ except AttributeError, e:
+ memory = "128M16"
+
+ if memory_size != "default":
+ filename = "bootldr1_" + board + "_" + memory + "_LM" + memory_size + ".mbn"
+ else:
+ filename = "bootldr1_" + board + "_" + memory + ".mbn"
+ file_info = "bootldr1_" + board + "_" + memory
+ else:
+ filename = "bootldr1_" + board + ".mbn"
+ file_info = "bootldr1_" + board
+
+ part_info = self.__get_part_info(partition)
+
+ if part_info == None and self.flinfo.type != 'norplusnand':
+ continue
+
+ if self.flinfo.type == 'nand':
+ img_size = self.__get_img_size(filename)
+ size = roundup(img_size, flinfo.pagesize)
+ if ( size != img_size ):
+ filename = filename + ".padded"
+ if self.flinfo.type == 'emmc':
+ img_size = self.__get_img_size(filename)
+ size = roundup(img_size, flinfo.blocksize)
+ if ( size != img_size ):
+ filename = filename + ".padded"
+ image_info = ImageInfo(file_info + "-" + sha1(filename),
+ filename, "firmware")
+ if filename.lower() != "none":
+ if image_info not in images:
+ images.append(image_info)
+
+
+ def __gen_script_append_images(self, filename, soc_version, wifi_fw_type, images, flinfo, root, section_conf, partition):
+
+ global QCN9000
part_info = self.__get_part_info(partition)
if part_info == None and self.flinfo.type != 'norplusnand':
@@ -1119,6 +1566,8 @@
section_conf = "ubi"
elif section_conf == "wififw" and self.flash_type in ["nand", "nand-4k", "nand-audio", "nand-audio-4k", "norplusnand", "norplusnand-4k"]:
section_conf = "wififw_ubi"
+ elif section_conf == "wififw" and wifi_fw_type:
+ section_conf = filename[:-13]
if soc_version:
section_conf = section_conf + "_v" + str(soc_version)
@@ -1129,6 +1578,14 @@
if image_info not in images:
images.append(image_info)
+ def __gen_script_append_images_wififw_ubi_volume(self, fw_filename, wifi_fw_type, images):
+
+ image_info = ImageInfo(fw_filename[:-13] + "-" + sha1(fw_filename),
+ fw_filename, "firmware")
+ if fw_filename.lower() != "none":
+ if image_info not in images:
+ images.append(image_info)
+
def __gen_script(self, script_fp, script, images, flinfo, root):
"""Generate the script to flash the multi-image blob.
@@ -1139,32 +1596,42 @@
"""
global MODE
global SRC_DIR
- global HK10
+ global QCN9000
soc_version = 0
diff_soc_ver_files = 0
+ wifi_fw_type = ""
+ wifi_fw_type_min = ""
+ wifi_fw_type_max = ""
diff_files = ""
file_exists = 1
- ret = self.__gen_flash_script(script, flinfo, root)
+ ret = self.__gen_flash_script(script, flinfo, root, True)
if ret == 0:
return 0 #Stop packing this single-image
- if HK10:
- script.end_if() #end if started for hk10+pine
+ if QCN9000:
+ script.end_if() #end if started for hk+pine
if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"):
if flinfo.type == "emmc":
- script.start_activity("Flashing rootfs_data:")
- part_info = self.partitions["rootfs_data"]
- script.erase(part_info.offset, part_info.length)
- script.finish_activity()
+ srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
+ rpart = ET.parse(srcDir_part)
+ parts = rpart.findall(".//physical_partition[@ref='emmc']/partition")
+ for index in range(len(parts)):
+ section = parts[index]
+ if section.attrib['label'] == "rootfs_data":
+ script.start_activity("Flashing rootfs_data:")
+ part_info = self.partitions["rootfs_data"]
+ script.erase(part_info.offset, part_info.length)
+ script.finish_activity()
script.end()
if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
else:
srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
+
root_part = ET.parse(srcDir_part)
if self.flash_type != "emmc" and flinfo.type != "emmc":
parts = root_part.findall(".//partitions/partition")
@@ -1229,26 +1696,31 @@
except KeyError, e:
continue
partition = section[0].text
- else:
+ else:
try:
diff_files = section.attrib['diff_files']
except KeyError, e:
- try:
+ try:
diff_soc_ver_files = section.attrib['diff_soc_ver_files']
partition = section.attrib['label']
except KeyError, e:
- try:
- if image_type == "all" or section.attrib['image_type'] == image_type:
- filename = section.attrib['filename']
- if lk == "true" and "u-boot" in filename:
- filename = filename.replace("u-boot", "lkboot")
- partition = section.attrib['label']
- if filename == "":
- continue
- except KeyError, e:
- print "Skipping partition '%s'" % section.attrib['label']
- pass
+ if (qcn6122 == "true" or tiny_16m == "true") and 'wififw_type_min' in section.attrib:
+ wifi_fw_type_min = section.attrib['wififw_type_min']
+ wifi_fw_type_max = section.attrib['wififw_type_max']
+ partition = section.attrib['label']
+ else:
+ try:
+ if image_type == "all" or section.attrib['image_type'] == image_type:
+ filename = section.attrib['filename']
+ if filename == "":
+ continue
+ partition = section.attrib['label']
+ if lk == "true" and "u-boot" in filename:
+ filename = filename.replace("u-boot", "lkboot")
+ except KeyError, e:
+ print "Skipping partition '%s'" % section.attrib['label']
+ pass
if diff_files == "true":
try:
@@ -1287,9 +1759,33 @@
except KeyError, e:
continue
+ if section_conf == "bootldr1":
+ try:
+ if image_type == "all" or section[8].attrib['image_type'] == image_type:
+ self.__gen_script_bootldr(images, flinfo, root, section_conf, partition)
+ continue
+ except KeyError, e:
+ continue
+
if flinfo.type != "emmc":
img = section.find('img_name')
+
+ if img != None and 'wififw_type' in img.attrib and (qcn6122 == "true" or tiny_16m == "true"):
+ imgs = section.findall('img_name')
+ try:
+ for img in imgs:
+ wifi_fw_type = img.get('wififw_type')
+ filename = img.text
+ if 'optional' in img.attrib:
+ if not os.path.exists(os.path.join(self.images_dname, filename)):
+ continue
+ self.__gen_script_append_images(filename, soc_version, wifi_fw_type, images, flinfo, root, section_conf, partition)
+ wififw_type = ""
+ continue
+ except KeyError, e:
+ continue
+
if img != None and 'soc_version' in img.attrib:
imgs = section.findall('img_name')
@@ -1297,45 +1793,72 @@
for img in imgs:
soc_version = img.get('soc_version')
filename = img.text
- if HK10 and section_conf == "wififw":
- filename_hk10 = filename.replace("wifi_fw_ubi", "wifi_fw_ipq8074_qcn9000_ubi")
- if os.path.exists(os.path.join(self.images_dname, filename_hk10)):
- section_conf_hk10 = section_conf + "_ubi_hk10"
- self.__gen_script_append_images(filename_hk10, soc_version, images, flinfo, root, section_conf_hk10, partition)
+ if QCN9000 and section_conf == "wififw":
+ filename_qcn9000 = filename.replace("wifi_fw_ubi", "wifi_fw_ipq8074_qcn9000_ubi")
+ if os.path.exists(os.path.join(self.images_dname, filename_qcn9000)):
+ section_conf_qcn9000 = section_conf + "_ubi_qcn9000"
+ self.__gen_script_append_images(filename_qcn9000, soc_version, wifi_fw_type, images, flinfo, root, section_conf_qcn9000, partition)
if 'optional' in img.attrib:
if not os.path.exists(os.path.join(self.images_dname, filename)):
file_exists = 0
if file_exists == 1:
- self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
+ self.__gen_script_append_images(filename, soc_version, wifi_fw_type, images, flinfo, root, section_conf, partition)
file_exists = 1
soc_version = 0 # Clear soc_version for next iteration
continue
except KeyError, e:
continue
- # system-partition specific for HK10+PINE
- if section_conf == "mibib" and HK10:
- img = section.find('img_name')
- filename_hk10 = img.text[:-4] + "-hk10.bin"
- section_conf_hk10 = section_conf + "_hk10"
- self.__gen_script_append_images(filename_hk10, soc_version, images, flinfo, root, section_conf_hk10, partition)
+ imgs = section.findall('img_name')
+ for img in imgs:
+ memory_attr = img.get('memory')
+ if memory_attr != None and memory_attr == memory_size:
+ filename = img.text;
+ atf_image = img.get('atf')
+ if atf_image != None and atf == "true":
+ filename = img.text;
+
+ # system-partition specific for HK+PINE
+ if section_conf == "mibib" and QCN9000:
+ img = section.find('img_name')
+ filename_qcn9000 = img.text[:-4] + "-qcn9000.bin"
+ section_conf_qcn9000 = section_conf + "_qcn9000"
+ self.__gen_script_append_images(filename_qcn9000, soc_version, wifi_fw_type, images, flinfo, root, section_conf_qcn9000, partition)
else:
+ # wififw images specific for RDP based on machid
+ if wifi_fw_type_min:
+
+ for fw_type in range(int(wifi_fw_type_min), int(wifi_fw_type_max) + 1):
+ if image_type == "all" or section.attrib['image_type'] == image_type:
+ filename = section.attrib['filename_img' + str(fw_type)]
+ if filename == "":
+ continue
+ if 'optional' in section.attrib:
+ if not os.path.exists(os.path.join(self.images_dname, filename)):
+ continue
+ wifi_fw_type = str(fw_type)
+ self.__gen_script_append_images(filename, soc_version, wifi_fw_type, images, flinfo, root, section_conf, partition)
+ wifi_fw_type = ""
+
+ wifi_fw_type_min = ""
+ wifi_fw_type_max = "" # Clean for next partition
+ continue
+
if diff_soc_ver_files:
try:
for version in range(1, int(diff_soc_ver_files)+1):
if image_type == "all" or section.attrib['image_type'] == image_type:
filename = section.attrib['filename_v' + str(version)]
- partition = section.attrib['label']
if filename == "":
continue
- if section.attrib['optional']:
+ if 'optional' in section.attrib:
if not os.path.exists(os.path.join(self.images_dname, filename)):
file_exists = 0
if file_exists == 1:
- self.__gen_script_append_images(filename, version, images, flinfo, root, section_conf, partition)
+ self.__gen_script_append_images(filename, version, wifi_fw_type, images, flinfo, root, section_conf, partition)
file_exists = 1
diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
@@ -1344,8 +1867,31 @@
print "Skipping partition '%s'" % section.attrib['label']
pass
+ if section != None and filename != "" and section.get('filename_mem' + memory_size) != None:
+ filename = section.get('filename_mem' + memory_size)
+
+ if section != None and atf == "true" and section.get('filename_atf') != None:
+ filename = section.get('filename_atf')
+
if filename != "":
- self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
+ self.__gen_script_append_images(filename, soc_version, wifi_fw_type, images, flinfo, root, section_conf, partition)
+
+ if self.flash_type in [ "nand", "nand-4k", "norplusnand", "norplusnand-4k" ] and section_conf == "rootfs" and qcn6122 == "true":
+
+ fw_imgs = section.findall('img_name')
+ try:
+ for fw_img in fw_imgs:
+ wifi_fw_type = fw_img.get('wififw_type')
+ if wifi_fw_type != None:
+ fw_filename = fw_img.text
+ ret = self.__gen_script_append_images_wififw_ubi_volume(fw_filename, wifi_fw_type, images)
+ if ret == 0:
+ return 0
+ wifi_fw_type = ""
+ continue
+ except KeyError, e:
+ continue
+
return 1
def __mkimage(self, images):
@@ -1373,7 +1919,7 @@
its_fp.write(its_data)
its_fp.close()
-
+
try:
cmd = [SRC_DIR + "/mkimage", "-f", self.its_fname, self.img_fname]
ret = subprocess.call(cmd)
@@ -1392,8 +1938,8 @@
def __gen_board_script(self, flinfo, part_fname, images, root):
global SRC_DIR
global ARCH_NAME
- global HK10
- global IF_HK10
+ global QCN9000
+ global IF_QCN9000
"""Generate the flashing script for one board.
@@ -1404,7 +1950,7 @@
fconf_fname -- string, flash config file specific to the board
images -- list of ImageInfo, append images used by the board here
"""
- IF_HK10 = False
+ IF_QCN9000 = False
script_fp = open(self.scr_fname, "a")
self.flinfo = flinfo
@@ -1436,22 +1982,22 @@
script = Flash_Script(flinfo, pagesize)
script.probe()
- # system-partition specific for HK10+PINE
- if HK10:
- IF_HK10 = True
- part_fname_hk10 = part_fname[:-4] + "-hk10.bin"
- mibib_hk10 = MIBIB(part_fname_hk10, flinfo.pagesize, flinfo.blocksize,
+ # system-partition specific for HK+PINE
+ if QCN9000:
+ IF_QCN9000 = True
+ part_fname_qcn9000 = part_fname[:-4] + "-qcn9000.bin"
+ mibib_qcn9000 = MIBIB(part_fname_qcn9000, flinfo.pagesize, flinfo.blocksize,
flinfo.chipsize, blocksize, chipsize, root_part)
- self.partitions = mibib_hk10.get_parts()
+ self.partitions = mibib_qcn9000.get_parts()
- script.append('if test "$machid" = "801000e" || test "$machid" = "801010e"; then\n', fatal=False)
- ret = self.__gen_flash_script(script, flinfo, root)
+ script.append('if test "$machid" = "801000e" || test "$machid" = "801010e" || test "$machid" = "8010012" || test "$machid" = "8010013" || test "$machid" = "8010500"; then\n', fatal=False)
+ ret = self.__gen_flash_script(script, flinfo, root, True)
if ret == 0:
- return 0 #Issue in packing hk10+pine single-image
+ return 0 #Issue in packing hk+pine single-image
script.append('else', fatal=False)
self.partitions = {}
- IF_HK10 = False
+ IF_QCN9000 = False
mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize,
flinfo.chipsize, blocksize, chipsize, root_part)
@@ -1466,8 +2012,8 @@
if ret == 0:
return 0
- if HK10:
- HK10 = False
+ if QCN9000:
+ QCN9000 = False
try:
script_fp.write(script.dumps())
@@ -1517,10 +2063,10 @@
global SRC_DIR
global ARCH_NAME
global MODE
- global HK10
+ global QCN9000
try:
- if ftype == "tiny-nor":
+ if ftype == "tiny-nor" or ftype == "tiny-nor-debug":
part_info = root.find(".//data[@type='" + "NOR_PARAMETER']")
elif ftype in ["nand", "nand-4k", "nand-audio", "nand-audio-4k"]:
if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
@@ -1539,11 +2085,8 @@
else:
part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
- if ARCH_NAME == "ipq6018" or ARCH_NAME == "ipq5018":
- if MODE == "64":
- MODE_APPEND = "_64"
- else:
- MODE_APPEND = ""
+ if ARCH_NAME in ["ipq6018", "ipq5018", "ipq807x"]:
+ MODE_APPEND = "_64" if MODE == "64" else ""
if ftype in ["nand-audio", "nand-audio-4k"]:
UBINIZE_CFG_NAME = ARCH_NAME + "-ubinize" + MODE_APPEND + "-audio.cfg"
@@ -1558,12 +2101,15 @@
f1.close()
f2.close()
- if ftype in ["nand-4k", "nand-audio-4k", "norplusnand-4k"]:
- if ARCH_NAME == "ipq6018":
- UBI_IMG_NAME = "openwrt-ipq-ipq60xx" + MODE_APPEND + "-ubi-root-m4096-p256KiB.img"
- if ARCH_NAME == "ipq5018":
- UBI_IMG_NAME = "openwrt-ipq-ipq50xx" + MODE_APPEND + "-ubi-root-m4096-p256KiB.img"
+ part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
+ parts = ET.parse(part_file).findall('.//partitions/partition')
+ for index in range(len(parts)):
+ section = parts[index]
+ if section[0].text == "rootfs":
+ rootfs_pos = 9 if MODE == "64" else 8
+ UBI_IMG_NAME = section[rootfs_pos].text
+ if ftype in ["nand-4k", "nand-audio-4k", "norplusnand-4k"]:
cmd = '%s -m 4096 -p 256KiB -o root.ubi %s' % ((SRC_DIR + "/ubinize") ,UBINIZE_CFG_NAME)
ret = subprocess.call(cmd, shell=True)
if ret != 0:
@@ -1572,12 +2118,8 @@
ret = subprocess.call(cmd, shell=True)
if ret != 0:
error("ubi image copy operation failed")
- elif ftype in ["nand", "nand-audio", "norplusnand"]:
- if ARCH_NAME == "ipq6018":
- UBI_IMG_NAME = "openwrt-ipq-ipq60xx" + MODE_APPEND +"-ubi-root.img"
- if ARCH_NAME == "ipq5018":
- UBI_IMG_NAME = "openwrt-ipq-ipq50xx" + MODE_APPEND +"-ubi-root.img"
+ elif ftype in ["nand", "nand-audio", "norplusnand"]:
cmd = '%s -m 2048 -p 128KiB -o root.ubi %s' % ((SRC_DIR + "/ubinize") ,UBINIZE_CFG_NAME)
ret = subprocess.call(cmd, shell=True)
if ret != 0:
@@ -1597,9 +2139,9 @@
blocks_per_chip = int(part_info.find(".//total_block").text)
if ARCH_NAME == "ipq807x" and (ftype == "norplusnand" or ftype == "nand"):
- HK10 = True
+ QCN9000 = True
- if ftype in ["tiny-nor", "norplusnand", "norplusnand-4k", "norplusemmc"]:
+ if ftype in ["tiny-nor", "norplusnand", "norplusnand-4k", "norplusemmc", "tiny-nor-debug"]:
ftype = "nor"
if ftype in ["nand-4k", "nand-audio", "nand-audio-4k"]:
ftype = "nand"
@@ -1617,11 +2159,11 @@
def __process_board(self, images, root):
- global HK10
+ global QCN9000
- HK10 = False
+ QCN9000 = False
try:
- if self.flash_type in [ "nand", "nand-4k", "nand-audio", "nand-audio-4k", "nor", "tiny-nor", "norplusnand", "norplusnand-4k" ]:
+ if self.flash_type in [ "nand", "nand-4k", "nand-audio", "nand-audio-4k", "nor", "tiny-nor", "norplusnand", "norplusnand-4k", "tiny-nor-debug" ]:
ret = self.__process_board_flash(self.flash_type, images, root)
elif self.flash_type == "emmc":
ret = self.__process_board_flash_emmc(self.flash_type, images, root)
@@ -1657,7 +2199,7 @@
self.__mkimage(images)
else:
fail_img = out_fname.split("/")
- print "Failed to pack %s" % fail_img[-1]
+ error("Failed to pack %s" % fail_img[-1])
class UsageError(Exception):
"""Indicates error in command arguments."""
@@ -1682,6 +2224,9 @@
global image_type
global memory_size
global lk
+ global atf
+ global skip_4k_nand
+ global qcn6122
"""Start the parsing process, and populate members with parsed value.
@@ -1691,7 +2236,7 @@
cdir = os.path.abspath(os.path.dirname(""))
if len(sys.argv) > 1:
try:
- opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type=", "memory=", "lk"])
+ opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type=", "memory=", "lk", "skip_4k_nand", "atf", "qcn6122"])
except GetoptError, e:
raise UsageError(e.msg)
@@ -1720,6 +2265,14 @@
elif option =="--lk":
lk = "true"
+ elif option =="--atf":
+ atf = "true"
+
+ elif option =="--skip_4k_nand":
+ skip_4k_nand = "true"
+
+ elif option == "--qcn6122":
+ qcn6122 = "true"
#Verify Arguments passed by user
@@ -1743,7 +2296,7 @@
if self.flash_type == None:
self.flash_type = ArgParser.DEFAULT_TYPE
for flash_type in self.flash_type.split(","):
- if flash_type not in [ "nand", "nor", "tiny-nor", "emmc", "norplusnand", "norplusemmc" ]:
+ if flash_type not in [ "nand", "nor", "tiny-nor", "emmc", "norplusnand", "norplusemmc", "tiny-nor-debug" ]:
raise UsageError("invalid flash type '%s'" % flash_type)
# Verify src Path
@@ -1771,7 +2324,7 @@
print "options:"
print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64/ipq6018/ipq6018_64/ipq5018/ipq5018_64]"
print
- print " --fltype \tFlash Type [nor/tiny-nor/nand/emmc/norplusnand/norplusemmc]"
+ print " --fltype \tFlash Type [nor/tiny-nor/nand/emmc/norplusnand/norplusemmc/tiny-nor-debug]"
print " \t\tMultiple flashtypes can be passed by a comma separated string"
print " \t\tDefault is all. i.e If \"--fltype\" is not passed image for all the flash-type will be created.\n"
print " --srcPath \tPath to the directory containg the meta scripts and configs"
@@ -1785,6 +2338,8 @@
print " \t\tIf specified, CDTs created with specified memory size will be used for single-image.\n"
print
print " --lk \t\tReplace u-boot with lkboot for appsbl"
+ print " --atf \t\tReplace tz with atf for QSEE partition"
+ print " --skip_4k_nand \tskip generating 4k nand images"
print " \t\tThis Argument does not take any value"
print "Pack Version: %s" % version
@@ -1818,8 +2373,17 @@
BASE_ADDR = "0x41000000"
src = parser.images_dname + "/qcom-" + BOARD_NAME + ".dtb"
+
+ #alternate name(alt_src) for linux-5.4 dtbs
+ alt_src = parser.images_dname + "/" + BOARD_NAME + ".dtb"
+ if ARCH_NAME == "ipq807x":
+ alt_src = parser.images_dname + "/ipq8074-hk01.dtb"
+
if not os.path.exists(src):
- error("%s file not found" % src)
+ if os.path.exists(alt_src):
+ src = alt_src
+ else:
+ error("%s file not found" % src)
copy(src, TMP_DIR)
src = parser.images_dname + "/Image"
@@ -1859,6 +2423,8 @@
Created to avoid polluting the global namespace.
"""
+
+ global tiny_16m
try:
parser = ArgParser()
parser.parse(sys.argv)
@@ -1874,18 +2440,25 @@
config = SRC_DIR + "/" + ARCH_NAME + "/config.xml"
root = ET.parse(config)
-# Add nand-4k flash type, if nand flash type is specified
- if "nand" in parser.flash_type.split(","):
- if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
- parser.flash_type = parser.flash_type + ",nand-4k"
+ if skip_4k_nand != "true":
+ # Add nand-4k flash type, if nand flash type is specified
+ if "nand" in parser.flash_type.split(","):
+ if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
+ parser.flash_type = parser.flash_type + ",nand-4k"
-# Add norplusnand-4k flash type, if norplusnand flash type is specified
- if "norplusnand" in parser.flash_type.split(","):
- if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
- parser.flash_type = parser.flash_type + ",norplusnand-4k"
+ # Add norplusnand-4k flash type, if norplusnand flash type is specified
+ if "norplusnand" in parser.flash_type.split(","):
+ if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
+ parser.flash_type = parser.flash_type + ",norplusnand-4k"
# Format the output image name from Arch, flash type and mode
for flash_type in parser.flash_type.split(","):
+
+ if ARCH_NAME == "ipq5018" and (flash_type == "tiny-nor" or flash_type == "tiny-nor-debug"):
+ tiny_16m = "true"
+ else:
+ tiny_16m = "false"
+
if image_type == "hlos":
if MODE == "64":
parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + "-apps.img"
diff --git a/tools/squashfs_to_array.sh b/tools/squashfs_to_array.sh
new file mode 100644
index 0000000..8ec8041
--- /dev/null
+++ b/tools/squashfs_to_array.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+######################################################################
+# Copyright (c) 2020 The Linux Foundation. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 and
+# only version 2 as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#####################################################################
+
+unsquashfs -d tmp bt_fw_patch_squashfs.img
+echo "" > bt_binary_array.h
+for entry in ./tmp/image/*
+do
+ echo "$entry"
+ file_name=${entry##*/}
+ file_name="${file_name//./}"
+
+ echo "unsigned char $file_name[] = {" >> bt_binary_array.h
+ hexdump -v -e '15/1 "0x%02X, " 1/1 " 0x%02X,\n"' $entry | sed 's/\, 0x .*//' >> bt_binary_array.h
+
+ echo "};" >> bt_binary_array.h
+done
+
+rm -rf ./tmp