diff options
| -rw-r--r-- | arch/arm/boot/dts/imx6q.dtsi | 20 | ||||
| -rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 65 |
2 files changed, 79 insertions, 6 deletions
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index ddc78de6a0be..ec092d294406 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi | |||
| @@ -38,12 +38,19 @@ | |||
| 38 | next-level-cache = <&L2>; | 38 | next-level-cache = <&L2>; |
| 39 | operating-points = < | 39 | operating-points = < |
| 40 | /* kHz uV */ | 40 | /* kHz uV */ |
| 41 | 792000 1100000 | 41 | 1200000 1275000 |
| 42 | 996000 1250000 | ||
| 43 | 792000 1150000 | ||
| 42 | 396000 950000 | 44 | 396000 950000 |
| 43 | 198000 850000 | ||
| 44 | >; | 45 | >; |
| 45 | clock-latency = <61036>; /* two CLK32 periods */ | 46 | clock-latency = <61036>; /* two CLK32 periods */ |
| 46 | cpu0-supply = <®_cpu>; | 47 | clocks = <&clks 104>, <&clks 6>, <&clks 16>, |
| 48 | <&clks 17>, <&clks 170>; | ||
| 49 | clock-names = "arm", "pll2_pfd2_396m", "step", | ||
| 50 | "pll1_sw", "pll1_sys"; | ||
| 51 | arm-supply = <®_arm>; | ||
| 52 | pu-supply = <®_pu>; | ||
| 53 | soc-supply = <®_soc>; | ||
| 47 | }; | 54 | }; |
| 48 | 55 | ||
| 49 | cpu@1 { | 56 | cpu@1 { |
| @@ -471,7 +478,7 @@ | |||
| 471 | anatop-max-voltage = <2750000>; | 478 | anatop-max-voltage = <2750000>; |
| 472 | }; | 479 | }; |
| 473 | 480 | ||
| 474 | reg_cpu: regulator-vddcore@140 { | 481 | reg_arm: regulator-vddcore@140 { |
| 475 | compatible = "fsl,anatop-regulator"; | 482 | compatible = "fsl,anatop-regulator"; |
| 476 | regulator-name = "cpu"; | 483 | regulator-name = "cpu"; |
| 477 | regulator-min-microvolt = <725000>; | 484 | regulator-min-microvolt = <725000>; |
| @@ -485,7 +492,7 @@ | |||
| 485 | anatop-max-voltage = <1450000>; | 492 | anatop-max-voltage = <1450000>; |
| 486 | }; | 493 | }; |
| 487 | 494 | ||
| 488 | regulator-vddpu@140 { | 495 | reg_pu: regulator-vddpu@140 { |
| 489 | compatible = "fsl,anatop-regulator"; | 496 | compatible = "fsl,anatop-regulator"; |
| 490 | regulator-name = "vddpu"; | 497 | regulator-name = "vddpu"; |
| 491 | regulator-min-microvolt = <725000>; | 498 | regulator-min-microvolt = <725000>; |
| @@ -499,7 +506,7 @@ | |||
| 499 | anatop-max-voltage = <1450000>; | 506 | anatop-max-voltage = <1450000>; |
| 500 | }; | 507 | }; |
| 501 | 508 | ||
| 502 | regulator-vddsoc@140 { | 509 | reg_soc: regulator-vddsoc@140 { |
| 503 | compatible = "fsl,anatop-regulator"; | 510 | compatible = "fsl,anatop-regulator"; |
| 504 | regulator-name = "vddsoc"; | 511 | regulator-name = "vddsoc"; |
| 505 | regulator-min-microvolt = <725000>; | 512 | regulator-min-microvolt = <725000>; |
| @@ -965,6 +972,7 @@ | |||
| 965 | }; | 972 | }; |
| 966 | 973 | ||
| 967 | ocotp@021bc000 { | 974 | ocotp@021bc000 { |
| 975 | compatible = "fsl,imx6q-ocotp"; | ||
| 968 | reg = <0x021bc000 0x4000>; | 976 | reg = <0x021bc000 0x4000>; |
| 969 | }; | 977 | }; |
| 970 | 978 | ||
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 4eb1b3ac794c..2f974f5096fd 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/cpuidle.h> | 16 | #include <linux/cpuidle.h> |
| 16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 17 | #include <linux/export.h> | 18 | #include <linux/export.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> |
| @@ -209,9 +211,72 @@ static struct cpuidle_driver imx6q_cpuidle_driver = { | |||
| 209 | .state_count = 1, | 211 | .state_count = 1, |
| 210 | }; | 212 | }; |
| 211 | 213 | ||
| 214 | #define OCOTP_CFG3 0x440 | ||
| 215 | #define OCOTP_CFG3_SPEED_SHIFT 16 | ||
| 216 | #define OCOTP_CFG3_SPEED_1P2GHZ 0x3 | ||
| 217 | |||
| 218 | static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev) | ||
| 219 | { | ||
| 220 | struct device_node *np; | ||
| 221 | void __iomem *base; | ||
| 222 | u32 val; | ||
| 223 | |||
| 224 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp"); | ||
| 225 | if (!np) { | ||
| 226 | pr_warn("failed to find ocotp node\n"); | ||
| 227 | return; | ||
| 228 | } | ||
| 229 | |||
| 230 | base = of_iomap(np, 0); | ||
| 231 | if (!base) { | ||
| 232 | pr_warn("failed to map ocotp\n"); | ||
| 233 | goto put_node; | ||
| 234 | } | ||
| 235 | |||
| 236 | val = readl_relaxed(base + OCOTP_CFG3); | ||
| 237 | val >>= OCOTP_CFG3_SPEED_SHIFT; | ||
| 238 | if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ) | ||
| 239 | if (opp_disable(cpu_dev, 1200000000)) | ||
| 240 | pr_warn("failed to disable 1.2 GHz OPP\n"); | ||
| 241 | |||
| 242 | put_node: | ||
| 243 | of_node_put(np); | ||
| 244 | } | ||
| 245 | |||
| 246 | static void __init imx6q_opp_init(struct device *cpu_dev) | ||
| 247 | { | ||
| 248 | struct device_node *np; | ||
| 249 | |||
| 250 | np = of_find_node_by_path("/cpus/cpu@0"); | ||
| 251 | if (!np) { | ||
| 252 | pr_warn("failed to find cpu0 node\n"); | ||
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | cpu_dev->of_node = np; | ||
| 257 | if (of_init_opp_table(cpu_dev)) { | ||
| 258 | pr_warn("failed to init OPP table\n"); | ||
| 259 | goto put_node; | ||
| 260 | } | ||
| 261 | |||
| 262 | imx6q_opp_check_1p2ghz(cpu_dev); | ||
| 263 | |||
| 264 | put_node: | ||
| 265 | of_node_put(np); | ||
| 266 | } | ||
| 267 | |||
| 268 | struct platform_device imx6q_cpufreq_pdev = { | ||
| 269 | .name = "imx6q-cpufreq", | ||
| 270 | }; | ||
| 271 | |||
| 212 | static void __init imx6q_init_late(void) | 272 | static void __init imx6q_init_late(void) |
| 213 | { | 273 | { |
| 214 | imx_cpuidle_init(&imx6q_cpuidle_driver); | 274 | imx_cpuidle_init(&imx6q_cpuidle_driver); |
| 275 | |||
| 276 | if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) { | ||
| 277 | imx6q_opp_init(&imx6q_cpufreq_pdev.dev); | ||
| 278 | platform_device_register(&imx6q_cpufreq_pdev); | ||
| 279 | } | ||
| 215 | } | 280 | } |
| 216 | 281 | ||
| 217 | static void __init imx6q_map_io(void) | 282 | static void __init imx6q_map_io(void) |
