diff options
398 files changed, 24080 insertions, 5035 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/clock-controller.txt b/Documentation/devicetree/bindings/arm/msm/clock-controller.txt index 20506e132727..17250cceea4c 100644 --- a/Documentation/devicetree/bindings/arm/msm/clock-controller.txt +++ b/Documentation/devicetree/bindings/arm/msm/clock-controller.txt @@ -65,18 +65,18 @@ Required properties: "qcom,cc-debug-californium" "qcom,gcc-mdm9607" "qcom,cc-debug-mdm9607" - "qcom,gcc-cobalt" - "qcom,gcc-cobalt-v2" + "qcom,gcc-8998" + "qcom,gcc-8998-v2" "qcom,gcc-hamster" - "qcom,cc-debug-cobalt" - "qcom,gpucc-cobalt" - "qcom,gfxcc-cobalt" - "qcom,gpucc-cobalt-v2" - "qcom,gfxcc-cobalt-v2" + "qcom,cc-debug-8998" + "qcom,gpucc-8998" + "qcom,gfxcc-8998" + "qcom,gpucc-8998-v2" + "qcom,gfxcc-8998-v2" "qcom,gpucc-hamster" "qcom,gfxcc-hamster" - "qcom,mmsscc-cobalt" - "qcom,mmsscc-cobalt-v2" + "qcom,mmsscc-8998" + "qcom,mmsscc-8998-v2" "qcom,mmsscc-hamster" - reg: Pairs of physical base addresses and region sizes of diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 7b1c081ef586..de99a5636ef3 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -47,8 +47,8 @@ SoCs: - APQTITANIUM compatible = "qcom,apqtitanium" -- APQCOBALT - compatible = "qcom,apqcobalt" +- APQ8998 + compatible = "qcom,apq8998" - MDM9630 compatible = "qcom,mdm9630" @@ -83,8 +83,8 @@ SoCs: - MSM8996 compatible = "qcom,msm8996" -- MSMCOBALT - compatible = "qcom,msmcobalt" +- MSM8998 + compatible = "qcom,msm8998" - MSMHAMSTER compatible = "qcom,msmhamster" @@ -183,9 +183,9 @@ compatible = "qcom,apq8037-cdp" compatible = "qcom,apq8037-mtp" compatible = "qcom,apqtitanium-cdp" compatible = "qcom,apqtitanium-mtp" -compatible = "qcom,apqcobalt-cdp" -compatible = "qcom,apqcobalt-mtp" -compatible = "qcom,apqcobalt-qrd" +compatible = "qcom,apq8998-cdp" +compatible = "qcom,apq8998-mtp" +compatible = "qcom,apq8998-qrd" compatible = "qcom,mdm9630-cdp" compatible = "qcom,mdm9630-mtp" compatible = "qcom,mdm9630-sim" @@ -252,11 +252,11 @@ compatible = "qcom,msm8996-fluid" compatible = "qcom,msm8996-liquid" compatible = "qcom,msm8996-mtp" compatible = "qcom,msm8996-adp" -compatible = "qcom,msmcobalt-sim" -compatible = "qcom,msmcobalt-rumi" -compatible = "qcom,msmcobalt-cdp" -compatible = "qcom,msmcobalt-mtp" -compatible = "qcom,msmcobalt-qrd" +compatible = "qcom,msm8998-sim" +compatible = "qcom,msm8998-rumi" +compatible = "qcom,msm8998-cdp" +compatible = "qcom,msm8998-mtp" +compatible = "qcom,msm8998-qrd" compatible = "qcom,msmhamster-rumi" compatible = "qcom,msmhamster-cdp" compatible = "qcom,msmhamster-mtp" diff --git a/Documentation/devicetree/bindings/arm/msm/msm_gladiator_hang_detect.txt b/Documentation/devicetree/bindings/arm/msm/msm_gladiator_hang_detect.txt index d35bb84ad2cc..1935a092f857 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm_gladiator_hang_detect.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm_gladiator_hang_detect.txt @@ -31,7 +31,7 @@ Required properties: Optional properties: Example: - For msmcobalt: + For msm8998: qcom,ghd { compatible = "qcom,gladiator-hang-detect"; qcom,threshold-arr = <0x179d141c 0x179d1420 diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt index 782fb6c4124d..a8334e1cfde7 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt @@ -9,8 +9,8 @@ Properties: - compatible Usage: required Value type: <string> - Definition: must be "qcom,cpu-clock-osm-msmcobalt-v1" or - "qcom,cpu-clock-osm-msmcobalt-v2". + Definition: must be "qcom,cpu-clock-osm-msm8998-v1" or + "qcom,cpu-clock-osm-msm8998-v2". - reg Usage: required @@ -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> @@ -342,8 +352,8 @@ Properties: Example: - clock_cpu: qcom,cpu-clock-cobalt@179c0000 { - compatible = "qcom,cpu-clock-osm-msmcobalt-v1"; + clock_cpu: qcom,cpu-clock-8998@179c0000 { + compatible = "qcom,cpu-clock-osm-msm8998-v1"; reg = <0x179C0000 0x4000>, <0x17916000 0x1000>, <0x17816000 0x1000>, diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt index 8b0f7841af8d..6aaf89c47781 100644 --- a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt @@ -10,6 +10,7 @@ Required properties : "qcom,mmcc-msm8960" "qcom,mmcc-msm8974" "qcom,mmcc-msm8996" + "qcom,mmcc-msmfalcon" - reg : shall contain base register location and length - #clock-cells : shall contain 1 diff --git a/Documentation/devicetree/bindings/cnss/icnss.txt b/Documentation/devicetree/bindings/cnss/icnss.txt index 505966fb9226..e19a43446357 100644 --- a/Documentation/devicetree/bindings/cnss/icnss.txt +++ b/Documentation/devicetree/bindings/cnss/icnss.txt @@ -53,6 +53,6 @@ Example: <0 140 0 /* CE10 */ >, <0 141 0 /* CE11 */ >; qcom,wlan-msa-memory = <0x200000>; - vdd-0.8-cx-mx-supply = <&pmcobalt_l5>; + vdd-0.8-cx-mx-supply = <&pm8998_l5>; qcom,vdd-0.8-cx-mx-config = <800000 800000 2400 1000>; }; diff --git a/Documentation/devicetree/bindings/fb/mdss-dp.txt b/Documentation/devicetree/bindings/fb/mdss-dp.txt index 85656e312acc..27516d3b54a5 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dp.txt @@ -59,8 +59,8 @@ Example: qcom,mdss-fb-map = <&mdss_fb3>; gdsc-supply = <&gdsc_mdss>; - vdda-1p2-supply = <&pmcobalt_l2>; - vdda-0p9-supply = <&pmcobalt_l1>; + vdda-1p2-supply = <&pm8998_l2>; + vdda-0p9-supply = <&pm8998_l1>; reg = <0xc990000 0xa84>, <0xc011000 0x910>, 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/fb/mdss-pll.txt b/Documentation/devicetree/bindings/fb/mdss-pll.txt index 37ca97021ed0..945d79825695 100644 --- a/Documentation/devicetree/bindings/fb/mdss-pll.txt +++ b/Documentation/devicetree/bindings/fb/mdss-pll.txt @@ -14,8 +14,8 @@ Required properties: "qcom,mdss_dsi_pll_8996", "qcom,mdss_hdmi_pll_8996", "qcom,mdss_hdmi_pll_8996_v2", "qcom,mdss_dsi_pll_8996_v2", "qcom,mdss_hdmi_pll_8996_v3", "qcom,mdss_hdmi_pll_8996_v3_1p8", - "qcom,mdss_dsi_pll_cobalt", "qcom,mdss_dp_pll_cobalt", - "qcom,mdss_hdmi_pll_cobalt" + "qcom,mdss_dsi_pll_8998", "qcom,mdss_dp_pll_8998", + "qcom,mdss_hdmi_pll_8998" - cell-index: Specifies the controller used - reg: offset and length of the register set for the device. - reg-names : names to refer to register sets related to this device diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt index 8844a816052e..581f1128355c 100644 --- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt +++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt @@ -11,6 +11,8 @@ Main node: Required properties: - compatible : Should be "qcom,qpnp-flash-led-v2" - reg : Base address and size for flash LED modules +- qcom,pmic-revid : phandle of PMIC revid module. This is used to + identify the PMIC subtype. Optional properties: - interrupts : Specifies the interrupts associated with flash-led. @@ -76,6 +78,39 @@ Optional properties: - qcom,thermal-derate-current : Array of currrent limits for thermal mitigation. Required if qcom,thermal-derate-en is specified. Unit is mA. Format is qcom,thermal-derate-current = <OTST1_LIMIT, OTST2_LIMIT, OTST3_LIMIT>. +- qcom,otst-ramp-back-up-dis : Boolean property to disable current ramp + backup after thermal derate trigger is + deasserted. +- qcom,thermal-derate-slow : Integer property to specify slow ramping + down thermal rate. Unit is in uS. Allowed + values are: 128, 256, 512, 1024, 2048, 4096, + 8192 and 314592. +- qcom,thermal-derate-fast : Integer property to specify fast ramping + down thermal rate. Unit is in uS. Allowed + values are: 32, 64, 96, 128, 256, 384 and + 512. +- qcom,thermal-debounce : Integer property to specify thermal debounce + time. It is only used if qcom,thermal-derate-en + is specified. Unit is in uS. Allowed values + are: 0, 16, 32, 64. +- qcom,thermal-hysteresis : Integer property to specify thermal derating + hysteresis. Unit is in deciDegC. It is only + used if qcom,thermal-derate-en is specified. + Allowed values are: + 0, 15, 30, 45 for pmi8998. + 0, 20, 40, 60 for pm2falcon. +- qcom,thermal-thrsh1 : Integer property to specify OTST1 threshold + for thermal mitigation. Unit is in Celsius. + Accepted values are: + 85, 79, 73, 67, 109, 103, 97, 91. +- qcom,thermal-thrsh2 : Integer property to specify OTST2 threshold + for thermal mitigation. Unit is in Celsius. + Accepted values are: + 110, 104, 98, 92, 134, 128, 122, 116. +- qcom,thermal-thrsh3 : Integer property to specify OTST3 threshold + for thermal mitigation. Unit is in Celsius. + Accepted values are: + 125, 119, 113, 107, 149, 143, 137, 131. - qcom,hw-strobe-option : Integer type to specify hardware strobe option. Based on the specified value, additional GPIO configuration may be required to provide strobing support. Supported values are: @@ -165,7 +200,7 @@ Example: qcom,hdrm-auto-mode; qcom,isc-delay = <192>; - switch0-supply = <&pmicobalt_bob>; + switch0-supply = <&pmi8998_bob>; pmi8998_flash0: qcom,flash_0 { label = "flash"; diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt index ebbcfe5b2fd0..74cee0d6ba0d 100644 --- a/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt +++ b/Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt @@ -25,12 +25,16 @@ Optional properties for WLED: - linux,default-trigger : trigger for the backlight. default is NONE. - qcom,fdbk-output : string feedback current output for wled module. The accepted values are "wled1", "wled2", "wled3", "wled4" and "auto". default is "auto". -- qcom,vref-mv : maximum reference voltage in mv. default is 350. +- qcom,vref-uv : maximum reference voltage in uV. + For pmi8994/8952/8996, supported values are from 300000 to 675000 + with a step size of 25000, the default value is 350000. + For pmi8998/pm2falcon, supported values are from 60000 to 397500 + with a step size of 22500, the default value is 127500. - qcom,switch-freq-khz : switch frequency in khz. default is 800. - qcom,ovp-mv : Over voltage protection threshold in mV. Default is 29500. Supported values are: - 31000, 29500, 19400, 17800 for pmi8994/8952/8996. - - 31100, 29600, 19600, 18100 for pmicobalt/pm2falcon. + - 31100, 29600, 19600, 18100 for pmi8998/pm2falcon. Should only be used if qcom,disp-type-amoled is not specified. - qcom,ilim-ma : Current limit threshold in mA. @@ -38,7 +42,7 @@ Optional properties for WLED: and AMOLED is 385mA. Supported values are: - 105, 385, 660, 980, 1150, 1420, 1700, 1980. - For pmicobalt/pm2falcon, default value for LCD is + For pmi8998/pm2falcon, default value for LCD is 970mA and AMOLED is 620mA. Supported values are: - 105, 280, 450, 620, 970, 1150, 1300, 1500. @@ -64,14 +68,20 @@ Optional properties for WLED: - qcom,cons-sync-write-delay-us : Specify in 'us' the duration of delay between two consecutive writes to SYNC register. - qcom,sc-deb-cycles : debounce time for short circuit detection +- qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. +- qcom,loop-auto-gm-en : A boolean property to specify if auto gm is enabled. +- qcom,loop-auto-gm-thresh : Specify auto gm threshold if "loop-auto-gm-en" is defined. + Supported values are: 0 - 3. +- qcom,lcd-auto-pfm-thresh : Specify the auto-pfm threshold, if the headroom voltage level + falls below this threshold and auto PFM is enabled, boost + controller will enter into PFM mode automatically. Optional properties if 'qcom,disp-type-amoled' is mentioned in DT: -- qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. - qcom,loop-comp-res-kohm : control to select the compensation resistor in kohm. default is 320. - qcom,vref-psm-mv : reference psm voltage in mv. default for amoled is 450. - qcom,avdd-mode-spmi: Boolean property to enable AMOLED_VOUT programming via SPMI. If not specified, AMOLED_VOUT is programmed via S-wire. This can be specified only for newer - PMICs like pmicobalt/pm2falcon. + PMICs like pmi8998/pm2falcon. - qcom,avdd-target-voltage-mv: The voltage required for AMOLED_VOUT. Accepted values are in the range of 5650 to 7900 in steps of 150. Default value is 7600. Unit is in mV. For old revisions, accepted values are: 7900, 7600, 7300, 6400, 6100, @@ -94,7 +104,7 @@ Example: linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <350000>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29500>; qcom,ilim-ma = <980>; diff --git a/Documentation/devicetree/bindings/media/video/msm-cpp.txt b/Documentation/devicetree/bindings/media/video/msm-cpp.txt index 52abf409cb65..ade5fbe8cbd7 100644 --- a/Documentation/devicetree/bindings/media/video/msm-cpp.txt +++ b/Documentation/devicetree/bindings/media/video/msm-cpp.txt @@ -26,6 +26,8 @@ Required properties: and reset lines used by this controller. - reset-names: reset signal name strings sorted in the same order as the resets property. +- qcom,src-clock-rates = This is an array which holds clock rates for cpp src + clocks. The maximum size for the array is 10. Required properties of the child node: - qcom,stripe-base = Base offset of stripes in cpp payload. @@ -107,6 +109,8 @@ Example: <0x24 0x10000000>, <0x28 0x10000000>, <0x2C 0x10000000>; + qcom,src-clock-rates = <100000000 200000000 384000000 404000000 + 480000000 576000000 600000000>; qcom,cpp-fw-payload-info { qcom,stripe-base = <553>; qcom,plane-base = <481>; diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt index b1869803d345..50b9b1ac8704 100644 --- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt +++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt @@ -183,6 +183,9 @@ Optional properties: - qcom,bus-rage-kbps : an array of two items (<min max>) that indicate the minimum and maximum acceptable votes for the bus. In the absence of this property <0 INT_MAX> is used. +- qcom,ubwc-10bit : UBWC 10 bit content has different bus requirements, + this tag will be used to pick the appropriate bus as per the session profile + as shown below in example. Example: @@ -270,4 +273,17 @@ Example: qcom,bus-governor = "msm-vidc-ddr"; qcom,bus-range-kbps = <1000 3388000>; }; + qcom,profile-dec-ubwc-10bit { + qcom,codec-mask = <0xffffffff>; + qcom,ubwc-10bit; + qcom,load-busfreq-tbl = + <979200 2446336>, /* UHD30D */ + <864000 2108416>, /* 720p240D */ + <489600 1207296>, /* 1080p60D */ + <432000 1058816>, /* 720p120D */ + <244800 616448>, /* 1080p30D */ + <216000 534528>, /* 720p60D */ + <108000 271360>, /* 720p30D */ + <0 0>; + }; }; diff --git a/Documentation/devicetree/bindings/nfc/nq-nci.txt b/Documentation/devicetree/bindings/nfc/nq-nci.txt index af8b81e56333..b85e0701bbae 100644 --- a/Documentation/devicetree/bindings/nfc/nq-nci.txt +++ b/Documentation/devicetree/bindings/nfc/nq-nci.txt @@ -34,7 +34,7 @@ Example: qcom,nq-irq = <&tlmm 29 0x00>; qcom,nq-ven = <&tlmm 30 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; qcom,clk-src = "BBCLK2"; interrupt-parent = <&tlmm>; diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt index 4f5e0a117b2d..421379116989 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt +++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt @@ -275,12 +275,12 @@ Second Level Nodes - Peripherals managed by FG Gen3 driver Example ======== -pmicobalt_fg: qpnp,fg { +pmi8998_fg: qpnp,fg { compatible = "qcom,fg-gen3"; #address-cells = <1>; #size-cells = <1>; - qcom,pmic-revid = <&pmicobalt_revid>; - io-channels = <&pmicobalt_rradc 3>; + qcom,pmic-revid = <&pmi8998_revid>; + io-channels = <&pmi8998_rradc 3>; io-channel-names = "rradc_batt_id"; qcom,ki-coeff-soc-dischg = <30 60 90>; qcom,ki-coeff-med-dischg = <800 1000 1400>; diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt index 438bd68b0e05..96b7dd517231 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt +++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt @@ -28,5 +28,5 @@ Example: reg = <0x1500 0x100>; interrupts = <0x2 0x15 0x0 IRQ_TYPE_NONE>; interrupt-names = "ptrain-done"; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; }; diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt index 7090426c68f8..382587ea5922 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt @@ -138,6 +138,14 @@ Charger specific properties: then charge inhibit will be disabled by default. Allowed values are: 50, 100, 200, 300. +- qcom,auto-recharge-soc + Usage: optional + Value type: <empty> + Definition: Specifies if automatic recharge needs to be based off battery + SOC. If this property is not specified, then auto recharge will + be based off battery voltage. For both SOC and battery voltage, + charger receives the signal from FG to resume charging. + ============================================= Second Level Nodes - SMB2 Charger Peripherals ============================================= @@ -163,7 +171,7 @@ Peripheral specific properties: Example ======= -pmicobalt_charger: qcom,qpnp-smb2 { +pmi8998_charger: qcom,qpnp-smb2 { compatible = "qcom,qpnp-smb2"; #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/qbt1000/qbt1000.txt b/Documentation/devicetree/bindings/qbt1000/qbt1000.txt index c9861e4948f9..4a18b79e9ba1 100644 --- a/Documentation/devicetree/bindings/qbt1000/qbt1000.txt +++ b/Documentation/devicetree/bindings/qbt1000/qbt1000.txt @@ -50,5 +50,5 @@ qcom,qbt1000 { <&clock_gcc clk_gcc_blsp2_ahb_clk>; clock-frequency = <15000000>; qcom,ipc-gpio = <&tlmm 121 0>; - qcom,finger-detect-gpio = <&pmcobalt_gpios 2 0>; + qcom,finger-detect-gpio = <&pm8998_gpios 2 0>; }; diff --git a/Documentation/devicetree/bindings/qdsp/msm-ssc-sensors.txt b/Documentation/devicetree/bindings/qdsp/msm-ssc-sensors.txt index ea671a1ff14a..2fb34fd16258 100644 --- a/Documentation/devicetree/bindings/qdsp/msm-ssc-sensors.txt +++ b/Documentation/devicetree/bindings/qdsp/msm-ssc-sensors.txt @@ -8,7 +8,7 @@ Required properties: - qcom,firmware-name: SLPI firmware name, must be "slpi_v1" or "slpi_v2" Example: - The following for msmcobalt version 1. + The following for msm8998 version 1. qcom,msm-ssc-sensors { compatible = "qcom,msm-ssc-sensors"; diff --git a/Documentation/devicetree/bindings/regulator/cpr3-mmss-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr3-mmss-regulator.txt index 19873f877a30..baa0cd2d6f1a 100644 --- a/Documentation/devicetree/bindings/regulator/cpr3-mmss-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/cpr3-mmss-regulator.txt @@ -33,12 +33,12 @@ MMSS specific properties: "qcom,cpr3-msm8996-v3-mmss-regulator", "qcom,cpr3-msm8996-mmss-regulator", "qcom,cpr3-msm8996pro-mmss-regulator", - "qcom,cpr4-msmcobalt-v1-mmss-regulator", - "qcom,cpr4-msmcobalt-v2-mmss-regulator", - "qcom,cpr4-msmcobalt-mmss-regulator". + "qcom,cpr4-msm8998-v1-mmss-regulator", + "qcom,cpr4-msm8998-v2-mmss-regulator", + "qcom,cpr4-msm8998-mmss-regulator". If the SoC revision is not specified, then it is assumed to be the most recent revision (i.e v3 for MSM8996 and v2 - for MSMCOBALT). + for MSM8998). - clocks Usage: required @@ -55,7 +55,7 @@ MMSS specific properties: specified in the 'clocks' property. "core_clk", "iface_clk", and "bus_clk" must be specified. Note that "iface_clk" is not required for devices with compatible = - "qcom,cpr4-msmcobalt-mmss-regulator". + "qcom,cpr4-msm8998-mmss-regulator". - qcom,cpr-temp-point-map Usage: Required if qcom,corner-allow-temp-adjustment is specified @@ -77,7 +77,7 @@ MMSS specific properties: - qcom,cpr-step-quot-fixed Usage: Optional for controllers with compatible = - "qcom,cpr4-msmcobalt-mmss-regulator"; unsupported for + "qcom,cpr4-msm8998-mmss-regulator"; unsupported for all others. Value type: <u32> Definition: Fixed step quotient value used by controller for applying @@ -200,7 +200,7 @@ MMSS specific properties: - qcom,corner-allow-temp-adjustment Usage: Optional for controllers with compatible = - "qcom,cpr4-msmcobalt-mmss-regulator"; unsupported for + "qcom,cpr4-msm8998-mmss-regulator"; unsupported for all others. Value type: <prop-encoded-array> Definition: A list of integer tuples which each define the CPR diff --git a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt index b286b0838643..5b0770785dbe 100644 --- a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt @@ -31,11 +31,11 @@ KBSS specific properties: Usage: required Value type: <string> Definition: should be one of the following: - "qcom,cprh-msmcobalt-v1-kbss-regulator", - "qcom,cprh-msmcobalt-v2-kbss-regulator", - "qcom,cprh-msmcobalt-kbss-regulator". + "qcom,cprh-msm8998-v1-kbss-regulator", + "qcom,cprh-msm8998-v2-kbss-regulator", + "qcom,cprh-msm8998-kbss-regulator". If the SoC revision is not specified, then it is assumed to - be the most recent revision of MSMCOBALT, i.e. v2. + be the most recent revision of MSM8998, i.e. v2. - qcom,cpr-controller-id Usage: required @@ -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> @@ -335,7 +353,7 @@ Example ======= apc0_cpr: cprh-ctrl@179c8000 { - compatible = "qcom,cprh-msmcobalt-kbss-regulator"; + compatible = "qcom,cprh-msm8998-kbss-regulator"; reg = <0x179c8000 0x4000>, <0x00784000 0x1000>; reg-names = "cpr_ctrl", "fuse_base"; clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>; diff --git a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt index 0545f6b7b59a..c039caca22c8 100644 --- a/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qpnp-labibb-regulator.txt @@ -98,7 +98,7 @@ LAB subnode required properties: - interrupts: Specify the interrupts as per the interrupt encoding. Currently "lab-vreg-ok" is required for - LCD mode in pmicobalt. For AMOLED mode, + LCD mode in pmi8998. For AMOLED mode, "lab-vreg-ok" is required only when SWIRE control is enabled and skipping 2nd SWIRE pulse is required in pmi8952/8996. diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index c3d58ce2c864..336b9f0087a5 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -2289,11 +2289,11 @@ Example: "SpkrRight", "SpkrLeft"; }; -* MSMCOBALT ASoC Machine driver +* MSM8998 ASoC Machine driver Required properties: -- compatible : "qcom,msmcobalt-asoc-snd-tasha" for tasha codec, - "qcom,msmcobalt-asoc-snd-tavil" for tavil codec. +- compatible : "qcom,msm8998-asoc-snd-tasha" for tasha codec, + "qcom,msm8998-asoc-snd-tavil" for tavil codec. - qcom,model : The user-visible name of this sound card. - qcom,tasha-mclk-clk-freq : MCLK frequency value for tasha codec - qcom,tavil-mclk-clk-freq : MCLK frequency value for tavil codec @@ -2333,8 +2333,8 @@ Optional properties: Example: sound-9335 { - compatible = "qcom,msmcobalt-asoc-snd"; - qcom,model = "msmcobalt-tasha-snd-card"; + compatible = "qcom,msm8998-asoc-snd"; + qcom,model = "msm8998-tasha-snd-card"; qcom,audio-routing = "RX_BIAS", "MCLK", @@ -2407,7 +2407,7 @@ Example: * MSMSTUB ASoC Machine driver Required properties: -- compatible : "qcom,msmcobalt-asoc-snd-stub" +- compatible : "qcom,msm8998-asoc-snd-stub" - qcom,model : The user-visible name of this sound card. - qcom,tasha-mclk-clk-freq : MCLK frequency value for tasha codec - asoc-platform: This is phandle list containing the references to platform device @@ -2433,8 +2433,8 @@ Optional properties: Example: sound_msm:sound-9335 { - compatible = "qcom,msmcobalt-asoc-snd"; - qcom,model = "msmcobalt-stub-snd-card"; + compatible = "qcom,msm8998-asoc-snd"; + qcom,model = "msm8998-stub-snd-card"; qcom,tasha-mclk-clk-freq = <9600000>; asoc-platform = <&pcm0>; diff --git a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt index 3aaa339e1b22..07e4374956f1 100644 --- a/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt +++ b/Documentation/devicetree/bindings/thermal/qpnp-adc-tm.txt @@ -203,7 +203,7 @@ Example for "qcom,qpnp-adc-tm" device: Example for "qcom,qpnp-adc-tm-hc" device: /* Main Node */ - pmcobalt_adc_tm: vadc@3400 { + pm8998_adc_tm: vadc@3400 { compatible = "qcom,qpnp-adc-tm-hc"; reg = <0x3400 0x100>; #address-cells = <1>; @@ -212,7 +212,7 @@ Example for "qcom,qpnp-adc-tm-hc" device: interrupt-names = "eoc-int-en-set"; qcom,adc-bit-resolution = <15>; qcom,adc-vdd-reference = <1875>; - qcom,adc_tm-vadc = <&pmcobalt_vadc>; + qcom,adc_tm-vadc = <&pm8998_vadc>; qcom,decimation = <0>; qcom,fast-avg-setup = <0>; diff --git a/Documentation/devicetree/bindings/thermal/tsens.txt b/Documentation/devicetree/bindings/thermal/tsens.txt index 7189edbf8c5c..fc697e843fbb 100644 --- a/Documentation/devicetree/bindings/thermal/tsens.txt +++ b/Documentation/devicetree/bindings/thermal/tsens.txt @@ -29,7 +29,7 @@ Required properties: should be "qcom,msmtitanium-tsens" for titanium TSENS driver. should be "qcom,msm8937-tsens" for 8937 TSENS driver. should be "qcom,msmgold-tsens" for gold TSENS driver. - should be "qcom,msmcobalt-tsens" for cobalt TSENS driver. + should be "qcom,msm8998-tsens" for 8998 TSENS driver. should be "qcom,msmhamster-tsens" for hamster TSENS driver. should be "qcom,msmfalcon-tsens" for falcon TSENS driver. should be "qcom,msmtriton-tsens" for triton TSENS driver. 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/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt b/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt index cd1386512bd3..f3c3163f0a3f 100644 --- a/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt +++ b/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt @@ -48,7 +48,7 @@ Example: qcom,qpnp-pdphy@1700 { compatible = "qcom,qpnp-pdphy"; reg = <0x1700 0x100>; - vdd-pdphy-supply = <&pmcobalt_l24>; + vdd-pdphy-supply = <&pm8998_l24>; interrupts = <0x2 0x17 0x0 IRQ_TYPE_EDGE_RISING>, <0x2 0x17 0x1 IRQ_TYPE_EDGE_RISING>, <0x2 0x17 0x2 IRQ_TYPE_EDGE_RISING>, diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 7810842100cd..730b76846c9d 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -102,34 +102,35 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \ apq8096-v3-pmi8996-mdm9x55-slimbus-mtp.dtb \ apq8096-v3-pmi8996-dragonboard.dtb -dtb-$(CONFIG_ARCH_MSMCOBALT) += msmcobalt-sim.dtb \ - msmcobalt-rumi.dtb \ - msmcobalt-cdp.dtb \ - msmcobalt-mtp.dtb \ - msmcobalt-qrd.dtb \ - msmcobalt-v2-sim.dtb \ - msmcobalt-v2-rumi.dtb \ - msmcobalt-v2-mtp.dtb \ - msmcobalt-v2-cdp.dtb \ - msmcobalt-v2-qrd.dtb \ - msmcobalt-qrd-skuk.dtb \ - msmcobalt-v2-qrd-skuk.dtb \ - msmcobalt-qrd-vr1.dtb \ - msmcobalt-v2-qrd-vr1.dtb \ - apqcobalt-mtp.dtb \ - apqcobalt-cdp.dtb \ - apqcobalt-v2-mtp.dtb \ - apqcobalt-v2-cdp.dtb \ - apqcobalt-v2-qrd.dtb \ - msmcobalt-v2.1-mtp.dtb \ - msmcobalt-v2.1-cdp.dtb \ - msmcobalt-v2.1-qrd.dtb \ - apqcobalt-v2.1-mtp.dtb \ - apqcobalt-v2.1-cdp.dtb \ - apqcobalt-v2.1-qrd.dtb \ - msmcobalt-v2.1-interposer-msmfalcon-cdp.dtb \ - msmcobalt-v2.1-interposer-msmfalcon-mtp.dtb \ - msmcobalt-v2.1-interposer-msmfalcon-qrd.dtb +dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ + msm8998-rumi.dtb \ + msm8998-cdp.dtb \ + msm8998-mtp.dtb \ + msm8998-qrd.dtb \ + msm8998-v2-sim.dtb \ + msm8998-v2-rumi.dtb \ + msm8998-v2-mtp.dtb \ + msm8998-v2-cdp.dtb \ + msm8998-v2-qrd.dtb \ + msm8998-qrd-skuk.dtb \ + msm8998-v2-qrd-skuk.dtb \ + msm8998-qrd-vr1.dtb \ + msm8998-v2-qrd-vr1.dtb \ + apq8998-mtp.dtb \ + apq8998-cdp.dtb \ + apq8998-v2-mtp.dtb \ + apq8998-v2-cdp.dtb \ + apq8998-v2-qrd.dtb \ + msm8998-v2.1-mtp.dtb \ + msm8998-v2.1-cdp.dtb \ + msm8998-v2.1-qrd.dtb \ + apq8998-v2.1-mtp.dtb \ + apq8998-v2.1-cdp.dtb \ + apq8998-v2.1-qrd.dtb \ + apq8998-v2.1-mediabox.dtb \ + msm8998-v2.1-interposer-msmfalcon-cdp.dtb \ + msm8998-v2.1-interposer-msmfalcon-mtp.dtb \ + msm8998-v2.1-interposer-msmfalcon-qrd.dtb dtb-$(CONFIG_ARCH_MSMHAMSTER) += msmhamster-rumi.dtb diff --git a/arch/arm/boot/dts/qcom/apqcobalt-cdp.dts b/arch/arm/boot/dts/qcom/apq8998-cdp.dts index 1f0066d15aaa..8acd2dabe18a 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-cdp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "apq8998.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT CDP"; - compatible = "qcom,apqcobalt-cdp", "qcom,apqcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. APQ 8998 CDP"; + compatible = "qcom,apq8998-cdp", "qcom,apq8998", "qcom,cdp"; qcom,board-id = <1 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-mtp.dts b/arch/arm/boot/dts/qcom/apq8998-mtp.dts index b63e9e027797..5bed816f77d6 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-mtp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "apq8998.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT MTP"; - compatible = "qcom,apqcobalt-mtp", "qcom,apqcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. APQ 8998 MTP"; + compatible = "qcom,apq8998-mtp", "qcom,apq8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2-cdp.dts b/arch/arm/boot/dts/qcom/apq8998-v2-cdp.dts index 69eb9ef15c46..397892dbb540 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2-cdp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "apq8998-v2.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2 CDP"; - compatible = "qcom,apqcobalt-cdp", "qcom,apqcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2 CDP"; + compatible = "qcom,apq8998-cdp", "qcom,apq8998", "qcom,cdp"; qcom,board-id = <1 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2-mtp.dts b/arch/arm/boot/dts/qcom/apq8998-v2-mtp.dts index 8587b56b289a..4dc735c8d182 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2-mtp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "apq8998-v2.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2 MTP"; - compatible = "qcom,apqcobalt-mtp", "qcom,apqcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2 MTP"; + compatible = "qcom,apq8998-mtp", "qcom,apq8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd.dts b/arch/arm/boot/dts/qcom/apq8998-v2-qrd.dts index 81c17c2077e4..4f7efa7b4357 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2-qrd.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-qrd.dtsi" +#include "apq8998-v2.dtsi" +#include "msm8998-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2 QRD"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2 QRD"; + compatible = "qcom,apq8998-qrd", "qcom,apq8998", "qcom,qrd"; qcom,board-id = <11 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-cdp.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-cdp.dts index f0ab8e0afc78..94c6031854fa 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-cdp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.1.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "apq8998-v2.1.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2.1 CDP"; - compatible = "qcom,apqcobalt-cdp", "qcom,apqcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2.1 CDP"; + compatible = "qcom,apq8998-cdp", "qcom,apq8998", "qcom,cdp"; qcom,board-id = <1 0>; }; diff --git a/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts new file mode 100644 index 000000000000..bc60d9a08c0b --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts @@ -0,0 +1,30 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; + +#include "apq8998-v2.1.dtsi" +#include "msm8998-cdp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ 8998 V2.1 mediabox"; + compatible = "qcom,apq8998-cdp", "qcom,apq8998", "qcom,cdp"; + qcom,board-id = <8 1>; +}; + +&pil_modem { + status = "disabled"; +}; + +&mdss_mdp { + qcom,mdss-pref-prim-intf = "hdmi"; +}; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-mtp.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-mtp.dts index e23134f8897b..fa4e28e515b5 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-mtp.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-mtp.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.1.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "apq8998-v2.1.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2.1 MTP"; - compatible = "qcom,apqcobalt-mtp", "qcom,apqcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2.1 MTP"; + compatible = "qcom,apq8998-mtp", "qcom,apq8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2-qrd.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-qrd.dts index 5a26313f9d59..6a91b966a9b7 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2-qrd.dts +++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-qrd.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.dtsi" -#include "msmcobalt-qrd.dtsi" +#include "apq8998-v2.1.dtsi" +#include "msm8998-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2 QRD"; - compatible = "qcom,apqcobalt-qrd", "qcom,apqcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2.1 QRD"; + compatible = "qcom,apq8998-qrd", "qcom,apq8998", "qcom,qrd"; qcom,board-id = <11 0>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2.1.dtsi b/arch/arm/boot/dts/qcom/apq8998-v2.1.dtsi index 5a49afecd60b..c7d44816c7d6 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2.1.dtsi +++ b/arch/arm/boot/dts/qcom/apq8998-v2.1.dtsi @@ -10,9 +10,9 @@ * GNU General Public License for more details. */ -#include "msmcobalt-v2.1.dtsi" +#include "msm8998-v2.1.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2.1"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2.1"; qcom,msm-id = <319 0x20001>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2.dtsi b/arch/arm/boot/dts/qcom/apq8998-v2.dtsi index 58abca9859d9..2be3db45bf37 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2.dtsi +++ b/arch/arm/boot/dts/qcom/apq8998-v2.dtsi @@ -10,9 +10,9 @@ * GNU General Public License for more details. */ -#include "msmcobalt-v2.dtsi" +#include "msm8998-v2.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2"; + model = "Qualcomm Technologies, Inc. APQ 8998 V2"; qcom,msm-id = <319 0x20000>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt.dtsi b/arch/arm/boot/dts/qcom/apq8998.dtsi index dcc1601245f5..99d3459e39ce 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt.dtsi +++ b/arch/arm/boot/dts/qcom/apq8998.dtsi @@ -10,10 +10,10 @@ * GNU General Public License for more details. */ -#include "msmcobalt.dtsi" +#include "msm8998.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT"; + model = "Qualcomm Technologies, Inc. APQ 8998"; qcom,msm-id = <319 0x10000>; }; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi index 8bf98d83d381..ba3b33361ba1 100644 --- a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi @@ -10,12 +10,12 @@ * GNU General Public License for more details. */ -qcom,qrd_msmcobalt_skuk_3000mah { +qcom,qrd_msm8998_skuk_3000mah { qcom,max-voltage-uv = <4400000>; qcom,nom-batt-capacity-mah = <3000>; qcom,batt-id-kohm = <68>; qcom,battery-beta = <3380>; - qcom,battery-type = "qrd_msmcobalt_skuk_300mah"; + qcom,battery-type = "qrd_msm8998_skuk_300mah"; qcom,checksum = <0x0F19>; qcom,fg-profile-data = [ 6F 1F B2 05 diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi index 9ad9e4adce00..94ca102c9dc0 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-cmd.dtsi @@ -44,6 +44,8 @@ qcom,mdss-dsi-dma-trigger = "trigger_sw"; qcom,mdss-dsi-mdp-trigger = "none"; qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <74>; + qcom,mdss-pan-physical-height-dimension = <131>; qcom,mdss-dsi-te-pin-select = <1>; qcom,mdss-dsi-wr-mem-start = <0x2c>; qcom,mdss-dsi-wr-mem-continue = <0x3c>; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi index 6b549a4af6eb..49130cc96f79 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dsc-wqxga-video.dtsi @@ -77,6 +77,8 @@ qcom,mdss-dsi-dma-trigger = "trigger_sw"; qcom,mdss-dsi-mdp-trigger = "none"; qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <74>; + qcom,mdss-pan-physical-height-dimension = <131>; qcom,compression-mode = "dsc"; qcom,config-select = <&dsi_nt35597_dsc_video_config0>; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi index 1e42d0846acf..10be9cc183f6 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi @@ -47,6 +47,8 @@ 04 00]; qcom,adjust-timer-wakeup-ms = <1>; qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <74>; + qcom,mdss-pan-physical-height-dimension = <131>; qcom,mdss-dsi-t-clk-post = <0x0d>; qcom,mdss-dsi-t-clk-pre = <0x2d>; qcom,mdss-dsi-bl-max-level = <4095>; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi index 82413bfbca89..a2cac50325c5 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi @@ -70,6 +70,8 @@ qcom,mdss-dsi-dma-trigger = "trigger_sw"; qcom,mdss-dsi-mdp-trigger = "none"; qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-pan-physical-width-dimension = <74>; + qcom,mdss-pan-physical-height-dimension = <131>; qcom,mdss-dsi-min-refresh-rate = <55>; qcom,mdss-dsi-max-refresh-rate = <60>; qcom,mdss-dsi-pan-enable-dynamic-fps; diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi index 3de3cd5f8de9..0ba86e81887f 100644 --- a/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include <dt-bindings/msm/msm-bus-ids.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -22,17 +22,13 @@ #iommu-cells = <0>; qcom,register-save; qcom,skip-init; - #global-interrupts = <2>; - interrupts = <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 231 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 364 IRQ_TYPE_EDGE_RISING>, + #global-interrupts = <0>; + interrupts = <GIC_SPI 364 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 365 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 366 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 367 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 368 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 369 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 370 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 431 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 369 IRQ_TYPE_EDGE_RISING>; clocks = <&clock_gcc clk_aggre1_noc_clk>; clock-names = "smmu_aggre1_noc_clk"; #clock-cells = <1>; @@ -45,10 +41,8 @@ #iommu-cells = <1>; qcom,register-save; qcom,skip-init; - #global-interrupts = <2>; - interrupts = <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 231 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>, + #global-interrupts = <0>; + interrupts = <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 374 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 375 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>, @@ -57,17 +51,7 @@ <GIC_SPI 462 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 353 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 354 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 356 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 357 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 358 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>; clocks = <&clock_gcc clk_aggre2_noc_clk>; clock-names = "smmu_aggre2_noc_clk"; #clock-cells = <1>; @@ -81,10 +65,8 @@ qcom,tz-device-id = "LPASS"; qcom,register-save; qcom,skip-init; - #global-interrupts = <2>; - interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, + #global-interrupts = <0>; + interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>, @@ -96,11 +78,7 @@ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; vdd-supply = <&gdsc_hlos1_vote_lpass_adsp>; clocks = <&clock_gcc clk_hlos1_vote_lpass_adsp_smmu_clk>; clock-names = "lpass_q6_smmu_clk"; @@ -115,10 +93,8 @@ qcom,register-save; qcom,no-smr-check; qcom,skip-init; - #global-interrupts = <2>; - interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>, + #global-interrupts = <0>; + interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, @@ -137,11 +113,7 @@ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; vdd-supply = <&gdsc_bimc_smmu>; clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>, <&clock_gcc clk_mmssnoc_axi_clk>, @@ -164,15 +136,10 @@ qcom,dynamic; qcom,register-save; qcom,skip-init; - #global-interrupts = <2>; - interrupts = <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 231 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 331 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 332 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 116 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 117 IRQ_TYPE_EDGE_RISING>; + #global-interrupts = <0>; + interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 331 IRQ_TYPE_EDGE_RISING>; vdd-supply = <&gdsc_gpu_cx>; clocks = <&clock_gcc clk_gcc_gpu_cfg_ahb_clk>, <&clock_gcc clk_gcc_bimc_gfx_clk>, diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-impl-defs-cobalt.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-impl-defs-8998.dtsi index 4fbf1e126842..4fbf1e126842 100644 --- a/arch/arm/boot/dts/qcom/msm-arm-smmu-impl-defs-cobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-impl-defs-8998.dtsi diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi new file mode 100644 index 000000000000..74c1779e6fca --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -0,0 +1,838 @@ +/* + * Copyright (c) 2015-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + pcm0: qcom,msm-pcm { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <0>; + }; + + routing: qcom,msm-pcm-routing { + compatible = "qcom,msm-pcm-routing"; + }; + + compr: qcom,msm-compr-dsp { + compatible = "qcom,msm-compr-dsp"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm1: qcom,msm-pcm-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <1>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "regular"; + }; + + pcm2: qcom,msm-ultra-low-latency { + compatible = "qcom,msm-pcm-dsp"; + qcom,msm-pcm-dsp-id = <2>; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + pcm_noirq: qcom,msm-pcm-dsp-noirq { + compatible = "qcom,msm-pcm-dsp-noirq"; + qcom,msm-pcm-low-latency; + qcom,latency-level = "ultra"; + }; + + cpe: qcom,msm-cpe-lsm { + compatible = "qcom,msm-cpe-lsm"; + }; + + cpe3: qcom,msm-cpe-lsm@3 { + compatible = "qcom,msm-cpe-lsm"; + qcom,msm-cpe-lsm-id = <3>; + }; + + compress: qcom,msm-compress-dsp { + compatible = "qcom,msm-compress-dsp"; + }; + + voip: qcom,msm-voip-dsp { + compatible = "qcom,msm-voip-dsp"; + }; + + voice: qcom,msm-pcm-voice { + compatible = "qcom,msm-pcm-voice"; + qcom,destroy-cvd; + }; + + stub_codec: qcom,msm-stub-codec { + compatible = "qcom,msm-stub-codec"; + }; + + qcom,msm-dai-fe { + compatible = "qcom,msm-dai-fe"; + }; + + afe: qcom,msm-pcm-afe { + compatible = "qcom,msm-pcm-afe"; + }; + + loopback: qcom,msm-pcm-loopback { + compatible = "qcom,msm-pcm-loopback"; + }; + + qcom,msm-dai-mi2s { + compatible = "qcom,msm-dai-mi2s"; + dai_mi2s0: qcom,msm-dai-q6-mi2s-prim { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <0>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; + }; + + dai_mi2s1: qcom,msm-dai-q6-mi2s-sec { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <1>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <0>; + }; + + dai_mi2s3: qcom,msm-dai-q6-mi2s-quat { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <3>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + dai_mi2s2: qcom,msm-dai-q6-mi2s-tert { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <2>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + + dai_mi2s5: qcom,msm-dai-q6-mi2s-quin { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <5>; + qcom,msm-mi2s-rx-lines = <1>; + qcom,msm-mi2s-tx-lines = <2>; + }; + + dai_mi2s6: qcom,msm-dai-q6-mi2s-senary { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <6>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + + dai_int_mi2s0: qcom,msm-dai-q6-int-mi2s0 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <7>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; + }; + + dai_int_mi2s1: qcom,msm-dai-q6-int-mi2s1 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <8>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; + }; + + dai_int_mi2s2: qcom,msm-dai-q6-int-mi2s2 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <9>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + + dai_int_mi2s3: qcom,msm-dai-q6-int-mi2s3 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <10>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + + dai_int_mi2s4: qcom,msm-dai-q6-int-mi2s4 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <11>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; + }; + + dai_int_mi2s5: qcom,msm-dai-q6-int-mi2s5 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <12>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + + dai_int_mi2s6: qcom,msm-dai-q6-int-mi2s6 { + compatible = "qcom,msm-dai-q6-mi2s"; + qcom,msm-dai-q6-mi2s-dev-id = <13>; + qcom,msm-mi2s-rx-lines = <0>; + qcom,msm-mi2s-tx-lines = <3>; + }; + }; + + lsm: qcom,msm-lsm-client { + compatible = "qcom,msm-lsm-client"; + }; + + qcom,msm-dai-q6 { + compatible = "qcom,msm-dai-q6"; + sb_0_rx: qcom,msm-dai-q6-sb-0-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16384>; + }; + + sb_0_tx: qcom,msm-dai-q6-sb-0-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16385>; + }; + + sb_1_rx: qcom,msm-dai-q6-sb-1-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16386>; + }; + + sb_1_tx: qcom,msm-dai-q6-sb-1-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16387>; + }; + + sb_2_rx: qcom,msm-dai-q6-sb-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16388>; + }; + + sb_2_tx: qcom,msm-dai-q6-sb-2-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16389>; + }; + + + sb_3_rx: qcom,msm-dai-q6-sb-3-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16390>; + }; + + sb_3_tx: qcom,msm-dai-q6-sb-3-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16391>; + }; + + sb_4_rx: qcom,msm-dai-q6-sb-4-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16392>; + }; + + sb_4_tx: qcom,msm-dai-q6-sb-4-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16393>; + }; + + sb_5_tx: qcom,msm-dai-q6-sb-5-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16395>; + }; + + sb_5_rx: qcom,msm-dai-q6-sb-5-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16394>; + }; + + sb_6_rx: qcom,msm-dai-q6-sb-6-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16396>; + }; + + sb_7_tx: qcom,msm-dai-q6-sb-7-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16399>; + }; + + sb_7_rx: qcom,msm-dai-q6-sb-7-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16398>; + }; + + sb_8_tx: qcom,msm-dai-q6-sb-8-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16401>; + }; + + sb_8_rx: qcom,msm-dai-q6-sb-8-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <16400>; + }; + + bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12288>; + }; + + bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12289>; + }; + + int_fm_rx: qcom,msm-dai-q6-int-fm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12292>; + }; + + int_fm_tx: qcom,msm-dai-q6-int-fm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <12293>; + }; + + afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <224>; + }; + + afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <225>; + }; + + afe_proxy_rx: qcom,msm-dai-q6-afe-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <241>; + }; + + afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <240>; + }; + + incall_record_rx: qcom,msm-dai-q6-incall-record-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32771>; + }; + + incall_record_tx: qcom,msm-dai-q6-incall-record-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32772>; + }; + + incall_music_rx: qcom,msm-dai-q6-incall-music-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32773>; + }; + + incall_music_2_rx: qcom,msm-dai-q6-incall-music-2-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <32770>; + }; + + usb_audio_rx: qcom,msm-dai-q6-usb-audio-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <28672>; + }; + + usb_audio_tx: qcom,msm-dai-q6-usb-audio-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <28673>; + }; + }; + + hostless: qcom,msm-pcm-hostless { + compatible = "qcom,msm-pcm-hostless"; + }; + + dai_pri_auxpcm: qcom,msm-pri-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "primary"; + }; + + dai_sec_auxpcm: qcom,msm-sec-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "secondary"; + qcom,msm-cpudai-afe-clk-ver = <2>; + }; + + dai_tert_auxpcm: qcom,msm-tert-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "tertiary"; + qcom,msm-cpudai-afe-clk-ver = <2>; + }; + + dai_quat_auxpcm: qcom,msm-quat-auxpcm { + compatible = "qcom,msm-auxpcm-dev"; + qcom,msm-cpudai-auxpcm-mode = <0>, <0>; + qcom,msm-cpudai-auxpcm-sync = <1>, <1>; + qcom,msm-cpudai-auxpcm-frame = <5>, <4>; + qcom,msm-cpudai-auxpcm-quant = <2>, <2>; + qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>; + qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>; + qcom,msm-cpudai-auxpcm-data = <0>, <0>; + qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>; + qcom,msm-auxpcm-interface = "quaternary"; + qcom,msm-cpudai-afe-clk-ver = <2>; + }; + + qcom,msm-audio-ion { + compatible = "qcom,msm-audio-ion"; + qcom,smmu-version = <2>; + qcom,smmu-enabled; + iommus = <&lpass_q6_smmu 1>; + }; + + qcom,msm-adsp-loader { + compatible = "qcom,adsp-loader"; + qcom,adsp-state = <0>; + }; + + qcom,msm-dai-tdm-pri-rx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37120>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36864>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_pri_tdm_rx_0: qcom,msm-dai-q6-tdm-pri-rx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36864>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-pri-tx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37121>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36865>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36865>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-sec-rx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37136>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36880>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_sec_tdm_rx_0: qcom,msm-dai-q6-tdm-sec-rx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36880>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-sec-tx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37137>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36881>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_sec_tdm_tx_0: qcom,msm-dai-q6-tdm-sec-tx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36881>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-tert-rx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37152>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36896>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_tert_tdm_rx_0: qcom,msm-dai-q6-tdm-tert-rx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36896>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-tert-tx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37153>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36897 >; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_tert_tdm_tx_0: qcom,msm-dai-q6-tdm-tert-tx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36897 >; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-quat-rx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37168>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36912>; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_quat_tdm_rx_0: qcom,msm-dai-q6-tdm-quat-rx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36912>; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,msm-dai-tdm-quat-tx { + compatible = "qcom,msm-dai-tdm"; + qcom,msm-cpudai-tdm-group-id = <37169>; + qcom,msm-cpudai-tdm-group-num-ports = <1>; + qcom,msm-cpudai-tdm-group-port-id = <36913 >; + qcom,msm-cpudai-tdm-clk-rate = <1536000>; + dai_quat_tdm_tx_0: qcom,msm-dai-q6-tdm-quat-tx-0 { + compatible = "qcom,msm-dai-q6-tdm"; + qcom,msm-cpudai-tdm-dev-id = <36913 >; + qcom,msm-cpudai-tdm-sync-mode = <1>; + qcom,msm-cpudai-tdm-sync-src = <1>; + qcom,msm-cpudai-tdm-data-out = <0>; + qcom,msm-cpudai-tdm-invert-sync = <1>; + qcom,msm-cpudai-tdm-data-delay = <1>; + qcom,msm-cpudai-tdm-data-align = <0>; + }; + }; + + qcom,avtimer@150f700c { + compatible = "qcom,avtimer"; + reg = <0x150f700c 0x4>, + <0x150f7010 0x4>; + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr"; + qcom,clk-div = <27>; + }; + + tasha_snd: sound-9335 { + compatible = "qcom,msmfalcon-asoc-snd-tasha"; + qcom,model = "msmfalcon-tasha-snd-card"; + qcom,wcn-btfm; + qcom,mi2s-audio-intf; + qcom,auxpcm-audio-intf; + qcom,msm-mi2s-master = <1>, <1>, <1>, <1>; + + reg = <0x1508a000 0x4>, + <0x1508b000 0x4>, + <0x1508c000 0x4>, + <0x1508d000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "AIF4 VI", "MCLK", + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS2", + "MIC BIAS2", "ANCRight Headset Mic", + "AMIC4", "MIC BIAS2", + "MIC BIAS2", "ANCLeft Headset Mic", + "AMIC5", "MIC BIAS3", + "MIC BIAS3", "Handset Mic", + "AMIC6", "MIC BIAS4", + "MIC BIAS4", "Analog Mic6", + "DMIC0", "MIC BIAS1", + "MIC BIAS1", "Digital Mic0", + "DMIC1", "MIC BIAS1", + "MIC BIAS1", "Digital Mic1", + "DMIC2", "MIC BIAS3", + "MIC BIAS3", "Digital Mic2", + "DMIC3", "MIC BIAS3", + "MIC BIAS3", "Digital Mic3", + "DMIC4", "MIC BIAS4", + "MIC BIAS4", "Digital Mic4", + "DMIC5", "MIC BIAS4", + "MIC BIAS4", "Digital Mic5", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT"; + + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; + qcom,us-euro-gpios = <&us_euro_gpio>; + qcom,tasha-mclk-clk-freq = <9600000>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>, + <&pcm_noirq>, <&cpe3>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-pcm-dsp.2", "msm-voip-dsp", + "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", + "msm-pcm-afe", "msm-lsm-client", + "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp", "msm-pcm-dsp-noirq", + "msm-cpe-lsm.3"; + asoc-cpu = <&dai_mi2s0>, <&dai_mi2s1>, + <&dai_mi2s2>, <&dai_mi2s3>, + <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, + <&dai_tert_auxpcm>, <&dai_quat_auxpcm>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&incall_music_2_rx>, <&sb_5_rx>, <&sb_6_rx>, + <&sb_7_rx>, <&sb_7_tx>, <&sb_8_tx>, <&sb_8_rx>, + <&usb_audio_rx>, <&usb_audio_tx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>; + asoc-cpu-names = "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-auxpcm.3", "msm-dai-q6-auxpcm.4", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770", "msm-dai-q6-dev.16394", + "msm-dai-q6-dev.16396", "msm-dai-q6-dev.16398", + "msm-dai-q6-dev.16399", "msm-dai-q6-dev.16401", + "msm-dai-q6-dev.16400", "msm-dai-q6-dev.28672", + "msm-dai-q6-dev.28673", "msm-dai-q6-tdm.36864", + "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36880", + "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896", + "msm-dai-q6-tdm.36897", "msm-dai-q6-tdm.36912", + "msm-dai-q6-tdm.36913"; + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + qcom,wsa-max-devs = <2>; + qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>, + <&wsa881x_0213>, <&wsa881x_0214>; + qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", + "SpkrLeft", "SpkrRight"; + }; + + tavil_snd: sound-tavil { + compatible = "qcom,msmfalcon-asoc-snd-tavil"; + qcom,model = "msmfalcon-tavil-snd-card"; + qcom,wcn-btfm; + qcom,mi2s-audio-intf; + qcom,auxpcm-audio-intf; + qcom,msm-mi2s-master = <1>, <1>, <1>, <1>; + + reg = <0x1508a000 0x4>, + <0x1508b000 0x4>, + <0x1508c000 0x4>, + <0x1508d000 0x4>; + reg-names = "lpaif_pri_mode_muxsel", + "lpaif_sec_mode_muxsel", + "lpaif_tert_mode_muxsel", + "lpaif_quat_mode_muxsel"; + + qcom,audio-routing = + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "AMIC3", "MIC BIAS2", + "MIC BIAS2", "ANCRight Headset Mic", + "AMIC4", "MIC BIAS2", + "MIC BIAS2", "ANCLeft Headset Mic", + "AMIC5", "MIC BIAS3", + "MIC BIAS3", "Handset Mic", + "DMIC0", "MIC BIAS1", + "MIC BIAS1", "Digital Mic0", + "DMIC1", "MIC BIAS1", + "MIC BIAS1", "Digital Mic1", + "DMIC2", "MIC BIAS3", + "MIC BIAS3", "Digital Mic2", + "DMIC3", "MIC BIAS3", + "MIC BIAS3", "Digital Mic3", + "DMIC4", "MIC BIAS4", + "MIC BIAS4", "Digital Mic4", + "DMIC5", "MIC BIAS4", + "MIC BIAS4", "Digital Mic5", + "SpkrLeft IN", "SPK1 OUT", + "SpkrRight IN", "SPK2 OUT"; + + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; + qcom,us-euro-gpios = <&tavil_us_euro_sw>; + qcom,hph-en0-gpio = <&tavil_hph_en0>; + qcom,hph-en1-gpio = <&tavil_hph_en1>; + qcom,tavil-mclk-clk-freq = <9600000>; + asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, + <&loopback>, <&compress>, <&hostless>, + <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>, + <&pcm_noirq>; + asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1", + "msm-pcm-dsp.2", "msm-voip-dsp", + "msm-pcm-voice", "msm-pcm-loopback", + "msm-compress-dsp", "msm-pcm-hostless", + "msm-pcm-afe", "msm-lsm-client", + "msm-pcm-routing", "msm-cpe-lsm", + "msm-compr-dsp", "msm-pcm-dsp-noirq"; + asoc-cpu = <&dai_mi2s0>, <&dai_mi2s1>, + <&dai_mi2s2>, <&dai_mi2s3>, + <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, + <&dai_tert_auxpcm>, <&dai_quat_auxpcm>, + <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>, + <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>, + <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>, + <&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>, + <&afe_proxy_tx>, <&incall_record_rx>, + <&incall_record_tx>, <&incall_music_rx>, + <&incall_music_2_rx>, <&sb_5_rx>, <&sb_6_rx>, + <&sb_7_rx>, <&sb_7_tx>, <&sb_8_tx>, <&sb_8_rx>, + <&usb_audio_rx>, <&usb_audio_tx>, + <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, + <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, + <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>; + asoc-cpu-names = "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", + "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", + "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2", + "msm-dai-q6-auxpcm.3", "msm-dai-q6-auxpcm.4", + "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385", + "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387", + "msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389", + "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391", + "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393", + "msm-dai-q6-dev.16395", "msm-dai-q6-dev.224", + "msm-dai-q6-dev.225", "msm-dai-q6-dev.241", + "msm-dai-q6-dev.240", "msm-dai-q6-dev.32771", + "msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773", + "msm-dai-q6-dev.32770", "msm-dai-q6-dev.16394", + "msm-dai-q6-dev.16396", "msm-dai-q6-dev.16398", + "msm-dai-q6-dev.16399", "msm-dai-q6-dev.16401", + "msm-dai-q6-dev.16400", "msm-dai-q6-dev.28672", + "msm-dai-q6-dev.28673", "msm-dai-q6-tdm.36864", + "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36880", + "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896", + "msm-dai-q6-tdm.36897", "msm-dai-q6-tdm.36912", + "msm-dai-q6-tdm.36913"; + asoc-codec = <&stub_codec>; + asoc-codec-names = "msm-stub-codec.1"; + qcom,wsa-max-devs = <2>; + qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>, + <&wsa881x_0213>, <&wsa881x_0214>; + qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", + "SpkrLeft", "SpkrRight"; + }; + + + us_euro_gpio: msm_cdc_pinctrl@75 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&wcd_gnd_mic_swap_active>; + pinctrl-1 = <&wcd_gnd_mic_swap_idle>; + }; + + wcd9xxx_intc: wcd9xxx-irq { + compatible = "qcom,wcd9xxx-irq"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tlmm>; + qcom,gpio-connect = <&tlmm 54 0>; + pinctrl-names = "default"; + pinctrl-0 = <&wcd_intr_default>; + }; + + clock_audio: audio_ext_clk { + compatible = "qcom,audio-ref-clk"; + qcom,audio-ref-clk-gpio = <&pmfalcon_gpios 3 0>; + clock-names = "osr_clk"; + clocks = <&clock_gcc clk_div_clk1>; + qcom,node_has_rpm_clock; + #clock-cells = <1>; + pinctrl-names = "sleep", "active"; + pinctrl-0 = <&spkr_i2s_clk_sleep>; + pinctrl-1 = <&spkr_i2s_clk_active>; + }; + + clock_audio_lnbb: audio_ext_clk_lnbb { + compatible = "qcom,audio-ref-clk"; + clock-names = "osr_clk"; + clocks = <&clock_gcc clk_ln_bb_clk2>; + qcom,node_has_rpm_clock; + #clock-cells = <1>; + }; + + wcd_rst_gpio: msm_cdc_pinctrl@64 { + compatible = "qcom,msm-cdc-pinctrl"; + qcom,cdc-rst-n-gpio = <&tlmm 64 0>; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_reset_active>; + pinctrl-1 = <&cdc_reset_sleep>; + }; + +}; + diff --git a/arch/arm/boot/dts/qcom/msm-gdsc-cobalt.dtsi b/arch/arm/boot/dts/qcom/msm-gdsc-8998.dtsi index c86351e48d5f..c86351e48d5f 100644 --- a/arch/arm/boot/dts/qcom/msm-gdsc-cobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-gdsc-8998.dtsi diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi index 0e5a999e4642..79883db10d06 100644 --- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi @@ -234,7 +234,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <127500>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29600>; qcom,ilim-ma = <970>; @@ -269,6 +269,7 @@ qcom,thermal-derate-en; qcom,thermal-derate-current = <200 500 1000>; qcom,isc-delay = <192>; + qcom,pmic-revid = <&pm2falcon_revid>; status = "disabled"; pm2falcon_flash0: qcom,flash_0 { diff --git a/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi new file mode 100644 index 000000000000..dcf7030a78e4 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi @@ -0,0 +1,16 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Disable WLED */ +&pm2falcon_wled { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/msm-pmcobalt-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm8998-rpm-regulator.dtsi index 7243a6b1d6d4..5ad84dbfcff6 100644 --- a/arch/arm/boot/dts/qcom/msm-pmcobalt-rpm-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm8998-rpm-regulator.dtsi @@ -11,7 +11,7 @@ */ &rpm_bus { - /* PMCOBALT S1 + S6 = VDD_CX supply */ + /* PM8998 S1 + S6 = VDD_CX supply */ rpm-regulator-smpa1 { compatible = "qcom,rpm-smd-regulator-resource"; qcom,resource-name = "rwcx"; @@ -21,7 +21,7 @@ regulator-s1 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s1"; + regulator-name = "pm8998_s1"; qcom,set = <3>; status = "disabled"; }; @@ -36,7 +36,7 @@ regulator-s2 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s2"; + regulator-name = "pm8998_s2"; qcom,set = <3>; status = "disabled"; }; @@ -51,7 +51,7 @@ regulator-s3 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s3"; + regulator-name = "pm8998_s3"; qcom,set = <3>; status = "disabled"; }; @@ -66,7 +66,7 @@ regulator-s4 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s4"; + regulator-name = "pm8998_s4"; qcom,set = <3>; status = "disabled"; }; @@ -81,7 +81,7 @@ regulator-s5 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s5"; + regulator-name = "pm8998_s5"; qcom,set = <3>; status = "disabled"; }; @@ -96,7 +96,7 @@ regulator-s7 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s7"; + regulator-name = "pm8998_s7"; qcom,set = <3>; status = "disabled"; }; @@ -111,13 +111,13 @@ regulator-s8 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s8"; + regulator-name = "pm8998_s8"; qcom,set = <3>; status = "disabled"; }; }; - /* PMCOBALT S9 = VDD_MX supply */ + /* PM8998 S9 = VDD_MX supply */ rpm-regulator-smpa9 { compatible = "qcom,rpm-smd-regulator-resource"; qcom,resource-name = "rwmx"; @@ -127,7 +127,7 @@ regulator-s9 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s9"; + regulator-name = "pm8998_s9"; qcom,set = <3>; status = "disabled"; }; @@ -142,7 +142,7 @@ regulator-l1 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l1"; + regulator-name = "pm8998_l1"; qcom,set = <3>; status = "disabled"; }; @@ -157,7 +157,7 @@ regulator-l2 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l2"; + regulator-name = "pm8998_l2"; qcom,set = <3>; status = "disabled"; }; @@ -172,7 +172,7 @@ regulator-l3 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l3"; + regulator-name = "pm8998_l3"; qcom,set = <3>; status = "disabled"; }; @@ -187,7 +187,7 @@ regulator-l4 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l4"; + regulator-name = "pm8998_l4"; qcom,set = <3>; status = "disabled"; }; @@ -202,7 +202,7 @@ regulator-l5 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l5"; + regulator-name = "pm8998_l5"; qcom,set = <3>; status = "disabled"; }; @@ -217,7 +217,7 @@ regulator-l6 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l6"; + regulator-name = "pm8998_l6"; qcom,set = <3>; status = "disabled"; }; @@ -232,7 +232,7 @@ regulator-l7 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l7"; + regulator-name = "pm8998_l7"; qcom,set = <3>; status = "disabled"; }; @@ -247,7 +247,7 @@ regulator-l8 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l8"; + regulator-name = "pm8998_l8"; qcom,set = <3>; status = "disabled"; }; @@ -262,7 +262,7 @@ regulator-l9 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l9"; + regulator-name = "pm8998_l9"; qcom,set = <3>; status = "disabled"; }; @@ -277,7 +277,7 @@ regulator-l10 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l10"; + regulator-name = "pm8998_l10"; qcom,set = <3>; status = "disabled"; }; @@ -292,7 +292,7 @@ regulator-l11 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l11"; + regulator-name = "pm8998_l11"; qcom,set = <3>; status = "disabled"; }; @@ -307,7 +307,7 @@ regulator-l12 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l12"; + regulator-name = "pm8998_l12"; qcom,set = <3>; status = "disabled"; }; @@ -322,7 +322,7 @@ regulator-l13 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l13"; + regulator-name = "pm8998_l13"; qcom,set = <3>; status = "disabled"; }; @@ -337,7 +337,7 @@ regulator-l14 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l14"; + regulator-name = "pm8998_l14"; qcom,set = <3>; status = "disabled"; }; @@ -352,7 +352,7 @@ regulator-l15 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l15"; + regulator-name = "pm8998_l15"; qcom,set = <3>; status = "disabled"; }; @@ -367,7 +367,7 @@ regulator-l16 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l16"; + regulator-name = "pm8998_l16"; qcom,set = <3>; status = "disabled"; }; @@ -382,7 +382,7 @@ regulator-l17 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l17"; + regulator-name = "pm8998_l17"; qcom,set = <3>; status = "disabled"; }; @@ -397,7 +397,7 @@ regulator-l18 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l18"; + regulator-name = "pm8998_l18"; qcom,set = <3>; status = "disabled"; }; @@ -412,7 +412,7 @@ regulator-l19 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l19"; + regulator-name = "pm8998_l19"; qcom,set = <3>; status = "disabled"; }; @@ -427,7 +427,7 @@ regulator-l20 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l20"; + regulator-name = "pm8998_l20"; qcom,set = <3>; status = "disabled"; }; @@ -442,7 +442,7 @@ regulator-l21 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l21"; + regulator-name = "pm8998_l21"; qcom,set = <3>; status = "disabled"; }; @@ -457,7 +457,7 @@ regulator-l22 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l22"; + regulator-name = "pm8998_l22"; qcom,set = <3>; status = "disabled"; }; @@ -472,7 +472,7 @@ regulator-l23 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l23"; + regulator-name = "pm8998_l23"; qcom,set = <3>; status = "disabled"; }; @@ -487,7 +487,7 @@ regulator-l24 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l24"; + regulator-name = "pm8998_l24"; qcom,set = <3>; status = "disabled"; }; @@ -502,7 +502,7 @@ regulator-l25 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l25"; + regulator-name = "pm8998_l25"; qcom,set = <3>; status = "disabled"; }; @@ -517,7 +517,7 @@ regulator-l26 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l26"; + regulator-name = "pm8998_l26"; qcom,set = <3>; status = "disabled"; }; @@ -532,7 +532,7 @@ regulator-l27 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l27"; + regulator-name = "pm8998_l27"; qcom,set = <3>; status = "disabled"; }; @@ -547,7 +547,7 @@ regulator-l28 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l28"; + regulator-name = "pm8998_l28"; qcom,set = <3>; status = "disabled"; }; @@ -562,7 +562,7 @@ regulator-lvs1 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_lvs1"; + regulator-name = "pm8998_lvs1"; qcom,set = <3>; status = "disabled"; }; @@ -577,7 +577,7 @@ regulator-lvs2 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_lvs2"; + regulator-name = "pm8998_lvs2"; qcom,set = <3>; status = "disabled"; }; @@ -592,7 +592,7 @@ regulator-bob { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmicobalt_bob"; + regulator-name = "pm8998_bob"; qcom,set = <3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/qcom/msm-pmcobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pm8998.dtsi index eb5208a8d983..e91fc68d2c52 100644 --- a/arch/arm/boot/dts/qcom/msm-pmcobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm8998.dtsi @@ -14,13 +14,13 @@ #include <dt-bindings/interrupt-controller/irq.h> &spmi_bus { - qcom,pmcobalt@0 { + qcom,pm8998@0 { compatible ="qcom,spmi-pmic"; reg = <0x0 SPMI_USID>; #address-cells = <2>; #size-cells = <0>; - pmcobalt_revid: qcom,revid@100 { + pm8998_revid: qcom,revid@100 { compatible = "qcom,qpnp-revid"; reg = <0x100 0x100>; }; @@ -69,18 +69,18 @@ compatible = "qcom,qpnp-temp-alarm"; reg = <0x2400 0x100>; interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>; - label = "pmcobalt_tz"; + label = "pm8998_tz"; qcom,channel-num = <6>; - qcom,temp_alarm-vadc = <&pmcobalt_vadc>; + qcom,temp_alarm-vadc = <&pm8998_vadc>; }; - pmcobalt_gpios: gpios { + pm8998_gpios: gpios { compatible = "qcom,qpnp-pin"; gpio-controller; #gpio-cells = <2>; #address-cells = <1>; #size-cells = <1>; - label = "pmcobalt-gpio"; + label = "pm8998-gpio"; gpio@c000 { reg = <0xc000 0x100>; @@ -239,28 +239,28 @@ }; }; - pmcobalt_coincell: qcom,coincell@2800 { + pm8998_coincell: qcom,coincell@2800 { compatible = "qcom,qpnp-coincell"; reg = <0x2800 0x100>; }; - pmcobalt_rtc: qcom,pmcobalt_rtc { + pm8998_rtc: qcom,pm8998_rtc { compatible = "qcom,qpnp-rtc"; #address-cells = <1>; #size-cells = <1>; qcom,qpnp-rtc-write = <0>; qcom,qpnp-rtc-alarm-pwrup = <0>; - qcom,pmcobalt_rtc_rw@6000 { + qcom,pm8998_rtc_rw@6000 { reg = <0x6000 0x100>; }; - qcom,pmcobalt_rtc_alarm@6100 { + qcom,pm8998_rtc_alarm@6100 { reg = <0x6100 0x100>; interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>; }; }; - pmcobalt_vadc: vadc@3100 { + pm8998_vadc: vadc@3100 { compatible = "qcom,qpnp-vadc-hc"; reg = <0x3100 0x100>; #address-cells = <1>; @@ -307,7 +307,7 @@ }; }; - pmcobalt_adc_tm: vadc@3400 { + pm8998_adc_tm: vadc@3400 { compatible = "qcom,qpnp-adc-tm-hc"; reg = <0x3400 0x100>; #address-cells = <1>; @@ -316,13 +316,13 @@ interrupt-names = "eoc-int-en-set"; qcom,adc-bit-resolution = <15>; qcom,adc-vdd-reference = <1875>; - qcom,adc_tm-vadc = <&pmcobalt_vadc>; + qcom,adc_tm-vadc = <&pm8998_vadc>; qcom,decimation = <0>; qcom,fast-avg-setup = <0>; }; }; - qcom,pmcobalt@1 { + qcom,pm8998@1 { compatible ="qcom,spmi-pmic"; reg = <0x1 SPMI_USID>; #address-cells = <2>; diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi index b8fac8a183a2..93cfab700aa9 100644 --- a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi @@ -273,6 +273,158 @@ }; }; + pmfalcon_charger: qcom,qpnp-smb2 { + compatible = "qcom,qpnp-smb2"; + #address-cells = <1>; + #size-cells = <1>; + + qcom,pmic-revid = <&pmfalcon_revid>; + + io-channels = <&pmfalcon_rradc 8>, + <&pmfalcon_rradc 10>, + <&pmfalcon_rradc 3>, + <&pmfalcon_rradc 4>; + io-channel-names = "charger_temp", + "charger_temp_max", + "usbin_i", + "usbin_v"; + + qcom,wipower-max-uw = <5000000>; + dpdm-supply = <&qusb_phy0>; + + qcom,thermal-mitigation + = <3000000 1500000 1000000 500000>; + + qcom,chgr@1000 { + reg = <0x1000 0x100>; + interrupts = <0x2 0x10 0x0 IRQ_TYPE_NONE>, + <0x2 0x10 0x1 IRQ_TYPE_NONE>, + <0x2 0x10 0x2 IRQ_TYPE_NONE>, + <0x2 0x10 0x3 IRQ_TYPE_NONE>, + <0x2 0x10 0x4 IRQ_TYPE_NONE>; + + interrupt-names = "chg-error", + "chg-state-change", + "step-chg-state-change", + "step-chg-soc-update-fail", + "step-chg-soc-update-request"; + }; + + qcom,otg@1100 { + reg = <0x1100 0x100>; + interrupts = <0x2 0x11 0x0 IRQ_TYPE_NONE>, + <0x2 0x11 0x1 IRQ_TYPE_NONE>, + <0x2 0x11 0x2 IRQ_TYPE_NONE>, + <0x2 0x11 0x3 IRQ_TYPE_NONE>; + + interrupt-names = "otg-fail", + "otg-overcurrent", + "otg-oc-dis-sw-sts", + "testmode-change-detect"; + }; + + qcom,bat-if@1200 { + reg = <0x1200 0x100>; + interrupts = <0x2 0x12 0x0 IRQ_TYPE_NONE>, + <0x2 0x12 0x1 IRQ_TYPE_NONE>, + <0x2 0x12 0x2 IRQ_TYPE_NONE>, + <0x2 0x12 0x3 IRQ_TYPE_NONE>, + <0x2 0x12 0x4 IRQ_TYPE_NONE>, + <0x2 0x12 0x5 IRQ_TYPE_NONE>; + + interrupt-names = "bat-temp", + "bat-ocp", + "bat-ov", + "bat-low", + "bat-therm-or-id-missing", + "bat-terminal-missing"; + }; + + qcom,usb-chgpth@1300 { + reg = <0x1300 0x100>; + interrupts = <0x2 0x13 0x0 IRQ_TYPE_NONE>, + <0x2 0x13 0x1 IRQ_TYPE_NONE>, + <0x2 0x13 0x2 IRQ_TYPE_NONE>, + <0x2 0x13 0x3 IRQ_TYPE_NONE>, + <0x2 0x13 0x4 IRQ_TYPE_NONE>, + <0x2 0x13 0x5 IRQ_TYPE_NONE>, + <0x2 0x13 0x6 IRQ_TYPE_NONE>, + <0x2 0x13 0x7 IRQ_TYPE_NONE>; + + interrupt-names = "usbin-collapse", + "usbin-lt-3p6v", + "usbin-uv", + "usbin-ov", + "usbin-plugin", + "usbin-src-change", + "usbin-icl-change", + "type-c-change"; + }; + + qcom,dc-chgpth@1400 { + reg = <0x1400 0x100>; + interrupts = <0x2 0x14 0x0 IRQ_TYPE_NONE>, + <0x2 0x14 0x1 IRQ_TYPE_NONE>, + <0x2 0x14 0x2 IRQ_TYPE_NONE>, + <0x2 0x14 0x3 IRQ_TYPE_NONE>, + <0x2 0x14 0x4 IRQ_TYPE_NONE>, + <0x2 0x14 0x5 IRQ_TYPE_NONE>, + <0x2 0x14 0x6 IRQ_TYPE_NONE>; + + interrupt-names = "dcin-collapse", + "dcin-lt-3p6v", + "dcin-uv", + "dcin-ov", + "dcin-plugin", + "div2-en-dg", + "dcin-icl-change"; + }; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x2 0x16 0x0 IRQ_TYPE_NONE>, + <0x2 0x16 0x1 IRQ_TYPE_NONE>, + <0x2 0x16 0x2 IRQ_TYPE_NONE>, + <0x2 0x16 0x3 IRQ_TYPE_NONE>, + <0x2 0x16 0x4 IRQ_TYPE_NONE>, + <0x2 0x16 0x5 IRQ_TYPE_NONE>, + <0x2 0x16 0x6 IRQ_TYPE_NONE>, + <0x2 0x16 0x7 IRQ_TYPE_NONE>; + + interrupt-names = "wdog-snarl", + "wdog-bark", + "aicl-fail", + "aicl-done", + "high-duty-cycle", + "input-current-limiting", + "temperature-change", + "switcher-power-ok"; + }; + }; + + pmfalcon_pdphy: qcom,usb-pdphy@1700 { + compatible = "qcom,qpnp-pdphy"; + reg = <0x1700 0x100>; + vdd-pdphy-supply = <&pm2falcon_l7>; + vbus-supply = <&smb2_vbus>; + vconn-supply = <&smb2_vconn>; + interrupts = <0x0 0x17 0x0 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x1 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x2 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x3 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x4 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x5 IRQ_TYPE_EDGE_RISING>, + <0x0 0x17 0x6 IRQ_TYPE_EDGE_RISING>; + + interrupt-names = "sig-tx", + "sig-rx", + "msg-tx", + "msg-rx", + "msg-tx-failed", + "msg-tx-discarded", + "msg-rx-discarded"; + }; + pmfalcon_adc_tm: vadc@3400 { compatible = "qcom,qpnp-adc-tm-hc"; reg = <0x3400 0x100>; @@ -337,6 +489,67 @@ #size-cells = <0>; #io-channel-cells = <1>; }; + + pmfalcon_fg: qpnp,fg { + compatible = "qcom,fg-gen3"; + #address-cells = <1>; + #size-cells = <1>; + qcom,pmic-revid = <&pmfalcon_revid>; + io-channels = <&pmfalcon_rradc 0>; + io-channel-names = "rradc_batt_id"; + qcom,fg-esr-timer-awake = <96>; + qcom,fg-esr-timer-asleep = <256>; + qcom,cycle-counter-en; + status = "okay"; + + qcom,fg-batt-soc@4000 { + status = "okay"; + reg = <0x4000 0x100>; + interrupts = <0x2 0x40 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x1 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x2 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x3 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x4 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x5 + IRQ_TYPE_EDGE_RISING>, + <0x2 0x40 0x6 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x40 0x7 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "soc-update", + "soc-ready", + "bsoc-delta", + "msoc-delta", + "msoc-low", + "msoc-empty", + "msoc-high", + "msoc-full"; + }; + + qcom,fg-batt-info@4100 { + status = "okay"; + reg = <0x4100 0x100>; + interrupts = <0x2 0x41 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x41 0x1 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x41 0x2 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x41 0x3 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x41 0x6 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "vbatt-pred-delta", + "vbatt-low", + "esr-delta", + "batt-missing", + "batt-temp-delta"; + }; + + qcom,fg-memif@4400 { + status = "okay"; + reg = <0x4400 0x100>; + interrupts = <0x2 0x44 0x0 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x44 0x1 IRQ_TYPE_EDGE_BOTH>, + <0x2 0x44 0x2 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "ima-rdy", + "mem-xcp", + "dma-grant"; + }; + }; }; qcom,pmfalcon@1 { diff --git a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi index c46c0963ff56..c820d213165b 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8994.dtsi @@ -523,7 +523,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <350000>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29500>; qcom,ilim-ma = <980>; diff --git a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi index 640aa53364a5..725c129a28da 100644 --- a/arch/arm/boot/dts/qcom/msm-pmicobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi @@ -14,13 +14,13 @@ #include <dt-bindings/spmi/spmi.h> &spmi_bus { - qcom,pmicobalt@2 { + qcom,pmi8998@2 { compatible = "qcom,spmi-pmic"; reg = <0x2 SPMI_USID>; #address-cells = <2>; #size-cells = <0>; - pmicobalt_revid: qcom,revid@100 { + pmi8998_revid: qcom,revid@100 { compatible = "qcom,qpnp-revid"; reg = <0x100 0x100>; qcom,fab-id-valid; @@ -35,16 +35,16 @@ compatible = "qcom,qpnp-temp-alarm"; reg = <0x2400 0x100>; interrupts = <0x2 0x24 0x0 IRQ_TYPE_EDGE_RISING>; - label = "pmicobalt_tz"; + label = "pmi8998_tz"; }; - pmicobalt_gpios: gpios { + pmi8998_gpios: gpios { compatible = "qcom,qpnp-pin"; gpio-controller; #gpio-cells = <2>; #address-cells = <1>; #size-cells = <1>; - label = "pmicobalt-gpio"; + label = "pmi8998-gpio"; gpio@c000 { reg = <0xc000 0x100>; @@ -136,20 +136,20 @@ reg = <0x1500 0x100>; interrupts = <0x2 0x15 0x0 IRQ_TYPE_NONE>; interrupt-names = "ptrain-done"; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; }; - pmicobalt_charger: qcom,qpnp-smb2 { + pmi8998_charger: qcom,qpnp-smb2 { compatible = "qcom,qpnp-smb2"; #address-cells = <1>; #size-cells = <1>; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; - io-channels = <&pmicobalt_rradc 8>, - <&pmicobalt_rradc 10>, - <&pmicobalt_rradc 3>, - <&pmicobalt_rradc 4>; + io-channels = <&pmi8998_rradc 8>, + <&pmi8998_rradc 10>, + <&pmi8998_rradc 3>, + <&pmi8998_rradc 4>; io-channel-names = "charger_temp", "charger_temp_max", "usbin_i", @@ -268,10 +268,10 @@ }; }; - pmicobalt_pdphy: qcom,usb-pdphy@1700 { + pmi8998_pdphy: qcom,usb-pdphy@1700 { compatible = "qcom,qpnp-pdphy"; reg = <0x1700 0x100>; - vdd-pdphy-supply = <&pmcobalt_l24>; + vdd-pdphy-supply = <&pm8998_l24>; vbus-supply = <&smb2_vbus>; vconn-supply = <&smb2_vconn>; interrupts = <0x2 0x17 0x0 IRQ_TYPE_EDGE_RISING>, @@ -305,21 +305,21 @@ qcom,ibat-polling-delay-ms = <100>; }; - pmicobalt_rradc: rradc@4500 { + pmi8998_rradc: rradc@4500 { compatible = "qcom,rradc"; reg = <0x4500 0x100>; #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; }; - pmicobalt_fg: qpnp,fg { + pmi8998_fg: qpnp,fg { compatible = "qcom,fg-gen3"; #address-cells = <1>; #size-cells = <1>; - qcom,pmic-revid = <&pmicobalt_revid>; - io-channels = <&pmicobalt_rradc 0>; + qcom,pmic-revid = <&pmi8998_revid>; + io-channels = <&pmi8998_rradc 0>; io-channel-names = "rradc_batt_id"; qcom,fg-esr-timer-awake = <96>; qcom,fg-esr-timer-asleep = <256>; @@ -376,13 +376,13 @@ }; }; - qcom,pmicobalt@3 { + qcom,pmi8998@3 { compatible ="qcom,spmi-pmic"; reg = <0x3 SPMI_USID>; #address-cells = <2>; #size-cells = <0>; - pmicobalt_pwm_1: pwm@b100 { + pmi8998_pwm_1: pwm@b100 { compatible = "qcom,qpnp-pwm"; reg = <0xb100 0x100>, <0xb042 0x7e>; @@ -396,7 +396,7 @@ status = "disabled"; }; - pmicobalt_pwm_2: pwm@b200 { + pmi8998_pwm_2: pwm@b200 { compatible = "qcom,qpnp-pwm"; reg = <0xb200 0x100>, <0xb042 0x7e>; @@ -410,7 +410,7 @@ status = "disabled"; }; - pmicobalt_pwm_3: pwm@b300 { + pmi8998_pwm_3: pwm@b300 { compatible = "qcom,qpnp-pwm"; reg = <0xb300 0x100>, <0xb042 0x7e>; @@ -423,7 +423,7 @@ #pwm-cells = <2>; }; - pmicobalt_pwm_4: pwm@b400 { + pmi8998_pwm_4: pwm@b400 { compatible = "qcom,qpnp-pwm"; reg = <0xb400 0x100>, <0xb042 0x7e>; @@ -436,7 +436,7 @@ #pwm-cells = <2>; }; - pmicobalt_pwm_5: pwm@b500 { + pmi8998_pwm_5: pwm@b500 { compatible = "qcom,qpnp-pwm"; reg = <0xb500 0x100>, <0xb042 0x7e>; @@ -449,7 +449,7 @@ #pwm-cells = <2>; }; - pmicobalt_pwm_6: pwm@b600 { + pmi8998_pwm_6: pwm@b600 { compatible = "qcom,qpnp-pwm"; reg = <0xb600 0x100>, <0xb042 0x7e>; @@ -473,7 +473,7 @@ label = "rgb"; qcom,id = <3>; qcom,mode = "pwm"; - pwms = <&pmicobalt_pwm_5 0 0>; + pwms = <&pmi8998_pwm_5 0 0>; qcom,pwm-us = <1000>; qcom,max-current = <12>; qcom,default-state = "off"; @@ -486,7 +486,7 @@ label = "rgb"; qcom,id = <4>; qcom,mode = "pwm"; - pwms = <&pmicobalt_pwm_4 0 0>; + pwms = <&pmi8998_pwm_4 0 0>; qcom,pwm-us = <1000>; qcom,max-current = <12>; qcom,default-state = "off"; @@ -498,7 +498,7 @@ label = "rgb"; qcom,id = <5>; qcom,mode = "pwm"; - pwms = <&pmicobalt_pwm_3 0 0>; + pwms = <&pmi8998_pwm_3 0 0>; qcom,pwm-us = <1000>; qcom,max-current = <12>; qcom,default-state = "off"; @@ -511,7 +511,7 @@ compatible = "qcom,qpnp-labibb-regulator"; #address-cells = <1>; #size-cells = <1>; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; status = "disabled"; ibb_regulator: qcom,ibb@dc00 { @@ -582,7 +582,7 @@ }; }; - pmicobalt_wled: qcom,leds@d800 { + pmi8998_wled: qcom,leds@d800 { compatible = "qcom,qpnp-wled"; reg = <0xd800 0x100>, <0xd900 0x100>, @@ -598,7 +598,7 @@ linux,name = "wled"; linux,default-trigger = "bkl-trigger"; qcom,fdbk-output = "auto"; - qcom,vref-mv = <350>; + qcom,vref-uv = <127500>; qcom,switch-freq-khz = <800>; qcom,ovp-mv = <29600>; qcom,ilim-ma = <970>; @@ -612,10 +612,11 @@ qcom,en-phase-stag; qcom,led-strings-list = [00 01 02 03]; qcom,en-ext-pfet-sc-pro; - qcom,pmic-revid = <&pmicobalt_revid>; + qcom,pmic-revid = <&pmi8998_revid>; + qcom,loop-auto-gm-en; }; - pmicobalt_haptics: qcom,haptic@c000 { + pmi8998_haptics: qcom,haptic@c000 { status = "disabled"; compatible = "qcom,qpnp-haptic"; reg = <0xc000 0x100>; @@ -657,8 +658,9 @@ qcom,thermal-derate-en; qcom,thermal-derate-current = <200 500 1000>; qcom,isc-delay = <192>; + qcom,pmic-revid = <&pmi8998_revid>; - pmicobalt_flash0: qcom,flash_0 { + pmi8998_flash0: qcom,flash_0 { label = "flash"; qcom,led-name = "led:flash_0"; qcom,max-current = <1500>; @@ -671,7 +673,7 @@ qcom,hdrm-vol-hi-lo-win-mv = <100>; }; - pmicobalt_flash1: qcom,flash_1 { + pmi8998_flash1: qcom,flash_1 { label = "flash"; qcom,led-name = "led:flash_1"; qcom,max-current = <1500>; @@ -684,7 +686,7 @@ qcom,hdrm-vol-hi-lo-win-mv = <100>; }; - pmicobalt_flash2: qcom,flash_2 { + pmi8998_flash2: qcom,flash_2 { label = "flash"; qcom,led-name = "led:flash_2"; qcom,max-current = <750>; @@ -700,7 +702,7 @@ pinctrl-1 = <&led_disable>; }; - pmicobalt_torch0: qcom,torch_0 { + pmi8998_torch0: qcom,torch_0 { label = "torch"; qcom,led-name = "led:torch_0"; qcom,max-current = <500>; @@ -712,7 +714,7 @@ qcom,hdrm-vol-hi-lo-win-mv = <100>; }; - pmicobalt_torch1: qcom,torch_1 { + pmi8998_torch1: qcom,torch_1 { label = "torch"; qcom,led-name = "led:torch_1"; qcom,max-current = <500>; @@ -724,7 +726,7 @@ qcom,hdrm-vol-hi-lo-win-mv = <100>; }; - pmicobalt_torch2: qcom,torch_2 { + pmi8998_torch2: qcom,torch_2 { label = "torch"; qcom,led-name = "led:torch_2"; qcom,max-current = <500>; @@ -739,14 +741,14 @@ pinctrl-1 = <&led_disable>; }; - pmicobalt_switch0: qcom,led_switch_0 { + pmi8998_switch0: qcom,led_switch_0 { label = "switch"; qcom,led-name = "led:switch_0"; qcom,led-mask = <3>; qcom,default-led-trigger = "switch0_trigger"; }; - pmicobalt_switch1: qcom,led_switch_1 { + pmi8998_switch1: qcom,led_switch_1 { label = "switch"; qcom,led-name = "led:switch_1"; qcom,led-mask = <4>; diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index 7e88f524367f..2735cfb93be0 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -1948,6 +1948,8 @@ clock-names = "core_clk", "iface_clk", "bus_aggr_clk", "utmi_clk", "sleep_clk", "xo", "cfg_ahb_clk"; + qcom,core-clk-rate = <120000000>; + resets = <&clock_gcc USB_30_BCR>; reset-names = "core_reset"; @@ -2056,6 +2058,7 @@ <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>; clock-names = "core_clk", "iface_clk", "utmi_clk", "sleep_clk", "xo", "cfg_ahb_clk"; + qcom,core-clk-rate = <60000000>; resets = <&clock_gcc USB_20_BCR>; reset-names = "core_reset"; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi index ca12a520c2aa..506e37c2349a 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi @@ -11,7 +11,7 @@ * GNU General Public License for more details. */ -#include "msmcobalt-wsa881x.dtsi" +#include "msm8998-wsa881x.dtsi" &msm_audio_ion { qcom,smmu-version = <2>; @@ -32,8 +32,8 @@ }; sound-9335 { - compatible = "qcom,msmcobalt-asoc-snd-tasha"; - qcom,model = "msmcobalt-tasha-snd-card"; + compatible = "qcom,msm8998-asoc-snd-tasha"; + qcom,model = "msm8998-tasha-snd-card"; qcom,ext-disp-audio-rx; qcom,wcn-btfm; qcom,mi2s-audio-intf; @@ -145,8 +145,8 @@ }; sound-tavil { - compatible = "qcom,msmcobalt-asoc-snd-tavil"; - qcom,model = "msmcobalt-tavil-snd-card"; + compatible = "qcom,msm8998-asoc-snd-tavil"; + qcom,model = "msm8998-tavil-snd-card"; qcom,ext-disp-audio-rx; qcom,wcn-btfm; qcom,mi2s-audio-intf; @@ -294,7 +294,7 @@ clock_audio: audio_ext_clk { status = "ok"; compatible = "qcom,audio-ref-clk"; - qcom,audio-ref-clk-gpio = <&pmcobalt_gpios 13 0>; + qcom,audio-ref-clk-gpio = <&pm8998_gpios 13 0>; clock-names = "osr_clk"; clocks = <&clock_gcc clk_div_clk1>; qcom,node_has_rpm_clock; @@ -347,23 +347,23 @@ clocks = <&clock_audio clk_audio_pmi_clk>, <&clock_audio clk_audio_ap_clk2>; - cdc-vdd-buck-supply = <&pmcobalt_s4>; + cdc-vdd-buck-supply = <&pm8998_s4>; qcom,cdc-vdd-buck-voltage = <1800000 1800000>; qcom,cdc-vdd-buck-current = <650000>; - cdc-buck-sido-supply = <&pmcobalt_s4>; + cdc-buck-sido-supply = <&pm8998_s4>; qcom,cdc-buck-sido-voltage = <1800000 1800000>; qcom,cdc-buck-sido-current = <250000>; - cdc-vdd-tx-h-supply = <&pmcobalt_s4>; + cdc-vdd-tx-h-supply = <&pm8998_s4>; qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; qcom,cdc-vdd-tx-h-current = <25000>; - cdc-vdd-rx-h-supply = <&pmcobalt_s4>; + cdc-vdd-rx-h-supply = <&pm8998_s4>; qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; qcom,cdc-vdd-rx-h-current = <25000>; - cdc-vddpx-1-supply = <&pmcobalt_s4>; + cdc-vddpx-1-supply = <&pm8998_s4>; qcom,cdc-vddpx-1-voltage = <1800000 1800000>; qcom,cdc-vddpx-1-current = <10000>; @@ -400,23 +400,23 @@ clock-names = "wcd_clk"; clocks = <&clock_audio_lnbb clk_audio_pmi_lnbb_clk>; - cdc-vdd-buck-supply = <&pmcobalt_s4>; + cdc-vdd-buck-supply = <&pm8998_s4>; qcom,cdc-vdd-buck-voltage = <1800000 1800000>; qcom,cdc-vdd-buck-current = <650000>; - cdc-buck-sido-supply = <&pmcobalt_s4>; + cdc-buck-sido-supply = <&pm8998_s4>; qcom,cdc-buck-sido-voltage = <1800000 1800000>; qcom,cdc-buck-sido-current = <250000>; - cdc-vdd-tx-h-supply = <&pmcobalt_s4>; + cdc-vdd-tx-h-supply = <&pm8998_s4>; qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; qcom,cdc-vdd-tx-h-current = <25000>; - cdc-vdd-rx-h-supply = <&pmcobalt_s4>; + cdc-vdd-rx-h-supply = <&pm8998_s4>; qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; qcom,cdc-vdd-rx-h-current = <25000>; - cdc-vddpx-1-supply = <&pmcobalt_s4>; + cdc-vddpx-1-supply = <&pm8998_s4>; qcom,cdc-vddpx-1-voltage = <1800000 1800000>; qcom,cdc-vddpx-1-current = <10000>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-blsp.dtsi b/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi index a660ea06795e..b9e323d894c3 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-blsp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi @@ -39,7 +39,7 @@ }; }; -#include "msmcobalt-pinctrl.dtsi" +#include "msm8998-pinctrl.dtsi" &soc { dma_blsp1: qcom,sps-dma@0xc144000 { /* BLSP1 */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi b/arch/arm/boot/dts/qcom/msm8998-bus.dtsi index edf7e7b9cbb0..edf7e7b9cbb0 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-bus.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-bus.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-cdp.dtsi index ed8eb8459e51..61fc31a17e52 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-cdp.dtsi @@ -15,18 +15,18 @@ led_flash0: qcom,camera-flash@0 { cell-index = <0>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>; - qcom,torch-source = <&pmicobalt_torch0 &pmicobalt_torch1>; - qcom,switch-source = <&pmicobalt_switch0>; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; led_flash1: qcom,camera-flash@1 { cell-index = <1>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash2>; - qcom,torch-source = <&pmicobalt_torch2>; - qcom,switch-source = <&pmicobalt_switch1>; + qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; + qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; }; @@ -82,9 +82,9 @@ cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -99,7 +99,7 @@ &cam_actuator_vaf_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>, <&tlmm 27 0>; qcom,gpio-reset = <1>; @@ -127,9 +127,9 @@ cell-index = <1>; reg = <0x1>; compatible = "qcom,eeprom"; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -164,9 +164,9 @@ cell-index = <2>; reg = <0x2>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -181,7 +181,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -210,9 +210,9 @@ qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -225,7 +225,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -254,9 +254,9 @@ qcom,csid-sd-index = <1>; qcom,mount-angle = <90>; qcom,eeprom-src = <&eeprom1>; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -297,9 +297,9 @@ qcom,eeprom-src = <&eeprom2>; qcom,led-flash-src = <&led_flash1>; qcom,actuator-src = <&actuator1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -314,7 +314,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -332,7 +332,7 @@ qcom,clock-rates = <24000000 0>; }; }; -&pmcobalt_gpios { +&pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ qcom,mode = <1>; /* Output */ qcom,pull = <5>; /* No Pull */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi index 2be67ab52ba7..0bd9ab40e8f1 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-mtp.dtsi @@ -15,18 +15,18 @@ led_flash0: qcom,camera-flash@0 { cell-index = <0>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>; - qcom,torch-source = <&pmicobalt_torch0 &pmicobalt_torch1>; - qcom,switch-source = <&pmicobalt_switch0>; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; led_flash1: qcom,camera-flash@1 { cell-index = <1>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash2>; - qcom,torch-source = <&pmicobalt_torch2>; - qcom,switch-source = <&pmicobalt_switch1>; + qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; + qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; }; @@ -82,9 +82,9 @@ cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -99,7 +99,7 @@ &cam_actuator_vaf_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>, <&tlmm 27 0>; qcom,gpio-reset = <1>; @@ -127,9 +127,9 @@ cell-index = <1>; reg = <0x1>; compatible = "qcom,eeprom"; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -164,9 +164,9 @@ cell-index = <2>; reg = <0x2>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -181,7 +181,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -210,9 +210,9 @@ qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -225,7 +225,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -254,9 +254,9 @@ qcom,csid-sd-index = <1>; qcom,mount-angle = <90>; qcom,eeprom-src = <&eeprom1>; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -297,9 +297,9 @@ qcom,eeprom-src = <&eeprom2>; qcom,led-flash-src = <&led_flash1>; qcom,actuator-src = <&actuator1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -314,7 +314,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -332,7 +332,7 @@ qcom,clock-rates = <24000000 0>; }; }; -&pmcobalt_gpios { +&pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ qcom,mode = <1>; /* Output */ qcom,pull = <5>; /* No Pull */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-qrd-vr1.dtsi index 0fb1a0425dd5..a56e9836784c 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd-vr1.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-qrd-vr1.dtsi @@ -15,16 +15,16 @@ led_flash0: qcom,camera-flash@0 { cell-index = <0>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>; - qcom,switch-source = <&pmicobalt_switch0>; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; led_flash1: qcom,camera-flash@1 { cell-index = <1>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash2>; - qcom,switch-source = <&pmicobalt_switch1>; + qcom,flash-source = <&pmi8998_flash2>; + qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; }; @@ -106,9 +106,9 @@ cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -121,7 +121,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -146,9 +146,9 @@ cell-index = <1>; reg = <0x1>; compatible = "qcom,eeprom"; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -183,9 +183,9 @@ cell-index = <2>; reg = <0x2>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; qcom,cam-vreg-max-voltage = <0 2864000 1352000>; @@ -198,7 +198,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 15 0>, <&tlmm 9 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -226,9 +226,9 @@ qcom,led-flash-src = <&led_flash0>; qcom,actuator-src = <&actuator0>; qcom,eeprom-src = <&eeprom0>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -241,7 +241,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -270,8 +270,8 @@ qcom,csid-sd-index = <1>; qcom,mount-angle = <90>; qcom,eeprom-src = <&eeprom1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 3312000>; qcom,cam-vreg-max-voltage = <0 3600000>; @@ -312,9 +312,9 @@ qcom,eeprom-src = <&eeprom2>; qcom,led-flash-src = <&led_flash1>; qcom,actuator-src = <&actuator1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; qcom,cam-vreg-max-voltage = <0 2864000 1352000>; @@ -327,7 +327,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 15 0>, <&tlmm 9 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -346,7 +346,7 @@ }; }; -&pmcobalt_gpios { +&pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ qcom,mode = <1>; /* Output */ qcom,pull = <5>; /* No Pull */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-qrd.dtsi index 4b435aee73b0..03abb5d69b52 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-qrd.dtsi @@ -16,18 +16,18 @@ led_flash0: qcom,camera-flash@0 { cell-index = <0>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>; - qcom,torch-source = <&pmicobalt_torch0 &pmicobalt_torch1>; - qcom,switch-source = <&pmicobalt_switch0>; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; led_flash1: qcom,camera-flash@1 { cell-index = <1>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash2>; - qcom,torch-source = <&pmicobalt_torch2>; - qcom,switch-source = <&pmicobalt_switch1>; + qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; + qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; }; @@ -83,9 +83,9 @@ cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3312000 1352000>; @@ -100,7 +100,7 @@ &cam_actuator_vaf_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>, <&tlmm 27 0>; qcom,gpio-reset = <1>; @@ -128,9 +128,9 @@ cell-index = <1>; reg = <0x1>; compatible = "qcom,eeprom"; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3312000>; @@ -165,9 +165,9 @@ cell-index = <2>; reg = <0x2>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -182,7 +182,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -211,9 +211,9 @@ qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3312000 1352000>; @@ -226,7 +226,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -255,9 +255,9 @@ qcom,csid-sd-index = <1>; qcom,mount-angle = <90>; qcom,eeprom-src = <&eeprom1>; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3312000>; @@ -298,9 +298,9 @@ qcom,eeprom-src = <&eeprom2>; qcom,led-flash-src = <&led_flash1>; qcom,actuator-src = <&actuator1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -315,7 +315,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -333,7 +333,7 @@ qcom,clock-rates = <24000000 0>; }; }; -&pmcobalt_gpios { +&pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ qcom,mode = <1>; /* Output */ qcom,pull = <5>; /* No Pull */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi index a432f0710fe2..da568fd8979c 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera-sensor-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi @@ -15,16 +15,16 @@ led_flash0: qcom,camera-flash@0 { cell-index = <0>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash0 &pmicobalt_flash1>; - qcom,switch-source = <&pmicobalt_switch0>; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; led_flash1: qcom,camera-flash@1 { cell-index = <1>; compatible = "qcom,camera-flash"; - qcom,flash-source = <&pmicobalt_flash2>; - qcom,switch-source = <&pmicobalt_switch1>; + qcom,flash-source = <&pmi8998_flash2>; + qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; }; @@ -64,9 +64,9 @@ cell-index = <0>; reg = <0>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -79,7 +79,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -104,9 +104,9 @@ cell-index = <1>; reg = <0x1>; compatible = "qcom,eeprom"; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -141,9 +141,9 @@ cell-index = <2>; reg = <0x2>; compatible = "qcom,eeprom"; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -158,7 +158,7 @@ &cam_sensor_front_suspend>; gpios = <&tlmm 14 0>, <&tlmm 28 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -185,9 +185,9 @@ qcom,csid-sd-index = <0>; qcom,mount-angle = <270>; qcom,eeprom-src = <&eeprom0>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 3312000 1352000>; qcom,cam-vreg-max-voltage = <0 3600000 1352000>; @@ -200,7 +200,7 @@ &cam_sensor_rear_suspend>; gpios = <&tlmm 13 0>, <&tlmm 30 0>, - <&pmcobalt_gpios 20 0>, + <&pm8998_gpios 20 0>, <&tlmm 29 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; @@ -229,9 +229,9 @@ qcom,csid-sd-index = <1>; qcom,mount-angle = <90>; qcom,eeprom-src = <&eeprom1>; - cam_vdig-supply = <&pmcobalt_lvs1>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmicobalt_bob>; + cam_vdig-supply = <&pm8998_lvs1>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pmi8998_bob>; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-min-voltage = <0 0 3312000>; qcom,cam-vreg-max-voltage = <0 0 3600000>; @@ -269,9 +269,9 @@ qcom,csiphy-sd-index = <2>; qcom,csid-sd-index = <2>; qcom,mount-angle = <90>; - cam_vio-supply = <&pmcobalt_lvs1>; - cam_vana-supply = <&pmcobalt_l22>; - cam_vdig-supply = <&pmcobalt_s3>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; qcom,cam-vreg-min-voltage = <0 2864000 1352000>; @@ -286,7 +286,7 @@ &cam_sensor_rear2_suspend>; gpios = <&tlmm 15 0>, <&tlmm 9 0>, - <&pmcobalt_gpios 9 0>; + <&pm8998_gpios 9 0>; qcom,gpio-reset = <1>; qcom,gpio-vdig = <2>; qcom,gpio-req-tbl-num = <0 1 2>; @@ -304,7 +304,7 @@ qcom,clock-rates = <24000000 0>; }; }; -&pmcobalt_gpios { +&pm8998_gpios { gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ qcom,mode = <1>; /* Output */ qcom,pull = <5>; /* No Pull */ diff --git a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi index 27e537c9c702..d0fa9921da3f 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi @@ -134,9 +134,9 @@ interrupts = <0 296 0>; interrupt-names = "csid"; qcom,csi-vdd-voltage = <1200000>; - qcom,mipi-csi-vdd-supply = <&pmcobalt_l2>; + qcom,mipi-csi-vdd-supply = <&pm8998_l2>; gdscr-supply = <&gdsc_camss_top>; - vdd_sec-supply = <&pmcobalt_l1>; + vdd_sec-supply = <&pm8998_l1>; bimc_smmu-supply = <&gdsc_bimc_smmu>; qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu"; clocks = <&clock_gcc clk_mmssnoc_axi_clk>, @@ -172,9 +172,9 @@ interrupts = <0 297 0>; interrupt-names = "csid"; qcom,csi-vdd-voltage = <1200000>; - qcom,mipi-csi-vdd-supply = <&pmcobalt_l2>; + qcom,mipi-csi-vdd-supply = <&pm8998_l2>; gdscr-supply = <&gdsc_camss_top>; - vdd_sec-supply = <&pmcobalt_l1>; + vdd_sec-supply = <&pm8998_l1>; bimc_smmu-supply = <&gdsc_bimc_smmu>; qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu"; clocks = <&clock_gcc clk_mmssnoc_axi_clk>, @@ -210,9 +210,9 @@ interrupts = <0 298 0>; interrupt-names = "csid"; qcom,csi-vdd-voltage = <1200000>; - qcom,mipi-csi-vdd-supply = <&pmcobalt_l2>; + qcom,mipi-csi-vdd-supply = <&pm8998_l2>; gdscr-supply = <&gdsc_camss_top>; - vdd_sec-supply = <&pmcobalt_l1>; + vdd_sec-supply = <&pm8998_l1>; bimc_smmu-supply = <&gdsc_bimc_smmu>; qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu"; clocks = <&clock_gcc clk_mmssnoc_axi_clk>, @@ -248,9 +248,9 @@ interrupts = <0 299 0>; interrupt-names = "csid"; qcom,csi-vdd-voltage = <1200000>; - qcom,mipi-csi-vdd-supply = <&pmcobalt_l2>; + qcom,mipi-csi-vdd-supply = <&pm8998_l2>; gdscr-supply = <&gdsc_camss_top>; - vdd_sec-supply = <&pmcobalt_l1>; + vdd_sec-supply = <&pm8998_l1>; bimc_smmu-supply = <&gdsc_bimc_smmu>; qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu"; clocks = <&clock_gcc clk_mmssnoc_axi_clk>, @@ -422,6 +422,8 @@ qcom,msm-bus-vector-dyn-vote; resets = <&clock_mmss CAMSS_MICRO_BCR>; reset-names = "micro_iface_reset"; + qcom,src-clock-rates = <100000000 200000000 576000000 + 600000000>; qcom,cpp-fw-payload-info { qcom,stripe-base = <790>; qcom,plane-base = <715>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-cdp.dts index 10edf71da2f3..487d71d4b6a8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-cdp.dts @@ -13,12 +13,12 @@ /dts-v1/; -#include "msmcobalt.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "msm8998.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v1 CDP"; - compatible = "qcom,msmcobalt-cdp", "qcom,msmcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v1 CDP"; + compatible = "qcom,msm8998-cdp", "qcom,msm8998", "qcom,cdp"; qcom,board-id = <1 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi index ca504a798659..ec57ab601d46 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi @@ -10,17 +10,17 @@ * GNU General Public License for more details. */ -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-cdp.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-camera-sensor-cdp.dtsi" / { bluetooth: bt_wcn3990 { compatible = "qca,wcn3990"; - qca,bt-vdd-io-supply = <&pmcobalt_s3>; - qca,bt-vdd-xtal-supply = <&pmcobalt_s5>; - qca,bt-vdd-core-supply = <&pmcobalt_l7>; - qca,bt-vdd-pa-supply = <&pmcobalt_l17>; - qca,bt-vdd-ldo-supply = <&pmcobalt_l25>; - qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>; + 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"; @@ -44,9 +44,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -57,9 +57,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -71,11 +71,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -98,7 +98,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 5 for Home Key */ gpio@c400 { status = "okay"; @@ -167,8 +167,8 @@ reg = <0x20>; interrupt-parent = <&tlmm>; interrupts = <125 0x2008>; - vdd-supply = <&pmcobalt_l6>; - avdd-supply = <&pmcobalt_l28>; + vdd-supply = <&pm8998_l6>; + avdd-supply = <&pm8998_l28>; synaptics,vdd-voltage = <1808000 1808000>; synaptics,avdd-voltage = <3008000 3008000>; synaptics,vdd-current = <40000>; @@ -193,7 +193,7 @@ qcom,nq-irq = <&tlmm 92 0x00>; qcom,nq-ven = <&tlmm 12 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK3"; @@ -302,7 +302,7 @@ qcom,qpnp-labibb-mode = "lcd"; }; -&pmicobalt_wled { +&pmi8998_wled { qcom,led-strings-list = [00 01]; }; @@ -432,15 +432,15 @@ qcom,usbplug-cc-gpio = <&tlmm 38 0>; }; -&pmicobalt_charger { +&pmi8998_charger { qcom,batteryless-platform; }; -&pmicobalt_haptics { +&pmi8998_haptics { status = "okay"; }; -&pmcobalt_vadc { +&pm8998_vadc { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -497,7 +497,7 @@ }; }; -&pmcobalt_adc_tm { +&pm8998_adc_tm { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -554,7 +554,7 @@ home { label = "home"; - gpios = <&pmcobalt_gpios 5 0x1>; + gpios = <&pm8998_gpios 5 0x1>; linux,input-type = <1>; linux,code = <102>; gpio-key,wakeup; @@ -564,7 +564,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -573,7 +573,7 @@ cam_snapshot { label = "cam_snapshot"; - gpios = <&pmcobalt_gpios 7 0x1>; + gpios = <&pm8998_gpios 7 0x1>; linux,input-type = <1>; linux,code = <766>; gpio-key,wakeup; @@ -582,7 +582,7 @@ cam_focus { label = "cam_focus"; - gpios = <&pmcobalt_gpios 8 0x1>; + gpios = <&pm8998_gpios 8 0x1>; linux,input-type = <1>; linux,code = <528>; gpio-key,wakeup; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi index aeb6bf6141d8..aeb6bf6141d8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi index 8739e8f22549..8739e8f22549 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-gpu.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi new file mode 100644 index 000000000000..20c69e0a9a1a --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi @@ -0,0 +1,73 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&clock_audio { + qcom,audio-ref-clk-gpio = <&pmfalcon_gpios 3 0>; +}; + +&slim_aud { + tasha_codec { + cdc-vdd-buck-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-buck-voltage = <1800000 1800000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-buck-sido-supply = <&pmfalcon_s4>; + qcom,cdc-buck-sido-voltage = <1800000 1800000>; + qcom,cdc-buck-sido-current = <250000>; + + cdc-vdd-tx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pmfalcon_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + }; + + tavil_codec { + cdc-vdd-buck-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-buck-voltage = <1800000 1800000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-buck-sido-supply = <&pmfalcon_s4>; + qcom,cdc-buck-sido-voltage = <1800000 1800000>; + qcom,cdc-buck-sido-current = <250000>; + + cdc-vdd-tx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pmfalcon_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + }; +}; + +&pmfalcon_gpios { + gpio@c200 { + status = "ok"; + qcom,mode = <1>; + qcom,pull = <5>; + qcom,vin-sel = <0>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + qcom,out-strength = <2>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi index 4822823aa63f..32f9dcdecb0c 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi @@ -10,17 +10,17 @@ * GNU General Public License for more details. */ -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-cdp.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-camera-sensor-cdp.dtsi" / { bluetooth: bt_wcn3990 { compatible = "qca,wcn3990"; - qca,bt-vdd-io-supply = <&pmcobalt_s3>; - qca,bt-vdd-xtal-supply = <&pmcobalt_s5>; - qca,bt-vdd-core-supply = <&pmcobalt_l7_pin_ctrl>; - qca,bt-vdd-pa-supply = <&pmcobalt_l17_pin_ctrl>; - qca,bt-vdd-ldo-supply = <&pmcobalt_l25_pin_ctrl>; - qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>; + qca,bt-vdd-io-supply = <&pm8998_s3>; + qca,bt-vdd-xtal-supply = <&pm8998_s5>; + qca,bt-vdd-core-supply = <&pm8998_l7_pin_ctrl>; + qca,bt-vdd-pa-supply = <&pm8998_l17_pin_ctrl>; + qca,bt-vdd-ldo-supply = <&pm8998_l25_pin_ctrl>; + qca,bt-chip-pwd-supply = <&pmi8998_bob_pin1>; clocks = <&clock_gcc clk_rf_clk2>; clock-names = "rf_clk2"; @@ -44,9 +44,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l1>; + vddp-ref-clk-supply = <&pmfalcon_l1>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -57,12 +57,10 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; - vcc-max-microamp = <750000>; - vccq-max-microamp = <560000>; - vccq2-max-microamp = <750000>; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; status = "ok"; }; @@ -71,11 +69,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -98,7 +96,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 5 for Home Key */ gpio@c400 { status = "okay"; @@ -167,8 +165,8 @@ reg = <0x20>; interrupt-parent = <&tlmm>; interrupts = <125 0x2008>; - vdd-supply = <&pmcobalt_l6>; - avdd-supply = <&pmcobalt_l28>; + vdd-supply = <&pm8998_l6>; + avdd-supply = <&pm8998_l28>; synaptics,vdd-voltage = <1808000 1808000>; synaptics,avdd-voltage = <3008000 3008000>; synaptics,vdd-current = <40000>; @@ -193,7 +191,7 @@ qcom,nq-irq = <&tlmm 92 0x00>; qcom,nq-ven = <&tlmm 12 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK3"; @@ -275,10 +273,15 @@ &mdss_dsi { hw-config = "split_dsi"; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; }; &mdss_dsi0 { - qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_video>; + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; @@ -288,7 +291,10 @@ }; &mdss_dsi1 { - qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_video>; + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; @@ -302,7 +308,7 @@ qpnp,qpnp-labibb-mode = "lcd"; }; -&pmicobalt_wled { +&pmi8998_wled { qcom,led-strings-list = [00 01]; }; @@ -424,6 +430,8 @@ }; &mdss_dp_ctrl { + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; pinctrl-names = "mdss_dp_active", "mdss_dp_sleep"; pinctrl-0 = <&mdss_dp_aux_active &mdss_dp_usbplug_cc_active>; pinctrl-1 = <&mdss_dp_aux_suspend &mdss_dp_usbplug_cc_suspend>; @@ -432,15 +440,15 @@ qcom,usbplug-cc-gpio = <&tlmm 38 0>; }; -&pmicobalt_charger { +&pmi8998_charger { qcom,batteryless-platform; }; -&pmicobalt_haptics { +&pmi8998_haptics { status = "okay"; }; -&pmcobalt_vadc { +&pm8998_vadc { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -497,7 +505,7 @@ }; }; -&pmcobalt_adc_tm { +&pm8998_adc_tm { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -554,7 +562,7 @@ home { label = "home"; - gpios = <&pmcobalt_gpios 5 0x1>; + gpios = <&pm8998_gpios 5 0x1>; linux,input-type = <1>; linux,code = <102>; gpio-key,wakeup; @@ -564,7 +572,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -573,7 +581,7 @@ cam_snapshot { label = "cam_snapshot"; - gpios = <&pmcobalt_gpios 7 0x1>; + gpios = <&pm8998_gpios 7 0x1>; linux,input-type = <1>; linux,code = <766>; gpio-key,wakeup; @@ -582,7 +590,7 @@ cam_focus { label = "cam_focus"; - gpios = <&pmcobalt_gpios 8 0x1>; + gpios = <&pm8998_gpios 8 0x1>; linux,input-type = <1>; linux,code = <528>; gpio-key,wakeup; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi index b77bab712ecf..e73ffc884210 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi @@ -11,17 +11,17 @@ */ #include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-mtp.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-camera-sensor-mtp.dtsi" / { bluetooth: bt_wcn3990 { compatible = "qca,wcn3990"; - qca,bt-vdd-io-supply = <&pmcobalt_s3>; - qca,bt-vdd-xtal-supply = <&pmcobalt_s5>; - qca,bt-vdd-core-supply = <&pmcobalt_l7_pin_ctrl>; - qca,bt-vdd-pa-supply = <&pmcobalt_l17_pin_ctrl>; - qca,bt-vdd-ldo-supply = <&pmcobalt_l25_pin_ctrl>; - qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>; + qca,bt-vdd-io-supply = <&pm8998_s3>; + qca,bt-vdd-xtal-supply = <&pm8998_s5>; + qca,bt-vdd-core-supply = <&pm8998_l7_pin_ctrl>; + qca,bt-vdd-pa-supply = <&pm8998_l17_pin_ctrl>; + qca,bt-vdd-ldo-supply = <&pm8998_l25_pin_ctrl>; + qca,bt-chip-pwd-supply = <&pmi8998_bob_pin1>; clocks = <&clock_gcc clk_rf_clk2>; clock-names = "rf_clk2"; @@ -45,9 +45,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l1>; + vddp-ref-clk-supply = <&pmfalcon_l1>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -58,12 +58,10 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; - vcc-max-microamp = <750000>; - vccq-max-microamp = <560000>; - vccq2-max-microamp = <750000>; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; status = "ok"; }; @@ -72,11 +70,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -99,7 +97,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 6 for Vol+ Key */ gpio@c500 { status = "okay"; @@ -168,8 +166,8 @@ reg = <0x20>; interrupt-parent = <&tlmm>; interrupts = <125 0x2008>; - vdd-supply = <&pmcobalt_l6>; - avdd-supply = <&pmcobalt_l28>; + vdd-supply = <&pm8998_l6>; + avdd-supply = <&pm8998_l28>; synaptics,vdd-voltage = <1808000 1808000>; synaptics,avdd-voltage = <3008000 3008000>; synaptics,vdd-current = <40000>; @@ -194,7 +192,7 @@ qcom,nq-irq = <&tlmm 92 0x00>; qcom,nq-ven = <&tlmm 12 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK3"; @@ -314,6 +312,8 @@ }; &mdss_dp_ctrl { + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; pinctrl-names = "mdss_dp_active", "mdss_dp_sleep"; pinctrl-0 = <&mdss_dp_aux_active &mdss_dp_usbplug_cc_active>; pinctrl-1 = <&mdss_dp_aux_suspend &mdss_dp_usbplug_cc_suspend>; @@ -328,10 +328,15 @@ &mdss_dsi { hw-config = "split_dsi"; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; }; &mdss_dsi0 { - qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_video>; + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; @@ -341,7 +346,10 @@ }; &mdss_dsi1 { - qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_video>; + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; @@ -355,7 +363,7 @@ qpnp,qpnp-labibb-mode = "lcd"; }; -&pmicobalt_wled { +&pmi8998_wled { qcom,led-strings-list = [00 01]; }; @@ -459,11 +467,11 @@ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; -&pmicobalt_haptics { +&pmi8998_haptics { status = "okay"; }; -&pmcobalt_vadc { +&pm8998_vadc { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -520,7 +528,7 @@ }; }; -&pmcobalt_adc_tm { +&pm8998_adc_tm { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -577,7 +585,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -586,7 +594,7 @@ cam_snapshot { label = "cam_snapshot"; - gpios = <&pmcobalt_gpios 7 0x1>; + gpios = <&pm8998_gpios 7 0x1>; linux,input-type = <1>; linux,code = <766>; gpio-key,wakeup; @@ -595,7 +603,7 @@ cam_focus { label = "cam_focus"; - gpios = <&pmcobalt_gpios 8 0x1>; + gpios = <&pm8998_gpios 8 0x1>; linux,input-type = <1>; linux,code = <528>; gpio-key,wakeup; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi index ffb42576ffd3..1ca5ce6eabbb 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi @@ -11,13 +11,13 @@ */ #include "skeleton64.dtsi" -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include <dt-bindings/regulator/qcom,rpm-smd-regulator.h> #include <dt-bindings/interrupt-controller/arm-gic.h> / { - model = "Qualcomm Technologies, Inc. MSM COBALT"; - compatible = "qcom,msmcobalt"; + model = "Qualcomm Technologies, Inc. MSM 8998"; + compatible = "qcom,msm8998"; qcom,msm-id = <292 0x0>; interrupt-parent = <&intc>; @@ -342,8 +342,8 @@ }; }; -#include "msmcobalt-smp2p.dtsi" -#include "msm-gdsc-cobalt.dtsi" +#include "msm8998-smp2p.dtsi" +#include "msm-gdsc-8998.dtsi" &soc { #address-cells = <1>; @@ -732,21 +732,21 @@ }; clock_gcc: qcom,gcc@100000 { - compatible = "qcom,gcc-cobalt"; + compatible = "qcom,gcc-8998"; reg = <0x100000 0xb0000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; - vdd_dig_ao-supply = <&pmcobalt_s1_level_ao>; + vdd_dig-supply = <&pm8998_s1_level>; + vdd_dig_ao-supply = <&pm8998_s1_level_ao>; #clock-cells = <1>; #reset-cells = <1>; }; clock_mmss: qcom,mmsscc@c8c0000 { - compatible = "qcom,mmsscc-cobalt"; + compatible = "qcom,mmsscc-8998"; reg = <0xc8c0000 0x40000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; - vdd_mmsscc_mx-supply = <&pmcobalt_s9_level>; + vdd_dig-supply = <&pm8998_s1_level>; + vdd_mmsscc_mx-supply = <&pm8998_s9_level>; clock-names = "xo", "gpll0", "gpll0_div", "pclk0_src", "pclk1_src", "byte0_src", "byte1_src", @@ -767,10 +767,10 @@ }; clock_gpu: qcom,gpucc@5065000 { - compatible = "qcom,gpucc-cobalt"; + compatible = "qcom,gpucc-8998"; reg = <0x5065000 0x9000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; + vdd_dig-supply = <&pm8998_s1_level>; clock-names = "xo_ao", "gpll0"; clocks = <&clock_gcc clk_cxo_clk_src_ao>, <&clock_gcc clk_gcc_gpu_gpll0_clk>; @@ -778,12 +778,12 @@ }; clock_gfx: qcom,gfxcc@5065000 { - compatible = "qcom,gfxcc-cobalt"; + compatible = "qcom,gfxcc-8998"; reg = <0x5065000 0x9000>; reg-names = "cc_base"; vdd_gpucc-supply = <&gfx_vreg>; - vdd_mx-supply = <&pmcobalt_s9_level>; - vdd_gpu_mx-supply = <&pmcobalt_s9_level>; + vdd_mx-supply = <&pm8998_s9_level>; + vdd_gpu_mx-supply = <&pm8998_s9_level>; qcom,gfx3d_clk_src-opp-handle = <&msm_gpu>; qcom,gfxfreq-speedbin0 = < 0 0 0 >, @@ -804,8 +804,8 @@ #clock-cells = <1>; }; - clock_cpu: qcom,cpu-clock-cobalt@179c0000 { - compatible = "qcom,cpu-clock-osm-msmcobalt-v1"; + clock_cpu: qcom,cpu-clock-8998@179c0000 { + compatible = "qcom,cpu-clock-osm-msm8998-v1"; reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, <0x17816000 0x1000>, @@ -942,7 +942,7 @@ }; clock_debug: qcom,debugcc@162000 { - compatible = "qcom,cc-debug-cobalt"; + compatible = "qcom,cc-debug-8998"; reg = <0x162000 0x4>; reg-names = "cc_base"; clock-names = "debug_gpu_clk", "debug_gfx_clk", @@ -1560,9 +1560,9 @@ wake-gpio = <&tlmm 37 0>; gdsc-vdd-supply = <&gdsc_pcie_0>; - vreg-1.8-supply = <&pmcobalt_l2>; - vreg-0.9-supply = <&pmcobalt_l1>; - vreg-cx-supply = <&pmcobalt_s1_level>; + vreg-1.8-supply = <&pm8998_l2>; + vreg-0.9-supply = <&pm8998_l1>; + vreg-cx-supply = <&pm8998_s1_level>; qcom,vreg-1.8-voltage-level = <1200000 1200000 24000>; qcom,vreg-0.9-voltage-level = <880000 880000 24000>; @@ -1853,7 +1853,7 @@ <61 512 240000 800000>; qcom,dwc-usb3-msm-tx-fifo-size = <21288>; - extcon = <&pmicobalt_pdphy>; + extcon = <&pmfalcon_pdphy>; clocks = <&clock_gcc clk_gcc_usb30_master_clk>, <&clock_gcc clk_gcc_cfg_noc_usb3_axi_clk>, @@ -1921,9 +1921,9 @@ <0x01fcb24c 0x4>; reg-names = "qusb_phy_base", "tcsr_clamp_dig_n_1p8"; - vdd-supply = <&pmcobalt_l1>; - vdda18-supply = <&pmcobalt_l12>; - vdda33-supply = <&pmcobalt_l24>; + vdd-supply = <&pm2falcon_l1>; + vdda18-supply = <&pm2falcon_l10>; + vdda33-supply = <&pm2falcon_l7>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,qusb-phy-init-seq = /* <value reg_offset> */ @@ -1951,8 +1951,8 @@ reg-names = "qmp_phy_base", "vls_clamp_reg", "tcsr_usb3_dp_phymode"; - vdd-supply = <&pmcobalt_l1>; - core-supply = <&pmcobalt_l2>; + vdd-supply = <&pm2falcon_l1>; + core-supply = <&pmfalcon_l1>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,vbus-valid-override; qcom,qmp-phy-init-seq = @@ -2121,7 +2121,7 @@ reg = <0x17300000 0x00100>; interrupts = <0 162 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; qcom,proxy-reg-names = "vdd_cx"; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>; @@ -2176,9 +2176,9 @@ "mnoc_axi_clk"; interrupts = <0 448 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>; - vdd_mx-supply = <&pmcobalt_s9_level>; + vdd_mx-supply = <&pm8998_s9_level>; vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>; qcom,firmware-name = "modem"; qcom,pil-self-auth; @@ -2202,7 +2202,7 @@ }; tsens0: tsens@10aa000 { - compatible = "qcom,msmcobalt-tsens"; + compatible = "qcom,msm8998-tsens"; reg = <0x10aa000 0x2000>; reg-names = "tsens_physical"; interrupts = <0 458 0>, <0 445 0>; @@ -2213,7 +2213,7 @@ }; tsens1: tsens@10ad000 { - compatible = "qcom,msmcobalt-tsens"; + compatible = "qcom,msm8998-tsens"; reg = <0x10ad000 0x2000>; reg-names = "tsens_physical"; interrupts = <0 184 0>, <0 430 0>; @@ -2538,7 +2538,7 @@ qcom,vdd-restriction-temp = <5>; qcom,vdd-restriction-temp-hysteresis = <10>; - vdd-dig-supply = <&pmcobalt_s1_floor_level>; + vdd-dig-supply = <&pm8998_s1_floor_level>; vdd-gfx-supply = <&gfx_vreg>; qcom,vdd-dig-rstr{ @@ -2587,8 +2587,8 @@ reg = <0x5c00000 0x4000>; interrupts = <0 390 1>; - vdd_cx-supply = <&pmcobalt_l27_level>; - vdd_px-supply = <&pmcobalt_lvs2>; + vdd_cx-supply = <&pm8998_l27_level>; + vdd_px-supply = <&pm8998_lvs2>; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 0>; qcom,proxy-reg-names = "vdd_cx", "vdd_px"; qcom,keep-proxy-regs-on; @@ -2671,7 +2671,7 @@ "sp2soc_irq_mask", "rmb_err", "rmb_err_spare2"; interrupts = <0 352 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; qcom,proxy-reg-names = "vdd_cx"; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>; @@ -2953,8 +2953,8 @@ <45 512 0 0>, <45 512 600000 800000>; /* ~4.6Gbps (MCS12) */ qcom,use-ext-supply; - vdd-supply= <&pmcobalt_s7>; - vddio-supply= <&pmcobalt_s5>; + vdd-supply= <&pm8998_s7>; + vddio-supply= <&pm8998_s5>; qcom,use-ext-clocks; clocks = <&clock_gcc clk_rf_clk3>, <&clock_gcc clk_rf_clk3_pin>; @@ -3067,28 +3067,27 @@ status = "ok"; }; -#include "msm-pmcobalt.dtsi" -#include "msm-pmicobalt.dtsi" +#include "msm-pm8998.dtsi" +#include "msm-pmi8998.dtsi" #include "msm-pm8005.dtsi" -#include "msm-pmcobalt-rpm-regulator.dtsi" -#include "msmcobalt-regulator.dtsi" - -#include "msmcobalt-pm.dtsi" -#include "msm-arm-smmu-cobalt.dtsi" -#include "msm-arm-smmu-impl-defs-cobalt.dtsi" -#include "msmcobalt-ion.dtsi" -#include "msmcobalt-camera.dtsi" -#include "msmcobalt-vidc.dtsi" -#include "msmcobalt-coresight.dtsi" -#include "msmcobalt-bus.dtsi" -#include "msmcobalt-gpu.dtsi" -#include "msmcobalt-pinctrl.dtsi" -#include "msm-audio-lpass.dtsi" -#include "msmcobalt-mdss.dtsi" -#include "msmcobalt-mdss-pll.dtsi" -#include "msmcobalt-blsp.dtsi" -#include "msmcobalt-audio.dtsi" - +#include "msm-pm8998-rpm-regulator.dtsi" +#include "msm8998-regulator.dtsi" + +#include "msm8998-pm.dtsi" +#include "msm-arm-smmu-8998.dtsi" +#include "msm-arm-smmu-impl-defs-8998.dtsi" +#include "msm8998-ion.dtsi" +#include "msm8998-camera.dtsi" +#include "msm8998-vidc.dtsi" +#include "msm8998-coresight.dtsi" +#include "msm8998-bus.dtsi" +#include "msm8998-gpu.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-mdss.dtsi" +#include "msm8998-mdss-pll.dtsi" +#include "msm8998-blsp.dtsi" +#include "msm-audio.dtsi" +#include "msmfalcon-audio.dtsi" /* GPU overrides */ &msm_gpu { diff --git a/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi index 274281f7c982..e83191ebfbc0 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-interposer-pmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi @@ -81,18 +81,6 @@ /delete-property/qca,bt-chip-pwd-supply; }; -&ufsphy1 { - /delete-property/vdda-phy-supply; - /delete-property/vdda-pll-supply; - /delete-property/vddp-ref-clk-supply; -}; - -&ufs1 { - /delete-property/vcc-supply; - /delete-property/vccq-supply; - /delete-property/vccq2-supply; -}; - &sdhc_2 { /delete-property/vdd-supply; /delete-property/vdd-io-supply; @@ -211,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; @@ -224,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; @@ -275,5 +263,23 @@ #include "msm-pmfalcon.dtsi" #include "msm-pm2falcon.dtsi" +#include "msm-pmfalcon-rpm-regulator.dtsi" +#include "msm-pm2falcon-rpm-regulator.dtsi" #include "msmfalcon-regulator.dtsi" +/* dummy LCDB regulator nodes */ +&soc { + lcdb_ldo_vreg: regulator-vdisp-vreg { + compatible = "qcom,stub-regulator"; + regulator-name = "lcdb_ldo"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <6000000>; + }; + + lcdb_ncp_vreg: regulator-vdisn-vreg { + compatible = "qcom,stub-regulator"; + regulator-name = "lcdb_ncp"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <6000000>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi b/arch/arm/boot/dts/qcom/msm8998-ion.dtsi index 7b15fd81c710..7b15fd81c710 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-ion.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-ion.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi index 6afd593f9610..6afd593f9610 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mdss-panels.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss-pll.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss-pll.dtsi index af0eb60818fb..d12b0ea1a9cc 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mdss-pll.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mdss-pll.dtsi @@ -12,7 +12,7 @@ &soc { mdss_dsi0_pll: qcom,mdss_dsi_pll@c994400 { - compatible = "qcom,mdss_dsi_pll_cobalt"; + compatible = "qcom,mdss_dsi_pll_8998"; status = "ok"; label = "MDSS DSI 0 PLL"; cell-index = <0>; @@ -48,7 +48,7 @@ }; mdss_dsi1_pll: qcom,mdss_dsi_pll@c996400 { - compatible = "qcom,mdss_dsi_pll_cobalt"; + compatible = "qcom,mdss_dsi_pll_8998"; status = "ok"; label = "MDSS DSI 1 PLL"; cell-index = <1>; @@ -83,7 +83,7 @@ }; mdss_dp_pll: qcom,mdss_dp_pll@c011000 { - compatible = "qcom,mdss_dp_pll_cobalt"; + compatible = "qcom,mdss_dp_pll_8998"; status = "ok"; label = "MDSS DP PLL"; cell-index = <0>; @@ -119,7 +119,7 @@ }; mdss_hdmi_pll: qcom,mdss_hdmi_pll@0xc9a0600 { - compatible = "qcom,mdss_hdmi_pll_cobalt"; + compatible = "qcom,mdss_hdmi_pll_8998"; label = "MDSS HDMI PLL"; cell-index = <2>; #clock-cells = <1>; @@ -130,8 +130,8 @@ reg-names = "pll_base", "phy_base", "gdsc_base"; gdsc-supply = <&gdsc_mdss>; - vdda-pll-supply = <&pmcobalt_l2>; - vdda-phy-supply = <&pmcobalt_l12>; + vdda-pll-supply = <&pm8998_l2>; + vdda-phy-supply = <&pm8998_l12>; clocks = <&clock_mmss clk_mmss_mdss_ahb_clk>, <&clock_gcc clk_gcc_hdmi_clkref_clk>, diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi index 75c985189842..dd2efefe264f 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi @@ -284,8 +284,8 @@ #address-cells = <1>; #size-cells = <1>; gdsc-supply = <&gdsc_mdss>; - vdda-1p2-supply = <&pmcobalt_l2>; - vdda-0p9-supply = <&pmcobalt_l1>; + vdda-1p2-supply = <&pm8998_l2>; + vdda-0p9-supply = <&pm8998_l1>; ranges = <0xc994000 0xc994000 0x400 0xc994400 0xc994400 0x7c0 0xc828000 0xc828000 0xac @@ -373,7 +373,7 @@ reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; qcom,timing-db-mode; - wqhd-vddio-supply = <&pmcobalt_l14>; + wqhd-vddio-supply = <&pm8998_l14>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; qcom,mdss-mdp = <&mdss_mdp>; @@ -411,7 +411,7 @@ reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; qcom,timing-db-mode; - wqhd-vddio-supply = <&pmcobalt_l14>; + wqhd-vddio-supply = <&pm8998_l14>; lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; qcom,mdss-mdp = <&mdss_mdp>; @@ -462,8 +462,8 @@ qcom,mdss-fb-map = <&mdss_fb3>; gdsc-supply = <&gdsc_mdss>; - vdda-1p2-supply = <&pmcobalt_l2>; - vdda-0p9-supply = <&pmcobalt_l1>; + vdda-1p2-supply = <&pm8998_l2>; + vdda-0p9-supply = <&pm8998_l1>; reg = <0xc990000 0xa84>, <0xc011000 0x910>, @@ -492,7 +492,7 @@ "ctrl_link_clk", "ctrl_link_iface_clk", "ctrl_crypto_clk", "ctrl_pixel_clk"; - qcom,dp-usbpd-detection = <&pmicobalt_pdphy>; + qcom,dp-usbpd-detection = <&pmi8998_pdphy>; qcom,msm_ext_disp = <&msm_ext_disp>; @@ -643,4 +643,4 @@ }; }; -#include "msmcobalt-mdss-panels.dtsi" +#include "msm8998-mdss-panels.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-mtp.dts index ea4047df25f6..f608f5f59a80 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-mtp.dts @@ -13,12 +13,12 @@ /dts-v1/; -#include "msmcobalt.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "msm8998.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v1 MTP"; - compatible = "qcom,msmcobalt-mtp", "qcom,msmcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v1 MTP"; + compatible = "qcom,msm8998-mtp", "qcom,msm8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi index 0cd6d0ab1f1d..76124833dc36 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi @@ -11,17 +11,17 @@ */ #include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-mtp.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-camera-sensor-mtp.dtsi" / { bluetooth: bt_wcn3990 { compatible = "qca,wcn3990"; - qca,bt-vdd-io-supply = <&pmcobalt_s3>; - qca,bt-vdd-xtal-supply = <&pmcobalt_s5>; - qca,bt-vdd-core-supply = <&pmcobalt_l7>; - qca,bt-vdd-pa-supply = <&pmcobalt_l17>; - qca,bt-vdd-ldo-supply = <&pmcobalt_l25>; - qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>; + 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"; @@ -45,9 +45,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -58,9 +58,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -72,11 +72,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -99,7 +99,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 2 for Home Key */ gpio@c100 { status = "okay"; @@ -178,8 +178,8 @@ reg = <0x20>; interrupt-parent = <&tlmm>; interrupts = <125 0x2008>; - vdd-supply = <&pmcobalt_l6>; - avdd-supply = <&pmcobalt_l28>; + vdd-supply = <&pm8998_l6>; + avdd-supply = <&pm8998_l28>; synaptics,vdd-voltage = <1808000 1808000>; synaptics,avdd-voltage = <3008000 3008000>; synaptics,vdd-current = <40000>; @@ -204,7 +204,7 @@ qcom,nq-irq = <&tlmm 92 0x00>; qcom,nq-ven = <&tlmm 12 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK3"; @@ -365,7 +365,7 @@ qcom,qpnp-labibb-mode = "lcd"; }; -&pmicobalt_wled { +&pmi8998_wled { qcom,led-strings-list = [00 01]; }; @@ -473,11 +473,11 @@ qcom,peripheral-size = <0x500000>; }; -&pmicobalt_haptics { +&pmi8998_haptics { status = "okay"; }; -&pmcobalt_vadc { +&pm8998_vadc { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -534,7 +534,7 @@ }; }; -&pmcobalt_adc_tm { +&pm8998_adc_tm { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -591,7 +591,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -600,7 +600,7 @@ cam_snapshot { label = "cam_snapshot"; - gpios = <&pmcobalt_gpios 7 0x1>; + gpios = <&pm8998_gpios 7 0x1>; linux,input-type = <1>; linux,code = <766>; gpio-key,wakeup; @@ -609,7 +609,7 @@ cam_focus { label = "cam_focus"; - gpios = <&pmcobalt_gpios 8 0x1>; + gpios = <&pm8998_gpios 8 0x1>; linux,input-type = <1>; linux,code = <528>; gpio-key,wakeup; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi index e5fd988dccce..5685e9041fe4 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi @@ -12,7 +12,7 @@ &soc { tlmm: pinctrl@03400000 { - compatible = "qcom,msmcobalt-pinctrl"; + compatible = "qcom,msm8998-pinctrl"; reg = <0x03400000 0xc00000>; interrupts = <0 208 0>; gpio-controller; @@ -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/msmcobalt-pm.dtsi b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi index c6d7defbf35c..c6d7defbf35c 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts index 88a5e945436c..d9afddd0ab46 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt.dtsi" -#include "msmcobalt-qrd-skuk.dtsi" +#include "msm8998.dtsi" +#include "msm8998-qrd-skuk.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT SKUK"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 SKUK"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <0x01000b 0x80>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index 7045208b690e..c09900597d87 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -11,18 +11,45 @@ */ #include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-audio.dtsi" -#include "msmcobalt-camera-sensor-skuk.dtsi" +#include "msm8998-pinctrl.dtsi" +#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"; }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -33,9 +60,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -47,11 +74,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -74,7 +101,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 6 for Vol+ Key */ gpio@c500 { status = "okay"; @@ -94,7 +121,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -103,7 +130,7 @@ }; sound-tavil { - qcom,model = "msmcobalt-skuk-tavil-snd-card"; + qcom,model = "msm8998-skuk-tavil-snd-card"; qcom,audio-routing = "AIF4 VI", "MCLK", @@ -203,6 +230,112 @@ }; }; -&pmicobalt_fg { +&pmi8998_fg { qcom,battery-data = <&qrd_batterydata>; }; + +&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/msmcobalt-qrd-vr1.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts index e53912071502..f5780529c99a 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt.dtsi" -#include "msmcobalt-qrd-vr1.dtsi" +#include "msm8998.dtsi" +#include "msm8998-qrd-vr1.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT VR1 Board"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 VR1 Board"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <0x02000b 0x80>; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi new file mode 100644 index 000000000000..bd9d8147dd82 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi @@ -0,0 +1,275 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#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"; +}; + +&ufsphy1 { + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; + vdda-phy-max-microamp = <51400>; + vdda-pll-max-microamp = <14600>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + status = "ok"; +}; + +&ufs1 { + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; + vcc-max-microamp = <750000>; + vccq-max-microamp = <560000>; + vccq2-max-microamp = <750000>; + status = "ok"; +}; + +&ufs_ice { + status = "ok"; +}; + +&sdhc_2 { + vdd-supply = <&pm8998_l21>; + qcom,vdd-voltage-level = <2950000 2960000>; + qcom,vdd-current-level = <200 800000>; + + vdd-io-supply = <&pm8998_l13>; + qcom,vdd-io-voltage-level = <1808000 2960000>; + qcom,vdd-io-current-level = <200 22000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + + qcom,clk-rates = <400000 20000000 25000000 + 50000000 100000000 200000000>; + qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; + + cd-gpios = <&tlmm 95 0x0>; + + status = "ok"; +}; + +&uartblsp2dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&pm8998_gpios { + /* GPIO 6 for Vol+ Key */ + gpio@c500 { + status = "okay"; + qcom,mode = <0>; + qcom,pull = <0>; + qcom,vin-sel = <0>; + qcom,src-sel = <0>; + qcom,out-strength = <1>; + }; +}; + +&soc { + gpio_keys { + compatible = "gpio-keys"; + input-name = "gpio-keys"; + status = "okay"; + + vol_up { + label = "volume_up"; + gpios = <&pm8998_gpios 6 0x1>; + linux,input-type = <1>; + linux,code = <115>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + }; + + sound-tavil { + qcom,model = "msm8998-qvr-tavil-snd-card"; + qcom,audio-routing = + "RX_BIAS", "MCLK", + "MADINPUT", "MCLK", + "AMIC2", "MIC BIAS2", + "MIC BIAS2", "Headset Mic", + "DMIC0", "MIC BIAS1", + "MIC BIAS1", "Digital Mic0", + "DMIC1", "MIC BIAS1", + "MIC BIAS1", "Digital Mic1", + "DMIC2", "MIC BIAS3", + "MIC BIAS3", "Digital Mic2", + "DMIC4", "MIC BIAS4", + "MIC BIAS4", "Digital Mic4", + "SpkrLeft IN", "SPK1 OUT"; + + qcom,msm-mbhc-hphl-swh = <1>; + /delete-property/ qcom,us-euro-gpios; + /delete-property/ qcom,hph-en0-gpio; + /delete-property/ qcom,hph-en0-gpio; + + qcom,wsa-max-devs = <1>; + qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>; + qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft"; + }; +}; + +/{ + qrd_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + + #include "batterydata-qrd-skuk-4v4-3000mah.dtsi" + }; +}; + +&pmi8998_fg { + qcom,battery-data = <&qrd_batterydata>; +}; + +&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/msmcobalt-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-qrd.dts index d95507b505c2..952b9a5cec6f 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt.dtsi" -#include "msmcobalt-qrd.dtsi" +#include "msm8998.dtsi" +#include "msm8998-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT QRD"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 QRD"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <11 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi index 6483453ec5fa..0a011b3656be 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi @@ -11,17 +11,17 @@ */ #include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-qrd.dtsi" +#include "msm8998-pinctrl.dtsi" +#include "msm8998-camera-sensor-qrd.dtsi" / { bluetooth: bt_wcn3990 { compatible = "qca,wcn3990"; - qca,bt-vdd-io-supply = <&pmcobalt_s3>; - qca,bt-vdd-xtal-supply = <&pmcobalt_s5>; - qca,bt-vdd-core-supply = <&pmcobalt_l7_pin_ctrl>; - qca,bt-vdd-pa-supply = <&pmcobalt_l17_pin_ctrl>; - qca,bt-vdd-ldo-supply = <&pmcobalt_l25_pin_ctrl>; - qca,bt-chip-pwd-supply = <&pmicobalt_bob_pin1>; + qca,bt-vdd-io-supply = <&pm8998_s3>; + qca,bt-vdd-xtal-supply = <&pm8998_s5>; + qca,bt-vdd-core-supply = <&pm8998_l7_pin_ctrl>; + qca,bt-vdd-pa-supply = <&pm8998_l17_pin_ctrl>; + qca,bt-vdd-ldo-supply = <&pm8998_l25_pin_ctrl>; + qca,bt-chip-pwd-supply = <&pmi8998_bob_pin1>; qca,bt-vdd-io-voltage-level = <1352000 1352000>; qca,bt-vdd-xtal-voltage-level = <2040000 2040000>; @@ -43,9 +43,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -56,9 +56,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -70,11 +70,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -97,7 +97,7 @@ pinctrl-0 = <&uart_console_active>; }; -&pmcobalt_gpios { +&pm8998_gpios { /* GPIO 6 for Vol+ Key */ gpio@c500 { status = "okay"; @@ -166,8 +166,8 @@ reg = <0x20>; interrupt-parent = <&tlmm>; interrupts = <125 0x2008>; - vdd-supply = <&pmcobalt_l6>; - avdd-supply = <&pmcobalt_l28>; + vdd-supply = <&pm8998_l6>; + avdd-supply = <&pm8998_l28>; synaptics,vdd-voltage = <1808000 1808000>; synaptics,avdd-voltage = <3008000 3008000>; synaptics,vdd-current = <40000>; @@ -192,7 +192,7 @@ qcom,nq-irq = <&tlmm 92 0x00>; qcom,nq-ven = <&tlmm 12 0x00>; qcom,nq-firm = <&tlmm 93 0x00>; - qcom,nq-clkreq = <&pmcobalt_gpios 21 0x00>; + qcom,nq-clkreq = <&pm8998_gpios 21 0x00>; qcom,nq-esepwr = <&tlmm 116 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK3"; @@ -263,7 +263,7 @@ qcom,qpnp-labibb-mode = "lcd"; }; -&pmicobalt_wled { +&pmi8998_wled { qcom,led-strings-list = [01 02]; }; @@ -381,11 +381,11 @@ }; }; -&pmicobalt_haptics { +&pmi8998_haptics { status = "okay"; }; -&pmcobalt_vadc { +&pm8998_vadc { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -442,7 +442,7 @@ }; }; -&pmcobalt_adc_tm { +&pm8998_adc_tm { chan@83 { label = "vph_pwr"; reg = <0x83>; @@ -503,7 +503,7 @@ vol_up { label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; + gpios = <&pm8998_gpios 6 0x1>; linux,input-type = <1>; linux,code = <115>; gpio-key,wakeup; @@ -512,7 +512,7 @@ cam_snapshot { label = "cam_snapshot"; - gpios = <&pmcobalt_gpios 7 0x1>; + gpios = <&pm8998_gpios 7 0x1>; linux,input-type = <1>; linux,code = <766>; gpio-key,wakeup; @@ -521,7 +521,7 @@ cam_focus { label = "cam_focus"; - gpios = <&pmcobalt_gpios 8 0x1>; + gpios = <&pm8998_gpios 8 0x1>; linux,input-type = <1>; linux,code = <528>; gpio-key,wakeup; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi b/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi index 32cf1663cf43..518ad33c63ea 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-regulator.dtsi @@ -10,16 +10,16 @@ * GNU General Public License for more details. */ -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include <dt-bindings/interrupt-controller/arm-gic.h> &rpm_bus { - /* PMCOBALT S1 + S6 = VDD_CX supply */ + /* PM8998 S1 + S6 = VDD_CX supply */ rpm-regulator-smpa1 { status = "okay"; - pmcobalt_s1_level: regulator-s1-level { + pm8998_s1_level: regulator-s1-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s1_level"; + regulator-name = "pm8998_s1_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -28,9 +28,9 @@ qcom,use-voltage-level; }; - pmcobalt_s1_floor_level: regulator-s1-floor-level { + pm8998_s1_floor_level: regulator-s1-floor-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s1_floor_level"; + regulator-name = "pm8998_s1_floor_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -40,9 +40,9 @@ qcom,always-send-voltage; }; - pmcobalt_s1_level_ao: regulator-s1-level-ao { + pm8998_s1_level_ao: regulator-s1-level-ao { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s1_level_ao"; + regulator-name = "pm8998_s1_level_ao"; qcom,set = <1>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -54,7 +54,7 @@ rpm-regulator-smpa2 { status = "okay"; - pmcobalt_s2: regulator-s2 { + pm8998_s2: regulator-s2 { regulator-min-microvolt = <1128000>; regulator-max-microvolt = <1128000>; status = "okay"; @@ -63,7 +63,7 @@ rpm-regulator-smpa3 { status = "okay"; - pmcobalt_s3: regulator-s3 { + pm8998_s3: regulator-s3 { regulator-min-microvolt = <1352000>; regulator-max-microvolt = <1352000>; status = "okay"; @@ -72,7 +72,7 @@ rpm-regulator-smpa4 { status = "okay"; - pmcobalt_s4: regulator-s4 { + pm8998_s4: regulator-s4 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; status = "okay"; @@ -81,7 +81,7 @@ rpm-regulator-smpa5 { status = "okay"; - pmcobalt_s5: regulator-s5 { + pm8998_s5: regulator-s5 { regulator-min-microvolt = <1904000>; regulator-max-microvolt = <2040000>; status = "okay"; @@ -90,7 +90,7 @@ rpm-regulator-smpa7 { status = "okay"; - pmcobalt_s7: regulator-s7 { + pm8998_s7: regulator-s7 { regulator-min-microvolt = <900000>; regulator-max-microvolt = <1028000>; status = "okay"; @@ -99,19 +99,19 @@ rpm-regulator-smpa8 { status = "okay"; - pmcobalt_s8: regulator-s8 { + pm8998_s8: regulator-s8 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; status = "okay"; }; }; - /* PMCOBALT S9 = VDD_MX supply */ + /* PM8998 S9 = VDD_MX supply */ rpm-regulator-smpa9 { status = "okay"; - pmcobalt_s9_level: regulator-s9-level { + pm8998_s9_level: regulator-s9-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s9_level"; + regulator-name = "pm8998_s9_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -120,9 +120,9 @@ qcom,use-voltage-level; }; - pmcobalt_s9_floor_level: regulator-s9-floor-level { + pm8998_s9_floor_level: regulator-s9-floor-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s9_floor_level"; + regulator-name = "pm8998_s9_floor_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -132,9 +132,9 @@ qcom,always-send-voltage; }; - pmcobalt_s9_level_ao: regulator-s9-level-ao { + pm8998_s9_level_ao: regulator-s9-level-ao { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_s9_level_ao"; + regulator-name = "pm8998_s9_level_ao"; qcom,set = <1>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -146,10 +146,10 @@ rpm-regulator-ldoa1 { status = "okay"; - pmcobalt_l1: regulator-l1 { + pm8998_l1: regulator-l1 { regulator-min-microvolt = <880000>; regulator-max-microvolt = <880000>; - proxy-supply = <&pmcobalt_l1>; + proxy-supply = <&pm8998_l1>; qcom,proxy-consumer-enable; qcom,proxy-consumer-current = <73400>; status = "okay"; @@ -158,10 +158,10 @@ rpm-regulator-ldoa2 { status = "okay"; - pmcobalt_l2: regulator-l2 { + pm8998_l2: regulator-l2 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; - proxy-supply = <&pmcobalt_l2>; + proxy-supply = <&pm8998_l2>; qcom,proxy-consumer-enable; qcom,proxy-consumer-current = <12560>; status = "okay"; @@ -170,19 +170,19 @@ rpm-regulator-ldoa3 { status = "okay"; - pmcobalt_l3: regulator-l3 { + pm8998_l3: regulator-l3 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; status = "okay"; }; }; - /* PMCOBALT L4 = VDD_SSC_MX supply */ + /* PM8998 L4 = VDD_SSC_MX supply */ rpm-regulator-ldoa4 { status = "okay"; - pmcobalt_l4_level: regulator-l4-level { + pm8998_l4_level: regulator-l4-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l4_level"; + regulator-name = "pm8998_l4_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -191,9 +191,9 @@ qcom,use-voltage-level; }; - pmcobalt_l4_floor_level: regulator-l4-floor-level { + pm8998_l4_floor_level: regulator-l4-floor-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l4_floor_level"; + regulator-name = "pm8998_l4_floor_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -206,7 +206,7 @@ rpm-regulator-ldoa5 { status = "okay"; - pmcobalt_l5: regulator-l5 { + pm8998_l5: regulator-l5 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <800000>; /* Force NPM follows HW0_EN */ @@ -217,7 +217,7 @@ rpm-regulator-ldoa6 { status = "okay"; - pmcobalt_l6: regulator-l6 { + pm8998_l6: regulator-l6 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <1808000>; status = "okay"; @@ -226,15 +226,15 @@ rpm-regulator-ldoa7 { status = "okay"; - pmcobalt_l7: regulator-l7 { + pm8998_l7: regulator-l7 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; status = "okay"; }; - pmcobalt_l7_pin_ctrl: regulator-l7-pin-ctrl { + pm8998_l7_pin_ctrl: regulator-l7-pin-ctrl { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l7_pin_ctrl"; + regulator-name = "pm8998_l7_pin_ctrl"; qcom,set = <3>; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -247,7 +247,7 @@ rpm-regulator-ldoa8 { status = "okay"; - pmcobalt_l8: regulator-l8 { + pm8998_l8: regulator-l8 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; status = "okay"; @@ -256,7 +256,7 @@ rpm-regulator-ldoa9 { status = "okay"; - pmcobalt_l9: regulator-l9 { + pm8998_l9: regulator-l9 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; status = "okay"; @@ -265,7 +265,7 @@ rpm-regulator-ldoa10 { status = "okay"; - pmcobalt_l10: regulator-l10 { + pm8998_l10: regulator-l10 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; status = "okay"; @@ -274,7 +274,7 @@ rpm-regulator-ldoa11 { status = "okay"; - pmcobalt_l11: regulator-l11 { + pm8998_l11: regulator-l11 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; status = "okay"; @@ -283,7 +283,7 @@ rpm-regulator-ldoa12 { status = "okay"; - pmcobalt_l12: regulator-l12 { + pm8998_l12: regulator-l12 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; status = "okay"; @@ -292,7 +292,7 @@ rpm-regulator-ldoa13 { status = "okay"; - pmcobalt_l13: regulator-l13 { + pm8998_l13: regulator-l13 { regulator-min-microvolt = <1808000>; regulator-max-microvolt = <2960000>; status = "okay"; @@ -301,10 +301,10 @@ rpm-regulator-ldoa14 { status = "okay"; - pmcobalt_l14: regulator-l14 { + pm8998_l14: regulator-l14 { regulator-min-microvolt = <1880000>; regulator-max-microvolt = <1880000>; - proxy-supply = <&pmcobalt_l14>; + proxy-supply = <&pm8998_l14>; qcom,proxy-consumer-enable; qcom,proxy-consumer-current = <32000>; status = "okay"; @@ -313,7 +313,7 @@ rpm-regulator-ldoa15 { status = "okay"; - pmcobalt_l15: regulator-l15 { + pm8998_l15: regulator-l15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; status = "okay"; @@ -322,7 +322,7 @@ rpm-regulator-ldoa16 { status = "okay"; - pmcobalt_l16: regulator-l16 { + pm8998_l16: regulator-l16 { regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; status = "okay"; @@ -331,15 +331,15 @@ rpm-regulator-ldoa17 { status = "okay"; - pmcobalt_l17: regulator-l17 { + pm8998_l17: regulator-l17 { regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; status = "okay"; }; - pmcobalt_l17_pin_ctrl: regulator-l17-pin-ctrl { + pm8998_l17_pin_ctrl: regulator-l17-pin-ctrl { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l17_pin_ctrl"; + regulator-name = "pm8998_l17_pin_ctrl"; qcom,set = <3>; regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; @@ -352,7 +352,7 @@ rpm-regulator-ldoa18 { status = "okay"; - pmcobalt_l18: regulator-l18 { + pm8998_l18: regulator-l18 { regulator-min-microvolt = <2704000>; regulator-max-microvolt = <2704000>; status = "okay"; @@ -361,7 +361,7 @@ rpm-regulator-ldoa19 { status = "okay"; - pmcobalt_l19: regulator-l19 { + pm8998_l19: regulator-l19 { regulator-min-microvolt = <3008000>; regulator-max-microvolt = <3008000>; status = "okay"; @@ -370,7 +370,7 @@ rpm-regulator-ldoa20 { status = "okay"; - pmcobalt_l20: regulator-l20 { + pm8998_l20: regulator-l20 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; status = "okay"; @@ -379,7 +379,7 @@ rpm-regulator-ldoa21 { status = "okay"; - pmcobalt_l21: regulator-l21 { + pm8998_l21: regulator-l21 { regulator-min-microvolt = <2960000>; regulator-max-microvolt = <2960000>; status = "okay"; @@ -388,7 +388,7 @@ rpm-regulator-ldoa22 { status = "okay"; - pmcobalt_l22: regulator-l22 { + pm8998_l22: regulator-l22 { regulator-min-microvolt = <2864000>; regulator-max-microvolt = <2864000>; status = "okay"; @@ -397,7 +397,7 @@ rpm-regulator-ldoa23 { status = "okay"; - pmcobalt_l23: regulator-l23 { + pm8998_l23: regulator-l23 { regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3312000>; status = "okay"; @@ -406,7 +406,7 @@ rpm-regulator-ldoa24 { status = "okay"; - pmcobalt_l24: regulator-l24 { + pm8998_l24: regulator-l24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>; status = "okay"; @@ -414,15 +414,15 @@ }; rpm-regulator-ldoa25 { status = "okay"; - pmcobalt_l25: regulator-l25 { + pm8998_l25: regulator-l25 { regulator-min-microvolt = <3104000>; regulator-max-microvolt = <3312000>; status = "okay"; }; - pmcobalt_l25_pin_ctrl: regulator-l25-pin-ctrl { + pm8998_l25_pin_ctrl: regulator-l25-pin-ctrl { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l25_pin_ctrl"; + regulator-name = "pm8998_l25_pin_ctrl"; qcom,set = <3>; regulator-min-microvolt = <3104000>; regulator-max-microvolt = <3312000>; @@ -435,19 +435,19 @@ rpm-regulator-ldoa26 { status = "okay"; - pmcobalt_l26: regulator-l26 { + pm8998_l26: regulator-l26 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; status = "okay"; }; }; - /* PMCOBALT L27 = VDD_SSC_CX supply */ + /* PM8998 L27 = VDD_SSC_CX supply */ rpm-regulator-ldoa27 { status = "okay"; - pmcobalt_l27_level: regulator-l27-level { + pm8998_l27_level: regulator-l27-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l27_level"; + regulator-name = "pm8998_l27_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -456,9 +456,9 @@ qcom,use-voltage-level; }; - pmcobalt_l27_floor_level: regulator-l27-floor-level { + pm8998_l27_floor_level: regulator-l27-floor-level { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmcobalt_l27_floor_level"; + regulator-name = "pm8998_l27_floor_level"; qcom,set = <3>; regulator-min-microvolt = <RPM_SMD_REGULATOR_LEVEL_RETENTION>; @@ -471,7 +471,7 @@ rpm-regulator-ldoa28 { status = "okay"; - pmcobalt_l28: regulator-l28 { + pm8998_l28: regulator-l28 { regulator-min-microvolt = <3008000>; regulator-max-microvolt = <3008000>; status = "okay"; @@ -480,44 +480,44 @@ rpm-regulator-vsa1 { status = "okay"; - pmcobalt_lvs1: regulator-lvs1 { + pm8998_lvs1: regulator-lvs1 { status = "okay"; }; }; rpm-regulator-vsa2 { status = "okay"; - pmcobalt_lvs2: regulator-lvs2 { + pm8998_lvs2: regulator-lvs2 { status = "okay"; }; }; rpm-regulator-bobb { status = "okay"; - pmicobalt_bob: regulator-bob { + pmi8998_bob: regulator-bob { regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3600000>; status = "okay"; }; - pmicobalt_bob_pin1: regulator-bob-pin1 { + pmi8998_bob_pin1: regulator-bob-pin1 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmicobalt_bob_pin1"; + regulator-name = "pm8998_bob_pin1"; qcom,set = <3>; regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3600000>; qcom,use-pin-ctrl-voltage1; }; - pmicobalt_bob_pin2: regulator-bob-pin2 { + pmi8998_bob_pin2: regulator-bob-pin2 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmicobalt_bob_pin2"; + regulator-name = "pm8998_bob_pin2"; qcom,set = <3>; regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3600000>; qcom,use-pin-ctrl-voltage2; }; - pmicobalt_bob_pin3: regulator-bob-pin3 { + pmi8998_bob_pin3: regulator-bob-pin3 { compatible = "qcom,rpm-smd-regulator"; - regulator-name = "pmicobalt_bob_pin3"; + regulator-name = "pm8998_bob_pin3"; qcom,set = <3>; regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3600000>; @@ -538,21 +538,21 @@ }; }; - qcom,pmcobalt@1 { - pmcobalt_s10: regulator@2f00 { + qcom,pm8998@1 { + pm8998_s10: regulator@2f00 { compatible = "qcom,qpnp-regulator"; reg = <0x2f00 0x100>; - regulator-name = "pmcobalt_s10"; + regulator-name = "pm8998_s10"; regulator-min-microvolt = <572000>; regulator-max-microvolt = <1112000>; qcom,enable-time = <500>; regulator-always-on; }; - pmcobalt_s13: regulator@3800 { + pm8998_s13: regulator@3800 { compatible = "qcom,qpnp-regulator"; reg = <0x3800 0x100>; - regulator-name = "pmcobalt_s13"; + regulator-name = "pm8998_s13"; regulator-min-microvolt = <572000>; regulator-max-microvolt = <1112000>; qcom,enable-time = <500>; @@ -577,7 +577,7 @@ &soc { /* CPR controller regulators */ apc0_cpr: cprh-ctrl@179c8000 { - compatible = "qcom,cprh-msmcobalt-v1-kbss-regulator"; + compatible = "qcom,cprh-msm8998-v1-kbss-regulator"; reg = <0x179c8000 0x4000>, <0x00784000 0x1000>; reg-names = "cpr_ctrl", "fuse_base"; clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>; @@ -614,7 +614,7 @@ "PWR_CPRH_STATUS", "APCLUS0_L2_SAW4_PMIC_STS"; qcom,cpr-aging-ref-voltage = <1112000>; - vdd-supply = <&pmcobalt_s10>; + vdd-supply = <&pm8998_s10>; thread@0 { qcom,cpr-thread-id = <0>; @@ -750,7 +750,7 @@ }; apc1_cpr: cprh-ctrl@179c4000{ - compatible = "qcom,cprh-msmcobalt-v1-kbss-regulator"; + compatible = "qcom,cprh-msm8998-v1-kbss-regulator"; reg = <0x179c4000 0x4000>, <0x00784000 0x1000>; reg-names = "cpr_ctrl", "fuse_base"; clocks = <&clock_gcc clk_gcc_hmss_rbcpr_clk>; @@ -787,7 +787,7 @@ "PERF_CPRH_STATUS", "APCLUS1_L2_SAW4_PMIC_STS"; qcom,cpr-aging-ref-voltage = <1112000>; - vdd-supply = <&pmcobalt_s13>; + vdd-supply = <&pm8998_s13>; thread@0 { qcom,cpr-thread-id = <0>; @@ -943,7 +943,7 @@ }; gfx_cpr: cpr4-ctrl@5061000 { - compatible = "qcom,cpr4-msmcobalt-v1-mmss-regulator"; + compatible = "qcom,cpr4-msm8998-v1-mmss-regulator"; reg = <0x05061000 0x4000>, <0x00784000 0x1000>, <0x05065204 0x4>; @@ -1121,7 +1121,7 @@ }; }; -&pmicobalt_charger { +&pmi8998_charger { smb2_vbus: qcom,smb2-vbus { regulator-name = "smb2-vbus"; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-rumi.dts b/arch/arm/boot/dts/qcom/msm8998-rumi.dts index 81927abd6886..eaeb711efba6 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-rumi.dts +++ b/arch/arm/boot/dts/qcom/msm8998-rumi.dts @@ -14,12 +14,12 @@ /dts-v1/; /memreserve/ 0x90000000 0x00000100; -#include "msmcobalt.dtsi" -#include "msmcobalt-rumi.dtsi" +#include "msm8998.dtsi" +#include "msm8998-rumi.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT RUMI"; - compatible = "qcom,msmcobalt-rumi", "qcom,msmcobalt", "qcom,rumi"; + model = "Qualcomm Technologies, Inc. MSM 8998 RUMI"; + compatible = "qcom,msm8998-rumi", "qcom,msm8998", "qcom,rumi"; qcom,board-id = <15 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-rumi.dtsi b/arch/arm/boot/dts/qcom/msm8998-rumi.dtsi index 105a83b56056..d5fd190c938d 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-rumi.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-rumi.dtsi @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#include "msmcobalt-pinctrl.dtsi" +#include "msm8998-pinctrl.dtsi" &uartblsp2dm1 { status = "ok"; }; @@ -20,9 +20,9 @@ reg = <0x1da7000 0xda8>, /* PHY regs */ <0x1db8000 0x100>; /* U11 user regs */ reg-names = "phy_mem", "u11_user"; - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -77,9 +77,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -95,11 +95,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -267,14 +267,14 @@ }; &spmi_bus { - qcom,pmicobalt@3 { + qcom,pmi8998@3 { flash_led: qcom,leds@d300 { status = "disabled"; }; }; }; -&pmicobalt_charger { +&pmi8998_charger { qcom,suspend-input; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-sim.dts b/arch/arm/boot/dts/qcom/msm8998-sim.dts index 69c047994c98..c92050ab20d6 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-sim.dts +++ b/arch/arm/boot/dts/qcom/msm8998-sim.dts @@ -14,12 +14,12 @@ /dts-v1/; /memreserve/ 0x90000000 0x00000100; -#include "msmcobalt.dtsi" -#include "msmcobalt-sim.dtsi" +#include "msm8998.dtsi" +#include "msm8998-sim.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT SIM"; - compatible = "qcom,msmcobalt-sim", "qcom,msmcobalt", "qcom,sim"; + model = "Qualcomm Technologies, Inc. MSM 8998 SIM"; + compatible = "qcom,msm8998-sim", "qcom,msm8998", "qcom,sim"; qcom,board-id = <16 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-sim.dtsi b/arch/arm/boot/dts/qcom/msm8998-sim.dtsi index 4e6b1dd9211a..8a0f4b30121c 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-sim.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-sim.dtsi @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#include "msmcobalt-pinctrl.dtsi" +#include "msm8998-pinctrl.dtsi" &uartblsp2dm1 { status = "ok"; @@ -19,9 +19,9 @@ }; &ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; + vdda-phy-supply = <&pm8998_l1>; + vdda-pll-supply = <&pm8998_l2>; + vddp-ref-clk-supply = <&pm8998_l26>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -32,9 +32,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; + vcc-supply = <&pm8998_l20>; + vccq-supply = <&pm8998_l26>; + vccq2-supply = <&pm8998_s4>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; @@ -50,11 +50,11 @@ }; &sdhc_2 { - vdd-supply = <&pmcobalt_l21>; + vdd-supply = <&pm8998_l21>; qcom,vdd-voltage-level = <2950000 2960000>; qcom,vdd-current-level = <200 800000>; - vdd-io-supply = <&pmcobalt_l13>; + vdd-io-supply = <&pm8998_l13>; qcom,vdd-io-voltage-level = <1808000 2960000>; qcom,vdd-io-current-level = <200 22000>; @@ -85,8 +85,8 @@ &soc { sound_sim { - compatible = "qcom,msmcobalt-asoc-snd-stub"; - qcom,model = "msmcobalt-stub-snd-card"; + compatible = "qcom,msm8998-asoc-snd-stub"; + qcom,model = "msm8998-stub-snd-card"; qcom,audio-routing = "AIF4 VI", "MCLK", @@ -111,7 +111,7 @@ interrupt-names = "cdc-int"; }; -&pmicobalt_charger { +&pmi8998_charger { qcom,suspend-input; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-smp2p.dtsi b/arch/arm/boot/dts/qcom/msm8998-smp2p.dtsi index 2926a6889395..2926a6889395 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-smp2p.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-smp2p.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi index fcc4d6d8ee2d..a81287c36266 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi @@ -116,5 +116,76 @@ 0 256000000 0>; status = "ok"; }; + + qcom,cpp@ca04000 { + cell-index = <0>; + compatible = "qcom,cpp"; + reg = <0xca04000 0x100>, + <0xca80000 0x3000>, + <0xca18000 0x3000>, + <0xc8c36d4 0x4>; + reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp"; + interrupts = <0 294 0>; + interrupt-names = "cpp"; + smmu-vdd-supply = <&gdsc_bimc_smmu>; + camss-vdd-supply = <&gdsc_camss_top>; + vdd-supply = <&gdsc_cpp>; + qcom,vdd-names = "smmu-vdd", "camss-vdd", "vdd"; + clocks = <&clock_gcc clk_mmssnoc_axi_clk>, + <&clock_mmss clk_mmss_mnoc_ahb_clk>, + <&clock_mmss clk_mmss_camss_ahb_clk>, + <&clock_mmss clk_mmss_camss_top_ahb_clk>, + <&clock_mmss clk_cpp_clk_src>, + <&clock_mmss clk_mmss_camss_cpp_clk>, + <&clock_mmss clk_mmss_camss_cpp_ahb_clk>, + <&clock_mmss clk_mmss_camss_cpp_axi_clk>, + <&clock_mmss clk_mmss_camss_micro_ahb_clk>, + <&clock_mmss clk_mmss_bimc_smmu_axi_clk>, + <&clock_mmss clk_mmss_camss_cpp_vbif_ahb_clk>; + clock-names = "mmssnoc_axi_clk", + "mnoc_ahb_clk", + "camss_ahb_clk", "camss_top_ahb_clk", + "cpp_src_clk", + "cpp_core_clk", "camss_cpp_ahb_clk", + "camss_cpp_axi_clk", "micro_iface_clk", + "mmss_smmu_axi_clk", "cpp_vbif_ahb_clk"; + qcom,clock-rates = <0 0 0 0 200000000 200000000 0 0 0 0 0>; + qcom,min-clock-rate = <200000000>; + qcom,bus-master = <1>; + qcom,vbif-qos-setting = <0x20 0x10000000>, + <0x24 0x10000000>, + <0x28 0x10000000>, + <0x2C 0x10000000>; + status = "ok"; + qcom,msm-bus,name = "msm_camera_cpp"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <106 512 0 0>, + <106 512 0 0>; + qcom,msm-bus-vector-dyn-vote; + resets = <&clock_mmss CAMSS_MICRO_BCR>; + reset-names = "micro_iface_reset"; + qcom,src-clock-rates = <100000000 200000000 384000000 404000000 + 480000000 576000000 600000000>; + qcom,cpp-fw-payload-info { + qcom,stripe-base = <790>; + qcom,plane-base = <715>; + qcom,stripe-size = <63>; + qcom,plane-size = <25>; + qcom,fe-ptr-off = <11>; + qcom,we-ptr-off = <23>; + qcom,ref-fe-ptr-off = <17>; + qcom,ref-we-ptr-off = <36>; + qcom,we-meta-ptr-off = <42>; + qcom,fe-mmu-pf-ptr-off = <7>; + qcom,ref-fe-mmu-pf-ptr-off = <10>; + qcom,we-mmu-pf-ptr-off = <13>; + qcom,dup-we-mmu-pf-ptr-off = <18>; + qcom,ref-we-mmu-pf-ptr-off = <23>; + qcom,set-group-buffer-len = <135>; + qcom,dup-frame-indicator-off = <70>; + }; + }; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts index 7cb8f107abc4..0f5ad5366c84 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-cdp.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2 CDP"; - compatible = "qcom,msmcobalt-cdp", "qcom,msmcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2 CDP"; + compatible = "qcom,msm8998-cdp", "qcom,msm8998", "qcom,cdp"; qcom,board-id = <1 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi index 46ed1f219970..dc548f8f499b 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2-interposer-msmfalcon.dtsi @@ -13,19 +13,38 @@ /* * As a general rule, only version-specific property overrides should be placed * inside this file. Common device definitions should be placed inside the - * msmcobalt.dtsi file. + * msm8998.dtsi file. */ -#include "msmcobalt-interposer-msmfalcon.dtsi" -#include "msmcobalt-v2-camera.dtsi" +#include "msm8998-interposer-msmfalcon.dtsi" +#include "msm8998-v2-camera.dtsi" / { - model = "Qualcomm Technologies, Inc. MSMCOBALT v2"; + model = "Qualcomm Technologies, Inc. MSM8998 v2"; qcom,msm-id = <292 0x20000>; }; &clock_cpu { - compatible = "qcom,cpu-clock-osm-msmcobalt-v2"; + 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 >, @@ -187,19 +206,19 @@ }; &clock_gcc { - compatible = "qcom,gcc-cobalt-v2"; + compatible = "qcom,gcc-8998-v2"; }; &clock_mmss { - compatible = "qcom,mmsscc-cobalt-v2"; + compatible = "qcom,mmsscc-8998-v2"; }; &clock_gpu { - compatible = "qcom,gpucc-cobalt-v2"; + compatible = "qcom,gpucc-8998-v2"; }; &clock_gfx { - compatible = "qcom,gfxcc-cobalt-v2"; + compatible = "qcom,gfxcc-8998-v2"; qcom,gfxfreq-speedbin0 = < 0 0 0 >, < 180000000 1 RPM_SMD_REGULATOR_LEVEL_SVS >, @@ -227,18 +246,18 @@ qcom,max-bandwidth-per-pipe-kbps = <4700000>; }; -&pmcobalt_s10 { +&pm8998_s10 { regulator-min-microvolt = <568000>; regulator-max-microvolt = <1056000>; }; -&pmcobalt_s13 { +&pm8998_s13 { regulator-min-microvolt = <568000>; regulator-max-microvolt = <1056000>; }; &apc0_cpr { - compatible = "qcom,cprh-msmcobalt-v2-kbss-regulator"; + compatible = "qcom,cprh-msm8998-v2-kbss-regulator"; qcom,cpr-corner-switch-delay-time = <1042>; qcom,cpr-aging-ref-voltage = <1056000>; }; @@ -389,7 +408,7 @@ }; &apc1_cpr { - compatible = "qcom,cprh-msmcobalt-v2-kbss-regulator"; + compatible = "qcom,cprh-msm8998-v2-kbss-regulator"; qcom,cpr-corner-switch-delay-time = <1042>; qcom,cpr-aging-ref-voltage = <1056000>; }; @@ -555,7 +574,7 @@ }; &gfx_cpr { - compatible = "qcom,cpr4-msmcobalt-v2-mmss-regulator"; + compatible = "qcom,cpr4-msm8998-v2-mmss-regulator"; qcom,cpr-aging-ref-voltage = <1024000>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts index 96e671f04df3..0708573934f3 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-mtp.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2 MTP"; - compatible = "qcom,msmcobalt-mtp", "qcom,msmcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2 MTP"; + compatible = "qcom,msm8998-mtp", "qcom,msm8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts index 581e9fef1aeb..471602ac80b9 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-qrd-skuk.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-skuk.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT V2 SKUK"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <0x01000b 0x10>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-vr1.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts index 15dd2d550b31..58c7dc3bac11 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-qrd-vr1.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-vr1.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-qrd-vr1.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-vr1.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT V2 VR1 Board"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 V2 VR1 Board"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <0x02000b 0x80>; }; diff --git a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts index 8da6f90958d2..37ad18278e5c 100644 --- a/arch/arm/boot/dts/qcom/apqcobalt-v2.1-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd.dts @@ -12,11 +12,11 @@ /dts-v1/; -#include "apqcobalt-v2.1.dtsi" -#include "msmcobalt-qrd.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ COBALT V2.1 QRD"; - compatible = "qcom,apqcobalt-qrd", "qcom,apqcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2 QRD"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <11 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-rumi.dts b/arch/arm/boot/dts/qcom/msm8998-v2-rumi.dts index cabfb135ca81..e6cf24e593ce 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-rumi.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-rumi.dts @@ -14,12 +14,12 @@ /dts-v1/; /memreserve/ 0x90000000 0x00000100; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-rumi.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-rumi.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT V2 RUMI"; - compatible = "qcom,msmcobalt-rumi", "qcom,msmcobalt", "qcom,rumi"; + model = "Qualcomm Technologies, Inc. MSM 8998 V2 RUMI"; + compatible = "qcom,msm8998-rumi", "qcom,msm8998", "qcom,rumi"; qcom,board-id = <15 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2-sim.dts b/arch/arm/boot/dts/qcom/msm8998-v2-sim.dts index 2789b27c9381..91c583df7ff3 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2-sim.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-sim.dts @@ -14,12 +14,12 @@ /dts-v1/; /memreserve/ 0x90000000 0x00000100; -#include "msmcobalt-v2.dtsi" -#include "msmcobalt-sim.dtsi" +#include "msm8998-v2.dtsi" +#include "msm8998-sim.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT V2 SIM"; - compatible = "qcom,msmcobalt-sim", "qcom,msmcobalt", "qcom,sim"; + model = "Qualcomm Technologies, Inc. MSM 8998 V2 SIM"; + compatible = "qcom,msm8998-sim", "qcom,msm8998", "qcom,sim"; qcom,board-id = <16 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts index d5afb1d3c151..871d13bdaa1a 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-cdp.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.1.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "msm8998-v2.1.dtsi" +#include "msm8998-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2.1 CDP"; - compatible = "qcom,msmcobalt-cdp", "qcom,msmcobalt", "qcom,cdp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 CDP"; + compatible = "qcom,msm8998-cdp", "qcom,msm8998", "qcom,cdp"; qcom,board-id = <1 0>; }; 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 new file mode 100644 index 000000000000..528e48df1268 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts @@ -0,0 +1,87 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8998-v2.1-interposer-msmfalcon.dtsi" +#include "msm8998-interposer-msmfalcon-cdp.dtsi" +#include "msm8998-interposer-pmfalcon.dtsi" +#include "msm8998-interposer-msmfalcon-audio.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 MSM FALCON Interposer CDP"; + compatible = "qcom,msm8998-cdp", "qcom,msm8998", "qcom,cdp"; + qcom,board-id = <1 1>; +}; + +&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 new file mode 100644 index 000000000000..0f0a88b33402 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts @@ -0,0 +1,87 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8998-v2.1-interposer-msmfalcon.dtsi" +#include "msm8998-interposer-msmfalcon-mtp.dtsi" +#include "msm8998-interposer-pmfalcon.dtsi" +#include "msm8998-interposer-msmfalcon-audio.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 MSM FALCON Interposer MTP"; + compatible = "qcom,msm8998-mtp", "qcom,msm8998", "qcom,mtp"; + qcom,board-id = <8 2>; +}; + +&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/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts index e5ad123f52a7..ddae02812731 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts @@ -13,12 +13,12 @@ /dts-v1/; -#include "msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi" +#include "msm8998-v2.1-interposer-msmfalcon-qrd.dtsi" / { model = - "Qualcomm Technologies, Inc. MSM COBALT v2.1 MSM FALCON Interposer QRD"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + "Qualcomm Technologies, Inc. MSM 8998 v2.1 MSM FALCON Interposer QRD"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <0x03000b 0x80>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi index b257281466a9..cd0e20a295d9 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi @@ -11,7 +11,7 @@ */ #include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-v2.1-interposer-msmfalcon.dtsi" +#include "msm8998-v2.1-interposer-msmfalcon.dtsi" &uartblsp2dm1 { status = "ok"; @@ -20,6 +20,9 @@ }; &ufsphy1 { + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l10>; + vddp-ref-clk-supply = <&pmfalcon_l8>; vdda-phy-max-microamp = <51400>; vdda-pll-max-microamp = <14600>; vddp-ref-clk-max-microamp = <100>; @@ -30,6 +33,9 @@ &ufs1 { vdd-hba-supply = <&gdsc_ufs>; vdd-hba-fixed-regulator; + vcc-supply = <&pm2falcon_l4>; + vccq-supply = <&pmfalcon_l8>; + vccq2-supply = <&pmfalcon_l8>; vcc-max-microamp = <750000>; vccq-max-microamp = <560000>; vccq2-max-microamp = <750000>; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon.dtsi index 96ff7f70788f..c2a393bd019d 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon.dtsi @@ -10,9 +10,9 @@ * GNU General Public License for more details. */ -#include "msmcobalt-v2-interposer-msmfalcon.dtsi" +#include "msm8998-v2-interposer-msmfalcon.dtsi" / { - model = "Qualcomm Technologies, Inc. MSMCOBALT v2.1"; + model = "Qualcomm Technologies, Inc. MSM8998 v2.1"; qcom,msm-id = <292 0x20001>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts index f49b43420a06..9d7cbc93d9df 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-mtp.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.1.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "msm8998-v2.1.dtsi" +#include "msm8998-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2.1 MTP"; - compatible = "qcom,msmcobalt-mtp", "qcom,msmcobalt", "qcom,mtp"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 MTP"; + compatible = "qcom,msm8998-mtp", "qcom,msm8998", "qcom,mtp"; qcom,board-id = <8 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts index 7a3b6f50932b..b20c888ad933 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-qrd.dts @@ -13,11 +13,11 @@ /dts-v1/; -#include "msmcobalt-v2.1.dtsi" -#include "msmcobalt-qrd.dtsi" +#include "msm8998-v2.1.dtsi" +#include "msm8998-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM COBALT v2.1 QRD"; - compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd"; + model = "Qualcomm Technologies, Inc. MSM 8998 v2.1 QRD"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; qcom,board-id = <11 0>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1.dtsi index 3f5c42ae8cc8..563157df40a8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1.dtsi @@ -10,9 +10,9 @@ * GNU General Public License for more details. */ -#include "msmcobalt-v2.dtsi" +#include "msm8998-v2.dtsi" / { - model = "Qualcomm Technologies, Inc. MSMCOBALT v2.1"; + model = "Qualcomm Technologies, Inc. MSM8998 v2.1"; qcom,msm-id = <292 0x20001>; }; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi index 93b586df5640..cc4e48ede2ad 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi @@ -13,19 +13,19 @@ /* * As a general rule, only version-specific property overrides should be placed * inside this file. Common device definitions should be placed inside the - * msmcobalt.dtsi file. + * msm8998.dtsi file. */ -#include "msmcobalt.dtsi" -#include "msmcobalt-v2-camera.dtsi" +#include "msm8998.dtsi" +#include "msm8998-v2-camera.dtsi" / { - model = "Qualcomm Technologies, Inc. MSMCOBALT v2"; + model = "Qualcomm Technologies, Inc. MSM8998 v2"; qcom,msm-id = <292 0x20000>; }; &clock_cpu { - compatible = "qcom,cpu-clock-osm-msmcobalt-v2"; + compatible = "qcom,cpu-clock-osm-msm8998-v2"; reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, <0x17816000 0x1000>, @@ -42,8 +42,10 @@ qcom,acdcr-val = <0x002b5ffd 0x002b5ffd>; qcom,acdsscr-val = <0x00000501 0x00000501>; qcom,acdextint0-val = <0x2cf9ae8 0x2cf9ae8>; - qcom,acdextint1-val = <0x2cf9afc 0x2cf9afc>; + 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 = @@ -96,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 >, @@ -129,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 { @@ -183,11 +268,17 @@ < 1958400 >, < 2035200 >, < 2112000 >, - < 2188800 >, + < 2208000 >, < 2265600 >, + < 2304000 >, + < 2323200 >, < 2342400 >, + < 2361600 >, < 2419200 >, - < 2496000 >; + < 2457600 >, + < 2476800 >, + < 2496000 >, + < 2592000 >; }; &bwmon { @@ -224,19 +315,19 @@ < 2208000 13763 >; }; &clock_gcc { - compatible = "qcom,gcc-cobalt-v2"; + compatible = "qcom,gcc-8998-v2"; }; &clock_mmss { - compatible = "qcom,mmsscc-cobalt-v2"; + compatible = "qcom,mmsscc-8998-v2"; }; &clock_gpu { - compatible = "qcom,gpucc-cobalt-v2"; + compatible = "qcom,gpucc-8998-v2"; }; &clock_gfx { - compatible = "qcom,gfxcc-cobalt-v2"; + compatible = "qcom,gfxcc-8998-v2"; qcom,gfxfreq-speedbin0 = < 0 0 0 >, < 180000000 1 RPM_SMD_REGULATOR_LEVEL_SVS >, @@ -266,12 +357,12 @@ qcom,max-bandwidth-per-pipe-kbps = <4700000>; }; -&pmcobalt_s10 { +&pm8998_s10 { regulator-min-microvolt = <568000>; regulator-max-microvolt = <1056000>; }; -&pmcobalt_s13 { +&pm8998_s13 { regulator-min-microvolt = <568000>; regulator-max-microvolt = <1056000>; }; @@ -355,37 +446,24 @@ }; &apc0_cpr { - compatible = "qcom,cprh-msmcobalt-v2-kbss-regulator"; + 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 @@ -393,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 @@ -407,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 @@ -458,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-msmcobalt-v2-kbss-regulator"; + 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 */ @@ -537,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 */ @@ -554,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 */ @@ -592,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 @@ -603,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 @@ -621,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>; }; @@ -676,7 +891,7 @@ }; &gfx_cpr { - compatible = "qcom,cpr4-msmcobalt-v2-mmss-regulator"; + compatible = "qcom,cpr4-msm8998-v2-mmss-regulator"; qcom,cpr-aging-ref-voltage = <1024000>; }; @@ -858,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/msmcobalt-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi index a8655c2e88a0..b8a0b8f3acf2 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi @@ -12,7 +12,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/msm/msm-bus-ids.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> &soc { msm_vidc: qcom,vidc@cc00000 { diff --git a/arch/arm/boot/dts/qcom/msmcobalt-wcd.dtsi b/arch/arm/boot/dts/qcom/msm8998-wcd.dtsi index 29f4ccaede9f..29f4ccaede9f 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-wcd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-wcd.dtsi diff --git a/arch/arm/boot/dts/qcom/msmcobalt-wsa881x.dtsi b/arch/arm/boot/dts/qcom/msm8998-wsa881x.dtsi index baf05c1c241b..746cf23b4c97 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-wsa881x.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-wsa881x.dtsi @@ -9,7 +9,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include "msmcobalt-wcd.dtsi" +#include "msm8998-wcd.dtsi" &slim_aud { tasha_codec { diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 9b0d3f674032..e95bc8597043 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -11,13 +11,13 @@ */ #include "skeleton64.dtsi" -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include <dt-bindings/regulator/qcom,rpm-smd-regulator.h> #include <dt-bindings/interrupt-controller/arm-gic.h> / { - model = "Qualcomm Technologies, Inc. MSM COBALT"; - compatible = "qcom,msmcobalt"; + model = "Qualcomm Technologies, Inc. MSM 8998"; + compatible = "qcom,msm8998"; qcom,msm-id = <292 0x0>; interrupt-parent = <&intc>; @@ -341,8 +341,8 @@ }; }; -#include "msmcobalt-smp2p.dtsi" -#include "msm-gdsc-cobalt.dtsi" +#include "msm8998-smp2p.dtsi" +#include "msm-gdsc-8998.dtsi" &soc { #address-cells = <1>; @@ -731,21 +731,21 @@ }; clock_gcc: qcom,gcc@100000 { - compatible = "qcom,gcc-cobalt"; + compatible = "qcom,gcc-8998"; reg = <0x100000 0xb0000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; - vdd_dig_ao-supply = <&pmcobalt_s1_level_ao>; + vdd_dig-supply = <&pm8998_s1_level>; + vdd_dig_ao-supply = <&pm8998_s1_level_ao>; #clock-cells = <1>; #reset-cells = <1>; }; clock_mmss: qcom,mmsscc@c8c0000 { - compatible = "qcom,mmsscc-cobalt"; + compatible = "qcom,mmsscc-8998"; reg = <0xc8c0000 0x40000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; - vdd_mmsscc_mx-supply = <&pmcobalt_s9_level>; + vdd_dig-supply = <&pm8998_s1_level>; + vdd_mmsscc_mx-supply = <&pm8998_s9_level>; clock-names = "xo", "gpll0", "gpll0_div", "pclk0_src", "pclk1_src", "byte0_src", "byte1_src", @@ -766,10 +766,10 @@ }; clock_gpu: qcom,gpucc@5065000 { - compatible = "qcom,gpucc-cobalt"; + compatible = "qcom,gpucc-8998"; reg = <0x5065000 0x9000>; reg-names = "cc_base"; - vdd_dig-supply = <&pmcobalt_s1_level>; + vdd_dig-supply = <&pm8998_s1_level>; clock-names = "xo_ao", "gpll0"; clocks = <&clock_gcc clk_cxo_clk_src_ao>, <&clock_gcc clk_gcc_gpu_gpll0_clk>; @@ -777,12 +777,12 @@ }; clock_gfx: qcom,gfxcc@5065000 { - compatible = "qcom,gfxcc-cobalt"; + compatible = "qcom,gfxcc-8998"; reg = <0x5065000 0x9000>; reg-names = "cc_base"; vdd_gpucc-supply = <&gfx_vreg>; - vdd_mx-supply = <&pmcobalt_s9_level>; - vdd_gpu_mx-supply = <&pmcobalt_s9_level>; + vdd_mx-supply = <&pm8998_s9_level>; + vdd_gpu_mx-supply = <&pm8998_s9_level>; qcom,gfx3d_clk_src-opp-handle = <&msm_gpu>; qcom,gfxfreq-speedbin0 = < 0 0 0 >, @@ -803,8 +803,8 @@ #clock-cells = <1>; }; - clock_cpu: qcom,cpu-clock-cobalt@179c0000 { - compatible = "qcom,cpu-clock-osm-msmcobalt-v1"; + clock_cpu: qcom,cpu-clock-8998@179c0000 { + compatible = "qcom,cpu-clock-osm-msm8998-v1"; reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, <0x17816000 0x1000>, @@ -941,7 +941,7 @@ }; clock_debug: qcom,debugcc@162000 { - compatible = "qcom,cc-debug-cobalt"; + compatible = "qcom,cc-debug-8998"; reg = <0x162000 0x4>; reg-names = "cc_base"; clock-names = "debug_gpu_clk", "debug_gfx_clk", @@ -1441,184 +1441,6 @@ }; }; - pcie0: qcom,pcie@01c00000 { - compatible = "qcom,pci-msm"; - cell-index = <0>; - - reg = <0x1c00000 0x2000>, - <0x1c06000 0x1000>, - <0x1b000000 0xf1d>, - <0x1b000f20 0xa8>, - <0x1b100000 0x100000>, - <0x1b200000 0x100000>, - <0x1b300000 0xd00000>; - - reg-names = "parf", "phy", "dm_core", "elbi", - "conf", "io", "bars"; - - #address-cells = <3>; - #size-cells = <2>; - ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>, - <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>; - interrupt-parent = <&pcie0>; - interrupts = <0 1 2 3 4 5>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0xffffffff>; - interrupt-map = <0 0 0 0 &intc 0 0 405 0 - 0 0 0 1 &intc 0 0 135 0 - 0 0 0 2 &intc 0 0 136 0 - 0 0 0 3 &intc 0 0 138 0 - 0 0 0 4 &intc 0 0 139 0 - 0 0 0 5 &intc 0 0 278 0>; - - interrupt-names = "int_msi", "int_a", "int_b", "int_c", - "int_d", "int_global_int"; - - qcom,phy-sequence = <0x804 0x01 0x00 - 0x034 0x14 0x00 - 0x138 0x30 0x00 - 0x048 0x0f 0x00 - 0x15c 0x06 0x00 - 0x090 0x01 0x00 - 0x088 0x20 0x00 - 0x0f0 0x00 0x00 - 0x0f8 0x01 0x00 - 0x0f4 0xc9 0x00 - 0x11c 0xff 0x00 - 0x120 0x3f 0x00 - 0x164 0x01 0x00 - 0x154 0x00 0x00 - 0x148 0x0a 0x00 - 0x05C 0x19 0x00 - 0x038 0x90 0x00 - 0x0b0 0x82 0x00 - 0x0c0 0x03 0x00 - 0x0bc 0x55 0x00 - 0x0b8 0x55 0x00 - 0x0a0 0x00 0x00 - 0x09c 0x0d 0x00 - 0x098 0x04 0x00 - 0x13c 0x00 0x00 - 0x060 0x08 0x00 - 0x068 0x16 0x00 - 0x070 0x34 0x00 - 0x15c 0x06 0x00 - 0x138 0x33 0x00 - 0x03c 0x02 0x00 - 0x040 0x0e 0x00 - 0x080 0x04 0x00 - 0x0dc 0x00 0x00 - 0x0d8 0x3f 0x00 - 0x00c 0x09 0x00 - 0x010 0x01 0x00 - 0x01c 0x40 0x00 - 0x020 0x01 0x00 - 0x014 0x02 0x00 - 0x018 0x00 0x00 - 0x024 0x7e 0x00 - 0x028 0x15 0x00 - 0x244 0x02 0x00 - 0x2a4 0x12 0x00 - 0x260 0x10 0x00 - 0x28c 0x06 0x00 - 0x504 0x03 0x00 - 0x500 0x1c 0x00 - 0x50c 0x14 0x00 - 0x4d4 0x0a 0x00 - 0x4d8 0x04 0x00 - 0x4dc 0x1a 0x00 - 0x434 0x4b 0x00 - 0x414 0x04 0x00 - 0x40c 0x04 0x00 - 0x4f8 0x00 0x00 - 0x4fc 0x80 0x00 - 0x51c 0x40 0x00 - 0x444 0x71 0x00 - 0x43c 0x40 0x00 - 0x854 0x04 0x00 - 0x62c 0x52 0x00 - 0x9ac 0x00 0x00 - 0x8a0 0x01 0x00 - 0x9e0 0x00 0x00 - 0x9dc 0x01 0x00 - 0x9a8 0x00 0x00 - 0x8a4 0x01 0x00 - 0x8a8 0x73 0x00 - 0x9d8 0x99 0x00 - 0x9b0 0x03 0x00 - 0x804 0x03 0x00 - 0x800 0x00 0x00 - 0x808 0x03 0x00>; - - pinctrl-names = "default"; - pinctrl-0 = <&pcie0_clkreq_default - &pcie0_perst_default - &pcie0_wake_default>; - - perst-gpio = <&tlmm 35 0>; - wake-gpio = <&tlmm 37 0>; - - gdsc-vdd-supply = <&gdsc_pcie_0>; - vreg-1.8-supply = <&pmcobalt_l2>; - vreg-0.9-supply = <&pmcobalt_l1>; - vreg-cx-supply = <&pmcobalt_s1_level>; - - qcom,vreg-1.8-voltage-level = <1200000 1200000 24000>; - qcom,vreg-0.9-voltage-level = <880000 880000 24000>; - qcom,vreg-cx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_BINNING - RPM_SMD_REGULATOR_LEVEL_SVS 0>; - - qcom,l1-supported; - qcom,l1ss-supported; - qcom,aux-clk-sync; - - qcom,ep-latency = <10>; - - qcom,ep-wakeirq; - - linux,pci-domain = <0>; - - qcom,pcie-phy-ver = <0x20>; - qcom,use-19p2mhz-aux-clk; - - iommus = <&anoc1_smmu>; - qcom,smmu-exist; - qcom,smmu-sid-base = <0x1480>; - - qcom,msm-bus,name = "pcie0"; - qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <1>; - qcom,msm-bus,vectors-KBps = - <45 512 0 0>, - <45 512 500 800>; - - clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, - <&clock_gcc clk_ln_bb_clk1>, - <&clock_gcc clk_gcc_pcie_0_aux_clk>, - <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, - <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, - <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, - <&clock_gcc clk_gcc_pcie_clkref_clk>; - - clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", - "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk", - "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk", - "pcie_0_ldo"; - - max-clock-frequency-hz = <0>, <0>, <19200000>, - <0>, <0>, <0>, <0>, <0>, <0>, - <0>, <0>, <0>, <0>, <0>, <0>, - <0>, <0>; - - resets = <&clock_gcc PCIE_PHY_BCR>, - <&clock_gcc PCIE_0_PHY_BCR>, - <&clock_gcc PCIE_0_PHY_BCR>; - - reset-names = "pcie_phy_reset", - "pcie_0_phy_reset", - "pcie_0_phy_pipe_reset"; - }; - qcom,ipc_router { compatible = "qcom,ipc_router"; qcom,node-id = <1>; @@ -1838,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"; @@ -1866,7 +1692,7 @@ <61 512 240000 800000>; qcom,dwc-usb3-msm-tx-fifo-size = <21288>; - extcon = <&pmicobalt_pdphy>; + extcon = <&pmi8998_pdphy>; clocks = <&clock_gcc clk_gcc_usb30_master_clk>, <&clock_gcc clk_gcc_cfg_noc_usb3_axi_clk>, @@ -1935,9 +1761,9 @@ <0x01fcb24c 0x4>; reg-names = "qusb_phy_base", "tcsr_clamp_dig_n_1p8"; - vdd-supply = <&pmcobalt_l1>; - vdda18-supply = <&pmcobalt_l12>; - vdda33-supply = <&pmcobalt_l24>; + vdd-supply = <&pm8998_l1>; + vdda18-supply = <&pm8998_l12>; + vdda33-supply = <&pm8998_l24>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,qusb-phy-init-seq = /* <value reg_offset> */ @@ -1965,8 +1791,8 @@ reg-names = "qmp_phy_base", "vls_clamp_reg", "tcsr_usb3_dp_phymode"; - vdd-supply = <&pmcobalt_l1>; - core-supply = <&pmcobalt_l2>; + vdd-supply = <&pm8998_l1>; + core-supply = <&pm8998_l2>; qcom,vdd-voltage-level = <0 880000 880000>; qcom,vbus-valid-override; qcom,qmp-phy-init-seq = @@ -2135,7 +1961,7 @@ reg = <0x17300000 0x00100>; interrupts = <0 162 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; qcom,proxy-reg-names = "vdd_cx"; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>; @@ -2216,9 +2042,9 @@ "mnoc_axi_clk"; interrupts = <0 448 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>; - vdd_mx-supply = <&pmcobalt_s9_level>; + vdd_mx-supply = <&pm8998_s9_level>; vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>; qcom,firmware-name = "modem"; qcom,pil-self-auth; @@ -2242,7 +2068,7 @@ }; tsens0: tsens@10aa000 { - compatible = "qcom,msmcobalt-tsens"; + compatible = "qcom,msm8998-tsens"; reg = <0x10aa000 0x2000>; reg-names = "tsens_physical"; interrupts = <0 458 0>, <0 445 0>; @@ -2253,7 +2079,7 @@ }; tsens1: tsens@10ad000 { - compatible = "qcom,msmcobalt-tsens"; + compatible = "qcom,msm8998-tsens"; reg = <0x10ad000 0x2000>; reg-names = "tsens_physical"; interrupts = <0 184 0>, <0 430 0>; @@ -2270,7 +2096,7 @@ <&clock_gcc clk_gcc_blsp2_ahb_clk>; clock-frequency = <15000000>; qcom,ipc-gpio = <&tlmm 121 0>; - qcom,finger-detect-gpio = <&pmcobalt_gpios 2 0>; + qcom,finger-detect-gpio = <&pm8998_gpios 2 0>; }; qcom,sensor-information { @@ -2588,7 +2414,7 @@ qcom,vdd-restriction-temp = <5>; qcom,vdd-restriction-temp-hysteresis = <10>; - vdd-dig-supply = <&pmcobalt_s1_floor_level>; + vdd-dig-supply = <&pm8998_s1_floor_level>; vdd-gfx-supply = <&gfx_vreg>; qcom,vdd-dig-rstr{ @@ -2614,6 +2440,229 @@ }; }; + pcie0: qcom,pcie@01c00000 { + compatible = "qcom,pci-msm"; + cell-index = <0>; + + reg = <0x1c00000 0x2000>, + <0x1c06000 0x1000>, + <0x1b000000 0xf1d>, + <0x1b000f20 0xa8>, + <0x1b100000 0x100000>, + <0x1b200000 0x100000>, + <0x1b300000 0xd00000>; + + reg-names = "parf", "phy", "dm_core", "elbi", + "conf", "io", "bars"; + + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>, + <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>; + interrupt-parent = <&pcie0>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 + 36 37>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0xffffffff>; + interrupt-map = <0 0 0 0 &intc 0 0 405 0 + 0 0 0 1 &intc 0 0 135 0 + 0 0 0 2 &intc 0 0 136 0 + 0 0 0 3 &intc 0 0 138 0 + 0 0 0 4 &intc 0 0 139 0 + 0 0 0 5 &intc 0 0 278 0 + 0 0 0 6 &intc 0 0 576 0 + 0 0 0 7 &intc 0 0 577 0 + 0 0 0 8 &intc 0 0 578 0 + 0 0 0 9 &intc 0 0 579 0 + 0 0 0 10 &intc 0 0 580 0 + 0 0 0 11 &intc 0 0 581 0 + 0 0 0 12 &intc 0 0 582 0 + 0 0 0 13 &intc 0 0 583 0 + 0 0 0 14 &intc 0 0 584 0 + 0 0 0 15 &intc 0 0 585 0 + 0 0 0 16 &intc 0 0 586 0 + 0 0 0 17 &intc 0 0 587 0 + 0 0 0 18 &intc 0 0 588 0 + 0 0 0 19 &intc 0 0 589 0 + 0 0 0 20 &intc 0 0 590 0 + 0 0 0 21 &intc 0 0 591 0 + 0 0 0 22 &intc 0 0 592 0 + 0 0 0 23 &intc 0 0 593 0 + 0 0 0 24 &intc 0 0 594 0 + 0 0 0 25 &intc 0 0 595 0 + 0 0 0 26 &intc 0 0 596 0 + 0 0 0 27 &intc 0 0 597 0 + 0 0 0 28 &intc 0 0 598 0 + 0 0 0 29 &intc 0 0 599 0 + 0 0 0 30 &intc 0 0 600 0 + 0 0 0 31 &intc 0 0 601 0 + 0 0 0 32 &intc 0 0 602 0 + 0 0 0 33 &intc 0 0 603 0 + 0 0 0 34 &intc 0 0 604 0 + 0 0 0 35 &intc 0 0 605 0 + 0 0 0 36 &intc 0 0 606 0 + 0 0 0 37 &intc 0 0 607 0>; + + interrupt-names = "int_msi", "int_a", "int_b", "int_c", + "int_d", "int_global_int", + "msi_0", "msi_1", "msi_2", "msi_3", + "msi_4", "msi_5", "msi_6", "msi_7", + "msi_8", "msi_9", "msi_10", "msi_11", + "msi_12", "msi_13", "msi_14", "msi_15", + "msi_16", "msi_17", "msi_18", "msi_19", + "msi_20", "msi_21", "msi_22", "msi_23", + "msi_24", "msi_25", "msi_26", "msi_27", + "msi_28", "msi_29", "msi_30", "msi_31"; + + qcom,phy-sequence = <0x804 0x01 0x00 + 0x034 0x14 0x00 + 0x138 0x30 0x00 + 0x048 0x0f 0x00 + 0x15c 0x06 0x00 + 0x090 0x01 0x00 + 0x088 0x20 0x00 + 0x0f0 0x00 0x00 + 0x0f8 0x01 0x00 + 0x0f4 0xc9 0x00 + 0x11c 0xff 0x00 + 0x120 0x3f 0x00 + 0x164 0x01 0x00 + 0x154 0x00 0x00 + 0x148 0x0a 0x00 + 0x05C 0x19 0x00 + 0x038 0x90 0x00 + 0x0b0 0x82 0x00 + 0x0c0 0x03 0x00 + 0x0bc 0x55 0x00 + 0x0b8 0x55 0x00 + 0x0a0 0x00 0x00 + 0x09c 0x0d 0x00 + 0x098 0x04 0x00 + 0x13c 0x00 0x00 + 0x060 0x08 0x00 + 0x068 0x16 0x00 + 0x070 0x34 0x00 + 0x15c 0x06 0x00 + 0x138 0x33 0x00 + 0x03c 0x02 0x00 + 0x040 0x0e 0x00 + 0x080 0x04 0x00 + 0x0dc 0x00 0x00 + 0x0d8 0x3f 0x00 + 0x00c 0x09 0x00 + 0x010 0x01 0x00 + 0x01c 0x40 0x00 + 0x020 0x01 0x00 + 0x014 0x02 0x00 + 0x018 0x00 0x00 + 0x024 0x7e 0x00 + 0x028 0x15 0x00 + 0x244 0x02 0x00 + 0x2a4 0x12 0x00 + 0x260 0x10 0x00 + 0x28c 0x06 0x00 + 0x504 0x03 0x00 + 0x500 0x1c 0x00 + 0x50c 0x14 0x00 + 0x4d4 0x0a 0x00 + 0x4d8 0x04 0x00 + 0x4dc 0x1a 0x00 + 0x434 0x4b 0x00 + 0x414 0x04 0x00 + 0x40c 0x04 0x00 + 0x4f8 0x00 0x00 + 0x4fc 0x80 0x00 + 0x51c 0x40 0x00 + 0x444 0x71 0x00 + 0x43c 0x40 0x00 + 0x854 0x04 0x00 + 0x62c 0x52 0x00 + 0x9ac 0x00 0x00 + 0x8a0 0x01 0x00 + 0x9e0 0x00 0x00 + 0x9dc 0x01 0x00 + 0x9a8 0x00 0x00 + 0x8a4 0x01 0x00 + 0x8a8 0x73 0x00 + 0x9d8 0x99 0x00 + 0x9b0 0x03 0x00 + 0x804 0x03 0x00 + 0x800 0x00 0x00 + 0x808 0x03 0x00>; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie0_clkreq_default + &pcie0_perst_default + &pcie0_wake_default>; + + perst-gpio = <&tlmm 35 0>; + wake-gpio = <&tlmm 37 0>; + + gdsc-vdd-supply = <&gdsc_pcie_0>; + vreg-1.8-supply = <&pm8998_l2>; + vreg-0.9-supply = <&pm8998_l1>; + vreg-cx-supply = <&pm8998_s1_level>; + + qcom,vreg-1.8-voltage-level = <1200000 1200000 24000>; + qcom,vreg-0.9-voltage-level = <880000 880000 24000>; + qcom,vreg-cx-voltage-level = <RPM_SMD_REGULATOR_LEVEL_BINNING + RPM_SMD_REGULATOR_LEVEL_SVS 0>; + + qcom,l1-supported; + qcom,l1ss-supported; + qcom,aux-clk-sync; + + qcom,ep-latency = <10>; + + qcom,ep-wakeirq; + + linux,pci-domain = <0>; + + qcom,msi-gicm-addr = <0x17a00040>; + qcom,msi-gicm-base = <0x260>; + + qcom,pcie-phy-ver = <0x20>; + qcom,use-19p2mhz-aux-clk; + + iommus = <&anoc1_smmu>; + qcom,smmu-exist; + qcom,smmu-sid-base = <0x1480>; + + qcom,msm-bus,name = "pcie0"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <45 512 0 0>, + <45 512 500 800>; + + clocks = <&clock_gcc clk_gcc_pcie_0_pipe_clk>, + <&clock_gcc clk_ln_bb_clk1>, + <&clock_gcc clk_gcc_pcie_0_aux_clk>, + <&clock_gcc clk_gcc_pcie_0_cfg_ahb_clk>, + <&clock_gcc clk_gcc_pcie_0_mstr_axi_clk>, + <&clock_gcc clk_gcc_pcie_0_slv_axi_clk>, + <&clock_gcc clk_gcc_pcie_clkref_clk>; + + clock-names = "pcie_0_pipe_clk", "pcie_0_ref_clk_src", + "pcie_0_aux_clk", "pcie_0_cfg_ahb_clk", + "pcie_0_mstr_axi_clk", "pcie_0_slv_axi_clk", + "pcie_0_ldo"; + + max-clock-frequency-hz = <0>, <0>, <19200000>, + <0>, <0>, <0>, <0>, <0>, <0>, + <0>, <0>, <0>, <0>, <0>, <0>, + <0>, <0>; + + resets = <&clock_gcc PCIE_PHY_BCR>, + <&clock_gcc PCIE_0_PHY_BCR>, + <&clock_gcc PCIE_0_PHY_BCR>; + + reset-names = "pcie_phy_reset", + "pcie_0_phy_reset", + "pcie_0_phy_pipe_reset"; + }; + qcom,bcl { compatible = "qcom,bcl"; qcom,bcl-enable; @@ -2637,8 +2686,8 @@ reg = <0x5c00000 0x4000>; interrupts = <0 390 1>; - vdd_cx-supply = <&pmcobalt_l27_level>; - vdd_px-supply = <&pmcobalt_lvs2>; + vdd_cx-supply = <&pm8998_l27_level>; + vdd_px-supply = <&pm8998_lvs2>; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 0>; qcom,proxy-reg-names = "vdd_cx", "vdd_px"; qcom,keep-proxy-regs-on; @@ -2721,7 +2770,7 @@ "sp2soc_irq_mask", "rmb_err", "rmb_err_spare2"; interrupts = <0 352 1>; - vdd_cx-supply = <&pmcobalt_s1_level>; + vdd_cx-supply = <&pm8998_s1_level>; qcom,proxy-reg-names = "vdd_cx"; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 100000>; @@ -2943,14 +2992,19 @@ <0 424 0 /* CE10 */ >, <0 425 0 /* CE11 */ >; qcom,wlan-msa-memory = <0x100000>; - vdd-0.8-cx-mx-supply = <&pmcobalt_l5>; - vdd-1.8-xo-supply = <&pmcobalt_l7_pin_ctrl>; - vdd-1.3-rfa-supply = <&pmcobalt_l17_pin_ctrl>; - vdd-3.3-ch0-supply = <&pmcobalt_l25_pin_ctrl>; + vdd-0.8-cx-mx-supply = <&pm8998_l5>; + vdd-1.8-xo-supply = <&pm8998_l7_pin_ctrl>; + vdd-1.3-rfa-supply = <&pm8998_l17_pin_ctrl>; + 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,icnss-vadc = <&pmcobalt_vadc>; - qcom,icnss-adc_tm = <&pmcobalt_adc_tm>; + 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>; }; tspp: msm_tspp@0c1e7000 { @@ -3015,8 +3069,8 @@ <45 512 0 0>, <45 512 600000 800000>; /* ~4.6Gbps (MCS12) */ qcom,use-ext-supply; - vdd-supply= <&pmcobalt_s7>; - vddio-supply= <&pmcobalt_s5>; + vdd-supply= <&pm8998_s7>; + vddio-supply= <&pm8998_s5>; qcom,use-ext-clocks; clocks = <&clock_gcc clk_rf_clk3>, <&clock_gcc clk_rf_clk3_pin>; @@ -3129,25 +3183,25 @@ status = "ok"; }; -#include "msm-pmcobalt.dtsi" -#include "msm-pmicobalt.dtsi" +#include "msm-pm8998.dtsi" +#include "msm-pmi8998.dtsi" #include "msm-pm8005.dtsi" -#include "msm-pmcobalt-rpm-regulator.dtsi" -#include "msmcobalt-regulator.dtsi" - -#include "msmcobalt-pm.dtsi" -#include "msm-arm-smmu-cobalt.dtsi" -#include "msm-arm-smmu-impl-defs-cobalt.dtsi" -#include "msmcobalt-ion.dtsi" -#include "msmcobalt-camera.dtsi" -#include "msmcobalt-vidc.dtsi" -#include "msmcobalt-coresight.dtsi" -#include "msmcobalt-bus.dtsi" -#include "msmcobalt-gpu.dtsi" -#include "msmcobalt-pinctrl.dtsi" +#include "msm-pm8998-rpm-regulator.dtsi" +#include "msm8998-regulator.dtsi" + +#include "msm8998-pm.dtsi" +#include "msm-arm-smmu-8998.dtsi" +#include "msm-arm-smmu-impl-defs-8998.dtsi" +#include "msm8998-ion.dtsi" +#include "msm8998-camera.dtsi" +#include "msm8998-vidc.dtsi" +#include "msm8998-coresight.dtsi" +#include "msm8998-bus.dtsi" +#include "msm8998-gpu.dtsi" +#include "msm8998-pinctrl.dtsi" #include "msm-audio-lpass.dtsi" -#include "msmcobalt-mdss.dtsi" -#include "msmcobalt-mdss-pll.dtsi" +#include "msm8998-mdss.dtsi" +#include "msm8998-mdss-pll.dtsi" #include "msm-rdbg.dtsi" -#include "msmcobalt-blsp.dtsi" -#include "msmcobalt-audio.dtsi" +#include "msm8998-blsp.dtsi" +#include "msm8998-audio.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi deleted file mode 100644 index d1776e796375..000000000000 --- a/arch/arm/boot/dts/qcom/msmcobalt-qrd-vr1.dtsi +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (c) 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <dt-bindings/interrupt-controller/irq.h> -#include "msmcobalt-pinctrl.dtsi" -#include "msmcobalt-camera-sensor-qrd-vr1.dtsi" - -&blsp1_uart3_hs { - status = "ok"; -}; - -&ufsphy1 { - vdda-phy-supply = <&pmcobalt_l1>; - vdda-pll-supply = <&pmcobalt_l2>; - vddp-ref-clk-supply = <&pmcobalt_l26>; - vdda-phy-max-microamp = <51400>; - vdda-pll-max-microamp = <14600>; - vddp-ref-clk-max-microamp = <100>; - vddp-ref-clk-always-on; - status = "ok"; -}; - -&ufs1 { - vdd-hba-supply = <&gdsc_ufs>; - vdd-hba-fixed-regulator; - vcc-supply = <&pmcobalt_l20>; - vccq-supply = <&pmcobalt_l26>; - vccq2-supply = <&pmcobalt_s4>; - vcc-max-microamp = <750000>; - vccq-max-microamp = <560000>; - vccq2-max-microamp = <750000>; - status = "ok"; -}; - -&ufs_ice { - status = "ok"; -}; - -&sdhc_2 { - vdd-supply = <&pmcobalt_l21>; - qcom,vdd-voltage-level = <2950000 2960000>; - qcom,vdd-current-level = <200 800000>; - - vdd-io-supply = <&pmcobalt_l13>; - qcom,vdd-io-voltage-level = <1808000 2960000>; - qcom,vdd-io-current-level = <200 22000>; - - pinctrl-names = "active", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; - - qcom,clk-rates = <400000 20000000 25000000 - 50000000 100000000 200000000>; - qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; - - cd-gpios = <&tlmm 95 0x0>; - - status = "ok"; -}; - -&uartblsp2dm1 { - status = "ok"; - pinctrl-names = "default"; - pinctrl-0 = <&uart_console_active>; -}; - -&pmcobalt_gpios { - /* GPIO 6 for Vol+ Key */ - gpio@c500 { - status = "okay"; - qcom,mode = <0>; - qcom,pull = <0>; - qcom,vin-sel = <0>; - qcom,src-sel = <0>; - qcom,out-strength = <1>; - }; -}; - -&soc { - gpio_keys { - compatible = "gpio-keys"; - input-name = "gpio-keys"; - status = "okay"; - - vol_up { - label = "volume_up"; - gpios = <&pmcobalt_gpios 6 0x1>; - linux,input-type = <1>; - linux,code = <115>; - gpio-key,wakeup; - debounce-interval = <15>; - }; - }; - - sound-tavil { - qcom,model = "msmcobalt-qvr-tavil-snd-card"; - qcom,audio-routing = - "RX_BIAS", "MCLK", - "MADINPUT", "MCLK", - "AMIC2", "MIC BIAS2", - "MIC BIAS2", "Headset Mic", - "DMIC0", "MIC BIAS1", - "MIC BIAS1", "Digital Mic0", - "DMIC1", "MIC BIAS1", - "MIC BIAS1", "Digital Mic1", - "DMIC2", "MIC BIAS3", - "MIC BIAS3", "Digital Mic2", - "DMIC4", "MIC BIAS4", - "MIC BIAS4", "Digital Mic4", - "SpkrLeft IN", "SPK1 OUT"; - - qcom,msm-mbhc-hphl-swh = <1>; - /delete-property/ qcom,us-euro-gpios; - /delete-property/ qcom,hph-en0-gpio; - /delete-property/ qcom,hph-en0-gpio; - - qcom,wsa-max-devs = <1>; - qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>; - qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft"; - }; -}; - -/{ - qrd_batterydata: qcom,battery-data { - qcom,batt-id-range-pct = <15>; - - #include "batterydata-qrd-skuk-4v4-3000mah.dtsi" - }; -}; - -&pmicobalt_fg { - qcom,battery-data = <&qrd_batterydata>; -}; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-cdp.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-cdp.dts deleted file mode 100644 index ac564d700cd8..000000000000 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-cdp.dts +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -/dts-v1/; - -#include "msmcobalt-v2.1-interposer-msmfalcon.dtsi" -#include "msmcobalt-interposer-msmfalcon-cdp.dtsi" -#include "msmcobalt-interposer-pmfalcon.dtsi" - -/ { - model = "Qualcomm Technologies, Inc. MSM COBALT v2.1 MSM FALCON Interposer CDP"; - compatible = "qcom,msmcobalt-cdp", "qcom,msmcobalt", "qcom,cdp"; - qcom,board-id = <1 1>; -}; diff --git a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-mtp.dts b/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-mtp.dts deleted file mode 100644 index aaa56ea2f492..000000000000 --- a/arch/arm/boot/dts/qcom/msmcobalt-v2.1-interposer-msmfalcon-mtp.dts +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 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 - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -/dts-v1/; - -#include "msmcobalt-v2.1-interposer-msmfalcon.dtsi" -#include "msmcobalt-interposer-msmfalcon-mtp.dtsi" -#include "msmcobalt-interposer-pmfalcon.dtsi" - -/ { - model = "Qualcomm Technologies, Inc. MSM COBALT v2.1 MSM FALCON Interposer MTP"; - compatible = "qcom,msmcobalt-mtp", "qcom,msmcobalt", "qcom,mtp"; - qcom,board-id = <8 2>; -}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi new file mode 100644 index 000000000000..b6b3c1f6245f --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msmfalcon-wsa881x.dtsi" + +&slim_aud { + msm_dai_slim { + compatible = "qcom,msm-dai-slim"; + elemental-addr = [ff ff ff fe 17 02]; + }; + + tasha_codec { + compatible = "qcom,tasha-slim-pgd"; + elemental-addr = [00 01 a0 01 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30>; + + qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>; + + clock-names = "wcd_clk", "wcd_native_clk"; + clocks = <&clock_audio clk_audio_pmi_clk>, + <&clock_audio clk_audio_ap_clk2>; + + cdc-vdd-buck-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-buck-voltage = <1800000 1800000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-buck-sido-supply = <&pmfalcon_s4>; + qcom,cdc-buck-sido-voltage = <1800000 1800000>; + qcom,cdc-buck-sido-current = <250000>; + + cdc-vdd-tx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pmfalcon_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-buck-sido", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1"; + + qcom,cdc-micbias1-mv = <1800>; + qcom,cdc-micbias2-mv = <1800>; + qcom,cdc-micbias3-mv = <1800>; + qcom,cdc-micbias4-mv = <1800>; + + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tasha-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 a0 01 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + }; + + wcd934x_cdc: tavil_codec { + compatible = "qcom,tavil-slim-pgd"; + elemental-addr = [00 01 50 02 17 02]; + + interrupt-parent = <&wcd9xxx_intc>; + interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 + 30 31>; + + qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>; + + clock-names = "wcd_clk"; + clocks = <&clock_audio_lnbb clk_audio_pmi_lnbb_clk>; + + cdc-vdd-buck-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-buck-voltage = <1800000 1800000>; + qcom,cdc-vdd-buck-current = <650000>; + + cdc-buck-sido-supply = <&pmfalcon_s4>; + qcom,cdc-buck-sido-voltage = <1800000 1800000>; + qcom,cdc-buck-sido-current = <250000>; + + cdc-vdd-tx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-tx-h-current = <25000>; + + cdc-vdd-rx-h-supply = <&pmfalcon_s4>; + qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>; + qcom,cdc-vdd-rx-h-current = <25000>; + + cdc-vddpx-1-supply = <&pmfalcon_s4>; + qcom,cdc-vddpx-1-voltage = <1800000 1800000>; + qcom,cdc-vddpx-1-current = <10000>; + + qcom,cdc-static-supplies = "cdc-vdd-buck", + "cdc-buck-sido", + "cdc-vdd-tx-h", + "cdc-vdd-rx-h", + "cdc-vddpx-1"; + + qcom,cdc-micbias1-mv = <1800>; + qcom,cdc-micbias2-mv = <1800>; + qcom,cdc-micbias3-mv = <1800>; + qcom,cdc-micbias4-mv = <1800>; + + qcom,cdc-mclk-clk-rate = <9600000>; + qcom,cdc-slim-ifd = "tavil-slim-ifd"; + qcom,cdc-slim-ifd-elemental-addr = [00 00 50 02 17 02]; + qcom,cdc-dmic-sample-rate = <4800000>; + qcom,cdc-mad-dmic-rate = <600000>; + + qcom,wdsp-cmpnt-dev-name = "tavil_codec"; + + wcd_spi_0: wcd_spi { + compatible = "qcom,wcd-spi-v2"; + qcom,master-bus-num = <10>; + qcom,chip-select = <0>; + qcom,max-frequency = <24000000>; + qcom,mem-base-addr = <0x100000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi index 61764a095a29..c401d364409b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-blsp.dtsi @@ -22,11 +22,203 @@ spi6 = &spi_6; spi7 = &spi_7; spi8 = &spi_8; + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c3 = &i2c_3; + i2c4 = &i2c_4; + i2c5 = &i2c_5; + i2c6 = &i2c_6; + i2c7 = &i2c_7; + i2c8 = &i2c_8; }; }; &soc { + i2c_1: i2c@c175000 { /* BLSP1 QUP1 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc175000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 95 0>; + dmas = <&dma_blsp1 4 64 0x20000020 0x20>, + <&dma_blsp1 5 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>, + <&clock_gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_1_active>; + pinctrl-1 = <&i2c_1_sleep>; + status = "disabled"; + }; + + i2c_2: i2c@c176000 { /* BLSP1 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc176000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 96 0>; + dmas = <&dma_blsp1 6 64 0x20000020 0x20>, + <&dma_blsp1 7 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>, + <&clock_gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_2_active>; + pinctrl-1 = <&i2c_2_sleep>; + status = "disabled"; + }; + + i2c_3: i2c@c177000 { /* BLSP1 QUP3 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc177000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 97 0>; + dmas = <&dma_blsp1 8 64 0x20000020 0x20>, + <&dma_blsp1 9 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>, + <&clock_gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_3_active>; + pinctrl-1 = <&i2c_3_sleep>; + status = "disabled"; + }; + + i2c_4: i2c@c178000 { /* BLSP1 QUP4 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc178000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 98 0>; + dmas = <&dma_blsp1 10 64 0x20000020 0x20>, + <&dma_blsp1 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <86>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>, + <&clock_gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_4_active>; + pinctrl-1 = <&i2c_4_sleep>; + status = "disabled"; + }; + + i2c_5: i2c@c1b5000 { /* BLSP2 QUP1 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc1b5000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 101 0>; + dmas = <&dma_blsp2 4 64 0x20000020 0x20>, + <&dma_blsp2 5 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>, + <&clock_gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_5_active>; + pinctrl-1 = <&i2c_5_sleep>; + status = "disabled"; + }; + + i2c_6: i2c@c1b6000 { /* BLSP2 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc1b6000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 102 0>; + dmas = <&dma_blsp2 6 64 0x20000020 0x20>, + <&dma_blsp2 7 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>, + <&clock_gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + status = "disabled"; + }; + + i2c_7: i2c@c1b7000 { /* BLSP2 QUP3 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc1b7000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 103 0>; + dmas = <&dma_blsp2 8 64 0x20000020 0x20>, + <&dma_blsp2 9 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>, + <&clock_gcc GCC_BLSP2_QUP3_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_7_active>; + pinctrl-1 = <&i2c_7_sleep>; + status = "disabled"; + }; + + i2c_8: i2c@c1b8000 { /* BLSP2 QUP4 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc1b8000 0x600>; + reg-names = "qup_phys_addr"; + interrupt-names = "qup_irq"; + interrupts = <0 104 0>; + dmas = <&dma_blsp2 10 64 0x20000020 0x20>, + <&dma_blsp2 11 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + qcom,master-id = <84>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>, + <&clock_gcc GCC_BLSP2_QUP4_I2C_APPS_CLK>; + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_8_active>; + pinctrl-1 = <&i2c_8_sleep>; + status = "disabled"; + }; + spi_1: spi@c175000 { /* BLSP1 QUP1 */ compatible = "qcom,spi-qup-v2"; #address-cells = <1>; @@ -226,4 +418,152 @@ <&clock_gcc GCC_BLSP2_QUP4_SPI_APPS_CLK>; status = "disabled"; }; + + blsp1_uart1_hs: uart@c16f000 { /* BLSP1 UART1 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xc16f000 0x200>, + <0xc144000 0x1f000>; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp1_uart1_hs>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 0 107 0 + 1 &intc 0 0 238 0 + 2 &tlmm 1 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xfd>; + + qcom,bam-tx-ep-pipe-index = <0>; + qcom,bam-rx-ep-pipe-index = <1>; + qcom,master-id = <86>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc GCC_BLSP1_UART1_APPS_CLK>, + <&clock_gcc GCC_BLSP1_AHB_CLK>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&blsp1_uart1_sleep>; + pinctrl-1 = <&blsp1_uart1_active>; + + qcom,msm-bus,name = "buart1"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <86 512 0 0>, + <86 512 500 800>; + status = "disabled"; + }; + + blsp1_uart2_hs: uart@c170000 { /* BLSP1 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xc170000 0x200>, + <0xc144000 0x1f000>; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp1_uart2_hs>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 0 108 0 + 1 &intc 0 0 238 0 + 2 &tlmm 5 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xfd>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <86>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>, + <&clock_gcc GCC_BLSP1_AHB_CLK>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&blsp1_uart2_sleep>; + pinctrl-1 = <&blsp1_uart2_active>; + + qcom,msm-bus,name = "buart2"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <86 512 0 0>, + <86 512 500 800>; + status = "disabled"; + }; + + blsp2_uart1_hs: uart@c1af000 { /* BLSP2 UART1 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xc1af000 0x200>, + <0xc184000 0x1f000>; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart1_hs>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 0 113 0 + 1 &intc 0 0 239 0 + 2 &tlmm 17 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xfd>; + + qcom,bam-tx-ep-pipe-index = <0>; + qcom,bam-rx-ep-pipe-index = <1>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc GCC_BLSP2_UART1_APPS_CLK>, + <&clock_gcc GCC_BLSP2_AHB_CLK>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&blsp2_uart1_sleep>; + pinctrl-1 = <&blsp2_uart1_active>; + + qcom,msm-bus,name = "buart3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + status = "disabled"; + }; + + blsp2_uart2_hs: uart@c1b0000 { /* BLSP2 UART2 */ + compatible = "qcom,msm-hsuart-v14"; + reg = <0xc1b0000 0x200>, + <0xc184000 0x1f000>; + reg-names = "core_mem", "bam_mem"; + interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; + #address-cells = <0>; + interrupt-parent = <&blsp2_uart2_hs>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 0 114 0 + 1 &intc 0 0 239 0 + 2 &tlmm 25 0>; + + qcom,inject-rx-on-wakeup; + qcom,rx-char-to-inject = <0xfd>; + + qcom,bam-tx-ep-pipe-index = <2>; + qcom,bam-rx-ep-pipe-index = <3>; + qcom,master-id = <84>; + clock-names = "core_clk", "iface_clk"; + clocks = <&clock_gcc GCC_BLSP2_UART2_APPS_CLK>, + <&clock_gcc GCC_BLSP2_AHB_CLK>; + pinctrl-names = "sleep", "default"; + pinctrl-0 = <&blsp2_uart2_sleep>; + pinctrl-1 = <&blsp2_uart2_active>; + + qcom,msm-bus,name = "buart4"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <84 512 0 0>, + <84 512 500 800>; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi new file mode 100644 index 000000000000..b3be67bd8c32 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi @@ -0,0 +1,196 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + usb3: ssusb@a800000 { + compatible = "qcom,dwc-usb3-msm"; + reg = <0x0a800000 0xfc100>, + <0x0c016000 0x400>; + reg-names = "core_base", + "ahb2phy_base"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + interrupts = <0 347 0>, <0 243 0>, <0 180 0>; + interrupt-names = "hs_phy_irq", "ss_phy_irq", "pwr_event_irq"; + + USB3_GDSC-supply = <&gdsc_usb30>; + + qcom,usb-dbm = <&dbm_1p5>; + qcom,msm-bus,name = "usb3"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <61 512 0 0>, + <61 512 240000 800000>; + + qcom,dwc-usb3-msm-tx-fifo-size = <21288>; + + clocks = <&clock_gcc GCC_USB30_MASTER_CLK>, + <&clock_gcc GCC_CFG_NOC_USB3_AXI_CLK>, + <&clock_gcc GCC_AGGRE2_USB3_AXI_CLK>, + <&clock_gcc GCC_USB30_MOCK_UTMI_CLK>, + <&clock_gcc GCC_USB30_SLEEP_CLK>, + <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&clock_rpmcc CXO_DWC3_CLK>; + + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + "utmi_clk", "sleep_clk", "cfg_ahb_clk", "xo"; + + resets = <&clock_gcc GCC_USB_30_BCR>; + reset-names = "core_reset"; + + dwc3@a800000 { + compatible = "snps,dwc3"; + reg = <0x0a800000 0xc8d0>; + interrupt-parent = <&intc>; + interrupts = <0 131 0>; + usb-phy = <&qusb_phy0>, <&ssphy>; + tx-fifo-resize; + snps,usb3-u1u2-disable; + snps,nominal-elastic-buffer; + snps,is-utmi-l1-suspend; + snps,hird-threshold = /bits/ 8 <0x0>; + }; + + qcom,usbbam@a904000 { + compatible = "qcom,usb-bam-msm"; + reg = <0x0a904000 0x17000>; + interrupt-parent = <&intc>; + interrupts = <0 132 0>; + + qcom,bam-type = <0>; + qcom,usb-bam-fifo-baseaddr = <0x066bb000>; + qcom,usb-bam-num-pipes = <8>; + qcom,ignore-core-reset-ack; + qcom,disable-clk-gating; + qcom,usb-bam-override-threshold = <0x4001>; + qcom,usb-bam-max-mbps-highspeed = <400>; + qcom,usb-bam-max-mbps-superspeed = <3600>; + qcom,reset-bam-on-connect; + + qcom,pipe0 { + label = "ssusb-ipa-out-0"; + qcom,usb-bam-mem-type = <1>; + qcom,dir = <0>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,src-bam-pipe-index = <1>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + }; + qcom,pipe1 { + label = "ssusb-ipa-in-0"; + qcom,usb-bam-mem-type = <1>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <1>; + qcom,dst-bam-pipe-index = <0>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + }; + qcom,pipe2 { + label = "ssusb-qdss-in-0"; + qcom,usb-bam-mem-type = <2>; + qcom,dir = <1>; + qcom,pipe-num = <0>; + qcom,peer-bam = <0>; + qcom,peer-bam-physical-address = <0x06064000>; + qcom,src-bam-pipe-index = <0>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-offset = <0x0>; + qcom,data-fifo-size = <0x1800>; + qcom,descriptor-fifo-offset = <0x1800>; + qcom,descriptor-fifo-size = <0x800>; + }; + qcom,pipe3 { + label = "ssusb-dpl-ipa-in-1"; + qcom,usb-bam-mem-type = <1>; + qcom,dir = <1>; + qcom,pipe-num = <1>; + qcom,peer-bam = <1>; + qcom,dst-bam-pipe-index = <2>; + qcom,data-fifo-size = <0x8000>; + qcom,descriptor-fifo-size = <0x2000>; + }; + }; + }; + + qusb_phy0: qusb@c012000 { + compatible = "qcom,qusb2phy"; + reg = <0x0c012000 0x180>, + <0x00188018 0x4>; + reg-names = "qusb_phy_base", + "ref_clk_addr"; + vdd-supply = <&pm2falcon_l1>; + vdda18-supply = <&pmfalcon_l10>; + vdda33-supply = <&pm2falcon_l7>; + qcom,vdd-voltage-level = <0 925000 925000>; + qcom,tune2-efuse-bit-pos = <21>; + qcom,tune2-efuse-num-bits = <4>; + qcom,enable-dpdm-pulsing; + qcom,qusb-phy-init-seq = <0xf8 0x80 + 0xb3 0x84 + 0x83 0x88 + 0xc0 0x8c + 0x30 0x08 + 0x79 0x0c + 0x21 0x10 + 0x14 0x9c + 0x9f 0x1c + 0x00 0x18>; + phy_type= "utmi"; + + clocks = <&clock_rpmcc RPM_LN_BB_CLK1>, + <&clock_gcc GCC_RX0_USB2_CLKREF_CLK>, + <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + + clock-names = "ref_clk_src", "ref_clk", "cfg_ahb_clk"; + + resets = <&clock_gcc GCC_QUSB2PHY_PRIM_BCR>; + reset-names = "phy_reset"; + }; + + ssphy: ssphy@c010000 { + compatible = "qcom,usb-ssphy-qmp-v2"; + reg = <0xc010000 0x7a8>, + <0x01fcb244 0x4>, + <0x01fcb248 0x4>; + reg-names = "qmp_phy_base", + "vls_clamp_reg", + "tcsr_usb3_dp_phymode"; + vdd-supply = <&pm2falcon_l1>; + core-supply = <&pmfalcon_l10>; + qcom,vdd-voltage-level = <0 925000 925000>; + qcom,vbus-valid-override; + + clocks = <&clock_gcc GCC_USB3_PHY_AUX_CLK>, + <&clock_gcc GCC_USB3_PHY_PIPE_CLK>, + <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&clock_rpmcc RPM_LN_BB_CLK1>, + <&clock_gcc GCC_USB3_CLKREF_CLK>; + + clock-names = "aux_clk", "pipe_clk", "cfg_ahb_clk", + "ref_clk_src", "ref_clk"; + + resets = <&clock_gcc GCC_USB3_PHY_BCR>, + <&clock_gcc GCC_USB3PHY_PHY_BCR>; + reset-names = "phy_reset", "phy_phy_reset"; + }; + + dbm_1p5: dbm@a8f8000 { + compatible = "qcom,usb-dbm-1p5"; + reg = <0xa8f8000 0x300>; + qcom,reset-ep-after-lpm-resume; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi index f13e34f8296b..a029d8689111 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi @@ -22,12 +22,12 @@ uart_console_active: uart_console_active { mux { - pins = "gpio0", "gpio1"; - function = "blsp_uart1"; + pins = "gpio4", "gpio5"; + function = "blsp_uart2"; }; config { - pins = "gpio0", "gpio1"; + pins = "gpio4", "gpio5"; drive-strength = <2>; bias-disable; }; @@ -113,6 +113,231 @@ }; }; + /* I2C CONFIGURATION */ + i2c_1 { + i2c_1_active: i2c_1_active { + mux { + pins = "gpio2", "gpio3"; + function = "blsp_i2c1"; + }; + + config { + pins = "gpio2", "gpio3"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_1_sleep: i2c_1_sleep { + mux { + pins = "gpio2", "gpio3"; + function = "blsp_i2c1"; + }; + + config { + pins = "gpio2", "gpio3"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_2 { + i2c_2_active: i2c_2_active { + mux { + pins = "gpio6", "gpio7"; + function = "blsp_i2c2"; + }; + + config { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_2_sleep: i2c_2_sleep { + mux { + pins = "gpio6", "gpio7"; + function = "blsp_i2c2"; + }; + + config { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_3 { + i2c_3_active: i2c_3_active { + mux { + pins = "gpio10", "gpio11"; + function = "blsp_i2c3"; + }; + + config { + pins = "gpio10", "gpio11"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_3_sleep: i2c_3_sleep { + mux { + pins = "gpio10", "gpio11"; + function = "blsp_i2c3"; + }; + + config { + pins = "gpio10", "gpio11"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_4 { + i2c_4_active: i2c_4_active { + mux { + pins = "gpio14", "gpio15"; + function = "blsp_i2c4"; + }; + + config { + pins = "gpio14", "gpio15"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_4_sleep: i2c_4_sleep { + mux { + pins = "gpio14", "gpio15"; + function = "blsp_i2c4"; + }; + + config { + pins = "gpio14", "gpio15"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_5 { + i2c_5_active: i2c_5_active { + mux { + pins = "gpio18", "gpio19"; + function = "blsp_i2c5"; + }; + + config { + pins = "gpio18", "gpio19"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_5_sleep: i2c_5_sleep { + mux { + pins = "gpio18", "gpio19"; + function = "blsp_i2c5"; + }; + + config { + pins = "gpio18", "gpio19"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_6 { + i2c_6_active: i2c_6_active { + mux { + pins = "gpio22", "gpio23"; + function = "blsp_i2c6"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_6_sleep: i2c_6_sleep { + mux { + pins = "gpio22", "gpio23"; + function = "blsp_i2c6"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_7 { + i2c_7_active: i2c_7_active { + mux { + pins = "gpio26", "gpio27"; + function = "blsp_i2c7"; + }; + + config { + pins = "gpio26", "gpio27"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_7_sleep: i2c_7_sleep { + mux { + pins = "gpio26", "gpio27"; + function = "blsp_i2c7"; + }; + + config { + pins = "gpio26", "gpio27"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + i2c_8 { + i2c_8_active: i2c_8_active { + mux { + pins = "gpio30", "gpio31"; + function = "blsp_i2c8_a"; + }; + + config { + pins = "gpio30", "gpio31"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_8_sleep: i2c_8_sleep { + mux { + pins = "gpio30", "gpio31"; + function = "blsp_i2c8_a"; + }; + + config { + pins = "gpio30", "gpio31"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + /* SPI CONFIGURATION */ spi_1 { spi_1_active: spi_1_active { @@ -369,5 +594,171 @@ }; }; }; + + /* WSA speaker reset pins */ + spkr_1_sd_n { + spkr_1_sd_n_sleep: spkr_1_sd_n_sleep { + mux { + pins = "gpio26"; + function = "gpio"; + }; + + config { + pins = "gpio26"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; + input-enable; + }; + }; + + spkr_1_sd_n_active: spkr_1_sd_n_active { + mux { + pins = "gpio26"; + function = "gpio"; + }; + + config { + pins = "gpio26"; + drive-strength = <16>; /* 16 mA */ + bias-disable; + output-high; + }; + }; + }; + + spkr_2_sd_n { + spkr_2_sd_n_sleep: spkr_2_sd_n_sleep { + mux { + pins = "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio27"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; + input-enable; + }; + }; + + spkr_2_sd_n_active: spkr_2_sd_n_active { + mux { + pins = "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio27"; + drive-strength = <16>; /* 16 mA */ + bias-disable; + output-high; + }; + }; + }; + + /* HS UART CONFIGURATION */ + blsp1_uart1_active: blsp1_uart1_active { + mux { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + function = "blsp_uart1"; + }; + + config { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp1_uart1_sleep: blsp1_uart1_sleep { + mux { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + function = "gpio"; + }; + + config { + pins = "gpio0", "gpio1", "gpio2", "gpio3"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp1_uart2_active: blsp1_uart2_active { + mux { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "blsp_uart2 "; + }; + + config { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp1_uart2_sleep: blsp1_uart2_sleep { + mux { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + function = "gpio"; + }; + + config { + pins = "gpio4", "gpio5", "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp2_uart1_active: blsp2_uart1_active { + mux { + pins = "gpio16", "gpio17", "gpio18", "gpio19"; + function = "blsp_uart5"; + }; + + config { + pins = "gpio16", "gpio17", "gpio18", "gpio19"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp2_uart1_sleep: blsp2_uart1_sleep { + mux { + pins = "gpio16", "gpio17", "gpio18", "gpio19"; + function = "gpio"; + }; + + config { + pins = "gpio16", "gpio17", "gpio18", "gpio19"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp2_uart2_active: blsp2_uart2_active { + mux { + pins = "gpio24", "gpio25", "gpio26", "gpio27"; + function = "blsp_uart6_a"; + }; + + config { + pins = "gpio24", "gpio25", "gpio26", "gpio27"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp2_uart2_sleep: blsp2_uart2_sleep { + mux { + pins = "gpio24", "gpio25", "gpio26", "gpio27"; + function = "gpio"; + }; + + config { + pins = "gpio24", "gpio25", "gpio26", "gpio27"; + drive-strength = <2>; + bias-disable; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi index 75cf4de97672..0ab76c273ac3 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi @@ -142,6 +142,7 @@ }; rpm-regulator-ldoa2 { + status = "okay"; pmfalcon_l2: regulator-l2 { regulator-min-microvolt = <950000>; regulator-max-microvolt = <1010000>; @@ -150,6 +151,7 @@ }; rpm-regulator-ldoa3 { + status = "okay"; pmfalcon_l3: regulator-l3 { regulator-min-microvolt = <950000>; regulator-max-microvolt = <1010000>; @@ -159,6 +161,7 @@ /* TODO: remove if ADRASTEA CX/MX not voted from APPS */ rpm-regulator-ldoa5 { + status = "okay"; pmfalcon_l5: regulator-l5 { regulator-min-microvolt = <525000>; regulator-max-microvolt = <950000>; @@ -167,6 +170,7 @@ }; rpm-regulator-ldoa6 { + status = "okay"; pmfalcon_l6: regulator-l6 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1370000>; @@ -175,6 +179,7 @@ }; rpm-regulator-ldoa7 { + status = "okay"; pmfalcon_l7: regulator-l7 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -183,6 +188,7 @@ }; rpm-regulator-ldoa8 { + status = "okay"; pmfalcon_l8: regulator-l8 { regulator-min-microvolt = <1750000>; regulator-max-microvolt = <1900000>; @@ -191,6 +197,7 @@ }; rpm-regulator-ldoa9 { + status = "okay"; pmfalcon_l9: regulator-l9 { regulator-min-microvolt = <1750000>; regulator-max-microvolt = <1900000>; @@ -199,6 +206,7 @@ }; rpm-regulator-ldoa10 { + status = "okay"; pmfalcon_l10: regulator-l10 { regulator-min-microvolt = <1780000>; regulator-max-microvolt = <1950000>; @@ -207,6 +215,7 @@ }; rpm-regulator-ldoa11 { + status = "okay"; pmfalcon_l11: regulator-l11 { regulator-min-microvolt = <1780000>; regulator-max-microvolt = <1950000>; @@ -215,6 +224,7 @@ }; rpm-regulator-ldoa12 { + status = "okay"; pmfalcon_l12: regulator-l12 { regulator-min-microvolt = <1780000>; regulator-max-microvolt = <1950000>; @@ -223,6 +233,7 @@ }; rpm-regulator-ldoa13 { + status = "okay"; pmfalcon_l13: regulator-l13 { regulator-min-microvolt = <1780000>; regulator-max-microvolt = <1950000>; @@ -231,6 +242,7 @@ }; rpm-regulator-ldoa14 { + status = "okay"; pmfalcon_l14: regulator-l14 { regulator-min-microvolt = <1710000>; regulator-max-microvolt = <1900000>; @@ -239,6 +251,7 @@ }; rpm-regulator-ldoa15 { + status = "okay"; pmfalcon_l15: regulator-l15 { regulator-min-microvolt = <1650000>; regulator-max-microvolt = <2950000>; @@ -247,6 +260,7 @@ }; rpm-regulator-ldoa17 { + status = "okay"; pmfalcon_l17: regulator-l17 { regulator-min-microvolt = <1650000>; regulator-max-microvolt = <2950000>; @@ -255,6 +269,7 @@ }; rpm-regulator-ldoa19 { + status = "okay"; pmfalcon_l19: regulator-l19 { regulator-min-microvolt = <3200000>; regulator-max-microvolt = <3400000>; @@ -263,6 +278,7 @@ }; rpm-regulator-ldob1 { + status = "okay"; pm2falcon_l1: regulator-l1 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <925000>; @@ -271,6 +287,7 @@ }; rpm-regulator-ldob2 { + status = "okay"; pm2falcon_l2: regulator-l2 { regulator-min-microvolt = <350000>; regulator-max-microvolt = <3100000>; @@ -279,6 +296,7 @@ }; rpm-regulator-ldob3 { + status = "okay"; pm2falcon_l3: regulator-l3 { regulator-min-microvolt = <1710000>; regulator-max-microvolt = <3600000>; @@ -287,6 +305,7 @@ }; rpm-regulator-ldob4 { + status = "okay"; pm2falcon_l4: regulator-l4 { regulator-min-microvolt = <1700000>; regulator-max-microvolt = <2950000>; @@ -295,6 +314,7 @@ }; rpm-regulator-ldob5 { + status = "okay"; pm2falcon_l5: regulator-l5 { regulator-min-microvolt = <1721000>; regulator-max-microvolt = <3600000>; @@ -303,6 +323,7 @@ }; rpm-regulator-ldob6 { + status = "okay"; pm2falcon_l6: regulator-l6 { regulator-min-microvolt = <1700000>; regulator-max-microvolt = <3300000>; @@ -311,6 +332,7 @@ }; rpm-regulator-ldob7 { + status = "okay"; pm2falcon_l7: regulator-l7 { regulator-min-microvolt = <2700000>; regulator-max-microvolt = <3125000>; @@ -319,6 +341,7 @@ }; rpm-regulator-ldob8 { + status = "okay"; pm2falcon_l8: regulator-l8 { regulator-min-microvolt = <3200000>; regulator-max-microvolt = <3400000>; @@ -417,6 +440,16 @@ }; }; +&pmfalcon_charger { + smb2_vbus: qcom,smb2-vbus { + regulator-name = "smb2-vbus"; + }; + + smb2_vconn: qcom,smb2-vconn { + regulator-name = "smb2-vconn"; + }; +}; + /* Stub regulators */ / { /* GFX Supply */ diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts index c94ba0df3e6e..2b8a78ee1fdc 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts @@ -26,6 +26,38 @@ }; }; +&usb3 { + /delete-property/ USB3_GDSC-supply; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + reg = <0x0a928000 0x8000>, + <0x0a8f8800 0x400>, + <0x0a920000 0x100>; + reg-names = "qusb_phy_base", + "qscratch_base", + "emu_phy_base"; + qcom,emulation; + qcom,qusb-phy-init-seq = <0x19 0x1404 + 0x20 0x1414 + 0x79 0x1410 + 0x00 0x1418 + 0x99 0x1404 + 0x04 0x1408 + 0xd9 0x1404>; + qcom,emu-dcm-reset-seq = <0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x5 0x14>; +}; + &uartblsp1dm1 { status = "ok"; pinctrl-names = "default"; @@ -62,3 +94,20 @@ compatible = "qcom,dummycc"; clock-output-names = "gcc_clocks"; }; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&clock_gfx { + compatible = "qcom,dummycc"; + clock-output-names = "gfx_clocks"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts index 00d97c8fdd32..d279e742c23a 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts @@ -26,6 +26,22 @@ }; }; +&usb3 { + reg = <0xa800000 0xfc000>; + reg-names = "core_base"; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + compatible = "usb-nop-xceiv"; +}; + &uartblsp1dm1 { status = "ok"; pinctrl-names = "default"; @@ -57,3 +73,15 @@ status = "ok"; }; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi new file mode 100644 index 000000000000..73d1cac48f9e --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi @@ -0,0 +1,268 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/msm/msm-bus-ids.h> +#include <dt-bindings/clock/qcom,gcc-msmfalcon.h> +#include <dt-bindings/clock/qcom,mmcc-msmfalcon.h> + +&soc { + msm_vidc: qcom,vidc@cc00000 { + compatible = "qcom,msm-vidc"; + status = "ok"; + reg = <0xcc00000 0x100000>; + interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>; + qcom,hfi = "venus"; + qcom,hfi-version = "3xx"; + qcom,firmware-name = "venus"; + qcom,sw-power-collapse; + qcom,debug-timeout; + qcom,reg-presets = + <0x80124 0x00000003>, + <0x80550 0x01111111>, + <0x80560 0x01111111>, + <0x80568 0x01111111>, + <0x80570 0x01111111>, + <0x80580 0x01111111>, + <0x80588 0x01111111>, + <0xe2010 0x00000000>; + + qcom,max-hw-load = <1036800>; /* Full 4k @ 30 */ + qcom,allowed-clock-rates = + /* TURBO NOM+ NOM + * SVS+ SVS SVS- + */ + <518400000 441600000 404000000 + 320000000 269330000 133330000>; + + qcom,dcvs-tbl = + /* Dec UHD@30 All decoder - NOM to SVS+ */ + <897600 734400 979200 0x3f00000c>, + + /* Dec DCI@24 HEVC - NOM to SVS+ */ + <816000 734400 829440 0x0c000000>, + + /* Enc UHD@30 H264/HEVC - TURBO to NOM+ */ + <897600 897600 979200 0x4000004>; + qcom,dcvs-limit = + <32400 30>, /* Encoder UHD */ + <32400 24>; /* Decoder UHD */ + + /* Regulators */ + smmu-vdd-supply = <&gdsc_bimc_smmu>; + venus-supply = <&gdsc_venus>; + venus-core0-supply = <&gdsc_venus_core0>; + + /* Clocks */ + clock-names = "gcc_mmss_sys_noc_axi_clk", + "mmssnoc_axi_clk", "mmss_mnoc_ahb_clk", + "mmss_bimc_smmu_ahb_clk", "mmss_bimc_smmu_axi_clk", + "mmss_video_core_clk", "mmss_video_ahb_clk", + "mmss_video_axi_clk", + "mmss_video_core0_clk"; + clocks = <&clock_gcc GCC_MMSS_SYS_NOC_AXI_CLK>, + <&clock_gcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, + <&clock_mmss MMSS_VIDEO_CORE_CLK>, + <&clock_mmss MMSS_VIDEO_AHB_CLK>, + <&clock_mmss MMSS_VIDEO_AXI_CLK>, + <&clock_mmss MMSS_VIDEO_SUBCORE0_CLK>; + qcom,clock-configs = <0x0 0x0 0x0 0x0 0x0 + 0x3 0x0 0x2 0x3>; + + /* Buses */ + bus_cnoc { + compatible = "qcom,msm-vidc,bus"; + label = "cnoc"; + qcom,bus-master = <MSM_BUS_MASTER_AMPSS_M0>; + qcom,bus-slave = <MSM_BUS_SLAVE_VENUS_CFG>; + qcom,bus-governor = "performance"; + qcom,bus-range-kbps = <1 1>; + }; + + venus_bus_ddr { + compatible = "qcom,msm-vidc,bus"; + label = "venus-ddr"; + qcom,bus-master = <MSM_BUS_MASTER_VIDEO_P0>; + qcom,bus-slave = <MSM_BUS_SLAVE_EBI_CH0>; + qcom,bus-governor = "venus-ddr-gov"; + qcom,bus-range-kbps = <1000 2365000>; + }; + + arm9_bus_ddr { + compatible = "qcom,msm-vidc,bus"; + label = "venus-arm9-ddr"; + qcom,bus-master = <MSM_BUS_MASTER_VIDEO_P0>; + qcom,bus-slave = <MSM_BUS_SLAVE_EBI_CH0>; + qcom,bus-governor = "performance"; + qcom,bus-range-kbps = <1 1>; + }; + + qcom,clock-freq-tbl { + qcom,profile-enc { + qcom,codec-mask = <0x55555555>; + qcom,cycles-per-mb = <863>; + qcom,low-power-mode-factor = <35616>; + }; + qcom,profile-dec { + qcom,codec-mask = <0xf3ffffff>; + qcom,cycles-per-mb = <355>; + }; + qcom,profile-hevcdec { + qcom,codec-mask = <0x0c000000>; + qcom,cycles-per-mb = <400>; + }; + }; + + venus-ddr-gov { + compatible = "qcom,msm-vidc,governor,table"; + name = "venus-ddr-gov"; + status = "ok"; + qcom,bus-freq-table { + qcom,profile-enc { + qcom,codec-mask = <0x55555555>; + qcom,load-busfreq-tbl = + <979200 1044000>, /* UHD30E */ + <864000 887000>, /* 720p240LPE */ + <489600 666000>, /* 1080p60E */ + <432000 578000>, /* 720p120E */ + <244800 346000>, /* 1080p30E */ + <216000 293000>, /* 720p60E */ + <108000 151000>, /* 720p30E */ + <0 0>; + }; + qcom,profile-dec { + qcom,codec-mask = <0xffffffff>; + qcom,load-busfreq-tbl = + <979200 2365000>, /* UHD30D */ + <864000 1978000>, /* 720p240D */ + <489600 1133000>, /* 1080p60D */ + <432000 994000>, /* 720p120D */ + <244800 580000>, /* 1080p30D */ + <216000 501000>, /* 720p60E */ + <108000 255000>, /* 720p30D */ + <0 0>; + }; + qcom,profile-dec-ubwc { + qcom,codec-mask = <0xffffffff>; + qcom,ubwc-mode; + qcom,load-busfreq-tbl = + <979200 1892000>, /* UHD30D */ + <864000 1554000>, /* 720p240D */ + <489600 895000>, /* 1080p60D */ + <432000 781000>, /* 720p120D */ + <244800 460000>, /* 1080p30D */ + <216000 301000>, /* 720p60E */ + <108000 202000>, /* 720p30D */ + <0 0>; + }; + qcom,profile-dec-ubwc-10bit { + qcom,codec-mask = <0xffffffff>; + qcom,ubwc-10bit; + qcom,load-busfreq-tbl = + <979200 2446336>, /* UHD30D */ + <864000 2108416>, /* 720p240D */ + <489600 1207296>, /* 1080p60D */ + <432000 1058816>, /* 720p120D */ + <244800 616448>, /* 1080p30D */ + <216000 534528>, /* 720p60D */ + <108000 271360>, /* 720p30D */ + <0 0>; + }; + }; + }; + + + /* MMUs */ + non_secure_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_ns"; + iommus = + <&mmss_bimc_smmu 0x400>, + <&mmss_bimc_smmu 0x401>, + <&mmss_bimc_smmu 0x40a>, + <&mmss_bimc_smmu 0x407>, + <&mmss_bimc_smmu 0x40e>, + <&mmss_bimc_smmu 0x40f>, + <&mmss_bimc_smmu 0x408>, + <&mmss_bimc_smmu 0x409>, + <&mmss_bimc_smmu 0x40b>, + <&mmss_bimc_smmu 0x40c>, + <&mmss_bimc_smmu 0x40d>, + <&mmss_bimc_smmu 0x410>, + <&mmss_bimc_smmu 0x421>, + <&mmss_bimc_smmu 0x428>, + <&mmss_bimc_smmu 0x429>, + <&mmss_bimc_smmu 0x42b>, + <&mmss_bimc_smmu 0x42c>, + <&mmss_bimc_smmu 0x42d>, + <&mmss_bimc_smmu 0x411>, + <&mmss_bimc_smmu 0x431>; + buffer-types = <0xfff>; + virtual-addr-pool = <0x70800000 0x8f800000>; + }; + + firmware_cb { + compatible = "qcom,msm-vidc,context-bank"; + qcom,fw-context-bank; + iommus = <&mmss_bimc_smmu 0x580>, + <&mmss_bimc_smmu 0x586>; + }; + secure_bitstream_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_bitstream"; + iommus = <&mmss_bimc_smmu 0x500>, + <&mmss_bimc_smmu 0x502>, + <&mmss_bimc_smmu 0x509>, + <&mmss_bimc_smmu 0x50a>, + <&mmss_bimc_smmu 0x50b>, + <&mmss_bimc_smmu 0x50e>, + <&mmss_bimc_smmu 0x526>, + <&mmss_bimc_smmu 0x529>, + <&mmss_bimc_smmu 0x52b>; + buffer-types = <0x241>; + virtual-addr-pool = <0x4b000000 0x25800000>; + qcom,secure-context-bank; + }; + + venus_secure_pixel_cb: secure_pixel_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_pixel"; + iommus = <&mmss_bimc_smmu 0x504>, + <&mmss_bimc_smmu 0x50c>, + <&mmss_bimc_smmu 0x510>, + <&mmss_bimc_smmu 0x52c>; + buffer-types = <0x106>; + virtual-addr-pool = <0x25800000 0x25800000>; + qcom,secure-context-bank; + }; + + venus_secure_non_pixel_cb: secure_non_pixel_cb { + compatible = "qcom,msm-vidc,context-bank"; + label = "venus_sec_non_pixel"; + iommus = <&mmss_bimc_smmu 0x505>, + <&mmss_bimc_smmu 0x507>, + <&mmss_bimc_smmu 0x508>, + <&mmss_bimc_smmu 0x50d>, + <&mmss_bimc_smmu 0x50f>, + <&mmss_bimc_smmu 0x525>, + <&mmss_bimc_smmu 0x528>, + <&mmss_bimc_smmu 0x52d>, + <&mmss_bimc_smmu 0x540>; + buffer-types = <0x480>; + virtual-addr-pool = <0x1000000 0x24800000>; + qcom,secure-context-bank; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-wcd.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-wcd.dtsi new file mode 100644 index 000000000000..29f4ccaede9f --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-wcd.dtsi @@ -0,0 +1,183 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&slim_aud { + tasha_codec { + wsa_spkr_sd1: msm_cdc_pinctrll { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-1 = <&spkr_1_sd_n_sleep>; + }; + + wsa_spkr_sd2: msm_cdc_pinctrlr { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_2_sd_n_active>; + pinctrl-1 = <&spkr_2_sd_n_sleep>; + }; + }; + + tavil_codec { + wcd: wcd_pinctrl@5 { + compatible = "qcom,wcd-pinctrl"; + qcom,num-gpios = <5>; + gpio-controller; + #gpio-cells = <2>; + + us_euro_sw_wcd_active: us_euro_sw_wcd_active { + mux { + pins = "gpio1"; + }; + + config { + pins = "gpio1"; + output-high; + }; + }; + + us_euro_sw_wcd_sleep: us_euro_sw_wcd_sleep { + mux { + pins = "gpio1"; + }; + + config { + pins = "gpio1"; + output-low; + }; + }; + + spkr_1_wcd_en_active: spkr_1_wcd_en_active { + mux { + pins = "gpio2"; + }; + + config { + pins = "gpio2"; + output-high; + }; + }; + + spkr_1_wcd_en_sleep: spkr_1_wcd_en_sleep { + mux { + pins = "gpio2"; + }; + + config { + pins = "gpio2"; + input-enable; + }; + }; + + spkr_2_wcd_en_active: spkr_2_sd_n_active { + mux { + pins = "gpio3"; + }; + + config { + pins = "gpio3"; + output-high; + }; + }; + + spkr_2_wcd_en_sleep: spkr_2_sd_n_sleep { + mux { + pins = "gpio3"; + }; + + config { + pins = "gpio3"; + input-enable; + }; + }; + + hph_en0_wcd_active: hph_en0_wcd_active { + mux { + pins = "gpio4"; + }; + + config { + pins = "gpio4"; + output-high; + }; + }; + + hph_en0_wcd_sleep: hph_en0_wcd_sleep { + mux { + pins = "gpio4"; + }; + + config { + pins = "gpio4"; + output-low; + }; + }; + + hph_en1_wcd_active: hph_en1_wcd_active { + mux { + pins = "gpio5"; + }; + + config { + pins = "gpio5"; + output-high; + }; + }; + + hph_en1_wcd_sleep: hph_en1_wcd_sleep { + mux { + pins = "gpio5"; + }; + + config { + pins = "gpio5"; + output-low; + }; + }; + }; + + wsa_spkr_wcd_sd1: msm_cdc_pinctrll { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_1_wcd_en_active>; + pinctrl-1 = <&spkr_1_wcd_en_sleep>; + }; + + wsa_spkr_wcd_sd2: msm_cdc_pinctrlr { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_2_wcd_en_active>; + pinctrl-1 = <&spkr_2_wcd_en_sleep>; + }; + + tavil_us_euro_sw: msm_cdc_pinctrl_us_euro_sw { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&us_euro_sw_wcd_active>; + pinctrl-1 = <&us_euro_sw_wcd_sleep>; + }; + + tavil_hph_en0: msm_cdc_pinctrl_hph_en0 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&hph_en0_wcd_active>; + pinctrl-1 = <&hph_en0_wcd_sleep>; + }; + + tavil_hph_en1: msm_cdc_pinctrl_hph_en1 { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&hph_en1_wcd_active>; + pinctrl-1 = <&hph_en1_wcd_sleep>; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-wsa881x.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-wsa881x.dtsi new file mode 100644 index 000000000000..123f922facdd --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-wsa881x.dtsi @@ -0,0 +1,79 @@ +/* Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msmfalcon-wcd.dtsi" + +&slim_aud { + tasha_codec { + swr_master { + compatible = "qcom,swr-wcd"; + #address-cells = <2>; + #size-cells = <0>; + + wsa881x_211: wsa881x@20170211 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x20170211>; + qcom,spkr-sd-n-node = <&wsa_spkr_sd1>; + }; + + wsa881x_212: wsa881x@20170212 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x20170212>; + qcom,spkr-sd-n-node = <&wsa_spkr_sd2>; + }; + + wsa881x_213: wsa881x@21170213 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x21170213>; + qcom,spkr-sd-n-node = <&wsa_spkr_sd1>; + }; + + wsa881x_214: wsa881x@21170214 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x21170214>; + qcom,spkr-sd-n-node = <&wsa_spkr_sd2>; + }; + }; + }; + + tavil_codec { + swr_master { + compatible = "qcom,swr-wcd"; + #address-cells = <2>; + #size-cells = <0>; + + wsa881x_0211: wsa881x@20170211 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x20170211>; + qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd1>; + }; + + wsa881x_0212: wsa881x@20170212 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x20170212>; + qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd2>; + }; + + wsa881x_0213: wsa881x@21170213 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x21170213>; + qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd1>; + }; + + wsa881x_0214: wsa881x@21170214 { + compatible = "qcom,wsa881x"; + reg = <0x0 0x21170214>; + qcom,spkr-sd-n-node = <&wsa_spkr_wcd_sd2>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index 473270d6e87d..ed8bee03b4d0 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -47,6 +47,7 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; }; CPU1: cpu@1 { @@ -54,6 +55,7 @@ compatible = "arm,armv8"; reg = <0x0 0x1>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; }; CPU2: cpu@2 { @@ -61,6 +63,7 @@ compatible = "arm,armv8"; reg = <0x0 0x2>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; }; CPU3: cpu@3 { @@ -68,6 +71,7 @@ compatible = "arm,armv8"; reg = <0x0 0x3>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; }; CPU4: cpu@100 { @@ -75,6 +79,7 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile1>; }; CPU5: cpu@101 { @@ -82,6 +87,7 @@ compatible = "arm,armv8"; reg = <0x0 0x101>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile2>; }; CPU6: cpu@102 { @@ -89,6 +95,7 @@ compatible = "arm,armv8"; reg = <0x0 0x102>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile3>; }; CPU7: cpu@103 { @@ -96,6 +103,7 @@ compatible = "arm,armv8"; reg = <0x0 0x103>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; }; cpu-map { @@ -249,6 +257,29 @@ clock-frequency = <19200000>; }; + dma_blsp1: qcom,sps-dma@0xc144000{ /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xc144000 0x1F000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <0x10>; + }; + + dma_blsp2: qcom,sps-dma@0xc184000{ /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xc184000 0x1F000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <0x10>; + }; + + restart@10ac000 { + compatible = "qcom,pshold"; + reg = <0x10ac000 0x4>, + <0x1fd3000 0x4>; + reg-names = "pshold-base", "tcsr-boot-misc-detect"; + }; + spmi_bus: qcom,spmi@800f000 { compatible = "qcom,spmi-pmic-arb"; reg = <0x800f000 0x1000>, @@ -335,6 +366,180 @@ clock-names = "core", "iface"; }; + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information-0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + qcom,scaling-factor = <10>; + }; + sensor_information1: qcom,sensor-information-1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + qcom,scaling-factor = <10>; + }; + sensor_information2: qcom,sensor-information-2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,scaling-factor = <10>; + }; + sensor_information3: qcom,sensor-information-3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + qcom,scaling-factor = <10>; + }; + sensor_information4: qcom,sensor-information-4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + qcom,scaling-factor = <10>; + }; + sensor_information5: qcom,sensor-information-5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + qcom,scaling-factor = <10>; + }; + sensor_information6: qcom,sensor-information-6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,scaling-factor = <10>; + }; + sensor_information7: qcom,sensor-information-7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,scaling-factor = <10>; + }; + sensor_information8: qcom,sensor-information-8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,scaling-factor = <10>; + qcom,alias-name = "gpu"; + }; + sensor_information9: qcom,sensor-information-9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,scaling-factor = <10>; + }; + sensor_information10: qcom,sensor-information-10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,scaling-factor = <10>; + }; + sensor_information11: qcom,sensor-information-11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + qcom,scaling-factor = <10>; + }; + sensor_information12: qcom,sensor-information-12 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor12"; + qcom,scaling-factor = <10>; + }; + sensor_information13: qcom,sensor-information-13 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor13"; + qcom,scaling-factor = <10>; + }; + sensor_information14: qcom,sensor-information-14 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pmfalcon_tz"; + qcom,scaling-factor = <1000>; + }; + sensor_information15: qcom,sensor-information-15 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + sensor_information16: qcom,sensor-information-16 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "xo_therm"; + }; + sensor_information17: qcom,sensor-information-17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + sensor_information18: qcom,sensor-information-18 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + sensor_information19: qcom,sensor-information-19 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + sensor_information20: qcom,sensor-information-20 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-00"; + }; + sensor_information21: qcom,sensor-information-21 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-01"; + }; + }; + + mitigation_profile0: qcom,limit_info-0 { + qcom,temperature-sensor = <&sensor_information1>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile1: qcom,limit_info-1 { + qcom,temperature-sensor = <&sensor_information3>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile2: qcom,limit_info-2 { + qcom,temperature-sensor = <&sensor_information4>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile3: qcom,limit_info-3 { + qcom,temperature-sensor = <&sensor_information5>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile4: qcom,limit_info-4 { + qcom,temperature-sensor = <&sensor_information6>; + qcom,hotplug-mitigation-enable; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <1>; + qcom,poll-ms = <100>; + qcom,therm-reset-temp = <115>; + qcom,core-limit-temp = <70>; + qcom,core-temp-hysteresis = <10>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <20>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,synchronous-cluster-map = <0 4 &CPU0 &CPU1 &CPU2 &CPU3>, + <1 4 &CPU4 &CPU5 &CPU6 &CPU7>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm2falcon_s3_floor_level>; + vdd-gfx-supply = <&gfx_vreg_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = <RPM_SMD_REGULATOR_LEVEL_NOM + RPM_SMD_REGULATOR_LEVEL_TURBO + RPM_SMD_REGULATOR_LEVEL_TURBO>; + qcom,min-level = <RPM_SMD_REGULATOR_LEVEL_NONE>; + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 6 6>; /* Nominal, Turbo, Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <1248000>; + qcom,freq-req; + }; + }; + uartblsp2dm1: serial@0c1b0000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xc1b0000 0x1000>; @@ -451,8 +656,21 @@ }; clock_gfx: clock-controller@5065000 { - compatible = "qcom,dummycc"; - clock-output-names = "gfx_clocks"; + compatible = "qcom,gpucc-msmfalcon"; + reg = <0x5065000 0x10000>; + vdd_dig_gfx-supply = <&pm2falcon_s3_level>; + vdd_mx_gfx-supply = <&pm2falcon_s5_level>; + vdd_gfx-supply = <&gfx_vreg_corner>; + qcom,gfxfreq-corner = + < 0 0>, + < 160000000 1>, /* MinSVS */ + < 266000000 2>, /* LowSVS */ + < 370000000 3>, /* SVS */ + < 465000000 4>, /* SVS_L1 */ + < 588000000 5>, /* NOM */ + < 647000000 6>, /* NOM_L1 */ + < 700000000 7>, /* TURBO */ + < 750000000 7>; /* TURBO */ #clock-cells = <1>; #reset-cells = <1>; }; @@ -477,6 +695,72 @@ status = "disabled"; }; + ipa_hw: qcom,ipa@14780000 { + compatible = "qcom,ipa"; + reg = <0x14780000 0x4effc>, <0x14784000 0x26934>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 333 0>, + <0 432 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <6>; /* IPA core version = IPAv2.6L */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; /* IPA WAN-rx-ring-size*/ + qcom,lan-rx-ring-size = <192>; /* IPA LAN-rx-ring-size*/ + clocks = <&clock_rpmcc RPM_IPA_CLK>, + <&clock_rpmcc RPM_AGGR2_NOC_CLK>; + clock-names = "core_clk", "smmu_clk"; + qcom,arm-smmu; + qcom,smmu-disable-htw; + qcom,smmu-s1-bypass; + qcom,ee = <0>; + qcom,use-ipa-tethering-bridge; + qcom,modem-cfg-emb-pipe-flt; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + /* No vote */ + <90 512 0 0>, + <1 676 0 0>, + /* SVS */ + <90 512 80000 640000>, + <1 676 80000 80000>, + /* NOMINAL */ + <90 512 206000 960000>, + <1 676 206000 160000>, + /* TURBO */ + <90 512 206000 960000>, + <1 676 206000 160000>; + qcom,bus-vector-names = "MIN", "SVS", "PERF", "TURBO"; + qcom,rx-polling-sleep-ms = <2>; /* Polling sleep interval */ + qcom,ipa-polling-iteration = <5>; /* Polling Iteration */ + + ipa_smmu_ap: ipa_smmu_ap { + compatible = "qcom,ipa-smmu-ap-cb"; + iommus = <&anoc2_smmu 0x19C0>; + qcom,iova-mapping = <0x10000000 0x40000000>; + }; + + ipa_smmu_wlan: ipa_smmu_wlan { + status = "disabled"; + compatible = "qcom,ipa-smmu-wlan-cb"; + iommus = <&anoc2_smmu 0x19C1>; + }; + + ipa_smmu_uc: ipa_smmu_uc { + compatible = "qcom,ipa-smmu-uc-cb"; + iommus = <&anoc2_smmu 0x19C2>; + qcom,iova-mapping = <0x40000000 0x20000000>; + }; + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + qcom,ipa-advertise-sg-support; + }; + qcom,ipc-spinlock@1f40000 { compatible = "qcom,ipc-spinlock-sfpb"; reg = <0x1f40000 0x8000>; @@ -861,6 +1145,17 @@ status = "ok"; }; + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + qcom,mpm2-sleep-counter@10a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0x10a3000 0x1000>; + clock-frequency = <32768>; + }; + qcom,msm-imem@146bf000 { compatible = "qcom,msm-imem"; reg = <0x146bf000 0x1000>; @@ -868,15 +1163,55 @@ #address-cells = <1>; #size-cells = <1>; + dload_type@18 { + compatible = "qcom,msm-imem-dload-type"; + reg = <0x18 4>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; }; }; + + qcom,ghd { + compatible = "qcom,gladiator-hang-detect"; + qcom,threshold-arr = <0x179d141c 0x179d1420 + 0x179d1424 0x179d1428 + 0x179d142c 0x179d1430>; + qcom,config-reg = <0x179d1434>; + }; + + qcom,msm-gladiator-v2@17900000 { + compatible = "qcom,msm-gladiator-v2"; + reg = <0x17900000 0xe000>; + reg-names = "gladiator_base"; + interrupts = <0 22 0>; + clock-names = "atb_clk"; + clocks = <&clock_rpmcc RPM_QDSS_CLK>; + }; + + cpu_pmu: cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 6 4>; + }; }; #include "msmfalcon-ion.dtsi" #include "msmfalcon-bus.dtsi" +#include "msm-pmfalcon.dtsi" +#include "msm-pm2falcon.dtsi" #include "msm-pmfalcon-rpm-regulator.dtsi" #include "msm-pm2falcon-rpm-regulator.dtsi" #include "msmfalcon-regulator.dtsi" @@ -950,10 +1285,8 @@ }; &gdsc_gpu_gx { - clock-names = "bimc_core_clk", "core_clk", "core_root_clk"; - clocks = <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, - <&clock_gfx GPUCC_GFX3D_CLK>, - <&clock_gfx GFX3D_CLK_SRC>; + clock-names = "core_root_clk"; + clocks = <&clock_gfx GFX3D_CLK_SRC>; qcom,force-enable-root-clk; parent-supply = <&gfx_vreg_corner>; status = "ok"; @@ -963,8 +1296,8 @@ status = "ok"; }; -#include "msm-pmfalcon.dtsi" -#include "msm-pm2falcon.dtsi" #include "msm-arm-smmu-falcon.dtsi" #include "msm-arm-smmu-impl-defs-falcon.dtsi" +#include "msmfalcon-common.dtsi" #include "msmfalcon-blsp.dtsi" +#include "msmfalcon-vidc.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmhamster-cdp.dts b/arch/arm/boot/dts/qcom/msmhamster-cdp.dts index dcb4b0830da3..a9a3e6d9f88a 100644 --- a/arch/arm/boot/dts/qcom/msmhamster-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmhamster-cdp.dts @@ -14,7 +14,7 @@ /dts-v1/; #include "msmhamster.dtsi" -#include "msmcobalt-cdp.dtsi" +#include "msm8998-cdp.dtsi" / { model = "Qualcomm Technologies, Inc. MSM HAMSTER"; diff --git a/arch/arm/boot/dts/qcom/msmhamster-mtp.dts b/arch/arm/boot/dts/qcom/msmhamster-mtp.dts index 72106c97db40..5d63fcb88e8a 100644 --- a/arch/arm/boot/dts/qcom/msmhamster-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmhamster-mtp.dts @@ -14,7 +14,7 @@ /dts-v1/; #include "msmhamster.dtsi" -#include "msmcobalt-mtp.dtsi" +#include "msm8998-mtp.dtsi" / { model = "Qualcomm Technologies, Inc. MSM HAMSTER"; diff --git a/arch/arm/boot/dts/qcom/msmhamster-rumi.dts b/arch/arm/boot/dts/qcom/msmhamster-rumi.dts index ac95d1f6618d..250fe060a9af 100644 --- a/arch/arm/boot/dts/qcom/msmhamster-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmhamster-rumi.dts @@ -15,7 +15,7 @@ /memreserve/ 0x90000000 0x00000100; #include "msmhamster.dtsi" -#include "msmcobalt-rumi.dtsi" +#include "msm8998-rumi.dtsi" / { model = "Qualcomm Technologies, Inc. MSM HAMSTER RUMI"; diff --git a/arch/arm/boot/dts/qcom/msmhamster.dtsi b/arch/arm/boot/dts/qcom/msmhamster.dtsi index 952740ae54e8..30308182e199 100644 --- a/arch/arm/boot/dts/qcom/msmhamster.dtsi +++ b/arch/arm/boot/dts/qcom/msmhamster.dtsi @@ -13,10 +13,10 @@ /* * As a general rule, only version-specific property overrides should be placed * inside this file. Common device definitions should be placed inside the - * msmcobalt.dtsi file. + * msm8998.dtsi file. */ -#include "msmcobalt-v2.dtsi" +#include "msm8998-v2.dtsi" / { model = "Qualcomm Technologies, Inc. MSM HAMSTER"; diff --git a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts index 0317c35d1f44..491b55aab9a6 100644 --- a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts @@ -22,6 +22,37 @@ qcom,board-id = <15 0>; }; +&usb3 { + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + reg = <0x0a928000 0x8000>, + <0x0a8f8800 0x400>, + <0x0a920000 0x100>; + reg-names = "qusb_phy_base", + "qscratch_base", + "emu_phy_base"; + qcom,emulation; + qcom,qusb-phy-init-seq = <0x19 0x1404 + 0x20 0x1414 + 0x79 0x1410 + 0x00 0x1418 + 0x99 0x1404 + 0x04 0x1408 + 0xd9 0x1404>; + qcom,emu-dcm-reset-seq = <0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x5 0x14>; +}; + &uartblsp1dm1 { status = "ok"; pinctrl-names = "default"; @@ -32,3 +63,8 @@ compatible = "qcom,dummycc"; clock-output-names = "gcc_clocks"; }; + +&clock_gfx { + compatible = "qcom,dummycc"; + clock-output-names = "gfx_clocks"; +}; diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 06f296a49113..e7416ebb8f58 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -241,6 +241,13 @@ clock-frequency = <19200000>; }; + restart@10ac000 { + compatible = "qcom,pshold"; + reg = <0x10ac000 0x4>, + <0x1fd3000 0x4>; + reg-names = "pshold-base", "tcsr-boot-misc-detect"; + }; + qcom,sps { compatible = "qcom,msm_sps_4k"; qcom,pipe-attr-ee; @@ -382,8 +389,21 @@ }; clock_gfx: clock-controller@5065000 { - compatible = "qcom,dummycc"; - clock-output-names = "gfx_clocks"; + compatible = "qcom,gpucc-msmfalcon"; + reg = <0x5065000 0x10000>; + vdd_dig_gfx-supply = <&pm2falcon_s3_level>; + vdd_mx_gfx-supply = <&pm2falcon_s5_level>; + vdd_gfx-supply = <&gfx_vreg_corner>; + qcom,gfxfreq-corner = + < 0 0>, + < 160000000 1>, /* MinSVS */ + < 266000000 2>, /* LowSVS */ + < 370000000 3>, /* SVS */ + < 465000000 4>, /* SVS_L1 */ + < 588000000 5>, /* NOM */ + < 647000000 6>, /* NOM_L1 */ + < 700000000 7>, /* TURBO */ + < 750000000 7>; /* TURBO */ #clock-cells = <1>; #reset-cells = <1>; }; @@ -698,6 +718,17 @@ status = "ok"; }; + qcom,msm-rtb { + compatible = "qcom,msm-rtb"; + qcom,rtb-size = <0x100000>; + }; + + qcom,mpm2-sleep-counter@10a3000 { + compatible = "qcom,mpm2-sleep-counter"; + reg = <0x10a3000 0x1000>; + clock-frequency = <32768>; + }; + qcom,msm-imem@146bf000 { compatible = "qcom,msm-imem"; reg = <0x146bf000 0x1000>; @@ -705,16 +736,55 @@ #address-cells = <1>; #size-cells = <1>; + dload_type@18 { + compatible = "qcom,msm-imem-dload-type"; + reg = <0x18 4>; + }; + + restart_reason@65c { + compatible = "qcom,msm-imem-restart_reason"; + reg = <0x65c 4>; + }; + + boot_stats@6b0 { + compatible = "qcom,msm-imem-boot_stats"; + reg = <0x6b0 32>; + }; + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; }; }; + + qcom,ghd { + compatible = "qcom,gladiator-hang-detect"; + qcom,threshold-arr = <0x179d141c 0x179d1420 + 0x179d1424 0x179d1428 + 0x179d142c 0x179d1430>; + qcom,config-reg = <0x179d1434>; + }; + + qcom,msm-gladiator-v2@17900000 { + compatible = "qcom,msm-gladiator-v2"; + reg = <0x17900000 0xe000>; + reg-names = "gladiator_base"; + interrupts = <0 22 0>; + clock-names = "atb_clk"; + clocks = <&clock_rpmcc RPM_QDSS_CLK>; + }; + + cpu_pmu: cpu-pmu { + compatible = "arm,armv8-pmuv3"; + qcom,irq-is-percpu; + interrupts = <1 6 4>; + }; }; #include "msmtriton-ion.dtsi" #include "msmtriton-regulator.dtsi" #include "msm-gdsc-falcon.dtsi" +#include "msmfalcon-common.dtsi" &gdsc_usb30 { clock-names = "core_clk"; @@ -776,10 +846,8 @@ }; &gdsc_gpu_gx { - clock-names = "bimc_core_clk", "core_clk", "core_root_clk"; - clocks = <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, - <&clock_gfx GPUCC_GFX3D_CLK>, - <&clock_gfx GFX3D_CLK_SRC>; + clock-names = "core_root_clk"; + clocks = <&clock_gfx GFX3D_CLK_SRC>; qcom,force-enable-root-clk; parent-supply = <&gfx_vreg_corner>; status = "ok"; diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index f843a98ee130..b55857fd7cc4 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -27,6 +27,7 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -287,7 +288,7 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_PINCTRL_MSMCOBALT=y +CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_MSMFALCON=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y 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 511b9fe32b9b..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_MSMCOBALT=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 @@ -337,6 +371,7 @@ 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 @@ -344,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 @@ -358,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 @@ -366,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 @@ -391,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 @@ -419,9 +465,10 @@ 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_MSM_GPUCC_FALCON=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y @@ -437,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 @@ -463,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 @@ -472,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 @@ -492,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 @@ -508,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 @@ -541,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 @@ -550,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 @@ -570,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/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index cbccbeb483c9..a4fba1af7744 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -2,7 +2,7 @@ if ARCH_QCOM menu "QCOM SoC Type" config ARCH_MSMFALCON - bool "Enable Support for Qualcomm MSMFALCON" + bool "Enable Support for MSMFALCON" select CLKDEV_LOOKUP select HAVE_CLK select HAVE_CLK_PREPARE @@ -40,7 +40,7 @@ config ARCH_MSMFALCON wish to build a kernel that runs on this chipset, say 'N' here. config ARCH_MSMTRITON - bool "Enable Support for Qualcomm MSMTRITON" + bool "Enable Support for MSMTRITON" select CLKDEV_LOOKUP select HAVE_CLK select HAVE_CLK_PREPARE diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 94c0bf30c284..56b7f310ddbc 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -69,12 +69,12 @@ config ARCH_MSM8996 This enables support for the MSM8996 chipset. If you do not wish to build a kernel that runs on this chipset, say 'N' here. -config ARCH_MSMCOBALT - bool "Enable Support for Qualcomm MSMCOBALT" +config ARCH_MSM8998 + bool "Enable Support for Qualcomm MSM8998" depends on ARCH_QCOM select COMMON_CLK_MSM help - This enables support for the MSMCOBALT chipset. If you do not + This enables support for the MSM8998 chipset. If you do not wish to build a kernel that runs on this chipset, say 'N' here. config ARCH_MSMHAMSTER diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 5f8b02904d49..520a60c46106 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -32,6 +32,7 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index c1c0ae9da001..6249b604466b 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -29,6 +29,7 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index df65a3db12f5..23287f8d06ea 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -35,6 +35,7 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -44,7 +45,7 @@ CONFIG_MODULE_SIG_FORCE=y CONFIG_MODULE_SIG_SHA512=y CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_QCOM=y -CONFIG_ARCH_MSMCOBALT=y +CONFIG_ARCH_MSM8998=y CONFIG_ARCH_MSMHAMSTER=y CONFIG_PCI=y CONFIG_PCI_MSM=y @@ -300,7 +301,7 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_PINCTRL_MSMCOBALT=y +CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_MSMFALCON=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -404,7 +405,7 @@ CONFIG_SND=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO_QMI=y CONFIG_SND_SOC=y -CONFIG_SND_SOC_MSMCOBALT=y +CONFIG_SND_SOC_MSM8998=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 2f7dfa9216b1..9cec02c83936 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -34,6 +34,7 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -45,7 +46,7 @@ CONFIG_MODULE_SIG_SHA512=y CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_DEADLINE is not set CONFIG_ARCH_QCOM=y -CONFIG_ARCH_MSMCOBALT=y +CONFIG_ARCH_MSM8998=y CONFIG_ARCH_MSMHAMSTER=y CONFIG_PCI=y CONFIG_PCI_MSM=y @@ -303,7 +304,7 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_PINCTRL_MSMCOBALT=y +CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_MSMFALCON=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -407,7 +408,7 @@ CONFIG_SND=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO_QMI=y CONFIG_SND_SOC=y -CONFIG_SND_SOC_MSMCOBALT=y +CONFIG_SND_SOC_MSM8998=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig index df695f993ed9..1074672d252f 100644 --- a/arch/arm64/configs/msmfalcon-perf_defconfig +++ b/arch/arm64/configs/msmfalcon-perf_defconfig @@ -304,7 +304,7 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_PINCTRL_MSMCOBALT=y +CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_MSMFALCON=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -408,7 +408,7 @@ CONFIG_SND=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO_QMI=y CONFIG_SND_SOC=y -CONFIG_SND_SOC_MSMCOBALT=y +CONFIG_SND_SOC_MSM8998=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y @@ -489,7 +489,7 @@ 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_MSM_GPUCC_FALCON=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig index 8719eb7cb92e..6d8d9eeab2d5 100644 --- a/arch/arm64/configs/msmfalcon_defconfig +++ b/arch/arm64/configs/msmfalcon_defconfig @@ -307,7 +307,6 @@ CONFIG_SPI=y CONFIG_SPI_QUP=y CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y -CONFIG_PINCTRL_MSMCOBALT=y CONFIG_PINCTRL_MSMFALCON=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -411,7 +410,7 @@ CONFIG_SND=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_AUDIO_QMI=y CONFIG_SND_SOC=y -CONFIG_SND_SOC_MSMCOBALT=y +CONFIG_SND_SOC_MSM8998=y CONFIG_UHID=y CONFIG_HID_APPLE=y CONFIG_HID_ELECOM=y @@ -499,7 +498,7 @@ 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_MSM_GPUCC_FALCON=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=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/block/genhd.c b/block/genhd.c index 817c67c9e45e..82bc52cad1c1 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -831,6 +831,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v) if (iter) { class_dev_iter_exit(iter); kfree(iter); + seqf->private = NULL; } } diff --git a/block/ioprio.c b/block/ioprio.c index cc7800e9eb44..01b8116298a1 100644 --- a/block/ioprio.c +++ b/block/ioprio.c @@ -150,8 +150,10 @@ static int get_task_ioprio(struct task_struct *p) if (ret) goto out; ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM); + task_lock(p); if (p->io_context) ret = p->io_context->ioprio; + task_unlock(p); out: return ret; } diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index a5781f6db269..9d0955289796 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -3434,9 +3434,6 @@ static int __init diagchar_init(void) ret = diagfwd_init(); if (ret) goto fail; - ret = diagfwd_bridge_init(); - if (ret) - goto fail; ret = diagfwd_cntl_init(); if (ret) goto fail; @@ -3467,6 +3464,9 @@ static int __init diagchar_init(void) goto fail; pr_debug("diagchar initialized now"); + ret = diagfwd_bridge_init(); + if (ret) + diagfwd_bridge_exit(); return 0; fail: @@ -3482,6 +3482,7 @@ fail: diag_masks_exit(); diag_remote_exit(); return -1; + } static void diagchar_exit(void) 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_glink.c b/drivers/char/diag/diagfwd_glink.c index a2ffabe43c86..ce523ac35a51 100644 --- a/drivers/char/diag/diagfwd_glink.c +++ b/drivers/char/diag/diagfwd_glink.c @@ -455,6 +455,8 @@ static void diag_glink_transport_notify_state(void *handle, const void *priv, "%s received channel remote disconnect for periph:%d\n", glink_info->name, glink_info->peripheral); atomic_set(&glink_info->opened, 0); + diagfwd_channel_close(glink_info->fwd_ctxt); + atomic_set(&glink_info->tx_intent_ready, 0); break; default: DIAG_LOG(DIAG_DEBUG_PERIPHERALS, @@ -501,6 +503,7 @@ static void diag_glink_close_work_fn(struct work_struct *work) glink_close(glink_info->hdl); atomic_set(&glink_info->opened, 0); + atomic_set(&glink_info->tx_intent_ready, 0); glink_info->hdl = NULL; diagfwd_channel_close(glink_info->fwd_ctxt); } diff --git a/drivers/char/diag/diagfwd_mhi.c b/drivers/char/diag/diagfwd_mhi.c index f7b1e98f22b0..df26e2522baf 100644 --- a/drivers/char/diag/diagfwd_mhi.c +++ b/drivers/char/diag/diagfwd_mhi.c @@ -49,6 +49,7 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = { .enabled = 0, .num_read = 0, .mempool = POOL_TYPE_MDM, + .mempool_init = 0, .mhi_wq = NULL, .read_ch = { .chan = MHI_CLIENT_DIAG_IN, @@ -68,6 +69,7 @@ struct diag_mhi_info diag_mhi[NUM_MHI_DEV] = { .enabled = 0, .num_read = 0, .mempool = POOL_TYPE_MDM_DCI, + .mempool_init = 0, .mhi_wq = NULL, .read_ch = { .chan = MHI_CLIENT_DCI_IN, @@ -684,6 +686,7 @@ int diag_mhi_init() strlcpy(wq_name, "diag_mhi_", DIAG_MHI_STRING_SZ); strlcat(wq_name, mhi_info->name, sizeof(mhi_info->name)); diagmem_init(driver, mhi_info->mempool); + mhi_info->mempool_init = 1; mhi_info->mhi_wq = create_singlethread_workqueue(wq_name); if (!mhi_info->mhi_wq) goto fail; @@ -725,7 +728,8 @@ void diag_mhi_exit() if (mhi_info->mhi_wq) destroy_workqueue(mhi_info->mhi_wq); mhi_close(mhi_info->id); - diagmem_exit(driver, mhi_info->mempool); + if (mhi_info->mempool_init) + diagmem_exit(driver, mhi_info->mempool); } } diff --git a/drivers/char/diag/diagfwd_mhi.h b/drivers/char/diag/diagfwd_mhi.h index 8332efdf5efb..a4466977ca97 100644 --- a/drivers/char/diag/diagfwd_mhi.h +++ b/drivers/char/diag/diagfwd_mhi.h @@ -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 @@ -65,6 +65,7 @@ struct diag_mhi_info { int id; int dev_id; int mempool; + int mempool_init; int num_read; uint8_t enabled; char name[DIAG_MHI_NAME_SZ]; diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c index 40fdcbaaf31a..9c9d000c94db 100644 --- a/drivers/char/diag/diagfwd_peripheral.c +++ b/drivers/char/diag/diagfwd_peripheral.c @@ -438,6 +438,7 @@ int diagfwd_peripheral_init(void) fwd_info->read_bytes = 0; fwd_info->write_bytes = 0; spin_lock_init(&fwd_info->buf_lock); + spin_lock_init(&fwd_info->write_buf_lock); mutex_init(&fwd_info->data_mutex); } } @@ -453,6 +454,7 @@ int diagfwd_peripheral_init(void) fwd_info->read_bytes = 0; fwd_info->write_bytes = 0; spin_lock_init(&fwd_info->buf_lock); + spin_lock_init(&fwd_info->write_buf_lock); mutex_init(&fwd_info->data_mutex); /* * This state shouldn't be set for Control channels @@ -686,16 +688,19 @@ void *diagfwd_request_write_buf(struct diagfwd_info *fwd_info) { void *buf = NULL; int index; + unsigned long flags; + spin_lock_irqsave(&fwd_info->write_buf_lock, flags); for (index = 0 ; index < NUM_WRITE_BUFFERS; index++) { if (!atomic_read(&(fwd_info->buf_ptr[index]->in_busy))) { + atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1); buf = fwd_info->buf_ptr[index]->data; if (!buf) return NULL; - atomic_set(&(fwd_info->buf_ptr[index]->in_busy), 1); break; } } + spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags); return buf; } @@ -760,7 +765,6 @@ int diagfwd_write(uint8_t peripheral, uint8_t type, void *buf, int len) static void __diag_fwd_open(struct diagfwd_info *fwd_info) { - int i; if (!fwd_info) return; @@ -775,10 +779,7 @@ static void __diag_fwd_open(struct diagfwd_info *fwd_info) if (fwd_info->p_ops && fwd_info->p_ops->open) fwd_info->p_ops->open(fwd_info->ctxt); - for (i = 0; i < NUM_WRITE_BUFFERS; i++) { - if (fwd_info->buf_ptr[i]) - atomic_set(&fwd_info->buf_ptr[i]->in_busy, 0); - } + diagfwd_queue_read(fwd_info); } @@ -839,6 +840,7 @@ void diagfwd_close(uint8_t peripheral, uint8_t type) int diagfwd_channel_open(struct diagfwd_info *fwd_info) { + int i; if (!fwd_info) return -EIO; @@ -859,6 +861,10 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info) diagfwd_write_buffers_init(fwd_info); if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->open) fwd_info->c_ops->open(fwd_info); + for (i = 0; i < NUM_WRITE_BUFFERS; i++) { + if (fwd_info->buf_ptr[i]) + atomic_set(&fwd_info->buf_ptr[i]->in_busy, 0); + } diagfwd_queue_read(fwd_info); DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d considered opened\n", fwd_info->peripheral, fwd_info->type); @@ -873,6 +879,7 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info) int diagfwd_channel_close(struct diagfwd_info *fwd_info) { + int i; if (!fwd_info) return -EIO; @@ -885,6 +892,10 @@ int diagfwd_channel_close(struct diagfwd_info *fwd_info) if (fwd_info->buf_2 && fwd_info->buf_2->data) atomic_set(&fwd_info->buf_2->in_busy, 0); + for (i = 0; i < NUM_WRITE_BUFFERS; i++) { + if (fwd_info->buf_ptr[i]) + atomic_set(&fwd_info->buf_ptr[i]->in_busy, 1); + } DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d considered closed\n", fwd_info->peripheral, fwd_info->type); @@ -940,10 +951,11 @@ int diagfwd_write_buffer_done(struct diagfwd_info *fwd_info, const void *ptr) int found = 0; int index = 0; + unsigned long flags; if (!fwd_info || !ptr) return found; - + spin_lock_irqsave(&fwd_info->write_buf_lock, flags); for (index = 0; index < NUM_WRITE_BUFFERS; index++) { if (fwd_info->buf_ptr[index]->data == ptr) { atomic_set(&fwd_info->buf_ptr[index]->in_busy, 0); @@ -951,6 +963,7 @@ int diagfwd_write_buffer_done(struct diagfwd_info *fwd_info, const void *ptr) break; } } + spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags); return found; } @@ -976,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)) { @@ -987,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)) { @@ -999,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); @@ -1197,7 +1214,7 @@ void diagfwd_write_buffers_init(struct diagfwd_info *fwd_info) return; } - spin_lock_irqsave(&fwd_info->buf_lock, flags); + spin_lock_irqsave(&fwd_info->write_buf_lock, flags); for (i = 0; i < NUM_WRITE_BUFFERS; i++) { if (!fwd_info->buf_ptr[i]) fwd_info->buf_ptr[i] = @@ -1215,11 +1232,11 @@ void diagfwd_write_buffers_init(struct diagfwd_info *fwd_info) kmemleak_not_leak(fwd_info->buf_ptr[i]->data); } } - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags); return; err: - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags); pr_err("diag:unable to allocate write buffers\n"); diagfwd_write_buffers_exit(fwd_info); @@ -1233,7 +1250,7 @@ static void diagfwd_write_buffers_exit(struct diagfwd_info *fwd_info) if (!fwd_info) return; - spin_lock_irqsave(&fwd_info->buf_lock, flags); + spin_lock_irqsave(&fwd_info->write_buf_lock, flags); for (i = 0; i < NUM_WRITE_BUFFERS; i++) { if (fwd_info->buf_ptr[i]) { kfree(fwd_info->buf_ptr[i]->data); @@ -1242,5 +1259,5 @@ static void diagfwd_write_buffers_exit(struct diagfwd_info *fwd_info) fwd_info->buf_ptr[i] = NULL; } } - spin_unlock_irqrestore(&fwd_info->buf_lock, flags); + spin_unlock_irqrestore(&fwd_info->write_buf_lock, flags); } diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h index b511bf495bc2..cbbab86a9425 100644 --- a/drivers/char/diag/diagfwd_peripheral.h +++ b/drivers/char/diag/diagfwd_peripheral.h @@ -71,6 +71,7 @@ struct diagfwd_info { unsigned long read_bytes; unsigned long write_bytes; spinlock_t buf_lock; + spinlock_t write_buf_lock; struct mutex data_mutex; void *ctxt; struct diagfwd_buf_t *buf_1; 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 1eb6e32e0d51..b42b68482279 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; @@ -2267,6 +2273,7 @@ EXPORT_SYMBOL_GPL(clk_set_flags); static struct dentry *rootdir; static int inited = 0; +static u32 debug_suspend; static DEFINE_MUTEX(clk_debug_lock); static HLIST_HEAD(clk_debug_list); @@ -2409,6 +2416,309 @@ static const struct file_operations clk_dump_fops = { .release = single_release, }; +static int clock_debug_rate_set(void *data, u64 val) +{ + struct clk_core *core = data; + int ret; + + ret = clk_set_rate(core->hw->clk, val); + if (ret) + pr_err("clk_set_rate(%lu) failed (%d)\n", + (unsigned long)val, ret); + + return ret; +} + +static int clock_debug_rate_get(void *data, u64 *val) +{ + struct clk_core *core = data; + + *val = core->hw->core->rate; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get, + clock_debug_rate_set, "%llu\n"); + +static ssize_t clock_parent_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char name[256] = {0}; + struct clk_core *core = filp->private_data; + struct clk_core *p = core->hw->core->parent; + + snprintf(name, sizeof(name), "%s\n", p ? p->name : "None\n"); + + return simple_read_from_buffer(ubuf, cnt, ppos, name, strlen(name)); +} + +static const struct file_operations clock_parent_fops = { + .open = simple_open, + .read = clock_parent_read, +}; + +static int clock_debug_enable_set(void *data, u64 val) +{ + struct clk_core *core = data; + int rc = 0; + + if (val) + rc = clk_prepare_enable(core->hw->clk); + else + clk_disable_unprepare(core->hw->clk); + + return rc; +} + +static int clock_debug_enable_get(void *data, u64 *val) +{ + struct clk_core *core = data; + int enabled = 0; + + enabled = core->enable_count; + + *val = enabled; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get, + clock_debug_enable_set, "%lld\n"); + +#define clock_debug_output(m, c, fmt, ...) \ +do { \ + if (m) \ + seq_printf(m, fmt, ##__VA_ARGS__); \ + else if (c) \ + pr_cont(fmt, ##__VA_ARGS__); \ + else \ + pr_info(fmt, ##__VA_ARGS__); \ +} while (0) + +int clock_debug_print_clock(struct clk_core *c, struct seq_file *s) +{ + char *start = ""; + struct clk *clk; + + if (!c || !c->prepare_count) + return 0; + + clk = c->hw->clk; + + clock_debug_output(s, 0, "\t"); + + do { + if (clk->core->vdd_class) + clock_debug_output(s, 1, "%s%s:%u:%u [%ld, %d]", start, + clk->core->name, + clk->core->prepare_count, + clk->core->enable_count, + clk->core->rate, + clk_find_vdd_level(clk->core, clk->core->rate)); + else + clock_debug_output(s, 1, "%s%s:%u:%u [%ld]", start, + clk->core->name, + clk->core->prepare_count, + clk->core->enable_count, + clk->core->rate); + start = " -> "; + } while ((clk = clk_get_parent(clk))); + + clock_debug_output(s, 1, "\n"); + + return 1; +} + +/* + * clock_debug_print_enabled_clocks() - Print names of enabled clocks + */ +static void clock_debug_print_enabled_clocks(struct seq_file *s) +{ + struct clk_core *core; + int cnt = 0; + + clock_debug_output(s, 0, "Enabled clocks:\n"); + + mutex_lock(&clk_debug_lock); + + hlist_for_each_entry(core, &clk_debug_list, debug_node) + cnt += clock_debug_print_clock(core, s); + + mutex_unlock(&clk_debug_lock); + + if (cnt) + clock_debug_output(s, 0, "Enabled clock count: %d\n", cnt); + else + clock_debug_output(s, 0, "No clocks enabled.\n"); +} + +static int enabled_clocks_show(struct seq_file *s, void *unused) +{ + clock_debug_print_enabled_clocks(s); + + return 0; +} + +static int enabled_clocks_open(struct inode *inode, struct file *file) +{ + return single_open(file, enabled_clocks_show, inode->i_private); +} + +static const struct file_operations clk_enabled_list_fops = { + .open = enabled_clocks_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f) +{ + if (IS_ERR_OR_NULL(clk)) + return; + + clk_debug_print_hw(clk->parent, f); + + clock_debug_output(f, false, "%s\n", clk->name); + + if (!clk->ops->list_registers) + return; + + clk->ops->list_registers(f, clk->hw); +} + +static int print_hw_show(struct seq_file *m, void *unused) +{ + struct clk_core *c = m->private; + + clk_debug_print_hw(c, m); + + return 0; +} + +static int print_hw_open(struct inode *inode, struct file *file) +{ + return single_open(file, print_hw_show, inode->i_private); +} + +static const struct file_operations clock_print_hw_fops = { + .open = print_hw_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int list_rates_show(struct seq_file *s, void *unused) +{ + struct clk_core *core = s->private; + int level = 0, i = 0; + unsigned long rate, rate_max = 0; + + /* Find max frequency supported within voltage constraints. */ + if (!core->vdd_class) { + rate_max = ULONG_MAX; + } else { + for (level = 0; level < core->num_rate_max; level++) + if (core->rate_max[level]) + rate_max = core->rate_max[level]; + } + + /* + * List supported frequencies <= rate_max. Higher frequencies may + * appear in the frequency table, but are not valid and should not + * be listed. + */ + while (!IS_ERR_VALUE(rate = + core->ops->list_rate(core->hw, i++, rate_max))) { + if (rate <= 0) + break; + if (rate <= rate_max) + seq_printf(s, "%lu\n", rate); + } + + return 0; +} + +static int list_rates_open(struct inode *inode, struct file *file) +{ + return single_open(file, list_rates_show, inode->i_private); +} + +static const struct file_operations list_rates_fops = { + .open = list_rates_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void clock_print_rate_max_by_level(struct seq_file *s, int level) +{ + struct clk_core *core = s->private; + struct clk_vdd_class *vdd_class = core->vdd_class; + int off, i, vdd_level, nregs = vdd_class->num_regulators; + + vdd_level = clk_find_vdd_level(core, core->rate); + + seq_printf(s, "%2s%10lu", vdd_level == level ? "[" : "", + core->rate_max[level]); + + for (i = 0; i < nregs; i++) { + off = nregs*level + i; + if (vdd_class->vdd_uv) + seq_printf(s, "%10u", vdd_class->vdd_uv[off]); + } + + if (vdd_level == level) + seq_puts(s, "]"); + + seq_puts(s, "\n"); +} + +static int rate_max_show(struct seq_file *s, void *unused) +{ + struct clk_core *core = s->private; + struct clk_vdd_class *vdd_class = core->vdd_class; + int level = 0, i, nregs = vdd_class->num_regulators; + char reg_name[10]; + + int vdd_level = clk_find_vdd_level(core, core->rate); + + if (vdd_level < 0) { + seq_printf(s, "could not find_vdd_level for %s, %ld\n", + core->name, core->rate); + return 0; + } + + seq_printf(s, "%12s", ""); + for (i = 0; i < nregs; i++) { + snprintf(reg_name, ARRAY_SIZE(reg_name), "reg %d", i); + seq_printf(s, "%10s", reg_name); + } + + seq_printf(s, "\n%12s", "freq"); + for (i = 0; i < nregs; i++) + seq_printf(s, "%10s", "uV"); + + seq_puts(s, "\n"); + + for (level = 0; level < core->num_rate_max; level++) + clock_print_rate_max_by_level(s, level); + + return 0; +} + +static int rate_max_open(struct inode *inode, struct file *file) +{ + return single_open(file, rate_max_show, inode->i_private); +} + +static const struct file_operations rate_max_fops = { + .open = rate_max_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) { struct dentry *d; @@ -2425,11 +2735,21 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) core->dentry = d; - d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry, - (u32 *)&core->rate); + d = debugfs_create_file("clk_rate", S_IRUGO, core->dentry, core, + &clock_rate_fops); if (!d) goto err_out; + if (core->ops->list_rate) { + if (!debugfs_create_file("clk_list_rates", + S_IRUGO, core->dentry, core, &list_rates_fops)) + goto err_out; + } + + if (core->vdd_class && !debugfs_create_file("clk_rate_max", + S_IRUGO, core->dentry, core, &rate_max_fops)) + goto err_out; + d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry, (u32 *)&core->accuracy); if (!d) @@ -2450,8 +2770,8 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) if (!d) goto err_out; - d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry, - (u32 *)&core->enable_count); + d = debugfs_create_file("clk_enable_count", S_IRUGO, core->dentry, + core, &clock_enable_fops); if (!d) goto err_out; @@ -2460,6 +2780,16 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) if (!d) goto err_out; + d = debugfs_create_file("clk_parent", S_IRUGO, core->dentry, core, + &clock_parent_fops); + if (!d) + goto err_out; + + d = debugfs_create_file("clk_print_regs", S_IRUGO, core->dentry, + core, &clock_print_hw_fops); + if (!d) + goto err_out; + if (core->ops->debug_init) { ret = core->ops->debug_init(core->hw, core->dentry); if (ret) @@ -2531,6 +2861,19 @@ struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode, } EXPORT_SYMBOL_GPL(clk_debugfs_add_file); +/* + * Print the names of all enabled clocks and their parents if + * debug_suspend is set from debugfs. + */ +void clock_debug_print_enabled(void) +{ + if (likely(!debug_suspend)) + return; + + clock_debug_print_enabled_clocks(NULL); +} +EXPORT_SYMBOL_GPL(clock_debug_print_enabled); + /** * clk_debug_init - lazily populate the debugfs clk directory * @@ -2570,6 +2913,17 @@ static int __init clk_debug_init(void) if (!d) return -ENOMEM; + d = debugfs_create_file("clk_enabled_list", S_IRUGO, rootdir, + &clk_debug_list, &clk_enabled_list_fops); + if (!d) + return -ENOMEM; + + + d = debugfs_create_u32("debug_suspend", S_IRUGO | S_IWUSR, + rootdir, &debug_suspend); + if (!d) + return -ENOMEM; + mutex_lock(&clk_debug_lock); hlist_for_each_entry(core, &clk_debug_list, debug_node) clk_debug_create_one(core, rootdir); @@ -2773,6 +3127,11 @@ 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) { + clk_core_prepare(core); + clk_core_enable(core); + } + kref_init(&core->ref); out: clk_prepare_unlock(); diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 97941b0f8f32..179b27c08022 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -20,6 +20,10 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id); void __clk_free_clk(struct clk *clk); + +/* Debugfs API to print the enabled clocks */ +void clock_debug_print_enabled(void); + #else /* All these casts to avoid ifdefs in clkdev... */ static inline struct clk * diff --git a/drivers/clk/msm/Kconfig b/drivers/clk/msm/Kconfig index 650a23ea1ead..bfb697347ec5 100644 --- a/drivers/clk/msm/Kconfig +++ b/drivers/clk/msm/Kconfig @@ -7,7 +7,7 @@ config COMMON_CLK_MSM This support clock controller used by MSM devices which support global, mmss and gpu clock controller. Say Y if you want to support the clocks exposed by the MSM on - platforms such as msm8996, msmcobalt, msmfalcon etc. + platforms such as msm8996, msm8998, msmfalcon etc. config MSM_CLK_CONTROLLER_V2 bool "QTI clock driver" diff --git a/drivers/clk/msm/Makefile b/drivers/clk/msm/Makefile index baf22bf1df9a..27e07eb12205 100644 --- a/drivers/clk/msm/Makefile +++ b/drivers/clk/msm/Makefile @@ -19,12 +19,12 @@ ifeq ($(CONFIG_COMMON_CLK_MSM), y) obj-$(CONFIG_ARCH_MSM8996) += clock-cpu-8996.o endif -# MSM COBALT +# MSM 8998 ifeq ($(CONFIG_COMMON_CLK_MSM), y) - obj-$(CONFIG_ARCH_MSMCOBALT) += clock-gcc-cobalt.o - obj-$(CONFIG_ARCH_MSMCOBALT) += clock-gpu-cobalt.o - obj-$(CONFIG_ARCH_MSMCOBALT) += clock-mmss-cobalt.o - obj-$(CONFIG_ARCH_MSMCOBALT) += clock-osm.o + obj-$(CONFIG_ARCH_MSM8998) += clock-gcc-8998.o + obj-$(CONFIG_ARCH_MSM8998) += clock-gpu-8998.o + obj-$(CONFIG_ARCH_MSM8998) += clock-mmss-8998.o + obj-$(CONFIG_ARCH_MSM8998) += clock-osm.o endif obj-$(CONFIG_COMMON_CLK_MSM) += gdsc.o diff --git a/drivers/clk/msm/clock-gcc-cobalt.c b/drivers/clk/msm/clock-gcc-8998.c index f2a3f7402f67..b1d767a4cb6f 100644 --- a/drivers/clk/msm/clock-gcc-cobalt.c +++ b/drivers/clk/msm/clock-gcc-8998.c @@ -28,10 +28,10 @@ #include <soc/qcom/rpm-smd.h> #include <soc/qcom/clock-rpm.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> -#include <dt-bindings/clock/msm-clocks-hwio-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> +#include <dt-bindings/clock/msm-clocks-hwio-8998.h> -#include "vdd-level-cobalt.h" +#include "vdd-level-8998.h" #include "reset.h" static void __iomem *virt_base; @@ -2444,7 +2444,7 @@ static struct mux_clk gcc_debug_mux = { }, }; -static struct clk_lookup msm_clocks_rpm_cobalt[] = { +static struct clk_lookup msm_clocks_rpm_8998[] = { CLK_LIST(cxo_clk_src), CLK_LIST(bimc_clk), CLK_LIST(bimc_a_clk), @@ -2520,7 +2520,7 @@ static struct clk_lookup msm_clocks_rpm_cobalt[] = { CLK_LIST(gcc_ce1_axi_m_clk), }; -static struct clk_lookup msm_clocks_gcc_cobalt[] = { +static struct clk_lookup msm_clocks_gcc_8998[] = { CLK_LIST(gpll0), CLK_LIST(gpll0_ao), CLK_LIST(gpll0_out_main), @@ -2685,7 +2685,7 @@ static struct clk_lookup msm_clocks_gcc_cobalt[] = { CLK_LIST(gcc_qspi_ref_clk), }; -static const struct msm_reset_map gcc_cobalt_resets[] = { +static const struct msm_reset_map gcc_8998_resets[] = { [QUSB2PHY_PRIM_BCR] = { 0x12000 }, [QUSB2PHY_SEC_BCR] = { 0x12004 }, [BLSP1_BCR] = { 0x17000 }, @@ -2702,7 +2702,7 @@ static const struct msm_reset_map gcc_cobalt_resets[] = { [PCIE_PHY_COM_BCR] = { 0x6f014 }, }; -static void msm_gcc_cobalt_v1_fixup(void) +static void msm_gcc_8998_v1_fixup(void) { gcc_ufs_rx_symbol_1_clk.c.ops = &clk_ops_dummy; qspi_ref_clk_src.c.ops = &clk_ops_dummy; @@ -2710,14 +2710,14 @@ static void msm_gcc_cobalt_v1_fixup(void) gcc_qspi_ahb_clk.c.ops = &clk_ops_dummy; } -static void msm_gcc_cobalt_v2_fixup(void) +static void msm_gcc_8998_v2_fixup(void) { qspi_ref_clk_src.c.ops = &clk_ops_dummy; gcc_qspi_ref_clk.c.ops = &clk_ops_dummy; gcc_qspi_ahb_clk.c.ops = &clk_ops_dummy; } -static int msm_gcc_cobalt_probe(struct platform_device *pdev) +static int msm_gcc_8998_probe(struct platform_device *pdev) { struct resource *res; u32 regval; @@ -2765,8 +2765,8 @@ static int msm_gcc_cobalt_probe(struct platform_device *pdev) } bimc_clk.c.parent = &cxo_clk_src.c; - ret = of_msm_clock_register(pdev->dev.of_node, msm_clocks_rpm_cobalt, - ARRAY_SIZE(msm_clocks_rpm_cobalt)); + ret = of_msm_clock_register(pdev->dev.of_node, msm_clocks_rpm_8998, + ARRAY_SIZE(msm_clocks_rpm_8998)); if (ret) return ret; @@ -2774,17 +2774,17 @@ static int msm_gcc_cobalt_probe(struct platform_device *pdev) if (ret < 0) return ret; - is_v1 = of_device_is_compatible(pdev->dev.of_node, "qcom,gcc-cobalt"); + is_v1 = of_device_is_compatible(pdev->dev.of_node, "qcom,gcc-8998"); if (is_v1) - msm_gcc_cobalt_v1_fixup(); + msm_gcc_8998_v1_fixup(); is_v2 = of_device_is_compatible(pdev->dev.of_node, - "qcom,gcc-cobalt-v2"); + "qcom,gcc-8998-v2"); if (is_v2) - msm_gcc_cobalt_v2_fixup(); + msm_gcc_8998_v2_fixup(); - ret = of_msm_clock_register(pdev->dev.of_node, msm_clocks_gcc_cobalt, - ARRAY_SIZE(msm_clocks_gcc_cobalt)); + ret = of_msm_clock_register(pdev->dev.of_node, msm_clocks_gcc_8998, + ARRAY_SIZE(msm_clocks_gcc_8998)); if (ret) return ret; @@ -2808,37 +2808,37 @@ static int msm_gcc_cobalt_probe(struct platform_device *pdev) clk_set_flags(&gcc_gpu_bimc_gfx_clk.c, CLKFLAG_RETAIN_MEM); /* Register block resets */ - msm_reset_controller_register(pdev, gcc_cobalt_resets, - ARRAY_SIZE(gcc_cobalt_resets), virt_base); + msm_reset_controller_register(pdev, gcc_8998_resets, + ARRAY_SIZE(gcc_8998_resets), virt_base); dev_info(&pdev->dev, "Registered GCC clocks\n"); return 0; } static struct of_device_id msm_clock_gcc_match_table[] = { - { .compatible = "qcom,gcc-cobalt" }, - { .compatible = "qcom,gcc-cobalt-v2" }, + { .compatible = "qcom,gcc-8998" }, + { .compatible = "qcom,gcc-8998-v2" }, { .compatible = "qcom,gcc-hamster" }, {} }; static struct platform_driver msm_clock_gcc_driver = { - .probe = msm_gcc_cobalt_probe, + .probe = msm_gcc_8998_probe, .driver = { - .name = "qcom,gcc-cobalt", + .name = "qcom,gcc-8998", .of_match_table = msm_clock_gcc_match_table, .owner = THIS_MODULE, }, }; -int __init msm_gcc_cobalt_init(void) +int __init msm_gcc_8998_init(void) { return platform_driver_register(&msm_clock_gcc_driver); } -arch_initcall(msm_gcc_cobalt_init); +arch_initcall(msm_gcc_8998_init); /* ======== Clock Debug Controller ======== */ -static struct clk_lookup msm_clocks_measure_cobalt[] = { +static struct clk_lookup msm_clocks_measure_8998[] = { CLK_LIST(gpu_gcc_debug_clk), CLK_LIST(gfx_gcc_debug_clk), CLK_LIST(debug_mmss_clk), @@ -2847,11 +2847,11 @@ static struct clk_lookup msm_clocks_measure_cobalt[] = { }; static struct of_device_id msm_clock_debug_match_table[] = { - { .compatible = "qcom,cc-debug-cobalt" }, + { .compatible = "qcom,cc-debug-8998" }, {} }; -static int msm_clock_debug_cobalt_probe(struct platform_device *pdev) +static int msm_clock_debug_8998_probe(struct platform_device *pdev) { struct resource *res; int ret; @@ -2883,8 +2883,8 @@ static int msm_clock_debug_cobalt_probe(struct platform_device *pdev) debug_cpu_clk.clk_id = "debug_cpu_clk"; ret = of_msm_clock_register(pdev->dev.of_node, - msm_clocks_measure_cobalt, - ARRAY_SIZE(msm_clocks_measure_cobalt)); + msm_clocks_measure_8998, + ARRAY_SIZE(msm_clocks_measure_8998)); if (ret) return ret; @@ -2893,16 +2893,16 @@ static int msm_clock_debug_cobalt_probe(struct platform_device *pdev) } static struct platform_driver msm_clock_debug_driver = { - .probe = msm_clock_debug_cobalt_probe, + .probe = msm_clock_debug_8998_probe, .driver = { - .name = "qcom,cc-debug-cobalt", + .name = "qcom,cc-debug-8998", .of_match_table = msm_clock_debug_match_table, .owner = THIS_MODULE, }, }; -int __init msm_clock_debug_cobalt_init(void) +int __init msm_clock_debug_8998_init(void) { return platform_driver_register(&msm_clock_debug_driver); } -late_initcall(msm_clock_debug_cobalt_init); +late_initcall(msm_clock_debug_8998_init); diff --git a/drivers/clk/msm/clock-gpu-cobalt.c b/drivers/clk/msm/clock-gpu-8998.c index 7cec9be1f42c..e4789a51b738 100644 --- a/drivers/clk/msm/clock-gpu-cobalt.c +++ b/drivers/clk/msm/clock-gpu-8998.c @@ -27,10 +27,10 @@ #include <soc/qcom/clock-pll.h> #include <soc/qcom/clock-alpha-pll.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> -#include <dt-bindings/clock/msm-clocks-hwio-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> +#include <dt-bindings/clock/msm-clocks-hwio-8998.h> -#include "vdd-level-cobalt.h" +#include "vdd-level-8998.h" static void __iomem *virt_base; static void __iomem *virt_base_gfx; @@ -490,7 +490,7 @@ static struct mux_clk gfxcc_dbg_clk = { }, }; -static struct clk_lookup msm_clocks_gpucc_cobalt[] = { +static struct clk_lookup msm_clocks_gpucc_8998[] = { CLK_LIST(gpucc_xo), CLK_LIST(gpucc_gpll0), CLK_LIST(gpucc_cxo_clk), @@ -510,7 +510,7 @@ static void msm_gpucc_hamster_fixup(void) } static struct platform_driver msm_clock_gfxcc_driver; -int msm_gpucc_cobalt_probe(struct platform_device *pdev) +int msm_gpucc_8998_probe(struct platform_device *pdev) { struct resource *res; struct device_node *of_node = pdev->dev.of_node; @@ -563,8 +563,8 @@ int msm_gpucc_cobalt_probe(struct platform_device *pdev) if (is_vq) msm_gpucc_hamster_fixup(); - rc = of_msm_clock_register(of_node, msm_clocks_gpucc_cobalt, - ARRAY_SIZE(msm_clocks_gpucc_cobalt)); + rc = of_msm_clock_register(of_node, msm_clocks_gpucc_8998, + ARRAY_SIZE(msm_clocks_gpucc_8998)); if (rc) return rc; @@ -579,22 +579,22 @@ int msm_gpucc_cobalt_probe(struct platform_device *pdev) } static const struct of_device_id msm_clock_gpucc_match_table[] = { - { .compatible = "qcom,gpucc-cobalt" }, - { .compatible = "qcom,gpucc-cobalt-v2" }, + { .compatible = "qcom,gpucc-8998" }, + { .compatible = "qcom,gpucc-8998-v2" }, { .compatible = "qcom,gpucc-hamster" }, {}, }; static struct platform_driver msm_clock_gpucc_driver = { - .probe = msm_gpucc_cobalt_probe, + .probe = msm_gpucc_8998_probe, .driver = { - .name = "qcom,gpucc-cobalt", + .name = "qcom,gpucc-8998", .of_match_table = msm_clock_gpucc_match_table, .owner = THIS_MODULE, }, }; -static struct clk_lookup msm_clocks_gfxcc_cobalt[] = { +static struct clk_lookup msm_clocks_gfxcc_8998[] = { CLK_LIST(gpu_pll0_pll), CLK_LIST(gpu_pll0_pll_out_even), CLK_LIST(gpu_pll0_pll_out_odd), @@ -610,13 +610,13 @@ static void msm_gfxcc_hamster_fixup(void) gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_vq; } -static void msm_gfxcc_cobalt_v2_fixup(void) +static void msm_gfxcc_8998_v2_fixup(void) { gpu_pll0_pll.c.fmax[VDD_DIG_MIN] = 1420000500; gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_v2; } -int msm_gfxcc_cobalt_probe(struct platform_device *pdev) +int msm_gfxcc_8998_probe(struct platform_device *pdev) { struct resource *res; struct device_node *of_node = pdev->dev.of_node; @@ -675,17 +675,17 @@ int msm_gfxcc_cobalt_probe(struct platform_device *pdev) } is_v2 = of_device_is_compatible(pdev->dev.of_node, - "qcom,gfxcc-cobalt-v2"); + "qcom,gfxcc-8998-v2"); if (is_v2) - msm_gfxcc_cobalt_v2_fixup(); + msm_gfxcc_8998_v2_fixup(); is_vq = of_device_is_compatible(pdev->dev.of_node, "qcom,gfxcc-hamster"); if (is_vq) msm_gfxcc_hamster_fixup(); - rc = of_msm_clock_register(of_node, msm_clocks_gfxcc_cobalt, - ARRAY_SIZE(msm_clocks_gfxcc_cobalt)); + rc = of_msm_clock_register(of_node, msm_clocks_gfxcc_8998, + ARRAY_SIZE(msm_clocks_gfxcc_8998)); if (rc) return rc; @@ -703,23 +703,23 @@ int msm_gfxcc_cobalt_probe(struct platform_device *pdev) } static const struct of_device_id msm_clock_gfxcc_match_table[] = { - { .compatible = "qcom,gfxcc-cobalt" }, - { .compatible = "qcom,gfxcc-cobalt-v2" }, + { .compatible = "qcom,gfxcc-8998" }, + { .compatible = "qcom,gfxcc-8998-v2" }, { .compatible = "qcom,gfxcc-hamster" }, {}, }; static struct platform_driver msm_clock_gfxcc_driver = { - .probe = msm_gfxcc_cobalt_probe, + .probe = msm_gfxcc_8998_probe, .driver = { - .name = "qcom,gfxcc-cobalt", + .name = "qcom,gfxcc-8998", .of_match_table = msm_clock_gfxcc_match_table, .owner = THIS_MODULE, }, }; -int __init msm_gpucc_cobalt_init(void) +int __init msm_gpucc_8998_init(void) { return platform_driver_register(&msm_clock_gpucc_driver); } -arch_initcall(msm_gpucc_cobalt_init); +arch_initcall(msm_gpucc_8998_init); diff --git a/drivers/clk/msm/clock-mmss-cobalt.c b/drivers/clk/msm/clock-mmss-8998.c index 9c1cdf967fb1..2a112aad1fa3 100644 --- a/drivers/clk/msm/clock-mmss-cobalt.c +++ b/drivers/clk/msm/clock-mmss-8998.c @@ -26,10 +26,10 @@ #include <soc/qcom/clock-pll.h> #include <soc/qcom/clock-alpha-pll.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> -#include <dt-bindings/clock/msm-clocks-hwio-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> +#include <dt-bindings/clock/msm-clocks-hwio-8998.h> -#include "vdd-level-cobalt.h" +#include "vdd-level-8998.h" #include "reset.h" static void __iomem *virt_base; @@ -245,6 +245,7 @@ static struct rcg_clk ahb_clk_src = { .c = { .dbg_name = "ahb_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 40000000, NOMINAL, 80800000), CLK_INIT(ahb_clk_src.c), @@ -277,6 +278,7 @@ static struct rcg_clk csi0_clk_src = { .c = { .dbg_name = "csi0_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 164571429, LOW, 256000000, NOMINAL, 384000000, HIGH, 576000000), CLK_INIT(csi0_clk_src.c), @@ -315,6 +317,7 @@ static struct rcg_clk vfe0_clk_src = { .c = { .dbg_name = "vfe0_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 200000000, LOW, 384000000, NOMINAL, 576000000, HIGH, 600000000), CLK_INIT(vfe0_clk_src.c), @@ -330,6 +333,7 @@ static struct rcg_clk vfe1_clk_src = { .c = { .dbg_name = "vfe1_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 200000000, LOW, 384000000, NOMINAL, 576000000, HIGH, 600000000), CLK_INIT(vfe1_clk_src.c), @@ -358,6 +362,7 @@ static struct rcg_clk mdp_clk_src = { .c = { .dbg_name = "mdp_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 171430000, LOW, 275000000, NOMINAL, 330000000, HIGH, 412500000), CLK_INIT(mdp_clk_src.c), @@ -382,6 +387,7 @@ static struct rcg_clk maxi_clk_src = { .c = { .dbg_name = "maxi_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 75000000, LOW, 171428571, NOMINAL, 323200000, HIGH, 406000000), CLK_INIT(maxi_clk_src.c), @@ -416,6 +422,7 @@ static struct rcg_clk cpp_clk_src = { .c = { .dbg_name = "cpp_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 200000000, NOMINAL, 576000000, HIGH, 600000000), CLK_INIT(cpp_clk_src.c), @@ -446,6 +453,7 @@ static struct rcg_clk jpeg0_clk_src = { .c = { .dbg_name = "jpeg0_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 75000000, LOW, 150000000, NOMINAL, 480000000), CLK_INIT(jpeg0_clk_src.c), @@ -469,6 +477,7 @@ static struct rcg_clk rot_clk_src = { .c = { .dbg_name = "rot_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 171430000, LOW, 275000000, NOMINAL, 330000000, HIGH, 412500000), CLK_INIT(rot_clk_src.c), @@ -501,6 +510,7 @@ static struct rcg_clk video_core_clk_src = { .c = { .dbg_name = "video_core_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000, NOMINAL, 360000000, HIGH, 465000000), CLK_INIT(video_core_clk_src.c), @@ -531,6 +541,7 @@ static struct rcg_clk csiphy_clk_src = { .c = { .dbg_name = "csiphy_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 164570000, LOW, 256000000, NOMINAL, 384000000), CLK_INIT(csiphy_clk_src.c), @@ -546,6 +557,7 @@ static struct rcg_clk csi1_clk_src = { .c = { .dbg_name = "csi1_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000, NOMINAL, 384000000, HIGH, 576000000), CLK_INIT(csi1_clk_src.c), @@ -561,6 +573,7 @@ static struct rcg_clk csi2_clk_src = { .c = { .dbg_name = "csi2_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000, NOMINAL, 384000000, HIGH, 576000000), CLK_INIT(csi2_clk_src.c), @@ -576,6 +589,7 @@ static struct rcg_clk csi3_clk_src = { .c = { .dbg_name = "csi3_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 164570000, LOW, 256000000, NOMINAL, 384000000, HIGH, 576000000), CLK_INIT(csi3_clk_src.c), @@ -607,6 +621,7 @@ static struct rcg_clk fd_core_clk_src = { .c = { .dbg_name = "fd_core_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000, NOMINAL, 576000000), CLK_INIT(fd_core_clk_src.c), @@ -755,6 +770,7 @@ static struct rcg_clk video_subcore0_clk_src = { .c = { .dbg_name = "video_subcore0_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000, NOMINAL, 360000000, HIGH, 465000000), CLK_INIT(video_subcore0_clk_src.c), @@ -771,6 +787,7 @@ static struct rcg_clk video_subcore1_clk_src = { .c = { .dbg_name = "video_subcore1_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP4(LOWER, 100000000, LOW, 186000000, NOMINAL, 360000000, HIGH, 465000000), CLK_INIT(video_subcore1_clk_src.c), @@ -793,6 +810,7 @@ static struct rcg_clk cci_clk_src = { .c = { .dbg_name = "cci_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 37500000, LOW, 50000000, NOMINAL, 100000000), CLK_INIT(cci_clk_src.c), @@ -818,6 +836,7 @@ static struct rcg_clk camss_gp0_clk_src = { .c = { .dbg_name = "camss_gp0_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, NOMINAL, 200000000), CLK_INIT(camss_gp0_clk_src.c), @@ -833,6 +852,7 @@ static struct rcg_clk camss_gp1_clk_src = { .c = { .dbg_name = "camss_gp1_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, NOMINAL, 200000000), CLK_INIT(camss_gp1_clk_src.c), @@ -862,6 +882,7 @@ static struct rcg_clk mclk0_clk_src = { .c = { .dbg_name = "mclk0_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667, NOMINAL, 68571429), CLK_INIT(mclk0_clk_src.c), @@ -877,6 +898,7 @@ static struct rcg_clk mclk1_clk_src = { .c = { .dbg_name = "mclk1_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667, NOMINAL, 68571429), CLK_INIT(mclk1_clk_src.c), @@ -892,6 +914,7 @@ static struct rcg_clk mclk2_clk_src = { .c = { .dbg_name = "mclk2_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667, NOMINAL, 68571429), CLK_INIT(mclk2_clk_src.c), @@ -907,6 +930,7 @@ static struct rcg_clk mclk3_clk_src = { .c = { .dbg_name = "mclk3_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 33333333, LOW, 66666667, NOMINAL, 68571429), CLK_INIT(mclk3_clk_src.c), @@ -928,6 +952,7 @@ static struct rcg_clk csi0phytimer_clk_src = { .c = { .dbg_name = "csi0phytimer_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000, NOMINAL, 269333333), CLK_INIT(csi0phytimer_clk_src.c), @@ -943,6 +968,7 @@ static struct rcg_clk csi1phytimer_clk_src = { .c = { .dbg_name = "csi1phytimer_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000, NOMINAL, 269333333), CLK_INIT(csi1phytimer_clk_src.c), @@ -958,6 +984,7 @@ static struct rcg_clk csi2phytimer_clk_src = { .c = { .dbg_name = "csi2phytimer_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 100000000, LOW, 200000000, NOMINAL, 269333333), CLK_INIT(csi2phytimer_clk_src.c), @@ -978,6 +1005,7 @@ static struct rcg_clk dp_gtc_clk_src = { .c = { .dbg_name = "dp_gtc_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 40000000, LOW, 300000000), CLK_INIT(dp_gtc_clk_src.c), }, @@ -997,6 +1025,7 @@ static struct rcg_clk esc0_clk_src = { .c = { .dbg_name = "esc0_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000), CLK_INIT(esc0_clk_src.c), }, @@ -1011,6 +1040,7 @@ static struct rcg_clk esc1_clk_src = { .c = { .dbg_name = "esc1_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000), CLK_INIT(esc1_clk_src.c), }, @@ -1033,6 +1063,7 @@ static struct rcg_clk extpclk_clk_src = { .dbg_name = "extpclk_clk_src", .parent = &ext_extpclk_clk_src.c, .ops = &clk_ops_byte, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 150000000, LOW, 300000000, NOMINAL, 600000000), CLK_INIT(extpclk_clk_src.c), @@ -1053,6 +1084,7 @@ static struct rcg_clk hdmi_clk_src = { .c = { .dbg_name = "hdmi_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000), CLK_INIT(hdmi_clk_src.c), }, @@ -1072,6 +1104,7 @@ static struct rcg_clk vsync_clk_src = { .c = { .dbg_name = "vsync_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000), CLK_INIT(vsync_clk_src.c), }, @@ -1091,6 +1124,7 @@ static struct rcg_clk dp_aux_clk_src = { .c = { .dbg_name = "dp_aux_clk_src", .ops = &clk_ops_rcg, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP2(LOWER, 19200000, NOMINAL, 19200000), CLK_INIT(dp_aux_clk_src.c), }, @@ -1165,6 +1199,7 @@ static struct rcg_clk dp_crypto_clk_src = { .c = { .dbg_name = "dp_crypto_clk_src", .ops = &clk_ops_rcg_mnd, + .flags = CLKFLAG_NO_RATE_CACHE, VDD_DIG_FMAX_MAP3(LOWER, 101250, LOW, 168750, NOMINAL, 337500), CLK_INIT(dp_crypto_clk_src.c), @@ -1237,6 +1272,7 @@ static struct branch_clk mmss_camss_cci_clk = { .c = { .dbg_name = "mmss_camss_cci_clk", .parent = &cci_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_cci_clk.c), }, @@ -1260,6 +1296,7 @@ static struct branch_clk mmss_camss_cpp_clk = { .c = { .dbg_name = "mmss_camss_cpp_clk", .parent = &cpp_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_cpp_clk.c), }, @@ -1317,6 +1354,7 @@ static struct branch_clk mmss_camss_csi0_clk = { .c = { .dbg_name = "mmss_camss_csi0_clk", .parent = &csi0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi0_clk.c), }, @@ -1376,6 +1414,7 @@ static struct branch_clk mmss_camss_csi1_clk = { .c = { .dbg_name = "mmss_camss_csi1_clk", .parent = &csi1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi1_clk.c), }, @@ -1435,6 +1474,7 @@ static struct branch_clk mmss_camss_csi2_clk = { .c = { .dbg_name = "mmss_camss_csi2_clk", .parent = &csi2_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi2_clk.c), }, @@ -1494,6 +1534,7 @@ static struct branch_clk mmss_camss_csi3_clk = { .c = { .dbg_name = "mmss_camss_csi3_clk", .parent = &csi3_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi3_clk.c), }, @@ -1555,6 +1596,7 @@ static struct branch_clk mmss_camss_csiphy0_clk = { .c = { .dbg_name = "mmss_camss_csiphy0_clk", .parent = &csiphy_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csiphy0_clk.c), }, @@ -1568,6 +1610,7 @@ static struct branch_clk mmss_camss_csiphy1_clk = { .c = { .dbg_name = "mmss_camss_csiphy1_clk", .parent = &csiphy_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csiphy1_clk.c), }, @@ -1581,6 +1624,7 @@ static struct branch_clk mmss_camss_csiphy2_clk = { .c = { .dbg_name = "mmss_camss_csiphy2_clk", .parent = &csiphy_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csiphy2_clk.c), }, @@ -1604,6 +1648,7 @@ static struct branch_clk mmss_fd_core_clk = { .c = { .dbg_name = "mmss_fd_core_clk", .parent = &fd_core_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_fd_core_clk.c), }, @@ -1628,6 +1673,7 @@ static struct branch_clk mmss_camss_gp0_clk = { .c = { .dbg_name = "mmss_camss_gp0_clk", .parent = &camss_gp0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_gp0_clk.c), }, @@ -1640,6 +1686,7 @@ static struct branch_clk mmss_camss_gp1_clk = { .c = { .dbg_name = "mmss_camss_gp1_clk", .parent = &camss_gp1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_gp1_clk.c), }, @@ -1663,6 +1710,7 @@ static struct branch_clk mmss_camss_jpeg0_clk = { .c = { .dbg_name = "mmss_camss_jpeg0_clk", .parent = &jpeg0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_jpeg0_clk.c), }, @@ -1701,6 +1749,7 @@ static struct branch_clk mmss_camss_mclk0_clk = { .c = { .dbg_name = "mmss_camss_mclk0_clk", .parent = &mclk0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_mclk0_clk.c), }, @@ -1713,6 +1762,7 @@ static struct branch_clk mmss_camss_mclk1_clk = { .c = { .dbg_name = "mmss_camss_mclk1_clk", .parent = &mclk1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_mclk1_clk.c), }, @@ -1725,6 +1775,7 @@ static struct branch_clk mmss_camss_mclk2_clk = { .c = { .dbg_name = "mmss_camss_mclk2_clk", .parent = &mclk2_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_mclk2_clk.c), }, @@ -1737,6 +1788,7 @@ static struct branch_clk mmss_camss_mclk3_clk = { .c = { .dbg_name = "mmss_camss_mclk3_clk", .parent = &mclk3_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_mclk3_clk.c), }, @@ -1760,6 +1812,7 @@ static struct branch_clk mmss_camss_csi0phytimer_clk = { .c = { .dbg_name = "mmss_camss_csi0phytimer_clk", .parent = &csi0phytimer_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi0phytimer_clk.c), }, @@ -1772,6 +1825,7 @@ static struct branch_clk mmss_camss_csi1phytimer_clk = { .c = { .dbg_name = "mmss_camss_csi1phytimer_clk", .parent = &csi1phytimer_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi1phytimer_clk.c), }, @@ -1784,6 +1838,7 @@ static struct branch_clk mmss_camss_csi2phytimer_clk = { .c = { .dbg_name = "mmss_camss_csi2phytimer_clk", .parent = &csi2phytimer_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_csi2phytimer_clk.c), }, @@ -1818,6 +1873,7 @@ static struct branch_clk mmss_camss_vfe0_clk = { .c = { .dbg_name = "mmss_camss_vfe0_clk", .parent = &vfe0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_vfe0_clk.c), }, @@ -1853,6 +1909,7 @@ static struct branch_clk mmss_camss_vfe1_clk = { .c = { .dbg_name = "mmss_camss_vfe1_clk", .parent = &vfe1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_camss_vfe1_clk.c), }, @@ -1921,6 +1978,7 @@ static struct branch_clk mmss_mdss_byte0_clk = { .c = { .dbg_name = "mmss_mdss_byte0_clk", .parent = &byte0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_byte0_clk.c), }, @@ -1956,6 +2014,7 @@ static struct branch_clk mmss_mdss_byte0_intf_clk = { .c = { .dbg_name = "mmss_mdss_byte0_intf_clk", .parent = &mmss_mdss_byte0_intf_div_clk.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_byte0_intf_clk.c), }, @@ -1968,6 +2027,7 @@ static struct branch_clk mmss_mdss_byte1_clk = { .c = { .dbg_name = "mmss_mdss_byte1_clk", .parent = &byte1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_byte1_clk.c), }, @@ -2003,6 +2063,7 @@ static struct branch_clk mmss_mdss_byte1_intf_clk = { .c = { .dbg_name = "mmss_mdss_byte1_intf_clk", .parent = &mmss_mdss_byte1_intf_div_clk.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_byte1_intf_clk.c), }, @@ -2015,6 +2076,7 @@ static struct branch_clk mmss_mdss_dp_aux_clk = { .c = { .dbg_name = "mmss_mdss_dp_aux_clk", .parent = &dp_aux_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_dp_aux_clk.c), }, @@ -2066,6 +2128,7 @@ static struct branch_clk mmss_mdss_dp_crypto_clk = { .c = { .dbg_name = "mmss_mdss_dp_crypto_clk", .parent = &dp_crypto_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_dp_crypto_clk.c), }, @@ -2078,6 +2141,7 @@ static struct branch_clk mmss_mdss_dp_gtc_clk = { .c = { .dbg_name = "mmss_mdss_dp_gtc_clk", .parent = &dp_gtc_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_dp_gtc_clk.c), }, @@ -2090,6 +2154,7 @@ static struct branch_clk mmss_mdss_esc0_clk = { .c = { .dbg_name = "mmss_mdss_esc0_clk", .parent = &esc0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_esc0_clk.c), }, @@ -2102,6 +2167,7 @@ static struct branch_clk mmss_mdss_esc1_clk = { .c = { .dbg_name = "mmss_mdss_esc1_clk", .parent = &esc1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_esc1_clk.c), }, @@ -2114,6 +2180,7 @@ static struct branch_clk mmss_mdss_extpclk_clk = { .c = { .dbg_name = "mmss_mdss_extpclk_clk", .parent = &extpclk_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_extpclk_clk.c), }, @@ -2126,6 +2193,7 @@ static struct branch_clk mmss_mdss_hdmi_clk = { .c = { .dbg_name = "mmss_mdss_hdmi_clk", .parent = &hdmi_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_hdmi_clk.c), }, @@ -2149,6 +2217,7 @@ static struct branch_clk mmss_mdss_mdp_clk = { .c = { .dbg_name = "mmss_mdss_mdp_clk", .parent = &mdp_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_mdp_clk.c), }, @@ -2175,6 +2244,7 @@ static struct branch_clk mmss_mdss_pclk0_clk = { .c = { .dbg_name = "mmss_mdss_pclk0_clk", .parent = &pclk0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_pclk0_clk.c), }, @@ -2187,6 +2257,7 @@ static struct branch_clk mmss_mdss_pclk1_clk = { .c = { .dbg_name = "mmss_mdss_pclk1_clk", .parent = &pclk1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_pclk1_clk.c), }, @@ -2199,6 +2270,7 @@ static struct branch_clk mmss_mdss_rot_clk = { .c = { .dbg_name = "mmss_mdss_rot_clk", .parent = &rot_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_rot_clk.c), }, @@ -2211,6 +2283,7 @@ static struct branch_clk mmss_mdss_vsync_clk = { .c = { .dbg_name = "mmss_mdss_vsync_clk", .parent = &vsync_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mdss_vsync_clk.c), }, @@ -2225,6 +2298,7 @@ static struct branch_clk mmss_mnoc_ahb_clk = { .c = { .dbg_name = "mmss_mnoc_ahb_clk", .parent = &ahb_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mnoc_ahb_clk.c), }, @@ -2260,6 +2334,7 @@ static struct branch_clk mmss_mnoc_maxi_clk = { .c = { .dbg_name = "mmss_mnoc_maxi_clk", .parent = &maxi_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_mnoc_maxi_clk.c), }, @@ -2272,6 +2347,7 @@ static struct branch_clk mmss_video_subcore0_clk = { .c = { .dbg_name = "mmss_video_subcore0_clk", .parent = &video_subcore0_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_video_subcore0_clk.c), }, @@ -2284,6 +2360,7 @@ static struct branch_clk mmss_video_subcore1_clk = { .c = { .dbg_name = "mmss_video_subcore1_clk", .parent = &video_subcore1_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_video_subcore1_clk.c), }, @@ -2318,6 +2395,7 @@ static struct branch_clk mmss_video_core_clk = { .c = { .dbg_name = "mmss_video_core_clk", .parent = &video_core_clk_src.c, + .flags = CLKFLAG_NO_RATE_CACHE, .ops = &clk_ops_branch, CLK_INIT(mmss_video_core_clk.c), }, @@ -2469,7 +2547,7 @@ static struct mux_clk mmss_debug_mux = { }, }; -static struct clk_lookup msm_clocks_mmss_cobalt[] = { +static struct clk_lookup msm_clocks_mmss_8998[] = { CLK_LIST(mmsscc_xo), CLK_LIST(mmsscc_gpll0), CLK_LIST(mmsscc_gpll0_div), @@ -2640,7 +2718,7 @@ static struct clk_lookup msm_clocks_mmss_cobalt[] = { CLK_LIST(mmss_debug_mux), }; -static const struct msm_reset_map mmss_cobalt_resets[] = { +static const struct msm_reset_map mmss_8998_resets[] = { [CAMSS_MICRO_BCR] = { 0x3490 }, }; @@ -2739,7 +2817,7 @@ static void msm_mmsscc_v2_fixup(void) csi3_clk_src.c.fmax[VDD_DIG_NOMINAL] = 480000000; } -int msm_mmsscc_cobalt_probe(struct platform_device *pdev) +int msm_mmsscc_8998_probe(struct platform_device *pdev) { struct resource *res; int rc; @@ -2822,49 +2900,52 @@ int msm_mmsscc_cobalt_probe(struct platform_device *pdev) ext_dp_phy_pll_vco.clk_id = "dp_vco_div"; ext_dp_phy_pll_vco.c.flags = CLKFLAG_NO_RATE_CACHE; + mmss_camss_jpeg0_vote_clk.c.flags = CLKFLAG_NO_RATE_CACHE; + mmss_camss_jpeg0_dma_vote_clk.c.flags = CLKFLAG_NO_RATE_CACHE; + is_vq = of_device_is_compatible(pdev->dev.of_node, "qcom,mmsscc-hamster"); if (is_vq) msm_mmsscc_hamster_fixup(); is_v2 = of_device_is_compatible(pdev->dev.of_node, - "qcom,mmsscc-cobalt-v2"); + "qcom,mmsscc-8998-v2"); if (is_v2) { msm_mmsscc_hamster_fixup(); msm_mmsscc_v2_fixup(); } - rc = of_msm_clock_register(pdev->dev.of_node, msm_clocks_mmss_cobalt, - ARRAY_SIZE(msm_clocks_mmss_cobalt)); + rc = of_msm_clock_register(pdev->dev.of_node, msm_clocks_mmss_8998, + ARRAY_SIZE(msm_clocks_mmss_8998)); if (rc) return rc; /* Register block resets */ - msm_reset_controller_register(pdev, mmss_cobalt_resets, - ARRAY_SIZE(mmss_cobalt_resets), virt_base); + msm_reset_controller_register(pdev, mmss_8998_resets, + ARRAY_SIZE(mmss_8998_resets), virt_base); dev_info(&pdev->dev, "Registered MMSS clocks.\n"); return 0; } static struct of_device_id msm_clock_mmss_match_table[] = { - { .compatible = "qcom,mmsscc-cobalt" }, - { .compatible = "qcom,mmsscc-cobalt-v2" }, + { .compatible = "qcom,mmsscc-8998" }, + { .compatible = "qcom,mmsscc-8998-v2" }, { .compatible = "qcom,mmsscc-hamster" }, {}, }; static struct platform_driver msm_clock_mmss_driver = { - .probe = msm_mmsscc_cobalt_probe, + .probe = msm_mmsscc_8998_probe, .driver = { - .name = "qcom,mmsscc-cobalt", + .name = "qcom,mmsscc-8998", .of_match_table = msm_clock_mmss_match_table, .owner = THIS_MODULE, }, }; -int __init msm_mmsscc_cobalt_init(void) +int __init msm_mmsscc_8998_init(void) { return platform_driver_register(&msm_clock_mmss_driver); } -arch_initcall(msm_mmsscc_cobalt_init); +arch_initcall(msm_mmsscc_8998_init); diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c index 3e45aee1c0f7..9ce6a1430250 100644 --- a/drivers/clk/msm/clock-osm.c +++ b/drivers/clk/msm/clock-osm.c @@ -40,8 +40,8 @@ #include <soc/qcom/clock-local2.h> #include <soc/qcom/clock-alpha-pll.h> -#include <dt-bindings/clock/msm-clocks-hwio-cobalt.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-hwio-8998.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include "clock.h" @@ -79,13 +79,15 @@ enum clk_osm_trace_packet_id { #define MEM_ACC_SEQ_CONST(n) (n) #define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) #define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) -#define SEQ_REG1_MSMCOBALT_V2 0x1048 +#define SEQ_REG1_MSM8998_V2 0x1048 #define VERSION_REG 0x0 #define VERSION_1P1 0x00010100 #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 @@ -224,10 +226,10 @@ enum clk_osm_trace_packet_id { #define PERFCL_EFUSE_SHIFT 29 #define PERFCL_EFUSE_MASK 0x7 -#define MSMCOBALTV1_PWRCL_BOOT_RATE 1478400000 -#define MSMCOBALTV1_PERFCL_BOOT_RATE 1536000000 -#define MSMCOBALTV2_PWRCL_BOOT_RATE 1555200000 -#define MSMCOBALTV2_PERFCL_BOOT_RATE 1728000000 +#define MSM8998V1_PWRCL_BOOT_RATE 1478400000 +#define MSM8998V1_PERFCL_BOOT_RATE 1536000000 +#define MSM8998V2_PWRCL_BOOT_RATE 1555200000 +#define MSM8998V2_PERFCL_BOOT_RATE 1728000000 /* ACD registers */ #define ACD_HW_VERSION 0x0 @@ -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; @@ -399,8 +403,8 @@ struct clk_osm { bool wdog_trace_en; }; -static bool msmcobalt_v1; -static bool msmcobalt_v2; +static bool msm8998_v1; +static bool msm8998_v2; static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val, u32 offset, u32 mask) @@ -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 */ } @@ -1908,7 +2007,7 @@ static void clk_osm_setup_osm_was(struct clk_osm *c) u32 cc_hyst; u32 val; - if (msmcobalt_v2) + if (msm8998_v2) return; val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); @@ -2191,14 +2290,14 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c) /* Ensure writes complete before returning */ clk_osm_mb(c, OSM_BASE); } else { - if (msmcobalt_v1) { + if (msm8998_v1) { scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1), c->apm_threshold_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73), 0x3b | c->apm_threshold_vc << 6); - } else if (msmcobalt_v2) { + } else if (msm8998_v2) { clk_osm_write_reg(c, c->apm_threshold_vc, - SEQ_REG1_MSMCOBALT_V2); + SEQ_REG1_MSM8998_V2); } scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72), c->apm_crossover_vc); @@ -2992,11 +3091,11 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) }; if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v1")) { - msmcobalt_v1 = true; + "qcom,cpu-clock-osm-msm8998-v1")) { + msm8998_v1 = true; } else if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v2")) { - msmcobalt_v2 = true; + "qcom,cpu-clock-osm-msm8998-v2")) { + msm8998_v2 = true; } rc = clk_osm_resources_init(pdev); @@ -3014,8 +3113,8 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } if ((pwrcl_clk.secure_init || perfcl_clk.secure_init) && - msmcobalt_v2) { - pr_err("unsupported configuration for msmcobalt v2\n"); + msm8998_v2) { + pr_err("unsupported configuration for msm8998 v2\n"); return -EINVAL; } @@ -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); @@ -3230,18 +3330,18 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } /* Set final boot rate */ - rc = clk_set_rate(&pwrcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PWRCL_BOOT_RATE : - MSMCOBALTV2_PWRCL_BOOT_RATE); + rc = clk_set_rate(&pwrcl_clk.c, msm8998_v1 ? + MSM8998V1_PWRCL_BOOT_RATE : + MSM8998V2_PWRCL_BOOT_RATE); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on pwr cluster, rc=%d\n", rc); goto exit2; } - rc = clk_set_rate(&perfcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PERFCL_BOOT_RATE : - MSMCOBALTV2_PERFCL_BOOT_RATE); + rc = clk_set_rate(&perfcl_clk.c, msm8998_v1 ? + MSM8998V1_PERFCL_BOOT_RATE : + MSM8998V2_PERFCL_BOOT_RATE); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on perf cluster, rc=%d\n", rc); @@ -3273,8 +3373,8 @@ exit: } static struct of_device_id match_table[] = { - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v1" }, - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v2" }, + { .compatible = "qcom,cpu-clock-osm-msm8998-v1" }, + { .compatible = "qcom,cpu-clock-osm-msm8998-v2" }, {} }; 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/Makefile b/drivers/clk/msm/mdss/Makefile index 89651e6ebc96..64c7609c15eb 100644 --- a/drivers/clk/msm/mdss/Makefile +++ b/drivers/clk/msm/mdss/Makefile @@ -2,8 +2,8 @@ obj-$(CONFIG_MSM_MDSS_PLL) += mdss-pll-util.o obj-$(CONFIG_MSM_MDSS_PLL) += mdss-pll.o obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-8996.o obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-8996-util.o -obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-cobalt.o -obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dp-pll-cobalt.o -obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dp-pll-cobalt-util.o +obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dsi-pll-8998.o +obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dp-pll-8998.o +obj-$(CONFIG_MSM_MDSS_PLL) += mdss-dp-pll-8998-util.o obj-$(CONFIG_MSM_MDSS_PLL) += mdss-hdmi-pll-8996.o -obj-$(CONFIG_MSM_MDSS_PLL) += mdss-hdmi-pll-cobalt.o +obj-$(CONFIG_MSM_MDSS_PLL) += mdss-hdmi-pll-8998.o diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c index 93bbcf5d40f5..af89610f8c65 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c +++ b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c @@ -22,7 +22,7 @@ #include "mdss-pll.h" #include "mdss-dp-pll.h" -#include "mdss-dp-pll-cobalt.h" +#include "mdss-dp-pll-8998.h" int link2xclk_divsel_set_div(struct div_clk *clk, int div) { diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dp-pll-8998.c index 598a2e8d25de..d5603179b24d 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c +++ b/drivers/clk/msm/mdss/mdss-dp-pll-8998.c @@ -59,11 +59,11 @@ v----------+----------v | divsel_two | | divsel_four | #include <linux/clk/msm-clk-provider.h> #include <linux/clk/msm-clk.h> #include <linux/clk/msm-clock-generic.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include "mdss-pll.h" #include "mdss-dp-pll.h" -#include "mdss-dp-pll-cobalt.h" +#include "mdss-dp-pll-8998.h" static struct clk_ops clk_ops_vco_divided_clk_src_c; static struct clk_ops clk_ops_link_2x_clk_div_c; @@ -79,7 +79,7 @@ static struct clk_div_ops vco_divided_clk_ops = { .get_div = vco_divided_clk_get_div, }; -static struct clk_ops dp_cobalt_vco_clk_ops = { +static struct clk_ops dp_8998_vco_clk_ops = { .set_rate = dp_vco_set_rate, .round_rate = dp_vco_round_rate, .prepare = dp_vco_prepare, @@ -97,7 +97,7 @@ static struct dp_pll_vco_clk dp_vco_clk = { .max_rate = DP_VCO_HSCLK_RATE_5400MHZDIV1000, .c = { .dbg_name = "dp_vco_clk", - .ops = &dp_cobalt_vco_clk_ops, + .ops = &dp_8998_vco_clk_ops, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dp_vco_clk.c), }, @@ -167,7 +167,7 @@ static struct mux_clk vco_divided_clk_src_mux = { } }; -static struct clk_lookup dp_pllcc_cobalt[] = { +static struct clk_lookup dp_pllcc_8998[] = { CLK_LIST(dp_vco_clk), CLK_LIST(dp_link_2x_clk_divsel_five), CLK_LIST(vco_divsel_four_clk_src), @@ -175,7 +175,7 @@ static struct clk_lookup dp_pllcc_cobalt[] = { CLK_LIST(vco_divided_clk_src_mux), }; -int dp_pll_clock_register_cobalt(struct platform_device *pdev, +int dp_pll_clock_register_8998(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { int rc = -ENOTSUPP; @@ -209,10 +209,10 @@ int dp_pll_clock_register_cobalt(struct platform_device *pdev, clk_ops_gen_mux_dp.get_rate = parent_get_rate; /* We can select different clock ops for future versions */ - dp_vco_clk.c.ops = &dp_cobalt_vco_clk_ops; + dp_vco_clk.c.ops = &dp_8998_vco_clk_ops; - rc = of_msm_clock_register(pdev->dev.of_node, dp_pllcc_cobalt, - ARRAY_SIZE(dp_pllcc_cobalt)); + rc = of_msm_clock_register(pdev->dev.of_node, dp_pllcc_8998, + ARRAY_SIZE(dp_pllcc_8998)); if (rc) { DEV_ERR("%s: Clock register failed rc=%d\n", __func__, rc); rc = -EPROBE_DEFER; diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h b/drivers/clk/msm/mdss/mdss-dp-pll-8998.h index 28f21ed1fe0d..2dd78ec1944b 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h +++ b/drivers/clk/msm/mdss/mdss-dp-pll-8998.h @@ -11,8 +11,8 @@ * */ -#ifndef __MDSS_DP_PLL_COBALT_H -#define __MDSS_DP_PLL_COBALT_H +#ifndef __MDSS_DP_PLL_8998_H +#define __MDSS_DP_PLL_8998_H #define DP_PHY_REVISION_ID0 0x0000 #define DP_PHY_REVISION_ID1 0x0004 @@ -177,4 +177,4 @@ int link2xclk_divsel_get_div(struct div_clk *clk); int vco_divided_clk_set_div(struct div_clk *clk, int div); int vco_divided_clk_get_div(struct div_clk *clk); -#endif /* __MDSS_DP_PLL_COBALT_H */ +#endif /* __MDSS_DP_PLL_8998_H */ diff --git a/drivers/clk/msm/mdss/mdss-dp-pll.h b/drivers/clk/msm/mdss/mdss-dp-pll.h index 3abc4c29c17e..f13c76ad6e32 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll.h +++ b/drivers/clk/msm/mdss/mdss-dp-pll.h @@ -28,7 +28,7 @@ static inline struct dp_pll_vco_clk *mdss_dp_to_vco_clk(struct clk *clk) return container_of(clk, struct dp_pll_vco_clk, c); } -int dp_pll_clock_register_cobalt(struct platform_device *pdev, +int dp_pll_clock_register_8998(struct platform_device *pdev, struct mdss_pll_resources *pll_res); diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c index 299934c86d05..a7b4c795591b 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c +++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c @@ -20,7 +20,7 @@ #include <linux/clk/msm-clk-provider.h> #include <linux/clk/msm-clk.h> #include <linux/clk/msm-clock-generic.h> -#include <dt-bindings/clock/msm-clocks-cobalt.h> +#include <dt-bindings/clock/msm-clocks-8998.h> #include "mdss-pll.h" #include "mdss-dsi-pll.h" @@ -128,14 +128,14 @@ struct dsi_pll_config { u32 refclk_cycles; }; -struct dsi_pll_cobalt { +struct dsi_pll_8998 { struct mdss_pll_resources *rsc; struct dsi_pll_config pll_configuration; struct dsi_pll_regs reg_setup; }; static struct mdss_pll_resources *pll_rsc_db[DSI_PLL_MAX]; -static struct dsi_pll_cobalt plls[DSI_PLL_MAX]; +static struct dsi_pll_8998 plls[DSI_PLL_MAX]; static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) { @@ -166,7 +166,7 @@ static void dsi_pll_config_slave(struct mdss_pll_resources *rsc) pr_debug("Slave PLL %s\n", rsc->slave ? "configured" : "absent"); } -static void dsi_pll_setup_config(struct dsi_pll_cobalt *pll, +static void dsi_pll_setup_config(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; @@ -198,7 +198,7 @@ static void dsi_pll_setup_config(struct dsi_pll_cobalt *pll, dsi_pll_config_slave(rsc); } -static void dsi_pll_calc_dec_frac(struct dsi_pll_cobalt *pll, +static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; @@ -278,7 +278,7 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_cobalt *pll, regs->frac_div_start_high = (frac & 0x30000) >> 16; } -static void dsi_pll_calc_ssc(struct dsi_pll_cobalt *pll, +static void dsi_pll_calc_ssc(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { struct dsi_pll_config *config = &pll->pll_configuration; @@ -323,7 +323,7 @@ static void dsi_pll_calc_ssc(struct dsi_pll_cobalt *pll, ssc_per, (u32)ssc_step_size, config->ssc_adj_per); } -static void dsi_pll_ssc_commit(struct dsi_pll_cobalt *pll, +static void dsi_pll_ssc_commit(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { void __iomem *pll_base = rsc->pll_base; @@ -349,7 +349,7 @@ static void dsi_pll_ssc_commit(struct dsi_pll_cobalt *pll, } } -static void dsi_pll_config_hzindep_reg(struct dsi_pll_cobalt *pll, +static void dsi_pll_config_hzindep_reg(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { void __iomem *pll_base = rsc->pll_base; @@ -373,7 +373,7 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_cobalt *pll, MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x80); } -static void dsi_pll_commit(struct dsi_pll_cobalt *pll, +static void dsi_pll_commit(struct dsi_pll_8998 *pll, struct mdss_pll_resources *rsc) { void __iomem *pll_base = rsc->pll_base; @@ -394,12 +394,12 @@ static void dsi_pll_commit(struct dsi_pll_cobalt *pll, } -static int vco_cobalt_set_rate(struct clk *c, unsigned long rate) +static int vco_8998_set_rate(struct clk *c, unsigned long rate) { int rc; struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *rsc = vco->priv; - struct dsi_pll_cobalt *pll; + struct dsi_pll_8998 *pll; if (!rsc) { pr_err("pll resource not found\n"); @@ -447,7 +447,7 @@ static int vco_cobalt_set_rate(struct clk *c, unsigned long rate) return 0; } -static int dsi_pll_cobalt_lock_status(struct mdss_pll_resources *pll) +static int dsi_pll_8998_lock_status(struct mdss_pll_resources *pll) { int rc; u32 status; @@ -519,7 +519,7 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco) wmb(); /* Check for PLL lock */ - rc = dsi_pll_cobalt_lock_status(rsc); + rc = dsi_pll_8998_lock_status(rsc); if (rc) { pr_err("PLL(%d) lock failed\n", rsc->index); goto error; @@ -570,7 +570,7 @@ static void dsi_pll_disable(struct dsi_pll_vco_clk *vco) rsc->pll_on = false; } -static void vco_cobalt_unprepare(struct clk *c) +static void vco_8998_unprepare(struct clk *c) { struct dsi_pll_vco_clk *vco = to_vco_clk(c); struct mdss_pll_resources *pll = vco->priv; @@ -585,7 +585,7 @@ static void vco_cobalt_unprepare(struct clk *c) mdss_pll_resource_enable(pll, false); } -static int vco_cobalt_prepare(struct clk *c) +static int vco_8998_prepare(struct clk *c) { int rc = 0; struct dsi_pll_vco_clk *vco = to_vco_clk(c); @@ -680,7 +680,7 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c) return (unsigned long)vco_rate; } -enum handoff vco_cobalt_handoff(struct clk *c) +enum handoff vco_8998_handoff(struct clk *c) { enum handoff ret = HANDOFF_DISABLED_CLK; int rc; @@ -800,7 +800,7 @@ static int bit_clk_set_div(struct div_clk *clk, int div) { int rc; struct mdss_pll_resources *rsc = clk->priv; - struct dsi_pll_cobalt *pll; + struct dsi_pll_8998 *pll; if (!rsc) { pr_err("pll resource not found\n"); @@ -971,7 +971,7 @@ static int post_bit_clk_set_div(struct div_clk *clk, int div) return rc; } -long vco_cobalt_round_rate(struct clk *c, unsigned long rate) +long vco_8998_round_rate(struct clk *c, unsigned long rate) { unsigned long rrate = rate; struct dsi_pll_vco_clk *vco = to_vco_clk(c); @@ -1011,12 +1011,12 @@ static struct clk_div_ops clk_bitclk_src_ops = { .get_div = bit_clk_get_div, }; -static struct clk_ops clk_ops_vco_cobalt = { - .set_rate = vco_cobalt_set_rate, - .round_rate = vco_cobalt_round_rate, - .handoff = vco_cobalt_handoff, - .prepare = vco_cobalt_prepare, - .unprepare = vco_cobalt_unprepare, +static struct clk_ops clk_ops_vco_8998 = { + .set_rate = vco_8998_set_rate, + .round_rate = vco_8998_round_rate, + .handoff = vco_8998_handoff, + .prepare = vco_8998_prepare, + .unprepare = vco_8998_unprepare, }; static struct clk_mux_ops mdss_mux_ops = { @@ -1079,7 +1079,7 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = { .max_rate = 3500000000UL, .c = { .dbg_name = "dsi0pll_vco_clk", - .ops = &clk_ops_vco_cobalt, + .ops = &clk_ops_vco_8998, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi0pll_vco_clk.c), }, @@ -1248,7 +1248,7 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = { .max_rate = 3500000000UL, .c = { .dbg_name = "dsi1pll_vco_clk", - .ops = &clk_ops_vco_cobalt, + .ops = &clk_ops_vco_8998, .flags = CLKFLAG_NO_RATE_CACHE, CLK_INIT(dsi1pll_vco_clk.c), }, @@ -1411,7 +1411,7 @@ static struct mux_clk dsi1pll_byteclk_mux = { } }; -static struct clk_lookup mdss_dsi_pll0cc_cobalt[] = { +static struct clk_lookup mdss_dsi_pll0cc_8998[] = { CLK_LIST(dsi0pll_byteclk_mux), CLK_LIST(dsi0pll_byteclk_src), CLK_LIST(dsi0pll_pclk_mux), @@ -1424,7 +1424,7 @@ static struct clk_lookup mdss_dsi_pll0cc_cobalt[] = { CLK_LIST(dsi0pll_bitclk_src), CLK_LIST(dsi0pll_vco_clk), }; -static struct clk_lookup mdss_dsi_pll1cc_cobalt[] = { +static struct clk_lookup mdss_dsi_pll1cc_8998[] = { CLK_LIST(dsi1pll_byteclk_mux), CLK_LIST(dsi1pll_byteclk_src), CLK_LIST(dsi1pll_pclk_mux), @@ -1438,7 +1438,7 @@ static struct clk_lookup mdss_dsi_pll1cc_cobalt[] = { CLK_LIST(dsi1pll_vco_clk), }; -int dsi_pll_clock_register_cobalt(struct platform_device *pdev, +int dsi_pll_clock_register_8998(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { int rc = 0, ndx; @@ -1498,8 +1498,8 @@ int dsi_pll_clock_register_cobalt(struct platform_device *pdev, dsi0pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pll0cc_cobalt, - ARRAY_SIZE(mdss_dsi_pll0cc_cobalt)); + mdss_dsi_pll0cc_8998, + ARRAY_SIZE(mdss_dsi_pll0cc_8998)); } else { dsi1pll_byteclk_mux.priv = pll_res; dsi1pll_byteclk_src.priv = pll_res; @@ -1514,8 +1514,8 @@ int dsi_pll_clock_register_cobalt(struct platform_device *pdev, dsi1pll_vco_clk.priv = pll_res; rc = of_msm_clock_register(pdev->dev.of_node, - mdss_dsi_pll1cc_cobalt, - ARRAY_SIZE(mdss_dsi_pll1cc_cobalt)); + mdss_dsi_pll1cc_8998, + ARRAY_SIZE(mdss_dsi_pll1cc_8998)); } if (rc) pr_err("dsi%dpll clock register failed, rc=%d\n", ndx, rc); diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll.h b/drivers/clk/msm/mdss/mdss-dsi-pll.h index f88ae4d0eea1..286c99e339c6 100644 --- a/drivers/clk/msm/mdss/mdss-dsi-pll.h +++ b/drivers/clk/msm/mdss/mdss-dsi-pll.h @@ -58,7 +58,7 @@ int dsi_pll_clock_register_lpm(struct platform_device *pdev, struct mdss_pll_resources *pll_res); int dsi_pll_clock_register_8996(struct platform_device *pdev, struct mdss_pll_resources *pll_res); -int dsi_pll_clock_register_cobalt(struct platform_device *pdev, +int dsi_pll_clock_register_8998(struct platform_device *pdev, struct mdss_pll_resources *pll_res); int set_byte_mux_sel(struct mux_clk *clk, int sel); diff --git a/drivers/clk/msm/mdss/mdss-hdmi-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c index c4f77e01b682..029f779979c7 100644 --- a/drivers/clk/msm/mdss/mdss-hdmi-pll-cobalt.c +++ b/drivers/clk/msm/mdss/mdss-hdmi-pll-8998.c @@ -20,7 +20,8 @@ #include <linux/clk/msm-clk-provider.h> #include <linux/clk/msm-clk.h> #include <linux/clk/msm-clock-generic.h> -#include <dt-bindings/clock/msm-clocks-cobalt.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,15 +79,18 @@ #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 #define HDMI_VCO_MAX_RATE_HZ 600000000 -struct cobalt_reg_cfg { +struct hdmi_8998_reg_cfg { u32 tx_band; u32 svs_mode_clk_sel; u32 hsclk_sel; @@ -109,7 +114,7 @@ struct cobalt_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; @@ -135,24 +140,26 @@ struct cobalt_reg_cfg { bool debug; }; -static void hdmi_cobalt_get_div(struct cobalt_reg_cfg *cfg, unsigned long pclk) +static void hdmi_8998_get_div(struct hdmi_8998_reg_cfg *cfg, unsigned long pclk) { u32 const ratio_list[] = {1, 2, 3, 4, 5, 6, 9, 10, 12, 15, 25}; 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); @@ -270,17 +276,17 @@ find_optimal_index: cfg->tx_band = found_tx_band_sel; } -static int hdmi_cobalt_config_phy(unsigned long rate, - struct cobalt_reg_cfg *cfg) +static int hdmi_8998_config_phy(unsigned long rate, + struct hdmi_8998_reg_cfg *cfg) { u64 const high_freq_bit_clk_threshold = 3400000000UL; u64 const dig_freq_bit_clk_threshold = 1500000000UL; 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; @@ -300,17 +306,17 @@ static int hdmi_cobalt_config_phy(unsigned long rate, tmds_bclk_ratio = 0; } - hdmi_cobalt_get_div(cfg, 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_cobalt_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); @@ -451,15 +457,15 @@ static int hdmi_cobalt_config_phy(unsigned long rate, return rc; } -static int hdmi_cobalt_pll_set_clk_rate(struct clk *c, unsigned long rate) +static int hdmi_8998_pll_set_clk_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; - struct cobalt_reg_cfg cfg = {0}; + struct hdmi_8998_reg_cfg cfg = {0}; void __iomem *phy = io->phy_base, *pll = io->pll_base; - rc = hdmi_cobalt_config_phy(rate, &cfg); + rc = hdmi_8998_config_phy(rate, &cfg); if (rc) { pr_err("rate calculation failed\n, rc=%d", rc); return rc; @@ -548,7 +554,7 @@ static int hdmi_cobalt_pll_set_clk_rate(struct clk *c, unsigned long rate) return 0; } -static int hdmi_cobalt_pll_lock_status(struct mdss_pll_resources *io) +static int hdmi_8998_pll_lock_status(struct mdss_pll_resources *io) { u32 const delay_us = 100; u32 const timeout_us = 5000; @@ -578,7 +584,7 @@ static int hdmi_cobalt_pll_lock_status(struct mdss_pll_resources *io) return rc; } -static int hdmi_cobalt_phy_ready_status(struct mdss_pll_resources *io) +static int hdmi_8998_phy_ready_status(struct mdss_pll_resources *io) { u32 const delay_us = 100; u32 const timeout_us = 5000; @@ -609,50 +615,7 @@ static int hdmi_cobalt_phy_ready_status(struct mdss_pll_resources *io) return rc; } -static int hdmi_cobalt_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_cobalt_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_cobalt_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_cobalt_pll_enable(struct clk *c) +static int hdmi_8998_pll_enable(struct clk *c) { int rc = 0; struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); @@ -669,7 +632,7 @@ static int hdmi_cobalt_pll_enable(struct clk *c) /* Ensure all registers are flushed to hardware */ wmb(); - rc = hdmi_cobalt_pll_lock_status(io); + rc = hdmi_8998_pll_lock_status(io); if (rc) { pr_err("PLL not locked, rc=%d\n", rc); return rc; @@ -683,7 +646,7 @@ static int hdmi_cobalt_pll_enable(struct clk *c) /* Ensure all registers are flushed to hardware */ wmb(); - rc = hdmi_cobalt_phy_ready_status(io); + rc = hdmi_8998_phy_ready_status(io); if (rc) { pr_err("PHY NOT READY, rc=%d\n", rc); return rc; @@ -700,7 +663,152 @@ static int hdmi_cobalt_pll_enable(struct clk *c) return rc; } -static int hdmi_cobalt_vco_prepare(struct clk *c) +/* + * 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); struct mdss_pll_resources *io = vco->priv; @@ -718,14 +826,14 @@ static int hdmi_cobalt_vco_prepare(struct clk *c) } if (!vco->rate_set && vco->rate) { - rc = hdmi_cobalt_pll_set_clk_rate(c, vco->rate); + rc = hdmi_8998_pll_set_clk_rate(c, vco->rate); if (rc) { pr_err("set rate failed, rc=%d\n", rc); goto error; } } - rc = hdmi_cobalt_pll_enable(c); + rc = hdmi_8998_pll_enable(c); if (rc) pr_err("pll enabled failed, rc=%d\n", rc); @@ -736,7 +844,7 @@ error: return rc; } -static void hdmi_cobalt_pll_disable(struct hdmi_pll_vco_clk *vco) +static void hdmi_8998_pll_disable(struct hdmi_pll_vco_clk *vco) { struct mdss_pll_resources *io = vco->priv; void __iomem *phy = io->phy_base; @@ -754,7 +862,7 @@ static void hdmi_cobalt_pll_disable(struct hdmi_pll_vco_clk *vco) io->pll_on = false; } -static void hdmi_cobalt_vco_unprepare(struct clk *c) +static void hdmi_8998_vco_unprepare(struct clk *c) { struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); struct mdss_pll_resources *io = vco->priv; @@ -764,11 +872,11 @@ static void hdmi_cobalt_vco_unprepare(struct clk *c) return; } - hdmi_cobalt_pll_disable(vco); + hdmi_8998_pll_disable(vco); mdss_pll_resource_enable(io, false); } -static enum handoff hdmi_cobalt_vco_handoff(struct clk *c) +static enum handoff hdmi_8998_vco_handoff(struct clk *c) { enum handoff ret = HANDOFF_DISABLED_CLK; struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c); @@ -796,29 +904,29 @@ static enum handoff hdmi_cobalt_vco_handoff(struct clk *c) return ret; } -static struct clk_ops hdmi_cobalt_vco_clk_ops = { - .set_rate = hdmi_cobalt_vco_set_rate, - .round_rate = hdmi_cobalt_vco_round_rate, - .prepare = hdmi_cobalt_vco_prepare, - .unprepare = hdmi_cobalt_vco_unprepare, - .handoff = hdmi_cobalt_vco_handoff, +static struct clk_ops hdmi_8998_vco_clk_ops = { + .set_rate = hdmi_8998_vco_set_rate, + .round_rate = hdmi_8998_vco_round_rate, + .prepare = hdmi_8998_vco_prepare, + .unprepare = hdmi_8998_vco_unprepare, + .handoff = hdmi_8998_vco_handoff, }; static struct hdmi_pll_vco_clk hdmi_vco_clk = { .min_rate = HDMI_VCO_MIN_RATE_HZ, .max_rate = HDMI_VCO_MAX_RATE_HZ, .c = { - .dbg_name = "hdmi_cobalt_vco_clk", - .ops = &hdmi_cobalt_vco_clk_ops, + .dbg_name = "hdmi_8998_vco_clk", + .ops = &hdmi_8998_vco_clk_ops, CLK_INIT(hdmi_vco_clk.c), }, }; -static struct clk_lookup hdmipllcc_cobalt[] = { +static struct clk_lookup hdmipllcc_8998[] = { CLK_LIST(hdmi_vco_clk), }; -int hdmi_cobalt_pll_clock_register(struct platform_device *pdev, +int hdmi_8998_pll_clock_register(struct platform_device *pdev, struct mdss_pll_resources *pll_res) { int rc = 0; @@ -830,8 +938,8 @@ int hdmi_cobalt_pll_clock_register(struct platform_device *pdev, hdmi_vco_clk.priv = pll_res; - rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_cobalt, - ARRAY_SIZE(hdmipllcc_cobalt)); + rc = of_msm_clock_register(pdev->dev.of_node, hdmipllcc_8998, + ARRAY_SIZE(hdmipllcc_8998)); if (rc) { pr_err("clock register failed, rc=%d\n", rc); return rc; diff --git a/drivers/clk/msm/mdss/mdss-hdmi-pll.h b/drivers/clk/msm/mdss/mdss-hdmi-pll.h index d4226bf43e13..19f9b925644a 100644 --- a/drivers/clk/msm/mdss/mdss-hdmi-pll.h +++ b/drivers/clk/msm/mdss/mdss-hdmi-pll.h @@ -56,6 +56,6 @@ int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev, int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev, struct mdss_pll_resources *pll_res); -int hdmi_cobalt_pll_clock_register(struct platform_device *pdev, +int hdmi_8998_pll_clock_register(struct platform_device *pdev, struct mdss_pll_resources *pll_res); #endif diff --git a/drivers/clk/msm/mdss/mdss-pll.c b/drivers/clk/msm/mdss/mdss-pll.c index 4633c7d0e245..01ce2b1817f2 100644 --- a/drivers/clk/msm/mdss/mdss-pll.c +++ b/drivers/clk/msm/mdss/mdss-pll.c @@ -135,10 +135,10 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, pll_res->pll_interface_type = MDSS_DSI_PLL_8996; pll_res->target_id = MDSS_PLL_TARGET_8996; pll_res->revision = 2; - } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_DSI_PLL_COBALT; - } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_DP_PLL_COBALT; + } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_8998")) { + pll_res->pll_interface_type = MDSS_DSI_PLL_8998; + } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_8998")) { + pll_res->pll_interface_type = MDSS_DP_PLL_8998; } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996")) { pll_res->pll_interface_type = MDSS_HDMI_PLL_8996; } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996_v2")) { @@ -148,8 +148,8 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996_v3_1p8")) { pll_res->pll_interface_type = MDSS_HDMI_PLL_8996_V3_1_8; - } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_HDMI_PLL_COBALT; + } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8998")) { + pll_res->pll_interface_type = MDSS_HDMI_PLL_8998; } else { goto err; } @@ -176,10 +176,10 @@ static int mdss_pll_clock_register(struct platform_device *pdev, case MDSS_DSI_PLL_8996: rc = dsi_pll_clock_register_8996(pdev, pll_res); break; - case MDSS_DSI_PLL_COBALT: - rc = dsi_pll_clock_register_cobalt(pdev, pll_res); - case MDSS_DP_PLL_COBALT: - rc = dp_pll_clock_register_cobalt(pdev, pll_res); + case MDSS_DSI_PLL_8998: + rc = dsi_pll_clock_register_8998(pdev, pll_res); + case MDSS_DP_PLL_8998: + rc = dp_pll_clock_register_8998(pdev, pll_res); break; case MDSS_HDMI_PLL_8996: rc = hdmi_8996_v1_pll_clock_register(pdev, pll_res); @@ -193,8 +193,8 @@ static int mdss_pll_clock_register(struct platform_device *pdev, case MDSS_HDMI_PLL_8996_V3_1_8: rc = hdmi_8996_v3_1p8_pll_clock_register(pdev, pll_res); break; - case MDSS_HDMI_PLL_COBALT: - rc = hdmi_cobalt_pll_clock_register(pdev, pll_res); + case MDSS_HDMI_PLL_8998: + rc = hdmi_8998_pll_clock_register(pdev, pll_res); break; case MDSS_UNKNOWN_PLL: default: @@ -394,13 +394,13 @@ static int mdss_pll_remove(struct platform_device *pdev) static const struct of_device_id mdss_pll_dt_match[] = { {.compatible = "qcom,mdss_dsi_pll_8996"}, {.compatible = "qcom,mdss_dsi_pll_8996_v2"}, - {.compatible = "qcom,mdss_dsi_pll_cobalt"}, + {.compatible = "qcom,mdss_dsi_pll_8998"}, {.compatible = "qcom,mdss_hdmi_pll_8996"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v2"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v3"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v3_1p8"}, - {.compatible = "qcom,mdss_dp_pll_cobalt"}, - {.compatible = "qcom,mdss_hdmi_pll_cobalt"}, + {.compatible = "qcom,mdss_dp_pll_8998"}, + {.compatible = "qcom,mdss_hdmi_pll_8998"}, {} }; diff --git a/drivers/clk/msm/mdss/mdss-pll.h b/drivers/clk/msm/mdss/mdss-pll.h index a2eb03e09146..8fffaf30d4ec 100644 --- a/drivers/clk/msm/mdss/mdss-pll.h +++ b/drivers/clk/msm/mdss/mdss-pll.h @@ -31,13 +31,13 @@ enum { MDSS_DSI_PLL_8996, - MDSS_DSI_PLL_COBALT, - MDSS_DP_PLL_COBALT, + MDSS_DSI_PLL_8998, + MDSS_DP_PLL_8998, MDSS_HDMI_PLL_8996, MDSS_HDMI_PLL_8996_V2, MDSS_HDMI_PLL_8996_V3, MDSS_HDMI_PLL_8996_V3_1_8, - MDSS_HDMI_PLL_COBALT, + MDSS_HDMI_PLL_8998, MDSS_UNKNOWN_PLL, }; diff --git a/drivers/clk/msm/vdd-level-cobalt.h b/drivers/clk/msm/vdd-level-8998.h index c1897b7da7f7..c45e003ef7d7 100644 --- a/drivers/clk/msm/vdd-level-cobalt.h +++ b/drivers/clk/msm/vdd-level-8998.h @@ -11,8 +11,8 @@ * GNU General Public License for more details. */ -#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_COBALT_H -#define __DRIVERS_CLK_QCOM_VDD_LEVEL_COBALT_H +#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_8998_H +#define __DRIVERS_CLK_QCOM_VDD_LEVEL_8998_H #include <linux/clk/msm-clock-generic.h> #include <linux/regulator/rpm-smd-regulator.h> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e39686ca4feb..36ab5cf68740 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -173,6 +173,16 @@ config MSM_GPUCC_FALCON Say Y if you want to support graphics controller devices which will be required to enable those device. +config MSM_MMCC_FALCON + tristate "MSMFALCON Multimedia Clock Controller" + select MSM_GCC_FALCON + depends on COMMON_CLK_QCOM + help + Support for the multimedia clock controller on Qualcomm Technologies, Inc + MSMfalcon devices. + Say Y if you want to support multimedia devices such as display, + video encode/decode, camera, etc. + config QCOM_HFPLL tristate "High-Frequency PLL (HFPLL) Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index adebefd63e71..595254f69db1 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o obj-$(CONFIG_MSM_GPUCC_FALCON) += gpucc-msmfalcon.o +obj-$(CONFIG_MSM_MMCC_FALCON) += mmcc-msmfalcon.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o obj-$(CONFIG_QCOM_HFPLL) += hfpll.o obj-$(CONFIG_KRAITCC) += krait-cc.o diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 085b9acfb9d5..f685e7fe3a4d 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -117,6 +117,11 @@ static int wait_for_pll_latch_ack(struct clk_alpha_pll *pll, u32 mask) return wait_for_pll(pll, mask, 0, "latch_ack"); } +static int wait_for_pll_update(struct clk_alpha_pll *pll, u32 mask) +{ + return wait_for_pll(pll, mask, 1, "update"); +} + /* alpha pll with hwfsm support */ #define PLL_OFFLINE_REQ BIT(7) @@ -562,12 +567,48 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, return clamp(rate, min_freq, max_freq); } +static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + int size, i, val; + + static struct clk_register_data data[] = { + {"PLL_MODE", 0x0}, + {"PLL_L_VAL", 0x4}, + {"PLL_ALPHA_VAL", 0x8}, + {"PLL_ALPHA_VAL_U", 0xC}, + {"PLL_USER_CTL", 0x10}, + {"PLL_CONFIG_CTL", 0x18}, + }; + + static struct clk_register_data data1[] = { + {"APSS_PLL_VOTE", 0x0}, + }; + + size = ARRAY_SIZE(data); + + for (i = 0; i < size; i++) { + regmap_read(pll->clkr.regmap, pll->offset + data[i].offset, + &val); + seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val); + } + + regmap_read(pll->clkr.regmap, pll->offset + data[0].offset, &val); + + if (val & PLL_FSM_ENA) { + regmap_read(pll->clkr.regmap, pll->clkr.enable_reg + + data1[0].offset, &val); + seq_printf(f, "%20s: 0x%.8x\n", data1[0].name, val); + } +} + const struct clk_ops clk_alpha_pll_ops = { .enable = clk_alpha_pll_enable, .disable = clk_alpha_pll_disable, .recalc_rate = clk_alpha_pll_recalc_rate, .round_rate = clk_alpha_pll_round_rate, .set_rate = clk_alpha_pll_set_rate, + .list_registers = clk_alpha_pll_list_registers, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_ops); @@ -577,6 +618,7 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = { .recalc_rate = clk_alpha_pll_recalc_rate, .round_rate = clk_alpha_pll_round_rate, .set_rate = clk_alpha_pll_set_rate, + .list_registers = clk_alpha_pll_list_registers, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops); @@ -633,3 +675,177 @@ const struct clk_ops clk_alpha_pll_postdiv_ops = { .set_rate = clk_alpha_pll_postdiv_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops); + +static int clk_alpha_pll_slew_update(struct clk_alpha_pll *pll) +{ + int ret = 0; + u32 val; + + regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_MODE, + PLL_UPDATE, PLL_UPDATE); + regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val); + + ret = wait_for_pll_update(pll, PLL_UPDATE); + if (ret) + return ret; + /* + * HPG mandates a wait of at least 570ns before polling the LOCK + * detect bit. Have a delay of 1us just to be safe. + */ + mb(); + udelay(1); + + ret = wait_for_pll_enable(pll, PLL_LOCK_DET); + + return ret; +} + +static int clk_alpha_pll_slew_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + unsigned long freq_hz; + const struct pll_vco *curr_vco, *vco; + u32 l; + u64 a; + + freq_hz = alpha_pll_round_rate(rate, parent_rate, &l, &a); + if (freq_hz != rate) { + pr_err("alpha_pll: Call clk_set_rate with rounded rates!\n"); + return -EINVAL; + } + + curr_vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw)); + if (!curr_vco) { + pr_err("alpha pll: not in a valid vco range\n"); + return -EINVAL; + } + + vco = alpha_pll_find_vco(pll, freq_hz); + if (!vco) { + pr_err("alpha pll: not in a valid vco range\n"); + return -EINVAL; + } + + /* + * Dynamic pll update will not support switching frequencies across + * vco ranges. In those cases fall back to normal alpha set rate. + */ + if (curr_vco->val != vco->val) + return clk_alpha_pll_set_rate(hw, rate, parent_rate); + + a = a << (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); + + regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32); + + /* Ensure that the write above goes through before proceeding. */ + mb(); + + if (clk_hw_is_enabled(hw)) + clk_alpha_pll_slew_update(pll); + + return 0; +} + +/* + * Slewing plls should be bought up at frequency which is in the middle of the + * desired VCO range. So after bringing up the pll at calibration freq, set it + * back to desired frequency(that was set by previous clk_set_rate). + */ +static int clk_alpha_pll_calibrate(struct clk_hw *hw) +{ + unsigned long calibration_freq, freq_hz; + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + const struct pll_vco *vco; + u64 a; + u32 l; + int rc; + + vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw)); + if (!vco) { + pr_err("alpha pll: not in a valid vco range\n"); + return -EINVAL; + } + + /* + * As during slewing plls vco_sel won't be allowed to change, vco table + * should have only one entry table, i.e. index = 0, find the + * calibration frequency. + */ + calibration_freq = (pll->vco_table[0].min_freq + + pll->vco_table[0].max_freq)/2; + + freq_hz = alpha_pll_round_rate(calibration_freq, + clk_hw_get_rate(clk_hw_get_parent(hw)), &l, &a); + if (freq_hz != calibration_freq) { + pr_err("alpha_pll: call clk_set_rate with rounded rates!\n"); + return -EINVAL; + } + + /* Setup PLL for calibration frequency */ + a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); + + regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32); + + regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL, + PLL_VCO_MASK << PLL_VCO_SHIFT, + vco->val << PLL_VCO_SHIFT); + + regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL, + PLL_ALPHA_EN, PLL_ALPHA_EN); + + /* Bringup the pll at calibration frequency */ + rc = clk_alpha_pll_enable(hw); + if (rc) { + pr_err("alpha pll calibration failed\n"); + return rc; + } + + /* + * PLL is already running at calibration frequency. + * So slew pll to the previously set frequency. + */ + freq_hz = alpha_pll_round_rate(clk_hw_get_rate(hw), + clk_hw_get_rate(clk_hw_get_parent(hw)), &l, &a); + + pr_debug("pll %s: setting back to required rate %lu, freq_hz %ld\n", + hw->init->name, clk_hw_get_rate(hw), freq_hz); + + /* Setup the PLL for the new frequency */ + a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); + + regmap_write(pll->clkr.regmap, pll->offset + PLL_L_VAL, l); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL, a); + regmap_write(pll->clkr.regmap, pll->offset + PLL_ALPHA_VAL_U, a >> 32); + + regmap_update_bits(pll->clkr.regmap, pll->offset + PLL_USER_CTL, + PLL_ALPHA_EN, PLL_ALPHA_EN); + + return clk_alpha_pll_slew_update(pll); +} + +static int clk_alpha_pll_slew_enable(struct clk_hw *hw) +{ + int rc; + + rc = clk_alpha_pll_calibrate(hw); + if (rc) + return rc; + + rc = clk_alpha_pll_enable(hw); + + return rc; +} + +const struct clk_ops clk_alpha_pll_slew_ops = { + .enable = clk_alpha_pll_slew_enable, + .disable = clk_alpha_pll_disable, + .recalc_rate = clk_alpha_pll_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = clk_alpha_pll_slew_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_alpha_pll_slew_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 9b1d3ee61cac..dd92bc340f8a 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -80,6 +80,7 @@ struct clk_alpha_pll_postdiv { extern const struct clk_ops clk_alpha_pll_ops; extern const struct clk_ops clk_alpha_pll_hwfsm_ops; extern const struct clk_ops clk_alpha_pll_postdiv_ops; +extern const struct clk_ops clk_alpha_pll_slew_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct pll_config *config); diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 8aea1d519311..ec3d02e8dcb1 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -16,10 +16,12 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/export.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/regmap.h> #include "clk-branch.h" +#include "clk-regmap.h" static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) { @@ -181,6 +183,43 @@ const struct clk_ops clk_branch_ops = { }; EXPORT_SYMBOL_GPL(clk_branch_ops); +static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw) +{ + struct clk_branch *br = to_clk_branch(hw); + struct clk_regmap *rclk = to_clk_regmap(hw); + int size, i, val; + + static struct clk_register_data data[] = { + {"CBCR", 0x0}, + }; + + static struct clk_register_data data1[] = { + {"APSS_VOTE", 0x0}, + {"APSS_SLEEP_VOTE", 0x4}, + }; + + size = ARRAY_SIZE(data); + + for (i = 0; i < size; i++) { + regmap_read(br->clkr.regmap, br->halt_reg + data[i].offset, + &val); + seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val); + } + + if ((br->halt_check & BRANCH_HALT_VOTED) && + !(br->halt_check & BRANCH_VOTED)) { + if (rclk->enable_reg) { + size = ARRAY_SIZE(data1); + for (i = 0; i < size; i++) { + regmap_read(br->clkr.regmap, rclk->enable_reg + + data1[i].offset, &val); + seq_printf(f, "%20s: 0x%.8x\n", + data1[i].name, val); + } + } + } +} + static int clk_branch2_enable(struct clk_hw *hw) { return clk_branch_toggle(hw, true, clk_branch2_check_halt); @@ -196,6 +235,7 @@ const struct clk_ops clk_branch2_ops = { .disable = clk_branch2_disable, .is_enabled = clk_is_enabled_regmap, .set_flags = clk_branch_set_flags, + .list_registers = clk_branch2_list_registers, }; EXPORT_SYMBOL_GPL(clk_branch2_ops); @@ -228,10 +268,38 @@ static void clk_gate2_disable(struct clk_hw *hw) clk_gate_toggle(hw, false); } +static void clk_gate2_list_registers(struct seq_file *f, struct clk_hw *hw) +{ + struct clk_gate2 *gt = to_clk_gate2(hw); + int size, i, val; + + static struct clk_register_data data[] = { + {"EN_REG", 0x0}, + }; + + size = ARRAY_SIZE(data); + + for (i = 0; i < size; i++) { + regmap_read(gt->clkr.regmap, gt->clkr.enable_reg + + data[i].offset, &val); + seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val); + } +} + +static int clk_gate2_set_flags(struct clk_hw *hw, unsigned flags) +{ + struct clk_gate2 *gt = to_clk_gate2(hw); + + return clk_cbcr_set_flags(gt->clkr.regmap, gt->clkr.enable_reg, + flags); +} + const struct clk_ops clk_gate2_ops = { .enable = clk_gate2_enable, .disable = clk_gate2_disable, .is_enabled = clk_is_enabled_regmap, + .list_registers = clk_gate2_list_registers, + .set_flags = clk_gate2_set_flags, }; EXPORT_SYMBOL_GPL(clk_gate2_ops); diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c new file mode 100644 index 000000000000..f97cd1b03c81 --- /dev/null +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -0,0 +1,3301 @@ +/* + * Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include <linux/debugfs.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/clk/msm-clk-provider.h> +#include <linux/clk/msm-clk.h> +#include <linux/clk/msm-clock-generic.h> +#include <linux/cpu.h> +#include <linux/platform_device.h> +#include <linux/of_platform.h> +#include <linux/pm_opp.h> +#include <linux/pm_qos.h> +#include <linux/interrupt.h> +#include <linux/regulator/driver.h> +#include <linux/uaccess.h> +#include <linux/sched.h> + +#include <soc/qcom/scm.h> +#include <soc/qcom/clock-pll.h> +#include <soc/qcom/clock-local2.h> +#include <soc/qcom/clock-alpha-pll.h> + +#include <dt-bindings/clock/msm-clocks-hwio-cobalt.h> +#include <dt-bindings/clock/msm-clocks-cobalt.h> + +#include "clock.h" + +enum clk_osm_bases { + OSM_BASE, + PLL_BASE, + EFUSE_BASE, + ACD_BASE, + NUM_BASES, +}; + +enum clk_osm_lut_data { + FREQ, + FREQ_DATA, + PLL_OVERRIDES, + SPARE_DATA, + VIRTUAL_CORNER, + NUM_FIELDS, +}; + +enum clk_osm_trace_method { + XOR_PACKET, + PERIODIC_PACKET, +}; + +enum clk_osm_trace_packet_id { + TRACE_PACKET0, + TRACE_PACKET1, + TRACE_PACKET2, + TRACE_PACKET3, +}; + +#define SEQ_REG(n) (0x300 + (n) * 4) +#define MEM_ACC_SEQ_REG_CFG_START(n) (SEQ_REG(12 + (n))) +#define MEM_ACC_SEQ_CONST(n) (n) +#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) +#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) +#define SEQ_REG1_MSMCOBALT_V2 0x1048 +#define VERSION_REG 0x0 +#define VERSION_1P1 0x00010100 + +#define OSM_TABLE_SIZE 40 +#define MAX_CLUSTER_CNT 2 +#define MAX_CONFIG 4 +#define LLM_SW_OVERRIDE_CNT 3 + +#define ENABLE_REG 0x1004 +#define INDEX_REG 0x1150 +#define FREQ_REG 0x1154 +#define VOLT_REG 0x1158 +#define OVERRIDE_REG 0x115C +#define SPARE_REG 0x1164 + +#define OSM_CYCLE_COUNTER_CTRL_REG 0x1F00 +#define OSM_CYCLE_COUNTER_STATUS_REG 0x1F04 +#define DCVS_PERF_STATE_DESIRED_REG 0x1F10 +#define DCVS_PERF_STATE_DEVIATION_INTR_STAT 0x1F14 +#define DCVS_PERF_STATE_DEVIATION_INTR_EN 0x1F18 +#define DCVS_PERF_STATE_DEVIATION_INTR_CLEAR 0x1F1C +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT 0x1F20 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN 0x1F24 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR 0x1F28 +#define DCVS_PERF_STATE_MET_INTR_STAT 0x1F2C +#define DCVS_PERF_STATE_MET_INTR_EN 0x1F30 +#define DCVS_PERF_STATE_MET_INTR_CLR 0x1F34 +#define OSM_CORE_TABLE_SIZE 8192 +#define OSM_REG_SIZE 32 + +#define WDOG_DOMAIN_PSTATE_STATUS 0x1c00 +#define WDOG_PROGRAM_COUNTER 0x1c74 + +#define OSM_CYCLE_COUNTER_USE_XO_EDGE_EN BIT(8) +#define PLL_MODE 0x0 +#define PLL_L_VAL 0x4 +#define PLL_USER_CTRL 0xC +#define PLL_CONFIG_CTL_LO 0x10 +#define PLL_TEST_CTL_HI 0x1C +#define PLL_STATUS 0x2C +#define PLL_LOCK_DET_MASK BIT(16) +#define PLL_WAIT_LOCK_TIME_US 10 +#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) +#define PLL_MIN_LVAL 43 + +#define CC_ZERO_BEHAV_CTRL 0x100C +#define SPM_CC_DCVS_DISABLE 0x1020 +#define SPM_CC_CTRL 0x1028 +#define SPM_CC_HYSTERESIS 0x101C +#define SPM_CORE_RET_MAPPING 0x1024 +#define CFG_DELAY_VAL_3 0x12C + +#define LLM_FREQ_VOTE_HYSTERESIS 0x102C +#define LLM_VOLT_VOTE_HYSTERESIS 0x1030 +#define LLM_INTF_DCVS_DISABLE 0x1034 + +#define ENABLE_OVERRIDE BIT(0) + +#define ITM_CL0_DISABLE_CL1_ENABLED 0x2 +#define ITM_CL0_ENABLED_CL1_DISABLE 0x1 + +#define APM_MX_MODE 0 +#define APM_APC_MODE BIT(1) +#define APM_MODE_SWITCH_MASK (BVAL(4, 2, 7) | BVAL(1, 0, 3)) +#define APM_MX_MODE_VAL 0 +#define APM_APC_MODE_VAL 0x3 + +#define GPLL_SEL 0x400 +#define PLL_EARLY_SEL 0x500 +#define PLL_MAIN_SEL 0x300 +#define RCG_UPDATE 0x3 +#define RCG_UPDATE_SUCCESS 0x2 +#define PLL_POST_DIV1 0x1F +#define PLL_POST_DIV2 0x11F + +#define LLM_SW_OVERRIDE_REG 0x1038 +#define VMIN_REDUC_ENABLE_REG 0x103C +#define VMIN_REDUC_TIMER_REG 0x1040 +#define PDN_FSM_CTRL_REG 0x1070 +#define CC_BOOST_TIMER_REG0 0x1074 +#define CC_BOOST_TIMER_REG1 0x1078 +#define CC_BOOST_TIMER_REG2 0x107C +#define CC_BOOST_EN_MASK BIT(0) +#define PS_BOOST_EN_MASK BIT(1) +#define DCVS_BOOST_EN_MASK BIT(2) +#define PC_RET_EXIT_DROOP_EN_MASK BIT(3) +#define WFX_DROOP_EN_MASK BIT(4) +#define DCVS_DROOP_EN_MASK BIT(5) +#define LMH_PS_EN_MASK BIT(6) +#define IGNORE_PLL_LOCK_MASK BIT(15) +#define SAFE_FREQ_WAIT_NS 5000 +#define DEXT_DECREMENT_WAIT_NS 1000 +#define DCVS_BOOST_TIMER_REG0 0x1084 +#define DCVS_BOOST_TIMER_REG1 0x1088 +#define DCVS_BOOST_TIMER_REG2 0x108C +#define PS_BOOST_TIMER_REG0 0x1094 +#define PS_BOOST_TIMER_REG1 0x1098 +#define PS_BOOST_TIMER_REG2 0x109C +#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 +#define DROOP_CTRL_REG 0x10A4 +#define DROOP_RELEASE_TIMER_CTRL 0x10A8 +#define DROOP_PROG_SYNC_DELAY_REG 0x10BC +#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 +#define OSM_PLL_SW_OVERRIDE_EN 0x10C0 + +#define PLL_SW_OVERRIDE_DROOP_EN BIT(0) +#define DCVS_DROOP_TIMER_CTRL 0x10B8 +#define SEQ_MEM_ADDR 0x500 +#define SEQ_CFG_BR_ADDR 0x170 +#define MAX_INSTRUCTIONS 256 +#define MAX_BR_INSTRUCTIONS 49 + +#define MAX_MEM_ACC_LEVELS 3 +#define MAX_MEM_ACC_VAL_PER_LEVEL 3 +#define MAX_MEM_ACC_VALUES (MAX_MEM_ACC_LEVELS * \ + MAX_MEM_ACC_VAL_PER_LEVEL) +#define MEM_ACC_APM_READ_MASK 0xff + +#define TRACE_CTRL 0x1F38 +#define TRACE_CTRL_EN_MASK BIT(0) +#define TRACE_CTRL_ENABLE 1 +#define TRACE_CTRL_DISABLE 0 +#define TRACE_CTRL_ENABLE_WDOG_STATUS BIT(30) +#define TRACE_CTRL_PACKET_TYPE_MASK BVAL(2, 1, 3) +#define TRACE_CTRL_PACKET_TYPE_SHIFT 1 +#define TRACE_CTRL_PERIODIC_TRACE_EN_MASK BIT(3) +#define TRACE_CTRL_PERIODIC_TRACE_ENABLE BIT(3) +#define PERIODIC_TRACE_TIMER_CTRL 0x1F3C +#define PERIODIC_TRACE_MIN_NS 1000 +#define PERIODIC_TRACE_MAX_NS 21474836475 +#define PERIODIC_TRACE_DEFAULT_NS 1000000 + +#define PLL_DD_USER_CTL_LO_ENABLE 0x0f04c408 +#define PLL_DD_USER_CTL_LO_DISABLE 0x1f04c41f +#define PLL_DD_D0_USER_CTL_LO 0x17916208 +#define PLL_DD_D1_USER_CTL_LO 0x17816208 + +#define PWRCL_EFUSE_SHIFT 0 +#define PWRCL_EFUSE_MASK 0 +#define PERFCL_EFUSE_SHIFT 29 +#define PERFCL_EFUSE_MASK 0x7 + +#define MSMCOBALTV1_PWRCL_BOOT_RATE 1478400000 +#define MSMCOBALTV1_PERFCL_BOOT_RATE 1536000000 +#define MSMCOBALTV2_PWRCL_BOOT_RATE 1555200000 +#define MSMCOBALTV2_PERFCL_BOOT_RATE 1728000000 + +/* ACD registers */ +#define ACD_HW_VERSION 0x0 +#define ACDCR 0x4 +#define ACDTD 0x8 +#define ACDSSCR 0x28 +#define ACD_EXTINT_CFG 0x30 +#define ACD_DCVS_SW 0x34 +#define ACD_GFMUX_CFG 0x3c +#define ACD_READOUT_CFG 0x48 +#define ACD_AUTOXFER_CFG 0x80 +#define ACD_AUTOXFER 0x84 +#define ACD_AUTOXFER_CTL 0x88 +#define ACD_AUTOXFER_STATUS 0x8c +#define ACD_WRITE_CTL 0x90 +#define ACD_WRITE_STATUS 0x94 +#define ACD_READOUT 0x98 + +#define ACD_MASTER_ONLY_REG_ADDR 0x80 +#define ACD_WRITE_CTL_UPDATE_EN BIT(0) +#define ACD_WRITE_CTL_SELECT_SHIFT 1 +#define ACD_GFMUX_CFG_SELECT BIT(0) +#define ACD_AUTOXFER_START_CLEAR 0 +#define ACD_AUTOXFER_START_SET BIT(0) +#define AUTO_XFER_DONE_MASK BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_SET BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR 0 +#define ACD_LOCAL_TRANSFER_TIMEOUT_NS 500 + +static void __iomem *virt_base; +static void __iomem *debug_base; + +#define lmh_lite_clk_src_source_val 1 + +#define ACD_REG_RELATIVE_ADDR(addr) (addr / 4) +#define ACD_REG_RELATIVE_ADDR_BITMASK(addr) \ + (1 << (ACD_REG_RELATIVE_ADDR(addr))) + +#define FIXDIV(div) (div ? (2 * (div) - 1) : (0)) + +#define F(f, s, div, m, n) \ + { \ + .freq_hz = (f), \ + .src_clk = &s.c, \ + .m_val = (m), \ + .n_val = ~((n)-(m)) * !!(n), \ + .d_val = ~(n),\ + .div_src_val = BVAL(4, 0, (int)FIXDIV(div)) \ + | BVAL(10, 8, s##_source_val), \ + } + +static u32 seq_instr[] = { + 0xc2005000, 0x2c9e3b21, 0xc0ab2cdc, 0xc2882525, 0x359dc491, + 0x700a500b, 0x5001aefc, 0xaefd7000, 0x390938c8, 0xcb44c833, + 0xce56cd54, 0x341336e0, 0xa4baadba, 0xb480a493, 0x10004000, + 0x70005001, 0x1000500c, 0xc792c5a1, 0x501625e1, 0x3da335a2, + 0x50170006, 0x50150006, 0x1000c633, 0x1000acb3, 0xc422acb4, + 0xaefc1000, 0x700a500b, 0x70005001, 0x5010aefd, 0x5012700b, + 0xad41700c, 0x84e5adb9, 0xb3808566, 0x239b0003, 0x856484e3, + 0xb9800007, 0x2bad0003, 0xac3aa20b, 0x0003181b, 0x0003bb40, + 0xa30d239b, 0x500c181b, 0x5011500f, 0x181b3413, 0x853984b9, + 0x0003bd80, 0xa0012ba4, 0x72050803, 0x500e1000, 0x500c1000, + 0x1c011c0a, 0x3b181c06, 0x1c073b43, 0x1c061000, 0x1c073983, + 0x1c02500c, 0x10001c0a, 0x70015002, 0x81031000, 0x70025003, + 0x70035004, 0x3b441000, 0x81553985, 0x70025003, 0x50054003, + 0xa1467009, 0x0003b1c0, 0x4005238b, 0x835a1000, 0x855c84db, + 0x1000a51f, 0x84de835d, 0xa52c855c, 0x50061000, 0x39cd3a4c, + 0x3ad03a8f, 0x10004006, 0x70065007, 0xa00f2c12, 0x08034007, + 0xaefc7205, 0xaefd700d, 0xa9641000, 0x40071c1a, 0x700daefc, + 0x1000aefd, 0x70065007, 0x50101c16, 0x40075012, 0x700daefc, + 0x2411aefd, 0xa8211000, 0x0803a00f, 0x500c7005, 0x1c1591e0, + 0x500f5014, 0x10005011, 0x500c2bd4, 0x0803a00f, 0x10007205, + 0xa00fa9d1, 0x0803a821, 0xa9d07005, 0x91e0500c, 0x500f1c15, + 0x10005011, 0x1c162bce, 0x50125010, 0xa022a82a, 0x70050803, + 0x1c1591df, 0x5011500f, 0x5014500c, 0x0803a00f, 0x10007205, + 0x501391a4, 0x22172217, 0x70075008, 0xa9634008, 0x1c1a0006, + 0x70085009, 0x10004009, 0x00008ed9, 0x3e05c8dd, 0x1c033604, + 0xabaf1000, 0x856284e1, 0x0003bb80, 0x1000239f, 0x0803a037, + 0x10007205, 0x8dc61000, 0x38a71c2a, 0x1c2a8dc4, 0x100038a6, + 0x1c2a8dc5, 0x8dc73867, 0x38681c2a, 0x8c491000, 0x8d4b8cca, + 0x10001c00, 0x8ccd8c4c, 0x1c008d4e, 0x8c4f1000, 0x8d518cd0, + 0x10001c00, 0xa759a79a, 0x1000a718, 0xbf80af9b, 0x00001000, +}; + +static u32 seq_br_instr[] = { + 0x248, 0x20e, 0x21c, 0xf6, 0x112, + 0x11c, 0xe4, 0xea, 0xc6, 0xd6, + 0x126, 0x108, 0x184, 0x1a8, 0x1b0, + 0x134, 0x158, 0x16e, 0x14a, 0xc2, + 0x190, 0x1d2, 0x1cc, 0x1d4, 0x1e8, + 0x0, 0x1f6, 0x32, 0x66, 0xb0, + 0xa6, 0x1fc, 0x3c, 0x44, 0x5c, + 0x60, 0x204, 0x30, 0x22a, 0x234, + 0x23e, 0x0, 0x250, 0x0, 0x0, 0x9a, + 0x20c, +}; + +DEFINE_EXT_CLK(xo_ao, NULL); +DEFINE_EXT_CLK(sys_apcsaux_clk_gcc, NULL); +DEFINE_EXT_CLK(lmh_lite_clk_src, NULL); + +struct osm_entry { + u16 virtual_corner; + u16 open_loop_volt; + u32 freq_data; + u32 override_data; + u32 spare_data; + long frequency; +}; + +static struct dentry *osm_debugfs_base; + +struct clk_osm { + struct clk c; + struct osm_entry osm_table[OSM_TABLE_SIZE]; + struct dentry *debugfs; + struct regulator *vdd_reg; + struct platform_device *vdd_dev; + void *vbases[NUM_BASES]; + unsigned long pbases[NUM_BASES]; + spinlock_t lock; + + u32 version; + u32 cpu_reg_mask; + u32 num_entries; + u32 cluster_num; + u32 irq; + u32 apm_crossover_vc; + u32 apm_threshold_vc; + u32 cycle_counter_reads; + u32 cycle_counter_delay; + u32 cycle_counter_factor; + u64 total_cycle_counter; + u32 prev_cycle_counter; + u32 l_val_base; + u32 apcs_itm_present; + u32 apcs_cfg_rcgr; + u32 apcs_cmd_rcgr; + u32 apcs_pll_user_ctl; + u32 apcs_mem_acc_cfg[MAX_MEM_ACC_VAL_PER_LEVEL]; + u32 apcs_mem_acc_val[MAX_MEM_ACC_VALUES]; + u32 llm_sw_overr[LLM_SW_OVERRIDE_CNT]; + u32 apm_mode_ctl; + u32 apm_ctrl_status; + u32 osm_clk_rate; + u32 xo_clk_rate; + u32 acd_td; + u32 acd_cr; + u32 acd_sscr; + u32 acd_extint0_cfg; + u32 acd_extint1_cfg; + u32 acd_autoxfer_ctl; + u32 acd_debugfs_addr; + bool acd_init; + bool secure_init; + bool red_fsm_en; + bool boost_fsm_en; + bool safe_fsm_en; + bool ps_fsm_en; + bool droop_fsm_en; + bool wfx_fsm_en; + bool pc_fsm_en; + + enum clk_osm_trace_method trace_method; + enum clk_osm_trace_packet_id trace_id; + struct notifier_block panic_notifier; + u32 trace_periodic_timer; + bool trace_en; + bool wdog_trace_en; +}; + +static bool msmcobalt_v1; +static bool msmcobalt_v2; + +static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val, + u32 offset, u32 mask) +{ + u32 val2, orig_val; + + val2 = orig_val = readl_relaxed((char *)c->vbases[OSM_BASE] + offset); + val2 &= ~mask; + val2 |= val & mask; + + if (val2 != orig_val) + writel_relaxed(val2, (char *)c->vbases[OSM_BASE] + offset); +} + +static inline void clk_osm_write_reg(struct clk_osm *c, u32 val, u32 offset) +{ + writel_relaxed(val, (char *)c->vbases[OSM_BASE] + offset); +} + +static inline int clk_osm_read_reg(struct clk_osm *c, u32 offset) +{ + return readl_relaxed((char *)c->vbases[OSM_BASE] + offset); +} + +static inline int clk_osm_read_reg_no_log(struct clk_osm *c, u32 offset) +{ + return readl_relaxed_no_log((char *)c->vbases[OSM_BASE] + offset); +} + +static inline int clk_osm_mb(struct clk_osm *c, int base) +{ + return readl_relaxed_no_log((char *)c->vbases[base] + VERSION_REG); +} + +static inline int clk_osm_acd_mb(struct clk_osm *c) +{ + return readl_relaxed_no_log((char *)c->vbases[ACD_BASE] + + ACD_HW_VERSION); +} + +static inline void clk_osm_acd_master_write_reg(struct clk_osm *c, + u32 val, u32 offset) +{ + writel_relaxed(val, (char *)c->vbases[ACD_BASE] + offset); +} + +static int clk_osm_acd_local_read_reg(struct clk_osm *c, u32 offset) +{ + u32 reg = 0; + int timeout; + + if (offset >= ACD_MASTER_ONLY_REG_ADDR) { + pr_err("ACD register at offset=0x%x not locally readable\n", + offset); + return -EINVAL; + } + + /* Set select field in read control register */ + writel_relaxed(ACD_REG_RELATIVE_ADDR(offset), + (char *)c->vbases[ACD_BASE] + ACD_READOUT_CFG); + + /* Clear write control register */ + writel_relaxed(reg, (char *)c->vbases[ACD_BASE] + ACD_WRITE_CTL); + + /* Set select and update_en fields in write control register */ + reg = (ACD_REG_RELATIVE_ADDR(ACD_READOUT_CFG) + << ACD_WRITE_CTL_SELECT_SHIFT) + | ACD_WRITE_CTL_UPDATE_EN; + writel_relaxed(reg, (char *)c->vbases[ACD_BASE] + ACD_WRITE_CTL); + + /* Ensure writes complete before polling */ + clk_osm_acd_mb(c); + + /* Poll write status register */ + for (timeout = ACD_LOCAL_TRANSFER_TIMEOUT_NS; timeout > 0; + timeout -= 100) { + reg = readl_relaxed((char *)c->vbases[ACD_BASE] + + ACD_WRITE_STATUS); + if ((reg & (ACD_REG_RELATIVE_ADDR_BITMASK(ACD_READOUT_CFG)))) + break; + ndelay(100); + } + + if (!timeout) { + pr_err("local read timed out, offset=0x%x status=0x%x\n", + offset, reg); + return -ETIMEDOUT; + } + + reg = readl_relaxed((char *)c->vbases[ACD_BASE] + + ACD_READOUT); + return reg; +} + +static int clk_osm_acd_local_write_reg(struct clk_osm *c, u32 val, u32 offset) +{ + u32 reg = 0; + int timeout; + + if (offset >= ACD_MASTER_ONLY_REG_ADDR) { + pr_err("ACD register at offset=0x%x not transferrable\n", + offset); + return -EINVAL; + } + + /* Clear write control register */ + writel_relaxed(reg, (char *)c->vbases[ACD_BASE] + ACD_WRITE_CTL); + + /* Set select and update_en fields in write control register */ + reg = (ACD_REG_RELATIVE_ADDR(offset) << ACD_WRITE_CTL_SELECT_SHIFT) + | ACD_WRITE_CTL_UPDATE_EN; + writel_relaxed(reg, (char *)c->vbases[ACD_BASE] + ACD_WRITE_CTL); + + /* Ensure writes complete before polling */ + clk_osm_acd_mb(c); + + /* Poll write status register */ + for (timeout = ACD_LOCAL_TRANSFER_TIMEOUT_NS; timeout > 0; + timeout -= 100) { + reg = readl_relaxed((char *)c->vbases[ACD_BASE] + + ACD_WRITE_STATUS); + if ((reg & (ACD_REG_RELATIVE_ADDR_BITMASK(offset)))) + break; + ndelay(100); + } + + if (!timeout) { + pr_err("local write timed out, offset=0x%x val=0x%x status=0x%x\n", + offset, val, reg); + return -ETIMEDOUT; + } + + return 0; +} + +static int clk_osm_acd_master_write_through_reg(struct clk_osm *c, + u32 val, u32 offset) +{ + writel_relaxed(val, (char *)c->vbases[ACD_BASE] + offset); + + /* Ensure writes complete before transfer to local copy */ + clk_osm_acd_mb(c); + + return clk_osm_acd_local_write_reg(c, val, offset); +} + +static int clk_osm_acd_auto_local_write_reg(struct clk_osm *c, u32 mask) +{ + u32 numregs, bitmask = mask; + u32 reg = 0; + int timeout; + + /* count number of bits set in register mask */ + for (numregs = 0; bitmask; numregs++) + bitmask &= bitmask - 1; + + /* Program auto-transfter mask */ + writel_relaxed(mask, (char *)c->vbases[ACD_BASE] + ACD_AUTOXFER_CFG); + + /* Clear start field in auto-transfer register */ + writel_relaxed(ACD_AUTOXFER_START_CLEAR, + (char *)c->vbases[ACD_BASE] + ACD_AUTOXFER); + + /* Set start field in auto-transfer register */ + writel_relaxed(ACD_AUTOXFER_START_SET, + (char *)c->vbases[ACD_BASE] + ACD_AUTOXFER); + + /* Ensure writes complete before polling */ + clk_osm_acd_mb(c); + + /* Poll auto-transfer status register */ + for (timeout = ACD_LOCAL_TRANSFER_TIMEOUT_NS * numregs; + timeout > 0; timeout -= 100) { + reg = readl_relaxed((char *)c->vbases[ACD_BASE] + + ACD_AUTOXFER_STATUS); + if (reg & AUTO_XFER_DONE_MASK) + break; + ndelay(100); + } + + if (!timeout) { + pr_err("local register auto-transfer timed out, mask=0x%x registers=%d status=0x%x\n", + mask, numregs, reg); + return -ETIMEDOUT; + } + + return 0; +} + +static inline int clk_osm_count_ns(struct clk_osm *c, u64 nsec) +{ + u64 temp; + + temp = (u64)c->osm_clk_rate * nsec; + do_div(temp, 1000000000); + + return temp; +} + +static inline struct clk_osm *to_clk_osm(struct clk *c) +{ + return container_of(c, struct clk_osm, c); +} + +static enum handoff clk_osm_handoff(struct clk *c) +{ + return HANDOFF_DISABLED_CLK; +} + +static long clk_osm_list_rate(struct clk *c, unsigned n) +{ + if (n >= c->num_fmax) + return -ENXIO; + return c->fmax[n]; +} + +static long clk_osm_round_rate(struct clk *c, unsigned long rate) +{ + int i; + unsigned long rrate = 0; + + /* + * If the rate passed in is 0, return the first frequency in + * the FMAX table. + */ + if (!rate) + return c->fmax[0]; + + for (i = 0; i < c->num_fmax; i++) { + if (is_better_rate(rate, rrate, c->fmax[i])) { + rrate = c->fmax[i]; + if (rrate == rate) + break; + } + } + + return rrate; +} + +static int clk_osm_search_table(struct osm_entry *table, int entries, long rate) +{ + int i; + + for (i = 0; i < entries; i++) + if (rate == table[i].frequency) + return i; + return -EINVAL; +} + +static int clk_osm_set_rate(struct clk *c, unsigned long rate) +{ + struct clk_osm *cpuclk = to_clk_osm(c); + int index = 0; + unsigned long r_rate; + + r_rate = clk_osm_round_rate(c, rate); + + if (rate != r_rate) { + pr_err("invalid rate requested rate=%ld\n", rate); + return -EINVAL; + } + + /* Convert rate to table index */ + index = clk_osm_search_table(cpuclk->osm_table, + cpuclk->num_entries, r_rate); + if (index < 0) { + pr_err("cannot set cluster %u to %lu\n", + cpuclk->cluster_num, rate); + return -EINVAL; + } + pr_debug("rate: %lu --> index %d\n", rate, index); + + if (cpuclk->llm_sw_overr[0]) { + clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[0], + LLM_SW_OVERRIDE_REG); + clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[1], + LLM_SW_OVERRIDE_REG); + udelay(1); + } + + /* Choose index and send request to OSM hardware */ + clk_osm_write_reg(cpuclk, index, DCVS_PERF_STATE_DESIRED_REG); + + if (cpuclk->llm_sw_overr[0]) { + udelay(1); + clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[2], + LLM_SW_OVERRIDE_REG); + } + + /* Make sure the write goes through before proceeding */ + clk_osm_mb(cpuclk, OSM_BASE); + + return 0; +} + +static int clk_osm_enable(struct clk *c) +{ + struct clk_osm *cpuclk = to_clk_osm(c); + + clk_osm_write_reg(cpuclk, 1, ENABLE_REG); + + /* Make sure the write goes through before proceeding */ + clk_osm_mb(cpuclk, OSM_BASE); + + /* Wait for 5us for OSM hardware to enable */ + udelay(5); + + pr_debug("OSM clk enabled for cluster=%d\n", cpuclk->cluster_num); + + return 0; +} + +static struct clk_ops clk_ops_cpu_osm = { + .enable = clk_osm_enable, + .set_rate = clk_osm_set_rate, + .round_rate = clk_osm_round_rate, + .list_rate = clk_osm_list_rate, + .handoff = clk_osm_handoff, +}; + +static struct regulator *vdd_pwrcl; +static struct regulator *vdd_perfcl; + +static struct clk_freq_tbl ftbl_osm_clk_src[] = { + F( 200000000, lmh_lite_clk_src, 1.5, 0, 0), + F_END +}; + +static struct rcg_clk osm_clk_src = { + .cmd_rcgr_reg = APCS_COMMON_LMH_CMD_RCGR, + .set_rate = set_rate_hid, + .freq_tbl = ftbl_osm_clk_src, + .current_freq = &rcg_dummy_freq, + .base = &virt_base, + .c = { + .dbg_name = "osm_clk_src", + .ops = &clk_ops_rcg, + CLK_INIT(osm_clk_src.c), + }, +}; + +static struct clk_osm pwrcl_clk = { + .cluster_num = 0, + .cpu_reg_mask = 0x3, + .c = { + .dbg_name = "pwrcl_clk", + .ops = &clk_ops_cpu_osm, + .parent = &xo_ao.c, + CLK_INIT(pwrcl_clk.c), + }, +}; + +static struct clk_osm perfcl_clk = { + .cluster_num = 1, + .cpu_reg_mask = 0x103, + .c = { + .dbg_name = "perfcl_clk", + .ops = &clk_ops_cpu_osm, + .parent = &xo_ao.c, + CLK_INIT(perfcl_clk.c), + }, +}; + +static struct clk_ops clk_ops_cpu_dbg_mux; + +static struct mux_clk cpu_debug_mux = { + .offset = 0x0, + .mask = 0x3, + .shift = 8, + .ops = &mux_reg_ops, + MUX_SRC_LIST( + { &pwrcl_clk.c, 0x00 }, + { &perfcl_clk.c, 0x01 }, + ), + .base = &debug_base, + .c = { + .dbg_name = "cpu_debug_mux", + .ops = &clk_ops_cpu_dbg_mux, + .flags = CLKFLAG_NO_RATE_CACHE, + CLK_INIT(cpu_debug_mux.c), + }, +}; + +static struct clk_lookup cpu_clocks_osm[] = { + CLK_LIST(pwrcl_clk), + CLK_LIST(perfcl_clk), + CLK_LIST(sys_apcsaux_clk_gcc), + CLK_LIST(xo_ao), + CLK_LIST(osm_clk_src), + CLK_LIST(cpu_debug_mux), +}; + +static unsigned long cpu_dbg_mux_get_rate(struct clk *clk) +{ + /* Account for the divider between the clock and the debug mux */ + if (!strcmp(clk->parent->dbg_name, "pwrcl_clk")) + return clk->rate/4; + else if (!strcmp(clk->parent->dbg_name, "perfcl_clk")) + return clk->rate/8; + return clk->rate; +} + +static void clk_osm_print_osm_table(struct clk_osm *c) +{ + int i; + struct osm_entry *table = c->osm_table; + u32 pll_src, pll_div, lval, core_count; + + pr_debug("Index, Frequency, VC, OLV (mv), Core Count, PLL Src, PLL Div, L-Val, ACC Level\n"); + for (i = 0; i < c->num_entries; i++) { + pll_src = (table[i].freq_data & GENMASK(27, 26)) >> 26; + pll_div = (table[i].freq_data & GENMASK(25, 24)) >> 24; + lval = table[i].freq_data & GENMASK(7, 0); + core_count = (table[i].freq_data & GENMASK(18, 16)) >> 16; + + pr_debug("%3d, %11lu, %2u, %5u, %2u, %6u, %8u, %7u, %5u\n", + i, + table[i].frequency, + table[i].virtual_corner, + table[i].open_loop_volt, + core_count, + pll_src, + pll_div, + lval, + table[i].spare_data); + } + pr_debug("APM threshold corner=%d, crossover corner=%d\n", + c->apm_threshold_vc, c->apm_crossover_vc); +} + +static int clk_osm_get_lut(struct platform_device *pdev, + struct clk_osm *c, char *prop_name) +{ + struct clk *clk = &c->c; + struct device_node *of = pdev->dev.of_node; + int prop_len, total_elems, num_rows, i, j, k; + int rc = 0; + u32 *array; + u32 data; + bool last_entry = false; + + if (!of_find_property(of, prop_name, &prop_len)) { + dev_err(&pdev->dev, "missing %s\n", prop_name); + return -EINVAL; + } + + total_elems = prop_len / sizeof(u32); + if (total_elems % NUM_FIELDS) { + dev_err(&pdev->dev, "bad length %d\n", prop_len); + return -EINVAL; + } + + num_rows = total_elems / NUM_FIELDS; + + clk->fmax = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long), + GFP_KERNEL); + if (!clk->fmax) + return -ENOMEM; + + array = devm_kzalloc(&pdev->dev, prop_len, GFP_KERNEL); + if (!array) + return -ENOMEM; + + rc = of_property_read_u32_array(of, prop_name, array, total_elems); + if (rc) { + dev_err(&pdev->dev, "Unable to parse OSM table, rc=%d\n", rc); + goto exit; + } + + pr_debug("%s: Entries in Table: %d\n", __func__, num_rows); + c->num_entries = num_rows; + if (c->num_entries > OSM_TABLE_SIZE) { + pr_err("LUT entries %d exceed maximum size %d\n", + c->num_entries, OSM_TABLE_SIZE); + return -EINVAL; + } + + for (i = 0, j = 0, k = 0; j < OSM_TABLE_SIZE; j++) { + c->osm_table[j].frequency = array[i + FREQ]; + c->osm_table[j].freq_data = array[i + FREQ_DATA]; + c->osm_table[j].override_data = array[i + PLL_OVERRIDES]; + c->osm_table[j].spare_data = array[i + SPARE_DATA]; + /* Voltage corners are 0 based in the OSM LUT */ + c->osm_table[j].virtual_corner = array[i + VIRTUAL_CORNER] - 1; + pr_debug("index=%d freq=%ld virtual_corner=%d freq_data=0x%x override_data=0x%x spare_data=0x%x\n", + j, c->osm_table[j].frequency, + c->osm_table[j].virtual_corner, + c->osm_table[j].freq_data, + c->osm_table[j].override_data, + c->osm_table[j].spare_data); + + data = (array[i + FREQ_DATA] & GENMASK(18, 16)) >> 16; + if (!last_entry) { + clk->fmax[k] = array[i]; + k++; + } + + if (i < total_elems - NUM_FIELDS) + i += NUM_FIELDS; + else + last_entry = true; + } + clk->num_fmax = k; +exit: + devm_kfree(&pdev->dev, array); + return rc; +} + +static int clk_osm_parse_dt_configs(struct platform_device *pdev) +{ + struct device_node *of = pdev->dev.of_node; + u32 *array; + int i, rc = 0; + + array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32), + GFP_KERNEL); + if (!array) + return -ENOMEM; + + rc = of_property_read_u32_array(of, "qcom,l-val-base", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,l-val-base property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.l_val_base = array[pwrcl_clk.cluster_num]; + perfcl_clk.l_val_base = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apcs-itm-present", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apcs-itm-present property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apcs_itm_present = array[pwrcl_clk.cluster_num]; + perfcl_clk.apcs_itm_present = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apcs-cfg-rcgr", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apcs-cfg-rcgr property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apcs_cfg_rcgr = array[pwrcl_clk.cluster_num]; + perfcl_clk.apcs_cfg_rcgr = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apcs-cmd-rcgr", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apcs-cmd-rcgr property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apcs_cmd_rcgr = array[pwrcl_clk.cluster_num]; + perfcl_clk.apcs_cmd_rcgr = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apcs-pll-user-ctl", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apcs-pll-user-ctl property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apcs_pll_user_ctl = array[pwrcl_clk.cluster_num]; + perfcl_clk.apcs_pll_user_ctl = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apm-mode-ctl", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apm-mode-ctl property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apm_mode_ctl = array[pwrcl_clk.cluster_num]; + perfcl_clk.apm_mode_ctl = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,apm-ctrl-status", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,apm-ctrl-status property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.apm_ctrl_status = array[pwrcl_clk.cluster_num]; + perfcl_clk.apm_ctrl_status = array[perfcl_clk.cluster_num]; + + for (i = 0; i < LLM_SW_OVERRIDE_CNT; i++) + of_property_read_u32_index(of, "qcom,llm-sw-overr", + pwrcl_clk.cluster_num * + LLM_SW_OVERRIDE_CNT + i, + &pwrcl_clk.llm_sw_overr[i]); + + for (i = 0; i < LLM_SW_OVERRIDE_CNT; i++) + of_property_read_u32_index(of, "qcom,llm-sw-overr", + perfcl_clk.cluster_num * + LLM_SW_OVERRIDE_CNT + i, + &perfcl_clk.llm_sw_overr[i]); + + if (pwrcl_clk.acd_init || perfcl_clk.acd_init) { + rc = of_property_read_u32_array(of, "qcom,acdtd-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdtd-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_td = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_td = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,acdcr-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdcr-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_cr = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_cr = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,acdsscr-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdsscr-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_sscr = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_sscr = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,acdextint0-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdextint0-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_extint0_cfg = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_extint0_cfg = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,acdextint1-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdextint1-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_extint1_cfg = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_extint1_cfg = array[perfcl_clk.cluster_num]; + + rc = of_property_read_u32_array(of, "qcom,acdautoxfer-val", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,acdautoxfer-val property, rc=%d\n", + rc); + return -EINVAL; + } + + pwrcl_clk.acd_autoxfer_ctl = array[pwrcl_clk.cluster_num]; + perfcl_clk.acd_autoxfer_ctl = array[perfcl_clk.cluster_num]; + } + + rc = of_property_read_u32(of, "qcom,xo-clk-rate", + &pwrcl_clk.xo_clk_rate); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,xo-clk-rate property, rc=%d\n", + rc); + return -EINVAL; + } + + perfcl_clk.xo_clk_rate = pwrcl_clk.xo_clk_rate; + + rc = of_property_read_u32(of, "qcom,osm-clk-rate", + &pwrcl_clk.osm_clk_rate); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,osm-clk-rate property, rc=%d\n", + rc); + return -EINVAL; + } + perfcl_clk.osm_clk_rate = pwrcl_clk.osm_clk_rate; + + rc = of_property_read_u32(of, "qcom,cc-reads", + &pwrcl_clk.cycle_counter_reads); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,cc-reads property, rc=%d\n", + rc); + return -EINVAL; + } + perfcl_clk.cycle_counter_reads = pwrcl_clk.cycle_counter_reads; + + rc = of_property_read_u32(of, "qcom,cc-delay", + &pwrcl_clk.cycle_counter_delay); + if (rc) + dev_dbg(&pdev->dev, "no delays between cycle counter reads\n"); + else + perfcl_clk.cycle_counter_delay = pwrcl_clk.cycle_counter_delay; + + rc = of_property_read_u32(of, "qcom,cc-factor", + &pwrcl_clk.cycle_counter_factor); + if (rc) + dev_dbg(&pdev->dev, "no factor specified for cycle counter estimation\n"); + else + perfcl_clk.cycle_counter_factor = + pwrcl_clk.cycle_counter_factor; + + perfcl_clk.red_fsm_en = pwrcl_clk.red_fsm_en = + of_property_read_bool(of, "qcom,red-fsm-en"); + + perfcl_clk.boost_fsm_en = pwrcl_clk.boost_fsm_en = + of_property_read_bool(of, "qcom,boost-fsm-en"); + + perfcl_clk.safe_fsm_en = pwrcl_clk.safe_fsm_en = + of_property_read_bool(of, "qcom,safe-fsm-en"); + + perfcl_clk.ps_fsm_en = pwrcl_clk.ps_fsm_en = + of_property_read_bool(of, "qcom,ps-fsm-en"); + + perfcl_clk.droop_fsm_en = pwrcl_clk.droop_fsm_en = + of_property_read_bool(of, "qcom,droop-fsm-en"); + + perfcl_clk.wfx_fsm_en = pwrcl_clk.wfx_fsm_en = + of_property_read_bool(of, "qcom,wfx-fsm-en"); + + perfcl_clk.pc_fsm_en = pwrcl_clk.pc_fsm_en = + of_property_read_bool(of, "qcom,pc-fsm-en"); + + devm_kfree(&pdev->dev, array); + + perfcl_clk.secure_init = pwrcl_clk.secure_init = + of_property_read_bool(pdev->dev.of_node, "qcom,osm-no-tz"); + + if (!pwrcl_clk.secure_init) + return rc; + + rc = of_property_read_u32_array(of, "qcom,pwrcl-apcs-mem-acc-cfg", + pwrcl_clk.apcs_mem_acc_cfg, + MAX_MEM_ACC_VAL_PER_LEVEL); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,pwrcl-apcs-mem-acc-cfg property, rc=%d\n", + rc); + return -EINVAL; + } + + of_property_read_u32_array(of, "qcom,perfcl-apcs-mem-acc-cfg", + perfcl_clk.apcs_mem_acc_cfg, + MAX_MEM_ACC_VAL_PER_LEVEL); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,perfcl-apcs-mem-acc-cfg property, rc=%d\n", + rc); + return -EINVAL; + } + + rc = of_property_read_u32_array(of, "qcom,pwrcl-apcs-mem-acc-val", + pwrcl_clk.apcs_mem_acc_val, + MAX_MEM_ACC_VALUES); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,pwrcl-apcs-mem-acc-val property, rc=%d\n", + rc); + return -EINVAL; + } + + rc = of_property_read_u32_array(of, "qcom,perfcl-apcs-mem-acc-val", + perfcl_clk.apcs_mem_acc_val, + MAX_MEM_ACC_VALUES); + if (rc) { + dev_err(&pdev->dev, "unable to find qcom,perfcl-apcs-mem-acc-val property, rc=%d\n", + rc); + return -EINVAL; + } + + return rc; +} + +static int clk_osm_resources_init(struct platform_device *pdev) +{ + struct device_node *node; + struct resource *res; + struct clk *c; + unsigned long pbase; + int i, rc = 0; + void *vbase; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osm"); + if (!res) { + dev_err(&pdev->dev, + "Unable to get platform resource for osm"); + return -ENOMEM; + } + + pwrcl_clk.pbases[OSM_BASE] = (unsigned long)res->start; + pwrcl_clk.vbases[OSM_BASE] = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!pwrcl_clk.vbases[OSM_BASE]) { + dev_err(&pdev->dev, "Unable to map in osm base\n"); + return -ENOMEM; + } + + perfcl_clk.pbases[OSM_BASE] = pwrcl_clk.pbases[OSM_BASE] + + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + perfcl_clk.vbases[OSM_BASE] = pwrcl_clk.vbases[OSM_BASE] + + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + + for (i = 0; i < MAX_CLUSTER_CNT; i++) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + i == pwrcl_clk.cluster_num ? + "pwrcl_pll" : "perfcl_pll"); + if (!res) { + dev_err(&pdev->dev, + "Unable to get platform resource\n"); + return -ENOMEM; + } + pbase = (unsigned long)res->start; + vbase = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + + if (!vbase) { + dev_err(&pdev->dev, "Unable to map in base\n"); + return -ENOMEM; + } + + if (i == pwrcl_clk.cluster_num) { + pwrcl_clk.pbases[PLL_BASE] = pbase; + pwrcl_clk.vbases[PLL_BASE] = vbase; + } else { + perfcl_clk.pbases[PLL_BASE] = pbase; + perfcl_clk.vbases[PLL_BASE] = vbase; + } + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "debug"); + if (!res) { + dev_err(&pdev->dev, "Failed to get debug mux base\n"); + return -EINVAL; + } + + debug_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!debug_base) { + dev_err(&pdev->dev, "Unable to map in debug mux base\n"); + return -ENOMEM; + } + + clk_ops_cpu_dbg_mux = clk_ops_gen_mux; + clk_ops_cpu_dbg_mux.get_rate = cpu_dbg_mux_get_rate; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_common"); + if (!res) { + dev_err(&pdev->dev, "Failed to get apcs common base\n"); + return -EINVAL; + } + + virt_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!virt_base) { + dev_err(&pdev->dev, "Failed to map apcs common registers\n"); + return -ENOMEM; + } + + /* efuse speed bin fuses are optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pwrcl_efuse"); + if (res) { + pbase = (unsigned long)res->start; + vbase = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!vbase) { + dev_err(&pdev->dev, "Unable to map in pwrcl_efuse base\n"); + return -ENOMEM; + } + pwrcl_clk.pbases[EFUSE_BASE] = pbase; + pwrcl_clk.vbases[EFUSE_BASE] = vbase; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "perfcl_efuse"); + if (res) { + pbase = (unsigned long)res->start; + vbase = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!vbase) { + dev_err(&pdev->dev, "Unable to map in perfcl_efuse base\n"); + return -ENOMEM; + } + perfcl_clk.pbases[EFUSE_BASE] = pbase; + perfcl_clk.vbases[EFUSE_BASE] = vbase; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pwrcl_acd"); + if (res) { + pbase = (unsigned long)res->start; + vbase = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!vbase) { + dev_err(&pdev->dev, "Unable to map in pwrcl_acd base\n"); + return -ENOMEM; + } + pwrcl_clk.pbases[ACD_BASE] = pbase; + pwrcl_clk.vbases[ACD_BASE] = vbase; + pwrcl_clk.acd_init = true; + } else { + pwrcl_clk.acd_init = false; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "perfcl_acd"); + if (res) { + pbase = (unsigned long)res->start; + vbase = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!vbase) { + dev_err(&pdev->dev, "Unable to map in perfcl_acd base\n"); + return -ENOMEM; + } + perfcl_clk.pbases[ACD_BASE] = pbase; + perfcl_clk.vbases[ACD_BASE] = vbase; + perfcl_clk.acd_init = true; + } else { + perfcl_clk.acd_init = false; + } + + vdd_pwrcl = devm_regulator_get(&pdev->dev, "vdd-pwrcl"); + if (IS_ERR(vdd_pwrcl)) { + rc = PTR_ERR(vdd_pwrcl); + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "Unable to get the pwrcl vreg, rc=%d\n", + rc); + return rc; + } + + vdd_perfcl = devm_regulator_get(&pdev->dev, "vdd-perfcl"); + if (IS_ERR(vdd_perfcl)) { + rc = PTR_ERR(vdd_perfcl); + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "Unable to get the perfcl vreg, rc=%d\n", + rc); + return rc; + } + + pwrcl_clk.vdd_reg = vdd_pwrcl; + perfcl_clk.vdd_reg = vdd_perfcl; + + node = of_parse_phandle(pdev->dev.of_node, "vdd-pwrcl-supply", 0); + if (!node) { + pr_err("Unable to find vdd-pwrcl-supply\n"); + return -EINVAL; + } + + pwrcl_clk.vdd_dev = of_find_device_by_node(node->parent->parent); + if (!pwrcl_clk.vdd_dev) { + pr_err("Unable to find device for vdd-pwrcl-supply node\n"); + return -EINVAL; + } + + node = of_parse_phandle(pdev->dev.of_node, + "vdd-perfcl-supply", 0); + if (!node) { + pr_err("Unable to find vdd-perfcl-supply\n"); + return -EINVAL; + } + + perfcl_clk.vdd_dev = of_find_device_by_node(node->parent->parent); + if (!perfcl_clk.vdd_dev) { + pr_err("Unable to find device for vdd-perfcl-supply\n"); + return -EINVAL; + } + + c = devm_clk_get(&pdev->dev, "aux_clk"); + if (IS_ERR(c)) { + rc = PTR_ERR(c); + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "Unable to get aux_clk, rc=%d\n", + rc); + return rc; + } + sys_apcsaux_clk_gcc.c.parent = c; + + c = devm_clk_get(&pdev->dev, "xo_ao"); + if (IS_ERR(c)) { + rc = PTR_ERR(c); + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "Unable to get xo_ao clk, rc=%d\n", + rc); + return rc; + } + xo_ao.c.parent = c; + + return 0; +} + +static void clk_osm_setup_cluster_pll(struct clk_osm *c) +{ + writel_relaxed(0x0, c->vbases[PLL_BASE] + PLL_MODE); + writel_relaxed(0x20, c->vbases[PLL_BASE] + PLL_L_VAL); + writel_relaxed(0x01000008, c->vbases[PLL_BASE] + + PLL_USER_CTRL); + writel_relaxed(0x20004AA8, c->vbases[PLL_BASE] + + PLL_CONFIG_CTL_LO); + writel_relaxed(0x2, c->vbases[PLL_BASE] + + PLL_MODE); + + /* Ensure writes complete before delaying */ + clk_osm_mb(c, PLL_BASE); + + udelay(PLL_WAIT_LOCK_TIME_US); + + writel_relaxed(0x6, c->vbases[PLL_BASE] + PLL_MODE); + + /* Ensure write completes before delaying */ + clk_osm_mb(c, PLL_BASE); + + usleep_range(50, 75); + + writel_relaxed(0x7, c->vbases[PLL_BASE] + PLL_MODE); +} + +static int clk_osm_setup_hw_table(struct clk_osm *c) +{ + struct osm_entry *entry = c->osm_table; + int i; + u32 freq_val, volt_val, override_val, spare_val; + u32 table_entry_offset, last_spare, last_virtual_corner = 0; + + for (i = 0; i < OSM_TABLE_SIZE; i++) { + if (i < c->num_entries) { + freq_val = entry[i].freq_data; + volt_val = BVAL(21, 16, entry[i].virtual_corner) + | BVAL(11, 0, entry[i].open_loop_volt); + override_val = entry[i].override_data; + spare_val = entry[i].spare_data; + + if (last_virtual_corner && last_virtual_corner == + entry[i].virtual_corner && last_spare != + entry[i].spare_data) { + pr_err("invalid LUT entry at row=%d virtual_corner=%d, spare_data=%d\n", + i, entry[i].virtual_corner, + entry[i].spare_data); + return -EINVAL; + } + last_virtual_corner = entry[i].virtual_corner; + last_spare = entry[i].spare_data; + } + + table_entry_offset = i * OSM_REG_SIZE; + clk_osm_write_reg(c, i, INDEX_REG + table_entry_offset); + clk_osm_write_reg(c, freq_val, FREQ_REG + table_entry_offset); + clk_osm_write_reg(c, volt_val, VOLT_REG + table_entry_offset); + clk_osm_write_reg(c, override_val, OVERRIDE_REG + + table_entry_offset); + clk_osm_write_reg(c, spare_val, SPARE_REG + + table_entry_offset); + } + + /* Make sure all writes go through */ + clk_osm_mb(c, OSM_BASE); + + return 0; +} + +static int clk_osm_resolve_open_loop_voltages(struct clk_osm *c) +{ + struct regulator *regulator = c->vdd_reg; + u32 vc, mv; + int i; + + for (i = 0; i < OSM_TABLE_SIZE; i++) { + vc = c->osm_table[i].virtual_corner + 1; + /* Voltage is in uv. Convert to mv */ + mv = regulator_list_corner_voltage(regulator, vc) / 1000; + c->osm_table[i].open_loop_volt = mv; + } + + return 0; +} + +static int clk_osm_resolve_crossover_corners(struct clk_osm *c, + struct platform_device *pdev) +{ + struct regulator *regulator = c->vdd_reg; + int count, vc, i, threshold, rc = 0; + u32 corner_volt; + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,apm-threshold-voltage", + &threshold); + if (rc) { + pr_info("qcom,apm-threshold-voltage property not specified\n"); + return rc; + } + + /* Determine crossover virtual corner */ + count = regulator_count_voltages(regulator); + if (count < 0) { + pr_err("Failed to get the number of virtual corners supported\n"); + return count; + } + + c->apm_crossover_vc = count - 1; + + /* Determine 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) { + c->apm_threshold_vc = c->osm_table[i].virtual_corner; + break; + } + } + + return 0; +} + +static int clk_osm_set_cc_policy(struct platform_device *pdev) +{ + int rc = 0, val; + u32 *array; + struct device_node *of = pdev->dev.of_node; + + array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32), + GFP_KERNEL); + if (!array) + return -ENOMEM; + + rc = of_property_read_u32_array(of, "qcom,up-timer", array, + MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No up timer value, rc=%d\n", + rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, SPM_CC_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, SPM_CC_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, SPM_CC_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, SPM_CC_HYSTERESIS); + } + + rc = of_property_read_u32_array(of, "qcom,down-timer", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No down timer value, rc=%d\n", rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, SPM_CC_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, SPM_CC_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, SPM_CC_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, SPM_CC_HYSTERESIS); + } + + /* OSM index override for cluster PC */ + rc = of_property_read_u32_array(of, "qcom,pc-override-index", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No PC override index value, rc=%d\n", + rc); + clk_osm_write_reg(&pwrcl_clk, 0, CC_ZERO_BEHAV_CTRL); + clk_osm_write_reg(&perfcl_clk, 0, CC_ZERO_BEHAV_CTRL); + } else { + val = BVAL(6, 1, array[pwrcl_clk.cluster_num]) + | ENABLE_OVERRIDE; + clk_osm_write_reg(&pwrcl_clk, val, CC_ZERO_BEHAV_CTRL); + val = BVAL(6, 1, array[perfcl_clk.cluster_num]) + | ENABLE_OVERRIDE; + clk_osm_write_reg(&perfcl_clk, val, CC_ZERO_BEHAV_CTRL); + } + + /* Wait for the writes to complete */ + clk_osm_mb(&perfcl_clk, OSM_BASE); + + rc = of_property_read_bool(pdev->dev.of_node, "qcom,set-ret-inactive"); + if (rc) { + dev_dbg(&pdev->dev, "Treat cores in retention as active\n"); + val = 0; + } else { + dev_dbg(&pdev->dev, "Treat cores in retention as inactive\n"); + val = 1; + } + + clk_osm_write_reg(&pwrcl_clk, val, SPM_CORE_RET_MAPPING); + clk_osm_write_reg(&perfcl_clk, val, SPM_CORE_RET_MAPPING); + + rc = of_property_read_bool(pdev->dev.of_node, "qcom,disable-cc-dvcs"); + if (rc) { + dev_dbg(&pdev->dev, "Disabling CC based DCVS\n"); + val = 1; + } else + val = 0; + + clk_osm_write_reg(&pwrcl_clk, val, SPM_CC_DCVS_DISABLE); + clk_osm_write_reg(&perfcl_clk, val, SPM_CC_DCVS_DISABLE); + + /* Wait for the writes to complete */ + clk_osm_mb(&perfcl_clk, OSM_BASE); + + devm_kfree(&pdev->dev, array); + return 0; +} + +static void clk_osm_setup_itm_to_osm_handoff(void) +{ + /* Program address of ITM_PRESENT of CPUSS */ + clk_osm_write_reg(&pwrcl_clk, pwrcl_clk.apcs_itm_present, + SEQ_REG(37)); + clk_osm_write_reg(&pwrcl_clk, 0, SEQ_REG(38)); + clk_osm_write_reg(&perfcl_clk, perfcl_clk.apcs_itm_present, + SEQ_REG(37)); + clk_osm_write_reg(&perfcl_clk, 0, SEQ_REG(38)); + + /* + * Program data to write to ITM_PRESENT assuming ITM for other domain + * is enabled and the ITM for this domain is to be disabled. + */ + clk_osm_write_reg(&pwrcl_clk, ITM_CL0_DISABLE_CL1_ENABLED, + SEQ_REG(39)); + clk_osm_write_reg(&perfcl_clk, ITM_CL0_ENABLED_CL1_DISABLE, + SEQ_REG(39)); +} + +static int clk_osm_set_llm_freq_policy(struct platform_device *pdev) +{ + struct device_node *of = pdev->dev.of_node; + u32 *array; + int rc = 0, val, regval; + + array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32), + GFP_KERNEL); + if (!array) + return -ENOMEM; + + /* + * Setup Timer to control how long OSM should wait before performing + * DCVS when a LLM up frequency request is received. + * Time is specified in us. + */ + rc = of_property_read_u32_array(of, "qcom,llm-freq-up-timer", array, + MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "Unable to get CC up timer value: %d\n", + rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, LLM_FREQ_VOTE_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, LLM_FREQ_VOTE_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, LLM_FREQ_VOTE_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, LLM_FREQ_VOTE_HYSTERESIS); + } + + /* + * Setup Timer to control how long OSM should wait before performing + * DCVS when a LLM down frequency request is received. + * Time is specified in us. + */ + rc = of_property_read_u32_array(of, "qcom,llm-freq-down-timer", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No LLM Frequency down timer value: %d\n", + rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, LLM_FREQ_VOTE_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, LLM_FREQ_VOTE_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, LLM_FREQ_VOTE_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, LLM_FREQ_VOTE_HYSTERESIS); + } + + /* Enable or disable honoring of LLM frequency requests */ + rc = of_property_read_bool(pdev->dev.of_node, + "qcom,enable-llm-freq-vote"); + if (rc) { + dev_dbg(&pdev->dev, "Honoring LLM Frequency requests\n"); + val = 0; + } else + val = 1; + + /* Enable or disable LLM FREQ DVCS */ + regval = val | clk_osm_read_reg(&pwrcl_clk, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&pwrcl_clk, regval, LLM_INTF_DCVS_DISABLE); + regval = val | clk_osm_read_reg(&perfcl_clk, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&perfcl_clk, regval, LLM_INTF_DCVS_DISABLE); + + /* Wait for the write to complete */ + clk_osm_mb(&perfcl_clk, OSM_BASE); + + devm_kfree(&pdev->dev, array); + return 0; +} + +static int clk_osm_set_llm_volt_policy(struct platform_device *pdev) +{ + struct device_node *of = pdev->dev.of_node; + u32 *array; + int rc = 0, val, regval; + + array = devm_kzalloc(&pdev->dev, MAX_CLUSTER_CNT * sizeof(u32), + GFP_KERNEL); + if (!array) + return -ENOMEM; + + /* + * Setup Timer to control how long OSM should wait before performing + * DCVS when a LLM up voltage request is received. + * Time is specified in us. + */ + rc = of_property_read_u32_array(of, "qcom,llm-volt-up-timer", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No LLM voltage up timer value, rc=%d\n", + rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, LLM_VOLT_VOTE_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, LLM_VOLT_VOTE_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, LLM_VOLT_VOTE_HYSTERESIS) + | BVAL(31, 16, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, LLM_VOLT_VOTE_HYSTERESIS); + } + + /* + * Setup Timer to control how long OSM should wait before performing + * DCVS when a LLM down voltage request is received. + * Time is specified in us. + */ + rc = of_property_read_u32_array(of, "qcom,llm-volt-down-timer", + array, MAX_CLUSTER_CNT); + if (rc) { + dev_dbg(&pdev->dev, "No LLM Voltage down timer value: %d\n", + rc); + } else { + val = clk_osm_read_reg(&pwrcl_clk, LLM_VOLT_VOTE_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&pwrcl_clk, + array[pwrcl_clk.cluster_num])); + clk_osm_write_reg(&pwrcl_clk, val, LLM_VOLT_VOTE_HYSTERESIS); + val = clk_osm_read_reg(&perfcl_clk, LLM_VOLT_VOTE_HYSTERESIS) + | BVAL(15, 0, clk_osm_count_ns(&perfcl_clk, + array[perfcl_clk.cluster_num])); + clk_osm_write_reg(&perfcl_clk, val, LLM_VOLT_VOTE_HYSTERESIS); + } + + /* Enable or disable honoring of LLM Voltage requests */ + rc = of_property_read_bool(pdev->dev.of_node, + "qcom,enable-llm-volt-vote"); + if (rc) { + dev_dbg(&pdev->dev, "Honoring LLM Voltage requests\n"); + val = 0; + } else + val = BIT(1); + + /* Enable or disable LLM VOLT DVCS */ + regval = val | clk_osm_read_reg(&pwrcl_clk, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&pwrcl_clk, val, LLM_INTF_DCVS_DISABLE); + regval = val | clk_osm_read_reg(&perfcl_clk, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&perfcl_clk, val, LLM_INTF_DCVS_DISABLE); + + /* Wait for the writes to complete */ + clk_osm_mb(&perfcl_clk, OSM_BASE); + + devm_kfree(&pdev->dev, array); + return 0; +} + +static void clk_osm_program_apm_regs(struct clk_osm *c) +{ + /* + * Program address of the control register used to configure + * the Array Power Mux controller + */ + clk_osm_write_reg(c, c->apm_mode_ctl, SEQ_REG(2)); + + /* Program address of controller status register */ + clk_osm_write_reg(c, c->apm_ctrl_status, SEQ_REG(3)); + + /* Program mode value to switch APM from VDD_APCC to VDD_MX */ + clk_osm_write_reg(c, APM_MX_MODE, SEQ_REG(77)); + + /* Program value used to determine current APM power supply is VDD_MX */ + clk_osm_write_reg(c, APM_MX_MODE_VAL, SEQ_REG(78)); + + /* Program mask used to determine status of APM power supply switch */ + clk_osm_write_reg(c, APM_MODE_SWITCH_MASK, SEQ_REG(79)); + + /* Program mode value to switch APM from VDD_MX to VDD_APCC */ + clk_osm_write_reg(c, APM_APC_MODE, SEQ_REG(80)); + + /* + * Program value used to determine current APM power supply + * is VDD_APCC + */ + clk_osm_write_reg(c, APM_APC_MODE_VAL, SEQ_REG(81)); +} + +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}; + + curr_level = c->osm_table[0].spare_data; + for (i = 0; i < c->num_entries; i++) { + if (curr_level == MAX_MEM_ACC_LEVELS) + break; + + if (c->osm_table[i].spare_data != curr_level) { + mem_acc_level_map[j++] = i - 1; + curr_level = c->osm_table[i].spare_data; + } + } + + if (c->secure_init) { + clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(1), SEQ_REG(51)); + clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(2), SEQ_REG(52)); + clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(3), SEQ_REG(53)); + clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(4), SEQ_REG(54)); + clk_osm_write_reg(c, MEM_ACC_APM_READ_MASK, SEQ_REG(59)); + clk_osm_write_reg(c, mem_acc_level_map[0], SEQ_REG(55)); + clk_osm_write_reg(c, mem_acc_level_map[0] + 1, SEQ_REG(56)); + clk_osm_write_reg(c, mem_acc_level_map[1], SEQ_REG(57)); + clk_osm_write_reg(c, mem_acc_level_map[1] + 1, SEQ_REG(58)); + clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(28), + SEQ_REG(49)); + + for (i = 0; i < MAX_MEM_ACC_VALUES; i++) + clk_osm_write_reg(c, c->apcs_mem_acc_val[i], + MEM_ACC_SEQ_REG_VAL_START(i)); + + for (i = 0; i < MAX_MEM_ACC_VAL_PER_LEVEL; i++) + clk_osm_write_reg(c, c->apcs_mem_acc_cfg[i], + MEM_ACC_SEQ_REG_CFG_START(i)); + } else { + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55), + mem_acc_level_map[0]); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(56), + mem_acc_level_map[0] + 1); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(57), + mem_acc_level_map[1]); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(58), + mem_acc_level_map[1] + 1); + /* SEQ_REG(49) = SEQ_REG(28) init by TZ */ + } +} + +void clk_osm_setup_sequencer(struct clk_osm *c) +{ + u32 i; + + pr_debug("Setting up sequencer for cluster=%d\n", c->cluster_num); + for (i = 0; i < ARRAY_SIZE(seq_instr); i++) { + clk_osm_write_reg(c, seq_instr[i], + (long)(SEQ_MEM_ADDR + i * 4)); + } + + pr_debug("Setting up sequencer branch instructions for cluster=%d\n", + c->cluster_num); + for (i = 0; i < ARRAY_SIZE(seq_br_instr); i++) { + clk_osm_write_reg(c, seq_br_instr[i], + (long)(SEQ_CFG_BR_ADDR + i * 4)); + } +} + +static void clk_osm_setup_cycle_counters(struct clk_osm *c) +{ + u32 ratio = c->osm_clk_rate; + u32 val = 0; + + /* Enable cycle counter */ + val |= BIT(0); + /* Setup OSM clock to XO ratio */ + do_div(ratio, c->xo_clk_rate); + val |= BVAL(5, 1, ratio - 1) | OSM_CYCLE_COUNTER_USE_XO_EDGE_EN; + clk_osm_write_reg(c, val, OSM_CYCLE_COUNTER_CTRL_REG); + c->total_cycle_counter = 0; + c->prev_cycle_counter = 0; + pr_debug("OSM to XO clock ratio: %d\n", ratio); +} + +static void clk_osm_setup_osm_was(struct clk_osm *c) +{ + u32 cc_hyst; + u32 val; + + if (msmcobalt_v2) + return; + + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + val |= IGNORE_PLL_LOCK_MASK; + cc_hyst = clk_osm_read_reg(c, SPM_CC_HYSTERESIS); + + if (c->secure_init) { + clk_osm_write_reg(c, val, SEQ_REG(47)); + val &= ~IGNORE_PLL_LOCK_MASK; + clk_osm_write_reg(c, val, SEQ_REG(48)); + + clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(42), + SEQ_REG(40)); + clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(43), + SEQ_REG(41)); + clk_osm_write_reg(c, 0x1, SEQ_REG(44)); + clk_osm_write_reg(c, 0x0, SEQ_REG(45)); + clk_osm_write_reg(c, c->pbases[OSM_BASE] + PDN_FSM_CTRL_REG, + SEQ_REG(46)); + + /* C2D/C3 + D2D workaround */ + clk_osm_write_reg(c, c->pbases[OSM_BASE] + SPM_CC_HYSTERESIS, + SEQ_REG(6)); + clk_osm_write_reg(c, cc_hyst, SEQ_REG(7)); + + /* Droop detector PLL lock detect workaround */ + clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_ENABLE, SEQ_REG(4)); + clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_DISABLE, SEQ_REG(5)); + clk_osm_write_reg(c, c->cluster_num == 0 ? PLL_DD_D0_USER_CTL_LO + : PLL_DD_D1_USER_CTL_LO, SEQ_REG(21)); + + /* PLL lock detect and HMSS AHB clock workaround */ + clk_osm_write_reg(c, 0x640, CFG_DELAY_VAL_3); + + /* DxFSM workaround */ + clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911200 : + 0x17811200, SEQ_REG(22)); + clk_osm_write_reg(c, 0x80800, SEQ_REG(23)); + clk_osm_write_reg(c, 0x179D1100, SEQ_REG(24)); + clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); + clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17912000 : + 0x17811290, SEQ_REG(26)); + clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911290 : + 0x17811290, SEQ_REG(20)); + clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17811290 : + 0x17911290, SEQ_REG(32)); + clk_osm_write_reg(c, 0x179D4020, SEQ_REG(35)); + clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); + clk_osm_write_reg(c, 0xa, SEQ_REG(86)); + clk_osm_write_reg(c, 0xe, SEQ_REG(87)); + clk_osm_write_reg(c, 0x00400000, SEQ_REG(88)); + clk_osm_write_reg(c, 0x00700000, SEQ_REG(89)); + } else { + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(47), val); + val &= ~IGNORE_PLL_LOCK_MASK; + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(48), val); + + /* C2D/C3 + D2D workaround */ + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(7), + cc_hyst); + + /* Droop detector PLL lock detect workaround */ + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(4), + PLL_DD_USER_CTL_LO_ENABLE); + } + + if (c->cluster_num == 0) { + val = readl_relaxed(c->vbases[PLL_BASE] + PLL_TEST_CTL_HI) + | BIT(13); + writel_relaxed(val, c->vbases[PLL_BASE] + + PLL_TEST_CTL_HI); + } + + /* Ensure writes complete before returning */ + clk_osm_mb(c, OSM_BASE); +} + +static void clk_osm_setup_fsms(struct clk_osm *c) +{ + u32 val; + + /* Reduction FSM */ + if (c->red_fsm_en) { + val = clk_osm_read_reg(c, VMIN_REDUC_ENABLE_REG) | BIT(0); + clk_osm_write_reg(c, val, VMIN_REDUC_ENABLE_REG); + clk_osm_write_reg(c, BVAL(15, 0, clk_osm_count_ns(c, 10000)), + VMIN_REDUC_TIMER_REG); + } + + /* Boost FSM */ + if (c->boost_fsm_en) { + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | CC_BOOST_EN_MASK, PDN_FSM_CTRL_REG); + + val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG0); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS)); + clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG0); + + val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG1); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG1); + + val = clk_osm_read_reg(c, CC_BOOST_TIMER_REG2); + val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS)); + clk_osm_write_reg(c, val, CC_BOOST_TIMER_REG2); + } + + /* Safe Freq FSM */ + if (c->safe_fsm_en) { + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | DCVS_BOOST_EN_MASK, + PDN_FSM_CTRL_REG); + + val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG0); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS)); + clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG0); + + val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG1); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG1); + + val = clk_osm_read_reg(c, DCVS_BOOST_TIMER_REG2); + val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS)); + clk_osm_write_reg(c, val, DCVS_BOOST_TIMER_REG2); + + } + + /* PS FSM */ + if (c->ps_fsm_en) { + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | PS_BOOST_EN_MASK, PDN_FSM_CTRL_REG); + + val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG0); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, SAFE_FREQ_WAIT_NS)); + clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG0); + + val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG1); + val |= BVAL(15, 0, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + val |= BVAL(31, 16, clk_osm_count_ns(c, PLL_WAIT_LOCK_TIME_NS)); + clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG1); + + val = clk_osm_read_reg(c, PS_BOOST_TIMER_REG2); + val |= BVAL(15, 0, clk_osm_count_ns(c, DEXT_DECREMENT_WAIT_NS)); + clk_osm_write_reg(c, val, PS_BOOST_TIMER_REG2); + } + + /* PLL signal timing control */ + if (c->boost_fsm_en || c->safe_fsm_en || c->ps_fsm_en) + clk_osm_write_reg(c, 0x5, BOOST_PROG_SYNC_DELAY_REG); + + /* Droop FSM */ + if (c->wfx_fsm_en) { + /* WFx FSM */ + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | WFX_DROOP_EN_MASK, PDN_FSM_CTRL_REG); + + val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG); + val |= BVAL(31, 16, clk_osm_count_ns(c, 500)); + clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG); + + val = clk_osm_read_reg(c, + DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); + val |= BVAL(31, 16, clk_osm_count_ns(c, 250)); + clk_osm_write_reg(c, val, + DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); + } + + /* PC/RET FSM */ + if (c->pc_fsm_en) { + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | PC_RET_EXIT_DROOP_EN_MASK, + PDN_FSM_CTRL_REG); + + val = clk_osm_read_reg(c, DROOP_UNSTALL_TIMER_CTRL_REG); + val |= BVAL(15, 0, clk_osm_count_ns(c, 500)); + clk_osm_write_reg(c, val, DROOP_UNSTALL_TIMER_CTRL_REG); + + val = clk_osm_read_reg(c, + DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); + val |= BVAL(15, 0, clk_osm_count_ns(c, 250)); + clk_osm_write_reg(c, val, + DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG); + } + + /* DCVS droop FSM - only if RCGwRC is not used for di/dt control */ + if (c->droop_fsm_en) { + val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); + clk_osm_write_reg(c, val | DCVS_DROOP_EN_MASK, + PDN_FSM_CTRL_REG); + } + + if (c->wfx_fsm_en || c->ps_fsm_en || c->droop_fsm_en) { + clk_osm_write_reg(c, 0x1, DROOP_PROG_SYNC_DELAY_REG); + clk_osm_write_reg(c, clk_osm_count_ns(c, 5), + DROOP_RELEASE_TIMER_CTRL); + clk_osm_write_reg(c, clk_osm_count_ns(c, 500), + DCVS_DROOP_TIMER_CTRL); + val = clk_osm_read_reg(c, DROOP_CTRL_REG); + val |= BIT(31) | BVAL(22, 16, 0x2) | + BVAL(6, 0, 0x8); + clk_osm_write_reg(c, val, DROOP_CTRL_REG); + } + + /* Enable the PLL Droop Override */ + val = clk_osm_read_reg(c, OSM_PLL_SW_OVERRIDE_EN); + val |= PLL_SW_OVERRIDE_DROOP_EN; + clk_osm_write_reg(c, val, OSM_PLL_SW_OVERRIDE_EN); +} + +static void clk_osm_do_additional_setup(struct clk_osm *c, + struct platform_device *pdev) +{ + if (!c->secure_init) + return; + + dev_info(&pdev->dev, "Performing additional OSM setup due to lack of TZ for cluster=%d\n", + c->cluster_num); + + clk_osm_write_reg(c, BVAL(23, 16, 0xF), SPM_CC_CTRL); + + /* PLL LVAL programming */ + clk_osm_write_reg(c, c->l_val_base, SEQ_REG(0)); + clk_osm_write_reg(c, PLL_MIN_LVAL, SEQ_REG(21)); + + /* PLL post-div programming */ + clk_osm_write_reg(c, c->apcs_pll_user_ctl, SEQ_REG(18)); + clk_osm_write_reg(c, PLL_POST_DIV2, SEQ_REG(19)); + clk_osm_write_reg(c, PLL_POST_DIV1, SEQ_REG(29)); + + /* APM Programming */ + clk_osm_program_apm_regs(c); + + /* GFMUX Programming */ + clk_osm_write_reg(c, c->apcs_cfg_rcgr, SEQ_REG(16)); + clk_osm_write_reg(c, c->apcs_cmd_rcgr, SEQ_REG(33)); + clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(34)); + clk_osm_write_reg(c, GPLL_SEL, SEQ_REG(17)); + clk_osm_write_reg(c, PLL_EARLY_SEL, SEQ_REG(82)); + clk_osm_write_reg(c, PLL_MAIN_SEL, SEQ_REG(83)); + clk_osm_write_reg(c, RCG_UPDATE_SUCCESS, SEQ_REG(84)); + clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(85)); + + /* ITM to OSM handoff */ + clk_osm_setup_itm_to_osm_handoff(); + + pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr), + ARRAY_SIZE(seq_br_instr)); + clk_osm_setup_sequencer(&pwrcl_clk); + clk_osm_setup_sequencer(&perfcl_clk); +} + +static void clk_osm_apm_vc_setup(struct clk_osm *c) +{ + /* + * APM crossover virtual corner corresponds to switching + * voltage during APM transition. APM threshold virtual + * corner is the first corner which requires switch + * sequence of APM from MX to APC. + */ + if (c->secure_init) { + clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(1)); + clk_osm_write_reg(c, c->apm_crossover_vc, SEQ_REG(72)); + clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(1), + SEQ_REG(8)); + clk_osm_write_reg(c, c->apm_threshold_vc, + SEQ_REG(15)); + clk_osm_write_reg(c, c->apm_threshold_vc != 0 ? + c->apm_threshold_vc - 1 : 0xff, + SEQ_REG(31)); + clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6, + SEQ_REG(73)); + clk_osm_write_reg(c, 0x39 | c->apm_threshold_vc << 6, + SEQ_REG(76)); + + /* Ensure writes complete before returning */ + clk_osm_mb(c, OSM_BASE); + } else { + if (msmcobalt_v1) { + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1), + c->apm_threshold_vc); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73), + 0x3b | c->apm_threshold_vc << 6); + } else if (msmcobalt_v2) { + clk_osm_write_reg(c, c->apm_threshold_vc, + SEQ_REG1_MSMCOBALT_V2); + } + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72), + c->apm_crossover_vc); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(15), + c->apm_threshold_vc); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31), + c->apm_threshold_vc != 0 ? + c->apm_threshold_vc - 1 : 0xff); + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76), + 0x39 | c->apm_threshold_vc << 6); + } +} + +static irqreturn_t clk_osm_debug_irq_cb(int irq, void *data) +{ + struct clk_osm *c = data; + unsigned long first, second, total_delta = 0; + u32 val, factor; + int i; + + val = clk_osm_read_reg(c, DCVS_PERF_STATE_DEVIATION_INTR_STAT); + if (val & BIT(0)) { + pr_info("OS DCVS performance state deviated\n"); + clk_osm_write_reg(c, BIT(0), + DCVS_PERF_STATE_DEVIATION_INTR_CLEAR); + } + + val = clk_osm_read_reg(c, + DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT); + if (val & BIT(0)) { + pr_info("OS DCVS performance state corrected\n"); + clk_osm_write_reg(c, BIT(0), + DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR); + } + + val = clk_osm_read_reg(c, DCVS_PERF_STATE_MET_INTR_STAT); + if (val & BIT(0)) { + pr_info("OS DCVS performance state desired reached\n"); + clk_osm_write_reg(c, BIT(0), DCVS_PERF_STATE_MET_INTR_CLR); + } + + factor = c->cycle_counter_factor ? c->cycle_counter_factor : 1; + + for (i = 0; i < c->cycle_counter_reads; i++) { + first = clk_osm_read_reg(c, OSM_CYCLE_COUNTER_STATUS_REG); + + if (c->cycle_counter_delay) + udelay(c->cycle_counter_delay); + + second = clk_osm_read_reg(c, OSM_CYCLE_COUNTER_STATUS_REG); + total_delta = total_delta + ((second - first) / factor); + } + + pr_info("cluster=%d, L_VAL (estimated)=%lu\n", + c->cluster_num, total_delta / c->cycle_counter_factor); + + return IRQ_HANDLED; +} + +static int clk_osm_setup_irq(struct platform_device *pdev, struct clk_osm *c, + char *irq_name) +{ + int rc = 0; + + rc = c->irq = platform_get_irq_byname(pdev, irq_name); + if (rc < 0) { + dev_err(&pdev->dev, "%s irq not specified\n", irq_name); + return rc; + } + + rc = devm_request_irq(&pdev->dev, c->irq, + clk_osm_debug_irq_cb, + IRQF_TRIGGER_RISING | IRQF_SHARED, + "OSM IRQ", c); + if (rc) + dev_err(&pdev->dev, "Request IRQ failed for OSM IRQ\n"); + + return rc; +} + +static u32 find_voltage(struct clk_osm *c, unsigned long rate) +{ + struct osm_entry *table = c->osm_table; + int entries = c->num_entries, i; + + for (i = 0; i < entries; i++) { + if (rate == table[i].frequency) { + /* OPP table voltages have units of mV */ + return table[i].open_loop_volt * 1000; + } + } + + return -EINVAL; +} + +static int add_opp(struct clk_osm *c, struct device *dev) +{ + unsigned long rate = 0; + u32 uv; + long rc; + int j = 0; + unsigned long min_rate = c->c.fmax[0]; + unsigned long max_rate = c->c.fmax[c->c.num_fmax - 1]; + + while (1) { + rate = c->c.fmax[j++]; + uv = find_voltage(c, rate); + if (uv <= 0) { + pr_warn("No voltage for %lu.\n", rate); + return -EINVAL; + } + + rc = dev_pm_opp_add(dev, rate, uv); + if (rc) { + pr_warn("failed to add OPP for %lu\n", rate); + return rc; + } + + /* + * Print the OPP pair for the lowest and highest frequency for + * each device that we're populating. This is important since + * this information will be used by thermal mitigation and the + * scheduler. + */ + if (rate == min_rate) + pr_info("Set OPP pair (%lu Hz, %d uv) on %s\n", + rate, uv, dev_name(dev)); + + if (rate == max_rate && max_rate != min_rate) { + pr_info("Set OPP pair (%lu Hz, %d uv) on %s\n", + rate, uv, dev_name(dev)); + break; + } + + if (min_rate == max_rate) + break; + } + + return 0; +} + +static struct clk *logical_cpu_to_clk(int cpu) +{ + struct device_node *cpu_node; + const u32 *cell; + u64 hwid; + static struct clk *cpu_clk_map[NR_CPUS]; + + if (cpu_clk_map[cpu]) + return cpu_clk_map[cpu]; + + cpu_node = of_get_cpu_node(cpu, NULL); + if (!cpu_node) + goto fail; + + cell = of_get_property(cpu_node, "reg", NULL); + if (!cell) { + pr_err("%s: missing reg property\n", cpu_node->full_name); + goto fail; + } + + hwid = of_read_number(cell, of_n_addr_cells(cpu_node)); + if ((hwid | pwrcl_clk.cpu_reg_mask) == pwrcl_clk.cpu_reg_mask) { + cpu_clk_map[cpu] = &pwrcl_clk.c; + return &pwrcl_clk.c; + } + if ((hwid | perfcl_clk.cpu_reg_mask) == perfcl_clk.cpu_reg_mask) { + cpu_clk_map[cpu] = &perfcl_clk.c; + return &perfcl_clk.c; + } + +fail: + return NULL; +} + +static u64 clk_osm_get_cpu_cycle_counter(int cpu) +{ + struct clk_osm *c; + u32 val; + unsigned long flags; + + if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) + c = &pwrcl_clk; + else if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) + c = &perfcl_clk; + else { + pr_err("no clock device for CPU=%d\n", cpu); + return 0; + } + + spin_lock_irqsave(&c->lock, flags); + val = clk_osm_read_reg_no_log(c, OSM_CYCLE_COUNTER_STATUS_REG); + + if (val < c->prev_cycle_counter) { + /* Handle counter overflow */ + c->total_cycle_counter += UINT_MAX - + c->prev_cycle_counter + val; + c->prev_cycle_counter = val; + } else { + c->total_cycle_counter += val - c->prev_cycle_counter; + c->prev_cycle_counter = val; + } + spin_unlock_irqrestore(&c->lock, flags); + + return c->total_cycle_counter; +} + +static void populate_opp_table(struct platform_device *pdev) +{ + int cpu; + + for_each_possible_cpu(cpu) { + if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) { + WARN(add_opp(&pwrcl_clk, get_cpu_device(cpu)), + "Failed to add OPP levels for power cluster\n"); + } + if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) { + WARN(add_opp(&perfcl_clk, get_cpu_device(cpu)), + "Failed to add OPP levels for perf cluster\n"); + } + } +} + +static int debugfs_get_trace_enable(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = c->trace_en; + return 0; +} + +static int debugfs_set_trace_enable(void *data, u64 val) +{ + struct clk_osm *c = data; + + clk_osm_masked_write_reg(c, val ? TRACE_CTRL_ENABLE : + TRACE_CTRL_DISABLE, + TRACE_CTRL, TRACE_CTRL_EN_MASK); + c->trace_en = val ? true : false; + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_trace_enable_fops, + debugfs_get_trace_enable, + debugfs_set_trace_enable, + "%llu\n"); + +static int debugfs_get_wdog_trace(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = c->wdog_trace_en; + return 0; +} + +static int debugfs_set_wdog_trace(void *data, u64 val) +{ + struct clk_osm *c = data; + int regval; + + if (c->version >= VERSION_1P1) { + regval = clk_osm_read_reg(c, TRACE_CTRL); + regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : + regval & ~TRACE_CTRL_ENABLE_WDOG_STATUS; + clk_osm_write_reg(c, regval, TRACE_CTRL); + c->wdog_trace_en = val ? true : false; + } else { + pr_info("wdog status registers enabled by default\n"); + } + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_trace_wdog_enable_fops, + debugfs_get_wdog_trace, + debugfs_set_wdog_trace, + "%llu\n"); + +#define MAX_DEBUG_BUF_LEN 15 + +static DEFINE_MUTEX(debug_buf_mutex); +static char debug_buf[MAX_DEBUG_BUF_LEN]; + +static ssize_t debugfs_trace_method_set(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct clk_osm *c = file->private_data; + u32 val; + + if (IS_ERR(file) || file == NULL) { + pr_err("input error %ld\n", PTR_ERR(file)); + return -EINVAL; + } + + if (!c) { + pr_err("invalid clk_osm handle\n"); + return -EINVAL; + } + + if (count < MAX_DEBUG_BUF_LEN) { + mutex_lock(&debug_buf_mutex); + + if (copy_from_user(debug_buf, (void __user *) buf, count)) { + mutex_unlock(&debug_buf_mutex); + return -EFAULT; + } + debug_buf[count] = '\0'; + mutex_unlock(&debug_buf_mutex); + + /* check that user entered a supported packet type */ + if (strcmp(debug_buf, "periodic\n") == 0) { + clk_osm_write_reg(c, clk_osm_count_ns(c, + PERIODIC_TRACE_DEFAULT_NS), + PERIODIC_TRACE_TIMER_CTRL); + clk_osm_masked_write_reg(c, + TRACE_CTRL_PERIODIC_TRACE_ENABLE, + TRACE_CTRL, TRACE_CTRL_PERIODIC_TRACE_EN_MASK); + c->trace_method = PERIODIC_PACKET; + c->trace_periodic_timer = PERIODIC_TRACE_DEFAULT_NS; + return count; + } else if (strcmp(debug_buf, "xor\n") == 0) { + val = clk_osm_read_reg(c, TRACE_CTRL); + val &= ~TRACE_CTRL_PERIODIC_TRACE_ENABLE; + clk_osm_write_reg(c, val, TRACE_CTRL); + c->trace_method = XOR_PACKET; + return count; + } + } + + pr_err("error, supported trace mode types: 'periodic' or 'xor'\n"); + return -EINVAL; +} + +static ssize_t debugfs_trace_method_get(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct clk_osm *c = file->private_data; + int len, rc; + + if (IS_ERR(file) || file == NULL) { + pr_err("input error %ld\n", PTR_ERR(file)); + return -EINVAL; + } + + if (!c) { + pr_err("invalid clk_osm handle\n"); + return -EINVAL; + } + + mutex_lock(&debug_buf_mutex); + + if (c->trace_method == PERIODIC_PACKET) + len = snprintf(debug_buf, sizeof(debug_buf), "periodic\n"); + else if (c->trace_method == XOR_PACKET) + len = snprintf(debug_buf, sizeof(debug_buf), "xor\n"); + + rc = simple_read_from_buffer((void __user *) buf, len, ppos, + (void *) debug_buf, len); + + mutex_unlock(&debug_buf_mutex); + + return rc; +} + +static int debugfs_trace_method_open(struct inode *inode, struct file *file) +{ + if (IS_ERR(file) || file == NULL) { + pr_err("input error %ld\n", PTR_ERR(file)); + return -EINVAL; + } + + file->private_data = inode->i_private; + return 0; +} + +static const struct file_operations debugfs_trace_method_fops = { + .write = debugfs_trace_method_set, + .open = debugfs_trace_method_open, + .read = debugfs_trace_method_get, +}; + +static int debugfs_get_trace_packet_id(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = c->trace_id; + return 0; +} + +static int debugfs_set_trace_packet_id(void *data, u64 val) +{ + struct clk_osm *c = data; + + if (val < TRACE_PACKET0 || val > TRACE_PACKET3) { + pr_err("supported trace IDs=%d-%d\n", + TRACE_PACKET0, TRACE_PACKET3); + return 0; + } + + clk_osm_masked_write_reg(c, val << TRACE_CTRL_PACKET_TYPE_SHIFT, + TRACE_CTRL, TRACE_CTRL_PACKET_TYPE_MASK); + c->trace_id = val; + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_trace_packet_id_fops, + debugfs_get_trace_packet_id, + debugfs_set_trace_packet_id, + "%llu\n"); + +static int debugfs_get_trace_periodic_timer(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = c->trace_periodic_timer; + return 0; +} + +static int debugfs_set_trace_periodic_timer(void *data, u64 val) +{ + struct clk_osm *c = data; + + if (val < PERIODIC_TRACE_MIN_NS || val > PERIODIC_TRACE_MAX_NS) { + pr_err("supported periodic trace periods=%d-%ld ns\n", + PERIODIC_TRACE_MIN_NS, PERIODIC_TRACE_MAX_NS); + return 0; + } + + clk_osm_write_reg(c, clk_osm_count_ns(c, val), + PERIODIC_TRACE_TIMER_CTRL); + c->trace_periodic_timer = val; + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_trace_periodic_timer_fops, + debugfs_get_trace_periodic_timer, + debugfs_set_trace_periodic_timer, + "%llu\n"); + +static int debugfs_get_perf_state_met_irq(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = clk_osm_read_reg(c, DCVS_PERF_STATE_MET_INTR_EN); + return 0; +} + +static int debugfs_set_perf_state_met_irq(void *data, u64 val) +{ + struct clk_osm *c = data; + + clk_osm_write_reg(c, val ? 1 : 0, + DCVS_PERF_STATE_MET_INTR_EN); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_perf_state_met_irq_fops, + debugfs_get_perf_state_met_irq, + debugfs_set_perf_state_met_irq, + "%llu\n"); + +static int debugfs_get_perf_state_deviation_irq(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = clk_osm_read_reg(c, + DCVS_PERF_STATE_DEVIATION_INTR_EN); + return 0; +} + +static int debugfs_set_perf_state_deviation_irq(void *data, u64 val) +{ + struct clk_osm *c = data; + + clk_osm_write_reg(c, val ? 1 : 0, + DCVS_PERF_STATE_DEVIATION_INTR_EN); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_perf_state_deviation_irq_fops, + debugfs_get_perf_state_deviation_irq, + debugfs_set_perf_state_deviation_irq, + "%llu\n"); + +static int debugfs_get_perf_state_deviation_corrected_irq(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = clk_osm_read_reg(c, + DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN); + return 0; +} + +static int debugfs_set_perf_state_deviation_corrected_irq(void *data, u64 val) +{ + struct clk_osm *c = data; + + clk_osm_write_reg(c, val ? 1 : 0, + DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_perf_state_deviation_corrected_irq_fops, + debugfs_get_perf_state_deviation_corrected_irq, + debugfs_set_perf_state_deviation_corrected_irq, + "%llu\n"); + +static int debugfs_get_debug_reg(void *data, u64 *val) +{ + struct clk_osm *c = data; + + if (c->acd_debugfs_addr >= ACD_MASTER_ONLY_REG_ADDR) + *val = readl_relaxed((char *)c->vbases[ACD_BASE] + + c->acd_debugfs_addr); + else + *val = clk_osm_acd_local_read_reg(c, c->acd_debugfs_addr); + return 0; +} + +static int debugfs_set_debug_reg(void *data, u64 val) +{ + struct clk_osm *c = data; + + if (c->acd_debugfs_addr >= ACD_MASTER_ONLY_REG_ADDR) + clk_osm_acd_master_write_reg(c, val, c->acd_debugfs_addr); + else + clk_osm_acd_master_write_through_reg(c, val, + c->acd_debugfs_addr); + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_acd_debug_reg_fops, + debugfs_get_debug_reg, + debugfs_set_debug_reg, + "0x%llx\n"); + +static int debugfs_get_debug_reg_addr(void *data, u64 *val) +{ + struct clk_osm *c = data; + + *val = c->acd_debugfs_addr; + return 0; +} + +static int debugfs_set_debug_reg_addr(void *data, u64 val) +{ + struct clk_osm *c = data; + + c->acd_debugfs_addr = val; + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debugfs_acd_debug_reg_addr_fops, + debugfs_get_debug_reg_addr, + debugfs_set_debug_reg_addr, + "%llu\n"); + +static void populate_debugfs_dir(struct clk_osm *c) +{ + struct dentry *temp; + + if (osm_debugfs_base == NULL) { + osm_debugfs_base = debugfs_create_dir("osm", NULL); + if (IS_ERR_OR_NULL(osm_debugfs_base)) { + pr_err("osm debugfs base directory creation failed\n"); + osm_debugfs_base = NULL; + return; + } + } + + c->debugfs = debugfs_create_dir(c->c.dbg_name, osm_debugfs_base); + if (IS_ERR_OR_NULL(c->debugfs)) { + pr_err("osm debugfs directory creation failed\n"); + return; + } + + temp = debugfs_create_file("perf_state_met_irq_enable", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_perf_state_met_irq_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("perf_state_met_irq_enable debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("perf_state_deviation_irq_enable", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_perf_state_deviation_irq_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("perf_state_deviation_irq_enable debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("perf_state_deviation_corrected_irq_enable", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_perf_state_deviation_corrected_irq_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_perf_state_deviation_corrected_irq_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("wdog_trace_enable", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_trace_wdog_enable_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_trace_wdog_enable_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("trace_enable", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_trace_enable_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_trace_enable_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("trace_method", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_trace_method_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_trace_method_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("trace_packet_id", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_trace_packet_id_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_trace_packet_id_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("trace_periodic_timer", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_trace_periodic_timer_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_trace_periodic_timer_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("acd_debug_reg", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_acd_debug_reg_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_acd_debug_reg_fops debugfs file creation failed\n"); + goto exit; + } + + temp = debugfs_create_file("acd_debug_reg_addr", + S_IRUGO | S_IWUSR, + c->debugfs, c, + &debugfs_acd_debug_reg_addr_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("debugfs_acd_debug_reg_addr_fops debugfs file creation failed\n"); + goto exit; + } + +exit: + if (IS_ERR_OR_NULL(temp)) + debugfs_remove_recursive(c->debugfs); +} + +static int clk_osm_panic_callback(struct notifier_block *nfb, + unsigned long event, + void *data) +{ + void __iomem *virt_addr; + u32 value, reg; + struct clk_osm *c = container_of(nfb, + struct clk_osm, + panic_notifier); + + reg = c->pbases[OSM_BASE] + WDOG_DOMAIN_PSTATE_STATUS; + virt_addr = ioremap(reg, 0x4); + if (virt_addr != NULL) { + value = readl_relaxed(virt_addr); + pr_err("DOM%d_PSTATE_STATUS[0x%08x]=0x%08x\n", c->cluster_num, + reg, value); + iounmap(virt_addr); + } + + reg = c->pbases[OSM_BASE] + WDOG_PROGRAM_COUNTER; + virt_addr = ioremap(reg, 0x4); + if (virt_addr != NULL) { + value = readl_relaxed(virt_addr); + pr_err("DOM%d_PROGRAM_COUNTER[0x%08x]=0x%08x\n", c->cluster_num, + reg, value); + iounmap(virt_addr); + } + + virt_addr = ioremap(c->apm_ctrl_status, 0x4); + if (virt_addr != NULL) { + value = readl_relaxed(virt_addr); + pr_err("APM_CTLER_STATUS_%d[0x%08x]=0x%08x\n", c->cluster_num, + c->apm_ctrl_status, value); + iounmap(virt_addr); + } + + return NOTIFY_OK; +} + +static int clk_osm_acd_init(struct clk_osm *c) +{ + + int rc = 0; + u32 auto_xfer_mask = 0; + + if (!c->acd_init) + return 0; + + c->acd_debugfs_addr = ACD_HW_VERSION; + + /* Program ACD tunable-length delay register */ + clk_osm_acd_master_write_reg(c, c->acd_td, ACDTD); + auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDTD); + + /* Program ACD control register */ + clk_osm_acd_master_write_reg(c, c->acd_cr, ACDCR); + auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDCR); + + /* Program ACD soft start control register */ + clk_osm_acd_master_write_reg(c, c->acd_sscr, ACDSSCR); + auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDSSCR); + + /* Program initial ACD external interface configuration register */ + clk_osm_acd_master_write_reg(c, c->acd_extint0_cfg, ACD_EXTINT_CFG); + auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_EXTINT_CFG); + + /* Program ACD auto-register transfer control register */ + clk_osm_acd_master_write_reg(c, c->acd_autoxfer_ctl, ACD_AUTOXFER_CTL); + + /* Ensure writes complete before transfers to local copy */ + clk_osm_acd_mb(c); + + /* Transfer master copies */ + rc = clk_osm_acd_auto_local_write_reg(c, auto_xfer_mask); + if (rc) + return rc; + + /* Switch CPUSS clock source to ACD clock */ + rc = clk_osm_acd_master_write_through_reg(c, ACD_GFMUX_CFG_SELECT, + ACD_GFMUX_CFG); + if (rc) + return rc; + + /* Program ACD_DCVS_SW */ + rc = clk_osm_acd_master_write_through_reg(c, + ACD_DCVS_SW_DCVS_IN_PRGR_SET, + ACD_DCVS_SW); + if (rc) + return rc; + + rc = clk_osm_acd_master_write_through_reg(c, + ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR, + ACD_DCVS_SW); + if (rc) + return rc; + + udelay(1); + + /* Program final ACD external interface configuration register */ + rc = clk_osm_acd_master_write_through_reg(c, c->acd_extint1_cfg, + ACD_EXTINT_CFG); + if (rc) + return rc; + + /* + * ACDCR, ACDTD, ACDSSCR, ACD_EXTINT_CFG, ACD_GFMUX_CFG + * must be copied from master to local copy on PC exit. + */ + auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_GFMUX_CFG); + clk_osm_acd_master_write_reg(c, auto_xfer_mask, ACD_AUTOXFER_CFG); + + return 0; +} + +static unsigned long init_rate = 300000000; +static unsigned long osm_clk_init_rate = 200000000; + +static int cpu_clock_osm_driver_probe(struct platform_device *pdev) +{ + int rc, cpu; + int speedbin = 0, pvs_ver = 0; + u32 pte_efuse; + char pwrclspeedbinstr[] = "qcom,pwrcl-speedbin0-v0"; + char perfclspeedbinstr[] = "qcom,perfcl-speedbin0-v0"; + struct cpu_cycle_counter_cb cb = { + .get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter, + }; + + if (of_find_compatible_node(NULL, NULL, + "qcom,cpu-clock-osm-msmcobalt-v1")) { + msmcobalt_v1 = true; + } else if (of_find_compatible_node(NULL, NULL, + "qcom,cpu-clock-osm-msmcobalt-v2")) { + msmcobalt_v2 = true; + } + + rc = clk_osm_resources_init(pdev); + if (rc) { + if (rc != -EPROBE_DEFER) + dev_err(&pdev->dev, "resources init failed, rc=%d\n", + rc); + return rc; + } + + rc = clk_osm_parse_dt_configs(pdev); + if (rc) { + dev_err(&pdev->dev, "Unable to parse device tree configurations\n"); + return rc; + } + + if ((pwrcl_clk.secure_init || perfcl_clk.secure_init) && + msmcobalt_v2) { + pr_err("unsupported configuration for msmcobalt v2\n"); + return -EINVAL; + } + + if (pwrcl_clk.vbases[EFUSE_BASE]) { + /* Multiple speed-bins are supported */ + pte_efuse = readl_relaxed(pwrcl_clk.vbases[EFUSE_BASE]); + speedbin = ((pte_efuse >> PWRCL_EFUSE_SHIFT) & + PWRCL_EFUSE_MASK); + snprintf(pwrclspeedbinstr, ARRAY_SIZE(pwrclspeedbinstr), + "qcom,pwrcl-speedbin%d-v%d", speedbin, pvs_ver); + } + + dev_info(&pdev->dev, "using pwrcl speed bin %u and pvs_ver %d\n", + speedbin, pvs_ver); + + rc = clk_osm_get_lut(pdev, &pwrcl_clk, + pwrclspeedbinstr); + if (rc) { + dev_err(&pdev->dev, "Unable to get OSM LUT for power cluster, rc=%d\n", + rc); + return rc; + } + + if (perfcl_clk.vbases[EFUSE_BASE]) { + /* Multiple speed-bins are supported */ + pte_efuse = readl_relaxed(perfcl_clk.vbases[EFUSE_BASE]); + speedbin = ((pte_efuse >> PERFCL_EFUSE_SHIFT) & + PERFCL_EFUSE_MASK); + snprintf(perfclspeedbinstr, ARRAY_SIZE(perfclspeedbinstr), + "qcom,perfcl-speedbin%d-v%d", speedbin, pvs_ver); + } + + dev_info(&pdev->dev, "using perfcl speed bin %u and pvs_ver %d\n", + speedbin, pvs_ver); + + rc = clk_osm_get_lut(pdev, &perfcl_clk, perfclspeedbinstr); + if (rc) { + dev_err(&pdev->dev, "Unable to get OSM LUT for perf cluster, rc=%d\n", + rc); + return rc; + } + + rc = clk_osm_resolve_open_loop_voltages(&pwrcl_clk); + if (rc) { + if (rc == -EPROBE_DEFER) + return rc; + dev_err(&pdev->dev, "Unable to determine open-loop voltages for power cluster, rc=%d\n", + rc); + return rc; + } + + rc = clk_osm_resolve_open_loop_voltages(&perfcl_clk); + if (rc) { + if (rc == -EPROBE_DEFER) + return rc; + dev_err(&pdev->dev, "Unable to determine open-loop voltages for perf cluster, rc=%d\n", + rc); + return rc; + } + + rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev); + if (rc) + dev_info(&pdev->dev, "No APM crossover corner programmed\n"); + + rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev); + if (rc) + dev_info(&pdev->dev, "No APM crossover corner programmed\n"); + + clk_osm_setup_cycle_counters(&pwrcl_clk); + clk_osm_setup_cycle_counters(&perfcl_clk); + + clk_osm_print_osm_table(&pwrcl_clk); + clk_osm_print_osm_table(&perfcl_clk); + + rc = clk_osm_setup_hw_table(&pwrcl_clk); + if (rc) { + dev_err(&pdev->dev, "failed to setup power cluster hardware table\n"); + goto exit; + } + rc = clk_osm_setup_hw_table(&perfcl_clk); + if (rc) { + dev_err(&pdev->dev, "failed to setup perf cluster hardware table\n"); + goto exit; + } + + /* Policy tuning */ + rc = clk_osm_set_cc_policy(pdev); + if (rc < 0) { + dev_err(&pdev->dev, "cc policy setup failed"); + goto exit; + } + + /* LLM Freq Policy Tuning */ + rc = clk_osm_set_llm_freq_policy(pdev); + if (rc < 0) { + dev_err(&pdev->dev, "LLM Frequency Policy setup failed"); + goto exit; + } + + /* LLM Voltage Policy Tuning */ + rc = clk_osm_set_llm_volt_policy(pdev); + if (rc < 0) { + dev_err(&pdev->dev, "Failed to set LLM voltage Policy"); + goto exit; + } + + clk_osm_setup_fsms(&pwrcl_clk); + clk_osm_setup_fsms(&perfcl_clk); + + /* + * Perform typical secure-world HW initialization + * as necessary. + */ + clk_osm_do_additional_setup(&pwrcl_clk, pdev); + clk_osm_do_additional_setup(&perfcl_clk, pdev); + + /* MEM-ACC Programming */ + clk_osm_program_mem_acc_regs(&pwrcl_clk); + clk_osm_program_mem_acc_regs(&perfcl_clk); + + /* Program APM crossover corners */ + clk_osm_apm_vc_setup(&pwrcl_clk); + clk_osm_apm_vc_setup(&perfcl_clk); + + rc = clk_osm_setup_irq(pdev, &pwrcl_clk, "pwrcl-irq"); + if (rc) + pr_err("Debug IRQ not set for pwrcl\n"); + + rc = clk_osm_setup_irq(pdev, &perfcl_clk, "perfcl-irq"); + if (rc) + pr_err("Debug IRQ not set for perfcl\n"); + + clk_osm_setup_osm_was(&pwrcl_clk); + clk_osm_setup_osm_was(&perfcl_clk); + + if (of_property_read_bool(pdev->dev.of_node, + "qcom,osm-pll-setup")) { + clk_osm_setup_cluster_pll(&pwrcl_clk); + clk_osm_setup_cluster_pll(&perfcl_clk); + } + + rc = clk_osm_acd_init(&pwrcl_clk); + if (rc) { + pr_err("failed to initialize ACD for pwrcl, rc=%d\n", rc); + return rc; + } + rc = clk_osm_acd_init(&perfcl_clk); + if (rc) { + pr_err("failed to initialize ACD for perfcl, rc=%d\n", rc); + return rc; + } + + spin_lock_init(&pwrcl_clk.lock); + spin_lock_init(&perfcl_clk.lock); + + pwrcl_clk.panic_notifier.notifier_call = clk_osm_panic_callback; + atomic_notifier_chain_register(&panic_notifier_list, + &pwrcl_clk.panic_notifier); + perfcl_clk.panic_notifier.notifier_call = clk_osm_panic_callback; + atomic_notifier_chain_register(&panic_notifier_list, + &perfcl_clk.panic_notifier); + + rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_osm, + ARRAY_SIZE(cpu_clocks_osm)); + if (rc) { + dev_err(&pdev->dev, "Unable to register CPU clocks, rc=%d\n", + rc); + return rc; + } + + /* + * The hmss_gpll0 clock runs at 300 MHz. Ensure it is at the correct + * frequency before enabling OSM. LUT index 0 is always sourced from + * this clock. + */ + rc = clk_set_rate(&sys_apcsaux_clk_gcc.c, init_rate); + if (rc) { + dev_err(&pdev->dev, "Unable to set init rate on hmss_gpll0, rc=%d\n", + rc); + return rc; + } + clk_prepare_enable(&sys_apcsaux_clk_gcc.c); + + rc = clk_set_rate(&osm_clk_src.c, osm_clk_init_rate); + if (rc) { + dev_err(&pdev->dev, "Unable to set init rate on osm_clk, rc=%d\n", + rc); + goto exit2; + } + + /* Make sure index zero is selected */ + rc = clk_set_rate(&pwrcl_clk.c, init_rate); + if (rc) { + dev_err(&pdev->dev, "Unable to set init rate on pwr cluster, rc=%d\n", + rc); + goto exit2; + } + + rc = clk_set_rate(&perfcl_clk.c, init_rate); + if (rc) { + dev_err(&pdev->dev, "Unable to set init rate on perf cluster, rc=%d\n", + rc); + goto exit2; + } + + get_online_cpus(); + + /* Enable OSM */ + for_each_online_cpu(cpu) { + WARN(clk_prepare_enable(logical_cpu_to_clk(cpu)), + "Failed to enable clock for cpu %d\n", cpu); + } + + /* Set final boot rate */ + rc = clk_set_rate(&pwrcl_clk.c, msmcobalt_v1 ? + MSMCOBALTV1_PWRCL_BOOT_RATE : + MSMCOBALTV2_PWRCL_BOOT_RATE); + if (rc) { + dev_err(&pdev->dev, "Unable to set boot rate on pwr cluster, rc=%d\n", + rc); + goto exit2; + } + + rc = clk_set_rate(&perfcl_clk.c, msmcobalt_v1 ? + MSMCOBALTV1_PERFCL_BOOT_RATE : + MSMCOBALTV2_PERFCL_BOOT_RATE); + if (rc) { + dev_err(&pdev->dev, "Unable to set boot rate on perf cluster, rc=%d\n", + rc); + goto exit2; + } + + pwrcl_clk.version = clk_osm_read_reg(&pwrcl_clk, VERSION_REG); + perfcl_clk.version = clk_osm_read_reg(&perfcl_clk, VERSION_REG); + + populate_opp_table(pdev); + populate_debugfs_dir(&pwrcl_clk); + populate_debugfs_dir(&perfcl_clk); + + of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + + register_cpu_cycle_counter_cb(&cb); + + pr_info("OSM driver inited\n"); + put_online_cpus(); + + return 0; + +exit2: + clk_disable_unprepare(&sys_apcsaux_clk_gcc.c); +exit: + dev_err(&pdev->dev, "OSM driver failed to initialize, rc=%d\n", + rc); + panic("Unable to Setup OSM"); +} + +static const struct of_device_id match_table[] = { + { .compatible = "qcom,cpu-clock-osm-msmcobalt-v1" }, + { .compatible = "qcom,cpu-clock-osm-msmcobalt-v2" }, + {} +}; + +static struct platform_driver cpu_clock_osm_driver = { + .probe = cpu_clock_osm_driver_probe, + .driver = { + .name = "cpu-clock-osm", + .of_match_table = match_table, + .owner = THIS_MODULE, + }, +}; + +static int __init cpu_clock_osm_init(void) +{ + return platform_driver_register(&cpu_clock_osm_driver); +} +arch_initcall(cpu_clock_osm_init); + +static void __exit cpu_clock_osm_exit(void) +{ + platform_driver_unregister(&cpu_clock_osm_driver); +} +module_exit(cpu_clock_osm_exit); + +MODULE_DESCRIPTION("CPU clock driver for OSM"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index da02ab499bff..4589a3b6cec6 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -24,6 +24,7 @@ struct freq_tbl { u16 m; u16 n; unsigned long src_freq; +#define FIXED_FREQ_SRC 0 }; /** diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 6d12ddb3e245..48ff5ea00040 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -232,9 +232,10 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, struct clk_rate_request *req) { unsigned long clk_flags, rate = req->rate; + struct clk_rate_request parent_req = { }; struct clk_hw *p; struct clk_rcg2 *rcg = to_clk_rcg2(hw); - int index; + int index, ret = 0; f = qcom_find_freq(f, rate); if (!f) @@ -265,6 +266,21 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, req->best_parent_rate = rate; req->rate = f->freq; + if (f->src_freq != FIXED_FREQ_SRC) { + rate = parent_req.rate = f->src_freq; + parent_req.best_parent_hw = p; + ret = __clk_determine_rate(p, &parent_req); + if (ret) + return ret; + + ret = clk_set_rate(p->clk, parent_req.rate); + if (ret) { + pr_err("Failed set rate(%lu) on parent for non-fixed source\n", + parent_req.rate); + return ret; + } + } + return 0; } @@ -317,6 +333,53 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) return update_config(rcg); } +static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int i = 0, size = 0, val; + + static struct clk_register_data data[] = { + {"CMD_RCGR", 0x0}, + {"CFG_RCGR", 0x4}, + }; + + static struct clk_register_data data1[] = { + {"CMD_RCGR", 0x0}, + {"CFG_RCGR", 0x4}, + {"M_VAL", 0x8}, + {"N_VAL", 0xC}, + {"D_VAL", 0x10}, + }; + + if (rcg->mnd_width) { + size = ARRAY_SIZE(data1); + for (i = 0; i < size; i++) { + regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr + + data1[i].offset), &val); + seq_printf(f, "%20s: 0x%.8x\n", data1[i].name, val); + } + } else { + size = ARRAY_SIZE(data); + for (i = 0; i < size; i++) { + regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr + + data[i].offset), &val); + seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val); + } + } +} + +/* Return the nth supported frequency for a given clock. */ +static long clk_rcg2_list_rate(struct clk_hw *hw, unsigned n, + unsigned long fmax) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + + if (!rcg->freq_tbl) + return -ENXIO; + + return (rcg->freq_tbl + n)->freq; +} + static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); @@ -351,6 +414,8 @@ const struct clk_ops clk_rcg2_ops = { .determine_rate = clk_rcg2_determine_rate, .set_rate = clk_rcg2_set_rate, .set_rate_and_parent = clk_rcg2_set_rate_and_parent, + .list_rate = clk_rcg2_list_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); @@ -557,6 +622,7 @@ const struct clk_ops clk_edp_pixel_ops = { .set_rate = clk_edp_pixel_set_rate, .set_rate_and_parent = clk_edp_pixel_set_rate_and_parent, .determine_rate = clk_edp_pixel_determine_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_edp_pixel_ops); @@ -615,6 +681,7 @@ const struct clk_ops clk_byte_ops = { .set_rate = clk_byte_set_rate, .set_rate_and_parent = clk_byte_set_rate_and_parent, .determine_rate = clk_byte_determine_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_byte_ops); @@ -685,6 +752,7 @@ const struct clk_ops clk_byte2_ops = { .set_rate = clk_byte2_set_rate, .set_rate_and_parent = clk_byte2_set_rate_and_parent, .determine_rate = clk_byte2_determine_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_byte2_ops); @@ -775,6 +843,7 @@ const struct clk_ops clk_pixel_ops = { .set_rate = clk_pixel_set_rate, .set_rate_and_parent = clk_pixel_set_rate_and_parent, .determine_rate = clk_pixel_determine_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_pixel_ops); @@ -864,6 +933,7 @@ const struct clk_ops clk_gfx3d_ops = { .set_rate = clk_gfx3d_set_rate, .set_rate_and_parent = clk_gfx3d_set_rate_and_parent, .determine_rate = clk_gfx3d_determine_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_gfx3d_ops); @@ -944,5 +1014,7 @@ const struct clk_ops clk_gfx3d_src_ops = { .set_rate = clk_gfx3d_set_rate, .set_rate_and_parent = clk_gfx3d_src_set_rate_and_parent, .determine_rate = clk_gfx3d_src_determine_rate, + .list_rate = clk_rcg2_list_rate, + .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_gfx3d_src_ops); diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h index 491a63d537df..8663dea02d79 100644 --- a/drivers/clk/qcom/clk-regmap.h +++ b/drivers/clk/qcom/clk-regmap.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 software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -15,6 +15,7 @@ #define __QCOM_CLK_REGMAP_H__ #include <linux/clk-provider.h> +#include <linux/debugfs.h> struct regmap; @@ -42,4 +43,9 @@ void clk_disable_regmap(struct clk_hw *hw); struct clk * devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); +struct clk_register_data { + char *name; + u32 offset; +}; + #endif diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index bc982c9bfa71..c6ea293a8df3 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -250,7 +250,8 @@ static int clk_smd_rpm_set_rate_sleep(struct clk_smd_rpm *r, static void to_active_sleep(struct clk_smd_rpm *r, unsigned long rate, unsigned long *active, unsigned long *sleep) { - *active = rate; + /* Convert the rate (hz) to khz */ + *active = DIV_ROUND_UP(rate, 1000); /* * Active-only clocks don't care what the rate is during sleep. So, @@ -533,9 +534,9 @@ DEFINE_CLK_SMD_RPM(msm8996, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); DEFINE_CLK_SMD_RPM(msm8996, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); DEFINE_CLK_SMD_RPM_BRANCH(msm8996, cxo, cxo_a, QCOM_SMD_RPM_MISC_CLK, 0, 19200000); DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre1_noc_clk, aggre1_noc_a_clk, - QCOM_SMD_RPM_AGGR_CLK, 0, 1000); -DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 1, 1000); +DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk, + QCOM_SMD_RPM_AGGR_CLK, 2, 1000); DEFINE_CLK_SMD_RPM_QDSS(msm8996, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk1, bb_clk1_a, 1); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk2, bb_clk2_a, 2); @@ -544,7 +545,7 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk2, rf_clk2_a, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, ln_bb_clk, ln_bb_a_clk, 8); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk1, div_clk1_ao, 0xb); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk2, div_clk2_ao, 0xc); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_ao, 0xc); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_ao, 0xd); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk1_pin, bb_clk1_a_pin, 1); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4); @@ -613,13 +614,13 @@ DEFINE_CLK_SMD_RPM(msmfalcon, aggre2_noc_clk, aggre2_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 2); DEFINE_CLK_SMD_RPM_QDSS(msmfalcon, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, rf_clk2, rf_clk2_ao, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, rf_clk1, rf_clk1_ao, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, div_clk1, div_clk1_ao, 0xb); DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, ln_bb_clk1, ln_bb_clk1_ao, 0x1); DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, ln_bb_clk2, ln_bb_clk2_ao, 0x2); DEFINE_CLK_SMD_RPM_XO_BUFFER(msmfalcon, ln_bb_clk3, ln_bb_clk3_ao, 0x3); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, rf_clk2_pin, rf_clk2_a_pin, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, rf_clk1_pin, rf_clk1_ao_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk1_pin, ln_bb_clk1_pin_ao, 0x1); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk2_pin, @@ -656,8 +657,10 @@ static struct clk_hw *msmfalcon_clks[] = { [RPM_BIMC_A_CLK] = &msmfalcon_bimc_a_clk.hw, [RPM_QDSS_CLK] = &msmfalcon_qdss_clk.hw, [RPM_QDSS_A_CLK] = &msmfalcon_qdss_a_clk.hw, - [RPM_RF_CLK2_PIN] = &msmfalcon_rf_clk2_pin.hw, - [RPM_RF_CLK2_A_PIN] = &msmfalcon_rf_clk2_a_pin.hw, + [RPM_RF_CLK1] = &msmfalcon_rf_clk1.hw, + [RPM_RF_CLK1_A] = &msmfalcon_rf_clk1_ao.hw, + [RPM_RF_CLK1_PIN] = &msmfalcon_rf_clk1_pin.hw, + [RPM_RF_CLK1_A_PIN] = &msmfalcon_rf_clk1_ao_pin.hw, [RPM_AGGR2_NOC_CLK] = &msmfalcon_aggre2_noc_clk.hw, [RPM_AGGR2_NOC_A_CLK] = &msmfalcon_aggre2_noc_a_clk.hw, [RPM_CNOC_CLK] = &msmfalcon_cnoc_clk.hw, diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll.h b/drivers/clk/qcom/mdss/mdss-dsi-pll.h index f88ae4d0eea1..286c99e339c6 100644 --- a/drivers/clk/qcom/mdss/mdss-dsi-pll.h +++ b/drivers/clk/qcom/mdss/mdss-dsi-pll.h @@ -58,7 +58,7 @@ int dsi_pll_clock_register_lpm(struct platform_device *pdev, struct mdss_pll_resources *pll_res); int dsi_pll_clock_register_8996(struct platform_device *pdev, struct mdss_pll_resources *pll_res); -int dsi_pll_clock_register_cobalt(struct platform_device *pdev, +int dsi_pll_clock_register_8998(struct platform_device *pdev, struct mdss_pll_resources *pll_res); int set_byte_mux_sel(struct mux_clk *clk, int sel); diff --git a/drivers/clk/qcom/mdss/mdss-hdmi-pll.h b/drivers/clk/qcom/mdss/mdss-hdmi-pll.h index d4226bf43e13..19f9b925644a 100644 --- a/drivers/clk/qcom/mdss/mdss-hdmi-pll.h +++ b/drivers/clk/qcom/mdss/mdss-hdmi-pll.h @@ -56,6 +56,6 @@ int hdmi_8996_v3_pll_clock_register(struct platform_device *pdev, int hdmi_8996_v3_1p8_pll_clock_register(struct platform_device *pdev, struct mdss_pll_resources *pll_res); -int hdmi_cobalt_pll_clock_register(struct platform_device *pdev, +int hdmi_8998_pll_clock_register(struct platform_device *pdev, struct mdss_pll_resources *pll_res); #endif diff --git a/drivers/clk/qcom/mdss/mdss-pll.c b/drivers/clk/qcom/mdss/mdss-pll.c index e91e9c9dc768..8264d2e5a3cd 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.c +++ b/drivers/clk/qcom/mdss/mdss-pll.c @@ -136,10 +136,10 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, pll_res->pll_interface_type = MDSS_DSI_PLL_8996; pll_res->target_id = MDSS_PLL_TARGET_8996; pll_res->revision = 2; - } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_DSI_PLL_COBALT; - } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_DP_PLL_COBALT; + } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_8998")) { + pll_res->pll_interface_type = MDSS_DSI_PLL_8998; + } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_8998")) { + pll_res->pll_interface_type = MDSS_DP_PLL_8998; } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996")) { pll_res->pll_interface_type = MDSS_HDMI_PLL_8996; } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996_v2")) { @@ -149,8 +149,8 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8996_v3_1p8")) { pll_res->pll_interface_type = MDSS_HDMI_PLL_8996_V3_1_8; - } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_cobalt")) { - pll_res->pll_interface_type = MDSS_HDMI_PLL_COBALT; + } else if (!strcmp(compatible_stream, "qcom,mdss_hdmi_pll_8998")) { + pll_res->pll_interface_type = MDSS_HDMI_PLL_8998; } else { goto err; } @@ -177,10 +177,10 @@ static int mdss_pll_clock_register(struct platform_device *pdev, case MDSS_DSI_PLL_8996: rc = dsi_pll_clock_register_8996(pdev, pll_res); break; - case MDSS_DSI_PLL_COBALT: - rc = dsi_pll_clock_register_cobalt(pdev, pll_res); - case MDSS_DP_PLL_COBALT: - rc = dp_pll_clock_register_cobalt(pdev, pll_res); + case MDSS_DSI_PLL_8998: + rc = dsi_pll_clock_register_8998(pdev, pll_res); + case MDSS_DP_PLL_8998: + rc = dp_pll_clock_register_8998(pdev, pll_res); break; case MDSS_HDMI_PLL_8996: rc = hdmi_8996_v1_pll_clock_register(pdev, pll_res); @@ -194,8 +194,8 @@ static int mdss_pll_clock_register(struct platform_device *pdev, case MDSS_HDMI_PLL_8996_V3_1_8: rc = hdmi_8996_v3_1p8_pll_clock_register(pdev, pll_res); break; - case MDSS_HDMI_PLL_COBALT: - rc = hdmi_cobalt_pll_clock_register(pdev, pll_res); + case MDSS_HDMI_PLL_8998: + rc = hdmi_8998_pll_clock_register(pdev, pll_res); break; case MDSS_UNKNOWN_PLL: default: @@ -394,13 +394,13 @@ static int mdss_pll_remove(struct platform_device *pdev) static const struct of_device_id mdss_pll_dt_match[] = { {.compatible = "qcom,mdss_dsi_pll_8996"}, {.compatible = "qcom,mdss_dsi_pll_8996_v2"}, - {.compatible = "qcom,mdss_dsi_pll_cobalt"}, + {.compatible = "qcom,mdss_dsi_pll_8998"}, {.compatible = "qcom,mdss_hdmi_pll_8996"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v2"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v3"}, {.compatible = "qcom,mdss_hdmi_pll_8996_v3_1p8"}, - {.compatible = "qcom,mdss_dp_pll_cobalt"}, - {.compatible = "qcom,mdss_hdmi_pll_cobalt"}, + {.compatible = "qcom,mdss_dp_pll_8998"}, + {.compatible = "qcom,mdss_hdmi_pll_8998"}, {} }; diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h index a2eb03e09146..8fffaf30d4ec 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.h +++ b/drivers/clk/qcom/mdss/mdss-pll.h @@ -31,13 +31,13 @@ enum { MDSS_DSI_PLL_8996, - MDSS_DSI_PLL_COBALT, - MDSS_DP_PLL_COBALT, + MDSS_DSI_PLL_8998, + MDSS_DP_PLL_8998, MDSS_HDMI_PLL_8996, MDSS_HDMI_PLL_8996_V2, MDSS_HDMI_PLL_8996_V3, MDSS_HDMI_PLL_8996_V3_1_8, - MDSS_HDMI_PLL_COBALT, + MDSS_HDMI_PLL_8998, MDSS_UNKNOWN_PLL, }; diff --git a/drivers/clk/qcom/mmcc-msmfalcon.c b/drivers/clk/qcom/mmcc-msmfalcon.c new file mode 100644 index 000000000000..e4a84765430a --- /dev/null +++ b/drivers/clk/qcom/mmcc-msmfalcon.c @@ -0,0 +1,3036 @@ +/* + * Copyright (c) 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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> +#include <dt-bindings/clock/qcom,mmcc-msmfalcon.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "common.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "reset.h" +#include "vdd-level-falcon.h" + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } +#define F_SLEW(f, s, h, m, n, src_freq) { (f), (s), (2 * (h) - 1), (m), (n), \ + (src_freq) } + +enum vdd_a_levels { + VDDA_NONE, + VDDA_LOWER, /* SVS2 */ + VDDA_NUM, +}; + +static int vdda_levels[] = { + 0, + 1800000, +}; + +#define VDDA_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdda, \ + .rate_max = (unsigned long[VDDA_NUM]) { \ + [VDDA_##l1] = (f1), \ + }, \ + .num_rate_max = VDDA_NUM + +static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdd_mx, VDD_DIG_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdda, VDDA_NUM, 1, vdda_levels); + +enum { + P_CORE_BI_PLL_TEST_SE, + P_CORE_PI_SLEEP_CLK, + P_CXO, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_MMPLL0_PLL_OUT_MAIN, + P_MMPLL10_PLL_OUT_MAIN, + P_MMPLL3_PLL_OUT_MAIN, + P_MMPLL4_PLL_OUT_MAIN, + P_MMPLL5_PLL_OUT_MAIN, + P_MMPLL6_PLL_OUT_MAIN, + P_MMPLL7_PLL_OUT_MAIN, + P_MMPLL8_PLL_OUT_MAIN, +}; + +static const struct parent_map mmcc_parent_map_0[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL4_PLL_OUT_MAIN, 2 }, + { P_MMPLL7_PLL_OUT_MAIN, 3 }, + { P_MMPLL8_PLL_OUT_MAIN, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_0[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll4_pll_out_main", + "mmpll7_pll_out_main", + "mmpll8_pll_out_main", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_1[] = { + { P_CXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_1[] = { + "xo", + "dsi0_phy_pll_out_byteclk", + "dsi1_phy_pll_out_byteclk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_2[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL4_PLL_OUT_MAIN, 2 }, + { P_MMPLL7_PLL_OUT_MAIN, 3 }, + { P_MMPLL10_PLL_OUT_MAIN, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_2[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll4_pll_out_main", + "mmpll7_pll_out_main", + "mmpll10_pll_out_main", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_3[] = { + { P_CXO, 0 }, + { P_MMPLL4_PLL_OUT_MAIN, 1 }, + { P_MMPLL7_PLL_OUT_MAIN, 2 }, + { P_MMPLL10_PLL_OUT_MAIN, 3 }, + { P_CORE_PI_SLEEP_CLK, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_3[] = { + "xo", + "mmpll4_pll_out_main", + "mmpll7_pll_out_main", + "mmpll10_pll_out_main", + "core_pi_sleep_clk", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_4[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL7_PLL_OUT_MAIN, 2 }, + { P_MMPLL10_PLL_OUT_MAIN, 3 }, + { P_CORE_PI_SLEEP_CLK, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_4[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll7_pll_out_main", + "mmpll10_pll_out_main", + "core_pi_sleep_clk", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_5[] = { + { P_CXO, 0 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_5[] = { + "xo", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_6[] = { + { P_CXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_6[] = { + "xo", + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_7[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL5_PLL_OUT_MAIN, 2 }, + { P_MMPLL7_PLL_OUT_MAIN, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_7[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll5_pll_out_main", + "mmpll7_pll_out_main", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_8[] = { + { P_CXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_8[] = { + "xo", + "dsi0_phy_pll_out_dsiclk", + "dsi1_phy_pll_out_dsiclk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_9[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL4_PLL_OUT_MAIN, 2 }, + { P_MMPLL7_PLL_OUT_MAIN, 3 }, + { P_MMPLL10_PLL_OUT_MAIN, 4 }, + { P_MMPLL6_PLL_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_9[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll4_pll_out_main", + "mmpll7_pll_out_main", + "mmpll10_pll_out_main", + "mmpll6_pll_out_main", + "gcc_mmss_gpll0_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_10[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_10[] = { + "xo", + "mmpll0_pll_out_main", + "gcc_mmss_gpll0_clk", + "gcc_mmss_gpll0_div_clk", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_11[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL4_PLL_OUT_MAIN, 2 }, + { P_MMPLL7_PLL_OUT_MAIN, 3 }, + { P_MMPLL10_PLL_OUT_MAIN, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_MMPLL6_PLL_OUT_MAIN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_11[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll4_pll_out_main", + "mmpll7_pll_out_main", + "mmpll10_pll_out_main", + "gcc_mmss_gpll0_clk", + "mmpll6_pll_out_main", + "core_bi_pll_test_se", +}; + +static const struct parent_map mmcc_parent_map_12[] = { + { P_CXO, 0 }, + { P_MMPLL0_PLL_OUT_MAIN, 1 }, + { P_MMPLL8_PLL_OUT_MAIN, 2 }, + { P_MMPLL3_PLL_OUT_MAIN, 3 }, + { P_MMPLL6_PLL_OUT_MAIN, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_MMPLL7_PLL_OUT_MAIN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const mmcc_parent_names_12[] = { + "xo", + "mmpll0_pll_out_main", + "mmpll8_pll_out_main", + "mmpll3_pll_out_main", + "mmpll6_pll_out_main", + "gcc_mmss_gpll0_clk", + "mmpll7_pll_out_main", + "core_bi_pll_test_se", +}; + +/* Voteable PLL */ +static struct clk_alpha_pll mmpll0_pll_out_main = { + .offset = 0xc000, + .clkr = { + .enable_reg = 0x1f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmpll0_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 404000000, + LOW, 808000000), + }, + }, +}; + +static struct clk_alpha_pll mmpll6_pll_out_main = { + .offset = 0xf0, + .clkr = { + .enable_reg = 0x1f0, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "mmpll6_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 540000000, + LOW_L1, 1080000000), + }, + }, +}; + +/* APSS controlled PLLs */ +static struct pll_vco vco[] = { + { 1000000000, 2000000000, 0 }, + { 750000000, 1500000000, 1 }, + { 500000000, 1000000000, 2 }, + { 250000000, 500000000, 3 }, +}; + +static const struct pll_config mmpll10_config = { + .l = 0x1e, + .config_ctl_val = 0x00004289, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll10_pll_out_main = { + .offset = 0x190, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll10_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDDA_FMAX_MAP1(LOWER, 576000000), + }, + }, +}; + +static struct pll_vco mmpll3_vco[] = { + { 750000000, 1500000000, 1 }, +}; + +static const struct pll_config mmpll3_config = { + .l = 0x2e, + .config_ctl_val = 0x4001055b, + .vco_val = 0x1 << 20, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll3_pll_out_main = { + .offset = 0x0, + .vco_table = mmpll3_vco, + .num_vco = ARRAY_SIZE(mmpll3_vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll3_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_slew_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 441600000, + NOMINAL, 1036800000), + }, + }, +}; + +static const struct pll_config mmpll4_config = { + .l = 0x28, + .config_ctl_val = 0x4001055b, + .vco_val = 0x2 << 20, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll4_pll_out_main = { + .offset = 0x50, + .vco_table = vco, + .num_vco = ARRAY_SIZE(vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll4_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 384000000, + LOW, 768000000), + }, + }, +}; + +static const struct pll_config mmpll5_config = { + .l = 0x2a, + .config_ctl_val = 0x4001055b, + .alpha_u = 0xf8, + .alpha_en_mask = BIT(24), + .vco_val = 0x2 << 20, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll5_pll_out_main = { + .offset = 0xa0, + .vco_table = vco, + .num_vco = ARRAY_SIZE(vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll5_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 421500000, + LOW, 825000000), + }, + }, +}; + +static const struct pll_config mmpll7_config = { + .l = 0x32, + .config_ctl_val = 0x4001055b, + .vco_val = 0x2 << 20, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll7_pll_out_main = { + .offset = 0x140, + .vco_table = vco, + .num_vco = ARRAY_SIZE(vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll7_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 480000000, + LOW, 960000000), + }, + }, +}; + +static const struct pll_config mmpll8_config = { + .l = 0x30, + .alpha_u = 0x70, + .alpha_en_mask = BIT(24), + .config_ctl_val = 0x4001055b, + .vco_val = 0x2 << 20, + .vco_mask = 0x3 << 20, + .main_output_mask = 0x1, +}; + +static struct clk_alpha_pll mmpll8_pll_out_main = { + .offset = 0x1c0, + .vco_table = vco, + .num_vco = ARRAY_SIZE(vco), + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmpll8_pll_out_main", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + VDD_MMSS_PLL_DIG_FMAX_MAP2(LOWER, 465000000, + LOW, 930000000), + }, + }, +}; + +static const struct freq_tbl ftbl_ahb_clk_src[] = { + F(19200000, P_CXO, 1, 0, 0), + F(40000000, P_GPLL0_OUT_MAIN_DIV, 7.5, 0, 0), + F(80800000, P_MMPLL0_PLL_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 ahb_clk_src = { + .cmd_rcgr = 0x5000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_10, + .freq_tbl = ftbl_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "ahb_clk_src", + .parent_names = mmcc_parent_names_10, + .num_parents = 5, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 19200000, + LOW, 40000000, + NOMINAL, 80800000), + }, +}; + +static struct clk_rcg2 byte0_clk_src = { + .cmd_rcgr = 0x2120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte0_clk_src", + .parent_names = mmcc_parent_names_1, + .num_parents = 4, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + VDD_DIG_FMAX_MAP3( + LOWER, 131250000, + LOW, 210000000, + NOMINAL, 262500000), + }, +}; + +static struct clk_rcg2 byte1_clk_src = { + .cmd_rcgr = 0x2140, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte1_clk_src", + .parent_names = mmcc_parent_names_1, + .num_parents = 4, + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + VDD_DIG_FMAX_MAP3( + LOWER, 131250000, + LOW, 210000000, + NOMINAL, 262500000), + }, +}; + +static const struct freq_tbl ftbl_camss_gp0_clk_src[] = { + F(10000, P_CXO, 16, 1, 120), + F(24000, P_CXO, 16, 1, 50), + F(6000000, P_GPLL0_OUT_MAIN_DIV, 10, 1, 5), + F(12000000, P_GPLL0_OUT_MAIN_DIV, 10, 2, 5), + F(13043478, P_GPLL0_OUT_MAIN_DIV, 1, 1, 23), + F(24000000, P_GPLL0_OUT_MAIN_DIV, 1, 2, 25), + F(50000000, P_GPLL0_OUT_MAIN_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN_DIV, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 camss_gp0_clk_src = { + .cmd_rcgr = 0x3420, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_4, + .freq_tbl = ftbl_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp0_clk_src", + .parent_names = mmcc_parent_names_4, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 50000000, + LOW, 100000000, + NOMINAL, 200000000), + }, +}; + +static struct clk_rcg2 camss_gp1_clk_src = { + .cmd_rcgr = 0x3450, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_4, + .freq_tbl = ftbl_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "camss_gp1_clk_src", + .parent_names = mmcc_parent_names_4, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 50000000, + LOW, 100000000, + NOMINAL, 200000000), + }, +}; + +static const struct freq_tbl ftbl_cci_clk_src[] = { + F(37500000, P_GPLL0_OUT_MAIN_DIV, 8, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN_DIV, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cci_clk_src = { + .cmd_rcgr = 0x3300, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_4, + .freq_tbl = ftbl_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cci_clk_src", + .parent_names = mmcc_parent_names_4, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 37500000, + LOW, 50000000, + NOMINAL, 100000000), + }, +}; + +static const struct freq_tbl ftbl_cpp_clk_src[] = { + F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(256000000, P_MMPLL4_PLL_OUT_MAIN, 3, 0, 0), + F(384000000, P_MMPLL4_PLL_OUT_MAIN, 2, 0, 0), + F(480000000, P_MMPLL7_PLL_OUT_MAIN, 2, 0, 0), + F(540000000, P_MMPLL6_PLL_OUT_MAIN, 2, 0, 0), + F(576000000, P_MMPLL10_PLL_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cpp_clk_src = { + .cmd_rcgr = 0x3640, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_11, + .freq_tbl = ftbl_cpp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cpp_clk_src", + .parent_names = mmcc_parent_names_11, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP6( + LOWER, 120000000, + LOW, 256000000, + LOW_L1, 384000000, + NOMINAL, 480000000, + NOMINAL_L1, 540000000, + HIGH, 576000000), + }, +}; + +static const struct freq_tbl ftbl_csi0_clk_src[] = { + F(100000000, P_GPLL0_OUT_MAIN_DIV, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(310000000, P_MMPLL8_PLL_OUT_MAIN, 3, 0, 0), + F(404000000, P_MMPLL0_PLL_OUT_MAIN, 2, 0, 0), + F(465000000, P_MMPLL8_PLL_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 csi0_clk_src = { + .cmd_rcgr = 0x3090, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_0, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0_clk_src", + .parent_names = mmcc_parent_names_0, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP5( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 310000000, + NOMINAL, 404000000, + NOMINAL_L1, 465000000), + }, +}; + +static const struct freq_tbl ftbl_csi0phytimer_clk_src[] = { + F(100000000, P_GPLL0_OUT_MAIN_DIV, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(269333333, P_MMPLL0_PLL_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 csi0phytimer_clk_src = { + .cmd_rcgr = 0x3000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_2, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi0phytimer_clk_src", + .parent_names = mmcc_parent_names_2, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 269333333), + }, +}; + +static struct clk_rcg2 csi1_clk_src = { + .cmd_rcgr = 0x3100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_0, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1_clk_src", + .parent_names = mmcc_parent_names_0, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP5( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 310000000, + NOMINAL, 404000000, + NOMINAL_L1, 465000000), + }, +}; + +static struct clk_rcg2 csi1phytimer_clk_src = { + .cmd_rcgr = 0x3030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_2, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi1phytimer_clk_src", + .parent_names = mmcc_parent_names_2, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 269333333), + }, +}; + +static struct clk_rcg2 csi2_clk_src = { + .cmd_rcgr = 0x3160, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_0, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2_clk_src", + .parent_names = mmcc_parent_names_0, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP5( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 310000000, + NOMINAL, 404000000, + NOMINAL_L1, 465000000), + }, +}; + +static struct clk_rcg2 csi2phytimer_clk_src = { + .cmd_rcgr = 0x3060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_2, + .freq_tbl = ftbl_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi2phytimer_clk_src", + .parent_names = mmcc_parent_names_2, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 269333333), + }, +}; + +static struct clk_rcg2 csi3_clk_src = { + .cmd_rcgr = 0x31c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_0, + .freq_tbl = ftbl_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csi3_clk_src", + .parent_names = mmcc_parent_names_0, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP5( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 310000000, + NOMINAL, 404000000, + NOMINAL_L1, 465000000), + }, +}; + +static const struct freq_tbl ftbl_csiphy_clk_src[] = { + F(100000000, P_GPLL0_OUT_MAIN_DIV, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(269333333, P_MMPLL0_PLL_OUT_MAIN, 3, 0, 0), + F(320000000, P_MMPLL7_PLL_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 csiphy_clk_src = { + .cmd_rcgr = 0x3800, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_0, + .freq_tbl = ftbl_csiphy_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "csiphy_clk_src", + .parent_names = mmcc_parent_names_0, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP4( + LOWER, 100000000, + LOW, 200000000, + LOW_L1, 269333333, + NOMINAL, 320000000), + }, +}; + +static const struct freq_tbl ftbl_dp_aux_clk_src[] = { + F(19200000, P_CXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 dp_aux_clk_src = { + .cmd_rcgr = 0x2260, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_5, + .freq_tbl = ftbl_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_aux_clk_src", + .parent_names = mmcc_parent_names_5, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1( + LOWER, 19200000), + }, +}; + +static const struct freq_tbl ftbl_dp_crypto_clk_src[] = { + F(101250000, P_DP_PHY_PLL_VCO_DIV, 4, 0, 0), + F(168750000, P_DP_PHY_PLL_VCO_DIV, 4, 0, 0), + F(337500000, P_DP_PHY_PLL_VCO_DIV, 4, 0, 0), + { } +}; + +static struct clk_rcg2 dp_crypto_clk_src = { + .cmd_rcgr = 0x2220, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_6, + .freq_tbl = ftbl_dp_crypto_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_crypto_clk_src", + .parent_names = mmcc_parent_names_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 101250000, + LOW, 168750000, + NOMINAL, 337500000), + }, +}; + +static const struct freq_tbl ftbl_dp_gtc_clk_src[] = { + F(40000000, P_GPLL0_OUT_MAIN_DIV, 7.5, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN_DIV, 1, 0, 0), + { } +}; + +static struct clk_rcg2 dp_gtc_clk_src = { + .cmd_rcgr = 0x2280, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_5, + .freq_tbl = ftbl_dp_gtc_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_gtc_clk_src", + .parent_names = mmcc_parent_names_5, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2( + LOWER, 40000000, + LOW, 300000000), + }, +}; + +static const struct freq_tbl ftbl_dp_link_clk_src[] = { + F(162000000, P_DP_PHY_PLL_LINK_CLK, 2, 0, 0), + F(270000000, P_DP_PHY_PLL_LINK_CLK, 2, 0, 0), + F(540000000, P_DP_PHY_PLL_LINK_CLK, 2, 0, 0), + { } +}; + +static struct clk_rcg2 dp_link_clk_src = { + .cmd_rcgr = 0x2200, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_6, + .freq_tbl = ftbl_dp_link_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_link_clk_src", + .parent_names = mmcc_parent_names_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + VDD_DIG_FMAX_MAP3( + LOWER, 162000000, + LOW, 270000000, + NOMINAL, 540000000), + }, +}; + +static struct clk_rcg2 dp_pixel_clk_src = { + .cmd_rcgr = 0x2240, + .mnd_width = 16, + .hid_width = 5, + .parent_map = mmcc_parent_map_6, + .clkr.hw.init = &(struct clk_init_data){ + .name = "dp_pixel_clk_src", + .parent_names = mmcc_parent_names_6, + .num_parents = 4, + .ops = &clk_dp_ops, + VDD_DIG_FMAX_MAP3( + LOWER, 148380000, + LOW, 296740000, + NOMINAL, 593470000), + }, +}; + +static struct clk_rcg2 esc0_clk_src = { + .cmd_rcgr = 0x2160, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_1, + .freq_tbl = ftbl_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc0_clk_src", + .parent_names = mmcc_parent_names_1, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1( + LOWER, 19200000), + }, +}; + +static struct clk_rcg2 esc1_clk_src = { + .cmd_rcgr = 0x2180, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_1, + .freq_tbl = ftbl_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc1_clk_src", + .parent_names = mmcc_parent_names_1, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1( + LOWER, 19200000), + }, +}; + +static const struct freq_tbl ftbl_jpeg0_clk_src[] = { + F(66666667, P_GPLL0_OUT_MAIN_DIV, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(219428571, P_MMPLL4_PLL_OUT_MAIN, 3.5, 0, 0), + F(320000000, P_MMPLL7_PLL_OUT_MAIN, 3, 0, 0), + F(480000000, P_MMPLL7_PLL_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 jpeg0_clk_src = { + .cmd_rcgr = 0x3500, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_2, + .freq_tbl = ftbl_jpeg0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "jpeg0_clk_src", + .parent_names = mmcc_parent_names_2, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP5( + LOWER, 66666667, + LOW, 133333333, + LOW_L1, 219428571, + NOMINAL, 320000000, + NOMINAL_L1, 480000000), + }, +}; + +static const struct freq_tbl ftbl_mclk0_clk_src[] = { + F(4800000, P_CXO, 4, 0, 0), + F(6000000, P_GPLL0_OUT_MAIN_DIV, 10, 1, 5), + F(8000000, P_GPLL0_OUT_MAIN_DIV, 1, 2, 75), + F(9600000, P_CXO, 2, 0, 0), + F(16666667, P_GPLL0_OUT_MAIN_DIV, 2, 1, 9), + F(19200000, P_CXO, 1, 0, 0), + F(24000000, P_GPLL0_OUT_MAIN_DIV, 1, 2, 25), + F(33333333, P_GPLL0_OUT_MAIN_DIV, 1, 1, 9), + F(48000000, P_GPLL0_OUT_MAIN, 1, 2, 25), + F(66666667, P_GPLL0_OUT_MAIN, 1, 1, 9), + { } +}; + +static struct clk_rcg2 mclk0_clk_src = { + .cmd_rcgr = 0x3360, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_3, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk0_clk_src", + .parent_names = mmcc_parent_names_3, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2( + LOWER, 33333333, + LOW, 66666667), + }, +}; + +static struct clk_rcg2 mclk1_clk_src = { + .cmd_rcgr = 0x3390, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_3, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk1_clk_src", + .parent_names = mmcc_parent_names_3, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2( + LOWER, 33333333, + LOW, 66666667), + }, +}; + +static struct clk_rcg2 mclk2_clk_src = { + .cmd_rcgr = 0x33c0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_3, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk2_clk_src", + .parent_names = mmcc_parent_names_3, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2( + LOWER, 33333333, + LOW, 66666667), + }, +}; + +static struct clk_rcg2 mclk3_clk_src = { + .cmd_rcgr = 0x33f0, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_3, + .freq_tbl = ftbl_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mclk3_clk_src", + .parent_names = mmcc_parent_names_3, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2( + LOWER, 33333333, + LOW, 66666667), + }, +}; + +static const struct freq_tbl ftbl_mdp_clk_src[] = { + F(100000000, P_GPLL0_OUT_MAIN_DIV, 3, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0), + F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(275000000, P_MMPLL5_PLL_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(330000000, P_MMPLL5_PLL_OUT_MAIN, 2.5, 0, 0), + F(412500000, P_MMPLL5_PLL_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 mdp_clk_src = { + .cmd_rcgr = 0x2040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_7, + .freq_tbl = ftbl_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "mdp_clk_src", + .parent_names = mmcc_parent_names_7, + .num_parents = 7, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP4( + LOWER, 171428571, + LOW, 275000000, + NOMINAL, 330000000, + HIGH, 412500000), + }, +}; + +static struct clk_rcg2 pclk0_clk_src = { + .cmd_rcgr = 0x2000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_8, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk0_clk_src", + .parent_names = mmcc_parent_names_8, + .num_parents = 4, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + VDD_DIG_FMAX_MAP3( + LOWER, 175000000, + LOW, 280000000, + NOMINAL, 350000000), + }, +}; + +static struct clk_rcg2 pclk1_clk_src = { + .cmd_rcgr = 0x2020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = mmcc_parent_map_8, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk1_clk_src", + .parent_names = mmcc_parent_names_8, + .num_parents = 4, + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + VDD_DIG_FMAX_MAP3( + LOWER, 175000000, + LOW, 280000000, + NOMINAL, 350000000), + }, +}; + +static const struct freq_tbl ftbl_rot_clk_src[] = { + F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), + F(275000000, P_MMPLL5_PLL_OUT_MAIN, 3, 0, 0), + F(330000000, P_MMPLL5_PLL_OUT_MAIN, 2.5, 0, 0), + F(412500000, P_MMPLL5_PLL_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 rot_clk_src = { + .cmd_rcgr = 0x21a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_7, + .freq_tbl = ftbl_rot_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rot_clk_src", + .parent_names = mmcc_parent_names_7, + .num_parents = 7, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP4( + LOWER, 171428571, + LOW, 275000000, + NOMINAL, 330000000, + HIGH, 412500000), + }, +}; + +static const struct freq_tbl ftbl_vfe0_clk_src[] = { + F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(256000000, P_MMPLL4_PLL_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(404000000, P_MMPLL0_PLL_OUT_MAIN, 2, 0, 0), + F(480000000, P_MMPLL7_PLL_OUT_MAIN, 2, 0, 0), + F(540000000, P_MMPLL6_PLL_OUT_MAIN, 2, 0, 0), + F(576000000, P_MMPLL10_PLL_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 vfe0_clk_src = { + .cmd_rcgr = 0x3600, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_9, + .freq_tbl = ftbl_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe0_clk_src", + .parent_names = mmcc_parent_names_9, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP6( + LOWER, 120000000, + LOW, 256000000, + LOW_L1, 404000000, + NOMINAL, 480000000, + NOMINAL_L1, 540000000, + HIGH, 576000000), + }, +}; + +static struct clk_rcg2 vfe1_clk_src = { + .cmd_rcgr = 0x3620, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_9, + .freq_tbl = ftbl_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vfe1_clk_src", + .parent_names = mmcc_parent_names_9, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP6( + LOWER, 120000000, + LOW, 256000000, + LOW_L1, 404000000, + NOMINAL, 480000000, + NOMINAL_L1, 540000000, + HIGH, 576000000), + }, +}; + +static const struct freq_tbl ftbl_video_core_clk_src[] = { + F_SLEW(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0, FIXED_FREQ_SRC), + F_SLEW(269333333, P_MMPLL0_PLL_OUT_MAIN, 3, 0, 0, FIXED_FREQ_SRC), + F_SLEW(320000000, P_MMPLL7_PLL_OUT_MAIN, 3, 0, 0, FIXED_FREQ_SRC), + F_SLEW(404000000, P_MMPLL0_PLL_OUT_MAIN, 2, 0, 0, FIXED_FREQ_SRC), + F_SLEW(441600000, P_MMPLL3_PLL_OUT_MAIN, 2, 0, 0, 883200000), + F_SLEW(518400000, P_MMPLL3_PLL_OUT_MAIN, 2, 0, 0, 1036800000), + { } +}; + +static struct clk_rcg2 video_core_clk_src = { + .cmd_rcgr = 0x1000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_12, + .freq_tbl = ftbl_video_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_core_clk_src", + .parent_names = mmcc_parent_names_12, + .num_parents = 8, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP6( + LOWER, 133333333, + LOW, 269333333, + LOW_L1, 320000000, + NOMINAL, 404000000, + NOMINAL_L1, 441600000, + HIGH, 518400000), + }, +}; + +static struct clk_rcg2 vsync_clk_src = { + .cmd_rcgr = 0x2080, + .mnd_width = 0, + .hid_width = 5, + .parent_map = mmcc_parent_map_5, + .freq_tbl = ftbl_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "vsync_clk_src", + .parent_names = mmcc_parent_names_5, + .num_parents = 4, + .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1( + LOWER, 19200000), + }, +}; + +static struct clk_branch mmss_bimc_smmu_ahb_clk = { + .halt_reg = 0xe004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0xe004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_bimc_smmu_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_bimc_smmu_axi_clk = { + .halt_reg = 0xe008, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0xe008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_bimc_smmu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_ahb_clk = { + .halt_reg = 0x348c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x348c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cci_ahb_clk = { + .halt_reg = 0x3348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cci_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cci_clk = { + .halt_reg = 0x3344, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cci_clk", + .parent_names = (const char *[]){ + "cci_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cphy_csid0_clk = { + .halt_reg = 0x3730, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3730, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cphy_csid0_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cphy_csid1_clk = { + .halt_reg = 0x3734, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3734, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cphy_csid1_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cphy_csid2_clk = { + .halt_reg = 0x3738, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3738, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cphy_csid2_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cphy_csid3_clk = { + .halt_reg = 0x373c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x373c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cphy_csid3_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cpp_ahb_clk = { + .halt_reg = 0x36b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cpp_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cpp_axi_clk = { + .halt_reg = 0x36c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36c4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cpp_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cpp_clk = { + .halt_reg = 0x36b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cpp_clk", + .parent_names = (const char *[]){ + "cpp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_cpp_vbif_ahb_clk = { + .halt_reg = 0x36c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36c8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_cpp_vbif_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi0_ahb_clk = { + .halt_reg = 0x30bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x30bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi0_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi0_clk = { + .halt_reg = 0x30b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x30b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi0_clk", + .parent_names = (const char *[]){ + "csi0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi0phytimer_clk = { + .halt_reg = 0x3024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi0phytimer_clk", + .parent_names = (const char *[]){ + "csi0phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi0pix_clk = { + .halt_reg = 0x30e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x30e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi0pix_clk", + .parent_names = (const char *[]){ + "csi0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi0rdi_clk = { + .halt_reg = 0x30d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x30d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi0rdi_clk", + .parent_names = (const char *[]){ + "csi0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi1_ahb_clk = { + .halt_reg = 0x3128, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3128, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi1_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi1_clk = { + .halt_reg = 0x3124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi1_clk", + .parent_names = (const char *[]){ + "csi1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi1phytimer_clk = { + .halt_reg = 0x3054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi1phytimer_clk", + .parent_names = (const char *[]){ + "csi1phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi1pix_clk = { + .halt_reg = 0x3154, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi1pix_clk", + .parent_names = (const char *[]){ + "csi1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi1rdi_clk = { + .halt_reg = 0x3144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3144, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi1rdi_clk", + .parent_names = (const char *[]){ + "csi1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi2_ahb_clk = { + .halt_reg = 0x3188, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3188, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi2_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi2_clk = { + .halt_reg = 0x3184, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3184, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi2_clk", + .parent_names = (const char *[]){ + "csi2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi2phytimer_clk = { + .halt_reg = 0x3084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi2phytimer_clk", + .parent_names = (const char *[]){ + "csi2phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi2pix_clk = { + .halt_reg = 0x31b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi2pix_clk", + .parent_names = (const char *[]){ + "csi2_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi2rdi_clk = { + .halt_reg = 0x31a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi2rdi_clk", + .parent_names = (const char *[]){ + "csi2_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi3_ahb_clk = { + .halt_reg = 0x31e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31e8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi3_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi3_clk = { + .halt_reg = 0x31e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x31e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi3_clk", + .parent_names = (const char *[]){ + "csi3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi3pix_clk = { + .halt_reg = 0x3214, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3214, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi3pix_clk", + .parent_names = (const char *[]){ + "csi3_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi3rdi_clk = { + .halt_reg = 0x3204, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi3rdi_clk", + .parent_names = (const char *[]){ + "csi3_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi_vfe0_clk = { + .halt_reg = 0x3704, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3704, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi_vfe0_clk", + .parent_names = (const char *[]){ + "vfe0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csi_vfe1_clk = { + .halt_reg = 0x3714, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3714, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csi_vfe1_clk", + .parent_names = (const char *[]){ + "vfe1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csiphy0_clk = { + .halt_reg = 0x3740, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3740, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csiphy0_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csiphy1_clk = { + .halt_reg = 0x3744, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3744, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csiphy1_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_csiphy2_clk = { + .halt_reg = 0x3748, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3748, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_csiphy2_clk", + .parent_names = (const char *[]){ + "csiphy_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_gp0_clk = { + .halt_reg = 0x3444, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3444, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_gp0_clk", + .parent_names = (const char *[]){ + "camss_gp0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_gp1_clk = { + .halt_reg = 0x3474, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3474, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_gp1_clk", + .parent_names = (const char *[]){ + "camss_gp1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_ispif_ahb_clk = { + .halt_reg = 0x3224, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3224, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_ispif_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_jpeg0_clk = { + .halt_reg = 0x35a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x35a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_jpeg0_clk", + .parent_names = (const char *[]){ + "jpeg0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_jpeg_ahb_clk = { + .halt_reg = 0x35b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x35b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_jpeg_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_jpeg_axi_clk = { + .halt_reg = 0x35b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x35b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_jpeg_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_mclk0_clk = { + .halt_reg = 0x3384, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3384, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_mclk0_clk", + .parent_names = (const char *[]){ + "mclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_mclk1_clk = { + .halt_reg = 0x33b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33b4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_mclk1_clk", + .parent_names = (const char *[]){ + "mclk1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_mclk2_clk = { + .halt_reg = 0x33e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33e4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_mclk2_clk", + .parent_names = (const char *[]){ + "mclk2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_mclk3_clk = { + .halt_reg = 0x3414, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3414, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_mclk3_clk", + .parent_names = (const char *[]){ + "mclk3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_micro_ahb_clk = { + .halt_reg = 0x3494, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3494, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_micro_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_top_ahb_clk = { + .halt_reg = 0x3484, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3484, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_top_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe0_ahb_clk = { + .halt_reg = 0x3668, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3668, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe0_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe0_clk = { + .halt_reg = 0x36a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe0_clk", + .parent_names = (const char *[]){ + "vfe0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe0_stream_clk = { + .halt_reg = 0x3720, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3720, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe0_stream_clk", + .parent_names = (const char *[]){ + "vfe0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe1_ahb_clk = { + .halt_reg = 0x3678, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3678, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe1_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe1_clk = { + .halt_reg = 0x36ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe1_clk", + .parent_names = (const char *[]){ + "vfe1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe1_stream_clk = { + .halt_reg = 0x3724, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3724, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe1_stream_clk", + .parent_names = (const char *[]){ + "vfe1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe_vbif_ahb_clk = { + .halt_reg = 0x36b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe_vbif_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_camss_vfe_vbif_axi_clk = { + .halt_reg = 0x36bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_camss_vfe_vbif_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_csiphy_ahb2crif_clk = { + .halt_reg = 0x374c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x374c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_csiphy_ahb2crif_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_ahb_clk = { + .halt_reg = 0x2308, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2308, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_axi_clk = { + .halt_reg = 0x2310, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2310, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_byte0_clk = { + .halt_reg = 0x233c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x233c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_byte0_clk", + .parent_names = (const char *[]){ + "byte0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_byte0_intf_clk = { + .halt_reg = 0x2374, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2374, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_byte0_intf_clk", + .parent_names = (const char *[]){ + "mmss_mdss_byte0_intf_div_clk", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap_div mmss_mdss_byte0_intf_div_clk = { + .reg = 0x237c, + .shift = 0, + .width = 2, + /* + * NOTE: Op does not work for div-3. Current assumption is that div-3 + * is not a recommended setting for this divider. + */ + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_byte0_intf_div_clk", + .parent_names = (const char *[]){ + "byte0_clk_src", + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + }, + }, +}; + +static struct clk_branch mmss_mdss_byte1_clk = { + .halt_reg = 0x2340, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2340, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_byte1_clk", + .parent_names = (const char *[]){ + "byte1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_byte1_intf_clk = { + .halt_reg = 0x2378, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2378, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_byte1_intf_clk", + .parent_names = (const char *[]){ + "byte1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_dp_aux_clk = { + .halt_reg = 0x2364, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2364, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_aux_clk", + .parent_names = (const char *[]){ + "dp_aux_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_dp_crypto_clk = { + .halt_reg = 0x235c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x235c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_crypto_clk", + .parent_names = (const char *[]){ + "dp_crypto_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_dp_gtc_clk = { + .halt_reg = 0x2368, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2368, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_gtc_clk", + .parent_names = (const char *[]){ + "dp_gtc_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_dp_link_clk = { + .halt_reg = 0x2354, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2354, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_link_clk", + .parent_names = (const char *[]){ + "dp_link_clk_src", + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* Reset state of MMSS_MDSS_DP_LINK_INTF_DIV is 0x3 (div-4) */ +static struct clk_branch mmss_mdss_dp_link_intf_clk = { + .halt_reg = 0x2358, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2358, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_link_intf_clk", + .parent_names = (const char *[]){ + "dp_link_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_dp_pixel_clk = { + .halt_reg = 0x2360, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2360, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_dp_pixel_clk", + .parent_names = (const char *[]){ + "dp_pixel_clk_src", + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_esc0_clk = { + .halt_reg = 0x2344, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2344, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_esc0_clk", + .parent_names = (const char *[]){ + "esc0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_esc1_clk = { + .halt_reg = 0x2348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2348, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_esc1_clk", + .parent_names = (const char *[]){ + "esc1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_hdmi_dp_ahb_clk = { + .halt_reg = 0x230c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x230c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_hdmi_dp_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_mdp_clk = { + .halt_reg = 0x231c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x231c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_mdp_clk", + .parent_names = (const char *[]){ + "mdp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_pclk0_clk = { + .halt_reg = 0x2314, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2314, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_pclk0_clk", + .parent_names = (const char *[]){ + "pclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_pclk1_clk = { + .halt_reg = 0x2318, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2318, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_pclk1_clk", + .parent_names = (const char *[]){ + "pclk1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_rot_clk = { + .halt_reg = 0x2350, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2350, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_rot_clk", + .parent_names = (const char *[]){ + "rot_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mdss_vsync_clk = { + .halt_reg = 0x2328, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mdss_vsync_clk", + .parent_names = (const char *[]){ + "vsync_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_misc_ahb_clk = { + .halt_reg = 0x328, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x328, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_misc_ahb_clk", + /* + * Dependency to be enabled before the branch is + * enabled. + */ + .parent_names = (const char *[]){ + "mmss_mnoc_ahb_clk", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_misc_cxo_clk = { + .halt_reg = 0x324, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x324, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_misc_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_mnoc_ahb_clk = { + .halt_reg = 0x5024, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x5024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_mnoc_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_snoc_dvm_axi_clk = { + .halt_reg = 0xe040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_snoc_dvm_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_video_ahb_clk = { + .halt_reg = 0x1030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_video_ahb_clk", + .parent_names = (const char *[]){ + "ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_video_axi_clk = { + .halt_reg = 0x1034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_video_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_video_core_clk = { + .halt_reg = 0x1028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_video_core_clk", + .parent_names = (const char *[]){ + "video_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch mmss_video_subcore0_clk = { + .halt_reg = 0x1048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "mmss_video_subcore0_clk", + .parent_names = (const char *[]){ + "video_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *mmcc_falcon_clocks[] = { + [AHB_CLK_SRC] = &ahb_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr, + [CSI3_CLK_SRC] = &csi3_clk_src.clkr, + [CSIPHY_CLK_SRC] = &csiphy_clk_src.clkr, + [DP_AUX_CLK_SRC] = &dp_aux_clk_src.clkr, + [DP_CRYPTO_CLK_SRC] = &dp_crypto_clk_src.clkr, + [DP_GTC_CLK_SRC] = &dp_gtc_clk_src.clkr, + [DP_LINK_CLK_SRC] = &dp_link_clk_src.clkr, + [DP_PIXEL_CLK_SRC] = &dp_pixel_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [MMPLL0_PLL] = &mmpll0_pll_out_main.clkr, + [MMPLL10_PLL] = &mmpll10_pll_out_main.clkr, + [MMPLL3_PLL] = &mmpll3_pll_out_main.clkr, + [MMPLL4_PLL] = &mmpll4_pll_out_main.clkr, + [MMPLL5_PLL] = &mmpll5_pll_out_main.clkr, + [MMPLL6_PLL] = &mmpll6_pll_out_main.clkr, + [MMPLL7_PLL] = &mmpll7_pll_out_main.clkr, + [MMPLL8_PLL] = &mmpll8_pll_out_main.clkr, + [MMSS_BIMC_SMMU_AHB_CLK] = &mmss_bimc_smmu_ahb_clk.clkr, + [MMSS_BIMC_SMMU_AXI_CLK] = &mmss_bimc_smmu_axi_clk.clkr, + [MMSS_CAMSS_AHB_CLK] = &mmss_camss_ahb_clk.clkr, + [MMSS_CAMSS_CCI_AHB_CLK] = &mmss_camss_cci_ahb_clk.clkr, + [MMSS_CAMSS_CCI_CLK] = &mmss_camss_cci_clk.clkr, + [MMSS_CAMSS_CPHY_CSID0_CLK] = &mmss_camss_cphy_csid0_clk.clkr, + [MMSS_CAMSS_CPHY_CSID1_CLK] = &mmss_camss_cphy_csid1_clk.clkr, + [MMSS_CAMSS_CPHY_CSID2_CLK] = &mmss_camss_cphy_csid2_clk.clkr, + [MMSS_CAMSS_CPHY_CSID3_CLK] = &mmss_camss_cphy_csid3_clk.clkr, + [MMSS_CAMSS_CPP_AHB_CLK] = &mmss_camss_cpp_ahb_clk.clkr, + [MMSS_CAMSS_CPP_AXI_CLK] = &mmss_camss_cpp_axi_clk.clkr, + [MMSS_CAMSS_CPP_CLK] = &mmss_camss_cpp_clk.clkr, + [MMSS_CAMSS_CPP_VBIF_AHB_CLK] = &mmss_camss_cpp_vbif_ahb_clk.clkr, + [MMSS_CAMSS_CSI0_AHB_CLK] = &mmss_camss_csi0_ahb_clk.clkr, + [MMSS_CAMSS_CSI0_CLK] = &mmss_camss_csi0_clk.clkr, + [MMSS_CAMSS_CSI0PHYTIMER_CLK] = &mmss_camss_csi0phytimer_clk.clkr, + [MMSS_CAMSS_CSI0PIX_CLK] = &mmss_camss_csi0pix_clk.clkr, + [MMSS_CAMSS_CSI0RDI_CLK] = &mmss_camss_csi0rdi_clk.clkr, + [MMSS_CAMSS_CSI1_AHB_CLK] = &mmss_camss_csi1_ahb_clk.clkr, + [MMSS_CAMSS_CSI1_CLK] = &mmss_camss_csi1_clk.clkr, + [MMSS_CAMSS_CSI1PHYTIMER_CLK] = &mmss_camss_csi1phytimer_clk.clkr, + [MMSS_CAMSS_CSI1PIX_CLK] = &mmss_camss_csi1pix_clk.clkr, + [MMSS_CAMSS_CSI1RDI_CLK] = &mmss_camss_csi1rdi_clk.clkr, + [MMSS_CAMSS_CSI2_AHB_CLK] = &mmss_camss_csi2_ahb_clk.clkr, + [MMSS_CAMSS_CSI2_CLK] = &mmss_camss_csi2_clk.clkr, + [MMSS_CAMSS_CSI2PHYTIMER_CLK] = &mmss_camss_csi2phytimer_clk.clkr, + [MMSS_CAMSS_CSI2PIX_CLK] = &mmss_camss_csi2pix_clk.clkr, + [MMSS_CAMSS_CSI2RDI_CLK] = &mmss_camss_csi2rdi_clk.clkr, + [MMSS_CAMSS_CSI3_AHB_CLK] = &mmss_camss_csi3_ahb_clk.clkr, + [MMSS_CAMSS_CSI3_CLK] = &mmss_camss_csi3_clk.clkr, + [MMSS_CAMSS_CSI3PIX_CLK] = &mmss_camss_csi3pix_clk.clkr, + [MMSS_CAMSS_CSI3RDI_CLK] = &mmss_camss_csi3rdi_clk.clkr, + [MMSS_CAMSS_CSI_VFE0_CLK] = &mmss_camss_csi_vfe0_clk.clkr, + [MMSS_CAMSS_CSI_VFE1_CLK] = &mmss_camss_csi_vfe1_clk.clkr, + [MMSS_CAMSS_CSIPHY0_CLK] = &mmss_camss_csiphy0_clk.clkr, + [MMSS_CAMSS_CSIPHY1_CLK] = &mmss_camss_csiphy1_clk.clkr, + [MMSS_CAMSS_CSIPHY2_CLK] = &mmss_camss_csiphy2_clk.clkr, + [MMSS_CAMSS_GP0_CLK] = &mmss_camss_gp0_clk.clkr, + [MMSS_CAMSS_GP1_CLK] = &mmss_camss_gp1_clk.clkr, + [MMSS_CAMSS_ISPIF_AHB_CLK] = &mmss_camss_ispif_ahb_clk.clkr, + [MMSS_CAMSS_JPEG0_CLK] = &mmss_camss_jpeg0_clk.clkr, + [MMSS_CAMSS_JPEG_AHB_CLK] = &mmss_camss_jpeg_ahb_clk.clkr, + [MMSS_CAMSS_JPEG_AXI_CLK] = &mmss_camss_jpeg_axi_clk.clkr, + [MMSS_CAMSS_MCLK0_CLK] = &mmss_camss_mclk0_clk.clkr, + [MMSS_CAMSS_MCLK1_CLK] = &mmss_camss_mclk1_clk.clkr, + [MMSS_CAMSS_MCLK2_CLK] = &mmss_camss_mclk2_clk.clkr, + [MMSS_CAMSS_MCLK3_CLK] = &mmss_camss_mclk3_clk.clkr, + [MMSS_CAMSS_MICRO_AHB_CLK] = &mmss_camss_micro_ahb_clk.clkr, + [MMSS_CAMSS_TOP_AHB_CLK] = &mmss_camss_top_ahb_clk.clkr, + [MMSS_CAMSS_VFE0_AHB_CLK] = &mmss_camss_vfe0_ahb_clk.clkr, + [MMSS_CAMSS_VFE0_CLK] = &mmss_camss_vfe0_clk.clkr, + [MMSS_CAMSS_VFE0_STREAM_CLK] = &mmss_camss_vfe0_stream_clk.clkr, + [MMSS_CAMSS_VFE1_AHB_CLK] = &mmss_camss_vfe1_ahb_clk.clkr, + [MMSS_CAMSS_VFE1_CLK] = &mmss_camss_vfe1_clk.clkr, + [MMSS_CAMSS_VFE1_STREAM_CLK] = &mmss_camss_vfe1_stream_clk.clkr, + [MMSS_CAMSS_VFE_VBIF_AHB_CLK] = &mmss_camss_vfe_vbif_ahb_clk.clkr, + [MMSS_CAMSS_VFE_VBIF_AXI_CLK] = &mmss_camss_vfe_vbif_axi_clk.clkr, + [MMSS_CSIPHY_AHB2CRIF_CLK] = &mmss_csiphy_ahb2crif_clk.clkr, + [MMSS_MDSS_AHB_CLK] = &mmss_mdss_ahb_clk.clkr, + [MMSS_MDSS_AXI_CLK] = &mmss_mdss_axi_clk.clkr, + [MMSS_MDSS_BYTE0_CLK] = &mmss_mdss_byte0_clk.clkr, + [MMSS_MDSS_BYTE0_INTF_CLK] = &mmss_mdss_byte0_intf_clk.clkr, + [MMSS_MDSS_BYTE0_INTF_DIV_CLK] = &mmss_mdss_byte0_intf_div_clk.clkr, + [MMSS_MDSS_BYTE1_CLK] = &mmss_mdss_byte1_clk.clkr, + [MMSS_MDSS_BYTE1_INTF_CLK] = &mmss_mdss_byte1_intf_clk.clkr, + [MMSS_MDSS_DP_AUX_CLK] = &mmss_mdss_dp_aux_clk.clkr, + [MMSS_MDSS_DP_CRYPTO_CLK] = &mmss_mdss_dp_crypto_clk.clkr, + [MMSS_MDSS_DP_GTC_CLK] = &mmss_mdss_dp_gtc_clk.clkr, + [MMSS_MDSS_DP_LINK_CLK] = &mmss_mdss_dp_link_clk.clkr, + [MMSS_MDSS_DP_LINK_INTF_CLK] = &mmss_mdss_dp_link_intf_clk.clkr, + [MMSS_MDSS_DP_PIXEL_CLK] = &mmss_mdss_dp_pixel_clk.clkr, + [MMSS_MDSS_ESC0_CLK] = &mmss_mdss_esc0_clk.clkr, + [MMSS_MDSS_ESC1_CLK] = &mmss_mdss_esc1_clk.clkr, + [MMSS_MDSS_HDMI_DP_AHB_CLK] = &mmss_mdss_hdmi_dp_ahb_clk.clkr, + [MMSS_MDSS_MDP_CLK] = &mmss_mdss_mdp_clk.clkr, + [MMSS_MDSS_PCLK0_CLK] = &mmss_mdss_pclk0_clk.clkr, + [MMSS_MDSS_PCLK1_CLK] = &mmss_mdss_pclk1_clk.clkr, + [MMSS_MDSS_ROT_CLK] = &mmss_mdss_rot_clk.clkr, + [MMSS_MDSS_VSYNC_CLK] = &mmss_mdss_vsync_clk.clkr, + [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr, + [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr, + [MMSS_MNOC_AHB_CLK] = &mmss_mnoc_ahb_clk.clkr, + [MMSS_SNOC_DVM_AXI_CLK] = &mmss_snoc_dvm_axi_clk.clkr, + [MMSS_VIDEO_AHB_CLK] = &mmss_video_ahb_clk.clkr, + [MMSS_VIDEO_AXI_CLK] = &mmss_video_axi_clk.clkr, + [MMSS_VIDEO_CORE_CLK] = &mmss_video_core_clk.clkr, + [MMSS_VIDEO_SUBCORE0_CLK] = &mmss_video_subcore0_clk.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [ROT_CLK_SRC] = &rot_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [VIDEO_CORE_CLK_SRC] = &video_core_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, +}; + +static const struct qcom_reset_map mmcc_falcon_resets[] = { + [CAMSS_MICRO_BCR] = { 0x3490 }, +}; + +static const struct regmap_config mmcc_falcon_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10004, + .fast_io = true, +}; + +static const struct qcom_cc_desc mmcc_falcon_desc = { + .config = &mmcc_falcon_regmap_config, + .clks = mmcc_falcon_clocks, + .num_clks = ARRAY_SIZE(mmcc_falcon_clocks), + .resets = mmcc_falcon_resets, + .num_resets = ARRAY_SIZE(mmcc_falcon_resets), +}; + +static const struct of_device_id mmcc_falcon_match_table[] = { + { .compatible = "qcom,mmcc-msmfalcon" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmcc_falcon_match_table); + +static int mmcc_falcon_probe(struct platform_device *pdev) +{ + int ret = 0; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &mmcc_falcon_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* PLLs connected on Mx rails of MMSS_CC */ + vdd_mx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_mx_mmss"); + if (IS_ERR(vdd_mx.regulator[0])) { + if (!(PTR_ERR(vdd_mx.regulator[0]) == -EPROBE_DEFER)) + dev_err(&pdev->dev, + "Unable to get vdd_mx_mmss regulator\n"); + return PTR_ERR(vdd_mx.regulator[0]); + } + + vdd_dig.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_dig_mmss"); + if (IS_ERR(vdd_dig.regulator[0])) { + if (!(PTR_ERR(vdd_dig.regulator[0]) == -EPROBE_DEFER)) + dev_err(&pdev->dev, + "Unable to get vdd_dig regulator\n"); + return PTR_ERR(vdd_dig.regulator[0]); + } + + /* MMPLL10 connected to the Analog Rail */ + vdda.regulator[0] = devm_regulator_get(&pdev->dev, "vdda"); + if (IS_ERR(vdda.regulator[0])) { + if (!(PTR_ERR(vdda.regulator[0]) == -EPROBE_DEFER)) + dev_err(&pdev->dev, + "Unable to get vdda regulator\n"); + return PTR_ERR(vdda.regulator[0]); + } + + clk_alpha_pll_configure(&mmpll3_pll_out_main, regmap, &mmpll3_config); + clk_alpha_pll_configure(&mmpll4_pll_out_main, regmap, &mmpll4_config); + clk_alpha_pll_configure(&mmpll5_pll_out_main, regmap, &mmpll5_config); + clk_alpha_pll_configure(&mmpll7_pll_out_main, regmap, &mmpll7_config); + clk_alpha_pll_configure(&mmpll8_pll_out_main, regmap, &mmpll8_config); + clk_alpha_pll_configure(&mmpll10_pll_out_main, regmap, &mmpll10_config); + + ret = qcom_cc_really_probe(pdev, &mmcc_falcon_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register MMSS clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered MMSS clocks\n"); + + return ret; +} + +static struct platform_driver mmcc_falcon_driver = { + .probe = mmcc_falcon_probe, + .driver = { + .name = "mmcc-msmfalcon", + .of_match_table = mmcc_falcon_match_table, + }, +}; + +static int __init mmcc_falcon_init(void) +{ + return platform_driver_register(&mmcc_falcon_driver); +} +core_initcall_sync(mmcc_falcon_init); + +static void __exit mmcc_falcon_exit(void) +{ + platform_driver_unregister(&mmcc_falcon_driver); +} +module_exit(mmcc_falcon_exit); diff --git a/drivers/clk/qcom/vdd-level-falcon.h b/drivers/clk/qcom/vdd-level-falcon.h index d54e801ecc67..8f9eefe3a89c 100644 --- a/drivers/clk/qcom/vdd-level-falcon.h +++ b/drivers/clk/qcom/vdd-level-falcon.h @@ -116,6 +116,21 @@ }, \ .num_rate_max = VDD_DIG_NUM +#define VDD_MMSS_PLL_DIG_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdd_mx, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMSS_PLL_DIG_FMAX_MAP2(l1, f1, l2, f2) \ + .vdd_class = &vdd_mx, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + }, \ + .num_rate_max = VDD_DIG_NUM + enum vdd_dig_levels { VDD_DIG_NONE, VDD_DIG_MIN, /* MIN SVS */ diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 77aea1f41714..11d88df37d31 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -372,18 +372,18 @@ config CRYPTO_DEV_QCRYPTO config CRYPTO_DEV_QCOM_MSM_QCE tristate "Qualcomm Crypto Engine (QCE) module" - select CRYPTO_DEV_QCE50 if ARCH_APQ8084 || ARCH_MSM8916 || ARCH_MSM8994 || ARCH_MSM8996 || ARCH_MSM8992 || ARCH_MSMTITANIUM || ARCH_MSM8909 || ARCH_MSMCOBALT || ARCH_MSMFALCON || ARCH_MSMTRITON + select CRYPTO_DEV_QCE50 if ARCH_APQ8084 || ARCH_MSM8916 || ARCH_MSM8994 || ARCH_MSM8996 || ARCH_MSM8992 || ARCH_MSMTITANIUM || ARCH_MSM8909 || ARCH_MSM8998 || ARCH_MSMFALCON || ARCH_MSMTRITON default n help This driver supports Qualcomm Crypto Engine in MSM7x30, MSM8660 MSM8x55, MSM8960, MSM9615, MSM8916, MSM8994, MSM8996, FSM9900, - MSMTITANINUM, APQ8084, MSMCOBALT, MSMFALCON and MSMTRITON. + MSMTITANINUM, APQ8084, MSM8998, MSMFALCON and MSMTRITON. To compile this driver as a module, choose M here: the For MSM7x30 MSM8660 and MSM8x55 the module is called qce For MSM8960, APQ8064 and MSM9615 the module is called qce40 For MSM8974, MSM8916, MSM8994, MSM8996, MSM8992, MSMTITANIUM, - APQ8084, MSMCOBALT, MSMFALCON and MSMTRITON the module is called qce50. + APQ8084, MSM8998, MSMFALCON and MSMTRITON the module is called qce50. config CRYPTO_DEV_QCEDEV tristate "QCEDEV Interface to CE module" @@ -391,7 +391,7 @@ config CRYPTO_DEV_QCEDEV help This driver supports Qualcomm QCEDEV Crypto in MSM7x30, MSM8660, MSM8960, MSM9615, APQ8064, MSM8974, MSM8916, MSM8994, MSM8996, - APQ8084, MSMCOBALT, MSMFALCON, MSMTRITON. This exposes the + APQ8084, MSM8998, MSMFALCON, MSMTRITON. This exposes the interface to the QCE hardware accelerator via IOCTLs. To compile this driver as a module, choose M here: the diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index e2099c4e7877..433e4783d1d1 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -603,7 +603,7 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq, while (len > 0) { user_src = (void __user *)qcedev_areq->sha_op_req.data[i].vaddr; - if (user_src && __copy_from_user(k_src, + if (user_src && copy_from_user(k_src, (void __user *)user_src, qcedev_areq->sha_op_req.data[i].len)) return -EFAULT; @@ -639,7 +639,7 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq, /* Copy data from user src(s) */ user_src = (void __user *)qcedev_areq->sha_op_req.data[0].vaddr; - if (user_src && __copy_from_user(k_src, + if (user_src && copy_from_user(k_src, (void __user *)user_src, qcedev_areq->sha_op_req.data[0].len)) { kzfree(k_buf_src); @@ -648,7 +648,7 @@ static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq, k_src += qcedev_areq->sha_op_req.data[0].len; for (i = 1; i < qcedev_areq->sha_op_req.entries; i++) { user_src = (void __user *)qcedev_areq->sha_op_req.data[i].vaddr; - if (user_src && __copy_from_user(k_src, + if (user_src && copy_from_user(k_src, (void __user *)user_src, qcedev_areq->sha_op_req.data[i].len)) { kzfree(k_buf_src); @@ -702,13 +702,6 @@ static int qcedev_sha_update(struct qcedev_async_req *qcedev_areq, return -EINVAL; } - /* verify address src(s) */ - for (i = 0; i < qcedev_areq->sha_op_req.entries; i++) - if (!access_ok(VERIFY_READ, - (void __user *)qcedev_areq->sha_op_req.data[i].vaddr, - qcedev_areq->sha_op_req.data[i].len)) - return -EFAULT; - if (qcedev_areq->sha_op_req.data_len > QCE_MAX_OPER_DATA) { struct qcedev_sha_op_req *saved_req; @@ -868,19 +861,7 @@ static int qcedev_hash_cmac(struct qcedev_async_req *qcedev_areq, total = qcedev_areq->sha_op_req.data_len; - /* verify address src(s) */ - for (i = 0; i < qcedev_areq->sha_op_req.entries; i++) - if (!access_ok(VERIFY_READ, - (void __user *)qcedev_areq->sha_op_req.data[i].vaddr, - qcedev_areq->sha_op_req.data[i].len)) - return -EFAULT; - - /* Verify Source Address */ - if (!access_ok(VERIFY_READ, - (void __user *)qcedev_areq->sha_op_req.authkey, - qcedev_areq->sha_op_req.authklen)) - return -EFAULT; - if (__copy_from_user(&handle->sha_ctxt.authkey[0], + if (copy_from_user(&handle->sha_ctxt.authkey[0], (void __user *)qcedev_areq->sha_op_req.authkey, qcedev_areq->sha_op_req.authklen)) return -EFAULT; @@ -900,7 +881,7 @@ static int qcedev_hash_cmac(struct qcedev_async_req *qcedev_areq, for (i = 0; i < qcedev_areq->sha_op_req.entries; i++) { user_src = (void __user *)qcedev_areq->sha_op_req.data[i].vaddr; - if (user_src && __copy_from_user(k_src, (void __user *)user_src, + if (user_src && copy_from_user(k_src, (void __user *)user_src, qcedev_areq->sha_op_req.data[i].len)) { kzfree(k_buf_src); return -EFAULT; @@ -928,12 +909,7 @@ static int qcedev_set_hmac_auth_key(struct qcedev_async_req *areq, if (areq->sha_op_req.authklen <= QCEDEV_MAX_KEY_SIZE) { qcedev_sha_init(areq, handle); - /* Verify Source Address */ - if (!access_ok(VERIFY_READ, - (void __user *)areq->sha_op_req.authkey, - areq->sha_op_req.authklen)) - return -EFAULT; - if (__copy_from_user(&handle->sha_ctxt.authkey[0], + if (copy_from_user(&handle->sha_ctxt.authkey[0], (void __user *)areq->sha_op_req.authkey, areq->sha_op_req.authklen)) return -EFAULT; @@ -1146,7 +1122,7 @@ static int qcedev_vbuf_ablk_cipher_max_xfer(struct qcedev_async_req *areq, byteoffset = areq->cipher_op_req.byteoffset; user_src = (void __user *)areq->cipher_op_req.vbuf.src[0].vaddr; - if (user_src && __copy_from_user((k_align_src + byteoffset), + if (user_src && copy_from_user((k_align_src + byteoffset), (void __user *)user_src, areq->cipher_op_req.vbuf.src[0].len)) return -EFAULT; @@ -1156,7 +1132,7 @@ static int qcedev_vbuf_ablk_cipher_max_xfer(struct qcedev_async_req *areq, for (i = 1; i < areq->cipher_op_req.entries; i++) { user_src = (void __user *)areq->cipher_op_req.vbuf.src[i].vaddr; - if (user_src && __copy_from_user(k_align_src, + if (user_src && copy_from_user(k_align_src, (void __user *)user_src, areq->cipher_op_req.vbuf.src[i].len)) { return -EFAULT; @@ -1188,7 +1164,7 @@ static int qcedev_vbuf_ablk_cipher_max_xfer(struct qcedev_async_req *areq, while (creq->data_len > 0) { if (creq->vbuf.dst[dst_i].len <= creq->data_len) { - if (err == 0 && __copy_to_user( + if (err == 0 && copy_to_user( (void __user *)creq->vbuf.dst[dst_i].vaddr, (k_align_dst + byteoffset), creq->vbuf.dst[dst_i].len)) @@ -1199,7 +1175,7 @@ static int qcedev_vbuf_ablk_cipher_max_xfer(struct qcedev_async_req *areq, creq->data_len -= creq->vbuf.dst[dst_i].len; dst_i++; } else { - if (err == 0 && __copy_to_user( + if (err == 0 && copy_to_user( (void __user *)creq->vbuf.dst[dst_i].vaddr, (k_align_dst + byteoffset), creq->data_len)) @@ -1531,36 +1507,6 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, __func__, total, req->data_len); goto error; } - /* Verify Source Address's */ - for (i = 0, total = 0; i < req->entries; i++) { - if (total < req->data_len) { - if (!access_ok(VERIFY_READ, - (void __user *)req->vbuf.src[i].vaddr, - req->vbuf.src[i].len)) { - pr_err("%s:SRC RD_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - req->vbuf.src[i].vaddr); - goto error; - } - total += req->vbuf.src[i].len; - } - } - - /* Verify Destination Address's */ - for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) { - if ((req->vbuf.dst[i].vaddr != 0) && - (total < req->data_len)) { - if (!access_ok(VERIFY_WRITE, - (void __user *)req->vbuf.dst[i].vaddr, - req->vbuf.dst[i].len)) { - pr_err("%s:DST WR_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - req->vbuf.dst[i].vaddr); - goto error; - } - total += req->vbuf.dst[i].len; - } - } return 0; error: return -EINVAL; @@ -1656,11 +1602,7 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) switch (cmd) { case QCEDEV_IOCTL_ENC_REQ: case QCEDEV_IOCTL_DEC_REQ: - if (!access_ok(VERIFY_WRITE, (void __user *)arg, - sizeof(struct qcedev_cipher_op_req))) - return -EFAULT; - - if (__copy_from_user(&qcedev_areq.cipher_op_req, + if (copy_from_user(&qcedev_areq.cipher_op_req, (void __user *)arg, sizeof(struct qcedev_cipher_op_req))) return -EFAULT; @@ -1673,20 +1615,17 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) err = qcedev_vbuf_ablk_cipher(&qcedev_areq, handle); if (err) return err; - if (__copy_to_user((void __user *)arg, + if (copy_to_user((void __user *)arg, &qcedev_areq.cipher_op_req, sizeof(struct qcedev_cipher_op_req))) - return -EFAULT; + return -EFAULT; break; case QCEDEV_IOCTL_SHA_INIT_REQ: { struct scatterlist sg_src; - if (!access_ok(VERIFY_WRITE, (void __user *)arg, - sizeof(struct qcedev_sha_op_req))) - return -EFAULT; - if (__copy_from_user(&qcedev_areq.sha_op_req, + if (copy_from_user(&qcedev_areq.sha_op_req, (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1696,9 +1635,9 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) err = qcedev_hash_init(&qcedev_areq, handle, &sg_src); if (err) return err; - if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, + if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) - return -EFAULT; + return -EFAULT; } handle->sha_ctxt.init_done = true; break; @@ -1708,11 +1647,8 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) case QCEDEV_IOCTL_SHA_UPDATE_REQ: { struct scatterlist sg_src; - if (!access_ok(VERIFY_WRITE, (void __user *)arg, - sizeof(struct qcedev_sha_op_req))) - return -EFAULT; - if (__copy_from_user(&qcedev_areq.sha_op_req, + if (copy_from_user(&qcedev_areq.sha_op_req, (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1734,10 +1670,15 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) return err; } + if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) { + pr_err("Invalid sha_ctxt.diglen %d\n", + handle->sha_ctxt.diglen); + return -EINVAL; + } memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); - if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, + if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; } @@ -1749,11 +1690,7 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) pr_err("%s Init was not called\n", __func__); return -EINVAL; } - if (!access_ok(VERIFY_WRITE, (void __user *)arg, - sizeof(struct qcedev_sha_op_req))) - return -EFAULT; - - if (__copy_from_user(&qcedev_areq.sha_op_req, + if (copy_from_user(&qcedev_areq.sha_op_req, (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1767,7 +1704,7 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); - if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, + if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; handle->sha_ctxt.init_done = false; @@ -1776,11 +1713,8 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) case QCEDEV_IOCTL_GET_SHA_REQ: { struct scatterlist sg_src; - if (!access_ok(VERIFY_WRITE, (void __user *)arg, - sizeof(struct qcedev_sha_op_req))) - return -EFAULT; - if (__copy_from_user(&qcedev_areq.sha_op_req, + if (copy_from_user(&qcedev_areq.sha_op_req, (void __user *)arg, sizeof(struct qcedev_sha_op_req))) return -EFAULT; @@ -1798,7 +1732,7 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg) memcpy(&qcedev_areq.sha_op_req.digest[0], &handle->sha_ctxt.digest[0], handle->sha_ctxt.diglen); - if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, + if (copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req, sizeof(struct qcedev_sha_op_req))) return -EFAULT; } 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/gpu/msm/a5xx_reg.h b/drivers/gpu/msm/a5xx_reg.h index 436b6949c414..ef2861ca96dd 100644 --- a/drivers/gpu/msm/a5xx_reg.h +++ b/drivers/gpu/msm/a5xx_reg.h @@ -893,6 +893,11 @@ #define A5XX_GDPM_INT_MASK 0xB811 #define A5XX_GPMU_BEC_ENABLE 0xB9A0 +/* ISENSE registers */ +#define A5XX_GPU_CS_DECIMAL_ALIGN 0xC16A +#define A5XX_GPU_CS_SENSOR_PARAM_CORE_1 0xC126 +#define A5XX_GPU_CS_SENSOR_PARAM_CORE_2 0xC127 +#define A5XX_GPU_CS_SW_OV_FUSE_EN 0xC168 #define A5XX_GPU_CS_SENSOR_GENERAL_STATUS 0xC41A #define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_0 0xC41D #define A5XX_GPU_CS_AMP_CALIBRATION_STATUS1_2 0xC41F @@ -900,5 +905,6 @@ #define A5XX_GPU_CS_ENABLE_REG 0xC520 #define A5XX_GPU_CS_AMP_CALIBRATION_CONTROL1 0xC557 #define A5XX_GPU_CS_AMP_CALIBRATION_DONE 0xC565 +#define A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE 0xC556 #endif /* _A5XX_REG_H */ diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index a02ed40ba9d5..e6163384f9c1 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -269,7 +269,7 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .patchid = ANY_ID, .features = ADRENO_PREEMPTION | ADRENO_64BIT | ADRENO_CONTENT_PROTECTION | - ADRENO_GPMU | ADRENO_SPTP_PC | ADRENO_LM, + ADRENO_GPMU | ADRENO_SPTP_PC, .pm4fw_name = "a530_pm4.fw", .pfpfw_name = "a530_pfp.fw", .zap_name = "a540_zap", @@ -283,4 +283,18 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .gpmu_tsens = 0x000C000D, .max_power = 5448, }, + { + .gpurev = ADRENO_REV_A512, + .core = 5, + .major = 1, + .minor = 2, + .patchid = ANY_ID, + .features = ADRENO_64BIT, + .pm4fw_name = "a530_pm4.fw", + .pfpfw_name = "a530_pfp.fw", + .gpudev = &adreno_a5xx_gpudev, + .gmem_size = (SZ_256K + SZ_16K), + .num_protected_regs = 0x20, + .busy_mask = 0xFFFFFFFE, + }, }; diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index d81142db5b58..1c30b43fdfcf 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -170,6 +170,7 @@ enum adreno_gpurev { ADRENO_REV_A505 = 505, ADRENO_REV_A506 = 506, ADRENO_REV_A510 = 510, + ADRENO_REV_A512 = 512, ADRENO_REV_A530 = 530, ADRENO_REV_A540 = 540, }; @@ -998,6 +999,7 @@ static inline int adreno_is_a5xx(struct adreno_device *adreno_dev) ADRENO_TARGET(a505, ADRENO_REV_A505) ADRENO_TARGET(a506, ADRENO_REV_A506) ADRENO_TARGET(a510, ADRENO_REV_A510) +ADRENO_TARGET(a512, ADRENO_REV_A512) ADRENO_TARGET(a530, ADRENO_REV_A530) ADRENO_TARGET(a540, ADRENO_REV_A540) diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index f652e955b07c..90b833888d9d 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -57,6 +57,7 @@ static const struct adreno_vbif_data a540_vbif[] = { static const struct adreno_vbif_platform a5xx_vbif_platforms[] = { { adreno_is_a540, a540_vbif }, { adreno_is_a530, a530_vbif }, + { adreno_is_a512, a540_vbif }, { adreno_is_a510, a530_vbif }, { adreno_is_a505, a530_vbif }, { adreno_is_a506, a530_vbif }, @@ -254,7 +255,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) return ret; ret = kgsl_allocate_user(&adreno_dev->dev, &crit_pkts_refbuf0, - NULL, PAGE_SIZE, KGSL_MEMFLAGS_SECURE); + PAGE_SIZE, KGSL_MEMFLAGS_SECURE); if (ret) return ret; @@ -431,6 +432,43 @@ static int _poll_gdsc_status(struct adreno_device *adreno_dev, return 0; } +static void a5xx_restore_isense_regs(struct adreno_device *adreno_dev) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + unsigned int reg, i, ramp = GPMU_ISENSE_SAVE; + static unsigned int isense_regs[6] = {0xFFFF}, isense_reg_addr[] = { + A5XX_GPU_CS_DECIMAL_ALIGN, + A5XX_GPU_CS_SENSOR_PARAM_CORE_1, + A5XX_GPU_CS_SENSOR_PARAM_CORE_2, + A5XX_GPU_CS_SW_OV_FUSE_EN, + A5XX_GPU_CS_ENDPOINT_CALIBRATION_DONE, + A5XX_GPMU_TEMP_SENSOR_CONFIG}; + + if (!adreno_is_a540(adreno_dev)) + return; + + /* read signature */ + kgsl_regread(device, ramp++, ®); + + if (reg == 0xBABEFACE) { + /* store memory locations in buffer */ + for (i = 0; i < ARRAY_SIZE(isense_regs); i++) + kgsl_regread(device, ramp + i, isense_regs + i); + + /* clear signature */ + kgsl_regwrite(device, GPMU_ISENSE_SAVE, 0x0); + } + + /* if we never stored memory locations - do nothing */ + if (isense_regs[0] == 0xFFFF) + return; + + /* restore registers from memory */ + for (i = 0; i < ARRAY_SIZE(isense_reg_addr); i++) + kgsl_regwrite(device, isense_reg_addr[i], isense_regs[i]); + +} + /* * a5xx_regulator_enable() - Enable any necessary HW regulators * @adreno_dev: The adreno device pointer @@ -480,6 +518,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev) kgsl_regrmw(device, A5XX_GPMU_GPMU_SP_CLOCK_CONTROL, CNTL_IP_CLK_ENABLE, 1); + a5xx_restore_isense_regs(adreno_dev); return 0; } @@ -1846,7 +1885,7 @@ static void a5xx_start(struct adreno_device *adreno_dev) if (adreno_is_a505_or_a506(adreno_dev)) kgsl_regwrite(device, A5XX_PC_DBG_ECO_CNTL, (0x100 << 11 | 0x100 << 22)); - else if (adreno_is_a510(adreno_dev)) + else if (adreno_is_a510(adreno_dev) || adreno_is_a512(adreno_dev)) kgsl_regwrite(device, A5XX_PC_DBG_ECO_CNTL, (0x200 << 11 | 0x200 << 22)); else @@ -1938,8 +1977,8 @@ static void a5xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A5XX_TPL1_MODE_CNTL, bit << 7); kgsl_regwrite(device, A5XX_RB_MODE_CNTL, bit << 1); - - if (adreno_is_a540(adreno_dev)) + if (adreno_is_a540(adreno_dev) || + adreno_is_a512(adreno_dev)) kgsl_regwrite(device, A5XX_UCHE_DBG_ECO_CNTL_2, bit); } diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h index e424e7a9f228..08fd16a83f30 100644 --- a/drivers/gpu/msm/adreno_a5xx.h +++ b/drivers/gpu/msm/adreno_a5xx.h @@ -228,6 +228,7 @@ void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on); #define LM_SEQUENCE_ID 1 #define MAX_SEQUENCE_ID 3 +#define GPMU_ISENSE_SAVE (A5XX_GPMU_DATA_RAM_BASE + 200/4) /* LM defaults */ #define LM_DEFAULT_LIMIT 6000 #define A530_DEFAULT_LEAKAGE 0x004E001A diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 554eb2dffae4..699d99651f2c 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -176,9 +176,10 @@ int kgsl_memfree_find_entry(pid_t ptname, uint64_t *gpuaddr, return 0; } -static void kgsl_memfree_purge(pid_t ptname, uint64_t gpuaddr, - uint64_t size) +static void kgsl_memfree_purge(struct kgsl_pagetable *pagetable, + uint64_t gpuaddr, uint64_t size) { + pid_t ptname = pagetable ? pagetable->name : 0; int i; if (memfree.list == NULL) @@ -342,60 +343,24 @@ kgsl_mem_entry_destroy(struct kref *kref) } EXPORT_SYMBOL(kgsl_mem_entry_destroy); -/** - * kgsl_mem_entry_track_gpuaddr - Insert a mem_entry in the address tree and - * assign it with a gpu address space before insertion - * @process: the process that owns the memory - * @entry: the memory entry - * - * @returns - 0 on succcess else error code - * - * Insert the kgsl_mem_entry in to the rb_tree for searching by GPU address. - * The assignment of gpu address and insertion into list needs to - * happen with the memory lock held to avoid race conditions between - * gpu address being selected and some other thread looking through the - * rb list in search of memory based on gpuaddr - * This function should be called with processes memory spinlock held - */ -static int -kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, - struct kgsl_mem_entry *entry) +/* Allocate a IOVA for memory objects that don't use SVM */ +static int kgsl_mem_entry_track_gpuaddr(struct kgsl_device *device, + struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) { - struct kgsl_pagetable *pagetable = process->pagetable; + struct kgsl_pagetable *pagetable; /* - * If cpu=gpu map is used then caller needs to set the - * gpu address + * If SVM is enabled for this object then the address needs to be + * assigned elsewhere */ - if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) { - if (!entry->memdesc.gpuaddr) - return 0; - } else if (entry->memdesc.gpuaddr) { - WARN_ONCE(1, "gpuaddr assigned w/o holding memory lock\n"); - return -EINVAL; - } - if (kgsl_memdesc_is_secured(&entry->memdesc)) - pagetable = pagetable->mmu->securepagetable; - - return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); -} + if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) + return 0; -/** - * kgsl_mem_entry_untrack_gpuaddr() - Untrack memory that is previously tracked - * process - Pointer to process private to which memory belongs - * entry - Memory entry to untrack - * - * Function just does the opposite of kgsl_mem_entry_track_gpuaddr. Needs to be - * called with processes spin lock held - */ -static void -kgsl_mem_entry_untrack_gpuaddr(struct kgsl_process_private *process, - struct kgsl_mem_entry *entry) -{ - struct kgsl_pagetable *pagetable = entry->memdesc.pagetable; + pagetable = kgsl_memdesc_is_secured(&entry->memdesc) ? + device->mmu.securepagetable : process->pagetable; - if (entry->memdesc.gpuaddr) - kgsl_mmu_put_gpuaddr(pagetable, &entry->memdesc); + return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); } /* Commit the entry to the process so it can be accessed by other operations */ @@ -409,33 +374,25 @@ static void kgsl_mem_entry_commit_process(struct kgsl_mem_entry *entry) spin_unlock(&entry->priv->mem_lock); } -/** - * kgsl_mem_entry_attach_process - Attach a mem_entry to its owner process - * @entry: the memory entry - * @process: the owner process - * - * Attach a newly created mem_entry to its owner process so that - * it can be found later. The mem_entry will be added to mem_idr and have - * its 'id' field assigned. - * - * @returns - 0 on success or error code on failure. +/* + * Attach the memory object to a process by (possibly) getting a GPU address and + * (possibly) mapping it */ -int -kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, - struct kgsl_device_private *dev_priv) +static int kgsl_mem_entry_attach_process(struct kgsl_device *device, + struct kgsl_process_private *process, + struct kgsl_mem_entry *entry) { - int id; - int ret; - struct kgsl_process_private *process = dev_priv->process_priv; - struct kgsl_pagetable *pagetable = NULL; + int id, ret; ret = kgsl_process_private_get(process); if (!ret) return -EBADF; - ret = kgsl_mem_entry_track_gpuaddr(process, entry); - if (ret) - goto err_put_proc_priv; + ret = kgsl_mem_entry_track_gpuaddr(device, process, entry); + if (ret) { + kgsl_process_private_put(process); + return ret; + } idr_preload(GFP_KERNEL); spin_lock(&process->mem_lock); @@ -445,47 +402,44 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, idr_preload_end(); if (id < 0) { - ret = id; - kgsl_mem_entry_untrack_gpuaddr(process, entry); - goto err_put_proc_priv; + if (!kgsl_memdesc_use_cpu_map(&entry->memdesc)) + kgsl_mmu_put_gpuaddr(&entry->memdesc); + kgsl_process_private_put(process); + return id; } entry->id = id; entry->priv = process; - /* map the memory after unlocking if gpuaddr has been assigned */ + /* + * Map the memory if a GPU address is already assigned, either through + * kgsl_mem_entry_track_gpuaddr() or via some other SVM process + */ if (entry->memdesc.gpuaddr) { - pagetable = process->pagetable; - if (kgsl_memdesc_is_secured(&entry->memdesc)) - pagetable = pagetable->mmu->securepagetable; - - entry->memdesc.pagetable = pagetable; - if (entry->memdesc.flags & KGSL_MEMFLAGS_SPARSE_VIRT) - ret = kgsl_mmu_sparse_dummy_map(pagetable, - &entry->memdesc, 0, entry->memdesc.size); + ret = kgsl_mmu_sparse_dummy_map( + entry->memdesc.pagetable, + &entry->memdesc, 0, + entry->memdesc.size); else if (entry->memdesc.gpuaddr) - ret = kgsl_mmu_map(pagetable, &entry->memdesc); + ret = kgsl_mmu_map(entry->memdesc.pagetable, + &entry->memdesc); + if (ret) kgsl_mem_entry_detach_process(entry); } - kgsl_memfree_purge(pagetable ? pagetable->name : 0, - entry->memdesc.gpuaddr, entry->memdesc.size); - - return ret; + kgsl_memfree_purge(entry->memdesc.pagetable, entry->memdesc.gpuaddr, + entry->memdesc.size); -err_put_proc_priv: - kgsl_process_private_put(process); return ret; } /* Detach a memory entry from a process and unmap it from the MMU */ - static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) { unsigned int type; - int ret; + if (entry == NULL) return; @@ -502,14 +456,7 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) entry->priv->stats[type].cur -= entry->memdesc.size; spin_unlock(&entry->priv->mem_lock); - ret = kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc); - /* - * Do not free the gpuaddr/size if unmap fails. Because if we try - * to map this range in future, the iommu driver will throw - * a BUG_ON() because it feels we are overwriting a mapping. - */ - if (ret == 0) - kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry); + kgsl_mmu_put_gpuaddr(&entry->memdesc); kgsl_process_private_put(entry->priv); @@ -2139,10 +2086,21 @@ static int kgsl_setup_anon_useraddr(struct kgsl_pagetable *pagetable, entry->memdesc.pagetable = pagetable; entry->memdesc.size = (uint64_t) size; entry->memdesc.useraddr = hostptr; - if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) - entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr; entry->memdesc.flags |= KGSL_MEMFLAGS_USERMEM_ADDR; + if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) { + int ret; + + /* Register the address in the database */ + ret = kgsl_mmu_set_svm_region(pagetable, + (uint64_t) entry->memdesc.useraddr, (uint64_t) size); + + if (ret) + return ret; + + entry->memdesc.gpuaddr = (uint64_t) entry->memdesc.useraddr; + } + return memdesc_sg_virt(&entry->memdesc, NULL); } @@ -2392,7 +2350,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv, param->flags = entry->memdesc.flags; - ret = kgsl_mem_entry_attach_process(entry, dev_priv); + ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry); if (ret) goto unmap; @@ -2696,7 +2654,8 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, /* echo back flags */ param->flags = (unsigned int) entry->memdesc.flags; - result = kgsl_mem_entry_attach_process(entry, dev_priv); + result = kgsl_mem_entry_attach_process(dev_priv->device, private, + entry); if (result) goto error_attach; @@ -3089,11 +3048,11 @@ static struct kgsl_mem_entry *gpumem_alloc_entry( entry->memdesc.priv |= KGSL_MEMDESC_SECURE; ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc, - private->pagetable, size, flags); + size, flags); if (ret != 0) goto err; - ret = kgsl_mem_entry_attach_process(entry, dev_priv); + ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry); if (ret != 0) { kgsl_sharedmem_free(&entry->memdesc); goto err; @@ -3292,7 +3251,7 @@ long kgsl_ioctl_sparse_phys_alloc(struct kgsl_device_private *dev_priv, kgsl_memdesc_set_align(&entry->memdesc, ilog2(param->pagesize)); ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc, - process->pagetable, param->size, entry->memdesc.flags); + param->size, entry->memdesc.flags); if (ret) goto err_remove_idr; @@ -3359,6 +3318,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv, long kgsl_ioctl_sparse_virt_alloc(struct kgsl_device_private *dev_priv, unsigned int cmd, void *data) { + struct kgsl_process_private *private = dev_priv->process_priv; struct kgsl_sparse_virt_alloc *param = data; struct kgsl_mem_entry *entry; int ret; @@ -3379,7 +3339,7 @@ long kgsl_ioctl_sparse_virt_alloc(struct kgsl_device_private *dev_priv, spin_lock_init(&entry->bind_lock); entry->bind_tree = RB_ROOT; - ret = kgsl_mem_entry_attach_process(entry, dev_priv); + ret = kgsl_mem_entry_attach_process(dev_priv->device, private, entry); if (ret) { kfree(entry); return ret; @@ -4057,16 +4017,16 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private, return ret; entry->memdesc.gpuaddr = (uint64_t) addr; + entry->memdesc.pagetable = private->pagetable; ret = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (ret) { - kgsl_mmu_put_gpuaddr(private->pagetable, - &entry->memdesc); + kgsl_mmu_put_gpuaddr(&entry->memdesc); return ret; } - kgsl_memfree_purge(private->pagetable ? private->pagetable->name : 0, - entry->memdesc.gpuaddr, entry->memdesc.size); + kgsl_memfree_purge(private->pagetable, entry->memdesc.gpuaddr, + entry->memdesc.size); return addr; } diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 9f35a3197a4c..bc681057250d 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1403,17 +1403,16 @@ static int _setstate_alloc(struct kgsl_device *device, { int ret; - ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, NULL, - PAGE_SIZE); - if (ret) - return ret; + ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, PAGE_SIZE); - /* Mark the setstate memory as read only */ - iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY; + if (!ret) { + /* Mark the setstate memory as read only */ + iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY; - kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE); + kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE); + } - return 0; + return ret; } static int kgsl_iommu_init(struct kgsl_mmu *mmu) @@ -1663,7 +1662,7 @@ static int _iommu_map_guard_page(struct kgsl_pagetable *pt, if (!kgsl_secure_guard_page_memdesc.sgt) { if (kgsl_allocate_user(KGSL_MMU_DEVICE(pt->mmu), - &kgsl_secure_guard_page_memdesc, pt, + &kgsl_secure_guard_page_memdesc, sgp_size, KGSL_MEMFLAGS_SECURE)) { KGSL_CORE_ERR( "Secure guard page alloc failed\n"); @@ -2364,23 +2363,27 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable, } ret = _insert_gpuaddr(pagetable, addr, size); - if (ret == 0) + if (ret == 0) { memdesc->gpuaddr = addr; + memdesc->pagetable = pagetable; + } out: spin_unlock(&pagetable->lock); return ret; } -static void kgsl_iommu_put_gpuaddr(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc) +static void kgsl_iommu_put_gpuaddr(struct kgsl_memdesc *memdesc) { - spin_lock(&pagetable->lock); + if (memdesc->pagetable == NULL) + return; + + spin_lock(&memdesc->pagetable->lock); - if (_remove_gpuaddr(pagetable, memdesc->gpuaddr)) + if (_remove_gpuaddr(memdesc->pagetable, memdesc->gpuaddr)) BUG(); - spin_unlock(&pagetable->lock); + spin_unlock(&memdesc->pagetable->lock); } static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable, diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index f516b7cd245a..46bb6f4656fb 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -424,17 +424,29 @@ EXPORT_SYMBOL(kgsl_mmu_map); * @pagetable: Pagetable to release the memory from * @memdesc: Memory descriptor containing the GPU address to free */ -void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc) +void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc) { + struct kgsl_pagetable *pagetable = memdesc->pagetable; + int unmap_fail = 0; + if (memdesc->size == 0 || memdesc->gpuaddr == 0) return; - if (PT_OP_VALID(pagetable, put_gpuaddr)) - pagetable->pt_ops->put_gpuaddr(pagetable, memdesc); + if (!kgsl_memdesc_is_global(memdesc)) + unmap_fail = kgsl_mmu_unmap(pagetable, memdesc); + + /* + * Do not free the gpuaddr/size if unmap fails. Because if we + * try to map this range in future, the iommu driver will throw + * a BUG_ON() because it feels we are overwriting a mapping. + */ + if (PT_OP_VALID(pagetable, put_gpuaddr) && (unmap_fail == 0)) + pagetable->pt_ops->put_gpuaddr(memdesc); if (!kgsl_memdesc_is_global(memdesc)) memdesc->gpuaddr = 0; + + memdesc->pagetable = NULL; } EXPORT_SYMBOL(kgsl_mmu_put_gpuaddr); @@ -630,7 +642,12 @@ static int nommu_get_gpuaddr(struct kgsl_pagetable *pagetable, memdesc->gpuaddr = (uint64_t) sg_phys(memdesc->sgt->sgl); - return memdesc->gpuaddr != 0 ? 0 : -ENOMEM; + if (memdesc->gpuaddr) { + memdesc->pagetable = pagetable; + return 0; + } + + return -ENOMEM; } static struct kgsl_mmu_pt_ops nommu_pt_ops = { diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 3e32c25b3dbe..bc448d424ccb 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -92,7 +92,7 @@ struct kgsl_mmu_pt_ops { u64 (*get_ttbr0)(struct kgsl_pagetable *); u32 (*get_contextidr)(struct kgsl_pagetable *); int (*get_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); - void (*put_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); + void (*put_gpuaddr)(struct kgsl_memdesc *); uint64_t (*find_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t, uint64_t, uint64_t); int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t); @@ -181,8 +181,7 @@ int kgsl_mmu_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); -void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc); +void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc); unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr); unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, u64 ttbr0, uint64_t addr); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 618e9e9a33a3..283b72c22db4 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -318,12 +318,11 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device, static int kgsl_allocate_secure(struct kgsl_device *device, struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size) { int ret; if (MMU_FEATURE(&device->mmu, KGSL_MMU_HYP_SECURE_ALLOC)) - ret = kgsl_sharedmem_page_alloc_user(memdesc, pagetable, size); + ret = kgsl_sharedmem_page_alloc_user(memdesc, size); else ret = kgsl_cma_alloc_secure(device, memdesc, size); @@ -332,7 +331,6 @@ static int kgsl_allocate_secure(struct kgsl_device *device, int kgsl_allocate_user(struct kgsl_device *device, struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size, uint64_t flags) { int ret; @@ -340,12 +338,11 @@ int kgsl_allocate_user(struct kgsl_device *device, memdesc->flags = flags; if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE) - ret = kgsl_sharedmem_alloc_contig(device, memdesc, - pagetable, size); + ret = kgsl_sharedmem_alloc_contig(device, memdesc, size); else if (flags & KGSL_MEMFLAGS_SECURE) - ret = kgsl_allocate_secure(device, memdesc, pagetable, size); + ret = kgsl_allocate_secure(device, memdesc, size); else - ret = kgsl_sharedmem_page_alloc_user(memdesc, pagetable, size); + ret = kgsl_sharedmem_page_alloc_user(memdesc, size); return ret; } @@ -637,7 +634,6 @@ static inline int get_page_size(size_t size, unsigned int align) int kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size) { int ret = 0; @@ -671,7 +667,6 @@ kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc, len_alloc = PAGE_ALIGN(size) >> PAGE_SHIFT; - memdesc->pagetable = pagetable; memdesc->ops = &kgsl_page_alloc_ops; /* @@ -805,18 +800,8 @@ void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc) if (memdesc == NULL || memdesc->size == 0) return; - if (memdesc->gpuaddr) { - int ret = 0; - - ret = kgsl_mmu_unmap(memdesc->pagetable, memdesc); - /* - * Do not free the gpuaddr/size if unmap fails. Because if we - * try to map this range in future, the iommu driver will throw - * a BUG_ON() because it feels we are overwriting a mapping. - */ - if (ret == 0) - kgsl_mmu_put_gpuaddr(memdesc->pagetable, memdesc); - } + /* Make sure the memory object has been unmapped */ + kgsl_mmu_put_gpuaddr(memdesc); if (memdesc->ops && memdesc->ops->free) memdesc->ops->free(memdesc); @@ -996,8 +981,7 @@ void kgsl_get_memory_usage(char *name, size_t name_size, uint64_t memflags) EXPORT_SYMBOL(kgsl_get_memory_usage); int kgsl_sharedmem_alloc_contig(struct kgsl_device *device, - struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size) + struct kgsl_memdesc *memdesc, uint64_t size) { int result = 0; @@ -1006,7 +990,6 @@ int kgsl_sharedmem_alloc_contig(struct kgsl_device *device, return -EINVAL; memdesc->size = size; - memdesc->pagetable = pagetable; memdesc->ops = &kgsl_cma_ops; memdesc->dev = device->dev->parent; @@ -1097,7 +1080,6 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device, { struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); int result = 0; - struct kgsl_pagetable *pagetable = device->mmu.securepagetable; size_t aligned; /* Align size to 1M boundaries */ @@ -1117,7 +1099,6 @@ static int kgsl_cma_alloc_secure(struct kgsl_device *device, memdesc->priv &= ~KGSL_MEMDESC_GUARD_PAGE; memdesc->size = aligned; - memdesc->pagetable = pagetable; memdesc->ops = &kgsl_cma_ops; memdesc->dev = iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE].dev; diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h index 9e6817c76df8..03f278ead20f 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.h +++ b/drivers/gpu/msm/kgsl_sharedmem.h @@ -26,7 +26,7 @@ struct kgsl_process_private; int kgsl_sharedmem_alloc_contig(struct kgsl_device *device, struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size); + uint64_t size); void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc); @@ -66,13 +66,11 @@ void kgsl_sharedmem_uninit_sysfs(void); int kgsl_allocate_user(struct kgsl_device *device, struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size, uint64_t flags); void kgsl_get_memory_usage(char *str, size_t len, uint64_t memflags); int kgsl_sharedmem_page_alloc_user(struct kgsl_memdesc *memdesc, - struct kgsl_pagetable *pagetable, uint64_t size); #define MEMFLAGS(_flags, _mask, _shift) \ @@ -287,11 +285,10 @@ static inline int kgsl_allocate_global(struct kgsl_device *device, memdesc->priv = priv; if ((memdesc->priv & KGSL_MEMDESC_CONTIG) != 0) - ret = kgsl_sharedmem_alloc_contig(device, memdesc, NULL, + ret = kgsl_sharedmem_alloc_contig(device, memdesc, (size_t) size); else { - ret = kgsl_sharedmem_page_alloc_user(memdesc, NULL, - (size_t) size); + ret = kgsl_sharedmem_page_alloc_user(memdesc, (size_t) size); if (ret == 0) kgsl_memdesc_map(memdesc); } diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9dc9f93f4e36..577183bea07c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1251,6 +1251,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, /* Ignore report if ErrorRollOver */ if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && value[n] >= min && value[n] <= max && + value[n] - min < field->maxusage && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) goto exit; } @@ -1263,11 +1264,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, } if (field->value[n] >= min && field->value[n] <= max + && field->value[n] - min < field->maxusage && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); if (value[n] >= min && value[n] <= max + && value[n] - min < field->maxusage && field->usage[value[n] - min].hid && search(field->value, value[n], count)) hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index e08de7a808eb..0e8fda8b9080 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -20,12 +20,18 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/delay.h> #include <linux/qpnp/qpnp-revid.h> #define FG_ADC_RR_EN_CTL 0x46 #define FG_ADC_RR_SKIN_TEMP_LSB 0x50 #define FG_ADC_RR_SKIN_TEMP_MSB 0x51 #define FG_ADC_RR_RR_ADC_CTL 0x52 +#define FG_ADC_RR_ADC_CTL_CONTINUOUS_SEL_MASK 0x8 +#define FG_ADC_RR_ADC_CTL_CONTINUOUS_SEL BIT(3) +#define FG_ADC_RR_ADC_LOG 0x53 +#define FG_ADC_RR_ADC_LOG_CLR_CTRL_MASK 0xFE +#define FG_ADC_RR_ADC_LOG_CLR_CTRL BIT(0) #define FG_ADC_RR_FAKE_BATT_LOW_LSB 0x58 #define FG_ADC_RR_FAKE_BATT_LOW_MSB 0x59 @@ -68,6 +74,8 @@ #define FG_ADC_RR_USB_IN_V_CTRL 0x90 #define FG_ADC_RR_USB_IN_V_TRIGGER 0x91 +#define FG_ADC_RR_USB_IN_V_EVERY_CYCLE_MASK 0x80 +#define FG_ADC_RR_USB_IN_V_EVERY_CYCLE BIT(7) #define FG_ADC_RR_USB_IN_V_STS 0x92 #define FG_ADC_RR_USB_IN_V_LSB 0x94 #define FG_ADC_RR_USB_IN_V_MSB 0x95 @@ -175,6 +183,9 @@ #define FG_RR_ADC_MAX_CONTINUOUS_BUFFER_LEN 16 #define FG_RR_ADC_STS_CHANNEL_READING_MASK 0x3 +#define FG_RR_CONV_CONTINUOUS_TIME_MIN 80000 +#define FG_RR_CONV_CONTINUOUS_TIME_MAX 81000 + /* * The channel number is not a physical index in hardware, * rather it's a list of supported channels and an index to @@ -230,6 +241,21 @@ struct rradc_chan_prop { u16 adc_code, int *result); }; +static int rradc_masked_write(struct rradc_chip *rr_adc, u16 offset, u8 mask, + u8 val) +{ + int rc; + + rc = regmap_update_bits(rr_adc->regmap, rr_adc->base + offset, + mask, val); + if (rc) { + pr_err("spmi write failed: addr=%03X, rc=%d\n", offset, rc); + return rc; + } + + return rc; +} + static int rradc_read(struct rradc_chip *rr_adc, u16 offset, u8 *data, int len) { int rc = 0, retry_cnt = 0, i = 0; @@ -547,7 +573,7 @@ static const struct rradc_channels rradc_chans[] = { static int rradc_do_conversion(struct rradc_chip *chip, struct rradc_chan_prop *prop, u16 *data) { - int rc = 0, bytes_to_read = 0; + int rc = 0, bytes_to_read = 0, retry = 0; u8 buf[6]; u16 offset = 0, batt_id_5 = 0, batt_id_15 = 0, batt_id_150 = 0; u16 status = 0; @@ -558,7 +584,8 @@ static int rradc_do_conversion(struct rradc_chip *chip, (prop->channel != RR_ADC_CHG_HOT_TEMP) && (prop->channel != RR_ADC_CHG_TOO_HOT_TEMP) && (prop->channel != RR_ADC_SKIN_HOT_TEMP) && - (prop->channel != RR_ADC_SKIN_TOO_HOT_TEMP)) { + (prop->channel != RR_ADC_SKIN_TOO_HOT_TEMP) && + (prop->channel != RR_ADC_USBIN_V)) { /* BATT_ID STS bit does not get set initially */ status = rradc_chans[prop->channel].sts; rc = rradc_read(chip, status, buf, 1); @@ -576,6 +603,85 @@ static int rradc_do_conversion(struct rradc_chip *chip, } } + if (prop->channel == RR_ADC_USBIN_V) { + /* Force conversion every cycle */ + rc = rradc_masked_write(chip, FG_ADC_RR_USB_IN_V_TRIGGER, + FG_ADC_RR_USB_IN_V_EVERY_CYCLE_MASK, + FG_ADC_RR_USB_IN_V_EVERY_CYCLE); + if (rc < 0) { + pr_err("Force every cycle update failed:%d\n", rc); + goto fail; + } + + /* Clear channel log */ + rc = rradc_masked_write(chip, FG_ADC_RR_ADC_LOG, + FG_ADC_RR_ADC_LOG_CLR_CTRL_MASK, + FG_ADC_RR_ADC_LOG_CLR_CTRL); + if (rc < 0) { + pr_err("log ctrl update to clear failed:%d\n", rc); + goto fail; + } + + rc = rradc_masked_write(chip, FG_ADC_RR_ADC_LOG, + FG_ADC_RR_ADC_LOG_CLR_CTRL_MASK, 0); + if (rc < 0) { + pr_err("log ctrl update to not clear failed:%d\n", rc); + goto fail; + } + + /* Switch to continuous mode */ + rc = rradc_masked_write(chip, FG_ADC_RR_RR_ADC_CTL, + FG_ADC_RR_ADC_CTL_CONTINUOUS_SEL_MASK, + FG_ADC_RR_ADC_CTL_CONTINUOUS_SEL); + if (rc < 0) { + pr_err("Update to continuous mode failed:%d\n", rc); + goto fail; + } + + status = rradc_chans[prop->channel].sts; + rc = rradc_read(chip, status, buf, 1); + if (rc < 0) { + pr_err("status read failed:%d\n", rc); + goto fail; + } + + buf[0] &= FG_RR_ADC_STS_CHANNEL_READING_MASK; + while ((buf[0] != FG_RR_ADC_STS_CHANNEL_READING_MASK) && + (retry < 2)) { + pr_debug("%s is not ready; nothing to read\n", + rradc_chans[prop->channel].datasheet_name); + usleep_range(FG_RR_CONV_CONTINUOUS_TIME_MIN, + FG_RR_CONV_CONTINUOUS_TIME_MAX); + retry++; + rc = rradc_read(chip, status, buf, 1); + if (rc < 0) { + pr_err("status read failed:%d\n", rc); + goto fail; + } + } + + /* Switch to non continuous mode */ + rc = rradc_masked_write(chip, FG_ADC_RR_RR_ADC_CTL, + FG_ADC_RR_ADC_CTL_CONTINUOUS_SEL_MASK, 0); + if (rc < 0) { + pr_err("Update to continuous mode failed:%d\n", rc); + goto fail; + } + + /* Restore usb_in trigger */ + rc = rradc_masked_write(chip, FG_ADC_RR_USB_IN_V_TRIGGER, + FG_ADC_RR_USB_IN_V_EVERY_CYCLE_MASK, 0); + if (rc < 0) { + pr_err("Restore every cycle update failed:%d\n", rc); + goto fail; + } + + if (retry >= 2) { + rc = -ENODATA; + goto fail; + } + } + offset = rradc_chans[prop->channel].lsb; if (prop->channel == RR_ADC_BATT_ID) bytes_to_read = 6; diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c index 2282fe005bc7..f001706236ab 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_fw_update.c @@ -1606,6 +1606,13 @@ static ssize_t fwu_sysfs_store_image(struct file *data_file, struct kobject *kobj, struct bin_attribute *attributes, char *buf, loff_t pos, size_t count) { + if (count > (fwu->image_size - fwu->data_pos)) { + dev_err(fwu->rmi4_data->pdev->dev.parent, + "%s: Not enough space in buffer\n", + __func__); + return -EINVAL; + } + memcpy((void *)(&fwu->ext_data_source[fwu->data_pos]), (const void *)buf, count); diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 4ed3fd177f15..eac6d07e6097 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1654,7 +1654,7 @@ static void arm_smmu_secure_domain_unlock(struct arm_smmu_domain *smmu_domain) static unsigned long arm_smmu_pgtbl_lock(struct arm_smmu_domain *smmu_domain) { - unsigned long flags; + unsigned long flags = 0; if (arm_smmu_is_slave_side_secure(smmu_domain)) mutex_lock(&smmu_domain->pgtbl_mutex_lock); diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index ea3d0eed47e1..674ca6161af9 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.c @@ -10,6 +10,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) "flashv2: %s: " fmt, __func__ + #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> @@ -27,6 +29,8 @@ #include <linux/regulator/consumer.h> #include <linux/leds-qpnp-flash.h> #include <linux/leds-qpnp-flash-v2.h> +#include <linux/qpnp/qpnp-revid.h> +#include <linux/log2.h> #include "leds.h" #define FLASH_LED_REG_LED_STATUS1(base) (base + 0x08) @@ -43,9 +47,12 @@ #define FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(base) (base + 0x50) #define FLASH_LED_REG_WARMUP_DELAY(base) (base + 0x51) #define FLASH_LED_REG_ISC_DELAY(base) (base + 0x52) +#define FLASH_LED_REG_THERMAL_RMP_DN_RATE(base) (base + 0x55) #define FLASH_LED_REG_THERMAL_THRSH1(base) (base + 0x56) #define FLASH_LED_REG_THERMAL_THRSH2(base) (base + 0x57) #define FLASH_LED_REG_THERMAL_THRSH3(base) (base + 0x58) +#define FLASH_LED_REG_THERMAL_HYSTERESIS(base) (base + 0x59) +#define FLASH_LED_REG_THERMAL_DEBOUNCE(base) (base + 0x5A) #define FLASH_LED_REG_VPH_DROOP_THRESHOLD(base) (base + 0x61) #define FLASH_LED_REG_VPH_DROOP_DEBOUNCE(base) (base + 0x62) #define FLASH_LED_REG_ILED_GRT_THRSH(base) (base + 0x67) @@ -58,13 +65,10 @@ #define FLASH_LED_REG_LMH_LEVEL(base) (base + 0x70) #define FLASH_LED_REG_CURRENT_DERATE_EN(base) (base + 0x76) -#define FLASH_LED_HDRM_MODE_PRGM_MASK GENMASK(7, 0) #define FLASH_LED_HDRM_VOL_MASK GENMASK(7, 4) #define FLASH_LED_CURRENT_MASK GENMASK(6, 0) #define FLASH_LED_ENABLE_MASK GENMASK(2, 0) #define FLASH_HW_STROBE_MASK GENMASK(2, 0) -#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0) -#define FLASH_LED_INT_RT_STS_MASK GENMASK(7, 0) #define FLASH_LED_ISC_WARMUP_DELAY_MASK GENMASK(1, 0) #define FLASH_LED_CURRENT_DERATE_EN_MASK GENMASK(2, 0) #define FLASH_LED_VPH_DROOP_DEBOUNCE_MASK GENMASK(1, 0) @@ -74,13 +78,19 @@ #define FLASH_LED_LMH_LEVEL_MASK GENMASK(1, 0) #define FLASH_LED_VPH_DROOP_HYSTERESIS_MASK GENMASK(5, 4) #define FLASH_LED_VPH_DROOP_THRESHOLD_MASK GENMASK(2, 0) +#define FLASH_LED_THERMAL_HYSTERESIS_MASK GENMASK(1, 0) +#define FLASH_LED_THERMAL_DEBOUNCE_MASK GENMASK(1, 0) #define FLASH_LED_THERMAL_THRSH_MASK GENMASK(2, 0) -#define FLASH_LED_THERMAL_OTST_MASK GENMASK(2, 0) #define FLASH_LED_MOD_CTRL_MASK BIT(7) #define FLASH_LED_HW_SW_STROBE_SEL_BIT BIT(2) #define FLASH_LED_VPH_DROOP_FAULT_MASK BIT(4) #define FLASH_LED_LMH_MITIGATION_EN_MASK BIT(0) #define FLASH_LED_CHGR_MITIGATION_EN_MASK BIT(4) +#define THERMAL_OTST1_RAMP_CTRL_MASK BIT(7) +#define THERMAL_OTST1_RAMP_CTRL_SHIFT 7 +#define THERMAL_DERATE_SLOW_SHIFT 4 +#define THERMAL_DERATE_SLOW_MASK GENMASK(6, 4) +#define THERMAL_DERATE_FAST_MASK GENMASK(2, 0) #define VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us) (val_us / 8) #define VPH_DROOP_HYST_MV_TO_VAL(val_mv) (val_mv / 25) @@ -89,17 +99,24 @@ #define MITIGATION_THRSH_MA_TO_VAL(val_ma) (val_ma / 100) #define CURRENT_MA_TO_REG_VAL(curr_ma, ires_ua) ((curr_ma * 1000) / ires_ua - 1) #define SAFETY_TMR_TO_REG_VAL(duration_ms) ((duration_ms / 10) - 1) +#define THERMAL_HYST_TEMP_TO_VAL(val, divisor) (val / divisor) #define FLASH_LED_ISC_WARMUP_DELAY_SHIFT 6 #define FLASH_LED_WARMUP_DELAY_DEFAULT 2 #define FLASH_LED_ISC_DELAY_DEFAULT 3 #define FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT 2 +#define FLASH_LED_VPH_DROOP_HYST_SHIFT 4 #define FLASH_LED_VPH_DROOP_HYST_DEFAULT 2 #define FLASH_LED_VPH_DROOP_THRESH_DEFAULT 5 -#define FLASH_LED_VPH_DROOP_DEBOUNCE_MAX 3 -#define FLASH_LED_VPH_DROOP_HYST_MAX 3 +#define FLASH_LED_DEBOUNCE_MAX 3 +#define FLASH_LED_HYSTERESIS_MAX 3 #define FLASH_LED_VPH_DROOP_THRESH_MAX 7 +#define THERMAL_DERATE_SLOW_MAX 314592 +#define THERMAL_DERATE_FAST_MAX 512 +#define THERMAL_DEBOUNCE_TIME_MAX 64 +#define THERMAL_DERATE_HYSTERESIS_MAX 3 #define FLASH_LED_THERMAL_THRSH_MIN 3 +#define FLASH_LED_THERMAL_THRSH_MAX 7 #define FLASH_LED_THERMAL_OTST_LEVELS 3 #define FLASH_LED_VLED_MAX_DEFAULT_UV 3500000 #define FLASH_LED_IBATT_OCP_THRESH_DEFAULT_UA 4500000 @@ -191,32 +208,41 @@ struct flash_switch_data { * Flash LED configuration read from device tree */ struct flash_led_platform_data { - int *thermal_derate_current; - int all_ramp_up_done_irq; - int all_ramp_down_done_irq; - int led_fault_irq; - int ibatt_ocp_threshold_ua; - int vled_max_uv; - int rpara_uohm; - int lmh_rbatt_threshold_uohm; - int lmh_ocv_threshold_uv; - u32 led1n2_iclamp_low_ma; - u32 led1n2_iclamp_mid_ma; - u32 led3_iclamp_low_ma; - u32 led3_iclamp_mid_ma; - u8 isc_delay; - u8 warmup_delay; - u8 current_derate_en_cfg; - u8 vph_droop_threshold; - u8 vph_droop_hysteresis; - u8 vph_droop_debounce; - u8 lmh_mitigation_sel; - u8 chgr_mitigation_sel; - u8 lmh_level; - u8 iled_thrsh_val; - u8 hw_strobe_option; - bool hdrm_auto_mode_en; - bool thermal_derate_en; + struct pmic_revid_data *pmic_rev_id; + int *thermal_derate_current; + int all_ramp_up_done_irq; + int all_ramp_down_done_irq; + int led_fault_irq; + int ibatt_ocp_threshold_ua; + int vled_max_uv; + int rpara_uohm; + int lmh_rbatt_threshold_uohm; + int lmh_ocv_threshold_uv; + int thermal_derate_slow; + int thermal_derate_fast; + int thermal_hysteresis; + int thermal_debounce; + int thermal_thrsh1; + int thermal_thrsh2; + int thermal_thrsh3; + u32 led1n2_iclamp_low_ma; + u32 led1n2_iclamp_mid_ma; + u32 led3_iclamp_low_ma; + u32 led3_iclamp_mid_ma; + u8 isc_delay; + u8 warmup_delay; + u8 current_derate_en_cfg; + u8 vph_droop_threshold; + u8 vph_droop_hysteresis; + u8 vph_droop_debounce; + u8 lmh_mitigation_sel; + u8 chgr_mitigation_sel; + u8 lmh_level; + u8 iled_thrsh_val; + u8 hw_strobe_option; + bool hdrm_auto_mode_en; + bool thermal_derate_en; + bool otst_ramp_bkup_en; }; /* @@ -239,22 +265,54 @@ struct qpnp_flash_led { bool trigger_chgr; }; -static int -qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data) +static int thermal_derate_slow_table[] = { + 128, 256, 512, 1024, 2048, 4096, 8192, 314592, +}; + +static int thermal_derate_fast_table[] = { + 32, 64, 96, 128, 256, 384, 512, +}; + +static int otst1_threshold_table[] = { + 85, 79, 73, 67, 109, 103, 97, 91, +}; + +static int otst2_threshold_table[] = { + 110, 104, 98, 92, 134, 128, 122, 116, +}; + +static int otst3_threshold_table[] = { + 125, 119, 113, 107, 149, 143, 137, 131, +}; + +static int qpnp_flash_led_read(struct qpnp_flash_led *led, u16 addr, u8 *data) { int rc; uint val; rc = regmap_read(led->regmap, addr, &val); - if (rc < 0) - dev_err(&led->pdev->dev, "Unable to read from 0x%04X rc = %d\n", - addr, rc); - else - dev_dbg(&led->pdev->dev, "Read 0x%02X from addr 0x%04X\n", - val, addr); + if (rc < 0) { + pr_err("Unable to read from 0x%04X rc = %d\n", addr, rc); + return rc; + } + pr_debug("Read 0x%02X from addr 0x%04X\n", val, addr); *data = (u8)val; - return rc; + return 0; +} + +static int qpnp_flash_led_write(struct qpnp_flash_led *led, u16 addr, u8 data) +{ + int rc; + + rc = regmap_write(led->regmap, addr, data); + if (rc < 0) { + pr_err("Unable to write to 0x%04X rc = %d\n", addr, rc); + return rc; + } + + pr_debug("Wrote 0x%02X to addr 0x%04X\n", data, addr); + return 0; } static int @@ -279,11 +337,10 @@ qpnp_flash_led_masked_write(struct qpnp_flash_led *led, u16 addr, u8 mask, rc = regmap_update_bits(led->regmap, addr, mask, val); if (rc < 0) - dev_err(&led->pdev->dev, "Unable to update bits from 0x%04X, rc = %d\n", - addr, rc); + pr_err("Unable to update bits from 0x%04X, rc = %d\n", addr, + rc); else - dev_dbg(&led->pdev->dev, "Wrote 0x%02X to addr 0x%04X\n", - val, addr); + pr_debug("Wrote 0x%02X to addr 0x%04X\n", val, addr); return rc; } @@ -297,13 +354,12 @@ led_brightness qpnp_flash_led_brightness_get(struct led_classdev *led_cdev) static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) { int rc, i, addr_offset; - u8 val = 0; + u8 val = 0, mask; for (i = 0; i < led->num_fnodes; i++) { addr_offset = led->fnode[i].id; - rc = qpnp_flash_led_masked_write(led, + rc = qpnp_flash_led_write(led, FLASH_LED_REG_HDRM_PRGM(led->base + addr_offset), - FLASH_LED_HDRM_MODE_PRGM_MASK, led->fnode[i].hdrm_val); if (rc < 0) return rc; @@ -311,9 +367,9 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) val |= 0x1 << led->fnode[i].id; } - rc = qpnp_flash_led_masked_write(led, + rc = qpnp_flash_led_write(led, FLASH_LED_REG_HDRM_AUTO_MODE_CTRL(led->base), - FLASH_LED_HDRM_MODE_PRGM_MASK, val); + val); if (rc < 0) return rc; @@ -338,6 +394,70 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led) if (rc < 0) return rc; + val = (led->pdata->otst_ramp_bkup_en << THERMAL_OTST1_RAMP_CTRL_SHIFT); + mask = THERMAL_OTST1_RAMP_CTRL_MASK; + if (led->pdata->thermal_derate_slow >= 0) { + val |= (led->pdata->thermal_derate_slow << + THERMAL_DERATE_SLOW_SHIFT); + mask |= THERMAL_DERATE_SLOW_MASK; + } + + if (led->pdata->thermal_derate_fast >= 0) { + val |= led->pdata->thermal_derate_fast; + mask |= THERMAL_DERATE_FAST_MASK; + } + + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_RMP_DN_RATE(led->base), + mask, val); + if (rc < 0) + return rc; + + if (led->pdata->thermal_debounce >= 0) { + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_DEBOUNCE(led->base), + FLASH_LED_THERMAL_DEBOUNCE_MASK, + led->pdata->thermal_debounce); + if (rc < 0) + return rc; + } + + if (led->pdata->thermal_hysteresis >= 0) { + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_HYSTERESIS(led->base), + FLASH_LED_THERMAL_HYSTERESIS_MASK, + led->pdata->thermal_hysteresis); + if (rc < 0) + return rc; + } + + if (led->pdata->thermal_thrsh1 >= 0) { + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_THRSH1(led->base), + FLASH_LED_THERMAL_THRSH_MASK, + led->pdata->thermal_thrsh1); + if (rc < 0) + return rc; + } + + if (led->pdata->thermal_thrsh2 >= 0) { + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_THRSH2(led->base), + FLASH_LED_THERMAL_THRSH_MASK, + led->pdata->thermal_thrsh2); + if (rc < 0) + return rc; + } + + if (led->pdata->thermal_thrsh3 >= 0) { + rc = qpnp_flash_led_masked_write(led, + FLASH_LED_REG_THERMAL_THRSH3(led->base), + FLASH_LED_THERMAL_THRSH_MASK, + led->pdata->thermal_thrsh3); + if (rc < 0) + return rc; + } + rc = qpnp_flash_led_masked_write(led, FLASH_LED_REG_VPH_DROOP_DEBOUNCE(led->base), FLASH_LED_VPH_DROOP_DEBOUNCE_MASK, @@ -456,8 +576,7 @@ static int qpnp_flash_led_hw_strobe_enable(struct flash_node_data *fnode, on ? fnode->hw_strobe_state_active : fnode->hw_strobe_state_suspend); if (rc < 0) { - dev_err(&fnode->pdev->dev, - "failed to change hw strobe pin state\n"); + pr_err("failed to change hw strobe pin state\n"); return rc; } } @@ -482,7 +601,7 @@ static int qpnp_flash_led_regulator_enable(struct qpnp_flash_led *led, rc = regulator_disable(snode->vreg); if (rc < 0) { - dev_err(&led->pdev->dev, "regulator_%s failed, rc=%d\n", + pr_err("regulator_%s failed, rc=%d\n", on ? "enable" : "disable", rc); return rc; } @@ -498,14 +617,13 @@ static int get_property_from_fg(struct qpnp_flash_led *led, union power_supply_propval pval = {0, }; if (!led->bms_psy) { - dev_err(&led->pdev->dev, "no bms psy found\n"); + pr_err("no bms psy found\n"); return -EINVAL; } rc = power_supply_get_property(led->bms_psy, prop, &pval); if (rc) { - dev_err(&led->pdev->dev, - "bms psy doesn't support reading prop %d rc = %d\n", + pr_err("bms psy doesn't support reading prop %d rc = %d\n", prop, rc); return rc; } @@ -567,8 +685,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) rc = get_property_from_fg(led, POWER_SUPPLY_PROP_RESISTANCE, &rbatt_uohm); if (rc < 0) { - dev_err(&led->pdev->dev, "bms psy does not support resistance, rc=%d\n", - rc); + pr_err("bms psy does not support resistance, rc=%d\n", rc); return rc; } @@ -578,16 +695,14 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv); if (rc < 0) { - dev_err(&led->pdev->dev, "bms psy does not support OCV, rc=%d\n", - rc); + pr_err("bms psy does not support OCV, rc=%d\n", rc); return rc; } rc = get_property_from_fg(led, POWER_SUPPLY_PROP_CURRENT_NOW, &ibat_now); if (rc < 0) { - dev_err(&led->pdev->dev, "bms psy does not support current, rc=%d\n", - rc); + pr_err("bms psy does not support current, rc=%d\n", rc); return rc; } @@ -606,8 +721,7 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) FLASH_LED_LMH_MITIGATION_EN_MASK, FLASH_LED_LMH_MITIGATION_ENABLE); if (rc < 0) { - dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n", - rc); + pr_err("trigger lmh mitigation failed, rc=%d\n", rc); return rc; } @@ -652,9 +766,8 @@ static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led) * before collapsing the battery. (available power/ flash input voltage) */ avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV); - dev_dbg(&led->pdev->dev, "avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n", - avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, - led->trigger_lmh); + pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n", + avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh); return min(FLASH_LED_MAX_TOTAL_CURRENT_MA, (int)(div64_s64(avail_flash_ua, MCONV))); } @@ -796,8 +909,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) FLASH_LED_LMH_MITIGATION_EN_MASK, FLASH_LED_LMH_MITIGATION_DISABLE); if (rc < 0) { - dev_err(&led->pdev->dev, "disable lmh mitigation failed, rc=%d\n", - rc); + pr_err("disable lmh mitigation failed, rc=%d\n", rc); return rc; } } @@ -808,8 +920,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) FLASH_LED_CHGR_MITIGATION_EN_MASK, FLASH_LED_CHGR_MITIGATION_DISABLE); if (rc < 0) { - dev_err(&led->pdev->dev, "disable chgr mitigation failed, rc=%d\n", - rc); + pr_err("disable chgr mitigation failed, rc=%d\n", rc); return rc; } } @@ -841,8 +952,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) rc = pinctrl_select_state(led->fnode[i].pinctrl, led->fnode[i].gpio_state_suspend); if (rc < 0) { - dev_err(&led->pdev->dev, - "failed to disable GPIO, rc=%d\n", rc); + pr_err("failed to disable GPIO, rc=%d\n", rc); return rc; } } @@ -851,8 +961,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode) rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i], led->pdata->hw_strobe_option, false); if (rc < 0) { - dev_err(&led->pdev->dev, - "Unable to disable hw strobe, rc=%d\n", + pr_err("Unable to disable hw strobe, rc=%d\n", rc); return rc; } @@ -870,8 +979,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) u8 val, mask; if (snode->enabled == on) { - dev_dbg(&led->pdev->dev, "Switch node is already %s!\n", - on ? "enabled" : "disabled"); + pr_debug("Switch node is already %s!\n", + on ? "enabled" : "disabled"); return 0; } @@ -921,9 +1030,9 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) if (rc < 0) return rc; - rc = qpnp_flash_led_masked_write(led, + rc = qpnp_flash_led_write(led, FLASH_LED_REG_SAFETY_TMR(led->base + addr_offset), - FLASH_LED_SAFETY_TMR_MASK, led->fnode[i].duration); + led->fnode[i].duration); if (rc < 0) return rc; @@ -933,8 +1042,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) rc = pinctrl_select_state(led->fnode[i].pinctrl, led->fnode[i].gpio_state_active); if (rc < 0) { - dev_err(&led->pdev->dev, - "failed to enable GPIO\n"); + pr_err("failed to enable GPIO rc=%d\n", rc); return rc; } } @@ -943,8 +1051,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i], led->pdata->hw_strobe_option, true); if (rc < 0) { - dev_err(&led->pdev->dev, - "Unable to enable hw strobe\n"); + pr_err("Unable to enable hw strobe rc=%d\n", + rc); return rc; } } @@ -965,8 +1073,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) FLASH_LED_LMH_MITIGATION_EN_MASK, FLASH_LED_LMH_MITIGATION_ENABLE); if (rc < 0) { - dev_err(&led->pdev->dev, "trigger lmh mitigation failed, rc=%d\n", - rc); + pr_err("trigger lmh mitigation failed, rc=%d\n", rc); return rc; } } @@ -977,8 +1084,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) FLASH_LED_CHGR_MITIGATION_EN_MASK, FLASH_LED_CHGR_MITIGATION_ENABLE); if (rc < 0) { - dev_err(&led->pdev->dev, "trigger chgr mitigation failed, rc=%d\n", - rc); + pr_err("trigger chgr mitigation failed, rc=%d\n", rc); return rc; } } @@ -1010,15 +1116,14 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, led = dev_get_drvdata(&snode->pdev->dev); if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) { - dev_err(&led->pdev->dev, "Invalid options %d\n", options); + pr_err("Invalid options %d\n", options); return -EINVAL; } if (options & ENABLE_REGULATOR) { rc = qpnp_flash_led_regulator_enable(led, snode, true); if (rc < 0) { - dev_err(&led->pdev->dev, - "enable regulator failed, rc=%d\n", rc); + pr_err("enable regulator failed, rc=%d\n", rc); return rc; } } @@ -1026,8 +1131,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, if (options & DISABLE_REGULATOR) { rc = qpnp_flash_led_regulator_enable(led, snode, false); if (rc < 0) { - dev_err(&led->pdev->dev, - "disable regulator failed, rc=%d\n", rc); + pr_err("disable regulator failed, rc=%d\n", rc); return rc; } } @@ -1035,8 +1139,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, if (options & QUERY_MAX_CURRENT) { rc = qpnp_flash_led_get_max_avail_current(led); if (rc < 0) { - dev_err(&led->pdev->dev, - "query max current failed, rc=%d\n", rc); + pr_err("query max current failed, rc=%d\n", rc); return rc; } *max_current = rc; @@ -1076,8 +1179,7 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev, if (snode) { rc = qpnp_flash_led_switch_set(snode, value > 0); if (rc < 0) - dev_err(&led->pdev->dev, - "Failed to set flash LED switch\n"); + pr_err("Failed to set flash LED switch rc=%d\n", rc); } else if (fnode) { qpnp_flash_led_node_set(fnode, value); } @@ -1099,8 +1201,7 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev, rc = qpnp_flash_led_get_max_avail_current(led); if (rc < 0) - dev_err(&led->pdev->dev, "query max current failed, rc=%d\n", - rc); + pr_err("query max current failed, rc=%d\n", rc); return snprintf(buf, PAGE_SIZE, "%d\n", rc); } @@ -1124,7 +1225,7 @@ static int flash_led_psy_notifier_call(struct notifier_block *nb, if (!strcmp(psy->desc->name, "bms")) { led->bms_psy = power_supply_get_by_name("bms"); if (!led->bms_psy) - dev_err(&led->pdev->dev, "Failed to get bms power_supply\n"); + pr_err("Failed to get bms power_supply\n"); else power_supply_unreg_notifier(&led->nb); } @@ -1154,13 +1255,12 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led) int rc; u8 irq_status, led_status1, led_status2; - dev_dbg(&led->pdev->dev, "irq received, irq=%d\n", irq); + pr_debug("irq received, irq=%d\n", irq); rc = qpnp_flash_led_read(led, FLASH_LED_REG_INT_RT_STS(led->base), &irq_status); if (rc < 0) { - dev_err(&led->pdev->dev, "Failed to read interrupt status reg, rc=%d\n", - rc); + pr_err("Failed to read interrupt status reg, rc=%d\n", rc); goto exit; } @@ -1179,29 +1279,27 @@ static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led) rc = qpnp_flash_led_read(led, FLASH_LED_REG_LED_STATUS1(led->base), &led_status1); if (rc < 0) { - dev_err(&led->pdev->dev, "Failed to read led_status1 reg, rc=%d\n", - rc); + pr_err("Failed to read led_status1 reg, rc=%d\n", rc); goto exit; } rc = qpnp_flash_led_read(led, FLASH_LED_REG_LED_STATUS2(led->base), &led_status2); if (rc < 0) { - dev_err(&led->pdev->dev, "Failed to read led_status2 reg, rc=%d\n", - rc); + pr_err("Failed to read led_status2 reg, rc=%d\n", rc); goto exit; } if (led_status1) - dev_emerg(&led->pdev->dev, "led short/open fault detected! led_status1=%x\n", - led_status1); + pr_emerg("led short/open fault detected! led_status1=%x\n", + led_status1); if (led_status2 & FLASH_LED_VPH_DROOP_FAULT_MASK) - dev_emerg(&led->pdev->dev, "led vph_droop fault detected!\n"); + pr_emerg("led vph_droop fault detected!\n"); } - dev_dbg(&led->pdev->dev, "irq handled, irq_type=%x, irq_status=%x\n", - irq_type, irq_status); + pr_debug("irq handled, irq_type=%x, irq_status=%x\n", irq_type, + irq_status); exit: return IRQ_HANDLED; @@ -1231,7 +1329,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, rc = of_property_read_string(node, "qcom,led-name", &fnode->cdev.name); if (rc < 0) { - dev_err(&led->pdev->dev, "Unable to read flash LED names\n"); + pr_err("Unable to read flash LED names\n"); return rc; } @@ -1242,11 +1340,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, } else if (!strcmp(temp_string, "torch")) { fnode->type = FLASH_LED_TYPE_TORCH; } else { - dev_err(&led->pdev->dev, "Wrong flash LED type\n"); + pr_err("Wrong flash LED type\n"); return rc; } } else { - dev_err(&led->pdev->dev, "Unable to read flash LED label\n"); + pr_err("Unable to read flash LED label\n"); return rc; } @@ -1254,14 +1352,14 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, if (!rc) { fnode->id = (u8)val; } else { - dev_err(&led->pdev->dev, "Unable to read flash LED ID\n"); + pr_err("Unable to read flash LED ID\n"); return rc; } rc = of_property_read_string(node, "qcom,default-led-trigger", &fnode->cdev.default_trigger); if (rc < 0) { - dev_err(&led->pdev->dev, "Unable to read trigger name\n"); + pr_err("Unable to read trigger name\n"); return rc; } @@ -1273,7 +1371,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->ires = FLASH_LED_IRES_BASE - (val - FLASH_LED_IRES_MIN_UA) / FLASH_LED_IRES_DIVISOR; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read current resolution\n"); + pr_err("Unable to read current resolution rc=%d\n", rc); return rc; } @@ -1284,8 +1382,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->max_current = val; fnode->cdev.max_brightness = val; } else { - dev_err(&led->pdev->dev, - "Unable to read max current, rc=%d\n", rc); + pr_err("Unable to read max current, rc=%d\n", rc); return rc; } @@ -1293,8 +1390,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, if (!rc) { if (val < FLASH_LED_MIN_CURRENT_MA || val > fnode->max_current) - dev_warn(&led->pdev->dev, - "Invalid operational current specified, capping it\n"); + pr_warn("Invalid operational current specified, capping it\n"); if (val < FLASH_LED_MIN_CURRENT_MA) val = FLASH_LED_MIN_CURRENT_MA; if (val > fnode->max_current) @@ -1302,8 +1398,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->current_ma = val; fnode->cdev.brightness = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read operational current, rc=%d\n", rc); + pr_err("Unable to read operational current, rc=%d\n", rc); return rc; } @@ -1314,13 +1409,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, FLASH_LED_SAFETY_TMR_ENABLE); } else if (rc == -EINVAL) { if (fnode->type == FLASH_LED_TYPE_FLASH) { - dev_err(&led->pdev->dev, - "Timer duration is required for flash LED\n"); + pr_err("Timer duration is required for flash LED\n"); return rc; } } else { - dev_err(&led->pdev->dev, - "Unable to read timer duration\n"); + pr_err("Unable to read timer duration\n"); return rc; } @@ -1332,7 +1425,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->hdrm_val = (val << FLASH_LED_HDRM_VOL_SHIFT) & FLASH_LED_HDRM_VOL_MASK; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read headroom voltage\n"); + pr_err("Unable to read headroom voltage\n"); return rc; } @@ -1343,8 +1436,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, } else if (rc == -EINVAL) { fnode->hdrm_val |= FLASH_LED_HDRM_VOL_HI_LO_WIN_DEFAULT_MV; } else { - dev_err(&led->pdev->dev, - "Unable to read hdrm hi-lo window voltage\n"); + pr_err("Unable to read hdrm hi-lo window voltage\n"); return rc; } @@ -1362,8 +1454,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->hw_strobe_gpio = of_get_named_gpio(node, "qcom,hw-strobe-gpio", 0); if (fnode->hw_strobe_gpio < 0) { - dev_err(&led->pdev->dev, - "Invalid gpio specified\n"); + pr_err("Invalid gpio specified\n"); return fnode->hw_strobe_gpio; } gpio_direction_output(fnode->hw_strobe_gpio, 0); @@ -1373,8 +1464,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, pinctrl_lookup_state(fnode->pinctrl, "strobe_enable"); if (IS_ERR_OR_NULL(fnode->hw_strobe_state_active)) { - dev_err(&led->pdev->dev, - "No active pin for hardware strobe, rc=%ld\n", + pr_err("No active pin for hardware strobe, rc=%ld\n", PTR_ERR(fnode->hw_strobe_state_active)); fnode->hw_strobe_state_active = NULL; } @@ -1383,8 +1473,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, pinctrl_lookup_state(fnode->pinctrl, "strobe_disable"); if (IS_ERR_OR_NULL(fnode->hw_strobe_state_suspend)) { - dev_err(&led->pdev->dev, - "No suspend pin for hardware strobe, rc=%ld\n", + pr_err("No suspend pin for hardware strobe, rc=%ld\n", PTR_ERR(fnode->hw_strobe_state_suspend) ); fnode->hw_strobe_state_suspend = NULL; @@ -1394,8 +1483,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, rc = led_classdev_register(&led->pdev->dev, &fnode->cdev); if (rc < 0) { - dev_err(&led->pdev->dev, "Unable to register led node %d\n", - fnode->id); + pr_err("Unable to register led node %d\n", fnode->id); return rc; } @@ -1403,14 +1491,13 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->pinctrl = devm_pinctrl_get(fnode->cdev.dev); if (IS_ERR_OR_NULL(fnode->pinctrl)) { - dev_dbg(&led->pdev->dev, "No pinctrl defined\n"); + pr_debug("No pinctrl defined\n"); fnode->pinctrl = NULL; } else { fnode->gpio_state_active = pinctrl_lookup_state(fnode->pinctrl, "led_enable"); if (IS_ERR_OR_NULL(fnode->gpio_state_active)) { - dev_err(&led->pdev->dev, - "Cannot lookup LED active state\n"); + pr_err("Cannot lookup LED active state\n"); devm_pinctrl_put(fnode->pinctrl); fnode->pinctrl = NULL; return PTR_ERR(fnode->gpio_state_active); @@ -1419,8 +1506,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led, fnode->gpio_state_suspend = pinctrl_lookup_state(fnode->pinctrl, "led_disable"); if (IS_ERR_OR_NULL(fnode->gpio_state_suspend)) { - dev_err(&led->pdev->dev, - "Cannot lookup LED disable state\n"); + pr_err("Cannot lookup LED disable state\n"); devm_pinctrl_put(fnode->pinctrl); fnode->pinctrl = NULL; return PTR_ERR(fnode->gpio_state_suspend); @@ -1439,8 +1525,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, rc = of_property_read_string(node, "qcom,led-name", &snode->cdev.name); if (rc < 0) { - dev_err(&led->pdev->dev, - "Failed to read switch node name, rc=%d\n", rc); + pr_err("Failed to read switch node name, rc=%d\n", rc); return rc; } @@ -1453,19 +1538,18 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, rc = of_property_read_string(node, "qcom,default-led-trigger", &snode->cdev.default_trigger); if (rc < 0) { - dev_err(&led->pdev->dev, - "Unable to read trigger name, rc=%d\n", rc); + pr_err("Unable to read trigger name, rc=%d\n", rc); return rc; } rc = of_property_read_u32(node, "qcom,led-mask", &snode->led_mask); if (rc < 0) { - dev_err(&led->pdev->dev, "Unable to read led mask rc=%d\n", rc); + pr_err("Unable to read led mask rc=%d\n", rc); return rc; } if (snode->led_mask < 1 || snode->led_mask > 7) { - dev_err(&led->pdev->dev, "Invalid value for led-mask\n"); + pr_err("Invalid value for led-mask\n"); return -EINVAL; } @@ -1476,8 +1560,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, if (IS_ERR_OR_NULL(snode->vreg)) { rc = PTR_ERR(snode->vreg); if (rc != -EPROBE_DEFER) - dev_err(&led->pdev->dev, "Failed to get regulator, rc=%d\n", - rc); + pr_err("Failed to get regulator, rc=%d\n", rc); snode->vreg = NULL; return rc; } @@ -1488,8 +1571,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, snode->cdev.brightness_get = qpnp_flash_led_brightness_get; rc = led_classdev_register(&led->pdev->dev, &snode->cdev); if (rc < 0) { - dev_err(&led->pdev->dev, - "Unable to register led switch node\n"); + pr_err("Unable to register led switch node\n"); return rc; } @@ -1497,13 +1579,53 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, return 0; } +static int get_code_from_table(int *table, int len, int value) +{ + int i; + + for (i = 0; i < len; i++) { + if (value == table[i]) + break; + } + + if (i == len) { + pr_err("Couldn't find %d from table\n", value); + return -ENODATA; + } + + return i; +} + static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, struct device_node *node) { + struct device_node *revid_node; int rc; u32 val; bool short_circuit_det, open_circuit_det, vph_droop_det; + revid_node = of_parse_phandle(node, "qcom,pmic-revid", 0); + if (!revid_node) { + pr_err("Missing qcom,pmic-revid property - driver failed\n"); + return -EINVAL; + } + + led->pdata->pmic_rev_id = get_revid_data(revid_node); + if (IS_ERR_OR_NULL(led->pdata->pmic_rev_id)) { + pr_err("Unable to get pmic_revid rc=%ld\n", + PTR_ERR(led->pdata->pmic_rev_id)); + /* + * the revid peripheral must be registered, any failure + * here only indicates that the rev-id module has not + * probed yet. + */ + return -EPROBE_DEFER; + } + + pr_debug("PMIC subtype %d Digital major %d\n", + led->pdata->pmic_rev_id->pmic_subtype, + led->pdata->pmic_rev_id->rev4); + led->pdata->hdrm_auto_mode_en = of_property_read_bool(node, "qcom,hdrm-auto-mode"); @@ -1513,8 +1635,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, led->pdata->isc_delay = val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read ISC delay, rc=%d\n", rc); + pr_err("Unable to read ISC delay, rc=%d\n", rc); return rc; } @@ -1524,8 +1645,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, led->pdata->warmup_delay = val >> FLASH_LED_ISC_WARMUP_DELAY_SHIFT; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read WARMUP delay, rc=%d\n", rc); + pr_err("Unable to read WARMUP delay, rc=%d\n", rc); return rc; } @@ -1552,26 +1672,128 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, led->pdata->thermal_derate_current, FLASH_LED_THERMAL_OTST_LEVELS); if (rc < 0) { - dev_err(&led->pdev->dev, "Unable to read thermal current limits, rc=%d\n", - rc); + pr_err("Unable to read thermal current limits, rc=%d\n", + rc); return rc; } } + led->pdata->otst_ramp_bkup_en = + !of_property_read_bool(node, "qcom,otst-ramp-back-up-dis"); + + led->pdata->thermal_derate_slow = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-derate-slow", &val); + if (!rc) { + if (val < 0 || val > THERMAL_DERATE_SLOW_MAX) { + pr_err("Invalid thermal_derate_slow %d\n", val); + return -EINVAL; + } + + led->pdata->thermal_derate_slow = + get_code_from_table(thermal_derate_slow_table, + ARRAY_SIZE(thermal_derate_slow_table), val); + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal derate slow, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_derate_fast = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-derate-fast", &val); + if (!rc) { + if (val < 0 || val > THERMAL_DERATE_FAST_MAX) { + pr_err("Invalid thermal_derate_fast %d\n", val); + return -EINVAL; + } + + led->pdata->thermal_derate_fast = + get_code_from_table(thermal_derate_fast_table, + ARRAY_SIZE(thermal_derate_fast_table), val); + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal derate fast, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_debounce = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-debounce", &val); + if (!rc) { + if (val < 0 || val > THERMAL_DEBOUNCE_TIME_MAX) { + pr_err("Invalid thermal_debounce %d\n", val); + return -EINVAL; + } + + if (val >= 0 && val < 16) + led->pdata->thermal_debounce = 0; + else + led->pdata->thermal_debounce = ilog2(val) - 3; + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal debounce, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_hysteresis = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-hysteresis", &val); + if (!rc) { + if (led->pdata->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + val = THERMAL_HYST_TEMP_TO_VAL(val, 20); + else + val = THERMAL_HYST_TEMP_TO_VAL(val, 15); + + if (val < 0 || val > THERMAL_DERATE_HYSTERESIS_MAX) { + pr_err("Invalid thermal_derate_hysteresis %d\n", val); + return -EINVAL; + } + + led->pdata->thermal_hysteresis = val; + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal hysteresis, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_thrsh1 = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-thrsh1", &val); + if (!rc) { + led->pdata->thermal_thrsh1 = + get_code_from_table(otst1_threshold_table, + ARRAY_SIZE(otst1_threshold_table), val); + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal thrsh1, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_thrsh2 = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-thrsh2", &val); + if (!rc) { + led->pdata->thermal_thrsh2 = + get_code_from_table(otst2_threshold_table, + ARRAY_SIZE(otst2_threshold_table), val); + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal thrsh2, rc=%d\n", rc); + return rc; + } + + led->pdata->thermal_thrsh3 = -EINVAL; + rc = of_property_read_u32(node, "qcom,thermal-thrsh3", &val); + if (!rc) { + led->pdata->thermal_thrsh3 = + get_code_from_table(otst3_threshold_table, + ARRAY_SIZE(otst3_threshold_table), val); + } else if (rc != -EINVAL) { + pr_err("Unable to read thermal thrsh3, rc=%d\n", rc); + return rc; + } + led->pdata->vph_droop_debounce = FLASH_LED_VPH_DROOP_DEBOUNCE_DEFAULT; rc = of_property_read_u32(node, "qcom,vph-droop-debounce-us", &val); if (!rc) { led->pdata->vph_droop_debounce = VPH_DROOP_DEBOUNCE_US_TO_VAL(val); } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read VPH droop debounce, rc=%d\n", rc); + pr_err("Unable to read VPH droop debounce, rc=%d\n", rc); return rc; } - if (led->pdata->vph_droop_debounce > FLASH_LED_VPH_DROOP_DEBOUNCE_MAX) { - dev_err(&led->pdev->dev, - "Invalid VPH droop debounce specified"); + if (led->pdata->vph_droop_debounce > FLASH_LED_DEBOUNCE_MAX) { + pr_err("Invalid VPH droop debounce specified\n"); return -EINVAL; } @@ -1581,14 +1803,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, led->pdata->vph_droop_threshold = VPH_DROOP_THRESH_MV_TO_VAL(val); } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read VPH droop threshold, rc=%d\n", rc); + pr_err("Unable to read VPH droop threshold, rc=%d\n", rc); return rc; } if (led->pdata->vph_droop_threshold > FLASH_LED_VPH_DROOP_THRESH_MAX) { - dev_err(&led->pdev->dev, - "Invalid VPH droop threshold specified"); + pr_err("Invalid VPH droop threshold specified\n"); return -EINVAL; } @@ -1599,23 +1819,22 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, led->pdata->vph_droop_hysteresis = VPH_DROOP_HYST_MV_TO_VAL(val); } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to read VPH droop hysteresis, rc=%d\n", rc); + pr_err("Unable to read VPH droop hysteresis, rc=%d\n", rc); return rc; } - if (led->pdata->vph_droop_hysteresis > FLASH_LED_VPH_DROOP_HYST_MAX) { - dev_err(&led->pdev->dev, - "Invalid VPH droop hysteresis specified"); + if (led->pdata->vph_droop_hysteresis > FLASH_LED_HYSTERESIS_MAX) { + pr_err("Invalid VPH droop hysteresis specified\n"); return -EINVAL; } + led->pdata->vph_droop_hysteresis <<= FLASH_LED_VPH_DROOP_HYST_SHIFT; + rc = of_property_read_u32(node, "qcom,hw-strobe-option", &val); if (!rc) { led->pdata->hw_strobe_option = (u8)val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, - "Unable to parse hw strobe option, rc=%d\n", rc); + pr_err("Unable to parse hw strobe option, rc=%d\n", rc); return rc; } @@ -1623,8 +1842,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->led1n2_iclamp_low_ma = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read led1n2_iclamp_low current, rc=%d\n", - rc); + pr_err("Unable to read led1n2_iclamp_low current, rc=%d\n", rc); return rc; } @@ -1632,8 +1850,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->led1n2_iclamp_mid_ma = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read led1n2_iclamp_mid current, rc=%d\n", - rc); + pr_err("Unable to read led1n2_iclamp_mid current, rc=%d\n", rc); return rc; } @@ -1641,8 +1858,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->led3_iclamp_low_ma = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read led3_iclamp_low current, rc=%d\n", - rc); + pr_err("Unable to read led3_iclamp_low current, rc=%d\n", rc); return rc; } @@ -1650,8 +1866,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->led3_iclamp_mid_ma = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to read led3_iclamp_mid current, rc=%d\n", - rc); + pr_err("Unable to read led3_iclamp_mid current, rc=%d\n", rc); return rc; } @@ -1660,8 +1875,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->vled_max_uv = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse vled_max voltage, rc=%d\n", - rc); + pr_err("Unable to parse vled_max voltage, rc=%d\n", rc); return rc; } @@ -1671,8 +1885,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->ibatt_ocp_threshold_ua = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse ibatt_ocp threshold, rc=%d\n", - rc); + pr_err("Unable to parse ibatt_ocp threshold, rc=%d\n", rc); return rc; } @@ -1681,8 +1894,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->rpara_uohm = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse rparasitic, rc=%d\n", - rc); + pr_err("Unable to parse rparasitic, rc=%d\n", rc); return rc; } @@ -1692,8 +1904,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->lmh_ocv_threshold_uv = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse lmh ocv threshold, rc=%d\n", - rc); + pr_err("Unable to parse lmh ocv threshold, rc=%d\n", rc); return rc; } @@ -1703,8 +1914,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->lmh_rbatt_threshold_uohm = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse lmh rbatt threshold, rc=%d\n", - rc); + pr_err("Unable to parse lmh rbatt threshold, rc=%d\n", rc); return rc; } @@ -1713,8 +1923,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->lmh_level = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse lmh_level, rc=%d\n", - rc); + pr_err("Unable to parse lmh_level, rc=%d\n", rc); return rc; } @@ -1723,13 +1932,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->lmh_mitigation_sel = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse lmh_mitigation_sel, rc=%d\n", - rc); + pr_err("Unable to parse lmh_mitigation_sel, rc=%d\n", rc); return rc; } if (led->pdata->lmh_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) { - dev_err(&led->pdev->dev, "Invalid lmh_mitigation_sel specified\n"); + pr_err("Invalid lmh_mitigation_sel specified\n"); return -EINVAL; } @@ -1738,13 +1946,12 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->chgr_mitigation_sel = val; } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse chgr_mitigation_sel, rc=%d\n", - rc); + pr_err("Unable to parse chgr_mitigation_sel, rc=%d\n", rc); return rc; } if (led->pdata->chgr_mitigation_sel > FLASH_LED_MITIGATION_SEL_MAX) { - dev_err(&led->pdev->dev, "Invalid chgr_mitigation_sel specified\n"); + pr_err("Invalid chgr_mitigation_sel specified\n"); return -EINVAL; } @@ -1755,30 +1962,29 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led, if (!rc) { led->pdata->iled_thrsh_val = MITIGATION_THRSH_MA_TO_VAL(val); } else if (rc != -EINVAL) { - dev_err(&led->pdev->dev, "Unable to parse iled_thrsh_val, rc=%d\n", - rc); + pr_err("Unable to parse iled_thrsh_val, rc=%d\n", rc); return rc; } if (led->pdata->iled_thrsh_val > FLASH_LED_MITIGATION_THRSH_MAX) { - dev_err(&led->pdev->dev, "Invalid iled_thrsh_val specified\n"); + pr_err("Invalid iled_thrsh_val specified\n"); return -EINVAL; } led->pdata->all_ramp_up_done_irq = of_irq_get_byname(node, "all-ramp-up-done-irq"); if (led->pdata->all_ramp_up_done_irq < 0) - dev_dbg(&led->pdev->dev, "all-ramp-up-done-irq not used\n"); + pr_debug("all-ramp-up-done-irq not used\n"); led->pdata->all_ramp_down_done_irq = of_irq_get_byname(node, "all-ramp-down-done-irq"); if (led->pdata->all_ramp_down_done_irq < 0) - dev_dbg(&led->pdev->dev, "all-ramp-down-done-irq not used\n"); + pr_debug("all-ramp-down-done-irq not used\n"); led->pdata->led_fault_irq = of_irq_get_byname(node, "led-fault-irq"); if (led->pdata->led_fault_irq < 0) - dev_dbg(&led->pdev->dev, "led-fault-irq not used\n"); + pr_debug("led-fault-irq not used\n"); return 0; } @@ -1793,14 +1999,14 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) node = pdev->dev.of_node; if (!node) { - dev_info(&pdev->dev, "No flash LED nodes defined\n"); + pr_err("No flash LED nodes defined\n"); return -ENODEV; } rc = of_property_read_u32(node, "reg", &base); if (rc < 0) { - dev_err(&pdev->dev, "Couldn't find reg in node %s, rc = %d\n", - node->full_name, rc); + pr_err("Couldn't find reg in node %s, rc = %d\n", + node->full_name, rc); return rc; } @@ -1811,7 +2017,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) led->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!led->regmap) { - dev_err(&pdev->dev, "Couldn't get parent's regmap\n"); + pr_err("Couldn't get parent's regmap\n"); return -EINVAL; } @@ -1824,16 +2030,14 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) rc = qpnp_flash_led_parse_common_dt(led, node); if (rc < 0) { - dev_err(&pdev->dev, - "Failed to parse common flash LED device tree\n"); + pr_err("Failed to parse common flash LED device tree\n"); return rc; } for_each_available_child_of_node(node, temp) { rc = of_property_read_string(temp, "label", &temp_string); if (rc < 0) { - dev_err(&pdev->dev, - "Failed to parse label, rc=%d\n", rc); + pr_err("Failed to parse label, rc=%d\n", rc); return rc; } @@ -1843,14 +2047,13 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) !strcmp("torch", temp_string)) { led->num_fnodes++; } else { - dev_err(&pdev->dev, - "Invalid label for led node\n"); + pr_err("Invalid label for led node\n"); return -EINVAL; } } if (!led->num_fnodes) { - dev_err(&pdev->dev, "No LED nodes defined\n"); + pr_err("No LED nodes defined\n"); return -ECHILD; } @@ -1872,8 +2075,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) for_each_available_child_of_node(node, temp) { rc = of_property_read_string(temp, "label", &temp_string); if (rc < 0) { - dev_err(&pdev->dev, - "Failed to parse label, rc=%d\n", rc); + pr_err("Failed to parse label, rc=%d\n", rc); return rc; } @@ -1882,7 +2084,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) rc = qpnp_flash_led_parse_each_led_dt(led, &led->fnode[i++], temp); if (rc < 0) { - dev_err(&pdev->dev, "Unable to parse flash node %d rc=%d\n", + pr_err("Unable to parse flash node %d rc=%d\n", i, rc); goto error_led_register; } @@ -1892,7 +2094,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) rc = qpnp_flash_led_parse_and_register_switch(led, &led->snode[j++], temp); if (rc < 0) { - dev_err(&pdev->dev, "Unable to parse and register switch node, rc=%d\n", + pr_err("Unable to parse and register switch node, rc=%d\n", rc); goto error_switch_register; } @@ -1907,8 +2109,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) IRQF_ONESHOT, "qpnp_flash_led_all_ramp_up_done_irq", led); if (rc < 0) { - dev_err(&pdev->dev, - "Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n", + pr_err("Unable to request all_ramp_up_done(%d) IRQ(err:%d)\n", led->pdata->all_ramp_up_done_irq, rc); goto error_switch_register; } @@ -1921,8 +2122,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) IRQF_ONESHOT, "qpnp_flash_led_all_ramp_down_done_irq", led); if (rc < 0) { - dev_err(&pdev->dev, - "Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n", + pr_err("Unable to request all_ramp_down_done(%d) IRQ(err:%d)\n", led->pdata->all_ramp_down_done_irq, rc); goto error_switch_register; } @@ -1935,8 +2135,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) IRQF_ONESHOT, "qpnp_flash_led_fault_irq", led); if (rc < 0) { - dev_err(&pdev->dev, - "Unable to request led_fault(%d) IRQ(err:%d)\n", + pr_err("Unable to request led_fault(%d) IRQ(err:%d)\n", led->pdata->led_fault_irq, rc); goto error_switch_register; } @@ -1946,16 +2145,14 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) if (!led->bms_psy) { rc = flash_led_psy_register_notifier(led); if (rc < 0) { - dev_err(&pdev->dev, "Couldn't register psy notifier, rc = %d\n", - rc); + pr_err("Couldn't register psy notifier, rc = %d\n", rc); goto error_switch_register; } } rc = qpnp_flash_led_init_settings(led); if (rc < 0) { - dev_err(&pdev->dev, - "Failed to initialize flash LED, rc=%d\n", rc); + pr_err("Failed to initialize flash LED, rc=%d\n", rc); goto unreg_notifier; } @@ -1964,8 +2161,7 @@ static int qpnp_flash_led_probe(struct platform_device *pdev) rc = sysfs_create_file(&led->snode[i].cdev.dev->kobj, &qpnp_flash_led_attrs[j].attr); if (rc < 0) { - dev_err(&pdev->dev, "sysfs creation failed, rc=%d\n", - rc); + pr_err("sysfs creation failed, rc=%d\n", rc); goto sysfs_fail; } } diff --git a/drivers/leds/leds-qpnp-flash.c b/drivers/leds/leds-qpnp-flash.c index 95b4c42a5adb..98dfa56add51 100644 --- a/drivers/leds/leds-qpnp-flash.c +++ b/drivers/leds/leds-qpnp-flash.c @@ -82,7 +82,6 @@ #define FLASH_LED_HDRM_SNS_ENABLE_MASK 0x81 #define FLASH_MASK_MODULE_CONTRL_MASK 0xE0 #define FLASH_FOLLOW_OTST2_RB_MASK 0x08 -#define FLASH_PREPARE_OPTIONS_MASK 0x08 #define FLASH_LED_TRIGGER_DEFAULT "none" #define FLASH_LED_HEADROOM_DEFAULT_MV 500 @@ -1172,7 +1171,7 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options, flash_node = container_of(led_cdev, struct flash_node_data, cdev); led = dev_get_drvdata(&flash_node->pdev->dev); - if (!(options & FLASH_PREPARE_OPTIONS_MASK)) { + if (!(options & FLASH_LED_PREPARE_OPTIONS_MASK)) { dev_err(&led->pdev->dev, "Invalid options %d\n", options); return -EINVAL; } diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c index 894c1d88b3ef..9695c35c56b4 100644 --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -50,6 +50,7 @@ #define QPNP_WLED_VLOOP_COMP_RES_REG(b) (b + 0x55) #define QPNP_WLED_VLOOP_COMP_GM_REG(b) (b + 0x56) #define QPNP_WLED_PSM_CTRL_REG(b) (b + 0x5B) +#define QPNP_WLED_LCD_AUTO_PFM_REG(b) (b + 0x5C) #define QPNP_WLED_SC_PRO_REG(b) (b + 0x5E) #define QPNP_WLED_SWIRE_AVDD_REG(b) (b + 0x5F) #define QPNP_WLED_CTRL_SPARE_REG(b) (b + 0xDF) @@ -61,11 +62,7 @@ #define QPNP_WLED_EN_MASK 0x7F #define QPNP_WLED_EN_SHIFT 7 #define QPNP_WLED_FDBK_OP_MASK 0xF8 -#define QPNP_WLED_VREF_MASK 0xF0 -#define QPNP_WLED_VREF_STEP_MV 25 -#define QPNP_WLED_VREF_MIN_MV 300 -#define QPNP_WLED_VREF_MAX_MV 675 -#define QPNP_WLED_DFLT_VREF_MV 350 +#define QPNP_WLED_VREF_MASK GENMASK(3, 0) #define QPNP_WLED_VLOOP_COMP_RES_MASK 0xF0 #define QPNP_WLED_VLOOP_COMP_RES_OVERWRITE 0x80 @@ -73,17 +70,29 @@ #define QPNP_WLED_LOOP_COMP_RES_STEP_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MIN_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MAX_KOHM 320 -#define QPNP_WLED_VLOOP_COMP_GM_MASK 0xF0 +#define QPNP_WLED_VLOOP_COMP_GM_MASK GENMASK(3, 0) #define QPNP_WLED_VLOOP_COMP_GM_OVERWRITE 0x80 -#define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED 0x03 +#define QPNP_WLED_VLOOP_COMP_AUTO_GM_EN BIT(6) +#define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK GENMASK(5, 4) +#define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT 4 +#define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994 0x03 +#define QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMI8998 0x09 +#define QPNP_WLED_LOOP_GM_DFLT_WLED 0x09 #define QPNP_WLED_LOOP_EA_GM_MIN 0x0 #define QPNP_WLED_LOOP_EA_GM_MAX 0xF +#define QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX 3 +#define QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH 1 #define QPNP_WLED_VREF_PSM_MASK 0xF8 #define QPNP_WLED_VREF_PSM_STEP_MV 50 #define QPNP_WLED_VREF_PSM_MIN_MV 400 #define QPNP_WLED_VREF_PSM_MAX_MV 750 #define QPNP_WLED_VREF_PSM_DFLT_AMOLED_MV 450 #define QPNP_WLED_PSM_CTRL_OVERWRITE 0x80 +#define QPNP_WLED_LCD_AUTO_PFM_DFLT_THRESH 1 +#define QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX 0xF +#define QPNP_WLED_LCD_AUTO_PFM_EN_SHIFT 7 +#define QPNP_WLED_LCD_AUTO_PFM_EN_BIT BIT(7) +#define QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK GENMASK(3, 0) #define QPNP_WLED_ILIM_MASK GENMASK(2, 0) #define QPNP_WLED_ILIM_OVERWRITE BIT(7) @@ -91,9 +100,9 @@ #define PMI8994_WLED_ILIM_MAX_MA 1980 #define PMI8994_WLED_DFLT_ILIM_MA 980 #define PMI8994_AMOLED_DFLT_ILIM_MA 385 -#define PMICOBALT_WLED_ILIM_MAX_MA 1500 -#define PMICOBALT_WLED_DFLT_ILIM_MA 970 -#define PMICOBALT_AMOLED_DFLT_ILIM_MA 620 +#define PMI8998_WLED_ILIM_MAX_MA 1500 +#define PMI8998_WLED_DFLT_ILIM_MA 970 +#define PMI8998_AMOLED_DFLT_ILIM_MA 620 #define QPNP_WLED_BOOST_DUTY_MASK 0xFC #define QPNP_WLED_BOOST_DUTY_STEP_NS 52 #define QPNP_WLED_BOOST_DUTY_MIN_NS 26 @@ -263,7 +272,7 @@ static int qpnp_wled_ovp_thresholds_pmi8994[NUM_SUPPORTED_OVP_THRESHOLDS] = { 31000, 29500, 19400, 17800, }; -static int qpnp_wled_ovp_thresholds_pmicobalt[NUM_SUPPORTED_OVP_THRESHOLDS] = { +static int qpnp_wled_ovp_thresholds_pmi8998[NUM_SUPPORTED_OVP_THRESHOLDS] = { 31100, 29600, 19600, 18100, }; @@ -271,10 +280,24 @@ static int qpnp_wled_ilim_settings_pmi8994[NUM_SUPPORTED_ILIM_THRESHOLDS] = { 105, 385, 660, 980, 1150, 1420, 1700, 1980, }; -static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = { +static int qpnp_wled_ilim_settings_pmi8998[NUM_SUPPORTED_ILIM_THRESHOLDS] = { 105, 280, 450, 620, 970, 1150, 1300, 1500, }; +struct wled_vref_setting { + u32 min_uv; + u32 max_uv; + u32 step_uv; + u32 default_uv; +}; + +static struct wled_vref_setting vref_setting_pmi8994 = { + 300000, 675000, 25000, 350000, +}; +static struct wled_vref_setting vref_setting_pmi8998 = { + 60000, 397500, 22500, 127500, +}; + /** * qpnp_wled - wed data structure * @ cdev - led class device @@ -294,7 +317,7 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = { * @ mod_freq_khz - modulator frequency in KHZ * @ hyb_thres - threshold for hybrid dimming * @ sync_dly_us - sync delay in us - * @ vref_mv - ref voltage in mv + * @ vref_uv - ref voltage in uv * @ vref_psm_mv - ref psm voltage in mv * @ loop_comp_res_kohm - control to select the compensation resistor * @ loop_ea_gm - control to select the gm for the gm stage in control loop @@ -309,6 +332,10 @@ static int qpnp_wled_ilim_settings_pmicobalt[NUM_SUPPORTED_ILIM_THRESHOLDS] = { * @ cons_sync_write_delay_us - delay between two consecutive writes to SYNC * @ strings - supported list of strings * @ num_strings - number of strings + * @ loop_auto_gm_thresh - the clamping level for auto gm + * @ lcd_auto_pfm_thresh - the threshold for lcd auto pfm mode + * @ loop_auto_gm_en - select if auto gm is enabled + * @ lcd_auto_pfm_en - select if auto pfm is enabled in lcd mode * @ avdd_mode_spmi - enable avdd programming via spmi * @ en_9b_dim_res - enable or disable 9bit dimming * @ en_phase_stag - enable or disable phase staggering @@ -337,7 +364,7 @@ struct qpnp_wled { u16 mod_freq_khz; u16 hyb_thres; u16 sync_dly_us; - u16 vref_mv; + u32 vref_uv; u16 vref_psm_mv; u16 loop_comp_res_kohm; u16 loop_ea_gm; @@ -352,6 +379,10 @@ struct qpnp_wled { u16 cons_sync_write_delay_us; u8 strings[QPNP_WLED_MAX_STRINGS]; u8 num_strings; + u8 loop_auto_gm_thresh; + u8 lcd_auto_pfm_thresh; + bool loop_auto_gm_en; + bool lcd_auto_pfm_en; bool avdd_mode_spmi; bool en_9b_dim_res; bool en_phase_stag; @@ -977,24 +1008,6 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr) if (rc) return rc; - /* Configure the LOOP COMP GM register for AMOLED */ - if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) - wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; - else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) - wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; - - rc = qpnp_wled_read_reg(wled, ®, - QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); - if (rc < 0) - return rc; - - reg &= QPNP_WLED_VLOOP_COMP_GM_MASK; - reg |= (wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE); - rc = qpnp_wled_write_reg(wled, reg, - QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); - if (rc) - return rc; - /* Configure the CTRL TEST4 register for AMOLED */ rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_TEST4_REG(wled->ctrl_base)); @@ -1051,10 +1064,10 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled) u8 reg = 0; /* - * AVDD trim adjustment is not required for pmicobalt/pm2falcon and not + * AVDD trim adjustment is not required for pmi8998/pm2falcon and not * supported for pmi8994. */ - if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PMI8994_SUBTYPE) return false; @@ -1074,6 +1087,45 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled) return !(reg & QPNP_WLED_AVDD_SET_BIT); } +static int qpnp_wled_gm_config(struct qpnp_wled *wled) +{ + int rc; + u8 mask = 0, reg = 0; + + /* Configure the LOOP COMP GM register */ + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { + if (wled->loop_auto_gm_en) + reg |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN; + + if (wled->loop_auto_gm_thresh > + QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX) + wled->loop_auto_gm_thresh = + QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX; + + reg |= wled->loop_auto_gm_thresh << + QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT; + mask |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN | + QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK; + } + + if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) + wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; + else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) + wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; + + reg |= wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; + mask |= QPNP_WLED_VLOOP_COMP_GM_MASK | + QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; + + rc = qpnp_wled_masked_write_reg(wled, mask, ®, + QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); + if (rc) + pr_err("write VLOOP_COMP_GM_REG failed, rc=%d]\n", rc); + + return rc; +} + static int qpnp_wled_ovp_config(struct qpnp_wled *wled) { int rc, i, *ovp_table; @@ -1086,9 +1138,9 @@ static int qpnp_wled_ovp_config(struct qpnp_wled *wled) if (wled->disp_type_amoled) return 0; - if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) - ovp_table = qpnp_wled_ovp_thresholds_pmicobalt; + ovp_table = qpnp_wled_ovp_thresholds_pmi8998; else ovp_table = qpnp_wled_ovp_thresholds_pmi8994; @@ -1170,9 +1222,9 @@ static int qpnp_wled_avdd_mode_config(struct qpnp_wled *wled) /* * At present, configuring the mode to SPMI/SWIRE for controlling - * AVDD voltage is available only in pmicobalt/pm2falcon. + * AVDD voltage is available only in pmi8998/pm2falcon. */ - if (wled->pmic_rev_id->pmic_subtype != PMICOBALT_SUBTYPE && + if (wled->pmic_rev_id->pmic_subtype != PMI8998_SUBTYPE && wled->pmic_rev_id->pmic_subtype != PM2FALCON_SUBTYPE) return 0; @@ -1216,11 +1268,11 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled) if (wled->ilim_ma < PMI8994_WLED_ILIM_MIN_MA) wled->ilim_ma = PMI8994_WLED_ILIM_MIN_MA; - if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { - ilim_table = qpnp_wled_ilim_settings_pmicobalt; - if (wled->ilim_ma > PMICOBALT_WLED_ILIM_MAX_MA) - wled->ilim_ma = PMICOBALT_WLED_ILIM_MAX_MA; + ilim_table = qpnp_wled_ilim_settings_pmi8998; + if (wled->ilim_ma > PMI8998_WLED_ILIM_MAX_MA) + wled->ilim_ma = PMI8998_WLED_ILIM_MAX_MA; } else { ilim_table = qpnp_wled_ilim_settings_pmi8994; if (wled->ilim_ma > PMI8994_WLED_ILIM_MAX_MA) @@ -1248,6 +1300,35 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled) return rc; } +static int qpnp_wled_vref_config(struct qpnp_wled *wled) +{ + + struct wled_vref_setting vref_setting; + int rc; + u8 reg = 0; + + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + vref_setting = vref_setting_pmi8998; + else + vref_setting = vref_setting_pmi8994; + + if (wled->vref_uv < vref_setting.min_uv) + wled->vref_uv = vref_setting.min_uv; + else if (wled->vref_uv > vref_setting.max_uv) + wled->vref_uv = vref_setting.max_uv; + + reg |= DIV_ROUND_CLOSEST(wled->vref_uv - vref_setting.min_uv, + vref_setting.step_uv); + + rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_VREF_MASK, + ®, QPNP_WLED_VREF_REG(wled->ctrl_base)); + if (rc) + pr_err("Write VREF_REG failed, rc=%d\n", rc); + + return rc; +} + /* Configure WLED registers */ static int qpnp_wled_config(struct qpnp_wled *wled) { @@ -1272,22 +1353,18 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; /* Configure the VREF register */ - if (wled->vref_mv < QPNP_WLED_VREF_MIN_MV) - wled->vref_mv = QPNP_WLED_VREF_MIN_MV; - else if (wled->vref_mv > QPNP_WLED_VREF_MAX_MV) - wled->vref_mv = QPNP_WLED_VREF_MAX_MV; - - rc = qpnp_wled_read_reg(wled, ®, - QPNP_WLED_VREF_REG(wled->ctrl_base)); - if (rc < 0) + rc = qpnp_wled_vref_config(wled); + if (rc < 0) { + pr_err("Error in configuring wled vref, rc=%d\n", rc); return rc; - reg &= QPNP_WLED_VREF_MASK; - temp = wled->vref_mv - QPNP_WLED_VREF_MIN_MV; - reg |= (temp / QPNP_WLED_VREF_STEP_MV); - rc = qpnp_wled_write_reg(wled, reg, - QPNP_WLED_VREF_REG(wled->ctrl_base)); - if (rc) + } + + /* Configure VLOOP_COMP_GM register */ + rc = qpnp_wled_gm_config(wled); + if (rc < 0) { + pr_err("Error in configureing wled gm, rc=%d\n", rc); return rc; + } /* Configure the ILIM register */ rc = qpnp_wled_ilim_config(wled); @@ -1296,6 +1373,24 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; } + /* Configure auto PFM mode for LCD mode only */ + if ((wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + && !wled->disp_type_amoled) { + reg = 0; + reg |= wled->lcd_auto_pfm_thresh; + reg |= wled->lcd_auto_pfm_en << + QPNP_WLED_LCD_AUTO_PFM_EN_SHIFT; + rc = qpnp_wled_masked_write_reg(wled, + QPNP_WLED_LCD_AUTO_PFM_EN_BIT | + QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK, ®, + QPNP_WLED_LCD_AUTO_PFM_REG(wled->ctrl_base)); + if (rc < 0) { + pr_err("Write LCD_AUTO_PFM failed, rc=%d\n", rc); + return rc; + } + } + /* Configure the Soft start Ramp delay: for AMOLED - 0,for LCD - 2 */ reg = (wled->disp_type_amoled) ? 0 : 2; rc = qpnp_wled_write_reg(wled, reg, @@ -1661,16 +1756,6 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } - wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED; - rc = of_property_read_u32(pdev->dev.of_node, - "qcom,loop-ea-gm", &temp_val); - if (!rc) { - wled->loop_ea_gm = temp_val; - } else if (rc != -EINVAL) { - dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); - return rc; - } - wled->avdd_mode_spmi = of_property_read_bool(pdev->dev.of_node, "qcom,avdd-mode-spmi"); @@ -1685,6 +1770,67 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) } } + if (wled->disp_type_amoled) { + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + wled->loop_ea_gm = + QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMI8998; + else + wled->loop_ea_gm = + QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994; + } else { + wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_WLED; + } + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,loop-ea-gm", &temp_val); + if (!rc) { + wled->loop_ea_gm = temp_val; + } else if (rc != -EINVAL) { + dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); + return rc; + } + + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { + wled->loop_auto_gm_en = + of_property_read_bool(pdev->dev.of_node, + "qcom,loop-auto-gm-en"); + wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH; + rc = of_property_read_u8(pdev->dev.of_node, + "qcom,loop-auto-gm-thresh", + &wled->loop_auto_gm_thresh); + if (rc && rc != -EINVAL) { + dev_err(&pdev->dev, + "Unable to read loop-auto-gm-thresh\n"); + return rc; + } + } + + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { + + if (wled->pmic_rev_id->rev4 == PMI8998_V2P0_REV4) + wled->lcd_auto_pfm_en = false; + else + wled->lcd_auto_pfm_en = true; + + wled->lcd_auto_pfm_thresh = QPNP_WLED_LCD_AUTO_PFM_DFLT_THRESH; + rc = of_property_read_u8(pdev->dev.of_node, + "qcom,lcd-auto-pfm-thresh", + &wled->lcd_auto_pfm_thresh); + if (rc && rc != -EINVAL) { + dev_err(&pdev->dev, + "Unable to read lcd-auto-pfm-thresh\n"); + return rc; + } + + if (wled->lcd_auto_pfm_thresh > + QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX) + wled->lcd_auto_pfm_thresh = + QPNP_WLED_LCD_AUTO_PFM_THRESH_MAX; + } + wled->sc_deb_cycles = QPNP_WLED_SC_DEB_CYCLES_DFLT; rc = of_property_read_u32(pdev->dev.of_node, "qcom,sc-deb-cycles", &temp_val); @@ -1714,11 +1860,15 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } - wled->vref_mv = QPNP_WLED_DFLT_VREF_MV; + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || + wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + wled->vref_uv = vref_setting_pmi8998.default_uv; + else + wled->vref_uv = vref_setting_pmi8994.default_uv; rc = of_property_read_u32(pdev->dev.of_node, - "qcom,vref-mv", &temp_val); + "qcom,vref-uv", &temp_val); if (!rc) { - wled->vref_mv = temp_val; + wled->vref_uv = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read vref\n"); return rc; @@ -1734,7 +1884,7 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } - if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) wled->ovp_mv = 29600; else @@ -1748,12 +1898,12 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } - if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || + if (wled->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { if (wled->disp_type_amoled) - wled->ilim_ma = PMICOBALT_AMOLED_DFLT_ILIM_MA; + wled->ilim_ma = PMI8998_AMOLED_DFLT_ILIM_MA; else - wled->ilim_ma = PMICOBALT_WLED_DFLT_ILIM_MA; + wled->ilim_ma = PMI8998_WLED_DFLT_ILIM_MA; } else { if (wled->disp_type_amoled) wled->ilim_ma = PMI8994_AMOLED_DFLT_ILIM_MA; diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c index feede3a14e07..d6b32036f31c 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/dma-buf.h> #include <asm/dma-iommu.h> +#include <asm/cacheflush.h> #include <linux/dma-direction.h> #include <linux/dma-attrs.h> #include <linux/of_platform.h> @@ -23,6 +24,8 @@ #include <linux/dma-mapping.h> #include <linux/msm_dma_iommu_mapping.h> #include <linux/workqueue.h> +#include <soc/qcom/scm.h> +#include <soc/qcom/secure_buffer.h> #include "cam_smmu_api.h" #define SCRATCH_ALLOC_START SZ_128K @@ -35,10 +38,15 @@ #define COOKIE_MASK ((1<<COOKIE_SIZE)-1) #define HANDLE_INIT (-1) #define CAM_SMMU_CB_MAX 2 +#define CAM_SMMU_SID_MAX 4 + #define GET_SMMU_HDL(x, y) (((x) << COOKIE_SIZE) | ((y) & COOKIE_MASK)) #define GET_SMMU_TABLE_IDX(x) (((x) >> COOKIE_SIZE) & COOKIE_MASK) +#define CAMERA_DEVICE_ID 0x16 +#define SECURE_SYSCALL_ID 0x18 + #ifdef CONFIG_CAM_SMMU_DBG #define CDBG(fmt, args...) pr_err(fmt, ##args) #else @@ -104,6 +112,8 @@ struct cam_context_bank_info { int, void*); void *token[CAM_SMMU_CB_MAX]; int cb_count; + int ref_cnt; + int sids[CAM_SMMU_SID_MAX]; }; struct cam_iommu_cb_set { @@ -136,6 +146,17 @@ struct cam_dma_buff_info { size_t phys_len; }; +struct cam_sec_buff_info { + struct ion_handle *i_hdl; + struct ion_client *i_client; + enum dma_data_direction dir; + int ref_count; + dma_addr_t paddr; + struct list_head list; + int ion_fd; + size_t len; +}; + static struct cam_iommu_cb_set iommu_cb_set; static enum dma_data_direction cam_smmu_translate_dir( @@ -151,6 +172,9 @@ static int cam_smmu_create_add_handle_in_table(char *name, static struct cam_dma_buff_info *cam_smmu_find_mapping_by_ion_index(int idx, int ion_fd); +static struct cam_sec_buff_info *cam_smmu_find_mapping_by_sec_buf_idx(int idx, + int ion_fd); + static int cam_smmu_init_scratch_map(struct scratch_mapping *scratch_map, dma_addr_t base, size_t size, int order); @@ -477,10 +501,14 @@ void cam_smmu_reset_iommu_table(enum cam_smmu_init_dir ops) iommu_cb_set.cb_info[i].state = CAM_SMMU_DETACH; iommu_cb_set.cb_info[i].dev = NULL; iommu_cb_set.cb_info[i].cb_count = 0; + iommu_cb_set.cb_info[i].ref_cnt = 0; for (j = 0; j < CAM_SMMU_CB_MAX; j++) { iommu_cb_set.cb_info[i].token[j] = NULL; iommu_cb_set.cb_info[i].handler[j] = NULL; } + for (j = 0; j < CAM_SMMU_SID_MAX; j++) + iommu_cb_set.cb_info[i].sids[j] = -1; + if (ops == CAM_SMMU_TABLE_INIT) mutex_init(&iommu_cb_set.cb_info[i].lock); else @@ -549,6 +577,8 @@ static int cam_smmu_create_add_handle_in_table(char *name, pr_err("Error: %s already got handle 0x%x\n", name, iommu_cb_set.cb_info[i].handle); + *hdl = iommu_cb_set.cb_info[i].handle; + iommu_cb_set.cb_info[i].ref_cnt++; mutex_unlock(&iommu_cb_set.cb_info[i].lock); return -EINVAL; } @@ -561,6 +591,7 @@ static int cam_smmu_create_add_handle_in_table(char *name, /* put handle in the table */ iommu_cb_set.cb_info[i].handle = handle; iommu_cb_set.cb_info[i].cb_count = 0; + iommu_cb_set.cb_info[i].ref_cnt++; *hdl = handle; CDBG("%s creates handle 0x%x\n", name, handle); mutex_unlock(&iommu_cb_set.cb_info[i].lock); @@ -698,6 +729,23 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_ion_index(int idx, return NULL; } +static struct cam_sec_buff_info *cam_smmu_find_mapping_by_sec_buf_idx(int idx, + int ion_fd) +{ + struct cam_sec_buff_info *mapping; + + list_for_each_entry(mapping, &iommu_cb_set.cb_info[idx].smmu_buf_list, + list) { + if (mapping->ion_fd == ion_fd) { + CDBG("[sec_cam] find ion_fd %d\n", ion_fd); + return mapping; + } + } + pr_err("Error: Cannot find fd %d by index %d\n", + ion_fd, idx); + return NULL; +} + static void cam_smmu_clean_buffer_list(int idx) { int ret; @@ -754,6 +802,148 @@ static int cam_smmu_attach(int idx) return ret; } +static int cam_smmu_send_syscall_cpp_intf(int vmid, int idx) +{ + int rc = 0; + struct scm_desc desc = {0}; + struct cam_context_bank_info *cb = &iommu_cb_set.cb_info[idx]; + uint32_t sid_info; + + + sid_info = cb->sids[0]; /* CPP SID */ + + desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL); + desc.args[0] = CAMERA_DEVICE_ID; + desc.args[1] = SCM_BUFFER_PHYS(&sid_info); + desc.args[2] = sizeof(uint32_t); + desc.args[3] = vmid; + /* + * Syscall to hypervisor to switch CPP SID's + * between secure and non-secure contexts + */ + dmac_flush_range(&sid_info, &sid_info + 1); + if (scm_call2(SCM_SIP_FNID(SCM_SVC_MP, SECURE_SYSCALL_ID), + &desc)){ + pr_err("call to hypervisor failed\n"); + return -EINVAL; + } + return rc; +} + +static int cam_smmu_send_syscall_pix_intf(int vmid, int idx) +{ + int rc = 0; + struct scm_desc desc = {0}; + uint32_t *sid_info = NULL; + struct cam_context_bank_info *cb = &iommu_cb_set.cb_info[idx]; + + sid_info = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL); + if (!sid_info) + return -ENOMEM; + + sid_info[0] = cb->sids[0]; /* VFE 0 Image SID */ + sid_info[1] = cb->sids[2]; /* VFE 1 Image SID */ + + desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL); + desc.args[0] = CAMERA_DEVICE_ID; + desc.args[1] = SCM_BUFFER_PHYS(sid_info); + desc.args[2] = sizeof(uint32_t) * 2; + desc.args[3] = vmid; + /* + * Syscall to hypervisor to switch VFE SID's + * between secure and non-secure contexts + */ + dmac_flush_range(sid_info, sid_info + 2); + if (scm_call2(SCM_SIP_FNID(SCM_SVC_MP, SECURE_SYSCALL_ID), + &desc)){ + pr_err("call to hypervisor failed\n"); + kfree(sid_info); + return -EINVAL; + } + + kfree(sid_info); + return rc; +} + +static int cam_smmu_detach_device(int idx) +{ + struct cam_context_bank_info *cb = &iommu_cb_set.cb_info[idx]; + + /* detach the mapping to device */ + arm_iommu_detach_device(cb->dev); + iommu_cb_set.cb_info[idx].state = CAM_SMMU_DETACH; + return 0; +} + +static int cam_smmu_attach_sec_cpp(int idx) +{ + /* + * When switching to secure, detach CPP NS, do scm call + * with CPP SID and no need of attach again, because + * all cpp sids are shared in SCM call. so no need of + * attach again. + */ + + if (cam_smmu_send_syscall_cpp_intf(VMID_CP_CAMERA, idx)) { + pr_err("error: syscall failed\n"); + return -EINVAL; + } + return 0; +} + +static int cam_smmu_detach_sec_cpp(int idx) +{ + /* + * When exiting secure, do scm call to attach + * with CPP SID in NS mode. + */ + if (cam_smmu_send_syscall_cpp_intf(VMID_HLOS, idx)) { + pr_err("error: syscall failed\n"); + return -EINVAL; + } + return 0; +} + +static int cam_smmu_attach_sec_vfe_ns_stats(int idx) +{ + /* + *When switching to secure, for secure pixel and non-secure stats + *localizing scm/attach of non-secure SID's in attach secure + */ + if (cam_smmu_send_syscall_pix_intf(VMID_CP_CAMERA, idx)) { + pr_err("error: syscall failed\n"); + return -EINVAL; + } + + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_ATTACH) { + if (cam_smmu_attach(idx)) { + pr_err("error: failed to attach\n"); + return -EINVAL; + } + } + return 0; +} + +static int cam_smmu_detach_sec_vfe_ns_stats(int idx) +{ + /* + *While exiting from secure mode for secure pixel and non-secure stats, + *localizing detach/scm of non-secure SID's to detach secure + */ + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_DETACH) { + if (cam_smmu_detach_device(idx) < 0) { + pr_err("Error: ARM IOMMU detach failed\n"); + return -ENODEV; + } + } + + if (cam_smmu_send_syscall_pix_intf(VMID_HLOS, idx)) { + pr_err("error: syscall failed\n"); + return -EINVAL; + } + return 0; +} + static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, size_t *len_ptr) @@ -805,7 +995,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, } else { rc = -EINVAL; pr_err("Error: table sgl is null\n"); - goto err_unmap_sg; + goto err_map_addr; } /* fill up mapping_info */ @@ -813,7 +1003,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, if (!mapping_info) { pr_err("Error: No enough space!\n"); rc = -ENOSPC; - goto err_unmap_sg; + goto err_map_addr; } mapping_info->ion_fd = ion_fd; mapping_info->buf = buf; @@ -831,7 +1021,7 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, if (!*paddr_ptr || !*len_ptr) { pr_err("Error: Space Allocation failed!\n"); rc = -ENOSPC; - goto err_unmap_sg; + goto err_mapping_info; } CDBG("ion_fd = %d, dev = %pK, paddr= %pK, len = %u\n", ion_fd, (void *)iommu_cb_set.cb_info[idx].dev, @@ -841,6 +1031,12 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd, list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); return 0; +err_mapping_info: + kzfree(mapping_info); +err_map_addr: + msm_dma_unmap_sg(iommu_cb_set.cb_info[idx].dev, + table->sgl, table->nents, + dma_dir, buf); err_unmap_sg: dma_buf_unmap_attachment(attach, table, dma_dir); err_detach: @@ -851,6 +1047,98 @@ err_out: return rc; } +static int cam_smmu_map_secure_buffer_and_add_to_list(int idx, + struct dma_buf *buf, + enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr, + size_t *len_ptr) +{ + int rc = -1; + struct cam_dma_buff_info *mapping_info; + struct dma_buf_attachment *attach = NULL; + struct sg_table *table = NULL; + + attach = dma_buf_attach(buf, iommu_cb_set.cb_info[idx].dev); + if (IS_ERR_OR_NULL(attach)) { + rc = PTR_ERR(attach); + pr_err("Error: dma buf attach failed\n"); + goto err_put; + } + + table = dma_buf_map_attachment(attach, dma_dir); + if (IS_ERR_OR_NULL(table)) { + rc = PTR_ERR(table); + pr_err("Error: dma buf map attachment failed\n"); + goto err_detach; + } + + rc = msm_dma_map_sg_lazy(iommu_cb_set.cb_info[idx].dev, table->sgl, + table->nents, dma_dir, buf); + if (!rc) { + pr_err("Error: msm_dma_map_sg_lazy failed\n"); + goto err_unmap_sg; + } + + if (table->sgl) { + CDBG("DMA buf: %p, device: %p, attach: %p, table: %p\n", + (void *)buf, + (void *)iommu_cb_set.cb_info[idx].dev, + (void *)attach, (void *)table); + CDBG("table sgl: %p, rc: %d, dma_address: 0x%x\n", + (void *)table->sgl, rc, + (unsigned int)table->sgl->dma_address); + } else { + rc = -EINVAL; + pr_err("Error: table sgl is null\n"); + goto err_map_addr; + } + + /* fill up mapping_info */ + mapping_info = kzalloc(sizeof(struct cam_dma_buff_info), GFP_KERNEL); + if (!mapping_info) { + rc = -ENOSPC; + goto err_map_addr; + } + mapping_info->ion_fd = 0; + mapping_info->buf = buf; + mapping_info->attach = attach; + mapping_info->table = table; + mapping_info->paddr = sg_dma_address(table->sgl); + mapping_info->len = (size_t)sg_dma_len(table->sgl); + mapping_info->dir = dma_dir; + mapping_info->ref_count = 1; + + /* return paddr and len to client */ + *paddr_ptr = sg_dma_address(table->sgl); + *len_ptr = (size_t)sg_dma_len(table->sgl); + + if (!*paddr_ptr || !*len_ptr) { + pr_err("Error: Invalid dma address/length\n"); + rc = -ENOSPC; + goto err_mapping_info; + } + CDBG("dev = %p, paddr= %p, len = %u\n", + (void *)iommu_cb_set.cb_info[idx].dev, + (void *)*paddr_ptr, (unsigned int)*len_ptr); + + /* add to the list */ + list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); + + return 0; + +err_mapping_info: + kzfree(mapping_info); +err_map_addr: + msm_dma_unmap_sg(iommu_cb_set.cb_info[idx].dev, + table->sgl, table->nents, + dma_dir, buf); +err_unmap_sg: + dma_buf_unmap_attachment(attach, table, dma_dir); +err_detach: + dma_buf_detach(buf, attach); +err_put: + return rc; +} + static int cam_smmu_unmap_buf_and_remove_from_list( struct cam_dma_buff_info *mapping_info, int idx) @@ -951,7 +1239,23 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param ops) break; } case CAM_SMMU_DETACH: { - ret = 0; + ret = cam_smmu_detach_device(idx); + break; + } + case CAM_SMMU_ATTACH_SEC_VFE_NS_STATS: { + ret = cam_smmu_attach_sec_vfe_ns_stats(idx); + break; + } + case CAM_SMMU_DETACH_SEC_VFE_NS_STATS: { + ret = cam_smmu_detach_sec_vfe_ns_stats(idx); + break; + } + case CAM_SMMU_ATTACH_SEC_CPP: { + ret = cam_smmu_attach_sec_cpp(idx); + break; + } + case CAM_SMMU_DETACH_SEC_CPP: { + ret = cam_smmu_detach_sec_cpp(idx); break; } case CAM_SMMU_VOTE: @@ -1126,7 +1430,7 @@ int cam_smmu_get_phy_addr_scratch(int handle, size_t virt_len, size_t phys_len) { - int idx, rc; + int idx, rc = 0; unsigned int iommu_dir; if (!paddr_ptr || !virt_len || !phys_len) { @@ -1250,12 +1554,384 @@ int cam_smmu_put_phy_addr_scratch(int handle, pr_err("Error: unmap or remove list fail\n"); goto handle_err; } +handle_err: + mutex_unlock(&iommu_cb_set.cb_info[idx].lock); + return rc; +} + +int cam_smmu_get_phy_addr_secure_scratch(int handle, + enum cam_smmu_map_dir dir, + struct dma_buf *scratch_buf, + dma_addr_t *paddr_ptr, + size_t *len_ptr) +{ + int idx, rc; + enum dma_data_direction dma_dir; + + if (!paddr_ptr || !len_ptr) { + pr_err("Error: Input pointer or lengths invalid\n"); + return -EINVAL; + } + + dma_dir = cam_smmu_translate_dir(dir); + if (dma_dir == DMA_NONE) { + pr_err("Error: translate direction failed. dir = %d\n", dir); + return -EINVAL; + } + + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + + mutex_lock(&iommu_cb_set.cb_info[idx].lock); + if (iommu_cb_set.cb_info[idx].handle != handle) { + pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", + iommu_cb_set.cb_info[idx].handle, handle); + rc = -EINVAL; + goto error; + } + + CDBG("%s: smmu handle = %x, idx = %d, dir = %d\n", + __func__, handle, idx, dir); + + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_ATTACH) { + pr_err("Error: Device %s should call SMMU attach before map buffer\n", + iommu_cb_set.cb_info[idx].name); + rc = -EINVAL; + goto error; + } + + rc = cam_smmu_map_secure_buffer_and_add_to_list(idx, + scratch_buf, + dma_dir, + paddr_ptr, + len_ptr); + if (rc < 0) { + pr_err("Error: mapping or add list fail\n"); + goto error; + } + + CDBG("Mapped scratch buffer physical address is %lx\n", + (unsigned long)*paddr_ptr); +error: + mutex_unlock(&iommu_cb_set.cb_info[idx].lock); + return rc; +} + +int cam_smmu_put_phy_addr_secure_scratch(int handle, + dma_addr_t paddr) +{ + int idx; + int rc = -1; + struct cam_dma_buff_info *mapping_info; + + /* find index in the iommu_cb_set.cb_info */ + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + + mutex_lock(&iommu_cb_set.cb_info[idx].lock); + if (iommu_cb_set.cb_info[idx].handle != handle) { + pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", + iommu_cb_set.cb_info[idx].handle, handle); + rc = -EINVAL; + goto handle_err; + } + + /* Based on virtual address and index, we can find mapping info + * of the scratch buffer + */ + mapping_info = cam_smmu_find_mapping_by_virt_address(idx, paddr); + if (!mapping_info) { + pr_err("Error: Invalid params\n"); + rc = -EINVAL; + goto handle_err; + } + + /* unmapping one buffer from device */ + rc = cam_smmu_unmap_buf_and_remove_from_list(mapping_info, idx); + if (rc < 0) { + pr_err("Error: unmap or remove list fail\n"); + goto handle_err; + } + CDBG("Unmap secure scratch buffer %lx success fully\n", + (unsigned long)paddr); handle_err: mutex_unlock(&iommu_cb_set.cb_info[idx].lock); return rc; } +int cam_smmu_alloc_get_stage2_scratch_mem(int handle, + enum cam_smmu_map_dir dir, struct ion_client *client, + struct ion_handle **sc_handle, ion_phys_addr_t *addr, + size_t *len_ptr) +{ + int idx, rc = 0; + enum dma_data_direction dma_dir; + + dma_dir = cam_smmu_translate_dir(dir); + if (dma_dir == DMA_NONE) { + pr_err("Error: translate direction failed. dir = %d\n", dir); + return -EINVAL; + } + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + if (iommu_cb_set.cb_info[idx].handle != handle) { + pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", + iommu_cb_set.cb_info[idx].handle, handle); + return -EINVAL; + } + + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_ATTACH) { + pr_err("Error: Device %s should call SMMU attach before map buffer\n", + iommu_cb_set.cb_info[idx].name); + return -EINVAL; + } + *sc_handle = ion_alloc(client, SZ_2M, SZ_2M, + ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID), + ION_FLAG_SECURE | ION_FLAG_CP_CAMERA); + if (IS_ERR_OR_NULL((void *) (*sc_handle))) { + rc = -ENOMEM; + goto err_ion_handle; + } + + /* return addr and len to client */ + rc = ion_phys(client, *sc_handle, addr, len_ptr); + if (rc) { + pr_err("%s: ION Get Physical failed, rc = %d\n", + __func__, rc); + rc = -EINVAL; + goto err_ion_phys; + } + + CDBG("dev = %pK, paddr= %pK, len = %u\n", + (void *)iommu_cb_set.cb_info[idx].dev, + (void *)*addr, (unsigned int)*len_ptr); + return rc; + +err_ion_phys: + ion_free(client, *sc_handle); + +err_ion_handle: + *sc_handle = NULL; + return rc; +} + +int cam_smmu_free_stage2_scratch_mem(int handle, + struct ion_client *client, struct ion_handle *sc_handle) +{ + int idx = 0; + /* find index in the iommu_cb_set.cb_info */ + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + ion_free(client, sc_handle); + return 0; +} + +static int cam_smmu_secure_unmap_buf_and_remove_from_list( + struct cam_sec_buff_info *mapping_info, + int idx) +{ + if (!mapping_info) { + pr_err("Error: List doesn't exist\n"); + return -EINVAL; + } + ion_free(mapping_info->i_client, mapping_info->i_hdl); + list_del_init(&mapping_info->list); + + /* free one buffer */ + kfree(mapping_info); + return 0; +} + +int cam_smmu_put_stage2_phy_addr(int handle, int ion_fd) +{ + int idx, rc; + struct cam_sec_buff_info *mapping_info; + + /* find index in the iommu_cb_set.cb_info */ + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + + mutex_lock(&iommu_cb_set.cb_info[idx].lock); + if (iommu_cb_set.cb_info[idx].handle != handle) { + pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", + iommu_cb_set.cb_info[idx].handle, handle); + rc = -EINVAL; + goto put_addr_end; + } + + /* based on ion fd and index, we can find mapping info of buffer */ + mapping_info = cam_smmu_find_mapping_by_sec_buf_idx(idx, ion_fd); + if (!mapping_info) { + pr_err("Error: Invalid params! idx = %d, fd = %d\n", + idx, ion_fd); + rc = -EINVAL; + goto put_addr_end; + } + + mapping_info->ref_count--; + if (mapping_info->ref_count > 0) { + CDBG("There are still %u buffer(s) with same fd %d", + mapping_info->ref_count, mapping_info->ion_fd); + rc = 0; + goto put_addr_end; + } + + /* unmapping one buffer from device */ + rc = cam_smmu_secure_unmap_buf_and_remove_from_list(mapping_info, idx); + if (rc < 0) { + pr_err("Error: unmap or remove list fail\n"); + goto put_addr_end; + } + +put_addr_end: + mutex_unlock(&iommu_cb_set.cb_info[idx].lock); + return rc; +} +EXPORT_SYMBOL(cam_smmu_put_stage2_phy_addr); + +static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd, + enum dma_data_direction dma_dir, struct ion_client *client, + dma_addr_t *paddr_ptr, + size_t *len_ptr) +{ + int rc = 0; + struct ion_handle *i_handle = NULL; + struct cam_sec_buff_info *mapping_info; + + + /* clean the content from clients */ + *paddr_ptr = (dma_addr_t)NULL; + *len_ptr = (size_t)0; + + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_ATTACH) { + pr_err("Error: Device %s should call SMMU attach before map buffer\n", + iommu_cb_set.cb_info[idx].name); + return -EINVAL; + } + + i_handle = ion_import_dma_buf(client, ion_fd); + if (IS_ERR_OR_NULL((void *)(i_handle))) { + pr_err("%s: ion import dma buffer failed\n", __func__); + return -EINVAL; + } + + /* return addr and len to client */ + rc = ion_phys(client, i_handle, paddr_ptr, len_ptr); + if (rc) { + pr_err("%s: ION Get Physical failed, rc = %d\n", + __func__, rc); + return -EINVAL; + } + + /* fill up mapping_info */ + mapping_info = kzalloc(sizeof(struct cam_sec_buff_info), GFP_KERNEL); + if (!mapping_info) + return -ENOSPC; + + mapping_info->ion_fd = ion_fd; + mapping_info->paddr = *paddr_ptr; + mapping_info->len = *len_ptr; + mapping_info->dir = dma_dir; + mapping_info->ref_count = 1; + mapping_info->i_hdl = i_handle; + mapping_info->i_client = client; + + CDBG("ion_fd = %d, dev = %pK, paddr= %pK, len = %u\n", ion_fd, + (void *)iommu_cb_set.cb_info[idx].dev, + (void *)*paddr_ptr, (unsigned int)*len_ptr); + + /* add to the list */ + list_add(&mapping_info->list, &iommu_cb_set.cb_info[idx].smmu_buf_list); + + return rc; +} + +int cam_smmu_get_stage2_phy_addr(int handle, + int ion_fd, enum cam_smmu_map_dir dir, + struct ion_client *client, ion_phys_addr_t *paddr_ptr, + size_t *len_ptr) +{ + int idx, rc; + enum dma_data_direction dma_dir; + enum cam_smmu_buf_state buf_state; + + if (!paddr_ptr || !len_ptr) { + pr_err("Error: Input pointers are invalid\n"); + return -EINVAL; + } + /* clean the content from clients */ + *paddr_ptr = (dma_addr_t)NULL; + *len_ptr = (size_t)0; + + dma_dir = cam_smmu_translate_dir(dir); + if (dma_dir == DMA_NONE) { + pr_err("Error: translate direction failed. dir = %d\n", dir); + return -EINVAL; + } + + idx = GET_SMMU_TABLE_IDX(handle); + if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) { + pr_err("Error: handle or index invalid. idx = %d hdl = %x\n", + idx, handle); + return -EINVAL; + } + + mutex_lock(&iommu_cb_set.cb_info[idx].lock); + if (iommu_cb_set.cb_info[idx].handle != handle) { + pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", + iommu_cb_set.cb_info[idx].handle, handle); + rc = -EINVAL; + goto get_addr_end; + } + + if (iommu_cb_set.cb_info[idx].state != CAM_SMMU_ATTACH) { + pr_err("Error: Device %s should call SMMU attach before map buffer\n", + iommu_cb_set.cb_info[idx].name); + rc = -EINVAL; + goto get_addr_end; + } + + buf_state = cam_smmu_check_fd_in_list(idx, ion_fd, paddr_ptr, len_ptr); + if (buf_state == CAM_SMMU_BUFF_EXIST) { + CDBG("ion_fd:%d already in the list, give same addr back", + ion_fd); + rc = 0; + goto get_addr_end; + } + rc = cam_smmu_map_stage2_buffer_and_add_to_list(idx, ion_fd, dma_dir, + client, paddr_ptr, len_ptr); + if (rc < 0) { + pr_err("Error: mapping or add list fail\n"); + goto get_addr_end; + } + +get_addr_end: + mutex_unlock(&iommu_cb_set.cb_info[idx].lock); + return rc; +} + + int cam_smmu_get_phy_addr(int handle, int ion_fd, enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr, size_t *len_ptr) @@ -1383,6 +2059,11 @@ int cam_smmu_destroy_handle(int handle) } mutex_lock(&iommu_cb_set.cb_info[idx].lock); + if (--iommu_cb_set.cb_info[idx].ref_cnt != 0) { + mutex_unlock(&iommu_cb_set.cb_info[idx].lock); + return 0; + } + if (iommu_cb_set.cb_info[idx].handle != handle) { pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n", iommu_cb_set.cb_info[idx].handle, handle); @@ -1469,6 +2150,28 @@ end: return rc; } +static int cam_smmu_populate_sids(struct device *dev, + struct cam_context_bank_info *cb) +{ + int i, j, rc = 0; + unsigned int cnt = 0; + const void *property; + + /* set the name of the context bank */ + property = of_get_property(dev->of_node, "iommus", &cnt); + cnt /= 4; + for (i = 0, j = 0; i < cnt; i = i + 2, j++) { + rc = of_property_read_u32_index(dev->of_node, + "iommus", i + 1, &cb->sids[j]); + if (rc < 0) + pr_err("misconfiguration, can't fetch SID\n"); + + pr_err("__debug cnt = %d, cb->name: :%s sid [%d] = %d\n,", + cnt, cb->name, j, cb->sids[j]); + } + return rc; +} + static int cam_alloc_smmu_context_banks(struct device *dev) { struct device_node *domains_child_node = NULL; @@ -1541,6 +2244,11 @@ static int cam_populate_smmu_context_banks(struct device *dev, goto cb_init_fail; } + /* populate SID's for each cb */ + rc = cam_smmu_populate_sids(dev, cb); + if (rc < 0) + pr_err("Error: failed to populate sids : %s\n", cb->name); + /* Check if context bank supports scratch buffers */ if (of_property_read_bool(dev->of_node, "qcom,scratch-buf-support")) cb->scratch_buf_support = 1; @@ -1549,9 +2257,9 @@ static int cam_populate_smmu_context_banks(struct device *dev, /* set the secure/non secure domain type */ if (of_property_read_bool(dev->of_node, "qcom,secure-context")) - cb->is_secure = CAM_SECURE; + cb->is_secure = true; else - cb->is_secure = CAM_NON_SECURE; + cb->is_secure = false; CDBG("cb->name :%s, cb->is_secure :%d, cb->scratch_support :%d\n", cb->name, cb->is_secure, cb->scratch_buf_support); diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h index 59d085989a9c..3b8481f8bf7e 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h @@ -23,6 +23,8 @@ #include <linux/random.h> #include <linux/spinlock_types.h> #include <linux/mutex.h> +#include <linux/msm_ion.h> + /* * Enum for possible CAM SMMU operations @@ -31,6 +33,10 @@ enum cam_smmu_ops_param { CAM_SMMU_ATTACH, CAM_SMMU_DETACH, + CAM_SMMU_ATTACH_SEC_VFE_NS_STATS, + CAM_SMMU_DETACH_SEC_VFE_NS_STATS, + CAM_SMMU_ATTACH_SEC_CPP, + CAM_SMMU_DETACH_SEC_CPP, CAM_SMMU_VOTE, CAM_SMMU_DEVOTE, CAM_SMMU_OPS_INVALID @@ -87,6 +93,59 @@ int cam_smmu_get_phy_addr(int handle, int cam_smmu_put_phy_addr(int handle, int ion_fd); /** + * @param handle: Client has to pass back the smmu handle provided. + * @param ion_fd: ION handle identifying the memory buffer. + * @dir : Mapping direction: which will traslate toDMA_BIDIRECTIONAL, + * DMA_TO_DEVICE or DMA_FROM_DEVICE + * @client : Client has to pass the ion_client pointer created by the client. + * @phys_addr : Pointer to physical address where mapped address will be + * returned. + * @len : Length of buffer mapped returned by CAM SMMU driver. + * @return Status of operation. Negative in case of error. Zero otherwise. + */ +int cam_smmu_get_stage2_phy_addr(int handle, + int ion_fd, enum cam_smmu_map_dir dir, + struct ion_client *client, ion_phys_addr_t *addr, + size_t *len_ptr); + +/** + * @param handle: Handle to identify the CAMSMMU client (VFE, CPP, FD etc.) + * @param ion_fd: ION handle identifying the memory buffer. + * + * @return Status of operation. Negative in case of error. Zero otherwise. + */ +int cam_smmu_put_stage2_phy_addr(int handle, int ion_fd); + +/** + * @param handle: Client has to pass back the smmu handle provided. + * @dir : Mapping direction: which will traslate toDMA_BIDIRECTIONAL, + * DMA_TO_DEVICE or DMA_FROM_DEVICE, client has to pass. + * @client : Client has to pass the ion_client pointer created by the client. + * @ion_handle : handle to the buffer returned by CAM SMMU driver. + * @phys_addr : Pointer to physical address where mapped address will be + * returned. + * @len : Length of buffer mapped returned by CAM SMMU driver. + * @return Status of operation. Negative in case of error. Zero otherwise. + */ +int cam_smmu_alloc_get_stage2_scratch_mem(int handle, + enum cam_smmu_map_dir dir, struct ion_client *client, + struct ion_handle **sc_handle, ion_phys_addr_t *addr, + size_t *len_ptr); + + +/** + * @param handle: Client has to pass back the smmu handle provided. + * @client : Client has to pass the ion_client pointer provided by SMMU + * driver. + * @ion_handle : Client has to pass the ion_handle provided by SMMU + * driver. + * @return Status of operation. Negative in case of error. Zero otherwise. + */ + +int cam_smmu_free_stage2_scratch_mem(int handle, + struct ion_client *client, struct ion_handle *sc_handle); + +/** * @brief : Allocates a scratch buffer * * This function allocates a scratch virtual buffer of length virt_len in the 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/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c index 2c313016bc90..8213f736205a 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c @@ -66,39 +66,72 @@ int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name) return -EINVAL; } -static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info, - uint32_t min_clk_rate) +static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev) { - uint32_t i; + uint32_t i, count, min_clk_rate; uint32_t idx = 0; - signed long freq_tbl_entry = 0; + struct device_node *of_node; + uint32_t *rates; + int32_t rc = 0; + struct cpp_hw_info *hw_info; - if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) || - (clk->ops->list_rate == NULL)) { + if (cpp_dev == NULL) { pr_err("Bad parameter\n"); - return -EINVAL; + rc = -EINVAL; + goto err; } - for (i = 0; i < MAX_FREQ_TBL; i++) { - freq_tbl_entry = clk->ops->list_rate(clk, i); - pr_debug("entry=%ld\n", freq_tbl_entry); - if (freq_tbl_entry >= 0) { - if (freq_tbl_entry >= min_clk_rate) { - hw_info->freq_tbl[idx++] = freq_tbl_entry; - pr_debug("tbl[%d]=%ld\n", idx-1, - freq_tbl_entry); + of_node = cpp_dev->pdev->dev.of_node; + min_clk_rate = cpp_dev->min_clk_rate; + hw_info = &cpp_dev->hw_info; + + if ((hw_info == NULL) || (of_node == NULL)) { + pr_err("Invalid hw_info %p or ofnode %p\n", hw_info, of_node); + rc = -EINVAL; + goto err; + + } + count = of_property_count_u32_elems(of_node, "qcom,src-clock-rates"); + if ((count == 0) || (count > MAX_FREQ_TBL)) { + pr_err("Clock count is invalid\n"); + rc = -EINVAL; + goto err; + } + + rates = devm_kcalloc(&cpp_dev->pdev->dev, count, sizeof(uint32_t), + GFP_KERNEL); + if (!rates) { + rc = -ENOMEM; + goto err; + } + + rc = of_property_read_u32_array(of_node, "qcom,src-clock-rates", + rates, count); + if (rc) { + rc = -EINVAL; + goto mem_free; + } + + for (i = 0; i < count; i++) { + pr_debug("entry=%d\n", rates[i]); + if (rates[i] >= 0) { + if (rates[i] >= min_clk_rate) { + hw_info->freq_tbl[idx++] = rates[i]; + pr_debug("tbl[%d]=%d\n", idx-1, rates[i]); } } else { - pr_debug("freq table returned invalid entry/end %ld\n", - freq_tbl_entry); + pr_debug("rate is invalid entry/end %d\n", rates[i]); break; } } - pr_debug("%s: idx %d", __func__, idx); + pr_debug("%s: idx %d\n", __func__, idx); hw_info->freq_tbl_count = idx; - return 0; +mem_free: + devm_kfree(&cpp_dev->pdev->dev, rates); +err: + return rc; } int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev) @@ -147,8 +180,7 @@ int msm_update_freq_tbl(struct cpp_device *cpp_dev) rc = msm_cpp_core_clk_idx; return rc; } - rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx], - &cpp_dev->hw_info, cpp_dev->min_clk_rate); + rc = cpp_get_clk_freq_tbl_dt(cpp_dev); if (rc < 0) { pr_err("%s: fail to get frequency table\n", __func__); return rc; 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/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c index 925b8497273a..eaf35733b38a 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c @@ -1502,7 +1502,8 @@ static void sde_hw_rotator_free_rotctx(struct sde_hw_rotator *rot, ctx->q_id, ctx->timestamp, atomic_read(&ctx->hwres->num_active)); - rot->rotCtx[ctx->q_id][sde_hw_rotator_get_regdma_ctxidx(ctx)] = NULL; + /* Clear rotator context from lookup purpose */ + sde_hw_rotator_clr_ctx(ctx); devm_kfree(&rot->pdev->dev, ctx); } @@ -2012,15 +2013,18 @@ static int sde_hw_rotator_validate_entry(struct sde_rot_mgr *mgr, } } - fmt = sde_get_format_params(item->output.format); - /* Tiled format downscale support not applied to AYUV tiled */ - if (sde_mdp_is_tilea5x_format(fmt) && (entry->dnsc_factor_h > 4)) { - SDEROT_DBG("max downscale for tiled format is 4\n"); + fmt = sde_get_format_params(item->input.format); + /* + * Rotator downscale support max 4 times for UBWC format and + * max 2 times for TP10/TP10_UBWC format + */ + if (sde_mdp_is_ubwc_format(fmt) && (entry->dnsc_factor_h > 4)) { + SDEROT_DBG("max downscale for UBWC format is 4\n"); ret = -EINVAL; goto dnsc_err; } - if (sde_mdp_is_ubwc_format(fmt) && (entry->dnsc_factor_h > 2)) { - SDEROT_DBG("downscale with ubwc cannot be more than 2\n"); + if (sde_mdp_is_tp10_format(fmt) && (entry->dnsc_factor_h > 2)) { + SDEROT_DBG("downscale with TP10 cannot be more than 2\n"); ret = -EINVAL; } goto dnsc_err; @@ -2075,6 +2079,7 @@ static ssize_t sde_hw_rotator_show_caps(struct sde_rot_mgr *mgr, struct device_attribute *attr, char *buf, ssize_t len) { struct sde_hw_rotator *hw_data; + struct sde_rot_data_type *mdata = sde_rot_get_mdata(); int cnt = 0; if (!mgr || !buf) @@ -2086,6 +2091,10 @@ static ssize_t sde_hw_rotator_show_caps(struct sde_rot_mgr *mgr, (cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__)) /* insert capabilities here */ + if (test_bit(SDE_CAPS_R3_1P5_DOWNSCALE, mdata->sde_caps_map)) + SPRINT("min_downscale=1.5\n"); + else + SPRINT("min_downscale=2.0\n"); #undef SPRINT return cnt; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h index 91ac3d0371fa..7aecc3cee210 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h @@ -345,10 +345,32 @@ static inline void sde_hw_rotator_put_ctx(struct sde_hw_rotator_context *ctx) { struct sde_hw_rotator *rot = ctx->rot; u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx); + unsigned long flags; + spin_lock_irqsave(&rot->rotisr_lock, flags); rot->rotCtx[ctx->q_id][idx] = ctx; + spin_unlock_irqrestore(&rot->rotisr_lock, flags); + SDEROT_DBG("rotCtx[%d][%d] <== ctx:%p | session-id:%d\n", ctx->q_id, idx, ctx, ctx->session_id); } +/** + * sde_hw_rotator_clr_ctx(): Clearing rotator context according to its + * timestamp. + */ +static inline void sde_hw_rotator_clr_ctx(struct sde_hw_rotator_context *ctx) +{ + struct sde_hw_rotator *rot = ctx->rot; + u32 idx = sde_hw_rotator_get_regdma_ctxidx(ctx); + unsigned long flags; + + spin_lock_irqsave(&rot->rotisr_lock, flags); + rot->rotCtx[ctx->q_id][idx] = NULL; + spin_unlock_irqrestore(&rot->rotisr_lock, flags); + + SDEROT_DBG("rotCtx[%d][%d] <== null | session-id:%d\n", + ctx->q_id, idx, ctx->session_id); +} + #endif /*_SDE_ROTATOR_R3_INTERNAL_H */ diff --git a/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c b/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c index dded8a25961a..98d9eb733371 100644 --- a/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c +++ b/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c @@ -24,6 +24,7 @@ enum bus_profile { VIDC_BUS_PROFILE_NORMAL = BIT(0), VIDC_BUS_PROFILE_LOW = BIT(1), VIDC_BUS_PROFILE_UBWC = BIT(2), + VIDC_BUS_PROFILE_UBWC_10_BIT = BIT(3), }; struct bus_profile_entry { @@ -53,7 +54,7 @@ static int __get_bus_freq(struct msm_vidc_bus_table_gov *gov, load = NUM_MBS_PER_SEC(data->width, data->height, data->fps); sess_type = VIDC_VOTE_DATA_SESSION_VAL(data->codec, data->domain); - /* check if ubwc bus profile is present */ + /* check if appropriate bus profile is present */ for (i = 0; i < gov->count; i++) { entry = &gov->bus_prof_entries[i]; if (!entry->bus_table || !entry->bus_table_size) @@ -119,18 +120,23 @@ static int msm_vidc_table_get_target_freq(struct devfreq *dev, } profile = VIDC_BUS_PROFILE_NORMAL; - if (data->color_formats[0] == HAL_COLOR_FORMAT_NV12_TP10_UBWC || - data->color_formats[0] == HAL_COLOR_FORMAT_NV12_UBWC) + if (data->color_formats[0] == HAL_COLOR_FORMAT_NV12_UBWC) profile = VIDC_BUS_PROFILE_UBWC; + else if (data->color_formats[0] == + HAL_COLOR_FORMAT_NV12_TP10_UBWC) + profile = VIDC_BUS_PROFILE_UBWC_10_BIT; freq = __get_bus_freq(gov, data, profile); /* * chose frequency from normal profile * if specific profile frequency was not found. */ - if (!freq) + if (!freq) { + dprintk(VIDC_WARN, + "appropriate bus table not found, voting with Normal Profile\n"); freq = __get_bus_freq(gov, data, VIDC_BUS_PROFILE_NORMAL); + } *frequency += (unsigned long)freq; @@ -260,6 +266,8 @@ static int msm_vidc_load_bus_table(struct platform_device *pdev, entry->profile = VIDC_BUS_PROFILE_LOW; else if (of_find_property(child_node, "qcom,ubwc-mode", NULL)) entry->profile = VIDC_BUS_PROFILE_UBWC; + else if (of_find_property(child_node, "qcom,ubwc-10bit", NULL)) + entry->profile = VIDC_BUS_PROFILE_UBWC_10_BIT; else entry->profile = VIDC_BUS_PROFILE_NORMAL; diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index c4d06b658b30..7bc1fe1af26d 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -1320,11 +1320,6 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) msm_comm_ctrl_deinit(inst); - mutex_destroy(&inst->sync_lock); - mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); - mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); - mutex_destroy(&inst->lock); - DEINIT_MSM_VIDC_LIST(&inst->pendingq); DEINIT_MSM_VIDC_LIST(&inst->scratchbufs); DEINIT_MSM_VIDC_LIST(&inst->persistbufs); @@ -1338,6 +1333,11 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) for (i = 0; i < MAX_PORT_NUM; i++) vb2_queue_release(&inst->bufq[i].vb2_bufq); + mutex_destroy(&inst->sync_lock); + mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); + mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); + mutex_destroy(&inst->lock); + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst); kfree(inst); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index fa2ad1754e77..73c52841fd34 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -298,6 +298,11 @@ static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst) rc = msm_comm_g_ctrl(inst, &ctrl); if (!rc && ctrl.value) { fps = (ctrl.value >> 16) ? ctrl.value >> 16 : 1; + /* + * Check if operating rate is less than fps. + * If Yes, then use fps to scale clocks + */ + fps = fps > inst->prop.fps ? fps : inst->prop.fps; return max(output_port_mbs, capture_port_mbs) * fps; } else return max(output_port_mbs, capture_port_mbs) * inst->prop.fps; @@ -1666,7 +1671,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) */ mutex_lock(&core->lock); - inst = list_first_entry(&core->instances, + inst = list_first_entry_or_null(&core->instances, struct msm_vidc_inst, list); mutex_unlock(&core->lock); @@ -5359,10 +5364,10 @@ static void msm_comm_print_debug_info(struct msm_vidc_inst *inst) dprintk(VIDC_ERR, "Venus core frequency = %lu", msm_comm_get_clock_rate(core)); + mutex_lock(&core->lock); dprintk(VIDC_ERR, "Printing instance info that caused Error\n"); msm_comm_print_inst_info(inst); dprintk(VIDC_ERR, "Printing remaining instances info\n"); - mutex_lock(&core->lock); list_for_each_entry(temp, &core->instances, list) { /* inst already printed above. Hence don't repeat.*/ if (temp == inst) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 787ee43ccbd2..0055e22b40b4 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -75,7 +75,7 @@ const struct msm_vidc_gov_data DEFAULT_BUS_VOTE = { .imem_size = 0, }; -const int max_packets = 250; +const int max_packets = 1000; static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); @@ -3576,6 +3576,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) struct venus_hfi_device *device = list_first_entry( &hal_ctxt.dev_head, struct venus_hfi_device, list); int num_responses = 0, i = 0; + u32 intr_status; mutex_lock(&device->lock); @@ -3601,10 +3602,9 @@ static void venus_hfi_core_work_handler(struct work_struct *work) num_responses = __response_handler(device); err_no_work: - /* We need re-enable the irq which was disabled in ISR handler */ - if (!(device->intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) - enable_irq(device->hal_data->irq); + /* Keep the interrupt status before releasing device lock */ + intr_status = device->intr_status; mutex_unlock(&device->lock); /* @@ -3619,6 +3619,10 @@ err_no_work: device->callback(r->response_type, &r->response); } + /* We need re-enable the irq which was disabled in ISR handler */ + if (!(intr_status & VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + enable_irq(device->hal_data->irq); + /* * XXX: Don't add any code beyond here. Reacquiring locks after release * it above doesn't guarantee the atomicity that we're aiming for. @@ -4548,7 +4552,7 @@ static struct venus_hfi_device *__add_device(u32 device_id, } hdevice->response_pkt = kmalloc_array(max_packets, - sizeof(*hdevice->response_pkt), GFP_TEMPORARY); + sizeof(*hdevice->response_pkt), GFP_KERNEL); if (!hdevice->response_pkt) { dprintk(VIDC_ERR, "failed to allocate response_pkt\n"); goto err_cleanup; diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 4e941f00b600..082ff5608455 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1403,11 +1403,12 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) * in order to avoid troubles during device release. */ kfree(priv->ctrl.fname); + priv->ctrl.fname = NULL; memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); if (p->fname) { priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); if (priv->ctrl.fname == NULL) - rc = -ENOMEM; + return -ENOMEM; } /* diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index 7dc7271b05c1..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; } @@ -8125,11 +8234,12 @@ static int qseecom_check_whitelist_feature(void) static int qseecom_probe(struct platform_device *pdev) { int rc; - int ret = 0; + int i; uint32_t feature = 10; struct device *class_dev; struct msm_bus_scale_pdata *qseecom_platform_support = NULL; struct qseecom_command_scm_resp resp; + struct qseecom_ce_info_use *pce_info_use = NULL; qseecom.qsee_bw_count = 0; qseecom.qsee_perf_client = 0; @@ -8171,7 +8281,7 @@ static int qseecom_probe(struct platform_device *pdev) class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL, QSEECOM_DEV); - if (!class_dev) { + if (IS_ERR(class_dev)) { pr_err("class_device_create failed %d\n", rc); rc = -ENOMEM; goto exit_destroy_class; @@ -8210,7 +8320,7 @@ static int qseecom_probe(struct platform_device *pdev) qseecom.pdev = class_dev; /* Create ION msm client */ qseecom.ion_clnt = msm_ion_client_create("qseecom-kernel"); - if (qseecom.ion_clnt == NULL) { + if (IS_ERR_OR_NULL(qseecom.ion_clnt)) { pr_err("Ion client cannot be created\n"); rc = -ENOMEM; goto exit_del_cdev; @@ -8272,14 +8382,14 @@ static int qseecom_probe(struct platform_device *pdev) pr_debug("CE operating frequency is not defined, setting to default 100MHZ\n"); qseecom.ce_opp_freq_hz = QSEE_CE_CLK_100MHZ; } - ret = __qseecom_init_clk(CLK_QSEE); - if (ret) + rc = __qseecom_init_clk(CLK_QSEE); + if (rc) goto exit_destroy_ion_client; if ((qseecom.qsee.instance != qseecom.ce_drv.instance) && (qseecom.support_pfe || qseecom.support_fde)) { - ret = __qseecom_init_clk(CLK_CE_DRV); - if (ret) { + rc = __qseecom_init_clk(CLK_CE_DRV); + if (rc) { __qseecom_deinit_clk(CLK_QSEE); goto exit_destroy_ion_client; } @@ -8333,9 +8443,14 @@ static int qseecom_probe(struct platform_device *pdev) } else { pr_err("Fail to get secure app region info\n"); rc = -EINVAL; - goto exit_destroy_ion_client; + goto exit_deinit_clock; + } + rc = __qseecom_enable_clk(CLK_QSEE); + if (rc) { + pr_err("CLK_QSEE enabling failed (%d)\n", rc); + rc = -EIO; + goto exit_deinit_clock; } - __qseecom_enable_clk(CLK_QSEE); rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len, &resp, sizeof(resp)); @@ -8344,7 +8459,7 @@ static int qseecom_probe(struct platform_device *pdev) pr_err("send secapp reg fail %d resp.res %d\n", rc, resp.result); rc = -EINVAL; - goto exit_destroy_ion_client; + goto exit_deinit_clock; } } /* @@ -8380,7 +8495,28 @@ static int qseecom_probe(struct platform_device *pdev) atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_READY); return 0; +exit_deinit_clock: + __qseecom_deinit_clk(CLK_QSEE); + if ((qseecom.qsee.instance != qseecom.ce_drv.instance) && + (qseecom.support_pfe || qseecom.support_fde)) + __qseecom_deinit_clk(CLK_CE_DRV); exit_destroy_ion_client: + if (qseecom.ce_info.fde) { + pce_info_use = qseecom.ce_info.fde; + for (i = 0; i < qseecom.ce_info.num_fde; i++) { + kzfree(pce_info_use->ce_pipe_entry); + pce_info_use++; + } + kfree(qseecom.ce_info.fde); + } + if (qseecom.ce_info.pfe) { + pce_info_use = qseecom.ce_info.pfe; + for (i = 0; i < qseecom.ce_info.num_pfe; i++) { + kzfree(pce_info_use->ce_pipe_entry); + pce_info_use++; + } + kfree(qseecom.ce_info.pfe); + } ion_client_destroy(qseecom.ion_clnt); exit_del_cdev: cdev_del(&qseecom.cdev); 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/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index 240bf2903308..9a6f1aed82e8 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -60,7 +60,7 @@ #define PCS_BASE 0x800 #define PCS_MISC_BASE 0x600 -#elif defined(CONFIG_ARCH_MSMCOBALT) +#elif defined(CONFIG_ARCH_MSM8998) #define PCIE_VENDOR_ID_RCP 0x17cb #define PCIE_DEVICE_ID_RCP 0x0105 diff --git a/drivers/phy/phy-qcom-ufs-qmp-v3.h b/drivers/phy/phy-qcom-ufs-qmp-v3.h index 8b1e03eab639..d5e49c281278 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-v3.h +++ b/drivers/phy/phy-qcom-ufs-qmp-v3.h @@ -225,22 +225,22 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_0_0[] = { UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE_INITVAL1, 0xFF), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_DEC_START_MODE0, 0x82), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE0, 0x06), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE0, 0x08), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE0, 0x36), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE0, 0x34), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3F), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE0, 0xDA), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE0, 0xCB), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE2_MODE0, 0x01), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP1_MODE0, 0xFF), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP2_MODE0, 0x0C), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_DEC_START_MODE1, 0x98), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE1, 0x06), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_CP_CTRL_MODE1, 0x08), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE1, 0x36), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_PLL_CCTRL_MODE1, 0x34), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x3F), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), - UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE1, 0xC1), + UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE1_MODE1, 0xB2), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_COM_LOCK_CMP2_MODE1, 0x0F), diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 4805c4feac74..6b83b50d382e 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -96,13 +96,13 @@ config PINCTRL_QCOM_SSBI_PMIC which are using SSBI for communication with SoC. Example PMIC's devices are pm8058 and pm8921. -config PINCTRL_MSMCOBALT - tristate "Qualcomm MSMCOBALT pin controller driver" +config PINCTRL_MSM8998 + tristate "Qualcomm MSM8998 pin controller driver" depends on GPIOLIB && OF select PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm TLMM block found in the Qualcomm MSMCOBALT platform. + Qualcomm TLMM block found in the Qualcomm MSM8998 platform. config PINCTRL_MSM8996 tristate "Qualcomm MSM8996 pin controller driver" diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index bddc21431eeb..7d9cc7a9eb43 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -13,6 +13,6 @@ obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-mpp.o obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o -obj-$(CONFIG_PINCTRL_MSMCOBALT) += pinctrl-msmcobalt.o +obj-$(CONFIG_PINCTRL_MSM8998) += pinctrl-msm8998.o obj-$(CONFIG_PINCTRL_MSMFALCON) += pinctrl-msmfalcon.o obj-$(CONFIG_PINCTRL_WCD) += pinctrl-wcd.o diff --git a/drivers/pinctrl/qcom/pinctrl-msmcobalt.c b/drivers/pinctrl/qcom/pinctrl-msm8998.c index 039da7b0997b..c4882f244d3f 100644 --- a/drivers/pinctrl/qcom/pinctrl-msmcobalt.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8998.c @@ -92,7 +92,32 @@ .intr_detection_bit = -1, \ .intr_detection_width = -1, \ } -static const struct pinctrl_pin_desc msmcobalt_pins[] = { + +#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"), PINCTRL_PIN(2, "GPIO_2"), @@ -246,6 +271,7 @@ static const struct pinctrl_pin_desc msmcobalt_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,8 +430,9 @@ 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 msmcobalt_functions { +enum msm8998_functions { msm_mux_blsp_spi1, msm_mux_blsp_uim1_a, msm_mux_blsp_uart1_a, @@ -1374,7 +1401,7 @@ static const char * const mss_lte_groups[] = { "gpio144", "gpio145", }; -static const struct msm_function msmcobalt_functions[] = { +static const struct msm_function msm8998_functions[] = { FUNCTION(blsp_spi1), FUNCTION(gpio), FUNCTION(blsp_uim1_a), @@ -1612,7 +1639,7 @@ static const struct msm_function msmcobalt_functions[] = { FUNCTION(mss_lte), }; -static const struct msm_pingroup msmcobalt_groups[] = { +static const struct msm_pingroup msm8998_groups[] = { PINGROUP(0, EAST, blsp_spi1, blsp_uart1_a, blsp_uim1_a, NA, NA, NA, NA, NA, NA), PINGROUP(1, EAST, blsp_spi1, blsp_uart1_a, blsp_uim1_a, NA, NA, NA, NA, @@ -1856,50 +1883,51 @@ static const struct msm_pingroup msmcobalt_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 msmcobalt_pinctrl = { - .pins = msmcobalt_pins, - .npins = ARRAY_SIZE(msmcobalt_pins), - .functions = msmcobalt_functions, - .nfunctions = ARRAY_SIZE(msmcobalt_functions), - .groups = msmcobalt_groups, - .ngroups = ARRAY_SIZE(msmcobalt_groups), +static const struct msm_pinctrl_soc_data msm8998_pinctrl = { + .pins = msm8998_pins, + .npins = ARRAY_SIZE(msm8998_pins), + .functions = msm8998_functions, + .nfunctions = ARRAY_SIZE(msm8998_functions), + .groups = msm8998_groups, + .ngroups = ARRAY_SIZE(msm8998_groups), .ngpios = 153, }; -static int msmcobalt_pinctrl_probe(struct platform_device *pdev) +static int msm8998_pinctrl_probe(struct platform_device *pdev) { - return msm_pinctrl_probe(pdev, &msmcobalt_pinctrl); + return msm_pinctrl_probe(pdev, &msm8998_pinctrl); } -static const struct of_device_id msmcobalt_pinctrl_of_match[] = { - { .compatible = "qcom,msmcobalt-pinctrl", }, +static const struct of_device_id msm8998_pinctrl_of_match[] = { + { .compatible = "qcom,msm8998-pinctrl", }, { }, }; -static struct platform_driver msmcobalt_pinctrl_driver = { +static struct platform_driver msm8998_pinctrl_driver = { .driver = { - .name = "msmcobalt-pinctrl", + .name = "msm8998-pinctrl", .owner = THIS_MODULE, - .of_match_table = msmcobalt_pinctrl_of_match, + .of_match_table = msm8998_pinctrl_of_match, }, - .probe = msmcobalt_pinctrl_probe, + .probe = msm8998_pinctrl_probe, .remove = msm_pinctrl_remove, }; -static int __init msmcobalt_pinctrl_init(void) +static int __init msm8998_pinctrl_init(void) { - return platform_driver_register(&msmcobalt_pinctrl_driver); + return platform_driver_register(&msm8998_pinctrl_driver); } -arch_initcall(msmcobalt_pinctrl_init); +arch_initcall(msm8998_pinctrl_init); -static void __exit msmcobalt_pinctrl_exit(void) +static void __exit msm8998_pinctrl_exit(void) { - platform_driver_unregister(&msmcobalt_pinctrl_driver); + platform_driver_unregister(&msm8998_pinctrl_driver); } -module_exit(msmcobalt_pinctrl_exit); +module_exit(msm8998_pinctrl_exit); -MODULE_DESCRIPTION("QTI msmcobalt pinctrl driver"); +MODULE_DESCRIPTION("QTI msm8998 pinctrl driver"); MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, msmcobalt_pinctrl_of_match); +MODULE_DEVICE_TABLE(of, msm8998_pinctrl_of_match); diff --git a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c index 3678f952fe0f..91bbce2ce1d1 100644 --- a/drivers/pinctrl/qcom/pinctrl-msmfalcon.c +++ b/drivers/pinctrl/qcom/pinctrl-msmfalcon.c @@ -748,10 +748,10 @@ static const char * const blsp_i2c5_groups[] = { "gpio18", "gpio19", }; static const char * const blsp_spi6_groups[] = { - "gpio20", "gpio21", "gpio22", "gpio23", + "gpio49", "gpio52", "gpio22", "gpio23", }; static const char * const blsp_uart2_groups[] = { - "gpio20", "gpio21", "gpio22", "gpio23", + "gpio4", "gpio5", "gpio6", "gpio7", }; static const char * const blsp_uim6_groups[] = { "gpio20", "gpio21", @@ -1495,13 +1495,14 @@ static const struct msm_pingroup msmfalcon_groups[] = { NA, NA), PINGROUP(3, SOUTH, blsp_spi1, blsp_uart1, blsp_i2c1, ddr_bist, NA, NA, atest_tsens2, atest_usb1, NA), - PINGROUP(4, NORTH, blsp_spi2, blsp_uim2, NA, phase_flag3, NA, NA, NA, - NA, NA), - PINGROUP(5, SOUTH, blsp_spi2, blsp_uim2, NA, phase_flag14, NA, NA, NA, - NA, NA), - PINGROUP(6, SOUTH, blsp_spi2, blsp_i2c2, NA, phase_flag31, NA, NA, NA, + PINGROUP(4, NORTH, blsp_spi2, blsp_uim2, blsp_uart2, phase_flag3, NA, + NA, NA, NA, NA), + PINGROUP(5, SOUTH, blsp_spi2, blsp_uim2, blsp_uart2, phase_flag14, NA, + NA, NA, NA, NA), + PINGROUP(6, SOUTH, blsp_spi2, blsp_i2c2, blsp_uart2, phase_flag31, NA, + NA, NA, NA, NA), + PINGROUP(7, SOUTH, blsp_spi2, blsp_i2c2, blsp_uart2, NA, NA, NA, NA, NA, NA), - PINGROUP(7, SOUTH, blsp_spi2, blsp_i2c2, NA, NA, NA, NA, NA, NA, NA), PINGROUP(8, NORTH, blsp_spi3, ddr_bist, NA, NA, NA, wlan1_adc1, atest_usb13, bimc_dte1, NA), PINGROUP(9, NORTH, blsp_spi3, ddr_bist, NA, NA, NA, wlan1_adc0, @@ -1526,13 +1527,13 @@ static const struct msm_pingroup msmfalcon_groups[] = { NA, NA), PINGROUP(19, CENTER, blsp_uart5, blsp_spi5, blsp_i2c5, NA, NA, NA, NA, NA, NA), - PINGROUP(20, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, NA, NA, NA, + PINGROUP(20, SOUTH, NA, NA, blsp_uim6, NA, NA, NA, NA, NA, NA), - PINGROUP(21, SOUTH, blsp_spi6, blsp_uart2, blsp_uim6, NA, phase_flag11, + PINGROUP(21, SOUTH, NA, NA, blsp_uim6, NA, phase_flag11, qdss_cti0_b, vsense_data0, NA, NA), - PINGROUP(22, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA, + PINGROUP(22, CENTER, blsp_spi6, NA, blsp_i2c6, NA, phase_flag12, vsense_data1, NA, NA, NA), - PINGROUP(23, CENTER, blsp_spi6, blsp_uart2, blsp_i2c6, NA, + PINGROUP(23, CENTER, blsp_spi6, NA, blsp_i2c6, NA, phase_flag13, vsense_mode, NA, NA, NA), PINGROUP(24, NORTH, blsp_spi7, blsp_uart6_a, sec_mi2s, sndwire_clk, NA, NA, phase_flag17, vsense_clkout, NA), @@ -1580,13 +1581,13 @@ static const struct msm_pingroup msmfalcon_groups[] = { NA, NA, NA), PINGROUP(48, SOUTH, NA, phase_flag1, qdss_gpio15, NA, NA, NA, NA, NA, NA), - PINGROUP(49, SOUTH, NA, phase_flag2, qdss_cti0_a, NA, NA, NA, NA, NA, - NA), + PINGROUP(49, SOUTH, blsp_spi6, phase_flag2, qdss_cti0_a, NA, NA, NA, + NA, NA, NA), PINGROUP(50, SOUTH, qspi_cs, NA, phase_flag9, qdss_cti0_a, NA, NA, NA, NA, NA), PINGROUP(51, SOUTH, qspi_data3, NA, phase_flag15, qdss_gpio8, NA, NA, NA, NA, NA), - PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi8_b, blsp_i2c8_b, NA, + PINGROUP(52, SOUTH, CCI_TIMER2, blsp_spi8_b, blsp_i2c8_b, blsp_spi6, phase_flag16, qdss_gpio, NA, NA, NA), PINGROUP(53, NORTH, NA, phase_flag6, qdss_cti1_a, NA, NA, NA, NA, NA, NA), diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index df3901093006..a617c9e8e11f 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -105,6 +105,8 @@ static void gsi_handle_ch_ctrl(int ee) ch = gsi_readl(gsi_ctx->base + GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_OFFS(ee)); + gsi_writel(ch, gsi_ctx->base + + GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_CLR_OFFS(ee)); GSIDBG("ch %x\n", ch); for (i = 0; i < 32; i++) { if ((1 << i) & ch) { @@ -124,9 +126,6 @@ static void gsi_handle_ch_ctrl(int ee) gsi_ctx->ch_dbg[i].cmd_completed++; } } - - gsi_writel(ch, gsi_ctx->base + - GSI_EE_n_CNTXT_SRC_GSI_CH_IRQ_CLR_OFFS(ee)); } static void gsi_handle_ev_ctrl(int ee) @@ -138,6 +137,8 @@ static void gsi_handle_ev_ctrl(int ee) ch = gsi_readl(gsi_ctx->base + GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_OFFS(ee)); + gsi_writel(ch, gsi_ctx->base + + GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_CLR_OFFS(ee)); GSIDBG("ev %x\n", ch); for (i = 0; i < 32; i++) { if ((1 << i) & ch) { @@ -156,9 +157,6 @@ static void gsi_handle_ev_ctrl(int ee) complete(&ctx->compl); } } - - gsi_writel(ch, gsi_ctx->base + - GSI_EE_n_CNTXT_SRC_EV_CH_IRQ_CLR_OFFS(ee)); } static void gsi_handle_glob_err(uint32_t err) @@ -439,9 +437,16 @@ static void gsi_handle_ieob(int ee) GSI_EE_n_CNTXT_SRC_IEOB_IRQ_OFFS(ee)); msk = gsi_readl(gsi_ctx->base + GSI_EE_n_CNTXT_SRC_IEOB_IRQ_MSK_OFFS(ee)); + gsi_writel(ch & msk, gsi_ctx->base + + GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(ee)); for (i = 0; i < 32; i++) { if ((1 << i) & ch & msk) { + if (i >= gsi_ctx->max_ev || i >= GSI_EVT_RING_MAX) { + GSIERR("invalid event %d\n", i); + break; + } + ctx = &gsi_ctx->evtr[i]; BUG_ON(ctx->props.intf != GSI_EVT_CHTYPE_GPI_EV); spin_lock_irqsave(&ctx->ring.slock, flags); @@ -467,9 +472,6 @@ check_again: spin_unlock_irqrestore(&ctx->ring.slock, flags); } } - - gsi_writel(ch & msk, gsi_ctx->base + - GSI_EE_n_CNTXT_SRC_IEOB_IRQ_CLR_OFFS(ee)); } static void gsi_handle_inter_ee_ch_ctrl(int ee) @@ -479,15 +481,14 @@ static void gsi_handle_inter_ee_ch_ctrl(int ee) ch = gsi_readl(gsi_ctx->base + GSI_INTER_EE_n_SRC_GSI_CH_IRQ_OFFS(ee)); + gsi_writel(ch, gsi_ctx->base + + GSI_INTER_EE_n_SRC_GSI_CH_IRQ_CLR_OFFS(ee)); for (i = 0; i < 32; i++) { if ((1 << i) & ch) { /* not currently expected */ GSIERR("ch %u was inter-EE changed\n", i); } } - - gsi_writel(ch, gsi_ctx->base + - GSI_INTER_EE_n_SRC_GSI_CH_IRQ_CLR_OFFS(ee)); } static void gsi_handle_inter_ee_ev_ctrl(int ee) @@ -497,15 +498,14 @@ static void gsi_handle_inter_ee_ev_ctrl(int ee) ch = gsi_readl(gsi_ctx->base + GSI_INTER_EE_n_SRC_EV_CH_IRQ_OFFS(ee)); + gsi_writel(ch, gsi_ctx->base + + GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_OFFS(ee)); for (i = 0; i < 32; i++) { if ((1 << i) & ch) { /* not currently expected */ GSIERR("evt %u was inter-EE changed\n", i); } } - - gsi_writel(ch, gsi_ctx->base + - GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_OFFS(ee)); } static void gsi_handle_general(int ee) diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c index 75b193def36e..159452c6e3bd 100644 --- a/drivers/platform/msm/ipa/ipa_api.c +++ b/drivers/platform/msm/ipa/ipa_api.c @@ -2907,6 +2907,22 @@ int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, return ret; } +/** + * ipa_get_pdev() - return a pointer to IPA dev struct + * + * Return value: a pointer to IPA dev struct + * + */ +struct device *ipa_get_pdev(void) +{ + struct device *ret; + + IPA_API_DISPATCH_RETURN_PTR(ipa_get_pdev); + + return ret; +} +EXPORT_SYMBOL(ipa_get_pdev); + static const struct dev_pm_ops ipa_pm_ops = { .suspend_noirq = ipa_ap_suspend, .resume_noirq = ipa_ap_resume, diff --git a/drivers/platform/msm/ipa/ipa_api.h b/drivers/platform/msm/ipa/ipa_api.h index eab048323bd5..78fcdeb4b7a0 100644 --- a/drivers/platform/msm/ipa/ipa_api.h +++ b/drivers/platform/msm/ipa/ipa_api.h @@ -369,6 +369,8 @@ struct ipa_api_controller { int (*ipa_tear_down_uc_offload_pipes)(int ipa_ep_idx_ul, int ipa_ep_idx_dl); + + struct device *(*ipa_get_pdev)(void); }; #ifdef CONFIG_IPA diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index 866170d3324d..fd61435db5e2 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -1847,4 +1847,5 @@ int ipa_ntn_init(void); int ipa2_get_ntn_stats(struct IpaHwStatsNTNInfoData_t *stats); int ipa2_register_ipa_ready_cb(void (*ipa_ready_cb)(void *), void *user_data); +struct device *ipa2_get_pdev(void); #endif /* _IPA_I_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c index b627cd1fc833..9813fa417c3a 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c @@ -5102,6 +5102,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_setup_uc_ntn_pipes = ipa2_setup_uc_ntn_pipes; api_ctrl->ipa_tear_down_uc_offload_pipes = ipa2_tear_down_uc_offload_pipes; + api_ctrl->ipa_get_pdev = ipa2_get_pdev; return 0; } @@ -5181,3 +5182,17 @@ void ipa_suspend_apps_pipes(bool suspend) } } } + +/** + * ipa2_get_pdev() - return a pointer to IPA dev struct + * + * Return value: a pointer to IPA dev struct + * + */ +struct device *ipa2_get_pdev(void) +{ + if (!ipa_ctx) + return NULL; + + return ipa_ctx->pdev; +} diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 4b0cd46082a3..be2946c873b3 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1723,6 +1723,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, struct ipa3_sys_context *sys; int src_ep_idx; int num_frags, f; + struct ipa_gsi_ep_config *gsi_ep; if (unlikely(!ipa3_ctx)) { IPAERR("IPA3 driver was not initialized\n"); @@ -1734,23 +1735,6 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, return -EINVAL; } - num_frags = skb_shinfo(skb)->nr_frags; - if (num_frags) { - /* 1 desc for tag to resolve status out-of-order issue; - * 1 desc is needed for the linear portion of skb; - * 1 desc may be needed for the PACKET_INIT; - * 1 desc for each frag - */ - desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); - if (!desc) { - IPAERR("failed to alloc desc array\n"); - goto fail_mem; - } - } else { - memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); - desc = &_desc[0]; - } - /* * USB_CONS: PKT_INIT ep_idx = dst pipe * Q6_CONS: PKT_INIT ep_idx = sender pipe @@ -1787,6 +1771,37 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, goto fail_gen; } + num_frags = skb_shinfo(skb)->nr_frags; + /* + * make sure TLV FIFO supports the needed frags. + * 2 descriptors are needed for IP_PACKET_INIT and TAG_STATUS. + * 1 descriptor needed for the linear portion of skb. + */ + gsi_ep = ipa3_get_gsi_ep_info(src_ep_idx); + if (gsi_ep && (num_frags + 3 > gsi_ep->ipa_if_tlv)) { + if (skb_linearize(skb)) { + IPAERR("Failed to linear skb with %d frags\n", + num_frags); + goto fail_gen; + } + num_frags = 0; + } + if (num_frags) { + /* 1 desc for tag to resolve status out-of-order issue; + * 1 desc is needed for the linear portion of skb; + * 1 desc may be needed for the PACKET_INIT; + * 1 desc for each frag + */ + desc = kzalloc(sizeof(*desc) * (num_frags + 3), GFP_ATOMIC); + if (!desc) { + IPAERR("failed to alloc desc array\n"); + goto fail_gen; + } + } else { + memset(_desc, 0, 3 * sizeof(struct ipa3_desc)); + desc = &_desc[0]; + } + if (dst_ep_idx != -1) { /* SW data path */ cmd.destination_pipe_index = dst_ep_idx; @@ -1794,7 +1809,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, IPA_IMM_CMD_IP_PACKET_INIT, &cmd, true); if (unlikely(!cmd_pyld)) { IPAERR("failed to construct ip_packet_init imm cmd\n"); - goto fail_gen; + goto fail_mem; } /* the tag field will be populated in ipa3_send() function */ @@ -1863,7 +1878,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (num_frags == 0) { if (ipa3_send(sys, 2, desc, true)) { IPAERR("fail to send skb %p HWP\n", skb); - goto fail_gen; + goto fail_mem; } } else { for (f = 0; f < num_frags; f++) { @@ -1880,7 +1895,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, if (ipa3_send(sys, num_frags + 2, desc, true)) { IPAERR("fail to send skb %p num_frags %u HWP\n", skb, num_frags); - goto fail_gen; + goto fail_mem; } } IPA_STATS_INC_CNT(ipa3_ctx->stats.tx_hw_pkts); @@ -1894,10 +1909,10 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, fail_send: ipahal_destroy_imm_cmd(cmd_pyld); -fail_gen: +fail_mem: if (num_frags) kfree(desc); -fail_mem: +fail_gen: return -EFAULT; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 1b78835cda6b..3a666419385e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2027,4 +2027,5 @@ int ipa3_ntn_init(void); int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); +struct device *ipa3_get_pdev(void); #endif /* _IPA3_I_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 4ea68ae1e95c..db60829bce69 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -3199,6 +3199,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_setup_uc_ntn_pipes = ipa3_setup_uc_ntn_pipes; api_ctrl->ipa_tear_down_uc_offload_pipes = ipa3_tear_down_uc_offload_pipes; + api_ctrl->ipa_get_pdev = ipa3_get_pdev; return 0; } @@ -3637,3 +3638,17 @@ bool ipa3_is_msm_device(void) return false; } + +/** + * ipa3_get_pdev() - return a pointer to IPA dev struct + * + * Return value: a pointer to IPA dev struct + * + */ +struct device *ipa3_get_pdev(void) +{ + if (!ipa3_ctx) + return NULL; + + return ipa3_ctx->pdev; +} diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c index 1ef8ebe3ed7d..cfc8093fa3dd 100644 --- a/drivers/platform/msm/qpnp-revid.c +++ b/drivers/platform/msm/qpnp-revid.c @@ -52,8 +52,8 @@ static const char *const pmic_names[] = { [PMI8950_SUBTYPE] = "PMI8950", [PMK8001_SUBTYPE] = "PMK8001", [PMI8996_SUBTYPE] = "PMI8996", - [PMCOBALT_SUBTYPE] = "PMCOBALT", - [PMICOBALT_SUBTYPE] = "PMICOBALT", + [PM8998_SUBTYPE] = "PM8998", + [PMI8998_SUBTYPE] = "PMI8998", [PM8005_SUBTYPE] = "PM8005", [PM8937_SUBTYPE] = "PM8937", [PM2FALCON_SUBTYPE] = "PM2FALCON", diff --git a/drivers/power/qcom-charger/bcl_peripheral.c b/drivers/power/qcom-charger/bcl_peripheral.c index 8a7012ac2bef..cae4967f1ef4 100644 --- a/drivers/power/qcom-charger/bcl_peripheral.c +++ b/drivers/power/qcom-charger/bcl_peripheral.c @@ -56,25 +56,25 @@ #define BCL_VBAT_TRIP 0x68 #define BCL_IBAT_TRIP 0x69 -#define BCL_COBALT_VBAT_VALUE 0x58 -#define BCL_COBALT_IBAT_VALUE 0x59 -#define BCL_COBALT_VBAT_MIN 0x5C -#define BCL_COBALT_IBAT_MAX 0x5D -#define BCL_COBALT_MAX_MIN_CLR 0x48 -#define BCL_COBALT_IBAT_MAX_CLR 3 -#define BCL_COBALT_VBAT_MIN_CLR 2 -#define BCL_COBALT_VBAT_ADC_LOW 0x72 -#define BCL_COBALT_VBAT_COMP_LOW 0x75 -#define BCL_COBALT_VBAT_COMP_TLOW 0x76 -#define BCL_COBALT_IBAT_HIGH 0x78 -#define BCL_COBALT_IBAT_TOO_HIGH 0x79 -#define BCL_COBALT_LMH_CFG 0xA3 -#define BCL_COBALT_BCL_CFG 0x6A -#define LMH_COBALT_INT_POL_HIGH 0x12 -#define LMH_COBALT_INT_EN 0x15 - -#define BCL_COBALT_VBAT_SCALING 39000 -#define BCL_COBALT_IBAT_SCALING 80000 +#define BCL_8998_VBAT_VALUE 0x58 +#define BCL_8998_IBAT_VALUE 0x59 +#define BCL_8998_VBAT_MIN 0x5C +#define BCL_8998_IBAT_MAX 0x5D +#define BCL_8998_MAX_MIN_CLR 0x48 +#define BCL_8998_IBAT_MAX_CLR 3 +#define BCL_8998_VBAT_MIN_CLR 2 +#define BCL_8998_VBAT_ADC_LOW 0x72 +#define BCL_8998_VBAT_COMP_LOW 0x75 +#define BCL_8998_VBAT_COMP_TLOW 0x76 +#define BCL_8998_IBAT_HIGH 0x78 +#define BCL_8998_IBAT_TOO_HIGH 0x79 +#define BCL_8998_LMH_CFG 0xA3 +#define BCL_8998_BCL_CFG 0x6A +#define LMH_8998_INT_POL_HIGH 0x12 +#define LMH_8998_INT_EN 0x15 + +#define BCL_8998_VBAT_SCALING 39000 +#define BCL_8998_IBAT_SCALING 80000 #define BCL_VBAT_LOW_THRESHOLD 0x7 /* 3.1V */ #define BCL_VBAT_TLOW_THRESHOLD 0x5 /* 2.9v */ #define BCL_IBAT_HIGH_THRESH_UA 4300000 @@ -124,7 +124,7 @@ enum bcl_monitor_state { enum bcl_hw_type { BCL_PMI8994, - BCL_PMICOBALT, + BCL_PMI8998, BCL_VERSION_MAX, }; @@ -243,8 +243,8 @@ static void convert_vbat_to_adc_val(int *val) / perph_data->gain_factor_den)) / perph_data->scaling_factor; break; - case BCL_PMICOBALT: - *val = *val / BCL_COBALT_VBAT_SCALING; + case BCL_PMI8998: + *val = *val / BCL_8998_VBAT_SCALING; break; default: break; @@ -268,8 +268,8 @@ static void convert_adc_to_vbat_val(int *val) * BCL_CONSTANT_NUM / perph_data->gain_factor_den) / 100; break; - case BCL_PMICOBALT: - *val = *val * BCL_COBALT_VBAT_SCALING; + case BCL_PMI8998: + *val = *val * BCL_8998_VBAT_SCALING; break; default: break; @@ -295,8 +295,8 @@ static void convert_ibat_to_adc_val(int *val) / perph_data->offset_factor_den) / perph_data->scaling_factor; break; - case BCL_PMICOBALT: - *val = *val / BCL_COBALT_IBAT_SCALING; + case BCL_PMI8998: + *val = *val / BCL_8998_IBAT_SCALING; break; default: break; @@ -321,8 +321,8 @@ static void convert_adc_to_ibat_val(int *val) * perph_data->gain) * BCL_CONSTANT_NUM / perph_data->gain_factor_den) / 100; break; - case BCL_PMICOBALT: - *val = *val * BCL_COBALT_IBAT_SCALING; + case BCL_PMI8998: + *val = *val * BCL_8998_IBAT_SCALING; break; default: break; @@ -355,18 +355,18 @@ static int bcl_set_high_ibat(int thresh_value) thresh_value); val = (int8_t)thresh_value; ret = bcl_write_register((bcl_perph_version == BCL_PMI8994) ? - BCL_IBAT_TRIP : BCL_COBALT_IBAT_HIGH, val); + BCL_IBAT_TRIP : BCL_8998_IBAT_HIGH, val); if (ret) { pr_err("Error accessing BCL peripheral. err:%d\n", ret); return ret; } bcl_perph->param[BCL_PARAM_CURRENT].high_trip = thresh_value; - if (bcl_perph_version == BCL_PMICOBALT) { + if (bcl_perph_version == BCL_PMI8998) { convert_ibat_to_adc_val(&too_high_thresh); pr_debug("Setting Ibat too high trip:%d. ADC_val:%d\n", BCL_IBAT_HIGH_THRESH_UA, too_high_thresh); val = (int8_t)too_high_thresh; - ret = bcl_write_register(BCL_COBALT_IBAT_TOO_HIGH, val); + ret = bcl_write_register(BCL_8998_IBAT_TOO_HIGH, val); if (ret) { pr_err("Error accessing BCL peripheral. err:%d\n", ret); return ret; @@ -408,13 +408,13 @@ static int bcl_set_low_vbat(int thresh_value) thresh_value); val = (int8_t)thresh_value; ret = bcl_write_register((bcl_perph_version == BCL_PMI8994) - ? BCL_VBAT_TRIP : BCL_COBALT_VBAT_ADC_LOW, val); + ? BCL_VBAT_TRIP : BCL_8998_VBAT_ADC_LOW, val); if (ret) { pr_err("Error accessing BCL peripheral. err:%d\n", ret); return ret; } - if (bcl_perph_version == BCL_PMICOBALT) { - ret = bcl_write_register(BCL_COBALT_VBAT_COMP_LOW, + if (bcl_perph_version == BCL_PMI8998) { + ret = bcl_write_register(BCL_8998_VBAT_COMP_LOW, BCL_VBAT_LOW_THRESHOLD); if (ret) { pr_err("Error accessing BCL peripheral. err:%d\n", ret); @@ -422,7 +422,7 @@ static int bcl_set_low_vbat(int thresh_value) } pr_debug("Setting Vbat low comparator threshold:0x%x.\n", BCL_VBAT_LOW_THRESHOLD); - ret = bcl_write_register(BCL_COBALT_VBAT_COMP_TLOW, + ret = bcl_write_register(BCL_8998_VBAT_COMP_TLOW, BCL_VBAT_TLOW_THRESHOLD); if (ret) { pr_err("Error accessing BCL peripheral. err:%d\n", ret); @@ -482,7 +482,7 @@ static int bcl_access_monitor_enable(bool enable) if (enable == bcl_perph->enabled) goto access_exit; - if ((bcl_perph_version == BCL_PMICOBALT) && !hw_enabled && enable) + if ((bcl_perph_version == BCL_PMI8998) && !hw_enabled && enable) bcl_lmh_dcvs_enable(); for (; i < BCL_PARAM_MAX; i++) { @@ -552,7 +552,7 @@ static int bcl_read_ibat_high_trip(int *thresh_value) *thresh_value = (int)val; ret = bcl_read_register((bcl_perph_version == BCL_PMI8994) ? - BCL_IBAT_TRIP : BCL_COBALT_IBAT_HIGH, &val); + BCL_IBAT_TRIP : BCL_8998_IBAT_HIGH, &val); if (ret) { pr_err("BCL register read error. err:%d\n", ret); ret = 0; @@ -581,7 +581,7 @@ static int bcl_read_vbat_low_trip(int *thresh_value) *thresh_value = (int)val; ret = bcl_read_register((bcl_perph_version == BCL_PMI8994) - ? BCL_VBAT_TRIP : BCL_COBALT_VBAT_ADC_LOW, + ? BCL_VBAT_TRIP : BCL_8998_VBAT_ADC_LOW, &val); if (ret) { pr_err("BCL register read error. err:%d\n", ret); @@ -610,8 +610,8 @@ static int bcl_clear_vbat_min(void) if (bcl_perph_version == BCL_PMI8994) ret = bcl_write_register(BCL_VBAT_MIN_CLR, BIT(7)); else - ret = bcl_write_register(BCL_COBALT_MAX_MIN_CLR, - BIT(BCL_COBALT_VBAT_MIN_CLR)); + ret = bcl_write_register(BCL_8998_MAX_MIN_CLR, + BIT(BCL_8998_VBAT_MIN_CLR)); if (ret) pr_err("Error in clearing vbat min reg. err:%d", ret); @@ -625,8 +625,8 @@ static int bcl_clear_ibat_max(void) if (bcl_perph_version == BCL_PMI8994) ret = bcl_write_register(BCL_IBAT_MAX_CLR, BIT(7)); else - ret = bcl_write_register(BCL_COBALT_MAX_MIN_CLR, - BIT(BCL_COBALT_IBAT_MAX_CLR)); + ret = bcl_write_register(BCL_8998_MAX_MIN_CLR, + BIT(BCL_8998_IBAT_MAX_CLR)); if (ret) pr_err("Error in clearing ibat max reg. err:%d", ret); @@ -642,7 +642,7 @@ static int bcl_read_ibat_max(int *adc_value) do { ret = bcl_read_multi_register( (bcl_perph_version == BCL_PMI8994) ? BCL_IBAT_MAX - : BCL_COBALT_IBAT_MAX, val, + : BCL_8998_IBAT_MAX, val, VAL_CP_REG_BUF_LEN); if (ret) { pr_err("BCL register read error. err:%d\n", ret); @@ -673,7 +673,7 @@ static int bcl_read_vbat_min(int *adc_value) do { ret = bcl_read_multi_register( (bcl_perph_version == BCL_PMI8994) ? BCL_VBAT_MIN - : BCL_COBALT_VBAT_MIN, val, + : BCL_8998_VBAT_MIN, val, VAL_CP_REG_BUF_LEN); if (ret) { pr_err("BCL register read error. err:%d\n", ret); @@ -704,7 +704,7 @@ static int bcl_read_ibat(int *adc_value) do { ret = bcl_read_multi_register( (bcl_perph_version == BCL_PMI8994) ? BCL_IBAT_VALUE - : BCL_COBALT_IBAT_VALUE, val, + : BCL_8998_IBAT_VALUE, val, VAL_CP_REG_BUF_LEN); if (ret) { pr_err("BCL register read error. err:%d\n", ret); @@ -735,7 +735,7 @@ static int bcl_read_vbat(int *adc_value) do { ret = bcl_read_multi_register( (bcl_perph_version == BCL_PMI8994) ? BCL_VBAT_VALUE : - BCL_COBALT_VBAT_VALUE, val, + BCL_8998_VBAT_VALUE, val, VAL_CP_REG_BUF_LEN); if (ret) { pr_err("BCL register read error. err:%d\n", ret); @@ -1231,11 +1231,11 @@ static int bcl_probe(struct platform_device *pdev) return ret; } } else { - bcl_write_register(BCL_COBALT_LMH_CFG, BCL_LMH_CFG_VAL); - bcl_write_register(BCL_COBALT_BCL_CFG, BCL_CFG_VAL); - bcl_write_general_register(LMH_COBALT_INT_POL_HIGH, + bcl_write_register(BCL_8998_LMH_CFG, BCL_LMH_CFG_VAL); + bcl_write_register(BCL_8998_BCL_CFG, BCL_CFG_VAL); + bcl_write_general_register(LMH_8998_INT_POL_HIGH, bcl_perph->fg_lmh_addr, LMH_INT_VAL); - bcl_write_general_register(LMH_COBALT_INT_EN, + bcl_write_general_register(LMH_8998_INT_EN, bcl_perph->fg_lmh_addr, LMH_INT_VAL); } @@ -1320,7 +1320,7 @@ static struct of_device_id bcl_match[] = { .data = (void *) BCL_PMI8994, }, { .compatible = "qcom,msm-bcl-lmh", - .data = (void *) BCL_PMICOBALT, + .data = (void *) BCL_PMI8998, }, {}, }; diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index 100153280d9e..6ff0e9e45b00 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -25,9 +25,9 @@ #define FG_GEN3_DEV_NAME "qcom,fg-gen3" #define PERPH_SUBTYPE_REG 0x05 -#define FG_BATT_SOC_PMICOBALT 0x10 -#define FG_BATT_INFO_PMICOBALT 0x11 -#define FG_MEM_INFO_PMICOBALT 0x0D +#define FG_BATT_SOC_PMI8998 0x10 +#define FG_BATT_INFO_PMI8998 0x11 +#define FG_MEM_INFO_PMI8998 0x0D /* SRAM address and offset in ascending order */ #define CUTOFF_VOLT_WORD 5 @@ -143,7 +143,7 @@ static void fg_encode_default(struct fg_sram_param *sp, .decode = _dec, \ } \ -static struct fg_sram_param pmicobalt_v1_sram_params[] = { +static struct fg_sram_param pmi8998_v1_sram_params[] = { PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL, fg_decode_default), PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL, @@ -197,7 +197,7 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = { fg_encode_default, NULL), }; -static struct fg_sram_param pmicobalt_v2_sram_params[] = { +static struct fg_sram_param pmi8998_v2_sram_params[] = { PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL, fg_decode_default), PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL, @@ -254,7 +254,7 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = { fg_encode_default, NULL), }; -static struct fg_alg_flag pmicobalt_v1_alg_flags[] = { +static struct fg_alg_flag pmi8998_v1_alg_flags[] = { [ALG_FLAG_SOC_LT_OTG_MIN] = { .name = "SOC_LT_OTG_MIN", .bit = BIT(0), @@ -284,7 +284,7 @@ static struct fg_alg_flag pmicobalt_v1_alg_flags[] = { }, }; -static struct fg_alg_flag pmicobalt_v2_alg_flags[] = { +static struct fg_alg_flag pmi8998_v2_alg_flags[] = { [ALG_FLAG_SOC_LT_OTG_MIN] = { .name = "SOC_LT_OTG_MIN", .bit = BIT(0), @@ -545,7 +545,7 @@ static int fg_get_battery_esr(struct fg_chip *chip, int *val) return rc; } - if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4) + if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4) temp = ((buf[0] & ESR_MSB_MASK) << 8) | (buf[1] & ESR_LSB_MASK); else @@ -592,7 +592,7 @@ static int fg_get_battery_current(struct fg_chip *chip, int *val) return rc; } - if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4) + if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4) temp = buf[0] << 8 | buf[1]; else temp = buf[1] << 8 | buf[0]; @@ -619,7 +619,7 @@ static int fg_get_battery_voltage(struct fg_chip *chip, int *val) return rc; } - if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4) + if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4) temp = buf[0] << 8 | buf[1]; else temp = buf[1] << 8 | buf[0]; @@ -2396,7 +2396,7 @@ static int fg_hw_init(struct fg_chip *chip) } /* This SRAM register is only present in v2.0 */ - if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4 && + if (chip->pmic_rev_id->rev4 == PMI8998_V2P0_REV4 && chip->bp.float_volt_uv > 0) { fg_encode(chip->sp, FG_SRAM_FLOAT_VOLT, chip->bp.float_volt_uv / 1000, buf); @@ -2986,13 +2986,13 @@ static int fg_parse_dt(struct fg_chip *chip) chip->pmic_rev_id->pmic_subtype, chip->pmic_rev_id->rev4); switch (chip->pmic_rev_id->pmic_subtype) { - case PMICOBALT_SUBTYPE: - if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4) { - chip->sp = pmicobalt_v1_sram_params; - chip->alg_flags = pmicobalt_v1_alg_flags; - } else if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4) { - chip->sp = pmicobalt_v2_sram_params; - chip->alg_flags = pmicobalt_v2_alg_flags; + case PMI8998_SUBTYPE: + if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4) { + chip->sp = pmi8998_v1_sram_params; + chip->alg_flags = pmi8998_v1_alg_flags; + } else if (chip->pmic_rev_id->rev4 == PMI8998_V2P0_REV4) { + chip->sp = pmi8998_v2_sram_params; + chip->alg_flags = pmi8998_v2_alg_flags; } else { return -EINVAL; } @@ -3032,13 +3032,13 @@ static int fg_parse_dt(struct fg_chip *chip) } switch (subtype) { - case FG_BATT_SOC_PMICOBALT: + case FG_BATT_SOC_PMI8998: chip->batt_soc_base = base; break; - case FG_BATT_INFO_PMICOBALT: + case FG_BATT_INFO_PMI8998: chip->batt_info_base = base; break; - case FG_MEM_INFO_PMICOBALT: + case FG_MEM_INFO_PMI8998: chip->mem_if_base = base; break; default: diff --git a/drivers/power/qcom-charger/qpnp-qnovo.c b/drivers/power/qcom-charger/qpnp-qnovo.c index 2418b112d670..ac1c900f4771 100644 --- a/drivers/power/qcom-charger/qpnp-qnovo.c +++ b/drivers/power/qcom-charger/qpnp-qnovo.c @@ -317,8 +317,8 @@ static int qnovo_check_chg_version(struct qnovo *chip) return rc; } - if ((chip->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE) - && (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4)) { + if ((chip->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) + && (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)) { chip->wa_flags |= QNOVO_ERASE_OFFSET_WA_BIT; chip->wa_flags |= QNOVO_NO_ERR_STS_BIT; } diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c index 6968ab2ab11c..f7a54f71a28a 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/qcom-charger/qpnp-smb2.c @@ -214,7 +214,6 @@ static struct smb_params v1_params = { #define STEP_CHARGING_MAX_STEPS 5 struct smb_dt_props { - bool no_battery; int fcc_ua; int usb_icl_ua; int otg_cl_ua; @@ -226,7 +225,9 @@ struct smb_dt_props { struct device_node *revid_dev_node; int float_option; int chg_inhibit_thr_mv; + bool no_battery; bool hvdcp_disable; + bool auto_recharge_soc; }; struct smb2 { @@ -344,6 +345,8 @@ static int smb2_parse_dt(struct smb2 *chip) return -EINVAL; } + chip->dt.auto_recharge_soc = of_property_read_bool(node, + "qcom,auto-recharge-soc"); return 0; } @@ -1069,6 +1072,7 @@ static int smb2_init_hw(struct smb2 *chip) &chip->dt.dc_icl_ua); chg->otg_cl_ua = chip->dt.otg_cl_ua; + chg->dcp_icl_ua = chip->dt.usb_icl_ua; rc = smblib_read(chg, APSD_RESULT_STATUS_REG, &stat); if (rc < 0) { @@ -1101,7 +1105,7 @@ static int smb2_init_hw(struct smb2 *chip) vote(chg->fv_votable, DEFAULT_VOTER, true, chip->dt.fv_uv); vote(chg->usb_icl_votable, - DEFAULT_VOTER, true, chip->dt.usb_icl_ua); + DCP_VOTER, true, chip->dt.usb_icl_ua); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); vote(chg->hvdcp_disable_votable, DEFAULT_VOTER, @@ -1168,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; } @@ -1186,6 +1192,13 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } + /* disable try.SINK mode */ + rc = smblib_masked_write(chg, TYPE_C_CFG_3_REG, EN_TRYSINK_MODE_BIT, 0); + if (rc < 0) { + dev_err(chg->dev, "Couldn't set TRYSINK_MODE rc=%d\n", rc); + return rc; + } + rc = smblib_masked_write(chg, QNOVO_PT_ENABLE_CMD_REG, QNOVO_PT_ENABLE_CMD_BIT, QNOVO_PT_ENABLE_CMD_BIT); if (rc < 0) { @@ -1280,6 +1293,35 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } + rc = smblib_validate_initial_typec_legacy_status(chg); + if (rc < 0) { + dev_err(chg->dev, "Couldn't validate typec legacy status rc=%d\n", + rc); + return rc; + } + + if (chip->dt.auto_recharge_soc) { + rc = smblib_masked_write(chg, FG_UPDATE_CFG_2_SEL_REG, + SOC_LT_CHG_RECHARGE_THRESH_SEL_BIT | + VBT_LT_CHG_RECHARGE_THRESH_SEL_BIT, + VBT_LT_CHG_RECHARGE_THRESH_SEL_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n", + rc); + return rc; + } + } else { + rc = smblib_masked_write(chg, FG_UPDATE_CFG_2_SEL_REG, + SOC_LT_CHG_RECHARGE_THRESH_SEL_BIT | + VBT_LT_CHG_RECHARGE_THRESH_SEL_BIT, + SOC_LT_CHG_RECHARGE_THRESH_SEL_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n", + rc); + return rc; + } + } + return rc; } @@ -1307,11 +1349,11 @@ static int smb2_setup_wa_flags(struct smb2 *chip) } switch (pmic_rev_id->pmic_subtype) { - case PMICOBALT_SUBTYPE: + case PMI8998_SUBTYPE: chip->chg.wa_flags |= BOOST_BACK_WA; - if (pmic_rev_id->rev4 == PMICOBALT_V1P1_REV4) /* PMI rev 1.1 */ + if (pmic_rev_id->rev4 == PMI8998_V1P1_REV4) /* PMI rev 1.1 */ chg->wa_flags |= QC_CHARGER_DETECTION_WA_BIT; - if (pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4) /* PMI rev 2.0 */ + if (pmic_rev_id->rev4 == PMI8998_V2P0_REV4) /* PMI rev 2.0 */ chg->wa_flags |= TYPEC_CC2_REMOVAL_WA_BIT; break; default: @@ -1822,8 +1864,13 @@ static void smb2_shutdown(struct platform_device *pdev) struct smb2 *chip = platform_get_drvdata(pdev); struct smb_charger *chg = &chip->chg; + /* configure power role for UFP */ + smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, + TYPEC_POWER_ROLE_CMD_MASK, UFP_EN_CMD_BIT); + + /* force HVDCP to 5V */ smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, - HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT, 0); + HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT, 0); smblib_write(chg, CMD_HVDCP_2_REG, FORCE_5V_BIT); } diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index 6aae7d49271f..0faf8aee8aa0 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -16,6 +16,7 @@ #include <linux/iio/consumer.h> #include <linux/power_supply.h> #include <linux/regulator/driver.h> +#include <linux/qpnp/power-on.h> #include <linux/irq.h> #include "smb-lib.h" #include "smb-reg.h" @@ -504,15 +505,14 @@ static int try_rerun_apsd_for_hvdcp(struct smb_charger *chg) static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) { - const struct apsd_result *apsd_result; + const struct apsd_result *apsd_result = smblib_get_apsd_result(chg); /* if PD is active, APSD is disabled so won't have a valid result */ if (chg->pd_active) { chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_PD; - return 0; + return apsd_result; } - apsd_result = smblib_get_apsd_result(chg); chg->usb_psy_desc.type = apsd_result->pst; return apsd_result; } @@ -2015,6 +2015,13 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } + rc = vote(chg->usb_icl_votable, DCP_VOTER, false, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", + rc); + return rc; + } + rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, USBIN_MODE_CHG_BIT, USBIN_MODE_CHG_BIT); if (rc < 0) { @@ -2031,6 +2038,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } } else { + rc = vote(chg->usb_icl_votable, DCP_VOTER, true, + chg->dcp_icl_ua); + if (rc < 0) { + smblib_err(chg, "Couldn't vote for USB ICL rc=%d\n", + rc); + return rc; + } + rc = smblib_masked_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT, 0); if (rc < 0) { @@ -2066,13 +2081,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_update_usb_type(chg); power_supply_changed(chg->usb_psy); - rc = smblib_masked_write(chg, TYPE_C_CFG_3_REG, EN_TRYSINK_MODE_BIT, - chg->pd_active ? 0 : EN_TRYSINK_MODE_BIT); - if (rc < 0) { - dev_err(chg->dev, "Couldn't set TRYSINK_MODE rc=%d\n", rc); - return rc; - } - return rc; } @@ -2857,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; } @@ -3356,3 +3364,40 @@ int smblib_deinit(struct smb_charger *chg) return 0; } + +int smblib_validate_initial_typec_legacy_status(struct smb_charger *chg) +{ + int rc; + u8 stat; + + + if (qpnp_pon_is_warm_reset()) + return 0; + + rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat); + if (rc < 0) { + smblib_err(chg, "Couldn't read TYPE_C_STATUS_5 rc=%d\n", rc); + return rc; + } + + if ((stat & TYPEC_LEGACY_CABLE_STATUS_BIT) == 0) + return 0; + + rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, + TYPEC_DISABLE_CMD_BIT, TYPEC_DISABLE_CMD_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't disable typec rc=%d\n", rc); + return rc; + } + + usleep_range(150000, 151000); + + rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, + TYPEC_DISABLE_CMD_BIT, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't enable typec rc=%d\n", rc); + return rc; + } + + return 0; +} diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h index a0237412ee8b..b309095b04c1 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/qcom-charger/smb-lib.h @@ -28,6 +28,7 @@ enum print_reason { #define DEFAULT_VOTER "DEFAULT_VOTER" #define USER_VOTER "USER_VOTER" #define PD_VOTER "PD_VOTER" +#define DCP_VOTER "DCP_VOTER" #define USB_PSY_VOTER "USB_PSY_VOTER" #define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER" #define PARALLEL_PSY_VOTER "PARALLEL_PSY_VOTER" @@ -203,6 +204,7 @@ struct smb_charger { int *thermal_mitigation; int otg_cl_ua; + int dcp_icl_ua; int fake_capacity; @@ -354,6 +356,8 @@ int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg, int smblib_get_prop_slave_current_now(struct smb_charger *chg, union power_supply_propval *val); +int smblib_validate_initial_typec_legacy_status(struct smb_charger *chg); + int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); #endif /* __SMB2_CHARGER_H */ diff --git a/drivers/power/qcom-charger/smb138x-charger.c b/drivers/power/qcom-charger/smb138x-charger.c index 9dc528a6bb45..4255958de300 100644 --- a/drivers/power/qcom-charger/smb138x-charger.c +++ b/drivers/power/qcom-charger/smb138x-charger.c @@ -630,10 +630,12 @@ static int smb138x_init_hw(struct smb138x *chip) vote(chg->fcc_votable, DEFAULT_VOTER, true, chip->dt.fcc_ua); vote(chg->usb_icl_votable, - DEFAULT_VOTER, true, chip->dt.usb_icl_ua); + DCP_VOTER, true, chip->dt.usb_icl_ua); vote(chg->dc_icl_votable, DEFAULT_VOTER, true, chip->dt.dc_icl_ua); + chg->dcp_icl_ua = chip->dt.usb_icl_ua; + /* configure charge enable for software control; active high */ rc = smblib_masked_write(chg, CHGR_CFG2_REG, CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0); diff --git a/drivers/regulator/cpr3-mmss-regulator.c b/drivers/regulator/cpr3-mmss-regulator.c index 59cbe7460750..1ac9791b467b 100644 --- a/drivers/regulator/cpr3-mmss-regulator.c +++ b/drivers/regulator/cpr3-mmss-regulator.c @@ -52,7 +52,7 @@ * min and max sensors measured at time of manufacturing * @force_highest_corner: Flag indicating that all corners must operate * at the voltage of the highest corner. This is - * applicable to MSMCOBALT only. + * applicable to MSM8998 only. * * This struct holds the values for all of the fuses read from memory. */ @@ -76,7 +76,7 @@ struct cpr3_msm8996_mmss_fuses { #define CPR3_MSM8996PRO_MMSS_FUSE_COMBO_COUNT 16 /* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */ -#define CPR3_MSMCOBALT_MMSS_FUSE_COMBO_COUNT 8 +#define CPR3_MSM8998_MMSS_FUSE_COMBO_COUNT 8 /* * MSM8996 MMSS fuse parameter locations: @@ -128,34 +128,34 @@ static const struct cpr3_fuse_param msm8996pro_mmss_speed_bin_param[] = { {}, }; -/* MSMCOBALT MMSS fuse parameter locations: */ +/* MSM8998 MMSS fuse parameter locations: */ static const struct cpr3_fuse_param -msmcobalt_mmss_init_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { +msm8998_mmss_init_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { {{65, 39, 43}, {} }, {{65, 34, 38}, {} }, {{65, 29, 33}, {} }, {{65, 24, 28}, {} }, }; -static const struct cpr3_fuse_param msmcobalt_cpr_fusing_rev_param[] = { +static const struct cpr3_fuse_param msm8998_cpr_fusing_rev_param[] = { {39, 48, 50}, {}, }; -static const struct cpr3_fuse_param msmcobalt_cpr_limitation_param[] = { +static const struct cpr3_fuse_param msm8998_cpr_limitation_param[] = { {41, 46, 47}, {}, }; static const struct cpr3_fuse_param -msmcobalt_mmss_aging_init_quot_diff_param[] = { +msm8998_mmss_aging_init_quot_diff_param[] = { {65, 60, 63}, {66, 0, 3}, {}, }; static const struct cpr3_fuse_param -msmcobalt_mmss_offset_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { +msm8998_mmss_offset_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { {{65, 56, 59}, {} }, {{65, 52, 55}, {} }, {{65, 48, 51}, {} }, @@ -163,14 +163,14 @@ msmcobalt_mmss_offset_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmcobalt_cpr_force_highest_corner_param[] = { +msm8998_cpr_force_highest_corner_param[] = { {100, 45, 45}, {}, }; #define MSM8996PRO_SOC_ID 4 -#define MSMCOBALT_V1_SOC_ID 5 -#define MSMCOBALT_V2_SOC_ID 6 +#define MSM8998_V1_SOC_ID 5 +#define MSM8998_V2_SOC_ID 6 /* * Some initial msm8996 parts cannot be used in a meaningful way by software. @@ -201,7 +201,7 @@ static const int msm8996pro_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { 1065000, }; -static const int msmcobalt_v1_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { +static const int msm8998_v1_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { 528000, 656000, 812000, @@ -209,14 +209,14 @@ static const int msmcobalt_v1_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { }; static const int -msmcobalt_v1_rev0_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { +msm8998_v1_rev0_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { 632000, 768000, 896000, 1032000, }; -static const int msmcobalt_v2_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { +static const int msm8998_v2_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { 516000, 628000, 752000, @@ -224,7 +224,7 @@ static const int msmcobalt_v2_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { }; static const int -msmcobalt_v2_rev0_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { +msm8998_v2_rev0_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { 616000, 740000, 828000, @@ -245,40 +245,40 @@ msmcobalt_v2_rev0_mmss_fuse_ref_volt[MSM8996_MMSS_FUSE_CORNERS] = { #define MSM8996_MMSS_AGING_SENSOR_ID 29 #define MSM8996_MMSS_AGING_BYPASS_MASK0 (GENMASK(23, 0)) -#define MSMCOBALT_MMSS_AGING_INIT_QUOT_DIFF_SCALE 1 -#define MSMCOBALT_MMSS_AGING_INIT_QUOT_DIFF_SIZE 8 +#define MSM8998_MMSS_AGING_INIT_QUOT_DIFF_SCALE 1 +#define MSM8998_MMSS_AGING_INIT_QUOT_DIFF_SIZE 8 -#define MSMCOBALT_MMSS_CPR_SENSOR_COUNT 35 +#define MSM8998_MMSS_CPR_SENSOR_COUNT 35 -#define MSMCOBALT_MMSS_AGING_SENSOR_ID 29 -#define MSMCOBALT_MMSS_AGING_BYPASS_MASK0 (GENMASK(23, 0)) +#define MSM8998_MMSS_AGING_SENSOR_ID 29 +#define MSM8998_MMSS_AGING_BYPASS_MASK0 (GENMASK(23, 0)) -#define MSMCOBALT_MMSS_MAX_TEMP_POINTS 3 -#define MSMCOBALT_MMSS_TEMP_SENSOR_ID_START 12 -#define MSMCOBALT_MMSS_TEMP_SENSOR_ID_END 13 +#define MSM8998_MMSS_MAX_TEMP_POINTS 3 +#define MSM8998_MMSS_TEMP_SENSOR_ID_START 12 +#define MSM8998_MMSS_TEMP_SENSOR_ID_END 13 /* - * Some initial msmcobalt parts cannot be operated at low voltages. The + * Some initial msm8998 parts cannot be operated at low voltages. The * open-loop voltage fuses are reused to identify these parts so that software * can properly handle the limitation. 0xF means that the next higher fuse * corner should be used. 0xE means that the next higher fuse corner which * does not have a voltage limitation should be used. */ -enum msmcobalt_cpr_partial_binning { - MSMCOBALT_CPR_PARTIAL_BINNING_NEXT_CORNER = 0xF, - MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER = 0xE, +enum msm8998_cpr_partial_binning { + MSM8998_CPR_PARTIAL_BINNING_NEXT_CORNER = 0xF, + MSM8998_CPR_PARTIAL_BINNING_SAFE_CORNER = 0xE, }; /* * The partial binning open-loop voltage fuse values only apply to the lowest * two fuse corners (0 and 1, i.e. MinSVS and SVS). */ -#define MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER 1 +#define MSM8998_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER 1 -static inline bool cpr3_ctrl_is_msmcobalt(const struct cpr3_controller *ctrl) +static inline bool cpr3_ctrl_is_msm8998(const struct cpr3_controller *ctrl) { - return ctrl->soc_revision == MSMCOBALT_V1_SOC_ID || - ctrl->soc_revision == MSMCOBALT_V2_SOC_ID; + return ctrl->soc_revision == MSM8998_V1_SOC_ID || + ctrl->soc_revision == MSM8998_V2_SOC_ID; } /** @@ -313,8 +313,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_cpr_fusing_rev_param + cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_cpr_fusing_rev_param : msm8996_cpr_fusing_rev_param, &fuse->cpr_fusing_rev); if (rc) { @@ -325,8 +325,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev); rc = cpr3_read_fuse_param(base, - cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_cpr_limitation_param + cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_cpr_limitation_param : msm8996_cpr_limitation_param, &fuse->limitation); if (rc) { @@ -341,8 +341,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) ? "CPR disabled and no interpolation" : "none"); rc = cpr3_read_fuse_param(base, - cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_mmss_aging_init_quot_diff_param + cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_mmss_aging_init_quot_diff_param : msm8996_mmss_aging_init_quot_diff_param, &fuse->aging_init_quot_diff); if (rc) { @@ -353,8 +353,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) for (i = 0; i < MSM8996_MMSS_FUSE_CORNERS; i++) { rc = cpr3_read_fuse_param(base, - cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_mmss_init_voltage_param[i] + cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_mmss_init_voltage_param[i] : msm8996_mmss_init_voltage_param[i], &fuse->init_voltage[i]); if (rc) { @@ -364,8 +364,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_mmss_offset_voltage_param[i] + cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_mmss_offset_voltage_param[i] : msm8996_mmss_offset_voltage_param[i], &fuse->offset_voltage[i]); if (rc) { @@ -375,9 +375,9 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) } } - if (cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl)) { + if (cpr3_ctrl_is_msm8998(vreg->thread->ctrl)) { rc = cpr3_read_fuse_param(base, - msmcobalt_cpr_force_highest_corner_param, + msm8998_cpr_force_highest_corner_param, &fuse->force_highest_corner); if (rc) { cpr3_err(vreg, "Unable to read CPR force highest corner fuse, rc=%d\n", @@ -388,8 +388,8 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) cpr3_info(vreg, "Fusing requires all operation at the highest corner\n"); } - if (cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl)) { - combo_max = CPR3_MSMCOBALT_MMSS_FUSE_COMBO_COUNT; + if (cpr3_ctrl_is_msm8998(vreg->thread->ctrl)) { + combo_max = CPR3_MSM8998_MMSS_FUSE_COMBO_COUNT; vreg->fuse_combo = fuse->cpr_fusing_rev; } else if (vreg->thread->ctrl->soc_revision == MSM8996PRO_SOC_ID) { combo_max = CPR3_MSM8996PRO_MMSS_FUSE_COMBO_COUNT; @@ -493,8 +493,8 @@ static int cpr3_msm8996_mmss_apply_closed_loop_offset_voltages( if (rc) goto done; - offset_param = cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl) - ? msmcobalt_mmss_offset_voltage_param + offset_param = cpr3_ctrl_is_msm8998(vreg->thread->ctrl) + ? msm8998_mmss_offset_voltage_param : msm8996_mmss_offset_voltage_param; for (i = 0; i < vreg->fuse_corner_count; i++) { fuse_len = offset_param[i][0].bit_end + 1 @@ -749,7 +749,7 @@ static int cpr3_msm8996_mmss_calculate_open_loop_voltages( { struct device_node *node = vreg->of_node; struct cpr3_msm8996_mmss_fuses *fuse = vreg->platform_fuses; - bool is_msmcobalt = cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl); + bool is_msm8998 = cpr3_ctrl_is_msm8998(vreg->thread->ctrl); int rc = 0; bool allow_interpolation; u64 freq_low, volt_low, freq_high, volt_high, volt_init; @@ -767,16 +767,16 @@ static int cpr3_msm8996_mmss_calculate_open_loop_voltages( goto done; } - if (vreg->thread->ctrl->soc_revision == MSMCOBALT_V2_SOC_ID + if (vreg->thread->ctrl->soc_revision == MSM8998_V2_SOC_ID && fuse->cpr_fusing_rev == 0) - ref_volt = msmcobalt_v2_rev0_mmss_fuse_ref_volt; - else if (vreg->thread->ctrl->soc_revision == MSMCOBALT_V2_SOC_ID) - ref_volt = msmcobalt_v2_mmss_fuse_ref_volt; - else if (vreg->thread->ctrl->soc_revision == MSMCOBALT_V1_SOC_ID + ref_volt = msm8998_v2_rev0_mmss_fuse_ref_volt; + else if (vreg->thread->ctrl->soc_revision == MSM8998_V2_SOC_ID) + ref_volt = msm8998_v2_mmss_fuse_ref_volt; + else if (vreg->thread->ctrl->soc_revision == MSM8998_V1_SOC_ID && fuse->cpr_fusing_rev == 0) - ref_volt = msmcobalt_v1_rev0_mmss_fuse_ref_volt; - else if (vreg->thread->ctrl->soc_revision == MSMCOBALT_V1_SOC_ID) - ref_volt = msmcobalt_v1_mmss_fuse_ref_volt; + ref_volt = msm8998_v1_rev0_mmss_fuse_ref_volt; + else if (vreg->thread->ctrl->soc_revision == MSM8998_V1_SOC_ID) + ref_volt = msm8998_v1_mmss_fuse_ref_volt; else if (vreg->thread->ctrl->soc_revision == MSM8996PRO_SOC_ID) ref_volt = msm8996pro_mmss_fuse_ref_volt; else @@ -785,16 +785,16 @@ static int cpr3_msm8996_mmss_calculate_open_loop_voltages( for (i = 0; i < vreg->fuse_corner_count; i++) { volt_init = fuse->init_voltage[i]; /* - * Handle partial binning on MSMCOBALT where the initial voltage + * Handle partial binning on MSM8998 where the initial voltage * fuse is reused as a flag for partial binning needs. Set the * open-loop voltage to the minimum possible value so that it * does not result in higher fuse corners getting forced to * higher open-loop voltages after monotonicity enforcement. */ - if (is_msmcobalt && - (volt_init == MSMCOBALT_CPR_PARTIAL_BINNING_NEXT_CORNER || - volt_init == MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER) && - i <= MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER) + if (is_msm8998 && + (volt_init == MSM8998_CPR_PARTIAL_BINNING_NEXT_CORNER || + volt_init == MSM8998_CPR_PARTIAL_BINNING_SAFE_CORNER) && + i <= MSM8998_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER) volt_init = MSM8996_MMSS_MIN_VOLTAGE_FUSE_VAL; fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i], @@ -887,7 +887,7 @@ done: } /** - * cpr3_msmcobalt_partial_binning_override() - override the voltage and quotient + * cpr3_msm8998_partial_binning_override() - override the voltage and quotient * settings for low corners based upon the special partial binning * open-loop voltage fuse values * @vreg: Pointer to the CPR3 regulator @@ -897,17 +897,17 @@ done: * * Return: 0 on success, errno on failure */ -static int cpr3_msmcobalt_partial_binning_override(struct cpr3_regulator *vreg) +static int cpr3_msm8998_partial_binning_override(struct cpr3_regulator *vreg) { struct cpr3_msm8996_mmss_fuses *fuse = vreg->platform_fuses; - u64 next = MSMCOBALT_CPR_PARTIAL_BINNING_NEXT_CORNER; - u64 safe = MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER; + u64 next = MSM8998_CPR_PARTIAL_BINNING_NEXT_CORNER; + u64 safe = MSM8998_CPR_PARTIAL_BINNING_SAFE_CORNER; u32 proc_freq; struct cpr3_corner *corner; struct cpr3_corner *safe_corner; int i, j, low, high, safe_fuse_corner, max_fuse_corner; - if (!cpr3_ctrl_is_msmcobalt(vreg->thread->ctrl)) + if (!cpr3_ctrl_is_msm8998(vreg->thread->ctrl)) return 0; /* Handle the force highest corner fuse. */ @@ -932,7 +932,7 @@ static int cpr3_msmcobalt_partial_binning_override(struct cpr3_regulator *vreg) * Allow up to the max corner which can be fused with partial * binning values. */ - max_fuse_corner = min(MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER, + max_fuse_corner = min(MSM8998_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER, vreg->fuse_corner_count - 2); for (i = 0; i <= max_fuse_corner; i++) { @@ -1042,15 +1042,15 @@ static int cpr3_mmss_init_aging(struct cpr3_controller *ctrl) ctrl->aging_sensor->ro_scale = aging_ro_scale; - if (cpr3_ctrl_is_msmcobalt(ctrl)) { - ctrl->aging_sensor->sensor_id = MSMCOBALT_MMSS_AGING_SENSOR_ID; + if (cpr3_ctrl_is_msm8998(ctrl)) { + ctrl->aging_sensor->sensor_id = MSM8998_MMSS_AGING_SENSOR_ID; ctrl->aging_sensor->bypass_mask[0] - = MSMCOBALT_MMSS_AGING_BYPASS_MASK0; + = MSM8998_MMSS_AGING_BYPASS_MASK0; ctrl->aging_sensor->init_quot_diff = cpr3_convert_open_loop_voltage_fuse(0, - MSMCOBALT_MMSS_AGING_INIT_QUOT_DIFF_SCALE, + MSM8998_MMSS_AGING_INIT_QUOT_DIFF_SCALE, fuse->aging_init_quot_diff, - MSMCOBALT_MMSS_AGING_INIT_QUOT_DIFF_SIZE); + MSM8998_MMSS_AGING_INIT_QUOT_DIFF_SIZE); } else { ctrl->aging_sensor->sensor_id = MSM8996_MMSS_AGING_SENSOR_ID; ctrl->aging_sensor->bypass_mask[0] @@ -1141,7 +1141,7 @@ static int cpr3_mmss_init_thread(struct cpr3_thread *thread) return rc; } - if (cpr3_ctrl_is_msmcobalt(thread->ctrl)) { + if (cpr3_ctrl_is_msm8998(thread->ctrl)) { rc = cpr4_parse_core_count_temp_voltage_adj(vreg, false); if (rc) { cpr3_err(vreg, "unable to parse temperature based voltage adjustments, rc=%d\n", @@ -1150,7 +1150,7 @@ static int cpr3_mmss_init_thread(struct cpr3_thread *thread) } } - rc = cpr3_msmcobalt_partial_binning_override(vreg); + rc = cpr3_msm8998_partial_binning_override(vreg); if (rc) { cpr3_err(vreg, "unable to override CPR parameters based on partial binning fuse values, rc=%d\n", rc); @@ -1179,9 +1179,9 @@ static int cpr4_mmss_parse_temp_adj_properties(struct cpr3_controller *ctrl) temp_point_count = len / sizeof(u32); if (temp_point_count <= 0 - || temp_point_count > MSMCOBALT_MMSS_MAX_TEMP_POINTS) { + || temp_point_count > MSM8998_MMSS_MAX_TEMP_POINTS) { cpr3_err(ctrl, "invalid number of temperature points %d > %d (max)\n", - temp_point_count, MSMCOBALT_MMSS_MAX_TEMP_POINTS); + temp_point_count, MSM8998_MMSS_MAX_TEMP_POINTS); return -EINVAL; } @@ -1218,8 +1218,8 @@ static int cpr4_mmss_parse_temp_adj_properties(struct cpr3_controller *ctrl) return -EINVAL; } - ctrl->temp_sensor_id_start = MSMCOBALT_MMSS_TEMP_SENSOR_ID_START; - ctrl->temp_sensor_id_end = MSMCOBALT_MMSS_TEMP_SENSOR_ID_END; + ctrl->temp_sensor_id_start = MSM8998_MMSS_TEMP_SENSOR_ID_START; + ctrl->temp_sensor_id_end = MSM8998_MMSS_TEMP_SENSOR_ID_END; ctrl->allow_temp_adj = true; return rc; @@ -1244,14 +1244,14 @@ static int cpr3_mmss_init_controller(struct cpr3_controller *ctrl) return rc; } - if (cpr3_ctrl_is_msmcobalt(ctrl)) { + if (cpr3_ctrl_is_msm8998(ctrl)) { rc = cpr4_mmss_parse_temp_adj_properties(ctrl); if (rc) return rc; } - ctrl->sensor_count = cpr3_ctrl_is_msmcobalt(ctrl) - ? MSMCOBALT_MMSS_CPR_SENSOR_COUNT + ctrl->sensor_count = cpr3_ctrl_is_msm8998(ctrl) + ? MSM8998_MMSS_CPR_SENSOR_COUNT : MSM8996_MMSS_CPR_SENSOR_COUNT; /* @@ -1264,7 +1264,7 @@ static int cpr3_mmss_init_controller(struct cpr3_controller *ctrl) return -ENOMEM; ctrl->cpr_clock_rate = MSM8996_MMSS_CPR_CLOCK_RATE; - ctrl->ctrl_type = cpr3_ctrl_is_msmcobalt(ctrl) + ctrl->ctrl_type = cpr3_ctrl_is_msm8998(ctrl) ? CPR_CTRL_TYPE_CPR4 : CPR_CTRL_TYPE_CPR3; if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) { @@ -1281,8 +1281,8 @@ static int cpr3_mmss_init_controller(struct cpr3_controller *ctrl) ctrl->iface_clk = devm_clk_get(ctrl->dev, "iface_clk"); if (IS_ERR(ctrl->iface_clk)) { rc = PTR_ERR(ctrl->iface_clk); - if (cpr3_ctrl_is_msmcobalt(ctrl)) { - /* iface_clk is optional for msmcobalt */ + if (cpr3_ctrl_is_msm8998(ctrl)) { + /* iface_clk is optional for msm8998 */ ctrl->iface_clk = NULL; } else if (rc == -EPROBE_DEFER) { return rc; @@ -1343,16 +1343,16 @@ static struct of_device_id cpr_regulator_match_table[] = { .data = (void *)(uintptr_t)MSM8996PRO_SOC_ID, }, { - .compatible = "qcom,cpr4-msmcobalt-v1-mmss-regulator", - .data = (void *)(uintptr_t)MSMCOBALT_V1_SOC_ID, + .compatible = "qcom,cpr4-msm8998-v1-mmss-regulator", + .data = (void *)(uintptr_t)MSM8998_V1_SOC_ID, }, { - .compatible = "qcom,cpr4-msmcobalt-v2-mmss-regulator", - .data = (void *)(uintptr_t)MSMCOBALT_V2_SOC_ID, + .compatible = "qcom,cpr4-msm8998-v2-mmss-regulator", + .data = (void *)(uintptr_t)MSM8998_V2_SOC_ID, }, { - .compatible = "qcom,cpr4-msmcobalt-mmss-regulator", - .data = (void *)(uintptr_t)MSMCOBALT_V2_SOC_ID, + .compatible = "qcom,cpr4-msm8998-mmss-regulator", + .data = (void *)(uintptr_t)MSM8998_V2_SOC_ID, }, {} }; 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 5661ae75843c..9cbd1ee18ec3 100644 --- a/drivers/regulator/cprh-kbss-regulator.c +++ b/drivers/regulator/cprh-kbss-regulator.c @@ -35,10 +35,10 @@ #include "cpr3-regulator.h" -#define MSMCOBALT_KBSS_FUSE_CORNERS 4 +#define MSM8998_KBSS_FUSE_CORNERS 4 /** - * struct cprh_msmcobalt_kbss_fuses - KBSS specific fuse data for MSMCOBALT + * struct cprh_msm8998_kbss_fuses - KBSS specific fuse data for MSM8998 * @ro_sel: Ring oscillator select fuse parameter value for each * fuse corner * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value @@ -53,17 +53,17 @@ * @cpr_fusing_rev: CPR fusing revision fuse parameter value * @force_highest_corner: Flag indicating that all corners must operate * at the voltage of the highest corner. This is - * applicable to MSMCOBALT only. + * applicable to MSM8998 only. * @aging_init_quot_diff: Initial quotient difference between CPR aging * min and max sensors measured at time of manufacturing * * This struct holds the values for all of the fuses read from memory. */ -struct cprh_msmcobalt_kbss_fuses { - u64 ro_sel[MSMCOBALT_KBSS_FUSE_CORNERS]; - u64 init_voltage[MSMCOBALT_KBSS_FUSE_CORNERS]; - u64 target_quot[MSMCOBALT_KBSS_FUSE_CORNERS]; - u64 quot_offset[MSMCOBALT_KBSS_FUSE_CORNERS]; +struct cprh_msm8998_kbss_fuses { + u64 ro_sel[MSM8998_KBSS_FUSE_CORNERS]; + u64 init_voltage[MSM8998_KBSS_FUSE_CORNERS]; + u64 target_quot[MSM8998_KBSS_FUSE_CORNERS]; + u64 quot_offset[MSM8998_KBSS_FUSE_CORNERS]; u64 speed_bin; u64 cpr_fusing_rev; u64 force_highest_corner; @@ -73,36 +73,38 @@ struct cprh_msmcobalt_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_MSMCOBALT_KBSS_FUSE_COMBO_COUNT 16 +#define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32 /* * Constants which define the name of each fuse corner. */ -enum cprh_msmcobalt_kbss_fuse_corner { - CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS = 0, - CPRH_MSMCOBALT_KBSS_FUSE_CORNER_SVS = 1, - CPRH_MSMCOBALT_KBSS_FUSE_CORNER_NOM = 2, - CPRH_MSMCOBALT_KBSS_FUSE_CORNER_TURBO_L1 = 3, +enum cprh_msm8998_kbss_fuse_corner { + CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS = 0, + CPRH_MSM8998_KBSS_FUSE_CORNER_SVS = 1, + CPRH_MSM8998_KBSS_FUSE_CORNER_NOM = 2, + CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1 = 3, }; -static const char * const cprh_msmcobalt_kbss_fuse_corner_name[] = { - [CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS] = "LowSVS", - [CPRH_MSMCOBALT_KBSS_FUSE_CORNER_SVS] = "SVS", - [CPRH_MSMCOBALT_KBSS_FUSE_CORNER_NOM] = "NOM", - [CPRH_MSMCOBALT_KBSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", +static const char * const cprh_msm8998_kbss_fuse_corner_name[] = { + [CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS] = "LowSVS", + [CPRH_MSM8998_KBSS_FUSE_CORNER_SVS] = "SVS", + [CPRH_MSM8998_KBSS_FUSE_CORNER_NOM] = "NOM", + [CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", }; /* KBSS cluster IDs */ -#define MSMCOBALT_KBSS_POWER_CLUSTER_ID 0 -#define MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID 1 +#define MSM8998_KBSS_POWER_CLUSTER_ID 0 +#define MSM8998_KBSS_PERFORMANCE_CLUSTER_ID 1 /* KBSS controller IDs */ -#define MSMCOBALT_KBSS_MIN_CONTROLLER_ID 0 -#define MSMCOBALT_KBSS_MAX_CONTROLLER_ID 1 +#define MSM8998_KBSS_MIN_CONTROLLER_ID 0 +#define MSM8998_KBSS_MAX_CONTROLLER_ID 1 /* - * MSMCOBALT KBSS fuse parameter locations: + * MSM8998 KBSS fuse parameter locations: * * Structs are organized with the following dimensions: * Outer: 0 or 1 for power or performance cluster @@ -116,14 +118,14 @@ static const char * const cprh_msmcobalt_kbss_fuse_corner_name[] = { * */ static const struct cpr3_fuse_param -msmcobalt_kbss_ro_sel_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][2] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_kbss_ro_sel_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { {{67, 12, 15}, {} }, {{67, 8, 11}, {} }, {{67, 4, 7}, {} }, {{67, 0, 3}, {} }, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { {{69, 26, 29}, {} }, {{69, 22, 25}, {} }, {{69, 18, 21}, {} }, @@ -132,14 +134,14 @@ msmcobalt_kbss_ro_sel_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmcobalt_kbss_init_voltage_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][2] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_kbss_init_voltage_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { {{67, 34, 39}, {} }, {{67, 28, 33}, {} }, {{67, 22, 27}, {} }, {{67, 16, 21}, {} }, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { {{69, 48, 53}, {} }, {{69, 42, 47}, {} }, {{69, 36, 41}, {} }, @@ -148,14 +150,14 @@ msmcobalt_kbss_init_voltage_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmcobalt_kbss_target_quot_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][3] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_kbss_target_quot_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { {{68, 18, 29}, {} }, {{68, 6, 17}, {} }, {{67, 58, 63}, {68, 0, 5} }, {{67, 46, 57}, {} }, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { {{70, 32, 43}, {} }, {{70, 20, 31}, {} }, {{70, 8, 19}, {} }, @@ -164,14 +166,14 @@ msmcobalt_kbss_target_quot_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][3] = { }; static const struct cpr3_fuse_param -msmcobalt_kbss_quot_offset_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][3] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_kbss_quot_offset_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { {{} }, {{68, 63, 63}, {69, 0, 5}, {} }, {{68, 56, 62}, {} }, {{68, 49, 55}, {} }, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { {{} }, {{71, 13, 15}, {71, 21, 24}, {} }, {{71, 6, 12}, {} }, @@ -179,39 +181,39 @@ msmcobalt_kbss_quot_offset_param[2][MSMCOBALT_KBSS_FUSE_CORNERS][3] = { }, }; -static const struct cpr3_fuse_param msmcobalt_cpr_fusing_rev_param[] = { +static const struct cpr3_fuse_param msm8998_cpr_fusing_rev_param[] = { {39, 51, 53}, {}, }; -static const struct cpr3_fuse_param msmcobalt_kbss_speed_bin_param[] = { +static const struct cpr3_fuse_param msm8998_kbss_speed_bin_param[] = { {38, 29, 31}, {}, }; static const struct cpr3_fuse_param -msmcobalt_cpr_force_highest_corner_param[] = { +msm8998_cpr_force_highest_corner_param[] = { {100, 45, 45}, {}, }; static const struct cpr3_fuse_param -msmcobalt_kbss_aging_init_quot_diff_param[2][2] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_kbss_aging_init_quot_diff_param[2][2] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { {69, 6, 13}, {}, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { {71, 25, 32}, {}, }, }; /* - * Open loop voltage fuse reference voltages in microvolts for MSMCOBALT v1 + * Open loop voltage fuse reference voltages in microvolts for MSM8998 v1 */ static const int -msmcobalt_v1_kbss_fuse_ref_volt[MSMCOBALT_KBSS_FUSE_CORNERS] = { +msm8998_v1_kbss_fuse_ref_volt[MSM8998_KBSS_FUSE_CORNERS] = { 696000, 768000, 896000, @@ -219,17 +221,17 @@ msmcobalt_v1_kbss_fuse_ref_volt[MSMCOBALT_KBSS_FUSE_CORNERS] = { }; /* - * Open loop voltage fuse reference voltages in microvolts for MSMCOBALT v2 + * Open loop voltage fuse reference voltages in microvolts for MSM8998 v2 */ static const int -msmcobalt_v2_kbss_fuse_ref_volt[2][MSMCOBALT_KBSS_FUSE_CORNERS] = { - [MSMCOBALT_KBSS_POWER_CLUSTER_ID] = { +msm8998_v2_kbss_fuse_ref_volt[2][MSM8998_KBSS_FUSE_CORNERS] = { + [MSM8998_KBSS_POWER_CLUSTER_ID] = { 688000, 756000, 828000, 1056000, }, - [MSMCOBALT_KBSS_PERFORMANCE_CLUSTER_ID] = { + [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { 756000, 756000, 828000, @@ -237,55 +239,55 @@ msmcobalt_v2_kbss_fuse_ref_volt[2][MSMCOBALT_KBSS_FUSE_CORNERS] = { }, }; -#define MSMCOBALT_KBSS_FUSE_STEP_VOLT 10000 -#define MSMCOBALT_KBSS_VOLTAGE_FUSE_SIZE 6 -#define MSMCOBALT_KBSS_QUOT_OFFSET_SCALE 5 -#define MSMCOBALT_KBSS_AGING_INIT_QUOT_DIFF_SIZE 8 -#define MSMCOBALT_KBSS_AGING_INIT_QUOT_DIFF_SCALE 1 +#define MSM8998_KBSS_FUSE_STEP_VOLT 10000 +#define MSM8998_KBSS_VOLTAGE_FUSE_SIZE 6 +#define MSM8998_KBSS_QUOT_OFFSET_SCALE 5 +#define MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SIZE 8 +#define MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SCALE 1 -#define MSMCOBALT_KBSS_POWER_CPR_SENSOR_COUNT 6 -#define MSMCOBALT_KBSS_PERFORMANCE_CPR_SENSOR_COUNT 9 +#define MSM8998_KBSS_POWER_CPR_SENSOR_COUNT 6 +#define MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT 9 -#define MSMCOBALT_KBSS_CPR_CLOCK_RATE 19200000 +#define MSM8998_KBSS_CPR_CLOCK_RATE 19200000 -#define MSMCOBALT_KBSS_MAX_CORNER_BAND_COUNT 4 -#define MSMCOBALT_KBSS_MAX_CORNER_COUNT 40 +#define MSM8998_KBSS_MAX_CORNER_BAND_COUNT 4 +#define MSM8998_KBSS_MAX_CORNER_COUNT 40 -#define MSMCOBALT_KBSS_CPR_SDELTA_CORE_COUNT 4 +#define MSM8998_KBSS_CPR_SDELTA_CORE_COUNT 4 -#define MSMCOBALT_KBSS_MAX_TEMP_POINTS 3 -#define MSMCOBALT_KBSS_POWER_TEMP_SENSOR_ID_START 1 -#define MSMCOBALT_KBSS_POWER_TEMP_SENSOR_ID_END 5 -#define MSMCOBALT_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START 6 -#define MSMCOBALT_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END 10 +#define MSM8998_KBSS_MAX_TEMP_POINTS 3 +#define MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START 1 +#define MSM8998_KBSS_POWER_TEMP_SENSOR_ID_END 5 +#define MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START 6 +#define MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END 10 -#define MSMCOBALT_KBSS_POWER_AGING_SENSOR_ID 0 -#define MSMCOBALT_KBSS_POWER_AGING_BYPASS_MASK0 0 +#define MSM8998_KBSS_POWER_AGING_SENSOR_ID 0 +#define MSM8998_KBSS_POWER_AGING_BYPASS_MASK0 0 -#define MSMCOBALT_KBSS_PERFORMANCE_AGING_SENSOR_ID 0 -#define MSMCOBALT_KBSS_PERFORMANCE_AGING_BYPASS_MASK0 0 +#define MSM8998_KBSS_PERFORMANCE_AGING_SENSOR_ID 0 +#define MSM8998_KBSS_PERFORMANCE_AGING_BYPASS_MASK0 0 /** - * cprh_msmcobalt_kbss_read_fuse_data() - load KBSS specific fuse parameter values + * cprh_msm8998_kbss_read_fuse_data() - load KBSS specific fuse parameter values * @vreg: Pointer to the CPR3 regulator * - * This function allocates a cprh_msmcobalt_kbss_fuses struct, fills it with + * This function allocates a cprh_msm8998_kbss_fuses struct, fills it with * values read out of hardware fuses, and finally copies common fuse values * into the CPR3 regulator struct. * * Return: 0 on success, errno on failure */ -static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) +static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg) { void __iomem *base = vreg->thread->ctrl->fuse_base; - struct cprh_msmcobalt_kbss_fuses *fuse; + struct cprh_msm8998_kbss_fuses *fuse; int i, id, rc; fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); if (!fuse) return -ENOMEM; - rc = cpr3_read_fuse_param(base, msmcobalt_kbss_speed_bin_param, + rc = cpr3_read_fuse_param(base, msm8998_kbss_speed_bin_param, &fuse->speed_bin); if (rc) { cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc); @@ -293,7 +295,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin); - rc = cpr3_read_fuse_param(base, msmcobalt_cpr_fusing_rev_param, + rc = cpr3_read_fuse_param(base, msm8998_cpr_fusing_rev_param, &fuse->cpr_fusing_rev); if (rc) { cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n", @@ -304,9 +306,9 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) id = vreg->thread->ctrl->ctrl_id; - for (i = 0; i < MSMCOBALT_KBSS_FUSE_CORNERS; i++) { + for (i = 0; i < MSM8998_KBSS_FUSE_CORNERS; i++) { rc = cpr3_read_fuse_param(base, - msmcobalt_kbss_init_voltage_param[id][i], + msm8998_kbss_init_voltage_param[id][i], &fuse->init_voltage[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n", @@ -315,7 +317,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmcobalt_kbss_target_quot_param[id][i], + msm8998_kbss_target_quot_param[id][i], &fuse->target_quot[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d target quotient fuse, rc=%d\n", @@ -324,7 +326,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmcobalt_kbss_ro_sel_param[id][i], + msm8998_kbss_ro_sel_param[id][i], &fuse->ro_sel[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d RO select fuse, rc=%d\n", @@ -333,7 +335,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmcobalt_kbss_quot_offset_param[id][i], + msm8998_kbss_quot_offset_param[id][i], &fuse->quot_offset[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d quotient offset fuse, rc=%d\n", @@ -344,7 +346,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmcobalt_kbss_aging_init_quot_diff_param[id], + msm8998_kbss_aging_init_quot_diff_param[id], &fuse->aging_init_quot_diff); if (rc) { cpr3_err(vreg, "Unable to read aging initial quotient difference fuse, rc=%d\n", @@ -353,7 +355,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmcobalt_cpr_force_highest_corner_param, + msm8998_cpr_force_highest_corner_param, &fuse->force_highest_corner); if (rc) { cpr3_err(vreg, "Unable to read CPR force highest corner fuse, rc=%d\n", @@ -365,7 +367,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) cpr3_info(vreg, "Fusing requires all operation at the highest corner\n"); vreg->fuse_combo = fuse->cpr_fusing_rev + 8 * fuse->speed_bin; - if (vreg->fuse_combo >= CPRH_MSMCOBALT_KBSS_FUSE_COMBO_COUNT) { + if (vreg->fuse_combo >= CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT) { cpr3_err(vreg, "invalid CPR fuse combo = %d found\n", vreg->fuse_combo); return -EINVAL; @@ -373,7 +375,7 @@ static int cprh_msmcobalt_kbss_read_fuse_data(struct cpr3_regulator *vreg) vreg->speed_bin_fuse = fuse->speed_bin; vreg->cpr_rev_fuse = fuse->cpr_fusing_rev; - vreg->fuse_corner_count = MSMCOBALT_KBSS_FUSE_CORNERS; + vreg->fuse_corner_count = MSM8998_KBSS_FUSE_CORNERS; vreg->platform_fuses = fuse; return 0; @@ -397,13 +399,13 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) } /* - * A total of MSMCOBALT_KBSS_MAX_CORNER_COUNT - 1 corners + * A total of MSM8998_KBSS_MAX_CORNER_COUNT - 1 corners * may be specified in device tree as an additional corner * must be allocated to correspond to the APM crossover voltage. */ - if (vreg->corner_count > MSMCOBALT_KBSS_MAX_CORNER_COUNT - 1) { + if (vreg->corner_count > MSM8998_KBSS_MAX_CORNER_COUNT - 1) { cpr3_err(vreg, "corner count %d exceeds supported maximum %d\n", - vreg->corner_count, MSMCOBALT_KBSS_MAX_CORNER_COUNT - 1); + vreg->corner_count, MSM8998_KBSS_MAX_CORNER_COUNT - 1); return -EINVAL; } @@ -411,7 +413,7 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) } /** - * cprh_msmcobalt_kbss_calculate_open_loop_voltages() - calculate the open-loop + * cprh_msm8998_kbss_calculate_open_loop_voltages() - calculate the open-loop * voltage for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -427,11 +429,11 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) * * Return: 0 on success, errno on failure */ -static int cprh_msmcobalt_kbss_calculate_open_loop_voltages( +static int cprh_msm8998_kbss_calculate_open_loop_voltages( struct cpr3_regulator *vreg) { struct device_node *node = vreg->of_node; - struct cprh_msmcobalt_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; int i, j, soc_revision, id, rc = 0; bool allow_interpolation; u64 freq_low, volt_low, freq_high, volt_high; @@ -451,19 +453,19 @@ static int cprh_msmcobalt_kbss_calculate_open_loop_voltages( id = vreg->thread->ctrl->ctrl_id; soc_revision = vreg->thread->ctrl->soc_revision; if (soc_revision == 1) - ref_volt = msmcobalt_v1_kbss_fuse_ref_volt; + ref_volt = msm8998_v1_kbss_fuse_ref_volt; else - ref_volt = msmcobalt_v2_kbss_fuse_ref_volt[id]; + ref_volt = msm8998_v2_kbss_fuse_ref_volt[id]; for (i = 0; i < vreg->fuse_corner_count; i++) { fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse( ref_volt[i], - MSMCOBALT_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], - MSMCOBALT_KBSS_VOLTAGE_FUSE_SIZE); + MSM8998_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], + MSM8998_KBSS_VOLTAGE_FUSE_SIZE); /* Log fused open-loop voltage values for debugging purposes. */ cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", - cprh_msmcobalt_kbss_fuse_corner_name[i], + cprh_msm8998_kbss_fuse_corner_name[i], fuse_volt[i]); } @@ -547,7 +549,7 @@ done: } /** - * cprh_msmcobalt_partial_binning_override() - override the voltage and quotient + * cprh_msm8998_partial_binning_override() - override the voltage and quotient * settings for low corners based upon special partial binning * fuse values * @@ -559,9 +561,9 @@ done: * * Return: 0 on success, errno on failure */ -static int cprh_msmcobalt_partial_binning_override(struct cpr3_regulator *vreg) +static int cprh_msm8998_partial_binning_override(struct cpr3_regulator *vreg) { - struct cprh_msmcobalt_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; struct cpr3_corner *corner; struct cpr4_sdelta *sdelta; int i; @@ -657,11 +659,11 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( kfree(combo_corner_bands); if (vreg->corner_band_count <= 0 || - vreg->corner_band_count > MSMCOBALT_KBSS_MAX_CORNER_BAND_COUNT || + vreg->corner_band_count > MSM8998_KBSS_MAX_CORNER_BAND_COUNT || vreg->corner_band_count > vreg->corner_count) { cpr3_err(vreg, "invalid corner band count %d > %d (max) for %d corners\n", vreg->corner_band_count, - MSMCOBALT_KBSS_MAX_CORNER_BAND_COUNT, + MSM8998_KBSS_MAX_CORNER_BAND_COUNT, vreg->corner_count); return -EINVAL; } @@ -759,9 +761,9 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( temp_point_count = len / sizeof(u32); if (temp_point_count <= 0 || temp_point_count > - MSMCOBALT_KBSS_MAX_TEMP_POINTS) { + MSM8998_KBSS_MAX_TEMP_POINTS) { cpr3_err(ctrl, "invalid number of temperature points %d > %d (max)\n", - temp_point_count, MSMCOBALT_KBSS_MAX_TEMP_POINTS); + temp_point_count, MSM8998_KBSS_MAX_TEMP_POINTS); rc = -EINVAL; goto free_temp; } @@ -810,13 +812,13 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( } ctrl->temp_sensor_id_start = ctrl->ctrl_id == - MSMCOBALT_KBSS_POWER_CLUSTER_ID - ? MSMCOBALT_KBSS_POWER_TEMP_SENSOR_ID_START : - MSMCOBALT_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START; + MSM8998_KBSS_POWER_CLUSTER_ID + ? MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START : + MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START; ctrl->temp_sensor_id_end = ctrl->ctrl_id == - MSMCOBALT_KBSS_POWER_CLUSTER_ID - ? MSMCOBALT_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START : - MSMCOBALT_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END; + MSM8998_KBSS_POWER_CLUSTER_ID + ? MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START : + MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END; ctrl->allow_temp_adj = true; return 0; @@ -866,7 +868,45 @@ static int cprh_kbss_apm_crossover_as_corner(struct cpr3_regulator *vreg) } /** - * cprh_msmcobalt_kbss_set_no_interpolation_quotients() - use the fused target + * 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 * @volt_adjust: Pointer to array of per-corner closed-loop adjustment @@ -878,11 +918,11 @@ static int cprh_kbss_apm_crossover_as_corner(struct cpr3_regulator *vreg) * * Return: 0 on success, errno on failure */ -static int cprh_msmcobalt_kbss_set_no_interpolation_quotients( +static int cprh_msm8998_kbss_set_no_interpolation_quotients( struct cpr3_regulator *vreg, int *volt_adjust, int *volt_adjust_fuse, int *ro_scale) { - struct cprh_msmcobalt_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; u32 quot, ro; int quot_adjust; int i, fuse_corner; @@ -909,7 +949,7 @@ static int cprh_msmcobalt_kbss_set_no_interpolation_quotients( } /** - * cprh_msmcobalt_kbss_calculate_target_quotients() - calculate the CPR target + * cprh_msm8998_kbss_calculate_target_quotients() - calculate the CPR target * quotient for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -925,10 +965,10 @@ static int cprh_msmcobalt_kbss_set_no_interpolation_quotients( * * Return: 0 on success, errno on failure */ -static int cprh_msmcobalt_kbss_calculate_target_quotients( +static int cprh_msm8998_kbss_calculate_target_quotients( struct cpr3_regulator *vreg) { - struct cprh_msmcobalt_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; int rc; bool allow_interpolation; u64 freq_low, freq_high, prev_quot; @@ -941,15 +981,15 @@ static int cprh_msmcobalt_kbss_calculate_target_quotients( /* Log fused quotient values for debugging purposes. */ cpr3_info(vreg, "fused LowSVS: quot[%2llu]=%4llu\n", - fuse->ro_sel[CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS], - fuse->target_quot[CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS]); - for (i = CPRH_MSMCOBALT_KBSS_FUSE_CORNER_SVS; - i <= CPRH_MSMCOBALT_KBSS_FUSE_CORNER_TURBO_L1; i++) + fuse->ro_sel[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS], + fuse->target_quot[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS]); + for (i = CPRH_MSM8998_KBSS_FUSE_CORNER_SVS; + i <= CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1; i++) cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu, quot_offset[%2llu]=%4llu\n", - cprh_msmcobalt_kbss_fuse_corner_name[i], + cprh_msm8998_kbss_fuse_corner_name[i], fuse->ro_sel[i], fuse->target_quot[i], fuse->ro_sel[i], fuse->quot_offset[i] * - MSMCOBALT_KBSS_QUOT_OFFSET_SCALE); + MSM8998_KBSS_QUOT_OFFSET_SCALE); allow_interpolation = of_property_read_bool(vreg->of_node, "qcom,allow-quotient-interpolation"); @@ -982,7 +1022,7 @@ static int cprh_msmcobalt_kbss_calculate_target_quotients( if (!allow_interpolation) { /* Use fused target quotients for lower frequencies. */ - return cprh_msmcobalt_kbss_set_no_interpolation_quotients( + return cprh_msm8998_kbss_set_no_interpolation_quotients( vreg, volt_adjust, volt_adjust_fuse, ro_scale); } @@ -1004,7 +1044,7 @@ static int cprh_msmcobalt_kbss_calculate_target_quotients( * Interpolation is not possible for corners mapped to the lowest fuse * corner so use the fuse corner value directly. */ - i = CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS; + i = CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS; quot_adjust = cpr3_quot_adjustment(ro_scale[i], volt_adjust_fuse[i]); quot = fuse->target_quot[i] + quot_adjust; quot_high[i] = quot_low[i] = quot; @@ -1013,11 +1053,11 @@ static int cprh_msmcobalt_kbss_calculate_target_quotients( cpr3_debug(vreg, "adjusted fuse corner %d RO%u target quot: %llu --> %u (%d uV)\n", i, ro, fuse->target_quot[i], quot, volt_adjust_fuse[i]); - for (i = 0; i <= fmax_corner[CPRH_MSMCOBALT_KBSS_FUSE_CORNER_LOWSVS]; + for (i = 0; i <= fmax_corner[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS]; i++) vreg->corner[i].target_quot[ro] = quot; - for (i = CPRH_MSMCOBALT_KBSS_FUSE_CORNER_SVS; + for (i = CPRH_MSM8998_KBSS_FUSE_CORNER_SVS; i < vreg->fuse_corner_count; i++) { quot_high[i] = fuse->target_quot[i]; if (fuse->ro_sel[i] == fuse->ro_sel[i - 1]) @@ -1025,7 +1065,7 @@ static int cprh_msmcobalt_kbss_calculate_target_quotients( else quot_low[i] = quot_high[i] - fuse->quot_offset[i] - * MSMCOBALT_KBSS_QUOT_OFFSET_SCALE; + * MSM8998_KBSS_QUOT_OFFSET_SCALE; if (quot_high[i] < quot_low[i]) { cpr3_debug(vreg, "quot_high[%d]=%llu < quot_low[%d]=%llu; overriding: quot_high[%d]=%llu\n", i, quot_high[i], i, quot_low[i], @@ -1163,10 +1203,10 @@ static int cprh_kbss_init_thread(struct cpr3_thread *thread) */ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) { - struct cprh_msmcobalt_kbss_fuses *fuse; + struct cprh_msm8998_kbss_fuses *fuse; int rc; - rc = cprh_msmcobalt_kbss_read_fuse_data(vreg); + rc = cprh_msm8998_kbss_read_fuse_data(vreg); if (rc) { cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc); return rc; @@ -1181,7 +1221,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cprh_msmcobalt_kbss_calculate_open_loop_voltages(vreg); + rc = cprh_msm8998_kbss_calculate_open_loop_voltages(vreg); if (rc) { cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n", rc); @@ -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); @@ -1205,7 +1246,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cprh_msmcobalt_kbss_calculate_target_quotients(vreg); + rc = cprh_msm8998_kbss_calculate_target_quotients(vreg); if (rc) { cpr3_err(vreg, "unable to calculate target quotients, rc=%d\n", rc); @@ -1228,13 +1269,13 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) if (vreg->allow_core_count_adj && (vreg->max_core_count <= 0 || vreg->max_core_count > - MSMCOBALT_KBSS_CPR_SDELTA_CORE_COUNT)) { + MSM8998_KBSS_CPR_SDELTA_CORE_COUNT)) { cpr3_err(vreg, "qcom,max-core-count has invalid value = %d\n", vreg->max_core_count); return -EINVAL; } - rc = cprh_msmcobalt_partial_binning_override(vreg); + rc = cprh_msm8998_partial_binning_override(vreg); if (rc) { cpr3_err(vreg, "unable to override CPR parameters based on partial binning fuse values, rc=%d\n", rc); @@ -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; @@ -1262,7 +1310,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) */ static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) { - struct cprh_msmcobalt_kbss_fuses *fuse = NULL; + struct cprh_msm8998_kbss_fuses *fuse = NULL; struct cpr3_regulator *vreg; u32 aging_ro_scale; int i, j, rc; @@ -1300,24 +1348,24 @@ static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) if (!ctrl->aging_sensor) return -ENOMEM; - if (ctrl->ctrl_id == MSMCOBALT_KBSS_POWER_CLUSTER_ID) { + if (ctrl->ctrl_id == MSM8998_KBSS_POWER_CLUSTER_ID) { ctrl->aging_sensor->sensor_id - = MSMCOBALT_KBSS_POWER_AGING_SENSOR_ID; + = MSM8998_KBSS_POWER_AGING_SENSOR_ID; ctrl->aging_sensor->bypass_mask[0] - = MSMCOBALT_KBSS_POWER_AGING_BYPASS_MASK0; + = MSM8998_KBSS_POWER_AGING_BYPASS_MASK0; } else { ctrl->aging_sensor->sensor_id - = MSMCOBALT_KBSS_PERFORMANCE_AGING_SENSOR_ID; + = MSM8998_KBSS_PERFORMANCE_AGING_SENSOR_ID; ctrl->aging_sensor->bypass_mask[0] - = MSMCOBALT_KBSS_PERFORMANCE_AGING_BYPASS_MASK0; + = MSM8998_KBSS_PERFORMANCE_AGING_BYPASS_MASK0; } ctrl->aging_sensor->ro_scale = aging_ro_scale; ctrl->aging_sensor->init_quot_diff = cpr3_convert_open_loop_voltage_fuse(0, - MSMCOBALT_KBSS_AGING_INIT_QUOT_DIFF_SCALE, + MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SCALE, fuse->aging_init_quot_diff, - MSMCOBALT_KBSS_AGING_INIT_QUOT_DIFF_SIZE); + MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SIZE); cpr3_debug(ctrl, "sensor %u aging init quotient diff = %d, aging RO scale = %u QUOT/V\n", ctrl->aging_sensor->sensor_id, @@ -1355,8 +1403,8 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) return rc; } - if (ctrl->ctrl_id < MSMCOBALT_KBSS_MIN_CONTROLLER_ID || - ctrl->ctrl_id > MSMCOBALT_KBSS_MAX_CONTROLLER_ID) { + if (ctrl->ctrl_id < MSM8998_KBSS_MIN_CONTROLLER_ID || + ctrl->ctrl_id > MSM8998_KBSS_MAX_CONTROLLER_ID) { cpr3_err(ctrl, "invalid qcom,cpr-controller-id specified\n"); return -EINVAL; } @@ -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 @@ -1436,9 +1503,9 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) "qcom,cpr-corner-switch-delay-time", &ctrl->corner_switch_delay_time); - ctrl->sensor_count = ctrl->ctrl_id == MSMCOBALT_KBSS_POWER_CLUSTER_ID ? - MSMCOBALT_KBSS_POWER_CPR_SENSOR_COUNT : - MSMCOBALT_KBSS_PERFORMANCE_CPR_SENSOR_COUNT; + ctrl->sensor_count = ctrl->ctrl_id == MSM8998_KBSS_POWER_CLUSTER_ID ? + MSM8998_KBSS_POWER_CPR_SENSOR_COUNT : + MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT; /* * KBSS only has one thread (0) per controller so the zeroed @@ -1449,7 +1516,7 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) if (!ctrl->sensor_owner) return -ENOMEM; - ctrl->cpr_clock_rate = MSMCOBALT_KBSS_CPR_CLOCK_RATE; + ctrl->cpr_clock_rate = MSM8998_KBSS_CPR_CLOCK_RATE; ctrl->supports_hw_closed_loop = true; ctrl->use_hw_closed_loop = of_property_read_bool(ctrl->dev->of_node, "qcom,cpr-hw-closed-loop"); @@ -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", @@ -1504,15 +1579,15 @@ static int cprh_kbss_regulator_resume(struct platform_device *pdev) /* Data corresponds to the SoC revision */ static struct of_device_id cprh_regulator_match_table[] = { { - .compatible = "qcom,cprh-msmcobalt-v1-kbss-regulator", + .compatible = "qcom,cprh-msm8998-v1-kbss-regulator", .data = (void *)(uintptr_t)1 }, { - .compatible = "qcom,cprh-msmcobalt-v2-kbss-regulator", + .compatible = "qcom,cprh-msm8998-v2-kbss-regulator", .data = (void *)(uintptr_t)2 }, { - .compatible = "qcom,cprh-msmcobalt-kbss-regulator", + .compatible = "qcom,cprh-msm8998-kbss-regulator", .data = (void *)(uintptr_t)2 }, {} diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c index 3d0be1f8a5b5..15ade85f446b 100644 --- a/drivers/regulator/qpnp-labibb-regulator.c +++ b/drivers/regulator/qpnp-labibb-regulator.c @@ -714,10 +714,10 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb, u32 tmp; /* - * Do not configure LCD_AMOLED_SEL for pmicobalt as it will be done by + * Do not configure LCD_AMOLED_SEL for pmi8998 as it will be done by * GPIO selector. */ - if (labibb->pmic_rev_id->pmic_subtype != PMICOBALT_SUBTYPE) { + if (labibb->pmic_rev_id->pmic_subtype != PMI8998_SUBTYPE) { if (labibb->mode == QPNP_LABIBB_LCD_MODE) val = REG_LAB_IBB_LCD_MODE; else @@ -1529,7 +1529,7 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb) return -EINVAL; } - if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE && + if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE && labibb->mode == QPNP_LABIBB_LCD_MODE) { rc = qpnp_lab_pfm_disable(labibb); if (rc < 0) { @@ -1752,7 +1752,7 @@ static irqreturn_t lab_vreg_ok_handler(int irq, void *_labibb) if (rc < 0) pr_err("Failed in 'qpnp_skip_swire_command' rc=%d\n", rc); - } else if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE && + } else if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE && labibb->mode == QPNP_LABIBB_LCD_MODE) { rc = qpnp_lab_pfm_enable(labibb); if (rc < 0) @@ -1776,13 +1776,13 @@ static bool is_lab_vreg_ok_irq_available(struct qpnp_labibb *labibb) { /* * LAB VREG_OK interrupt is used only to skip 2nd SWIRE command in - * dig_major < 2 targets. For pmicobalt, it is used to enable PFM in + * dig_major < 2 targets. For pmi8998, it is used to enable PFM in * LCD mode. */ if (labibb->skip_2nd_swire_cmd && labibb->lab_dig_major < 2) return true; - if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE && + if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE && labibb->mode == QPNP_LABIBB_LCD_MODE) return true; @@ -2092,11 +2092,11 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb, u8 val; /* - * Do not configure LCD_AMOLED_SEL for pmicobalt as it will be done by + * Do not configure LCD_AMOLED_SEL for pmi8998 as it will be done by * GPIO selector. Override the labibb->mode with what was configured * by the bootloader. */ - if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE) { + if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) { rc = qpnp_labibb_read(labibb, &val, labibb->ibb_base + REG_IBB_LCD_AMOLED_SEL, 1); if (rc) { @@ -2627,10 +2627,10 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb, } /* - * For pmicobalt, override swire_control with what was configured + * For pmi8998, override swire_control with what was configured * before by the bootloader. */ - if (labibb->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE) + if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) labibb->swire_control = val & IBB_ENABLE_CTL_SWIRE_RDY; if (ibb_enable_ctl & diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 873b4615d4a9..1e200370deea 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -412,8 +412,9 @@ static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba, /** * Returns zero for success and non-zero in case of a failure */ -static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, - u32 hs, u32 rate, bool update_link_startup_timer) +static int __ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, + u32 hs, u32 rate, bool update_link_startup_timer, + bool is_pre_scale_up) { int ret = 0; struct ufs_qcom_host *host = ufshcd_get_variant(hba); @@ -460,8 +461,12 @@ static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, } list_for_each_entry(clki, &hba->clk_list_head, list) { - if (!strcmp(clki->name, "core_clk")) - core_clk_rate = clk_get_rate(clki->clk); + if (!strcmp(clki->name, "core_clk")) { + if (is_pre_scale_up) + core_clk_rate = clki->max_freq; + else + core_clk_rate = clk_get_rate(clki->clk); + } } /* If frequency is smaller than 1MHz, set to 1MHz */ @@ -558,6 +563,13 @@ out: return ret; } +static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear, + u32 hs, u32 rate, bool update_link_startup_timer) +{ + return __ufs_qcom_cfg_timers(hba, gear, hs, rate, + update_link_startup_timer, false); +} + static int ufs_qcom_link_startup_pre_change(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); @@ -779,8 +791,12 @@ static int ufs_qcom_full_reset(struct ufs_hba *hba) goto out; } - /* Very small delay, per the documented requirement */ - usleep_range(1, 2); + /* + * The hardware requirement for delay between assert/deassert + * is at least 3-4 sleep clock (32.7KHz) cycles, which comes to + * ~125us (4/32768). To be on the safe side add 200us delay. + */ + usleep_range(200, 210); ret = reset_control_deassert(hba->core_reset); if (ret) @@ -2160,61 +2176,49 @@ out: static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); + struct ufs_pa_layer_attr *attr = &host->dev_req_params; + int err = 0; if (!ufs_qcom_cap_qunipro(host)) - return 0; - - return ufs_qcom_configure_lpm(hba, false); -} + goto out; -static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba) -{ - struct ufs_qcom_host *host = ufshcd_get_variant(hba); + err = ufs_qcom_configure_lpm(hba, false); + if (err) + goto out; - if (!ufs_qcom_cap_qunipro(host)) - return 0; + if (attr) + __ufs_qcom_cfg_timers(hba, attr->gear_rx, attr->pwr_rx, + attr->hs_rate, false, true); /* set unipro core clock cycles to 150 and clear clock divider */ - return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150); + err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150); +out: + return err; } static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); - u32 core_clk_ctrl_reg; - int err = 0; if (!ufs_qcom_cap_qunipro(host)) - goto out; - - err = ufs_qcom_configure_lpm(hba, true); - if (err) - goto out; - - err = ufshcd_dme_get(hba, - UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL), - &core_clk_ctrl_reg); + return 0; - /* make sure CORE_CLK_DIV_EN is cleared */ - if (!err && - (core_clk_ctrl_reg & DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT)) { - core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT; - err = ufshcd_dme_set(hba, - UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL), - core_clk_ctrl_reg); - } -out: - return err; + return ufs_qcom_configure_lpm(hba, true); } static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); + struct ufs_pa_layer_attr *attr = &host->dev_req_params; int err = 0; if (!ufs_qcom_cap_qunipro(host)) return 0; + if (attr) + ufs_qcom_cfg_timers(hba, attr->gear_rx, attr->pwr_rx, + attr->hs_rate, false); + if (ufs_qcom_cap_svs2(host)) /* * For SVS2 set unipro core clock cycles to 37 and @@ -2235,7 +2239,6 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, bool scale_up, enum ufs_notify_change_status status) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); - struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params; int err = 0; switch (status) { @@ -2246,19 +2249,9 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, err = ufs_qcom_clk_scale_down_pre_change(hba); break; case POST_CHANGE: - if (scale_up) - err = ufs_qcom_clk_scale_up_post_change(hba); - else + if (!scale_up) err = ufs_qcom_clk_scale_down_post_change(hba); - if (err || !dev_req_params) - goto out; - - ufs_qcom_cfg_timers(hba, - dev_req_params->gear_rx, - dev_req_params->pwr_rx, - dev_req_params->hs_rate, - false); ufs_qcom_update_bus_bw_vote(host); break; default: @@ -2267,7 +2260,6 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, break; } -out: return err; } 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 862d56e78086..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) { @@ -2633,6 +2690,65 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id) } /** + * ufshcd_get_write_lock - synchronize between shutdown, scaling & + * arrival of requests + * @hba: ufs host + * + * Lock is predominantly held by shutdown context thus, ensuring + * that no requests from any other context may sneak through. + */ +static void ufshcd_get_write_lock(struct ufs_hba *hba) +{ + down_write(&hba->lock); + hba->issuing_task = current; +} + +/** + * ufshcd_get_read_lock - synchronize between shutdown, scaling & + * arrival of requests + * @hba: ufs host + * + * Returns 1 if acquired, < 0 on contention + * + * After shutdown's initiated, allow requests only from shutdown + * context. The sync between scaling & issue is maintained + * as is and this restructuring syncs shutdown with these too. + */ +static int ufshcd_get_read_lock(struct ufs_hba *hba) +{ + int err = 0; + + err = down_read_trylock(&hba->lock); + if (err > 0) + goto out; + if (hba->issuing_task == current) + return 0; + else if (!ufshcd_is_shutdown_ongoing(hba)) + return -EAGAIN; + else + return -EPERM; + +out: + hba->issuing_task = current; + return err; +} + +/** + * ufshcd_put_read_lock - synchronize between shutdown, scaling & + * arrival of requests + * @hba: ufs host + * + * Returns none + */ +static inline void ufshcd_put_read_lock(struct ufs_hba *hba) +{ + if (!ufshcd_is_shutdown_ongoing(hba)) { + hba->issuing_task = NULL; + up_read(&hba->lock); + } +} + +/** * ufshcd_queuecommand - main entry point for SCSI requests * @cmd: command from SCSI Midlayer * @done: call back function @@ -2657,8 +2773,16 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) BUG(); } - if (!down_read_trylock(&hba->clk_scaling_lock)) - return SCSI_MLQUEUE_HOST_BUSY; + err = ufshcd_get_read_lock(hba); + if (unlikely(err < 0)) { + if (err == -EPERM) { + set_host_byte(cmd, DID_ERROR); + cmd->scsi_done(cmd); + return 0; + } + if (err == -EAGAIN) + return SCSI_MLQUEUE_HOST_BUSY; + } spin_lock_irqsave(hba->host->host_lock, flags); @@ -2798,7 +2922,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) out_unlock: spin_unlock_irqrestore(hba->host->host_lock, flags); out: - up_read(&hba->clk_scaling_lock); + ufshcd_put_read_lock(hba); return err; } @@ -2990,7 +3114,12 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, struct completion wait; unsigned long flags; - down_read(&hba->clk_scaling_lock); + /* + * May get invoked from shutdown and IOCTL contexts. + * In shutdown context, it comes in with lock acquired. + */ + if (!ufshcd_is_shutdown_ongoing(hba)) + down_read(&hba->lock); /* * Get free slot, sleep if slots are unavailable. @@ -3023,7 +3152,8 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, out_put_tag: ufshcd_put_dev_cmd_tag(hba, tag); wake_up(&hba->dev_cmd.tag_wq); - up_read(&hba->clk_scaling_lock); + if (!ufshcd_is_shutdown_ongoing(hba)) + up_read(&hba->lock); return err; } @@ -4132,7 +4262,13 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba) trace_ufshcd_profile_hibern8(dev_name(hba->dev), "enter", ktime_to_us(ktime_sub(ktime_get(), start)), ret); - if (ret) { + /* + * Do full reinit if enter failed or if LINERESET was detected during + * Hibern8 operation. After LINERESET, link moves to default PWM-G1 + * mode hence full reinit is required to move link to HS speeds. + */ + if (ret || hba->full_init_linereset) { + hba->full_init_linereset = false; ufshcd_update_error_stats(hba, UFS_ERR_HIBERN8_ENTER); dev_err(hba->dev, "%s: hibern8 enter failed. ret = %d", __func__, ret); @@ -4175,8 +4311,13 @@ int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) ret = ufshcd_uic_pwr_ctrl(hba, &uic_cmd); trace_ufshcd_profile_hibern8(dev_name(hba->dev), "exit", ktime_to_us(ktime_sub(ktime_get(), start)), ret); - - if (ret) { + /* + * Do full reinit if exit failed or if LINERESET was detected during + * Hibern8 operation. After LINERESET, link moves to default PWM-G1 + * mode hence full reinit is required to move link to HS speeds. + */ + if (ret || hba->full_init_linereset) { + hba->full_init_linereset = false; ufshcd_update_error_stats(hba, UFS_ERR_HIBERN8_EXIT); dev_err(hba->dev, "%s: hibern8 exit failed. ret = %d", __func__, ret); @@ -5696,10 +5837,13 @@ static void ufshcd_err_handler(struct work_struct *work) dev_err(hba->dev, "%s: saved_err 0x%x saved_uic_err 0x%x", __func__, hba->saved_err, hba->saved_uic_err); if (!hba->silence_err_logs) { + /* release lock as print host regs sleeps */ + spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_print_host_regs(hba); ufshcd_print_host_state(hba); ufshcd_print_pwr_info(hba); ufshcd_print_tmrs(hba, hba->outstanding_tasks); + spin_lock_irqsave(hba->host->host_lock, flags); } } @@ -5827,9 +5971,8 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) /* PHY layer lane error */ reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); - /* Ignore LINERESET indication, as this is not an error */ if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) && - (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) { + (reg & UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK)) { /* * To know whether this error is fatal or not, DB timeout * must be checked but this error is handled separately. @@ -5837,6 +5980,20 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) dev_dbg(hba->dev, "%s: UIC Lane error reported, reg 0x%x\n", __func__, reg); ufshcd_update_uic_reg_hist(&hba->ufs_stats.pa_err, reg); + + /* Don't ignore LINERESET indication during hibern8 operation */ + if (reg & UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR) { + struct uic_command *cmd = hba->active_uic_cmd; + + if (cmd) { + if ((cmd->command == UIC_CMD_DME_HIBER_ENTER) + || (cmd->command == UIC_CMD_DME_HIBER_EXIT)) { + dev_err(hba->dev, "%s: LINERESET during hibern8, reg 0x%x\n", + __func__, reg); + hba->full_init_linereset = true; + } + } + } } /* PA_INIT_ERROR is fatal and needs UIC reset */ @@ -6420,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); @@ -6908,11 +7070,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) if (ret) goto out; - /* Enable auto hibern8 if supported */ - if (ufshcd_is_auto_hibern8_supported(hba)) - ufshcd_set_auto_hibern8_timer(hba, - hba->hibern8_on_idle.delay_ms); - /* Debug counters initialization */ ufshcd_clear_dbg_ufs_stats(hba); /* set the default level for urgent bkops */ @@ -6979,6 +7136,13 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) if (ufshcd_scsi_add_wlus(hba)) goto out; + /* Enable auto hibern8 if supported, after full host and + * device initialization. + */ + if (ufshcd_is_auto_hibern8_supported(hba)) + ufshcd_set_auto_hibern8_timer(hba, + hba->hibern8_on_idle.delay_ms); + /* Initialize devfreq after UFS device is detected */ if (ufshcd_is_clkscaling_supported(hba)) { memcpy(&hba->clk_scaling.saved_pwr_info.info, @@ -8118,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); @@ -8232,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; @@ -8329,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; @@ -8654,11 +8800,37 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) */ int ufshcd_shutdown(struct ufs_hba *hba) { - /* - * TODO: This function should send the power down notification to - * UFS device and then power off the UFS link. But we need to be sure - * that there will not be any new UFS requests issued after this. + int ret = 0; + + if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) + goto out; + + pm_runtime_get_sync(hba->dev); + ufshcd_hold_all(hba); + /** + * (1) Acquire the lock to stop any more requests + * (2) Set state to shutting down + * (3) Suspend clock scaling + * (4) Wait for all issued requests to complete */ + ufshcd_get_write_lock(hba); + ufshcd_mark_shutdown_ongoing(hba); + ufshcd_scsi_block_requests(hba); + ufshcd_suspend_clkscaling(hba); + ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX); + if (ret) + dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n", + __func__, ret); + /* Requests may have errored out above, let it be handled */ + flush_work(&hba->eh_work); + /* reqs issued from contexts other than shutdown will fail from now */ + ufshcd_scsi_unblock_requests(hba); + ufshcd_release_all(hba); + ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); +out: + if (ret) + dev_err(hba->dev, "%s failed, err %d\n", __func__, ret); + /* allow force shutdown even in case of errors */ return 0; } EXPORT_SYMBOL(ufshcd_shutdown); @@ -8843,10 +9015,10 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba) * clock scaling is in progress */ ufshcd_scsi_block_requests(hba); - down_write(&hba->clk_scaling_lock); + down_write(&hba->lock); if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) { ret = -EBUSY; - up_write(&hba->clk_scaling_lock); + up_write(&hba->lock); ufshcd_scsi_unblock_requests(hba); } @@ -8855,7 +9027,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba) static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba) { - up_write(&hba->clk_scaling_lock); + up_write(&hba->lock); ufshcd_scsi_unblock_requests(hba); } @@ -9038,6 +9210,10 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work) clk_scaling.resume_work); unsigned long irq_flags; + /* Let's not resume scaling if shutdown is ongoing */ + if (ufshcd_is_shutdown_ongoing(hba)) + return; + spin_lock_irqsave(hba->host->host_lock, irq_flags); if (!hba->clk_scaling.is_suspended) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -9250,7 +9426,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Initialize mutex for device management commands */ mutex_init(&hba->dev_cmd.lock); - init_rwsem(&hba->clk_scaling_lock); + init_rwsem(&hba->lock); /* Initialize device management tag acquire wait queue */ init_waitqueue_head(&hba->dev_cmd.tag_wq); @@ -9287,6 +9463,15 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) goto exit_gating; } + /* 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 c0714b7bea72..c5eb21d8a0fe 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -895,15 +895,31 @@ struct ufs_hba { enum bkops_status urgent_bkops_lvl; bool is_urgent_bkops_lvl_checked; - struct rw_semaphore clk_scaling_lock; + /* sync b/w diff contexts */ + struct rw_semaphore lock; + struct task_struct *issuing_task; + unsigned long shutdown_in_prog; struct reset_control *core_reset; /* If set, don't gate device ref_clk during clock gating */ bool no_ref_clk_gating; int scsi_block_reqs_cnt; + + bool full_init_linereset; + struct pinctrl *pctrl; }; +static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba) +{ + set_bit(0, &hba->shutdown_in_prog); +} + +static inline bool ufshcd_is_shutdown_ongoing(struct ufs_hba *hba) +{ + return !!(test_bit(0, &hba->shutdown_in_prog)); +} + /* Returns true if clocks can be gated. Otherwise false */ static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index d65dad03bdd2..c0e4650a75ad 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -190,6 +190,7 @@ enum { /* UECPA - Host UIC Error Code PHY Adapter Layer 38h */ #define UIC_PHY_ADAPTER_LAYER_ERROR UFS_BIT(31) +#define UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR UFS_BIT(4) #define UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK 0x1F #define UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK 0xF diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index d3f967319d21..21733633cb6c 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -628,12 +628,10 @@ config MSM_PERFORMANCE config MSM_PERFORMANCE_HOTPLUG_ON bool "Hotplug functionality through msm_performance turned on" depends on MSM_PERFORMANCE - default y help - If some other core-control driver is present turn off the core-control - capability of msm_performance driver. Setting this flag to false will - compile out the nodes needed for core-control functionality through - msm_performance. + Setting this flag to true will enable the nodes needed for core-control + functionality of hot plugging cores through msm_performance if there is + no default core-control driver available. endif # ARCH_QCOM diff --git a/drivers/soc/qcom/gladiator_erp_v2.c b/drivers/soc/qcom/gladiator_erp_v2.c index 25c7bd77ae96..91b5d39be242 100644 --- a/drivers/soc/qcom/gladiator_erp_v2.c +++ b/drivers/soc/qcom/gladiator_erp_v2.c @@ -628,9 +628,11 @@ static irqreturn_t msm_gladiator_isr(int irq, void *dev_id) msm_gld_data->gladiator_virt_base + get_gld_offset(err_log)); } - pr_alert("Main log register data:\n%08x %08x %08x %08x\n%08x %08x %08x %08x\n%08x %08x %08x\n", - err_buf[0], err_buf[1], err_buf[2], err_buf[3], err_buf[4], err_buf[5], err_buf[6], - err_buf[7], err_buf[8], err_buf[9], err_buf[10]); + pr_alert("Main log register data:\n%08x %08x %08x %08x\n" + "%08x %08x %08x %08x\n%08x %08x %08x %08x\n", + err_buf[2], err_buf[3], err_buf[4], err_buf[5], + err_buf[6], err_buf[7], err_buf[8], err_buf[9], + err_buf[10], err_buf[11], err_buf[12], err_buf[13]); } if (obsrv_err_valid) { diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index feeed645fc47..59d7f6423932 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -45,6 +45,7 @@ #include <soc/qcom/service-locator.h> #include <soc/qcom/service-notifier.h> #include <soc/qcom/socinfo.h> +#include <soc/qcom/ramdump.h> #include "wlan_firmware_service_v01.h" @@ -439,6 +440,7 @@ static struct icnss_priv { struct wlfw_rf_board_info_s_v01 board_info; struct wlfw_soc_info_s_v01 soc_info; struct wlfw_fw_version_info_s_v01 fw_version_info; + char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; u32 pwr_pin_result; u32 phy_io_pin_result; u32 rf_pin_result; @@ -463,6 +465,7 @@ static struct icnss_priv { struct qpnp_vadc_chip *vadc_dev; uint64_t vph_pwr; atomic_t pm_count; + struct ramdump_device *msa0_dump_dev; } *penv; static void icnss_hw_write_reg(void *base, u32 offset, u32 val) @@ -1482,8 +1485,18 @@ static int icnss_hw_reset(struct icnss_priv *priv) icnss_hw_reset_wlan_rfactrl_power_down(priv); ret = icnss_hw_reset_rf_reset_cmd(priv); - if (ret) + if (ret) { + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_FORCE_ACTIVE, 0); + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_DISCONNECT_CLR, 0); + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_WLAN_DISABLE, 1); goto top_level_reset; + } icnss_hw_reset_switch_to_cxo(priv); @@ -1508,8 +1521,18 @@ static int icnss_hw_reset(struct icnss_priv *priv) } ret = icnss_hw_reset_xo_disable_cmd(priv); - if (ret) + if (ret) { + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_FORCE_ACTIVE, 0); + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_DISCONNECT_CLR, 0); + icnss_hw_write_reg_field(priv->mpm_config_va, + MPM_WCSSAON_CONFIG_OFFSET, + MPM_WCSSAON_CONFIG_WLAN_DISABLE, 1); goto top_level_reset; + } icnss_hw_write_reg_field(priv->mpm_config_va, MPM_WCSSAON_CONFIG_OFFSET, MPM_WCSSAON_CONFIG_FORCE_ACTIVE, 0); @@ -1971,12 +1994,16 @@ static int wlfw_cap_send_sync_msg(void) penv->soc_info = resp.soc_info; if (resp.fw_version_info_valid) penv->fw_version_info = resp.fw_version_info; + if (resp.fw_build_id_valid) + strlcpy(penv->fw_build_id, resp.fw_build_id, + QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1); - icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s", + icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s", penv->chip_info.chip_id, penv->chip_info.chip_family, penv->board_info.board_id, penv->soc_info.soc_id, penv->fw_version_info.fw_version, - penv->fw_version_info.fw_build_timestamp); + penv->fw_version_info.fw_build_timestamp, + penv->fw_build_id); return 0; @@ -2657,8 +2684,6 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv, out: ret = icnss_hw_power_off(priv); - icnss_remove_msa_permissions(priv); - kfree(data); return ret; @@ -2763,6 +2788,16 @@ static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this, return ret; } +static int icnss_msa0_ramdump(struct icnss_priv *priv) +{ + struct ramdump_segment segment; + + memset(&segment, 0, sizeof(segment)); + segment.v_address = priv->msa_va; + segment.size = priv->msa_mem_size; + return do_ramdump(priv->msa0_dump_dev, &segment, 1); +} + static struct notifier_block wlfw_clnt_nb = { .notifier_call = icnss_qmi_wlfw_clnt_svc_event_notify, }; @@ -2778,9 +2813,19 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, icnss_pr_dbg("Modem-Notify: event %lu\n", code); + if (code == SUBSYS_AFTER_SHUTDOWN) { + icnss_remove_msa_permissions(priv); + icnss_pr_info("Collecting msa0 segment dump\n"); + icnss_msa0_ramdump(priv); + return NOTIFY_OK; + } + if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; + if (test_bit(ICNSS_PDR_ENABLED, &priv->state)) + return NOTIFY_OK; + icnss_pr_info("Modem went down, state: %lx\n", priv->state); event_data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -2936,8 +2981,6 @@ static int icnss_get_service_location_notify(struct notifier_block *nb, set_bit(ICNSS_PDR_ENABLED, &priv->state); - icnss_modem_ssr_unregister_notifier(priv); - icnss_pr_dbg("PD restart enabled, state: 0x%lx\n", priv->state); return NOTIFY_OK; @@ -3000,6 +3043,11 @@ static int icnss_enable_recovery(struct icnss_priv *priv) goto enable_pdr; } + priv->msa0_dump_dev = create_ramdump_device("wcss_msa0", + &priv->pdev->dev); + if (!priv->msa0_dump_dev) + return -ENOMEM; + icnss_modem_ssr_register_notifier(priv); if (test_bit(SSR_ONLY, &quirks)) { icnss_pr_dbg("PDR disabled through module parameter\n"); @@ -3929,6 +3977,8 @@ static int icnss_stats_show_capability(struct seq_file *s, priv->fw_version_info.fw_version); seq_printf(s, "Firmware Build Timestamp: %s\n", priv->fw_version_info.fw_build_timestamp); + seq_printf(s, "Firmware Build ID: %s\n", + priv->fw_build_id); } return 0; @@ -4511,6 +4561,8 @@ static int icnss_remove(struct platform_device *pdev) icnss_modem_ssr_unregister_notifier(penv); + destroy_ramdump_device(penv->msa0_dump_dev); + icnss_pdr_unregister_notifier(penv); qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01, @@ -4522,6 +4574,8 @@ static int icnss_remove(struct platform_device *pdev) icnss_hw_power_off(penv); + icnss_remove_msa_permissions(penv); + dev_set_drvdata(&pdev->dev, NULL); return 0; diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c index deb7231a4ed1..10fb4cc8ebff 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c @@ -869,7 +869,7 @@ static void unregister_client_adhoc(uint32_t cl) } curr = client->curr; - if (curr >= pdata->num_usecases) { + if ((curr < 0) || (curr >= pdata->num_usecases)) { MSM_BUS_ERR("Invalid index Defaulting curr to 0"); curr = 0; } diff --git a/drivers/soc/qcom/msm_smem.c b/drivers/soc/qcom/msm_smem.c index cd3d387645fd..8f5ad7af8d0d 100644 --- a/drivers/soc/qcom/msm_smem.c +++ b/drivers/soc/qcom/msm_smem.c @@ -84,6 +84,7 @@ static int smem_module_inited; static RAW_NOTIFIER_HEAD(smem_module_init_notifier_list); static DEFINE_MUTEX(smem_module_init_notifier_lock); static bool probe_done; +uint32_t smem_max_items; /* smem security feature components */ #define SMEM_TOC_IDENTIFIER 0x434f5424 /* "$TOC" */ @@ -139,6 +140,11 @@ struct smem_partition_info { }; static struct smem_partition_info partitions[NUM_SMEM_SUBSYSTEMS]; + +#define SMEM_COMM_PART_VERSION 0x000C +#define SMEM_COMM_HOST 0xFFFE +static bool use_comm_partition; +static struct smem_partition_info comm_partition; /* end smem security feature components */ /* Identifier for the SMEM target info struct. */ @@ -149,6 +155,7 @@ struct smem_targ_info_type { uint32_t identifier; uint32_t size; phys_addr_t phys_base_addr; + uint32_t max_items; }; struct restart_notifier_block { @@ -312,7 +319,7 @@ static void *__smem_get_entry_nonsecure(unsigned id, unsigned *size, if (!skip_init_check && !smem_initialized_check()) return ret; - if (id >= SMEM_NUM_ITEMS) + if (id >= smem_max_items) return ret; if (use_spinlocks) { @@ -374,7 +381,7 @@ static void *__smem_get_entry_secure(unsigned id, if (!skip_init_check && !smem_initialized_check()) return NULL; - if (id >= SMEM_NUM_ITEMS) { + if (id >= smem_max_items) { SMEM_INFO("%s: invalid id %d\n", __func__, id); return NULL; } @@ -385,12 +392,18 @@ static void *__smem_get_entry_secure(unsigned id, return NULL; } - if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset) - return __smem_get_entry_nonsecure(id, size, skip_init_check, - use_rspinlock); - - partition_num = partitions[to_proc].partition_num; - hdr = smem_areas[0].virt_addr + partitions[to_proc].offset; + if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset) { + if (use_comm_partition) { + partition_num = comm_partition.partition_num; + hdr = smem_areas[0].virt_addr + comm_partition.offset; + } else { + return __smem_get_entry_nonsecure(id, size, + skip_init_check, use_rspinlock); + } + } else { + partition_num = partitions[to_proc].partition_num; + hdr = smem_areas[0].virt_addr + partitions[to_proc].offset; + } if (unlikely(!spinlocks_initialized)) { rc = init_smem_remote_spinlock(); if (unlikely(rc)) { @@ -613,8 +626,19 @@ static void *alloc_item_secure(unsigned id, unsigned size_in, unsigned to_proc, uint32_t partition_num; void *ret = NULL; - hdr = smem_base + partitions[to_proc].offset; - partition_num = partitions[to_proc].partition_num; + if (to_proc == SMEM_COMM_HOST) { + hdr = smem_base + comm_partition.offset; + partition_num = comm_partition.partition_num; + size_cacheline = comm_partition.size_cacheline; + } else if (to_proc < NUM_SMEM_SUBSYSTEMS) { + hdr = smem_base + partitions[to_proc].offset; + partition_num = partitions[to_proc].partition_num; + size_cacheline = partitions[to_proc].size_cacheline; + } else { + SMEM_INFO("%s: invalid to_proc %u for id %u\n", __func__, + to_proc, id); + return NULL; + } if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) { LOG_ERR( @@ -626,7 +650,6 @@ static void *alloc_item_secure(unsigned id, unsigned size_in, unsigned to_proc, BUG(); } - size_cacheline = partitions[to_proc].size_cacheline; free_space = hdr->offset_free_cached - hdr->offset_free_uncached; @@ -718,7 +741,7 @@ void *smem_alloc(unsigned id, unsigned size_in, unsigned to_proc, if (!smem_initialized_check()) return NULL; - if (id >= SMEM_NUM_ITEMS) { + if (id >= smem_max_items) { SMEM_INFO("%s: invalid id %u\n", __func__, id); return NULL; } @@ -761,11 +784,16 @@ void *smem_alloc(unsigned id, unsigned size_in, unsigned to_proc, if (id > SMEM_FIXED_ITEM_LAST) { SMEM_INFO("%s: allocating %u size %u to_proc %u flags %u\n", __func__, id, size_in, to_proc, flags); - if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset) - ret = alloc_item_nonsecure(id, a_size_in); - else + if (flags & SMEM_ANY_HOST_FLAG + || !partitions[to_proc].offset) { + if (use_comm_partition) + ret = alloc_item_secure(id, size_in, + SMEM_COMM_HOST, flags); + else + ret = alloc_item_nonsecure(id, a_size_in); + } else { ret = alloc_item_secure(id, size_in, to_proc, flags); - + } } else { SMEM_INFO("%s: attempted to allocate non-dynamic item %u\n", __func__, id); @@ -893,14 +921,18 @@ EXPORT_SYMBOL(smem_get_free_space); unsigned smem_get_version(unsigned idx) { int *version_array; + struct smem_shared *smem = smem_ram_base; if (idx > 32) { pr_err("%s: invalid idx:%d\n", __func__, idx); return 0; } - version_array = __smem_find(SMEM_VERSION_INFO, SMEM_VERSION_INFO_SIZE, - true); + if (use_comm_partition) + version_array = smem->version; + else + version_array = __smem_find(SMEM_VERSION_INFO, + SMEM_VERSION_INFO_SIZE, true); if (version_array == NULL) return 0; @@ -948,6 +980,7 @@ bool smem_initialized_check(void) static int is_inited; unsigned long flags; struct smem_shared *smem; + unsigned ver; if (likely(checked)) { if (unlikely(!is_inited)) @@ -976,8 +1009,12 @@ bool smem_initialized_check(void) * structures. Without the extra configuration data, the SMEM driver * cannot be properly initialized. */ - if (smem_get_version(MODEM_SBL_VERSION_INDEX) != SMEM_VERSION << 16) { - pr_err("%s: SBL version not correct\n", __func__); + ver = smem->version[MODEM_SBL_VERSION_INDEX]; + if (ver == SMEM_COMM_PART_VERSION << 16) { + use_comm_partition = true; + } else if (ver != SMEM_VERSION << 16) { + pr_err("%s: SBL version not correct 0x%x\n", + __func__, smem->version[7]); goto failed; } @@ -1122,6 +1159,7 @@ static void smem_init_security_partition(struct smem_toc_entry *entry, { uint16_t remote_host; struct smem_partition_header *hdr; + bool is_comm_partition = false; if (!entry->offset) { SMEM_INFO("Skipping smem partition %d - bad offset\n", num); @@ -1136,31 +1174,38 @@ static void smem_init_security_partition(struct smem_toc_entry *entry, return; } - if (entry->host0 == SMEM_APPS) - remote_host = entry->host1; - else - remote_host = entry->host0; + if (entry->host0 == SMEM_COMM_HOST && entry->host1 == SMEM_COMM_HOST) + is_comm_partition = true; - if (remote_host >= NUM_SMEM_SUBSYSTEMS) { - SMEM_INFO("Skipping smem partition %d - bad remote:%d\n", num, - remote_host); - return; - } - if (partitions[remote_host].offset) { - SMEM_INFO("Skipping smem partition %d - duplicate of %d\n", num, - partitions[remote_host].partition_num); - return; - } + if (!is_comm_partition) { + if (entry->host0 == SMEM_APPS) + remote_host = entry->host1; + else + remote_host = entry->host0; - hdr = smem_areas[0].virt_addr + entry->offset; + if (remote_host >= NUM_SMEM_SUBSYSTEMS) { + SMEM_INFO( + "Skipping smem partition %d - bad remote:%d\n", + num, remote_host); + return; + } + if (partitions[remote_host].offset) { + SMEM_INFO( + "Skipping smem partition %d - duplicate of %d\n", + num, partitions[remote_host].partition_num); + return; + } - if (entry->host0 != SMEM_APPS && entry->host1 != SMEM_APPS) { - SMEM_INFO( - "Non-APSS Partition %d offset:%x host0:%d host1:%d\n", - num, entry->offset, entry->host0, entry->host1); - return; + if (entry->host0 != SMEM_APPS && entry->host1 != SMEM_APPS) { + SMEM_INFO( + "Non-APSS Partition %d offset:%x host0:%d host1:%d\n", + num, entry->offset, entry->host0, entry->host1); + return; + } } + hdr = smem_areas[0].virt_addr + entry->offset; + if (hdr->identifier != SMEM_PART_HDR_IDENTIFIER) { LOG_ERR("Smem partition %d hdr magic is bad\n", num); BUG(); @@ -1177,6 +1222,14 @@ static void smem_init_security_partition(struct smem_toc_entry *entry, LOG_ERR("Smem partition %d cached heap exceeds size\n", num); BUG(); } + if (hdr->host0 == SMEM_COMM_HOST && hdr->host1 == SMEM_COMM_HOST) { + comm_partition.partition_num = num; + comm_partition.offset = entry->offset; + comm_partition.size_cacheline = entry->size_cacheline; + SMEM_INFO("Common Partition %d offset:%x\n", num, + entry->offset); + return; + } if (hdr->host0 != SMEM_APPS && hdr->host1 != SMEM_APPS) { LOG_ERR("Smem partition %d hosts don't match TOC\n", num); BUG(); @@ -1253,6 +1306,8 @@ static int smem_init_target_info(phys_addr_t info_addr, resource_size_t size) } smem_ram_phys = smem_targ_info->phys_base_addr; smem_ram_size = smem_targ_info->size; + if (smem_targ_info->max_items) + smem_max_items = smem_targ_info->max_items; iounmap(smem_targ_info_addr); return 0; } @@ -1488,7 +1543,7 @@ int __init msm_smem_init(void) return 0; registered = true; - + smem_max_items = SMEM_NUM_ITEMS; smem_ipc_log_ctx = ipc_log_context_create(NUM_LOG_PAGES, "smem", 0); if (!smem_ipc_log_ctx) { pr_err("%s: unable to create logging context\n", __func__); diff --git a/drivers/soc/qcom/rpm-smd.c b/drivers/soc/qcom/rpm-smd.c index 242071f52811..20f406b9a2f7 100644 --- a/drivers/soc/qcom/rpm-smd.c +++ b/drivers/soc/qcom/rpm-smd.c @@ -83,7 +83,7 @@ static struct glink_apps_rpm_data *glink_data; #define DEFAULT_BUFFER_SIZE 256 #define DEBUG_PRINT_BUFFER_SIZE 512 #define MAX_SLEEP_BUFFER 128 -#define GFP_FLAG(noirq) (noirq ? GFP_ATOMIC : GFP_NOFS) +#define GFP_FLAG(noirq) (noirq ? GFP_ATOMIC : GFP_NOIO) #define INV_RSC "resource does not exist" #define ERR "err\0" #define MAX_ERR_BUFFER_SIZE 128 diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c index b4713ac1b68b..f2216f968319 100644 --- a/drivers/soc/qcom/scm.c +++ b/drivers/soc/qcom/scm.c @@ -665,10 +665,6 @@ int scm_call2(u32 fn_id, struct scm_desc *desc) desc->ret[0] = desc->ret[1] = desc->ret[2] = 0; - pr_debug("scm_call: func id %#llx, args: %#x, %#llx, %#llx, %#llx, %#llx\n", - x0, desc->arginfo, desc->args[0], desc->args[1], - desc->args[2], desc->x5); - trace_scm_call_start(x0, desc); if (scm_version == SCM_ARMV8_64) @@ -698,10 +694,8 @@ int scm_call2(u32 fn_id, struct scm_desc *desc) } while (ret == SCM_V2_EBUSY && (retry_count++ < SCM_EBUSY_MAX_RETRY)); if (ret < 0) - pr_err("scm_call failed: func id %#llx, arginfo: %#x, args: %#llx, %#llx, %#llx, %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n", - x0, desc->arginfo, desc->args[0], desc->args[1], - desc->args[2], desc->x5, ret, desc->ret[0], - desc->ret[1], desc->ret[2]); + pr_err("scm_call failed: func id %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n", + x0, ret, desc->ret[0], desc->ret[1], desc->ret[2]); if (arglen > N_REGISTER_ARGS) kfree(desc->extra_arg_buf); diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c index afe6b2309e27..95d50fe01ee1 100644 --- a/drivers/soc/qcom/secure_buffer.c +++ b/drivers/soc/qcom/secure_buffer.c @@ -260,7 +260,7 @@ int hyp_assign_table(struct sg_table *table, int *dest_vmids, int *dest_perms, int dest_nelems) { - int ret; + int ret = 0; struct scm_desc desc = {0}; u32 *source_vm_copy; size_t source_vm_copy_size; diff --git a/drivers/soc/qcom/smem_debug.c b/drivers/soc/qcom/smem_debug.c index ace89afb614c..766a1781e6b9 100644 --- a/drivers/soc/qcom/smem_debug.c +++ b/drivers/soc/qcom/smem_debug.c @@ -1,7 +1,7 @@ /* arch/arm/mach-msm/smem_debug.c * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2013,2016 The Linux Foundation. All rights reserved. * Author: Brian Swetland <swetland@google.com> * * This software is licensed under the terms of the GNU General Public @@ -53,7 +53,7 @@ static void debug_read_mem(struct seq_file *s) heap_info->free_offset, heap_info->heap_remaining); - for (n = 0; n < SMEM_NUM_ITEMS; n++) { + for (n = 0; n < smem_max_items; n++) { if (toc[n].allocated == 0) continue; seq_printf(s, "%04d: offset %08x size %08x\n", @@ -67,9 +67,8 @@ static void debug_read_smem_version(struct seq_file *s) for (n = 0; n < 32; n++) { version = smem_get_version(n); - seq_printf(s, "entry %d: smem = %d proc_comm = %d\n", n, - version >> 16, - version & 0xffff); + seq_printf(s, "entry %d:%x smem = %d proc_comm = %d\n", + n, version, version >> 16, version & 0xffff); } } diff --git a/drivers/soc/qcom/smem_private.h b/drivers/soc/qcom/smem_private.h index 7aeca5eed8d2..ddbc29e30dfb 100644 --- a/drivers/soc/qcom/smem_private.h +++ b/drivers/soc/qcom/smem_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013,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 @@ -18,6 +18,7 @@ #define SMD_HEAP_SIZE 512 +extern uint32_t smem_max_items; struct smem_heap_info { unsigned initialized; diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index ea4f557fcd70..f93ee29123fe 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -42,8 +42,8 @@ #define SMEM_IMAGE_VERSION_NAME_SIZE 75 #define SMEM_IMAGE_VERSION_VARIANT_SIZE 20 #define SMEM_IMAGE_VERSION_VARIANT_OFFSET 75 -#define SMEM_IMAGE_VERSION_OEM_SIZE 32 -#define SMEM_IMAGE_VERSION_OEM_OFFSET 96 +#define SMEM_IMAGE_VERSION_OEM_SIZE 33 +#define SMEM_IMAGE_VERSION_OEM_OFFSET 95 #define SMEM_IMAGE_VERSION_PARTITION_APPS 10 enum { @@ -529,8 +529,8 @@ static struct msm_soc_info cpu_of_id[] = { [271] = {MSM_CPU_8929, "APQ8029"}, /* Cobalt IDs */ - [292] = {MSM_CPU_COBALT, "MSMCOBALT"}, - [319] = {MSM_CPU_COBALT, "APQCOBALT"}, + [292] = {MSM_CPU_8998, "MSM8998"}, + [319] = {MSM_CPU_8998, "APQ8998"}, /* Hamster ID */ [306] = {MSM_CPU_HAMSTER, "MSMHAMSTER"}, @@ -974,7 +974,7 @@ msm_get_image_crm_version(struct device *dev, } string_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE; string_address += SMEM_IMAGE_VERSION_OEM_OFFSET; - return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s\n", + return snprintf(buf, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.33s\n", string_address); } @@ -995,7 +995,7 @@ msm_set_image_crm_version(struct device *dev, } store_address += current_image * SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE; store_address += SMEM_IMAGE_VERSION_OEM_OFFSET; - snprintf(store_address, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.32s", buf); + snprintf(store_address, SMEM_IMAGE_VERSION_OEM_SIZE, "%-.33s", buf); return count; } @@ -1049,7 +1049,8 @@ msm_get_images(struct device *dev, image_address); pos += snprintf(buf + pos, PAGE_SIZE - pos, "\tVariant:\t%-.20s\n", image_address + SMEM_IMAGE_VERSION_VARIANT_OFFSET); - pos += snprintf(buf + pos, PAGE_SIZE - pos, "\tVersion:\t%-.32s\n\n", + pos += snprintf(buf + pos, PAGE_SIZE - pos, + "\tVersion:\t%-.33s\n", image_address + SMEM_IMAGE_VERSION_OEM_OFFSET); image_address += SMEM_IMAGE_VERSION_SINGLE_BLOCK_SIZE; @@ -1198,9 +1199,9 @@ static void * __init setup_dummy_socinfo(void) dummy_socinfo.id = 268; strlcpy(dummy_socinfo.build_id, "msm8929 - ", sizeof(dummy_socinfo.build_id)); - } else if (early_machine_is_msmcobalt()) { + } else if (early_machine_is_msm8998()) { dummy_socinfo.id = 292; - strlcpy(dummy_socinfo.build_id, "msmcobalt - ", + strlcpy(dummy_socinfo.build_id, "msm8998 - ", sizeof(dummy_socinfo.build_id)); } else if (early_machine_is_msmhamster()) { dummy_socinfo.id = 306; @@ -1214,9 +1215,9 @@ static void * __init setup_dummy_socinfo(void) dummy_socinfo.id = 318; strlcpy(dummy_socinfo.build_id, "msmtriton - ", sizeof(dummy_socinfo.build_id)); - } else if (early_machine_is_apqcobalt()) { + } else if (early_machine_is_apq8998()) { dummy_socinfo.id = 319; - strlcpy(dummy_socinfo.build_id, "apqcobalt - ", + strlcpy(dummy_socinfo.build_id, "apq8998 - ", sizeof(dummy_socinfo.build_id)); } diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.c b/drivers/soc/qcom/wlan_firmware_service_v01.c index f5f7ae8c9901..3e00d6c9d153 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.c +++ b/drivers/soc/qcom/wlan_firmware_service_v01.c @@ -766,6 +766,24 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = { .ei_array = wlfw_fw_version_info_s_v01_ei, }, { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + fw_build_id_valid), + }, + { + .data_type = QMI_STRING, + .elem_len = QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1, + .elem_size = sizeof(char), + .is_array = NO_ARRAY, + .tlv_type = 0x14, + .offset = offsetof(struct wlfw_cap_resp_msg_v01, + fw_build_id), + }, + { .data_type = QMI_EOTI, .is_array = NO_ARRAY, .is_array = QMI_COMMON_TLV_TYPE, @@ -1588,3 +1606,47 @@ struct elem_info wlfw_vbatt_resp_msg_v01_ei[] = { .is_array = QMI_COMMON_TLV_TYPE, }, }; + +struct elem_info wlfw_mac_addr_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(uint8_t), + .is_array = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, + mac_addr_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = QMI_WLFW_MAC_ADDR_SIZE_V01, + .elem_size = sizeof(uint8_t), + .is_array = STATIC_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_mac_addr_req_msg_v01, + mac_addr), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info wlfw_mac_addr_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .is_array = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct wlfw_mac_addr_resp_msg_v01, + resp), + .ei_array = get_qmi_response_type_v01_ei(), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; diff --git a/drivers/soc/qcom/wlan_firmware_service_v01.h b/drivers/soc/qcom/wlan_firmware_service_v01.h index 29bdfb23480a..47b315fce94c 100644 --- a/drivers/soc/qcom/wlan_firmware_service_v01.h +++ b/drivers/soc/qcom/wlan_firmware_service_v01.h @@ -24,6 +24,7 @@ #define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027 #define QMI_WLFW_INI_RESP_V01 0x002F #define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026 +#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033 #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 #define QMI_WLFW_MSA_READY_IND_V01 0x002B #define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031 @@ -43,6 +44,7 @@ #define QMI_WLFW_CAP_RESP_V01 0x0024 #define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030 #define QMI_WLFW_VBATT_REQ_V01 0x0032 +#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033 #define QMI_WLFW_VBATT_RESP_V01 0x0032 #define QMI_WLFW_MSA_INFO_REQ_V01 0x002D #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 @@ -57,6 +59,8 @@ #define QMI_WLFW_MAX_TIMESTAMP_LEN_V01 32 #define QMI_WLFW_MAX_STR_LEN_V01 16 #define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24 +#define QMI_WLFW_MAC_ADDR_SIZE_V01 6 +#define QMI_WLFW_MAX_BUILD_ID_LEN_V01 128 #define QMI_WLFW_MAX_NUM_SVC_V01 24 enum wlfw_driver_mode_enum_v01 { @@ -99,6 +103,7 @@ enum wlfw_pipedir_enum_v01 { #define QMI_WLFW_ALREADY_REGISTERED_V01 ((uint64_t)0x01ULL) #define QMI_WLFW_FW_READY_V01 ((uint64_t)0x02ULL) +#define QMI_WLFW_MSA_READY_V01 ((uint64_t)0x04ULL) struct wlfw_ce_tgt_pipe_cfg_s_v01 { uint32_t pipe_num; @@ -243,8 +248,10 @@ struct wlfw_cap_resp_msg_v01 { struct wlfw_soc_info_s_v01 soc_info; uint8_t fw_version_info_valid; struct wlfw_fw_version_info_s_v01 fw_version_info; + uint8_t fw_build_id_valid; + char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1]; }; -#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 72 +#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 203 extern struct elem_info wlfw_cap_resp_msg_v01_ei[]; struct wlfw_bdf_download_req_msg_v01 { @@ -428,4 +435,17 @@ struct wlfw_vbatt_resp_msg_v01 { #define WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct elem_info wlfw_vbatt_resp_msg_v01_ei[]; +struct wlfw_mac_addr_req_msg_v01 { + uint8_t mac_addr_valid; + uint8_t mac_addr[QMI_WLFW_MAC_ADDR_SIZE_V01]; +}; +#define WLFW_MAC_ADDR_REQ_MSG_V01_MAX_MSG_LEN 9 +extern struct elem_info wlfw_mac_addr_req_msg_v01_ei[]; + +struct wlfw_mac_addr_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info wlfw_mac_addr_resp_msg_v01_ei[]; + #endif diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index b2e1a4c1b170..b5905fc81147 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -274,11 +274,16 @@ static int ion_secure_cma_allocate(struct ion_heap *heap, source_vm = VMID_HLOS; dest_vm = get_secure_vmid(flags); + if (dest_vm < 0) { pr_err("%s: Failed to get secure vmid\n", __func__); return -EINVAL; } - dest_perms = PERM_READ | PERM_WRITE; + + if (dest_vm == VMID_CP_SEC_DISPLAY) + dest_perms = PERM_READ; + else + dest_perms = PERM_READ | PERM_WRITE; ret = ion_cma_allocate(heap, buffer, len, align, flags); if (ret) { diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c index df3a638510c2..7592bcb984ff 100644 --- a/drivers/thermal/msm-tsens.c +++ b/drivers/thermal/msm-tsens.c @@ -924,7 +924,7 @@ static struct of_device_id tsens_match[] = { { .compatible = "qcom,msmgold-tsens", .data = (void *)TSENS_CALIB_FUSE_MAP_MSMGOLD, }, - { .compatible = "qcom,msmcobalt-tsens", + { .compatible = "qcom,msm8998-tsens", .data = (void *)TSENS_CALIB_FUSE_MAP_NONE, }, { .compatible = "qcom,msmhamster-tsens", @@ -980,7 +980,7 @@ static int32_t get_tsens_sensor_for_client_id(struct tsens_tm_device *tmdev, } if (!strcmp(id->compatible, "qcom,msm8996-tsens") || - (!strcmp(id->compatible, "qcom,msmcobalt-tsens")) || + (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,msmhamster-tsens"))) { while (i < tmdev->tsens_num_sensor && !id_found) { if (tmdev->sensor[i].sensor_client_id == @@ -1109,7 +1109,7 @@ int tsens_get_hw_id_mapping(int thermal_sensor_num, int *sensor_client_id) } if (!strcmp(id->compatible, "qcom,msm8996-tsens") || - (!strcmp(id->compatible, "qcom,msmcobalt-tsens")) || + (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,msmhamster-tsens"))) { /* Assign client id's that is used to get the * controller and hw_sensor details @@ -5434,7 +5434,7 @@ static int get_device_tree_data(struct platform_device *pdev, (!strcmp(id->compatible, "qcom,msm8992-tsens"))) tmdev->tsens_type = TSENS_TYPE2; else if (!strcmp(id->compatible, "qcom,msm8996-tsens") || - (!strcmp(id->compatible, "qcom,msmcobalt-tsens"))) + (!strcmp(id->compatible, "qcom,msm8998-tsens"))) tmdev->tsens_type = TSENS_TYPE3; else if (!strcmp(id->compatible, "qcom,msmtitanium-tsens") || (!strcmp(id->compatible, "qcom,msmfalcon-tsens") || @@ -5459,7 +5459,7 @@ static int get_device_tree_data(struct platform_device *pdev, (!strcmp(id->compatible, "qcom,msm8952-tsens")) || (!strcmp(id->compatible, "qcom,msm8937-tsens")) || (!strcmp(id->compatible, "qcom,msmtitanium-tsens")) || - (!strcmp(id->compatible, "qcom,msmcobalt-tsens")) || + (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,msmfalcon-tsens") || (!strcmp(id->compatible, "qcom,msmtriton-tsens") || (!strcmp(id->compatible, "qcom,msmhamster-tsens"))))) @@ -5475,7 +5475,7 @@ static int get_device_tree_data(struct platform_device *pdev, } if (!strcmp(id->compatible, "qcom,msm8996-tsens") || - (!strcmp(id->compatible, "qcom,msmcobalt-tsens")) || + (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,msmhamster-tsens")) || (!strcmp(id->compatible, "qcom,msmfalcon-tsens") || (!strcmp(id->compatible, "qcom,msmtriton-tsens") || diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c index ced2f23addd4..002cafb08f37 100644 --- a/drivers/thermal/msm_thermal.c +++ b/drivers/thermal/msm_thermal.c @@ -60,6 +60,7 @@ #define MSM_LIMITS_NODE_DCVS 0x44435653 #define MSM_LIMITS_SUB_FN_GENERAL 0x47454E00 #define MSM_LIMITS_SUB_FN_CRNT 0x43524E54 +#define MSM_LIMITS_SUB_FN_REL 0x52454C00 #define MSM_LIMITS_DOMAIN_MAX 0x444D4158 #define MSM_LIMITS_DOMAIN_MIN 0x444D494E #define MSM_LIMITS_CLUSTER_0 0x6370302D @@ -1674,7 +1675,20 @@ static int msm_thermal_lmh_dcvs_init(struct platform_device *pdev) */ devm_clk_put(&pdev->dev, osm_clk); - /* Enable the CRNT algorithm. Again, we dont care if this fails */ + /* Enable the CRNT and Reliability algorithm. Again, we dont + * care if this fails + */ + ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0, + MSM_LIMITS_SUB_FN_REL, + MSM_LIMITS_ALGO_MODE_ENABLE, 1); + if (ret) + pr_err("Unable to enable REL algo for cluster0\n"); + ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_1, + MSM_LIMITS_SUB_FN_REL, + MSM_LIMITS_ALGO_MODE_ENABLE, 1); + if (ret) + pr_err("Unable to enable REL algo for cluster1\n"); + ret = msm_lmh_dcvs_write(MSM_LIMITS_CLUSTER_0, MSM_LIMITS_SUB_FN_CRNT, MSM_LIMITS_ALGO_MODE_ENABLE, 1); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 629e3c865072..9bee25cfa0be 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -417,6 +417,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); * they are not on hot paths so a little discipline won't do * any harm. * + * The line discipline-related tty_struct fields are reset to + * prevent the ldisc driver from re-using stale information for + * the new ldisc instance. + * * Locking: takes termios_rwsem */ @@ -425,6 +429,9 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) down_write(&tty->termios_rwsem); tty->termios.c_line = num; up_write(&tty->termios_rwsem); + + tty->disc_data = NULL; + tty->receive_room = 0; } /** diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index dadd1e8dfe09..26a305f43ff6 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1441,6 +1441,9 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); + if (udev->bus->skip_resume && udev->state == USB_STATE_SUSPENDED) + return 0; + unbind_no_pm_drivers_interfaces(udev); /* From now on we are sure all drivers support suspend/resume @@ -1470,6 +1473,15 @@ int usb_resume(struct device *dev, pm_message_t msg) struct usb_device *udev = to_usb_device(dev); int status; + /* + * Some buses would like to keep their devices in suspend + * state after system resume. Their resume happen when + * a remote wakeup is detected or interface driver start + * I/O. + */ + if (udev->bus->skip_resume) + return 0; + /* For all calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. * Unbind the interfaces that will need rebinding later, diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index add035269ae7..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; @@ -1967,7 +1966,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) clk_disable_unprepare(mdwc->xo_clk); /* Perform controller power collapse */ - if (!mdwc->in_host_mode && !mdwc->vbus_active) { + if (!mdwc->in_host_mode && (!mdwc->vbus_active || mdwc->in_restart)) { mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE; dev_dbg(mdwc->dev, "%s: power collapse\n", __func__); dwc3_msm_config_gdsc(mdwc, 0); diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index eb2409dda50d..19d6a997ee6c 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -760,8 +760,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) ssize_t ret, data_len = -EINVAL; int halt; - ffs_log("enter: epfile name %s epfile err %d", epfile->name, - atomic_read(&epfile->error)); + ffs_log("enter: epfile name %s epfile err %d (%s)", epfile->name, + atomic_read(&epfile->error), io_data->read ? "READ" : "WRITE"); smp_mb__before_atomic(); if (atomic_read(&epfile->error)) @@ -781,6 +781,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) goto error; } + /* Don't wait on write if device is offline */ + if (!io_data->read) { + ret = -EINTR; + goto error; + } + /* * If ep is disabled, this fails all current IOs * and wait for next epfile open to happen. diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c025dccdd8f1..fcb9b4b822aa 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -167,6 +167,8 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!hcd) return -ENOMEM; + hcd_to_bus(hcd)->skip_resume = true; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { @@ -221,6 +223,8 @@ static int xhci_plat_probe(struct platform_device *pdev) goto disable_clk; } + hcd_to_bus(xhci->shared_hcd)->skip_resume = true; + if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || (pdata && pdata->usb3_lpm_capable)) xhci->quirks |= XHCI_LPM_SUPPORT; diff --git a/drivers/usb/pd/Kconfig b/drivers/usb/pd/Kconfig index dd2813000dec..cc88df495f6e 100644 --- a/drivers/usb/pd/Kconfig +++ b/drivers/usb/pd/Kconfig @@ -9,6 +9,7 @@ config USB_PD config USB_PD_POLICY tristate "USB Power Delivery Protocol and Policy Engine" depends on EXTCON + depends on DUAL_ROLE_USB_INTF select USB_PD help Say Y here to enable USB PD protocol and policy engine. diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index b4d7c7d8bddf..2fbe4c8faa79 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -10,6 +10,7 @@ * GNU General Public License for more details. */ +#include <linux/completion.h> #include <linux/delay.h> #include <linux/hrtimer.h> #include <linux/ipc_logging.h> @@ -24,6 +25,7 @@ #include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/extcon.h> +#include <linux/usb/class-dual-role.h> #include <linux/usb/usbpd.h> #include "usbpd.h" @@ -163,11 +165,11 @@ static void *usbpd_ipc_log; /* Timeouts (in ms) */ #define ERROR_RECOVERY_TIME 25 #define SENDER_RESPONSE_TIME 26 -#define SINK_WAIT_CAP_TIME 620 +#define SINK_WAIT_CAP_TIME 500 #define PS_TRANSITION_TIME 450 #define SRC_CAP_TIME 120 #define SRC_TRANSITION_TIME 25 -#define SRC_RECOVER_TIME 660 +#define SRC_RECOVER_TIME 750 #define PS_HARD_RESET_TIME 25 #define PS_SOURCE_ON 400 #define PS_SOURCE_OFF 750 @@ -175,8 +177,11 @@ static void *usbpd_ipc_log; #define VDM_BUSY_TIME 50 #define VCONN_ON_TIME 100 -/* tPSHardReset + tSafe0V + tSrcRecover + tSrcTurnOn */ -#define SNK_HARD_RESET_RECOVER_TIME (35 + 650 + 1000 + 275) +/* tPSHardReset + tSafe0V */ +#define SNK_HARD_RESET_VBUS_OFF_TIME (35 + 650) + +/* tSrcRecover + tSrcTurnOn */ +#define SNK_HARD_RESET_VBUS_ON_TIME (1000 + 275) #define PD_CAPS_COUNT 50 @@ -308,15 +313,23 @@ struct usbpd { enum power_supply_typec_mode typec_mode; enum power_supply_type psy_type; + enum power_supply_typec_power_role forced_pr; bool vbus_present; enum data_role current_dr; enum power_role current_pr; bool in_pr_swap; bool pd_phy_opened; + struct completion swap_complete; + + struct dual_role_phy_instance *dual_role; + struct dual_role_phy_desc dr_desc; + bool send_pr_swap; + bool send_dr_swap; struct regulator *vbus; struct regulator *vconn; + bool vbus_enabled; bool vconn_enabled; bool vconn_is_external; @@ -409,6 +422,17 @@ static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid) return NULL; } +/* Reset protocol layer */ +static inline void pd_reset_protocol(struct usbpd *pd) +{ + /* + * first Rx ID should be 0; set this to a sentinel of -1 so that in + * phy_msg_received() we can check if we had seen it before. + */ + pd->rx_msgid = -1; + pd->tx_msgid = 0; +} + static int pd_send_msg(struct usbpd *pd, u8 hdr_type, const u32 *data, size_t num_data, enum pd_msg_type type) { @@ -423,7 +447,9 @@ static int pd_send_msg(struct usbpd *pd, u8 hdr_type, const u32 *data, /* MessageID incremented regardless of Tx error */ pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID; - if (ret != num_data * sizeof(u32)) + if (ret < 0) + return ret; + else if (ret != num_data * sizeof(u32)) return -EIO; return 0; } @@ -631,6 +657,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) switch (next_state) { case PE_ERROR_RECOVERY: /* perform hard disconnect/reconnect */ pd->in_pr_swap = false; + pd->current_pr = PR_NONE; set_power_role(pd, PR_NONE); pd->typec_mode = POWER_SUPPLY_TYPEC_NONE; kick_sm(pd, 0); @@ -646,12 +673,14 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) */ } + dual_role_instance_changed(pd->dual_role); + /* Set CC back to DRP toggle for the next disconnect */ val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val); - pd->rx_msgid = -1; + pd_reset_protocol(pd); if (!pd->in_pr_swap) { if (pd->pd_phy_opened) { @@ -677,6 +706,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) pd->current_state = PE_SRC_SEND_CAPABILITIES; if (pd->in_pr_swap) { kick_sm(pd, SWAP_SOURCE_START_TIME); + pd->in_pr_swap = false; break; } @@ -758,6 +788,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) } kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); + complete(&pd->swap_complete); + dual_role_instance_changed(pd->dual_role); break; case PE_SRC_HARD_RESET: @@ -768,9 +800,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SRC_SEND_SOFT_RESET: case PE_SNK_SEND_SOFT_RESET: - /* Reset protocol layer */ - pd->tx_msgid = 0; - pd->rx_msgid = -1; + pd_reset_protocol(pd); ret = pd_send_msg(pd, MSG_SOFT_RESET, NULL, 0, SOP_MSG); if (ret) { @@ -801,6 +831,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) } } + dual_role_instance_changed(pd->dual_role); + ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_ALLOWED, &val); if (ret) { @@ -812,9 +844,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) if (!val.intval) break; - /* Reset protocol layer */ - pd->tx_msgid = 0; - pd->rx_msgid = -1; + pd_reset_protocol(pd); if (!pd->in_pr_swap) { if (pd->pd_phy_opened) { @@ -837,7 +867,17 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) pd->pd_phy_opened = true; } - pd->current_voltage = 5000000; + pd->current_voltage = pd->requested_voltage = 5000000; + val.intval = pd->requested_voltage; /* set max range to 5V */ + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_VOLTAGE_MAX, &val); + + if (!pd->vbus_present) { + pd->current_state = PE_SNK_DISCOVERY; + /* max time for hard reset to turn vbus back on */ + kick_sm(pd, SNK_HARD_RESET_VBUS_ON_TIME); + break; + } pd->current_state = PE_SNK_WAIT_FOR_CAPABILITIES; /* fall-through */ @@ -882,6 +922,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SNK_READY: pd->in_explicit_contract = true; kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); + complete(&pd->swap_complete); + dual_role_instance_changed(pd->dual_role); break; case PE_SNK_TRANSITION_TO_DEFAULT: @@ -901,19 +943,14 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) pd->vconn_enabled = false; } - val.intval = pd->requested_voltage; /* set range back to 5V */ - power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_VOLTAGE_MAX, &val); - pd->current_voltage = pd->requested_voltage; - - /* max time for hard reset to toggle vbus off/on */ - kick_sm(pd, SNK_HARD_RESET_RECOVER_TIME); + /* max time for hard reset to turn vbus off */ + kick_sm(pd, SNK_HARD_RESET_VBUS_OFF_TIME); break; case PE_PRS_SNK_SRC_TRANSITION_TO_OFF: val.intval = pd->requested_current = 0; /* suspend charging */ power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &val); + POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); pd->in_explicit_contract = false; @@ -996,7 +1033,7 @@ int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos) pd->vdm_tx = vdm_tx; /* slight delay before queuing to prioritize handling of incoming VDM */ - kick_sm(pd, 5); + kick_sm(pd, 2); return 0; } @@ -1039,23 +1076,23 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) return; } - if (handler && handler->svdm_received) + /* if this interrupts a previous exchange, abort queued response */ + if (cmd_type == SVDM_CMD_TYPE_INITIATOR && pd->vdm_tx) { + usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n", + VDM_HDR_SVID(pd->vdm_tx->data[0])); + + kfree(pd->vdm_tx); + pd->vdm_tx = NULL; + } + + if (handler && handler->svdm_received) { handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos); + return; + } + /* Standard Discovery or unhandled messages go here */ switch (cmd_type) { case SVDM_CMD_TYPE_INITIATOR: - /* - * if this interrupts a previous exchange, abort the previous - * outgoing response - */ - if (pd->vdm_tx) { - usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n", - VDM_HDR_SVID(pd->vdm_tx->data[0])); - - kfree(pd->vdm_tx); - pd->vdm_tx = NULL; - } - if (svid == USBPD_SID && cmd == USBPD_SVDM_DISCOVER_IDENTITY) { u32 tx_vdos[3] = { ID_HDR_USB_HOST | ID_HDR_USB_DEVICE | @@ -1074,13 +1111,14 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) break; case SVDM_CMD_TYPE_RESP_ACK: + if (svid != USBPD_SID) { + usbpd_err(&pd->dev, "unhandled ACK for SVID:0x%x\n", + svid); + break; + } + switch (cmd) { case USBPD_SVDM_DISCOVER_IDENTITY: - if (svid != USBPD_SID) { - usbpd_err(&pd->dev, "invalid VID:0x%x\n", svid); - break; - } - kfree(pd->vdm_tx_retry); pd->vdm_tx_retry = NULL; @@ -1091,11 +1129,6 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) break; case USBPD_SVDM_DISCOVER_SVIDS: - if (svid != USBPD_SID) { - usbpd_err(&pd->dev, "invalid VID:0x%x\n", svid); - break; - } - pd->vdm_state = DISCOVERED_SVIDS; kfree(pd->vdm_tx_retry); @@ -1181,33 +1214,15 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) break; - case USBPD_SVDM_DISCOVER_MODES: - usbpd_info(&pd->dev, "SVID:0x%04x VDM Modes discovered\n", - svid); - pd->vdm_state = DISCOVERED_MODES; - break; - - case USBPD_SVDM_ENTER_MODE: - usbpd_info(&pd->dev, "SVID:0x%04x VDM Mode entered\n", - svid); - pd->vdm_state = MODE_ENTERED; - kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); - break; - - case USBPD_SVDM_EXIT_MODE: - usbpd_info(&pd->dev, "SVID:0x%04x VDM Mode exited\n", - svid); - pd->vdm_state = MODE_EXITED; - kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); - break; - default: + usbpd_dbg(&pd->dev, "unhandled ACK for command:0x%x\n", + cmd); break; } break; case SVDM_CMD_TYPE_RESP_NAK: - usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:%d\n", + usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n", svid, cmd); break; @@ -1236,21 +1251,32 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) static void handle_vdm_tx(struct usbpd *pd) { int ret; + unsigned long flags; /* only send one VDM at a time */ if (pd->vdm_tx) { u32 vdm_hdr = pd->vdm_tx->data[0]; + /* bail out and try again later if a message just arrived */ + spin_lock_irqsave(&pd->rx_lock, flags); + if (!list_empty(&pd->rx_q)) { + spin_unlock_irqrestore(&pd->rx_lock, flags); + return; + } + spin_unlock_irqrestore(&pd->rx_lock, flags); + ret = pd_send_msg(pd, MSG_VDM, pd->vdm_tx->data, pd->vdm_tx->size, SOP_MSG); if (ret) { - usbpd_err(&pd->dev, "Error sending VDM command %d\n", - SVDM_HDR_CMD(pd->vdm_tx->data[0])); - usbpd_set_state(pd, pd->current_pr == PR_SRC ? + usbpd_err(&pd->dev, "Error (%d) sending VDM command %d\n", + ret, SVDM_HDR_CMD(pd->vdm_tx->data[0])); + + /* retry when hitting PE_SRC/SNK_Ready again */ + if (ret != -EBUSY) + usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_SOFT_RESET : PE_SNK_SEND_SOFT_RESET); - /* retry when hitting PE_SRC/SNK_Ready again */ return; } @@ -1262,7 +1288,7 @@ static void handle_vdm_tx(struct usbpd *pd) SVDM_HDR_CMD_TYPE(vdm_hdr) == SVDM_CMD_TYPE_INITIATOR && SVDM_HDR_CMD(vdm_hdr) <= USBPD_SVDM_DISCOVER_SVIDS) { if (pd->vdm_tx_retry) { - usbpd_err(&pd->dev, "Previous Discover VDM command %d not ACKed/NAKed\n", + usbpd_dbg(&pd->dev, "Previous Discover VDM command %d not ACKed/NAKed\n", SVDM_HDR_CMD( pd->vdm_tx_retry->data[0])); kfree(pd->vdm_tx_retry); @@ -1341,6 +1367,13 @@ static void vconn_swap(struct usbpd *pd) pd->vconn_enabled = true; + /* + * Small delay to ensure Vconn has ramped up. This is well + * below tVCONNSourceOn (100ms) so we still send PS_RDY within + * the allowed time. + */ + usleep_range(5000, 10000); + ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG); if (ret) { usbpd_err(&pd->dev, "Error sending PS_RDY\n"); @@ -1388,7 +1421,7 @@ static void usbpd_sm(struct work_struct *w) spin_unlock_irqrestore(&pd->rx_lock, flags); /* Disconnect? */ - if (pd->typec_mode == POWER_SUPPLY_TYPEC_NONE && !pd->in_pr_swap) { + if (pd->current_pr == PR_NONE) { if (pd->current_state == PE_UNKNOWN) goto sm_done; @@ -1422,8 +1455,10 @@ static void usbpd_sm(struct work_struct *w) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_ACTIVE, &val); - if (pd->current_pr == PR_SRC) + if (pd->vbus_enabled) { regulator_disable(pd->vbus); + pd->vbus_enabled = false; + } if (pd->vconn_enabled) { regulator_disable(pd->vconn); @@ -1445,13 +1480,22 @@ static void usbpd_sm(struct work_struct *w) usleep_range(ERROR_RECOVERY_TIME * USEC_PER_MSEC, (ERROR_RECOVERY_TIME + 5) * USEC_PER_MSEC); - /* Set CC back to DRP toggle */ - val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; + /* set due to dual_role class "mode" change */ + if (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE) + val.intval = pd->forced_pr; + else + /* Set CC back to DRP toggle */ + val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; + power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val); + pd->forced_pr = POWER_SUPPLY_TYPEC_PR_NONE; pd->current_state = PE_UNKNOWN; + kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); + dual_role_instance_changed(pd->dual_role); + goto sm_done; } @@ -1495,6 +1539,8 @@ static void usbpd_sm(struct work_struct *w) ret = regulator_enable(pd->vbus); if (ret) usbpd_err(&pd->dev, "Unable to enable vbus\n"); + else + pd->vbus_enabled = true; if (!pd->vconn_enabled && pd->typec_mode == @@ -1543,10 +1589,6 @@ static void usbpd_sm(struct work_struct *w) break; } - val.intval = 1; - power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_PD_ACTIVE, &val); - /* transmit was successful if GoodCRC was received */ pd->caps_count = 0; pd->hard_reset_count = 0; @@ -1555,6 +1597,10 @@ static void usbpd_sm(struct work_struct *w) /* wait for REQUEST */ pd->current_state = PE_SRC_SEND_CAPABILITIES_WAIT; kick_sm(pd, SENDER_RESPONSE_TIME); + + val.intval = 1; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_ACTIVE, &val); break; case PE_SRC_SEND_CAPABILITIES_WAIT: @@ -1604,7 +1650,6 @@ static void usbpd_sm(struct work_struct *w) } dr_swap(pd); - kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); } else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) { /* lock in current mode */ set_power_role(pd, pd->current_pr); @@ -1629,18 +1674,40 @@ static void usbpd_sm(struct work_struct *w) } vconn_swap(pd); + } else if (IS_DATA(rx_msg, MSG_VDM)) { + handle_vdm_rx(pd, rx_msg); + } else if (pd->send_pr_swap) { + pd->send_pr_swap = false; + ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); + if (ret) { + dev_err(&pd->dev, "Error sending PR Swap\n"); + usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); + break; + } + + pd->current_state = PE_PRS_SRC_SNK_SEND_SWAP; + kick_sm(pd, SENDER_RESPONSE_TIME); + } else if (pd->send_dr_swap) { + pd->send_dr_swap = false; + ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); + if (ret) { + dev_err(&pd->dev, "Error sending DR Swap\n"); + usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); + break; + } + + pd->current_state = PE_DRS_SEND_DR_SWAP; + kick_sm(pd, SENDER_RESPONSE_TIME); } else { - if (IS_DATA(rx_msg, MSG_VDM)) - handle_vdm_rx(pd, rx_msg); - else - handle_vdm_tx(pd); + handle_vdm_tx(pd); } break; case PE_SRC_TRANSITION_TO_DEFAULT: if (pd->vconn_enabled) regulator_disable(pd->vconn); - regulator_disable(pd->vbus); + if (pd->vbus_enabled) + regulator_disable(pd->vbus); if (pd->current_dr != DR_DFP) { extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0); @@ -1650,9 +1717,12 @@ static void usbpd_sm(struct work_struct *w) msleep(SRC_RECOVER_TIME); + pd->vbus_enabled = false; ret = regulator_enable(pd->vbus); if (ret) usbpd_err(&pd->dev, "Unable to enable vbus\n"); + else + pd->vbus_enabled = true; if (pd->vconn_enabled) { ret = regulator_enable(pd->vconn); @@ -1687,23 +1757,48 @@ static void usbpd_sm(struct work_struct *w) usbpd_set_state(pd, PE_SNK_STARTUP); break; + case PE_SNK_DISCOVERY: + if (!rx_msg) { + if (pd->vbus_present) + usbpd_set_state(pd, + PE_SNK_WAIT_FOR_CAPABILITIES); + + /* + * Handle disconnection in the middle of PR_Swap. + * Since in psy_changed() if pd->in_pr_swap is true + * we ignore the typec_mode==NONE change since that is + * expected to happen. However if the cable really did + * get disconnected we need to check for it here after + * waiting for VBUS presence times out. + */ + if (!pd->typec_mode) { + pd->current_pr = PR_NONE; + kick_sm(pd, 0); + } + + break; + } + /* else fall-through */ + case PE_SNK_WAIT_FOR_CAPABILITIES: + pd->in_pr_swap = false; + if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) { val.intval = 0; power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); - val.intval = 1; - power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_PD_ACTIVE, &val); - /* save the PDOs so userspace can further evaluate */ memcpy(&pd->received_pdos, rx_msg->payload, sizeof(pd->received_pdos)); pd->src_cap_id++; usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY); + + val.intval = 1; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_ACTIVE, &val); } else if (pd->hard_reset_count < 3) { usbpd_set_state(pd, PE_SNK_HARD_RESET); } else if (pd->pd_connected) { @@ -1731,6 +1826,8 @@ static void usbpd_sm(struct work_struct *w) case PE_SNK_SELECT_CAPABILITY: if (IS_CTRL(rx_msg, MSG_ACCEPT)) { + usbpd_set_state(pd, PE_SNK_TRANSITION_SINK); + /* prepare for voltage increase/decrease */ val.intval = pd->requested_voltage; power_supply_set_property(pd->usb_psy, @@ -1740,16 +1837,31 @@ static void usbpd_sm(struct work_struct *w) &val); /* - * disable charging; technically we are allowed to - * charge up to pSnkStdby (2.5 W) during this - * transition, but disable it just for simplicity. + * if we are changing voltages, we must lower input + * current to pSnkStdby (2.5W). Calculate it and set + * PD_CURRENT_MAX accordingly. */ - val.intval = 0; - power_supply_set_property(pd->usb_psy, + if (pd->requested_voltage != pd->current_voltage) { + int mv = max(pd->requested_voltage, + pd->current_voltage) / 1000; + val.intval = (2500000 / mv) * 1000; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); + } else { + /* decreasing current? */ + ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); + if (!ret && + pd->requested_current < val.intval) { + val.intval = + pd->requested_current * 1000; + power_supply_set_property(pd->usb_psy, + POWER_SUPPLY_PROP_PD_CURRENT_MAX, + &val); + } + } pd->selected_pdo = pd->requested_pdo; - usbpd_set_state(pd, PE_SNK_TRANSITION_SINK); } else if (IS_CTRL(rx_msg, MSG_REJECT) || IS_CTRL(rx_msg, MSG_WAIT)) { if (pd->in_explicit_contract) @@ -1826,7 +1938,6 @@ static void usbpd_sm(struct work_struct *w) } dr_swap(pd); - kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); } else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) { /* lock in current mode */ set_power_role(pd, pd->current_pr); @@ -1868,37 +1979,42 @@ static void usbpd_sm(struct work_struct *w) } vconn_swap(pd); + } else if (IS_DATA(rx_msg, MSG_VDM)) { + handle_vdm_rx(pd, rx_msg); + } else if (pd->send_pr_swap) { + pd->send_pr_swap = false; + ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); + if (ret) { + dev_err(&pd->dev, "Error sending PR Swap\n"); + usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); + break; + } + + pd->current_state = PE_PRS_SNK_SRC_SEND_SWAP; + kick_sm(pd, SENDER_RESPONSE_TIME); + } else if (pd->send_dr_swap) { + pd->send_dr_swap = false; + ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); + if (ret) { + dev_err(&pd->dev, "Error sending DR Swap\n"); + usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); + break; + } + + pd->current_state = PE_DRS_SEND_DR_SWAP; + kick_sm(pd, SENDER_RESPONSE_TIME); } else { - if (IS_DATA(rx_msg, MSG_VDM)) - handle_vdm_rx(pd, rx_msg); - else - handle_vdm_tx(pd); + handle_vdm_tx(pd); } break; case PE_SNK_TRANSITION_TO_DEFAULT: - val.intval = 0; - power_supply_set_property(pd->usb_psy, - POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); - - if (pd->vbus_present) { - usbpd_set_state(pd, PE_SNK_STARTUP); - } else { - /* Hard reset and VBUS didn't come back? */ - power_supply_get_property(pd->usb_psy, - POWER_SUPPLY_PROP_TYPEC_MODE, &val); - if (val.intval == POWER_SUPPLY_TYPEC_NONE) { - pd->typec_mode = POWER_SUPPLY_TYPEC_NONE; - kick_sm(pd, 0); - } - } + usbpd_set_state(pd, PE_SNK_STARTUP); break; case PE_SRC_SOFT_RESET: case PE_SNK_SOFT_RESET: - /* Reset protocol layer */ - pd->tx_msgid = 0; - pd->rx_msgid = -1; + pd_reset_protocol(pd); ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { @@ -1974,7 +2090,10 @@ static void usbpd_sm(struct work_struct *w) pd->in_pr_swap = true; pd->in_explicit_contract = false; - regulator_disable(pd->vbus); + if (pd->vbus_enabled) { + regulator_disable(pd->vbus); + pd->vbus_enabled = false; + } /* PE_PRS_SRC_SNK_Assert_Rd */ pd->current_pr = PR_SINK; @@ -2029,6 +2148,8 @@ static void usbpd_sm(struct work_struct *w) ret = regulator_enable(pd->vbus); if (ret) usbpd_err(&pd->dev, "Unable to enable vbus\n"); + else + pd->vbus_enabled = true; msleep(200); /* allow time VBUS ramp-up, must be < tNewSrc */ @@ -2139,6 +2260,21 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) pd->psy_type = val.intval; + /* + * For sink hard reset, state machine needs to know when VBUS changes + * - when in PE_SNK_TRANSITION_TO_DEFAULT, notify when VBUS falls + * - when in PE_SNK_DISCOVERY, notify when VBUS rises + */ + if (typec_mode && ((!pd->vbus_present && + pd->current_state == PE_SNK_TRANSITION_TO_DEFAULT) || + (pd->vbus_present && pd->current_state == PE_SNK_DISCOVERY))) { + usbpd_dbg(&pd->dev, "hard reset: typec mode:%d present:%d\n", + typec_mode, pd->vbus_present); + pd->typec_mode = typec_mode; + kick_sm(pd, 0); + return 0; + } + if (pd->typec_mode == typec_mode) return 0; @@ -2156,32 +2292,7 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) return 0; } - /* - * Workaround for PMIC HW bug. - * - * During hard reset when VBUS goes to 0 the CC logic - * will report this as a disconnection. In those cases - * it can be ignored, however the downside is that - * we can also happen to be in the SNK_Transition_to_default - * state due to a hard reset attempt even with a non-PD - * capable source, in which a physical disconnect may get - * masked. In that case, allow for the common case of - * disconnecting from an SDP. - * - * The less common case is a PD-capable SDP which will - * result in a hard reset getting treated like a - * disconnect. We can live with this until the HW bug - * is fixed: in which disconnection won't be reported - * on VBUS loss alone unless pullup is also removed - * from CC. - */ - if (pd->psy_type != POWER_SUPPLY_TYPE_USB && - pd->current_state == - PE_SNK_TRANSITION_TO_DEFAULT) { - usbpd_dbg(&pd->dev, "Ignoring disconnect due to hard reset\n"); - return 0; - } - + pd->current_pr = PR_NONE; break; /* Sink states */ @@ -2190,8 +2301,11 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) case POWER_SUPPLY_TYPEC_SOURCE_HIGH: usbpd_info(&pd->dev, "Type-C Source (%s) connected\n", src_current(typec_mode)); + + if (pd->current_pr == PR_SINK) + return 0; + pd->current_pr = PR_SINK; - pd->in_pr_swap = false; break; /* Source states */ @@ -2200,8 +2314,11 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) usbpd_info(&pd->dev, "Type-C Sink%s connected\n", typec_mode == POWER_SUPPLY_TYPEC_SINK ? "" : " (powered)"); + + if (pd->current_pr == PR_SRC) + return 0; + pd->current_pr = PR_SRC; - pd->in_pr_swap = false; break; case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY: @@ -2221,6 +2338,198 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) return 0; } +static enum dual_role_property usbpd_dr_properties[] = { + DUAL_ROLE_PROP_SUPPORTED_MODES, + DUAL_ROLE_PROP_MODE, + DUAL_ROLE_PROP_PR, + DUAL_ROLE_PROP_DR, +}; + +static int usbpd_dr_get_property(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop, unsigned int *val) +{ + struct usbpd *pd = dual_role_get_drvdata(dual_role); + + if (!pd) + return -ENODEV; + + switch (prop) { + case DUAL_ROLE_PROP_MODE: + /* For now associate UFP/DFP with data role only */ + if (pd->current_dr == DR_UFP) + *val = DUAL_ROLE_PROP_MODE_UFP; + else if (pd->current_dr == DR_DFP) + *val = DUAL_ROLE_PROP_MODE_DFP; + else + *val = DUAL_ROLE_PROP_MODE_NONE; + break; + case DUAL_ROLE_PROP_PR: + if (pd->current_pr == PR_SRC) + *val = DUAL_ROLE_PROP_PR_SRC; + else if (pd->current_pr == PR_SINK) + *val = DUAL_ROLE_PROP_PR_SNK; + else + *val = DUAL_ROLE_PROP_PR_NONE; + break; + case DUAL_ROLE_PROP_DR: + if (pd->current_dr == DR_UFP) + *val = DUAL_ROLE_PROP_DR_DEVICE; + else if (pd->current_dr == DR_DFP) + *val = DUAL_ROLE_PROP_DR_HOST; + else + *val = DUAL_ROLE_PROP_DR_NONE; + break; + default: + usbpd_warn(&pd->dev, "unsupported property %d\n", prop); + return -ENODATA; + } + + return 0; +} + +static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop, const unsigned int *val) +{ + struct usbpd *pd = dual_role_get_drvdata(dual_role); + bool do_swap = false; + + if (!pd) + return -ENODEV; + + switch (prop) { + case DUAL_ROLE_PROP_MODE: + usbpd_dbg(&pd->dev, "Setting mode to %d\n", *val); + + /* + * Forces disconnect on CC and re-establishes connection. + * This does not use PD-based PR/DR swap + */ + if (*val == DUAL_ROLE_PROP_MODE_UFP) + pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SINK; + else if (*val == DUAL_ROLE_PROP_MODE_DFP) + pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SOURCE; + + /* new mode will be applied in disconnect handler */ + set_power_role(pd, PR_NONE); + + /* wait until it takes effect */ + while (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE) + msleep(20); + + break; + + case DUAL_ROLE_PROP_DR: + usbpd_dbg(&pd->dev, "Setting data_role to %d\n", *val); + + if (*val == DUAL_ROLE_PROP_DR_HOST) { + if (pd->current_dr == DR_UFP) + do_swap = true; + } else if (*val == DUAL_ROLE_PROP_DR_DEVICE) { + if (pd->current_dr == DR_DFP) + do_swap = true; + } else { + usbpd_warn(&pd->dev, "setting data_role to 'none' unsupported\n"); + return -ENOTSUPP; + } + + if (do_swap) { + if (pd->current_state != PE_SRC_READY && + pd->current_state != PE_SNK_READY) { + usbpd_err(&pd->dev, "data_role swap not allowed: PD not in Ready state\n"); + return -EAGAIN; + } + + reinit_completion(&pd->swap_complete); + pd->send_dr_swap = true; + kick_sm(pd, 0); + + /* wait for operation to complete */ + if (!wait_for_completion_timeout(&pd->swap_complete, + msecs_to_jiffies(100))) { + usbpd_err(&pd->dev, "data_role swap timed out\n"); + return -ETIMEDOUT; + } + + if ((*val == DUAL_ROLE_PROP_DR_HOST && + pd->current_dr != DR_DFP) || + (*val == DUAL_ROLE_PROP_DR_DEVICE && + pd->current_dr != DR_UFP)) { + usbpd_err(&pd->dev, "incorrect state (%s) after data_role swap\n", + pd->current_dr == DR_DFP ? + "dfp" : "ufp"); + return -EPROTO; + } + } + + break; + + case DUAL_ROLE_PROP_PR: + usbpd_dbg(&pd->dev, "Setting power_role to %d\n", *val); + + if (*val == DUAL_ROLE_PROP_PR_SRC) { + if (pd->current_pr == PR_SINK) + do_swap = true; + } else if (*val == DUAL_ROLE_PROP_PR_SNK) { + if (pd->current_pr == PR_SRC) + do_swap = true; + } else { + usbpd_warn(&pd->dev, "setting power_role to 'none' unsupported\n"); + return -ENOTSUPP; + } + + if (do_swap) { + if (pd->current_state != PE_SRC_READY && + pd->current_state != PE_SNK_READY) { + usbpd_err(&pd->dev, "power_role swap not allowed: PD not in Ready state\n"); + return -EAGAIN; + } + + reinit_completion(&pd->swap_complete); + pd->send_pr_swap = true; + kick_sm(pd, 0); + + /* wait for operation to complete */ + if (!wait_for_completion_timeout(&pd->swap_complete, + msecs_to_jiffies(2000))) { + usbpd_err(&pd->dev, "power_role swap timed out\n"); + return -ETIMEDOUT; + } + + if ((*val == DUAL_ROLE_PROP_PR_SRC && + pd->current_pr != PR_SRC) || + (*val == DUAL_ROLE_PROP_PR_SNK && + pd->current_pr != PR_SINK)) { + usbpd_err(&pd->dev, "incorrect state (%s) after power_role swap\n", + pd->current_pr == PR_SRC ? + "source" : "sink"); + return -EPROTO; + } + } + break; + + default: + usbpd_warn(&pd->dev, "unsupported property %d\n", prop); + return -ENOTSUPP; + } + + return 0; +} + +static int usbpd_dr_prop_writeable(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop) +{ + switch (prop) { + case DUAL_ROLE_PROP_MODE: + case DUAL_ROLE_PROP_DR: + case DUAL_ROLE_PROP_PR: + return 1; + default: + break; + } + + return 0; +} + static int usbpd_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usbpd *pd = dev_get_drvdata(dev); @@ -2703,6 +3012,30 @@ struct usbpd *usbpd_create(struct device *parent) pd->vconn_is_external = device_property_present(parent, "qcom,vconn-uses-external-source"); + /* + * Register the Android dual-role class (/sys/class/dual_role_usb/). + * The first instance should be named "otg_default" as that's what + * Android expects. + * Note this is different than the /sys/class/usbpd/ created above. + */ + pd->dr_desc.name = (num_pd_instances == 1) ? + "otg_default" : dev_name(&pd->dev); + pd->dr_desc.supported_modes = DUAL_ROLE_SUPPORTED_MODES_DFP_AND_UFP; + pd->dr_desc.properties = usbpd_dr_properties; + pd->dr_desc.num_properties = ARRAY_SIZE(usbpd_dr_properties); + pd->dr_desc.get_property = usbpd_dr_get_property; + pd->dr_desc.set_property = usbpd_dr_set_property; + pd->dr_desc.property_is_writeable = usbpd_dr_prop_writeable; + + pd->dual_role = devm_dual_role_instance_register(&pd->dev, + &pd->dr_desc); + if (IS_ERR(pd->dual_role)) { + usbpd_err(&pd->dev, "could not register dual_role instance\n"); + goto unreg_psy; + } else { + pd->dual_role->drv_data = pd; + } + pd->current_pr = PR_NONE; pd->current_dr = DR_NONE; list_add_tail(&pd->instance, &_usbpd); @@ -2710,6 +3043,7 @@ struct usbpd *usbpd_create(struct device *parent) spin_lock_init(&pd->rx_lock); INIT_LIST_HEAD(&pd->rx_q); INIT_LIST_HEAD(&pd->svid_handlers); + init_completion(&pd->swap_complete); /* force read initial power_supply values */ psy_changed(&pd->psy_nb, PSY_EVENT_PROP_CHANGED, pd->usb_psy); 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/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c index 5456b9e8733b..839d701ec9b5 100644 --- a/drivers/usb/phy/phy-msm-qusb.c +++ b/drivers/usb/phy/phy-msm-qusb.c @@ -109,6 +109,7 @@ struct qusb_phy { void __iomem *base; void __iomem *tune2_efuse_reg; void __iomem *ref_clk_base; + void __iomem *tcsr_clamp_dig_n; struct clk *ref_clk_src; struct clk *ref_clk; @@ -147,6 +148,7 @@ struct qusb_phy { int phy_pll_reset_seq_len; int *emu_dcm_reset_seq; int emu_dcm_reset_seq_len; + bool put_into_high_z_state; }; static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on) @@ -189,15 +191,14 @@ static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high) return ret; } -static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on, - bool toggle_vdd) +static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on) { int ret = 0; dev_dbg(qphy->phy.dev, "%s turn %s regulators. power_enabled:%d\n", __func__, on ? "on" : "off", qphy->power_enabled); - if (toggle_vdd && qphy->power_enabled == on) { + if (qphy->power_enabled == on) { dev_dbg(qphy->phy.dev, "PHYs' regulators are already ON.\n"); return 0; } @@ -205,19 +206,17 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on, if (!on) goto disable_vdda33; - if (toggle_vdd) { - ret = qusb_phy_config_vdd(qphy, true); - if (ret) { - dev_err(qphy->phy.dev, "Unable to config VDD:%d\n", - ret); - goto err_vdd; - } + ret = qusb_phy_config_vdd(qphy, true); + if (ret) { + dev_err(qphy->phy.dev, "Unable to config VDD:%d\n", + ret); + goto err_vdd; + } - ret = regulator_enable(qphy->vdd); - if (ret) { - dev_err(qphy->phy.dev, "Unable to enable VDD\n"); - goto unconfig_vdd; - } + ret = regulator_enable(qphy->vdd); + if (ret) { + dev_err(qphy->phy.dev, "Unable to enable VDD\n"); + goto unconfig_vdd; } ret = regulator_set_load(qphy->vdda18, QUSB2PHY_1P8_HPM_LOAD); @@ -260,8 +259,7 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on, goto unset_vdd33; } - if (toggle_vdd) - qphy->power_enabled = true; + qphy->power_enabled = true; pr_debug("%s(): QUSB PHY's regulators are turned ON.\n", __func__); return ret; @@ -299,21 +297,18 @@ put_vdda18_lpm: dev_err(qphy->phy.dev, "Unable to set LPM of vdda18\n"); disable_vdd: - if (toggle_vdd) { - ret = regulator_disable(qphy->vdd); - if (ret) - dev_err(qphy->phy.dev, "Unable to disable vdd:%d\n", + ret = regulator_disable(qphy->vdd); + if (ret) + dev_err(qphy->phy.dev, "Unable to disable vdd:%d\n", ret); unconfig_vdd: - ret = qusb_phy_config_vdd(qphy, false); - if (ret) - dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n", + ret = qusb_phy_config_vdd(qphy, false); + if (ret) + dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n", ret); - } err_vdd: - if (toggle_vdd) - qphy->power_enabled = false; + qphy->power_enabled = false; dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n"); return ret; } @@ -330,12 +325,53 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value) case POWER_SUPPLY_DP_DM_DPF_DMF: dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPF_DMF\n"); if (!qphy->rm_pulldown) { - ret = qusb_phy_enable_power(qphy, true, false); + ret = qusb_phy_enable_power(qphy, true); if (ret >= 0) { qphy->rm_pulldown = true; dev_dbg(phy->dev, "DP_DM_F: rm_pulldown:%d\n", qphy->rm_pulldown); } + + if (qphy->put_into_high_z_state) { + if (qphy->tcsr_clamp_dig_n) + writel_relaxed(0x1, + qphy->tcsr_clamp_dig_n); + + qusb_phy_enable_clocks(qphy, true); + + dev_dbg(phy->dev, "RESET QUSB PHY\n"); + ret = reset_control_assert(qphy->phy_reset); + if (ret) + dev_err(phy->dev, "phyassert failed\n"); + usleep_range(100, 150); + ret = reset_control_deassert(qphy->phy_reset); + if (ret) + dev_err(phy->dev, "deassert failed\n"); + + /* + * Phy in non-driving mode leaves Dp and Dm + * lines in high-Z state. Controller power + * collapse is not switching phy to non-driving + * mode causing charger detection failure. Bring + * phy to non-driving mode by overriding + * controller output via UTMI interface. + */ + writel_relaxed(TERM_SELECT | XCVR_SELECT_FS | + OP_MODE_NON_DRIVE, + qphy->base + QUSB2PHY_PORT_UTMI_CTRL1); + writel_relaxed(UTMI_ULPI_SEL | + UTMI_TEST_MUX_SEL, + qphy->base + QUSB2PHY_PORT_UTMI_CTRL2); + + /* Disable PHY */ + writel_relaxed(CLAMP_N_EN | FREEZIO_N | + POWER_DOWN, + qphy->base + QUSB2PHY_PORT_POWERDOWN); + /* Make sure that above write is completed */ + wmb(); + + qusb_phy_enable_clocks(qphy, false); + } } break; @@ -343,7 +379,13 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value) case POWER_SUPPLY_DP_DM_DPR_DMR: dev_dbg(phy->dev, "POWER_SUPPLY_DP_DM_DPR_DMR\n"); if (qphy->rm_pulldown) { - ret = qusb_phy_enable_power(qphy, false, false); + if (!qphy->cable_connected) { + if (qphy->tcsr_clamp_dig_n) + writel_relaxed(0x0, + qphy->tcsr_clamp_dig_n); + dev_dbg(phy->dev, "turn off for HVDCP case\n"); + ret = qusb_phy_enable_power(qphy, false); + } if (ret >= 0) { qphy->rm_pulldown = false; dev_dbg(phy->dev, "DP_DM_R: rm_pulldown:%d\n", @@ -420,7 +462,7 @@ static int qusb_phy_init(struct usb_phy *phy) dev_dbg(phy->dev, "%s\n", __func__); - ret = qusb_phy_enable_power(qphy, true, true); + ret = qusb_phy_enable_power(qphy, true); if (ret) return ret; @@ -651,22 +693,23 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) /* Disable all interrupts */ writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); - /* - * Phy in non-driving mode leaves Dp and Dm lines in - * high-Z state. Controller power collapse is not - * switching phy to non-driving mode causing charger - * detection failure. Bring phy to non-driving mode by - * overriding controller output via UTMI interface. - */ - writel_relaxed(TERM_SELECT | XCVR_SELECT_FS | - OP_MODE_NON_DRIVE, - qphy->base + QUSB2PHY_PORT_UTMI_CTRL1); - writel_relaxed(UTMI_ULPI_SEL | UTMI_TEST_MUX_SEL, - qphy->base + QUSB2PHY_PORT_UTMI_CTRL2); + /* Make sure that above write is completed */ + wmb(); qusb_phy_enable_clocks(qphy, false); - qusb_phy_enable_power(qphy, false, true); + if (qphy->tcsr_clamp_dig_n) + writel_relaxed(0x0, + qphy->tcsr_clamp_dig_n); + qusb_phy_enable_power(qphy, false); + /* + * Set put_into_high_z_state to true so next USB + * cable connect, DPF_DMF request performs PHY + * reset and put it into high-z state. For bootup + * with or without USB cable, it doesn't require + * to put QUSB PHY into high-z state. + */ + qphy->put_into_high_z_state = true; } qphy->suspended = true; } else { @@ -678,7 +721,10 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); } else { - qusb_phy_enable_power(qphy, true, true); + qusb_phy_enable_power(qphy, true); + if (qphy->tcsr_clamp_dig_n) + writel_relaxed(0x1, + qphy->tcsr_clamp_dig_n); qusb_phy_enable_clocks(qphy, true); } qphy->suspended = false; @@ -849,6 +895,18 @@ static int qusb_phy_probe(struct platform_device *pdev) } } + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "tcsr_clamp_dig_n_1p8"); + if (res) { + qphy->tcsr_clamp_dig_n = devm_ioremap_nocache(dev, + res->start, resource_size(res)); + if (IS_ERR(qphy->tcsr_clamp_dig_n)) { + dev_err(dev, "err reading tcsr_clamp_dig_n\n"); + qphy->tcsr_clamp_dig_n = NULL; + } + } + + qphy->ref_clk_src = devm_clk_get(dev, "ref_clk_src"); if (IS_ERR(qphy->ref_clk_src)) dev_dbg(dev, "clk get failed for ref_clk_src\n"); @@ -1046,7 +1104,7 @@ static int qusb_phy_remove(struct platform_device *pdev) qphy->clocks_enabled = false; } - qusb_phy_enable_power(qphy, false, true); + qusb_phy_enable_power(qphy, false); return 0; } 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 b4191bc340d1..4c920f58d8ff 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -2068,7 +2068,7 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev, "hdcp_physical")) pr_warn("unable to remap dp hdcp resources\n"); - pr_debug("DP Driver base=%p size=%x\n", + pr_debug("DP Driver base=%pK size=%x\n", dp_drv->base, dp_drv->base_size); mdss_debug_register_base("dp", 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_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index cf7a398c13ce..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); @@ -2985,6 +3020,12 @@ static int mdss_dsi_cont_splash_config(struct mdss_panel_info *pinfo, mdss_dsi_panel_pwm_enable(ctrl_pdata); ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE | CTRL_STATE_DSI_ACTIVE); + + /* + * MDP client removes this extra vote during splash reconfigure + * for command mode panel from interface. DSI removes the vote + * during suspend-resume for video mode panel. + */ if (ctrl_pdata->panel_data.panel_info.type == MIPI_CMD_PANEL) clk_handle = ctrl_pdata->mdp_clk_handle; else diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 3536cb2d294d..6c840c8459ae 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -557,7 +557,8 @@ struct mdss_dsi_ctrl_pdata { void *clk_mngr; void *dsi_clk_handle; void *mdp_clk_handle; - int m_vote_cnt; + int m_dsi_vote_cnt; + int m_mdp_vote_cnt; /* debugfs structure */ struct mdss_dsi_debugfs_info *debugfs_info; @@ -691,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_clk.c b/drivers/video/fbdev/msm/mdss_dsi_clk.c index a7d1c251fab0..755d6092ea11 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_clk.c +++ b/drivers/video/fbdev/msm/mdss_dsi_clk.c @@ -795,8 +795,29 @@ error: return rc; } +bool is_dsi_clk_in_ecg_state(void *client) +{ + struct mdss_dsi_clk_client_info *c = client; + struct mdss_dsi_clk_mngr *mngr; + bool is_ecg = false; + + if (!client) { + pr_err("Invalid client params\n"); + goto end; + } + + mngr = c->mngr; + + mutex_lock(&mngr->clk_mutex); + is_ecg = (c->core_clk_state == MDSS_DSI_CLK_EARLY_GATE); + mutex_unlock(&mngr->clk_mutex); + +end: + return is_ecg; +} + int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk, - enum mdss_dsi_clk_state state) + enum mdss_dsi_clk_state state, u32 index) { int rc = 0; struct mdss_dsi_clk_client_info *c = client; @@ -817,7 +838,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk, c->name, mngr->name, clk, state, c->core_clk_state, c->link_clk_state); - MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state); + MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state); /* * Refcount handling rules: * 1. Increment refcount whenever ON is called @@ -883,7 +904,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk, pr_debug("[%s]%s: change=%d, Core (ref=%d, state=%d), Link (ref=%d, state=%d)\n", c->name, mngr->name, changed, c->core_refcount, c->core_clk_state, c->link_refcount, c->link_clk_state); - MDSS_XLOG(clk, state, c->core_clk_state, c->link_clk_state); + MDSS_XLOG(index, clk, state, c->core_clk_state, c->link_clk_state); if (changed) { rc = dsi_recheck_clk_state(mngr); diff --git a/drivers/video/fbdev/msm/mdss_dsi_clk.h b/drivers/video/fbdev/msm/mdss_dsi_clk.h index 9fe45254fe6d..0b88ddb57166 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_clk.h +++ b/drivers/video/fbdev/msm/mdss_dsi_clk.h @@ -197,6 +197,7 @@ int mdss_dsi_clk_deregister(void *client); * @client: client handle. * @clk: Type of clock requested (enum mdss_dsi_clk_type). * @state: clock state requested. + * @index: controller index. * * This routine is used to request a new clock state for a specific clock. If * turning ON the clocks, this guarantees that clocks will be on before @@ -206,7 +207,7 @@ int mdss_dsi_clk_deregister(void *client); * @return: error code. */ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk, - enum mdss_dsi_clk_state state); + enum mdss_dsi_clk_state state, u32 index); /** * mdss_dsi_clk_set_link_rate() - set clock rate for link clocks @@ -238,4 +239,16 @@ int mdss_dsi_clk_set_link_rate(void *client, enum mdss_dsi_link_clk_type clk, * @return:error code. */ int mdss_dsi_clk_force_toggle(void *client, u32 clk); + +/** + * is_dsi_clk_in_ecg_state() - Checks the current state of clocks + * @client: client handle. + * + * This routine returns checks the clocks status for client and return + * success code based on it. + * + * @return:true: if clocks are in ECG state + * false: for all other cases + */ +bool is_dsi_clk_in_ecg_state(void *client); #endif /* _MDSS_DSI_CLK_H_ */ diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index c9168242da60..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; @@ -2811,12 +2811,6 @@ static int dsi_event_thread(void *data) pr_debug("%s: Handling underflow event\n", __func__); __dsi_fifo_error_handler(ctrl, true); - } else { - pr_err("%s: ctrl recovery not defined\n", - __func__); - MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", - "dsi0_phy", "dsi1_ctrl", "dsi1_phy", "vbif", - "vbif_nrt", "dbg_bus", "vbif_dbg_bus", "panic"); } mutex_unlock(&ctrl->mutex); } @@ -2984,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; @@ -2996,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); @@ -3054,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_dsi_phy_v3.c b/drivers/video/fbdev/msm/mdss_dsi_phy_v3.c index d4ff82a11a09..992fd51606ca 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_phy_v3.c +++ b/drivers/video/fbdev/msm/mdss_dsi_phy_v3.c @@ -220,13 +220,13 @@ static void mdss_dsi_phy_v3_config_lane_settings( int mdss_dsi_phy_v3_regulator_enable(struct mdss_dsi_ctrl_pdata *ctrl) { - /* Nothing to be done for cobalt */ + /* Nothing to be done for 8998 */ return 0; } int mdss_dsi_phy_v3_regulator_disable(struct mdss_dsi_ctrl_pdata *ctrl) { - /* Nothing to be done for cobalt */ + /* Nothing to be done for 8998 */ return 0; } diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 08e06c75522a..98ca6c3da20b 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -233,9 +233,11 @@ static int mdss_fb_notify_update(struct msm_fb_data_type *mfd, } } else if (notify == NOTIFY_UPDATE_STOP) { mutex_lock(&mfd->update.lock); - if (mfd->update.init_done) + if (mfd->update.init_done) { + mutex_unlock(&mfd->update.lock); + mutex_lock(&mfd->no_update.lock); reinit_completion(&mfd->no_update.comp); - else { + } else { mutex_unlock(&mfd->update.lock); pr_err("notify update stop called without init\n"); return -EINVAL; @@ -1132,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; @@ -1509,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; @@ -1551,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); @@ -1595,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) { @@ -1806,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 a75a77b4b761..cefe368ccc9a 100644 --- a/drivers/video/fbdev/msm/mdss_hdcp_1x.c +++ b/drivers/video/fbdev/msm/mdss_hdcp_1x.c @@ -659,7 +659,7 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x_ctrl *hdcp_ctrl) 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; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index b90ac82049c6..0a316fa19909 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -134,6 +134,7 @@ struct hdmi_edid_ctrl { u8 it_scan_info; u8 ce_scan_info; u8 cea_blks; + /* DC: MSB -> LSB: Y420_48|Y420_36|Y420_30|RGB48|RGB36|RGB30|Y444 */ u8 deep_color; u16 physical_address; u32 video_resolution; /* selected by user */ @@ -858,6 +859,43 @@ static const u8 *hdmi_edid_find_block(const u8 *in_buf, u32 start_offset, return NULL; } /* hdmi_edid_find_block */ +static const u8 *hdmi_edid_find_hfvsdb(const u8 *in_buf) +{ + u8 len = 0, i = 0; + const u8 *vsd = NULL; + u32 vsd_offset = DBC_START_OFFSET; + u32 hf_ieee_oui = 0; + + /* Find HF-VSDB with HF-OUI */ + do { + vsd = hdmi_edid_find_block(in_buf, vsd_offset, + VENDOR_SPECIFIC_DATA_BLOCK, &len); + + if (!vsd || !len || len > MAX_DATA_BLOCK_SIZE) { + if (i == 0) + pr_debug("%s: VSDB not found\n", __func__); + else + pr_debug("%s: no more VSDB found\n", __func__); + + return NULL; + } + + hf_ieee_oui = (vsd[1] << 16) | (vsd[2] << 8) | vsd[3]; + + if (hf_ieee_oui == HDMI_FORUM_IEEE_OUI) { + pr_debug("%s: found HF-VSDB\n", __func__); + break; + } + + pr_debug("%s: Not a HF OUI 0x%x\n", __func__, hf_ieee_oui); + + i++; + vsd_offset = vsd - in_buf + len + 1; + } while (1); + + return vsd; +} + static void hdmi_edid_set_y420_support(struct hdmi_edid_ctrl *edid_ctrl, u32 video_format) { @@ -1251,62 +1289,32 @@ static void hdmi_edid_extract_speaker_allocation_data( static void hdmi_edid_extract_sink_caps(struct hdmi_edid_ctrl *edid_ctrl, const u8 *in_buf) { - u8 len = 0, i = 0; const u8 *vsd = NULL; - u32 vsd_offset = DBC_START_OFFSET; - u32 hf_ieee_oui = 0; if (!edid_ctrl) { - DEV_ERR("%s: invalid input\n", __func__); + pr_err("%s: invalid input\n", __func__); return; } - /* Find HF-VSDB with HF-OUI */ - do { - vsd = hdmi_edid_find_block(in_buf, vsd_offset, - VENDOR_SPECIFIC_DATA_BLOCK, &len); - - if (!vsd || !len || len > MAX_DATA_BLOCK_SIZE) { - if (i == 0) - DEV_ERR("%s: VSDB not found\n", __func__); - else - DEV_DBG("%s: no more VSDB found\n", __func__); - break; - } - - hf_ieee_oui = (vsd[1] << 16) | (vsd[2] << 8) | vsd[3]; - - if (hf_ieee_oui == HDMI_FORUM_IEEE_OUI) { - DEV_DBG("%s: found HF-VSDB\n", __func__); - break; - } - - DEV_DBG("%s: Not a HF OUI 0x%x\n", __func__, hf_ieee_oui); - - i++; - vsd_offset = vsd - in_buf + len + 1; - } while (1); - - if (!vsd) { - DEV_DBG("%s: HF-VSDB not found\n", __func__); - return; + vsd = hdmi_edid_find_hfvsdb(in_buf); + + if (vsd) { + /* Max pixel clock is in multiples of 5Mhz. */ + edid_ctrl->sink_caps.max_pclk_in_hz = + vsd[5]*5000000; + edid_ctrl->sink_caps.scdc_present = + (vsd[6] & 0x80) ? true : false; + edid_ctrl->sink_caps.scramble_support = + (vsd[6] & 0x08) ? true : false; + edid_ctrl->sink_caps.read_req_support = + (vsd[6] & 0x40) ? true : false; + edid_ctrl->sink_caps.osd_disparity = + (vsd[6] & 0x01) ? true : false; + edid_ctrl->sink_caps.dual_view_support = + (vsd[6] & 0x02) ? true : false; + edid_ctrl->sink_caps.ind_view_support = + (vsd[6] & 0x04) ? true : false; } - - /* Max pixel clock is in multiples of 5Mhz. */ - edid_ctrl->sink_caps.max_pclk_in_hz = - vsd[5]*5000000; - edid_ctrl->sink_caps.scdc_present = - (vsd[6] & 0x80) ? true : false; - edid_ctrl->sink_caps.scramble_support = - (vsd[6] & 0x08) ? true : false; - edid_ctrl->sink_caps.read_req_support = - (vsd[6] & 0x40) ? true : false; - edid_ctrl->sink_caps.osd_disparity = - (vsd[6] & 0x01) ? true : false; - edid_ctrl->sink_caps.dual_view_support = - (vsd[6] & 0x02) ? true : false; - edid_ctrl->sink_caps.ind_view_support = - (vsd[6] & 0x04) ? true : false; } static void hdmi_edid_extract_latency_fields(struct hdmi_edid_ctrl *edid_ctrl, @@ -1404,12 +1412,19 @@ static void hdmi_edid_extract_dc(struct hdmi_edid_ctrl *edid_ctrl, edid_ctrl->deep_color = (vsd[6] >> 0x3) & 0xF; - DEV_DBG("%s: deep color: Y444|RGB30|RGB36|RGB48: (%d|%d|%d|%d)\n", - __func__, + vsd = hdmi_edid_find_hfvsdb(in_buf); + + if (vsd) + edid_ctrl->deep_color |= (vsd[7] & 0x07) << 4; + + pr_debug("deep color: Y444|RGB30|RGB36|RGB48|Y420_30|Y420_36|Y420_48: (%d|%d|%d|%d|%d|%d|%d)\n", (int) (edid_ctrl->deep_color & BIT(0)) >> 0, (int) (edid_ctrl->deep_color & BIT(1)) >> 1, (int) (edid_ctrl->deep_color & BIT(2)) >> 2, - (int) (edid_ctrl->deep_color & BIT(3)) >> 3); + (int) (edid_ctrl->deep_color & BIT(3)) >> 3, + (int) (edid_ctrl->deep_color & BIT(4)) >> 4, + (int) (edid_ctrl->deep_color & BIT(5)) >> 5, + (int) (edid_ctrl->deep_color & BIT(6)) >> 6); } static u32 hdmi_edid_check_header(const u8 *edid_buf) @@ -2398,8 +2413,8 @@ u32 hdmi_edid_get_sink_mode(void *input) * * This API returns deep color for different formats supported by sink. * Deep color support for Y444 (BIT(0)), RGB30 (BIT(1)), RGB36 (BIT(2), - * RGB 48 (BIT(3)) is provided in a 8 bit integer. The MSB 8 bits are - * not used. + * RGB 48 (BIT(3)), Y420_30 (BIT(4)), Y420_36 (BIT(5)), Y420_48 (BIT(6)) + * is provided in a 8 bit integer. The MSB 8 bits are not used. * * Return: deep color data. */ @@ -2416,6 +2431,25 @@ u8 hdmi_edid_get_deep_color(void *input) } /** + * hdmi_edid_get_max_pclk() - get max pclk supported. Sink side's limitation + * should be concerned as well. + * @input: edid parser data + * + * Return: max pclk rate + */ +u32 hdmi_edid_get_max_pclk(void *input) +{ + struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return 0; + } + + return edid_ctrl->init_data.max_pclk_khz; +} + +/** * hdmi_edid_get_hdr_data() - get the HDR capabiliies of the sink * @input: edid parser data * diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h index ce6cecbb2e03..43e1adb1f139 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h @@ -60,6 +60,7 @@ void *hdmi_edid_init(struct hdmi_edid_init_data *init_data); bool hdmi_edid_is_s3d_mode_supported(void *input, u32 video_mode, u32 s3d_mode); u8 hdmi_edid_get_deep_color(void *edid_ctrl); +u32 hdmi_edid_get_max_pclk(void *edid_ctrl); void hdmi_edid_get_hdr_data(void *edid_ctrl, struct hdmi_edid_hdr_data **hdr_data); 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_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c index 522debfba8ce..a8a56e3a8745 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c @@ -602,14 +602,51 @@ end: return rc; } +static int hdmi_panel_setup_dc(struct hdmi_panel *panel) +{ + u32 hdmi_ctrl_reg; + u32 vbi_pkt_reg; + int rc = 0; + + pr_debug("Deep Color: %s\n", panel->data->dc_enable ? "ON" : "OFF"); + + /* enable deep color if supported */ + if (panel->data->dc_enable) { + hdmi_ctrl_reg = DSS_REG_R(panel->io, HDMI_CTRL); + + /* GC CD override */ + hdmi_ctrl_reg |= BIT(27); + + /* enable deep color for RGB888 30 bits */ + hdmi_ctrl_reg |= BIT(24); + DSS_REG_W(panel->io, HDMI_CTRL, hdmi_ctrl_reg); + + /* Enable GC_CONT and GC_SEND in General Control Packet + * (GCP) register so that deep color data is + * transmitted to the sink on every frame, allowing + * the sink to decode the data correctly. + * + * GC_CONT: 0x1 - Send GCP on every frame + * GC_SEND: 0x1 - Enable GCP Transmission + */ + vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL); + vbi_pkt_reg |= BIT(5) | BIT(4); + DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); + } + + return rc; +} + static int hdmi_panel_setup_scrambler(struct hdmi_panel *panel) { int rc = 0; int timeout_hsync; u32 reg_val = 0; u32 tmds_clock_ratio = 0; + u32 tmds_clock = 0; bool scrambler_on = false; struct msm_hdmi_mode_timing_info *timing = NULL; + struct mdss_panel_info *pinfo = NULL; if (!panel) { pr_err("invalid input\n"); @@ -622,13 +659,22 @@ static int hdmi_panel_setup_scrambler(struct hdmi_panel *panel) return -EINVAL; } + pinfo = panel->data->pinfo; + if (!pinfo) { + pr_err("invalid panel data\n"); + return -EINVAL; + } + /* Scrambling is supported from HDMI TX 4.0 */ if (panel->version < HDMI_TX_SCRAMBLER_MIN_TX_VERSION) { pr_debug("scrambling not supported by tx\n"); return 0; } - if (timing->pixel_freq > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) { + tmds_clock = hdmi_tx_setup_tmds_clk_rate(timing->pixel_freq, + pinfo->out_format, panel->data->dc_enable); + + if (tmds_clock > HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ) { scrambler_on = true; tmds_clock_ratio = 1; } else { @@ -798,6 +844,12 @@ static int hdmi_panel_power_on(void *input) pr_err("scrambler setup failed. rc=%d\n", rc); goto err; } + + rc = hdmi_panel_setup_dc(panel); + if (rc) { + pr_err("Deep Color setup failed. rc=%d\n", rc); + goto err; + } end: panel->on = true; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.h b/drivers/video/fbdev/msm/mdss_hdmi_panel.h index 6fa9af13d46e..cb40f0cad55e 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.h @@ -28,6 +28,7 @@ * @infoframe: set to true if infoframes should be sent to sink * @is_it_content: set to true if content is IT * @scrambler: set to true if scrambler needs to be enabled + * @dc_enable: set to true if deep color is enabled */ struct hdmi_panel_data { struct mdss_panel_info *pinfo; @@ -39,6 +40,7 @@ struct hdmi_panel_data { bool infoframe; bool is_it_content; bool scrambler; + bool dc_enable; }; /** diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 9c90a72bce99..e9ae30bb6914 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -35,6 +35,7 @@ #include "mdss.h" #include "mdss_panel.h" #include "mdss_hdmi_mhl.h" +#include "mdss_hdmi_util.h" #define DRV_NAME "hdmi-tx" #define COMPATIBLE_NAME "qcom,hdmi-tx" @@ -58,13 +59,6 @@ #define AUDIO_POLL_SLEEP_US (5 * 1000) #define AUDIO_POLL_TIMEOUT_US (AUDIO_POLL_SLEEP_US * 1000) -#define HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO 2 -#define HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 -#define HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 - -#define HDMI_TX_SCRAMBLER_THRESHOLD_RATE_KHZ 340000 -#define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200 - /* Maximum pixel clock rates for hdmi tx */ #define HDMI_DEFAULT_MAX_PCLK_RATE 148500 #define HDMI_TX_3_MAX_PCLK_RATE 297000 @@ -77,8 +71,9 @@ #define HDMI_TX_MIN_FPS 20000 #define HDMI_TX_MAX_FPS 120000 +#define HDMI_KHZ_TO_HZ 1000 -#define HDMI_TX_VERSION_403 0x40000003 /* msmcobalt */ +#define HDMI_TX_VERSION_403 0x40000003 /* msm8998 */ #define HDMI_GET_MSB(x) (x >> 8) #define HDMI_GET_LSB(x) (x & 0xff) @@ -111,7 +106,6 @@ static irqreturn_t hdmi_tx_isr(int irq, void *data); static void hdmi_tx_hpd_off(struct hdmi_tx_ctrl *hdmi_ctrl); static int hdmi_tx_enable_power(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, int enable); -static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl); static void hdmi_tx_fps_work(struct work_struct *work); static int hdmi_tx_pinctrl_set_state(struct hdmi_tx_ctrl *hdmi_ctrl, enum hdmi_tx_power_module_type module, bool active); @@ -121,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, @@ -318,11 +313,29 @@ static inline bool hdmi_tx_metadata_type_one(struct hdmi_tx_ctrl *hdmi_ctrl) return hdr_data->metadata_type_one; } +static inline bool hdmix_tx_sink_dc_support(struct hdmi_tx_ctrl *hdmi_ctrl) +{ + void *edid_fd = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); + + if (hdmi_ctrl->panel_data.panel_info.out_format == MDP_Y_CBCR_H2V2) + return (hdmi_edid_get_deep_color(edid_fd) & BIT(4)); + else + return (hdmi_edid_get_deep_color(edid_fd) & BIT(1)); +} + static inline bool hdmi_tx_dc_support(struct hdmi_tx_ctrl *hdmi_ctrl) { - return hdmi_ctrl->dc_feature_on && hdmi_ctrl->dc_support && - (hdmi_edid_get_deep_color( - hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)) & BIT(1)); + /* actual pixel clock if deep color is enabled */ + void *edid_fd = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); + u32 tmds_clk_with_dc = hdmi_tx_setup_tmds_clk_rate( + hdmi_ctrl->timing.pixel_freq, + hdmi_ctrl->panel.pinfo->out_format, + true); + + return hdmi_ctrl->dc_feature_on && + hdmi_ctrl->dc_support && + hdmix_tx_sink_dc_support(hdmi_ctrl) && + (tmds_clk_with_dc <= hdmi_edid_get_max_pclk(edid_fd)); } static const char *hdmi_tx_pm_name(enum hdmi_tx_power_module_type module) @@ -349,7 +362,10 @@ static const char *hdmi_tx_io_name(u32 type) static void hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl) { if (hdmi_ctrl && hdmi_ctrl->audio_ops.on) { - u32 pclk = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl); + u32 pclk = hdmi_tx_setup_tmds_clk_rate( + hdmi_ctrl->timing.pixel_freq, + hdmi_ctrl->panel.pinfo->out_format, + hdmi_ctrl->panel.dc_enable); hdmi_ctrl->audio_ops.on(hdmi_ctrl->audio_data, pclk, &hdmi_ctrl->audio_params); @@ -369,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); @@ -379,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) + return; + + fd = hdmi_tx_get_fd(HDMI_TX_FEAT_CEC_HW); - if (!hdmi_ctrl || !fd) + if (!fd) return; hdmi_cec_device_suspend(fd, hdmi_ctrl->panel_suspend); @@ -399,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); } @@ -634,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; } @@ -646,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; } @@ -1212,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) { @@ -1302,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, @@ -1322,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, @@ -1337,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 = { @@ -2100,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; @@ -2345,7 +2422,6 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on) struct dss_io_data *io = NULL; /* Defaults: Disable block, HDMI mode */ u32 hdmi_ctrl_reg = BIT(1); - u32 vbi_pkt_reg; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); @@ -2383,27 +2459,6 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on) * longer be used */ hdmi_ctrl_reg |= BIT(31); - - /* enable deep color if supported */ - if (hdmi_tx_dc_support(hdmi_ctrl)) { - /* GC CD override */ - hdmi_ctrl_reg |= BIT(27); - - /* enable deep color for RGB888 30 bits */ - hdmi_ctrl_reg |= BIT(24); - - /* Enable GC_CONT and GC_SEND in General Control Packet - * (GCP) register so that deep color data is - * transmitted to the sink on every frame, allowing - * the sink to decode the data correctly. - * - * GC_CONT: 0x1 - Send GCP on every frame - * GC_SEND: 0x1 - Enable GCP Transmission - */ - vbi_pkt_reg = DSS_REG_R(io, HDMI_VBI_PKT_CTRL); - vbi_pkt_reg |= BIT(5) | BIT(4); - DSS_REG_W(io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); - } } DSS_REG_W(io, HDMI_CTRL, hdmi_ctrl_reg); @@ -2973,44 +3028,6 @@ static int hdmi_tx_get_cable_status(struct platform_device *pdev, u32 vote) return hpd; } -static int hdmi_tx_setup_tmds_clk_rate(struct hdmi_tx_ctrl *hdmi_ctrl) -{ - u32 rate = 0; - struct msm_hdmi_mode_timing_info *timing = NULL; - u32 rate_ratio; - - if (!hdmi_ctrl) { - DEV_ERR("%s: Bad input parameters\n", __func__); - goto end; - } - - timing = &hdmi_ctrl->timing; - if (!timing) { - DEV_ERR("%s: Invalid timing info\n", __func__); - goto end; - } - - switch (hdmi_ctrl->panel_data.panel_info.out_format) { - case MDP_Y_CBCR_H2V2: - rate_ratio = HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO; - break; - case MDP_Y_CBCR_H2V1: - rate_ratio = HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO; - break; - default: - rate_ratio = HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO; - break; - } - - rate = timing->pixel_freq / rate_ratio; - - if (hdmi_tx_dc_support(hdmi_ctrl)) - rate += rate >> 2; - -end: - return rate; -} - static inline bool hdmi_tx_hw_is_cable_connected(struct hdmi_tx_ctrl *hdmi_ctrl) { return DSS_REG_R(&hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO], @@ -3059,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, @@ -3069,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__); @@ -3117,7 +3145,7 @@ static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl) void *pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL); void *edata = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); - hdmi_panel_get_vic(&panel_data->panel_info, + hdmi_ctrl->vic = hdmi_panel_get_vic(&panel_data->panel_info, &hdmi_ctrl->ds_data); if (hdmi_ctrl->vic <= 0) { @@ -3144,16 +3172,14 @@ static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_ctrl->vic); hdmi_ctrl->panel.scrambler = hdmi_edid_get_sink_scrambler_support( edata); + hdmi_ctrl->panel.dc_enable = hdmi_tx_dc_support(hdmi_ctrl); if (hdmi_ctrl->panel_ops.on) hdmi_ctrl->panel_ops.on(pdata); - pixel_clk = hdmi_ctrl->timing.pixel_freq * 1000; - - if (panel_data->panel_info.out_format == MDP_Y_CBCR_H2V2) - pixel_clk >>= 1; - else if (hdmi_tx_dc_support(hdmi_ctrl)) - pixel_clk += pixel_clk >> 2; + pixel_clk = hdmi_tx_setup_tmds_clk_rate(hdmi_ctrl->timing.pixel_freq, + hdmi_ctrl->panel.pinfo->out_format, + hdmi_ctrl->panel.dc_enable) * 1000; DEV_DBG("%s: setting pixel clk %d\n", __func__, pixel_clk); @@ -3215,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", @@ -3568,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) { @@ -3576,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; @@ -3614,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; @@ -3844,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) { @@ -4545,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_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c index c9fc8ba8bfdb..89890bcf68df 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/delay.h> +#include <linux/msm_mdp.h> #include "mdss_hdmi_util.h" #define RESOLUTION_NAME_STR_LEN 30 @@ -26,6 +27,10 @@ #define HDMI_SCDC_UNKNOWN_REGISTER "Unknown register" +#define HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO 2 +#define HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 +#define HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO 1 + static char res_buf[RESOLUTION_NAME_STR_LEN]; enum trigger_mode { @@ -738,6 +743,30 @@ ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf, u32 size) return len; } /* hdmi_get_video_3d_fmt_2string */ +int hdmi_tx_setup_tmds_clk_rate(u32 pixel_freq, u32 out_format, bool dc_enable) +{ + u32 rate_ratio; + + switch (out_format) { + case MDP_Y_CBCR_H2V2: + rate_ratio = HDMI_TX_YUV420_24BPP_PCLK_TMDS_CH_RATE_RATIO; + break; + case MDP_Y_CBCR_H2V1: + rate_ratio = HDMI_TX_YUV422_24BPP_PCLK_TMDS_CH_RATE_RATIO; + break; + default: + rate_ratio = HDMI_TX_RGB_24BPP_PCLK_TMDS_CH_RATE_RATIO; + break; + } + + pixel_freq /= rate_ratio; + + if (dc_enable) + pixel_freq += pixel_freq >> 2; + + return pixel_freq; +} + static void hdmi_ddc_trigger(struct hdmi_tx_ddc_ctrl *ddc_ctrl, enum trigger_mode mode, bool seg) { diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.h b/drivers/video/fbdev/msm/mdss_hdmi_util.h index 8a7e4d1ebafc..4fd659616bcc 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.h @@ -16,6 +16,7 @@ #include "video/msm_hdmi_modes.h" #include "mdss_panel.h" +#include "mdss_hdmi_panel.h" /* HDMI_TX Registers */ #define HDMI_CTRL (0x00000000) @@ -495,6 +496,7 @@ bool hdmi_is_valid_resv_timing(int mode); void hdmi_reset_resv_timing_info(void); int hdmi_panel_get_vic(struct mdss_panel_info *pinfo, struct hdmi_util_ds_data *ds_data); +int hdmi_tx_setup_tmds_clk_rate(u32 pixel_freq, u32 out_format, bool dc_enable); /* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */ void *hdmi_get_featuredata_from_sysfs_dev(struct device *device, u32 type); 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 9ed44937efe6..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; @@ -4227,9 +4339,11 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff) return 0; } - ret = mdss_mdp_ctl_setup(ctl); - if (ret) - return ret; + if (mdss_mdp_ctl_is_power_off(ctl)) { + ret = mdss_mdp_ctl_setup(ctl); + if (ret) + return ret; + } sctl = mdss_mdp_get_split_ctl(ctl); @@ -5408,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_debug.c b/drivers/video/fbdev/msm/mdss_mdp_debug.c index 711d2d222c7d..1ad6810a6bb6 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_debug.c +++ b/drivers/video/fbdev/msm/mdss_mdp_debug.c @@ -938,7 +938,7 @@ static struct debug_bus dbg_bus_8996[] = { }; -static struct debug_bus dbg_bus_msmcobalt[] = { +static struct debug_bus dbg_bus_msm8998[] = { /* * sspp0 - 0x188 @@ -1727,7 +1727,7 @@ static struct vbif_debug_bus nrt_vbif_dbg_bus_8996[] = { {0x21c, 0x214, 0, 12, 0, 0xc}, /* xin blocks - clock side */ }; -static struct vbif_debug_bus vbif_dbg_bus_msmcobalt[] = { +static struct vbif_debug_bus vbif_dbg_bus_msm8998[] = { {0x214, 0x21c, 16, 2, 0x0, 0xd}, /* arb clients */ {0x214, 0x21c, 16, 2, 0x80, 0xc0}, /* arb clients */ {0x214, 0x21c, 16, 2, 0x100, 0x140}, /* arb clients */ @@ -1757,10 +1757,10 @@ void mdss_mdp_hw_rev_debug_caps_init(struct mdss_data_type *mdata) break; case MDSS_MDP_HW_REV_300: case MDSS_MDP_HW_REV_301: - mdata->dbg_bus = dbg_bus_msmcobalt; - mdata->dbg_bus_size = ARRAY_SIZE(dbg_bus_msmcobalt); - mdata->vbif_dbg_bus = vbif_dbg_bus_msmcobalt; - mdata->vbif_dbg_bus_size = ARRAY_SIZE(vbif_dbg_bus_msmcobalt); + mdata->dbg_bus = dbg_bus_msm8998; + mdata->dbg_bus_size = ARRAY_SIZE(dbg_bus_msm8998); + mdata->vbif_dbg_bus = vbif_dbg_bus_msm8998; + mdata->vbif_dbg_bus_size = ARRAY_SIZE(vbif_dbg_bus_msm8998); mdata->nrt_vbif_dbg_bus = nrt_vbif_dbg_bus_8996; mdata->nrt_vbif_dbg_bus_size = ARRAY_SIZE(nrt_vbif_dbg_bus_8996); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index f08af5d6edd3..a71c7254de7c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -335,6 +335,57 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_mixer *mixer, return 0; } +static bool __disable_rd_ptr_from_te(char __iomem *pingpong_base) +{ + u32 cfg; + bool disabled; + + cfg = mdss_mdp_pingpong_read(pingpong_base, + MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC); + + disabled = BIT(20) & cfg; + cfg &= ~BIT(20); + mdss_mdp_pingpong_write(pingpong_base, + MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg); + + return disabled; +} + +static inline void __enable_rd_ptr_from_te(char __iomem *pingpong_base) +{ + u32 cfg; + + cfg = mdss_mdp_pingpong_read(pingpong_base, + MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC); + cfg |= BIT(20); + mdss_mdp_pingpong_write(pingpong_base, + MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg); +} + +/* +* __disable_autorefresh - disables autorefresh feature in the hw. +* +* To disable autorefresh, driver needs to make sure no transactions are +* on-going; for ensuring this, driver must: +* +* 1. Disable listening to the external TE (this gives extra time before +* trigger next transaction). +* 2. Wait for any on-going transaction (wait for ping pong done interrupt). +* 3. Disable auto-refresh. +* 4. Re-enable listening to the external panel TE. +* +* So it is responsability of the caller of this function to only call to disable +* autorefresh if no hw transaction is on-going (wait for ping pong) and if +* the listening for the external TE is disabled in the tear check logic (this +* to prevent any race conditions with the hw), as mentioned in the above +* steps. +*/ +static inline void __disable_autorefresh(char __iomem *pingpong_base) +{ + mdss_mdp_pingpong_write(pingpong_base, + MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0x0); +} + static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, bool locked) { @@ -342,7 +393,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, struct mdss_mdp_mixer *mixer = NULL, *mixer_right = NULL; struct mdss_mdp_ctl *ctl = ctx->ctl; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - u32 offset = 0; + bool rd_ptr_disabled = false; mixer = mdss_mdp_mixer_get(ctl, MDSS_MDP_MIXER_MUX_LEFT); if (mixer) { @@ -352,21 +403,32 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_cmd_ctx *ctx, */ if (mdss_mdp_pingpong_read(mixer->pingpong_base, MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG) & BIT(31)) { - offset = MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG; + + /* 1. disable rd pointer from the external te */ + rd_ptr_disabled = + __disable_rd_ptr_from_te(mixer->pingpong_base); + + /* 2. disable autorefresh */ if (is_pingpong_split(ctl->mfd)) - writel_relaxed(0x0, - (mdata->slave_pingpong_base + offset)); + __disable_autorefresh( + mdata->slave_pingpong_base); + if (is_split_lm(ctl->mfd)) { - mixer_right = - mdss_mdp_mixer_get(ctl, - MDSS_MDP_MIXER_MUX_RIGHT); + mixer_right = mdss_mdp_mixer_get(ctl, + MDSS_MDP_MIXER_MUX_RIGHT); + if (mixer_right) - writel_relaxed(0x0, - (mixer_right->pingpong_base + offset)); + __disable_autorefresh( + mixer_right->pingpong_base); } - mdss_mdp_pingpong_write(mixer->pingpong_base, - MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0x0); + + __disable_autorefresh(mixer->pingpong_base); pr_debug("%s: disabling auto refresh\n", __func__); + + /* 2. re-enable rd pointer from te (if was enabled) */ + if (rd_ptr_disabled) + __enable_rd_ptr_from_te(mixer->pingpong_base); + } rc = mdss_mdp_cmd_tearcheck_cfg(mixer, ctx, locked); if (rc) @@ -991,6 +1053,7 @@ static void mdss_mdp_cmd_readptr_done(void *arg) vsync_time = ktime_get(); ctl->vsync_cnt++; MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt)); + trace_mdp_cmd_readptr_done(ctl->num, atomic_read(&ctx->koff_cnt)); complete_all(&ctx->rdptr_done); /* If caller is waiting for the read pointer, notify. */ @@ -2364,7 +2427,6 @@ static void mdss_mdp_cmd_pre_programming(struct mdss_mdp_ctl *mctl) struct mdss_mdp_cmd_ctx *ctx = mctl->intf_ctx[MASTER_CTX]; char __iomem *pp_base; u32 autorefresh_state; - u32 cfg; if (!mctl->is_master) return; @@ -2384,11 +2446,8 @@ static void mdss_mdp_cmd_pre_programming(struct mdss_mdp_ctl *mctl) * instruct MDP to ignore the panel TE so the next auto-refresh * is delayed until flush bits are set. */ - cfg = mdss_mdp_pingpong_read(pp_base, - MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC); - cfg &= ~BIT(20); - mdss_mdp_pingpong_write(pp_base, - MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg); + __disable_rd_ptr_from_te(pp_base); + ctx->ignore_external_te = true; } @@ -2400,7 +2459,6 @@ static void mdss_mdp_cmd_post_programming(struct mdss_mdp_ctl *mctl) { struct mdss_mdp_cmd_ctx *ctx = mctl->intf_ctx[MASTER_CTX]; char __iomem *pp_base; - u32 cfg; if (!mctl->is_master) return; @@ -2419,11 +2477,8 @@ static void mdss_mdp_cmd_post_programming(struct mdss_mdp_ctl *mctl) pp_base = mctl->mixer_left->pingpong_base; /* enable MDP to listen to the TE */ - cfg = mdss_mdp_pingpong_read(pp_base, - MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC); - cfg |= BIT(20); - mdss_mdp_pingpong_write(pp_base, - MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg); + __enable_rd_ptr_from_te(pp_base); + ctx->ignore_external_te = false; } } @@ -2675,11 +2730,10 @@ static int mdss_mdp_disable_autorefresh(struct mdss_mdp_ctl *ctl, mdss_mdp_cmd_wait4_autorefresh_pp(sctl); /* disable autorefresh */ - mdss_mdp_pingpong_write(pp_base, MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0); + __disable_autorefresh(pp_base); if (is_pingpong_split(ctl->mfd)) - mdss_mdp_pingpong_write(mdata->slave_pingpong_base, - MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG, 0); + __disable_autorefresh(mdata->slave_pingpong_base); ctx->autorefresh_state = MDP_AUTOREFRESH_OFF; ctx->autorefresh_frame_cnt = 0; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 048e5fce30c6..fabdc5cd3e42 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -960,7 +960,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, ctx->intf_num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num, ctx->base); ret = mdss_mdp_video_ctx_stop(ctl, pinfo, ctx); @@ -978,7 +978,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, sctx->intf_num, sctx->base); ret = mdss_mdp_video_ctx_stop(ctl, pinfo, sctx); @@ -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__); @@ -2021,7 +2029,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); @@ -2054,7 +2062,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; ctl->intf_ctx[SLAVE_CTX] = ctx; 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 036e4e39efda..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, @@ -852,7 +855,7 @@ static int __validate_layer_reconfig(struct mdp_input_layer *layer, */ if (pipe->csc_coeff_set != layer->color_space) { src_fmt = mdss_mdp_get_format_params(layer->buffer.format); - if (pipe->src_fmt->is_yuv && src_fmt->is_yuv) { + if (pipe->src_fmt->is_yuv && src_fmt && src_fmt->is_yuv) { status = -EPERM; pr_err("csc change is not permitted on used pipe\n"); } @@ -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 946e33033ab7..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; @@ -1453,6 +1453,21 @@ static void mdss_mdp_overlay_update_pm(struct mdss_overlay_private *mdp5_data) activate_event_timer(mdp5_data->cpu_pm_hdl, wakeup_time); } +static void __unstage_pipe_and_clean_buf(struct msm_fb_data_type *mfd, + struct mdss_mdp_pipe *pipe, struct mdss_mdp_data *buf) +{ + + pr_debug("unstaging pipe:%d rect:%d buf:%d\n", + pipe->num, pipe->multirect.num, !buf); + MDSS_XLOG(pipe->num, pipe->multirect.num, !buf); + mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left); + mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right); + pipe->dirty = true; + + if (buf) + __pipe_buf_mark_cleanup(mfd, buf); +} + static int __overlay_queue_pipes(struct msm_fb_data_type *mfd) { struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd); @@ -1533,7 +1548,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd) } break; default: - pr_err("invalid state of buf %p=%d\n", + pr_err("invalid state of buf %pK=%d\n", buf, buf->state); BUG(); break; @@ -1573,14 +1588,36 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd) ret = mdss_mdp_pipe_queue_data(pipe, buf); if (IS_ERR_VALUE(ret)) { - pr_warn("Unable to queue data for pnum=%d\n", - pipe->num); - mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_left); - mdss_mdp_mixer_pipe_unstage(pipe, pipe->mixer_right); - pipe->dirty = true; + pr_warn("Unable to queue data for pnum=%d rect=%d\n", + pipe->num, pipe->multirect.num); + + /* + * If we fail for a multi-rect pipe, unstage both rects + * so we don't leave the pipe configured in multi-rect + * mode with only one rectangle staged. + */ + if (pipe->multirect.mode != + MDSS_MDP_PIPE_MULTIRECT_NONE) { + struct mdss_mdp_pipe *next_pipe = + (struct mdss_mdp_pipe *) + pipe->multirect.next; + + if (next_pipe) { + struct mdss_mdp_data *next_buf = + list_first_entry_or_null( + &next_pipe->buf_queue, + struct mdss_mdp_data, + pipe_list); + + __unstage_pipe_and_clean_buf(mfd, + next_pipe, next_buf); + } else { + pr_warn("cannot find rect pnum=%d\n", + pipe->num); + } + } - if (buf) - __pipe_buf_mark_cleanup(mfd, buf); + __unstage_pipe_and_clean_buf(mfd, pipe, buf); } } @@ -3728,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) { @@ -4365,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); @@ -4577,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) { @@ -5123,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; @@ -6111,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 bcf5309993b9..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) { @@ -2702,8 +2703,8 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, if (ret) { pr_err("pipe pp setup error for pnum=%d\n", pipe->num); - MDSS_XLOG(pipe->num, pipe->mixer_left->num, - pipe->play_cnt, 0xbad); + MDSS_XLOG(pipe->num, pipe->multirect.num, + pipe->mixer_left->num, pipe->play_cnt, 0xbad); goto done; } @@ -2714,13 +2715,14 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, pipe->params_changed = 0; mdss_mdp_pipe_solidfill_setup(pipe); - MDSS_XLOG(pipe->num, pipe->mixer_left->num, pipe->play_cnt, - 0x111); + MDSS_XLOG(pipe->num, pipe->multirect.num, pipe->mixer_left->num, + pipe->play_cnt, 0x111); goto update_nobuf; } - MDSS_XLOG(pipe->num, pipe->mixer_left->num, pipe->play_cnt, 0x222); + MDSS_XLOG(pipe->num, pipe->multirect.num, pipe->mixer_left->num, + pipe->play_cnt, 0x222); if (params_changed) { pipe->params_changed = 0; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index f79212ea740d..5a8438caba4b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -2190,7 +2190,7 @@ static int pp_hist_setup(u32 *op, u32 block, struct mdss_mdp_mixer *mix, if (hist_info->col_en) mdss_mdp_hist_irq_set_mask(intr_mask << hist_info->intr_shift); /* - * Starting from msmcobalt, the histogram enable bit has been moved + * Starting from msm8998, the histogram enable bit has been moved * from DSPP opmode register to PA_HIST opmode register, hence we need * to update the histogram enable bit differently based on mdss version. * If HIST pp_set_config is defined, we will enable or disable the @@ -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); @@ -2906,7 +2908,7 @@ int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -3250,7 +3252,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -5754,7 +5756,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -5789,7 +5791,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, mfd->index); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -5929,7 +5931,7 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd, mfd->index); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -6298,7 +6300,7 @@ static int mdss_mdp_ad_ipc_reset(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -6339,7 +6341,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK\n", ret, ad); return ret; } @@ -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_pp_cache_config.c b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c index 5bd627853c59..e51cf44c2de2 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c @@ -367,7 +367,7 @@ int pp_dither_cache_params(struct mdp_dither_cfg_data *config, { int ret = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %pi pp_res %pK\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_trace.h b/drivers/video/fbdev/msm/mdss_mdp_trace.h index 648e4fcd1cd2..b79b4c70f5dc 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_trace.h +++ b/drivers/video/fbdev/msm/mdss_mdp_trace.h @@ -372,6 +372,22 @@ TRACE_EVENT(mdp_cmd_pingpong_done, __entry->koff_cnt) ); +TRACE_EVENT(mdp_cmd_readptr_done, + TP_PROTO(u32 ctl_num, int koff_cnt), + TP_ARGS(ctl_num, koff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(int, koff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->koff_cnt = koff_cnt; + ), + TP_printk("ctl num:%d kickoff:%d", + __entry->ctl_num, + __entry->koff_cnt) +); + TRACE_EVENT(mdp_cmd_release_bw, TP_PROTO(u32 ctl_num), TP_ARGS(ctl_num), 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/mdss_util.c b/drivers/video/fbdev/msm/mdss_util.c index d2610ff80878..65941601cfdc 100644 --- a/drivers/video/fbdev/msm/mdss_util.c +++ b/drivers/video/fbdev/msm/mdss_util.c @@ -23,6 +23,7 @@ int mdss_register_irq(struct mdss_hw *hw) { unsigned long irq_flags; u32 ndx_bit; + bool err = false; if (!hw || hw->hw_ndx >= MDSS_MAX_HW_BLK) return -EINVAL; @@ -33,10 +34,12 @@ int mdss_register_irq(struct mdss_hw *hw) if (!mdss_irq_handlers[hw->hw_ndx]) mdss_irq_handlers[hw->hw_ndx] = hw; else - pr_err("panel %d's irq at %pK is already registered\n", - hw->hw_ndx, hw->irq_handler); + err = true; spin_unlock_irqrestore(&mdss_lock, irq_flags); + if (err) + pr_err("panel %d's irq at %pK is already registered\n", + hw->hw_ndx, hw->irq_handler); return 0; } @@ -76,6 +79,7 @@ void mdss_disable_irq(struct mdss_hw *hw) { unsigned long irq_flags; u32 ndx_bit; + bool err = false; if (hw->hw_ndx >= MDSS_MAX_HW_BLK) return; @@ -87,7 +91,7 @@ void mdss_disable_irq(struct mdss_hw *hw) spin_lock_irqsave(&mdss_lock, irq_flags); if (!(hw->irq_info->irq_mask & ndx_bit)) { - pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); + err = true; } else { hw->irq_info->irq_mask &= ~ndx_bit; if (hw->irq_info->irq_mask == 0) { @@ -96,12 +100,16 @@ void mdss_disable_irq(struct mdss_hw *hw) } } spin_unlock_irqrestore(&mdss_lock, irq_flags); + + if (err) + pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); } /* called from interrupt context */ void mdss_disable_irq_nosync(struct mdss_hw *hw) { u32 ndx_bit; + bool err = false; if (hw->hw_ndx >= MDSS_MAX_HW_BLK) return; @@ -113,7 +121,7 @@ void mdss_disable_irq_nosync(struct mdss_hw *hw) spin_lock(&mdss_lock); if (!(hw->irq_info->irq_mask & ndx_bit)) { - pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); + err = true; } else { hw->irq_info->irq_mask &= ~ndx_bit; if (hw->irq_info->irq_mask == 0) { @@ -122,6 +130,9 @@ void mdss_disable_irq_nosync(struct mdss_hw *hw) } } spin_unlock(&mdss_lock); + + if (err) + pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); } int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr) @@ -176,6 +187,7 @@ void mdss_disable_irq_wake(struct mdss_hw *hw) { unsigned long irq_flags; u32 ndx_bit; + bool err = false; if (hw->hw_ndx >= MDSS_MAX_HW_BLK) return; @@ -188,7 +200,7 @@ void mdss_disable_irq_wake(struct mdss_hw *hw) spin_lock_irqsave(&mdss_lock, irq_flags); if (!(hw->irq_info->irq_wake_mask & ndx_bit)) { - pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); + err = true; } else { hw->irq_info->irq_wake_mask &= ~ndx_bit; if (hw->irq_info->irq_wake_ena) { @@ -197,6 +209,9 @@ void mdss_disable_irq_wake(struct mdss_hw *hw) } } spin_unlock_irqrestore(&mdss_lock, irq_flags); + + if (err) + pr_warn("MDSS HW ndx=%d is NOT set\n", hw->hw_ndx); } struct mdss_util_intf mdss_util = { diff --git a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c index 20d48575f323..4c9045d6a2a7 100644 --- a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c +++ b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c @@ -1118,7 +1118,7 @@ static void tx_prune_dtd_list(struct edid_3d_data_t *mhl_edid_3d_data, if ((0 != p_desc->dtd.pixel_clock_low) || (0 != p_desc->dtd.pixel_clock_high)) { MHL_TX_EDID_INFO( - "pix clock non-zero p_desc:%p", p_desc) + "pix clock non-zero p_desc:%pK", p_desc) if ((0 == p_desc->dtd.horz_active_7_0) && (0 == p_desc->dtd.horz_active_blanking_high. horz_active_11_8)) { @@ -1722,9 +1722,10 @@ static void prune_svd_list( ("\n\nInvalid extension size\n\n")); while (pb_src < pb_limit) { MHL_TX_EDID_INFO( - "moving data up %p(0x%02X) " - "<- %p(0x%02X)\n", - pb_dest, (uint16_t)*pb_dest, + "moving data up %pK(0x%02X) ", + pb_dest, (uint16_t)*pb_dest); + MHL_TX_EDID_INFO( + "<- %pK(0x%02X)\n", pb_src, (uint16_t)*pb_src); *pb_dest++ = *pb_src++; } diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index b5b5a026733e..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) @@ -2081,7 +2090,11 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle, { int rc = 0; struct mdss_dsi_ctrl_pdata *mctrl = NULL; - int i; + int i, *vote_cnt; + + void *m_clk_handle; + bool is_ecg = false; + int state = MDSS_DSI_CLK_OFF; if (!ctrl) { pr_err("%s: Invalid arg\n", __func__); @@ -2113,6 +2126,18 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle, } /* + * it should add and remove extra votes based on voting clients to avoid + * removal of legitimate vote from DSI client. + */ + if (mctrl && (clk_handle == ctrl->dsi_clk_handle)) { + m_clk_handle = mctrl->dsi_clk_handle; + vote_cnt = &mctrl->m_dsi_vote_cnt; + } else if (mctrl) { + m_clk_handle = mctrl->mdp_clk_handle; + vote_cnt = &mctrl->m_mdp_vote_cnt; + } + + /* * When DSI is used in split mode, the link clock for master controller * has to be turned on first before the link clock for slave can be * turned on. In case the current controller is a slave, an ON vote is @@ -2124,18 +2149,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle, __func__, ctrl->ndx, clk_type, clk_state, __builtin_return_address(0), mctrl ? 1 : 0); if (mctrl && (clk_type & MDSS_DSI_LINK_CLK)) { - rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle, - MDSS_DSI_ALL_CLKS, - MDSS_DSI_CLK_ON); + if (clk_state != MDSS_DSI_CLK_ON) { + /* preserve clk state; do not turn off forcefully */ + is_ecg = is_dsi_clk_in_ecg_state(m_clk_handle); + if (is_ecg) + state = MDSS_DSI_CLK_EARLY_GATE; + } + + rc = mdss_dsi_clk_req_state(m_clk_handle, + MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON, mctrl->ndx); if (rc) { pr_err("%s: failed to turn on mctrl clocks, rc=%d\n", __func__, rc); goto error; } - ctrl->m_vote_cnt++; + (*vote_cnt)++; } - rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state); + rc = mdss_dsi_clk_req_state(clk_handle, clk_type, clk_state, ctrl->ndx); if (rc) { pr_err("%s: failed set clk state, rc = %d\n", __func__, rc); goto error; @@ -2164,24 +2195,24 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, void *clk_handle, * for ON, since the previous ECG state must have * removed two votes to let clocks turn off. * - * To satisfy the above requirement, m_vote_cnt keeps track of + * To satisfy the above requirement, vote_cnt keeps track of * the number of ON votes for master requested by slave. For - * every OFF/ECG state request, Either 2 or m_vote_cnt number of + * every OFF/ECG state request, Either 2 or vote_cnt number of * votes are removed depending on which is lower. */ - for (i = 0; (i < ctrl->m_vote_cnt && i < 2); i++) { - rc = mdss_dsi_clk_req_state(mctrl->dsi_clk_handle, - MDSS_DSI_ALL_CLKS, - MDSS_DSI_CLK_OFF); + for (i = 0; (i < *vote_cnt && i < 2); i++) { + rc = mdss_dsi_clk_req_state(m_clk_handle, + MDSS_DSI_ALL_CLKS, state, mctrl->ndx); if (rc) { pr_err("%s: failed to set mctrl clk state, rc = %d\n", __func__, rc); goto error; } } - ctrl->m_vote_cnt -= i; - pr_debug("%s: ctrl=%d, m_vote_cnt=%d\n", __func__, ctrl->ndx, - ctrl->m_vote_cnt); + (*vote_cnt) -= i; + pr_debug("%s: ctrl=%d, vote_cnt=%d dsi_vote_cnt=%d mdp_vote_cnt:%d\n", + __func__, ctrl->ndx, *vote_cnt, mctrl->m_dsi_vote_cnt, + mctrl->m_mdp_vote_cnt); } error: diff --git a/fs/proc/array.c b/fs/proc/array.c index b6c00ce0e29e..d5c6f5b38617 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -171,15 +171,15 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, seq_printf(m, "State:\t%s\n" "Tgid:\t%d\n" - "Ngid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" "TracerPid:\t%d\n" "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n" + "Ngid:\t%d\n" "FDSize:\t%d\nGroups:\t", get_task_state(p), - tgid, ngid, pid_nr_ns(pid, ns), ppid, tpid, + tgid, pid_nr_ns(pid, ns), ppid, tpid, from_kuid_munged(user_ns, cred->uid), from_kuid_munged(user_ns, cred->euid), from_kuid_munged(user_ns, cred->suid), @@ -188,7 +188,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, from_kgid_munged(user_ns, cred->egid), from_kgid_munged(user_ns, cred->sgid), from_kgid_munged(user_ns, cred->fsgid), - max_fds); + ngid, max_fds); group_info = cred->group_info; for (g = 0; g < group_info->ngroups; g++) diff --git a/include/dt-bindings/clock/audio-ext-clk.h b/include/dt-bindings/clock/audio-ext-clk.h index 6e4932342751..c9a8286d7c7f 100644 --- a/include/dt-bindings/clock/audio-ext-clk.h +++ b/include/dt-bindings/clock/audio-ext-clk.h @@ -14,9 +14,19 @@ #define __AUDIO_EXT_CLK_H /* Audio External Clocks */ +#ifdef CONFIG_COMMON_CLK_QCOM +#define AUDIO_PMI_CLK 0 +#define AUDIO_PMIC_LNBB_CLK 1 +#define AUDIO_AP_CLK 2 +#define AUDIO_AP_CLK2 3 +#define AUDIO_LPASS_MCLK 4 +#define AUDIO_LPASS_MCLK2 5 +#else #define clk_audio_ap_clk 0x9b5727cb #define clk_audio_pmi_clk 0xcbfe416d #define clk_audio_ap_clk2 0x454d1e91 #define clk_audio_lpass_mclk 0xf0f2a284 #define clk_audio_pmi_lnbb_clk 0x57312343 #endif + +#endif diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-8998.h index 4bacef303967..42617016188d 100644 --- a/include/dt-bindings/clock/msm-clocks-cobalt.h +++ b/include/dt-bindings/clock/msm-clocks-8998.h @@ -10,8 +10,8 @@ * GNU General Public License for more details. */ -#ifndef __MSM_CLOCKS_COBALT_H -#define __MSM_CLOCKS_COBALT_H +#ifndef __MSM_CLOCKS_8998_H +#define __MSM_CLOCKS_8998_H #include "audio-ext-clk.h" diff --git a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h b/include/dt-bindings/clock/msm-clocks-hwio-8998.h index f10afffc74b2..f10afffc74b2 100644 --- a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h +++ b/include/dt-bindings/clock/msm-clocks-hwio-8998.h diff --git a/include/dt-bindings/clock/qcom,mmcc-msmfalcon.h b/include/dt-bindings/clock/qcom,mmcc-msmfalcon.h index ffb80a128dd6..7a6ec2bf2418 100644 --- a/include/dt-bindings/clock/qcom,mmcc-msmfalcon.h +++ b/include/dt-bindings/clock/qcom,mmcc-msmfalcon.h @@ -159,46 +159,47 @@ #define MMSS_MDSS_AXI_CLK 142 #define MMSS_MDSS_BYTE0_CLK 143 #define MMSS_MDSS_BYTE0_INTF_CLK 144 -#define MMSS_MDSS_BYTE1_CLK 145 -#define MMSS_MDSS_BYTE1_INTF_CLK 146 -#define MMSS_MDSS_DP_AUX_CLK 147 -#define MMSS_MDSS_DP_CRYPTO_CLK 148 -#define MMSS_MDSS_DP_GTC_CLK 149 -#define MMSS_MDSS_DP_LINK_CLK 150 -#define MMSS_MDSS_DP_LINK_INTF_CLK 151 -#define MMSS_MDSS_DP_PIXEL_CLK 152 -#define MMSS_MDSS_ESC0_CLK 153 -#define MMSS_MDSS_ESC1_CLK 154 -#define MMSS_MDSS_HDMI_DP_AHB_CLK 155 -#define MMSS_MDSS_MDP_CLK 156 -#define MMSS_MDSS_PCLK0_CLK 157 -#define MMSS_MDSS_PCLK1_CLK 158 -#define MMSS_MDSS_ROT_CLK 159 -#define MMSS_MDSS_VSYNC_CLK 160 -#define MMSS_MISC_AHB_CLK 161 -#define MMSS_MISC_CXO_CLK 162 -#define MMSS_MNOC_AHB_CLK 163 -#define MMSS_SNOC_DVM_AXI_CLK 164 -#define MMSS_THROTTLE_CAMSS_AHB_CLK 165 -#define MMSS_THROTTLE_CAMSS_AXI_CLK 166 -#define MMSS_THROTTLE_CAMSS_CXO_CLK 167 -#define MMSS_THROTTLE_MDSS_AHB_CLK 168 -#define MMSS_THROTTLE_MDSS_AXI_CLK 169 -#define MMSS_THROTTLE_MDSS_CXO_CLK 170 -#define MMSS_THROTTLE_VIDEO_AHB_CLK 171 -#define MMSS_THROTTLE_VIDEO_AXI_CLK 172 -#define MMSS_THROTTLE_VIDEO_CXO_CLK 173 -#define MMSS_VIDEO_AHB_CLK 174 -#define MMSS_VIDEO_AXI_CLK 175 -#define MMSS_VIDEO_CORE_CLK 176 -#define MMSS_VIDEO_SUBCORE0_CLK 177 -#define PCLK0_CLK_SRC 178 -#define PCLK1_CLK_SRC 179 -#define ROT_CLK_SRC 180 -#define VFE0_CLK_SRC 181 -#define VFE1_CLK_SRC 182 -#define VIDEO_CORE_CLK_SRC 183 -#define VSYNC_CLK_SRC 184 +#define MMSS_MDSS_BYTE0_INTF_DIV_CLK 145 +#define MMSS_MDSS_BYTE1_CLK 146 +#define MMSS_MDSS_BYTE1_INTF_CLK 147 +#define MMSS_MDSS_DP_AUX_CLK 148 +#define MMSS_MDSS_DP_CRYPTO_CLK 149 +#define MMSS_MDSS_DP_GTC_CLK 150 +#define MMSS_MDSS_DP_LINK_CLK 151 +#define MMSS_MDSS_DP_LINK_INTF_CLK 152 +#define MMSS_MDSS_DP_PIXEL_CLK 153 +#define MMSS_MDSS_ESC0_CLK 154 +#define MMSS_MDSS_ESC1_CLK 155 +#define MMSS_MDSS_HDMI_DP_AHB_CLK 156 +#define MMSS_MDSS_MDP_CLK 157 +#define MMSS_MDSS_PCLK0_CLK 158 +#define MMSS_MDSS_PCLK1_CLK 159 +#define MMSS_MDSS_ROT_CLK 160 +#define MMSS_MDSS_VSYNC_CLK 161 +#define MMSS_MISC_AHB_CLK 162 +#define MMSS_MISC_CXO_CLK 163 +#define MMSS_MNOC_AHB_CLK 164 +#define MMSS_SNOC_DVM_AXI_CLK 165 +#define MMSS_THROTTLE_CAMSS_AHB_CLK 166 +#define MMSS_THROTTLE_CAMSS_AXI_CLK 167 +#define MMSS_THROTTLE_CAMSS_CXO_CLK 168 +#define MMSS_THROTTLE_MDSS_AHB_CLK 169 +#define MMSS_THROTTLE_MDSS_AXI_CLK 170 +#define MMSS_THROTTLE_MDSS_CXO_CLK 171 +#define MMSS_THROTTLE_VIDEO_AHB_CLK 172 +#define MMSS_THROTTLE_VIDEO_AXI_CLK 173 +#define MMSS_THROTTLE_VIDEO_CXO_CLK 174 +#define MMSS_VIDEO_AHB_CLK 175 +#define MMSS_VIDEO_AXI_CLK 176 +#define MMSS_VIDEO_CORE_CLK 177 +#define MMSS_VIDEO_SUBCORE0_CLK 178 +#define PCLK0_CLK_SRC 179 +#define PCLK1_CLK_SRC 180 +#define ROT_CLK_SRC 181 +#define VFE0_CLK_SRC 182 +#define VFE1_CLK_SRC 183 +#define VIDEO_CORE_CLK_SRC 184 +#define VSYNC_CLK_SRC 185 #define BIMC_SMMU_GDSC 0 #define CAMSS_CPP_GDSC 1 @@ -209,5 +210,6 @@ #define VIDEO_SUBCORE0_GDSC 6 #define VIDEO_TOP_GDSC 7 +#define CAMSS_MICRO_BCR 0 #endif diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2a5acbdc6327..83e9c6e23f2f 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; @@ -177,6 +178,14 @@ struct clk_rate_request { * @set_flags: Set custom flags which deals with hardware specifics. Returns 0 * on success, -EEROR otherwise. * + * @list_registers: Queries the hardware to get the current register contents. + * This callback is optional and required clocks could + * add this callback. + * + * @list_rate: Return the nth supported frequency for a given clock which is + * below rate_max on success and -ENXIO in case of no frequency + * table. + * * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow * implementations to split any work between atomic (enable) and sleepable * (prepare) contexts. If enabling a clock requires code that might sleep, @@ -217,6 +226,10 @@ struct clk_ops { void (*init)(struct clk_hw *hw); int (*debug_init)(struct clk_hw *hw, struct dentry *dentry); int (*set_flags)(struct clk_hw *hw, unsigned flags); + void (*list_registers)(struct seq_file *f, + struct clk_hw *hw); + long (*list_rate)(struct clk_hw *hw, unsigned n, + unsigned long rate_max); }; /** diff --git a/include/linux/filter.h b/include/linux/filter.h index 5110d4211866..ccb98b459c59 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -421,7 +421,11 @@ static inline void bpf_prog_unlock_ro(struct bpf_prog *fp) } #endif /* CONFIG_DEBUG_SET_MODULE_RONX */ -int sk_filter(struct sock *sk, struct sk_buff *skb); +int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap); +static inline int sk_filter(struct sock *sk, struct sk_buff *skb) +{ + return sk_filter_trim_cap(sk, skb, 1); +} int bpf_prog_select_runtime(struct bpf_prog *fp); void bpf_prog_free(struct bpf_prog *fp); diff --git a/include/linux/ipa.h b/include/linux/ipa.h index e66d388651b8..c3ffe51d8069 100644 --- a/include/linux/ipa.h +++ b/include/linux/ipa.h @@ -98,7 +98,7 @@ enum ipa_dp_evt_type { }; /** - * enum hdr_total_len_or_pad_type - type vof alue held by TOTAL_LEN_OR_PAD + * enum hdr_total_len_or_pad_type - type of value held by TOTAL_LEN_OR_PAD * field in header configuration register. * @IPA_HDR_PAD: field is used as padding length * @IPA_HDR_TOTAL_LEN: field is used as total length @@ -433,6 +433,55 @@ typedef void (*ipa_notify_cb)(void *priv, enum ipa_dp_evt_type evt, unsigned long data); /** + * enum ipa_wdi_meter_evt_type - type of event client callback is + * for AP+STA mode metering + * @IPA_GET_WDI_SAP_STATS: get IPA_stats betwen SAP and STA - + * use ipa_get_wdi_sap_stats structure + * @IPA_SET_WIFI_QUOTA: set quota limit on STA - + * use ipa_set_wifi_quota structure + */ +enum ipa_wdi_meter_evt_type { + IPA_GET_WDI_SAP_STATS, + IPA_SET_WIFI_QUOTA, +}; + +struct ipa_get_wdi_sap_stats { + /* indicate to reset stats after query */ + uint8_t reset_stats; + /* indicate valid stats from wlan-fw */ + uint8_t stats_valid; + /* Tx: SAP->STA */ + uint64_t ipv4_tx_packets; + uint64_t ipv4_tx_bytes; + /* Rx: STA->SAP */ + uint64_t ipv4_rx_packets; + uint64_t ipv4_rx_bytes; + uint64_t ipv6_tx_packets; + uint64_t ipv6_tx_bytes; + uint64_t ipv6_rx_packets; + uint64_t ipv6_rx_bytes; +}; + +/** + * struct ipa_set_wifi_quota - structure used for + * IPA_SET_WIFI_QUOTA. + * + * @quota_bytes: Quota (in bytes) for the STA interface. + * @set_quota: Indicate whether to set the quota (use 1) or + * unset the quota. + * + */ +struct ipa_set_wifi_quota { + uint64_t quota_bytes; + uint8_t set_quota; + /* indicate valid quota set from wlan-fw */ + uint8_t set_valid; +}; + +typedef void (*ipa_wdi_meter_notifier_cb)(enum ipa_wdi_meter_evt_type evt, + void *data); + +/** * struct ipa_connect_params - low-level client connect input parameters. Either * client allocates the data and desc FIFO and specifies that in data+desc OR * specifies sizes and pipe_mem pref and IPA does the allocation. @@ -1001,6 +1050,7 @@ struct ipa_wdi_dl_params_smmu { * @ul_smmu: WDI_RX configuration info when WLAN uses SMMU * @dl_smmu: WDI_TX configuration info when WLAN uses SMMU * @smmu_enabled: true if WLAN uses SMMU + * @ipa_wdi_meter_notifier_cb: Get WDI stats and quato info */ struct ipa_wdi_in_params { struct ipa_sys_connect_params sys; @@ -1011,6 +1061,9 @@ struct ipa_wdi_in_params { struct ipa_wdi_dl_params_smmu dl_smmu; } u; bool smmu_enabled; +#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN + ipa_wdi_meter_notifier_cb wdi_notify; +#endif }; /** @@ -1265,6 +1318,9 @@ int ipa_resume_wdi_pipe(u32 clnt_hdl); int ipa_suspend_wdi_pipe(u32 clnt_hdl); int ipa_get_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); u16 ipa_get_smem_restr_bytes(void); +int ipa_broadcast_wdi_quota_reach_ind(uint32_t fid, + uint64_t num_bytes); + /* * To retrieve doorbell physical address of * wlan pipes @@ -1845,6 +1901,12 @@ static inline int ipa_suspend_wdi_pipe(u32 clnt_hdl) return -EPERM; } +static inline int ipa_broadcast_wdi_quota_reach_ind(uint32_t fid, + uint64_t num_bytes) +{ + return -EPERM; +} + static inline int ipa_uc_wdi_get_dbpa( struct ipa_wdi_db_params *out) { diff --git a/include/linux/qpnp/qpnp-revid.h b/include/linux/qpnp/qpnp-revid.h index 652d68ac63bf..8d9bbfd67992 100644 --- a/include/linux/qpnp/qpnp-revid.h +++ b/include/linux/qpnp/qpnp-revid.h @@ -171,30 +171,30 @@ /* PMI8996 */ #define PMI8996_SUBTYPE 0x13 -/* PMCOBALT */ -#define PMCOBALT_SUBTYPE 0x14 +/* PM8998 */ +#define PM8998_SUBTYPE 0x14 -/* PMICOBALT */ -#define PMICOBALT_SUBTYPE 0x15 +/* PMI8998 */ +#define PMI8998_SUBTYPE 0x15 /* PMFALCON */ #define PM2FALCON_SUBTYPE 0x1A #define PMFALCON_SUBTYPE 0x1B -#define PMICOBALT_V1P0_REV1 0x00 -#define PMICOBALT_V1P0_REV2 0x00 -#define PMICOBALT_V1P0_REV3 0x00 -#define PMICOBALT_V1P0_REV4 0x01 +#define PMI8998_V1P0_REV1 0x00 +#define PMI8998_V1P0_REV2 0x00 +#define PMI8998_V1P0_REV3 0x00 +#define PMI8998_V1P0_REV4 0x01 -#define PMICOBALT_V1P1_REV1 0x00 -#define PMICOBALT_V1P1_REV2 0x00 -#define PMICOBALT_V1P1_REV3 0x01 -#define PMICOBALT_V1P1_REV4 0x01 +#define PMI8998_V1P1_REV1 0x00 +#define PMI8998_V1P1_REV2 0x00 +#define PMI8998_V1P1_REV3 0x01 +#define PMI8998_V1P1_REV4 0x01 -#define PMICOBALT_V2P0_REV1 0x00 -#define PMICOBALT_V2P0_REV2 0x00 -#define PMICOBALT_V2P0_REV3 0x00 -#define PMICOBALT_V2P0_REV4 0x02 +#define PMI8998_V2P0_REV1 0x00 +#define PMI8998_V2P0_REV2 0x00 +#define PMI8998_V2P0_REV3 0x00 +#define PMI8998_V2P0_REV4 0x02 /* PM8005 */ #define PM8005_SUBTYPE 0x18 diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 6848454c5447..5d0899df64ff 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -53,6 +53,8 @@ extern unsigned int sysctl_sched_spill_nr_run; extern unsigned int sysctl_sched_spill_load_pct; extern unsigned int sysctl_sched_upmigrate_pct; extern unsigned int sysctl_sched_downmigrate_pct; +extern unsigned int sysctl_sched_group_upmigrate_pct; +extern unsigned int sysctl_sched_group_downmigrate_pct; extern unsigned int sysctl_early_detection_duration; extern unsigned int sysctl_sched_boost; extern unsigned int sysctl_sched_small_wakee_task_load_pct; diff --git a/include/linux/usb.h b/include/linux/usb.h index 440248ba4123..7e6e4665212f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -395,6 +395,15 @@ struct usb_bus { struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif + unsigned skip_resume:1; /* All USB devices are brought into full + * power state after system resume. It + * is desirable for some buses to keep + * their devices in suspend state even + * after system resume. The devices + * are resumed later when a remote + * wakeup is detected or an interface + * driver starts I/O. + */ }; struct usb_dev_state; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b89c9c2f7f6e..cc1e8d6b3454 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -796,19 +796,15 @@ struct cfg80211_csa_settings { * @iftype_num: array with the number of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. - * @beacon_int_gcd: a value specifying GCD of all beaconing interfaces, - * the GCD of a single value is considered the value itself, so for - * a single interface this should be set to that interface's beacon - * interval - * @beacon_int_different: a flag indicating whether or not all beacon - * intervals (of beaconing interfaces) are different or not. + * @new_beacon_int: set this to the beacon interval of a new interface + * that's not operating yet, if such is to be checked as part of + * the verification */ struct iface_combination_params { int num_different_channels; u8 radar_detect; int iftype_num[NUM_NL80211_IFTYPES]; - u32 beacon_int_gcd; - bool beacon_int_different; + u32 new_beacon_int; }; /** @@ -3219,6 +3215,9 @@ struct wiphy_iftype_ext_capab { * @vht_capa_mod_mask: Specify what VHT capabilities can be over-ridden. * If null, then none can be over-ridden. * + * @wdev_list: the list of associated (virtual) interfaces; this list must + * not be modified by the driver, but can be read with RTNL/RCU protection. + * * @max_acl_mac_addrs: Maximum number of MAC addresses that the device * supports for ACL. * @@ -3363,6 +3362,8 @@ struct wiphy { const struct ieee80211_ht_cap *ht_capa_mod_mask; const struct ieee80211_vht_cap *vht_capa_mod_mask; + struct list_head wdev_list; + /* the network namespace this phy lives in currently */ possible_net_t _net; diff --git a/include/net/tcp.h b/include/net/tcp.h index 5ed36a59b08e..52402ab90c57 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1171,6 +1171,7 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp) } bool tcp_prequeue(struct sock *sk, struct sk_buff *skb); +int tcp_filter(struct sock *sk, struct sk_buff *skb); #undef STATE_TRACE @@ -1527,6 +1528,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli { if (sk->sk_send_head == skb_unlinked) sk->sk_send_head = NULL; + if (tcp_sk(sk)->highest_sack == skb_unlinked) + tcp_sk(sk)->highest_sack = NULL; } static inline void tcp_init_send_head(struct sock *sk) diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h index 76555ce53d97..5f1912a62267 100644 --- a/include/soc/qcom/socinfo.h +++ b/include/soc/qcom/socinfo.h @@ -88,10 +88,10 @@ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8996-cdp") #define early_machine_is_msm8929() \ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8929") -#define early_machine_is_msmcobalt() \ - of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msmcobalt") -#define early_machine_is_apqcobalt() \ - of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,apqcobalt") +#define early_machine_is_msm8998() \ + of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msm8998") +#define early_machine_is_apq8998() \ + of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,apq8998") #define early_machine_is_msmhamster() \ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msmhamster") #define early_machine_is_msmfalcon() \ @@ -131,8 +131,8 @@ #define early_machine_is_msm8996() 0 #define early_machine_is_msm8976() 0 #define early_machine_is_msm8929() 0 -#define early_machine_is_msmcobalt() 0 -#define early_machine_is_apqcobalt() 0 +#define early_machine_is_msm8998() 0 +#define early_machine_is_apq8998() 0 #define early_machine_is_msmhamster() 0 #define early_machine_is_msmfalcon() 0 #define early_machine_is_msmtriton() 0 @@ -192,7 +192,7 @@ enum msm_cpu { MSM_CPU_8996, MSM_CPU_8976, MSM_CPU_8929, - MSM_CPU_COBALT, + MSM_CPU_8998, MSM_CPU_HAMSTER, MSM_CPU_FALCON, MSM_CPU_TRITON, diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 7778ff3947de..72bbed9ad5db 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -133,6 +133,7 @@ TRACE_EVENT(sched_task_load, __field( u32, flags ) __field( int, best_cpu ) __field( u64, latency ) + __field( int, grp_id ) ), TP_fast_assign( @@ -148,12 +149,13 @@ TRACE_EVENT(sched_task_load, __entry->latency = p->state == TASK_WAKING ? sched_ktime_clock() - p->ravg.mark_start : 0; + __entry->grp_id = p->grp ? p->grp->id : 0; ), - TP_printk("%d (%s): demand=%u boost=%d reason=%d sync=%d need_idle=%d flags=%x best_cpu=%d latency=%llu", + TP_printk("%d (%s): demand=%u boost=%d reason=%d sync=%d need_idle=%d flags=%x grp=%d best_cpu=%d latency=%llu", __entry->pid, __entry->comm, __entry->demand, __entry->boost, __entry->reason, __entry->sync, - __entry->need_idle, __entry->flags, + __entry->need_idle, __entry->flags, __entry->grp_id, __entry->best_cpu, __entry->latency) ); @@ -164,9 +166,12 @@ TRACE_EVENT(sched_set_preferred_cluster, TP_ARGS(grp, total_demand), TP_STRUCT__entry( - __field( int, id ) - __field( u64, demand ) - __field( int, cluster_first_cpu ) + __field( int, id ) + __field( u64, demand ) + __field( int, cluster_first_cpu ) + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field(unsigned int, task_demand ) ), TP_fast_assign( @@ -245,19 +250,19 @@ DEFINE_EVENT(sched_cpu_load, sched_cpu_load_cgroup, TRACE_EVENT(sched_set_boost, - TP_PROTO(int ref_count), + TP_PROTO(int type), - TP_ARGS(ref_count), + TP_ARGS(type), TP_STRUCT__entry( - __field(unsigned int, ref_count ) + __field(int, type ) ), TP_fast_assign( - __entry->ref_count = ref_count; + __entry->type = type; ), - TP_printk("ref_count=%d", __entry->ref_count) + TP_printk("type %d", __entry->type) ); #if defined(CREATE_TRACE_POINTS) && defined(CONFIG_SCHED_HMP) diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index f0ac02e9c7a8..20b879c2e5fc 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -116,8 +116,8 @@ #define MDSS_MDP_HW_REV_114 MDSS_MDP_REV(1, 14, 0) /* 8937 v1.0 */ #define MDSS_MDP_HW_REV_115 MDSS_MDP_REV(1, 15, 0) /* msmgold */ #define MDSS_MDP_HW_REV_116 MDSS_MDP_REV(1, 16, 0) /* msmtitanium */ -#define MDSS_MDP_HW_REV_300 MDSS_MDP_REV(3, 0, 0) /* msmcobalt */ -#define MDSS_MDP_HW_REV_301 MDSS_MDP_REV(3, 0, 1) /* msmcobalt v1.0 */ +#define MDSS_MDP_HW_REV_300 MDSS_MDP_REV(3, 0, 0) /* msm8998 */ +#define MDSS_MDP_HW_REV_301 MDSS_MDP_REV(3, 0, 1) /* msm8998 v1.0 */ enum { NOTIFY_UPDATE_INIT, 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/include/uapi/media/msm_sde_rotator.h b/include/uapi/media/msm_sde_rotator.h index 12976e3f14d7..4487edf0c854 100644 --- a/include/uapi/media/msm_sde_rotator.h +++ b/include/uapi/media/msm_sde_rotator.h @@ -86,10 +86,4 @@ struct msm_sde_rotator_fence { /* SDE Rotator private control ID's */ #define V4L2_CID_SDE_ROTATOR_SECURE (V4L2_CID_USER_BASE + 0x1000) -/* - * This control Id indicates this context is associated with the - * secure camera - */ -#define V4L2_CID_SDE_ROTATOR_SECURE_CAMERA (V4L2_CID_USER_BASE + 0x2000) - #endif /* __UAPI_MSM_SDE_ROTATOR_H__ */ diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b86cc04959de..48f45987dc6c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -73,6 +73,7 @@ #include <linux/compat.h> #include <linux/ctype.h> #include <linux/string.h> +#include <linux/uaccess.h> #include <uapi/linux/limits.h> #include "audit.h" @@ -82,7 +83,8 @@ #define AUDITSC_SUCCESS 1 #define AUDITSC_FAILURE 2 -/* no execve audit message should be longer than this (userspace limits) */ +/* no execve audit message should be longer than this (userspace limits), + * see the note near the top of audit_log_execve_info() about this value */ #define MAX_EXECVE_AUDIT_LEN 7500 /* max length to print of cmdline/proctitle value during audit */ @@ -988,184 +990,178 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, return rc; } -/* - * to_send and len_sent accounting are very loose estimates. We aren't - * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being - * within about 500 bytes (next page boundary) - * - * why snprintf? an int is up to 12 digits long. if we just assumed when - * logging that a[%d]= was going to be 16 characters long we would be wasting - * space in every audit message. In one 7500 byte message we can log up to - * about 1000 min size arguments. That comes down to about 50% waste of space - * if we didn't do the snprintf to find out how long arg_num_len was. - */ -static int audit_log_single_execve_arg(struct audit_context *context, - struct audit_buffer **ab, - int arg_num, - size_t *len_sent, - const char __user *p, - char *buf) +static void audit_log_execve_info(struct audit_context *context, + struct audit_buffer **ab) { - char arg_num_len_buf[12]; - const char __user *tmp_p = p; - /* how many digits are in arg_num? 5 is the length of ' a=""' */ - size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5; - size_t len, len_left, to_send; - size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; - unsigned int i, has_cntl = 0, too_long = 0; - int ret; - - /* strnlen_user includes the null we don't want to send */ - len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1; - - /* - * We just created this mm, if we can't find the strings - * we just copied into it something is _very_ wrong. Similar - * for strings that are too long, we should not have created - * any. - */ - if (WARN_ON_ONCE(len < 0 || len > MAX_ARG_STRLEN - 1)) { - send_sig(SIGKILL, current, 0); - return -1; + long len_max; + long len_rem; + long len_full; + long len_buf; + long len_abuf; + long len_tmp; + bool require_data; + bool encode; + unsigned int iter; + unsigned int arg; + char *buf_head; + char *buf; + const char __user *p = (const char __user *)current->mm->arg_start; + + /* NOTE: this buffer needs to be large enough to hold all the non-arg + * data we put in the audit record for this argument (see the + * code below) ... at this point in time 96 is plenty */ + char abuf[96]; + + /* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the + * current value of 7500 is not as important as the fact that it + * is less than 8k, a setting of 7500 gives us plenty of wiggle + * room if we go over a little bit in the logging below */ + WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500); + len_max = MAX_EXECVE_AUDIT_LEN; + + /* scratch buffer to hold the userspace args */ + buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); + if (!buf_head) { + audit_panic("out of memory for argv string"); + return; } + buf = buf_head; - /* walk the whole argument looking for non-ascii chars */ + audit_log_format(*ab, "argc=%d", context->execve.argc); + + len_rem = len_max; + len_buf = 0; + len_full = 0; + require_data = true; + encode = false; + iter = 0; + arg = 0; do { - if (len_left > MAX_EXECVE_AUDIT_LEN) - to_send = MAX_EXECVE_AUDIT_LEN; - else - to_send = len_left; - ret = copy_from_user(buf, tmp_p, to_send); - /* - * There is no reason for this copy to be short. We just - * copied them here, and the mm hasn't been exposed to user- - * space yet. - */ - if (ret) { - WARN_ON(1); - send_sig(SIGKILL, current, 0); - return -1; - } - buf[to_send] = '\0'; - has_cntl = audit_string_contains_control(buf, to_send); - if (has_cntl) { - /* - * hex messages get logged as 2 bytes, so we can only - * send half as much in each message - */ - max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2; - break; - } - len_left -= to_send; - tmp_p += to_send; - } while (len_left > 0); - - len_left = len; - - if (len > max_execve_audit_len) - too_long = 1; - - /* rewalk the argument actually logging the message */ - for (i = 0; len_left > 0; i++) { - int room_left; - - if (len_left > max_execve_audit_len) - to_send = max_execve_audit_len; - else - to_send = len_left; - - /* do we have space left to send this argument in this ab? */ - room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; - if (has_cntl) - room_left -= (to_send * 2); - else - room_left -= to_send; - if (room_left < 0) { - *len_sent = 0; - audit_log_end(*ab); - *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE); - if (!*ab) - return 0; - } + /* NOTE: we don't ever want to trust this value for anything + * serious, but the audit record format insists we + * provide an argument length for really long arguments, + * e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but + * to use strncpy_from_user() to obtain this value for + * recording in the log, although we don't use it + * anywhere here to avoid a double-fetch problem */ + if (len_full == 0) + len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1; + + /* read more data from userspace */ + if (require_data) { + /* can we make more room in the buffer? */ + if (buf != buf_head) { + memmove(buf_head, buf, len_buf); + buf = buf_head; + } + + /* fetch as much as we can of the argument */ + len_tmp = strncpy_from_user(&buf_head[len_buf], p, + len_max - len_buf); + if (len_tmp == -EFAULT) { + /* unable to copy from userspace */ + send_sig(SIGKILL, current, 0); + goto out; + } else if (len_tmp == (len_max - len_buf)) { + /* buffer is not large enough */ + require_data = true; + /* NOTE: if we are going to span multiple + * buffers force the encoding so we stand + * a chance at a sane len_full value and + * consistent record encoding */ + encode = true; + len_full = len_full * 2; + p += len_tmp; + } else { + require_data = false; + if (!encode) + encode = audit_string_contains_control( + buf, len_tmp); + /* try to use a trusted value for len_full */ + if (len_full < len_max) + len_full = (encode ? + len_tmp * 2 : len_tmp); + p += len_tmp + 1; + } + len_buf += len_tmp; + buf_head[len_buf] = '\0'; - /* - * first record needs to say how long the original string was - * so we can be sure nothing was lost. - */ - if ((i == 0) && (too_long)) - audit_log_format(*ab, " a%d_len=%zu", arg_num, - has_cntl ? 2*len : len); - - /* - * normally arguments are small enough to fit and we already - * filled buf above when we checked for control characters - * so don't bother with another copy_from_user - */ - if (len >= max_execve_audit_len) - ret = copy_from_user(buf, p, to_send); - else - ret = 0; - if (ret) { - WARN_ON(1); - send_sig(SIGKILL, current, 0); - return -1; + /* length of the buffer in the audit record? */ + len_abuf = (encode ? len_buf * 2 : len_buf + 2); } - buf[to_send] = '\0'; - - /* actually log it */ - audit_log_format(*ab, " a%d", arg_num); - if (too_long) - audit_log_format(*ab, "[%d]", i); - audit_log_format(*ab, "="); - if (has_cntl) - audit_log_n_hex(*ab, buf, to_send); - else - audit_log_string(*ab, buf); - - p += to_send; - len_left -= to_send; - *len_sent += arg_num_len; - if (has_cntl) - *len_sent += to_send * 2; - else - *len_sent += to_send; - } - /* include the null we didn't log */ - return len + 1; -} -static void audit_log_execve_info(struct audit_context *context, - struct audit_buffer **ab) -{ - int i, len; - size_t len_sent = 0; - const char __user *p; - char *buf; + /* write as much as we can to the audit log */ + if (len_buf > 0) { + /* NOTE: some magic numbers here - basically if we + * can't fit a reasonable amount of data into the + * existing audit buffer, flush it and start with + * a new buffer */ + if ((sizeof(abuf) + 8) > len_rem) { + len_rem = len_max; + audit_log_end(*ab); + *ab = audit_log_start(context, + GFP_KERNEL, AUDIT_EXECVE); + if (!*ab) + goto out; + } - p = (const char __user *)current->mm->arg_start; + /* create the non-arg portion of the arg record */ + len_tmp = 0; + if (require_data || (iter > 0) || + ((len_abuf + sizeof(abuf)) > len_rem)) { + if (iter == 0) { + len_tmp += snprintf(&abuf[len_tmp], + sizeof(abuf) - len_tmp, + " a%d_len=%lu", + arg, len_full); + } + len_tmp += snprintf(&abuf[len_tmp], + sizeof(abuf) - len_tmp, + " a%d[%d]=", arg, iter++); + } else + len_tmp += snprintf(&abuf[len_tmp], + sizeof(abuf) - len_tmp, + " a%d=", arg); + WARN_ON(len_tmp >= sizeof(abuf)); + abuf[sizeof(abuf) - 1] = '\0'; + + /* log the arg in the audit record */ + audit_log_format(*ab, "%s", abuf); + len_rem -= len_tmp; + len_tmp = len_buf; + if (encode) { + if (len_abuf > len_rem) + len_tmp = len_rem / 2; /* encoding */ + audit_log_n_hex(*ab, buf, len_tmp); + len_rem -= len_tmp * 2; + len_abuf -= len_tmp * 2; + } else { + if (len_abuf > len_rem) + len_tmp = len_rem - 2; /* quotes */ + audit_log_n_string(*ab, buf, len_tmp); + len_rem -= len_tmp + 2; + /* don't subtract the "2" because we still need + * to add quotes to the remaining string */ + len_abuf -= len_tmp; + } + len_buf -= len_tmp; + buf += len_tmp; + } - audit_log_format(*ab, "argc=%d", context->execve.argc); + /* ready to move to the next argument? */ + if ((len_buf == 0) && !require_data) { + arg++; + iter = 0; + len_full = 0; + require_data = true; + encode = false; + } + } while (arg < context->execve.argc); - /* - * we need some kernel buffer to hold the userspace args. Just - * allocate one big one rather than allocating one of the right size - * for every single argument inside audit_log_single_execve_arg() - * should be <8k allocation so should be pretty safe. - */ - buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); - if (!buf) { - audit_panic("out of memory for argv string"); - return; - } + /* NOTE: the caller handles the final audit_log_end() call */ - for (i = 0; i < context->execve.argc; i++) { - len = audit_log_single_execve_arg(context, ab, i, - &len_sent, p, buf); - if (len <= 0) - break; - p += len; - } - kfree(buf); +out: + kfree(buf_head); } static void show_special(struct audit_context *context, int *call_panic) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ae83d9602aa0..8c9823947c7a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -6002,7 +6002,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) struct task_struct *task; int count = 0; - seq_printf(seq, "css_set %p\n", cset); + seq_printf(seq, "css_set %pK\n", cset); list_for_each_entry(task, &cset->tasks, cg_list) { if (count++ > MAX_TASKS_SHOWN_PER_CSS) diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 69c32c42080f..582b66e882ce 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -358,7 +358,11 @@ int pm_qos_update_target(struct pm_qos_constraints *c, spin_unlock_irqrestore(&pm_qos_lock, flags); trace_pm_qos_update_target(action, prev_value, curr_value); - if (prev_value != curr_value) { + /* + * if cpu mask bits are set, call the notifier call chain + * to update the new qos restriction for the cores + */ + if (!cpumask_empty(&cpus)) { ret = 1; if (c->notifiers) blocking_notifier_call_chain(c->notifiers, @@ -592,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; @@ -602,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); @@ -630,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/Makefile b/kernel/sched/Makefile index 7d0d34c53e08..7c0382a3eace 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile @@ -15,7 +15,7 @@ obj-y += core.o loadavg.o clock.o cputime.o obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o obj-y += wait.o completion.o idle.o sched_avg.o obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o -obj-$(CONFIG_SCHED_HMP) += hmp.o +obj-$(CONFIG_SCHED_HMP) += hmp.o boost.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o obj-$(CONFIG_SCHED_DEBUG) += debug.o diff --git a/kernel/sched/boost.c b/kernel/sched/boost.c new file mode 100644 index 000000000000..fcfda385b74a --- /dev/null +++ b/kernel/sched/boost.c @@ -0,0 +1,226 @@ +/* Copyright (c) 2012-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 + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sched.h" +#include <linux/of.h> +#include <linux/sched/core_ctl.h> +#include <trace/events/sched.h> + +/* + * Scheduler boost is a mechanism to temporarily place tasks on CPUs + * with higher capacity than those where a task would have normally + * ended up with their load characteristics. Any entity enabling + * boost is responsible for disabling it as well. + */ + +unsigned int sysctl_sched_boost; +static enum sched_boost_policy boost_policy; +static enum sched_boost_policy boost_policy_dt = SCHED_BOOST_NONE; +static DEFINE_MUTEX(boost_mutex); +static unsigned int freq_aggr_threshold_backup; + +static inline void boost_kick(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + + if (!test_and_set_bit(BOOST_KICK, &rq->hmp_flags)) + smp_send_reschedule(cpu); +} + +static void boost_kick_cpus(void) +{ + int i; + struct cpumask kick_mask; + + if (boost_policy != SCHED_BOOST_ON_BIG) + return; + + cpumask_andnot(&kick_mask, cpu_online_mask, cpu_isolated_mask); + + for_each_cpu(i, &kick_mask) { + if (cpu_capacity(i) != max_capacity) + boost_kick(i); + } +} + +int got_boost_kick(void) +{ + int cpu = smp_processor_id(); + struct rq *rq = cpu_rq(cpu); + + return test_bit(BOOST_KICK, &rq->hmp_flags); +} + +void clear_boost_kick(int cpu) +{ + struct rq *rq = cpu_rq(cpu); + + clear_bit(BOOST_KICK, &rq->hmp_flags); +} + +/* + * Scheduler boost type and boost policy might at first seem unrelated, + * however, there exists a connection between them that will allow us + * to use them interchangeably during placement decisions. We'll explain + * the connection here in one possible way so that the implications are + * clear when looking at placement policies. + * + * When policy = SCHED_BOOST_NONE, type is either none or RESTRAINED + * When policy = SCHED_BOOST_ON_ALL or SCHED_BOOST_ON_BIG, type can + * neither be none nor RESTRAINED. + */ +static void set_boost_policy(int type) +{ + if (type == SCHED_BOOST_NONE || type == RESTRAINED_BOOST) { + boost_policy = SCHED_BOOST_NONE; + return; + } + + if (boost_policy_dt) { + boost_policy = boost_policy_dt; + return; + } + + if (min_possible_efficiency != max_possible_efficiency) { + boost_policy = SCHED_BOOST_ON_BIG; + return; + } + + boost_policy = SCHED_BOOST_ON_ALL; +} + +enum sched_boost_policy sched_boost_policy(void) +{ + return boost_policy; +} + +static bool verify_boost_params(int old_val, int new_val) +{ + /* + * Boost can only be turned on or off. There is no possiblity of + * switching from one boost type to another or to set the same + * kind of boost several times. + */ + return !(!!old_val == !!new_val); +} + +static void _sched_set_boost(int old_val, int type) +{ + switch (type) { + case NO_BOOST: + if (old_val == FULL_THROTTLE_BOOST) + core_ctl_set_boost(false); + else if (old_val == CONSERVATIVE_BOOST) + restore_cgroup_boost_settings(); + else + update_freq_aggregate_threshold( + freq_aggr_threshold_backup); + break; + + case FULL_THROTTLE_BOOST: + core_ctl_set_boost(true); + boost_kick_cpus(); + break; + + case CONSERVATIVE_BOOST: + update_cgroup_boost_settings(); + boost_kick_cpus(); + break; + + case RESTRAINED_BOOST: + freq_aggr_threshold_backup = + update_freq_aggregate_threshold(1); + break; + + default: + WARN_ON(1); + return; + } + + set_boost_policy(type); + sysctl_sched_boost = type; + trace_sched_set_boost(type); +} + +void sched_boost_parse_dt(void) +{ + struct device_node *sn; + const char *boost_policy; + + if (!sched_enable_hmp) + return; + + sn = of_find_node_by_path("/sched-hmp"); + if (!sn) + return; + + if (!of_property_read_string(sn, "boost-policy", &boost_policy)) { + if (!strcmp(boost_policy, "boost-on-big")) + boost_policy_dt = SCHED_BOOST_ON_BIG; + else if (!strcmp(boost_policy, "boost-on-all")) + boost_policy_dt = SCHED_BOOST_ON_ALL; + } +} + +int sched_set_boost(int type) +{ + int ret = 0; + + if (!sched_enable_hmp) + return -EINVAL; + + mutex_lock(&boost_mutex); + + if (verify_boost_params(sysctl_sched_boost, type)) + _sched_set_boost(sysctl_sched_boost, type); + else + ret = -EINVAL; + + mutex_unlock(&boost_mutex); + return ret; +} + +int sched_boost_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + int ret; + unsigned int *data = (unsigned int *)table->data; + unsigned int old_val; + + if (!sched_enable_hmp) + return -EINVAL; + + mutex_lock(&boost_mutex); + + old_val = *data; + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write) + goto done; + + if (verify_boost_params(old_val, *data)) { + _sched_set_boost(old_val, *data); + } else { + *data = old_val; + ret = -EINVAL; + } + +done: + mutex_unlock(&boost_mutex); + return ret; +} + +int sched_boost(void) +{ + return sysctl_sched_boost; +} diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 84563da000cf..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; } @@ -7846,7 +7844,6 @@ void __init sched_init_smp(void) hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE); update_cluster_topology(); - init_sched_hmp_boost_policy(); init_hrtick(); @@ -7895,7 +7892,7 @@ void __init sched_init(void) BUG_ON(num_possible_cpus() > BITS_PER_LONG); - sched_hmp_parse_dt(); + sched_boost_parse_dt(); init_clusters(); #ifdef CONFIG_FAIR_GROUP_SCHED 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/fair.c b/kernel/sched/fair.c index 1674b1054f83..3db77aff2433 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2596,6 +2596,7 @@ static u32 __compute_runnable_contrib(u64 n) #define SBC_FLAG_COLOC_CLUSTER 0x10000 #define SBC_FLAG_WAKER_CLUSTER 0x20000 #define SBC_FLAG_BACKUP_CLUSTER 0x40000 +#define SBC_FLAG_BOOST_CLUSTER 0x80000 struct cpu_select_env { struct task_struct *p; @@ -2605,7 +2606,7 @@ struct cpu_select_env { u8 need_waker_cluster:1; u8 sync:1; u8 ignore_prev_cpu:1; - enum sched_boost_type boost_type; + enum sched_boost_policy boost_policy; int prev_cpu; DECLARE_BITMAP(candidate_list, NR_CPUS); DECLARE_BITMAP(backup_list, NR_CPUS); @@ -2705,10 +2706,38 @@ select_least_power_cluster(struct cpu_select_env *env) struct sched_cluster *cluster; if (env->rtg) { - env->task_load = scale_load_to_cpu(task_load(env->p), - cluster_first_cpu(env->rtg->preferred_cluster)); - env->sbc_best_cluster_flag |= SBC_FLAG_COLOC_CLUSTER; - return env->rtg->preferred_cluster; + int cpu = cluster_first_cpu(env->rtg->preferred_cluster); + + env->task_load = scale_load_to_cpu(task_load(env->p), cpu); + + if (task_load_will_fit(env->p, env->task_load, + cpu, env->boost_policy)) { + env->sbc_best_cluster_flag |= SBC_FLAG_COLOC_CLUSTER; + + if (env->boost_policy == SCHED_BOOST_NONE) + return env->rtg->preferred_cluster; + + for_each_sched_cluster(cluster) { + if (cluster != env->rtg->preferred_cluster) { + __set_bit(cluster->id, + env->backup_list); + __clear_bit(cluster->id, + env->candidate_list); + } + } + + return env->rtg->preferred_cluster; + } + + /* + * Since the task load does not fit on the preferred + * cluster anymore, pretend that the task does not + * have any preferred cluster. This allows the waking + * task to get the appropriate CPU it needs as per the + * non co-location placement policy without having to + * wait until the preferred cluster is updated. + */ + env->rtg = NULL; } for_each_sched_cluster(cluster) { @@ -2718,7 +2747,7 @@ select_least_power_cluster(struct cpu_select_env *env) env->task_load = scale_load_to_cpu(task_load(env->p), cpu); if (task_load_will_fit(env->p, env->task_load, cpu, - env->boost_type)) + env->boost_policy)) return cluster; __set_bit(cluster->id, env->backup_list); @@ -2961,7 +2990,14 @@ static void find_best_cpu_in_cluster(struct sched_cluster *c, update_spare_capacity(stats, env, i, c->capacity, env->cpu_load); - if (env->boost_type == SCHED_BOOST_ON_ALL || + /* + * need_idle takes precedence over sched boost but when both + * are set, idlest CPU with in all the clusters is selected + * when boost_policy = BOOST_ON_ALL whereas idlest CPU in the + * big cluster is selected within boost_policy = BOOST_ON_BIG. + */ + if ((!env->need_idle && + env->boost_policy != SCHED_BOOST_NONE) || env->need_waker_cluster || sched_cpu_high_irqload(i) || spill_threshold_crossed(env, cpu_rq(i))) @@ -3005,7 +3041,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats) struct task_struct *task = env->p; struct sched_cluster *cluster; - if (env->boost_type != SCHED_BOOST_NONE || env->reason || + if (env->boost_policy != SCHED_BOOST_NONE || env->reason || !task->ravg.mark_start || env->need_idle || !sched_short_sleep_task_threshold) return false; @@ -3034,7 +3070,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats) cluster = cpu_rq(prev_cpu)->cluster; if (!task_load_will_fit(task, env->task_load, prev_cpu, - sched_boost_type())) { + sched_boost_policy())) { __set_bit(cluster->id, env->backup_list); __clear_bit(cluster->id, env->candidate_list); @@ -3056,7 +3092,7 @@ bias_to_prev_cpu(struct cpu_select_env *env, struct cluster_cpu_stats *stats) static inline bool wake_to_waker_cluster(struct cpu_select_env *env) { - return env->boost_type == SCHED_BOOST_NONE && + return env->boost_policy == SCHED_BOOST_NONE && !env->need_idle && !env->reason && env->sync && task_load(current) > sched_big_waker_task_load && task_load(env->p) < sched_small_wakee_task_load; @@ -3098,7 +3134,6 @@ static int select_best_cpu(struct task_struct *p, int target, int reason, .reason = reason, .need_idle = wake_to_idle(p), .need_waker_cluster = 0, - .boost_type = sched_boost_type(), .sync = sync, .prev_cpu = target, .ignore_prev_cpu = 0, @@ -3107,6 +3142,9 @@ static int select_best_cpu(struct task_struct *p, int target, int reason, .sbc_best_cluster_flag = 0, }; + env.boost_policy = task_sched_boost(p) ? + sched_boost_policy() : SCHED_BOOST_NONE; + bitmap_copy(env.candidate_list, all_cluster_ids, NR_CPUS); bitmap_zero(env.backup_list, NR_CPUS); @@ -3178,12 +3216,23 @@ retry: sbc_flag |= env.sbc_best_flag; target = stats.best_cpu; } else { - if (env.rtg) { + if (env.rtg && env.boost_policy == SCHED_BOOST_NONE) { env.rtg = NULL; goto retry; } - find_backup_cluster(&env, &stats); + /* + * With boost_policy == SCHED_BOOST_ON_BIG, we reach here with + * backup_list = little cluster, candidate_list = none and + * stats->best_capacity_cpu points the best spare capacity + * CPU among the CPUs in the big cluster. + */ + if (env.boost_policy == SCHED_BOOST_ON_BIG && + stats.best_capacity_cpu >= 0) + sbc_flag |= SBC_FLAG_BOOST_CLUSTER; + else + find_backup_cluster(&env, &stats); + if (stats.best_capacity_cpu >= 0) { target = stats.best_capacity_cpu; sbc_flag |= SBC_FLAG_BEST_CAP_CPU; @@ -3193,8 +3242,8 @@ retry: out: sbc_flag |= env.sbc_best_cluster_flag; rcu_read_unlock(); - trace_sched_task_load(p, sched_boost(), env.reason, env.sync, - env.need_idle, sbc_flag, target); + trace_sched_task_load(p, sched_boost_policy() && task_sched_boost(p), + env.reason, env.sync, env.need_idle, sbc_flag, target); return target; } @@ -3402,11 +3451,9 @@ static inline int migration_needed(struct task_struct *p, int cpu) if (task_will_be_throttled(p)) return 0; - if (sched_boost_type() == SCHED_BOOST_ON_BIG) { - if (cpu_capacity(cpu) != max_capacity) - return UP_MIGRATION; - return 0; - } + if (sched_boost_policy() == SCHED_BOOST_ON_BIG && + cpu_capacity(cpu) != max_capacity && task_sched_boost(p)) + return UP_MIGRATION; if (sched_cpu_high_irqload(cpu)) return IRQLOAD_MIGRATION; @@ -3420,7 +3467,7 @@ static inline int migration_needed(struct task_struct *p, int cpu) return DOWN_MIGRATION; } - if (!grp && !task_will_fit(p, cpu)) { + if (!task_will_fit(p, cpu)) { rcu_read_unlock(); return UP_MIGRATION; } @@ -6648,10 +6695,7 @@ enum fbq_type { regular, remote, all }; #define LBF_NEED_BREAK 0x02 #define LBF_DST_PINNED 0x04 #define LBF_SOME_PINNED 0x08 -#define LBF_SCHED_BOOST_ACTIVE_BALANCE 0x40 #define LBF_BIG_TASK_ACTIVE_BALANCE 0x80 -#define LBF_HMP_ACTIVE_BALANCE (LBF_SCHED_BOOST_ACTIVE_BALANCE | \ - LBF_BIG_TASK_ACTIVE_BALANCE) #define LBF_IGNORE_BIG_TASKS 0x100 #define LBF_IGNORE_PREFERRED_CLUSTER_TASKS 0x200 #define LBF_MOVED_RELATED_THREAD_GROUP_TASK 0x400 @@ -6682,6 +6726,7 @@ struct lb_env { enum fbq_type fbq_type; struct list_head tasks; + enum sched_boost_policy boost_policy; }; /* @@ -6826,9 +6871,14 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) /* Record that we found atleast one task that could run on dst_cpu */ env->flags &= ~LBF_ALL_PINNED; - if (cpu_capacity(env->dst_cpu) > cpu_capacity(env->src_cpu) && - nr_big_tasks(env->src_rq) && !is_big_task(p)) - return 0; + if (cpu_capacity(env->dst_cpu) > cpu_capacity(env->src_cpu)) { + if (nr_big_tasks(env->src_rq) && !is_big_task(p)) + return 0; + + if (env->boost_policy == SCHED_BOOST_ON_BIG && + !task_sched_boost(p)) + return 0; + } twf = task_will_fit(p, env->dst_cpu); @@ -6951,8 +7001,7 @@ static int detach_tasks(struct lb_env *env) if (env->imbalance <= 0) return 0; - if (cpu_capacity(env->dst_cpu) < cpu_capacity(env->src_cpu) && - !sched_boost()) + if (cpu_capacity(env->dst_cpu) < cpu_capacity(env->src_cpu)) env->flags |= LBF_IGNORE_BIG_TASKS; else if (!same_cluster(env->dst_cpu, env->src_cpu)) env->flags |= LBF_IGNORE_PREFERRED_CLUSTER_TASKS; @@ -7255,8 +7304,10 @@ bail_inter_cluster_balance(struct lb_env *env, struct sd_lb_stats *sds) int local_capacity, busiest_capacity; int local_pwr_cost, busiest_pwr_cost; int nr_cpus; + int boost = sched_boost(); - if (!sysctl_sched_restrict_cluster_spill || sched_boost()) + if (!sysctl_sched_restrict_cluster_spill || + boost == FULL_THROTTLE_BOOST || boost == CONSERVATIVE_BOOST) return 0; local_cpu = group_first_cpu(sds->local); @@ -7628,11 +7679,6 @@ static bool update_sd_pick_busiest_active_balance(struct lb_env *env, { if (env->idle != CPU_NOT_IDLE && cpu_capacity(env->dst_cpu) > group_rq_capacity(sg)) { - if (sched_boost() && !sds->busiest && sgs->sum_nr_running) { - env->flags |= LBF_SCHED_BOOST_ACTIVE_BALANCE; - return true; - } - if (sgs->sum_nr_big_tasks > sds->busiest_stat.sum_nr_big_tasks) { env->flags |= LBF_BIG_TASK_ACTIVE_BALANCE; @@ -8045,7 +8091,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) if (!sds.busiest || busiest->sum_nr_running == 0) goto out_balanced; - if (env->flags & LBF_HMP_ACTIVE_BALANCE) + if (env->flags & LBF_BIG_TASK_ACTIVE_BALANCE) goto force_balance; if (bail_inter_cluster_balance(env, &sds)) @@ -8257,7 +8303,7 @@ static int need_active_balance(struct lb_env *env) { struct sched_domain *sd = env->sd; - if (env->flags & LBF_HMP_ACTIVE_BALANCE) + if (env->flags & LBF_BIG_TASK_ACTIVE_BALANCE) return 1; if (env->idle == CPU_NEWLY_IDLE) { @@ -8348,20 +8394,21 @@ static int load_balance(int this_cpu, struct rq *this_rq, struct cpumask *cpus = this_cpu_cpumask_var_ptr(load_balance_mask); struct lb_env env = { - .sd = sd, - .dst_cpu = this_cpu, - .dst_rq = this_rq, - .dst_grpmask = sched_group_cpus(sd->groups), - .idle = idle, - .loop_break = sched_nr_migrate_break, - .cpus = cpus, - .fbq_type = all, - .tasks = LIST_HEAD_INIT(env.tasks), - .imbalance = 0, - .flags = 0, - .loop = 0, + .sd = sd, + .dst_cpu = this_cpu, + .dst_rq = this_rq, + .dst_grpmask = sched_group_cpus(sd->groups), + .idle = idle, + .loop_break = sched_nr_migrate_break, + .cpus = cpus, + .fbq_type = all, + .tasks = LIST_HEAD_INIT(env.tasks), + .imbalance = 0, + .flags = 0, + .loop = 0, .busiest_nr_running = 0, .busiest_grp_capacity = 0, + .boost_policy = sched_boost_policy(), }; /* @@ -8510,7 +8557,7 @@ more_balance: no_move: if (!ld_moved) { - if (!(env.flags & LBF_HMP_ACTIVE_BALANCE)) + if (!(env.flags & LBF_BIG_TASK_ACTIVE_BALANCE)) schedstat_inc(sd, lb_failed[idle]); /* @@ -8520,7 +8567,7 @@ no_move: * excessive cache_hot migrations and active balances. */ if (idle != CPU_NEWLY_IDLE && - !(env.flags & LBF_HMP_ACTIVE_BALANCE)) + !(env.flags & LBF_BIG_TASK_ACTIVE_BALANCE)) sd->nr_balance_failed++; if (need_active_balance(&env)) { @@ -8797,6 +8844,7 @@ static int active_load_balance_cpu_stop(void *data) .busiest_grp_capacity = 0, .flags = 0, .loop = 0, + .boost_policy = sched_boost_policy(), }; bool moved = false; @@ -9272,7 +9320,8 @@ static inline int _nohz_kick_needed_hmp(struct rq *rq, int cpu, int *type) if (rq->nr_running < 2) return 0; - if (!sysctl_sched_restrict_cluster_spill || sched_boost()) + if (!sysctl_sched_restrict_cluster_spill || + sched_boost_policy() == SCHED_BOOST_ON_ALL) return 1; if (cpu_max_power_cost(cpu) == max_power_cost) diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 30391aae0822..a9ccb63c8e23 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -17,8 +17,6 @@ #include <linux/cpufreq.h> #include <linux/list_sort.h> #include <linux/syscore_ops.h> -#include <linux/of.h> -#include <linux/sched/core_ctl.h> #include "sched.h" @@ -231,52 +229,6 @@ fail: return ret; } -/* - * It is possible that CPUs of the same micro architecture can have slight - * difference in the efficiency due to other factors like cache size. The - * BOOST_ON_BIG policy may not be optimial for such systems. The required - * boost policy can be specified via device tree to handle this. - */ -static int __read_mostly sched_boost_policy = SCHED_BOOST_NONE; - -/* - * This should be called after clusters are populated and - * the respective efficiency values are initialized. - */ -void init_sched_hmp_boost_policy(void) -{ - /* - * Initialize the boost type here if it is not passed from - * device tree. - */ - if (sched_boost_policy == SCHED_BOOST_NONE) { - if (max_possible_efficiency != min_possible_efficiency) - sched_boost_policy = SCHED_BOOST_ON_BIG; - else - sched_boost_policy = SCHED_BOOST_ON_ALL; - } -} - -void sched_hmp_parse_dt(void) -{ - struct device_node *sn; - const char *boost_policy; - - if (!sched_enable_hmp) - return; - - sn = of_find_node_by_path("/sched-hmp"); - if (!sn) - return; - - if (!of_property_read_string(sn, "boost-policy", &boost_policy)) { - if (!strcmp(boost_policy, "boost-on-big")) - sched_boost_policy = SCHED_BOOST_ON_BIG; - else if (!strcmp(boost_policy, "boost-on-all")) - sched_boost_policy = SCHED_BOOST_ON_ALL; - } -} - unsigned int max_possible_efficiency = 1; unsigned int min_possible_efficiency = UINT_MAX; @@ -680,29 +632,6 @@ int __init set_sched_enable_hmp(char *str) early_param("sched_enable_hmp", set_sched_enable_hmp); -int got_boost_kick(void) -{ - int cpu = smp_processor_id(); - struct rq *rq = cpu_rq(cpu); - - return test_bit(BOOST_KICK, &rq->hmp_flags); -} - -inline void clear_boost_kick(int cpu) -{ - struct rq *rq = cpu_rq(cpu); - - clear_bit(BOOST_KICK, &rq->hmp_flags); -} - -inline void boost_kick(int cpu) -{ - struct rq *rq = cpu_rq(cpu); - - if (!test_and_set_bit(BOOST_KICK, &rq->hmp_flags)) - smp_send_reschedule(cpu); -} - /* Clear any HMP scheduler related requests pending from or on cpu */ void clear_hmp_request(int cpu) { @@ -712,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); } } @@ -840,6 +773,9 @@ min_max_possible_capacity = 1024; /* min(rq->max_possible_capacity) */ /* Window size (in ns) */ __read_mostly unsigned int sched_ravg_window = MIN_SCHED_RAVG_WINDOW; +/* Maximum allowed threshold before freq aggregation must be enabled */ +#define MAX_FREQ_AGGR_THRESH 1000 + /* Temporarily disable window-stats activity on all cpus */ unsigned int __read_mostly sched_disable_window_stats; @@ -919,8 +855,8 @@ static const unsigned int top_tasks_bitmap_size = * C1 busy time = 5 + 5 + 6 = 16ms * */ -static __read_mostly unsigned int sched_freq_aggregate; -__read_mostly unsigned int sysctl_sched_freq_aggregate; +static __read_mostly unsigned int sched_freq_aggregate = 1; +__read_mostly unsigned int sysctl_sched_freq_aggregate = 1; unsigned int __read_mostly sysctl_sched_freq_aggregate_threshold_pct; static unsigned int __read_mostly sched_freq_aggregate_threshold; @@ -937,14 +873,6 @@ unsigned int max_task_load(void) /* Use this knob to turn on or off HMP-aware task placement logic */ unsigned int __read_mostly sched_enable_hmp; -/* - * Scheduler boost is a mechanism to temporarily place tasks on CPUs - * with higher capacity than those where a task would have normally - * ended up with their load characteristics. Any entity enabling - * boost is responsible for disabling it as well. - */ -unsigned int sysctl_sched_boost; - /* A cpu can no longer accommodate more tasks if: * * rq->nr_running > sysctl_sched_spill_nr_run || @@ -996,6 +924,21 @@ unsigned int __read_mostly sched_downmigrate; unsigned int __read_mostly sysctl_sched_downmigrate_pct = 60; /* + * Task groups whose aggregate demand on a cpu is more than + * sched_group_upmigrate need to be up-migrated if possible. + */ +unsigned int __read_mostly sched_group_upmigrate; +unsigned int __read_mostly sysctl_sched_group_upmigrate_pct = 100; + +/* + * Task groups, once up-migrated, will need to drop their aggregate + * demand to less than sched_group_downmigrate before they are "down" + * migrated. + */ +unsigned int __read_mostly sched_group_downmigrate; +unsigned int __read_mostly sysctl_sched_group_downmigrate_pct = 95; + +/* * The load scale factor of a CPU gets boosted when its max frequency * is restricted due to which the tasks are migrating to higher capacity * CPUs early. The sched_upmigrate threshold is auto-upgraded by @@ -1017,33 +960,46 @@ sched_long_cpu_selection_threshold = 100 * NSEC_PER_MSEC; unsigned int __read_mostly sysctl_sched_restrict_cluster_spill; -void update_up_down_migrate(void) +static void +_update_up_down_migrate(unsigned int *up_migrate, unsigned int *down_migrate) { - unsigned int up_migrate = pct_to_real(sysctl_sched_upmigrate_pct); - unsigned int down_migrate = pct_to_real(sysctl_sched_downmigrate_pct); unsigned int delta; if (up_down_migrate_scale_factor == 1024) - goto done; + return; - delta = up_migrate - down_migrate; + delta = *up_migrate - *down_migrate; - up_migrate /= NSEC_PER_USEC; - up_migrate *= up_down_migrate_scale_factor; - up_migrate >>= 10; - up_migrate *= NSEC_PER_USEC; + *up_migrate /= NSEC_PER_USEC; + *up_migrate *= up_down_migrate_scale_factor; + *up_migrate >>= 10; + *up_migrate *= NSEC_PER_USEC; - up_migrate = min(up_migrate, sched_ravg_window); + *up_migrate = min(*up_migrate, sched_ravg_window); - down_migrate /= NSEC_PER_USEC; - down_migrate *= up_down_migrate_scale_factor; - down_migrate >>= 10; - down_migrate *= NSEC_PER_USEC; + *down_migrate /= NSEC_PER_USEC; + *down_migrate *= up_down_migrate_scale_factor; + *down_migrate >>= 10; + *down_migrate *= NSEC_PER_USEC; - down_migrate = min(down_migrate, up_migrate - delta); -done: + *down_migrate = min(*down_migrate, *up_migrate - delta); +} + +static void update_up_down_migrate(void) +{ + unsigned int up_migrate = pct_to_real(sysctl_sched_upmigrate_pct); + unsigned int down_migrate = pct_to_real(sysctl_sched_downmigrate_pct); + + _update_up_down_migrate(&up_migrate, &down_migrate); sched_upmigrate = up_migrate; sched_downmigrate = down_migrate; + + up_migrate = pct_to_real(sysctl_sched_group_upmigrate_pct); + down_migrate = pct_to_real(sysctl_sched_group_downmigrate_pct); + + _update_up_down_migrate(&up_migrate, &down_migrate); + sched_group_upmigrate = up_migrate; + sched_group_downmigrate = down_migrate; } void set_hmp_defaults(void) @@ -1134,82 +1090,6 @@ u64 cpu_load_sync(int cpu, int sync) return scale_load_to_cpu(cpu_cravg_sync(cpu, sync), cpu); } -static int boost_refcount; -static DEFINE_SPINLOCK(boost_lock); -static DEFINE_MUTEX(boost_mutex); - -static void boost_kick_cpus(void) -{ - int i; - - for_each_online_cpu(i) { - if (cpu_capacity(i) != max_capacity) - boost_kick(i); - } -} - -int sched_boost(void) -{ - return boost_refcount > 0; -} - -int sched_set_boost(int enable) -{ - unsigned long flags; - int ret = 0; - int old_refcount; - - if (!sched_enable_hmp) - return -EINVAL; - - spin_lock_irqsave(&boost_lock, flags); - - old_refcount = boost_refcount; - - if (enable == 1) { - boost_refcount++; - } else if (!enable) { - if (boost_refcount >= 1) - boost_refcount--; - else - ret = -EINVAL; - } else { - ret = -EINVAL; - } - - if (!old_refcount && boost_refcount) - boost_kick_cpus(); - - if (boost_refcount <= 1) - core_ctl_set_boost(boost_refcount == 1); - trace_sched_set_boost(boost_refcount); - spin_unlock_irqrestore(&boost_lock, flags); - - return ret; -} - -int sched_boost_handler(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret; - - mutex_lock(&boost_mutex); - if (!write) - sysctl_sched_boost = sched_boost(); - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (ret || !write) - goto done; - - ret = (sysctl_sched_boost <= 1) ? - sched_set_boost(sysctl_sched_boost) : -EINVAL; - -done: - mutex_unlock(&boost_mutex); - return ret; -} - /* * Task will fit on a cpu if it's bandwidth consumption on that cpu * will be less than sched_upmigrate. A big task that was previously @@ -1219,60 +1099,63 @@ done: * tasks with load close to the upmigrate threshold */ int task_load_will_fit(struct task_struct *p, u64 task_load, int cpu, - enum sched_boost_type boost_type) + enum sched_boost_policy boost_policy) { - int upmigrate; + int upmigrate = sched_upmigrate; if (cpu_capacity(cpu) == max_capacity) return 1; - if (boost_type != SCHED_BOOST_ON_BIG) { + if (cpu_capacity(task_cpu(p)) > cpu_capacity(cpu)) + upmigrate = sched_downmigrate; + + if (boost_policy != SCHED_BOOST_ON_BIG) { if (task_nice(p) > SCHED_UPMIGRATE_MIN_NICE || upmigrate_discouraged(p)) return 1; - upmigrate = sched_upmigrate; - if (cpu_capacity(task_cpu(p)) > cpu_capacity(cpu)) - upmigrate = sched_downmigrate; - if (task_load < upmigrate) return 1; + } else { + if (task_sched_boost(p) || task_load >= upmigrate) + return 0; + + return 1; } return 0; } -enum sched_boost_type sched_boost_type(void) -{ - if (sched_boost()) - return sched_boost_policy; - - return SCHED_BOOST_NONE; -} - int task_will_fit(struct task_struct *p, int cpu) { u64 tload = scale_load_to_cpu(task_load(p), cpu); - return task_load_will_fit(p, tload, cpu, sched_boost_type()); + return task_load_will_fit(p, tload, cpu, sched_boost_policy()); } -int group_will_fit(struct sched_cluster *cluster, - struct related_thread_group *grp, u64 demand) +static int +group_will_fit(struct sched_cluster *cluster, struct related_thread_group *grp, + u64 demand, bool group_boost) { int cpu = cluster_first_cpu(cluster); int prev_capacity = 0; - unsigned int threshold = sched_upmigrate; + unsigned int threshold = sched_group_upmigrate; u64 load; if (cluster->capacity == max_capacity) return 1; + if (group_boost) + return 0; + + if (!demand) + return 1; + if (grp->preferred_cluster) prev_capacity = grp->preferred_cluster->capacity; if (cluster->capacity < prev_capacity) - threshold = sched_downmigrate; + threshold = sched_group_downmigrate; load = scale_load_to_cpu(demand, cpu); if (load < threshold) @@ -1495,6 +1378,23 @@ void post_big_task_count_change(const struct cpumask *cpus) DEFINE_MUTEX(policy_mutex); +unsigned int update_freq_aggregate_threshold(unsigned int threshold) +{ + unsigned int old_threshold; + + mutex_lock(&policy_mutex); + + old_threshold = sysctl_sched_freq_aggregate_threshold_pct; + + sysctl_sched_freq_aggregate_threshold_pct = threshold; + sched_freq_aggregate_threshold = + pct_to_real(sysctl_sched_freq_aggregate_threshold_pct); + + mutex_unlock(&policy_mutex); + + return old_threshold; +} + static inline int invalid_value_freq_input(unsigned int *data) { if (data == &sysctl_sched_freq_aggregate) @@ -1578,7 +1478,9 @@ int sched_hmp_proc_update_handler(struct ctl_table *table, int write, if (write && (old_val == *data)) goto done; - if (sysctl_sched_downmigrate_pct > sysctl_sched_upmigrate_pct) { + if (sysctl_sched_downmigrate_pct > sysctl_sched_upmigrate_pct || + sysctl_sched_group_downmigrate_pct > + sysctl_sched_group_upmigrate_pct) { *data = old_val; ret = -EINVAL; goto done; @@ -3110,37 +3012,9 @@ static void reset_all_task_stats(void) { struct task_struct *g, *p; - read_lock(&tasklist_lock); do_each_thread(g, p) { - raw_spin_lock_irq(&p->pi_lock); reset_task_stats(p); - raw_spin_unlock_irq(&p->pi_lock); } while_each_thread(g, p); - read_unlock(&tasklist_lock); -} - -static void disable_window_stats(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for_each_possible_cpu(i) - raw_spin_lock(&cpu_rq(i)->lock); - - sched_disable_window_stats = 1; - - for_each_possible_cpu(i) - raw_spin_unlock(&cpu_rq(i)->lock); - - local_irq_restore(flags); -} - -/* Called with all cpu's rq->lock held */ -static void enable_window_stats(void) -{ - sched_disable_window_stats = 0; - } enum reset_reason_code { @@ -3166,17 +3040,22 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size) unsigned int old = 0, new = 0; struct related_thread_group *grp; - read_lock(&related_thread_group_lock); - - disable_window_stats(); + local_irq_save(flags); - reset_all_task_stats(); + read_lock(&tasklist_lock); - local_irq_save(flags); + read_lock(&related_thread_group_lock); + /* Taking all runqueue locks prevents race with sched_exit(). */ for_each_possible_cpu(cpu) raw_spin_lock(&cpu_rq(cpu)->lock); + sched_disable_window_stats = 1; + + reset_all_task_stats(); + + read_unlock(&tasklist_lock); + list_for_each_entry(grp, &related_thread_groups, list) { int j; @@ -3196,7 +3075,7 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size) sched_load_granule = sched_ravg_window / NUM_LOAD_INDICES; } - enable_window_stats(); + sched_disable_window_stats = 0; for_each_possible_cpu(cpu) { struct rq *rq = cpu_rq(cpu); @@ -3239,10 +3118,10 @@ void reset_all_window_stats(u64 window_start, unsigned int window_size) for_each_possible_cpu(cpu) raw_spin_unlock(&cpu_rq(cpu)->lock); - local_irq_restore(flags); - read_unlock(&related_thread_group_lock); + local_irq_restore(flags); + trace_sched_reset_all_window_stats(window_start, window_size, sched_ktime_clock() - start_ts, reason, old, new); } @@ -3824,13 +3703,13 @@ static void check_for_up_down_migrate_update(const struct cpumask *cpus) } /* Return cluster which can offer required capacity for group */ -static struct sched_cluster * -best_cluster(struct related_thread_group *grp, u64 total_demand) +static struct sched_cluster *best_cluster(struct related_thread_group *grp, + u64 total_demand, bool group_boost) { struct sched_cluster *cluster = NULL; for_each_sched_cluster(cluster) { - if (group_will_fit(cluster, grp, total_demand)) + if (group_will_fit(cluster, grp, total_demand, group_boost)) return cluster; } @@ -3841,6 +3720,9 @@ static void _set_preferred_cluster(struct related_thread_group *grp) { struct task_struct *p; u64 combined_demand = 0; + bool boost_on_big = sched_boost_policy() == SCHED_BOOST_ON_BIG; + bool group_boost = false; + u64 wallclock; if (!sysctl_sched_enable_colocation) { grp->last_update = sched_ktime_clock(); @@ -3848,31 +3730,43 @@ static void _set_preferred_cluster(struct related_thread_group *grp) return; } + if (list_empty(&grp->tasks)) + return; + + wallclock = sched_ktime_clock(); + /* * wakeup of two or more related tasks could race with each other and * could result in multiple calls to _set_preferred_cluster being issued * at same time. Avoid overhead in such cases of rechecking preferred * cluster */ - if (sched_ktime_clock() - grp->last_update < sched_ravg_window / 10) + if (wallclock - grp->last_update < sched_ravg_window / 10) return; - list_for_each_entry(p, &grp->tasks, grp_list) + list_for_each_entry(p, &grp->tasks, grp_list) { + if (boost_on_big && task_sched_boost(p)) { + group_boost = true; + break; + } + + if (p->ravg.mark_start < wallclock - + (sched_ravg_window * sched_ravg_hist_size)) + continue; + combined_demand += p->ravg.demand; - grp->preferred_cluster = best_cluster(grp, combined_demand); + } + + grp->preferred_cluster = best_cluster(grp, + combined_demand, group_boost); grp->last_update = sched_ktime_clock(); trace_sched_set_preferred_cluster(grp, combined_demand); } void set_preferred_cluster(struct related_thread_group *grp) { - /* - * Prevent possible deadlock with update_children(). Not updating - * the preferred cluster once is not a big deal. - */ - if (!raw_spin_trylock(&grp->lock)) - return; + raw_spin_lock(&grp->lock); _set_preferred_cluster(grp); raw_spin_unlock(&grp->lock); } @@ -3880,6 +3774,8 @@ void set_preferred_cluster(struct related_thread_group *grp) #define ADD_TASK 0 #define REM_TASK 1 +#define DEFAULT_CGROUP_COLOC_ID 1 + static inline void free_group_cputime(struct related_thread_group *grp) { free_percpu(grp->cpu_time); @@ -4116,64 +4012,19 @@ static void free_related_thread_group(struct rcu_head *rcu) kfree(grp); } -/* - * The thread group for a task can change while we are here. However, - * add_new_task_to_grp() will take care of any tasks that we miss here. - * When a parent exits, and a child thread is simultaneously exiting, - * sched_set_group_id() will synchronize those operations. - */ -static void update_children(struct task_struct *leader, - struct related_thread_group *grp, int event) -{ - struct task_struct *child; - struct rq *rq; - unsigned long flags; - - if (!thread_group_leader(leader)) - return; - - if (event == ADD_TASK && !sysctl_sched_enable_thread_grouping) - return; - - if (thread_group_empty(leader)) - return; - - child = next_thread(leader); - - do { - rq = task_rq_lock(child, &flags); - - if (event == REM_TASK && child->grp && grp == child->grp) { - transfer_busy_time(rq, grp, child, event); - list_del_init(&child->grp_list); - rcu_assign_pointer(child->grp, NULL); - } else if (event == ADD_TASK && !child->grp) { - transfer_busy_time(rq, grp, child, event); - list_add(&child->grp_list, &grp->tasks); - rcu_assign_pointer(child->grp, grp); - } - - task_rq_unlock(rq, child, &flags); - } while_each_thread(leader, child); - -} - static void remove_task_from_group(struct task_struct *p) { struct related_thread_group *grp = p->grp; struct rq *rq; int empty_group = 1; - unsigned long flags; raw_spin_lock(&grp->lock); - rq = task_rq_lock(p, &flags); + rq = __task_rq_lock(p); transfer_busy_time(rq, p->grp, p, REM_TASK); list_del_init(&p->grp_list); rcu_assign_pointer(p->grp, NULL); - task_rq_unlock(rq, p, &flags); - - update_children(p, grp, REM_TASK); + __task_rq_unlock(rq); if (!list_empty(&grp->tasks)) { empty_group = 0; @@ -4182,7 +4033,8 @@ static void remove_task_from_group(struct task_struct *p) raw_spin_unlock(&grp->lock); - if (empty_group) { + /* Reserved groups cannot be destroyed */ + if (empty_group && grp->id != DEFAULT_CGROUP_COLOC_ID) { list_del(&grp->list); call_rcu(&grp->rcu, free_related_thread_group); } @@ -4192,7 +4044,6 @@ static int add_task_to_group(struct task_struct *p, struct related_thread_group *grp) { struct rq *rq; - unsigned long flags; raw_spin_lock(&grp->lock); @@ -4200,13 +4051,11 @@ add_task_to_group(struct task_struct *p, struct related_thread_group *grp) * Change p->grp under rq->lock. Will prevent races with read-side * reference of p->grp in various hot-paths */ - rq = task_rq_lock(p, &flags); + rq = __task_rq_lock(p); transfer_busy_time(rq, grp, p, ADD_TASK); list_add(&p->grp_list, &grp->tasks); rcu_assign_pointer(p->grp, grp); - task_rq_unlock(rq, p, &flags); - - update_children(p, grp, ADD_TASK); + __task_rq_unlock(rq); _set_preferred_cluster(grp); @@ -4219,23 +4068,33 @@ void add_new_task_to_grp(struct task_struct *new) { unsigned long flags; struct related_thread_group *grp; - struct task_struct *parent; + struct task_struct *leader = new->group_leader; + unsigned int leader_grp_id = sched_get_group_id(leader); - if (!sysctl_sched_enable_thread_grouping) + if (!sysctl_sched_enable_thread_grouping && + leader_grp_id != DEFAULT_CGROUP_COLOC_ID) return; if (thread_group_leader(new)) return; - parent = new->group_leader; + if (leader_grp_id == DEFAULT_CGROUP_COLOC_ID) { + if (!same_schedtune(new, leader)) + return; + } write_lock_irqsave(&related_thread_group_lock, flags); rcu_read_lock(); - grp = task_related_thread_group(parent); + grp = task_related_thread_group(leader); rcu_read_unlock(); - /* Its possible that update_children() already added us to the group */ + /* + * It's possible that someone already added the new task to the + * group. A leader's thread group is updated prior to calling + * this function. It's also possible that the leader has exited + * the group. In either case, there is nothing else to do. + */ if (!grp || new->grp) { write_unlock_irqrestore(&related_thread_group_lock, flags); return; @@ -4250,14 +4109,55 @@ void add_new_task_to_grp(struct task_struct *new) write_unlock_irqrestore(&related_thread_group_lock, flags); } +#if defined(CONFIG_SCHED_TUNE) && defined(CONFIG_CGROUP_SCHEDTUNE) +/* + * We create a default colocation group at boot. There is no need to + * synchronize tasks between cgroups at creation time because the + * correct cgroup hierarchy is not available at boot. Therefore cgroup + * colocation is turned off by default even though the colocation group + * itself has been allocated. Furthermore this colocation group cannot + * be destroyted once it has been created. All of this has been as part + * of runtime optimizations. + * + * The job of synchronizing tasks to the colocation group is done when + * the colocation flag in the cgroup is turned on. + */ +static int __init create_default_coloc_group(void) +{ + struct related_thread_group *grp = NULL; + unsigned long flags; + + grp = alloc_related_thread_group(DEFAULT_CGROUP_COLOC_ID); + if (IS_ERR(grp)) { + WARN_ON(1); + return -ENOMEM; + } + + write_lock_irqsave(&related_thread_group_lock, flags); + list_add(&grp->list, &related_thread_groups); + write_unlock_irqrestore(&related_thread_group_lock, flags); + + update_freq_aggregate_threshold(MAX_FREQ_AGGR_THRESH); + return 0; +} +late_initcall(create_default_coloc_group); + +int sync_cgroup_colocation(struct task_struct *p, bool insert) +{ + unsigned int grp_id = insert ? DEFAULT_CGROUP_COLOC_ID : 0; + + return sched_set_group_id(p, grp_id); +} +#endif + int sched_set_group_id(struct task_struct *p, unsigned int group_id) { int rc = 0; unsigned long flags; struct related_thread_group *grp = NULL; - /* Prevents tasks from exiting while we are managing groups. */ - write_lock_irqsave(&related_thread_group_lock, flags); + raw_spin_lock_irqsave(&p->pi_lock, flags); + write_lock(&related_thread_group_lock); /* Switching from one group to another directly is not permitted */ if ((current != p && p->flags & PF_EXITING) || @@ -4272,6 +4172,12 @@ int sched_set_group_id(struct task_struct *p, unsigned int group_id) grp = lookup_related_thread_group(group_id); if (!grp) { + /* This is a reserved id */ + if (group_id == DEFAULT_CGROUP_COLOC_ID) { + rc = -EINVAL; + goto done; + } + grp = alloc_related_thread_group(group_id); if (IS_ERR(grp)) { rc = -ENOMEM; @@ -4281,10 +4187,10 @@ int sched_set_group_id(struct task_struct *p, unsigned int group_id) list_add(&grp->list, &related_thread_groups); } - BUG_ON(!grp); rc = add_task_to_group(p, grp); done: - write_unlock_irqrestore(&related_thread_group_lock, flags); + write_unlock(&related_thread_group_lock); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); return rc; } @@ -4529,7 +4435,7 @@ bool early_detection_notify(struct rq *rq, u64 wallclock) struct task_struct *p; int loop_max = 10; - if (!sched_boost() || !rq->cfs.h_nr_running) + if (sched_boost_policy() == SCHED_BOOST_NONE || !rq->cfs.h_nr_running) return 0; rq->ed_task = NULL; diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index ba4403e910d8..12a04f30ef77 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1677,8 +1677,13 @@ static int find_lowest_rq_hmp(struct task_struct *task) int prev_cpu = task_cpu(task); u64 cpu_load, min_load = ULLONG_MAX; int i; - int restrict_cluster = sched_boost() ? 0 : - sysctl_sched_restrict_cluster_spill; + int restrict_cluster; + int boost_on_big; + + boost_on_big = sched_boost() == FULL_THROTTLE_BOOST && + sched_boost_policy() == SCHED_BOOST_ON_BIG; + + restrict_cluster = sysctl_sched_restrict_cluster_spill; /* Make sure the mask is initialized first */ if (unlikely(!lowest_mask)) @@ -1697,6 +1702,9 @@ static int find_lowest_rq_hmp(struct task_struct *task) */ for_each_sched_cluster(cluster) { + if (boost_on_big && cluster->capacity != max_possible_capacity) + continue; + cpumask_and(&candidate_mask, &cluster->cpus, lowest_mask); cpumask_andnot(&candidate_mask, &candidate_mask, cpu_isolated_mask); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 4289bf6cd642..30838bb9b442 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1061,8 +1061,6 @@ extern unsigned int max_load_scale_factor; extern unsigned int max_possible_capacity; extern unsigned int min_max_possible_capacity; extern unsigned int max_power_cost; -extern unsigned int sched_upmigrate; -extern unsigned int sched_downmigrate; extern unsigned int sched_init_task_load_windows; extern unsigned int up_down_migrate_scale_factor; extern unsigned int sysctl_sched_restrict_cluster_spill; @@ -1106,18 +1104,23 @@ extern void sched_account_irqstart(int cpu, struct task_struct *curr, u64 wallclock); extern unsigned int cpu_temp(int cpu); extern unsigned int nr_eligible_big_tasks(int cpu); -extern void update_up_down_migrate(void); extern int update_preferred_cluster(struct related_thread_group *grp, struct task_struct *p, u32 old_load); extern void set_preferred_cluster(struct related_thread_group *grp); extern void add_new_task_to_grp(struct task_struct *new); +extern unsigned int update_freq_aggregate_threshold(unsigned int threshold); -enum sched_boost_type { +enum sched_boost_policy { SCHED_BOOST_NONE, SCHED_BOOST_ON_BIG, SCHED_BOOST_ON_ALL, }; +#define NO_BOOST 0 +#define FULL_THROTTLE_BOOST 1 +#define CONSERVATIVE_BOOST 2 +#define RESTRAINED_BOOST 3 + static inline struct sched_cluster *cpu_cluster(int cpu) { return cpu_rq(cpu)->cluster; @@ -1387,14 +1390,11 @@ extern void set_hmp_defaults(void); extern int power_delta_exceeded(unsigned int cpu_cost, unsigned int base_cost); extern unsigned int power_cost(int cpu, u64 demand); extern void reset_all_window_stats(u64 window_start, unsigned int window_size); -extern void boost_kick(int cpu); extern int sched_boost(void); extern int task_load_will_fit(struct task_struct *p, u64 task_load, int cpu, - enum sched_boost_type boost_type); -extern enum sched_boost_type sched_boost_type(void); + enum sched_boost_policy boost_policy); +extern enum sched_boost_policy sched_boost_policy(void); extern int task_will_fit(struct task_struct *p, int cpu); -extern int group_will_fit(struct sched_cluster *cluster, - struct related_thread_group *grp, u64 demand); extern u64 cpu_load(int cpu); extern u64 cpu_load_sync(int cpu, int sync); extern int preferred_cluster(struct sched_cluster *cluster, @@ -1422,10 +1422,32 @@ extern u64 cpu_upmigrate_discourage_read_u64(struct cgroup_subsys_state *css, struct cftype *cft); extern int cpu_upmigrate_discourage_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, u64 upmigrate_discourage); -extern void sched_hmp_parse_dt(void); -extern void init_sched_hmp_boost_policy(void); +extern void sched_boost_parse_dt(void); extern void clear_top_tasks_bitmap(unsigned long *bitmap); +#if defined(CONFIG_SCHED_TUNE) && defined(CONFIG_CGROUP_SCHEDTUNE) +extern bool task_sched_boost(struct task_struct *p); +extern int sync_cgroup_colocation(struct task_struct *p, bool insert); +extern bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2); +extern void update_cgroup_boost_settings(void); +extern void restore_cgroup_boost_settings(void); + +#else +static inline bool +same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2) +{ + return true; +} + +static inline bool task_sched_boost(struct task_struct *p) +{ + return true; +} + +static inline void update_cgroup_boost_settings(void) { } +static inline void restore_cgroup_boost_settings(void) { } +#endif + #else /* CONFIG_SCHED_HMP */ struct hmp_sched_stats; @@ -1615,8 +1637,7 @@ static inline void post_big_task_count_change(void) { } static inline void set_hmp_defaults(void) { } static inline void clear_reserved(int cpu) { } -static inline void sched_hmp_parse_dt(void) {} -static inline void init_sched_hmp_boost_policy(void) {} +static inline void sched_boost_parse_dt(void) {} #define trace_sched_cpu_load(...) #define trace_sched_cpu_load_lb(...) diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c index 4f8182302e5e..ee2af8e0b5ce 100644 --- a/kernel/sched/tune.c +++ b/kernel/sched/tune.c @@ -25,6 +25,33 @@ struct schedtune { /* Boost value for tasks on that SchedTune CGroup */ int boost; +#ifdef CONFIG_SCHED_HMP + /* Toggle ability to override sched boost enabled */ + bool sched_boost_no_override; + + /* + * Controls whether a cgroup is eligible for sched boost or not. This + * can temporariliy be disabled by the kernel based on the no_override + * flag above. + */ + bool sched_boost_enabled; + + /* + * This tracks the default value of sched_boost_enabled and is used + * restore the value following any temporary changes to that flag. + */ + bool sched_boost_enabled_backup; + + /* + * Controls whether tasks of this cgroup should be colocated with each + * other and tasks of other cgroups that have the same flag turned on. + */ + bool colocate; + + /* Controls whether further updates are allowed to the colocate flag */ + bool colocate_update_disabled; +#endif + }; static inline struct schedtune *css_st(struct cgroup_subsys_state *css) @@ -54,6 +81,13 @@ static inline struct schedtune *parent_st(struct schedtune *st) static struct schedtune root_schedtune = { .boost = 0, +#ifdef CONFIG_SCHED_HMP + .sched_boost_no_override = false, + .sched_boost_enabled = true, + .sched_boost_enabled_backup = true, + .colocate = false, + .colocate_update_disabled = false, +#endif }; /* @@ -97,6 +131,121 @@ struct boost_groups { /* Boost groups affecting each CPU in the system */ DEFINE_PER_CPU(struct boost_groups, cpu_boost_groups); +#ifdef CONFIG_SCHED_HMP +static inline void init_sched_boost(struct schedtune *st) +{ + st->sched_boost_no_override = false; + st->sched_boost_enabled = true; + st->sched_boost_enabled_backup = st->sched_boost_enabled; + st->colocate = false; + st->colocate_update_disabled = false; +} + +bool same_schedtune(struct task_struct *tsk1, struct task_struct *tsk2) +{ + return task_schedtune(tsk1) == task_schedtune(tsk2); +} + +void update_cgroup_boost_settings(void) +{ + int i; + + for (i = 0; i < BOOSTGROUPS_COUNT; i++) { + if (!allocated_group[i]) + break; + + if (allocated_group[i]->sched_boost_no_override) + continue; + + allocated_group[i]->sched_boost_enabled = false; + } +} + +void restore_cgroup_boost_settings(void) +{ + int i; + + for (i = 0; i < BOOSTGROUPS_COUNT; i++) { + if (!allocated_group[i]) + break; + + allocated_group[i]->sched_boost_enabled = + allocated_group[i]->sched_boost_enabled_backup; + } +} + +bool task_sched_boost(struct task_struct *p) +{ + struct schedtune *st = task_schedtune(p); + + return st->sched_boost_enabled; +} + +static u64 +sched_boost_override_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct schedtune *st = css_st(css); + + return st->sched_boost_no_override; +} + +static int sched_boost_override_write(struct cgroup_subsys_state *css, + struct cftype *cft, u64 override) +{ + struct schedtune *st = css_st(css); + + st->sched_boost_no_override = !!override; + + return 0; +} + +static u64 sched_boost_enabled_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct schedtune *st = css_st(css); + + return st->sched_boost_enabled; +} + +static int sched_boost_enabled_write(struct cgroup_subsys_state *css, + struct cftype *cft, u64 enable) +{ + struct schedtune *st = css_st(css); + + st->sched_boost_enabled = !!enable; + st->sched_boost_enabled_backup = st->sched_boost_enabled; + + return 0; +} + +static u64 sched_colocate_read(struct cgroup_subsys_state *css, + struct cftype *cft) +{ + struct schedtune *st = css_st(css); + + return st->colocate; +} + +static int sched_colocate_write(struct cgroup_subsys_state *css, + struct cftype *cft, u64 colocate) +{ + struct schedtune *st = css_st(css); + + if (st->colocate_update_disabled) + return -EPERM; + + st->colocate = !!colocate; + st->colocate_update_disabled = true; + return 0; +} + +#else /* CONFIG_SCHED_HMP */ + +static inline void init_sched_boost(struct schedtune *st) { } + +#endif /* CONFIG_SCHED_HMP */ + static u64 boost_read(struct cgroup_subsys_state *css, struct cftype *cft) { @@ -121,12 +270,45 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft, return 0; } +static void schedtune_attach(struct cgroup_taskset *tset) +{ + struct task_struct *task; + struct cgroup_subsys_state *css; + struct schedtune *st; + bool colocate; + + cgroup_taskset_first(tset, &css); + st = css_st(css); + + colocate = st->colocate; + + cgroup_taskset_for_each(task, css, tset) + sync_cgroup_colocation(task, colocate); +} + static struct cftype files[] = { { .name = "boost", .read_u64 = boost_read, .write_u64 = boost_write, }, +#ifdef CONFIG_SCHED_HMP + { + .name = "sched_boost_no_override", + .read_u64 = sched_boost_override_read, + .write_u64 = sched_boost_override_write, + }, + { + .name = "sched_boost_enabled", + .read_u64 = sched_boost_enabled_read, + .write_u64 = sched_boost_enabled_write, + }, + { + .name = "colocate", + .read_u64 = sched_colocate_read, + .write_u64 = sched_colocate_write, + }, +#endif { } /* terminate */ }; @@ -189,6 +371,7 @@ schedtune_css_alloc(struct cgroup_subsys_state *parent_css) /* Initialize per CPUs boost group support */ st->idx = idx; + init_sched_boost(st); if (schedtune_boostgroup_init(st)) goto release; @@ -222,6 +405,7 @@ struct cgroup_subsys schedtune_cgrp_subsys = { .legacy_cftypes = files, .early_init = 1, .allow_attach = subsys_cgroup_allow_attach, + .attach = schedtune_attach, }; #endif /* CONFIG_CGROUP_SCHEDTUNE */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 574316f1c344..b7cbd7940f7b 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -124,6 +124,7 @@ static int __maybe_unused neg_one = -1; static int zero; static int __maybe_unused one = 1; static int __maybe_unused two = 2; +static int __maybe_unused three = 3; static int __maybe_unused four = 4; static unsigned long one_ul = 1; static int one_hundred = 100; @@ -377,6 +378,22 @@ static struct ctl_table kern_table[] = { .extra2 = &one_hundred, }, { + .procname = "sched_group_upmigrate", + .data = &sysctl_sched_group_upmigrate_pct, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = sched_hmp_proc_update_handler, + .extra1 = &zero, + }, + { + .procname = "sched_group_downmigrate", + .data = &sysctl_sched_group_downmigrate_pct, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = sched_hmp_proc_update_handler, + .extra1 = &zero, + }, + { .procname = "sched_init_task_load", .data = &sysctl_sched_init_task_load_pct, .maxlen = sizeof(unsigned int), @@ -487,6 +504,8 @@ static struct ctl_table kern_table[] = { .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = sched_boost_handler, + .extra1 = &zero, + .extra2 = &three, }, #endif /* CONFIG_SCHED_HMP */ #ifdef CONFIG_SCHED_DEBUG diff --git a/net/core/filter.c b/net/core/filter.c index 75e9b2b2336d..eedb05468fcb 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -52,9 +52,10 @@ #include <net/dst.h> /** - * sk_filter - run a packet through a socket filter + * sk_filter_trim_cap - run a packet through a socket filter * @sk: sock associated with &sk_buff * @skb: buffer to filter + * @cap: limit on how short the eBPF program may trim the packet * * Run the eBPF program and then cut skb->data to correct size returned by * the program. If pkt_len is 0 we toss packet. If skb->len is smaller @@ -63,7 +64,7 @@ * be accepted or -EPERM if the packet should be tossed. * */ -int sk_filter(struct sock *sk, struct sk_buff *skb) +int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap) { int err; struct sk_filter *filter; @@ -85,13 +86,13 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) if (filter) { unsigned int pkt_len = bpf_prog_run_save_cb(filter->prog, skb); - err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; + err = pkt_len ? pskb_trim(skb, max(cap, pkt_len)) : -EPERM; } rcu_read_unlock(); return err; } -EXPORT_SYMBOL(sk_filter); +EXPORT_SYMBOL(sk_filter_trim_cap); static u64 __skb_get_pay_offset(u64 ctx, u64 a, u64 x, u64 r4, u64 r5) { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 07408b81bcd7..e3b0b55f2c92 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1529,6 +1529,21 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb) } EXPORT_SYMBOL(tcp_prequeue); +int tcp_filter(struct sock *sk, struct sk_buff *skb) +{ + struct tcphdr *th = (struct tcphdr *)skb->data; + unsigned int eaten = skb->len; + int err; + + err = sk_filter_trim_cap(sk, skb, th->doff * 4); + if (!err) { + eaten -= skb->len; + TCP_SKB_CB(skb)->end_seq -= eaten; + } + return err; +} +EXPORT_SYMBOL(tcp_filter); + /* * From tcp_input.c */ @@ -1634,8 +1649,10 @@ process: nf_reset(skb); - if (sk_filter(sk, skb)) + if (tcp_filter(sk, skb)) goto discard_and_relse; + th = (const struct tcphdr *)skb->data; + iph = ip_hdr(skb); skb->dev = NULL; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 04955a5d2350..8647afa77db4 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1199,7 +1199,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); - if (sk_filter(sk, skb)) + if (tcp_filter(sk, skb)) goto discard; /* @@ -1431,8 +1431,10 @@ process: if (tcp_v6_inbound_md5_hash(sk, skb)) goto discard_and_relse; - if (sk_filter(sk, skb)) + if (tcp_filter(sk, skb)) goto discard_and_relse; + th = (const struct tcphdr *)skb->data; + hdr = ipv6_hdr(skb); skb->dev = NULL; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 77afe913d03d..9adedba78eea 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -326,10 +326,12 @@ replay: nlh = nlmsg_hdr(skb); err = 0; - if (nlmsg_len(nlh) < sizeof(struct nfgenmsg) || - skb->len < nlh->nlmsg_len) { - err = -EINVAL; - goto ack; + if (nlh->nlmsg_len < NLMSG_HDRLEN || + skb->len < nlh->nlmsg_len || + nlmsg_len(nlh) < sizeof(struct nfgenmsg)) { + nfnl_err_reset(&err_list); + status |= NFNL_BATCH_FAILURE; + goto done; } /* Only requests are handled by the kernel */ diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c index 79c4abcfa6b4..fb31d2ea5a81 100644 --- a/net/rose/rose_in.c +++ b/net/rose/rose_in.c @@ -164,7 +164,8 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety rose_frames_acked(sk, nr); if (ns == rose->vr) { rose_start_idletimer(sk); - if (sock_queue_rcv_skb(sk, skb) == 0) { + if (sk_filter_trim_cap(sk, skb, ROSE_MIN_LEN) == 0 && + sock_queue_rcv_skb(sk, skb) == 0) { rose->vr = (rose->vr + 1) % ROSE_MODULUS; queued = 1; } else { diff --git a/net/wireless/chan.c b/net/wireless/chan.c index cf14c7e22fb3..d5ccaeaa76e0 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -749,7 +749,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy, * and thus fail the GO instantiation, consider only the interfaces of * the current registered device. */ - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { struct ieee80211_channel *other_chan = NULL; int r1, r2; diff --git a/net/wireless/core.c b/net/wireless/core.c index 6d3402434a63..16043faba52c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -3,6 +3,7 @@ * * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright 2015 Intel Deutschland GmbH */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -157,7 +158,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) return -EOPNOTSUPP; - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; @@ -171,7 +172,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, /* failed -- clean up to old netns */ net = wiphy_net(&rdev->wiphy); - list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list, + list_for_each_entry_continue_reverse(wdev, + &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; @@ -230,7 +232,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) ASSERT_RTNL(); - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (wdev->netdev) { dev_close(wdev->netdev); continue; @@ -298,7 +300,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev) kfree(item); spin_unlock_irq(&rdev->destroy_list_lock); - list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) { + list_for_each_entry_safe(wdev, tmp, + &rdev->wiphy.wdev_list, list) { if (nlportid == wdev->owner_nlportid) rdev_del_virtual_intf(rdev, wdev); } @@ -400,7 +403,7 @@ use_default_name: dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); } - INIT_LIST_HEAD(&rdev->wdev_list); + INIT_LIST_HEAD(&rdev->wiphy.wdev_list); INIT_LIST_HEAD(&rdev->beacon_registrations); spin_lock_init(&rdev->beacon_registrations_lock); spin_lock_init(&rdev->bss_lock); @@ -812,7 +815,7 @@ void wiphy_unregister(struct wiphy *wiphy) nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); rdev->wiphy.registered = false; - WARN_ON(!list_empty(&rdev->wdev_list)); + WARN_ON(!list_empty(&rdev->wiphy.wdev_list)); /* * First remove the hardware from everywhere, this makes @@ -949,7 +952,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, spin_lock_init(&wdev->mgmt_registrations_lock); wdev->identifier = ++rdev->wdev_id; - list_add_rcu(&wdev->list, &rdev->wdev_list); + list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list); rdev->devlist_generation++; /* can only change netns with wiphy */ dev->features |= NETIF_F_NETNS_LOCAL; diff --git a/net/wireless/core.h b/net/wireless/core.h index fcd59e76a8e5..a06a1056f726 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -50,8 +50,7 @@ struct cfg80211_registered_device { /* wiphy index, internal only */ int wiphy_idx; - /* associated wireless interfaces, protected by rtnl or RCU */ - struct list_head wdev_list; + /* protected by RTNL */ int devlist_generation, wdev_id; int opencount; /* also protected by devlist_mtx */ wait_queue_head_t dev_wait; diff --git a/net/wireless/db.txt b/net/wireless/db.txt index 23b7c76ff2d8..89130cf4db04 100644 --- a/net/wireless/db.txt +++ b/net/wireless/db.txt @@ -16,7 +16,7 @@ country 00: (57240 - 63720 @ 2160), (0) -country AE: DFS-FCC +country AE: DFS-ETSI (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (24), AUTO-BW (5250 - 5330 @ 80), (24), DFS, AUTO-BW @@ -52,13 +52,12 @@ country AN: DFS-ETSI (5250 - 5330 @ 80), (23), DFS, AUTO-BW (5490 - 5710 @ 160), (30), DFS -country AR: DFS-FCC - (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (24), AUTO-BW - (5250 - 5330 @ 80), (24), DFS, AUTO-BW - (5490 - 5590 @ 80), (24), DFS - (5650 - 5730 @ 80), (24), DFS - (5735 - 5835 @ 80), (30) +country AR: + (2402 - 2482 @ 40), (36) + (5170 - 5330 @ 160), (23) + (5490 - 5590 @ 80), (36) + (5650 - 5730 @ 80), (36) + (5735 - 5835 @ 80), (36) country AS: DFS-FCC (2402 - 2472 @ 40), (30) @@ -162,11 +161,10 @@ country BG: DFS-ETSI # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR -country BH: DFS-ETSI +country BH: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 20), (20) - (5250 - 5330 @ 20), (20), DFS - (5735 - 5835 @ 20), (20) + (5170 - 5330 @ 20), (23) + (5735 - 5835 @ 20), (33) country BL: DFS-ETSI (2402 - 2482 @ 40), (20) @@ -219,8 +217,10 @@ country BY: DFS-ETSI (5490 - 5710 @ 160), (30), DFS country BZ: - (2402 - 2482 @ 40), (30) - (5735 - 5835 @ 80), (30) + (2402 - 2482 @ 40), (36) + (5170 - 5330 @ 160), (27) + (5490 - 5730 @ 160), (36) + (5735 - 5835 @ 80), (36) country CA: DFS-FCC (2402 - 2472 @ 40), (30) @@ -259,10 +259,9 @@ country CI: DFS-FCC (5490 - 5730 @ 160), (24), DFS (5735 - 5835 @ 80), (30) -country CL: DFS-ETSI +country CL: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW + (5170 - 5330 @ 160), (20) (5735 - 5835 @ 80), (20) country CN: DFS-FCC @@ -416,9 +415,9 @@ country EE: DFS-ETSI (57240 - 65880 @ 2160), (40), NO-OUTDOOR country EG: DFS-ETSI - (2402 - 2482 @ 20), (20) - (5170 - 5250 @ 20), (23) - (5250 - 5330 @ 20), (23), DFS + (2402 - 2482 @ 40), (20) + (5170 - 5250 @ 40), (23) + (5250 - 5330 @ 40), (23), DFS country ES: DFS-ETSI (2402 - 2482 @ 40), (20) @@ -581,11 +580,10 @@ country HK: DFS-FCC (5490 - 5730 @ 160), (24), DFS (5735 - 5835 @ 80), (30) -country HN: DFS-FCC +country HN: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (24), AUTO-BW - (5250 - 5330 @ 80), (24), DFS, AUTO-BW - (5490 - 5730 @ 160), (24), DFS + (5170 - 5330 @ 160), (24) + (5490 - 5730 @ 160), (24) (5735 - 5835 @ 80), (30) country HR: DFS-ETSI @@ -657,10 +655,9 @@ country IL: DFS-ETSI (5170 - 5250 @ 80), (23), AUTO-BW (5250 - 5330 @ 80), (23), DFS, AUTO-BW -country IN: DFS-ETSI +country IN: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (23), AUTO-BW - (5250 - 5330 @ 80), (23), DFS, AUTO-BW + (5170 - 5330 @ 160), (23) (5735 - 5835 @ 80), (30) country IR: @@ -735,7 +732,7 @@ country KH: DFS-ETSI (5250 - 5330 @ 80), (23), DFS, AUTO-BW (5490 - 5710 @ 160), (30), DFS -country KN: DFS-ETSI +country KN: DFS-FCC (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (23), AUTO-BW (5250 - 5330 @ 80), (23), DFS, AUTO-BW @@ -746,8 +743,8 @@ country KR: DFS-ETSI (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (20), AUTO-BW (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5630 @ 80), (30), DFS - (5735 - 5815 @ 80), (30) + (5490 - 5710 @ 80), (30), DFS + (5735 - 5835 @ 80), (30) # 60 GHz band channels 1-4, # ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99 (57000 - 66000 @ 2160), (43) @@ -781,7 +778,7 @@ country LB: DFS-FCC (5490 - 5730 @ 160), (24), DFS (5735 - 5835 @ 80), (30) -country LC: DFS-ETSI +country LC: DFS-FCC (2402 - 2482 @ 40), (20) (5170 - 5250 @ 80), (20), AUTO-BW (5250 - 5330 @ 80), (30), DFS, AUTO-BW @@ -1047,10 +1044,9 @@ country NO: DFS-ETSI # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR -country NP: DFS-ETSI +country NP: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW + (5170 - 5330 @ 160), (20) (5735 - 5835 @ 80), (20) country NZ: DFS-FCC @@ -1066,11 +1062,11 @@ country OM: DFS-ETSI (5250 - 5330 @ 80), (23), DFS, AUTO-BW (5490 - 5710 @ 160), (30), DFS -country PA: DFS-FCC +country PA: (2402 - 2472 @ 40), (30) - (5170 - 5250 @ 80), (23), AUTO-BW - (5250 - 5330 @ 80), (23), DFS, AUTO-BW - (5735 - 5835 @ 80), (30) + (5170 - 5250 @ 80), (23), AUT0-BW + (5250 - 5330 @ 80), (30), AUTO-BW + (5735 - 5835 @ 80), (36) country PE: DFS-FCC (2402 - 2482 @ 40), (20) @@ -1208,11 +1204,10 @@ country RS: DFS-ETSI # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR -country RU: DFS-ETSI +country RU: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (23), AUTO-BW - (5250 - 5330 @ 80), (23), DFS, AUTO-BW - (5490 - 5730 @ 160), (30), DFS + (5170 - 5330 @ 160), (23) + (5490 - 5730 @ 160), (30) (5735 - 5835 @ 80), (30) country RW: DFS-FCC @@ -1286,11 +1281,10 @@ country SK: DFS-ETSI # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR -country SN: DFS-FCC +country SN: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (24), AUTO-BW - (5250 - 5330 @ 80), (24), DFS, AUTO-BW - (5490 - 5730 @ 160), (24), DFS + (5170 - 5330 @ 160), (24) + (5490 - 5730 @ 160), (24) (5735 - 5835 @ 80), (30) country SR: DFS-ETSI @@ -1347,12 +1341,11 @@ country TR: DFS-ETSI # 60 gHz band channels 1-4, ref: Etsi En 302 567 (57240 - 65880 @ 2160), (40), NO-OUTDOOR -country TT: DFS-FCC +country TT: (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (24), AUTO-BW - (5250 - 5330 @ 80), (24), DFS, AUTO-BW - (5490 - 5730 @ 160), (24), DFS - (5735 - 5835 @ 80), (30) + (5170 - 5330 @ 160), (27) + (5490 - 5730 @ 160), (36) + (5735 - 5835 @ 80), (36) country TW: DFS-FCC (2402 - 2472 @ 40), (30) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 40299f19c09b..375d6c1732fa 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -103,7 +103,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) continue; - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (have_ifidx && wdev->netdev && wdev->netdev->ifindex == ifidx) { result = wdev; @@ -149,7 +149,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); if (tmp) { /* make sure wdev exists */ - list_for_each_entry(wdev, &tmp->wdev_list, list) { + list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) { if (wdev->identifier != (u32)wdev_id) continue; found = true; @@ -524,7 +524,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb, *rdev = wiphy_to_rdev(wiphy); *wdev = NULL; - list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { + list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) { if (tmp->identifier == cb->args[1]) { *wdev = tmp; break; @@ -2504,7 +2504,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * } if_idx = 0; - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (if_idx < if_start) { if_idx++; continue; @@ -2776,7 +2776,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) spin_lock_init(&wdev->mgmt_registrations_lock); wdev->identifier = ++rdev->wdev_id; - list_add_rcu(&wdev->list, &rdev->wdev_list); + list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list); rdev->devlist_generation++; break; default: @@ -3585,7 +3585,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev; bool ret = false; - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (wdev->iftype != NL80211_IFTYPE_AP && wdev->iftype != NL80211_IFTYPE_P2P_GO) continue; @@ -7770,12 +7770,14 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) ibss.beacon_interval = 100; - if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { + if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) ibss.beacon_interval = nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); - if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000) - return -EINVAL; - } + + err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC, + ibss.beacon_interval); + if (err) + return err; if (!rdev->ops->join_ibss) return -EOPNOTSUPP; @@ -9013,9 +9015,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { setup.beacon_interval = nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); - if (setup.beacon_interval < 10 || - setup.beacon_interval > 10000) - return -EINVAL; + + err = cfg80211_validate_beacon_int(rdev, + NL80211_IFTYPE_MESH_POINT, + setup.beacon_interval); + if (err) + return err; } if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { @@ -10328,7 +10333,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, *wdev = NULL; if (cb->args[1]) { - list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { + list_for_each_entry(tmp, &wiphy->wdev_list, list) { if (tmp->identifier == cb->args[1] - 1) { *wdev = tmp; break; @@ -13339,7 +13344,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, sched_scan_req->owner_nlportid == notify->portid) schedule_scan_stop = true; - list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { + list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) { cfg80211_mlme_unregister_socket(wdev, notify->portid); if (wdev->owner_nlportid == notify->portid) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 2fed05f2edf8..050d7948dd68 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1685,7 +1685,7 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy) struct cfg80211_sched_scan_request *sched_scan_req; ASSERT_RTNL(); - list_for_each_entry(wdev, &rdev->wdev_list, list) + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) if (!reg_wdev_chan_valid(wiphy, wdev)) { dev = wdev->netdev; switch (wdev->iftype) { diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 37d8ab3a71be..e5b962d2ffe7 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -54,7 +54,7 @@ static bool cfg80211_is_all_countryie_ignore(void) bool is_all_countryie_ignore = true; list_for_each_entry(rdev, &cfg80211_rdev_list, list) { - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { wdev_lock(wdev); if (!(wdev->wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_IGNORE)) { @@ -246,7 +246,7 @@ void cfg80211_conn_work(struct work_struct *work) rtnl_lock(); - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { if (!wdev->netdev) continue; @@ -630,7 +630,7 @@ static bool cfg80211_is_all_idle(void) * count as new regulatory hints. */ list_for_each_entry(rdev, &cfg80211_rdev_list, list) { - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { wdev_lock(wdev); if (wdev->conn || wdev->current_bss) is_all_idle = false; diff --git a/net/wireless/util.c b/net/wireless/util.c index acff02fcc281..ef394e8a42bc 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -13,6 +13,7 @@ #include <net/dsfield.h> #include <linux/if_vlan.h> #include <linux/mpls.h> +#include <linux/gcd.h> #include "core.h" #include "rdev-ops.h" @@ -910,7 +911,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) ASSERT_RTNL(); - list_for_each_entry(wdev, &rdev->wdev_list, list) + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) cfg80211_process_wdev_events(wdev); } @@ -1482,47 +1483,53 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, } EXPORT_SYMBOL(ieee80211_chandef_to_operating_class); -int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, - enum nl80211_iftype iftype, u32 beacon_int) +static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int, + u32 *beacon_int_gcd, + bool *beacon_int_different) { struct wireless_dev *wdev; - struct iface_combination_params params = { - .beacon_int_gcd = beacon_int, /* GCD(n) = n */ - }; - if (!beacon_int) - return -EINVAL; + *beacon_int_gcd = 0; + *beacon_int_different = false; - params.iftype_num[iftype] = 1; - list_for_each_entry(wdev, &rdev->wdev_list, list) { + list_for_each_entry(wdev, &wiphy->wdev_list, list) { if (!wdev->beacon_interval) continue; - params.iftype_num[wdev->iftype]++; - } - - list_for_each_entry(wdev, &rdev->wdev_list, list) { - u32 bi_prev = wdev->beacon_interval; - - if (!wdev->beacon_interval) + if (!*beacon_int_gcd) { + *beacon_int_gcd = wdev->beacon_interval; continue; + } - /* slight optimisation - skip identical BIs */ - if (wdev->beacon_interval == beacon_int) + if (wdev->beacon_interval == *beacon_int_gcd) continue; - params.beacon_int_different = true; - - /* Get the GCD */ - while (bi_prev != 0) { - u32 tmp_bi = bi_prev; + *beacon_int_different = true; + *beacon_int_gcd = gcd(*beacon_int_gcd, wdev->beacon_interval); + } - bi_prev = params.beacon_int_gcd % bi_prev; - params.beacon_int_gcd = tmp_bi; - } + if (new_beacon_int && *beacon_int_gcd != new_beacon_int) { + if (*beacon_int_gcd) + *beacon_int_different = true; + *beacon_int_gcd = gcd(*beacon_int_gcd, new_beacon_int); } +} - return cfg80211_check_combinations(&rdev->wiphy, ¶ms); +int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, + enum nl80211_iftype iftype, u32 beacon_int) +{ + /* + * This is just a basic pre-condition check; if interface combinations + * are possible the driver must already be checking those with a call + * to cfg80211_check_combinations(), in which case we'll validate more + * through the cfg80211_calculate_bi_data() call and code in + * cfg80211_iter_combinations(). + */ + + if (beacon_int < 10 || beacon_int > 10000) + return -EINVAL; + + return 0; } int cfg80211_iter_combinations(struct wiphy *wiphy, @@ -1536,6 +1543,21 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, int i, j, iftype; int num_interfaces = 0; u32 used_iftypes = 0; + u32 beacon_int_gcd; + bool beacon_int_different; + + /* + * This is a bit strange, since the iteration used to rely only on + * the data given by the driver, but here it now relies on context, + * in form of the currently operating interfaces. + * This is OK for all current users, and saves us from having to + * push the GCD calculations into all the drivers. + * In the future, this should probably rely more on data that's in + * cfg80211 already - the only thing not would appear to be any new + * interfaces (while being brought up) and channel/radar data. + */ + cfg80211_calculate_bi_data(wiphy, params->new_beacon_int, + &beacon_int_gcd, &beacon_int_different); if (params->radar_detect) { rcu_read_lock(); @@ -1598,14 +1620,11 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, if ((all_iftypes & used_iftypes) != used_iftypes) goto cont; - if (params->beacon_int_gcd) { + if (beacon_int_gcd) { if (c->beacon_int_min_gcd && - params->beacon_int_gcd < c->beacon_int_min_gcd) { - kfree(limits); - return -EINVAL; - } - if (!c->beacon_int_min_gcd && - params->beacon_int_different) + beacon_int_gcd < c->beacon_int_min_gcd) + goto cont; + if (!c->beacon_int_min_gcd && beacon_int_different) goto cont; } @@ -1701,7 +1720,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, break; } - list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { + list_for_each_entry(wdev_iter, &rdev->wiphy.wdev_list, list) { if (wdev_iter == wdev) continue; if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 38b8a806584f..553b35a2d717 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -989,7 +989,7 @@ config SND_SOC_MSM_STUB config SND_SOC_MSM_HDMI_CODEC_RX bool "HDMI Audio Playback" - depends on FB_MSM_MDSS_HDMI_PANEL && (SND_SOC_APQ8084 || SND_SOC_MSM8994 || SND_SOC_MSM8996 || SND_SOC_MSMCOBALT) + depends on FB_MSM_MDSS_HDMI_PANEL && (SND_SOC_APQ8084 || SND_SOC_MSM8994 || SND_SOC_MSM8996 || SND_SOC_MSM8998) help HDMI audio drivers should be built only if the platform supports hdmi panel. diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index a1f23685beb5..debb6c5e52d5 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -902,6 +902,11 @@ static int wcd_check_cross_conn(struct wcd_mbhc *mbhc) return -EINVAL; } + /* If PA is enabled, dont check for cross-connection */ + if (mbhc->mbhc_cb->hph_pa_on_status) + if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) + return false; + WCD_MBHC_REG_READ(WCD_MBHC_ELECT_SCHMT_ISRC, reg1); /* * Check if there is any cross connection, diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 06e00fdfe6a1..71858e268232 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -13681,6 +13681,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_ignore_suspend(dapm, "AIF Mix Playback"); snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX"); snd_soc_dapm_ignore_suspend(dapm, "VIfeed"); + snd_soc_dapm_ignore_suspend(dapm, "AIF5 CPE TX"); } snd_soc_dapm_sync(dapm); diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 56882be12554..b0bb89c8d9c2 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -2366,19 +2366,20 @@ static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct tavil_priv *tavil; - int ch_cnt; + int ch_cnt = 0; tavil = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_PRE_PMU: - if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) && - !tavil->swr.rx_7_count) + if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2"))))) tavil->swr.rx_7_count++; if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && !tavil->swr.rx_8_count) tavil->swr.rx_8_count++; - ch_cnt = tavil->swr.rx_7_count + tavil->swr.rx_8_count; + ch_cnt = !!(tavil->swr.rx_7_count) + tavil->swr.rx_8_count; swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, SWR_DEVICE_UP, NULL); @@ -2386,21 +2387,22 @@ static int __tavil_codec_enable_swr(struct snd_soc_dapm_widget *w, int event) SWR_SET_NUM_RX_CH, &ch_cnt); break; case SND_SOC_DAPM_POST_PMD: - if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) && - tavil->swr.rx_7_count) + if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) || + (strnstr(w->name, "INT7 MIX2", + sizeof("RX INT7 MIX2")))) tavil->swr.rx_7_count--; if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) && tavil->swr.rx_8_count) tavil->swr.rx_8_count--; - ch_cnt = tavil->swr.rx_7_count + tavil->swr.rx_8_count; + ch_cnt = !!(tavil->swr.rx_7_count) + tavil->swr.rx_8_count; swrm_wcd_notify(tavil->swr.ctrl_data[0].swr_pdev, SWR_SET_NUM_RX_CH, &ch_cnt); break; } - dev_dbg(tavil->dev, "%s: current swr ch cnt: %d\n", - __func__, tavil->swr.rx_7_count + tavil->swr.rx_8_count); + dev_dbg(tavil->dev, "%s: %s: current swr ch cnt: %d\n", + __func__, w->name, ch_cnt); return 0; } @@ -3685,6 +3687,34 @@ static void tavil_tx_mute_update_callback(struct work_struct *work) snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00); } +static int tavil_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + u16 sidetone_reg; + + dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift); + sidetone_reg = WCD934X_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __tavil_codec_enable_swr(w, event); + tavil_codec_enable_interp_clk(codec, event, w->shift); + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00); + tavil_codec_enable_interp_clk(codec, event, w->shift); + if (!strcmp(w->name, "RX INT7 MIX2 INP")) + __tavil_codec_enable_swr(w, event); + break; + default: + break; + }; + return 0; +} + static int tavil_codec_enable_dec(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -6630,18 +6660,24 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = { NULL, 0, tavil_codec_spk_boost_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX("RX INT0 MIX2 INP", WCD934X_CDC_RX0_RX_PATH_CFG1, 4, - 0, &rx_int0_mix2_inp_mux), - SND_SOC_DAPM_MUX("RX INT1 MIX2 INP", WCD934X_CDC_RX1_RX_PATH_CFG1, 4, - 0, &rx_int1_mix2_inp_mux), - SND_SOC_DAPM_MUX("RX INT2 MIX2 INP", WCD934X_CDC_RX2_RX_PATH_CFG1, 4, - 0, &rx_int2_mix2_inp_mux), - SND_SOC_DAPM_MUX("RX INT3 MIX2 INP", WCD934X_CDC_RX3_RX_PATH_CFG1, 4, - 0, &rx_int3_mix2_inp_mux), - SND_SOC_DAPM_MUX("RX INT4 MIX2 INP", WCD934X_CDC_RX4_RX_PATH_CFG1, 4, - 0, &rx_int4_mix2_inp_mux), - SND_SOC_DAPM_MUX("RX INT7 MIX2 INP", WCD934X_CDC_RX7_RX_PATH_CFG1, 4, - 0, &rx_int7_mix2_inp_mux), + SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_EAR, + 0, &rx_int0_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL, + 0, &rx_int1_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR, + 0, &rx_int2_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT3 MIX2 INP", SND_SOC_NOPM, INTERP_LO1, + 0, &rx_int3_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT4 MIX2 INP", SND_SOC_NOPM, INTERP_LO2, + 0, &rx_int4_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", SND_SOC_NOPM, INTERP_SPKR1, + 0, &rx_int7_mix2_inp_mux, tavil_codec_enable_rx_path_clk, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), WCD_DAPM_MUX("CDC_IF TX0 MUX", WCD934X_TX0, cdc_if_tx0), WCD_DAPM_MUX("CDC_IF TX1 MUX", WCD934X_TX1, cdc_if_tx1), diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig index 9cf69eca0028..a5cd94f91cfc 100644 --- a/sound/soc/msm/Kconfig +++ b/sound/soc/msm/Kconfig @@ -190,8 +190,8 @@ config SND_SOC_MSM8996 the machine driver and the corresponding DAI-links -config SND_SOC_MSMCOBALT - tristate "SoC Machine driver for MSMCOBALT boards" +config SND_SOC_MSM8998 + tristate "SoC Machine driver for MSM8998 boards" depends on ARCH_QCOM select SND_SOC_COMPRESS select SND_SOC_QDSP6V2 @@ -215,7 +215,7 @@ config SND_SOC_MSMCOBALT select SND_HWDEP select DTS_EAGLE help - To add support for SoC audio on MSMCOBALT. + To add support for SoC audio on MSM8998. This will enable sound soc drivers which interfaces with DSP, also it will enable the machine driver and the corresponding diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile index 799c9ee63d43..8df7fad3893d 100644 --- a/sound/soc/msm/Makefile +++ b/sound/soc/msm/Makefile @@ -16,9 +16,9 @@ obj-$(CONFIG_SND_SOC_CPE) += snd-soc-cpe.o snd-soc-msm8996-objs := msm8996.o obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-msm8996.o -# for MSMCOBALT sound card driver -snd-soc-msmcobalt-objs := msmcobalt.o -obj-$(CONFIG_SND_SOC_MSMCOBALT) += snd-soc-msmcobalt.o +# for MSM8998 sound card driver +snd-soc-msm8998-objs := msm8998.o +obj-$(CONFIG_SND_SOC_MSM8998) += snd-soc-msm8998.o # for MSMFALCON sound card driver snd-soc-msmfalcon-common-objs := msm-audio-pinctrl.o msmfalcon-common.o @@ -33,4 +33,3 @@ obj-$(CONFIG_SND_SOC_INT_CODEC) += snd-soc-int-codec.o snd-soc-ext-codec-objs := msmfalcon-external.o msmfalcon-ext-dai-links.o obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-msmfalcon-common.o obj-$(CONFIG_SND_SOC_EXT_CODEC) += snd-soc-ext-codec.o - diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c index aa036d352f40..9c720acf8ef8 100644 --- a/sound/soc/msm/msm-dai-fe.c +++ b/sound/soc/msm/msm-dai-fe.c @@ -2449,6 +2449,63 @@ static struct snd_soc_dai_driver msm_fe_dais[] = { .name = "VoiceMMode2", .probe = fe_dai_probe, }, + { + .capture = { + .stream_name = "MultiMedia17 Capture", + .aif_name = "MM_UL17", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia17", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia18 Capture", + .aif_name = "MM_UL18", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia18", + .probe = fe_dai_probe, + }, + { + .capture = { + .stream_name = "MultiMedia19 Capture", + .aif_name = "MM_UL19", + .rates = (SNDRV_PCM_RATE_8000_48000| + SNDRV_PCM_RATE_KNOT), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE), + .channels_min = 1, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &msm_fe_Multimedia_dai_ops, + .compress_new = snd_soc_new_compress, + .name = "MultiMedia19", + .probe = fe_dai_probe, + }, }; static int msm_fe_dai_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/msm/msmcobalt.c b/sound/soc/msm/msm8998.c index 9c392f3d4ddc..94a529acaff7 100644 --- a/sound/soc/msm/msmcobalt.c +++ b/sound/soc/msm/msm8998.c @@ -40,9 +40,9 @@ #include "../codecs/wcd934x/wcd934x-mbhc.h" #include "../codecs/wsa881x.h" -#define DRV_NAME "msmcobalt-asoc-snd" +#define DRV_NAME "msm8998-asoc-snd" -#define __CHIPSET__ "MSMCOBALT " +#define __CHIPSET__ "MSM8998 " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) #define SAMPLING_RATE_8KHZ 8000 @@ -3108,7 +3108,7 @@ err_fail: return ret; } -static int msmcobalt_notifier_service_cb(struct notifier_block *this, +static int msm8998_notifier_service_cb(struct notifier_block *this, unsigned long opcode, void *ptr) { int ret; @@ -3166,7 +3166,7 @@ done: } static struct notifier_block service_nb = { - .notifier_call = msmcobalt_notifier_service_cb, + .notifier_call = msm8998_notifier_service_cb, .priority = -INT_MAX, }; @@ -5824,12 +5824,12 @@ err_pcm_runtime: } struct snd_soc_card snd_soc_card_tasha_msm = { - .name = "msmcobalt-tasha-snd-card", + .name = "msm8998-tasha-snd-card", .late_probe = msm_snd_card_late_probe, }; struct snd_soc_card snd_soc_card_tavil_msm = { - .name = "msmcobalt-tavil-snd-card", + .name = "msm8998-tavil-snd-card", .late_probe = msm_snd_card_tavil_late_probe, }; @@ -6089,15 +6089,15 @@ static struct snd_soc_dai_link msm_stub_dai_links[ ARRAY_SIZE(msm_stub_be_dai_links)]; struct snd_soc_card snd_soc_card_stub_msm = { - .name = "msmcobalt-stub-snd-card", + .name = "msm8998-stub-snd-card", }; -static const struct of_device_id msmcobalt_asoc_machine_of_match[] = { - { .compatible = "qcom,msmcobalt-asoc-snd-tasha", +static const struct of_device_id msm8998_asoc_machine_of_match[] = { + { .compatible = "qcom,msm8998-asoc-snd-tasha", .data = "tasha_codec"}, - { .compatible = "qcom,msmcobalt-asoc-snd-tavil", + { .compatible = "qcom,msm8998-asoc-snd-tavil", .data = "tavil_codec"}, - { .compatible = "qcom,msmcobalt-asoc-snd-stub", + { .compatible = "qcom,msm8998-asoc-snd-stub", .data = "stub_codec"}, {}, }; @@ -6110,7 +6110,7 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) int total_links; const struct of_device_id *match; - match = of_match_node(msmcobalt_asoc_machine_of_match, dev->of_node); + match = of_match_node(msm8998_asoc_machine_of_match, dev->of_node); if (!match) { dev_err(dev, "%s: No DT match found for sound card\n", __func__); @@ -6590,7 +6590,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) goto err; } - match = of_match_node(msmcobalt_asoc_machine_of_match, + match = of_match_node(msm8998_asoc_machine_of_match, pdev->dev.of_node); if (!match) { dev_err(&pdev->dev, "%s: no matched codec is found.\n", @@ -6710,7 +6710,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) i2s_auxpcm_init(pdev); is_initial_boot = true; - ret = audio_notifier_register("msmcobalt", AUDIO_NOTIFIER_ADSP_DOMAIN, + ret = audio_notifier_register("msm8998", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) pr_err("%s: Audio notifier register failed ret = %d\n", @@ -6755,19 +6755,19 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) return 0; } -static struct platform_driver msmcobalt_asoc_machine_driver = { +static struct platform_driver msm8998_asoc_machine_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, - .of_match_table = msmcobalt_asoc_machine_of_match, + .of_match_table = msm8998_asoc_machine_of_match, }, .probe = msm_asoc_machine_probe, .remove = msm_asoc_machine_remove, }; -module_platform_driver(msmcobalt_asoc_machine_driver); +module_platform_driver(msm8998_asoc_machine_driver); MODULE_DESCRIPTION("ALSA SoC msm"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); -MODULE_DEVICE_TABLE(of, msmcobalt_asoc_machine_of_match); +MODULE_DEVICE_TABLE(of, msm8998_asoc_machine_of_match); diff --git a/sound/soc/msm/msmfalcon-common.c b/sound/soc/msm/msmfalcon-common.c index 6c96a0778b52..c82319539f39 100644 --- a/sound/soc/msm/msmfalcon-common.c +++ b/sound/soc/msm/msmfalcon-common.c @@ -28,6 +28,112 @@ #define DEV_NAME_STR_LEN 32 #define DEFAULT_MCLK_RATE 9600000 +struct dev_config { + u32 sample_rate; + u32 bit_format; + u32 channels; +}; + +/* TDM default config */ +static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */ + } +}; + +/* TDM default config */ +static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = { + { /* PRI TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* SEC TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* TERT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + }, + { /* QUAT TDM */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */ + {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */ + } +}; + +static struct dev_config usb_rx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, +}; + +static struct dev_config usb_tx_cfg = { + .sample_rate = SAMPLING_RATE_48KHZ, + .bit_format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 1, +}; + enum { PRIM_MI2S = 0, SEC_MI2S, @@ -68,12 +174,6 @@ struct auxpcm_conf { u32 ref_cnt; }; -struct dev_config { - u32 sample_rate; - u32 bit_format; - u32 channels; -}; - struct msm_wsa881x_dev_info { struct device_node *of_node; u32 index; @@ -111,12 +211,6 @@ static struct dev_config proxy_rx_cfg = { .channels = 2, }; -static struct dev_config btsco_cfg = { - .sample_rate = SAMPLING_RATE_8KHZ, - .bit_format = SNDRV_PCM_FORMAT_S16_LE, - .channels = 1, -}; - /* Default configuration of MI2S channels */ static struct dev_config mi2s_rx_cfg[] = { [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, @@ -155,8 +249,22 @@ static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16", static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"}; +static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE", + "S32_LE"}; +static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight"}; +static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"}; +static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", + "KHZ_44P1", "KHZ_48", "KHZ_96", + "KHZ_192", "KHZ_352P8", "KHZ_384"}; +static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four", + "Five", "Six", "Seven", + "Eight"}; +static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025", + "KHZ_16", "KHZ_22P05", + "KHZ_32", "KHZ_44P1", "KHZ_48", + "KHZ_96", "KHZ_192", "KHZ_384"}; -static SOC_ENUM_SINGLE_EXT_DECL(btsco_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text); static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text); @@ -182,6 +290,18 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text); +static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text); static struct afe_clk_set mi2s_clk[MI2S_MAX] = { { @@ -242,6 +362,439 @@ static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol, return 1; } +static int tdm_get_sample_rate(int value) +{ + int sample_rate = 0; + + switch (value) { + case 0: + sample_rate = SAMPLING_RATE_8KHZ; + break; + case 1: + sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + sample_rate = SAMPLING_RATE_352P8KHZ; + break; + case 8: + sample_rate = SAMPLING_RATE_384KHZ; + break; + default: + sample_rate = SAMPLING_RATE_48KHZ; + break; + } + return sample_rate; +} + +static int tdm_get_sample_rate_val(int sample_rate) +{ + int sample_rate_val = 0; + + switch (sample_rate) { + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_352P8KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_384KHZ: + sample_rate_val = 8; + break; + default: + sample_rate_val = 4; + break; + } + return sample_rate_val; +} + +static int tdm_get_port_idx(struct snd_kcontrol *kcontrol, + struct tdm_port *port) +{ + if (port) { + if (strnstr(kcontrol->id.name, "PRI", + sizeof(kcontrol->id.name))) { + port->mode = TDM_PRI; + } else if (strnstr(kcontrol->id.name, "SEC", + sizeof(kcontrol->id.name))) { + port->mode = TDM_SEC; + } else if (strnstr(kcontrol->id.name, "TERT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_TERT; + } else if (strnstr(kcontrol->id.name, "QUAT", + sizeof(kcontrol->id.name))) { + port->mode = TDM_QUAT; + } else { + pr_err("%s: unsupported mode in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + + if (strnstr(kcontrol->id.name, "RX_0", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_0", + sizeof(kcontrol->id.name))) { + port->channel = TDM_0; + } else if (strnstr(kcontrol->id.name, "RX_1", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_1", + sizeof(kcontrol->id.name))) { + port->channel = TDM_1; + } else if (strnstr(kcontrol->id.name, "RX_2", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_2", + sizeof(kcontrol->id.name))) { + port->channel = TDM_2; + } else if (strnstr(kcontrol->id.name, "RX_3", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_3", + sizeof(kcontrol->id.name))) { + port->channel = TDM_3; + } else if (strnstr(kcontrol->id.name, "RX_4", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_4", + sizeof(kcontrol->id.name))) { + port->channel = TDM_4; + } else if (strnstr(kcontrol->id.name, "RX_5", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_5", + sizeof(kcontrol->id.name))) { + port->channel = TDM_5; + } else if (strnstr(kcontrol->id.name, "RX_6", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_6", + sizeof(kcontrol->id.name))) { + port->channel = TDM_6; + } else if (strnstr(kcontrol->id.name, "RX_7", + sizeof(kcontrol->id.name)) || + strnstr(kcontrol->id.name, "TX_7", + sizeof(kcontrol->id.name))) { + port->channel = TDM_7; + } else { + pr_err("%s: unsupported channel in: %s", + __func__, kcontrol->id.name); + return -EINVAL; + } + } else + return -EINVAL; + return 0; +} + +static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_rx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val( + tdm_tx_cfg[port.mode][port.channel].sample_rate); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].sample_rate = + tdm_get_sample_rate(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].sample_rate, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_get_format(int value) +{ + int format = 0; + + switch (value) { + case 0: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + case 1: + format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 2: + format = SNDRV_PCM_FORMAT_S32_LE; + break; + default: + format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + return format; +} + +static int tdm_get_format_val(int format) +{ + int value = 0; + + switch (format) { + case SNDRV_PCM_FORMAT_S16_LE: + value = 0; + break; + case SNDRV_PCM_FORMAT_S24_LE: + value = 1; + break; + case SNDRV_PCM_FORMAT_S32_LE: + value = 2; + break; + default: + value = 0; + break; + } + return value; +} + +static int tdm_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_rx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = tdm_get_format_val( + tdm_tx_cfg[port.mode][port.channel].bit_format); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].bit_format = + tdm_get_format(ucontrol->value.enumerated.item[0]); + + pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].bit_format, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + + ucontrol->value.enumerated.item[0] = + tdm_rx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_rx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__, + tdm_rx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + +static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + ucontrol->value.enumerated.item[0] = + tdm_tx_cfg[port.mode][port.channel].channels - 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels - 1, + ucontrol->value.enumerated.item[0]); + } + return ret; +} + +static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tdm_port port; + int ret = tdm_get_port_idx(kcontrol, &port); + + if (ret) { + pr_err("%s: unsupported control: %s", + __func__, kcontrol->id.name); + } else { + tdm_tx_cfg[port.mode][port.channel].channels = + ucontrol->value.enumerated.item[0] + 1; + + pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__, + tdm_tx_cfg[port.mode][port.channel].channels, + ucontrol->value.enumerated.item[0] + 1); + } + return ret; +} + static int aux_pcm_get_sample_rate(int value) { int sample_rate; @@ -299,32 +852,6 @@ static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol) return idx; } -static int btsco_sample_rate_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - btsco_cfg.sample_rate = - aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]); - - pr_debug("%s: btsco_sample_rate = %d, item = %d\n", __func__, - btsco_cfg.sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - -static int btsco_sample_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = - aux_pcm_get_sample_rate_val(btsco_cfg.sample_rate); - - pr_debug("%s: btsco_sample_rate = %d, item = %d\n", __func__, - btsco_cfg.sample_rate, - ucontrol->value.enumerated.item[0]); - - return 0; -} - static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -632,12 +1159,331 @@ static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol, return 1; } +static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, + usb_rx_cfg.channels); + ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1; + return 0; +} + +static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels); + return 1; +} + +static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_rx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + sample_rate_val = 0; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__, + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_rx_cfg.sample_rate); + return 0; +} + +static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_rx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n", + __func__, usb_rx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + +static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, + usb_tx_cfg.channels); + ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1; + return 0; +} + +static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1; + + pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels); + return 1; +} + +static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int sample_rate_val; + + switch (usb_tx_cfg.sample_rate) { + case SAMPLING_RATE_384KHZ: + sample_rate_val = 9; + break; + case SAMPLING_RATE_192KHZ: + sample_rate_val = 8; + break; + case SAMPLING_RATE_96KHZ: + sample_rate_val = 7; + break; + case SAMPLING_RATE_48KHZ: + sample_rate_val = 6; + break; + case SAMPLING_RATE_44P1KHZ: + sample_rate_val = 5; + break; + case SAMPLING_RATE_32KHZ: + sample_rate_val = 4; + break; + case SAMPLING_RATE_22P05KHZ: + sample_rate_val = 3; + break; + case SAMPLING_RATE_16KHZ: + sample_rate_val = 2; + break; + case SAMPLING_RATE_11P025KHZ: + sample_rate_val = 1; + break; + case SAMPLING_RATE_8KHZ: + sample_rate_val = 0; + break; + default: + sample_rate_val = 6; + break; + } + + ucontrol->value.integer.value[0] = sample_rate_val; + pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__, + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 9: + usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ; + break; + case 8: + usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ; + break; + case 7: + usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ; + break; + case 6: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + case 5: + usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ; + break; + case 4: + usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ; + break; + case 3: + usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ; + break; + case 2: + usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ; + break; + case 1: + usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ; + break; + case 0: + usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ; + break; + default: + usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ; + break; + } + + pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n", + __func__, ucontrol->value.integer.value[0], + usb_tx_cfg.sample_rate); + return 0; +} + +static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (usb_tx_cfg.bit_format) { + case SNDRV_PCM_FORMAT_S32_LE: + ucontrol->value.integer.value[0] = 3; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + ucontrol->value.integer.value[0] = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ucontrol->value.integer.value[0] = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + return 0; +} + +static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int rc = 0; + + switch (ucontrol->value.integer.value[0]) { + case 3: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE; + break; + case 2: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE; + break; + case 1: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE; + break; + case 0: + default: + usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE; + break; + } + pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n", + __func__, usb_tx_cfg.bit_format, + ucontrol->value.integer.value[0]); + + return rc; +} + const struct snd_kcontrol_new msm_common_snd_controls[] = { SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs, proxy_rx_ch_get, proxy_rx_ch_put), - SOC_ENUM_EXT("BTSCO SampleRate", btsco_sample_rate, - btsco_sample_rate_get, - btsco_sample_rate_put), SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate, aux_pcm_rx_sample_rate_get, aux_pcm_rx_sample_rate_put), @@ -702,8 +1548,119 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put), SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs, msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs, + usb_audio_rx_ch_get, usb_audio_rx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs, + usb_audio_tx_ch_get, usb_audio_tx_ch_put), + SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format, + usb_audio_rx_format_get, usb_audio_rx_format_put), + SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format, + usb_audio_tx_format_get, usb_audio_tx_format_put), + SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate, + usb_audio_rx_sample_rate_get, + usb_audio_rx_sample_rate_put), + SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate, + usb_audio_tx_sample_rate_get, + usb_audio_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate, + tdm_rx_sample_rate_get, + tdm_rx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate, + tdm_tx_sample_rate_get, + tdm_tx_sample_rate_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format, + tdm_rx_format_get, + tdm_rx_format_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format, + tdm_tx_format_get, + tdm_tx_format_put), + SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs, + tdm_rx_ch_get, + tdm_rx_ch_put), + SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs, + tdm_tx_ch_get, + tdm_tx_ch_put), }; +static inline int param_is_mask(int p) +{ + return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && + (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); +} + +static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, + int n) +{ + return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); +} + +static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit) +{ + if (bit >= SNDRV_MASK_MAX) + return; + if (param_is_mask(n)) { + struct snd_mask *m = param_to_mask(p, n); + + m->bits[0] = 0; + m->bits[1] = 0; + m->bits[bit >> 5] |= (1 << (bit & 31)); + } +} + /** * msm_common_be_hw_params_fixup - updates settings of ALSA BE hw params. * @@ -726,10 +1683,18 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, __func__, params_format(params), params_rate(params)); switch (dai_link->be_id) { - case MSM_BACKEND_DAI_INT_BT_SCO_RX: - case MSM_BACKEND_DAI_INT_BT_SCO_TX: - channels->min = channels->max = btsco_cfg.channels; - rate->min = rate->max = 1; + case MSM_BACKEND_DAI_USB_RX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_rx_cfg.bit_format); + rate->min = rate->max = usb_rx_cfg.sample_rate; + channels->min = channels->max = usb_rx_cfg.channels; + break; + + case MSM_BACKEND_DAI_USB_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + usb_tx_cfg.bit_format); + rate->min = rate->max = usb_tx_cfg.sample_rate; + channels->min = channels->max = usb_tx_cfg.channels; break; case MSM_BACKEND_DAI_AFE_PCM_RX: @@ -737,6 +1702,70 @@ int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = SAMPLING_RATE_48KHZ; break; + case MSM_BACKEND_DAI_PRI_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_PRI_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_PRI][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_PRI][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_SEC_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_SEC][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_SEC][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_TERT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_TERT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_TERT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_RX_0: + channels->min = channels->max = + tdm_rx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + + case MSM_BACKEND_DAI_QUAT_TDM_TX_0: + channels->min = channels->max = + tdm_tx_cfg[TDM_QUAT][TDM_0].channels; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format); + rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate; + break; + case MSM_BACKEND_DAI_AUXPCM_RX: rate->min = rate->max = aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate; @@ -1640,11 +2669,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!strcmp(match->data, "tasha_codec") || !strcmp(match->data, "tavil_codec")) { + if (!strcmp(match->data, "tasha_codec")) + pdata->snd_card_val = EXT_SND_CARD_TASHA; + else + pdata->snd_card_val = EXT_SND_CARD_TAVIL; ret = msm_ext_cdc_init(pdev, pdata, &card, &mbhc_cfg); if (ret) goto err; } else if (!strcmp(match->data, "internal_codec")) { - pdata->int_codec = 1; + pdata->snd_card_val = INT_SND_CARD; ret = msm_int_cdc_init(pdev, pdata, &card, &mbhc_cfg); if (ret) goto err; @@ -1656,12 +2689,15 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) if (!card) goto err; - /*reading the gpio configurations from dtsi file*/ - ret = msm_gpioset_initialize(CLIENT_WCD, &pdev->dev); - if (ret < 0) { - dev_err(&pdev->dev, - "%s: error reading dtsi files%d\n", __func__, ret); - goto err; + if (pdata->snd_card_val == INT_SND_CARD) { + /*reading the gpio configurations from dtsi file*/ + ret = msm_gpioset_initialize(CLIENT_WCD, &pdev->dev); + if (ret < 0) { + dev_err(&pdev->dev, + "%s: error reading dtsi files%d\n", + __func__, ret); + goto err; + } } /* @@ -1710,6 +2746,8 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) ret); goto err; } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_register_audio_notifier(); return 0; err: if (pdata->us_euro_gpio > 0) { @@ -1738,7 +2776,7 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - if (pdata->int_codec) + if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); msm_free_auxdev_mem(pdev); diff --git a/sound/soc/msm/msmfalcon-common.h b/sound/soc/msm/msmfalcon-common.h index ff8232d6fcbb..5f6b8592acec 100644 --- a/sound/soc/msm/msmfalcon-common.h +++ b/sound/soc/msm/msmfalcon-common.h @@ -31,12 +31,46 @@ #define SAMPLING_RATE_352P8KHZ 352800 #define SAMPLING_RATE_384KHZ 384000 +#define TDM_CHANNEL_MAX 8 +#define TDM_SLOT_OFFSET_MAX 8 + +enum { + TDM_0 = 0, + TDM_1, + TDM_2, + TDM_3, + TDM_4, + TDM_5, + TDM_6, + TDM_7, + TDM_PORT_MAX, +}; + +enum { + TDM_PRI = 0, + TDM_SEC, + TDM_TERT, + TDM_QUAT, + TDM_INTERFACE_MAX, +}; + +struct tdm_port { + u32 mode; + u32 channel; +}; + extern const struct snd_kcontrol_new msm_common_snd_controls[]; struct msmfalcon_codec { void* (*get_afe_config_fn)(struct snd_soc_codec *codec, enum afe_config_type config_type); }; +enum { + INT_SND_CARD, + EXT_SND_CARD_TASHA, + EXT_SND_CARD_TAVIL, +}; + struct msm_asoc_mach_data { int us_euro_gpio; /* used by gpio driver API */ int hph_en1_gpio; @@ -50,6 +84,7 @@ struct msm_asoc_mach_data { int spk_ext_pa_gpio; int mclk_freq; int lb_mode; + int snd_card_val; u8 micbias1_cap_mode; u8 micbias2_cap_mode; atomic_t int_mclk0_rsc_ref; @@ -57,7 +92,6 @@ struct msm_asoc_mach_data { struct mutex cdc_int_mclk0_mutex; struct delayed_work disable_int_mclk0_work; struct afe_clk_set digital_cdc_core_clk; - bool int_codec; }; int msm_common_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, diff --git a/sound/soc/msm/msmfalcon-ext-dai-links.c b/sound/soc/msm/msmfalcon-ext-dai-links.c index 4dca7908c108..6f066c5945a9 100644 --- a/sound/soc/msm/msmfalcon-ext-dai-links.c +++ b/sound/soc/msm/msmfalcon-ext-dai-links.c @@ -16,6 +16,7 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/pcm.h> +#include <sound/pcm_params.h> #include "qdsp6v2/msm-pcm-routing-v2.h" #include "../codecs/wcd9335.h" #include "msmfalcon-common.h" @@ -25,7 +26,11 @@ #define __CHIPSET__ "MSMFALCON " #define MSM_DAILINK_NAME(name) (__CHIPSET__#name) -static struct snd_soc_card snd_soc_card_msm_card; +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + +static struct snd_soc_card snd_soc_card_msm_card_tavil; +static struct snd_soc_card snd_soc_card_msm_card_tasha; static struct snd_soc_ops msm_ext_slimbus_be_ops = { .hw_params = msm_snd_hw_params, @@ -49,6 +54,222 @@ static struct snd_soc_ops msm_aux_pcm_be_ops = { .shutdown = msm_aux_pcm_snd_shutdown, }; +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", + __func__, tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + static struct snd_soc_dai_link msm_ext_tasha_fe_dai[] = { /* tasha_vifeedback for speaker protection */ { @@ -1167,6 +1388,145 @@ static struct snd_soc_dai_link msm_ext_common_be_dai[] = { .be_hw_params_fixup = msm_ext_be_hw_params_fixup, .ignore_suspend = 1, }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { @@ -1415,13 +1775,66 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { }, }; +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_ext_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_ext_tasha_dai_links[ ARRAY_SIZE(msm_ext_common_fe_dai) + ARRAY_SIZE(msm_ext_tasha_fe_dai) + ARRAY_SIZE(msm_ext_common_be_dai) + ARRAY_SIZE(msm_ext_tasha_be_dai) + ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links)]; +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links)]; static struct snd_soc_dai_link msm_ext_tavil_dai_links[ ARRAY_SIZE(msm_ext_common_fe_dai) + @@ -1429,7 +1842,8 @@ ARRAY_SIZE(msm_ext_tavil_fe_dai) + ARRAY_SIZE(msm_ext_common_be_dai) + ARRAY_SIZE(msm_ext_tavil_be_dai) + ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links)]; +ARRAY_SIZE(msm_auxpcm_be_dai_links) + +ARRAY_SIZE(msm_wcn_be_dai_links)]; /** * populate_snd_card_dailinks - prepares dailink array and initializes card. @@ -1438,13 +1852,24 @@ ARRAY_SIZE(msm_auxpcm_be_dai_links)]; * * Returns card on success or NULL on failure. */ -struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val) { - struct snd_soc_card *card = &snd_soc_card_msm_card; + struct snd_soc_card *card; struct snd_soc_dai_link *msm_ext_dai_links = NULL; int ret, len1, len2, len3, len4; enum codec_variant codec_ver = 0; + if (snd_card_val == EXT_SND_CARD_TASHA) { + card = &snd_soc_card_msm_card_tasha; + } else if (snd_card_val == EXT_SND_CARD_TAVIL) { + card = &snd_soc_card_msm_card_tavil; + } else { + dev_err(dev, "%s: failing as no matching card name\n", + __func__); + return NULL; + } + card->dev = dev; ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { @@ -1484,6 +1909,14 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_auxpcm_be_dai_links)); len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tasha_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } msm_ext_dai_links = msm_ext_tasha_dai_links; } else if (strnstr(card->name, "tavil", strlen(card->name))) { len1 = ARRAY_SIZE(msm_ext_common_fe_dai); @@ -1512,6 +1945,14 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) sizeof(msm_auxpcm_be_dai_links)); len4 += ARRAY_SIZE(msm_auxpcm_be_dai_links); } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(msm_ext_tavil_dai_links + len4, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len4 += ARRAY_SIZE(msm_wcn_be_dai_links); + } msm_ext_dai_links = msm_ext_tavil_dai_links; } else { dev_err(dev, "%s: failing as no matching card name\n", @@ -1520,7 +1961,6 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) } card->dai_link = msm_ext_dai_links; card->num_links = len4; - card->dev = dev; return card; } diff --git a/sound/soc/msm/msmfalcon-external.c b/sound/soc/msm/msmfalcon-external.c index 046c63bb73cf..3934c50c48a9 100644 --- a/sound/soc/msm/msmfalcon-external.c +++ b/sound/soc/msm/msmfalcon-external.c @@ -122,6 +122,7 @@ static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_88P2", "KHZ_96", "KHZ_176P4", "KHZ_192", "KHZ_352P8", "KHZ_384"}; static const char *const spk_function_text[] = {"Off", "On"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; static SOC_ENUM_SINGLE_EXT_DECL(spk_func_en, spk_function_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text); @@ -140,6 +141,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); static int slim_get_sample_rate_val(int sample_rate) { @@ -302,6 +304,59 @@ static int slim_get_port_idx(struct snd_kcontrol *kcontrol) return port_id; } +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (slim_rx_cfg[SLIM_RX_7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ; + slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n", + __func__, + slim_rx_cfg[SLIM_RX_7].sample_rate, + slim_tx_cfg[SLIM_TX_7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -670,6 +725,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { slim_rx_sample_rate_get, slim_rx_sample_rate_put), SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate, slim_rx_sample_rate_get, slim_rx_sample_rate_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), }; static int msm_slim_get_ch_from_beid(int32_t be_id) @@ -1627,6 +1685,21 @@ err_mbhc_cal: EXPORT_SYMBOL(msm_audrx_init); /** + * msm_ext_register_audio_notifier - register SSR notifier. + */ +void msm_ext_register_audio_notifier(void) +{ + int ret; + + ret = audio_notifier_register("msmfalcon", AUDIO_NOTIFIER_ADSP_DOMAIN, + &service_nb); + if (ret < 0) + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); +} +EXPORT_SYMBOL(msm_ext_register_audio_notifier); + +/** * msm_ext_cdc_init - external codec machine specific init. * * @pdev: platform device handle @@ -1650,24 +1723,16 @@ int msm_ext_cdc_init(struct platform_device *pdev, wcd_mbhc_cfg_ptr->anc_micbias = MIC_BIAS_2; wcd_mbhc_cfg_ptr->enable_anc_mic_detect = false; - *card = populate_snd_card_dailinks(&pdev->dev); + *card = populate_snd_card_dailinks(&pdev->dev, pdata->snd_card_val); if (!(*card)) { dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__); ret = -EPROBE_DEFER; goto err; } - (*card)->dev = &pdev->dev; spdev = pdev; platform_set_drvdata(pdev, *card); snd_soc_card_set_drvdata(*card, pdata); is_initial_boot = true; - ret = audio_notifier_register("msmfalcon", AUDIO_NOTIFIER_ADSP_DOMAIN, - &service_nb); - if (ret < 0) { - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - goto err; - } pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio)) diff --git a/sound/soc/msm/msmfalcon-external.h b/sound/soc/msm/msmfalcon-external.h index 24aa7ea53a09..654cb70b9c84 100644 --- a/sound/soc/msm/msmfalcon-external.h +++ b/sound/soc/msm/msmfalcon-external.h @@ -26,12 +26,14 @@ int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, int msm_audrx_init(struct snd_soc_pcm_runtime *rtd); int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); -struct snd_soc_card *populate_snd_card_dailinks(struct device *dev); +struct snd_soc_card *populate_snd_card_dailinks(struct device *dev, + int snd_card_val); int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params); #ifdef CONFIG_SND_SOC_EXT_CODEC int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); +void msm_ext_register_audio_notifier(void); #else inline int msm_ext_cdc_init(struct platform_device *pdev, struct msm_asoc_mach_data *pdata, @@ -40,5 +42,9 @@ inline int msm_ext_cdc_init(struct platform_device *pdev, { return 0; } + +inline void msm_ext_register_audio_notifier(void) +{ +} #endif #endif diff --git a/sound/soc/msm/msmfalcon-internal.c b/sound/soc/msm/msmfalcon-internal.c index 3a8b88cdfb64..180ff492e9e9 100644 --- a/sound/soc/msm/msmfalcon-internal.c +++ b/sound/soc/msm/msmfalcon-internal.c @@ -27,6 +27,9 @@ #define WCD_MBHC_DEF_RLOADS 5 +#define WCN_CDC_SLIM_RX_CH_MAX 2 +#define WCN_CDC_SLIM_TX_CH_MAX 3 + enum { INT0_MI2S = 0, INT1_MI2S, @@ -38,6 +41,24 @@ enum { INT_MI2S_MAX, }; +enum { + BT_SLIM7, + FM_SLIM8, + SLIM_MAX, +}; + +/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */ +static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = { + {0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */ + {AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */ +}; + static struct afe_clk_set int_mi2s_clk[INT_MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, @@ -114,6 +135,11 @@ static struct dev_config int_mi2s_cfg[] = { [INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, }; +static struct dev_config bt_fm_cfg[] = { + [BT_SLIM7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, + [FM_SLIM8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, +}; + static char const *int_mi2s_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32", "KHZ_44P1", "KHZ_48", "KHZ_96", "KHZ_192"}; @@ -122,6 +148,7 @@ static const char *const int_mi2s_tx_ch_text[] = {"One", "Two", "Three", "Four"}; static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"}; static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"}; +static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_48"}; static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_sample_rate, int_mi2s_rate_text); static SOC_ENUM_SINGLE_EXT_DECL(int0_mi2s_rx_chs, int_mi2s_ch_text); @@ -137,6 +164,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_chs, int_mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(int4_mi2s_rx_format, bit_format_text); static SOC_ENUM_SINGLE_EXT_DECL(int5_mi2s_tx_chs, int_mi2s_ch_text); static SOC_ENUM_SINGLE_EXT_DECL(loopback_mclk_en, loopback_mclk_text); +static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text); static int msm_dmic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); @@ -544,7 +572,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, +static int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_soc_dai_link *dai_link = rtd->dai_link; @@ -577,6 +605,38 @@ int int_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int msm_btfm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + switch (dai_link->be_id) { + case MSM_BACKEND_DAI_SLIMBUS_7_RX: + case MSM_BACKEND_DAI_SLIMBUS_7_TX: + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + bt_fm_cfg[BT_SLIM7].bit_format); + rate->min = rate->max = bt_fm_cfg[BT_SLIM7].sample_rate; + channels->min = channels->max = + bt_fm_cfg[BT_SLIM7].channels; + break; + + case MSM_BACKEND_DAI_SLIMBUS_8_TX: + rate->min = rate->max = bt_fm_cfg[FM_SLIM8].sample_rate; + channels->min = channels->max = + bt_fm_cfg[FM_SLIM8].channels; + break; + + default: + rate->min = rate->max = SAMPLING_RATE_48KHZ; + break; + } + return 0; +} + static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -746,6 +806,55 @@ static int loopback_mclk_put(struct snd_kcontrol *kcontrol, return ret; } +static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Slimbus_7_Rx/Tx sample rate values should always be in sync (same) + * when used for BT_SCO use case. Return either Rx or Tx sample rate + * value. + */ + switch (bt_fm_cfg[BT_SLIM7].sample_rate) { + case SAMPLING_RATE_48KHZ: + ucontrol->value.integer.value[0] = 2; + break; + case SAMPLING_RATE_16KHZ: + ucontrol->value.integer.value[0] = 1; + break; + case SAMPLING_RATE_8KHZ: + default: + ucontrol->value.integer.value[0] = 0; + break; + } + pr_debug("%s: sample rate = %d", __func__, + bt_fm_cfg[BT_SLIM7].sample_rate); + + return 0; +} + +static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 1: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_16KHZ; + break; + case 2: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_48KHZ; + break; + case 0: + default: + bt_fm_cfg[BT_SLIM7].sample_rate = SAMPLING_RATE_8KHZ; + break; + } + pr_debug("%s: sample rates: slim7_rx = %d, value = %d\n", + __func__, + bt_fm_cfg[BT_SLIM7].sample_rate, + ucontrol->value.enumerated.item[0]); + + return 0; +} + static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("INT0_MI2S_RX Format", int0_mi2s_rx_format, int_mi2s_bit_format_get, int_mi2s_bit_format_put), @@ -779,6 +888,9 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { int_mi2s_ch_get, int_mi2s_ch_put), SOC_ENUM_EXT("Loopback MCLK", loopback_mclk_en, loopback_mclk_get, loopback_mclk_put), + SOC_ENUM_EXT("BT SampleRate", bt_sample_rate, + msm_bt_sample_rate_get, + msm_bt_sample_rate_put), }; static const struct snd_kcontrol_new msm_swr_controls[] = { @@ -1209,6 +1321,210 @@ static int msm_swr_audrx_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd) +{ + unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158}; + unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161}; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), + tx_ch, ARRAY_SIZE(rx_ch), rx_ch); +} + +static int msm_wcn_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX]; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret; + + dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__, + codec_dai->name, codec_dai->id); + ret = snd_soc_dai_get_channel_map(codec_dai, + &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); + if (ret) { + dev_err(rtd->dev, + "%s: failed to get BTFM codec chan map\n, err:%d\n", + __func__, ret); + goto exit; + } + + dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) be_id %d\n", + __func__, tx_ch_cnt, dai_link->be_id); + + ret = snd_soc_dai_set_channel_map(cpu_dai, + tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch); + if (ret) + dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n", + __func__, ret); + +exit: + return ret; +} + +static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width, + int slots) +{ + unsigned int slot_mask = 0; + int i, j; + unsigned int *slot_offset; + + for (i = TDM_0; i < TDM_PORT_MAX; i++) { + slot_offset = tdm_slot_offset[i]; + + for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) { + if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) + slot_mask |= + (1 << ((slot_offset[j] * 8) / slot_width)); + else + break; + } + } + + return slot_mask; +} + +static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + int channels, slot_width, slots; + unsigned int slot_mask; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id); + + channels = params_channels(params); + switch (channels) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S32_LE: + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S16_LE: + /* + * up to 8 channels HW config should + * use 32 bit slot width for max support of + * stream bit width. (slot_width > bit_width) + */ + slot_width = 32; + break; + default: + pr_err("%s: invalid param format 0x%x\n", + __func__, params_format(params)); + return -EINVAL; + } + slots = 8; + slot_mask = tdm_param_set_slot_mask(cpu_dai->id, + slot_width, + slots); + if (!slot_mask) { + pr_err("%s: invalid slot_mask 0x%x\n", + __func__, slot_mask); + return -EINVAL; + } + break; + default: + pr_err("%s: invalid param channels %d\n", + __func__, channels); + return -EINVAL; + } + /* currently only supporting TDM_RX_0 and TDM_TX_0 */ + switch (cpu_dai->id) { + case AFE_PORT_ID_PRIMARY_TDM_RX: + case AFE_PORT_ID_SECONDARY_TDM_RX: + case AFE_PORT_ID_TERTIARY_TDM_RX: + case AFE_PORT_ID_QUATERNARY_TDM_RX: + case AFE_PORT_ID_PRIMARY_TDM_TX: + case AFE_PORT_ID_SECONDARY_TDM_TX: + case AFE_PORT_ID_TERTIARY_TDM_TX: + case AFE_PORT_ID_QUATERNARY_TDM_TX: + slot_offset = tdm_slot_offset[TDM_0]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + else + break; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d exceed offset_channels %d\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL, + channels, slot_offset); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } else { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0, + slots, slot_width); + if (ret < 0) { + pr_err("%s: failed to set tdm slot, err:%d\n", + __func__, ret); + goto end; + } + + ret = snd_soc_dai_set_channel_map(cpu_dai, channels, + slot_offset, 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops msm_tdm_be_ops = { + .hw_params = msm_tdm_snd_hw_params +}; + +static struct snd_soc_ops msm_wcn_ops = { + .hw_params = msm_wcn_hw_params, +}; + static struct snd_soc_ops msm_mi2s_be_ops = { .startup = msm_mi2s_snd_startup, .shutdown = msm_mi2s_snd_shutdown, @@ -2029,6 +2345,145 @@ static struct snd_soc_dai_link msm_int_dai[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, + { + .name = LPASS_BE_USB_AUDIO_RX, + .stream_name = "USB Audio Playback", + .cpu_dai_name = "msm-dai-q6-dev.28672", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_USB_RX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_USB_AUDIO_TX, + .stream_name = "USB Audio Capture", + .cpu_dai_name = "msm-dai-q6-dev.28673", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_USB_TX, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_RX_0, + .stream_name = "Primary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36864", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_PRI_TDM_TX_0, + .stream_name = "Primary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36865", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_RX_0, + .stream_name = "Secondary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36880", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_TDM_TX_0, + .stream_name = "Secondary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36881", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SEC_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_RX_0, + .stream_name = "Tertiary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36896", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_TDM_TX_0, + .stream_name = "Tertiary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36897", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_RX_0, + .stream_name = "Quaternary TDM0 Playback", + .cpu_dai_name = "msm-dai-q6-tdm.36912", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_TDM_TX_0, + .stream_name = "Quaternary TDM0 Capture", + .cpu_dai_name = "msm-dai-q6-tdm.36913", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUAT_TDM_TX_0, + .be_hw_params_fixup = msm_common_be_hw_params_fixup, + .ops = &msm_tdm_be_ops, + .ignore_suspend = 1, + }, }; static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { @@ -2277,10 +2732,64 @@ static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = { }, }; + +static struct snd_soc_dai_link msm_wcn_be_dai_links[] = { + { + .name = LPASS_BE_SLIMBUS_7_RX, + .stream_name = "Slimbus7 Playback", + .cpu_dai_name = "msm-dai-q6-dev.16398", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + /* BT codec driver determines capabilities based on + * dai name, bt codecdai name should always contains + * supported usecase information + */ + .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_RX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + /* dai link has playback support */ + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_7_TX, + .stream_name = "Slimbus7 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16399", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_bt_sco_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_7_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SLIMBUS_8_TX, + .stream_name = "Slimbus8 Capture", + .cpu_dai_name = "msm-dai-q6-dev.16401", + .platform_name = "msm-pcm-routing", + .codec_name = "btfmslim_slave", + .codec_dai_name = "btfm_fm_slim_tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SLIMBUS_8_TX, + .be_hw_params_fixup = msm_btfm_be_hw_params_fixup, + .init = &msm_wcn_init, + .ops = &msm_wcn_ops, + .ignore_suspend = 1, + }, +}; + static struct snd_soc_dai_link msm_int_dai_links[ ARRAY_SIZE(msm_int_dai) + ARRAY_SIZE(msm_mi2s_be_dai_links) + -ARRAY_SIZE(msm_auxpcm_be_dai_links)]; +ARRAY_SIZE(msm_auxpcm_be_dai_links)+ +ARRAY_SIZE(msm_wcn_be_dai_links)]; static struct snd_soc_card msmfalcon_card = { /* snd_soc_card_msmfalcon */ @@ -2357,6 +2866,14 @@ static struct snd_soc_card *msm_int_populate_sndcard_dailinks( sizeof(msm_auxpcm_be_dai_links)); len1 += ARRAY_SIZE(msm_auxpcm_be_dai_links); } + if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) { + dev_dbg(dev, "%s(): WCN BTFM support present\n", + __func__); + memcpy(dailink + len1, + msm_wcn_be_dai_links, + sizeof(msm_wcn_be_dai_links)); + len1 += ARRAY_SIZE(msm_wcn_be_dai_links); + } card->dai_link = dailink; card->num_links = len1; return card; diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index a2cd6c6f98db..90371b8e27f4 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -127,6 +127,11 @@ struct msm_compr_audio { uint64_t bytes_received; /* from userspace */ uint64_t bytes_sent; /* to DSP */ + uint64_t received_total; /* bytes received from DSP */ + uint64_t bytes_copied; /* to userspace */ + uint64_t bytes_read; /* from DSP */ + uint32_t bytes_read_offset; /* bytes read offset*/ + int32_t first_buffer; int32_t last_buffer; int32_t partial_drain_delay; @@ -362,6 +367,49 @@ static int msm_compr_send_buffer(struct msm_compr_audio *prtd) return 0; } +static int msm_compr_read_buffer(struct msm_compr_audio *prtd) +{ + int buffer_length; + uint64_t bytes_available; + uint64_t buffer_sent; + struct audio_aio_read_param param; + int ret; + + if (!atomic_read(&prtd->start)) { + pr_err("%s: stream is not in started state\n", __func__); + return -EINVAL; + } + + buffer_length = prtd->codec_param.buffer.fragment_size; + bytes_available = prtd->received_total - prtd->bytes_copied; + buffer_sent = prtd->bytes_read - prtd->bytes_copied; + if (buffer_sent + buffer_length > prtd->buffer_size) { + pr_debug(" %s : Buffer is Full bytes_available: %llu\n", + __func__, bytes_available); + return 0; + } + + memset(¶m, 0x0, sizeof(struct audio_aio_read_param)); + param.paddr = prtd->buffer_paddr + prtd->bytes_read_offset; + param.len = buffer_length; + param.uid = buffer_length; + + pr_debug("%s: reading %d bytes from DSP byte_offset = %llu\n", + __func__, buffer_length, prtd->bytes_read); + ret = q6asm_async_read(prtd->audio_client, ¶m); + if (ret < 0) { + pr_err("%s: q6asm_async_read failed - %d\n", + __func__, ret); + return ret; + } + prtd->bytes_read += buffer_length; + prtd->bytes_read_offset += buffer_length; + if (prtd->bytes_read_offset >= prtd->buffer_size) + prtd->bytes_read_offset -= prtd->buffer_size; + + return 0; +} + static void compr_event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv) { @@ -374,6 +422,7 @@ static void compr_event_handler(uint32_t opcode, int stream_id; uint32_t stream_index; unsigned long flags; + uint64_t read_size; if (!prtd) { pr_err("%s: prtd is NULL\n", __func__); @@ -459,6 +508,32 @@ static void compr_event_handler(uint32_t opcode, spin_unlock_irqrestore(&prtd->lock, flags); break; + + case ASM_DATA_EVENT_READ_DONE_V2: + spin_lock_irqsave(&prtd->lock, flags); + + pr_debug("ASM_DATA_EVENT_READ_DONE_V2 offset %d, length %d\n", + prtd->byte_offset, payload[4]); + /* Always assume read_size is same as fragment_size */ + read_size = prtd->codec_param.buffer.fragment_size; + prtd->byte_offset += read_size; + prtd->received_total += read_size; + if (prtd->byte_offset >= prtd->buffer_size) + prtd->byte_offset -= prtd->buffer_size; + + snd_compr_fragment_elapsed(cstream); + + if (!atomic_read(&prtd->start)) { + pr_debug("read_done received while not started, treat as xrun"); + atomic_set(&prtd->xrun, 1); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + msm_compr_read_buffer(prtd); + + spin_unlock_irqrestore(&prtd->lock, flags); + break; + case ASM_DATA_EVENT_RENDERED_EOS: spin_lock_irqsave(&prtd->lock, flags); pr_debug("%s: ASM_DATA_CMDRSP_EOS token 0x%x,stream id %d\n", @@ -511,6 +586,14 @@ static void compr_event_handler(uint32_t opcode, /* FIXME: A state is a better way, dealing with this*/ spin_lock_irqsave(&prtd->lock, flags); + + if (cstream->direction == SND_COMPRESS_CAPTURE) { + atomic_set(&prtd->start, 1); + msm_compr_read_buffer(prtd); + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } + if (!prtd->bytes_sent) { bytes_available = prtd->bytes_received - prtd->copied_total; if (bytes_available < cstream->runtime->fragment_size) { @@ -958,7 +1041,8 @@ static int msm_compr_init_pp_params(struct snd_compr_stream *cstream, return ret; } -static int msm_compr_configure_dsp(struct snd_compr_stream *cstream) +static int msm_compr_configure_dsp_for_playback + (struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; @@ -1096,7 +1180,103 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream) return ret; } -static int msm_compr_open(struct snd_compr_stream *cstream) +static int msm_compr_configure_dsp_for_capture(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *soc_prtd = cstream->private_data; + uint16_t bits_per_sample; + uint16_t sample_word_size; + int dir = OUT, ret = 0; + struct audio_client *ac = prtd->audio_client; + uint32_t stream_index; + + switch (prtd->codec_param.codec.format) { + case SNDRV_PCM_FORMAT_S24_LE: + bits_per_sample = 24; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + bits_per_sample = 24; + sample_word_size = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bits_per_sample = 32; + sample_word_size = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + bits_per_sample = 16; + sample_word_size = 16; + break; + } + + pr_debug("%s: stream_id %d bits_per_sample %d\n", + __func__, ac->stream_id, bits_per_sample); + + ret = q6asm_open_read_v3(prtd->audio_client, FORMAT_LINEAR_PCM, + bits_per_sample); + if (ret < 0) { + pr_err("%s: q6asm_open_read failed:%d\n", __func__, ret); + return ret; + } + + ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id, + ac->perf_mode, + prtd->session_id, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) { + pr_err("%s: stream reg failed:%d\n", __func__, ret); + return ret; + } + + ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE)); + if (ret < 0) { + pr_err("%s: Set IO mode failed\n", __func__); + return -EINVAL; + } + + stream_index = STREAM_ARRAY_INDEX(ac->stream_id); + if (stream_index >= MAX_NUMBER_OF_STREAMS || stream_index < 0) { + pr_err("%s: Invalid stream index:%d", __func__, stream_index); + return -EINVAL; + } + + runtime->fragments = prtd->codec_param.buffer.fragments; + runtime->fragment_size = prtd->codec_param.buffer.fragment_size; + pr_debug("%s: allocate %d buffers each of size %d\n", + __func__, runtime->fragments, + runtime->fragment_size); + ret = q6asm_audio_client_buf_alloc_contiguous(dir, ac, + runtime->fragment_size, + runtime->fragments); + if (ret < 0) { + pr_err("Audio Start: Buffer Allocation failed rc = %d\n", ret); + return -ENOMEM; + } + + prtd->byte_offset = 0; + prtd->received_total = 0; + prtd->app_pointer = 0; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->buffer = ac->port[dir].buf[0].data; + prtd->buffer_paddr = ac->port[dir].buf[0].phys; + prtd->buffer_size = runtime->fragments * runtime->fragment_size; + + + pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n", + __func__, prtd->sample_rate, prtd->num_channels, + bits_per_sample, sample_word_size); + ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client, + prtd->sample_rate, prtd->num_channels, + bits_per_sample, sample_word_size); + + return ret; +} + +static int msm_compr_playback_open(struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; @@ -1181,15 +1361,80 @@ static int msm_compr_open(struct snd_compr_stream *cstream) kfree(prtd); return -ENOMEM; } + pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session); + prtd->audio_client->perf_mode = false; + prtd->session_id = prtd->audio_client->session; + + return 0; +} +static int msm_compr_capture_open(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct msm_compr_audio *prtd; + struct msm_compr_pdata *pdata = + snd_soc_platform_get_drvdata(rtd->platform); + + pr_debug("%s\n", __func__); + prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL); + if (prtd == NULL) { + pr_err("Failed to allocate memory for msm_compr_audio\n"); + return -ENOMEM; + } + + runtime->private_data = NULL; + prtd->cstream = cstream; + pdata->cstream[rtd->dai_link->be_id] = cstream; + + prtd->audio_client = q6asm_audio_client_alloc( + (app_cb)compr_event_handler, prtd); + if (!prtd->audio_client) { + pr_err("%s: Could not allocate memory for client\n", __func__); + pdata->cstream[rtd->dai_link->be_id] = NULL; + kfree(prtd); + return -ENOMEM; + } pr_debug("%s: session ID %d\n", __func__, prtd->audio_client->session); prtd->audio_client->perf_mode = false; prtd->session_id = prtd->audio_client->session; + prtd->codec = FORMAT_LINEAR_PCM; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->received_total = 0; + prtd->byte_offset = 0; + prtd->sample_rate = 48000; + prtd->num_channels = 2; + prtd->first_buffer = 0; + + spin_lock_init(&prtd->lock); + + atomic_set(&prtd->eos, 0); + atomic_set(&prtd->start, 0); + atomic_set(&prtd->drain, 0); + atomic_set(&prtd->xrun, 0); + atomic_set(&prtd->close, 0); + atomic_set(&prtd->wait_on_close, 0); + atomic_set(&prtd->error, 0); + + runtime->private_data = prtd; return 0; } -static int msm_compr_free(struct snd_compr_stream *cstream) +static int msm_compr_open(struct snd_compr_stream *cstream) +{ + int ret = 0; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_open(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_open(cstream); + return ret; +} + +static int msm_compr_playback_free(struct snd_compr_stream *cstream) { struct snd_compr_runtime *runtime; struct msm_compr_audio *prtd; @@ -1284,6 +1529,76 @@ static int msm_compr_free(struct snd_compr_stream *cstream) return 0; } +static int msm_compr_capture_free(struct snd_compr_stream *cstream) +{ + struct snd_compr_runtime *runtime; + struct msm_compr_audio *prtd; + struct snd_soc_pcm_runtime *soc_prtd; + struct msm_compr_pdata *pdata; + struct audio_client *ac; + int dir = OUT, stream_id; + unsigned long flags; + uint32_t stream_index; + + if (!cstream) { + pr_err("%s cstream is null\n", __func__); + return 0; + } + runtime = cstream->runtime; + soc_prtd = cstream->private_data; + if (!runtime || !soc_prtd || !(soc_prtd->platform)) { + pr_err("%s runtime or soc_prtd or platform is null\n", + __func__); + return 0; + } + prtd = runtime->private_data; + if (!prtd) { + pr_err("%s prtd is null\n", __func__); + return 0; + } + pdata = snd_soc_platform_get_drvdata(soc_prtd->platform); + ac = prtd->audio_client; + if (!pdata || !ac) { + pr_err("%s pdata or ac is null\n", __func__); + return 0; + } + + spin_lock_irqsave(&prtd->lock, flags); + stream_id = ac->stream_id; + + stream_index = STREAM_ARRAY_INDEX(stream_id); + if ((stream_index < MAX_NUMBER_OF_STREAMS && stream_index >= 0)) { + spin_unlock_irqrestore(&prtd->lock, flags); + pr_debug("close stream %d", stream_id); + q6asm_stream_cmd(ac, CMD_CLOSE, stream_id); + spin_lock_irqsave(&prtd->lock, flags); + } + spin_unlock_irqrestore(&prtd->lock, flags); + + pdata->cstream[soc_prtd->dai_link->be_id] = NULL; + msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, + SNDRV_PCM_STREAM_CAPTURE); + + q6asm_audio_client_buf_free_contiguous(dir, ac); + + q6asm_audio_client_free(ac); + + kfree(prtd); + + return 0; +} + +static int msm_compr_free(struct snd_compr_stream *cstream) +{ + int ret = 0; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_free(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_free(cstream); + return ret; +} + static bool msm_compr_validate_codec_compr(__u32 codec_id) { int32_t i; @@ -1449,7 +1764,10 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream, prtd->partial_drain_delay = msm_compr_get_partial_drain_delay(frame_sz, prtd->sample_rate); - ret = msm_compr_configure_dsp(cstream); + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_configure_dsp_for_playback(cstream); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_configure_dsp_for_capture(cstream); return ret; } @@ -1539,11 +1857,6 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) uint32_t stream_index; uint16_t bits_per_sample = 16; - if (cstream->direction != SND_COMPRESS_PLAYBACK) { - pr_err("%s: Unsupported stream type\n", __func__); - return -EINVAL; - } - spin_lock_irqsave(&prtd->lock, flags); if (atomic_read(&prtd->error)) { pr_err("%s Got RESET EVENTS notification, return immediately", @@ -1566,7 +1879,8 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) * compress passthrough volume is controlled in * ADM by adm_send_compressed_device_mute() */ - if (prtd->compr_passthr == LEGACY_PCM) { + if (prtd->compr_passthr == LEGACY_PCM && + cstream->direction == SND_COMPRESS_PLAYBACK) { /* set volume for the stream before RUN */ rc = msm_compr_set_volume(cstream, volume[0], volume[1]); @@ -1578,8 +1892,9 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) if (rc) pr_err("%s : init PP params failed : %d\n", __func__, rc); + } else { + msm_compr_read_buffer(prtd); } - /* issue RUN command for the stream */ q6asm_run_nowait(prtd->audio_client, 0, 0, 0); break; @@ -1589,6 +1904,18 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) prtd->gapless_state.gapless_transition); stream_id = ac->stream_id; atomic_set(&prtd->start, 0); + if (cstream->direction == SND_COMPRESS_CAPTURE) { + q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); + atomic_set(&prtd->xrun, 0); + prtd->received_total = 0; + prtd->bytes_copied = 0; + prtd->bytes_read = 0; + prtd->bytes_read_offset = 0; + prtd->byte_offset = 0; + prtd->app_pointer = 0; + spin_unlock_irqrestore(&prtd->lock, flags); + break; + } if (prtd->next_stream) { pr_debug("%s: interrupt next track wait queues\n", __func__); @@ -1979,7 +2306,7 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd) } static int msm_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *arg) + struct snd_compr_tstamp *arg) { struct snd_compr_runtime *runtime = cstream->runtime; struct snd_soc_pcm_runtime *rtd = cstream->private_data; @@ -1998,7 +2325,10 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, spin_lock_irqsave(&prtd->lock, flags); tstamp.sampling_rate = prtd->sample_rate; tstamp.byte_offset = prtd->byte_offset; - tstamp.copied_total = prtd->copied_total; + if (cstream->direction == SND_COMPRESS_PLAYBACK) + tstamp.copied_total = prtd->copied_total; + else if (cstream->direction == SND_COMPRESS_CAPTURE) + tstamp.copied_total = prtd->received_total; first_buffer = prtd->first_buffer; if (atomic_read(&prtd->error)) { pr_err("%s Got RESET EVENTS notification, return error\n", @@ -2012,37 +2342,39 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream, spin_unlock_irqrestore(&prtd->lock, flags); return -ENETRESET; } + if (cstream->direction == SND_COMPRESS_PLAYBACK) { - gapless_transition = prtd->gapless_state.gapless_transition; - spin_unlock_irqrestore(&prtd->lock, flags); - - if (gapless_transition) - pr_debug("%s session time in gapless transition", - __func__); - - /* - - Do not query if no buffer has been given. - - Do not query on a gapless transition. - Playback for the 2nd stream can start (thus returning time - starting from 0) before the driver knows about EOS of first stream. - */ - - if (!first_buffer && !gapless_transition) { - if (pdata->use_legacy_api) - rc = q6asm_get_session_time_legacy(prtd->audio_client, - &prtd->marker_timestamp); - else - rc = q6asm_get_session_time(prtd->audio_client, - &prtd->marker_timestamp); + gapless_transition = prtd->gapless_state.gapless_transition; + spin_unlock_irqrestore(&prtd->lock, flags); + if (gapless_transition) + pr_debug("%s session time in gapless transition", + __func__); + /* + *- Do not query if no buffer has been given. + *- Do not query on a gapless transition. + * Playback for the 2nd stream can start (thus returning time + * starting from 0) before the driver knows about EOS of first + * stream. + */ + if (!first_buffer || gapless_transition) { - if (rc < 0) { - pr_err("%s: Get Session Time return value =%lld\n", - __func__, timestamp); - if (atomic_read(&prtd->error)) - return -ENETRESET; + if (pdata->use_legacy_api) + rc = q6asm_get_session_time_legacy( + prtd->audio_client, &prtd->marker_timestamp); else - return -EAGAIN; + rc = q6asm_get_session_time( + prtd->audio_client, &prtd->marker_timestamp); + if (rc < 0) { + pr_err("%s: Get Session Time return =%lld\n", + __func__, timestamp); + if (atomic_read(&prtd->error)) + return -ENETRESET; + else + return -EAGAIN; + } } + } else { + spin_unlock_irqrestore(&prtd->lock, flags); } timestamp = prtd->marker_timestamp; @@ -2103,8 +2435,8 @@ static int msm_compr_ack(struct snd_compr_stream *cstream, return 0; } -static int msm_compr_copy(struct snd_compr_stream *cstream, - char __user *buf, size_t count) +static int msm_compr_playback_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) { struct snd_compr_runtime *runtime = cstream->runtime; struct msm_compr_audio *prtd = runtime->private_data; @@ -2166,6 +2498,60 @@ static int msm_compr_copy(struct snd_compr_stream *cstream, return count; } +static int msm_compr_capture_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + struct snd_compr_runtime *runtime = cstream->runtime; + struct msm_compr_audio *prtd = runtime->private_data; + void *source; + unsigned long flags; + + pr_debug("%s: count = %zd\n", __func__, count); + if (!prtd->buffer) { + pr_err("%s: Buffer is not allocated yet ??", __func__); + return 0; + } + + spin_lock_irqsave(&prtd->lock, flags); + if (atomic_read(&prtd->error)) { + pr_err("%s Got RESET EVENTS notification", __func__); + spin_unlock_irqrestore(&prtd->lock, flags); + return -ENETRESET; + } + + source = prtd->buffer + prtd->app_pointer; + /* check if we have requested amount of data to copy to user*/ + if (count <= prtd->received_total - prtd->bytes_copied) { + spin_unlock_irqrestore(&prtd->lock, flags); + if (copy_to_user(buf, source, count)) { + pr_err("copy_to_user failed"); + return -EFAULT; + } + spin_lock_irqsave(&prtd->lock, flags); + prtd->app_pointer += count; + if (prtd->app_pointer >= prtd->buffer_size) + prtd->app_pointer -= prtd->buffer_size; + prtd->bytes_copied += count; + } + msm_compr_read_buffer(prtd); + + spin_unlock_irqrestore(&prtd->lock, flags); + return count; +} + +static int msm_compr_copy(struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + int ret = 0; + + pr_debug(" In %s\n", __func__); + if (cstream->direction == SND_COMPRESS_PLAYBACK) + ret = msm_compr_playback_copy(cstream, buf, count); + else if (cstream->direction == SND_COMPRESS_CAPTURE) + ret = msm_compr_capture_copy(cstream, buf, count); + return ret; +} + static int msm_compr_get_caps(struct snd_compr_stream *cstream, struct snd_compr_caps *arg) { diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c index 718f7017342b..f1f2fd908eca 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -2645,8 +2645,10 @@ static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = { .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000, + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, @@ -2667,8 +2669,10 @@ static struct snd_soc_dai_driver msm_dai_q6_usb_tx_dai = { .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_384000, + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | + SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_352800 | + SNDRV_PCM_RATE_384000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 1, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 9681330be33b..a456cc2ab857 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -280,11 +280,19 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { { SLIMBUS_1_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX}, { SLIMBUS_1_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX}, { SLIMBUS_2_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX}, - { SLIMBUS_4_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, - { SLIMBUS_4_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_2_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX}, { SLIMBUS_3_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX}, { SLIMBUS_3_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX}, + { SLIMBUS_4_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX}, + { SLIMBUS_4_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX}, + { SLIMBUS_5_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, { SLIMBUS_5_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX}, + { SLIMBUS_6_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, + { SLIMBUS_6_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, + { SLIMBUS_7_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, + { SLIMBUS_7_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, + { SLIMBUS_8_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, + { SLIMBUS_8_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX}, { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX}, { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX}, @@ -310,12 +318,9 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_SEC_AUXPCM_RX}, { AFE_PORT_ID_SECONDARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_AUXPCM_TX}, - { SLIMBUS_6_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX}, - { SLIMBUS_6_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX}, { AFE_PORT_ID_SPDIF_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX}, { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_MI2S_RX_SD1}, - { SLIMBUS_5_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX}, { AFE_PORT_ID_QUINARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUIN_MI2S_RX}, { AFE_PORT_ID_QUINARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, @@ -451,10 +456,6 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_QUAT_TDM_TX_7}, { INT_BT_A2DP_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX}, - { SLIMBUS_7_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX}, - { SLIMBUS_7_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, - { SLIMBUS_8_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, - { SLIMBUS_8_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, { AFE_PORT_ID_USB_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX}, { AFE_PORT_ID_USB_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX}, { DISPLAY_PORT_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT}, @@ -547,6 +548,15 @@ static struct msm_pcm_routing_fdai_data /* MULTIMEDIA16 */ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA17 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA18 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, + /* MULTIMEDIA19 */ + {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} }, + {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } }, }; static unsigned long session_copp_map[MSM_FRONTEND_DAI_MM_SIZE][2] @@ -2257,6 +2267,11 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul2 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul3 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL3 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static const struct snd_kcontrol_new ext_ec_ref_mux_ul4 = SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL4 MUX Mux", msm_route_ec_ref_rx_enum[0], @@ -2282,6 +2297,21 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul9 = msm_route_ec_ref_rx_enum[0], msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); +static const struct snd_kcontrol_new ext_ec_ref_mux_ul17 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL17 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul18 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL18 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + +static const struct snd_kcontrol_new ext_ec_ref_mux_ul19 = + SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL19 MUX Mux", + msm_route_ec_ref_rx_enum[0], + msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put); + static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2411,6 +2441,15 @@ static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { @@ -2462,6 +2501,15 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_I2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_I2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { @@ -2513,6 +2561,16 @@ static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SPDIF_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SPDIF_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + }; static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = { @@ -2615,6 +2673,15 @@ static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_5_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { @@ -2666,6 +2733,15 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { @@ -2717,6 +2793,15 @@ static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { @@ -2768,6 +2853,15 @@ static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { @@ -2819,6 +2913,15 @@ static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUINARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { @@ -2834,9 +2937,15 @@ static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), @@ -2858,6 +2967,15 @@ static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { @@ -2915,15 +3033,15 @@ static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), -}; - -static const struct snd_kcontrol_new mi2s_hl_mixer_controls[] = { - SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), - SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { @@ -2975,6 +3093,15 @@ static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_MI2S_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_MI2S_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = { @@ -3128,6 +3255,15 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_HDMI_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new display_port_mixer_controls[] = { @@ -3429,6 +3565,15 @@ static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = { @@ -3531,6 +3676,15 @@ static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_INT_FM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_FM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { @@ -3582,6 +3736,15 @@ static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AFE_PCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { @@ -3633,6 +3796,15 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { @@ -3684,6 +3856,15 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = { @@ -4536,10 +4717,10 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, @@ -4908,10 +5089,10 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0, @@ -5015,6 +5196,77 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new mmul17_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul18_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new mmul19_mixer_controls[] = { + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, @@ -5091,6 +5343,12 @@ static const struct snd_kcontrol_new sec_mi2s_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = { @@ -5223,6 +5481,9 @@ static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_INT_BT_SCO_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_INT_BT_SCO_RX , MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), @@ -6159,10 +6420,10 @@ static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -6198,10 +6459,10 @@ static const struct snd_kcontrol_new tx_voice2_stub_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -6243,10 +6504,10 @@ static const struct snd_kcontrol_new tx_volte_stub_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX, MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, msm_routing_put_voice_stub_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX, @@ -6342,10 +6603,10 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, @@ -6354,6 +6615,9 @@ static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), @@ -6405,7 +6669,7 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = { }; static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_TERT_AUXPCM_RX, @@ -6417,7 +6681,7 @@ static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = { }; static const struct snd_kcontrol_new quat_auxpcm_rx_port_mixer_controls[] = { - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_RX, @@ -6441,10 +6705,10 @@ static const struct snd_kcontrol_new sbus_1_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("TERT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_SINGLE_EXT("TERT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_TERT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("QUAT_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, + SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_QUAT_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; @@ -7161,17 +7425,20 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = { SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, - msm_routing_put_port_mixer), SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), - SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, - MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer, + SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer, + msm_routing_put_port_mixer), + SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX, + MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer, msm_routing_put_port_mixer), }; @@ -7313,7 +7580,7 @@ static const struct soc_enum aanc_slim_0_rx_enum = aanc_slim_0_rx_text); static const struct snd_kcontrol_new aanc_slim_0_rx_mux[] = { - SOC_DAPM_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, + SOC_ENUM_EXT("AANC_SLIM_0_RX MUX", aanc_slim_0_rx_enum, msm_routing_slim_0_rx_aanc_mux_get, msm_routing_slim_0_rx_aanc_mux_put) }; @@ -8080,6 +8347,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("MM_UL9", "MultiMedia9 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL17", "MultiMedia17 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0), @@ -8115,10 +8385,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("SLIM4_UL_HL", "SLIMBUS4_HOSTLESS Capture", 0, 0, 0, 0), - SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", - 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIM6_DL_HL", "SLIMBUS6_HOSTLESS Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM6_UL_HL", "SLIMBUS6_HOSTLESS Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIM8_DL_HL", "SLIMBUS8_HOSTLESS Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SLIM8_UL_HL", "SLIMBUS8_HOSTLESS Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("INTFM_DL_HL", "INT_FM_HOSTLESS Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture", @@ -8430,8 +8704,11 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture", + 0, 0, 0, 0), SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback", 0, 0, 0 , 0), SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture", @@ -8669,8 +8946,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MUX("LSM6 MUX", SND_SOC_NOPM, 0, 0, &lsm6_mux), SND_SOC_DAPM_MUX("LSM7 MUX", SND_SOC_NOPM, 0, 0, &lsm7_mux), SND_SOC_DAPM_MUX("LSM8 MUX", SND_SOC_NOPM, 0, 0, &lsm8_mux), - SND_SOC_DAPM_MUX("SLIM_0_RX AANC MUX", SND_SOC_NOPM, 0, 0, - aanc_slim_0_rx_mux), /* Mixer definitions */ SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -8705,9 +8980,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SEC_MI2S_RX_SD1 Audio Mixer", SND_SOC_NOPM, 0, 0, secondary_mi2s_rx2_mixer_controls, ARRAY_SIZE(secondary_mi2s_rx2_mixer_controls)), - SND_SOC_DAPM_MIXER("SEC_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0, - mi2s_hl_mixer_controls, - ARRAY_SIZE(mi2s_hl_mixer_controls)), SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, primary_mi2s_rx_mixer_controls, ARRAY_SIZE(primary_mi2s_rx_mixer_controls)), @@ -8776,6 +9048,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)), SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0, mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0, + mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0, + mmul18_mixer_controls, ARRAY_SIZE(mmul18_mixer_controls)), + SND_SOC_DAPM_MIXER("MultiMedia19 Mixer", SND_SOC_NOPM, 0, 0, + mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)), SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0, @@ -9028,6 +9306,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul1), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL2 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul2), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL3 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul3), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL4 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul4), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL5 MUX", SND_SOC_NOPM, 0, 0, @@ -9038,6 +9318,12 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { &ext_ec_ref_mux_ul8), SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL9 MUX", SND_SOC_NOPM, 0, 0, &ext_ec_ref_mux_ul9), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL17 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul17), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL18 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul18), + SND_SOC_DAPM_MUX("AUDIO_REF_EC_UL19 MUX", SND_SOC_NOPM, 0, 0, + &ext_ec_ref_mux_ul19), }; static const struct snd_soc_dapm_route intercon[] = { @@ -9265,9 +9551,15 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"}, {"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"}, {"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, @@ -9691,10 +9983,10 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "SEC_AUX_PCM_TX", "SEC_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "TERT_AUX_PCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "TERT_AUX_PCM_TX", "TERT_AUX_PCM_TX"}, - {"MultiMedia1 Mixer", "QUAT_AUX_PCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"MultiMedia1 Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia3 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia5 Mixer", "QUAT_AUX_PCM_TX", "QUAT_AUX_PCM_TX"}, {"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, @@ -9862,10 +10154,16 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia3 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia4 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"}, {"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia4 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, + {"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, @@ -9873,6 +10171,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia3 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia4 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"}, + {"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"}, {"MM_UL1", NULL, "MultiMedia1 Mixer"}, @@ -9883,6 +10184,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL5", NULL, "MultiMedia5 Mixer"}, {"MM_UL6", NULL, "MultiMedia6 Mixer"}, {"MM_UL8", NULL, "MultiMedia8 Mixer"}, + {"MM_UL17", NULL, "MultiMedia17 Mixer"}, + {"MM_UL18", NULL, "MultiMedia18 Mixer"}, + {"MM_UL19", NULL, "MultiMedia19 Mixer"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, @@ -10048,6 +10352,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"}, {"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, @@ -10230,6 +10536,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL2 MUX", "TERT_MI2S_TX" , "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL2 MUX", "QUAT_MI2S_TX" , "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL3 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL4 MUX", "PRI_MI2S_TX" , "PRI_MI2S_TX"}, {"AUDIO_REF_EC_UL4 MUX", "SEC_MI2S_TX" , "SEC_MI2S_TX"}, {"AUDIO_REF_EC_UL4 MUX", "TERT_MI2S_TX" , "TERT_MI2S_TX"}, @@ -10255,6 +10566,21 @@ static const struct snd_soc_dapm_route intercon[] = { {"AUDIO_REF_EC_UL9 MUX", "TERT_MI2S_TX" , "TERT_MI2S_TX"}, {"AUDIO_REF_EC_UL9 MUX", "QUAT_MI2S_TX" , "QUAT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL17 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL18 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL18 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + + {"AUDIO_REF_EC_UL19 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"}, + {"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MM_UL1", NULL, "AUDIO_REF_EC_UL1 MUX"}, {"MM_UL2", NULL, "AUDIO_REF_EC_UL2 MUX"}, {"MM_UL3", NULL, "AUDIO_REF_EC_UL3 MUX"}, @@ -10263,6 +10589,9 @@ static const struct snd_soc_dapm_route intercon[] = { {"MM_UL6", NULL, "AUDIO_REF_EC_UL6 MUX"}, {"MM_UL8", NULL, "AUDIO_REF_EC_UL8 MUX"}, {"MM_UL9", NULL, "AUDIO_REF_EC_UL9 MUX"}, + {"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"}, + {"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"}, + {"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"}, {"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"}, {"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"}, @@ -10482,11 +10811,11 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT_FM_RX", NULL, "INTFM_DL_HL"}, {"INTFM_UL_HL", NULL, "INT_FM_TX"}, - {"INTHFP_UL_HL", "NULL", "HFP_PRI_AUX_UL_HL"}, + {"INTHFP_UL_HL", NULL, "HFP_PRI_AUX_UL_HL"}, {"HFP_PRI_AUX_UL_HL", "Switch", "AUX_PCM_TX"}, - {"INTHFP_UL_HL", "NULL", "HFP_AUX_UL_HL"}, + {"INTHFP_UL_HL", NULL, "HFP_AUX_UL_HL"}, {"HFP_AUX_UL_HL", "Switch", "SEC_AUX_PCM_TX"}, - {"INTHFP_UL_HL", "NULL", "HFP_INT_UL_HL"}, + {"INTHFP_UL_HL", NULL, "HFP_INT_UL_HL"}, {"HFP_INT_UL_HL", "Switch", "INT_BT_SCO_TX"}, {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"}, {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"}, @@ -10688,8 +11017,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_0_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"}, {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "TERT_AUX_PCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"SLIMBUS_0_RX Port Mixer", "QUAT_AUX_PCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"SLIMBUS_0_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"SLIMBUS_0_RX Port Mixer", "MI2S_TX", "MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"SLIMBUS_0_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, @@ -10713,12 +11042,12 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"}, {"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"TERT_AUXPCM_RX Port Mixer", "TERT_AUX_PCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"TERT_AUXPCM_RX Port Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, {"TERT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"TERT_AUX_PCM_RX", NULL, "TERT_AUXPCM_RX Port Mixer"}, {"QUAT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, - {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUX_PCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"QUAT_AUXPCM_RX Port Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"QUAT_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, {"QUAT_AUX_PCM_RX", NULL, "QUAT_AUXPCM_RX Port Mixer"}, @@ -10728,8 +11057,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice Stub Tx Mixer", "STUB_1_TX_HL", "STUB_1_TX"}, {"Voice Stub Tx Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "TERT_AUX_PCM_UL_TX", "TERT_AUX_PCM_TX"}, - {"Voice Stub Tx Mixer", "QUAT_AUX_PCM_UL_TX", "QUAT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "TERT_AUXPCM_UL_TX", "TERT_AUX_PCM_TX"}, + {"Voice Stub Tx Mixer", "QUAT_AUXPCM_UL_TX", "QUAT_AUX_PCM_TX"}, {"Voice Stub Tx Mixer", "MI2S_TX", "MI2S_TX"}, {"Voice Stub Tx Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"Voice Stub Tx Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, @@ -10776,8 +11105,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, {"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, - {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, {"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, {"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, @@ -10869,6 +11196,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SEC_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, {"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"}, + {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"}, {"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"}, {"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, @@ -11404,9 +11732,8 @@ static int msm_routing_probe(struct snd_soc_platform *platform) snd_soc_add_platform_controls(platform, lsm_function, ARRAY_SIZE(lsm_function)); - snd_soc_add_platform_controls(platform, - aanc_slim_0_rx_mux, - ARRAY_SIZE(aanc_slim_0_rx_mux)); + snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux, + ARRAY_SIZE(aanc_slim_0_rx_mux)); snd_soc_add_platform_controls(platform, msm_voc_session_controls, ARRAY_SIZE(msm_voc_session_controls)); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index 8a62e900ff28..d64fd640618e 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -59,14 +59,15 @@ #define LPASS_BE_SLIMBUS_1_TX "SLIMBUS_1_TX" #define LPASS_BE_STUB_1_TX "STUB_1_TX" #define LPASS_BE_SLIMBUS_2_RX "SLIMBUS_2_RX" +#define LPASS_BE_SLIMBUS_2_TX "SLIMBUS_2_TX" #define LPASS_BE_SLIMBUS_3_RX "SLIMBUS_3_RX" #define LPASS_BE_SLIMBUS_3_TX "SLIMBUS_3_TX" #define LPASS_BE_SLIMBUS_4_RX "SLIMBUS_4_RX" #define LPASS_BE_SLIMBUS_4_TX "SLIMBUS_4_TX" +#define LPASS_BE_SLIMBUS_5_RX "SLIMBUS_5_RX" #define LPASS_BE_SLIMBUS_5_TX "SLIMBUS_5_TX" #define LPASS_BE_SLIMBUS_6_RX "SLIMBUS_6_RX" #define LPASS_BE_SLIMBUS_6_TX "SLIMBUS_6_TX" -#define LPASS_BE_SLIMBUS_5_RX "SLIMBUS_5_RX" #define LPASS_BE_QUIN_MI2S_RX "QUIN_MI2S_RX" #define LPASS_BE_QUIN_MI2S_TX "QUIN_MI2S_TX" #define LPASS_BE_SENARY_MI2S_TX "SENARY_MI2S_TX" @@ -181,6 +182,9 @@ enum { MSM_FRONTEND_DAI_MULTIMEDIA14, MSM_FRONTEND_DAI_MULTIMEDIA15, MSM_FRONTEND_DAI_MULTIMEDIA16, + MSM_FRONTEND_DAI_MULTIMEDIA17, + MSM_FRONTEND_DAI_MULTIMEDIA18, + MSM_FRONTEND_DAI_MULTIMEDIA19, MSM_FRONTEND_DAI_CS_VOICE, MSM_FRONTEND_DAI_VOIP, MSM_FRONTEND_DAI_AFE_RX, @@ -206,8 +210,8 @@ enum { MSM_FRONTEND_DAI_MAX, }; -#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA16 + 1) -#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA16 +#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA19 + 1) +#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA19 enum { MSM_BACKEND_DAI_PRI_I2S_RX = 0, @@ -233,11 +237,19 @@ enum { MSM_BACKEND_DAI_SLIMBUS_1_RX, MSM_BACKEND_DAI_SLIMBUS_1_TX, MSM_BACKEND_DAI_SLIMBUS_2_RX, - MSM_BACKEND_DAI_SLIMBUS_4_RX, - MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_BACKEND_DAI_SLIMBUS_2_TX, MSM_BACKEND_DAI_SLIMBUS_3_RX, MSM_BACKEND_DAI_SLIMBUS_3_TX, + MSM_BACKEND_DAI_SLIMBUS_4_RX, + MSM_BACKEND_DAI_SLIMBUS_4_TX, + MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_BACKEND_DAI_SLIMBUS_5_TX, + MSM_BACKEND_DAI_SLIMBUS_6_RX, + MSM_BACKEND_DAI_SLIMBUS_6_TX, + MSM_BACKEND_DAI_SLIMBUS_7_RX, + MSM_BACKEND_DAI_SLIMBUS_7_TX, + MSM_BACKEND_DAI_SLIMBUS_8_RX, + MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_BACKEND_DAI_EXTPROC_RX, MSM_BACKEND_DAI_EXTPROC_TX, MSM_BACKEND_DAI_EXTPROC_EC_TX, @@ -252,11 +264,8 @@ enum { MSM_BACKEND_DAI_AUDIO_I2S_RX, MSM_BACKEND_DAI_SEC_AUXPCM_RX, MSM_BACKEND_DAI_SEC_AUXPCM_TX, - MSM_BACKEND_DAI_SLIMBUS_6_RX, - MSM_BACKEND_DAI_SLIMBUS_6_TX, MSM_BACKEND_DAI_SPDIF_RX, MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1, - MSM_BACKEND_DAI_SLIMBUS_5_RX, MSM_BACKEND_DAI_QUINARY_MI2S_RX, MSM_BACKEND_DAI_QUINARY_MI2S_TX, MSM_BACKEND_DAI_SENARY_MI2S_TX, @@ -325,10 +334,6 @@ enum { MSM_BACKEND_DAI_QUAT_TDM_RX_7, MSM_BACKEND_DAI_QUAT_TDM_TX_7, MSM_BACKEND_DAI_INT_BT_A2DP_RX, - MSM_BACKEND_DAI_SLIMBUS_7_RX, - MSM_BACKEND_DAI_SLIMBUS_7_TX, - MSM_BACKEND_DAI_SLIMBUS_8_RX, - MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_BACKEND_DAI_USB_RX, MSM_BACKEND_DAI_USB_TX, MSM_BACKEND_DAI_DISPLAY_PORT_RX, diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 22e14f431bb3..e3545405f61d 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -421,12 +421,12 @@ static void config_debug_fs_write(struct audio_buffer *ab) } static void config_debug_fs_init(void) { - out_buffer = kmalloc(OUT_BUFFER_SIZE, GFP_KERNEL); + out_buffer = kzalloc(OUT_BUFFER_SIZE, GFP_KERNEL); if (out_buffer == NULL) { pr_err("%s: kmalloc() for out_buffer failed\n", __func__); goto outbuf_fail; } - in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL); + in_buffer = kzalloc(IN_BUFFER_SIZE, GFP_KERNEL); if (in_buffer == NULL) { pr_err("%s: kmalloc() for in_buffer failed\n", __func__); goto inbuf_fail; |
