Blame view

drivers/clk/mvebu/armada-370.c 4.7 KB
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  /*
   * Marvell Armada 370 SoC clocks
   *
   * Copyright (C) 2012 Marvell
   *
   * Gregory CLEMENT <gregory.clement@free-electrons.com>
   * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
   * Andrew Lunn <andrew@lunn.ch>
   *
   * This file is licensed under the terms of the GNU General Public
   * License version 2.  This program is licensed "as is" without any
   * warranty of any kind, whether express or implied.
   */
  
  #include <linux/kernel.h>
  #include <linux/clk-provider.h>
  #include <linux/io.h>
  #include <linux/of.h>
  #include "common.h"
  
  /*
   * Core Clocks
   */
  
  #define SARL				0	/* Low part [0:31] */
5e1a63f5f   Gregory CLEMENT   clk: mvebu: armad...
26
  #define	 SARL_A370_SSCG_ENABLE		BIT(10)
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
27
28
29
30
31
32
33
34
  #define	 SARL_A370_PCLK_FREQ_OPT	11
  #define	 SARL_A370_PCLK_FREQ_OPT_MASK	0xF
  #define	 SARL_A370_FAB_FREQ_OPT		15
  #define	 SARL_A370_FAB_FREQ_OPT_MASK	0x1F
  #define	 SARL_A370_TCLK_FREQ_OPT	20
  #define	 SARL_A370_TCLK_FREQ_OPT_MASK	0x1
  
  enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK };
682dfdc01   Sachin Kamat   clk: armada-370: ...
35
  static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
36
37
38
39
  	{ .id = A370_CPU_TO_NBCLK, .name = "nbclk" },
  	{ .id = A370_CPU_TO_HCLK, .name = "hclk" },
  	{ .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" },
  };
682dfdc01   Sachin Kamat   clk: armada-370: ...
40
  static const u32 a370_tclk_freqs[] __initconst = {
1022c75f5   Simon Guinot   clk: armada-370: ...
41
42
  	166000000,
  	200000000,
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
43
44
45
46
47
48
49
50
51
52
  };
  
  static u32 __init a370_get_tclk_freq(void __iomem *sar)
  {
  	u8 tclk_freq_select = 0;
  
  	tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
  			    SARL_A370_TCLK_FREQ_OPT_MASK);
  	return a370_tclk_freqs[tclk_freq_select];
  }
682dfdc01   Sachin Kamat   clk: armada-370: ...
53
  static const u32 a370_cpu_freqs[] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  	400000000,
  	533000000,
  	667000000,
  	800000000,
  	1000000000,
  	1067000000,
  	1200000000,
  };
  
  static u32 __init a370_get_cpu_freq(void __iomem *sar)
  {
  	u32 cpu_freq;
  	u8 cpu_freq_select = 0;
  
  	cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
  			   SARL_A370_PCLK_FREQ_OPT_MASK);
  	if (cpu_freq_select >= ARRAY_SIZE(a370_cpu_freqs)) {
  		pr_err("CPU freq select unsupported %d
  ", cpu_freq_select);
  		cpu_freq = 0;
  	} else
  		cpu_freq = a370_cpu_freqs[cpu_freq_select];
  
  	return cpu_freq;
  }
682dfdc01   Sachin Kamat   clk: armada-370: ...
79
  static const int a370_nbclk_ratios[32][2] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
80
81
82
83
84
85
86
87
88
  	{0, 1}, {1, 2}, {2, 2}, {2, 2},
  	{1, 2}, {1, 2}, {1, 1}, {2, 3},
  	{0, 1}, {1, 2}, {2, 4}, {0, 1},
  	{1, 2}, {0, 1}, {0, 1}, {2, 2},
  	{0, 1}, {0, 1}, {0, 1}, {1, 1},
  	{2, 3}, {0, 1}, {0, 1}, {0, 1},
  	{0, 1}, {0, 1}, {0, 1}, {1, 1},
  	{0, 1}, {0, 1}, {0, 1}, {0, 1},
  };
682dfdc01   Sachin Kamat   clk: armada-370: ...
89
  static const int a370_hclk_ratios[32][2] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
90
91
92
93
94
95
96
97
98
  	{0, 1}, {1, 2}, {2, 6}, {2, 3},
  	{1, 3}, {1, 4}, {1, 2}, {2, 6},
  	{0, 1}, {1, 6}, {2, 10}, {0, 1},
  	{1, 4}, {0, 1}, {0, 1}, {2, 5},
  	{0, 1}, {0, 1}, {0, 1}, {1, 2},
  	{2, 6}, {0, 1}, {0, 1}, {0, 1},
  	{0, 1}, {0, 1}, {0, 1}, {1, 1},
  	{0, 1}, {0, 1}, {0, 1}, {0, 1},
  };
682dfdc01   Sachin Kamat   clk: armada-370: ...
99
  static const int a370_dramclk_ratios[32][2] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  	{0, 1}, {1, 2}, {2, 3}, {2, 3},
  	{1, 3}, {1, 2}, {1, 2}, {2, 6},
  	{0, 1}, {1, 3}, {2, 5}, {0, 1},
  	{1, 4}, {0, 1}, {0, 1}, {2, 5},
  	{0, 1}, {0, 1}, {0, 1}, {1, 1},
  	{2, 3}, {0, 1}, {0, 1}, {0, 1},
  	{0, 1}, {0, 1}, {0, 1}, {1, 1},
  	{0, 1}, {0, 1}, {0, 1}, {0, 1},
  };
  
  static void __init a370_get_clk_ratio(
  	void __iomem *sar, int id, int *mult, int *div)
  {
  	u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
  		SARL_A370_FAB_FREQ_OPT_MASK);
  
  	switch (id) {
  	case A370_CPU_TO_NBCLK:
  		*mult = a370_nbclk_ratios[opt][0];
  		*div = a370_nbclk_ratios[opt][1];
  		break;
  	case A370_CPU_TO_HCLK:
  		*mult = a370_hclk_ratios[opt][0];
  		*div = a370_hclk_ratios[opt][1];
  		break;
  	case A370_CPU_TO_DRAMCLK:
  		*mult = a370_dramclk_ratios[opt][0];
  		*div = a370_dramclk_ratios[opt][1];
  		break;
  	}
  }
5e1a63f5f   Gregory CLEMENT   clk: mvebu: armad...
131
132
133
134
  static bool a370_is_sscg_enabled(void __iomem *sar)
  {
  	return !(readl(sar) & SARL_A370_SSCG_ENABLE);
  }
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
135
136
137
138
  static const struct coreclk_soc_desc a370_coreclks = {
  	.get_tclk_freq = a370_get_tclk_freq,
  	.get_cpu_freq = a370_get_cpu_freq,
  	.get_clk_ratio = a370_get_clk_ratio,
5e1a63f5f   Gregory CLEMENT   clk: mvebu: armad...
139
140
  	.is_sscg_enabled = a370_is_sscg_enabled,
  	.fix_sscg_deviation = kirkwood_fix_sscg_deviation,
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
141
142
143
  	.ratios = a370_coreclk_ratios,
  	.num_ratios = ARRAY_SIZE(a370_coreclk_ratios),
  };
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
144
145
146
  /*
   * Clock Gating Control
   */
682dfdc01   Sachin Kamat   clk: armada-370: ...
147
  static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
148
149
150
151
152
153
154
155
156
  	{ "audio", NULL, 0, 0 },
  	{ "pex0_en", NULL, 1, 0 },
  	{ "pex1_en", NULL,  2, 0 },
  	{ "ge1", NULL, 3, 0 },
  	{ "ge0", NULL, 4, 0 },
  	{ "pex0", "pex0_en", 5, 0 },
  	{ "pex1", "pex1_en", 9, 0 },
  	{ "sata0", NULL, 15, 0 },
  	{ "sdio", NULL, 17, 0 },
dc627eea9   Boris Brezillon   clk: mvebu: flag ...
157
  	{ "crypto", NULL, 23, CLK_IGNORE_UNUSED },
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
158
159
160
161
162
  	{ "tdm", NULL, 25, 0 },
  	{ "ddr", NULL, 28, CLK_IGNORE_UNUSED },
  	{ "sata1", NULL, 30, 0 },
  	{ }
  };
07ad6836f   Sebastian Hesselbarth   clk: mvebu: armad...
163
  static void __init a370_clk_init(struct device_node *np)
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
164
  {
07ad6836f   Sebastian Hesselbarth   clk: mvebu: armad...
165
166
167
168
169
170
171
  	struct device_node *cgnp =
  		of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock");
  
  	mvebu_coreclk_setup(np, &a370_coreclks);
  
  	if (cgnp)
  		mvebu_clk_gating_setup(cgnp, a370_gating_desc);
6b72333d5   Sebastian Hesselbarth   clk: mvebu: add A...
172
  }
07ad6836f   Sebastian Hesselbarth   clk: mvebu: armad...
173
  CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init);