0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kernel.h>
0014 #include <linux/clk-provider.h>
0015 #include <linux/io.h>
0016 #include <linux/of.h>
0017 #include "common.h"
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #define SAR1_A375_TCLK_FREQ_OPT 22
0041 #define SAR1_A375_TCLK_FREQ_OPT_MASK 0x1
0042 #define SAR1_A375_CPU_DDR_L2_FREQ_OPT 17
0043 #define SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK 0x1F
0044
0045 static const u32 armada_375_tclk_frequencies[] __initconst = {
0046 166000000,
0047 200000000,
0048 };
0049
0050 static u32 __init armada_375_get_tclk_freq(void __iomem *sar)
0051 {
0052 u8 tclk_freq_select;
0053
0054 tclk_freq_select = ((readl(sar) >> SAR1_A375_TCLK_FREQ_OPT) &
0055 SAR1_A375_TCLK_FREQ_OPT_MASK);
0056 return armada_375_tclk_frequencies[tclk_freq_select];
0057 }
0058
0059
0060 static const u32 armada_375_cpu_frequencies[] __initconst = {
0061 0, 0, 0, 0, 0, 0,
0062 400000000,
0063 0, 0, 0, 0, 0, 0, 0, 0,
0064 600000000,
0065 0, 0, 0, 0, 0,
0066 800000000,
0067 0, 0, 0,
0068 1000000000,
0069 };
0070
0071 static u32 __init armada_375_get_cpu_freq(void __iomem *sar)
0072 {
0073 u8 cpu_freq_select;
0074
0075 cpu_freq_select = ((readl(sar) >> SAR1_A375_CPU_DDR_L2_FREQ_OPT) &
0076 SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK);
0077 if (cpu_freq_select >= ARRAY_SIZE(armada_375_cpu_frequencies)) {
0078 pr_err("Selected CPU frequency (%d) unsupported\n",
0079 cpu_freq_select);
0080 return 0;
0081 } else
0082 return armada_375_cpu_frequencies[cpu_freq_select];
0083 }
0084
0085 enum { A375_CPU_TO_DDR, A375_CPU_TO_L2 };
0086
0087 static const struct coreclk_ratio armada_375_coreclk_ratios[] __initconst = {
0088 { .id = A375_CPU_TO_L2, .name = "l2clk" },
0089 { .id = A375_CPU_TO_DDR, .name = "ddrclk" },
0090 };
0091
0092 static const int armada_375_cpu_l2_ratios[32][2] __initconst = {
0093 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0094 {0, 1}, {0, 1}, {1, 2}, {0, 1},
0095 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0096 {0, 1}, {0, 1}, {0, 1}, {1, 2},
0097 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0098 {0, 1}, {1, 2}, {0, 1}, {0, 1},
0099 {0, 1}, {1, 2}, {0, 1}, {0, 1},
0100 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0101 };
0102
0103 static const int armada_375_cpu_ddr_ratios[32][2] __initconst = {
0104 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0105 {0, 1}, {0, 1}, {1, 1}, {0, 1},
0106 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0107 {0, 1}, {0, 1}, {0, 1}, {2, 3},
0108 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0109 {0, 1}, {2, 3}, {0, 1}, {0, 1},
0110 {0, 1}, {1, 2}, {0, 1}, {0, 1},
0111 {0, 1}, {0, 1}, {0, 1}, {0, 1},
0112 };
0113
0114 static void __init armada_375_get_clk_ratio(
0115 void __iomem *sar, int id, int *mult, int *div)
0116 {
0117 u32 opt = ((readl(sar) >> SAR1_A375_CPU_DDR_L2_FREQ_OPT) &
0118 SAR1_A375_CPU_DDR_L2_FREQ_OPT_MASK);
0119
0120 switch (id) {
0121 case A375_CPU_TO_L2:
0122 *mult = armada_375_cpu_l2_ratios[opt][0];
0123 *div = armada_375_cpu_l2_ratios[opt][1];
0124 break;
0125 case A375_CPU_TO_DDR:
0126 *mult = armada_375_cpu_ddr_ratios[opt][0];
0127 *div = armada_375_cpu_ddr_ratios[opt][1];
0128 break;
0129 }
0130 }
0131
0132 static const struct coreclk_soc_desc armada_375_coreclks = {
0133 .get_tclk_freq = armada_375_get_tclk_freq,
0134 .get_cpu_freq = armada_375_get_cpu_freq,
0135 .get_clk_ratio = armada_375_get_clk_ratio,
0136 .ratios = armada_375_coreclk_ratios,
0137 .num_ratios = ARRAY_SIZE(armada_375_coreclk_ratios),
0138 };
0139
0140 static void __init armada_375_coreclk_init(struct device_node *np)
0141 {
0142 mvebu_coreclk_setup(np, &armada_375_coreclks);
0143 }
0144 CLK_OF_DECLARE(armada_375_core_clk, "marvell,armada-375-core-clock",
0145 armada_375_coreclk_init);
0146
0147
0148
0149
0150 static const struct clk_gating_soc_desc armada_375_gating_desc[] __initconst = {
0151 { "mu", NULL, 2 },
0152 { "pp", NULL, 3 },
0153 { "ptp", NULL, 4 },
0154 { "pex0", NULL, 5 },
0155 { "pex1", NULL, 6 },
0156 { "audio", NULL, 8 },
0157 { "nd_clk", "nand", 11 },
0158 { "sata0_link", "sata0_core", 14 },
0159 { "sata0_core", NULL, 15 },
0160 { "usb3", NULL, 16 },
0161 { "sdio", NULL, 17 },
0162 { "usb", NULL, 18 },
0163 { "gop", NULL, 19 },
0164 { "sata1_link", "sata1_core", 20 },
0165 { "sata1_core", NULL, 21 },
0166 { "xor0", NULL, 22 },
0167 { "xor1", NULL, 23 },
0168 { "copro", NULL, 24 },
0169 { "tdm", NULL, 25 },
0170 { "crypto0_enc", NULL, 28 },
0171 { "crypto0_core", NULL, 29 },
0172 { "crypto1_enc", NULL, 30 },
0173 { "crypto1_core", NULL, 31 },
0174 { }
0175 };
0176
0177 static void __init armada_375_clk_gating_init(struct device_node *np)
0178 {
0179 mvebu_clk_gating_setup(np, armada_375_gating_desc);
0180 }
0181 CLK_OF_DECLARE(armada_375_clk_gating, "marvell,armada-375-gating-clock",
0182 armada_375_clk_gating_init);