From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 7/8] mips: ath79: Add AR934x support
Date: Fri, 6 May 2016 13:32:34 +0200 [thread overview]
Message-ID: <572C80D2.7030906@gmail.com> (raw)
In-Reply-To: <1462472097-6407-7-git-send-email-marex@denx.de>
Am 05.05.2016 um 20:14 schrieb Marek Vasut:
> Add support for the Atheros AR934x WiSoCs. This patchs adds complete
> system init, including PLL and DRAM init, both of which happen from
> full C environment, since the AR934x has proper SRAM.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> Cc: Wills Wang <wills.wang@live.com>
> ---
> arch/mips/dts/ar934x.dtsi | 94 +++++++
> arch/mips/mach-ath79/Kconfig | 9 +
> arch/mips/mach-ath79/Makefile | 3 +-
> arch/mips/mach-ath79/ar934x/Makefile | 7 +
> arch/mips/mach-ath79/ar934x/clk.c | 336 ++++++++++++++++++++++++
> arch/mips/mach-ath79/ar934x/cpu.c | 10 +
> arch/mips/mach-ath79/ar934x/ddr.c | 165 ++++++++++++
> arch/mips/mach-ath79/include/mach/ar71xx_regs.h | 43 +++
> arch/mips/mach-ath79/include/mach/ath79.h | 3 +
> 9 files changed, 669 insertions(+), 1 deletion(-)
> create mode 100644 arch/mips/dts/ar934x.dtsi
> create mode 100644 arch/mips/mach-ath79/ar934x/Makefile
> create mode 100644 arch/mips/mach-ath79/ar934x/clk.c
> create mode 100644 arch/mips/mach-ath79/ar934x/cpu.c
> create mode 100644 arch/mips/mach-ath79/ar934x/ddr.c
there are checkpatch.pl warnings:
warning: arch/mips/mach-ath79/ar934x/clk.c,151: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/clk.c,152: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/clk.c,158: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/clk.c,159: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/clk.c,323: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/ddr.c,141: line over 80 characters
warning: arch/mips/mach-ath79/ar934x/ddr.c,142: line over 80 characters
error: arch/mips/mach-ath79/ar934x/ddr.c,158: do not use C99 // comments
error: arch/mips/mach-ath79/ar934x/ddr.c,159: do not use C99 // comments
error: arch/mips/mach-ath79/ar934x/ddr.c,160: do not use C99 // comments
checkpatch.pl found 3 error(s), 8 warning(s), 0 checks(s)
>
> diff --git a/arch/mips/dts/ar934x.dtsi b/arch/mips/dts/ar934x.dtsi
> new file mode 100644
> index 0000000..d62c447
> --- /dev/null
> +++ b/arch/mips/dts/ar934x.dtsi
> @@ -0,0 +1,94 @@
> +/*
> + * Copyright (C) 2016 Marek Vasut <marex@denx.de>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> + compatible = "qca,ar934x";
> +
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cpu at 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>;
> +
> + ehci0: ehci at 1b000100 {
> + compatible = "generic-ehci";
> + reg = <0x1b000100 0x100>;
> +
> + status = "disabled";
> + };
> +
> + uart0: uart at 18020000 {
> + compatible = "ns16550";
> + reg = <0x18020000 0x20>;
> + reg-shift = <2>;
> +
> + status = "disabled";
> + };
> +
> + gmac0: eth at 0x19000000 {
> + compatible = "qca,ag934x-mac";
> + reg = <0x19000000 0x200>;
> + phy-mode = "rgmii";
> +
> + status = "disabled";
> + };
> +
> + gmac1: eth at 0x1a000000 {
> + compatible = "qca,ag934x-mac";
> + reg = <0x1a000000 0x200>;
> + phy-mode = "rgmii";
> +
> + status = "disabled";
> + };
> + };
> +
> + spi0: spi at 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 f45403b..527960f 100644
> --- a/arch/mips/mach-ath79/Kconfig
> +++ b/arch/mips/mach-ath79/Kconfig
> @@ -13,6 +13,15 @@ config SOC_AR933X
> help
> This supports QCA/Atheros ar933x family SOCs.
>
> +config SOC_AR934X
> + bool
> + select SUPPORTS_BIG_ENDIAN
> + select SUPPORTS_CPU_MIPS32_R1
> + select SUPPORTS_CPU_MIPS32_R2
> + select MIPS_TUNE_74KC
MIPS_TUNE_74KC doesn't exist yet in arch/mips/Makefile and
arch/mips/Kconfig. You should add it with an extra patch.
> + help
> + This supports QCA/Atheros ar934x family SOCs.
> +
> config SOC_QCA953X
> bool
> select SUPPORTS_BIG_ENDIAN
> diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
> index 160dfaa..d7e2666 100644
> --- a/arch/mips/mach-ath79/Makefile
> +++ b/arch/mips/mach-ath79/Makefile
> @@ -7,4 +7,5 @@ obj-y += cpu.o
> obj-y += dram.o
>
> obj-$(CONFIG_SOC_AR933X) += ar933x/
> -obj-$(CONFIG_SOC_QCA953X) += qca953x/
> \ No newline at end of file
> +obj-$(CONFIG_SOC_AR934X) += ar934x/
> +obj-$(CONFIG_SOC_QCA953X) += qca953x/
> diff --git a/arch/mips/mach-ath79/ar934x/Makefile b/arch/mips/mach-ath79/ar934x/Makefile
> new file mode 100644
> index 0000000..348c65b
> --- /dev/null
> +++ b/arch/mips/mach-ath79/ar934x/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +
> +obj-y += cpu.o
> +obj-y += clk.o
> +obj-y += ddr.o
> diff --git a/arch/mips/mach-ath79/ar934x/clk.c b/arch/mips/mach-ath79/ar934x/clk.c
> new file mode 100644
> index 0000000..6611b8d
> --- /dev/null
> +++ b/arch/mips/mach-ath79/ar934x/clk.c
> @@ -0,0 +1,336 @@
> +/*
> + * Copyright (C) 2016 Marek Vasut <marex@denx.de>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <mach/ar71xx_regs.h>
> +#include <mach/reset.h>
> +#include <wait_bit.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * The math for calculating PLL:
> + * NFRAC * 2^8
> + * NINT + -------------
> + * XTAL [MHz] 2^(18 - 1)
> + * PLL [MHz] = ------------ * ----------------------
> + * REFDIV 2^OUTDIV
> + *
> + * Unfortunatelly, there is no way to reliably compute the variables.
> + * The vendor U-Boot port contains macros for various combinations of
> + * CPU PLL / DDR PLL / AHB bus speed and there is no obvious pattern
> + * in those numbers.
> + */
> +struct ar934x_pll_config {
> + u8 range;
> + u8 refdiv;
> + u8 outdiv;
> + /* Index 0 is for XTAL=25MHz , Index 1 is for XTAL=40MHz */
> + u8 nint[2];
> +};
> +
> +struct ar934x_clock_config {
> + u16 cpu_freq;
> + u16 ddr_freq;
> + u16 ahb_freq;
> +
> + struct ar934x_pll_config cpu_pll;
> + struct ar934x_pll_config ddr_pll;
> +};
> +
> +static const struct ar934x_clock_config ar934x_clock_config[] = {
> + { 300, 300, 150, { 1, 1, 1, { 24, 15 } }, { 1, 1, 1, { 24, 15 } } },
> + { 400, 200, 200, { 1, 1, 1, { 32, 20 } }, { 1, 1, 2, { 32, 20 } } },
> + { 400, 400, 200, { 0, 1, 1, { 32, 20 } }, { 0, 1, 1, { 32, 20 } } },
> + { 500, 400, 200, { 1, 1, 0, { 20, 12 } }, { 0, 1, 1, { 32, 20 } } },
> + { 533, 400, 200, { 1, 1, 0, { 21, 13 } }, { 0, 1, 1, { 32, 20 } } },
> + { 533, 500, 250, { 1, 1, 0, { 21, 13 } }, { 0, 1, 0, { 20, 12 } } },
> + { 560, 480, 240, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 12 } } },
> + { 566, 400, 200, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 16, 10 } } },
> + { 566, 450, 225, { 1, 1, 0, { 22, 14 } }, { 0, 1, 1, { 36, 22 } } },
> + { 566, 475, 237, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 11 } } },
> + { 566, 500, 250, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 20, 12 } } },
> + { 566, 525, 262, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 21, 13 } } },
> + { 566, 550, 275, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 22, 13 } } },
> + { 600, 266, 133, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
> + { 600, 266, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
> + { 600, 300, 150, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 24, 15 } } },
> + { 600, 332, 166, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
> + { 600, 332, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
> + { 600, 400, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 32, 20 } } },
> + { 600, 450, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 18, 20 } } },
> + { 600, 500, 250, { 0, 1, 0, { 24, 15 } }, { 1, 1, 0, { 20, 12 } } },
> + { 600, 525, 262, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 21, 20 } } },
> + { 600, 550, 275, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 22, 20 } } },
> + { 600, 575, 287, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 23, 14 } } },
> + { 600, 600, 300, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 24, 20 } } },
> + { 600, 650, 325, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 26, 20 } } },
> + { 650, 600, 300, { 0, 1, 0, { 26, 15 } }, { 0, 1, 0, { 24, 20 } } },
> + { 700, 400, 200, { 3, 1, 0, { 28, 17 } }, { 0, 1, 1, { 32, 20 } } },
> +};
> +
> +static void ar934x_srif_pll_cfg(void __iomem *pll_reg_base, const u32 srif_val)
> +{
> + u32 reg;
> + do {
> + writel(0x10810f00, pll_reg_base + 0x4);
> + writel(srif_val, pll_reg_base + 0x0);
> + writel(0xd0810f00, pll_reg_base + 0x4);
> + writel(0x03000000, pll_reg_base + 0x8);
> + writel(0xd0800f00, pll_reg_base + 0x4);
> +
> + clrbits_be32(pll_reg_base + 0x8, BIT(30));
> + udelay(5);
> + setbits_be32(pll_reg_base + 0x8, BIT(30));
> + udelay(5);
> +
> + wait_for_bit("clk", pll_reg_base + 0xc, BIT(3), 1, 10, 0);
> +
> + clrbits_be32(pll_reg_base + 0x8, BIT(30));
> + udelay(5);
> +
> + /* Check if CPU SRIF PLL locked. */
> + reg = readl(pll_reg_base + 0x8);
> + reg = (reg & 0x7ffff8) >> 3;
> + } while (reg >= 0x40000);
> +}
> +
> +void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
> +{
> + void __iomem *srif_regs = map_physmem(AR934X_SRIF_BASE,
> + AR934X_SRIF_SIZE, MAP_NOCACHE);
> + void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
> + AR71XX_RESET_SIZE, MAP_NOCACHE);
> + void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
> + AR71XX_PLL_SIZE, MAP_NOCACHE);
> + const struct ar934x_pll_config *pll_cfg;
> + int i, xtal_40 = 0;
> + u32 reg, cpu_pll, cpu_srif, ddr_pll, ddr_srif;
> +
> + /* Register remap failed, hang. */
> + if (!srif_regs || !reset_regs || !pll_regs)
> + hang();
map_physmem() is never NULL unless you implement plat_ioremap(). Thus
those checks aren't necessary.
> +
> + /* Configure SRIF PLL with initial values. */
> + writel(0x13210f00, srif_regs + AR934X_SRIF_CPU_DPLL2_REG);
> + writel(0x03000000, srif_regs + AR934X_SRIF_CPU_DPLL3_REG);
> + writel(0x13210f00, srif_regs + AR934X_SRIF_DDR_DPLL2_REG);
> + writel(0x03000000, srif_regs + AR934X_SRIF_DDR_DPLL3_REG);
> + writel(0x03000000, srif_regs + 0x188); /* Undocumented reg :-) */
> +
> + /* Test for 40MHz XTAL */
> + reg = get_bootstrap();
> + if (reg & AR934X_BOOTSTRAP_REF_CLK_40) {
> + xtal_40 = 1;
> + cpu_srif = 0x41c00000;
> + ddr_srif = 0x41680000;
> + } else {
> + xtal_40 = 0;
> + cpu_srif = 0x29c00000;
> + ddr_srif = 0x29680000;
> + }
> +
> + /* Locate CPU/DDR PLL configuration */
> + for (i = 0; i < ARRAY_SIZE(ar934x_clock_config); i++) {
> + if (cpu_mhz != ar934x_clock_config[i].cpu_freq)
> + continue;
> + if (ddr_mhz != ar934x_clock_config[i].ddr_freq)
> + continue;
> + if (ahb_mhz != ar934x_clock_config[i].ahb_freq)
> + continue;
> +
> + /* Entry found */
> + pll_cfg = &ar934x_clock_config[i].cpu_pll;
> + cpu_pll =
> + (pll_cfg->nint[xtal_40] << AR934X_PLL_CPU_CONFIG_NINT_SHIFT) |
> + (pll_cfg->refdiv << AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) |
> + (pll_cfg->range << AR934X_PLL_CPU_CONFIG_RANGE_SHIFT) |
> + (pll_cfg->outdiv << AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT);
> +
> + pll_cfg = &ar934x_clock_config[i].ddr_pll;
> + ddr_pll =
> + (pll_cfg->nint[xtal_40] << AR934X_PLL_DDR_CONFIG_NINT_SHIFT) |
> + (pll_cfg->refdiv << AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) |
> + (pll_cfg->range << AR934X_PLL_DDR_CONFIG_RANGE_SHIFT) |
> + (pll_cfg->outdiv << AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT);
> + break;
> + }
> +
> + /* PLL configuration not found, hang. */
> + if (i == ARRAY_SIZE(ar934x_clock_config))
> + hang();
> +
> + /* Set PLL Bypass */
> + setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
> + setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
> + setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
> +
> + /* Configure CPU PLL */
> + writel(cpu_pll | AR934X_PLL_CPU_CONFIG_PLLPWD,
> + pll_regs + AR934X_PLL_CPU_CONFIG_REG);
> + /* Configure DDR PLL */
> + writel(ddr_pll | AR934X_PLL_DDR_CONFIG_PLLPWD,
> + pll_regs + AR934X_PLL_DDR_CONFIG_REG);
> + /* Configure PLL routing */
> + writel(AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS |
> + AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS |
> + AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS |
> + (0 << AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) |
> + (0 << AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) |
> + (1 << AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) |
> + AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL |
> + AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL |
> + AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL,
> + pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
> +
> + /* Configure SRIF PLLs, which is completely undocumented :-) */
> + ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_CPU_DPLL1_REG, cpu_srif);
> + ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_DDR_DPLL1_REG, ddr_srif);
> +
> + /* Unset PLL Bypass */
> + clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
> + clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
> + clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
> + AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
> +
> + /* Enable PLL dithering */
> + writel((1 << AR934X_PLL_DDR_DIT_FRAC_STEP_SHIFT) |
> + (0xf << AR934X_PLL_DDR_DIT_UPD_CNT_SHIFT),
> + pll_regs + AR934X_PLL_DDR_DIT_FRAC_REG);
> + writel(48 << AR934X_PLL_CPU_DIT_UPD_CNT_SHIFT,
> + pll_regs + AR934X_PLL_CPU_DIT_FRAC_REG);
> +}
> +
> +static u32 ar934x_get_xtal(void)
> +{
> + u32 val;
> +
> + val = get_bootstrap();
> + if (val & AR934X_BOOTSTRAP_REF_CLK_40)
> + return 40000000;
> + else
> + return 25000000;
> +}
> +
> +int get_serial_clock(void)
> +{
> + return ar934x_get_xtal();
> +}
> +
> +static u32 ar934x_cpupll_to_hz(const u32 regval)
> +{
> + const u32 outdiv = (regval >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
> + AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
> + const u32 refdiv = (regval >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
> + AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
> + const u32 nint = (regval >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
> + AR934X_PLL_CPU_CONFIG_NINT_MASK;
> + const u32 nfrac = (regval >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
> + AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
> + const u32 xtal = ar934x_get_xtal();
> +
> + return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
> +}
> +
> +static u32 ar934x_ddrpll_to_hz(const u32 regval)
> +{
> + const u32 outdiv = (regval >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
> + AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
> + const u32 refdiv = (regval >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
> + AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
> + const u32 nint = (regval >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
> + AR934X_PLL_DDR_CONFIG_NINT_MASK;
> + const u32 nfrac = (regval >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
> + AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
> + const u32 xtal = ar934x_get_xtal();
> +
> + return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
> +}
> +
> +static void ar934x_update_clock(void)
> +{
> + void __iomem *regs;
> + u32 ctrl, cpu, cpupll, ddr, ddrpll;
> + u32 cpudiv, ddrdiv, busdiv;
> + u32 cpuclk, ddrclk, busclk;
> +
> + regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
> + MAP_NOCACHE);
> +
> + cpu = readl(regs + AR934X_PLL_CPU_CONFIG_REG);
> + ddr = readl(regs + AR934X_PLL_DDR_CONFIG_REG);
> + ctrl = readl(regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
> +
> + cpupll = ar934x_cpupll_to_hz(cpu);
> + ddrpll = ar934x_ddrpll_to_hz(ddr);
> +
> + if (ctrl & AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
> + cpuclk = ar934x_get_xtal();
> + else if (ctrl & AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
> + cpuclk = cpupll;
> + else
> + cpuclk = ddrpll;
> +
> + if (ctrl & AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
> + ddrclk = ar934x_get_xtal();
> + else if (ctrl & AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
> + ddrclk = ddrpll;
> + else
> + ddrclk = cpupll;
> +
> + if (ctrl & AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
> + busclk = ar934x_get_xtal();
> + else if (ctrl & AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
> + busclk = ddrpll;
> + else
> + busclk = cpupll;
> +
> + cpudiv = (ctrl >> AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
> + AR934X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
> + ddrdiv = (ctrl >> AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
> + AR934X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
> + busdiv = (ctrl >> AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
> + AR934X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
> +
> + gd->cpu_clk = cpuclk / (cpudiv + 1);
> + gd->mem_clk = ddrclk / (ddrdiv + 1);
> + gd->bus_clk = busclk / (busdiv + 1);
> +}
> +
> +ulong get_bus_freq(ulong dummy)
> +{
> + ar934x_update_clock();
> + return gd->bus_clk;
> +}
> +
> +ulong get_ddr_freq(ulong dummy)
> +{
> + ar934x_update_clock();
> + return gd->mem_clk;
> +}
> +
> +int do_ar934x_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> + ar934x_update_clock();
> + printf("CPU: %8ld MHz\n", gd->cpu_clk / 1000000);
> + printf("Memory: %8ld MHz\n", gd->mem_clk / 1000000);
> + printf("AHB: %8ld MHz\n", gd->bus_clk / 1000000);
> + return 0;
> +}
> +
> +U_BOOT_CMD(
> + clocks, CONFIG_SYS_MAXARGS, 1, do_ar934x_showclocks,
> + "display clocks",
> + ""
> +);
> diff --git a/arch/mips/mach-ath79/ar934x/cpu.c b/arch/mips/mach-ath79/ar934x/cpu.c
> new file mode 100644
> index 0000000..8fcdf65
> --- /dev/null
> +++ b/arch/mips/mach-ath79/ar934x/cpu.c
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (C) 2016 Marek Vasut <marex@denx.de>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +
> +/* The lowlevel_init() is not needed on AR934x */
> +void lowlevel_init(void) {}
> diff --git a/arch/mips/mach-ath79/ar934x/ddr.c b/arch/mips/mach-ath79/ar934x/ddr.c
> new file mode 100644
> index 0000000..175ffa5
> --- /dev/null
> +++ b/arch/mips/mach-ath79/ar934x/ddr.c
> @@ -0,0 +1,165 @@
> +/*
> + * Copyright (C) 2016 Marek Vasut <marex@denx.de>
> + *
> + * Based on RAM init sequence by Piotr Dymacz <pepe2k@gmail.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <mach/ar71xx_regs.h>
> +#include <mach/reset.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +enum {
> + AR934X_SDRAM = 0,
> + AR934X_DDR1,
> + AR934X_DDR2,
> +};
> +
> +struct ar934x_mem_config {
> + u32 config1;
> + u32 config2;
> + u32 mode;
> + u32 extmode;
> + u32 tap;
> +};
> +
> +static const struct ar934x_mem_config ar934x_mem_config[] = {
> + [AR934X_SDRAM] = { 0x7fbe8cd0, 0x959f66a8, 0x33, 0, 0x1f1f },
> + [AR934X_DDR1] = { 0x7fd48cd0, 0x99d0e6a8, 0x33, 0, 0x14 },
> + [AR934X_DDR2] = { 0xc7d48cd0, 0x9dd0e6a8, 0x33, 0, 0x10012 },
> +};
> +
> +void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
> +{
> + void __iomem *ddr_regs;
> + const struct ar934x_mem_config *memcfg;
> + int memtype;
> + u32 reg, cycle, ctl;
> +
> + ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
> + MAP_NOCACHE);
> +
> + reg = get_bootstrap();
> + if (reg & AR934X_BOOTSTRAP_SDRAM_DISABLED) { /* DDR */
> + if (reg & AR934X_BOOTSTRAP_DDR1) { /* DDR 1 */
> + memtype = AR934X_DDR1;
> + cycle = 0xffff;
> + } else { /* DDR 2 */
> + memtype = AR934X_DDR2;
> + if (gd->arch.rev) {
> + ctl = BIT(6); /* Undocumented bit :-( */
> + if (reg & BIT(3))
> + cycle = 0xff;
> + else
> + cycle = 0xffff;
> + } else {
> + /* Force DDR2/x16 configuratio on old chips. */
> + ctl = 0;
> + cycle = 0xffff; /* DDR2 16bit */
> + }
> +
> + writel(0xe59, ddr_regs + AR934X_DDR_REG_DDR2_CONFIG);
> + udelay(100);
> +
> + writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(ctl, ddr_regs + AR934X_DDR_REG_CTL_CONF);
> + udelay(10);
> + }
> + } else { /* SDRAM */
> + memtype = AR934X_SDRAM;
> + cycle = 0xffffffff;
> +
> + writel(0x13b, ddr_regs + AR934X_DDR_REG_CTL_CONF);
> + udelay(100);
> +
> + /* Undocumented register */
> + writel(0x13b, ddr_regs + 0x118);
> + udelay(100);
> + }
> +
> + memcfg = &ar934x_mem_config[memtype];
> +
> + writel(memcfg->config1, ddr_regs + AR71XX_DDR_REG_CONFIG);
> + udelay(100);
> +
> + writel(memcfg->config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
> + udelay(100);
> +
> + writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_MODE);
> + mdelay(1);
> +
> + writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + if (memtype == AR934X_DDR2) {
> + writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_EMR);
> + udelay(100);
> +
> + writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> + }
> +
> + if (memtype != AR934X_SDRAM)
> + writel(0x402, ddr_regs + AR71XX_DDR_REG_EMR);
> +
> + udelay(100);
> +
> + writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(memcfg->mode, ddr_regs + AR71XX_DDR_REG_MODE);
> + udelay(100);
> +
> + writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
> + udelay(10);
> +
> + writel(0x412c /* FIXME */, ddr_regs + AR71XX_DDR_REG_REFRESH);
> + udelay(100);
> +
> + writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
> + writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
> +
> + if (memtype != AR934X_SDRAM) {
> + if ((gd->arch.rev && (reg & BIT(3))) || !gd->arch.rev) {
> + writel(memcfg->tap, ddr_regs + AR934X_DDR_REG_TAP_CTRL2);
> + writel(memcfg->tap, ddr_regs + AR934X_DDR_REG_TAP_CTRL3);
> + }
> + }
> +
> + writel(cycle, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
> + udelay(100);
> +
> + writel(0x74444444, ddr_regs + AR934X_DDR_REG_BURST);
> + udelay(100);
> +
> + writel(0x222, ddr_regs + AR934X_DDR_REG_BURST2);
> + udelay(100);
> +
> + writel(0xfffff, ddr_regs + AR934X_DDR_REG_TIMEOUT_MAX);
> + udelay(100);
> +
> + // FIXME PMU2 ddr ldo tune
> +// ar7240_reg_rmw_set(0xb8116c44, (0x3 << 19));
> +// udelay(100);
> +}
> +
> +void ddr_tap_tuning(void)
> +{
> +}
> diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> index a9630c0..a8e51cb 100644
> --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
> @@ -250,11 +250,22 @@
> #define AR933X_DDR_REG_TIMEOUT_CNT 0x9c
> #define AR933X_DDR_REG_TIMEOUT_ADDR 0x9c
>
> +#define AR934X_DDR_REG_TAP_CTRL2 0x24
> +#define AR934X_DDR_REG_TAP_CTRL3 0x28
> #define AR934X_DDR_REG_FLUSH_GE0 0x9c
> #define AR934X_DDR_REG_FLUSH_GE1 0xa0
> #define AR934X_DDR_REG_FLUSH_USB 0xa4
> #define AR934X_DDR_REG_FLUSH_PCIE 0xa8
> #define AR934X_DDR_REG_FLUSH_WMAC 0xac
> +#define AR934X_DDR_REG_FLUSH_SRC1 0xb0
> +#define AR934X_DDR_REG_FLUSH_SRC2 0xb4
> +#define AR934X_DDR_REG_DDR2_CONFIG 0xb8
> +#define AR934X_DDR_REG_EMR2 0xbc
> +#define AR934X_DDR_REG_EMR3 0xc0
> +#define AR934X_DDR_REG_BURST 0xc4
> +#define AR934X_DDR_REG_BURST2 0xc8
> +#define AR934X_DDR_REG_TIMEOUT_MAX 0xcc
> +#define AR934X_DDR_REG_CTL_CONF 0x108
>
> #define QCA953X_DDR_REG_FLUSH_GE0 0x9c
> #define QCA953X_DDR_REG_FLUSH_GE1 0xa0
> @@ -341,6 +352,8 @@
> #define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
> #define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
> #define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c
> +#define AR934X_PLL_DDR_DIT_FRAC_REG 0x44
> +#define AR934X_PLL_CPU_DIT_FRAC_REG 0x48
>
> #define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
> #define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
> @@ -348,8 +361,12 @@
> #define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f
> #define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
> #define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
> +#define AR934X_PLL_CPU_CONFIG_RANGE_SHIFT 17
> +#define AR934X_PLL_CPU_CONFIG_RANGE_MASK 0x3
> #define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
> #define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
> +#define AR934X_PLL_CPU_CONFIG_PLLPWD BIT(30)
> +#define AR934X_PLL_CPU_CONFIG_UPDATING BIT(31)
>
> #define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
> #define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
> @@ -357,8 +374,12 @@
> #define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f
> #define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
> #define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
> +#define AR934X_PLL_DDR_CONFIG_RANGE_SHIFT 21
> +#define AR934X_PLL_DDR_CONFIG_RANGE_MASK 0x3
> #define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
> #define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
> +#define AR934X_PLL_DDR_CONFIG_PLLPWD BIT(30)
> +#define AR934X_PLL_DDR_CONFIG_UPDATING BIT(31)
>
> #define AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
> #define AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
> @@ -375,6 +396,26 @@
>
> #define AR934X_PLL_SWITCH_CLK_CTRL_MDIO_CLK_SEL BIT(6)
>
> +#define AR934X_PLL_DDR_DIT_FRAC_MAX_SHIFT 0
> +#define AR934X_PLL_DDR_DIT_FRAC_MAX_MASK 0x3ff
> +#define AR934X_PLL_DDR_DIT_FRAC_MIN_SHIFT 10
> +#define AR934X_PLL_DDR_DIT_FRAC_MIN_MASK 0x3ff
> +#define AR934X_PLL_DDR_DIT_FRAC_STEP_SHIFT 20
> +#define AR934X_PLL_DDR_DIT_FRAC_STEP_MASK 0x3f
> +#define AR934X_PLL_DDR_DIT_UPD_CNT_SHIFT 27
> +#define AR934X_PLL_DDR_DIT_UPD_CNT_MASK 0x3f
> +#define AR934X_PLL_DDR_DIT_DITHER_EN BIT(31)
> +
> +#define AR934X_PLL_CPU_DIT_FRAC_MAX_SHIFT 0
> +#define AR934X_PLL_CPU_DIT_FRAC_MAX_MASK 0x3f
> +#define AR934X_PLL_CPU_DIT_FRAC_MIN_SHIFT 6
> +#define AR934X_PLL_CPU_DIT_FRAC_MIN_MASK 0x3f
> +#define AR934X_PLL_CPU_DIT_FRAC_STEP_SHIFT 12
> +#define AR934X_PLL_CPU_DIT_FRAC_STEP_MASK 0x3f
> +#define AR934X_PLL_CPU_DIT_UPD_CNT_SHIFT 18
> +#define AR934X_PLL_CPU_DIT_UPD_CNT_MASK 0x3f
> +#define AR934X_PLL_CPU_DIT_DITHER_EN BIT(31)
> +
> #define QCA953X_PLL_CPU_CONFIG_REG 0x00
> #define QCA953X_PLL_DDR_CONFIG_REG 0x04
> #define QCA953X_PLL_CLK_CTRL_REG 0x08
> @@ -1081,10 +1122,12 @@
> #define AR934X_SRIF_CPU_DPLL1_REG 0x1c0
> #define AR934X_SRIF_CPU_DPLL2_REG 0x1c4
> #define AR934X_SRIF_CPU_DPLL3_REG 0x1c8
> +#define AR934X_SRIF_CPU_DPLL4_REG 0x1cc
>
> #define AR934X_SRIF_DDR_DPLL1_REG 0x240
> #define AR934X_SRIF_DDR_DPLL2_REG 0x244
> #define AR934X_SRIF_DDR_DPLL3_REG 0x248
> +#define AR934X_SRIF_DDR_DPLL4_REG 0x24c
>
> #define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27
> #define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f
> diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h
> index 2c6c118..17af082 100644
> --- a/arch/mips/mach-ath79/include/mach/ath79.h
> +++ b/arch/mips/mach-ath79/include/mach/ath79.h
> @@ -143,4 +143,7 @@ static inline int soc_is_qca956x(void)
> int ath79_eth_reset(void);
> 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);
> +
> #endif /* __ASM_MACH_ATH79_H */
>
--
- Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160506/c2a5a90b/attachment.sig>
next prev parent reply other threads:[~2016-05-06 11:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-05 18:14 [U-Boot] [PATCH 1/8] mips: ath79: Fix ar71xx_regs.h indent Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 2/8] mips: ath79: Fix compiler warning on const assignment Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 3/8] mips: ath79: dts: Add generic-ehci node Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 4/8] mips: ath79: Add support for ungating USB on ar933x and ar934x Marek Vasut
2016-05-06 11:34 ` Daniel Schwierzeck
2016-05-06 16:59 ` Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 5/8] mips: ath79: dts: Add ethernet MAC nodes Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 6/8] mips: ath79: Add support for ungating ethernet on ar933x and ar934x Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 7/8] mips: ath79: Add AR934x support Marek Vasut
2016-05-06 11:32 ` Daniel Schwierzeck [this message]
2016-05-06 17:12 ` Marek Vasut
2016-05-05 18:14 ` [U-Boot] [PATCH 8/8] mips: ath79: Add support for TPLink WDR4300 Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=572C80D2.7030906@gmail.com \
--to=daniel.schwierzeck@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.