mirror of https://gitee.com/openkylin/linux.git
ARM: SoC: late fixes and dependencies
This is a collection of a few late fixes and other misc. stuff that had dependencies on things being merged from other trees. The bulk of the changes are for samsung/exynos SoCs for some changes that needed a few minor reworks so ended up a bit late. The others are mainly for qcom SoCs: a couple fixes and some DTS updates. There's one conflict with drivers/cpufreq/exynos-cpufreq.c because it's now been completely removed, but there were some fixes that hit mainline in the meantime. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIbBAABAgAGBQJV8fkAAAoJEFk3GJrT+8Zllf8P9jj3+TnvbJS/8bWoQoB7BRUZ LZPgi2+sBXylrBV60uQdyodiTHQUMZhbL7GvgEVG0z6yyin7nyijqNkulTbQbWmg WhumLNCNcs8vlZegA/corbwgcVC7FkjOP97HveTe2mgwZ+GaXj9qMRQzBsMqSXEo 4890ZeP1nWBTP42oXOQHkNyKWFBjuERK0dTw2MXj7WE0/Ag8i7ERp76uJQdQ7V5O BpNRwxp3vSCky8rxbpD/avWdlspv1yZGBQyLeIreVq2YQFojvT36K8wHcf6iWBT/ pzGGV/uZM7MnrGZdqSfVEMDHl7Z2s7Ls+sv5F6Md7ErnVDerHGRjw/6lJDjbeH7u trucpsuhz5yhTjpZssGHH2NT8pWxxh8M+AaNOiiH8PuYESAbPAmWLpWkn+648bIn P++Z90DIyfNEqnNSMHkcQYpVt8zc4g75gZfTIIsXLB+DLgzgSK8ergrfyRN/O0zj oFY35g3wHdgisnGve+BAW30zTZtP19TMT36OltWjIkjuRZC29PS2vkH8eTETdVXx 01f/qcpbB1L1rXfIBjNkjx81j89XPd68JIBfctTF5QBOAGm/Dix6tj2mU/N7TNu5 TrBmD3CXdOQbCPaoK/qWX7/b11IN/XOlGL06hhYwbSdvCVy7rNccApXvfnrDWziK Ly923FP1OB7h0Kk1cmo= =85Ck -----END PGP SIGNATURE----- Merge tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull late ARM SoC updates from Kevin Hilman: "This is a collection of a few late fixes and other misc stuff that had dependencies on things being merged from other trees. The bulk of the changes are for samsung/exynos SoCs for some changes that needed a few minor reworks so ended up a bit late. The others are mainly for qcom SoCs: a couple fixes and some DTS updates" * tag 'armsoc-late' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (37 commits) ARM: multi_v7_defconfig: Enable PBIAS regulator soc: qcom: smd: Correct fBLOCKREADINTR handling soc: qcom: smd: Use correct remote processor ID soc: qcom: smem: Fix errant private access ARM: dts: qcom: msm8974-sony-xperia-honami: Use stdout-path ARM: dts: qcom: msm8960-cdp: Use stdout-path ARM: dts: qcom: msm8660-surf: Use stdout-path ARM: dts: qcom: ipq8064-ap148: Use stdout-path ARM: dts: qcom: apq8084-mtp: Use stdout-path ARM: dts: qcom: apq8084-ifc6540: Use stdout-path ARM: dts: qcom: apq8074-dragonboard: Use stdout-path ARM: dts: qcom: apq8064-ifc6410: Use stdout-path ARM: dts: qcom: apq8064-cm-qs600: Use stdout-path ARM: dts: qcom: Label serial nodes for aliasing and stdout-path reset: ath79: Fix missing spin_lock_init reset: Add (devm_)reset_control_get stub functions ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12 cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o ARM: dts: add iommu property to JPEG device for exynos4 ARM: dts: enable SPI1 for exynos4412-odroidu3 ...
This commit is contained in:
commit
d71fc239b6
|
@ -37,6 +37,12 @@ The edge is described by the following properties:
|
|||
Definition: the identifier of the remote processor in the smd channel
|
||||
allocation table
|
||||
|
||||
- qcom,remote-pid:
|
||||
Usage: optional
|
||||
Value type: <u32>
|
||||
Definition: the identifier for the remote processor as known by the rest
|
||||
of the system.
|
||||
|
||||
= SMD DEVICES
|
||||
|
||||
In turn, subnodes of the "edges" represent devices tied to SMD channels on that
|
||||
|
|
|
@ -116,6 +116,21 @@ haptics {
|
|||
min-microvolt = <1100000>;
|
||||
max-microvolt = <2700000>;
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu_thermal: cpu-thermal {
|
||||
cooling-maps {
|
||||
map0 {
|
||||
/* Correspond to 500MHz at freq_table */
|
||||
cooling-device = <&cpu0 5 5>;
|
||||
};
|
||||
map1 {
|
||||
/* Correspond to 200MHz at freq_table */
|
||||
cooling-device = <&cpu0 8 8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
|
@ -141,6 +156,10 @@ thermistor-battery {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&exynos_usbphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -107,6 +107,21 @@ haptics {
|
|||
min-microvolt = <1100000>;
|
||||
max-microvolt = <2700000>;
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu_thermal: cpu-thermal {
|
||||
cooling-maps {
|
||||
map0 {
|
||||
/* Corresponds to 500MHz */
|
||||
cooling-device = <&cpu0 5 5>;
|
||||
};
|
||||
map1 {
|
||||
/* Corresponds to 200MHz */
|
||||
cooling-device = <&cpu0 8 8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
|
@ -132,6 +147,10 @@ thermistor-battery {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&exynos_usbphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -53,6 +53,22 @@ cpu0: cpu@0 {
|
|||
compatible = "arm,cortex-a7";
|
||||
reg = <0>;
|
||||
clock-frequency = <1000000000>;
|
||||
clocks = <&cmu CLK_ARM_CLK>;
|
||||
clock-names = "cpu";
|
||||
#cooling-cells = <2>;
|
||||
|
||||
operating-points = <
|
||||
1000000 1150000
|
||||
900000 1112500
|
||||
800000 1075000
|
||||
700000 1037500
|
||||
600000 1000000
|
||||
500000 962500
|
||||
400000 925000
|
||||
300000 887500
|
||||
200000 850000
|
||||
100000 850000
|
||||
>;
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
|
|
|
@ -702,6 +702,7 @@ jpeg_codec: jpeg-codec@11840000 {
|
|||
clocks = <&clock CLK_JPEG>;
|
||||
clock-names = "jpeg";
|
||||
power-domains = <&pd_cam>;
|
||||
iommus = <&sysmmu_jpeg>;
|
||||
};
|
||||
|
||||
hdmi: hdmi@12D00000 {
|
||||
|
|
|
@ -30,6 +30,9 @@ cpu0: cpu@A00 {
|
|||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA00>;
|
||||
clocks = <&clock CLK_ARM_CLK>;
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
cooling-min-level = <13>;
|
||||
cooling-max-level = <7>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
|
@ -39,6 +42,84 @@ cpu@A01 {
|
|||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA01>;
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu0_opp_table: opp_table0 {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp00 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
opp-microvolt = <900000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp01 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-microvolt = <900000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp02 {
|
||||
opp-hz = /bits/ 64 <400000000>;
|
||||
opp-microvolt = <925000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp03 {
|
||||
opp-hz = /bits/ 64 <500000000>;
|
||||
opp-microvolt = <950000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp04 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <975000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp05 {
|
||||
opp-hz = /bits/ 64 <700000000>;
|
||||
opp-microvolt = <987500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp06 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-microvolt = <1000000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp07 {
|
||||
opp-hz = /bits/ 64 <900000000>;
|
||||
opp-microvolt = <1037500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp08 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-microvolt = <1087500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp09 {
|
||||
opp-hz = /bits/ 64 <1100000000>;
|
||||
opp-microvolt = <1137500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp10 {
|
||||
opp-hz = /bits/ 64 <1200000000>;
|
||||
opp-microvolt = <1187500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp11 {
|
||||
opp-hz = /bits/ 64 <1300000000>;
|
||||
opp-microvolt = <1250000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp12 {
|
||||
opp-hz = /bits/ 64 <1400000000>;
|
||||
opp-microvolt = <1287500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp13 {
|
||||
opp-hz = /bits/ 64 <1500000000>;
|
||||
opp-microvolt = <1350000>;
|
||||
clock-latency-ns = <200000>;
|
||||
turbo-mode;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -107,6 +107,10 @@ map1 {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
/* RSTN signal for eMMC */
|
||||
&sd1_cd {
|
||||
samsung,pin-pud = <0>;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
/dts-v1/;
|
||||
#include "exynos4412-odroid-common.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
model = "Hardkernel ODROID-U3 board based on Exynos4412";
|
||||
|
@ -61,3 +62,10 @@ &sound {
|
|||
"Speakers", "SPKL",
|
||||
"Speakers", "SPKR";
|
||||
};
|
||||
|
||||
&spi_1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi1_bus>;
|
||||
cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -78,6 +78,10 @@ xusbxti {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&fimd {
|
||||
pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
@ -288,6 +288,10 @@ &adc {
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&csis_0 {
|
||||
status = "okay";
|
||||
vddcore-supply = <&ldo8_reg>;
|
||||
|
|
|
@ -30,6 +30,9 @@ cpu0: cpu@A00 {
|
|||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA00>;
|
||||
clocks = <&clock CLK_ARM_CLK>;
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
cooling-min-level = <13>;
|
||||
cooling-max-level = <7>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
|
@ -39,18 +42,98 @@ cpu@A01 {
|
|||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA01>;
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
};
|
||||
|
||||
cpu@A02 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA02>;
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
};
|
||||
|
||||
cpu@A03 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0xA03>;
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
};
|
||||
};
|
||||
|
||||
cpu0_opp_table: opp_table0 {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
opp00 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
opp-microvolt = <900000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp01 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-microvolt = <900000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp02 {
|
||||
opp-hz = /bits/ 64 <400000000>;
|
||||
opp-microvolt = <925000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp03 {
|
||||
opp-hz = /bits/ 64 <500000000>;
|
||||
opp-microvolt = <950000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp04 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <975000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp05 {
|
||||
opp-hz = /bits/ 64 <700000000>;
|
||||
opp-microvolt = <987500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp06 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-microvolt = <1000000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp07 {
|
||||
opp-hz = /bits/ 64 <900000000>;
|
||||
opp-microvolt = <1037500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp08 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-microvolt = <1087500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp09 {
|
||||
opp-hz = /bits/ 64 <1100000000>;
|
||||
opp-microvolt = <1137500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp10 {
|
||||
opp-hz = /bits/ 64 <1200000000>;
|
||||
opp-microvolt = <1187500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp11 {
|
||||
opp-hz = /bits/ 64 <1300000000>;
|
||||
opp-microvolt = <1250000>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp12 {
|
||||
opp-hz = /bits/ 64 <1400000000>;
|
||||
opp-microvolt = <1287500>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
opp13 {
|
||||
opp-hz = /bits/ 64 <1500000000>;
|
||||
opp-microvolt = <1350000>;
|
||||
clock-latency-ns = <200000>;
|
||||
turbo-mode;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -117,6 +117,10 @@ usb_hub: usb-hub {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&dp {
|
||||
status = "okay";
|
||||
samsung,color-space = <0>;
|
||||
|
|
|
@ -74,6 +74,10 @@ codec_mclk: codec-mclk {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&dp {
|
||||
samsung,color-space = <0>;
|
||||
samsung,dynamic-range = <0>;
|
||||
|
|
|
@ -235,6 +235,10 @@ mmc3_pwrseq: mmc3_pwrseq {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&dp {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
|
@ -688,6 +692,7 @@ &spi_1 {
|
|||
status = "okay";
|
||||
samsung,spi-src-clk = <0>;
|
||||
num-cs = <1>;
|
||||
cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&usbdrd_dwc3 {
|
||||
|
|
|
@ -65,6 +65,10 @@ xxti {
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&dp {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
|
|
|
@ -62,6 +62,28 @@ cpu0: cpu@0 {
|
|||
compatible = "arm,cortex-a15";
|
||||
reg = <0>;
|
||||
clock-frequency = <1700000000>;
|
||||
clocks = <&clock CLK_ARM_CLK>;
|
||||
clock-names = "cpu";
|
||||
clock-latency = <140000>;
|
||||
|
||||
operating-points = <
|
||||
1700000 1300000
|
||||
1600000 1250000
|
||||
1500000 1225000
|
||||
1400000 1200000
|
||||
1300000 1150000
|
||||
1200000 1125000
|
||||
1100000 1100000
|
||||
1000000 1075000
|
||||
900000 1050000
|
||||
800000 1025000
|
||||
700000 1012500
|
||||
600000 1000000
|
||||
500000 975000
|
||||
400000 950000
|
||||
300000 937500
|
||||
200000 925000
|
||||
>;
|
||||
cooling-min-level = <15>;
|
||||
cooling-max-level = <9>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* SAMSUNG EXYNOS5422 SoC cpu device tree source
|
||||
*
|
||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* The only difference between EXYNOS5422 and EXYNOS5800 is cpu ordering. The
|
||||
* EXYNOS5422 is booting from Cortex-A7 core while the EXYNOS5800 is booting
|
||||
* from Cortex-A15 core.
|
||||
*
|
||||
* EXYNOS5422 based board files can include this file to provide cpu ordering
|
||||
* which could boot a cortex-a7 from cpu0.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
&cpu0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x100>;
|
||||
clock-frequency = <1000000000>;
|
||||
cci-control-port = <&cci_control0>;
|
||||
};
|
||||
|
||||
&cpu1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x101>;
|
||||
clock-frequency = <1000000000>;
|
||||
cci-control-port = <&cci_control0>;
|
||||
};
|
||||
|
||||
&cpu2 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x102>;
|
||||
clock-frequency = <1000000000>;
|
||||
cci-control-port = <&cci_control0>;
|
||||
};
|
||||
|
||||
&cpu3 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a7";
|
||||
reg = <0x103>;
|
||||
clock-frequency = <1000000000>;
|
||||
cci-control-port = <&cci_control0>;
|
||||
};
|
||||
|
||||
&cpu4 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0x0>;
|
||||
clock-frequency = <1800000000>;
|
||||
cci-control-port = <&cci_control1>;
|
||||
};
|
||||
|
||||
&cpu5 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0x1>;
|
||||
clock-frequency = <1800000000>;
|
||||
cci-control-port = <&cci_control1>;
|
||||
};
|
||||
|
||||
&cpu6 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0x2>;
|
||||
clock-frequency = <1800000000>;
|
||||
cci-control-port = <&cci_control1>;
|
||||
};
|
||||
|
||||
&cpu7 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0x3>;
|
||||
clock-frequency = <1800000000>;
|
||||
cci-control-port = <&cci_control1>;
|
||||
};
|
|
@ -15,6 +15,7 @@
|
|||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/sound/samsung-i2s.h>
|
||||
#include "exynos5800.dtsi"
|
||||
#include "exynos5422-cpus.dtsi"
|
||||
#include "exynos5422-cpu-thermal.dtsi"
|
||||
|
||||
/ {
|
||||
|
|
|
@ -4,6 +4,14 @@ / {
|
|||
model = "CompuLab CM-QS600";
|
||||
compatible = "qcom,apq8064-cm-qs600", "qcom,apq8064";
|
||||
|
||||
aliases {
|
||||
serial0 = &gsbi7_serial;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
pinctrl@800000 {
|
||||
i2c1_pins: i2c1 {
|
||||
|
|
|
@ -10,6 +10,10 @@ aliases {
|
|||
serial1 = &gsbi6_serial;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
pinctrl@800000 {
|
||||
card_detect: card_detect {
|
||||
|
|
|
@ -6,6 +6,14 @@ / {
|
|||
model = "Qualcomm APQ8074 Dragonboard";
|
||||
compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
serial@f991e000 {
|
||||
status = "ok";
|
||||
|
|
|
@ -5,6 +5,14 @@ / {
|
|||
model = "Qualcomm APQ8084/IFC6540";
|
||||
compatible = "qcom,apq8084-ifc6540", "qcom,apq8084";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp2_uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
serial@f995e000 {
|
||||
status = "okay";
|
||||
|
|
|
@ -5,6 +5,14 @@ / {
|
|||
model = "Qualcomm APQ 8084-MTP";
|
||||
compatible = "qcom,apq8084-mtp", "qcom,apq8084";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp2_uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
serial@f995e000 {
|
||||
status = "okay";
|
||||
|
|
|
@ -234,7 +234,7 @@ tlmm: pinctrl@fd510000 {
|
|||
interrupts = <0 208 0>;
|
||||
};
|
||||
|
||||
serial@f995e000 {
|
||||
blsp2_uart2: serial@f995e000 {
|
||||
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
|
||||
reg = <0xf995e000 0x1000>;
|
||||
interrupts = <0 114 0x0>;
|
||||
|
|
|
@ -4,6 +4,14 @@ / {
|
|||
model = "Qualcomm IPQ8064/AP148";
|
||||
compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
|
||||
|
||||
aliases {
|
||||
serial0 = &gsbi4_serial;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -197,7 +197,7 @@ gsbi4: gsbi@16300000 {
|
|||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
serial@16340000 {
|
||||
gsbi4_serial: serial@16340000 {
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x16340000 0x1000>,
|
||||
<0x16300000 0x1000>;
|
||||
|
|
|
@ -6,6 +6,14 @@ / {
|
|||
model = "Qualcomm MSM8660 SURF";
|
||||
compatible = "qcom,msm8660-surf", "qcom,msm8660";
|
||||
|
||||
aliases {
|
||||
serial0 = &gsbi12_serial;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
gsbi@19c00000 {
|
||||
status = "ok";
|
||||
|
|
|
@ -98,7 +98,7 @@ gsbi12: gsbi@19c00000 {
|
|||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
serial@19c40000 {
|
||||
gsbi12_serial: serial@19c40000 {
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x19c40000 0x1000>,
|
||||
<0x19c00000 0x1000>;
|
||||
|
|
|
@ -6,6 +6,14 @@ / {
|
|||
model = "Qualcomm MSM8960 CDP";
|
||||
compatible = "qcom,msm8960-cdp", "qcom,msm8960";
|
||||
|
||||
aliases {
|
||||
serial0 = &gsbi5_serial;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
soc {
|
||||
gsbi@16400000 {
|
||||
status = "ok";
|
||||
|
|
|
@ -157,7 +157,7 @@ gsbi5: gsbi@16400000 {
|
|||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
serial@16440000 {
|
||||
gsbi5_serial: serial@16440000 {
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x16440000 0x1000>,
|
||||
<0x16400000 0x1000>;
|
||||
|
|
|
@ -6,6 +6,14 @@ / {
|
|||
model = "Sony Xperia Z1";
|
||||
compatible = "sony,xperia-honami", "qcom,msm8974";
|
||||
|
||||
aliases {
|
||||
serial0 = &blsp1_uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
reg = <0 0x40000000>, <0x40000000 0x40000000>;
|
||||
device_type = "memory";
|
||||
|
|
|
@ -259,7 +259,7 @@ smem@fa00000 {
|
|||
hwlocks = <&tcsr_mutex 3>;
|
||||
};
|
||||
|
||||
serial@f991e000 {
|
||||
blsp1_uart2: serial@f991e000 {
|
||||
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
|
||||
reg = <0xf991e000 0x1000>;
|
||||
interrupts = <0 108 0x0>;
|
||||
|
|
|
@ -27,6 +27,8 @@ CONFIG_ARM_APPENDED_DTB=y
|
|||
CONFIG_ARM_ATAG_DTB_COMPAT=y
|
||||
CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_ARM_EXYNOS_CPUIDLE=y
|
||||
CONFIG_VFP=y
|
||||
|
@ -94,6 +96,7 @@ CONFIG_CHARGER_MAX14577=y
|
|||
CONFIG_CHARGER_MAX77693=y
|
||||
CONFIG_CHARGER_TPS65090=y
|
||||
CONFIG_SENSORS_LM90=y
|
||||
CONFIG_SENSORS_NTC_THERMISTOR=y
|
||||
CONFIG_SENSORS_PWM_FAN=y
|
||||
CONFIG_SENSORS_INA2XX=y
|
||||
CONFIG_THERMAL=y
|
||||
|
@ -144,6 +147,8 @@ CONFIG_SND=y
|
|||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_SAMSUNG=y
|
||||
CONFIG_SND_SOC_SNOW=y
|
||||
CONFIG_SND_SOC_ODROIDX2=y
|
||||
CONFIG_SND_SIMPLE_CARD=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
|
|
|
@ -362,6 +362,7 @@ CONFIG_POWER_RESET_KEYSTONE=y
|
|||
CONFIG_POWER_RESET_RMOBILE=y
|
||||
CONFIG_SENSORS_LM90=y
|
||||
CONFIG_SENSORS_LM95245=y
|
||||
CONFIG_SENSORS_NTC_THERMISTOR=m
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_RCAR_THERMAL=y
|
||||
|
@ -410,7 +411,9 @@ CONFIG_REGULATOR_MAX8907=y
|
|||
CONFIG_REGULATOR_MAX8973=y
|
||||
CONFIG_REGULATOR_MAX77686=y
|
||||
CONFIG_REGULATOR_MAX77693=m
|
||||
CONFIG_REGULATOR_MAX77802=m
|
||||
CONFIG_REGULATOR_PALMAS=y
|
||||
CONFIG_REGULATOR_PBIAS=y
|
||||
CONFIG_REGULATOR_PWM=m
|
||||
CONFIG_REGULATOR_S2MPS11=y
|
||||
CONFIG_REGULATOR_S5M8767=y
|
||||
|
@ -509,8 +512,6 @@ CONFIG_USB_CHIPIDEA_HOST=y
|
|||
CONFIG_AB8500_USB=y
|
||||
CONFIG_KEYSTONE_USB_PHY=y
|
||||
CONFIG_OMAP_USB3=y
|
||||
CONFIG_SAMSUNG_USB2PHY=y
|
||||
CONFIG_SAMSUNG_USB3PHY=y
|
||||
CONFIG_USB_GPIO_VBUS=y
|
||||
CONFIG_USB_ISP1301=y
|
||||
CONFIG_USB_MXS_PHY=y
|
||||
|
@ -635,6 +636,7 @@ CONFIG_EXTCON=y
|
|||
CONFIG_TI_AEMIF=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_AT91_ADC=m
|
||||
CONFIG_EXYNOS_ADC=m
|
||||
CONFIG_XILINX_XADC=y
|
||||
CONFIG_AK8975=y
|
||||
CONFIG_PWM=y
|
||||
|
|
|
@ -15,6 +15,7 @@ menuconfig ARCH_EXYNOS
|
|||
select ARM_AMBA
|
||||
select ARM_GIC
|
||||
select COMMON_CLK_SAMSUNG
|
||||
select EXYNOS_THERMAL
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_S3C2410_I2C if I2C
|
||||
select HAVE_S3C2410_WATCHDOG if WATCHDOG
|
||||
|
@ -24,6 +25,7 @@ menuconfig ARCH_EXYNOS
|
|||
select PM_GENERIC_DOMAINS if PM
|
||||
select S5P_DEV_MFC
|
||||
select SRAM
|
||||
select THERMAL
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
|
||||
|
|
|
@ -225,7 +225,11 @@ static void __init exynos_init_irq(void)
|
|||
}
|
||||
|
||||
static const struct of_device_id exynos_cpufreq_matches[] = {
|
||||
{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
|
||||
{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
|
||||
{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
|
||||
{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
|
||||
{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
|
|
@ -1398,6 +1398,45 @@ static const struct exynos_cpuclk_cfg_data e4210_armclk_d[] __initconst = {
|
|||
{ 0 },
|
||||
};
|
||||
|
||||
static const struct exynos_cpuclk_cfg_data e4212_armclk_d[] __initconst = {
|
||||
{ 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
|
||||
{ 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
|
||||
{ 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
|
||||
{ 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
|
||||
{ 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4210_CPU_DIV1(2, 4), },
|
||||
{ 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4210_CPU_DIV1(2, 4), },
|
||||
{ 900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
|
||||
{ 200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4210_CPU_DIV1(2, 3), },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
#define E4412_CPU_DIV1(cores, hpm, copy) \
|
||||
(((cores) << 8) | ((hpm) << 4) | ((copy) << 0))
|
||||
|
||||
static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
|
||||
{ 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(7, 0, 6), },
|
||||
{ 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(6, 0, 6), },
|
||||
{ 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(6, 0, 5), },
|
||||
{ 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(5, 0, 5), },
|
||||
{ 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4412_CPU_DIV1(5, 0, 4), },
|
||||
{ 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4412_CPU_DIV1(4, 0, 4), },
|
||||
{ 900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(4, 0, 3), },
|
||||
{ 800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(3, 0, 3), },
|
||||
{ 700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(3, 0, 3), },
|
||||
{ 600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
|
||||
{ 500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
|
||||
{ 400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
|
||||
{ 300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
|
||||
{ 200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4412_CPU_DIV1(0, 0, 3), },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
/* register exynos4 clocks */
|
||||
static void __init exynos4_clk_init(struct device_node *np,
|
||||
enum exynos4_soc soc)
|
||||
|
@ -1491,6 +1530,17 @@ static void __init exynos4_clk_init(struct device_node *np,
|
|||
samsung_clk_register_fixed_factor(ctx,
|
||||
exynos4x12_fixed_factor_clks,
|
||||
ARRAY_SIZE(exynos4x12_fixed_factor_clks));
|
||||
if (of_machine_is_compatible("samsung,exynos4412")) {
|
||||
exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
|
||||
mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
|
||||
e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
|
||||
CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
|
||||
} else {
|
||||
exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
|
||||
mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
|
||||
e4212_armclk_d, ARRAY_SIZE(e4212_armclk_d),
|
||||
CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
|
||||
}
|
||||
}
|
||||
|
||||
samsung_clk_register_alias(ctx, exynos4_aliases,
|
||||
|
|
|
@ -24,55 +24,6 @@ config ARM_VEXPRESS_SPC_CPUFREQ
|
|||
This add the CPUfreq driver support for Versatile Express
|
||||
big.LITTLE platforms using SPC for power management.
|
||||
|
||||
|
||||
config ARM_EXYNOS_CPUFREQ
|
||||
tristate "SAMSUNG EXYNOS CPUfreq Driver"
|
||||
depends on CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
|
||||
depends on THERMAL
|
||||
help
|
||||
This adds the CPUFreq driver for Samsung EXYNOS platforms.
|
||||
Supported SoC versions are:
|
||||
Exynos4210, Exynos4212, Exynos4412, and Exynos5250.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config ARM_EXYNOS4X12_CPUFREQ
|
||||
bool "SAMSUNG EXYNOS4x12"
|
||||
depends on SOC_EXYNOS4212 || SOC_EXYNOS4412
|
||||
depends on ARM_EXYNOS_CPUFREQ
|
||||
default y
|
||||
help
|
||||
This adds the CPUFreq driver for Samsung EXYNOS4X12
|
||||
SoC (EXYNOS4212 or EXYNOS4412).
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config ARM_EXYNOS5250_CPUFREQ
|
||||
bool "SAMSUNG EXYNOS5250"
|
||||
depends on SOC_EXYNOS5250
|
||||
depends on ARM_EXYNOS_CPUFREQ
|
||||
default y
|
||||
help
|
||||
This adds the CPUFreq driver for Samsung EXYNOS5250
|
||||
SoC.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config ARM_EXYNOS_CPU_FREQ_BOOST_SW
|
||||
bool "EXYNOS Frequency Overclocking - Software"
|
||||
depends on ARM_EXYNOS_CPUFREQ && THERMAL
|
||||
select CPU_FREQ_BOOST_SW
|
||||
select EXYNOS_THERMAL
|
||||
help
|
||||
This driver supports software managed overclocking (BOOST).
|
||||
It allows usage of special frequencies for Samsung Exynos
|
||||
processors if thermal conditions are appropriate.
|
||||
|
||||
It requires, for safe operation, thermal framework with properly
|
||||
defined trip points.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config ARM_EXYNOS5440_CPUFREQ
|
||||
tristate "SAMSUNG EXYNOS5440"
|
||||
depends on SOC_EXYNOS5440
|
||||
|
|
|
@ -52,10 +52,6 @@ obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
|
|||
|
||||
obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
|
||||
obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o
|
||||
obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += arm-exynos-cpufreq.o
|
||||
arm-exynos-cpufreq-y := exynos-cpufreq.o
|
||||
arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
|
||||
arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
|
||||
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
|
||||
obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
|
||||
obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* EXYNOS - CPU frequency scaling support for EXYNOS series
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include "exynos-cpufreq.h"
|
||||
|
||||
static struct exynos_dvfs_info *exynos_info;
|
||||
static struct thermal_cooling_device *cdev;
|
||||
static struct regulator *arm_regulator;
|
||||
static unsigned int locking_frequency;
|
||||
|
||||
static int exynos_cpufreq_get_index(unsigned int freq)
|
||||
{
|
||||
struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
|
||||
struct cpufreq_frequency_table *pos;
|
||||
|
||||
cpufreq_for_each_entry(pos, freq_table)
|
||||
if (pos->frequency == freq)
|
||||
break;
|
||||
|
||||
if (pos->frequency == CPUFREQ_TABLE_END)
|
||||
return -EINVAL;
|
||||
|
||||
return pos - freq_table;
|
||||
}
|
||||
|
||||
static int exynos_cpufreq_scale(unsigned int target_freq)
|
||||
{
|
||||
struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
|
||||
unsigned int *volt_table = exynos_info->volt_table;
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
|
||||
unsigned int arm_volt, safe_arm_volt = 0;
|
||||
unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz;
|
||||
struct device *dev = exynos_info->dev;
|
||||
unsigned int old_freq;
|
||||
int index, old_index;
|
||||
int ret = 0;
|
||||
|
||||
old_freq = policy->cur;
|
||||
|
||||
/*
|
||||
* The policy max have been changed so that we cannot get proper
|
||||
* old_index with cpufreq_frequency_table_target(). Thus, ignore
|
||||
* policy and get the index from the raw frequency table.
|
||||
*/
|
||||
old_index = exynos_cpufreq_get_index(old_freq);
|
||||
if (old_index < 0) {
|
||||
ret = old_index;
|
||||
goto out;
|
||||
}
|
||||
|
||||
index = exynos_cpufreq_get_index(target_freq);
|
||||
if (index < 0) {
|
||||
ret = index;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* ARM clock source will be changed APLL to MPLL temporary
|
||||
* To support this level, need to control regulator for
|
||||
* required voltage level
|
||||
*/
|
||||
if (exynos_info->need_apll_change != NULL) {
|
||||
if (exynos_info->need_apll_change(old_index, index) &&
|
||||
(freq_table[index].frequency < mpll_freq_khz) &&
|
||||
(freq_table[old_index].frequency < mpll_freq_khz))
|
||||
safe_arm_volt = volt_table[exynos_info->pll_safe_idx];
|
||||
}
|
||||
arm_volt = volt_table[index];
|
||||
|
||||
/* When the new frequency is higher than current frequency */
|
||||
if ((target_freq > old_freq) && !safe_arm_volt) {
|
||||
/* Firstly, voltage up to increase frequency */
|
||||
ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set cpu voltage to %d\n",
|
||||
arm_volt);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe_arm_volt) {
|
||||
ret = regulator_set_voltage(arm_regulator, safe_arm_volt,
|
||||
safe_arm_volt);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set cpu voltage to %d\n",
|
||||
safe_arm_volt);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
exynos_info->set_freq(old_index, index);
|
||||
|
||||
/* When the new frequency is lower than current frequency */
|
||||
if ((target_freq < old_freq) ||
|
||||
((target_freq > old_freq) && safe_arm_volt)) {
|
||||
/* down the voltage after frequency change */
|
||||
ret = regulator_set_voltage(arm_regulator, arm_volt,
|
||||
arm_volt);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set cpu voltage to %d\n",
|
||||
arm_volt);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
cpufreq_cpu_put(policy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
|
||||
{
|
||||
return exynos_cpufreq_scale(exynos_info->freq_table[index].frequency);
|
||||
}
|
||||
|
||||
static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
policy->clk = exynos_info->cpu_clk;
|
||||
policy->suspend_freq = locking_frequency;
|
||||
return cpufreq_generic_init(policy, exynos_info->freq_table, 100000);
|
||||
}
|
||||
|
||||
static struct cpufreq_driver exynos_driver = {
|
||||
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
|
||||
.verify = cpufreq_generic_frequency_table_verify,
|
||||
.target_index = exynos_target,
|
||||
.get = cpufreq_generic_get,
|
||||
.init = exynos_cpufreq_cpu_init,
|
||||
.name = "exynos_cpufreq",
|
||||
.attr = cpufreq_generic_attr,
|
||||
#ifdef CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW
|
||||
.boost_supported = true,
|
||||
#endif
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = cpufreq_generic_suspend,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int exynos_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *cpu0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
|
||||
if (!exynos_info)
|
||||
return -ENOMEM;
|
||||
|
||||
exynos_info->dev = &pdev->dev;
|
||||
|
||||
if (of_machine_is_compatible("samsung,exynos4212")) {
|
||||
exynos_info->type = EXYNOS_SOC_4212;
|
||||
ret = exynos4x12_cpufreq_init(exynos_info);
|
||||
} else if (of_machine_is_compatible("samsung,exynos4412")) {
|
||||
exynos_info->type = EXYNOS_SOC_4412;
|
||||
ret = exynos4x12_cpufreq_init(exynos_info);
|
||||
} else if (of_machine_is_compatible("samsung,exynos5250")) {
|
||||
exynos_info->type = EXYNOS_SOC_5250;
|
||||
ret = exynos5250_cpufreq_init(exynos_info);
|
||||
} else {
|
||||
pr_err("%s: Unknown SoC type\n", __func__);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto err_vdd_arm;
|
||||
|
||||
if (exynos_info->set_freq == NULL) {
|
||||
dev_err(&pdev->dev, "No set_freq function (ERR)\n");
|
||||
ret = -EINVAL;
|
||||
goto err_vdd_arm;
|
||||
}
|
||||
|
||||
arm_regulator = regulator_get(NULL, "vdd_arm");
|
||||
if (IS_ERR(arm_regulator)) {
|
||||
dev_err(&pdev->dev, "failed to get resource vdd_arm\n");
|
||||
ret = -EINVAL;
|
||||
goto err_vdd_arm;
|
||||
}
|
||||
|
||||
/* Done here as we want to capture boot frequency */
|
||||
locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;
|
||||
|
||||
ret = cpufreq_register_driver(&exynos_driver);
|
||||
if (ret)
|
||||
goto err_cpufreq_reg;
|
||||
|
||||
cpu0 = of_get_cpu_node(0, NULL);
|
||||
if (!cpu0) {
|
||||
pr_err("failed to find cpu0 node\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (of_find_property(cpu0, "#cooling-cells", NULL)) {
|
||||
cdev = of_cpufreq_cooling_register(cpu0,
|
||||
cpu_present_mask);
|
||||
if (IS_ERR(cdev))
|
||||
pr_err("running cpufreq without cooling device: %ld\n",
|
||||
PTR_ERR(cdev));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_cpufreq_reg:
|
||||
dev_err(&pdev->dev, "failed to register cpufreq driver\n");
|
||||
regulator_put(arm_regulator);
|
||||
err_vdd_arm:
|
||||
kfree(exynos_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver exynos_cpufreq_platdrv = {
|
||||
.driver = {
|
||||
.name = "exynos-cpufreq",
|
||||
},
|
||||
.probe = exynos_cpufreq_probe,
|
||||
};
|
||||
module_platform_driver(exynos_cpufreq_platdrv);
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* EXYNOS - CPUFreq support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
enum cpufreq_level_index {
|
||||
L0, L1, L2, L3, L4,
|
||||
L5, L6, L7, L8, L9,
|
||||
L10, L11, L12, L13, L14,
|
||||
L15, L16, L17, L18, L19,
|
||||
L20,
|
||||
};
|
||||
|
||||
enum exynos_soc_type {
|
||||
EXYNOS_SOC_4212,
|
||||
EXYNOS_SOC_4412,
|
||||
EXYNOS_SOC_5250,
|
||||
};
|
||||
|
||||
#define APLL_FREQ(f, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, m, p, s) \
|
||||
{ \
|
||||
.freq = (f) * 1000, \
|
||||
.clk_div_cpu0 = ((a0) | (a1) << 4 | (a2) << 8 | (a3) << 12 | \
|
||||
(a4) << 16 | (a5) << 20 | (a6) << 24 | (a7) << 28), \
|
||||
.clk_div_cpu1 = (b0 << 0 | b1 << 4 | b2 << 8), \
|
||||
.mps = ((m) << 16 | (p) << 8 | (s)), \
|
||||
}
|
||||
|
||||
struct apll_freq {
|
||||
unsigned int freq;
|
||||
u32 clk_div_cpu0;
|
||||
u32 clk_div_cpu1;
|
||||
u32 mps;
|
||||
};
|
||||
|
||||
struct exynos_dvfs_info {
|
||||
enum exynos_soc_type type;
|
||||
struct device *dev;
|
||||
unsigned long mpll_freq_khz;
|
||||
unsigned int pll_safe_idx;
|
||||
struct clk *cpu_clk;
|
||||
unsigned int *volt_table;
|
||||
struct cpufreq_frequency_table *freq_table;
|
||||
void (*set_freq)(unsigned int, unsigned int);
|
||||
bool (*need_apll_change)(unsigned int, unsigned int);
|
||||
void __iomem *cmu_regs;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ
|
||||
extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
|
||||
#else
|
||||
static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_EXYNOS5250_CPUFREQ
|
||||
extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
|
||||
#else
|
||||
static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EXYNOS4_CLKSRC_CPU 0x14200
|
||||
#define EXYNOS4_CLKMUX_STATCPU 0x14400
|
||||
|
||||
#define EXYNOS4_CLKDIV_CPU 0x14500
|
||||
#define EXYNOS4_CLKDIV_CPU1 0x14504
|
||||
#define EXYNOS4_CLKDIV_STATCPU 0x14600
|
||||
#define EXYNOS4_CLKDIV_STATCPU1 0x14604
|
||||
|
||||
#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT (16)
|
||||
#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)
|
||||
|
||||
#define EXYNOS5_APLL_LOCK 0x00000
|
||||
#define EXYNOS5_APLL_CON0 0x00100
|
||||
#define EXYNOS5_CLKMUX_STATCPU 0x00400
|
||||
#define EXYNOS5_CLKDIV_CPU0 0x00500
|
||||
#define EXYNOS5_CLKDIV_CPU1 0x00504
|
||||
#define EXYNOS5_CLKDIV_STATCPU0 0x00600
|
||||
#define EXYNOS5_CLKDIV_STATCPU1 0x00604
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* EXYNOS4X12 - CPU frequency scaling support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "exynos-cpufreq.h"
|
||||
|
||||
static struct clk *cpu_clk;
|
||||
static struct clk *moutcore;
|
||||
static struct clk *mout_mpll;
|
||||
static struct clk *mout_apll;
|
||||
static struct exynos_dvfs_info *cpufreq;
|
||||
|
||||
static unsigned int exynos4x12_volt_table[] = {
|
||||
1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
|
||||
1000000, 987500, 975000, 950000, 925000, 900000, 900000
|
||||
};
|
||||
|
||||
static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
|
||||
{CPUFREQ_BOOST_FREQ, L0, 1500 * 1000},
|
||||
{0, L1, 1400 * 1000},
|
||||
{0, L2, 1300 * 1000},
|
||||
{0, L3, 1200 * 1000},
|
||||
{0, L4, 1100 * 1000},
|
||||
{0, L5, 1000 * 1000},
|
||||
{0, L6, 900 * 1000},
|
||||
{0, L7, 800 * 1000},
|
||||
{0, L8, 700 * 1000},
|
||||
{0, L9, 600 * 1000},
|
||||
{0, L10, 500 * 1000},
|
||||
{0, L11, 400 * 1000},
|
||||
{0, L12, 300 * 1000},
|
||||
{0, L13, 200 * 1000},
|
||||
{0, 0, CPUFREQ_TABLE_END},
|
||||
};
|
||||
|
||||
static struct apll_freq *apll_freq_4x12;
|
||||
|
||||
static struct apll_freq apll_freq_4212[] = {
|
||||
/*
|
||||
* values:
|
||||
* freq
|
||||
* clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
|
||||
* clock divider for COPY, HPM, RESERVED
|
||||
* PLL M, P, S
|
||||
*/
|
||||
APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 250, 4, 0),
|
||||
APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 175, 3, 0),
|
||||
APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 325, 6, 0),
|
||||
APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 200, 4, 0),
|
||||
APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 2, 0, 275, 6, 0),
|
||||
APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 2, 0, 125, 3, 0),
|
||||
APLL_FREQ(900, 0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 150, 4, 0),
|
||||
APLL_FREQ(800, 0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 0),
|
||||
APLL_FREQ(700, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 175, 3, 1),
|
||||
APLL_FREQ(600, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 200, 4, 1),
|
||||
APLL_FREQ(500, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 125, 3, 1),
|
||||
APLL_FREQ(400, 0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 1),
|
||||
APLL_FREQ(300, 0, 2, 4, 0, 2, 1, 1, 0, 3, 2, 0, 200, 4, 2),
|
||||
APLL_FREQ(200, 0, 1, 3, 0, 1, 1, 1, 0, 3, 2, 0, 100, 3, 2),
|
||||
};
|
||||
|
||||
static struct apll_freq apll_freq_4412[] = {
|
||||
/*
|
||||
* values:
|
||||
* freq
|
||||
* clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
|
||||
* clock divider for COPY, HPM, CORES
|
||||
* PLL M, P, S
|
||||
*/
|
||||
APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 7, 250, 4, 0),
|
||||
APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 6, 175, 3, 0),
|
||||
APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 6, 325, 6, 0),
|
||||
APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 5, 200, 4, 0),
|
||||
APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 0, 5, 275, 6, 0),
|
||||
APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 0, 4, 125, 3, 0),
|
||||
APLL_FREQ(900, 0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 4, 150, 4, 0),
|
||||
APLL_FREQ(800, 0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 3, 100, 3, 0),
|
||||
APLL_FREQ(700, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 3, 175, 3, 1),
|
||||
APLL_FREQ(600, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 200, 4, 1),
|
||||
APLL_FREQ(500, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 125, 3, 1),
|
||||
APLL_FREQ(400, 0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 1, 100, 3, 1),
|
||||
APLL_FREQ(300, 0, 2, 4, 0, 2, 1, 1, 0, 3, 0, 1, 200, 4, 2),
|
||||
APLL_FREQ(200, 0, 1, 3, 0, 1, 1, 1, 0, 3, 0, 0, 100, 3, 2),
|
||||
};
|
||||
|
||||
static void exynos4x12_set_clkdiv(unsigned int div_index)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
/* Change Divider - CPU0 */
|
||||
|
||||
tmp = apll_freq_4x12[div_index].clk_div_cpu0;
|
||||
|
||||
__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU);
|
||||
|
||||
while (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU)
|
||||
& 0x11111111)
|
||||
cpu_relax();
|
||||
|
||||
/* Change Divider - CPU1 */
|
||||
tmp = apll_freq_4x12[div_index].clk_div_cpu1;
|
||||
|
||||
__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU1);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU1);
|
||||
} while (tmp != 0x0);
|
||||
}
|
||||
|
||||
static void exynos4x12_set_apll(unsigned int index)
|
||||
{
|
||||
unsigned int tmp, freq = apll_freq_4x12[index].freq;
|
||||
|
||||
/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
|
||||
clk_set_parent(moutcore, mout_mpll);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU)
|
||||
>> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
|
||||
tmp &= 0x7;
|
||||
} while (tmp != 0x2);
|
||||
|
||||
clk_set_rate(mout_apll, freq * 1000);
|
||||
|
||||
/* MUX_CORE_SEL = APLL */
|
||||
clk_set_parent(moutcore, mout_apll);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU);
|
||||
tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
|
||||
} while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
|
||||
}
|
||||
|
||||
static void exynos4x12_set_frequency(unsigned int old_index,
|
||||
unsigned int new_index)
|
||||
{
|
||||
if (old_index > new_index) {
|
||||
exynos4x12_set_clkdiv(new_index);
|
||||
exynos4x12_set_apll(new_index);
|
||||
} else if (old_index < new_index) {
|
||||
exynos4x12_set_apll(new_index);
|
||||
exynos4x12_set_clkdiv(new_index);
|
||||
}
|
||||
}
|
||||
|
||||
int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
|
||||
{
|
||||
struct device_node *np;
|
||||
unsigned long rate;
|
||||
|
||||
/*
|
||||
* HACK: This is a temporary workaround to get access to clock
|
||||
* controller registers directly and remove static mappings and
|
||||
* dependencies on platform headers. It is necessary to enable
|
||||
* Exynos multi-platform support and will be removed together with
|
||||
* this whole driver as soon as Exynos gets migrated to use
|
||||
* cpufreq-dt driver.
|
||||
*/
|
||||
np = of_find_compatible_node(NULL, NULL, "samsung,exynos4412-clock");
|
||||
if (!np) {
|
||||
pr_err("%s: failed to find clock controller DT node\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->cmu_regs = of_iomap(np, 0);
|
||||
if (!info->cmu_regs) {
|
||||
pr_err("%s: failed to map CMU registers\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cpu_clk = clk_get(NULL, "armclk");
|
||||
if (IS_ERR(cpu_clk))
|
||||
return PTR_ERR(cpu_clk);
|
||||
|
||||
moutcore = clk_get(NULL, "moutcore");
|
||||
if (IS_ERR(moutcore))
|
||||
goto err_moutcore;
|
||||
|
||||
mout_mpll = clk_get(NULL, "mout_mpll");
|
||||
if (IS_ERR(mout_mpll))
|
||||
goto err_mout_mpll;
|
||||
|
||||
rate = clk_get_rate(mout_mpll) / 1000;
|
||||
|
||||
mout_apll = clk_get(NULL, "mout_apll");
|
||||
if (IS_ERR(mout_apll))
|
||||
goto err_mout_apll;
|
||||
|
||||
if (info->type == EXYNOS_SOC_4212)
|
||||
apll_freq_4x12 = apll_freq_4212;
|
||||
else
|
||||
apll_freq_4x12 = apll_freq_4412;
|
||||
|
||||
info->mpll_freq_khz = rate;
|
||||
/* 800Mhz */
|
||||
info->pll_safe_idx = L7;
|
||||
info->cpu_clk = cpu_clk;
|
||||
info->volt_table = exynos4x12_volt_table;
|
||||
info->freq_table = exynos4x12_freq_table;
|
||||
info->set_freq = exynos4x12_set_frequency;
|
||||
|
||||
cpufreq = info;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mout_apll:
|
||||
clk_put(mout_mpll);
|
||||
err_mout_mpll:
|
||||
clk_put(moutcore);
|
||||
err_moutcore:
|
||||
clk_put(cpu_clk);
|
||||
|
||||
pr_debug("%s: failed initialization\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-20122Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* EXYNOS5250 - CPU frequency scaling support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "exynos-cpufreq.h"
|
||||
|
||||
static struct clk *cpu_clk;
|
||||
static struct clk *moutcore;
|
||||
static struct clk *mout_mpll;
|
||||
static struct clk *mout_apll;
|
||||
static struct exynos_dvfs_info *cpufreq;
|
||||
|
||||
static unsigned int exynos5250_volt_table[] = {
|
||||
1300000, 1250000, 1225000, 1200000, 1150000,
|
||||
1125000, 1100000, 1075000, 1050000, 1025000,
|
||||
1012500, 1000000, 975000, 950000, 937500,
|
||||
925000
|
||||
};
|
||||
|
||||
static struct cpufreq_frequency_table exynos5250_freq_table[] = {
|
||||
{0, L0, 1700 * 1000},
|
||||
{0, L1, 1600 * 1000},
|
||||
{0, L2, 1500 * 1000},
|
||||
{0, L3, 1400 * 1000},
|
||||
{0, L4, 1300 * 1000},
|
||||
{0, L5, 1200 * 1000},
|
||||
{0, L6, 1100 * 1000},
|
||||
{0, L7, 1000 * 1000},
|
||||
{0, L8, 900 * 1000},
|
||||
{0, L9, 800 * 1000},
|
||||
{0, L10, 700 * 1000},
|
||||
{0, L11, 600 * 1000},
|
||||
{0, L12, 500 * 1000},
|
||||
{0, L13, 400 * 1000},
|
||||
{0, L14, 300 * 1000},
|
||||
{0, L15, 200 * 1000},
|
||||
{0, 0, CPUFREQ_TABLE_END},
|
||||
};
|
||||
|
||||
static struct apll_freq apll_freq_5250[] = {
|
||||
/*
|
||||
* values:
|
||||
* freq
|
||||
* clock divider for ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2
|
||||
* clock divider for COPY, HPM, RESERVED
|
||||
* PLL M, P, S
|
||||
*/
|
||||
APLL_FREQ(1700, 0, 3, 7, 7, 7, 3, 5, 0, 0, 2, 0, 425, 6, 0),
|
||||
APLL_FREQ(1600, 0, 3, 7, 7, 7, 1, 4, 0, 0, 2, 0, 200, 3, 0),
|
||||
APLL_FREQ(1500, 0, 2, 7, 7, 7, 1, 4, 0, 0, 2, 0, 250, 4, 0),
|
||||
APLL_FREQ(1400, 0, 2, 7, 7, 6, 1, 4, 0, 0, 2, 0, 175, 3, 0),
|
||||
APLL_FREQ(1300, 0, 2, 7, 7, 6, 1, 3, 0, 0, 2, 0, 325, 6, 0),
|
||||
APLL_FREQ(1200, 0, 2, 7, 7, 5, 1, 3, 0, 0, 2, 0, 200, 4, 0),
|
||||
APLL_FREQ(1100, 0, 3, 7, 7, 5, 1, 3, 0, 0, 2, 0, 275, 6, 0),
|
||||
APLL_FREQ(1000, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 125, 3, 0),
|
||||
APLL_FREQ(900, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 150, 4, 0),
|
||||
APLL_FREQ(800, 0, 1, 7, 7, 4, 1, 2, 0, 0, 2, 0, 100, 3, 0),
|
||||
APLL_FREQ(700, 0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 175, 3, 1),
|
||||
APLL_FREQ(600, 0, 1, 7, 7, 3, 1, 1, 0, 0, 2, 0, 200, 4, 1),
|
||||
APLL_FREQ(500, 0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 125, 3, 1),
|
||||
APLL_FREQ(400, 0, 1, 7, 7, 2, 1, 1, 0, 0, 2, 0, 100, 3, 1),
|
||||
APLL_FREQ(300, 0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 200, 4, 2),
|
||||
APLL_FREQ(200, 0, 1, 7, 7, 1, 1, 1, 0, 0, 2, 0, 100, 3, 2),
|
||||
};
|
||||
|
||||
static void set_clkdiv(unsigned int div_index)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
/* Change Divider - CPU0 */
|
||||
|
||||
tmp = apll_freq_5250[div_index].clk_div_cpu0;
|
||||
|
||||
__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU0);
|
||||
|
||||
while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU0)
|
||||
& 0x11111111)
|
||||
cpu_relax();
|
||||
|
||||
/* Change Divider - CPU1 */
|
||||
tmp = apll_freq_5250[div_index].clk_div_cpu1;
|
||||
|
||||
__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU1);
|
||||
|
||||
while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU1) & 0x11)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void set_apll(unsigned int index)
|
||||
{
|
||||
unsigned int tmp;
|
||||
unsigned int freq = apll_freq_5250[index].freq;
|
||||
|
||||
/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
|
||||
clk_set_parent(moutcore, mout_mpll);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU)
|
||||
>> 16);
|
||||
tmp &= 0x7;
|
||||
} while (tmp != 0x2);
|
||||
|
||||
clk_set_rate(mout_apll, freq * 1000);
|
||||
|
||||
/* MUX_CORE_SEL = APLL */
|
||||
clk_set_parent(moutcore, mout_apll);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU);
|
||||
tmp &= (0x7 << 16);
|
||||
} while (tmp != (0x1 << 16));
|
||||
}
|
||||
|
||||
static void exynos5250_set_frequency(unsigned int old_index,
|
||||
unsigned int new_index)
|
||||
{
|
||||
if (old_index > new_index) {
|
||||
set_clkdiv(new_index);
|
||||
set_apll(new_index);
|
||||
} else if (old_index < new_index) {
|
||||
set_apll(new_index);
|
||||
set_clkdiv(new_index);
|
||||
}
|
||||
}
|
||||
|
||||
int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
|
||||
{
|
||||
struct device_node *np;
|
||||
unsigned long rate;
|
||||
|
||||
/*
|
||||
* HACK: This is a temporary workaround to get access to clock
|
||||
* controller registers directly and remove static mappings and
|
||||
* dependencies on platform headers. It is necessary to enable
|
||||
* Exynos multi-platform support and will be removed together with
|
||||
* this whole driver as soon as Exynos gets migrated to use
|
||||
* cpufreq-dt driver.
|
||||
*/
|
||||
np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-clock");
|
||||
if (!np) {
|
||||
pr_err("%s: failed to find clock controller DT node\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->cmu_regs = of_iomap(np, 0);
|
||||
if (!info->cmu_regs) {
|
||||
pr_err("%s: failed to map CMU registers\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cpu_clk = clk_get(NULL, "armclk");
|
||||
if (IS_ERR(cpu_clk))
|
||||
return PTR_ERR(cpu_clk);
|
||||
|
||||
moutcore = clk_get(NULL, "mout_cpu");
|
||||
if (IS_ERR(moutcore))
|
||||
goto err_moutcore;
|
||||
|
||||
mout_mpll = clk_get(NULL, "mout_mpll");
|
||||
if (IS_ERR(mout_mpll))
|
||||
goto err_mout_mpll;
|
||||
|
||||
rate = clk_get_rate(mout_mpll) / 1000;
|
||||
|
||||
mout_apll = clk_get(NULL, "mout_apll");
|
||||
if (IS_ERR(mout_apll))
|
||||
goto err_mout_apll;
|
||||
|
||||
info->mpll_freq_khz = rate;
|
||||
/* 800Mhz */
|
||||
info->pll_safe_idx = L9;
|
||||
info->cpu_clk = cpu_clk;
|
||||
info->volt_table = exynos5250_volt_table;
|
||||
info->freq_table = exynos5250_freq_table;
|
||||
info->set_freq = exynos5250_set_frequency;
|
||||
|
||||
cpufreq = info;
|
||||
|
||||
return 0;
|
||||
|
||||
err_mout_apll:
|
||||
clk_put(mout_mpll);
|
||||
err_mout_mpll:
|
||||
clk_put(moutcore);
|
||||
err_moutcore:
|
||||
clk_put(cpu_clk);
|
||||
|
||||
pr_err("%s: failed initialization\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
|
@ -89,6 +89,7 @@ static int ath79_reset_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(ath79_reset->base))
|
||||
return PTR_ERR(ath79_reset->base);
|
||||
|
||||
spin_lock_init(&ath79_reset->lock);
|
||||
ath79_reset->rcdev.ops = &ath79_reset_ops;
|
||||
ath79_reset->rcdev.owner = THIS_MODULE;
|
||||
ath79_reset->rcdev.of_node = pdev->dev.of_node;
|
||||
|
|
|
@ -96,6 +96,7 @@ static const struct {
|
|||
* @smd: handle to qcom_smd
|
||||
* @of_node: of_node handle for information related to this edge
|
||||
* @edge_id: identifier of this edge
|
||||
* @remote_pid: identifier of remote processor
|
||||
* @irq: interrupt for signals on this edge
|
||||
* @ipc_regmap: regmap handle holding the outgoing ipc register
|
||||
* @ipc_offset: offset within @ipc_regmap of the register for ipc
|
||||
|
@ -111,6 +112,7 @@ struct qcom_smd_edge {
|
|||
struct qcom_smd *smd;
|
||||
struct device_node *of_node;
|
||||
unsigned edge_id;
|
||||
unsigned remote_pid;
|
||||
|
||||
int irq;
|
||||
|
||||
|
@ -310,7 +312,7 @@ static void qcom_smd_channel_reset(struct qcom_smd_channel *channel)
|
|||
SET_TX_CHANNEL_INFO(channel, fHEAD, 0);
|
||||
SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
|
||||
SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
|
||||
SET_TX_CHANNEL_INFO(channel, head, 0);
|
||||
SET_TX_CHANNEL_INFO(channel, tail, 0);
|
||||
|
||||
|
@ -572,7 +574,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
|
|||
* have to scan if the amount of available space in smem have changed
|
||||
* since last scan.
|
||||
*/
|
||||
available = qcom_smem_get_free_space(edge->edge_id);
|
||||
available = qcom_smem_get_free_space(edge->remote_pid);
|
||||
if (available != edge->smem_available) {
|
||||
edge->smem_available = available;
|
||||
edge->need_rescan = true;
|
||||
|
@ -681,7 +683,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
|
|||
goto out;
|
||||
}
|
||||
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
|
||||
|
||||
ret = wait_event_interruptible(channel->fblockread_event,
|
||||
qcom_smd_get_tx_avail(channel) >= tlen ||
|
||||
|
@ -689,7 +691,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
|
||||
SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
|
||||
}
|
||||
|
||||
SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
|
||||
|
@ -976,7 +978,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
|
|||
spin_lock_init(&channel->recv_lock);
|
||||
init_waitqueue_head(&channel->fblockread_event);
|
||||
|
||||
ret = qcom_smem_get(edge->edge_id, smem_info_item, (void **)&info, &info_size);
|
||||
ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
|
||||
&info_size);
|
||||
if (ret)
|
||||
goto free_name_and_channel;
|
||||
|
||||
|
@ -997,7 +1000,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
|
|||
goto free_name_and_channel;
|
||||
}
|
||||
|
||||
ret = qcom_smem_get(edge->edge_id, smem_fifo_item, &fifo_base, &fifo_size);
|
||||
ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
|
||||
&fifo_size);
|
||||
if (ret)
|
||||
goto free_name_and_channel;
|
||||
|
||||
|
@ -1041,7 +1045,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
|
|||
int i;
|
||||
|
||||
for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
|
||||
ret = qcom_smem_get(edge->edge_id,
|
||||
ret = qcom_smem_get(edge->remote_pid,
|
||||
smem_items[tbl].alloc_tbl_id,
|
||||
(void **)&alloc_tbl,
|
||||
NULL);
|
||||
|
@ -1184,6 +1188,10 @@ static int qcom_smd_parse_edge(struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
edge->remote_pid = QCOM_SMEM_HOST_ANY;
|
||||
key = "qcom,remote-pid";
|
||||
of_property_read_u32(node, key, &edge->remote_pid);
|
||||
|
||||
syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
|
||||
if (!syscon_np) {
|
||||
dev_err(dev, "no qcom,ipc node\n");
|
||||
|
|
|
@ -258,10 +258,6 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
|
|||
size_t alloc_size;
|
||||
void *p;
|
||||
|
||||
/* We're not going to find it if there's no matching partition */
|
||||
if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
|
||||
return -ENOENT;
|
||||
|
||||
phdr = smem->partitions[host];
|
||||
|
||||
p = (void *)phdr + sizeof(*phdr);
|
||||
|
@ -371,8 +367,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qcom_smem_alloc_private(__smem, host, item, size);
|
||||
if (ret == -ENOENT)
|
||||
if (host < SMEM_HOST_COUNT && __smem->partitions[host])
|
||||
ret = qcom_smem_alloc_private(__smem, host, item, size);
|
||||
else
|
||||
ret = qcom_smem_alloc_global(__smem, item, size);
|
||||
|
||||
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
|
||||
|
@ -428,10 +425,6 @@ static int qcom_smem_get_private(struct qcom_smem *smem,
|
|||
struct smem_private_entry *hdr;
|
||||
void *p;
|
||||
|
||||
/* We're not going to find it if there's no matching partition */
|
||||
if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
|
||||
return -ENOENT;
|
||||
|
||||
phdr = smem->partitions[host];
|
||||
|
||||
p = (void *)phdr + sizeof(*phdr);
|
||||
|
@ -484,8 +477,9 @@ int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qcom_smem_get_private(__smem, host, item, ptr, size);
|
||||
if (ret == -ENOENT)
|
||||
if (host < SMEM_HOST_COUNT && __smem->partitions[host])
|
||||
ret = qcom_smem_get_private(__smem, host, item, ptr, size);
|
||||
else
|
||||
ret = qcom_smem_get_global(__smem, item, ptr, size);
|
||||
|
||||
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
|
||||
|
|
|
@ -74,6 +74,20 @@ static inline int device_reset_optional(struct device *dev)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline struct reset_control *__must_check reset_control_get(
|
||||
struct device *dev, const char *id)
|
||||
{
|
||||
WARN_ON(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline struct reset_control *__must_check devm_reset_control_get(
|
||||
struct device *dev, const char *id)
|
||||
{
|
||||
WARN_ON(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static inline struct reset_control *reset_control_get_optional(
|
||||
struct device *dev, const char *id)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue