279 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Marvell Orion SoC clocks4 *5 * Copyright (C) 2014 Thomas Petazzoni6 *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 518123 */24 25#define SAR_MV88F5181_TCLK_FREQ 826#define SAR_MV88F5181_TCLK_FREQ_MASK 0x327 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 else39 return 0;40}41 42#define SAR_MV88F5181_CPU_FREQ 443#define SAR_MV88F5181_CPU_FREQ_MASK 0xf44 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 else56 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 518293 */94 95#define SAR_MV88F5182_TCLK_FREQ 896#define SAR_MV88F5182_TCLK_FREQ_MASK 0x397 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 else107 return 0;108}109 110#define SAR_MV88F5182_CPU_FREQ 4111#define SAR_MV88F5182_CPU_FREQ_MASK 0xf112 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 else124 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 5281161 */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 4170#define SAR_MV88F5281_CPU_FREQ_MASK 0xf171 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 else181 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 6183218 */219 220#define SAR_MV88F6183_TCLK_FREQ 9221#define SAR_MV88F6183_TCLK_FREQ_MASK 0x1222 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 else232 return 0;233}234 235#define SAR_MV88F6183_CPU_FREQ 1236#define SAR_MV88F6183_CPU_FREQ_MASK 0x3f237 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 else247 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