1/* 2 * Marvell Dove SoC clocks 3 * 4 * Copyright (C) 2012 Marvell 5 * 6 * Gregory CLEMENT <gregory.clement@free-electrons.com> 7 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> 8 * Andrew Lunn <andrew@lunn.ch> 9 * 10 * This file is licensed under the terms of the GNU General Public 11 * License version 2. This program is licensed "as is" without any 12 * warranty of any kind, whether express or implied. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/clk-provider.h> 17#include <linux/io.h> 18#include <linux/of.h> 19#include "common.h" 20 21/* 22 * Core Clocks 23 * 24 * Dove PLL sample-at-reset configuration 25 * 26 * SAR0[8:5] : CPU frequency 27 * 5 = 1000 MHz 28 * 6 = 933 MHz 29 * 7 = 933 MHz 30 * 8 = 800 MHz 31 * 9 = 800 MHz 32 * 10 = 800 MHz 33 * 11 = 1067 MHz 34 * 12 = 667 MHz 35 * 13 = 533 MHz 36 * 14 = 400 MHz 37 * 15 = 333 MHz 38 * others reserved. 39 * 40 * SAR0[11:9] : CPU to L2 Clock divider ratio 41 * 0 = (1/1) * CPU 42 * 2 = (1/2) * CPU 43 * 4 = (1/3) * CPU 44 * 6 = (1/4) * CPU 45 * others reserved. 46 * 47 * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio 48 * 0 = (1/1) * CPU 49 * 2 = (1/2) * CPU 50 * 3 = (2/5) * CPU 51 * 4 = (1/3) * CPU 52 * 6 = (1/4) * CPU 53 * 8 = (1/5) * CPU 54 * 10 = (1/6) * CPU 55 * 12 = (1/7) * CPU 56 * 14 = (1/8) * CPU 57 * 15 = (1/10) * CPU 58 * others reserved. 59 * 60 * SAR0[24:23] : TCLK frequency 61 * 0 = 166 MHz 62 * 1 = 125 MHz 63 * others reserved. 64 */ 65 66#define SAR_DOVE_CPU_FREQ 5 67#define SAR_DOVE_CPU_FREQ_MASK 0xf 68#define SAR_DOVE_L2_RATIO 9 69#define SAR_DOVE_L2_RATIO_MASK 0x7 70#define SAR_DOVE_DDR_RATIO 12 71#define SAR_DOVE_DDR_RATIO_MASK 0xf 72#define SAR_DOVE_TCLK_FREQ 23 73#define SAR_DOVE_TCLK_FREQ_MASK 0x3 74 75enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR }; 76 77static const struct coreclk_ratio dove_coreclk_ratios[] __initconst = { 78 { .id = DOVE_CPU_TO_L2, .name = "l2clk", }, 79 { .id = DOVE_CPU_TO_DDR, .name = "ddrclk", } 80}; 81 82static const u32 dove_tclk_freqs[] __initconst = { 83 166666667, 84 125000000, 85 0, 0 86}; 87 88static u32 __init dove_get_tclk_freq(void __iomem *sar) 89{ 90 u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) & 91 SAR_DOVE_TCLK_FREQ_MASK; 92 return dove_tclk_freqs[opt]; 93} 94 95static const u32 dove_cpu_freqs[] __initconst = { 96 0, 0, 0, 0, 0, 97 1000000000, 98 933333333, 933333333, 99 800000000, 800000000, 800000000, 100 1066666667, 101 666666667, 102 533333333, 103 400000000, 104 333333333 105}; 106 107static u32 __init dove_get_cpu_freq(void __iomem *sar) 108{ 109 u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) & 110 SAR_DOVE_CPU_FREQ_MASK; 111 return dove_cpu_freqs[opt]; 112} 113 114static const int dove_cpu_l2_ratios[8][2] __initconst = { 115 { 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 }, 116 { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 } 117}; 118 119static const int dove_cpu_ddr_ratios[16][2] __initconst = { 120 { 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 }, 121 { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }, 122 { 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 }, 123 { 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 } 124}; 125 126static void __init dove_get_clk_ratio( 127 void __iomem *sar, int id, int *mult, int *div) 128{ 129 switch (id) { 130 case DOVE_CPU_TO_L2: 131 { 132 u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) & 133 SAR_DOVE_L2_RATIO_MASK; 134 *mult = dove_cpu_l2_ratios[opt][0]; 135 *div = dove_cpu_l2_ratios[opt][1]; 136 break; 137 } 138 case DOVE_CPU_TO_DDR: 139 { 140 u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) & 141 SAR_DOVE_DDR_RATIO_MASK; 142 *mult = dove_cpu_ddr_ratios[opt][0]; 143 *div = dove_cpu_ddr_ratios[opt][1]; 144 break; 145 } 146 } 147} 148 149static const struct coreclk_soc_desc dove_coreclks = { 150 .get_tclk_freq = dove_get_tclk_freq, 151 .get_cpu_freq = dove_get_cpu_freq, 152 .get_clk_ratio = dove_get_clk_ratio, 153 .ratios = dove_coreclk_ratios, 154 .num_ratios = ARRAY_SIZE(dove_coreclk_ratios), 155}; 156 157/* 158 * Clock Gating Control 159 */ 160 161static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = { 162 { "usb0", NULL, 0, 0 }, 163 { "usb1", NULL, 1, 0 }, 164 { "ge", "gephy", 2, 0 }, 165 { "sata", NULL, 3, 0 }, 166 { "pex0", NULL, 4, 0 }, 167 { "pex1", NULL, 5, 0 }, 168 { "sdio0", NULL, 8, 0 }, 169 { "sdio1", NULL, 9, 0 }, 170 { "nand", NULL, 10, 0 }, 171 { "camera", NULL, 11, 0 }, 172 { "i2s0", NULL, 12, 0 }, 173 { "i2s1", NULL, 13, 0 }, 174 { "crypto", NULL, 15, 0 }, 175 { "ac97", NULL, 21, 0 }, 176 { "pdma", NULL, 22, 0 }, 177 { "xor0", NULL, 23, 0 }, 178 { "xor1", NULL, 24, 0 }, 179 { "gephy", NULL, 30, 0 }, 180 { } 181}; 182 183static void __init dove_clk_init(struct device_node *np) 184{ 185 struct device_node *cgnp = 186 of_find_compatible_node(NULL, NULL, "marvell,dove-gating-clock"); 187 188 mvebu_coreclk_setup(np, &dove_coreclks); 189 190 if (cgnp) 191 mvebu_clk_gating_setup(cgnp, dove_gating_desc); 192} 193CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init); 194