Merge "msm_fb: display: free writeback buffer at correct time" into msm-3.4
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 50894fb..84f0c24 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -103,6 +103,22 @@
- compatible : "qcom,msm-pcm-hostless"
+* msm-ocmem-audio
+
+Required properties:
+
+ - compatible : "qcom,msm-ocmem-audio"
+
+ - qcom,msm-ocmem-audio-src-id: Master port id
+
+ - qcom,msm-ocmem-audio-dst-id: Slave port id
+
+ - qcom,msm-ocmem-audio-ab: arbitrated bandwidth
+ in Bytes/s
+
+ - qcom,msm-ocmem-audio-ib: instantaneous bandwidth
+ in Bytes/s
+
Example:
qcom,msm-pcm {
@@ -172,3 +188,11 @@
compatible = "qcom,msm-pcm-hostless";
};
+ qcom,msm-ocmem-audio {
+ compatible = "qcom,msm-ocmem-audio";
+ qcom,msm-ocmem-audio-src-id = <11>;
+ qcom,msm-ocmem-audio-dst-id = <604>;
+ qcom,msm-ocmem-audio-ab = <209715200>;
+ qcom,msm-ocmem-audio-ib = <471859200>;
+ };
+
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 3a0f0b9..f71f74c 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -439,6 +439,14 @@
compatible = "qcom,msm-pcm-hostless";
};
+ qcom,msm-ocmem-audio {
+ compatible = "qcom,msm-ocmem-audio";
+ qcom,msm-ocmem-audio-src-id = <11>;
+ qcom,msm-ocmem-audio-dst-id = <604>;
+ qcom,msm-ocmem-audio-ab = <32505856>;
+ qcom,msm-ocmem-audio-ib = <32505856>;
+ };
+
qcom,mss@fc880000 {
compatible = "qcom,pil-q6v5-mss";
reg = <0xfc880000 0x100>,
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index e21eed5..ab55bb1 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -698,20 +698,6 @@
help
Support for the Qualcomm MSM8x55 SVLTE SURF eval board.
-config MACH_MSM8X60_RUMI3
- depends on ARCH_MSM8X60
- default n
- bool "MSM8x60 RUMI3"
- help
- Support for the Qualcomm MSM8x60 RUMI3 emulator.
-
-config MACH_MSM8X60_SIM
- depends on ARCH_MSM8X60
- default n
- bool "MSM8x60 Simulator"
- help
- Support for the Qualcomm MSM8x60 simulator.
-
config MACH_MSM8X60_SURF
depends on ARCH_MSM8X60
default n
@@ -757,18 +743,6 @@
help
Support for the Qualcomm MSM8x60 Dragon board.
-config MACH_MSM8960_SIM
- depends on ARCH_MSM8960
- bool "MSM8960 Simulator"
- help
- Support for the Qualcomm MSM8960 simulator.
-
-config MACH_MSM8960_RUMI3
- depends on ARCH_MSM8960
- bool "MSM8960 RUMI3"
- help
- Support for the Qualcomm MSM8960 RUMI3 emulator.
-
config MACH_MSM8960_CDP
depends on ARCH_MSM8960
bool "MSM8960 CDP"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 50f811e..50841ae 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -229,8 +229,6 @@
obj-$(CONFIG_MSM_WATCHDOG) += msm_watchdog.o
obj-$(CONFIG_MSM_WATCHDOG) += msm_watchdog_asm.o
obj-$(CONFIG_MSM_WATCHDOG_V2) += msm_watchdog_v2.o
-obj-$(CONFIG_MACH_MSM8X60_RUMI3) += board-msm8x60.o
-obj-$(CONFIG_MACH_MSM8X60_SIM) += board-msm8x60.o
obj-$(CONFIG_MACH_MSM8X60_SURF) += board-msm8x60.o
obj-$(CONFIG_MACH_MSM8X60_FFA) += board-msm8x60.o
obj-$(CONFIG_MACH_MSM8X60_FLUID) += board-msm8x60.o
@@ -274,8 +272,6 @@
board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o board-8930-gpu.o
board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o board-8064-camera.o board-8064-display.o board-8064-gpu.o
-obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_MTP) += board-8960-all.o board-8960-regulator.o
obj-$(CONFIG_MACH_MSM8960_FLUID) += board-8960-all.o board-8960-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index cf9b877..6f9960d 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -106,102 +106,98 @@
};
static struct l2_level l2_freq_tbl[] __initdata __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 5 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 5 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 5 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 5 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
+ [0] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 5 },
+ [11] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 5 },
+ [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 5 },
+ [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 5 },
+ [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 5 },
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1250000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(14), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(14), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(14), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(14), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(14), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(14), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(14), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(14), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(14), 1250000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 925000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 950000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 975000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1025000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1050000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1075000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1125000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1125000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1150000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1150000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1175000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1175000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1187500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1187500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1200000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(14), 1125000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(14), 1125000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(14), 1150000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(14), 1150000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(14), 1175000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(14), 1175000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(14), 1187500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(14), 1187500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(14), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 850000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 850000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 875000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 900000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 925000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 975000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1000000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1025000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1075000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1075000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1100000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1100000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1125000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1125000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1137500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(15), 1137500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(15), 1150000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 975000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 975000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(14), 1075000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(14), 1075000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(14), 1100000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(14), 1100000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(14), 1125000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(14), 1125000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(14), 1137500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(14), 1137500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(14), 1150000 },
{ 0, { 0 } }
};
@@ -222,6 +218,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0x00700000,
+ .stby_khz = 384000,
};
static int __init acpuclk_8064_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index 9458ea4..1642dae 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -92,36 +92,34 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 1 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 1 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 2 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 3 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
+ [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 1 },
+ [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 1 },
+ [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 2 },
+ [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 3 },
+ [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 3 },
+ [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 3 },
+ [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 4 },
+ [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 4 },
};
/* TODO: Update core voltages when data is available. */
static struct acpu_level acpu_freq_tbl[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 925000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 937500 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 962500 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(9), 987500 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(9), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(9), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(9), 1062500 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(12), 1062500 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(12), 1087500 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(12), 1100000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(4), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(4), 925000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(4), 937500 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(4), 962500 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(8), 987500 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(8), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(8), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(8), 1062500 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1062500 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1087500 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
{ 0, { 0 } }
};
@@ -140,6 +138,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0x00700000,
+ .stby_khz = 384000,
};
static int __init acpuclk_8627_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 3328642..5647d14 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -95,85 +95,81 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
+ [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
+ [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
+ [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
+ [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
+ [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 925000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 925000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 950000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 975000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 975000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 925000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 950000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 950000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 975000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 975000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1050000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1075000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1075000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1100000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1100000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1150000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1150000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1175000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 900000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 900000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 925000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 950000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 950000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 900000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 900000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 925000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 925000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 950000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 950000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1000000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1000000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1025000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1050000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1050000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1100000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1100000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1125000 },
{ 0, { 0 } }
};
@@ -192,6 +188,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0x00700000,
+ .stby_khz = 384000,
};
static int __init acpuclk_8930_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index dbdc244..34ba1da 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -95,97 +95,93 @@
/* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, LVL_NOM, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
+ [0] = { { 384000, PLL_8, 0, 2, 0x00 }, LVL_NOM, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0, 0x20 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0, 0x24 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0, 0x28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0, 0x16 }, LVL_NOM, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0, 0x18 }, LVL_NOM, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0, 0x1A }, LVL_NOM, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0, 0x1C }, LVL_HIGH, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0, 0x1E }, LVL_HIGH, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0, 0x20 }, LVL_HIGH, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0, 0x22 }, LVL_HIGH, 1150000, 7 },
+ [11] = { { 972000, HFPLL, 1, 0, 0x24 }, LVL_HIGH, 1150000, 7 },
+ [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, LVL_HIGH, 1150000, 7 },
+ [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, LVL_HIGH, 1150000, 7 },
+ [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, LVL_HIGH, 1150000, 7 },
+ [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, LVL_HIGH, 1150000, 7 },
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 975000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 1000000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1025000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1075000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1100000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1125000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1175000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1200000 },
+ { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1225000 },
+ { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1237500 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 925000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 925000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 950000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 950000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 975000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 975000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1000000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1000000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1050000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1075000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1075000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1100000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1100000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1175000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1200000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1200000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1212500 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 925000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 950000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 950000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 975000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 975000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 1000000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 1000000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1050000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1050000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1075000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1075000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1100000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1100000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1150000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1150000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1175000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1175000 },
+ { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1200000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1200000 },
+ { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1212500 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 900000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 900000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 925000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 925000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 950000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 950000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1000000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1000000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1025000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1025000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(11), 1050000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(11), 1050000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1125000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1150000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1150000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1162500 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(5), 900000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(5), 900000 },
+ { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(5), 925000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(5), 925000 },
+ { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(5), 950000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(5), 950000 },
+ { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(10), 1000000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(10), 1000000 },
+ { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(10), 1025000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(10), 1025000 },
+ { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(10), 1050000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(10), 1050000 },
+ { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(15), 1100000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(15), 1100000 },
+ { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(15), 1125000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(15), 1125000 },
+ { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(15), 1150000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(15), 1150000 },
+ { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(15), 1162500 },
{ 0, { 0 } }
};
@@ -204,6 +200,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0x00700000,
+ .stby_khz = 384000,
};
static int __init acpuclk_8930aa_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 5ed363d..8cc4b13 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -90,106 +90,102 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0x00 }, 1050000, 1050000, 0 },
- [1] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
- [2] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
- [3] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
- [4] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
- [5] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
- [6] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
- [7] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
- [8] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
- [9] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
- [10] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
- [11] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 6 },
- [12] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 6 },
- [13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 6 },
- [14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 6 },
- [15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 6 },
- [16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 6 },
- [17] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 6 },
- [18] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 6 },
- [19] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 6 },
+ [0] = { { 384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+ [1] = { { 432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 2 },
+ [2] = { { 486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 2 },
+ [3] = { { 540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 2 },
+ [4] = { { 594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
+ [5] = { { 648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 4 },
+ [6] = { { 702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 4 },
+ [7] = { { 756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 4 },
+ [8] = { { 810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 4 },
+ [9] = { { 864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 4 },
+ [10] = { { 918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 6 },
+ [11] = { { 972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 6 },
+ [12] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 6 },
+ [13] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 6 },
+ [14] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 6 },
+ [15] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 6 },
+ [16] = { { 1242000, HFPLL, 1, 0, 0x2E }, 1150000, 1150000, 6 },
+ [17] = { { 1296000, HFPLL, 1, 0, 0x30 }, 1150000, 1150000, 6 },
+ [18] = { { 1350000, HFPLL, 1, 0, 0x32 }, 1150000, 1150000, 6 },
};
static struct acpu_level acpu_freq_tbl_slow[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(19), 1175000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(19), 1175000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(19), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1200000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1225000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1250000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 950000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1175000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1175000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1250000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_nom[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 925000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 950000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 975000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1025000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1050000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1075000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(19), 1125000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(19), 1125000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(19), 1150000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1150000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1175000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1175000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1187500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1187500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1200000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 900000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1125000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1125000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1150000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1150000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1175000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1175000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1187500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1187500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_fast[] __initdata = {
- { 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 850000 },
- { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 850000 },
- { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 875000 },
- { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 900000 },
- { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 925000 },
- { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 975000 },
- { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1000000 },
- { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1025000 },
- { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(19), 1075000 },
- { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(19), 1075000 },
- { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(19), 1100000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1100000 },
- { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1125000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1125000 },
- { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1137500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1137500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1150000 },
+ { 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(0), 850000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(6), 975000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(6), 975000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(6), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(6), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(6), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(6), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(18), 1075000 },
+ { 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(18), 1075000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(18), 1100000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(18), 1100000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(18), 1125000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(18), 1125000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(18), 1137500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(18), 1137500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(18), 1150000 },
{ 0, { 0 } }
};
@@ -208,6 +204,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0x00700000,
+ .stby_khz = 384000,
};
static int __init acpuclk_8960_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index c7800fc..8c89014 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -109,33 +109,31 @@
};
static struct l2_level l2_freq_tbl[] __initdata = {
- [0] = { {STBY_KHZ, QSB, 0, 0, 0 }, LVL_LOW, 1050000, 0 },
- [1] = { { 300000, PLL_0, 0, 2, 0 }, LVL_LOW, 1050000, 2 },
- [2] = { { 384000, HFPLL, 2, 0, 40 }, LVL_NOM, 1050000, 2 },
- [3] = { { 460800, HFPLL, 2, 0, 48 }, LVL_NOM, 1050000, 2 },
- [4] = { { 537600, HFPLL, 1, 0, 28 }, LVL_NOM, 1050000, 2 },
- [5] = { { 576000, HFPLL, 1, 0, 30 }, LVL_NOM, 1050000, 3 },
- [6] = { { 652800, HFPLL, 1, 0, 34 }, LVL_NOM, 1050000, 3 },
- [7] = { { 729600, HFPLL, 1, 0, 38 }, LVL_NOM, 1050000, 3 },
- [8] = { { 806400, HFPLL, 1, 0, 42 }, LVL_NOM, 1050000, 3 },
- [9] = { { 883200, HFPLL, 1, 0, 46 }, LVL_NOM, 1050000, 4 },
- [10] = { { 960000, HFPLL, 1, 0, 50 }, LVL_NOM, 1050000, 4 },
- [11] = { { 1036800, HFPLL, 1, 0, 54 }, LVL_NOM, 1050000, 4 },
+ [0] = { { 300000, PLL_0, 0, 2, 0 }, LVL_LOW, 1050000, 2 },
+ [1] = { { 384000, HFPLL, 2, 0, 40 }, LVL_NOM, 1050000, 2 },
+ [2] = { { 460800, HFPLL, 2, 0, 48 }, LVL_NOM, 1050000, 2 },
+ [3] = { { 537600, HFPLL, 1, 0, 28 }, LVL_NOM, 1050000, 2 },
+ [4] = { { 576000, HFPLL, 1, 0, 30 }, LVL_NOM, 1050000, 3 },
+ [5] = { { 652800, HFPLL, 1, 0, 34 }, LVL_NOM, 1050000, 3 },
+ [6] = { { 729600, HFPLL, 1, 0, 38 }, LVL_NOM, 1050000, 3 },
+ [7] = { { 806400, HFPLL, 1, 0, 42 }, LVL_NOM, 1050000, 3 },
+ [8] = { { 883200, HFPLL, 1, 0, 46 }, LVL_NOM, 1050000, 4 },
+ [9] = { { 960000, HFPLL, 1, 0, 50 }, LVL_NOM, 1050000, 4 },
+ [10] = { { 1036800, HFPLL, 1, 0, 54 }, LVL_NOM, 1050000, 4 },
};
static struct acpu_level acpu_freq_tbl[] __initdata = {
- { 0, {STBY_KHZ, QSB, 0, 0, 0 }, L2(0), 1050000, 3200000 },
- { 1, { 300000, PLL_0, 0, 2, 0 }, L2(1), 1050000, 3200000 },
- { 1, { 384000, HFPLL, 2, 0, 40 }, L2(2), 1050000, 3200000 },
- { 1, { 460800, HFPLL, 2, 0, 48 }, L2(3), 1050000, 3200000 },
- { 1, { 537600, HFPLL, 1, 0, 28 }, L2(4), 1050000, 3200000 },
- { 1, { 576000, HFPLL, 1, 0, 30 }, L2(5), 1050000, 3200000 },
- { 1, { 652800, HFPLL, 1, 0, 34 }, L2(6), 1050000, 3200000 },
- { 1, { 729600, HFPLL, 1, 0, 38 }, L2(7), 1050000, 3200000 },
- { 1, { 806400, HFPLL, 1, 0, 42 }, L2(8), 1050000, 3200000 },
- { 1, { 883200, HFPLL, 1, 0, 46 }, L2(9), 1050000, 3200000 },
- { 1, { 960000, HFPLL, 1, 0, 50 }, L2(10), 1050000, 3200000 },
- { 1, { 1036800, HFPLL, 1, 0, 54 }, L2(11), 1050000, 3200000 },
+ { 1, { 300000, PLL_0, 0, 2, 0 }, L2(0), 1050000, 3200000 },
+ { 1, { 384000, HFPLL, 2, 0, 40 }, L2(1), 1050000, 3200000 },
+ { 1, { 460800, HFPLL, 2, 0, 48 }, L2(2), 1050000, 3200000 },
+ { 1, { 537600, HFPLL, 1, 0, 28 }, L2(3), 1050000, 3200000 },
+ { 1, { 576000, HFPLL, 1, 0, 30 }, L2(4), 1050000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 0, 34 }, L2(5), 1050000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 0, 38 }, L2(6), 1050000, 3200000 },
+ { 1, { 806400, HFPLL, 1, 0, 42 }, L2(7), 1050000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 0, 46 }, L2(8), 1050000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 0, 50 }, L2(9), 1050000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 0, 54 }, L2(10), 1050000, 3200000 },
{ 0, { 0 } }
};
@@ -154,6 +152,7 @@
.l2_freq_tbl_size = sizeof(l2_freq_tbl),
.bus_scale = &bus_scale_data,
.qfprom_phys_base = 0xFC4A8000,
+ .stby_khz = 300000,
};
static int __init acpuclk_8974_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 1469bee..33396e5 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -41,7 +41,6 @@
#define PRI_SRC_SEL_SEC_SRC 0
#define PRI_SRC_SEL_HFPLL 1
#define PRI_SRC_SEL_HFPLL_DIV2 2
-#define SEC_SRC_SEL_QSB 0
#define SEC_SRC_SEL_L2PLL 1
#define SEC_SRC_SEL_AUX 2
@@ -513,6 +512,11 @@
return rc;
}
+static struct acpuclk_data acpuclk_krait_data = {
+ .set_rate = acpuclk_krait_set_rate,
+ .get_rate = acpuclk_krait_get_rate,
+};
+
/* Initialize a HFPLL at a given rate and enable it. */
static void __init hfpll_init(struct scalable *sc,
const struct core_speed *tgt_s)
@@ -775,7 +779,7 @@
}
acpu_level = find_cur_acpu_level(cpu);
- if (!acpu_level || acpu_level->speed.src == QSB) {
+ if (!acpu_level) {
acpu_level = find_min_acpu_level();
if (!acpu_level) {
ret = -ENODEV;
@@ -863,20 +867,20 @@
static void __init cpufreq_table_init(void) {}
#endif
-#define HOT_UNPLUG_KHZ STBY_KHZ
static int __cpuinit acpuclk_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
static int prev_khz[NR_CPUS];
int rc, cpu = (int)hcpu;
struct scalable *sc = &drv.scalable[cpu];
+ unsigned long hot_unplug_khz = acpuclk_krait_data.power_collapse_khz;
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_DEAD:
prev_khz[cpu] = acpuclk_krait_get_rate(cpu);
/* Fall through. */
case CPU_UP_CANCELED:
- acpuclk_krait_set_rate(cpu, HOT_UNPLUG_KHZ, SETRATE_HOTPLUG);
+ acpuclk_krait_set_rate(cpu, hot_unplug_khz, SETRATE_HOTPLUG);
regulator_set_optimum_mode(sc->vreg[VREG_CORE].reg, 0);
break;
case CPU_UP_PREPARE:
@@ -972,13 +976,6 @@
return tbl_idx;
}
-static struct acpuclk_data acpuclk_krait_data = {
- .set_rate = acpuclk_krait_set_rate,
- .get_rate = acpuclk_krait_get_rate,
- .power_collapse_khz = STBY_KHZ,
- .wait_for_irq_khz = STBY_KHZ,
-};
-
static void __init drv_data_init(struct device *dev,
const struct acpuclk_krait_params *params)
{
@@ -1011,6 +1008,9 @@
GFP_KERNEL);
BUG_ON(!drv.acpu_freq_tbl);
drv.boost_uv = params->pvs_tables[tbl_idx].boost_uv;
+
+ acpuclk_krait_data.power_collapse_khz = params->stby_khz;
+ acpuclk_krait_data.wait_for_irq_khz = params->stby_khz;
}
static void __init hw_init(void)
@@ -1033,9 +1033,10 @@
BUG_ON(rc);
l2_level = find_cur_l2_level();
- if (!l2_level || l2_level->speed.src == QSB) {
+ if (!l2_level) {
l2_level = drv.l2_freq_tbl;
- dev_dbg(drv.dev, "L2 is running at an unknown rate. Defaulting to QSB.\n");
+ dev_dbg(drv.dev, "L2 is running at an unknown rate. Defaulting to %lu KHz.\n",
+ l2_level->speed.khz);
} else {
dev_dbg(drv.dev, "L2 is running at %lu KHz\n",
l2_level->speed.khz);
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index 5d29772..5a95e76 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -14,7 +14,6 @@
#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H
#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H
-#define STBY_KHZ 1
#define L2(x) (x)
#define BW_MBPS(_bw) \
{ \
@@ -39,7 +38,6 @@
enum src_id {
PLL_0 = 0,
HFPLL,
- QSB,
PLL_8,
};
@@ -240,6 +238,7 @@
* @l2_freq_tbl_size: Size of @l2_freq_tbl.
* @qfprom_phys_base: Physical base address of QFPROM.
* @bus_scale: MSM bus driver parameters.
+ * @stby_khz: KHz value corresponding to an always-on clock source.
*/
struct acpuclk_krait_params {
struct scalable *scalable;
@@ -250,6 +249,7 @@
size_t l2_freq_tbl_size;
phys_addr_t qfprom_phys_base;
struct msm_bus_scale_pdata *bus_scale;
+ unsigned long stby_khz;
};
/**
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index d3af1a7..ce1c829 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1751,10 +1751,10 @@
static struct msm_thermal_data msm_thermal_pdata = {
.sensor_id = 7,
- .poll_ms = 1000,
- .limit_temp = 60,
- .temp_hysteresis = 10,
- .limit_freq = 918000,
+ .poll_ms = 250,
+ .limit_temp_degC = 60,
+ .temp_hysteresis_degC = 10,
+ .freq_step = 2,
};
#define MSM_SHARED_RAM_PHYS 0x80000000
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 9110849..ed0cc82 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2095,10 +2095,10 @@
static struct msm_thermal_data msm_thermal_pdata = {
.sensor_id = 9,
- .poll_ms = 1000,
- .limit_temp = 60,
- .temp_hysteresis = 10,
- .limit_freq = 918000,
+ .poll_ms = 250,
+ .limit_temp_degC = 60,
+ .temp_hysteresis_degC = 10,
+ .freq_step = 2,
};
#ifdef CONFIG_MSM_FAKE_BATTERY
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 88827ab..ddeba32 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -615,16 +615,6 @@
return mdp_pdata.cont_splash_enabled;
}
-static struct platform_device mipi_dsi_renesas_panel_device = {
- .name = "mipi_renesas",
- .id = 0,
-};
-
-static struct platform_device mipi_dsi_simulator_panel_device = {
- .name = "mipi_simulator",
- .id = 0,
-};
-
#define LPM_CHANNEL0 0
static int toshiba_gpio[] = {LPM_CHANNEL0};
@@ -1015,31 +1005,19 @@
platform_device_register(&wfd_device);
#endif
- if (machine_is_msm8960_sim())
- platform_device_register(&mipi_dsi_simulator_panel_device);
-
- if (machine_is_msm8960_rumi3())
- platform_device_register(&mipi_dsi_renesas_panel_device);
-
- if (!machine_is_msm8960_sim() && !machine_is_msm8960_rumi3()) {
- platform_device_register(&mipi_dsi_novatek_panel_device);
- platform_device_register(&mipi_dsi_orise_panel_device);
+ platform_device_register(&mipi_dsi_novatek_panel_device);
+ platform_device_register(&mipi_dsi_orise_panel_device);
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- platform_device_register(&hdmi_msm_device);
+ platform_device_register(&hdmi_msm_device);
#endif
- }
if (machine_is_msm8960_liquid())
platform_device_register(&mipi_dsi2lvds_bridge_device);
else
platform_device_register(&mipi_dsi_toshiba_panel_device);
- if (machine_is_msm8x60_rumi3()) {
- msm_fb_register_device("mdp", NULL);
- mipi_dsi_pdata.target_type = 1;
- } else
- msm_fb_register_device("mdp", &mdp_pdata);
+ msm_fb_register_device("mdp", &mdp_pdata);
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#ifdef CONFIG_MSM_BUS_SCALING
msm_fb_register_device("dtv", &dtv_pdata);
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 17b0b6f..5950026 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -386,25 +386,6 @@
KEY(0, 3, KEY_CAMERA_FOCUS),
};
-static struct matrix_keymap_data keymap_data_sim = {
- .keymap_size = ARRAY_SIZE(keymap_sim),
- .keymap = keymap_sim,
-};
-
-static struct pm8xxx_keypad_platform_data keypad_data_sim = {
- .input_name = "keypad_8960",
- .input_phys_device = "keypad_8960/input0",
- .num_rows = 12,
- .num_cols = 8,
- .rows_gpio_start = PM8921_GPIO_PM_TO_SYS(9),
- .cols_gpio_start = PM8921_GPIO_PM_TO_SYS(1),
- .debounce_ms = 15,
- .scan_delay_ms = 32,
- .row_hold_ns = 91500,
- .wakeup = 1,
- .keymap_data = &keymap_data_sim,
-};
-
static int pm8921_therm_mitigation[] = {
1100,
700,
@@ -613,10 +594,6 @@
&msm8960_ssbi_pm8921_pdata;
pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
- /* Simulator supports a QWERTY keypad */
- if (machine_is_msm8960_sim())
- pm8921_platform_data.keypad_pdata = &keypad_data_sim;
-
if (machine_is_msm8960_liquid()) {
pm8921_platform_data.keypad_pdata = &keypad_data_liquid;
pm8921_platform_data.leds_pdata = &pm8xxx_leds_pdata_liquid;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 18db7ce..63eef4a 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2382,10 +2382,10 @@
static struct msm_thermal_data msm_thermal_pdata = {
.sensor_id = 0,
- .poll_ms = 1000,
- .limit_temp = 60,
- .temp_hysteresis = 10,
- .limit_freq = 918000,
+ .poll_ms = 250,
+ .limit_temp_degC = 60,
+ .temp_hysteresis_degC = 10,
+ .freq_step = 2,
};
#ifdef CONFIG_MSM_FAKE_BATTERY
@@ -2583,67 +2583,6 @@
&msm_tsens_device,
};
-static struct platform_device *sim_devices[] __initdata = {
- &msm8960_device_uart_gsbi5,
- &msm8960_device_otg,
- &msm8960_device_gadget_peripheral,
- &msm_device_hsusb_host,
- &msm_device_hsic_host,
- &android_usb_device,
- &msm_device_vidc,
- &msm_bus_apps_fabric,
- &msm_bus_sys_fabric,
- &msm_bus_mm_fabric,
- &msm_bus_sys_fpb,
- &msm_bus_cpss_fpb,
- &msm_pcm,
- &msm_multi_ch_pcm,
- &msm_pcm_routing,
- &msm_cpudai0,
- &msm_cpudai1,
- &msm8960_cpudai_slimbus_2_rx,
- &msm8960_cpudai_slimbus_2_tx,
- &msm_cpudai_hdmi_rx,
- &msm_cpudai_bt_rx,
- &msm_cpudai_bt_tx,
- &msm_cpudai_fm_rx,
- &msm_cpudai_fm_tx,
- &msm_cpudai_auxpcm_rx,
- &msm_cpudai_auxpcm_tx,
- &msm_cpu_fe,
- &msm_stub_codec,
- &msm_voice,
- &msm_voip,
- &msm_lpa_pcm,
- &msm_compr_dsp,
- &msm_cpudai_incall_music_rx,
- &msm_cpudai_incall_record_rx,
- &msm_cpudai_incall_record_tx,
-
-#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
- defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
- &qcrypto_device,
-#endif
-
-#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
- defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
- &qcedev_device,
-#endif
-};
-
-static struct platform_device *rumi3_devices[] __initdata = {
- &msm8960_device_uart_gsbi5,
- &msm_kgsl_3d0,
- &msm_kgsl_2d0,
- &msm_kgsl_2d1,
-#ifdef CONFIG_MSM_GEMINI
- &msm8960_gemini_device,
-#endif
-#ifdef CONFIG_MSM_MERCURY
- &msm8960_mercury_device,
-#endif
-};
-
static struct platform_device *cdp_devices[] __initdata = {
&msm_8960_q6_lpass,
&msm_8960_q6_mss_fw,
@@ -3001,10 +2940,6 @@
/* Build the matching 'supported_machs' bitmask */
if (machine_is_msm8960_cdp())
mach_mask = I2C_SURF;
- else if (machine_is_msm8960_rumi3())
- mach_mask = I2C_RUMI;
- else if (machine_is_msm8960_sim())
- mach_mask = I2C_SIM;
else if (machine_is_msm8960_fluid())
mach_mask = I2C_FLUID;
else if (machine_is_msm8960_liquid())
@@ -3043,71 +2978,6 @@
#endif
}
-static void __init msm8960_sim_init(void)
-{
- struct msm_watchdog_pdata *wdog_pdata = (struct msm_watchdog_pdata *)
- &msm8960_device_watchdog.dev.platform_data;
-
- wdog_pdata->bark_time = 15000;
- msm_tsens_early_init(&msm_tsens_pdata);
- msm_thermal_init(&msm_thermal_pdata);
- BUG_ON(msm_rpm_init(&msm8960_rpm_data));
- BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
- regulator_suppress_info_printing();
- platform_device_register(&msm8960_device_rpm_regulator);
- msm_clock_init(&msm8960_clock_init_data);
- msm8960_init_pmic();
-
- msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
- msm8960_init_gpiomux();
- msm8960_i2c_init();
- msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
- msm_spm_l2_init(msm_spm_l2_data);
- msm8960_init_buses();
- platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
- msm8960_pm8921_gpio_mpp_init();
- platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
-
- msm8960_device_qup_spi_gsbi1.dev.platform_data =
- &msm8960_qup_spi_gsbi1_pdata;
- spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-
- msm8960_init_mmc();
- msm8960_init_fb();
- slim_register_board_info(msm_slim_devices,
- ARRAY_SIZE(msm_slim_devices));
- BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-}
-
-static void __init msm8960_rumi3_init(void)
-{
- msm_tsens_early_init(&msm_tsens_pdata);
- msm_thermal_init(&msm_thermal_pdata);
- BUG_ON(msm_rpm_init(&msm8960_rpm_data));
- BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
- regulator_suppress_info_printing();
- platform_device_register(&msm8960_device_rpm_regulator);
- msm8960_init_gpiomux();
- msm8960_init_pmic();
- msm8960_device_qup_spi_gsbi1.dev.platform_data =
- &msm8960_qup_spi_gsbi1_pdata;
- spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
- msm8960_i2c_init();
- msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
- msm_spm_l2_init(msm_spm_l2_data);
- platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
- msm8960_pm8921_gpio_mpp_init();
- platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
- msm8960_init_mmc();
- register_i2c_devices();
-
-
- msm8960_init_fb();
- slim_register_board_info(msm_slim_devices,
- ARRAY_SIZE(msm_slim_devices));
- BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-}
-
static void __init msm8960_cdp_init(void)
{
if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -3200,30 +3070,6 @@
}
}
-MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
- .map_io = msm8960_map_io,
- .reserve = msm8960_reserve,
- .init_irq = msm8960_init_irq,
- .handle_irq = gic_handle_irq,
- .timer = &msm_timer,
- .init_machine = msm8960_sim_init,
- .init_early = msm8960_allocate_memory_regions,
- .init_very_early = msm8960_early_memory,
- .restart = msm_restart,
-MACHINE_END
-
-MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
- .map_io = msm8960_map_io,
- .reserve = msm8960_reserve,
- .init_irq = msm8960_init_irq,
- .handle_irq = gic_handle_irq,
- .timer = &msm_timer,
- .init_machine = msm8960_rumi3_init,
- .init_early = msm8960_allocate_memory_regions,
- .init_very_early = msm8960_early_memory,
- .restart = msm_restart,
-MACHINE_END
-
MACHINE_START(MSM8960_CDP, "QCT MSM8960 CDP")
.map_io = msm8960_map_io,
.reserve = msm8960_reserve,
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index ba4e098..3bd7eeb 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -883,6 +883,7 @@
*/
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
+ .has_outer_cache = 1,
.heaps = {
{
.id = ION_SYSTEM_HEAP_ID,
@@ -896,7 +897,6 @@
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_CAMERA_HEAP_NAME,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
/* PMEM_AUDIO */
@@ -905,7 +905,6 @@
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_AUDIO_HEAP_NAME,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
/* PMEM_MDP = SF */
@@ -914,7 +913,6 @@
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_SF_HEAP_NAME,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
#endif
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 1b21c23..50b1ac5 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -468,26 +468,6 @@
},
};
-/*
- * The smc91x configuration varies depending on platform.
- * The resources data structure is filled in at runtime.
- */
-static struct resource smc91x_resources[] = {
- [0] = {
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = 0,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
-};
-
static struct resource smsc911x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
@@ -4208,72 +4188,6 @@
.id = -1,
};
-static struct platform_device *rumi_sim_devices[] __initdata = {
- &smc91x_device,
- &msm_device_uart_dm12,
-#ifdef CONFIG_I2C_QUP
- &msm_gsbi3_qup_i2c_device,
- &msm_gsbi4_qup_i2c_device,
- &msm_gsbi7_qup_i2c_device,
- &msm_gsbi8_qup_i2c_device,
- &msm_gsbi9_qup_i2c_device,
- &msm_gsbi12_qup_i2c_device,
-#endif
-#ifdef CONFIG_I2C_SSBI
- &msm_device_ssbi3,
-#endif
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
- &android_pmem_device,
- &android_pmem_adsp_device,
- &android_pmem_smipool_device,
- &android_pmem_audio_device,
-#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
-#endif /*CONFIG_ANDROID_PMEM*/
-#ifdef CONFIG_MSM_ROTATOR
- &msm_rotator_device,
-#endif
- &msm_fb_device,
- &msm_kgsl_3d0,
- &msm_kgsl_2d0,
- &msm_kgsl_2d1,
- &lcdc_samsung_panel_device,
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
- &hdmi_msm_device,
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
-#ifdef CONFIG_MSM_CAMERA
-#ifndef CONFIG_MSM_CAMERA_V4L2
-#ifdef CONFIG_MT9E013
- &msm_camera_sensor_mt9e013,
-#endif
-#ifdef CONFIG_IMX074
- &msm_camera_sensor_imx074,
-#endif
-#ifdef CONFIG_VX6953
- &msm_camera_sensor_vx6953,
-#endif
-#ifdef CONFIG_WEBCAM_OV7692
- &msm_camera_sensor_webcam_ov7692,
-#endif
-#ifdef CONFIG_WEBCAM_OV9726
- &msm_camera_sensor_webcam_ov9726,
-#endif
-#ifdef CONFIG_QS_S5K4E1
- &msm_camera_sensor_qs_s5k4e1,
-#endif
-#endif
-#endif
-#ifdef CONFIG_MSM_GEMINI
- &msm_gemini_device,
-#endif
-#ifdef CONFIG_MSM_VPE
-#ifndef CONFIG_MSM_CAMERA_V4L2
- &msm_vpe_device,
-#endif
-#endif
- &msm_device_vidc,
-};
-
#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
enum {
SX150X_CORE,
@@ -7452,10 +7366,6 @@
mach_mask = I2C_SURF;
else if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa())
mach_mask = I2C_FFA;
- else if (machine_is_msm8x60_rumi3())
- mach_mask = I2C_RUMI;
- else if (machine_is_msm8x60_sim())
- mach_mask = I2C_SIM;
else if (machine_is_msm8x60_fluid())
mach_mask = I2C_FLUID;
else if (machine_is_msm8x60_dragon())
@@ -7642,10 +7552,6 @@
machine_is_msm8x60_fluid() ||
machine_is_msm8x60_dragon())
ebi2_cfg |= (1 << 4) | (1 << 5); /* CS2, CS3 */
- else if (machine_is_msm8x60_sim())
- ebi2_cfg |= (1 << 4); /* CS2 */
- else if (machine_is_msm8x60_rumi3())
- ebi2_cfg |= (1 << 5); /* CS3 */
writel_relaxed(ebi2_cfg, ebi2_cfg_ptr);
iounmap(ebi2_cfg_ptr);
@@ -7686,32 +7592,6 @@
}
}
-static void __init msm8x60_configure_smc91x(void)
-{
- if (machine_is_msm8x60_sim()) {
-
- smc91x_resources[0].start = 0x1b800300;
- smc91x_resources[0].end = 0x1b8003ff;
-
- smc91x_resources[1].start = (NR_MSM_IRQS + 40);
- smc91x_resources[1].end = (NR_MSM_IRQS + 40);
-
- } else if (machine_is_msm8x60_rumi3()) {
-
- smc91x_resources[0].start = 0x1d000300;
- smc91x_resources[0].end = 0x1d0003ff;
-
- smc91x_resources[1].start = TLMM_MSM_DIR_CONN_IRQ_0;
- smc91x_resources[1].end = TLMM_MSM_DIR_CONN_IRQ_0;
- }
-}
-
-static void __init msm8x60_init_tlmm(void)
-{
- if (machine_is_msm8x60_rumi3())
- msm_gpio_install_direct_irq(0, 0, 1);
-}
-
#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\
|| defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\
|| defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\
@@ -9875,10 +9755,7 @@
mdp_pdata.num_mdp_clk = 0;
mdp_pdata.mdp_core_clk_rate = 200000000;
#endif
- if (machine_is_msm8x60_rumi3())
- msm_fb_register_device("mdp", NULL);
- else
- msm_fb_register_device("mdp", &mdp_pdata);
+ msm_fb_register_device("mdp", &mdp_pdata);
msm_fb_register_device("lcdc", &lcdc_pdata);
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
@@ -10300,14 +10177,6 @@
struct msm_gpiomux_configs *gpiomux_cfgs;
};
-static struct msm_board_data msm8x60_rumi3_board_data __initdata = {
- .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
-};
-
-static struct msm_board_data msm8x60_sim_board_data __initdata = {
- .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
-};
-
static struct msm_board_data msm8x60_surf_board_data __initdata = {
.gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
};
@@ -10418,12 +10287,9 @@
* it disabled for all others for additional power savings.
*/
if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
- machine_is_msm8x60_rumi3() ||
- machine_is_msm8x60_sim() ||
machine_is_msm8x60_fluid() ||
machine_is_msm8x60_dragon())
msm8x60_init_ebi2();
- msm8x60_init_tlmm();
msm8x60_init_gpiomux(board_data->gpiomux_cfgs);
msm8x60_init_uart12dm();
#ifdef CONFIG_MSM_CAMERA_V4L2
@@ -10513,10 +10379,6 @@
#endif
platform_add_devices(asoc_devices,
ARRAY_SIZE(asoc_devices));
- } else {
- msm8x60_configure_smc91x();
- platform_add_devices(rumi_sim_devices,
- ARRAY_SIZE(rumi_sim_devices));
}
#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
@@ -10540,8 +10402,7 @@
if (machine_is_msm8x60_fluid())
cyttsp_set_params();
#endif
- if (!machine_is_msm8x60_sim())
- msm_fb_add_devices();
+ msm_fb_add_devices();
fixup_i2c_configs();
register_i2c_devices();
@@ -10608,16 +10469,6 @@
msm_fusion_setup_pinctrl();
}
-static void __init msm8x60_rumi3_init(void)
-{
- msm8x60_init(&msm8x60_rumi3_board_data);
-}
-
-static void __init msm8x60_sim_init(void)
-{
- msm8x60_init(&msm8x60_sim_board_data);
-}
-
static void __init msm8x60_surf_init(void)
{
msm8x60_init(&msm8x60_surf_board_data);
@@ -10653,28 +10504,6 @@
msm8x60_init(&msm8x60_dragon_board_data);
}
-MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
- .map_io = msm8x60_map_io,
- .reserve = msm8x60_reserve,
- .init_irq = msm8x60_init_irq,
- .handle_irq = gic_handle_irq,
- .init_machine = msm8x60_rumi3_init,
- .timer = &msm_timer,
- .init_early = msm8x60_charm_init_early,
- .restart = msm_restart,
-MACHINE_END
-
-MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
- .map_io = msm8x60_map_io,
- .reserve = msm8x60_reserve,
- .init_irq = msm8x60_init_irq,
- .handle_irq = gic_handle_irq,
- .init_machine = msm8x60_sim_init,
- .timer = &msm_timer,
- .init_early = msm8x60_charm_init_early,
- .restart = msm_restart,
-MACHINE_END
-
MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
.map_io = msm8x60_map_io,
.reserve = msm8x60_reserve,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index a694557..1921cc3 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -772,6 +772,7 @@
*/
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
+ .has_outer_cache = 1,
.heaps = {
{
.id = ION_SYSTEM_HEAP_ID,
@@ -786,7 +787,6 @@
.name = ION_CAMERA_HEAP_NAME,
.size = MSM_ION_CAMERA_SIZE,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
/* PMEM_AUDIO */
@@ -796,7 +796,6 @@
.name = ION_AUDIO_HEAP_NAME,
.size = MSM_ION_AUDIO_SIZE,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
/* PMEM_MDP = SF */
@@ -806,7 +805,6 @@
.name = ION_SF_HEAP_NAME,
.size = MSM_ION_SF_SIZE,
.memory_type = ION_EBI_TYPE,
- .has_outer_cache = 1,
.extra_data = (void *)&co_ion_pdata,
},
#endif
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 73fd8ef..5463924 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -20,6 +20,7 @@
#include <linux/clk.h>
#include <mach/clk.h>
+#include <mach/rpm-regulator-smd.h>
#include "clock-local2.h"
#include "clock-pll.h"
@@ -197,6 +198,7 @@
#define AHB_CMD_RCGR 0x5000
#define AXI_CMD_RCGR 0x5040
#define OCMEMNOC_CMD_RCGR 0x5090
+#define OCMEMCX_OCMEMNOC_CBCR 0x4058
#define MMSS_BCR 0x0240
#define USB_30_BCR 0x03C0
@@ -580,10 +582,19 @@
VDD_DIG_HIGH
};
+static const int vdd_corner[] = {
+ [VDD_DIG_NONE] = RPM_REGULATOR_CORNER_NONE,
+ [VDD_DIG_LOW] = RPM_REGULATOR_CORNER_SVS_SOC,
+ [VDD_DIG_NOMINAL] = RPM_REGULATOR_CORNER_NORMAL,
+ [VDD_DIG_HIGH] = RPM_REGULATOR_CORNER_SUPER_TURBO,
+};
+
+static struct rpm_regulator *vdd_dig_reg;
+
static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
{
- /* TODO: Actually call into regulator APIs to set VDD_DIG here. */
- return 0;
+ return rpm_regulator_set_voltage(vdd_dig_reg, vdd_corner[level],
+ RPM_REGULATOR_CORNER_SUPER_TURBO);
}
static DEFINE_VDD_CLASS(vdd_dig, set_vdd_dig);
@@ -689,7 +700,7 @@
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "mmpll1_clk_src",
- .rate = 1000000000,
+ .rate = 846000000,
.ops = &clk_ops_pll_vote,
.warned = true,
CLK_INIT(mmpll1_clk_src.c),
@@ -705,6 +716,7 @@
.dbg_name = "mmpll3_clk_src",
.rate = 1000000000,
.ops = &clk_ops_local_pll,
+ .warned = true,
CLK_INIT(mmpll3_clk_src.c),
},
};
@@ -2205,6 +2217,28 @@
},
};
+struct branch_clk gcc_mmss_noc_cfg_ahb_clk = {
+ .cbcr_reg = MMSS_NOC_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mmss_noc_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mmss_noc_cfg_ahb_clk.c),
+ },
+};
+
+struct branch_clk gcc_ocmem_noc_cfg_ahb_clk = {
+ .cbcr_reg = OCMEM_NOC_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ocmem_noc_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_ocmem_noc_cfg_ahb_clk.c),
+ },
+};
+
static struct branch_clk gcc_mss_cfg_ahb_clk = {
.cbcr_reg = MSS_CFG_AHB_CBCR,
.has_sibling = 1,
@@ -2217,10 +2251,11 @@
};
static struct clk_freq_tbl ftbl_mmss_axi_clk[] = {
- F_MM( 19200000, cxo, 1, 0, 0),
- F_MM(150000000, gpll0, 4, 0, 0),
- F_MM(333330000, mmpll1, 3, 0, 0),
- F_MM(400000000, mmpll0, 2, 0, 0),
+ F_MM( 19200000, cxo, 1, 0, 0),
+ F_MM(150000000, gpll0, 4, 0, 0),
+ F_MM(282000000, mmpll1, 3, 0, 0),
+ F_MM(320000000, mmpll1, 2.5, 0, 0),
+ F_MM(400000000, mmpll0, 2, 0, 0),
F_END
};
@@ -2233,8 +2268,8 @@
.c = {
.dbg_name = "axi_clk_src",
.ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 333330000,
- HIGH, 400000000),
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 282000000,
+ HIGH, 320000000),
CLK_INIT(axi_clk_src.c),
},
};
@@ -2242,7 +2277,7 @@
static struct clk_freq_tbl ftbl_ocmemnoc_clk[] = {
F_MM( 19200000, cxo, 1, 0, 0),
F_MM(150000000, gpll0, 4, 0, 0),
- F_MM(333330000, mmpll1, 3, 0, 0),
+ F_MM(282000000, mmpll1, 3, 0, 0),
F_MM(400000000, mmpll0, 2, 0, 0),
F_END
};
@@ -2256,7 +2291,7 @@
.c = {
.dbg_name = "ocmemnoc_clk_src",
.ops = &clk_ops_rcg,
- VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 333330000,
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 282000000,
HIGH, 400000000),
CLK_INIT(ocmemnoc_clk_src.c),
},
@@ -3735,6 +3770,18 @@
},
};
+struct branch_clk ocmemcx_ocmemnoc_clk = {
+ .cbcr_reg = OCMEMCX_OCMEMNOC_CBCR,
+ .parent = &ocmemnoc_clk_src.c,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "ocmemcx_ocmemnoc_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(ocmemcx_ocmemnoc_clk.c),
+ },
+};
+
static struct branch_clk venus0_ahb_clk = {
.cbcr_reg = VENUS0_AHB_CBCR,
.has_sibling = 1,
@@ -4319,6 +4366,8 @@
{&gcc_blsp2_uart5_apps_clk.c, GCC_BASE, 0x00c6},
{&gcc_blsp2_uart6_apps_clk.c, GCC_BASE, 0x00cb},
{&gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x0100},
+ {&gcc_ocmem_noc_cfg_ahb_clk.c, GCC_BASE, 0x0029},
+ {&gcc_mmss_noc_cfg_ahb_clk.c, GCC_BASE, 0x002A},
{&gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
{&gcc_ce1_clk.c, GCC_BASE, 0x0140},
{&gcc_ce2_clk.c, GCC_BASE, 0x0148},
@@ -4346,6 +4395,7 @@
{&mmss_mmssnoc_ahb_clk.c, MMSS_BASE, 0x0001},
{&mmss_mmssnoc_axi_clk.c, MMSS_BASE, 0x0004},
{&ocmemnoc_clk.c, MMSS_BASE, 0x0007},
+ {&ocmemcx_ocmemnoc_clk.c, MMSS_BASE, 0x0009},
{&camss_cci_cci_ahb_clk.c, MMSS_BASE, 0x002e},
{&camss_cci_cci_clk.c, MMSS_BASE, 0x002d},
{&camss_csi0_ahb_clk.c, MMSS_BASE, 0x0042},
@@ -4780,6 +4830,8 @@
CLK_LOOKUP("bus_clk", mdss_axi_clk.c, "mdp.0"),
CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdb00000.qcom,kgsl-3d0"),
CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("mem_iface_clk", ocmemcx_ocmemnoc_clk.c,
+ "fdb00000.qcom,kgsl-3d0"),
CLK_LOOKUP("core_clk", oxilicx_axi_clk.c, "fdb10000.qcom,iommu"),
CLK_LOOKUP("iface_clk", oxilicx_ahb_clk.c, "fdb10000.qcom,iommu"),
CLK_LOOKUP("alt_core_clk", oxili_gfx3d_clk.c, "fdb10000.qcom,iommu"),
@@ -4871,6 +4923,8 @@
CLK_LOOKUP("bus_a_clk", ocmemnoc_clk.c, "msm_ocmem_noc"),
CLK_LOOKUP("bus_clk", mmss_mmssnoc_axi_clk.c, "msm_mmss_noc"),
CLK_LOOKUP("bus_a_clk", mmss_mmssnoc_axi_clk.c, "msm_mmss_noc"),
+ CLK_LOOKUP("iface_clk", gcc_mmss_noc_cfg_ahb_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_ocmem_noc_cfg_ahb_clk.c, ""),
CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etr"),
CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tpiu"),
@@ -4990,9 +5044,9 @@
/* MMPLL1 at 1000 MHz, main output enabled. */
static struct pll_config mmpll1_config __initdata = {
- .l = 0x34,
+ .l = 0x2C,
.m = 0x1,
- .n = 0xC,
+ .n = 0x10,
.vco_val = 0x0,
.vco_mask = BM(21, 20),
.pre_div_val = 0x0,
@@ -5095,8 +5149,8 @@
static void __init msm8974_clock_post_init(void)
{
- clk_set_rate(&axi_clk_src.c, 333330000);
- clk_set_rate(&ocmemnoc_clk_src.c, 333330000);
+ clk_set_rate(&axi_clk_src.c, 282000000);
+ clk_set_rate(&ocmemnoc_clk_src.c, 282000000);
/*
* Hold an active set vote at a rate of 40MHz for the MMSS NOC AHB
@@ -5111,6 +5165,13 @@
*/
clk_prepare_enable(&cxo_a_clk_src.c);
+ /*
+ * TODO: Temporarily enable NOC configuration AHB clocks. Remove when
+ * the bus driver is ready.
+ */
+ clk_prepare_enable(&gcc_mmss_noc_cfg_ahb_clk.c);
+ clk_prepare_enable(&gcc_ocmem_noc_cfg_ahb_clk.c);
+
/* Set rates for single-rate clocks. */
clk_set_rate(&usb30_master_clk_src.c,
usb30_master_clk_src.freq_tbl[0].freq_hz);
@@ -5172,12 +5233,31 @@
clk_ops_local_pll.enable = msm8974_pll_clk_enable;
+ vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig_reg))
+ panic("clock-copper: Unable to get the vdd_dig regulator!");
+
+ /*
+ * TODO: Set a voltage and enable vdd_dig, leaving the voltage high
+ * until late_init. This may not be necessary with clock handoff;
+ * Investigate this code on a real non-simulator target to determine
+ * its necessity.
+ */
+ vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+ rpm_regulator_enable(vdd_dig_reg);
+
reg_init();
}
+static int __init msm8974_clock_late_init(void)
+{
+ return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+}
+
struct clock_init_data msm8974_clock_init_data __initdata = {
.table = msm_clocks_8974,
.size = ARRAY_SIZE(msm_clocks_8974),
.pre_init = msm8974_clock_pre_init,
.post_init = msm8974_clock_post_init,
+ .late_init = msm8974_clock_late_init,
};
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index ca913dc..51e5703 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -355,7 +355,7 @@
{
u32 reg_val;
- reg_val = readl_relaxed(b->ctl_reg);
+ reg_val = b->ctl_reg ? readl_relaxed(b->ctl_reg) : 0;
if (b->en_mask) {
reg_val &= ~(b->en_mask);
writel_relaxed(reg_val, b->ctl_reg);
@@ -564,7 +564,7 @@
if (!branch_in_hwcg_mode(b)) {
b->hwcg_mask = 0;
c->flags &= ~CLKFLAG_HWCG;
- if (readl_relaxed(b->ctl_reg) & b->en_mask)
+ if (b->ctl_reg && readl_relaxed(b->ctl_reg) & b->en_mask)
return HANDOFF_ENABLED_CLK;
} else {
c->flags |= CLKFLAG_HWCG;
diff --git a/arch/arm/mach-msm/mpm-of.c b/arch/arm/mach-msm/mpm-of.c
index cc60596..f98c0f2 100644
--- a/arch/arm/mach-msm/mpm-of.c
+++ b/arch/arm/mach-msm/mpm-of.c
@@ -554,6 +554,14 @@
pr_info("%s(): request_irq failed errno: %d\n", __func__, ret);
goto failed_irq_get;
}
+ ret = irq_set_irq_wake(dev->mpm_ipc_irq, 1);
+
+ if (ret) {
+ pr_err("%s: failed to set wakeup irq %u: %d\n",
+ __func__, dev->mpm_ipc_irq, ret);
+ goto failed_irq_get;
+
+ }
msm_mpm_initialized |= MSM_MPM_DEVICE_PROBED;
return 0;
diff --git a/arch/arm/mach-msm/msm-krait-l2-accessors.c b/arch/arm/mach-msm/msm-krait-l2-accessors.c
index 41a2490..3da155a 100644
--- a/arch/arm/mach-msm/msm-krait-l2-accessors.c
+++ b/arch/arm/mach-msm/msm-krait-l2-accessors.c
@@ -82,10 +82,6 @@
u32 uninitialized_var(l2cpuvrf8_val), l2cpuvrf8_addr = 0;
u32 ret_val;
- /* CP15 registers are not emulated on RUMI3. */
- if (machine_is_msm8960_rumi3())
- return 0;
-
raw_spin_lock_irqsave(&l2_access_lock, flags);
if (l2cpuvrf8_needs_fix(reg_addr))
@@ -115,10 +111,6 @@
unsigned long flags;
u32 uninitialized_var(l2cpuvrf8_val), l2cpuvrf8_addr = 0;
- /* CP15 registers are not emulated on RUMI3. */
- if (machine_is_msm8960_rumi3())
- return;
-
raw_spin_lock_irqsave(&l2_access_lock, flags);
if (l2cpuvrf8_needs_fix(reg_addr))
@@ -144,9 +136,6 @@
{
u32 val;
unsigned long flags;
- /* CP15 registers are not emulated on RUMI3. */
- if (machine_is_msm8960_rumi3())
- return 0;
raw_spin_lock_irqsave(&l2_access_lock, flags);
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index e279f99..62685ca 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -155,11 +155,14 @@
goto err_clks;
/* Program Image Address */
- if (drv->self_auth)
+ if (drv->self_auth) {
writel_relaxed(drv->start_addr, drv->rmb_base + RMB_MBA_IMAGE);
- else
+ /* Ensure write to RMB base occurs before reset is released. */
+ mb();
+ } else {
writel_relaxed((drv->start_addr >> 4) & 0x0FFFFFF0,
drv->reg_base + QDSP6SS_RST_EVB);
+ }
ret = pil_q6v5_reset(pil);
if (ret)
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 5e063a1..08cbc34 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -83,11 +83,6 @@
if (!base_ptr)
return -ENODEV;
- if (machine_is_msm8960_sim() || machine_is_msm8960_rumi3()) {
- writel_relaxed(0x10, base_ptr+0x04);
- writel_relaxed(0x80, base_ptr+0x04);
- }
-
if (machine_is_apq8064_sim())
writel_relaxed(0xf0000, base_ptr+0x04);
@@ -135,8 +130,7 @@
if (cpu_is_msm8x60())
return scorpion_release_secondary();
- if (machine_is_msm8960_sim() || machine_is_msm8960_rumi3() ||
- machine_is_apq8064_sim())
+ if (machine_is_apq8064_sim())
return krait_release_secondary_sim(0x02088000, cpu);
if (machine_is_msm8974_sim())
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index f3b5720..bea567b 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -628,8 +628,7 @@
static void * __init setup_dummy_socinfo(void)
{
- if (machine_is_msm8960_rumi3() || machine_is_msm8960_sim() ||
- machine_is_msm8960_cdp())
+ if (machine_is_msm8960_cdp())
dummy_socinfo.id = 87;
else if (machine_is_apq8064_rumi3() || machine_is_apq8064_sim())
dummy_socinfo.id = 109;
@@ -758,7 +757,6 @@
return 1;
if (read_cpuid_mpidr() & BIT(30) &&
- !machine_is_msm8960_sim() &&
!machine_is_apq8064_sim())
return 1;
@@ -768,9 +766,6 @@
const int read_msm_cpu_type(void)
{
- if (machine_is_msm8960_sim() || machine_is_msm8960_rumi3())
- return MSM_CPU_8960;
-
if (socinfo_get_msm_cpu() != MSM_CPU_UNKNOWN)
return socinfo_get_msm_cpu();
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 2f48999..fc51970 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -303,8 +303,8 @@
device->mmu.setstate_memory.gpuaddr +
KGSL_IOMMU_SETSTATE_NOP_OFFSET);
+ pt_val = kgsl_mmu_pt_get_base_addr(device->mmu.hwpagetable);
if (flags & KGSL_MMUFLAGS_PTUPDATE) {
- pt_val = kgsl_mmu_pt_get_base_addr(device->mmu.hwpagetable);
/*
* We need to perfrom the following operations for all
* IOMMU units
@@ -338,24 +338,6 @@
reg_pt_val,
device->mmu.setstate_memory.gpuaddr +
KGSL_IOMMU_SETSTATE_NOP_OFFSET);
-
- /* set the asid */
- *cmds++ = cp_type3_packet(CP_MEM_WRITE, 2);
- *cmds++ = reg_map_desc[i]->gpuaddr +
- (KGSL_IOMMU_CONTEXT_USER <<
- KGSL_IOMMU_CTX_SHIFT) + KGSL_IOMMU_CONTEXTIDR;
- *cmds++ = kgsl_mmu_get_hwpagetable_asid(&device->mmu);
- *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
- *cmds++ = 0x00000000;
-
- /* Read back asid to ensure above write completes */
- cmds += adreno_add_read_cmds(device, cmds,
- reg_map_desc[i]->gpuaddr +
- (KGSL_IOMMU_CONTEXT_USER <<
- KGSL_IOMMU_CTX_SHIFT) + KGSL_IOMMU_CONTEXTIDR,
- kgsl_mmu_get_hwpagetable_asid(&device->mmu),
- device->mmu.setstate_memory.gpuaddr +
- KGSL_IOMMU_SETSTATE_NOP_OFFSET);
}
/* invalidate all base pointers */
*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
@@ -367,15 +349,21 @@
}
if (flags & KGSL_MMUFLAGS_TLBFLUSH) {
/*
- * tlb flush based on asid, no need to flush entire tlb
+ * tlb flush
*/
for (i = 0; i < num_iommu_units; i++) {
+ reg_pt_val = (pt_val &
+ (KGSL_IOMMU_TTBR0_PA_MASK <<
+ KGSL_IOMMU_TTBR0_PA_SHIFT)) +
+ kgsl_mmu_get_pt_lsb(&device->mmu, i,
+ KGSL_IOMMU_CONTEXT_USER);
+
*cmds++ = cp_type3_packet(CP_MEM_WRITE, 2);
*cmds++ = (reg_map_desc[i]->gpuaddr +
(KGSL_IOMMU_CONTEXT_USER <<
KGSL_IOMMU_CTX_SHIFT) +
- KGSL_IOMMU_CTX_TLBIASID);
- *cmds++ = kgsl_mmu_get_hwpagetable_asid(&device->mmu);
+ KGSL_IOMMU_CTX_TLBIALL);
+ *cmds++ = 1;
cmds += __adreno_add_idle_indirect_cmds(cmds,
device->mmu.setstate_memory.gpuaddr +
@@ -384,9 +372,8 @@
cmds += adreno_add_read_cmds(device, cmds,
reg_map_desc[i]->gpuaddr +
(KGSL_IOMMU_CONTEXT_USER <<
- KGSL_IOMMU_CTX_SHIFT) +
- KGSL_IOMMU_CONTEXTIDR,
- kgsl_mmu_get_hwpagetable_asid(&device->mmu),
+ KGSL_IOMMU_CTX_SHIFT) + KGSL_IOMMU_TTBR0,
+ reg_pt_val,
device->mmu.setstate_memory.gpuaddr +
KGSL_IOMMU_SETSTATE_NOP_OFFSET);
}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index d54ce6b..86a349a 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -120,6 +120,8 @@
goto err;
}
+ continue;
+
err:
if (!adreno_dump_and_recover(rb->device))
wait_time = jiffies + wait_timeout;
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 998eaab..edccff1 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -732,7 +732,6 @@
.mmu_get_current_ptbase = kgsl_gpummu_get_current_ptbase,
.mmu_enable_clk = NULL,
.mmu_disable_clk_on_ts = NULL,
- .mmu_get_hwpagetable_asid = NULL,
.mmu_get_pt_lsb = NULL,
.mmu_get_reg_map_desc = NULL,
};
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 25d0463..016771b 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -292,14 +292,6 @@
struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt;
if (iommu_pt->domain)
iommu_domain_free(iommu_pt->domain);
- if (iommu_pt->iommu) {
- if ((KGSL_IOMMU_ASID_REUSE == iommu_pt->asid) &&
- iommu_pt->iommu->asid_reuse)
- iommu_pt->iommu->asid_reuse--;
- if (!iommu_pt->iommu->asid_reuse ||
- (KGSL_IOMMU_ASID_REUSE != iommu_pt->asid))
- clear_bit(iommu_pt->asid, iommu_pt->iommu->asids);
- }
kfree(iommu_pt);
}
@@ -621,20 +613,15 @@
unsigned int context_id)
{
if (mmu->flags & KGSL_FLAGS_STARTED) {
- struct kgsl_iommu *iommu = mmu->priv;
- struct kgsl_iommu_pt *iommu_pt = pagetable->priv;
/* page table not current, then setup mmu to use new
* specified page table
*/
if (mmu->hwpagetable != pagetable) {
unsigned int flags = 0;
mmu->hwpagetable = pagetable;
- /* force tlb flush if asid is reused */
- if (iommu->asid_reuse &&
- (KGSL_IOMMU_ASID_REUSE == iommu_pt->asid))
- flags |= KGSL_MMUFLAGS_TLBFLUSH;
flags |= kgsl_mmu_pt_get_flags(mmu->hwpagetable,
- mmu->device->id);
+ mmu->device->id) |
+ KGSL_MMUFLAGS_TLBFLUSH;
kgsl_setstate(mmu, context_id,
KGSL_MMUFLAGS_PTUPDATE | flags);
}
@@ -657,14 +644,6 @@
sizeof(struct kgsl_iommu));
return -ENOMEM;
}
- iommu->asids = kzalloc(BITS_TO_LONGS(KGSL_IOMMU_MAX_ASIDS) *
- sizeof(unsigned long), GFP_KERNEL);
- if (!iommu->asids) {
- KGSL_CORE_ERR("kzalloc(%d) failed\n",
- sizeof(struct kgsl_iommu));
- status = -ENOMEM;
- goto done;
- }
mmu->priv = iommu;
status = kgsl_get_iommu_ctxt(mmu);
@@ -684,7 +663,6 @@
__func__);
done:
if (status) {
- kfree(iommu->asids);
kfree(iommu);
mmu->priv = NULL;
}
@@ -718,7 +696,6 @@
goto err;
}
iommu_pt = mmu->priv_bank_table->priv;
- iommu_pt->asid = 1;
}
mmu->defaultpagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
/* Return error if the default pagetable doesn't exist */
@@ -740,14 +717,6 @@
goto err;
}
}
- /*
- * The dafault pagetable always has asid 0 assigned by the iommu driver
- * and asid 1 is assigned to the private context.
- */
- iommu_pt = mmu->defaultpagetable->priv;
- iommu_pt->asid = 0;
- set_bit(0, iommu->asids);
- set_bit(1, iommu->asids);
return status;
err:
for (i--; i >= 0; i--) {
@@ -818,12 +787,6 @@
*/
for (i = 0; i < iommu->unit_count; i++) {
struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
- /* Make sure that the ASID of the priv bank is set to 1.
- * When we a different pagetable for the priv bank then the
- * iommu driver sets the ASID to 0 instead of 1 */
- KGSL_IOMMU_SET_IOMMU_REG(iommu->iommu_units[i].reg_map.hostptr,
- KGSL_IOMMU_CONTEXT_PRIV,
- CONTEXTIDR, 1);
for (j = 0; j < iommu_unit->dev_count; j++)
iommu_unit->dev[j].pt_lsb = KGSL_IOMMMU_PT_LSB(
KGSL_IOMMU_GET_IOMMU_REG(
@@ -831,10 +794,6 @@
iommu_unit->dev[j].ctx_id,
TTBR0));
}
- iommu->asid = KGSL_IOMMU_GET_IOMMU_REG(
- iommu->iommu_units[0].reg_map.hostptr,
- KGSL_IOMMU_CONTEXT_USER,
- CONTEXTIDR);
kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
mmu->flags |= KGSL_FLAGS_STARTED;
@@ -955,7 +914,6 @@
kgsl_mmu_putpagetable(mmu->priv_bank_table);
if (mmu->defaultpagetable)
kgsl_mmu_putpagetable(mmu->defaultpagetable);
- kfree(iommu->asids);
kfree(iommu);
return 0;
@@ -981,47 +939,6 @@
}
/*
- * kgsl_iommu_get_hwpagetable_asid - Returns asid(application space ID) for a
- * pagetable
- * @mmu - Pointer to mmu structure
- *
- * Allocates an asid to a IOMMU domain if it does not already have one. asid's
- * are unique identifiers for pagetable that can be used to selectively flush
- * tlb entries of the IOMMU unit.
- * Return - asid to be used with the IOMMU domain
- */
-static int kgsl_iommu_get_hwpagetable_asid(struct kgsl_mmu *mmu)
-{
- struct kgsl_iommu *iommu = mmu->priv;
- struct kgsl_iommu_pt *iommu_pt = mmu->hwpagetable->priv;
-
- /*
- * If the iommu pagetable does not have any asid assigned and is not the
- * default pagetable then assign asid.
- */
- if (!iommu_pt->asid && iommu_pt != mmu->defaultpagetable->priv) {
- iommu_pt->asid = find_first_zero_bit(iommu->asids,
- KGSL_IOMMU_MAX_ASIDS);
- /* No free bits means reuse asid */
- if (iommu_pt->asid >= KGSL_IOMMU_MAX_ASIDS) {
- iommu_pt->asid = KGSL_IOMMU_ASID_REUSE;
- iommu->asid_reuse++;
- }
- set_bit(iommu_pt->asid, iommu->asids);
- /*
- * Store pointer to asids list so that during pagetable destroy
- * the asid assigned to this pagetable may be cleared
- */
- iommu_pt->iommu = iommu;
- }
- /* Return the asid + the constant part of asid that never changes */
- return (iommu_pt->asid & (KGSL_IOMMU_CONTEXTIDR_ASID_MASK <<
- KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT)) +
- (iommu->asid & ~(KGSL_IOMMU_CONTEXTIDR_ASID_MASK <<
- KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT));
-}
-
-/*
* kgsl_iommu_default_setstate - Change the IOMMU pagetable or flush IOMMU tlb
* of the primary context bank
* @mmu - Pointer to mmu structure
@@ -1066,15 +983,6 @@
temp = KGSL_IOMMU_GET_IOMMU_REG(
iommu->iommu_units[i].reg_map.hostptr,
KGSL_IOMMU_CONTEXT_USER, TTBR0);
- /* Set asid */
- KGSL_IOMMU_SET_IOMMU_REG(
- iommu->iommu_units[i].reg_map.hostptr,
- KGSL_IOMMU_CONTEXT_USER, CONTEXTIDR,
- kgsl_iommu_get_hwpagetable_asid(mmu));
- mb();
- temp = KGSL_IOMMU_GET_IOMMU_REG(
- iommu->iommu_units[i].reg_map.hostptr,
- KGSL_IOMMU_CONTEXT_USER, CONTEXTIDR);
}
}
/* Flush tlb */
@@ -1082,8 +990,8 @@
for (i = 0; i < iommu->unit_count; i++) {
KGSL_IOMMU_SET_IOMMU_REG(
iommu->iommu_units[i].reg_map.hostptr,
- KGSL_IOMMU_CONTEXT_USER, CTX_TLBIASID,
- kgsl_iommu_get_hwpagetable_asid(mmu));
+ KGSL_IOMMU_CONTEXT_USER, CTX_TLBIALL,
+ 1);
mb();
}
}
@@ -1139,7 +1047,6 @@
.mmu_get_current_ptbase = kgsl_iommu_get_current_ptbase,
.mmu_enable_clk = kgsl_iommu_enable_clk,
.mmu_disable_clk_on_ts = kgsl_iommu_disable_clk_on_ts,
- .mmu_get_hwpagetable_asid = kgsl_iommu_get_hwpagetable_asid,
.mmu_get_pt_lsb = kgsl_iommu_get_pt_lsb,
.mmu_get_reg_map_desc = kgsl_iommu_get_reg_map_desc,
};
diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h
index 354a5cf..f14db93 100644
--- a/drivers/gpu/msm/kgsl_iommu.h
+++ b/drivers/gpu/msm/kgsl_iommu.h
@@ -23,15 +23,8 @@
#define KGSL_IOMMU_TTBR0_PA_MASK 0x0003FFFF
#define KGSL_IOMMU_TTBR0_PA_SHIFT 14
#define KGSL_IOMMU_CTX_TLBIALL 0x800
-#define KGSL_IOMMU_CONTEXTIDR 0x8
-#define KGSL_IOMMU_CONTEXTIDR_ASID_MASK 0xFF
-#define KGSL_IOMMU_CONTEXTIDR_ASID_SHIFT 0
-#define KGSL_IOMMU_CTX_TLBIASID 0x804
#define KGSL_IOMMU_CTX_SHIFT 12
-#define KGSL_IOMMU_MAX_ASIDS 256
-#define KGSL_IOMMU_ASID_REUSE 2
-
/*
* Max number of iommu units that the gpu core can have
* On APQ8064, KGSL can control a maximum of 2 IOMMU units.
@@ -106,10 +99,6 @@
* @clk_event_queued: Indicates whether an event to disable clocks
* is already queued or not
* @device: Pointer to kgsl device
- * @asids: A bit structure indicating which id's are presently used
- * @asid: Contains the initial value of IOMMU_CONTEXTIDR when a domain
- * is first attached
- * asid_reuse: Holds the number of times the reuse asid is reused
*/
struct kgsl_iommu {
struct kgsl_iommu_unit iommu_units[KGSL_IOMMU_MAX_UNITS];
@@ -117,21 +106,16 @@
unsigned int iommu_last_cmd_ts;
bool clk_event_queued;
struct kgsl_device *device;
- unsigned long *asids;
- unsigned int asid;
- unsigned int asid_reuse;
};
/*
* struct kgsl_iommu_pt - Iommu pagetable structure private to kgsl driver
* @domain: Pointer to the iommu domain that contains the iommu pagetable
* @iommu: Pointer to iommu structure
- * @asid: The asid assigned to this domain
*/
struct kgsl_iommu_pt {
struct iommu_domain *domain;
struct kgsl_iommu *iommu;
- unsigned int asid;
};
#endif
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index f8a2ea4..bc6ec8e 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -136,7 +136,6 @@
(struct kgsl_mmu *mmu, uint32_t ts, bool ts_valid);
int (*mmu_enable_clk)
(struct kgsl_mmu *mmu, int ctx_id);
- int (*mmu_get_hwpagetable_asid)(struct kgsl_mmu *mmu);
int (*mmu_get_pt_lsb)(struct kgsl_mmu *mmu,
unsigned int unit_id,
enum kgsl_iommu_context_id ctx_id);
@@ -278,14 +277,6 @@
return 0;
}
-static inline int kgsl_mmu_get_hwpagetable_asid(struct kgsl_mmu *mmu)
-{
- if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_hwpagetable_asid)
- return mmu->mmu_ops->mmu_get_hwpagetable_asid(mmu);
- else
- return 0;
-}
-
static inline int kgsl_mmu_enable_clk(struct kgsl_mmu *mmu,
int ctx_id)
{
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 7a87ca9..3a02d3a 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1136,11 +1136,15 @@
}
}
- /* Clear CDR_EN bit for write operations */
- if (host->tuning_needed && cmd->mrq->data &&
- (cmd->mrq->data->flags & MMC_DATA_WRITE))
- writel_relaxed((readl_relaxed(host->base + MCI_DLL_CONFIG) &
- ~MCI_CDR_EN), host->base + MCI_DLL_CONFIG);
+ if (cmd->mrq->data && (cmd->mrq->data->flags & MMC_DATA_READ))
+ writel_relaxed((readl_relaxed(host->base +
+ MCI_DLL_CONFIG) | MCI_CDR_EN),
+ host->base + MCI_DLL_CONFIG);
+ else
+ /* Clear CDR_EN bit for non read operations */
+ writel_relaxed((readl_relaxed(host->base +
+ MCI_DLL_CONFIG) & ~MCI_CDR_EN),
+ host->base + MCI_DLL_CONFIG);
if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
*c |= MCI_CPSM_PROGENA;
@@ -3083,8 +3087,10 @@
* Select the controller timing mode according
* to current bus speed mode
*/
- if ((ios->timing == MMC_TIMING_UHS_SDR104) ||
- (ios->timing == MMC_TIMING_MMC_HS200)) {
+ if (host->clk_rate > (100 * 1000 * 1000) &&
+ (ios->timing == MMC_TIMING_UHS_SDR104 ||
+ ios->timing == MMC_TIMING_MMC_HS200)) {
+ /* Card clock frequency must be > 100MHz to enable tuning */
clk |= (4 << 14);
host->tuning_needed = 1;
} else if (ios->timing == MMC_TIMING_UHS_DDR50) {
diff --git a/drivers/platform/msm/qpnp-pwm.c b/drivers/platform/msm/qpnp-pwm.c
index c9cd0e0..708d658 100644
--- a/drivers/platform/msm/qpnp-pwm.c
+++ b/drivers/platform/msm/qpnp-pwm.c
@@ -440,7 +440,7 @@
unsigned int pwm_value, max_pwm_value;
struct qpnp_lpg_chip *chip = pwm->chip;
struct qpnp_lut_config *lut = &chip->lpg_config.lut_config;
- int i, pwm_size, rc;
+ int i, pwm_size, rc = 0;
int burst_size = SPMI_MAX_BUF_LEN;
int list_len = lut->list_size << 1;
int offset = lut->lo_index << 2;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index a8d3720..0575d80 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -28,6 +28,33 @@
static uint32_t limited_max_freq = MSM_CPUFREQ_NO_LIMIT;
static struct delayed_work check_temp_work;
+static int limit_idx;
+static int limit_idx_low;
+static int limit_idx_high;
+static struct cpufreq_frequency_table *table;
+
+static int msm_thermal_get_freq_table(void)
+{
+ int ret = 0;
+ int i = 0;
+
+ table = cpufreq_frequency_get_table(0);
+ if (table == NULL) {
+ pr_debug("%s: error reading cpufreq table\n", __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ while (table[i].frequency != CPUFREQ_TABLE_END)
+ i++;
+
+ limit_idx_low = 0;
+ limit_idx_high = limit_idx = i - 1;
+ BUG_ON(limit_idx_high <= 0 || limit_idx_high <= limit_idx_low);
+fail:
+ return ret;
+}
+
static int update_cpu_max_freq(int cpu, uint32_t max_freq)
{
int ret = 0;
@@ -36,10 +63,6 @@
if (ret)
return ret;
- ret = cpufreq_update_policy(cpu);
- if (ret)
- return ret;
-
limited_max_freq = max_freq;
if (max_freq != MSM_CPUFREQ_NO_LIMIT)
pr_info("msm_thermal: Limiting cpu%d max frequency to %d\n",
@@ -47,11 +70,14 @@
else
pr_info("msm_thermal: Max frequency reset for cpu%d\n", cpu);
+ ret = cpufreq_update_policy(cpu);
+
return ret;
}
static void check_temp(struct work_struct *work)
{
+ static int limit_init;
struct tsens_device tsens_dev;
unsigned long temp = 0;
uint32_t max_freq = limited_max_freq;
@@ -66,12 +92,34 @@
goto reschedule;
}
- if (temp >= msm_thermal_info.limit_temp)
- max_freq = msm_thermal_info.limit_freq;
- else if (temp <
- msm_thermal_info.limit_temp - msm_thermal_info.temp_hysteresis)
- max_freq = MSM_CPUFREQ_NO_LIMIT;
+ if (!limit_init) {
+ ret = msm_thermal_get_freq_table();
+ if (ret)
+ goto reschedule;
+ else
+ limit_init = 1;
+ }
+ if (temp >= msm_thermal_info.limit_temp_degC) {
+ if (limit_idx == limit_idx_low)
+ goto reschedule;
+
+ limit_idx -= msm_thermal_info.freq_step;
+ if (limit_idx < limit_idx_low)
+ limit_idx = limit_idx_low;
+ max_freq = table[limit_idx].frequency;
+ } else if (temp < msm_thermal_info.limit_temp_degC -
+ msm_thermal_info.temp_hysteresis_degC) {
+ if (limit_idx == limit_idx_high)
+ goto reschedule;
+
+ limit_idx += msm_thermal_info.freq_step;
+ if (limit_idx >= limit_idx_high) {
+ limit_idx = limit_idx_high;
+ max_freq = MSM_CPUFREQ_NO_LIMIT;
+ } else
+ max_freq = table[limit_idx].frequency;
+ }
if (max_freq == limited_max_freq)
goto reschedule;
diff --git a/drivers/usb/gadget/u_qc_ether.c b/drivers/usb/gadget/u_qc_ether.c
new file mode 100644
index 0000000..20933b6
--- /dev/null
+++ b/drivers/usb/gadget/u_qc_ether.c
@@ -0,0 +1,409 @@
+/*
+ * u_qc_ether.c -- Ethernet-over-USB link layer utilities for Gadget stack
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (c) 2012, Code Aurora Forum. 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
+#include "u_ether.h"
+
+
+/*
+ * This component encapsulates the Ethernet link glue needed to provide
+ * one (!) network link through the USB gadget stack, normally "usb0".
+ *
+ * The control and data models are handled by the function driver which
+ * connects to this code; such as CDC Ethernet (ECM or EEM),
+ * "CDC Subset", or RNDIS. That includes all descriptor and endpoint
+ * management.
+ *
+ * Link level addressing is handled by this component using module
+ * parameters; if no such parameters are provided, random link level
+ * addresses are used. Each end of the link uses one address. The
+ * host end address is exported in various ways, and is often recorded
+ * in configuration databases.
+ *
+ * The driver which assembles each configuration using such a link is
+ * responsible for ensuring that each configuration includes at most one
+ * instance of is network link. (The network layer provides ways for
+ * this single "physical" link to be used by multiple virtual links.)
+ *
+ * This utilities is based on Ethernet-over-USB link layer utilities and
+ * contains MSM specific implementation.
+ */
+
+#define UETH__VERSION "29-May-2008"
+
+struct eth_qc_dev {
+ /* lock is held while accessing port_usb
+ * or updating its backlink port_usb->ioport
+ */
+ spinlock_t lock;
+ struct qc_gether *port_usb;
+
+ struct net_device *net;
+ struct usb_gadget *gadget;
+
+ unsigned header_len;
+
+ bool zlp;
+ u8 host_mac[ETH_ALEN];
+};
+
+/*-------------------------------------------------------------------------*/
+
+#undef DBG
+#undef VDBG
+#undef ERROR
+#undef INFO
+
+#define xprintk(d, level, fmt, args...) \
+ printk(level "%s: " fmt , (d)->net->name , ## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DBG(dev, fmt, args...) \
+ xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev, fmt, args...) \
+ do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE_DEBUG
+#define VDBG DBG
+#else
+#define VDBG(dev, fmt, args...) \
+ do { } while (0)
+#endif /* DEBUG */
+
+#define ERROR(dev, fmt, args...) \
+ xprintk(dev , KERN_ERR , fmt , ## args)
+#define INFO(dev, fmt, args...) \
+ xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-------------------------------------------------------------------------*/
+
+/* NETWORK DRIVER HOOKUP (to the layer above this driver) */
+static int ueth_qc_change_mtu(struct net_device *net, int new_mtu)
+{
+ struct eth_qc_dev *dev = netdev_priv(net);
+ unsigned long flags;
+ int status = 0;
+
+ /* don't change MTU on "live" link (peer won't know) */
+ spin_lock_irqsave(&dev->lock, flags);
+ if (dev->port_usb)
+ status = -EBUSY;
+ else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
+ status = -ERANGE;
+ else
+ net->mtu = new_mtu;
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return status;
+}
+
+static void eth_qc_get_drvinfo(struct net_device *net,
+ struct ethtool_drvinfo *p)
+{
+ struct eth_qc_dev *dev = netdev_priv(net);
+
+ strlcpy(p->driver, "g_qc_ether", sizeof p->driver);
+ strlcpy(p->version, UETH__VERSION, sizeof p->version);
+ strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
+ strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
+}
+
+static const struct ethtool_ops qc_ethtool_ops = {
+ .get_drvinfo = eth_qc_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+static netdev_tx_t eth_qc_start_xmit(struct sk_buff *skb,
+ struct net_device *net)
+{
+ return NETDEV_TX_OK;
+}
+
+static int eth_qc_open(struct net_device *net)
+{
+ struct eth_qc_dev *dev = netdev_priv(net);
+ struct qc_gether *link;
+
+ DBG(dev, "%s\n", __func__);
+ if (netif_carrier_ok(dev->net)) {
+ /* Force the netif to send the RTM_NEWLINK event
+ * that in use to notify on the USB cable status.
+ */
+ netif_carrier_off(dev->net);
+ netif_carrier_on(dev->net);
+ netif_wake_queue(dev->net);
+ }
+
+ spin_lock_irq(&dev->lock);
+ link = dev->port_usb;
+ if (link && link->open)
+ link->open(link);
+ spin_unlock_irq(&dev->lock);
+
+ return 0;
+}
+
+static int eth_qc_stop(struct net_device *net)
+{
+ struct eth_qc_dev *dev = netdev_priv(net);
+ unsigned long flags;
+ struct qc_gether *link = dev->port_usb;
+
+ VDBG(dev, "%s\n", __func__);
+ netif_stop_queue(net);
+
+ spin_lock_irqsave(&dev->lock, flags);
+ if (dev->port_usb && link->close)
+ link->close(link);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
+static char *qc_dev_addr;
+module_param(qc_dev_addr, charp, S_IRUGO);
+MODULE_PARM_DESC(qc_dev_addr, "QC Device Ethernet Address");
+
+/* this address is invisible to ifconfig */
+static char *qc_host_addr;
+module_param(qc_host_addr, charp, S_IRUGO);
+MODULE_PARM_DESC(qc_host_addr, "QC Host Ethernet Address");
+
+static int get_qc_ether_addr(const char *str, u8 *dev_addr)
+{
+ if (str) {
+ unsigned i;
+
+ for (i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if ((*str == '.') || (*str == ':'))
+ str++;
+ num = hex_to_bin(*str++) << 4;
+ num |= hex_to_bin(*str++);
+ dev_addr[i] = num;
+ }
+ if (is_valid_ether_addr(dev_addr))
+ return 0;
+ }
+ random_ether_addr(dev_addr);
+ return 1;
+}
+
+static struct eth_qc_dev *qc_dev;
+
+static const struct net_device_ops eth_qc_netdev_ops = {
+ .ndo_open = eth_qc_open,
+ .ndo_stop = eth_qc_stop,
+ .ndo_start_xmit = eth_qc_start_xmit,
+ .ndo_change_mtu = ueth_qc_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static struct device_type qc_gadget_type = {
+ .name = "gadget",
+};
+
+/**
+ * gether_qc_setup - initialize one ethernet-over-usb link
+ * @g: gadget to associated with these links
+ * @ethaddr: NULL, or a buffer in which the ethernet address of the
+ * host side of the link is recorded
+ * Context: may sleep
+ *
+ * This sets up the single network link that may be exported by a
+ * gadget driver using this framework. The link layer addresses are
+ * set up using module parameters.
+ *
+ * Returns negative errno, or zero on success
+ */
+int gether_qc_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
+{
+ return gether_qc_setup_name(g, ethaddr, "usb");
+}
+
+/**
+ * gether_qc_setup_name - initialize one ethernet-over-usb link
+ * @g: gadget to associated with these links
+ * @ethaddr: NULL, or a buffer in which the ethernet address of the
+ * host side of the link is recorded
+ * @netname: name for network device (for example, "usb")
+ * Context: may sleep
+ *
+ * This sets up the single network link that may be exported by a
+ * gadget driver using this framework. The link layer addresses are
+ * set up using module parameters.
+ *
+ * Returns negative errno, or zero on success
+ */
+int gether_qc_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+ const char *netname)
+{
+ struct eth_qc_dev *dev;
+ struct net_device *net;
+ int status;
+
+ if (qc_dev)
+ return -EBUSY;
+
+ net = alloc_etherdev(sizeof *dev);
+ if (!net)
+ return -ENOMEM;
+
+ dev = netdev_priv(net);
+ spin_lock_init(&dev->lock);
+
+ /* network device setup */
+ dev->net = net;
+ snprintf(net->name, sizeof(net->name), "%s%%d", netname);
+
+ if (get_qc_ether_addr(qc_dev_addr, net->dev_addr))
+ dev_warn(&g->dev,
+ "using random %s ethernet address\n", "self");
+ if (get_qc_ether_addr(qc_host_addr, dev->host_mac))
+ dev_warn(&g->dev,
+ "using random %s ethernet address\n", "host");
+
+ if (ethaddr)
+ memcpy(ethaddr, dev->host_mac, ETH_ALEN);
+
+ net->netdev_ops = ð_qc_netdev_ops;
+
+ SET_ETHTOOL_OPS(net, &qc_ethtool_ops);
+
+ netif_carrier_off(net);
+
+ dev->gadget = g;
+ SET_NETDEV_DEV(net, &g->dev);
+ SET_NETDEV_DEVTYPE(net, &qc_gadget_type);
+
+ status = register_netdev(net);
+ if (status < 0) {
+ dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
+ free_netdev(net);
+ } else {
+ INFO(dev, "MAC %pM\n", net->dev_addr);
+ INFO(dev, "HOST MAC %pM\n", dev->host_mac);
+
+ qc_dev = dev;
+ }
+
+ return status;
+}
+
+/**
+ * gether_qc_cleanup - remove Ethernet-over-USB device
+ * Context: may sleep
+ *
+ * This is called to free all resources allocated by @gether_qc_setup().
+ */
+void gether_qc_cleanup(void)
+{
+ if (!qc_dev)
+ return;
+
+ unregister_netdev(qc_dev->net);
+ free_netdev(qc_dev->net);
+
+ qc_dev = NULL;
+}
+
+
+/**
+ * gether_qc_connect - notify network layer that USB link is active
+ * @link: the USB link, set up with endpoints, descriptors matching
+ * current device speed, and any framing wrapper(s) set up.
+ * Context: irqs blocked
+ *
+ * This is called to let the network layer know the connection
+ * is active ("carrier detect").
+ */
+struct net_device *gether_qc_connect(struct qc_gether *link)
+{
+ struct eth_qc_dev *dev = qc_dev;
+
+ if (!dev)
+ return ERR_PTR(-EINVAL);
+
+ dev->zlp = link->is_zlp_ok;
+ dev->header_len = link->header_len;
+
+ spin_lock(&dev->lock);
+ dev->port_usb = link;
+ link->ioport = dev;
+ if (netif_running(dev->net)) {
+ if (link->open)
+ link->open(link);
+ } else {
+ if (link->close)
+ link->close(link);
+ }
+ spin_unlock(&dev->lock);
+
+ netif_carrier_on(dev->net);
+ if (netif_running(dev->net))
+ netif_wake_queue(dev->net);
+
+ return dev->net;
+}
+
+/**
+ * gether_qc_disconnect - notify network layer that USB link is inactive
+ * @link: the USB link, on which gether_connect() was called
+ * Context: irqs blocked
+ *
+ * This is called to let the network layer know the connection
+ * went inactive ("no carrier").
+ *
+ * On return, the state is as if gether_connect() had never been called.
+ */
+void gether_qc_disconnect(struct qc_gether *link)
+{
+ struct eth_qc_dev *dev = link->ioport;
+
+ if (!dev)
+ return;
+
+ DBG(dev, "%s\n", __func__);
+
+ netif_stop_queue(dev->net);
+ netif_carrier_off(dev->net);
+
+ spin_lock(&dev->lock);
+ dev->port_usb = NULL;
+ link->ioport = NULL;
+ spin_unlock(&dev->lock);
+}
diff --git a/drivers/usb/gadget/u_qc_ether.h b/drivers/usb/gadget/u_qc_ether.h
new file mode 100644
index 0000000..b3c281b
--- /dev/null
+++ b/drivers/usb/gadget/u_qc_ether.h
@@ -0,0 +1,97 @@
+/*
+ * u_qc_ether.h -- interface to USB gadget "ethernet link" utilities
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (c) 2012, Code Aurora Forum. 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __U_QC_ETHER_H
+#define __U_QC_ETHER_H
+
+#include <linux/err.h>
+#include <linux/if_ether.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/cdc.h>
+
+#include "gadget_chips.h"
+
+
+/*
+ * This represents the USB side of an "ethernet" link, managed by a USB
+ * function which provides control and (maybe) framing. Two functions
+ * in different configurations could share the same ethernet link/netdev,
+ * using different host interaction models.
+ *
+ * There is a current limitation that only one instance of this link may
+ * be present in any given configuration. When that's a problem, network
+ * layer facilities can be used to package multiple logical links on this
+ * single "physical" one.
+ *
+ * This function is based on Ethernet-over-USB link layer utilities and
+ * contains MSM specific implementation.
+ */
+
+struct qc_gether {
+ struct usb_function func;
+
+ /* updated by gether_{connect,disconnect} */
+ struct eth_qc_dev *ioport;
+
+ /* endpoints handle full and/or high speeds */
+ struct usb_ep *in_ep;
+ struct usb_ep *out_ep;
+
+ bool is_zlp_ok;
+
+ u16 cdc_filter;
+
+ /* hooks for added framing, as needed for RNDIS and EEM. */
+ u32 header_len;
+ /* NCM requires fixed size bundles */
+ bool is_fixed;
+ u32 fixed_out_len;
+ u32 fixed_in_len;
+ struct sk_buff *(*wrap)(struct qc_gether *port,
+ struct sk_buff *skb);
+ int (*unwrap)(struct qc_gether *port,
+ struct sk_buff *skb,
+ struct sk_buff_head *list);
+
+ /* called on network open/close */
+ void (*open)(struct qc_gether *);
+ void (*close)(struct qc_gether *);
+};
+
+/* netdev setup/teardown as directed by the gadget driver */
+int gether_qc_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]);
+void gether_qc_cleanup(void);
+/* variant of gether_setup that allows customizing network device name */
+int gether_qc_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+ const char *netname);
+
+/* connect/disconnect is handled by individual functions */
+struct net_device *gether_qc_connect(struct qc_gether *);
+void gether_qc_disconnect(struct qc_gether *);
+
+/* each configuration may bind one instance of an ethernet link */
+int ecm_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+
+int
+rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+ u32 vendorID, const char *manufacturer,
+ u8 maxPktPerXfer);
+#endif /* __U_QC_ETHER_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 43ddb5e..2e9a2dc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -115,11 +115,10 @@
if (fmt->is_yuv) {
if ((req->src_rect.x & 0x1) || (req->src_rect.y & 0x1) ||
(req->src_rect.w & 0x1) || (req->src_rect.h & 0x1)) {
- pr_err("invalid odd src resolution\n");
+ pr_err("invalid odd src resolution or coordinates\n");
return -EINVAL;
}
- if ((req->dst_rect.x & 0x1) || (req->dst_rect.y & 0x1) ||
- (req->dst_rect.w & 0x1) || (req->dst_rect.h & 0x1)) {
+ if ((req->dst_rect.w & 0x1) || (req->dst_rect.h & 0x1)) {
pr_err("invalid odd dst resolution\n");
return -EINVAL;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 52f4324..d9a148e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -354,11 +354,12 @@
u32 chroma_sample;
if (pipe->type == MDSS_MDP_PIPE_TYPE_DMA) {
- if (!(pipe->flags & MDP_ROT_90) && (pipe->dst.h != pipe->src.h
- || pipe->dst.w != pipe->src.w))
- return -EINVAL; /* no scaling supported on dma pipes */
- else
+ if (pipe->dst.h != pipe->src.h || pipe->dst.w != pipe->src.w) {
+ pr_err("no scaling supported on dma pipe\n");
+ return -EINVAL;
+ } else {
return 0;
+ }
}
chroma_sample = pipe->src_fmt->chroma_sample;
@@ -535,10 +536,10 @@
pr_debug("pnum=%d format=%d opmode=%x\n", pipe->num, fmt->format,
opmode);
- rot90 = !!(pipe->flags & MDP_SOURCE_ROTATED_90);
+ rot90 = !!(pipe->flags & MDP_ROT_90);
chroma_samp = fmt->chroma_sample;
- if (rot90) {
+ if (pipe->flags & MDP_SOURCE_ROTATED_90) {
if (chroma_samp == MDSS_MDP_CHROMA_H2V1)
chroma_samp = MDSS_MDP_CHROMA_H1V2;
else if (chroma_samp == MDSS_MDP_CHROMA_H1V2)
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index fc3a843..dc1cb0d 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -212,6 +212,7 @@
rot_pipe->img_width = rot->img_width;
rot_pipe->img_height = rot->img_height;
rot_pipe->src = rot->src_rect;
+ rot_pipe->dst = rot->src_rect;
rot_pipe->bwc_mode = rot->bwc_mode;
rot_pipe->params_changed++;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_wb.c b/drivers/video/msm/mdss/mdss_mdp_wb.c
index da55edc..046f666 100644
--- a/drivers/video/msm/mdss/mdss_mdp_wb.c
+++ b/drivers/video/msm/mdss/mdss_mdp_wb.c
@@ -60,32 +60,40 @@
static struct mdss_mdp_wb mdss_mdp_wb_info;
#ifdef DEBUG_WRITEBACK
-/* for debugging: writeback output buffer to framebuffer memory */
+/* for debugging: writeback output buffer to allocated memory */
static inline
struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd)
{
+ static struct ion_handle *ihdl;
static void *videomemory;
- static void *mdss_wb_mem;
- static struct mdss_mdp_data buffer = {
- .num_planes = 1,
- };
-
+ static ion_phys_addr_t mdss_wb_mem;
+ static struct mdss_mdp_data buffer = { .num_planes = 1, };
struct fb_info *fbi;
- int img_size;
- int offset;
-
+ size_t img_size;
fbi = mfd->fbi;
img_size = fbi->var.xres * fbi->var.yres * fbi->var.bits_per_pixel / 8;
- offset = fbi->fix.smem_len - img_size;
- videomemory = fbi->screen_base + offset;
- mdss_wb_mem = (void *)(fbi->fix.smem_start + offset);
+ if (ihdl == NULL) {
+ ihdl = ion_alloc(mfd->iclient, img_size, SZ_4K,
+ ION_HEAP(ION_SF_HEAP_ID));
+ if (!IS_ERR_OR_NULL(ihdl)) {
+ videomemory = ion_map_kernel(mfd->iclient, ihdl, 0);
+ ion_phys(mfd->iclient, ihdl, &mdss_wb_mem, &img_size);
+ } else {
+ pr_err("unable to alloc fbmem from ion (%p)\n", ihdl);
+ ihdl = NULL;
+ }
+ }
- buffer.p[0].addr = fbi->fix.smem_start + offset;
- buffer.p[0].len = img_size;
+ if (mdss_wb_mem) {
+ buffer.p[0].addr = (u32) mdss_wb_mem;
+ buffer.p[0].len = img_size;
- return &buffer;
+ return &buffer;
+ }
+
+ return NULL;
}
#else
static inline
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index fe9be89..47a8753 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -17,9 +17,9 @@
struct msm_thermal_data {
uint32_t sensor_id;
uint32_t poll_ms;
- uint32_t limit_temp;
- uint32_t temp_hysteresis;
- uint32_t limit_freq;
+ uint32_t limit_temp_degC;
+ uint32_t temp_hysteresis_degC;
+ uint32_t freq_step;
};
#ifdef CONFIG_THERMAL_MONITOR
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c34cbbd..831509c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5649,7 +5649,12 @@
__alloc_contig_migrate_alloc(struct page *page, unsigned long private,
int **resultp)
{
- return alloc_page(GFP_HIGHUSER_MOVABLE);
+ gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE;
+
+ if (PageHighMem(page))
+ gfp_mask |= __GFP_HIGHMEM;
+
+ return alloc_page(gfp_mask);
}
/* [start, end) must belong to a single zone. */
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 67a5d8a..6da9166 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -1890,6 +1890,12 @@
return 0;
}
+static int taiko_codec_enable_spk_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("%s %d %s\n", __func__, event, w->name);
+ return 0;
+}
static int taiko_codec_enable_dmic(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
@@ -2891,6 +2897,13 @@
return 0;
}
+static int taiko_spk_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("%s %s %d\n", __func__, w->name, event);
+ return 0;
+}
+
static const struct snd_soc_dapm_route audio_i2s_map[] = {
{"RX_I2S_CLK", NULL, "CDC_CONN"},
{"SLIM RX1", NULL, "RX_I2S_CLK"},
@@ -3038,6 +3051,7 @@
{"LINEOUT2", NULL, "LINEOUT2 PA"},
{"LINEOUT3", NULL, "LINEOUT3 PA"},
{"LINEOUT4", NULL, "LINEOUT4 PA"},
+ {"SPK_OUT", NULL, "SPK PA"},
{"LINEOUT1 PA", NULL, "LINEOUT1_PA_MIXER"},
{"LINEOUT1_PA_MIXER", NULL, "LINEOUT1 DAC"},
@@ -3060,6 +3074,9 @@
{"RX6 DSM MUX", "CIC_OUT", "RX6 MIX1"},
{"LINEOUT4 DAC", NULL, "RX6 DSM MUX"},
+ {"SPK PA", NULL, "SPK DAC"},
+ {"SPK DAC", NULL, "RX7 MIX1"},
+
{"RX1 CHAIN", NULL, "RX1 MIX2"},
{"RX2 CHAIN", NULL, "RX2 MIX2"},
{"RX1 CHAIN", NULL, "ANC"},
@@ -3070,6 +3087,7 @@
{"LINEOUT2 DAC", NULL, "RX_BIAS"},
{"LINEOUT3 DAC", NULL, "RX_BIAS"},
{"LINEOUT4 DAC", NULL, "RX_BIAS"},
+ {"SPK DAC", NULL, "RX_BIAS"},
{"RX1 MIX1", NULL, "COMP1_CLK"},
{"RX2 MIX1", NULL, "COMP1_CLK"},
@@ -4192,6 +4210,7 @@
SND_SOC_DAPM_OUTPUT("LINEOUT2"),
SND_SOC_DAPM_OUTPUT("LINEOUT3"),
SND_SOC_DAPM_OUTPUT("LINEOUT4"),
+ SND_SOC_DAPM_OUTPUT("SPK_OUT"),
SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TAIKO_A_RX_LINE_CNP_EN, 0, 0, NULL,
0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
@@ -4205,6 +4224,9 @@
SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TAIKO_A_RX_LINE_CNP_EN, 3, 0, NULL,
0, taiko_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("SPK PA", TAIKO_A_SPKR_DRV_EN, 7, 0 , NULL,
+ 0, taiko_codec_enable_spk_pa, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TAIKO_A_RX_LINE_1_DAC_CTL, 7, 0
, taiko_lineout_dac_event,
@@ -4223,6 +4245,10 @@
SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
&lineout4_ground_switch),
+ SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
+ taiko_spk_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
0, taiko_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMU),
@@ -6709,11 +6735,16 @@
struct taiko_priv *taiko;
int rc = 0;
- if (!codec || !cfg->calibration) {
- pr_err("Error: no codec or calibration\n");
+ if (!codec) {
+ pr_err("%s: no codec\n", __func__);
return -EINVAL;
}
+ if (!cfg->calibration) {
+ pr_warn("%s: mbhc is not configured\n", __func__);
+ return 0;
+ }
+
if (cfg->mclk_rate != TAIKO_MCLK_RATE_12288KHZ) {
if (cfg->mclk_rate == TAIKO_MCLK_RATE_9600KHZ)
pr_err("Error: clock rate %dHz is not yet supported\n",
@@ -7158,6 +7189,102 @@
};
#endif
+static int taiko_setup_irqs(struct taiko_priv *taiko)
+{
+ int ret;
+ int i;
+ struct snd_soc_codec *codec = taiko->codec;
+
+ ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION,
+ taiko_hs_insert_irq, "Headset insert detect",
+ taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_MBHC_INSERTION);
+ goto err_insert_irq;
+ }
+ wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION);
+
+ ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_REMOVAL,
+ taiko_hs_remove_irq, "Headset remove detect",
+ taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_MBHC_REMOVAL);
+ goto err_remove_irq;
+ }
+
+ ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_POTENTIAL,
+ taiko_dce_handler, "DC Estimation detect",
+ taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_MBHC_POTENTIAL);
+ goto err_potential_irq;
+ }
+
+ ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_RELEASE,
+ taiko_release_handler, "Button Release detect",
+ taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_MBHC_RELEASE);
+ goto err_release_irq;
+ }
+
+ ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_SLIMBUS,
+ taiko_slimbus_irq, "SLIMBUS Slave", taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_SLIMBUS);
+ goto err_slimbus_irq;
+ }
+
+ for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
+ wcd9xxx_interface_reg_write(codec->control_data,
+ TAIKO_SLIM_PGD_PORT_INT_EN0 + i,
+ 0xFF);
+
+ ret = wcd9xxx_request_irq(codec->control_data,
+ TAIKO_IRQ_HPH_PA_OCPL_FAULT,
+ taiko_hphl_ocp_irq,
+ "HPH_L OCP detect", taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_HPH_PA_OCPL_FAULT);
+ goto err_hphl_ocp_irq;
+ }
+ wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_HPH_PA_OCPL_FAULT);
+
+ ret = wcd9xxx_request_irq(codec->control_data,
+ TAIKO_IRQ_HPH_PA_OCPR_FAULT,
+ taiko_hphr_ocp_irq,
+ "HPH_R OCP detect", taiko);
+ if (ret) {
+ pr_err("%s: Failed to request irq %d\n", __func__,
+ TAIKO_IRQ_HPH_PA_OCPR_FAULT);
+ goto err_hphr_ocp_irq;
+ }
+ wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_HPH_PA_OCPR_FAULT);
+
+err_hphr_ocp_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_HPH_PA_OCPL_FAULT,
+ taiko);
+err_hphl_ocp_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_SLIMBUS, taiko);
+err_slimbus_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_RELEASE, taiko);
+err_release_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_POTENTIAL, taiko);
+err_potential_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_REMOVAL, taiko);
+err_remove_irq:
+ wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION, taiko);
+err_insert_irq:
+
+ return ret;
+}
+
static int taiko_codec_probe(struct snd_soc_codec *codec)
{
struct wcd9xxx *control;
@@ -7167,6 +7294,7 @@
int i;
int ch_cnt;
+
codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
@@ -7234,70 +7362,8 @@
snd_soc_dapm_sync(dapm);
- ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION,
- taiko_hs_insert_irq, "Headset insert detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_MBHC_INSERTION);
- goto err_insert_irq;
- }
- wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION);
+ (void) taiko_setup_irqs(taiko);
- ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_REMOVAL,
- taiko_hs_remove_irq, "Headset remove detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_MBHC_REMOVAL);
- goto err_remove_irq;
- }
-
- ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_POTENTIAL,
- taiko_dce_handler, "DC Estimation detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_MBHC_POTENTIAL);
- goto err_potential_irq;
- }
-
- ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_MBHC_RELEASE,
- taiko_release_handler, "Button Release detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_MBHC_RELEASE);
- goto err_release_irq;
- }
-
- ret = wcd9xxx_request_irq(codec->control_data, TAIKO_IRQ_SLIMBUS,
- taiko_slimbus_irq, "SLIMBUS Slave", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_SLIMBUS);
- goto err_slimbus_irq;
- }
-
- for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
- wcd9xxx_interface_reg_write(codec->control_data,
- TAIKO_SLIM_PGD_PORT_INT_EN0 + i, 0xFF);
-
- ret = wcd9xxx_request_irq(codec->control_data,
- TAIKO_IRQ_HPH_PA_OCPL_FAULT, taiko_hphl_ocp_irq,
- "HPH_L OCP detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_HPH_PA_OCPL_FAULT);
- goto err_hphl_ocp_irq;
- }
- wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_HPH_PA_OCPL_FAULT);
-
- ret = wcd9xxx_request_irq(codec->control_data,
- TAIKO_IRQ_HPH_PA_OCPR_FAULT, taiko_hphr_ocp_irq,
- "HPH_R OCP detect", taiko);
- if (ret) {
- pr_err("%s: Failed to request irq %d\n", __func__,
- TAIKO_IRQ_HPH_PA_OCPR_FAULT);
- goto err_hphr_ocp_irq;
- }
- wcd9xxx_disable_irq(codec->control_data, TAIKO_IRQ_HPH_PA_OCPR_FAULT);
for (i = 0; i < ARRAY_SIZE(taiko_dai); i++) {
switch (taiko_dai[i].id) {
case AIF1_PB:
@@ -7338,20 +7404,6 @@
codec->ignore_pmdown_time = 1;
return ret;
-err_hphr_ocp_irq:
- wcd9xxx_free_irq(codec->control_data,
- TAIKO_IRQ_HPH_PA_OCPL_FAULT, taiko);
-err_hphl_ocp_irq:
- wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_SLIMBUS, taiko);
-err_slimbus_irq:
- wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_RELEASE, taiko);
-err_release_irq:
- wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_POTENTIAL, taiko);
-err_potential_irq:
- wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_REMOVAL, taiko);
-err_remove_irq:
- wcd9xxx_free_irq(codec->control_data, TAIKO_IRQ_MBHC_INSERTION, taiko);
-err_insert_irq:
err_pdata:
mutex_destroy(&taiko->codec_resource_lock);
kfree(taiko);
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index e56b1da..894e114 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -153,6 +153,16 @@
help
To add support for SoC audio on MSM8960 and APQ8064 boards
+config AUDIO_OCMEM
+ bool "Enable OCMEM for audio/voice usecase"
+ depends on MSM_OCMEM
+ default n
+ help
+ To add support for on-chip memory use
+ for audio use cases on MSM8974.
+ OCMEM gets exercised for low-power
+ audio and voice use cases.
+
config SND_SOC_MSM8974
tristate "SoC Machine driver for MSM8974 boards"
depends on ARCH_MSM8974
@@ -161,6 +171,7 @@
select SND_SOC_MSM_HOSTLESS_PCM
select SND_SOC_WCD9320
select SND_DYNAMIC_MINORS
+ select AUDIO_OCMEM
help
To add support for SoC audio on MSM8974.
This will enable sound soc drivers which
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 9c57161..3516022 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -26,7 +26,7 @@
#include <asm/mach-types.h>
#include <mach/socinfo.h>
#include <qdsp6v2/msm-pcm-routing-v2.h>
-#include "../codecs/wcd9310.h"
+#include "../codecs/wcd9320.h"
/* 8974 machine driver */
@@ -81,21 +81,7 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
-static int msm_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
- bool dapm);
-
-static struct tabla_mbhc_config mbhc_cfg = {
- .headset_jack = &hs_jack,
- .button_jack = &button_jack,
- .read_fw_bin = false,
- .calibration = NULL,
- .micbias = TABLA_MICBIAS2,
- .mclk_cb_fn = msm_enable_codec_ext_clk,
- .mclk_rate = TABLA_EXT_CLK_RATE,
- .gpio = 0, /* MBHC GPIO is not configured */
- .gpio_irq = 0,
- .gpio_level_insert = 1,
-};
+static struct mutex cdc_mclk_mutex;
static void msm_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
@@ -244,6 +230,8 @@
{
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ mutex_lock(&dapm->codec->mutex);
+
pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
if (msm_spk_control == MSM8974_SPK_ON) {
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
@@ -258,17 +246,19 @@
}
snd_soc_dapm_sync(dapm);
+ mutex_unlock(&dapm->codec->mutex);
}
static int msm_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
ucontrol->value.integer.value[0] = msm_spk_control;
return 0;
}
+
static int msm_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -280,8 +270,9 @@
msm_ext_control(codec);
return 1;
}
+
static int msm_spkramp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
+ struct snd_kcontrol *k, int event)
{
pr_debug("%s() %x\n", __func__, SND_SOC_DAPM_EVENT_ON(event));
@@ -318,12 +309,6 @@
return 0;
}
-static int msm_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
- bool dapm)
-{
- return 0;
-}
-
static int msm_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -453,14 +438,14 @@
static const char *const btsco_rate_text[] = {"8000", "16000"};
static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+ SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
};
static int msm_slim_0_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
- msm_slim_0_rx_ch);
+ msm_slim_0_rx_ch);
ucontrol->value.integer.value[0] = msm_slim_0_rx_ch - 1;
return 0;
}
@@ -471,7 +456,7 @@
msm_slim_0_rx_ch = ucontrol->value.integer.value[0] + 1;
pr_debug("%s: msm_slim_0_rx_ch = %d\n", __func__,
- msm_slim_0_rx_ch);
+ msm_slim_0_rx_ch);
return 1;
}
@@ -479,7 +464,7 @@
struct snd_ctl_elem_value *ucontrol)
{
pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__,
- msm_slim_0_tx_ch);
+ msm_slim_0_tx_ch);
ucontrol->value.integer.value[0] = msm_slim_0_tx_ch - 1;
return 0;
}
@@ -489,16 +474,14 @@
{
msm_slim_0_tx_ch = ucontrol->value.integer.value[0] + 1;
- pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__,
- msm_slim_0_tx_ch);
+ pr_debug("%s: msm_slim_0_tx_ch = %d\n", __func__, msm_slim_0_tx_ch);
return 1;
}
static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- pr_debug("%s: msm_btsco_rate = %d", __func__,
- msm_btsco_rate);
+ pr_debug("%s: msm_btsco_rate = %d", __func__, msm_btsco_rate);
ucontrol->value.integer.value[0] = msm_btsco_rate;
return 0;
}
@@ -517,33 +500,23 @@
msm_btsco_rate = BTSCO_RATE_8KHZ;
break;
}
- pr_debug("%s: msm_btsco_rate = %d\n", __func__,
- msm_btsco_rate);
+ pr_debug("%s: msm_btsco_rate = %d\n", __func__, msm_btsco_rate);
return 0;
}
-static const struct snd_kcontrol_new tabla_msm_controls[] = {
- SOC_ENUM_EXT("Speaker Function", msm_enum[0], msm_get_spk,
- msm_set_spk),
- SOC_ENUM_EXT("SLIM_0_RX Channels", msm_enum[1],
- msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
- SOC_ENUM_EXT("SLIM_0_TX Channels", msm_enum[2],
- msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
-};
-
static const struct snd_kcontrol_new int_btsco_rate_mixer_controls[] = {
SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
- msm_btsco_rate_get, msm_btsco_rate_put),
+ msm_btsco_rate_get, msm_btsco_rate_put),
};
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
- struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *rate =
+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
+ struct snd_interval *channels =
+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
/* PCM only supports mono output with 8khz sample rate */
rate->min = rate->max = 8000;
@@ -629,6 +602,193 @@
.startup = msm_auxpcm_startup,
.shutdown = msm_auxpcm_shutdown,
};
+
+static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels =
+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s()\n", __func__);
+ rate->min = rate->max = 48000;
+ channels->min = channels->max = msm_slim_0_rx_ch;
+
+ return 0;
+}
+
+static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s()\n", __func__);
+ rate->min = rate->max = 48000;
+ channels->min = channels->max = msm_slim_0_tx_ch;
+
+ return 0;
+}
+
+static const struct soc_enum msm_snd_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, spk_function),
+ SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
+ SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+};
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("Speaker Function", msm_snd_enum[0], msm_get_spk,
+ msm_set_spk),
+ SOC_ENUM_EXT("SLIM_0_RX Channels", msm_snd_enum[1],
+ msm_slim_0_rx_ch_get, msm_slim_0_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_0_TX Channels", msm_snd_enum[2],
+ msm_slim_0_tx_ch_get, msm_slim_0_tx_ch_put),
+};
+
+static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int err;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+ pr_info("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+
+ if (machine_is_msm8960_liquid()) {
+ top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
+ bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18));
+ }
+
+ rtd->pmdown_time = 0;
+
+ err = snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+ if (err < 0)
+ return err;
+
+ snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
+ ARRAY_SIZE(msm_dapm_widgets));
+
+ snd_soc_dapm_add_routes(dapm, common_audio_map,
+ ARRAY_SIZE(common_audio_map));
+
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
+ snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
+
+ snd_soc_dapm_sync(dapm);
+
+ err = snd_soc_jack_new(codec, "Headset Jack",
+ (SND_JACK_HEADSET | SND_JACK_OC_HPHL |
+ SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED),
+ &hs_jack);
+ if (err) {
+ pr_err("failed to create new jack\n");
+ return err;
+ }
+
+ err = snd_soc_jack_new(codec, "Button Jack",
+ TAIKO_JACK_BUTTON_MASK, &button_jack);
+ if (err) {
+ pr_err("failed to create new jack\n");
+ return err;
+ }
+
+ return err;
+}
+
+static int msm_snd_startup(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ return 0;
+}
+
+static int msm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+ unsigned int user_set_tx_ch = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("%s: rx_0_ch=%d\n", __func__, msm_slim_0_rx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ msm_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+ msm_slim_0_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ } else {
+
+ if (codec_dai->id == 2)
+ user_set_tx_ch = msm_slim_0_tx_ch;
+ else if (codec_dai->id == 4)
+ user_set_tx_ch = params_channels(params);
+
+ pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
+ codec_dai->name, codec_dai->id, user_set_tx_ch);
+
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ user_set_tx_ch, tx_ch, 0 , 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map\n", __func__);
+ goto end;
+ }
+ ret = snd_soc_dai_set_channel_map(codec_dai,
+ user_set_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set codec channel map\n",
+ __func__);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static void msm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+}
+
+static struct snd_soc_ops msm8974_be_ops = {
+ .startup = msm_snd_startup,
+ .hw_params = msm_snd_hw_params,
+ .shutdown = msm_snd_shutdown,
+};
+
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_dai[] = {
/* FrontEnd DAI Links */
@@ -734,7 +894,33 @@
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
},
-
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "taiko_codec",
+ .codec_dai_name = "taiko_rx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+ .ops = &msm8974_be_ops,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "taiko_codec",
+ .codec_dai_name = "taiko_tx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+ .ops = &msm8974_be_ops,
+ },
};
struct snd_soc_card snd_soc_card_msm = {
@@ -756,6 +942,8 @@
static int __init msm_audio_init(void)
{
int ret = 0;
+
+ mutex_init(&cdc_mclk_mutex);
if (!machine_is_msm8974_sim()) {
pr_err("%s: Not the right machine type\n", __func__);
return -ENODEV;
@@ -763,7 +951,6 @@
msm_snd_device = platform_device_alloc("soc-audio", 0);
if (!msm_snd_device) {
pr_err("Platform device allocation failed\n");
- kfree(mbhc_cfg.calibration);
return -ENOMEM;
}
@@ -771,7 +958,6 @@
ret = platform_device_add(msm_snd_device);
if (ret) {
platform_device_put(msm_snd_device);
- kfree(mbhc_cfg.calibration);
return ret;
}
return ret;
@@ -787,7 +973,6 @@
}
msm_free_headset_mic_gpios();
platform_device_unregister(msm_snd_device);
- kfree(mbhc_cfg.calibration);
}
module_exit(msm_audio_exit);
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index ff2cc8d..acb073d 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -1,4 +1,6 @@
snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o msm-compr-q6-v2.o msm-multi-ch-pcm-q6-v2.o
snd-soc-qdsp6v2-objs += msm-pcm-lpa-v2.o msm-pcm-afe-v2.o msm-pcm-voip-v2.o msm-pcm-voice-v2.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o
-obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o
+obj-y += q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o
+ocmem-audio-objs += audio_ocmem.o
+obj-$(CONFIG_AUDIO_OCMEM) += ocmem-audio.o
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
new file mode 100644
index 0000000..86a82e2
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -0,0 +1,672 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <asm/mach-types.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/ocmem.h>
+#include "q6core.h"
+#include "audio_ocmem.h"
+
+#define AUDIO_OCMEM_BUF_SIZE (512 * SZ_1K)
+
+enum {
+ OCMEM_STATE_ALLOC = 1,
+ OCMEM_STATE_MAP_TRANSITION,
+ OCMEM_STATE_MAP_COMPL,
+ OCMEM_STATE_UNMAP_TRANSITION,
+ OCMEM_STATE_UNMAP_COMPL,
+ OCMEM_STATE_SHRINK,
+ OCMEM_STATE_GROW,
+ OCMEM_STATE_FREE,
+ OCMEM_STATE_MAP_FAIL,
+ OCMEM_STATE_UNMAP_FAIL,
+ OCMEM_STATE_EXIT,
+};
+static void audio_ocmem_process_workdata(struct work_struct *work);
+
+struct audio_ocmem_workdata {
+ int id;
+ bool en;
+ struct work_struct work;
+};
+
+struct voice_ocmem_workdata {
+ int id;
+ bool en;
+ struct work_struct work;
+};
+
+struct audio_ocmem_prv {
+ atomic_t audio_state;
+ struct ocmem_notifier *audio_hdl;
+ struct ocmem_buf *buf;
+ uint32_t audio_ocmem_bus_client;
+ struct ocmem_map_list mlist;
+ struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_memseg_ptr;
+ wait_queue_head_t audio_wait;
+ atomic_t audio_cond;
+ atomic_t audio_exit;
+ spinlock_t audio_lock;
+ struct workqueue_struct *audio_ocmem_workqueue;
+ struct workqueue_struct *voice_ocmem_workqueue;
+};
+
+static struct audio_ocmem_prv audio_ocmem_lcl;
+
+
+static int audio_ocmem_client_cb(struct notifier_block *this,
+ unsigned long event1, void *data)
+{
+ int rc = NOTIFY_DONE;
+ unsigned long flags;
+
+ pr_debug("%s: event[%ld] cur state[%x]\n", __func__,
+ event1, atomic_read(&audio_ocmem_lcl.audio_state));
+
+ spin_lock_irqsave(&audio_ocmem_lcl.audio_lock, flags);
+ switch (event1) {
+ case OCMEM_MAP_DONE:
+ pr_debug("%s: map done\n", __func__);
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_COMPL);
+ break;
+ case OCMEM_MAP_FAIL:
+ pr_debug("%s: map fail\n", __func__);
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_FAIL);
+ break;
+ case OCMEM_UNMAP_DONE:
+ pr_debug("%s: unmap done\n", __func__);
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_COMPL);
+ break;
+ case OCMEM_UNMAP_FAIL:
+ pr_debug("%s: unmap fail\n", __func__);
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_FAIL);
+ break;
+ case OCMEM_ALLOC_GROW:
+ audio_ocmem_lcl.buf = data;
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_GROW);
+ break;
+ case OCMEM_ALLOC_SHRINK:
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_SHRINK);
+ break;
+ default:
+ pr_err("%s: Invalid event[%ld]\n", __func__, event1);
+ break;
+ }
+ spin_unlock_irqrestore(&audio_ocmem_lcl.audio_lock, flags);
+ if (atomic_read(&audio_ocmem_lcl.audio_cond)) {
+ atomic_set(&audio_ocmem_lcl.audio_cond, 0);
+ wake_up(&audio_ocmem_lcl.audio_wait);
+ }
+ return rc;
+}
+
+/**
+ * audio_ocmem_enable() - Exercise OCMEM for audio
+ * @cid: client id - OCMEM_LP_AUDIO
+ *
+ * OCMEM gets allocated for audio usecase and the low power
+ * segments obtained from the DSP will be moved from/to main
+ * memory to OCMEM. Shrink and grow requests will be received
+ * and processed accordingly based on the current audio state.
+ */
+int audio_ocmem_enable(int cid)
+{
+ int ret;
+ int i, j;
+ struct ocmem_buf *buf = NULL;
+ struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_segptr;
+
+ pr_debug("%s\n", __func__);
+ /* Non-blocking ocmem allocate (asynchronous) */
+ buf = ocmem_allocate_nb(cid, AUDIO_OCMEM_BUF_SIZE);
+ if (IS_ERR_OR_NULL(buf)) {
+ pr_err("%s: failed: %d\n", __func__, cid);
+ return -ENOMEM;
+ }
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_ALLOC);
+
+ audio_ocmem_lcl.buf = buf;
+ atomic_set(&audio_ocmem_lcl.audio_exit, 0);
+ if (!buf->len) {
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ (atomic_read(&audio_ocmem_lcl.audio_cond) == 0) ||
+ (atomic_read(&audio_ocmem_lcl.audio_exit) == 1));
+
+ if (atomic_read(&audio_ocmem_lcl.audio_exit)) {
+ pr_err("%s: audio playback ended while waiting for ocmem\n",
+ __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ }
+ if (audio_ocmem_lcl.lp_memseg_ptr == NULL) {
+ /* Retrieve low power segments */
+ ret = core_get_low_power_segments(
+ &audio_ocmem_lcl.lp_memseg_ptr);
+ if (ret != 0) {
+ pr_err("%s: get low power segments from DSP failed, rc=%d\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
+ }
+ lp_segptr = audio_ocmem_lcl.lp_memseg_ptr;
+ audio_ocmem_lcl.mlist.num_chunks = lp_segptr->num_segments;
+ for (i = 0, j = 0; j < audio_ocmem_lcl.mlist.num_chunks; j++, i++) {
+ audio_ocmem_lcl.mlist.chunks[j].ro =
+ (lp_segptr->mem_segment[i].type == READ_ONLY_SEGMENT);
+ audio_ocmem_lcl.mlist.chunks[j].ddr_paddr =
+ lp_segptr->mem_segment[i].start_address_lsw;
+ audio_ocmem_lcl.mlist.chunks[j].size =
+ lp_segptr->mem_segment[i].size;
+ pr_debug("%s: ro:%d, ddr_paddr[%x], size[%x]\n", __func__,
+ audio_ocmem_lcl.mlist.chunks[j].ro,
+ (uint32_t)audio_ocmem_lcl.mlist.chunks[j].ddr_paddr,
+ (uint32_t)audio_ocmem_lcl.mlist.chunks[j].size);
+ }
+
+ /* vote for ocmem bus bandwidth */
+ ret = msm_bus_scale_client_update_request(
+ audio_ocmem_lcl.audio_ocmem_bus_client,
+ 0);
+ if (ret)
+ pr_err("%s: failed to vote for bus bandwidth\n", __func__);
+
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_MAP_TRANSITION);
+
+ ret = ocmem_map(cid, audio_ocmem_lcl.buf, &audio_ocmem_lcl.mlist);
+ if (ret) {
+ pr_err("%s: ocmem_map failed\n", __func__);
+ goto fail_cmd;
+ }
+
+
+ while ((atomic_read(&audio_ocmem_lcl.audio_state) !=
+ OCMEM_STATE_EXIT)) {
+
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+
+ switch (atomic_read(&audio_ocmem_lcl.audio_state)) {
+ case OCMEM_STATE_MAP_COMPL:
+ pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n",
+ __func__, atomic_read(&audio_ocmem_lcl.audio_cond),
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL);
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ break;
+ case OCMEM_STATE_SHRINK:
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
+ &audio_ocmem_lcl.mlist);
+ if (ret) {
+ pr_err("%s: ocmem_unmap failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_TRANSITION);
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_UNMAP_COMPL);
+ ret = ocmem_shrink(cid, audio_ocmem_lcl.buf, 0);
+ if (ret) {
+ pr_err("%s: ocmem_shrink failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+
+ break;
+ case OCMEM_STATE_GROW:
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ ret = ocmem_map(cid, audio_ocmem_lcl.buf,
+ &audio_ocmem_lcl.mlist);
+ if (ret) {
+ pr_err("%s: ocmem_map failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_TRANSITION);
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+ atomic_set(&audio_ocmem_lcl.audio_state,
+ OCMEM_STATE_MAP_COMPL);
+ break;
+ }
+ }
+fail_cmd:
+ pr_debug("%s: exit\n", __func__);
+ return ret;
+}
+
+/**
+ * audio_ocmem_disable() - Disable OCMEM for audio
+ * @cid: client id - OCMEM_LP_AUDIO
+ *
+ * OCMEM gets deallocated for audio usecase. Depending on
+ * current audio state, OCMEM will be freed from using audio
+ * segments.
+ */
+int audio_ocmem_disable(int cid)
+{
+ int ret;
+
+ if (atomic_read(&audio_ocmem_lcl.audio_cond))
+ atomic_set(&audio_ocmem_lcl.audio_cond, 0);
+ pr_debug("%s: audio_cond[0x%x], audio_state[0x%x]\n", __func__,
+ atomic_read(&audio_ocmem_lcl.audio_cond),
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ switch (atomic_read(&audio_ocmem_lcl.audio_state)) {
+ case OCMEM_STATE_MAP_COMPL:
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ ret = ocmem_unmap(cid, audio_ocmem_lcl.buf,
+ &audio_ocmem_lcl.mlist);
+ if (ret) {
+ pr_err("%s: ocmem_unmap failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+
+ atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_EXIT);
+
+ wait_event_interruptible(audio_ocmem_lcl.audio_wait,
+ atomic_read(&audio_ocmem_lcl.audio_cond) == 0);
+ case OCMEM_STATE_UNMAP_COMPL:
+ ret = ocmem_free(OCMEM_LP_AUDIO, audio_ocmem_lcl.buf);
+ if (ret) {
+ pr_err("%s: ocmem_free failed, state[%d]\n",
+ __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ goto fail_cmd;
+ }
+ pr_debug("%s: ocmem_free success\n", __func__);
+ default:
+ pr_debug("%s: state=%d", __func__,
+ atomic_read(&audio_ocmem_lcl.audio_state));
+ break;
+
+ }
+ return 0;
+fail_cmd:
+ return ret;
+}
+
+static void voice_ocmem_process_workdata(struct work_struct *work)
+{
+ int cid;
+ bool en;
+ int rc = 0;
+
+ struct voice_ocmem_workdata *voice_ocm_work =
+ container_of(work, struct voice_ocmem_workdata, work);
+
+ en = voice_ocm_work->en;
+ switch (voice_ocm_work->id) {
+ case VOICE:
+ cid = OCMEM_VOICE;
+ if (en)
+ disable_ocmem_for_voice(cid);
+ else
+ enable_ocmem_after_voice(cid);
+ break;
+ default:
+ pr_err("%s: Invalid client id[%d]\n", __func__,
+ voice_ocm_work->id);
+ rc = -EINVAL;
+ }
+
+}
+/**
+ * voice_ocmem_process_req() - disable/enable OCMEM during voice call
+ * @cid: client id - VOICE
+ * @enable: 1 - enable
+ * 0 - disable
+ *
+ * This configures OCMEM during start of voice call. If any
+ * audio clients are already using OCMEM, they will be evicted
+ * out of OCMEM during voice call and get restored after voice
+ * call.
+ */
+int voice_ocmem_process_req(int cid, bool enable)
+{
+
+ struct voice_ocmem_workdata *workdata = NULL;
+
+ if (audio_ocmem_lcl.voice_ocmem_workqueue == NULL) {
+ pr_err("%s: voice ocmem workqueue is NULL\n", __func__);
+ return -EINVAL;
+ }
+ workdata = kzalloc(sizeof(struct voice_ocmem_workdata),
+ GFP_ATOMIC);
+ if (workdata == NULL) {
+ pr_err("%s: mem failure\n", __func__);
+ return -ENOMEM;
+ }
+ workdata->id = cid;
+ workdata->en = enable;
+
+ INIT_WORK(&workdata->work, voice_ocmem_process_workdata);
+ queue_work(audio_ocmem_lcl.voice_ocmem_workqueue, &workdata->work);
+
+ return 0;
+}
+
+/**
+ * disable_ocmem_for_voice() - disable OCMEM during voice call
+ * @cid: client id - OCMEM_VOICE
+ *
+ * This configures OCMEM during start of voice call. If any
+ * audio clients are already using OCMEM, they will be evicted
+ */
+int disable_ocmem_for_voice(int cid)
+{
+ int ret;
+
+ ret = ocmem_evict(cid);
+ if (ret)
+ pr_err("%s: ocmem_evict is not successful\n", __func__);
+ return ret;
+}
+
+/**
+ * enable_ocmem_for_voice() - To enable OCMEM after voice call
+ * @cid: client id - OCMEM_VOICE
+ *
+ * OCMEM gets re-enabled after OCMEM voice call. If other client
+ * is evicted out of OCMEM, that gets restored and remapped in
+ * OCMEM after the voice call.
+ */
+int enable_ocmem_after_voice(int cid)
+{
+ int ret;
+
+ ret = ocmem_restore(cid);
+ if (ret)
+ pr_err("%s: ocmem_restore is not successful\n", __func__);
+ return ret;
+}
+
+
+static void audio_ocmem_process_workdata(struct work_struct *work)
+{
+ int cid;
+ bool en;
+ int rc = 0;
+
+ struct audio_ocmem_workdata *audio_ocm_work =
+ container_of(work, struct audio_ocmem_workdata, work);
+
+ en = audio_ocm_work->en;
+ switch (audio_ocm_work->id) {
+ case AUDIO:
+ cid = OCMEM_LP_AUDIO;
+ if (en)
+ audio_ocmem_enable(cid);
+ else
+ audio_ocmem_disable(cid);
+ break;
+ default:
+ pr_err("%s: Invalid client id[%d]\n", __func__,
+ audio_ocm_work->id);
+ rc = -EINVAL;
+ }
+
+}
+
+/**
+ * audio_ocmem_process_req() - process audio request to use OCMEM
+ * @id: client id - OCMEM_LP_AUDIO
+ * @enable: enable or disable OCMEM
+ *
+ * A workqueue gets created and initialized to use OCMEM for
+ * audio clients.
+ */
+int audio_ocmem_process_req(int id, bool enable)
+{
+ struct audio_ocmem_workdata *workdata = NULL;
+
+ if (audio_ocmem_lcl.audio_ocmem_workqueue == NULL) {
+ pr_err("%s: audio ocmem workqueue is NULL\n", __func__);
+ return -EINVAL;
+ }
+ workdata = kzalloc(sizeof(struct audio_ocmem_workdata),
+ GFP_ATOMIC);
+ if (workdata == NULL) {
+ pr_err("%s: mem failure\n", __func__);
+ return -ENOMEM;
+ }
+ workdata->id = id;
+ workdata->en = enable;
+
+ /* if previous work waiting for ocmem - signal it to exit */
+ atomic_set(&audio_ocmem_lcl.audio_exit, 1);
+
+ INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
+ queue_work(audio_ocmem_lcl.audio_ocmem_workqueue, &workdata->work);
+
+ return 0;
+}
+
+
+static struct notifier_block audio_ocmem_client_nb = {
+ .notifier_call = audio_ocmem_client_cb,
+};
+
+static int audio_ocmem_platform_data_populate(struct platform_device *pdev)
+{
+ int ret;
+ struct msm_bus_scale_pdata *audio_ocmem_bus_scale_pdata = NULL;
+ struct msm_bus_vectors *audio_ocmem_bus_vectors = NULL;
+ struct msm_bus_paths *ocmem_audio_bus_paths = NULL;
+ u32 val;
+
+ if (!pdev->dev.of_node) {
+ pr_err("%s: device tree information missing\n", __func__);
+ return -ENODEV;
+ }
+
+ audio_ocmem_bus_vectors = kzalloc(sizeof(struct msm_bus_vectors),
+ GFP_KERNEL);
+ if (!audio_ocmem_bus_vectors) {
+ dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
+ return -ENOMEM;
+ }
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-ocmem-audio-src-id", &val);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: qcom,msm-ocmem-audio-src-id missing in DT node\n",
+ __func__);
+ goto fail1;
+ }
+ audio_ocmem_bus_vectors->src = val;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-ocmem-audio-dst-id", &val);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: qcom,msm-ocmem-audio-dst-id missing in DT node\n",
+ __func__);
+ goto fail1;
+ }
+ audio_ocmem_bus_vectors->dst = val;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-ocmem-audio-ab", &val);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: qcom,msm-ocmem-audio-ab missing in DT node\n",
+ __func__);
+ goto fail1;
+ }
+ audio_ocmem_bus_vectors->ab = val;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-ocmem-audio-ib", &val);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: qcom,msm-ocmem-audio-ib missing in DT node\n",
+ __func__);
+ goto fail1;
+ }
+ audio_ocmem_bus_vectors->ib = val;
+
+ ocmem_audio_bus_paths = kzalloc(sizeof(struct msm_bus_paths),
+ GFP_KERNEL);
+ if (!ocmem_audio_bus_paths) {
+ dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
+ goto fail1;
+ }
+ ocmem_audio_bus_paths->num_paths = 1;
+ ocmem_audio_bus_paths->vectors = audio_ocmem_bus_vectors;
+
+ audio_ocmem_bus_scale_pdata =
+ kzalloc(sizeof(struct msm_bus_scale_pdata), GFP_KERNEL);
+
+ if (!audio_ocmem_bus_scale_pdata) {
+ dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
+ goto fail2;
+ }
+
+ audio_ocmem_bus_scale_pdata->usecase = ocmem_audio_bus_paths;
+ audio_ocmem_bus_scale_pdata->num_usecases = 1;
+ audio_ocmem_bus_scale_pdata->name = "audio-ocmem";
+
+ dev_set_drvdata(&pdev->dev, audio_ocmem_bus_scale_pdata);
+ return ret;
+
+fail2:
+ kfree(ocmem_audio_bus_paths);
+fail1:
+ kfree(audio_ocmem_bus_vectors);
+ return ret;
+}
+static int ocmem_audio_client_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct msm_bus_scale_pdata *audio_ocmem_bus_scale_pdata = NULL;
+
+ pr_debug("%s\n", __func__);
+ audio_ocmem_lcl.audio_ocmem_workqueue =
+ alloc_workqueue("ocmem_audio_client_driver_audio",
+ WQ_NON_REENTRANT, 0);
+ if (!audio_ocmem_lcl.audio_ocmem_workqueue) {
+ pr_err("%s: Failed to create ocmem audio work queue\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ audio_ocmem_lcl.voice_ocmem_workqueue =
+ alloc_workqueue("ocmem_audio_client_driver_voice",
+ WQ_NON_REENTRANT, 0);
+ if (!audio_ocmem_lcl.voice_ocmem_workqueue) {
+ pr_err("%s: Failed to create ocmem voice work queue\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ init_waitqueue_head(&audio_ocmem_lcl.audio_wait);
+ atomic_set(&audio_ocmem_lcl.audio_cond, 1);
+ atomic_set(&audio_ocmem_lcl.audio_exit, 0);
+ spin_lock_init(&audio_ocmem_lcl.audio_lock);
+
+ /* populate platform data */
+ ret = audio_ocmem_platform_data_populate(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: failed to populate platform data, rc = %d\n",
+ __func__, ret);
+ return -ENODEV;
+ }
+ audio_ocmem_bus_scale_pdata = dev_get_drvdata(&pdev->dev);
+
+ audio_ocmem_lcl.audio_ocmem_bus_client =
+ msm_bus_scale_register_client(audio_ocmem_bus_scale_pdata);
+
+ if (!audio_ocmem_lcl.audio_ocmem_bus_client) {
+ pr_err("%s: msm_bus_scale_register_client() failed\n",
+ __func__);
+ return -EFAULT;
+ }
+ audio_ocmem_lcl.audio_hdl = ocmem_notifier_register(OCMEM_LP_AUDIO,
+ &audio_ocmem_client_nb);
+ if (audio_ocmem_lcl.audio_hdl == NULL) {
+ pr_err("%s: Failed to get ocmem handle %d\n", __func__,
+ OCMEM_LP_AUDIO);
+ }
+ audio_ocmem_lcl.lp_memseg_ptr = NULL;
+ return 0;
+}
+
+static int ocmem_audio_client_remove(struct platform_device *pdev)
+{
+ struct msm_bus_scale_pdata *audio_ocmem_bus_scale_pdata = NULL;
+
+ audio_ocmem_bus_scale_pdata = (struct msm_bus_scale_pdata *)
+ dev_get_drvdata(&pdev->dev);
+
+ kfree(audio_ocmem_bus_scale_pdata->usecase->vectors);
+ kfree(audio_ocmem_bus_scale_pdata->usecase);
+ kfree(audio_ocmem_bus_scale_pdata);
+ ocmem_notifier_unregister(audio_ocmem_lcl.audio_hdl,
+ &audio_ocmem_client_nb);
+ return 0;
+}
+static const struct of_device_id msm_ocmem_audio_dt_match[] = {
+ {.compatible = "qcom,msm-ocmem-audio"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, msm_ocmem_audio_dt_match);
+
+static struct platform_driver audio_ocmem_driver = {
+ .driver = {
+ .name = "audio-ocmem",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_ocmem_audio_dt_match,
+ },
+ .probe = ocmem_audio_client_probe,
+ .remove = ocmem_audio_client_remove,
+};
+
+
+static int __init ocmem_audio_client_init(void)
+{
+ int rc;
+
+ rc = platform_driver_register(&audio_ocmem_driver);
+
+ if (rc)
+ pr_err("%s: Failed to register audio ocmem driver\n", __func__);
+ return rc;
+}
+module_init(ocmem_audio_client_init);
+
+static void __exit ocmem_audio_client_exit(void)
+{
+ platform_driver_unregister(&audio_ocmem_driver);
+}
+
+module_exit(ocmem_audio_client_exit);
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.h b/sound/soc/msm/qdsp6v2/audio_ocmem.h
new file mode 100644
index 0000000..e915516
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AUDIO_OCMEM_H_
+#define _AUDIO_OCMEM_H_
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+
+#include <mach/ocmem.h>
+
+#define AUDIO 0
+#define VOICE 1
+
+#ifdef CONFIG_AUDIO_OCMEM
+int audio_ocmem_process_req(int id, bool enable);
+int voice_ocmem_process_req(int cid, bool enable);
+int enable_ocmem_after_voice(int cid);
+int disable_ocmem_for_voice(int cid);
+#else
+static inline int audio_ocmem_process_req(int id, bool enable)\
+ { return 0; }
+static inline int voice_ocmem_process_req(int cid, bool enable)\
+ { return 0; }
+static inline int enable_ocmem_after_voice(int cid) { return 0; }
+static inline int disable_ocmem_for_voice(int cid) { return 0; }
+#endif
+
+#endif
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
index 1ac872d..047e0f0 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c
@@ -35,6 +35,7 @@
#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
+#include "audio_ocmem.h"
static struct audio_locks the_locks;
@@ -223,6 +224,7 @@
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
prtd->pcm_irq_pos = 0;
+ audio_ocmem_process_req(AUDIO, true);
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
pr_debug("SNDRV_PCM_TRIGGER_START\n");
@@ -231,6 +233,7 @@
break;
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+ audio_ocmem_process_req(AUDIO, false);
atomic_set(&prtd->start, 0);
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index 630405a..492569b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -30,6 +30,7 @@
#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
#include "q6voice.h"
+#include "audio_ocmem.h"
#define VOIP_MAX_Q_LEN 10
#define VOIP_MAX_VOC_PKT_SIZE 640
@@ -452,6 +453,8 @@
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
pr_debug("%s: Trigger start\n", __func__);
+ if ((!prtd->capture_start) && (!prtd->playback_start))
+ voice_ocmem_process_req(VOICE, true);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
prtd->capture_start = 1;
else
@@ -459,6 +462,8 @@
break;
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+ if (prtd->capture_start && prtd->playback_start)
+ voice_ocmem_process_req(VOICE, false);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
prtd->playback_start = 0;
else
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
new file mode 100644
index 0000000..2c31d39
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -0,0 +1,211 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <mach/msm_smd.h>
+#include <mach/qdsp6v2/apr.h>
+#include "q6core.h"
+#include <mach/ocmem.h>
+
+#define TIMEOUT_MS 1000
+
+struct q6core_str {
+ struct apr_svc *core_handle_q;
+ wait_queue_head_t bus_bw_req_wait;
+ u32 bus_bw_resp_received;
+ struct avcs_cmd_rsp_get_low_power_segments_info_t *lp_ocm_payload;
+};
+
+struct q6core_str q6core_lcl;
+
+static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
+{
+ uint32_t *payload1;
+ uint32_t nseg;
+ int i, j;
+
+ pr_info("core msg: payload len = %u, apr resp opcode = 0x%X\n",
+ data->payload_size, data->opcode);
+
+ switch (data->opcode) {
+
+ case APR_BASIC_RSP_RESULT:{
+
+ if (data->payload_size == 0) {
+ pr_err("%s: APR_BASIC_RSP_RESULT No Payload ",
+ __func__);
+ return 0;
+ }
+
+ payload1 = data->payload;
+
+ switch (payload1[0]) {
+
+ case AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO:
+ pr_info("%s: Cmd = AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO status[0x%x]\n",
+ __func__, payload1[1]);
+ break;
+ default:
+ pr_err("Invalid cmd rsp[0x%x][0x%x]\n",
+ payload1[0], payload1[1]);
+ break;
+ }
+ break;
+ }
+
+ case AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO:
+ payload1 = data->payload;
+ pr_info("%s: cmd = AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO num_segments = 0x%x\n",
+ __func__, payload1[0]);
+ nseg = payload1[0];
+ q6core_lcl.lp_ocm_payload->num_segments = nseg;
+ q6core_lcl.lp_ocm_payload->bandwidth = payload1[1];
+ for (i = 0, j = 2; i < nseg; i++) {
+ q6core_lcl.lp_ocm_payload->mem_segment[i].type =
+ (payload1[j] & 0xffff);
+ q6core_lcl.lp_ocm_payload->mem_segment[i].category =
+ ((payload1[j++] >> 16) & 0xffff);
+ q6core_lcl.lp_ocm_payload->mem_segment[i].size =
+ payload1[j++];
+ q6core_lcl.lp_ocm_payload->
+ mem_segment[i].start_address_lsw =
+ payload1[j++];
+ q6core_lcl.lp_ocm_payload->
+ mem_segment[i].start_address_msw =
+ payload1[j++];
+ }
+
+ q6core_lcl.bus_bw_resp_received = 1;
+ wake_up(&q6core_lcl.bus_bw_req_wait);
+ break;
+
+ case RESET_EVENTS:{
+ pr_debug("Reset event received in Core service");
+ apr_reset(q6core_lcl.core_handle_q);
+ q6core_lcl.core_handle_q = NULL;
+ break;
+ }
+
+ default:
+ pr_err("Message id from adsp core svc: %d\n", data->opcode);
+ break;
+ }
+
+ return 0;
+}
+
+
+void ocm_core_open(void)
+{
+ if (q6core_lcl.core_handle_q == NULL)
+ q6core_lcl.core_handle_q = apr_register("ADSP", "CORE",
+ aprv2_core_fn_q, 0xFFFFFFFF, NULL);
+ pr_debug("Open_q %p\n", q6core_lcl.core_handle_q);
+ if (q6core_lcl.core_handle_q == NULL)
+ pr_err("%s: Unable to register CORE\n", __func__);
+}
+
+int core_get_low_power_segments(
+ struct avcs_cmd_rsp_get_low_power_segments_info_t **lp_memseg)
+{
+ struct avcs_cmd_get_low_power_segments_info lp_ocm_cmd;
+ u8 *cptr = NULL;
+ int ret = 0;
+
+ pr_debug("%s: ", __func__);
+
+ ocm_core_open();
+ if (q6core_lcl.core_handle_q == NULL) {
+ pr_info("%s: apr registration for CORE failed\n", __func__);
+ return -ENODEV;
+ }
+
+ cptr = kzalloc(
+ sizeof(struct avcs_cmd_rsp_get_low_power_segments_info_t),
+ GFP_KERNEL);
+ if (!cptr) {
+ pr_err("%s: Failed to allocate memory for low power segment struct\n",
+ __func__);
+ return -ENOMEM;
+ }
+ q6core_lcl.lp_ocm_payload =
+ (struct avcs_cmd_rsp_get_low_power_segments_info_t *) cptr;
+
+ lp_ocm_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ lp_ocm_cmd.hdr.pkt_size =
+ sizeof(struct avcs_cmd_get_low_power_segments_info);
+
+ lp_ocm_cmd.hdr.src_port = 0;
+ lp_ocm_cmd.hdr.dest_port = 0;
+ lp_ocm_cmd.hdr.token = 0;
+ lp_ocm_cmd.hdr.opcode = AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO;
+
+
+ ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) &lp_ocm_cmd);
+ if (ret < 0) {
+ pr_err("%s: CORE low power segment request failed\n", __func__);
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(q6core_lcl.bus_bw_req_wait,
+ (q6core_lcl.bus_bw_resp_received == 1),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout for GET_LOW_POWER_SEGMENTS\n",
+ __func__);
+ ret = -ETIME;
+ goto fail_cmd;
+ }
+
+ *lp_memseg = q6core_lcl.lp_ocm_payload;
+ return 0;
+
+fail_cmd:
+ return ret;
+}
+
+
+static int __init core_init(void)
+{
+ init_waitqueue_head(&q6core_lcl.bus_bw_req_wait);
+ q6core_lcl.bus_bw_resp_received = 0;
+
+ q6core_lcl.core_handle_q = NULL;
+ q6core_lcl.lp_ocm_payload = kzalloc(
+ sizeof(struct avcs_cmd_rsp_get_low_power_segments_info_t), GFP_KERNEL);
+
+ if (!q6core_lcl.lp_ocm_payload) {
+ pr_err("%s: Failed to allocate memory for low power segment struct\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+module_init(core_init);
+
+static void __exit core_exit(void)
+{
+ kfree(q6core_lcl.lp_ocm_payload);
+}
+module_exit(core_exit);
+MODULE_DESCRIPTION("ADSP core driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/sound/soc/msm/qdsp6v2/q6core.h b/sound/soc/msm/qdsp6v2/q6core.h
new file mode 100644
index 0000000..5cb6098
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/q6core.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __Q6CORE_H__
+#define __Q6CORE_H__
+#include <mach/qdsp6v2/apr.h>
+#include <mach/ocmem.h>
+
+
+#define AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO 0x00012903
+
+struct avcs_cmd_get_low_power_segments_info {
+ struct apr_hdr hdr;
+} __packed;
+
+
+#define AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO 0x00012904
+
+/* @brief AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO payload
+ * structure. Payload for this event comprises one instance of
+ * avcs_cmd_rsp_get_low_power_segments_info_t, followed
+ * immediately by num_segments number of instances of the
+ * avcs_mem_segment_t structure.
+ */
+
+/* Types of Low Power Memory Segments. */
+#define READ_ONLY_SEGMENT 1
+/*< Read Only memory segment. */
+#define READ_WRITE_SEGMENT 2
+/*< Read Write memory segment. */
+/*Category indicates whether audio/os/sensor segments. */
+#define AUDIO_SEGMENT 1
+/*< Audio memory segment. */
+#define OS_SEGMENT 2
+/*< QDSP6's OS memory segment. */
+
+/* @brief Payload structure for AVS low power memory segment
+ * structure.
+ */
+struct avcs_mem_segment_t {
+ uint16_t type;
+/*< Indicates which type of memory this segment is.
+ *Allowed values: READ_ONLY_SEGMENT or READ_WRITE_SEGMENT only.
+ */
+ uint16_t category;
+/*< Indicates whether audio or OS segments.
+ *Allowed values: AUDIO_SEGMENT or OS_SEGMENT only.
+ */
+ uint32_t size;
+/*< Size (in bytes) of this segment.
+ * Will be a non-zero value.
+ */
+ uint32_t start_address_lsw;
+/*< Lower 32 bits of the 64-bit physical start address
+ * of this segment.
+ */
+ uint32_t start_address_msw;
+/*< Upper 32 bits of the 64-bit physical start address
+ * of this segment.
+ */
+};
+
+struct avcs_cmd_rsp_get_low_power_segments_info_t {
+ uint32_t num_segments;
+/*< Number of segments in this response.
+ * 0: there are no known sections that should be mapped
+ * from DDR to OCMEM.
+ * >0: the number of memory segments in the following list.
+ */
+
+ uint32_t bandwidth;
+/*< Required OCMEM read/write bandwidth (in bytes per second)
+ * if OCMEM is granted.
+ * 0 if num_segments = 0
+ * >0 if num_segments > 0.
+ */
+ struct avcs_mem_segment_t mem_segment[OCMEM_MAX_CHUNKS];
+};
+
+
+int core_get_low_power_segments(
+ struct avcs_cmd_rsp_get_low_power_segments_info_t **);
+
+#endif /* __Q6CORE_H__ */