uboot/arch/mips/mach-ath79/ar933x/clk.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
   4 */
   5
   6#include <common.h>
   7#include <asm/io.h>
   8#include <asm/addrspace.h>
   9#include <asm/types.h>
  10#include <mach/ar71xx_regs.h>
  11#include <mach/ath79.h>
  12
  13DECLARE_GLOBAL_DATA_PTR;
  14
  15static u32 ar933x_get_xtal(void)
  16{
  17        u32 val;
  18
  19        val = ath79_get_bootstrap();
  20        if (val & AR933X_BOOTSTRAP_REF_CLK_40)
  21                return 40000000;
  22        else
  23                return 25000000;
  24}
  25
  26int get_serial_clock(void)
  27{
  28        return ar933x_get_xtal();
  29}
  30
  31int get_clocks(void)
  32{
  33        void __iomem *regs;
  34        u32 val, xtal, pll, div;
  35
  36        regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
  37                           MAP_NOCACHE);
  38        xtal = ar933x_get_xtal();
  39        val = readl(regs + AR933X_PLL_CPU_CONFIG_REG);
  40
  41        /* VCOOUT = XTAL * DIV_INT */
  42        div = (val >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT)
  43                        & AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
  44        pll = xtal / div;
  45
  46        /* PLLOUT = VCOOUT * (1/2^OUTDIV) */
  47        div = (val >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT)
  48                        & AR933X_PLL_CPU_CONFIG_NINT_MASK;
  49        pll *= div;
  50        div = (val >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT)
  51                        & AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
  52        if (!div)
  53                div = 1;
  54        pll >>= div;
  55
  56        val = readl(regs + AR933X_PLL_CLK_CTRL_REG);
  57
  58        /* CPU_CLK = PLLOUT / CPU_POST_DIV */
  59        div = ((val >> AR933X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT)
  60                        & AR933X_PLL_CLK_CTRL_CPU_POST_DIV_MASK) + 1;
  61        gd->cpu_clk = pll / div;
  62
  63        /* DDR_CLK = PLLOUT / DDR_POST_DIV */
  64        div = ((val >> AR933X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT)
  65                        & AR933X_PLL_CLK_CTRL_DDR_POST_DIV_MASK) + 1;
  66        gd->mem_clk = pll / div;
  67
  68        /* AHB_CLK = PLLOUT / AHB_POST_DIV */
  69        div = ((val >> AR933X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT)
  70                        & AR933X_PLL_CLK_CTRL_AHB_POST_DIV_MASK) + 1;
  71        gd->bus_clk = pll / div;
  72
  73        return 0;
  74}
  75
  76ulong get_bus_freq(ulong dummy)
  77{
  78        if (!gd->bus_clk)
  79                get_clocks();
  80        return gd->bus_clk;
  81}
  82
  83ulong get_ddr_freq(ulong dummy)
  84{
  85        if (!gd->mem_clk)
  86                get_clocks();
  87        return gd->mem_clk;
  88}
  89