diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ecec5c7fff..d2e9a01fc4 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -63,13 +63,21 @@ dtb-$(CONFIG_ARCH_IPQ40xx) += ipq40xx-dk01-c1.dtb \ ipq40xx-dk01-s1.dtb \ ipq40xx-dk06-c1.dtb +ifneq ($(CONFIG_IPQ_TINY),y) dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb \ ipq5018-mp02.1.dtb \ - ipq5018-mp03.1.dtb \ + ipq5018-mp03.1-c2.dtb \ ipq5018-mp03.3.dtb \ + ipq5018-mp03.3-c2.dtb \ ipq5018-db-mp02.1.dtb \ ipq5018-db-mp03.1.dtb \ - ipq5018-db-mp03.3.dtb + ipq5018-db-mp03.1-c2.dtb \ + ipq5018-db-mp03.3.dtb \ + ipq5018-db-mp03.3-c2.dtb \ + ipq5018-sod.dtb +else +dtb-$(CONFIG_ARCH_IPQ5018) += ipq5018-emulation.dtb +endif dtb-$(CONFIG_ARCH_IPQ6018) += ipq6018-cp01-c1.dtb \ ipq6018-cp02-c1.dtb \ diff --git a/arch/arm/dts/ipq5018-db-mp02.1.dts b/arch/arm/dts/ipq5018-db-mp02.1.dts index 3bd99d5403..1921d890de 100644 --- a/arch/arm/dts/ipq5018-db-mp02.1.dts +++ b/arch/arm/dts/ipq5018-db-mp02.1.dts @@ -16,7 +16,7 @@ / { model ="QCA, IPQ5018/DB-MP02.1"; compatible = "qca,ipq5018", "qca,ipq5018-db-mp02.1"; - machid = <0x1040000>; + machid = <0x1040003>; config_name = "config@db-mp02.1"; aliases { @@ -26,15 +26,53 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + pci1 = "/pci@a0000000"; }; - mmc: sdhci@7804000 { - status = "disabled"; - }; - - nand: nand-controller@79B0000 { + console: serial@78AF000 { status = "ok"; - nand_gpio {}; + serial_gpio { + blsp0_uart_rx { + gpio = <28>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <29>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + }; + }; + + pci0: pci@80000000 { + status = "ok"; + pci_gpio { + pcie_rst_n_5G { + gpio = <15>; + func = <0>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pcie_rst_n_6G { + gpio = <27>; + func = <0>; + pull = ; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-db-mp03.1-c2.dts b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts new file mode 100644 index 0000000000..12ae8d9828 --- /dev/null +++ b/arch/arm/dts/ipq5018-db-mp03.1-c2.dts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "ipq5018-db-mp03.1.dts" +/ { + model ="QCA, IPQ5018/DB-MP03.1-C2"; + compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.1-c2"; + machid = <0x1040104>; + config_name = "config@db-mp03.1-c2"; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + status = "okay"; + mmc_gpio { + emmc_dat3 { + gpio = <4>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat2 { + gpio = <5>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat1 { + gpio = <6>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat0 { + gpio = <7>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_cmd{ + gpio = <8>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_clk{ + gpio = <9>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + nand: nand-controller@79B0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/dts/ipq5018-db-mp03.1.dts b/arch/arm/dts/ipq5018-db-mp03.1.dts index f8b09caeb1..c37a7b603b 100644 --- a/arch/arm/dts/ipq5018-db-mp03.1.dts +++ b/arch/arm/dts/ipq5018-db-mp03.1.dts @@ -16,7 +16,7 @@ / { model ="QCA, IPQ5018/DB-MP03.1"; compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.1"; - machid = <0x1040100>; + machid = <0x1040004>; config_name = "config@db-mp03.1"; aliases { @@ -26,15 +26,96 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + pci1 = "/pci@a0000000"; + nand = "/nand-controller@79B0000"; }; - mmc: sdhci@7804000 { - compatible = "qcom,sdhci-msm"; + console: serial@78AF000 { + status = "ok"; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + }; }; nand: nand-controller@79B0000 { + status = "okay"; + nand_gpio { + qspi_dat3 { + gpio = <4>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat2 { + gpio = <5>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat1 { + gpio = <6>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat0 { + gpio = <7>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_cs_n { + gpio = <8>; + func = <2>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci0: pci@80000000 { status = "ok"; - nand_gpio {}; + pci_gpio { + pci_rst { + gpio = <15>; + func = <0>; + pull = ; + oe = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <18>; + func = <0>; + pull = ; + oe = ; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-db-mp03.3-c2.dts b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts new file mode 100644 index 0000000000..2451ffb2d6 --- /dev/null +++ b/arch/arm/dts/ipq5018-db-mp03.3-c2.dts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "ipq5018-db-mp03.3.dts" +/ { + model ="QCA, IPQ5018/DB-MP03.3-C2"; + compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.3-c2"; + machid = <0x1040105>; + config_name = "config@db-mp03.3-c2"; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + status = "okay"; + mmc_gpio { + emmc_dat3 { + gpio = <4>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat2 { + gpio = <5>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat1 { + gpio = <6>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat0 { + gpio = <7>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_cmd{ + gpio = <8>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_clk{ + gpio = <9>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + nand: nand-controller@79B0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/dts/ipq5018-db-mp03.3.dts b/arch/arm/dts/ipq5018-db-mp03.3.dts index aa9c60a666..75c02aa547 100644 --- a/arch/arm/dts/ipq5018-db-mp03.3.dts +++ b/arch/arm/dts/ipq5018-db-mp03.3.dts @@ -16,7 +16,7 @@ / { model ="QCA, IPQ5018/DB-MP03.3"; compatible = "qca,ipq5018", "qca,ipq5018-db-mp03.3"; - machid = <0x1040200>; + machid = <0x1040005>; config_name = "config@db-mp03.3"; aliases { @@ -26,15 +26,89 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + nand = "/nand-controller@79B0000"; }; - mmc: sdhci@7804000 { - compatible = "qcom,sdhci-msm"; + console: serial@78AF000 { + status = "ok"; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + }; }; nand: nand-controller@79B0000 { + status = "okay"; + nand_gpio { + qspi_dat3 { + gpio = <4>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat2 { + gpio = <5>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat1 { + gpio = <6>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat0 { + gpio = <7>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_cs_n { + gpio = <8>; + func = <2>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci0: pci@80000000 { status = "ok"; - nand_gpio {}; + pci_gpio { + pci_rst { + gpio = <15>; + func = <0>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <18>; + func = <0>; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-emulation.dts b/arch/arm/dts/ipq5018-emulation.dts index 928a2a8242..b0fe1d4aaf 100644 --- a/arch/arm/dts/ipq5018-emulation.dts +++ b/arch/arm/dts/ipq5018-emulation.dts @@ -26,15 +26,100 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + nand = "/nand-controller@79B0000"; }; mmc: sdhci@7804000 { compatible = "qcom,sdhci-msm"; }; - nand: nand-controller@79B0000 { + console: serial@78AF000 { status = "ok"; - nand_gpio {}; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + }; + }; + + nand: nand-controller@79B0000 { + status = "okay"; + nand_gpio { + qspi_dat3 { + gpio = <4>; + func = <2>; + oe = ; + od_en = ; + drvstr = ; + }; + qspi_dat2 { + gpio = <5>; + func = <2>; + oe = ; + od_en = ; + drvstr = ; + }; + qspi_dat1 { + gpio = <6>; + func = <2>; + oe = ; + od_en = ; + drvstr = ; + }; + qspi_dat0 { + gpio = <7>; + func = <2>; + oe = ; + od_en = ; + drvstr = ; + }; + qspi_cs_n { + gpio = <8>; + func = <2>; + oe = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci0: pci@80000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <15>; + func = <0>; + oe = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <18>; + func = <0>; + oe = ; + od_en = ; + drvstr = ; + }; + }; }; timer { @@ -43,11 +128,12 @@ gmac_cfg { gmac_count = <2>; - + ext_mdio_gpio = <1>; gmac1_cfg { unit = <0>; base = <0x39C00000>; phy_address = <7>; + phy_interface_mode = <2>; phy_name = "IPQ MDIO0"; }; @@ -55,7 +141,11 @@ unit = <1>; base = <0x39D00000>; phy_address = <1>; + phy_interface_mode = <2>; phy_name = "IPQ MDIO1"; + mac_pwr0 = <0x00080000>; + mac_pwr1 = <0x00040000>; + s17c_switch_enable = <0>; }; }; diff --git a/arch/arm/dts/ipq5018-mp02.1.dts b/arch/arm/dts/ipq5018-mp02.1.dts index a7decd243f..1d1d571d42 100644 --- a/arch/arm/dts/ipq5018-mp02.1.dts +++ b/arch/arm/dts/ipq5018-mp02.1.dts @@ -26,15 +26,53 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + pci1 = "/pci@a0000000"; }; - mmc: sdhci@7804000 { - status = "disabled"; - }; - - nand: nand-controller@79B0000 { + console: serial@78AF000 { status = "ok"; - nand_gpio {}; + serial_gpio { + blsp0_uart_rx { + gpio = <28>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <29>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + }; + }; + + pci0: pci@80000000 { + status = "ok"; + pci_gpio { + pcie_rst_n_5G { + gpio = <15>; + func = <0>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pcie_rst_n_6G { + gpio = <27>; + func = <0>; + pull = ; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-mp03.1-c2.dts b/arch/arm/dts/ipq5018-mp03.1-c2.dts new file mode 100644 index 0000000000..c77894fc71 --- /dev/null +++ b/arch/arm/dts/ipq5018-mp03.1-c2.dts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "ipq5018-mp03.1.dts" +/ { + model ="QCA, IPQ5018-MP03.1-C2"; + compatible = "qca,ipq5018", "qca,ipq5018-mp03.1-c2"; + machid = <0x8040101>; + config_name = "config@mp03.1-c2"; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + status = "okay"; + mmc_gpio { + emmc_dat3 { + gpio = <4>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat2 { + gpio = <5>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat1 { + gpio = <6>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat0 { + gpio = <7>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_cmd{ + gpio = <8>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_clk{ + gpio = <9>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + nand: nand-controller@79B0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/dts/ipq5018-mp03.1.dts b/arch/arm/dts/ipq5018-mp03.1.dts index c86c4b79d5..605ff5e574 100644 --- a/arch/arm/dts/ipq5018-mp03.1.dts +++ b/arch/arm/dts/ipq5018-mp03.1.dts @@ -16,7 +16,7 @@ / { model ="QCA, IPQ5018-MP03.1"; compatible = "qca,ipq5018", "qca,ipq5018-mp03.1"; - machid = <0x8040100>; + machid = <0x8040001>; config_name = "config@mp03.1"; aliases { @@ -26,15 +26,96 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + pci1 = "/pci@a0000000"; + nand = "/nand-controller@79B0000"; }; - mmc: sdhci@7804000 { - compatible = "qcom,sdhci-msm"; + console: serial@78AF000 { + status = "ok"; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + }; }; nand: nand-controller@79B0000 { + status = "okay"; + nand_gpio { + qspi_dat3 { + gpio = <4>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat2 { + gpio = <5>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat1 { + gpio = <6>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_dat0 { + gpio = <7>; + func = <2>; + pull = ; + od_en = ; + drvstr = ; + }; + qspi_cs_n { + gpio = <8>; + func = <2>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci0: pci@80000000 { status = "ok"; - nand_gpio {}; + pci_gpio { + pci_rst { + gpio = <15>; + func = <0>; + pull = ; + oe = ; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <18>; + func = <0>; + pull = ; + oe = ; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-mp03.3-c2.dts b/arch/arm/dts/ipq5018-mp03.3-c2.dts new file mode 100644 index 0000000000..7cef9202cf --- /dev/null +++ b/arch/arm/dts/ipq5018-mp03.3-c2.dts @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include "ipq5018-mp03.3.dts" +/ { + model ="QCA, IPQ5018-MP03.3-C2"; + compatible = "qca,ipq5018", "qca,ipq5018-mp03.3-c2"; + machid = <0x8040102>; + config_name = "config@mp03.3-c2"; + + mmc: sdhci@7804000 { + compatible = "qcom,sdhci-msm"; + status = "okay"; + mmc_gpio { + emmc_dat3 { + gpio = <4>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat2 { + gpio = <5>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat1 { + gpio = <6>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_dat0 { + gpio = <7>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_cmd{ + gpio = <8>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + emmc_clk{ + gpio = <9>; + func = <1>; + pull = ; + od_en = ; + drvstr = ; + }; + }; + }; + + nand: nand-controller@79B0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/dts/ipq5018-mp03.3.dts b/arch/arm/dts/ipq5018-mp03.3.dts index aafcc29876..9f760cbd6e 100644 --- a/arch/arm/dts/ipq5018-mp03.3.dts +++ b/arch/arm/dts/ipq5018-mp03.3.dts @@ -16,7 +16,7 @@ / { model ="QCA, IPQ5018-MP03.3"; compatible = "qca,ipq5018", "qca,ipq5018-mp03.3"; - machid = <0x08040200>; + machid = <0x8040002>; config_name = "config@mp03.3"; aliases { @@ -26,15 +26,90 @@ gmac_gpio = "/gmac_gpio"; usb0 = "/xhci@8a00000"; pci0 = "/pci@80000000"; + pcie1 = "/pci@a0000000"; + nand = "/nand-controller@79B0000"; }; - mmc: sdhci@7804000 { - compatible = "qcom,sdhci-msm"; + console: serial@78AF000 { + status = "ok"; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + od_en = ; + }; + }; }; nand: nand-controller@79B0000 { + status = "okay"; + nand_gpio { + qspi_dat3 { + gpio = <4>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat2 { + gpio = <5>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat1 { + gpio = <6>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_dat0 { + gpio = <7>; + func = <2>; + od_en = ; + drvstr = ; + }; + qspi_cs_n { + gpio = <8>; + func = <2>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci0: pci@80000000 { status = "ok"; - nand_gpio {}; + pci_gpio { + pci_rst { + gpio = <15>; + func = <0>; + od_en = ; + drvstr = ; + }; + }; + }; + + pci1: pci@a0000000 { + status = "ok"; + pci_gpio { + pci_rst { + gpio = <18>; + func = <0>; + od_en = ; + drvstr = ; + }; + }; }; gmac_cfg { diff --git a/arch/arm/dts/ipq5018-soc.dtsi b/arch/arm/dts/ipq5018-soc.dtsi index 38c13fe79c..e139a29964 100644 --- a/arch/arm/dts/ipq5018-soc.dtsi +++ b/arch/arm/dts/ipq5018-soc.dtsi @@ -19,31 +19,11 @@ serial@78AF000 { compatible = "qca,ipq-uartdm"; reg = <0x78af000 0x200>; - id = <2>; + m_value = <0x24>; + n_value = <0xC31A>; + d_value = <0xC2F6>; bit_rate = <0xff>; - status = "ok"; - serial_gpio { - gpio1 { - gpio = <20>; - func = <1>; - pull = ; - oe = ; - drvstr = ; - od_en = ; - sr_en = ; - pu_res =; - }; - gpio2 { - gpio = <21>; - func = <1>; - pull = ; - oe = ; - drvstr = ; - od_en = ; - sr_en = ; - pu_res =; - }; - }; + status = "disabled"; }; timer { @@ -54,11 +34,38 @@ }; spi { - status = "ok"; compatible = "qcom,spi-qup-v2.7.0"; wr_pipe_0 = <4>; rd_pipe_0 = <5>; - spi_gpio {}; + status = "ok"; + spi_gpio { + blsp0_spi_clk { + gpio = <10>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + }; + blsp0_spi_mosi { + gpio = <11>; + func = <1>; + pull = ; + oe = ; + drvstr = ; + }; + blsp0_spi_miso { + gpio = <12>; + func = <1>; + pull = ; + drvstr = ; + }; + blsp0_spi_cs { + gpio = <13>; + func = <1>; + oe = ; + drvstr = ; + }; + }; }; nand: nand-controller@79B0000 { @@ -66,51 +73,7 @@ #size-cells = <0>; compatible = "qcom,qpic-nand-v2.1.1"; reg = <0x79B0000 0x10000>; - - nand_gpio { - qspi_data0 { - gpio = <7>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - qspi_data1 { - gpio = <6>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - qspi_data2 { - gpio = <5>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - qspi_data3 { - gpio = <4>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - qspi_cs_n { - gpio = <8>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - qspi_clk { - gpio = <9>; - func = <2>; - pull = ; - drvstr = ; - oe = ; - }; - }; + status = "disabled"; }; i2c@78b6000 { @@ -163,46 +126,8 @@ "axi_conf", "pci_rst", "pci_phy"; perst_gpio = <27>; gen3 = <1>; - - pci_gpio { - gpio1 { - gpio = <14>; - func = <0>; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - gpio2 { - gpio = <15>; - func = <0>; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - gpio3 { - gpio = <16>; - func = <0>; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - gpio4 { - gpio = <27>; - func = <0>; - out = ; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - }; + status = "disabled"; + skip_phy_init = <1>; }; pci@a0000000 { @@ -221,28 +146,7 @@ "axi_conf", "pci_rst", "pci_phy"; perst_gpio = <28>; gen3 = <1>; - - pci_gpio { - gpio1 { - gpio = <17>; - func = <0>; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - gpio2 { - gpio = <28>; - func = <0>; - out = ; - pull = ; - drvstr = ; - oe = ; - od_en = ; - pu_res = ; - }; - }; + status = "disabled"; + skip_phy_init = <1>; }; - }; diff --git a/arch/arm/dts/ipq5018-sod.dts b/arch/arm/dts/ipq5018-sod.dts new file mode 100644 index 0000000000..38402d822e --- /dev/null +++ b/arch/arm/dts/ipq5018-sod.dts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "skeleton.dtsi" +#include +/ { + model ="QCA, IPQ5018-MP03.1"; + compatible = "qca,ipq5018", "qca,ipq5018-mp03.1"; + machid = <0x8040001>; + config_name = "config@mp03.1"; + + serial@78AF000 { + compatible = "qca,ipq-uartdm"; + reg = <0x78af000 0x200>; + m_value = <0x24>; + n_value = <0xC31A>; + d_value = <0xC2F6>; + bit_rate = <0xff>; + status = "ok"; + serial_gpio { + blsp0_uart_rx { + gpio = <20>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + blsp0_uart_tx { + gpio = <21>; + func = <1>; + pull = ; + drvstr = ; + od_en = ; + }; + }; + }; + + timer { + gcnt_cntcv_lo = <0x4a2000>; + gcnt_cntcv_hi = <0x4a2004>; + gpt_freq_hz = <24000000>; + timer_load_val = <0x00FFFFFF 0xFFFFFFFF>; + }; + + aliases { + console = "/serial@78AF000"; + }; + + +}; diff --git a/arch/arm/dts/ipq6018-soc.dtsi b/arch/arm/dts/ipq6018-soc.dtsi index f19906b586..801b217223 100644 --- a/arch/arm/dts/ipq6018-soc.dtsi +++ b/arch/arm/dts/ipq6018-soc.dtsi @@ -22,6 +22,9 @@ reg = <0x78B1000 0x200>; id = <4>; bit_rate = <0xff>; + m_value = <36>; + n_value = <15625>; + d_value = <15625>; serial_gpio { gpio1 { gpio = <44>; diff --git a/arch/arm/dts/ipq807x-hk01.dts b/arch/arm/dts/ipq807x-hk01.dts index 7d0afcbf12..19eb620941 100644 --- a/arch/arm/dts/ipq807x-hk01.dts +++ b/arch/arm/dts/ipq807x-hk01.dts @@ -16,7 +16,7 @@ #include / { machid = <0x08010000>; - config_name = "config@hk01"; + config_name = "config@hk01", "config@hk01.c1"; aliases { console = "/serial@78B3000"; diff --git a/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h new file mode 100644 index 0000000000..d5c1d4f193 --- /dev/null +++ b/arch/arm/include/asm/arch-ipq5018/athrs17_phy.h @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ATHRS17_PHY_H +#define _ATHRS17_PHY_H + +/*****************/ +/* PHY Registers */ +/*****************/ +#define ATHR_PHY_CONTROL 0 +#define ATHR_PHY_STATUS 1 +#define ATHR_PHY_ID1 2 +#define ATHR_PHY_ID2 3 +#define ATHR_AUTONEG_ADVERT 4 +#define ATHR_LINK_PARTNER_ABILITY 5 +#define ATHR_AUTONEG_EXPANSION 6 +#define ATHR_NEXT_PAGE_TRANSMIT 7 +#define ATHR_LINK_PARTNER_NEXT_PAGE 8 +#define ATHR_1000BASET_CONTROL 9 +#define ATHR_1000BASET_STATUS 10 +#define ATHR_PHY_SPEC_CONTROL 16 +#define ATHR_PHY_SPEC_STATUS 17 +#define ATHR_DEBUG_PORT_ADDRESS 29 +#define ATHR_DEBUG_PORT_DATA 30 + +/* ATHR_PHY_CONTROL fields */ +#define ATHR_CTRL_SOFTWARE_RESET 0x8000 +#define ATHR_CTRL_SPEED_LSB 0x2000 +#define ATHR_CTRL_AUTONEGOTIATION_ENABLE 0x1000 +#define ATHR_CTRL_RESTART_AUTONEGOTIATION 0x0200 +#define ATHR_CTRL_SPEED_FULL_DUPLEX 0x0100 +#define ATHR_CTRL_SPEED_MSB 0x0040 + +#define ATHR_RESET_DONE(phy_control) \ + (((phy_control) & (ATHR_CTRL_SOFTWARE_RESET)) == 0) + +/* Phy status fields */ +#define ATHR_STATUS_AUTO_NEG_DONE 0x0020 + +#define ATHR_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & \ + (ATHR_STATUS_AUTO_NEG_DONE)) == \ + (ATHR_STATUS_AUTO_NEG_DONE)) + +/* Link Partner ability */ +#define ATHR_LINK_100BASETX_FULL_DUPLEX 0x0100 +#define ATHR_LINK_100BASETX 0x0080 +#define ATHR_LINK_10BASETX_FULL_DUPLEX 0x0040 +#define ATHR_LINK_10BASETX 0x0020 + +/* Advertisement register. */ +#define ATHR_ADVERTISE_NEXT_PAGE 0x8000 +#define ATHR_ADVERTISE_ASYM_PAUSE 0x0800 +#define ATHR_ADVERTISE_PAUSE 0x0400 +#define ATHR_ADVERTISE_100FULL 0x0100 +#define ATHR_ADVERTISE_100HALF 0x0080 +#define ATHR_ADVERTISE_10FULL 0x0040 +#define ATHR_ADVERTISE_10HALF 0x0020 + +#define ATHR_ADVERTISE_ALL (ATHR_ADVERTISE_ASYM_PAUSE | ATHR_ADVERTISE_PAUSE | \ + ATHR_ADVERTISE_10HALF | ATHR_ADVERTISE_10FULL | \ + ATHR_ADVERTISE_100HALF | ATHR_ADVERTISE_100FULL) + +/* 1000BASET_CONTROL */ +#define ATHR_ADVERTISE_1000FULL 0x0200 + +/* Phy Specific status fields */ +#define ATHER_STATUS_LINK_MASK 0xC000 +#define ATHER_STATUS_LINK_SHIFT 14 +#define ATHER_STATUS_FULL_DEPLEX 0x2000 +#define ATHR_STATUS_LINK_PASS 0x0400 +#define ATHR_STATUS_RESOVLED 0x0800 + +/*phy debug port register */ +#define ATHER_DEBUG_SERDES_REG 5 + +/* Serdes debug fields */ +#define ATHER_SERDES_BEACON 0x0100 + +/* S17 CSR Registers */ + +#define S17_ENABLE_CPU_BROADCAST (1 << 26) + +#define S17_PHY_LINK_CHANGE_REG 0x4 +#define S17_PHY_LINK_UP 0x400 +#define S17_PHY_LINK_DOWN 0x800 +#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000 +#define S17_PHY_LINK_SPEED_CHANGE 0x4000 +#define S17_PHY_LINK_INTRS (PHY_LINK_UP | PHY_LINK_DOWN | PHY_LINK_DUPLEX_CHANGE | PHY_LINK_SPEED_CHANGE) + +#define S17_MASK_CTRL_REG 0x0000 +#define S17_P0PAD_MODE_REG 0x0004 +#define S17_P5PAD_MODE_REG 0x0008 +#define S17_P6PAD_MODE_REG 0x000c +#define S17_PWS_REG 0x0010 +#define S17_GLOBAL_INT0_REG 0x0020 +#define S17_GLOBAL_INT1_REG 0x0024 +#define S17_GLOBAL_INTMASK0 0x0028 +#define S17_GLOBAL_INTMASK1 0x002c +#define S17_MODULE_EN_REG 0x0030 +#define S17_MIB_REG 0x0034 +#define S17_INTF_HIADDR_REG 0x0038 +#define S17_MDIO_CTRL_REG 0x003c +#define S17_BIST_CTRL_REG 0x0040 +#define S17_BIST_REC_REG 0x0044 +#define S17_SERVICE_REG 0x0048 +#define S17_LED_CTRL0_REG 0x0050 +#define S17_LED_CTRL1_REG 0x0054 +#define S17_LED_CTRL2_REG 0x0058 +#define S17_LED_CTRL3_REG 0x005c +#define S17_MACADDR0_REG 0x0060 +#define S17_MACADDR1_REG 0x0064 +#define S17_MAX_FRAME_SIZE_REG 0x0078 +#define S17_P0STATUS_REG 0x007c +#define S17_P1STATUS_REG 0x0080 +#define S17_P2STATUS_REG 0x0084 +#define S17_P3STATUS_REG 0x0088 +#define S17_P4STATUS_REG 0x008c +#define S17_P5STATUS_REG 0x0090 +#define S17_P6STATUS_REG 0x0094 +#define S17_HDRCTRL_REG 0x0098 +#define S17_P0HDRCTRL_REG 0x009c +#define S17_P1HDRCTRL_REG 0x00A0 +#define S17_P2HDRCTRL_REG 0x00a4 +#define S17_P3HDRCTRL_REG 0x00a8 +#define S17_P4HDRCTRL_REG 0x00ac +#define S17_P5HDRCTRL_REG 0x00b0 +#define S17_P6HDRCTRL_REG 0x00b4 +#define S17_SGMII_CTRL_REG 0x00e0 +#define S17_MAC_PWR_REG 0x00e4 +#define S17_EEE_CTRL_REG 0x0100 + +/* ACL Registers */ +#define S17_ACL_FUNC0_REG 0x0400 +#define S17_ACL_FUNC1_REG 0x0404 +#define S17_ACL_FUNC2_REG 0x0408 +#define S17_ACL_FUNC3_REG 0x040c +#define S17_ACL_FUNC4_REG 0x0410 +#define S17_ACL_FUNC5_REG 0x0414 +#define S17_PRIVATE_IP_REG 0x0418 +#define S17_P0VLAN_CTRL0_REG 0x0420 +#define S17_P0VLAN_CTRL1_REG 0x0424 +#define S17_P1VLAN_CTRL0_REG 0x0428 +#define S17_P1VLAN_CTRL1_REG 0x042c +#define S17_P2VLAN_CTRL0_REG 0x0430 +#define S17_P2VLAN_CTRL1_REG 0x0434 +#define S17_P3VLAN_CTRL0_REG 0x0438 +#define S17_P3VLAN_CTRL1_REG 0x043c +#define S17_P4VLAN_CTRL0_REG 0x0440 +#define S17_P4VLAN_CTRL1_REG 0x0444 +#define S17_P5VLAN_CTRL0_REG 0x0448 +#define S17_P5VLAN_CTRL1_REG 0x044c +#define S17_P6VLAN_CTRL0_REG 0x0450 +#define S17_P6VLAN_CTRL1_REG 0x0454 + +/* Table Lookup Registers */ +#define S17_ATU_DATA0_REG 0x0600 +#define S17_ATU_DATA1_REG 0x0604 +#define S17_ATU_DATA2_REG 0x0608 +#define S17_ATU_FUNC_REG 0x060C +#define S17_VTU_FUNC0_REG 0x0610 +#define S17_VTU_FUNC1_REG 0x0614 +#define S17_ARL_CTRL_REG 0x0618 +#define S17_GLOFW_CTRL0_REG 0x0620 +#define S17_GLOFW_CTRL1_REG 0x0624 +#define S17_GLOLEARN_LIMIT_REG 0x0628 +#define S17_TOS_PRIMAP_REG0 0x0630 +#define S17_TOS_PRIMAP_REG1 0x0634 +#define S17_TOS_PRIMAP_REG2 0x0638 +#define S17_TOS_PRIMAP_REG3 0x063c +#define S17_TOS_PRIMAP_REG4 0x0640 +#define S17_TOS_PRIMAP_REG5 0x0644 +#define S17_TOS_PRIMAP_REG6 0x0648 +#define S17_TOS_PRIMAP_REG7 0x064c +#define S17_VLAN_PRIMAP_REG0 0x0650 +#define S17_LOOP_CHECK_REG 0x0654 +#define S17_P0LOOKUP_CTRL_REG 0x0660 +#define S17_P0PRI_CTRL_REG 0x0664 +#define S17_P0LEARN_LMT_REG 0x0668 +#define S17_P1LOOKUP_CTRL_REG 0x066c +#define S17_P1PRI_CTRL_REG 0x0670 +#define S17_P1LEARN_LMT_REG 0x0674 +#define S17_P2LOOKUP_CTRL_REG 0x0678 +#define S17_P2PRI_CTRL_REG 0x067c +#define S17_P2LEARN_LMT_REG 0x0680 +#define S17_P3LOOKUP_CTRL_REG 0x0684 +#define S17_P3PRI_CTRL_REG 0x0688 +#define S17_P3LEARN_LMT_REG 0x068c +#define S17_P4LOOKUP_CTRL_REG 0x0690 +#define S17_P4PRI_CTRL_REG 0x0694 +#define S17_P4LEARN_LMT_REG 0x0698 +#define S17_P5LOOKUP_CTRL_REG 0x069c +#define S17_P5PRI_CTRL_REG 0x06a0 +#define S17_P5LEARN_LMT_REG 0x06a4 +#define S17_P6LOOKUP_CTRL_REG 0x06a8 +#define S17_P6PRI_CTRL_REG 0x06ac +#define S17_P6LEARN_LMT_REG 0x06b0 +#define S17_GLO_TRUNK_CTRL0_REG 0x0700 +#define S17_GLO_TRUNK_CTRL1_REG 0x0704 +#define S17_GLO_TRUNK_CTRL2_REG 0x0708 + +/* Queue Management Registers */ +#define S17_PORT0_HOL_CTRL0 0x0970 +#define S17_PORT0_HOL_CTRL1 0x0974 +#define S17_PORT1_HOL_CTRL0 0x0978 +#define S17_PORT1_HOL_CTRL1 0x097c +#define S17_PORT2_HOL_CTRL0 0x0980 +#define S17_PORT2_HOL_CTRL1 0x0984 +#define S17_PORT3_HOL_CTRL0 0x0988 +#define S17_PORT3_HOL_CTRL1 0x098c +#define S17_PORT4_HOL_CTRL0 0x0990 +#define S17_PORT4_HOL_CTRL1 0x0994 +#define S17_PORT5_HOL_CTRL0 0x0998 +#define S17_PORT5_HOL_CTRL1 0x099c +#define S17_PORT6_HOL_CTRL0 0x09a0 +#define S17_PORT6_HOL_CTRL1 0x09a4 + +/* Port flow control registers */ +#define S17_P0_FLCTL_REG 0x09b0 +#define S17_P1_FLCTL_REG 0x09b4 +#define S17_P2_FLCTL_REG 0x09b8 +#define S17_P3_FLCTL_REG 0x09bc +#define S17_P4_FLCTL_REG 0x09c0 +#define S17_P5_FLCTL_REG 0x09c4 + +/* Packet Edit registers */ +#define S17_PKT_EDIT_CTRL 0x0c00 +#define S17_P0Q_REMAP_REG0 0x0c40 +#define S17_P0Q_REMAP_REG1 0x0c44 +#define S17_P1Q_REMAP_REG0 0x0c48 +#define S17_P2Q_REMAP_REG0 0x0c4c +#define S17_P3Q_REMAP_REG0 0x0c50 +#define S17_P4Q_REMAP_REG0 0x0c54 +#define S17_P5Q_REMAP_REG0 0x0c58 +#define S17_P5Q_REMAP_REG1 0x0c5c +#define S17_P6Q_REMAP_REG0 0x0c60 +#define S17_P6Q_REMAP_REG1 0x0c64 +#define S17_ROUTER_VID0 0x0c70 +#define S17_ROUTER_VID1 0x0c74 +#define S17_ROUTER_VID2 0x0c78 +#define S17_ROUTER_VID3 0x0c7c +#define S17_ROUTER_EG_VLAN_MODE 0x0c80 + +/* L3 Registers */ +#define S17_HROUTER_CTRL_REG 0x0e00 +#define S17_HROUTER_PBCTRL0_REG 0x0e04 +#define S17_HROUTER_PBCTRL1_REG 0x0e08 +#define S17_HROUTER_PBCTRL2_REG 0x0e0c +#define S17_WCMP_HASH_TABLE0_REG 0x0e10 +#define S17_WCMP_HASH_TABLE1_REG 0x0e14 +#define S17_WCMP_HASH_TABLE2_REG 0x0e18 +#define S17_WCMP_HASH_TABLE3_REG 0x0e1c +#define S17_WCMP_NHOP_TABLE0_REG 0x0e20 +#define S17_WCMP_NHOP_TABLE1_REG 0x0e24 +#define S17_WCMP_NHOP_TABLE2_REG 0x0e28 +#define S17_WCMP_NHOP_TABLE3_REG 0x0e2c +#define S17_ARP_ENTRY_CTRL_REG 0x0e30 +#define S17_ARP_USECNT_REG 0x0e34 +#define S17_HNAT_CTRL_REG 0x0e38 +#define S17_NAPT_ENTRY_CTRL0_REG 0x0e3c +#define S17_NAPT_ENTRY_CTRL1_REG 0x0e40 +#define S17_NAPT_USECNT_REG 0x0e44 +#define S17_ENTRY_EDIT_DATA0_REG 0x0e48 +#define S17_ENTRY_EDIT_DATA1_REG 0x0e4c +#define S17_ENTRY_EDIT_DATA2_REG 0x0e50 +#define S17_ENTRY_EDIT_DATA3_REG 0x0e54 +#define S17_ENTRY_EDIT_CTRL_REG 0x0e58 +#define S17_HNAT_PRIVATE_IP_REG 0x0e5c + +/* MIB counters */ +#define S17_MIB_PORT0 0x1000 +#define S17_MIB_PORT1 0x1100 +#define S17_MIB_PORT2 0x1200 +#define S17_MIB_PORT3 0x1300 +#define S17_MIB_PORT4 0x1400 +#define S17_MIB_PORT5 0x1500 +#define S17_MIB_PORT6 0x1600 + +#define S17_MIB_RXBROAD 0x0 +#define S17_MIB_RXPAUSE 0x4 +#define S17_MIB_RXMULTI 0x8 +#define S17_MIB_RXFCSERR 0xC +#define S17_MIB_RXALIGNERR 0x10 +#define S17_MIB_RXUNDERSIZE 0x14 +#define S17_MIB_RXFRAG 0x18 +#define S17_MIB_RX64B 0x1C +#define S17_MIB_RX128B 0x20 +#define S17_MIB_RX256B 0x24 +#define S17_MIB_RX512B 0x28 +#define S17_MIB_RX1024B 0x2C +#define S17_MIB_RX1518B 0x30 +#define S17_MIB_RXMAXB 0x34 +#define S17_MIB_RXTOOLONG 0x38 +#define S17_MIB_RXBYTE1 0x3C +#define S17_MIB_RXBYTE2 0x40 +#define S17_MIB_RXOVERFLOW 0x4C +#define S17_MIB_FILTERED 0x50 +#define S17_MIB_TXBROAD 0x54 +#define S17_MIB_TXPAUSE 0x58 +#define S17_MIB_TXMULTI 0x5C +#define S17_MIB_TXUNDERRUN 0x60 +#define S17_MIB_TX64B 0x64 +#define S17_MIB_TX128B 0x68 +#define S17_MIB_TX256B 0x6c +#define S17_MIB_TX512B 0x70 +#define S17_MIB_TX1024B 0x74 +#define S17_MIB_TX1518B 0x78 +#define S17_MIB_TXMAXB 0x7C +#define S17_MIB_TXOVERSIZE 0x80 +#define S17_MIB_TXBYTE1 0x84 +#define S17_MIB_TXBYTE2 0x88 +#define S17_MIB_TXCOL 0x8C +#define S17_MIB_TXABORTCOL 0x90 +#define S17_MIB_TXMULTICOL 0x94 +#define S17_MIB_TXSINGLECOL 0x98 +#define S17_MIB_TXEXCDEFER 0x9C +#define S17_MIB_TXDEFER 0xA0 +#define S17_MIB_TXLATECOL 0xA4 + +/* Register fields */ +#define S17_CHIPID_V1_0 0x1201 +#define S17_CHIPID_V1_1 0x1202 + +#define S17_MASK_CTRL_SOFT_RET (1 << 31) + +#define S17_GLOBAL_INT0_ACL_INI_INT (1<<29) +#define S17_GLOBAL_INT0_LOOKUP_INI_INT (1<<28) +#define S17_GLOBAL_INT0_QM_INI_INT (1<<27) +#define S17_GLOBAL_INT0_MIB_INI_INT (1<<26) +#define S17_GLOBAL_INT0_OFFLOAD_INI_INT (1<<25) +#define S17_GLOBAL_INT0_HARDWARE_INI_DONE (1<<24) + +#define S17_GLOBAL_INITIALIZED_STATUS \ + ( \ + S17_GLOBAL_INT0_ACL_INI_INT | \ + S17_GLOBAL_INT0_LOOKUP_INI_INT | \ + S17_GLOBAL_INT0_QM_INI_INT | \ + S17_GLOBAL_INT0_MIB_INI_INT | \ + S17_GLOBAL_INT0_OFFLOAD_INI_INT | \ + S17_GLOBAL_INT0_HARDWARE_INI_DONE \ + ) + +#define S17_MAC0_MAC_MII_RXCLK_SEL (1 << 0) +#define S17_MAC0_MAC_MII_TXCLK_SEL (1 << 1) +#define S17_MAC0_MAC_MII_EN (1 << 2) +#define S17_MAC0_MAC_GMII_RXCLK_SEL (1 << 4) +#define S17_MAC0_MAC_GMII_TXCLK_SEL (1 << 5) +#define S17_MAC0_MAC_GMII_EN (1 << 6) +#define S17_MAC0_SGMII_EN (1 << 7) +#define S17_MAC0_PHY_MII_RXCLK_SEL (1 << 8) +#define S17_MAC0_PHY_MII_TXCLK_SEL (1 << 9) +#define S17_MAC0_PHY_MII_EN (1 << 10) +#define S17_MAC0_PHY_MII_PIPE_SEL (1 << 11) +#define S17_MAC0_PHY_GMII_RXCLK_SEL (1 << 12) +#define S17_MAC0_PHY_GMII_TXCLK_SEL (1 << 13) +#define S17_MAC0_PHY_GMII_EN (1 << 14) +#define S17_MAC0_RGMII_RXCLK_SHIFT 20 +#define S17_MAC0_RGMII_TXCLK_SHIFT 22 +#define S17_MAC0_RGMII_RXCLK_DELAY (1 << 24) +#define S17_MAC0_RGMII_TXCLK_DELAY (1 << 25) +#define S17_MAC0_RGMII_EN (1 << 26) + +#define S17_MAC5_MAC_MII_RXCLK_SEL (1 << 0) +#define S17_MAC5_MAC_MII_TXCLK_SEL (1 << 1) +#define S17_MAC5_MAC_MII_EN (1 << 2) +#define S17_MAC5_PHY_MII_RXCLK_SEL (1 << 8) +#define S17_MAC5_PHY_MII_TXCLK_SEL (1 << 9) +#define S17_MAC5_PHY_MII_EN (1 << 10) +#define S17_MAC5_PHY_MII_PIPE_SEL (1 << 11) +#define S17_MAC5_RGMII_RXCLK_SHIFT 20 +#define S17_MAC5_RGMII_TXCLK_SHIFT 22 +#define S17_MAC5_RGMII_RXCLK_DELAY (1 << 24) +#define S17_MAC5_RGMII_TXCLK_DELAY (1 << 25) +#define S17_MAC5_RGMII_EN (1 << 26) + +#define S17_MAC6_MAC_MII_RXCLK_SEL (1 << 0) +#define S17_MAC6_MAC_MII_TXCLK_SEL (1 << 1) +#define S17_MAC6_MAC_MII_EN (1 << 2) +#define S17_MAC6_MAC_GMII_RXCLK_SEL (1 << 4) +#define S17_MAC6_MAC_GMII_TXCLK_SEL (1 << 5) +#define S17_MAC6_MAC_GMII_EN (1 << 6) +#define S17_MAC6_SGMII_EN (1 << 7) +#define S17_MAC6_PHY_MII_RXCLK_SEL (1 << 8) +#define S17_MAC6_PHY_MII_TXCLK_SEL (1 << 9) +#define S17_MAC6_PHY_MII_EN (1 << 10) +#define S17_MAC6_PHY_MII_PIPE_SEL (1 << 11) +#define S17_MAC6_PHY_GMII_RXCLK_SEL (1 << 12) +#define S17_MAC6_PHY_GMII_TXCLK_SEL (1 << 13) +#define S17_MAC6_PHY_GMII_EN (1 << 14) +#define S17_PHY4_GMII_EN (1 << 16) +#define S17_PHY4_RGMII_EN (1 << 17) +#define S17_PHY4_MII_EN (1 << 18) +#define S17_MAC6_RGMII_RXCLK_SHIFT 20 +#define S17_MAC6_RGMII_TXCLK_SHIFT 22 +#define S17_MAC6_RGMII_RXCLK_DELAY (1 << 24) +#define S17_MAC6_RGMII_TXCLK_DELAY (1 << 25) +#define S17_MAC6_RGMII_EN (1 << 26) + +#define S17_SPEED_10M (0 << 0) +#define S17_SPEED_100M (1 << 0) +#define S17_SPEED_1000M (2 << 0) +#define S17_TXMAC_EN (1 << 2) +#define S17_RXMAC_EN (1 << 3) +#define S17_TX_FLOW_EN (1 << 4) +#define S17_RX_FLOW_EN (1 << 5) +#define S17_DUPLEX_FULL (1 << 6) +#define S17_DUPLEX_HALF (0 << 6) +#define S17_TX_HALF_FLOW_EN (1 << 7) +#define S17_LINK_EN (1 << 9) +#define S17_FLOW_LINK_EN (1 << 12) +#define S17_PORT_STATUS_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \ + S17_RXMAC_EN | S17_TX_FLOW_EN | \ + S17_RX_FLOW_EN | S17_DUPLEX_FULL | \ + S17_TX_HALF_FLOW_EN) + +#define S17_PORT_STATUS_AZ_DEFAULT (S17_SPEED_1000M | S17_TXMAC_EN | \ + S17_RXMAC_EN | S17_TX_FLOW_EN | \ + S17_RX_FLOW_EN | S17_DUPLEX_FULL) + + +#define S17_HDRLENGTH_SEL (1 << 16) +#define S17_HDR_VALUE 0xAAAA + +#define S17_TXHDR_MODE_NO 0 +#define S17_TXHDR_MODE_MGM 1 +#define S17_TXHDR_MODE_ALL 2 +#define S17_RXHDR_MODE_NO (0 << 2) +#define S17_RXHDR_MODE_MGM (1 << 2) +#define S17_RXHDR_MODE_ALL (2 << 2) + +#define S17_CPU_PORT_EN (1 << 10) +#define S17_PPPOE_REDIR_EN (1 << 8) +#define S17_MIRROR_PORT_SHIFT 4 +#define S17_IGMP_COPY_EN (1 << 3) +#define S17_RIP_COPY_EN (1 << 2) +#define S17_EAPOL_REDIR_EN (1 << 0) + +#define S17_IGMP_JOIN_LEAVE_DP_SHIFT 24 +#define S17_BROAD_DP_SHIFT 16 +#define S17_MULTI_FLOOD_DP_SHIFT 8 +#define S17_UNI_FLOOD_DP_SHIFT 0 +#define S17_IGMP_JOIN_LEAVE_DPALL (0x7f << S17_IGMP_JOIN_LEAVE_DP_SHIFT) +#define S17_BROAD_DPALL (0x7f << S17_BROAD_DP_SHIFT) +#define S17_MULTI_FLOOD_DPALL (0x7f << S17_MULTI_FLOOD_DP_SHIFT) +#define S17_UNI_FLOOD_DPALL (0x7f << S17_UNI_FLOOD_DP_SHIFT) + +#define S17_PWS_CHIP_AR8327 (1 << 30) +#define S17c_PWS_SERDES_ANEG_DISABLE (1 << 7) + +/* S17_PHY_CONTROL fields */ +#define S17_CTRL_SOFTWARE_RESET 0x8000 +#define S17_CTRL_SPEED_LSB 0x2000 +#define S17_CTRL_AUTONEGOTIATION_ENABLE 0x1000 +#define S17_CTRL_RESTART_AUTONEGOTIATION 0x0200 +#define S17_CTRL_SPEED_FULL_DUPLEX 0x0100 +#define S17_CTRL_SPEED_MSB 0x0040 + +/* For EEE_CTRL_REG */ +#define S17_LPI_DISABLE_P1 (1 << 4) +#define S17_LPI_DISABLE_P2 (1 << 6) +#define S17_LPI_DISABLE_P3 (1 << 8) +#define S17_LPI_DISABLE_P4 (1 << 10) +#define S17_LPI_DISABLE_P5 (1 << 12) +#define S17_LPI_DISABLE_ALL 0x1550 + +/* For MMD register control */ +#define S17_MMD_FUNC_ADDR (0 << 14) +#define S17_MMD_FUNC_DATA (1 << 14) +#define S17_MMD_FUNC_DATA_2 (2 << 14) +#define S17_MMD_FUNC_DATA_3 (3 << 14) + +/* For phyInfo_t azFeature */ +#define S17_8023AZ_PHY_ENABLED (1 << 0) +#define S17_8023AZ_PHY_LINKED (1 << 1) + +/* Queue Management registe fields */ +#define S17_HOL_CTRL0_LAN 0x2a008888 /* egress priority 8, eg_portq = 0x2a */ +#define S17_HOL_CTRL0_WAN 0x2a666666 /* egress priority 6, eg_portq = 0x2a */ +#define S17_HOL_CTRL1_DEFAULT 0xc6 /* enable HOL control */ + +/* Packet Edit register fields */ +#define S17_ROUTER_EG_UNMOD 0x0 /* unmodified */ +#define S17_ROUTER_EG_WOVLAN 0x1 /* without VLAN */ +#define S17_ROUTER_EG_WVLAN 0x2 /* with VLAN */ +#define S17_ROUTER_EG_UNTOUCH 0x3 /* untouched */ +#define S17_ROUTER_EG_MODE_DEFAULT 0x01111111 /* all ports without VLAN */ + +#define S17_RESET_DONE(phy_control) \ + (((phy_control) & (S17_CTRL_SOFTWARE_RESET)) == 0) + +/* Phy status fields */ +#define S17_STATUS_AUTO_NEG_DONE 0x0020 + +#define S17_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & \ + (S17_STATUS_AUTO_NEG_DONE)) == \ + (S17_STATUS_AUTO_NEG_DONE)) + +/* Link Partner ability */ +#define S17_LINK_100BASETX_FULL_DUPLEX 0x0100 +#define S17_LINK_100BASETX 0x0080 +#define S17_LINK_10BASETX_FULL_DUPLEX 0x0040 +#define S17_LINK_10BASETX 0x0020 + +/* Advertisement register. */ +#define S17_ADVERTISE_NEXT_PAGE 0x8000 +#define S17_ADVERTISE_ASYM_PAUSE 0x0800 +#define S17_ADVERTISE_PAUSE 0x0400 +#define S17_ADVERTISE_100FULL 0x0100 +#define S17_ADVERTISE_100HALF 0x0080 +#define S17_ADVERTISE_10FULL 0x0040 +#define S17_ADVERTISE_10HALF 0x0020 + +#define S17_ADVERTISE_ALL (S17_ADVERTISE_ASYM_PAUSE | S17_ADVERTISE_PAUSE | \ + S17_ADVERTISE_10HALF | S17_ADVERTISE_10FULL | \ + S17_ADVERTISE_100HALF | S17_ADVERTISE_100FULL) + +/* 1000BASET_CONTROL */ +#define S17_ADVERTISE_1000FULL 0x0200 + +/* Phy Specific status fields */ +#define S17_STATUS_LINK_MASK 0xC000 +#define S17_STATUS_LINK_SHIFT 14 +#define S17_STATUS_FULL_DEPLEX 0x2000 +#define S17_STATUS_LINK_PASS 0x0400 +#define S17_STATUS_RESOLVED 0x0800 +#define S17_STATUS_LINK_10M 0 +#define S17_STATUS_LINK_100M 1 +#define S17_STATUS_LINK_1000M 2 + +#define S17_GLOBAL_INT_PHYMASK (1 << 15) + +#define S17_PHY_LINK_UP 0x400 +#define S17_PHY_LINK_DOWN 0x800 +#define S17_PHY_LINK_DUPLEX_CHANGE 0x2000 +#define S17_PHY_LINK_SPEED_CHANGE 0x4000 + +/* For Port flow control registers */ +#define S17_PORT_FLCTL_XON_DEFAULT (0x3a << 16) +#define S17_PORT_FLCTL_XOFF_DEFAULT (0x4a) + +/* Module enable Register */ +#define S17_MODULE_L3_EN (1 << 2) +#define S17_MODULE_ACL_EN (1 << 1) +#define S17_MODULE_MIB_EN (1 << 0) + +/* MIB Function Register 1 */ +#define S17_MIB_FUNC_ALL (3 << 24) +#define S17_MIB_CPU_KEEP (1 << 20) +#define S17_MIB_BUSY (1 << 17) +#define S17_MIB_AT_HALF_EN (1 << 16) +#define S17_MIB_TIMER_DEFAULT 0x100 + +#define S17_MAC_MAX 7 + +/* MAC power selector bit definitions */ +#define S17_RGMII0_1_8V (1 << 19) +#define S17_RGMII1_1_8V (1 << 18) + +/* SGMII_CTRL bit definitions */ +#define S17c_SGMII_EN_LCKDT (1 << 0) +#define S17c_SGMII_EN_PLL (1 << 1) +#define S17c_SGMII_EN_RX (1 << 2) +#define S17c_SGMII_EN_TX (1 << 3) +#define S17c_SGMII_EN_SD (1 << 4) +#define S17c_SGMII_BW_HIGH (1 << 6) +#define S17c_SGMII_SEL_CLK125M (1 << 7) +#define S17c_SGMII_TXDR_CTRL_600mV (1 << 10) +#define S17c_SGMII_CDR_BW_8 (3 << 13) +#define S17c_SGMII_DIS_AUTO_LPI_25M (1 << 16) +#define S17c_SGMII_MODE_CTRL_SGMII_PHY (1 << 22) +#define S17c_SGMII_PAUSE_SG_TX_EN_25M (1 << 24) +#define S17c_SGMII_ASYM_PAUSE_25M (1 << 25) +#define S17c_SGMII_PAUSE_25M (1 << 26) +#define S17c_SGMII_HALF_DUPLEX_25M (1 << 30) +#define S17c_SGMII_FULL_DUPLEX_25M (1 << 31) + +#ifndef BOOL +#define BOOL int +#endif + +/*add feature define here*/ + +#ifdef CONFIG_AR7242_S17_PHY +#undef HEADER_REG_CONF +#undef HEADER_EN +#endif +int athrs17_init_switch(void); +void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg); +void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg); +void athrs17_vlan_config(void); +#endif + + diff --git a/arch/arm/include/asm/arch-ipq5018/clk.h b/arch/arm/include/asm/arch-ipq5018/clk.h index 4144d9a066..4480027d6e 100644 --- a/arch/arm/include/asm/arch-ipq5018/clk.h +++ b/arch/arm/include/asm/arch-ipq5018/clk.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, 2018-2020 The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,6 +18,4 @@ #ifdef CONFIG_IPQ5018_I2C void i2c_clock_config(void); #endif - -#define CLK_ENABLE 0x1 #endif /*IPQ5018_CLK_H*/ diff --git a/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h index e1643c5686..9cc49f35f8 100644 --- a/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h +++ b/arch/arm/include/asm/arch-ipq5018/ipq5018_gmac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,11 @@ #include #include +#define GEPHY 0x7 /* Dummy */ + +#define GEPHY_PHY_TYPE 0x1 +#define NAPA_PHY_TYPE 0x2 + #define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ) #define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ) #define CONFIG_PHYRESET_TIMEOUT (3 * CONFIG_SYS_HZ) @@ -224,7 +229,7 @@ typedef struct } ipq_gmac_desc_t ; #define IPQ5018_GMAC_PORT 2 -#define IPQ5018_PHY_MAX 2 +#define IPQ5018_PHY_MAX 1 struct ipq_eth_dev { uint phy_address; @@ -235,7 +240,9 @@ struct ipq_eth_dev { uint duplex; uint phy_configured; uint mac_unit; + uint phy_type; uint mac_ps; + uint ipq_swith; int link_printed; u32 padding; ipq_gmac_desc_t *desc_tx[NO_OF_TX_DESC]; @@ -247,7 +254,7 @@ struct ipq_eth_dev { struct eth_mac_regs *mac_regs_p; struct eth_dma_regs *dma_regs_p; struct eth_device *dev; - struct phy_ops *ops[IPQ5018_PHY_MAX]; + struct phy_ops *ops; const char phy_name[MDIO_NAME_LEN]; struct ipq_forced_mode *forced_params; ipq_gmac_board_cfg_t *gmac_board_cfg; diff --git a/arch/arm/include/asm/arch-ipq6018/clk.h b/arch/arm/include/asm/arch-ipq6018/clk.h index 5d545d4bce..e33a06481c 100644 --- a/arch/arm/include/asm/arch-ipq6018/clk.h +++ b/arch/arm/include/asm/arch-ipq6018/clk.h @@ -14,6 +14,8 @@ #ifndef IPQ6018_CLK_H #define IPQ6018_CLK_H +#include + /* I2C clocks configuration */ #ifdef CONFIG_IPQ6018_I2C @@ -31,4 +33,42 @@ void i2c_clock_config(void); #endif +#define GCC_BLSP1_UART1_BCR 0x1802038 +#define GCC_BLSP1_UART2_BCR 0x1803028 +#define GCC_BLSP1_UART3_BCR 0x1804028 +#define GCC_BLSP1_UART4_BCR 0x1805028 +#define GCC_BLSP1_UART5_BCR 0x1806028 +#define GCC_BLSP1_UART6_BCR 0x1807028 + +#define GCC_BLSP1_UART_BCR(id) ((id < 1) ? \ + (GCC_BLSP1_UART1_BCR):\ + (GCC_BLSP1_UART1_BCR + (0x1000 * id) - 0x10)) + +#define GCC_BLSP1_UART_APPS_CBCR(id) (GCC_BLSP1_UART_BCR(id) + 0x04) +#define GCC_BLSP1_UART_APPS_CMD_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x0C) +#define GCC_BLSP1_UART_APPS_CFG_RCGR(id) (GCC_BLSP1_UART_BCR(id) + 0x10) +#define GCC_BLSP1_UART_APPS_M(id) (GCC_BLSP1_UART_BCR(id) + 0x14) +#define GCC_BLSP1_UART_APPS_N(id) (GCC_BLSP1_UART_BCR(id) + 0x18) +#define GCC_BLSP1_UART_APPS_D(id) (GCC_BLSP1_UART_BCR(id) + 0x1C) + +#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000 +#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700 +#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F + +#define GCC_UART_CFG_RCGR_MODE_SHIFT 12 +#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8 +#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0 + +#define UART_RCGR_SRC_SEL 0x1 +#define UART_RCGR_SRC_DIV 0x0 +#define UART_RCGR_MODE 0x2 +#define UART_CMD_RCGR_UPDATE 0x1 +#define UART_CBCR_CLK_ENABLE 0x1 + +#define NOT_2D(two_d) (~two_d) +#define NOT_N_MINUS_M(n,m) (~(n - m)) +#define CLOCK_UPDATE_TIMEOUT_US 1000 + +int uart_clock_config(struct ipq_serial_platdata *plat); + #endif /*IPQ6018_CLK_H*/ diff --git a/arch/arm/include/asm/arch-qca-common/qpic_nand.h b/arch/arm/include/asm/arch-qca-common/qpic_nand.h index 642c3bdd52..bb9a8efed7 100644 --- a/arch/arm/include/asm/arch-qca-common/qpic_nand.h +++ b/arch/arm/include/asm/arch-qca-common/qpic_nand.h @@ -112,6 +112,7 @@ #define NAND_FLASH_SPI_CFG NAND_REG(0x70C0) #define NAND_SPI_NUM_ADDR_CYCLES NAND_REG(0x70C4) #define NAND_SPI_BUSY_CHECK_WAIT_CNT NAND_REG(0x70C8) +#define NAND_QSPI_MSTR_CONFIG NAND_REG(0x7f60) /* Register mask & shift value used in SPI transfer mode */ #define SPI_TRANSFER_MODE_1X 0x1 diff --git a/arch/arm/include/asm/arch-qca-common/uart.h b/arch/arm/include/asm/arch-qca-common/uart.h index f1c6474acd..cf9e839f6e 100644 --- a/arch/arm/include/asm/arch-qca-common/uart.h +++ b/arch/arm/include/asm/arch-qca-common/uart.h @@ -88,6 +88,7 @@ struct ipq_serial_platdata { int m_value; int n_value; int d_value; + int gpio_node; }; diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index bbc2a06dd4..86fa70a1ad 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1144,6 +1144,8 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_IPQ6018_AP_CP01_C2 0x8030001 #define MACH_TYPE_IPQ6018_AP_CP01_C3 0x8030002 #define MACH_TYPE_IPQ6018_AP_CP01_C4 0x8030003 +#define MACH_TYPE_IPQ5018_AP_MP02_1 0x8040000 +#define MACH_TYPE_IPQ5018_DB_MP02_1 0X1040003 #ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type diff --git a/board/ipq5018/Kconfig b/board/ipq5018/Kconfig index 314d9e88c2..e1a56bc2db 100644 --- a/board/ipq5018/Kconfig +++ b/board/ipq5018/Kconfig @@ -21,5 +21,34 @@ config USB_XHCI_IPQ config PCI_IPQ bool "Enable pci support for ipq5018" -endif +config MMC_FLASH + bool "Enable MMC flash support for ipq5018" +config IPQ_TZT + bool "Enable TZ test command for ipq5018" + +config UBI_WRITE + bool "Enable ubi volume write command for ipq5018" + +config QPIC_SERIAL + bool "Enable QPIC serial spi nand for ipq5018" + +config IPQ_TINY + bool "Enable Tiny support for ipq5018" + +config IPQ_MTD_NOR + bool "Register nor in MTD framework for ipq5018" + +config IPQ_TINY_SPI_NOR + bool "This config helps to update spi-nor related updated in ipq5018" + +config NAND_FLASH + bool "Enable NAND driver for ipq5018" + +config GEPHY + bool "Enable Internel GEPHY for ipq5018" + +config ART_COMPRESSED + bool "Enable uncompress support for ipq5018" + +endif diff --git a/board/qca/arm/common/board_init.c b/board/qca/arm/common/board_init.c index d4b98280d2..b219433eae 100644 --- a/board/qca/arm/common/board_init.c +++ b/board/qca/arm/common/board_init.c @@ -24,10 +24,11 @@ #include DECLARE_GLOBAL_DATA_PTR; - +#ifdef CONFIG_ENV_IS_IN_NAND extern int nand_env_device; extern env_t *nand_env_ptr; extern char *nand_env_name_spec; +#endif extern char *sf_env_name_spec; extern int nand_saveenv(void); extern int sf_saveenv(void); @@ -138,12 +139,16 @@ int board_init(void) #ifndef CONFIG_ENV_IS_NOWHERE switch (sfi->flash_type) { +#ifdef CONFIG_ENV_IS_IN_NAND case SMEM_BOOT_NAND_FLASH: case SMEM_BOOT_QSPI_NAND_FLASH: nand_env_device = CONFIG_NAND_FLASH_INFO_IDX; break; +#endif case SMEM_BOOT_SPI_FLASH: +#ifdef CONFIG_ENV_IS_IN_NAND nand_env_device = CONFIG_SPI_FLASH_INFO_IDX; +#endif break; case SMEM_BOOT_MMC_FLASH: case SMEM_BOOT_NO_FLASH: @@ -196,9 +201,11 @@ int board_init(void) env_name_spec = mmc_env_name_spec; #endif } else { +#ifdef CONFIG_ENV_IS_IN_NAND saveenv = nand_saveenv; env_ptr = nand_env_ptr; env_name_spec = nand_env_name_spec; +#endif } #endif ret = ipq_board_usb_init(); diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c index 590fac47b8..8ba27f5dfa 100644 --- a/board/qca/arm/common/cmd_bootqca.c +++ b/board/qca/arm/common/cmd_bootqca.c @@ -204,40 +204,54 @@ int config_select(unsigned int addr, char *rcmd, int rcmd_size) * or board name based config is used. */ +#ifdef CONFIG_ARCH_IPQ806x int soc_version = 0; +#endif + int i, strings_count; const char *config = getenv("config_name"); if (config) { printf("Manual device tree config selected!\n"); strlcpy(dtb_config_name, config, sizeof(dtb_config_name)); - } else { - config = fdt_getprop(gd->fdt_blob, 0, "config_name", NULL); + if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) { + snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n", + addr, dtb_config_name); + return 0; + } - if(config == NULL) { + } else { + strings_count = fdt_count_strings(gd->fdt_blob, 0, "config_name"); + + if (!strings_count) { printf("Failed to get config_name\n"); return -1; } - snprintf((char *)dtb_config_name, - sizeof(dtb_config_name), "%s", config); + for (i = 0; i < strings_count; i++) { + fdt_get_string_index(gd->fdt_blob, 0, "config_name", + i, &config); + + snprintf((char *)dtb_config_name, + sizeof(dtb_config_name), "%s", config); - ipq_smem_get_socinfo_version((uint32_t *)&soc_version); #ifdef CONFIG_ARCH_IPQ806x - if(SOCINFO_VERSION_MAJOR(soc_version) >= 2) { - snprintf(dtb_config_name + strlen("config@"), - sizeof(dtb_config_name) - strlen("config@"), - "v%d.0-%s", - SOCINFO_VERSION_MAJOR(soc_version), - config + strlen("config@")); - } + ipq_smem_get_socinfo_version((uint32_t *)&soc_version); + if(SOCINFO_VERSION_MAJOR(soc_version) >= 2) { + snprintf(dtb_config_name + strlen("config@"), + sizeof(dtb_config_name) - strlen("config@"), + "v%d.0-%s", + SOCINFO_VERSION_MAJOR(soc_version), + config + strlen("config@")); + } #endif + if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) { + snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n", + addr, dtb_config_name); + return 0; + } + } } - if (fit_conf_get_node((void *)addr, dtb_config_name) >= 0) { - snprintf(rcmd, rcmd_size, "bootm 0x%x#%s\n", - addr, dtb_config_name); - return 0; - } printf("Config not availabale\n"); return -1; @@ -472,6 +486,7 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a kernel_img_info.kernel_load_addr = request; if (ipq_fs_on_nand) { +#ifdef CONFIG_CMD_UBI /* * The kernel will be available inside a UBI volume */ @@ -512,6 +527,7 @@ static int do_boot_signedimg(cmd_tbl_t *cmdtp, int flag, int argc, char *const a kernel_img_info.kernel_load_size = (unsigned int)ubi_get_volume_size("kernel"); +#endif #ifdef CONFIG_QCA_MMC } else if (sfi->flash_type == SMEM_BOOT_MMC_FLASH || ((sfi->flash_type == SMEM_BOOT_SPI_FLASH) && diff --git a/board/qca/arm/common/crashdump.c b/board/qca/arm/common/crashdump.c index 6da019088c..9a97fe5d20 100644 --- a/board/qca/arm/common/crashdump.c +++ b/board/qca/arm/common/crashdump.c @@ -118,8 +118,9 @@ struct crashdump_flash_emmc_cxt { }; #endif - +#ifdef CONFIG_MTD_DEVICE static struct crashdump_flash_nand_cxt crashdump_nand_cnxt; +#endif #ifdef CONFIG_QCA_SPI static struct spi_flash *crashdump_spi_flash; static struct crashdump_flash_spi_cxt crashdump_flash_spi_cnxt; @@ -734,7 +735,7 @@ void dump_func(unsigned int dump_level) reset: reset_board(); } - +#ifdef CONFIG_MTD_DEVICE /* * Init function for NAND flash writing. It intializes its own context * and erases the required sectors @@ -879,7 +880,7 @@ int crashdump_nand_flash_write_data(void *cnxt, return 0; } - +#endif #ifdef CONFIG_QCA_SPI /* Init function for SPI NOR flash writing. It erases the required sectors */ int init_crashdump_spi_flash_write(void *cnxt, @@ -1121,11 +1122,13 @@ static int qca_wdt_write_crashdump_data( */ if (((flash_type == SMEM_BOOT_NAND_FLASH) || (flash_type == SMEM_BOOT_QSPI_NAND_FLASH))) { +#ifdef CONFIG_MTD_DEVICE crashdump_cnxt = (void *)&crashdump_nand_cnxt; crashdump_flash_write_init = init_crashdump_nand_flash_write; crashdump_flash_write = crashdump_nand_flash_write_data; crashdump_flash_write_deinit = deinit_crashdump_nand_flash_write; +#endif #ifdef CONFIG_QCA_SPI } else if (flash_type == SMEM_BOOT_SPI_FLASH) { if (!crashdump_spi_flash) { diff --git a/board/qca/arm/common/env.c b/board/qca/arm/common/env.c index 3050b82f57..a28c076203 100644 --- a/board/qca/arm/common/env.c +++ b/board/qca/arm/common/env.c @@ -18,10 +18,10 @@ #ifdef CONFIG_SDHCI_SUPPORT #include #endif - +#ifdef CONFIG_ENV_IS_IN_NAND extern void nand_env_relocate_spec(void); extern int nand_env_init(void); - +#endif #ifdef CONFIG_ENV_IS_IN_SPI_FLASH extern void sf_env_relocate_spec(void); extern int sf_env_init(void); @@ -58,7 +58,9 @@ int env_init(void) ret = mmc_env_init(); #endif } else { +#ifdef CONFIG_ENV_IS_IN_NAND ret = nand_env_init(); +#endif } return ret; @@ -85,7 +87,9 @@ void env_relocate_spec(void) mmc_env_relocate_spec(); #endif } else { +#ifdef CONFIG_ENV_IS_IN_NAND nand_env_relocate_spec(); +#endif } }; diff --git a/board/qca/arm/common/ethaddr.c b/board/qca/arm/common/ethaddr.c index cd7af73610..e9611851df 100644 --- a/board/qca/arm/common/ethaddr.c +++ b/board/qca/arm/common/ethaddr.c @@ -19,7 +19,15 @@ #include #include #include - +#ifdef CONFIG_IPQ_TINY_SPI_NOR +#include +#include +#endif +#if defined(CONFIG_ART_COMPRESSED) && \ + (defined(CONFIG_GZIP) || defined(CONFIG_LZMA)) +#include +#include +#endif #ifdef CONFIG_QCA_MMC #ifndef CONFIG_SDHCI_SUPPORT extern qca_mmc mmc_host; @@ -46,6 +54,14 @@ int get_eth_mac_address(uchar *enetaddr, uint no_of_macs) struct mmc *mmc; char mmc_blks[512]; #endif +#ifdef CONFIG_IPQ_TINY_SPI_NOR + struct spi_flash *flash = NULL; +#if defined(CONFIG_ART_COMPRESSED) && (defined(CONFIG_GZIP) || defined(CONFIG_LZMA)) + void *load_buf, *image_buf; + unsigned long img_size; +#endif +#endif + if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) { if (qca_smem_flash_info.flash_type == SMEM_BOOT_SPI_FLASH) flash_type = CONFIG_SPI_FLASH_INFO_IDX; @@ -70,8 +86,49 @@ int get_eth_mac_address(uchar *enetaddr, uint no_of_macs) art_offset = ((loff_t) qca_smem_flash_info.flash_block_size * start_blocks); +#ifdef CONFIG_IPQ_TINY_SPI_NOR + flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, + CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); + if (flash == NULL){ + printf("No SPI flash device found\n"); + ret = -1; + } else { +#if defined(CONFIG_ART_COMPRESSED) && (defined(CONFIG_GZIP) || defined(CONFIG_LZMA)) + image_buf = map_sysmem(CONFIG_SYS_LOAD_ADDR, 0); + load_buf = map_sysmem(CONFIG_SYS_LOAD_ADDR + 0x100000, 0); + img_size = qca_smem_flash_info.flash_block_size * size_blocks; + 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); +#endif +#ifdef CONFIG_LZMA + if (ret != 0) + ret = lzmaBuffToBuffDecompress(load_buf, + (SizeT *)&img_size, + image_buf, + (SizeT)img_size); +#endif + if (ret == 0) { + memcpy(enetaddr, load_buf, length); + } else { + printf("Invalid compression type..\n"); + ret = -1; + } + } +#else + ret = spi_flash_read(flash, art_offset, length, enetaddr); +#endif + } + /* + * Avoid unused warning + */ + (void)flash_type; +#else ret = nand_read(&nand_info[flash_type], art_offset, &length, enetaddr); +#endif if (ret < 0) printf("ART partition read failed..\n"); #ifdef CONFIG_QCA_MMC diff --git a/board/qca/arm/common/fdt_fixup.c b/board/qca/arm/common/fdt_fixup.c index ef256762ae..6ac9750072 100644 --- a/board/qca/arm/common/fdt_fixup.c +++ b/board/qca/arm/common/fdt_fixup.c @@ -595,11 +595,6 @@ __weak void fdt_fixup_cpus_node(void * blob) return; } -__weak void fdt_fixup_set_dload_dis(void *blob) -{ - return; -} - __weak void fdt_fixup_set_dload_warm_reset(void *blob) { return; @@ -620,6 +615,11 @@ __weak void fdt_fixup_wcss_rproc_for_atf(void *blob) return; } +__weak void fdt_fixup_bt_debug(void *blob) +{ + return; +} + /* * 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 @@ -636,6 +636,7 @@ int ft_board_setup(void *blob, bd_t *bd) uint32_t flash_type; char *s; char *mtdparts = NULL; + char *addparts = NULL; char parts_str[4096]; int len = sizeof(parts_str), ret; qca_smem_flash_info_t *sfi = &qca_smem_flash_info; @@ -689,6 +690,12 @@ int ft_board_setup(void *blob, bd_t *bd) if (mtdparts) { qca_smem_part_to_mtdparts(mtdparts,len); if (mtdparts[0] != '\0') { + addparts = getenv("addmtdparts"); + if (addparts) { + debug("addmtdparts = %s\n", addparts); + strlcat(mtdparts, ",", sizeof(parts_str)); + strlcat(mtdparts, addparts, sizeof(parts_str)); + } debug("mtdparts = %s\n", mtdparts); setenv("mtdparts", mtdparts); } @@ -729,7 +736,7 @@ int ft_board_setup(void *blob, bd_t *bd) fdt_fixup_set_dload_warm_reset(blob); s = getenv("dload_dis"); if (s) - fdt_fixup_set_dload_dis(blob); + ipq_fdt_mem_rsvd_fixup(blob); s = getenv("qce_fixed_key"); if (s) fdt_fixup_set_qce_fixed_key(blob); @@ -738,6 +745,10 @@ int ft_board_setup(void *blob, bd_t *bd) fdt_fixup_set_qca_cold_reboot_enable(blob); fdt_fixup_wcss_rproc_for_atf(blob); } + s = getenv("bt_debug"); + if (s) { + fdt_fixup_bt_debug(blob); + } #ifdef CONFIG_QCA_MMC board_mmc_deinit(); diff --git a/board/qca/arm/ipq5018/ipq5018.c b/board/qca/arm/ipq5018/ipq5018.c index 9153db83ad..66c5b1d915 100644 --- a/board/qca/arm/ipq5018/ipq5018.c +++ b/board/qca/arm/ipq5018/ipq5018.c @@ -17,15 +17,21 @@ #include #include #include -#include #include #include #include #include #include +#ifdef CONFIG_QCA_MMC #include #include +#endif +#ifdef CONFIG_USB_XHCI_IPQ #include +#endif +#ifdef CONFIG_QPIC_NAND +#include +#endif #define DLOAD_MAGIC_COOKIE 0x10 #define DLOAD_DISABLED 0x40 @@ -33,8 +39,14 @@ ipq_gmac_board_cfg_t gmac_cfg[CONFIG_IPQ_NO_MACS]; DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_QCA_MMC struct sdhci_host mmc_host; +#endif + +#ifdef CONFIG_IPQ_MTD_NOR extern int ipq_spi_init(u16); +#endif const char *rsvd_node = "/reserved-memory"; const char *del_node[] = {"uboot", @@ -56,10 +68,16 @@ struct dumpinfo_t dumpinfo_n[] = { * | (192k) | * | | * ------------------------ + * | | + * | BTRAM Copy | + * | (352k) | + * | | + * ------------------------ */ { "EBICS0.BIN", 0x40000000, 0x10000000, 0 }, { "IMEM.BIN", 0x08600000, 0x00001000, 0 }, { "NSSUTCM.BIN", 0x08600658, 0x00030000, 0, 1, 0x2000 }, + { "BTRAM.BIN", 0x08600658, 0x00058000, 0, 1, 0x00032000 }, { "UNAME.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, { "CPU_INFO.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, { "DMESG.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, @@ -73,6 +91,7 @@ struct dumpinfo_t dumpinfo_s[] = { { "EBICS_S1.BIN", CONFIG_TZ_END_ADDR, 0x10000000, 0 }, { "IMEM.BIN", 0x08600000, 0x00001000, 0 }, { "NSSUTCM.BIN", 0x08600658, 0x00030000, 0, 1, 0x2000 }, + { "BTRAM.BIN", 0x08600658, 0x00058000, 0, 1, 0x00032000 }, { "UNAME.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, { "CPU_INFO.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, { "DMESG.BIN", 0, 0, 0, 0, 0, MINIMAL_DUMP }, @@ -108,28 +127,8 @@ void uart1_set_rate_mnd(unsigned int m, unsigned int n, unsigned int two_d) { writel(m, GCC_BLSP1_UART1_APPS_M); - writel(NOT_N_MINUS_M(n, m), GCC_BLSP1_UART1_APPS_N); - writel(NOT_2D(two_d), GCC_BLSP1_UART1_APPS_D); -} - -int uart1_trigger_update(void) -{ - unsigned long cmd_rcgr; - int timeout = 0; - - cmd_rcgr = readl(GCC_BLSP1_UART1_APPS_CMD_RCGR); - cmd_rcgr |= UART1_CMD_RCGR_UPDATE; - writel(cmd_rcgr, GCC_BLSP1_UART1_APPS_CMD_RCGR); - - while (readl(GCC_BLSP1_UART1_APPS_CMD_RCGR) & UART1_CMD_RCGR_UPDATE) { - if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { - printf("Timeout waiting for UART1 clock update\n"); - return -ETIMEDOUT; - udelay(1); - } - } - cmd_rcgr = readl(GCC_BLSP1_UART1_APPS_CMD_RCGR); - return 0; + writel(n, GCC_BLSP1_UART1_APPS_N); + writel(two_d, GCC_BLSP1_UART1_APPS_D); } void reset_board(void) @@ -146,39 +145,48 @@ void uart1_toggle_clock(void) writel(cbcr_val, GCC_BLSP1_UART1_APPS_CBCR); } -void uart1_clock_config(unsigned int m, - unsigned int n, unsigned int two_d) +int uart1_trigger_update(void) { - uart1_configure_mux(); - uart1_set_rate_mnd(m, n, two_d); - uart1_trigger_update(); + unsigned long cmd_rcgr; + int timeout = 0; + + cmd_rcgr = readl(GCC_BLSP1_UART1_APPS_CMD_RCGR); + cmd_rcgr |= UART1_CMD_RCGR_UPDATE | UART1_CMD_RCGR_ROOT_EN; + writel(cmd_rcgr, GCC_BLSP1_UART1_APPS_CMD_RCGR); + + while (readl(GCC_BLSP1_UART1_APPS_CMD_RCGR) & UART1_CMD_RCGR_UPDATE) { + if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { + printf("Timeout waiting for UART1 clock update\n"); + return -ETIMEDOUT; + udelay(1); + } + } uart1_toggle_clock(); + return 0; +} + +int uart1_clock_config(struct ipq_serial_platdata *plat) +{ + + uart1_configure_mux(); + uart1_set_rate_mnd(plat->m_value, + plat->n_value, + plat->d_value); + return uart1_trigger_update(); } void qca_serial_init(struct ipq_serial_platdata *plat) { - int node, uart1_node; + int ret; - writel(1, GCC_BLSP1_UART1_APPS_CBCR); - node = fdt_path_offset(gd->fdt_blob, "/serial@78AF000/serial_gpio"); - if (node < 0) { - printf("Could not find serial_gpio node\n"); + if (plat->gpio_node < 0) { + printf("serial_init: unable to find gpio node \n"); return; } - - if (plat->port_id == 1) { - uart1_node = fdt_path_offset(gd->fdt_blob, "uart1"); - if (uart1_node < 0) { - printf("Could not find uart1 node\n"); - return; - } - node = fdt_subnode_offset(gd->fdt_blob, - uart1_node, "serial_gpio"); - uart1_clock_config(plat->m_value, plat->n_value, plat->d_value); - writel(1, GCC_BLSP1_UART1_APPS_CBCR); - } - - qca_gpio_init(node); + qca_gpio_init(plat->gpio_node); + ret = uart1_clock_config(plat); + if (ret) + printf("UART clock config failed %d \n", ret); } /* @@ -251,6 +259,10 @@ void emmc_clock_config(void) /* Delay for clock operation complete */ udelay(10); writel(0x1, GCC_SDCC1_APPS_M); + /* check this M, N D value while debugging + * because as per clock tool the actual M, N, D + * values are M=1, N=FA, D=F9 + */ writel(0xFC, GCC_SDCC1_APPS_N); writel(0xFD, GCC_SDCC1_APPS_D); /* Delay for clock operation complete */ @@ -278,15 +290,12 @@ void sdhci_bus_pwr_off(struct sdhci_host *host) sdhci_writeb(host,(val & (~SDHCI_POWER_ON)), SDHCI_POWER_CONTROL); } -void emmc_clock_disable(void) +__weak void board_mmc_deinit(void) { - /* Clear divider */ - writel(0x0, GCC_SDCC1_MISC); -} - -void board_mmc_deinit(void) -{ - emmc_clock_disable(); + /*since we do not have misc register in ipq5018 + * so simply return from this function + */ + return; } void emmc_clock_reset(void) @@ -298,7 +307,7 @@ void emmc_clock_reset(void) int board_mmc_init(bd_t *bis) { - int node; + int node, gpio_node; int ret = 0; qca_smem_flash_info_t *sfi = &qca_smem_flash_info; @@ -308,13 +317,15 @@ int board_mmc_init(bd_t *bis) return -1; } + gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "mmc_gpio"); + qca_gpio_init(gpio_node); + mmc_host.ioaddr = (void *)MSM_SDC1_SDHCI_BASE; mmc_host.voltages = MMC_VDD_165_195; mmc_host.version = SDHCI_SPEC_300; mmc_host.cfg.part_type = PART_TYPE_EFI; mmc_host.quirks = SDHCI_QUIRK_BROKEN_VOLTAGE; - emmc_clock_disable(); emmc_clock_reset(); udelay(10); emmc_clock_config(); @@ -390,11 +401,6 @@ void ipq_fdt_fixup_usb_device_mode(void *blob) printf("%s: invalid param for usb_mode\n", __func__); } -void fdt_fixup_set_dload_dis(void *blob) -{ - parse_fdt_fixup("/soc/qca,scm_restart_reason%dload_status%1", blob); -} - void ipq_fdt_fixup_socinfo(void *blob) { uint32_t cpu_type; @@ -495,30 +501,90 @@ void reset_cpu(unsigned long a) while(1); } -void qpic_clk_enbale(void) +#ifdef CONFIG_QPIC_NAND +void qpic_set_clk_rate(unsigned int clk_rate, int blk_type, int req_clk_src_type) { -#ifdef QPIC_CLOCK_ENABLE -/* - || clock enable code has been disabled due to NOC error in emualtion - || will verify on RDB and remove this clock configuration -*/ - writel(QPIC_CBCR_VAL, GCC_QPIC_CBCR_ADDR); - writel(0x1, GCC_QPIC_AHB_CBCR_ADDR); - writel(0x1, GCC_QPIC_IO_MACRO_CBCR); - writel(0x1, GCC_QPIC_CBCR_ADDR); -#endif + switch (blk_type) { + case QPIC_IO_MACRO_CLK: + /* select the clk source for IO_PAD_MACRO + * clk source wil be either XO = 24MHz. or GPLL0 = 800MHz. + */ + if (req_clk_src_type == XO_CLK_SRC) { + /* default XO clock will enabled + * i.e XO clock = 24MHz. + * so div value will 0. + * Input clock to IO_MACRO will be divided by 4 by default + * by hardware and then taht clock will be go on bus. + * i.e 24/4MHz = 6MHz i.e 6MHz will go onto the bus. + */ + writel(0x0, GCC_QPIC_IO_MACRO_CFG_RCGR); + + } else if (req_clk_src_type == GPLL0_CLK_SRC) { + /* selct GPLL0 clock source 800MHz + * so 800/4 = 200MHz. + * Input clock to IO_MACRO will be divided by 4 by default + * by hardware and then that clock will be go on bus. + * i.e 200/4MHz = 50MHz i.e 50MHz will go onto the bus. + */ + if (clk_rate == IO_MACRO_CLK_320_MHZ) + writel(0x104, GCC_QPIC_IO_MACRO_CFG_RCGR); + else if (clk_rate == IO_MACRO_CLK_266_MHZ) + writel(0x105, GCC_QPIC_IO_MACRO_CFG_RCGR); + else if (clk_rate == IO_MACRO_CLK_228_MHZ) + writel(0x106, GCC_QPIC_IO_MACRO_CFG_RCGR); + else if (clk_rate == IO_MACRO_CLK_100_MHZ) + writel(0x10F, GCC_QPIC_IO_MACRO_CFG_RCGR); + else if (clk_rate == IO_MACRO_CLK_200_MHZ) + writel(0x107, GCC_QPIC_IO_MACRO_CFG_RCGR); + + } else { + printf("wrong clk src selection requested.\n"); + } + + /* Enablle update bit to update the new configuration */ + writel((UPDATE_EN | readl(GCC_QPIC_IO_MACRO_CMD_RCGR)), + GCC_QPIC_IO_MACRO_CMD_RCGR); + + /* Enable the QPIC_IO_MACRO_CLK */ + writel(0x1, GCC_QPIC_IO_MACRO_CBCR); + + break; + case QPIC_CORE_CLK: + /* To DO if needed for QPIC core clock setting */ + break; + default: + printf("wrong qpic block type\n"); + break; + } } +#endif void board_nand_init(void) { - qpic_nand_init(NULL); +#ifdef CONFIG_QPIC_SERIAL + /* check for nand node in dts + * if nand node in dts is disabled then + * simply return from here without + * initializing + */ + int node; + + node = fdt_path_offset(gd->fdt_blob, "/nand-controller"); + if (!fdtdec_get_is_enabled(gd->fdt_blob, node)) { + printf("QPIC: disabled, skipping initialization\n"); + } else { + qpic_nand_init(NULL); + } +#endif #ifdef CONFIG_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 ipq_spi_init(CONFIG_IPQ_SPI_NOR_INFO_IDX); +#endif } #endif } @@ -548,6 +614,172 @@ unsigned long timer_read_counter(void) return 0; } +static void set_ext_mdio_gpio(void) +{ + /* mdc */ + writel(0x7, (unsigned int *)GPIO_CONFIG_ADDR(36)); + /* mdio */ + writel(0x7, (unsigned int *)GPIO_CONFIG_ADDR(37)); +} + +static void set_napa_phy_gpio(int gpio) +{ + unsigned int *napa_gpio_base; + + napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(gpio); + writel(0x203, napa_gpio_base); + gpio_direction_output(gpio, 0x0); + mdelay(500); + gpio_set_value(gpio, 0x1); +} + +static void cmn_blk_clk_set(void) +{ + /* GMN block */ + writel(0x1, GCC_CMN_BLK_AHB_CBCR); + mdelay(200); + writel(0x1, GCC_CMN_BLK_SYS_CBCR); + mdelay(200); +} + +static void uniphy_clk_set(void) +{ + writel(0x1, GCC_UNIPHY_AHB_CBCR); + mdelay(200); + writel(0x1, GCC_UNIPHY_SYS_CBCR); + mdelay(200); +} + +static void gephy_port_clock_reset(void) +{ + writel(0, GCC_GEPHY_RX_CBCR); + mdelay(200); + writel(0, GCC_GEPHY_TX_CBCR); + mdelay(200); +} + +static void gmac0_clock_reset(void) +{ + writel(0, GCC_GMAC0_RX_CBCR); + mdelay(200); + writel(0, GCC_GMAC0_TX_CBCR); + mdelay(200); +} + +static void gmac_clk_src_init(void) +{ + u32 reg_val; + + /*select source of GMAC*/ + reg_val = readl(GCC_GMAC0_RX_CFG_RCGR); + reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK; + reg_val |= GCC_GMAC0_RX_SRC_SEL_GEPHY_TX; + writel(reg_val, GCC_GMAC0_RX_CFG_RCGR); + + reg_val = readl(GCC_GMAC0_TX_CFG_RCGR); + reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK; + reg_val |= GCC_GMAC0_TX_SRC_SEL_GEPHY_TX; + writel(reg_val, GCC_GMAC0_TX_CFG_RCGR); + + reg_val = readl(GCC_GMAC1_RX_CFG_RCGR); + reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK; + reg_val |= GCC_GMAC1_RX_SRC_SEL_UNIPHY_RX; + writel(reg_val, GCC_GMAC1_RX_CFG_RCGR); + + reg_val = readl(GCC_GMAC1_TX_CFG_RCGR); + reg_val &= ~GCC_GMAC_CFG_RCGR_SRC_SEL_MASK; + reg_val |= GCC_GMAC1_TX_SRC_SEL_UNIPHY_TX; + writel(reg_val, GCC_GMAC1_TX_CFG_RCGR); +} + +static void gephy_reset(void) +{ + u32 reg_val; + + reg_val = readl(GCC_GEPHY_BCR); + writel(reg_val | (GCC_GEPHY_BCR_BLK_ARES), + GCC_GEPHY_BCR); + mdelay(200); + 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); + writel(reg_val & (~GCC_GEPHY_MISC_ARES), + GCC_GEPHY_MISC); +} + +static void uniphy_reset(void) +{ + u32 reg_val; + + reg_val = readl(GCC_UNIPHY_BCR); + writel(reg_val | (GCC_UNIPHY_BCR_BLK_ARES), + GCC_UNIPHY_BCR); + mdelay(200); + writel(reg_val & (~GCC_UNIPHY_BCR_BLK_ARES), + GCC_UNIPHY_BCR); +} + +static void gmac_reset(void) +{ + u32 reg_val; + + reg_val = readl(GCC_GMAC0_BCR); + writel(reg_val | (GCC_GMAC0_BCR_BLK_ARES), + GCC_GMAC0_BCR); + mdelay(200); + writel(reg_val & (~GCC_GMAC0_BCR_BLK_ARES), + GCC_GMAC0_BCR); + + reg_val = readl(GCC_GMAC1_BCR); + writel(reg_val | (GCC_GMAC1_BCR_BLK_ARES), + GCC_GMAC1_BCR); + mdelay(200); + writel(reg_val & (~GCC_GMAC1_BCR_BLK_ARES), + GCC_GMAC1_BCR); + +} + +static void gmac_clock_enable(void) +{ + cmn_blk_clk_set(); + uniphy_clk_set(); + gephy_port_clock_reset(); + gmac0_clock_reset(); + gmac_clk_src_init(); + gephy_reset(); + uniphy_reset(); + gmac_reset(); + + /* 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); + + /* 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); +} + int board_eth_init(bd_t *bis) { int status; @@ -559,6 +791,15 @@ int board_eth_init(bd_t *bis) gmac_cfg_node = fdt_path_offset(gd->fdt_blob, "/gmac_cfg"); if (gmac_cfg_node >= 0) { + /* + * Clock enable + */ + gmac_clock_enable(); + + 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++) { @@ -572,12 +813,33 @@ int board_eth_init(bd_t *bis) gmac_cfg[loop].phy_addr = fdtdec_get_uint(gd->fdt_blob, offset, "phy_address", 0); + gmac_cfg[loop].phy_interface_mode = fdtdec_get_uint(gd->fdt_blob, + offset, "phy_interface_mode", 0); + + gmac_cfg[loop].phy_napa_gpio = fdtdec_get_uint(gd->fdt_blob, + offset, "napa_gpio", 0); + if (gmac_cfg[loop].phy_napa_gpio){ + set_napa_phy_gpio(gmac_cfg[loop].phy_napa_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].ipq_swith = fdtdec_get_uint(gd->fdt_blob, + offset, "s17c_switch_enable", 0); + phy_name_ptr = (char*)fdt_getprop(gd->fdt_blob, offset, "phy_name", &phy_name_len); strlcpy((char *)gmac_cfg[loop].phy_name, phy_name_ptr, phy_name_len); - } - } + } + } gmac_cfg[loop].unit = -1; ipq_gmac_common_init(gmac_cfg); @@ -608,21 +870,23 @@ void board_usb_deinit(int id) return; /* Enable USB PHY Power down */ - setbits_le32(USB30_PHY_1_QUSB2PHY_BASE + 0xB4, 0x1); + setbits_le32(QUSB2PHY_BASE + 0xA4, 0x0); /* Disable clocks */ - writel(0x8000, GCC_USB0_PHY_CFG_AHB_CBCR); - writel(0x8ff0, GCC_USB0_MASTER_CBCR); - writel(0, GCC_SYS_NOC_USB0_AXI_CBCR); - writel(0, GCC_SNOC_BUS_TIMEOUT2_AHB_CBCR); - writel(0, GCC_USB0_SLEEP_CBCR); - writel(0, GCC_USB0_MOCK_UTMI_CBCR); - writel(0, GCC_USB0_AUX_CBCR); + writel(0x0, GCC_USB0_PHY_CFG_AHB_CBCR); + writel(0x4220, GCC_USB0_MASTER_CBCR); + writel(0x0, GCC_SYS_NOC_USB0_AXI_CBCR); + writel(0x0, GCC_USB0_SLEEP_CBCR); + writel(0x0, GCC_USB0_MOCK_UTMI_CBCR); + writel(0x0, GCC_USB0_AUX_CBCR); + writel(0x0, GCC_USB0_LFPS_CBCR); /* GCC_QUSB2_0_PHY_BCR */ set_mdelay_clearbits_le32(GCC_QUSB2_0_PHY_BCR, 0x1, 10); /* GCC_USB0_PHY_BCR */ 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); } static void usb_clock_init(int id) @@ -641,13 +905,22 @@ static void usb_clock_init(int id) cfg = (GCC_USB_MOCK_UTMI_SRC_SEL | GCC_USB_MOCK_UTMI_SRC_DIV); writel(cfg, GCC_USB0_MOCK_UTMI_CFG_RCGR); - writel(UTMI_M, GCC_USB0_MOCK_UTMI_M); - writel(UTMI_N, GCC_USB0_MOCK_UTMI_N); - writel(UTMI_D, GCC_USB0_MOCK_UTMI_D); + writel(GCC_USB_MOCK_UTMI_CLK_DIV, GCC_USB0_MOCK_UTMI_CBCR); writel(CMD_UPDATE, GCC_USB0_MOCK_UTMI_CMD_RCGR); mdelay(100); writel(ROOT_EN, GCC_USB0_MOCK_UTMI_CMD_RCGR); + /* Configure usb0_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); @@ -658,132 +931,61 @@ static void usb_clock_init(int id) /* Configure CBCRs */ writel(CLK_DISABLE, GCC_SYS_NOC_USB0_AXI_CBCR); - writel(CLK_DISABLE, GCC_SNOC_BUS_TIMEOUT2_AHB_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_SNOC_BUS_TIMEOUT2_AHB_CBCR); writel(CLK_ENABLE, GCC_USB0_SLEEP_CBCR); writel(CLK_ENABLE, GCC_USB0_MOCK_UTMI_CBCR); - writel((CLK_ENABLE | NOC_HANDSHAKE_FSM_EN), - GCC_USB0_PHY_CFG_AHB_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); } static void usb_init_hsphy(void __iomem *phybase) { - /* Enable QUSB2PHY Power down */ - setbits_le32(phybase+0xB4, 0x1); - - /* PHY Config Sequence */ - /* QUSB2PHY_PLL:PLL Feedback Divider Value */ - out_8(phybase+0x00, 0x14); - /* QUSB2PHY_PORT_TUNE1: USB Product Application Tuning Register A */ - out_8(phybase+0x80, 0xF8); - /* QUSB2PHY_PORT_TUNE2: USB Product Application Tuning Register B */ - out_8(phybase+0x84, 0xB3); - /* QUSB2PHY_PORT_TUNE3: USB Product Application Tuning Register C */ - out_8(phybase+0x88, 0x83); - /* QUSB2PHY_PORT_TUNE4: USB Product Application Tuning Register D */ - out_8(phybase+0x8C, 0xC0); - /* QUSB2PHY_PORT_TEST2 */ - out_8(phybase+0x9C, 0x14); - /* QUSB2PHY_PLL_TUNE: PLL Test Configuration */ - out_8(phybase+0x08, 0x30); - /* QUSB2PHY_PLL_USER_CTL1: PLL Control Configuration */ - out_8(phybase+0x0C, 0x79); - /* QUSB2PHY_PLL_USER_CTL2: PLL Control Configuration */ - out_8(phybase+0x10, 0x21); - /* QUSB2PHY_PORT_TUNE5 */ - out_8(phybase+0x90, 0x00); - /* QUSB2PHY_PLL_PWR_CTL: PLL Manual SW Programming - * and Biasing Power Options */ - out_8(phybase+0x18, 0x00); - /* QUSB2PHY_PLL_AUTOPGM_CTL1: Auto vs. Manual PLL/Power-mode - * programming State Machine Control Options */ - out_8(phybase+0x1C, 0x9F); - /* QUSB2PHY_PLL_TEST: PLL Test Configuration-Disable diff ended clock */ - out_8(phybase+0x04, 0x80); - - /* Disable QUSB2PHY Power down */ - clrbits_le32(phybase+0xB4, 0x1); + /* Disable USB PHY Power down */ + setbits_le32(phybase + 0xA4, 0x1); + /* Enable override ctrl */ + writel(UTMI_PHY_OVERRIDE_EN, phybase + USB_PHY_CFG0); + /* Enable POR*/ + writel(POR_EN, phybase + USB_PHY_UTMI_CTRL5); + udelay(15); + /* Configure frequency select value*/ + writel(FREQ_SEL, phybase + USB_PHY_FSEL_SEL); + /* Configure refclk frequency */ + writel(COMMONONN | FSEL | RETENABLEN, + phybase + USB_PHY_HS_PHY_CTRL_COMMON0); + /* select refclk source */ + writel(CLKCORE, phybase + USB_PHY_REFCLK_CTRL); + /* select ATERESET*/ + writel(POR_EN & ATERESET, phybase + USB_PHY_UTMI_CTRL5); + writel(USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN, + phybase + USB_PHY_HS_PHY_CTRL2); + writel(0x0, phybase + USB_PHY_UTMI_CTRL5); + writel(USB2_SUSPEND_N | USB2_UTMI_CLK_EN, + phybase + USB_PHY_HS_PHY_CTRL2); + /* Disable override ctrl */ + writel(0x0, phybase + USB_PHY_CFG0); } static void usb_init_ssphy(void __iomem *phybase) { - out_8(phybase + USB3_PHY_POWER_DOWN_CONTROL,0x1); - out_8(phybase + QSERDES_COM_SYSCLK_EN_SEL,0x1a); - out_8(phybase + QSERDES_COM_BIAS_EN_CLKBUFLR_EN,0x08); - out_8(phybase + QSERDES_COM_CLK_SELECT,0x30); - out_8(phybase + QSERDES_COM_BG_TRIM,0x0f); - out_8(phybase + QSERDES_RX_UCDR_FASTLOCK_FO_GAIN,0x0b); - out_8(phybase + QSERDES_COM_SVS_MODE_CLK_SEL,0x01); - out_8(phybase + QSERDES_COM_HSCLK_SEL,0x00); - out_8(phybase + QSERDES_COM_CMN_CONFIG,0x06); - out_8(phybase + QSERDES_COM_PLL_IVCO,0x0f); - out_8(phybase + QSERDES_COM_SYS_CLK_CTRL,0x06); - out_8(phybase + QSERDES_COM_DEC_START_MODE0,0x68); - out_8(phybase + QSERDES_COM_DIV_FRAC_START1_MODE0,0xAB); - out_8(phybase + QSERDES_COM_DIV_FRAC_START2_MODE0,0xAA); - out_8(phybase + QSERDES_COM_DIV_FRAC_START3_MODE0,0x02); - out_8(phybase + QSERDES_COM_CP_CTRL_MODE0,0x09); - out_8(phybase + QSERDES_COM_PLL_RCTRL_MODE0,0x16); - out_8(phybase + QSERDES_COM_PLL_CCTRL_MODE0,0x28); - out_8(phybase + QSERDES_COM_INTEGLOOP_GAIN0_MODE0,0xA0); - out_8(phybase + QSERDES_COM_LOCK_CMP1_MODE0,0xAA); - out_8(phybase + QSERDES_COM_LOCK_CMP2_MODE0,0x29); - out_8(phybase + QSERDES_COM_LOCK_CMP3_MODE0,0x00); - out_8(phybase + QSERDES_COM_CORE_CLK_EN,0x00); - out_8(phybase + QSERDES_COM_LOCK_CMP_CFG,0x00); - out_8(phybase + QSERDES_COM_VCO_TUNE_MAP,0x00); - out_8(phybase + QSERDES_COM_BG_TIMER,0x0a); - out_8(phybase + QSERDES_COM_SSC_EN_CENTER,0x01); - out_8(phybase + QSERDES_COM_SSC_PER1,0x7D); - out_8(phybase + QSERDES_COM_SSC_PER2,0x01); - out_8(phybase + QSERDES_COM_SSC_ADJ_PER1,0x00); - out_8(phybase + QSERDES_COM_SSC_ADJ_PER2,0x00); - out_8(phybase + QSERDES_COM_SSC_STEP_SIZE1,0x0A); - out_8(phybase + QSERDES_COM_SSC_STEP_SIZE2,0x05); - out_8(phybase + QSERDES_RX_UCDR_SO_GAIN,0x06); - out_8(phybase + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2,0x02); - out_8(phybase + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3,0x6c); - out_8(phybase + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3,0x4c); - out_8(phybase + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4,0xb8); - out_8(phybase + QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL,0x77); - out_8(phybase + QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2,0x80); - out_8(phybase + QSERDES_RX_SIGDET_CNTRL,0x03); - out_8(phybase + QSERDES_RX_SIGDET_DEGLITCH_CNTRL,0x16); - out_8(phybase + QSERDES_RX_SIGDET_ENABLES,0x0c); - out_8(phybase + QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_D,0x45); - out_8(phybase + QSERDES_TX_RCV_DETECT_LVL_2,0x12); - out_8(phybase + QSERDES_TX_LANE_MODE,0x06); - out_8(phybase + PCS_TXDEEMPH_M6DB_V0,0x15); - out_8(phybase + PCS_TXDEEMPH_M3P5DB_V0,0x0e); - out_8(phybase + PCS_FLL_CNTRL2,0x83); - out_8(phybase + PCS_FLL_CNTRL1,0x02); - out_8(phybase + PCS_FLL_CNT_VAL_L,0x09); - out_8(phybase + PCS_FLL_CNT_VAL_H_TOL,0xa2); - out_8(phybase + PCS_FLL_MAN_CODE,0x85); - out_8(phybase + PCS_LOCK_DETECT_CONFIG1,0xd1); - out_8(phybase + PCS_LOCK_DETECT_CONFIG2,0x1f); - out_8(phybase + PCS_LOCK_DETECT_CONFIG3,0x47); - out_8(phybase + PCS_POWER_STATE_CONFIG2,0x1b); - out_8(phybase + PCS_RXEQTRAINING_WAIT_TIME,0x75); - out_8(phybase + PCS_RXEQTRAINING_RUN_TIME,0x13); - out_8(phybase + PCS_LFPS_TX_ECSTART_EQTLOCK,0x86); - out_8(phybase + PCS_PWRUP_RESET_DLY_TIME_AUXCLK,0x04); - out_8(phybase + PCS_TSYNC_RSYNC_TIME,0x44); - out_8(phybase + PCS_RCVR_DTCT_DLY_P1U2_L,0xe7); - out_8(phybase + PCS_RCVR_DTCT_DLY_P1U2_H,0x03); - out_8(phybase + PCS_RCVR_DTCT_DLY_U3_L,0x40); - out_8(phybase + PCS_RCVR_DTCT_DLY_U3_H,0x00); - out_8(phybase + PCS_RX_SIGDET_LVL,0x88); - out_8(phybase + USB3_PCS_TXDEEMPH_M6DB_V0,0x17); - out_8(phybase + USB3_PCS_TXDEEMPH_M3P5DB_V0,0x0f); - out_8(phybase + QSERDES_RX_SIGDET_ENABLES,0x0); - out_8(phybase + USB3_PHY_START_CONTROL,0x03); - out_8(phybase + USB3_PHY_SW_RESET,0x00); + /* 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); + /*set fstep*/ + writel(0x1, phybase + SSCG_CTRL_REG_1); + writel(0xeb, phybase + SSCG_CTRL_REG_2); + return; } static void usb_init_phy(int index) @@ -815,8 +1017,8 @@ static void usb_init_phy(int index) clrbits_le32(qusb2_phy_bcr, 0x1); mdelay(10); - usb_init_hsphy((u32 *)USB30_PHY_1_QUSB2PHY_BASE); - usb_init_ssphy((u32 *)USB30_PHY_1_USB3PHY_AHB2PHY_BASE); + usb_init_hsphy((u32 *)QUSB2PHY_BASE); + usb_init_ssphy((u32 *)USB3PHY_APB_BASE); } int ipq_board_usb_init(void) @@ -827,6 +1029,10 @@ int ipq_board_usb_init(void) for (i=0; ifdt_blob, node_name); + if (nodeoff < 0){ + printf("USB: Node Not found, skipping initialization \n"); + return -1; + } if (!fdtdec_get_int(gd->fdt_blob, nodeoff, "qcom,emulation", 0)) { usb_clock_init(i); @@ -841,6 +1047,105 @@ int ipq_board_usb_init(void) #endif #ifdef CONFIG_PCI_IPQ +static void pcie_v2_clock_init(int id) +{ +#ifdef CONFIG_PCI + int cfg; + unsigned tmp; + void __iomem *base; + + /*single lane*/ + if (id == 0) { + base = (void __iomem *)GCC_PCIE1_BOOT_CLOCK_CTL; + /* Configure pcie1_aux_clk_src */ + cfg = (GCC_PCIE1_AUX_CFG_RCGR_SRC_SEL | + GCC_PCIE1_AUX_CFG_RCGR_SRC_DIV); + } else { /*double lane*/ + base = (void __iomem *)GCC_PCIE0_BOOT_CLOCK_CTL; + /* Configure pcie0_aux_clk_src */ + cfg = (GCC_PCIE0_AUX_CFG_RCGR_SRC_SEL | + GCC_PCIE0_AUX_CFG_RCGR_SRC_DIV); + } + + writel(cfg, base + PCIE_AUX_CFG_RCGR); + writel(CMD_UPDATE, base + PCIE_AUX_CMD_RCGR); + mdelay(100); + writel(ROOT_EN, base + PCIE_AUX_CMD_RCGR); + + if (id == 0) + /* Configure pcie1_axi_clk_src */ + cfg = (GCC_PCIE1_AXI_CFG_RCGR_SRC_SEL | + GCC_PCIE1_AXI_CFG_RCGR_SRC_DIV); + + else + /* Configure pcie0_axi_clk_src */ + cfg = (GCC_PCIE0_AXI_CFG_RCGR_SRC_SEL | + GCC_PCIE0_AXI_CFG_RCGR_SRC_DIV); + + writel(cfg, base + PCIE_AXI_CFG_RCGR); + writel(CMD_UPDATE, base + PCIE_AXI_CMD_RCGR); + mdelay(100); + writel(ROOT_EN, base + PCIE_AXI_CMD_RCGR); + + /* Configure CBCRs */ + if (id == 0) + writel(CLK_ENABLE, GCC_SYS_NOC_PCIE1_AXI_CBCR); + else + writel(CLK_ENABLE, GCC_SYS_NOC_PCIE0_AXI_CBCR); + + writel(CLK_ENABLE, base + PCIE_AHB_CBCR); + + tmp = readl(base + PCIE_AXI_M_CBCR); + tmp |= CLK_ENABLE; + writel(tmp, base + PCIE_AXI_M_CBCR); + + tmp = readl(base + PCIE_AXI_S_CBCR); + tmp |= CLK_ENABLE; + writel(tmp, base + PCIE_AXI_S_CBCR); + + writel(CLK_ENABLE, base + PCIE_AUX_CBCR); + + tmp = readl(base + PCIE_PIPE_CBCR); + tmp |= CLK_ENABLE; + writel(tmp, base + PCIE_PIPE_CBCR); + + writel(CLK_ENABLE, PCIE_AXI_S_BRIDGE_CBCR); +#endif + return; +} + +static void pcie_v2_clock_deinit(int id) +{ +#ifdef CONFIG_PCI + void __iomem *base; + + /*single lane*/ + if (id == 0) + base = (void __iomem *)GCC_PCIE1_BOOT_CLOCK_CTL; + else /*double lane*/ + base = (void __iomem *)GCC_PCIE0_BOOT_CLOCK_CTL; + + writel(0x0, base + PCIE_AUX_CFG_RCGR); + writel(0x0, base + PCIE_AUX_CMD_RCGR); + writel(0x0, base + PCIE_AXI_CFG_RCGR); + writel(0x0, base + PCIE_AXI_CMD_RCGR); + mdelay(100); + + if (id == 0) + writel(0x0, GCC_SYS_NOC_PCIE1_AXI_CBCR); + else + writel(0x0, GCC_SYS_NOC_PCIE0_AXI_CBCR); + + writel(0x0, base + PCIE_AHB_CBCR); + writel(0x0, base + PCIE_AXI_M_CBCR); + writel(0x0, base + PCIE_AXI_S_CBCR); + writel(0x0, base + PCIE_AUX_CBCR); + writel(0x0, base + PCIE_PIPE_CBCR); + writel(0x0, base + PCIE_AXI_S_BRIDGE_CBCR); +#endif + return; +} + void board_pci_init(int id) { int node, gpio_node; @@ -856,6 +1161,7 @@ void board_pci_init(int id) if (gpio_node >= 0) qca_gpio_init(gpio_node); + pcie_v2_clock_init(id); return; } @@ -888,8 +1194,50 @@ void board_pci_deinit() if (gpio_node >= 0) qca_gpio_deinit(gpio_node); + pcie_v2_clock_deinit(i); } return ; } #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_bt_debug(void *blob) +{ + int node, phandle; + char node_name[32]; + + if ((gd->bd->bi_arch_number == MACH_TYPE_IPQ5018_AP_MP02_1) || + (gd->bd->bi_arch_number == MACH_TYPE_IPQ5018_DB_MP02_1)) { + node = fdt_path_offset(blob, "/soc/pinctrl@1000000/btss_pins"); + if (node) { + phandle = fdtdec_get_int(blob, node, "phandle", 0); + snprintf(node_name, + sizeof(node_name), + "%s%d", + "/soc/bt@7000000%pinctrl-0%", + phandle); + parse_fdt_fixup("/soc/bt@7000000%pinctrl-names%?btss_pins", blob); + parse_fdt_fixup(node_name, blob); + } + } + parse_fdt_fixup("/soc/serial@78b0000/%status%?ok", blob); + +} + +void run_tzt(void *address) +{ + execute_tzt(address); +} diff --git a/board/qca/arm/ipq5018/ipq5018.h b/board/qca/arm/ipq5018/ipq5018.h index d713da95f7..00ecbc3e66 100644 --- a/board/qca/arm/ipq5018/ipq5018.h +++ b/board/qca/arm/ipq5018/ipq5018.h @@ -19,8 +19,73 @@ #include #include "phy.h" -#define MSM_SDC1_BASE 0x7800000 -#define MSM_SDC1_SDHCI_BASE 0x7804000 +#define MSM_SDC1_BASE 0x7800000 +#define MSM_SDC1_SDHCI_BASE 0x7804000 + +#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 +/* + * CMN BLK clock + */ +#define GCC_CMN_BLK_AHB_CBCR 0x01856308 +#define GCC_CMN_BLK_SYS_CBCR 0x0185630C +/* + * GEPHY Block Register + */ +#define GCC_GEPHY_BCR 0x01856000 +#define GCC_GEPHY_MISC 0x01856004 +#define GCC_GEPHY_RX_CBCR 0x01856010 +#define GCC_GEPHY_TX_CBCR 0x01856014 +#define GCC_GEPHY_BCR_BLK_ARES 0x1 +#define GCC_GEPHY_MISC_ARES 0xf + +/* + * UNIPHY Block Register + */ +#define GCC_UNIPHY_BCR 0x01856100 +#define GCC_UNIPHY_AHB_CBCR 0x01856108 +#define GCC_UNIPHY_SYS_CBCR 0x0185610C +#define GCC_UNIPHY_BCR_BLK_ARES 0x1 +#define GCC_UNIPHY_MISC_ARES 0x32 + +/* GMAC0 GCC clock */ +#define GCC_GMAC0_RX_CMD_RCGR 0x01868020 +#define GCC_GMAC0_RX_CFG_RCGR 0x01868024 +#define GCC_GMAC0_TX_CMD_RCGR 0x01868028 +#define GCC_GMAC0_TX_CFG_RCGR 0x0186802C +#define GCC_GMAC0_RX_MISC 0x01868420 +#define GCC_GMAC0_TX_MISC 0x01868424 +#define GCC_GMAC0_MISC 0x01868428 +#define GCC_GMAC0_BCR 0x01819000 +#define GCC_SNOC_GMAC0_AXI_CBCR 0x01826084 +#define GCC_SNOC_GMAC0_AHB_CBCR 0x018260A0 +#define GCC_GMAC0_PTP_CBCR 0x01868300 +#define GCC_GMAC0_CFG_CBCR 0x01868304 +#define GCC_GMAC0_SYS_CBCR 0x01868190 +#define GCC_GMAC0_RX_CBCR 0x01868240 +#define GCC_GMAC0_TX_CBCR 0x01868244 +#define GCC_GMAC0_BCR_BLK_ARES 0x1 + +/* GMAC1 GCC Clock */ +#define GCC_GMAC1_RX_CMD_RCGR 0x01868030 +#define GCC_GMAC1_RX_CFG_RCGR 0x01868034 +#define GCC_GMAC1_TX_CMD_RCGR 0x01868038 +#define GCC_GMAC1_TX_CFG_RCGR 0x0186803C +#define GCC_GMAC1_RX_MISC 0x01868430 +#define GCC_GMAC1_TX_MISC 0x01868434 +#define GCC_GMAC1_MISC 0x01868438 +#define GCC_GMAC1_BCR 0x01819100 +#define GCC_SNOC_GMAC1_AXI_CBCR 0x01826088 +#define GCC_SNOC_GMAC1_AHB_CBCR 0x018260A4 +#define GCC_GMAC1_SYS_CBCR 0x01868310 +#define GCC_GMAC1_PTP_CBCR 0x01868320 +#define GCC_GMAC1_CFG_CBCR 0x01868324 +#define GCC_GMAC1_RX_CBCR 0x01868248 +#define GCC_GMAC1_TX_CBCR 0x0186824C +#define GCC_GMAC1_BCR_BLK_ARES 0x1 /* * GCC-SDCC Registers @@ -34,7 +99,6 @@ #define GCC_SDCC1_APPS_D 0x01842014 #define GCC_SDCC1_APPS_CBCR 0x01842018 #define GCC_SDCC1_AHB_CBCR 0x0184201C -#define GCC_SDCC1_MISC 0x01842020 /* * GCC-QPIC Registers @@ -44,6 +108,20 @@ #define GCC_QPIC_AHB_CBCR_ADDR 0x01857024 #define GCC_QPIC_SLEEP_CBCR 0x01857028 #define QPIC_CBCR_VAL 0x80004FF1 +#define GCC_QPIC_IO_MACRO_CMD_RCGR 0x01857010 +#define GCC_QPIC_IO_MACRO_CFG_RCGR 0x01857014 +#define IO_MACRO_CLK_320_MHZ 320000000 +#define IO_MACRO_CLK_266_MHZ 266000000 +#define IO_MACRO_CLK_228_MHZ 228000000 +#define IO_MACRO_CLK_200_MHZ 200000000 +#define IO_MACRO_CLK_100_MHZ 100000000 +#define IO_MACRO_CLK_24MHZ 24000000 +#define QPIC_IO_MACRO_CLK 0 +#define QPIC_CORE_CLK 1 +#define XO_CLK_SRC 2 +#define GPLL0_CLK_SRC 3 +#define FB_CLK_BIT (1 << 4) +#define UPDATE_EN 0x1 /* UART 1 */ #define GCC_BLSP1_UART1_BCR 0x01802038 @@ -63,9 +141,6 @@ #define GCC_BLSP1_UART2_APPS_N 0x01803040 #define GCC_BLSP1_UART2_APPS_D 0x01803044 - -#define GCC_SDCC1_BCR 0x01842000 - #define GCC_UART_CFG_RCGR_MODE_MASK 0x3000 #define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700 #define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F @@ -74,11 +149,12 @@ #define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8 #define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0 -#define UART1_RCGR_SRC_SEL 0x1 -#define UART1_RCGR_SRC_DIV 0x0 -#define UART1_RCGR_MODE 0x2 -#define UART1_CMD_RCGR_UPDATE 0x1 -#define UART1_CBCR_CLK_ENABLE 0x1 +#define UART1_RCGR_SRC_SEL 0x1 +#define UART1_RCGR_SRC_DIV 0x0 +#define UART1_RCGR_MODE 0x2 +#define UART1_CMD_RCGR_UPDATE 0x1 +#define UART1_CMD_RCGR_ROOT_EN 0x2 +#define UART1_CBCR_CLK_ENABLE 0x1 /* USB Registers */ #define GCC_SYS_NOC_USB0_AXI_CBCR 0x1826040 @@ -123,11 +199,17 @@ #define GUCTL 0x700C12C #define FLADJ 0x700C630 -#define USB30_PHY_1_QUSB2PHY_BASE 0x79000 +#define QUSB2PHY_BASE 0x5b000 + +#define GCC_USB0_LFPS_CFG_SRC_SEL (0x1 << 8) +#define GCC_USB0_LFPS_CFG_SRC_DIV (0x1f << 0) +#define LFPS_M 0x1 +#define LFPS_N 0xfe +#define LFPS_D 0xfd #define GCC_USB0_AUX_CFG_MODE_DUAL_EDGE (2 << 12) #define GCC_USB0_AUX_CFG_SRC_SEL (0 << 8) -#define GCC_USB0_AUX_CFG_SRC_DIV (0 << 0) +#define GCC_USB0_AUX_CFG_SRC_DIV (0x17 << 0) #define AUX_M 0x0 #define AUX_N 0x0 @@ -138,20 +220,18 @@ #define GCC_USB0_MASTER_CFG_RCGR_SRC_SEL (1 << 8) -#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV (0xb << 0) +#define GCC_USB0_MASTER_CFG_RCGR_SRC_DIV (0x7 << 0) -#define GCC_USB_MOCK_UTMI_SRC_SEL (0 << 8) -#define GCC_USB_MOCK_UTMI_SRC_DIV (1 << 0) +#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_SNOC_BUS_TIMEOUT2_AHB_CBCR 0x01847014 #define GCC_QUSB2_1_PHY_BCR 0x1841040 -#define USB30_PHY_2_QUSB2PHY_BASE 0x59000 -#define USB30_PHY_1_USB3PHY_AHB2PHY_BASE 0x78000 -#define USB30_PHY_2_USB2PHY_AHB2PHY_BASE 0x58000 +#define USB3PHY_APB_BASE 0x5d000 #define USB3_PHY_POWER_DOWN_CONTROL 0x804 #define QSERDES_COM_SYSCLK_EN_SEL 0xac @@ -227,7 +307,6 @@ #define CMD_UPDATE 0x1 #define ROOT_EN 0x2 -#define PIPE_CLK_ENABLE 0x4FF1 #define CLK_DISABLE 0x0 #define NOC_HANDSHAKE_FSM_EN (1 << 15) @@ -259,6 +338,11 @@ #define GCC_PCIE0_AXI_CMD_RCGR 0x01875050 #define GCC_PCIE0_AXI_CFG_RCGR 0x01875054 #define GCC_PCIE0_LINK_DOWN_BCR 0x018750A8 +#define GCC_PCIE0_AUX_CFG_RCGR_SRC_SEL (0 << 8) +#define GCC_PCIE0_AUX_CFG_RCGR_SRC_DIV 0x17 +#define GCC_PCIE0_AXI_CFG_RCGR_SRC_SEL (2 << 8) +#define GCC_PCIE0_AXI_CFG_RCGR_SRC_DIV 0x9 + #define GCC_PCIE1_BOOT_CLOCK_CTL 0x01876000 #define GCC_PCIE1_BCR 0x01876004 @@ -277,6 +361,21 @@ #define GCC_PCIE1_AXI_S_BRIDGE_CBCR 0x01876048 #define GCC_PCIE1_AXI_CMD_RCGR 0x01876050 #define GCC_PCIE1_AXI_CFG_RCGR 0x01876054 +#define GCC_PCIE1_AUX_CFG_RCGR_SRC_SEL (0 << 8) +#define GCC_PCIE1_AUX_CFG_RCGR_SRC_DIV 0x17 +#define GCC_PCIE1_AXI_CFG_RCGR_SRC_SEL (1 << 8) +#define GCC_PCIE1_AXI_CFG_RCGR_SRC_DIV 0x7 + +#define PCIE_AXI_M_CBCR 0x8 +#define PCIE_AXI_S_CBCR 0xC +#define PCIE_AHB_CBCR 0x10 +#define PCIE_AUX_CBCR 0x14 +#define PCIE_PIPE_CBCR 0x18 +#define PCIE_AUX_CMD_RCGR 0x20 +#define PCIE_AUX_CFG_RCGR 0x24 +#define PCIE_AXI_S_BRIDGE_CBCR 0x48 +#define PCIE_AXI_CMD_RCGR 0x50 +#define PCIE_AXI_CFG_RCGR 0x54 #define NOT_2D(two_d) (~two_d) #define NOT_N_MINUS_M(n,m) (~(n - m)) @@ -292,13 +391,47 @@ #define ARM_PSCI_TZ_FN_CPU_ON ARM_PSCI_TZ_FN(3) #define ARM_PSCI_TZ_FN_AFFINITY_INFO ARM_PSCI_TZ_FN(4) +#define CLK_ENABLE 0x1 +#define SSCG_CTRL_REG_1 0x9c +#define SSCG_CTRL_REG_2 0xa0 +#define SSCG_CTRL_REG_3 0xa4 +#define SSCG_CTRL_REG_4 0xa8 +#define SSCG_CTRL_REG_5 0xac +#define SSCG_CTRL_REG_6 0xb0 + +#define USB_PHY_CFG0 0x94 +#define USB_PHY_UTMI_CTRL5 0x50 +#define USB_PHY_FSEL_SEL 0xB8 +#define USB_PHY_HS_PHY_CTRL_COMMON0 0x54 +#define USB_PHY_REFCLK_CTRL 0xA0 +#define USB_PHY_HS_PHY_CTRL2 0x64 +#define USB_PHY_UTMI_CTRL0 0x3c + +#define UTMI_PHY_OVERRIDE_EN (1 << 1) +#define POR_EN (1 << 1) +#define FREQ_SEL (1 << 0) +#define COMMONONN (1 << 7) +#define FSEL (1 << 4) +#define RETENABLEN (1 << 3) +#define USB2_SUSPEND_N_SEL (1 << 3) +#define USB2_SUSPEND_N (1 << 2) +#define USB2_UTMI_CLK_EN (1 << 1) +#define CLKCORE (1 << 1) +#define ATERESET ~(1 << 0) + unsigned int __invoke_psci_fn_smc(unsigned int, unsigned int, unsigned int, unsigned int); typedef struct { - uint base; + u32 base; int unit; - uint phy_addr; + int phy_addr; + int phy_interface_mode; + int phy_napa_gpio; + int phy_type; + u32 mac_pwr0; + u32 mac_pwr1; + int ipq_swith; const char phy_name[MDIO_NAME_LEN]; } ipq_gmac_board_cfg_t; @@ -366,6 +499,8 @@ void reset_board(void); void qpic_clk_enbale(void); int ipq_get_tz_version(char *version_name, int buf_size); void ipq_fdt_fixup_socinfo(void *blob); +void qpic_set_clk_rate(unsigned int clk_rate, int blk_type, + int req_clk_src_type); extern const char *rsvd_node; extern const char *del_node[]; diff --git a/board/qca/arm/ipq6018/clock.c b/board/qca/arm/ipq6018/clock.c index 92beb069e5..71497fd7b0 100644 --- a/board/qca/arm/ipq6018/clock.c +++ b/board/qca/arm/ipq6018/clock.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_IPQ6018_I2C void i2c_clock_config(void) @@ -34,3 +35,67 @@ void i2c_clock_config(void) } #endif +static void uart_configure_mux(u8 id) +{ + unsigned long cfg_rcgr; + + cfg_rcgr = readl(GCC_BLSP1_UART_APPS_CFG_RCGR(id)); + /* Clear mode, src sel, src div */ + cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK | + GCC_UART_CFG_RCGR_SRCSEL_MASK | + GCC_UART_CFG_RCGR_SRCDIV_MASK); + + cfg_rcgr |= ((UART_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT) + & GCC_UART_CFG_RCGR_SRCSEL_MASK); + + cfg_rcgr |= ((UART_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT) + & GCC_UART_CFG_RCGR_SRCDIV_MASK); + + cfg_rcgr |= ((UART_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT) + & GCC_UART_CFG_RCGR_MODE_MASK); + + writel(cfg_rcgr, GCC_BLSP1_UART_APPS_CFG_RCGR(id)); +} + +static int uart_trigger_update(u8 id) +{ + unsigned long cmd_rcgr; + int timeout = 0; + + cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + cmd_rcgr |= UART_CMD_RCGR_UPDATE; + writel(cmd_rcgr, GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + + while (readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)) & UART_CMD_RCGR_UPDATE) { + if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { + printf("Timeout waiting for UART clock update\n"); + return -ETIMEDOUT; + } + udelay(1); + } + cmd_rcgr = readl(GCC_BLSP1_UART_APPS_CMD_RCGR(id)); + return 0; +} + +int uart_clock_config(struct ipq_serial_platdata *plat) +{ + unsigned long cbcr_val; + int ret; + + uart_configure_mux(plat->port_id); + + writel(plat->m_value, GCC_BLSP1_UART_APPS_M(plat->port_id)); + writel(NOT_N_MINUS_M(plat->n_value, plat->m_value), + GCC_BLSP1_UART_APPS_N(plat->port_id)); + writel(NOT_2D(plat->d_value), GCC_BLSP1_UART_APPS_D(plat->port_id)); + + ret = uart_trigger_update(plat->port_id); + if (ret) + return ret; + + cbcr_val = readl(GCC_BLSP1_UART_APPS_CBCR(plat->port_id)); + cbcr_val |= UART_CBCR_CLK_ENABLE; + writel(cbcr_val, GCC_BLSP1_UART_APPS_CBCR(plat->port_id)); + return 0; +} + diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c index bea8351f41..1e33bfdef7 100644 --- a/board/qca/arm/ipq6018/ipq6018.c +++ b/board/qca/arm/ipq6018/ipq6018.c @@ -109,99 +109,25 @@ struct dumpinfo_t dumpinfo_s[] = { int dump_entries_s = ARRAY_SIZE(dumpinfo_s); u32 *tz_wonce = (u32 *)CONFIG_IPQ6018_TZ_WONCE_4_ADDR; - -void uart2_configure_mux(void) -{ - unsigned long cfg_rcgr; - - cfg_rcgr = readl(GCC_BLSP1_UART2_APPS_CFG_RCGR); - /* Clear mode, src sel, src div */ - cfg_rcgr &= ~(GCC_UART_CFG_RCGR_MODE_MASK | - GCC_UART_CFG_RCGR_SRCSEL_MASK | - GCC_UART_CFG_RCGR_SRCDIV_MASK); - - cfg_rcgr |= ((UART2_RCGR_SRC_SEL << GCC_UART_CFG_RCGR_SRCSEL_SHIFT) - & GCC_UART_CFG_RCGR_SRCSEL_MASK); - - cfg_rcgr |= ((UART2_RCGR_SRC_DIV << GCC_UART_CFG_RCGR_SRCDIV_SHIFT) - & GCC_UART_CFG_RCGR_SRCDIV_MASK); - - cfg_rcgr |= ((UART2_RCGR_MODE << GCC_UART_CFG_RCGR_MODE_SHIFT) - & GCC_UART_CFG_RCGR_MODE_MASK); - - writel(cfg_rcgr, GCC_BLSP1_UART2_APPS_CFG_RCGR); -} - -void uart2_set_rate_mnd(unsigned int m, - unsigned int n, unsigned int two_d) -{ - writel(m, GCC_BLSP1_UART2_APPS_M); - writel(NOT_N_MINUS_M(n, m), GCC_BLSP1_UART2_APPS_N); - writel(NOT_2D(two_d), GCC_BLSP1_UART2_APPS_D); -} - -int uart2_trigger_update(void) -{ - unsigned long cmd_rcgr; - int timeout = 0; - - cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR); - cmd_rcgr |= UART2_CMD_RCGR_UPDATE; - writel(cmd_rcgr, GCC_BLSP1_UART2_APPS_CMD_RCGR); - - while (readl(GCC_BLSP1_UART2_APPS_CMD_RCGR) & UART2_CMD_RCGR_UPDATE) { - if (timeout++ >= CLOCK_UPDATE_TIMEOUT_US) { - printf("Timeout waiting for UART2 clock update\n"); - return -ETIMEDOUT; - } - udelay(1); - } - cmd_rcgr = readl(GCC_BLSP1_UART2_APPS_CMD_RCGR); - return 0; -} - -void uart2_toggle_clock(void) -{ - unsigned long cbcr_val; - - cbcr_val = readl(GCC_BLSP1_UART2_APPS_CBCR); - cbcr_val |= UART2_CBCR_CLK_ENABLE; - writel(cbcr_val, GCC_BLSP1_UART2_APPS_CBCR); -} - -void uart2_clock_config(unsigned int m, - unsigned int n, unsigned int two_d) -{ - uart2_configure_mux(); - uart2_set_rate_mnd(m, n, two_d); - uart2_trigger_update(); - uart2_toggle_clock(); -} +#define BLSP1_UART0_BASE 0x078AF000 +#define UART_PORT_ID(reg) ((reg - BLSP1_UART0_BASE) / 0x1000) void qca_serial_init(struct ipq_serial_platdata *plat) { - int node, uart2_node; + int ret; - writel(1, GCC_BLSP1_UART1_APPS_CBCR); - - node = fdt_path_offset(gd->fdt_blob, "/serial@78B1000/serial_gpio"); - if (node < 0) { - printf("Could not find serial_gpio node\n"); + if (plat->gpio_node < 0) { + printf("serial_init: unable to find gpio node \n"); return; } - if (plat->port_id == 1) { - uart2_node = fdt_path_offset(gd->fdt_blob, "uart2"); - if (uart2_node < 0) { - printf("Could not find uart2 node\n"); - return; - } - node = fdt_subnode_offset(gd->fdt_blob, - uart2_node, "serial_gpio"); - uart2_clock_config(plat->m_value, plat->n_value, plat->d_value); - writel(1, GCC_BLSP1_UART2_APPS_CBCR); - } - qca_gpio_init(node); + qca_gpio_init(plat->gpio_node); + plat->port_id = UART_PORT_ID(plat->reg_base); + ret = uart_clock_config(plat); + if (ret) + printf("UART clock config failed %d \n", ret); + + return; } int do_pmic_reset() @@ -844,11 +770,6 @@ void ipq_fdt_fixup_usb_device_mode(void *blob) printf("%s: invalid param for usb_mode\n", __func__); } -void fdt_fixup_set_dload_dis(void *blob) -{ - parse_fdt_fixup("/soc/qca,scm_restart_reason%dload_status%1", blob); -} - void enable_caches(void) { qca_smem_flash_info_t *sfi = &qca_smem_flash_info; diff --git a/board/qca/arm/ipq6018/ipq6018.h b/board/qca/arm/ipq6018/ipq6018.h index 85cb3f7362..c02fb9bbfa 100644 --- a/board/qca/arm/ipq6018/ipq6018.h +++ b/board/qca/arm/ipq6018/ipq6018.h @@ -59,35 +59,9 @@ #define SDCC1_N_VAL 0xFC #define SDCC1_D_VAL 0xFD -#define GCC_BLSP1_UART1_APPS_CBCR 0x0180203c #define GCC_SDCC1_BCR 0x01842000 #define GCC_SDCC1_AHB_CBCR 0x0184201C -#define GCC_BLSP1_UART2_APPS_CFG_RCGR 0x01803038 -#define GCC_BLSP1_UART2_APPS_M 0x0180303C -#define GCC_BLSP1_UART2_APPS_N 0x01803040 -#define GCC_BLSP1_UART2_APPS_D 0x01803044 -#define GCC_BLSP1_UART2_APPS_CMD_RCGR 0x01803034 -#define GCC_BLSP1_UART2_APPS_CBCR 0x0180302C - -#define GCC_UART_CFG_RCGR_MODE_MASK 0x3000 -#define GCC_UART_CFG_RCGR_SRCSEL_MASK 0x0700 -#define GCC_UART_CFG_RCGR_SRCDIV_MASK 0x001F - -#define GCC_UART_CFG_RCGR_MODE_SHIFT 12 -#define GCC_UART_CFG_RCGR_SRCSEL_SHIFT 8 -#define GCC_UART_CFG_RCGR_SRCDIV_SHIFT 0 - -#define UART2_RCGR_SRC_SEL 0x1 -#define UART2_RCGR_SRC_DIV 0x0 -#define UART2_RCGR_MODE 0x2 -#define UART2_CMD_RCGR_UPDATE 0x1 -#define UART2_CBCR_CLK_ENABLE 0x1 - -#define NOT_2D(two_d) (~two_d) -#define NOT_N_MINUS_M(n,m) (~(n - m)) -#define CLOCK_UPDATE_TIMEOUT_US 1000 - #define CLOCK_UPDATE_TIMEOUT_US 1000 #define KERNEL_AUTH_CMD 0x1E #define SCM_CMD_SEC_AUTH 0x1F diff --git a/common/Makefile b/common/Makefile index c8f28287af..5287a19e3e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -141,7 +141,9 @@ 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 diff --git a/configs/ipq5018_defconfig b/configs/ipq5018_defconfig index 1a4effce0d..675e717f87 100644 --- a/configs/ipq5018_defconfig +++ b/configs/ipq5018_defconfig @@ -18,8 +18,9 @@ CONFIG_SYS_EXTRA_OPTIONS="" CONFIG_SYS_PROMPT="IPQ5018# " # -# Commands +# Tiny support # +# CONFIG_IPQ_TINY is not set # # Info commands @@ -53,7 +54,7 @@ CONFIG_CMD_ENV_EXISTS=y CONFIG_CMD_MEMORY=y CONFIG_CMD_CRC32=y # CONFIG_LOOPW is not set -# CONFIG_CMD_MEMTEST is not set +CONFIG_CMD_MEMTEST=y # CONFIG_CMD_MX_CYCLIC is not set # CONFIG_CMD_MEMINFO is not set @@ -104,7 +105,8 @@ CONFIG_CMD_MISC=y CONFIG_CMD_PART=y CONFIG_PARTITION_UUIDS=y # CONFIG_CMD_TIMER is not set - +CONFIG_IPQ_TZT=y +CONFIG_UBI_WRITE=y # # Boot timing # @@ -176,6 +178,7 @@ CONFIG_SIMPLE_BUS=y # # CONFIG_DM_I2C_COMPAT is not set # CONFIG_CROS_EC_KEYB is not set +CONFIG_IPQ5018_I2C=y # # LED Support @@ -194,6 +197,7 @@ CONFIG_SIMPLE_BUS=y # MMC Host controller Support # # CONFIG_DM_MMC is not set +CONFIG_MMC_FLASH=y # # NAND Device Support @@ -205,6 +209,12 @@ CONFIG_SIMPLE_BUS=y # # Generic NAND options # +CONFIG_NAND_FLASH=y + +# +# Serial NAND +# +CONFIG_QPIC_SERIAL=y # # SPI Flash Support @@ -214,6 +224,8 @@ CONFIG_SIMPLE_BUS=y # CONFIG_DM_ETH is not set # CONFIG_PHYLIB is not set # CONFIG_NETDEVICES is not set +CONFIG_IPQ_MTD_NOR=y +# CONFIG_IPQ_TINY_SPI_NOR is not set # # PCI @@ -309,6 +321,7 @@ CONFIG_REGEX=y # Compression Support # # CONFIG_LZ4 is not set +CONFIG_LZMA=y # CONFIG_ERRNO_STR is not set # CONFIG_UNIT_TEST is not set diff --git a/configs/ipq5018_tiny_defconfig b/configs/ipq5018_tiny_defconfig new file mode 100644 index 0000000000..50a20170c7 --- /dev/null +++ b/configs/ipq5018_tiny_defconfig @@ -0,0 +1,337 @@ +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=y +CONFIG_CMD_CONSOLE=y + +# +# Boot commands +# +# CONFIG_CMD_BOOTD is not set +CONFIG_CMD_BOOTM=y +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set + +# +# Environment commands +# +CONFIG_CMD_EXPORTENV=y +CONFIG_CMD_IMPORTENV=y +CONFIG_CMD_EDITENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_ENV_EXISTS=y + +# +# Memory commands +# +CONFIG_CMD_MEMORY=y +CONFIG_CMD_CRC32=y +# CONFIG_LOOPW is not set +# CONFIG_CMD_MEMTEST is not set +# CONFIG_CMD_MX_CYCLIC is not set +# CONFIG_CMD_MEMINFO is not set + +# +# Device access commands +# + +CONFIG_CMD_DM=y +# CONFIG_CMD_DEMO is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_FLASH=y +# CONFIG_CMD_NAND is not set +# CONFIG_CMD_SF is not set +# CONFIG_CMD_SPI is not set +# CONFIG_CMD_I2C is not set +# CONFIG_CMD_USB is not set +# CONFIG_CMD_FPGA is not set + +# +# Shell scripting commands +# +CONFIG_CMD_ECHO=y +CONFIG_CMD_ITEST=y +CONFIG_CMD_SOURCE=y +CONFIG_CMD_SETEXPR=y + +# +# 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=y +CONFIG_PARTITION_UUIDS=y +# CONFIG_CMD_TIMER is not set +# CONFIG_IPQ_TZT is not set +# CONFIG_UBI_WRITE is not set +# +# Boot timing +# +# CONFIG_BOOTSTAGE is not set +CONFIG_BOOTSTAGE_USER_COUNT=20 +CONFIG_BOOTSTAGE_STASH_ADDR=0 +CONFIG_BOOTSTAGE_STASH_SIZE=4096 + +# +# Power commands +# + +# +# Security commands +# +CONFIG_SUPPORT_OF_CONTROL=y + +# +# Device Tree Control +# +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +# CONFIG_OF_EMBED is not set +CONFIG_NET=y +# CONFIG_NET_RANDOM_ETHADDR is not set +# CONFIG_NETCONSOLE is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_DM=y +CONFIG_DM_WARN=y +CONFIG_DM_DEVICE_REMOVE=y +CONFIG_DM_STDIO=y +CONFIG_DM_SEQ_ALIAS=y +# CONFIG_REGMAP is not set +# CONFIG_DEVRES is not set +CONFIG_SIMPLE_BUS=y +# CONFIG_CLK is not set +# CONFIG_CPU is not set + +# +# Hardware crypto devices +# +# CONFIG_FSL_CAAM is not set + +# +# Demo for driver model +# +# CONFIG_DM_DEMO is not set + +# +# DFU support +# +# CONFIG_DFU_TFTP is not set + +# +# GPIO Support +# +# CONFIG_LPC32XX_GPIO is not set +# CONFIG_VYBRID_GPIO is not set + +# +# I2C support +# +# CONFIG_DM_I2C_COMPAT is not set +# CONFIG_CROS_EC_KEYB is not set +# CONFIG_IPQ5018_I2C is not set + +# +# LED Support +# +# CONFIG_LED is not set + +# +# Multifunction device drivers +# +# CONFIG_CROS_EC is not set +# CONFIG_FSL_SEC_MON is not set +# CONFIG_PCA9551_LED is not set +# CONFIG_RESET is not set + +# +# MMC Host controller Support +# +# CONFIG_DM_MMC is not set +# CONFIG_MMC_FLASH is not set + +# +# NAND Device Support +# +# CONFIG_NAND_DENALI is not set +# CONFIG_NAND_VF610_NFC is not set +# CONFIG_NAND_PXA3XX is not set + +# +# Generic NAND options +# +# CONFIG_NAND_FLASH is not set + +# +# Serial NAND +# +# CONFIG_QPIC_SERIAL is not set + +# +# SPI Flash Support + +# +# CONFIG_SPI_FLASH is not set +# CONFIG_DM_ETH is not set +# CONFIG_PHYLIB is not set +# CONFIG_NETDEVICES is not set +# CONFIG_IPQ_MTD_NOR is not set +CONFIG_IPQ_TINY_SPI_NOR=y + +# +# PCI +# +# CONFIG_DM_PCI is not set +# CONFIG_PCI_IPQ is not set + +# +# Pin controllers +# +# CONFIG_PINCTRL is not set + +# +# Power +# +# CONFIG_DM_PMIC is not set +# CONFIG_DM_REGULATOR is not set +# CONFIG_RAM is not set + +# +# Real Time Clock +# +# CONFIG_DM_RTC is not set + +# +# Serial drivers +# +CONFIG_REQUIRE_SERIAL_CONSOLE=y +# CONFIG_DEBUG_UART is not set + +# + +# Sound support +# +# CONFIG_SOUND is not set + +# +# SPI Support +# +# CONFIG_FSL_ESPI is not set +# CONFIG_TI_QSPI is not set +# CONFIG_DM_THERMAL is not set + +# +# TPM support +# + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_DM_USB is not set +# CONFIG_USB_XHCI_IPQ is not set + +# +# Graphics support +# +# CONFIG_VIDEO_VESA is not set +# CONFIG_VIDEO_LCD_ANX9804 is not set +# CONFIG_VIDEO_LCD_SSD2828 is not set +# CONFIG_DISPLAY_PORT is not set +# CONFIG_VIDEO_TEGRA124 is not set +# CONFIG_VIDEO_BRIDGE is not set +# CONFIG_PHYS_TO_BUS is not set + +# +# File systems +# + +# +# Library routines + +# +# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set +CONFIG_HAVE_PRIVATE_LIBGCC=y +# CONFIG_USE_PRIVATE_LIBGCC is not set +CONFIG_SYS_HZ=1000 +# CONFIG_SYS_VSNPRINTF is not set +CONFIG_REGEX=y +# CONFIG_LIB_RAND is not set +# CONFIG_CMD_DHRYSTONE is not set +# CONFIG_RSA is not set +# CONFIG_TPM is not set + +# +# Hashing Support +# +# CONFIG_SHA1 is not set +# CONFIG_SHA256 is not set +# CONFIG_SHA_HW_ACCEL is not set + +# +# Compression Support +# +# CONFIG_LZ4 is not set +CONFIG_LZMA=y +# CONFIG_ERRNO_STR is not set +# CONFIG_UNIT_TEST is not set + +# +# Thumb2 mode support +# +CONFIG_SYS_THUMB_BUILD=y +CONFIG_HAS_THUMB2=y + +# +# ART uncompression support +# +CONFIG_ART_COMPRESSED=y diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 64eb742ac9..0fea98de4c 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -27,6 +27,9 @@ 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 @@ -34,7 +37,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 diff --git a/drivers/mtd/nand/qpic_nand.c b/drivers/mtd/nand/qpic_nand.c index 4aaacd2852..c3d9410433 100644 --- a/drivers/mtd/nand/qpic_nand.c +++ b/drivers/mtd/nand/qpic_nand.c @@ -118,6 +118,30 @@ static struct qpic_serial_nand_params qpic_serial_nand_tbl[] = { struct qpic_serial_nand_params *serial_params; #define MICRON_DEVICE_ID 0x152c152c #define CMD3_MASK 0xfff0ffff +/* + * An array holding the fixed pattern to compare with + * training pattern. + */ +static const unsigned int training_block_64[] = { + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, +}; + +static const unsigned int training_block_128[] = { + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, + 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, +}; +#define TRAINING_PART_OFFSET 0x100000 +#define MAXIMUM_ALLOCATED_TRAINING_BLOCK 8 +#define TOTAL_NUM_PHASE 7 #endif struct cmd_element ce_array[100] @@ -1129,6 +1153,7 @@ int qpic_spi_nand_config(struct mtd_info *mtd) uint32_t status = 0x0; struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd); uint32_t cmd3_val = NAND_FLASH_DEV_CMD3_VAL; + /* For micron device the READ_CACHE_SEQ command is different than * Giga device. for Giga 0x31 and for Micron 0x30. * so based on id update the command configuration register @@ -1138,6 +1163,7 @@ int qpic_spi_nand_config(struct mtd_info *mtd) cmd3_val = (NAND_FLASH_DEV_CMD3_VAL & CMD3_MASK); writel(cmd3_val, SPI_NAND_DEV_CMD3); } + /* Get the block protection status*/ status = qpic_serial_get_feature(mtd, FLASH_SPI_NAND_BLK_PROCT_ADDR); if (status < 0) { @@ -1404,27 +1430,50 @@ static void qpic_spi_init(struct mtd_info *mtd) uint32_t xfer_start = NAND_XFR_STEPS_V1_5_20; int i; - /* Enabel QPIC CLK*/ - qpic_clk_enbale(); + unsigned int val; + int num_desc = 0; - /* Configure the NAND_FLASH_SPI_CFG to load the timer CLK_CNTR_INIT_VAL_VEC - * value, enable the LOAD_CLK_CNTR_INIT_EN bit and enable SPI_CFG mode. - */ - writel(0x0, NAND_FLASH_SPI_CFG); + struct cmd_element *cmd_list_ptr = ce_array; + struct cmd_element *cmd_list_ptr_start = ce_array; - /* Make bit-28 of NAND_FLASH_SPI_CFG register to load - * CLK_CNTR_INIT_VAL_VEC into IO Macro clock generation - * registers is its not worked then, - * check with this val 0x1DB6C00D + val = readl(NAND_QSPI_MSTR_CONFIG); + val |= FB_CLK_BIT; + + bam_add_cmd_element(cmd_list_ptr, NAND_QSPI_MSTR_CONFIG, (uint32_t)val, CE_WRITE_TYPE); + cmd_list_ptr++; + + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)0, CE_WRITE_TYPE); + cmd_list_ptr++; + + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)SPI_CFG_VAL, CE_WRITE_TYPE); + cmd_list_ptr++; + + val = SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN; + bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_SPI_CFG, (uint32_t)val, CE_WRITE_TYPE); + cmd_list_ptr++; + + bam_add_one_desc(&bam, + CMD_PIPE_INDEX, + (unsigned char*)cmd_list_ptr_start, + ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), + BAM_DESC_CMD_FLAG | BAM_DESC_LOCK_FLAG); + num_desc++; + + qpic_nand_wait_for_cmd_exec(num_desc); + + num_desc = 0; + + /* set the FB_CLK_BIT of register QPIC_QSPI_MSTR_CONFIG + * to by pass the serial training. if this FB_CLK_BIT + * bit enabled then , we can apply upto maximum 200MHz + * input to IO_MACRO_BLOCK. */ - writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG); - /*Change LOAD_CLK_CNTR_INIT_EN to generate a pulse, - * with CLK_CNTR_INIT_VAL_VEC loaded and SPI_CFG enabled - * If not worked then, - * Check with this val 0xDB6C00D - */ - writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN), - NAND_FLASH_SPI_CFG); + + qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, + GPLL0_CLK_SRC); + + /*qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, + XO_CLK_SRC);*/ /* According to HPG Setting Xfer steps and spi_num_addr_cycles * is part of initialization flow before reset.However these @@ -1463,9 +1512,26 @@ 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. */ - writel(SPI_NUM_ADDR_CYCLES, NAND_SPI_NUM_ADDR_CYCLES); + cmd_list_ptr = ce_array; + bam_add_cmd_element(cmd_list_ptr, NAND_SPI_NUM_ADDR_CYCLES, + (uint32_t)SPI_NUM_ADDR_CYCLES, CE_WRITE_TYPE); - writel(SPI_BUSY_CHECK_WAIT_CNT, NAND_SPI_BUSY_CHECK_WAIT_CNT); + cmd_list_ptr++; + + bam_add_cmd_element(cmd_list_ptr, NAND_SPI_BUSY_CHECK_WAIT_CNT, + (uint32_t)SPI_BUSY_CHECK_WAIT_CNT, CE_WRITE_TYPE); + + cmd_list_ptr++; + + bam_add_one_desc(&bam, + CMD_PIPE_INDEX, + (unsigned char*)cmd_list_ptr_start, + ((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start), + BAM_DESC_CMD_FLAG | BAM_DESC_LOCK_FLAG); + num_desc++; + qpic_nand_wait_for_cmd_exec(num_desc); + + num_desc = 0; } #endif static int qpic_nand_reset(struct mtd_info *mtd) @@ -3912,6 +3978,230 @@ qpic_nand_mtd_params(struct mtd_info *mtd) chip->scan_bbt = qpic_nand_scan_bbt_nop; } +#ifdef CONFIG_QSPI_SERIAL_TRAINING +static void qpic_set_phase(int phase) +{ + int spi_flash_cfg_val = 0x0; + + 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) | + (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 qpic_find_most_appropriate_phase(u8 *phase_table, int phase_count) +{ + int cnt; + 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. + */ + for (cnt = 0; cnt < phase_count; cnt++) { + if (!memcmp(phase_table+cnt, phase_ranges+cnt, 3)) { + phase = cnt+1; + break; + } + } + + phase = phase_table[phase]; + return phase; +} + +static int qpic_execute_serial_training(struct mtd_info *mtd) +{ + struct qpic_nand_dev *dev = MTD_QPIC_NAND_DEV(mtd); + struct nand_chip *chip = MTD_NAND_CHIP(mtd); + + unsigned int start, training_offset, blk_cnt = 0; + unsigned int offset, pageno, curr_freq; + int size = sizeof(training_block_64); + unsigned int io_macro_freq_tbl[] = {100000000, 200000000, 228000000, + 266000000, 320000000}; + + unsigned char *data_buff, trained_phase[TOTAL_NUM_PHASE]; + int phase, phase_cnt; + int training_seq_cnt = 3; + int index = 4, ret, phase_failed=0; + + training_offset = TRAINING_PART_OFFSET; + /* write pattern at lower frequency */ + start = (training_offset >> chip->phys_erase_shift); + offset = (start << chip->phys_erase_shift); + /* erase the all block */ + pageno = (offset >> chip->page_shift); + + /* At 50Mhz frequency check the bad blocks, if training + * blocks is not bad then only start training else operate + * at 50Mhz with bypassing software serial traning. + */ + while (qpic_nand_block_isbad(mtd, offset) != 0) { + /* block is bad skip this block and goto next + * block + */ + training_offset += mtd->erasesize; + start = (training_offset >> chip->phys_erase_shift); + offset = (start << chip->phys_erase_shift); + pageno = (offset >> chip->page_shift); + blk_cnt++; + } + + if (blk_cnt == MAXIMUM_ALLOCATED_TRAINING_BLOCK) { + printf("All training blocks are bad skipping serial training\n"); + ret = -EIO; + goto err; + } + + ret = qpic_nand_blk_erase(mtd, pageno); + if (ret) { + printf("error in erasing training block @%x\n",offset); + ret = -EIO; + goto err; + } + + data_buff = (unsigned char *)malloc(size); + if (!data_buff) { + printf("Errorn in allocating memory.\n"); + ret = -ENOMEM; + goto err; + } + memset(data_buff, 0, size); + memcpy(data_buff, training_block_64, size); + + /*write training data to flash */ + ret = NANDC_RESULT_SUCCESS; + struct mtd_oob_ops ops; + + /* write this dumy byte in spare area to avoid bam + * transaction error while writing. + */ + memset(dev->pad_oob, 0xFF, dev->oob_per_page); + + ops.mode = MTD_OPS_AUTO_OOB; + ops.len = size; + ops.retlen = 0; + ops.ooblen = dev->oob_per_page; + ops.oobretlen = 0; + ops.ooboffs = 0; + ops.datbuf = (uint8_t *)data_buff; + ops.oobbuf = (uint8_t *)dev->pad_oob; + + /* write should be only once */ + ret = qpic_nand_write_page(mtd, pageno, NAND_CFG, &ops); + if (ret) { + printf("Error in writing training data..\n"); + goto err; + } + /* After write verify the the data with read @ lower frequency + * after that only start serial tarining @ higher frequency + */ + memset(data_buff, 0, size); + 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; + } + + /* compare original data and read data */ + if (memcmp(data_buff, training_block_64, size)) { + printf("Training data read failed @ lower frequency\n"); + goto err; + } + + /* disable feed back clock bit to start serial training */ + writel((~FB_CLK_BIT & readl(NAND_QSPI_MSTR_CONFIG)), + NAND_QSPI_MSTR_CONFIG); + + /* start serial training here */ + curr_freq = io_macro_freq_tbl[index]; +rettry: + phase = 1; + phase_cnt = 0; + + /* set frequency, start from higer frequency */ + qpic_set_clk_rate(curr_freq, QPIC_IO_MACRO_CLK, GPLL0_CLK_SRC); + + do { + /* set the phase */ + qpic_set_phase(phase); + + memset(data_buff, 0, size); + 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; + } + /* compare original data and read data */ + if (memcmp(data_buff, training_block_64, size)) { + /* wrong data read on one of miso line + * change the phase value and try again + */ + continue; + phase_failed++; + } else { + /* we got good phase update the good phase list + */ + trained_phase[phase_cnt++] = phase; + /*printf("%s : Found good phase %d\n",__func__,phase);*/ + } + + } while (phase++ <= TOTAL_NUM_PHASE); + + if (phase_cnt) { + /* Get the appropriate phase */ + phase = qpic_find_most_appropriate_phase(trained_phase, phase_cnt); + qpic_set_phase(phase); + } else { + /* lower the the clock frequency + * and try again + */ + curr_freq = io_macro_freq_tbl[--index]; + if (--training_seq_cnt) + goto rettry; + + /* Training failed */ + printf("%s : Serial training failed\n",__func__); + ret = -EIO; + goto free; + } + + /* if phase_failed == 7 it means serial traing failed + * on all the phase. so now we have to go via line by line + * i.e first check for MISO_0, with all the phase value i.e + * 1-7 and then MISO_1 and so on. + * NOTE: But this is the worse case , and it this type of senario + * will not come. if it will come then go with this design. + * ======To DO===== + */ +free: + free(data_buff); +err: + return ret; +} +#endif + static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg) @@ -3968,26 +4258,9 @@ void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg) return; } -#ifdef CONFIG_QPIC_SERIAL - - qpic_spi_init(mtd); - - /* Read the Hardware Version register */ - hw_ver = readl(NAND_VERSION); - /* Only maintain major number */ - hw_ver >>= 28; - if (hw_ver >= QCA_QPIC_V2_1_1) { - printf("QPIC controller support serial NAND\n"); - } else { - printf("%s : Qpic controller not support serial NAND\n", - __func__); - return; - } - #ifdef CONFIG_PAGE_SCOPE_MULTI_PAGE_READ config.pipes.status_pipe = NAND_BAM_STATUS_PIPE; config.pipes.status_pipe_grp = NAND_BAM_STATUS_PIPE_GRP; -#endif #endif config.pipes.read_pipe = DATA_PRODUCER_PIPE; config.pipes.write_pipe = DATA_CONSUMER_PIPE; @@ -4004,6 +4277,21 @@ void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg) qpic_bam_init(&config); +#ifdef CONFIG_QPIC_SERIAL + qpic_spi_init(mtd); + + /* Read the Hardware Version register */ + hw_ver = readl(NAND_VERSION); + /* Only maintain major number */ + hw_ver >>= 28; + if (hw_ver >= QCA_QPIC_V2_1_1) { + printf("QPIC controller support serial NAND\n"); + } else { + printf("%s : Qpic controller not support serial NAND\n", + __func__); + return; + } +#endif ret = qpic_nand_reset(mtd); if (ret < 0) return; @@ -4100,6 +4388,24 @@ void qpic_nand_init(qpic_nand_cfg_t *qpic_nand_cfg) dev->tmp_oobbuf = buf; buf += mtd->oobsize; +#ifdef CONFIG_QSPI_SERIAL_TRAINING + /* start serial training here */ + ret = qpic_execute_serial_training(mtd); + if (ret) { + printf("Error in serial training.\n"); + printf("switch back to 50MHz with feed back clock bit enabled\n"); + writel((FB_CLK_BIT | readl(NAND_QSPI_MSTR_CONFIG)), + NAND_QSPI_MSTR_CONFIG); + + qpic_set_clk_rate(IO_MACRO_CLK_200_MHZ, QPIC_IO_MACRO_CLK, + GPLL0_CLK_SRC); + + writel(0x0, NAND_FLASH_SPI_CFG); + writel(SPI_CFG_VAL, NAND_FLASH_SPI_CFG); + writel((SPI_CFG_VAL & ~SPI_LOAD_CLK_CNTR_INIT_EN), + NAND_FLASH_SPI_CFG); + } +#endif /* Register with MTD subsystem. */ ret = nand_register(CONFIG_QPIC_NAND_NAND_INFO_IDX); if (ret < 0) { diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3270843d63..ee3de33e5b 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -87,7 +87,11 @@ obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_edma.o obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_ppe.o obj-$(CONFIG_IPQ6018_EDMA) += ipq6018/ipq6018_uniphy.o obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_gmac.o +obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/ipq5018_uniphy.o +obj-$(CONFIG_IPQ5018_MDIO) += ipq5018/ipq5018_mdio.o +obj-$(CONFIG_IPQ5018_GMAC) += ipq5018/athrs17_phy.o obj-$(CONFIG_IPQ_MDIO) += ipq_common/ipq_mdio.o +obj-$(CONFIG_GEPHY) += ipq_common/ipq_gephy.o obj-$(CONFIG_QCA8075_PHY) += ipq_common/ipq_qca8075.o obj-$(CONFIG_QCA8033_PHY) += ipq_common/ipq_qca8033.o obj-$(CONFIG_QCA8081_PHY) += ipq_common/ipq_qca8081.o diff --git a/drivers/net/ipq5018/athrs17_phy.c b/drivers/net/ipq5018/athrs17_phy.c new file mode 100644 index 0000000000..5fdca97dad --- /dev/null +++ b/drivers/net/ipq5018/athrs17_phy.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2015-2016, 2020 The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Manage the atheros ethernet PHY. + * + * All definitions in this file are operating system independent! + */ + +#include +#include + +/* + * Externel Common mdio read, PHY Name : IPQ MDIO1 + */ + +extern int ipq_mdio_write(int mii_id, + int regnum, u16 value); +extern int ipq_mdio_read(int mii_id, + int regnum, ushort *data); + +/****************************************************************************** + * FUNCTION DESCRIPTION: Read switch internal register. + * Switch internal register is accessed through the + * MDIO interface. MDIO access is only 16 bits wide so + * it needs the two time access to complete the internal + * register access. + * INPUT : register address + * OUTPUT : Register value + * + *****************************************************************************/ +static uint32_t +athrs17_reg_read(uint32_t reg_addr) +{ + uint32_t reg_word_addr; + uint32_t phy_addr, reg_val; + uint16_t phy_val; + uint16_t tmp_val; + uint8_t phy_reg; + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */ + ipq_mdio_write(phy_addr, phy_reg, phy_val); + /* + * For some registers such as MIBs, since it is read/clear, we should + * read the lower 16-bit register then the higher one + */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + ipq_mdio_read(phy_addr, phy_reg, &phy_val); + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + ipq_mdio_read(phy_addr, phy_reg, &tmp_val); + reg_val = (tmp_val << 16 | phy_val); + + return reg_val; +} + +/****************************************************************************** + * FUNCTION DESCRIPTION: Write switch internal register. + * Switch internal register is accessed through the + * MDIO interface. MDIO access is only 16 bits wide so + * it needs the two time access to complete the internal + * register access. + * INPUT : register address, value to be written + * OUTPUT : NONE + * + *****************************************************************************/ +static void +athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val) +{ + uint32_t reg_word_addr; + uint32_t phy_addr; + uint16_t phy_val; + uint8_t phy_reg; + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (uint16_t) ((reg_word_addr >> 8) & 0x1ff); /* bit16-8 of reg address */ + ipq_mdio_write(phy_addr, phy_reg, phy_val); + + /* + * For some registers such as ARL and VLAN, since they include BUSY bit + * in lower address, we should write the higher 16-bit register then the + * lower one + */ + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (uint16_t) ((reg_val >> 16) & 0xffff); + ipq_mdio_write(phy_addr, phy_reg, phy_val); + + /* write register in lower address */ + reg_word_addr--; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (uint16_t) (reg_val & 0xffff); + ipq_mdio_write(phy_addr, phy_reg, phy_val); +} + +/********************************************************************* + * FUNCTION DESCRIPTION: V-lan configuration given by Switch team + Vlan 1:PHY0,1,2,3 and Mac 6 of s17c + Vlan 2:PHY4 and Mac 0 of s17c + * INPUT : NONE + * OUTPUT: NONE + *********************************************************************/ +void athrs17_vlan_config(void) +{ + athrs17_reg_write(S17_P0LOOKUP_CTRL_REG, 0x00140020); + athrs17_reg_write(S17_P0VLAN_CTRL0_REG, 0x20001); + + athrs17_reg_write(S17_P1LOOKUP_CTRL_REG, 0x0014005c); + athrs17_reg_write(S17_P1VLAN_CTRL0_REG, 0x10001); + + athrs17_reg_write(S17_P2LOOKUP_CTRL_REG, 0x0014005a); + athrs17_reg_write(S17_P2VLAN_CTRL0_REG, 0x10001); + + athrs17_reg_write(S17_P3LOOKUP_CTRL_REG, 0x00140056); + athrs17_reg_write(S17_P3VLAN_CTRL0_REG, 0x10001); + + athrs17_reg_write(S17_P4LOOKUP_CTRL_REG, 0x0014004e); + athrs17_reg_write(S17_P4VLAN_CTRL0_REG, 0x10001); + + athrs17_reg_write(S17_P5LOOKUP_CTRL_REG, 0x00140001); + athrs17_reg_write(S17_P5VLAN_CTRL0_REG, 0x20001); + + athrs17_reg_write(S17_P6LOOKUP_CTRL_REG, 0x0014001e); + athrs17_reg_write(S17_P6VLAN_CTRL0_REG, 0x10001); + printf("%s ...done\n", __func__); +} + +/******************************************************************* +* FUNCTION DESCRIPTION: Reset S17 register +* INPUT: NONE +* OUTPUT: NONE +*******************************************************************/ +int athrs17_init_switch(void) +{ + uint32_t data; + uint32_t i = 0; + + /* Reset the switch before initialization */ + athrs17_reg_write(S17_MASK_CTRL_REG, S17_MASK_CTRL_SOFT_RET); + do { + udelay(10); + data = athrs17_reg_read(S17_MASK_CTRL_REG); + } while (data & S17_MASK_CTRL_SOFT_RET); + + do { + udelay(10); + data = athrs17_reg_read(S17_GLOBAL_INT0_REG); + i++; + if (i == 10) + return -1; + } while ((data & S17_GLOBAL_INITIALIZED_STATUS) != S17_GLOBAL_INITIALIZED_STATUS); + + return 0; +} + +/********************************************************************* + * FUNCTION DESCRIPTION: Configure S17 register + * INPUT : NONE + * OUTPUT: NONE + *********************************************************************/ +void athrs17_reg_init(ipq_gmac_board_cfg_t *gmac_cfg) +{ + uint32_t data; + + 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_GLOFW_CTRL1_REG, (S17_IGMP_JOIN_LEAVE_DPALL | + S17_BROAD_DPALL | + S17_MULTI_FLOOD_DPALL | + S17_UNI_FLOOD_DPALL)); + + athrs17_reg_write(S17_P5PAD_MODE_REG, S17_MAC0_RGMII_RXCLK_DELAY); + athrs17_reg_write(S17_P0PAD_MODE_REG, (S17_MAC0_RGMII_EN | \ + S17_MAC0_RGMII_TXCLK_DELAY | S17_MAC0_RGMII_RXCLK_DELAY | \ + (0x1 << S17_MAC0_RGMII_TXCLK_SHIFT) | \ + (0x3 << S17_MAC0_RGMII_RXCLK_SHIFT))); + + printf("%s: complete\n", __func__); +} + +/********************************************************************* + * FUNCTION DESCRIPTION: Configure S17 register + * INPUT : NONE + * OUTPUT: NONE + *********************************************************************/ +void athrs17_reg_init_lan(ipq_gmac_board_cfg_t *gmac_cfg) +{ + uint32_t reg_val; + + athrs17_reg_write(S17_P6STATUS_REG, (S17_SPEED_1000M | S17_TXMAC_EN | + S17_RXMAC_EN | + S17_DUPLEX_FULL)); + + reg_val = athrs17_reg_read(S17_MAC_PWR_REG) | gmac_cfg->mac_pwr1; + athrs17_reg_write(S17_MAC_PWR_REG, reg_val); + + 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_SGMII_CTRL_REG,(S17c_SGMII_EN_PLL | + S17c_SGMII_EN_RX | + S17c_SGMII_EN_TX | + S17c_SGMII_EN_SD | + S17c_SGMII_BW_HIGH | + S17c_SGMII_SEL_CLK125M | + S17c_SGMII_TXDR_CTRL_600mV | + S17c_SGMII_CDR_BW_8 | + S17c_SGMII_DIS_AUTO_LPI_25M | + S17c_SGMII_MODE_CTRL_SGMII_PHY | + S17c_SGMII_PAUSE_SG_TX_EN_25M | + S17c_SGMII_ASYM_PAUSE_25M | + S17c_SGMII_PAUSE_25M | + S17c_SGMII_HALF_DUPLEX_25M | + S17c_SGMII_FULL_DUPLEX_25M)); +} + +struct athrs17_regmap { + uint32_t start; + uint32_t end; +}; + +struct athrs17_regmap regmap[] = { + { 0x000, 0x0e0 }, + { 0x100, 0x168 }, + { 0x200, 0x270 }, + { 0x400, 0x454 }, + { 0x600, 0x718 }, + { 0x800, 0xb70 }, + { 0xC00, 0xC80 }, +}; + +int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + int i; + + for (i = 0; i < ARRAY_SIZE(regmap); i++) { + uint32_t reg; + struct athrs17_regmap *section = ®map[i]; + + for (reg = section->start; reg <= section->end; reg += sizeof(uint32_t)) { + uint32_t val = athrs17_reg_read(reg); + printf("%03zx: %08zx\n", reg, val); + } + } + + return 0; +}; +U_BOOT_CMD( + ar8xxx_dump, 1, 1, do_ar8xxx_dump, + "Dump ar8xxx registers", + "\n - print all ar8xxx registers\n" +); + +/********************************************************************* + * + * FUNCTION DESCRIPTION: This function invokes RGMII, + * SGMII switch init routines. + * INPUT : ipq_gmac_board_cfg_t * + * OUTPUT: NONE + * +**********************************************************************/ +int ipq_athrs17_init(ipq_gmac_board_cfg_t *gmac_cfg) +{ + int ret; + + if (gmac_cfg == NULL) + return -1; + + ret = athrs17_init_switch(); + if (ret != -1) { + athrs17_reg_init(gmac_cfg); + athrs17_reg_init_lan(gmac_cfg); + athrs17_vlan_config(); + printf ("S17c init done\n"); + } + + return ret; +} diff --git a/drivers/net/ipq5018/ipq5018_gmac.c b/drivers/net/ipq5018/ipq5018_gmac.c index 0c4ef71fc2..0dacbe7153 100644 --- a/drivers/net/ipq5018/ipq5018_gmac.c +++ b/drivers/net/ipq5018/ipq5018_gmac.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2019 The Linux Foundation. All rights reserved. +* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,9 +18,7 @@ #include #include #include -#include #include -#include #include "ipq_phy.h" #include @@ -39,10 +37,14 @@ 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 ipq5018_mdio_read(int mii_id, int regnum, ushort *data); extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id); -extern void ipq_qca8075_phy_map_ops(struct phy_ops **ops); extern int ipq_qca8081_phy_init(struct phy_ops **ops, u32 phy_id); +extern int ipq_gephy_phy_init(struct phy_ops **ops, u32 phy_id); extern int ipq_sw_mdio_init(const char *); +extern int ipq5018_sw_mdio_init(const char *); +extern void ppe_uniphy_mode_set(uint32_t mode); +extern int ipq_athrs17_init(ipq_gmac_board_cfg_t *gmac_cfg); static int ipq_eth_wr_macaddr(struct eth_device *dev) { @@ -238,69 +240,136 @@ static inline u32 ipq_gmac_is_desc_empty(ipq_gmac_desc_t *fr) { return ((fr->length & DescSize1Mask) == 0); } -#if 0 -static int ipq_eth_update(struct eth_device *dev, bd_t *this) +static void ipq5018_gmac0_speed_clock_set(int speed_clock1, + int speed_clock2, int gmacid) +{ + int iTxRx; + uint32_t reg_value; + /* + * iTxRx indicates Tx and RX register + * 0 = Rx and 1 = Tx + */ + for (iTxRx = 0; iTxRx < 2; ++iTxRx){ + /* gcc port first clock divider */ + reg_value = 0; + reg_value = readl(GCC_GMAC0_RX_CFG_RCGR + + (iTxRx * 8) + (gmacid * 0x10)); + reg_value &= ~0x71f; + reg_value |= speed_clock1; + writel(reg_value, GCC_GMAC0_RX_CFG_RCGR + + (iTxRx * 8) + (gmacid * 0x10)); + /* gcc port second clock divider */ + reg_value = 0; + reg_value = readl(GCC_GMAC0_RX_MISC + + (iTxRx * 4) + (gmacid * 0x10)); + reg_value &= ~0xf; + reg_value |= speed_clock2; + writel(reg_value, GCC_GMAC0_RX_MISC + + (iTxRx * 4) + (gmacid * 0x10)); + /* update above clock configuration */ + reg_value = 0; + reg_value = readl(GCC_GMAC0_RX_CMD_RCGR + + (iTxRx * 8) + (gmacid * 0x10)); + reg_value &= ~0x1; + reg_value |= 0x1; + writel(reg_value, GCC_GMAC0_RX_CMD_RCGR + + (iTxRx * 8) + (gmacid * 0x10)); + } +} + +static int ipq5018_phy_link_update(struct eth_device *dev) { struct ipq_eth_dev *priv = dev->priv; - struct phy_ops *phy_get_ops = priv->ops[priv->mac_unit]; - uint phy_status; - uint cur_speed; - uint cur_duplex; - - phy_status = phy_get_ops->phy_get_link_status(priv->mac_unit, priv->phy_address); - phy_get_ops->phy_get_speed(priv->mac_unit, priv->phy_address, &curr_speed); - phy_get_ops->phy_get_duplex(priv->mac_unit, priv->phy_address, &duplex); - - if (cur_speed != priv->speed || cur_duplex != priv->duplex) { - ipq_info("Link %x status changed\n", priv->mac_unit); - if (priv->duplex) - ipq_info("Full duplex link\n"); - else - ipq_info("Half duplex link\n"); - - ipq_info("Link %x up, Phy_status = %x\n", - priv->mac_unit, phy_status); - - switch (cur_speed) { - case SPEED_1000M: - ipq_info("Port:%d speed 1000Mbps\n", - priv->mac_unit); - priv->mac_ps = GMII_PORT_SELECT; - break; - - case SPEED_100M: - ipq_info("Port:%d speed 100Mbps\n", - priv->mac_unit); - priv->mac_ps = MII_PORT_SELECT; - break; - - case SPEED_10M: - ipq_info("Port:%d speed 10Mbps\n", - priv->mac_unit); - priv->mac_ps = MII_PORT_SELECT; - break; - - default: - ipq_info("Port speed unknown\n"); - return -1; - } - - priv->speed = cur_speed; - priv->duplex = cur_duplex; + u8 status; + struct phy_ops *phy_get_ops; + fal_port_speed_t speed; + fal_port_duplex_t duplex; + char *lstatus[] = {"up", "Down"}; + char *dp[] = {"Half", "Full"}; + int speed_clock1 = 0, speed_clock2 = 0; + 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; } + } + + if (priv->ipq_swith) { + speed_clock1 = 0x1; + speed_clock2 = 0; + } else { + status = phy_get_ops->phy_get_link_status(priv->mac_unit, + priv->phy_address); + phy_get_ops->phy_get_speed(priv->mac_unit, + priv->phy_address, &speed); + phy_get_ops->phy_get_duplex(priv->mac_unit, + priv->phy_address, &duplex); + + switch (speed) { + case FAL_SPEED_10: + speed_clock1 = 0x9; + speed_clock2 = 0x9; + printf ("eth%d %s Speed :%d %s duplex\n", + priv->mac_unit, lstatus[status], speed, + dp[duplex]); + break; + case FAL_SPEED_100: + speed_clock1 = 0x9; + 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: + speed_clock1 = 0x1; + 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: + speed_clock1 = 0x1; + 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 (priv->mac_unit){ + if (priv->phy_type == QCA8081_PHY_TYPE) + ppe_uniphy_mode_set(PORT_WRAPPER_SGMII_PLUS); + else + ppe_uniphy_mode_set(PORT_WRAPPER_SGMII_FIBER); + } + + ipq5018_gmac0_speed_clock_set(speed_clock1, speed_clock2, priv->mac_unit); + + if (status) { + /* No PHY link is alive */ + return -1; + } return 0; } -#endif + int ipq_eth_init(struct eth_device *dev, bd_t *this) { struct ipq_eth_dev *priv = dev->priv; struct eth_dma_regs *dma_reg = (struct eth_dma_regs *)priv->dma_regs_p; u32 data; -#if 0 - ipq_phy_link_status(dev); -#endif + + if(ipq5018_phy_link_update(dev) < 0); + priv->next_rx = 0; priv->next_tx = 0; @@ -455,8 +524,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) { struct eth_device *dev[CONFIG_IPQ_NO_MACS]; uchar enet_addr[CONFIG_IPQ_NO_MACS * 6]; - char ethaddr[32] = "ethaddr"; - int i, phy_id; + int i; uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2; int ret; memset(enet_addr, 0, sizeof(enet_addr)); @@ -468,11 +536,11 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) dev[i] = malloc(sizeof(struct eth_device)); if (dev[i] == NULL) - goto failed; + goto init_failed; ipq_gmac_macs[i] = malloc(sizeof(struct ipq_eth_dev)); if (ipq_gmac_macs[i] == NULL) - goto failed; + goto init_failed; memset(dev[i], 0, sizeof(struct eth_device)); memset(ipq_gmac_macs[i], 0, sizeof(struct ipq_eth_dev)); @@ -484,12 +552,9 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) dev[i]->send = ipq_eth_send; dev[i]->write_hwaddr = ipq_eth_wr_macaddr; dev[i]->priv = (void *) ipq_gmac_macs[i]; - - snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", i); - /* - * Setting the Default MAC address if the MAC read from ART partition - * is invalid. + * Setting the Default MAC address + * if the MAC read from ART partition is invalid */ if ((ret < 0) || (!is_valid_ethaddr(&enet_addr[i * 6]))) { @@ -507,7 +572,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) dev[i]->enetaddr[4], dev[i]->enetaddr[5]); - snprintf(ethaddr, sizeof(ethaddr), "eth%daddr", (i + 1)); + snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", i); ipq_gmac_macs[i]->dev = dev[i]; ipq_gmac_macs[i]->mac_unit = gmac_cfg->unit; @@ -515,82 +580,89 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg) (struct eth_mac_regs *)(gmac_cfg->base); ipq_gmac_macs[i]->dma_regs_p = (struct eth_dma_regs *)(gmac_cfg->base + DW_DMA_BASE_OFFSET); -#if 0 - ipq_gmac_macs[i]->interface = gmac_cfg->phy; - ipq_gmac_macs[i]->phy_address = gmac_cfg->phy_addr.addr; - ipq_gmac_macs[i]->no_of_phys = gmac_cfg->phy_addr.count; -#endif ipq_gmac_macs[i]->phy_address = gmac_cfg->phy_addr; ipq_gmac_macs[i]->gmac_board_cfg = gmac_cfg; + ipq_gmac_macs[i]->interface = gmac_cfg->phy_interface_mode; + ipq_gmac_macs[i]->phy_type = gmac_cfg->phy_type; + ipq_gmac_macs[i]->ipq_swith = gmac_cfg->ipq_swith; -#if 0 - if (get_params.gmac_port == gmac_cfg->unit) { - ipq_gmac_macs[i]->forced_params = &get_params; - } -#endif - /* tx/rx Descriptor initialization */ - if (ipq_gmac_tx_rx_desc_ring(dev[i]->priv) == -1) - goto failed; -#if 0 - if(ipq_gmac_macs[i]->mac_unit == 0) - ipq_gmac_macs[i]->speed = SPEED_10M; - else - ipq_gmac_macs[i]->speed = SPEED_1000M; -#endif + strlcpy((char *)ipq_gmac_macs[i]->phy_name, + gmac_cfg->phy_name, + sizeof(ipq_gmac_macs[i]->phy_name)); - strlcpy((char *)ipq_gmac_macs[i]->phy_name, gmac_cfg->phy_name, - sizeof(ipq_gmac_macs[i]->phy_name)); + phy_chip_id = -1; -if (0){ - if (ipq_sw_mdio_init(gmac_cfg->phy_name)) - goto failed; - - for (phy_id = 0; phy_id < 2; phy_id++) { -#if 0 - if (phy_node >= 0) { - phy_addr = phy_info[phy_id]->phy_address; + if (gmac_cfg->unit){ + ret = ipq_sw_mdio_init(gmac_cfg->phy_name); + 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"); } else { - if (phy_id == port_8033) - phy_addr = QCA8033_PHY_ADDR; - else if (phy_id == aquantia_port) - phy_addr = AQU_PHY_ADDR; - else - phy_addr = phy_id; + 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; } -#endif - 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); + } else { + ret = ipq5018_sw_mdio_init(gmac_cfg->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_id = (phy_chip_id1 << 16) | phy_chip_id2; - - switch(phy_chip_id) { - case QCA8033_PHY: - ipq_qca8033_phy_init( - &ipq_gmac_macs[i]->ops[phy_id], - ipq_gmac_macs[i]->phy_address); - break; - case QCA8081_PHY: - case QCA8081_1_1_PHY: - ipq_qca8081_phy_init( - &ipq_gmac_macs[i]->ops[phy_id], - ipq_gmac_macs[i]->phy_address); - break; - default: - ipq_qca8075_phy_map_ops(&ipq_gmac_macs[i]->ops[phy_id]); - break; - } } -} - eth_register(dev[i]); + + switch(phy_chip_id) { + /* + * NAPA PHY For GMAC1 + */ + case QCA8081_PHY: + case QCA8081_1_1_PHY: + ipq_qca8081_phy_init( + &ipq_gmac_macs[i]->ops, + ipq_gmac_macs[i]->phy_address); + break; + /* + * Internel GEPHY only for GMAC0 + */ + case GEPHY: + ipq_gephy_phy_init( + &ipq_gmac_macs[i]->ops, + ipq_gmac_macs[i]->phy_address); + break; + /* + * 1G PHY + */ + case QCA8033_PHY: + ipq_qca8033_phy_init( + &ipq_gmac_macs[i]->ops, + ipq_gmac_macs[i]->phy_address); + break; + default: + printf("GMAC%d : Invalid PHY ID \n", i); + break; + } + /* + * Tx/Rx Descriptor initialization + */ + if (ipq_gmac_tx_rx_desc_ring(dev[i]->priv) == -1) + goto init_failed; + + eth_register(dev[i]); } return 0; -failed: +init_failed: for (i = 0; i < IPQ5018_GMAC_PORT; i++) { if (dev[i]) { - eth_unregister(dev[i]); free(dev[i]); } if (ipq_gmac_macs[i]) diff --git a/drivers/net/ipq5018/ipq5018_mdio.c b/drivers/net/ipq5018/ipq5018_mdio.c new file mode 100644 index 0000000000..8f4bf24db7 --- /dev/null +++ b/drivers/net/ipq5018/ipq5018_mdio.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include +#include +#include +#include +#include +#include +#include "ipq5018_mdio.h" + +struct ipq5018_mdio_data { + struct mii_bus *bus; + int phy_irq[PHY_MAX_ADDR]; +}; + +static int ipq5018_mdio_wait_busy(void) +{ + int i; + u32 busy; + for (i = 0; i < IPQ5018_MDIO_RETRY; i++) { + udelay(IPQ5018_MDIO_DELAY); + busy = readl(IPQ5018_MDIO_BASE + + MDIO_CTRL_4_REG) & + MDIO_CTRL_4_ACCESS_BUSY; + + if (!busy) + return 0; + udelay(IPQ5018_MDIO_DELAY); + } + printf("%s: MDIO operation timed out\n", + __func__); + return -ETIMEDOUT; +} + +int ipq5018_mdio_write(int mii_id, int regnum, u16 value) +{ + u32 cmd; + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + + + if (regnum & MII_ADDR_C45) { + unsigned int mmd = (regnum >> 16) & 0x1F; + unsigned int reg = regnum & 0xFFFF; + + writel(CTRL_0_REG_C45_DEFAULT_VALUE, + IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG); + + /* Issue the phy address and reg */ + writel((mii_id << 8) | mmd, + IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG); + + writel(reg, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG); + + /* issue read command */ + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR; + + writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG); + + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + } else { + writel(CTRL_0_REG_DEFAULT_VALUE, + IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG); + + /* Issue the phy addreass and reg */ + writel((mii_id << 8 | regnum), + IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG); + } + + /* Issue a write data */ + writel(value, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG); + + if (regnum & MII_ADDR_C45) { + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_WRITE ; + } else { + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_WRITE ; + } + + writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG); + /* Wait for write complete */ + + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + + return 0; +} + +int ipq5018_mdio_read(int mii_id, int regnum, ushort *data) +{ + u32 val,cmd; + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + + if (regnum & MII_ADDR_C45) { + + unsigned int mmd = (regnum >> 16) & 0x1F; + unsigned int reg = regnum & 0xFFFF; + + writel(CTRL_0_REG_C45_DEFAULT_VALUE, + IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG); + + /* Issue the phy address and reg */ + writel((mii_id << 8) | mmd, + IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG); + + + writel(reg, IPQ5018_MDIO_BASE + MDIO_CTRL_2_REG); + + /* issue read command */ + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_ADDR; + } else { + + writel(CTRL_0_REG_DEFAULT_VALUE, + IPQ5018_MDIO_BASE + MDIO_CTRL_0_REG); + + /* Issue the phy address and reg */ + writel((mii_id << 8 | regnum ) , + IPQ5018_MDIO_BASE + MDIO_CTRL_1_REG); + + /* issue read command */ + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_READ ; + } + + /* issue read command */ + writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG); + + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + + + if (regnum & MII_ADDR_C45) { + cmd = MDIO_CTRL_4_ACCESS_START | MDIO_CTRL_4_ACCESS_CODE_C45_READ; + writel(cmd, IPQ5018_MDIO_BASE + MDIO_CTRL_4_REG); + + if (ipq5018_mdio_wait_busy()) + return -ETIMEDOUT; + } + + /* Read data */ + val = readl(IPQ5018_MDIO_BASE + MDIO_CTRL_3_REG); + + if (data != NULL) + *data = val; + + return val; +} + +int ipq5018_phy_write(struct mii_dev *bus, + int addr, int dev_addr, + int regnum, ushort value) +{ + return ipq5018_mdio_write(addr, regnum, value); +} + +int ipq5018_phy_read(struct mii_dev *bus, + int addr, int dev_addr, int regnum) +{ + return ipq5018_mdio_read(addr, regnum, NULL); +} + +int ipq5018_sw_mdio_init(const char *name) +{ + struct mii_dev *bus = mdio_alloc(); + if(!bus) { + printf("Failed to allocate IPQ5018 MDIO bus\n"); + return -1; + } + bus->read = ipq5018_phy_read; + bus->write = ipq5018_phy_write; + bus->reset = NULL; + snprintf(bus->name, MDIO_NAME_LEN, name); + return mdio_register(bus); +} + +static int do_ipq5018_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char op[2]; + unsigned int addr = 0, reg = 0; + unsigned short data = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + op[0] = argv[1][0]; + if (strlen(argv[1]) > 1) + op[1] = argv[1][1]; + else + op[1] = '\0'; + + if (argc >= 3) + addr = simple_strtoul(argv[2], NULL, 16); + if (argc >= 4) + reg = simple_strtoul(argv[3], NULL, 16); + if (argc >= 5) + data = simple_strtoul(argv[4], NULL, 16); + + if (op[0] == 'r') { + data = ipq5018_mdio_read(addr, reg, NULL); + printf("0x%x\n", data); + } else if (op[0] == 'w') { + ipq5018_mdio_write(addr, reg, data); + } else { + return CMD_RET_USAGE; + } + + return 0; +} + +U_BOOT_CMD( + ipq5018_mdio, 5, 1, do_ipq5018_mdio, + "IPQ5018 mdio utility commands", + "ipq5018_mdio read - read IPQ5018 MDIO PHY register \n" + "ipq5018_mdio write - write IPQ5018 MDIO PHY register \n" + "Addr and/or reg may be ranges, e.g. 0-7." +); diff --git a/drivers/net/ipq5018/ipq5018_mdio.h b/drivers/net/ipq5018/ipq5018_mdio.h new file mode 100644 index 0000000000..857dfe1622 --- /dev/null +++ b/drivers/net/ipq5018/ipq5018_mdio.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015-2017, 2020 The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ +#ifndef _IPQ5018_MDIO_H +#define _IPQ5018_MDIO_H + +#define IPQ5018_MDIO_BASE 0x88000 +#define MDIO_CTRL_0_REG 0x40 +#define MDIO_CTRL_1_REG 0x44 +#define MDIO_CTRL_2_REG 0x48 +#define MDIO_CTRL_3_REG 0x4c +#define MDIO_CTRL_4_REG 0x50 +#define MDIO_CTRL_4_ACCESS_BUSY (1 << 16) +#define MDIO_CTRL_4_ACCESS_START (1 << 8) +#define MDIO_CTRL_4_ACCESS_CODE_READ 0 +#define MDIO_CTRL_4_ACCESS_CODE_WRITE 1 +#define MDIO_CTRL_4_ACCESS_CODE_C45_ADDR 0 +#define MDIO_CTRL_4_ACCESS_CODE_C45_WRITE 1 +#define MDIO_CTRL_4_ACCESS_CODE_C45_READ 2 +#define CTRL_0_REG_DEFAULT_VALUE 0x1500F +#ifdef MDIO_12_5_MHZ +#define CTRL_0_REG_C45_DEFAULT_VALUE 0x15107 +#else +#define CTRL_0_REG_C45_DEFAULT_VALUE 0x1510F +#endif +#define IPQ5018_MDIO_RETRY 1000 +#define IPQ5018_MDIO_DELAY 5 +#endif /* End _IPQ5018_MDIO_H */ diff --git a/drivers/net/ipq5018/ipq5018_uniphy.c b/drivers/net/ipq5018/ipq5018_uniphy.c new file mode 100644 index 0000000000..616ff31590 --- /dev/null +++ b/drivers/net/ipq5018/ipq5018_uniphy.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipq5018_uniphy.h" +#include "ipq_phy.h" + +static int ppe_uniphy_calibration(void) +{ + int retries = 100, calibration_done = 0; + uint32_t reg_value = 0; + + while(calibration_done != UNIPHY_CALIBRATION_DONE) { + mdelay(1); + if (retries-- == 0) { + printf("uniphy callibration time out!\n"); + return -1; + } + reg_value = readl(PPE_UNIPHY_BASE + PPE_UNIPHY_OFFSET_CALIB_4); + calibration_done = (reg_value >> 0x7) & 0x1; + } + + return 0; +} + +static void ppe_gcc_uniphy_soft_reset(void) +{ + uint32_t reg_value; + + reg_value = readl(GCC_UNIPHY0_MISC); + + reg_value |= GCC_UNIPHY_SGMII_SOFT_RESET; + + writel(reg_value, GCC_UNIPHY0_MISC); + + udelay(500); + + reg_value &= ~GCC_UNIPHY_SGMII_SOFT_RESET; + + writel(reg_value, GCC_UNIPHY0_MISC); +} + +static void ppe_uniphy_sgmii_mode_set(uint32_t mode) +{ + 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); + writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE + + UNIPHY_PLL_RESET_REG_OFFSET); + mdelay(500); + + writel(0x0, GCC_UNIPHY_RX_CBCR); + writel(0x0, GCC_UNIPHY_TX_CBCR); + writel(0x0, GCC_GMAC1_RX_CBCR); + writel(0x0, GCC_GMAC1_TX_CBCR); + + switch (mode) { + case PORT_WRAPPER_SGMII_FIBER: + writel(UNIPHY_SG_MODE, PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL); + break; + + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII4_RGMII4: + writel((UNIPHY_SG_MODE | UNIPHY_PSGMII_MAC_MODE), + PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL); + break; + + case PORT_WRAPPER_SGMII_PLUS: + writel((UNIPHY_SG_PLUS_MODE | UNIPHY_PSGMII_MAC_MODE), + PPE_UNIPHY_BASE + PPE_UNIPHY_MODE_CONTROL); + break; + + default: + printf("SGMII Config. wrongly"); + break; + } + + ppe_gcc_uniphy_soft_reset(); + + writel(0x1, GCC_UNIPHY_RX_CBCR); + writel(0x1, GCC_UNIPHY_TX_CBCR); + writel(0x1, GCC_GMAC1_RX_CBCR); + writel(0x1, GCC_GMAC1_TX_CBCR); + + ppe_uniphy_calibration(); +} + +void ppe_uniphy_mode_set(uint32_t mode) +{ + /* + * SGMII and SHMII plus confugure in same function + */ + ppe_uniphy_sgmii_mode_set(mode); +} + diff --git a/drivers/net/ipq5018/ipq5018_uniphy.h b/drivers/net/ipq5018/ipq5018_uniphy.h new file mode 100644 index 0000000000..de1f599adf --- /dev/null +++ b/drivers/net/ipq5018/ipq5018_uniphy.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _IPQ5018_UNIPHY_H_ +#define _IPQ5018_UNIPHY_H + +#define PPE_UNIPHY_INSTANCE0 0 + +#define GCC_UNIPHY_RX_CBCR 0x01856110 +#define GCC_UNIPHY_TX_CBCR 0x01856114 + +#define GCC_GMAC1_RX_CBCR 0x01868248 +#define GCC_GMAC1_TX_CBCR 0x0186824C + +#define GCC_UNIPHY0_MISC 0x01856004 + +#define PPE_UNIPHY_OFFSET_CALIB_4 0x1E0 +#define UNIPHY_CALIBRATION_DONE 0x1 + +#define GCC_UNIPHY_PSGMII_SOFT_RESET 0x3ff2 +#define GCC_UNIPHY_SGMII_SOFT_RESET 0x32 + +#define PPE_UNIPHY_BASE 0x00098000 +#define PPE_UNIPHY_MODE_CONTROL 0x46C +#define UNIPHY_XPCS_MODE (1 << 12) +#define UNIPHY_SG_PLUS_MODE (1 << 11) +#define UNIPHY_SG_MODE (1 << 10) +#define UNIPHY_CH0_PSGMII_QSGMII (1 << 9) +#define UNIPHY_CH0_QSGMII_SGMII (1 << 8) +#define UNIPHY_PSGMII_MAC_MODE (1 << 5) +#define UNIPHY_CH4_CH1_0_SGMII (1 << 2) +#define UNIPHY_CH1_CH0_SGMII (1 << 1) +#define UNIPHY_CH0_ATHR_CSCO_MODE_25M (1 << 0) + +#define UNIPHY_INSTANCE_LINK_DETECT 0x570 + +#define UNIPHY_MISC2_REG_OFFSET 0x218 +#define UNIPHY_MISC2_REG_SGMII_MODE 0x30 +#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50 + +#define UNIPHY_MISC2_REG_VALUE 0x70 + +#define UNIPHY_PLL_RESET_REG_OFFSET 0x780 +#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf +#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff + +void ppe_uniphy_mode_set(uint32_t mode); +#endif diff --git a/drivers/net/ipq_common/ipq_gephy.c b/drivers/net/ipq_common/ipq_gephy.c new file mode 100644 index 0000000000..90b1c130fe --- /dev/null +++ b/drivers/net/ipq_common/ipq_gephy.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ +#include +#include +#include +#include +#include +#include +#include "ipq_gephy.h" +#include "ipq_phy.h" + +extern int ipq5018_mdio_read(int mii_id, + int regnum, ushort *data); +extern int ipq5018_mdio_write(int mii_id, + int regnum, u16 data); + +u16 gephy_phy_reg_read(u32 dev_id, u32 phy_id, u32 reg_id) +{ + return ipq5018_mdio_read(phy_id, reg_id, NULL); +} + +u16 gephy_phy_reg_write(u32 dev_id, u32 phy_id, u32 reg_id, u16 value) +{ + return ipq5018_mdio_write(phy_id, reg_id, value); +} + +u8 gephy_phy_get_link_status(u32 dev_id, u32 phy_id) +{ + u16 phy_data; + phy_data = gephy_phy_reg_read(dev_id, + phy_id, GEPHY_PHY_SPEC_STATUS); + if (phy_data & GEPHY_STATUS_LINK_PASS) + return 0; + + return 1; +} + +u32 gephy_phy_get_duplex(u32 dev_id, u32 phy_id, fal_port_duplex_t *duplex) +{ + u16 phy_data; + + phy_data = gephy_phy_reg_read(dev_id, phy_id, + GEPHY_PHY_SPEC_STATUS); + + /* + * Read duplex + */ + if (phy_data & GEPHY_STATUS_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + + return 0; +} + +u32 gephy_phy_get_speed(u32 dev_id, u32 phy_id, fal_port_speed_t *speed) +{ + u16 phy_data; + + phy_data = gephy_phy_reg_read(dev_id, + phy_id, GEPHY_PHY_SPEC_STATUS); + + switch (phy_data & GEPHY_STATUS_SPEED_MASK) { + case GEPHY_STATUS_SPEED_2500MBS: + *speed = FAL_SPEED_2500; + break; + case GEPHY_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case GEPHY_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case GEPHY_STATUS_SPEED_10MBS: + *speed = FAL_SPEED_10; + break; + default: + return -EINVAL; + } + return 0; +} + +int ipq_gephy_phy_init(struct phy_ops **ops, u32 phy_id) +{ + u16 phy_data; + struct phy_ops *gephy_ops; + + gephy_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops)); + if (!gephy_ops) + return -ENOMEM; + gephy_ops->phy_get_link_status = gephy_phy_get_link_status; + gephy_ops->phy_get_speed = gephy_phy_get_speed; + gephy_ops->phy_get_duplex = gephy_phy_get_duplex; + *ops = gephy_ops; + + phy_data = gephy_phy_reg_read(0x0, phy_id, GEPHY_PHY_ID1); + printf ("PHY ID1: 0x%x\n", phy_data); + phy_data = gephy_phy_reg_read(0x0, phy_id, GEPHY_PHY_ID2); + printf ("PHY ID2: 0x%x\n", phy_data); + + /*enable vga when init napa to fix 8023az issue*/ + phy_data = gephy_phy_reg_read(0x0, phy_id, QCA808X_8023AZ_ENABLE_VGA); + phy_data &= (~QCA808X_PHY_8023AZ_AFE_CTRL_MASK); + phy_data |= QCA808X_PHY_8023AZ_AFE_EN; + phy_data = gephy_phy_reg_write(0x0, phy_id, QCA808X_8023AZ_ENABLE_VGA, phy_data); + if (phy_data != 0) + return phy_data; + + /*special configuration for AZ under 1G speed mode*/ + phy_data = QCA808X_PHY_MMD3_AZ_TRAINING_VAL; + phy_data = gephy_phy_reg_write(0x0, phy_id, QCA808X_AZ_CONFIG_UNDER_1G_SPEED, + phy_data); + return phy_data; +} diff --git a/drivers/net/ipq_common/ipq_gephy.h b/drivers/net/ipq_common/ipq_gephy.h new file mode 100644 index 0000000000..1491bfd4c4 --- /dev/null +++ b/drivers/net/ipq_common/ipq_gephy.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#ifndef _IPQ_GEPHY_H_ +#define _IPQ_GEPHY_H_ + +/* PHY Registers */ +#define GEPHY_PHY_CONTROL 0 +#define GEPHY_PHY_STATUS 1 +#define GEPHY_PHY_SPEC_STATUS 17 + +#define GEPHY_PHY_ID1 2 +#define GEPHY_PHY_ID2 3 +#define GEPHY_AUTONEG_ADVERT 4 +#define GEPHY_LINK_PARTNER_ABILITY 5 +#define GEPHY_1000BASET_CONTROL 9 +#define GEPHY_1000BASET_STATUS 10 +#define GEPHY_MMD_CTRL_REG 13 +#define GEPHY_MMD_DATA_REG 14 +#define GEPHY_EXTENDED_STATUS 15 +#define GEPHY_PHY_SPEC_CONTROL 16 +#define GEPHY_PHY_INTR_MASK 18 +#define GEPHY_PHY_INTR_STATUS 19 +#define GEPHY_PHY_CDT_CONTROL 22 +#define GEPHY_DEBUG_PORT_ADDRESS 29 +#define GEPHY_DEBUG_PORT_DATA 30 + +#define GEPHY_STATUS_LINK_PASS 0x0400 + +#define GEPHY_STATUS_FULL_DUPLEX 0x2000 + +#define GEPHY_STATUS_SPEED_MASK 0x380 +#define GEPHY_STATUS_SPEED_2500MBS 0x200 +#define GEPHY_STATUS_SPEED_1000MBS 0x100 +#define GEPHY_STATUS_SPEED_100MBS 0x80 +#define GEPHY_STATUS_SPEED_10MBS 0x0000 + +#define QCA808X_PHY_MMD3_AZ_TRAINING_VAL 0x1c32 +#define QCA808X_PHY_MMD3_NUM 3 +#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 +#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 +#define QCA808X_PHY_8023AZ_AFE_CTRL_MASK 0x01f0 +#define QCA808X_PHY_8023AZ_AFE_EN 0x0090 +#define QCA808X_MII_ADDR_C45 (1<<30) +#define QCA808X_REG_C45_ADDRESS(dev_type, reg_num) (QCA808X_MII_ADDR_C45 | \ + ((dev_type & 0x1f) << 16) | (reg_num & 0xffff)) +#define QCA808X_8023AZ_ENABLE_VGA QCA808X_REG_C45_ADDRESS(QCA808X_PHY_MMD3_NUM, \ + QCA808X_PHY_MMD3_ADDR_CLD_CTRL7) +#define QCA808X_AZ_CONFIG_UNDER_1G_SPEED QCA808X_REG_C45_ADDRESS(QCA808X_PHY_MMD3_NUM, \ + QCA808X_PHY_MMD3_AZ_TRAINING_CTRL) + +#endif /* _GEPHY_PHY_H_ */ diff --git a/drivers/pci/pci_ipq.c b/drivers/pci/pci_ipq.c index b57fba31f5..f9f8ba2bcc 100644 --- a/drivers/pci/pci_ipq.c +++ b/drivers/pci/pci_ipq.c @@ -625,6 +625,7 @@ struct ipq_pcie { int is_gen3; int linkup; int version; + int skip_phy_init; }; static void ipq_pcie_write_mask(uint32_t addr, @@ -1130,11 +1131,13 @@ static int ipq_pcie_parse_dt(const void *fdt, int id, if (err < 0) goto err; pcie->is_gen3 = 1; - } + } } else { goto err; } } + pcie->skip_phy_init = + fdtdec_get_int(fdt, node, "skip_phy_int", 0); } rst_gpio = fdtdec_get_int(fdt, node, "perst_gpio", 0); if (rst_gpio <= 0) { @@ -1333,17 +1336,18 @@ static inline void qca_pcie_write_reg(u32 base, u32 offset, u32 value) void pcie_phy_v2_init(struct ipq_pcie *pcie) { - const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq; - int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq); + if (!pcie->skip_phy_init) { + const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq; + int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq); - for (i = 0; i < size; i++) { - if (regs[i].reg_offset == PCIE_PHY_DELAY_MS) - mdelay(regs[i].val); - else - writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset); + for (i = 0; i < size; i++) { + if (regs[i].reg_offset == PCIE_PHY_DELAY_MS) + mdelay(regs[i].val); + else + writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset); + } + mdelay(5); } - - mdelay(5); return; } diff --git a/drivers/serial/qca_uart.c b/drivers/serial/qca_uart.c index 49fc06605b..77acd785a0 100644 --- a/drivers/serial/qca_uart.c +++ b/drivers/serial/qca_uart.c @@ -453,6 +453,8 @@ static int ipq_serial_ofdata_to_platdata(struct udevice *dev) plat->n_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "n_value", -1); plat->d_value = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "d_value", -1); + plat->gpio_node = fdt_subnode_offset(gd->fdt_blob, dev->of_offset, "serial_gpio"); + return 0; } @@ -559,6 +561,7 @@ static void do_uart_start(void) uart2.n_value = fdtdec_get_int(gd->fdt_blob, node, "n_value", -1); uart2.d_value = fdtdec_get_int(gd->fdt_blob, node, "d_value", -1); + uart2.gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "serial_gpio"); ipq_serial_init(&uart2, uart2.reg_base); } diff --git a/include/configs/ipq5018.h b/include/configs/ipq5018.h index 22f49f5ad1..d4d5d7495b 100644 --- a/include/configs/ipq5018.h +++ b/include/configs/ipq5018.h @@ -24,14 +24,15 @@ #define CONFIG_SPI_FLASH_CYPRESS #define CONFIG_SYS_NO_FLASH #define CONFIG_SYS_CACHELINE_SIZE 64 -#define CONFIG_CMD_CACHE #define CONFIG_IPQ_NO_RELOC #define CONFIG_SYS_VSNPRINTF /* -* Enable Early and Late init -* This config needs for secondary boot and to set BADOFF5E + * Enable Early and Late init + * This config needs for secondary boot and to set BADOFF5E + * This config also need for spi-nor boot, + * set size and offset of hlos and rootfs */ #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_LATE_INIT @@ -49,12 +50,6 @@ */ #define CONFIG_ARMV7_PSCI -/* - * Block Device & Disk Partition Config - */ -#define HAVE_BLOCK_DEVICE -#define CONFIG_DOS_PARTITION - /* * Enable Flashwrite command */ @@ -142,8 +137,6 @@ extern loff_t board_env_size; #define CONFIG_ENV_RANGE board_env_range #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE_MAX + (1024 << 10)) -#define CONFIG_ENV_IS_IN_NAND 1 - /* * NAND Flash Configs */ @@ -152,16 +145,22 @@ extern loff_t board_env_size; * CONFIG_IPQ_NAND: QPIC NAND in FIFO/block mode. * BAM is enabled by default. */ -#define CONFIG_QPIC_NAND #define CONFIG_CMD_NAND -#define CONFIG_CMD_NAND_YAFFS #define CONFIG_SYS_NAND_SELF_INIT -#define CONFIG_SYS_NAND_ONFI_DETECTION -#define CONFIG_PAGE_SCOPE_MULTI_PAGE_READ +#define CONFIG_CMD_MTDPARTS -/* QSPI Flash configs - */ -#define CONFIG_QPIC_SERIAL +#ifdef CONFIG_NAND_FLASH +#define CONFIG_ENV_IS_IN_NAND 1 +#define CONFIG_QPIC_NAND +#define CONFIG_SYS_NAND_ONFI_DETECTION +#define CONFIG_CMD_NAND_YAFFS +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#endif + +#ifdef CONFIG_QPIC_SERIAL +#define CONFIG_PAGE_SCOPE_MULTI_PAGE_READ +#endif /* * SPI Flash Configs @@ -183,15 +182,13 @@ extern loff_t board_env_size; #define CONFIG_IPQ_4B_ADDR_SWITCH_REQD #define CONFIG_QUP_SPI_USE_DMA 1 -#define CONFIG_EFI_PARTITION #define CONFIG_QCA_BAM 1 /* * MMC configs */ +#ifdef CONFIG_MMC_FLASH #define CONFIG_QCA_MMC - -#ifdef CONFIG_QCA_MMC #define CONFIG_MMC #define CONFIG_CMD_MMC #define CONFIG_GENERIC_MMC @@ -201,6 +198,7 @@ extern loff_t board_env_size; #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SDHCI_SUPPORT #define CONFIG_MMC_ADMA +#define CONFIG_EFI_PARTITION /* * eMMC controller support only 4-bit * force SDHC driver to 4-bit mode @@ -211,8 +209,6 @@ extern loff_t board_env_size; /* * I2C Enable */ -#define CONFIG_IPQ5018_I2C - #ifdef CONFIG_IPQ5018_I2C #define CONFIG_SYS_I2C_QUP #define CONFIG_CMD_I2C @@ -224,6 +220,7 @@ extern loff_t board_env_size; */ #define CONFIG_IPQ5018_GMAC +#define CONFIG_IPQ5018_MDIO #define CONFIG_NET_RETRY_COUNT 5 #define CONFIG_SYS_RX_ETH_BUFFER 16 @@ -235,11 +232,17 @@ extern loff_t board_env_size; #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_SERVERIP 192.168.10.19 #define CONFIG_CMD_TFTPPUT -#define CONFIG_IPQ_MDIO 2 +#define CONFIG_IPQ_MDIO 1 #define CONFIG_IPQ_ETH_INIT_DEFER - #define CONFIG_IPQ_NO_MACS 2 +/* + * PHY + */ +#define CONFIG_GEPHY +#define CONFIG_QCA8033_PHY +#define CONFIG_QCA8081_PHY + /* * USB Support */ @@ -250,6 +253,11 @@ extern loff_t board_env_size; #define CONFIG_USB_STORAGE #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +/* + * Block Device & Disk Partition Config + */ +#define HAVE_BLOCK_DEVICE +#define CONFIG_DOS_PARTITION #endif /* @@ -288,7 +296,6 @@ extern loff_t board_env_size; #define CONFIG_CMD_XIMG /* MTEST */ -#define CONFIG_CMD_MEMTEST #define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE + 0x1300000 #define CONFIG_SYS_MEMTEST_END CONFIG_SYS_MEMTEST_START + 0x100 @@ -299,15 +306,13 @@ extern loff_t board_env_size; #define CONFIG_BOOTDELAY 2 -#define CONFIG_MTD_DEVICE -#define CONFIG_CMD_MTDPARTS -#define CONFIG_MTD_PARTITIONS #define NUM_ALT_PARTITION 16 -#define CONFIG_CMD_UBI -#define CONFIG_RBTREE - +#ifndef CONFIG_IPQ_TINY #define CONFIG_CMD_BOOTZ +#define CONFIG_CMD_CACHE +#endif + #define CONFIG_FDT_FIXUP_PARTITIONS #define CONFIG_IPQ_FDT_FIXUP @@ -337,9 +342,7 @@ extern loff_t board_env_size; #define CONFIG_QCA_APPSBL_DLOAD #define CONFIG_IPQ5018_DMAGIC_ADDR 0x193D100 #ifdef CONFIG_QCA_APPSBL_DLOAD -#define CONFIG_CMD_TFTPPUT -#define CONFIG_CMD_TFTPPUT -/* We will be uploading very big files */ + #undef CONFIG_NET_RETRY_COUNT #define CONFIG_NET_RETRY_COUNT 500 @@ -356,14 +359,23 @@ extern loff_t board_env_size; * size is configured to 64 */ #define CONFIG_SYS_CACHELINE_SIZE 64 -/* - * Tz Xpu test ccommand - */ -#define CONFIG_IPQ_TZT - /* * UBI write command */ +#ifdef CONFIG_UBI_WRITE +#define CONFIG_CMD_UBI +#define CONFIG_RBTREE #define IPQ_UBI_VOL_WRITE_SUPPORT +#endif + +#undef CONFIG_BOOTM_NETBSD +#undef CONFIG_BOOTM_PLAN9 +#undef CONFIG_BOOTM_RTEMS +#undef CONFIG_BOOTM_VXWORKS + +#ifdef CONFIG_ART_COMPRESSED +#undef CONFIG_GZIP +#undef CONFIG_ZLIB +#endif #endif /* _IPQ5018_H */ diff --git a/lib/Kconfig b/lib/Kconfig index 9d580e4115..ff53702844 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -127,6 +127,14 @@ config LZ4 frame format currently (2015) implemented in the Linux kernel (generated by 'lz4 -l'). The two formats are incompatible. +config LZMA + bool "Enable LZMA decompression support" + help + If this option is set, support for LZMA compressed images + is included. The LZMA algorithm can run in-place as long as the + compressed image is loaded to the end of the output buffer, and + trades high compression ratios and fairly fast decompression speed. + endmenu config ERRNO_STR diff --git a/tools/pack.py b/tools/pack.py index a0e15e566e..69ea313810 100644 --- a/tools/pack.py +++ b/tools/pack.py @@ -87,6 +87,7 @@ MODE = "" image_type = "all" memory_size = "default" lk = "false" +skip_4k_nand = "false" # # Python 2.6 and earlier did not have OrderedDict use the backport @@ -714,7 +715,7 @@ class Pack(object): def __gen_flash_script_image(self, filename, soc_version, file_exists, machid, partition, flinfo, script): - global IF_HK10 + global IF_QCN9000 img_size = 0 if file_exists == 1: @@ -774,8 +775,8 @@ class Pack(object): if machid: script.start_if("machid", machid) - if section_conf == "mibib" and IF_HK10: - section_conf = "mibib_hk10" + if section_conf == "mibib" and IF_QCN9000: + section_conf = "mibib_qcn9000" if section_conf == "qsee": section_conf = "tz" elif section_conf == "appsbl": @@ -787,8 +788,8 @@ class Pack(object): section_conf = "ubi" elif section_conf == "wififw" and self.flash_type in ["nand", "nand-4k", "nand-audio", "nand-audio-4k", "norplusnand", "norplusnand-4k"]: section_conf = "wififw_ubi" - if IF_HK10: - section_conf = "wififw_ubi_hk10" + if IF_QCN9000: + section_conf = "wififw_ubi_qcn9000" if soc_version: section_conf = section_conf + "_v" + str(soc_version) @@ -849,7 +850,7 @@ class Pack(object): global MODE global SRC_DIR global ARCH_NAME - global IF_HK10 + global IF_QCN9000 diff_files = "" count = 0 @@ -860,8 +861,8 @@ class Pack(object): if self.flash_type == "norplusemmc" and flinfo.type == "emmc": srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml" else: - if IF_HK10: - srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition-hk10.xml" + if IF_QCN9000: + srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition-qcn9000.xml" else: srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml" @@ -1091,7 +1092,7 @@ class Pack(object): def __gen_script_append_images(self, filename, soc_version, images, flinfo, root, section_conf, partition): - global HK10 + global QCN9000 part_info = self.__get_part_info(partition) if part_info == None and self.flinfo.type != 'norplusnand': @@ -1139,7 +1140,7 @@ class Pack(object): """ global MODE global SRC_DIR - global HK10 + global QCN9000 soc_version = 0 diff_soc_ver_files = 0 @@ -1150,8 +1151,8 @@ class Pack(object): if ret == 0: return 0 #Stop packing this single-image - if HK10: - script.end_if() #end if started for hk10+pine + if QCN9000: + script.end_if() #end if started for hk+pine if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"): if flinfo.type == "emmc": @@ -1297,11 +1298,11 @@ class Pack(object): for img in imgs: soc_version = img.get('soc_version') filename = img.text - if HK10 and section_conf == "wififw": - filename_hk10 = filename.replace("wifi_fw_ubi", "wifi_fw_ipq8074_qcn9000_ubi") - if os.path.exists(os.path.join(self.images_dname, filename_hk10)): - section_conf_hk10 = section_conf + "_ubi_hk10" - self.__gen_script_append_images(filename_hk10, soc_version, images, flinfo, root, section_conf_hk10, partition) + if QCN9000 and section_conf == "wififw": + filename_qcn9000 = filename.replace("wifi_fw_ubi", "wifi_fw_ipq8074_qcn9000_ubi") + if os.path.exists(os.path.join(self.images_dname, filename_qcn9000)): + section_conf_qcn9000 = section_conf + "_ubi_qcn9000" + self.__gen_script_append_images(filename_qcn9000, soc_version, images, flinfo, root, section_conf_qcn9000, partition) if 'optional' in img.attrib: if not os.path.exists(os.path.join(self.images_dname, filename)): file_exists = 0 @@ -1314,12 +1315,12 @@ class Pack(object): except KeyError, e: continue - # system-partition specific for HK10+PINE - if section_conf == "mibib" and HK10: + # system-partition specific for HK+PINE + if section_conf == "mibib" and QCN9000: img = section.find('img_name') - filename_hk10 = img.text[:-4] + "-hk10.bin" - section_conf_hk10 = section_conf + "_hk10" - self.__gen_script_append_images(filename_hk10, soc_version, images, flinfo, root, section_conf_hk10, partition) + filename_qcn9000 = img.text[:-4] + "-qcn9000.bin" + section_conf_qcn9000 = section_conf + "_qcn9000" + self.__gen_script_append_images(filename_qcn9000, soc_version, images, flinfo, root, section_conf_qcn9000, partition) else: if diff_soc_ver_files: @@ -1392,8 +1393,8 @@ class Pack(object): def __gen_board_script(self, flinfo, part_fname, images, root): global SRC_DIR global ARCH_NAME - global HK10 - global IF_HK10 + global QCN9000 + global IF_QCN9000 """Generate the flashing script for one board. @@ -1404,7 +1405,7 @@ class Pack(object): fconf_fname -- string, flash config file specific to the board images -- list of ImageInfo, append images used by the board here """ - IF_HK10 = False + IF_QCN9000 = False script_fp = open(self.scr_fname, "a") self.flinfo = flinfo @@ -1436,22 +1437,22 @@ class Pack(object): script = Flash_Script(flinfo, pagesize) script.probe() - # system-partition specific for HK10+PINE - if HK10: - IF_HK10 = True - part_fname_hk10 = part_fname[:-4] + "-hk10.bin" - mibib_hk10 = MIBIB(part_fname_hk10, flinfo.pagesize, flinfo.blocksize, + # system-partition specific for HK+PINE + if QCN9000: + IF_QCN9000 = True + part_fname_qcn9000 = part_fname[:-4] + "-qcn9000.bin" + mibib_qcn9000 = MIBIB(part_fname_qcn9000, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize, blocksize, chipsize, root_part) - self.partitions = mibib_hk10.get_parts() + self.partitions = mibib_qcn9000.get_parts() script.append('if test "$machid" = "801000e" || test "$machid" = "801010e" || test "$machid" = "8010012"; then\n', fatal=False) ret = self.__gen_flash_script(script, flinfo, root) if ret == 0: - return 0 #Issue in packing hk10+pine single-image + return 0 #Issue in packing hk+pine single-image script.append('else', fatal=False) self.partitions = {} - IF_HK10 = False + IF_QCN9000 = False mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize, blocksize, chipsize, root_part) @@ -1466,8 +1467,8 @@ class Pack(object): if ret == 0: return 0 - if HK10: - HK10 = False + if QCN9000: + QCN9000 = False try: script_fp.write(script.dumps()) @@ -1517,7 +1518,7 @@ class Pack(object): global SRC_DIR global ARCH_NAME global MODE - global HK10 + global QCN9000 try: if ftype == "tiny-nor": @@ -1597,7 +1598,7 @@ class Pack(object): blocks_per_chip = int(part_info.find(".//total_block").text) if ARCH_NAME == "ipq807x" and (ftype == "norplusnand" or ftype == "nand"): - HK10 = True + QCN9000 = True if ftype in ["tiny-nor", "norplusnand", "norplusnand-4k", "norplusemmc"]: ftype = "nor" @@ -1617,9 +1618,9 @@ class Pack(object): def __process_board(self, images, root): - global HK10 + global QCN9000 - HK10 = False + QCN9000 = False try: if self.flash_type in [ "nand", "nand-4k", "nand-audio", "nand-audio-4k", "nor", "tiny-nor", "norplusnand", "norplusnand-4k" ]: ret = self.__process_board_flash(self.flash_type, images, root) @@ -1657,7 +1658,7 @@ class Pack(object): self.__mkimage(images) else: fail_img = out_fname.split("/") - print "Failed to pack %s" % fail_img[-1] + error("Failed to pack %s" % fail_img[-1]) class UsageError(Exception): """Indicates error in command arguments.""" @@ -1682,6 +1683,7 @@ class ArgParser(object): global image_type global memory_size global lk + global skip_4k_nand """Start the parsing process, and populate members with parsed value. @@ -1691,7 +1693,7 @@ class ArgParser(object): cdir = os.path.abspath(os.path.dirname("")) if len(sys.argv) > 1: try: - opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type=", "memory=", "lk"]) + opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type=", "memory=", "lk", "skip_4k_nand"]) except GetoptError, e: raise UsageError(e.msg) @@ -1720,6 +1722,9 @@ class ArgParser(object): elif option =="--lk": lk = "true" + elif option =="--skip_4k_nand": + skip_4k_nand = "true" + #Verify Arguments passed by user @@ -1785,6 +1790,7 @@ class ArgParser(object): print " \t\tIf specified, CDTs created with specified memory size will be used for single-image.\n" print print " --lk \t\tReplace u-boot with lkboot for appsbl" + print " --skip_4k_nand \tskip generating 4k nand images" print " \t\tThis Argument does not take any value" print "Pack Version: %s" % version @@ -1874,15 +1880,16 @@ def main(): config = SRC_DIR + "/" + ARCH_NAME + "/config.xml" root = ET.parse(config) -# Add nand-4k flash type, if nand flash type is specified - if "nand" in parser.flash_type.split(","): - if root.find(".//data[@type='NAND_PARAMETER']/entry") != None: - parser.flash_type = parser.flash_type + ",nand-4k" + if skip_4k_nand != "true": + # Add nand-4k flash type, if nand flash type is specified + if "nand" in parser.flash_type.split(","): + if root.find(".//data[@type='NAND_PARAMETER']/entry") != None: + parser.flash_type = parser.flash_type + ",nand-4k" -# Add norplusnand-4k flash type, if norplusnand flash type is specified - if "norplusnand" in parser.flash_type.split(","): - if root.find(".//data[@type='NAND_PARAMETER']/entry") != None: - parser.flash_type = parser.flash_type + ",norplusnand-4k" + # Add norplusnand-4k flash type, if norplusnand flash type is specified + if "norplusnand" in parser.flash_type.split(","): + if root.find(".//data[@type='NAND_PARAMETER']/entry") != None: + parser.flash_type = parser.flash_type + ",norplusnand-4k" # Format the output image name from Arch, flash type and mode for flash_type in parser.flash_type.split(","):