Am 15.02.19 um 12:56 schrieb Rosy Song:
> Signed-off-by: Rosy Song <rosys...@rosinson.com>
> ---
>  arch/mips/dts/Makefile                        |   1 +
>  arch/mips/dts/ap152.dts                       |  48 ++
>  arch/mips/dts/qca956x.dtsi                    |  87 ++++
>  arch/mips/mach-ath79/Kconfig                  |  14 +
>  arch/mips/mach-ath79/Makefile                 |   1 +
>  .../mach-ath79/include/mach/ar71xx_regs.h     |  70 +++
>  arch/mips/mach-ath79/include/mach/ath79.h     |   3 +
>  arch/mips/mach-ath79/qca956x/Makefile         |   5 +
>  arch/mips/mach-ath79/qca956x/clk.c            | 419 ++++++++++++++++++
>  arch/mips/mach-ath79/qca956x/cpu.c            |   9 +
>  arch/mips/mach-ath79/qca956x/ddr.c            | 308 +++++++++++++
>  arch/mips/mach-ath79/qca956x/lowlevel_init.S  |  79 ++++
>  .../mips/mach-ath79/qca956x/qca956x-ddr-tap.S | 194 ++++++++
>  arch/mips/mach-ath79/reset.c                  | 271 +++++++++++
>  board/qca/ap152/Kconfig                       |  27 ++
>  board/qca/ap152/MAINTAINERS                   |   6 +
>  board/qca/ap152/Makefile                      |   3 +
>  board/qca/ap152/ap152.c                       |  81 ++++
>  configs/ap152_defconfig                       |  55 +++
>  include/configs/ap152.h                       |  54 +++
>  20 files changed, 1735 insertions(+)
>  create mode 100644 arch/mips/dts/ap152.dts
>  create mode 100644 arch/mips/dts/qca956x.dtsi
>  create mode 100644 arch/mips/mach-ath79/qca956x/Makefile
>  create mode 100644 arch/mips/mach-ath79/qca956x/clk.c
>  create mode 100644 arch/mips/mach-ath79/qca956x/cpu.c
>  create mode 100644 arch/mips/mach-ath79/qca956x/ddr.c
>  create mode 100644 arch/mips/mach-ath79/qca956x/lowlevel_init.S
>  create mode 100644 arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
>  create mode 100644 board/qca/ap152/Kconfig
>  create mode 100644 board/qca/ap152/MAINTAINERS
>  create mode 100644 board/qca/ap152/Makefile
>  create mode 100644 board/qca/ap152/ap152.c
>  create mode 100644 configs/ap152_defconfig
>  create mode 100644 include/configs/ap152.h
> 
> diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
> index b94b582837..621c35f0ef 100644
> --- a/arch/mips/dts/Makefile
> +++ b/arch/mips/dts/Makefile
> @@ -2,6 +2,7 @@
>  
>  dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
>  dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
> +dtb-$(CONFIG_TARGET_AP152) += ap152.dtb
>  dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
>  dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
>  dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
> diff --git a/arch/mips/dts/ap152.dts b/arch/mips/dts/ap152.dts
> new file mode 100644
> index 0000000000..1722290c73
> --- /dev/null
> +++ b/arch/mips/dts/ap152.dts
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +/dts-v1/;
> +#include "qca956x.dtsi"
> +
> +/ {
> +     model = "AP152 Reference Board";
> +     compatible = "qca,ap152", "qca,qca956x";
> +
> +     aliases {
> +             spi0 = &spi0;
> +             serial0 = &uart0;
> +     };
> +
> +     chosen {
> +             stdout-path = "serial0:115200n8";
> +     };
> +};
> +
> +&gmac0 {
> +     phy-mode = "sgmii";
> +     status = "okay";
> +};
> +
> +&xtal {
> +     clock-frequency = <25000000>;
> +};
> +
> +&uart0 {
> +     clock-frequency = <25000000>;
> +     status = "okay";
> +};
> +
> +&spi0 {
> +     spi-max-frequency = <25000000>;
> +     status = "okay";
> +     spi-flash@0 {
> +             #address-cells = <1>;
> +             #size-cells = <1>;
> +             compatible = "spi-flash";
> +             memory-map = <0x9f000000 0x01000000>;
> +             spi-max-frequency = <25000000>;
> +             reg = <0>;
> +     };
> +};
> diff --git a/arch/mips/dts/qca956x.dtsi b/arch/mips/dts/qca956x.dtsi
> new file mode 100644
> index 0000000000..6cb360b3f8
> --- /dev/null
> +++ b/arch/mips/dts/qca956x.dtsi
> @@ -0,0 +1,87 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +     compatible = "qca,qca956x";
> +
> +     #address-cells = <1>;
> +     #size-cells = <1>;
> +
> +     cpus {
> +             #address-cells = <1>;
> +             #size-cells = <0>;
> +
> +             cpu@0 {
> +                     device_type = "cpu";
> +                     compatible = "mips,mips74Kc";
> +                     reg = <0>;
> +             };
> +     };
> +
> +     clocks {
> +             #address-cells = <1>;
> +             #size-cells = <1>;
> +             ranges;
> +
> +             xtal: xtal {
> +                     #clock-cells = <0>;
> +                     compatible = "fixed-clock";
> +                     clock-output-names = "xtal";
> +             };
> +     };
> +
> +     ahb {
> +             compatible = "simple-bus";
> +             ranges;
> +
> +             #address-cells = <1>;
> +             #size-cells = <1>;
> +
> +             apb {
> +                     compatible = "simple-bus";
> +                     ranges;
> +
> +                     #address-cells = <1>;
> +                     #size-cells = <1>;
> +
> +                     uart0: uart@18020000 {
> +                             compatible = "ns16550";
> +                             reg = <0x18020000 0x20>;
> +                             reg-shift = <2>;
> +
> +                             status = "disabled";
> +                     };
> +
> +                     gmac0: eth@0x19000000 {
> +                             compatible = "qca,ag956x-mac";
> +                             reg = <0x19000000 0x200>;
> +                             phy = <&phy0>;
> +                             phy-mode = "sgmii";
> +
> +                             status = "disabled";
> +
> +                             mdio {
> +                                     #address-cells = <1>;
> +                                     #size-cells = <0>;
> +                                     phy0: ethernet-phy@0 {
> +                                             reg = <0>;
> +                                     };
> +                             };
> +                     };
> +             };
> +
> +             spi0: spi@1f000000 {
> +                     compatible = "qca,ar7100-spi";
> +                     reg = <0x1f000000 0x10>;
> +
> +                     status = "disabled";
> +
> +                     #address-cells = <1>;
> +                     #size-cells = <0>;
> +             };
> +     };
> +};
> diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
> index bc86f591df..bdb23b5765 100644
> --- a/arch/mips/mach-ath79/Kconfig
> +++ b/arch/mips/mach-ath79/Kconfig
> @@ -33,6 +33,15 @@ config SOC_QCA953X
>       help
>         This supports QCA/Atheros qca953x family SOCs.
>  
> +config SOC_QCA956X
> +     bool
> +     select MIPS_TUNE_74KC
> +     select SUPPORTS_BIG_ENDIAN
> +     select SUPPORTS_CPU_MIPS32_R1
> +     select SUPPORTS_CPU_MIPS32_R2
> +     help
> +       This supports QCA/Atheros qca956x family SOCs.
> +
>  choice
>       prompt "Board select"
>  
> @@ -44,6 +53,10 @@ config TARGET_AP143
>       bool "AP143 Reference Board"
>       select SOC_QCA953X
>  
> +config TARGET_AP152
> +     bool "AP152 Reference Board"
> +     select SOC_QCA956X
> +
>  config BOARD_TPLINK_WDR4300
>       bool "TP-Link WDR4300 Board"
>       select SOC_AR934X
> @@ -52,6 +65,7 @@ endchoice
>  
>  source "board/qca/ap121/Kconfig"
>  source "board/qca/ap143/Kconfig"
> +source "board/qca/ap152/Kconfig"
>  source "board/tplink/wdr4300/Kconfig"
>  
>  endmenu
> diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
> index 7aa40c65d3..fbd40c02be 100644
> --- a/arch/mips/mach-ath79/Makefile
> +++ b/arch/mips/mach-ath79/Makefile
> @@ -7,3 +7,4 @@ obj-y += dram.o
>  obj-$(CONFIG_SOC_AR933X)     += ar933x/
>  obj-$(CONFIG_SOC_AR934X)     += ar934x/
>  obj-$(CONFIG_SOC_QCA953X)    += qca953x/
> +obj-$(CONFIG_SOC_QCA956X)    += qca956x/
> diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h 
> b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> index 5d371bb582..380f387a26 100644
> --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> @@ -201,6 +201,10 @@
>       (AR71XX_APB_BASE + 0x00070000)
>  #define QCA956X_GMAC_SIZE                            0x64
>  
> +#define QCA956X_SRIF_BASE \
> +     (AR71XX_APB_BASE + 0x00116000)
> +#define QCA956X_SRIF_SIZE                            0x1000
> +
>  /*
>   * DDR_CTRL block
>   */
> @@ -278,6 +282,18 @@
>  #define QCA953X_DDR_REG_CTL_CONF                     0x108
>  #define QCA953X_DDR_REG_CONFIG3                              0x15c
>  
> +#define QCA956X_DDR_REG_TAP_CTRL2                    0x24
> +#define QCA956X_DDR_REG_TAP_CTRL3                    0x28
> +#define QCA956X_DDR_REG_DDR2_CONFIG                  0xb8
> +#define QCA956X_DDR_REG_DDR2_EMR2                    0xbc
> +#define QCA956X_DDR_REG_DDR2_EMR3                    0xc0
> +#define QCA956X_DDR_REG_BURST                                0xc4
> +#define QCA956X_DDR_REG_BURST2                               0xc8
> +#define QCA956X_DDR_REG_TIMEOUT_MAX                  0xcc
> +#define QCA956X_DDR_REG_FSM_WAIT_CTRL                        0xe4
> +#define QCA956X_DDR_REG_CTL_CONF                     0x108
> +#define QCA956X_DDR_REG_DDR3_CONFIG                  0x15c
> +
>  /*
>   * PLL block
>   */
> @@ -519,6 +535,13 @@
>  #define QCA956X_PLL_DDR_CONFIG_REG                   0x08
>  #define QCA956X_PLL_DDR_CONFIG1_REG                  0x0c
>  #define QCA956X_PLL_CLK_CTRL_REG                     0x10
> +#define QCA956X_PLL_SWITCH_CLK_CTRL_REG                      0x28
> +#define QCA956X_PLL_ETH_XMII_CTRL_REG                        0x30
> +#define QCA956X_PLL_DDR_DIT_FRAC_REG                 0x38
> +#define QCA956X_PLL_DDR_DIT2_FRAC_REG                        0x3c
> +#define QCA956X_PLL_CPU_DIT_FRAC_REG                 0x40
> +#define QCA956X_PLL_CPU_DIT2_FRAC_REG                        0x44
> +#define QCA956X_PLL_ETH_SGMII_SERDES_REG             0x4c
>  
>  #define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT          12
>  #define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK           0x1f
> @@ -756,6 +779,17 @@
>  #define QCA955X_RESET_MBOX                           BIT(1)
>  #define QCA955X_RESET_I2S                            BIT(0)
>  
> +#define QCA956X_RESET_EXTERNAL                               BIT(28)
> +#define QCA956X_RESET_FULL_CHIP                              BIT(24)
> +#define QCA956X_RESET_GE1_MDIO                               BIT(23) /* 
> Reserved in datasheet */
> +#define QCA956X_RESET_GE0_MDIO                               BIT(22)
> +#define QCA956X_RESET_GE1_MAC                                BIT(13) /* 
> Reserved in datasheet */
> +#define QCA956X_RESET_SGMII_ASSERT                   BIT(12)
> +#define QCA956X_RESET_GE0_MAC                                BIT(9)
> +#define QCA956X_RESET_SGMII                          BIT(8)
> +#define QCA956X_RESET_SGMII_ANALOG                           BIT(2)
> +#define QCA956X_RESET_SWITCH                         BIT(0)
> +
>  #define AR933X_BOOTSTRAP_MDIO_GPIO_EN                        BIT(18)
>  #define AR933X_BOOTSTRAP_DDR2                                BIT(13)
>  #define AR933X_BOOTSTRAP_EEPBUSY                     BIT(4)
> @@ -1099,8 +1133,12 @@
>  #define QCA953X_GPIO_IN_MUX_UART0_SIN                        9
>  #define QCA953X_GPIO_IN_MUX_SPI_DATA_IN                      8
>  
> +#define QCA956X_GPIO(x)                                      BIT(x)
> +#define QCA956X_GPIO_MUX_MASK(x)                     (0xff << (x))
>  #define QCA956X_GPIO_OUT_MUX_GE0_MDO                 32
>  #define QCA956X_GPIO_OUT_MUX_GE0_MDC                 33
> +#define QCA956X_GPIO_IN_MUX_UART0_SIN                        0x12
> +#define QCA956X_GPIO_OUT_MUX_UART0_SOUT                      0x16
>  
>  #define AR71XX_GPIO_COUNT                            16
>  #define AR7240_GPIO_COUNT                            18
> @@ -1179,6 +1217,25 @@
>  #define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT                      13
>  #define QCA953X_SRIF_DPLL2_OUTDIV_MASK                       0x7
>  
> +#define QCA956X_SRIF_BB_DPLL1_REG                    0x180
> +#define QCA956X_SRIF_BB_DPLL2_REG                    0x184
> +#define QCA956X_SRIF_BB_DPLL3_REG                    0x188
> +
> +#define QCA956X_SRIF_CPU_DPLL1_REG                   0xf00
> +#define QCA956X_SRIF_CPU_DPLL2_REG                   0xf04
> +#define QCA956X_SRIF_CPU_DPLL3_REG                   0xf08
> +
> +#define QCA956X_SRIF_DDR_DPLL1_REG                   0xec0
> +#define QCA956X_SRIF_DDR_DPLL2_REG                   0xec4
> +#define QCA956X_SRIF_DDR_DPLL3_REG                   0xec8
> +
> +#define QCA956X_SRIF_PCIE_DPLL1_REG                  0xc80
> +#define QCA956X_SRIF_PCIE_DPLL2_REG                  0xc84
> +#define QCA956X_SRIF_PCIE_DPLL3_REG                  0xc88
> +
> +#define QCA956X_SRIF_PMU1_REG                                0xcc0
> +#define QCA956X_SRIF_PMU2_REG                                0xcc4
> +
>  /*
>   * MII_CTRL block
>   */
> @@ -1261,4 +1318,17 @@
>  #define QCA955X_ETH_CFG_RGMII_EN                     BIT(0)
>  #define QCA955X_ETH_CFG_GE0_SGMII                    BIT(6)
>  
> +/*
> + * QCA956X GMAC Interface
> + */
> +
> +#define QCA956X_GMAC_REG_ETH_CFG                     0x00
> +#define QCA956X_GMAC_REG_SGMII_RESET                 0x14
> +#define QCA956X_GMAC_REG_SGMII_SERDES                        0x18
> +#define QCA956X_GMAC_REG_MR_AN_CTRL                  0x1c
> +#define QCA956X_GMAC_REG_SGMII_CONFIG                        0x34
> +#define QCA956X_GMAC_REG_SGMII_DEBUG                 0x58
> +
> +#define QCA956X_ETH_CFG_GE0_SGMII                    BIT(6)
> +
>  #endif /* __ASM_AR71XX_H */
> diff --git a/arch/mips/mach-ath79/include/mach/ath79.h 
> b/arch/mips/mach-ath79/include/mach/ath79.h
> index 5de7a43f79..0fde5079b1 100644
> --- a/arch/mips/mach-ath79/include/mach/ath79.h
> +++ b/arch/mips/mach-ath79/include/mach/ath79.h
> @@ -2,6 +2,7 @@
>  /*
>   * Atheros AR71XX/AR724X/AR913X common definitions
>   *
> + * Copyright (C) 2018-2019 Rosy Song <rosys...@rosinson.com>
>   * Copyright (C) 2015-2016 Wills Wang <wills.w...@live.com>
>   * Copyright (C) 2008-2011 Gabor Juhos <juh...@openwrt.org>
>   * Copyright (C) 2008 Imre Kaloz <ka...@openwrt.org>
> @@ -146,4 +147,6 @@ int ath79_usb_reset(void);
>  void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 
> ahb_mhz);
>  void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 
> ahb_mhz);
>  
> +void qca956x_pll_init(void);
> +void qca956x_ddr_init(void);
>  #endif /* __ASM_MACH_ATH79_H */
> diff --git a/arch/mips/mach-ath79/qca956x/Makefile 
> b/arch/mips/mach-ath79/qca956x/Makefile
> new file mode 100644
> index 0000000000..3f5fc0363f
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-y += cpu.o
> +obj-y += clk.o
> +obj-y += ddr.o qca956x-ddr-tap.o
> diff --git a/arch/mips/mach-ath79/qca956x/clk.c 
> b/arch/mips/mach-ath79/qca956x/clk.c
> new file mode 100644
> index 0000000000..ca956d1291
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/clk.c
> @@ -0,0 +1,419 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <mach/ar71xx_regs.h>
> +#include <mach/ath79.h>
> +#include <wait_bit.h>
> +
> +#define PLL_SRIF_DPLL2_KI_LSB 29
> +#define PLL_SRIF_DPLL2_KI_MASK 0x60000000
> +#define PLL_SRIF_DPLL2_KI_SET(x) \
> +     (((x) << PLL_SRIF_DPLL2_KI_LSB) & PLL_SRIF_DPLL2_KI_MASK)
> +#define PLL_SRIF_DPLL2_KD_LSB 25
> +#define PLL_SRIF_DPLL2_KD_MASK 0x1e000000
> +#define PLL_SRIF_DPLL2_KD_SET(x) \
> +     (((x) << PLL_SRIF_DPLL2_KD_LSB) & PLL_SRIF_DPLL2_KD_MASK)
> +#define PLL_SRIF_DPLL2_PLL_PWD_LSB 22
> +#define PLL_SRIF_DPLL2_PLL_PWD_MASK 0x00400000
> +#define PLL_SRIF_DPLL2_PLL_PWD_SET(x) \
> +     (((x) << PLL_SRIF_DPLL2_PLL_PWD_LSB) & PLL_SRIF_DPLL2_PLL_PWD_MASK)
> +#define PLL_SRIF_DPLL2_OUTDIV_LSB 19
> +#define PLL_SRIF_DPLL2_OUTDIV_MASK 0x00380000
> +#define PLL_SRIF_DPLL2_OUTDIV_SET(x) \
> +     (((x) << PLL_SRIF_DPLL2_OUTDIV_LSB) & PLL_SRIF_DPLL2_OUTDIV_MASK)
> +#define PLL_SRIF_DPLL2_PHASE_SHIFT_LSB 12
> +#define PLL_SRIF_DPLL2_PHASE_SHIFT_MASK 0x0007f000
> +#define PLL_SRIF_DPLL2_PHASE_SHIFT_SET(x) \
> +     (((x) << PLL_SRIF_DPLL2_PHASE_SHIFT_LSB) & 
> PLL_SRIF_DPLL2_PHASE_SHIFT_MASK)
> +#define CPU_PLL_CONFIG_PLLPWD_LSB 30
> +#define CPU_PLL_CONFIG_PLLPWD_MASK 0x40000000
> +#define CPU_PLL_CONFIG_PLLPWD_SET(x) \
> +     (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK)
> +#define CPU_PLL_CONFIG_OUTDIV_LSB 19
> +#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00380000
> +#define CPU_PLL_CONFIG_OUTDIV_SET(x) \
> +     (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK)
> +#define CPU_PLL_CONFIG_RANGE_LSB 17
> +#define CPU_PLL_CONFIG_RANGE_MASK 0x00060000
> +#define CPU_PLL_CONFIG_RANGE_SET(x) \
> +     (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK)
> +#define CPU_PLL_CONFIG_REFDIV_LSB 12
> +#define CPU_PLL_CONFIG_REFDIV_MASK 0x0001f000
> +#define CPU_PLL_CONFIG_REFDIV_SET(x) \
> +     (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK)
> +#define CPU_PLL_CONFIG1_NINT_LSB 18
> +#define CPU_PLL_CONFIG1_NINT_MASK 0x07fc0000
> +#define CPU_PLL_CONFIG1_NINT_SET(x) \
> +     (((x) << CPU_PLL_CONFIG1_NINT_LSB) & CPU_PLL_CONFIG1_NINT_MASK)
> +#define CPU_PLL_DITHER1_DITHER_EN_LSB 31
> +#define CPU_PLL_DITHER1_DITHER_EN_MASK 0x80000000
> +#define CPU_PLL_DITHER1_DITHER_EN_SET(x) \
> +     (((x) << CPU_PLL_DITHER1_DITHER_EN_LSB) & 
> CPU_PLL_DITHER1_DITHER_EN_MASK)
> +#define CPU_PLL_DITHER1_UPDATE_COUNT_LSB 24
> +#define CPU_PLL_DITHER1_UPDATE_COUNT_MASK 0x3f000000
> +#define CPU_PLL_DITHER1_UPDATE_COUNT_SET(x) \
> +     (((x) << CPU_PLL_DITHER1_UPDATE_COUNT_LSB) & 
> CPU_PLL_DITHER1_UPDATE_COUNT_MASK)
> +#define CPU_PLL_DITHER1_NFRAC_STEP_LSB 18
> +#define CPU_PLL_DITHER1_NFRAC_STEP_MASK 0x00fc0000
> +#define CPU_PLL_DITHER1_NFRAC_STEP_SET(x) \
> +     (((x) << CPU_PLL_DITHER1_NFRAC_STEP_LSB) & 
> CPU_PLL_DITHER1_NFRAC_STEP_MASK)
> +#define CPU_PLL_DITHER1_NFRAC_MIN_LSB 0
> +#define CPU_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
> +#define CPU_PLL_DITHER1_NFRAC_MIN_SET(x) \
> +     (((x) << CPU_PLL_DITHER1_NFRAC_MIN_LSB) & 
> CPU_PLL_DITHER1_NFRAC_MIN_MASK)
> +#define CPU_PLL_DITHER2_NFRAC_MAX_LSB 0
> +#define CPU_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
> +#define CPU_PLL_DITHER2_NFRAC_MAX_SET(x) \
> +     (((x) << CPU_PLL_DITHER2_NFRAC_MAX_LSB) & 
> CPU_PLL_DITHER2_NFRAC_MAX_MASK)
> +#define DDR_PLL_CONFIG_PLLPWD_LSB 30
> +#define DDR_PLL_CONFIG_PLLPWD_MASK 0x40000000
> +#define DDR_PLL_CONFIG_PLLPWD_SET(x) \
> +     (((x) << DDR_PLL_CONFIG_PLLPWD_LSB) & DDR_PLL_CONFIG_PLLPWD_MASK)
> +#define DDR_PLL_CONFIG_OUTDIV_LSB 23
> +#define DDR_PLL_CONFIG_OUTDIV_MASK 0x03800000
> +#define DDR_PLL_CONFIG_OUTDIV_SET(x) \
> +     (((x) << DDR_PLL_CONFIG_OUTDIV_LSB) & DDR_PLL_CONFIG_OUTDIV_MASK)
> +#define DDR_PLL_CONFIG_RANGE_LSB 21
> +#define DDR_PLL_CONFIG_RANGE_MASK 0x00600000
> +#define DDR_PLL_CONFIG_RANGE_SET(x) \
> +     (((x) << DDR_PLL_CONFIG_RANGE_LSB) & DDR_PLL_CONFIG_RANGE_MASK)
> +#define DDR_PLL_CONFIG_REFDIV_LSB 16
> +#define DDR_PLL_CONFIG_REFDIV_MASK 0x001f0000
> +#define DDR_PLL_CONFIG_REFDIV_SET(x) \
> +     (((x) << DDR_PLL_CONFIG_REFDIV_LSB) & DDR_PLL_CONFIG_REFDIV_MASK)
> +#define DDR_PLL_CONFIG1_NINT_LSB 18
> +#define DDR_PLL_CONFIG1_NINT_MASK 0x07fc0000
> +#define DDR_PLL_CONFIG1_NINT_SET(x) \
> +     (((x) << DDR_PLL_CONFIG1_NINT_LSB) & DDR_PLL_CONFIG1_NINT_MASK)
> +#define DDR_PLL_DITHER1_DITHER_EN_LSB 31
> +#define DDR_PLL_DITHER1_DITHER_EN_MASK 0x80000000
> +#define DDR_PLL_DITHER1_DITHER_EN_SET(x) \
> +     (((x) << DDR_PLL_DITHER1_DITHER_EN_LSB) & 
> DDR_PLL_DITHER1_DITHER_EN_MASK)
> +#define DDR_PLL_DITHER1_UPDATE_COUNT_LSB 27
> +#define DDR_PLL_DITHER1_UPDATE_COUNT_MASK 0x78000000
> +#define DDR_PLL_DITHER1_UPDATE_COUNT_SET(x) \
> +     (((x) << DDR_PLL_DITHER1_UPDATE_COUNT_LSB) & 
> DDR_PLL_DITHER1_UPDATE_COUNT_MASK)
> +#define DDR_PLL_DITHER1_NFRAC_STEP_LSB 20
> +#define DDR_PLL_DITHER1_NFRAC_STEP_MASK 0x07f00000
> +#define DDR_PLL_DITHER1_NFRAC_STEP_SET(x) \
> +     (((x) << DDR_PLL_DITHER1_NFRAC_STEP_LSB) & 
> DDR_PLL_DITHER1_NFRAC_STEP_MASK)
> +#define DDR_PLL_DITHER1_NFRAC_MIN_LSB 0
> +#define DDR_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
> +#define DDR_PLL_DITHER1_NFRAC_MIN_SET(x) \
> +     (((x) << DDR_PLL_DITHER1_NFRAC_MIN_LSB) & 
> DDR_PLL_DITHER1_NFRAC_MIN_MASK)
> +#define DDR_PLL_DITHER2_NFRAC_MAX_LSB 0
> +#define DDR_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
> +#define DDR_PLL_DITHER2_NFRAC_MAX_SET(x) \
> +     (((x) << DDR_PLL_DITHER2_NFRAC_MAX_LSB) & 
> DDR_PLL_DITHER2_NFRAC_MAX_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB 24
> +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK 0x01000000
> +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB) & 
> CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB 21
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK 0x00200000
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB) & 
> CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB 20
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK 0x00100000
> +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB) & 
> CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB 15
> +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK 0x000f8000
> +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB) & 
> CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB 10
> +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK 0x00007c00
> +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB) & 
> CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB 5
> +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK 0x000003e0
> +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB) & 
> CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB 4
> +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK 0x00000010
> +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB) & 
> CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB 3
> +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK 0x00000008
> +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB) & 
> CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK)
> +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB 2
> +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK 0x00000004
> +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(x) \
> +     (((x) << CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB) & 
> CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK)
> +
> +#define CPU_PLL_CONFIG1_NINT_VAL CPU_PLL_CONFIG1_NINT_SET(0x1f)
> +#define CPU_PLL_CONFIG_REF_DIV_VAL CPU_PLL_CONFIG_REFDIV_SET(0x1)
> +#define CPU_PLL_CONFIG_RANGE_VAL CPU_PLL_CONFIG_RANGE_SET(0)
> +#define CPU_PLL_CONFIG_OUT_DIV_VAL1 CPU_PLL_CONFIG_OUTDIV_SET(0)
> +#define CPU_PLL_CONFIG_OUT_DIV_VAL2 CPU_PLL_CONFIG_OUTDIV_SET(0)
> +#define CPU_PLL_DITHER1_VAL CPU_PLL_DITHER1_DITHER_EN_SET(0) | \
> +     CPU_PLL_DITHER1_NFRAC_MIN_SET(0) | \
> +     CPU_PLL_DITHER1_NFRAC_STEP_SET(0) | \
> +     CPU_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
> +#define CPU_PLL_DITHER2_VAL CPU_PLL_DITHER2_NFRAC_MAX_SET(0x0)
> +#define DDR_PLL_CONFIG1_NINT_VAL DDR_PLL_CONFIG1_NINT_SET(0x1a)
> +#define DDR_PLL_CONFIG_REF_DIV_VAL DDR_PLL_CONFIG_REFDIV_SET(0x1)
> +#define DDR_PLL_CONFIG_RANGE_VAL DDR_PLL_CONFIG_RANGE_SET(0)
> +#define DDR_PLL_CONFIG_OUT_DIV_VAL1 DDR_PLL_CONFIG_OUTDIV_SET(0)
> +#define DDR_PLL_CONFIG_OUT_DIV_VAL2 DDR_PLL_CONFIG_OUTDIV_SET(0)
> +#define DDR_PLL_DITHER1_VAL DDR_PLL_DITHER1_DITHER_EN_SET(0) | \
> +     DDR_PLL_DITHER1_NFRAC_MIN_SET(0) | \
> +     DDR_PLL_DITHER1_NFRAC_STEP_SET(0) | \
> +     DDR_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
> +#define DDR_PLL_DITHER2_VAL DDR_PLL_DITHER2_NFRAC_MAX_SET(0x0)
> +#define AHB_CLK_FROM_DDR CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(0)
> +#define CPU_AND_DDR_CLK_FROM_DDR \
> +     CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(0)
> +#define CPU_AND_DDR_CLK_FROM_CPU \
> +     CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(0)
> +#define CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL \
> +     CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(0x2)
> +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV \
> +     CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(0)
> +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV \
> +     CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(0)
> +
> +static inline void set_val(u32 _reg, u32 _mask, u32 _val)
> +{
> +     void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
> +                                          AR71XX_PLL_SIZE, MAP_NOCACHE);
> +     writel((readl(pll_regs + _reg) & (~(_mask))) | _val, pll_regs + _reg);
> +}
> +
> +#define cpu_pll_set(_mask, _val)     \
> +     set_val(QCA956X_PLL_CPU_CONFIG_REG, _mask, _val)
> +
> +#define ddr_pll_set(_mask, _val)     \
> +     set_val(QCA956X_PLL_DDR_CONFIG_REG, _mask, _val)
> +
> +#define cpu_ddr_control_set(_mask, _val)     \
> +     set_val(QCA956X_PLL_CLK_CTRL_REG, _mask, _val)
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static u32 qca956x_get_xtal(void)
> +{
> +     u32 val;
> +
> +     val = ath79_get_bootstrap();
> +     if (val & QCA956X_BOOTSTRAP_REF_CLK_40)
> +             return 40000000;
> +     else
> +             return 25000000;
> +}
> +
> +int get_serial_clock(void)
> +{
> +     return qca956x_get_xtal();
> +}
> +
> +void qca956x_pll_init(void)
> +{
> +     void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE,
> +                                           QCA956X_SRIF_SIZE, MAP_NOCACHE);
> +     void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
> +                                          AR71XX_PLL_SIZE, MAP_NOCACHE);
> +
> +     /* 8.16.2 Baseband DPLL2 */
> +     writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
> +             PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(1) |
> +             PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + 
> QCA956X_SRIF_BB_DPLL2_REG);
> +
> +     /* 8.16.2 PCIE DPLL2 */
> +     writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
> +             PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(3) |
> +             PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + 
> QCA956X_SRIF_PCIE_DPLL2_REG);
> +
> +     /* 8.16.2 DDR DPLL2 */
> +     writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
> +             PLL_SRIF_DPLL2_PLL_PWD_SET(1) | 
> PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
> +             srif_regs + QCA956X_SRIF_DDR_DPLL2_REG);
> +
> +     /* 8.16.2 CPU DPLL2 */
> +     writel(PLL_SRIF_DPLL2_KI_SET(1) | PLL_SRIF_DPLL2_KD_SET(7) |
> +                       PLL_SRIF_DPLL2_PLL_PWD_SET(1) | 
> PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
> +                       srif_regs + QCA956X_SRIF_CPU_DPLL2_REG);
> +
> +     /* pll_bypass_set */
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1));
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1));
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
> +
> +     /* init_cpu_pll */
> +     cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK,  CPU_PLL_CONFIG_PLLPWD_SET(1));
> +     cpu_pll_set(CPU_PLL_CONFIG_REFDIV_MASK, CPU_PLL_CONFIG_REF_DIV_VAL);
> +     cpu_pll_set(CPU_PLL_CONFIG_RANGE_MASK, CPU_PLL_CONFIG_RANGE_VAL);
> +     cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL1);
> +     set_val(QCA956X_PLL_CPU_CONFIG1_REG, CPU_PLL_CONFIG1_NINT_MASK, \
> +             CPU_PLL_CONFIG1_NINT_VAL);
> +
> +     /* init_ddr_pll */
> +     ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK,  DDR_PLL_CONFIG_PLLPWD_SET(1));
> +     ddr_pll_set(DDR_PLL_CONFIG_REFDIV_MASK, DDR_PLL_CONFIG_REF_DIV_VAL);
> +     ddr_pll_set(DDR_PLL_CONFIG_RANGE_MASK, DDR_PLL_CONFIG_RANGE_VAL);
> +     ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL1);
> +     set_val(QCA956X_PLL_DDR_CONFIG1_REG, DDR_PLL_CONFIG1_NINT_MASK,
> +             DDR_PLL_CONFIG1_NINT_VAL);
> +
> +     /* init_ahb_pll */
> +     writel(CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL | AHB_CLK_FROM_DDR |
> +             CPU_AND_DDR_CLK_FROM_DDR | CPU_AND_DDR_CLK_FROM_CPU |
> +             CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV | 
> CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV |
> +             CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) |
> +             CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) |
> +             CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1), pll_regs + 
> QCA956X_PLL_CLK_CTRL_REG);
> +
> +     /* ddr_pll_dither_unset */
> +     writel(DDR_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_DDR_DIT_FRAC_REG);
> +     writel(DDR_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_DDR_DIT2_FRAC_REG);
> +
> +     /* cpu_pll_dither_unset */
> +     writel(CPU_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_CPU_DIT_FRAC_REG);
> +     writel(CPU_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_CPU_DIT2_FRAC_REG);
> +
> +     /* pll_pwd_unset */
> +     cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0));
> +     ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0));
> +
> +     /* outdiv_unset */
> +     cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2);
> +     ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2);
> +
> +     /* pll_bypass_unset */
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0));
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0));
> +     cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
> +                        CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0));
> +
> +     while (readl(pll_regs + QCA956X_PLL_CPU_CONFIG_REG) & 0x8000000)
> +             /* NOP */;
> +
> +     while (readl(pll_regs + QCA956X_PLL_DDR_CONFIG_REG) & 0x8000000)
> +             /* NOP */;
> +}
> +
> +int get_clocks(void)
> +{
> +     void __iomem *regs;
> +     u32 ref_rate, cpu_rate, ddr_rate, ahb_rate;
> +     u32 out_div, ref_div, postdiv, nint, hfrac, lfrac, clk_ctrl;
> +     u32 pll, cpu_pll, ddr_pll, misc;
> +
> +     /*
> +      * QCA956x timer init workaround has to be applied right before setting
> +      * up the clock. Else, there will be no jiffies
> +      */
> +     regs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
> +                       MAP_NOCACHE);
> +     misc = readl(regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
> +     misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
> +     writel(misc, regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
> +
> +     regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
> +                       MAP_NOCACHE);
> +     pll = readl(regs + QCA956X_PLL_CPU_CONFIG_REG);
> +     out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
> +                       QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
> +     ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
> +                       QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
> +
> +     pll = readl(regs + QCA956X_PLL_CPU_CONFIG1_REG);
> +     nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
> +                       QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
> +     hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
> +                       QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
> +     lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
> +                       QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
> +
> +     ref_rate = qca956x_get_xtal();
> +
> +     cpu_pll = nint * ref_rate / ref_div;
> +     cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
> +     cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
> +     cpu_pll /= (1 << out_div);
> +
> +     pll = readl(regs + QCA956X_PLL_DDR_CONFIG_REG);
> +     out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
> +                       QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
> +     ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
> +                       QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
> +     pll = readl(regs + QCA956X_PLL_DDR_CONFIG1_REG);
> +     nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
> +             QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
> +     hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
> +             QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
> +     lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
> +             QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
> +
> +     ddr_pll = nint * ref_rate / ref_div;
> +     ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
> +     ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
> +     ddr_pll /= (1 << out_div);
> +
> +     clk_ctrl = readl(regs + QCA956X_PLL_CLK_CTRL_REG);
> +
> +     postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
> +               QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
> +
> +     if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
> +             cpu_rate = ref_rate;
> +     else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
> +             cpu_rate = ddr_pll / (postdiv + 1);
> +     else
> +             cpu_rate = cpu_pll / (postdiv + 1);
> +
> +     postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
> +               QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
> +
> +     if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
> +             ddr_rate = ref_rate;
> +     else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
> +             ddr_rate = cpu_pll / (postdiv + 1);
> +     else
> +             ddr_rate = ddr_pll / (postdiv + 1);
> +
> +     postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
> +               QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
> +
> +     if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
> +             ahb_rate = ref_rate;
> +     else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
> +             ahb_rate = ddr_pll / (postdiv + 1);
> +     else
> +             ahb_rate = cpu_pll / (postdiv + 1);
> +
> +     gd->cpu_clk = cpu_rate;
> +     gd->mem_clk = ddr_rate;
> +     gd->bus_clk = ahb_rate;
> +
> +     debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n",
> +             cpu_rate, ddr_rate, ahb_rate);
> +
> +     return 0;
> +}
> +
> +ulong get_bus_freq(ulong dummy)
> +{
> +     if (!gd->bus_clk)
> +             get_clocks();
> +     return gd->bus_clk;
> +}
> +
> +ulong get_ddr_freq(ulong dummy)
> +{
> +     if (!gd->mem_clk)
> +             get_clocks();
> +     return gd->mem_clk;
> +}
> diff --git a/arch/mips/mach-ath79/qca956x/cpu.c 
> b/arch/mips/mach-ath79/qca956x/cpu.c
> new file mode 100644
> index 0000000000..08a8c84e72
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/cpu.c
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +#include <common.h>
> +
> +/* The lowlevel_init() is not needed on QCA956X */
> +void lowlevel_init(void) {}

why? Below you add a lowlevel_init.S?

> diff --git a/arch/mips/mach-ath79/qca956x/ddr.c 
> b/arch/mips/mach-ath79/qca956x/ddr.c
> new file mode 100644
> index 0000000000..b6ea0f9654
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/ddr.c
> @@ -0,0 +1,308 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Rosy Song <rosys...@rosinson.com>
> + *
> + * Based on QSDK
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <mach/ar71xx_regs.h>
> +#include <mach/ath79.h>
> +
> +#define DDR_FSM_WAIT_CTRL_VAL 0xa12
> +#define DDR_CTL_CONFIG_SRAM_TSEL_LSB 30
> +#define DDR_CTL_CONFIG_SRAM_TSEL_MASK 0xc0000000
> +#define DDR_CTL_CONFIG_SRAM_TSEL_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_SRAM_TSEL_LSB) & DDR_CTL_CONFIG_SRAM_TSEL_MASK)
> +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB 20
> +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK 0x00100000
> +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB 19
> +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK 0x00080000
> +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB 18
> +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK 0x00040000
> +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB 17
> +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK 0x00020000
> +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB 16
> +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK 0x00010000
> +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB 15
> +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK 0x00008000
> +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB 14
> +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK 0x00004000
> +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB) & 
> DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK)
> +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB 6
> +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK 0x00000040
> +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB) & 
> DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK)
> +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB 2
> +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK 0x00000004
> +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB) & 
> DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK)
> +#define DDR_CTL_CONFIG_HALF_WIDTH_LSB 1
> +#define DDR_CTL_CONFIG_HALF_WIDTH_MASK 0x00000002
> +#define DDR_CTL_CONFIG_HALF_WIDTH_SET(x) \
> +     (((x) << DDR_CTL_CONFIG_HALF_WIDTH_LSB) & 
> DDR_CTL_CONFIG_HALF_WIDTH_MASK)
> +#define DDR_CONFIG_CAS_LATENCY_MSB_LSB 31
> +#define DDR_CONFIG_CAS_LATENCY_MSB_MASK 0x80000000
> +#define DDR_CONFIG_CAS_LATENCY_MSB_SET(x) \
> +     (((x) << DDR_CONFIG_CAS_LATENCY_MSB_LSB) & 
> DDR_CONFIG_CAS_LATENCY_MSB_MASK)
> +#define DDR_CONFIG_OPEN_PAGE_LSB 30
> +#define DDR_CONFIG_OPEN_PAGE_MASK 0x40000000
> +#define DDR_CONFIG_OPEN_PAGE_SET(x) \
> +     (((x) << DDR_CONFIG_OPEN_PAGE_LSB) & DDR_CONFIG_OPEN_PAGE_MASK)
> +#define DDR_CONFIG_CAS_LATENCY_LSB 27
> +#define DDR_CONFIG_CAS_LATENCY_MASK 0x38000000
> +#define DDR_CONFIG_CAS_LATENCY_SET(x) \
> +     (((x) << DDR_CONFIG_CAS_LATENCY_LSB) & DDR_CONFIG_CAS_LATENCY_MASK)
> +#define DDR_CONFIG_TMRD_LSB 23
> +#define DDR_CONFIG_TMRD_MASK 0x07800000
> +#define DDR_CONFIG_TMRD_SET(x) \
> +     (((x) << DDR_CONFIG_TMRD_LSB) & DDR_CONFIG_TMRD_MASK)
> +#define DDR_CONFIG_TRFC_LSB 17
> +#define DDR_CONFIG_TRFC_MASK 0x007e0000
> +#define DDR_CONFIG_TRFC_SET(x) \
> +     (((x) << DDR_CONFIG_TRFC_LSB) & DDR_CONFIG_TRFC_MASK)
> +#define DDR_CONFIG_TRRD_LSB 13
> +#define DDR_CONFIG_TRRD_MASK 0x0001e000
> +#define DDR_CONFIG_TRRD_SET(x) \
> +     (((x) << DDR_CONFIG_TRRD_LSB) & DDR_CONFIG_TRRD_MASK)
> +#define DDR_CONFIG_TRP_LSB 9
> +#define DDR_CONFIG_TRP_MASK 0x00001e00
> +#define DDR_CONFIG_TRP_SET(x) \
> +     (((x) << DDR_CONFIG_TRP_LSB) & DDR_CONFIG_TRP_MASK)
> +#define DDR_CONFIG_TRCD_LSB 5
> +#define DDR_CONFIG_TRCD_MASK 0x000001e0
> +#define DDR_CONFIG_TRCD_SET(x) \
> +     (((x) << DDR_CONFIG_TRCD_LSB) & DDR_CONFIG_TRCD_MASK)
> +#define DDR_CONFIG_TRAS_LSB 0
> +#define DDR_CONFIG_TRAS_MASK 0x0000001f
> +#define DDR_CONFIG_TRAS_SET(x) \
> +     (((x) << DDR_CONFIG_TRAS_LSB) & DDR_CONFIG_TRAS_MASK)
> +#define DDR_CONFIG2_HALF_WIDTH_LOW_LSB 31
> +#define DDR_CONFIG2_HALF_WIDTH_LOW_MASK 0x80000000
> +#define DDR_CONFIG2_HALF_WIDTH_LOW_SET(x) \
> +     (((x) << DDR_CONFIG2_HALF_WIDTH_LOW_LSB) & 
> DDR_CONFIG2_HALF_WIDTH_LOW_MASK)
> +#define DDR_CONFIG2_SWAP_A26_A27_LSB 30
> +#define DDR_CONFIG2_SWAP_A26_A27_MASK 0x40000000
> +#define DDR_CONFIG2_SWAP_A26_A27_SET(x) \
> +     (((x) << DDR_CONFIG2_SWAP_A26_A27_LSB) & DDR_CONFIG2_SWAP_A26_A27_MASK)
> +#define DDR_CONFIG2_GATE_OPEN_LATENCY_LSB 26
> +#define DDR_CONFIG2_GATE_OPEN_LATENCY_MASK 0x3c000000
> +#define DDR_CONFIG2_GATE_OPEN_LATENCY_SET(x) \
> +     (((x) << DDR_CONFIG2_GATE_OPEN_LATENCY_LSB) & 
> DDR_CONFIG2_GATE_OPEN_LATENCY_MASK)
> +#define DDR_CONFIG2_TWTR_LSB 21
> +#define DDR_CONFIG2_TWTR_MASK 0x03e00000
> +#define DDR_CONFIG2_TWTR_SET(x) \
> +     (((x) << DDR_CONFIG2_TWTR_LSB) & DDR_CONFIG2_TWTR_MASK)
> +#define DDR_CONFIG2_TRTP_LSB 17
> +#define DDR_CONFIG2_TRTP_MASK 0x001e0000
> +#define DDR_CONFIG2_TRTP_SET(x) \
> +     (((x) << DDR_CONFIG2_TRTP_LSB) & DDR_CONFIG2_TRTP_MASK)
> +#define DDR_CONFIG2_TRTW_LSB 12
> +#define DDR_CONFIG2_TRTW_MASK 0x0001f000
> +#define DDR_CONFIG2_TRTW_SET(x) \
> +     (((x) << DDR_CONFIG2_TRTW_LSB) & DDR_CONFIG2_TRTW_MASK)
> +#define DDR_CONFIG2_TWR_LSB 8
> +#define DDR_CONFIG2_TWR_MASK 0x00000f00
> +#define DDR_CONFIG2_TWR_SET(x) \
> +     (((x) << DDR_CONFIG2_TWR_LSB) & DDR_CONFIG2_TWR_MASK)
> +#define DDR_CONFIG2_CKE_LSB 7
> +#define DDR_CONFIG2_CKE_MASK 0x00000080
> +#define DDR_CONFIG2_CKE_SET(x) \
> +     (((x) << DDR_CONFIG2_CKE_LSB) & DDR_CONFIG2_CKE_MASK)
> +#define DDR_CONFIG2_CNTL_OE_EN_LSB 5
> +#define DDR_CONFIG2_CNTL_OE_EN_MASK 0x00000020
> +#define DDR_CONFIG2_CNTL_OE_EN_SET(x) \
> +     (((x) << DDR_CONFIG2_CNTL_OE_EN_LSB) & DDR_CONFIG2_CNTL_OE_EN_MASK)
> +#define DDR_CONFIG2_BURST_LENGTH_LSB 0
> +#define DDR_CONFIG2_BURST_LENGTH_MASK 0x0000000f
> +#define DDR_CONFIG2_BURST_LENGTH_SET(x) \
> +     (((x) << DDR_CONFIG2_BURST_LENGTH_LSB) & DDR_CONFIG2_BURST_LENGTH_MASK)
> +#define RST_BOOTSTRAP_ADDRESS                0x180600b0
> +#define PMU2_SWREGMSB_LSB 22
> +#define PMU2_SWREGMSB_MASK 0xffc00000
> +#define PMU2_SWREGMSB_SET(x) \
> +     (((x) << PMU2_SWREGMSB_LSB) & PMU2_SWREGMSB_MASK)
> +#define PMU2_PGM_LSB 21
> +#define PMU2_PGM_MASK 0x00200000
> +#define PMU2_PGM_SET(x) \
> +     (((x) << PMU2_PGM_LSB) & PMU2_PGM_MASK)
> +
> +#define CPU_DDR_SYNC_MODE DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(0)
> +
> +/*
> +* DDR2                      DDR1
> +* 0x40c3   25MHz            0x4186   25Mhz
> +* 0x4138   40MHz            0x4270   40Mhz
> +*/
> +#define CFG_DDR2_REFRESH_VAL 0x40c3
> +#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
> +     DDR_CONFIG_OPEN_PAGE_SET(0x1) | DDR_CONFIG_CAS_LATENCY_SET(0x4) | \
> +     DDR_CONFIG_TMRD_SET(0x6) | DDR_CONFIG_TRFC_SET(0x16) | \
> +     DDR_CONFIG_TRRD_SET(0x7) | DDR_CONFIG_TRP_SET(0xb) | \
> +     DDR_CONFIG_TRCD_SET(0xb) | DDR_CONFIG_TRAS_SET(0)
> +#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
> +     DDR_CONFIG2_SWAP_A26_A27_SET(0x0) | 
> DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xa) | \
> +     DDR_CONFIG2_TWTR_SET(0x16) | DDR_CONFIG2_TRTP_SET(0xa) | \
> +     DDR_CONFIG2_TRTW_SET(0xe) | DDR_CONFIG2_TWR_SET(0x2) | \
> +     DDR_CONFIG2_CKE_SET(0x1) | DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
> +     DDR_CONFIG2_BURST_LENGTH_SET(0x8)
> +
> +#define CFG_DDR2_CONFIG3_VAL 0x0000000e
> +#define CFG_DDR2_EXT_MODE_VAL1 0x782
> +#define CFG_DDR2_EXT_MODE_VAL2 0x402
> +#define CFG_DDR2_MODE_VAL_INIT 0xb53
> +#define CFG_DDR2_MODE_VAL 0xa53
> +#define CFG_DDR2_TAP_VAL 0x10
> +#define CFG_DDR2_EN_TWL_VAL 0x00001e91
> +#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
> +
> +#define CFG_DDR_CTL_CONFIG DDR_CTL_CONFIG_SRAM_TSEL_SET(0x1) | \
> +     DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(0x1) | \
> +     DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(0x1)
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +void qca956x_ddr_init(void)
> +{
> +     u32 ddr_config, ddr_config2, ddr_config3, mod_val, \
> +             mod_val_init, cycle_val, tap_val, ctl_config;
> +     void __iomem *ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, 
> AR71XX_DDR_CTRL_SIZE,
> +                            MAP_NOCACHE);
> +     void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE, 
> QCA956X_SRIF_SIZE,
> +                            MAP_NOCACHE);
> +
> +     ddr_config = CFG_DDR2_CONFIG_VAL;
> +     ddr_config2 = CFG_DDR2_CONFIG2_VAL;
> +     ddr_config3 = CFG_DDR2_CONFIG3_VAL;
> +     mod_val_init = CFG_DDR2_MODE_VAL_INIT;
> +     mod_val = CFG_DDR2_MODE_VAL;
> +     tap_val = CFG_DDR2_TAP_VAL;
> +     cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16;
> +     ctl_config = CFG_DDR_CTL_CONFIG | DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1) |
> +                      DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1) | CPU_DDR_SYNC_MODE;
> +
> +     writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
> +     udelay(10);
> +
> +     writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
> +     udelay(10);
> +
> +     writel(ctl_config, ddr_regs + QCA956X_DDR_REG_CTL_CONF);
> +     udelay(10);
> +
> +     writel(cycle_val, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
> +     udelay(100);
> +
> +     writel(0x74444444, ddr_regs + QCA956X_DDR_REG_BURST);
> +     udelay(100);
> +
> +     writel(0x44444444, ddr_regs + QCA956X_DDR_REG_BURST2);
> +     udelay(100);
> +
> +     writel(DDR_FSM_WAIT_CTRL_VAL, ddr_regs + QCA956X_DDR_REG_FSM_WAIT_CTRL);
> +     udelay(100);
> +
> +     writel(0xfffff, ddr_regs + QCA956X_DDR_REG_TIMEOUT_MAX);
> +     udelay(100);
> +
> +     writel(ddr_config, ddr_regs + AR71XX_DDR_REG_CONFIG);
> +     udelay(100);
> +
> +     writel(ddr_config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
> +     udelay(100);
> +
> +     writel(ddr_config3, ddr_regs + QCA956X_DDR_REG_DDR3_CONFIG);
> +     udelay(100);
> +
> +     writel(CFG_DDR2_EN_TWL_VAL, ddr_regs + QCA956X_DDR_REG_DDR2_CONFIG);
> +     udelay(100);
> +
> +     writel(ddr_config2 | 0x80, ddr_regs + AR71XX_DDR_REG_CONFIG2);  // CKE 
> Enable
> +     udelay(100);
> +
> +     writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); // Precharge
> +     udelay(10);
> +
> +     writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR2);
> +     writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);        // EMR2
> +     udelay(10);
> +
> +     writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR3);
> +     writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);        // EMR3
> +     udelay(10);
> +
> +     // EMR DLL enable, Reduced Driver Impedance control, Differential DQS 
> disabled

no C++ style comments

> +     writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
> +     udelay(100);
> +
> +     writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
> +     udelay(10);
> +
> +     writel(mod_val_init, ddr_regs + AR71XX_DDR_REG_MODE);
> +     udelay(1000);
> +
> +     writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); // MR Write
> +     udelay(10);
> +
> +     writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); // Precharge
> +     udelay(10);
> +
> +     writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); // Auto Refresh
> +     udelay(10);
> +
> +     writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); // Auto Refresh
> +     udelay(10);
> +
> +     // Issue MRS to remove DLL out-of-reset
> +     writel(mod_val, ddr_regs + AR71XX_DDR_REG_MODE);
> +     udelay(100);
> +
> +     writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); // MR write
> +     udelay(100);
> +
> +     writel(CFG_DDR2_EXT_MODE_VAL1, ddr_regs + AR71XX_DDR_REG_EMR);
> +     udelay(100);
> +
> +     writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
> +     udelay(100);
> +
> +     writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
> +     udelay(100);
> +
> +     writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); // EMR write
> +     udelay(100);
> +
> +     writel(CFG_DDR2_REFRESH_VAL, ddr_regs + AR71XX_DDR_REG_REFRESH);
> +     udelay(100);
> +
> +     writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
> +     writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
> +     writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL2);
> +     writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL3);
> +
> +     writel(0x633c8176, srif_regs + QCA956X_SRIF_PMU1_REG);
> +     // Set DDR2 Voltage to 1.8 volts
> +     writel(PMU2_SWREGMSB_SET(0x40) | PMU2_PGM_SET(0x1),
> +            srif_regs + QCA956X_SRIF_PMU2_REG);
> +}
> diff --git a/arch/mips/mach-ath79/qca956x/lowlevel_init.S 
> b/arch/mips/mach-ath79/qca956x/lowlevel_init.S
> new file mode 100644
> index 0000000000..0580e238bc
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/lowlevel_init.S
> @@ -0,0 +1,79 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018-1029 Rosy Song <rosys...@rosinson.com>
> + * Based on Atheros LSDK/QSDK
> + */
> +
> +#include <config.h>
> +#include <asm/asm.h>
> +#include <asm/regdef.h>
> +#include <asm/mipsregs.h>
> +#include <asm/addrspace.h>
> +#include <mach/ar71xx_regs.h>
> +
> +    .text

this is implied by LEAF() and can be removed

> +    .set noreorder
> +
> +LEAF(lowlevel_init)
> +     li      t0,         CKSEG1ADDR(QCA956X_SRIF_BASE)

all instruction parameters should only be separated by ", "

> +     li      t1,         0x54486000
> +     sw      t1,         QCA953X_SRIF_BB_DPLL2_REG(t0)
> +
> +     li      t1,         0x2e406000
> +     sw      t1,         QCA956X_SRIF_CPU_DPLL2_REG(t0)
> +
> +     li      t1,         0x54406000
> +     sw      t1,         QCA956X_SRIF_DDR_DPLL2_REG(t0)
> +
> +     li      t1,         0x88586000
> +     sw      t1,         QCA956X_SRIF_PCIE_DPLL2_REG(t0)
> +
> +init_cpu_pll:

remove all unused jump labels

> +     li      t0,         CKSEG1ADDR(AR71XX_PLL_BASE)
> +     li      t1,         0x00001000
> +     sw      t1,         QCA956X_PLL_CPU_CONFIG_REG(t0)
> +     li      t1,         0x007c0000
> +     sw      t1,         QCA956X_PLL_CPU_CONFIG1_REG(t0)
> +
> +init_ddr_pll:
> +     li      t1,         0x00010000
> +     sw      t1,         QCA956X_PLL_DDR_CONFIG_REG(t0)
> +     li      t1,         0x00680000
> +     sw      t1,         QCA956X_PLL_DDR_CONFIG1_REG(t0)
> +
> +init_ahb_pll:
> +     li      t1,         0x00010000
> +     sw      t1,         QCA956X_PLL_CLK_CTRL_REG(t0)
> +
> +ddr_pll_dither_unset:
> +     li      t1,         0x00000000
> +     sw      t1,         QCA956X_PLL_DDR_DIT_FRAC_REG(t0)
> +
> +     li      t1,         0x00000000
> +     sw      t1,         QCA956X_PLL_DDR_DIT2_FRAC_REG(t0)
> +
> +cpu_pll_dither_unset:
> +     li      t1,         0x00000000
> +     sw      t1,         QCA956X_PLL_CPU_DIT_FRAC_REG(t0)
> +
> +     li      t1,         0x00000000
> +     sw      t1,         QCA956X_PLL_CPU_DIT2_FRAC_REG(t0)
> +
> +check_cpu_pll_locked:
> +     li  t7, KSEG1ADDR(AR71XX_PLL_BASE);

you already have this address stored in t0 (after init_cpu_pll: )

> +     lw  t8, QCA956X_PLL_CPU_CONFIG_REG(t7);
> +     li  t9, 0x8000000;
> +     and t8, t8, t9;
> +     bne zero, t8, check_cpu_pll_locked;

this needs a "nop" in the delay slot

> +
> +check_ddr_pll_locked:
> +     li  t7, KSEG1ADDR(AR71XX_PLL_BASE);

you already have this address stored in t0 (after init_cpu_pll: )

> +     lw  t8, QCA956X_PLL_DDR_CONFIG_REG(t7);
> +     li  t9, 0x8000000;
> +     and t8, t8, t9;
> +     bne zero, t8, check_ddr_pll_locked;
> +

remove this blank line ...

> +     nop

... and add one here, also all instructions in delay slots should be
indended by an extra space character

> +     jr ra
> +     nop
> +    END(lowlevel_init)
> diff --git a/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S 
> b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
> new file mode 100644
> index 0000000000..fa5f6c1a76
> --- /dev/null
> +++ b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
> @@ -0,0 +1,194 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Rosy Song <rosys...@rosinson.com>
> + *
> + * Based on QSDK
> + */
> +
> +#include <config.h>
> +#include <asm/asm.h>
> +#include <asm/regdef.h>
> +#include <asm/mipsregs.h>
> +#include <asm/addrspace.h>
> +#include <mach/ar71xx_regs.h>
> +
> +    .text

this is implied by LEAF() and can be removed

> +    .set noreorder
> +
> +LEAF(ddr_tap_tuning)
> +     li      a0,     0xbd001f00

all instruction parameters should only be separated by ", "

> +     sw      zero,   0x0(a0)                 // Place where the tap values 
> are saved and used for SWEEP

again no C++ style comments

> +     sw      zero,   0x4(a0)                 // Place where the number of 
> passing taps are saved.
> +     sw      zero,   0x14(a0)                // Place where the last pass 
> tap value is stored
> +     li      a1,     0xaa55aa55              // Indicates that the First 
> pass tap value is not found
> +     sw      a1,     0x10(a0)                // Place where the First pass 
> tap value is stored
> +     nop
> +
> +     li      a0,     0xb8060000              // RESET_BASE_ADDRESS

no magic values, use something like CKSEG1ADDR(QCA956X_RESET_BASE)

> +     lw      a1,     0x1c(a0)                // Reading the RST_RESET_ADDRESS
> +     li      a2,     0x08000000              // Setting the 
> RST_RESET_RTC_RESET
> +     or      a1,     a1,     a2
> +     sw      a1,     0x1c(a0)
> +
> +     li      a3,     0xffffffff
> +     xor     a2,     a2,     a3
> +     and     a1,     a1,     a2
> +     sw      a1,     0x1c(a0)                // Taking the RTC out of RESET
> +     nop
> +
> +     li      a0,     0xb8107000              // RTC_BASE_ADDRESS

no magic values, use something like CKSEG1ADDR(QCA956X_RTC_BASE)

> +     li      a1,     0x1
> +     sw      a1,     0x0040(a0)              // RTC_SYNC_RESET_ADDRESS
> +
> +     li      a2,     0x2
> +
> +_poll_for_RTC_ON:
> +     lw      a1,     0x0044(a0)              // RTC_SYNC_STATUS_ADDRESS
> +     and     a1,     a2,     a1
> +     bne     a1,     a2,     _poll_for_RTC_ON
> +     nop

all instructions in delay slots should be indended by an extra space
character

> +
> +_CHANGE_TAPS:
> +     li      t0,     0xbd001f00              // Read the current value of 
> the TAP for programming
> +     lw      t1,     0x0(t0)
> +     li      t2,     0x00000000
> +     or      t3,     t1,     t2
> +
> +     li      t0,     0xb8000000              // DDR_BASE_ADDRESS
> +     sw      t3,     0x1c(t0)                // TAP_CONTROL_0_ADDRESS
> +     sw      t3,     0x20(t0)                // TAP_CONTROL_1_ADDRESS
> +     sw      t3,     0x24(t0)                // TAP_CONTROL_2_ADDRESS
> +     sw      t3,     0x28(t0)                // TAP_CONTROL_3_ADDRESS
> +
> +     li      t1,     0x00000010              // Running the test 8 times
> +     sw      t1,     0x0068(t0)              // PERF_COMP_ADDR_1_ADDRESS
> +
> +     li      t1,     0xfa5de83f              // 4 Row Address Bits, 4 Column 
> Address Bits, 2 BA bits
> +     sw      t1,     0x002c(t0)              // PERF_MASK_ADDR_0_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0070(t0)              // PERF_COMP_AHB_GE0_1_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0040(t0)              // PERF_COMP_AHB_GE1_0_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0078(t0)              // PERF_COMP_AHB_GE1_1_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0034(t0)              // PERF_MASK_AHB_GE0_0_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x006c(t0)              // PERF_MASK_AHB_GE0_1_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x003c(t0)              // PERF_MASK_AHB_GE1_0_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0074(t0)              // PERF_MASK_AHB_GE1_1_ADDRESS
> +
> +     li      t1,     0x0000ffff
> +     sw      t1,     0x0038(t0)              // PERF_COMP_AHB_GE0_0_ADDRESS
> +
> +     li      t1,     0x00000001
> +     sw      t1,     0x011c(t0)              // DDR_BIST_ADDRESS
> +
> +     li      t2,     0x1
> +
> +_bist_done_poll:
> +     lw      t1,     0x0120(t0)              // DDR_BIST_STATUS_ADDRESS
> +     and     t1,     t1,     t2
> +     bne     t1,     t2,     _bist_done_poll
> +     nop
> +
> +     lw      t1,     0x0120(t0)              // DDR_BIST_STATUS_ADDRESS
> +     li      t4,     0x000001fe
> +     and     t2,     t1,     t4
> +     srl     t2,     t2,     0x1             // no. of Pass Runs
> +
> +     li      t5,     0x00000000
> +     sw      t5,     0x011c(t0)              //DDR_BIST_ADDRESS      - Stop 
> the DDR BIST test
> +
> +     li      t5,     0x0001fe00
> +     and     t5,     t5,     t1
> +     bnez    t5,     _iterate_tap            // This is a redundant compare 
> but nevertheless - Comparing the FAILS
> +     nop
> +
> +     lw      t1,     0x0068(t0)              // PERF_COMP_ADDR_1_ADDRESS
> +     li      t3,     0x000001fe
> +     and     t3,     t3,     t1
> +     srl     t3,     t3,     0x1             // No. of runs in the config 
> register.
> +     bne     t3,     t2,     _iterate_tap
> +     nop
> +
> +pass_tap:
> +     li      t0,     0xbd001f00
> +     lw      t1,     0x4(t0)
> +     addiu   t1,     t1,     0x1
> +     sw      t1,     0x4(t0)
> +
> +     li      t0,     0xbd001f10
> +     lw      t1,     0x0(t0)
> +     li      t2,     0xaa55aa55
> +     beq     t1,     t2,     _first_pass
> +     nop
> +
> +     li      t0,     0xbd001f00
> +     lw      t1,     0x0(t0)
> +     li      t0,     0xbd001f10
> +     sw      t1,     0x4(t0)
> +     nop
> +     b       _iterate_tap
> +     nop
> +
> +_first_pass:
> +     li      t0,     0xbd001f00
> +     lw      t1,     0x0(t0)
> +     li      t0,     0xbd001f10
> +     sw      t1,     0x0(t0)
> +     sw      t1,     0x4(t0)
> +     nop
> +
> +_iterate_tap:
> +     li      t0,     0xbd001f00
> +     lw      t1,     0x0(t0)
> +     li      t2,     0x3f
> +     beq     t1,     t2,     _STOP_TEST
> +     nop
> +
> +     addiu   t1,     t1,     0x1
> +     sw      t1,     0x0(t0)
> +     nop
> +     b       _CHANGE_TAPS
> +     nop
> +
> +_STOP_TEST:
> +     li      t0,     0xbd001f00
> +     lw      t1,     0x4(t0)
> +     bnez    t1,     _load_center_tap
> +     nop
> +
> +     li      t3,     0x8                     // Default Tap to be used
> +     b       _load_tap_into_reg
> +     nop
> +
> +_load_center_tap:
> +     li      t0,     0xbd001f10
> +     lw      t1,     0x0(t0)
> +     lw      t2,     0x4(t0)
> +     add     t3,     t1,     t2
> +     srl     t3,     t3,     0x1
> +     li      t4,     0x3f
> +     and     t3,     t3,     t4
> +
> +_load_tap_into_reg:
> +     li      t0,     0xb8000000
> +     sw      t3,     0x1c(t0)                // TAP_CONTROL_0_ADDRESS
> +     sw      t3,     0x20(t0)                // TAP_CONTROL_1_ADDRESS
> +     sw      t3,     0x24(t0)                // TAP_CONTROL_2_ADDRESS
> +     sw      t3,     0x28(t0)                // TAP_CONTROL_3_ADDRESS
> +
> +     nop
> +     jr ra
> +     nop
> +    END(ddr_tap_tuning)
> diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c
> index 6a94d886f9..0ab3ab6383 100644
> --- a/arch/mips/mach-ath79/reset.c
> +++ b/arch/mips/mach-ath79/reset.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
>   * Copyright (C) 2015-2016 Wills Wang <wills.w...@live.com>
> + * Copyright (C) 2018-2019 Rosy Song <rosys...@rosinson.com>
>   */
>  
>  #include <common.h>
> @@ -11,6 +12,44 @@
>  #include <mach/ath79.h>
>  #include <mach/ar71xx_regs.h>
>  
> +/* QCA956X ETH_SGMII_SERDES Registers */
> +#define SGMII_SERDES_RES_CALIBRATION_LSB 23
> +#define SGMII_SERDES_RES_CALIBRATION_MASK 0x07800000
> +#define SGMII_SERDES_RES_CALIBRATION_SET(x) \
> +     (((x) << SGMII_SERDES_RES_CALIBRATION_LSB) & 
> SGMII_SERDES_RES_CALIBRATION_MASK)
> +#define SGMII_SERDES_CDR_BW_LSB 1
> +#define SGMII_SERDES_CDR_BW_MASK 0x00000006
> +#define SGMII_SERDES_CDR_BW_SET(x) \
> +     (((x) << SGMII_SERDES_CDR_BW_LSB) & SGMII_SERDES_CDR_BW_MASK)
> +#define SGMII_SERDES_TX_DR_CTRL_LSB 4
> +#define SGMII_SERDES_TX_DR_CTRL_MASK 0x00000070
> +#define SGMII_SERDES_TX_DR_CTRL_SET(x) \
> +     (((x) << SGMII_SERDES_TX_DR_CTRL_LSB) & SGMII_SERDES_TX_DR_CTRL_MASK)
> +#define SGMII_SERDES_PLL_BW_LSB 8
> +#define SGMII_SERDES_PLL_BW_MASK 0x00000100
> +#define SGMII_SERDES_PLL_BW_SET(x) \
> +     (((x) << SGMII_SERDES_PLL_BW_LSB) & SGMII_SERDES_PLL_BW_MASK)
> +#define SGMII_SERDES_EN_SIGNAL_DETECT_LSB 16
> +#define SGMII_SERDES_EN_SIGNAL_DETECT_MASK 0x00010000
> +#define SGMII_SERDES_EN_SIGNAL_DETECT_SET(x) \
> +     (((x) << SGMII_SERDES_EN_SIGNAL_DETECT_LSB) & 
> SGMII_SERDES_EN_SIGNAL_DETECT_MASK)
> +#define SGMII_SERDES_FIBER_SDO_LSB 17
> +#define SGMII_SERDES_FIBER_SDO_MASK 0x00020000
> +#define SGMII_SERDES_FIBER_SDO_SET(x) \
> +     (((x) << SGMII_SERDES_FIBER_SDO_LSB) & SGMII_SERDES_FIBER_SDO_MASK)
> +#define SGMII_SERDES_VCO_REG_LSB 27
> +#define SGMII_SERDES_VCO_REG_MASK 0x78000000
> +#define SGMII_SERDES_VCO_REG_SET(x) \
> +     (((x) << SGMII_SERDES_VCO_REG_LSB) & SGMII_SERDES_VCO_REG_MASK)
> +#define SGMII_SERDES_VCO_FAST_LSB 9
> +#define SGMII_SERDES_VCO_FAST_MASK 0x00000200
> +#define SGMII_SERDES_VCO_FAST_GET(x) \
> +     (((x) & SGMII_SERDES_VCO_FAST_MASK) >> SGMII_SERDES_VCO_FAST_LSB)
> +#define SGMII_SERDES_VCO_SLOW_LSB 10
> +#define SGMII_SERDES_VCO_SLOW_MASK 0x00000400
> +#define SGMII_SERDES_VCO_SLOW_GET(x) \
> +     (((x) & SGMII_SERDES_VCO_SLOW_MASK) >> SGMII_SERDES_VCO_SLOW_LSB)
> +
>  void _machine_restart(void)
>  {
>       void __iomem *base;
> @@ -152,6 +191,236 @@ static int eth_init_qca953x(void)
>       return 0;
>  }
>  
> +static int qca956x_sgmii_cal(void)
> +{
> +     int i;
> +     u32 reg, rev_sgmii_val;
> +     u32 vco_fast, vco_slow;
> +     u32 start_val = 0, end_val = 0;
> +     void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
> +                                       MAP_NOCACHE);
> +     void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
> +                                       MAP_NOCACHE);
> +     void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
> +                                       MAP_NOCACHE);
> +     const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII;
> +
> +     writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
> +
> +     reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +     vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
> +     vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
> +
> +     /* Set resistor calibration from 0000 to 1111 */
> +     for (i = 0; i < 0x10; i++) {
> +             reg = (readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
> +                   ~SGMII_SERDES_RES_CALIBRATION_MASK) |
> +                   SGMII_SERDES_RES_CALIBRATION_SET(i);
> +             writel(reg, gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +
> +             udelay(50);
> +
> +             reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +             if (vco_fast != SGMII_SERDES_VCO_FAST_GET(reg) ||
> +                 vco_slow != SGMII_SERDES_VCO_SLOW_GET(reg)) {
> +                     if (start_val == 0) {
> +                             start_val = i;
> +                             end_val = i;
> +                     } else {
> +                             end_val = i;
> +                     }
> +             }
> +             vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
> +             vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
> +     }
> +
> +     if (start_val == 0)
> +             rev_sgmii_val = 0x7;
> +     else
> +             rev_sgmii_val = (start_val + end_val) >> 1;
> +
> +     writel((readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
> +            ~SGMII_SERDES_RES_CALIBRATION_MASK) |
> +            SGMII_SERDES_RES_CALIBRATION_SET(rev_sgmii_val),
> +            gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +
> +     writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
> +
> +     reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +     writel(SGMII_SERDES_CDR_BW_SET(3) | SGMII_SERDES_TX_DR_CTRL_SET(1) |
> +            SGMII_SERDES_PLL_BW_SET(1) | 
> SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) |
> +            SGMII_SERDES_FIBER_SDO_SET(1) | SGMII_SERDES_VCO_REG_SET(3) | 
> reg,
> +            gregs + QCA956X_GMAC_REG_SGMII_SERDES);
> +
> +     setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
> +     mdelay(1);
> +     clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
> +     mdelay(1);
> +
> +     while (!(readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & BIT(15)))
> +             /* NOP */;
> +
> +     return 0;
> +}
> +
> +static int qca956x_sgmii_setup(void)
> +{
> +     int i;
> +     u32 s = 0, reg = 0;
> +     u32 _regs[] = {
> +             BIT(4), /* HW_RX_125M_N */
> +             BIT(2), /* RX_125M_N */
> +             BIT(3), /* TX_125M_N */
> +             BIT(0), /* RX_CLK_N */
> +             BIT(1), /* TX_CLK_N */
> +     };
> +     void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
> +                                       MAP_NOCACHE);
> +
> +     /* Force sgmii mode */
> +     writel(BIT(6) | BIT(15) | BIT(8), gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
> +     udelay(10);
> +     writel(0x2 | BIT(5) | (0x2 << 6), gregs + 
> QCA956X_GMAC_REG_SGMII_CONFIG);
> +
> +     /* SGMII reset sequence sugguest by qca systems team. */
> +     writel(0, gregs + QCA956X_GMAC_REG_SGMII_RESET);
> +     for (i = 0; i < ARRAY_SIZE(_regs); i++) {
> +             reg |= _regs[i];
> +             writel(reg, gregs + QCA956X_GMAC_REG_SGMII_RESET);
> +     }
> +
> +     writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
> +            gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
> +
> +     /*
> +      * WARNING: Across resets SGMII link status goes to weird state.
> +      * if 0xb8070058 (SGMII_DEBUG Register) reads other than 0xf or 0x10
> +      * for sure we are in bad state.
> +      * Issue a PHY RESET in MR_AN_CONTROL_ADDRESS to keep going.
> +      */
> +     i = 0;
> +     s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
> +     while (!(s == 0xf || s == 0x10)) {
> +             writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) | BIT(15),
> +                    gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
> +             udelay(100);
> +             writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
> +                    gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
> +             if (i++ == 10)
> +                     break;
> +             s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
> +     }
> +
> +     return 0;
> +}
> +
> +static int qca956x_s17_reset(void)
> +{
> +     void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
> +                                       MAP_NOCACHE);
> +     void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
> +                                       MAP_NOCACHE);
> +     const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
> +                      QCA956X_RESET_EXTERNAL | QCA956X_RESET_SGMII_ANALOG |
> +                      QCA956X_RESET_SWITCH;
> +     /* Bits(Reserved in datasheet) should be set to 1 */
> +     const u32 mask_r = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
> +                      QCA956X_RESET_EXTERNAL;
> +
> +     setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
> +     mdelay(1);
> +     clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask_r);
> +     mdelay(1);
> +
> +     /* Reset s17 switch(GPIO11) SYS_RST_L */
> +     writel(readl(regs + AR71XX_GPIO_REG_OE) & ~BIT(11),
> +            regs + AR71XX_GPIO_REG_OE);
> +     udelay(100);
> +
> +     writel(readl(regs + AR71XX_GPIO_REG_OUT) & ~BIT(11),
> +            regs + AR71XX_GPIO_REG_OUT);
> +     udelay(100);
> +     writel(readl(regs + AR71XX_GPIO_REG_OUT) | BIT(11),
> +            regs + AR71XX_GPIO_REG_OUT);
> +
> +     return 0;
> +}
> +
> +static int qca956x_init_mdio(void)
> +{
> +     u32 reg;
> +     void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
> +                                             MAP_NOCACHE);
> +     void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
> +                                       MAP_NOCACHE);
> +     const u32 mask = QCA956X_RESET_GE0_MDIO | QCA956X_RESET_GE0_MAC |
> +                      QCA956X_RESET_GE1_MDIO | QCA956X_RESET_GE1_MAC;
> +
> +     setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
> +     mdelay(1);
> +     clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
> +     mdelay(1);
> +
> +     /* GPIO4 as MDI */
> +     reg = readl(regs + QCA956X_GPIO_REG_IN_ENABLE3);
> +     reg &= ~(0xff << 16);
> +     reg |= (0x4 << 16);
> +     writel(reg, regs + QCA956X_GPIO_REG_IN_ENABLE3);
> +
> +     /* GPIO4 as MDO */
> +     reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC1);
> +     reg &= ~0xff;
> +     reg |= 0x20;
> +     writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC1);
> +
> +     /* Init MDC(GPIO3) / MDIO(GPIO4) */
> +     reg = readl(regs + AR71XX_GPIO_REG_OE);
> +     reg &= ~BIT(4);
> +     writel(reg, regs + AR71XX_GPIO_REG_OE);
> +     udelay(100);
> +
> +     reg = readl(regs + AR71XX_GPIO_REG_OE);
> +     reg &= ~BIT(3);
> +     writel(reg, regs + AR71XX_GPIO_REG_OE);
> +     udelay(100);
> +
> +     /* GPIO3 as MDI */
> +     reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC0);
> +     reg &= ~(0xff << 24);
> +     reg |= (0x21 << 24);
> +     writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC0);
> +
> +     return 0;
> +}
> +
> +static int eth_init_qca956x(void)
> +{
> +     void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
> +                                       MAP_NOCACHE);
> +     void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
> +                                       MAP_NOCACHE);
> +
> +     qca956x_sgmii_cal();
> +     qca956x_s17_reset();
> +     qca956x_init_mdio();
> +
> +     if (ath79_get_bootstrap() & QCA956X_BOOTSTRAP_REF_CLK_40)
> +             writel(0x45500, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
> +     else
> +             writel(0xc5200, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
> +
> +     qca956x_sgmii_setup();
> +
> +     writel((3 << 16) | (3 << 14) | (1 << 0) | (1 << 6),
> +            gregs + QCA956X_GMAC_REG_ETH_CFG);
> +
> +     writel((1 << 31) | (2 << 28) | (2 << 26) | (1 << 25),
> +            pregs + QCA956X_PLL_ETH_XMII_CTRL_REG);
> +     mdelay(1);
> +
> +     return 0;
> +}
> +
>  int ath79_eth_reset(void)
>  {
>       /*
> @@ -164,6 +433,8 @@ int ath79_eth_reset(void)
>               return eth_init_ar934x();
>       if (soc_is_qca953x())
>               return eth_init_qca953x();
> +     if (soc_is_qca956x())
> +             return eth_init_qca956x();
>  
>       return -EINVAL;
>  }
> diff --git a/board/qca/ap152/Kconfig b/board/qca/ap152/Kconfig
> new file mode 100644
> index 0000000000..a3d82780fe
> --- /dev/null
> +++ b/board/qca/ap152/Kconfig
> @@ -0,0 +1,27 @@
> +if TARGET_AP152
> +
> +config SYS_VENDOR
> +     default "qca"
> +
> +config SYS_BOARD
> +     default "ap152"
> +
> +config SYS_CONFIG_NAME
> +     default "ap152"
> +
> +config SYS_TEXT_BASE
> +     default 0x9f000000
> +
> +config SYS_DCACHE_SIZE
> +     default 32768
> +
> +config SYS_DCACHE_LINE_SIZE
> +     default 32
> +
> +config SYS_ICACHE_SIZE
> +     default 65536
> +
> +config SYS_ICACHE_LINE_SIZE
> +     default 32

don't define this and try to use the automatic cache size detection

> +
> +endif
> diff --git a/board/qca/ap152/MAINTAINERS b/board/qca/ap152/MAINTAINERS
> new file mode 100644
> index 0000000000..785ec2766d
> --- /dev/null
> +++ b/board/qca/ap152/MAINTAINERS
> @@ -0,0 +1,6 @@
> +AP152 BOARD
> +M:   Rosy Song <rosys...@rosinson.com>
> +S:   Maintained
> +F:   board/qca/ap152/
> +F:   include/configs/ap152.h
> +F:   configs/ap152_defconfig
> diff --git a/board/qca/ap152/Makefile b/board/qca/ap152/Makefile
> new file mode 100644
> index 0000000000..4270afa129
> --- /dev/null
> +++ b/board/qca/ap152/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-y        = ap152.o
> diff --git a/board/qca/ap152/ap152.c b/board/qca/ap152/ap152.c
> new file mode 100644
> index 0000000000..30cd56563b
> --- /dev/null
> +++ b/board/qca/ap152/ap152.c
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <mach/ar71xx_regs.h>
> +#include <mach/ddr.h>
> +#include <mach/ath79.h>
> +#include <debug_uart.h>
> +
> +#define RST_RESET_RTC_RESET_LSB 27
> +#define RST_RESET_RTC_RESET_MASK 0x08000000
> +#define RST_RESET_RTC_RESET_SET(x) \
> +     (((x) << RST_RESET_RTC_RESET_LSB) & RST_RESET_RTC_RESET_MASK)
> +
> +#ifdef CONFIG_DEBUG_UART_BOARD_INIT
> +void board_debug_uart_init(void)
> +{
> +     void __iomem *regs;
> +     u32 val;
> +
> +     regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
> +                        MAP_NOCACHE);
> +
> +     /* UART : RX18, TX22 done
> +      * GPIO18 as input, GPIO22 as output
> +      */
> +     val = readl(regs + AR71XX_GPIO_REG_OE);
> +     val |= QCA956X_GPIO(18);
> +     val &= ~QCA956X_GPIO(22);
> +     writel(val, regs + AR71XX_GPIO_REG_OE);
> +
> +     /*
> +      * Enable GPIO22 as UART0_SOUT
> +      */
> +     val = readl(regs + QCA956X_GPIO_REG_OUT_FUNC5);
> +     val &= ~QCA956X_GPIO_MUX_MASK(16);
> +     val |= QCA956X_GPIO_OUT_MUX_UART0_SOUT << 16;
> +     writel(val, regs + QCA956X_GPIO_REG_OUT_FUNC5);
> +
> +     /*
> +      * Enable GPIO18 as UART0_SIN
> +      */
> +     val = readl(regs + QCA956X_GPIO_REG_IN_ENABLE0);
> +     val &= ~QCA956X_GPIO_MUX_MASK(8);
> +     val |= QCA956X_GPIO_IN_MUX_UART0_SIN << 8;
> +     writel(val, regs + QCA956X_GPIO_REG_IN_ENABLE0);
> +
> +     /*
> +      * Enable GPIO22 output
> +      */
> +     val = readl(regs + AR71XX_GPIO_REG_OUT);
> +     val |= QCA956X_GPIO(22);
> +     writel(val, regs + AR71XX_GPIO_REG_OUT);
> +}
> +#endif
> +
> +int board_early_init_f(void)
> +{
> +     u32 reg;
> +     void __iomem *rst_regs = map_physmem(AR71XX_RESET_BASE,
> +                                                      AR71XX_RESET_SIZE, 
> MAP_NOCACHE);
> +
> +#ifndef CONFIG_SKIP_LOWLEVEL_INIT
> +     /* CPU:775, DDR:650, AHB:258 */
> +     qca956x_pll_init();
> +     qca956x_ddr_init();
> +#endif
> +
> +     /* Take WMAC out of reset */
> +     reg = readl(rst_regs + QCA956X_RESET_REG_RESET_MODULE);
> +     reg &= (~RST_RESET_RTC_RESET_SET(1));
> +     writel(reg, rst_regs + QCA956X_RESET_REG_RESET_MODULE);
> +
> +     ath79_eth_reset();
> +     return 0;
> +}
> diff --git a/configs/ap152_defconfig b/configs/ap152_defconfig
> new file mode 100644
> index 0000000000..383c48b03d
> --- /dev/null
> +++ b/configs/ap152_defconfig
> @@ -0,0 +1,55 @@
> +CONFIG_MIPS=y
> +CONFIG_SYS_TEXT_BASE=0x9F000000
> +CONFIG_SYS_MALLOC_F_LEN=0x800
> +CONFIG_DEBUG_UART_BOARD_INIT=y
> +CONFIG_DEBUG_UART_BASE=0xb8020000
> +CONFIG_DEBUG_UART_CLOCK=25000000
> +CONFIG_ARCH_ATH79=y
> +CONFIG_TARGET_AP152=y
> +CONFIG_DEBUG_UART=y
> +CONFIG_BOOTDELAY=3
> +CONFIG_USE_BOOTARGS=y
> +CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/mtdblock2 
> rootfstype=squashfs"

doesn't use the Linux serial driver something like "ttyATH0" ?

> +CONFIG_DISPLAY_CPUINFO=y
> +CONFIG_BOARD_EARLY_INIT_F=y
> +CONFIG_SYS_PROMPT="ap152 # "
> +# CONFIG_CMD_BDI is not set
> +# CONFIG_CMD_CONSOLE is not set
> +# CONFIG_CMD_ELF is not set
> +# CONFIG_CMD_XIMG is not set
> +# CONFIG_CMD_EXPORTENV is not set
> +# CONFIG_CMD_IMPORTENV is not set
> +# CONFIG_CMD_EDITENV is not set
> +# CONFIG_CMD_CRC32 is not set
> +CONFIG_CMD_MEMTEST=y
> +# CONFIG_CMD_FLASH is not set
> +CONFIG_CMD_SF=y
> +CONFIG_CMD_SPI=y
> +CONFIG_CMD_MTDPARTS=y
> +CONFIG_MTDIDS_DEFAULT="nor0=spi-flash.0"
> +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-flash.0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1472k(uImage),64k(ART)"
> +# CONFIG_ISO_PARTITION is not set
> +CONFIG_DEFAULT_DEVICE_TREE="ap152"
> +CONFIG_ENV_IS_IN_SPI_FLASH=y
> +# CONFIG_NET is not set
> +CONFIG_DM_SPI_FLASH=y
> +CONFIG_SPI_FLASH=y
> +CONFIG_SPI_FLASH_BAR=y
> +CONFIG_SPI_FLASH_ATMEL=y
> +CONFIG_SPI_FLASH_EON=y
> +CONFIG_SPI_FLASH_GIGADEVICE=y
> +CONFIG_SPI_FLASH_MACRONIX=y
> +CONFIG_SPI_FLASH_SPANSION=y
> +CONFIG_SPI_FLASH_STMICRO=y
> +CONFIG_SPI_FLASH_SST=y
> +CONFIG_SPI_FLASH_WINBOND=y
> +CONFIG_SPI_FLASH_DATAFLASH=y

do you really need all possible flash vendors?

> +CONFIG_SPI_FLASH_MTD=y
> +CONFIG_PINCTRL=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_DEBUG_UART_SHIFT=2
> +CONFIG_SYS_NS16550=y
> +CONFIG_SPI=y
> +CONFIG_DM_SPI=y
> +CONFIG_ATH79_SPI=y
> +CONFIG_LZMA=y
> diff --git a/include/configs/ap152.h b/include/configs/ap152.h
> new file mode 100644
> index 0000000000..bc88506dff
> --- /dev/null
> +++ b/include/configs/ap152.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Rosy Song <rosys...@rosinson.com>
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#define CONFIG_SYS_HZ                   1000
> +#define CONFIG_SYS_MHZ                  375
> +#define CONFIG_SYS_MIPS_TIMER_FREQ      (CONFIG_SYS_MHZ * 1000000)
> +
> +#define CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
> +
> +#define CONFIG_SYS_MALLOC_LEN           0x40000
> +#define CONFIG_SYS_BOOTPARAMS_LEN       0x20000
> +
> +#define CONFIG_SYS_SDRAM_BASE           0x80000000
> +#define CONFIG_SYS_LOAD_ADDR            0x81000000
> +
> +#define CONFIG_SYS_INIT_RAM_ADDR        0xbd000000
> +#define CONFIG_SYS_INIT_RAM_SIZE        0x2000
> +#define CONFIG_SYS_INIT_SP_ADDR \
> +     (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
> +
> +/*
> + * Serial Port
> + */
> +#define CONFIG_SYS_NS16550_CLK          25000000
> +#define CONFIG_SYS_BAUDRATE_TABLE \
> +     {9600, 19200, 38400, 57600, 115200}
> +
> +#define CONFIG_BOOTCOMMAND              "sf probe;" \
> +                                     "mtdparts default;" \
> +                                     "bootm 0x9f060000"
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +     "ipaddr=192.168.1.1\0" \
> +     "serverip=192.168.1.10\0" \
> +
> +#define CONFIG_ENV_SPI_MAX_HZ           25000000
> +#define CONFIG_ENV_OFFSET               0x40000
> +#define CONFIG_ENV_SECT_SIZE            0x10000
> +#define CONFIG_ENV_SIZE                 0x10000
> +
> +/* Miscellaneous configurable options */
> +
> +/*
> + * Diagnostics
> + */
> +#define CONFIG_SYS_MEMTEST_START        0x80100000
> +#define CONFIG_SYS_MEMTEST_END          0x83f00000
> +
> +#endif  /* __CONFIG_H */
> 

-- 
- Daniel
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to