diff --git a/arch/arm/dts/ipq5018-mp03.1.dts b/arch/arm/dts/ipq5018-mp03.1.dts index 8cb97f53c5..5e3359e506 100644 --- a/arch/arm/dts/ipq5018-mp03.1.dts +++ b/arch/arm/dts/ipq5018-mp03.1.dts @@ -108,6 +108,11 @@ }; }; }; + + usb0: xhci@8a00000 { + ssphy = <1>; + }; + gmac_cfg { ext_mdio_gpio = <36 37>; gephy_led = <46>; diff --git a/arch/arm/dts/ipq807x-hk10.dts b/arch/arm/dts/ipq807x-hk10.dts index c9d3f7d04f..7c47d22bf0 100644 --- a/arch/arm/dts/ipq807x-hk10.dts +++ b/arch/arm/dts/ipq807x-hk10.dts @@ -28,9 +28,11 @@ ess-switch { switch_mac_mode = <0x0>; switch_mac_mode1 = <0x2>; - switch_mac_mode2 = <0x6>; + switch_mac_mode2 = <0x7>; aquantia_port = <4>; aquantia_gpio = <44>; + sfp_port = <5>; + sfp_gpio = <59>; port_phyinfo { port@0 { phy_address = <0>; @@ -52,6 +54,10 @@ phy_address = <7>; phy_type = <3>; }; + port@5 { + phy_address = <30>; + phy_type = <5>; + }; }; }; }; diff --git a/arch/arm/dts/ipq807x-hk14.dts b/arch/arm/dts/ipq807x-hk14.dts index e4d7dfe19d..581af01270 100644 --- a/arch/arm/dts/ipq807x-hk14.dts +++ b/arch/arm/dts/ipq807x-hk14.dts @@ -25,9 +25,9 @@ }; ess-switch { switch_mac_mode = <0x5>; - switch_mac_mode1 = <0x7>; + switch_mac_mode1 = <0xFF>; switch_mac_mode2 = <0x2>; - aquantia_port = <4>; + aquantia_port = <5>; aquantia_gpio = <44>; port_phyinfo { port@0 { @@ -47,9 +47,14 @@ phy_type = <1>; }; port@4 { + phy_address = <4>; + phy_type = <1>; + }; + port@5 { phy_address = <7>; phy_type = <3>; }; + }; }; }; diff --git a/board/qca/arm/common/fdt_fixup.c b/board/qca/arm/common/fdt_fixup.c index 6ac9750072..c632c8952e 100644 --- a/board/qca/arm/common/fdt_fixup.c +++ b/board/qca/arm/common/fdt_fixup.c @@ -162,7 +162,162 @@ void ipq_fdt_fixup_version(void *blob) } #endif /* RPM_VERSION */ } +#ifdef CONFIG_IPQ_TINY +#define OFFSET_NOT_SPECIFIED (~0llu) +struct reg_cell { + unsigned int r0; + unsigned int r1; +}; +extern int fdt_del_partitions(void *blob, int parent_offset); + +int parse_nor_partition(const char *const partdef, + const char **ret, + struct part_info **retpart); + +void free_parse(struct list_head *head); + +static void ipq_nor_fdt_fixup(void *blob, struct flash_node_info *ni) +{ + int parent_offset; + struct part_info *part, *pPartInfo; + struct reg_cell cell; + int off, ndepth = 0; + int part_num, ret, newoff; + char buf[64]; + int offset = 0; + struct list_head *pentry; + LIST_HEAD(tmp_list); + const char *pMtdparts = getenv("mtdparts"); + + if (!pMtdparts) + return; + + for (; ni->compat; ni++) { + parent_offset = fdt_node_offset_by_compatible( + blob, -1, ni->compat); + if (parent_offset != -FDT_ERR_NOTFOUND) + break; + } + + if (parent_offset == -FDT_ERR_NOTFOUND){ + printf(" compatible not found \n"); + return; + } + + ret = fdt_del_partitions(blob, parent_offset); + if (ret < 0) + return; + + /* + * Check if it is nand {}; subnode, adjust + * the offset in this case + */ + off = fdt_next_node(blob, parent_offset, &ndepth); + if (off > 0 && ndepth == 1) + parent_offset = off; + + if (strncmp(pMtdparts, "mtdparts=", 9) == 0) { + pMtdparts += 9; + pMtdparts = strchr(pMtdparts, ':'); + pMtdparts++; + } else { + printf("mtdparts variable doesn't start with 'mtdparts='\n"); + return; + } + + part_num = 0; + + while (pMtdparts && (*pMtdparts != '\0') && (*pMtdparts != ';')) { + if ((parse_nor_partition(pMtdparts, &pMtdparts, &pPartInfo) != 0)) + break; + + /* calculate offset when not specified */ + if (pPartInfo->offset == OFFSET_NOT_SPECIFIED) + pPartInfo->offset = offset; + else + offset = pPartInfo->offset; + + offset += pPartInfo->size; + /* partition is ok, add it to the list */ + list_add_tail(&pPartInfo->link, &tmp_list); + } + list_for_each_prev(pentry, &tmp_list) { + + part = list_entry(pentry, struct part_info, link); + + debug("%2d: %-20s0x%08llx\t0x%08llx\t%d\n", + part_num, part->name, part->size, + part->offset, part->mask_flags); + + snprintf(buf, sizeof(buf), "partition@%llx", part->offset); +add_sub: + ret = fdt_add_subnode(blob, parent_offset, buf); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_sub; + else + goto err_size; + } else if (ret < 0) { + printf("Can't add partition node: %s\n", + fdt_strerror(ret)); + return; + } + newoff = ret; + + /* Check MTD_WRITEABLE_CMD flag */ + if (pPartInfo->mask_flags & 1) { +add_ro: + ret = fdt_setprop(blob, newoff, "read_only", NULL, 0); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_ro; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + } + + cell.r0 = cpu_to_fdt32(part->offset); + cell.r1 = cpu_to_fdt32(part->size); +add_reg: + ret = fdt_setprop(blob, newoff, "reg", &cell, sizeof(cell)); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_reg; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + +add_label: + ret = fdt_setprop_string(blob, newoff, "label", part->name); + if (ret == -FDT_ERR_NOSPACE) { + ret = fdt_increase_size(blob, 512); + if (!ret) + goto add_label; + else + goto err_size; + } else if (ret < 0) + goto err_prop; + + part_num++; + } + goto remove_list; +err_size: + printf("Can't increase blob size: %s\n", fdt_strerror(ret)); + goto remove_list; +err_prop: + printf("Can't add property: %s\n", fdt_strerror(ret)); + goto remove_list; +remove_list: + free_parse(&tmp_list); + return; +} +#else void ipq_fdt_fixup_mtdparts(void *blob, struct flash_node_info *ni) { struct mtd_device *dev; @@ -191,6 +346,7 @@ void ipq_fdt_fixup_mtdparts(void *blob, struct flash_node_info *ni) } } } +#endif void ipq_fdt_mem_rsvd_fixup(void *blob) { @@ -641,6 +797,12 @@ int ft_board_setup(void *blob, bd_t *bd) int len = sizeof(parts_str), ret; qca_smem_flash_info_t *sfi = &qca_smem_flash_info; int activepart = 0; +#ifdef CONFIG_IPQ_TINY + struct flash_node_info nodes[] = { + { "n25q128a11", MTD_DEV_TYPE_NAND, + CONFIG_IPQ_SPI_NOR_INFO_IDX } + }; +#else struct flash_node_info nodes[] = { { "qcom,msm-nand", MTD_DEV_TYPE_NAND, 0 }, { "qcom,qcom_nand", MTD_DEV_TYPE_NAND, 0 }, @@ -653,7 +815,7 @@ int ft_board_setup(void *blob, bd_t *bd) { "s25fl256s1", MTD_DEV_TYPE_NAND, 1 }, { NULL, 0, -1 }, /* Terminator */ }; - +#endif fdt_fixup_memory_banks(blob, &memory_start, &memory_size, 1); ipq_fdt_fixup_version(blob); #ifndef CONFIG_QCA_APPSBL_DLOAD @@ -701,7 +863,11 @@ int ft_board_setup(void *blob, bd_t *bd) } debug("MTDIDS: %s\n", getenv("mtdids")); +#ifdef CONFIG_IPQ_TINY + ipq_nor_fdt_fixup(blob, nodes); +#else ipq_fdt_fixup_mtdparts(blob, nodes); +#endif } /* Add "flash_type" to root node of the devicetree*/ diff --git a/board/qca/arm/ipq5018/ipq5018.c b/board/qca/arm/ipq5018/ipq5018.c index 235fddaafe..c539599743 100644 --- a/board/qca/arm/ipq5018/ipq5018.c +++ b/board/qca/arm/ipq5018/ipq5018.c @@ -1073,13 +1073,14 @@ void set_flash_secondary_type(qca_smem_flash_info_t *smem) #ifdef CONFIG_USB_XHCI_IPQ void board_usb_deinit(int id) { - int nodeoff; + int nodeoff, ssphy; char node_name[8]; snprintf(node_name, sizeof(node_name), "usb%d", id); nodeoff = fdt_path_offset(gd->fdt_blob, node_name); if (fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) return; + ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0); /* Enable USB PHY Power down */ setbits_le32(QUSB2PHY_BASE + 0xA4, 0x0); /* Disable clocks */ @@ -1093,19 +1094,22 @@ void board_usb_deinit(int id) /* GCC_QUSB2_0_PHY_BCR */ set_mdelay_clearbits_le32(GCC_QUSB2_0_PHY_BCR, 0x1, 10); /* GCC_USB0_PHY_BCR */ - set_mdelay_clearbits_le32(GCC_USB0_PHY_BCR, 0x1, 10); + if (ssphy) + set_mdelay_clearbits_le32(GCC_USB0_PHY_BCR, 0x1, 10); /* GCC Reset USB BCR */ set_mdelay_clearbits_le32(GCC_USB0_BCR, 0x1, 10); /* Deselect the usb phy mux */ - writel(0x0, TCSR_USB_PCIE_SEL); + if (ssphy) + writel(0x0, TCSR_USB_PCIE_SEL); } -static void usb_clock_init(int id) +static void usb_clock_init(int id, int ssphy) { int cfg; /* select usb phy mux */ - writel(0x1, TCSR_USB_PCIE_SEL); + if (ssphy) + writel(0x1, TCSR_USB_PCIE_SEL); /* Configure usb0_master_clk_src */ cfg = (GCC_USB0_MASTER_CFG_RCGR_SRC_SEL | @@ -1199,10 +1203,12 @@ static void usb_init_ssphy(void __iomem *phybase) /*set fstep*/ writel(0x1, phybase + SSCG_CTRL_REG_1); writel(0xeb, phybase + SSCG_CTRL_REG_2); + writel((readl(phybase + CDR_CTRL_REG_1) | APB_FIXED_OFFSET), + phybase + CDR_CTRL_REG_1); return; } -static void usb_init_phy(int index) +static void usb_init_phy(int index, int ssphy) { void __iomem *boot_clk_ctl, *usb_bcr, *qusb2_phy_bcr; @@ -1216,16 +1222,15 @@ static void usb_init_phy(int index) /* GCC Reset USB BCR */ set_mdelay_clearbits_le32(usb_bcr, 0x1, 10); - /*usb3 specific wrapper reset*/ - writel(0x3, 0x08AF89BC); - /* GCC_QUSB2_PHY_BCR */ setbits_le32(qusb2_phy_bcr, 0x1); /* GCC_USB0_PHY_BCR */ - setbits_le32(GCC_USB0_PHY_BCR, 0x1); - mdelay(100); - clrbits_le32(GCC_USB0_PHY_BCR, 0x1); + if (ssphy) { + setbits_le32(GCC_USB0_PHY_BCR, 0x1); + mdelay(100); + clrbits_le32(GCC_USB0_PHY_BCR, 0x1); + } /* Config user control register */ writel(0x4004010, USB30_GUCTL); @@ -1236,25 +1241,28 @@ static void usb_init_phy(int index) mdelay(10); usb_init_hsphy((u32 *)QUSB2PHY_BASE); - usb_init_ssphy((u32 *)USB3PHY_APB_BASE); + if (ssphy) + usb_init_ssphy((u32 *)USB3PHY_APB_BASE); } int ipq_board_usb_init(void) { - int i, nodeoff; + int i, nodeoff, ssphy; char node_name[8]; for (i=0; ifdt_blob, node_name); if (nodeoff < 0){ - printf("USB: Node Not found, skipping initialization \n"); + printf("USB: Node Not found, skipping initialization\n"); return -1; } + + ssphy = fdtdec_get_int(gd->fdt_blob, nodeoff, "ssphy", 0); if (!fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) { - usb_clock_init(i); - usb_init_phy(i); + usb_clock_init(i, ssphy); + usb_init_phy(i, ssphy); }else { /* Config user control register */ writel(0x0C804010, USB30_GUCTL); diff --git a/board/qca/arm/ipq5018/ipq5018.h b/board/qca/arm/ipq5018/ipq5018.h index bf62e9b560..cecf45e9cc 100644 --- a/board/qca/arm/ipq5018/ipq5018.h +++ b/board/qca/arm/ipq5018/ipq5018.h @@ -419,6 +419,15 @@ #define SSCG_CTRL_REG_4 0xa8 #define SSCG_CTRL_REG_5 0xac #define SSCG_CTRL_REG_6 0xb0 +#define CDR_CTRL_REG_1 0x80 +#define CDR_CTRL_REG_2 0x84 +#define CDR_CTRL_REG_3 0x88 +#define CDR_CTRL_REG_4 0x8C +#define CDR_CTRL_REG_5 0x90 +#define CDR_CTRL_REG_6 0x94 +#define CDR_CTRL_REG_7 0x98 + +#define APB_FIXED_OFFSET (0x1 << 3) #define USB_PHY_CFG0 0x94 #define USB_PHY_UTMI_CTRL5 0x50 diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 380db533c7..ca7c9fc9d7 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -809,6 +809,27 @@ static void device_add(struct mtd_device *dev) index_partitions(); } +#ifdef CONFIG_IPQ_TINY +int parse_nor_partition(const char *const partdef, + const char **ret, struct part_info **retpart) +{ + return part_parse(partdef, ret, retpart); +} + +void free_parse(struct list_head *head) +{ + struct list_head *entry, *n; + struct part_info *dev_tmp; + + /* clean devices list */ + list_for_each_safe(entry, n, head) { + dev_tmp = list_entry(entry, struct part_info, link); + list_del(entry); + free(dev_tmp); + } +} +#endif + /** * Parse device type, name and mtd-id. If syntax is ok allocate memory and * return pointer to the device structure. diff --git a/drivers/net/ipq_common/ipq_phy.h b/drivers/net/ipq_common/ipq_phy.h index 1176e97095..6ac7c224d9 100755 --- a/drivers/net/ipq_common/ipq_phy.h +++ b/drivers/net/ipq_common/ipq_phy.h @@ -104,6 +104,7 @@ enum phy_mode { QCA8081_PHY_TYPE = 2, AQ_PHY_TYPE = 3, QCA8033_PHY_TYPE = 4, + SFP_PHY_TYPE = 5, }; typedef struct {