diff options
Diffstat (limited to 'arch/arm/mach-imx/mach-imx6q.c')
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 1786b2d1257e..9ffd103b27e4 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
15 | #include <linux/cpu.h> | ||
15 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
16 | #include <linux/export.h> | 17 | #include <linux/export.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -22,6 +23,7 @@ | |||
22 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
23 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
24 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
26 | #include <linux/opp.h> | ||
25 | #include <linux/phy.h> | 27 | #include <linux/phy.h> |
26 | #include <linux/regmap.h> | 28 | #include <linux/regmap.h> |
27 | #include <linux/micrel_phy.h> | 29 | #include <linux/micrel_phy.h> |
@@ -200,6 +202,64 @@ static void __init imx6q_init_machine(void) | |||
200 | imx6q_1588_init(); | 202 | imx6q_1588_init(); |
201 | } | 203 | } |
202 | 204 | ||
205 | #define OCOTP_CFG3 0x440 | ||
206 | #define OCOTP_CFG3_SPEED_SHIFT 16 | ||
207 | #define OCOTP_CFG3_SPEED_1P2GHZ 0x3 | ||
208 | |||
209 | static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev) | ||
210 | { | ||
211 | struct device_node *np; | ||
212 | void __iomem *base; | ||
213 | u32 val; | ||
214 | |||
215 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp"); | ||
216 | if (!np) { | ||
217 | pr_warn("failed to find ocotp node\n"); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | base = of_iomap(np, 0); | ||
222 | if (!base) { | ||
223 | pr_warn("failed to map ocotp\n"); | ||
224 | goto put_node; | ||
225 | } | ||
226 | |||
227 | val = readl_relaxed(base + OCOTP_CFG3); | ||
228 | val >>= OCOTP_CFG3_SPEED_SHIFT; | ||
229 | if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) | ||
230 | if (opp_disable(cpu_dev, 1200000000)) | ||
231 | pr_warn("failed to disable 1.2 GHz OPP\n"); | ||
232 | |||
233 | put_node: | ||
234 | of_node_put(np); | ||
235 | } | ||
236 | |||
237 | static void __init imx6q_opp_init(struct device *cpu_dev) | ||
238 | { | ||
239 | struct device_node *np; | ||
240 | |||
241 | np = of_find_node_by_path("/cpus/cpu@0"); | ||
242 | if (!np) { | ||
243 | pr_warn("failed to find cpu0 node\n"); | ||
244 | return; | ||
245 | } | ||
246 | |||
247 | cpu_dev->of_node = np; | ||
248 | if (of_init_opp_table(cpu_dev)) { | ||
249 | pr_warn("failed to init OPP table\n"); | ||
250 | goto put_node; | ||
251 | } | ||
252 | |||
253 | imx6q_opp_check_1p2ghz(cpu_dev); | ||
254 | |||
255 | put_node: | ||
256 | of_node_put(np); | ||
257 | } | ||
258 | |||
259 | struct platform_device imx6q_cpufreq_pdev = { | ||
260 | .name = "imx6q-cpufreq", | ||
261 | }; | ||
262 | |||
203 | static void __init imx6q_init_late(void) | 263 | static void __init imx6q_init_late(void) |
204 | { | 264 | { |
205 | /* | 265 | /* |
@@ -208,6 +268,11 @@ static void __init imx6q_init_late(void) | |||
208 | */ | 268 | */ |
209 | if (imx6q_revision() > IMX_CHIP_REVISION_1_1) | 269 | if (imx6q_revision() > IMX_CHIP_REVISION_1_1) |
210 | imx6q_cpuidle_init(); | 270 | imx6q_cpuidle_init(); |
271 | |||
272 | if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { | ||
273 | imx6q_opp_init(&imx6q_cpufreq_pdev.dev); | ||
274 | platform_device_register(&imx6q_cpufreq_pdev); | ||
275 | } | ||
211 | } | 276 | } |
212 | 277 | ||
213 | static void __init imx6q_map_io(void) | 278 | static void __init imx6q_map_io(void) |