mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 17:18:59 +00:00
91e57a42e2
Add initial support for Qualcomm Atheros QCA955x series SoCs. This support was based on the QCA956x support, QSDK, GPL tar of TP-Link Archer C5 v1.20. Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com> Link: https://github.com/openwrt/openwrt/pull/16297 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
1021 lines
32 KiB
Diff
1021 lines
32 KiB
Diff
From 7c59f0fe98eb20db8dfbf4d3c67d6043a9efe116 Mon Sep 17 00:00:00 2001
|
|
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
|
Date: Sat, 22 Jun 2024 20:45:31 +0900
|
|
Subject: [PATCH 1/2] mips: ath79: add initial support for QCA955x SoCs
|
|
|
|
---
|
|
arch/mips/dts/qca955x.dtsi | 70 +++++
|
|
arch/mips/mach-ath79/Kconfig | 9 +
|
|
arch/mips/mach-ath79/Makefile | 1 +
|
|
.../mach-ath79/include/mach/ar71xx_regs.h | 63 ++++
|
|
arch/mips/mach-ath79/include/mach/ath79.h | 3 +
|
|
arch/mips/mach-ath79/qca955x/Makefile | 5 +
|
|
arch/mips/mach-ath79/qca955x/clk.c | 286 ++++++++++++++++++
|
|
arch/mips/mach-ath79/qca955x/cpu.c | 7 +
|
|
arch/mips/mach-ath79/qca955x/ddr.c | 222 ++++++++++++++
|
|
.../mips/mach-ath79/qca955x/qca955x-ddr-tap.S | 191 ++++++++++++
|
|
10 files changed, 857 insertions(+)
|
|
create mode 100644 arch/mips/dts/qca955x.dtsi
|
|
create mode 100644 arch/mips/mach-ath79/qca955x/Makefile
|
|
create mode 100644 arch/mips/mach-ath79/qca955x/clk.c
|
|
create mode 100644 arch/mips/mach-ath79/qca955x/cpu.c
|
|
create mode 100644 arch/mips/mach-ath79/qca955x/ddr.c
|
|
create mode 100644 arch/mips/mach-ath79/qca955x/qca955x-ddr-tap.S
|
|
|
|
diff --git a/arch/mips/dts/qca955x.dtsi b/arch/mips/dts/qca955x.dtsi
|
|
new file mode 100644
|
|
index 0000000000..93bc659743
|
|
--- /dev/null
|
|
+++ b/arch/mips/dts/qca955x.dtsi
|
|
@@ -0,0 +1,70 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (C) 2024 INAGAKI Hiroshi <musashino.open@gmail.com>
|
|
+ */
|
|
+
|
|
+#include "skeleton.dtsi"
|
|
+
|
|
+/ {
|
|
+ compatible = "qca,qca955x";
|
|
+
|
|
+ #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";
|
|
+ };
|
|
+ };
|
|
+
|
|
+ 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 2fa628568a..21ac4b9f95 100644
|
|
--- a/arch/mips/mach-ath79/Kconfig
|
|
+++ b/arch/mips/mach-ath79/Kconfig
|
|
@@ -34,6 +34,15 @@ config SOC_QCA953X
|
|
help
|
|
This supports QCA/Atheros qca953x family SOCs.
|
|
|
|
+config SOC_QCA955X
|
|
+ bool
|
|
+ select MIPS_TUNE_74KC
|
|
+ select SUPPORT_BIG_ENDIAN
|
|
+ select SUPPORTS_CPU_MIPS32_R1
|
|
+ select SUPPORTS_CPU_MIPS32_R2
|
|
+ help
|
|
+ This supports QCA/Atheros qca955x family SOCs.
|
|
+
|
|
config SOC_QCA956X
|
|
bool
|
|
select MIPS_TUNE_74KC
|
|
diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
|
|
index fbd40c02be..cd8c1f0334 100644
|
|
--- a/arch/mips/mach-ath79/Makefile
|
|
+++ b/arch/mips/mach-ath79/Makefile
|
|
@@ -7,4 +7,5 @@ obj-y += dram.o
|
|
obj-$(CONFIG_SOC_AR933X) += ar933x/
|
|
obj-$(CONFIG_SOC_AR934X) += ar934x/
|
|
obj-$(CONFIG_SOC_QCA953X) += qca953x/
|
|
+obj-$(CONFIG_SOC_QCA955X) += qca955x/
|
|
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 5888f6eb28..1e4860ec9c 100644
|
|
--- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
|
|
+++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
|
|
@@ -174,11 +174,17 @@
|
|
#define QCA955X_WMAC_BASE \
|
|
(AR71XX_APB_BASE + 0x00100000)
|
|
#define QCA955X_WMAC_SIZE 0x20000
|
|
+#define QCA955X_RTC_BASE \
|
|
+ (AR71XX_APB_BASE + 0x00107000)
|
|
+#define QCA955X_RTC_SIZE 0x1000
|
|
#define QCA955X_EHCI0_BASE 0x1b000000
|
|
#define QCA955X_EHCI1_BASE 0x1b400000
|
|
#define QCA955X_EHCI_SIZE 0x1000
|
|
#define QCA955X_NFC_BASE 0x1b800200
|
|
#define QCA955X_NFC_SIZE 0xb8
|
|
+#define QCA955X_SRIF_BASE \
|
|
+ (AR71XX_APB_BASE + 0x00116000)
|
|
+#define QCA955X_SRIF_SIZE 0x1000
|
|
|
|
#define QCA956X_PCI_MEM_BASE1 0x12000000
|
|
#define QCA956X_PCI_MEM_SIZE 0x02000000
|
|
@@ -285,6 +291,17 @@
|
|
#define QCA953X_DDR_REG_CTL_CONF 0x108
|
|
#define QCA953X_DDR_REG_CONFIG3 0x15c
|
|
|
|
+#define QCA955X_DDR_REG_TAP_CTRL2 0x24
|
|
+#define QCA955X_DDR_REG_TAP_CTRL3 0x28
|
|
+#define QCA955X_DDR_REG_DDR2_CONFIG 0xb8
|
|
+#define QCA955X_DDR_REG_DDR2_EMR2 0xbc
|
|
+#define QCA955X_DDR_REG_DDR2_EMR3 0xc0
|
|
+#define QCA955X_DDR_REG_BURST 0xc4
|
|
+#define QCA955X_DDR_REG_BURST2 0xc8
|
|
+#define QCA955X_DDR_REG_TIMEOUT_MAX 0xcc
|
|
+#define QCA955X_DDR_REG_CTL_CONF 0x108
|
|
+#define QCA955X_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
|
|
@@ -500,6 +517,8 @@
|
|
#define QCA955X_PLL_DDR_CONFIG_REG 0x04
|
|
#define QCA955X_PLL_CLK_CTRL_REG 0x08
|
|
#define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
|
|
+#define QCA955X_PLL_DDR_DIT_FRAC_REG 0x40
|
|
+#define QCA955X_PLL_CPU_DIT_FRAC_REG 0x44
|
|
#define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
|
|
|
|
#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
|
|
@@ -508,8 +527,11 @@
|
|
#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f
|
|
#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
|
|
#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
|
|
+#define QCA955X_PLL_CPU_CONFIG_RANGE_SHIFT 17
|
|
+#define QCA955X_PLL_CPU_CONFIG_RANGE_MASK 0x3
|
|
#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
|
|
#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
|
|
+#define QCA955X_PLL_CPU_CONFIG_PLLPWD BIT(30)
|
|
|
|
#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
|
|
#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
|
|
@@ -517,8 +539,11 @@
|
|
#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f
|
|
#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
|
|
#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
|
|
+#define QCA955X_PLL_DDR_CONFIG_RANGE_SHIFT 21
|
|
+#define QCA955X_PLL_DDR_CONFIG_RANGE_MASK 0x3
|
|
#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
|
|
#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
|
|
+#define QCA955X_PLL_DDR_CONFIG_PLLPWD BIT(30)
|
|
|
|
#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
|
|
#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
|
|
@@ -533,6 +558,24 @@
|
|
#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
|
|
#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
|
|
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MAX_SHIFT 0
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MAX_MASK 0x3ff
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MIN_SHIFT 10
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MIN_MASK 0x3ff
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_STEP_SHIFT 20
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_STEP_MASK 0x7f
|
|
+#define QCA955X_PLL_DDR_DIT_UPD_CNT_SHIFT 27
|
|
+#define QCA955X_PLL_DDR_DIT_UPD_CNT_MASK 0xf
|
|
+
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MAX_SHIFT 0
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MAX_MASK 0x3f
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MIN_SHIFT 6
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MIN_MASK 0x3f
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_STEP_SHIFT 12
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_STEP_MASK 0x3f
|
|
+#define QCA955X_PLL_CPU_DIT_UPD_CNT_SHIFT 18
|
|
+#define QCA955X_PLL_CPU_DIT_UPD_CNT_MASK 0x3f
|
|
+
|
|
#define QCA956X_PLL_CPU_CONFIG_REG 0x00
|
|
#define QCA956X_PLL_CPU_CONFIG1_REG 0x04
|
|
#define QCA956X_PLL_DDR_CONFIG_REG 0x08
|
|
@@ -1027,6 +1070,7 @@
|
|
#define QCA955X_GPIO_REG_OUT_FUNC3 0x38
|
|
#define QCA955X_GPIO_REG_OUT_FUNC4 0x3c
|
|
#define QCA955X_GPIO_REG_OUT_FUNC5 0x40
|
|
+#define QCA955X_GPIO_REG_IN_ENABLE0 0x44
|
|
#define QCA955X_GPIO_REG_FUNC 0x6c
|
|
|
|
#define QCA956X_GPIO_REG_OUT_FUNC0 0x2c
|
|
@@ -1220,6 +1264,25 @@
|
|
#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13
|
|
#define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7
|
|
|
|
+#define QCA955X_SRIF_BB_DPLL1_REG 0x180
|
|
+#define QCA955X_SRIF_BB_DPLL2_REG 0x184
|
|
+#define QCA955X_SRIF_BB_DPLL3_REG 0x188
|
|
+
|
|
+#define QCA955X_SRIF_CPU_DPLL1_REG 0xf00
|
|
+#define QCA955X_SRIF_CPU_DPLL2_REG 0xf04
|
|
+#define QCA955X_SRIF_CPU_DPLL3_REG 0xf08
|
|
+
|
|
+#define QCA955X_SRIF_DDR_DPLL1_REG 0xec0
|
|
+#define QCA955X_SRIF_DDR_DPLL2_REG 0xec4
|
|
+#define QCA955X_SRIF_DDR_DPLL3_REG 0xec8
|
|
+
|
|
+#define QCA955X_SRIF_PCIE_DPLL1_REG 0xc80
|
|
+#define QCA955X_SRIF_PCIE_DPLL2_REG 0xc84
|
|
+#define QCA955X_SRIF_PCIE_DPLL3_REG 0xc88
|
|
+
|
|
+#define QCA955X_SRIF_PMU1_REG 0xcc0
|
|
+#define QCA955X_SRIF_PMU2_REG 0xcc4
|
|
+
|
|
#define QCA956X_SRIF_BB_DPLL1_REG 0x180
|
|
#define QCA956X_SRIF_BB_DPLL2_REG 0x184
|
|
#define QCA956X_SRIF_BB_DPLL3_REG 0x188
|
|
diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h
|
|
index 2eda38885e..445cb2711b 100644
|
|
--- a/arch/mips/mach-ath79/include/mach/ath79.h
|
|
+++ b/arch/mips/mach-ath79/include/mach/ath79.h
|
|
@@ -148,6 +148,9 @@ 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 qca955x_pll_init(void);
|
|
+void qca955x_ddr_init(void);
|
|
+
|
|
void qca956x_pll_init(void);
|
|
void qca956x_ddr_init(void);
|
|
#endif /* __ASM_MACH_ATH79_H */
|
|
diff --git a/arch/mips/mach-ath79/qca955x/Makefile b/arch/mips/mach-ath79/qca955x/Makefile
|
|
new file mode 100644
|
|
index 0000000000..a405f9a12d
|
|
--- /dev/null
|
|
+++ b/arch/mips/mach-ath79/qca955x/Makefile
|
|
@@ -0,0 +1,5 @@
|
|
+# SPDX-License-Identifier: GPL-2.0+
|
|
+
|
|
+obj-y += cpu.o
|
|
+obj-y += clk.o
|
|
+obj-y += ddr.o qca955x-ddr-tap.o
|
|
diff --git a/arch/mips/mach-ath79/qca955x/clk.c b/arch/mips/mach-ath79/qca955x/clk.c
|
|
new file mode 100644
|
|
index 0000000000..20c93de163
|
|
--- /dev/null
|
|
+++ b/arch/mips/mach-ath79/qca955x/clk.c
|
|
@@ -0,0 +1,286 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (C) 2024 INAGAKI Hiroshi <musashino.open@gmail.com>
|
|
+ *
|
|
+ * based on QCA956x support and QSDK
|
|
+ */
|
|
+
|
|
+#include <clock_legacy.h>
|
|
+#include <log.h>
|
|
+#include <asm/global_data.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/addrspace.h>
|
|
+#include <asm/types.h>
|
|
+#include <linux/bitfield.h>
|
|
+#include <linux/bitops.h>
|
|
+#include <mach/ar71xx_regs.h>
|
|
+#include <mach/ath79.h>
|
|
+#include <wait_bit.h>
|
|
+
|
|
+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_FMASK \
|
|
+ QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK \
|
|
+ << QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT
|
|
+#define QCA955X_PLL_CPU_CONFIG_RANGE_FMASK \
|
|
+ QCA955X_PLL_CPU_CONFIG_RANGE_MASK \
|
|
+ << QCA955X_PLL_CPU_CONFIG_RANGE_SHIFT
|
|
+#define QCA955X_PLL_CPU_CONFIG_REFDIV_FMASK \
|
|
+ QCA955X_PLL_CPU_CONFIG_REFDIV_MASK \
|
|
+ << QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT
|
|
+#define QCA955X_PLL_CPU_CONFIG_NINT_FMASK \
|
|
+ QCA955X_PLL_CPU_CONFIG_NINT_MASK \
|
|
+ << QCA955X_PLL_CPU_CONFIG_NINT_SHIFT
|
|
+#define QCA955X_PLL_CPU_CONFIG_NFRAC_FMASK \
|
|
+ QCA955X_PLL_CPU_CONFIG_NFRAC_MASK \
|
|
+ << QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT
|
|
+
|
|
+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_FMASK \
|
|
+ QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK \
|
|
+ << QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT
|
|
+#define QCA955X_PLL_DDR_CONFIG_RANGE_FMASK \
|
|
+ QCA955X_PLL_DDR_CONFIG_RANGE_MASK \
|
|
+ << QCA955X_PLL_DDR_CONFIG_RANGE_SHIFT
|
|
+#define QCA955X_PLL_DDR_CONFIG_REFDIV_FMASK \
|
|
+ QCA955X_PLL_DDR_CONFIG_REFDIV_MASK \
|
|
+ << QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT
|
|
+#define QCA955X_PLL_DDR_CONFIG_NINT_FMASK \
|
|
+ QCA955X_PLL_DDR_CONFIG_NINT_MASK \
|
|
+ << QCA955X_PLL_DDR_CONFIG_NINT_SHIFT
|
|
+#define QCA955X_PLL_DDR_CONFIG_NFRAC_FMASK \
|
|
+ QCA955X_PLL_DDR_CONFIG_NFRAC_MASK \
|
|
+ << QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT
|
|
+
|
|
+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_FMASK \
|
|
+ QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK \
|
|
+ << QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT
|
|
+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_FMASK \
|
|
+ QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK \
|
|
+ << QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT
|
|
+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_FMASK \
|
|
+ QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK \
|
|
+ << QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT
|
|
+
|
|
+#define QCA955X_PLL_DDR_DIT_UPD_CNT_FMASK \
|
|
+ QCA955X_PLL_DDR_DIT_UPD_CNT_MASK \
|
|
+ << QCA955X_PLL_DDR_DIT_UPD_CNT_SHIFT
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_STEP_FMASK \
|
|
+ QCA955X_PLL_DDR_DIT_NFRAC_STEP_MASK \
|
|
+ << QCA955X_PLL_DDR_DIT_NFRAC_STEP_SHIFT
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MIN_FMASK \
|
|
+ QCA955X_PLL_DDR_DIT_NFRAC_MIN_MASK \
|
|
+ << QCA955X_PLL_DDR_DIT_NFRAC_MIN_SHIFT
|
|
+#define QCA955X_PLL_DDR_DIT_NFRAC_MAX_FMASK \
|
|
+ QCA955X_PLL_DDR_DIT_NFRAC_MAX_MASK \
|
|
+ << QCA955X_PLL_DDR_DIT_NFRAC_MAX_SHIFT
|
|
+
|
|
+#define QCA955X_PLL_CPU_DIT_UPD_CNT_FMASK \
|
|
+ QCA955X_PLL_CPU_DIT_UPD_CNT_MASK \
|
|
+ << QCA955X_PLL_CPU_DIT_UPD_CNT_SHIFT
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_STEP_FMASK \
|
|
+ QCA955X_PLL_CPU_DIT_NFRAC_STEP_MASK \
|
|
+ << QCA955X_PLL_CPU_DIT_NFRAC_STEP_SHIFT
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MIN_FMASK \
|
|
+ QCA955X_PLL_CPU_DIT_NFRAC_MIN_MASK \
|
|
+ << QCA955X_PLL_CPU_DIT_NFRAC_MIN_SHIFT
|
|
+#define QCA955X_PLL_CPU_DIT_NFRAC_MAX_FMASK \
|
|
+ QCA955X_PLL_CPU_DIT_NFRAC_MAX_MASK \
|
|
+ << QCA955X_PLL_CPU_DIT_NFRAC_MAX_SHIFT
|
|
+
|
|
+#define PLL_SRIF_DPLL2_KI_MASK GENMASK(29, 26)
|
|
+#define PLL_SRIF_DPLL2_KD_MASK GENMASK(25, 19)
|
|
+#define PLL_SRIF_DPLL2_PLL_PWD_MASK BIT(16)
|
|
+#define PLL_SRIF_DPLL2_DELTA_MASK GENMASK(12, 7)
|
|
+
|
|
+#define PLL_SRIF_DPLL2_DEFAULT \
|
|
+ FIELD_PREP(PLL_SRIF_DPLL2_KI_MASK, 0x4) | \
|
|
+ FIELD_PREP(PLL_SRIF_DPLL2_KD_MASK, 0x60) | \
|
|
+ FIELD_PREP(PLL_SRIF_DPLL2_PLL_PWD_MASK, 0x1) | \
|
|
+ FIELD_PREP(PLL_SRIF_DPLL2_DELTA_MASK, 0x1e)
|
|
+
|
|
+DECLARE_GLOBAL_DATA_PTR;
|
|
+
|
|
+static u32 qca955x_get_xtal(void)
|
|
+{
|
|
+ u32 val;
|
|
+
|
|
+ val = ath79_get_bootstrap();
|
|
+ if (val & QCA955X_BOOTSTRAP_REF_CLK_40)
|
|
+ return 40000000;
|
|
+ else
|
|
+ return 25000000;
|
|
+}
|
|
+
|
|
+int get_serial_clock(void)
|
|
+{
|
|
+ return qca955x_get_xtal();
|
|
+}
|
|
+
|
|
+void qca955x_pll_init(void)
|
|
+{
|
|
+ void __iomem *srif_regs = map_physmem(QCA955X_SRIF_BASE,
|
|
+ QCA955X_SRIF_SIZE, MAP_NOCACHE);
|
|
+ void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
|
|
+ AR71XX_PLL_SIZE, MAP_NOCACHE);
|
|
+
|
|
+ /* 10.33.2 Baseband DPLL2 */
|
|
+ writel(PLL_SRIF_DPLL2_DEFAULT,
|
|
+ srif_regs + QCA955X_SRIF_BB_DPLL2_REG);
|
|
+
|
|
+ /* 10.33.2 PCIE DPLL2 */
|
|
+ writel(PLL_SRIF_DPLL2_DEFAULT,
|
|
+ srif_regs + QCA955X_SRIF_PCIE_DPLL2_REG);
|
|
+
|
|
+ /* 10.33.2 DDR DPLL2 */
|
|
+ writel(PLL_SRIF_DPLL2_DEFAULT,
|
|
+ srif_regs + QCA955X_SRIF_DDR_DPLL2_REG);
|
|
+
|
|
+ /* 10.33.2 CPU DPLL2 */
|
|
+ writel(PLL_SRIF_DPLL2_DEFAULT,
|
|
+ srif_regs + QCA955X_SRIF_CPU_DPLL2_REG);
|
|
+
|
|
+ /* pll_bypass_set */
|
|
+ setbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
|
|
+ setbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
|
|
+ setbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
|
|
+
|
|
+ /* init_cpu_pll (720_600_240) */
|
|
+ writel(QCA955X_PLL_CPU_CONFIG_PLLPWD |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_CONFIG_OUTDIV_FMASK, 0x0) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_CONFIG_RANGE_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_CONFIG_REFDIV_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_CONFIG_NINT_FMASK, 0x12),
|
|
+ pll_regs + QCA955X_PLL_CPU_CONFIG_REG);
|
|
+
|
|
+ /* init_ddr_pll (720_600_240) */
|
|
+ writel(QCA955X_PLL_DDR_CONFIG_PLLPWD |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_CONFIG_OUTDIV_FMASK, 0x0) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_CONFIG_RANGE_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_CONFIG_REFDIV_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_CONFIG_NINT_FMASK, 0xf),
|
|
+ pll_regs + QCA955X_PLL_DDR_CONFIG_REG);
|
|
+
|
|
+ /* init_ahb_pll (720_600_240) */
|
|
+ writel(/* use CPU PLL for AHB (0) */
|
|
+ /* use DDR PLL for DDR (0) */
|
|
+ /* use CPU PLL for CPU (0) */
|
|
+ FIELD_PREP(QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_FMASK, 0x2) |
|
|
+ FIELD_PREP(QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_FMASK, 0x0) |
|
|
+ FIELD_PREP(QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_FMASK, 0x0) |
|
|
+ QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS |
|
|
+ QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS |
|
|
+ QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS,
|
|
+ pll_regs + QCA955X_PLL_CLK_CTRL_REG);
|
|
+
|
|
+ /* pll_pwd_unset */
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_CPU_CONFIG_REG,
|
|
+ QCA955X_PLL_CPU_CONFIG_PLLPWD);
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_DDR_CONFIG_REG,
|
|
+ QCA955X_PLL_DDR_CONFIG_PLLPWD);
|
|
+
|
|
+ /* outdiv_unset */
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_CPU_CONFIG_REG,
|
|
+ QCA955X_PLL_CPU_CONFIG_OUTDIV_FMASK);
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_DDR_CONFIG_REG,
|
|
+ QCA955X_PLL_DDR_CONFIG_OUTDIV_FMASK);
|
|
+
|
|
+ /* pll_bypass_unset */
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
|
|
+ clrbits_be32(pll_regs + QCA955X_PLL_CLK_CTRL_REG,
|
|
+ QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
|
|
+
|
|
+ /* ddr_pll_dither_unset */
|
|
+ writel(FIELD_PREP(QCA955X_PLL_DDR_DIT_UPD_CNT_FMASK, 0xf) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_DIT_NFRAC_STEP_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_DIT_NFRAC_MIN_FMASK, 0x0) |
|
|
+ FIELD_PREP(QCA955X_PLL_DDR_DIT_NFRAC_MAX_FMASK, 0x3ff),
|
|
+ pll_regs + QCA955X_PLL_DDR_DIT_FRAC_REG);
|
|
+
|
|
+ /* cpu_pll_dither_unset */
|
|
+ writel(FIELD_PREP(QCA955X_PLL_CPU_DIT_UPD_CNT_FMASK, 0xf) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_DIT_NFRAC_STEP_FMASK, 0x1) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_DIT_NFRAC_MIN_FMASK, 0x0) |
|
|
+ FIELD_PREP(QCA955X_PLL_CPU_DIT_NFRAC_MAX_FMASK, 0x3f),
|
|
+ pll_regs + QCA955X_PLL_CPU_DIT_FRAC_REG);
|
|
+}
|
|
+
|
|
+int get_clocks(void)
|
|
+{
|
|
+ void __iomem *regs;
|
|
+ u32 pll, cpu_pll, ddr_pll, clk_ctrl;
|
|
+ u32 cpu_clk, ddr_clk, ahb_clk;
|
|
+ u32 outdiv, refdiv, nint, nfrac, postdiv;
|
|
+ u32 xtal = qca955x_get_xtal();
|
|
+
|
|
+ regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
|
+ MAP_NOCACHE);
|
|
+ pll = readl(regs + QCA955X_PLL_CPU_CONFIG_REG);
|
|
+ outdiv = FIELD_GET(QCA955X_PLL_CPU_CONFIG_OUTDIV_FMASK, pll);
|
|
+ refdiv = FIELD_GET(QCA955X_PLL_CPU_CONFIG_REFDIV_FMASK, pll);
|
|
+ nint = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NINT_FMASK, pll);
|
|
+ nfrac = FIELD_GET(QCA955X_PLL_CPU_CONFIG_NFRAC_FMASK, pll);
|
|
+
|
|
+ cpu_pll = (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
|
|
+
|
|
+ pll = readl(regs + QCA955X_PLL_DDR_CONFIG_REG);
|
|
+ outdiv = FIELD_GET(QCA955X_PLL_DDR_CONFIG_OUTDIV_FMASK, pll);
|
|
+ refdiv = FIELD_GET(QCA955X_PLL_DDR_CONFIG_REFDIV_FMASK, pll);
|
|
+ nint = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NINT_FMASK, pll);
|
|
+ nfrac = FIELD_GET(QCA955X_PLL_DDR_CONFIG_NFRAC_FMASK, pll);
|
|
+
|
|
+ ddr_pll = (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
|
|
+
|
|
+ clk_ctrl = readl(regs + QCA955X_PLL_CLK_CTRL_REG);
|
|
+
|
|
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_FMASK, clk_ctrl);
|
|
+ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
|
|
+ cpu_clk = xtal;
|
|
+ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
|
|
+ cpu_clk = ddr_pll / (postdiv + 1);
|
|
+ else
|
|
+ cpu_clk = cpu_pll / (postdiv + 1);
|
|
+
|
|
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_FMASK, clk_ctrl);
|
|
+ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
|
|
+ ddr_clk = xtal;
|
|
+ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
|
|
+ ddr_clk = cpu_pll / (postdiv + 1);
|
|
+ else
|
|
+ ddr_clk = ddr_pll / (postdiv + 1);
|
|
+
|
|
+ postdiv = FIELD_GET(QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_FMASK, clk_ctrl);
|
|
+ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
|
|
+ ahb_clk = xtal;
|
|
+ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
|
|
+ ahb_clk = ddr_pll;
|
|
+ else
|
|
+ ahb_clk = cpu_pll;
|
|
+ ahb_clk /= (postdiv + 1);
|
|
+
|
|
+ gd->cpu_clk = cpu_clk;
|
|
+ gd->mem_clk = ddr_clk;
|
|
+ gd->bus_clk = ahb_clk;
|
|
+
|
|
+ debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n",
|
|
+ cpu_clk, ddr_clk, ahb_clk);
|
|
+
|
|
+ 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/qca955x/cpu.c b/arch/mips/mach-ath79/qca955x/cpu.c
|
|
new file mode 100644
|
|
index 0000000000..9405871444
|
|
--- /dev/null
|
|
+++ b/arch/mips/mach-ath79/qca955x/cpu.c
|
|
@@ -0,0 +1,7 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (C) 2024 INAGAKI Hiroshi <musashino.open@gmail.com>
|
|
+ */
|
|
+
|
|
+/* The lowlevel_init() is not needed on QCA955X */
|
|
+void lowlevel_init(void) {}
|
|
diff --git a/arch/mips/mach-ath79/qca955x/ddr.c b/arch/mips/mach-ath79/qca955x/ddr.c
|
|
new file mode 100644
|
|
index 0000000000..654a410d95
|
|
--- /dev/null
|
|
+++ b/arch/mips/mach-ath79/qca955x/ddr.c
|
|
@@ -0,0 +1,222 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (C) 2024 INAGAKI Hiroshi <musashino.open@gmail.com>
|
|
+ *
|
|
+ * Based on QCA956x support and QSDK
|
|
+ */
|
|
+
|
|
+#include <asm/global_data.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/addrspace.h>
|
|
+#include <asm/types.h>
|
|
+#include <linux/bitfield.h>
|
|
+#include <linux/bitops.h>
|
|
+#include <linux/delay.h>
|
|
+#include <mach/ar71xx_regs.h>
|
|
+#include <mach/ath79.h>
|
|
+
|
|
+#define DDR_CONFIG_CAS_LATENCY_MSB_MASK BIT(31)
|
|
+#define DDR_CONFIG_OPEN_PAGE_MASK BIT(30)
|
|
+#define DDR_CONFIG_CAS_LATENCY_MASK GENMASK(29, 27)
|
|
+#define DDR_CONFIG_TMRD_MASK GENMASK(26, 23)
|
|
+#define DDR_CONFIG_TRFC_MASK GENMASK(22, 17)
|
|
+#define DDR_CONFIG_TRRD_MASK GENMASK(16, 13)
|
|
+#define DDR_CONFIG_TRP_MASK GENMASK(12, 9)
|
|
+#define DDR_CONFIG_TRCD_MASK GENMASK(8, 5)
|
|
+#define DDR_CONFIG_TRAS_MASK GENMASK(4, 0)
|
|
+
|
|
+#define DDR_CONFIG2_HALF_WIDTH_LOW_MASK BIT(31)
|
|
+#define DDR_CONFIG2_SWAP_A26_A27_MASK BIT(30)
|
|
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_MASK GENMASK(29, 26)
|
|
+#define DDR_CONFIG2_TWTR_MASK GENMASK(25, 21)
|
|
+#define DDR_CONFIG2_TRTP_MASK GENMASK(20, 17)
|
|
+#define DDR_CONFIG2_TRTW_MASK GENMASK(16, 12)
|
|
+#define DDR_CONFIG2_TWR_MASK GENMASK(11, 8)
|
|
+#define DDR_CONFIG2_CKE_MASK BIT(7)
|
|
+#define DDR_CONFIG2_CNTL_OE_EN_MASK BIT(5)
|
|
+#define DDR_CONFIG2_BURST_LENGTH_MASK GENMASK(3, 0)
|
|
+
|
|
+#define DDR_CTL_CONFIG_SRAM_TSEL_MASK GENMASK(31, 30)
|
|
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK BIT(20)
|
|
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK BIT(19)
|
|
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK BIT(18)
|
|
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK BIT(17)
|
|
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK BIT(16)
|
|
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK BIT(15)
|
|
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK BIT(14)
|
|
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK BIT(6)
|
|
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK BIT(2)
|
|
+#define DDR_CTL_CONFIG_HALF_WIDTH_MASK BIT(1)
|
|
+
|
|
+#define RST_BOOTSTRAP_DDR_WIDTH_MASK BIT(3)
|
|
+
|
|
+#define PMU2_PGM_MASK BIT(21)
|
|
+#define PMU2_LDO_TUNE_MASK GENMASK(20, 19)
|
|
+
|
|
+/*
|
|
+* DDR2 DDR1
|
|
+* 0x40c3 25MHz 0x4186 25Mhz
|
|
+* 0x4138 40MHz 0x4270 40Mhz
|
|
+*/
|
|
+#define CFG_DDR2_REFRESH_VAL 0x4138
|
|
+
|
|
+#define CFG_DDR2_CONFIG_VAL \
|
|
+ DDR_CONFIG_CAS_LATENCY_MSB_MASK | DDR_CONFIG_OPEN_PAGE_MASK | \
|
|
+ FIELD_PREP(DDR_CONFIG_CAS_LATENCY_MASK, 0x4) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TMRD_MASK, 0xf) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TRFC_MASK, 0x15) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TRRD_MASK, 0x7) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TRP_MASK, 0x9) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TRCD_MASK, 0x9) | \
|
|
+ FIELD_PREP(DDR_CONFIG_TRAS_MASK, 0x1b)
|
|
+
|
|
+#define CFG_DDR2_CONFIG2_VAL \
|
|
+ DDR_CONFIG2_HALF_WIDTH_LOW_MASK | /* SWAP_A26_A27 is off */ \
|
|
+ FIELD_PREP(DDR_CONFIG2_GATE_OPEN_LATENCY_MASK, 0xb) | \
|
|
+ FIELD_PREP(DDR_CONFIG2_TWTR_MASK, 0x15) | \
|
|
+ FIELD_PREP(DDR_CONFIG2_TRTP_MASK, 0x9) | \
|
|
+ FIELD_PREP(DDR_CONFIG2_TRTW_MASK, 0xe) | \
|
|
+ FIELD_PREP(DDR_CONFIG2_TWR_MASK, 0x1) | \
|
|
+ DDR_CONFIG2_CKE_MASK | DDR_CONFIG2_CNTL_OE_EN_MASK | \
|
|
+ FIELD_PREP(DDR_CONFIG2_BURST_LENGTH_MASK, 0x8)
|
|
+
|
|
+#define CFG_DDR2_CONFIG3_VAL 0x0000000a
|
|
+#define CFG_DDR2_EXT_MODE_VAL1 0x782
|
|
+#define CFG_DDR2_EXT_MODE_VAL2 0x402
|
|
+#define CFG_DDR2_MODE_VAL_INIT 0x153
|
|
+#define CFG_DDR2_MODE_VAL 0x53
|
|
+#define CFG_DDR2_TAP_VAL 0x10
|
|
+#define CFG_DDR2_EN_TWL_VAL 0x00001e7d
|
|
+#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
|
|
+#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
|
|
+
|
|
+#define CFG_DDR_CTL_CONFIG \
|
|
+ FIELD_PREP(DDR_CTL_CONFIG_SRAM_TSEL_MASK, 0x1) | \
|
|
+ DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK | \
|
|
+ DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK /* for DDR2 */
|
|
+ /* CPU_DDR_SYNC is off (CPU clk != DDR clk) */
|
|
+
|
|
+DECLARE_GLOBAL_DATA_PTR;
|
|
+
|
|
+void qca955x_ddr_init(void)
|
|
+{
|
|
+ u32 cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32;
|
|
+ u32 ctl_config = CFG_DDR_CTL_CONFIG;
|
|
+ void __iomem *ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
|
+ MAP_NOCACHE);
|
|
+ void __iomem *srif_regs = map_physmem(QCA955X_SRIF_BASE, QCA955X_SRIF_SIZE,
|
|
+ MAP_NOCACHE);
|
|
+
|
|
+ /* 16bit */
|
|
+ if (!(ath79_get_bootstrap() & RST_BOOTSTRAP_DDR_WIDTH_MASK))
|
|
+ {
|
|
+ ctl_config |= DDR_CTL_CONFIG_HALF_WIDTH_MASK;
|
|
+ cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16;
|
|
+ }
|
|
+
|
|
+ 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 + QCA955X_DDR_REG_CTL_CONF);
|
|
+ udelay(10);
|
|
+
|
|
+ writel(cycle_val, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(0x74444444, ddr_regs + QCA955X_DDR_REG_BURST);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(0x44444444, ddr_regs + QCA955X_DDR_REG_BURST2);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(0xfffff, ddr_regs + QCA955X_DDR_REG_TIMEOUT_MAX);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(CFG_DDR2_CONFIG_VAL, ddr_regs + AR71XX_DDR_REG_CONFIG);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(CFG_DDR2_CONFIG2_VAL, ddr_regs + AR71XX_DDR_REG_CONFIG2);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(CFG_DDR2_CONFIG3_VAL, ddr_regs + QCA955X_DDR_REG_CONFIG3);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(CFG_DDR2_EN_TWL_VAL, ddr_regs + QCA955X_DDR_REG_DDR2_CONFIG);
|
|
+ udelay(100);
|
|
+
|
|
+ writel(CFG_DDR2_CONFIG2_VAL | 0x80,
|
|
+ ddr_regs + AR71XX_DDR_REG_CONFIG2); /* CKE Enable */
|
|
+ udelay(100);
|
|
+
|
|
+ writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Precharge */
|
|
+ udelay(10);
|
|
+
|
|
+ writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR2 */
|
|
+ udelay(10);
|
|
+
|
|
+ writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR3 */
|
|
+ udelay(10);
|
|
+
|
|
+ /* EMR DLL enable, Reduced Driver Impedance control, Differential DQS disabled */
|
|
+ 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(CFG_DDR2_MODE_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(CFG_DDR2_MODE_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(CFG_DDR2_TAP_VAL, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
|
|
+ writel(CFG_DDR2_TAP_VAL, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
|
|
+ writel(CFG_DDR2_TAP_VAL, ddr_regs + QCA955X_DDR_REG_TAP_CTRL2);
|
|
+ writel(CFG_DDR2_TAP_VAL, ddr_regs + QCA955X_DDR_REG_TAP_CTRL3);
|
|
+
|
|
+ writel(0x633c8176, srif_regs + QCA955X_SRIF_PMU1_REG);
|
|
+ /* Set DDR2 Voltage to 1.8 volts */
|
|
+ writel(PMU2_PGM_MASK | FIELD_PREP(PMU2_LDO_TUNE_MASK, 0x3),
|
|
+ srif_regs + QCA955X_SRIF_PMU2_REG);
|
|
+}
|
|
diff --git a/arch/mips/mach-ath79/qca955x/qca955x-ddr-tap.S b/arch/mips/mach-ath79/qca955x/qca955x-ddr-tap.S
|
|
new file mode 100644
|
|
index 0000000000..1c117a5b69
|
|
--- /dev/null
|
|
+++ b/arch/mips/mach-ath79/qca955x/qca955x-ddr-tap.S
|
|
@@ -0,0 +1,191 @@
|
|
+// SPDX-License-Identifier: GPL-2.0+
|
|
+/*
|
|
+ * Copyright (C) 2024 INAGAKI Hiroshi <musashino.open@gmail.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>
|
|
+
|
|
+ .set noreorder
|
|
+
|
|
+LEAF(ddr_tap_tuning)
|
|
+ li a0, 0xbd007f00
|
|
+ sw zero, 0x0(a0) /* Place where the tap values are saved and used for SWEEP */
|
|
+ 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, CKSEG1ADDR(AR71XX_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, CKSEG1ADDR(QCA955X_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
|
|
+
|
|
+_CHANGE_TAPS:
|
|
+ li t0, 0xbd007f00 /* Read the current value of the TAP for programming */
|
|
+ lw t1, 0x0(t0)
|
|
+ li t2, 0x00000000
|
|
+ or t3, t1, t2
|
|
+
|
|
+ li t0, CKSEG1ADDR(AR71XX_DDR_CTRL_BASE)
|
|
+ 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, 0x545fc332
|
|
+ sw t1, 0x0070(t0) /* PERF_COMP_AHB_GE0_1_ADDRESS */
|
|
+
|
|
+ li t1, 0xaba03ccd
|
|
+ sw t1, 0x0040(t0) /* PERF_COMP_AHB_GE1_0_ADDRESS */
|
|
+
|
|
+ li t1, 0x545fc332
|
|
+ sw t1, 0x0078(t0) /* PERF_COMP_AHB_GE1_1_ADDRESS */
|
|
+
|
|
+ li t1, 0xaba03ccd
|
|
+ sw t1, 0x0034(t0) /* PERF_MASK_AHB_GE0_0_ADDRESS */
|
|
+
|
|
+ li t1, 0x545fc332
|
|
+ sw t1, 0x006c(t0) /* PERF_MASK_AHB_GE0_1_ADDRESS */
|
|
+
|
|
+ li t1, 0xaba03ccd
|
|
+ sw t1, 0x003c(t0) /* PERF_MASK_AHB_GE1_0_ADDRESS */
|
|
+
|
|
+ li t1, 0x545fc332
|
|
+ sw t1, 0x0074(t0) /* PERF_MASK_AHB_GE1_1_ADDRESS */
|
|
+
|
|
+ li t1, 0xaba03ccd
|
|
+ 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, 0xbd007f00
|
|
+ lw t1, 0x4(t0)
|
|
+ addiu t1, t1, 0x1
|
|
+ sw t1, 0x4(t0)
|
|
+
|
|
+ li t0, 0xbd007f10
|
|
+ lw t1, 0x0(t0)
|
|
+ li t2, 0xaa55aa55
|
|
+ beq t1, t2, _first_pass
|
|
+ nop
|
|
+
|
|
+ li t0, 0xbd007f00
|
|
+ lw t1, 0x0(t0)
|
|
+ li t0, 0xbd007f10
|
|
+ sw t1, 0x4(t0)
|
|
+ nop
|
|
+ b _iterate_tap
|
|
+ nop
|
|
+
|
|
+_first_pass:
|
|
+ li t0, 0xbd007f00
|
|
+ lw t1, 0x0(t0)
|
|
+ li t0, 0xbd007f10
|
|
+ sw t1, 0x0(t0)
|
|
+ sw t1, 0x4(t0)
|
|
+ nop
|
|
+
|
|
+_iterate_tap:
|
|
+ li t0, 0xbd007f00
|
|
+ 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, 0xbd007f00
|
|
+ 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, 0xbd007f10
|
|
+ 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, CKSEG1ADDR(AR71XX_DDR_CTRL_BASE)
|
|
+ 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)
|
|
--
|
|
2.43.0
|
|
|