All of lore.kernel.org
 help / color / mirror / Atom feed
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>

  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.