Merge "msm: gpiomux: Add audio clock related misc TLMM registers"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
index 5692ad2..4a1fb59 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_tspp.txt
@@ -38,7 +38,6 @@
the below optional properties:
- qcom,msm-bus,name
- qcom,msm-bus,num-cases
- - qcom,msm-bus,active-only
- qcom,msm-bus,num-paths
- qcom,msm-bus,vectors-KBps
@@ -85,7 +84,6 @@
qcom,msm-bus,name = "tsif";
qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,active-only = <0>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<82 512 0 0>, /* No vote */
diff --git a/Documentation/devicetree/bindings/arm/msm/smem.txt b/Documentation/devicetree/bindings/arm/msm/smem.txt
index a38984c..b6dcdc1 100644
--- a/Documentation/devicetree/bindings/arm/msm/smem.txt
+++ b/Documentation/devicetree/bindings/arm/msm/smem.txt
@@ -10,6 +10,10 @@
"aux-mem1", "aux-mem2", "aux-mem3", ... - optional strings to
identify any auxiliary shared memory regions
+Optional properties:
+-mpu-enabled : boolean value indicating that Memory Protection Unit based
+ security is enabled on the "smem" shared memory region
+
[Second level nodes]
qcom,smd
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 9ad8abe..9b30b39 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -63,6 +63,10 @@
Optional properties:
- qcom,mdss-dsi-panel-name: A string used as a descriptive name of the panel
- qcom,cont-splash-enabled: Boolean used to enable continuous splash mode.
+ If this property is specified, it is required to
+ to specify the memory reserved for the splash
+ screen using the qcom,memblock-reserve binding
+ for the framebuffer device attached to the panel.
- qcom,mdss-dsi-panel-broadcast-mode: Boolean used to enable broadcast mode.
- qcom,mdss-dsi-fbc-enable: Boolean used to enable frame buffer compression mode.
- qcom,mdss-dsi-fbc-bpp: Compressed bpp supported by the panel.
@@ -116,6 +120,12 @@
0xff = default value.
- qcom,mdss-dsi-border-color: Defines the border color value if border is present.
0 = default value.
+- qcom,mdss-dsi-pan-enable-dynamic-fps: Boolean used to enable change in frame rate dynamically.
+- qcom,mdss-dsi-pan-fps-update: A string that specifies when to change the frame rate.
+ "dfps_suspend_resume_mode"= FPS change request is
+ implemented during suspend/resume.
+ "dfps_immediate_clk_mode" = FPS change request is
+ implemented immediately using DSI clocks.
- qcom,mdss-dsi-bl-pmic-control-type: A string that specifies the implementation of backlight
control for this panel.
"bl_ctrl_pwm" = Backlight controlled by PWM gpio.
@@ -232,7 +242,8 @@
in dsi controller.
"high" = Set GPIO to HIGH
"low" = Set GPIO to LOW
-
+- qcom,partial-update-enabled: Boolean used to enable partial
+ panel update for command mode panels.
Note, if a given optional qcom,* binding is not present, then the driver will configure
the default values specified.
@@ -315,11 +326,14 @@
qcom,mdss-dsi-off-command = [22 01 00 00 00 00 00];
qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_suspend_resume_mode";
qcom,mdss-dsi-bl-pmic-bank-select = <0>;
qcom,mdss-dsi-bl-pmic-pwm-frequency = <0>;
qcom,mdss-dsi-pwm-gpio = <&pm8941_mpps 5 0>;
qcom,mdss-pan-physical-width-dimension = <60>;
qcom,mdss-pan-physical-height-dimension = <140>;
qcom,mdss-dsi-panel-mode-gpio-state = "low";
+ qcom,partial-update-enabled;
};
};
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 829cce2..5a70b6b 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -163,6 +163,11 @@
enabled if framebuffer size is less than max mixer
width; 2) the defaut even split is enabled if frambuffer
size is greater than max mixer width.
+- qcom,memblock-reserve: Specifies the memory location and the size reserved
+ for the framebuffer used to display the splash screen.
+ This property is required whenever the continuous splash
+ screen feature is enabled for the corresponding
+ framebuffer device.
Example:
mdss_mdp: qcom,mdss_mdp@fd900000 {
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index a419f5e..8a20b47 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -26,6 +26,7 @@
- boot_reason [ ARM only ]
- callhome [ S390 only ]
- cap_last_cap
+- cold_boot [ ARM only ]
- core_pattern
- core_pipe_limit
- core_uses_pid
@@ -176,6 +177,16 @@
Highest valid capability of the running kernel. Exports
CAP_LAST_CAP from the kernel.
+===============================================================
+
+cold_boot
+
+ARM -- indicator for system cold boot
+
+A single bit will be set in the unsigned integer value to identify
+whether the device was booted from a cold or warm state. Zero
+indicating a warm boot and one indicating a cold boot.
+
==============================================================
core_pattern:
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 58fc698..aa37edc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1854,6 +1854,11 @@
config DONT_MAP_HOLE_AFTER_MEMBANK0
def_bool n
+ depends on ENABLE_VMALLOC_SAVING=n
+
+config ENABLE_VMALLOC_SAVING
+ def_bool n
+ depends on DONT_MAP_HOLE_AFTER_MEMBANK0=n
config HOLES_IN_ZONE
def_bool n
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
index 0b98db7..021ddef 100644
--- a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -90,6 +90,7 @@
qcom,mdss-dsi-dma-trigger = <0x04>;
qcom,mdss-dsi-mdp-trigger = <0x0>;
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
-
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_suspend_resume_mode";
};
};
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-cdp.dtsi
index d377bf0..3ebe225 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-cdp.dtsi
@@ -104,7 +104,7 @@
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
- qcom,headset-jack-type-NO;
+ qcom,headset-jack-type-NC;
};
sound-9302 {
@@ -122,7 +122,7 @@
qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
- qcom,headset-jack-type-NO;
+ qcom,headset-jack-type-NC;
};
};
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 2ec7b6c..c7a4eee 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -49,6 +49,7 @@
compatible = "qcom,mdss-fb";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x800000>;
+ qcom,memblock-reserve = <0x03200000 0xFA0000>;
};
mdss_fb1: qcom,mdss_fb_wfd {
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
index cbafe80..d12f8c9 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
@@ -46,6 +46,29 @@
qcom,cdc-us-euro-gpios;
};
+ sound-9302 {
+ qcom,model = "msm8226-tapan9302-skuf-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "Lineout_1 amp", "LINEOUT1",
+ "Lineout_2 amp", "LINEOUT2",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-lineout-spkr-gpios = <&pm8226_gpios 2 0>;
+ qcom,cdc-vdd-spkr-gpios;
+ qcom,cdc-us-euro-gpios;
+ };
+
tp_power: regulator-tp {
compatible = "regulator-fixed";
regulator-name = "tp_power";
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
index 77037be..9a750ae 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
@@ -46,6 +46,29 @@
qcom,cdc-us-euro-gpios;
};
+ sound-9302 {
+ qcom,model = "msm8226-tapan9302-skuf-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "Lineout_1 amp", "LINEOUT1",
+ "Lineout_2 amp", "LINEOUT2",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-lineout-spkr-gpios = <&pm8226_gpios 2 0>;
+ qcom,cdc-vdd-spkr-gpios;
+ qcom,cdc-us-euro-gpios;
+ };
+
tp_power: regulator-tp {
compatible = "regulator-fixed";
regulator-name = "tp_power";
diff --git a/arch/arm/boot/dts/msm8610-cdp.dtsi b/arch/arm/boot/dts/msm8610-cdp.dtsi
index 4e0ee32..452cc2f 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8610-cdp.dtsi
@@ -76,21 +76,6 @@
];
};
};
-
- synaptics@20 {
- compatible = "synaptics,rmi4";
- reg = <0x20>;
- interrupt-parent = <&msmgpio>;
- interrupts = <1 0x2008>;
- vdd-supply = <&pm8110_l19>;
- vcc_i2c-supply = <&pm8110_l14>;
- synaptics,reset-gpio = <&msmgpio 0 0x00>;
- synaptics,irq-gpio = <&msmgpio 1 0x2008>;
- synaptics,button-map = <139 102 158>;
- synaptics,i2c-pull-up;
- synaptics,power-down;
- synaptics,disable-gpios;
- };
};
gen-vkeys {
diff --git a/arch/arm/boot/dts/msm8610-mdss.dtsi b/arch/arm/boot/dts/msm8610-mdss.dtsi
index f37a42b..de74e52 100644
--- a/arch/arm/boot/dts/msm8610-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8610-mdss.dtsi
@@ -20,6 +20,7 @@
mdss_fb0: qcom,mdss_fb_primary {
cell-index = <0>;
compatible = "qcom,mdss-fb";
+ qcom,memblock-reserve = <0x3200000 0x800000>;
};
};
diff --git a/arch/arm/boot/dts/msm8610-mtp.dtsi b/arch/arm/boot/dts/msm8610-mtp.dtsi
index 82f5aea..1cc3e61 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-mtp.dtsi
@@ -76,21 +76,6 @@
];
};
};
-
- synaptics@20 {
- compatible = "synaptics,rmi4";
- reg = <0x20>;
- interrupt-parent = <&msmgpio>;
- interrupts = <1 0x2008>;
- vdd-supply = <&pm8110_l19>;
- vcc_i2c-supply = <&pm8110_l14>;
- synaptics,reset-gpio = <&msmgpio 0 0x00>;
- synaptics,irq-gpio = <&msmgpio 1 0x2008>;
- synaptics,button-map = <139 102 158>;
- synaptics,i2c-pull-up;
- synaptics,power-down;
- synaptics,disable-gpios;
- };
};
i2c@f9925000 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 24b5860..7181db2 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -64,6 +64,7 @@
compatible = "qcom,mdss-fb";
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x800000>;
+ qcom,memblock-reserve = <0x03200000 0x01E00000>;
};
mdss_fb1: qcom,mdss_fb_external {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 0283bfd..3057e6e 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -77,7 +77,7 @@
adsp_mem: adsp_region {
linux,contiguous-region;
- reg = <0 0x2F00000>;
+ reg = <0 0x3F00000>;
label = "adsp_mem";
};
@@ -220,7 +220,7 @@
qcom,vidc {
compatible = "qcom,msm-vidc";
qcom,hfi = "q6";
- qcom,max-hw-load = <108000>; /* 720p @ 30 */
+ qcom,max-hw-load = <243000>; /* 1080p @ 30 */
};
qcom,wfd {
@@ -629,10 +629,10 @@
"MSM_TSIF1_PHYS",
"MSM_TSPP_PHYS",
"MSM_TSPP_BAM_PHYS";
- interrupts = <0 153 0>, /* TSIF_TSPP_IRQ */
- <0 151 0>, /* TSIF0_IRQ */
- <0 152 0>, /* TSIF1_IRQ */
- <0 154 0>; /* TSIF_BAM_IRQ */
+ interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */
+ <0 119 0>, /* TSIF0_IRQ */
+ <0 120 0>, /* TSIF1_IRQ */
+ <0 122 0>; /* TSIF_BAM_IRQ */
interrupt-names = "TSIF_TSPP_IRQ",
"TSIF0_IRQ",
"TSIF1_IRQ",
@@ -659,7 +659,6 @@
qcom,msm-bus,name = "tsif";
qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,active-only = <0>;
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps =
<82 512 0 0>, /* No vote */
@@ -1561,7 +1560,8 @@
memory_hole: qcom,msm-mem-hole {
compatible = "qcom,msm-mem-hole";
- qcom,memblock-remove = <0x5d00000 0xa200000>; /* Address and Size of Hole */
+ qcom,memblock-remove = <0x5d00000 0x7d00000
+ 0xfa00000 0x500000>; /* Address and Size of Hole */
};
uart7: uart@f995d000 { /*BLSP #2, UART #7 */
diff --git a/arch/arm/boot/dts/msm8974pro-ab-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
index 002baf7..f61b4a6 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-mtp.dts
@@ -26,3 +26,7 @@
<217 8 0x10000>,
<218 8 0x10000>;
};
+
+&sdhc_1 {
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+};
diff --git a/arch/arm/boot/dts/msm8974pro-ab.dtsi b/arch/arm/boot/dts/msm8974pro-ab.dtsi
index 5809069..0f37584 100644
--- a/arch/arm/boot/dts/msm8974pro-ab.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ab.dtsi
@@ -36,6 +36,22 @@
qcom,use-phase-switching;
};
+&krait0_vreg {
+ regulator-max-microvolt = <1120000>;
+};
+
+&krait1_vreg {
+ regulator-max-microvolt = <1120000>;
+};
+
+&krait2_vreg {
+ regulator-max-microvolt = <1120000>;
+};
+
+&krait3_vreg {
+ regulator-max-microvolt = <1120000>;
+};
+
&tspp {
vdd_cx-supply = <&pm8841_s2_corner>;
};
diff --git a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
index 237c9f9..e1d7605 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ac-mtp.dts
@@ -126,7 +126,7 @@
&sdhc_1 {
reg = <0xf9824900 0x1a0>, <0xf9824000 0x800>;
- qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000 400000000>;
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 200000000 384000000>;
qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
qcom,pad-pull-on = <0x0 0x3 0x3 0x1>; /* no-pull, pull-up, pull-up, pull-down */
diff --git a/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi
index e0473b7..c38c9e1 100644
--- a/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-ac-regulator.dtsi
@@ -488,7 +488,7 @@
<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
reg-names = "acs", "mdd";
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1100000>;
+ regulator-max-microvolt = <1120000>;
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
@@ -504,7 +504,7 @@
<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
reg-names = "acs", "mdd";
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1100000>;
+ regulator-max-microvolt = <1120000>;
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
@@ -520,7 +520,7 @@
<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
reg-names = "acs", "mdd";
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1100000>;
+ regulator-max-microvolt = <1120000>;
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
@@ -536,7 +536,7 @@
<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
reg-names = "acs", "mdd";
regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1100000>;
+ regulator-max-microvolt = <1120000>;
qcom,headroom-voltage = <150000>;
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 66d66fc..7c1af1a 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -268,6 +268,7 @@
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB350_CHARGER=y
+CONFIG_SMB349_USB_CHARGER=y
CONFIG_BATTERY_BQ28400=y
CONFIG_QPNP_CHARGER=y
CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index d11634b..f8369a9 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -82,6 +82,7 @@
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
+CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index b03e4cd..816b020 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -83,6 +83,7 @@
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
+CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 6683409..329fcec 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -94,6 +94,7 @@
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
+CONFIG_ENABLE_VMALLOC_SAVING=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
@@ -168,6 +169,7 @@
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 02494b2..812faf6 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -100,6 +100,7 @@
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
CONFIG_COMPACTION=y
+CONFIG_ENABLE_VMALLOC_SAVING=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_CP_ACCESS=y
CONFIG_USE_OF=y
@@ -174,6 +175,7 @@
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
@@ -320,6 +322,7 @@
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
CONFIG_SMB350_CHARGER=y
+CONFIG_SMB349_USB_CHARGER=y
CONFIG_BATTERY_BQ28400=y
CONFIG_QPNP_CHARGER=y
CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 07209d7..3a2cd22 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -30,6 +30,7 @@
#endif
extern unsigned int boot_reason;
+extern unsigned int cold_boot;
struct debug_info {
#ifdef CONFIG_HAVE_HW_BREAKPOINT
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 28b114f..7298f9a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -107,6 +107,9 @@
unsigned int boot_reason;
EXPORT_SYMBOL(boot_reason);
+unsigned int cold_boot;
+EXPORT_SYMBOL(cold_boot);
+
#ifdef MULTI_CPU
struct processor processor __read_mostly;
#endif
diff --git a/arch/arm/mach-msm/acpuclock-8226.c b/arch/arm/mach-msm/acpuclock-8226.c
index 65e22ae..da3cfba 100644
--- a/arch/arm/mach-msm/acpuclock-8226.c
+++ b/arch/arm/mach-msm/acpuclock-8226.c
@@ -49,7 +49,7 @@
[2] = BW_MBPS(400), /* At least 50 MHz on bus. */
[3] = BW_MBPS(800), /* At least 100 MHz on bus. */
[4] = BW_MBPS(1600), /* At least 200 MHz on bus. */
- [5] = BW_MBPS(2128), /* At least 266 MHz on bus. */
+ [5] = BW_MBPS(2664), /* At least 333 MHz on bus. */
};
static struct msm_bus_scale_pdata bus_client_pdata = {
@@ -63,7 +63,7 @@
{ 1, 300000, PLL0, 4, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 384000, ACPUPLL, 5, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 600000, PLL0, 4, 0, CPR_CORNER_NORMAL, 0, 6 },
- { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 7 },
+ { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 6 },
{ 1, 998400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1094400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 0, 1190400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
@@ -74,7 +74,7 @@
{ 1, 300000, PLL0, 4, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 384000, ACPUPLL, 5, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 600000, PLL0, 4, 0, CPR_CORNER_NORMAL, 0, 6 },
- { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 7 },
+ { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 6 },
{ 1, 998400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1094400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1190400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
@@ -85,7 +85,7 @@
{ 1, 300000, PLL0, 4, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 384000, ACPUPLL, 5, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 600000, PLL0, 4, 0, CPR_CORNER_NORMAL, 0, 6 },
- { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 7 },
+ { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 6 },
{ 1, 998400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1094400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1190400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
@@ -99,7 +99,7 @@
{ 1, 300000, PLL0, 4, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 384000, ACPUPLL, 5, 2, CPR_CORNER_SVS, 0, 4 },
{ 1, 600000, PLL0, 4, 0, CPR_CORNER_NORMAL, 0, 6 },
- { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 7 },
+ { 1, 787200, ACPUPLL, 5, 0, CPR_CORNER_NORMAL, 0, 6 },
{ 1, 998400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1094400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
{ 1, 1190400, ACPUPLL, 5, 0, CPR_CORNER_TURBO, 0, 7 },
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 8410019..3e488e3 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -899,7 +899,7 @@
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs0[] __initdata = {
+static struct acpu_level pro_rev0_2p3g_pvs0[] __initdata = {
{ 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
{ 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
{ 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101 },
@@ -930,38 +930,38 @@
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 120},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 139},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 785000, 159},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 795000, 180},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 805000, 200},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 815000, 221},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 825000, 242},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 835000, 264},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 287},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 308},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 333},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 885000, 356},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 895000, 380},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 905000, 404},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 920000, 430},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 935000, 456},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 950000, 482},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 965000, 510},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 980000, 538},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 995000, 565},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 596},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 627},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 659},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 691},
+static struct acpu_level pro_rev0_2p3g_pvs1[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 72 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 83 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 101 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 120 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 139 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 785000, 159 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 795000, 180 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 805000, 200 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 815000, 221 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 825000, 242 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 835000, 264 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 287 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 308 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 333 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 885000, 356 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 895000, 380 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 905000, 404 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 920000, 430 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 935000, 456 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 950000, 482 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 965000, 510 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 980000, 538 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 995000, 565 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 596 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 627 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 659 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 691 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs2[] __initdata = {
+static struct acpu_level pro_rev0_2p3g_pvs2[] __initdata = {
{ 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
{ 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
{ 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101 },
@@ -992,449 +992,1525 @@
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 755000, 159},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 765000, 180},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 200},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 785000, 221},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 795000, 242},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 805000, 264},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 815000, 287},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 825000, 308},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 835000, 333},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 356},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 380},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 404},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 885000, 430},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 456},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 910000, 482},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 925000, 510},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 935000, 538},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 945000, 565},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 596},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 970000, 627},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 985000, 659},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 691},
+static struct acpu_level pro_rev0_2p3g_pvs3[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 755000, 159 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 765000, 180 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 200 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 785000, 221 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 795000, 242 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 805000, 264 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 815000, 287 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 825000, 308 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 835000, 333 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 356 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 380 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 404 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 885000, 430 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 456 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 910000, 482 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 925000, 510 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 935000, 538 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 945000, 565 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 596 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 970000, 627 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 985000, 659 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 691 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 159},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 755000, 180},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 765000, 200},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 221},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 785000, 242},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 795000, 264},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 805000, 287},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 815000, 308},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 825000, 333},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 835000, 356},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 845000, 380},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 855000, 404},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 430},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 456},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 482},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 510},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 538},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 925000, 565},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 935000, 596},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 950000, 627},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 960000, 659},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 975000, 691},
+static struct acpu_level pro_rev0_2p3g_pvs4[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 72 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 83 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 101 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 120 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 139 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 159 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 755000, 180 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 765000, 200 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 221 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 785000, 242 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 795000, 264 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 805000, 287 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 815000, 308 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 825000, 333 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 835000, 356 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 845000, 380 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 855000, 404 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 430 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 456 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 482 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 510 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 538 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 925000, 565 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 935000, 596 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 950000, 627 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 960000, 659 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 975000, 691 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs5[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 72},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 83},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 101},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 120},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 139},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 735000, 159},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 745000, 180},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 755000, 200},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 765000, 221},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 242},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 785000, 264},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 795000, 287},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 805000, 308},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 815000, 333},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 825000, 356},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 835000, 380},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 845000, 404},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 855000, 430},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 865000, 456},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 875000, 482},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 885000, 510},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 895000, 538},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 905000, 565},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 915000, 596},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 930000, 627},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 659},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 950000, 691},
+static struct acpu_level pro_rev0_2p3g_pvs5[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 72 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 83 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 101 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 120 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 139 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 735000, 159 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 745000, 180 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 755000, 200 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 765000, 221 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 242 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 785000, 264 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 795000, 287 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 805000, 308 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 815000, 333 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 825000, 356 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 835000, 380 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 845000, 404 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 855000, 430 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 865000, 456 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 875000, 482 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 885000, 510 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 895000, 538 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 905000, 565 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 915000, 596 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 930000, 627 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 659 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 950000, 691 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p3g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 72},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 83},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 101},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 120},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 139},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 725000, 159},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 735000, 180},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 745000, 200},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 755000, 221},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 765000, 242},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 264},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 785000, 287},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 795000, 308},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 805000, 333},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 815000, 356},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 825000, 380},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 835000, 404},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 845000, 430},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 850000, 456},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 860000, 482},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 870000, 510},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 880000, 538},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 890000, 565},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 895000, 596},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 905000, 627},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 915000, 659},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 925000, 691},
+static struct acpu_level pro_rev0_2p3g_pvs6[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 72 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 83 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 101 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 120 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 139 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 725000, 159 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 735000, 180 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 745000, 200 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 755000, 221 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 765000, 242 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 264 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 785000, 287 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 795000, 308 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 805000, 333 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 815000, 356 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 825000, 380 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 835000, 404 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 845000, 430 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 850000, 456 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 860000, 482 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 870000, 510 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 880000, 538 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 890000, 565 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 895000, 596 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 905000, 627 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 915000, 659 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 925000, 691 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs0[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 805000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 815000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 825000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 835000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 845000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 855000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 885000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 915000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 945000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 960000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 980000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1000000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1020000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1040000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1060000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1080000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1100000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs0[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 805000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 815000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 825000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 835000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 845000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 855000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 885000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 915000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 945000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 960000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 980000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1000000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1020000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1040000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1060000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1080000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1100000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs1[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 805000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 815000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 825000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 835000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 845000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 855000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 900000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 915000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 930000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 945000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 975000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 995000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1015000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1035000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1055000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1075000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs1[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 805000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 815000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 825000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 835000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 845000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 855000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 900000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 915000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 930000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 945000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 975000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 995000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1015000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1035000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1055000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1075000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs2[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 780000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 790000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 800000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 810000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 820000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 830000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 840000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 850000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 865000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 880000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 895000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 910000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 925000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 940000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 955000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 970000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 990000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1010000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1030000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1050000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs2[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 780000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 790000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 800000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 810000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 820000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 830000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 840000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 850000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 865000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 880000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 895000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 910000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 925000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 940000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 955000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 970000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 990000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1010000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1030000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1050000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs3[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 780000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 790000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 800000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 810000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 820000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 830000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 840000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 850000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 865000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 880000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 895000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 910000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 925000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 955000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 970000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 985000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1005000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1025000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs3[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 780000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 790000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 800000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 810000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 820000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 830000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 840000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 850000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 865000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 880000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 895000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 910000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 925000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 955000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 970000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 985000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1005000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1025000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs4[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 760000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 770000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 780000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 790000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 800000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 810000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 820000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 830000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 840000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 850000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 865000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 880000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 895000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 910000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 925000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 955000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 970000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 985000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1000000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs4[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 760000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 770000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 780000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 790000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 800000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 810000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 820000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 830000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 840000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 850000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 865000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 880000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 895000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 910000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 925000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 955000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 970000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 985000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 1000000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs5[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 750000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 760000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 770000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 780000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 790000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 800000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 810000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 820000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 830000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 840000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 850000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 860000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 870000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 885000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 900000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 915000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 930000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 945000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 960000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 975000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs5[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 750000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 760000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 770000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 780000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 790000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 800000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 810000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 820000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 830000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 840000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 850000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 860000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 870000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 885000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 900000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 915000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 930000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 945000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 960000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 975000, 800 },
{ 0, { 0 } }
};
-static struct acpu_level acpu_ftbl_pro_2p5g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 76},
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 87},
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 106},
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 125},
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 145},
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 725000, 164},
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 725000, 183},
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 725000, 202},
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 725000, 222},
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 725000, 241},
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 735000, 261},
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 745000, 282},
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 755000, 305},
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 765000, 327},
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 775000, 350},
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 785000, 373},
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 795000, 398},
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 805000, 424},
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 815000, 449},
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 825000, 476},
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 835000, 503},
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 845000, 530},
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 855000, 559},
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 865000, 590},
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 875000, 621},
- { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 890000, 654},
- { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 905000, 686},
- { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 920000, 723},
- { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 935000, 761},
- { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 950000, 800},
+static struct acpu_level pro_rev0_2p5g_pvs6[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 725000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 725000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 725000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 725000, 125 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 725000, 145 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 725000, 164 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 725000, 183 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 725000, 202 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 725000, 222 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 725000, 241 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 735000, 261 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 745000, 282 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 755000, 305 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 765000, 327 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 775000, 350 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 785000, 373 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 795000, 398 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 805000, 424 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 815000, 449 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 825000, 476 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 835000, 503 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 845000, 530 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 855000, 559 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 865000, 590 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 875000, 621 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 890000, 654 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 905000, 686 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 920000, 723 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 935000, 761 },
+ { 1, { 2496000, HFPLL, 1, 130 }, L2(19), 950000, 800 },
{ 0, { 0 } }
};
-static struct pvs_table pvs_v1[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+static struct acpu_level pro_rev1_2p5g_pvs0[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 810000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 820000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 830000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 840000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 850000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 860000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 870000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 890000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 900000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 920000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 930000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 940000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 950000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 965000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 980000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 995000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1010000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1025000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1040000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1055000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1070000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1085000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1100000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1115000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1120000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs1[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 870000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 880000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 890000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 900000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 920000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 940000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 955000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 970000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 985000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1000000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1015000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1030000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1045000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1060000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1075000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1090000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1105000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1110000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs2[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 870000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 880000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 890000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 900000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 910000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 920000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 930000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 945000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 960000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 975000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 990000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1005000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1020000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1035000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1050000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1065000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1080000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1095000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1100000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs3[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 810000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 820000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 830000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 840000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 850000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 860000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 870000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 880000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 900000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 920000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 935000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 950000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 965000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 980000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 995000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1010000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1025000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1040000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1055000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1070000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1085000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1090000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs4[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 880000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 890000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 900000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 910000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 925000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 940000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 955000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 970000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 985000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1000000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1015000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1030000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1045000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1060000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1075000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1080000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs5[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 870000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 880000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 890000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 900000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 915000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 930000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 945000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 960000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 975000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 990000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1005000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1020000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1035000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1050000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1065000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1070000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs6[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 870000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 890000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 905000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 920000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 935000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 950000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 965000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 980000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 995000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1010000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1025000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1040000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1055000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1060000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs7[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 880000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 895000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 910000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 925000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 940000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 955000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 970000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 985000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1000000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1015000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1030000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1045000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1050000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs8[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 780000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 790000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 810000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 820000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 830000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 840000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 850000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 860000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 870000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 900000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 915000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 930000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 945000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 960000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 975000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 990000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1005000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1020000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1035000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1040000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs9[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 780000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 790000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 800000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 810000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 820000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 830000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 840000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 850000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 860000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 875000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 890000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 920000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 935000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 950000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 965000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 980000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 995000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1010000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1025000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1030000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs10[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 780000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 790000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 800000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 810000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 820000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 830000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 840000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 850000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 865000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 880000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 895000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 910000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 925000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 940000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 955000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 970000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 985000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 1000000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1015000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1020000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs11[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 780000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 790000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 800000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 810000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 820000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 830000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 840000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 855000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 870000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 885000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 900000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 915000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 930000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 945000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 960000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 975000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 990000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 1005000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1010000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs12[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 775000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 780000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 790000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 800000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 810000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 820000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 830000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 845000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 860000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 875000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 890000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 905000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 920000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 935000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 950000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 965000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 980000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 995000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 1000000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs13[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 775000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 775000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 780000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 790000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 800000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 810000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 820000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 835000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 850000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 865000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 880000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 895000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 910000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 925000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 940000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 955000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 970000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 985000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 990000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs14[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 750000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 750000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 760000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 770000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 780000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 790000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 800000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 810000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 825000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 840000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 855000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 870000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 885000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 900000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 915000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 930000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 945000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 960000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 975000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 980000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p5g_pvs15[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 106 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 126 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 147 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 168 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 189 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 211 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 233 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 256 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 750000, 278 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 750000, 301 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 750000, 324 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 760000, 348 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 770000, 372 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 780000, 396 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 790000, 421 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 800000, 446 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 815000, 473 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 830000, 501 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 845000, 529 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 860000, 558 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 875000, 588 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 890000, 617 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 905000, 649 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 920000, 682 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 935000, 716 },
+ { 0, { 2342400, HFPLL, 1, 122 }, L2(19), 950000, 751 },
+ { 0, { 2419200, HFPLL, 1, 126 }, L2(19), 965000, 786 },
+ { 1, { 2457600, HFPLL, 1, 128 }, L2(19), 970000, 802 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs0[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 810000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 820000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 830000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 840000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 850000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 860000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 870000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 880000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 890000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 900000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 910000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 920000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 930000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 940000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 955000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 970000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 985000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 1000000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1015000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1030000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1045000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1060000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1075000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1090000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1105000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1120000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs1[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 810000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 820000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 830000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 840000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 850000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 860000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 870000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 880000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 890000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 900000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 910000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 920000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 930000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 945000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 960000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 975000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 990000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 1005000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1020000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1035000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1050000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1065000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1080000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1095000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1110000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs2[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 810000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 820000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 830000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 840000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 850000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 860000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 870000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 880000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 890000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 900000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 910000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 920000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 935000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 950000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 965000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 980000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 995000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1010000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1025000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1040000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1055000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1070000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1085000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1100000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs3[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 810000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 820000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 830000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 840000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 850000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 860000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 870000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 880000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 890000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 900000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 910000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 925000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 940000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 955000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 970000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 985000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 1000000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1015000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1030000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1045000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1060000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1075000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1090000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs4[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 810000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 820000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 830000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 840000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 850000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 860000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 870000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 880000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 890000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 900000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 915000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 930000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 945000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 960000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 975000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 990000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 1005000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1020000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1035000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1050000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1065000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1080000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs5[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 800000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 800000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 800000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 800000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 800000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 800000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 810000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 820000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 830000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 840000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 850000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 860000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 870000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 880000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 890000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 905000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 920000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 935000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 950000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 965000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 980000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 995000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1010000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1025000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1040000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1055000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1070000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs6[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 780000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 790000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 800000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 810000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 820000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 830000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 840000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 850000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 860000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 870000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 880000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 895000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 910000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 925000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 940000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 955000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 970000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 985000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 1000000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1015000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1030000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1045000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1060000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs7[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 780000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 790000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 800000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 810000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 820000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 830000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 840000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 850000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 860000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 870000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 885000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 900000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 915000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 930000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 945000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 960000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 975000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 990000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 1005000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1020000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1035000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1050000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs8[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 780000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 790000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 800000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 810000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 820000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 830000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 840000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 850000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 860000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 875000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 890000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 905000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 920000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 935000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 950000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 965000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 980000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 995000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1010000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1025000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1040000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs9[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 865000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 880000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 895000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 910000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 925000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 940000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 955000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 970000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 985000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 1000000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1015000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1030000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs10[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 780000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 790000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 800000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 810000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 820000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 830000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 840000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 855000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 885000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 900000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 915000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 930000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 945000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 960000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 975000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 990000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 1005000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1020000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs11[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 780000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 790000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 800000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 810000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 820000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 830000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 845000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 860000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 875000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 890000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 905000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 920000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 935000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 950000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 965000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 980000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 995000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1010000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs12[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 780000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 790000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 800000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 810000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 820000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 835000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 850000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 865000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 880000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 910000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 925000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 940000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 955000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 970000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 985000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 1000000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs13[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 775000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 775000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 775000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 775000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 775000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 775000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 775000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 775000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 775000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 775000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 775000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 780000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 790000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 800000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 810000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 825000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 840000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 855000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 870000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 885000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 900000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 930000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 945000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 960000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 975000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 990000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs14[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 760000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 770000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 780000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 790000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 800000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 815000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 830000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 845000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 860000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 875000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 890000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 905000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 920000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 935000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 950000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 965000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 980000, 738 },
+ { 0, { 0 } }
+};
+
+static struct acpu_level pro_rev1_2p3g_pvs15[] __initdata = {
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 76 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 87 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 108 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 129 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 150 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 750000, 171 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 750000, 193 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 750000, 215 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 750000, 237 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 750000, 260 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 750000, 282 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 760000, 306 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 770000, 330 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 780000, 354 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 790000, 378 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 805000, 404 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 820000, 431 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 835000, 458 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 850000, 486 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 865000, 515 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 880000, 543 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 895000, 572 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 910000, 604 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 925000, 636 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 669 },
+ { 0, { 2188800, HFPLL, 1, 114 }, L2(19), 955000, 703 },
+ { 1, { 2265600, HFPLL, 1, 118 }, L2(19), 970000, 738 },
+ { 0, { 0 } }
+};
+
+static struct pvs_table pvs_v1[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
/* 8974v1 1.7GHz Parts */
- [0][0] = { acpu_freq_tbl_v1_pvs0, sizeof(acpu_freq_tbl_v1_pvs0) },
- [0][1] = { acpu_freq_tbl_v1_pvs1, sizeof(acpu_freq_tbl_v1_pvs1) },
- [0][2] = { acpu_freq_tbl_v1_pvs2, sizeof(acpu_freq_tbl_v1_pvs2) },
- [0][3] = { acpu_freq_tbl_v1_pvs3, sizeof(acpu_freq_tbl_v1_pvs3) },
- [0][4] = { acpu_freq_tbl_v1_pvs4, sizeof(acpu_freq_tbl_v1_pvs4) },
+ [0][0][0] = { acpu_freq_tbl_v1_pvs0, sizeof(acpu_freq_tbl_v1_pvs0) },
+ [0][0][1] = { acpu_freq_tbl_v1_pvs1, sizeof(acpu_freq_tbl_v1_pvs1) },
+ [0][0][2] = { acpu_freq_tbl_v1_pvs2, sizeof(acpu_freq_tbl_v1_pvs2) },
+ [0][0][3] = { acpu_freq_tbl_v1_pvs3, sizeof(acpu_freq_tbl_v1_pvs3) },
+ [0][0][4] = { acpu_freq_tbl_v1_pvs4, sizeof(acpu_freq_tbl_v1_pvs4) },
};
-static struct pvs_table pvs_v2[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+static struct pvs_table pvs_v2[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
/* 8974v2 2.0GHz Parts */
- [0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
- [0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
- [0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
- [0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
- [0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
- [0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
- [0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
- [0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
+ [0][0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
+ [0][0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
+ [0][0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
+ [0][0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
+ [0][0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
+ [0][0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
+ [0][0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
+ [0][0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
/* 8974v2 2.3GHz Parts */
- [1][0] = { acpu_freq_tbl_2p3g_pvs0, sizeof(acpu_freq_tbl_2p3g_pvs0) },
- [1][1] = { acpu_freq_tbl_2p3g_pvs1, sizeof(acpu_freq_tbl_2p3g_pvs1) },
- [1][2] = { acpu_freq_tbl_2p3g_pvs2, sizeof(acpu_freq_tbl_2p3g_pvs2) },
- [1][3] = { acpu_freq_tbl_2p3g_pvs3, sizeof(acpu_freq_tbl_2p3g_pvs3) },
- [1][4] = { acpu_freq_tbl_2p3g_pvs4, sizeof(acpu_freq_tbl_2p3g_pvs4) },
- [1][5] = { acpu_freq_tbl_2p3g_pvs5, sizeof(acpu_freq_tbl_2p3g_pvs5) },
- [1][6] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
- [1][7] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
+ [0][1][0] = { acpu_freq_tbl_2p3g_pvs0, sizeof(acpu_freq_tbl_2p3g_pvs0) },
+ [0][1][1] = { acpu_freq_tbl_2p3g_pvs1, sizeof(acpu_freq_tbl_2p3g_pvs1) },
+ [0][1][2] = { acpu_freq_tbl_2p3g_pvs2, sizeof(acpu_freq_tbl_2p3g_pvs2) },
+ [0][1][3] = { acpu_freq_tbl_2p3g_pvs3, sizeof(acpu_freq_tbl_2p3g_pvs3) },
+ [0][1][4] = { acpu_freq_tbl_2p3g_pvs4, sizeof(acpu_freq_tbl_2p3g_pvs4) },
+ [0][1][5] = { acpu_freq_tbl_2p3g_pvs5, sizeof(acpu_freq_tbl_2p3g_pvs5) },
+ [0][1][6] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
+ [0][1][7] = { acpu_freq_tbl_2p3g_pvs6, sizeof(acpu_freq_tbl_2p3g_pvs6) },
/* 8974v2 2.2GHz Parts */
- [2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
- [2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
- [2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
- [2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
- [2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
- [2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
- [2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
- [2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
+ [0][2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
+ [0][2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
+ [0][2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
+ [0][2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
+ [0][2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
+ [0][2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
+ [0][2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
+ [0][2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
};
-static struct pvs_table pvs_pro[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+static struct pvs_table pvs_pro[NUM_PVS_REVS][NUM_SPEED_BINS][NUM_PVS] __initdata = {
/* 2.0 GHz is not used on 8974Pro */
- [0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
- [0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
- [0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
- [0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
- [0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
- [0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
- [0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
- [0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
+ [0][0][0] = { acpu_freq_tbl_2g_pvs0, sizeof(acpu_freq_tbl_2g_pvs0) },
+ [0][0][1] = { acpu_freq_tbl_2g_pvs1, sizeof(acpu_freq_tbl_2g_pvs1) },
+ [0][0][2] = { acpu_freq_tbl_2g_pvs2, sizeof(acpu_freq_tbl_2g_pvs2) },
+ [0][0][3] = { acpu_freq_tbl_2g_pvs3, sizeof(acpu_freq_tbl_2g_pvs3) },
+ [0][0][4] = { acpu_freq_tbl_2g_pvs4, sizeof(acpu_freq_tbl_2g_pvs4) },
+ [0][0][5] = { acpu_freq_tbl_2g_pvs5, sizeof(acpu_freq_tbl_2g_pvs5) },
+ [0][0][6] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
+ [0][0][7] = { acpu_freq_tbl_2g_pvs6, sizeof(acpu_freq_tbl_2g_pvs6) },
/* 8974Pro AB 2.3GHz */
- [1][0] = { acpu_ftbl_pro_2p3g_pvs0, sizeof(acpu_ftbl_pro_2p3g_pvs0) },
- [1][1] = { acpu_ftbl_pro_2p3g_pvs1, sizeof(acpu_ftbl_pro_2p3g_pvs1) },
- [1][2] = { acpu_ftbl_pro_2p3g_pvs2, sizeof(acpu_ftbl_pro_2p3g_pvs2) },
- [1][3] = { acpu_ftbl_pro_2p3g_pvs3, sizeof(acpu_ftbl_pro_2p3g_pvs3) },
- [1][4] = { acpu_ftbl_pro_2p3g_pvs4, sizeof(acpu_ftbl_pro_2p3g_pvs4) },
- [1][5] = { acpu_ftbl_pro_2p3g_pvs5, sizeof(acpu_ftbl_pro_2p3g_pvs5) },
- [1][6] = { acpu_ftbl_pro_2p3g_pvs6, sizeof(acpu_ftbl_pro_2p3g_pvs6) },
- [1][7] = { acpu_ftbl_pro_2p3g_pvs6, sizeof(acpu_ftbl_pro_2p3g_pvs6) },
+ [0][1][0] = { pro_rev0_2p3g_pvs0, sizeof(pro_rev0_2p3g_pvs0) },
+ [0][1][1] = { pro_rev0_2p3g_pvs1, sizeof(pro_rev0_2p3g_pvs1) },
+ [0][1][2] = { pro_rev0_2p3g_pvs2, sizeof(pro_rev0_2p3g_pvs2) },
+ [0][1][3] = { pro_rev0_2p3g_pvs3, sizeof(pro_rev0_2p3g_pvs3) },
+ [0][1][4] = { pro_rev0_2p3g_pvs4, sizeof(pro_rev0_2p3g_pvs4) },
+ [0][1][5] = { pro_rev0_2p3g_pvs5, sizeof(pro_rev0_2p3g_pvs5) },
+ [0][1][6] = { pro_rev0_2p3g_pvs6, sizeof(pro_rev0_2p3g_pvs6) },
+ [0][1][7] = { pro_rev0_2p3g_pvs6, sizeof(pro_rev0_2p3g_pvs6) },
/* 2.2GHz is not used on 8974Pro */
- [2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
- [2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
- [2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
- [2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
- [2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
- [2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
- [2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
- [2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
+ [0][2][0] = { acpu_freq_tbl_2p2g_pvs0, sizeof(acpu_freq_tbl_2p2g_pvs0) },
+ [0][2][1] = { acpu_freq_tbl_2p2g_pvs1, sizeof(acpu_freq_tbl_2p2g_pvs1) },
+ [0][2][2] = { acpu_freq_tbl_2p2g_pvs2, sizeof(acpu_freq_tbl_2p2g_pvs2) },
+ [0][2][3] = { acpu_freq_tbl_2p2g_pvs3, sizeof(acpu_freq_tbl_2p2g_pvs3) },
+ [0][2][4] = { acpu_freq_tbl_2p2g_pvs4, sizeof(acpu_freq_tbl_2p2g_pvs4) },
+ [0][2][5] = { acpu_freq_tbl_2p2g_pvs5, sizeof(acpu_freq_tbl_2p2g_pvs5) },
+ [0][2][6] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
+ [0][2][7] = { acpu_freq_tbl_2p2g_pvs6, sizeof(acpu_freq_tbl_2p2g_pvs6) },
/* 8974Pro AC 2.5GHz */
- [3][0] = { acpu_ftbl_pro_2p5g_pvs0, sizeof(acpu_ftbl_pro_2p5g_pvs0) },
- [3][1] = { acpu_ftbl_pro_2p5g_pvs1, sizeof(acpu_ftbl_pro_2p5g_pvs1) },
- [3][2] = { acpu_ftbl_pro_2p5g_pvs2, sizeof(acpu_ftbl_pro_2p5g_pvs2) },
- [3][3] = { acpu_ftbl_pro_2p5g_pvs3, sizeof(acpu_ftbl_pro_2p5g_pvs3) },
- [3][4] = { acpu_ftbl_pro_2p5g_pvs4, sizeof(acpu_ftbl_pro_2p5g_pvs4) },
- [3][5] = { acpu_ftbl_pro_2p5g_pvs5, sizeof(acpu_ftbl_pro_2p5g_pvs5) },
- [3][6] = { acpu_ftbl_pro_2p5g_pvs6, sizeof(acpu_ftbl_pro_2p5g_pvs6) },
- [3][7] = { acpu_ftbl_pro_2p5g_pvs6, sizeof(acpu_ftbl_pro_2p5g_pvs6) },
+ [0][3][0] = { pro_rev0_2p5g_pvs0, sizeof(pro_rev0_2p5g_pvs0) },
+ [0][3][1] = { pro_rev0_2p5g_pvs1, sizeof(pro_rev0_2p5g_pvs1) },
+ [0][3][2] = { pro_rev0_2p5g_pvs2, sizeof(pro_rev0_2p5g_pvs2) },
+ [0][3][3] = { pro_rev0_2p5g_pvs3, sizeof(pro_rev0_2p5g_pvs3) },
+ [0][3][4] = { pro_rev0_2p5g_pvs4, sizeof(pro_rev0_2p5g_pvs4) },
+ [0][3][5] = { pro_rev0_2p5g_pvs5, sizeof(pro_rev0_2p5g_pvs5) },
+ [0][3][6] = { pro_rev0_2p5g_pvs6, sizeof(pro_rev0_2p5g_pvs6) },
+ [0][3][7] = { pro_rev0_2p5g_pvs6, sizeof(pro_rev0_2p5g_pvs6) },
+
+ /* 8974Pro AB 2.3GHz */
+ [1][1][0] = { pro_rev1_2p3g_pvs0, sizeof(pro_rev1_2p3g_pvs0) },
+ [1][1][1] = { pro_rev1_2p3g_pvs1, sizeof(pro_rev1_2p3g_pvs1) },
+ [1][1][2] = { pro_rev1_2p3g_pvs2, sizeof(pro_rev1_2p3g_pvs2) },
+ [1][1][3] = { pro_rev1_2p3g_pvs3, sizeof(pro_rev1_2p3g_pvs3) },
+ [1][1][4] = { pro_rev1_2p3g_pvs4, sizeof(pro_rev1_2p3g_pvs4) },
+ [1][1][5] = { pro_rev1_2p3g_pvs5, sizeof(pro_rev1_2p3g_pvs5) },
+ [1][1][6] = { pro_rev1_2p3g_pvs6, sizeof(pro_rev1_2p3g_pvs6) },
+ [1][1][7] = { pro_rev1_2p3g_pvs7, sizeof(pro_rev1_2p3g_pvs7) },
+ [1][1][8] = { pro_rev1_2p3g_pvs8, sizeof(pro_rev1_2p3g_pvs8) },
+ [1][1][9] = { pro_rev1_2p3g_pvs9, sizeof(pro_rev1_2p3g_pvs9) },
+ [1][1][10] = { pro_rev1_2p3g_pvs10, sizeof(pro_rev1_2p3g_pvs10) },
+ [1][1][11] = { pro_rev1_2p3g_pvs11, sizeof(pro_rev1_2p3g_pvs11) },
+ [1][1][12] = { pro_rev1_2p3g_pvs12, sizeof(pro_rev1_2p3g_pvs12) },
+ [1][1][13] = { pro_rev1_2p3g_pvs13, sizeof(pro_rev1_2p3g_pvs13) },
+ [1][1][14] = { pro_rev1_2p3g_pvs14, sizeof(pro_rev1_2p3g_pvs14) },
+ [1][1][15] = { pro_rev1_2p3g_pvs15, sizeof(pro_rev1_2p3g_pvs15) },
+
+ /* 8974Pro AC 2.5GHz */
+ [1][3][0] = { pro_rev1_2p5g_pvs0, sizeof(pro_rev1_2p5g_pvs0) },
+ [1][3][1] = { pro_rev1_2p5g_pvs1, sizeof(pro_rev1_2p5g_pvs1) },
+ [1][3][2] = { pro_rev1_2p5g_pvs2, sizeof(pro_rev1_2p5g_pvs2) },
+ [1][3][3] = { pro_rev1_2p5g_pvs3, sizeof(pro_rev1_2p5g_pvs3) },
+ [1][3][4] = { pro_rev1_2p5g_pvs4, sizeof(pro_rev1_2p5g_pvs4) },
+ [1][3][5] = { pro_rev1_2p5g_pvs5, sizeof(pro_rev1_2p5g_pvs5) },
+ [1][3][6] = { pro_rev1_2p5g_pvs6, sizeof(pro_rev1_2p5g_pvs6) },
+ [1][3][7] = { pro_rev1_2p5g_pvs7, sizeof(pro_rev1_2p5g_pvs7) },
+ [1][3][8] = { pro_rev1_2p5g_pvs8, sizeof(pro_rev1_2p5g_pvs8) },
+ [1][3][9] = { pro_rev1_2p5g_pvs9, sizeof(pro_rev1_2p5g_pvs9) },
+ [1][3][10] = { pro_rev1_2p5g_pvs10, sizeof(pro_rev1_2p5g_pvs10) },
+ [1][3][11] = { pro_rev1_2p5g_pvs11, sizeof(pro_rev1_2p5g_pvs11) },
+ [1][3][12] = { pro_rev1_2p5g_pvs12, sizeof(pro_rev1_2p5g_pvs12) },
+ [1][3][13] = { pro_rev1_2p5g_pvs13, sizeof(pro_rev1_2p5g_pvs13) },
+ [1][3][14] = { pro_rev1_2p5g_pvs14, sizeof(pro_rev1_2p5g_pvs14) },
+ [1][3][15] = { pro_rev1_2p5g_pvs15, sizeof(pro_rev1_2p5g_pvs15) },
};
static struct msm_bus_scale_pdata bus_scale_data __initdata = {
@@ -1470,12 +2546,15 @@
{ }
};
struct acpu_level *l;
- int s, p;
+ int s, p, r;
- for (s = 0; s < NUM_SPEED_BINS; s++)
- for (p = 0; p < NUM_PVS; p++)
- for (l = pvs_v1[s][p].table; l && l->speed.khz; l++)
- l->l2_level = l->l2_level > 5 ? 1 : 0;
+ for (r = 0; r < NUM_PVS_REVS; r++)
+ for (s = 0; s < NUM_SPEED_BINS; s++)
+ for (p = 0; p < NUM_PVS; p++) {
+ l = pvs_v1[r][s][p].table;
+ for (; l && l->speed.khz; l++)
+ l->l2_level = l->l2_level > 5 ? 1 : 0;
+ }
acpuclk_8974_params.l2_freq_tbl = resticted_l2_tbl;
acpuclk_8974_params.l2_freq_tbl_size = sizeof(resticted_l2_tbl);
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 0479844..cf3fac0 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -1092,15 +1092,17 @@
pte_efuse = readl_relaxed(base);
redundant_sel = (pte_efuse >> 24) & 0x7;
+ bin->pvs_rev = (pte_efuse >> 4) & 0x3;
bin->speed = pte_efuse & 0x7;
- bin->pvs = (pte_efuse >> 6) & 0x7;
+ /* PVS number is in bits 31, 8, 7, 6 */
+ bin->pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7);
switch (redundant_sel) {
case 1:
- bin->speed = (pte_efuse >> 27) & 0x7;
+ bin->speed = (pte_efuse >> 27) & 0xF;
break;
case 2:
- bin->pvs = (pte_efuse >> 27) & 0x7;
+ bin->pvs = (pte_efuse >> 27) & 0xF;
break;
}
bin->speed_valid = true;
@@ -1136,13 +1138,15 @@
if (bin.pvs_valid) {
drv.pvs_bin = bin.pvs;
dev_info(drv.dev, "ACPU PVS: %d\n", drv.pvs_bin);
+ drv.pvs_rev = bin.pvs_rev;
+ dev_info(drv.dev, "ACPU PVS REVISION: %d\n", drv.pvs_rev);
} else {
drv.pvs_bin = 0;
dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n",
drv.pvs_bin);
}
- return ¶ms->pvs_tables[drv.speed_bin][drv.pvs_bin];
+ return ¶ms->pvs_tables[drv.pvs_rev][drv.speed_bin][drv.pvs_bin];
}
static void __init drv_data_init(struct device *dev,
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index f02af98..4eff45d 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -50,10 +50,15 @@
PVS_NOMINAL = 1,
PVS_FAST = 3,
PVS_FASTER = 4,
- NUM_PVS = 8
+ NUM_PVS = 16
};
/**
+ * The maximum number of PVS revisions.
+ */
+#define NUM_PVS_REVS (4)
+
+/**
* The maximum number of speed bins.
*/
#define NUM_SPEED_BINS (16)
@@ -236,12 +241,14 @@
* @pvs_valid: @pvs field is valid
* @speed: Speed bin ID
* @pvs: PVS bin ID
+ * @pvs_rev: PVS revision ID
*/
struct bin_info {
bool speed_valid;
bool pvs_valid;
int speed;
int pvs;
+ int pvs_rev;
};
/**
@@ -273,7 +280,7 @@
struct scalable *scalable;
size_t scalable_size;
struct hfpll_data *hfpll_data;
- struct pvs_table (*pvs_tables)[NUM_PVS];
+ struct pvs_table (*pvs_tables)[NUM_SPEED_BINS][NUM_PVS];
struct l2_level *l2_freq_tbl;
size_t l2_freq_tbl_size;
phys_addr_t pte_efuse_phys;
@@ -293,6 +300,7 @@
* @boost_uv: Voltage boost amount
* @speed_bin: Speed bin ID.
* @pvs_bin: PVS bin ID.
+ * @pvs_bin: PVS revision ID.
* @dev: Device.
*/
struct drv_data {
@@ -305,6 +313,7 @@
int boost_uv;
int speed_bin;
int pvs_bin;
+ int pvs_rev;
struct device *dev;
};
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index e9ad86f..87794c4 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -23,6 +23,11 @@
.drv = GPIOMUX_DRV_6MA,
.pull = GPIOMUX_PULL_NONE,
};
+static struct gpiomux_setting gpio_spi_susp_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
static struct gpiomux_setting gpio_i2c_config = {
.func = GPIOMUX_FUNC_3,
@@ -247,25 +252,29 @@
{
.gpio = 86, /* BLSP1 QUP4 SPI_DATA_MOSI */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 87, /* BLSP1 QUP4 SPI_DATA_MISO */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 89, /* BLSP1 QUP4 SPI_CLK */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 88, /* BLSP1 QUP4 SPI_CS */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
};
@@ -288,25 +297,29 @@
{
.gpio = 86, /* BLSP1 QUP4 SPI_DATA_MOSI */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 87, /* BLSP1 QUP4 SPI_DATA_MISO */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 89, /* BLSP1 QUP4 SPI_CLK */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 88, /* BLSP1 QUP4 SPI_CS */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
};
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 31bcced..c35a607 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -143,6 +143,11 @@
.drv = GPIOMUX_DRV_12MA,
.pull = GPIOMUX_PULL_NONE,
};
+static struct gpiomux_setting gpio_spi_susp_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
static struct gpiomux_setting gpio_spi_cs1_config = {
.func = GPIOMUX_FUNC_GPIO,
@@ -564,31 +569,36 @@
{
.gpio = 0, /* BLSP1 QUP SPI_DATA_MOSI */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 1, /* BLSP1 QUP SPI_DATA_MISO */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 3, /* BLSP1 QUP SPI_CLK */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 9, /* BLSP1 QUP SPI_CS2A_N */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_cs2_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
{
.gpio = 8, /* BLSP1 QUP SPI_CS1_N */
.settings = {
- [GPIOMUX_SUSPENDED] = &gpio_spi_cs1_config,
+ [GPIOMUX_ACTIVE] = &gpio_spi_cs1_config,
+ [GPIOMUX_SUSPENDED] = &gpio_spi_susp_config,
},
},
#endif
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 654dbd3..0e3310c 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -777,7 +777,7 @@
.base = &virt_bases[GCC_BASE],
.c = {
.parent = &cxo_clk_src.c,
- .rate = 800000000,
+ .rate = 768000000,
.dbg_name = "gpll4_clk_src",
.ops = &clk_ops_pll_vote,
CLK_INIT(gpll4_clk_src.c),
@@ -1553,7 +1553,7 @@
F( 50000000, gpll0, 12, 0, 0),
F(100000000, gpll0, 6, 0, 0),
F(200000000, gpll0, 3, 0, 0),
- F(400000000, gpll4, 2, 0, 0),
+ F(384000000, gpll4, 2, 0, 0),
F_END
};
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 3bb4c57..cf2df18 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -1398,7 +1398,8 @@
{
int rc = 0;
- if (vco_cached_rate != 0) {
+ if ((vco_cached_rate != 0)
+ && (vco_cached_rate == c->rate)) {
rc = vco_set_rate(c, vco_cached_rate);
if (rc) {
pr_err("%s: vco_set_rate failed. rc=%d\n",
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 59e0e2a..6ddf340 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -1274,10 +1274,6 @@
quot[CPR_CORNER_NORMAL])
<= CPR_FUSE_MIN_QUOT_DIFF)
valid_fuse = false;
- else if ((quot[CPR_CORNER_NORMAL] -
- quot[CPR_CORNER_SVS])
- <= CPR_FUSE_MIN_QUOT_DIFF)
- valid_fuse = false;
} else {
valid_fuse = false;
}
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
index 5556db9..19f9c0e 100644
--- a/arch/arm/mach-msm/include/mach/msm_smem.h
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -26,6 +26,18 @@
NUM_SMEM_SUBSYSTEMS,
};
+/*
+ * Flag options for the XXX_to_proc() API
+ *
+ * SMEM_ITEM_CACHED_FLAG - Indicates this operation should use cachable smem
+ *
+ * SMEM_ANY_HOST_FLAG - Indicates this operation should not apply to smem items
+ * which are limited to a specific host pairing. Will
+ * cause this operation to ignore the to_proc parameter.
+ */
+#define SMEM_ITEM_CACHED_FLAG 1
+#define SMEM_ANY_HOST_FLAG 2
+
#define SMEM_NUM_SMD_STREAM_CHANNELS 64
enum {
@@ -145,6 +157,15 @@
void *smem_get_entry(unsigned id, unsigned *size);
void *smem_find(unsigned id, unsigned size);
+void *smem_alloc2_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags);
+void *smem_alloc_to_proc(unsigned id, unsigned size, unsigned to_proc,
+ unsigned flags);
+void *smem_find_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags);
+void *smem_get_entry_to_proc(unsigned id, unsigned *size, unsigned to_proc,
+ unsigned flags);
+
/**
* smem_get_entry_no_rlock - Get existing item without using remote spinlock
*
@@ -193,6 +214,26 @@
{
return NULL;
}
+void *smem_alloc2_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags)
+{
+ return NULL;
+}
+static void *smem_alloc_to_proc(unsigned id, unsigned size, unsigned to_proc,
+ unsigned flags)
+{
+ return NULL;
+}
+static void *smem_find_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags)
+{
+ return NULL;
+}
+static void *smem_get_entry_to_proc(unsigned id, unsigned *size,
+ unsigned to_proc, unsigned flags)
+{
+ return NULL;
+}
void *smem_get_entry_no_rlock(unsigned id, unsigned *size_out)
{
return NULL;
diff --git a/arch/arm/mach-msm/msm_qmi_interface.c b/arch/arm/mach-msm/msm_qmi_interface.c
index a8fed52..e2ff0f4 100644
--- a/arch/arm/mach-msm/msm_qmi_interface.c
+++ b/arch/arm/mach-msm/msm_qmi_interface.c
@@ -160,6 +160,10 @@
msg_id = ((struct qmi_header *)pend_txn->enc_data)->msg_id;
kfree(pend_txn->enc_data);
if (ret < 0) {
+ pr_err("%s: Sending transaction %d from port %d failed",
+ __func__, pend_txn->txn_id,
+ ((struct msm_ipc_port *)handle->src_port)->
+ this_port.port_id);
if (pend_txn->type == QMI_ASYNC_TXN) {
pend_txn->resp_cb(pend_txn->handle,
msg_id, pend_txn->resp,
@@ -171,10 +175,6 @@
pend_txn->send_stat = ret;
wake_up(&pend_txn->wait_q);
}
- pr_err("%s: Sending transaction %d from port %d failed",
- __func__, pend_txn->txn_id,
- ((struct msm_ipc_port *)handle->src_port)->
- this_port.port_id);
} else {
list_del(&pend_txn->list);
list_add_tail(&pend_txn->list, &handle->txn_list);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index b5ccc31..a13100b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -887,7 +887,7 @@
static int acdb_mmap(struct file *file, struct vm_area_struct *vma)
{
int result = 0;
- int size = vma->vm_end - vma->vm_start;
+ uint32_t size = vma->vm_end - vma->vm_start;
pr_debug("%s\n", __func__);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index d34bdf2..110ab87 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -57,7 +57,7 @@
#define SMD_VERSION 0x00020000
#define SMSM_SNAPSHOT_CNT 64
-#define SMSM_SNAPSHOT_SIZE ((SMSM_NUM_ENTRIES + 1) * 4)
+#define SMSM_SNAPSHOT_SIZE ((SMSM_NUM_ENTRIES + 1) * 4 + sizeof(uint64_t))
#define RSPIN_INIT_WAIT_MS 1000
#define SMD_FIFO_FULL_RESERVE 4
@@ -144,49 +144,65 @@
SMSM_APPS_DEM_I = 3,
};
-int msm_smd_debug_mask = MSM_SMx_POWER_INFO | MSM_SMD_INFO;
+int msm_smd_debug_mask = MSM_SMD_POWER_INFO | MSM_SMD_INFO |
+ MSM_SMSM_POWER_INFO;
module_param_named(debug_mask, msm_smd_debug_mask,
int, S_IRUGO | S_IWUSR | S_IWGRP);
void *smd_log_ctx;
+void *smsm_log_ctx;
#define NUM_LOG_PAGES 4
-#define IPC_LOG(level, x...) do { \
+#define IPC_LOG_SMD(level, x...) do { \
if (smd_log_ctx) \
ipc_log_string(smd_log_ctx, x); \
else \
printk(level x); \
} while (0)
+#define IPC_LOG_SMSM(level, x...) do { \
+ if (smsm_log_ctx) \
+ ipc_log_string(smsm_log_ctx, x); \
+ else \
+ printk(level x); \
+ } while (0)
+
#if defined(CONFIG_MSM_SMD_DEBUG)
#define SMD_DBG(x...) do { \
if (msm_smd_debug_mask & MSM_SMD_DEBUG) \
- IPC_LOG(KERN_DEBUG, x); \
+ IPC_LOG_SMD(KERN_DEBUG, x); \
} while (0)
#define SMSM_DBG(x...) do { \
if (msm_smd_debug_mask & MSM_SMSM_DEBUG) \
- IPC_LOG(KERN_DEBUG, x); \
+ IPC_LOG_SMSM(KERN_DEBUG, x); \
} while (0)
#define SMD_INFO(x...) do { \
if (msm_smd_debug_mask & MSM_SMD_INFO) \
- IPC_LOG(KERN_INFO, x); \
+ IPC_LOG_SMD(KERN_INFO, x); \
} while (0)
#define SMSM_INFO(x...) do { \
if (msm_smd_debug_mask & MSM_SMSM_INFO) \
- IPC_LOG(KERN_INFO, x); \
+ IPC_LOG_SMSM(KERN_INFO, x); \
} while (0)
-#define SMx_POWER_INFO(x...) do { \
- if (msm_smd_debug_mask & MSM_SMx_POWER_INFO) \
- IPC_LOG(KERN_INFO, x); \
+
+#define SMD_POWER_INFO(x...) do { \
+ if (msm_smd_debug_mask & MSM_SMD_POWER_INFO) \
+ IPC_LOG_SMD(KERN_INFO, x); \
+ } while (0)
+
+#define SMSM_POWER_INFO(x...) do { \
+ if (msm_smd_debug_mask & MSM_SMSM_POWER_INFO) \
+ IPC_LOG_SMSM(KERN_INFO, x); \
} while (0)
#else
#define SMD_DBG(x...) do { } while (0)
#define SMSM_DBG(x...) do { } while (0)
#define SMD_INFO(x...) do { } while (0)
#define SMSM_INFO(x...) do { } while (0)
-#define SMx_POWER_INFO(x...) do { } while (0)
+#define SMD_POWER_INFO(x...) do { } while (0)
+#define SMSM_POWER_INFO(x...) do { } while (0)
#endif
/**
@@ -200,8 +216,6 @@
#define OVERFLOW_ADD_UNSIGNED(type, a, b) \
(((type)~0 - (a)) < (b) ? true : false)
-static unsigned last_heap_free = 0xffffffff;
-
static inline void smd_write_intr(unsigned int val,
const void __iomem *addr);
#ifndef INT_ADSP_A11_SMSM
@@ -223,6 +237,8 @@
static int smd_stream_write_avail(struct smd_channel *ch);
static int smd_stream_read_avail(struct smd_channel *ch);
+static bool pid_is_on_edge(uint32_t edge_num, unsigned pid);
+
static inline void smd_write_intr(unsigned int val,
const void __iomem *addr)
{
@@ -237,9 +253,9 @@
(void) subsys;
if (!ch)
- SMx_POWER_INFO("Apps->%s\n", subsys);
+ SMD_POWER_INFO("Apps->%s\n", subsys);
else
- SMx_POWER_INFO(
+ SMD_POWER_INFO(
"Apps->%s ch%d '%s': tx%d/rx%d %dr/%dw : %dr/%dw\n",
subsys, ch->n, ch->name,
ch->fifo_size -
@@ -322,7 +338,7 @@
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_MODEM].smsm;
- SMx_POWER_INFO("SMSM Apps->%s", "MODEM");
+ SMSM_POWER_INFO("SMSM Apps->%s", "MODEM");
if (intr->out_base) {
++interrupt_stats[SMD_MODEM].smsm_out_config_count;
@@ -336,7 +352,7 @@
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_Q6].smsm;
- SMx_POWER_INFO("SMSM Apps->%s", "ADSP");
+ SMSM_POWER_INFO("SMSM Apps->%s", "ADSP");
if (intr->out_base) {
++interrupt_stats[SMD_Q6].smsm_out_config_count;
@@ -350,7 +366,7 @@
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_DSPS].smsm;
- SMx_POWER_INFO("SMSM Apps->%s", "DSPS");
+ SMSM_POWER_INFO("SMSM Apps->%s", "DSPS");
if (intr->out_base) {
++interrupt_stats[SMD_DSPS].smsm_out_config_count;
@@ -364,7 +380,7 @@
static const struct interrupt_config_item *intr
= &private_intr_config[SMD_WCNSS].smsm;
- SMx_POWER_INFO("SMSM Apps->%s", "WCNSS");
+ SMSM_POWER_INFO("SMSM Apps->%s", "WCNSS");
if (intr->out_base) {
++interrupt_stats[SMD_WCNSS].smsm_out_config_count;
@@ -447,13 +463,15 @@
char *x;
int size;
- x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+ x = smem_find_to_proc(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG, 0,
+ SMEM_ANY_HOST_FLAG);
if (x != 0) {
x[SZ_DIAG_ERR_MSG - 1] = 0;
SMD_INFO("smem: DIAG '%s'\n", x);
}
- x = smem_get_entry(SMEM_ERR_CRASH_LOG, &size);
+ x = smem_get_entry_to_proc(SMEM_ERR_CRASH_LOG, &size, 0,
+ SMEM_ANY_HOST_FLAG);
if (x != 0) {
x[size - 1] = 0;
pr_err("smem: CRASH LOG\n'%s'\n", x);
@@ -560,15 +578,17 @@
static LIST_HEAD(smd_ch_closed_list);
static LIST_HEAD(smd_ch_closing_list);
static LIST_HEAD(smd_ch_to_close_list);
-static LIST_HEAD(smd_ch_list_modem);
-static LIST_HEAD(smd_ch_list_dsp);
-static LIST_HEAD(smd_ch_list_dsps);
-static LIST_HEAD(smd_ch_list_wcnss);
-static LIST_HEAD(smd_ch_list_rpm);
-/* 2 total supported tables of channels */
-static unsigned char smd_ch_allocated[SMEM_NUM_SMD_STREAM_CHANNELS * 2];
-static struct work_struct probe_work;
+struct remote_proc_info {
+ unsigned remote_pid;
+ unsigned free_space;
+ struct work_struct probe_work;
+ struct list_head ch_list;
+ /* 2 total supported tables of channels */
+ unsigned char ch_allocated[SMEM_NUM_SMD_STREAM_CHANNELS * 2];
+};
+
+static struct remote_proc_info remote_info[NUM_SMD_SUBSYSTEMS];
static void finalize_channel_close_fn(struct work_struct *work);
static DECLARE_WORK(finalize_channel_close_work, finalize_channel_close_fn);
@@ -576,7 +596,8 @@
#define PRI_ALLOC_TBL 1
#define SEC_ALLOC_TBL 2
-static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id);
+static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id,
+ struct remote_proc_info *r_info);
static bool smd_edge_inited(int edge)
{
@@ -594,19 +615,23 @@
*
* @shared: pointer to the table array in SMEM
* @smd_ch_allocated: pointer to an array indicating already allocated channels
- * table_id: identifier for this channel allocation table
+ * @table_id: identifier for this channel allocation table
+ * @num_entries: number of entries in this allocation table
+ * @r_info: pointer to the info structure of the remote proc we care about
*
* The smd_probe_lock must be locked by the calling function. Shared and
* smd_ch_allocated are assumed to be valid pointers.
*/
static void scan_alloc_table(struct smd_alloc_elm *shared,
char *smd_ch_allocated,
- int table_id)
+ int table_id,
+ unsigned num_entries,
+ struct remote_proc_info *r_info)
{
unsigned n;
uint32_t type;
- for (n = 0; n < SMEM_NUM_SMD_STREAM_CHANNELS; n++) {
+ for (n = 0; n < num_entries; n++) {
if (smd_ch_allocated[n])
continue;
@@ -615,8 +640,8 @@
* involved
*/
type = SMD_CHANNEL_TYPE(shared[n].type);
- if (type >= ARRAY_SIZE(edge_to_pids) ||
- edge_to_pids[type].local_pid != SMD_APPS)
+ if (!pid_is_on_edge(type, SMD_APPS) ||
+ !pid_is_on_edge(type, r_info->remote_pid))
continue;
if (!shared[n].ref_count)
continue;
@@ -625,17 +650,17 @@
if (!smd_initialized && !smd_edge_inited(type)) {
SMD_INFO(
- "Probe skipping tbl %d, ch %d, edge not inited\n",
- table_id, n);
+ "Probe skipping proc %d, tbl %d, ch %d, edge not inited\n",
+ r_info->remote_pid, table_id, n);
continue;
}
- if (!smd_alloc_channel(&shared[n], table_id))
+ if (!smd_alloc_channel(&shared[n], table_id, r_info))
smd_ch_allocated[n] = 1;
else
SMD_INFO(
- "Probe skipping tbl %d, ch %d, not allocated\n",
- table_id, n);
+ "Probe skipping proc %d, tbl %d, ch %d, not allocated\n",
+ r_info->remote_pid, table_id, n);
}
}
@@ -650,9 +675,13 @@
static void smd_channel_probe_worker(struct work_struct *work)
{
struct smd_alloc_elm *shared;
+ struct remote_proc_info *r_info;
+ unsigned tbl_size;
- shared = smem_find(ID_CH_ALLOC_TBL,
- sizeof(*shared) * SMEM_NUM_SMD_STREAM_CHANNELS);
+ r_info = container_of(work, struct remote_proc_info, probe_work);
+
+ shared = smem_get_entry_to_proc(ID_CH_ALLOC_TBL, &tbl_size,
+ r_info->remote_pid, 0);
if (!shared) {
pr_err("%s: allocation table not initialized\n", __func__);
@@ -661,71 +690,50 @@
mutex_lock(&smd_probe_lock);
- scan_alloc_table(shared, smd_ch_allocated, PRI_ALLOC_TBL);
+ scan_alloc_table(shared, r_info->ch_allocated, PRI_ALLOC_TBL,
+ tbl_size / sizeof(*shared),
+ r_info);
- shared = smem_find(SMEM_CHANNEL_ALLOC_TBL_2,
- sizeof(*shared) * SMEM_NUM_SMD_STREAM_CHANNELS);
+ shared = smem_get_entry_to_proc(SMEM_CHANNEL_ALLOC_TBL_2, &tbl_size,
+ r_info->remote_pid, 0);
if (shared)
scan_alloc_table(shared,
- &(smd_ch_allocated[SMEM_NUM_SMD_STREAM_CHANNELS]),
- SEC_ALLOC_TBL);
+ &(r_info->ch_allocated[SMEM_NUM_SMD_STREAM_CHANNELS]),
+ SEC_ALLOC_TBL,
+ tbl_size / sizeof(*shared),
+ r_info);
mutex_unlock(&smd_probe_lock);
}
/**
- * Lookup processor ID and determine if it belongs to the proved edge
- * type.
+ * get_remote_ch() - gathers remote channel info
*
* @shared2: Pointer to v2 shared channel structure
* @type: Edge type
* @pid: Processor ID of processor on edge
- * @local_ch: Channel that belongs to processor @pid
- * @remote_ch: Other side of edge contained @pid
+ * @remote_ch: Channel that belongs to processor @pid
* @is_word_access_ch: Bool, is this a word aligned access channel
*
- * Returns 0 for not on edge, 1 for found on edge
+ * @returns: 0 on success, error code on failure
*/
-static int pid_is_on_edge(void *shared2,
+static int get_remote_ch(void *shared2,
uint32_t type, uint32_t pid,
- void **local_ch,
void **remote_ch,
int is_word_access_ch
)
{
- int ret = 0;
- struct edge_to_pid *edge;
- void *ch0;
- void *ch1;
+ if (!remote_ch || !shared2 || !pid_is_on_edge(type, pid) ||
+ !pid_is_on_edge(type, SMD_APPS))
+ return -EINVAL;
- *local_ch = 0;
- *remote_ch = 0;
+ if (is_word_access_ch)
+ *remote_ch =
+ &((struct smd_shared_v2_word_access *)(shared2))->ch1;
+ else
+ *remote_ch = &((struct smd_shared_v2 *)(shared2))->ch1;
- if (!shared2 || (type >= ARRAY_SIZE(edge_to_pids)))
- return 0;
-
- if (is_word_access_ch) {
- ch0 = &((struct smd_shared_v2_word_access *)(shared2))->ch0;
- ch1 = &((struct smd_shared_v2_word_access *)(shared2))->ch1;
- } else {
- ch0 = &((struct smd_shared_v2 *)(shared2))->ch0;
- ch1 = &((struct smd_shared_v2 *)(shared2))->ch1;
- }
-
- edge = &edge_to_pids[type];
- if (edge->local_pid != edge->remote_pid) {
- if (pid == edge->local_pid) {
- *local_ch = ch0;
- *remote_ch = ch1;
- ret = 1;
- } else if (pid == edge->remote_pid) {
- *local_ch = ch1;
- *remote_ch = ch0;
- ret = 1;
- }
- }
-
- return ret;
+ return 0;
}
/**
@@ -825,13 +833,25 @@
}
}
+/**
+ * smd_channel_reset_state() - find channels in an allocation table and set them
+ * to the specified state
+ *
+ * @shared: Pointer to the allocation table to scan
+ * @table_id: ID of the table
+ * @new_state: New state that channels should be set to
+ * @pid: Processor ID of the remote processor for the channels
+ * @num_entries: Number of entries in the table
+ *
+ * Scan the indicated table for channels between Apps and @pid. If a valid
+ * channel is found, set the remote side of the channel to @new_state.
+ */
static void smd_channel_reset_state(struct smd_alloc_elm *shared, int table_id,
- unsigned new_state, unsigned pid)
+ unsigned new_state, unsigned pid, unsigned num_entries)
{
unsigned n;
void *shared2;
uint32_t type;
- void *local_ch;
void *remote_ch;
int is_word_access;
unsigned base_id;
@@ -848,7 +868,7 @@
return;
}
- for (n = 0; n < SMD_CHANNELS; n++) {
+ for (n = 0; n < num_entries; n++) {
if (!shared[n].ref_count)
continue;
if (!shared[n].name[0])
@@ -857,45 +877,59 @@
type = SMD_CHANNEL_TYPE(shared[n].type);
is_word_access = is_word_access_ch(type);
if (is_word_access)
- shared2 = smem_alloc(base_id + n,
- sizeof(struct smd_shared_v2_word_access));
+ shared2 = smem_find_to_proc(base_id + n,
+ sizeof(struct smd_shared_v2_word_access), pid,
+ 0);
else
- shared2 = smem_alloc(base_id + n,
- sizeof(struct smd_shared_v2));
+ shared2 = smem_find_to_proc(base_id + n,
+ sizeof(struct smd_shared_v2), pid, 0);
if (!shared2)
continue;
- if (pid_is_on_edge(shared2, type, pid, &local_ch, &remote_ch,
- is_word_access))
- smd_reset_edge(local_ch, new_state, is_word_access);
-
- /*
- * ModemFW is in the same subsystem as ModemSW, but has
- * separate SMD edges that need to be reset.
- */
- if (pid == SMSM_MODEM &&
- pid_is_on_edge(shared2, type, SMD_MODEM_Q6_FW,
- &local_ch, &remote_ch, is_word_access))
- smd_reset_edge(local_ch, new_state, is_word_access);
+ if (!get_remote_ch(shared2, type, pid,
+ &remote_ch, is_word_access))
+ smd_reset_edge(remote_ch, new_state, is_word_access);
}
}
+/**
+ * pid_is_on_edge() - checks to see if the processor with id pid is on the
+ * edge specified by edge_num
+ *
+ * @edge_num: the number of the edge which is being tested
+ * @pid: the id of the processor being tested
+ *
+ * @returns: true if on edge, false otherwise
+ */
+static bool pid_is_on_edge(uint32_t edge_num, unsigned pid)
+{
+ struct edge_to_pid edge;
+
+ if (edge_num >= ARRAY_SIZE(edge_to_pids))
+ return 0;
+
+ edge = edge_to_pids[edge_num];
+ return (edge.local_pid == pid || edge.remote_pid == pid);
+}
void smd_channel_reset(uint32_t restart_pid)
{
struct smd_alloc_elm *shared_pri;
struct smd_alloc_elm *shared_sec;
unsigned long flags;
+ unsigned pri_size;
+ unsigned sec_size;
- SMx_POWER_INFO("%s: starting reset\n", __func__);
+ SMD_POWER_INFO("%s: starting reset\n", __func__);
- shared_pri = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared_pri) * 64);
+ shared_pri = smem_get_entry_to_proc(ID_CH_ALLOC_TBL, &pri_size,
+ restart_pid, 0);
if (!shared_pri) {
pr_err("%s: allocation table not initialized\n", __func__);
return;
}
- shared_sec = smem_find(SMEM_CHANNEL_ALLOC_TBL_2,
- sizeof(*shared_sec) * 64);
+ shared_sec = smem_get_entry_to_proc(SMEM_CHANNEL_ALLOC_TBL_2, &sec_size,
+ restart_pid, 0);
/* reset SMSM entry */
if (smsm_info.state) {
@@ -920,43 +954,33 @@
mutex_lock(&smd_probe_lock);
spin_lock_irqsave(&smd_lock, flags);
smd_channel_reset_state(shared_pri, PRI_ALLOC_TBL, SMD_SS_CLOSING,
- restart_pid);
+ restart_pid, pri_size / sizeof(*shared_pri));
if (shared_sec)
smd_channel_reset_state(shared_sec, SEC_ALLOC_TBL,
- SMD_SS_CLOSING, restart_pid);
+ SMD_SS_CLOSING, restart_pid,
+ sec_size / sizeof(*shared_sec));
spin_unlock_irqrestore(&smd_lock, flags);
mutex_unlock(&smd_probe_lock);
- /* notify SMD processors */
mb();
smd_fake_irq_handler(0);
- notify_modem_smd(NULL);
- notify_dsp_smd(NULL);
- notify_dsps_smd(NULL);
- notify_wcnss_smd(NULL);
- notify_rpm_smd(NULL);
/* change all remote states to CLOSED */
mutex_lock(&smd_probe_lock);
spin_lock_irqsave(&smd_lock, flags);
smd_channel_reset_state(shared_pri, PRI_ALLOC_TBL, SMD_SS_CLOSED,
- restart_pid);
+ restart_pid, pri_size / sizeof(*shared_pri));
if (shared_sec)
smd_channel_reset_state(shared_sec, SEC_ALLOC_TBL,
- SMD_SS_CLOSED, restart_pid);
+ SMD_SS_CLOSED, restart_pid,
+ sec_size / sizeof(*shared_sec));
spin_unlock_irqrestore(&smd_lock, flags);
mutex_unlock(&smd_probe_lock);
- /* notify SMD processors */
mb();
smd_fake_irq_handler(0);
- notify_modem_smd(NULL);
- notify_dsp_smd(NULL);
- notify_dsps_smd(NULL);
- notify_wcnss_smd(NULL);
- notify_rpm_smd(NULL);
- SMx_POWER_INFO("%s: finished reset\n", __func__);
+ SMD_POWER_INFO("%s: finished reset\n", __func__);
}
/* how many bytes are available for reading */
@@ -1157,15 +1181,33 @@
ch->notify_other_cpu(ch);
}
-static void do_smd_probe(void)
+/**
+ * do_smd_probe() - Look for newly created SMD channels a specific processor
+ *
+ * @remote_pid: remote processor id of the proc that may have created channels
+ */
+static void do_smd_probe(unsigned remote_pid)
{
- struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
- if (shared->heap_info.free_offset != last_heap_free) {
- last_heap_free = shared->heap_info.free_offset;
- schedule_work(&probe_work);
+ unsigned free_space;
+
+ free_space = smem_get_free_space(remote_pid);
+ if (free_space != remote_info[remote_pid].free_space) {
+ remote_info[remote_pid].free_space = free_space;
+ schedule_work(&remote_info[remote_pid].probe_work);
}
}
+/**
+ * do_smd_probe() - Look for newly created SMD channels from any remote proc
+ */
+static void do_smd_probe_all(void)
+{
+ int i;
+
+ for (i = 1; i < NUM_SMD_SUBSYSTEMS; ++i)
+ do_smd_probe(i);
+}
+
static void smd_state_change(struct smd_channel *ch,
unsigned last, unsigned next)
{
@@ -1230,7 +1272,7 @@
spin_unlock_irqrestore(&smd_lock, flags);
}
-static void handle_smd_irq(struct list_head *list,
+static void handle_smd_irq(struct remote_proc_info *r_info,
void (*notify)(smd_channel_t *ch))
{
unsigned long flags;
@@ -1238,6 +1280,9 @@
unsigned ch_flags;
unsigned tmp;
unsigned char state_change;
+ struct list_head *list;
+
+ list = &r_info->ch_list;
spin_lock_irqsave(&smd_lock, flags);
list_for_each_entry(ch, list, ch_list) {
@@ -1259,14 +1304,14 @@
}
tmp = ch->half_ch->get_state(ch->recv);
if (tmp != ch->last_state) {
- SMx_POWER_INFO("SMD ch%d '%s' State change %d->%d\n",
+ SMD_POWER_INFO("SMD ch%d '%s' State change %d->%d\n",
ch->n, ch->name, ch->last_state, tmp);
smd_state_change(ch, ch->last_state, tmp);
state_change = 1;
}
if (ch_flags & 0x3) {
ch->update_state(ch);
- SMx_POWER_INFO(
+ SMD_POWER_INFO(
"SMD ch%d '%s' Data event 0x%x tx%d/rx%d %dr/%dw : %dr/%dw\n",
ch->n, ch->name,
ch_flags,
@@ -1281,13 +1326,13 @@
ch->notify(ch->priv, SMD_EVENT_DATA);
}
if (ch_flags & 0x4 && !state_change) {
- SMx_POWER_INFO("SMD ch%d '%s' State update\n",
+ SMD_POWER_INFO("SMD ch%d '%s' State update\n",
ch->n, ch->name);
ch->notify(ch->priv, SMD_EVENT_STATUS);
}
}
spin_unlock_irqrestore(&smd_lock, flags);
- do_smd_probe();
+ do_smd_probe(r_info->remote_pid);
}
static inline void log_irq(uint32_t subsystem)
@@ -1296,14 +1341,14 @@
(void) subsys;
- SMx_POWER_INFO("SMD Int %s->Apps\n", subsys);
+ SMD_POWER_INFO("SMD Int %s->Apps\n", subsys);
}
irqreturn_t smd_modem_irq_handler(int irq, void *data)
{
log_irq(SMD_APPS_MODEM);
++interrupt_stats[SMD_MODEM].smd_in_count;
- handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+ handle_smd_irq(&remote_info[SMD_MODEM], notify_modem_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
@@ -1312,7 +1357,7 @@
{
log_irq(SMD_APPS_QDSP);
++interrupt_stats[SMD_Q6].smd_in_count;
- handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+ handle_smd_irq(&remote_info[SMD_Q6], notify_dsp_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
@@ -1321,7 +1366,7 @@
{
log_irq(SMD_APPS_DSPS);
++interrupt_stats[SMD_DSPS].smd_in_count;
- handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
+ handle_smd_irq(&remote_info[SMD_DSPS], notify_dsps_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
@@ -1330,7 +1375,7 @@
{
log_irq(SMD_APPS_WCNSS);
++interrupt_stats[SMD_WCNSS].smd_in_count;
- handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
+ handle_smd_irq(&remote_info[SMD_WCNSS], notify_wcnss_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
@@ -1339,18 +1384,18 @@
{
log_irq(SMD_APPS_RPM);
++interrupt_stats[SMD_RPM].smd_in_count;
- handle_smd_irq(&smd_ch_list_rpm, notify_rpm_smd);
+ handle_smd_irq(&remote_info[SMD_RPM], notify_rpm_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
static void smd_fake_irq_handler(unsigned long arg)
{
- handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
- handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
- handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
- handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
- handle_smd_irq(&smd_ch_list_rpm, notify_rpm_smd);
+ handle_smd_irq(&remote_info[SMD_MODEM], notify_modem_smd);
+ handle_smd_irq(&remote_info[SMD_Q6], notify_dsp_smd);
+ handle_smd_irq(&remote_info[SMD_DSPS], notify_dsps_smd);
+ handle_smd_irq(&remote_info[SMD_WCNSS], notify_wcnss_smd);
+ handle_smd_irq(&remote_info[SMD_RPM], notify_rpm_smd);
handle_smd_irq_closing_list();
}
@@ -1376,32 +1421,32 @@
int need_int = 0;
spin_lock_irqsave(&smd_lock, flags);
- list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
+ list_for_each_entry(ch, &remote_info[SMD_MODEM].ch_list, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
- list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
+ list_for_each_entry(ch, &remote_info[SMD_Q6].ch_list, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
- list_for_each_entry(ch, &smd_ch_list_dsps, ch_list) {
+ list_for_each_entry(ch, &remote_info[SMD_DSPS].ch_list, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
- list_for_each_entry(ch, &smd_ch_list_wcnss, ch_list) {
+ list_for_each_entry(ch, &remote_info[SMD_WCNSS].ch_list, ch_list) {
if (smd_need_int(ch)) {
need_int = 1;
break;
}
}
spin_unlock_irqrestore(&smd_lock, flags);
- do_smd_probe();
+ do_smd_probe_all();
if (need_int) {
SMD_DBG("smd_sleep_exit need interrupt\n");
@@ -1582,12 +1627,14 @@
* @ch: pointer to the local structure for this channel
* @table_id: the id of the table this channel resides in. 1 = first table, 2 =
* second table, etc
+ * @r_info: pointer to the info structure of the remote proc for this channel
* @returns: -EINVAL for failure; 0 for success
*
* ch must point to an allocated instance of struct smd_channel that is zeroed
* out, and has the n and type members already initialized to the correct values
*/
-static int smd_alloc_v2(struct smd_channel *ch, int table_id)
+static int smd_alloc_v2(struct smd_channel *ch, int table_id,
+ struct remote_proc_info *r_info)
{
void *buffer;
unsigned buffer_sz;
@@ -1610,7 +1657,8 @@
if (is_word_access_ch(ch->type)) {
struct smd_shared_v2_word_access *shared2;
- shared2 = smem_alloc(base_id + ch->n, sizeof(*shared2));
+ shared2 = smem_alloc_to_proc(base_id + ch->n, sizeof(*shared2),
+ r_info->remote_pid, 0);
if (!shared2) {
SMD_INFO("smem_alloc failed ch=%d\n", ch->n);
return -EINVAL;
@@ -1619,7 +1667,8 @@
ch->recv = &shared2->ch1;
} else {
struct smd_shared_v2 *shared2;
- shared2 = smem_alloc(base_id + ch->n, sizeof(*shared2));
+ shared2 = smem_alloc_to_proc(base_id + ch->n, sizeof(*shared2),
+ r_info->remote_pid, 0);
if (!shared2) {
SMD_INFO("smem_alloc failed ch=%d\n", ch->n);
return -EINVAL;
@@ -1629,7 +1678,8 @@
}
ch->half_ch = get_half_ch_funcs(ch->type);
- buffer = smem_get_entry(fifo_id + ch->n, &buffer_sz);
+ buffer = smem_get_entry_to_proc(fifo_id + ch->n, &buffer_sz,
+ r_info->remote_pid, 0);
if (!buffer) {
SMD_INFO("smem_get_entry failed\n");
return -EINVAL;
@@ -1654,7 +1704,8 @@
}
#else /* define v1 for older targets */
-static int smd_alloc_v2(struct smd_channel *ch, int table_id)
+static int smd_alloc_v2(struct smd_channel *ch, int table_id,
+ struct remote_proc_info *r_info)
{
return -EINVAL;
}
@@ -1662,7 +1713,8 @@
static int smd_alloc_v1(struct smd_channel *ch)
{
struct smd_shared_v1 *shared1;
- shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
+ shared1 = smem_alloc_to_proc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1),
+ 0, SMEM_ANY_HOST_FLAG);
if (!shared1) {
pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
return -EINVAL;
@@ -1685,9 +1737,11 @@
* @alloc_elm: the allocation element stored in SMEM for this channel
* @table_id: the id of the table this channel resides in. 1 = first table, 2 =
* seconds table, etc
+ * @r_info: pointer to the info structure of the remote proc for this channel
* @returns: -1 for failure; 0 for success
*/
-static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id)
+static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id,
+ struct remote_proc_info *r_info)
{
struct smd_channel *ch;
@@ -1699,7 +1753,7 @@
ch->n = alloc_elm->cid;
ch->type = SMD_CHANNEL_TYPE(alloc_elm->type);
- if (smd_alloc_v2(ch, table_id) && smd_alloc_v1(ch)) {
+ if (smd_alloc_v2(ch, table_id, r_info) && smd_alloc_v1(ch)) {
kfree(ch);
return -1;
}
@@ -1922,18 +1976,11 @@
SMD_DBG("smd_open: opening '%s'\n", ch->name);
spin_lock_irqsave(&smd_lock, flags);
- if (SMD_CHANNEL_TYPE(ch->type) == SMD_APPS_MODEM)
- list_add(&ch->ch_list, &smd_ch_list_modem);
- else if (SMD_CHANNEL_TYPE(ch->type) == SMD_APPS_QDSP)
- list_add(&ch->ch_list, &smd_ch_list_dsp);
- else if (SMD_CHANNEL_TYPE(ch->type) == SMD_APPS_DSPS)
- list_add(&ch->ch_list, &smd_ch_list_dsps);
- else if (SMD_CHANNEL_TYPE(ch->type) == SMD_APPS_WCNSS)
- list_add(&ch->ch_list, &smd_ch_list_wcnss);
- else if (SMD_CHANNEL_TYPE(ch->type) == SMD_APPS_RPM)
- list_add(&ch->ch_list, &smd_ch_list_rpm);
- else
+ if (unlikely(ch->type == SMD_LOOPBACK_TYPE))
list_add(&ch->ch_list, &smd_ch_list_loopback);
+ else
+ list_add(&ch->ch_list,
+ &remote_info[edge_to_pids[ch->type].remote_pid].ch_list);
SMD_DBG("%s: opening ch %d\n", __func__, ch->n);
@@ -2232,11 +2279,11 @@
return -ENODEV;
if (mask) {
- SMx_POWER_INFO("SMD Masking interrupts from %s\n",
+ SMD_POWER_INFO("SMD Masking interrupts from %s\n",
edge_to_pids[ch->type].subsys_name);
irq_chip->irq_mask(irq_data);
} else {
- SMx_POWER_INFO("SMD Unmasking interrupts from %s\n",
+ SMD_POWER_INFO("SMD Unmasking interrupts from %s\n",
edge_to_pids[ch->type].subsys_name);
irq_chip->irq_unmask(irq_data);
}
@@ -2405,8 +2452,9 @@
}
remote_spin_unlock_irqrestore(remote_spinlock, flags);
- smsm_size_info = smem_alloc(SMEM_SMSM_SIZE_INFO,
- sizeof(struct smsm_size_info_type));
+ smsm_size_info = smem_alloc_to_proc(SMEM_SMSM_SIZE_INFO,
+ sizeof(struct smsm_size_info_type), 0,
+ SMEM_ANY_HOST_FLAG);
if (smsm_size_info) {
SMSM_NUM_ENTRIES = smsm_size_info->num_entries;
SMSM_NUM_HOSTS = smsm_size_info->num_hosts;
@@ -2423,9 +2471,10 @@
"smsm_snapshot");
if (!smsm_info.state) {
- smsm_info.state = smem_alloc2(ID_SHARED_STATE,
- SMSM_NUM_ENTRIES *
- sizeof(uint32_t));
+ smsm_info.state = smem_alloc2_to_proc(ID_SHARED_STATE,
+ SMSM_NUM_ENTRIES *
+ sizeof(uint32_t), 0,
+ SMEM_ANY_HOST_FLAG);
if (smsm_info.state) {
__raw_writel(0, SMSM_STATE_ADDR(SMSM_APPS_STATE));
@@ -2436,10 +2485,12 @@
}
if (!smsm_info.intr_mask) {
- smsm_info.intr_mask = smem_alloc2(SMEM_SMSM_CPU_INTR_MASK,
- SMSM_NUM_ENTRIES *
- SMSM_NUM_HOSTS *
- sizeof(uint32_t));
+ smsm_info.intr_mask = smem_alloc2_to_proc(
+ SMEM_SMSM_CPU_INTR_MASK,
+ SMSM_NUM_ENTRIES *
+ SMSM_NUM_HOSTS *
+ sizeof(uint32_t), 0,
+ SMEM_ANY_HOST_FLAG);
if (smsm_info.intr_mask) {
for (i = 0; i < SMSM_NUM_ENTRIES; i++)
@@ -2454,9 +2505,10 @@
}
if (!smsm_info.intr_mux)
- smsm_info.intr_mux = smem_alloc2(SMEM_SMD_SMSM_INTR_MUX,
- SMSM_NUM_INTR_MUX *
- sizeof(uint32_t));
+ smsm_info.intr_mux = smem_alloc2_to_proc(SMEM_SMD_SMSM_INTR_MUX,
+ SMSM_NUM_INTR_MUX *
+ sizeof(uint32_t), 0,
+ SMEM_ANY_HOST_FLAG);
i = smsm_cb_init();
if (i)
@@ -2509,7 +2561,9 @@
uint32_t new_state;
unsigned long flags;
int ret;
+ uint64_t timestamp;
+ timestamp = sched_clock();
ret = kfifo_avail(&smsm_snapshot_fifo);
if (ret < SMSM_SNAPSHOT_SIZE) {
pr_err("%s: SMSM snapshot full %d\n", __func__, ret);
@@ -2532,7 +2586,7 @@
if (use_wakelock) {
spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
if (smsm_snapshot_count == 0) {
- SMx_POWER_INFO("SMSM snapshot wake lock\n");
+ SMSM_POWER_INFO("SMSM snapshot wake lock\n");
wake_lock(&smsm_snapshot_wakelock);
}
++smsm_snapshot_count;
@@ -2551,6 +2605,12 @@
}
}
+ ret = kfifo_in(&smsm_snapshot_fifo, ×tamp, sizeof(timestamp));
+ if (ret != sizeof(timestamp)) {
+ pr_err("%s: SMSM snapshot failure %d\n", __func__, ret);
+ goto restore_snapshot_count;
+ }
+
/* queue wakelock usage flag */
ret = kfifo_in(&smsm_snapshot_fifo,
&use_wakelock, sizeof(use_wakelock));
@@ -2568,7 +2628,7 @@
if (smsm_snapshot_count) {
--smsm_snapshot_count;
if (smsm_snapshot_count == 0) {
- SMx_POWER_INFO("SMSM snapshot wake unlock\n");
+ SMSM_POWER_INFO("SMSM snapshot wake unlock\n");
wake_unlock(&smsm_snapshot_wakelock);
}
} else {
@@ -2651,7 +2711,6 @@
if (old_apps != apps) {
SMSM_DBG("<SM %08x NOTIFY>\n", apps);
__raw_writel(apps, SMSM_STATE_ADDR(SMSM_APPS_STATE));
- do_smd_probe();
notify_other_smsm(SMSM_APPS_STATE, (old_apps ^ apps));
}
@@ -2663,28 +2722,28 @@
irqreturn_t smsm_modem_irq_handler(int irq, void *data)
{
- SMx_POWER_INFO("SMSM Int Modem->Apps\n");
+ SMSM_POWER_INFO("SMSM Int Modem->Apps\n");
++interrupt_stats[SMD_MODEM].smsm_in_count;
return smsm_irq_handler(irq, data);
}
irqreturn_t smsm_dsp_irq_handler(int irq, void *data)
{
- SMx_POWER_INFO("SMSM Int LPASS->Apps\n");
+ SMSM_POWER_INFO("SMSM Int LPASS->Apps\n");
++interrupt_stats[SMD_Q6].smsm_in_count;
return smsm_irq_handler(irq, data);
}
irqreturn_t smsm_dsps_irq_handler(int irq, void *data)
{
- SMx_POWER_INFO("SMSM Int DSPS->Apps\n");
+ SMSM_POWER_INFO("SMSM Int DSPS->Apps\n");
++interrupt_stats[SMD_DSPS].smsm_in_count;
return smsm_irq_handler(irq, data);
}
irqreturn_t smsm_wcnss_irq_handler(int irq, void *data)
{
- SMx_POWER_INFO("SMSM Int WCNSS->Apps\n");
+ SMSM_POWER_INFO("SMSM Int WCNSS->Apps\n");
++interrupt_stats[SMD_WCNSS].smsm_in_count;
return smsm_irq_handler(irq, data);
}
@@ -2774,7 +2833,7 @@
old_state = __raw_readl(SMSM_STATE_ADDR(smsm_entry));
new_state = (old_state & ~clear_mask) | set_mask;
__raw_writel(new_state, SMSM_STATE_ADDR(smsm_entry));
- SMx_POWER_INFO("%s %d:%08x->%08x", __func__, smsm_entry,
+ SMSM_POWER_INFO("%s %d:%08x->%08x", __func__, smsm_entry,
old_state, new_state);
notify_other_smsm(SMSM_APPS_STATE, (old_state ^ new_state));
@@ -2818,8 +2877,12 @@
uint32_t use_wakelock;
int ret;
unsigned long flags;
+ uint64_t t_snapshot;
+ uint64_t t_start;
+ unsigned long nanosec_rem;
while (kfifo_len(&smsm_snapshot_fifo) >= SMSM_SNAPSHOT_SIZE) {
+ t_start = sched_clock();
mutex_lock(&smsm_lock);
for (n = 0; n < SMSM_NUM_ENTRIES; n++) {
state_info = &smsm_states[n];
@@ -2835,7 +2898,7 @@
state_changes = state_info->last_value ^ new_state;
if (state_changes) {
- SMx_POWER_INFO("SMSM Change %d: %08x->%08x\n",
+ SMSM_POWER_INFO("SMSM Change %d: %08x->%08x\n",
n, state_info->last_value,
new_state);
list_for_each_entry(cb_info,
@@ -2850,6 +2913,15 @@
}
}
+ ret = kfifo_out(&smsm_snapshot_fifo, &t_snapshot,
+ sizeof(t_snapshot));
+ if (ret != sizeof(t_snapshot)) {
+ pr_err("%s: snapshot underflow %d\n",
+ __func__, ret);
+ mutex_unlock(&smsm_lock);
+ return;
+ }
+
/* read wakelock flag */
ret = kfifo_out(&smsm_snapshot_fifo, &use_wakelock,
sizeof(use_wakelock));
@@ -2866,7 +2938,7 @@
if (smsm_snapshot_count) {
--smsm_snapshot_count;
if (smsm_snapshot_count == 0) {
- SMx_POWER_INFO("SMSM snapshot"
+ SMSM_POWER_INFO("SMSM snapshot"
" wake unlock\n");
wake_unlock(&smsm_snapshot_wakelock);
}
@@ -2877,6 +2949,12 @@
spin_unlock_irqrestore(&smsm_snapshot_count_lock,
flags);
}
+
+ t_start = t_start - t_snapshot;
+ nanosec_rem = do_div(t_start, 1000000000U);
+ SMSM_POWER_INFO(
+ "SMSM snapshot queue response time %6u.%09lu s\n",
+ (unsigned)t_start, nanosec_rem);
}
}
@@ -3087,18 +3165,22 @@
* smd_post_init() - SMD post initialization
* @is_leagcy: 1 for Leagcy/platform device init sequence
* 0 for device tree init sequence
+ * @remote_pid: remote pid that has been initialized. Ignored when is_legacy=1
*
* This function is used by the legacy and device tree initialization
* to complete the SMD init sequence.
*/
-void smd_post_init(bool is_legacy)
+void smd_post_init(bool is_legacy, unsigned remote_pid)
{
+ int i;
+
if (is_legacy) {
smd_initialized = 1;
smd_alloc_loopback_channel();
- tasklet_schedule(&smd_fake_irq_tasklet);
+ for (i = 1; i < NUM_SMD_SUBSYSTEMS; ++i)
+ schedule_work(&remote_info[i].probe_work);
} else {
- schedule_work(&probe_work);
+ schedule_work(&remote_info[remote_pid].probe_work);
}
}
@@ -3235,19 +3317,31 @@
{
static bool registered;
int rc;
+ int i;
if (registered)
return 0;
smd_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smd");
if (!smd_log_ctx) {
- pr_err("%s: unable to create logging context\n", __func__);
+ pr_err("%s: unable to create SMD logging context\n", __func__);
+ msm_smd_debug_mask = 0;
+ }
+
+ smsm_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smsm");
+ if (!smsm_log_ctx) {
+ pr_err("%s: unable to create SMSM logging context\n", __func__);
msm_smd_debug_mask = 0;
}
registered = true;
- INIT_WORK(&probe_work, smd_channel_probe_worker);
+ for (i = 0; i < NUM_SMD_SUBSYSTEMS; ++i) {
+ remote_info[i].remote_pid = i;
+ remote_info[i].free_space = UINT_MAX;
+ INIT_WORK(&remote_info[i].probe_work, smd_channel_probe_worker);
+ INIT_LIST_HEAD(&remote_info[i].ch_list);
+ }
channel_close_wq = create_singlethread_workqueue("smd_channel_close");
if (IS_ERR(channel_close_wq)) {
diff --git a/arch/arm/mach-msm/smd_init_dt.c b/arch/arm/mach-msm/smd_init_dt.c
index d888a72..640656c 100644
--- a/arch/arm/mach-msm/smd_init_dt.c
+++ b/arch/arm/mach-msm/smd_init_dt.c
@@ -259,7 +259,7 @@
smd_set_edge_subsys_name(edge, pilstr);
smd_set_edge_initialized(edge);
- smd_post_init(0);
+ smd_post_init(0, remote_pid);
return 0;
missing_key:
diff --git a/arch/arm/mach-msm/smd_init_plat.c b/arch/arm/mach-msm/smd_init_plat.c
index c6f6cd9..c58b150 100644
--- a/arch/arm/mach-msm/smd_init_plat.c
+++ b/arch/arm/mach-msm/smd_init_plat.c
@@ -502,7 +502,7 @@
pr_err("smd_post_init() failed ret = %d\n", ret);
return ret;
}
- smd_post_init(1);
+ smd_post_init(1, 0);
return 0;
}
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 4664197..812a7d6 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -230,7 +230,8 @@
MSM_SMSM_DEBUG = 1U << 1,
MSM_SMD_INFO = 1U << 2,
MSM_SMSM_INFO = 1U << 3,
- MSM_SMx_POWER_INFO = 1U << 4,
+ MSM_SMD_POWER_INFO = 1U << 4,
+ MSM_SMSM_POWER_INFO = 1U << 5,
};
struct interrupt_config {
@@ -261,7 +262,7 @@
extern irqreturn_t smd_rpm_irq_handler(int irq, void *data);
extern int msm_smd_driver_register(void);
-extern void smd_post_init(bool is_legacy);
+extern void smd_post_init(bool is_legacy, unsigned remote_pid);
extern int smsm_post_init(void);
extern struct interrupt_config *smd_get_intr_config(uint32_t edge);
diff --git a/arch/arm/mach-msm/smem.c b/arch/arm/mach-msm/smem.c
index 1ec2a78..f41240a 100644
--- a/arch/arm/mach-msm/smem.c
+++ b/arch/arm/mach-msm/smem.c
@@ -16,12 +16,14 @@
#include <linux/moduleparam.h>
#include <linux/printk.h>
#include <linux/notifier.h>
+#include <linux/of.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
#include <mach/msm_smem.h>
#include <mach/ramdump.h>
#include <mach/subsystem_notif.h>
+#include <mach/msm_ipc_logging.h>
#include "smem_private.h"
@@ -45,13 +47,29 @@
MSM_SMEM_INFO = 1U << 1,
};
-static int msm_smem_debug_mask;
+static int msm_smem_debug_mask = MSM_SMEM_INFO;
module_param_named(debug_mask, msm_smem_debug_mask,
int, S_IRUGO | S_IWUSR | S_IWGRP);
+static void *smem_ipc_log_ctx;
+#define NUM_LOG_PAGES 4
+#define IPC_LOG(x...) do { \
+ if (smem_ipc_log_ctx) \
+ ipc_log_string(smem_ipc_log_ctx, x); \
+ } while (0)
+
+
+#define LOG_ERR(x...) do { \
+ pr_err(x); \
+ IPC_LOG(x); \
+ } while (0)
#define SMEM_DBG(x...) do { \
if (msm_smem_debug_mask & MSM_SMEM_DEBUG) \
- pr_debug(x); \
+ IPC_LOG(x); \
+ } while (0)
+#define SMEM_INFO(x...) do { \
+ if (msm_smem_debug_mask & MSM_SMEM_INFO) \
+ IPC_LOG(x); \
} while (0)
#define SMEM_SPINLOCK_SMEM_ALLOC "S:3"
@@ -68,6 +86,61 @@
static RAW_NOTIFIER_HEAD(smem_module_init_notifier_list);
static DEFINE_MUTEX(smem_module_init_notifier_lock);
+/* smem security feature components */
+#define SMEM_TOC_IDENTIFIER 0x434f5424 /* "$TOC" */
+#define SMEM_TOC_MAX_EXCLUSIONS 4
+#define SMEM_PART_HDR_IDENTIFIER 0x54525024 /* "$PRT" */
+#define SMEM_ALLOCATION_CANARY 0xa5a5
+
+struct smem_toc_entry {
+ uint32_t offset;
+ uint32_t size;
+ uint32_t flags;
+ uint16_t host0;
+ uint16_t host1;
+ uint32_t size_cacheline;
+ uint32_t reserved[3];
+ uint32_t exclusion_sizes[SMEM_TOC_MAX_EXCLUSIONS];
+};
+
+struct smem_toc {
+ /* Identifier is a constant, set to SMEM_TOC_IDENTIFIER. */
+ uint32_t identifier;
+ uint32_t version;
+ uint32_t num_entries;
+ uint32_t reserved[5];
+ struct smem_toc_entry entry[];
+};
+
+struct smem_partition_header {
+ /* Identifier is a constant, set to SMEM_PART_HDR_IDENTIFIER. */
+ uint32_t identifier;
+ uint16_t host0;
+ uint16_t host1;
+ uint32_t size;
+ uint32_t offset_free_uncached;
+ uint32_t offset_free_cached;
+ uint32_t reserved[3];
+};
+
+struct smem_partition_allocation_header {
+ /* Canary is a constant, set to SMEM_ALLOCATION_CANARY */
+ uint16_t canary;
+ uint16_t smem_type;
+ uint32_t size; /* includes padding bytes */
+ uint16_t padding_data;
+ uint16_t padding_hdr;
+ uint32_t reserved[1];
+};
+
+struct smem_partition_info {
+ uint32_t partition_num;
+ uint32_t offset;
+ uint32_t size_cacheline;
+};
+
+static struct smem_partition_info partitions[NUM_SMEM_SUBSYSTEMS];
+/* end smem security feature components */
struct restart_notifier_block {
unsigned processor;
@@ -128,7 +201,7 @@
if (base >= phys_addr && base + offset < phys_addr + size) {
if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
(uintptr_t)MSM_SHARED_RAM_BASE, offset)) {
- pr_err("%s: overflow %p %x\n", __func__,
+ SMEM_INFO("%s: overflow %p %x\n", __func__,
MSM_SHARED_RAM_BASE, offset);
return NULL;
}
@@ -147,7 +220,7 @@
if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
(uintptr_t)smem_areas[i].virt_addr, offset)) {
- pr_err("%s: overflow %p %x\n", __func__,
+ SMEM_INFO("%s: overflow %p %x\n", __func__,
smem_areas[i].virt_addr, offset);
return NULL;
}
@@ -201,6 +274,22 @@
EXPORT_SYMBOL(smem_alloc);
/**
+ * smem_alloc_to_proc - Find existing item with security support
+ *
+ * @id: ID of SMEM item
+ * @size: Size of the SMEM item
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ */
+void *smem_alloc_to_proc(unsigned id, unsigned size, unsigned to_proc,
+ unsigned flags)
+{
+ return smem_find_to_proc(id, size, to_proc, flags);
+}
+EXPORT_SYMBOL(smem_alloc_to_proc);
+
+/**
* __smem_get_entry - Get pointer and size of existing SMEM item
*
* @id: ID of SMEM item
@@ -246,6 +335,138 @@
return ret;
}
+/**
+ * __smem_get_entry_to_proc - Get pointer and size of existing SMEM item with
+ * security support
+ *
+ * @id: ID of SMEM item
+ * @size: Pointer to size variable for storing the result
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @skip_init_check: True means do not verify that SMEM has been initialized
+ * @use_rspinlock: True to use the remote spinlock
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ */
+static void *__smem_get_entry_to_proc(unsigned id,
+ unsigned *size,
+ unsigned to_proc,
+ unsigned flags,
+ bool skip_init_check,
+ bool use_rspinlock)
+{
+ struct smem_partition_header *hdr;
+ unsigned long lflags = 0;
+ void *item = NULL;
+ struct smem_partition_allocation_header *alloc_hdr;
+ uint32_t partition_num;
+ uint32_t a_hdr_size;
+ int rc;
+
+ SMEM_DBG("%s(%u, %u, %u, %u, %d, %d)\n", __func__, id, *size, to_proc,
+ flags, skip_init_check, use_rspinlock);
+
+ if (!skip_init_check && !smem_initialized_check())
+ return NULL;
+
+ if (id >= SMEM_NUM_ITEMS) {
+ SMEM_INFO("%s: invalid id %d\n", __func__, id);
+ return NULL;
+ }
+
+ if (!(flags & SMEM_ANY_HOST_FLAG) && to_proc >= NUM_SMEM_SUBSYSTEMS) {
+ SMEM_INFO("%s: id %u invalid to_proc %d\n", __func__, id,
+ to_proc);
+ return NULL;
+ }
+
+ if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset)
+ return __smem_get_entry(id, size, skip_init_check,
+ use_rspinlock);
+
+ partition_num = partitions[to_proc].partition_num;
+ hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
+ if (unlikely(!spinlocks_initialized)) {
+ rc = init_smem_remote_spinlock();
+ if (unlikely(rc)) {
+ SMEM_INFO(
+ "%s: id:%u remote spinlock init failed %d\n",
+ __func__, id, rc);
+ return NULL;
+ }
+ }
+ if (use_rspinlock)
+ remote_spin_lock_irqsave(&remote_spinlock, lflags);
+ if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) {
+ LOG_ERR(
+ "%s: SMEM corruption detected. Partition %d to %d at %p\n",
+ __func__,
+ partition_num,
+ to_proc,
+ hdr);
+ BUG();
+ }
+
+ if (flags & SMEM_ITEM_CACHED_FLAG) {
+ a_hdr_size = ALIGN(sizeof(*alloc_hdr),
+ partitions[to_proc].size_cacheline);
+ for (alloc_hdr = (void *)(hdr) + hdr->size - a_hdr_size;
+ (void *)(alloc_hdr) > (void *)(hdr) +
+ hdr->offset_free_cached;
+ alloc_hdr = (void *)(alloc_hdr) -
+ alloc_hdr->size - a_hdr_size) {
+ if (alloc_hdr->canary != SMEM_ALLOCATION_CANARY) {
+ LOG_ERR(
+ "%s: SMEM corruption detected. Partition %d to %d at %p\n",
+ __func__,
+ partition_num,
+ to_proc,
+ alloc_hdr);
+ BUG();
+
+ }
+ if (alloc_hdr->smem_type == id) {
+ /* 8 byte alignment to match legacy */
+ *size = ALIGN(alloc_hdr->size -
+ alloc_hdr->padding_data, 8);
+ item = (void *)(alloc_hdr) - alloc_hdr->size;
+ break;
+ }
+ }
+ } else {
+ for (alloc_hdr = (void *)(hdr) + sizeof(*hdr);
+ (void *)(alloc_hdr) < (void *)(hdr) +
+ hdr->offset_free_uncached;
+ alloc_hdr = (void *)(alloc_hdr) +
+ sizeof(*alloc_hdr) +
+ alloc_hdr->padding_hdr +
+ alloc_hdr->size) {
+ if (alloc_hdr->canary != SMEM_ALLOCATION_CANARY) {
+ LOG_ERR(
+ "%s: SMEM corruption detected. Partition %d to %d at %p\n",
+ __func__,
+ partition_num,
+ to_proc,
+ alloc_hdr);
+ BUG();
+
+ }
+ if (alloc_hdr->smem_type == id) {
+ /* 8 byte alignment to match legacy */
+ *size = ALIGN(alloc_hdr->size -
+ alloc_hdr->padding_data, 8);
+ item = (void *)(alloc_hdr) +
+ sizeof(*alloc_hdr) +
+ alloc_hdr->padding_hdr;
+ break;
+ }
+ }
+ }
+ if (use_rspinlock)
+ remote_spin_unlock_irqrestore(&remote_spinlock, lflags);
+
+ return item;
+}
+
static void *__smem_find(unsigned id, unsigned size_in, bool skip_init_check)
{
unsigned size;
@@ -257,7 +478,7 @@
size_in = ALIGN(size_in, 8);
if (size_in != size) {
- pr_err("smem_find(%d, %d): wrong size %d\n",
+ SMEM_INFO("smem_find(%u, %u): wrong size %u\n",
id, size_in, size);
return 0;
}
@@ -271,6 +492,189 @@
}
EXPORT_SYMBOL(smem_find);
+/**
+ * smem_find_to_proc - Find existing item with security support
+ *
+ * @id: ID of SMEM item
+ * @size_in: Size of the SMEM item
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ */
+void *smem_find_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags)
+{
+ unsigned size;
+ void *ptr;
+
+ SMEM_DBG("%s(%u, %u, %u, %u)\n", __func__, id, size_in, to_proc,
+ flags);
+
+ ptr = smem_get_entry_to_proc(id, &size, to_proc, flags);
+ if (!ptr)
+ return 0;
+
+ size_in = ALIGN(size_in, 8);
+ if (size_in != size) {
+ SMEM_INFO("smem_find_to_proc(%u, %u, %u, %u): wrong size %u\n",
+ id, size_in, to_proc, flags, size);
+ return 0;
+ }
+
+ return ptr;
+}
+EXPORT_SYMBOL(smem_find_to_proc);
+
+/**
+ * alloc_item_nonsecure - Allocate an SMEM item in the nonsecure partition
+ *
+ * @id: ID of SMEM item
+ * @size_in: Size to allocate
+ * @returns: Pointer to SMEM item or NULL for error
+ *
+ * Assumes the id parameter is valid and does not already exist. Assumes
+ * size_in is already adjusted for alignment, if necessary. Requires the
+ * remote spinlock to already be locked.
+ */
+static void *alloc_item_nonsecure(unsigned id, unsigned size_in)
+{
+ void *smem_base = MSM_SHARED_RAM_BASE;
+ struct smem_shared *shared = smem_base;
+ struct smem_heap_entry *toc = shared->heap_toc;
+ void *ret = NULL;
+
+ if (shared->heap_info.heap_remaining >= size_in) {
+ toc[id].offset = shared->heap_info.free_offset;
+ toc[id].size = size_in;
+ /*
+ * wmb() is necessary to ensure the allocation data is
+ * consistent before setting the allocated flag to prevent race
+ * conditions with remote processors
+ */
+ wmb();
+ toc[id].allocated = 1;
+
+ shared->heap_info.free_offset += size_in;
+ shared->heap_info.heap_remaining -= size_in;
+ ret = smem_base + toc[id].offset;
+ /*
+ * wmb() is necessary to ensure the heap data is consistent
+ * before continuing to prevent race conditions with remote
+ * processors
+ */
+ wmb();
+ } else {
+ SMEM_INFO("%s: id %u not enough memory %u (required %u)\n",
+ __func__, id, shared->heap_info.heap_remaining,
+ size_in);
+ }
+
+ return ret;
+}
+
+/**
+ * alloc_item_secure - Allocate an SMEM item in a secure partition
+ *
+ * @id: ID of SMEM item
+ * @size_in: Size to allocate
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @returns: Pointer to SMEM item or NULL for error
+ *
+ * Assumes the id parameter is valid and does not already exist. Assumes
+ * size_in is the raw size requested by the client. Assumes to_proc is a valid
+ * host, and a valid partition to that host exists. Requires the remote
+ * spinlock to already be locked.
+ */
+static void *alloc_item_secure(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags)
+{
+ void *smem_base = MSM_SHARED_RAM_BASE;
+ struct smem_partition_header *hdr;
+ struct smem_partition_allocation_header *alloc_hdr;
+ uint32_t a_hdr_size;
+ uint32_t a_data_size;
+ uint32_t size_cacheline;
+ uint32_t free_space;
+ uint32_t partition_num;
+ void *ret = NULL;
+
+ hdr = smem_base + partitions[to_proc].offset;
+ partition_num = partitions[to_proc].partition_num;
+
+ if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) {
+ LOG_ERR(
+ "%s: SMEM corruption detected. Partition %d to %d at %p\n",
+ __func__,
+ partition_num,
+ to_proc,
+ hdr);
+ BUG();
+ }
+
+ size_cacheline = partitions[to_proc].size_cacheline;
+ free_space = hdr->offset_free_cached -
+ hdr->offset_free_uncached;
+
+ if (flags & SMEM_ITEM_CACHED_FLAG) {
+ a_hdr_size = ALIGN(sizeof(*alloc_hdr), size_cacheline);
+ a_data_size = ALIGN(size_in, size_cacheline);
+ if (free_space < a_hdr_size + a_data_size) {
+ SMEM_INFO(
+ "%s: id %u not enough memory %u (required %u)\n",
+ __func__, id, free_space,
+ a_hdr_size + a_data_size);
+ return ret;
+ }
+ alloc_hdr = (void *)(hdr) + hdr->offset_free_cached -
+ a_hdr_size;
+ alloc_hdr->canary = SMEM_ALLOCATION_CANARY;
+ alloc_hdr->smem_type = id;
+ alloc_hdr->size = a_data_size;
+ alloc_hdr->padding_data = a_data_size - size_in;
+ alloc_hdr->padding_hdr = a_hdr_size - sizeof(*alloc_hdr);
+ hdr->offset_free_cached = hdr->offset_free_cached -
+ a_hdr_size - a_data_size;
+ ret = (void *)(alloc_hdr) - a_data_size;
+ /*
+ * The SMEM protocol currently does not support cacheable
+ * areas within the smem region, but if it ever does in the
+ * future, then cache management needs to be done here.
+ * The area of memory this item is allocated from will need to
+ * be dynamically made cachable, and a cache flush of the
+ * allocation header using __cpuc_flush_dcache_area and
+ * outer_flush_area will need to be done.
+ */
+ } else {
+ a_hdr_size = sizeof(*alloc_hdr);
+ a_data_size = ALIGN(size_in, 8);
+ if (free_space < a_hdr_size + a_data_size) {
+ SMEM_INFO(
+ "%s: id %u not enough memory %u (required %u)\n",
+ __func__, id, free_space,
+ a_hdr_size + a_data_size);
+ return ret;
+ }
+ alloc_hdr = (void *)(hdr) + hdr->offset_free_uncached;
+ alloc_hdr->canary = SMEM_ALLOCATION_CANARY;
+ alloc_hdr->smem_type = id;
+ alloc_hdr->size = a_data_size;
+ alloc_hdr->padding_data = a_data_size - size_in;
+ alloc_hdr->padding_hdr = a_hdr_size - sizeof(*alloc_hdr);
+ hdr->offset_free_uncached = hdr->offset_free_uncached +
+ a_hdr_size + a_data_size;
+ ret = alloc_hdr + 1;
+ }
+ /*
+ * wmb() is necessary to ensure the heap and allocation data is
+ * consistent before continuing to prevent race conditions with remote
+ * processors
+ */
+ wmb();
+
+ return ret;
+}
+
/* smem_alloc2 returns the pointer to smem item. If it is not allocated,
* it allocates it and then returns the pointer to it.
*/
@@ -285,13 +689,15 @@
if (!smem_initialized_check())
return NULL;
- if (id >= SMEM_NUM_ITEMS)
+ if (id >= SMEM_NUM_ITEMS) {
+ SMEM_INFO("%s: invalid id %u\n", __func__, id);
return NULL;
+ }
if (unlikely(!spinlocks_initialized)) {
rc = init_smem_remote_spinlock();
if (unlikely(rc)) {
- pr_err("%s: remote spinlock init failed %d\n",
+ SMEM_INFO("%s: remote spinlock init failed %d\n",
__func__, rc);
return NULL;
}
@@ -300,34 +706,102 @@
size_in = ALIGN(size_in, 8);
remote_spin_lock_irqsave(&remote_spinlock, flags);
if (toc[id].allocated) {
- SMEM_DBG("%s: %u already allocated\n", __func__, id);
+ SMEM_INFO("%s: %u already allocated\n", __func__, id);
if (size_in != toc[id].size)
- pr_err("%s: wrong size %u (expected %u)\n",
+ SMEM_INFO("%s: wrong size %u (expected %u)\n",
__func__, toc[id].size, size_in);
else
ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
} else if (id > SMEM_FIXED_ITEM_LAST) {
- SMEM_DBG("%s: allocating %u\n", __func__, id);
- if (shared->heap_info.heap_remaining >= size_in) {
- toc[id].offset = shared->heap_info.free_offset;
- toc[id].size = size_in;
- wmb();
- toc[id].allocated = 1;
-
- shared->heap_info.free_offset += size_in;
- shared->heap_info.heap_remaining -= size_in;
- ret = (void *)(MSM_SHARED_RAM_BASE + toc[id].offset);
- } else
- pr_err("%s: not enough memory %u (required %u)\n",
- __func__, shared->heap_info.heap_remaining,
- size_in);
+ SMEM_INFO("%s: allocating %u\n", __func__, id);
+ ret = alloc_item_nonsecure(id, size_in);
}
- wmb();
remote_spin_unlock_irqrestore(&remote_spinlock, flags);
return ret;
}
EXPORT_SYMBOL(smem_alloc2);
+/**
+ * smem_alloc2_to_proc - Find an existing item, otherwise allocate it with
+ * security support
+ *
+ * @id: ID of SMEM item
+ * @size_in: Size of the SMEM item
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @returns: Pointer to SMEM item or NULL if it couldn't be found/allocated
+ */
+void *smem_alloc2_to_proc(unsigned id, unsigned size_in, unsigned to_proc,
+ unsigned flags)
+{
+ unsigned long lflags;
+ void *ret = NULL;
+ int rc;
+ unsigned size_out;
+ unsigned a_size_in;
+
+ SMEM_DBG("%s(%u, %u, %u, %u)\n", __func__, id, size_in, to_proc,
+ flags);
+
+ if (!smem_initialized_check())
+ return NULL;
+
+ if (id >= SMEM_NUM_ITEMS) {
+ SMEM_INFO("%s: invalid id %u\n", __func__, id);
+ return NULL;
+ }
+
+ if (!(flags & SMEM_ANY_HOST_FLAG) && to_proc >= NUM_SMEM_SUBSYSTEMS) {
+ SMEM_INFO("%s: invalid to_proc %u for id %u\n", __func__,
+ to_proc, id);
+ return NULL;
+ }
+
+ if (unlikely(!spinlocks_initialized)) {
+ rc = init_smem_remote_spinlock();
+ if (unlikely(rc)) {
+ SMEM_INFO("%s: id:%u remote spinlock init failed %d\n",
+ __func__, id, rc);
+ return NULL;
+ }
+ }
+
+ a_size_in = ALIGN(size_in, 8);
+ remote_spin_lock_irqsave(&remote_spinlock, lflags);
+
+ ret = __smem_get_entry_to_proc(id, &size_out, to_proc, flags, true,
+ false);
+ if (ret) {
+ SMEM_INFO("%s: %u already allocated\n", __func__, id);
+ if (a_size_in == size_out) {
+ remote_spin_unlock_irqrestore(&remote_spinlock, lflags);
+ return ret;
+ } else {
+ remote_spin_unlock_irqrestore(&remote_spinlock, lflags);
+ SMEM_INFO("%s: id %u wrong size %u (expected %u)\n",
+ __func__, id, size_out, a_size_in);
+ return NULL;
+ }
+ }
+
+ if (id > SMEM_FIXED_ITEM_LAST) {
+ SMEM_INFO("%s: allocating %u size %u to_proc %u flags %u\n",
+ __func__, id, size_in, to_proc, flags);
+ if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset)
+ ret = alloc_item_nonsecure(id, a_size_in);
+ else
+ ret = alloc_item_secure(id, size_in, to_proc, flags);
+
+ } else {
+ SMEM_INFO("%s: attempted to allocate non-dynamic item %u\n",
+ __func__, id);
+ }
+
+ remote_spin_unlock_irqrestore(&remote_spinlock, lflags);
+ return ret;
+}
+EXPORT_SYMBOL(smem_alloc2_to_proc);
+
void *smem_get_entry(unsigned id, unsigned *size)
{
return __smem_get_entry(id, size, false, true);
@@ -335,6 +809,24 @@
EXPORT_SYMBOL(smem_get_entry);
/**
+ * smem_get_entry_to_proc - Get existing item with security support
+ *
+ * @id: ID of SMEM item
+ * @size: Pointer to size variable for storing the result
+ * @to_proc: SMEM host that shares the item with apps
+ * @flags: Item attribute flags
+ * @returns: Pointer to SMEM item or NULL if it doesn't exist
+ */
+void *smem_get_entry_to_proc(unsigned id, unsigned *size, unsigned to_proc,
+ unsigned flags)
+{
+ SMEM_DBG("%s(%u, %u, %u, %u)\n", __func__, id, *size, to_proc, flags);
+
+ return __smem_get_entry_to_proc(id, size, to_proc, flags, false, true);
+}
+EXPORT_SYMBOL(smem_get_entry_to_proc);
+
+/**
* smem_get_entry_no_rlock - Get existing item without using remote spinlock
*
* @id: ID of SMEM item
@@ -365,9 +857,50 @@
EXPORT_SYMBOL(smem_get_remote_spinlock);
/**
+ * smem_get_free_space() - Get the available allocation free space for a
+ * partition
+ *
+ * @to_proc: remote SMEM host. Determines the applicable partition
+ * @returns: size in bytes available to allocate
+ *
+ * Helper function for SMD so that SMD only scans the channel allocation
+ * table for a partition when it is reasonably certain that a channel has
+ * actually been created, because scanning can be expensive. Creating a channel
+ * will consume some of the free space in a partition, so SMD can compare the
+ * last free space size against the current free space size to determine if
+ * a channel may have been created. SMD can't do this directly, because the
+ * necessary partition internals are restricted to just SMEM.
+ */
+unsigned smem_get_free_space(unsigned to_proc)
+{
+ struct smem_partition_header *hdr;
+ struct smem_shared *shared;
+
+ if (to_proc >= NUM_SMEM_SUBSYSTEMS) {
+ pr_err("%s: invalid to_proc:%d\n", __func__, to_proc);
+ return UINT_MAX;
+ }
+
+ if (partitions[to_proc].offset) {
+ if (unlikely(OVERFLOW_ADD_UNSIGNED(uintptr_t,
+ (uintptr_t)smem_areas[0].virt_addr,
+ partitions[to_proc].offset))) {
+ pr_err("%s: unexpected overflow detected\n", __func__);
+ return UINT_MAX;
+ }
+ hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
+ return hdr->offset_free_cached - hdr->offset_free_uncached;
+ } else {
+ shared = (void *)MSM_SHARED_RAM_BASE;
+ return shared->heap_info.heap_remaining;
+ }
+}
+EXPORT_SYMBOL(smem_get_free_space);
+
+/**
* init_smem_remote_spinlock - Reentrant remote spinlock initialization
*
- * @returns: sucess or error code for failure
+ * @returns: success or error code for failure
*/
static int init_smem_remote_spinlock(void)
{
@@ -408,7 +941,7 @@
if (likely(checked)) {
if (unlikely(!is_inited))
- pr_err("%s: smem not initialized\n", __func__);
+ LOG_ERR("%s: smem not initialized\n", __func__);
return is_inited;
}
@@ -416,7 +949,7 @@
if (checked) {
spin_unlock_irqrestore(&smem_init_check_lock, flags);
if (unlikely(!is_inited))
- pr_err("%s: smem not initialized\n", __func__);
+ LOG_ERR("%s: smem not initialized\n", __func__);
return is_inited;
}
@@ -431,8 +964,17 @@
true);
if (version_array == NULL)
goto failed;
- if (version_array[MODEM_SBL_VERSION_INDEX] != SMEM_VERSION << 16)
+
+ /*
+ * The Modem SBL is now the Master SBL version and is required to
+ * pre-initialize SMEM and fill in any necessary configuration
+ * structures. Without the extra configuration data, the SMEM driver
+ * cannot be properly initialized.
+ */
+ if (version_array[MODEM_SBL_VERSION_INDEX] != SMEM_VERSION << 16) {
+ pr_err("%s: SBL version not correct\n", __func__);
goto failed;
+ }
is_inited = 1;
checked = 1;
@@ -443,7 +985,8 @@
is_inited = 0;
checked = 1;
spin_unlock_irqrestore(&smem_init_check_lock, flags);
- pr_err("%s: bootloader failure detected, shared memory not inited\n",
+ LOG_ERR(
+ "%s: shared memory needs to be initialized by SBL before booting\n",
__func__);
return is_inited;
}
@@ -458,7 +1001,7 @@
notifier = container_of(this,
struct restart_notifier_block, nb);
- SMEM_DBG("%s: ssrestart for processor %d ('%s')\n",
+ SMEM_INFO("%s: ssrestart for processor %d ('%s')\n",
__func__, notifier->processor,
notifier->name);
@@ -478,8 +1021,8 @@
ret = do_elf_ramdump(smem_ramdump_dev,
smem_ramdump_segments, 1);
if (ret < 0)
- pr_err("%s: unable to dump smem %d\n", __func__,
- ret);
+ LOG_ERR("%s: unable to dump smem %d\n",
+ __func__, ret);
}
}
@@ -494,7 +1037,7 @@
smem_ramdump_dev = create_ramdump_device("smem", NULL);
if (IS_ERR_OR_NULL(smem_ramdump_dev)) {
- pr_err("%s: Unable to create smem ramdump device.\n",
+ LOG_ERR("%s: Unable to create smem ramdump device.\n",
__func__);
smem_ramdump_dev = NULL;
}
@@ -546,6 +1089,124 @@
mutex_unlock(&smem_module_init_notifier_lock);
}
+/**
+ * smem_init_security_partition - Init local structures for a secured smem
+ * partition that has apps as one of the hosts
+ *
+ * @entry: Entry in the security TOC for the partition to init
+ * @num: Partition ID
+ *
+ * Initialize local data structures to point to a secured smem partition
+ * that is accessible by apps and another processor. Assumes that one of the
+ * listed hosts is apps. Verifiess that the partition is valid, otherwise will
+ * skip. Checks for memory corruption and will BUG() if detected. Assumes
+ * smem_areas is already initialized and that smem_areas[0] corresponds to the
+ * smem region with the secured partitions.
+ */
+static void smem_init_security_partition(struct smem_toc_entry *entry,
+ uint32_t num)
+{
+ uint16_t remote_host;
+ struct smem_partition_header *hdr;
+
+ if (!entry->offset) {
+ SMEM_INFO("Skipping smem partition %d - bad offset\n", num);
+ return;
+ }
+ if (!entry->size) {
+ SMEM_INFO("Skipping smem partition %d - bad size\n", num);
+ return;
+ }
+ if (!entry->size_cacheline) {
+ SMEM_INFO("Skipping smem partition %d - bad cacheline\n", num);
+ return;
+ }
+
+ if (entry->host0 == SMEM_APPS)
+ remote_host = entry->host1;
+ else
+ remote_host = entry->host0;
+
+ if (remote_host >= NUM_SMEM_SUBSYSTEMS) {
+ SMEM_INFO("Skipping smem partition %d - bad remote:%d\n", num,
+ remote_host);
+ return;
+ }
+ if (partitions[remote_host].offset) {
+ SMEM_INFO("Skipping smem partition %d - duplicate of %d\n", num,
+ partitions[remote_host].partition_num);
+ return;
+ }
+
+ hdr = smem_areas[0].virt_addr + entry->offset;
+
+ if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) {
+ LOG_ERR("Smem partition %d hdr magic is bad\n", num);
+ BUG();
+ }
+ if (!hdr->size) {
+ LOG_ERR("Smem partition %d size is 0\n", num);
+ BUG();
+ }
+ if (hdr->offset_free_uncached > hdr->size) {
+ LOG_ERR("Smem partition %d uncached heap exceeds size\n", num);
+ BUG();
+ }
+ if (hdr->offset_free_cached > hdr->size) {
+ LOG_ERR("Smem partition %d cached heap exceeds size\n", num);
+ BUG();
+ }
+ if (hdr->host0 != SMEM_APPS && hdr->host1 != SMEM_APPS) {
+ LOG_ERR("Smem partition %d hosts don't match TOC\n", num);
+ BUG();
+ }
+ if (hdr->host0 != remote_host && hdr->host1 != remote_host) {
+ LOG_ERR("Smem partition %d hosts don't match TOC\n", num);
+ BUG();
+ }
+
+ partitions[remote_host].partition_num = num;
+ partitions[remote_host].offset = entry->offset;
+ partitions[remote_host].size_cacheline = entry->size_cacheline;
+ SMEM_INFO("Partition %d offset:%x remote:%d\n", num, entry->offset,
+ remote_host);
+}
+
+/**
+ * smem_init_security - Init local support for secured smem
+ *
+ * Looks for a valid security TOC, and if one is found, parses it looking for
+ * partitions that apps can access. If any such partitions are found, do the
+ * required local initialization to support them. Assumes smem_areas is inited
+ * and smem_area[0] corresponds to the smem region with the TOC.
+ */
+static void smem_init_security(void)
+{
+ struct smem_toc *toc;
+ uint32_t i;
+
+ SMEM_DBG("%s\n", __func__);
+
+ toc = smem_areas[0].virt_addr + smem_areas[0].size - 4 * 1024;
+
+ if (toc->identifier != SMEM_TOC_IDENTIFIER) {
+ LOG_ERR("%s failed: invalid TOC magic\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < toc->num_entries; ++i) {
+ SMEM_DBG("Partition %d host0:%d host1:%d\n", i,
+ toc->entry[i].host0,
+ toc->entry[i].host1);
+
+ if (toc->entry[i].host0 == SMEM_APPS ||
+ toc->entry[i].host1 == SMEM_APPS)
+ smem_init_security_partition(&toc->entry[i], i);
+ }
+
+ SMEM_DBG("%s done\n", __func__);
+}
+
static int msm_smem_probe(struct platform_device *pdev)
{
char *key;
@@ -558,6 +1219,7 @@
struct ramdump_segment *ramdump_segments_tmp = NULL;
struct smem_area *smem_areas_tmp = NULL;
int smem_idx = 0;
+ bool security_enabled;
if (!smem_initialized_check())
return -ENODEV;
@@ -565,7 +1227,7 @@
key = "irq-reg-base";
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
if (!r) {
- pr_err("%s: missing '%s'\n", __func__, key);
+ LOG_ERR("%s: missing '%s'\n", __func__, key);
return -ENODEV;
}
@@ -580,7 +1242,7 @@
++num_smem_areas;
if (num_smem_areas > 999) {
- pr_err("%s: max num aux mem regions reached\n",
+ LOG_ERR("%s: max num aux mem regions reached\n",
__func__);
break;
}
@@ -589,14 +1251,14 @@
key = "smem";
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
if (!r) {
- pr_err("%s: missing '%s'\n", __func__, key);
+ LOG_ERR("%s: missing '%s'\n", __func__, key);
return -ENODEV;
}
smem_areas_tmp = kmalloc_array(num_smem_areas, sizeof(struct smem_area),
GFP_KERNEL);
if (!smem_areas_tmp) {
- pr_err("%s: smem areas kmalloc failed\n", __func__);
+ LOG_ERR("%s: smem areas kmalloc failed\n", __func__);
ret = -ENOMEM;
goto free_smem_areas;
}
@@ -604,7 +1266,7 @@
ramdump_segments_tmp = kmalloc_array(num_smem_areas,
sizeof(struct ramdump_segment), GFP_KERNEL);
if (!ramdump_segments_tmp) {
- pr_err("%s: ramdump segment kmalloc failed\n", __func__);
+ LOG_ERR("%s: ramdump segment kmalloc failed\n", __func__);
ret = -ENOMEM;
goto free_smem_areas;
}
@@ -640,7 +1302,7 @@
smem_areas_tmp[smem_idx].virt_addr);
if (!smem_areas_tmp[smem_idx].virt_addr) {
- pr_err("%s: ioremap_nocache() of addr:%pa size: %pa\n",
+ LOG_ERR("%s: ioremap_nocache() of addr:%pa size: %pa\n",
__func__,
&smem_areas_tmp[smem_idx].phys_addr,
&smem_areas_tmp[smem_idx].size);
@@ -651,7 +1313,8 @@
if (OVERFLOW_ADD_UNSIGNED(uintptr_t,
(uintptr_t)smem_areas_tmp[smem_idx].virt_addr,
smem_areas_tmp[smem_idx].size)) {
- pr_err("%s: invalid virtual address block %i: %p:%pa\n",
+ LOG_ERR(
+ "%s: invalid virtual address block %i: %p:%pa\n",
__func__, smem_idx,
smem_areas_tmp[smem_idx].virt_addr,
&smem_areas_tmp[smem_idx].size);
@@ -662,18 +1325,26 @@
++smem_idx;
if (smem_idx > 999) {
- pr_err("%s: max num aux mem regions reached\n",
+ LOG_ERR("%s: max num aux mem regions reached\n",
__func__);
break;
}
}
- ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
- if (ret)
- pr_err("%s: of_platform_populate failed %d\n", __func__, ret);
-
smem_areas = smem_areas_tmp;
smem_ramdump_segments = ramdump_segments_tmp;
+
+ key = "mpu-enabled";
+ security_enabled = of_property_read_bool(pdev->dev.of_node, key);
+ if (security_enabled) {
+ SMEM_INFO("smem security enabled\n");
+ smem_init_security();
+ }
+
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret)
+ LOG_ERR("%s: of_platform_populate failed %d\n", __func__, ret);
+
return 0;
free_smem_areas:
@@ -710,15 +1381,21 @@
registered = true;
+ smem_ipc_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smem");
+ if (!smem_ipc_log_ctx) {
+ pr_err("%s: unable to create logging context\n", __func__);
+ msm_smem_debug_mask = 0;
+ }
+
rc = init_smem_remote_spinlock();
if (rc) {
- pr_err("%s: remote spinlock init failed %d\n", __func__, rc);
+ LOG_ERR("%s: remote spinlock init failed %d\n", __func__, rc);
return rc;
}
rc = platform_driver_register(&msm_smem_driver);
if (rc) {
- pr_err("%s: msm_smem_driver register failed %d\n",
+ LOG_ERR("%s: msm_smem_driver register failed %d\n",
__func__, rc);
return rc;
}
diff --git a/arch/arm/mach-msm/smem_private.h b/arch/arm/mach-msm/smem_private.h
index ceb8028..3fa842f 100644
--- a/arch/arm/mach-msm/smem_private.h
+++ b/arch/arm/mach-msm/smem_private.h
@@ -76,4 +76,21 @@
* @nb: Notifier block to be unregistered
*/
int smem_module_init_notifier_unregister(struct notifier_block *nb);
+
+/**
+ * smem_get_free_space() - Get the available allocation free space for a
+ * partition
+ *
+ * @to_proc: remote SMEM host. Determines the applicable partition
+ * @returns: size in bytes available to allocate
+ *
+ * Helper function for SMD so that SMD only scans the channel allocation
+ * table for a partition when it is reasonably certain that a channel has
+ * actually been created, because scanning can be expensive. Creating a channel
+ * will consume some of the free space in a partition, so SMD can compare the
+ * last free space size against the current free space size to determine if
+ * a channel may have been created. SMD can't do this directly, because the
+ * necessary partition internals are restricted to just SMEM.
+ */
+unsigned smem_get_free_space(unsigned to_proc);
#endif /* _ARCH_ARM_MACH_MSM_SMEM_PRIVATE_H_ */
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e82ea2b..34ae4e6 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -734,6 +734,46 @@
#endif
}
+#define MLK(b, t) b, t, ((t) - (b)) >> 10
+#define MLM(b, t) b, t, ((t) - (b)) >> 20
+#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
+
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+void print_vmalloc_lowmem_info(void)
+{
+ int i;
+ void *va_start, *va_end;
+
+ printk(KERN_NOTICE
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM(VMALLOC_START, VMALLOC_END));
+
+ for (i = meminfo.nr_banks - 1; i >= 0; i--) {
+ if (!meminfo.bank[i].highmem) {
+ va_start = __va(meminfo.bank[i].start);
+ va_end = __va(meminfo.bank[i].start +
+ meminfo.bank[i].size);
+ printk(KERN_NOTICE
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)va_start, (unsigned long)va_end));
+ }
+ if (i && ((meminfo.bank[i-1].start + meminfo.bank[i-1].size) !=
+ meminfo.bank[i].start)) {
+ if (meminfo.bank[i-1].start + meminfo.bank[i-1].size
+ <= MAX_HOLE_ADDRESS) {
+ va_start = __va(meminfo.bank[i-1].start
+ + meminfo.bank[i-1].size);
+ va_end = __va(meminfo.bank[i].start);
+ printk(KERN_NOTICE
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM((unsigned long)va_start,
+ (unsigned long)va_end));
+ }
+ }
+ }
+}
+#endif
+
/*
* mem_init() marks the free areas in the mem_map and tells us how much
* memory is free. This is done after various parts of the system have
@@ -814,10 +854,6 @@
reserved_pages << (PAGE_SHIFT-10),
totalhigh_pages << (PAGE_SHIFT-10));
-#define MLK(b, t) b, t, ((t) - (b)) >> 10
-#define MLM(b, t) b, t, ((t) - (b)) >> 20
-#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
-
printk(KERN_NOTICE "Virtual kernel memory layout:\n"
" vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
#ifdef CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS
@@ -827,20 +863,7 @@
" DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
" ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
#endif
- " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
- " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
- " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#ifdef CONFIG_HIGHMEM
- " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#endif
-#ifdef CONFIG_MODULES
- " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
-#endif
- " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
- " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
- " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
- " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
-
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n",
MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
(PAGE_SIZE)),
#ifdef CONFIG_ARM_USE_USER_ACCESSIBLE_TIMERS
@@ -852,25 +875,39 @@
MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
MLK(ITCM_OFFSET, (unsigned long) itcm_end),
#endif
- MLK(FIXADDR_START, FIXADDR_TOP),
- MLM(VMALLOC_START, VMALLOC_END),
- MLM(PAGE_OFFSET, (unsigned long)high_memory),
+ MLK(FIXADDR_START, FIXADDR_TOP));
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ print_vmalloc_lowmem_info();
+#else
+ printk(KERN_NOTICE
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n",
+ MLM(VMALLOC_START, VMALLOC_END),
+ MLM(PAGE_OFFSET, (unsigned long)high_memory));
+#endif
#ifdef CONFIG_HIGHMEM
- MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
+ printk(KERN_NOTICE
+ " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+#ifdef CONFIG_MODULES
+ " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+ " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
+#ifdef CONFIG_HIGHMEM
+ MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
(PAGE_SIZE)),
#endif
#ifdef CONFIG_MODULES
- MLM(MODULES_VADDR, MODULES_END),
+ MLM(MODULES_VADDR, MODULES_END),
#endif
- MLK_ROUNDUP(_text, _etext),
- MLK_ROUNDUP(__init_begin, __init_end),
- MLK_ROUNDUP(_sdata, _edata),
- MLK_ROUNDUP(__bss_start, __bss_stop));
-
-#undef MLK
-#undef MLM
-#undef MLK_ROUNDUP
+ MLK_ROUNDUP(_text, _etext),
+ MLK_ROUNDUP(__init_begin, __init_end),
+ MLK_ROUNDUP(_sdata, _edata),
+ MLK_ROUNDUP(__bss_start, __bss_stop));
/*
* Check boundaries twice: Some fundamental inconsistencies can
@@ -878,7 +915,7 @@
*/
#ifdef CONFIG_MMU
BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
- BUG_ON(TASK_SIZE > MODULES_VADDR);
+ BUG_ON(TASK_SIZE > MODULES_VADDR);
#endif
#ifdef CONFIG_HIGHMEM
@@ -897,6 +934,9 @@
}
}
+#undef MLK
+#undef MLM
+#undef MLK_ROUNDUP
void free_initmem(void)
{
unsigned long reclaimed_initmem;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e5a60a9..509f59d 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -871,6 +871,7 @@
{
struct map_desc *md;
struct vm_struct *vm;
+ int rc = 0;
if (!nr)
return;
@@ -881,11 +882,13 @@
create_mapping(md);
vm->addr = (void *)(md->virtual & PAGE_MASK);
vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
- vm->phys_addr = __pfn_to_phys(md->pfn);
- vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+ vm->phys_addr = __pfn_to_phys(md->pfn);
+ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->flags |= VM_ARM_MTYPE(md->type);
vm->caller = iotable_init;
- vm_area_add_early(vm++);
+ rc = vm_area_check_early(vm);
+ if (!rc)
+ vm_area_add_early(vm++);
}
}
@@ -999,6 +1002,18 @@
{
int i, j, highmem = 0;
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ unsigned long hole_start;
+ for (i = 0; i < (meminfo.nr_banks - 1); i++) {
+ hole_start = meminfo.bank[i].start + meminfo.bank[i].size;
+ if (hole_start != meminfo.bank[i+1].start) {
+ if (hole_start <= MAX_HOLE_ADDRESS) {
+ vmalloc_min = (void *) (vmalloc_min +
+ (meminfo.bank[i+1].start - hole_start));
+ }
+ }
+ }
+#endif
#ifdef CONFIG_DONT_MAP_HOLE_AFTER_MEMBANK0
find_memory_hole();
#endif
@@ -1382,12 +1397,21 @@
static void __init map_lowmem(void)
{
struct memblock_region *reg;
+ struct vm_struct *vm;
+ phys_addr_t start;
+ phys_addr_t end;
+ unsigned long vaddr;
+ unsigned long pfn;
+ unsigned long length;
+ unsigned int type;
+ int nr = 0;
/* Map all the lowmem memory banks. */
for_each_memblock(memory, reg) {
- phys_addr_t start = reg->base;
- phys_addr_t end = start + reg->size;
struct map_desc map;
+ nr++;
+ start = reg->base;
+ end = start + reg->size;
if (end > arm_lowmem_limit)
end = arm_lowmem_limit;
@@ -1440,6 +1464,32 @@
create_mapping(&map);
}
+
+ vm = early_alloc_aligned(sizeof(*vm) * nr, __alignof__(*vm));
+
+ for_each_memblock(memory, reg) {
+
+ start = reg->base;
+ end = start + reg->size;
+
+ if (end > arm_lowmem_limit)
+ end = arm_lowmem_limit;
+ if (start >= end)
+ break;
+
+ pfn = __phys_to_pfn(start);
+ vaddr = __phys_to_virt(start);
+ length = end - start;
+ type = MT_MEMORY;
+
+ vm->addr = (void *)(vaddr & PAGE_MASK);
+ vm->size = PAGE_ALIGN(length + (vaddr & ~PAGE_MASK));
+ vm->phys_addr = __pfn_to_phys(pfn);
+ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+ vm->flags |= VM_ARM_MTYPE(type);
+ vm->caller = map_lowmem;
+ vm_area_add_early(vm++);
+ }
}
/*
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index 415c73e..90451ca 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -136,10 +136,28 @@
buf = __ion_secure_cma_allocate(heap, buffer, len, align, flags);
if (buf) {
+ int ret;
+
buf->secure.want_delayed_unsecure = 0;
atomic_set(&buf->secure.secure_cnt, 0);
mutex_init(&buf->secure.lock);
buf->secure.is_secure = 1;
+ buf->secure.ignore_check = true;
+
+ /*
+ * make sure the size is set before trying to secure
+ */
+ buffer->size = len;
+ ret = ion_cp_secure_buffer(buffer, ION_CP_V2, 0, 0);
+ if (ret) {
+ /*
+ * Don't treat the secure buffer failing here as an
+ * error for backwards compatibility reasons. If
+ * the secure fails, the map will also fail so there
+ * is no security risk.
+ */
+ pr_debug("%s: failed to secure buffer\n", __func__);
+ }
return 0;
} else {
return -ENOMEM;
@@ -153,6 +171,8 @@
struct ion_secure_cma_buffer_info *info = buffer->priv_virt;
dev_dbg(dev, "Release buffer %p\n", buffer);
+
+ ion_cp_unsecure_buffer(buffer, 1);
/* release memory */
dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
sg_free_table(info->table);
diff --git a/drivers/gpu/ion/msm/ion_cp_common.c b/drivers/gpu/ion/msm/ion_cp_common.c
index d315fc4..7ffab09 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.c
+++ b/drivers/gpu/ion/msm/ion_cp_common.c
@@ -286,7 +286,7 @@
goto out_unlock;
}
- if (atomic_read(&buf->secure_cnt)) {
+ if (atomic_read(&buf->secure_cnt) && !buf->ignore_check) {
if (buf->version != version || buf->data != data) {
pr_err("%s: Trying to re-secure buffer with different values",
__func__);
diff --git a/drivers/gpu/ion/msm/ion_cp_common.h b/drivers/gpu/ion/msm/ion_cp_common.h
index 8ae19be..ded6af9 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.h
+++ b/drivers/gpu/ion/msm/ion_cp_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,6 +38,10 @@
struct mutex lock;
int version;
void *data;
+ /*
+ * secure is happening at allocation time, ignore version/data check
+ */
+ bool ignore_check;
};
#if defined(CONFIG_ION_MSM)
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 6507852..a837574 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -63,7 +63,6 @@
#define ADRENO_DEFAULT_PWRSCALE_POLICY NULL
#endif
-void adreno_debugfs_init(struct kgsl_device *device);
#define ADRENO_ISTORE_START 0x5000 /* Istore offset */
@@ -749,4 +748,11 @@
return ADRENO_REG_REGISTER_MAX;
return adreno_dev->gpudev->reg_offsets->offsets[offset_name];
}
+
+#ifdef CONFIG_DEBUG_FS
+void adreno_debugfs_init(struct kgsl_device *device);
+#else
+static inline void adreno_debugfs_init(struct kgsl_device *device) { }
+#endif
+
#endif /*__ADRENO_H */
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index fc98d86..a7d1b7f 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -23,8 +23,6 @@
#include "a2xx_reg.h"
-unsigned int kgsl_cff_dump_enable;
-
DEFINE_SIMPLE_ATTRIBUTE(kgsl_cff_dump_enable_fops, kgsl_cff_dump_enable_get,
kgsl_cff_dump_enable_set, "%llu\n");
diff --git a/drivers/gpu/msm/adreno_profile.h b/drivers/gpu/msm/adreno_profile.h
index d91b09b..7e1ccb2 100644
--- a/drivers/gpu/msm/adreno_profile.h
+++ b/drivers/gpu/msm/adreno_profile.h
@@ -61,6 +61,7 @@
#define ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS (ADRENO_PROFILE_LOG_BUF_SIZE / \
sizeof(unsigned int))
+#ifdef CONFIG_DEBUG_FS
void adreno_profile_init(struct kgsl_device *device);
void adreno_profile_close(struct kgsl_device *device);
int adreno_profile_process_results(struct kgsl_device *device);
@@ -70,6 +71,22 @@
void adreno_profile_postib_processing(struct kgsl_device *device,
unsigned int *cmd_flags, unsigned int **rbptr,
unsigned int *cmds_gpu);
+#else
+static inline void adreno_profile_init(struct kgsl_device *device) { }
+static inline void adreno_profile_close(struct kgsl_device *device) { }
+static inline int adreno_profile_process_results(struct kgsl_device *device)
+{
+ return 0;
+}
+
+static inline void adreno_profile_preib_processing(struct kgsl_device *device,
+ unsigned int context_id, unsigned int *cmd_flags,
+ unsigned int **rbptr, unsigned int *cmds_gpu) { }
+
+static inline void adreno_profile_postib_processing(struct kgsl_device *device,
+ unsigned int *cmd_flags, unsigned int **rbptr,
+ unsigned int *cmds_gpu) { }
+#endif
static inline bool adreno_profile_enabled(struct adreno_profile *profile)
{
diff --git a/drivers/gpu/msm/kgsl_log.h b/drivers/gpu/msm/kgsl_log.h
index a7832e4..94649bd 100644
--- a/drivers/gpu/msm/kgsl_log.h
+++ b/drivers/gpu/msm/kgsl_log.h
@@ -13,8 +13,6 @@
#ifndef __KGSL_LOG_H
#define __KGSL_LOG_H
-extern unsigned int kgsl_cff_dump_enable;
-
#define KGSL_LOG_INFO(dev, lvl, fmt, args...) \
do { \
if ((lvl) >= 6) \
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 06ca31c..4dbe5c1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -399,7 +399,6 @@
#if defined(CONFIG_SECURE_TOUCH)
atomic_t st_enabled;
atomic_t st_pending_irqs;
- struct completion st_completion;
struct completion st_powerdown;
#endif
};
@@ -1002,11 +1001,16 @@
}
#if defined(CONFIG_SECURE_TOUCH)
+static void mxt_secure_touch_notify(struct mxt_data *data)
+{
+ sysfs_notify(&data->client->dev.kobj, NULL, "secure_touch");
+}
+
static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
{
if (atomic_read(&data->st_enabled)) {
if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0)
- complete(&data->st_completion);
+ mxt_secure_touch_notify(data);
return IRQ_HANDLED;
}
return IRQ_NONE;
@@ -1998,7 +2002,7 @@
pm_runtime_put(data->client->adapter->dev.parent);
atomic_set(&data->st_enabled, 0);
- complete(&data->st_completion);
+ mxt_secure_touch_notify(data);
mxt_interrupt(data->client->irq, data);
complete(&data->st_powerdown);
break;
@@ -2013,7 +2017,6 @@
err = -EIO;
break;
}
- INIT_COMPLETION(data->st_completion);
INIT_COMPLETION(data->st_powerdown);
atomic_set(&data->st_enabled, 1);
synchronize_irq(data->client->irq);
@@ -2032,20 +2035,18 @@
struct device_attribute *attr, char *buf)
{
struct mxt_data *data = dev_get_drvdata(dev);
- int err;
+ int val = 0;
if (atomic_read(&data->st_enabled) == 0)
return -EBADF;
- err = wait_for_completion_interruptible(&data->st_completion);
-
- if (err)
- return err;
-
- if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
+ if (atomic_cmpxchg(&data->st_pending_irqs, -1, 0) == -1)
return -EINVAL;
- return scnprintf(buf, PAGE_SIZE, "%u", 1);
+ if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) == 1)
+ val = 1;
+
+ return scnprintf(buf, PAGE_SIZE, "%u", val);
}
static DEVICE_ATTR(secure_touch_enable, 0666, mxt_secure_touch_enable_show,
@@ -2074,15 +2075,17 @@
#if defined(CONFIG_SECURE_TOUCH)
-static void mxt_secure_touch_stop(struct mxt_data *data)
+static void mxt_secure_touch_stop(struct mxt_data *data, int blocking)
{
if (atomic_read(&data->st_enabled)) {
- complete(&data->st_completion);
- wait_for_completion_interruptible(&data->st_powerdown);
+ atomic_set(&data->st_pending_irqs, -1);
+ mxt_secure_touch_notify(data);
+ if (blocking)
+ wait_for_completion_interruptible(&data->st_powerdown);
}
}
#else
-static void mxt_secure_touch_stop(struct mxt_data *data)
+static void mxt_secure_touch_stop(struct mxt_data *data, int blocking)
{
}
#endif
@@ -2090,7 +2093,7 @@
static int mxt_start(struct mxt_data *data)
{
int error;
- mxt_secure_touch_stop(data);
+ mxt_secure_touch_stop(data, 1);
/* restore the old power state values and reenable touch */
error = __mxt_write_reg(data->client, data->t7_start_addr,
@@ -2108,7 +2111,7 @@
{
int error;
u8 t7_data[T7_DATA_SIZE] = {0};
- mxt_secure_touch_stop(data);
+ mxt_secure_touch_stop(data, 1);
error = __mxt_write_reg(data->client, data->t7_start_addr,
T7_DATA_SIZE, t7_data);
@@ -2523,7 +2526,7 @@
/* calibrate */
if (data->pdata->need_calibration) {
- mxt_secure_touch_stop(data);
+ mxt_secure_touch_stop(data, 1);
error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
MXT_COMMAND_CALIBRATE, 1);
if (error < 0)
@@ -2836,13 +2839,14 @@
struct mxt_data *mxt_dev_data =
container_of(self, struct mxt_data, fb_notif);
- if (evdata && evdata->data && event == FB_EVENT_BLANK && mxt_dev_data &&
- mxt_dev_data->client) {
- blank = evdata->data;
- if (*blank == FB_BLANK_UNBLANK)
- mxt_resume(&mxt_dev_data->client->dev);
- else if (*blank == FB_BLANK_POWERDOWN)
- mxt_suspend(&mxt_dev_data->client->dev);
+ if (evdata && evdata->data && mxt_dev_data && mxt_dev_data->client) {
+ if (event == FB_EVENT_BLANK) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK)
+ mxt_resume(&mxt_dev_data->client->dev);
+ else if (*blank == FB_BLANK_POWERDOWN)
+ mxt_suspend(&mxt_dev_data->client->dev);
+ }
}
return 0;
@@ -2867,7 +2871,6 @@
#if defined(CONFIG_SECURE_TOUCH)
static void __devinit mxt_secure_touch_init(struct mxt_data *data)
{
- init_completion(&data->st_completion);
init_completion(&data->st_powerdown);
}
#else
diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c
index bdac3fd..aa8159f 100644
--- a/drivers/input/touchscreen/gt9xx/goodix_tool.c
+++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c
@@ -22,6 +22,7 @@
*/
#include "gt9xx.h"
+#include <linux/mutex.h>
#define DATA_LENGTH_UINT 512
#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8 *))
@@ -53,6 +54,8 @@
static struct proc_dir_entry *goodix_proc_entry;
+static struct mutex lock;
+
static s32 goodix_tool_write(struct file *filp, const char __user *buff,
unsigned long len, void *data);
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
@@ -188,7 +191,7 @@
s32 init_wr_node(struct i2c_client *client)
{
- s32 i;
+ u8 i;
gt_client = client;
memset(&cmd_head, 0, sizeof(cmd_head));
@@ -202,8 +205,8 @@
i--;
}
if (i) {
- DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH;
- GTP_INFO("Applied memory size:%d.", DATA_LENGTH);
+ DATA_LENGTH = i * DATA_LENGTH_UINT;
+ dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH);
} else {
GTP_ERROR("Apply for memory failed.");
return FAIL;
@@ -214,8 +217,9 @@
register_i2c_func();
+ mutex_init(&lock);
tool_set_proc_name(procname);
- goodix_proc_entry = create_proc_entry(procname, 0666, NULL);
+ goodix_proc_entry = create_proc_entry(procname, 0660, NULL);
if (goodix_proc_entry == NULL) {
GTP_ERROR("Couldn't create proc entry!");
return FAIL;
@@ -334,9 +338,13 @@
GTP_DEBUG_FUNC();
GTP_DEBUG_ARRAY((u8 *)buff, len);
+ mutex_lock(&lock);
ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH);
- if (ret)
+ if (ret) {
GTP_ERROR("copy_from_user failed.");
+ ret = -EACCES;
+ goto exit;
+ }
GTP_DEBUG("wr :0x%02x.", cmd_head.wr);
GTP_DEBUG("flag:0x%02x.", cmd_head.flag);
@@ -354,6 +362,19 @@
GTP_DEBUG("len:%d.", (s32)len);
GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]);
+ if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) {
+ pr_err("data len %d > data buff %d, rejected!\n",
+ cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH));
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (cmd_head.addr_len > GTP_ADDR_LENGTH) {
+ pr_err(" addr len %d > data buff %d, rejected!\n",
+ cmd_head.addr_len, GTP_ADDR_LENGTH);
+ ret = -EINVAL;
+ goto exit;
+ }
+
if (cmd_head.wr == 1) {
/* copy_from_user(&cmd_head.data[cmd_head.addr_len],
&buff[CMD_HEAD_LENGTH], cmd_head.data_len); */
@@ -373,7 +394,8 @@
if (cmd_head.flag == 1) {
if (FAIL == comfirm()) {
GTP_ERROR("[WRITE]Comfirm fail!");
- return FAIL;
+ ret = -EINVAL;
+ goto exit;
}
} else if (cmd_head.flag == 2) {
/* Need interrupt! */
@@ -382,7 +404,8 @@
&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
cmd_head.data_len + cmd_head.addr_len) <= 0) {
GTP_ERROR("[WRITE]Write data failed!");
- return FAIL;
+ ret = -EIO;
+ goto exit;
}
GTP_DEBUG_ARRAY(
@@ -391,7 +414,8 @@
if (cmd_head.delay)
msleep(cmd_head.delay);
- return cmd_head.data_len + CMD_HEAD_LENGTH;
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
+ goto exit;
} else if (cmd_head.wr == 3) { /* Write ic type */
ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH],
@@ -399,30 +423,40 @@
if (ret)
GTP_ERROR("copy_from_user failed.");
+ if (cmd_head.data_len > sizeof(IC_TYPE)) {
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
+ cmd_head.data_len, sizeof(IC_TYPE));
+ ret = -EINVAL;
+ goto exit;
+ }
memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
register_i2c_func();
- return cmd_head.data_len + CMD_HEAD_LENGTH;
- } else if (cmd_head.wr == 3) {
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
+ goto exit;
+ } else if (cmd_head.wr == 5) {
/* memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); */
- return cmd_head.data_len + CMD_HEAD_LENGTH;
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
+ goto exit;
} else if (cmd_head.wr == 7) { /* disable irq! */
gtp_irq_disable(i2c_get_clientdata(gt_client));
#if GTP_ESD_PROTECT
gtp_esd_switch(gt_client, SWITCH_OFF);
#endif
- return CMD_HEAD_LENGTH;
+ ret = CMD_HEAD_LENGTH;
+ goto exit;
} else if (cmd_head.wr == 9) { /* enable irq! */
gtp_irq_enable(i2c_get_clientdata(gt_client));
#if GTP_ESD_PROTECT
gtp_esd_switch(gt_client, SWITCH_ON);
#endif
- return CMD_HEAD_LENGTH;
+ ret = CMD_HEAD_LENGTH;
+ goto exit;
} else if (cmd_head.wr == 17) {
struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
@@ -436,27 +470,41 @@
ts->gtp_rawdiff_mode = false;
GTP_DEBUG("gtp leave rawdiff.");
}
- return CMD_HEAD_LENGTH;
+ ret = CMD_HEAD_LENGTH;
+ goto exit;
}
#ifdef UPDATE_FUNCTIONS
else if (cmd_head.wr == 11) { /* Enter update mode! */
- if (FAIL == gup_enter_update_mode(gt_client))
- return FAIL;
+ if (FAIL == gup_enter_update_mode(gt_client)) {
+ ret = -EBUSY;
+ goto exit;
+ }
} else if (cmd_head.wr == 13) { /* Leave update mode! */
gup_leave_update_mode();
} else if (cmd_head.wr == 15) { /* Update firmware! */
show_len = 0;
total_len = 0;
+ if (cmd_head.data_len + 1 > DATA_LENGTH) {
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
+ cmd_head.data_len + 1, DATA_LENGTH);
+ ret = -EINVAL;
+ goto exit;
+ }
memset(cmd_head.data, 0, cmd_head.data_len + 1);
memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH],
cmd_head.data_len);
- if (FAIL == gup_update_proc((void *)cmd_head.data))
- return FAIL;
+ if (FAIL == gup_update_proc((void *)cmd_head.data)) {
+ ret = -EBUSY;
+ goto exit;
+ }
}
#endif
+ ret = CMD_HEAD_LENGTH;
- return CMD_HEAD_LENGTH;
+exit:
+ mutex_unlock(&lock);
+ return ret;
}
/*******************************************************
@@ -470,10 +518,14 @@
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
+ s32 ret;
GTP_DEBUG_FUNC();
+ mutex_lock(&lock);
if (cmd_head.wr % 2) {
- return FAIL;
+ pr_err("<< [READ]command head wrong\n");
+ ret = -EINVAL;
+ goto exit;
} else if (!cmd_head.wr) {
u16 len = 0;
s16 data_len = 0;
@@ -482,7 +534,8 @@
if (cmd_head.flag == 1) {
if (FAIL == comfirm()) {
GTP_ERROR("[READ]Comfirm fail!");
- return FAIL;
+ ret = -EINVAL;
+ goto exit;
}
} else if (cmd_head.flag == 2) {
/* Need interrupt! */
@@ -505,11 +558,12 @@
else
len = data_len;
- data_len -= DATA_LENGTH;
+ data_len -= len;
if (tool_i2c_read(cmd_head.data, len) <= 0) {
GTP_ERROR("[READ]Read data failed!");
- return FAIL;
+ ret = -EINVAL;
+ goto exit;
}
memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH],
len);
@@ -525,15 +579,14 @@
GTP_DEBUG("Return ic type:%s len:%d.", page,
(s32)cmd_head.data_len);
- return cmd_head.data_len;
+ ret = cmd_head.data_len;
+ goto exit;
/* return sizeof(IC_TYPE_NAME); */
} else if (cmd_head.wr == 4) {
page[0] = show_len >> 8;
page[1] = show_len & 0xff;
page[2] = total_len >> 8;
page[3] = total_len & 0xff;
-
- return cmd_head.data_len;
} else if (6 == cmd_head.wr) {
/* Read error code! */
} else if (8 == cmd_head.wr) { /*Read driver version */
@@ -544,6 +597,9 @@
memcpy(page, GTP_DRIVER_VERSION, tmp_len);
page[tmp_len] = 0;
}
+ ret = cmd_head.data_len;
- return cmd_head.data_len;
+exit:
+ mutex_unlock(&lock);
+ return ret;
}
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 0a92d51..70c1307 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -2031,6 +2031,9 @@
static void synaptics_rmi4_fwu_attn(struct synaptics_rmi4_data *rmi4_data,
unsigned char intr_mask)
{
+ if (!fwu)
+ return;
+
if (fwu->intr_mask & intr_mask)
fwu->interrupt_flag = true;
@@ -2116,6 +2119,7 @@
dev_err(&rmi4_data->i2c_client->dev,
"%s: Failed to alloc mem for fwu\n",
__func__);
+ retval = -ENOMEM;
goto exit;
}
@@ -2141,10 +2145,12 @@
dev_dbg(&rmi4_data->i2c_client->dev,
"%s: Failed to read PDT properties, assuming 0x00\n",
__func__);
+ goto exit_free_mem;
} else if (pdt_props.has_bsr) {
dev_err(&rmi4_data->i2c_client->dev,
"%s: Reflash for LTS not currently supported\n",
__func__);
+ retval = -EINVAL;
goto exit_free_mem;
}
@@ -2243,7 +2249,7 @@
fwu = NULL;
exit:
- return 0;
+ return retval;
}
static void synaptics_rmi4_fwu_remove(struct synaptics_rmi4_data *rmi4_data)
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index aec655c..4e75971 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -2378,8 +2378,12 @@
link) {
if ((exp_fhandler->func_init != NULL) &&
(exp_fhandler->inserted == false)) {
- exp_fhandler->func_init(rmi4_data);
- exp_fhandler->inserted = true;
+ if (exp_fhandler->func_init(rmi4_data) < 0) {
+ list_del(&exp_fhandler->link);
+ kfree(exp_fhandler);
+ } else {
+ exp_fhandler->inserted = true;
+ }
} else if ((exp_fhandler->func_init == NULL) &&
(exp_fhandler->inserted == true)) {
exp_fhandler->func_remove(rmi4_data);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index 32d74ba..16a1616 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -41,6 +41,7 @@
struct msm_actuator_move_params_t *move_params)
{
int32_t rc = 0;
+ struct msm_camera_i2c_reg_setting reg_setting;
CDBG("Enter\n");
if (a_ctrl->curr_step_pos != 0) {
@@ -49,10 +50,12 @@
a_ctrl->initial_code, 0, 0);
a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
a_ctrl->initial_code, 0, 0);
+ reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
+ reg_setting.data_type = a_ctrl->i2c_data_type;
+ reg_setting.size = a_ctrl->i2c_tbl_index;
rc = a_ctrl->i2c_client.i2c_func_tbl->
i2c_write_table_w_microdelay(
- &a_ctrl->i2c_client, a_ctrl->i2c_reg_tbl,
- a_ctrl->i2c_tbl_index, a_ctrl->i2c_data_type);
+ &a_ctrl->i2c_client, ®_setting);
if (rc < 0) {
pr_err("%s: i2c write error:%d\n",
__func__, rc);
@@ -73,7 +76,7 @@
uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
uint16_t value = 0;
uint32_t size = a_ctrl->reg_tbl_size, i = 0;
- struct msm_camera_i2c_reg_tbl *i2c_tbl = a_ctrl->i2c_reg_tbl;
+ struct msm_camera_i2c_reg_array *i2c_tbl = a_ctrl->i2c_reg_tbl;
CDBG("Enter\n");
for (i = 0; i < size; i++) {
if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
@@ -195,6 +198,7 @@
int32_t dest_step_position = move_params->dest_step_pos;
int32_t rc = 0;
int32_t num_steps = move_params->num_steps;
+ struct msm_camera_i2c_reg_setting reg_setting;
CDBG("Enter\n");
if (num_steps == 0)
@@ -206,10 +210,11 @@
a_ctrl->region_params[0].code_per_step),
move_params->ringing_params[0].hw_params, 0);
+ reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
+ reg_setting.data_type = a_ctrl->i2c_data_type;
+ reg_setting.size = a_ctrl->i2c_tbl_index;
rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay(
- &a_ctrl->i2c_client,
- a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
- a_ctrl->i2c_data_type);
+ &a_ctrl->i2c_client, ®_setting);
if (rc < 0) {
pr_err("i2c write error:%d\n", rc);
return rc;
@@ -233,6 +238,7 @@
uint16_t curr_lens_pos = 0;
int dir = move_params->dir;
int32_t num_steps = move_params->num_steps;
+ struct msm_camera_i2c_reg_setting reg_setting;
CDBG("called, dir %d, num_steps %d\n", dir, num_steps);
@@ -280,10 +286,11 @@
a_ctrl->curr_step_pos = target_step_pos;
}
+ reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
+ reg_setting.data_type = a_ctrl->i2c_data_type;
+ reg_setting.size = a_ctrl->i2c_tbl_index;
rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_write_table_w_microdelay(
- &a_ctrl->i2c_client,
- a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
- a_ctrl->i2c_data_type);
+ &a_ctrl->i2c_client, ®_setting);
if (rc < 0) {
pr_err("i2c write error:%d\n", rc);
return rc;
@@ -439,7 +446,7 @@
kfree(a_ctrl->i2c_reg_tbl);
a_ctrl->i2c_reg_tbl =
- kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
+ kmalloc(sizeof(struct msm_camera_i2c_reg_array) *
(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
if (!a_ctrl->i2c_reg_tbl) {
pr_err("kmalloc fail\n");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
index c4a4137..809c9cf 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.h
@@ -77,7 +77,7 @@
uint32_t total_steps;
uint16_t pwd_step;
uint16_t initial_code;
- struct msm_camera_i2c_reg_tbl *i2c_reg_tbl;
+ struct msm_camera_i2c_reg_array *i2c_reg_tbl;
uint16_t i2c_tbl_index;
enum cci_i2c_master_t cci_master;
uint32_t subdev_id;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index d11798e..968dcd7 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -26,6 +26,8 @@
#define V4L2_IDENT_CCI 50005
#define CCI_I2C_QUEUE_0_SIZE 64
#define CCI_I2C_QUEUE_1_SIZE 16
+#define CYCLES_PER_MICRO_SEC 4915
+#define CCI_MAX_DELAY 10000
#define CCI_TIMEOUT msecs_to_jiffies(100)
@@ -178,13 +180,13 @@
{
uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
int32_t rc = 0;
- uint32_t cmd = 0;
+ uint32_t cmd = 0, delay = 0;
uint8_t data[10];
uint16_t reg_addr = 0;
- struct msm_camera_cci_i2c_write_cfg *i2c_msg =
+ struct msm_camera_i2c_reg_setting *i2c_msg =
&c_ctrl->cfg.cci_i2c_write_cfg;
uint16_t cmd_size = i2c_msg->size;
- struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
+ struct msm_camera_i2c_reg_array *i2c_cmd = i2c_msg->reg_setting;
enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
if (i2c_cmd == NULL) {
@@ -213,6 +215,7 @@
while (cmd_size) {
CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
+ delay = i2c_cmd->delay;
data[i++] = CCI_I2C_WRITE_CMD;
if (i2c_cmd->reg_addr)
reg_addr = i2c_cmd->reg_addr;
@@ -257,6 +260,17 @@
CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
master * 0x200 + queue * 0x100);
}
+ if ((delay > 0) && (delay < CCI_MAX_DELAY)) {
+ cmd = (uint32_t)((delay * CYCLES_PER_MICRO_SEC) /
+ 0x100);
+ cmd <<= 4;
+ cmd |= CCI_I2C_WAIT_CMD;
+ CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n",
+ __func__, cmd);
+ msm_camera_io_w(cmd, cci_dev->base +
+ CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
+ master * 0x200 + queue * 0x100);
+ }
i = 0;
}
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
index 16edaae..6067f26 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
@@ -64,13 +64,6 @@
uint16_t i2c_queue;
};
-struct msm_camera_cci_i2c_write_cfg {
- struct msm_camera_i2c_reg_conf *reg_conf_tbl;
- enum msm_camera_i2c_reg_addr_type addr_type;
- enum msm_camera_i2c_data_type data_type;
- uint16_t size;
-};
-
struct msm_camera_cci_i2c_read_cfg {
uint16_t addr;
enum msm_camera_i2c_reg_addr_type addr_type;
@@ -90,7 +83,7 @@
struct msm_camera_cci_client *cci_info;
enum msm_cci_cmd_type cmd;
union {
- struct msm_camera_cci_i2c_write_cfg cci_i2c_write_cfg;
+ struct msm_camera_i2c_reg_setting cci_i2c_write_cfg;
struct msm_camera_cci_i2c_read_cfg cci_i2c_read_cfg;
struct msm_camera_cci_wait_sync_cfg cci_wait_sync_cfg;
struct msm_camera_cci_gpio_cfg gpio_cfg;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index 3792247..8d9274b 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -108,7 +108,7 @@
{
int32_t rc = -EFAULT;
struct msm_camera_cci_ctrl cci_ctrl;
- struct msm_camera_i2c_reg_conf reg_conf_tbl;
+ struct msm_camera_i2c_reg_array reg_conf_tbl;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
@@ -122,7 +122,7 @@
reg_conf_tbl.reg_data = data;
cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
cci_ctrl.cci_info = client->cci_client;
- cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = ®_conf_tbl;
+ cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = ®_conf_tbl;
cci_ctrl.cfg.cci_i2c_write_cfg.data_type = data_type;
cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
cci_ctrl.cfg.cci_i2c_write_cfg.size = 1;
@@ -142,7 +142,7 @@
int32_t rc = -EFAULT;
uint8_t i = 0;
struct msm_camera_cci_ctrl cci_ctrl;
- struct msm_camera_i2c_reg_conf reg_conf_tbl[num_byte];
+ struct msm_camera_i2c_reg_array reg_conf_tbl[num_byte];
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
@@ -152,13 +152,15 @@
S_I2C_DBG("%s reg addr = 0x%x num bytes: %d\n",
__func__, addr, num_byte);
memset(reg_conf_tbl, 0,
- num_byte * sizeof(struct msm_camera_i2c_reg_conf));
+ num_byte * sizeof(struct msm_camera_i2c_reg_array));
reg_conf_tbl[0].reg_addr = addr;
- for (i = 0; i < num_byte; i++)
+ for (i = 0; i < num_byte; i++) {
reg_conf_tbl[i].reg_data = data[i];
+ reg_conf_tbl[i].delay = 0;
+ }
cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
cci_ctrl.cci_info = client->cci_client;
- cci_ctrl.cfg.cci_i2c_write_cfg.reg_conf_tbl = reg_conf_tbl;
+ cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = reg_conf_tbl;
cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA;
cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
cci_ctrl.cfg.cci_i2c_write_cfg.size = num_byte;
@@ -173,10 +175,8 @@
struct msm_camera_i2c_client *client,
struct msm_camera_i2c_reg_setting *write_setting)
{
- int i;
int32_t rc = -EFAULT;
- struct msm_camera_i2c_reg_array *reg_setting;
- uint16_t client_addr_type;
+ struct msm_camera_cci_ctrl cci_ctrl;
if (!client || !write_setting)
return rc;
@@ -187,24 +187,26 @@
&& write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
return rc;
- reg_setting = write_setting->reg_setting;
- client_addr_type = client->addr_type;
- client->addr_type = write_setting->addr_type;
-
- for (i = 0; i < write_setting->size; i++) {
- rc = msm_camera_cci_i2c_write(client, reg_setting->reg_addr,
- reg_setting->reg_data, write_setting->data_type);
- if (rc < 0)
- return rc;
- reg_setting++;
+ cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+ cci_ctrl.cci_info = client->cci_client;
+ cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting =
+ write_setting->reg_setting;
+ cci_ctrl.cfg.cci_i2c_write_cfg.data_type = write_setting->data_type;
+ cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
+ cci_ctrl.cfg.cci_i2c_write_cfg.size = write_setting->size;
+ rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+ core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+ if (rc < 0) {
+ pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc);
+ return rc;
}
+ rc = cci_ctrl.status;
if (write_setting->delay > 20)
msleep(write_setting->delay);
else if (write_setting->delay)
usleep_range(write_setting->delay * 1000, (write_setting->delay
* 1000) + 1000);
- client->addr_type = client_addr_type;
return rc;
}
@@ -250,30 +252,34 @@
int32_t msm_camera_cci_i2c_write_table_w_microdelay(
struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
- enum msm_camera_i2c_data_type data_type)
+ struct msm_camera_i2c_reg_setting *write_setting)
{
- int i;
int32_t rc = -EFAULT;
+ struct msm_camera_cci_ctrl cci_ctrl;
- if (!client || !reg_tbl)
+ if (!client || !write_setting)
return rc;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
- || (data_type != MSM_CAMERA_I2C_BYTE_DATA
- && data_type != MSM_CAMERA_I2C_WORD_DATA))
+ || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+ && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
return rc;
- for (i = 0; i < size; i++) {
- rc = msm_camera_cci_i2c_write(client, reg_tbl->reg_addr,
- reg_tbl->reg_data, data_type);
- if (rc < 0)
- return rc;
- if (reg_tbl->delay)
- usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
- reg_tbl++;
+ cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
+ cci_ctrl.cci_info = client->cci_client;
+ cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting =
+ write_setting->reg_setting;
+ cci_ctrl.cfg.cci_i2c_write_cfg.data_type = write_setting->data_type;
+ cci_ctrl.cfg.cci_i2c_write_cfg.addr_type = client->addr_type;
+ cci_ctrl.cfg.cci_i2c_write_cfg.size = write_setting->size;
+ rc = v4l2_subdev_call(client->cci_client->cci_subdev,
+ core, ioctl, VIDIOC_MSM_CCI_CFG, &cci_ctrl);
+ if (rc < 0) {
+ pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc);
+ return rc;
}
+ rc = cci_ctrl.status;
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
index 389e9d9..763c131 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
@@ -25,12 +25,6 @@
enum msm_camera_i2c_reg_addr_type addr_type;
};
-struct msm_camera_i2c_reg_tbl {
- uint16_t reg_addr;
- uint16_t reg_data;
- uint16_t delay;
-};
-
struct msm_camera_i2c_fn_t {
int (*i2c_read) (struct msm_camera_i2c_client *, uint32_t, uint16_t *,
enum msm_camera_i2c_data_type);
@@ -46,8 +40,7 @@
struct msm_camera_i2c_seq_reg_setting *);
int32_t (*i2c_write_table_w_microdelay)
(struct msm_camera_i2c_client *,
- struct msm_camera_i2c_reg_tbl *, uint16_t,
- enum msm_camera_i2c_data_type);
+ struct msm_camera_i2c_reg_setting *);
int32_t (*i2c_util)(struct msm_camera_i2c_client *, uint16_t);
int32_t (*i2c_write_conf_tbl)(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
@@ -81,8 +74,7 @@
int32_t msm_camera_cci_i2c_write_table_w_microdelay(
struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
- enum msm_camera_i2c_data_type data_type);
+ struct msm_camera_i2c_reg_setting *write_setting);
int32_t msm_camera_cci_i2c_write_conf_tbl(
struct msm_camera_i2c_client *client,
@@ -118,8 +110,7 @@
int32_t msm_camera_qup_i2c_write_table_w_microdelay(
struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
- enum msm_camera_i2c_data_type data_type);
+ struct msm_camera_i2c_reg_setting *write_setting);
int32_t msm_camera_qup_i2c_write_conf_tbl(
struct msm_camera_i2c_client *client,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
index 60d1509..d5b89b7 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -308,29 +308,31 @@
int32_t msm_camera_qup_i2c_write_table_w_microdelay(
struct msm_camera_i2c_client *client,
- struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
- enum msm_camera_i2c_data_type data_type)
+ struct msm_camera_i2c_reg_setting *write_setting)
{
int i;
int32_t rc = -EFAULT;
+ struct msm_camera_i2c_reg_array *reg_setting = NULL;
- if (!client || !reg_tbl)
+ if (!client || !write_setting)
return rc;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
- || (data_type != MSM_CAMERA_I2C_BYTE_DATA
- && data_type != MSM_CAMERA_I2C_WORD_DATA))
+ || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+ && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
return rc;
- for (i = 0; i < size; i++) {
- rc = msm_camera_qup_i2c_write(client, reg_tbl->reg_addr,
- reg_tbl->reg_data, data_type);
+ reg_setting = write_setting->reg_setting;
+ for (i = 0; i < write_setting->size; i++) {
+ rc = msm_camera_qup_i2c_write(client, reg_setting->reg_addr,
+ reg_setting->reg_data, write_setting->data_type);
if (rc < 0)
break;
- if (reg_tbl->delay)
- usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
- reg_tbl++;
+ if (reg_setting->delay)
+ usleep_range(reg_setting->delay,
+ reg_setting->delay + 1000);
+ reg_setting++;
}
return rc;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 6ef389c..e5315bd 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1384,15 +1384,25 @@
static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
{
struct mmc_blk_data *md = mq->data;
+ struct request_queue *q = mq->queue;
struct mmc_card *card = md->queue.card;
int ret = 0;
ret = mmc_flush_cache(card);
- if (ret)
+ if (ret == -ETIMEDOUT) {
+ pr_info("%s: requeue flush request after timeout", __func__);
+ spin_lock_irq(q->queue_lock);
+ blk_requeue_request(q, req);
+ spin_unlock_irq(q->queue_lock);
+ ret = 0;
+ goto exit;
+ } else if (ret) {
+ pr_err("%s: notify flush error to upper layers", __func__);
ret = -EIO;
+ }
blk_end_request_all(req, ret);
-
+exit:
return ret ? 0 : 1;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 91efb12..1e2d367 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -60,7 +60,7 @@
#define MMC_BKOPS_MAX_TIMEOUT (30 * 1000) /* max time to wait in ms */
/* Flushing a large amount of cached data may take a long time. */
-#define MMC_FLUSH_REQ_TIMEOUT_MS 30000 /* msec */
+#define MMC_FLUSH_REQ_TIMEOUT_MS 90000 /* msec */
static struct workqueue_struct *workqueue;
@@ -3339,7 +3339,7 @@
EXT_CSD_FLUSH_CACHE, 1,
MMC_FLUSH_REQ_TIMEOUT_MS);
if (err == -ETIMEDOUT) {
- pr_debug("%s: cache flush timeout\n",
+ pr_err("%s: cache flush timeout\n",
mmc_hostname(card->host));
rc = mmc_interrupt_hpi(card);
if (rc)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index a7ce6ae..2c8598b 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2687,6 +2687,9 @@
goto vreg_deinit;
}
+ /* Unset HC_MODE_EN bit in HC_MODE register */
+ writel_relaxed(0, (msm_host->core_mem + CORE_HC_MODE));
+
/* Set SW_RST bit in POWER register (Offset 0x0) */
writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
CORE_SW_RST, msm_host->core_mem + CORE_POWER);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f9f3802..0cb0491 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -110,7 +110,7 @@
sdhci_readl(host, SDHCI_INT_ENABLE),
sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
pr_info(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
- sdhci_readw(host, SDHCI_ACMD12_ERR),
+ sdhci_readw(host, SDHCI_AUTO_CMD_ERR),
sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
pr_info(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n",
sdhci_readl(host, SDHCI_CAPABILITIES),
@@ -118,6 +118,12 @@
pr_info(DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n",
sdhci_readw(host, SDHCI_COMMAND),
sdhci_readl(host, SDHCI_MAX_CURRENT));
+ pr_info(DRIVER_NAME ": Resp 1: 0x%08x | Resp 0: 0x%08x\n",
+ sdhci_readl(host, SDHCI_RESPONSE + 0x4),
+ sdhci_readl(host, SDHCI_RESPONSE));
+ pr_info(DRIVER_NAME ": Resp 3: 0x%08x | Resp 2: 0x%08x\n",
+ sdhci_readl(host, SDHCI_RESPONSE + 0xC),
+ sdhci_readl(host, SDHCI_RESPONSE + 0x8));
pr_info(DRIVER_NAME ": Host ctl2: 0x%08x\n",
sdhci_readw(host, SDHCI_HOST_CONTROL2));
@@ -278,7 +284,8 @@
SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
- SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
+ SDHCI_INT_AUTO_CMD_ERR);
if (soft) {
/* force clock reconfiguration */
@@ -2440,6 +2447,7 @@
static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
{
+ u16 auto_cmd_status;
BUG_ON(intmask == 0);
if (!host->cmd) {
@@ -2456,6 +2464,18 @@
SDHCI_INT_INDEX))
host->cmd->error = -EILSEQ;
+ if (intmask & SDHCI_INT_AUTO_CMD_ERR) {
+ auto_cmd_status = sdhci_readw(host, SDHCI_AUTO_CMD_ERR);
+ if (auto_cmd_status & (SDHCI_AUTO_CMD12_NOT_EXEC |
+ SDHCI_AUTO_CMD_INDEX_ERR |
+ SDHCI_AUTO_CMD_ENDBIT_ERR))
+ host->cmd->error = -EIO;
+ else if (auto_cmd_status & SDHCI_AUTO_CMD_TIMEOUT_ERR)
+ host->cmd->error = -ETIMEDOUT;
+ else if (auto_cmd_status & SDHCI_AUTO_CMD_CRC_ERR)
+ host->cmd->error = -EILSEQ;
+ }
+
if (host->quirks2 & SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING) {
if ((host->cmd->opcode == MMC_SEND_TUNING_BLOCK_HS400) ||
(host->cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index a3d8442..3db99c4 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -135,21 +135,29 @@
#define SDHCI_INT_DATA_CRC 0x00200000
#define SDHCI_INT_DATA_END_BIT 0x00400000
#define SDHCI_INT_BUS_POWER 0x00800000
-#define SDHCI_INT_ACMD12ERR 0x01000000
+#define SDHCI_INT_AUTO_CMD_ERR 0x01000000
#define SDHCI_INT_ADMA_ERROR 0x02000000
#define SDHCI_INT_NORMAL_MASK 0x00007FFF
#define SDHCI_INT_ERROR_MASK 0xFFFF8000
#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
- SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
+ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \
+ SDHCI_INT_AUTO_CMD_ERR)
+
#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR)
#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
-#define SDHCI_ACMD12_ERR 0x3C
+#define SDHCI_AUTO_CMD_ERR 0x3C
+#define SDHCI_AUTO_CMD12_NOT_EXEC 0x0001
+#define SDHCI_AUTO_CMD_TIMEOUT_ERR 0x0002
+#define SDHCI_AUTO_CMD_CRC_ERR 0x0004
+#define SDHCI_AUTO_CMD_ENDBIT_ERR 0x0008
+#define SDHCI_AUTO_CMD_INDEX_ERR 0x0010
+#define SDHCI_AUTO_CMD12_NOT_ISSUED 0x0080
#define SDHCI_HOST_CONTROL2 0x3E
#define SDHCI_CTRL_UHS_MASK 0x0007
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index d35bdaa..64d1478 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -98,6 +98,12 @@
#define PRONTO_PMU_CBCR_OFFSET 0x0008
#define PRONTO_PMU_CBCR_CLK_EN BIT(0)
+#define PRONTO_PMU_COM_CPU_CBCR_OFFSET 0x0030
+#define PRONTO_PMU_COM_AHB_CBCR_OFFSET 0x0034
+#define PRONTO_PMU_CFG_OFFSET 0x1004
+#define PRONTO_PMU_COM_CSR_OFFSET 0x1040
+#define PRONTO_PMU_SOFT_RESET_OFFSET 0x104C
+
#define MSM_PRONTO_A2XB_BASE 0xfb100400
#define A2XB_CFG_OFFSET 0x00
#define A2XB_INT_SRC_OFFSET 0x0c
@@ -477,8 +483,34 @@
reg = readl_relaxed(reg_addr);
pr_info_ratelimited("%s: PRONTO_PMU_SPARE %08x\n", __func__, reg);
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_CPU_CBCR_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_COM_CPU_CBCR %08x\n",
+ __func__, reg);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_AHB_CBCR_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_COM_AHB_CBCR %08x\n",
+ __func__, reg);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CFG_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_CFG %08x\n", __func__, reg);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_CSR_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_COM_CSR %08x\n",
+ __func__, reg);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_SOFT_RESET_OFFSET;
+ reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_SOFT_RESET %08x\n",
+ __func__, reg);
+
reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_GDSCR_OFFSET;
reg = readl_relaxed(reg_addr);
+ pr_info_ratelimited("%s: PRONTO_PMU_COM_GDSCR %08x\n",
+ __func__, reg);
reg >>= 31;
if (!reg) {
diff --git a/drivers/platform/msm/qpnp-power-on.c b/drivers/platform/msm/qpnp-power-on.c
index b4edce8..c0371a5 100644
--- a/drivers/platform/msm/qpnp-power-on.c
+++ b/drivers/platform/msm/qpnp-power-on.c
@@ -1031,8 +1031,11 @@
index = ffs(pon_sts);
if ((index > PON_REASON_MAX) || (index < 0))
index = 0;
- pr_info("PMIC@SID%d Power-on reason: %s\n", pon->spmi->sid,
- index ? qpnp_pon_reason[index - 1] : "Unknown");
+
+ cold_boot = !qpnp_pon_is_warm_reset();
+ pr_info("PMIC@SID%d Power-on reason: %s and '%s' boot\n",
+ pon->spmi->sid, index ? qpnp_pon_reason[index - 1] :
+ "Unknown", cold_boot ? "cold" : "warm");
rc = of_property_read_u32(pon->spmi->dev.of_node,
"qcom,pon-dbc-delay", &delay);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 1cf901e..8d9da6b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -89,14 +89,30 @@
}
EXPORT_SYMBOL(sensor_get_id);
+static long get_min(struct sensor_info *sensor, long temp)
+{
+ long min = LONG_MIN;
+ struct sensor_threshold *pos, *var;
+
+ list_for_each_entry_safe(pos, var, &sensor->threshold_list, list) {
+ if (pos->trip == THERMAL_TRIP_CONFIGURABLE_LOW)
+ if (pos->temp < temp && pos->temp > min)
+ min = pos->temp;
+ }
+
+ return min;
+}
+
static void __update_sensor_thresholds(struct sensor_info *sensor)
{
- int min = INT_MIN;
- int max = INT_MAX;
+ long min = LONG_MIN;
+ long max = LONG_MAX;
+ long max_of_min = LONG_MIN;
+ long min_of_max = LONG_MAX;
struct sensor_threshold *pos, *var;
enum thermal_trip_type type;
int i;
- unsigned long curr_temp;
+ long curr_temp;
for (i = 0; ((sensor->max_idx == -1) || (sensor->min_idx == -1)) &&
(sensor->tz->ops->get_trip_type) && (i < sensor->tz->trips);
@@ -106,36 +122,58 @@
sensor->max_idx = i;
if (type == THERMAL_TRIP_CONFIGURABLE_LOW)
sensor->min_idx = i;
+ sensor->tz->ops->get_trip_temp(sensor->tz,
+ THERMAL_TRIP_CONFIGURABLE_LOW, &sensor->threshold_min);
+ sensor->tz->ops->get_trip_temp(sensor->tz,
+ THERMAL_TRIP_CONFIGURABLE_HI, &sensor->threshold_max);
}
- get_cpu();
sensor->tz->ops->get_temp(sensor->tz, &curr_temp);
list_for_each_entry_safe(pos, var, &sensor->threshold_list, list) {
- if ((pos->trip == THERMAL_TRIP_CONFIGURABLE_LOW) &&
- (pos->temp < (int)curr_temp))
- if (pos->temp > min)
+ if (pos->trip == THERMAL_TRIP_CONFIGURABLE_LOW) {
+ if (pos->temp > max_of_min)
+ max_of_min = pos->temp;
+ if (pos->temp < curr_temp && pos->temp > min)
min = pos->temp;
- if ((pos->trip == THERMAL_TRIP_CONFIGURABLE_HI) &&
- (pos->temp > (int)curr_temp))
- if (pos->temp < max)
+ }
+ if (pos->trip == THERMAL_TRIP_CONFIGURABLE_HI) {
+ if (pos->temp < min_of_max)
+ min_of_max = pos->temp;
+ if (pos->temp > curr_temp && pos->temp < max)
max = pos->temp;
+ }
}
- put_cpu();
+
+ pr_debug("sensor %d: min of max: %ld max of min: %ld\n",
+ sensor->sensor_id, max_of_min, min_of_max);
+
+ /* If we haven't found a max and min bounding the curr_temp,
+ * use the min of max and max of min instead.
+ */
+ if (max == LONG_MAX)
+ max = min_of_max;
+ if (min == LONG_MIN) {
+ min = get_min(sensor, max);
+ if (min == LONG_MIN)
+ min = max_of_min;
+ }
if (sensor->tz->ops->set_trip_temp) {
- if (max != INT_MAX) {
+ if (max != sensor->threshold_max) {
sensor->tz->ops->set_trip_temp(sensor->tz,
sensor->max_idx, max);
sensor->threshold_max = max;
}
- if (min != INT_MIN) {
+ if (min != sensor->threshold_min) {
sensor->tz->ops->set_trip_temp(sensor->tz,
sensor->min_idx, min);
sensor->threshold_min = min;
}
}
- pr_debug("sensor %d, min: %d, max %d\n", sensor->sensor_id, min, max);
+ pr_debug("sensor %d: curr_temp: %ld min: %ld max: %ld\n",
+ sensor->sensor_id, curr_temp,
+ sensor->threshold_min, sensor->threshold_max);
}
static void sensor_update_work(struct work_struct *work)
@@ -151,7 +189,7 @@
* Do NOT call sensor_set_trip from this function
*/
int thermal_sensor_trip(struct thermal_zone_device *tz,
- enum thermal_trip_type trip, unsigned long temp)
+ enum thermal_trip_type trip, long temp)
{
struct sensor_threshold *pos, *var;
int ret = -ENODEV;
@@ -168,10 +206,10 @@
continue;
if (((trip == THERMAL_TRIP_CONFIGURABLE_LOW) &&
(pos->temp <= tz->sensor.threshold_min) &&
- (pos->temp >= (int) temp)) ||
+ (pos->temp >= temp)) ||
((trip == THERMAL_TRIP_CONFIGURABLE_HI) &&
(pos->temp >= tz->sensor.threshold_max) &&
- (pos->temp <= (int)temp))) {
+ (pos->temp <= temp))) {
pos->notify(trip, temp, pos->data);
}
}
@@ -235,29 +273,6 @@
}
EXPORT_SYMBOL(sensor_cancel_trip);
-static int sensor_get_trip_temp(struct thermal_zone_device *tz,
- int type, unsigned long *temp)
-{
- struct sensor_info *sensor = get_sensor(tz->id);
-
- if (!sensor)
- return -EFAULT;
-
- switch (type) {
- case THERMAL_TRIP_CONFIGURABLE_HI:
- *temp = tz->sensor.threshold_max;
- break;
- case THERMAL_TRIP_CONFIGURABLE_LOW:
- *temp = tz->sensor.threshold_min;
- break;
- default:
- tz->ops->get_trip_temp(tz, type, temp);
- break;
- }
-
- return 0;
-}
-
static int tz_notify_trip(enum thermal_trip_type type, int temp, void *data)
{
struct thermal_zone_device *tz = (struct thermal_zone_device *)data;
@@ -310,7 +325,7 @@
sensor->sensor_id = tz->id;
sensor->tz = tz;
sensor->threshold_min = 0;
- sensor->threshold_max = INT_MAX;
+ sensor->threshold_max = LONG_MAX;
sensor->max_idx = -1;
sensor->min_idx = -1;
mutex_init(&sensor->lock);
@@ -511,7 +526,7 @@
if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
return -EINVAL;
- ret = sensor_get_trip_temp(tz, trip, &temperature);
+ ret = tz->ops->get_trip_temp(tz, trip, &temperature);
if (ret)
return ret;
diff --git a/drivers/video/msm/mdss/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
index 9ca3461..531c814 100644
--- a/drivers/video/msm/mdss/dsi_v2.c
+++ b/drivers/video/msm/mdss/dsi_v2.c
@@ -65,6 +65,7 @@
panel_data);
if (enable) {
+ dsi_ctrl_gpio_request(ctrl_pdata);
mdss_dsi_panel_reset(pdata, 1);
rc = dsi_cmds_tx_v2(pdata, &dsi_panel_tx_buf,
@@ -82,6 +83,7 @@
ctrl_pdata->off_cmds.cmd_cnt);
mdss_dsi_panel_reset(pdata, 0);
+ dsi_ctrl_gpio_free(ctrl_pdata);
}
return rc;
}
@@ -145,59 +147,17 @@
ctrl_pdata->disp_en_gpio = of_get_named_gpio(np,
"qcom,platform-enable-gpio", 0);
- if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) {
+ if (!gpio_is_valid(ctrl_pdata->disp_en_gpio))
pr_err("%s:%d, Disp_en gpio not specified\n",
__func__, __LINE__);
- } else {
- rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable");
- if (rc) {
- pr_err("request reset gpio failed, rc=%d\n",
- rc);
- gpio_free(ctrl_pdata->disp_en_gpio);
- return -ENODEV;
- }
- }
+ ctrl_pdata->disp_te_gpio = -1;
if (ctrl_pdata->panel_data.panel_info.mipi.mode == DSI_CMD_MODE) {
ctrl_pdata->disp_te_gpio = of_get_named_gpio(np,
"qcom,platform-te-gpio", 0);
- if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) {
+ if (!gpio_is_valid(ctrl_pdata->disp_te_gpio))
pr_err("%s:%d, Disp_te gpio not specified\n",
__func__, __LINE__);
- } else {
- rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te");
- if (rc) {
- pr_err("request TE gpio failed, rc=%d\n",
- rc);
- gpio_free(ctrl_pdata->disp_te_gpio);
- return -ENODEV;
- }
- rc = gpio_tlmm_config(GPIO_CFG(
- ctrl_pdata->disp_te_gpio, 1,
- GPIO_CFG_INPUT,
- GPIO_CFG_PULL_DOWN,
- GPIO_CFG_2MA),
- GPIO_CFG_ENABLE);
-
- if (rc) {
- pr_err("%s: unable to config tlmm = %d\n",
- __func__, ctrl_pdata->disp_te_gpio);
- gpio_free(ctrl_pdata->disp_te_gpio);
- return -ENODEV;
- }
-
- rc = gpio_direction_input(ctrl_pdata->disp_te_gpio);
- if (rc) {
- pr_err("set_direction for disp_en gpio failed, rc=%d\n",
- rc);
- gpio_free(ctrl_pdata->disp_te_gpio);
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
- gpio_free(ctrl_pdata->disp_en_gpio);
- return -ENODEV;
- }
- pr_debug("%s: te_gpio=%d\n", __func__,
- ctrl_pdata->disp_te_gpio);
- }
}
rc = of_property_read_u32_array(np,
@@ -211,45 +171,18 @@
ctrl_pdata->rst_gpio = of_get_named_gpio(np,
"qcom,platform-reset-gpio", 0);
- if (!gpio_is_valid(ctrl_pdata->rst_gpio)) {
+ if (!gpio_is_valid(ctrl_pdata->rst_gpio))
pr_err("%s:%d, reset gpio not specified\n",
__func__, __LINE__);
- } else {
- rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n");
- if (rc) {
- pr_err("request reset gpio failed, rc=%d\n",
- rc);
- gpio_free(ctrl_pdata->rst_gpio);
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
- gpio_free(ctrl_pdata->disp_en_gpio);
- if (gpio_is_valid(ctrl_pdata->disp_te_gpio))
- gpio_free(ctrl_pdata->disp_te_gpio);
- return -ENODEV;
- }
- }
+ ctrl_pdata->mode_gpio = -1;
if (ctrl_pdata->panel_data.panel_info.mode_gpio_state !=
MODE_GPIO_NOT_VALID) {
ctrl_pdata->mode_gpio = of_get_named_gpio(np,
"qcom,platform-mode-gpio", 0);
- if (!gpio_is_valid(ctrl_pdata->mode_gpio)) {
+ if (!gpio_is_valid(ctrl_pdata->mode_gpio))
pr_info("%s:%d, reset gpio not specified\n",
__func__, __LINE__);
- } else {
- rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode");
- if (rc) {
- pr_err("request panel mode gpio failed,rc=%d\n",
- rc);
- gpio_free(ctrl_pdata->mode_gpio);
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
- gpio_free(ctrl_pdata->disp_en_gpio);
- if (gpio_is_valid(ctrl_pdata->rst_gpio))
- gpio_free(ctrl_pdata->rst_gpio);
- if (gpio_is_valid(ctrl_pdata->disp_te_gpio))
- gpio_free(ctrl_pdata->disp_te_gpio);
- return -ENODEV;
- }
- }
}
return 0;
}
@@ -268,15 +201,81 @@
module_power->vreg_config = NULL;
}
module_power->num_vreg = 0;
+}
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
- gpio_free(ctrl_pdata->disp_en_gpio);
- if (gpio_is_valid(ctrl_pdata->rst_gpio))
- gpio_free(ctrl_pdata->rst_gpio);
+int dsi_ctrl_gpio_request(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+ int rc = 0;
+
+ if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) {
+ rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable");
+ if (rc)
+ goto gpio_request_err4;
+
+ ctrl_pdata->disp_en_gpio_requested = 1;
+ }
+
+ if (gpio_is_valid(ctrl_pdata->rst_gpio)) {
+ rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n");
+ if (rc)
+ goto gpio_request_err3;
+
+ ctrl_pdata->rst_gpio_requested = 1;
+ }
+
+ if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) {
+ rc = gpio_request(ctrl_pdata->disp_te_gpio, "disp_te");
+ if (rc)
+ goto gpio_request_err2;
+
+ ctrl_pdata->disp_te_gpio_requested = 1;
+ }
+
+ if (gpio_is_valid(ctrl_pdata->mode_gpio)) {
+ rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode");
+ if (rc)
+ goto gpio_request_err1;
+
+ ctrl_pdata->mode_gpio_requested = 1;
+ }
+
+ return rc;
+
+gpio_request_err1:
if (gpio_is_valid(ctrl_pdata->disp_te_gpio))
gpio_free(ctrl_pdata->disp_te_gpio);
- if (gpio_is_valid(ctrl_pdata->mode_gpio))
+gpio_request_err2:
+ if (gpio_is_valid(ctrl_pdata->rst_gpio))
+ gpio_free(ctrl_pdata->rst_gpio);
+gpio_request_err3:
+ if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
+ gpio_free(ctrl_pdata->disp_en_gpio);
+gpio_request_err4:
+ ctrl_pdata->disp_en_gpio_requested = 0;
+ ctrl_pdata->rst_gpio_requested = 0;
+ ctrl_pdata->disp_te_gpio_requested = 0;
+ ctrl_pdata->mode_gpio_requested = 0;
+ return rc;
+}
+
+void dsi_ctrl_gpio_free(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+ if (ctrl_pdata->disp_en_gpio_requested) {
+ gpio_free(ctrl_pdata->disp_en_gpio);
+ ctrl_pdata->disp_en_gpio_requested = 0;
+ }
+ if (ctrl_pdata->rst_gpio_requested) {
+ gpio_free(ctrl_pdata->rst_gpio);
+ ctrl_pdata->rst_gpio_requested = 0;
+ }
+ if (ctrl_pdata->disp_te_gpio_requested) {
+ gpio_free(ctrl_pdata->disp_te_gpio);
+ ctrl_pdata->disp_te_gpio_requested = 0;
+ }
+ if (ctrl_pdata->mode_gpio_requested) {
gpio_free(ctrl_pdata->mode_gpio);
+ ctrl_pdata->mode_gpio_requested = 0;
+ }
}
static int dsi_parse_vreg(struct device *dev, struct dss_module_power *mp)
diff --git a/drivers/video/msm/mdss/dsi_v2.h b/drivers/video/msm/mdss/dsi_v2.h
index a554856..e15f640 100644
--- a/drivers/video/msm/mdss/dsi_v2.h
+++ b/drivers/video/msm/mdss/dsi_v2.h
@@ -70,6 +70,10 @@
int dsi_ctrl_config_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+int dsi_ctrl_gpio_request(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+
+void dsi_ctrl_gpio_free(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
+
struct mdss_panel_cfg *mdp3_panel_intf_type(int intf_val);
int mdp3_panel_get_boot_cfg(void);
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index 8a5f1ee..eff60a3 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -35,6 +35,9 @@
#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/msm_kgsl.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <mach/board.h>
#include <mach/clk.h>
@@ -583,6 +586,41 @@
return 0;
}
+struct reg_dump {
+ int start_addr;
+ int num_reads;
+};
+
+struct reg_dump ppp_reg[] = {
+ {0x10108, 3},
+ {0x10118, 6},
+ {0x10138, 9},
+ {0x10158, 1},
+ {0x10164, 7},
+ {0x1019C, 1},
+ {0x101b8, 2},
+ {0x101c0, 8},
+};
+
+static int mdp3_iommu_fault_handler(struct iommu_domain *domain,
+ struct device *dev, unsigned long iova, int flags, void *token)
+{
+ unsigned int addr, val;
+ int i, j;
+ pr_err("MDP IOMMU page fault: iova 0x%lx\n", iova);
+ for (i = 0; i < ARRAY_SIZE(ppp_reg); i++) {
+ for (j = 0; j < ppp_reg[i].num_reads; j++) {
+ addr = ppp_reg[i].start_addr + (j*4);
+ val = MDP3_REG_READ(addr);
+ pr_err("TMsg: Addr= 0x%08x, val= 0x%08x\n",
+ (unsigned int)addr, (unsigned int)val);
+ }
+ }
+ panic("PPP pagefault, shutting down for easier debugging\n");
+ return 0;
+}
+
+
int mdp3_iommu_attach(int context)
{
struct mdp3_iommu_ctx_map *context_map;
@@ -658,6 +696,9 @@
else
return PTR_ERR(mdp3_iommu_domains[i].domain);
}
+ iommu_set_fault_handler(mdp3_iommu_domains[i].domain,
+ mdp3_iommu_fault_handler,
+ NULL);
}
mdp3_res->domains = mdp3_iommu_domains;
@@ -1594,6 +1635,45 @@
}
}
+int mdp3_parse_dt_splash(struct msm_fb_data_type *mfd)
+{
+ struct platform_device *pdev = mfd->pdev;
+ int rc;
+ u32 offsets[2];
+
+ rc = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,memblock-reserve", offsets, 2);
+
+ if (rc) {
+ pr_err("fail to get memblock-reserve property\n");
+ return rc;
+ }
+
+ if (mdp3_res->splash_mem_addr != offsets[0])
+ rc = -EINVAL;
+
+ mdp3_res->splash_mem_addr = offsets[0];
+ mdp3_res->splash_mem_size = offsets[1];
+
+ pr_debug("memaddr=%x size=%x\n", mdp3_res->splash_mem_addr,
+ mdp3_res->splash_mem_size);
+
+ return rc;
+}
+
+void mdp3_release_splash_memory(void)
+{
+ /* Give back the reserved memory to the system */
+ if (mdp3_res->splash_mem_addr) {
+ pr_debug("mdp3_release_splash_memory\n");
+ memblock_free(mdp3_res->splash_mem_addr,
+ mdp3_res->splash_mem_size);
+ free_bootmem_late(mdp3_res->splash_mem_addr,
+ mdp3_res->splash_mem_size);
+ mdp3_res->splash_mem_addr = 0;
+ }
+}
+
struct mdp3_dma *mdp3_get_dma_pipe(int capability)
{
int i;
@@ -1684,6 +1764,8 @@
rc = (status == 0x080000);
}
+ mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_S_IBUF_ADDR);
+
mdp3_clk_update(MDP3_CLK_AHB, 0);
mdp3_clk_update(MDP3_CLK_CORE, 0);
return rc;
@@ -1717,12 +1799,6 @@
goto splash_on_err;
}
- rc = mdp3_continuous_splash_copy(pdata);
- if (rc) {
- pr_err("fail to copy continuous splash image\n");
- goto splash_on_err;
- }
-
mdp3_irq_register();
if (pdata->event_handler) {
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index 2f73c42..caee34f 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -149,6 +149,8 @@
struct early_suspend suspend_handler;
struct mdss_panel_cfg pan_cfg;
+ u32 splash_mem_addr;
+ u32 splash_mem_size;
};
struct mdp3_img_data {
@@ -181,6 +183,8 @@
int mdp3_iommu_disable(int client);
int mdp3_iommu_is_attached(int client);
void mdp3_free(void);
+int mdp3_parse_dt_splash(struct msm_fb_data_type *mfd);
+void mdp3_release_splash_memory(void);
#define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr)
#define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index ac3fd3a..08bff9a 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -742,7 +742,8 @@
return rc;
}
-static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd)
+static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
+ struct mdp_display_commit *cmt_data)
{
struct mdp3_session_data *mdp3_session;
struct mdp3_img_data *data;
@@ -758,8 +759,8 @@
if (!mdp3_iommu_is_attached(MDP3_CLIENT_DMA_P)) {
pr_debug("continuous splash screen, IOMMU not attached\n");
mdp3_ctrl_reset(mfd);
- mdp3_free();
}
+ mdp3_release_splash_memory();
mutex_lock(&mdp3_session->lock);
@@ -805,9 +806,9 @@
if (!mdp3_iommu_is_attached(MDP3_CLIENT_DMA_P)) {
pr_debug("continuous splash screen, IOMMU not attached\n");
- mdp3_ctrl_off(mfd);
- mdp3_ctrl_on(mfd);
+ mdp3_ctrl_reset(mfd);
}
+ mdp3_release_splash_memory();
mutex_lock(&mdp3_session->lock);
@@ -1359,8 +1360,13 @@
struct mdp3_session_data *mdp3_session = NULL;
u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
int rc;
+ int splash_mismatch = 0;
pr_debug("mdp3_ctrl_init\n");
+ rc = mdp3_parse_dt_splash(mfd);
+ if (rc)
+ splash_mismatch = 1;
+
mdp3_interface->on_fnc = mdp3_ctrl_on;
mdp3_interface->off_fnc = mdp3_ctrl_off;
mdp3_interface->do_histogram = NULL;
@@ -1405,7 +1411,7 @@
mdp3_session->dma->output_config.out_sel = intf_type;
mdp3_session->mfd = mfd;
mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
- mdp3_session->status = 0;
+ mdp3_session->status = mdp3_session->intf->active;
mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
mdp3_bufq_init(&mdp3_session->bufq_in);
mdp3_bufq_init(&mdp3_session->bufq_out);
@@ -1435,6 +1441,11 @@
kobject_uevent(&dev->kobj, KOBJ_ADD);
pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
+ if (splash_mismatch) {
+ pr_err("splash memory mismatch, stop splash\n");
+ mdp3_ctrl_off(mfd);
+ }
+
init_done:
if (IS_ERR_VALUE(rc))
kfree(mdp3_session);
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index e1f2d10..6e62cc7 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -498,6 +498,7 @@
src_w = req->src_rect.w;
dst_h = blit_op->dst.roi.height;
+ pr_err("TMsg: In workaround. srcw= %d, dstH=%d\n", src_w, dst_h);
/* bg tile fetching HW workaround */
for (i = 0; i < (req->dst_rect.h / 16); i++) {
/* this tile size */
diff --git a/drivers/video/msm/mdss/mdp3_ppp_data.c b/drivers/video/msm/mdss/mdp3_ppp_data.c
index e1c0f27..ba2a369 100644
--- a/drivers/video/msm/mdss/mdp3_ppp_data.c
+++ b/drivers/video/msm/mdss/mdp3_ppp_data.c
@@ -16,6 +16,8 @@
#include "mdss_fb.h"
#include "mdp3_ppp.h"
+#define MDP_IS_IMGTYPE_BAD(x) ((x) >= MDP_IMGTYPE_LIMIT)
+
/* bg_config_lut not needed since it is same as src */
const uint32_t src_cfg_lut[MDP_IMGTYPE_LIMIT] = {
[MDP_RGB_565] = MDP_RGB_565_SRC_REG,
@@ -1504,56 +1506,56 @@
uint32_t ppp_bpp(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return bytes_per_pixel[type];
}
uint32_t ppp_src_config(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return src_cfg_lut[type];
}
uint32_t ppp_out_config(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return out_cfg_lut[type];
}
uint32_t ppp_pack_pattern(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return pack_patt_lut[type];
}
uint32_t ppp_dst_op_reg(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return dst_op_reg[type];
}
uint32_t ppp_src_op_reg(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return src_op_reg[type];
}
bool ppp_per_p_alpha(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return per_pixel_alpha[type];
}
bool ppp_multi_plane(uint32_t type)
{
- if (type > MDP_IMGTYPE_LIMIT)
+ if (MDP_IS_IMGTYPE_BAD(type))
return 0;
return multi_plane[type];
}
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index e156116..b794ac4 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -289,6 +289,7 @@
{
int ret = 0;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ struct mdss_panel_info *panel_info = NULL;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -305,6 +306,7 @@
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ panel_info = &ctrl_pdata->panel_data.panel_info;
pr_debug("%s+: ctrl=%p ndx=%d\n", __func__,
ctrl_pdata, ctrl_pdata->ndx);
@@ -335,6 +337,11 @@
return ret;
}
+ if (panel_info->dynamic_fps
+ && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE)
+ && (panel_info->new_fps != panel_info->mipi.frame_rate))
+ panel_info->mipi.frame_rate = panel_info->new_fps;
+
pr_debug("%s-:\n", __func__);
return ret;
@@ -350,6 +357,7 @@
u32 ystride, bpp, data, dst_bpp;
u32 dummy_xres, dummy_yres;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ u32 hsync_period, vsync_period;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -412,11 +420,16 @@
pdata->panel_info.bpp);
height = pdata->panel_info.yres;
- mipi = &pdata->panel_info.mipi;
if (pdata->panel_info.type == MIPI_VIDEO_PANEL) {
dummy_xres = pdata->panel_info.lcdc.xres_pad;
dummy_yres = pdata->panel_info.lcdc.yres_pad;
+ }
+ vsync_period = vspw + vbp + height + dummy_yres + vfp;
+ hsync_period = hspw + hbp + width + dummy_xres + hfp;
+
+ mipi = &pdata->panel_info.mipi;
+ if (pdata->panel_info.type == MIPI_VIDEO_PANEL) {
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x24,
((hspw + hbp + width + dummy_xres) << 16 |
(hspw + hbp)));
@@ -424,9 +437,8 @@
((vspw + vbp + height + dummy_yres) << 16 |
(vspw + vbp)));
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C,
- (vspw + vbp + height + dummy_yres +
- vfp - 1) << 16 | (hspw + hbp +
- width + dummy_xres + hfp - 1));
+ ((vsync_period - 1) << 16)
+ | (hsync_period - 1));
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x30, (hspw << 16));
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x34, 0);
@@ -591,6 +603,102 @@
return ret;
}
+static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
+{
+ int rc = 0;
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ u32 dsi_ctrl;
+
+ pr_debug("%s+:\n", __func__);
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+
+ if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) {
+ pr_err("%s: Dynamic fps not enabled for this panel\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_fps !=
+ ctrl_pdata->panel_data.panel_info.mipi.frame_rate) {
+ rc = mdss_dsi_clk_div_config
+ (&ctrl_pdata->panel_data.panel_info, new_fps);
+ if (rc) {
+ pr_err("%s: unable to initialize the clk dividers\n",
+ __func__);
+ return rc;
+ }
+ ctrl_pdata->pclk_rate =
+ ctrl_pdata->panel_data.panel_info.mipi.dsi_pclk_rate;
+ ctrl_pdata->byte_clk_rate =
+ ctrl_pdata->panel_data.panel_info.clk_rate / 8;
+
+ if (pdata->panel_info.dfps_update
+ == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
+ dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) +
+ 0x0004);
+ ctrl_pdata->panel_data.panel_info.mipi.frame_rate =
+ new_fps;
+ dsi_ctrl &= ~0x2;
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004,
+ dsi_ctrl);
+ mdss_dsi_controller_cfg(true, pdata);
+ mdss_dsi_clk_ctrl(ctrl_pdata, 0);
+ mdss_dsi_clk_ctrl(ctrl_pdata, 1);
+ dsi_ctrl |= 0x2;
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004,
+ dsi_ctrl);
+ }
+ } else {
+ pr_debug("%s: Panel is already at this FPS\n", __func__);
+ }
+
+ return rc;
+}
+
+static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata)
+{
+ int rc = -EINVAL;
+ u32 data;
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+
+ /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
+ data = (((pdata->panel_info.roi_w * 3) + 1) << 16) |
+ (pdata->panel_info.mipi.vc << 8) | DTYPE_DCS_LWRITE;
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, data);
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, data);
+
+ /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */
+ data = pdata->panel_info.roi_h << 16 | pdata->panel_info.roi_w;
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data);
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data);
+
+ if (ctrl_pdata->partial_update_fnc)
+ rc = ctrl_pdata->partial_update_fnc(pdata);
+
+ if (rc) {
+ pr_err("%s: unable to initialize the panel\n",
+ __func__);
+ return rc;
+ }
+
+ return rc;
+}
+
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
int event, void *arg)
{
@@ -644,6 +752,12 @@
break;
case MDSS_EVENT_DSI_CMDLIST_KOFF:
mdss_dsi_cmdlist_commit(ctrl_pdata, 1);
+ case MDSS_EVENT_PANEL_UPDATE_FPS:
+ if (arg != NULL) {
+ rc = mdss_dsi_dfps_config(pdata, (int)arg);
+ pr_debug("%s:update fps to = %d\n",
+ __func__, (int)arg);
+ }
break;
case MDSS_EVENT_CONT_SPLASH_BEGIN:
if (ctrl_pdata->off_cmds.link_state == DSI_HS_MODE) {
@@ -651,6 +765,9 @@
rc = mdss_dsi_blank(pdata);
}
break;
+ case MDSS_EVENT_ENABLE_PARTIAL_UPDATE:
+ rc = mdss_dsi_ctl_partial_update(pdata);
+ break;
default:
pr_debug("%s: unhandled event=%d\n", __func__, event);
break;
@@ -952,77 +1069,25 @@
{
struct mipi_panel_info *mipi;
int rc, i, len;
- u8 lanes = 0, bpp;
- u32 h_period, v_period, dsi_pclk_rate, tmp[9];
+ u32 tmp[9];
struct device_node *dsi_ctrl_np = NULL;
struct platform_device *ctrl_pdev = NULL;
+ bool dynamic_fps;
const char *data;
struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
- h_period = ((pinfo->lcdc.h_pulse_width)
- + (pinfo->lcdc.h_back_porch)
- + (pinfo->xres)
- + (pinfo->lcdc.h_front_porch));
-
- v_period = ((pinfo->lcdc.v_pulse_width)
- + (pinfo->lcdc.v_back_porch)
- + (pinfo->yres)
- + (pinfo->lcdc.v_front_porch));
-
- mipi = &pinfo->mipi;
mipi = &(pinfo->mipi);
pinfo->type =
((mipi->mode == DSI_VIDEO_MODE)
? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL);
- if (mipi->data_lane3)
- lanes += 1;
- if (mipi->data_lane2)
- lanes += 1;
- if (mipi->data_lane1)
- lanes += 1;
- if (mipi->data_lane0)
- lanes += 1;
-
-
- if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888)
- || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB888)
- || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB666_LOOSE))
- bpp = 3;
- else if ((mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565)
- || (mipi->dst_format == DSI_VIDEO_DST_FORMAT_RGB565))
- bpp = 2;
- else
- bpp = 3; /* Default format set to RGB888 */
-
- if (!pinfo->clk_rate) {
- h_period += pinfo->lcdc.xres_pad;
- v_period += pinfo->lcdc.yres_pad;
-
- if (lanes > 0) {
- pinfo->clk_rate =
- ((h_period * v_period * (mipi->frame_rate) * bpp * 8)
- / lanes);
- } else {
- pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
- pinfo->clk_rate =
- (h_period * v_period
- * (mipi->frame_rate) * bpp * 8);
- }
- }
- pll_divider_config.clk_rate = pinfo->clk_rate;
-
- rc = mdss_dsi_clk_div_config(bpp, lanes, &dsi_pclk_rate);
+ rc = mdss_dsi_clk_div_config(pinfo, mipi->frame_rate);
if (rc) {
pr_err("%s: unable to initialize the clk dividers\n", __func__);
return rc;
}
- if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000))
- dsi_pclk_rate = 35000000;
- mipi->dsi_pclk_rate = dsi_pclk_rate;
-
dsi_ctrl_np = of_parse_phandle(pan_node,
"qcom,mdss-dsi-panel-controller", 0);
if (!dsi_ctrl_np) {
@@ -1088,6 +1153,43 @@
ctrl_pdata->shared_pdata.broadcast_enable = of_property_read_bool(
pan_node, "qcom,mdss-dsi-panel-broadcast-mode");
+ dynamic_fps = of_property_read_bool(pan_node,
+ "qcom,mdss-dsi-pan-enable-dynamic-fps");
+ if (dynamic_fps) {
+ pinfo->dynamic_fps = true;
+ data = of_get_property(pan_node,
+ "qcom,mdss-dsi-pan-fps-update", NULL);
+ if (data) {
+ if (!strcmp(data, "dfps_suspend_resume_mode")) {
+ pinfo->dfps_update =
+ DFPS_SUSPEND_RESUME_MODE;
+ pr_debug("%s: dfps mode: suspend/resume\n",
+ __func__);
+ } else if (!strcmp(data,
+ "dfps_immediate_clk_mode")) {
+ pinfo->dfps_update =
+ DFPS_IMMEDIATE_CLK_UPDATE_MODE;
+ pr_debug("%s: dfps mode: Immediate clk\n",
+ __func__);
+ } else {
+ pr_debug("%s: dfps to default mode\n",
+ __func__);
+ pinfo->dfps_update =
+ DFPS_SUSPEND_RESUME_MODE;
+ pr_debug("%s: dfps mode: suspend/resume\n",
+ __func__);
+ }
+ } else {
+ pr_debug("%s: dfps update mode not configured\n",
+ __func__);
+ pinfo->dynamic_fps =
+ false;
+ pr_debug("%s: dynamic FPS disabled\n",
+ __func__);
+ }
+ pinfo->new_fps = pinfo->mipi.frame_rate;
+ }
+
ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
"qcom,platform-enable-gpio", 0);
@@ -1219,7 +1321,7 @@
* register in mdp driver
*/
- ctrl_pdata->pclk_rate = dsi_pclk_rate;
+ ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate;
ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8;
pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 2d63532..b2b20f2 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -313,6 +313,7 @@
int ndx; /* panel_num */
int (*on) (struct mdss_panel_data *pdata);
int (*off) (struct mdss_panel_data *pdata);
+ int (*partial_update_fnc) (struct mdss_panel_data *pdata);
struct mdss_panel_data panel_data;
unsigned char *ctrl_base;
int reg_size;
@@ -330,11 +331,16 @@
int disp_en_gpio;
int disp_te_gpio;
int mode_gpio;
+ int rst_gpio_requested;
+ int disp_en_gpio_requested;
+ int disp_te_gpio_requested;
+ int mode_gpio_requested;
int bklt_ctrl; /* backlight ctrl */
int pwm_period;
int pwm_pmic_gpio;
int pwm_lpg_chan;
int bklt_max;
+ int new_fps;
struct pwm_device *pwm_bl;
struct dsi_drv_cm_data shared_pdata;
u32 pclk_rate;
@@ -397,8 +403,8 @@
void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mipi_set_tx_power_mode(int mode, struct mdss_panel_data *pdata);
-int mdss_dsi_clk_div_config(u8 bpp, u8 lanes,
- u32 *expected_dsi_pclk);
+int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
+ int frame_rate);
int mdss_dsi_clk_init(struct platform_device *pdev,
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 203900c..f37a6cc 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -209,6 +209,61 @@
}
}
+static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */
+static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */
+
+static struct dsi_cmd_desc partial_update_enable_cmd[] = {
+ {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(caset)}, caset},
+ {{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset},
+};
+
+static int mdss_dsi_panel_partial_update(struct mdss_panel_data *pdata)
+{
+ struct mipi_panel_info *mipi;
+ struct mdss_dsi_ctrl_pdata *ctrl = NULL;
+ struct dcs_cmd_req cmdreq;
+ int rc = 0;
+
+ if (pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+ return -EINVAL;
+ }
+
+ ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+ mipi = &pdata->panel_info.mipi;
+
+ pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx);
+
+ caset[1] = (((pdata->panel_info.roi_x) & 0xFF00) >> 8);
+ caset[2] = (((pdata->panel_info.roi_x) & 0xFF));
+ caset[3] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w)
+ & 0xFF00) >> 8);
+ caset[4] = (((pdata->panel_info.roi_x - 1 + pdata->panel_info.roi_w)
+ & 0xFF));
+ partial_update_enable_cmd[0].payload = caset;
+
+ paset[1] = (((pdata->panel_info.roi_y) & 0xFF00) >> 8);
+ paset[2] = (((pdata->panel_info.roi_y) & 0xFF));
+ paset[3] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h)
+ & 0xFF00) >> 8);
+ paset[4] = (((pdata->panel_info.roi_y - 1 + pdata->panel_info.roi_h)
+ & 0xFF));
+ partial_update_enable_cmd[1].payload = paset;
+
+ pr_debug("%s: enabling partial update\n", __func__);
+ memset(&cmdreq, 0, sizeof(cmdreq));
+ cmdreq.cmds = partial_update_enable_cmd;
+ cmdreq.cmds_cnt = 2;
+ cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL;
+ cmdreq.rlen = 0;
+ cmdreq.cb = NULL;
+
+ mdss_dsi_cmdlist_put(ctrl, &cmdreq);
+
+ return rc;
+}
+
static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,
u32 bl_level)
{
@@ -759,6 +814,7 @@
int rc = 0;
static const char *panel_name;
bool cont_splash_enabled;
+ bool partial_update_enabled;
if (!node) {
pr_err("%s: no panel node\n", __func__);
@@ -795,6 +851,18 @@
ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1;
}
+ partial_update_enabled = of_property_read_bool(node,
+ "qcom,partial-update-enabled");
+ if (partial_update_enabled) {
+ pr_info("%s:%d Partial update enabled.\n", __func__, __LINE__);
+ ctrl_pdata->panel_data.panel_info.partial_update_enabled = 1;
+ ctrl_pdata->partial_update_fnc = mdss_dsi_panel_partial_update;
+ } else {
+ pr_info("%s:%d Partial update disabled.\n", __func__, __LINE__);
+ ctrl_pdata->panel_data.panel_info.partial_update_enabled = 0;
+ ctrl_pdata->partial_update_fnc = NULL;
+ }
+
ctrl_pdata->on = mdss_dsi_panel_on;
ctrl_pdata->off = mdss_dsi_panel_off;
ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 793cbd7..74b0217 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1431,7 +1431,7 @@
MDP_DISPLAY_COMMIT_OVERLAY) {
mdss_fb_wait_for_fence(mfd);
if (mfd->mdp.kickoff_fnc)
- mfd->mdp.kickoff_fnc(mfd);
+ mfd->mdp.kickoff_fnc(mfd, &fb_backup->disp_commit);
mdss_fb_update_backlight(mfd);
mdss_fb_signal_timeline(mfd);
} else {
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index fd96e63..1f85373 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -63,7 +63,8 @@
int (*off_fnc)(struct msm_fb_data_type *mfd);
/* called to release resources associated to the process */
int (*release_fnc)(struct msm_fb_data_type *mfd);
- int (*kickoff_fnc)(struct msm_fb_data_type *mfd);
+ int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
+ struct mdp_display_commit *data);
int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
void (*dma_fnc)(struct msm_fb_data_type *mfd);
int (*cursor_update)(struct msm_fb_data_type *mfd,
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index 65dc19c..488bc11 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -27,6 +27,8 @@
#define MAX_AUDIO_DATA_BLOCK_SIZE 30
#define MAX_SPKR_ALLOC_DATA_BLOCK_SIZE 3
+#define BUFF_SIZE_3D 128
+
struct hdmi_edid_sink_data {
u32 disp_mode_list[HDMI_VFRMT_MAX];
u32 disp_3d_mode_list[HDMI_VFRMT_MAX];
@@ -249,19 +251,19 @@
if (!hdmi_get_supported_mode(*video_mode))
continue;
if (ret > 0)
- ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%d",
- *video_mode++);
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret,
+ ",%d", *video_mode++);
else
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
- *video_mode++);
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret,
+ "%d", *video_mode++);
}
} else {
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d",
edid_ctrl->video_resolution);
}
DEV_DBG("%s: '%s'\n", __func__, buf);
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
return ret;
} /* hdmi_edid_sysfs_rda_modes */
@@ -279,7 +281,7 @@
return -EINVAL;
}
- ret = snprintf(buf, PAGE_SIZE, "%d\n", edid_ctrl->physical_address);
+ ret = scnprintf(buf, PAGE_SIZE, "%d\n", edid_ctrl->physical_address);
DEV_DBG("%s: '%d'\n", __func__, edid_ctrl->physical_address);
return ret;
@@ -298,7 +300,7 @@
return -EINVAL;
}
- ret = snprintf(buf, PAGE_SIZE, "%d, %d, %d\n", edid_ctrl->pt_scan_info,
+ ret = scnprintf(buf, PAGE_SIZE, "%d, %d, %d\n", edid_ctrl->pt_scan_info,
edid_ctrl->it_scan_info, edid_ctrl->ce_scan_info);
DEV_DBG("%s: '%s'\n", __func__, buf);
@@ -311,7 +313,8 @@
{
ssize_t ret = 0;
int i;
- char buff_3d[128];
+ char buff_3d[BUFF_SIZE_3D];
+
struct hdmi_edid_ctrl *edid_ctrl =
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_EDID);
@@ -327,23 +330,23 @@
for (i = 0; i < edid_ctrl->sink_data.num_of_elements; ++i) {
ret = hdmi_get_video_3d_fmt_2string(*video_3d_mode++,
- buff_3d);
+ buff_3d, sizeof(buff_3d));
if (ret > 0)
- ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret,
",%d=%s", *video_mode++,
buff_3d);
else
- ret += snprintf(buf+ret, PAGE_SIZE-ret,
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"%d=%s", *video_mode++,
buff_3d);
}
} else {
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d",
edid_ctrl->video_resolution);
}
DEV_DBG("%s: '%s'\n", __func__, buf);
- ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+ ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
return ret;
} /* hdmi_edid_sysfs_rda_3d_modes */
@@ -816,7 +819,7 @@
static void hdmi_edid_add_sink_3d_format(struct hdmi_edid_sink_data *sink_data,
u32 video_format, u32 video_3d_format)
{
- char string[128];
+ char string[BUFF_SIZE_3D];
u32 added = false;
int i;
@@ -828,7 +831,7 @@
}
}
- hdmi_get_video_3d_fmt_2string(video_3d_format, string);
+ hdmi_get_video_3d_fmt_2string(video_3d_format, string, sizeof(string));
DEV_DBG("%s: EDID[3D]: format: %d [%s], %s %s\n", __func__,
video_format, msm_hdmi_mode_2string(video_format),
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 0fd3655..7117779 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -327,7 +327,7 @@
{
struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
- if (!device || feature_type > HDMI_TX_FEAT_MAX) {
+ if (!device || feature_type >= HDMI_TX_FEAT_MAX) {
DEV_ERR("%s: invalid input\n", __func__);
return NULL;
}
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index 53dfc71..711ec68 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -123,30 +123,30 @@
return "";
} /* hdmi_get_single_video_3d_fmt_2string */
-ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf)
+ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf, u32 size)
{
ssize_t ret, len = 0;
- ret = snprintf(buf, PAGE_SIZE, "%s",
+ ret = scnprintf(buf, size, "%s",
hdmi_get_single_video_3d_fmt_2string(
format & FRAME_PACKING));
len += ret;
if (len && (format & TOP_AND_BOTTOM))
- ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+ ret = scnprintf(buf + len, size - len, ":%s",
hdmi_get_single_video_3d_fmt_2string(
format & TOP_AND_BOTTOM));
else
- ret = snprintf(buf + len, PAGE_SIZE, "%s",
+ ret = scnprintf(buf + len, size - len, "%s",
hdmi_get_single_video_3d_fmt_2string(
format & TOP_AND_BOTTOM));
len += ret;
if (len && (format & SIDE_BY_SIDE_HALF))
- ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+ ret = scnprintf(buf + len, size - len, ":%s",
hdmi_get_single_video_3d_fmt_2string(
format & SIDE_BY_SIDE_HALF));
else
- ret = snprintf(buf + len, PAGE_SIZE, "%s",
+ ret = scnprintf(buf + len, size - len, "%s",
hdmi_get_single_video_3d_fmt_2string(
format & SIDE_BY_SIDE_HALF));
len += ret;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.h b/drivers/video/msm/mdss/mdss_hdmi_util.h
index e99e549..5f7878b 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.h
@@ -256,7 +256,7 @@
int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in);
const struct msm_hdmi_mode_timing_info *hdmi_get_supported_mode(u32 mode);
void hdmi_del_supported_mode(u32 mode);
-ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf);
+ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf, u32 size);
/* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */
void *hdmi_get_featuredata_from_sysfs_dev(struct device *device, u32 type);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 351d52b..7338d85 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -114,6 +114,13 @@
struct mdss_mdp_ctl;
typedef void (*mdp_vsync_handler_t)(struct mdss_mdp_ctl *, ktime_t);
+struct mdss_mdp_img_rect {
+ u16 x;
+ u16 y;
+ u16 w;
+ u16 h;
+};
+
struct mdss_mdp_vsync_handler {
bool enabled;
bool cmd_post_flush;
@@ -153,6 +160,7 @@
u32 bus_ib_quota;
u32 clk_rate;
u32 perf_changed;
+ int force_screen_state;
struct mdss_data_type *mdata;
struct msm_fb_data_type *mfd;
@@ -164,6 +172,9 @@
struct mdss_panel_data *panel_data;
struct mdss_mdp_vsync_handler vsync_handler;
+ struct mdss_mdp_img_rect roi;
+ u8 roi_changed;
+
int (*start_fnc) (struct mdss_mdp_ctl *ctl);
int (*stop_fnc) (struct mdss_mdp_ctl *ctl);
int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg);
@@ -175,7 +186,7 @@
struct mdss_mdp_vsync_handler *);
int (*remove_vsync_handler) (struct mdss_mdp_ctl *,
struct mdss_mdp_vsync_handler *);
-
+ int (*config_fps_fnc) (struct mdss_mdp_ctl *ctl, int new_fps);
void *priv_data;
u32 wb_type;
};
@@ -190,6 +201,7 @@
u8 params_changed;
u16 width;
u16 height;
+ struct mdss_mdp_img_rect roi;
u8 cursor_enabled;
u8 rotator_mode;
@@ -197,13 +209,6 @@
struct mdss_mdp_pipe *stage_pipe[MDSS_MDP_MAX_STAGE];
};
-struct mdss_mdp_img_rect {
- u16 x;
- u16 y;
- u16 w;
- u16 h;
-};
-
struct mdss_mdp_format_params {
u32 format;
u8 is_yuv;
@@ -387,6 +392,9 @@
struct mdss_mdp_data free_list[MAX_FREE_LIST_SIZE];
int free_list_size;
int ad_state;
+
+ u32 splash_mem_addr;
+ u32 splash_mem_size;
};
struct mdss_mdp_perf_params {
@@ -395,6 +403,17 @@
u32 mdp_clk_rate;
};
+/**
+ * enum mdss_screen_state - Screen states that MDP can be forced into
+ *
+ * @MDSS_SCREEN_DEFAULT: Do not force MDP into any screen state.
+ * @MDSS_SCREEN_FORCE_BLANK: Force MDP to generate blank color fill screen.
+ */
+enum mdss_screen_state {
+ MDSS_SCREEN_DEFAULT,
+ MDSS_SCREEN_FORCE_BLANK,
+};
+
#define is_vig_pipe(_pipe_id_) ((_pipe_id_) <= MDSS_MDP_SSPP_VIG2)
static inline void mdss_mdp_ctl_write(struct mdss_mdp_ctl *ctl,
u32 reg, u32 val)
@@ -420,7 +439,6 @@
irqreturn_t mdss_mdp_isr(int irq, void *ptr);
int mdss_iommu_attach(struct mdss_data_type *mdata);
-int mdss_mdp_video_copy_splash_screen(struct mdss_panel_data *pdata);
void mdss_mdp_irq_clear(struct mdss_data_type *mdata,
u32 intr_type, u32 intf_num);
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num);
@@ -446,14 +464,13 @@
int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl);
int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl);
-int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd);
+int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
+ struct mdp_display_commit *data);
struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
struct msm_fb_data_type *mfd);
int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl);
int mdss_mdp_cmd_reconfigure_splash_done(struct mdss_mdp_ctl *ctl);
-int mdss_mdp_video_copy_splash_screen(struct mdss_panel_data *pdata);
-void mdss_mdp_ctl_splash_start(struct mdss_panel_data *pdata);
int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl);
int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl);
int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl,
@@ -571,6 +588,9 @@
int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data);
u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
int mdss_mdp_calc_phase_step(u32 src, u32 dst, u32 *out_phase);
+void mdss_mdp_intersect_rect(struct mdss_mdp_img_rect *res_rect,
+ const struct mdss_mdp_img_rect *dst_rect,
+ const struct mdss_mdp_img_rect *sci_rect);
int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd);
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
@@ -583,11 +603,13 @@
int mdss_mdp_calib_config(struct mdp_calib_config_data *cfg, u32 *copyback);
int mdss_mdp_calib_config_buffer(struct mdp_calib_config_buffer *cfg,
u32 *copyback);
-
+int mdss_mdp_ctl_update_fps(struct mdss_mdp_ctl *ctl, int fps);
int mdss_mdp_pipe_is_staged(struct mdss_mdp_pipe *pipe);
int mdss_mdp_writeback_display_commit(struct mdss_mdp_ctl *ctl, void *arg);
struct mdss_mdp_ctl *mdss_mdp_ctl_mixer_switch(struct mdss_mdp_ctl *ctl,
u32 return_type);
+void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
+ struct mdp_display_commit *data);
int mdss_mdp_wb_set_format(struct msm_fb_data_type *mfd, int dst_format);
int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd,
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d2c684f..503effa 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -428,6 +428,7 @@
ctl->add_vsync_handler = NULL;
ctl->remove_vsync_handler = NULL;
ctl->panel_data = NULL;
+ ctl->config_fps_fnc = NULL;
mutex_unlock(&mdss_mdp_ctl_lock);
return 0;
@@ -602,18 +603,6 @@
return 0;
}
-void mdss_mdp_ctl_splash_start(struct mdss_panel_data *pdata)
-{
- switch (pdata->panel_info.type) {
- case MIPI_VIDEO_PANEL:
- mdss_mdp_video_copy_splash_screen(pdata);
- break;
- case MIPI_CMD_PANEL:
- default:
- break;
- }
-}
-
int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl)
{
switch (ctl->panel_data->panel_info.type) {
@@ -727,6 +716,7 @@
ctl->width = width;
ctl->height = height;
+ ctl->roi = (struct mdss_mdp_img_rect) {0, 0, width, height};
if (!ctl->mixer_left) {
ctl->mixer_left =
@@ -745,6 +735,7 @@
ctl->mixer_left->width = width;
ctl->mixer_left->height = height;
+ ctl->mixer_left->roi = (struct mdss_mdp_img_rect) {0, 0, width, height};
if (split_ctl) {
pr_debug("split display detected\n");
@@ -767,6 +758,8 @@
}
ctl->mixer_right->width = width;
ctl->mixer_right->height = height;
+ ctl->mixer_right->roi = (struct mdss_mdp_img_rect)
+ {0, 0, width, height};
} else if (ctl->mixer_right) {
mdss_mdp_mixer_free(ctl->mixer_right);
ctl->mixer_right = NULL;
@@ -1219,6 +1212,48 @@
return ret;
}
+void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
+ struct mdp_display_commit *data)
+{
+ struct mdss_mdp_img_rect temp_roi, mixer_roi;
+
+ temp_roi.x = data->roi.x;
+ temp_roi.y = data->roi.y;
+ temp_roi.w = data->roi.w;
+ temp_roi.h = data->roi.h;
+
+ /*
+ * No Partial Update for:
+ * 1) dual DSI panels
+ * 2) non-cmd mode panels
+ */
+ if (!temp_roi.w || !temp_roi.h || ctl->mixer_right ||
+ (ctl->panel_data->panel_info.type != MIPI_CMD_PANEL) ||
+ !ctl->panel_data->panel_info.partial_update_enabled) {
+ temp_roi = (struct mdss_mdp_img_rect)
+ {0, 0, ctl->mixer_left->width,
+ ctl->mixer_left->height};
+ }
+
+ ctl->roi_changed = 0;
+ if (((temp_roi.x != ctl->roi.x) ||
+ (temp_roi.y != ctl->roi.y)) ||
+ ((temp_roi.w != ctl->roi.w) ||
+ (temp_roi.h != ctl->roi.h))) {
+ ctl->roi = temp_roi;
+ ctl->roi_changed++;
+
+ mixer_roi = ctl->mixer_left->roi;
+ if ((mixer_roi.w != temp_roi.w) ||
+ (mixer_roi.h != temp_roi.h)) {
+ ctl->mixer_left->roi = temp_roi;
+ ctl->mixer_left->params_changed++;
+ }
+ }
+ pr_debug("ROI requested: [%d, %d, %d, %d]\n",
+ ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h);
+}
+
static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_mixer *mixer)
{
@@ -1227,12 +1262,24 @@
u32 mixercfg = 0, blend_color_out = 0, bg_alpha_enable = 0;
u32 fg_alpha = 0, bg_alpha = 0;
int stage, secure = 0;
+ int screen_state;
+ int outsize = 0;
+
+ screen_state = ctl->force_screen_state;
if (!mixer)
return -ENODEV;
pr_debug("setup mixer=%d\n", mixer->num);
+ outsize = (mixer->roi.h << 16) | mixer->roi.w;
+ mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize);
+
+ if (screen_state == MDSS_SCREEN_FORCE_BLANK) {
+ mixercfg = MDSS_MDP_LM_BORDER_COLOR;
+ goto update_mixer;
+ }
+
pipe = mixer->stage_pipe[MDSS_MDP_STAGE_BASE];
if (pipe == NULL) {
mixercfg = MDSS_MDP_LM_BORDER_COLOR;
@@ -1340,6 +1387,7 @@
if (mixer->cursor_enabled)
mixercfg |= MDSS_MDP_LM_CURSOR_OUT;
+update_mixer:
pr_debug("mixer=%d mixer_cfg=%x\n", mixer->num, mixercfg);
if (mixer->num == MDSS_MDP_INTF_LAYERMIXER3)
@@ -1601,6 +1649,16 @@
return 0;
}
+int mdss_mdp_ctl_update_fps(struct mdss_mdp_ctl *ctl, int fps)
+{
+ int ret = 0;
+
+ if (ctl->config_fps_fnc)
+ ret = ctl->config_fps_fnc(ctl, fps);
+
+ return ret;
+}
+
int mdss_mdp_display_wakeup_time(struct mdss_mdp_ctl *ctl,
ktime_t *wakeup_time)
{
@@ -1739,7 +1797,8 @@
mixer2_changed = (ctl->mixer_right && ctl->mixer_right->params_changed);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- if (mixer1_changed || mixer2_changed) {
+ if (mixer1_changed || mixer2_changed
+ || ctl->force_screen_state) {
perf_update = mdss_mdp_ctl_perf_update(ctl);
if (ctl->prepare_fnc)
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 920c231..addb9b0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -428,6 +428,22 @@
return rc;
}
+static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl)
+{
+ int rc = 0;
+ if (ctl->roi.w && ctl->roi.h && ctl->roi_changed &&
+ ctl->panel_data->panel_info.partial_update_enabled) {
+ ctl->panel_data->panel_info.roi_x = ctl->roi.x;
+ ctl->panel_data->panel_info.roi_y = ctl->roi.y;
+ ctl->panel_data->panel_info.roi_w = ctl->roi.w;
+ ctl->panel_data->panel_info.roi_h = ctl->roi.h;
+
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_ENABLE_PARTIAL_UPDATE, NULL);
+ }
+ return rc;
+}
+
int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_cmd_ctx *ctx;
@@ -450,13 +466,15 @@
WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc);
}
- mdss_mdp_cmd_clk_on(ctx);
+ mdss_mdp_cmd_set_partial_roi(ctl);
/*
* tx dcs command if had any
*/
mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF, NULL);
+ mdss_mdp_cmd_clk_on(ctx);
+
INIT_COMPLETION(ctx->pp_comp);
mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index c78339a..8d4ca2b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -16,6 +16,8 @@
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include "mdss_fb.h"
#include "mdss_mdp.h"
@@ -109,7 +111,7 @@
return 0;
}
-static int mdss_mdp_video_timegen_setup(struct mdss_mdp_video_ctx *ctx,
+static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl,
struct intf_timing_params *p)
{
u32 hsync_period, vsync_period;
@@ -117,7 +119,9 @@
u32 active_h_start, active_h_end, active_v_start, active_v_end;
u32 den_polarity, hsync_polarity, vsync_polarity;
u32 display_hctl, active_hctl, hsync_ctl, polarity_ctl;
+ struct mdss_mdp_video_ctx *ctx;
+ ctx = ctl->priv_data;
hsync_period = p->hsync_pulse_width + p->h_back_porch +
p->width + p->h_front_porch;
vsync_period = p->vsync_pulse_width + p->v_back_porch +
@@ -180,7 +184,7 @@
mdp_video_write(ctx, MDSS_MDP_REG_INTF_HSYNC_CTL, hsync_ctl);
mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0,
- vsync_period * hsync_period);
+ vsync_period * hsync_period);
mdp_video_write(ctx, MDSS_MDP_REG_INTF_VSYNC_PULSE_WIDTH_F0,
p->vsync_pulse_width * hsync_period);
mdp_video_write(ctx, MDSS_MDP_REG_INTF_DISPLAY_HCTL, display_hctl);
@@ -440,6 +444,88 @@
ctl->underrun_cnt);
}
+static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps)
+{
+ struct mdss_mdp_video_ctx *ctx;
+ struct mdss_panel_data *pdata;
+ int rc = 0;
+ u32 hsync_period, vsync_period;
+
+ pr_debug("Updating fps for ctl=%d\n", ctl->num);
+
+ ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data;
+ if (!ctx) {
+ pr_err("invalid ctx\n");
+ return -ENODEV;
+ }
+
+ pdata = ctl->panel_data;
+ if (pdata == NULL) {
+ pr_err("%s: Invalid panel data\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!pdata->panel_info.dynamic_fps) {
+ pr_err("%s: Dynamic fps not enabled for this panel\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ vsync_period = mdss_panel_get_vtotal(&pdata->panel_info);
+ hsync_period = mdss_panel_get_htotal(&pdata->panel_info);
+
+ if (pdata->panel_info.dfps_update
+ != DFPS_SUSPEND_RESUME_MODE) {
+ if (pdata->panel_info.dfps_update
+ == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
+ if (!ctx->timegen_en) {
+ pr_err("TG is OFF. DFPS mode invalid\n");
+ return -EINVAL;
+ }
+ ctl->force_screen_state = MDSS_SCREEN_FORCE_BLANK;
+ mdss_mdp_display_commit(ctl, NULL);
+ mdss_mdp_display_wait4comp(ctl);
+ mdp_video_write(ctx,
+ MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0);
+ /*
+ * Need to wait for atleast one vsync time for proper
+ * TG OFF before doing changes on interfaces
+ */
+ msleep(20);
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_PANEL_UPDATE_FPS,
+ (void *)new_fps);
+ WARN(rc, "intf %d panel fps update error (%d)\n",
+ ctl->intf_num, rc);
+ mdp_video_write(ctx,
+ MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1);
+ /*
+ * Add memory barrier to make sure the MDP Video
+ * mode engine is enabled before next frame is sent
+ */
+ mb();
+ ctl->force_screen_state = MDSS_SCREEN_DEFAULT;
+ mdss_mdp_display_commit(ctl, NULL);
+ mdss_mdp_display_wait4comp(ctl);
+ } else {
+ pr_err("intf %d panel, unknown FPS mode\n",
+ ctl->intf_num);
+ return -EINVAL;
+ }
+ } else {
+ rc = mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_PANEL_UPDATE_FPS,
+ (void *)new_fps);
+ WARN(rc, "intf %d panel fps update error (%d)\n",
+ ctl->intf_num, rc);
+ }
+
+ return rc;
+}
+
+
+
+
static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_video_ctx *ctx;
@@ -492,67 +578,13 @@
return 0;
}
-int mdss_mdp_video_copy_splash_screen(struct mdss_panel_data *pdata)
-{
- void *virt = NULL;
- unsigned long bl_fb_addr = 0;
- unsigned long *bl_fb_addr_va;
- unsigned long pipe_addr, pipe_src_size;
- u32 height, width, rgb_size, bpp;
- size_t size;
- static struct ion_handle *ihdl;
- struct ion_client *iclient = mdss_get_ionclient();
- static ion_phys_addr_t phys;
-
- pipe_addr = MDSS_MDP_REG_SSPP_OFFSET(3) +
- MDSS_MDP_REG_SSPP_SRC0_ADDR;
- pipe_src_size =
- MDSS_MDP_REG_SSPP_OFFSET(3) + MDSS_MDP_REG_SSPP_SRC_SIZE;
-
- bpp = 3;
- rgb_size = MDSS_MDP_REG_READ(pipe_src_size);
- bl_fb_addr = MDSS_MDP_REG_READ(pipe_addr);
-
- height = (rgb_size >> 16) & 0xffff;
- width = rgb_size & 0xffff;
- size = PAGE_ALIGN(height * width * bpp);
- pr_debug("%s:%d splash_height=%d splash_width=%d Buffer size=%d\n",
- __func__, __LINE__, height, width, size);
-
- ihdl = ion_alloc(iclient, size, SZ_1M,
- ION_HEAP(ION_QSECOM_HEAP_ID), 0);
- if (IS_ERR_OR_NULL(ihdl)) {
- pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
- return -ENOMEM;
- }
-
- pdata->panel_info.splash_ihdl = ihdl;
-
- virt = ion_map_kernel(iclient, ihdl);
- ion_phys(iclient, ihdl, &phys, &size);
-
- pr_debug("%s %d Allocating %u bytes at 0x%lx (%pa phys)\n",
- __func__, __LINE__, size,
- (unsigned long int)virt, &phys);
-
- bl_fb_addr_va = (unsigned long *)ioremap(bl_fb_addr, size);
- memcpy(virt, bl_fb_addr_va, size);
- iounmap(bl_fb_addr_va);
-
- MDSS_MDP_REG_WRITE(pipe_addr, phys);
- MDSS_MDP_REG_WRITE(MDSS_MDP_REG_CTL_FLUSH + MDSS_MDP_REG_CTL_OFFSET(0),
- 0x48);
-
- return 0;
-}
-
int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl)
{
- struct ion_client *iclient = mdss_get_ionclient();
struct mdss_panel_data *pdata;
int ret = 0, off;
int mdss_mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION);
int mdss_v2_intf_off = 0;
+ struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(ctl->mfd);
off = 0;
@@ -578,7 +610,12 @@
mdss_v2_intf_off, 0);
/* wait for 1 VSYNC for the pipe to be unstaged */
msleep(20);
- ion_free(iclient, pdata->panel_info.splash_ihdl);
+
+ /* Give back the reserved memory to the system */
+ memblock_free(mdp5_data->splash_mem_addr, mdp5_data->splash_mem_size);
+ free_bootmem_late(mdp5_data->splash_mem_addr,
+ mdp5_data->splash_mem_size);
+
ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CONT_SPLASH_FINISH,
NULL);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
@@ -654,7 +691,7 @@
pinfo->bpp);
itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width;
- if (mdss_mdp_video_timegen_setup(ctx, &itp)) {
+ if (mdss_mdp_video_timegen_setup(ctl, &itp)) {
pr_err("unable to get timing parameters\n");
return -EINVAL;
}
@@ -666,6 +703,7 @@
ctl->read_line_cnt_fnc = mdss_mdp_video_line_count;
ctl->add_vsync_handler = mdss_mdp_video_add_vsync_handler;
ctl->remove_vsync_handler = mdss_mdp_video_remove_vsync_handler;
+ ctl->config_fps_fnc = mdss_mdp_video_config_fps;
return 0;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index fcc87f6..948f275 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -22,6 +22,7 @@
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/msm_mdp.h>
+#include <linux/memblock.h>
#include <mach/iommu_domains.h>
#include <mach/event_timer.h>
@@ -45,6 +46,7 @@
static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd);
static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd);
static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd);
+static int mdss_mdp_overlay_splash_parse_dt(struct msm_fb_data_type *mfd);
static int mdss_mdp_overlay_get(struct msm_fb_data_type *mfd,
struct mdp_overlay *req)
@@ -824,7 +826,8 @@
activate_event_timer(mdp5_data->cpu_pm_hdl, wakeup_time);
}
-int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd)
+int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
+ struct mdp_display_commit *data)
{
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdss_mdp_pipe *pipe;
@@ -847,6 +850,9 @@
return ret;
}
+ if (data)
+ mdss_mdp_set_roi(ctl, data);
+
list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
struct mdss_mdp_data *buf;
/*
@@ -1052,7 +1058,7 @@
mutex_unlock(&mdp5_data->ov_lock);
if (cnt)
- mfd->mdp.kickoff_fnc(mfd);
+ mfd->mdp.kickoff_fnc(mfd, NULL);
list_for_each_entry_safe(rot, tmp, &mdp5_data->rot_proc_list, list) {
if (rot->pid == pid) {
@@ -1073,7 +1079,7 @@
if (!mfd)
return -ENODEV;
- ret = mfd->mdp.kickoff_fnc(mfd);
+ ret = mfd->mdp.kickoff_fnc(mfd, NULL);
if (!ret)
pr_err("error displaying\n");
@@ -1336,7 +1342,7 @@
if (!fbi->fix.smem_start || fbi->fix.smem_len == 0 ||
mdp5_data->borderfill_enable) {
- mfd->mdp.kickoff_fnc(mfd);
+ mfd->mdp.kickoff_fnc(mfd, NULL);
return;
}
@@ -1410,7 +1416,7 @@
if ((fbi->var.activate & FB_ACTIVATE_VBL) ||
(fbi->var.activate & FB_ACTIVATE_FORCE))
- mfd->mdp.kickoff_fnc(mfd);
+ mfd->mdp.kickoff_fnc(mfd, NULL);
return;
@@ -1465,6 +1471,96 @@
return rc;
}
+static ssize_t dynamic_fps_sysfs_rda_dfps(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret;
+ struct mdss_panel_data *pdata;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
+
+ if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
+ return 0;
+
+ pdata = dev_get_platdata(&mfd->pdev->dev);
+ if (!pdata) {
+ pr_err("no panel connected for fb%d\n", mfd->index);
+ return -ENODEV;
+ }
+
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ pdata->panel_info.mipi.frame_rate);
+ pr_debug("%s: '%d'\n", __func__,
+ pdata->panel_info.mipi.frame_rate);
+
+ return ret;
+} /* dynamic_fps_sysfs_rda_dfps */
+
+static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int dfps, rc = 0;
+ struct mdss_panel_data *pdata;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
+
+ rc = kstrtoint(buf, 10, &dfps);
+ if (rc) {
+ pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc);
+ return rc;
+ }
+
+ if (!mdp5_data->ctl || !mdp5_data->ctl->power_on)
+ return 0;
+
+ pdata = dev_get_platdata(&mfd->pdev->dev);
+ if (!pdata) {
+ pr_err("no panel connected for fb%d\n", mfd->index);
+ return -ENODEV;
+ }
+
+ if (dfps == pdata->panel_info.mipi.frame_rate) {
+ pr_debug("%s: FPS is already %d\n",
+ __func__, dfps);
+ return count;
+ }
+
+ if (dfps < 30) {
+ pr_err("Unsupported FPS. Configuring to min_fps = 30\n");
+ dfps = 30;
+ rc = mdss_mdp_ctl_update_fps(mdp5_data->ctl, dfps);
+ } else if (dfps > 60) {
+ pr_err("Unsupported FPS. Configuring to max_fps = 60\n");
+ dfps = 60;
+ rc = mdss_mdp_ctl_update_fps(mdp5_data->ctl, dfps);
+ } else {
+ rc = mdss_mdp_ctl_update_fps(mdp5_data->ctl, dfps);
+ }
+ if (!rc) {
+ pr_info("%s: configured to '%d' FPS\n", __func__, dfps);
+ } else {
+ pr_err("Failed to configure '%d' FPS. rc = %d\n",
+ dfps, rc);
+ return rc;
+ }
+ pdata->panel_info.new_fps = dfps;
+ return count;
+} /* dynamic_fps_sysfs_wta_dfps */
+
+
+static DEVICE_ATTR(dynamic_fps, S_IRUGO | S_IWUSR, dynamic_fps_sysfs_rda_dfps,
+ dynamic_fps_sysfs_wta_dfps);
+
+static struct attribute *dynamic_fps_fs_attrs[] = {
+ &dev_attr_dynamic_fps.attr,
+ NULL,
+};
+static struct attribute_group dynamic_fps_fs_attrs_group = {
+ .attrs = dynamic_fps_fs_attrs,
+};
+
static ssize_t mdss_mdp_vsync_show_event(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -2068,7 +2164,7 @@
break;
case MSMFB_OVERLAY_COMMIT:
mdss_fb_wait_for_fence(mfd);
- ret = mfd->mdp.kickoff_fnc(mfd);
+ ret = mfd->mdp.kickoff_fnc(mfd, NULL);
mdss_fb_signal_timeline(mfd);
break;
case MSMFB_METADATA_SET:
@@ -2144,7 +2240,7 @@
(mfd->panel_info->type != WRITEBACK_PANEL)) {
rc = mdss_mdp_overlay_start(mfd);
if (!IS_ERR_VALUE(rc))
- rc = mdss_mdp_overlay_kickoff(mfd);
+ rc = mdss_mdp_overlay_kickoff(mfd, NULL);
} else {
rc = mdss_mdp_ctl_setup(mdp5_data->ctl);
if (rc)
@@ -2197,7 +2293,7 @@
if (need_cleanup) {
pr_debug("cleaning up pipes on fb%d\n", mfd->index);
- mdss_mdp_overlay_kickoff(mfd);
+ mdss_mdp_overlay_kickoff(mfd, NULL);
}
rc = mdss_mdp_ctl_stop(mdp5_data->ctl);
@@ -2230,7 +2326,6 @@
if (pdata->panel_info.cont_splash_enabled) {
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
mdss_mdp_footswitch_ctrl_splash(1);
- mdss_mdp_ctl_splash_start(pdata);
}
return 0;
}
@@ -2292,6 +2387,15 @@
goto init_fail;
}
+ if (mfd->panel_info->type == MIPI_VIDEO_PANEL) {
+ rc = sysfs_create_group(&dev->kobj,
+ &dynamic_fps_fs_attrs_group);
+ if (rc) {
+ pr_err("Error dfps sysfs creation ret=%d\n", rc);
+ goto init_fail;
+ }
+ }
+
pm_runtime_set_suspended(&mfd->pdev->dev);
pm_runtime_enable(&mfd->pdev->dev);
@@ -2308,8 +2412,48 @@
return rc;
}
+static __ref int mdss_mdp_overlay_splash_parse_dt(struct msm_fb_data_type *mfd)
+{
+ struct platform_device *pdev = mfd->pdev;
+ struct mdss_overlay_private *mdp5_mdata = mfd_to_mdp5_data(mfd);
+ int len = 0, rc = 0;
+ u32 offsets[2];
+
+ of_find_property(pdev->dev.of_node, "qcom,memblock-reserve", &len);
+
+ if (len < 1) {
+ pr_debug("mem reservation for splash screen fb not present\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ len = len/sizeof(u32);
+
+ rc = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,memblock-reserve", offsets, len);
+ if (rc) {
+ pr_debug("Error reading mem reserve settings for fb\n");
+ goto error;
+ }
+
+ if (!memblock_is_reserved(offsets[0])) {
+ pr_debug("failed to reserve memory for fb splash\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
+ mdp5_mdata->splash_mem_addr = offsets[0];
+ mdp5_mdata->splash_mem_size = offsets[1];
+ pr_debug("memaddr=%x size=%x\n", mdp5_mdata->splash_mem_addr,
+ mdp5_mdata->splash_mem_size);
+
+error:
+ return rc;
+}
+
static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd)
{
+ int rc = 0;
struct platform_device *pdev = mfd->pdev;
struct mdss_overlay_private *mdp5_mdata = mfd_to_mdp5_data(mfd);
@@ -2320,5 +2464,13 @@
pdev->name);
}
- return 0;
+ rc = mdss_mdp_overlay_splash_parse_dt(mfd);
+ if (rc && mfd->panel_info->cont_splash_enabled) {
+ pr_err("No rsvd mem found in DT for splash screen\n");
+ } else {
+ pr_debug("Mem reservation not reqd if cont splash diasbled\n");
+ rc = 0;
+ }
+
+ return rc;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 16ea7dc..8920fe1 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -481,16 +481,37 @@
}
+void mdss_mdp_crop_rect(struct mdss_mdp_img_rect *src_rect,
+ struct mdss_mdp_img_rect *dst_rect,
+ const struct mdss_mdp_img_rect *sci_rect)
+{
+ struct mdss_mdp_img_rect res;
+ mdss_mdp_intersect_rect(&res, dst_rect, sci_rect);
+
+ if (res.w && res.h) {
+ if ((res.w != dst_rect->w) || (res.h != dst_rect->h)) {
+ src_rect->x = src_rect->x + (res.x - dst_rect->x);
+ src_rect->y = src_rect->y + (res.y - dst_rect->y);
+ src_rect->w = res.w;
+ src_rect->h = res.h;
+ }
+ *dst_rect = (struct mdss_mdp_img_rect)
+ {(res.x - sci_rect->x), (res.y - sci_rect->y),
+ res.w, res.h};
+ }
+}
+
static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe)
{
u32 img_size, src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
u32 width, height;
u32 decimation;
+ struct mdss_mdp_img_rect sci, dst, src;
pr_debug("pnum=%d wh=%dx%d src={%d,%d,%d,%d} dst={%d,%d,%d,%d}\n",
- pipe->num, pipe->img_width, pipe->img_height,
- pipe->src.x, pipe->src.y, pipe->src.w, pipe->src.h,
- pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h);
+ pipe->num, pipe->img_width, pipe->img_height,
+ pipe->src.x, pipe->src.y, pipe->src.w, pipe->src.h,
+ pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h);
width = pipe->img_width;
height = pipe->img_height;
@@ -512,15 +533,23 @@
pr_debug("Image decimation h=%d v=%d\n",
pipe->horz_deci, pipe->vert_deci);
+ sci = pipe->mixer->ctl->roi;
+ dst = pipe->dst;
+ src = pipe->src;
+
+ mdss_mdp_crop_rect(&src, &dst, &sci);
+
+ src_size = (src.h << 16) | src.w;
+ src_xy = (src.y << 16) | src.x;
+ dst_size = (dst.h << 16) | dst.w;
+ dst_xy = (dst.y << 16) | dst.x;
+
img_size = (height << 16) | width;
- src_size = (pipe->src.h << 16) | pipe->src.w;
- src_xy = (pipe->src.y << 16) | pipe->src.x;
- dst_size = (pipe->dst.h << 16) | pipe->dst.w;
- dst_xy = (pipe->dst.y << 16) | pipe->dst.x;
+
ystride0 = (pipe->src_planes.ystride[0]) |
- (pipe->src_planes.ystride[1] << 16);
+ (pipe->src_planes.ystride[1] << 16);
ystride1 = (pipe->src_planes.ystride[2]) |
- (pipe->src_planes.ystride[3] << 16);
+ (pipe->src_planes.ystride[3] << 16);
if (pipe->overfetch_disable) {
img_size = src_size;
@@ -706,7 +735,8 @@
params_changed = (pipe->params_changed) ||
((pipe->type == MDSS_MDP_PIPE_TYPE_DMA) &&
(pipe->mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)
- && (ctl->mdata->mixer_switched));
+ && (ctl->mdata->mixer_switched)) ||
+ ctl->roi_changed;
if (src_data == NULL) {
mdss_mdp_pipe_solidfill_setup(pipe);
goto update_nobuf;
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index b65d894..1170d1e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -237,6 +237,20 @@
return NULL;
}
+void mdss_mdp_intersect_rect(struct mdss_mdp_img_rect *res_rect,
+ const struct mdss_mdp_img_rect *dst_rect,
+ const struct mdss_mdp_img_rect *sci_rect)
+{
+ int l = max(dst_rect->x, sci_rect->x);
+ int t = max(dst_rect->y, sci_rect->y);
+ int r = min((dst_rect->x + dst_rect->w), (sci_rect->x + sci_rect->w));
+ int b = min((dst_rect->y + dst_rect->h), (sci_rect->y + sci_rect->h));
+
+ if (r < l || b < t)
+ *res_rect = (struct mdss_mdp_img_rect){0, 0, 0, 0};
+ else
+ *res_rect = (struct mdss_mdp_img_rect){l, t, (r-l), (b-t)};
+}
int mdss_mdp_get_rau_strides(u32 w, u32 h,
struct mdss_mdp_format_params *fmt,
struct mdss_mdp_plane_sizes *ps)
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index d05ca66..d5b6ec7 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -112,6 +112,7 @@
* display state from boot loader to panel driver.
* The event handler will enable the panel and
* vote for the display clocks.
+ * @MDSS_EVENT_PANEL_UPDATE_FPS: Event to update the frame rate of the panel.
* @MDSS_EVENT_FB_REGISTERED: Called after fb dev driver has been registered,
* panel driver gets ptr to struct fb_info which
* holds fb dev information.
@@ -119,6 +120,7 @@
- 0 clock disable
- 1 clock enable
* @MDSS_EVENT_DSI_CMDLIST_KOFF: kickoff sending dcs command from command list
+ * @MDSS_EVENT_ENABLE_PARTIAL_UPDATE: Event to update ROI of the panel.
*/
enum mdss_intf_events {
MDSS_EVENT_RESET = 1,
@@ -132,9 +134,11 @@
MDSS_EVENT_CHECK_PARAMS,
MDSS_EVENT_CONT_SPLASH_BEGIN,
MDSS_EVENT_CONT_SPLASH_FINISH,
+ MDSS_EVENT_PANEL_UPDATE_FPS,
MDSS_EVENT_FB_REGISTERED,
MDSS_EVENT_PANEL_CLK_CTRL,
MDSS_EVENT_DSI_CMDLIST_KOFF,
+ MDSS_EVENT_ENABLE_PARTIAL_UPDATE,
};
struct lcd_panel_info {
@@ -214,6 +218,11 @@
char hw_vsync_mode;
};
+enum dynamic_fps_update {
+ DFPS_SUSPEND_RESUME_MODE,
+ DFPS_IMMEDIATE_CLK_UPDATE_MODE,
+};
+
enum lvds_mode {
LVDS_SINGLE_CHANNEL_MODE,
LVDS_DUAL_CHANNEL_MODE,
@@ -264,13 +273,21 @@
u32 is_3d_panel;
u32 out_format;
u32 vic; /* video identification code */
+ u32 roi_x;
+ u32 roi_y;
+ u32 roi_w;
+ u32 roi_h;
int bklt_ctrl; /* backlight ctrl */
int pwm_pmic_gpio;
int pwm_lpg_chan;
int pwm_period;
u32 mode_gpio_state;
+ bool dynamic_fps;
+ char dfps_update;
+ int new_fps;
u32 cont_splash_enabled;
+ u32 partial_update_enabled;
struct ion_handle *splash_ihdl;
u32 panel_power_on;
@@ -354,6 +371,20 @@
pinfo->lcdc.v_pulse_width;
}
+/*
+ * mdss_panel_get_htotal() - return panel horizontal width
+ * @pinfo: Pointer to panel info containing all panel information
+ *
+ * Returns the total width of the panel including any blanking regions
+ * which are not visible to user but used for calculations.
+ */
+static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo)
+{
+ return pinfo->xres + pinfo->lcdc.h_back_porch +
+ pinfo->lcdc.h_front_porch +
+ pinfo->lcdc.h_pulse_width;
+}
+
int mdss_register_panel(struct platform_device *pdev,
struct mdss_panel_data *pdata);
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index d24daab..f7ea557 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -106,13 +106,64 @@
#define PREF_DIV_RATIO 27
struct dsiphy_pll_divider_config pll_divider_config;
-int mdss_dsi_clk_div_config(u8 bpp, u8 lanes,
- u32 *expected_dsi_pclk)
+int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
+ int frame_rate)
{
u32 fb_divider, rate, vco;
u32 div_ratio = 0;
u32 pll_analog_posDiv = 1;
+ u32 h_period, v_period;
+ u32 dsi_pclk_rate;
+ u8 lanes = 0, bpp;
struct dsi_clk_mnd_table const *mnd_entry = mnd_table;
+
+ if (panel_info->mipi.data_lane3)
+ lanes += 1;
+ if (panel_info->mipi.data_lane2)
+ lanes += 1;
+ if (panel_info->mipi.data_lane1)
+ lanes += 1;
+ if (panel_info->mipi.data_lane0)
+ lanes += 1;
+
+ switch (panel_info->mipi.dst_format) {
+ case DSI_CMD_DST_FORMAT_RGB888:
+ case DSI_VIDEO_DST_FORMAT_RGB888:
+ case DSI_VIDEO_DST_FORMAT_RGB666_LOOSE:
+ bpp = 3;
+ break;
+ case DSI_CMD_DST_FORMAT_RGB565:
+ case DSI_VIDEO_DST_FORMAT_RGB565:
+ bpp = 2;
+ break;
+ default:
+ bpp = 3; /* Default format set to RGB888 */
+ break;
+ }
+
+ h_period = mdss_panel_get_htotal(panel_info);
+ v_period = mdss_panel_get_vtotal(panel_info);
+
+ if ((frame_rate !=
+ panel_info->mipi.frame_rate) ||
+ (!panel_info->clk_rate)) {
+ h_period += panel_info->lcdc.xres_pad;
+ v_period += panel_info->lcdc.yres_pad;
+
+ if (lanes > 0) {
+ panel_info->clk_rate =
+ ((h_period * v_period *
+ frame_rate * bpp * 8)
+ / lanes);
+ } else {
+ pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
+ panel_info->clk_rate =
+ (h_period * v_period * frame_rate * bpp * 8);
+ }
+ }
+ pll_divider_config.clk_rate = panel_info->clk_rate;
+
+
if (pll_divider_config.clk_rate == 0)
pll_divider_config.clk_rate = 454000000;
@@ -176,9 +227,13 @@
dsi_pclk.n = mnd_entry->pclk_n;
dsi_pclk.d = mnd_entry->pclk_d;
}
- *expected_dsi_pclk = (((pll_divider_config.clk_rate) * lanes)
+ dsi_pclk_rate = (((pll_divider_config.clk_rate) * lanes)
/ (8 * bpp));
+ if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000))
+ dsi_pclk_rate = 35000000;
+ panel_info->mipi.dsi_pclk_rate = dsi_pclk_rate;
+
return 0;
}
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index baa9d6c..9b21dca 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -862,6 +862,7 @@
uint32_t wait_for_finish;
struct fb_var_screeninfo var;
struct mdp_buf_fence buf_fence;
+ struct mdp_rect roi;
};
struct mdp_page_protection {
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 84c59dc..d950b5c 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -154,6 +154,7 @@
KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
KERN_BOOT_REASON = 77, /* int: identify reason system was booted */
+ KERN_COLD_BOOT = 78, /* int: identify if system cold booted */
};
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 1bb3b06..ed6d41b 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -98,7 +98,7 @@
#define CELSIUS_TO_KELVIN(t) ((t)*10+2732)
struct sensor_threshold {
- int temp;
+ long temp;
enum thermal_trip_type trip;
int (*notify)(enum thermal_trip_type type, int temp, void *data);
void *data;
@@ -108,8 +108,8 @@
struct sensor_info {
uint32_t sensor_id;
struct thermal_zone_device *tz;
- int threshold_min;
- int threshold_max;
+ long threshold_min;
+ long threshold_max;
int max_idx;
int min_idx;
struct list_head sensor_list;
@@ -190,7 +190,7 @@
int sensor_set_trip(uint32_t sensor_id, struct sensor_threshold *threshold);
int sensor_cancel_trip(uint32_t sensor_id, struct sensor_threshold *threshold);
int thermal_sensor_trip(struct thermal_zone_device *tz,
- enum thermal_trip_type trip, unsigned long temp);
+ enum thermal_trip_type trip, long temp);
#ifdef CONFIG_NET
extern int thermal_generate_netlink_event(u32 orig, enum events event);
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 6071e91..663bc05 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -134,6 +134,7 @@
extern struct vm_struct *vmlist;
extern __init void vm_area_add_early(struct vm_struct *vm);
extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
+extern __init int vm_area_check_early(struct vm_struct *vm);
#ifdef CONFIG_SMP
# ifdef CONFIG_MMU
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 540fd2c..326e8bf 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -231,6 +231,7 @@
struct msm_camera_i2c_reg_array {
uint16_t reg_addr;
uint16_t reg_data;
+ uint32_t delay;
};
struct msm_camera_i2c_reg_setting {
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index b390dad..d16a59ec 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1009,7 +1009,15 @@
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = proc_dointvec,
-},
+ },
+
+ {
+ .procname = "cold_boot",
+ .data = &cold_boot,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
#endif
/*
* NOTE: do not add new entries to this table unless you have read
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index acb60be..6170f45 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -138,6 +138,7 @@
{ CTL_INT, KERN_MAX_LOCK_DEPTH, "max_lock_depth" },
{ CTL_INT, KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" },
{ CTL_INT, KERN_BOOT_REASON, "boot_reason" },
+ { CTL_INT, KERN_COLD_BOOT, "cold_boot" },
{}
};
diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c
index 789ff70..bc91cba 100644
--- a/mm/debug-pagealloc.c
+++ b/mm/debug-pagealloc.c
@@ -69,6 +69,7 @@
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
end - start + 1, 1);
+ BUG_ON(PANIC_CORRUPTION);
dump_stack();
}
diff --git a/mm/memory.c b/mm/memory.c
index b6ab040..acc9aa6 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -58,6 +58,7 @@
#include <linux/swapops.h>
#include <linux/elf.h>
#include <linux/gfp.h>
+#include <linux/bug.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
@@ -705,6 +706,9 @@
if (vma->vm_file && vma->vm_file->f_op)
print_symbol(KERN_ALERT "vma->vm_file->f_op->mmap: %s\n",
(unsigned long)vma->vm_file->f_op->mmap);
+
+ BUG_ON(PANIC_CORRUPTION);
+
dump_stack();
add_taint(TAINT_BAD_PAGE);
}
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 5065adb..a2ab2ab 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1116,7 +1116,31 @@
return mem;
}
EXPORT_SYMBOL(vm_map_ram);
+/**
+ * vm_area_check_early - check if vmap area is already mapped
+ * @vm: vm_struct to be checked
+ *
+ * This function is used to check if the vmap area has been
+ * mapped already. @vm->addr, @vm->size and @vm->flags should
+ * contain proper values.
+ *
+ */
+int __init vm_area_check_early(struct vm_struct *vm)
+{
+ struct vm_struct *tmp, **p;
+ BUG_ON(vmap_initialized);
+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+ if (tmp->addr >= vm->addr) {
+ if (tmp->addr < vm->addr + vm->size)
+ return 1;
+ } else {
+ if (tmp->addr + tmp->size > vm->addr)
+ return 1;
+ }
+ }
+ return 0;
+}
/**
* vm_area_add_early - add vmap area early during boot
* @vm: vm_struct to add
@@ -1392,15 +1416,26 @@
*/
struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
{
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ return __get_vm_area_node(size, 1, flags, PAGE_OFFSET, VMALLOC_END,
+ -1, GFP_KERNEL, __builtin_return_address(0));
+#else
return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
-1, GFP_KERNEL, __builtin_return_address(0));
+#endif
+
}
struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
const void *caller)
{
- return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+ return __get_vm_area_node(size, 1, flags, PAGE_OFFSET, VMALLOC_END,
-1, GFP_KERNEL, caller);
+#else
+ return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
+ -1, GFP_KERNEL, __builtin_return_address(0));
+#endif
}
/**
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index c2d626b..0c08fd2 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -1077,6 +1077,18 @@
mbhc->mbhc_cb->enable_mb_source(codec, true);
/*
+ * setup internal micbias if codec uses internal micbias for
+ * headset detection
+ */
+ if (mbhc->mbhc_cfg->use_int_rbias) {
+ if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
+ mbhc->mbhc_cb->setup_int_rbias(codec, true);
+ else
+ pr_err("%s: internal bias is requested but codec did not provide callback\n",
+ __func__);
+ }
+
+ /*
* Request BG and clock.
* These will be released by wcd9xxx_cleanup_hs_polling
*/
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 9460ec0..d1ddfae 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -2003,7 +2003,7 @@
mutex_init(&cdc_mclk_mutex);
mbhc_cfg.gpio_level_insert = of_property_read_bool(pdev->dev.of_node,
- "qcom,headset-jack-type-NO");
+ "qcom,headset-jack-type-NC");
ret = snd_soc_register_card(card);
if (ret == -EPROBE_DEFER)
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index c4b44fe..d80ca19 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -35,8 +35,8 @@
#define MIN_PLAYBACK_PERIOD_SIZE (128 * 2)
#define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6)
-#define MIN_PLAYBACK_NUM_PERIODS (32)
-#define MAX_PLAYBACK_NUM_PERIODS (384)
+#define MIN_PLAYBACK_NUM_PERIODS (64)
+#define MAX_PLAYBACK_NUM_PERIODS (768)
#define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
#define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index bba4c14..27c74ce 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -36,7 +36,7 @@
#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t))
#define ULL_SUPPORTED_SAMPLE_RATE 48000
-
+#define ULL_MAX_SUPPORTED_CHANNEL 2
enum {
ADM_RX_AUDPROC_CAL,
ADM_TX_AUDPROC_CAL,
@@ -1128,8 +1128,9 @@
if (perf_mode) {
open.topology_id = NULL_COPP_TOPOLOGY;
rate = ULL_SUPPORTED_SAMPLE_RATE;
+ if(channel_mode > ULL_MAX_SUPPORTED_CHANNEL)
+ channel_mode = ULL_MAX_SUPPORTED_CHANNEL;
}
-
open.dev_num_channel = channel_mode & 0x00FF;
open.bit_width = bits_per_sample;
WARN_ON(perf_mode && (rate != 48000));