Merge remote-tracking branch 'origin/win.coretech.1.0'

Change-Id: I7d23f9025357d5f0a1fe46dd30c906f938bab240
Signed-off-by: c_nguruj <dharilak@codeaurora.org>
This commit is contained in:
c_nguruj 2020-12-24 17:11:49 +05:30
commit c731f6790a
64 changed files with 3240 additions and 316 deletions

View file

@ -104,6 +104,9 @@ menu "Boot images"
config SUPPORT_SPL
bool
config COMPRESSED_DTB_BASE
hex
config SUPPORT_TPL
bool

View file

@ -556,6 +556,12 @@ else
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 @@ libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
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 @@ ifneq ($(CONFIG_SYS_TEXT_BASE),)
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) \
@ -890,6 +910,11 @@ u-boot.bin: u-boot FORCE
$(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) $< $@
@ -1204,6 +1229,23 @@ quiet_cmd_u-boot__ ?= LD $@
--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) | \
@ -1211,7 +1253,7 @@ cmd_smap = \
$(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)
@ -1228,10 +1270,16 @@ $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
# 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
@ -1346,6 +1394,13 @@ cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
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)

View file

@ -450,8 +450,12 @@ int qca_scm_fuseipq(u32 svc_id, u32 cmd_id, void *buf, size_t len)
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 @@ int qca_scm_secure_authenticate(void *cmd_buf, size_t cmd_len)
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 @@ int qca_scm_secure_authenticate(void *cmd_buf, size_t cmd_len)
}
#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 @@ int qca_scm_sdi(void)
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;

View file

@ -508,7 +508,7 @@ unsigned int get_rootfs_active_partition(void)
return 0; /* alt partition not available */
}
#ifdef CONFIG_CMD_NAND
/*
* get nand block size by device id.
* dev_id is 0 for parallel nand.
@ -522,16 +522,20 @@ uint32_t get_nand_block_size(uint8_t dev_id)
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)
@ -539,9 +543,13 @@ static inline uint32_t get_flash_block_size(char *name,
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,
@ -577,6 +585,52 @@ unsigned int get_partition_table_offset(void)
return primary_mibib;
}
/*
* 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
@ -611,8 +665,13 @@ int smem_getpart(char *part_name, uint32_t *start, uint32_t *size)
* 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;
}
@ -885,8 +944,12 @@ void qca_smem_part_to_mtdparts(char *mtdid, int len)
* 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;
}
@ -957,8 +1020,12 @@ int getpart_offset_size(char *part_name, uint32_t *offset, uint32_t *size)
* 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;
}
@ -1110,8 +1177,12 @@ int do_smeminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* 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;
}

View file

@ -65,13 +65,21 @@ 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.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 \

View file

@ -0,0 +1,40 @@
/*
* 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 <config.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SECTIONS
{
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
*(.text*)
}
#ifdef CONFIG_OF_COMBINE
. = ALIGN(4);
.dtb : {
KEEP(*(.dtb.combine*));
}
#endif
. = ALIGN(4);
}

View file

@ -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

View file

@ -59,7 +59,7 @@
gmac_cfg {
ext_mdio_gpio = <36 37>;
gephy_led = <46>;
gephy_led = <30>;
gmac1_cfg {
unit = <0>;

View file

@ -127,6 +127,16 @@
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 {

View file

@ -120,6 +120,19 @@
};
};
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>;
@ -128,6 +141,11 @@
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>;

View file

@ -59,7 +59,7 @@
gmac_cfg {
ext_mdio_gpio = <36 37>;
gephy_led = <46>;
gephy_led = <30>;
gmac1_cfg {
unit = <0>;

View file

@ -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>;
};
};
};

View file

@ -113,9 +113,19 @@
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 {
gmac_cfg {
ext_mdio_gpio = <36 37>;
gephy_led = <46>;

View file

@ -126,6 +126,19 @@
};
};
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>;
@ -134,6 +147,11 @@
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>;

View file

@ -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";
};

View file

@ -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";
};

View file

@ -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.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_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>;
};
};
};

View file

@ -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";
};
};

View file

@ -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";
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_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>;
};
};
};

View file

@ -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";
};
};

View file

@ -44,26 +44,26 @@
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
drvstr = <GPIO_2MA>;
};
blsp0_spi_mosi {
gpio = <11>;
func = <1>;
pull = <GPIO_NO_PULL>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
drvstr = <GPIO_2MA>;
};
blsp0_spi_miso {
gpio = <12>;
func = <1>;
pull = <GPIO_NO_PULL>;
drvstr = <GPIO_8MA>;
drvstr = <GPIO_2MA>;
};
blsp0_spi_cs {
gpio = <13>;
func = <1>;
oe = <GPIO_OE_ENABLE>;
drvstr = <GPIO_8MA>;
drvstr = <GPIO_2MA>;
};
};
};

View file

@ -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";
};

View file

@ -14,6 +14,7 @@
#ifndef IPQ5018_CLK_H
#define IPQ5018_CLK_H
#define CLK_ENABLE 0x1
/* I2C clocks configuration */
#ifdef CONFIG_IPQ5018_I2C
@ -26,8 +27,14 @@
#define CMD_UPDATE 0x1
#define ROOT_EN 0x2
#define CLK_ENABLE 0x1
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*/

View file

@ -17,14 +17,28 @@
#include <net.h>
#include <configs/ipq5018.h>
#define LINK(_data) (_data & 0x400)? "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 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 0x1302
#define S17C_VERSION 0x1302
#define QCA_8337 0x004DD036
#define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ)
#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ)
@ -248,6 +262,7 @@ struct ipq_eth_dev {
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];

View file

@ -105,6 +105,7 @@ void aquantia_phy_reset_init(void);
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 */

View file

@ -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 @@ extern int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len);
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 @@ int is_scm_sec_auth_available(u32 svc_id, u32 cmd_id);
#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

View file

@ -61,6 +61,7 @@ int smem_get_boot_flash(uint32_t *flash_type,
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);

View file

@ -214,9 +214,11 @@ int board_init(void)
#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();
@ -352,11 +354,17 @@ void board_flash_protect(void)
}
#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;
@ -384,6 +392,10 @@ int board_late_init(void)
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

View file

@ -849,8 +849,11 @@ static int do_bootipq(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
ret = qca_scm_call(SCM_SVC_FUSE, QFPROM_IS_AUTHENTICATE_CMD, &buf, sizeof(char));
aquantia_phy_reset_init_done();
if (ret == 0 && buf == 1) {
/*
|| if atf is enable in env ,do_boot_signedimg is skip.
|| Note: This features currently support in ipq50XX.
*/
if (ret == 0 && buf == 1 && !getenv("atf")) {
ret = do_boot_signedimg(cmdtp, flag, argc, argv);
} else if (ret == 0 || ret == -EOPNOTSUPP) {
ret = do_boot_unsignedimg(cmdtp, flag, argc, argv);

View file

@ -97,6 +97,8 @@ struct crashdump_flash_nand_cxt {
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
@ -748,6 +750,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
* and erases the required sectors
@ -755,10 +849,14 @@ reset:
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;
@ -769,16 +867,6 @@ int init_crashdump_nand_flash_write(void *cnxt, loff_t offset,
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;
}
@ -803,9 +891,11 @@ int deinit_crashdump_nand_flash_write(void *cnxt)
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;
@ -853,15 +943,14 @@ int crashdump_nand_flash_write_data(void *cnxt,
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
@ -871,17 +960,16 @@ int crashdump_nand_flash_write_data(void *cnxt,
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;

View file

@ -128,4 +128,28 @@ int board_mmc_env_init(qca_mmc mmc_host)
}
return ret;
}
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);
}
}
#endif

View file

@ -62,6 +62,7 @@ int get_eth_mac_address(uchar *enetaddr, uint no_of_macs)
#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
@ -100,16 +101,17 @@ int get_eth_mac_address(uchar *enetaddr, uint no_of_macs)
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, img_size, image_buf, &img_size);
ret = gunzip(load_buf, desMaxSize, image_buf, &img_size);
#endif
#ifdef CONFIG_LZMA
if (ret != 0)
ret = lzmaBuffToBuffDecompress(load_buf,
(SizeT *)&img_size,
(SizeT *)&desMaxSize,
image_buf,
(SizeT)img_size);
#endif

View file

@ -16,6 +16,8 @@
#include <asm/arch-qca-common/scm.h>
#include <jffs2/load_kernel.h>
#include <fdtdec.h>
#include <stdlib.h>
#include "fdt_info.h"
DECLARE_GLOBAL_DATA_PTR;
@ -647,60 +649,148 @@ static int ipq40xx_patch_eth_params(void *blob, unsigned long gmac_no)
}
#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;
@ -771,6 +861,11 @@ __weak void fdt_fixup_wcss_rproc_for_atf(void *blob)
return;
}
__weak void fdt_fixup_art_format(void *blob)
{
return;
}
__weak void fdt_fixup_bt_debug(void *blob)
{
return;
@ -781,6 +876,41 @@ __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);
}
}
/*
* For newer kernel that boot with device tree (3.14+), all of memory is
* described in the /memory node, including areas that the kernel should not be
@ -867,6 +997,7 @@ int ft_board_setup(void *blob, bd_t *bd)
setenv("mtdparts", mtdparts);
}
set_mtdids();
debug("MTDIDS: %s\n", getenv("mtdids"));
#ifdef CONFIG_IPQ_TINY
ipq_nor_fdt_fixup(blob, nodes);
@ -921,6 +1052,11 @@ int ft_board_setup(void *blob, bd_t *bd)
if (s) {
fdt_fixup_bt_debug(blob);
}
/*
|| This features fixup compressed_art in
|| dts if its 16M profile build.
*/
fdt_fixup_art_format(blob);
#ifdef CONFIG_QCA_MMC
board_mmc_deinit();

View file

@ -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 @@ void ipq_uboot_fdt_fixup(void)
return;
}
int get_soc_hw_version(void)
{
return readl(TCSR_SOC_HW_VERSION_REG);
}

View file

@ -2,4 +2,5 @@ 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

208
board/qca/arm/ipq5018/bt.h Normal file
View file

@ -0,0 +1,208 @@
/*
* 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);
#endif /* _BT_H */

View file

@ -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);
}

View file

@ -35,3 +35,9 @@ void i2c_clock_config(void)
}
#endif
#ifdef CONFIG_IPQ_BT_SUPPORT
void enable_btss_lpo_clk(void)
{
writel(CLK_ENABLE, GCC_BTSS_LPO_CBCR);
}
#endif

View file

@ -32,9 +32,16 @@
#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 DLOAD_DISABLED 0x40
#define TCSR_SOC_HW_VERSION_REG 0x194D000
ipq_gmac_board_cfg_t gmac_cfg[CONFIG_IPQ_NO_MACS];
@ -44,7 +51,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct sdhci_host mmc_host;
#endif
#ifdef CONFIG_IPQ_MTD_NOR
#ifdef CONFIG_MTD_DEVICE
extern int ipq_spi_init(u16);
#endif
@ -80,6 +87,18 @@ struct dumpinfo_t dumpinfo_n[] = {
* ------------------------
*/
{ "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 },
@ -94,6 +113,11 @@ 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 },
@ -357,16 +381,6 @@ __weak int ipq_get_tz_version(char *version_name, int buf_size)
return 1;
}
int apps_iscrashed_crashdump_disabled(void)
{
u32 *dmagic = (u32 *)CONFIG_IPQ5018_DMAGIC_ADDR;
if (*dmagic == DLOAD_DISABLED)
return 1;
return 0;
}
int apps_iscrashed(void)
{
u32 *dmagic = (u32 *)CONFIG_IPQ5018_DMAGIC_ADDR;
@ -469,6 +483,186 @@ void fdt_fixup_auto_restart(void *blob)
return;
}
#ifdef CONFIG_IPQ_BT_SUPPORT
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);
return 0;
}
#endif
void reset_crashdump(void)
{
unsigned int ret = 0;
@ -580,12 +774,15 @@ void board_nand_init(void)
}
#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_IPQ_MTD_NOR
#ifdef CONFIG_MTD_DEVICE
ipq_spi_init(CONFIG_IPQ_SPI_NOR_INFO_IDX);
#endif
}
@ -853,9 +1050,19 @@ static void gmac_reset(void)
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);
@ -958,6 +1165,13 @@ static void gcc_clock_enable(void)
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)
@ -1022,6 +1236,9 @@ int board_eth_init(bd_t *bis)
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){
@ -1077,7 +1294,7 @@ void set_flash_secondary_type(qca_smem_flash_info_t *smem)
#ifdef CONFIG_USB_XHCI_IPQ
void board_usb_deinit(int id)
{
int nodeoff, ssphy;
int nodeoff, ssphy, gpio_node;
char node_name[8];
if(readl(EUD_EUD_EN2))
@ -1112,6 +1329,24 @@ void board_usb_deinit(int id)
/* 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);
writel(0xC1, gpio_base);
}
}
}
static void usb_clock_init(int id, int ssphy)
@ -1174,8 +1409,20 @@ static void usb_clock_init(int id, int ssphy)
writel(CLK_ENABLE, GCC_USB0_LFPS_CBCR);
}
static void usb_init_hsphy(void __iomem *phybase)
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 */
@ -1245,12 +1492,12 @@ static void usb_init_phy(int index, int ssphy)
if (ssphy)
usb_init_ssphy((u32 *)USB3PHY_APB_BASE);
usb_init_hsphy((u32 *)QUSB2PHY_BASE);
usb_init_hsphy((u32 *)QUSB2PHY_BASE, ssphy);
}
int ipq_board_usb_init(void)
{
int i, nodeoff, ssphy;
int i, nodeoff, ssphy, gpio_node;
char node_name[8];
if(readl(EUD_EUD_EN2)) {
@ -1276,6 +1523,15 @@ int ipq_board_usb_init(void)
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);
}
return 0;
}
#endif
@ -1584,19 +1840,6 @@ void board_pci_deinit()
}
#endif
void fdt_fixup_wcss_rproc_for_atf(void *blob)
{
/*
* Set q6 in non-secure mode only if ATF is enable
*/
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);
/*
* Set btss in non-secure mode only if ATF is enable
*/
parse_fdt_fixup("/soc/bt@7000000%qcom,nosecure%1", blob);
}
void fdt_fixup_qpic(void *blob)
{
int node_off, ret;
@ -1633,7 +1876,7 @@ void fdt_fixup_bt_debug(void *blob)
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) {
if (node >= 0) {
phandle = fdtdec_get_int(blob, node, "phandle", 0);
snprintf(node_name,
sizeof(node_name),
@ -1643,10 +1886,22 @@ void fdt_fixup_bt_debug(void *blob)
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)
{
@ -1705,3 +1960,13 @@ int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg)
return 0;
}
#endif
int get_soc_hw_version(void)
{
return readl(TCSR_SOC_HW_VERSION_REG);
}
void sdi_disable(void)
{
qca_scm_sdi();
}

View file

@ -52,6 +52,13 @@
#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
@ -227,6 +234,10 @@
#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)
@ -483,6 +494,7 @@ typedef struct {
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];
@ -580,4 +592,56 @@ typedef enum {
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 50000
int bt_init(void);
#endif
#endif /* _IPQ5018_CDP_H_ */

View file

@ -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);
@ -1048,7 +1051,7 @@ void set_function_select_as_mdc_mdio(void)
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);
}
}
}
@ -1374,3 +1377,8 @@ void fdt_fixup_wcss_rproc_for_atf(void *blob)
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);
}

View file

@ -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
@ -1790,20 +1793,6 @@ void run_tzt(void *address)
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();
@ -1884,3 +1873,8 @@ void qgic_init(void)
qgic_dist_init();
qgic_cpu_init();
}
int get_soc_hw_version(void)
{
return readl(TCSR_SOC_HW_VERSION_REG);
}

View file

@ -141,9 +141,7 @@ obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
obj-$(CONFIG_MP) += cmd_mp.o
obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
ifndef CONFIG_IPQ_TINY
obj-$(CONFIG_CMD_NAND) += cmd_nand.o
endif
obj-$(CONFIG_CMD_NET) += cmd_net.o
obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
obj-$(CONFIG_CMD_OTP) += cmd_otp.o

View file

@ -842,12 +842,15 @@ static init_fnc_t init_sequence_f[] = {
#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()? */

View file

@ -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 @@ U_BOOT_CMD(
"AES 128 CBC encryption",
aes_help_text
);
#endif

View file

@ -202,8 +202,9 @@ char * const argv[])
#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 @@ char * const argv[])
}
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 @@ char * const argv[])
if (adj_size)
file_size = file_size + (nand->writesize - adj_size);
}
#endif
if (flash_type == SMEM_BOOT_MMC_FLASH) {
if (disk_info.blksz) {

View file

@ -3261,17 +3261,34 @@ int mALLOPt(param_number, value) int param_number; int value;
}
}
#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:

View file

@ -76,12 +76,18 @@ int saveenv(void)
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 @@ void env_relocate_spec(void)
}
env_import(buf, 1);
free(buf);
return;
err_env_relocate:
set_default_env(NULL);
if (buf)
free(buf);
}

View file

@ -139,15 +139,21 @@ static unsigned char env_flags;
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 @@ int mmc_saveenv(void)
fini:
fini_mmc_for_env(mmc);
free(env_new);
return ret;
}
#endif /* CONFIG_CMD_SAVEENV */
@ -298,12 +305,17 @@ err:
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 @@ fini:
err:
if (ret)
set_default_env(errmsg);
if (buf)
free(buf);
#endif
}
#endif /* CONFIG_ENV_OFFSET_REDUND */

View file

@ -183,7 +183,6 @@ static unsigned char env_flags;
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 @@ int nand_saveenv(void)
#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 @@ int nand_saveenv(void)
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 @@ int nand_saveenv(void)
printf("Warning: primary env write failed,"
" redundancy is lost!\n");
#endif
free(env_new);
return ret;
}
#endif /* CMD_SAVEENV */
@ -385,7 +394,13 @@ void nand_env_relocate_spec(void)
{
#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 @@ void nand_env_relocate_spec(void)
printf("Found Environment offset in OOB..\n");
} else {
set_default_env("!no env offset in OOB");
free(buf);
return;
}
#endif
@ -404,10 +420,12 @@ void nand_env_relocate_spec(void)
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 */

View file

@ -81,14 +81,21 @@ int saveenv(void)
#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 @@ int saveenv(void)
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 @@ void env_relocate_spec(void)
#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 @@ void env_relocate_spec(void)
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 */

View file

@ -230,7 +230,7 @@ CONFIG_QPIC_SERIAL=y
# CONFIG_DM_ETH is not set
# CONFIG_PHYLIB is not set
# CONFIG_NETDEVICES is not set
CONFIG_IPQ_MTD_NOR=y
# CONFIG_IPQ_MTD_NOR is not set
# CONFIG_IPQ_TINY_SPI_NOR is not set
#
@ -331,3 +331,5 @@ CONFIG_LZMA=y
# CONFIG_ERRNO_STR is not set
# CONFIG_UNIT_TEST is not set
CONFIG_SYS_THUMB_BUILD=y
CONFIG_HAS_THUMB2=y

View file

@ -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

View file

@ -25,8 +25,8 @@ CONFIG_IPQ_TINY=y
#
# Info commands
#
CONFIG_CMD_BDI=y
CONFIG_CMD_CONSOLE=y
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
#
# Boot commands
@ -44,7 +44,7 @@ CONFIG_CMD_RUN=y
#
CONFIG_CMD_EXPORTENV=y
CONFIG_CMD_IMPORTENV=y
CONFIG_CMD_EDITENV=y
# CONFIG_CMD_EDITENV is not set
CONFIG_CMD_SAVEENV=y
CONFIG_CMD_ENV_EXISTS=y
@ -66,7 +66,7 @@ CONFIG_CMD_CRC32=y
# CONFIG_CMD_DEMO is not set
# CONFIG_CMD_LOADB is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_FLASH=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_NAND is not set
# CONFIG_CMD_SF is not set
# CONFIG_CMD_SPI is not set

View file

@ -130,7 +130,7 @@ static int ipq_spi_block_markbad(struct mtd_info *mtd, loff_t offs)
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,
@ -163,14 +163,14 @@ int ipq_spi_init(u16 idx)
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;
}

View file

@ -27,9 +27,6 @@ else # not spl
NORMAL_DRIVERS=y
ifdef CONFIG_IPQ_TINY
obj-y += nand.o
else
obj-y += nand.o
obj-y += nand_bbt.o
obj-y += nand_ids.o
@ -37,7 +34,7 @@ obj-y += nand_util.o
obj-y += nand_ecc.o
obj-y += nand_base.o
obj-y += nand_timings.o
endif
endif # not spl
ifdef NORMAL_DRIVERS

View file

@ -123,11 +123,7 @@ struct qpic_serial_nand_params *serial_params;
* training pattern.
*/
static const unsigned int training_block_128[] = {
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
static const unsigned int training_block_64[] = {
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F,
@ -3838,6 +3834,7 @@ nand_result_t qpic_nand_blk_erase(struct mtd_info *mtd, uint32_t page)
* 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);
@ -4126,7 +4123,7 @@ static int qpic_execute_serial_training(struct mtd_info *mtd)
unsigned int start, blk_cnt = 0;
unsigned int offset, pageno, curr_freq;
int size = sizeof(training_block_128);
int i;
unsigned int io_macro_freq_tbl[] = {24000000, 100000000, 200000000, 320000000};
unsigned char *data_buff, trained_phase[TOTAL_NUM_PHASE] = {'\0'};
@ -4180,15 +4177,16 @@ static int qpic_execute_serial_training(struct mtd_info *mtd)
goto err;
}
data_buff = (unsigned char *)malloc(size);
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, size);
memcpy(data_buff, training_block_128, size);
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;
@ -4200,7 +4198,7 @@ static int qpic_execute_serial_training(struct mtd_info *mtd)
memset(dev->pad_oob, 0xFF, dev->oob_per_page);
ops.mode = MTD_OPS_AUTO_OOB;
ops.len = size;
ops.len = mtd->writesize;
ops.retlen = 0;
ops.ooblen = dev->oob_per_page;
ops.oobretlen = 0;
@ -4212,24 +4210,26 @@ static int qpic_execute_serial_training(struct mtd_info *mtd)
ret = qpic_nand_write_page(mtd, pageno, NAND_CFG, &ops);
if (ret) {
printf("Error in writing training data..\n");
goto err;
goto free;
}
/* After write verify the the data with read @ lower frequency
* after that only start serial tarining @ higher frequency
*/
memset(data_buff, 0xff, size);
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.\n",__func__);
goto err;
printf("%s : Read training data failed before training start\n",__func__);
goto free;
}
/* compare original data and read data */
if (memcmp(data_buff, training_block_128, size)) {
printf("Training data read failed @ lower frequency\n");
goto err;
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 */
@ -4251,26 +4251,24 @@ rettry:
/* set the phase */
qpic_set_phase(phase);
memset(data_buff, 0, size);
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 err;
goto free;
}
/* compare original data and read data */
if (memcmp(data_buff, training_block_128, size)) {
/* wrong data read on one of miso line
* change the phase value and try again
*/
phase_failed++;
} else {
/* we got good phase update the good phase list
*/
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);
@ -4504,11 +4502,11 @@ void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg)
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)) {
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,
NAND_QSPI_MSTR_CONFIG);
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,

View file

@ -173,7 +173,7 @@ int athrs17_init_switch(void)
data = athrs17_reg_read(S17_MASK_CTRL_REG);
i++;
if (i == 10){
printf("Failed to reset S17C \n");
printf("QCA_8337: Failed to reset\n");
return -1;
}
} while (data & S17_MASK_CTRL_SOFT_RET);

View file

@ -38,6 +38,7 @@ 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);
@ -316,9 +317,14 @@ static int ipq5018_s17c_Link_Update(struct ipq_eth_dev *priv)
priv->gmac_board_cfg->switch_port_phy_address[i],
0x11,
NULL);
if (phy_data == 0x50)
continue;
status = 0;
/* 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)){
@ -349,22 +355,19 @@ static int ipq5018_phy_link_update(struct eth_device *dev)
int speed_clock1 = 0, speed_clock2 = 0;
int mode = PORT_WRAPPER_SGMII0_RGMII4;
if (priv->ipq_swith == 0) {
phy_get_ops = priv->ops;
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)) {
printf ("Link status/Get speed/Get duplex not mapped\n");
return -1;
}
}
phy_get_ops = priv->ops;
if (priv->ipq_swith) {
speed_clock1 = 1;
speed_clock2 = 0;
status = ipq5018_s17c_Link_Update(priv);
} else {
}
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,
@ -373,51 +376,53 @@ static int ipq5018_phy_link_update(struct eth_device *dev)
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;
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;
}
@ -592,6 +597,118 @@ static void ipq_eth_halt(struct eth_device *dev)
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];
@ -601,6 +718,9 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
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);
@ -656,80 +776,35 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
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]->ipq_swith = gmac_cfg->ipq_swith;
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);
phy_chip_id = -1;
if (gmac_cfg->unit){
ret = ipq_sw_mdio_init(ipq_gmac_macs[i]->phy_name);
if (ret)
goto init_failed;
if (ipq_gmac_macs[i]->ipq_swith){
/* S17C switch Id */
phy_chip_id = S17C;
for (int port = 0;
port < gmac_cfg->switch_port_count;
++port) {
u32 phy_val;
/* phy powerdown */
ipq_mdio_write(port, 0x0, 0x0800);
phy_val = ipq_mdio_read(port, 0x3d, NULL);
phy_val &= ~0x0040;
ipq_mdio_write(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(port, 0xb, NULL);
phy_val &= ~0x2400;
ipq_mdio_write(port, 0xb, phy_val);
mdelay(100);
}
if (ipq_athrs17_init(gmac_cfg) != 0){
printf("S17C switch init failed port \n");
}
for (int port = 0;
port < gmac_cfg->switch_port_count;
++port) {
ipq_mdio_write(port, MII_ADVERTISE, ADVERTISE_ALL |
ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
/*
* phy reg 0x9, b10,1 = Prefer multi-port device (master)
*/
ipq_mdio_write(port, MII_CTRL1000, (0x0400|ADVERTISE_1000FULL));
ipq_mdio_write(port, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
mdelay(100);
}
} else {
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;
}
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 {
ret = ipq5018_sw_mdio_init(ipq_gmac_macs[i]->phy_name);
if (ret)
goto init_failed;
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_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
*/
/* NAPA PHY For GMAC1 */
case QCA8081_PHY:
case QCA8081_1_1_PHY:
ipq_gmac_macs[i]->phy_type = QCA8081_1_1_PHY;
@ -738,19 +813,17 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
ipq_gmac_macs[i]->phy_address);
break;
#endif
/*
* Internel GEPHY only for GMAC0
*/
/* 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
*/
/* 1G PHY */
case QCA8033_PHY:
ipq_gmac_macs[i]->phy_type = QCA8033_PHY;
ipq_qca8033_phy_init(
@ -758,21 +831,29 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
ipq_gmac_macs[i]->phy_address);
break;
#endif
case S17C:
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);
printf("GMAC%d:Invalid PHY ID \n", i);
break;
}
/*
* Tx/Rx Descriptor initialization
*/
/* 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:

View file

@ -96,7 +96,7 @@
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE + 0x4 + (x)*0x1000)
#define CONFIG_SYS_SDRAM_BASE 0x40000000
#define CONFIG_SYS_TEXT_BASE 0x4A900000
#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))
@ -107,12 +107,16 @@
#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
@ -134,7 +138,7 @@ extern loff_t board_env_size;
#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 + (1024 << 10))
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE_MAX + (500 << 10))
/*
* NAND Flash Configs
@ -144,11 +148,11 @@ extern loff_t board_env_size;
* CONFIG_IPQ_NAND: QPIC NAND in FIFO/block mode.
* BAM is enabled by default.
*/
#define CONFIG_CMD_NAND
#define CONFIG_SYS_NAND_SELF_INIT
#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
@ -232,7 +236,6 @@ extern loff_t board_env_size;
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_MII
#define CONFIG_CMD_MII
#define CONFIG_IPADDR 192.168.10.10
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.10.19
@ -319,13 +322,29 @@ extern loff_t board_env_size;
#define NUM_ALT_PARTITION 16
#ifndef CONFIG_IPQ_TINY
#ifdef CONFIG_IPQ_TINY
/* undef gzip lib */
#undef CONFIG_GZIP
#undef CONFIG_ZLIB
#else
#define CONFIG_CMD_BOOTZ
#define CONFIG_CMD_CACHE
/*
* Multicore CPU support
*/
/* 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
@ -388,10 +407,10 @@ extern loff_t board_env_size;
#undef CONFIG_BOOTM_VXWORKS
#ifdef CONFIG_ART_COMPRESSED
#undef CONFIG_GZIP
#undef CONFIG_ZLIB
/*
* CONFIG_COMPRESSED_LOAD_ADDR loads the compressed data for uncompress action
* 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
@ -400,4 +419,12 @@ extern loff_t board_env_size;
#define NR_CPUS 2
#endif
/*
* 96 MHz
*/
#define INTERNAL_96MHZ
/*#define CONFIG_IPQ_BT_SUPPORT*/
#endif /* _IPQ5018_H */

View file

@ -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

View file

@ -909,6 +909,9 @@ void *realloc_simple(void *ptr, size_t size);
/* 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 */

View file

@ -1216,19 +1216,58 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index,
}
#ifdef CONFIG_OF_COMBINE
#ifdef CONFIG_COMPRESSED_DTB_BASE
extern unsigned long __dtb_blob_begin;
extern unsigned long __dtb_blob_end;
static uint32_t uncompress_gzipped_dtb(unsigned long dest_ddr_addr)
{
uint32_t size;
unsigned long compressed_len;
unsigned long dtb_begin;
unsigned long dtb_end;
dtb_begin = (unsigned long)&__dtb_blob_begin;
dtb_end = (unsigned long)&__dtb_blob_end;
size = CONFIG_COMPRESSED_DTB_MAX_SIZE;
compressed_len = dtb_end - dtb_begin;
if (gunzip((void *)dest_ddr_addr, size, (unsigned char *)dtb_begin, &compressed_len) != 0 )
hang();
else
debug("Unzipping compressed DTB's success\n");
return compressed_len;
}
# else
extern unsigned long __dtb_table_start;
#endif
struct dtb_combined_hdr {
unsigned long machid;
unsigned long dtbaddr;
};
static int parse_combined_fdt(unsigned long machid)
{
unsigned long *ptr = NULL;
struct dtb_combined_hdr *fdt_table;
unsigned long ndtbs = 0;
#ifdef CONFIG_COMPRESSED_DTB_BASE
uint32_t size, uncompressed_size;
unsigned long dtb_end, dtb_begin, dtb_base;
unsigned long pgtable_base;
uncompressed_size = uncompress_gzipped_dtb(CONFIG_COMPRESSED_DTB_BASE);
ptr = (void *)CONFIG_COMPRESSED_DTB_BASE;
# else
ptr = &__dtb_table_start;
#endif
ndtbs = *ptr;
ptr++;
@ -1243,7 +1282,28 @@ static int parse_combined_fdt(unsigned long machid)
if(ndtbs == 0)
hang();
#ifdef CONFIG_COMPRESSED_DTB_BASE
dtb_begin = fdt_table->dtbaddr;
if (ndtbs == 1) {
size = CONFIG_COMPRESSED_DTB_BASE + uncompressed_size - dtb_begin;
} else {
fdt_table++;
dtb_end = fdt_table->dtbaddr;
size = dtb_end - dtb_begin;
}
pgtable_base = CONFIG_SYS_TEXT_BASE + gd->mon_len;
pgtable_base += (0x10000 - 1);
pgtable_base &= ~(0x10000 - 1);
dtb_base = (unsigned long)(pgtable_base + PGTABLE_SIZE) + 0x4; // 0x4 breathing space for overcome overlap.
memcpy((ulong *)dtb_base, (void *)dtb_begin, size);
return dtb_base;
# else
return fdt_table->dtbaddr;
#endif
}
#endif

30
tools/squashfs_to_array.sh Executable file
View file

@ -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