summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,osm.txt10
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt7
-rw-r--r--Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt18
-rw-r--r--Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt4
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi129
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi129
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi19
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts58
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts58
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.dtsi544
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi9
-rw-r--r--arch/arm/configs/msmfalcon-perf_defconfig607
-rw-r--r--arch/arm/configs/msmfalcon_defconfig76
-rw-r--r--arch/arm64/mm/fault.c3
-rw-r--r--drivers/char/diag/diagfwd.c2
-rw-r--r--drivers/char/diag/diagfwd_peripheral.c12
-rw-r--r--drivers/char/diag/diagfwd_smd.c5
-rw-r--r--drivers/clk/clk.c51
-rw-r--r--drivers/clk/msm/clock-osm.c150
-rw-r--r--drivers/clk/msm/clock.h2
-rw-r--r--drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c246
-rw-r--r--drivers/devfreq/governor_msm_adreno_tz.c5
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c2
-rw-r--r--drivers/misc/qseecom.c215
-rw-r--r--drivers/net/wireless/ath/wil6210/ftm.c97
-rw-r--r--drivers/net/wireless/ath/wil6210/ftm.h10
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm8998.c28
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c10
-rw-r--r--drivers/power/qcom-charger/smb-lib.c22
-rw-r--r--drivers/regulator/cpr3-regulator.h11
-rw-r--r--drivers/regulator/cpr3-util.c70
-rw-r--r--drivers/regulator/cprh-kbss-regulator.c77
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c21
-rw-r--r--drivers/scsi/ufs/ufshcd.c86
-rw-r--r--drivers/scsi/ufs/ufshcd.h1
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c7
-rw-r--r--drivers/usb/gadget/function/f_gsi.c4
-rw-r--r--drivers/usb/pd/qpnp-pdphy.c17
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_compat_utils.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_dba_utils.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_debug.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c15
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c29
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c49
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_host.c20
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c40
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp_1x.c347
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c203
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c26
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h5
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_cdm.c42
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_cdm.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c189
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c46
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c76
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c16
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c51
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c16
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_util.c9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_wfd.c27
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h4
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c15
-rw-r--r--include/linux/clk-provider.h11
-rw-r--r--include/net/sock.h2
-rw-r--r--include/uapi/linux/msm_mdp_ext.h13
-rw-r--r--kernel/power/qos.c26
-rw-r--r--kernel/sched/core.c12
-rw-r--r--kernel/sched/core_ctl.c10
-rw-r--r--kernel/sched/hmp.c6
-rw-r--r--net/core/sock.c14
82 files changed, 3405 insertions, 837 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
index adcaa6444ab8..a8334e1cfde7 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
@@ -289,6 +289,16 @@ Properties:
values per performance mode with a total of 4 tuples
corresponding to each supported performance mode.
+- qcom,perfcl-apcs-mem-acc-threshold-voltage
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the highest MEM ACC threshold voltage in
+ microvolts for the Performance cluster. This voltage is
+ used to determine which MEM ACC setting is used for the
+ highest frequencies. If specified, the voltage must match
+ the MEM ACC threshold voltage specified for the
+ corresponding CPRh device.
+
- qcom,red-fsm-en
Usage: optional
Value type: <empty>
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 56ad8c361219..0174306135c1 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -459,7 +459,11 @@ the fps window.
fields in the supply entry, refer to the qcom,ctrl-supply-entries
binding above.
- qcom,config-select: Optional property to select default configuration.
-
+- qcom,panel-allow-phy-poweroff: A boolean property indicates that panel allows to turn off the phy power
+ supply during idle screen. A panel should able to handle the dsi lanes
+ in floating state(not LP00 or LP11) to turn on this property. Software
+ turns off PHY pmic power supply, phy ldo and DSI Lane ldo during
+ idle screen (footswitch control off) when this property is enabled.
[[Optional config sub-nodes]] These subnodes provide different configurations for a given same panel.
Default configuration can be chosen by specifying phandle of the
selected subnode in the qcom,config-select.
@@ -647,6 +651,7 @@ Example:
qcom,suspend-ulps-enabled;
qcom,panel-roi-alignment = <4 4 2 2 20 20>;
qcom,esd-check-enabled;
+ qcom,panel-allow-phy-poweroff;
qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08];
qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode";
qcom,mdss-dsi-panel-status-check-mode = "reg_read";
diff --git a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt
index 8b806f4828bd..5b0770785dbe 100644
--- a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt
@@ -73,6 +73,24 @@ KBSS specific properties:
switching. If this property is not specified, then a value
of 0 is assumed.
+- qcom,mem-acc-threshold-voltage
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the highest memory accelerator (MEM ACC) threshold
+ voltage in microvolts. The floor to ceiling voltage range
+ for every corner is adjusted to ensure that it does not
+ intersect this voltage. The value of this property must
+ match with the MEM ACC threshold voltage defined in the OSM
+ device to ensure that MEM ACC settings are switched
+ appropriately.
+
+- qcom,mem-acc-crossover-voltage
+ Usage: required if qcom,mem-acc-threshold-voltage is specified
+ Value type: <u32>
+ Definition: Specifies the MEM ACC crossover voltage in microvolts which
+ corresponds to the voltage the VDD supply must be set to
+ when switching the MEM ACC configuration.
+
- qcom,voltage-base
Usage: required
Value type: <u32>
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index bceee5e1747d..a25961c6e7de 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -55,6 +55,10 @@ Optional properties:
- lanes-per-direction: number of lanes available per direction - either 1 or 2.
Note that it is assume same number of lanes is used both directions at once.
If not specified, default is 2 lanes per direction.
+- pinctrl-names, pinctrl-0, pinctrl-1,.. pinctrl-n: Refer to "Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt"
+ for these optional properties
+
+
Note: If above properties are not defined it can be assumed that the supply
regulators or clocks are always on.
diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi
index 66c53649ad71..e83191ebfbc0 100644
--- a/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi
@@ -199,9 +199,7 @@
};
&gfx_cpr {
- reg = <0x05061000 0x4000>,
- <0x00784000 0x1000>;
- reg-names = "cpr_ctrl", "fuse_base";
+ status = "disabled";
/* disable aging and closed-loop */
/delete-property/vdd-supply;
@@ -212,6 +210,8 @@
};
&gfx_vreg {
+ status = "disabled";
+
/delete-property/qcom,cpr-aging-max-voltage-adjustment;
/delete-property/qcom,cpr-aging-ref-corner;
/delete-property/qcom,cpr-aging-ro-scaling-factor;
diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
index 1f5facd5cde5..5685e9041fe4 100644
--- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
@@ -1624,6 +1624,52 @@
};
};
+ ufs_dev_reset_assert: ufs_dev_reset_assert {
+ config {
+ pins = "ufs_reset";
+ bias-pull-down; /* default: pull down */
+ /*
+ * UFS_RESET driver strengths are having
+ * different values/steps compared to typical
+ * GPIO drive strengths.
+ *
+ * Following table clarifies:
+ *
+ * HDRV value | UFS_RESET | Typical GPIO
+ * (dec) | (mA) | (mA)
+ * 0 | 0.8 | 2
+ * 1 | 1.55 | 4
+ * 2 | 2.35 | 6
+ * 3 | 3.1 | 8
+ * 4 | 3.9 | 10
+ * 5 | 4.65 | 12
+ * 6 | 5.4 | 14
+ * 7 | 6.15 | 16
+ *
+ * POR value for UFS_RESET HDRV is 3 which means
+ * 3.1mA and we want to use that. Hence just
+ * specify 8mA to "drive-strength" binding and
+ * that should result into writing 3 to HDRV
+ * field.
+ */
+ drive-strength = <8>; /* default: 3.1 mA */
+ output-low; /* active low reset */
+ };
+ };
+
+ ufs_dev_reset_deassert: ufs_dev_reset_deassert {
+ config {
+ pins = "ufs_reset";
+ bias-pull-down; /* default: pull down */
+ /*
+ * default: 3.1 mA
+ * check comments under ufs_dev_reset_assert
+ */
+ drive-strength = <8>;
+ output-high; /* active low reset */
+ };
+ };
+
sdc2_clk_on: sdc2_clk_on {
config {
pins = "sdc2_clk";
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
index cead74b02528..c09900597d87 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
@@ -15,6 +15,33 @@
#include "msm8998-audio.dtsi"
#include "msm8998-camera-sensor-skuk.dtsi"
+/ {
+ bluetooth: bt_wcn3990 {
+ compatible = "qca,wcn3990";
+ qca,bt-vdd-io-supply = <&pm8998_s3>;
+ qca,bt-vdd-xtal-supply = <&pm8998_s5>;
+ qca,bt-vdd-core-supply = <&pm8998_l7>;
+ qca,bt-vdd-pa-supply = <&pm8998_l17>;
+ qca,bt-vdd-ldo-supply = <&pm8998_l25>;
+ qca,bt-chip-pwd-supply = <&pmi8998_bob_pin1>;
+ clocks = <&clock_gcc clk_rf_clk2_pin>;
+ clock-names = "rf_clk2";
+
+ qca,bt-vdd-io-voltage-level = <1352000 1352000>;
+ qca,bt-vdd-xtal-voltage-level = <2040000 2040000>;
+ qca,bt-vdd-core-voltage-level = <1800000 1800000>;
+ qca,bt-vdd-pa-voltage-level = <1304000 1304000>;
+ qca,bt-vdd-ldo-voltage-level = <3312000 3312000>;
+ qca,bt-chip-pwd-voltage-level = <3600000 3600000>;
+
+ qca,bt-vdd-io-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-xtal-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
+ };
+};
+
&blsp1_uart3_hs {
status = "ok";
};
@@ -210,3 +237,105 @@
&pmi8998_haptics {
status = "okay";
};
+
+&pm8998_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@85 {
+ label = "vcoin";
+ reg = <0x85>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+};
+
+&pm8998_adc_tm {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,btm-channel-number = <0x60>;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x68>;
+ qcom,thermal-node;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
+ };
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x78>;
+ qcom,thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
index ccdfe7ee03f6..bd9d8147dd82 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
@@ -14,6 +14,33 @@
#include "msm8998-pinctrl.dtsi"
#include "msm8998-camera-sensor-qrd-vr1.dtsi"
+/ {
+ bluetooth: bt_wcn3990 {
+ compatible = "qca,wcn3990";
+ qca,bt-vdd-io-supply = <&pm8998_s3>;
+ qca,bt-vdd-xtal-supply = <&pm8998_s5>;
+ qca,bt-vdd-core-supply = <&pm8998_l7>;
+ qca,bt-vdd-pa-supply = <&pm8998_l17>;
+ qca,bt-vdd-ldo-supply = <&pm8998_l25>;
+ qca,bt-chip-pwd-supply = <&pmi8998_bob_pin1>;
+ clocks = <&clock_gcc clk_rf_clk2_pin>;
+ clock-names = "rf_clk2";
+
+ qca,bt-vdd-io-voltage-level = <1352000 1352000>;
+ qca,bt-vdd-xtal-voltage-level = <2040000 2040000>;
+ qca,bt-vdd-core-voltage-level = <1800000 1800000>;
+ qca,bt-vdd-pa-voltage-level = <1304000 1304000>;
+ qca,bt-vdd-ldo-voltage-level = <3312000 3312000>;
+ qca,bt-chip-pwd-voltage-level = <3600000 3600000>;
+
+ qca,bt-vdd-io-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-xtal-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
+ };
+};
+
&blsp1_uart3_hs {
status = "ok";
};
@@ -144,3 +171,105 @@
&pmi8998_haptics {
status = "okay";
};
+
+&pm8998_vadc {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@85 {
+ label = "vcoin";
+ reg = <0x85>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,decimation = <2>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+};
+
+&pm8998_adc_tm {
+ chan@83 {
+ label = "vph_pwr";
+ reg = <0x83>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,btm-channel-number = <0x60>;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x68>;
+ qcom,thermal-node;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
+ };
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x78>;
+ qcom,thermal-node;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
index 41f9c3c69fe9..0a011b3656be 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
@@ -11,7 +11,6 @@
*/
#include <dt-bindings/interrupt-controller/irq.h>
-#include "msm8998-mtp.dtsi"
#include "msm8998-pinctrl.dtsi"
#include "msm8998-camera-sensor-qrd.dtsi"
/ {
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi
index d207628f06a1..dc548f8f499b 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi
@@ -26,6 +26,25 @@
&clock_cpu {
compatible = "qcom,cpu-clock-osm-msm8998-v2";
+ reg = <0x179c0000 0x4000>,
+ <0x17916000 0x1000>,
+ <0x17816000 0x1000>,
+ <0x179d1000 0x1000>,
+ <0x17914800 0x800>,
+ <0x17814800 0x800>,
+ <0x00784130 0x8>,
+ <0x1791101c 0x8>;
+ reg-names = "osm", "pwrcl_pll", "perfcl_pll",
+ "apcs_common", "pwrcl_acd", "perfcl_acd",
+ "perfcl_efuse", "debug";
+
+ qcom,acdtd-val = <0x00009611 0x00009611>;
+ qcom,acdcr-val = <0x002b5ffd 0x002b5ffd>;
+ qcom,acdsscr-val = <0x00000501 0x00000501>;
+ qcom,acdextint0-val = <0x2cf9ae8 0x2cf9ae8>;
+ qcom,acdextint1-val = <0x2cf9afc 0x2cf9afc>;
+ qcom,acdautoxfer-val = <0x00000015 0x00000015>;
+
/delete-property/ qcom,llm-sw-overr;
qcom,pwrcl-speedbin0-v0 =
< 300000000 0x0004000f 0x01200020 0x1 1 >,
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts
index 03e6a7e17215..528e48df1268 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts
@@ -27,3 +27,61 @@
&pmfalcon_charger {
qcom,batteryless-platform;
};
+
+&clock_gcc {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_dig_ao-supply = <&pm2falcon_s3_level_ao>;
+};
+
+&clock_mmss {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_mmsscc_mx-supply = <&pm2falcon_s5_level>;
+};
+
+&clock_gpu {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+};
+
+&clock_gfx {
+ /* GFX Rail = CX */
+ vdd_gpucc-supply = <&pm2falcon_s3_level>;
+ vdd_mx-supply = <&pm2falcon_s5_level>;
+ vdd_gpu_mx-supply = <&pm2falcon_s5_level>;
+ qcom,gfxfreq-speedbin0 =
+ < 0 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_MIN_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_LOW_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS_PLUS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM_PLUS
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ qcom,gfxfreq-mx-speedbin0 =
+ < 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+};
+
+&gdsc_gpu_gx {
+ clock-names = "core_root_clk";
+ clocks = <&clock_gfx clk_gfx3d_clk_src>;
+ qcom,force-enable-root-clk;
+ /* GFX Rail = CX */
+ parent-supply = <&pm2falcon_s3_level>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts
index b66e4bbe236f..0f0a88b33402 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts
@@ -27,3 +27,61 @@
&pmfalcon_fg {
qcom,battery-data = <&mtp_batterydata>;
};
+
+&clock_gcc {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_dig_ao-supply = <&pm2falcon_s3_level_ao>;
+};
+
+&clock_mmss {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_mmsscc_mx-supply = <&pm2falcon_s5_level>;
+};
+
+&clock_gpu {
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+};
+
+&clock_gfx {
+ /* GFX Rail = CX */
+ vdd_gpucc-supply = <&pm2falcon_s3_level>;
+ vdd_mx-supply = <&pm2falcon_s5_level>;
+ vdd_gpu_mx-supply = <&pm2falcon_s5_level>;
+ qcom,gfxfreq-speedbin0 =
+ < 0 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_MIN_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_LOW_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS_PLUS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM_PLUS
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ qcom,gfxfreq-mx-speedbin0 =
+ < 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+};
+
+&gdsc_gpu_gx {
+ clock-names = "core_root_clk";
+ clocks = <&clock_gfx clk_gfx3d_clk_src>;
+ qcom,force-enable-root-clk;
+ /* GFX Rail = CX */
+ parent-supply = <&pm2falcon_s3_level>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
index dc1922851a77..cc4e48ede2ad 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
@@ -26,6 +26,27 @@
&clock_cpu {
compatible = "qcom,cpu-clock-osm-msm8998-v2";
+ reg = <0x179c0000 0x4000>,
+ <0x17916000 0x1000>,
+ <0x17816000 0x1000>,
+ <0x179d1000 0x1000>,
+ <0x17914800 0x800>,
+ <0x17814800 0x800>,
+ <0x00784130 0x8>,
+ <0x1791101c 0x8>;
+ reg-names = "osm", "pwrcl_pll", "perfcl_pll",
+ "apcs_common", "pwrcl_acd", "perfcl_acd",
+ "perfcl_efuse", "debug";
+
+ qcom,acdtd-val = <0x00009611 0x00009611>;
+ qcom,acdcr-val = <0x002b5ffd 0x002b5ffd>;
+ qcom,acdsscr-val = <0x00000501 0x00000501>;
+ qcom,acdextint0-val = <0x2cf9ae8 0x2cf9ae8>;
+ qcom,acdextint1-val = <0x2cf9afe 0x2cf9afe>;
+ qcom,acdautoxfer-val = <0x00000015 0x00000015>;
+ qcom,perfcl-apcs-mem-acc-threshold-voltage = <852000>;
+ qcom,apm-threshold-voltage = <800000>;
+
/delete-property/ qcom,llm-sw-overr;
qcom,pwrcl-speedbin0-v0 =
< 300000000 0x0004000f 0x01200020 0x1 1 >,
@@ -77,11 +98,20 @@
< 1958400000 0x04040066 0x09520052 0x2 23 >,
< 2035200000 0x0404006a 0x09550055 0x3 24 >,
< 2112000000 0x0404006e 0x0a580058 0x3 25 >,
- < 2188800000 0x04040072 0x0a5b005b 0x3 26 >,
+ < 2208000000 0x04040073 0x0a5c005c 0x3 26 >,
+ < 2265600000 0x04010076 0x0a5e005e 0x3 26 >,
< 2265600000 0x04040076 0x0a5e005e 0x3 27 >,
+ < 2342400000 0x0401007a 0x0a620062 0x3 27 >,
< 2342400000 0x0404007a 0x0a620062 0x3 28 >,
+ < 2419200000 0x0401007e 0x0a650065 0x3 28 >,
< 2419200000 0x0404007e 0x0a650065 0x3 29 >,
- < 2496000000 0x04040082 0x0a680068 0x3 30 >;
+ < 2496000000 0x04010082 0x0a680068 0x3 29 >,
+ < 2457600000 0x04040080 0x0a660066 0x3 30 >,
+ < 2553600000 0x04010085 0x0a6a006a 0x3 30 >,
+ < 2476800000 0x04040081 0x0a670067 0x3 31 >,
+ < 2572800000 0x04010086 0x0a6b006b 0x3 31 >,
+ < 2496000000 0x04040082 0x0a680068 0x3 32 >,
+ < 2592000000 0x04010087 0x0a6c006c 0x3 32 >;
qcom,perfcl-speedbin1-v0 =
< 300000000 0x0004000f 0x01200020 0x1 1 >,
@@ -110,7 +140,81 @@
< 2035200000 0x0404006a 0x09550055 0x3 24 >,
< 2112000000 0x0404006e 0x0a580058 0x3 25 >,
< 2208000000 0x04040073 0x0a5c005c 0x3 26 >,
- < 2304000000 0x04010078 0x0a5c005c 0x3 26 >;
+ < 2304000000 0x04010078 0x0a600060 0x3 26 >;
+
+ qcom,perfcl-speedbin2-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 345600000 0x05040012 0x01200020 0x1 2 >,
+ < 422400000 0x05040016 0x02200020 0x1 3 >,
+ < 499200000 0x0504001a 0x02200020 0x1 4 >,
+ < 576000000 0x0504001e 0x02200020 0x1 5 >,
+ < 652800000 0x05040022 0x03200020 0x1 6 >,
+ < 729600000 0x05040026 0x03200020 0x1 7 >,
+ < 806400000 0x0504002a 0x03220022 0x1 8 >,
+ < 902400000 0x0404002f 0x04260026 0x1 9 >,
+ < 979200000 0x04040033 0x04290029 0x1 10 >,
+ < 1056000000 0x04040037 0x052c002c 0x1 11 >,
+ < 1132800000 0x0404003b 0x052f002f 0x1 12 >,
+ < 1190400000 0x0404003e 0x05320032 0x2 13 >,
+ < 1267200000 0x04040042 0x06350035 0x2 14 >,
+ < 1344000000 0x04040046 0x06380038 0x2 15 >,
+ < 1420800000 0x0404004a 0x063b003b 0x2 16 >,
+ < 1497600000 0x0404004e 0x073e003e 0x2 17 >,
+ < 1574400000 0x04040052 0x07420042 0x2 18 >,
+ < 1651200000 0x04040056 0x07450045 0x2 19 >,
+ < 1728000000 0x0404005a 0x08480048 0x2 20 >,
+ < 1804800000 0x0404005e 0x084b004b 0x2 21 >,
+ < 1881600000 0x04040062 0x094e004e 0x2 22 >,
+ < 1958400000 0x04040066 0x09520052 0x2 23 >,
+ < 2035200000 0x0404006a 0x09550055 0x3 24 >,
+ < 2112000000 0x0404006e 0x0a580058 0x3 25 >,
+ < 2208000000 0x04040073 0x0a5c005c 0x3 26 >,
+ < 2265600000 0x04010076 0x0a5e005e 0x3 26 >,
+ < 2265600000 0x04040076 0x0a5e005e 0x3 27 >,
+ < 2342400000 0x0401007a 0x0a620062 0x3 27 >,
+ < 2323200000 0x04040079 0x0a610061 0x3 28 >,
+ < 2419200000 0x0401007e 0x0a650065 0x3 28 >,
+ < 2342400000 0x0404007a 0x0a620062 0x3 29 >,
+ < 2438400000 0x0401007f 0x0a660066 0x3 29 >,
+ < 2361600000 0x0404007b 0x0a620062 0x3 30 >,
+ < 2457600000 0x04010080 0x0a660066 0x3 30 >;
+
+ qcom,perfcl-speedbin3-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 345600000 0x05040012 0x01200020 0x1 2 >,
+ < 422400000 0x05040016 0x02200020 0x1 3 >,
+ < 499200000 0x0504001a 0x02200020 0x1 4 >,
+ < 576000000 0x0504001e 0x02200020 0x1 5 >,
+ < 652800000 0x05040022 0x03200020 0x1 6 >,
+ < 729600000 0x05040026 0x03200020 0x1 7 >,
+ < 806400000 0x0504002a 0x03220022 0x1 8 >,
+ < 902400000 0x0404002f 0x04260026 0x1 9 >,
+ < 979200000 0x04040033 0x04290029 0x1 10 >,
+ < 1056000000 0x04040037 0x052c002c 0x1 11 >,
+ < 1132800000 0x0404003b 0x052f002f 0x1 12 >,
+ < 1190400000 0x0404003e 0x05320032 0x2 13 >,
+ < 1267200000 0x04040042 0x06350035 0x2 14 >,
+ < 1344000000 0x04040046 0x06380038 0x2 15 >,
+ < 1420800000 0x0404004a 0x063b003b 0x2 16 >,
+ < 1497600000 0x0404004e 0x073e003e 0x2 17 >,
+ < 1574400000 0x04040052 0x07420042 0x2 18 >,
+ < 1651200000 0x04040056 0x07450045 0x2 19 >,
+ < 1728000000 0x0404005a 0x08480048 0x2 20 >,
+ < 1804800000 0x0404005e 0x084b004b 0x2 21 >,
+ < 1881600000 0x04040062 0x094e004e 0x2 22 >,
+ < 1958400000 0x04040066 0x09520052 0x2 23 >,
+ < 2035200000 0x0404006a 0x09550055 0x3 24 >,
+ < 2112000000 0x0404006e 0x0a580058 0x3 25 >,
+ < 2208000000 0x04040073 0x0a5c005c 0x3 26 >,
+ < 2265600000 0x04010076 0x0a5e005e 0x3 26 >,
+ < 2265600000 0x04040076 0x0a5e005e 0x3 27 >,
+ < 2342400000 0x0401007a 0x0a620062 0x3 27 >,
+ < 2323200000 0x04040079 0x0a610061 0x3 28 >,
+ < 2419200000 0x0401007e 0x0a650065 0x3 28 >,
+ < 2342400000 0x0404007a 0x0a620062 0x3 29 >,
+ < 2438400000 0x0401007f 0x0a660066 0x3 29 >,
+ < 2361600000 0x0404007b 0x0a620062 0x3 30 >,
+ < 2457600000 0x04010080 0x0a660066 0x3 30 >;
};
&msm_cpufreq {
@@ -164,11 +268,17 @@
< 1958400 >,
< 2035200 >,
< 2112000 >,
- < 2188800 >,
+ < 2208000 >,
< 2265600 >,
+ < 2304000 >,
+ < 2323200 >,
< 2342400 >,
+ < 2361600 >,
< 2419200 >,
- < 2496000 >;
+ < 2457600 >,
+ < 2476800 >,
+ < 2496000 >,
+ < 2592000 >;
};
&bwmon {
@@ -339,34 +449,21 @@
compatible = "qcom,cprh-msm8998-v2-kbss-regulator";
qcom,cpr-corner-switch-delay-time = <1042>;
qcom,cpr-aging-ref-voltage = <1056000>;
+ qcom,apm-threshold-voltage = <800000>;
+ qcom,apm-hysteresis-voltage = <0>;
};
&apc0_pwrcl_vreg {
regulator-max-microvolt = <23>;
- qcom,cpr-fuse-combos = <16>;
- qcom,cpr-speed-bins = <2>;
- qcom,cpr-speed-bin-corners = <22 22>;
- qcom,cpr-corners =
- /* Speed bin 0 */
- <22 22 22 22 22 22 22 22>,
- /* Speed bin 1 */
- <22 22 22 22 22 22 22 22>;
+ qcom,cpr-fuse-combos = <32>;
+ qcom,cpr-speed-bins = <4>;
+ qcom,cpr-speed-bin-corners = <22 22 22 22>;
+ qcom,cpr-corners = <22>;
- qcom,cpr-corner-fmax-map =
- /* Speed bin 0 */
- <8 11 18 22>,
- /* Speed bin 1 */
- <8 11 18 22>;
+ qcom,cpr-corner-fmax-map = <8 11 18 22>;
qcom,cpr-voltage-ceiling =
- /* Speed bin 0 */
- <828000 828000 828000 828000 828000
- 828000 828000 828000 828000 828000
- 828000 900000 900000 900000 900000
- 900000 900000 900000 952000 952000
- 1056000 1056000>,
- /* Speed bin 1 */
<828000 828000 828000 828000 828000
828000 828000 828000 828000 828000
828000 900000 900000 900000 900000
@@ -374,13 +471,6 @@
1056000 1056000>;
qcom,cpr-voltage-floor =
- /* Speed bin 0 */
- <568000 568000 568000 568000 568000
- 568000 568000 568000 568000 568000
- 568000 632000 632000 632000 632000
- 632000 632000 632000 712000 712000
- 772000 772000>,
- /* Speed bin 1 */
<568000 568000 568000 568000 568000
568000 568000 568000 568000 568000
568000 632000 632000 632000 632000
@@ -388,32 +478,14 @@
772000 772000>;
qcom,cpr-floor-to-ceiling-max-range =
- /* Speed bin 0 */
- <55000 55000 55000 55000
- 55000 55000 55000 55000
- 55000 55000 55000 65000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000>,
- /* Speed bin 1 */
- <55000 55000 55000 55000
- 55000 55000 55000 55000
- 55000 55000 55000 65000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000>;
+ <32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 40000 40000
+ 40000 40000>;
qcom,corner-frequencies =
- /* Speed bin 0 */
- <300000000 364800000 441600000
- 518400000 595200000 672000000
- 748800000 825600000 883200000
- 960000000 1036800000 1094400000
- 1171200000 1248000000 1324800000
- 1401600000 1478400000 1555200000
- 1670400000 1747200000 1824000000
- 1900800000>,
- /* Speed bin 1 */
<300000000 364800000 441600000
518400000 595200000 672000000
748800000 825600000 883200000
@@ -439,78 +511,128 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
/* Speed bin 1 */
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <40000 24000 0 30000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>,
- <25000 9000 (-15000) 15000>;
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ /* Speed bin 2 */
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ /* Speed bin 3 */
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <40000 24000 12000 30000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>,
+ <25000 9000 (-3000) 15000>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
/* Speed bin 1 */
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- <20000 26000 0 30000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>,
- < 5000 11000 (-15000) 15000>;
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ /* Speed bin 2 */
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ /* Speed bin 3 */
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ <20000 26000 12000 30000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>,
+ < 5000 11000 (-3000) 15000>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
- qcom,cpr-aging-ref-corner = <22 22>;
+ qcom,cpr-aging-ref-corner = <22>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
qcom,allow-aging-voltage-adjustment =
<0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>,
<0 0 0 0 1 1 1 1>;
};
&apc1_cpr {
compatible = "qcom,cprh-msm8998-v2-kbss-regulator";
qcom,cpr-corner-switch-delay-time = <1042>;
- qcom,cpr-aging-ref-voltage = <1056000>;
+ qcom,cpr-aging-ref-voltage = <1136000>;
+ qcom,apm-threshold-voltage = <800000>;
+ qcom,apm-hysteresis-voltage = <0>;
+ qcom,mem-acc-threshold-voltage = <852000>;
+ qcom,mem-acc-crossover-voltage = <852000>;
};
&apc1_perfcl_vreg {
- regulator-max-microvolt = <31>;
+ regulator-max-microvolt = <34>;
- qcom,cpr-fuse-combos = <16>;
- qcom,cpr-speed-bins = <2>;
- qcom,cpr-speed-bin-corners = <30 26>;
+ qcom,cpr-fuse-combos = <32>;
+ qcom,cpr-speed-bins = <4>;
+ qcom,cpr-speed-bin-corners = <32 26 30 31>;
qcom,cpr-corners =
/* Speed bin 0 */
- <30 30 30 30 30 30 30 30>,
+ <32 32 32 32 32 32 32 32>,
/* Speed bin 1 */
- <26 26 26 26 26 26 26 26>;
+ <26 26 26 26 26 26 26 26>,
+ /* Speed bin 2 */
+ <30 30 30 30 30 30 30 30>,
+ /* Speed bin 3 */
+ <31 31 31 31 31 31 31 31>;
qcom,cpr-corner-fmax-map =
/* Speed bin 0 */
- <8 12 20 30>,
+ <8 12 20 32>,
/* Speed bin 1 */
- <8 12 20 26>;
+ <8 12 20 26>,
+ /* Speed bin 2 */
+ <8 12 20 30>,
+ /* Speed bin 3 */
+ <8 12 20 31>;
qcom,cpr-voltage-ceiling =
/* Speed bin 0 */
@@ -518,15 +640,31 @@
828000 828000 828000 828000 828000
828000 828000 900000 900000 900000
900000 900000 900000 900000 900000
- 952000 952000 952000 1056000 1056000
- 1056000 1056000 1056000 1056000 1056000>,
+ 952000 952000 952000 1136000 1136000
+ 1136000 1136000 1136000 1136000 1136000
+ 1136000 1136000>,
/* Speed bin 1 */
<828000 828000 828000 828000 828000
828000 828000 828000 828000 828000
828000 828000 900000 900000 900000
900000 900000 900000 900000 900000
- 952000 952000 952000 1056000 1056000
- 1056000>;
+ 952000 952000 952000 1136000 1136000
+ 1136000>,
+ /* Speed bin 2 */
+ <828000 828000 828000 828000 828000
+ 828000 828000 828000 828000 828000
+ 828000 828000 900000 900000 900000
+ 900000 900000 900000 900000 900000
+ 952000 952000 952000 1136000 1136000
+ 1136000 1136000 1136000 1136000 1136000>,
+ /* Speed bin 3 */
+ <828000 828000 828000 828000 828000
+ 828000 828000 828000 828000 828000
+ 828000 828000 900000 900000 900000
+ 900000 900000 900000 900000 900000
+ 952000 952000 952000 1136000 1136000
+ 1136000 1136000 1136000 1136000 1136000
+ 1136000>;
qcom,cpr-voltage-floor =
/* Speed bin 0 */
@@ -535,33 +673,67 @@
568000 568000 632000 632000 632000
632000 632000 632000 632000 632000
712000 712000 712000 772000 772000
- 772000 772000 772000 772000 772000>,
+ 772000 772000 772000 772000 772000
+ 772000 772000>,
/* Speed bin 1 */
<568000 568000 568000 568000 568000
568000 568000 568000 568000 568000
568000 568000 632000 632000 632000
632000 632000 632000 632000 632000
712000 712000 712000 772000 772000
+ 772000>,
+ /* Speed bin 2 */
+ <568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 632000 632000 632000
+ 632000 632000 632000 632000 632000
+ 712000 712000 712000 772000 772000
+ 772000 772000 772000 772000 772000>,
+ /* Speed bin 3 */
+ <568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 632000 632000 632000
+ 632000 632000 632000 632000 632000
+ 712000 712000 712000 772000 772000
+ 772000 772000 772000 772000 772000
772000>;
qcom,cpr-floor-to-ceiling-max-range =
/* Speed bin 0 */
- <55000 55000 55000 55000
- 55000 55000 55000 55000
- 55000 55000 55000 55000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000>,
+ <32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 40000 40000 40000 40000
+ 40000 40000 40000 40000
+ 40000 40000 40000 40000>,
/* Speed bin 1 */
- <55000 55000 55000 55000
- 55000 55000 55000 55000
- 55000 55000 55000 55000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000 65000 65000
- 65000 65000>;
+ <32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 40000 40000 40000 40000
+ 40000 40000>,
+ /* Speed bin 2 */
+ <32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 40000 40000 40000 40000
+ 40000 40000 40000 40000
+ 40000 40000>,
+ /* Speed bin 3 */
+ <32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 32000 32000 32000 32000
+ 40000 40000 40000 40000
+ 40000 40000 40000 40000
+ 40000 40000 40000>;
qcom,corner-frequencies =
/* Speed bin 0 */
@@ -573,8 +745,9 @@
1420800000 1497600000 1574400000
1651200000 1728000000 1804800000
1881600000 1958400000 2035200000
- 2112000000 2188800000 2265600000
- 2342400000 2419200000 2496000000>,
+ 2112000000 2208000000 2265600000
+ 2342400000 2419200000 2457600000
+ 2476800000 2496000000>,
/* Speed bin 1 */
<300000000 345600000 422400000
499200000 576000000 652800000
@@ -584,7 +757,30 @@
1420800000 1497600000 1574400000
1651200000 1728000000 1804800000
1881600000 1958400000 2035200000
- 2112000000 2208000000>;
+ 2112000000 2208000000>,
+ /* Speed bin 2 */
+ <300000000 345600000 422400000
+ 499200000 576000000 652800000
+ 729600000 806400000 902400000
+ 979200000 1056000000 1132800000
+ 1190400000 1267200000 1344000000
+ 1420800000 1497600000 1574400000
+ 1651200000 1728000000 1804800000
+ 1881600000 1958400000 2035200000
+ 2112000000 2208000000 2265600000
+ 2323200000 2342400000 2361600000>,
+ /* Speed bin 3 */
+ <300000000 345600000 422400000
+ 499200000 576000000 652800000
+ 729600000 806400000 902400000
+ 979200000 1056000000 1132800000
+ 1190400000 1267200000 1344000000
+ 1420800000 1497600000 1574400000
+ 1651200000 1728000000 1804800000
+ 1881600000 1958400000 2035200000
+ 2112000000 2208000000 2265600000
+ 2323200000 2342400000 2361600000
+ 2457600000>;
qcom,cpr-ro-scaling-factor =
<2857 3057 2828 2952 2699 2798 2446
@@ -602,52 +798,90 @@
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
/* Speed bin 1 */
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- < 8000 0 0 52000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>,
- <(-7000) (-15000) (-15000) 37000>;
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ /* Speed bin 2 */
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ /* Speed bin 3 */
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ < 8000 0 12000 52000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>,
+ <(-7000) (-15000) (-3000) 37000>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0 */
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ /* Speed bin 1 */
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ /* Speed bin 0 */
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
/* Speed bin 1 */
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- < 0 0 0 50000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>,
- <(-15000) (-15000) (-15000) 35000>;
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ < 0 0 12000 50000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>,
+ <(-15000) (-15000) (-3000) 35000>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
- qcom,cpr-aging-ref-corner = <30 26>;
+ qcom,cpr-aging-ref-corner = <32 26 30 31>;
qcom,cpr-aging-ro-scaling-factor = <1700>;
qcom,allow-aging-voltage-adjustment =
<0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>,
+ <0 0 0 0 1 1 1 1>,
<0 0 0 0 1 1 1 1>;
};
@@ -839,7 +1073,7 @@
&soc {
/* Gold L2 SAW */
qcom,spm@178120000 {
- qcom,saw2-avs-limit = <0x4200420>;
+ qcom,saw2-avs-limit = <0x4700470>;
};
/* Silver L2 SAW */
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 7f7f2f65deee..ef488bbe0010 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -1660,6 +1660,10 @@
qcom,pm-qos-cpu-group-latency-us = <70 70>;
qcom,pm-qos-default-cpu = <0>;
+ pinctrl-names = "dev-reset-assert", "dev-reset-deassert";
+ pinctrl-0 = <&ufs_dev_reset_assert>;
+ pinctrl-1 = <&ufs_dev_reset_deassert>;
+
resets = <&clock_gcc UFS_BCR>;
reset-names = "core_reset";
@@ -2994,11 +2998,6 @@
vdd-3.3-ch0-supply = <&pm8998_l25_pin_ctrl>;
qcom,vdd-0.8-cx-mx-config = <800000 800000>;
qcom,vdd-3.3-ch0-config = <3104000 3312000>;
- qcom,msm-bus,name = "msm-icnss";
- qcom,msm-bus,num-cases = <2>;
- qcom,msm-bus,num-paths = <1>;
- qcom,msm-bus,vectors-KBps = <81 10065 0 0>,
- <81 10065 0 16000>;
qcom,icnss-vadc = <&pm8998_vadc>;
qcom,icnss-adc_tm = <&pm8998_adc_tm>;
};
diff --git a/arch/arm/configs/msmfalcon-perf_defconfig b/arch/arm/configs/msmfalcon-perf_defconfig
new file mode 100644
index 000000000000..1f8d22153a32
--- /dev/null
+++ b/arch/arm/configs/msmfalcon-perf_defconfig
@@ -0,0 +1,607 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_SCHED_HMP=y
+CONFIG_SCHED_HMP_CSTATE_AWARE=y
+CONFIG_SCHED_CORE_CTL=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_SCHED_TUNE=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_MEMBARRIER is not set
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
+CONFIG_MODULE_SIG_SHA512=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSMFALCON=y
+CONFIG_ARCH_MSMTRITON=y
+CONFIG_ARM_KERNMEM_PERMS=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_NR_CPUS=8
+CONFIG_ARM_PSCI=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_CLEANCACHE=y
+CONFIG_CMA=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_ZSMALLOC=y
+CONFIG_SECCOMP=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
+# CONFIG_CPU_FREQ_STAT is not set
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_L2TP=y
+CONFIG_L2TP_DEBUGFS=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=y
+CONFIG_NET_EMATCH_NBYTE=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_EMATCH_META=y
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_SOCKEV_NLMCAST=y
+CONFIG_BT=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_BTFM_SLIM=y
+CONFIG_BTFM_SLIM_WCN3990=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+# CONFIG_CFG80211_CRDA_SUPPORT is not set
+CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=40
+CONFIG_ZRAM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_QSEECOM=y
+CONFIG_HDCP_QSEECOM=y
+CONFIG_UID_CPUTIME=y
+CONFIG_MSM_ULTRASOUND=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=y
+CONFIG_DUMMY=y
+CONFIG_TUN=y
+CONFIG_RNDIS_IPA=y
+CONFIG_PHYLIB=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_ATH_CARDS=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_QPNP_POWER_ON=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYRESET=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y
+CONFIG_SECURE_TOUCH=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_SERIAL_MSM_SMD=y
+CONFIG_DIAG_CHAR=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_MSM_ADSPRPC=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
+CONFIG_SLIMBUS=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_SOUNDWIRE=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPMI=y
+CONFIG_PINCTRL_MSMFALCON=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_APSS_CORE_EA=y
+CONFIG_MSM_APM=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_MSM_BCL_CTL=y
+CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_BATTERY_BCL=y
+CONFIG_QPNP_SMB2=y
+CONFIG_SMB138X_CHARGER=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_LIMITS_MONITOR=y
+CONFIG_LIMITS_LITE_HW=y
+CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_QCOM_THERMAL_LIMITS_DCVS=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MSM_CDC_PINCTRL=y
+CONFIG_MSM_CDC_SUPPLY=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_SPM=y
+CONFIG_REGULATOR_CPR3_HMSS=y
+CONFIG_REGULATOR_CPR3_MMSS=y
+CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_PROXY_CONSUMER=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA=y
+CONFIG_MSM_CAMERA_DEBUG=y
+CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_QCOM_KGSL=y
+CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
+CONFIG_FB_MSM=y
+CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_WRITEBACK=y
+CONFIG_FB_MSM_MDSS_HDMI_PANEL=y
+CONFIG_FB_MSM_MDSS_DP_PANEL=y
+CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO_QMI=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_PLANTRONICS=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_ISP1760=y
+CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_PD_POLICY=y
+CONFIG_QPNP_USB_PDPHY=y
+CONFIG_USB_OTG_WAKELOCK=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_QUSB_PHY=y
+CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_MTP=y
+CONFIG_USB_CONFIGFS_F_PTP=y
+CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_DIAG=y
+CONFIG_USB_CONFIGFS_F_GSI=y
+CONFIG_USB_CONFIGFS_F_CDEV=y
+CONFIG_USB_CONFIGFS_F_QDSS=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH_V2=y
+CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_SWITCH=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_QPNP_REVID=y
+CONFIG_QPNP_COINCELL=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_IPA=y
+CONFIG_RMNET_IPA=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_RMNET_IPA3=y
+CONFIG_GPIO_USB_DETECT=y
+CONFIG_SEEMP_CORE=y
+CONFIG_USB_BAM=y
+CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_MSM_GCC_FALCON=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_ARM_SMMU=y
+CONFIG_QCOM_COMMON_LOG=y
+CONFIG_MSM_SMEM=y
+CONFIG_QPNP_HAPTIC=y
+CONFIG_MSM_SMD=y
+CONFIG_MSM_SMD_DEBUG=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMD_XPRT=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_MSM_SPCOM=y
+CONFIG_MSM_SMEM_LOGGING=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_QCOM_BUS_SCALING=y
+CONFIG_MSM_SERVICE_LOCATOR=y
+CONFIG_QCOM_DCC=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_SYSMON_GLINK_COMM=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SPM=y
+CONFIG_QCOM_SCM=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_IRQ_HELPER=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_ICNSS=y
+CONFIG_MSM_GLADIATOR_ERP_V2=y
+CONFIG_PANIC_ON_GLADIATOR_ERROR_V2=y
+CONFIG_MSM_GLADIATOR_HANG_DETECT=y
+CONFIG_MSM_RUN_QUEUE_STATS=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_QCOM_CPUSS_DUMP=y
+CONFIG_MSM_QDSP6_APRV2_GLINK=y
+CONFIG_MSM_ADSP_LOADER=y
+CONFIG_MSM_PERFORMANCE=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_TRACER_PKT=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_MSM_MPM_OF=y
+CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_AVTIMER=y
+CONFIG_QCOM_REMOTEQDSS=y
+CONFIG_MSM_SERVICE_NOTIFIER=y
+CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
+CONFIG_MSM_RPM_LOG=y
+CONFIG_MSM_RPM_STATS_LOG=y
+CONFIG_MEM_SHARE_QMI_SERVICE=y
+CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_ARM_MEMLAT_MON=y
+CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
+CONFIG_DEVFREQ_SPDM=y
+CONFIG_PM_DEVFREQ_EVENT=y
+CONFIG_EXTCON=y
+CONFIG_IIO=y
+CONFIG_QCOM_RRADC=y
+CONFIG_QCOM_TADC=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_SENSORS_SSC=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_EXT4_FS_ENCRYPTION=y
+CONFIG_EXT4_DEBUG=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=y
+CONFIG_ECRYPT_FS_MESSAGING=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PAGE_EXTENSION=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_TIMEOUT=5
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_PANIC_ON_SCHED_BUG=y
+CONFIG_PANIC_ON_RT_THROTTLING=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_IPC_LOGGING=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_TRACER_SNAPSHOT=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_DEBUG_SET_MODULE_RONX=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_LINKS_AND_SINKS=y
+CONFIG_CORESIGHT_QCOM_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+CONFIG_CORESIGHT_QPDI=y
+CONFIG_CORESIGHT_SOURCE_DUMMY=y
+CONFIG_PFK=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
+CONFIG_CRYPTO_DEV_QCE=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_XZ_DEC=y
diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig
index abd89c1ca060..06faf702156f 100644
--- a/arch/arm/configs/msmfalcon_defconfig
+++ b/arch/arm/configs/msmfalcon_defconfig
@@ -6,16 +6,22 @@ CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_RCU_EXPERT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_HMP=y
+CONFIG_SCHED_HMP_CSTATE_AWARE=y
+CONFIG_SCHED_CORE_CTL=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
+CONFIG_SCHED_TUNE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
@@ -32,6 +38,7 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_SHA512=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
@@ -39,6 +46,7 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSMFALCON=y
CONFIG_ARCH_MSMTRITON=y
+CONFIG_ARM_KERNMEM_PERMS=y
CONFIG_SMP=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
@@ -49,6 +57,7 @@ CONFIG_HIGHMEM=y
# CONFIG_HIGHPTE is not set
CONFIG_CLEANCACHE=y
CONFIG_CMA=y
+CONFIG_CMA_DEBUGFS=y
CONFIG_ZSMALLOC=y
CONFIG_SECCOMP=y
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
@@ -239,6 +248,8 @@ CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_NETDEVICES=y
@@ -250,9 +261,15 @@ CONFIG_PHYLIB=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
CONFIG_PPPOLAC=y
CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_ATH_CARDS=y
CONFIG_CLD_LL_CORE=y
@@ -265,6 +282,7 @@ CONFIG_INPUT_JOYSTICK=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21=y
+CONFIG_SECURE_TOUCH=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_KEYCHORD=y
@@ -277,6 +295,7 @@ CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_MSM_ADSPRPC=y
@@ -289,10 +308,13 @@ CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
-CONFIG_PINCTRL_MSM8998=y
CONFIG_PINCTRL_MSMFALCON=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
CONFIG_APSS_CORE_EA=y
CONFIG_MSM_APM=y
CONFIG_QPNP_SMBCHARGER=y
@@ -300,10 +322,19 @@ CONFIG_SMB135X_CHARGER=y
CONFIG_SMB1351_USB_CHARGER=y
CONFIG_MSM_BCL_CTL=y
CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_SMB2=y
CONFIG_SMB138X_CHARGER=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_LIMITS_MONITOR=y
+CONFIG_LIMITS_LITE_HW=y
+CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_QCOM_THERMAL_LIMITS_DCVS=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_I2C_PMIC=y
CONFIG_MSM_CDC_PINCTRL=y
@@ -329,7 +360,10 @@ CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA=y
CONFIG_MSM_CAMERA_DEBUG=y
+CONFIG_MSM_VIDC_V4L2=m
+CONFIG_MSM_VIDC_GOVERNORS=m
CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
@@ -345,10 +379,16 @@ CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_AUDIO_QMI=y
CONFIG_SND_SOC=y
CONFIG_UHID=y
CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_PLANTRONICS=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
@@ -359,6 +399,8 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_ISP1760=y
CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_PD_POLICY=y
+CONFIG_QPNP_USB_PDPHY=y
CONFIG_USB_OTG_WAKELOCK=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_MSM_SSPHY_QMP=y
@@ -367,12 +409,14 @@ CONFIG_DUAL_ROLE_USB_INTF=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_F_ACC=y
CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_DIAG=y
CONFIG_USB_CONFIGFS_F_GSI=y
@@ -392,6 +436,7 @@ CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
@@ -420,6 +465,7 @@ CONFIG_GSI=y
CONFIG_IPA3=y
CONFIG_RMNET_IPA3=y
CONFIG_GPIO_USB_DETECT=y
+CONFIG_SEEMP_CORE=y
CONFIG_USB_BAM=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_MSM_GPUCC_FALCON=y
@@ -438,6 +484,7 @@ CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
CONFIG_MSM_GLINK_SMD_XPRT=y
CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
CONFIG_MSM_SPCOM=y
+CONFIG_MSM_SPSS_UTILS=y
CONFIG_MSM_SMEM_LOGGING=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_SMP2P_TEST=y
@@ -464,6 +511,7 @@ CONFIG_MSM_RUN_QUEUE_STATS=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_CPUSS_DUMP=y
CONFIG_MSM_QDSP6_APRV2_GLINK=y
+CONFIG_MSM_ADSP_LOADER=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
@@ -473,15 +521,25 @@ CONFIG_TRACER_PKT=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_MSM_MPM_OF=y
CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_AVTIMER=y
CONFIG_QCOM_REMOTEQDSS=y
CONFIG_MSM_SERVICE_NOTIFIER=y
+CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
+CONFIG_MSM_RPM_LOG=y
+CONFIG_MSM_RPM_STATS_LOG=y
+CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_MEM_SHARE_QMI_SERVICE=y
CONFIG_QCOM_BIMC_BWMON=y
+CONFIG_ARM_MEMLAT_MON=y
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
+CONFIG_SPDM_SCM=y
+CONFIG_DEVFREQ_SPDM=y
CONFIG_EXTCON=y
CONFIG_IIO=y
CONFIG_QCOM_RRADC=y
+CONFIG_QCOM_TADC=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
CONFIG_ARM_GIC_V3_ACL=y
@@ -493,6 +551,9 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_EXT4_FS_ENCRYPTION=y
+CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
@@ -509,6 +570,8 @@ CONFIG_DEBUG_INFO=y
CONFIG_PAGE_OWNER=y
CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
CONFIG_SLUB_DEBUG_PANIC_ON=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_FREE=y
@@ -542,8 +605,10 @@ CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_IPC_LOGGING=y
CONFIG_QCOM_RTB=y
+CONFIG_QCOM_RTB_SEPARATE_CPUS=y
CONFIG_FUNCTION_TRACER=y
-CONFIG_TRACER_SNAPSHOT=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_CPU_FREQ_SWITCH_PROFILER=y
CONFIG_MEMTEST=y
@@ -551,13 +616,19 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y
CONFIG_PID_IN_CONTEXTIDR=y
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_LINKS_AND_SINKS=y
CONFIG_CORESIGHT_REMOTE_ETM=y
CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0
+CONFIG_CORESIGHT_QCOM_REPLICATOR=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_HWEVENT=y
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_TPDA=y
CONFIG_CORESIGHT_TPDM=y
CONFIG_CORESIGHT_QPDI=y
CONFIG_CORESIGHT_SOURCE_DUMMY=y
+CONFIG_PFK=y
CONFIG_SECURITY=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SMACK=y
@@ -571,4 +642,5 @@ CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
CONFIG_CRYPTO_DEV_QCE=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
CONFIG_XZ_DEC=y
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 55b944a913cb..7326be306618 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -283,7 +283,8 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
if (esr & ESR_LNX_EXEC) {
vm_flags = VM_EXEC;
- } else if ((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) {
+ } else if (((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) ||
+ ((esr & ESR_ELx_CM) && !(mm_flags & FAULT_FLAG_USER))) {
vm_flags = VM_WRITE;
mm_flags |= FAULT_FLAG_WRITE;
}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 0111b02634c8..876b455624b2 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1275,6 +1275,7 @@ static uint8_t hdlc_reset;
static void hdlc_reset_timer_start(struct diag_md_session_t *info)
{
+ mutex_lock(&driver->md_session_lock);
if (!hdlc_timer_in_progress) {
hdlc_timer_in_progress = 1;
if (info)
@@ -1284,6 +1285,7 @@ static void hdlc_reset_timer_start(struct diag_md_session_t *info)
mod_timer(&driver->hdlc_reset_timer,
jiffies + msecs_to_jiffies(200));
}
+ mutex_unlock(&driver->md_session_lock);
}
static void hdlc_reset_timer_func(unsigned long data)
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index c78a5f4fbe74..9c9d000c94db 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -989,8 +989,6 @@ void diagfwd_channel_read(struct diagfwd_info *fwd_info)
}
if (fwd_info->buf_1 && !atomic_read(&fwd_info->buf_1->in_busy)) {
- temp_buf = fwd_info->buf_1;
- atomic_set(&temp_buf->in_busy, 1);
if (driver->feature[fwd_info->peripheral].encode_hdlc &&
(fwd_info->type == TYPE_DATA ||
fwd_info->type == TYPE_CMD)) {
@@ -1000,9 +998,11 @@ void diagfwd_channel_read(struct diagfwd_info *fwd_info)
read_buf = fwd_info->buf_1->data;
read_len = fwd_info->buf_1->len;
}
+ if (read_buf) {
+ temp_buf = fwd_info->buf_1;
+ atomic_set(&temp_buf->in_busy, 1);
+ }
} else if (fwd_info->buf_2 && !atomic_read(&fwd_info->buf_2->in_busy)) {
- temp_buf = fwd_info->buf_2;
- atomic_set(&temp_buf->in_busy, 1);
if (driver->feature[fwd_info->peripheral].encode_hdlc &&
(fwd_info->type == TYPE_DATA ||
fwd_info->type == TYPE_CMD)) {
@@ -1012,6 +1012,10 @@ void diagfwd_channel_read(struct diagfwd_info *fwd_info)
read_buf = fwd_info->buf_2->data;
read_len = fwd_info->buf_2->len;
}
+ if (read_buf) {
+ temp_buf = fwd_info->buf_2;
+ atomic_set(&temp_buf->in_busy, 1);
+ }
} else {
pr_debug("diag: In %s, both buffers are empty for p: %d, t: %d\n",
__func__, fwd_info->peripheral, fwd_info->type);
diff --git a/drivers/char/diag/diagfwd_smd.c b/drivers/char/diag/diagfwd_smd.c
index 12069df1224d..f0698f0814d6 100644
--- a/drivers/char/diag/diagfwd_smd.c
+++ b/drivers/char/diag/diagfwd_smd.c
@@ -765,14 +765,13 @@ static int diag_smd_read(void *ctxt, unsigned char *buf, int buf_len)
}
/*
- * In this case don't reset the buffers as there is no need to further
- * read over peripherals. Also release the wake source hold earlier.
+ * Reset the buffers. Also release the wake source hold earlier.
*/
if (atomic_read(&smd_info->diag_state) == 0) {
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"%s closing read thread. diag state is closed\n",
smd_info->name);
- diag_ws_release();
+ diagfwd_channel_read_done(smd_info->fwd_ctxt, buf, 0);
return 0;
}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 25ab30063072..c1865f9ee8b3 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -825,6 +825,9 @@ static void clk_core_unprepare(struct clk_core *core)
if (WARN_ON(core->prepare_count == 0))
return;
+ if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL))
+ return;
+
if (--core->prepare_count > 0)
return;
@@ -940,6 +943,9 @@ static void clk_core_disable(struct clk_core *core)
if (WARN_ON(core->enable_count == 0))
return;
+ if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL))
+ return;
+
if (--core->enable_count > 0)
return;
@@ -3121,6 +3127,16 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
if (core->ops->init)
core->ops->init(core->hw);
+ if (core->flags & CLK_IS_CRITICAL) {
+ unsigned long flags;
+
+ clk_core_prepare(core);
+
+ flags = clk_enable_lock();
+ clk_core_enable(core);
+ clk_enable_unlock(flags);
+ }
+
kref_init(&core->ref);
out:
clk_prepare_unlock();
@@ -3853,6 +3869,41 @@ static int parent_ready(struct device_node *np)
}
/**
+ * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
+ * @np: Device node pointer associated with clock provider
+ * @index: clock index
+ * @flags: pointer to clk_core->flags
+ *
+ * Detects if the clock-critical property exists and, if so, sets the
+ * corresponding CLK_IS_CRITICAL flag.
+ *
+ * Do not use this function. It exists only for legacy Device Tree
+ * bindings, such as the one-clock-per-node style that are outdated.
+ * Those bindings typically put all clock data into .dts and the Linux
+ * driver has no clock data, thus making it impossible to set this flag
+ * correctly from the driver. Only those drivers may call
+ * of_clk_detect_critical from their setup functions.
+ *
+ * Return: error code or zero on success
+ */
+int of_clk_detect_critical(struct device_node *np,
+ int index, unsigned long *flags)
+{
+ struct property *prop;
+ const __be32 *cur;
+ uint32_t idx;
+
+ if (!np || !flags)
+ return -EINVAL;
+
+ of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
+ if (index == idx)
+ *flags |= CLK_IS_CRITICAL;
+
+ return 0;
+}
+
+/**
* of_clk_init() - Scan and init clock providers from the DT
* @matches: array of compatible values and init functions for providers.
*
diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c
index b9e977088126..9ce6a1430250 100644
--- a/drivers/clk/msm/clock-osm.c
+++ b/drivers/clk/msm/clock-osm.c
@@ -85,7 +85,9 @@ enum clk_osm_trace_packet_id {
#define OSM_TABLE_SIZE 40
#define MAX_CLUSTER_CNT 2
-#define MAX_CONFIG 4
+#define CORE_COUNT_VAL(val) ((val & GENMASK(18, 16)) >> 16)
+#define SINGLE_CORE 1
+#define MAX_CORE_COUNT 4
#define LLM_SW_OVERRIDE_CNT 3
#define ENABLE_REG 0x1004
@@ -357,6 +359,8 @@ struct clk_osm {
u32 irq;
u32 apm_crossover_vc;
u32 apm_threshold_vc;
+ u32 mem_acc_crossover_vc;
+ u32 mem_acc_threshold_vc;
u32 cycle_counter_reads;
u32 cycle_counter_delay;
u32 cycle_counter_factor;
@@ -642,11 +646,25 @@ static long clk_osm_round_rate(struct clk *c, unsigned long rate)
static int clk_osm_search_table(struct osm_entry *table, int entries, long rate)
{
- int i;
+ int quad_core_index, single_core_index = 0;
+ int core_count;
+
+ for (quad_core_index = 0; quad_core_index < entries;
+ quad_core_index++) {
+ core_count =
+ CORE_COUNT_VAL(table[quad_core_index].freq_data);
+ if (rate == table[quad_core_index].frequency &&
+ core_count == SINGLE_CORE) {
+ single_core_index = quad_core_index;
+ continue;
+ }
+ if (rate == table[quad_core_index].frequency &&
+ core_count == MAX_CORE_COUNT)
+ return quad_core_index;
+ }
+ if (single_core_index)
+ return single_core_index;
- for (i = 0; i < entries; i++)
- if (rate == table[i].frequency)
- return i;
return -EINVAL;
}
@@ -829,6 +847,8 @@ static void clk_osm_print_osm_table(struct clk_osm *c)
}
pr_debug("APM threshold corner=%d, crossover corner=%d\n",
c->apm_threshold_vc, c->apm_crossover_vc);
+ pr_debug("MEM-ACC threshold corner=%d, crossover corner=%d\n",
+ c->mem_acc_threshold_vc, c->mem_acc_crossover_vc);
}
static int clk_osm_get_lut(struct platform_device *pdev,
@@ -839,8 +859,10 @@ static int clk_osm_get_lut(struct platform_device *pdev,
int prop_len, total_elems, num_rows, i, j, k;
int rc = 0;
u32 *array;
+ u32 *fmax_temp;
u32 data;
bool last_entry = false;
+ unsigned long abs_fmax = 0;
if (!of_find_property(of, prop_name, &prop_len)) {
dev_err(&pdev->dev, "missing %s\n", prop_name);
@@ -855,9 +877,9 @@ static int clk_osm_get_lut(struct platform_device *pdev,
num_rows = total_elems / NUM_FIELDS;
- clk->fmax = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long),
- GFP_KERNEL);
- if (!clk->fmax)
+ fmax_temp = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!fmax_temp)
return -ENOMEM;
array = devm_kzalloc(&pdev->dev, prop_len, GFP_KERNEL);
@@ -893,18 +915,33 @@ static int clk_osm_get_lut(struct platform_device *pdev,
c->osm_table[j].spare_data);
data = (array[i + FREQ_DATA] & GENMASK(18, 16)) >> 16;
- if (!last_entry) {
- clk->fmax[k] = array[i];
+ if (!last_entry && data == MAX_CORE_COUNT) {
+ fmax_temp[k] = array[i];
k++;
}
if (i < total_elems - NUM_FIELDS)
i += NUM_FIELDS;
- else
+ else {
+ abs_fmax = array[i];
last_entry = true;
+ }
+ }
+
+ fmax_temp[k++] = abs_fmax;
+ clk->fmax = devm_kzalloc(&pdev->dev, k * sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!clk->fmax) {
+ rc = -ENOMEM;
+ goto exit;
}
+
+ for (i = 0; i < k; i++)
+ clk->fmax[i] = fmax_temp[i];
+
clk->num_fmax = k;
exit:
+ devm_kfree(&pdev->dev, fmax_temp);
devm_kfree(&pdev->dev, array);
return rc;
}
@@ -1490,20 +1527,27 @@ static int clk_osm_resolve_open_loop_voltages(struct clk_osm *c)
}
static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
- struct platform_device *pdev)
+ struct platform_device *pdev,
+ const char *mem_acc_prop)
{
struct regulator *regulator = c->vdd_reg;
- int count, vc, i, threshold, rc = 0;
+ int count, vc, i, apm_threshold;
+ int mem_acc_threshold = 0;
+ int rc = 0;
u32 corner_volt;
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,apm-threshold-voltage",
- &threshold);
+ &apm_threshold);
if (rc) {
pr_info("qcom,apm-threshold-voltage property not specified\n");
return rc;
}
+ if (mem_acc_prop)
+ of_property_read_u32(pdev->dev.of_node, mem_acc_prop,
+ &mem_acc_threshold);
+
/* Determine crossover virtual corner */
count = regulator_count_voltages(regulator);
if (count < 0) {
@@ -1511,19 +1555,49 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
return count;
}
- c->apm_crossover_vc = count - 1;
+ /*
+ * CPRh corners (in hardware) are ordered:
+ * 0 - n-1 - for n functional corners
+ * APM crossover - required for OSM
+ * [MEM ACC crossover] - optional
+ *
+ * 'count' corresponds to the total number of corners including n
+ * functional corners, the APM crossover corner, and potentially the
+ * MEM ACC cross over corner.
+ */
+ if (mem_acc_threshold) {
+ c->apm_crossover_vc = count - 2;
+ c->mem_acc_crossover_vc = count - 1;
+ } else {
+ c->apm_crossover_vc = count - 1;
+ }
- /* Determine threshold virtual corner */
+ /* Determine APM threshold virtual corner */
for (i = 0; i < OSM_TABLE_SIZE; i++) {
vc = c->osm_table[i].virtual_corner + 1;
corner_volt = regulator_list_corner_voltage(regulator, vc);
- if (corner_volt >= threshold) {
+ if (corner_volt >= apm_threshold) {
c->apm_threshold_vc = c->osm_table[i].virtual_corner;
break;
}
}
+ /* Determine MEM ACC threshold virtual corner */
+ if (mem_acc_threshold) {
+ for (i = 0; i < OSM_TABLE_SIZE; i++) {
+ vc = c->osm_table[i].virtual_corner + 1;
+ corner_volt
+ = regulator_list_corner_voltage(regulator, vc);
+
+ if (corner_volt >= mem_acc_threshold) {
+ c->mem_acc_threshold_vc
+ = c->osm_table[i].virtual_corner;
+ break;
+ }
+ }
+ }
+
return 0;
}
@@ -1822,6 +1896,7 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
{
int i, curr_level, j = 0;
int mem_acc_level_map[MAX_MEM_ACC_LEVELS] = {0, 0, 0};
+ int threshold_vc[4];
curr_level = c->osm_table[0].spare_data;
for (i = 0; i < c->num_entries; i++) {
@@ -1829,7 +1904,8 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
break;
if (c->osm_table[i].spare_data != curr_level) {
- mem_acc_level_map[j++] = i - 1;
+ mem_acc_level_map[j++]
+ = c->osm_table[i].virtual_corner - 1;
curr_level = c->osm_table[i].spare_data;
}
}
@@ -1855,14 +1931,37 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
clk_osm_write_reg(c, c->apcs_mem_acc_cfg[i],
MEM_ACC_SEQ_REG_CFG_START(i));
} else {
+ if (c->mem_acc_crossover_vc)
+ scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(88),
+ c->mem_acc_crossover_vc);
+
+ threshold_vc[0] = mem_acc_level_map[0];
+ threshold_vc[1] = mem_acc_level_map[0] + 1;
+ threshold_vc[2] = mem_acc_level_map[1];
+ threshold_vc[3] = mem_acc_level_map[1] + 1;
+
+ /*
+ * Use dynamic MEM ACC threshold voltage based value for the
+ * highest MEM ACC threshold if it is specified instead of the
+ * fixed mapping in the LUT.
+ */
+ if (c->mem_acc_threshold_vc) {
+ threshold_vc[2] = c->mem_acc_threshold_vc - 1;
+ threshold_vc[3] = c->mem_acc_threshold_vc;
+ if (threshold_vc[1] >= threshold_vc[2])
+ threshold_vc[1] = threshold_vc[2] - 1;
+ if (threshold_vc[0] >= threshold_vc[1])
+ threshold_vc[0] = threshold_vc[1] - 1;
+ }
+
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55),
- mem_acc_level_map[0]);
+ threshold_vc[0]);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(56),
- mem_acc_level_map[0] + 1);
+ threshold_vc[1]);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(57),
- mem_acc_level_map[1]);
+ threshold_vc[2]);
scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(58),
- mem_acc_level_map[1] + 1);
+ threshold_vc[3]);
/* SEQ_REG(49) = SEQ_REG(28) init by TZ */
}
@@ -3076,13 +3175,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
return rc;
}
- rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev);
+ rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev, NULL);
if (rc)
dev_info(&pdev->dev, "No APM crossover corner programmed\n");
- rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev);
+ rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev,
+ "qcom,perfcl-apcs-mem-acc-threshold-voltage");
if (rc)
- dev_info(&pdev->dev, "No APM crossover corner programmed\n");
+ dev_info(&pdev->dev, "No MEM-ACC crossover corner programmed\n");
clk_osm_setup_cycle_counters(&pwrcl_clk);
clk_osm_setup_cycle_counters(&perfcl_clk);
diff --git a/drivers/clk/msm/clock.h b/drivers/clk/msm/clock.h
index b7aa946f1931..6d286a5d2e5b 100644
--- a/drivers/clk/msm/clock.h
+++ b/drivers/clk/msm/clock.h
@@ -41,6 +41,8 @@ extern struct list_head orphan_clk_list;
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMMON_CLK_MSM)
int clock_debug_register(struct clk *clk);
void clock_debug_print_enabled(void);
+#elif defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMMON_CLK_QCOM)
+void clock_debug_print_enabled(void);
#else
static inline int clock_debug_register(struct clk *unused)
{
diff --git a/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c b/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c
index c74162ae8148..029f779979c7 100644
--- a/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c
+++ b/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c
@@ -21,6 +21,7 @@
#include <linux/clk/msm-clk.h>
#include <linux/clk/msm-clock-generic.h>
#include <dt-bindings/clock/msm-clocks-8998.h>
+#include <linux/math64.h>
#include "mdss-pll.h"
#include "mdss-hdmi-pll.h"
@@ -29,6 +30,7 @@
#define _R(x, y) MDSS_PLL_REG_R(x, y)
/* PLL REGISTERS */
+#define FREQ_UPDATE (0x008)
#define BIAS_EN_CLKBUFLR_EN (0x034)
#define CLK_ENABLE1 (0x038)
#define SYS_CLK_CTRL (0x03C)
@@ -77,9 +79,12 @@
#define PHY_CMN_CTRL (0x68)
#define PHY_STATUS (0xB4)
+#define HDMI_VCO_MAX_FREQ 12000000000
+#define HDMI_VCO_MIN_FREQ 8000000000
#define HDMI_BIT_CLK_TO_PIX_CLK_RATIO 10
#define HDMI_MHZ_TO_HZ 1000000
#define HDMI_HZ_TO_MHZ 1000000
+#define HDMI_KHZ_TO_HZ 1000
#define HDMI_REF_CLOCK_MHZ 19.2
#define HDMI_REF_CLOCK_HZ (HDMI_REF_CLOCK_MHZ * 1000000)
#define HDMI_VCO_MIN_RATE_HZ 25000000
@@ -109,7 +114,7 @@ struct hdmi_8998_reg_cfg {
u32 core_clk_en;
u32 coreclk_div_mode0;
u32 phy_mode;
- u32 vco_freq;
+ u64 vco_freq;
u32 hsclk_divsel;
u32 vco_ratio;
u32 ssc_en_center;
@@ -142,17 +147,19 @@ static void hdmi_8998_get_div(struct hdmi_8998_reg_cfg *cfg, unsigned long pclk)
u32 const band_list[] = {0, 1, 2, 3};
u32 const sz_ratio = ARRAY_SIZE(ratio_list);
u32 const sz_band = ARRAY_SIZE(band_list);
- u32 const min_freq = 8000, max_freq = 12000;
u32 const cmp_cnt = 1024;
u32 const th_min = 500, th_max = 1000;
- u64 bit_clk = ((u64)pclk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
u32 half_rate_mode = 0;
- u32 freq_optimal, list_elements;
+ u32 list_elements;
int optimal_index;
u32 i, j, k;
- u32 freq_list[sz_ratio * sz_band];
u32 found_hsclk_divsel = 0, found_vco_ratio;
- u32 found_tx_band_sel, found_vco_freq;
+ u32 found_tx_band_sel;
+ u64 const min_freq = HDMI_VCO_MIN_FREQ, max_freq = HDMI_VCO_MAX_FREQ;
+ u64 const bit_clk = ((u64)pclk) * HDMI_BIT_CLK_TO_PIX_CLK_RATIO;
+ u64 freq_list[sz_ratio * sz_band];
+ u64 found_vco_freq;
+ u64 freq_optimal;
find_optimal_index:
freq_optimal = max_freq;
@@ -164,7 +171,6 @@ find_optimal_index:
u64 freq = div_u64(bit_clk, (1 << half_rate_mode));
freq *= (ratio_list[i] * (1 << band_list[j]));
- do_div(freq, (u64) HDMI_MHZ_TO_HZ);
freq_list[list_elements++] = freq;
}
}
@@ -172,23 +178,23 @@ find_optimal_index:
for (k = 0; k < ARRAY_SIZE(freq_list); k++) {
u32 const clks_pll_div = 2, core_clk_div = 5;
u32 const rng1 = 16, rng2 = 8;
- u32 core_clk, rvar1;
u32 th1, th2;
+ u64 core_clk, rvar1, rem;
core_clk = (((freq_list[k] /
ratio_list[k / sz_band]) /
clks_pll_div) / core_clk_div);
- rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt;
- rvar1 *= rng1;
- rvar1 /= core_clk;
-
+ rvar1 = HDMI_REF_CLOCK_HZ * rng1 * HDMI_MHZ_TO_HZ;
+ rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+ if (rem > ((cmp_cnt * core_clk) >> 1))
+ rvar1++;
th1 = rvar1;
- rvar1 = HDMI_REF_CLOCK_HZ / cmp_cnt;
- rvar1 *= rng2;
- rvar1 /= core_clk;
-
+ rvar1 = HDMI_REF_CLOCK_HZ * rng2 * HDMI_MHZ_TO_HZ;
+ rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+ if (rem > ((cmp_cnt * core_clk) >> 1))
+ rvar1++;
th2 = rvar1;
if (freq_list[k] >= min_freq &&
@@ -257,7 +263,7 @@ find_optimal_index:
break;
};
- pr_debug("found_vco_freq=%d\n", found_vco_freq);
+ pr_debug("found_vco_freq=%llu\n", found_vco_freq);
pr_debug("found_hsclk_divsel=%d\n", found_hsclk_divsel);
pr_debug("found_vco_ratio=%d\n", found_vco_ratio);
pr_debug("found_tx_band_sel=%d\n", found_tx_band_sel);
@@ -278,9 +284,9 @@ static int hdmi_8998_config_phy(unsigned long rate,
u64 const mid_freq_bit_clk_threshold = 750000000;
int rc = 0;
u64 fdata, tmds_clk;
- u64 pll_div = 4 * HDMI_REF_CLOCK_HZ;
+ u32 pll_div = 4 * HDMI_REF_CLOCK_HZ;
u64 bclk;
- u64 vco_freq_mhz;
+ u64 vco_freq;
u64 hsclk_sel, dec_start, div_frac_start;
u64 rem;
u64 cpctrl, rctrl, cctrl;
@@ -302,15 +308,15 @@ static int hdmi_8998_config_phy(unsigned long rate,
hdmi_8998_get_div(cfg, rate);
- vco_freq_mhz = cfg->vco_freq * (u64) HDMI_HZ_TO_MHZ;
+ vco_freq = cfg->vco_freq;
fdata = cfg->vco_freq;
do_div(fdata, cfg->vco_ratio);
hsclk_sel = cfg->hsclk_divsel;
- dec_start = vco_freq_mhz;
+ dec_start = vco_freq;
do_div(dec_start, pll_div);
- div_frac_start = vco_freq_mhz * (1 << 20);
+ div_frac_start = vco_freq * (1 << 20);
rem = do_div(div_frac_start, pll_div);
div_frac_start -= (dec_start * (1 << 20));
if (rem > (pll_div >> 1))
@@ -330,19 +336,19 @@ static int hdmi_8998_config_phy(unsigned long rate,
integloop_gain = ((div_frac_start != 0) ||
(gen_ssc == true)) ? 0x3F : 0xC4;
- integloop_gain <<= digclk_divsel;
+ integloop_gain <<= (digclk_divsel == 2 ? 1 : 0);
integloop_gain = (integloop_gain <= 2046 ? integloop_gain : 0x7FE);
cmp_rng = gen_ssc ? 0x40 : 0x10;
pll_cmp = cmp_cnt * fdata;
- rem = do_div(pll_cmp, (u64)(HDMI_REF_CLOCK_MHZ * 10));
- if (rem > ((u64)(HDMI_REF_CLOCK_MHZ * 10) >> 1))
+ rem = do_div(pll_cmp, (u32)(HDMI_REF_CLOCK_HZ * 10));
+ if (rem > ((u64)(HDMI_REF_CLOCK_HZ * 10) >> 1))
pll_cmp++;
pll_cmp = pll_cmp - 1;
- pr_debug("VCO_FREQ = %u\n", cfg->vco_freq);
+ pr_debug("VCO_FREQ = %llu\n", cfg->vco_freq);
pr_debug("FDATA = %llu\n", fdata);
pr_debug("DEC_START = %llu\n", dec_start);
pr_debug("DIV_FRAC_START = %llu\n", div_frac_start);
@@ -609,49 +615,6 @@ static int hdmi_8998_phy_ready_status(struct mdss_pll_resources *io)
return rc;
}
-static int hdmi_8998_vco_set_rate(struct clk *c, unsigned long rate)
-{
- int rc = 0;
- struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
- struct mdss_pll_resources *io = vco->priv;
-
- rc = mdss_pll_resource_enable(io, true);
- if (rc) {
- pr_err("pll resource enable failed, rc=%d\n", rc);
- return rc;
- }
-
- if (io->pll_on)
- goto error;
-
- rc = hdmi_8998_pll_set_clk_rate(c, rate);
- if (rc) {
- pr_err("failed to set clk rate, rc=%d\n", rc);
- goto error;
- }
-
- vco->rate = rate;
- vco->rate_set = true;
-
-error:
- (void)mdss_pll_resource_enable(io, false);
-
- return rc;
-}
-
-static long hdmi_8998_vco_round_rate(struct clk *c, unsigned long rate)
-{
- unsigned long rrate = rate;
- struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
-
- if (rate < vco->min_rate)
- rrate = vco->min_rate;
- if (rate > vco->max_rate)
- rrate = vco->max_rate;
-
- return rrate;
-}
-
static int hdmi_8998_pll_enable(struct clk *c)
{
int rc = 0;
@@ -700,6 +663,151 @@ static int hdmi_8998_pll_enable(struct clk *c)
return rc;
}
+/*
+ * Get the clock range allowed in atomic update. If clock rate
+ * goes beyond this range, a full tear down is required to set
+ * the new pixel clock.
+ */
+static int hdmi_8998_vco_get_lock_range(struct clk *c,
+ unsigned long pixel_clk)
+{
+ const u32 rng = 64, cmp_cnt = 1024;
+ const u32 coreclk_div = 5, clks_pll_divsel = 2;
+ u32 vco_freq, vco_ratio, ppm_range;
+ struct hdmi_8998_reg_cfg cfg = {0};
+
+ pr_debug("rate=%ld\n", pixel_clk);
+
+ hdmi_8998_get_div(&cfg, pixel_clk);
+ if (cfg.vco_ratio <= 0 || cfg.vco_freq <= 0) {
+ pr_err("couldn't get post div\n");
+ return -EINVAL;
+ }
+
+ do_div(cfg.vco_freq, HDMI_KHZ_TO_HZ * HDMI_KHZ_TO_HZ);
+
+ vco_freq = (u32) cfg.vco_freq;
+ vco_ratio = (u32) cfg.vco_ratio;
+
+ pr_debug("freq %d, ratio %d\n", vco_freq, vco_ratio);
+
+ ppm_range = (rng * HDMI_REF_CLOCK_HZ) / cmp_cnt;
+ ppm_range /= vco_freq / vco_ratio;
+ ppm_range *= coreclk_div * clks_pll_divsel;
+
+ pr_debug("ppm range: %d\n", ppm_range);
+
+ return ppm_range;
+}
+
+static int hdmi_8998_vco_rate_atomic_update(struct clk *c,
+ unsigned long rate)
+{
+ struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+ struct mdss_pll_resources *io = vco->priv;
+ void __iomem *pll;
+ struct hdmi_8998_reg_cfg cfg = {0};
+ int rc = 0;
+
+ rc = hdmi_8998_config_phy(rate, &cfg);
+ if (rc) {
+ pr_err("rate calculation failed\n, rc=%d", rc);
+ goto end;
+ }
+
+ pll = io->pll_base;
+
+ _W(pll, DEC_START_MODE0, cfg.dec_start_mode0);
+ _W(pll, DIV_FRAC_START1_MODE0, cfg.div_frac_start1_mode0);
+ _W(pll, DIV_FRAC_START2_MODE0, cfg.div_frac_start2_mode0);
+ _W(pll, DIV_FRAC_START3_MODE0, cfg.div_frac_start3_mode0);
+
+ _W(pll, FREQ_UPDATE, 0x01);
+ _W(pll, FREQ_UPDATE, 0x00);
+
+ pr_debug("updated to rate %ld\n", rate);
+end:
+ return rc;
+}
+
+static int hdmi_8998_vco_set_rate(struct clk *c, unsigned long rate)
+{
+ struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+ struct mdss_pll_resources *io = vco->priv;
+ unsigned int set_power_dwn = 0;
+ bool atomic_update = false;
+ int pll_lock_range = 0;
+ int rc = 0;
+
+ rc = mdss_pll_resource_enable(io, true);
+ if (rc) {
+ pr_err("pll resource enable failed, rc=%d\n", rc);
+ return rc;
+ }
+
+ pr_debug("rate %ld, vco_rate %ld\n", rate, vco->rate);
+
+ if (_R(io->pll_base, C_READY_STATUS) & BIT(0) &&
+ _R(io->phy_base, PHY_STATUS) & BIT(0)) {
+ pll_lock_range = hdmi_8998_vco_get_lock_range(c, vco->rate);
+
+ if (pll_lock_range > 0 && vco->rate) {
+ u32 range_limit;
+
+ range_limit = pll_lock_range *
+ (vco->rate / HDMI_KHZ_TO_HZ);
+ range_limit /= HDMI_KHZ_TO_HZ;
+
+ pr_debug("range limit %d\n", range_limit);
+
+ if (abs(rate - vco->rate) < range_limit)
+ atomic_update = true;
+ }
+ }
+
+ if (io->pll_on && !atomic_update)
+ set_power_dwn = 1;
+
+ if (atomic_update)
+ rc = hdmi_8998_vco_rate_atomic_update(c, rate);
+ else
+ rc = hdmi_8998_pll_set_clk_rate(c, rate);
+
+ if (rc) {
+ pr_err("failed to set clk rate\n");
+ goto error;
+ }
+
+ if (set_power_dwn) {
+ rc = hdmi_8998_pll_enable(c);
+ if (rc) {
+ pr_err("failed to enable pll, rc=%d\n", rc);
+ goto error;
+ }
+ }
+
+ vco->rate = rate;
+ vco->rate_set = true;
+
+error:
+ (void)mdss_pll_resource_enable(io, false);
+
+ return rc;
+}
+
+static long hdmi_8998_vco_round_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long rrate = rate;
+ struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+
+ if (rate < vco->min_rate)
+ rrate = vco->min_rate;
+ if (rate > vco->max_rate)
+ rrate = vco->max_rate;
+
+ return rrate;
+}
+
static int hdmi_8998_vco_prepare(struct clk *c)
{
struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c
index eb5e3fc127e0..0276952debbb 100644
--- a/drivers/devfreq/governor_msm_adreno_tz.c
+++ b/drivers/devfreq/governor_msm_adreno_tz.c
@@ -92,14 +92,15 @@ static ssize_t gpu_load_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- unsigned long sysfs_busy_perc;
+ unsigned long sysfs_busy_perc = 0;
/*
* Average out the samples taken since last read
* This will keep the average value in sync with
* with the client sampling duration.
*/
spin_lock(&sample_lock);
- sysfs_busy_perc = (acc_relative_busy * 100) / acc_total;
+ if (acc_total)
+ sysfs_busy_perc = (acc_relative_busy * 100) / acc_total;
/* Reset the parameters */
acc_total = 0;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 094a7861831a..dc2061fc4537 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -1444,7 +1444,8 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
}
if (fatal_err == true) {
- pr_err("%s: fatal error, stop ispif immediately\n", __func__);
+ pr_err_ratelimited("%s: fatal error, stop ispif immediately\n",
+ __func__);
for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 0d8c6cb8f3f3..dc5a5a0dc851 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -237,7 +237,7 @@ static void sde_rotator_set_clk_rate(struct sde_rot_mgr *mgr,
clk_rate = clk_round_rate(clk, rate);
if (IS_ERR_VALUE(clk_rate)) {
SDEROT_ERR("unable to round rate err=%ld\n", clk_rate);
- } else if (clk_rate != clk_get_rate(clk)) {
+ } else {
ret = clk_set_rate(clk, clk_rate);
if (IS_ERR_VALUE(ret))
SDEROT_ERR("clk_set_rate failed, err:%d\n",
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 457629ee4bf5..4fd845ab4086 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1293,9 +1293,11 @@ static int __qseecom_set_msm_bus_request(uint32_t mode)
pr_err("Bandwidth req failed(%d) MODE (%d)\n",
ret, mode);
if (qclk->ce_core_src_clk != NULL) {
- if (mode == INACTIVE)
- __qseecom_enable_clk(CLK_QSEE);
- else
+ if (mode == INACTIVE) {
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ pr_err("CLK enable failed\n");
+ } else
__qseecom_disable_clk(CLK_QSEE);
}
}
@@ -1603,12 +1605,21 @@ static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data,
if (ptr_svc)
pr_warn("listener_id:%x, lstnr: %x\n",
ptr_svc->svc.listener_id, lstnr);
- if (ptr_svc && ptr_svc->ihandle)
- msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
+ if (ptr_svc && ptr_svc->ihandle) {
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
ION_IOC_CLEAN_INV_CACHES);
- if (lstnr == RPMB_SERVICE)
- __qseecom_enable_clk(CLK_QSEE);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
+ }
+
+ if (lstnr == RPMB_SERVICE) {
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
+ }
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, send_data_rsp,
sizeof(send_data_rsp), resp, sizeof(*resp));
if (ret) {
@@ -1764,13 +1775,22 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
else
*(uint32_t *)cmd_buf =
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;
- if (ptr_svc)
- msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
+ if (ptr_svc) {
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
+ ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
- ION_IOC_CLEAN_INV_CACHES);
+ ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
+ }
- if ((lstnr == RPMB_SERVICE) || (lstnr == SSD_SERVICE))
- __qseecom_enable_clk(CLK_QSEE);
+ if ((lstnr == RPMB_SERVICE) || (lstnr == SSD_SERVICE)) {
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
+ }
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len, resp, sizeof(*resp));
@@ -2005,13 +2025,21 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
else
*(uint32_t *)cmd_buf =
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;
- if (ptr_svc)
- msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
+ if (ptr_svc) {
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
+ ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
- ION_IOC_CLEAN_INV_CACHES);
-
- if (lstnr == RPMB_SERVICE)
- __qseecom_enable_clk(CLK_QSEE);
+ ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
+ }
+ if (lstnr == RPMB_SERVICE) {
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
+ }
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len, resp, sizeof(*resp));
@@ -2297,8 +2325,12 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
cmd_len = sizeof(struct qseecom_load_app_64bit_ireq);
}
- msm_ion_do_cache_op(qseecom.ion_clnt, ihandle, NULL, len,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto loadapp_err;
+ }
/* SCM_CALL to load the app and get the app_id back */
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf,
@@ -2776,15 +2808,16 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
}
}
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto exit;
+ }
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
(const void *)send_req_ptr,
req_buf_size, &resp, sizeof(resp));
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
- data->client.sb_virt, data->client.sb_length,
- ION_IOC_INV_CACHES);
if (ret) {
pr_err("qseecom_scm_call failed with err: %d\n", ret);
if (!qseecom.support_bus_scaling) {
@@ -2796,7 +2829,13 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
}
goto exit;
}
-
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ data->client.sb_virt, data->client.sb_length,
+ ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto exit;
+ }
switch (resp.result) {
case QSEOS_RESULT_SUCCESS:
break;
@@ -3029,10 +3068,14 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
else
*(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST;
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
reqd_len_sb_in,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
__qseecom_reentrancy_check_if_this_app_blocked(ptr_app);
@@ -3063,9 +3106,11 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
}
}
}
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_INV_CACHES);
+ if (ret)
+ pr_err("cache operation failed %d\n", ret);
return ret;
}
@@ -3177,7 +3222,7 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
}
/* Populate the cmd data structure with the phys_addr */
sg_ptr = ion_sg_table(qseecom.ion_clnt, ihandle);
- if (sg_ptr == NULL) {
+ if (IS_ERR_OR_NULL(sg_ptr)) {
pr_err("IOn client could not retrieve sg table\n");
goto err;
}
@@ -3285,13 +3330,21 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
}
if (cleanup) {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
} else {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
if (data->type == QSEECOM_CLIENT_APP) {
offset = req->ifd_data[i].cmd_buf_offset;
data->sglistinfo_ptr[i].indexAndFlags =
@@ -3432,7 +3485,7 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup,
}
/* Populate the cmd data structure with the phys_addr */
sg_ptr = ion_sg_table(qseecom.ion_clnt, ihandle);
- if (sg_ptr == NULL) {
+ if (IS_ERR_OR_NULL(sg_ptr)) {
pr_err("IOn client could not retrieve sg table\n");
goto err;
}
@@ -3515,13 +3568,21 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup,
}
cleanup:
if (cleanup) {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
} else {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
if (data->type == QSEECOM_CLIENT_APP) {
offset = req->ifd_data[i].cmd_buf_offset;
data->sglistinfo_ptr[i].indexAndFlags =
@@ -4010,9 +4071,13 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname)
goto exit_unregister_bus_bw_need;
}
- msm_ion_do_cache_op(qseecom.ion_clnt, ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, ihandle,
img_data, fw_size,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto exit_disable_clk_vote;
+ }
/* SCM_CALL to load the image */
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len,
@@ -4126,9 +4191,13 @@ static int qseecom_load_commonlib_image(struct qseecom_dev_handle *data,
goto exit_unregister_bus_bw_need;
}
- msm_ion_do_cache_op(qseecom.ion_clnt, qseecom.cmnlib_ion_handle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, qseecom.cmnlib_ion_handle,
img_data, fw_size,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto exit_disable_clk_vote;
+ }
/* SCM_CALL to load the image */
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len,
@@ -4694,9 +4763,10 @@ static int __qseecom_enable_clk(enum qseecom_ce_hw_instance ce)
}
mutex_lock(&clk_access_lock);
- if (qclk->clk_access_cnt == ULONG_MAX)
+ if (qclk->clk_access_cnt == ULONG_MAX) {
+ pr_err("clk_access_cnt beyond limitation\n");
goto err;
-
+ }
if (qclk->clk_access_cnt > 0) {
qclk->clk_access_cnt++;
mutex_unlock(&clk_access_lock);
@@ -5009,9 +5079,12 @@ static int qseecom_load_external_elf(struct qseecom_dev_handle *data,
ret = -EIO;
goto exit_register_bus_bandwidth_needs;
}
- msm_ion_do_cache_op(qseecom.ion_clnt, ihandle, NULL, len,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
-
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto exit_disable_clock;
+ }
/* SCM_CALL to load the external elf */
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len,
&resp, sizeof(resp));
@@ -5257,7 +5330,9 @@ static int __qseecom_generate_and_save_key(struct qseecom_dev_handle *data,
pr_err("Error:: unsupported usage %d\n", usage);
return -EFAULT;
}
- __qseecom_enable_clk(CLK_QSEE);
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
ireq, sizeof(struct qseecom_key_generate_ireq),
@@ -5315,7 +5390,9 @@ static int __qseecom_delete_saved_key(struct qseecom_dev_handle *data,
pr_err("Error:: unsupported usage %d\n", usage);
return -EFAULT;
}
- __qseecom_enable_clk(CLK_QSEE);
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
ireq, sizeof(struct qseecom_key_delete_ireq),
@@ -5374,10 +5451,15 @@ static int __qseecom_set_clear_ce_key(struct qseecom_dev_handle *data,
pr_err("Error:: unsupported usage %d\n", usage);
return -EFAULT;
}
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
- __qseecom_enable_clk(CLK_QSEE);
- if (qseecom.qsee.instance != qseecom.ce_drv.instance)
- __qseecom_enable_clk(CLK_CE_DRV);
+ if (qseecom.qsee.instance != qseecom.ce_drv.instance) {
+ ret = __qseecom_enable_clk(CLK_CE_DRV);
+ if (ret)
+ return ret;
+ }
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
ireq, sizeof(struct qseecom_key_select_ireq),
@@ -5452,8 +5534,9 @@ static int __qseecom_update_current_key_user_info(
pr_err("Error:: unsupported usage %d\n", usage);
return -EFAULT;
}
-
- __qseecom_enable_clk(CLK_QSEE);
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ return ret;
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
ireq, sizeof(struct qseecom_key_userinfo_update_ireq),
@@ -5994,7 +6077,9 @@ static int qseecom_mdtp_cipher_dip(void __user *argp)
desc.args[3] = req.out_buf_size;
desc.args[4] = req.direction;
- __qseecom_enable_clk(CLK_QSEE);
+ ret = __qseecom_enable_clk(CLK_QSEE);
+ if (ret)
+ break;
ret = scm_call2(TZ_MDTP_CIPHER_DIP_ID, &desc);
@@ -6181,7 +6266,7 @@ static int __qseecom_update_qteec_req_buf(struct qseecom_qteec_modfd_req *req,
}
/* Populate the cmd data structure with the phys_addr */
sg_ptr = ion_sg_table(qseecom.ion_clnt, ihandle);
- if (sg_ptr == NULL) {
+ if (IS_ERR_OR_NULL(sg_ptr)) {
pr_err("IOn client could not retrieve sg table\n");
goto err;
}
@@ -6237,13 +6322,21 @@ static int __qseecom_update_qteec_req_buf(struct qseecom_qteec_modfd_req *req,
}
clean:
if (cleanup) {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, sg->length,
ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
} else {
- msm_ion_do_cache_op(qseecom.ion_clnt,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, sg->length,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ goto err;
+ }
data->sglistinfo_ptr[i].indexAndFlags =
SGLISTINFO_SET_INDEX_FLAG(
(sg_ptr->nents == 1), 0,
@@ -6356,10 +6449,14 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
*(uint32_t *)cmd_buf = cmd_id;
reqd_len_sb_in = req->req_len + req->resp_len;
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
reqd_len_sb_in,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
__qseecom_reentrancy_check_if_this_app_blocked(ptr_app);
@@ -6390,9 +6487,13 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
}
}
}
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
@@ -6536,10 +6637,14 @@ static int qseecom_qteec_invoke_modfd_cmd(struct qseecom_dev_handle *data,
else
*(uint32_t *)cmd_buf = QSEOS_TEE_INVOKE_COMMAND;
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
reqd_len_sb_in,
ION_IOC_CLEAN_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
__qseecom_reentrancy_check_if_this_app_blocked(ptr_app);
@@ -6574,9 +6679,13 @@ static int qseecom_qteec_invoke_modfd_cmd(struct qseecom_dev_handle *data,
if (ret)
return ret;
- msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+ ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_INV_CACHES);
+ if (ret) {
+ pr_err("cache operation failed %d\n", ret);
+ return ret;
+ }
return 0;
}
diff --git a/drivers/net/wireless/ath/wil6210/ftm.c b/drivers/net/wireless/ath/wil6210/ftm.c
index 5cf07343a33c..6891a38d7a59 100644
--- a/drivers/net/wireless/ath/wil6210/ftm.c
+++ b/drivers/net/wireless/ath/wil6210/ftm.c
@@ -52,6 +52,7 @@ nla_policy wil_nl80211_loc_policy[QCA_WLAN_VENDOR_ATTR_LOC_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_FTM_INITIAL_TOKEN] = { .type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_AOA_TYPE] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK] = { .type = NLA_U32 },
+ [QCA_WLAN_VENDOR_ATTR_FREQ] = { .type = NLA_U32 },
};
static const struct
@@ -61,6 +62,7 @@ nla_policy wil_nl80211_ftm_peer_policy[
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS] = { .type = NLA_NESTED },
[QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ] = { .type = NLA_U32 },
};
static const struct
@@ -72,6 +74,37 @@ nla_policy wil_nl80211_ftm_meas_param_policy[
[QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD] = { .type = NLA_U16 },
};
+static u8 wil_ftm_get_channel(struct wil6210_priv *wil,
+ const u8 *mac_addr, u32 freq)
+{
+ struct wiphy *wiphy = wil_to_wiphy(wil);
+ struct cfg80211_bss *bss;
+ struct ieee80211_channel *chan;
+ u8 channel;
+
+ if (freq) {
+ chan = ieee80211_get_channel(wiphy, freq);
+ if (!chan) {
+ wil_err(wil, "invalid freq: %d\n", freq);
+ return 0;
+ }
+ channel = chan->hw_value;
+ } else {
+ bss = cfg80211_get_bss(wiphy, NULL, mac_addr,
+ NULL, 0, IEEE80211_BSS_TYPE_ANY,
+ IEEE80211_PRIVACY_ANY);
+ if (!bss) {
+ wil_err(wil, "Unable to find BSS\n");
+ return 0;
+ }
+ channel = bss->channel->hw_value;
+ cfg80211_put_bss(wiphy, bss);
+ }
+
+ wil_dbg_misc(wil, "target %pM at channel %d\n", mac_addr, channel);
+ return channel;
+}
+
static int wil_ftm_parse_meas_params(struct wil6210_priv *wil,
struct nlattr *attr,
struct wil_ftm_meas_params *params)
@@ -273,7 +306,7 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
{
int rc = 0;
bool has_lci = false, has_lcr = false;
- u8 max_meas = 0, *ptr;
+ u8 max_meas = 0, channel, *ptr;
u32 i, cmd_len;
struct wmi_tof_session_start_cmd *cmd;
@@ -283,12 +316,6 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
rc = -EAGAIN;
goto out;
}
- /* for now allow measurement to associated AP only */
- if (!test_bit(wil_status_fwconnected, wil->status)) {
- wil_err(wil, "must be associated\n");
- rc = -ENOTSUPP;
- goto out;
- }
for (i = 0; i < request->n_peers; i++) {
if (request->peers[i].flags &
@@ -333,7 +360,14 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
for (i = 0; i < request->n_peers; i++) {
ether_addr_copy(cmd->ftm_dest_info[i].dst_mac,
request->peers[i].mac_addr);
- cmd->ftm_dest_info[i].channel = request->peers[i].channel;
+ channel = wil_ftm_get_channel(wil, request->peers[i].mac_addr,
+ request->peers[i].freq);
+ if (!channel) {
+ wil_err(wil, "can't find FTM target at index %d\n", i);
+ rc = -EINVAL;
+ goto out_cmd;
+ }
+ cmd->ftm_dest_info[i].channel = channel - 1;
if (request->peers[i].flags &
QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE) {
cmd->ftm_dest_info[i].flags |=
@@ -367,14 +401,13 @@ wil_ftm_cfg80211_start_session(struct wil6210_priv *wil,
}
rc = wmi_send(wil, WMI_TOF_SESSION_START_CMDID, cmd, cmd_len);
- kfree(cmd);
-
- if (rc)
- goto out_ftm_res;
-
- wil->ftm.session_cookie = request->session_cookie;
- wil->ftm.session_started = 1;
+ if (!rc) {
+ wil->ftm.session_cookie = request->session_cookie;
+ wil->ftm.session_started = 1;
+ }
+out_cmd:
+ kfree(cmd);
out_ftm_res:
if (rc) {
kfree(wil->ftm.ftm_res);
@@ -444,8 +477,8 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_priv *wil,
struct wil_aoa_meas_request *request)
{
int rc = 0;
- struct cfg80211_bss *bss;
struct wmi_aoa_meas_cmd cmd;
+ u8 channel;
mutex_lock(&wil->ftm.lock);
@@ -460,30 +493,25 @@ wil_aoa_cfg80211_start_measurement(struct wil6210_priv *wil,
goto out;
}
- bss = cfg80211_get_bss(wil_to_wiphy(wil), NULL, request->mac_addr,
- NULL, 0,
- IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
- if (!bss) {
- wil_err(wil, "Unable to find BSS\n");
- rc = -ENOENT;
+ channel = wil_ftm_get_channel(wil, request->mac_addr, request->freq);
+ if (!channel) {
+ rc = -EINVAL;
goto out;
}
memset(&cmd, 0, sizeof(cmd));
ether_addr_copy(cmd.mac_addr, request->mac_addr);
- cmd.channel = bss->channel->hw_value - 1;
+ cmd.channel = channel - 1;
cmd.aoa_meas_type = request->type;
rc = wmi_send(wil, WMI_AOA_MEAS_CMDID, &cmd, sizeof(cmd));
if (rc)
- goto out_bss;
+ goto out;
ether_addr_copy(wil->ftm.aoa_peer_mac_addr, request->mac_addr);
mod_timer(&wil->ftm.aoa_timer,
jiffies + msecs_to_jiffies(WIL_AOA_MEASUREMENT_TIMEOUT));
wil->ftm.aoa_started = 1;
-out_bss:
- cfg80211_put_bss(wil_to_wiphy(wil), bss);
out:
mutex_unlock(&wil->ftm.lock);
return rc;
@@ -721,7 +749,6 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev,
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX + 1];
struct nlattr *peer;
int rc, n_peers = 0, index = 0, tmp;
- struct cfg80211_bss *bss;
if (!test_bit(WMI_FW_CAPABILITY_FTM, wil->fw_capabilities))
return -ENOTSUPP;
@@ -785,17 +812,9 @@ int wil_ftm_start_session(struct wiphy *wiphy, struct wireless_dev *wdev,
memcpy(request->peers[index].mac_addr,
nla_data(tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR]),
ETH_ALEN);
- bss = cfg80211_get_bss(wiphy, NULL,
- request->peers[index].mac_addr, NULL, 0,
- IEEE80211_BSS_TYPE_ANY,
- IEEE80211_PRIVACY_ANY);
- if (!bss) {
- wil_err(wil, "invalid bss at index %d\n", index);
- rc = -ENOENT;
- goto out;
- }
- request->peers[index].channel = bss->channel->hw_value - 1;
- cfg80211_put_bss(wiphy, bss);
+ if (tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ])
+ request->peers[index].freq = nla_get_u32(
+ tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ]);
if (tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS])
request->peers[index].flags = nla_get_u32(
tb2[QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS]);
@@ -868,6 +887,8 @@ int wil_aoa_start_measurement(struct wiphy *wiphy, struct wireless_dev *wdev,
ether_addr_copy(request.mac_addr,
nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]));
request.type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_AOA_TYPE]);
+ if (tb[QCA_WLAN_VENDOR_ATTR_FREQ])
+ request.freq = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_FREQ]);
rc = wil_aoa_cfg80211_start_measurement(wil, &request);
return rc;
diff --git a/drivers/net/wireless/ath/wil6210/ftm.h b/drivers/net/wireless/ath/wil6210/ftm.h
index 9721344579aa..ea186d641d59 100644
--- a/drivers/net/wireless/ath/wil6210/ftm.h
+++ b/drivers/net/wireless/ath/wil6210/ftm.h
@@ -77,6 +77,8 @@
* %QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16
* values, phase and amplitude of the strongest CIR path for each
* antenna in the measured array(s)
+ * @QCA_WLAN_VENDOR_ATTR_FREQ: Frequency where peer is listening, in MHz.
+ * Unsigned 32 bit value.
*/
enum qca_wlan_vendor_attr_loc {
/* we reuse these attributes */
@@ -94,6 +96,7 @@ enum qca_wlan_vendor_attr_loc {
QCA_WLAN_VENDOR_ATTR_AOA_TYPE = 23,
QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK = 24,
QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT = 25,
+ QCA_WLAN_VENDOR_ATTR_FREQ = 26,
/* keep last */
QCA_WLAN_VENDOR_ATTR_LOC_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_LOC_MAX = QCA_WLAN_VENDOR_ATTR_LOC_AFTER_LAST - 1,
@@ -176,6 +179,9 @@ enum qca_wlan_vendor_attr_loc_capa_flags {
* @QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA
* measurement every _value_ bursts. If 0 or not specified,
* AOA measurements will be disabled for this peer.
+ * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ: Frequency in MHz where
+ * peer is listening. Optional; if not specified, use the
+ * entry from the kernel scan results cache.
*/
enum qca_wlan_vendor_attr_ftm_peer_info {
QCA_WLAN_VENDOR_ATTR_FTM_PEER_INVALID,
@@ -184,6 +190,7 @@ enum qca_wlan_vendor_attr_ftm_peer_info {
QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD,
+ QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ,
/* keep last */
QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX =
@@ -426,7 +433,7 @@ struct wil_ftm_meas_params {
/* measurement request for a single peer */
struct wil_ftm_meas_peer_info {
u8 mac_addr[ETH_ALEN];
- u8 channel;
+ u32 freq;
u32 flags; /* enum qca_wlan_vendor_attr_ftm_peer_meas_flags */
struct wil_ftm_meas_params params;
u8 secure_token_id;
@@ -465,6 +472,7 @@ struct wil_ftm_peer_meas_res {
/* standalone AOA measurement request */
struct wil_aoa_meas_request {
u8 mac_addr[ETH_ALEN];
+ u32 freq;
u32 type;
};
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8998.c b/drivers/pinctrl/qcom/pinctrl-msm8998.c
index e983bcc8e47d..c4882f244d3f 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm8998.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm8998.c
@@ -92,6 +92,31 @@
.intr_detection_bit = -1, \
.intr_detection_width = -1, \
}
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = (unsigned)ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x4, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
static const struct pinctrl_pin_desc msm8998_pins[] = {
PINCTRL_PIN(0, "GPIO_0"),
PINCTRL_PIN(1, "GPIO_1"),
@@ -246,6 +271,7 @@ static const struct pinctrl_pin_desc msm8998_pins[] = {
PINCTRL_PIN(150, "SDC2_CLK"),
PINCTRL_PIN(151, "SDC2_CMD"),
PINCTRL_PIN(152, "SDC2_DATA"),
+ PINCTRL_PIN(153, "UFS_RESET"),
};
#define DECLARE_MSM_GPIO_PINS(pin) \
@@ -404,6 +430,7 @@ DECLARE_MSM_GPIO_PINS(149);
static const unsigned int sdc2_clk_pins[] = { 150 };
static const unsigned int sdc2_cmd_pins[] = { 151 };
static const unsigned int sdc2_data_pins[] = { 152 };
+static const unsigned int ufs_reset_pins[] = { 153 };
enum msm8998_functions {
msm_mux_blsp_spi1,
@@ -1856,6 +1883,7 @@ static const struct msm_pingroup msm8998_groups[] = {
SDC_QDSD_PINGROUP(sdc2_clk, 0x999000, 14, 6),
SDC_QDSD_PINGROUP(sdc2_cmd, 0x999000, 11, 3),
SDC_QDSD_PINGROUP(sdc2_data, 0x999000, 9, 0),
+ UFS_RESET(ufs_reset, 0x19d000),
};
static const struct msm_pinctrl_soc_data msm8998_pinctrl = {
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index 039ffcc24c23..f7a54f71a28a 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -1172,12 +1172,14 @@ static int smb2_init_hw(struct smb2 *chip)
return rc;
}
- /* disable Type-C factory mode */
+ /*
+ * disable Type-C factory mode and stay in Attached.SRC state when VCONN
+ * over-current happens
+ */
rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
- FACTORY_MODE_DETECTION_EN_BIT, 0);
+ FACTORY_MODE_DETECTION_EN_BIT | VCONN_OC_CFG_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't disable Type-C factory mode rc=%d\n", rc);
+ dev_err(chg->dev, "Couldn't configure Type-C rc=%d\n", rc);
return rc;
}
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 52805357ef92..0faf8aee8aa0 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -2865,39 +2865,39 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
struct smb_irq_data *irq_data = data;
struct smb_charger *chg = irq_data->parent_data;
int rc;
- u8 stat;
+ u8 stat4, stat5;
bool debounce_done, sink_attached, legacy_cable;
/* WA - not when PD hard_reset WIP on cc2 in sink mode */
if (chg->cc2_sink_detach_flag == CC2_SINK_STD)
return IRQ_HANDLED;
- rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat4);
if (rc < 0) {
smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
return IRQ_HANDLED;
}
- smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat);
- debounce_done = (bool)(stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
- sink_attached = (bool)(stat & UFP_DFP_MODE_STATUS_BIT);
- rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat);
+ rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat5);
if (rc < 0) {
smblib_err(chg, "Couldn't read TYPE_C_STATUS_5 rc=%d\n", rc);
return IRQ_HANDLED;
}
- smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_5 = 0x%02x\n", stat);
- legacy_cable = (bool)(stat & TYPEC_LEGACY_CABLE_STATUS_BIT);
+
+ debounce_done = (bool)(stat4 & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
+ sink_attached = (bool)(stat4 & UFP_DFP_MODE_STATUS_BIT);
+ legacy_cable = (bool)(stat5 & TYPEC_LEGACY_CABLE_STATUS_BIT);
smblib_handle_typec_debounce_done(chg,
debounce_done, sink_attached, legacy_cable);
- power_supply_changed(chg->usb_psy);
-
- if (stat & TYPEC_VBUS_ERROR_STATUS_BIT)
+ if (stat4 & TYPEC_VBUS_ERROR_STATUS_BIT)
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s vbus-error\n",
irq_data->name);
+ power_supply_changed(chg->usb_psy);
+ smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat4);
+ smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_5 = 0x%02x\n", stat5);
return IRQ_HANDLED;
}
diff --git a/drivers/regulator/cpr3-regulator.h b/drivers/regulator/cpr3-regulator.h
index ac571271b0d5..3c652ca8d489 100644
--- a/drivers/regulator/cpr3-regulator.h
+++ b/drivers/regulator/cpr3-regulator.h
@@ -565,6 +565,11 @@ struct cpr3_panic_regs_info {
* @mem_acc_corner_map: mem-acc regulator corners mapping to low and high
* voltage mem-acc settings for the memories powered by
* this CPR3 controller and its associated CPR3 regulators
+ * @mem_acc_crossover_volt: Voltage in microvolts corresponding to the voltage
+ * that the VDD supply must be set to while a MEM ACC
+ * switch is in progress. This element must be initialized
+ * for CPRh controllers when a MEM ACC threshold voltage is
+ * defined.
* @core_clk: Pointer to the CPR3 controller core clock
* @iface_clk: Pointer to the CPR3 interface clock (platform specific)
* @bus_clk: Pointer to the CPR3 bus clock (platform specific)
@@ -744,6 +749,7 @@ struct cpr3_controller {
int system_supply_max_volt;
int mem_acc_threshold_volt;
int mem_acc_corner_map[CPR3_MEM_ACC_CORNERS];
+ int mem_acc_crossover_volt;
struct clk *core_clk;
struct clk *iface_clk;
struct clk *bus_clk;
@@ -876,6 +882,7 @@ int cpr4_parse_core_count_temp_voltage_adj(struct cpr3_regulator *vreg,
int cpr3_apm_init(struct cpr3_controller *ctrl);
int cpr3_mem_acc_init(struct cpr3_regulator *vreg);
void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg);
+void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg);
#else
@@ -1052,6 +1059,10 @@ static inline void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
{
}
+static inline void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
+{
+}
+
#endif /* CONFIG_REGULATOR_CPR3 */
#endif /* __REGULATOR_CPR_REGULATOR_H__ */
diff --git a/drivers/regulator/cpr3-util.c b/drivers/regulator/cpr3-util.c
index c377a65a6393..60fe825ca013 100644
--- a/drivers/regulator/cpr3-util.c
+++ b/drivers/regulator/cpr3-util.c
@@ -680,12 +680,13 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
}
/*
- * In CPRh compliant controllers an additional corner is
- * allocated to correspond to the APM crossover voltage
+ * For CPRh compliant controllers two additional corners are
+ * allocated to correspond to the APM crossover voltage and the MEM ACC
+ * crossover voltage.
*/
vreg->corner = devm_kcalloc(ctrl->dev, ctrl->ctrl_type ==
CPR_CTRL_TYPE_CPRH ?
- vreg->corner_count + 1 :
+ vreg->corner_count + 2 :
vreg->corner_count,
sizeof(*vreg->corner), GFP_KERNEL);
temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
@@ -2083,3 +2084,66 @@ void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
corner->ceiling_volt, corner->open_loop_volt);
}
}
+
+/**
+ * cprh_adjust_voltages_for_mem_acc() - adjust per-corner floor and ceiling
+ * voltages so that they do not intersect the MEM ACC threshold
+ * voltage
+ * @vreg: Pointer to the CPR3 regulator
+ *
+ * The following algorithm is applied:
+ * if floor < threshold <= ceiling:
+ * if open_loop >= threshold, then floor = threshold
+ * else ceiling = threshold - step
+ * where:
+ * step = voltage in microvolts of a single step of the VDD supply
+ *
+ * The open-loop voltage is also bounded by the new floor or ceiling value as
+ * needed.
+ *
+ * Return: none
+ */
+void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
+{
+ struct cpr3_controller *ctrl = vreg->thread->ctrl;
+ struct cpr3_corner *corner;
+ int i, threshold, prev_ceiling, prev_floor, prev_open_loop;
+
+ if (!ctrl->mem_acc_threshold_volt) {
+ /* MEM ACC not being used. */
+ return;
+ }
+
+ ctrl->mem_acc_threshold_volt = CPR3_ROUND(ctrl->mem_acc_threshold_volt,
+ ctrl->step_volt);
+
+ threshold = ctrl->mem_acc_threshold_volt;
+
+ for (i = 0; i < vreg->corner_count; i++) {
+ corner = &vreg->corner[i];
+
+ if (threshold <= corner->floor_volt
+ || threshold > corner->ceiling_volt)
+ continue;
+
+ prev_floor = corner->floor_volt;
+ prev_ceiling = corner->ceiling_volt;
+ prev_open_loop = corner->open_loop_volt;
+
+ if (corner->open_loop_volt >= threshold) {
+ corner->floor_volt = max(corner->floor_volt, threshold);
+ if (corner->open_loop_volt < corner->floor_volt)
+ corner->open_loop_volt = corner->floor_volt;
+ } else {
+ corner->ceiling_volt = threshold - ctrl->step_volt;
+ }
+
+ if (corner->floor_volt != prev_floor
+ || corner->ceiling_volt != prev_ceiling
+ || corner->open_loop_volt != prev_open_loop)
+ cpr3_debug(vreg, "MEM ACC threshold=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
+ threshold, i, prev_floor, prev_ceiling,
+ prev_open_loop, corner->floor_volt,
+ corner->ceiling_volt, corner->open_loop_volt);
+ }
+}
diff --git a/drivers/regulator/cprh-kbss-regulator.c b/drivers/regulator/cprh-kbss-regulator.c
index 2608cc4a430a..9cbd1ee18ec3 100644
--- a/drivers/regulator/cprh-kbss-regulator.c
+++ b/drivers/regulator/cprh-kbss-regulator.c
@@ -73,8 +73,10 @@ struct cprh_msm8998_kbss_fuses {
/*
* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 with speed bin fuse = 0.
* Fuse combos 8 - 15 map to CPR fusing revision 0 - 7 with speed bin fuse = 1.
+ * Fuse combos 16 - 23 map to CPR fusing revision 0 - 7 with speed bin fuse = 2.
+ * Fuse combos 24 - 31 map to CPR fusing revision 0 - 7 with speed bin fuse = 3.
*/
-#define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 16
+#define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32
/*
* Constants which define the name of each fuse corner.
@@ -866,6 +868,44 @@ static int cprh_kbss_apm_crossover_as_corner(struct cpr3_regulator *vreg)
}
/**
+ * cprh_kbss_mem_acc_crossover_as_corner() - introduce a corner whose floor,
+ * open-loop, and ceiling voltages correspond to the MEM ACC
+ * crossover voltage.
+ * @vreg: Pointer to the CPR3 regulator
+ *
+ * The MEM ACC corner is utilized as a crossover corner by OSM and CPRh
+ * hardware to set the VDD supply voltage during the MEM ACC switch
+ * routine.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int cprh_kbss_mem_acc_crossover_as_corner(struct cpr3_regulator *vreg)
+{
+ struct cpr3_controller *ctrl = vreg->thread->ctrl;
+ struct cpr3_corner *corner;
+
+ if (!ctrl->mem_acc_crossover_volt) {
+ /* MEM ACC voltage crossover corner not required. */
+ return 0;
+ }
+
+ corner = &vreg->corner[vreg->corner_count];
+ /*
+ * 0 MHz indicates this corner is not to be
+ * used as active DCVS set point.
+ */
+ corner->proc_freq = 0;
+ corner->floor_volt = ctrl->mem_acc_crossover_volt;
+ corner->ceiling_volt = ctrl->mem_acc_crossover_volt;
+ corner->open_loop_volt = ctrl->mem_acc_crossover_volt;
+ corner->abs_ceiling_volt = ctrl->mem_acc_crossover_volt;
+ corner->use_open_loop = true;
+ vreg->corner_count++;
+
+ return 0;
+}
+
+/**
* cprh_msm8998_kbss_set_no_interpolation_quotients() - use the fused target
* quotient values for lower frequencies.
* @vreg: Pointer to the CPR3 regulator
@@ -1196,6 +1236,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg)
}
cprh_adjust_voltages_for_apm(vreg);
+ cprh_adjust_voltages_for_mem_acc(vreg);
cpr3_open_loop_voltage_as_ceiling(vreg);
@@ -1248,6 +1289,13 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg)
return rc;
}
+ rc = cprh_kbss_mem_acc_crossover_as_corner(vreg);
+ if (rc) {
+ cpr3_err(vreg, "unable to introduce MEM ACC voltage crossover corner, rc=%d\n",
+ rc);
+ return rc;
+ }
+
cprh_kbss_print_settings(vreg);
return 0;
@@ -1420,6 +1468,25 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl)
ctrl->saw_use_unit_mV = of_property_read_bool(ctrl->dev->of_node,
"qcom,cpr-saw-use-unit-mV");
+ rc = of_property_read_u32(ctrl->dev->of_node,
+ "qcom,mem-acc-threshold-voltage",
+ &ctrl->mem_acc_threshold_volt);
+ if (!rc) {
+ ctrl->mem_acc_threshold_volt
+ = CPR3_ROUND(ctrl->mem_acc_threshold_volt, ctrl->step_volt);
+
+ rc = of_property_read_u32(ctrl->dev->of_node,
+ "qcom,mem-acc-crossover-voltage",
+ &ctrl->mem_acc_crossover_volt);
+ if (rc) {
+ cpr3_err(ctrl, "error reading property qcom,mem-acc-crossover-voltage, rc=%d\n",
+ rc);
+ return rc;
+ }
+ ctrl->mem_acc_crossover_volt
+ = CPR3_ROUND(ctrl->mem_acc_crossover_volt, ctrl->step_volt);
+ }
+
/*
* Use fixed step quotient if specified otherwise use dynamically
* calculated per RO step quotient
@@ -1475,6 +1542,14 @@ static int cprh_kbss_populate_opp_table(struct cpr3_controller *ctrl)
for (i = 0; i < vreg->corner_count; i++) {
corner = &vreg->corner[i];
+ if (!corner->proc_freq) {
+ /*
+ * 0 MHz indicates this corner is not to be
+ * used as active DCVS set point. Don't add it
+ * to the OPP table.
+ */
+ continue;
+ }
rc = dev_pm_opp_add(dev, corner->proc_freq, i + 1);
if (rc) {
cpr3_err(ctrl, "could not add OPP for corner %d with frequency %u MHz, rc=%d\n",
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 5a9564326099..41684dca6baa 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -250,6 +250,20 @@ static void ufshcd_parse_pm_levels(struct ufs_hba *hba)
}
}
+static int ufshcd_parse_pinctrl_info(struct ufs_hba *hba)
+{
+ int ret = 0;
+
+ /* Try to obtain pinctrl handle */
+ hba->pctrl = devm_pinctrl_get(hba->dev);
+ if (IS_ERR(hba->pctrl)) {
+ ret = PTR_ERR(hba->pctrl);
+ hba->pctrl = NULL;
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_SMP
/**
* ufshcd_pltfrm_suspend - suspend power management function
@@ -361,6 +375,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
goto dealloc_host;
}
+ err = ufshcd_parse_pinctrl_info(hba);
+ if (err) {
+ dev_dbg(&pdev->dev, "%s: unable to parse pinctrl data %d\n",
+ __func__, err);
+ /* let's not fail the probe */
+ }
+
ufshcd_parse_pm_levels(hba);
if (!dev->dma_mask)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index e52aed51f67d..06defae6d5ba 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -446,6 +446,63 @@ void ufshcd_scsi_block_requests(struct ufs_hba *hba)
}
EXPORT_SYMBOL(ufshcd_scsi_block_requests);
+static int ufshcd_device_reset_ctrl(struct ufs_hba *hba, bool ctrl)
+{
+ int ret = 0;
+
+ if (!hba->pctrl)
+ return 0;
+
+ /* Assert reset if ctrl == true */
+ if (ctrl)
+ ret = pinctrl_select_state(hba->pctrl,
+ pinctrl_lookup_state(hba->pctrl, "dev-reset-assert"));
+ else
+ ret = pinctrl_select_state(hba->pctrl,
+ pinctrl_lookup_state(hba->pctrl, "dev-reset-deassert"));
+
+ if (ret < 0)
+ dev_err(hba->dev, "%s: %s failed with err %d\n",
+ __func__, ctrl ? "Assert" : "Deassert", ret);
+
+ return ret;
+}
+
+static inline int ufshcd_assert_device_reset(struct ufs_hba *hba)
+{
+ return ufshcd_device_reset_ctrl(hba, true);
+}
+
+static inline int ufshcd_deassert_device_reset(struct ufs_hba *hba)
+{
+ return ufshcd_device_reset_ctrl(hba, false);
+}
+
+static int ufshcd_reset_device(struct ufs_hba *hba)
+{
+ int ret;
+
+ /* reset the connected UFS device */
+ ret = ufshcd_assert_device_reset(hba);
+ if (ret)
+ goto out;
+ /*
+ * The reset signal is active low.
+ * The UFS device shall detect more than or equal to 1us of positive
+ * or negative RST_n pulse width.
+ * To be on safe side, keep the reset low for atleast 10us.
+ */
+ usleep_range(10, 15);
+
+ ret = ufshcd_deassert_device_reset(hba);
+ if (ret)
+ goto out;
+ /* same as assert, wait for atleast 10us after deassert */
+ usleep_range(10, 15);
+out:
+ return ret;
+}
+
/* replace non-printable or non-ASCII characters with spaces */
static inline void ufshcd_remove_non_printable(char *val)
{
@@ -6520,6 +6577,11 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba)
dev_warn(hba->dev, "%s: full reset returned %d\n",
__func__, err);
+ err = ufshcd_reset_device(hba);
+ if (err)
+ dev_warn(hba->dev, "%s: device reset failed. err %d\n",
+ __func__, err);
+
err = ufshcd_host_reset_and_restore(hba);
} while (err && --retries);
@@ -8220,13 +8282,6 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
hba->clk_gating.is_suspended = true;
hba->hibern8_on_idle.is_suspended = true;
- /*
- * Disable auto hibern8 to prevent unnecessary hibern8 enter/exit
- * during suspend path
- */
- if (ufshcd_is_auto_hibern8_supported(hba))
- ufshcd_set_auto_hibern8_timer(hba, 0);
-
if (hba->clk_scaling.is_allowed) {
cancel_work_sync(&hba->clk_scaling.suspend_work);
cancel_work_sync(&hba->clk_scaling.resume_work);
@@ -8334,10 +8389,6 @@ enable_gating:
ufshcd_resume_clkscaling(hba);
hba->hibern8_on_idle.is_suspended = false;
hba->clk_gating.is_suspended = false;
- /* Re-enable auto hibern8 in case of suspend failure */
- if (ufshcd_is_auto_hibern8_supported(hba))
- ufshcd_set_auto_hibern8_timer(hba,
- hba->hibern8_on_idle.delay_ms);
ufshcd_release_all(hba);
out:
hba->pm_op_in_progress = 0;
@@ -8431,13 +8482,6 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
if (hba->clk_scaling.is_allowed)
ufshcd_resume_clkscaling(hba);
- /*
- * Enable auto hibern8 after successful resume to prevent
- * unnecessary hibern8 enter/exit during resume path
- */
- if (ufshcd_is_auto_hibern8_supported(hba))
- ufshcd_set_auto_hibern8_timer(hba,
- hba->hibern8_on_idle.delay_ms);
/* Schedule clock gating in case of no access to UFS device yet */
ufshcd_release_all(hba);
goto out;
@@ -9422,6 +9466,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
/* Reset controller to power on reset (POR) state */
ufshcd_vops_full_reset(hba);
+ /* reset connected UFS device */
+ err = ufshcd_reset_device(hba);
+ if (err)
+ dev_warn(hba->dev, "%s: device reset failed. err %d\n",
+ __func__, err);
+
/* Host controller enable */
err = ufshcd_hba_enable(hba);
if (err) {
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 9f2b04c8ff82..c5eb21d8a0fe 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -907,6 +907,7 @@ struct ufs_hba {
int scsi_block_reqs_cnt;
bool full_init_linereset;
+ struct pinctrl *pctrl;
};
static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index de6cb6c6df05..a21f6735808b 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1465,11 +1465,10 @@ static void dwc3_restart_usb_work(struct work_struct *w)
pm_runtime_suspend(mdwc->dev);
}
+ mdwc->in_restart = false;
/* Force reconnect only if cable is still connected */
- if (mdwc->vbus_active) {
- mdwc->in_restart = false;
+ if (mdwc->vbus_active)
dwc3_resume_work(&mdwc->resume_work);
- }
dwc->err_evt_seen = false;
flush_delayed_work(&mdwc->sm_work);
@@ -1781,7 +1780,7 @@ static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc)
u32 reg = 0;
if ((mdwc->in_host_mode || mdwc->vbus_active)
- && dwc3_msm_is_superspeed(mdwc)) {
+ && dwc3_msm_is_superspeed(mdwc) && !mdwc->in_restart) {
if (!atomic_read(&mdwc->in_p3)) {
dev_err(mdwc->dev, "Not in P3,aborting LPM sequence\n");
return -EBUSY;
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 738f20d935d6..af20033b621f 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -1984,6 +1984,10 @@ static int gsi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
atomic_set(&gsi->connected, 1);
+ /* send 0 len pkt to qti to notify state change */
+ if (gsi->prot_id == IPA_USB_DIAG)
+ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
+
return 0;
notify_ep_disable:
diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c
index 0b9b60c3ca45..1a03b0d71a18 100644
--- a/drivers/usb/pd/qpnp-pdphy.c
+++ b/drivers/usb/pd/qpnp-pdphy.c
@@ -71,6 +71,9 @@
#define USB_PDPHY_RX_BUFFER 0x80
+#define USB_PDPHY_SEC_ACCESS 0xD0
+#define USB_PDPHY_TRIM_3 0xF3
+
/* VDD regulator */
#define VDD_PDPHY_VOL_MIN 3088000 /* uV */
#define VDD_PDPHY_VOL_MAX 3088000 /* uV */
@@ -673,6 +676,9 @@ static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
if (ret)
goto done;
+ /* ack to change ownership of rx buffer back to PDPHY RX HW */
+ pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);
+
if (((buf[0] & 0xf) == PD_MSG_BIST) && size >= 5) { /* BIST */
u8 mode = buf[5] >> 4; /* [31:28] of 1st data object */
@@ -689,9 +695,6 @@ static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
if (pdphy->msg_rx_cb)
pdphy->msg_rx_cb(pdphy->usbpd, frame_type, buf, size + 1);
- /* ack to change ownership of rx buffer back to PDPHY RX HW */
- pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);
-
print_hex_dump_debug("rx msg:", DUMP_PREFIX_NONE, 32, 4, buf, size + 1,
false);
pdphy->rx_bytes += size + 1;
@@ -806,6 +809,14 @@ static int pdphy_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ ret = pdphy_reg_write(pdphy, USB_PDPHY_SEC_ACCESS, 0xA5);
+ if (ret)
+ return ret;
+
+ ret = pdphy_reg_write(pdphy, USB_PDPHY_TRIM_3, 0x2);
+ if (ret)
+ return ret;
+
/* usbpd_create() could call back to us, so have __pdphy ready */
__pdphy = pdphy;
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 31c0cd86df4b..da6c68d43b53 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -1603,10 +1603,6 @@ int mdp3_validate_scale_config(struct mdp_bl_scale_data *data)
pr_err("%s invalid bl_scale\n", __func__);
return -EINVAL;
}
- if (data->min_lvl > MDP_HISTOGRAM_BL_LEVEL_MAX) {
- pr_err("%s invalid bl_min_lvl\n", __func__);
- return -EINVAL;
- }
return 0;
}
@@ -1810,9 +1806,7 @@ static int mdp3_bl_scale_config(struct msm_fb_data_type *mfd,
mutex_lock(&mfd->bl_lock);
curr_bl = mfd->bl_level;
mfd->bl_scale = data->scale;
- mfd->bl_min_lvl = data->min_lvl;
- pr_debug("update scale = %d, min_lvl = %d\n", mfd->bl_scale,
- mfd->bl_min_lvl);
+ pr_debug("update scale = %d\n", mfd->bl_scale);
/* update current backlight to use new scaling*/
mdss_fb_set_backlight(mfd, curr_bl);
diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.c b/drivers/video/fbdev/msm/mdss_compat_utils.c
index 5ad51dd23f3b..d3eb3db48eb7 100644
--- a/drivers/video/fbdev/msm/mdss_compat_utils.c
+++ b/drivers/video/fbdev/msm/mdss_compat_utils.c
@@ -197,7 +197,7 @@ static struct mdp_input_layer *__create_layer_list(
struct mdp_input_layer32 *layer_list32,
u32 layer_count)
{
- int i, ret;
+ int i, ret = 0;
u32 buffer_size;
struct mdp_input_layer *layer, *layer_list;
struct mdp_input_layer32 *layer32;
diff --git a/drivers/video/fbdev/msm/mdss_dba_utils.c b/drivers/video/fbdev/msm/mdss_dba_utils.c
index fa78bd0166ea..76671b539aa7 100644
--- a/drivers/video/fbdev/msm/mdss_dba_utils.c
+++ b/drivers/video/fbdev/msm/mdss_dba_utils.c
@@ -323,7 +323,9 @@ static void mdss_dba_utils_dba_cb(void *data, enum msm_dba_callback_event event)
if (!ret) {
hdmi_edid_parser(udata->edid_data);
hdmi_edid_get_audio_blk(udata->edid_data, &blk);
- udata->ops.set_audio_block(udata->dba_data,
+ if (udata->ops.set_audio_block)
+ udata->ops.set_audio_block(
+ udata->dba_data,
sizeof(blk), &blk);
} else {
pr_err("failed to get edid%d\n", ret);
diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c
index 8663797f1730..6b455e0f1e6f 100644
--- a/drivers/video/fbdev/msm/mdss_debug.c
+++ b/drivers/video/fbdev/msm/mdss_debug.c
@@ -244,23 +244,19 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
mdss_dsi_panel_cmd_read(ctrl_pdata, panel_reg[0], panel_reg[1],
NULL, rx_buf, dbg->cnt);
- len = snprintf(panel_reg_buf, reg_buf_len, "0x%02zx: ", dbg->off);
- if (len < 0)
- goto read_reg_fail;
+ len = scnprintf(panel_reg_buf, reg_buf_len, "0x%02zx: ", dbg->off);
for (i = 0; (len < reg_buf_len) && (i < ctrl_pdata->rx_len); i++)
len += scnprintf(panel_reg_buf + len, reg_buf_len - len,
"0x%02x ", rx_buf[i]);
- panel_reg_buf[len - 1] = '\n';
+ if (len)
+ panel_reg_buf[len - 1] = '\n';
if (mdata->debug_inf.debug_enable_clock)
mdata->debug_inf.debug_enable_clock(0);
- if (len < 0 || len >= sizeof(panel_reg_buf))
- return 0;
-
- if ((count < sizeof(panel_reg_buf))
+ if ((count < reg_buf_len)
|| (copy_to_user(user_buf, panel_reg_buf, len)))
goto read_reg_fail;
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index b7561e49955b..840df3741b21 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -2152,8 +2152,9 @@ static void mdss_dp_event_work(struct work_struct *work)
SVDM_CMD_TYPE_INITIATOR, 0x1, 0x0, 0x0);
break;
case EV_USBPD_DP_STATUS:
+ config = 0x1; /* DFP_D connected */
usbpd_send_svdm(dp->pd, USB_C_DP_SID, DP_VDM_STATUS,
- SVDM_CMD_TYPE_INITIATOR, 0x1, 0x0, 0x0);
+ SVDM_CMD_TYPE_INITIATOR, 0x1, &config, 0x1);
break;
case EV_USBPD_DP_CONFIGURE:
config = mdss_dp_usbpd_gen_config_pkt(dp);
@@ -2552,7 +2553,8 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
dp_drv->alt_mode.dp_cap.response = *vdos;
mdss_dp_usbpd_ext_capabilities(&dp_drv->alt_mode.dp_cap);
dp_drv->alt_mode.current_state |= DISCOVER_MODES_DONE;
- dp_send_events(dp_drv, EV_USBPD_ENTER_MODE);
+ if (dp_drv->alt_mode.dp_cap.s_port & BIT(0))
+ dp_send_events(dp_drv, EV_USBPD_ENTER_MODE);
break;
case USBPD_SVDM_ENTER_MODE:
dp_drv->alt_mode.current_state |= ENTER_MODE_DONE;
@@ -2574,7 +2576,8 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
if (!(dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE)) {
dp_drv->alt_mode.current_state |= DP_STATUS_DONE;
- dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
+ if (dp_drv->alt_mode.dp_status.c_port & BIT(1))
+ dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
}
break;
case DP_VDM_CONFIGURE:
@@ -2599,8 +2602,10 @@ static void mdss_dp_process_attention(struct mdss_dp_drv_pdata *dp_drv)
pr_debug("Attention: hpd_irq high\n");
if (dp_drv->power_on && dp_drv->hdcp.ops &&
- dp_drv->hdcp.ops->cp_irq)
- dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
+ dp_drv->hdcp.ops->cp_irq) {
+ if (!dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data))
+ return;
+ }
if (!mdss_dp_process_hpd_irq_high(dp_drv))
return;
diff --git a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
index 79cd94cfbe88..695331babf55 100644
--- a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
@@ -574,18 +574,6 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work)
cdata.context = ctrl->lib_ctx;
- ctrl->sink_rx_status = 0;
- rc = mdss_dp_aux_read_rx_status(ctrl->init_data.cb_data,
- &ctrl->sink_rx_status);
-
- if (rc) {
- pr_err("failed to read rx status\n");
-
- cdata.cmd = HDCP_LIB_WKUP_CMD_LINK_FAILED;
- atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
- goto exit;
- }
-
if (ctrl->sink_rx_status & ctrl->abort_mask) {
if (ctrl->sink_rx_status & BIT(3))
pr_err("reauth_req set by sink\n");
@@ -636,6 +624,7 @@ static void dp_hdcp2p2_auth_work(struct kthread_work *work)
static int dp_hdcp2p2_cp_irq(void *input)
{
+ int rc = 0;
struct dp_hdcp2p2_ctrl *ctrl = input;
if (!ctrl) {
@@ -643,9 +632,25 @@ static int dp_hdcp2p2_cp_irq(void *input)
return -EINVAL;
}
+ ctrl->sink_rx_status = 0;
+ rc = mdss_dp_aux_read_rx_status(ctrl->init_data.cb_data,
+ &ctrl->sink_rx_status);
+ if (rc) {
+ pr_err("failed to read rx status\n");
+ goto error;
+ }
+
+ if (!ctrl->sink_rx_status) {
+ pr_debug("not a hdcp 2.2 irq\n");
+ rc = -EINVAL;
+ goto error;
+ }
+
queue_kthread_work(&ctrl->worker, &ctrl->link);
return 0;
+error:
+ return rc;
}
void dp_hdcp2p2_deinit(void *input)
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 86edc4492599..10962548c3c5 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -266,8 +266,7 @@ void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
mvid = (pixel_m & 0xFFFF) * 5;
nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
- if (lrate == DP_LINK_RATE_540)
- nvid = nvid * 2;
+
pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
writel_relaxed(mvid, ctrl_io->base + DP_SOFTWARE_MVID);
writel_relaxed(nvid, ctrl_io->base + DP_SOFTWARE_NVID);
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index 4b28d98177be..82e9f9417662 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -185,6 +185,7 @@
#define DP_HDCP_RCVPORT_DATA6 (0x0C4)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_CTRL (0x024)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_DATA (0x028)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA0 (0x004)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA1 (0x008)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA7 (0x00C)
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 8dccab8a81be..423a15d82679 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1283,7 +1283,11 @@ int mdss_dsi_switch_mode(struct mdss_panel_data *pdata, int mode)
MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
if (dsi_ctrl_setup_needed)
mdss_dsi_ctrl_setup(ctrl_pdata);
+
+ ATRACE_BEGIN("switch_cmds");
ctrl_pdata->switch_mode(pdata, mode);
+ ATRACE_END("switch_cmds");
+
mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
@@ -1733,6 +1737,38 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
return ret;
}
+static void __mdss_dsi_mask_dfps_errors(struct mdss_dsi_ctrl_pdata *ctrl,
+ bool mask)
+{
+ u32 data = 0;
+
+ /*
+ * Assumption is that the DSI clocks will be enabled
+ * when this API is called from dfps thread
+ */
+ if (mask) {
+ /* mask FIFO underflow and PLL unlock bits */
+ mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x7c000000);
+ } else {
+ data = MIPI_INP((ctrl->ctrl_base) + 0x0120);
+ if (data & BIT(16)) {
+ pr_debug("pll unlocked: 0x%x\n", data);
+ /* clear PLL unlock bit */
+ MIPI_OUTP((ctrl->ctrl_base) + 0x120, BIT(16));
+ }
+
+ data = MIPI_INP((ctrl->ctrl_base) + 0x00c);
+ if (data & 0x88880000) {
+ pr_debug("dsi fifo underflow: 0x%x\n", data);
+ /* clear DSI FIFO underflow and empty */
+ MIPI_OUTP((ctrl->ctrl_base) + 0x00c, 0x99990000);
+ }
+
+ /* restore FIFO underflow and PLL unlock bits */
+ mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x0);
+ }
+}
+
static void __mdss_dsi_update_video_mode_total(struct mdss_panel_data *pdata,
int new_fps)
{
@@ -1935,7 +1971,6 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL;
struct mdss_panel_info *pinfo, *spinfo;
int rc = 0;
- u32 data;
if (pdata == NULL) {
pr_err("%s Invalid pdata\n", __func__);
@@ -2055,12 +2090,9 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL,
0x00);
- data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0120);
- if (data & BIT(16)) {
- pr_debug("pll unlocked: 0x%x\n", data);
- /* clear PLL unlock bit */
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x120, BIT(16));
- }
+ __mdss_dsi_mask_dfps_errors(ctrl_pdata, false);
+ if (sctrl_pdata)
+ __mdss_dsi_mask_dfps_errors(sctrl_pdata, false);
/* Move the mux clocks to main byte and pixel clocks */
rc = clk_set_parent(ctrl_pdata->mux_byte_clk,
@@ -2188,6 +2220,9 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
__mdss_dsi_update_video_mode_total(pdata, new_fps);
} else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
/* Clock update method */
+
+ __mdss_dsi_mask_dfps_errors(ctrl_pdata, true);
+
if (phy_rev == DSI_PHY_REV_20) {
rc = mdss_dsi_phy_calc_timing_param(pinfo, phy_rev,
new_fps);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 3a347681f434..6c840c8459ae 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -692,6 +692,8 @@ void mdss_dsi_dsc_config(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsc_desc *dsc);
void mdss_dsi_dfps_config_8996(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_set_burst_mode(struct mdss_dsi_ctrl_pdata *ctrl);
+void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
+ u32 mask, u32 val);
static inline const char *__mdss_dsi_pm_name(enum dsi_pm_type module)
{
diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c
index 5f8b45413e32..bf854a3140b2 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_host.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_host.c
@@ -134,7 +134,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
}
}
-static void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
+void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
u32 mask, u32 val)
{
u32 data;
@@ -2978,7 +2978,7 @@ bool mdss_dsi_dln0_phy_err(struct mdss_dsi_ctrl_pdata *ctrl, bool print_en)
static bool mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl)
{
- u32 status, isr;
+ u32 status;
unsigned char *base;
bool ret = false;
@@ -2990,17 +2990,7 @@ static bool mdss_dsi_fifo_status(struct mdss_dsi_ctrl_pdata *ctrl)
if (status & 0xcccc4409) {
MIPI_OUTP(base + 0x000c, status);
- /*
- * When dynamic refresh operation is under progress, it is
- * expected to have FIFO underflow error sometimes. In such
- * cases, do not trigger the underflow recovery process and
- * avoid printing the error status on console.
- */
- isr = MIPI_INP(ctrl->ctrl_base + 0x0110);
- if (isr & DSI_INTR_DYNAMIC_REFRESH_MASK)
- status &= ~(0x88880000);
- else
- pr_err("%s: status=%x\n", __func__, status);
+ pr_err("%s: status=%x\n", __func__, status);
if (status & 0x44440000) {/* DLNx_HS_FIFO_OVERFLOW */
dsi_send_events(ctrl, DSI_EV_DLNx_FIFO_OVERFLOW, 0);
@@ -3048,6 +3038,10 @@ static bool mdss_dsi_clk_status(struct mdss_dsi_ctrl_pdata *ctrl)
if (status & 0x10000) { /* DSI_CLK_PLL_UNLOCKED */
MIPI_OUTP(base + 0x0120, status);
+ /* If PLL unlock is masked, do not report error */
+ if (MIPI_INP(base + 0x10c) & BIT(28))
+ return false;
+
dsi_send_events(ctrl, DSI_EV_PLL_UNLOCKED, 0);
pr_err("%s: status=%x\n", __func__, status);
ret = true;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 7c36bb627043..8fbf2544f487 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -1960,6 +1960,9 @@ static int mdss_dsi_parse_panel_features(struct device_node *np,
pinfo->panel_ack_disabled = pinfo->sim_panel_mode ?
1 : of_property_read_bool(np, "qcom,panel-ack-disabled");
+ pinfo->allow_phy_power_off = of_property_read_bool(np,
+ "qcom,panel-allow-phy-poweroff");
+
mdss_dsi_parse_esd_params(np, ctrl);
if (pinfo->panel_ack_disabled && pinfo->esd_check_enabled) {
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index d528305af798..98ca6c3da20b 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -1134,10 +1134,10 @@ static int mdss_fb_probe(struct platform_device *pdev)
mfd->bl_level = 0;
mfd->bl_scale = 1024;
- mfd->bl_min_lvl = 30;
mfd->ad_bl_level = 0;
mfd->fb_imgType = MDP_RGBA_8888;
mfd->calib_mode_bl = 0;
+ mfd->unset_bl_level = U32_MAX;
mfd->pdev = pdev;
@@ -1511,27 +1511,22 @@ static void mdss_fb_scale_bl(struct msm_fb_data_type *mfd, u32 *bl_lvl)
u32 temp = *bl_lvl;
pr_debug("input = %d, scale = %d\n", temp, mfd->bl_scale);
- if (temp >= mfd->bl_min_lvl) {
- if (temp > mfd->panel_info->bl_max) {
- pr_warn("%s: invalid bl level\n",
+ if (temp > mfd->panel_info->bl_max) {
+ pr_warn("%s: invalid bl level\n",
__func__);
- temp = mfd->panel_info->bl_max;
- }
- if (mfd->bl_scale > 1024) {
- pr_warn("%s: invalid bl scale\n",
+ temp = mfd->panel_info->bl_max;
+ }
+ if (mfd->bl_scale > 1024) {
+ pr_warn("%s: invalid bl scale\n",
__func__);
- mfd->bl_scale = 1024;
- }
- /*
- * bl_scale is the numerator of
- * scaling fraction (x/1024)
- */
- temp = (temp * mfd->bl_scale) / 1024;
-
- /*if less than minimum level, use min level*/
- if (temp < mfd->bl_min_lvl)
- temp = mfd->bl_min_lvl;
+ mfd->bl_scale = 1024;
}
+ /*
+ * bl_scale is the numerator of
+ * scaling fraction (x/1024)
+ */
+ temp = (temp * mfd->bl_scale) / 1024;
+
pr_debug("output = %d\n", temp);
(*bl_lvl) = temp;
@@ -1553,7 +1548,7 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
} else if (mdss_fb_is_power_on(mfd) && mfd->panel_info->panel_dead) {
mfd->unset_bl_level = mfd->bl_level;
} else {
- mfd->unset_bl_level = 0;
+ mfd->unset_bl_level = U32_MAX;
}
pdata = dev_get_platdata(&mfd->pdev->dev);
@@ -1597,7 +1592,7 @@ void mdss_fb_update_backlight(struct msm_fb_data_type *mfd)
u32 temp;
bool bl_notify = false;
- if (!mfd->unset_bl_level)
+ if (mfd->unset_bl_level == U32_MAX)
return;
mutex_lock(&mfd->bl_lock);
if (!mfd->allow_bl_update) {
@@ -1808,7 +1803,8 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd)
*/
if (IS_CALIB_MODE_BL(mfd))
mdss_fb_set_backlight(mfd, mfd->calib_mode_bl);
- else if (!mfd->panel_info->mipi.post_init_delay)
+ else if ((!mfd->panel_info->mipi.post_init_delay) &&
+ (mfd->unset_bl_level != U32_MAX))
mdss_fb_set_backlight(mfd, mfd->unset_bl_level);
/*
diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h
index 56997e40d244..2eb6c6456f29 100644
--- a/drivers/video/fbdev/msm/mdss_fb.h
+++ b/drivers/video/fbdev/msm/mdss_fb.h
@@ -299,7 +299,6 @@ struct msm_fb_data_type {
u32 ad_bl_level;
u32 bl_level;
u32 bl_scale;
- u32 bl_min_lvl;
u32 unset_bl_level;
bool allow_bl_update;
u32 bl_level_scaled;
diff --git a/drivers/video/fbdev/msm/mdss_hdcp_1x.c b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
index a8182c2f0e76..cefe368ccc9a 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp_1x.c
+++ b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
@@ -72,6 +72,7 @@ struct hdcp_sink_addr_map {
struct hdcp_sink_addr bksv;
struct hdcp_sink_addr r0;
struct hdcp_sink_addr bstatus;
+ struct hdcp_sink_addr cp_irq_status;
struct hdcp_sink_addr ksv_fifo;
struct hdcp_sink_addr v_h0;
struct hdcp_sink_addr v_h1;
@@ -82,7 +83,6 @@ struct hdcp_sink_addr_map {
/* addresses to write to sink */
struct hdcp_sink_addr an;
struct hdcp_sink_addr aksv;
- struct hdcp_sink_addr rep;
};
struct hdcp_int_set {
@@ -126,7 +126,9 @@ struct hdcp_reg_set {
u32 entropy_ctrl0;
u32 entropy_ctrl1;
u32 sha_ctrl;
+ u32 sha_data;
u32 sec_sha_ctrl;
+ u32 sec_sha_data;
u32 sha_status;
u32 data0;
@@ -154,13 +156,17 @@ struct hdcp_reg_set {
u32 reset;
u32 reset_bit;
+
+ u32 repeater;
};
#define HDCP_REG_SET_CLIENT_HDMI \
{HDMI_HDCP_LINK0_STATUS, 28, 24, 20, HDMI_HDCP_CTRL, \
HDMI_HDCP_SW_LOWER_AKSV, HDMI_HDCP_SW_UPPER_AKSV, \
HDMI_HDCP_ENTROPY_CTRL0, HDMI_HDCP_ENTROPY_CTRL1, \
- HDMI_HDCP_SHA_CTRL, HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_CTRL, \
+ HDMI_HDCP_SHA_CTRL, HDMI_HDCP_SHA_DATA, \
+ HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_CTRL, \
+ HDCP_SEC_TZ_HV_HLOS_HDCP_SHA_DATA, \
HDMI_HDCP_SHA_STATUS, HDMI_HDCP_RCVPORT_DATA0, \
HDMI_HDCP_RCVPORT_DATA1, HDMI_HDCP_RCVPORT_DATA2_0, \
HDMI_HDCP_RCVPORT_DATA3, HDMI_HDCP_RCVPORT_DATA4, \
@@ -176,13 +182,14 @@ struct hdcp_reg_set {
HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA10, \
HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA11, \
HDCP_SEC_TZ_HV_HLOS_HDCP_RCVPORT_DATA12, \
- HDMI_HDCP_RESET, BIT(0)}
+ HDMI_HDCP_RESET, BIT(0), BIT(6)}
#define HDCP_REG_SET_CLIENT_DP \
{DP_HDCP_STATUS, 16, 14, 13, DP_HDCP_CTRL, \
DP_HDCP_SW_LOWER_AKSV, DP_HDCP_SW_UPPER_AKSV, \
DP_HDCP_ENTROPY_CTRL0, DP_HDCP_ENTROPY_CTRL1, \
- 0, HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_CTRL, \
+ 0, 0, HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_CTRL, \
+ HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_DATA, \
DP_HDCP_SHA_STATUS, 0, 0, DP_HDCP_RCVPORT_DATA2_0, \
DP_HDCP_RCVPORT_DATA3, DP_HDCP_RCVPORT_DATA4, \
DP_HDCP_RCVPORT_DATA5, DP_HDCP_RCVPORT_DATA6, \
@@ -195,21 +202,21 @@ struct hdcp_reg_set {
HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA10, \
HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11, \
HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12, \
- DP_SW_RESET, BIT(1)}
+ DP_SW_RESET, BIT(1), BIT(1)}
#define HDCP_HDMI_SINK_ADDR_MAP \
{{"bcaps", 0x40, 1}, {"bksv", 0x00, 5}, {"r0'", 0x08, 2}, \
- {"bstatus", 0x41, 2}, {"ksv-fifo", 0x43, 0}, {"v_h0", 0x20, 4}, \
- {"v_h1", 0x24, 4}, {"v_h2", 0x28, 4}, {"v_h3", 0x2c, 4}, \
- {"v_h4", 0x30, 4}, {"an", 0x18, 8}, {"aksv", 0x10, 5}, \
- {"repeater", 0x00, 0} }
+ {"bstatus", 0x41, 2}, {"??", 0x0, 0}, {"ksv-fifo", 0x43, 0}, \
+ {"v_h0", 0x20, 4}, {"v_h1", 0x24, 4}, {"v_h2", 0x28, 4}, \
+ {"v_h3", 0x2c, 4}, {"v_h4", 0x30, 4}, {"an", 0x18, 8}, \
+ {"aksv", 0x10, 5} }
#define HDCP_DP_SINK_ADDR_MAP \
{{"bcaps", 0x68028, 1}, {"bksv", 0x68000, 5}, {"r0'", 0x68005, 2}, \
- {"bstatus", 0x6802A, 2}, {"ksv-fifo", 0x6802A, 0}, \
- {"v_h0", 0x68014, 4}, {"v_h1", 0x68018, 4}, {"v_h2", 0x6801C, 4}, \
- {"v_h3", 0x68020, 4}, {"v_h4", 0x68024, 4}, {"an", 0x6800C, 8}, \
- {"aksv", 0x68007, 5}, {"repeater", 0x68028, 1} }
+ {"binfo", 0x6802A, 2}, {"cp_irq_status", 0x68029, 2}, \
+ {"ksv-fifo", 0x6802C, 0}, {"v_h0", 0x68014, 4}, {"v_h1", 0x68018, 4}, \
+ {"v_h2", 0x6801C, 4}, {"v_h3", 0x68020, 4}, {"v_h4", 0x68024, 4}, \
+ {"an", 0x6800C, 8}, {"aksv", 0x68007, 5} }
#define HDCP_HDMI_INT_SET \
{HDMI_HDCP_INT_CTRL, \
@@ -227,17 +234,21 @@ struct hdcp_1x_ctrl {
u32 auth_retries;
u32 tp_msgid;
u32 tz_hdcp;
+ bool sink_r0_ready;
enum hdcp_states hdcp_state;
struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
struct HDCP_V2V1_MSG_TOPOLOGY current_tp;
struct delayed_work hdcp_auth_work;
struct work_struct hdcp_int_work;
struct completion r0_checked;
+ struct completion sink_r0_available;
+ struct completion sink_rep_ready;
struct hdcp_init_data init_data;
struct hdcp_ops *ops;
struct hdcp_reg_set reg_set;
struct hdcp_int_set int_set;
struct hdcp_sink_addr_map sink_addr;
+ struct workqueue_struct *workq;
};
const char *hdcp_state_name(enum hdcp_states hdcp_state)
@@ -527,6 +538,7 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
u8 *buf, bool realign)
{
u32 rc = 0;
+ int const max_size = 15, edid_read_delay_us = 20;
struct hdmi_tx_ddc_data ddc_data;
if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI) {
@@ -550,17 +562,30 @@ static int hdcp_1x_read(struct hdcp_1x_ctrl *hdcp_ctrl,
HDCP_STATE_NAME, sink->name);
} else if (IS_ENABLED(CONFIG_FB_MSM_MDSS_DP_PANEL) &&
hdcp_ctrl->init_data.client_id == HDCP_CLIENT_DP) {
- struct edp_cmd cmd = {0};
+ int size = sink->len;
- cmd.read = 1;
- cmd.addr = sink->addr;
- cmd.out_buf = buf;
- cmd.len = sink->len;
+ do {
+ struct edp_cmd cmd = {0};
+ int read_size;
- rc = dp_aux_read(hdcp_ctrl->init_data.cb_data, &cmd);
- if (rc)
- DEV_ERR("%s: %s: %s read failed\n", __func__,
- HDCP_STATE_NAME, sink->name);
+ read_size = min(size, max_size);
+
+ cmd.read = 1;
+ cmd.addr = sink->addr;
+ cmd.len = read_size;
+ cmd.out_buf = buf;
+
+ rc = dp_aux_read(hdcp_ctrl->init_data.cb_data, &cmd);
+ if (rc) {
+ pr_err("Aux read failed\n");
+ break;
+ }
+
+ /* give sink/repeater time to ready edid */
+ msleep(edid_read_delay_us);
+ buf += read_size;
+ size -= read_size;
+ } while (size > 0);
}
return rc;
@@ -621,19 +646,20 @@ static void hdcp_1x_enable_interrupts(struct hdcp_1x_ctrl *hdcp_ctrl)
static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
{
- int rc;
+ int rc, r0_retry = 3;
+ u32 const r0_read_delay_us = 1;
+ u32 const r0_read_timeout_us = r0_read_delay_us * 10;
u32 link0_aksv_0, link0_aksv_1;
u32 link0_bksv_0, link0_bksv_1;
u32 link0_an_0, link0_an_1;
u32 timeout_count;
- bool is_match;
struct dss_io_data *io;
struct dss_io_data *hdcp_io;
struct hdcp_reg_set *reg_set;
u8 aksv[5], *bksv = NULL;
u8 an[8];
u8 bcaps = 0;
- u32 link0_status;
+ u32 link0_status = 0;
u8 buf[0xFF];
struct scm_hdcp_req scm_buf[SCM_HDCP_MAX_REG];
u32 phy_addr;
@@ -669,9 +695,8 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
hdcp_1x_enable_interrupts(hdcp_ctrl);
- /* receiver (0), repeater (1) */
- hdcp_ctrl->current_tp.ds_type =
- (bcaps & BIT(6)) >> 6 ? DS_REPEATER : DS_RECEIVER;
+ hdcp_ctrl->current_tp.ds_type = bcaps & reg_set->repeater ?
+ DS_REPEATER : DS_RECEIVER;
/* Write BCAPS to the hardware */
if (hdcp_ctrl->tz_hdcp) {
@@ -757,18 +782,6 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
an[6] = (link0_an_1 >> 16) & 0xFF;
an[7] = (link0_an_1 >> 24) & 0xFF;
- rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.an, an);
- if (IS_ERR_VALUE(rc)) {
- DEV_ERR("%s: error writing an to sink\n", __func__);
- goto error;
- }
-
- rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.aksv, aksv);
- if (IS_ERR_VALUE(rc)) {
- DEV_ERR("%s: error writing aksv to sink\n", __func__);
- goto error;
- }
-
rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.bksv, bksv, false);
if (IS_ERR_VALUE(rc)) {
DEV_ERR("%s: error reading bksv from sink\n", __func__);
@@ -818,12 +831,6 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
DSS_REG_W(io, reg_set->data1, link0_bksv_1);
}
- /*
- * HDCP Compliace Test case 1A-01:
- * Wait here at least 100ms before reading R0'
- */
- msleep(125);
-
/* Wait for HDCP R0 computation to be completed */
rc = readl_poll_timeout(io->base + reg_set->status, link0_status,
link0_status & BIT(reg_set->r0_offset),
@@ -833,6 +840,38 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
goto error;
}
+ rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.an, an);
+ if (IS_ERR_VALUE(rc)) {
+ DEV_ERR("%s: error writing an to sink\n", __func__);
+ goto error;
+ }
+
+ rc = hdcp_1x_write(hdcp_ctrl, &hdcp_ctrl->sink_addr.aksv, aksv);
+ if (IS_ERR_VALUE(rc)) {
+ DEV_ERR("%s: error writing aksv to sink\n", __func__);
+ goto error;
+ }
+
+ /*
+ * HDCP Compliace Test case 1A-01:
+ * Wait here at least 100ms before reading R0'
+ */
+ if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI) {
+ msleep(125);
+ } else {
+ if (!hdcp_ctrl->sink_r0_ready) {
+ reinit_completion(&hdcp_ctrl->sink_r0_available);
+ timeout_count = wait_for_completion_timeout(
+ &hdcp_ctrl->sink_r0_available, HZ / 2);
+
+ if (!timeout_count) {
+ DEV_ERR("sink R0 not ready\n");
+ rc = -EINVAL;
+ goto error;
+ }
+ }
+ }
+r0_read_retry:
memset(buf, 0, sizeof(buf));
rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.r0, buf, false);
if (IS_ERR_VALUE(rc)) {
@@ -844,37 +883,29 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl)
buf[1], buf[0]);
/* Write R0' to HDCP registers and check to see if it is a match */
- reinit_completion(&hdcp_ctrl->r0_checked);
DSS_REG_W(io, reg_set->data2_0, (((u32)buf[1]) << 8) | buf[0]);
- timeout_count = wait_for_completion_timeout(
- &hdcp_ctrl->r0_checked, HZ*2);
- link0_status = DSS_REG_R(io, reg_set->status);
- is_match = link0_status & BIT(12);
- if (!is_match) {
- DEV_DBG("%s: %s: Link0_Status=0x%08x\n", __func__,
- HDCP_STATE_NAME, link0_status);
- if (!timeout_count) {
- DEV_ERR("%s: %s: Timeout. No R0 mtch. R0'=%02x%02x\n",
- __func__, HDCP_STATE_NAME, buf[1], buf[0]);
- rc = -ETIMEDOUT;
- goto error;
- } else {
- DEV_ERR("%s: %s: R0 mismatch. R0'=%02x%02x\n", __func__,
- HDCP_STATE_NAME, buf[1], buf[0]);
- rc = -EINVAL;
- goto error;
- }
- } else {
- DEV_DBG("%s: %s: R0 matches\n", __func__, HDCP_STATE_NAME);
+ rc = readl_poll_timeout(io->base + reg_set->status, link0_status,
+ link0_status & BIT(12),
+ r0_read_delay_us, r0_read_timeout_us);
+ if (IS_ERR_VALUE(rc)) {
+ DEV_ERR("%s: R0 mismatch\n", __func__);
+ if (--r0_retry)
+ goto r0_read_retry;
+
+ goto error;
}
+ hdcp1_set_enc(true);
+
+ DEV_INFO("%s: %s: Authentication Part I successful\n", __func__,
+ hdcp_ctrl ? HDCP_STATE_NAME : "???");
+
+ return 0;
+
error:
- if (rc)
- DEV_ERR("%s: %s: Authentication Part I failed\n", __func__,
- hdcp_ctrl ? HDCP_STATE_NAME : "???");
- else
- DEV_INFO("%s: %s: Authentication Part I successful\n",
- __func__, HDCP_STATE_NAME);
+ DEV_ERR("%s: %s: Authentication Part I failed\n", __func__,
+ hdcp_ctrl ? HDCP_STATE_NAME : "???");
+
return rc;
} /* hdcp_1x_authentication_part1 */
@@ -895,10 +926,6 @@ static int hdcp_1x_set_v_h(struct hdcp_1x_ctrl *hdcp_ctrl,
goto end;
}
- DEV_DBG("%s: %s: %s: buf[0]=%x, buf[1]=%x, buf[2]=%x, buf[3]=%x\n",
- __func__, HDCP_STATE_NAME, rd->sink->name, buf[0], buf[1],
- buf[2], buf[3]);
-
if (!hdcp_ctrl->tz_hdcp)
DSS_REG_W(io, rd->reg_id,
(buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]));
@@ -971,6 +998,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
u32 ret = 0;
u32 resp = 0;
u32 ksv_read_retry = 20;
+ int v_retry = 3;
if (!hdcp_ctrl || !hdcp_ctrl->init_data.core_io) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -999,16 +1027,35 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
* Wait until READY bit is set in BCAPS, as per HDCP specifications
* maximum permitted time to check for READY bit is five seconds.
*/
- timeout_count = 50;
- do {
- rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.bcaps,
- &bcaps, true);
- if (IS_ERR_VALUE(rc)) {
- DEV_ERR("%s: error reading bcaps\n", __func__);
+ rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.bcaps, &bcaps, true);
+ if (IS_ERR_VALUE(rc)) {
+ DEV_ERR("%s: error reading bcaps\n", __func__);
+ goto error;
+ }
+
+ if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI) {
+ timeout_count = 50;
+
+ while (!(bcaps & BIT(5)) && --timeout_count) {
+ rc = hdcp_1x_read(hdcp_ctrl,
+ &hdcp_ctrl->sink_addr.bcaps, &bcaps, true);
+ if (IS_ERR_VALUE(rc)) {
+ DEV_ERR("%s: error reading bcaps\n", __func__);
+ goto error;
+ }
+ msleep(100);
+ }
+ } else {
+ reinit_completion(&hdcp_ctrl->sink_rep_ready);
+ timeout_count = wait_for_completion_timeout(
+ &hdcp_ctrl->sink_rep_ready, HZ * 5);
+
+ if (!timeout_count) {
+ DEV_ERR("sink not ready with DS KSV list\n");
+ rc = -EINVAL;
goto error;
}
- msleep(100);
- } while (!(bcaps & BIT(5)) && --timeout_count);
+ }
rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.bstatus,
buf, true);
@@ -1043,20 +1090,12 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
}
down_stream_devices = bstatus & 0x7F;
- if (down_stream_devices == 0) {
- /*
- * If no downstream devices are attached to the repeater
- * then part II fails.
- * todo: The other approach would be to continue PART II.
- */
- DEV_ERR("%s: %s: No downstream devices\n", __func__,
- HDCP_STATE_NAME);
- rc = -EINVAL;
- goto error;
- }
+
+ DEV_DBG("%s: DEVICE_COUNT %d\n", __func__, down_stream_devices);
/* Cascaded repeater depth */
repeater_cascade_depth = (bstatus >> 8) & 0x7;
+ DEV_DBG("%s: DEPTH %d\n", __func__, repeater_cascade_depth);
/*
* HDCP Compliance 1B-05:
@@ -1064,6 +1103,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
* exceed max_devices_connected from bit 7 of Bstatus.
*/
max_devs_exceeded = (bstatus & BIT(7)) >> 7;
+ DEV_DBG("%s: MAX_DEVS_EXCEEDED %d\n", __func__, max_devs_exceeded);
if (max_devs_exceeded == 0x01) {
DEV_ERR("%s: %s: no. of devs connected exceeds max allowed",
__func__, HDCP_STATE_NAME);
@@ -1077,6 +1117,8 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
* exceed max_cascade_connected from bit 11 of Bstatus.
*/
max_cascade_exceeded = (bstatus & BIT(11)) >> 11;
+ DEV_DBG("%s: MAX CASCADE_EXCEEDED %d\n", __func__,
+ max_cascade_exceeded);
if (max_cascade_exceeded == 0x01) {
DEV_ERR("%s: %s: no. of cascade conn exceeds max allowed",
__func__, HDCP_STATE_NAME);
@@ -1096,7 +1138,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
ksv_bytes = 5 * down_stream_devices;
hdcp_ctrl->sink_addr.ksv_fifo.len = ksv_bytes;
- do {
+ while (ksv_bytes && --ksv_read_retry) {
rc = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.ksv_fifo,
ksv_fifo, false);
if (IS_ERR_VALUE(rc)) {
@@ -1108,19 +1150,24 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
* read from the KSV FIFO register.
*/
msleep(25);
-
+ } else {
+ break;
}
- } while (rc && --ksv_read_retry);
+ }
if (rc) {
DEV_ERR("%s: error reading ksv_fifo\n", __func__);
goto error;
}
-
+v_read_retry:
rc = hdcp_1x_transfer_v_h(hdcp_ctrl);
if (rc)
goto error;
+ /* do not proceed further if no downstream device connected */
+ if (!ksv_bytes)
+ goto error;
+
/*
* Write KSV FIFO to HDCP_SHA_DATA.
* This is done 1 byte at time starting with the LSB.
@@ -1161,7 +1208,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
if (hdcp_ctrl->tz_hdcp) {
memset(scm_buf, 0x00, sizeof(scm_buf));
- scm_buf[0].addr = phy_addr + reg_set->sha_ctrl;
+ scm_buf[0].addr = phy_addr + reg_set->sha_data;
scm_buf[0].val = ksv_fifo[i] << 16;
ret = hdcp_scm_call(scm_buf, &resp);
@@ -1173,10 +1220,10 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
}
} else if (hdcp_ctrl->init_data.sec_access) {
DSS_REG_W_ND(hdcp_ctrl->init_data.hdcp_io,
- reg_set->sec_sha_ctrl,
+ reg_set->sec_sha_data,
ksv_fifo[i] << 16);
} else {
- DSS_REG_W_ND(io, reg_set->sha_ctrl, ksv_fifo[i] << 16);
+ DSS_REG_W_ND(io, reg_set->sha_data, ksv_fifo[i] << 16);
}
/*
@@ -1199,7 +1246,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
if (hdcp_ctrl->tz_hdcp) {
memset(scm_buf, 0x00, sizeof(scm_buf));
- scm_buf[0].addr = phy_addr + reg_set->sha_ctrl;
+ scm_buf[0].addr = phy_addr + reg_set->sha_data;
scm_buf[0].val = (ksv_fifo[ksv_bytes - 1] << 16) | 0x1;
ret = hdcp_scm_call(scm_buf, &resp);
@@ -1211,10 +1258,10 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
}
} else if (hdcp_ctrl->init_data.sec_access) {
DSS_REG_W_ND(hdcp_ctrl->init_data.hdcp_io,
- reg_set->sec_sha_ctrl,
+ reg_set->sec_sha_data,
(ksv_fifo[ksv_bytes - 1] << 16) | 0x1);
} else {
- DSS_REG_W_ND(io, reg_set->sha_ctrl,
+ DSS_REG_W_ND(io, reg_set->sha_data,
(ksv_fifo[ksv_bytes - 1] << 16) | 0x1);
}
@@ -1223,7 +1270,7 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
sha_status & BIT(4),
HDCP_POLL_SLEEP_US, HDCP_POLL_TIMEOUT_US);
if (IS_ERR_VALUE(rc)) {
- DEV_ERR("%s: comp not done\n", __func__);
+ DEV_ERR("%s: V computation not done\n", __func__);
goto error;
}
@@ -1232,8 +1279,9 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x_ctrl *hdcp_ctrl)
status & BIT(reg_set->v_offset),
HDCP_POLL_SLEEP_US, HDCP_POLL_TIMEOUT_US);
if (IS_ERR_VALUE(rc)) {
- DEV_ERR("%s: V not ready\n", __func__);
- goto error;
+ DEV_ERR("%s: V mismatch\n", __func__);
+ if (--v_retry)
+ goto v_read_retry;
}
error:
if (rc)
@@ -1330,6 +1378,8 @@ static void hdcp_1x_auth_work(struct work_struct *work)
return;
}
+ hdcp_ctrl->sink_r0_ready = false;
+
io = hdcp_ctrl->init_data.core_io;
/* Enabling Software DDC for HDMI and REF timer for DP */
if (hdcp_ctrl->init_data.client_id == HDCP_CLIENT_HDMI)
@@ -1388,8 +1438,6 @@ error:
hdcp_ctrl->init_data.cb_data,
hdcp_ctrl->hdcp_state);
}
-
- hdcp1_set_enc(true);
} else {
DEV_DBG("%s: %s: HDCP state changed during authentication\n",
__func__, HDCP_STATE_NAME);
@@ -1419,12 +1467,12 @@ int hdcp_1x_authenticate(void *input)
if (!hdcp_1x_load_keys(input)) {
flush_delayed_work(&hdcp_ctrl->hdcp_auth_work);
- queue_delayed_work(hdcp_ctrl->init_data.workq,
+ queue_delayed_work(hdcp_ctrl->workq,
&hdcp_ctrl->hdcp_auth_work, HZ/2);
} else {
flush_work(&hdcp_ctrl->hdcp_int_work);
- queue_work(hdcp_ctrl->init_data.workq,
+ queue_work(hdcp_ctrl->workq,
&hdcp_ctrl->hdcp_int_work);
}
@@ -1478,10 +1526,10 @@ int hdcp_1x_reauthenticate(void *input)
DSS_REG_W(io, reg_set->reset, reg & ~reg_set->reset_bit);
if (!hdcp_1x_load_keys(input))
- queue_delayed_work(hdcp_ctrl->init_data.workq,
+ queue_delayed_work(hdcp_ctrl->workq,
&hdcp_ctrl->hdcp_auth_work, HZ);
else
- queue_work(hdcp_ctrl->init_data.workq,
+ queue_work(hdcp_ctrl->workq,
&hdcp_ctrl->hdcp_int_work);
return ret;
@@ -1531,7 +1579,7 @@ void hdcp_1x_off(void *input)
* No more reauthentiaction attempts will be scheduled since we
* set the currect state to inactive.
*/
- rc = cancel_delayed_work_sync(&hdcp_ctrl->hdcp_auth_work);
+ rc = cancel_delayed_work(&hdcp_ctrl->hdcp_auth_work);
if (rc)
DEV_DBG("%s: %s: Deleted hdcp auth work\n", __func__,
HDCP_STATE_NAME);
@@ -1549,6 +1597,8 @@ void hdcp_1x_off(void *input)
DSS_REG_W(io, reg_set->reset, reg & ~reg_set->reset_bit);
+ hdcp_ctrl->sink_r0_ready = false;
+
DEV_DBG("%s: %s: HDCP: Off\n", __func__, HDCP_STATE_NAME);
} /* hdcp_1x_off */
@@ -1599,7 +1649,7 @@ int hdcp_1x_isr(void *input)
__func__, HDCP_STATE_NAME, link_status);
if (HDCP_STATE_AUTHENTICATED == hdcp_ctrl->hdcp_state) {
/* Inform HDMI Tx of the failure */
- queue_work(hdcp_ctrl->init_data.workq,
+ queue_work(hdcp_ctrl->workq,
&hdcp_ctrl->hdcp_int_work);
/* todo: print debug log with auth fail reason */
} else if (HDCP_STATE_AUTHENTICATING == hdcp_ctrl->hdcp_state) {
@@ -1785,6 +1835,9 @@ void hdcp_1x_deinit(void *input)
return;
}
+ if (hdcp_ctrl->workq)
+ destroy_workqueue(hdcp_ctrl->workq);
+
sysfs_remove_group(hdcp_ctrl->init_data.sysfs_kobj,
&hdcp_1x_fs_attr_group);
@@ -1812,12 +1865,61 @@ static void hdcp_1x_update_client_reg_set(struct hdcp_1x_ctrl *hdcp_ctrl)
}
}
+static int hdcp_1x_cp_irq(void *input)
+{
+ struct hdcp_1x_ctrl *hdcp_ctrl = (struct hdcp_1x_ctrl *)input;
+ u8 buf = 0;
+ int ret = -EINVAL;
+
+ if (!hdcp_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ goto end;
+ }
+
+ ret = hdcp_1x_read(hdcp_ctrl, &hdcp_ctrl->sink_addr.cp_irq_status,
+ &buf, false);
+ if (IS_ERR_VALUE(ret)) {
+ DEV_ERR("%s: error reading cp_irq_status\n", __func__);
+ goto end;
+ }
+
+ if (!buf) {
+ DEV_DBG("%s: not a hdcp 1.x irq\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if ((buf & BIT(2)) || (buf & BIT(3))) {
+ DEV_ERR("%s: REAUTH REQUIRED\n", __func__);
+
+ queue_work(hdcp_ctrl->workq, &hdcp_ctrl->hdcp_int_work);
+ goto end;
+ }
+
+ if (buf & BIT(1)) {
+ DEV_DBG("%s: R0' AVAILABLE\n", __func__);
+ hdcp_ctrl->sink_r0_ready = true;
+ complete_all(&hdcp_ctrl->sink_r0_available);
+ goto end;
+ }
+
+ if (buf & BIT(0)) {
+ DEV_DBG("%s: KSVs READY\n", __func__);
+ complete_all(&hdcp_ctrl->sink_rep_ready);
+ goto end;
+ }
+end:
+ return ret;
+}
+
void *hdcp_1x_init(struct hdcp_init_data *init_data)
{
struct hdcp_1x_ctrl *hdcp_ctrl = NULL;
+ char name[20];
int ret;
static struct hdcp_ops ops = {
.isr = hdcp_1x_isr,
+ .cp_irq = hdcp_1x_cp_irq,
.reauthenticate = hdcp_1x_reauthenticate,
.authenticate = hdcp_1x_authenticate,
.off = hdcp_1x_off
@@ -1844,6 +1946,15 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
hdcp_ctrl->init_data = *init_data;
hdcp_ctrl->ops = &ops;
+ snprintf(name, sizeof(name), "hdcp_1x_%d",
+ hdcp_ctrl->init_data.client_id);
+
+ hdcp_ctrl->workq = create_workqueue(name);
+ if (!hdcp_ctrl->workq) {
+ DEV_ERR("%s: Error creating workqueue\n", __func__);
+ goto error;
+ }
+
hdcp_1x_update_client_reg_set(hdcp_ctrl);
if (sysfs_create_group(init_data->sysfs_kobj,
@@ -1857,6 +1968,8 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
init_completion(&hdcp_ctrl->r0_checked);
+ init_completion(&hdcp_ctrl->sink_r0_available);
+ init_completion(&hdcp_ctrl->sink_rep_ready);
if (!hdcp_ctrl->init_data.sec_access) {
ret = scm_is_call_available(SCM_SVC_HDCP, SCM_CMD_HDCP);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
index 481fc118c7ad..7934e4cf3bc4 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
@@ -666,7 +666,7 @@ static void hdmi_hdcp2p2_link_cb(void *data)
static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
{
- int rc, timeout_hsync;
+ int rc = 0, timeout_hsync;
char *recvd_msg_buf = NULL;
struct hdmi_tx_hdcp2p2_ddc_data *ddc_data;
struct hdmi_tx_ddc_ctrl *ddc_ctrl;
@@ -689,6 +689,7 @@ static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
pr_err("hdcp is off\n");
+ rc = -EINVAL;
goto exit;
}
hdmi_ddc_config(ddc_ctrl);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index ff44d0ae4ac5..e9ae30bb6914 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -71,6 +71,7 @@
#define HDMI_TX_MIN_FPS 20000
#define HDMI_TX_MAX_FPS 120000
+#define HDMI_KHZ_TO_HZ 1000
#define HDMI_TX_VERSION_403 0x40000003 /* msm8998 */
#define HDMI_GET_MSB(x) (x >> 8)
@@ -114,6 +115,7 @@ static int hdmi_tx_audio_info_setup(struct platform_device *pdev,
static int hdmi_tx_get_audio_edid_blk(struct platform_device *pdev,
struct msm_ext_disp_audio_edid_blk *blk);
static int hdmi_tx_get_cable_status(struct platform_device *pdev, u32 vote);
+static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm);
static struct mdss_hw hdmi_tx_hw = {
.hw_ndx = MDSS_HW_HDMI,
@@ -383,9 +385,14 @@ static inline bool hdmi_tx_is_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
static inline bool hdmi_tx_is_cec_wakeup_en(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- void *fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+ void *fd = NULL;
- if (!hdmi_ctrl || !fd)
+ if (!hdmi_ctrl)
+ return false;
+
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+
+ if (!fd)
return false;
return hdmi_cec_is_wakeup_en(fd);
@@ -393,9 +400,14 @@ static inline bool hdmi_tx_is_cec_wakeup_en(struct hdmi_tx_ctrl *hdmi_ctrl)
static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- void *fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+ void *fd = NULL;
- if (!hdmi_ctrl || !fd)
+ if (!hdmi_ctrl)
+ return;
+
+ fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW);
+
+ if (!fd)
return;
hdmi_cec_device_suspend(fd, hdmi_ctrl->panel_suspend);
@@ -413,7 +425,8 @@ static inline void hdmi_tx_send_cable_notification(
static inline void hdmi_tx_set_audio_switch_node(
struct hdmi_tx_ctrl *hdmi_ctrl, int val)
{
- if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.notify)
+ if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.notify &&
+ !hdmi_tx_is_dvi_mode(hdmi_ctrl))
hdmi_ctrl->ext_audio_data.intf_ops.notify(hdmi_ctrl->ext_pdev,
val);
}
@@ -648,10 +661,11 @@ static int hdmi_tx_update_pixel_clk(struct hdmi_tx_ctrl *hdmi_ctrl)
{
struct dss_module_power *power_data = NULL;
struct mdss_panel_info *pinfo;
+ u32 new_clk_rate = 0;
int rc = 0;
if (!hdmi_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
+ pr_err("invalid input\n");
rc = -EINVAL;
goto end;
}
@@ -660,21 +674,25 @@ static int hdmi_tx_update_pixel_clk(struct hdmi_tx_ctrl *hdmi_ctrl)
power_data = &hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM];
if (!power_data) {
- DEV_ERR("%s: Error: invalid power data\n", __func__);
+ pr_err("Error: invalid power data\n");
rc = -EINVAL;
goto end;
}
- if (power_data->clk_config->rate == pinfo->clk_rate) {
- rc = -EINVAL;
+ new_clk_rate = hdmi_tx_setup_tmds_clk_rate(pinfo->clk_rate,
+ pinfo->out_format, hdmi_ctrl->panel.dc_enable);
+
+ if (power_data->clk_config->rate == new_clk_rate)
goto end;
- }
- power_data->clk_config->rate = pinfo->clk_rate;
+ power_data->clk_config->rate = new_clk_rate;
- DEV_DBG("%s: rate %ld\n", __func__, power_data->clk_config->rate);
+ pr_debug("rate %ld\n", power_data->clk_config->rate);
- msm_dss_clk_set_rate(power_data->clk_config, power_data->num_clk);
+ rc = msm_dss_clk_set_rate(power_data->clk_config, power_data->num_clk);
+ if (rc < 0)
+ pr_err("failed to set clock rate %lu\n",
+ power_data->clk_config->rate);
end:
return rc;
}
@@ -1226,11 +1244,23 @@ static ssize_t hdmi_tx_sysfs_wta_5v(struct device *dev,
hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
- ret = -EINVAL;
- goto end;
+ return -EINVAL;
+ }
+
+ pd = &hdmi_ctrl->pdata.power_data[HDMI_TX_HPD_PM];
+
+ if (!pd || !pd->gpio_config) {
+ DEV_ERR("%s: Error: invalid power data\n", __func__);
+ return -EINVAL;
}
mutex_lock(&hdmi_ctrl->tx_lock);
+ pd = &hdmi_ctrl->pdata.power_data[HDMI_TX_HPD_PM];
+ if (!pd || !pd->gpio_config) {
+ DEV_ERR("%s: Error: invalid power data\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
ret = kstrtoint(buf, 10, &read);
if (ret) {
@@ -1316,6 +1346,35 @@ end:
return ret;
}
+static ssize_t hdmi_tx_sysfs_wta_hdmi_ppm(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret, ppm;
+ struct hdmi_tx_ctrl *hdmi_ctrl
+ = hdmi_tx_get_drvdata_from_sysfs_dev(dev);
+
+ if (!hdmi_ctrl) {
+ pr_err("invalid input\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&hdmi_ctrl->tx_lock);
+
+ ret = kstrtoint(buf, 10, &ppm);
+ if (ret) {
+ pr_err("kstrtoint failed. rc=%d\n", ret);
+ goto end;
+ }
+
+ hdmi_tx_update_ppm(hdmi_ctrl, ppm);
+
+ ret = strnlen(buf, PAGE_SIZE);
+ pr_debug("write ppm %d\n", ppm);
+end:
+ mutex_unlock(&hdmi_ctrl->tx_lock);
+ return ret;
+}
+
static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL);
static DEVICE_ATTR(hot_plug, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hot_plug);
static DEVICE_ATTR(sim_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_sim_mode,
@@ -1336,6 +1395,8 @@ static DEVICE_ATTR(s3d_mode, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_s3d_mode,
hdmi_tx_sysfs_wta_s3d_mode);
static DEVICE_ATTR(5v, S_IWUSR, NULL, hdmi_tx_sysfs_wta_5v);
static DEVICE_ATTR(hdr_stream, S_IWUSR, NULL, hdmi_tx_sysfs_wta_hdr_stream);
+static DEVICE_ATTR(hdmi_ppm, S_IRUGO | S_IWUSR, NULL,
+ hdmi_tx_sysfs_wta_hdmi_ppm);
static struct attribute *hdmi_tx_fs_attrs[] = {
&dev_attr_connected.attr,
@@ -1351,6 +1412,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = {
&dev_attr_s3d_mode.attr,
&dev_attr_5v.attr,
&dev_attr_hdr_stream.attr,
+ &dev_attr_hdmi_ppm.attr,
NULL,
};
static struct attribute_group hdmi_tx_fs_attrs_group = {
@@ -2114,6 +2176,7 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl)
pinfo->type = DTV_PANEL;
pinfo->pdest = DISPLAY_3;
pinfo->wait_cycle = 0;
+ pinfo->out_format = MDP_RGB_888;
pinfo->bpp = 24;
pinfo->fb_num = 1;
@@ -3013,7 +3076,12 @@ static void hdmi_tx_hpd_polarity_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
static inline void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- if (hdmi_ctrl && hdmi_ctrl->audio_ops.off)
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return;
+ }
+
+ if (hdmi_ctrl->audio_ops.off)
hdmi_ctrl->audio_ops.off(hdmi_ctrl->audio_data);
memset(&hdmi_ctrl->audio_params, 0,
@@ -3023,13 +3091,19 @@ static inline void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
static int hdmi_tx_power_off(struct hdmi_tx_ctrl *hdmi_ctrl)
{
struct dss_io_data *io = NULL;
- void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
+ void *pdata = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return -EINVAL;
}
+ pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
+ if (!pdata) {
+ DEV_ERR("%s: invalid panel data\n", __func__);
+ return -EINVAL;
+ }
+
io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
if (!io->base) {
DEV_ERR("%s: Core io is not initialized\n", __func__);
@@ -3167,7 +3241,7 @@ static void hdmi_tx_hpd_off(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_ctrl->mdss_util->disable_irq(&hdmi_tx_hw);
hdmi_tx_set_mode(hdmi_ctrl, false);
}
-
+ hdmi_tx_config_5v(hdmi_ctrl, false);
rc = hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_HPD_PM, 0);
if (rc)
DEV_INFO("%s: Failed to disable hpd power. Error=%d\n",
@@ -3520,7 +3594,7 @@ static int hdmi_tx_hdcp_off(struct hdmi_tx_ctrl *hdmi_ctrl)
static void hdmi_tx_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- void *pdata = pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
+ void *pdata = NULL;
struct mdss_panel_info *pinfo;
if (!hdmi_ctrl) {
@@ -3528,8 +3602,15 @@ static void hdmi_tx_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
return;
}
- pinfo = &hdmi_ctrl->panel_data.panel_info;
+ pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
+
+ pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL);
+ if (!pdata) {
+ DEV_ERR("%s: invalid panel data\n", __func__);
+ return;
+ }
+ pinfo = &hdmi_ctrl->panel_data.panel_info;
if (!pinfo->dynamic_fps) {
DEV_DBG("%s: Dynamic fps not enabled\n", __func__);
return;
@@ -3566,6 +3647,80 @@ static void hdmi_tx_fps_work(struct work_struct *work)
hdmi_tx_update_fps(hdmi_ctrl);
}
+static u64 hdmi_tx_clip_valid_pclk(struct hdmi_tx_ctrl *hdmi_ctrl, u64 pclk_in)
+{
+ struct msm_hdmi_mode_timing_info timing = {0};
+ u32 pclk_delta, pclk;
+ u64 pclk_clip = pclk_in;
+
+ hdmi_get_supported_mode(&timing,
+ &hdmi_ctrl->ds_data, hdmi_ctrl->vic);
+
+ /* as per standard, 0.5% of deviation is allowed */
+ pclk = timing.pixel_freq * HDMI_KHZ_TO_HZ;
+ pclk_delta = pclk * 5 / 1000;
+
+ if (pclk_in < (pclk - pclk_delta))
+ pclk_clip = pclk - pclk_delta;
+ else if (pclk_in > (pclk + pclk_delta))
+ pclk_clip = pclk + pclk_delta;
+
+ if (pclk_in != pclk_clip)
+ pr_debug("the deviation is too big, so clip pclk from %lld to %lld\n",
+ pclk_in, pclk_clip);
+
+ return pclk_clip;
+}
+
+/**
+ * hdmi_tx_update_ppm() - Update the HDMI pixel clock as per the input ppm
+ *
+ * @ppm: ppm is parts per million multiplied by 1000.
+ * return: 0 on success, non-zero in case of failure.
+ */
+static int hdmi_tx_update_ppm(struct hdmi_tx_ctrl *hdmi_ctrl, s32 ppm)
+{
+ struct mdss_panel_info *pinfo = NULL;
+ u64 cur_pclk, dst_pclk;
+ u64 clip_pclk;
+ int rc = 0;
+
+ if (!hdmi_ctrl) {
+ pr_err("invalid hdmi_ctrl\n");
+ return -EINVAL;
+ }
+
+ pinfo = &hdmi_ctrl->panel_data.panel_info;
+
+ /* only available in case HDMI is up */
+ if (!hdmi_tx_is_panel_on(hdmi_ctrl)) {
+ pr_err("hdmi is not on\n");
+ return -EINVAL;
+ }
+
+ /* get current pclk */
+ cur_pclk = pinfo->clk_rate;
+ /* get desired pclk */
+ dst_pclk = cur_pclk * (1000000000 + ppm);
+ do_div(dst_pclk, 1000000000);
+
+ clip_pclk = hdmi_tx_clip_valid_pclk(hdmi_ctrl, dst_pclk);
+
+ /* update pclk */
+ if (clip_pclk != cur_pclk) {
+ pr_debug("pclk changes from %llu to %llu when ppm is %d\n",
+ cur_pclk, clip_pclk, ppm);
+ pinfo->clk_rate = clip_pclk;
+ rc = hdmi_tx_update_pixel_clk(hdmi_ctrl);
+ if (rc < 0) {
+ pr_err("PPM update failed, reset clock rate\n");
+ pinfo->clk_rate = cur_pclk;
+ }
+ }
+
+ return rc;
+}
+
static int hdmi_tx_evt_handle_register(struct hdmi_tx_ctrl *hdmi_ctrl)
{
int rc = 0;
@@ -3796,6 +3951,13 @@ static int hdmi_tx_evt_handle_deep_color(struct hdmi_tx_ctrl *hdmi_ctrl)
return 0;
}
+static int hdmi_tx_evt_handle_hdmi_ppm(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ s32 ppm = (s32) (unsigned long)hdmi_ctrl->evt_arg;
+
+ return hdmi_tx_update_ppm(hdmi_ctrl, ppm);
+}
+
static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
int event, void *arg)
{
@@ -4497,6 +4659,7 @@ static int hdmi_tx_init_event_handler(struct hdmi_tx_ctrl *hdmi_ctrl)
handler[MDSS_EVENT_PANEL_OFF] = hdmi_tx_evt_handle_panel_off;
handler[MDSS_EVENT_CLOSE] = hdmi_tx_evt_handle_close;
handler[MDSS_EVENT_DEEP_COLOR] = hdmi_tx_evt_handle_deep_color;
+ handler[MDSS_EVENT_UPDATE_PANEL_PPM] = hdmi_tx_evt_handle_hdmi_ppm;
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 1dae41391795..3dfcbfb291ef 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -2409,12 +2409,12 @@ static void __update_sspp_info(struct mdss_mdp_pipe *pipe,
#define SPRINT(fmt, ...) \
(*cnt += scnprintf(buf + *cnt, len - *cnt, fmt, ##__VA_ARGS__))
- for (i = 0; i < pipe_cnt; i++) {
+ for (i = 0; i < pipe_cnt && pipe; i++) {
SPRINT("pipe_num:%d pipe_type:%s pipe_ndx:%d rects:%d pipe_is_handoff:%d display_id:%d ",
pipe->num, type, pipe->ndx, pipe->multirect.max_rects,
pipe->is_handed_off, mdss_mdp_get_display_id(pipe));
SPRINT("fmts_supported:");
- for (j = 0; j < num_bytes && pipe; j++)
+ for (j = 0; j < num_bytes; j++)
SPRINT("%d,", pipe->supported_formats[j]);
SPRINT("\n");
pipe += pipe->multirect.max_rects;
@@ -3391,15 +3391,18 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-sw-reset-off",
&sw_reset_offset, 1);
if (sw_reset_offset) {
- mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
- "qcom,mdss-pipe-vig-sw-reset-map", mdata->vig_pipes,
- mdata->nvig_pipes);
- mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
- "qcom,mdss-pipe-rgb-sw-reset-map", mdata->rgb_pipes,
- mdata->nrgb_pipes);
- mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
- "qcom,mdss-pipe-dma-sw-reset-map", mdata->dma_pipes,
- mdata->ndma_pipes);
+ if (mdata->vig_pipes)
+ mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
+ "qcom,mdss-pipe-vig-sw-reset-map",
+ mdata->vig_pipes, mdata->nvig_pipes);
+ if (mdata->rgb_pipes)
+ mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
+ "qcom,mdss-pipe-rgb-sw-reset-map",
+ mdata->rgb_pipes, mdata->nrgb_pipes);
+ if (mdata->dma_pipes)
+ mdss_mdp_parse_dt_pipe_sw_reset(pdev, sw_reset_offset,
+ "qcom,mdss-pipe-dma-sw-reset-map",
+ mdata->dma_pipes, mdata->ndma_pipes);
}
mdata->has_panic_ctrl = of_property_read_bool(pdev->dev.of_node,
@@ -3584,6 +3587,7 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata,
head[i].base = (mdata->mdss_io.base) + cdm_offsets[i];
atomic_set(&head[i].kref.refcount, 0);
mutex_init(&head[i].lock);
+ init_completion(&head[i].free_comp);
pr_debug("%s: cdm off (%d) = %pK\n", __func__, i, head[i].base);
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index e1c3841c82de..623c588ae456 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -465,6 +465,9 @@ struct mdss_mdp_ctl {
u32 vsync_cnt;
u32 underrun_cnt;
+ struct work_struct cpu_pm_work;
+ int autorefresh_frame_cnt;
+
u16 width;
u16 height;
u16 border_x_off;
@@ -473,6 +476,7 @@ struct mdss_mdp_ctl {
/* used for WFD */
u32 dst_format;
+ enum mdss_mdp_csc_type csc_type;
struct mult_factor dst_comp_ratio;
u32 clk_rate;
@@ -1910,6 +1914,7 @@ int mdss_mdp_ctl_cmd_set_autorefresh(struct mdss_mdp_ctl *ctl, int frame_cnt);
int mdss_mdp_ctl_cmd_get_autorefresh(struct mdss_mdp_ctl *ctl);
int mdss_mdp_enable_panel_disable_mode(struct msm_fb_data_type *mfd,
bool disable_panel);
+void mdss_mdp_ctl_event_timer(void *data);
int mdss_mdp_pp_get_version(struct mdp_pp_feature_version *version);
int mdss_mdp_layer_pre_commit_cwb(struct msm_fb_data_type *mfd,
struct mdp_layer_commit_v1 *commit);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_cdm.c b/drivers/video/fbdev/msm/mdss_mdp_cdm.c
index e0bf1cdf1361..f1d1bdd301e3 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_cdm.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_cdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -26,6 +26,8 @@ static u32 cdm_cdwn2_offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
static u32 cdm_cdwn2_cosite_v_coeff[] = {0x00080004};
static u32 cdm_cdwn2_offsite_v_coeff[] = {0x00060002};
+#define VSYNC_TIMEOUT_US 16000
+
/**
* @mdss_mdp_cdm_alloc() - Allocates a cdm block by parsing the list of
* available cdm blocks.
@@ -66,6 +68,7 @@ static void mdss_mdp_cdm_free(struct kref *kref)
if (!cdm)
return;
+ complete_all(&cdm->free_comp);
pr_debug("free cdm_num = %d\n", cdm->num);
}
@@ -84,6 +87,28 @@ struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, u32 intf_type)
cdm = mdss_mdp_cdm_alloc(mdata);
+ /**
+ * give hdmi interface priority to alloc the cdm block. It will wait
+ * for one vsync cycle to allow wfd to finish its job and try to reserve
+ * the block the again.
+ */
+ if (!cdm && (intf_type == MDP_CDM_CDWN_OUTPUT_HDMI)) {
+ /* always wait for first cdm block */
+ cdm = mdata->cdm_off;
+ if (cdm) {
+ reinit_completion(&cdm->free_comp);
+ /*
+ * no need to check the return status of completion
+ * timeout. Next cdm_alloc call will try to reserve
+ * the cdm block and returns failure if allocation
+ * fails.
+ */
+ wait_for_completion_timeout(&cdm->free_comp,
+ usecs_to_jiffies(VSYNC_TIMEOUT_US));
+ cdm = mdss_mdp_cdm_alloc(mdata);
+ }
+ }
+
if (!cdm) {
pr_err("%s: Unable to allocate cdm\n", __func__);
return ERR_PTR(-EBUSY);
@@ -110,7 +135,9 @@ static int mdss_mdp_cdm_csc_setup(struct mdss_mdp_cdm *cdm,
mdss_mdp_csc_setup(MDSS_MDP_BLOCK_CDM, cdm->num, data->csc_type);
- if (data->csc_type == MDSS_MDP_CSC_RGB2YUV_601L) {
+ if ((data->csc_type == MDSS_MDP_CSC_RGB2YUV_601L) ||
+ (data->csc_type == MDSS_MDP_CSC_RGB2YUV_601FR) ||
+ (data->csc_type == MDSS_MDP_CSC_RGB2YUV_709L)) {
op_mode |= BIT(2); /* DST_DATA_FORMAT = YUV */
op_mode &= ~BIT(1); /* SRC_DATA_FORMAT = RGB */
op_mode |= BIT(0); /* EN = 1 */
@@ -350,17 +377,6 @@ int mdss_mdp_cdm_destroy(struct mdss_mdp_cdm *cdm)
return -EINVAL;
}
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
- mutex_lock(&cdm->lock);
- /* Disable HDMI packer */
- writel_relaxed(0x0, cdm->base + MDSS_MDP_REG_CDM_HDMI_PACK_OP_MODE);
-
- /* Put CDM in bypass */
- writel_relaxed(0x0, cdm->mdata->mdp_base + MDSS_MDP_MDP_OUT_CTL_0);
-
- mutex_unlock(&cdm->lock);
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
-
kref_put(&cdm->kref, mdss_mdp_cdm_free);
return rc;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_cdm.h b/drivers/video/fbdev/msm/mdss_mdp_cdm.h
index 4515628da0e7..3b7fdced6623 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_cdm.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_cdm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014,2016, 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
@@ -59,6 +59,7 @@ struct mdss_mdp_cdm {
u32 out_intf;
bool is_bypassed;
struct mdp_cdm_cfg setup;
+ struct completion free_comp;
};
struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl,
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 6b71025229a0..169095f64a0f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/bitmap.h>
+#include <soc/qcom/event_timer.h>
#include "mdss_fb.h"
#include "mdss_mdp.h"
#include "mdss_mdp_trace.h"
@@ -2681,12 +2682,122 @@ int mdss_mdp_block_mixer_destroy(struct mdss_mdp_mixer *mixer)
return 0;
}
+int mdss_mdp_display_wakeup_time(struct mdss_mdp_ctl *ctl,
+ ktime_t *wakeup_time)
+{
+ struct mdss_panel_info *pinfo;
+ u64 clk_rate;
+ u32 clk_period;
+ u32 current_line, total_line;
+ u32 time_of_line, time_to_vsync, adjust_line_ns;
+
+ ktime_t current_time = ktime_get();
+
+ if (!ctl->ops.read_line_cnt_fnc)
+ return -EINVAL;
+
+ pinfo = &ctl->panel_data->panel_info;
+ if (!pinfo)
+ return -ENODEV;
+
+ clk_rate = mdss_mdp_get_pclk_rate(ctl);
+
+ clk_rate = DIV_ROUND_UP_ULL(clk_rate, 1000); /* in kHz */
+ if (!clk_rate)
+ return -EINVAL;
+
+ /*
+ * calculate clk_period as pico second to maintain good
+ * accuracy with high pclk rate and this number is in 17 bit
+ * range.
+ */
+ clk_period = DIV_ROUND_UP_ULL(1000000000, clk_rate);
+ if (!clk_period)
+ return -EINVAL;
+
+ time_of_line = (pinfo->lcdc.h_back_porch +
+ pinfo->lcdc.h_front_porch +
+ pinfo->lcdc.h_pulse_width +
+ pinfo->xres) * clk_period;
+
+ time_of_line /= 1000; /* in nano second */
+ if (!time_of_line)
+ return -EINVAL;
+
+ current_line = ctl->ops.read_line_cnt_fnc(ctl);
+
+ total_line = pinfo->lcdc.v_back_porch +
+ pinfo->lcdc.v_front_porch +
+ pinfo->lcdc.v_pulse_width +
+ pinfo->yres;
+
+ if (current_line >= total_line)
+ time_to_vsync = time_of_line * total_line;
+ else
+ time_to_vsync = time_of_line * (total_line - current_line);
+
+ if (pinfo->adjust_timer_delay_ms) {
+ adjust_line_ns = pinfo->adjust_timer_delay_ms
+ * 1000000; /* convert to ns */
+
+ /* Ignore large values of adjust_line_ns\ */
+ if (time_to_vsync > adjust_line_ns)
+ time_to_vsync -= adjust_line_ns;
+ }
+
+ if (!time_to_vsync)
+ return -EINVAL;
+
+ *wakeup_time = ktime_add_ns(current_time, time_to_vsync);
+
+ pr_debug("clk_rate=%lldkHz clk_period=%d cur_line=%d tot_line=%d\n",
+ clk_rate, clk_period, current_line, total_line);
+ pr_debug("time_to_vsync=%d current_time=%d wakeup_time=%d\n",
+ time_to_vsync, (int)ktime_to_ms(current_time),
+ (int)ktime_to_ms(*wakeup_time));
+
+ return 0;
+}
+
+static void __cpu_pm_work_handler(struct work_struct *work)
+{
+ struct mdss_mdp_ctl *ctl =
+ container_of(work, typeof(*ctl), cpu_pm_work);
+ ktime_t wakeup_time;
+ struct mdss_overlay_private *mdp5_data;
+
+ if (!ctl)
+ return;
+
+ if (mdss_mdp_display_wakeup_time(ctl, &wakeup_time))
+ return;
+
+ mdp5_data = mfd_to_mdp5_data(ctl->mfd);
+ activate_event_timer(mdp5_data->cpu_pm_hdl, wakeup_time);
+}
+
+void mdss_mdp_ctl_event_timer(void *data)
+{
+ struct mdss_overlay_private *mdp5_data =
+ (struct mdss_overlay_private *)data;
+ struct mdss_mdp_ctl *ctl = mdp5_data->ctl;
+
+ if (mdp5_data->cpu_pm_hdl && ctl && ctl->autorefresh_frame_cnt)
+ schedule_work(&ctl->cpu_pm_work);
+}
+
int mdss_mdp_ctl_cmd_set_autorefresh(struct mdss_mdp_ctl *ctl, int frame_cnt)
{
int ret = 0;
+ struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(ctl->mfd);
if (ctl->panel_data->panel_info.type == MIPI_CMD_PANEL) {
ret = mdss_mdp_cmd_set_autorefresh_mode(ctl, frame_cnt);
+ if (!ret) {
+ ctl->autorefresh_frame_cnt = frame_cnt;
+ if (frame_cnt)
+ mdss_mdp_ctl_event_timer(mdp5_data);
+ }
} else {
pr_err("Mode not supported for this panel\n");
ret = -EINVAL;
@@ -3824,6 +3935,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
ctl->intf_type = MDSS_INTF_DSI;
ctl->opmode = MDSS_MDP_CTL_OP_CMD_MODE;
ctl->ops.start_fnc = mdss_mdp_cmd_start;
+ INIT_WORK(&ctl->cpu_pm_work, __cpu_pm_work_handler);
break;
case DTV_PANEL:
ctl->is_video_mode = true;
@@ -5410,83 +5522,6 @@ exit:
return ret;
}
-int mdss_mdp_display_wakeup_time(struct mdss_mdp_ctl *ctl,
- ktime_t *wakeup_time)
-{
- struct mdss_panel_info *pinfo;
- u64 clk_rate;
- u32 clk_period;
- u32 current_line, total_line;
- u32 time_of_line, time_to_vsync, adjust_line_ns;
-
- ktime_t current_time = ktime_get();
-
- if (!ctl->ops.read_line_cnt_fnc)
- return -ENOSYS;
-
- pinfo = &ctl->panel_data->panel_info;
- if (!pinfo)
- return -ENODEV;
-
- clk_rate = mdss_mdp_get_pclk_rate(ctl);
-
- clk_rate = DIV_ROUND_UP_ULL(clk_rate, 1000); /* in kHz */
- if (!clk_rate)
- return -EINVAL;
-
- /*
- * calculate clk_period as pico second to maintain good
- * accuracy with high pclk rate and this number is in 17 bit
- * range.
- */
- clk_period = DIV_ROUND_UP_ULL(1000000000, clk_rate);
- if (!clk_period)
- return -EINVAL;
-
- time_of_line = (pinfo->lcdc.h_back_porch +
- pinfo->lcdc.h_front_porch +
- pinfo->lcdc.h_pulse_width +
- pinfo->xres) * clk_period;
-
- time_of_line /= 1000; /* in nano second */
- if (!time_of_line)
- return -EINVAL;
-
- current_line = ctl->ops.read_line_cnt_fnc(ctl);
-
- total_line = pinfo->lcdc.v_back_porch +
- pinfo->lcdc.v_front_porch +
- pinfo->lcdc.v_pulse_width +
- pinfo->yres;
-
- if (current_line > total_line)
- return -EINVAL;
-
- time_to_vsync = time_of_line * (total_line - current_line);
-
- if (pinfo->adjust_timer_delay_ms) {
- adjust_line_ns = pinfo->adjust_timer_delay_ms
- * 1000000; /* convert to ns */
-
- /* Ignore large values of adjust_line_ns\ */
- if (time_to_vsync > adjust_line_ns)
- time_to_vsync -= adjust_line_ns;
- }
-
- if (!time_to_vsync)
- return -EINVAL;
-
- *wakeup_time = ktime_add_ns(current_time, time_to_vsync);
-
- pr_debug("clk_rate=%lldkHz clk_period=%d cur_line=%d tot_line=%d\n",
- clk_rate, clk_period, current_line, total_line);
- pr_debug("time_to_vsync=%d current_time=%d wakeup_time=%d\n",
- time_to_vsync, (int)ktime_to_ms(current_time),
- (int)ktime_to_ms(*wakeup_time));
-
- return 0;
-}
-
int mdss_mdp_display_wait4comp(struct mdss_mdp_ctl *ctl)
{
int ret;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 70b36a08d5ca..fabdc5cd3e42 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -1793,21 +1793,12 @@ static inline bool mdss_mdp_video_need_pixel_drop(u32 vic)
}
static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm,
- struct mdss_panel_info *pinfo)
+ struct mdss_panel_info *pinfo, struct mdss_mdp_format_params *fmt)
{
- struct mdss_mdp_format_params *fmt;
struct mdp_cdm_cfg setup;
- fmt = mdss_mdp_get_format_params(pinfo->out_format);
-
- if (!fmt) {
- pr_err("%s: format %d not supported\n", __func__,
- pinfo->out_format);
- return -EINVAL;
- }
- setup.out_format = pinfo->out_format;
if (fmt->is_yuv)
- setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601L;
+ setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601FR;
else
setup.csc_type = MDSS_MDP_CSC_RGB2RGB;
@@ -1835,6 +1826,7 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm,
return -EINVAL;
}
+ setup.out_format = pinfo->out_format;
setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT;
setup.output_width = pinfo->xres + pinfo->lcdc.xres_pad;
setup.output_height = pinfo->yres + pinfo->lcdc.yres_pad;
@@ -1868,6 +1860,7 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
{
struct intf_timing_params *itp = &ctx->itp;
u32 dst_bpp;
+ struct mdss_mdp_format_params *fmt;
struct mdss_data_type *mdata = ctl->mdata;
struct dsc_desc *dsc = NULL;
u32 hdmi_dp_core;
@@ -1902,17 +1895,32 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
}
if (mdss_mdp_is_cdm_supported(mdata, ctl->intf_type, 0)) {
- ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI);
- if (!IS_ERR_OR_NULL(ctl->cdm)) {
- if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo)) {
- pr_err("%s: setting up cdm failed\n",
- __func__);
+
+ fmt = mdss_mdp_get_format_params(pinfo->out_format);
+ if (!fmt) {
+ pr_err("%s: format %d not supported\n", __func__,
+ pinfo->out_format);
+ return -EINVAL;
+ }
+ if (fmt->is_yuv) {
+ ctl->cdm =
+ mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI);
+ if (!IS_ERR_OR_NULL(ctl->cdm)) {
+ if (mdss_mdp_video_cdm_setup(ctl->cdm,
+ pinfo, fmt)) {
+ pr_err("%s: setting up cdm failed\n",
+ __func__);
+ return -EINVAL;
+ }
+ ctl->flush_bits |= BIT(26);
+ } else {
+ pr_err("%s: failed to initialize cdm\n",
+ __func__);
return -EINVAL;
}
- ctl->flush_bits |= BIT(26);
} else {
- pr_err("%s: failed to initialize cdm\n", __func__);
- return -EINVAL;
+ pr_debug("%s: Format is not YUV,cdm not required\n",
+ __func__);
}
} else {
pr_debug("%s: cdm not supported\n", __func__);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
index e6e03e7d54b2..80549908beb6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
@@ -57,6 +57,7 @@ struct mdss_mdp_writeback_ctx {
u16 width;
u16 height;
u16 frame_rate;
+ enum mdss_mdp_csc_type csc_type;
struct mdss_rect dst_rect;
u32 dnsc_factor_w;
@@ -202,17 +203,10 @@ static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx,
}
static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx,
- struct mdss_mdp_cdm *cdm, u32 format)
+ struct mdss_mdp_cdm *cdm, struct mdss_mdp_format_params *fmt)
{
- struct mdss_mdp_format_params *fmt;
struct mdp_cdm_cfg setup;
- fmt = mdss_mdp_get_format_params(format);
- if (!fmt) {
- pr_err("%s: format %d not supported\n", __func__, format);
- return -EINVAL;
- }
-
if (fmt->is_yuv)
setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601L;
else
@@ -237,10 +231,11 @@ static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx,
return -EINVAL;
}
- setup.out_format = format;
+ setup.out_format = fmt->format;
setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT;
setup.output_width = ctx->width;
setup.output_height = ctx->height;
+ setup.csc_type = ctx->csc_type;
return mdss_mdp_cdm_setup(cdm, &setup);
}
@@ -260,10 +255,19 @@ static void mdss_mdp_writeback_cwb_overflow(void *arg)
mdp5_data->cwb.valid = 0;
mdss_mdp_irq_disable_nosync(ctx->intr_type, ctx->intf_num);
+ mdss_mdp_set_intr_callback_nosync(ctx->intr_type, ctx->intf_num,
+ NULL, NULL);
+
mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0);
- if (mdss_mdp_get_split_ctl(ctl))
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
+ CWB_PPB_0, NULL, NULL);
+
+ if (mdss_mdp_get_split_ctl(ctl)) {
mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
- CWB_PPB_1);
+ CWB_PPB_1);
+ mdss_mdp_set_intr_callback_nosync(
+ MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1, NULL, NULL);
+ }
if (!atomic_add_unless(&mdp5_data->wb_busy, -1, 0))
pr_err("Invalid state for WB\n");
@@ -285,10 +289,20 @@ static void mdss_mdp_writeback_cwb_intr_done(void *arg)
mdp5_data->cwb.valid = 0;
mdss_mdp_irq_disable_nosync(ctx->intr_type, ctx->intf_num);
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0);
- if (mdss_mdp_get_split_ctl(ctl))
+ mdss_mdp_set_intr_callback_nosync(ctx->intr_type, ctx->intf_num,
+ NULL, NULL);
+
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
+ CWB_PPB_0);
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
+ CWB_PPB_0, NULL, NULL);
+
+ if (mdss_mdp_get_split_ctl(ctl)) {
mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
- CWB_PPB_1);
+ CWB_PPB_1);
+ mdss_mdp_set_intr_callback_nosync(
+ MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1, NULL, NULL);
+ }
queue_work(mdp5_data->cwb.cwb_work_queue, &mdp5_data->cwb.cwb_work);
@@ -353,10 +367,9 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx,
chroma_samp = fmt->chroma_sample;
if (ctl->cdm) {
-
- rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, format);
+ rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, fmt);
if (rc) {
- pr_err("%s: CDM configuration failed with error %d\n",
+ pr_err("%s: CDM config failed with error %d\n",
__func__, rc);
return rc;
}
@@ -495,21 +508,20 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl,
pr_err("cwb writeback data setup error\n");
return ret;
}
- mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
mdss_mdp_writeback_cwb_intr_done, ctl);
+ mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, ctl->intf_num);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
- ctl->intf_num,
- mdss_mdp_writeback_cwb_overflow, ctl);
+ CWB_PPB_0, mdss_mdp_writeback_cwb_overflow, ctl);
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0);
+
sctl = mdss_mdp_get_split_ctl(ctl);
if (sctl) {
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
- sctl->intf_num);
mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
- sctl->intf_num,
- mdss_mdp_writeback_cwb_overflow, sctl);
+ CWB_PPB_1, mdss_mdp_writeback_cwb_overflow,
+ sctl);
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1);
}
if (test_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, ctl->mdata->mdss_qos_map))
@@ -544,6 +556,7 @@ static int mdss_mdp_writeback_prepare_wfd(struct mdss_mdp_ctl *ctl, void *arg)
ctx->width = ctl->width;
ctx->height = ctl->height;
ctx->frame_rate = ctl->frame_rate;
+ ctx->csc_type = ctl->csc_type;
ctx->dst_rect.x = 0;
ctx->dst_rect.y = 0;
ctx->dst_rect.w = ctx->width;
@@ -1014,6 +1027,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
struct mdss_mdp_writeback_ctx *ctx;
struct mdss_mdp_writeback *wb;
u32 mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED;
+ struct mdss_mdp_format_params *fmt = NULL;
bool is_rot;
pr_debug("start ctl=%d\n", ctl->num);
@@ -1037,6 +1051,10 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
return -EINVAL;
}
+ fmt = mdss_mdp_get_format_params(ctl->dst_format);
+ if (!fmt)
+ return -EINVAL;
+
is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ? true : false;
if (ctl->mixer_left) {
@@ -1050,15 +1068,13 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
}
if (mdss_mdp_is_cdm_supported(ctl->mdata, ctl->intf_type,
- mixer_type)) {
+ mixer_type) && fmt->is_yuv) {
ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_WB);
if (IS_ERR_OR_NULL(ctl->cdm)) {
- pr_err("%s failed to init cdm\n", __func__);
+ pr_err("cdm block already in use\n");
+ ctl->cdm = NULL;
return -EBUSY;
}
- } else {
- ctl->cdm = NULL;
- pr_debug("%s: cdm not supported\n", __func__);
}
ctl->priv_data = ctx;
ctx->wb_num = wb->num;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 73350b3a5a6f..3fc8e3883250 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -71,6 +71,7 @@ static void mdss_mdp_disable_destination_scaler_setup(struct mdss_mdp_ctl *ctl)
{
struct mdss_data_type *mdata = ctl->mdata;
struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;
+ struct mdss_mdp_ctl *split_ctl;
if (test_bit(MDSS_CAPS_DEST_SCALER, mdata->mdss_caps_map)) {
if (ctl->mixer_left && ctl->mixer_right &&
@@ -80,9 +81,11 @@ static void mdss_mdp_disable_destination_scaler_setup(struct mdss_mdp_ctl *ctl)
/*
* DUAL mode disable
*/
+ split_ctl = mdss_mdp_get_split_ctl(ctl);
ctl->mixer_left->width = get_panel_width(ctl);
ctl->mixer_left->height = get_panel_yres(pinfo);
- ctl->mixer_left->width /= 2;
+ if (!split_ctl)
+ ctl->mixer_left->width /= 2;
ctl->mixer_right->width = ctl->mixer_left->width;
ctl->mixer_right->height = ctl->mixer_left->height;
ctl->mixer_left->roi = (struct mdss_rect) { 0, 0,
@@ -2136,7 +2139,7 @@ static int __validate_multirect(struct msm_fb_data_type *mfd,
static int __validate_layers(struct msm_fb_data_type *mfd,
struct file *file, struct mdp_layer_commit_v1 *commit)
{
- int ret, i;
+ int ret, i = 0;
int rec_ndx[MDSS_MDP_PIPE_MAX_RECTS] = { 0 };
int rec_release_ndx[MDSS_MDP_PIPE_MAX_RECTS] = { 0 };
int rec_destroy_ndx[MDSS_MDP_PIPE_MAX_RECTS] = { 0 };
@@ -2660,13 +2663,22 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd,
if (mdp5_data->cwb.valid) {
struct sync_fence *retire_fence = NULL;
+ if (!commit->output_layer) {
+ pr_err("cwb request without setting output layer\n");
+ goto map_err;
+ }
+
retire_fence = __create_fence(mfd,
&mdp5_data->cwb.cwb_sync_pt_data,
MDSS_MDP_CWB_RETIRE_FENCE,
&commit->output_layer->buffer.fence, 0);
if (IS_ERR_OR_NULL(retire_fence)) {
pr_err("failed to handle cwb fence");
+ goto map_err;
}
+
+ sync_fence_install(retire_fence,
+ commit->output_layer->buffer.fence);
}
map_err:
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 6ba5828479f5..0203c0e69e3f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1404,14 +1404,6 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
mdss_iommu_ctrl(0);
}
- /* Restore any previously configured PP features by resetting the dirty
- * bits for enabled features. The dirty bits will be consumed during the
- * first display commit when the PP hardware blocks are updated
- */
- rc = mdss_mdp_pp_resume(mfd);
- if (rc && (rc != -EPERM) && (rc != -ENODEV))
- pr_err("PP resume err %d\n", rc);
-
/*
* Increment the overlay active count prior to calling ctl_start.
* This is needed to ensure that if idle power collapse kicks in
@@ -1427,6 +1419,14 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
goto ctl_error;
}
+ /* Restore any previously configured PP features by resetting the dirty
+ * bits for enabled features. The dirty bits will be consumed during the
+ * first display commit when the PP hardware blocks are updated
+ */
+ rc = mdss_mdp_pp_resume(mfd);
+ if (rc && (rc != -EPERM) && (rc != -ENODEV))
+ pr_err("PP resume err %d\n", rc);
+
rc = mdss_mdp_splash_cleanup(mfd, true);
if (!rc)
goto end;
@@ -3765,6 +3765,9 @@ static ssize_t mdss_mdp_misr_store(struct device *dev,
return rc;
}
+ req.block_id = DISPLAY_MISR_MAX;
+ sreq.block_id = DISPLAY_MISR_MAX;
+
pr_debug("intf_type:%d enable:%d\n", ctl->intf_type, enable_misr);
if (ctl->intf_type == MDSS_INTF_DSI) {
@@ -4402,9 +4405,7 @@ static int mdss_bl_scale_config(struct msm_fb_data_type *mfd,
mutex_lock(&mfd->bl_lock);
curr_bl = mfd->bl_level;
mfd->bl_scale = data->scale;
- mfd->bl_min_lvl = data->min_lvl;
- pr_debug("update scale = %d, min_lvl = %d\n", mfd->bl_scale,
- mfd->bl_min_lvl);
+ pr_debug("update scale = %d\n", mfd->bl_scale);
/* update current backlight to use new scaling*/
mdss_fb_set_backlight(mfd, curr_bl);
@@ -4614,6 +4615,20 @@ static int mdss_fb_set_metadata(struct msm_fb_data_type *mfd,
return ret;
}
+static int mdss_fb_set_panel_ppm(struct msm_fb_data_type *mfd, s32 ppm)
+{
+ struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
+ int ret = 0;
+
+ if (!ctl)
+ return -EPERM;
+
+ ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UPDATE_PANEL_PPM,
+ (void *) (unsigned long) ppm,
+ CTL_INTF_EVENT_FLAG_DEFAULT);
+ return ret;
+}
+
static int mdss_fb_get_hw_caps(struct msm_fb_data_type *mfd,
struct mdss_hw_caps *caps)
{
@@ -5160,6 +5175,16 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
}
ret = mdss_mdp_set_cfg(mfd, &cfg);
break;
+ case MSMFB_MDP_SET_PANEL_PPM:
+ ret = copy_from_user(&val, argp, sizeof(val));
+ if (ret) {
+ pr_err("copy failed MSMFB_MDP_SET_PANEL_PPM ret %d\n",
+ ret);
+ ret = -EFAULT;
+ break;
+ }
+ ret = mdss_fb_set_panel_ppm(mfd, val);
+ break;
default:
break;
@@ -6148,8 +6173,8 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
/* Adding event timer only for primary panel */
if ((mfd->index == 0) && (mfd->panel_info->type != WRITEBACK_PANEL)) {
- mdp5_data->cpu_pm_hdl = add_event_timer(mdss_irq->irq, NULL,
- (void *)mdp5_data);
+ mdp5_data->cpu_pm_hdl = add_event_timer(mdss_irq->irq,
+ mdss_mdp_ctl_event_timer, (void *)mdp5_data);
if (!mdp5_data->cpu_pm_hdl)
pr_warn("%s: unable to add event timer\n", __func__);
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index d7678e4d2ae5..94e64dd396d5 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -2599,7 +2599,8 @@ static int mdss_mdp_set_ts_pipe(struct mdss_mdp_pipe *pipe)
__get_ordered_rects(pipe, &low_pipe, &high_pipe);
ts_count_low = __get_ts_count(low_pipe, mixer, true);
- ts_count_high = __get_ts_count(high_pipe, mixer, false);
+ if (high_pipe != NULL)
+ ts_count_high = __get_ts_count(high_pipe, mixer, false);
ts_bytes = __get_ts_bytes(pipe, mixer);
if (low_pipe->multirect.num == MDSS_MDP_PIPE_RECT0) {
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index 248492b28ce2..5a8438caba4b 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -2519,7 +2519,9 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
DSPP);
}
- pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode);
+ if (pp_sts != NULL)
+ pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev,
+ &opmode);
if (ad_hw) {
mutex_lock(&ad->lock);
@@ -6984,9 +6986,6 @@ static int is_valid_calib_addr(void *addr, u32 operation)
int ret = 0;
char __iomem *ptr = addr;
char __iomem *mixer_base = mdss_res->mixer_intf->base;
- char __iomem *rgb_base = mdss_res->rgb_pipes->base;
- char __iomem *dma_base = mdss_res->dma_pipes->base;
- char __iomem *vig_base = mdss_res->vig_pipes->base;
char __iomem *ctl_base = mdss_res->ctl_off->base;
char __iomem *dspp_base = mdss_res->mixer_intf->dspp_base;
@@ -7018,17 +7017,20 @@ static int is_valid_calib_addr(void *addr, u32 operation)
if (ret)
goto valid_addr;
}
- if (ptr >= vig_base) {
+ if (mdss_res->vig_pipes &&
+ ptr >= mdss_res->vig_pipes->base) {
ret = is_valid_calib_vig_addr(ptr);
if (ret)
goto valid_addr;
}
- if (ptr >= rgb_base) {
+ if (mdss_res->rgb_pipes &&
+ ptr >= mdss_res->rgb_pipes->base) {
ret = is_valid_calib_rgb_addr(ptr);
if (ret)
goto valid_addr;
}
- if (ptr >= dma_base) {
+ if (mdss_res->dma_pipes &&
+ ptr >= mdss_res->dma_pipes->base) {
ret = is_valid_calib_dma_addr(ptr);
if (ret)
goto valid_addr;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c
index 199c2b66d90e..c14840ffd08d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_util.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_util.c
@@ -573,13 +573,6 @@ int mdss_mdp_get_plane_sizes(struct mdss_mdp_format_params *fmt, u32 w, u32 h,
chroma_samp = fmt->chroma_sample;
- if (rotation) {
- if (chroma_samp == MDSS_MDP_CHROMA_H2V1)
- chroma_samp = MDSS_MDP_CHROMA_H1V2;
- else if (chroma_samp == MDSS_MDP_CHROMA_H1V2)
- chroma_samp = MDSS_MDP_CHROMA_H2V1;
- }
-
mdss_mdp_get_v_h_subsample_rate(chroma_samp,
&v_subsample, &h_subsample);
@@ -1027,7 +1020,7 @@ static int mdss_mdp_get_img(struct msmfb_data *img,
} else if (iclient) {
if (mdss_mdp_is_map_needed(mdata, data)) {
data->srcp_dma_buf = dma_buf_get(img->memory_id);
- if (IS_ERR(data->srcp_dma_buf)) {
+ if (IS_ERR_OR_NULL(data->srcp_dma_buf)) {
pr_err("error on ion_import_fd\n");
ret = PTR_ERR(data->srcp_dma_buf);
data->srcp_dma_buf = NULL;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_wfd.c b/drivers/video/fbdev/msm/mdss_mdp_wfd.c
index f04450e9974c..71a07f6b7d39 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_wfd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_wfd.c
@@ -152,6 +152,7 @@ int mdss_mdp_wfd_setup(struct mdss_mdp_wfd *wfd,
u32 wb_idx = layer->writeback_ndx;
struct mdss_mdp_ctl *ctl = wfd->ctl;
struct mdss_mdp_writeback *wb = NULL;
+ struct mdss_mdp_format_params *fmt = NULL;
int ret = 0;
u32 width, height, max_mixer_width;
@@ -192,6 +193,32 @@ int mdss_mdp_wfd_setup(struct mdss_mdp_wfd *wfd,
ctl->roi = (struct mdss_rect) {0, 0, width, height};
ctl->is_secure = (layer->flags & MDP_LAYER_SECURE_SESSION);
+ fmt = mdss_mdp_get_format_params(layer->buffer.format);
+
+ if (fmt == NULL) {
+ pr_err("invalid buffer format\n");
+ ret = -EINVAL;
+ goto wfd_setup_error;
+ }
+
+ /* only 3 csc type supported */
+ if (fmt->is_yuv) {
+ switch (layer->color_space) {
+ case MDP_CSC_ITU_R_601:
+ ctl->csc_type = MDSS_MDP_CSC_RGB2YUV_601L;
+ break;
+ case MDP_CSC_ITU_R_709:
+ ctl->csc_type = MDSS_MDP_CSC_RGB2YUV_709L;
+ break;
+ case MDP_CSC_ITU_R_601_FR:
+ default:
+ ctl->csc_type = MDSS_MDP_CSC_RGB2YUV_601FR;
+ break;
+ }
+ } else {
+ ctl->csc_type = MDSS_MDP_CSC_RGB2RGB;
+ }
+
if (ctl->mdata->wfd_mode == MDSS_MDP_WFD_INTERFACE) {
ctl->mixer_left = mdss_mdp_mixer_alloc(ctl,
MDSS_MDP_MIXER_TYPE_INTF, (width > max_mixer_width), 0);
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 0483e3d42873..25ae326ebbc3 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -255,6 +255,8 @@ struct mdss_intf_recovery {
* Argument provided is new panel timing.
* @MDSS_EVENT_DEEP_COLOR: Set deep color.
* Argument provided is bits per pixel (8/10/12)
+ * @MDSS_EVENT_UPDATE_PANEL_PPM: update pixel clock by input PPM.
+ * Argument provided is parts per million.
*/
enum mdss_intf_events {
MDSS_EVENT_RESET = 1,
@@ -287,6 +289,7 @@ enum mdss_intf_events {
MDSS_EVENT_PANEL_TIMING_SWITCH,
MDSS_EVENT_DEEP_COLOR,
MDSS_EVENT_DISABLE_PANEL,
+ MDSS_EVENT_UPDATE_PANEL_PPM,
MDSS_EVENT_MAX,
};
@@ -761,6 +764,7 @@ struct mdss_panel_info {
bool ulps_suspend_enabled;
bool panel_ack_disabled;
bool esd_check_enabled;
+ bool allow_phy_power_off;
char dfps_update;
/* new requested fps before it is updated in hw */
int new_fps;
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index 0c43a2642ede..fdd888edc2fb 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -960,13 +960,22 @@ static void mdss_dsi_8996_phy_power_off(
static void mdss_dsi_phy_power_off(
struct mdss_dsi_ctrl_pdata *ctrl)
{
+ struct mdss_panel_info *pinfo;
+
if (ctrl->phy_power_off)
return;
- /* supported for phy rev 2.0 */
- if (ctrl->shared_data->phy_rev != DSI_PHY_REV_20)
+ pinfo = &ctrl->panel_data.panel_info;
+
+ if ((ctrl->shared_data->phy_rev != DSI_PHY_REV_20) ||
+ !pinfo->allow_phy_power_off) {
+ pr_debug("%s: ctrl%d phy rev:%d panel support for phy off:%d\n",
+ __func__, ctrl->ndx, ctrl->shared_data->phy_rev,
+ pinfo->allow_phy_power_off);
return;
+ }
+ /* supported for phy rev 2.0 and if panel allows it*/
mdss_dsi_8996_phy_power_off(ctrl);
ctrl->phy_power_off = true;
@@ -1003,7 +1012,7 @@ static void mdss_dsi_8996_phy_power_on(
static void mdss_dsi_phy_power_on(
struct mdss_dsi_ctrl_pdata *ctrl, bool mmss_clamp)
{
- if (mmss_clamp && (ctrl->shared_data->phy_rev != DSI_PHY_REV_20))
+ if (mmss_clamp && !ctrl->phy_power_off)
mdss_dsi_phy_init(ctrl);
else if ((ctrl->shared_data->phy_rev == DSI_PHY_REV_20) &&
ctrl->phy_power_off)
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index fd2eb059b991..aed90a4902c7 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -32,6 +32,7 @@
#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
#define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */
+#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
struct clk;
struct clk_hw;
@@ -787,7 +788,8 @@ int of_clk_get_parent_count(struct device_node *np);
int of_clk_parent_fill(struct device_node *np, const char **parents,
unsigned int size);
const char *of_clk_get_parent_name(struct device_node *np, int index);
-
+int of_clk_detect_critical(struct device_node *np, int index,
+ unsigned long *flags);
void of_clk_init(const struct of_device_id *matches);
#else /* !CONFIG_OF */
@@ -825,6 +827,13 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
{
return NULL;
}
+
+static inline int of_clk_detect_critical(struct device_node *np, int index,
+ unsigned long *flags)
+{
+ return 0;
+}
+
#define of_clk_init(matches) \
{ while (0); }
#endif /* CONFIG_OF */
diff --git a/include/net/sock.h b/include/net/sock.h
index fca6e414f844..0e49452f5c48 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -457,6 +457,7 @@ struct sock {
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
+ struct rcu_head sk_rcu;
};
#define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data)))
@@ -739,6 +740,7 @@ enum sock_flags {
*/
SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */
SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
+ SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
};
#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
diff --git a/include/uapi/linux/msm_mdp_ext.h b/include/uapi/linux/msm_mdp_ext.h
index 1a71e860ba48..24f1e7c7b742 100644
--- a/include/uapi/linux/msm_mdp_ext.h
+++ b/include/uapi/linux/msm_mdp_ext.h
@@ -31,6 +31,12 @@
struct mdp_set_cfg)
/*
+ * Ioctl for setting the PLL PPM.
+ * PLL PPM is passed by the user space using this IOCTL.
+ */
+#define MSMFB_MDP_SET_PANEL_PPM _IOW(MDP_IOCTL_MAGIC, 131, int)
+
+/*
* To allow proper structure padding for 64bit/32bit target
*/
#ifdef __LP64
@@ -165,6 +171,8 @@ VALIDATE/COMMIT FLAG CONFIGURATION
#define MDP_COMMIT_VERSION_1_0 0x00010000
+#define OUT_LAYER_COLOR_SPACE
+
/**********************************************************************
Configuration structures
All parameters are input to driver unless mentioned output parameter
@@ -357,8 +365,11 @@ struct mdp_output_layer {
/* Buffer attached with output layer. Device uses it for commit call */
struct mdp_layer_buffer buffer;
+ /* color space of the destination */
+ enum mdp_color_space color_space;
+
/* 32bits reserved value for future usage. */
- uint32_t reserved[6];
+ uint32_t reserved[5];
};
/*
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index b822206ac811..582b66e882ce 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -596,7 +596,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
#ifdef CONFIG_SMP
case PM_QOS_REQ_AFFINE_IRQ:
if (irq_can_set_affinity(req->irq)) {
- int ret = 0;
struct irq_desc *desc = irq_to_desc(req->irq);
struct cpumask *mask = desc->irq_data.common->affinity;
@@ -606,13 +605,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
req->irq_notify.notify = pm_qos_irq_notify;
req->irq_notify.release = pm_qos_irq_release;
- ret = irq_set_affinity_notifier(req->irq,
- &req->irq_notify);
- if (ret) {
- WARN(1, KERN_ERR "IRQ affinity notify set failed\n");
- req->type = PM_QOS_REQ_ALL_CORES;
- cpumask_setall(&req->cpus_affine);
- }
} else {
req->type = PM_QOS_REQ_ALL_CORES;
cpumask_setall(&req->cpus_affine);
@@ -634,6 +626,24 @@ void pm_qos_add_request(struct pm_qos_request *req,
trace_pm_qos_add_request(pm_qos_class, value);
pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
req, PM_QOS_ADD_REQ, value);
+
+#ifdef CONFIG_SMP
+ if (req->type == PM_QOS_REQ_AFFINE_IRQ &&
+ irq_can_set_affinity(req->irq)) {
+ int ret = 0;
+
+ ret = irq_set_affinity_notifier(req->irq,
+ &req->irq_notify);
+ if (ret) {
+ WARN(1, "IRQ affinity notify set failed\n");
+ req->type = PM_QOS_REQ_ALL_CORES;
+ cpumask_setall(&req->cpus_affine);
+ pm_qos_update_target(
+ pm_qos_array[pm_qos_class]->constraints,
+ req, PM_QOS_UPDATE_REQ, value);
+ }
+ }
+#endif
}
EXPORT_SYMBOL_GPL(pm_qos_add_request);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a5d101e8a5f2..f352d06d7673 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5600,7 +5600,6 @@ int do_isolation_work_cpu_stop(void *data)
*/
nohz_balance_clear_nohz_mask(cpu);
- clear_hmp_request(cpu);
local_irq_enable();
return 0;
}
@@ -5682,7 +5681,7 @@ int sched_isolate_cpu(int cpu)
if (trace_sched_isolate_enabled())
start_time = sched_clock();
- lock_device_hotplug();
+ cpu_maps_update_begin();
cpumask_andnot(&avail_cpus, cpu_online_mask, cpu_isolated_mask);
@@ -5725,13 +5724,14 @@ int sched_isolate_cpu(int cpu)
migrate_sync_cpu(cpu, cpumask_first(&avail_cpus));
stop_cpus(cpumask_of(cpu), do_isolation_work_cpu_stop, 0);
+ clear_hmp_request(cpu);
calc_load_migrate(rq);
update_max_interval();
sched_update_group_capacities(cpu);
out:
- unlock_device_hotplug();
+ cpu_maps_update_done();
trace_sched_isolate(cpu, cpumask_bits(cpu_isolated_mask)[0],
start_time, 1);
return ret_code;
@@ -5752,8 +5752,6 @@ int sched_unisolate_cpu_unlocked(int cpu)
if (trace_sched_isolate_enabled())
start_time = sched_clock();
- lock_device_hotplug_assert();
-
if (!cpu_isolation_vote[cpu]) {
ret_code = -EINVAL;
goto out;
@@ -5792,9 +5790,9 @@ int sched_unisolate_cpu(int cpu)
{
int ret_code;
- lock_device_hotplug();
+ cpu_maps_update_begin();
ret_code = sched_unisolate_cpu_unlocked(cpu);
- unlock_device_hotplug();
+ cpu_maps_update_done();
return ret_code;
}
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index 9b21a09ec4ba..aac12bfc2ae6 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -893,14 +893,10 @@ static int __ref cpu_callback(struct notifier_block *nfb,
unsigned int need;
int ret = NOTIFY_OK;
- /* Don't affect suspend resume */
- if (action & CPU_TASKS_FROZEN)
- return NOTIFY_OK;
-
if (unlikely(!cluster || !cluster->inited))
return NOTIFY_OK;
- switch (action) {
+ switch (action & ~CPU_TASKS_FROZEN) {
case CPU_UP_PREPARE:
/* If online state of CPU somehow got out of sync, fix it. */
@@ -1095,7 +1091,7 @@ static int __init core_ctl_init(void)
cpufreq_register_notifier(&cpufreq_pol_nb, CPUFREQ_POLICY_NOTIFIER);
cpufreq_register_notifier(&cpufreq_gov_nb, CPUFREQ_GOVINFO_NOTIFIER);
- lock_device_hotplug();
+ cpu_maps_update_begin();
for_each_online_cpu(cpu) {
struct cpufreq_policy *policy;
int ret;
@@ -1109,7 +1105,7 @@ static int __init core_ctl_init(void)
cpufreq_cpu_put(policy);
}
}
- unlock_device_hotplug();
+ cpu_maps_update_done();
initialized = true;
return 0;
}
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index ad5d115bdd7f..5ff7a11d043f 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -641,14 +641,18 @@ void clear_hmp_request(int cpu)
clear_boost_kick(cpu);
clear_reserved(cpu);
if (rq->push_task) {
+ struct task_struct *push_task = NULL;
+
raw_spin_lock_irqsave(&rq->lock, flags);
if (rq->push_task) {
clear_reserved(rq->push_cpu);
- put_task_struct(rq->push_task);
+ push_task = rq->push_task;
rq->push_task = NULL;
}
rq->active_balance = 0;
raw_spin_unlock_irqrestore(&rq->lock, flags);
+ if (push_task)
+ put_task_struct(push_task);
}
}
diff --git a/net/core/sock.c b/net/core/sock.c
index 0d91f7dca751..fed6f3462c95 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1439,8 +1439,12 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
}
EXPORT_SYMBOL(sk_alloc);
-void sk_destruct(struct sock *sk)
+/* Sockets having SOCK_RCU_FREE will call this function after one RCU
+ * grace period. This is the case for UDP sockets and TCP listeners.
+ */
+static void __sk_destruct(struct rcu_head *head)
{
+ struct sock *sk = container_of(head, struct sock, sk_rcu);
struct sk_filter *filter;
if (sk->sk_destruct)
@@ -1467,6 +1471,14 @@ void sk_destruct(struct sock *sk)
sk_prot_free(sk->sk_prot_creator, sk);
}
+void sk_destruct(struct sock *sk)
+{
+ if (sock_flag(sk, SOCK_RCU_FREE))
+ call_rcu(&sk->sk_rcu, __sk_destruct);
+ else
+ __sk_destruct(&sk->sk_rcu);
+}
+
static void __sk_free(struct sock *sk)
{
if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt))