linux/drivers/clk/mvebu/orion.c
<<
>>
Prefs
   1/*
   2 * Marvell Orion SoC clocks
   3 *
   4 * Copyright (C) 2014 Thomas Petazzoni
   5 *
   6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
   7 *
   8 * This file is licensed under the terms of the GNU General Public
   9 * License version 2.  This program is licensed "as is" without any
  10 * warranty of any kind, whether express or implied.
  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
  19static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = {
  20        { .id = 0, .name = "ddrclk", }
  21};
  22
  23/*
  24 * Orion 5181
  25 */
  26
  27#define SAR_MV88F5181_TCLK_FREQ      8
  28#define SAR_MV88F5181_TCLK_FREQ_MASK 0x3
  29
  30static u32 __init mv88f5181_get_tclk_freq(void __iomem *sar)
  31{
  32        u32 opt = (readl(sar) >> SAR_MV88F5181_TCLK_FREQ) &
  33                SAR_MV88F5181_TCLK_FREQ_MASK;
  34        if (opt == 0)
  35                return 133333333;
  36        else if (opt == 1)
  37                return 150000000;
  38        else if (opt == 2)
  39                return 166666667;
  40        else
  41                return 0;
  42}
  43
  44#define SAR_MV88F5181_CPU_FREQ       4
  45#define SAR_MV88F5181_CPU_FREQ_MASK  0xf
  46
  47static u32 __init mv88f5181_get_cpu_freq(void __iomem *sar)
  48{
  49        u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
  50                SAR_MV88F5181_CPU_FREQ_MASK;
  51        if (opt == 0)
  52                return 333333333;
  53        else if (opt == 1 || opt == 2)
  54                return 400000000;
  55        else if (opt == 3)
  56                return 500000000;
  57        else
  58                return 0;
  59}
  60
  61static void __init mv88f5181_get_clk_ratio(void __iomem *sar, int id,
  62                                           int *mult, int *div)
  63{
  64        u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
  65                SAR_MV88F5181_CPU_FREQ_MASK;
  66        if (opt == 0 || opt == 1) {
  67                *mult = 1;
  68                *div  = 2;
  69        } else if (opt == 2 || opt == 3) {
  70                *mult = 1;
  71                *div  = 3;
  72        } else {
  73                *mult = 0;
  74                *div  = 1;
  75        }
  76}
  77
  78static const struct coreclk_soc_desc mv88f5181_coreclks = {
  79        .get_tclk_freq = mv88f5181_get_tclk_freq,
  80        .get_cpu_freq = mv88f5181_get_cpu_freq,
  81        .get_clk_ratio = mv88f5181_get_clk_ratio,
  82        .ratios = orion_coreclk_ratios,
  83        .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
  84};
  85
  86static void __init mv88f5181_clk_init(struct device_node *np)
  87{
  88        return mvebu_coreclk_setup(np, &mv88f5181_coreclks);
  89}
  90
  91CLK_OF_DECLARE(mv88f5181_clk, "marvell,mv88f5181-core-clock", mv88f5181_clk_init);
  92
  93/*
  94 * Orion 5182
  95 */
  96
  97#define SAR_MV88F5182_TCLK_FREQ      8
  98#define SAR_MV88F5182_TCLK_FREQ_MASK 0x3
  99
 100static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar)
 101{
 102        u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) &
 103                SAR_MV88F5182_TCLK_FREQ_MASK;
 104        if (opt == 1)
 105                return 150000000;
 106        else if (opt == 2)
 107                return 166666667;
 108        else
 109                return 0;
 110}
 111
 112#define SAR_MV88F5182_CPU_FREQ       4
 113#define SAR_MV88F5182_CPU_FREQ_MASK  0xf
 114
 115static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar)
 116{
 117        u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
 118                SAR_MV88F5182_CPU_FREQ_MASK;
 119        if (opt == 0)
 120                return 333333333;
 121        else if (opt == 1 || opt == 2)
 122                return 400000000;
 123        else if (opt == 3)
 124                return 500000000;
 125        else
 126                return 0;
 127}
 128
 129static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id,
 130                                           int *mult, int *div)
 131{
 132        u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
 133                SAR_MV88F5182_CPU_FREQ_MASK;
 134        if (opt == 0 || opt == 1) {
 135                *mult = 1;
 136                *div  = 2;
 137        } else if (opt == 2 || opt == 3) {
 138                *mult = 1;
 139                *div  = 3;
 140        } else {
 141                *mult = 0;
 142                *div  = 1;
 143        }
 144}
 145
 146static const struct coreclk_soc_desc mv88f5182_coreclks = {
 147        .get_tclk_freq = mv88f5182_get_tclk_freq,
 148        .get_cpu_freq = mv88f5182_get_cpu_freq,
 149        .get_clk_ratio = mv88f5182_get_clk_ratio,
 150        .ratios = orion_coreclk_ratios,
 151        .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
 152};
 153
 154static void __init mv88f5182_clk_init(struct device_node *np)
 155{
 156        return mvebu_coreclk_setup(np, &mv88f5182_coreclks);
 157}
 158
 159CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init);
 160
 161/*
 162 * Orion 5281
 163 */
 164
 165static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar)
 166{
 167        /* On 5281, tclk is always 166 Mhz */
 168        return 166666667;
 169}
 170
 171#define SAR_MV88F5281_CPU_FREQ       4
 172#define SAR_MV88F5281_CPU_FREQ_MASK  0xf
 173
 174static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar)
 175{
 176        u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
 177                SAR_MV88F5281_CPU_FREQ_MASK;
 178        if (opt == 1 || opt == 2)
 179                return 400000000;
 180        else if (opt == 3)
 181                return 500000000;
 182        else
 183                return 0;
 184}
 185
 186static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id,
 187                                           int *mult, int *div)
 188{
 189        u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
 190                SAR_MV88F5281_CPU_FREQ_MASK;
 191        if (opt == 1) {
 192                *mult = 1;
 193                *div = 2;
 194        } else if (opt == 2 || opt == 3) {
 195                *mult = 1;
 196                *div = 3;
 197        } else {
 198                *mult = 0;
 199                *div = 1;
 200        }
 201}
 202
 203static const struct coreclk_soc_desc mv88f5281_coreclks = {
 204        .get_tclk_freq = mv88f5281_get_tclk_freq,
 205        .get_cpu_freq = mv88f5281_get_cpu_freq,
 206        .get_clk_ratio = mv88f5281_get_clk_ratio,
 207        .ratios = orion_coreclk_ratios,
 208        .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
 209};
 210
 211static void __init mv88f5281_clk_init(struct device_node *np)
 212{
 213        return mvebu_coreclk_setup(np, &mv88f5281_coreclks);
 214}
 215
 216CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init);
 217
 218/*
 219 * Orion 6183
 220 */
 221
 222#define SAR_MV88F6183_TCLK_FREQ      9
 223#define SAR_MV88F6183_TCLK_FREQ_MASK 0x1
 224
 225static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar)
 226{
 227        u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) &
 228                SAR_MV88F6183_TCLK_FREQ_MASK;
 229        if (opt == 0)
 230                return 133333333;
 231        else if (opt == 1)
 232                return 166666667;
 233        else
 234                return 0;
 235}
 236
 237#define SAR_MV88F6183_CPU_FREQ       1
 238#define SAR_MV88F6183_CPU_FREQ_MASK  0x3f
 239
 240static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar)
 241{
 242        u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
 243                SAR_MV88F6183_CPU_FREQ_MASK;
 244        if (opt == 9)
 245                return 333333333;
 246        else if (opt == 17)
 247                return 400000000;
 248        else
 249                return 0;
 250}
 251
 252static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id,
 253                                           int *mult, int *div)
 254{
 255        u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
 256                SAR_MV88F6183_CPU_FREQ_MASK;
 257        if (opt == 9 || opt == 17) {
 258                *mult = 1;
 259                *div  = 2;
 260        } else {
 261                *mult = 0;
 262                *div  = 1;
 263        }
 264}
 265
 266static const struct coreclk_soc_desc mv88f6183_coreclks = {
 267        .get_tclk_freq = mv88f6183_get_tclk_freq,
 268        .get_cpu_freq = mv88f6183_get_cpu_freq,
 269        .get_clk_ratio = mv88f6183_get_clk_ratio,
 270        .ratios = orion_coreclk_ratios,
 271        .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
 272};
 273
 274
 275static void __init mv88f6183_clk_init(struct device_node *np)
 276{
 277        return mvebu_coreclk_setup(np, &mv88f6183_coreclks);
 278}
 279
 280CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init);
 281