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