Merge "msm: avs: Remove vestigial software based AVS"
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/hwmon/qpnp-adc-current.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
index e458ea0..fbe8ffa 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-current.txt
@@ -10,6 +10,8 @@
Required properties:
- compatible : should be "qcom,qpnp-iadc" for Current ADC driver.
- reg : offset and length of the PMIC Aribter register map.
+- address-cells : Must be one.
+- size-cells : Must be zero.
- interrupts : The USR bank peripheral IADC interrupt.
- interrupt-names : Should contain "eoc-int-en-set".
- qcom,adc-bit-resolution : Bit resolution of the ADC.
@@ -21,6 +23,7 @@
Required properties:
- label : Channel name used for sysfs entry.
+- reg : AMUX channel number.
- qcom,channel-num : Channel number associated to the AMUX input.
- qcom,decimation : Sampling rate to use for the individual channel measurement.
Select from the following unsigned int.
@@ -84,6 +87,8 @@
qcom,iadc@3200 {
compatible = "qcom,qpnp-iadc";
reg = <0x3200 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
interrupts = <0 0x36 0>;
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <16>;
@@ -93,7 +98,7 @@
/* Channel Node */
chan@0 = {
label = "rsense";
- qcom,channel-num = <0>;
+ reg = <0>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <20>;
qcom,calibration-type = "fresh";
diff --git a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
index e23605c..bb66e7b 100644
--- a/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
+++ b/Documentation/devicetree/bindings/hwmon/qpnp-adc-voltage.txt
@@ -10,6 +10,8 @@
Required properties:
- compatible : should be "qcom,qpnp-vadc" for Voltage ADC driver.
- reg : offset and length of the PMIC Aribter register map.
+- address-cells : Must be one.
+- size-cells : Must be zero.
- interrupts : The USR bank peripheral VADC interrupt.
- interrupt-names : Should contain "eoc-int-en-set".
- qcom,adc-bit-resolution : Bit resolution of the ADC.
@@ -20,7 +22,7 @@
Required properties:
- label : Channel name used for sysfs entry.
-- qcom,channel-num : Channel number associated to the AMUX input.
+- reg : AMUX channel number.
- qcom,decimation : Sampling rate to use for the individual channel measurement.
Select from following unsigned int.
0 : 512
@@ -82,6 +84,8 @@
qcom,vadc@3100 {
compatible = "qcom,qpnp-vadc";
reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
interrupts = <0x0 0x31 0x0>;
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <15>;
@@ -90,7 +94,7 @@
/* Channel Node */
chan@0 {
label = "usb_in";
- qcom,channel-num = <0>;
+ reg = <0>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <20>;
qcom,calibration-type = "absolute";
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/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
new file mode 100644
index 0000000..f1f4e94
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt
@@ -0,0 +1,120 @@
+Qualcomm's QPNP PMIC thermal monitor ADC driver (VADC_TM)
+
+QPNP PMIC thermal monitoring (TM) provides interface to thermal clients
+to set temperature thresholds and receive notification when the thresholds
+are crossed. A 15 bit ADC is used for measurements. The driver is part
+of the sysfs thermal framework that provides support to read the trip
+points, set threshold for the trip points and enable the trip points.
+Seperate kernel api's are provided to usb_id and batt_therm
+to set thresholds and receive threshold notifications.
+
+VADC_TM node
+
+Required properties:
+- compatible : should be "qcom,qpnp-adc-tm" for thermal ADC driver.
+- reg : offset and length of the PMIC Aribter register map.
+- address-cells : Must be one.
+- size-cells : Must be zero.
+- interrupts : The thermal ADC bank peripheral interrupts for eoc, high and low interrupts.
+- interrupt-names : Should be "eoc-int-en-set", "high-thr-en-set" and "low-thr-en-set".
+- qcom,adc-bit-resolution : Bit resolution of the ADC.
+- qcom,adc-vdd-reference : Voltage reference used by the ADC.
+
+Channel nodes
+NOTE: Atleast one Channel node is required.
+
+Required properties:
+- label : Channel name used for sysfs entry.
+- reg : AMUX channel number.
+- qcom,decimation : Sampling rate to use for the individual channel measurement.
+ Select from the following unsigned int.
+ 0 : 512
+ 1 : 1K
+ 2 : 2K
+ 3 : 4K
+- qcom,pre-div-channel-scaling : Pre-div used for the channel before the signal is being measured.
+ Select from the following unsigned int for the corresponding
+ numerator/denominator pre-div ratio.
+ 0 : pre-div ratio of {1, 1}
+ 1 : pre-div ratio of {1, 3}
+ 2 : pre-div ratio of {1, 4}
+ 3 : pre-div ratio of {1, 6}
+ 4 : pre-div ratio of {1, 20}
+- qcom,calibration-type : Reference voltage to use for channel calibration.
+ Channel calibration is dependendent on the channel.
+ Certain channels like XO_THERM, BATT_THERM use ratiometric
+ calibration. Most other channels fall under absolute calibration.
+ Select from the following strings.
+ "absolute" : Uses the 625mv and 1.25V reference channels.
+ "ratiometric" : Uses the reference Voltage/GND for calibration.
+- qcom,scale-function : Scaling fuction used to convert raw ADC code to units specific to
+ a given channel.
+ Select from the following unsigned int.
+ 0 : Default scaling to convert raw adc code to voltage.
+ 1 : Conversion to temperature based on btm parameters.
+ 2 : Returns result in milli degree's Centigrade.
+ 3 : Returns current across 0.1 ohm resistor.
+ 4 : Returns XO thermistor voltage in degree's Centigrade.
+- qcom,hw-settle-time : Settling period for the channel before ADC read.
+ Select from the following unsigned int.
+ 0 : 0us
+ 1 : 100us
+ 2 : 200us
+ 3 : 300us
+ 4 : 400us
+ 5 : 500us
+ 6 : 600us
+ 7 : 700us
+ 8 : 800us
+ 9 : 900us
+ 0xa : 1ms
+ 0xb : 2ms
+ 0xc : 4ms
+ 0xd : 6ms
+ 0xe : 8ms
+ 0xf : 10ms
+- qcom,fast-avg-setup : Average number of samples to be used for measurement. Fast averaging
+ provides the option to obtain a single measurement from the ADC that
+ is an average of multiple samples. The value selected is 2^(value)
+ Select from
+ 0 : 1
+ 1 : 2
+ 2 : 4
+ 3 : 8
+ 4 : 16
+ 5 : 32
+ 6 : 64
+ 7 : 128
+ 8 : 256
+- qcom,btm-channel-number : There are 5 BTM channels. The BTM channel numbers are statically
+ allocated to the corresponding channel node.
+
+Example:
+ /* Main Node */
+ qcom,vadc@3400 {
+ compatible = "qcom,qpnp-adc-tm";
+ reg = <0x3400 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x34 0x0>,
+ <0x0 0x34 0x3>,
+ <0x0 0x34 0x4>;
+ interrupt-names = "eoc-int-en-set",
+ "high-thr-en-set",
+ "low-thr-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+
+ /* Channel Node */
+ chan@b5 {
+ label = "pa_therm1";
+ reg = <0xb5>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x70>;
+ };
+ };
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
index 2105e8a..322e601 100755
--- a/arch/arm/boot/dts/msm-pm8019.dtsi
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -156,13 +156,15 @@
pm8019_vadc: vadc@3100 {
compatible = "qcom,qpnp-vadc";
reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
interrupts = <0x0 0x31 0x0>;
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
chan@8 {
label = "die_temp";
- qcom,channel-num = <8>;
+ reg = <8>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
@@ -173,7 +175,7 @@
chan@9 {
label = "ref_625mv";
- qcom,channel-num = <9>;
+ reg = <9>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
@@ -182,9 +184,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@10 {
+ chan@a {
label = "ref_1250v";
- qcom,channel-num = <10>;
+ reg = <0xa>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
diff --git a/arch/arm/boot/dts/msm-pm8110.dtsi b/arch/arm/boot/dts/msm-pm8110.dtsi
new file mode 100644
index 0000000..94db3ea
--- /dev/null
+++ b/arch/arm/boot/dts/msm-pm8110.dtsi
@@ -0,0 +1,18 @@
+/* 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.
+ */
+
+&spmi_bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+};
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index fe7b3e9..d5f59de 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -492,6 +492,8 @@
vadc@3100 {
compatible = "qcom,qpnp-vadc";
reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
interrupts = <0x0 0x31 0x0>;
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <15>;
@@ -499,7 +501,7 @@
chan@0 {
label = "usb_in";
- qcom,channel-num = <0>;
+ reg = <0>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <4>;
qcom,calibration-type = "absolute";
@@ -510,7 +512,7 @@
chan@1 {
label = "dc_in";
- qcom,channel-num = <1>;
+ reg = <1>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <4>;
qcom,calibration-type = "absolute";
@@ -521,7 +523,7 @@
chan@2 {
label = "vchg_sns";
- qcom,channel-num = <2>;
+ reg = <2>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <3>;
qcom,calibration-type = "absolute";
@@ -532,7 +534,7 @@
chan@3 {
label = "spare1";
- qcom,channel-num = <3>;
+ reg = <3>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <6>;
qcom,calibration-type = "absolute";
@@ -543,7 +545,7 @@
chan@4 {
label = "spare2";
- qcom,channel-num = <4>;
+ reg = <4>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <6>;
qcom,calibration-type = "absolute";
@@ -554,7 +556,7 @@
chan@5 {
label = "vcoin";
- qcom,channel-num = <5>;
+ reg = <5>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <1>;
qcom,calibration-type = "absolute";
@@ -565,7 +567,7 @@
chan@6 {
label = "vbat_sns";
- qcom,channel-num = <6>;
+ reg = <6>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <1>;
qcom,calibration-type = "absolute";
@@ -576,7 +578,7 @@
chan@7 {
label = "vph_pwr";
- qcom,channel-num = <7>;
+ reg = <7>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <1>;
qcom,calibration-type = "absolute";
@@ -587,7 +589,7 @@
chan@8 {
label = "die_temp";
- qcom,channel-num = <8>;
+ reg = <8>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
@@ -598,7 +600,7 @@
chan@9 {
label = "ref_625mv";
- qcom,channel-num = <9>;
+ reg = <9>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
@@ -607,9 +609,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@10 {
+ chan@a {
label = "ref_1250v";
- qcom,channel-num = <10>;
+ reg = <0xa>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "absolute";
@@ -618,9 +620,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@48 {
+ chan@30 {
label = "batt_therm";
- qcom,channel-num = <48>;
+ reg = <0x30>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -629,9 +631,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@49 {
+ chan@31 {
label = "batt_id";
- qcom,channel-num = <49>;
+ reg = <0x31>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -640,9 +642,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@178 {
+ chan@b2 {
label = "xo_therm_pu2";
- qcom,channel-num = <178>;
+ reg = <0xb2>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -651,9 +653,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@179 {
+ chan@b3 {
label = "msm_therm";
- qcom,channel-num = <179>;
+ reg = <0xb3>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -662,9 +664,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@180 {
+ chan@b4 {
label = "emmc_therm";
- qcom,channel-num = <180>;
+ reg = <0xb4>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -673,9 +675,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@181 {
+ chan@b5 {
label = "pa_therm1";
- qcom,channel-num = <181>;
+ reg = <0xb5>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -684,9 +686,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@183 {
+ chan@b7 {
label = "pa_therm2";
- qcom,channel-num = <183>;
+ reg = <0xb7>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -695,9 +697,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@184 {
+ chan@b8 {
label = "quiet_therm";
- qcom,channel-num = <184>;
+ reg = <0xb8>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -706,9 +708,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@185 {
+ chan@b9 {
label = "usb_id";
- qcom,channel-num = <185>;
+ reg = <0xb9>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -721,6 +723,8 @@
iadc@3600 {
compatible = "qcom,qpnp-iadc";
reg = <0x3600 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
interrupts = <0x0 0x36 0x0>;
interrupt-names = "eoc-int-en-set";
qcom,adc-bit-resolution = <16>;
@@ -729,7 +733,7 @@
chan@0 {
label = "internal_rsense";
- qcom,channel-num = <0>;
+ reg = <0>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <1>;
qcom,calibration-type = "absolute";
@@ -738,6 +742,82 @@
qcom,fast-avg-setup = <0>;
};
};
+
+ qcom,vadc@3400 {
+ compatible = "qcom,qpnp-adc-tm";
+ reg = <0x3400 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x34 0x0>,
+ <0x0 0x34 0x3>,
+ <0x0 0x34 0x4>;
+ interrupt-names = "eoc-int-en-set",
+ "high-thr-en-set",
+ "low-thr-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+
+ /* Channel Node */
+ chan@b9 {
+ label = "usb_id";
+ reg = <0xb9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x48>;
+ };
+
+ chan@30 {
+ label = "batt_therm";
+ reg = <0x30>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <1>;
+ qcom,hw-settle-time = <0xf>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x68>;
+ };
+
+ chan@b5 {
+ label = "pa_therm1";
+ reg = <0xb5>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x70>;
+ };
+
+ chan@b7 {
+ label = "pa_therm2";
+ reg = <0xb7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x78>;
+ };
+
+ chan@b4 {
+ label = "emmc_therm";
+ reg = <0xb4>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x80>;
+ };
+ };
};
qcom,pm8941@1 {
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..8ad4eda 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>;
};
@@ -215,6 +216,96 @@
qcom,pet-time = <10000>;
qcom,ipi-ping = <1>;
};
+
+ spmi_bus: qcom,spmi@fc4c0000 {
+ cell-index = <0>;
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xfc4cf000 0x1000>,
+ <0Xfc4cb000 0x1000>;
+ /* 190,ee0_krait_hlos_spmi_periph_irq */
+ /* 187,channel_0_krait_hlos_trans_done_irq */
+ interrupts = <0 190 0>, <0 187 0>;
+ qcom,not-wakeup;
+ qcom,pmic-arb-ee = <0>;
+ qcom,pmic-arb-channel = <0>;
+ qcom,pmic-arb-ppid-map = <0x001000a0>, /* PM8110 */
+ <0x005000a2>, /* INTERRUPT */
+ <0x006000a3>, /* SPMI_0 */
+ <0x00800000>, /* PON0 */
+ <0x01000002>, /* SMBB_CHG */
+ <0x01100003>, /* SMBB_BUCK */
+ <0x01200004>, /* SMBB_BIF */
+ <0x01300005>, /* SMBB_USB */
+ <0x01500006>, /* SMBB_BOOST */
+ <0x01600007>, /* SMBB_MISC */
+ <0x0280000a>, /* COINCELL */
+ <0x02c000a5>, /* MBG */
+ <0x0310000b>, /* VADC1_LC_USR */
+ <0x03200041>, /* VADC3_LC_MDM */
+ <0x0330000c>, /* VADC3_LC_BMS */
+ <0x0340000d>, /* VADC2_LC_BTM */
+ <0x0360000e>, /* IADC1_USR */
+ <0x03700042>, /* IADC2_MDM */
+ <0x0380000f>, /* IADC2_BMS */
+ <0x04000010>, /* BMS_1 */
+ <0x050000a6>, /* SHARED_XO */
+ <0x051000a7>, /* BB_CLK1 */
+ <0x054000a8>, /* RF_CLK1 */
+ <0x055000a9>, /* RF_CLK1 */
+ <0x05a000ab>, /* SLEEP_CLK */
+ <0x06000043>, /* RTC_RW */
+ <0x06100011>, /* RTC_ALARM */
+ <0x070000ac>, /* PBS_CORE */
+ <0x071000ad>, /* PBS_CLIENT_1 */
+ <0x072000ae>, /* PBS_CLIENT_2 */
+ <0x07300013>, /* PBS_CLIENT_3 */
+ <0x07400044>, /* PBS_CLIENT_4 */
+ <0x0a000014>, /* MPP_1 */
+ <0x0a100015>, /* MPP_2 */
+ <0x0a200016>, /* MPP_3 */
+ <0x0a300045>, /* MPP_4 */
+ <0x0c000046>, /* GPIO_1 */
+ <0x0c1000f0>, /* GPIO_2 */
+ <0x0c2000af>, /* GPIO_3 */
+ <0x0c300047>, /* GPIO_4 */
+ <0x0fe000b0>, /* TRIM_0 */
+ <0x110000b1>, /* BUCK_CMN_1 */
+ <0x11400048>, /* SMPS1 */
+ <0x115000b2>, /* SMPS_1_PS1 */
+ <0x116000b3>, /* BUCK_FREQ_1 */
+ <0x11700017>, /* SMPS2 */
+ <0x11800018>, /* FTPS1_2 */
+ <0x11900019>, /* BUCK_FREQ_2 */
+ <0x11a000b4>, /* SMPS3 */
+ <0x11b000b5>, /* SMPS_3_PS1 */
+ <0x11c000b6>, /* BUCK_FREQ_3 */
+ <0x11d000b7>, /* SMPS4 */
+ <0x11e000b8>, /* SMPS_4_PS1 */
+ <0x11f000b9>, /* BUCK_FREQ_4 */
+ <0x140000ba>, /* LDO_1 */
+ <0x141000bb>, /* LDO_2 */
+ <0x142000bc>, /* LDO_3 */
+ <0x143000bd>, /* LDO_4 */
+ <0x144000be>, /* LDO_5 */
+ <0x145000bf>, /* LDO_6 */
+ <0x146000c0>, /* LDO_7 */
+ <0x147000c1>, /* LDO_8 */
+ <0x148000c2>, /* LDO_9 */
+ <0x149000c3>, /* LDO_10 */
+ <0x14a000c4>, /* LDO_11 */
+ <0x14b000c5>, /* LDO_12 */
+ <0x14c000c6>, /* LDO_13 */
+ <0x14d000c7>, /* LDO_14 */
+ <0x14e000c8>, /* LDO_15 */
+ <0x14f000c9>, /* LDO_16 */
+ <0x150000ca>, /* LDO_17 */
+ <0x151000cb>, /* LDO_18 */
+ <0x152000cc>, /* LDO_19 */
+ <0x153000cd>, /* LDO_20 */
+ <0x154000ce>, /* LDO_21 */
+ <0x155000cf>; /* LDO_22 */
+ };
+
};
&gdsc_vfe {
@@ -250,3 +341,4 @@
};
/include/ "msm8910-regulator.dtsi"
+/include/ "msm-pm8110.dtsi"
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.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..ddba4c3 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{
@@ -582,9 +583,9 @@
/include/ "msm9625-regulator.dtsi"
&pm8019_vadc {
- chan@49 {
+ chan@31 {
label = "batt_id_therm";
- qcom,channel-num = <49>;
+ reg = <0x31>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -593,9 +594,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@51 {
+ chan@33 {
label = "pa_therm1";
- qcom,channel-num = <51>;
+ reg = <0x33>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -604,9 +605,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@52 {
+ chan@34 {
label = "pa_therm2";
- qcom,channel-num = <52>;
+ reg = <0x34>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -615,9 +616,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@50 {
+ chan@32 {
label = "xo_therm";
- qcom,channel-num = <50>;
+ reg = <0x32>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
@@ -626,9 +627,9 @@
qcom,fast-avg-setup = <0>;
};
- chan@60 {
+ chan@3c {
label = "xo_therm_amux";
- qcom,channel-num = <60>;
+ reg = <0x3c>;
qcom,decimation = <0>;
qcom,pre-div-channel-scaling = <0>;
qcom,calibration-type = "ratiometric";
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 94e2f36..c534bef 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -286,6 +286,7 @@
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_MONITOR=y
CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_WCD9320_CODEC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_STUB=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 0428362..8e0dadb 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -290,6 +290,7 @@
CONFIG_THERMAL_QPNP=y
CONFIG_WCD9320_CODEC=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_REGULATOR_STUB=y
CONFIG_REGULATOR_QPNP=y
CONFIG_MEDIA_SUPPORT=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 2105648..0010971 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"
@@ -2704,4 +2707,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 077a002..0eacdca 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -304,6 +304,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
@@ -417,3 +418,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/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index d25d503..69b35e9 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -94,10 +94,14 @@
};
static struct msm_bus_paths bw_level_tbl[] __initdata = {
- [0] = BW_MBPS(552), /* At least 69 MHz on bus. */
- [1] = BW_MBPS(1112), /* At least 139 MHz on bus. */
- [2] = BW_MBPS(2224), /* At least 278 MHz on bus. */
- [3] = BW_MBPS(4448), /* At least 556 MHz on bus. */
+ [0] = BW_MBPS(600), /* At least 75 MHz on bus. */
+ [1] = BW_MBPS(800), /* At least 100 MHz on bus. */
+ [2] = BW_MBPS(1200), /* At least 150 MHz on bus. */
+ [3] = BW_MBPS(1600), /* At least 200 MHz on bus. */
+ [4] = BW_MBPS(2224), /* At least 278 MHz on bus. */
+ [5] = BW_MBPS(3200), /* At least 400 MHz on bus. */
+ [6] = BW_MBPS(4448), /* At least 556 MHz on bus. */
+ [7] = BW_MBPS(6400), /* At least 800 MHz on bus. */
};
static struct msm_bus_scale_pdata bus_scale_data __initdata = {
@@ -113,27 +117,27 @@
[2] = { { 422400, HFPLL, 2, 44 }, LVL_NOM, 1050000, 1 },
[3] = { { 499200, HFPLL, 2, 52 }, LVL_NOM, 1050000, 2 },
[4] = { { 576000, HFPLL, 1, 30 }, LVL_NOM, 1050000, 2 },
- [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 1050000, 2 },
- [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 1050000, 2 },
- [7] = { { 806400, HFPLL, 1, 42 }, LVL_NOM, 1050000, 2 },
- [8] = { { 883200, HFPLL, 1, 46 }, LVL_HIGH, 1050000, 2 },
- [9] = { { 960000, HFPLL, 1, 50 }, LVL_HIGH, 1050000, 2 },
- [10] = { { 1036800, HFPLL, 1, 54 }, LVL_HIGH, 1050000, 3 },
- [11] = { { 1113600, HFPLL, 1, 58 }, LVL_HIGH, 1050000, 3 },
- [12] = { { 1190400, HFPLL, 1, 62 }, LVL_HIGH, 1050000, 3 },
- [13] = { { 1267200, HFPLL, 1, 66 }, LVL_HIGH, 1050000, 3 },
- [14] = { { 1344000, HFPLL, 1, 70 }, LVL_HIGH, 1050000, 3 },
- [15] = { { 1420800, HFPLL, 1, 74 }, LVL_HIGH, 1050000, 3 },
- [16] = { { 1497600, HFPLL, 1, 78 }, LVL_HIGH, 1050000, 3 },
- [17] = { { 1574400, HFPLL, 1, 82 }, LVL_HIGH, 1050000, 3 },
- [18] = { { 1651200, HFPLL, 1, 86 }, LVL_HIGH, 1050000, 3 },
- [19] = { { 1728000, HFPLL, 1, 90 }, LVL_HIGH, 1050000, 3 },
- [20] = { { 1804800, HFPLL, 1, 94 }, LVL_HIGH, 1050000, 3 },
- [21] = { { 1881600, HFPLL, 1, 98 }, LVL_HIGH, 1050000, 3 },
- [22] = { { 1958400, HFPLL, 1, 102 }, LVL_HIGH, 1050000, 3 },
- [23] = { { 2035200, HFPLL, 1, 106 }, LVL_HIGH, 1050000, 3 },
- [24] = { { 2112000, HFPLL, 1, 110 }, LVL_HIGH, 1050000, 3 },
- [25] = { { 2188800, HFPLL, 1, 114 }, LVL_HIGH, 1050000, 3 },
+ [5] = { { 652800, HFPLL, 1, 34 }, LVL_NOM, 1050000, 3 },
+ [6] = { { 729600, HFPLL, 1, 38 }, LVL_NOM, 1050000, 3 },
+ [7] = { { 806400, HFPLL, 1, 42 }, LVL_NOM, 1050000, 3 },
+ [8] = { { 883200, HFPLL, 1, 46 }, LVL_HIGH, 1050000, 4 },
+ [9] = { { 960000, HFPLL, 1, 50 }, LVL_HIGH, 1050000, 4 },
+ [10] = { { 1036800, HFPLL, 1, 54 }, LVL_HIGH, 1050000, 4 },
+ [11] = { { 1113600, HFPLL, 1, 58 }, LVL_HIGH, 1050000, 5 },
+ [12] = { { 1190400, HFPLL, 1, 62 }, LVL_HIGH, 1050000, 5 },
+ [13] = { { 1267200, HFPLL, 1, 66 }, LVL_HIGH, 1050000, 6 },
+ [14] = { { 1344000, HFPLL, 1, 70 }, LVL_HIGH, 1050000, 6 },
+ [15] = { { 1420800, HFPLL, 1, 74 }, LVL_HIGH, 1050000, 7 },
+ [16] = { { 1497600, HFPLL, 1, 78 }, LVL_HIGH, 1050000, 7 },
+ [17] = { { 1574400, HFPLL, 1, 82 }, LVL_HIGH, 1050000, 7 },
+ [18] = { { 1651200, HFPLL, 1, 86 }, LVL_HIGH, 1050000, 7 },
+ [19] = { { 1728000, HFPLL, 1, 90 }, LVL_HIGH, 1050000, 7 },
+ [20] = { { 1804800, HFPLL, 1, 94 }, LVL_HIGH, 1050000, 7 },
+ [21] = { { 1881600, HFPLL, 1, 98 }, LVL_HIGH, 1050000, 7 },
+ [22] = { { 1958400, HFPLL, 1, 102 }, LVL_HIGH, 1050000, 7 },
+ [23] = { { 2035200, HFPLL, 1, 106 }, LVL_HIGH, 1050000, 7 },
+ [24] = { { 2112000, HFPLL, 1, 110 }, LVL_HIGH, 1050000, 7 },
+ [25] = { { 2188800, HFPLL, 1, 114 }, LVL_HIGH, 1050000, 7 },
{ }
};
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 796059c..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,
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-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 5cabe64..2bd92f2 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -403,7 +403,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -422,7 +422,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -441,7 +441,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(2, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -460,7 +460,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(3, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index d15b67d..53d3023 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -382,7 +382,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -401,7 +401,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -420,7 +420,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(2, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -439,7 +439,7 @@
.idle_enabled = 0,
.suspend_enabled = 0,
.latency = 500,
- .residency = 6000,
+ .residency = 500,
},
[MSM_PM_MODE(3, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
@@ -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 d91bc7e..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,
@@ -2029,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()) {
@@ -2040,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_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/pil-venus.c b/arch/arm/mach-msm/pil-venus.c
index 103fd9f..eb222e3 100644
--- a/arch/arm/mach-msm/pil-venus.c
+++ b/arch/arm/mach-msm/pil-venus.c
@@ -33,6 +33,7 @@
#include "peripheral-loader.h"
#include "scm-pas.h"
+#include "ramdump.h"
/* VENUS WRAPPER registers */
#define VENUS_WRAPPER_CLOCK_CONFIG 0x4
@@ -76,6 +77,7 @@
struct iommu_domain *iommu_fw_domain;
int venus_domain_num;
bool is_booted;
+ void *ramdump_dev;
u32 fw_sz;
u32 fw_min_paddr;
u32 fw_max_paddr;
@@ -459,6 +461,29 @@
pil_shutdown(&drv->desc);
}
+static int venus_shutdown(const struct subsys_desc *desc)
+{
+ struct venus_data *drv = subsys_to_drv(desc);
+ pil_shutdown(&drv->desc);
+ return 0;
+}
+
+static int venus_powerup(const struct subsys_desc *desc)
+{
+ struct venus_data *drv = subsys_to_drv(desc);
+ return pil_boot(&drv->desc);
+}
+
+static int venus_ramdump(int enable, const struct subsys_desc *desc)
+{
+ struct venus_data *drv = subsys_to_drv(desc);
+
+ if (!enable)
+ return 0;
+
+ return pil_do_ramdump(&drv->desc, drv->ramdump_dev);
+}
+
static int __devinit pil_venus_probe(struct platform_device *pdev)
{
struct venus_data *drv;
@@ -524,23 +549,34 @@
dev_info(&pdev->dev, "using non-secure boot\n");
}
+ drv->ramdump_dev = create_ramdump_device("venus", &pdev->dev);
+ if (!drv->ramdump_dev)
+ return -ENOMEM;
+
rc = pil_desc_init(desc);
if (rc)
- return rc;
+ goto err_ramdump;
drv->subsys_desc.name = desc->name;
drv->subsys_desc.owner = THIS_MODULE;
drv->subsys_desc.dev = &pdev->dev;
drv->subsys_desc.start = venus_start;
drv->subsys_desc.stop = venus_stop;
+ drv->subsys_desc.shutdown = venus_shutdown;
+ drv->subsys_desc.powerup = venus_powerup;
+ drv->subsys_desc.ramdump = venus_ramdump;
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
- pil_desc_release(desc);
- return PTR_ERR(drv->subsys);
+ rc = PTR_ERR(drv->subsys);
+ goto err_subsys;
}
-
- return 0;
+ return rc;
+err_subsys:
+ pil_desc_release(desc);
+err_ramdump:
+ destroy_ramdump_device(drv->ramdump_dev);
+ return rc;
}
static int __devexit pil_venus_remove(struct platform_device *pdev)
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/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index 5fb041d..440dc42 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -632,7 +632,7 @@
do_div(adc_voltage, param1.dy);
- qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
+ qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
ARRAY_SIZE(adcmap_100k_104ef_104fb),
adc_voltage, result);
if (negative_offset)
@@ -649,7 +649,7 @@
qpnp_get_vadc_gain_and_offset(¶m1, CALIB_RATIOMETRIC);
- rc = qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
+ rc = qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
ARRAY_SIZE(adcmap_100k_104ef_104fb),
param->low_thr_temp, ¶m->low_thr_voltage);
if (rc)
@@ -659,7 +659,7 @@
do_div(param->low_thr_voltage, param1.adc_vref);
param->low_thr_voltage += param1.adc_gnd;
- rc = qpnp_adc_map_voltage_temp(adcmap_100k_104ef_104fb,
+ rc = qpnp_adc_map_temp_voltage(adcmap_100k_104ef_104fb,
ARRAY_SIZE(adcmap_100k_104ef_104fb),
param->high_thr_temp, ¶m->high_thr_voltage);
if (rc)
@@ -822,7 +822,7 @@
struct device_node *node = spmi->dev.of_node;
struct resource *res;
struct device_node *child;
- struct qpnp_vadc_amux *adc_channel_list;
+ struct qpnp_adc_amux *adc_channel_list;
struct qpnp_adc_properties *adc_prop;
struct qpnp_adc_amux_properties *amux_prop;
int count_adc_channel_list = 0, decimation, rc = 0, i = 0;
@@ -847,7 +847,7 @@
return -ENOMEM;
}
adc_channel_list = devm_kzalloc(&spmi->dev,
- ((sizeof(struct qpnp_vadc_amux)) * count_adc_channel_list),
+ ((sizeof(struct qpnp_adc_amux)) * count_adc_channel_list),
GFP_KERNEL);
if (!adc_channel_list) {
dev_err(&spmi->dev, "Unable to allocate memory\n");
@@ -877,8 +877,7 @@
return -EINVAL;
}
- rc = of_property_read_u32(child, "qcom,channel-num",
- &channel_num);
+ rc = of_property_read_u32(child, "reg", &channel_num);
if (rc) {
pr_err("Invalid channel num\n");
return -EINVAL;
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 91e93c2..2a60840 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -1087,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;
@@ -1362,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,
@@ -1405,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)? */
@@ -1436,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?! */
@@ -1445,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;
@@ -1453,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)
@@ -1574,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;
}
@@ -1727,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;
@@ -1778,12 +1814,9 @@
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",
- __func__);
- } else {
- if (is_video_frame == 1)
- feed_data->write_pts_dts = 0;
+ MPQ_DVB_ERR_PRINT(
+ "%s: Couldn't write packet. Should never happen\n",
+ __func__);
}
}
@@ -1883,9 +1916,9 @@
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;
@@ -1898,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 b46779c..f7af1ef 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -309,10 +309,13 @@
* 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;
@@ -333,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/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/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/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/thermal/Kconfig b/drivers/thermal/Kconfig
index e70924c..347d9f2 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -107,3 +107,13 @@
available. If allowed via compile time configuration; enabling the
thermal zone device via the mode file results in shifting PMIC over
temperature shutdown control from hardware to software.
+
+config THERMAL_QPNP_ADC_TM
+ tristate "Qualcomm 8974 Thermal Monitor ADC Driver"
+ depends on THERMAL && SPMI
+ help
+ This enables the thermal Sysfs driver for the ADC thermal monitoring
+ device. It shows up in Sysfs as a thermal zone with multiple trip points.
+ Disabling the thermal zone device via the mode file results in disabling
+ the sensor. Also able to set threshold temperature for both hot and cold
+ and update when a threshold is reached.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 3b2b3a8..01dce2d 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -11,3 +11,4 @@
obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
obj-$(CONFIG_THERMAL_TSENS8974) += msm8974-tsens.o
obj-$(CONFIG_THERMAL_QPNP) += qpnp-temp-alarm.o
+obj-$(CONFIG_THERMAL_QPNP_ADC_TM) += qpnp-adc-tm.o
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
new file mode 100644
index 0000000..bcc85f3
--- /dev/null
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -0,0 +1,1531 @@
+/* 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.
+ *
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/hwmon.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/spmi.h>
+#include <linux/of_irq.h>
+#include <linux/wakelock.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/qpnp/qpnp-adc.h>
+#include <linux/thermal.h>
+#include <linux/platform_device.h>
+
+/* QPNP VADC TM register definition */
+#define QPNP_STATUS1 0x8
+#define QPNP_STATUS1_OP_MODE 4
+#define QPNP_STATUS1_MEAS_INTERVAL_EN_STS BIT(2)
+#define QPNP_STATUS1_REQ_STS BIT(1)
+#define QPNP_STATUS1_EOC BIT(0)
+#define QPNP_STATUS2 0x9
+#define QPNP_STATUS2_CONV_SEQ_STATE 6
+#define QPNP_STATUS2_FIFO_NOT_EMPTY_FLAG BIT(1)
+#define QPNP_STATUS2_CONV_SEQ_TIMEOUT_STS BIT(0)
+#define QPNP_CONV_TIMEOUT_ERR 2
+
+#define QPNP_MODE_CTL 0x40
+#define QPNP_OP_MODE_SHIFT 3
+#define QPNP_VREF_XO_THM_FORCE BIT(2)
+#define QPNP_AMUX_TRIM_EN BIT(1)
+#define QPNP_ADC_TRIM_EN BIT(0)
+#define QPNP_EN_CTL1 0x46
+#define QPNP_ADC_TM_EN BIT(7)
+#define QPNP_ADC_CH_SEL_CTL 0x48
+#define QPNP_ADC_DIG_PARAM 0x50
+#define QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT 3
+#define QPNP_HW_SETTLE_DELAY 0x51
+#define QPNP_CONV_REQ 0x52
+#define QPNP_CONV_REQ_SET BIT(7)
+#define QPNP_CONV_SEQ_CTL 0x54
+#define QPNP_CONV_SEQ_HOLDOFF_SHIFT 4
+#define QPNP_CONV_SEQ_TRIG_CTL 0x55
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL 0x57
+#define QPNP_ADC_TM_MEAS_INTERVAL_TIME_SHIFT 0x3
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2 0x58
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT 0x4
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_MASK 0xf0
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL3_MASK 0xf
+
+#define QPNP_ADC_MEAS_INTERVAL_OP_CTL 0x59
+#define QPNP_ADC_MEAS_INTERVAL_OP BIT(7)
+
+#define QPNP_FAST_AVG_CTL 0x5a
+#define QPNP_FAST_AVG_EN 0x5b
+
+#define QPNP_M0_LOW_THR_LSB 0x5c
+#define QPNP_M0_LOW_THR_MSB 0x5d
+#define QPNP_M0_HIGH_THR_LSB 0x5e
+#define QPNP_M0_HIGH_THR_MSB 0x5f
+#define QPNP_M1_LOW_THR_LSB 0x69
+#define QPNP_M1_LOW_THR_MSB 0x6a
+#define QPNP_M1_HIGH_THR_LSB 0x6b
+#define QPNP_M1_HIGH_THR_MSB 0x6c
+#define QPNP_M2_LOW_THR_LSB 0x71
+#define QPNP_M2_LOW_THR_MSB 0x72
+#define QPNP_M2_HIGH_THR_LSB 0x7b
+#define QPNP_M2_HIGH_THR_MSB 0x7c
+#define QPNP_M3_LOW_THR_LSB 0x79
+#define QPNP_M3_LOW_THR_MSB 0x7a
+#define QPNP_M3_HIGH_THR_LSB 0x7b
+#define QPNP_M3_HIGH_THR_MSB 0x7c
+#define QPNP_M4_LOW_THR_LSB 0x81
+#define QPNP_M4_LOW_THR_MSB 0x82
+#define QPNP_M4_HIGH_THR_LSB 0x83
+#define QPNP_M4_HIGH_THR_MSB 0x84
+
+#define QPNP_ADC_TM_MULTI_MEAS_EN 0x41
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M0 BIT(0)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M1 BIT(1)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M2 BIT(2)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M3 BIT(3)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M4 BIT(4)
+#define QPNP_ADC_TM_LOW_THR_INT_EN 0x42
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M0 BIT(0)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M1 BIT(1)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M2 BIT(2)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M3 BIT(3)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M4 BIT(4)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN 0x43
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M0 BIT(0)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M1 BIT(1)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M2 BIT(2)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M3 BIT(3)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M4 BIT(4)
+
+#define QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL 0x57
+#define QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL 0x6d
+#define QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL 0x75
+#define QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL 0x7d
+#define QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL 0x85
+#define QPNP_ADC_TM_STATUS1 0x8
+#define QPNP_ADC_TM_STATUS_LOW 0xa
+#define QPNP_ADC_TM_STATUS_HIGH 0xb
+
+#define QPNP_ADC_TM_M0_LOW_THR 0x5d5c
+#define QPNP_ADC_TM_M0_HIGH_THR 0x5f5e
+#define QPNP_ADC_TM_MEAS_INTERVAL 0x0
+
+#define QPNP_ADC_TM_THR_LSB_MASK(val) (val & 0xff)
+#define QPNP_ADC_TM_THR_MSB_MASK(val) ((val & 0xff00) >> 8)
+
+struct qpnp_adc_tm_sensor {
+ struct thermal_zone_device *tz_dev;
+ enum thermal_device_mode mode;
+ uint32_t sensor_num;
+ enum qpnp_adc_meas_timer_select timer_select;
+ uint32_t meas_interval;
+ uint32_t low_thr;
+ uint32_t high_thr;
+ uint32_t btm_channel_num;
+ struct work_struct work;
+};
+
+struct qpnp_adc_tm_drv {
+ struct qpnp_adc_drv *adc;
+ struct qpnp_adc_tm_usbid_param *usb_id_param;
+ struct work_struct usbid_work;
+ struct qpnp_adc_tm_btm_param *battery_param;
+ struct work_struct batt_work;
+ bool adc_tm_initialized;
+ struct qpnp_adc_tm_sensor sensor[0];
+};
+
+struct qpnp_adc_tm_drv *qpnp_adc_tm;
+
+struct qpnp_adc_tm_trip_reg_type {
+ uint16_t low_thr_lsb_addr;
+ uint16_t low_thr_msb_addr;
+ uint16_t high_thr_lsb_addr;
+ uint16_t high_thr_msb_addr;
+ u8 multi_meas_en;
+ u8 low_thr_int_chan_en;
+ u8 high_thr_int_chan_en;
+};
+
+static struct qpnp_adc_tm_trip_reg_type adc_tm_data[] = {
+ [QPNP_ADC_TM_M0_ADC_CH_SEL_CTL] = {QPNP_M0_LOW_THR_LSB,
+ QPNP_M0_LOW_THR_MSB, QPNP_M0_HIGH_THR_LSB,
+ QPNP_M0_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M0,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M0, QPNP_ADC_TM_HIGH_THR_INT_EN_M0},
+ [QPNP_ADC_TM_M1_ADC_CH_SEL_CTL] = {QPNP_M1_LOW_THR_LSB,
+ QPNP_M1_LOW_THR_MSB, QPNP_M1_HIGH_THR_LSB,
+ QPNP_M1_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M1,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M1, QPNP_ADC_TM_HIGH_THR_INT_EN_M1},
+ [QPNP_ADC_TM_M2_ADC_CH_SEL_CTL] = {QPNP_M2_LOW_THR_LSB,
+ QPNP_M2_LOW_THR_MSB, QPNP_M2_HIGH_THR_LSB,
+ QPNP_M2_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M2,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M2, QPNP_ADC_TM_HIGH_THR_INT_EN_M2},
+ [QPNP_ADC_TM_M3_ADC_CH_SEL_CTL] = {QPNP_M3_LOW_THR_LSB,
+ QPNP_M3_LOW_THR_MSB, QPNP_M3_HIGH_THR_LSB,
+ QPNP_M3_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M3,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M3, QPNP_ADC_TM_HIGH_THR_INT_EN_M3},
+ [QPNP_ADC_TM_M4_ADC_CH_SEL_CTL] = {QPNP_M4_LOW_THR_LSB,
+ QPNP_M4_LOW_THR_MSB, QPNP_M4_HIGH_THR_LSB,
+ QPNP_M4_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M4,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M4, QPNP_ADC_TM_HIGH_THR_INT_EN_M4},
+};
+
+static int32_t qpnp_adc_tm_read_reg(int16_t reg, u8 *data)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int rc = 0;
+
+ rc = spmi_ext_register_readl(adc_tm->adc->spmi->ctrl,
+ adc_tm->adc->slave, (adc_tm->adc->offset + reg), data, 1);
+ if (rc < 0)
+ pr_err("adc-tm read reg %d failed with %d\n", reg, rc);
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_write_reg(int16_t reg, u8 data)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int rc = 0;
+ u8 *buf;
+
+ buf = &data;
+
+ rc = spmi_ext_register_writel(adc_tm->adc->spmi->ctrl,
+ adc_tm->adc->slave, (adc_tm->adc->offset + reg), buf, 1);
+ if (rc < 0)
+ pr_err("adc-tm write reg %d failed with %d\n", reg, rc);
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_enable(bool state)
+{
+ int rc = 0;
+ u8 data = 0, enable_check = 0;
+
+ if (state) {
+ data = QPNP_ADC_TM_EN;
+ rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1,
+ data);
+ if (rc < 0)
+ pr_err("adc-tm enable failed\n");
+ } else {
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
+ &enable_check);
+ if (rc < 0) {
+ pr_err("multi measurement read failed\n");
+ return rc;
+ }
+
+ if (!enable_check) {
+ data = 0;
+ rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, data);
+ if (rc < 0)
+ pr_err("adc-tm disable failed\n");
+ }
+ }
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_enable_req_sts_check(void)
+{
+ u8 status1;
+ int rc;
+
+ /* The VADC_TM bank needs to be disabled for new conversion request */
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS1, &status1);
+ if (rc) {
+ pr_err("adc-tm read status1 failed\n");
+ return rc;
+ }
+
+ /* Disable the bank if a conversion is occuring */
+ if (status1 & QPNP_STATUS1_REQ_STS) {
+ rc = qpnp_adc_tm_write_reg(QPNP_EN_CTL1, 0);
+ if (rc < 0)
+ pr_err("adc-tm disable failed\n");
+ }
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_mode_select(u8 mode_ctl)
+{
+ int rc;
+
+ /* VADC_BTM current sets mode to recurring measurements */
+ rc = qpnp_adc_tm_write_reg(QPNP_MODE_CTL, mode_ctl);
+ if (rc < 0)
+ pr_err("adc-tm write mode selection err\n");
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_timer_interval_select(
+ struct qpnp_vadc_chan_properties *chan_prop)
+{
+ int rc;
+ u8 meas_interval_timer2 = 0;
+
+ /* Configure USB_ID to timer1, batt_therm to timer2 */
+ switch (chan_prop->timer_select) {
+ case ADC_MEAS_TIMER_SELECT1:
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL,
+ chan_prop->meas_interval1);
+ if (rc < 0) {
+ pr_err("timer1 configure failed\n");
+ return rc;
+ }
+ break;
+ case ADC_MEAS_TIMER_SELECT2:
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ &meas_interval_timer2);
+ if (rc < 0) {
+ pr_err("timer2 configure read failed\n");
+ return rc;
+ }
+ meas_interval_timer2 |=
+ (chan_prop->meas_interval2 <<
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT);
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ meas_interval_timer2);
+ if (rc < 0) {
+ pr_err("timer2 configure failed\n");
+ return rc;
+ }
+ break;
+ case ADC_MEAS_TIMER_SELECT3:
+ /* Thermal channels uses timer3, default to 1 second */
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ &meas_interval_timer2);
+ if (rc < 0) {
+ pr_err("timer3 read failed\n");
+ return rc;
+ }
+ chan_prop->meas_interval2 = ADC_MEAS3_INTERVAL_1S;
+ meas_interval_timer2 |= chan_prop->meas_interval2;
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ meas_interval_timer2);
+ if (rc < 0) {
+ pr_err("timer3 configure failed\n");
+ return rc;
+ }
+ break;
+ default:
+ pr_err("Invalid timer selection\n");
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_meas_int_update(uint16_t reg_addr_src,
+ u8 reg_addr_dst, bool state)
+{
+ u8 bit_mask_check = 0;
+ int rc = 0;
+
+ rc = qpnp_adc_tm_read_reg(reg_addr_src, &bit_mask_check);
+ if (rc < 0) {
+ pr_err("read failed for addr:%x\n", reg_addr_src);
+ return rc;
+ }
+
+ if (state)
+ bit_mask_check |= reg_addr_dst;
+ else
+ bit_mask_check &= ~reg_addr_dst;
+
+ rc = qpnp_adc_tm_write_reg(reg_addr_src, bit_mask_check);
+ if (rc < 0)
+ pr_err("write failed for addr:%x\n", reg_addr_src);
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_usbid_btm_thr_en(uint32_t btm_chan,
+ struct qpnp_vadc_chan_properties *chan_prop)
+{
+ int rc = 0;
+
+ rc = qpnp_adc_tm_write_reg(
+ adc_tm_data[btm_chan].low_thr_lsb_addr,
+ QPNP_ADC_TM_THR_LSB_MASK(chan_prop->low_thr));
+ if (rc < 0) {
+ pr_err("low threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(
+ adc_tm_data[btm_chan].low_thr_msb_addr,
+ QPNP_ADC_TM_THR_MSB_MASK(chan_prop->low_thr));
+ if (rc < 0) {
+ pr_err("low threshold msb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(
+ adc_tm_data[btm_chan].high_thr_lsb_addr,
+ QPNP_ADC_TM_THR_LSB_MASK(chan_prop->high_thr));
+ if (rc < 0) {
+ pr_err("high threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(
+ adc_tm_data[btm_chan].high_thr_msb_addr,
+ QPNP_ADC_TM_THR_MSB_MASK(chan_prop->high_thr));
+ if (rc < 0)
+ pr_err("high threshold msb setting failed\n");
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_channel_configure(uint32_t btm_chan,
+ struct qpnp_vadc_chan_properties *chan_prop,
+ uint32_t amux_channel)
+{
+ int rc = 0;
+
+ switch (btm_chan) {
+ case QPNP_ADC_TM_M0_ADC_CH_SEL_CTL:
+ case QPNP_ADC_TM_M1_ADC_CH_SEL_CTL:
+ /* Update low and high notification thresholds */
+ rc = qpnp_adc_tm_usbid_btm_thr_en(btm_chan,
+ chan_prop);
+ if (rc < 0) {
+ pr_err("setting chan:%d threshold failed\n", btm_chan);
+ return rc;
+ }
+
+ if ((chan_prop->state_request ==
+ ADC_TM_LOW_THR_ENABLE) ||
+ (chan_prop->state_request ==
+ ADC_TM_HIGH_LOW_THR_ENABLE)) {
+ /* Enable low threshold's interrupt */
+ rc = qpnp_adc_tm_meas_int_update(
+ QPNP_ADC_TM_LOW_THR_INT_EN,
+ adc_tm_data[btm_chan].low_thr_int_chan_en,
+ true);
+ if (rc < 0) {
+ pr_err("low thr enable err:%d\n", btm_chan);
+ return rc;
+ }
+ }
+
+ if ((chan_prop->state_request ==
+ ADC_TM_HIGH_THR_ENABLE) ||
+ (chan_prop->state_request ==
+ ADC_TM_HIGH_LOW_THR_ENABLE)) {
+ /* Enable high threshold's interrupt */
+ rc = qpnp_adc_tm_meas_int_update(
+ QPNP_ADC_TM_HIGH_THR_INT_EN,
+ adc_tm_data[btm_chan].high_thr_int_chan_en,
+ true);
+ if (rc < 0) {
+ pr_err("high thr enable err:%d\n", btm_chan);
+ return rc;
+ }
+ }
+ /* intention fall through to configure common chan meas */
+ case QPNP_ADC_TM_M2_ADC_CH_SEL_CTL:
+ case QPNP_ADC_TM_M3_ADC_CH_SEL_CTL:
+ case QPNP_ADC_TM_M4_ADC_CH_SEL_CTL:
+ /* Configure AMUX control register for channel selection */
+ rc = qpnp_adc_tm_write_reg(btm_chan, amux_channel);
+ if (rc < 0) {
+ pr_err("btm_chan:%d selection failed\n", btm_chan);
+ return rc;
+ }
+
+ /* Enable corresponding BTM channel measurement */
+ rc = qpnp_adc_tm_meas_int_update(
+ QPNP_ADC_TM_MULTI_MEAS_EN,
+ adc_tm_data[btm_chan].multi_meas_en, true);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ return rc;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_configure(
+ struct qpnp_adc_amux_properties *chan_prop)
+{
+ u8 decimation = 0;
+ int rc = 0;
+ uint32_t btm_chan = 0;
+
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_enable_req_sts_check();
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ return rc;
+ }
+
+ /* Set measurement in recurring mode */
+ rc = qpnp_adc_tm_mode_select(chan_prop->mode_sel);
+ if (rc < 0) {
+ pr_err("adc-tm mode select failed\n");
+ return rc;
+ }
+
+ /* Configure AMUX channel */
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_CH_SEL_CTL,
+ chan_prop->amux_channel);
+ if (rc < 0) {
+ pr_err("adc-tm channel selection err\n");
+ return rc;
+ }
+
+ /* Digital paramater setup */
+ decimation |= chan_prop->decimation <<
+ QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT;
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_DIG_PARAM, decimation);
+ if (rc < 0) {
+ pr_err("adc-tm digital parameter setup err\n");
+ return rc;
+ }
+
+ /* Hardware setting time */
+ rc = qpnp_adc_tm_write_reg(QPNP_HW_SETTLE_DELAY,
+ chan_prop->hw_settle_time);
+ if (rc < 0) {
+ pr_err("adc-tm hw settling time setup err\n");
+ return rc;
+ }
+
+ /* Fast averaging setup */
+ rc = qpnp_adc_tm_write_reg(QPNP_FAST_AVG_CTL,
+ chan_prop->fast_avg_setup);
+ if (rc < 0) {
+ pr_err("adc-tm fast-avg setup err\n");
+ return rc;
+ }
+
+ /* Measurement interval setup */
+ rc = qpnp_adc_tm_timer_interval_select(chan_prop->chan_prop);
+ if (rc < 0) {
+ pr_err("adc-tm timer select failed\n");
+ return rc;
+ }
+
+ /* Channel configuration setup */
+ btm_chan = chan_prop->chan_prop->tm_channel_select;
+ rc = qpnp_adc_tm_channel_configure(btm_chan, chan_prop->chan_prop,
+ chan_prop->amux_channel);
+ if (rc < 0) {
+ pr_err("adc-tm channel configure failed\n");
+ return rc;
+ }
+
+ /* Enable bank */
+ rc = qpnp_adc_tm_enable(true);
+ if (rc)
+ return rc;
+
+ /* Recurring interval measurement enable */
+ rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_MEAS_INTERVAL_OP_CTL,
+ QPNP_ADC_MEAS_INTERVAL_OP, true);
+ if (rc < 0) {
+ pr_err("adc-tm meas interval op configure failed\n");
+ return rc;
+ }
+
+ /* Request conversion */
+ rc = qpnp_adc_tm_write_reg(QPNP_CONV_REQ, QPNP_CONV_REQ_SET);
+ if (rc < 0) {
+ pr_err("adc-tm request conversion failed\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+static int qpnp_adc_tm_get_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode *mode)
+{
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+
+ if (!adc_tm || !mode)
+ return -EINVAL;
+
+ *mode = adc_tm->mode;
+
+ return 0;
+}
+
+static int qpnp_adc_tm_set_mode(struct thermal_zone_device *thermal,
+ enum thermal_device_mode mode)
+{
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ struct qpnp_adc_tm_drv *adc_drv = qpnp_adc_tm;
+ int rc = 0, channel;
+
+ if (!adc_tm)
+ return -EINVAL;
+
+ if (mode == THERMAL_DEVICE_ENABLED) {
+ adc_drv->adc->amux_prop->amux_channel = adc_tm->sensor_num;
+ channel = adc_tm->sensor_num;
+ adc_drv->adc->amux_prop->decimation =
+ adc_drv->adc->adc_channels[channel].adc_decimation;
+ adc_drv->adc->amux_prop->hw_settle_time =
+ adc_drv->adc->adc_channels[channel].hw_settle_time;
+ adc_drv->adc->amux_prop->fast_avg_setup =
+ adc_drv->adc->adc_channels[channel].fast_avg_setup;
+ adc_drv->adc->amux_prop->mode_sel =
+ ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
+ adc_drv->adc->amux_prop->chan_prop->timer_select =
+ ADC_MEAS_TIMER_SELECT1;
+ adc_drv->adc->amux_prop->chan_prop->meas_interval1 =
+ ADC_MEAS1_INTERVAL_1S;
+ adc_drv->adc->amux_prop->chan_prop->low_thr = adc_tm->low_thr;
+ adc_drv->adc->amux_prop->chan_prop->high_thr = adc_tm->high_thr;
+ adc_drv->adc->amux_prop->chan_prop->tm_channel_select =
+ adc_tm->btm_channel_num;
+
+ rc = qpnp_adc_tm_configure(adc_drv->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm tm configure failed with %d\n", rc);
+ return -EINVAL;
+ }
+ } else if (mode == THERMAL_DEVICE_DISABLED) {
+ rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ adc_tm_data[adc_tm->btm_channel_num].multi_meas_en,
+ false);
+ if (rc < 0) {
+ pr_err("multi measurement update failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_enable(false);
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ return rc;
+ }
+ }
+
+ adc_tm->mode = mode;
+
+ return 0;
+}
+
+static int qpnp_adc_tm_get_trip_type(struct thermal_zone_device *thermal,
+ int trip, enum thermal_trip_type *type)
+{
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+
+ if (!adc_tm || !type || type < 0)
+ return -EINVAL;
+
+ switch (trip) {
+ case ADC_TM_TRIP_HIGH_WARM:
+ *type = THERMAL_TRIP_CONFIGURABLE_HI;
+ break;
+ case ADC_TM_TRIP_LOW_COOL:
+ *type = THERMAL_TRIP_CONFIGURABLE_LOW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int qpnp_adc_tm_get_trip_temp(struct thermal_zone_device *thermal,
+ int trip, unsigned long *temp)
+{
+ struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int64_t result = 0;
+ u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
+ unsigned int reg, rc = 0, btm_channel_num;
+ uint16_t reg_low_thr_lsb, reg_low_thr_msb;
+ uint16_t reg_high_thr_lsb, reg_high_thr_msb;
+
+ if (!adc_tm)
+ return -EINVAL;
+
+ btm_channel_num = adc_tm_sensor->btm_channel_num;
+ reg_low_thr_lsb = adc_tm_data[btm_channel_num].low_thr_lsb_addr;
+ reg_low_thr_msb = adc_tm_data[btm_channel_num].low_thr_msb_addr;
+ reg_high_thr_lsb = adc_tm_data[btm_channel_num].high_thr_lsb_addr;
+ reg_high_thr_msb = adc_tm_data[btm_channel_num].high_thr_msb_addr;
+
+ switch (trip) {
+ case ADC_TM_TRIP_HIGH_WARM:
+ rc = qpnp_adc_tm_read_reg(reg_low_thr_lsb, &trip_warm_thr0);
+ if (rc) {
+ pr_err("adc-tm low_thr_lsb err\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(reg_low_thr_msb, &trip_warm_thr1);
+ if (rc) {
+ pr_err("adc-tm low_thr_msb err\n");
+ return rc;
+ }
+ reg = (trip_warm_thr1 << 8) | trip_warm_thr0;
+ break;
+ case ADC_TM_TRIP_LOW_COOL:
+ rc = qpnp_adc_tm_read_reg(reg_high_thr_lsb, &trip_cool_thr0);
+ if (rc) {
+ pr_err("adc-tm_tm high_thr_lsb err\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(reg_high_thr_msb, &trip_cool_thr1);
+ if (rc) {
+ pr_err("adc-tm_tm high_thr_lsb err\n");
+ return rc;
+ }
+ reg = (trip_cool_thr1 << 8) | trip_cool_thr0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rc = qpnp_adc_tm_scale_voltage_therm_pu2(reg, &result);
+ if (rc < 0) {
+ pr_err("Failed to lookup the therm thresholds\n");
+ return rc;
+ }
+
+ *temp = result;
+
+ return 0;
+}
+
+static int qpnp_adc_tm_set_trip_temp(struct thermal_zone_device *thermal,
+ int trip, long temp)
+{
+ struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ struct qpnp_adc_tm_config tm_config;
+ u8 trip_cool_thr0, trip_cool_thr1, trip_warm_thr0, trip_warm_thr1;
+ uint16_t reg_low_thr_lsb, reg_low_thr_msb;
+ uint16_t reg_high_thr_lsb, reg_high_thr_msb;
+ int rc = 0, btm_channel_num;
+
+ if (!adc_tm)
+ return -EINVAL;
+
+ tm_config.channel = adc_tm_sensor->sensor_num;
+ switch (trip) {
+ case ADC_TM_TRIP_HIGH_WARM:
+ tm_config.high_thr_temp = temp;
+ break;
+ case ADC_TM_TRIP_LOW_COOL:
+ tm_config.low_thr_temp = temp;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rc = qpnp_adc_tm_scale_therm_voltage_pu2(&tm_config);
+ if (rc < 0) {
+ pr_err("Failed to lookup the adc-tm thresholds\n");
+ return rc;
+ }
+
+ trip_warm_thr0 = ((tm_config.low_thr_voltage << 24) >> 24);
+ trip_warm_thr1 = ((tm_config.low_thr_voltage << 16) >> 24);
+ trip_cool_thr0 = ((tm_config.high_thr_voltage << 24) >> 24);
+ trip_cool_thr1 = ((tm_config.high_thr_voltage << 16) >> 24);
+
+ btm_channel_num = adc_tm_sensor->btm_channel_num;
+ reg_low_thr_lsb = adc_tm_data[btm_channel_num].low_thr_lsb_addr;
+ reg_low_thr_msb = adc_tm_data[btm_channel_num].low_thr_msb_addr;
+ reg_high_thr_lsb = adc_tm_data[btm_channel_num].high_thr_lsb_addr;
+ reg_high_thr_msb = adc_tm_data[btm_channel_num].high_thr_msb_addr;
+
+ switch (trip) {
+ case ADC_TM_TRIP_HIGH_WARM:
+ rc = qpnp_adc_tm_write_reg(reg_low_thr_lsb, trip_cool_thr0);
+ if (rc) {
+ pr_err("adc-tm_tm read threshold err\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(reg_low_thr_msb, trip_cool_thr1);
+ if (rc) {
+ pr_err("adc-tm_tm read threshold err\n");
+ return rc;
+ }
+ adc_tm_sensor->low_thr = tm_config.high_thr_voltage;
+ break;
+ case ADC_TM_TRIP_LOW_COOL:
+ rc = qpnp_adc_tm_write_reg(reg_high_thr_lsb, trip_warm_thr0);
+ if (rc) {
+ pr_err("adc-tm_tm read threshold err\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(reg_high_thr_msb, trip_warm_thr1);
+ if (rc) {
+ pr_err("adc-tm_tm read threshold err\n");
+ return rc;
+ }
+ adc_tm_sensor->high_thr = tm_config.low_thr_voltage;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void notify_uspace_qpnp_adc_tm_fn(struct work_struct *work)
+{
+ struct qpnp_adc_tm_sensor *adc_tm = container_of(work,
+ struct qpnp_adc_tm_sensor, work);
+
+ sysfs_notify(&adc_tm->tz_dev->device.kobj,
+ NULL, "btm");
+}
+
+static void notify_usb_fn(struct work_struct *work)
+{
+ struct qpnp_adc_tm_drv *adc_tm = container_of(work,
+ struct qpnp_adc_tm_drv, usbid_work);
+ int rc;
+ u8 status_low, status_high;
+
+ if (adc_tm->usb_id_param->threshold_notification != NULL) {
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
+ &status_low);
+ if (rc) {
+ pr_err("adc-tm read low status failed\n");
+ return;
+ }
+
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
+ &status_high);
+ if (rc) {
+ pr_err("adc-tm read high status failed\n");
+ return;
+ }
+
+ if (status_low & 1)
+ adc_tm->usb_id_param->threshold_notification(
+ ADC_TM_LOW_STATE, adc_tm->usb_id_param->usbid_ctx);
+ else if (status_high & 1)
+ adc_tm->usb_id_param->threshold_notification(
+ ADC_TM_HIGH_STATE, adc_tm->usb_id_param->usbid_ctx);
+ }
+
+ return;
+}
+
+static void notify_batt_fn(struct work_struct *work)
+{
+ struct qpnp_adc_tm_drv *adc_tm = container_of(work,
+ struct qpnp_adc_tm_drv, batt_work);
+ int rc;
+ u8 status_low, status_high;
+
+ if (adc_tm->battery_param->threshold_notification != NULL) {
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW,
+ &status_low);
+ if (rc) {
+ pr_err("adc-tm read low status failed\n");
+ return;
+ }
+
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH,
+ &status_high);
+ if (rc) {
+ pr_err("adc-tm read high status failed\n");
+ return;
+ }
+
+ if (status_low & QPNP_ADC_TM_LOW_THR_INT_EN_M1)
+ adc_tm->battery_param->threshold_notification(
+ ADC_TM_LOW_STATE);
+ else if (status_high & QPNP_ADC_TM_HIGH_THR_INT_EN_M1)
+ adc_tm->battery_param->threshold_notification(
+ ADC_TM_HIGH_STATE);
+ }
+
+ return;
+}
+
+static int qpnp_adc_tm_activate_trip_type_fn(uint32_t btm_channel_num,
+ enum thermal_trip_activation_mode mode, u8 *data, uint32_t reg)
+{
+ u8 thr_int = 0;
+ int rc = 0;
+
+ rc = qpnp_adc_tm_read_reg(reg, &thr_int);
+ if (rc) {
+ pr_err("multi meas read failed\n");
+ return rc;
+ }
+
+ thr_int = adc_tm_data[btm_channel_num].low_thr_int_chan_en;
+
+ if (mode == THERMAL_TRIP_ACTIVATION_ENABLED)
+ thr_int |= *data;
+ else
+ thr_int &= ~*data;
+
+ rc = qpnp_adc_tm_write_reg(reg, thr_int);
+ if (rc)
+ pr_err("multi meas write failed\n");
+
+ return rc;
+}
+
+static int qpnp_adc_tm_activate_trip_type(struct thermal_zone_device *thermal,
+ int trip, enum thermal_trip_activation_mode mode)
+{
+ struct qpnp_adc_tm_sensor *adc_tm = thermal->devdata;
+ int rc = 0;
+ u8 thr_int_en = 0;
+
+ if (!adc_tm)
+ return -EINVAL;
+
+ switch (trip) {
+ case ADC_TM_TRIP_HIGH_WARM:
+ thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
+ low_thr_int_chan_en;
+ rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
+ mode, &thr_int_en, QPNP_ADC_TM_LOW_THR_INT_EN);
+ if (rc)
+ pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
+ break;
+ case ADC_TM_TRIP_LOW_COOL:
+ thr_int_en = adc_tm_data[adc_tm->btm_channel_num].
+ high_thr_int_chan_en;
+ rc = qpnp_adc_tm_activate_trip_type_fn(adc_tm->btm_channel_num,
+ mode, &thr_int_en, QPNP_ADC_TM_HIGH_THR_INT_EN);
+ if (rc)
+ pr_err("channel:%x failed\n", adc_tm->btm_channel_num);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int qpnp_adc_tm_read_status(void)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ u8 status_low = 0, status_high = 0, qpnp_adc_tm_meas_en = 0;
+ u8 adc_tm_low_enable = 0, adc_tm_high_enable = 0;
+ u8 thr_int_disable = 0;
+ int rc = 0, sensor_notify_num = 0;
+
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_LOW, &status_low);
+ if (rc) {
+ pr_err("adc-tm-tm read status low failed with %d\n", rc);
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_STATUS_HIGH, &status_high);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ goto fail;
+ }
+
+ /* Check which interrupt threshold is lower and measure against the
+ * enabled channel */
+ rc = qpnp_adc_tm_read_reg(QPNP_ADC_TM_MULTI_MEAS_EN,
+ &qpnp_adc_tm_meas_en);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ goto fail;
+ }
+
+ adc_tm_low_enable = qpnp_adc_tm_meas_en & status_low;
+ adc_tm_high_enable = qpnp_adc_tm_meas_en & status_high;
+
+ if (adc_tm_high_enable) {
+ sensor_notify_num = (adc_tm_high_enable >> 3);
+ switch (adc_tm_high_enable) {
+ case 1:
+ case 2:
+ {
+ if (adc_tm_high_enable == 1)
+ thr_int_disable =
+ QPNP_ADC_TM_HIGH_THR_INT_EN_M0;
+ else if (adc_tm_high_enable == 2)
+ thr_int_disable =
+ QPNP_ADC_TM_HIGH_THR_INT_EN_M1;
+
+ rc = qpnp_adc_tm_meas_int_update(
+ QPNP_ADC_TM_HIGH_THR_INT_EN,
+ thr_int_disable, false);
+ if (rc < 0) {
+ pr_err("high threshold int read failed\n");
+ goto fail;
+ }
+
+ if (adc_tm_high_enable == 1)
+ schedule_work(&adc_tm->usbid_work);
+ else if (adc_tm_high_enable == 2)
+ schedule_work(&adc_tm->batt_work);
+ }
+ break;
+ case 4:
+ case 8:
+ case 16:
+ {
+ /* High voltage threshold is triggered by low temp */
+ rc = qpnp_adc_tm_activate_trip_type(
+ adc_tm->sensor[sensor_notify_num].tz_dev,
+ ADC_TM_TRIP_LOW_COOL,
+ THERMAL_TRIP_ACTIVATION_DISABLED);
+ if (rc < 0) {
+ pr_err("notify error:%d\n", sensor_notify_num);
+ goto fail;
+ }
+ schedule_work(&adc_tm->sensor[sensor_notify_num].work);
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ }
+ }
+
+ if (adc_tm_low_enable) {
+ sensor_notify_num = (adc_tm_low_enable >> 3);
+ switch (adc_tm_low_enable) {
+ case 1:
+ case 2:
+ {
+ if (adc_tm_low_enable == 1)
+ thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M0;
+ else if (adc_tm_low_enable == 2)
+ thr_int_disable = QPNP_ADC_TM_LOW_THR_INT_EN_M1;
+
+ rc = qpnp_adc_tm_meas_int_update(
+ QPNP_ADC_TM_LOW_THR_INT_EN,
+ thr_int_disable, false);
+ if (rc < 0) {
+ pr_err("low threshold int disable failed\n");
+ goto fail;
+ }
+
+ if (adc_tm_low_enable == 1)
+ schedule_work(&adc_tm->usbid_work);
+ else if (adc_tm_low_enable == 2)
+ schedule_work(&adc_tm->batt_work);
+ }
+ break;
+ case 4:
+ case 8:
+ case 16:
+ {
+ /* Low voltage threshold is triggered by high temp */
+ rc = qpnp_adc_tm_activate_trip_type(
+ adc_tm->sensor[sensor_notify_num].tz_dev,
+ ADC_TM_TRIP_HIGH_WARM,
+ THERMAL_TRIP_ACTIVATION_DISABLED);
+ if (rc < 0) {
+ pr_err("notify error:%d\n", sensor_notify_num);
+ goto fail;
+ }
+ schedule_work(&adc_tm->sensor[sensor_notify_num].work);
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ }
+ }
+
+fail:
+ return rc;
+}
+
+static void qpnp_adc_tm_high_thr_work(struct work_struct *work)
+{
+ int rc;
+
+ rc = qpnp_adc_tm_read_status();
+
+ return;
+}
+DECLARE_WORK(trigger_completion_adc_tm_high_thr_work,
+ qpnp_adc_tm_high_thr_work);
+
+static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
+{
+ schedule_work(&trigger_completion_adc_tm_high_thr_work);
+
+ return IRQ_HANDLED;
+}
+
+static void qpnp_adc_tm_low_thr_work(struct work_struct *work)
+{
+ int rc;
+
+ rc = qpnp_adc_tm_read_status();
+
+ return;
+}
+DECLARE_WORK(trigger_completion_adc_tm_low_thr_work, qpnp_adc_tm_low_thr_work);
+
+static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
+{
+ schedule_work(&trigger_completion_adc_tm_low_thr_work);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t qpnp_adc_tm_isr(int irq, void *dev_id)
+{
+ struct qpnp_adc_tm_drv *adc_tm = dev_id;
+
+ complete(&adc_tm->adc->adc_rslt_completion);
+
+ return IRQ_HANDLED;
+}
+
+static int qpnp_adc_read_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ struct qpnp_adc_tm_sensor *adc_tm_sensor = thermal->devdata;
+ struct qpnp_vadc_result result;
+ int rc = 0;
+
+ rc = qpnp_vadc_read(adc_tm_sensor->sensor_num, &result);
+ if (rc)
+ return rc;
+
+ *temp = result.physical;
+
+ return rc;
+}
+
+static struct thermal_zone_device_ops qpnp_adc_tm_thermal_ops = {
+ .get_temp = qpnp_adc_read_temp,
+ .get_mode = qpnp_adc_tm_get_mode,
+ .set_mode = qpnp_adc_tm_set_mode,
+ .get_trip_type = qpnp_adc_tm_get_trip_type,
+ .activate_trip_type = qpnp_adc_tm_activate_trip_type,
+ .get_trip_temp = qpnp_adc_tm_get_trip_temp,
+ .set_trip_temp = qpnp_adc_tm_set_trip_temp,
+};
+
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_usbid_param *param)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ uint32_t channel;
+ int rc = 0;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -ENODEV;
+
+ if (param->threshold_notification == NULL) {
+ pr_err("No USB_ID high/low voltage notificaton??\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ adc_tm->adc->amux_prop->amux_channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
+ channel = LR_MUX10_PU2_AMUX_USB_ID_LV;
+ adc_tm->adc->amux_prop->decimation =
+ adc_tm->adc->adc_channels[channel].adc_decimation;
+ adc_tm->adc->amux_prop->hw_settle_time =
+ adc_tm->adc->adc_channels[channel].hw_settle_time;
+ adc_tm->adc->amux_prop->fast_avg_setup =
+ adc_tm->adc->adc_channels[channel].fast_avg_setup;
+ adc_tm->adc->amux_prop->mode_sel =
+ ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
+ adc_tm->adc->amux_prop->chan_prop->meas_interval1 =
+ ADC_MEAS1_INTERVAL_1S;
+ qpnp_adc_usb_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
+ &adc_tm->adc->amux_prop->chan_prop->high_thr);
+ adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
+ QPNP_ADC_TM_M0_ADC_CH_SEL_CTL;
+ adc_tm->adc->amux_prop->chan_prop->timer_select =
+ ADC_MEAS_TIMER_SELECT1;
+ adc_tm->adc->amux_prop->chan_prop->state_request =
+ param->state_request;
+ rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm configure failed with %d\n", rc);
+ goto fail_unlock;
+ }
+
+ adc_tm->usb_id_param = param;
+
+fail_unlock:
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_usbid_configure);
+
+static int32_t qpnp_adc_tm_chan_usbid_chan_btm_end(
+ uint32_t btm_chan_num)
+{
+ int32_t rc = 0;
+
+ rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_LOW_THR_INT_EN,
+ adc_tm_data[btm_chan_num].low_thr_int_chan_en,
+ false);
+ if (rc < 0) {
+ pr_err("low threshold int write failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_HIGH_THR_INT_EN,
+ adc_tm_data[btm_chan_num].high_thr_int_chan_en,
+ false);
+ if (rc < 0) {
+ pr_err("high threshold int enable failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_meas_int_update(QPNP_ADC_TM_MULTI_MEAS_EN,
+ adc_tm_data[btm_chan_num].multi_meas_en,
+ false);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_enable(false);
+ if (rc < 0)
+ pr_err("TM disable failed\n");
+
+ return rc;
+}
+
+int32_t qpnp_adc_tm_usbid_end(void)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int rc = 0;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -ENODEV;
+
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
+ QPNP_ADC_TM_M0_ADC_CH_SEL_CTL);
+ if (rc < 0)
+ pr_err("disabling thresholds for usb channel failed\n");
+
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_usbid_end);
+
+int32_t qpnp_adc_tm_btm_configure(struct qpnp_adc_tm_btm_param *param)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ uint32_t channel;
+ int rc = 0;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -ENODEV;
+
+ if (param->threshold_notification == NULL) {
+ pr_err("No battery high/low temp notificaton??\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ adc_tm->adc->amux_prop->amux_channel = LR_MUX1_BATT_THERM;
+ channel = LR_MUX1_BATT_THERM;
+ adc_tm->adc->amux_prop->decimation =
+ adc_tm->adc->adc_channels[channel].adc_decimation;
+ adc_tm->adc->amux_prop->hw_settle_time =
+ adc_tm->adc->adc_channels[channel].hw_settle_time;
+ adc_tm->adc->amux_prop->fast_avg_setup =
+ adc_tm->adc->adc_channels[channel].fast_avg_setup;
+ adc_tm->adc->amux_prop->mode_sel =
+ ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
+ adc_tm->adc->amux_prop->chan_prop->meas_interval2 =
+ ADC_MEAS2_INTERVAL_1S;
+ qpnp_adc_btm_scaler(param, &adc_tm->adc->amux_prop->chan_prop->low_thr,
+ &adc_tm->adc->amux_prop->chan_prop->high_thr);
+ adc_tm->adc->amux_prop->chan_prop->tm_channel_select =
+ QPNP_ADC_TM_M1_ADC_CH_SEL_CTL;
+ adc_tm->adc->amux_prop->chan_prop->timer_select =
+ ADC_MEAS_TIMER_SELECT2;
+ adc_tm->adc->amux_prop->chan_prop->state_request =
+ param->state_request;
+ rc = qpnp_adc_tm_configure(adc_tm->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm configure failed with %d\n", rc);
+ goto fail_unlock;
+ }
+
+ adc_tm->battery_param = param;
+
+fail_unlock:
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_btm_configure);
+
+int32_t qpnp_adc_tm_btm_end(void)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+ int rc = 0;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -ENODEV;
+
+ mutex_lock(&adc_tm->adc->adc_lock);
+
+ rc = qpnp_adc_tm_chan_usbid_chan_btm_end(
+ QPNP_ADC_TM_M1_ADC_CH_SEL_CTL);
+ if (rc < 0)
+ pr_err("disabling thresholds for batt channel failed\n");
+
+ mutex_unlock(&adc_tm->adc->adc_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_btm_end);
+
+int32_t qpnp_adc_tm_is_ready(void)
+{
+ struct qpnp_adc_tm_drv *adc_tm = qpnp_adc_tm;
+
+ if (!adc_tm || !adc_tm->adc_tm_initialized)
+ return -EPROBE_DEFER;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(qpnp_adc_tm_is_ready);
+
+static int __devinit qpnp_adc_tm_probe(struct spmi_device *spmi)
+{
+ struct device_node *node = spmi->dev.of_node, *child;
+ struct qpnp_adc_tm_drv *adc_tm;
+ struct qpnp_adc_drv *adc_qpnp;
+ int32_t count_adc_channel_list = 0, rc, i = 0, j = 0;
+ u8 thr_init = 0;
+
+ if (!node)
+ return -EINVAL;
+
+ if (qpnp_adc_tm) {
+ pr_err("adc-tm already in use\n");
+ return -EBUSY;
+ }
+
+ for_each_child_of_node(node, child)
+ count_adc_channel_list++;
+
+ if (!count_adc_channel_list) {
+ pr_err("No channel listing\n");
+ return -EINVAL;
+ }
+
+ adc_tm = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_tm_drv) +
+ (count_adc_channel_list *
+ sizeof(struct qpnp_adc_tm_sensor)),
+ GFP_KERNEL);
+ if (!adc_tm) {
+ dev_err(&spmi->dev, "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ adc_qpnp = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_adc_drv),
+ GFP_KERNEL);
+ if (!adc_qpnp) {
+ dev_err(&spmi->dev, "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ adc_tm->adc = adc_qpnp;
+
+ rc = qpnp_adc_get_devicetree_data(spmi, adc_tm->adc);
+ if (rc) {
+ dev_err(&spmi->dev, "failed to read device tree\n");
+ return rc;
+ }
+
+ /* Register the ADC peripheral interrupt */
+ adc_tm->adc->adc_high_thr_irq = spmi_get_irq_byname(spmi,
+ NULL, "high-thr-en-set");
+ if (adc_tm->adc->adc_high_thr_irq < 0) {
+ pr_err("Invalid irq\n");
+ return -ENXIO;
+ }
+
+ adc_tm->adc->adc_low_thr_irq = spmi_get_irq_byname(spmi,
+ NULL, "low-thr-en-set");
+ if (adc_tm->adc->adc_low_thr_irq < 0) {
+ pr_err("Invalid irq\n");
+ return -ENXIO;
+ }
+
+ rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_irq_eoc,
+ qpnp_adc_tm_isr, IRQF_TRIGGER_RISING,
+ "qpnp_adc_tm_interrupt", adc_tm);
+ if (rc) {
+ dev_err(&spmi->dev,
+ "failed to request adc irq with error %d\n", rc);
+ return rc;
+ } else {
+ enable_irq_wake(adc_tm->adc->adc_irq_eoc);
+ }
+
+ rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_high_thr_irq,
+ qpnp_adc_tm_high_thr_isr,
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", adc_tm);
+ if (rc) {
+ dev_err(&spmi->dev, "failed to request adc irq\n");
+ return rc;
+ } else {
+ enable_irq_wake(adc_tm->adc->adc_high_thr_irq);
+ }
+
+ rc = devm_request_irq(&spmi->dev, adc_tm->adc->adc_low_thr_irq,
+ qpnp_adc_tm_low_thr_isr,
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_low_interrupt", adc_tm);
+ if (rc) {
+ dev_err(&spmi->dev, "failed to request adc irq\n");
+ return rc;
+ } else {
+ enable_irq_wake(adc_tm->adc->adc_low_thr_irq);
+ }
+
+ for_each_child_of_node(node, child) {
+ char name[25];
+ int btm_channel_num;
+ rc = of_property_read_u32(child,
+ "qcom,btm-channel-number", &btm_channel_num);
+ if (rc) {
+ pr_err("Invalid btm channel number\n");
+ return -EINVAL;
+ }
+
+ if ((btm_channel_num != QPNP_ADC_TM_M0_ADC_CH_SEL_CTL) &&
+ (btm_channel_num != QPNP_ADC_TM_M1_ADC_CH_SEL_CTL)) {
+ /* Register with the thermal zone */
+ adc_tm->sensor[i].mode = THERMAL_DEVICE_DISABLED;
+ snprintf(name, sizeof(name), "qpnp_adc_tm_sensor%d", i);
+ adc_tm->sensor[i].sensor_num =
+ adc_tm->adc->adc_channels[j].channel_num;
+ adc_tm->sensor[i].btm_channel_num = btm_channel_num;
+ adc_tm->sensor[i].meas_interval =
+ QPNP_ADC_TM_MEAS_INTERVAL;
+ adc_tm->sensor[i].low_thr = QPNP_ADC_TM_M0_LOW_THR;
+ adc_tm->sensor[i].high_thr = QPNP_ADC_TM_M0_HIGH_THR;
+ adc_tm->sensor[i].tz_dev =
+ thermal_zone_device_register(name,
+ ADC_TM_TRIP_NUM,
+ &adc_tm->sensor[i],
+ &qpnp_adc_tm_thermal_ops, 0, 0, 0, 0);
+ if (IS_ERR(adc_tm->sensor[i].tz_dev))
+ pr_err("thermal device register failed.\n");
+ INIT_WORK(&adc_tm->sensor[i].work,
+ notify_uspace_qpnp_adc_tm_fn);
+ i++;
+ }
+ j++;
+ }
+ INIT_WORK(&adc_tm->usbid_work, notify_usb_fn);
+ INIT_WORK(&adc_tm->batt_work, notify_batt_fn);
+ qpnp_adc_tm = adc_tm;
+ dev_set_drvdata(&spmi->dev, adc_tm);
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_HIGH_THR_INT_EN, thr_init);
+ if (rc < 0) {
+ pr_err("high thr init failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_LOW_THR_INT_EN, thr_init);
+ if (rc < 0) {
+ pr_err("low thr init failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(QPNP_ADC_TM_MULTI_MEAS_EN, thr_init);
+ if (rc < 0) {
+ pr_err("multi meas en failed\n");
+ return rc;
+ }
+
+ adc_tm->adc_tm_initialized = true;
+
+ return 0;
+}
+
+static int __devexit qpnp_adc_tm_remove(struct spmi_device *spmi)
+{
+ struct qpnp_adc_tm_drv *adc_tm = dev_get_drvdata(&spmi->dev);
+ struct device_node *node = spmi->dev.of_node;
+ struct device_node *child;
+ int i = 0;
+
+ for_each_child_of_node(node, child) {
+ thermal_zone_device_unregister(adc_tm->sensor[i].tz_dev);
+ i++;
+ }
+
+ adc_tm->adc_tm_initialized = false;
+ dev_set_drvdata(&spmi->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id qpnp_adc_tm_match_table[] = {
+ { .compatible = "qcom,qpnp-adc-tm" },
+ {}
+};
+
+static struct spmi_driver qpnp_adc_tm_driver = {
+ .driver = {
+ .name = "qcom,qpnp-adc-tm",
+ .of_match_table = qpnp_adc_tm_match_table,
+ },
+ .probe = qpnp_adc_tm_probe,
+ .remove = qpnp_adc_tm_remove,
+};
+
+static int __init qpnp_adc_tm_init(void)
+{
+ return spmi_driver_register(&qpnp_adc_tm_driver);
+}
+module_init(qpnp_adc_tm_init);
+
+static void __exit qpnp_adc_tm_exit(void)
+{
+ spmi_driver_unregister(&qpnp_adc_tm_driver);
+}
+module_exit(qpnp_adc_tm_exit);
+
+MODULE_DESCRIPTION("QPNP PMIC ADC Threshold Monitoring driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 2b0a79f..e3906bc 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -34,6 +34,7 @@
#include <linux/usb/msm_hsusb.h>
#include <linux/regulator/consumer.h>
#include <linux/power_supply.h>
+#include <linux/qpnp/qpnp-adc.h>
#include <mach/rpm-regulator.h>
#include <mach/rpm-regulator-smd.h>
@@ -44,6 +45,19 @@
#include "core.h"
#include "gadget.h"
+/* ADC threshold values */
+static int adc_low_threshold = 700;
+module_param(adc_low_threshold, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(adc_low_threshold, "ADC ID Low voltage threshold");
+
+static int adc_high_threshold = 950;
+module_param(adc_high_threshold, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(adc_high_threshold, "ADC ID High voltage threshold");
+
+static int adc_meas_interval = ADC_MEAS1_INTERVAL_1S;
+module_param(adc_meas_interval, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(adc_meas_interval, "ADC ID polling period");
+
/**
* USB DBM Hardware registers.
*
@@ -160,6 +174,9 @@
struct usb_phy *otg_xceiv;
struct delayed_work chg_work;
enum usb_chg_state chg_state;
+ struct qpnp_adc_tm_usbid_param adc_param;
+ struct delayed_work init_adc_work;
+ bool id_adc_detect;
u8 dcd_retries;
u32 bus_perf_client;
struct msm_bus_scale_pdata *bus_scale_table;
@@ -1482,7 +1499,7 @@
}
}
-static u32 debug_id, debug_bsv, debug_connect;
+static u32 debug_id = true, debug_bsv, debug_connect;
static int dwc3_connect_show(struct seq_file *s, void *unused)
{
@@ -1628,7 +1645,6 @@
if (mdwc->otg_xceiv && (mdwc->ext_xceiv.otg_capability ||
!init)) {
mdwc->ext_xceiv.bsv = val->intval;
- mdwc->ext_xceiv.id = DWC3_ID_FLOAT;
if (atomic_read(&mdwc->in_lpm)) {
dev_dbg(mdwc->dev,
"%s received in LPM\n", __func__);
@@ -1669,6 +1685,88 @@
POWER_SUPPLY_PROP_SCOPE,
};
+static void dwc3_adc_notification(enum qpnp_tm_state state, void *ctx)
+{
+ struct dwc3_msm *mdwc = ctx;
+
+ if (state >= ADC_TM_STATE_NUM) {
+ pr_err("%s: invalid notification %d\n", __func__, state);
+ return;
+ }
+
+ dev_dbg(mdwc->dev, "%s: state = %s\n", __func__,
+ state == ADC_TM_HIGH_STATE ? "high" : "low");
+
+ if (state == ADC_TM_HIGH_STATE) {
+ mdwc->ext_xceiv.id = DWC3_ID_FLOAT;
+ mdwc->adc_param.state_request = ADC_TM_LOW_THR_ENABLE;
+ } else {
+ mdwc->ext_xceiv.id = DWC3_ID_GROUND;
+ mdwc->adc_param.state_request = ADC_TM_HIGH_THR_ENABLE;
+ }
+
+ /* notify OTG */
+ queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+
+ /* re-arm notification interrupt */
+ qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+}
+
+static void dwc3_init_adc_work(struct work_struct *w)
+{
+ struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm,
+ init_adc_work.work);
+ int ret;
+
+ ret = qpnp_adc_tm_is_ready();
+ if (ret == -EPROBE_DEFER) {
+ queue_delayed_work(system_nrt_wq, to_delayed_work(w), 100);
+ return;
+ }
+
+ mdwc->adc_param.low_thr = adc_low_threshold;
+ mdwc->adc_param.high_thr = adc_high_threshold;
+ mdwc->adc_param.timer_interval = adc_meas_interval;
+ mdwc->adc_param.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
+ mdwc->adc_param.usbid_ctx = mdwc;
+ mdwc->adc_param.threshold_notification = dwc3_adc_notification;
+
+ ret = qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+ if (ret) {
+ dev_err(mdwc->dev, "%s: request ADC error %d\n", __func__, ret);
+ return;
+ }
+
+ mdwc->id_adc_detect = true;
+}
+
+static ssize_t adc_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", context->id_adc_detect ?
+ "enabled" : "disabled");
+}
+
+static ssize_t adc_enable_store(struct device *dev,
+ struct device_attribute *attr, const char
+ *buf, size_t size)
+{
+ if (!strnicmp(buf, "enable", 6)) {
+ if (!context->id_adc_detect)
+ dwc3_init_adc_work(&context->init_adc_work.work);
+ return size;
+ } else if (!strnicmp(buf, "disable", 7)) {
+ qpnp_adc_tm_usbid_end();
+ context->id_adc_detect = false;
+ return size;
+ }
+
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(adc_enable, S_IRUGO | S_IWUSR, adc_enable_show,
+ adc_enable_store);
+
static int __devinit dwc3_msm_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -1694,6 +1792,7 @@
INIT_LIST_HEAD(&msm->req_complete_list);
INIT_DELAYED_WORK(&msm->chg_work, dwc3_chg_detect_work);
INIT_DELAYED_WORK(&msm->resume_work, dwc3_resume_work);
+ INIT_DELAYED_WORK(&msm->init_adc_work, dwc3_init_adc_work);
msm->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
if (IS_ERR(msm->xo_handle)) {
@@ -1832,6 +1931,7 @@
goto free_hs_ldo_init;
}
+ msm->ext_xceiv.id = DWC3_ID_FLOAT;
msm->ext_xceiv.otg_capability = of_property_read_bool(node,
"qcom,otg-capability");
msm->charger.charging_disabled = of_property_read_bool(node,
@@ -1852,6 +1952,10 @@
}
enable_irq_wake(msm->hs_phy_irq);
}
+ } else {
+ /* Use ADC for ID pin detection */
+ queue_delayed_work(system_nrt_wq, &msm->init_adc_work, 0);
+ device_create_file(&pdev->dev, &dev_attr_adc_enable);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -2080,12 +2184,15 @@
{
struct dwc3_msm *msm = platform_get_drvdata(pdev);
+ if (msm->id_adc_detect)
+ qpnp_adc_tm_usbid_end();
if (dwc3_debugfs_root)
debugfs_remove_recursive(dwc3_debugfs_root);
if (msm->otg_xceiv) {
dwc3_start_chg_det(&msm->charger, false);
usb_put_transceiver(msm->otg_xceiv);
}
+
pm_runtime_disable(msm->dev);
platform_device_unregister(msm->dwc3);
wake_lock_destroy(&msm->wlock);
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index fab443c..01ba161 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -1,7 +1,7 @@
/**
* dwc3_otg.c - DesignWare USB3 DRD Controller OTG
*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -331,10 +331,13 @@
}
}
} else if (event == DWC3_EVENT_XCEIV_STATE) {
- if (ext_xceiv->id == DWC3_ID_FLOAT)
+ if (ext_xceiv->id == DWC3_ID_FLOAT) {
+ dev_dbg(phy->dev, "XCVR: ID set\n");
set_bit(ID, &dotg->inputs);
- else
+ } else {
+ dev_dbg(phy->dev, "XCVR: ID clear\n");
clear_bit(ID, &dotg->inputs);
+ }
if (ext_xceiv->bsv) {
dev_dbg(phy->dev, "XCVR: BSV set\n");
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_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index 557db63..ad63605 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -521,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/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/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index fc34b22..7ba91f1 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -660,13 +660,16 @@
* thresholds.
* @timer_interval: Select polling rate from qpnp_adc_meas_timer_1 type.
* @threshold_notification: Notification callback once threshold are crossed.
+ * @usbid_ctx: A context of void type.
*/
struct qpnp_adc_tm_usbid_param {
int32_t high_thr;
int32_t low_thr;
enum qpnp_state_request state_request;
enum qpnp_adc_meas_timer_1 timer_interval;
- void (*threshold_notification) (enum qpnp_tm_state state);
+ void *usbid_ctx;
+ void (*threshold_notification) (enum qpnp_tm_state state,
+ void *ctx);
};
/**
@@ -743,16 +746,32 @@
* input channel.
* @offset_gain_denominator: The inverse denominator of the gain applied to the
* input channel.
+ * @high_thr: High threshold voltage that is requested to be set.
+ * @low_thr: Low threshold voltage that is requested to be set.
+ * @timer_select: Choosen from one of the 3 timers to set the polling rate for
+ * the VADC_BTM channel.
+ * @meas_interval1: Polling rate to set for timer 1.
+ * @meas_interval2: Polling rate to set for timer 2.
+ * @tm_channel_select: BTM channel number for the 5 VADC_BTM channels.
+ * @state_request: User can select either enable or disable high/low or both
+ * activation levels based on the qpnp_state_request type.
* @adc_graph: ADC graph for the channel of struct type qpnp_adc_linear_graph.
*/
struct qpnp_vadc_chan_properties {
uint32_t offset_gain_numerator;
uint32_t offset_gain_denominator;
+ uint32_t high_thr;
+ uint32_t low_thr;
+ enum qpnp_adc_meas_timer_select timer_select;
+ enum qpnp_adc_meas_timer_1 meas_interval1;
+ enum qpnp_adc_meas_timer_2 meas_interval2;
+ enum qpnp_adc_tm_channel_select tm_channel_select;
+ enum qpnp_state_request state_request;
struct qpnp_vadc_linear_graph adc_graph[2];
};
/**
- * struct qpnp_adc_result - Represent the result of the QPNP ADC.
+ * struct qpnp_vadc_result - Represent the result of the QPNP ADC.
* @chan: The channel number of the requested conversion.
* @adc_code: The pre-calibrated digital output of a given ADC relative to the
* the ADC reference.
@@ -774,7 +793,7 @@
};
/**
- * struct qpnp_vadc_amux - AMUX properties for individual channel
+ * struct qpnp_adc_amux - AMUX properties for individual channel
* @name: Channel string name.
* @channel_num: Channel in integer used from qpnp_adc_channels.
* @chan_path_prescaling: Channel scaling performed on the input signal.
@@ -783,7 +802,7 @@
* each individual channel whether it is voltage, current,
* temperature, etc and compensates the channel properties.
*/
-struct qpnp_vadc_amux {
+struct qpnp_adc_amux {
char *name;
enum qpnp_vadc_channels channel_num;
enum qpnp_adc_channel_scaling_param chan_path_prescaling;
@@ -858,6 +877,11 @@
* @amux_prop - AMUX properties representing the ADC peripheral.
* @adc_channels - ADC channel properties for the ADC peripheral.
* @adc_irq_eoc - End of Conversion IRQ.
+ * @adc_irq_fifo_not_empty - Conversion sequencer request written
+ * to FIFO when not empty.
+ * @adc_irq_conv_seq_timeout - Conversion sequencer trigger timeout.
+ * @adc_high_thr_irq - Output higher than high threshold set for measurement.
+ * @adc_low_thr_irq - Output lower than low threshold set for measurement.
* @adc_lock - ADC lock for access to the peripheral.
* @adc_rslt_completion - ADC result notification after interrupt
* is received.
@@ -869,8 +893,12 @@
uint16_t offset;
struct qpnp_adc_properties *adc_prop;
struct qpnp_adc_amux_properties *amux_prop;
- struct qpnp_vadc_amux *adc_channels;
+ struct qpnp_adc_amux *adc_channels;
int adc_irq_eoc;
+ int adc_irq_fifo_not_empty;
+ int adc_irq_conv_seq_timeout;
+ int adc_high_thr_irq;
+ int adc_low_thr_irq;
struct mutex adc_lock;
struct completion adc_rslt_completion;
struct qpnp_iadc_calib calib;
@@ -1234,4 +1262,65 @@
{ return -ENXIO; }
#endif
+/* Public API */
+#if defined(CONFIG_THERMAL_QPNP_ADC_TM) \
+ || defined(CONFIG_THERMAL_QPNP_ADC_TM_MODULE)
+/**
+ * qpnp_adc_tm_usbid_configure() - Configures Channel 0 of VADC_BTM to
+ * monitor USB_ID channel using 100k internal pull-up.
+ * USB driver passes the high/low voltage threshold along
+ * with the notification callback once the set thresholds
+ * are crossed.
+ * @param: Structure pointer of qpnp_adc_tm_usbid_param type.
+ * Clients pass the low/high voltage along with the threshold
+ * notification callback.
+ */
+int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_usbid_param *param);
+/**
+ * qpnp_adc_tm_usbid_end() - Disables the monitoring of channel 0 thats
+ * assigned for monitoring USB_ID. Disables the low/high
+ * threshold activation for channel 0 as well.
+ * @param: none.
+ */
+int32_t qpnp_adc_tm_usbid_end(void);
+/**
+ * qpnp_adc_tm_usbid_configure() - Configures Channel 1 of VADC_BTM to
+ * monitor batt_therm channel using 100k internal pull-up.
+ * Battery driver passes the high/low voltage threshold along
+ * with the notification callback once the set thresholds
+ * are crossed.
+ * @param: Structure pointer of qpnp_adc_tm_btm_param type.
+ * Clients pass the low/high temperature along with the threshold
+ * notification callback.
+ */
+int32_t qpnp_adc_tm_btm_configure(struct qpnp_adc_tm_btm_param *param);
+/**
+ * qpnp_adc_tm_btm_end() - Disables the monitoring of channel 1 thats
+ * assigned for monitoring batt_therm. Disables the low/high
+ * threshold activation for channel 1 as well.
+ * @param: none.
+ */
+int32_t qpnp_adc_tm_btm_end(void);
+/**
+ * qpnp_adc_tm_is_ready() - Clients can use this API to check if the
+ * device is ready to use.
+ * @result: 0 on success and -EPROBE_DEFER when probe for the device
+ * has not occured.
+ */
+int32_t qpnp_adc_tm_is_ready(void);
+#else
+static inline int32_t qpnp_adc_tm_usbid_configure(
+ struct qpnp_adc_tm_usbid_param *param)
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_tm_usbid_end(void)
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_tm_btm_configure(
+ struct qpnp_adc_tm_btm_param *param)
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_tm_btm_end(void)
+{ return -ENXIO; }
+static inline int32_t qpnp_adc_tm_is_ready(void)
+{ return -ENXIO; }
+#endif
+
#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/sound/apr_audio.h b/include/sound/apr_audio.h
index bfd7208..5afbfad 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -697,18 +697,6 @@
#define ASM_OPEN_READ_PERF_MODE_BIT (1<<29)
#define ADM_MULTI_CH_COPP_OPEN_PERF_MODE_BIT (1<<13)
-/* SRS TRUMEDIA GUIDS */
-/* topology */
-#define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90
-/* module */
-#define SRS_TRUMEDIA_MODULE_ID 0x10005010
-/* parameters */
-#define SRS_TRUMEDIA_PARAMS 0x10005011
-#define SRS_TRUMEDIA_PARAMS_WOWHD 0x10005012
-#define SRS_TRUMEDIA_PARAMS_CSHP 0x10005013
-#define SRS_TRUMEDIA_PARAMS_HPF 0x10005014
-#define SRS_TRUMEDIA_PARAMS_PEQ 0x10005015
-#define SRS_TRUMEDIA_PARAMS_HL 0x10005016
#define ASM_MAX_EQ_BANDS 12
@@ -1767,18 +1755,36 @@
#define ADSP_ENOTIMPL 0x00000011 /* Operation is not implemented. */
#define ADSP_ENEEDMORE 0x00000012 /* Operation needs more data or resources*/
-/* SRS TRUMEDIA start */
-#define SRS_ID_GLOBAL 0x00000001
-#define SRS_ID_WOWHD 0x00000002
-#define SRS_ID_CSHP 0x00000003
-#define SRS_ID_HPF 0x00000004
-#define SRS_ID_PEQ 0x00000005
-#define SRS_ID_HL 0x00000006
+/* SRS TRUMEDIA GUIDS */
+#define SRS_TRUMEDIA_TOPOLOGY_ID 0x00010D90
+#define SRS_TRUMEDIA_MODULE_ID 0x10005010
+#define SRS_TRUMEDIA_PARAMS 0x10005011
+#define SRS_TRUMEDIA_PARAMS_WOWHD 0x10005012
+#define SRS_TRUMEDIA_PARAMS_CSHP 0x10005013
+#define SRS_TRUMEDIA_PARAMS_HPF 0x10005014
+#define SRS_TRUMEDIA_PARAMS_PEQ 0x10005015
+#define SRS_TRUMEDIA_PARAMS_HL 0x10005016
-#define SRS_CMD_UPLOAD 0x7FFF0000
-#define SRS_PARAM_INDEX_MASK 0x80000000
-#define SRS_PARAM_OFFSET_MASK 0x3FFF0000
-#define SRS_PARAM_VALUE_MASK 0x0000FFFF
+/* SRS STUDIO SOUND 3D GUIDS */
+#define SRS_SS3D_TOPOLOGY_ID 0x00010720
+#define SRS_SS3D_MODULE_ID 0x10005020
+#define SRS_SS3D_PARAMS 0x10005021
+#define SRS_SS3D_PARAMS_CTRL 0x10005022
+#define SRS_SS3D_PARAMS_FILTER 0x10005023
+
+/* SRS ALSA CMD MASKS */
+#define SRS_CMD_UPLOAD 0x7FFF0000
+#define SRS_PARAM_INDEX_MASK 0x80000000
+#define SRS_PARAM_OFFSET_MASK 0x3FFF0000
+#define SRS_PARAM_VALUE_MASK 0x0000FFFF
+
+/* SRS TRUMEDIA start */
+#define SRS_ID_GLOBAL 0x00000001
+#define SRS_ID_WOWHD 0x00000002
+#define SRS_ID_CSHP 0x00000003
+#define SRS_ID_HPF 0x00000004
+#define SRS_ID_PEQ 0x00000005
+#define SRS_ID_HL 0x00000006
struct srs_trumedia_params_GLOBAL {
uint8_t v1;
@@ -1856,7 +1862,41 @@
struct srs_trumedia_params_PEQ peq;
struct srs_trumedia_params_HL hl;
} __packed;
+
int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params);
/* SRS TruMedia end */
+/* SRS Studio Sound 3D start */
+#define SRS_ID_SS3D_GLOBAL 0x00000001
+#define SRS_ID_SS3D_CTRL 0x00000002
+#define SRS_ID_SS3D_FILTER 0x00000003
+
+struct srs_SS3D_params_GLOBAL {
+ uint8_t v1;
+ uint8_t v2;
+ uint8_t v3;
+ uint8_t v4;
+ uint8_t v5;
+ uint8_t v6;
+ uint8_t v7;
+ uint8_t v8;
+} __packed;
+
+struct srs_SS3D_ctrl_params {
+ uint8_t v[236];
+} __packed;
+
+struct srs_SS3D_filter_params {
+ uint8_t v[28 + 2752];
+} __packed;
+
+struct srs_SS3D_params {
+ struct srs_SS3D_params_GLOBAL global;
+ struct srs_SS3D_ctrl_params ss3d;
+ struct srs_SS3D_filter_params ss3d_f;
+} __packed;
+
+int srs_ss3d_open(int port_id, int srs_tech_id, void *srs_params);
+/* SRS Studio Sound 3D end */
+
#endif /*_APR_AUDIO_H_*/
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/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/apq8064.c b/sound/soc/msm/apq8064.c
index 4fe002b..a351f7b 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -92,7 +92,7 @@
static int msm_btsco_rate = BTSCO_RATE_8KHZ;
static int msm_btsco_ch = 1;
-
+static int hdmi_rate_variable;
static int rec_mode = INCALL_REC_MONO;
static struct clk *codec_clk;
@@ -642,11 +642,13 @@
static const char *spk_function[] = {"Off", "On"};
static const char *slim0_rx_ch_text[] = {"One", "Two"};
static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+static const char * const hdmi_rate[] = {"Default", "Variable"};
static const struct soc_enum msm_enum[] = {
SOC_ENUM_SINGLE_EXT(2, spk_function),
SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+ SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
};
static const char *btsco_rate_text[] = {"8000", "16000"};
@@ -756,6 +758,21 @@
return 0;
}
+static int msm_hdmi_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ hdmi_rate_variable = ucontrol->value.integer.value[0];
+ pr_debug("%s: hdmi_rate_variable = %d\n", __func__, hdmi_rate_variable);
+ return 0;
+}
+
+static int msm_hdmi_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = hdmi_rate_variable;
+ return 0;
+}
+
static const struct snd_kcontrol_new tabla_msm_controls[] = {
SOC_ENUM_EXT("Speaker Function", msm_enum[0], msm_get_spk,
msm_set_spk),
@@ -769,6 +786,9 @@
msm_incall_rec_mode_get, msm_incall_rec_mode_put),
SOC_ENUM_EXT("SLIM_3_RX Channels", msm_enum[1],
msm_slim_3_rx_ch_get, msm_slim_3_rx_ch_put),
+ SOC_ENUM_EXT("HDMI RX Rate", msm_enum[3],
+ msm_hdmi_rate_get,
+ msm_hdmi_rate_put),
};
static void *def_tabla_mbhc_cal(void)
@@ -1328,7 +1348,8 @@
if (channels->max < 2)
channels->min = channels->max = 2;
- rate->min = rate->max = 48000;
+ if (!hdmi_rate_variable)
+ rate->min = rate->max = 48000;
return 0;
}
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/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 79ce671..841d313 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -49,7 +49,8 @@
static int fm_switch_enable;
static int fm_pcmrx_switch_enable;
-static int srs_alsa_ctrl_ever_called;
+static short int srs_alsa_ctrl_ever_called_tm;
+static short int srs_alsa_ctrl_ever_called_ss3d;
#define INT_RX_VOL_MAX_STEPS 0x2000
#define INT_RX_VOL_GAIN 0x2000
@@ -125,19 +126,13 @@
unsigned short int raw_params[1];
};
static union srs_trumedia_params_u msm_srs_trumedia_params[2];
-static int srs_port_id = -1;
-static void srs_send_params(int port_id, unsigned int techs,
+static void srs_send_params_trumedia(int port_id, unsigned int techs,
int param_block_idx) {
-
- /* only send commands to dsp if srs alsa ctrl was used
- at least one time */
- if (!srs_alsa_ctrl_ever_called)
- return;
-
pr_debug("SRS %s: called, port_id = %d, techs flags = %u,"
" paramblockidx %d", __func__, port_id, techs,
param_block_idx);
+
/* force all if techs is set to 1 */
if (techs == 1)
techs = 0xFFFFFFFF;
@@ -162,6 +157,46 @@
(void *)&msm_srs_trumedia_params[param_block_idx].srs_params.global);
}
+union srs_SS3D_params_u {
+ struct srs_SS3D_params srs_params;
+ unsigned short int raw_params[1];
+};
+static union srs_SS3D_params_u msm_srs_SS3D_params[2];
+
+static void srs_send_params_SS3D(int port_id, unsigned int techs,
+ int param_block_idx) {
+ pr_debug("SRS %s: called, port_id = %d, techs flags = %u,\n"
+ " paramblockidx %d", __func__, port_id, techs,
+ param_block_idx);
+
+ /* force all if techs is set to 1 */
+ if (techs == 1)
+ techs = 0xFFFFFFFF;
+
+ if (techs & (1 << SRS_ID_SS3D_CTRL))
+ srs_ss3d_open(port_id, SRS_ID_SS3D_CTRL,
+ (void *)&msm_srs_SS3D_params[param_block_idx].srs_params.ss3d);
+ if (techs & (1 << SRS_ID_SS3D_FILTER))
+ srs_ss3d_open(port_id, SRS_ID_SS3D_FILTER,
+ (void *)&msm_srs_SS3D_params[param_block_idx].srs_params.ss3d_f);
+ if (techs & (1 << SRS_ID_SS3D_GLOBAL))
+ srs_ss3d_open(port_id, SRS_ID_SS3D_GLOBAL,
+ (void *)&msm_srs_SS3D_params[param_block_idx].srs_params.global);
+ return;
+}
+
+static int srs_port_id = -1;
+static void srs_send_params(int port_id, unsigned int techs,
+ int param_block_id) {
+ if (srs_alsa_ctrl_ever_called_tm)
+ srs_send_params_trumedia(port_id, techs, param_block_id);
+ if (srs_alsa_ctrl_ever_called_ss3d)
+ srs_send_params_SS3D(port_id, techs, param_block_id);
+}
+
+/* This array is indexed by back-end DAI ID defined in msm-pcm-routing.h
+ * If new back-end is defined, add new back-end DAI ID at the end of enum
+ */
static struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
{ PRIMARY_I2S_RX, 0, 0, 0, 0, 0},
{ PRIMARY_I2S_TX, 0, 0, 0, 0, 0},
@@ -994,7 +1029,7 @@
unsigned int techs = 0;
unsigned short offset, value, max, index;
- srs_alsa_ctrl_ever_called = 1;
+ srs_alsa_ctrl_ever_called_tm = 1;
max = sizeof(msm_srs_trumedia_params) >> 1;
index = (unsigned short)((ucontrol->value.integer.value[0] &
@@ -1005,7 +1040,7 @@
pr_debug("SRS %s: send params request, flags = %u",
__func__, techs);
if (srs_port_id >= 0 && techs)
- srs_send_params(srs_port_id, techs, index);
+ srs_send_params_trumedia(srs_port_id, techs, index);
return 0;
}
offset = (unsigned short)((ucontrol->value.integer.value[0] &
@@ -1014,32 +1049,10 @@
SRS_PARAM_VALUE_MASK);
if (offset < max) {
msm_srs_trumedia_params[index].raw_params[offset] = value;
- pr_debug("SRS %s: index set... (max %d, requested %d,"
- " val %d, paramblockidx %d)", __func__, max, offset,
- value, index);
} else {
pr_err("SRS %s: index out of bounds! (max %d, requested %d)",
__func__, max, offset);
}
- if (offset == 4) {
- int i;
- for (i = 0; i < max; i++) {
- if (i == 0) {
- pr_debug("SRS %s: global block start",
- __func__);
- }
- if (i ==
- (sizeof(struct srs_trumedia_params_GLOBAL) >> 1)) {
- break;
- pr_debug("SRS %s: wowhd block start at"
- " offset %d word offset %d", __func__,
- i, i>>1);
- }
- pr_debug("SRS %s: param_index %d index %d val %d",
- __func__, index, i,
- msm_srs_trumedia_params[index].raw_params[i]);
- }
- }
return 0;
}
@@ -1047,7 +1060,6 @@
struct snd_ctl_elem_value *ucontrol) {
int ret;
- pr_debug("SRS control normal called");
mutex_lock(&routing_lock);
srs_port_id = SLIMBUS_0_RX;
ret = msm_routing_set_srs_trumedia_control_(kcontrol, ucontrol);
@@ -1060,7 +1072,6 @@
struct snd_ctl_elem_value *ucontrol) {
int ret;
- pr_debug("SRS control I2S called");
mutex_lock(&routing_lock);
srs_port_id = PRIMARY_I2S_RX;
ret = msm_routing_set_srs_trumedia_control_(kcontrol, ucontrol);
@@ -1073,7 +1084,6 @@
struct snd_ctl_elem_value *ucontrol) {
int ret;
- pr_debug("SRS control HDMI called");
mutex_lock(&routing_lock);
srs_port_id = HDMI_RX;
ret = msm_routing_set_srs_trumedia_control_(kcontrol, ucontrol);
@@ -1081,6 +1091,83 @@
return ret;
}
+static int msm_routing_get_srs_SS3D_control(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = 0;
+ return 0;
+}
+
+
+static int msm_routing_set_srs_SS3D_control_(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned int techs = 0;
+ unsigned short offset, value, max, index;
+
+ srs_alsa_ctrl_ever_called_ss3d = 1;
+
+ max = sizeof(msm_srs_SS3D_params) >> 1;
+ index = (unsigned short)((ucontrol->value.integer.value[0] &
+ SRS_PARAM_INDEX_MASK) >> 31);
+ if (SRS_CMD_UPLOAD ==
+ (ucontrol->value.integer.value[0] & SRS_CMD_UPLOAD)) {
+ techs = ucontrol->value.integer.value[0] & 0xFF;
+ pr_debug("SRS %s: send params request, flags = %u", __func__,
+ techs);
+ if (srs_port_id >= 0 && techs)
+ srs_send_params_SS3D(srs_port_id, techs, index);
+ return 0;
+ }
+
+ offset = (unsigned short)((ucontrol->value.integer.value[0] &
+ SRS_PARAM_OFFSET_MASK) >> 16);
+ value = (unsigned short)(ucontrol->value.integer.value[0] &
+ SRS_PARAM_VALUE_MASK);
+ if (offset < max) {
+ msm_srs_SS3D_params[index].raw_params[offset] = value;
+ } else {
+ pr_err("SRS %s: index out of bounds! (max %d, requested %d)",
+ __func__, max, offset);
+ }
+ return 0;
+}
+
+static int msm_routing_set_srs_SS3D_control(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int ret;
+
+ mutex_lock(&routing_lock);
+ srs_port_id = SLIMBUS_0_RX;
+ ret = msm_routing_set_srs_SS3D_control_(kcontrol, ucontrol);
+ mutex_unlock(&routing_lock);
+ return ret;
+}
+
+static int msm_routing_set_srs_SS3D_control_I2S(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int ret;
+
+ mutex_lock(&routing_lock);
+ srs_port_id = PRIMARY_I2S_RX;
+ ret = msm_routing_set_srs_SS3D_control_(kcontrol, ucontrol);
+ mutex_unlock(&routing_lock);
+ return ret;
+}
+
+static int msm_routing_set_srs_SS3D_control_HDMI(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol) {
+ int ret;
+
+ mutex_lock(&routing_lock);
+ srs_port_id = HDMI_RX;
+ ret = msm_routing_set_srs_SS3D_control_(kcontrol, ucontrol);
+ mutex_unlock(&routing_lock);
+ return ret;
+}
+
static void msm_send_eq_values(int eq_idx)
{
int result;
@@ -2109,6 +2196,66 @@
}
};
+static const struct snd_kcontrol_new lpa_SRS_SS3D_controls[] = {
+ {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "SRS SS3D",
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_soc_info_volsw, \
+ .get = msm_routing_get_srs_SS3D_control,
+ .put = msm_routing_set_srs_SS3D_control,
+ .private_value = ((unsigned long)&(struct soc_mixer_control)
+ {.reg = SND_SOC_NOPM,
+ .rreg = SND_SOC_NOPM,
+ .shift = 0,
+ .rshift = 0,
+ .max = 0xFFFFFFFF,
+ .platform_max = 0xFFFFFFFF,
+ .invert = 0
+ })
+ }
+};
+
+static const struct snd_kcontrol_new lpa_SRS_SS3D_controls_HDMI[] = {
+ {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "SRS SS3D HDMI",
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_soc_info_volsw, \
+ .get = msm_routing_get_srs_SS3D_control,
+ .put = msm_routing_set_srs_SS3D_control_HDMI,
+ .private_value = ((unsigned long)&(struct soc_mixer_control)
+ {.reg = SND_SOC_NOPM,
+ .rreg = SND_SOC_NOPM,
+ .shift = 0,
+ .rshift = 0,
+ .max = 0xFFFFFFFF,
+ .platform_max = 0xFFFFFFFF,
+ .invert = 0
+ })
+ }
+};
+
+static const struct snd_kcontrol_new lpa_SRS_SS3D_controls_I2S[] = {
+ {.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "SRS SS3D I2S",
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_soc_info_volsw, \
+ .get = msm_routing_get_srs_SS3D_control,
+ .put = msm_routing_set_srs_SS3D_control_I2S,
+ .private_value = ((unsigned long)&(struct soc_mixer_control)
+ {.reg = SND_SOC_NOPM,
+ .rreg = SND_SOC_NOPM,
+ .shift = 0,
+ .rshift = 0,
+ .max = 0xFFFFFFFF,
+ .platform_max = 0xFFFFFFFF,
+ .invert = 0
+ })
+ }
+};
+
static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
@@ -3060,6 +3207,18 @@
ARRAY_SIZE(lpa_SRS_trumedia_controls_I2S));
snd_soc_add_platform_controls(platform,
+ lpa_SRS_SS3D_controls,
+ ARRAY_SIZE(lpa_SRS_SS3D_controls));
+
+ snd_soc_add_platform_controls(platform,
+ lpa_SRS_SS3D_controls_HDMI,
+ ARRAY_SIZE(lpa_SRS_SS3D_controls_HDMI));
+
+ snd_soc_add_platform_controls(platform,
+ lpa_SRS_SS3D_controls_I2S,
+ ARRAY_SIZE(lpa_SRS_SS3D_controls_I2S));
+
+ snd_soc_add_platform_controls(platform,
ec_ref_rx_mixer_controls,
ARRAY_SIZE(ec_ref_rx_mixer_controls));
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 42699c9..bb9f2be 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -58,7 +58,7 @@
static int msm8930_ext_spk_pamp;
static int msm8930_btsco_rate = BTSCO_RATE_8KHZ;
static int msm8930_btsco_ch = 1;
-
+static int hdmi_rate_variable;
static struct clk *codec_clk;
static int clk_users;
@@ -395,10 +395,13 @@
static const char *slim0_rx_ch_text[] = {"One", "Two"};
static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+static const char * const hdmi_rate[] = {"Default", "Variable"};
+
static const struct soc_enum msm8930_enum[] = {
SOC_ENUM_SINGLE_EXT(2, spk_function),
SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+ SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
};
static const char *btsco_rate_text[] = {"8000", "16000"};
@@ -505,6 +508,21 @@
return ret;
}
+static int msm8930_hdmi_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ hdmi_rate_variable = ucontrol->value.integer.value[0];
+ pr_debug("%s: hdmi_rate_variable = %d\n", __func__, hdmi_rate_variable);
+ return 0;
+}
+
+static int msm8930_hdmi_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = hdmi_rate_variable;
+ return 0;
+}
+
static const struct snd_kcontrol_new sitar_msm8930_controls[] = {
SOC_ENUM_EXT("Speaker Function", msm8930_enum[0], msm8930_get_spk,
msm8930_set_spk),
@@ -516,6 +534,9 @@
msm8930_pmic_gain_get, msm8930_pmic_gain_put),
SOC_ENUM_EXT("Internal BTSCO SampleRate", msm8930_btsco_enum[0],
msm8930_btsco_rate_get, msm8930_btsco_rate_put),
+ SOC_ENUM_EXT("HDMI RX Rate", msm8930_enum[3],
+ msm8930_hdmi_rate_get,
+ msm8930_hdmi_rate_put),
};
static void *def_sitar_mbhc_cal(void)
@@ -751,7 +772,8 @@
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
- rate->min = rate->max = 48000;
+ if (!hdmi_rate_variable)
+ rate->min = rate->max = 48000;
channels->min = channels->max = 2;
return 0;
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index ad78255..da62729 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -73,7 +73,7 @@
static int msm8960_btsco_rate = SAMPLE_RATE_8KHZ;
static int msm8960_btsco_ch = 1;
-
+static int hdmi_rate_variable;
static int msm8960_auxpcm_rate = SAMPLE_RATE_8KHZ;
static struct clk *codec_clk;
@@ -549,11 +549,13 @@
static const char *spk_function[] = {"Off", "On"};
static const char *slim0_rx_ch_text[] = {"One", "Two"};
static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
+static const char * const hdmi_rate[] = {"Default", "Variable"};
static const struct soc_enum msm8960_enum[] = {
SOC_ENUM_SINGLE_EXT(2, spk_function),
SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
+ SOC_ENUM_SINGLE_EXT(2, hdmi_rate),
};
static const char *btsco_rate_text[] = {"8000", "16000"};
@@ -660,6 +662,21 @@
return 0;
}
+static int msm8960_hdmi_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ hdmi_rate_variable = ucontrol->value.integer.value[0];
+ pr_debug("%s: hdmi_rate_variable = %d\n", __func__, hdmi_rate_variable);
+ return 0;
+}
+
+static int msm8960_hdmi_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = hdmi_rate_variable;
+ return 0;
+}
+
static const struct snd_kcontrol_new tabla_msm8960_controls[] = {
SOC_ENUM_EXT("Speaker Function", msm8960_enum[0], msm8960_get_spk,
msm8960_set_spk),
@@ -671,6 +688,9 @@
msm8960_btsco_rate_get, msm8960_btsco_rate_put),
SOC_ENUM_EXT("AUX PCM SampleRate", msm8960_auxpcm_enum[0],
msm8960_auxpcm_rate_get, msm8960_auxpcm_rate_put),
+ SOC_ENUM_EXT("HDMI RX Rate", msm8960_enum[3],
+ msm8960_hdmi_rate_get,
+ msm8960_hdmi_rate_put),
};
static void *def_tabla_mbhc_cal(void)
@@ -1003,7 +1023,8 @@
if (channels->max < 2)
channels->min = channels->max = 2;
- rate->min = rate->max = 48000;
+ if (!hdmi_rate_variable)
+ rate->min = rate->max = 48000;
return 0;
}
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 119e017..2d8d9ca 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -230,6 +230,182 @@
return ret;
}
+struct SS3D {
+ int _1; int _2; short _3; short _4;
+ short _5; short _6; int _7; int _X[32];
+ short _8; short _9; short _10; short _11;
+ short _12; short _13; short _14; short _15;
+ short _16; short _17; short _18; short _19;
+ short _20; short _21; short _22; short _23;
+ short _24; short _25; short _26[5];
+ short _27; short _28; short _29; short _30;
+ short _31; short _32; short _33; int _34; int _35;
+ int _36; int _37; int _38; int _39; int _40;
+};
+
+struct SS3D_F {
+ int _1; int _2; int _3; int _4; int _5; int _6; int _7; int _X[];
+};
+
+int srs_ss3d_open(int port_id, int srs_tech_id, void *srs_params)
+{
+ struct asm_pp_params_command *open = NULL;
+ int ret = 0, sz = 0;
+
+ int index;
+
+ pr_debug("SRS - %s: called.", __func__);
+
+ switch (srs_tech_id) {
+ case SRS_ID_SS3D_GLOBAL: {
+ struct srs_SS3D_params_GLOBAL *glb_params = NULL;
+ sz = sizeof(struct asm_pp_params_command) +
+ sizeof(struct srs_SS3D_params_GLOBAL);
+ open = kzalloc(sz, GFP_KERNEL);
+
+ open->payload_size = sizeof(struct srs_SS3D_params_GLOBAL) +
+ sizeof(struct asm_pp_param_data_hdr);
+ open->params.param_id = SRS_SS3D_PARAMS;
+ open->params.param_size =
+ sizeof(struct srs_SS3D_params_GLOBAL);
+
+ glb_params = (struct srs_SS3D_params_GLOBAL *)((u8 *)open +
+ sizeof(struct asm_pp_params_command));
+ memcpy(glb_params, srs_params,
+ sizeof(struct srs_SS3D_params_GLOBAL));
+
+ pr_debug("SRS - ss3d global params - 1 = %x, 2 = %x, 3 = %x\n"
+ " 4 = %x, 5 = %x, 6 = %x, 7 = %x, 8 = %x\n",
+ (int)glb_params->v1, (int)glb_params->v2,
+ (int)glb_params->v3, (int)glb_params->v4,
+ (int)glb_params->v5, (int)glb_params->v6,
+ (int)glb_params->v7, (int)glb_params->v8);
+ break;
+ }
+ case SRS_ID_SS3D_CTRL: {
+ struct srs_SS3D_ctrl_params *whd_params = NULL;
+ sz = sizeof(struct asm_pp_params_command) +
+ sizeof(struct srs_SS3D_ctrl_params);
+ open = kzalloc(sz, GFP_KERNEL);
+
+ open->payload_size = sizeof(struct srs_SS3D_ctrl_params) +
+ sizeof(struct asm_pp_param_data_hdr);
+ open->params.param_id = SRS_SS3D_PARAMS_CTRL;
+ open->params.param_size = sizeof(struct srs_SS3D_ctrl_params);
+
+ whd_params = (struct srs_SS3D_ctrl_params *)((u8 *)open +
+ sizeof(struct asm_pp_params_command));
+ memcpy(whd_params, srs_params,
+ sizeof(struct srs_SS3D_ctrl_params));
+
+ {
+ struct SS3D *D = (struct SS3D *)whd_params->v;
+ pr_debug("SRS - ss3d ctrl params\n"
+ "1 = 0x%08X, 2 = 0x%08X, 3 = 0x%04X,\n"
+ "4 = 0x%04X, 5 = 0x%04X, 6 = 0x%04X,\n"
+ "7 = 0x%08X, 8 = 0x%04X, 9 = 0x%04X,\n"
+ "10 = 0x%04X, 11 = 0x%04X, 12 = 0x%04X,\n"
+ "13 = 0x%04X, 14 = 0x%04X, 15 = 0x%04X,\n"
+ "16 = 0x%04X, 17 = 0x%04X, 18 = 0x%04X,\n"
+ "19 = 0x%04X, 20 = 0x%04X, 21 = 0x%04X,\n"
+ "22 = 0x%04X, 23 = 0x%04X, 24 = 0x%04X,\n"
+ "25 = 0x%04X, 26.0 = 0x%04X, 26.1 = 0x%04X,\n"
+ "26.2 = 0x%04X, 26.3 = 0x%04X,\n"
+ "26.4 = 0x%04X, 27 = 0x%04X, 28 = 0x%04X,\n"
+ "29 = 0x%04X, 30 = 0x%04X, 31 = 0x%04X,\n"
+ "32 = 0x%04X, 33 = 0x%04X, 34 = 0x%08X,\n"
+ "35 = 0x%08X, 36 = 0x%08X, 37 = 0x%08X,\n"
+ "38 = 0x%08X, 39 = 0x%08X, 40 = 0x%08X",
+ D->_1, D->_2, D->_3, D->_4, D->_5, D->_6, D->_7,
+ D->_8, D->_9, D->_10, D->_11, D->_12, D->_13,
+ D->_14, D->_15, D->_16, D->_17, D->_18, D->_19,
+ D->_20, D->_21, D->_22, D->_23, D->_24, D->_25,
+ D->_26[0], D->_26[1], D->_26[2], D->_26[3],
+ D->_26[4], D->_27, D->_28, D->_29, D->_30,
+ D->_31, D->_32, D->_33, D->_34, D->_35, D->_36,
+ D->_37, D->_38, D->_39, D->_40);
+ }
+ break;
+ }
+ case SRS_ID_SS3D_FILTER: {
+ struct srs_SS3D_filter_params *chp_params = NULL;
+ sz = sizeof(struct asm_pp_params_command) +
+ sizeof(struct srs_SS3D_filter_params);
+ open = kzalloc(sz, GFP_KERNEL);
+
+ open->payload_size = sizeof(struct srs_SS3D_filter_params) +
+ sizeof(struct asm_pp_param_data_hdr);
+ open->params.param_id = SRS_SS3D_PARAMS_FILTER;
+ open->params.param_size =
+ sizeof(struct srs_SS3D_filter_params);
+
+ chp_params = (struct srs_SS3D_filter_params *)((u8 *)open +
+ sizeof(struct asm_pp_params_command));
+ memcpy(chp_params, srs_params,
+ sizeof(struct srs_SS3D_filter_params));
+
+ {
+ struct SS3D_F *D = (struct SS3D_F *)chp_params->v;
+ pr_debug("SRS - ss3d filter params\n"
+ "1 = 0x%08X, 2 = 0x%08X, 3 = 0x%08X\n"
+ "4 = 0x%08X, 5 = 0x%08X, 6 = 0x%08X\n"
+ "7 = 0x%08X", D->_1, D->_2, D->_3, D->_4, D->_5,
+ D->_6, D->_7);
+ }
+ break;
+ }
+ default:
+ pr_debug("SRS - bad param!\n");
+ goto fail_cmd;
+ }
+
+ open->payload = NULL;
+
+ open->params.module_id = SRS_SS3D_MODULE_ID;
+ open->params.reserved = 0;
+
+ open->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ open->hdr.pkt_size = sz;
+ open->hdr.src_svc = APR_SVC_ADM;
+ open->hdr.src_domain = APR_DOMAIN_APPS;
+ open->hdr.src_port = port_id;
+ open->hdr.dest_svc = APR_SVC_ADM;
+ open->hdr.dest_domain = APR_DOMAIN_ADSP;
+
+ index = afe_get_port_index(port_id);
+ open->hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+ /* port_id;//atomic_read(&this_adm.copp_id[port_id]); */
+ open->hdr.token = port_id;
+ open->hdr.opcode = ADM_CMD_SET_PARAMS;
+
+ pr_debug("SRS - %s: Command was sent now check Q6 - port id = %d,\n"
+ "size %d, module id %x, param id %x.\n",
+ __func__, open->hdr.dest_port, open->payload_size,
+ open->params.module_id, open->params.param_id);
+
+ ret = apr_send_pkt(this_adm.apr, (uint32_t *)open);
+ if (ret < 0) {
+ pr_err("SRS - %s: ADM enable for port %d failed\n",
+ __func__, port_id);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ /* Wait for the callback with copp id */
+ ret = wait_event_timeout(this_adm.wait, 1,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("SRS - %s: ADM open failed for port %d\n",
+ __func__, port_id);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+fail_cmd:
+ kfree(open);
+ return ret;
+}
+
static int32_t adm_callback(struct apr_client_data *data, void *priv)
{
uint32_t *payload;