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