root/drivers/clk/mvebu/armada-370.c

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

DEFINITIONS

This source file includes following definitions.
  1. a370_get_tclk_freq
  2. a370_get_cpu_freq
  3. a370_get_clk_ratio
  4. a370_is_sscg_enabled
  5. a370_clk_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Marvell Armada 370 SoC clocks
   4  *
   5  * Copyright (C) 2012 Marvell
   6  *
   7  * Gregory CLEMENT <gregory.clement@free-electrons.com>
   8  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
   9  * Andrew Lunn <andrew@lunn.ch>
  10  *
  11  */
  12 
  13 #include <linux/kernel.h>
  14 #include <linux/clk-provider.h>
  15 #include <linux/io.h>
  16 #include <linux/of.h>
  17 #include "common.h"
  18 
  19 /*
  20  * Core Clocks
  21  */
  22 
  23 #define SARL                            0       /* Low part [0:31] */
  24 #define  SARL_A370_SSCG_ENABLE          BIT(10)
  25 #define  SARL_A370_PCLK_FREQ_OPT        11
  26 #define  SARL_A370_PCLK_FREQ_OPT_MASK   0xF
  27 #define  SARL_A370_FAB_FREQ_OPT         15
  28 #define  SARL_A370_FAB_FREQ_OPT_MASK    0x1F
  29 #define  SARL_A370_TCLK_FREQ_OPT        20
  30 #define  SARL_A370_TCLK_FREQ_OPT_MASK   0x1
  31 
  32 enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK };
  33 
  34 static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = {
  35         { .id = A370_CPU_TO_NBCLK, .name = "nbclk" },
  36         { .id = A370_CPU_TO_HCLK, .name = "hclk" },
  37         { .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" },
  38 };
  39 
  40 static const u32 a370_tclk_freqs[] __initconst = {
  41         166000000,
  42         200000000,
  43 };
  44 
  45 static u32 __init a370_get_tclk_freq(void __iomem *sar)
  46 {
  47         u8 tclk_freq_select = 0;
  48 
  49         tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
  50                             SARL_A370_TCLK_FREQ_OPT_MASK);
  51         return a370_tclk_freqs[tclk_freq_select];
  52 }
  53 
  54 static const u32 a370_cpu_freqs[] __initconst = {
  55         400000000,
  56         533000000,
  57         667000000,
  58         800000000,
  59         1000000000,
  60         1067000000,
  61         1200000000,
  62 };
  63 
  64 static u32 __init a370_get_cpu_freq(void __iomem *sar)
  65 {
  66         u32 cpu_freq;
  67         u8 cpu_freq_select = 0;
  68 
  69         cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
  70                            SARL_A370_PCLK_FREQ_OPT_MASK);
  71         if (cpu_freq_select >= ARRAY_SIZE(a370_cpu_freqs)) {
  72                 pr_err("CPU freq select unsupported %d\n", cpu_freq_select);
  73                 cpu_freq = 0;
  74         } else
  75                 cpu_freq = a370_cpu_freqs[cpu_freq_select];
  76 
  77         return cpu_freq;
  78 }
  79 
  80 static const int a370_nbclk_ratios[32][2] __initconst = {
  81         {0, 1}, {1, 2}, {2, 2}, {2, 2},
  82         {1, 2}, {1, 2}, {1, 1}, {2, 3},
  83         {0, 1}, {1, 2}, {2, 4}, {0, 1},
  84         {1, 2}, {0, 1}, {0, 1}, {2, 2},
  85         {0, 1}, {0, 1}, {0, 1}, {1, 1},
  86         {2, 3}, {0, 1}, {0, 1}, {0, 1},
  87         {0, 1}, {0, 1}, {0, 1}, {1, 1},
  88         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  89 };
  90 
  91 static const int a370_hclk_ratios[32][2] __initconst = {
  92         {0, 1}, {1, 2}, {2, 6}, {2, 3},
  93         {1, 3}, {1, 4}, {1, 2}, {2, 6},
  94         {0, 1}, {1, 6}, {2, 10}, {0, 1},
  95         {1, 4}, {0, 1}, {0, 1}, {2, 5},
  96         {0, 1}, {0, 1}, {0, 1}, {1, 2},
  97         {2, 6}, {0, 1}, {0, 1}, {0, 1},
  98         {0, 1}, {0, 1}, {0, 1}, {1, 1},
  99         {0, 1}, {0, 1}, {0, 1}, {0, 1},
 100 };
 101 
 102 static const int a370_dramclk_ratios[32][2] __initconst = {
 103         {0, 1}, {1, 2}, {2, 3}, {2, 3},
 104         {1, 3}, {1, 2}, {1, 2}, {2, 6},
 105         {0, 1}, {1, 3}, {2, 5}, {0, 1},
 106         {1, 4}, {0, 1}, {0, 1}, {2, 5},
 107         {0, 1}, {0, 1}, {0, 1}, {1, 1},
 108         {2, 3}, {0, 1}, {0, 1}, {0, 1},
 109         {0, 1}, {0, 1}, {0, 1}, {1, 1},
 110         {0, 1}, {0, 1}, {0, 1}, {0, 1},
 111 };
 112 
 113 static void __init a370_get_clk_ratio(
 114         void __iomem *sar, int id, int *mult, int *div)
 115 {
 116         u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
 117                 SARL_A370_FAB_FREQ_OPT_MASK);
 118 
 119         switch (id) {
 120         case A370_CPU_TO_NBCLK:
 121                 *mult = a370_nbclk_ratios[opt][0];
 122                 *div = a370_nbclk_ratios[opt][1];
 123                 break;
 124         case A370_CPU_TO_HCLK:
 125                 *mult = a370_hclk_ratios[opt][0];
 126                 *div = a370_hclk_ratios[opt][1];
 127                 break;
 128         case A370_CPU_TO_DRAMCLK:
 129                 *mult = a370_dramclk_ratios[opt][0];
 130                 *div = a370_dramclk_ratios[opt][1];
 131                 break;
 132         }
 133 }
 134 
 135 static bool a370_is_sscg_enabled(void __iomem *sar)
 136 {
 137         return !(readl(sar) & SARL_A370_SSCG_ENABLE);
 138 }
 139 
 140 static const struct coreclk_soc_desc a370_coreclks = {
 141         .get_tclk_freq = a370_get_tclk_freq,
 142         .get_cpu_freq = a370_get_cpu_freq,
 143         .get_clk_ratio = a370_get_clk_ratio,
 144         .is_sscg_enabled = a370_is_sscg_enabled,
 145         .fix_sscg_deviation = kirkwood_fix_sscg_deviation,
 146         .ratios = a370_coreclk_ratios,
 147         .num_ratios = ARRAY_SIZE(a370_coreclk_ratios),
 148 };
 149 
 150 /*
 151  * Clock Gating Control
 152  */
 153 
 154 static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
 155         { "audio", NULL, 0, 0 },
 156         { "pex0_en", NULL, 1, 0 },
 157         { "pex1_en", NULL,  2, 0 },
 158         { "ge1", NULL, 3, 0 },
 159         { "ge0", NULL, 4, 0 },
 160         { "pex0", "pex0_en", 5, 0 },
 161         { "pex1", "pex1_en", 9, 0 },
 162         { "sata0", NULL, 15, 0 },
 163         { "sdio", NULL, 17, 0 },
 164         { "crypto", NULL, 23, CLK_IGNORE_UNUSED },
 165         { "tdm", NULL, 25, 0 },
 166         { "ddr", NULL, 28, CLK_IGNORE_UNUSED },
 167         { "sata1", NULL, 30, 0 },
 168         { }
 169 };
 170 
 171 static void __init a370_clk_init(struct device_node *np)
 172 {
 173         struct device_node *cgnp =
 174                 of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock");
 175 
 176         mvebu_coreclk_setup(np, &a370_coreclks);
 177 
 178         if (cgnp) {
 179                 mvebu_clk_gating_setup(cgnp, a370_gating_desc);
 180                 of_node_put(cgnp);
 181         }
 182 }
 183 CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init);
 184 

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