Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Marvell Dove SoC clocks
0004  *
0005  * Copyright (C) 2012 Marvell
0006  *
0007  * Gregory CLEMENT <gregory.clement@free-electrons.com>
0008  * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
0009  * Andrew Lunn <andrew@lunn.ch>
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 #include "dove-divider.h"
0019 
0020 /*
0021  * Core Clocks
0022  *
0023  * Dove PLL sample-at-reset configuration
0024  *
0025  * SAR0[8:5]   : CPU frequency
0026  *       5  = 1000 MHz
0027  *       6  =  933 MHz
0028  *       7  =  933 MHz
0029  *       8  =  800 MHz
0030  *       9  =  800 MHz
0031  *       10 =  800 MHz
0032  *       11 = 1067 MHz
0033  *       12 =  667 MHz
0034  *       13 =  533 MHz
0035  *       14 =  400 MHz
0036  *       15 =  333 MHz
0037  *       others reserved.
0038  *
0039  * SAR0[11:9]  : CPU to L2 Clock divider ratio
0040  *       0 = (1/1) * CPU
0041  *       2 = (1/2) * CPU
0042  *       4 = (1/3) * CPU
0043  *       6 = (1/4) * CPU
0044  *       others reserved.
0045  *
0046  * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio
0047  *       0  = (1/1) * CPU
0048  *       2  = (1/2) * CPU
0049  *       3  = (2/5) * CPU
0050  *       4  = (1/3) * CPU
0051  *       6  = (1/4) * CPU
0052  *       8  = (1/5) * CPU
0053  *       10 = (1/6) * CPU
0054  *       12 = (1/7) * CPU
0055  *       14 = (1/8) * CPU
0056  *       15 = (1/10) * CPU
0057  *       others reserved.
0058  *
0059  * SAR0[24:23] : TCLK frequency
0060  *       0 = 166 MHz
0061  *       1 = 125 MHz
0062  *       others reserved.
0063  */
0064 
0065 #define SAR_DOVE_CPU_FREQ       5
0066 #define SAR_DOVE_CPU_FREQ_MASK      0xf
0067 #define SAR_DOVE_L2_RATIO       9
0068 #define SAR_DOVE_L2_RATIO_MASK      0x7
0069 #define SAR_DOVE_DDR_RATIO      12
0070 #define SAR_DOVE_DDR_RATIO_MASK     0xf
0071 #define SAR_DOVE_TCLK_FREQ      23
0072 #define SAR_DOVE_TCLK_FREQ_MASK     0x3
0073 
0074 enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
0075 
0076 static const struct coreclk_ratio dove_coreclk_ratios[] __initconst = {
0077     { .id = DOVE_CPU_TO_L2, .name = "l2clk", },
0078     { .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
0079 };
0080 
0081 static const u32 dove_tclk_freqs[] __initconst = {
0082     166666667,
0083     125000000,
0084     0, 0
0085 };
0086 
0087 static u32 __init dove_get_tclk_freq(void __iomem *sar)
0088 {
0089     u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
0090         SAR_DOVE_TCLK_FREQ_MASK;
0091     return dove_tclk_freqs[opt];
0092 }
0093 
0094 static const u32 dove_cpu_freqs[] __initconst = {
0095     0, 0, 0, 0, 0,
0096     1000000000,
0097     933333333, 933333333,
0098     800000000, 800000000, 800000000,
0099     1066666667,
0100     666666667,
0101     533333333,
0102     400000000,
0103     333333333
0104 };
0105 
0106 static u32 __init dove_get_cpu_freq(void __iomem *sar)
0107 {
0108     u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
0109         SAR_DOVE_CPU_FREQ_MASK;
0110     return dove_cpu_freqs[opt];
0111 }
0112 
0113 static const int dove_cpu_l2_ratios[8][2] __initconst = {
0114     { 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
0115     { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
0116 };
0117 
0118 static const int dove_cpu_ddr_ratios[16][2] __initconst = {
0119     { 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
0120     { 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
0121     { 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
0122     { 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
0123 };
0124 
0125 static void __init dove_get_clk_ratio(
0126     void __iomem *sar, int id, int *mult, int *div)
0127 {
0128     switch (id) {
0129     case DOVE_CPU_TO_L2:
0130     {
0131         u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
0132             SAR_DOVE_L2_RATIO_MASK;
0133         *mult = dove_cpu_l2_ratios[opt][0];
0134         *div = dove_cpu_l2_ratios[opt][1];
0135         break;
0136     }
0137     case DOVE_CPU_TO_DDR:
0138     {
0139         u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
0140             SAR_DOVE_DDR_RATIO_MASK;
0141         *mult = dove_cpu_ddr_ratios[opt][0];
0142         *div = dove_cpu_ddr_ratios[opt][1];
0143         break;
0144     }
0145     }
0146 }
0147 
0148 static const struct coreclk_soc_desc dove_coreclks = {
0149     .get_tclk_freq = dove_get_tclk_freq,
0150     .get_cpu_freq = dove_get_cpu_freq,
0151     .get_clk_ratio = dove_get_clk_ratio,
0152     .ratios = dove_coreclk_ratios,
0153     .num_ratios = ARRAY_SIZE(dove_coreclk_ratios),
0154 };
0155 
0156 /*
0157  * Clock Gating Control
0158  */
0159 
0160 static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = {
0161     { "usb0", NULL, 0, 0 },
0162     { "usb1", NULL, 1, 0 },
0163     { "ge", "gephy", 2, 0 },
0164     { "sata", NULL, 3, 0 },
0165     { "pex0", NULL, 4, 0 },
0166     { "pex1", NULL, 5, 0 },
0167     { "sdio0", NULL, 8, 0 },
0168     { "sdio1", NULL, 9, 0 },
0169     { "nand", NULL, 10, 0 },
0170     { "camera", NULL, 11, 0 },
0171     { "i2s0", NULL, 12, 0 },
0172     { "i2s1", NULL, 13, 0 },
0173     { "crypto", NULL, 15, 0 },
0174     { "ac97", NULL, 21, 0 },
0175     { "pdma", NULL, 22, 0 },
0176     { "xor0", NULL, 23, 0 },
0177     { "xor1", NULL, 24, 0 },
0178     { "gephy", NULL, 30, 0 },
0179     { }
0180 };
0181 
0182 static void __init dove_clk_init(struct device_node *np)
0183 {
0184     struct device_node *cgnp =
0185         of_find_compatible_node(NULL, NULL, "marvell,dove-gating-clock");
0186     struct device_node *ddnp =
0187         of_find_compatible_node(NULL, NULL, "marvell,dove-divider-clock");
0188 
0189     mvebu_coreclk_setup(np, &dove_coreclks);
0190 
0191     if (ddnp) {
0192         dove_divider_clk_init(ddnp);
0193         of_node_put(ddnp);
0194     }
0195 
0196     if (cgnp) {
0197         mvebu_clk_gating_setup(cgnp, dove_gating_desc);
0198         of_node_put(cgnp);
0199     }
0200 }
0201 CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init);