Merge "msm: pil-venus: Implement subsystem restart callbacks"
diff --git a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
index b7dd427..f8152cfb 100644
--- a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
+++ b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
@@ -37,9 +37,9 @@
- qcom,algo-ss-win-size-max-us: sets maximum steady state window size.
- qcom,algo-ss-util-pct: sets target CPU utilization during
steady-state.
-- qcom,algo-ss-iobusy-conv: specifies how wait time (i/o busy time)
- is incorporated into the steady-state
- algorithm.
+- qcom,algo-ss-no-corr-below-freq: specifies frequency below which DCVS
+ will not attempt to correlate busy or
+ idle information from different CPUs
- qcom,energy-active-coeff-a: sets active power equation coefficient a.
- qcom,energy-active-coeff-b: sets active power equation coefficient b.
@@ -89,7 +89,7 @@
qcom,algo-ss-win-size-min-us = <1000000>;
qcom,algo-ss-win-size-max-us = <1000000>;
qcom,algo-ss-util-pct = <95>;
- qcom,algo-ss-iobusy-conv = <100>;
+ qcom,algo-ss-no-corr-below-freq = <0>;
qcom,energy-active-coeff-a = <2492>;
qcom,energy-active-coeff-b = <0>;
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 9164647..2ea9ba9 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -132,7 +132,7 @@
qcom,algo-ss-window-size = <1000000>;
qcom,algo-ss-util-pct = <95>;
qcom,algo-em-max-util-pct = <97>;
- qcom,algo-ss-iobusy-conv = <100>;
+ qcom,algo-ss-no-corr-below-freq = <0>;
qcom,dcvs-freq@0 {
reg = <0>;
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index 090d8db..74c25a0 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -34,7 +34,7 @@
- qcom,cdc-micbias2-ext-cap: Boolean. Enable micbias 2 external capacitor mode.
- qcom,cdc-micbias3-ext-cap: Boolean. Enable micbias 3 external capacitor mode.
- qcom,cdc-micbias4-ext-cap: Boolean. Enable micbias 4 external capacitor mode.
-
+ - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for codec.
- qcom,cdc-slim-ifd-dev - namme of the codec slim interface device.
- qcom,cdc-slim-ifd-elemental-addr - codec slimbus slave interface device
enumeration address.
@@ -86,7 +86,7 @@
qcom,cdc-micbias2-ext-cap;
qcom,cdc-micbias3-ext-cap;
qcom,cdc-micbias4-ext-cap;
-
+ qcom,cdc-mclk-clk-rate = <9600000>;
qcom,cdc-slim-ifd = "taiko-slim-ifd";
qcom,cdc-slim-ifd-elemental-addr = [00 00 A0 00 17 02];
};
@@ -123,6 +123,7 @@
- qcom,cdc-micbias2-ext-cap: Boolean. Enable micbias 2 external capacitor mode.
- qcom,cdc-micbias3-ext-cap: Boolean. Enable micbias 3 external capacitor mode.
- qcom,cdc-micbias4-ext-cap: Boolean. Enable micbias 4 external capacitor mode.
+ - qcom,cdc-mclk-clk-rate - Specifies the master clock rate in Hz required for codec.
Example:
i2c@f9925000 {
@@ -180,6 +181,7 @@
qcom,cdc-micbias2-cfilt-sel = <0x1>;
qcom,cdc-micbias3-cfilt-sel = <0x2>;
qcom,cdc-micbias4-cfilt-sel = <0x2>;
+ qcom,cdc-mclk-clk-rate = <12288000>;
};
wcd9xxx_codec@77{
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
index 41ac69d..9a0ec17 100644
--- a/arch/arm/boot/dts/msm8226-sim.dts
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -23,3 +23,54 @@
status = "ok";
};
};
+
+&sdcc1 {
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <800 500000>;
+
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <250 154000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ vdd-supply = <&pm8026_l17>;
+ vdd-io-supply = <&pm8026_l6>;
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+ status = "ok";
+};
+
+&sdcc2 {
+ vdd-supply = <&pm8026_l18>;
+ vdd-io-supply = <&pm8026_l21>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
+
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <6 22000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,xpc;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+ qcom,current-limit = <800>;
+
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index a69e1b7..38a9ba4 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -32,6 +32,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xfd510000 0x4000>;
+ gpio-controller;
#gpio-cells = <2>;
interrupts = <0 208 0>;
};
@@ -159,6 +160,31 @@
};
};
+ sdcc1: qcom,sdcc@f9824000 {
+ cell-index = <1>; /* SDC1 eMMC slot */
+ compatible = "qcom,msm-sdcc";
+
+ reg = <0xf9824000 0x800>;
+ reg-names = "core_mem";
+ interrupts = <0 123 0>;
+ interrupt-names ="core_irq";
+
+ qcom,bus-width = <8>;
+ status = "disabled";
+ };
+
+ sdcc2: qcom,sdcc@f98a4000 {
+ cell-index = <2>; /* SDC2 SD card slot */
+ compatible = "qcom,msm-sdcc";
+
+ reg = <0xf98a4000 0x800>;
+ reg-names = "core_mem";
+ interrupts = <0 125 0>;
+ interrupt-names = "core_irq";
+
+ qcom,bus-width = <4>;
+ status = "disabled";
+ };
};
&gdsc_venus {
diff --git a/arch/arm/boot/dts/msm8910.dtsi b/arch/arm/boot/dts/msm8910.dtsi
index e1e608b..2d7ad2b 100644
--- a/arch/arm/boot/dts/msm8910.dtsi
+++ b/arch/arm/boot/dts/msm8910.dtsi
@@ -33,6 +33,7 @@
interrupt-controller;
#interrupt-cells = <2>;
reg = <0xfd510000 0x4000>;
+ gpio-controller;
#gpio-cells = <2>;
interrupts = <0 208 0>;
};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 570eb0f..979876d 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -233,6 +233,10 @@
wp-gpios = <&pm8941_gpios 29 0x1>;
};
+&usb3 {
+ qcom,otg-capability;
+};
+
&pm8941_chg {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index e4211b3..6a35f2f 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -252,6 +252,10 @@
cd-gpios = <&msmgpio 62 0x1>;
};
+&usb3 {
+ qcom,otg-capability;
+};
+
&pm8941_chg {
status = "ok";
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index 6623568..480a034 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -36,8 +36,8 @@
qcom,msm-bus,num-paths = <2>;
qcom,msm-bus,vectors-KBps =
<26 512 0 0>, <89 604 0 0>,
- <26 512 0 2000000>, <89 604 0 3000000>,
- <26 512 0 4000000>, <89 604 0 5000000>,
+ <26 512 0 1600000>, <89 604 0 3000000>,
+ <26 512 0 4000000>, <89 604 0 4500000>,
<26 512 0 6400000>, <89 604 0 7600000>;
/* GDSC oxili regulators */
@@ -108,7 +108,7 @@
qcom,algo-ss-win-size-min-us = <1000000>;
qcom,algo-ss-win-size-max-us = <1000000>;
qcom,algo-ss-util-pct = <95>;
- qcom,algo-ss-iobusy-conv = <100>;
+ qcom,algo-ss-no-corr-below-freq = <0>;
qcom,energy-active-coeff-a = <2492>;
qcom,energy-active-coeff-b = <0>;
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index c877134..b8a977b 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -188,10 +188,10 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <100>;
- qcom,ss-power = <650>;
- qcom,energy-overhead = <801>;
- qcom,time-overhead = <200>;
+ qcom,latency-us = <1>;
+ qcom,ss-power = <784>;
+ qcom,energy-overhead = <190000>;
+ qcom,time-overhead = <100>;
};
qcom,lpm-level@1 {
@@ -203,10 +203,10 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <1500>;
- qcom,ss-power = <200>;
- qcom,energy-overhead = <576000>;
- qcom,time-overhead = <2000>;
+ qcom,latency-us = <75>;
+ qcom,ss-power = <735>;
+ qcom,energy-overhead = <77341>;
+ qcom,time-overhead = <105>;
};
@@ -219,10 +219,10 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <2000>;
- qcom,ss-power = <200>;
- qcom,energy-overhead = <576000>;
- qcom,time-overhead = <2000>;
+ qcom,latency-us = <95>;
+ qcom,ss-power = <725>;
+ qcom,energy-overhead = <99500>;
+ qcom,time-overhead = <130>;
};
qcom,lpm-level@3 {
@@ -234,10 +234,10 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <8500>;
- qcom,ss-power = <51>;
- qcom,energy-overhead = <1122000>;
- qcom,time-overhead = <8500>;
+ qcom,latency-us = <2000>;
+ qcom,ss-power = <138>;
+ qcom,energy-overhead = <1208400>;
+ qcom,time-overhead = <3200>;
};
qcom,lpm-level@4 {
@@ -245,33 +245,18 @@
qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <1>; /* ON */
qcom,l2 = <0>; /* OFF */
- qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
- qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
- qcom,vdd-dig-upper-bound = <5>; /* MAX */
- qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <9000>;
- qcom,ss-power = <51>;
- qcom,energy-overhead = <1130300>;
- qcom,time-overhead = <9000>;
- };
-
- qcom,lpm-level@5 {
- reg = <0x5>;
- qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
- qcom,xo = <1>; /* ON */
- qcom,l2 = <0>; /* OFF */
qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
qcom,vdd-mem-lower-bound = <750000>; /* RETENTION HIGH */
qcom,vdd-dig-upper-bound = <3>; /* ACTIVE */
qcom,vdd-dig-lower-bound = <2>; /* RETENTION HIGH */
- qcom,latency-us = <10000>;
- qcom,ss-power = <51>;
- qcom,energy-overhead = <1130300>;
- qcom,time-overhead = <10000>;
+ qcom,latency-us = <3000>;
+ qcom,ss-power = <110>;
+ qcom,energy-overhead = <1250300>;
+ qcom,time-overhead = <3500>;
};
- qcom,lpm-level@6 {
- reg = <0x6>;
+ qcom,lpm-level@5 {
+ reg = <0x5>;
qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
qcom,l2 = <1>; /* GDHS */
@@ -279,14 +264,14 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <12000>;
- qcom,ss-power = <14>;
- qcom,energy-overhead = <2205900>;
- qcom,time-overhead = <12000>;
+ qcom,latency-us = <3000>;
+ qcom,ss-power = <68>;
+ qcom,energy-overhead = <1350200>;
+ qcom,time-overhead = <4000>;
};
- qcom,lpm-level@7 {
- reg = <0x7>;
+ qcom,lpm-level@6 {
+ reg = <0x6>;
qcom,mode = <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
qcom,l2 = <0>; /* OFF */
@@ -294,14 +279,14 @@
qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
qcom,vdd-dig-upper-bound = <5>; /* MAX */
qcom,vdd-dig-lower-bound = <3>; /* ACTIVE */
- qcom,latency-us = <18000>;
- qcom,ss-power = <12>;
- qcom,energy-overhead = <2364250>;
- qcom,time-overhead = <18000>;
+ qcom,latency-us = <10300>;
+ qcom,ss-power = <63>;
+ qcom,energy-overhead = <2128000>;
+ qcom,time-overhead = <18200>;
};
- qcom,lpm-level@8 {
- reg = <0x8>;
+ qcom,lpm-level@7 {
+ reg = <0x7>;
qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
qcom,l2 = <0>; /* OFF */
@@ -309,14 +294,14 @@
qcom,vdd-mem-lower-bound = <750000>; /* RETENTION HIGH */
qcom,vdd-dig-upper-bound = <3>; /* ACTIVE */
qcom,vdd-dig-lower-bound = <2>; /* RETIONTION HIGH */
- qcom,latency-us = <23500>;
+ qcom,latency-us = <18000>;
qcom,ss-power = <10>;
- qcom,energy-overhead = <2667000>;
- qcom,time-overhead = <23500>;
+ qcom,energy-overhead = <3202600>;
+ qcom,time-overhead = <27000>;
};
- qcom,lpm-level@9 {
- reg = <0x9>;
+ qcom,lpm-level@8 {
+ reg = <0x8>;
qcom,mode= <3>; /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
qcom,xo = <0>; /* OFF */
qcom,l2 = <0>; /* OFF */
@@ -324,10 +309,10 @@
qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
- qcom,latency-us = <29700>;
- qcom,ss-power = <5>;
- qcom,energy-overhead = <2867000>;
- qcom,time-overhead = <30000>;
+ qcom,latency-us = <20000>;
+ qcom,ss-power = <2>;
+ qcom,energy-overhead = <4252000>;
+ qcom,time-overhead = <32000>;
};
};
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 2cef567..a7a7c88 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -108,9 +108,9 @@
rpm-regulator-smpb4 {
status = "okay";
pm8841_s4: regulator-s4 {
- regulator-min-microvolt = <900000>;
+ regulator-min-microvolt = <815000>;
regulator-max-microvolt = <900000>;
- qcom,init-voltage = <900000>;
+ qcom,init-voltage = <815000>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index a892d24..1faa5f4 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -406,7 +406,7 @@
qcom,cdc-micbias2-cfilt-sel = <0x1>;
qcom,cdc-micbias3-cfilt-sel = <0x2>;
qcom,cdc-micbias4-cfilt-sel = <0x2>;
-
+ qcom,cdc-mclk-clk-rate = <9600000>;
qcom,cdc-slim-ifd = "taiko-slim-ifd";
qcom,cdc-slim-ifd-elemental-addr = [00 00 A0 00 17 02];
};
@@ -878,6 +878,14 @@
<11 604 32506 32506>;
};
+ qcom,msm-adsp-sensors {
+ compatible = "qcom,msm-adsp-sensors";
+ qcom,msm-adsp-sensors-src-id = <11>;
+ qcom,msm-adsp-sensors-dst-id = <604>;
+ qcom,msm-adsp-sensors-ab = <32505856>;
+ qcom,msm-adsp-sensors-ib = <32505856>;
+ };
+
qcom,mss@fc880000 {
compatible = "qcom,pil-q6v5-mss";
reg = <0xfc880000 0x100>,
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index dfa5223..324d358 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -417,6 +417,7 @@
qcom,cdc-micbias2-cfilt-sel = <0x1>;
qcom,cdc-micbias3-cfilt-sel = <0x2>;
qcom,cdc-micbias4-cfilt-sel = <0x2>;
+ qcom,cdc-mclk-clk-rate = <12288000>;
};
wcd9xxx_codec@77{
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index e6255f2..ccd23e8 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -184,6 +184,7 @@
select USE_USER_ACCESSIBLE_TIMERS
select ARM_USE_USER_ACCESSIBLE_TIMERS
select MSM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_CPU_PWRCTL
config ARCH_MSM8930
bool "MSM8930"
@@ -221,6 +222,7 @@
select USE_USER_ACCESSIBLE_TIMERS
select ARM_USE_USER_ACCESSIBLE_TIMERS
select MSM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_CPU_PWRCTL
config ARCH_APQ8064
bool "APQ8064"
@@ -254,6 +256,7 @@
select USE_USER_ACCESSIBLE_TIMERS
select ARM_USE_USER_ACCESSIBLE_TIMERS
select MSM_USE_USER_ACCESSIBLE_TIMERS
+ select MSM_CPU_PWRCTL
config ARCH_MSM8974
bool "MSM8974"
@@ -2715,4 +2718,11 @@
help
Use Device Control Volume as opposed to ALSA volume control.
+config MSM_CPU_PWRCTL
+ bool "Ensures that krait droop detectors are always off"
+ help
+ Droop detector mechanism can adversely affect krait plls during
+ stand alone power collapse operation. Selecting this option
+ ensures that they are always off.
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 64fa9e2..78fe55f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -305,6 +305,7 @@
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
obj-$(CONFIG_ARCH_MSM8910) += board-8910.o board-8910-gpiomux.o
+obj-$(CONFIG_ARCH_MSM8910) += clock-local2.o clock-pll.o clock-8910.o clock-rpm.o clock-voter.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
@@ -418,3 +419,4 @@
obj-$(CONFIG_MEMORY_HOLE_CARVEOUT) += msm_mem_hole.o
obj-$(CONFIG_MSM_SMCMOD) += smcmod.o
+obj-$(CONFIG_MSM_CPU_PWRCTL) += msm_cpu_pwrctl.o
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index 8174370..db77a34 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -505,20 +505,20 @@
[0][PVS_FASTER] = {tbl_faster, sizeof(tbl_faster), 25000 },
[1][0] = { tbl_PVS0_1700MHz, sizeof(tbl_PVS0_1700MHz), 0 },
- [1][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz), 0 },
- [1][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz), 0 },
- [1][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz), 0 },
- [1][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz), 0 },
- [1][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz), 0 },
- [1][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz), 0 },
+ [1][1] = { tbl_PVS1_1700MHz, sizeof(tbl_PVS1_1700MHz), 25000 },
+ [1][2] = { tbl_PVS2_1700MHz, sizeof(tbl_PVS2_1700MHz), 25000 },
+ [1][3] = { tbl_PVS3_1700MHz, sizeof(tbl_PVS3_1700MHz), 25000 },
+ [1][4] = { tbl_PVS4_1700MHz, sizeof(tbl_PVS4_1700MHz), 25000 },
+ [1][5] = { tbl_PVS5_1700MHz, sizeof(tbl_PVS5_1700MHz), 25000 },
+ [1][6] = { tbl_PVS6_1700MHz, sizeof(tbl_PVS6_1700MHz), 25000 },
[2][0] = { tbl_PVS0_2000MHz, sizeof(tbl_PVS0_2000MHz), 0 },
- [2][1] = { tbl_PVS1_2000MHz, sizeof(tbl_PVS1_2000MHz), 0 },
- [2][2] = { tbl_PVS2_2000MHz, sizeof(tbl_PVS2_2000MHz), 0 },
- [2][3] = { tbl_PVS3_2000MHz, sizeof(tbl_PVS3_2000MHz), 0 },
- [2][4] = { tbl_PVS4_2000MHz, sizeof(tbl_PVS4_2000MHz), 0 },
- [2][5] = { tbl_PVS5_2000MHz, sizeof(tbl_PVS5_2000MHz), 0 },
- [2][6] = { tbl_PVS6_2000MHz, sizeof(tbl_PVS6_2000MHz), 0 },
+ [2][1] = { tbl_PVS1_2000MHz, sizeof(tbl_PVS1_2000MHz), 25000 },
+ [2][2] = { tbl_PVS2_2000MHz, sizeof(tbl_PVS2_2000MHz), 25000 },
+ [2][3] = { tbl_PVS3_2000MHz, sizeof(tbl_PVS3_2000MHz), 25000 },
+ [2][4] = { tbl_PVS4_2000MHz, sizeof(tbl_PVS4_2000MHz), 25000 },
+ [2][5] = { tbl_PVS5_2000MHz, sizeof(tbl_PVS5_2000MHz), 25000 },
+ [2][6] = { tbl_PVS6_2000MHz, sizeof(tbl_PVS6_2000MHz), 25000 },
};
static struct acpuclk_krait_params acpuclk_8064_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8625q.c b/arch/arm/mach-msm/acpuclock-8625q.c
index 00022ff..0a6dfbe 100644
--- a/arch/arm/mach-msm/acpuclock-8625q.c
+++ b/arch/arm/mach-msm/acpuclock-8625q.c
@@ -554,7 +554,9 @@
#define MHZ 1000000
-static void __devinit select_freq_plan(unsigned int pvs_voltage)
+static void __devinit select_freq_plan(unsigned int pvs_voltage,
+ unsigned int nominal_vol_uv,
+ unsigned int default_vol_uv)
{
unsigned long pll_mhz[ACPU_PLL_END];
int i;
@@ -628,6 +630,8 @@
*/
for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
if (tbl->a11clk_khz >= 1008000) {
+ if (tbl->a11clk_khz == 1209600)
+ tbl->vdd = default_vol_uv;
/*
* Change voltage as per PVS formula,
* i is initialized above with 2 or 1
@@ -639,11 +643,13 @@
tbl->vdd = max((int)(pvs_voltage - delta[i]), tbl->vdd);
i--;
- }
+ } else if (tbl->a11clk_khz != 600000
+ && tbl->a11clk_khz != 19200)
+ tbl->vdd = nominal_vol_uv;
}
- /* find the backup PLL entry from the table */
+ /* find the backup PLL entry from the table */
for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
if (tbl->pll == ACPU_PLL_2 &&
tbl->a11clk_src_div == 1) {
@@ -723,6 +729,8 @@
{
const struct acpuclk_pdata_8625q *pdata = pdev->dev.platform_data;
unsigned int pvs_voltage = pdata->pvs_voltage_uv;
+ unsigned int nom_vol_uv = pdata->nominal_voltage;
+ unsigned int default_vol_uv = pdata->default_turbo_voltage;
drv_state.max_speed_delta_khz = pdata->acpu_clk_data->
max_speed_delta_khz;
@@ -731,7 +739,7 @@
BUG_ON(IS_ERR(drv_state.ebi1_clk));
mutex_init(&drv_state.lock);
- select_freq_plan(pvs_voltage);
+ select_freq_plan(pvs_voltage, nom_vol_uv, default_vol_uv);
acpuclk_8625q_data.wait_for_irq_khz = find_wait_for_irq_khz();
if (acpuclk_hw_init() < 0)
diff --git a/arch/arm/mach-msm/acpuclock-8625q.h b/arch/arm/mach-msm/acpuclock-8625q.h
index ca2058f..c91e3bd 100644
--- a/arch/arm/mach-msm/acpuclock-8625q.h
+++ b/arch/arm/mach-msm/acpuclock-8625q.h
@@ -23,6 +23,8 @@
struct acpuclk_pdata_8625q {
struct acpuclk_pdata *acpu_clk_data;
unsigned int pvs_voltage_uv;
+ unsigned int nominal_voltage;
+ unsigned int default_turbo_voltage;
};
#endif /* __ARCH_ARM_MACH_MSM_ACPUCLOCK_8625Q_H */
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index 96029b4..5003862 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -243,9 +243,9 @@
/* TODO: Update boost voltage once the pvs data is available */
static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
-[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
-[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 0 },
-[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 0 },
+[0][PVS_SLOW] = { acpu_freq_tbl_slow, sizeof(acpu_freq_tbl_slow), 0 },
+[0][PVS_NOMINAL] = { acpu_freq_tbl_nom, sizeof(acpu_freq_tbl_nom), 25000 },
+[0][PVS_FAST] = { acpu_freq_tbl_fast, sizeof(acpu_freq_tbl_fast), 25000 },
};
static struct acpuclk_krait_params acpuclk_8930ab_params __initdata = {
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 03a2004..9b4eecd 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -233,12 +233,12 @@
static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
[0][0] = { freq_tbl_PVS0, sizeof(freq_tbl_PVS0), 0 },
-[0][1] = { freq_tbl_PVS1, sizeof(freq_tbl_PVS1), 0 },
-[0][2] = { freq_tbl_PVS2, sizeof(freq_tbl_PVS2), 0 },
-[0][3] = { freq_tbl_PVS3, sizeof(freq_tbl_PVS3), 0 },
-[0][4] = { freq_tbl_PVS4, sizeof(freq_tbl_PVS4), 0 },
-[0][5] = { freq_tbl_PVS5, sizeof(freq_tbl_PVS5), 0 },
-[0][6] = { freq_tbl_PVS6, sizeof(freq_tbl_PVS6), 0 },
+[0][1] = { freq_tbl_PVS1, sizeof(freq_tbl_PVS1), 25000 },
+[0][2] = { freq_tbl_PVS2, sizeof(freq_tbl_PVS2), 25000 },
+[0][3] = { freq_tbl_PVS3, sizeof(freq_tbl_PVS3), 25000 },
+[0][4] = { freq_tbl_PVS4, sizeof(freq_tbl_PVS4), 25000 },
+[0][5] = { freq_tbl_PVS5, sizeof(freq_tbl_PVS5), 25000 },
+[0][6] = { freq_tbl_PVS6, sizeof(freq_tbl_PVS6), 25000 },
};
static struct acpuclk_krait_params acpuclk_8960ab_params __initdata = {
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index cd3e636..9e34f47 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -1647,7 +1647,8 @@
msm_gpiomux_install(mpq8064_mi2s_configs,
ARRAY_SIZE(mpq8064_mi2s_configs));
- msm_gpiomux_install(apq8064_ext_regulator_configs,
+ if (!machine_is_mpq8064_hrd())
+ msm_gpiomux_install(apq8064_ext_regulator_configs,
ARRAY_SIZE(apq8064_ext_regulator_configs));
if (machine_is_apq8064_mtp()) {
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 38ac83e..6b15883 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -51,7 +51,7 @@
.ss_win_size_min_us = 1000000,
.ss_win_size_max_us = 1000000,
.ss_util_pct = 95,
- .ss_iobusy_conv = 100,
+ .ss_no_corr_below_freq = 0,
},
.energy_coeffs = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ed03e46..07e2623 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1635,10 +1635,10 @@
static struct cyttsp_platform_data cyttsp_pdata = {
.panel_maxx = 634,
.panel_maxy = 1166,
- .disp_maxx = 599,
- .disp_maxy = 1023,
- .disp_minx = 0,
- .disp_miny = 0,
+ .disp_minx = 18,
+ .disp_maxx = 617,
+ .disp_miny = 18,
+ .disp_maxy = 1041,
.flags = 0x01,
.gen = CY_GEN3,
.use_st = CY_USE_ST,
@@ -2527,6 +2527,13 @@
&apq8064_device_ssbi_pmic2,
};
+static struct platform_device *pm8921_mpq_hrd_common_devices[] __initdata = {
+ &apq8064_device_ext_5v_vreg,
+ &apq8064_device_ext_mpp8_vreg,
+ &apq8064_device_ssbi_pmic1,
+ &apq8064_device_ssbi_pmic2,
+};
+
static struct platform_device *pm8917_common_devices[] __initdata = {
&apq8064_device_ext_mpp8_vreg,
&apq8064_device_ext_3p3v_vreg,
@@ -3556,9 +3563,14 @@
platform_add_devices(early_common_devices,
ARRAY_SIZE(early_common_devices));
- if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917)
- platform_add_devices(pm8921_common_devices,
- ARRAY_SIZE(pm8921_common_devices));
+ if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
+ if (!machine_is_mpq8064_hrd())
+ platform_add_devices(pm8921_common_devices,
+ ARRAY_SIZE(pm8921_common_devices));
+ else
+ platform_add_devices(pm8921_mpq_hrd_common_devices,
+ ARRAY_SIZE(pm8921_mpq_hrd_common_devices));
+ }
else
platform_add_devices(pm8917_common_devices,
ARRAY_SIZE(pm8917_common_devices));
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
index f9c5367..a4bafa5 100644
--- a/arch/arm/mach-msm/board-8910.c
+++ b/arch/arm/mach-msm/board-8910.c
@@ -58,37 +58,6 @@
return MEMTYPE_EBI1;
}
-static struct clk_lookup msm_clocks_dummy[] = {
- CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
- CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
- CLK_DUMMY("iface_clk", HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
- CLK_DUMMY("core_clk", HSUSB_CORE_CLK, "f9a55000.usb", OFF),
- CLK_DUMMY("iface_clk", NULL, "msm_sdcc.1", OFF),
- CLK_DUMMY("core_clk", NULL, "msm_sdcc.1", OFF),
- CLK_DUMMY("bus_clk", NULL, "msm_sdcc.1", OFF),
- CLK_DUMMY("iface_clk", NULL, "msm_sdcc.2", OFF),
- CLK_DUMMY("core_clk", NULL, "msm_sdcc.2", OFF),
- CLK_DUMMY("bus_clk", NULL, "msm_sdcc.2", OFF),
- CLK_DUMMY("dfab_clk", DFAB_CLK, "msm_sps", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd890000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd890000.qcom,iommu", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd860000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd860000.qcom,iommu", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd870000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd870000.qcom,iommu", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd880000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd880000.qcom,iommu", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd000000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd000000.qcom,iommu", OFF),
- CLK_DUMMY("iface_clk", NULL, "fd010000.qcom,iommu", OFF),
- CLK_DUMMY("core_clk", NULL, "fd010000.qcom,iommu", OFF),
-};
-
-static struct clock_init_data msm_dummy_clock_init_data __initdata = {
- .table = msm_clocks_dummy,
- .size = ARRAY_SIZE(msm_clocks_dummy),
-};
-
static struct of_dev_auxdata msm8910_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9824000, \
"msm_sdcc.1", NULL),
@@ -118,7 +87,11 @@
struct of_dev_auxdata *adata = msm8910_auxdata_lookup;
msm8910_init_gpiomux();
- msm_clock_init(&msm_dummy_clock_init_data);
+
+ if (machine_is_msm8910_rumi())
+ msm_clock_init(&msm8910_rumi_clock_init_data);
+ else
+ msm_clock_init(&msm8910_clock_init_data);
if (socinfo_init() < 0)
pr_err("%s: socinfo_init() failed\n", __func__);
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 1dcd54f..2392f57 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -882,7 +882,9 @@
&msm_device_hsic_host,
&msm_device_usb_bam,
&msm_android_usb_device,
+#ifdef CONFIG_USB_CI13XXX_MSM_HSIC
&msm_android_usb_hsic_device,
+#endif
&msm9615_device_uart_gsbi4,
&msm9615_device_ext_2p95v_vreg,
&msm9615_device_ssbi_pmic1,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index d15b67d..82fe67b 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -667,6 +667,10 @@
/* Regulator configuration for the NCP6335D buck */
struct regulator_consumer_supply ncp6335d_consumer_supplies[] = {
REGULATOR_SUPPLY("ncp6335d", NULL),
+ /* TO DO: NULL entry needs to be fixed once
+ * we fix the cross-dependencies.
+ */
+ REGULATOR_SUPPLY("vddx_cx", NULL),
};
static struct regulator_init_data ncp6335d_init_data = {
diff --git a/arch/arm/mach-msm/clock-8910.c b/arch/arm/mach-msm/clock-8910.c
new file mode 100644
index 0000000..c5541b4
--- /dev/null
+++ b/arch/arm/mach-msm/clock-8910.c
@@ -0,0 +1,3443 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+
+#include <mach/rpm-regulator-smd.h>
+#include <mach/socinfo.h>
+#include <mach/rpm-smd.h>
+
+#include "clock-local2.h"
+#include "clock-pll.h"
+#include "clock-rpm.h"
+#include "clock-voter.h"
+#include "clock.h"
+
+enum {
+ GCC_BASE,
+ MMSS_BASE,
+ LPASS_BASE,
+ APCS_BASE,
+ N_BASES,
+};
+
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define MMSS_REG_BASE(x) (void __iomem *)(virt_bases[MMSS_BASE] + (x))
+#define LPASS_REG_BASE(x) (void __iomem *)(virt_bases[LPASS_BASE] + (x))
+#define APCS_REG_BASE(x) (void __iomem *)(virt_bases[APCS_BASE] + (x))
+
+#define GPLL0_MODE 0x0000
+#define GPLL0_L_VAL 0x0004
+#define GPLL0_M_VAL 0x0008
+#define GPLL0_N_VAL 0x000C
+#define GPLL0_USER_CTL 0x0010
+#define GPLL0_STATUS 0x001C
+#define GPLL2_MODE 0x0080
+#define GPLL2_L_VAL 0x0084
+#define GPLL2_M_VAL 0x0088
+#define GPLL2_N_VAL 0x008C
+#define GPLL2_USER_CTL 0x0090
+#define GPLL2_STATUS 0x009C
+#define CONFIG_NOC_BCR 0x0140
+#define MMSS_BCR 0x0240
+#define MMSS_NOC_CFG_AHB_CBCR 0x024C
+#define MSS_CFG_AHB_CBCR 0x0280
+#define MSS_Q6_BIMC_AXI_CBCR 0x0284
+#define USB_HS_BCR 0x0480
+#define USB_HS_SYSTEM_CBCR 0x0484
+#define USB_HS_AHB_CBCR 0x0488
+#define USB_HS_SYSTEM_CMD_RCGR 0x0490
+#define USB2A_PHY_BCR 0x04A8
+#define USB2A_PHY_SLEEP_CBCR 0x04AC
+#define SDCC1_BCR 0x04C0
+#define SDCC1_APPS_CMD_RCGR 0x04D0
+#define SDCC1_APPS_CBCR 0x04C4
+#define SDCC1_AHB_CBCR 0x04C8
+#define SDCC2_BCR 0x0500
+#define SDCC2_APPS_CMD_RCGR 0x0510
+#define SDCC2_APPS_CBCR 0x0504
+#define SDCC2_AHB_CBCR 0x0508
+#define BLSP1_BCR 0x05C0
+#define BLSP1_AHB_CBCR 0x05C4
+#define BLSP1_QUP1_BCR 0x0640
+#define BLSP1_QUP1_SPI_APPS_CBCR 0x0644
+#define BLSP1_QUP1_I2C_APPS_CBCR 0x0648
+#define BLSP1_QUP1_SPI_APPS_CMD_RCGR 0x064C
+#define BLSP1_UART1_BCR 0x0680
+#define BLSP1_UART1_APPS_CBCR 0x0684
+#define BLSP1_UART1_SIM_CBCR 0x0688
+#define BLSP1_UART1_APPS_CMD_RCGR 0x068C
+#define BLSP1_QUP2_BCR 0x06C0
+#define BLSP1_QUP2_SPI_APPS_CBCR 0x06C4
+#define BLSP1_QUP2_I2C_APPS_CBCR 0x06C8
+#define BLSP1_QUP2_SPI_APPS_CMD_RCGR 0x06CC
+#define BLSP1_UART2_BCR 0x0700
+#define BLSP1_UART2_APPS_CBCR 0x0704
+#define BLSP1_UART2_SIM_CBCR 0x0708
+#define BLSP1_UART2_APPS_CMD_RCGR 0x070C
+#define BLSP1_QUP3_BCR 0x0740
+#define BLSP1_QUP3_SPI_APPS_CBCR 0x0744
+#define BLSP1_QUP3_I2C_APPS_CBCR 0x0748
+#define BLSP1_QUP3_SPI_APPS_CMD_RCGR 0x074C
+#define BLSP1_UART3_BCR 0x0780
+#define BLSP1_UART3_APPS_CBCR 0x0784
+#define BLSP1_UART3_SIM_CBCR 0x0788
+#define BLSP1_UART3_APPS_CMD_RCGR 0x078C
+#define BLSP1_QUP4_BCR 0x07C0
+#define BLSP1_QUP4_SPI_APPS_CBCR 0x07C4
+#define BLSP1_QUP4_I2C_APPS_CBCR 0x07C8
+#define BLSP1_QUP4_SPI_APPS_CMD_RCGR 0x07CC
+#define BLSP1_UART4_BCR 0x0800
+#define BLSP1_UART4_APPS_CBCR 0x0804
+#define BLSP1_UART4_SIM_CBCR 0x0808
+#define BLSP1_UART4_APPS_CMD_RCGR 0x080C
+#define BLSP1_QUP5_BCR 0x0840
+#define BLSP1_QUP5_SPI_APPS_CBCR 0x0844
+#define BLSP1_QUP5_I2C_APPS_CBCR 0x0848
+#define BLSP1_QUP5_SPI_APPS_CMD_RCGR 0x084C
+#define BLSP1_UART5_BCR 0x0880
+#define BLSP1_UART5_APPS_CBCR 0x0884
+#define BLSP1_UART5_SIM_CBCR 0x0888
+#define BLSP1_UART5_APPS_CMD_RCGR 0x088C
+#define BLSP1_QUP6_BCR 0x08C0
+#define BLSP1_QUP6_SPI_APPS_CBCR 0x08C4
+#define BLSP1_QUP6_I2C_APPS_CBCR 0x08C8
+#define BLSP1_QUP6_SPI_APPS_CMD_RCGR 0x08CC
+#define BLSP1_UART6_BCR 0x0900
+#define BLSP1_UART6_APPS_CBCR 0x0904
+#define BLSP1_UART6_SIM_CBCR 0x0908
+#define BLSP1_UART6_APPS_CMD_RCGR 0x090C
+#define PDM_BCR 0x0CC0
+#define PDM_AHB_CBCR 0x0CC4
+#define PDM2_CBCR 0x0CCC
+#define PDM2_CMD_RCGR 0x0CD0
+#define PRNG_BCR 0x0D00
+#define PRNG_AHB_CBCR 0x0D04
+#define BOOT_ROM_BCR 0x0E00
+#define BOOT_ROM_AHB_CBCR 0x0E04
+#define CE1_BCR 0x1040
+#define CE1_CMD_RCGR 0x1050
+#define CE1_CBCR 0x1044
+#define CE1_AXI_CBCR 0x1048
+#define CE1_AHB_CBCR 0x104C
+#define COPSS_SMMU_AHB_CBCR 0x015C
+#define LPSS_SMMU_AHB_CBCR 0x0158
+#define LPASS_Q6_AXI_CBCR 0x11C0
+#define APCS_GPLL_ENA_VOTE 0x1480
+#define APCS_CLOCK_BRANCH_ENA_VOTE 0x1484
+#define APCS_CLOCK_SLEEP_ENA_VOTE 0x1488
+#define GP1_CBCR 0x1900
+#define GP1_CMD_RCGR 0x1904
+#define GP2_CBCR 0x1940
+#define GP2_CMD_RCGR 0x1944
+#define GP3_CBCR 0x1980
+#define GP3_CMD_RCGR 0x1984
+#define XO_CBCR 0x0034
+
+#define MMPLL0_PLL_MODE 0x0000
+#define MMPLL0_PLL_L_VAL 0x0004
+#define MMPLL0_PLL_M_VAL 0x0008
+#define MMPLL0_PLL_N_VAL 0x000C
+#define MMPLL0_PLL_USER_CTL 0x0010
+#define MMPLL0_PLL_STATUS 0x001C
+#define MMSS_PLL_VOTE_APCS_REG 0x0100
+#define MMPLL1_PLL_MODE 0x4100
+#define MMPLL1_PLL_L_VAL 0x4104
+#define MMPLL1_PLL_M_VAL 0x4108
+#define MMPLL1_PLL_N_VAL 0x410C
+#define MMPLL1_PLL_USER_CTL 0x4110
+#define MMPLL1_PLL_STATUS 0x411C
+#define DSI_PCLK_CMD_RCGR 0x2000
+#define DSI_CMD_RCGR 0x2020
+#define MDP_VSYNC_CMD_RCGR 0x2080
+#define DSI_BYTE_CMD_RCGR 0x2120
+#define DSI_ESC_CMD_RCGR 0x2160
+#define DSI_BCR 0x2200
+#define DSI_BYTE_BCR 0x2204
+#define DSI_ESC_BCR 0x2208
+#define DSI_AHB_BCR 0x220C
+#define DSI_PCLK_BCR 0x2214
+#define MDP_LCDC_BCR 0x2218
+#define MDP_DSI_BCR 0x221C
+#define MDP_VSYNC_BCR 0x2220
+#define MDP_AXI_BCR 0x2224
+#define MDP_AHB_BCR 0x2228
+#define MDP_AXI_CBCR 0x2314
+#define MDP_VSYNC_CBCR 0x231C
+#define MDP_AHB_CBCR 0x2318
+#define DSI_PCLK_CBCR 0x233C
+#define GMEM_GFX3D_CBCR 0x4038
+#define MDP_LCDC_CBCR 0x2340
+#define MDP_DSI_CBCR 0x2320
+#define DSI_CBCR 0x2324
+#define DSI_BYTE_CBCR 0x2328
+#define DSI_ESC_CBCR 0x232C
+#define DSI_AHB_CBCR 0x2330
+#define CSI0PHYTIMER_CMD_RCGR 0x3000
+#define CSI0PHYTIMER_BCR 0x3020
+#define CSI0PHYTIMER_CBCR 0x3024
+#define CSI1PHYTIMER_CMD_RCGR 0x3030
+#define CSI1PHYTIMER_BCR 0x3050
+#define CSI1PHYTIMER_CBCR 0x3054
+#define CSI0_CMD_RCGR 0x3090
+#define CSI0_BCR 0x30B0
+#define CSI0_CBCR 0x30B4
+#define CSI_AHB_BCR 0x30B8
+#define CSI_AHB_CBCR 0x30BC
+#define CSI0PHY_BCR 0x30C0
+#define CSI0PHY_CBCR 0x30C4
+#define CSI0RDI_BCR 0x30D0
+#define CSI0RDI_CBCR 0x30D4
+#define CSI0PIX_BCR 0x30E0
+#define CSI0PIX_CBCR 0x30E4
+#define CSI1_CMD_RCGR 0x3100
+#define CSI1_BCR 0x3120
+#define CSI1_CBCR 0x3124
+#define CSI1PHY_BCR 0x3130
+#define CSI1PHY_CBCR 0x3134
+#define CSI1RDI_BCR 0x3140
+#define CSI1RDI_CBCR 0x3144
+#define CSI1PIX_BCR 0x3150
+#define CSI1PIX_CBCR 0x3154
+#define MCLK0_CMD_RCGR 0x3360
+#define MCLK0_BCR 0x3380
+#define MCLK0_CBCR 0x3384
+#define MCLK1_CMD_RCGR 0x3390
+#define MCLK1_BCR 0x33B0
+#define MCLK1_CBCR 0x33B4
+#define VFE_CMD_RCGR 0x3600
+#define VFE_BCR 0x36A0
+#define VFE_AHB_BCR 0x36AC
+#define VFE_AXI_BCR 0x36B0
+#define VFE_CBCR 0x36A8
+#define VFE_AHB_CBCR 0x36B8
+#define VFE_AXI_CBCR 0x36BC
+#define CSI_VFE_BCR 0x3700
+#define CSI_VFE_CBCR 0x3704
+#define GFX3D_CMD_RCGR 0x4000
+#define OXILI_GFX3D_CBCR 0x4028
+#define OXILI_GFX3D_BCR 0x4030
+#define OXILI_AHB_BCR 0x4044
+#define OXILI_AHB_CBCR 0x403C
+#define AHB_CMD_RCGR 0x5000
+#define MMSSNOCAHB_BCR 0x5020
+#define MMSSNOCAHB_BTO_BCR 0x5030
+#define MMSS_MISC_AHB_BCR 0x5034
+#define MMSS_MMSSNOC_AHB_CBCR 0x5024
+#define MMSS_MMSSNOC_BTO_AHB_CBCR 0x5028
+#define MMSS_MISC_AHB_CBCR 0x502C
+#define AXI_CMD_RCGR 0x5040
+#define MMSSNOCAXI_BCR 0x5060
+#define MMSS_S0_AXI_BCR 0x5068
+#define MMSS_S0_AXI_CBCR 0x5064
+#define MMSS_MMSSNOC_AXI_CBCR 0x506C
+#define BIMC_GFX_BCR 0x5090
+#define BIMC_GFX_CBCR 0x5094
+
+#define AUDIO_CORE_GDSCR 0x7000
+#define SPDM_BCR 0x1000
+#define LPAAUDIO_PLL_MODE 0x0000
+#define LPAAUDIO_PLL_L_VAL 0x0004
+#define LPAAUDIO_PLL_M_VAL 0x0008
+#define LPAAUDIO_PLL_N_VAL 0x000C
+#define LPAAUDIO_PLL_USER_CTL 0x0010
+#define LPAAUDIO_PLL_STATUS 0x001C
+#define LPAQ6_PLL_MODE 0x1000
+#define LPAQ6_PLL_USER_CTL 0x1010
+#define LPAQ6_PLL_STATUS 0x101C
+#define LPA_PLL_VOTE_APPS 0x2000
+#define AUDIO_CORE_BCR_SLP_CBCR 0x4004
+#define Q6SS_BCR_SLP_CBCR 0x6004
+#define AUDIO_CORE_GDSC_XO_CBCR 0x7004
+#define AUDIO_CORE_LPAIF_DMA_CBCR 0x9000
+#define AUDIO_CORE_LPAIF_CSR_CBCR 0x9004
+#define LPAIF_SPKR_CMD_RCGR 0xA000
+#define AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR 0xA014
+#define AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR 0xA018
+#define AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR 0xA01C
+#define LPAIF_PRI_CMD_RCGR 0xB000
+#define AUDIO_CORE_LPAIF_PRI_OSR_CBCR 0xB014
+#define AUDIO_CORE_LPAIF_PRI_IBIT_CBCR 0xB018
+#define AUDIO_CORE_LPAIF_PRI_EBIT_CBCR 0xB01C
+#define LPAIF_SEC_CMD_RCGR 0xC000
+#define AUDIO_CORE_LPAIF_SEC_OSR_CBCR 0xC014
+#define AUDIO_CORE_LPAIF_SEC_IBIT_CBCR 0xC018
+#define AUDIO_CORE_LPAIF_SEC_EBIT_CBCR 0xC01C
+#define LPAIF_TER_CMD_RCGR 0xD000
+#define AUDIO_CORE_LPAIF_TER_OSR_CBCR 0xD014
+#define AUDIO_CORE_LPAIF_TER_IBIT_CBCR 0xD018
+#define AUDIO_CORE_LPAIF_TER_EBIT_CBCR 0xD01C
+#define LPAIF_QUAD_CMD_RCGR 0xE000
+#define AUDIO_CORE_LPAIF_QUAD_OSR_CBCR 0xE014
+#define AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR 0xE018
+#define AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR 0xE01C
+#define LPAIF_PCM0_CMD_RCGR 0xF000
+#define AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR 0xF014
+#define AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR 0xF018
+#define LPAIF_PCM1_CMD_RCGR 0x10000
+#define AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR 0x10014
+#define AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR 0x10018
+#define SLIMBUS_CMD_RCGR 0x12000
+#define AUDIO_CORE_SLIMBUS_CORE_CBCR 0x12014
+#define LPAIF_PCMOE_CMD_RCGR 0x13000
+#define AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR 0x13014
+#define Q6CORE_CMD_RCGR 0x14000
+#define SLEEP_CMD_RCGR 0x15000
+#define SPDM_CMD_RCGR 0x16000
+#define AUDIO_WRAPPER_SPDM_CBCR 0x16014
+#define XO_CMD_RCGR 0x17000
+#define AHBFABRIC_CMD_RCGR 0x18000
+#define AUDIO_CORE_LPM_CBCR 0x19000
+#define AUDIO_CORE_AVSYNC_CSR_CBCR 0x1A000
+#define AUDIO_CORE_AVSYNC_XO_CBCR 0x1A004
+#define AUDIO_CORE_AVSYNC_BT_XO_CBCR 0x1A008
+#define AUDIO_CORE_AVSYNC_FM_XO_CBCR 0x1A00C
+#define AUDIO_CORE_IXFABRIC_CBCR 0x1B000
+#define AUDIO_WRAPPER_EFABRIC_CBCR 0x1B004
+#define AUDIO_CORE_TCM_SLAVE_CBCR 0x1C000
+#define AUDIO_CORE_CSR_CBCR 0x1D000
+#define AUDIO_CORE_DML_CBCR 0x1E000
+#define AUDIO_CORE_SYSNOC_CBCR 0x1F000
+#define AUDIO_WRAPPER_SYSNOC_SWAY_CBCR 0x1F004
+#define AUDIO_CORE_TIMEOUT_CBCR 0x20000
+#define AUDIO_WRAPPER_TIMEOUT_CBCR 0x20004
+#define AUDIO_CORE_SECURITY_CBCR 0x21000
+#define AUDIO_WRAPPER_SECURITY_CBCR 0x21004
+#define Q6SS_AHB_LFABIF_CBCR 0x22000
+#define Q6SS_AHBM_CBCR 0x22004
+#define AUDIO_WRAPPER_LCC_CSR_CBCR 0x23000
+#define AUDIO_WRAPPER_BR_CBCR 0x24000
+#define AUDIO_WRAPPER_SMEM_CBCR 0x25000
+#define Q6SS_XO_CBCR 0x26000
+#define Q6SS_SLP_CBCR 0x26004
+#define LPASS_Q6SS_BCR 0x6000
+#define AUDIO_WRAPPER_STM_XO_CBCR 0x27000
+#define AUDIO_CORE_IXFABRIC_SPDMTM_CSR_CBCR 0x28000
+#define AUDIO_WRAPPER_EFABRIC_SPDMTM_CSR_CBCR 0x28004
+
+/* Mux source select values */
+#define gcc_xo_source_val 0
+#define gpll0_source_val 1
+#define gnd_source_val 5
+#define mmpll0_mm_source_val 1
+#define mmpll1_mm_source_val 2
+#define gpll0_mm_source_val 5
+#define gcc_xo_mm_source_val 0
+#define mm_gnd_source_val 6
+#define cxo_lpass_source_val 0
+#define lpapll0_lpass_source_val 1
+#define gpll0_lpass_source_val 5
+#define dsipll_mm_source_val 1
+
+#define F(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s##_clk_src.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_source_val), \
+ }
+
+#define F_MM(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s##_clk_src.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_mm_source_val), \
+ }
+
+#define F_HDMI(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s##_clk_src, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_mm_source_val), \
+ }
+
+#define F_MDSS(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_mm_source_val), \
+ }
+
+#define F_LPASS(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s##_clk_src.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_lpass_source_val), \
+ }
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ [VDD_DIG_##l3] = (f3), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+ VDD_DIG_NONE,
+ VDD_DIG_LOW,
+ VDD_DIG_NOMINAL,
+ VDD_DIG_HIGH,
+ VDD_DIG_NUM
+};
+
+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)
+{
+ 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, VDD_DIG_NUM);
+
+#define RPM_MISC_CLK_TYPE 0x306b6c63
+#define RPM_BUS_CLK_TYPE 0x316b6c63
+#define RPM_MEM_CLK_TYPE 0x326b6c63
+
+#define RPM_SMD_KEY_ENABLE 0x62616E45
+
+#define CXO_ID 0x0
+#define QDSS_ID 0x1
+#define RPM_SCALING_ENABLE_ID 0x2
+
+#define PNOC_ID 0x0
+#define SNOC_ID 0x1
+#define CNOC_ID 0x2
+#define MMSSNOC_AHB_ID 0x3
+
+#define BIMC_ID 0x0
+#define OXILI_ID 0x1
+#define OCMEM_ID 0x2
+
+#define D0_ID 1
+#define D1_ID 2
+#define A0_ID 3
+#define A1_ID 4
+#define A2_ID 5
+#define DIFF_CLK_ID 7
+#define DIV_CLK_ID 11
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+DEFINE_CLK_RPM_SMD(mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, RPM_BUS_CLK_TYPE,
+ MMSSNOC_AHB_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD_BRANCH(gcc_xo_clk_src, gcc_xo_a_clk_src,
+ RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d0, cxo_d0_a, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_d1, cxo_d1_a, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk, div_a_clk, DIV_CLK_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk, diff_a_clk, DIFF_CLK_ID);
+
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d1_pin, cxo_d1_a_pin, D1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a0_pin, cxo_a0_a_pin, A0_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a1_pin, cxo_a1_a_pin, A1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_a2_pin, cxo_a2_a_pin, A2_ID);
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_iommu_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_qseecom_clk, &pnoc_clk.c, LONG_MAX);
+
+static struct pll_vote_clk gpll0_clk_src = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)GPLL0_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .rate = 600000000,
+ .dbg_name = "gpll0_clk_src",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(gpll0_clk_src.c),
+ },
+};
+
+static struct pll_vote_clk mmpll0_clk_src = {
+ .en_reg = (void __iomem *)MMSS_PLL_VOTE_APCS_REG,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)MMPLL0_PLL_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "mmpll0_clk_src",
+ .rate = 800000000,
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(mmpll0_clk_src.c),
+ },
+};
+
+static struct pll_config_regs mmpll0_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL0_PLL_L_VAL,
+ .m_reg = (void __iomem *)MMPLL0_PLL_M_VAL,
+ .n_reg = (void __iomem *)MMPLL0_PLL_N_VAL,
+ .config_reg = (void __iomem *)MMPLL0_PLL_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL0_PLL_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+static struct pll_clk mmpll1_clk_src = {
+ .mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
+ .status_reg = (void __iomem *)MMPLL1_PLL_STATUS,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "mmpll1_clk_src",
+ .rate = 1200000000,
+ .ops = &clk_ops_local_pll,
+ CLK_INIT(mmpll1_clk_src.c),
+ },
+};
+
+static struct pll_config_regs mmpll1_regs __initdata = {
+ .l_reg = (void __iomem *)MMPLL1_PLL_L_VAL,
+ .m_reg = (void __iomem *)MMPLL1_PLL_M_VAL,
+ .n_reg = (void __iomem *)MMPLL1_PLL_N_VAL,
+ .config_reg = (void __iomem *)MMPLL1_PLL_USER_CTL,
+ .mode_reg = (void __iomem *)MMPLL1_PLL_MODE,
+ .base = &virt_bases[MMSS_BASE],
+};
+
+static struct pll_vote_clk lpapll0_clk_src = {
+ .en_reg = (void __iomem *)LPA_PLL_VOTE_APPS,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)LPAAUDIO_PLL_STATUS,
+ .status_mask = BIT(17),
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .rate = 491520000,
+ .dbg_name = "lpapll0_clk_src",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(lpapll0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+ F( 960000, gcc_xo, 10, 1, 2),
+ F( 4800000, gcc_xo, 4, 0, 0),
+ F( 9600000, gcc_xo, 2, 0, 0),
+ F(15000000, gpll0, 10, 1, 4),
+ F(19200000, gcc_xo, 1, 0, 0),
+ F(25000000, gpll0, 12, 1, 2),
+ F(50000000, gpll0, 12, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup1_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup2_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup3_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup4_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup5_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP6_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup6_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+ F( 3686400, gpll0, 1, 96, 15625),
+ F( 7372800, gpll0, 1, 192, 15625),
+ F(14745600, gpll0, 1, 384, 15625),
+ F(16000000, gpll0, 5, 2, 15),
+ F(19200000, gcc_xo, 1, 0, 0),
+ F(24000000, gpll0, 5, 1, 5),
+ F(32000000, gpll0, 1, 4, 75),
+ F(40000000, gpll0, 15, 0, 0),
+ F(46400000, gpll0, 1, 29, 375),
+ F(48000000, gpll0, 12.5, 0, 0),
+ F(51200000, gpll0, 1, 32, 375),
+ F(56000000, gpll0, 1, 7, 75),
+ F(58982400, gpll0, 1, 1536, 15625),
+ F(60000000, gpll0, 10, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart3_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart4_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart4_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart5_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART5_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart5_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart5_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart6_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART6_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart6_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart6_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+ F(50000000, gpll0, 12, 0, 0),
+ F(100000000, gpll0, 6, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk ce1_clk_src = {
+ .cmd_rcgr_reg = CE1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "ce1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+ CLK_INIT(ce1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_gp1_3_clk[] = {
+ F(19200000, gcc_xo, 1, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk gp1_clk_src = {
+ .cmd_rcgr_reg = GP1_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gp1_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(gp1_clk_src.c),
+ },
+};
+
+static struct rcg_clk gp2_clk_src = {
+ .cmd_rcgr_reg = GP2_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gp2_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(gp2_clk_src.c),
+ },
+};
+
+static struct rcg_clk gp3_clk_src = {
+ .cmd_rcgr_reg = GP3_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_gp1_3_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gp3_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(gp3_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+ F(60000000, gpll0, 10, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk pdm2_clk_src = {
+ .cmd_rcgr_reg = PDM2_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_pdm2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "pdm2_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 120000000),
+ CLK_INIT(pdm2_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] = {
+ F( 144000, gcc_xo, 16, 3, 25),
+ F( 400000, gcc_xo, 12, 1, 4),
+ F( 20000000, gpll0, 15, 1, 2),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F(100000000, gpll0, 6, 0, 0),
+ F(200000000, gpll0, 3, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk sdcc1_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(sdcc1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(sdcc2_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+ F(75000000, gpll0, 8, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+ .cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hs_system_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 100000000),
+ CLK_INIT(usb_hs_system_clk_src.c),
+ },
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = BLSP1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(17),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_blsp1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup1_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup2_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup3_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup4_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup5_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_qup6_spi_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+ .cbcr_reg = BLSP1_UART1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart1_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart1_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+ .cbcr_reg = BLSP1_UART2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart2_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart2_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+ .cbcr_reg = BLSP1_UART3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart3_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart3_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+ .cbcr_reg = BLSP1_UART4_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart4_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart4_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart5_apps_clk = {
+ .cbcr_reg = BLSP1_UART5_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart5_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart5_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart6_apps_clk = {
+ .cbcr_reg = BLSP1_UART6_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &blsp1_uart6_apps_clk_src.c,
+ .dbg_name = "gcc_blsp1_uart6_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+ .cbcr_reg = BOOT_ROM_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(10),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_boot_rom_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_boot_rom_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+ .cbcr_reg = CE1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(3),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+ .cbcr_reg = CE1_AXI_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(4),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_axi_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_axi_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+ .cbcr_reg = CE1_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(5),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_clk.c),
+ },
+};
+
+static struct branch_clk gcc_copss_smmu_ahb_clk = {
+ .cbcr_reg = COPSS_SMMU_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_copss_smmu_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_copss_smmu_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpss_smmu_ahb_clk = {
+ .cbcr_reg = LPSS_SMMU_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpss_smmu_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpss_smmu_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_gp1_clk = {
+ .cbcr_reg = GP1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gp1_clk_src.c,
+ .dbg_name = "gcc_gp1_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_gp1_clk.c),
+ },
+};
+
+static struct branch_clk gcc_gp2_clk = {
+ .cbcr_reg = GP2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gp2_clk_src.c,
+ .dbg_name = "gcc_gp2_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_gp2_clk.c),
+ },
+};
+
+static struct branch_clk gcc_gp3_clk = {
+ .cbcr_reg = GP3_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &gp3_clk_src.c,
+ .dbg_name = "gcc_gp3_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_gp3_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+ .cbcr_reg = LPASS_Q6_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpass_q6_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpass_q6_axi_clk.c),
+ },
+};
+
+static 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),
+ },
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+ .cbcr_reg = MSS_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+ .cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_q6_bimc_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+ .cbcr_reg = PDM2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &pdm2_clk_src.c,
+ .dbg_name = "gcc_pdm2_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm2_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+ .cbcr_reg = PDM_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pdm_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+ .cbcr_reg = PRNG_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(13),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_prng_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_prng_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_ahb_clk = {
+ .cbcr_reg = SDCC1_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc1_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk = {
+ .cbcr_reg = SDCC1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &sdcc1_apps_clk_src.c,
+ .dbg_name = "gcc_sdcc1_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+ .cbcr_reg = SDCC2_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc2_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+ .cbcr_reg = SDCC2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &sdcc2_apps_clk_src.c,
+ .dbg_name = "gcc_sdcc2_apps_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb2a_phy_sleep_clk = {
+ .cbcr_reg = USB2A_PHY_SLEEP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb2a_phy_sleep_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+ .cbcr_reg = USB_HS_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+ .cbcr_reg = USB_HS_SYSTEM_CBCR,
+ .has_sibling = 0,
+ .bcr_reg = USB_HS_BCR,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .parent = &usb_hs_system_clk_src.c,
+ .dbg_name = "gcc_usb_hs_system_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_system_clk.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_csi0_1_clk[] = {
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(200000000, mmpll0, 4, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk csi0_clk_src = {
+ .cmd_rcgr_reg = CSI0_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_csi0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi0_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi0_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mmss_mmssnoc_ahb_clk[] = {
+ F_MM(19200000, gcc_xo, 1, 0, 0),
+ F_MM(40000000, gpll0, 15, 0, 0),
+ F_MM(80000000, mmpll0, 10, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk ahb_clk_src = {
+ .cmd_rcgr_reg = AHB_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mmss_mmssnoc_ahb_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "ahb_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 40000000, NOMINAL, 80000000),
+ CLK_INIT(ahb_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mmss_mmssnoc_axi_clk[] = {
+ F_MM( 19200000, gcc_xo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(150000000, gpll0, 4, 0, 0),
+ F_MM(200000000, mmpll0, 4, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk axi_clk_src = {
+ .cmd_rcgr_reg = AXI_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mmss_mmssnoc_axi_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "axi_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(axi_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_dsi_pclk_clk[] = {
+ F_MDSS( 50000000, dsipll, 10, 0, 0),
+ F_MDSS(103330000, dsipll, 9, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk dsi_pclk_clk_src = {
+ .cmd_rcgr_reg = DSI_PCLK_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_dsi_pclk_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "dsi_pclk_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 103330000),
+ CLK_INIT(dsi_pclk_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_oxili_gfx3d_clk[] = {
+ F_MM( 19200000, gcc_xo, 1, 0, 0),
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 75000000, gpll0, 8, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(150000000, gpll0, 4, 0, 0),
+ F_MM(200000000, gpll0, 3, 0, 0),
+ F_MM(300000000, gpll0, 2, 0, 0),
+ F_MM(400000000, mmpll1, 3, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk gfx3d_clk_src = {
+ .cmd_rcgr_reg = GFX3D_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_oxili_gfx3d_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "gfx3d_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 150000000, NOMINAL, 300000000, HIGH,
+ 400000000),
+ CLK_INIT(gfx3d_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_vfe_clk[] = {
+ F_MM( 37500000, gpll0, 16, 0, 0),
+ F_MM( 50000000, gpll0, 12, 0, 0),
+ F_MM( 60000000, gpll0, 10, 0, 0),
+ F_MM( 80000000, gpll0, 7.5, 0, 0),
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(109090000, gpll0, 5.5, 0, 0),
+ F_MM(133330000, gpll0, 4.5, 0, 0),
+ F_MM(200000000, gpll0, 3, 0, 0),
+ F_MM(228570000, mmpll0, 3.5, 0, 0),
+ F_MM(266670000, mmpll0, 3, 0, 0),
+ F_MM(320000000, mmpll0, 2.5, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk vfe_clk_src = {
+ .cmd_rcgr_reg = VFE_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_vfe_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vfe_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 133330000, NOMINAL, 266670000, HIGH,
+ 320000000),
+ CLK_INIT(vfe_clk_src.c),
+ },
+};
+
+static struct rcg_clk csi1_clk_src = {
+ .cmd_rcgr_reg = CSI1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_csi0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_csi0_1phytimer_clk[] = {
+ F_MM(100000000, gpll0, 6, 0, 0),
+ F_MM(200000000, mmpll0, 4, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk csi0phytimer_clk_src = {
+ .cmd_rcgr_reg = CSI0PHYTIMER_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_csi0_1phytimer_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi0phytimer_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi0phytimer_clk_src.c),
+ },
+};
+
+static struct rcg_clk csi1phytimer_clk_src = {
+ .cmd_rcgr_reg = CSI1PHYTIMER_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_csi0_1phytimer_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi1phytimer_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(csi1phytimer_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_dsi_clk[] = {
+ F_MDSS(155000000, dsipll, 6, 0, 0),
+ F_MDSS(310000000, dsipll, 3, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk dsi_clk_src = {
+ .cmd_rcgr_reg = DSI_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_dsi_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "dsi_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 155000000, NOMINAL, 310000000),
+ CLK_INIT(dsi_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_dsi_byte_clk[] = {
+ F_MDSS( 62500000, dsipll, 12, 0, 0),
+ F_MDSS(125000000, dsipll, 6, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk dsi_byte_clk_src = {
+ .cmd_rcgr_reg = DSI_BYTE_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_dsi_byte_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "dsi_byte_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
+ CLK_INIT(dsi_byte_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_dsi_esc_clk[] = {
+ F_MM(19200000, gcc_xo, 1, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk dsi_esc_clk_src = {
+ .cmd_rcgr_reg = DSI_ESC_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_dsi_esc_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "dsi_esc_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(dsi_esc_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mclk0_1_clk[] = {
+ F_MM(66670000, gpll0, 9, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk mclk0_clk_src = {
+ .cmd_rcgr_reg = MCLK0_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_mclk0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mclk0_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 66670000),
+ CLK_INIT(mclk0_clk_src.c),
+ },
+};
+
+static struct rcg_clk mclk1_clk_src = {
+ .cmd_rcgr_reg = MCLK1_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_mclk0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mclk1_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 66670000),
+ CLK_INIT(mclk1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdp_vsync_clk[] = {
+ F_MM(19200000, gcc_xo, 1, 0, 0),
+ F_END,
+};
+
+static struct rcg_clk mdp_vsync_clk_src = {
+ .cmd_rcgr_reg = MDP_VSYNC_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_mdp_vsync_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdp_vsync_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(mdp_vsync_clk_src.c),
+ },
+};
+
+static struct branch_clk bimc_gfx_clk = {
+ .cbcr_reg = BIMC_GFX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "bimc_gfx_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(bimc_gfx_clk.c),
+ },
+};
+
+static struct branch_clk csi0_clk = {
+ .cbcr_reg = CSI0_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi0_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi0_clk.c),
+ },
+};
+
+static struct branch_clk csi0phy_clk = {
+ .cbcr_reg = CSI0PHY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi0phy_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi0phy_clk.c),
+ },
+};
+
+static struct branch_clk csi0phytimer_clk = {
+ .cbcr_reg = CSI0PHYTIMER_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0phytimer_clk_src.c,
+ .dbg_name = "csi0phytimer_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi0phytimer_clk.c),
+ },
+};
+
+static struct branch_clk csi0pix_clk = {
+ .cbcr_reg = CSI0PIX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi0pix_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi0pix_clk.c),
+ },
+};
+
+static struct branch_clk csi0rdi_clk = {
+ .cbcr_reg = CSI0RDI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi0rdi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi0rdi_clk.c),
+ },
+};
+
+static struct branch_clk csi1_clk = {
+ .cbcr_reg = CSI1_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi1_clk_src.c,
+ .dbg_name = "csi1_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi1_clk.c),
+ },
+};
+
+static struct branch_clk csi1phy_clk = {
+ .cbcr_reg = CSI1PHY_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi1_clk_src.c,
+ .dbg_name = "csi1phy_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi1phy_clk.c),
+ },
+};
+
+static struct branch_clk csi1phytimer_clk = {
+ .cbcr_reg = CSI1PHYTIMER_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi1phytimer_clk_src.c,
+ .dbg_name = "csi1phytimer_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi1phytimer_clk.c),
+ },
+};
+
+static struct branch_clk csi1pix_clk = {
+ .cbcr_reg = CSI1PIX_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi1pix_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi1pix_clk.c),
+ },
+};
+
+static struct branch_clk csi1rdi_clk = {
+ .cbcr_reg = CSI1RDI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &csi0_clk_src.c,
+ .dbg_name = "csi1rdi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi1rdi_clk.c),
+ },
+};
+
+static struct branch_clk csi_ahb_clk = {
+ .cbcr_reg = CSI_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "csi_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi_ahb_clk.c),
+ },
+};
+
+static struct branch_clk csi_vfe_clk = {
+ .cbcr_reg = CSI_VFE_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &vfe_clk_src.c,
+ .dbg_name = "csi_vfe_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(csi_vfe_clk.c),
+ },
+};
+
+static struct branch_clk dsi_clk = {
+ .cbcr_reg = DSI_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_clk_src.c,
+ .dbg_name = "dsi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(dsi_clk.c),
+ },
+};
+
+static struct branch_clk dsi_ahb_clk = {
+ .cbcr_reg = DSI_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "dsi_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(dsi_ahb_clk.c),
+ },
+};
+
+static struct branch_clk dsi_byte_clk = {
+ .cbcr_reg = DSI_BYTE_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_byte_clk_src.c,
+ .dbg_name = "dsi_byte_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(dsi_byte_clk.c),
+ },
+};
+
+static struct branch_clk dsi_esc_clk = {
+ .cbcr_reg = DSI_ESC_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_esc_clk_src.c,
+ .dbg_name = "dsi_esc_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(dsi_esc_clk.c),
+ },
+};
+
+static struct branch_clk dsi_pclk_clk = {
+ .cbcr_reg = DSI_PCLK_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_pclk_clk_src.c,
+ .dbg_name = "dsi_pclk_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(dsi_pclk_clk.c),
+ },
+};
+
+static struct branch_clk gmem_gfx3d_clk = {
+ .cbcr_reg = GMEM_GFX3D_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &gfx3d_clk_src.c,
+ .dbg_name = "gmem_gfx3d_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gmem_gfx3d_clk.c),
+ },
+};
+
+static struct branch_clk mclk0_clk = {
+ .cbcr_reg = MCLK0_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &mclk0_clk_src.c,
+ .dbg_name = "mclk0_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mclk0_clk.c),
+ },
+};
+
+static struct branch_clk mclk1_clk = {
+ .cbcr_reg = MCLK1_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &mclk1_clk_src.c,
+ .dbg_name = "mclk1_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mclk1_clk.c),
+ },
+};
+
+static struct branch_clk mdp_ahb_clk = {
+ .cbcr_reg = MDP_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mdp_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdp_ahb_clk.c),
+ },
+};
+
+static struct branch_clk mdp_axi_clk = {
+ .cbcr_reg = MDP_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &axi_clk_src.c,
+ .dbg_name = "mdp_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdp_axi_clk.c),
+ },
+};
+
+static struct branch_clk mdp_dsi_clk = {
+ .cbcr_reg = MDP_DSI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_pclk_clk_src.c,
+ .dbg_name = "mdp_dsi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdp_dsi_clk.c),
+ },
+};
+
+static struct branch_clk mdp_lcdc_clk = {
+ .cbcr_reg = MDP_LCDC_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &dsi_pclk_clk_src.c,
+ .dbg_name = "mdp_lcdc_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdp_lcdc_clk.c),
+ },
+};
+
+static struct branch_clk mdp_vsync_clk = {
+ .cbcr_reg = MDP_VSYNC_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &mdp_vsync_clk_src.c,
+ .dbg_name = "mdp_vsync_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mdp_vsync_clk.c),
+ },
+};
+
+static struct branch_clk mmss_misc_ahb_clk = {
+ .cbcr_reg = MMSS_MISC_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_misc_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_misc_ahb_clk.c),
+ },
+};
+
+static struct branch_clk mmss_mmssnoc_axi_clk = {
+ .cbcr_reg = MMSS_MMSSNOC_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &axi_clk_src.c,
+ .dbg_name = "mmss_mmssnoc_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_mmssnoc_axi_clk.c),
+ },
+};
+
+static struct branch_clk mmss_s0_axi_clk = {
+ .cbcr_reg = MMSS_S0_AXI_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &axi_clk_src.c,
+ .dbg_name = "mmss_s0_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_s0_axi_clk.c),
+ .depends = &mmss_mmssnoc_axi_clk.c,
+ },
+};
+
+static struct branch_clk mmss_mmssnoc_ahb_clk = {
+ .cbcr_reg = MMSS_MMSSNOC_AHB_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &ahb_clk_src.c,
+ .dbg_name = "mmss_mmssnoc_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_mmssnoc_ahb_clk.c),
+ },
+};
+
+static struct branch_clk mmss_mmssnoc_bto_ahb_clk = {
+ .cbcr_reg = MMSS_MMSSNOC_BTO_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "mmss_mmssnoc_bto_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(mmss_mmssnoc_bto_ahb_clk.c),
+ },
+};
+
+static struct branch_clk oxili_ahb_clk = {
+ .cbcr_reg = OXILI_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "oxili_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(oxili_ahb_clk.c),
+ },
+};
+
+static struct branch_clk oxili_gfx3d_clk = {
+ .cbcr_reg = OXILI_GFX3D_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &gfx3d_clk_src.c,
+ .dbg_name = "oxili_gfx3d_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(oxili_gfx3d_clk.c),
+ },
+};
+
+static struct branch_clk vfe_clk = {
+ .cbcr_reg = VFE_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &vfe_clk_src.c,
+ .dbg_name = "vfe_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(vfe_clk.c),
+ },
+};
+
+static struct branch_clk vfe_ahb_clk = {
+ .cbcr_reg = VFE_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .dbg_name = "vfe_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(vfe_ahb_clk.c),
+ },
+};
+
+static struct branch_clk vfe_axi_clk = {
+ .cbcr_reg = VFE_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[MMSS_BASE],
+ .c = {
+ .parent = &axi_clk_src.c,
+ .dbg_name = "vfe_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(vfe_axi_clk.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_audio_core_lpaif_clk[] = {
+ F_LPASS( 512000, lpapll0, 16, 1, 60),
+ F_LPASS( 768000, lpapll0, 16, 1, 40),
+ F_LPASS( 1024000, lpapll0, 16, 1, 30),
+ F_LPASS( 1536000, lpapll0, 16, 1, 20),
+ F_LPASS( 2048000, lpapll0, 16, 1, 15),
+ F_LPASS( 3072000, lpapll0, 16, 1, 10),
+ F_LPASS( 4096000, lpapll0, 15, 1, 8),
+ F_LPASS( 6144000, lpapll0, 10, 1, 8),
+ F_LPASS( 8192000, lpapll0, 15, 1, 4),
+ F_LPASS(12288000, lpapll0, 10, 1, 4),
+ F_END,
+};
+
+static struct rcg_clk lpaif_pri_clk_src = {
+ .cmd_rcgr_reg = LPAIF_PRI_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_pri_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+ CLK_INIT(lpaif_pri_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_quad_clk_src = {
+ .cmd_rcgr_reg = LPAIF_QUAD_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_quad_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+ CLK_INIT(lpaif_quad_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_sec_clk_src = {
+ .cmd_rcgr_reg = LPAIF_SEC_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_sec_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+ CLK_INIT(lpaif_sec_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_spkr_clk_src = {
+ .cmd_rcgr_reg = LPAIF_SPKR_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_spkr_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+ CLK_INIT(lpaif_spkr_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_ter_clk_src = {
+ .cmd_rcgr_reg = LPAIF_TER_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_ter_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12290000, NOMINAL, 24580000),
+ CLK_INIT(lpaif_ter_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_audio_core_lpaif_pcm0_1_clk[] = {
+ F_LPASS( 512000, lpapll0, 16, 1, 60),
+ F_LPASS( 768000, lpapll0, 16, 1, 40),
+ F_LPASS(1024000, lpapll0, 16, 1, 30),
+ F_LPASS(1536000, lpapll0, 16, 1, 20),
+ F_LPASS(2048000, lpapll0, 16, 1, 15),
+ F_LPASS(3072000, lpapll0, 16, 1, 10),
+ F_LPASS(4096000, lpapll0, 15, 1, 8),
+ F_LPASS(6144000, lpapll0, 10, 1, 8),
+ F_LPASS(8192000, lpapll0, 15, 1, 4),
+ F_END,
+};
+
+static struct rcg_clk lpaif_pcm0_clk_src = {
+ .cmd_rcgr_reg = LPAIF_PCM0_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_pcm0_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
+ CLK_INIT(lpaif_pcm0_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_pcm1_clk_src = {
+ .cmd_rcgr_reg = LPAIF_PCM1_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_pcm1_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 4100000, NOMINAL, 8192000),
+ CLK_INIT(lpaif_pcm1_clk_src.c),
+ },
+};
+
+static struct rcg_clk lpaif_pcmoe_clk_src = {
+ .cmd_rcgr_reg = LPAIF_PCMOE_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_lpaif_pcm0_1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "lpaif_pcmoe_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 6140000, NOMINAL, 12290000),
+ CLK_INIT(lpaif_pcmoe_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_audio_core_slimbus_core_clock[] = {
+ F_LPASS(24576000, lpapll0, 4, 1, 5),
+ F_END
+};
+
+static struct rcg_clk audio_core_slimbus_core_clk_src = {
+ .cmd_rcgr_reg = SLIMBUS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_audio_core_slimbus_core_clock,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_slimbus_core_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 12935000, NOMINAL, 25869000),
+ CLK_INIT(audio_core_slimbus_core_clk_src.c),
+ },
+};
+
+static struct branch_clk audio_core_slimbus_core_clk = {
+ .cbcr_reg = AUDIO_CORE_SLIMBUS_CORE_CBCR,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &audio_core_slimbus_core_clk_src.c,
+ .dbg_name = "audio_core_slimbus_core_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_slimbus_core_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_ixfabric_clk = {
+ .cbcr_reg = AUDIO_CORE_IXFABRIC_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_ixfabric_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_ixfabric_clk.c),
+ },
+};
+
+static struct branch_clk audio_wrapper_br_clk = {
+ .cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_wrapper_br_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_wrapper_br_clk.c),
+ },
+};
+
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+ .cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "q6ss_ahb_lfabif_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(q6ss_ahb_lfabif_clk.c),
+ },
+};
+
+static struct branch_clk q6ss_ahbm_clk = {
+ .cbcr_reg = Q6SS_AHBM_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "q6ss_ahbm_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(q6ss_ahbm_clk.c),
+ },
+};
+
+static struct branch_clk q6ss_xo_clk = {
+ .cbcr_reg = Q6SS_XO_CBCR,
+ .has_sibling = 1,
+ .bcr_reg = LPASS_Q6SS_BCR,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &gcc_xo_clk_src.c,
+ .dbg_name = "q6ss_xo_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(q6ss_xo_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pcm_data_oe_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PCM_DATA_OE_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_pcmoe_clk_src.c,
+ .dbg_name = "audio_core_lpaif_pcm_data_oe_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pcm_data_oe_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pri_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PRI_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_pri_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pri_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pri_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PRI_IBIT_CBCR,
+ .has_sibling = 0,
+ .max_div = 511,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_pri_clk_src.c,
+ .dbg_name = "audio_core_lpaif_pri_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pri_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pri_osr_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PRI_OSR_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_pri_clk_src.c,
+ .dbg_name = "audio_core_lpaif_pri_osr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pri_osr_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pcm0_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_pcm0_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pcm0_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pcm0_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PCM0_IBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_pcm0_clk_src.c,
+ .dbg_name = "audio_core_lpaif_pcm0_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pcm0_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_quad_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_quad_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_quad_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_quad_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_IBIT_CBCR,
+ .has_sibling = 0,
+ .max_div = 511,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_quad_clk_src.c,
+ .dbg_name = "audio_core_lpaif_quad_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_quad_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_quad_osr_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_QUAD_OSR_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_quad_clk_src.c,
+ .dbg_name = "audio_core_lpaif_quad_osr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_quad_osr_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_sec_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_SEC_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_sec_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_sec_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_sec_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_SEC_IBIT_CBCR,
+ .has_sibling = 0,
+ .max_div = 511,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_sec_clk_src.c,
+ .dbg_name = "audio_core_lpaif_sec_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_sec_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_sec_osr_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_SEC_OSR_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_sec_clk_src.c,
+ .dbg_name = "audio_core_lpaif_sec_osr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_sec_osr_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pcm1_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_pcm1_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pcm1_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_pcm1_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_PCM1_IBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_pcm1_clk_src.c,
+ .dbg_name = "audio_core_lpaif_pcm1_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_pcm1_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_codec_spkr_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_codec_spkr_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_IBIT_CBCR,
+ .has_sibling = 1,
+ .max_div = 511,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_spkr_clk_src.c,
+ .dbg_name = "audio_core_lpaif_codec_spkr_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_codec_spkr_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_codec_spkr_osr_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_CODEC_SPKR_OSR_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_spkr_clk_src.c,
+ .dbg_name = "audio_core_lpaif_codec_spkr_osr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_codec_spkr_osr_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_ter_ebit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_TER_EBIT_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "audio_core_lpaif_ter_ebit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_ter_ebit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_ter_ibit_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_TER_IBIT_CBCR,
+ .has_sibling = 0,
+ .max_div = 511,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_ter_clk_src.c,
+ .dbg_name = "audio_core_lpaif_ter_ibit_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_ter_ibit_clk.c),
+ },
+};
+
+static struct branch_clk audio_core_lpaif_ter_osr_clk = {
+ .cbcr_reg = AUDIO_CORE_LPAIF_TER_OSR_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .parent = &lpaif_ter_clk_src.c,
+ .dbg_name = "audio_core_lpaif_ter_osr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(audio_core_lpaif_ter_osr_clk.c),
+ },
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+struct measure_mux_entry {
+ struct clk *c;
+ int base;
+ u32 debug_mux;
+};
+
+static struct measure_mux_entry measure_mux[] = {
+ { &snoc_clk.c, GCC_BASE, 0x0000},
+ { &cnoc_clk.c, GCC_BASE, 0x0008},
+ { &gcc_copss_smmu_ahb_clk.c, GCC_BASE, 0x000c},
+ { &gcc_lpss_smmu_ahb_clk.c, GCC_BASE, 0x000d},
+ { &pnoc_clk.c, GCC_BASE, 0x0010},
+ { &gcc_mmss_noc_cfg_ahb_clk.c, GCC_BASE, 0x002a},
+ { &gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
+ { &gcc_mss_q6_bimc_axi_clk.c, GCC_BASE, 0x0031},
+ { &gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
+ { &gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
+ { &gcc_usb2a_phy_sleep_clk.c, GCC_BASE, 0x0063},
+ { &gcc_sdcc1_apps_clk.c, GCC_BASE, 0x0068},
+ { &gcc_sdcc1_ahb_clk.c, GCC_BASE, 0x0069},
+ { &gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
+ { &gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
+ { &gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
+ {&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
+ {&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
+ { &gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
+ {&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
+ {&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
+ { &gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
+ {&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
+ {&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
+ { &gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
+ {&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
+ {&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
+ { &gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
+ {&gcc_blsp1_qup5_spi_apps_clk.c, GCC_BASE, 0x009c},
+ {&gcc_blsp1_qup5_i2c_apps_clk.c, GCC_BASE, 0x009d},
+ { &gcc_blsp1_uart5_apps_clk.c, GCC_BASE, 0x009e},
+ {&gcc_blsp1_qup6_spi_apps_clk.c, GCC_BASE, 0x00a1},
+ {&gcc_blsp1_qup6_i2c_apps_clk.c, GCC_BASE, 0x00a2},
+ { &gcc_blsp1_uart6_apps_clk.c, GCC_BASE, 0x00a3},
+ { &gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
+ { &gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
+ { &gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
+ { &gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
+ { &gcc_ce1_clk.c, GCC_BASE, 0x0138},
+ { &gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
+ { &gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
+ { &gcc_xo_clk_src.c, GCC_BASE, 0x0149},
+ { &bimc_clk.c, GCC_BASE, 0x0154},
+ { &gcc_lpass_q6_axi_clk.c, GCC_BASE, 0x0160},
+
+ {&mmss_mmssnoc_ahb_clk.c, MMSS_BASE, 0x0001},
+ { &mmss_misc_ahb_clk.c, MMSS_BASE, 0x0003},
+ {&mmss_mmssnoc_axi_clk.c, MMSS_BASE, 0x0004},
+ { &mmss_s0_axi_clk.c, MMSS_BASE, 0x0005},
+ { &oxili_ahb_clk.c, MMSS_BASE, 0x0007},
+ { &oxili_gfx3d_clk.c, MMSS_BASE, 0x0008},
+ { &gmem_gfx3d_clk.c, MMSS_BASE, 0x0009},
+ { &mdp_axi_clk.c, MMSS_BASE, 0x000a},
+ { &mdp_vsync_clk.c, MMSS_BASE, 0x000b},
+ { &mdp_ahb_clk.c, MMSS_BASE, 0x000c},
+ { &dsi_pclk_clk.c, MMSS_BASE, 0x000d},
+ { &mdp_dsi_clk.c, MMSS_BASE, 0x000e},
+ { &mdp_lcdc_clk.c, MMSS_BASE, 0x000f},
+ { &dsi_clk.c, MMSS_BASE, 0x0010},
+ { &dsi_byte_clk.c, MMSS_BASE, 0x0011},
+ { &dsi_esc_clk.c, MMSS_BASE, 0x0012},
+ { &dsi_ahb_clk.c, MMSS_BASE, 0x0013},
+ { &mclk0_clk.c, MMSS_BASE, 0x0015},
+ { &mclk1_clk.c, MMSS_BASE, 0x0016},
+ { &csi0phytimer_clk.c, MMSS_BASE, 0x0017},
+ { &csi1phytimer_clk.c, MMSS_BASE, 0x0018},
+ { &vfe_clk.c, MMSS_BASE, 0x0019},
+ { &vfe_ahb_clk.c, MMSS_BASE, 0x001a},
+ { &vfe_axi_clk.c, MMSS_BASE, 0x001b},
+ { &csi_vfe_clk.c, MMSS_BASE, 0x001c},
+ { &csi0_clk.c, MMSS_BASE, 0x001d},
+ { &csi_ahb_clk.c, MMSS_BASE, 0x001e},
+ { &csi0phy_clk.c, MMSS_BASE, 0x001f},
+ { &csi0rdi_clk.c, MMSS_BASE, 0x0020},
+ { &csi0pix_clk.c, MMSS_BASE, 0x0021},
+ { &csi1_clk.c, MMSS_BASE, 0x0022},
+ { &csi1phy_clk.c, MMSS_BASE, 0x0023},
+ { &csi1rdi_clk.c, MMSS_BASE, 0x0024},
+ { &csi1pix_clk.c, MMSS_BASE, 0x0025},
+ { &bimc_gfx_clk.c, MMSS_BASE, 0x0032},
+
+ { &lpaif_pcmoe_clk_src.c, LPASS_BASE, 0x000f},
+ { &lpaif_pcm1_clk_src.c, LPASS_BASE, 0x0012},
+ { &lpaif_pcm0_clk_src.c, LPASS_BASE, 0x0013},
+ { &lpaif_quad_clk_src.c, LPASS_BASE, 0x0014},
+ { &lpaif_ter_clk_src.c, LPASS_BASE, 0x0015},
+ { &lpaif_sec_clk_src.c, LPASS_BASE, 0x0016},
+ { &lpaif_pri_clk_src.c, LPASS_BASE, 0x0017},
+ { &lpaif_spkr_clk_src.c, LPASS_BASE, 0x0018},
+ { &q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
+ { &q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
+ { &audio_wrapper_br_clk.c, LPASS_BASE, 0x0022},
+ { &q6ss_xo_clk.c, LPASS_BASE, 0x002b},
+ {&audio_core_lpaif_pcm_data_oe_clk.c, LPASS_BASE, 0x0030},
+ { &audio_core_ixfabric_clk.c, LPASS_BASE, 0x0059},
+
+ {&dummy_clk, N_BASES, 0x0000},
+};
+
+#define GCC_DEBUG_CLK_CTL 0x1880
+#define MMSS_DEBUG_CLK_CTL 0x0900
+#define LPASS_DEBUG_CLK_CTL 0x29000
+#define GLB_CLK_DIAG 0x001C
+
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned long flags;
+ u32 regval, clk_sel, i;
+
+ if (!parent)
+ return -EINVAL;
+
+ for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
+ if (measure_mux[i].c == parent)
+ break;
+
+ if (measure_mux[i].c == &dummy_clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+ /*
+ * Program the test vector, measurement period (sample_ticks)
+ * and scaling multiplier.
+ */
+ clk->sample_ticks = 0x10000;
+ clk->multiplier = 1;
+
+ switch (measure_mux[i].base) {
+
+ case GCC_BASE:
+ writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+ clk_sel = measure_mux[i].debug_mux;
+ break;
+
+ case MMSS_BASE:
+ writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+ clk_sel = 0x02C;
+ regval = BVAL(11, 0, measure_mux[i].debug_mux);
+ writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(16);
+ writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL));
+ break;
+
+ case LPASS_BASE:
+ writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+ clk_sel = 0x161;
+ regval = BVAL(11, 0, measure_mux[i].debug_mux);
+ writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(20);
+ writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL));
+ break;
+
+ case APCS_BASE:
+ clk->multiplier = 4;
+ clk_sel = 0x16A;
+ regval = measure_mux[i].debug_mux;
+ writel_relaxed(regval, APCS_REG_BASE(GLB_CLK_DIAG));
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Set debug mux clock index */
+ regval = BVAL(8, 0, clk_sel);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(16);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Make sure test vector is set before starting measurements. */
+ mb();
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ return 0;
+}
+
+#define CLOCK_FRQ_MEASURE_CTL 0x1884
+#define CLOCK_FRQ_MEASURE_STATUS 0x1888
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+ /* Stop counters and set the XO4 counter start value. */
+ writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+ /* Wait for timer to become ready. */
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) != 0)
+ cpu_relax();
+
+ /* Run measurement and wait for completion. */
+ writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) == 0)
+ cpu_relax();
+
+ /* Return measured ticks. */
+ return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BM(24, 0);
+}
+
+#define GCC_XO_DIV4_CBCR 0x10C8
+#define PLLTEST_PAD_CFG 0x188C
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+ unsigned long flags;
+ u32 gcc_xo4_reg_backup;
+ u64 raw_count_short, raw_count_full;
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned ret;
+
+ ret = clk_prepare_enable(&gcc_xo_clk_src.c);
+ if (ret) {
+ pr_warning("CXO clock failed to enable. Can't measure\n");
+ return 0;
+ }
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+ /* Enable CXO/4 and RINGOSC branch. */
+ gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+ writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /*
+ * The ring oscillator counter will not reset if the measured clock
+ * is not running. To detect this, run a short measurement before
+ * the full measurement. If the raw results of the two are the same
+ * then the clock must be off.
+ */
+
+ /* Run a short measurement. (~1 ms) */
+ raw_count_short = run_measurement(0x1000);
+ /* Run a full measurement. (~14 ms) */
+ raw_count_full = run_measurement(clk->sample_ticks);
+
+ writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /* Return 0 if the clock is off. */
+ if (raw_count_full == raw_count_short) {
+ ret = 0;
+ } else {
+ /* Compute rate in Hz. */
+ raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+ do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+ ret = (raw_count_full * clk->multiplier);
+ }
+
+ writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ clk_disable_unprepare(&gcc_xo_clk_src.c);
+
+ return ret;
+}
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+ .set_parent = measure_clk_set_parent,
+ .get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+ .c = {
+ .dbg_name = "measure_clk",
+ .ops = &clk_ops_measure,
+ CLK_INIT(measure_clk.c),
+ },
+ .multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_8910[] = {
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "msm_otg"),
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "pil-q6v5-mss"),
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "pil-mba"),
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "fb000000.qcom,wcnss-wlan"),
+ CLK_LOOKUP("xo", gcc_xo_clk_src.c, "pil_pronto"),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+
+ CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
+ CLK_LOOKUP("bus_clk", pnoc_qseecom_clk.c, "qseecom"),
+
+ CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+ CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+ CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+ CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+ CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
+
+ CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, "msm_bimc"),
+ CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc"),
+ CLK_LOOKUP("mem_clk", bimc_acpu_a_clk.c, ""),
+
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etr"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tpiu"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-replicator"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-tmc-etf"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-merg"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-in1"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-kpss"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-funnel-mmss"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-stm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm1"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm2"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "coresight-etm3"),
+
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etr"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tpiu"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-replicator"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-tmc-etf"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-merg"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in0"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-in1"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-kpss"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-funnel-mmss"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-stm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm0"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm1"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm2"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "coresight-etm3"),
+
+ CLK_LOOKUP("core_clk_src", blsp1_qup1_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_qup2_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_qup3_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_qup4_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_qup5_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_qup6_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart1_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart2_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart3_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart4_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart5_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", blsp1_uart6_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", gp1_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", gp2_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", gp3_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", pdm2_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", sdcc1_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", sdcc2_apps_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", usb_hs_system_clk_src.c, ""),
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup3_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup3_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup4_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup5_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_boot_rom_ahb_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_ce1_axi_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_copss_smmu_ahb_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_lpss_smmu_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_lpass_q6_axi_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_mss_q6_bimc_axi_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_pdm2_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_pdm_ahb_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_prng_ahb_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("core_clk", gcc_sdcc1_apps_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("core_clk", gcc_usb2a_phy_sleep_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
+ CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
+
+ CLK_LOOKUP("core_clk_src", csi0_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", axi_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", dsi_pclk_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", gfx3d_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", vfe_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", csi1_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", csi0phytimer_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", csi1phytimer_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", dsi_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", dsi_byte_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", dsi_esc_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", mclk0_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", mclk1_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", mdp_vsync_clk_src.c, ""),
+
+ CLK_LOOKUP("core_clk", bimc_gfx_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi0_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi0phy_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi0phytimer_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi0pix_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi0rdi_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi1_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi1phy_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi1phytimer_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi1pix_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi1rdi_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", csi_vfe_clk.c, ""),
+ CLK_LOOKUP("core_clk", dsi_clk.c, ""),
+ CLK_LOOKUP("core_clk", dsi_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", dsi_byte_clk.c, ""),
+ CLK_LOOKUP("core_clk", dsi_esc_clk.c, ""),
+ CLK_LOOKUP("core_clk", dsi_pclk_clk.c, ""),
+ CLK_LOOKUP("core_clk", gmem_gfx3d_clk.c, ""),
+ CLK_LOOKUP("core_clk", mclk0_clk.c, ""),
+ CLK_LOOKUP("core_clk", mclk1_clk.c, ""),
+ CLK_LOOKUP("core_clk", mdp_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, ""),
+ CLK_LOOKUP("core_clk", mdp_dsi_clk.c, ""),
+ CLK_LOOKUP("core_clk", mdp_lcdc_clk.c, ""),
+ CLK_LOOKUP("core_clk", mdp_vsync_clk.c, ""),
+ CLK_LOOKUP("core_clk", mmss_misc_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", mmss_s0_axi_clk.c, ""),
+ CLK_LOOKUP("core_clk", mmss_mmssnoc_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", mmss_mmssnoc_bto_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", mmss_mmssnoc_axi_clk.c, ""),
+ CLK_LOOKUP("core_clk", vfe_clk.c, ""),
+ CLK_LOOKUP("core_clk", vfe_ahb_clk.c, ""),
+ CLK_LOOKUP("core_clk", vfe_axi_clk.c, ""),
+
+ CLK_LOOKUP("core_clk", oxili_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("iface_clk", oxili_ahb_clk.c, "fdc00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("mem_iface_clk", bimc_gfx_clk.c, "fdc00000.qcom,kgsl-3d0"),
+ CLK_LOOKUP("mem_clk", gmem_gfx3d_clk.c, "fdc00000.qcom,kgsl-3d0"),
+
+ CLK_LOOKUP("iface_clk", vfe_ahb_clk.c, "fd890000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", vfe_axi_clk.c, "fd890000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", mdp_ahb_clk.c, "fd860000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, "fd860000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", mdp_ahb_clk.c, "fd870000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, "fd870000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", oxili_ahb_clk.c, "fd880000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", bimc_gfx_clk.c, "fd880000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", gcc_lpss_smmu_ahb_clk.c, "fd000000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", gcc_lpass_q6_axi_clk.c, "fd000000.qcom,iommu"),
+ CLK_LOOKUP("iface_clk", gcc_copss_smmu_ahb_clk.c,
+ "fd010000.qcom,iommu"),
+ CLK_LOOKUP("core_clk", pnoc_iommu_clk.c, "fd010000.qcom,iommu"),
+
+ CLK_LOOKUP("core_clk_src", lpaif_pri_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_quad_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_sec_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_spkr_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_ter_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_pcm0_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_pcm1_clk_src.c, ""),
+ CLK_LOOKUP("core_clk_src", lpaif_pcmoe_clk_src.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_ixfabric_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_wrapper_br_clk.c, ""),
+ CLK_LOOKUP("core_clk", q6ss_ahb_lfabif_clk.c, ""),
+ CLK_LOOKUP("core_clk", q6ss_ahbm_clk.c, ""),
+ CLK_LOOKUP("core_clk", q6ss_xo_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pcm_data_oe_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pri_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pri_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pri_osr_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_quad_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_quad_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_quad_osr_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_sec_osr_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_pcm1_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_codec_spkr_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_codec_spkr_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_codec_spkr_osr_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_ter_ebit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_ter_ibit_clk.c, ""),
+ CLK_LOOKUP("core_clk", audio_core_lpaif_ter_osr_clk.c, ""),
+
+ CLK_LOOKUP("core_clk", q6ss_xo_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("bus_clk", gcc_lpass_q6_axi_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("reg_clk", q6ss_ahbm_clk.c, "fe200000.qcom,lpass"),
+};
+
+static struct clk_lookup msm_clocks_8910_rumi[] = {
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+ CLK_DUMMY("iface_clk", HSUSB_IFACE_CLK, "f9a55000.usb", OFF),
+ CLK_DUMMY("core_clk", HSUSB_CORE_CLK, "f9a55000.usb", OFF),
+ CLK_DUMMY("iface_clk", NULL, "msm_sdcc.1", OFF),
+ CLK_DUMMY("core_clk", NULL, "msm_sdcc.1", OFF),
+ CLK_DUMMY("bus_clk", NULL, "msm_sdcc.1", OFF),
+ CLK_DUMMY("iface_clk", NULL, "msm_sdcc.2", OFF),
+ CLK_DUMMY("core_clk", NULL, "msm_sdcc.2", OFF),
+ CLK_DUMMY("bus_clk", NULL, "msm_sdcc.2", OFF),
+ CLK_DUMMY("dfab_clk", DFAB_CLK, "msm_sps", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd890000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd890000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd860000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd860000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd870000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd870000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd880000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd880000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd000000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd000000.qcom,iommu", OFF),
+ CLK_DUMMY("iface_clk", NULL, "fd010000.qcom,iommu", OFF),
+ CLK_DUMMY("core_clk", NULL, "fd010000.qcom,iommu", OFF),
+};
+
+struct clock_init_data msm8910_rumi_clock_init_data __initdata = {
+ .table = msm_clocks_8910_rumi,
+ .size = ARRAY_SIZE(msm_clocks_8910_rumi),
+};
+
+static struct pll_config_regs gpll0_regs __initdata = {
+ .l_reg = (void __iomem *)GPLL0_L_VAL,
+ .m_reg = (void __iomem *)GPLL0_M_VAL,
+ .n_reg = (void __iomem *)GPLL0_N_VAL,
+ .config_reg = (void __iomem *)GPLL0_USER_CTL,
+ .mode_reg = (void __iomem *)GPLL0_MODE,
+ .base = &virt_bases[GCC_BASE],
+};
+
+/* GPLL0 at 600 MHz, main output enabled. */
+static struct pll_config gpll0_config __initdata = {
+ .l = 0x1f,
+ .m = 0x1,
+ .n = 0x4,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+/* MMPLL0 at 800 MHz, main output enabled. */
+static struct pll_config mmpll0_config __initdata = {
+ .l = 0x29,
+ .m = 0x2,
+ .n = 0x3,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+/* MMPLL1 at 1200 MHz, main output enabled. */
+static struct pll_config mmpll1_config __initdata = {
+ .l = 0x3E,
+ .m = 0x1,
+ .n = 0x2,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+static struct pll_config_regs lpapll0_regs __initdata = {
+ .l_reg = (void __iomem *)LPAAUDIO_PLL_L_VAL,
+ .m_reg = (void __iomem *)LPAAUDIO_PLL_M_VAL,
+ .n_reg = (void __iomem *)LPAAUDIO_PLL_N_VAL,
+ .config_reg = (void __iomem *)LPAAUDIO_PLL_USER_CTL,
+ .mode_reg = (void __iomem *)LPAAUDIO_PLL_MODE,
+ .base = &virt_bases[LPASS_BASE],
+};
+
+/* LPAPLL0 at 491.52 MHz, main output enabled. */
+static struct pll_config lpapll0_config __initdata = {
+ .l = 0x33,
+ .m = 0x1,
+ .n = 0x5,
+ .vco_val = 0x0,
+ .vco_mask = BM(21, 20),
+ .pre_div_val = BVAL(14, 12, 0x1),
+ .pre_div_mask = BM(14, 12),
+ .post_div_val = 0x0,
+ .post_div_mask = BM(9, 8),
+ .mn_ena_val = BIT(24),
+ .mn_ena_mask = BIT(24),
+ .main_output_val = BIT(0),
+ .main_output_mask = BIT(0),
+};
+
+#define PLL_AUX_OUTPUT_BIT 1
+#define PLL_AUX2_OUTPUT_BIT 2
+
+#define PWR_ON_MASK BIT(31)
+#define EN_REST_WAIT_MASK (0xF << 20)
+#define EN_FEW_WAIT_MASK (0xF << 16)
+#define CLK_DIS_WAIT_MASK (0xF << 12)
+#define SW_OVERRIDE_MASK BIT(2)
+#define HW_CONTROL_MASK BIT(1)
+#define SW_COLLAPSE_MASK BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL (0x2 << 20)
+#define EN_FEW_WAIT_VAL (0x2 << 16)
+#define CLK_DIS_WAIT_VAL (0x2 << 12)
+#define GDSC_TIMEOUT_US 50000
+
+static void __init reg_init(void)
+{
+ u32 regval, status;
+ int ret;
+
+ if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS))
+ & gpll0_clk_src.status_mask))
+ configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
+
+ configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
+ configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
+ configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
+
+ /* Enable GPLL0's aux outputs. */
+ regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL));
+ regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
+ writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL));
+
+ /* Vote for GPLL0 to turn on. Needed by acpuclock. */
+ regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+ regval |= BIT(0);
+ writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+
+ /*
+ * TODO: Confirm that no clocks need to be voted on in this sleep vote
+ * register.
+ */
+ writel_relaxed(0x0, GCC_REG_BASE(APCS_CLOCK_SLEEP_ENA_VOTE));
+
+ /*
+ * TODO: The following sequence enables the LPASS audio core GDSC.
+ * Remove when this becomes unnecessary.
+ */
+
+ /*
+ * Disable HW trigger: collapse/restore occur based on registers writes.
+ * Disable SW override: Use hardware state-machine for sequencing.
+ */
+ regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+ regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK);
+
+ /* Configure wait time between states. */
+ regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK);
+ regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+ writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+
+ regval = readl_relaxed(LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+ regval &= ~BIT(0);
+ writel_relaxed(regval, LPASS_REG_BASE(AUDIO_CORE_GDSCR));
+
+ ret = readl_poll_timeout(LPASS_REG_BASE(AUDIO_CORE_GDSCR), status,
+ status & PWR_ON_MASK, 50, GDSC_TIMEOUT_US);
+ WARN(ret, "LPASS Audio Core GDSC did not power on.\n");
+}
+
+static void __init msm8910_clock_post_init(void)
+{
+ /*
+ * Hold an active set vote for CXO; this is because CXO is expected
+ * to remain on whenever CPUs aren't power collapsed.
+ */
+ clk_prepare_enable(&gcc_xo_a_clk_src.c);
+
+
+ /* Set rates for single-rate clocks. */
+ clk_set_rate(&usb_hs_system_clk_src.c,
+ usb_hs_system_clk_src.freq_tbl[0].freq_hz);
+ clk_set_rate(&pdm2_clk_src.c, pdm2_clk_src.freq_tbl[0].freq_hz);
+ clk_set_rate(&mclk0_clk_src.c, mclk0_clk_src.freq_tbl[0].freq_hz);
+ clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
+ clk_set_rate(&audio_core_slimbus_core_clk_src.c,
+ audio_core_slimbus_core_clk_src.freq_tbl[0].freq_hz);
+}
+
+#define GCC_CC_PHYS 0xFC400000
+#define GCC_CC_SIZE SZ_16K
+
+#define MMSS_CC_PHYS 0xFD8C0000
+#define MMSS_CC_SIZE SZ_256K
+
+#define LPASS_CC_PHYS 0xFE000000
+#define LPASS_CC_SIZE SZ_256K
+
+#define APCS_GCC_CC_PHYS 0xF9011000
+#define APCS_GCC_CC_SIZE SZ_4K
+
+static void __init msm8910_clock_pre_init(void)
+{
+ virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+ if (!virt_bases[GCC_BASE])
+ panic("clock-8910: Unable to ioremap GCC memory!");
+
+ virt_bases[MMSS_BASE] = ioremap(MMSS_CC_PHYS, MMSS_CC_SIZE);
+ if (!virt_bases[MMSS_BASE])
+ panic("clock-8910: Unable to ioremap MMSS_CC memory!");
+
+ virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
+ if (!virt_bases[LPASS_BASE])
+ panic("clock-8910: Unable to ioremap LPASS_CC memory!");
+
+ virt_bases[APCS_BASE] = ioremap(APCS_GCC_CC_PHYS, APCS_GCC_CC_SIZE);
+ if (!virt_bases[APCS_BASE])
+ panic("clock-8910: Unable to ioremap APCS_GCC_CC memory!");
+
+ clk_ops_local_pll.enable = sr_hpm_lp_pll_clk_enable;
+
+ vdd_dig_reg = rpm_regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig_reg))
+ panic("clock-8910: 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);
+
+ enable_rpm_scaling();
+
+ /* Enable a clock to allow access to MMSS clock registers */
+ clk_prepare_enable(&gcc_mmss_noc_cfg_ahb_clk.c),
+
+ reg_init();
+
+ /* TODO: Remove this once the bus driver is in place */
+ clk_set_rate(&ahb_clk_src.c, 40000000);
+ clk_set_rate(&axi_clk_src.c, 200000000);
+ clk_prepare_enable(&mmss_mmssnoc_ahb_clk.c);
+ clk_prepare_enable(&mmss_s0_axi_clk.c);
+
+ /* TODO: Temporarily enable a clock to allow access to LPASS core
+ * registers.
+ */
+ clk_prepare_enable(&audio_core_ixfabric_clk.c);
+}
+
+static int __init msm8910_clock_late_init(void)
+{
+ return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+}
+
+struct clock_init_data msm8910_clock_init_data __initdata = {
+ .table = msm_clocks_8910,
+ .size = ARRAY_SIZE(msm_clocks_8910),
+ .pre_init = msm8910_clock_pre_init,
+ .post_init = msm8910_clock_post_init,
+ .late_init = msm8910_clock_late_init,
+};
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 4a885c8..94fb856 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -3020,34 +3020,17 @@
static int hdmi_pll_clk_enable(struct clk *c)
{
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&local_clock_reg_lock, flags);
- ret = hdmi_pll_enable();
- spin_unlock_irqrestore(&local_clock_reg_lock, flags);
- return ret;
+ return hdmi_pll_enable();
}
static void hdmi_pll_clk_disable(struct clk *c)
{
- unsigned long flags;
-
- spin_lock_irqsave(&local_clock_reg_lock, flags);
hdmi_pll_disable();
- spin_unlock_irqrestore(&local_clock_reg_lock, flags);
}
static int hdmi_pll_clk_set_rate(struct clk *c, unsigned long rate)
{
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&local_clock_reg_lock, flags);
- rc = hdmi_pll_set_rate(rate);
- spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
- return rc;
+ return hdmi_pll_set_rate(rate);
}
static struct clk_ops clk_ops_hdmi_pll = {
@@ -3084,21 +3067,39 @@
* Unlike other clocks, the HDMI rate is adjusted through PLL
* re-programming. It is also routed through an HID divider.
*/
-static void set_rate_hdmi(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
+static int rcg_clk_set_rate_hdmi(struct clk *c, unsigned long rate)
{
- clk_set_rate(nf->src_clk, nf->freq_hz);
+ struct clk_freq_tbl *nf;
+ struct rcg_clk *rcg = to_rcg_clk(c);
+ int rc;
+
+ for (nf = rcg->freq_tbl; nf->freq_hz != rate; nf++)
+ if (nf->freq_hz == FREQ_END) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = clk_set_rate(nf->src_clk, rate);
+ if (rc < 0)
+ goto out;
set_rate_hid(rcg, nf);
+
+ rcg->current_freq = nf;
+ c->parent = nf->src_clk;
+out:
+ return rc;
}
+static struct clk_ops clk_ops_rcg_hdmi;
+
static struct rcg_clk extpclk_clk_src = {
.cmd_rcgr_reg = EXTPCLK_CMD_RCGR,
- .set_rate = set_rate_hdmi,
.freq_tbl = ftbl_mdss_extpclk_clk,
.current_freq = &rcg_dummy_freq,
.base = &virt_bases[MMSS_BASE],
.c = {
.dbg_name = "extpclk_clk_src",
- .ops = &clk_ops_rcg,
+ .ops = &clk_ops_rcg_hdmi,
VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 297000000),
CLK_INIT(extpclk_clk_src.c),
},
@@ -5687,6 +5688,9 @@
clk_ops_pixel = clk_ops_rcg;
clk_ops_pixel.set_rate = set_rate_pixel;
+ clk_ops_rcg_hdmi = clk_ops_rcg;
+ clk_ops_rcg_hdmi.set_rate = rcg_clk_set_rate_hdmi;
+
mdss_clk_ctrl_init();
}
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index c30e566..79bc639 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -350,9 +350,11 @@
void hdmi_pll_disable(void)
{
+ clk_enable(mdss_dsi_ahb_clk);
REG_W(0x0, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(5);
REG_W(0x0, hdmi_phy_base + HDMI_PHY_GLB_CFG);
+ clk_disable(mdss_dsi_ahb_clk);
hdmi_pll_on = 0;
} /* hdmi_pll_disable */
@@ -362,6 +364,7 @@
u32 status;
u32 max_reads, timeout_us;
+ clk_enable(mdss_dsi_ahb_clk);
/* Global Enable */
REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
/* Power up power gen */
@@ -387,6 +390,7 @@
pr_err("%s: hdmi phy pll status=%x failed to Lock\n",
__func__, status);
hdmi_pll_disable();
+ clk_disable(mdss_dsi_ahb_clk);
return -EINVAL;
}
pr_debug("%s: hdmi phy pll is locked\n", __func__);
@@ -400,9 +404,11 @@
pr_err("%s: hdmi phy status=%x failed to Lock\n",
__func__, status);
hdmi_pll_disable();
+ clk_disable(mdss_dsi_ahb_clk);
return -EINVAL;
}
pr_debug("%s: hdmi phy is locked\n", __func__);
+ clk_disable(mdss_dsi_ahb_clk);
hdmi_pll_on = 1;
@@ -418,6 +424,7 @@
set_power_dwn = 1;
}
+ clk_enable(mdss_dsi_ahb_clk);
pr_debug("%s: rate=%ld\n", __func__, rate);
switch (rate) {
case 0:
@@ -746,6 +753,8 @@
/* Make sure writes complete before disabling iface clock */
mb();
+ clk_disable(mdss_dsi_ahb_clk);
+
if (set_power_dwn)
hdmi_pll_enable();
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index 8a75d390..181cf4c 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -49,6 +49,8 @@
extern struct clock_init_data msm8930_pm8917_clock_init_data;
extern struct clock_init_data msm8974_clock_init_data;
extern struct clock_init_data msm8974_rumi_clock_init_data;
+extern struct clock_init_data msm8910_clock_init_data;
+extern struct clock_init_data msm8910_rumi_clock_init_data;
int msm_clock_init(struct clock_init_data *data);
int find_vdd_level(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 0bfaa71..fd5fc81 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2796,7 +2796,7 @@
.slack_weight_thresh_pct = 3,
.slack_time_min_us = 45000,
.slack_time_max_us = 45000,
- .ss_iobusy_conv = 100,
+ .ss_no_corr_below_freq = 0,
.ss_win_size_min_us = 1000000,
.ss_win_size_max_us = 1000000,
.ss_util_pct = 95,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0b10784..4780c57 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3030,7 +3030,7 @@
.ss_win_size_min_us = 1000000,
.ss_win_size_max_us = 1000000,
.ss_util_pct = 95,
- .ss_iobusy_conv = 100,
+ .ss_no_corr_below_freq = 0,
},
.energy_coeffs = {
.active_coeff_a = 2492,
@@ -3067,7 +3067,7 @@
.ss_win_size_min_us = 1000000,
.ss_win_size_max_us = 1000000,
.ss_util_pct = 95,
- .ss_iobusy_conv = 100,
+ .ss_no_corr_below_freq = 0,
},
.energy_coeffs = {
.active_coeff_a = 2492,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index b3d887e..5aa747a 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -36,6 +36,7 @@
#include "devices-msm7x2xa.h"
#include "footswitch.h"
#include "acpuclock.h"
+#include "acpuclock-8625q.h"
#include "spm.h"
#include "mpm-8625.h"
#include "irq.h"
@@ -240,6 +241,21 @@
.dev.platform_data = &msm7x27aa_acpuclk_pdata,
};
+static struct acpuclk_pdata msm8625q_pdata = {
+ .max_speed_delta_khz = 801600,
+};
+
+static struct acpuclk_pdata_8625q msm8625q_acpuclk_pdata = {
+ .acpu_clk_data = &msm8625q_pdata,
+ .pvs_voltage_uv = 1350000,
+};
+
+struct platform_device msm8625q_device_acpuclk = {
+ .name = "acpuclock-8625q",
+ .id = -1,
+ .dev.platform_data = &msm8625q_acpuclk_pdata,
+};
+
static struct acpuclk_pdata msm8625_acpuclk_pdata = {
/* TODO: Need to update speed delta from H/w Team */
.max_speed_delta_khz = 604800,
@@ -1775,13 +1791,6 @@
},
};
-struct msm_cpr_vp_data vp_data = {
- .min_volt = 1000000,
- .max_volt = 1350000,
- .default_volt = 1300000,
- .step_size = 12500,
-};
-
static uint32_t
msm_cpr_get_quot(uint32_t max_quot, uint32_t max_freq, uint32_t new_freq)
{
@@ -1823,7 +1832,7 @@
.max_freq = 1401600,
.max_quot = 0,
.disable_cpr = false,
- .vp_data = &vp_data,
+ .step_size = 12500,
.get_quot = msm_cpr_get_quot,
.clk_enable = msm_cpr_clk_enable,
};
@@ -2036,6 +2045,24 @@
return ret;
}
+static int __init msm_acpuclock_init(int nominal_voltage,
+ int default_turbo_voltage)
+{
+ struct cpr_info_type *acpu_info = NULL;
+ acpu_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
+ if (!acpu_info) {
+ pr_err("%s: Out of memory %d\n", __func__, -ENOMEM);
+ return -ENOMEM;
+ }
+ msm_smem_get_cpr_info(acpu_info);
+ msm8625q_acpuclk_pdata.pvs_voltage_uv =
+ msm_c2_pmic_mv[acpu_info->pvs_fuse & 0x1F];
+ kfree(acpu_info);
+ msm8625q_acpuclk_pdata.nominal_voltage = nominal_voltage;
+ msm8625q_acpuclk_pdata.default_turbo_voltage = default_turbo_voltage;
+ return 0;
+}
+
int __init msm7x2x_misc_init(void)
{
if (machine_is_msm8625_rumi3()) {
@@ -2047,8 +2074,14 @@
msm_clock_init(&msm7x27a_clock_init_data);
if (cpu_is_msm7x27aa() || cpu_is_msm7x25ab())
platform_device_register(&msm7x27aa_device_acpuclk);
- else if (cpu_is_msm8625() || cpu_is_msm8625q()) {
- if (msm8625_cpu_id() == MSM8625)
+ else if (cpu_is_msm8625q()) {
+ msm_acpuclock_init(1050000, 0);
+ platform_device_register(&msm8625q_device_acpuclk);
+ } else if (cpu_is_msm8625()) {
+ if (machine_is_qrd_skud_prime()) {
+ msm_acpuclock_init(1150000, 1275000);
+ platform_device_register(&msm8625q_device_acpuclk);
+ } else if (msm8625_cpu_id() == MSM8625)
platform_device_register(&msm7x27aa_device_acpuclk);
else if (msm8625_cpu_id() == MSM8625A)
platform_device_register(&msm8625_device_acpuclk);
diff --git a/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h b/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
index 597fdc0..7eefd54 100644
--- a/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
+++ b/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
@@ -48,7 +48,7 @@
uint32_t slack_time_min_us;
uint32_t slack_time_max_us;
uint32_t slack_weight_thresh_pct;
- uint32_t ss_iobusy_conv;
+ uint32_t ss_no_corr_below_freq;
uint32_t ss_win_size_min_us;
uint32_t ss_win_size_max_us;
uint32_t ss_util_pct;
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h b/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
index 08f21b6..64990da 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8910.h
@@ -22,7 +22,7 @@
*
*/
-#define MSM8910_MSM_SHARED_RAM_PHYS 0x0FA00000
+#define MSM8910_MSM_SHARED_RAM_PHYS 0x0D600000
#define MSM8910_APCS_GCC_PHYS 0xF9011000
#define MSM8910_APCS_GCC_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 17156b1..fe928b9 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -127,6 +127,7 @@
#define MSM_HDMI_SIZE SZ_4K
/* Needed to keep the unified iomap happy */
+#define MSM_APCS_GCC_BASE IOMEM(0xFA006000) /* 4K */
#define MSM_MPM2_PSHOLD_BASE MSM_TLMM_BASE
#ifdef CONFIG_DEBUG_MSM8660_UART
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 0499a7a..d41a1f0 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -60,6 +60,8 @@
of_machine_is_compatible("qcom,msm8910")
#define machine_is_msm8910_sim() \
of_machine_is_compatible("qcom,msm8910-sim")
+#define machine_is_msm8910_rumi() \
+ of_machine_is_compatible("qcom,msm8910-rumi")
#else
#define early_machine_is_msm8974() 0
#define machine_is_msm8974() 0
@@ -75,6 +77,7 @@
#define early_machine_is_msm8910() 0
#define machine_is_msm8910() 0
#define machine_is_msm8910_sim() 0
+#define machine_is_msm8910_rumi() 0
#endif
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index c7a8b98..dd6ffab 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -91,7 +91,7 @@
struct regulator *vreg_cx;
const struct msm_cpr_config *config;
struct notifier_block freq_transition;
- struct msm_cpr_vp_data *vp;
+ uint32_t step_size;
};
/* Need to maintain state data for suspend and resume APIs */
@@ -219,7 +219,7 @@
*
*/
level_uV = chip_data->turbo_Vmax -
- (chip_data->tgt_volt_offset * cpr->vp->step_size);
+ (chip_data->tgt_volt_offset * cpr->step_size);
msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
"tgt_volt_uV = %d\n", level_uV);
@@ -260,7 +260,7 @@
quot1 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
/* Take second CPR measurement at a lower voltage to get QUOT2 */
- level_uV -= 4 * cpr->vp->step_size;
+ level_uV -= 4 * cpr->step_size;
msm_cpr_debug(MSM_CPR_DEBUG_CONFIG,
"tgt_volt_uV = %d\n", level_uV);
@@ -493,7 +493,7 @@
error_step += 1;
/* Calculte new PMIC voltage */
- new_volt = curr_volt + (error_step * cpr->vp->step_size);
+ new_volt = curr_volt + (error_step * cpr->step_size);
msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
"UP_INT: new_volt: %d, error_step=%d\n",
new_volt, error_step);
@@ -531,7 +531,7 @@
error_step = 2;
/* Calculte new PMIC voltage */
- new_volt = curr_volt - (error_step * cpr->vp->step_size);
+ new_volt = curr_volt - (error_step * cpr->step_size);
msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
"DOWN_INT: new_volt: %d, error_step=%d\n",
new_volt, error_step);
@@ -953,7 +953,7 @@
cpr->base = base;
- cpr->vp = pdata->vp_data;
+ cpr->step_size = pdata->step_size;
spin_lock_init(&cpr->cpr_lock);
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index 3d10478..d9c8e9b 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -122,20 +122,6 @@
};
/**
- * struct msm_vp_data - structure for VP configuration
- * @min_volt: minimum microvolt level for VP
- * @max_volt: maximum microvolt level for VP
- * @default_volt: default microvolt for VP
- * @step_size: step size of voltage in microvolt
- */
-struct msm_cpr_vp_data {
- int min_volt;
- int max_volt;
- int default_volt;
- int step_size;
-};
-
-/**
* struct msm_cpr_osc - Data for CPR ring oscillator
* @gcnt: gate count value for the oscillator
* @quot: target value for ring oscillator
@@ -189,7 +175,7 @@
uint32_t max_freq;
uint32_t max_quot;
bool disable_cpr;
- struct msm_cpr_vp_data *vp_data;
+ uint32_t step_size;
uint32_t (*get_quot)(uint32_t max_quot, uint32_t max_freq,
uint32_t new_freq);
void (*clk_enable)(void);
diff --git a/arch/arm/mach-msm/msm_cpu_pwrctl.c b/arch/arm/mach-msm/msm_cpu_pwrctl.c
new file mode 100644
index 0000000..6e339dd
--- /dev/null
+++ b/arch/arm/mach-msm/msm_cpu_pwrctl.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/types.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/compiler.h>
+#include <linux/notifier.h>
+#include <linux/percpu.h>
+#include <linux/workqueue.h>
+
+#define MSM_CPU_SECONDARY_CORE_OFFSET 0x10000
+
+static const phys_addr_t primary_cpu_pwrctl_phys = 0x2088004;
+static DEFINE_PER_CPU(int, pll_clamp_set);
+static void msm_cpu_pwrctl_work_cb(struct work_struct *work);
+static __cpuinitdata DECLARE_WORK(msm_cpu_pwrctl_work, msm_cpu_pwrctl_work_cb);
+static int nr_cpus_done;
+static int __cpuinit msm_cpu_pwrctl_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu);
+static struct notifier_block __cpuinitdata msm_cpu_pwrctl_cpu_notifier = {
+ .notifier_call = msm_cpu_pwrctl_cpu_callback,
+};
+
+static void __cpuinit msm_cpu_pwrctl_work_cb(struct work_struct *work)
+{
+ unregister_hotcpu_notifier(&msm_cpu_pwrctl_cpu_notifier);
+}
+
+static int __cpuinit msm_cpu_pwrctl_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ int cpu = (int) hcpu;
+ int *pll_clamp;
+ void *pwrctl_ptr;
+ unsigned int value;
+
+ switch (action & ~CPU_TASKS_FROZEN) {
+ case CPU_ONLINE:
+ pll_clamp = &per_cpu(pll_clamp_set, cpu);
+ if (likely(*pll_clamp))
+ goto done;
+
+ pwrctl_ptr = ioremap_nocache(primary_cpu_pwrctl_phys +
+ (cpu * MSM_CPU_SECONDARY_CORE_OFFSET), SZ_4K);
+ if (unlikely(!pwrctl_ptr))
+ goto done;
+
+ value = readl_relaxed(pwrctl_ptr);
+ value |= 0x100;
+ writel_relaxed(value, pwrctl_ptr);
+ *pll_clamp = 1;
+ iounmap(pwrctl_ptr);
+
+ if (++nr_cpus_done == cpumask_weight(cpu_possible_mask))
+ schedule_work(&msm_cpu_pwrctl_work);
+done:
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+
+}
+
+static int __init msm_cpu_pwrctl_init(void)
+{
+ int cpu = smp_processor_id();
+
+ /* We won't get cpu online notification for this CPU,
+ * so take this opportunity to process this CPU.
+ */
+ msm_cpu_pwrctl_cpu_callback(&msm_cpu_pwrctl_cpu_notifier,
+ CPU_ONLINE, (void *) cpu);
+
+ register_hotcpu_notifier(&msm_cpu_pwrctl_cpu_notifier);
+ return 0;
+}
+
+early_initcall(msm_cpu_pwrctl_init);
diff --git a/arch/arm/mach-msm/msm_dcvs.c b/arch/arm/mach-msm/msm_dcvs.c
index 3b9656e..9e0be63 100644
--- a/arch/arm/mach-msm/msm_dcvs.c
+++ b/arch/arm/mach-msm/msm_dcvs.c
@@ -49,7 +49,7 @@
struct kobj_attribute slack_time_min_us;
struct kobj_attribute slack_time_max_us;
struct kobj_attribute slack_weight_thresh_pct;
- struct kobj_attribute ss_iobusy_conv;
+ struct kobj_attribute ss_no_corr_below_freq;
struct kobj_attribute ss_win_size_min_us;
struct kobj_attribute ss_win_size_max_us;
struct kobj_attribute ss_util_pct;
@@ -151,6 +151,7 @@
static unsigned num_cpu_freqs;
static struct msm_dcvs_platform_data *dcvs_pdata;
+static DEFINE_MUTEX(param_update_mutex);
static DEFINE_MUTEX(gpu_floor_mutex);
static void force_stop_slack_timer(struct dcvs_core *core)
@@ -309,6 +310,20 @@
mutex_unlock(&gpu_floor_mutex);
}
+static void check_power_collapse_modes(struct dcvs_core *core)
+{
+ struct msm_dcvs_algo_param *params;
+
+ params = &core_list[CPU_OFFSET + num_online_cpus() - 1].algo_param;
+
+ if (core->actual_freq >= params->disable_pc_threshold)
+ core->idle_enable(core->type_core_num,
+ MSM_DCVS_DISABLE_HIGH_LATENCY_MODES);
+ else
+ core->idle_enable(core->type_core_num,
+ MSM_DCVS_ENABLE_HIGH_LATENCY_MODES);
+}
+
static int __msm_dcvs_change_freq(struct dcvs_core *core)
{
int ret = 0;
@@ -355,16 +370,11 @@
core->freq_change_us = (uint32_t)ktime_to_us(
ktime_sub(ktime_get(), time_start));
- /**
- * Disable low power modes if the actual frequency is >
- * disable_pc_threshold.
- */
- if (core->actual_freq > core->algo_param.disable_pc_threshold) {
- core->idle_enable(core->type_core_num,
- MSM_DCVS_DISABLE_HIGH_LATENCY_MODES);
- } else if (core->actual_freq <= core->algo_param.disable_pc_threshold) {
- core->idle_enable(core->type_core_num,
- MSM_DCVS_ENABLE_HIGH_LATENCY_MODES);
+ if (core->type == MSM_DCVS_CORE_TYPE_CPU &&
+ core->type_core_num == 0) {
+ mutex_lock(¶m_update_mutex);
+ check_power_collapse_modes(core);
+ mutex_unlock(¶m_update_mutex);
}
/**
@@ -556,7 +566,6 @@
int msm_dcvs_update_algo_params(void)
{
static struct msm_dcvs_algo_param curr_params;
- static DEFINE_MUTEX(param_update_mutex);
struct msm_dcvs_algo_param *new_params;
int cpu, ret = 0;
@@ -566,6 +575,7 @@
if (memcmp(&curr_params, new_params,
sizeof(struct msm_dcvs_algo_param))) {
for_each_possible_cpu(cpu) {
+ struct dcvs_core *core = &core_list[CPU_OFFSET + cpu];
ret = msm_dcvs_scm_set_algo_params(CPU_OFFSET + cpu,
new_params);
if (ret) {
@@ -574,6 +584,8 @@
mutex_unlock(¶m_update_mutex);
return ret;
}
+ if (cpu == 0)
+ check_power_collapse_modes(core);
}
memcpy(&curr_params, new_params,
sizeof(struct msm_dcvs_algo_param));
@@ -706,7 +718,7 @@
DCVS_ALGO_PARAM(slack_time_min_us)
DCVS_ALGO_PARAM(slack_time_max_us)
DCVS_ALGO_PARAM(slack_weight_thresh_pct)
-DCVS_ALGO_PARAM(ss_iobusy_conv)
+DCVS_ALGO_PARAM(ss_no_corr_below_freq)
DCVS_ALGO_PARAM(ss_win_size_min_us)
DCVS_ALGO_PARAM(ss_win_size_max_us)
DCVS_ALGO_PARAM(ss_util_pct)
@@ -892,7 +904,7 @@
DCVS_RW_ATTRIB(8, slack_weight_thresh_pct);
DCVS_RW_ATTRIB(9, slack_time_min_us);
DCVS_RW_ATTRIB(10, slack_time_max_us);
- DCVS_RW_ATTRIB(11, ss_iobusy_conv);
+ DCVS_RW_ATTRIB(11, ss_no_corr_below_freq);
DCVS_RW_ATTRIB(12, ss_win_size_min_us);
DCVS_RW_ATTRIB(13, ss_win_size_max_us);
DCVS_RW_ATTRIB(14, ss_util_pct);
diff --git a/arch/arm/mach-msm/msm_mpdecision.c b/arch/arm/mach-msm/msm_mpdecision.c
index 910804b..746bbe8 100644
--- a/arch/arm/mach-msm/msm_mpdecision.c
+++ b/arch/arm/mach-msm/msm_mpdecision.c
@@ -41,12 +41,14 @@
#include <trace/events/mpdcvs_trace.h>
#define DEFAULT_RQ_AVG_POLL_MS (1)
+#define DEFAULT_RQ_AVG_DIVIDE (25)
struct mpd_attrib {
struct kobj_attribute enabled;
struct kobj_attribute rq_avg_poll_ms;
- struct kobj_attribute iowait_threshold_pct;
+ struct kobj_attribute iowait_threshold_pct;
+ struct kobj_attribute rq_avg_divide;
struct kobj_attribute em_win_size_min_us;
struct kobj_attribute em_win_size_max_us;
struct kobj_attribute em_max_util_pct;
@@ -75,6 +77,7 @@
atomic_t algo_cpu_mask;
uint32_t rq_avg_poll_ms;
uint32_t iowait_threshold_pct;
+ uint32_t rq_avg_divide;
ktime_t next_update;
uint32_t slack_us;
struct msm_mpd_algo_param mp_param;
@@ -125,20 +128,19 @@
static int num_present_hundreds;
static ktime_t last_down_time;
-#define RQ_AVG_INSIGNIFICANT_BITS 3
static bool ok_to_update_tz(int nr, int last_nr)
{
/*
* Exclude unnecessary TZ reports if run queue haven't changed much from
- * the last reported value. The left shift by INSIGNIFICANT_BITS is to
+ * the last reported value. The divison by rq_avg_divide is to
* filter out small changes in the run queue average which won't cause
* a online cpu mask change. Also if the cpu online count does not match
* the count requested by TZ and we are not in the process of bringing
* cpus online as indicated by a HPUPDATE_IN_PROGRESS in msm_mpd.hpdata
*/
return
- (((nr >> RQ_AVG_INSIGNIFICANT_BITS)
- != (last_nr >> RQ_AVG_INSIGNIFICANT_BITS))
+ (((nr / msm_mpd.rq_avg_divide)
+ != (last_nr / msm_mpd.rq_avg_divide))
|| ((hweight32(atomic_read(&msm_mpd.algo_cpu_mask))
!= num_online_cpus())
&& (msm_mpd.hpupdate != HPUPDATE_IN_PROGRESS)));
@@ -509,6 +511,20 @@
return 0;
}
+static int msm_mpd_set_rq_avg_divide(uint32_t val)
+{
+ /*
+ * No need to do anything. New value will be used next time
+ * the decision is made as to whether to update tz.
+ */
+
+ if (val == 0)
+ return -EINVAL;
+
+ msm_mpd.rq_avg_divide = val;
+ return 0;
+}
+
#define MPD_ALGO_PARAM(_name, _param) \
static ssize_t msm_mpd_attr_##_name##_show(struct kobject *kobj, \
struct kobj_attribute *attr, char *buf) \
@@ -580,6 +596,7 @@
MPD_PARAM(enabled, msm_mpd.enabled);
MPD_PARAM(rq_avg_poll_ms, msm_mpd.rq_avg_poll_ms);
MPD_PARAM(iowait_threshold_pct, msm_mpd.iowait_threshold_pct);
+MPD_PARAM(rq_avg_divide, msm_mpd.rq_avg_divide);
MPD_ALGO_PARAM(em_win_size_min_us, msm_mpd.mp_param.em_win_size_min_us);
MPD_ALGO_PARAM(em_win_size_max_us, msm_mpd.mp_param.em_win_size_max_us);
MPD_ALGO_PARAM(em_max_util_pct, msm_mpd.mp_param.em_max_util_pct);
@@ -602,7 +619,7 @@
{
struct kobject *module_kobj = NULL;
int ret = 0;
- const int attr_count = 19;
+ const int attr_count = 20;
struct msm_mpd_algo_param *param = NULL;
param = pdev->dev.platform_data;
@@ -624,28 +641,30 @@
MPD_RW_ATTRIB(0, enabled);
MPD_RW_ATTRIB(1, rq_avg_poll_ms);
MPD_RW_ATTRIB(2, iowait_threshold_pct);
- MPD_RW_ATTRIB(3, em_win_size_min_us);
- MPD_RW_ATTRIB(4, em_win_size_max_us);
- MPD_RW_ATTRIB(5, em_max_util_pct);
- MPD_RW_ATTRIB(6, mp_em_rounding_point_min);
- MPD_RW_ATTRIB(7, mp_em_rounding_point_max);
- MPD_RW_ATTRIB(8, online_util_pct_min);
- MPD_RW_ATTRIB(9, online_util_pct_max);
- MPD_RW_ATTRIB(10, slack_time_min_us);
- MPD_RW_ATTRIB(11, slack_time_max_us);
- MPD_RW_ATTRIB(12, hp_up_max_ms);
- MPD_RW_ATTRIB(13, hp_up_ms);
- MPD_RW_ATTRIB(14, hp_up_count);
- MPD_RW_ATTRIB(15, hp_dw_max_ms);
- MPD_RW_ATTRIB(16, hp_dw_ms);
- MPD_RW_ATTRIB(17, hp_dw_count);
+ MPD_RW_ATTRIB(3, rq_avg_divide);
+ MPD_RW_ATTRIB(4, em_win_size_min_us);
+ MPD_RW_ATTRIB(5, em_win_size_max_us);
+ MPD_RW_ATTRIB(6, em_max_util_pct);
+ MPD_RW_ATTRIB(7, mp_em_rounding_point_min);
+ MPD_RW_ATTRIB(8, mp_em_rounding_point_max);
+ MPD_RW_ATTRIB(9, online_util_pct_min);
+ MPD_RW_ATTRIB(10, online_util_pct_max);
+ MPD_RW_ATTRIB(11, slack_time_min_us);
+ MPD_RW_ATTRIB(12, slack_time_max_us);
+ MPD_RW_ATTRIB(13, hp_up_max_ms);
+ MPD_RW_ATTRIB(14, hp_up_ms);
+ MPD_RW_ATTRIB(15, hp_up_count);
+ MPD_RW_ATTRIB(16, hp_dw_max_ms);
+ MPD_RW_ATTRIB(17, hp_dw_ms);
+ MPD_RW_ATTRIB(18, hp_dw_count);
- msm_mpd.attrib.attrib_group.attrs[18] = NULL;
+ msm_mpd.attrib.attrib_group.attrs[19] = NULL;
ret = sysfs_create_group(module_kobj, &msm_mpd.attrib.attrib_group);
if (ret)
pr_err("Unable to create sysfs objects :%d\n", ret);
msm_mpd.rq_avg_poll_ms = DEFAULT_RQ_AVG_POLL_MS;
+ msm_mpd.rq_avg_divide = DEFAULT_RQ_AVG_DIVIDE;
memcpy(&msm_mpd.mp_param, param, sizeof(struct msm_mpd_algo_param));
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 94632da..5e03aa8 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -195,15 +195,10 @@
void *ss_handle)
{
int ret;
- switch (code) {
- case SUBSYS_BEFORE_SHUTDOWN:
- pr_debug("%s: M-Notify: Shutdown started\n", __func__);
- ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
- SUBSYS_BEFORE_SHUTDOWN);
- if (ret < 0)
- pr_err("%s: sysmon_send_event error %d", __func__, ret);
- break;
- }
+ pr_debug("%s: M-Notify: event %lu\n", __func__, code);
+ ret = sysmon_send_event(SYSMON_SS_LPASS, "modem", code);
+ if (ret < 0)
+ pr_err("%s: sysmon_send_event error %d", __func__, ret);
return NOTIFY_DONE;
}
@@ -295,15 +290,8 @@
{
struct lpass_data *drv = subsys_to_lpass(subsys);
int ret = 0;
-
- if (get_restart_level() == RESET_SUBSYS_INDEPENDENT) {
- pr_debug("%s: Wait for ADSP power up!", __func__);
- msleep(10000);
- }
-
ret = pil_boot(&drv->q6->desc);
enable_irq(drv->wdog_irq);
-
return ret;
}
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index a353ce0..01f6787 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -130,7 +130,14 @@
int msm_spm_set_low_power_mode(unsigned int mode, bool notify_rpm);
int msm_spm_set_vdd(unsigned int cpu, unsigned int vlevel);
unsigned int msm_spm_get_vdd(unsigned int cpu);
+#if defined(CONFIG_MSM_SPM_V2)
int msm_spm_turn_on_cpu_rail(unsigned int cpu);
+#else
+static inline int msm_spm_turn_on_cpu_rail(unsigned int cpu)
+{
+ return -ENOSYS;
+}
+#endif
/* Internal low power management specific functions */
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8f3c107..8a75cd9 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -1160,7 +1160,6 @@
dbs_timer_exit(this_dbs_info);
mutex_lock(&dbs_mutex);
- mutex_destroy(&this_dbs_info->timer_mutex);
dbs_enable--;
/* If device is being removed, policy is no longer
* valid. */
@@ -1239,7 +1238,14 @@
static void __exit cpufreq_gov_dbs_exit(void)
{
+ unsigned int i;
+
cpufreq_unregister_governor(&cpufreq_gov_ondemand);
+ for_each_possible_cpu(i) {
+ struct cpu_dbs_info_s *this_dbs_info =
+ &per_cpu(od_cpu_dbs_info, i);
+ mutex_destroy(&this_dbs_info->timer_mutex);
+ }
destroy_workqueue(input_wq);
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 55597fc..24be1b0 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -884,8 +884,8 @@
if (adreno_of_read_property(node, "qcom,algo-ss-util-pct",
&info->algo_param.ss_util_pct))
goto err;
- if (adreno_of_read_property(node, "qcom,algo-ss-iobusy-conv",
- &info->algo_param.ss_iobusy_conv))
+ if (adreno_of_read_property(node, "qcom,algo-ss-no-corr-below-freq",
+ &info->algo_param.ss_no_corr_below_freq))
goto err;
if (adreno_of_read_property(node, "qcom,energy-active-coeff-a",
diff --git a/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c b/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c
index 4b0e7be..f779851 100644
--- a/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c
+++ b/drivers/media/dvb/mpq/adapter/mpq_stream_buffer.c
@@ -14,17 +14,47 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/uaccess.h>
#include "mpq_dvb_debug.h"
#include "mpq_stream_buffer.h"
-void mpq_streambuffer_init(
+
+
+int mpq_streambuffer_init(
struct mpq_streambuffer *sbuff,
- void *data_buff, size_t data_buff_len,
- void *packet_buff, size_t packet_buff_size)
+ enum mpq_streambuffer_mode mode,
+ struct mpq_streambuffer_buffer_desc *data_buffers,
+ u32 data_buff_num,
+ void *packet_buff,
+ size_t packet_buff_size)
{
- dvb_ringbuffer_init(&sbuff->raw_data, data_buff, data_buff_len);
+ if ((NULL == sbuff) || (NULL == data_buffers) || (NULL == packet_buff))
+ return -EINVAL;
+
+ if (data_buff_num > 1) {
+ if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR)
+ return -EINVAL;
+ /* Linear buffer group */
+ dvb_ringbuffer_init(
+ &sbuff->raw_data,
+ data_buffers,
+ data_buff_num *
+ sizeof(struct mpq_streambuffer_buffer_desc));
+ } else if (data_buff_num == 1) {
+ if (mode != MPQ_STREAMBUFFER_BUFFER_MODE_RING)
+ return -EINVAL;
+ /* Single ring-buffer */
+ dvb_ringbuffer_init(&sbuff->raw_data,
+ data_buffers[0].base, data_buffers[0].size);
+ }
+ sbuff->mode = mode;
+ sbuff->buffers = data_buffers;
+ sbuff->pending_buffers_count = 0;
+ sbuff->buffers_num = data_buff_num;
dvb_ringbuffer_init(&sbuff->packet_data, packet_buff, packet_buff_size);
+
+ return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_init);
@@ -87,34 +117,55 @@
int ret;
struct mpq_streambuffer_packet_header packet;
- if (dispose_data) {
- /* read-out the packet header first */
- ret = dvb_ringbuffer_pkt_read(
- &sbuff->packet_data,
- idx,
- 0,
- (u8 *)&packet,
- sizeof(struct mpq_streambuffer_packet_header));
+ if (NULL == sbuff)
+ return -EINVAL;
- if (ret != sizeof(struct mpq_streambuffer_packet_header))
- return -EINVAL;
+ /* read-out the packet header first */
+ ret = dvb_ringbuffer_pkt_read(&sbuff->packet_data, idx,
+ 0,
+ (u8 *)&packet,
+ sizeof(struct mpq_streambuffer_packet_header));
+ if (ret != sizeof(struct mpq_streambuffer_packet_header))
+ return -EINVAL;
+
+ if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) ||
+ (dispose_data)) {
/* Advance the read pointer in the raw-data buffer first */
- ret = mpq_streambuffer_data_read_dispose(
- sbuff,
- packet.raw_data_len);
+ ret = mpq_streambuffer_data_read_dispose(sbuff,
+ packet.raw_data_len);
if (ret != 0)
return ret;
}
+ /* Move read pointer to the next linear buffer for subsequent reads */
+ if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
+ (packet.raw_data_len > 0)) {
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+
+ desc->write_ptr = 0;
+ desc->read_ptr = 0;
+
+ DVB_RINGBUFFER_SKIP(&sbuff->raw_data,
+ sizeof(struct mpq_streambuffer_buffer_desc));
+ sbuff->pending_buffers_count--;
+
+ wake_up_all(&sbuff->raw_data.queue);
+ }
+
/* Now clear the packet from the packet header */
dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);
+ if (sbuff->cb)
+ sbuff->cb(sbuff, sbuff->cb_user_data);
+
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_pkt_dispose);
-
int mpq_streambuffer_pkt_write(
struct mpq_streambuffer *sbuff,
struct mpq_streambuffer_packet_header *packet,
@@ -123,30 +174,48 @@
ssize_t idx;
size_t len;
- len =
- sizeof(struct mpq_streambuffer_packet_header) +
+ if ((NULL == sbuff) || (NULL == packet))
+ return -EINVAL;
+
+ MPQ_DVB_DBG_PRINT(
+ "%s: handle=%d, offset=%d, len=%d\n",
+ __func__,
+ packet->raw_data_handle,
+ packet->raw_data_offset,
+ packet->raw_data_len);
+
+ len = sizeof(struct mpq_streambuffer_packet_header) +
packet->user_data_len;
/* Make sure enough space available for packet header */
if (dvb_ringbuffer_free(&sbuff->packet_data) < len)
return -ENOSPC;
- /* Starting writting packet header */
+ /* Starting writing packet header */
idx = dvb_ringbuffer_pkt_start(&sbuff->packet_data, len);
/* Write non-user private data header */
- dvb_ringbuffer_write(
- &sbuff->packet_data,
- (u8 *)packet,
- sizeof(struct mpq_streambuffer_packet_header));
+ dvb_ringbuffer_write(&sbuff->packet_data,
+ (u8 *)packet,
+ sizeof(struct mpq_streambuffer_packet_header));
/* Write user's own private data header */
dvb_ringbuffer_write(&sbuff->packet_data,
- user_data,
- packet->user_data_len);
+ user_data,
+ packet->user_data_len);
dvb_ringbuffer_pkt_close(&sbuff->packet_data, idx);
+ /* Move write pointer to next linear buffer for subsequent writes */
+ if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
+ (packet->raw_data_len > 0)) {
+ if (sbuff->pending_buffers_count == sbuff->buffers_num)
+ return -ENOSPC;
+ DVB_RINGBUFFER_PUSH(&sbuff->raw_data,
+ sizeof(struct mpq_streambuffer_buffer_desc));
+ sbuff->pending_buffers_count++;
+ }
+
wake_up_all(&sbuff->packet_data.queue);
return 0;
@@ -160,11 +229,52 @@
{
int res;
- if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
- return -ENOSPC;
+ if ((NULL == sbuff) || (NULL == buf))
+ return -EINVAL;
- res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len);
- wake_up_all(&sbuff->raw_data.queue);
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
+ return -ENOSPC;
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == sbuff->raw_data.data)
+ return -EPERM;
+ res = dvb_ringbuffer_write(&sbuff->raw_data, buf, len);
+ wake_up_all(&sbuff->raw_data.queue);
+ } else {
+ /* Linear buffer group */
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pwrite];
+
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == desc->base)
+ return -EPERM;
+
+ if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
+ ((desc->size - desc->write_ptr) < len)) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: No space available! %d pending buffers out of %d total buffers. write_ptr=%d, size=%d\n",
+ __func__,
+ sbuff->pending_buffers_count,
+ sbuff->buffers_num,
+ desc->write_ptr,
+ desc->size);
+ return -ENOSPC;
+ }
+ memcpy(desc->base + desc->write_ptr, buf, len);
+ desc->write_ptr += len;
+ MPQ_DVB_DBG_PRINT(
+ "%s: copied %d data bytes. handle=%d, write_ptr=%d\n",
+ __func__, len, desc->handle, desc->write_ptr);
+ res = len;
+ }
return res;
}
@@ -175,50 +285,244 @@
struct mpq_streambuffer *sbuff,
size_t len)
{
+ if (NULL == sbuff)
+ return -EINVAL;
+
if (unlikely(dvb_ringbuffer_free(&sbuff->raw_data) < len))
return -ENOSPC;
- sbuff->raw_data.pwrite =
- (sbuff->raw_data.pwrite+len) % sbuff->raw_data.size;
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ DVB_RINGBUFFER_PUSH(&sbuff->raw_data, len);
+ wake_up_all(&sbuff->raw_data.queue);
+ } else {
+ /* Linear buffer group */
+ struct mpq_streambuffer_buffer_desc *desc;
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pwrite];
- wake_up_all(&sbuff->raw_data.queue);
+ if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
+ ((desc->size - desc->write_ptr) < len)) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: No space available!\n",
+ __func__);
+ return -ENOSPC;
+ }
+ desc->write_ptr += len;
+ }
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_data_write_deposit);
-size_t mpq_streambuffer_data_read(
+ssize_t mpq_streambuffer_data_read(
struct mpq_streambuffer *sbuff,
u8 *buf, size_t len)
{
- ssize_t actual_len;
+ ssize_t actual_len = 0;
- actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
- if (actual_len < len)
- len = actual_len;
+ if ((NULL == sbuff) || (NULL == buf))
+ return -EINVAL;
- if (len)
- dvb_ringbuffer_read(&sbuff->raw_data, buf, len);
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == sbuff->raw_data.data)
+ return -EPERM;
- wake_up_all(&sbuff->raw_data.queue);
+ actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
+ if (actual_len < len)
+ len = actual_len;
+ if (len)
+ dvb_ringbuffer_read(&sbuff->raw_data, buf, len);
+
+ wake_up_all(&sbuff->raw_data.queue);
+ } else {
+ /* Linear buffer group */
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == desc->base)
+ return -EPERM;
+
+ actual_len = (desc->write_ptr - desc->read_ptr);
+ if (actual_len < len)
+ len = actual_len;
+ memcpy(buf, desc->base + desc->read_ptr, len);
+ desc->read_ptr += len;
+ }
return len;
}
EXPORT_SYMBOL(mpq_streambuffer_data_read);
+ssize_t mpq_streambuffer_data_read_user(
+ struct mpq_streambuffer *sbuff,
+ u8 __user *buf, size_t len)
+{
+ ssize_t actual_len = 0;
+
+ if ((NULL == sbuff) || (NULL == buf))
+ return -EINVAL;
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == sbuff->raw_data.data)
+ return -EPERM;
+
+ actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
+ if (actual_len < len)
+ len = actual_len;
+ if (len)
+ dvb_ringbuffer_read_user(&sbuff->raw_data, buf, len);
+ wake_up_all(&sbuff->raw_data.queue);
+ } else {
+ /* Linear buffer group */
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+
+ /*
+ * Secure buffers are not permitted to be mapped into kernel
+ * memory, and so buffer base address may be NULL
+ */
+ if (NULL == desc->base)
+ return -EPERM;
+
+ actual_len = (desc->write_ptr - desc->read_ptr);
+ if (actual_len < len)
+ len = actual_len;
+ if (copy_to_user(buf, desc->base + desc->read_ptr, len))
+ return -EFAULT;
+ desc->read_ptr += len;
+ }
+
+ return len;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_read_user);
+
+
int mpq_streambuffer_data_read_dispose(
struct mpq_streambuffer *sbuff,
size_t len)
{
- if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
+ if (NULL == sbuff)
return -EINVAL;
- DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
+ return -EINVAL;
- wake_up_all(&sbuff->raw_data.queue);
+ DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
+ wake_up_all(&sbuff->raw_data.queue);
+ } else {
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+ if ((desc->read_ptr + len) > desc->size)
+ desc->read_ptr = desc->size;
+ else
+ desc->read_ptr += len;
+ }
+
return 0;
}
EXPORT_SYMBOL(mpq_streambuffer_data_read_dispose);
+
+int mpq_streambuffer_get_buffer_handle(
+ struct mpq_streambuffer *sbuff,
+ int read_buffer,
+ int *handle)
+{
+ struct mpq_streambuffer_buffer_desc *desc = NULL;
+
+ if ((NULL == sbuff) || (NULL == handle))
+ return -EINVAL;
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
+ *handle = sbuff->buffers[0].handle;
+ } else {
+ if (read_buffer)
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+ else
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pwrite];
+ *handle = desc->handle;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_get_buffer_handle);
+
+
+int mpq_streambuffer_register_pkt_dispose(
+ struct mpq_streambuffer *sbuff,
+ mpq_streambuffer_pkt_dispose_cb cb_func,
+ void *user_data)
+{
+ if ((NULL == sbuff) || (NULL == cb_func))
+ return -EINVAL;
+
+ sbuff->cb = cb_func;
+ sbuff->cb_user_data = user_data;
+
+ return 0;
+}
+EXPORT_SYMBOL(mpq_streambuffer_register_pkt_dispose);
+
+
+ssize_t mpq_streambuffer_data_free(
+ struct mpq_streambuffer *sbuff)
+{
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ if (NULL == sbuff)
+ return -EINVAL;
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
+ return dvb_ringbuffer_free(&sbuff->raw_data);
+
+ if (sbuff->pending_buffers_count == sbuff->buffers_num)
+ return 0;
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pwrite];
+
+ return desc->size - desc->write_ptr;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_free);
+
+
+ssize_t mpq_streambuffer_data_avail(
+ struct mpq_streambuffer *sbuff)
+{
+ struct mpq_streambuffer_buffer_desc *desc;
+
+ if (NULL == sbuff)
+ return -EINVAL;
+
+ if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode)
+ return dvb_ringbuffer_avail(&sbuff->raw_data);
+
+ desc = (struct mpq_streambuffer_buffer_desc *)
+ &sbuff->raw_data.data[sbuff->raw_data.pread];
+
+ return desc->write_ptr - desc->read_ptr;
+}
+EXPORT_SYMBOL(mpq_streambuffer_data_avail);
+
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index e2ef6a0..2a60840 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
+#include <linux/file.h>
#include "mpq_dvb_debug.h"
#include "mpq_dmx_plugin_common.h"
@@ -983,6 +984,19 @@
goto init_failed_free_payload_buffer;
}
+ feed_data->buffer_desc.read_ptr = 0;
+ feed_data->buffer_desc.write_ptr = 0;
+ feed_data->buffer_desc.base = payload_buffer;
+ feed_data->buffer_desc.size = actual_buffer_size;
+ feed_data->buffer_desc.handle =
+ ion_share_dma_buf(
+ mpq_demux->ion_client,
+ feed_data->payload_buff_handle);
+ if (feed_data->buffer_desc.handle < 0) {
+ ret = -EFAULT;
+ goto init_failed_unmap_payload_buffer;
+ }
+
/* Register the new stream-buffer interface to MPQ adapter */
switch (feed->pes_type) {
case DMX_TS_PES_VIDEO0:
@@ -1011,7 +1025,7 @@
__func__,
feed->pes_type);
ret = -EINVAL;
- goto init_failed_unmap_payload_buffer;
+ goto init_failed_unshare_payload_buffer;
}
/* make sure not occupied already */
@@ -1025,30 +1039,36 @@
__func__,
feed_data->stream_interface);
ret = -EBUSY;
- goto init_failed_unmap_payload_buffer;
+ goto init_failed_unshare_payload_buffer;
}
feed_data->video_buffer =
&mpq_dmx_info.decoder_buffers[feed_data->stream_interface];
- mpq_streambuffer_init(
- feed_data->video_buffer,
- payload_buffer,
- actual_buffer_size,
- packet_buffer,
- VIDEO_META_DATA_BUFFER_SIZE);
+ ret = mpq_streambuffer_init(
+ feed_data->video_buffer,
+ MPQ_STREAMBUFFER_BUFFER_MODE_RING,
+ &feed_data->buffer_desc,
+ 1,
+ packet_buffer,
+ VIDEO_META_DATA_BUFFER_SIZE);
+ if (ret < 0) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: mpq_streambuffer_init failed, err = %d\n",
+ __func__, ret);
+ goto init_failed_unshare_payload_buffer;
+ }
- ret =
- mpq_adapter_register_stream_if(
- feed_data->stream_interface,
- feed_data->video_buffer);
+ ret = mpq_adapter_register_stream_if(
+ feed_data->stream_interface,
+ feed_data->video_buffer);
if (ret < 0) {
MPQ_DVB_ERR_PRINT(
"%s: mpq_adapter_register_stream_if failed, "
"err = %d\n",
__func__, ret);
- goto init_failed_unmap_payload_buffer;
+ goto init_failed_unshare_payload_buffer;
}
feed->buffer_size = actual_buffer_size;
@@ -1067,7 +1087,13 @@
sizeof(struct mpq_framing_prefix_size_masks));
feed_data->first_pattern_offset = 0;
feed_data->first_prefix_size = 0;
- feed_data->write_pts_dts = 0;
+ feed_data->saved_pts_dts_info.pts_exist = 0;
+ feed_data->saved_pts_dts_info.dts_exist = 0;
+ feed_data->new_pts_dts_info.pts_exist = 0;
+ feed_data->new_pts_dts_info.dts_exist = 0;
+ feed_data->saved_info_used = 1;
+ feed_data->new_info_exists = 0;
+ feed_data->first_pts_dts_copy = 1;
spin_lock(&mpq_demux->feed_lock);
feed->priv = (void *)feed_data;
@@ -1075,6 +1101,8 @@
return 0;
+init_failed_unshare_payload_buffer:
+ put_unused_fd(feed_data->buffer_desc.handle);
init_failed_unmap_payload_buffer:
ion_unmap_kernel(mpq_demux->ion_client,
feed_data->payload_buff_handle);
@@ -1119,6 +1147,8 @@
vfree(feed_data->video_buffer->packet_data.data);
+ put_unused_fd(feed_data->buffer_desc.handle);
+
ion_unmap_kernel(mpq_demux->ion_client,
feed_data->payload_buff_handle);
@@ -1338,6 +1368,83 @@
return 0;
}
+static inline void mpq_dmx_save_pts_dts(struct mpq_video_feed_info *feed_data)
+{
+ if (feed_data->new_info_exists) {
+ feed_data->saved_pts_dts_info.pts_exist =
+ feed_data->new_pts_dts_info.pts_exist;
+ feed_data->saved_pts_dts_info.pts =
+ feed_data->new_pts_dts_info.pts;
+ feed_data->saved_pts_dts_info.dts_exist =
+ feed_data->new_pts_dts_info.dts_exist;
+ feed_data->saved_pts_dts_info.dts =
+ feed_data->new_pts_dts_info.dts;
+
+ feed_data->new_info_exists = 0;
+ feed_data->saved_info_used = 0;
+ }
+}
+
+static inline void mpq_dmx_write_pts_dts(struct mpq_video_feed_info *feed_data,
+ struct dmx_pts_dts_info *info)
+{
+ if (!feed_data->saved_info_used) {
+ info->pts_exist = feed_data->saved_pts_dts_info.pts_exist;
+ info->pts = feed_data->saved_pts_dts_info.pts;
+ info->dts_exist = feed_data->saved_pts_dts_info.dts_exist;
+ info->dts = feed_data->saved_pts_dts_info.dts;
+
+ feed_data->saved_info_used = 1;
+ } else {
+ info->pts_exist = 0;
+ info->dts_exist = 0;
+ }
+}
+
+static inline void mpq_dmx_get_pts_dts(struct mpq_video_feed_info *feed_data,
+ struct pes_packet_header *pes_header)
+{
+ struct dmx_pts_dts_info *info = &(feed_data->new_pts_dts_info);
+
+ /* Get PTS/DTS information from PES header */
+
+ if ((pes_header->pts_dts_flag == 2) ||
+ (pes_header->pts_dts_flag == 3)) {
+ info->pts_exist = 1;
+
+ info->pts =
+ ((u64)pes_header->pts_1 << 30) |
+ ((u64)pes_header->pts_2 << 22) |
+ ((u64)pes_header->pts_3 << 15) |
+ ((u64)pes_header->pts_4 << 7) |
+ (u64)pes_header->pts_5;
+ } else {
+ info->pts_exist = 0;
+ info->pts = 0;
+ }
+
+ if (pes_header->pts_dts_flag == 3) {
+ info->dts_exist = 1;
+
+ info->dts =
+ ((u64)pes_header->dts_1 << 30) |
+ ((u64)pes_header->dts_2 << 22) |
+ ((u64)pes_header->dts_3 << 15) |
+ ((u64)pes_header->dts_4 << 7) |
+ (u64)pes_header->dts_5;
+ } else {
+ info->dts_exist = 0;
+ info->dts = 0;
+ }
+
+ feed_data->new_info_exists = 1;
+
+ if (feed_data->first_pts_dts_copy) {
+ mpq_dmx_save_pts_dts(feed_data);
+ feed_data->first_pts_dts_copy = 0;
+ }
+}
+
static inline int mpq_dmx_parse_remaining_pes_header(
struct dvb_demux_feed *feed,
struct mpq_video_feed_info *feed_data,
@@ -1381,7 +1488,6 @@
/* else - we have the PTS */
*bytes_avail -= copy_len;
*ts_payload_offset += copy_len;
- feed_data->write_pts_dts = 1;
}
/* Did we capture the DTS value (if exist)? */
@@ -1412,7 +1518,6 @@
/* else - we have the DTS */
*bytes_avail -= copy_len;
*ts_payload_offset += copy_len;
- feed_data->write_pts_dts = 1;
}
/* Any more header bytes?! */
@@ -1421,6 +1526,9 @@
return -EINVAL;
}
+ /* get PTS/DTS information from PES header to be written later */
+ mpq_dmx_get_pts_dts(feed_data, pes_header);
+
/* Got PES header, process payload */
*bytes_avail -= feed_data->pes_header_left_bytes;
*ts_payload_offset += feed_data->pes_header_left_bytes;
@@ -1429,53 +1537,6 @@
return 0;
}
-static inline void mpq_dmx_get_pts_dts(struct mpq_video_feed_info *feed_data,
- struct pes_packet_header *pes_header,
- struct mpq_adapter_video_meta_data *meta_data,
- enum dmx_packet_type packet_type)
-{
- struct dmx_pts_dts_info *info;
-
- if (packet_type == DMX_PES_PACKET)
- info = &(meta_data->info.pes.pts_dts_info);
- else
- info = &(meta_data->info.framing.pts_dts_info);
-
- if (feed_data->write_pts_dts) {
- if ((pes_header->pts_dts_flag == 2) ||
- (pes_header->pts_dts_flag == 3)) {
- info->pts_exist = 1;
-
- info->pts =
- ((u64)pes_header->pts_1 << 30) |
- ((u64)pes_header->pts_2 << 22) |
- ((u64)pes_header->pts_3 << 15) |
- ((u64)pes_header->pts_4 << 7) |
- (u64)pes_header->pts_5;
- } else {
- info->pts_exist = 0;
- info->pts = 0;
- }
-
- if (pes_header->pts_dts_flag == 3) {
- info->dts_exist = 1;
-
- info->dts =
- ((u64)pes_header->dts_1 << 30) |
- ((u64)pes_header->dts_2 << 22) |
- ((u64)pes_header->dts_3 << 15) |
- ((u64)pes_header->dts_4 << 7) |
- (u64)pes_header->dts_5;
- } else {
- info->dts_exist = 0;
- info->dts = 0;
- }
- } else {
- info->pts_exist = 0;
- info->dts_exist = 0;
- }
-}
-
static int mpq_dmx_process_video_packet_framing(
struct dvb_demux_feed *feed,
const u8 *buf)
@@ -1550,7 +1611,6 @@
feed_data->pes_header_offset = 0;
feed_data->pes_header_left_bytes =
PES_MANDATORY_FIELDS_LEN;
- feed_data->write_pts_dts = 0;
} else {
feed->pusi_seen = 1;
}
@@ -1692,6 +1752,8 @@
feed->peslen += bytes_avail;
meta_data.packet_type = DMX_FRAMING_INFO_PACKET;
+ packet.raw_data_handle = feed_data->buffer_desc.handle;
+ packet.raw_data_offset = 0;
packet.user_data_len =
sizeof(struct mpq_adapter_video_meta_data);
@@ -1701,10 +1763,10 @@
feed->indexing_params.standard,
feed_data->last_framing_match_type);
if (is_video_frame == 1) {
- mpq_dmx_get_pts_dts(feed_data,
- pes_header,
- &meta_data,
- DMX_FRAMING_INFO_PACKET);
+ mpq_dmx_write_pts_dts(feed_data,
+ &(meta_data.info.framing.
+ pts_dts_info));
+ mpq_dmx_save_pts_dts(feed_data);
} else {
meta_data.info.framing.
pts_dts_info.pts_exist = 0;
@@ -1717,8 +1779,6 @@
*/
meta_data.info.framing.pattern_type =
feed_data->last_framing_match_type;
- packet.raw_data_addr =
- feed_data->last_framing_match_address;
pattern_addr = feed_data->pes_payload_address +
framing_res.info[i].offset -
@@ -1742,10 +1802,8 @@
feed_data->first_pattern_offset;
}
- MPQ_DVB_DBG_PRINT("Writing Packet: "
- "addr = 0x%X, len = %d, type = %d, "
- "isPts = %d, isDts = %d\n",
- packet.raw_data_addr,
+ MPQ_DVB_DBG_PRINT(
+ "Writing Packet: len = %d, type = %d, isPts = %d, isDts = %d\n",
packet.raw_data_len,
meta_data.info.framing.pattern_type,
meta_data.info.framing.
@@ -1754,16 +1812,11 @@
pts_dts_info.dts_exist);
if (mpq_streambuffer_pkt_write(stream_buffer,
- &packet,
- (u8 *)&meta_data) < 0) {
- MPQ_DVB_ERR_PRINT(
- "%s: "
- "Couldn't write packet. "
- "Should never happen\n",
+ &packet,
+ (u8 *)&meta_data) < 0) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: Couldn't write packet. Should never happen\n",
__func__);
- } else {
- if (is_video_frame == 1)
- feed_data->write_pts_dts = 0;
}
}
@@ -1855,18 +1908,17 @@
*/
if (0 == feed_data->pes_header_left_bytes) {
- packet.raw_data_addr =
- feed_data->pes_payload_address;
-
packet.raw_data_len = feed->peslen;
-
+ packet.raw_data_handle =
+ feed_data->buffer_desc.handle;
+ packet.raw_data_offset = 0;
packet.user_data_len =
sizeof(struct
mpq_adapter_video_meta_data);
- mpq_dmx_get_pts_dts(feed_data, pes_header,
- &meta_data,
- DMX_PES_PACKET);
+ mpq_dmx_write_pts_dts(feed_data,
+ &(meta_data.info.pes.pts_dts_info));
+ mpq_dmx_save_pts_dts(feed_data);
meta_data.packet_type = DMX_PES_PACKET;
@@ -1879,8 +1931,6 @@
"Couldn't write packet. "
"Should never happen\n",
__func__);
- else
- feed_data->write_pts_dts = 0;
} else {
MPQ_DVB_ERR_PRINT(
"%s: received PUSI"
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 69305b6..f7af1ef 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -275,6 +275,7 @@
* @plugin_data: Underlying plugin's own private data.
* @video_buffer: Holds the streamer buffer shared with
* the decoder for feeds having the data going to the decoder.
+ * @buffer_desc: Holds decoder buffer(s) information used for stream buffer.
* @pes_header: Used for feeds that output data to decoder,
* holds PES header of current processed PES.
* @pes_header_left_bytes: Used for feeds that output data to decoder,
@@ -308,14 +309,18 @@
* to the stream buffer.
* @first_prefix_size: used to save the prefix size used to find the first
* pattern written to the stream buffer.
- * @write_pts_dts: Flag used to decide if to write PTS/DTS information
- * (if it is available in the PES header) in the meta-data passed
- * to the video decoder. PTS/DTS information is written in the first
- * packet after it is available.
+ * @saved_pts_dts_info: used to save PTS/DTS information until it is written.
+ * @new_pts_dts_info: used to store PTS/DTS information from current PES header.
+ * @saved_info_used: indicates if saved PTS/DTS information was used.
+ * @new_info_exists: indicates if new PTS/DTS information exists in
+ * new_pts_dts_info that should be saved to saved_pts_dts_info.
+ * @first_pts_dts_copy: a flag used to indicate if PTS/DTS information needs
+ * to be copied from the currently parsed PES header to the saved_pts_dts_info.
*/
struct mpq_video_feed_info {
void *plugin_data;
struct mpq_streambuffer *video_buffer;
+ struct mpq_streambuffer_buffer_desc buffer_desc;
struct pes_packet_header pes_header;
u32 pes_header_left_bytes;
u32 pes_header_offset;
@@ -331,7 +336,11 @@
struct mpq_framing_prefix_size_masks prefix_size;
u32 first_pattern_offset;
u32 first_prefix_size;
- int write_pts_dts;
+ struct dmx_pts_dts_info saved_pts_dts_info;
+ struct dmx_pts_dts_info new_pts_dts_info;
+ int saved_info_used;
+ int new_info_exists;
+ int first_pts_dts_copy;
};
/**
diff --git a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h b/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
index 4ea4222..9476c73 100644
--- a/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
+++ b/drivers/media/dvb/mpq/include/mpq_stream_buffer.h
@@ -19,7 +19,7 @@
/**
* DOC: MPQ Stream Buffer
*
- * A stream buffer implmenetation used to transfer data between two units
+ * A stream buffer implementation is used to transfer data between two units
* such as demux and decoders. The implementation relies on dvb_ringbuffer
* implementation. Refer to dvb_ringbuffer.h for details.
*
@@ -28,8 +28,19 @@
* meta-data (information from PES header for example).
*
* The meta-data uses dvb_ringbuffer packet interface. Each meta-data
- * packet hold the address and size of raw-data described by the
- * meta-data packet, in addition to user's own parameters if any required.
+ * packet points to the data buffer, and includes the offset to the data in the
+ * buffer, the size of raw-data described by the meta-data packet, and also the
+ * size of user's own parameters if any required.
+ *
+ * Data can be managed in two ways: ring-buffer & linear buffers, as specified
+ * in initialization when calling the mpq_streambuffer_init function.
+ * For managing data as a ring buffer exactly 1 data buffer descriptor must be
+ * specified in initialization. For this mode, dvb_ringbuffer is used "as-is".
+ * For managing data in several linear buffers, an array of buffer descriptors
+ * must be passed.
+ * For both modes, data descriptor(s) must be remain valid throughout the life
+ * span of the mpq_streambuffer object.
+ * Apart from initialization API remains the same for both modes.
*
* Contrary to dvb_ringbuffer implementation, this API makes sure there's
* enough data to read/write when making read/write operations.
@@ -44,18 +55,22 @@
*
* Typical call flow from producer:
*
- * - Start writting the raw-data of new packet, the following call is
+ * - Start writing the raw-data of new packet, the following call is
* repeated until end of data of the specific packet
*
- * mpq_streambuffer_data_write(...)
+ * mpq_streambuffer_data_write(...)
*
* - Now write a new packet describing the new available raw-data
- * mpq_streambuffer_pkt_write(...)
+ * mpq_streambuffer_pkt_write(...)
+ *
+ * For linear buffer mode, writing a new packet with data size > 0, causes the
+ * current buffer to be marked as pending for reading, and triggers moving to
+ * the next available buffer, that shall now be the current write buffer.
*
* Typical call flow from consumer:
*
* - Poll for next available packet:
- * mpq_streambuffer_pkt_next(&streambuff,-1)
+ * mpq_streambuffer_pkt_next(&streambuff,-1,&len)
*
* In different approach, consumer can wait on event for new data and then
* call mpq_streambuffer_pkt_next, waiting for data can be done as follows:
@@ -77,58 +92,126 @@
* data buffer, the amount of raw-data is provided part of the
* packet's information. User should then call mpq_streambuffer_pkt_dispose
* with dispose_data set to 0 as the raw-data was already disposed.
+ * Note that secure buffer cannot be accessed directly and an error will
+ * occur.
*
* 2. Access the data directly using the raw-data address. The address
* of the raw data is provided part of the packet's information. User
* then should call mpq_streambuffer_pkt_dispose with dispose_data set
* to 1 to dispose the packet along with it's raw-data.
+ *
+ * - Disposal of packets:
+ * mpq_streambuffer_pkt_dispose(...)
+ *
+ * For linear buffer mode, disposing of a packet with data size > 0, causes
+ * the current buffer to be marked as free for writing, and triggers moving to
+ * the next available buffer, that shall now be the current read buffer.
+
+ *
*/
+struct mpq_streambuffer;
+
+typedef void (*mpq_streambuffer_pkt_dispose_cb) (
+ struct mpq_streambuffer *sbuff,
+ void *user_data);
+
+enum mpq_streambuffer_mode {
+ MPQ_STREAMBUFFER_BUFFER_MODE_RING,
+ MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR
+};
+
/**
* struct mpq_streambuffer - mpq stream buffer representation
*
- * @raw_data: The buffer used to hold the raw-data
+ * @raw_data: The buffer used to hold raw-data, or linear buffer descriptors
* @packet_data: The buffer user to hold the meta-data
+ * @buffers: array of buffer descriptor(s) holding buffer initial & dynamic
+ * buffer information
+ * @mode: mpq_streambuffer buffer management work mode - Ring-buffer or Linear
+ * buffers
+ * @buffers_num: number of data buffers to manage
+ * @pending_buffers_count: for linear buffer management, counts the number of
+ * buffer that has been
*/
struct mpq_streambuffer {
struct dvb_ringbuffer raw_data;
struct dvb_ringbuffer packet_data;
+ struct mpq_streambuffer_buffer_desc *buffers;
+ enum mpq_streambuffer_mode mode;
+ u32 buffers_num;
+ u32 pending_buffers_count;
+ mpq_streambuffer_pkt_dispose_cb cb;
+ void *cb_user_data;
+};
+
+/**
+ * mpq_streambuffer_linear_desc
+ * @handle: ION handle's file descriptor of buffer
+ * @base: kernel mapped address to start of buffer.
+ * Can be NULL for secured buffers
+ * @size: size of buffer
+ * @read_ptr: initial read pointer value (should normally be 0)
+ * @write_ptr: initial write pointer value (should normally be 0)
+ */
+struct mpq_streambuffer_buffer_desc {
+ int handle;
+ void *base;
+ u32 size;
+ u32 read_ptr;
+ u32 write_ptr;
};
/**
* struct mpq_streambuffer_packet_header - packet header saved in packet buffer
* @user_data_len: length of private user (meta) data
- * @raw_data_addr: raw-data address in the raw-buffer described by the packet
+ * @raw_data_handle: ION handle's file descriptor of raw-data buffer
+ * @raw_data_offset: offset of raw-data from start of buffer (0 for linear)
* @raw_data_len: size of raw-data in the raw-data buffer (can be 0)
*
* The packet structure that is saved in each packet-buffer:
* user_data_len
- * raw_data_addr
+ * raw_data_handle
+ * raw_data_offset
* raw_data_len
* private user-data bytes
*/
struct mpq_streambuffer_packet_header {
u32 user_data_len;
- u32 raw_data_addr;
- u32 raw_data_len;
+ int raw_data_handle;
+ u32 raw_data_offset;
+ u32 raw_data_len;
} __packed;
/**
* mpq_streambuffer_init - Initialize a new stream buffer
*
* @sbuff: The buffer to initialize
- * @data_buff: The buffer holding raw-data
- * @data_buff_len: Size of raw-data buffer
+ * @data_buffers: array of data buffer descriptor(s).
+ * Data descriptor(s) must be remain valid throughout the life
+ * span of the mpq_streambuffer object
+ * @data_buff_num: number of data buffer in array
* @packet_buff: The buffer holding meta-data
* @packet_buff_size: Size of meta-data buffer
+ *
+ * Return Error status, -EINVAL if any of the arguments are invalid
+ *
+ * Note:
+ * for data_buff_num > 1, mpq_streambuffer object manages these buffers as a
+ * separated set of linear buffers. A linear buffer cannot wrap-around and one
+ * can only write as many data bytes as the buffer's size. Data will not be
+ * written to the next free buffer.
*/
-void mpq_streambuffer_init(
+int mpq_streambuffer_init(
struct mpq_streambuffer *sbuff,
- void *data_buff, size_t data_buff_len,
- void *packet_buff, size_t packet_buff_size);
+ enum mpq_streambuffer_mode mode,
+ struct mpq_streambuffer_buffer_desc *data_buffers,
+ u32 data_buff_num,
+ void *packet_buff,
+ size_t packet_buff_size);
/**
- * mpq_streambuffer_packet_next - Returns index of next avaialble packet.
+ * mpq_streambuffer_packet_next - Returns index of next available packet.
*
* @sbuff: The stream buffer
* @idx: Previous packet index or -1 to return index of the the first
@@ -234,19 +317,29 @@
* @buf: The buffer to read the raw-data data to
* @len: The length of the buffer that will hold the raw-data
*
- * Return The actual number of bytes read
+ * Return The actual number of bytes read or error code
*
- * This fucntion copies the data from the ring-buffer to the
+ * This function copies the data from the ring-buffer to the
* provided buf parameter. The user can save the extra copy by accessing
* the data pointer directly and reading from it, then update the
* read pointer by the amount of data that was read using
* mpq_streambuffer_data_read_dispose
*/
-size_t mpq_streambuffer_data_read(
+ssize_t mpq_streambuffer_data_read(
struct mpq_streambuffer *sbuff,
u8 *buf, size_t len);
/**
+ * mpq_streambuffer_data_read_user
+ *
+ * Same as mpq_streambuffer_data_read except data can be copied to user-space
+ * buffer.
+ */
+ssize_t mpq_streambuffer_data_read_user(
+ struct mpq_streambuffer *sbuff,
+ u8 __user *buf, size_t len);
+
+/**
* mpq_streambuffer_data_read_dispose - Advances the raw-buffer read pointer.
* Assumes the raw-data was read by the user directly.
*
@@ -256,12 +349,69 @@
* Return error status, -EINVAL if buffer there's no enough data to
* be disposed
*
- * The user can instead dipose a packet along with the data in the
+ * The user can instead dispose a packet along with the data in the
* raw-data buffer using mpq_streambuffer_pkt_dispose.
*/
int mpq_streambuffer_data_read_dispose(
struct mpq_streambuffer *sbuff,
size_t len);
+/**
+ * mpq_streambuffer_get_buffer_handle - Returns the current linear buffer
+ * ION handle.
+ * @sbuff: The stream buffer
+ * @read_buffer: specifies if a read buffer handle is requested (when set),
+ * or a write buffer handle is requested.
+ * For linear buffer mode read & write buffers may be different
+ * buffers. For ring buffer mode, the same (single) buffer handle
+ * is returned.
+ * buffer handle
+ * @handle: returned handle
+ *
+ * Return error status
+ * -EINVAL is arguments are invalid.
+ * -EPERM if stream buffer specified was not initialized with linear support.
+ */
+int mpq_streambuffer_get_buffer_handle(
+ struct mpq_streambuffer *sbuff,
+ int read_buffer,
+ int *handle);
+
+/**
+ * mpq_streambuffer_data_free - Returns number of free bytes in data buffer.
+ * @sbuff: The stream buffer object
+ *
+ * Note: for linear buffer management this return number of free bytes in the
+ * current write buffer only.
+ */
+ssize_t mpq_streambuffer_data_free(
+ struct mpq_streambuffer *sbuff);
+
+/**
+ * mpq_streambuffer_data_avail - Returns number of bytes in data buffer that
+ * can be read.
+ * @sbuff: The stream buffer object
+ *
+ * Note: for linear buffer management this return number of data bytes in the
+ * current read buffer only.
+ */
+ssize_t mpq_streambuffer_data_avail(
+ struct mpq_streambuffer *sbuff);
+
+/**
+ * mpq_streambuffer_register_pkt_dispose - Registers a callback to notify on
+ * packet disposal events.
+ * can be read.
+ * @sbuff: The stream buffer object
+ * @cb_func: user callback function
+ * @user_data: user data to be passed to callback function.
+ *
+ * Returns error status
+ * -EINVAL if arguments are invalid
+ */
+int mpq_streambuffer_register_pkt_dispose(
+ struct mpq_streambuffer *sbuff,
+ mpq_streambuffer_pkt_dispose_cb cb_func,
+ void *user_data);
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index f61b74f..af31748 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -1445,9 +1445,10 @@
/*so that it isn't closed again*/
pmctl->mctl_release = NULL;
}
- msm_cam_server_send_error_evt(pmctl,
- V4L2_EVENT_PRIVATE_START +
- MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+ if (pmctl)
+ msm_cam_server_send_error_evt(pmctl,
+ V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_APP_NOTIFY_ERROR_EVENT);
}
}
sub.type = V4L2_EVENT_ALL;
@@ -1753,7 +1754,7 @@
case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- if (p_mctl->isp_notify && p_mctl->vfe_sdev)
+ if (p_mctl && p_mctl->isp_notify && p_mctl->vfe_sdev)
rc = p_mctl->isp_notify(p_mctl,
p_mctl->vfe_sdev, notification, arg);
break;
@@ -1772,18 +1773,20 @@
break;
case NOTIFY_AXI_RDI_SOF_COUNT:
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- if (p_mctl->axi_sdev)
+ if (p_mctl && p_mctl->axi_sdev)
rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
break;
case NOTIFY_PCLK_CHANGE:
p_mctl = v4l2_get_subdev_hostdata(sd);
- if (p_mctl->axi_sdev)
- rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
- s_crystal_freq, *(uint32_t *)arg, 0);
- else
- rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
- s_crystal_freq, *(uint32_t *)arg, 0);
+ if (p_mctl) {
+ if (p_mctl->axi_sdev)
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ else
+ rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
+ s_crystal_freq, *(uint32_t *)arg, 0);
+ }
break;
case NOTIFY_GESTURE_EVT:
rc = v4l2_subdev_call(g_server_dev.gesture_device,
@@ -1795,8 +1798,10 @@
break;
case NOTIFY_VFE_CAMIF_ERROR: {
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- msm_cam_server_send_error_evt(p_mctl, V4L2_EVENT_PRIVATE_START
- + MSM_CAM_APP_NOTIFY_ERROR_EVENT);
+ if (p_mctl)
+ msm_cam_server_send_error_evt(p_mctl,
+ V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_APP_NOTIFY_ERROR_EVENT);
break;
}
default:
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index e1b73ef..eae18c4 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -134,6 +134,9 @@
}
heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
+ if (!(flags & SMEM_SECURE))
+ heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
+
dprintk(VIDC_DBG, "domain: %d, partition: %d\n",
domain, partition);
hndl = ion_alloc(client->clnt, size, align, heap_mask, ionflags);
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index 711b3007..48e6a93 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -27,6 +27,10 @@
#define MIN_NUM_OUTPUT_BUFFERS 4
#define MAX_NUM_OUTPUT_BUFFERS 6
+enum msm_vdec_ctrl_cluster {
+ MSM_VDEC_CTRL_CLUSTER_MAX = 1,
+};
+
static const char *const mpeg_video_vidc_divx_format[] = {
"DIVX Format 3",
"DIVX Format 4",
@@ -68,7 +72,7 @@
"Extradata aspect ratio",
};
-static const struct msm_vidc_ctrl msm_vdec_ctrls[] = {
+static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT,
.name = "NAL Format",
@@ -85,6 +89,7 @@
),
.qmenu = mpeg_video_stream_format,
.step = 0,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER,
@@ -99,6 +104,7 @@
),
.qmenu = mpeg_video_output_order,
.step = 0,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE,
@@ -110,6 +116,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO,
@@ -121,6 +128,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE,
@@ -132,6 +140,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT,
@@ -147,6 +156,7 @@
),
.qmenu = mpeg_video_vidc_divx_format,
.step = 0,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING,
@@ -158,6 +168,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER,
@@ -169,6 +180,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE,
@@ -188,6 +200,7 @@
.step = 0,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA,
@@ -1060,10 +1073,11 @@
inst->prop.height = DEFAULT_HEIGHT;
inst->prop.width = DEFAULT_WIDTH;
inst->prop.fps = 30;
+ inst->prop.prev_time_stamp = 0;
return rc;
}
-static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
int rc = 0;
struct v4l2_control control;
@@ -1074,62 +1088,59 @@
enum hal_property property_id = 0;
u32 property_val = 0;
void *pdata;
- struct msm_vidc_inst *inst = container_of(ctrl->handler,
- struct msm_vidc_inst, ctrl_handler);
- control.id = ctrl->id;
- control.value = ctrl->val;
- switch (control.id) {
+
+ switch (ctrl->id) {
case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT:
property_id =
HAL_PARAM_NAL_STREAM_FORMAT_SELECT;
stream_format.nal_stream_format_supported =
- (0x00000001 << control.value);
+ (0x00000001 << ctrl->val);
pdata = &stream_format;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER:
property_id = HAL_PARAM_VDEC_OUTPUT_ORDER;
- property_val = control.value;
+ property_val = ctrl->val;
pdata = &property_val;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_PICTURE_TYPE:
property_id =
HAL_PARAM_VDEC_PICTURE_TYPE_DECODE;
- enable_picture.picture_type = control.value;
+ enable_picture.picture_type = ctrl->val;
pdata = &enable_picture;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO:
property_id =
HAL_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
- hal_property.enable = control.value;
+ hal_property.enable = ctrl->val;
pdata = &hal_property;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE:
property_id =
HAL_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
- hal_property.enable = control.value;
+ hal_property.enable = ctrl->val;
pdata = &hal_property;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT:
property_id = HAL_PARAM_DIVX_FORMAT;
- property_val = control.value;
+ property_val = ctrl->val;
pdata = &property_val;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING:
property_id =
HAL_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
- hal_property.enable = control.value;
+ hal_property.enable = ctrl->val;
pdata = &hal_property;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER:
property_id =
HAL_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
- hal_property.enable = control.value;
+ hal_property.enable = ctrl->val;
pdata = &hal_property;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE:
property_id =
HAL_PARAM_VDEC_SYNC_FRAME_DECODE;
- hal_property.enable = control.value;
+ hal_property.enable = ctrl->val;
pdata = &hal_property;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
@@ -1140,7 +1151,7 @@
{
struct hal_extradata_enable extra;
property_id = HAL_PARAM_INDEX_EXTRADATA;
- extra.index = msm_comm_get_hal_extradata_index(control.value);
+ extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
extra.enable = 1;
pdata = &extra;
break;
@@ -1148,13 +1159,8 @@
default:
break;
}
+
if (property_id) {
- rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %p to start done state\n", inst);
- goto failed_open_done;
- }
dprintk(VIDC_DBG,
"Control: HAL property=%d,ctrl_id=%d,ctrl_value=%d\n",
property_id,
@@ -1163,10 +1169,37 @@
rc = vidc_hal_session_set_property((void *)
inst->session, property_id,
pdata);
+ }
+
+ return rc;
+}
+
+static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ int rc = 0, c = 0;
+ struct msm_vidc_inst *inst = container_of(ctrl->handler,
+ struct msm_vidc_inst, ctrl_handler);
+ rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %p to start done state\n", inst);
+ goto failed_open_done;
+ }
+
+ for (c = 0; c < ctrl->ncontrols; ++c) {
+ if (ctrl->cluster[c]->is_new) {
+ rc = try_set_ctrl(inst, ctrl->cluster[c]);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed setting %x",
+ ctrl->cluster[c]->id);
+ break;
+ }
}
+ }
+
+failed_open_done:
if (rc)
dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
-failed_open_done:
return rc;
}
@@ -1194,6 +1227,27 @@
{
return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
}
+
+static struct v4l2_ctrl **get_cluster(int type, int *size)
+{
+ int c = 0, sz = 0;
+ struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
+ NUM_CTRLS, GFP_KERNEL);
+
+ if (type <= 0 || !size || !cluster)
+ return NULL;
+
+ for (c = 0; c < NUM_CTRLS; c++) {
+ if (msm_vdec_ctrls[c].cluster == type) {
+ cluster[sz] = msm_vdec_ctrls[c].priv;
+ ++sz;
+ }
+ }
+
+ *size = sz;
+ return cluster;
+}
+
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
{
int idx = 0;
@@ -1209,12 +1263,13 @@
}
for (; idx < NUM_CTRLS; idx++) {
+ struct v4l2_ctrl *ctrl = NULL;
if (IS_PRIV_CTRL(msm_vdec_ctrls[idx].id)) {
/*add private control*/
ctrl_cfg.def = msm_vdec_ctrls[idx].default_value;
ctrl_cfg.flags = 0;
ctrl_cfg.id = msm_vdec_ctrls[idx].id;
- /*ctrl_cfg.is_private =
+ /* ctrl_cfg.is_private =
* msm_vdec_ctrls[idx].is_private;
* ctrl_cfg.is_volatile =
* msm_vdec_ctrls[idx].is_volatile;*/
@@ -1228,18 +1283,19 @@
ctrl_cfg.type = msm_vdec_ctrls[idx].type;
ctrl_cfg.qmenu = msm_vdec_ctrls[idx].qmenu;
- v4l2_ctrl_new_custom(&inst->ctrl_handler,
+ ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
&ctrl_cfg, NULL);
} else {
if (msm_vdec_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
- v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
+ ctrl = v4l2_ctrl_new_std_menu(
+ &inst->ctrl_handler,
&msm_vdec_ctrl_ops,
msm_vdec_ctrls[idx].id,
msm_vdec_ctrls[idx].maximum,
msm_vdec_ctrls[idx].menu_skip_mask,
msm_vdec_ctrls[idx].default_value);
} else {
- v4l2_ctrl_new_std(&inst->ctrl_handler,
+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
&msm_vdec_ctrl_ops,
msm_vdec_ctrls[idx].id,
msm_vdec_ctrls[idx].minimum,
@@ -1248,11 +1304,51 @@
msm_vdec_ctrls[idx].default_value);
}
}
+
+
+ msm_vdec_ctrls[idx].priv = ctrl;
}
ret_val = inst->ctrl_handler.error;
if (ret_val)
dprintk(VIDC_ERR,
"Error adding ctrls to ctrl handle, %d\n",
inst->ctrl_handler.error);
+
+ /* Construct clusters */
+ for (idx = 1; idx < MSM_VDEC_CTRL_CLUSTER_MAX; ++idx) {
+ struct msm_vidc_ctrl_cluster *temp = NULL;
+ struct v4l2_ctrl **cluster = NULL;
+ int cluster_size = 0;
+
+ cluster = get_cluster(idx, &cluster_size);
+ if (!cluster || !cluster_size) {
+ dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
+ idx);
+ continue;
+ }
+
+ v4l2_ctrl_cluster(cluster_size, cluster);
+
+ temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+ if (!temp) {
+ ret_val = -ENOMEM;
+ break;
+ }
+
+ temp->cluster = cluster;
+ INIT_LIST_HEAD(&temp->list);
+ list_add_tail(&temp->list, &inst->ctrl_clusters);
+ }
return ret_val;
}
+
+int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst)
+{
+ struct msm_vidc_ctrl_cluster *curr, *next;
+ list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
+ kfree(curr->cluster);
+ kfree(curr);
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/msm_vidc/msm_vdec.h b/drivers/media/video/msm_vidc/msm_vdec.h
index 419c8c1..73a516e 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.h
+++ b/drivers/media/video/msm_vidc/msm_vdec.h
@@ -18,6 +18,7 @@
int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
+int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst);
int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 41518d7..a0aa150 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -88,7 +88,20 @@
"High Latency",
};
-static const struct msm_vidc_ctrl msm_venc_ctrls[] = {
+enum msm_venc_ctrl_cluster {
+ MSM_VENC_CTRL_CLUSTER_QP = 1,
+ MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+ MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
+ MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
+ MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
+ MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
+ MSM_VENC_CTRL_CLUSTER_SLICING,
+ MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+ MSM_VENC_CTRL_CLUSTER_BITRATE,
+ MSM_VENC_CTRL_CLUSTER_MAX,
+};
+
+static struct msm_vidc_ctrl msm_venc_ctrls[] = {
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
.name = "Frame Rate",
@@ -99,12 +112,13 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
.name = "IDR Period",
.type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = 0,
+ .minimum = 1,
.maximum = 10*MAX_FRAME_RATE,
.default_value = DEFAULT_FRAME_RATE,
.step = 1,
@@ -112,6 +126,18 @@
.qmenu = NULL,
},
{
+ .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
+ .name = "Intra Period",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = 10*MAX_FRAME_RATE,
+ .default_value = DEFAULT_FRAME_RATE,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
+ },
+ {
.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES,
.name = "Intra Period for P frames",
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -121,17 +147,19 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
.name = "Intra Period for B frames",
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
- .maximum = 10*DEFAULT_FRAME_RATE,
+ .maximum = 2,
.default_value = 0,
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_PERIOD,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME,
@@ -143,10 +171,11 @@
.step = 0,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL,
- .name = "Rate Control",
+ .name = "Video Framerate and Bitrate Control",
.type = V4L2_CTRL_TYPE_MENU,
.minimum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF,
.maximum = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR,
@@ -160,6 +189,22 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR)
),
.qmenu = mpeg_video_rate_control,
+ .cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ .name = "Bitrate Control",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .maximum = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ .default_value = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ .step = 0,
+ .menu_skip_mask = ~(
+ (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+ (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ ),
+ .qmenu = mpeg_video_rate_control,
+ .cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
},
{
.id = V4L2_CID_MPEG_VIDEO_BITRATE,
@@ -171,6 +216,7 @@
.step = BIT_RATE_STEP,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_BITRATE,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
@@ -184,6 +230,7 @@
(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
(1 << V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
),
+ .cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
@@ -199,6 +246,7 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2)
),
.qmenu = h264_video_entropy_cabac_model,
+ .cluster = MSM_VENC_CTRL_CLUSTER_H264_ENTROPY,
},
{
.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
@@ -209,6 +257,7 @@
.default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
.step = 1,
.menu_skip_mask = 0,
+ .cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
@@ -219,6 +268,7 @@
.default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
.step = 1,
.menu_skip_mask = 0,
+ .cluster = MSM_VENC_CTRL_CLUSTER_MPEG_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
@@ -229,6 +279,7 @@
.default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
.step = 1,
.menu_skip_mask = 0,
+ .cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
@@ -239,6 +290,7 @@
.default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
.step = 0,
.menu_skip_mask = 0,
+ .cluster = MSM_VENC_CTRL_CLUSTER_H264_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
@@ -259,6 +311,7 @@
(1 << V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY)
),
.qmenu = h263_profile,
+ .cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
@@ -277,6 +330,7 @@
(1 << V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0)
),
.qmenu = h263_level,
+ .cluster = MSM_VENC_CTRL_CLUSTER_H263_PROFILE_LEVEL,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
@@ -293,6 +347,7 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270)
),
.qmenu = mpeg_video_rotation,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
@@ -304,6 +359,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_QP,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
@@ -315,6 +371,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_QP,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
@@ -326,6 +383,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_QP,
},
{
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
@@ -336,6 +394,7 @@
.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
.step = 1,
.menu_skip_mask = 0,
+ .cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
},
{
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
@@ -347,6 +406,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
},
{
.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
@@ -358,6 +418,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE,
@@ -374,6 +435,7 @@
(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE) |
(1 << V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM)
),
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS,
@@ -385,6 +447,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF,
@@ -396,6 +459,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
},
{
.id = V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS,
@@ -407,6 +471,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
@@ -418,6 +483,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
@@ -429,6 +495,7 @@
.step = 1,
.menu_skip_mask = 0,
.qmenu = NULL,
+ .cluster = 0,
},
{
.id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
@@ -443,18 +510,24 @@
(1 << V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED) |
(1 << L_MODE)
),
+ .cluster = 0,
},
{
- .id = V4L2_CID_QCOM_VIDEO_SYNC_FRAME_SEQ_HDR,
- .name = "CodecConfig with sync frame",
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
+ .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+ .name = "Sequence Header Mode",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
+ .default_value =
+ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME,
.step = 1,
- .menu_skip_mask = 0,
+ .menu_skip_mask = ~(
+ (1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+ (1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME)
+ ),
.qmenu = NULL,
- },
+ .cluster = 0,
+ }
};
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -476,29 +549,6 @@
return sz;
}
-static struct hal_quantization
- venc_quantization = {I_FRAME_QP, P_FRAME_QP, B_FRAME_QP};
-static struct hal_intra_period
- venc_intra_period = {2*DEFAULT_FRAME_RATE-1 , 0};
-static struct hal_profile_level
- venc_h264_profile_level = {HAL_H264_PROFILE_BASELINE,
- HAL_H264_LEVEL_1};
-static struct hal_profile_level
- venc_mpeg4_profile_level = {HAL_MPEG4_PROFILE_SIMPLE,
- HAL_MPEG4_LEVEL_0};
-static struct hal_profile_level
- venc_h263_profile_level = {HAL_H263_PROFILE_BASELINE,
- HAL_H263_LEVEL_10};
-static struct hal_h264_entropy_control
- venc_h264_entropy_control = {HAL_H264_ENTROPY_CAVLC,
- HAL_H264_CABAC_MODEL_0};
-static struct hal_multi_slice_control
- venc_multi_slice_control = {HAL_MULTI_SLICE_OFF ,
- 0};
-static struct hal_intra_refresh
- venc_intra_refresh = {HAL_INTRA_REFRESH_NONE ,
- DEFAULT_IR_MBS, DEFAULT_IR_MBS, DEFAULT_IR_MBS};
-
static const struct msm_vidc_format venc_formats[] = {
{
.name = "YCbCr Semiplanar 4:2:0",
@@ -744,11 +794,162 @@
return &msm_venc_vb2q_ops;
}
-static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+static struct v4l2_ctrl *get_ctrl_from_cluster(int id,
+ struct v4l2_ctrl **cluster, int ncontrols)
{
+ int c;
+ for (c = 0; c < ncontrols; ++c)
+ if (cluster[c]->id == id)
+ return cluster[c];
+ return NULL;
+}
+
+/* Helper function to translate V4L2_* to HAL_* */
+static inline int venc_v4l2_to_hal(int id, int value)
+{
+ switch (id) {
+ /* MPEG4 */
+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
+ return HAL_MPEG4_LEVEL_0;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
+ return HAL_MPEG4_LEVEL_0b;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
+ return HAL_MPEG4_LEVEL_1;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
+ return HAL_MPEG4_LEVEL_2;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
+ return HAL_MPEG4_LEVEL_3;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
+ return HAL_MPEG4_LEVEL_4;
+ case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
+ return HAL_MPEG4_LEVEL_5;
+ default:
+ goto unknown_value;
+ }
+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
+ return HAL_MPEG4_PROFILE_SIMPLE;
+ case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
+ return HAL_MPEG4_PROFILE_ADVANCEDSIMPLE;
+ default:
+ goto unknown_value;
+ }
+ /* H264 */
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ return HAL_H264_PROFILE_BASELINE;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ return HAL_H264_PROFILE_MAIN;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+ return HAL_H264_PROFILE_EXTENDED;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ return HAL_H264_PROFILE_HIGH;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
+ return HAL_H264_PROFILE_HIGH10;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
+ return HAL_H264_PROFILE_HIGH422;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
+ return HAL_H264_PROFILE_HIGH444;
+ default:
+ goto unknown_value;
+ }
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
+ return HAL_H264_LEVEL_1;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
+ return HAL_H264_LEVEL_1b;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
+ return HAL_H264_LEVEL_11;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
+ return HAL_H264_LEVEL_12;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
+ return HAL_H264_LEVEL_13;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
+ return HAL_H264_LEVEL_2;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
+ return HAL_H264_LEVEL_21;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
+ return HAL_H264_LEVEL_22;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
+ return HAL_H264_LEVEL_3;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
+ return HAL_H264_LEVEL_31;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
+ return HAL_H264_LEVEL_32;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
+ return HAL_H264_LEVEL_4;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
+ return HAL_H264_LEVEL_41;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+ return HAL_H264_LEVEL_42;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
+ return HAL_H264_LEVEL_3;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
+ return HAL_H264_LEVEL_51;
+ default:
+ goto unknown_value;
+ }
+ /* H263 */
+ case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+ switch (value) {
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
+ return HAL_H263_PROFILE_BASELINE;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
+ return HAL_H263_PROFILE_H320CODING;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
+ return HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
+ return HAL_H263_PROFILE_ISWV2;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
+ return HAL_H263_PROFILE_ISWV3;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
+ return HAL_H263_PROFILE_HIGHCOMPRESSION;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
+ return HAL_H263_PROFILE_INTERNET;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
+ return HAL_H263_PROFILE_INTERLACE;
+ case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
+ return HAL_H263_PROFILE_HIGHLATENCY;
+ default:
+ goto unknown_value;
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+ switch (value) {
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
+ return HAL_H263_LEVEL_10;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
+ return HAL_H263_LEVEL_20;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
+ return HAL_H263_LEVEL_30;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
+ return HAL_H263_LEVEL_40;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
+ return HAL_H263_LEVEL_45;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
+ return HAL_H263_LEVEL_50;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
+ return HAL_H263_LEVEL_60;
+ case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
+ return HAL_H263_LEVEL_70;
+ default:
+ goto unknown_value;
+ }
+ }
+
+unknown_value:
+ dprintk(VIDC_WARN, "Unknown control (%x, %d)", id, value);
+ return -EINVAL;
+}
+
+static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
+{
int rc = 0;
- struct v4l2_control control;
struct hal_frame_rate frame_rate;
struct hal_request_iframe request_iframe;
struct hal_bitrate bitrate;
@@ -762,48 +963,78 @@
struct hal_multi_slice_control multi_slice_control;
struct hal_h264_db_control h264_db_control;
struct hal_enable enable;
- u32 property_id = 0;
- u32 property_val = 0;
+ u32 property_id = 0, property_val = 0;
void *pdata;
- struct msm_vidc_inst *inst = container_of(ctrl->handler,
- struct msm_vidc_inst, ctrl_handler);
- rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %p to start done state\n", inst);
- goto failed_open_done;
- }
- control.id = ctrl->id;
- control.value = ctrl->val;
+ struct v4l2_ctrl *temp_ctrl = NULL;
- switch (control.id) {
+ /* Small helper macro for quickly getting a control and err checking */
+#define TRY_GET_CTRL(__ctrl_id) ({ \
+ struct v4l2_ctrl *__temp; \
+ __temp = get_ctrl_from_cluster( \
+ __ctrl_id, \
+ ctrl->cluster, ctrl->ncontrols); \
+ if (!__temp) { \
+ dprintk(VIDC_ERR, "Can't find %s (%x) in cluster", \
+ #__ctrl_id, __ctrl_id); \
+ rc = -ENOENT; \
+ break; \
+ } \
+ __temp; \
+ })
+
+ switch (ctrl->id) {
case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
- property_id =
- HAL_CONFIG_FRAME_RATE;
- frame_rate.frame_rate = control.value;
- frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
- pdata = &frame_rate;
+ property_id =
+ HAL_CONFIG_FRAME_RATE;
+ frame_rate.frame_rate = ctrl->val;
+ frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
+ pdata = &frame_rate;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
property_id =
HAL_CONFIG_VENC_IDR_PERIOD;
- idr_period.idr_period = control.value;
- pdata = &idr_period;
+ idr_period.idr_period = ctrl->val;
+ pdata = &idr_period;
break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: {
+ struct v4l2_ctrl *b;
+ b = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
+
+ if (inst->fmts[CAPTURE_PORT]->fourcc != V4L2_PIX_FMT_H264 &&
+ inst->fmts[CAPTURE_PORT]->fourcc !=
+ V4L2_PIX_FMT_H264_NO_SC) {
+ dprintk(VIDC_ERR, "Control 0x%x only valid for H264",
+ ctrl->id);
+ rc = -ENOTSUPP;
+ break;
+ }
+
+ /*
+ * We can't set the I-period explicitly. So set it implicitly
+ * by setting the number of P and B frames per I-period
+ */
+ property_id = HAL_CONFIG_VENC_INTRA_PERIOD;
+ intra_period.pframes = (ctrl->val - 1) - b->val;
+ intra_period.bframes = b->val;
+ pdata = &intra_period;
+ break;
+ }
case V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
+
property_id =
HAL_CONFIG_VENC_INTRA_PERIOD;
- intra_period.pframes = control.value;
- venc_intra_period.pframes = control.value;
- intra_period.bframes = venc_intra_period.bframes;
+ intra_period.pframes = ctrl->val;
+ intra_period.bframes = temp_ctrl->val;
pdata = &intra_period;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES);
+
property_id =
HAL_CONFIG_VENC_INTRA_PERIOD;
- intra_period.bframes = control.value;
- venc_intra_period.bframes = control.value;
- intra_period.pframes = venc_intra_period.pframes;
+ intra_period.bframes = ctrl->val;
+ intra_period.pframes = temp_ctrl->val;
pdata = &intra_period;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
@@ -812,396 +1043,405 @@
request_iframe.enable = true;
pdata = &request_iframe;
break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ {
+ bool cfr = true, cbr = true;
+ int final_mode = 0;
+
+ temp_ctrl = TRY_GET_CTRL(
+ V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL);
+
+ switch (temp_ctrl->val) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF:
+ /* Let's assume CFR */
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
+ cfr = true;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR:
+ case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR:
+ cfr = false;
+ break;
+ default:
+ dprintk(VIDC_WARN, "Unknown framerate mode");
+ }
+
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+ cbr = false;
+ break;
+ case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+ cbr = true;
+ break;
+ default:
+ dprintk(VIDC_WARN, "Unknown bitrate mode");
+ }
+
+ if (!cfr && !cbr)
+ final_mode =
+ V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+ else if (!cfr && cbr)
+ final_mode =
+ V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
+ else if (cfr && !cbr)
+ final_mode =
+ V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
+ else /* ... if (cfr && cbr) */
+ final_mode =
+ V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
+
+ property_id = HAL_PARAM_VENC_RATE_CONTROL;
+ property_val = final_mode;
+ pdata = &property_val;
+ break;
+ }
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL:
- property_id =
- HAL_PARAM_VENC_RATE_CONTROL;
- property_val = control.value;
+ property_id = HAL_PARAM_VENC_RATE_CONTROL;
+ property_val = ctrl->val;
pdata = &property_val;
break;
case V4L2_CID_MPEG_VIDEO_BITRATE:
property_id =
HAL_CONFIG_VENC_TARGET_BITRATE;
- bitrate.bit_rate = control.value;
+ bitrate.bit_rate = ctrl->val;
pdata = &bitrate;
break;
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ temp_ctrl = TRY_GET_CTRL(
+ V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL);
+
property_id =
HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
- h264_entropy_control.entropy_mode = control.value;
- venc_h264_entropy_control.entropy_mode = control.value;
- h264_entropy_control.cabac_model =
- venc_h264_entropy_control.cabac_model;
+ h264_entropy_control.entropy_mode = ctrl->val;
+ h264_entropy_control.cabac_model = temp_ctrl->val;
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE);
+
property_id =
HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
- h264_entropy_control.cabac_model = control.value;
- venc_h264_entropy_control.cabac_model = control.value;
- h264_entropy_control.entropy_mode =
- venc_h264_entropy_control.entropy_mode;
+ h264_entropy_control.cabac_model = ctrl->val;
+ h264_entropy_control.entropy_mode = temp_ctrl->val;
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
- switch (control.value) {
- case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
- control.value = HAL_MPEG4_PROFILE_SIMPLE;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
- control.value = HAL_MPEG4_PROFILE_ADVANCEDSIMPLE;
- break;
- default:
- break;
- }
- profile_level.profile = control.value;
- venc_mpeg4_profile_level.profile = control.value;
- profile_level.level = venc_mpeg4_profile_level.level;
+ profile_level.profile = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.level = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+ temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
- switch (control.value) {
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
- control.value = HAL_MPEG4_LEVEL_0;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
- control.value = HAL_MPEG4_LEVEL_0b;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
- control.value = HAL_MPEG4_LEVEL_1;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
- control.value = HAL_MPEG4_LEVEL_2;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
- control.value = HAL_MPEG4_LEVEL_3;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
- control.value = HAL_MPEG4_LEVEL_4;
- break;
- case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
- control.value = HAL_MPEG4_LEVEL_5;
- break;
- default:
- break;
- }
- profile_level.level = control.value;
- venc_mpeg4_profile_level.level = control.value;
- profile_level.profile = venc_mpeg4_profile_level.profile;
+ profile_level.level = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.profile = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+ temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
-
- switch (control.value) {
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
- control.value = HAL_H264_PROFILE_BASELINE;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
- control.value = HAL_H264_PROFILE_MAIN;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
- control.value = HAL_H264_PROFILE_EXTENDED;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
- control.value = HAL_H264_PROFILE_HIGH;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
- control.value = HAL_H264_PROFILE_HIGH10;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
- control.value = HAL_H264_PROFILE_HIGH422;
- break;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
- control.value = HAL_H264_PROFILE_HIGH444;
- break;
- default:
- break;
- }
- profile_level.profile = control.value;
- venc_h264_profile_level.profile = control.value;
- profile_level.level = venc_h264_profile_level.level;
+ profile_level.profile = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.level = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+ temp_ctrl->val);
pdata = &profile_level;
dprintk(VIDC_DBG, "\nprofile: %d\n",
profile_level.profile);
break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
-
- switch (control.value) {
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
- control.value = HAL_H264_LEVEL_1;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
- control.value = HAL_H264_LEVEL_1b;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
- control.value = HAL_H264_LEVEL_11;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
- control.value = HAL_H264_LEVEL_12;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
- control.value = HAL_H264_LEVEL_13;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
- control.value = HAL_H264_LEVEL_2;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
- control.value = HAL_H264_LEVEL_21;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
- control.value = HAL_H264_LEVEL_22;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
- control.value = HAL_H264_LEVEL_3;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
- control.value = HAL_H264_LEVEL_31;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
- control.value = HAL_H264_LEVEL_32;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
- control.value = HAL_H264_LEVEL_4;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
- control.value = HAL_H264_LEVEL_41;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
- control.value = HAL_H264_LEVEL_42;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
- control.value = HAL_H264_LEVEL_3;
- break;
- case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
- control.value = HAL_H264_LEVEL_51;
- break;
- default:
- break;
- }
- profile_level.level = control.value;
- venc_h264_profile_level.level = control.value;
- profile_level.profile = venc_h264_profile_level.profile;
- pdata = &profile_level;
+ profile_level.level = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.profile = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+ temp_ctrl->val);
pdata = &profile_level;
dprintk(VIDC_DBG, "\nLevel: %d\n",
profile_level.level);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
-
- switch (control.value) {
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE:
- control.value = HAL_H263_PROFILE_BASELINE;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING:
- control.value = HAL_H263_PROFILE_H320CODING;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE:
- control.value = HAL_H263_PROFILE_BACKWARDCOMPATIBLE;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2:
- control.value = HAL_H263_PROFILE_ISWV2;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3:
- control.value = HAL_H263_PROFILE_ISWV3;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION:
- control.value = HAL_H263_PROFILE_HIGHCOMPRESSION;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET:
- control.value = HAL_H263_PROFILE_INTERNET;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE:
- control.value = HAL_H263_PROFILE_INTERLACE;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY:
- control.value = HAL_H263_PROFILE_HIGHLATENCY;
- break;
- default:
- break;
- }
- profile_level.profile = control.value;
- venc_h263_profile_level.profile = control.value;
- profile_level.level = venc_h263_profile_level.level;
+ profile_level.profile = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.level = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
+ temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE);
+
property_id =
HAL_PARAM_PROFILE_LEVEL_CURRENT;
-
- switch (control.value) {
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0:
- control.value = HAL_H263_LEVEL_10;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0:
- control.value = HAL_H263_LEVEL_20;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0:
- control.value = HAL_H263_LEVEL_30;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0:
- control.value = HAL_H263_LEVEL_40;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5:
- control.value = HAL_H263_LEVEL_45;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0:
- control.value = HAL_H263_LEVEL_50;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0:
- control.value = HAL_H263_LEVEL_60;
- break;
- case V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0:
- control.value = HAL_H263_LEVEL_70;
- break;
- default:
- break;
- }
-
- profile_level.level = control.value;
- venc_h263_profile_level.level = control.value;
- profile_level.profile = venc_h263_profile_level.profile;
+ profile_level.level = venc_v4l2_to_hal(ctrl->id,
+ ctrl->val);
+ profile_level.profile = venc_v4l2_to_hal(
+ V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
+ ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
property_id =
HAL_CONFIG_VPE_OPERATIONS;
- operations.rotate = control.value;
+ operations.rotate = ctrl->val;
pdata = &operations;
break;
- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: {
+ struct v4l2_ctrl *qpp, *qpb;
+
+ qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
+ qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
+
property_id =
HAL_PARAM_VENC_SESSION_QP;
- quantization.qpi = control.value;
- venc_quantization.qpi = control.value;
- quantization.qpp = venc_quantization.qpp;
- quantization.qpb = venc_quantization.qpb;
+ quantization.qpi = ctrl->val;
+ quantization.qpp = qpp->val;
+ quantization.qpb = qpb->val;
+
pdata = &quantization;
break;
- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ }
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: {
+ struct v4l2_ctrl *qpi, *qpb;
+
+ qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
+ qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP);
+
property_id =
HAL_PARAM_VENC_SESSION_QP;
- quantization.qpp = control.value;
- venc_quantization.qpp = control.value;
- quantization.qpi = venc_quantization.qpi;
- quantization.qpb = venc_quantization.qpb;
+ quantization.qpp = ctrl->val;
+ quantization.qpi = qpi->val;
+ quantization.qpb = qpb->val;
+
pdata = &quantization;
break;
- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+ }
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: {
+ struct v4l2_ctrl *qpi, *qpp;
+
+ qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
+ qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
+
property_id =
HAL_PARAM_VENC_SESSION_QP;
- quantization.qpb = control.value;
- venc_quantization.qpb = control.value;
- quantization.qpi = venc_quantization.qpi;
- quantization.qpp = venc_quantization.qpp;
+ quantization.qpb = ctrl->val;
+ quantization.qpi = qpi->val;
+ quantization.qpp = qpp->val;
+
pdata = &quantization;
break;
- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+ }
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: {
+ int temp = 0;
+
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
+ temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
+ break;
+ case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
+ temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+ break;
+ case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
+ default:
+ temp = 0;
+ break;
+ }
+
+ if (temp)
+ temp_ctrl = TRY_GET_CTRL(temp);
+
property_id =
HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
- multi_slice_control.multi_slice = control.value;
- venc_multi_slice_control.multi_slice = control.value;
- multi_slice_control.slice_size =
- venc_multi_slice_control.slice_size;
+ multi_slice_control.multi_slice = ctrl->val;
+ multi_slice_control.slice_size = temp ? temp_ctrl->val : 0;
+
pdata = &multi_slice_control;
break;
+ }
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+ temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
+
property_id =
HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
- multi_slice_control.multi_slice =
- venc_multi_slice_control.multi_slice;
- multi_slice_control.slice_size = control.value;
- venc_multi_slice_control.slice_size = control.value;
+ multi_slice_control.multi_slice = temp_ctrl->val;
+ multi_slice_control.slice_size = ctrl->val;
pdata = &multi_slice_control;
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE:
+ case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: {
+ struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs;
+ air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+ air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+ cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
property_id =
HAL_PARAM_VENC_INTRA_REFRESH;
- intra_refresh.mode = control.value;
- intra_refresh.air_mbs = venc_intra_refresh.air_mbs;
- intra_refresh.air_ref = venc_intra_refresh.air_ref;
- intra_refresh.cir_mbs = venc_intra_refresh.cir_mbs;
- venc_intra_refresh.mode = intra_refresh.mode;
+
+ intra_refresh.mode = ctrl->val;
+ intra_refresh.air_mbs = air_mbs->val;
+ intra_refresh.air_ref = air_ref->val;
+ intra_refresh.cir_mbs = cir_mbs->val;
+
pdata = &intra_refresh;
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS:
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS: {
+ struct v4l2_ctrl *ir_mode, *air_ref, *cir_mbs;
+ ir_mode = TRY_GET_CTRL(
+ V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+ air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+ cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
property_id =
HAL_PARAM_VENC_INTRA_REFRESH;
- intra_refresh.air_mbs = control.value;
- intra_refresh.mode = venc_intra_refresh.mode;
- intra_refresh.air_ref = venc_intra_refresh.air_ref;
- intra_refresh.cir_mbs = venc_intra_refresh.cir_mbs;
- venc_intra_refresh.air_mbs = control.value;
+ intra_refresh.air_mbs = ctrl->val;
+ intra_refresh.mode = ir_mode->val;
+ intra_refresh.air_ref = air_ref->val;
+ intra_refresh.cir_mbs = cir_mbs->val;
+
pdata = &intra_refresh;
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF:
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF: {
+ struct v4l2_ctrl *ir_mode, *air_mbs, *cir_mbs;
+ ir_mode = TRY_GET_CTRL(
+ V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+ air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+ cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
+
property_id =
HAL_PARAM_VENC_INTRA_REFRESH;
- intra_refresh.air_ref = control.value;
- intra_refresh.air_mbs = venc_intra_refresh.air_mbs;
- intra_refresh.mode = venc_intra_refresh.mode;
- intra_refresh.cir_mbs = venc_intra_refresh.cir_mbs;
- venc_intra_refresh.air_ref = control.value;
+ intra_refresh.air_ref = ctrl->val;
+ intra_refresh.air_mbs = air_mbs->val;
+ intra_refresh.mode = ir_mode->val;
+ intra_refresh.cir_mbs = cir_mbs->val;
+
pdata = &intra_refresh;
break;
- case V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS:
+ }
+ case V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS: {
+ struct v4l2_ctrl *ir_mode, *air_mbs, *air_ref;
+
+ ir_mode = TRY_GET_CTRL(
+ V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
+ air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+ air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+
property_id =
HAL_PARAM_VENC_INTRA_REFRESH;
- intra_refresh.cir_mbs = control.value;
- intra_refresh.air_mbs = venc_intra_refresh.air_mbs;
- intra_refresh.air_ref = venc_intra_refresh.air_ref;
- intra_refresh.mode = venc_intra_refresh.mode;
- venc_intra_refresh.cir_mbs = control.value;
+
+ intra_refresh.cir_mbs = ctrl->val;
+ intra_refresh.air_mbs = air_mbs->val;
+ intra_refresh.air_ref = air_ref->val;
+ intra_refresh.mode = ir_mode->val;
+
pdata = &intra_refresh;
break;
+ }
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
property_id =
HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
- h264_db_control.mode = control.value;
+ h264_db_control.mode = ctrl->val;
pdata = &h264_db_control;
break;
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
property_id =
HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
- h264_db_control.slice_alpha_offset = control.value;
+ h264_db_control.slice_alpha_offset = ctrl->val;
pdata = &h264_db_control;
break;
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
property_id =
HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
- h264_db_control.slice_beta_offset = control.value;
+ h264_db_control.slice_beta_offset = ctrl->val;
pdata = &h264_db_control;
break;
- case V4L2_CID_QCOM_VIDEO_SYNC_FRAME_SEQ_HDR:
+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
property_id =
HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER;
- enable.enable = control.value;
+
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
+ enable.enable = 0;
+ break;
+ case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
+ enable.enable = 1;
+ break;
+ case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
+ default:
+ rc = -ENOTSUPP;
+ break;
+ }
pdata = &enable;
break;
default:
+ rc = -ENOTSUPP;
break;
}
+#undef TRY_GET_CTRL
+
if (property_id) {
dprintk(VIDC_DBG, "Control: HAL property=%d,ctrl_value=%d\n",
property_id,
- control.value);
+ ctrl->val);
rc = vidc_hal_session_set_property((void *)inst->session,
property_id, pdata);
}
- if (rc)
- dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
-failed_open_done:
+
return rc;
}
+
+static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+
+ int rc = 0, c = 0;
+ struct msm_vidc_inst *inst = container_of(ctrl->handler,
+ struct msm_vidc_inst, ctrl_handler);
+ rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
+
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %p to start done state\n", inst);
+ goto failed_open_done;
+ }
+
+ for (c = 0; c < ctrl->ncontrols; ++c) {
+ if (ctrl->cluster[c]->is_new) {
+ rc = try_set_ctrl(inst, ctrl->cluster[c]);
+ if (rc) {
+ dprintk(VIDC_ERR, "Failed setting %x",
+ ctrl->cluster[c]->id);
+ break;
+ }
+ }
+ }
+failed_open_done:
+ if (rc)
+ dprintk(VIDC_ERR, "Failed to set hal property\n");
+ return rc;
+}
+
static int msm_venc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
return 0;
@@ -1665,6 +1905,26 @@
return rc;
}
+static struct v4l2_ctrl **get_cluster(int type, int *size)
+{
+ int c = 0, sz = 0;
+ struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
+ NUM_CTRLS, GFP_KERNEL);
+
+ if (type <= 0 || !size || !cluster)
+ return NULL;
+
+ for (c = 0; c < NUM_CTRLS; c++) {
+ if (msm_venc_ctrls[c].cluster == type) {
+ cluster[sz] = msm_venc_ctrls[c].priv;
+ ++sz;
+ }
+ }
+
+ *size = sz;
+ return cluster;
+}
+
int msm_venc_ctrl_init(struct msm_vidc_inst *inst)
{
@@ -1679,6 +1939,7 @@
}
for (; idx < NUM_CTRLS; idx++) {
+ struct v4l2_ctrl *ctrl = NULL;
if (IS_PRIV_CTRL(msm_venc_ctrls[idx].id)) {
ctrl_cfg.def = msm_venc_ctrls[idx].default_value;
ctrl_cfg.flags = 0;
@@ -1692,18 +1953,20 @@
ctrl_cfg.step = msm_venc_ctrls[idx].step;
ctrl_cfg.type = msm_venc_ctrls[idx].type;
ctrl_cfg.qmenu = msm_venc_ctrls[idx].qmenu;
- v4l2_ctrl_new_custom(&inst->ctrl_handler,
- &ctrl_cfg, NULL);
+ ctrl = v4l2_ctrl_new_custom(
+ &inst->ctrl_handler,
+ &ctrl_cfg, NULL);
} else {
if (msm_venc_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
- v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
+ ctrl = v4l2_ctrl_new_std_menu(
+ &inst->ctrl_handler,
&msm_venc_ctrl_ops,
msm_venc_ctrls[idx].id,
msm_venc_ctrls[idx].maximum,
msm_venc_ctrls[idx].menu_skip_mask,
msm_venc_ctrls[idx].default_value);
} else {
- v4l2_ctrl_new_std(&inst->ctrl_handler,
+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
&msm_venc_ctrl_ops,
msm_venc_ctrls[idx].id,
msm_venc_ctrls[idx].minimum,
@@ -1712,11 +1975,51 @@
msm_venc_ctrls[idx].default_value);
}
}
+
+ msm_venc_ctrls[idx].priv = ctrl;
}
ret_val = inst->ctrl_handler.error;
if (ret_val)
dprintk(VIDC_ERR,
"CTRL ERR: Error adding ctrls to ctrl handle, %d\n",
inst->ctrl_handler.error);
+
+ /* Construct clusters */
+ for (idx = 1; idx < MSM_VENC_CTRL_CLUSTER_MAX; ++idx) {
+ struct msm_vidc_ctrl_cluster *temp = NULL;
+ struct v4l2_ctrl **cluster = NULL;
+ int cluster_size = 0;
+
+ cluster = get_cluster(idx, &cluster_size);
+ if (!cluster || !cluster_size) {
+ dprintk(VIDC_WARN, "Failed to setup cluster of type %d",
+ idx);
+ continue;
+ }
+
+ v4l2_ctrl_cluster(cluster_size, cluster);
+
+ temp = kzalloc(sizeof(*temp), GFP_KERNEL);
+ if (!temp) {
+ ret_val = -ENOMEM;
+ break;
+ }
+
+ temp->cluster = cluster;
+ INIT_LIST_HEAD(&temp->list);
+ list_add_tail(&temp->list, &inst->ctrl_clusters);
+ }
+
return ret_val;
}
+
+int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst)
+{
+ struct msm_vidc_ctrl_cluster *curr, *next;
+ list_for_each_entry_safe(curr, next, &inst->ctrl_clusters, list) {
+ kfree(curr->cluster);
+ kfree(curr);
+ }
+
+ return 0;
+}
diff --git a/drivers/media/video/msm_vidc/msm_venc.h b/drivers/media/video/msm_vidc/msm_venc.h
index ad63e7d..c098773 100644
--- a/drivers/media/video/msm_vidc/msm_venc.h
+++ b/drivers/media/video/msm_vidc/msm_venc.h
@@ -18,6 +18,7 @@
int msm_venc_inst_init(struct msm_vidc_inst *inst);
int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
+int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst);
int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
diff --git a/drivers/media/video/msm_vidc/msm_vidc.c b/drivers/media/video/msm_vidc/msm_vidc.c
index 6ecea30..13180c5 100644
--- a/drivers/media/video/msm_vidc/msm_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_vidc.c
@@ -428,6 +428,7 @@
INIT_LIST_HEAD(&inst->pendingq);
INIT_LIST_HEAD(&inst->internalbufs);
INIT_LIST_HEAD(&inst->persistbufs);
+ INIT_LIST_HEAD(&inst->ctrl_clusters);
init_waitqueue_head(&inst->kernel_event_queue);
inst->state = MSM_VIDC_CORE_UNINIT_DONE;
inst->core = core;
@@ -555,6 +556,12 @@
list_del(&inst->list);
}
mutex_unlock(&core->sync_lock);
+
+ if (inst->session_type == MSM_VIDC_DECODER)
+ msm_vdec_ctrl_deinit(inst);
+ else if (inst->session_type == MSM_VIDC_ENCODER)
+ msm_venc_ctrl_deinit(inst);
+
cleanup_instance(inst);
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID)
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index fa056ca..b9ff82e 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -63,6 +63,8 @@
int ret;
};
+#define TIME_DIFF_THRESHOLD 200
+
static const u32 bus_table[] = {
36000,
110400,
@@ -756,12 +758,58 @@
}
}
+static void msm_comm_update_clocks(struct msm_vidc_inst *inst,
+ u64 cur_time_stamp)
+{
+ u32 new_time_diff = 0, cur_time_diff = 0;
+ u8 updated_fps = 0;
+ struct v4l2_ctrl *ctrl = NULL;
+ u32 output_order = 0;
+
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ goto exit;
+ ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
+ V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER);
+ if (!ctrl) {
+ dprintk(VIDC_WARN, "Unable to find output order control\n");
+ dprintk(VIDC_WARN,
+ "Performance might be impacted for higher fps clips\n");
+ goto exit;
+ }
+ output_order = v4l2_ctrl_g_ctrl(ctrl);
+ if (output_order == V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY) {
+ new_time_diff =
+ (u32)(cur_time_stamp - inst->prop.prev_time_stamp);
+ inst->prop.prev_time_stamp = cur_time_stamp;
+ if (!new_time_diff)
+ goto exit;
+ if (inst->prop.fps)
+ cur_time_diff = USEC_PER_SEC / inst->prop.fps;
+ cur_time_diff = cur_time_diff > new_time_diff ?
+ cur_time_diff - new_time_diff :
+ new_time_diff - cur_time_diff;
+ if (cur_time_diff > TIME_DIFF_THRESHOLD) {
+ updated_fps = (u8) (USEC_PER_SEC / new_time_diff);
+ if (updated_fps && (updated_fps != inst->prop.fps)) {
+ inst->prop.fps = updated_fps;
+ dprintk(VIDC_DBG,
+ "Updating clocks: Decoding fps = %d\n",
+ inst->prop.fps);
+ msm_comm_scale_clocks_and_bus(inst);
+ }
+ }
+ }
+exit:
+ return;
+}
+
static void handle_fbd(enum command_response cmd, void *data)
{
struct msm_vidc_cb_data_done *response = data;
struct msm_vidc_inst *inst;
struct vb2_buffer *vb;
struct vidc_hal_fbd *fill_buf_done;
+
if (!response) {
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
return;
@@ -777,9 +825,9 @@
int64_t time_usec = fill_buf_done->timestamp_hi;
time_usec = (time_usec << 32) |
fill_buf_done->timestamp_lo;
-
vb->v4l2_buf.timestamp =
ns_to_timeval(time_usec * NSEC_PER_USEC);
+ msm_comm_update_clocks(inst, time_usec);
}
vb->v4l2_buf.flags = 0;
@@ -1013,16 +1061,17 @@
}
if (msm_comm_scale_clocks(core)) {
dprintk(VIDC_WARN,
- "Failed to scale clocks. Performance might be impacted\n");
+ "Failed to scale clocks. Performance might be impacted\n");
}
if (msm_comm_scale_bus(core, inst->session_type, DDR_MEM)) {
dprintk(VIDC_WARN,
- "Failed to scale DDR bus. Performance might be impacted\n");
+ "Failed to scale DDR bus. Performance might be impacted\n");
}
if (core->resources.ocmem.buf) {
- if (msm_comm_scale_bus(core, inst->session_type, OCMEM_MEM))
+ if (msm_comm_scale_bus(core, inst->session_type,
+ OCMEM_MEM))
dprintk(VIDC_WARN,
- "Failed to scale OCMEM bus. Performance might be impacted\n");
+ "Failed to scale OCMEM bus. Performance might be impacted\n");
}
}
@@ -1710,7 +1759,6 @@
inst->state, state);
return rc;
}
-
int msm_comm_qbuf(struct vb2_buffer *vb)
{
int rc = 0;
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index b274d13..88aedf9 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -170,6 +170,7 @@
u32 height;
u32 fps;
u32 bitrate;
+ u64 prev_time_stamp;
};
struct buf_queue {
@@ -258,6 +259,7 @@
void *mem_client;
struct v4l2_ctrl_handler ctrl_handler;
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
+ struct list_head ctrl_clusters;
struct v4l2_fh event_handler;
struct msm_smem *extradata_handle;
wait_queue_head_t kernel_event_queue;
@@ -275,6 +277,11 @@
extern struct msm_vidc_drv *vidc_driver;
+struct msm_vidc_ctrl_cluster {
+ struct v4l2_ctrl **cluster;
+ struct list_head list;
+};
+
struct msm_vidc_ctrl {
u32 id;
char name[MAX_NAME_LENGTH];
@@ -285,6 +292,8 @@
u32 step;
u32 menu_skip_mask;
const char * const *qmenu;
+ u32 cluster;
+ struct v4l2_ctrl *priv;
};
void handle_cmd_response(enum command_response cmd, void *data);
diff --git a/drivers/media/video/msm_wfd/enc-venus-subdev.c b/drivers/media/video/msm_wfd/enc-venus-subdev.c
index 86242a3..0f3ed58 100644
--- a/drivers/media/video/msm_wfd/enc-venus-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-venus-subdev.c
@@ -1064,7 +1064,6 @@
static long venc_set_property(struct v4l2_subdev *sd, void *arg)
{
struct venc_inst *inst = NULL;
- struct v4l2_control *ctrl = arg;
if (!sd) {
WFD_MSG_ERR("Subdevice required for %s\n", __func__);
@@ -1072,13 +1071,6 @@
}
inst = (struct venc_inst *)sd->dev_priv;
- if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEADER_MODE) {
- /* XXX: We don't support this yet, but to prevent unncessary
- * target specific code for the client, we'll not error out.
- * The client ideally shouldn't notice this */
- return 0;
- }
-
return msm_vidc_s_ctrl(inst->vidc_context, (struct v4l2_control *)arg);
}
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 47b36ae..4012fec 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -252,6 +252,7 @@
static const char * const header_mode[] = {
"Separate Buffer",
"Joined With 1st Frame",
+ "Joined With I-Frames",
NULL,
};
static const char * const multi_slice[] = {
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index 5161b7b..06891899 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -166,17 +166,22 @@
void update_nr_value(struct vcap_dev *dev)
{
struct nr_param *par;
+ uint32_t val = 0;
par = &dev->nr_param;
if (par->mode == NR_MANUAL) {
writel_relaxed(par->window << 24 | par->decay_ratio << 20,
VCAP_VP_NR_CONFIG);
- writel_relaxed(par->luma.max_blend_ratio << 24 |
+ if (par->threshold)
+ val = VP_NR_DYNAMIC_THRESHOLD;
+ writel_relaxed(val |
+ par->luma.max_blend_ratio << 24 |
par->luma.scale_diff_ratio << 12 |
par->luma.diff_limit_ratio << 8 |
par->luma.scale_motion_ratio << 4 |
par->luma.blend_limit_ratio << 0,
VCAP_VP_NR_LUMA_CONFIG);
- writel_relaxed(par->chroma.max_blend_ratio << 24 |
+ writel_relaxed(val |
+ par->chroma.max_blend_ratio << 24 |
par->chroma.scale_diff_ratio << 12 |
par->chroma.diff_limit_ratio << 8 |
par->chroma.scale_motion_ratio << 4 |
@@ -646,6 +651,9 @@
param->decay_ratio = BITS_VALUE(rc, 20, 3);
rc = readl_relaxed(VCAP_VP_NR_LUMA_CONFIG);
+ param->threshold = NR_THRESHOLD_STATIC;
+ if (BITS_VALUE(rc, 16, 1))
+ param->threshold = NR_THRESHOLD_DYNAMIC;
param->luma.max_blend_ratio = BITS_VALUE(rc, 24, 4);
param->luma.scale_diff_ratio = BITS_VALUE(rc, 12, 4);
param->luma.diff_limit_ratio = BITS_VALUE(rc, 8, 4);
@@ -662,6 +670,7 @@
void s_default_nr_val(struct nr_param *param)
{
+ param->threshold = NR_THRESHOLD_STATIC;
param->window = 10;
param->decay_ratio = 0;
param->luma.max_blend_ratio = 0;
diff --git a/drivers/media/video/vcap_vp.h b/drivers/media/video/vcap_vp.h
index 2ad5848..70b10c3 100644
--- a/drivers/media/video/vcap_vp.h
+++ b/drivers/media/video/vcap_vp.h
@@ -90,6 +90,7 @@
#define VP_NR_MAX_WINDOW 120
#define VP_NR_MAX_RATIO 16
+#define VP_NR_DYNAMIC_THRESHOLD 0x000F0000
#define BITS_MASK(start, num_of_bits) \
(((1 << (num_of_bits)) - 1) << (start))
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index fa7c116..d43b399 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -37,6 +37,14 @@
#define SITAR_I2C_MODE 0x01
#define CODEC_DT_MAX_PROP_SIZE 40
#define WCD9XXX_I2C_GSBI_SLAVE_ID "3-000d"
+#define WCD9XXX_I2C_TOP_SLAVE_ADDR 0x0d
+#define WCD9XXX_ANALOG_I2C_SLAVE_ADDR 0x77
+#define WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR 0x66
+#define WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR 0x55
+#define WCD9XXX_I2C_TOP_LEVEL 0
+#define WCD9XXX_I2C_ANALOG 1
+#define WCD9XXX_I2C_DIGITAL_1 2
+#define WCD9XXX_I2C_DIGITAL_2 3
struct wcd9xxx_i2c {
struct i2c_client *client;
@@ -644,10 +652,11 @@
kfree(wcd9xxx->supplies);
}
-int wcd9xxx_get_intf_type(void)
+enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void)
{
return wcd9xxx_intf;
}
+
EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
@@ -768,100 +777,146 @@
return wcd9xxx_i2c_write_device(reg, src, bytes);
}
+static int wcd9xxx_i2c_get_client_index(struct i2c_client *client,
+ int *wcd9xx_index)
+{
+ int ret = 0;
+ switch (client->addr) {
+ case WCD9XXX_I2C_TOP_SLAVE_ADDR:
+ *wcd9xx_index = WCD9XXX_I2C_TOP_LEVEL;
+ break;
+ case WCD9XXX_ANALOG_I2C_SLAVE_ADDR:
+ *wcd9xx_index = WCD9XXX_I2C_ANALOG;
+ break;
+ case WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR:
+ *wcd9xx_index = WCD9XXX_I2C_DIGITAL_1;
+ break;
+ case WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR:
+ *wcd9xx_index = WCD9XXX_I2C_DIGITAL_2;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct wcd9xxx *wcd9xxx;
- struct wcd9xxx_pdata *pdata;
+ struct wcd9xxx *wcd9xxx = NULL;
+ struct wcd9xxx_pdata *pdata = NULL;
int val = 0;
int ret = 0;
int i2c_mode = 0;
- static int device_id;
+ int wcd9xx_index = 0;
struct device *dev;
- pr_info("%s\n", __func__);
+ pr_debug("%s: interface status %d\n", __func__, wcd9xxx_intf);
if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
dev_dbg(&client->dev, "%s:Codec is detected in slimbus mode\n",
- __func__);
+ __func__);
return -ENODEV;
- }
- if (device_id > 0) {
- wcd9xxx_modules[device_id++].client = client;
- dev_dbg(&client->dev, "%s:probe for other slaves\n"
- "devices of codec\n", __func__);
+ } else if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_I2C) {
+ ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index);
+ if (ret != 0)
+ dev_err(&client->dev, "%s: I2C set codec I2C\n"
+ "client failed\n", __func__);
+ else {
+ dev_err(&client->dev, "%s:probe for other slaves\n"
+ "devices of codec I2C slave Addr = %x\n",
+ __func__, client->addr);
+ wcd9xxx_modules[wcd9xx_index].client = client;
+ }
return ret;
- }
- dev = &client->dev;
- if (client->dev.of_node) {
- dev_dbg(&client->dev, "%s:Platform data from device tree\n",
- __func__);
- pdata = wcd9xxx_populate_dt_pdata(&client->dev);
- client->dev.platform_data = pdata;
- } else {
- dev_dbg(&client->dev, "%s:Platform data from board file\n",
- __func__);
- pdata = client->dev.platform_data;
- }
- wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
- if (wcd9xxx == NULL) {
- pr_err("%s: error, allocation failed\n", __func__);
- ret = -ENOMEM;
- goto fail;
- }
+ } else if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_PROBING) {
+ dev = &client->dev;
+ if (client->dev.of_node) {
+ dev_dbg(&client->dev, "%s:Platform data\n"
+ "from device tree\n", __func__);
+ pdata = wcd9xxx_populate_dt_pdata(&client->dev);
+ client->dev.platform_data = pdata;
+ } else {
+ dev_dbg(&client->dev, "%s:Platform data from\n"
+ "board file\n", __func__);
+ pdata = client->dev.platform_data;
+ }
+ wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
+ if (wcd9xxx == NULL) {
+ pr_err("%s: error, allocation failed\n", __func__);
+ ret = -ENOMEM;
+ goto fail;
+ }
- if (!pdata) {
- dev_dbg(&client->dev, "no platform data?\n");
- ret = -EINVAL;
- goto fail;
- }
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
- dev_dbg(&client->dev, "can't talk I2C?\n");
- ret = -EIO;
- goto fail;
- }
- dev_set_drvdata(&client->dev, wcd9xxx);
- wcd9xxx->dev = &client->dev;
- wcd9xxx->reset_gpio = pdata->reset_gpio;
- ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
- if (ret) {
- pr_err("%s: Fail to enable Codec supplies\n", __func__);
- goto err_codec;
- }
+ if (!pdata) {
+ dev_dbg(&client->dev, "no platform data?\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_I2C) == 0) {
+ dev_dbg(&client->dev, "can't talk I2C?\n");
+ ret = -EIO;
+ goto fail;
+ }
+ dev_set_drvdata(&client->dev, wcd9xxx);
+ wcd9xxx->dev = &client->dev;
+ wcd9xxx->reset_gpio = pdata->reset_gpio;
+ if (client->dev.of_node)
+ wcd9xxx->mclk_rate = pdata->mclk_rate;
+ ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
+ if (ret) {
+ pr_err("%s: Fail to enable Codec supplies\n",
+ __func__);
+ goto err_codec;
+ }
- usleep_range(5, 5);
- ret = wcd9xxx_reset(wcd9xxx);
- if (ret) {
- pr_err("%s: Resetting Codec failed\n", __func__);
+ usleep_range(5, 5);
+ ret = wcd9xxx_reset(wcd9xxx);
+ if (ret) {
+ pr_err("%s: Resetting Codec failed\n", __func__);
goto err_supplies;
- }
- wcd9xxx_modules[device_id++].client = client;
+ }
- wcd9xxx->read_dev = wcd9xxx_i2c_read;
- wcd9xxx->write_dev = wcd9xxx_i2c_write;
- if (!wcd9xxx->dev->of_node) {
- wcd9xxx->irq = pdata->irq;
- wcd9xxx->irq_base = pdata->irq_base;
- }
+ ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index);
+ if (ret != 0) {
+ pr_err("%s:Set codec I2C client failed\n", __func__);
+ goto err_supplies;
+ }
- ret = wcd9xxx_device_init(wcd9xxx);
- if (ret) {
- pr_err("%s: error, initializing device failed\n", __func__);
- goto err_device_init;
- }
+ wcd9xxx_modules[wcd9xx_index].client = client;
+ wcd9xxx->read_dev = wcd9xxx_i2c_read;
+ wcd9xxx->write_dev = wcd9xxx_i2c_write;
+ if (!wcd9xxx->dev->of_node) {
+ wcd9xxx->irq = pdata->irq;
+ wcd9xxx->irq_base = pdata->irq_base;
+ }
- if ((wcd9xxx->idbyte[0] == 0x2) || (wcd9xxx->idbyte[0] == 0x1))
- i2c_mode = TABLA_I2C_MODE;
- else if (wcd9xxx->idbyte[0] == 0x0)
- i2c_mode = SITAR_I2C_MODE;
+ ret = wcd9xxx_device_init(wcd9xxx);
+ if (ret) {
+ pr_err("%s: error, initializing device failed\n",
+ __func__);
+ goto err_device_init;
+ }
- ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
+ if ((wcd9xxx->idbyte[0] == 0x2) || (wcd9xxx->idbyte[0] == 0x1))
+ i2c_mode = TABLA_I2C_MODE;
+ else if (wcd9xxx->idbyte[0] == 0x0)
+ i2c_mode = SITAR_I2C_MODE;
- if ((ret < 0) || (val != i2c_mode))
- pr_err("failed to read the wcd9xxx status ret = %d\n", ret);
+ ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
+
+ if ((ret < 0) || (val != i2c_mode))
+ pr_err("failed to read the wcd9xxx status ret = %d\n",
+ ret);
wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
- return ret;
+ return ret;
+ } else
+ pr_err("%s: I2C probe in wrong state\n", __func__);
+
+
err_device_init:
wcd9xxx_free_reset(wcd9xxx);
err_supplies:
@@ -1087,6 +1142,7 @@
int ret, i;
char **codec_supplies;
u32 num_of_supplies = 0;
+ u32 mclk_rate = 0;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
@@ -1130,6 +1186,19 @@
goto err;
}
dev_dbg(dev, "%s: reset gpio %d", __func__, pdata->reset_gpio);
+ ret = of_property_read_u32(dev->of_node,
+ "qcom,cdc-mclk-clk-rate",
+ &mclk_rate);
+ if (ret) {
+ dev_err(dev, "Looking up %s property in\n"
+ "node %s failed",
+ "qcom,cdc-mclk-clk-rate",
+ dev->of_node->full_name);
+ devm_kfree(dev, pdata);
+ ret = -EINVAL;
+ goto err;
+ }
+ pdata->mclk_rate = mclk_rate;
return pdata;
err:
devm_kfree(dev, pdata);
@@ -1162,6 +1231,11 @@
struct wcd9xxx_pdata *pdata;
int ret = 0;
+ if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_I2C) {
+ dev_dbg(&slim->dev, "%s:Codec is detected in I2C mode\n",
+ __func__);
+ return -ENODEV;
+ }
if (slim->dev.of_node) {
dev_info(&slim->dev, "Platform data from device tree\n");
pdata = wcd9xxx_populate_dt_pdata(&slim->dev);
@@ -1201,6 +1275,7 @@
slim_set_clientdata(slim, wcd9xxx);
wcd9xxx->reset_gpio = pdata->reset_gpio;
wcd9xxx->dev = &slim->dev;
+ wcd9xxx->mclk_rate = pdata->mclk_rate;
ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
if (ret)
@@ -1477,11 +1552,6 @@
.suspend = wcd9xxx_slim_suspend,
};
-#define WCD9XXX_I2C_TOP_LEVEL 0
-#define WCD9XXX_I2C_ANALOG 1
-#define WCD9XXX_I2C_DIGITAL_1 2
-#define WCD9XXX_I2C_DIGITAL_2 3
-
static struct i2c_device_id wcd9xxx_id_table[] = {
{"wcd9xxx-i2c", WCD9XXX_I2C_TOP_LEVEL},
{"wcd9xxx-i2c", WCD9XXX_I2C_ANALOG},
@@ -1528,6 +1598,8 @@
{
int ret1, ret2, ret3, ret4, ret5, ret6, ret7;
+ wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_PROBING;
+
ret1 = slim_driver_register(&tabla_slim_driver);
if (ret1 != 0)
pr_err("Failed to register tabla SB driver: %d\n", ret1);
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 8f97531..6b067e7 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -398,8 +398,8 @@
pr_err("%s: src pipe connection failure\n", __func__);
return ret;
}
+ connection->src_enabled = 1;
}
- connection->src_enabled = 1;
if (dst_pipe_idx) {
/* open Peripheral -> USB pipe */
@@ -409,8 +409,8 @@
pr_err("%s: dst pipe connection failure\n", __func__);
return ret;
}
+ connection->dst_enabled = 1;
}
- connection->dst_enabled = 1;
return 0;
}
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 05b47cc..a8d52b5 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1800,7 +1800,7 @@
pr_debug("RUC = %duAh\n", remaining_usable_charge_uah);
if (fcc_uah - unusable_charge_uah <= 0) {
- pr_warn("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
+ pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
fcc_uah, unusable_charge_uah);
soc = 0;
} else {
@@ -1843,13 +1843,13 @@
soc = 100;
if (soc < 0) {
- pr_err("bad rem_usb_chg = %d rem_chg %d,"
+ pr_debug("bad rem_usb_chg = %d rem_chg %d,"
"cc_uah %d, unusb_chg %d\n",
remaining_usable_charge_uah,
remaining_charge_uah,
cc_uah, unusable_charge_uah);
- pr_err("for bad rem_usb_chg last_ocv_uv = %d"
+ pr_debug("for bad rem_usb_chg last_ocv_uv = %d"
"chargecycles = %d, batt_temp = %d"
"fcc = %d soc =%d\n",
chip->last_ocv_uv, chargecycles, batt_temp,
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 2c89065..81ffa3a 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -1345,7 +1345,7 @@
pr_debug("RUC = %duAh\n", remaining_usable_charge_uah);
if (params.fcc_uah - params.uuc_uah <= 0) {
- pr_warn("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
+ pr_debug("FCC = %duAh, UUC = %duAh forcing soc = 0\n",
params.fcc_uah,
params.uuc_uah);
soc = 0;
@@ -1379,12 +1379,12 @@
soc = 100;
if (soc < 0) {
- pr_err("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
+ pr_debug("bad rem_usb_chg = %d rem_chg %d, cc_uah %d, unusb_chg %d\n",
remaining_usable_charge_uah,
params.ocv_charge_uah,
params.cc_uah, params.uuc_uah);
- pr_err("for bad rem_usb_chg last_ocv_uv = %d batt_temp = %d fcc = %d soc =%d\n",
+ pr_debug("for bad rem_usb_chg last_ocv_uv = %d batt_temp = %d fcc = %d soc =%d\n",
chip->last_ocv_uv, batt_temp,
params.fcc_uah, soc);
soc = 0;
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index dba02f8..6135e71 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -127,13 +127,72 @@
}
}
+/**
+ * msm_spi_clk_max_rate: finds the nearest lower rate for a clk
+ * @clk the clock for which to find nearest lower rate
+ * @rate clock frequency in Hz
+ * @return nearest lower rate or negative error value
+ *
+ * Public clock API extends clk_round_rate which is a ceiling function. This
+ * function is a floor function implemented as a binary search using the
+ * ceiling function.
+ */
+static long msm_spi_clk_max_rate(struct clk *clk, unsigned long rate)
+{
+ long lowest_available, nearest_low, step_size, cur;
+ long step_direction = -1;
+ long guess = rate;
+ int max_steps = 10;
+
+ cur = clk_round_rate(clk, rate);
+ if (cur == rate)
+ return rate;
+
+ /* if we got here then: cur > rate */
+ lowest_available = clk_round_rate(clk, 0);
+ if (lowest_available > rate)
+ return -EINVAL;
+
+ step_size = (rate - lowest_available) >> 1;
+ nearest_low = lowest_available;
+
+ while (max_steps-- && step_size) {
+ guess += step_size * step_direction;
+
+ cur = clk_round_rate(clk, guess);
+
+ if ((cur < rate) && (cur > nearest_low))
+ nearest_low = cur;
+
+ /*
+ * if we stepped too far, then start stepping in the other
+ * direction with half the step size
+ */
+ if (((cur > rate) && (step_direction > 0))
+ || ((cur < rate) && (step_direction < 0))) {
+ step_direction = -step_direction;
+ step_size >>= 1;
+ }
+ }
+ return nearest_low;
+}
+
static void msm_spi_clock_set(struct msm_spi *dd, int speed)
{
+ long rate;
int rc;
- rc = clk_set_rate(dd->clk, speed);
+ rate = msm_spi_clk_max_rate(dd->clk, speed);
+ if (rate < 0) {
+ dev_err(dd->dev,
+ "%s: no match found for requested clock frequency:%d",
+ __func__, speed);
+ return;
+ }
+
+ rc = clk_set_rate(dd->clk, rate);
if (!rc)
- dd->clock_speed = speed;
+ dd->clock_speed = rate;
}
static int msm_spi_calculate_size(int *fifo_size,
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 85240ef..65b4890 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -216,7 +216,7 @@
.bcdMbbVersion = cpu_to_le16(0x0100),
.wMaxControlMessage = cpu_to_le16(0x1000),
- .bNumberFilters = 0x10,
+ .bNumberFilters = 0x20,
.bMaxFilterSize = 0x80,
.wMaxSegmentSize = cpu_to_le16(0xfe0),
.bmNetworkCapabilities = 0x20,
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 79aac27..32fc79e 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -50,9 +50,6 @@
struct list_head cpkt_resp_q;
atomic_t notify_count;
unsigned long cpkts_len;
-
- /* IPA / RmNet Bridge support*/
- struct usb_bam_connect_ipa_params ipa_params;
};
#define NR_RMNET_PORTS 3
@@ -433,18 +430,9 @@
switch (dxport) {
case USB_GADGET_XPORT_BAM:
case USB_GADGET_XPORT_BAM2BAM:
- ret = gbam_connect(&dev->port, port_num,
- dxport, port_num, NULL);
- if (ret) {
- pr_err("%s: gbam_connect failed: err:%d\n",
- __func__, ret);
- gsmd_ctrl_disconnect(&dev->port, port_num);
- return ret;
- }
- break;
case USB_GADGET_XPORT_BAM2BAM_IPA:
ret = gbam_connect(&dev->port, port_num,
- dxport, port_num, &(dev->ipa_params));
+ dxport, port_num);
if (ret) {
pr_err("%s: gbam_connect failed: err:%d\n",
__func__, ret);
@@ -514,11 +502,8 @@
switch (dxport) {
case USB_GADGET_XPORT_BAM:
case USB_GADGET_XPORT_BAM2BAM:
- gbam_disconnect(&dev->port, port_num, dxport, NULL);
- break;
case USB_GADGET_XPORT_BAM2BAM_IPA:
- gbam_disconnect(&dev->port, port_num, dxport,
- &(dev->ipa_params));
+ gbam_disconnect(&dev->port, port_num, dxport);
break;
case USB_GADGET_XPORT_HSIC:
ghsic_data_disconnect(&dev->port, port_num);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 7f3713f..aa93a7d 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -102,7 +102,7 @@
u32 dst_pipe_idx;
u8 connection_idx;
enum transport_type trans;
- struct usb_bam_connect_ipa_params *ipa_params;
+ struct usb_bam_connect_ipa_params ipa_params;
/* stats */
unsigned int pending_with_bam;
@@ -649,7 +649,7 @@
int ret;
if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- ret = usb_bam_disconnect_ipa(d->connection_idx, d->ipa_params);
+ ret = usb_bam_disconnect_ipa(d->connection_idx, &d->ipa_params);
if (ret)
pr_err("%s: usb_bam_disconnect_ipa failed: err:%d\n",
__func__, ret);
@@ -706,29 +706,29 @@
return;
}
} else if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- d->ipa_params->client = IPA_CLIENT_USB_CONS;
- d->ipa_params->dir = PEER_PERIPHERAL_TO_USB;
- ret = usb_bam_connect_ipa(d->ipa_params);
+ d->ipa_params.client = IPA_CLIENT_USB_CONS;
+ d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
+ ret = usb_bam_connect_ipa(&d->ipa_params);
if (ret) {
pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
__func__, ret);
return;
}
- d->ipa_params->client = IPA_CLIENT_USB_PROD;
- d->ipa_params->dir = USB_TO_PEER_PERIPHERAL;
+ d->ipa_params.client = IPA_CLIENT_USB_PROD;
+ d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
/* Currently only DMA mode is supported */
- d->ipa_params->ipa_ep_cfg.mode.mode = IPA_DMA;
- d->ipa_params->ipa_ep_cfg.mode.dst =
+ d->ipa_params.ipa_ep_cfg.mode.mode = IPA_DMA;
+ d->ipa_params.ipa_ep_cfg.mode.dst =
IPA_CLIENT_A2_TETHERED_CONS;
- ret = usb_bam_connect_ipa(d->ipa_params);
+ ret = usb_bam_connect_ipa(&d->ipa_params);
if (ret) {
pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
__func__, ret);
return;
}
- rmnet_bridge_connect(d->ipa_params->prod_clnt_hdl,
- d->ipa_params->cons_clnt_hdl, 0);
+ rmnet_bridge_connect(d->ipa_params.prod_clnt_hdl,
+ d->ipa_params.cons_clnt_hdl, 0);
}
d->rx_req = usb_ep_alloc_request(port->port_usb->out, GFP_KERNEL);
@@ -1037,8 +1037,7 @@
static void gam_debugfs_init(void) { }
#endif
-void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans,
- struct usb_bam_connect_ipa_params *ipa_params)
+void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
{
struct gbam_port *port;
unsigned long flags;
@@ -1096,8 +1095,7 @@
}
int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx,
- struct usb_bam_connect_ipa_params *ipa_params)
+ enum transport_type trans, u8 connection_idx)
{
struct gbam_port *port;
struct bam_ch_info *d;
@@ -1166,11 +1164,10 @@
port->gr = gr;
d->connection_idx = connection_idx;
} else if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- d->ipa_params = ipa_params;
port->gr = gr;
- d->ipa_params->src_pipe = &(d->src_pipe_idx);
- d->ipa_params->dst_pipe = &(d->dst_pipe_idx);
- d->ipa_params->idx = connection_idx;
+ d->ipa_params.src_pipe = &(d->src_pipe_idx);
+ d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
+ d->ipa_params.idx = connection_idx;
}
d->trans = trans;
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index a3d42fa..0f7c4fb 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -48,10 +48,8 @@
int gbam_setup(unsigned int no_bam_port, unsigned int no_bam2bam_port);
int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx,
- struct usb_bam_connect_ipa_params *ipa_params);
-void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans,
- struct usb_bam_connect_ipa_params *ipa_params);
+ enum transport_type trans, u8 connection_idx);
+void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans);
void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans);
void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans);
int gsmd_ctrl_connect(struct grmnet *gr, int port_num);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index dde9312..3ad05b06 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -3133,8 +3133,16 @@
struct msm_otg *motg = the_msm_otg;
/* Ignore received BSV interrupts, if ID pin is GND */
- if (!test_bit(ID, &motg->inputs))
- return;
+ if (!test_bit(ID, &motg->inputs)) {
+ /*
+ * state machine work waits for initial VBUS
+ * completion in UNDEFINED state. Process
+ * the initial VBUS event in ID_GND state.
+ */
+ if (init)
+ return;
+ goto complete;
+ }
if (online) {
pr_debug("PMIC: BSV set\n");
@@ -3143,7 +3151,7 @@
pr_debug("PMIC: BSV clear\n");
clear_bit(B_SESS_VLD, &motg->inputs);
}
-
+complete:
if (!init) {
init = true;
complete(&pmic_vbus_init);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index 8db38d6..50750e1 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -16,7 +16,7 @@
#include "mdss_hdmi_edid.h"
#define DBC_START_OFFSET 4
-#define HDMI_VSDB_3D_DATA_OFFSET(vsd) \
+#define HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd) \
(!((vsd)[8] & BIT(7)) ? 9 : (!((vsd)[8] & BIT(6)) ? 11 : 13))
struct hdmi_edid_sink_data {
@@ -180,6 +180,10 @@
{HDMI_VFRMT_1920x1080i120_16_9, 1920, 1080, true, 2200, 280, 1125,
22, 67500, 120000, 148500, 120000, false},
+ /* All 2560 H Active */
+ {HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, false, 2720, 160, 1646,
+ 46, 98700, 60000, 268500, 60000, false},
+
/* All 2880 H Active */
{HDMI_VFRMT_2880x576i50_4_3, 2880, 576, true, 3456, 576, 625, 24,
15625, 50000, 54000, 50000, true},
@@ -437,7 +441,7 @@
u8 block_len = in_buf[offset] & 0x1F;
if ((in_buf[offset] >> 5) == type) {
*len = block_len;
- DEV_DBG("%s: EDID: block=%d found @ %d w/ length=%d\n",
+ DEV_DBG("%s: EDID: block=%d found @ 0x%x w/ len=%d\n",
__func__, type, offset, block_len);
return in_buf + offset;
@@ -533,8 +537,8 @@
return;
}
- offset = HDMI_VSDB_3D_DATA_OFFSET(vsd);
- DEV_DBG("%s: EDID: 3D present @ %d = %02x\n", __func__,
+ offset = HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd);
+ DEV_DBG("%s: EDID: 3D present @ 0x%x = %02x\n", __func__,
offset, vsd[offset]);
if (vsd[offset] >> 7) { /* 3D format indication present */
@@ -835,7 +839,7 @@
3, &len) : NULL;
int i;
- offset = HDMI_VSDB_3D_DATA_OFFSET(vsd);
+ offset = HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd);
present_multi_3d = (vsd[offset] & 0x60) >> 5;
offset += 1;
@@ -897,17 +901,16 @@
i = 0;
while (hdmi_3d_len > 0) {
- DEV_DBG("%s: EDID[3D]: 3D_Structure_%d @ %d: %02x\n", __func__,
- i + 1, offset, vsd[offset]);
+ DEV_DBG("%s: EDID: 3D_Structure_%d @ 0x%x: %02x\n",
+ __func__, i + 1, offset, vsd[offset]);
if ((vsd[offset] >> 4) >=
sink_data->disp_multi_3d_mode_list_cnt) {
if ((vsd[offset] & 0x0F) >= 8) {
offset += 1;
hdmi_3d_len -= 1;
- DEV_DBG("%s:EDID[3D]:3D_Detail_%d @ %d: %02x\n",
- __func__, i + 1, offset,
- vsd[offset]);
+ DEV_DBG("%s:EDID:3D_Detail_%d @ 0x%x: %02x\n",
+ __func__, i + 1, offset, vsd[offset]);
}
i += 1;
offset += 1;
@@ -941,7 +944,7 @@
if ((vsd[offset] & 0x0F) >= 8) {
offset += 1;
hdmi_3d_len -= 1;
- DEV_DBG("%s: EDID[3D]: 3D_Detail_%d @ %d: %02x\n",
+ DEV_DBG("%s: EDID[3D]: 3D_Detail_%d @ 0x%x: %02x\n",
__func__, i + 1, offset,
vsd[offset]);
}
@@ -951,6 +954,49 @@
}
} /* hdmi_edid_get_display_vsd_3d_mode */
+static void hdmi_edid_get_extended_video_formats(
+ struct hdmi_edid_ctrl *edid_ctrl, const u8 *in_buf)
+{
+ u8 db_len, offset, i;
+ u8 hdmi_vic_len;
+ u32 video_format;
+ const u8 *vsd = NULL;
+
+ if (!edid_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ vsd = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 3, &db_len);
+
+ if (vsd == NULL || db_len < 9) {
+ DEV_DBG("%s: blk-id 3 not found or not long enough\n",
+ __func__);
+ return;
+ }
+
+ /* check if HDMI_Video_present flag is set or not */
+ if (!(vsd[8] & BIT(5))) {
+ DEV_DBG("%s: extended vfmts are not supported by the sink.\n",
+ __func__);
+ return;
+ }
+
+ offset = HDMI_VSDB_3D_EVF_DATA_OFFSET(vsd);
+
+ hdmi_vic_len = vsd[offset + 1] >> 5;
+ if (hdmi_vic_len) {
+ DEV_DBG("%s: EDID: EVFRMT @ 0x%x of block 3, len = %02x\n",
+ __func__, offset, hdmi_vic_len);
+
+ for (i = 0; i < hdmi_vic_len; i++) {
+ video_format = HDMI_VFRMT_END + vsd[offset + 2 + i];
+ hdmi_edid_add_sink_video_format(&edid_ctrl->sink_data,
+ video_format);
+ }
+ }
+} /* hdmi_edid_get_extended_video_formats */
+
static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl,
const u8 *data_buf, u32 num_of_cea_blocks)
{
@@ -1113,6 +1159,8 @@
}
}
+ hdmi_edid_get_extended_video_formats(edid_ctrl, data_buf+0x80);
+
/* mandaroty 3d format */
if (edid_ctrl->present_3d) {
if (has60hz_mode) {
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 37bbbdf..9235856 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -32,7 +32,7 @@
#define DRV_NAME "hdmi-tx"
#define COMPATIBLE_NAME "qcom,hdmi-tx"
-#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9;
+#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_1920x1080p60_16_9
/* HDMI PHY/PLL bit field macros */
#define SW_RESET BIT(2)
@@ -91,35 +91,46 @@
}
} /* hdmi_pm_name */
-static u8 hdmi_tx_avi_iframe_lut[][16] = {
-/* 480p60 480i60 576p50 576i50 720p60 720p50 1080p60 1080i60 1080p50
- 1080i50 1080p24 1080p30 1080p25 640x480p 480p60_16_9 576p50_4_3 */
- {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, /*00*/
- {0x18, 0x18, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x18, 0x28, 0x18}, /*01*/
- {0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x88, 0x00, 0x04}, /*02*/
- {0x02, 0x06, 0x11, 0x15, 0x04, 0x13, 0x10, 0x05, 0x1F,
- 0x14, 0x20, 0x22, 0x21, 0x01, 0x03, 0x11}, /*03*/
- {0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*04*/
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*05*/
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*06*/
- {0xE1, 0xE1, 0x41, 0x41, 0xD1, 0xd1, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0xe1, 0xE1, 0x41}, /*07*/
- {0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x02}, /*08*/
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*09*/
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*10*/
- {0xD1, 0xD1, 0xD1, 0xD1, 0x01, 0x01, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0xD1, 0xD1}, /*11*/
- {0x02, 0x02, 0x02, 0x02, 0x05, 0x05, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x02, 0x02, 0x02} /*12*/
+static u8 hdmi_tx_avi_iframe_lut[][20] = {
+ {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10}, /*00*/
+ {0x18, 0x18, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x18, 0x28, 0x18, 0x28, 0x28,
+ 0x28, 0x28}, /*01*/
+ {0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x88, 0x00, 0x04, 0x04, 0x04,
+ 0x04, 0x04}, /*02*/
+ {0x02, 0x06, 0x11, 0x15, 0x04, 0x13, 0x10, 0x05, 0x1F,
+ 0x14, 0x20, 0x22, 0x21, 0x01, 0x03, 0x11, 0x00, 0x00,
+ 0x00, 0x00}, /*03*/
+ {0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00}, /*04*/
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00}, /*05*/
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00}, /*06*/
+ {0xE1, 0xE1, 0x41, 0x41, 0xD1, 0xd1, 0x39, 0x39, 0x39,
+ 0x39, 0x39, 0x39, 0x39, 0xe1, 0xE1, 0x41, 0x71, 0x71,
+ 0x71, 0x71}, /*07*/
+ {0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x02, 0x08, 0x08,
+ 0x08, 0x08}, /*08*/
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00}, /*09*/
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00}, /*10*/
+ {0xD1, 0xD1, 0xD1, 0xD1, 0x01, 0x01, 0x81, 0x81, 0x81,
+ 0x81, 0x81, 0x81, 0x81, 0x81, 0xD1, 0xD1, 0x01, 0x01,
+ 0x01, 0x01}, /*11*/
+ {0x02, 0x02, 0x02, 0x02, 0x05, 0x05, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x02, 0x02, 0x02, 0x0F, 0x0F,
+ 0x0F, 0x10} /*12*/
};
/* Audio constants lookup table for hdmi_tx_audio_acr_setup */
@@ -141,6 +152,10 @@
{148500, {{4096, 148500}, {6272, 165000}, {6144, 148500},
{12544, 165000}, {12288, 148500}, {25088, 165000},
{24576, 148500} } },
+ /* 297.000MHz */
+ {297000, {{3072, 222750}, {4704, 247500}, {5120, 247500},
+ {9408, 247500}, {10240, 247500}, {18816, 247500},
+ {20480, 247500} } },
};
const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module)
@@ -482,9 +497,11 @@
} /* hdmi_tx_init_panel_info */
/* Table indicating the video format supported by the HDMI TX Core */
-/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
+/* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25, 148.5, 268.5, 297 */
static void hdmi_tx_setup_video_mode_lut(void)
{
+ hdmi_init_supported_video_timings();
+
hdmi_set_supported_mode(HDMI_VFRMT_640x480p60_4_3);
hdmi_set_supported_mode(HDMI_VFRMT_720x480p60_4_3);
hdmi_set_supported_mode(HDMI_VFRMT_720x480p60_16_9);
@@ -502,6 +519,11 @@
hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p50_16_9);
hdmi_set_supported_mode(HDMI_VFRMT_1920x1080i60_16_9);
hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p60_16_9);
+ hdmi_set_supported_mode(HDMI_VFRMT_2560x1600p60_16_9);
+ hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p30_16_9);
+ hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p25_16_9);
+ hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p24_16_9);
+ hdmi_set_supported_mode(HDMI_VFRMT_4096x2160p24_16_9);
} /* hdmi_tx_setup_video_mode_lut */
static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -636,7 +658,7 @@
return 0;
} /* hdmi_tx_set_video_fmt */
-static void hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
+static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
int video_format)
{
u32 total_v = 0;
@@ -652,47 +674,53 @@
if (timing == NULL) {
DEV_ERR("%s: video format not supported: %d\n", __func__,
video_format);
- return;
+ return -EPERM;
}
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
- return;
+ return -EINVAL;
}
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
if (!io->base) {
DEV_ERR("%s: Core io is not initialized\n", __func__);
- return;
+ return -EPERM;
}
total_h = timing->active_h + timing->front_porch_h +
timing->back_porch_h + timing->pulse_width_h - 1;
total_v = timing->active_v + timing->front_porch_v +
timing->back_porch_v + timing->pulse_width_v - 1;
- DSS_REG_W(io, HDMI_TOTAL,
- ((total_v << 16) & 0x0FFF0000) |
- ((total_h << 0) & 0x00000FFF));
+ if (((total_v << 16) & 0xE0000000) || (total_h & 0xFFFFE000)) {
+ DEV_ERR("%s: total v=%d or h=%d is larger than supported\n",
+ __func__, total_v, total_h);
+ return -EPERM;
+ }
+ DSS_REG_W(io, HDMI_TOTAL, (total_v << 16) | (total_h << 0));
start_h = timing->back_porch_h + timing->pulse_width_h;
end_h = (total_h + 1) - timing->front_porch_h;
- DSS_REG_W(io, HDMI_ACTIVE_H,
- ((end_h << 16) & 0x0FFF0000) |
- ((start_h << 0) & 0x00000FFF));
+ if (((end_h << 16) & 0xE0000000) || (start_h & 0xFFFFE000)) {
+ DEV_ERR("%s: end_h=%d or start_h=%d is larger than supported\n",
+ __func__, end_h, start_h);
+ return -EPERM;
+ }
+ DSS_REG_W(io, HDMI_ACTIVE_H, (end_h << 16) | (start_h << 0));
start_v = timing->back_porch_v + timing->pulse_width_v - 1;
end_v = total_v - timing->front_porch_v;
- DSS_REG_W(io, HDMI_ACTIVE_V,
- ((end_v << 16) & 0x0FFF0000) |
- ((start_v << 0) & 0x00000FFF));
+ if (((end_v << 16) & 0xE0000000) || (start_v & 0xFFFFE000)) {
+ DEV_ERR("%s: end_v=%d or start_v=%d is larger than supported\n",
+ __func__, end_v, start_v);
+ return -EPERM;
+ }
+ DSS_REG_W(io, HDMI_ACTIVE_V, (end_v << 16) | (start_v << 0));
if (timing->interlaced) {
- DSS_REG_W(io, HDMI_V_TOTAL_F2,
- ((total_v + 1) << 0) & 0x00000FFF);
-
+ DSS_REG_W(io, HDMI_V_TOTAL_F2, (total_v + 1) << 0);
DSS_REG_W(io, HDMI_ACTIVE_V_F2,
- (((start_v + 1) << 0) & 0x00000FFF) |
- (((end_v + 1) << 16) & 0x0FFF0000));
+ ((end_v + 1) << 16) | ((start_v + 1) << 0));
} else {
DSS_REG_W(io, HDMI_V_TOTAL_F2, 0);
DSS_REG_W(io, HDMI_ACTIVE_V_F2, 0);
@@ -702,6 +730,8 @@
((timing->interlaced << 31) & 0x80000000) |
((timing->active_low_h << 29) & 0x20000000) |
((timing->active_low_v << 28) & 0x10000000));
+
+ return 0;
} /* hdmi_tx_video_setup */
static void hdmi_tx_set_avi_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -772,6 +802,18 @@
case HDMI_VFRMT_720x576p50_4_3:
mode = 15;
break;
+ case HDMI_VFRMT_3840x2160p30_16_9:
+ mode = 16;
+ break;
+ case HDMI_VFRMT_3840x2160p25_16_9:
+ mode = 17;
+ break;
+ case HDMI_VFRMT_3840x2160p24_16_9:
+ mode = 18;
+ break;
+ case HDMI_VFRMT_4096x2160p24_16_9:
+ mode = 19;
+ break;
default:
DEV_INFO("%s: mode %d not supported\n", __func__,
hdmi_ctrl->video_resolution);
@@ -846,12 +888,87 @@
regVal = regVal << 8 | avi_iframe[14];
DSS_REG_W(io, HDMI_AVI_INFO3, regVal);
- /* 0x3 for AVI InfFrame enable (every frame) */
+ /* AVI InfFrame enable (every frame) */
DSS_REG_W(io, HDMI_INFOFRAME_CTRL0,
- DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) |
- 0x00000003L);
+ DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) | BIT(1) | BIT(0));
} /* hdmi_tx_set_avi_infoframe */
+/* todo: add 3D support */
+static void hdmi_tx_set_vendor_specific_infoframe(
+ struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ int i;
+ u8 vs_iframe[9]; /* two header + length + 6 data */
+ u32 sum, reg_val;
+ u32 hdmi_vic, hdmi_video_format;
+ struct dss_io_data *io = NULL;
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return;
+ }
+
+ /* HDMI Spec 1.4a Table 8-10 */
+ vs_iframe[0] = 0x81; /* type */
+ vs_iframe[1] = 0x1; /* version */
+ vs_iframe[2] = 0x8; /* length */
+
+ vs_iframe[3] = 0x0; /* PB0: checksum */
+
+ /* PB1..PB3: 24 Bit IEEE Registration Code 00_0C_03 */
+ vs_iframe[4] = 0x03;
+ vs_iframe[5] = 0x0C;
+ vs_iframe[6] = 0x00;
+
+ hdmi_video_format = 0x1;
+ switch (hdmi_ctrl->video_resolution) {
+ case HDMI_VFRMT_3840x2160p30_16_9:
+ hdmi_vic = 0x1;
+ break;
+ case HDMI_VFRMT_3840x2160p25_16_9:
+ hdmi_vic = 0x2;
+ break;
+ case HDMI_VFRMT_3840x2160p24_16_9:
+ hdmi_vic = 0x3;
+ break;
+ case HDMI_VFRMT_4096x2160p24_16_9:
+ hdmi_vic = 0x4;
+ break;
+ default:
+ hdmi_video_format = 0x0;
+ hdmi_vic = 0x0;
+ }
+
+ /* PB4: HDMI Video Format[7:5], Reserved[4:0] */
+ vs_iframe[7] = (hdmi_video_format << 5) & 0xE0;
+
+ /* PB5: HDMI_VIC or 3D_Structure[7:4], Reserved[3:0] */
+ vs_iframe[8] = hdmi_vic;
+
+ /* compute checksum */
+ sum = 0;
+ for (i = 0; i < 9; i++)
+ sum += vs_iframe[i];
+
+ sum &= 0xFF;
+ sum = 256 - sum;
+ vs_iframe[3] = (u8)sum;
+
+ reg_val = (hdmi_vic << 16) | (vs_iframe[3] << 8) |
+ (hdmi_video_format << 5) | vs_iframe[2];
+ DSS_REG_W(io, HDMI_VENSPEC_INFO0, reg_val);
+
+ /* vendor specific info-frame enable (every frame) */
+ DSS_REG_W(io, HDMI_INFOFRAME_CTRL0,
+ DSS_REG_R(io, HDMI_INFOFRAME_CTRL0) | BIT(13) | BIT(12));
+} /* hdmi_tx_set_vendor_specific_infoframe */
+
static void hdmi_tx_set_spd_infoframe(struct hdmi_tx_ctrl *hdmi_ctrl)
{
u32 packet_header = 0;
@@ -1610,7 +1727,13 @@
hdmi_tx_set_mode(hdmi_ctrl, true);
- hdmi_tx_video_setup(hdmi_ctrl, hdmi_ctrl->video_resolution);
+ rc = hdmi_tx_video_setup(hdmi_ctrl, hdmi_ctrl->video_resolution);
+ if (rc) {
+ DEV_ERR("%s: hdmi_tx_video_setup failed. rc=%d\n",
+ __func__, rc);
+ hdmi_tx_set_mode(hdmi_ctrl, false);
+ return rc;
+ }
if (!hdmi_tx_is_dvi_mode(hdmi_ctrl)) {
rc = hdmi_tx_audio_setup(hdmi_ctrl);
@@ -1624,11 +1747,11 @@
switch_set_state(&hdmi_ctrl->audio_sdev, 1);
DEV_INFO("%s: hdmi_audio state switch to %d\n", __func__,
hdmi_ctrl->audio_sdev.state);
- }
- hdmi_tx_set_avi_infoframe(hdmi_ctrl);
- /* todo: CONFIG_FB_MSM_HDMI_3D */
- hdmi_tx_set_spd_infoframe(hdmi_ctrl);
+ hdmi_tx_set_avi_infoframe(hdmi_ctrl);
+ hdmi_tx_set_vendor_specific_infoframe(hdmi_ctrl);
+ hdmi_tx_set_spd_infoframe(hdmi_ctrl);
+ }
/* todo: HDCP/CEC */
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index a3d76be..ad63605 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -16,73 +16,24 @@
#include "mdss_hdmi_util.h"
static struct hdmi_disp_mode_timing_type
- hdmi_supported_video_mode_lut[HDMI_VFRMT_MAX] = {
- HDMI_SETTINGS_640x480p60_4_3,
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x240p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480i60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x240p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x288p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576i50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x288p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p24_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p25_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080p30_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x480p60_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_2880x576p50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1250i50_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i100_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p100_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p100_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i100_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1920x1080i120_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1280x720p120_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p120_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i120_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x576p200_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x576i200_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_720x480p240_16_9),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_4_3),
- VFRMT_NOT_SUPPORTED(HDMI_VFRMT_1440x480i240_16_9),
-}; /* hdmi_supported_video_mode_lut */
+ hdmi_supported_video_mode_lut[HDMI_VFRMT_MAX];
#define HDMI_SETUP_LUT(MODE) do { \
struct hdmi_disp_mode_timing_type mode = HDMI_SETTINGS_##MODE; \
hdmi_supported_video_mode_lut[mode.video_format] = mode; \
} while (0)
+void hdmi_init_supported_video_timings(void)
+{
+ int i;
+
+ for (i = 0; i < HDMI_VFRMT_MAX; i++) {
+ struct hdmi_disp_mode_timing_type mode = VFRMT_NOT_SUPPORTED(i);
+
+ hdmi_supported_video_mode_lut[i] = mode;
+ }
+} /* hdmi_init_supported_video_timings */
+
const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode)
{
const struct hdmi_disp_mode_timing_type *ret = NULL;
@@ -203,6 +154,21 @@
case HDMI_VFRMT_1920x1080p60_16_9:
HDMI_SETUP_LUT(1920x1080p60_16_9);
break;
+ case HDMI_VFRMT_2560x1600p60_16_9:
+ HDMI_SETUP_LUT(2560x1600p60_16_9);
+ break;
+ case HDMI_VFRMT_3840x2160p30_16_9:
+ HDMI_SETUP_LUT(3840x2160p30_16_9);
+ break;
+ case HDMI_VFRMT_3840x2160p25_16_9:
+ HDMI_SETUP_LUT(3840x2160p25_16_9);
+ break;
+ case HDMI_VFRMT_3840x2160p24_16_9:
+ HDMI_SETUP_LUT(3840x2160p24_16_9);
+ break;
+ case HDMI_VFRMT_4096x2160p24_16_9:
+ HDMI_SETUP_LUT(4096x2160p24_16_9);
+ break;
default:
DEV_ERR("%s: unsupported mode=%d\n", __func__, mode);
}
@@ -270,6 +236,11 @@
case HDMI_VFRMT_720x480p240_16_9: return " 720x 480 p240 16/9";
case HDMI_VFRMT_1440x480i240_4_3: return "1440x 480 i240 4/3";
case HDMI_VFRMT_1440x480i240_16_9: return "1440x 480 i240 16/9";
+ case HDMI_VFRMT_2560x1600p60_16_9: return "2560x1600 p60 16/9";
+ case HDMI_VFRMT_3840x2160p30_16_9: return "3840x2160 p30 16/9";
+ case HDMI_VFRMT_3840x2160p25_16_9: return "3840x2160 p25 16/9";
+ case HDMI_VFRMT_3840x2160p24_16_9: return "3840x2160 p24 16/9";
+ case HDMI_VFRMT_4096x2160p24_16_9: return "4096x2160 p24 16/9";
default: return "???";
}
} /* hdmi_get_video_fmt_2string */
@@ -550,8 +521,8 @@
*/
DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_SETUP, 0xFF000000);
- /* Enable reference timer to 27 micro-seconds */
- DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_REF, (1 << 16) | (27 << 0));
+ /* Enable reference timer to 19 micro-seconds */
+ DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_REF, (1 << 16) | (19 << 0));
} /* hdmi_ddc_config */
int hdmi_ddc_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.h b/drivers/video/msm/mdss/mdss_hdmi_util.h
index c970ebe..cd7b7dd 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.h
@@ -216,7 +216,7 @@
#define QFPROM_RAW_FEAT_CONFIG_ROW0_LSB (0x000000F8)
#define QFPROM_RAW_FEAT_CONFIG_ROW0_MSB (0x000000FC)
-/* all video formats defined by EIA CEA 861D */
+/* all video formats defined by EIA CEA-861-E */
#define HDMI_VFRMT_640x480p60_4_3 0
#define HDMI_VFRMT_720x480p60_4_3 1
#define HDMI_VFRMT_720x480p60_16_9 2
@@ -292,7 +292,18 @@
#define HDMI_VFRMT_1440x480i240_4_3 HDMI_VFRMT_720x480i240_4_3
#define HDMI_VFRMT_720x480i240_16_9 58
#define HDMI_VFRMT_1440x480i240_16_9 HDMI_VFRMT_720x480i240_16_9
-#define HDMI_VFRMT_MAX 59
+/* Video Identification Codes from 65-127 are reserved for the future */
+#define HDMI_VFRMT_END 127
+/* extended video formats */
+#define HDMI_VFRMT_3840x2160p30_16_9 (HDMI_VFRMT_END + 1)
+#define HDMI_VFRMT_3840x2160p25_16_9 (HDMI_VFRMT_END + 2)
+#define HDMI_VFRMT_3840x2160p24_16_9 (HDMI_VFRMT_END + 3)
+#define HDMI_VFRMT_4096x2160p24_16_9 (HDMI_VFRMT_END + 4)
+#define HDMI_EVFRMT_END HDMI_VFRMT_4096x2160p24_16_9
+/* DVI only resolutions */
+#define HDMI_VFRMT_2560x1600p60_16_9 (HDMI_EVFRMT_END + 1)
+#define DVI_VFRMT_END HDMI_VFRMT_2560x1600p60_16_9
+#define HDMI_VFRMT_MAX (DVI_VFRMT_END + 1)
#define HDMI_VFRMT_FORCE_32BIT 0x7FFFFFFF
#define VFRMT_NOT_SUPPORTED(VFRMT) \
@@ -349,6 +360,21 @@
#define HDMI_SETTINGS_1920x1080p30_16_9 \
{HDMI_VFRMT_1920x1080p30_16_9, 1920, 88, 44, 148, false, \
1080, 4, 5, 36, false, 74250, 30000, false, true}
+#define HDMI_SETTINGS_2560x1600p60_16_9 \
+ {HDMI_VFRMT_2560x1600p60_16_9, 2560, 48, 32, 80, false, \
+ 1600, 3, 6, 37, false, 268500, 60000, false, true}
+#define HDMI_SETTINGS_3840x2160p30_16_9 \
+ {HDMI_VFRMT_3840x2160p30_16_9, 3840, 176, 88, 296, false, \
+ 2160, 8, 10, 72, false, 297000, 30000, false, true}
+#define HDMI_SETTINGS_3840x2160p25_16_9 \
+ {HDMI_VFRMT_3840x2160p25_16_9, 3840, 1056, 88, 296, false, \
+ 2160, 8, 10, 72, false, 297000, 25000, false, true}
+#define HDMI_SETTINGS_3840x2160p24_16_9 \
+ {HDMI_VFRMT_3840x2160p24_16_9, 3840, 1276, 88, 296, false, \
+ 2160, 8, 10, 72, false, 297000, 24000, false, true}
+#define HDMI_SETTINGS_4096x2160p24_16_9 \
+ {HDMI_VFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false, \
+ 2160, 8, 10, 72, false, 297000, 24000, false, true}
#define TOP_AND_BOTTOM 0x10
#define FRAME_PACKING 0x20
@@ -397,6 +423,8 @@
int retry;
};
+/* video timing related utility routines */
+void hdmi_init_supported_video_timings(void);
int hdmi_get_video_id_code(struct hdmi_disp_mode_timing_type *timing_in);
const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode);
void hdmi_set_supported_mode(u32 mode);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 78f96c8..d189408 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1259,7 +1259,7 @@
output_vcd_frm->flags |=
VCD_FRAME_FLAG_DATACORRUPT;
}
- if (decoder->codec.codec != VCD_CODEC_H264 ||
+ if (decoder->codec.codec != VCD_CODEC_H264 &&
decoder->codec.codec != VCD_CODEC_MPEG2)
output_vcd_frm->flags &= ~VCD_FRAME_FLAG_DATACORRUPT;
output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top;
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 4e9e1ce..2874a3b 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -22,10 +22,6 @@
#define WCD9XXX_NUM_IRQ_REGS 4
#define WCD9XXX_SLIM_NUM_PORT_REG 3
-
-#define WCD9XXX_INTERFACE_TYPE_SLIMBUS 0x00
-#define WCD9XXX_INTERFACE_TYPE_I2C 0x01
-
#define TABLA_VERSION_1_0 0
#define TABLA_VERSION_1_1 1
#define TABLA_VERSION_2_0 2
@@ -135,6 +131,12 @@
wait_queue_head_t dai_wait;
};
+enum wcd9xxx_intf_status {
+ WCD9XXX_INTERFACE_TYPE_PROBING,
+ WCD9XXX_INTERFACE_TYPE_SLIMBUS,
+ WCD9XXX_INTERFACE_TYPE_I2C,
+};
+
#define WCD9XXX_CH(xport, xshift) \
{.port = xport, .shift = xshift}
@@ -177,6 +179,7 @@
u32 num_tx_port;
struct wcd9xxx_ch *rx_chs;
struct wcd9xxx_ch *tx_chs;
+ u32 mclk_rate;
};
int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
@@ -192,7 +195,7 @@
int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx);
void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx);
int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
-int wcd9xxx_get_intf_type(void);
+enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void);
bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index a7ca417..bfd95a6 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -154,6 +154,7 @@
struct wcd9xxx_micbias_setting micbias;
struct wcd9xxx_ocp_setting ocp;
struct wcd9xxx_regulator regulator[MAX_REGULATOR];
+ u32 mclk_rate;
};
#endif
diff --git a/include/media/msm_media_info.h b/include/media/msm_media_info.h
index 13ce043..ab76d79 100644
--- a/include/media/msm_media_info.h
+++ b/include/media/msm_media_info.h
@@ -97,7 +97,7 @@
uv_sclines = VENUS_UV_SCANLINES(color_fmt, height);
switch (color_fmt) {
case COLOR_FMT_NV12:
- uv_alignment = 0;
+ uv_alignment = 4096;
y_plane = y_stride * y_sclines;
uv_plane = uv_stride * uv_sclines + uv_alignment;
size = y_plane + uv_plane;
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 369cf45..2787e8d 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -47,6 +47,11 @@
HAL_VCAP_RGB,
};
+enum nr_threshold_mode {
+ NR_THRESHOLD_STATIC = 0,
+ NR_THRESHOLD_DYNAMIC,
+};
+
enum nr_mode {
NR_DISABLE = 0,
NR_AUTO,
@@ -73,6 +78,7 @@
};
struct nr_param {
+ enum nr_threshold_mode threshold;
enum nr_mode mode;
enum nr_decay_ratio decay_ratio;
uint8_t window;
diff --git a/mm/filemap.c b/mm/filemap.c
index 79c4b2b..8ed5c5c 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2343,9 +2343,17 @@
if (page)
goto found;
+retry:
page = __page_cache_alloc(gfp_mask & ~gfp_notmask);
if (!page)
return NULL;
+
+ if (is_cma_pageblock(page)) {
+ __free_page(page);
+ gfp_notmask |= __GFP_MOVABLE;
+ goto retry;
+ }
+
status = add_to_page_cache_lru(page, mapping, index,
GFP_KERNEL & ~gfp_notmask);
if (unlikely(status)) {
diff --git a/sound/soc/codecs/msm_stub.c b/sound/soc/codecs/msm_stub.c
index 7e603b4..0143e51 100644
--- a/sound/soc/codecs/msm_stub.c
+++ b/sound/soc/codecs/msm_stub.c
@@ -34,7 +34,7 @@
.capture = { /* Support maximum range */
.stream_name = "Record",
.channels_min = 1,
- .channels_max = 4,
+ .channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 6aa5bbb..76623b1 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -54,7 +54,8 @@
#define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
#define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
#define TAIKO_SLIM_IRQ_PORT_CLOSED (1 << 2)
-
+#define TAIKO_MCLK_CLK_12P288MHZ 12288000
+#define TAIKO_MCLK_CLK_9P6HZ 9600000
enum {
AIF1_PB = 0,
AIF1_CAP,
@@ -3120,11 +3121,7 @@
static int taiko_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
- struct snd_soc_codec *codec = dai->codec;
- if (freq == TAIKO_MCLK_CLK_12P288MHZ)
- snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x04);
- else if (freq == TAIKO_MCLK_CLK_9P6HZ)
- snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x0A);
+ pr_debug("%s\n", __func__);
return 0;
}
@@ -4810,6 +4807,11 @@
taiko->aux_l_gain = 0x1F;
taiko->aux_r_gain = 0x1F;
taiko_update_reg_defaults(codec);
+ pr_debug("%s: MCLK Rate = %x\n", __func__, wcd9xxx->mclk_rate);
+ if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ)
+ snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x04);
+ else if (wcd9xxx->mclk_rate == TAIKO_MCLK_CLK_9P6HZ)
+ snd_soc_write(codec, TAIKO_A_CHIP_CTL, 0x0A);
taiko_codec_init_reg(codec);
ret = taiko_handle_pdata(taiko);
if (IS_ERR_VALUE(ret)) {
diff --git a/sound/soc/msm/mdm9625.c b/sound/soc/msm/mdm9625.c
index b1822f6..4c7b69d 100644
--- a/sound/soc/msm/mdm9625.c
+++ b/sound/soc/msm/mdm9625.c
@@ -68,7 +68,6 @@
unsigned gpio_no;
char *gpio_name;
};
-static bool cdc_mclk_init;
static struct mutex cdc_mclk_mutex;
static int mdm9625_mi2s_rx_ch = 1;
static int mdm9625_mi2s_tx_ch = 1;
@@ -292,25 +291,6 @@
return ret;
}
-static int set_codec_mclk(struct snd_soc_pcm_runtime *rtd)
-{
- int ret = 0;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_card *card = rtd->card;
- struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
-
- if (cdc_mclk_init == true)
- return 0;
- ret = snd_soc_dai_set_sysclk(codec_dai, TAIKO_MCLK_ID, pdata->mclk_freq,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("%s: Set codec sys clk failed %x", __func__, ret);
- return ret;
- }
- cdc_mclk_init = true;
- return 0;
-}
-
static int mdm9625_mi2s_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -320,7 +300,6 @@
SNDRV_PCM_HW_PARAM_CHANNELS);
rate->min = rate->max = 48000;
channels->min = channels->max = mdm9625_mi2s_rx_ch;
- set_codec_mclk(rtd);
return 0;
}
@@ -333,7 +312,6 @@
SNDRV_PCM_HW_PARAM_CHANNELS);
rate->min = rate->max = 48000;
channels->min = channels->max = mdm9625_mi2s_tx_ch;
- set_codec_mclk(rtd);
return 0;
}
@@ -713,7 +691,6 @@
mutex_init(&cdc_mclk_mutex);
gpio_enable = false;
- cdc_mclk_init = false;
if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "No platform supplied from device tree\n");
return -EINVAL;
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 6f0dbf2..2f4c256 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -900,7 +900,7 @@
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
- .channels_max = 4,
+ .channels_max = 8,
.rate_min = 8000,
.rate_max = 48000,
},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 73a04c2..1aa12e3 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -33,8 +33,10 @@
#include <mach/msm_subsystem_map.h>
#include "msm-pcm-afe-v2.h"
-#define MIN_PERIOD_SIZE (128 * 2)
-#define MAX_PERIOD_SIZE (128 * 2 * 2 * 6)
+#define MIN_PERIOD_SIZE (128 * 2 * 8)
+#define MAX_PERIOD_SIZE (128 * 2 * 2 * 6 * 8)
+#define MAX_NUM_PERIODS 384
+#define MIN_NUM_PERIODS 32
static struct snd_pcm_hardware msm_afe_hardware = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -47,12 +49,12 @@
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
- .channels_max = 2,
+ .channels_max = 8,
.buffer_bytes_max = MAX_PERIOD_SIZE * 32,
.period_bytes_min = MIN_PERIOD_SIZE,
.period_bytes_max = MAX_PERIOD_SIZE,
- .periods_min = 32,
- .periods_max = 384,
+ .periods_min = MIN_NUM_PERIODS,
+ .periods_max = MAX_NUM_PERIODS,
.fifo_size = 0,
};
static enum hrtimer_restart afe_hrtimer_callback(struct hrtimer *hrt);
@@ -353,6 +355,17 @@
if (ret < 0)
pr_err("snd_pcm_hw_constraint_integer failed\n");
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ MAX_NUM_PERIODS * MIN_PERIOD_SIZE,
+ MIN_NUM_PERIODS * MAX_PERIOD_SIZE);
+ if (ret < 0) {
+ pr_err("constraint for buffer bytes min max ret = %d\n",
+ ret);
+ }
+ }
+
return 0;
}
@@ -497,8 +510,8 @@
dir = OUT;
rc = q6afe_audio_client_buf_alloc_contiguous(dir,
prtd->audio_client,
- runtime->hw.period_bytes_min,
- runtime->hw.periods_max);
+ (params_buffer_bytes(params) / params_periods(params)),
+ params_periods(params));
if (rc < 0) {
pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc);
mutex_unlock(&prtd->lock);
@@ -517,14 +530,14 @@
dma_buf->private_data = NULL;
dma_buf->area = buf[0].data;
dma_buf->addr = buf[0].phys;
- dma_buf->bytes = runtime->hw.buffer_bytes_max;
+ dma_buf->bytes = params_buffer_bytes(params);
if (!dma_buf->area) {
pr_err("%s:MSM AFE physical memory allocation failed\n",
__func__);
mutex_unlock(&prtd->lock);
return -ENOMEM;
}
- memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
+ memset(dma_buf->area, 0, params_buffer_bytes(params));
prtd->dma_addr = (u32) dma_buf->addr;
mutex_unlock(&prtd->lock);