Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: mvebu: add Orion5x clock driver

This commit adds a core clock driver for the Orion5x SoC, with support
for the tclk, the CPU frequency and the DDR frequency. All the details
about the Sample-At-Reset register were extracted from the U-Boot
sources for Orion5x.

Note that Orion5x does not have gatable clocks, so this core clock
driver is sufficient to support clocking on Orion5x platforms.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Link: https://lkml.kernel.org/r/1398202002-28530-5-git-send-email-thomas.petazzoni@free-electrons.com
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>

authored by

Thomas Petazzoni and committed by
Jason Cooper
66ecbfea c9eaa447

+223
+8
Documentation/devicetree/bindings/clock/mvebu-core-clock.txt
··· 29 29 2 = l2clk (L2 Cache clock derived from CPU0 clock) 30 30 3 = ddrclk (DDR controller clock derived from CPU0 clock) 31 31 32 + The following is a list of provided IDs and clock names on Orion5x: 33 + 0 = tclk (Internal Bus clock) 34 + 1 = cpuclk (CPU0 clock) 35 + 2 = ddrclk (DDR controller clock derived from CPU0 clock) 36 + 32 37 Required properties: 33 38 - compatible : shall be one of the following: 34 39 "marvell,armada-370-core-clock" - For Armada 370 SoC core clocks ··· 43 38 "marvell,dove-core-clock" - for Dove SoC core clocks 44 39 "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) 45 40 "marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC 41 + "marvell,mv88f5182-core-clock" - for Orion MV88F5182 SoC 42 + "marvell,mv88f5281-core-clock" - for Orion MV88F5281 SoC 43 + "marvell,mv88f6183-core-clock" - for Orion MV88F6183 SoC 46 44 - reg : shall be the register address of the Sample-At-Reset (SAR) register 47 45 - #clock-cells : from common clock binding; shall be set to 1 48 46
+4
drivers/clk/mvebu/Kconfig
··· 34 34 config KIRKWOOD_CLK 35 35 bool 36 36 select MVEBU_CLK_COMMON 37 + 38 + config ORION_CLK 39 + bool 40 + select MVEBU_CLK_COMMON
+1
drivers/clk/mvebu/Makefile
··· 8 8 obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 9 9 obj-$(CONFIG_DOVE_CLK) += dove.o 10 10 obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o 11 + obj-$(CONFIG_ORION_CLK) += orion.o
+210
drivers/clk/mvebu/orion.c
··· 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 + 19 + static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = { 20 + { .id = 0, .name = "ddrclk", } 21 + }; 22 + 23 + /* 24 + * Orion 5182 25 + */ 26 + 27 + #define SAR_MV88F5182_TCLK_FREQ 8 28 + #define SAR_MV88F5182_TCLK_FREQ_MASK 0x3 29 + 30 + static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar) 31 + { 32 + u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) & 33 + SAR_MV88F5182_TCLK_FREQ_MASK; 34 + if (opt == 1) 35 + return 150000000; 36 + else if (opt == 2) 37 + return 166666667; 38 + else 39 + return 0; 40 + } 41 + 42 + #define SAR_MV88F5182_CPU_FREQ 4 43 + #define SAR_MV88F5182_CPU_FREQ_MASK 0xf 44 + 45 + static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar) 46 + { 47 + u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & 48 + SAR_MV88F5182_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 + 59 + static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id, 60 + int *mult, int *div) 61 + { 62 + u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) & 63 + SAR_MV88F5182_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 + 76 + static const struct coreclk_soc_desc mv88f5182_coreclks = { 77 + .get_tclk_freq = mv88f5182_get_tclk_freq, 78 + .get_cpu_freq = mv88f5182_get_cpu_freq, 79 + .get_clk_ratio = mv88f5182_get_clk_ratio, 80 + .ratios = orion_coreclk_ratios, 81 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 82 + }; 83 + 84 + static void __init mv88f5182_clk_init(struct device_node *np) 85 + { 86 + return mvebu_coreclk_setup(np, &mv88f5182_coreclks); 87 + } 88 + 89 + CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init); 90 + 91 + /* 92 + * Orion 5281 93 + */ 94 + 95 + static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar) 96 + { 97 + /* On 5281, tclk is always 166 Mhz */ 98 + return 166666667; 99 + } 100 + 101 + #define SAR_MV88F5281_CPU_FREQ 4 102 + #define SAR_MV88F5281_CPU_FREQ_MASK 0xf 103 + 104 + static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar) 105 + { 106 + u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & 107 + SAR_MV88F5281_CPU_FREQ_MASK; 108 + if (opt == 1 || opt == 2) 109 + return 400000000; 110 + else if (opt == 3) 111 + return 500000000; 112 + else 113 + return 0; 114 + } 115 + 116 + static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id, 117 + int *mult, int *div) 118 + { 119 + u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) & 120 + SAR_MV88F5281_CPU_FREQ_MASK; 121 + if (opt == 1) { 122 + *mult = 1; 123 + *div = 2; 124 + } else if (opt == 2 || opt == 3) { 125 + *mult = 1; 126 + *div = 3; 127 + } else { 128 + *mult = 0; 129 + *div = 1; 130 + } 131 + } 132 + 133 + static const struct coreclk_soc_desc mv88f5281_coreclks = { 134 + .get_tclk_freq = mv88f5281_get_tclk_freq, 135 + .get_cpu_freq = mv88f5281_get_cpu_freq, 136 + .get_clk_ratio = mv88f5281_get_clk_ratio, 137 + .ratios = orion_coreclk_ratios, 138 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 139 + }; 140 + 141 + static void __init mv88f5281_clk_init(struct device_node *np) 142 + { 143 + return mvebu_coreclk_setup(np, &mv88f5281_coreclks); 144 + } 145 + 146 + CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init); 147 + 148 + /* 149 + * Orion 6183 150 + */ 151 + 152 + #define SAR_MV88F6183_TCLK_FREQ 9 153 + #define SAR_MV88F6183_TCLK_FREQ_MASK 0x1 154 + 155 + static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar) 156 + { 157 + u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) & 158 + SAR_MV88F6183_TCLK_FREQ_MASK; 159 + if (opt == 0) 160 + return 133333333; 161 + else if (opt == 1) 162 + return 166666667; 163 + else 164 + return 0; 165 + } 166 + 167 + #define SAR_MV88F6183_CPU_FREQ 1 168 + #define SAR_MV88F6183_CPU_FREQ_MASK 0x3f 169 + 170 + static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar) 171 + { 172 + u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & 173 + SAR_MV88F6183_CPU_FREQ_MASK; 174 + if (opt == 9) 175 + return 333333333; 176 + else if (opt == 17) 177 + return 400000000; 178 + else 179 + return 0; 180 + } 181 + 182 + static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id, 183 + int *mult, int *div) 184 + { 185 + u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) & 186 + SAR_MV88F6183_CPU_FREQ_MASK; 187 + if (opt == 9 || opt == 17) { 188 + *mult = 1; 189 + *div = 2; 190 + } else { 191 + *mult = 0; 192 + *div = 1; 193 + } 194 + } 195 + 196 + static const struct coreclk_soc_desc mv88f6183_coreclks = { 197 + .get_tclk_freq = mv88f6183_get_tclk_freq, 198 + .get_cpu_freq = mv88f6183_get_cpu_freq, 199 + .get_clk_ratio = mv88f6183_get_clk_ratio, 200 + .ratios = orion_coreclk_ratios, 201 + .num_ratios = ARRAY_SIZE(orion_coreclk_ratios), 202 + }; 203 + 204 + 205 + static void __init mv88f6183_clk_init(struct device_node *np) 206 + { 207 + return mvebu_coreclk_setup(np, &mv88f6183_coreclks); 208 + } 209 + 210 + CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init);