GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -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
|
||||
@@ -0,0 +1,419 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Rosy Song <rosysong@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;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* The lowlevel_init() is not needed on QCA956X */
|
||||
void lowlevel_init(void) {}
|
||||
@@ -0,0 +1,308 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Rosy Song <rosysong@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 */
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Rosy Song <rosysong@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>
|
||||
|
||||
.set noreorder
|
||||
|
||||
LEAF(ddr_tap_tuning)
|
||||
li a0, 0xbd001f00
|
||||
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) /* RESET_BASE_ADDRESS */
|
||||
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(QCA956X_RTC_BASE) /* RTC_BASE_ADDRESS */
|
||||
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, 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)
|
||||
Reference in New Issue
Block a user