root/drivers/clk/mvebu/armada-38x.c

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

DEFINITIONS

This source file includes following definitions.
  1. armada_38x_get_tclk_freq
  2. armada_38x_get_cpu_freq
  3. armada_38x_get_clk_ratio
  4. armada_38x_coreclk_init
  5. armada_38x_clk_gating_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Marvell Armada 380/385 SoC clocks
   4  *
   5  * Copyright (C) 2014 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  * SAR[14:10] : Ratios between PCLK0, NBCLK, HCLK and DRAM clocks
  21  *
  22  * SAR[15]    : TCLK frequency
  23  *               0 = 250 MHz
  24  *               1 = 200 MHz
  25  */
  26 
  27 #define SAR_A380_TCLK_FREQ_OPT            15
  28 #define SAR_A380_TCLK_FREQ_OPT_MASK       0x1
  29 #define SAR_A380_CPU_DDR_L2_FREQ_OPT      10
  30 #define SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK 0x1F
  31 
  32 static const u32 armada_38x_tclk_frequencies[] __initconst = {
  33         250000000,
  34         200000000,
  35 };
  36 
  37 static u32 __init armada_38x_get_tclk_freq(void __iomem *sar)
  38 {
  39         u8 tclk_freq_select;
  40 
  41         tclk_freq_select = ((readl(sar) >> SAR_A380_TCLK_FREQ_OPT) &
  42                             SAR_A380_TCLK_FREQ_OPT_MASK);
  43         return armada_38x_tclk_frequencies[tclk_freq_select];
  44 }
  45 
  46 static const u32 armada_38x_cpu_frequencies[] __initconst = {
  47         666 * 1000 * 1000,  0, 800 * 1000 * 1000, 0,
  48         1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
  49         1332 * 1000 * 1000, 0, 0, 0,
  50         1600 * 1000 * 1000, 0, 0, 0,
  51         1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
  52 };
  53 
  54 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
  55 {
  56         u8 cpu_freq_select;
  57 
  58         cpu_freq_select = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) &
  59                            SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK);
  60         if (cpu_freq_select >= ARRAY_SIZE(armada_38x_cpu_frequencies)) {
  61                 pr_err("Selected CPU frequency (%d) unsupported\n",
  62                         cpu_freq_select);
  63                 return 0;
  64         }
  65 
  66         return armada_38x_cpu_frequencies[cpu_freq_select];
  67 }
  68 
  69 enum { A380_CPU_TO_DDR, A380_CPU_TO_L2 };
  70 
  71 static const struct coreclk_ratio armada_38x_coreclk_ratios[] __initconst = {
  72         { .id = A380_CPU_TO_L2,  .name = "l2clk" },
  73         { .id = A380_CPU_TO_DDR, .name = "ddrclk" },
  74 };
  75 
  76 static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
  77         {1, 2}, {0, 1}, {1, 2}, {0, 1},
  78         {1, 2}, {0, 1}, {1, 2}, {0, 1},
  79         {1, 2}, {0, 1}, {0, 1}, {0, 1},
  80         {1, 2}, {0, 1}, {0, 1}, {0, 1},
  81         {1, 2}, {0, 1}, {0, 1}, {1, 2},
  82         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  83         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  84         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  85 };
  86 
  87 static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = {
  88         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  89         {1, 2}, {0, 1}, {0, 1}, {0, 1},
  90         {1, 2}, {0, 1}, {0, 1}, {0, 1},
  91         {1, 2}, {0, 1}, {0, 1}, {0, 1},
  92         {1, 2}, {0, 1}, {0, 1}, {7, 15},
  93         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  94         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  95         {0, 1}, {0, 1}, {0, 1}, {0, 1},
  96 };
  97 
  98 static void __init armada_38x_get_clk_ratio(
  99         void __iomem *sar, int id, int *mult, int *div)
 100 {
 101         u32 opt = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) &
 102                 SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK);
 103 
 104         switch (id) {
 105         case A380_CPU_TO_L2:
 106                 *mult = armada_38x_cpu_l2_ratios[opt][0];
 107                 *div = armada_38x_cpu_l2_ratios[opt][1];
 108                 break;
 109         case A380_CPU_TO_DDR:
 110                 *mult = armada_38x_cpu_ddr_ratios[opt][0];
 111                 *div = armada_38x_cpu_ddr_ratios[opt][1];
 112                 break;
 113         }
 114 }
 115 
 116 static const struct coreclk_soc_desc armada_38x_coreclks = {
 117         .get_tclk_freq = armada_38x_get_tclk_freq,
 118         .get_cpu_freq = armada_38x_get_cpu_freq,
 119         .get_clk_ratio = armada_38x_get_clk_ratio,
 120         .ratios = armada_38x_coreclk_ratios,
 121         .num_ratios = ARRAY_SIZE(armada_38x_coreclk_ratios),
 122 };
 123 
 124 static void __init armada_38x_coreclk_init(struct device_node *np)
 125 {
 126         mvebu_coreclk_setup(np, &armada_38x_coreclks);
 127 }
 128 CLK_OF_DECLARE(armada_38x_core_clk, "marvell,armada-380-core-clock",
 129                armada_38x_coreclk_init);
 130 
 131 /*
 132  * Clock Gating Control
 133  */
 134 static const struct clk_gating_soc_desc armada_38x_gating_desc[] __initconst = {
 135         { "audio", NULL, 0 },
 136         { "ge2", NULL, 2 },
 137         { "ge1", NULL, 3 },
 138         { "ge0", NULL, 4 },
 139         { "pex1", NULL, 5 },
 140         { "pex2", NULL, 6 },
 141         { "pex3", NULL, 7 },
 142         { "pex0", NULL, 8 },
 143         { "usb3h0", NULL, 9 },
 144         { "usb3h1", NULL, 10 },
 145         { "usb3d", NULL, 11 },
 146         { "bm", NULL, 13 },
 147         { "crypto0z", NULL, 14 },
 148         { "sata0", NULL, 15 },
 149         { "crypto1z", NULL, 16 },
 150         { "sdio", NULL, 17 },
 151         { "usb2", NULL, 18 },
 152         { "crypto1", NULL, 21 },
 153         { "xor0", NULL, 22 },
 154         { "crypto0", NULL, 23 },
 155         { "tdm", NULL, 25 },
 156         { "xor1", NULL, 28 },
 157         { "sata1", NULL, 30 },
 158         { }
 159 };
 160 
 161 static void __init armada_38x_clk_gating_init(struct device_node *np)
 162 {
 163         mvebu_clk_gating_setup(np, armada_38x_gating_desc);
 164 }
 165 CLK_OF_DECLARE(armada_38x_clk_gating, "marvell,armada-380-gating-clock",
 166                armada_38x_clk_gating_init);

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