diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d2e9a01fc4..2f50b1afb3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -36,7 +36,6 @@ dtb-$(CONFIG_ARCH_IPQ807x) += ipq807x-hk01.dtb \ ipq807x-oak02.dtb \ ipq807x-oak03.dtb \ ipq807x-hk01-c2.dtb \ - ipq807x-hk01-c3.dtb \ ipq807x-hk01-c4.dtb \ ipq807x-hk01-c5.dtb \ ipq807x-hk10-c2.dtb @@ -74,9 +73,10 @@ dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb \ ipq5018-db-mp03.1-c2.dtb \ ipq5018-db-mp03.3.dtb \ ipq5018-db-mp03.3-c2.dtb \ - ipq5018-sod.dtb + ipq5018-mp03.1.dtb else -dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb +dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-db-mp02.1.dtb \ + ipq5018-mp02.1.dtb endif dtb-$(CONFIG_ARCH_IPQ6018) += ipq6018-cp01-c1.dtb \ diff --git a/arch/arm/dts/ipq5018-db-mp02.1.dts b/arch/arm/dts/ipq5018-db-mp02.1.dts index 1921d890de..514e8a7e21 100644 --- a/arch/arm/dts/ipq5018-db-mp02.1.dts +++ b/arch/arm/dts/ipq5018-db-mp02.1.dts @@ -76,7 +76,7 @@ }; gmac_cfg { - gmac_count = <2>; + gephy_led = <46>; gmac1_cfg { unit = <0>; @@ -84,15 +84,7 @@ phy_address = <7>; phy_name = "IPQ MDIO0"; }; - - gmac2_cfg { - unit = <1>; - base = <0x39D00000>; - phy_address = <1>; - phy_name = "IPQ MDIO1"; - }; }; - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq5018-db-mp03.1-c2.dts b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts index 12ae8d9828..4fffdb900c 100644 --- a/arch/arm/dts/ipq5018-db-mp03.1-c2.dts +++ b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts @@ -53,7 +53,7 @@ emmc_cmd{ gpio = <8>; func = <1>; - pull = ; + pull = ; od_en = ; drvstr = ; }; @@ -70,4 +70,19 @@ nand: nand-controller@79B0000 { status = "disabled"; }; + gmac_cfg { + gmac_count = <1>; + ext_mdio_gpio = <36 37>; + gmac2_cfg { + unit = <1>; + base = <0x39D00000>; + phy_name = "IPQ MDIO1"; + mac_pwr = <0xaa545>; + s17c_switch_enable = <1>; + switch_port_count = <4>; + switch_phy_address = <0 1 2 3>; + switch_gpio = <39>; + }; + }; + }; diff --git a/arch/arm/dts/ipq5018-db-mp03.1.dts b/arch/arm/dts/ipq5018-db-mp03.1.dts index c37a7b603b..e3fea72e43 100644 --- a/arch/arm/dts/ipq5018-db-mp03.1.dts +++ b/arch/arm/dts/ipq5018-db-mp03.1.dts @@ -87,6 +87,12 @@ od_en = ; drvstr = ; }; + qspi_clk { + gpio = <9>; + func = <2>; + od_en = ; + drvstr = ; + }; }; }; @@ -117,9 +123,9 @@ }; }; }; - - gmac_cfg { - gmac_count = <2>; + gmac_cfg { + ext_mdio_gpio = <36 37>; + gephy_led = <46>; gmac1_cfg { unit = <0>; @@ -131,10 +137,13 @@ gmac2_cfg { unit = <1>; base = <0x39D00000>; - phy_address = <1>; phy_name = "IPQ MDIO1"; + mac_pwr = <0xaa545>; + s17c_switch_enable = <1>; + switch_port_count = <4>; + switch_phy_address = <0 1 2 3>; + switch_gpio = <39>; }; }; - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq5018-db-mp03.3-c2.dts b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts index 2451ffb2d6..db66c53d6a 100644 --- a/arch/arm/dts/ipq5018-db-mp03.3-c2.dts +++ b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts @@ -53,7 +53,7 @@ emmc_cmd{ gpio = <8>; func = <1>; - pull = ; + pull = ; od_en = ; drvstr = ; }; diff --git a/arch/arm/dts/ipq5018-db-mp03.3.dts b/arch/arm/dts/ipq5018-db-mp03.3.dts index 75c02aa547..3fbdb8d83b 100644 --- a/arch/arm/dts/ipq5018-db-mp03.3.dts +++ b/arch/arm/dts/ipq5018-db-mp03.3.dts @@ -112,7 +112,7 @@ }; gmac_cfg { - gmac_count = <2>; + gephy_led = <46>; gmac1_cfg { unit = <0>; @@ -120,14 +120,5 @@ phy_address = <7>; phy_name = "IPQ MDIO0"; }; - - gmac2_cfg { - unit = <1>; - base = <0x39D00000>; - phy_address = <1>; - phy_name = "IPQ MDIO1"; - }; }; - - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq5018-mp02.1.dts b/arch/arm/dts/ipq5018-mp02.1.dts index 1d1d571d42..de592c696c 100644 --- a/arch/arm/dts/ipq5018-mp02.1.dts +++ b/arch/arm/dts/ipq5018-mp02.1.dts @@ -76,22 +76,13 @@ }; gmac_cfg { - gmac_count = <2>; - + gephy_led = <46> +; gmac1_cfg { unit = <0>; base = <0x39C00000>; phy_address = <7>; phy_name = "IPQ MDIO0"; }; - - gmac2_cfg { - unit = <1>; - base = <0x39D00000>; - phy_address = <1>; - phy_name = "IPQ MDIO1"; - }; }; - - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq5018-mp03.1-c2.dts b/arch/arm/dts/ipq5018-mp03.1-c2.dts index c77894fc71..b4a5270c2b 100644 --- a/arch/arm/dts/ipq5018-mp03.1-c2.dts +++ b/arch/arm/dts/ipq5018-mp03.1-c2.dts @@ -53,7 +53,7 @@ emmc_cmd{ gpio = <8>; func = <1>; - pull = ; + pull = ; od_en = ; drvstr = ; }; diff --git a/arch/arm/dts/ipq5018-mp03.1.dts b/arch/arm/dts/ipq5018-mp03.1.dts index 605ff5e574..8cb97f53c5 100644 --- a/arch/arm/dts/ipq5018-mp03.1.dts +++ b/arch/arm/dts/ipq5018-mp03.1.dts @@ -25,7 +25,6 @@ i2c0 = "/i2c@78b6000"; gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; - pci0 = "/pci@80000000"; pci1 = "/pci@a0000000"; nand = "/nand-controller@79B0000"; }; @@ -87,17 +86,9 @@ od_en = ; drvstr = ; }; - }; - }; - - pci0: pci@80000000 { - status = "ok"; - pci_gpio { - pci_rst { - gpio = <15>; - func = <0>; - pull = ; - oe = ; + qspi_clk { + gpio = <9>; + func = <2>; od_en = ; drvstr = ; }; @@ -117,9 +108,9 @@ }; }; }; - - gmac_cfg { - gmac_count = <2>; + gmac_cfg { + ext_mdio_gpio = <36 37>; + gephy_led = <46>; gmac1_cfg { unit = <0>; @@ -131,10 +122,13 @@ gmac2_cfg { unit = <1>; base = <0x39D00000>; - phy_address = <1>; phy_name = "IPQ MDIO1"; + mac_pwr = <0xaa545>; + s17c_switch_enable = <1>; + switch_port_count = <4>; + switch_phy_address = <0 1 2 3>; + switch_gpio = <39>; }; }; - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq5018-mp03.3-c2.dts b/arch/arm/dts/ipq5018-mp03.3-c2.dts index 7cef9202cf..3fc368189b 100644 --- a/arch/arm/dts/ipq5018-mp03.3-c2.dts +++ b/arch/arm/dts/ipq5018-mp03.3-c2.dts @@ -52,7 +52,7 @@ emmc_cmd{ gpio = <8>; func = <1>; - pull = ; + pull = ; od_en = ; drvstr = ; }; diff --git a/arch/arm/dts/ipq5018-mp03.3.dts b/arch/arm/dts/ipq5018-mp03.3.dts index 9f760cbd6e..12d0df0830 100644 --- a/arch/arm/dts/ipq5018-mp03.3.dts +++ b/arch/arm/dts/ipq5018-mp03.3.dts @@ -85,6 +85,12 @@ od_en = ; drvstr = ; }; + qspi_clk { + gpio = <9>; + func = <2>; + od_en = ; + drvstr = ; + }; }; }; @@ -113,7 +119,7 @@ }; gmac_cfg { - gmac_count = <2>; + gephy_led = <46>; gmac1_cfg { unit = <0>; @@ -121,14 +127,6 @@ phy_address = <7>; phy_name = "IPQ MDIO0"; }; - - gmac2_cfg { - unit = <1>; - base = <0x39D00000>; - phy_address = <1>; - phy_name = "IPQ MDIO1"; - }; }; - gmac_gpio{}; }; diff --git a/arch/arm/dts/ipq807x-hk01-c3.dts b/arch/arm/dts/ipq807x-hk01-c3.dts deleted file mode 100644 index 5c1050a11c..0000000000 --- a/arch/arm/dts/ipq807x-hk01-c3.dts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/dts-v1/; -#include "ipq807x-soc.dtsi" -#include -/ { - machid = <0x08010200>; - config_name = "config@hk01.c3"; - - aliases { - console = "/serial@78B3000"; - uart2 = "/serial@78B0000"; - i2c0 = "/i2c@78b6000"; - pci0 = "/pci@20000000"; - pci1 = "/pci@10000000"; - mmc = "/sdhci@07824000"; - }; - ess-switch { - switch_mac_mode = <0x0>; - switch_mac_mode1 = <0xFF>; - switch_mac_mode2 = <0x2>; - aquantia_port = <5>; - aquantia_gpio = <44>; - }; -}; - diff --git a/arch/arm/dts/ipq807x-hk05.dts b/arch/arm/dts/ipq807x-hk05.dts deleted file mode 100644 index 88a5a3d0a0..0000000000 --- a/arch/arm/dts/ipq807x-hk05.dts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/dts-v1/; -#include "ipq807x-soc.dtsi" -#include -/ { - machid = <0x080100002>; - config_name = "config@hk05"; - - aliases { - console = "/serial@78B3000"; - i2c0 = "/i2c@78b6000"; - pci0 = "/pci@20000000"; - pci1 = "/pci@10000000"; - }; -}; - diff --git a/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h index d5c1d4f193..cf739885c9 100644 --- a/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h +++ b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -286,6 +286,9 @@ #define S17_MIB_PORT5 0x1500 #define S17_MIB_PORT6 0x1600 +#define S17_MIB_COUNTER_ENABLE (1 << 0) +#define S17_MIB_NON_CLEAR (1 << 20) + #define S17_MIB_RXBROAD 0x0 #define S17_MIB_RXPAUSE 0x4 #define S17_MIB_RXMULTI 0x8 diff --git a/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h index 9cc49f35f8..bb2aedb07e 100644 --- a/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h +++ b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h @@ -17,10 +17,8 @@ #include #include -#define GEPHY 0x7 /* Dummy */ - -#define GEPHY_PHY_TYPE 0x1 -#define NAPA_PHY_TYPE 0x2 +#define GEPHY 0x004DD0C0 +#define S17C 0x1302 #define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ) #define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ) @@ -39,7 +37,6 @@ /* Poll demand definitions */ #define POLL_DATA (0x0) - /* Descriptior related definitions */ #define MAC_MAX_FRAME_SZ (1600) @@ -171,8 +168,9 @@ /* GMAC config definitions */ #define MII_PORT_SELECT (1 << 15) -#define GMII_PORT_SELECT (0 << 15) +#define SGMII_PORT_SELECT (0 << 15) #define FRAME_BURST_ENABLE (1 << 21) +#define JABBER_DISABLE (1 << 22) #define JUMBO_FRAME_ENABLE (1 << 20) #define HALF_DUPLEX_ENABLE (0 << 11) #define FULL_DUPLEX_ENABLE (1 << 11) diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index 86fa70a1ad..a6af4b7455 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1146,6 +1146,8 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_IPQ6018_AP_CP01_C4 0x8030003 #define MACH_TYPE_IPQ5018_AP_MP02_1 0x8040000 #define MACH_TYPE_IPQ5018_DB_MP02_1 0X1040003 +#define MACH_TYPE_IPQ807x_AP_HK01_C1 0x8010000 +#define MACH_TYPE_IPQ807x_AP_HK01_C3 0x8010200 #ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type diff --git a/board/qca/arm/common/board_init.c b/board/qca/arm/common/board_init.c index b219433eae..f92dc03e71 100644 --- a/board/qca/arm/common/board_init.c +++ b/board/qca/arm/common/board_init.c @@ -181,10 +181,12 @@ int board_init(void) break; #ifdef CONFIG_QCA_MMC case SMEM_BOOT_MMC_FLASH: - case SMEM_BOOT_NO_FLASH: board_env_range = CONFIG_ENV_SIZE_MAX; break; #endif + case SMEM_BOOT_NO_FLASH: + board_env_range = CONFIG_ENV_SIZE_MAX; + break; default: printf("BUG: unsupported flash type : %d\n", sfi->flash_type); BUG(); @@ -205,6 +207,10 @@ int board_init(void) saveenv = nand_saveenv; env_ptr = nand_env_ptr; env_name_spec = nand_env_name_spec; +#else + saveenv = sf_saveenv; + env_name_spec = sf_env_name_spec; + #endif } #endif diff --git a/board/qca/arm/ipq5018/ipq5018.c b/board/qca/arm/ipq5018/ipq5018.c index 66c5b1d915..235fddaafe 100644 --- a/board/qca/arm/ipq5018/ipq5018.c +++ b/board/qca/arm/ipq5018/ipq5018.c @@ -310,7 +310,6 @@ int board_mmc_init(bd_t *bis) int node, gpio_node; int ret = 0; qca_smem_flash_info_t *sfi = &qca_smem_flash_info; - node = fdt_path_offset(gd->fdt_blob, "mmc"); if (node < 0) { printf("sdhci: Node Not found, skipping initialization\n"); @@ -568,7 +567,6 @@ void board_nand_init(void) * initializing */ int node; - node = fdt_path_offset(gd->fdt_blob, "/nand-controller"); if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) { printf("QPIC: disabled, skipping initialization\n"); @@ -614,12 +612,27 @@ unsigned long timer_read_counter(void) return 0; } -static void set_ext_mdio_gpio(void) +static void set_ext_mdio_gpio(int node) { - /* mdc */ - writel(0x7, (unsigned int *)GPIO_CONFIG_ADDR(36)); - /* mdio */ - writel(0x7, (unsigned int *)GPIO_CONFIG_ADDR(37)); + unsigned int mdio_gpio[2] = {0}; + int status = -1; + unsigned int *s17C_gpio_base; + + status = fdtdec_get_int_array(gd->fdt_blob, + node, + "ext_mdio_gpio", + mdio_gpio, + 2); + if (status >= 0) { + /* mdc */ + s17C_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR(mdio_gpio[0]); + writel(0x7, s17C_gpio_base); + /* mdio */ + s17C_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR(mdio_gpio[1]); + writel(0x7, s17C_gpio_base); + } } static void set_napa_phy_gpio(int gpio) @@ -628,47 +641,99 @@ static void set_napa_phy_gpio(int gpio) napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(gpio); writel(0x203, napa_gpio_base); - gpio_direction_output(gpio, 0x0); + writel(0x0, GPIO_IN_OUT_ADDR(gpio)); mdelay(500); - gpio_set_value(gpio, 0x1); + writel(0x1, GPIO_IN_OUT_ADDR(gpio)); +} + +static void reset_s17c_switch_gpio(int gpio) +{ + unsigned int *switch_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR(gpio); + + writel(0x203, switch_gpio_base); + writel(0x0, GPIO_IN_OUT_ADDR(gpio)); + mdelay(500); + writel(0x2, GPIO_IN_OUT_ADDR(gpio)); } static void cmn_blk_clk_set(void) { /* GMN block */ writel(0x1, GCC_CMN_BLK_AHB_CBCR); - mdelay(200); + mdelay(20); writel(0x1, GCC_CMN_BLK_SYS_CBCR); - mdelay(200); + mdelay(20); } static void uniphy_clk_set(void) { writel(0x1, GCC_UNIPHY_AHB_CBCR); - mdelay(200); + mdelay(20); writel(0x1, GCC_UNIPHY_SYS_CBCR); - mdelay(200); + mdelay(20); + writel(0x1, GCC_UNIPHY_RX_CBCR); + mdelay(20); + writel(0x1, GCC_UNIPHY_TX_CBCR); + mdelay(20); + } -static void gephy_port_clock_reset(void) +static void gephy_uniphy_clock_disable(void) { - writel(0, GCC_GEPHY_RX_CBCR); - mdelay(200); - writel(0, GCC_GEPHY_TX_CBCR); - mdelay(200); + u32 reg_val = 0; + + reg_val = readl(GCC_GEPHY_RX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GEPHY_RX_CBCR); + mdelay(20); + + reg_val = readl(GCC_GEPHY_TX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GEPHY_TX_CBCR); + mdelay(20); + + reg_val = readl(GCC_UNIPHY_RX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_UNIPHY_RX_CBCR); + mdelay(20); + + reg_val = readl(GCC_UNIPHY_TX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_UNIPHY_TX_CBCR); + mdelay(20); + } -static void gmac0_clock_reset(void) +static void gmac_clock_disable(void) { - writel(0, GCC_GMAC0_RX_CBCR); - mdelay(200); - writel(0, GCC_GMAC0_TX_CBCR); - mdelay(200); + u32 reg_val = 0; + + reg_val = readl(GCC_GMAC0_RX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GMAC0_RX_CBCR); + mdelay(20); + + reg_val = readl(GCC_GMAC0_TX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GMAC0_TX_CBCR); + mdelay(20); + + reg_val = readl(GCC_GMAC1_RX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GMAC1_RX_CBCR); + mdelay(20); + + reg_val = readl(GCC_GMAC1_TX_CBCR); + reg_val &= ~GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GMAC1_TX_CBCR); + mdelay(20); + } static void gmac_clk_src_init(void) { - u32 reg_val; + u32 reg_val, iGmac_id, iTxRx; /*select source of GMAC*/ reg_val = readl(GCC_GMAC0_RX_CFG_RCGR); @@ -690,6 +755,27 @@ static void gmac_clk_src_init(void) reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK; reg_val |= GCC_GMAC1_TX_SRC_SEL_UNIPHY_TX; writel(reg_val, GCC_GMAC1_TX_CFG_RCGR); + + /* update above clock configuration */ + for (iGmac_id = 0; iGmac_id < 2; ++iGmac_id) { + for (iTxRx = 0; iTxRx < 2; ++iTxRx){ + reg_val = 0; + reg_val = readl(GCC_GMAC0_RX_CMD_RCGR + + (iTxRx * 8) + (iGmac_id * 0x10)); + reg_val &= ~0x1; + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_RX_CMD_RCGR + + (iTxRx * 8) + (iGmac_id * 0x10)); + } + } + reg_val = readl(GCC_GMAC_CFG_RCGR); + reg_val = 0x209; + writel(reg_val, GCC_GMAC_CFG_RCGR); + + reg_val = readl(GCC_GMAC_CMD_RCGR); + reg_val &= ~0x1; + reg_val |= 0x1; + writel(reg_val, GCC_GMAC_CMD_RCGR); } static void gephy_reset(void) @@ -699,13 +785,13 @@ static void gephy_reset(void) reg_val = readl(GCC_GEPHY_BCR); writel(reg_val | (GCC_GEPHY_BCR_BLK_ARES), GCC_GEPHY_BCR); - mdelay(200); + mdelay(20); writel(reg_val & (~GCC_GEPHY_BCR_BLK_ARES), GCC_GEPHY_BCR); reg_val = readl(GCC_GEPHY_MISC); writel(reg_val | (GCC_GEPHY_MISC_ARES), GCC_GEPHY_MISC); - mdelay(200); + mdelay(20); writel(reg_val & (~GCC_GEPHY_MISC_ARES), GCC_GEPHY_MISC); } @@ -717,7 +803,7 @@ static void uniphy_reset(void) reg_val = readl(GCC_UNIPHY_BCR); writel(reg_val | (GCC_UNIPHY_BCR_BLK_ARES), GCC_UNIPHY_BCR); - mdelay(200); + mdelay(20); writel(reg_val & (~GCC_UNIPHY_BCR_BLK_ARES), GCC_UNIPHY_BCR); } @@ -729,7 +815,7 @@ static void gmac_reset(void) reg_val = readl(GCC_GMAC0_BCR); writel(reg_val | (GCC_GMAC0_BCR_BLK_ARES), GCC_GMAC0_BCR); - mdelay(200); + mdelay(20); writel(reg_val & (~GCC_GMAC0_BCR_BLK_ARES), GCC_GMAC0_BCR); @@ -742,51 +828,165 @@ static void gmac_reset(void) } -static void gmac_clock_enable(void) +static void cmn_clock_init (void) +{ + u32 reg_val = 0; + reg_val = readl(CMN_BLK_ADDR + 4); + reg_val = (reg_val & FREQUENCY_MASK) | INTERNAL_48MHZ_CLOCK; + writel(reg_val, CMN_BLK_ADDR + 0x4); + reg_val = readl(CMN_BLK_ADDR); + reg_val = reg_val | 0x40; + writel(reg_val, CMN_BLK_ADDR); + mdelay(1); + reg_val = reg_val & (~0x40); + writel(reg_val, CMN_BLK_ADDR); + mdelay(1); + writel(0xbf, CMN_BLK_ADDR); + mdelay(1); + writel(0xff, CMN_BLK_ADDR); + mdelay(1); +} + +static void cmnblk_enable(void) +{ + u32 reg_val; + + reg_val = readl(TCSR_ETH_LDO_RDY_REG); + reg_val |= ETH_LDO_RDY; + writel(reg_val, TCSR_ETH_LDO_RDY_REG); +} + +static void cmnblk_check_state(void) +{ + u32 reg_val, times = 20; + + while(times--) + { + reg_val = readl(CMN_PLL_PLL_LOCKED_REG); + if(reg_val & CMN_PLL_LOCKED) { + printf("cmbblk is stable %x\n", + reg_val); + break; + } + mdelay(10); + } + if(!times) { + printf("200ms have been over %x\n", + readl(CMN_PLL_PLL_LOCKED_REG)); + } +} + +static void uniphy_refclk_set(void) +{ +/* + * This function drive the uniphy ref clock + * DEC_REFCLKOUTPUTCONTROLREGISTERS + * Its is configured as 25 MHZ + */ +#define UNIPHY_REF_CLK_CTRL_REG 0x98074 + + u32 reg_val = readl(UNIPHY_REF_CLK_CTRL_REG); + reg_val |= 0x2; + writel(reg_val, UNIPHY_REF_CLK_CTRL_REG); + mdelay(500); +} + +static void gcc_clock_enable(void) +{ + u32 reg_val; + + reg_val = readl(GCC_MDIO0_BASE + 0x4); + reg_val |= 0x1; + writel(reg_val, GCC_MDIO0_BASE + 0x4); + + reg_val = readl(GCC_MDIO0_BASE + 0x14); + reg_val |= 0x1; + writel(reg_val, GCC_MDIO0_BASE + 0x14); + + reg_val = readl(GCC_GMAC0_SYS_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_SYS_CBCR); + + reg_val = readl(GCC_GMAC0_PTP_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_PTP_CBCR); + + reg_val = readl(GCC_GMAC0_CFG_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_CFG_CBCR); + + reg_val = readl(GCC_GMAC1_SYS_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC1_SYS_CBCR); + + reg_val = readl(GCC_GMAC1_PTP_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC1_PTP_CBCR); + + reg_val = readl(GCC_GMAC1_CFG_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC1_CFG_CBCR); + + reg_val = readl(GCC_GMAC0_RX_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_RX_CBCR); + + reg_val = readl(GCC_GMAC0_TX_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC0_TX_CBCR); + + reg_val = readl(GCC_GMAC1_RX_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC1_RX_CBCR); + + reg_val = readl(GCC_GMAC1_TX_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_GMAC1_TX_CBCR); + + reg_val = readl(GCC_SNOC_GMAC0_AHB_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_SNOC_GMAC0_AHB_CBCR); + + reg_val = readl(GCC_SNOC_GMAC1_AHB_CBCR); + reg_val |= 0x1; + writel(reg_val, GCC_SNOC_GMAC1_AHB_CBCR); + +} + +static void ethernet_clock_enable(void) { cmn_blk_clk_set(); uniphy_clk_set(); - gephy_port_clock_reset(); - gmac0_clock_reset(); + gephy_uniphy_clock_disable(); + gmac_clock_disable(); gmac_clk_src_init(); + cmn_clock_init(); + cmnblk_enable(); + cmnblk_check_state(); gephy_reset(); uniphy_reset(); gmac_reset(); + uniphy_refclk_set(); + gcc_clock_enable(); +} - /* GMAC0 AHB clock enable */ - writel(0x1, GCC_SNOC_GMAC0_AHB_CBCR); - udelay(10); - /* GMAC0 SYS clock */ - writel(0x1, GCC_GMAC0_SYS_CBCR); - udelay(10); - /* GMAC0 PTP clock */ - writel(0x1, GCC_GMAC0_PTP_CBCR); - udelay(10); - /* GMAC0 CFG clock */ - writel(0x1, GCC_GMAC0_CFG_CBCR); - udelay(10); +static void enable_gephy_led(int gpio) +{ + unsigned int *led_gpio_base = + (unsigned int *)GPIO_CONFIG_ADDR(gpio); - /* GMAC0 AHB clock enable */ - writel(0x1, GCC_SNOC_GMAC1_AHB_CBCR); - udelay(10); - /* GMAC0 SYS clock */ - writel(0x1, GCC_GMAC1_SYS_CBCR); - udelay(10); - /* GMAC0 PTP clock */ - writel(0x1, GCC_GMAC1_PTP_CBCR); - udelay(10); - /* GMAC0 CFG clock */ - writel(0x1, GCC_GMAC1_CFG_CBCR); - udelay(10); + writel(0xc5, led_gpio_base); } int board_eth_init(bd_t *bis) { int status; - int gmac_gpio_node = 0; + int led_gpio; int gmac_cfg_node = 0, offset = 0; int loop = 0; + int switch_gpio = 0; int phy_name_len = 0; + unsigned int tmp_phy_array[8] = {0}; char *phy_name_ptr = NULL; gmac_cfg_node = fdt_path_offset(gd->fdt_blob, "/gmac_cfg"); @@ -794,12 +994,14 @@ int board_eth_init(bd_t *bis) /* * Clock enable */ - gmac_clock_enable(); + ethernet_clock_enable(); + led_gpio = fdtdec_get_uint(gd->fdt_blob, + gmac_cfg_node, "gephy_led", 0); + if (led_gpio) + enable_gephy_led(led_gpio); + + set_ext_mdio_gpio(gmac_cfg_node); - status = fdtdec_get_uint(gd->fdt_blob,offset, "ext_mdio_gpio", 0); - if (status){ - set_ext_mdio_gpio(); - } for (offset = fdt_first_subnode(gd->fdt_blob, gmac_cfg_node); offset > 0; offset = fdt_next_subnode(gd->fdt_blob, offset) , loop++) { @@ -821,18 +1023,32 @@ int board_eth_init(bd_t *bis) if (gmac_cfg[loop].phy_napa_gpio){ set_napa_phy_gpio(gmac_cfg[loop].phy_napa_gpio); } - + switch_gpio = fdtdec_get_uint(gd->fdt_blob, offset, "switch_gpio", 0); + if (switch_gpio) { + reset_s17c_switch_gpio(switch_gpio); + } gmac_cfg[loop].phy_type = fdtdec_get_uint(gd->fdt_blob, offset, "phy_type", -1); - gmac_cfg[loop].mac_pwr0 = fdtdec_get_uint(gd->fdt_blob, - offset, "mac_pwr0", 0); - - gmac_cfg[loop].mac_pwr1 = fdtdec_get_uint(gd->fdt_blob, - offset, "mac_pwr1", 0); + gmac_cfg[loop].mac_pwr = fdtdec_get_uint(gd->fdt_blob, + offset, "mac_pwr", 0); gmac_cfg[loop].ipq_swith = fdtdec_get_uint(gd->fdt_blob, offset, "s17c_switch_enable", 0); + if (gmac_cfg[loop].ipq_swith) { + gmac_cfg[loop].switch_port_count = fdtdec_get_uint( + gd->fdt_blob, + offset, "switch_port_count", 0); + + fdtdec_get_int_array(gd->fdt_blob, offset, "switch_phy_address", + tmp_phy_array, gmac_cfg[loop].switch_port_count); + + for(int inner_loop = 0; inner_loop < gmac_cfg[loop].switch_port_count; + inner_loop++){ + gmac_cfg[loop].switch_port_phy_address[inner_loop] = + (char)tmp_phy_array[inner_loop]; + } + } phy_name_ptr = (char*)fdt_getprop(gd->fdt_blob, offset, "phy_name", &phy_name_len); @@ -840,14 +1056,10 @@ int board_eth_init(bd_t *bis) strlcpy((char *)gmac_cfg[loop].phy_name, phy_name_ptr, phy_name_len); } } - gmac_cfg[loop].unit = -1; - ipq_gmac_common_init(gmac_cfg); + if (loop < CONFIG_IPQ_NO_MACS) + gmac_cfg[loop].unit = -1; - gmac_gpio_node = fdt_path_offset(gd->fdt_blob, "gmac_gpio"); - if (gmac_gpio_node) { - qca_gpio_init(gmac_gpio_node); - } status = ipq_gmac_init(gmac_cfg); return status; @@ -863,7 +1075,6 @@ void board_usb_deinit(int id) { int nodeoff; 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)) @@ -893,6 +1104,9 @@ static void usb_clock_init(int id) { int cfg; + /* select usb phy mux */ + writel(0x1, TCSR_USB_PCIE_SEL); + /* Configure usb0_master_clk_src */ cfg = (GCC_USB0_MASTER_CFG_RCGR_SRC_SEL | GCC_USB0_MASTER_CFG_RCGR_SRC_DIV); @@ -910,17 +1124,6 @@ static void usb_clock_init(int id) mdelay(100); writel(ROOT_EN, GCC_USB0_MOCK_UTMI_CMD_RCGR); - /* Configure usb0_lfps_cmd_rcgr */ - cfg = (GCC_USB0_LFPS_CFG_SRC_SEL | - GCC_USB0_LFPS_CFG_SRC_DIV); - writel(cfg, GCC_USB0_LFPS_CFG_RCGR); - writel(LFPS_M, GCC_USB0_LFPS_M); - writel(LFPS_N, GCC_USB0_LFPS_N); - writel(LFPS_D, GCC_USB0_LFPS_D); - writel(CMD_UPDATE, GCC_USB0_LFPS_CMD_RCGR); - mdelay(100); - writel(ROOT_EN, GCC_USB0_LFPS_CMD_RCGR); - /* Configure usb0_aux_clk_src */ cfg = (GCC_USB0_AUX_CFG_SRC_SEL | GCC_USB0_AUX_CFG_SRC_DIV); @@ -929,16 +1132,30 @@ static void usb_clock_init(int id) mdelay(100); writel(ROOT_EN, GCC_USB0_AUX_CMD_RCGR); + /* Configure usb0_lfps_cmd_rcgr */ + cfg = (GCC_USB0_LFPS_CFG_SRC_SEL | + GCC_USB0_LFPS_CFG_SRC_DIV); + writel(cfg, GCC_USB0_LFPS_CFG_RCGR); + writel(LFPS_M, GCC_USB0_LFPS_M); + writel(LFPS_N, GCC_USB0_LFPS_N); + writel(LFPS_D, GCC_USB0_LFPS_D); + writel(readl(GCC_USB0_LFPS_CFG_RCGR) | GCC_USB0_LFPS_MODE, + GCC_USB0_LFPS_CFG_RCGR); + writel(CMD_UPDATE, GCC_USB0_LFPS_CMD_RCGR); + mdelay(100); + writel(ROOT_EN, GCC_USB0_LFPS_CMD_RCGR); + /* Configure CBCRs */ writel(CLK_DISABLE, GCC_SYS_NOC_USB0_AXI_CBCR); writel(CLK_ENABLE, GCC_SYS_NOC_USB0_AXI_CBCR); writel((readl(GCC_USB0_MASTER_CBCR) | CLK_ENABLE), GCC_USB0_MASTER_CBCR); writel(CLK_ENABLE, GCC_USB0_SLEEP_CBCR); - writel(CLK_ENABLE, GCC_USB0_MOCK_UTMI_CBCR); + writel((GCC_USB_MOCK_UTMI_CLK_DIV | CLK_ENABLE), + GCC_USB0_MOCK_UTMI_CBCR); + writel(CLK_DISABLE, GCC_USB0_PIPE_CBCR); writel(CLK_ENABLE, GCC_USB0_PHY_CFG_AHB_CBCR); writel(CLK_ENABLE, GCC_USB0_AUX_CBCR); - writel(CLK_ENABLE, GCC_USB0_PIPE_CBCR); writel(CLK_ENABLE, GCC_USB0_LFPS_CBCR); } @@ -971,17 +1188,14 @@ static void usb_init_hsphy(void __iomem *phybase) static void usb_init_ssphy(void __iomem *phybase) { - /* select usb phy mux */ - writel(0x1, TCSR_USB_PCIE_SEL); writel(CLK_ENABLE, GCC_USB0_PHY_CFG_AHB_CBCR); writel(CLK_ENABLE, GCC_USB0_PIPE_CBCR); - writel(CLK_DISABLE, GCC_USB0_PIPE_CBCR); udelay(100); /*set frequency initial value*/ writel(0x1cb9, phybase + SSCG_CTRL_REG_4); writel(0x023a, phybase + SSCG_CTRL_REG_5); /*set spectrum spread count*/ - writel(0x1360, phybase + SSCG_CTRL_REG_3); + writel(0xd360, phybase + SSCG_CTRL_REG_3); /*set fstep*/ writel(0x1, phybase + SSCG_CTRL_REG_1); writel(0xeb, phybase + SSCG_CTRL_REG_2); @@ -995,23 +1209,27 @@ static void usb_init_phy(int index) boot_clk_ctl = (u32 *)GCC_USB_0_BOOT_CLOCK_CTL; usb_bcr = (u32 *)GCC_USB0_BCR; qusb2_phy_bcr = (u32 *)GCC_QUSB2_0_PHY_BCR; + /* Disable USB Boot Clock */ clrbits_le32(boot_clk_ctl, 0x0); /* GCC Reset USB BCR */ set_mdelay_clearbits_le32(usb_bcr, 0x1, 10); + /*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(10); + mdelay(100); clrbits_le32(GCC_USB0_PHY_BCR, 0x1); /* Config user control register */ - writel(0x0C804010, USB30_GUCTL); - writel(0x8C80C8A0, USB30_FLADJ); + writel(0x4004010, USB30_GUCTL); + writel(0x4945920, USB30_FLADJ); /* GCC_QUSB2_0_PHY_BCR */ clrbits_le32(qusb2_phy_bcr, 0x1); diff --git a/board/qca/arm/ipq5018/ipq5018.h b/board/qca/arm/ipq5018/ipq5018.h index 00ecbc3e66..bf62e9b560 100644 --- a/board/qca/arm/ipq5018/ipq5018.h +++ b/board/qca/arm/ipq5018/ipq5018.h @@ -22,16 +22,35 @@ #define MSM_SDC1_BASE 0x7800000 #define MSM_SDC1_SDHCI_BASE 0x7804000 +#define GCC_MDIO0_BASE 0x1858000 +#define GCC_GMAC_CFG_RCGR 0x01868084 +#define GCC_GMAC_CMD_RCGR 0x01868080 +#define GCC_GMAC_BASE 0x01868000 + + #define GCC_GMAC_CFG_RCGR_SRC_SEL_MASK 0x700 #define GCC_GMAC0_RX_SRC_SEL_GEPHY_TX 0x200 #define GCC_GMAC0_TX_SRC_SEL_GEPHY_TX 0x100 #define GCC_GMAC1_RX_SRC_SEL_UNIPHY_RX 0x100 #define GCC_GMAC1_TX_SRC_SEL_UNIPHY_TX 0x100 +#define CMN_PLL_PLL_LOCKED_REG 0x9B064 +#define CMN_PLL_PLL_LOCKED_SIZE 0x4 +#define CMN_PLL_LOCKED 0x4 + /* * CMN BLK clock */ #define GCC_CMN_BLK_AHB_CBCR 0x01856308 #define GCC_CMN_BLK_SYS_CBCR 0x0185630C +#define CMN_BLK_ADDR 0x0009B780 +#define CMN_BLK_SIZE 0x100 +#define FREQUENCY_MASK 0xfffffdf0 +#define INTERNAL_48MHZ_CLOCK 0x7 + +#define TCSR_ETH_LDO_RDY_REG 0x19475C4 +#define TCSR_ETH_LDO_RDY_SIZE 0x4 +#define ETH_LDO_RDY 0x1 + /* * GEPHY Block Register */ @@ -50,6 +69,8 @@ #define GCC_UNIPHY_SYS_CBCR 0x0185610C #define GCC_UNIPHY_BCR_BLK_ARES 0x1 #define GCC_UNIPHY_MISC_ARES 0x32 +#define GCC_UNIPHY_RX_CBCR 0x01856110 +#define GCC_UNIPHY_TX_CBCR 0x01856114 /* GMAC0 GCC clock */ #define GCC_GMAC0_RX_CMD_RCGR 0x01868020 @@ -87,6 +108,8 @@ #define GCC_GMAC1_TX_CBCR 0x0186824C #define GCC_GMAC1_BCR_BLK_ARES 0x1 +#define GCC_CBCR_CLK_ENABLE 0x1 + /* * GCC-SDCC Registers */ @@ -206,6 +229,7 @@ #define LFPS_M 0x1 #define LFPS_N 0xfe #define LFPS_D 0xfd +#define GCC_USB0_LFPS_MODE (0x2 << 12) #define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE (2 << 12) #define GCC_USB0_AUX_CFG_SRC_SEL (0 << 8) @@ -224,9 +248,6 @@ #define GCC_USB_MOCK_UTMI_SRC_SEL (1 << 8) #define GCC_USB_MOCK_UTMI_SRC_DIV (0x13 << 0) -#define UTMI_M 0x1 -#define UTMI_N 0xf7 -#define UTMI_D 0xf6 #define GCC_USB_MOCK_UTMI_CLK_DIV (0x1 << 16) #define GCC_QUSB2_1_PHY_BCR 0x1841040 @@ -422,6 +443,8 @@ unsigned int __invoke_psci_fn_smc(unsigned int, unsigned int, unsigned int, unsigned int); +#define S17C_MAX_PORT 4 + typedef struct { u32 base; int unit; @@ -429,9 +452,10 @@ typedef struct { int phy_interface_mode; int phy_napa_gpio; int phy_type; - u32 mac_pwr0; - u32 mac_pwr1; + u32 mac_pwr; int ipq_swith; + int switch_port_count; + int switch_port_phy_address[S17C_MAX_PORT]; const char phy_name[MDIO_NAME_LEN]; } ipq_gmac_board_cfg_t; diff --git a/board/qca/arm/ipq807x/ipq807x.c b/board/qca/arm/ipq807x/ipq807x.c index 264a02e32b..3b67a6a2ed 100644 --- a/board/qca/arm/ipq807x/ipq807x.c +++ b/board/qca/arm/ipq807x/ipq807x.c @@ -1262,6 +1262,48 @@ int ipq_board_usb_init(void) } #endif +unsigned int get_dts_machid(unsigned int machid) +{ + switch (machid) + { + case MACH_TYPE_IPQ807x_AP_HK01_C3: + return MACH_TYPE_IPQ807x_AP_HK01_C1; + default: + return machid; + } +} + +void ipq_uboot_fdt_fixup(void) +{ + int ret, len; + char *config = NULL; + + switch (gd->bd->bi_arch_number) + { + case MACH_TYPE_IPQ807x_AP_HK01_C3: + config = "config@hk01.c3"; + break; + } + + if (config != NULL) + { + len = fdt_totalsize(gd->fdt_blob) + strlen(config) + 1; + + /* + * Open in place with a new length. + */ + ret = fdt_open_into(gd->fdt_blob, (void *)gd->fdt_blob, len); + if (ret) + printf("uboot-fdt-fixup: Cannot expand FDT: %s\n", fdt_strerror(ret)); + + ret = fdt_setprop((void *)gd->fdt_blob, 0, "config_name", + config, (strlen(config)+1)); + if (ret) + printf("uboot-fdt-fixup: unable to set config_name(%d)\n", ret); + } + return; +} + void ipq_fdt_fixup_socinfo(void *blob) { uint32_t cpu_type; diff --git a/configs/ipq5018_defconfig b/configs/ipq5018_defconfig index 675e717f87..7bdb272b76 100644 --- a/configs/ipq5018_defconfig +++ b/configs/ipq5018_defconfig @@ -34,7 +34,7 @@ CONFIG_CMD_CONSOLE=y # CONFIG_CMD_BOOTD is not set CONFIG_CMD_BOOTM=y CONFIG_CMD_GO=y -# CONFIG_CMD_RUN 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 diff --git a/drivers/mtd/nand/qpic_nand.c b/drivers/mtd/nand/qpic_nand.c index c3d9410433..05a3c5af0a 100644 --- a/drivers/mtd/nand/qpic_nand.c +++ b/drivers/mtd/nand/qpic_nand.c @@ -139,7 +139,7 @@ static const unsigned int training_block_128[] = { 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, }; -#define TRAINING_PART_OFFSET 0x100000 +#define TRAINING_PART_OFFSET 0x3c00000 #define MAXIMUM_ALLOCATED_TRAINING_BLOCK 8 #define TOTAL_NUM_PHASE 7 #endif @@ -1429,37 +1429,58 @@ static void qpic_spi_init(struct mtd_info *mtd) { uint32_t xfer_start = NAND_XFR_STEPS_V1_5_20; int i; + unsigned int default_clk_rate; - unsigned int val; int num_desc = 0; - struct cmd_element *cmd_list_ptr = ce_array; struct cmd_element *cmd_list_ptr_start = ce_array; + unsigned int val; + val = readl(NAND_QSPI_MSTR_CONFIG); + +#if defined(QSPI_IO_MACRO_DEFAULT_CLK_320MHZ) && !defined(CONFIG_QSPI_SERIAL_TRAINING) + default_clk_rate = IO_MACRO_CLK_320_MHZ; + val &= ~FB_CLK_BIT; +#else + default_clk_rate = IO_MACRO_CLK_200_MHZ; val |= FB_CLK_BIT; +#endif + if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) { - bam_add_cmd_element(cmd_list_ptr, NAND_QSPI_MSTR_CONFIG, (uint32_t)val, CE_WRITE_TYPE); - cmd_list_ptr++; + bam_add_cmd_element(cmd_list_ptr, NAND_QSPI_MSTR_CONFIG, + (uint32_t)val, CE_WRITE_TYPE); + cmd_list_ptr++; - bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)0, CE_WRITE_TYPE); - cmd_list_ptr++; + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)0, CE_WRITE_TYPE); + cmd_list_ptr++; - bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)SPI_CFG_VAL, CE_WRITE_TYPE); - cmd_list_ptr++; + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)SPI_CFG_VAL, CE_WRITE_TYPE); + cmd_list_ptr++; - val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN; - bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)val, CE_WRITE_TYPE); - cmd_list_ptr++; + val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN; + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)val, CE_WRITE_TYPE); + cmd_list_ptr++; - bam_add_one_desc(&bam, + bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr_start, ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), - BAM_DESC_CMD_FLAG | BAM_DESC_LOCK_FLAG); - num_desc++; + BAM_DESC_CMD_FLAG); + num_desc++; - qpic_nand_wait_for_cmd_exec(num_desc); + /* Notify BAM HW about the newly added descriptors */ + bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc); + } else { + writel(val, NAND_QSPI_MSTR_CONFIG); + writel(0x0, NAND_FLASH_SPI_CFG); + writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG); + val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN; + writel(val, NAND_FLASH_SPI_CFG); + } num_desc = 0; @@ -1468,8 +1489,7 @@ static void qpic_spi_init(struct mtd_info *mtd) * bit enabled then , we can apply upto maximum 200MHz * input to IO_MACRO_BLOCK. */ - - qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, + qpic_set_clk_rate(default_clk_rate, QPIC_IO_MACRO_CLK, GPLL0_CLK_SRC); /*qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, @@ -1512,26 +1532,31 @@ static void qpic_spi_init(struct mtd_info *mtd) /* No of address cycle is same for Giga device & Micron so * configure no of address cycle now. */ - cmd_list_ptr = ce_array; - bam_add_cmd_element(cmd_list_ptr, NAND_SPI_NUM_ADDR_CYCLES, - (uint32_t)SPI_NUM_ADDR_CYCLES, CE_WRITE_TYPE); + if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) { + cmd_list_ptr = ce_array; + bam_add_cmd_element(cmd_list_ptr, NAND_SPI_NUM_ADDR_CYCLES, + (uint32_t)SPI_NUM_ADDR_CYCLES, CE_WRITE_TYPE); - cmd_list_ptr++; + cmd_list_ptr++; - bam_add_cmd_element(cmd_list_ptr, NAND_SPI_BUSY_CHECK_WAIT_CNT, - (uint32_t)SPI_BUSY_CHECK_WAIT_CNT, CE_WRITE_TYPE); + bam_add_cmd_element(cmd_list_ptr, NAND_SPI_BUSY_CHECK_WAIT_CNT, + (uint32_t)SPI_BUSY_CHECK_WAIT_CNT, CE_WRITE_TYPE); - cmd_list_ptr++; + cmd_list_ptr++; - bam_add_one_desc(&bam, + bam_add_one_desc(&bam, CMD_PIPE_INDEX, (unsigned char*)cmd_list_ptr_start, ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), - BAM_DESC_CMD_FLAG | BAM_DESC_LOCK_FLAG); - num_desc++; - qpic_nand_wait_for_cmd_exec(num_desc); + BAM_DESC_CMD_FLAG); + num_desc++; - num_desc = 0; + /* Notify BAM HW about the newly added descriptors */ + bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc); + } else { + writel(SPI_NUM_ADDR_CYCLES, NAND_SPI_NUM_ADDR_CYCLES); + writel(SPI_BUSY_CHECK_WAIT_CNT, NAND_SPI_BUSY_CHECK_WAIT_CNT); + } } #endif static int qpic_nand_reset(struct mtd_info *mtd) @@ -3056,8 +3081,8 @@ static int qpic_nand_multi_page_read(struct mtd_info *mtd, uint32_t page, } if (uncorrectable_err_cws) { - nand_ret = qpic_nand_check_erased_page(mtd, page, (ops_datbuf + (j * mtd->writesize)), - ops_oobbuf + j * 64, + nand_ret = qpic_nand_check_erased_page(mtd, page + j, (ops_datbuf + (j * mtd->writesize)), + ops_oobbuf, uncorrectable_err_cws, &max_bitflips); if (nand_ret < 0) @@ -3424,7 +3449,6 @@ static int qpic_nand_read_page_scope_multi_page(struct mtd_info *mtd, start_page = ((to >> chip->page_shift)); num_pages = qpic_get_read_page_count(mtd, ops, to); - while (1) { if (num_pages > MAX_MULTI_PAGE) { @@ -3979,50 +4003,163 @@ qpic_nand_mtd_params(struct mtd_info *mtd) } #ifdef CONFIG_QSPI_SERIAL_TRAINING +static void qpic_reg_write_bam(unsigned int reg, unsigned int val) +{ + int num_desc = 0; + struct cmd_element *cmd_list_ptr = ce_array; + struct cmd_element *cmd_list_ptr_start = ce_array; + + bam_add_cmd_element(cmd_list_ptr, reg, + (uint32_t)val, CE_WRITE_TYPE); + cmd_list_ptr++; + + bam_add_one_desc(&bam, + CMD_PIPE_INDEX, + (unsigned char*)cmd_list_ptr_start, + ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), + BAM_DESC_CMD_FLAG); + num_desc++; + + /* Notify BAM HW about the newly added descriptors */ + bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc); +} static void qpic_set_phase(int phase) { int spi_flash_cfg_val = 0x0; + int num_desc = 0; + struct cmd_element *cmd_list_ptr = ce_array; + struct cmd_element *cmd_list_ptr_start = ce_array; + if (phase < 1 || phase > 7) { printf("%s : wrong phase value\n", __func__); return; } /* get the current value of NAND_FLASH_SPI_CFG register */ spi_flash_cfg_val = readl(NAND_FLASH_SPI_CFG); - /* set SPI_LOAD_CLK_CNTR_INIT_EN bit */ spi_flash_cfg_val |= SPI_LOAD_CLK_CNTR_INIT_EN; - writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); - /* write the phase value for all the line */ - spi_flash_cfg_val |= ((phase << 16) | (phase << 19) | + if ((readl(QPIC_NAND_CTRL) & BAM_MODE_EN)) { + + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE); + cmd_list_ptr++; + + spi_flash_cfg_val &= 0xf000ffff; + /* write the phase value for all the line */ + spi_flash_cfg_val |= ((phase << 16) | (phase << 19) | (phase << 22) | (phase << 25)); - writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); - /* clear the SPI_LOAD_CLK_CNTR_INIT_EN bit to load the required - * phase value - */ - spi_flash_cfg_val &= ~SPI_LOAD_CLK_CNTR_INIT_EN; - writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE); + cmd_list_ptr++; + /* clear the SPI_LOAD_CLK_CNTR_INIT_EN bit to load the required + * phase value + */ + spi_flash_cfg_val &= ~SPI_LOAD_CLK_CNTR_INIT_EN; + + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, + (uint32_t)spi_flash_cfg_val, CE_WRITE_TYPE); + cmd_list_ptr++; + + bam_add_one_desc(&bam, + CMD_PIPE_INDEX, + (unsigned char*)cmd_list_ptr_start, + ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), + BAM_DESC_CMD_FLAG); + num_desc++; + + /* Notify BAM HW about the newly added descriptors */ + bam_sys_gen_event(&bam, CMD_PIPE_INDEX, num_desc); + } else { + writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); + + spi_flash_cfg_val &= 0xf000ffff; + /* write the phase value for all the line */ + spi_flash_cfg_val |= ((phase << 16) | (phase << 19) | + (phase << 22) | (phase << 25)); + writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); + + /* clear the SPI_LOAD_CLK_CNTR_INIT_EN bit to load the required + * phase value + */ + spi_flash_cfg_val &= ~SPI_LOAD_CLK_CNTR_INIT_EN; + writel(spi_flash_cfg_val, NAND_FLASH_SPI_CFG); + } +} + +static int find_element(int val, u8 *phase_table, int index) +{ + int i; + int ret = 0; + + for (i = 0; i < TOTAL_NUM_PHASE; i++) { + if (phase_table[i] == val) { + ret = i; + break; + } + } + + if ( i > TOTAL_NUM_PHASE) { + printf("%s : wrong array index\n",__func__); + ret = -EIO; + } + + return ret; } static int qpic_find_most_appropriate_phase(u8 *phase_table, int phase_count) { - int cnt; + int cnt = 0; + int i, j, new_index = 0, limit; int phase = 0x0; u8 phase_ranges[TOTAL_NUM_PHASE] = {1, 2, 3, 4, 5, 6, 7}; /*currently we are considering continious 3 phase will * pass and tke the middle one out of passed three phase. + * if all 7 phase passed so return middle phase i.e 4 */ - for (cnt = 0; cnt < phase_count; cnt++) { - if (!memcmp(phase_table+cnt, phase_ranges+cnt, 3)) { - phase = cnt+1; - break; - } + + new_index = find_element(phase_table[0], phase_ranges, 0); + if (new_index < 0) { + printf("%s : Wrong index ..\n",__func__); + return -EIO; } - phase = phase_table[phase]; + /* best case all phase will passed */ + j = 0; + if (new_index == 0) { + for (i =0; i < TOTAL_NUM_PHASE; i++) { + if ((phase_table[j] == phase_ranges[i])) + cnt++; + j++; + } + + if (cnt == TOTAL_NUM_PHASE) + return 4; + } else { + limit = TOTAL_NUM_PHASE - new_index; + j = 0; + cnt = 0; + for (i = new_index; i <= limit; i++) { + if (phase_table[j] == phase_ranges[i]) { + cnt++; + if (cnt == 3) + break; + } else if (phase_table[j] > phase_ranges[i]) { + + new_index = find_element(phase_table[j], phase_ranges, i); + if (new_index < 0) { + printf("%s : wrong index..\n",__func__); + return -EIO; + } + } + + j++; + } + } + phase = phase_ranges[i-1]; return phase; } @@ -4129,8 +4266,8 @@ static int qpic_execute_serial_training(struct mtd_info *mtd) } /* disable feed back clock bit to start serial training */ - writel((~FB_CLK_BIT & readl(NAND_QSPI_MSTR_CONFIG)), - NAND_QSPI_MSTR_CONFIG); + qpic_reg_write_bam(NAND_QSPI_MSTR_CONFIG, + (~FB_CLK_BIT & readl(NAND_QSPI_MSTR_CONFIG))); /* start serial training here */ curr_freq = io_macro_freq_tbl[index]; @@ -4158,8 +4295,8 @@ rettry: /* wrong data read on one of miso line * change the phase value and try again */ - continue; phase_failed++; + continue; } else { /* we got good phase update the good phase list */ @@ -4167,7 +4304,7 @@ rettry: /*printf("%s : Found good phase %d\n",__func__,phase);*/ } - } while (phase++ <= TOTAL_NUM_PHASE); + } while (phase++ < TOTAL_NUM_PHASE); if (phase_cnt) { /* Get the appropriate phase */ @@ -4394,16 +4531,28 @@ 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"); - writel((FB_CLK_BIT | readl(NAND_QSPI_MSTR_CONFIG)), - NAND_QSPI_MSTR_CONFIG); + 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); + qpic_reg_write_bam(NAND_FLASH_SPI_CFG, 0x0); + qpic_reg_write_bam(NAND_FLASH_SPI_CFG, SPI_CFG_VAL); + qpic_reg_write_bam(NAND_FLASH_SPI_CFG, + (SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN)); - qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, - GPLL0_CLK_SRC); + } else { + writel((FB_CLK_BIT | readl(NAND_QSPI_MSTR_CONFIG)), + NAND_QSPI_MSTR_CONFIG); - writel(0x0, NAND_FLASH_SPI_CFG); - writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG); - writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN), - NAND_FLASH_SPI_CFG); + qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, + GPLL0_CLK_SRC); + + writel(0x0, NAND_FLASH_SPI_CFG); + writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG); + writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN), + NAND_FLASH_SPI_CFG); + } } #endif /* Register with MTD subsystem. */ diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c index 4608cbafd1..ee8031b1cf 100644 --- a/drivers/mtd/spi/sf_params.c +++ b/drivers/mtd/spi/sf_params.c @@ -37,6 +37,7 @@ const struct spi_flash_params spi_flash_params_table[] = { {"GD25LQ32", 0xc86016, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K}, {"GD25Q128", 0xc84018, 0x0, 64 * 1024, 256, RD_NORM, SECT_4K}, {"GD25Q256", 0xc84019, 0x0, 64 * 1024, 512, RD_NORM, SECT_4K}, + {"GD25LB128D", 0xc86018, 0x0, 4 * 1024, 4096, RD_NORM, SECT_4K}, #endif #ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */ {"IS25LP032", 0x9d6016, 0x0, 64 * 1024, 64, RD_NORM, 0}, diff --git a/drivers/net/ipq5018/athrs17_phy.c b/drivers/net/ipq5018/athrs17_phy.c index 5fdca97dad..02fbd6d49c 100644 --- a/drivers/net/ipq5018/athrs17_phy.c +++ b/drivers/net/ipq5018/athrs17_phy.c @@ -171,8 +171,15 @@ int athrs17_init_switch(void) do { udelay(10); data = athrs17_reg_read(S17_MASK_CTRL_REG); + i++; + if (i == 10){ + printf("Failed to reset S17C \n"); + return -1; + } } while (data & S17_MASK_CTRL_SOFT_RET); + i = 0; + do { udelay(10); data = athrs17_reg_read(S17_GLOBAL_INT0_REG); @@ -191,14 +198,12 @@ int athrs17_init_switch(void) *********************************************************************/ void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg) { - uint32_t data; + athrs17_reg_write(S17_MAC_PWR_REG, gmac_cfg->mac_pwr); - data = athrs17_reg_read(S17_MAC_PWR_REG) | gmac_cfg->mac_pwr0; - athrs17_reg_write(S17_MAC_PWR_REG, data); - - athrs17_reg_write(S17_P0STATUS_REG, (S17_SPEED_1000M | S17_TXMAC_EN | - S17_RXMAC_EN | S17_TX_FLOW_EN | - S17_RX_FLOW_EN | S17_DUPLEX_FULL)); + athrs17_reg_write(S17_P0STATUS_REG, (S17_SPEED_1000M | + S17_TXMAC_EN | + S17_RXMAC_EN | + S17_DUPLEX_FULL)); athrs17_reg_write(S17_GLOFW_CTRL1_REG, (S17_IGMP_JOIN_LEAVE_DPALL | S17_BROAD_DPALL | @@ -206,10 +211,12 @@ void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg) S17_UNI_FLOOD_DPALL)); athrs17_reg_write(S17_P5PAD_MODE_REG, S17_MAC0_RGMII_RXCLK_DELAY); - athrs17_reg_write(S17_P0PAD_MODE_REG, (S17_MAC0_RGMII_EN | \ - S17_MAC0_RGMII_TXCLK_DELAY | S17_MAC0_RGMII_RXCLK_DELAY | \ - (0x1 << S17_MAC0_RGMII_TXCLK_SHIFT) | \ - (0x3 << S17_MAC0_RGMII_RXCLK_SHIFT))); + + athrs17_reg_write(S17_P0PAD_MODE_REG, (S17_MAC0_RGMII_EN | + S17_MAC0_RGMII_TXCLK_DELAY | + S17_MAC0_RGMII_RXCLK_DELAY | + (0x1 << S17_MAC0_RGMII_TXCLK_SHIFT) | + (0x2 << S17_MAC0_RGMII_RXCLK_SHIFT))); printf("%s: complete\n", __func__); } @@ -223,19 +230,16 @@ void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg) { uint32_t reg_val; - athrs17_reg_write(S17_P6STATUS_REG, (S17_SPEED_1000M | S17_TXMAC_EN | - S17_RXMAC_EN | - S17_DUPLEX_FULL)); - - reg_val = athrs17_reg_read(S17_MAC_PWR_REG) | gmac_cfg->mac_pwr1; - athrs17_reg_write(S17_MAC_PWR_REG, reg_val); + athrs17_reg_write(S17_P6STATUS_REG, (S17_SPEED_1000M | + S17_TXMAC_EN | + S17_RXMAC_EN | + S17_DUPLEX_FULL)); + athrs17_reg_write(S17_MAC_PWR_REG, gmac_cfg->mac_pwr); reg_val = athrs17_reg_read(S17_P6PAD_MODE_REG); athrs17_reg_write(S17_P6PAD_MODE_REG, (reg_val | S17_MAC6_SGMII_EN)); - reg_val = athrs17_reg_read(S17_PWS_REG); - athrs17_reg_write(S17_PWS_REG, (reg_val | - S17c_PWS_SERDES_ANEG_DISABLE)); + athrs17_reg_write(S17_PWS_REG, 0x2613a0); athrs17_reg_write(S17_SGMII_CTRL_REG,(S17c_SGMII_EN_PLL | S17c_SGMII_EN_RX | @@ -252,6 +256,8 @@ void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg) S17c_SGMII_PAUSE_25M | S17c_SGMII_HALF_DUPLEX_25M | S17c_SGMII_FULL_DUPLEX_25M)); + + athrs17_reg_write(S17_MODULE_EN_REG, S17_MIB_COUNTER_ENABLE); } struct athrs17_regmap { @@ -260,13 +266,18 @@ struct athrs17_regmap { }; struct athrs17_regmap regmap[] = { - { 0x000, 0x0e0 }, - { 0x100, 0x168 }, - { 0x200, 0x270 }, - { 0x400, 0x454 }, - { 0x600, 0x718 }, - { 0x800, 0xb70 }, - { 0xC00, 0xC80 }, + { 0x000, 0x0e4 }, + { 0x100, 0x168 }, + { 0x200, 0x270 }, + { 0x400, 0x454 }, + { 0x600, 0x718 }, + { 0x800, 0xb70 }, + { 0xC00, 0xC80 }, + { 0x1100, 0x11a7 }, + { 0x1200, 0x12a7 }, + { 0x1300, 0x13a7 }, + { 0x1400, 0x14a7 }, + { 0x1600, 0x16a7 }, }; int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/drivers/net/ipq5018/ipq5018_gmac.c b/drivers/net/ipq5018/ipq5018_gmac.c index 0dacbe7153..f436b9d7a1 100644 --- a/drivers/net/ipq5018/ipq5018_gmac.c +++ b/drivers/net/ipq5018/ipq5018_gmac.c @@ -37,6 +37,7 @@ uchar ipq_def_enetaddr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; phy_info_t *phy_info[IPQ5018_PHY_MAX] = {0}; extern int ipq_mdio_read(int mii_id, int regnum, ushort *data); +extern int ipq_mdio_write(int mii_id, int regnum, u16 value); extern int ipq5018_mdio_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); @@ -83,15 +84,24 @@ static void ipq_eth_mac_cfg(struct eth_device *dev) struct eth_mac_regs *mac_reg = (struct eth_mac_regs *)priv->mac_regs_p; uint ipq_mac_cfg = 0; + uint ipq_mac_framefilter = 0; ipq_mac_framefilter = PROMISCUOUS_MODE_ON; - ipq_mac_cfg |= (FRAME_BURST_ENABLE | JUMBO_FRAME_ENABLE | + if (priv->mac_unit) { + ipq_mac_cfg |= (FRAME_BURST_ENABLE | JUMBO_FRAME_ENABLE | JABBER_DISABLE | TX_ENABLE | RX_ENABLE | FULL_DUPLEX_ENABLE); - writel(ipq_mac_cfg, &mac_reg->conf); + writel(ipq_mac_cfg, &mac_reg->conf); + } else { + ipq_mac_cfg |= (priv->speed | FULL_DUPLEX_ENABLE | FRAME_BURST_ENABLE | + TX_ENABLE | RX_ENABLE); + writel(ipq_mac_cfg, &mac_reg->conf); + } + writel(ipq_mac_framefilter, &mac_reg->framefilt); + } static void ipq_eth_dma_cfg(struct eth_device *dev) @@ -240,6 +250,7 @@ static inline u32 ipq_gmac_is_desc_empty(ipq_gmac_desc_t *fr) { return ((fr->length & DescSize1Mask) == 0); } + static void ipq5018_gmac0_speed_clock_set(int speed_clock1, int speed_clock2, int gmacid) { @@ -254,7 +265,7 @@ static void ipq5018_gmac0_speed_clock_set(int speed_clock1, reg_value = 0; reg_value = readl(GCC_GMAC0_RX_CFG_RCGR + (iTxRx * 8) + (gmacid * 0x10)); - reg_value &= ~0x71f; + reg_value &= ~0x1f; reg_value |= speed_clock1; writel(reg_value, GCC_GMAC0_RX_CFG_RCGR + (iTxRx * 8) + (gmacid * 0x10)); @@ -277,10 +288,25 @@ static void ipq5018_gmac0_speed_clock_set(int speed_clock1, } } +static void ipq5018_enable_gephy(void) +{ + uint32_t reg_val; + + reg_val = readl(GCC_GEPHY_RX_CBCR); + reg_val |= GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GEPHY_RX_CBCR); + mdelay(20); + + reg_val = readl(GCC_GEPHY_TX_CBCR); + reg_val |= GCC_CBCR_CLK_ENABLE; + writel(reg_val, GCC_GEPHY_TX_CBCR); + mdelay(20); +} + static int ipq5018_phy_link_update(struct eth_device *dev) { struct ipq_eth_dev *priv = dev->priv; - u8 status; + u8 status = 1; struct phy_ops *phy_get_ops; fal_port_speed_t speed; fal_port_duplex_t duplex; @@ -300,8 +326,9 @@ static int ipq5018_phy_link_update(struct eth_device *dev) } if (priv->ipq_swith) { - speed_clock1 = 0x1; + speed_clock1 = 1; speed_clock2 = 0; + status = 0; } else { status = phy_get_ops->phy_get_link_status(priv->mac_unit, priv->phy_address); @@ -312,31 +339,39 @@ static int ipq5018_phy_link_update(struct eth_device *dev) switch (speed) { case FAL_SPEED_10: - speed_clock1 = 0x9; - speed_clock2 = 0x9; + 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, + priv->mac_unit, + lstatus[status], speed, dp[duplex]); break; case FAL_SPEED_100: - speed_clock1 = 0x9; + priv->speed = MII_PORT_SELECT; + speed_clock1 = 9; speed_clock2 = 0; printf ("eth%d %s Speed :%d %s duplex\n", - priv->mac_unit, lstatus[status], speed, + priv->mac_unit, + lstatus[status], speed, dp[duplex]); break; case FAL_SPEED_1000: - speed_clock1 = 0x1; + 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, + priv->mac_unit, + lstatus[status], speed, dp[duplex]); break; case FAL_SPEED_2500: - speed_clock1 = 0x1; + 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, + priv->mac_unit, + lstatus[status], speed, dp[duplex]); break; default: @@ -346,10 +381,13 @@ static int ipq5018_phy_link_update(struct eth_device *dev) } if (priv->mac_unit){ - if (priv->phy_type == QCA8081_PHY_TYPE) + if (priv->phy_type == QCA8081_PHY_TYPE || + priv->phy_type == QCA8081_1_1_PHY) ppe_uniphy_mode_set(PORT_WRAPPER_SGMII_PLUS); else ppe_uniphy_mode_set(PORT_WRAPPER_SGMII_FIBER); + } else { + ipq5018_enable_gephy(); } ipq5018_gmac0_speed_clock_set(speed_clock1, speed_clock2, priv->mac_unit); @@ -368,7 +406,9 @@ int ipq_eth_init(struct eth_device *dev, bd_t *this) struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p; u32 data; - if(ipq5018_phy_link_update(dev) < 0); + if(ipq5018_phy_link_update(dev) < 0) { + return -1; + } priv->next_rx = 0; priv->next_tx = 0; @@ -597,8 +637,49 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) if (ret) goto init_failed; if (ipq_gmac_macs[i]->ipq_swith){ - if (ipq_athrs17_init(gmac_cfg) != 0) - printf(" S17C switch init failed \n"); + /* 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) { + u32 value; + + 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); + value = ipq_mdio_read(port, 0, NULL); + value &= (~(1<<12)); + ipq_mdio_write(port, 0, value); + mdelay(100); + } + } else { phy_chip_id1 = ipq_mdio_read( ipq_gmac_macs[i]->phy_address, @@ -625,6 +706,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) */ case QCA8081_PHY: case QCA8081_1_1_PHY: + ipq_gmac_macs[i]->phy_type = QCA8081_PHY; ipq_qca8081_phy_init( &ipq_gmac_macs[i]->ops, ipq_gmac_macs[i]->phy_address); @@ -633,6 +715,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) * 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); @@ -641,10 +724,13 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) * 1G PHY */ case QCA8033_PHY: + ipq_gmac_macs[i]->phy_type = QCA8033_PHY; ipq_qca8033_phy_init( &ipq_gmac_macs[i]->ops, ipq_gmac_macs[i]->phy_address); break; + case S17C: + break; default: printf("GMAC%d : Invalid PHY ID \n", i); break; @@ -672,8 +758,3 @@ init_failed: return -ENOMEM; } -void ipq_gmac_common_init(ipq_gmac_board_cfg_t *gmac_cfg) -{ - return; -} - diff --git a/drivers/net/ipq5018/ipq5018_uniphy.c b/drivers/net/ipq5018/ipq5018_uniphy.c index 616ff31590..b0b0228529 100644 --- a/drivers/net/ipq5018/ipq5018_uniphy.c +++ b/drivers/net/ipq5018/ipq5018_uniphy.c @@ -59,24 +59,31 @@ static void ppe_gcc_uniphy_soft_reset(void) static void ppe_uniphy_sgmii_mode_set(uint32_t mode) { + bool force_enable =false; + writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE + UNIPHY_MISC2_REG_OFFSET); writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE + UNIPHY_PLL_RESET_REG_OFFSET); - mdelay(500); + mdelay(10); writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE + UNIPHY_PLL_RESET_REG_OFFSET); - mdelay(500); + mdelay(10); writel(0x0, GCC_UNIPHY_RX_CBCR); + udelay(500); writel(0x0, GCC_UNIPHY_TX_CBCR); + udelay(500); writel(0x0, GCC_GMAC1_RX_CBCR); + udelay(500); writel(0x0, GCC_GMAC1_TX_CBCR); + udelay(500); switch (mode) { case PORT_WRAPPER_SGMII_FIBER: writel(UNIPHY_SG_MODE, PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL); + force_enable = true; break; case PORT_WRAPPER_SGMII0_RGMII4: @@ -84,6 +91,7 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t mode) case PORT_WRAPPER_SGMII4_RGMII4: writel((UNIPHY_SG_MODE | UNIPHY_PSGMII_MAC_MODE), PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL); + force_enable = true; break; case PORT_WRAPPER_SGMII_PLUS: @@ -99,11 +107,24 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t mode) ppe_gcc_uniphy_soft_reset(); writel(0x1, GCC_UNIPHY_RX_CBCR); + udelay(500); writel(0x1, GCC_UNIPHY_TX_CBCR); + udelay(500); writel(0x1, GCC_GMAC1_RX_CBCR); + udelay(500); writel(0x1, GCC_GMAC1_TX_CBCR); + udelay(500); ppe_uniphy_calibration(); + +/* + * Force Speed mode enable + */ + if(force_enable){ + writel((readl(PPE_UNIPHY_BASE + UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4) | + UNIPHY_FORCE_SPEED_25M), + PPE_UNIPHY_BASE + UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4); + } } void ppe_uniphy_mode_set(uint32_t mode) diff --git a/drivers/net/ipq5018/ipq5018_uniphy.h b/drivers/net/ipq5018/ipq5018_uniphy.h index de1f599adf..ad4645d614 100644 --- a/drivers/net/ipq5018/ipq5018_uniphy.h +++ b/drivers/net/ipq5018/ipq5018_uniphy.h @@ -43,6 +43,9 @@ #define UNIPHY_CH1_CH0_SGMII (1 << 1) #define UNIPHY_CH0_ATHR_CSCO_MODE_25M (1 << 0) +#define UNIPHY_DEC_CHANNEL_0_INPUT_OUTPUT_4 0x480 +#define UNIPHY_FORCE_SPEED_25M (1 << 3) + #define UNIPHY_INSTANCE_LINK_DETECT 0x570 #define UNIPHY_MISC2_REG_OFFSET 0x218 diff --git a/include/configs/ipq5018.h b/include/configs/ipq5018.h index d4d5d7495b..ce1ebeca97 100644 --- a/include/configs/ipq5018.h +++ b/include/configs/ipq5018.h @@ -304,7 +304,7 @@ extern loff_t board_env_size; #define CONFIG_BOOTARGS "console=ttyMSM0,115200n8" #define QCA_ROOT_FS_PART_NAME "rootfs" -#define CONFIG_BOOTDELAY 2 +#define CONFIG_BOOTDELAY 5 #define NUM_ALT_PARTITION 16 @@ -331,7 +331,6 @@ extern loff_t board_env_size; #define SCM_CMD_TZ_PSHOLD 0x16 #define BOOT_VERSION 0 #define TZ_VERSION 1 -#define RPM_VERSION 3 #endif @@ -351,7 +350,7 @@ extern loff_t board_env_size; #define CONFIG_QCA_KERNEL_CRASHDUMP_ADDRESS *((unsigned int *)0x08600658) #define CONFIG_CPU_CONTEXT_DUMP_SIZE 4096 -#define TLV_BUF_OFFSET 244 * 1024 +#define TLV_BUF_OFFSET 1012 * 1024 #define CONFIG_TLV_DUMP_SIZE 12 * 1024 /* L1 cache line size is 64 bytes, L2 cache line size is 128 bytes