root/drivers/clk/tegra/clk-tegra-fixed.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tegra_osc_clk_init
  2. tegra_fixed_clk_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012, 2013, NVIDIA CORPORATION.  All rights reserved.
   4  */
   5 
   6 #include <linux/io.h>
   7 #include <linux/clk-provider.h>
   8 #include <linux/of.h>
   9 #include <linux/of_address.h>
  10 #include <linux/delay.h>
  11 #include <linux/export.h>
  12 #include <linux/clk/tegra.h>
  13 
  14 #include "clk.h"
  15 #include "clk-id.h"
  16 
  17 #define OSC_CTRL                        0x50
  18 #define OSC_CTRL_OSC_FREQ_SHIFT         28
  19 #define OSC_CTRL_PLL_REF_DIV_SHIFT      26
  20 
  21 int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
  22                               unsigned long *input_freqs, unsigned int num,
  23                               unsigned int clk_m_div, unsigned long *osc_freq,
  24                               unsigned long *pll_ref_freq)
  25 {
  26         struct clk *clk, *osc;
  27         struct clk **dt_clk;
  28         u32 val, pll_ref_div;
  29         unsigned osc_idx;
  30 
  31         val = readl_relaxed(clk_base + OSC_CTRL);
  32         osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT;
  33 
  34         if (osc_idx < num)
  35                 *osc_freq = input_freqs[osc_idx];
  36         else
  37                 *osc_freq = 0;
  38 
  39         if (!*osc_freq) {
  40                 WARN_ON(1);
  41                 return -EINVAL;
  42         }
  43 
  44         osc = clk_register_fixed_rate(NULL, "osc", NULL, 0, *osc_freq);
  45 
  46         dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks);
  47         if (!dt_clk)
  48                 return 0;
  49 
  50         clk = clk_register_fixed_factor(NULL, "clk_m", "osc",
  51                                         0, 1, clk_m_div);
  52         *dt_clk = clk;
  53 
  54         /* pll_ref */
  55         val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
  56         pll_ref_div = 1 << val;
  57         dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, clks);
  58         if (!dt_clk)
  59                 return 0;
  60 
  61         clk = clk_register_fixed_factor(NULL, "pll_ref", "osc",
  62                                         0, 1, pll_ref_div);
  63         *dt_clk = clk;
  64 
  65         if (pll_ref_freq)
  66                 *pll_ref_freq = *osc_freq / pll_ref_div;
  67 
  68         return 0;
  69 }
  70 
  71 void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
  72 {
  73         struct clk *clk;
  74         struct clk **dt_clk;
  75 
  76         /* clk_32k */
  77         dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks);
  78         if (dt_clk) {
  79                 clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768);
  80                 *dt_clk = clk;
  81         }
  82 
  83         /* clk_m_div2 */
  84         dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div2, tegra_clks);
  85         if (dt_clk) {
  86                 clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m",
  87                                         CLK_SET_RATE_PARENT, 1, 2);
  88                 *dt_clk = clk;
  89         }
  90 
  91         /* clk_m_div4 */
  92         dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m_div4, tegra_clks);
  93         if (dt_clk) {
  94                 clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m",
  95                                         CLK_SET_RATE_PARENT, 1, 4);
  96                 *dt_clk = clk;
  97         }
  98 }

/* [<][>][^][v][top][bottom][index][help] */