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