diff options
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)) |
