diff options
88 files changed, 2935 insertions, 1837 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index 0174306135c1..a9bb6b81e60d 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -436,6 +436,11 @@ the fps window. - qcom,cmd-to-video-mode-switch-commands: List of commands that need to be sent to panel in order to switch from command mode to video mode dynamically. Refer to "qcom,mdss-dsi-on-command" section for adding commands. +- qcom,mode-switch-commands-state: String that specifies the ctrl state for sending commands to switch + the panel mode, it applies for both switches, from command to video and + from video to command. + "dsi_lp_mode" = DSI low power mode (default) + "dsi_hs_mode" = DSI high speed mode - qcom,send-pps-before-switch: Boolean propety to indicate when PPS commands should be sent, either before or after switch commands during dynamic resolution switch in DSC panels. If the property is not present, the default @@ -665,6 +670,7 @@ Example: qcom,video-to-cmd-mode-switch-commands = [15 01 00 00 00 00 02 C2 0B 15 01 00 00 00 00 02 C2 08]; qcom,cmd-to-video-mode-switch-commands = [15 01 00 00 00 00 02 C2 03]; + qcom,mode-switch-commands-state = "dsi_hs_mode"; qcom,send-pps-before-switch; qcom,panel-ack-disabled; qcom,mdss-dsi-horizontal-line-idle = <0 40 256>, diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt index 54a3c5689b9c..be5633024986 100644 --- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt +++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt @@ -16,6 +16,8 @@ Required properties: If "halt_base" is in same 4K pages this register then this will be defined else "halt_q6", "halt_modem", "halt_nc" is required. + "cxip_lm_vote_clear" needs to defined , in case PIL has to + clear the CX Ipeak bit if it was set by MSS. - interrupts: The modem watchdog interrupt - vdd_cx-supply: Reference to the regulator that supplies the vdd_cx domain. - vdd_cx-voltage: Voltage corner/level(max) for cx rail. @@ -84,6 +86,8 @@ Optional properties: wordline clamp, and compiler memory clamp during MSS restart. - qcom,qdsp6v56-1-10: Boolean- Present if the qdsp version is v56 1.10 - qcom,override-acc-1: Override the default ACC settings with this value if present. +- qcom,cx-ipeak-vote: Boolean- Present if we need to set bit 5 of cxip_lm_vote_clear + during modem shutdown Example: qcom,mss@fc880000 { diff --git a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt index 891feb571157..29bb2d32bf91 100644 --- a/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt @@ -36,7 +36,7 @@ APSS specific properties: Usage: required Value type: <string> Definition: should be one of the following: - "qcom,cpr4-msmtitanium-apss-regulator"; + "qcom,cpr4-msm8953-apss-regulator"; - interrupts Usage: required @@ -357,7 +357,7 @@ APSS specific properties: Each tuple list must contain a number of tuples equal to 2 to the power of the number of bits selected for misc - voltage adj fuse definition. For MSMTITANIUM the tuple + voltage adj fuse definition. For MSM8953 the tuple list must contain 2 tuples for the 1-bit misc fuse. Tuples in a list should be specified in ascending order according to the misc fuse value assuming that the fuse @@ -373,7 +373,7 @@ Example ======= apc_cpr: cpr4-ctrl@b018000 { - compatible = "qcom,cpr4-msmtitanium-apss-regulator"; + compatible = "qcom,cpr4-msm8953-apss-regulator"; reg = <0xb018000 0x4000>, <0xa4000 0x1000>; reg-names = "cpr_ctrl", "fuse_base"; interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>; @@ -394,9 +394,9 @@ apc_cpr: cpr4-ctrl@b018000 { qcom,apm-threshold-voltage = <848000>; qcom,apm-hysteresis-voltage = <5000>; - vdd-supply = <&pmtitanium_s5>; + vdd-supply = <&pm8953_s5>; qcom,voltage-step = <5000>; - vdd-limit-supply = <&pmtitanium_s5_limit>; + vdd-limit-supply = <&pm8953_s5_limit>; mem-acc-supply = <&apc_mem_acc_vreg>; qcom,cpr-enable; diff --git a/Documentation/devicetree/bindings/regulator/msm_gfx_ldo.txt b/Documentation/devicetree/bindings/regulator/msm_gfx_ldo.txt index f8b243e5509d..890255749704 100644 --- a/Documentation/devicetree/bindings/regulator/msm_gfx_ldo.txt +++ b/Documentation/devicetree/bindings/regulator/msm_gfx_ldo.txt @@ -1,6 +1,6 @@ Qualcomm Technologies, Inc. GFX LDO for Graphics -The GPU core on MSM TITANIUM can be powered by an internal (on-die) +The GPU core on MSM 8953 can be powered by an internal (on-die) MSM LDO or BHS based on its operating corner. This document describes the bindings that apply for the GFX LDO regulator. @@ -8,7 +8,7 @@ This document describes the bindings that apply for the GFX LDO regulator. - compatible Usage: required Value type: <string> - Definition: should be "qcom,msmtitanium-gfx-ldo" for MSMTITANIUM. + Definition: should be "qcom,msm8953-gfx-ldo" for MSM8953. - reg Usage: required @@ -103,12 +103,20 @@ This document describes the bindings that apply for the GFX LDO regulator. corner value for each gfx corner. The elements in the array are ordered from lowest voltage corner to highest voltage corner. +- qcom,ldo-init-voltage-adjustment + Usage: optional + Value type: <prop-encoded-aray> + Definition: Array of voltages in microvolts which indicate the static + adjustment to be applied to the open-loop voltages for the + LDO supported corners. The length of this property must be + equal to qcom,num-ldo-corners. + ======= Example ======= gfx_vreg_corner: ldo@0185f000 { - compatible = "qcom,msmtitanium-gfx-ldo"; + compatible = "qcom,msm8953-gfx-ldo"; reg = <0x0185f000 0x30>, <0xa0000 0x1000>; reg-names = "ldo_addr", "efuse_addr"; @@ -124,7 +132,7 @@ Example qcom,ldo-enable-corner-map = <1 1 1 0 0 0 0>; qcom,init-corner = <5>; - vdd-cx-supply = <&pmtitanium_s2_level>; + vdd-cx-supply = <&pm8953_s2_level>; qcom,vdd-cx-corner-map = <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>, <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>, <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>, @@ -135,4 +143,5 @@ Example mem-acc-supply = <&gfx_mem_acc>; qcom,mem-acc-corner-map = <1 1 2 2 2 2 2>; + qcom,ldo-init-voltage-adjustment = <10000 20000 30000>; }; diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt index f4d10908f4ff..1c870acbd034 100644 --- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt @@ -39,7 +39,7 @@ Optional properties : - clocks: a list of phandles to the controller clocks. Use as per Documentation/devicetree/bindings/clock/clock-bindings.txt - clock-names: Names of the clocks in 1-1 correspondence with the "clocks" - property. Optional clocks are "bus_aggr_clk" and "cfg_ahb_clk". + property. Optional clocks are "bus_aggr_clk", "noc_aggr_clk" and "cfg_ahb_clk". - qcom,charging-disabled: If present then battery charging using USB is disabled. - vbus_dwc3-supply: phandle to the 5V VBUS supply regulator used for host mode. @@ -95,12 +95,13 @@ Example MSM USB3.0 controller device node : clocks = <&clock_gcc clk_gcc_usb30_master_clk>, <&clock_gcc clk_gcc_cfg_noc_usb3_axi_clk>, <&clock_gcc clk_gcc_aggre1_usb3_axi_clk>, + <&clock_rpmcc RPM_AGGR2_NOC_CLK>, <&clock_gcc clk_gcc_usb30_mock_utmi_clk>, <&clock_gcc clk_gcc_usb30_sleep_clk>, <&clock_gcc clk_gcc_usb_phy_cfg_ahb2phy_clk>, <&clock_gcc clk_cxo_dwc3_clk>; - clock-names = "core_clk", "iface_clk", "bus_aggr_clk", + clock-names = "core_clk", "iface_clk", "bus_aggr_clk", "noc_aggr_clk", "utmi_clk", "sleep_clk", "cfg_ahb_clk", "xo"; resets = <&clock_gcc GCC_USB_30_BCR>; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-jdi-dualmipi-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-jdi-dualmipi-cmd.dtsi index 9c309973f5d0..50c4c728fd4a 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-jdi-dualmipi-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-jdi-dualmipi-cmd.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, 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 @@ -123,6 +123,7 @@ qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; qcom,dynamic-mode-switch-enabled; qcom,dynamic-mode-switch-type = "dynamic-switch-immediate"; + qcom,mode-switch-commands-state = "dsi_hs_mode"; qcom,video-to-cmd-mode-switch-commands = [23 00 00 00 00 00 02 b0 00 29 00 00 00 00 00 02 b3 0c diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-triton.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-triton.dtsi new file mode 100644 index 000000000000..f4bf275dcc3c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-triton.dtsi @@ -0,0 +1,45 @@ +/* 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 "msm-arm-smmu-falcon.dtsi" +#include "msm-arm-smmu-impl-defs-falcon.dtsi" + +&soc { + /delete-node/ arm,smmu-turing_q6@5180000; +}; + +&mmss_bimc_smmu { + attach-impl-defs = <0x6000 0x2378>, + <0x6060 0x1055>, + <0x678c 0x28>, + <0x6794 0xe0>, + <0x6800 0x6>, + <0x6900 0x3ff>, + <0x6924 0x204>, + <0x6928 0x11002>, + <0x6930 0x800>, + <0x6960 0xffffffff>, + <0x6964 0xffffffff>, + <0x6968 0xffffffff>, + <0x696c 0xffffffff>, + <0x6b48 0x330330>, + <0x6b4c 0x81>, + <0x6b50 0x3333>, + <0x6b54 0x3333>, + <0x6b64 0x1a5555>, + <0x6b68 0xbaaa892a>, + <0x6b70 0x0c0c0202>, + <0x6b74 0x0e0e0202>, + <0x6b78 0x0e0e0000>, + <0x6b80 0x20042004>, + <0x6b84 0x20042004>; +}; diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index 74c1779e6fca..7f2d1cba5b42 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -616,8 +616,8 @@ "SpkrLeft IN", "SPK1 OUT", "SpkrRight IN", "SPK2 OUT"; - qcom,msm-mbhc-hphl-swh = <0>; - qcom,msm-mbhc-gnd-swh = <0>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; qcom,us-euro-gpios = <&us_euro_gpio>; qcom,tasha-mclk-clk-freq = <9600000>; asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, @@ -723,8 +723,8 @@ "SpkrLeft IN", "SPK1 OUT", "SpkrRight IN", "SPK2 OUT"; - qcom,msm-mbhc-hphl-swh = <0>; - qcom,msm-mbhc-gnd-swh = <0>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; qcom,us-euro-gpios = <&tavil_us_euro_sw>; qcom,hph-en0-gpio = <&tavil_hph_en0>; qcom,hph-en1-gpio = <&tavil_hph_en1>; diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi index f500079e6953..bc0793fec990 100644 --- a/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi @@ -194,7 +194,7 @@ rpm-regulator-ldob9 { compatible = "qcom,rpm-smd-regulator-resource"; qcom,resource-name = "rwsc"; - qcom,resource-id = <9>; + qcom,resource-id = <0>; qcom,regulator-type = <0>; status = "disabled"; @@ -209,7 +209,7 @@ rpm-regulator-ldob10 { compatible = "qcom,rpm-smd-regulator-resource"; qcom,resource-name = "rwsm"; - qcom,resource-id = <10>; + qcom,resource-id = <0>; qcom,regulator-type = <0>; status = "disabled"; diff --git a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi index 79883db10d06..67247c956c42 100644 --- a/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi @@ -130,10 +130,10 @@ reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; qcom,channel-id = <1>; + qcom,lpg-lut-size = <0x7e>; qcom,supported-sizes = <6>, <9>; qcom,ramp-index = <0>; #pwm-cells = <2>; - status = "disabled"; }; pm2falcon_pwm_2: pwm@b200 { @@ -143,10 +143,10 @@ reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; qcom,channel-id = <2>; + qcom,lpg-lut-size = <0x7e>; qcom,supported-sizes = <6>, <9>; qcom,ramp-index = <1>; #pwm-cells = <2>; - status = "disabled"; }; pm2falcon_pwm_3: pwm@b300 { @@ -156,10 +156,10 @@ reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; qcom,channel-id = <3>; + qcom,lpg-lut-size = <0x7e>; qcom,supported-sizes = <6>, <9>; qcom,ramp-index = <2>; #pwm-cells = <2>; - status = "disabled"; }; pm2falcon_pwm_4: pwm@b400 { @@ -169,6 +169,7 @@ reg-names = "qpnp-lpg-channel-base", "qpnp-lpg-lut-base"; qcom,channel-id = <4>; + qcom,lpg-lut-size = <0x7e>; qcom,supported-sizes = <6>, <9>; qcom,ramp-index = <3>; #pwm-cells = <2>; @@ -179,7 +180,6 @@ compatible = "qcom,leds-qpnp"; reg = <0xd000 0x100>; label = "rgb"; - status = "disabled"; red_led: qcom,rgb_0 { label = "rgb"; @@ -270,7 +270,6 @@ qcom,thermal-derate-current = <200 500 1000>; qcom,isc-delay = <192>; qcom,pmic-revid = <&pm2falcon_revid>; - status = "disabled"; pm2falcon_flash0: qcom,flash_0 { label = "flash"; diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi index 08248794ffdb..9af9ba7e4537 100644 --- a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi @@ -557,5 +557,28 @@ reg = <0x1 SPMI_USID>; #address-cells = <2>; #size-cells = <0>; + + pmfalcon_haptics: qcom,haptic@c000 { + compatible = "qcom,qpnp-haptic"; + reg = <0xc000 0x100>; + interrupts = <0x1 0xc0 0x0>, + <0x1 0xc0 0x1>; + interrupt-names = "sc-irq", "play-irq"; + qcom,actuator-type = "lra"; + qcom,play-mode = "direct"; + qcom,vmax-mv = <3200>; + qcom,ilim-ma = <800>; + qcom,wave-shape = "square"; + qcom,wave-play-rate-us = <6667>; + qcom,int-pwm-freq-khz = <505>; + qcom,sc-deb-cycles = <8>; + qcom,en-brake; + qcom,brake-pattern = [03 03 00 00]; + qcom,use-play-irq; + qcom,use-sc-irq; + qcom,lra-high-z = "opt1"; + qcom,lra-auto-res-mode = "qwd"; + qcom,lra-res-cal-period = <4>; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi new file mode 100644 index 000000000000..b8c721e64ca7 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi @@ -0,0 +1,103 @@ +/* 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> + +&i2c_7 { + status = "okay"; + qcom,smb138x@8 { + compatible = "qcom,i2c-pmic"; + reg = <0x8>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-parent = <&spmi_bus>; + interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; + interrupt_names = "smb138x"; + interrupt-controller; + #interrupt-cells = <3>; + qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; + + smb138x_revid: qcom,revid@100 { + compatible = "qcom,qpnp-revid"; + reg = <0x100 0x100>; + }; + + smb138x_tadc: qcom,tadc@3600 { + compatible = "qcom,tadc"; + reg = <0x3600 0x100>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "eoc"; + + batt_temp@0 { + reg = <0>; + qcom,rbias = <68100>; + qcom,rtherm-at-25degc = <68000>; + qcom,beta-coefficient = <3450>; + }; + + skin_temp@1 { + reg = <1>; + qcom,rbias = <33000>; + qcom,rtherm-at-25degc = <68000>; + qcom,beta-coefficient = <3450>; + }; + + die_temp@2 { + reg = <2>; + qcom,scale = <(-1032)>; + qcom,offset = <344125>; + }; + + batt_i@3 { + reg = <3>; + qcom,channel = <3>; + qcom,scale = <(-20000000)>; + }; + + batt_v@4 { + reg = <4>; + qcom,scale = <5000000>; + }; + + input_i@5 { + reg = <5>; + qcom,scale = <14285714>; + }; + + input_v@6 { + reg = <6>; + qcom,scale = <25000000>; + }; + + otg_i@7 { + reg = <7>; + qcom,scale = <5714286>; + }; + }; + + smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 { + compatible = "qcom,smb138x-parallel-slave"; + qcom,pmic-revid = <&smb138x_revid>; + reg = <0x1000 0x700>; + + io-channels = <&smb138x_tadc 2>, + <&smb138x_tadc 12>, + <&smb138x_tadc 3>; + io-channel-names = "charger_temp", + "charger_temp_max", + "batt_i"; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi index ec57ab601d46..605f1562a10a 100644 --- a/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-cdp.dtsi @@ -207,68 +207,6 @@ }; }; -&i2c_7 { - status = "okay"; - qcom,smb138x@8 { - compatible = "qcom,i2c-pmic"; - reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-parent = <&spmi_bus>; - interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; - interrupt_names = "smb138x"; - interrupt-controller; - #interrupt-cells = <3>; - qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; - - smb138x_tadc: qcom,tadc@3600 { - compatible = "qcom,tadc"; - reg = <0x3600 0x100>; - - interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "eoc"; - - batt_therm { - qcom,rbias = <68100>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - skin_temp { - qcom,rbias = <33000>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - die_temp { - qcom,scale = <(-1032)>; - qcom,offset = <344125>; - }; - - batt_i { - qcom,channel = <3>; - qcom,scale = <20000000>; - }; - - batt_v { - qcom,scale = <5000000>; - }; - - input_i { - qcom,scale = <14285714>; - }; - - input_v { - qcom,scale = <25000000>; - }; - - otg_i { - qcom,scale = <5714286>; - }; - }; - }; -}; - &mdss_mdp { qcom,mdss-pref-prim-intf = "dsi"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-cdp.dtsi index 3ef09569a430..0b8d84766fc4 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-cdp.dtsi @@ -12,6 +12,24 @@ */ &soc { + led_flash0: qcom,camera-flash@0 { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pm2falcon_flash0 &pm2falcon_flash1>; + qcom,torch-source = <&pm2falcon_torch0 &pm2falcon_torch1>; + qcom,switch-source = <&pm2falcon_switch0>; + status = "ok"; + }; + + led_flash1: qcom,camera-flash@1 { + cell-index = <1>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pm2falcon_flash2>; + qcom,torch-source = <&pm2falcon_torch2>; + qcom,switch-source = <&pm2falcon_switch1>; + status = "ok"; + }; + qcom,csiphy@ca34000 { qcom,clock-rates = <0 0 0 0 0 0 384000000 0 0 269333333 0 0 384000000 0>; @@ -164,6 +182,46 @@ qcom,clock-rates = <24000000 0>; }; + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pmfalcon_l11>; + cam_vana-supply = <&pm2falcon_bob>; + cam_vdig-supply = <&pmfalcon_s5>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 3300000 1350000>; + qcom,cam-vreg-max-voltage = <0 3600000 1350000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pmfalcon_gpios 3 0>, + <&tlmm 29 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-vana = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG", + "CAM_VANA"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + qcom,camera@0 { cell-index = <0>; compatible = "qcom,camera"; @@ -171,6 +229,7 @@ qcom,csiphy-sd-index = <0>; qcom,csid-sd-index = <0>; qcom,mount-angle = <270>; + qcom,led-flash-src = <&led_flash0>; qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; @@ -209,8 +268,55 @@ clock-names = "cam_src_clk", "cam_clk"; qcom,clock-rates = <24000000 0>; }; + + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <90>; + qcom,led-flash-src = <&led_flash1>; + qcom,eeprom-src = <&eeprom2>; + qcom,actuator-src = <&actuator1>; + cam_vio-supply = <&pmfalcon_l11>; + cam_vana-supply = <&pm2falcon_bob>; + cam_vdig-supply = <&pmfalcon_s5>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 3300000 1350000>; + qcom,cam-vreg-max-voltage = <0 3600000 1350000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pmfalcon_gpios 3 0>, + <&tlmm 29 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-vana = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG", + "CAM_VANA"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; }; + &pmfalcon_gpios { gpio@c300 { /* GPIO4 -CAMERA SENSOR 0 VDIG*/ qcom,mode = <1>; /* Output */ @@ -221,4 +327,14 @@ qcom,master-en = <1>; /* Enable GPIO */ status = "ok"; }; + + gpio@c200 { /* GPIO3 -CAMERA SENSOR 1 VDIG*/ + qcom,mode = <1>; /* Output */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <0>; /* VIN1 GPIO_LV */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "ok"; + }; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi index 3ef09569a430..0b8d84766fc4 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi @@ -12,6 +12,24 @@ */ &soc { + led_flash0: qcom,camera-flash@0 { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pm2falcon_flash0 &pm2falcon_flash1>; + qcom,torch-source = <&pm2falcon_torch0 &pm2falcon_torch1>; + qcom,switch-source = <&pm2falcon_switch0>; + status = "ok"; + }; + + led_flash1: qcom,camera-flash@1 { + cell-index = <1>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pm2falcon_flash2>; + qcom,torch-source = <&pm2falcon_torch2>; + qcom,switch-source = <&pm2falcon_switch1>; + status = "ok"; + }; + qcom,csiphy@ca34000 { qcom,clock-rates = <0 0 0 0 0 0 384000000 0 0 269333333 0 0 384000000 0>; @@ -164,6 +182,46 @@ qcom,clock-rates = <24000000 0>; }; + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pmfalcon_l11>; + cam_vana-supply = <&pm2falcon_bob>; + cam_vdig-supply = <&pmfalcon_s5>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 3300000 1350000>; + qcom,cam-vreg-max-voltage = <0 3600000 1350000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pmfalcon_gpios 3 0>, + <&tlmm 29 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-vana = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG", + "CAM_VANA"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + qcom,camera@0 { cell-index = <0>; compatible = "qcom,camera"; @@ -171,6 +229,7 @@ qcom,csiphy-sd-index = <0>; qcom,csid-sd-index = <0>; qcom,mount-angle = <270>; + qcom,led-flash-src = <&led_flash0>; qcom,actuator-src = <&actuator0>; qcom,ois-src = <&ois0>; qcom,eeprom-src = <&eeprom0>; @@ -209,8 +268,55 @@ clock-names = "cam_src_clk", "cam_clk"; qcom,clock-rates = <24000000 0>; }; + + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <90>; + qcom,led-flash-src = <&led_flash1>; + qcom,eeprom-src = <&eeprom2>; + qcom,actuator-src = <&actuator1>; + cam_vio-supply = <&pmfalcon_l11>; + cam_vana-supply = <&pm2falcon_bob>; + cam_vdig-supply = <&pmfalcon_s5>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 3300000 1350000>; + qcom,cam-vreg-max-voltage = <0 3600000 1350000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pmfalcon_gpios 3 0>, + <&tlmm 29 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-vana = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG", + "CAM_VANA"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; }; + &pmfalcon_gpios { gpio@c300 { /* GPIO4 -CAMERA SENSOR 0 VDIG*/ qcom,mode = <1>; /* Output */ @@ -221,4 +327,14 @@ qcom,master-en = <1>; /* Enable GPIO */ status = "ok"; }; + + gpio@c200 { /* GPIO3 -CAMERA SENSOR 1 VDIG*/ + qcom,mode = <1>; /* Output */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <0>; /* VIN1 GPIO_LV */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "ok"; + }; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi index 20c69e0a9a1a..26c021da803d 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi @@ -14,52 +14,6 @@ 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"; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi index 76326e7ae86f..a2193de57dea 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi @@ -205,68 +205,6 @@ }; }; -&i2c_7 { - status = "okay"; - qcom,smb138x@8 { - compatible = "qcom,i2c-pmic"; - reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-parent = <&spmi_bus>; - interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; - interrupt_names = "smb138x"; - interrupt-controller; - #interrupt-cells = <3>; - qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; - - smb138x_tadc: qcom,tadc@3600 { - compatible = "qcom,tadc"; - reg = <0x3600 0x100>; - - interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "eoc"; - - batt_therm { - qcom,rbias = <68100>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - skin_temp { - qcom,rbias = <33000>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - die_temp { - qcom,scale = <(-1032)>; - qcom,offset = <344125>; - }; - - batt_i { - qcom,channel = <3>; - qcom,scale = <20000000>; - }; - - batt_v { - qcom,scale = <5000000>; - }; - - input_i { - qcom,scale = <14285714>; - }; - - input_v { - qcom,scale = <25000000>; - }; - - otg_i { - qcom,scale = <5714286>; - }; - }; - }; -}; - &mdss_mdp { qcom,mdss-pref-prim-intf = "dsi"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi index 5c55732e0de7..9257c031d2f9 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi @@ -206,96 +206,6 @@ }; }; -&i2c_7 { - status = "okay"; - qcom,smb138x@8 { - compatible = "qcom,i2c-pmic"; - reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-parent = <&spmi_bus>; - interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; - interrupt_names = "smb138x"; - interrupt-controller; - #interrupt-cells = <3>; - qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; - - smb138x_revid: qcom,revid@100 { - compatible = "qcom,qpnp-revid"; - reg = <0x100 0x100>; - }; - - smb138x_tadc: qcom,tadc@3600 { - compatible = "qcom,tadc"; - reg = <0x3600 0x100>; - #address-cells = <1>; - #size-cells = <0>; - #io-channel-cells = <1>; - interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "eoc"; - - batt_temp@0 { - reg = <0>; - qcom,rbias = <68100>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - skin_temp@1 { - reg = <1>; - qcom,rbias = <33000>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - die_temp@2 { - reg = <2>; - qcom,scale = <(-1032)>; - qcom,offset = <344125>; - }; - - batt_i@3 { - reg = <3>; - qcom,channel = <3>; - qcom,scale = <20000000>; - }; - - batt_v@4 { - reg = <4>; - qcom,scale = <5000000>; - }; - - input_i@5 { - reg = <5>; - qcom,scale = <14285714>; - }; - - input_v@6 { - reg = <6>; - qcom,scale = <25000000>; - }; - - otg_i@7 { - reg = <7>; - qcom,scale = <5714286>; - }; - }; - - smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 { - compatible = "qcom,smb138x-parallel-slave"; - qcom,pmic-revid = <&smb138x_revid>; - reg = <0x1000 0x700>; - - io-channels = <&smb138x_tadc 2>, - <&smb138x_tadc 12>, - <&smb138x_tadc 3>; - io-channel-names = "charger_temp", - "charger_temp_max", - "batt_i"; - }; - }; -}; - &mdss_hdmi_tx { pinctrl-names = "hdmi_hpd_active", "hdmi_ddc_active", "hdmi_cec_active", "hdmi_active", "hdmi_sleep"; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi index 1ca5ce6eabbb..e57573166b7b 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi @@ -2121,7 +2121,7 @@ reg = <0x17300000 0x00100>; interrupts = <0 162 1>; - vdd_cx-supply = <&pm8998_s1_level>; + vdd_cx-supply = <&pm2falcon_s3_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 = <&pm8998_s1_level>; + vdd_cx-supply = <&pm2falcon_s3_level>; vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>; - vdd_mx-supply = <&pm8998_s9_level>; + vdd_mx-supply = <&pm2falcon_s5_level>; vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>; qcom,firmware-name = "modem"; qcom,pil-self-auth; @@ -2587,10 +2587,9 @@ reg = <0x5c00000 0x4000>; interrupts = <0 390 1>; - vdd_cx-supply = <&pm8998_l27_level>; - vdd_px-supply = <&pm8998_lvs2>; + vdd_cx-supply = <&pm2falcon_l9_level>; qcom,vdd_cx-uV-uA = <RPM_SMD_REGULATOR_LEVEL_TURBO 0>; - qcom,proxy-reg-names = "vdd_cx", "vdd_px"; + qcom,proxy-reg-names = "vdd_cx"; qcom,keep-proxy-regs-on; clocks = <&clock_gcc clk_cxo_pil_ssc_clk>, @@ -3088,6 +3087,7 @@ #include "msm8998-blsp.dtsi" #include "msm-audio.dtsi" #include "msmfalcon-audio.dtsi" +#include "msm-smb138x.dtsi" /* GPU overrides */ &msm_gpu { diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi index 54a2a4a00dc0..1c39fe03b477 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi @@ -214,11 +214,8 @@ &soc { /delete-node/gpio_keys; - /delete-node/qcom,lpass@17300000; - /delete-node/qcom,mss@4080000; /delete-node/qcom,bcl; /delete-node/qcom,msm-thermal; - /delete-node/qcom,ssc@5c00000; /delete-node/qcom,spss@1d00000; /delete-node/qcom,wil6210; /delete-node/qcom,rpm-smd; diff --git a/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi index 45d6398daf25..9193fbe14a5a 100644 --- a/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi @@ -218,96 +218,6 @@ }; }; -&i2c_7 { - status = "okay"; - qcom,smb138x@8 { - compatible = "qcom,i2c-pmic"; - reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-parent = <&spmi_bus>; - interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; - interrupt_names = "smb138x"; - interrupt-controller; - #interrupt-cells = <3>; - qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; - - smb138x_revid: qcom,revid@100 { - compatible = "qcom,qpnp-revid"; - reg = <0x100 0x100>; - }; - - smb138x_tadc: qcom,tadc@3600 { - compatible = "qcom,tadc"; - reg = <0x3600 0x100>; - #address-cells = <1>; - #size-cells = <0>; - #io-channel-cells = <1>; - interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "eoc"; - - batt_temp@0 { - reg = <0>; - qcom,rbias = <68100>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - skin_temp@1 { - reg = <1>; - qcom,rbias = <33000>; - qcom,rtherm-at-25degc = <68000>; - qcom,beta-coefficient = <3450>; - }; - - die_temp@2 { - reg = <2>; - qcom,scale = <(-1032)>; - qcom,offset = <344125>; - }; - - batt_i@3 { - reg = <3>; - qcom,channel = <3>; - qcom,scale = <(-20000000)>; - }; - - batt_v@4 { - reg = <4>; - qcom,scale = <5000000>; - }; - - input_i@5 { - reg = <5>; - qcom,scale = <14285714>; - }; - - input_v@6 { - reg = <6>; - qcom,scale = <25000000>; - }; - - otg_i@7 { - reg = <7>; - qcom,scale = <5714286>; - }; - }; - - smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 { - compatible = "qcom,smb138x-parallel-slave"; - qcom,pmic-revid = <&smb138x_revid>; - reg = <0x1000 0x700>; - - io-channels = <&smb138x_tadc 2>, - <&smb138x_tadc 12>, - <&smb138x_tadc 3>; - io-channel-names = "charger_temp", - "charger_temp_max", - "batt_i"; - }; - }; -}; - &mdss_hdmi_tx { pinctrl-names = "hdmi_hpd_active", "hdmi_ddc_active", "hdmi_cec_active", "hdmi_active", "hdmi_sleep"; diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi index 5685e9041fe4..436df2410de6 100644 --- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi @@ -1347,14 +1347,14 @@ }; cam_sensor_front_active: cam_sensor_front_active { - /* RESET */ + /* RESET VANA*/ mux { - pins = "gpio28"; + pins = "gpio28", "gpio29"; function = "gpio"; }; config { - pins = "gpio28"; + pins = "gpio28", "gpio29"; bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; @@ -1508,7 +1508,7 @@ mdss_dp_usbplug_cc_active: mdss_dp_usbplug_cc_active { mux { pins = "gpio38"; - function = "usb_phy"; + function = "gpio"; }; config { @@ -1521,7 +1521,7 @@ mdss_dp_usbplug_cc_suspend: mdss_dp_usbplug_cc_suspend { mux { pins = "gpio38"; - function = "usb_phy"; + function = "gpio"; }; config { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi index 0a011b3656be..150194a0e86f 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi @@ -360,27 +360,6 @@ qcom,5v-boost-gpio = <&tlmm 51 0>; }; -&i2c_7 { - status = "okay"; - qcom,smb138x@8 { - compatible = "qcom,i2c-pmic"; - reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; - interrupt-parent = <&spmi_bus>; - interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; - interrupt_names = "smb138x"; - interrupt-controller; - #interrupt-cells = <3>; - qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>; - - smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 { - compatible = "qcom,smb138x-parallel-slave"; - reg = <0x1000 0x700>; - }; - }; -}; - &pmi8998_haptics { status = "okay"; }; @@ -607,4 +586,3 @@ /delete-property/ qcom,us-euro-gpios; }; }; - diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts index bb7046ab58cb..aae66d41966f 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts @@ -86,3 +86,49 @@ parent-supply = <&pm2falcon_s3_level>; status = "ok"; }; + +&mdss_dsi { + hw-config = "split_dsi"; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + + qcom,ctrl-supply-entries { + qcom,ctrl-supply-entry@0 { + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + }; + }; + + qcom,phy-supply-entries { + qcom,phy-supply-entry@0 { + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + }; + }; +}; + +&mdss_dsi0 { + 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>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; + +&mdss_dsi1 { + 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>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts index 166e09577d46..e537928b21e0 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts @@ -86,3 +86,49 @@ parent-supply = <&pm2falcon_s3_level>; status = "ok"; }; + +&mdss_dsi { + hw-config = "split_dsi"; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + + qcom,ctrl-supply-entries { + qcom,ctrl-supply-entry@0 { + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + }; + }; + + qcom,phy-supply-entries { + qcom,phy-supply-entry@0 { + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + }; + }; +}; + +&mdss_dsi0 { + 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>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; + +&mdss_dsi1 { + 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>; + qcom,platform-reset-gpio = <&tlmm 94 0>; + qcom,platform-te-gpio = <&tlmm 10 0>; + qcom,panel-mode-gpio = <&tlmm 91 0>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi index 807ff29d3695..e449d81a25e5 100644 --- a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi @@ -239,9 +239,11 @@ qcom,msm-bus,name = "vmem"; qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,num-paths = <2>; qcom,msm-bus,vectors-KBps = + <MSM_BUS_MASTER_VIDEO_P0_OCMEM MSM_BUS_SLAVE_VMEM 0 0>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VMEM_CFG 0 0>, + <MSM_BUS_MASTER_VIDEO_P0_OCMEM MSM_BUS_SLAVE_VMEM 1000 1000>, <MSM_BUS_MASTER_AMPSS_M0 MSM_BUS_SLAVE_VMEM_CFG 500 800>; qcom,bank-size = <131072>; /* 128 kB */ diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index ef488bbe0010..0b54647fedfb 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -3200,3 +3200,4 @@ #include "msm-rdbg.dtsi" #include "msm8998-blsp.dtsi" #include "msm8998-audio.dtsi" +#include "msm-smb138x.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi index b6b3c1f6245f..7b216a0aa990 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi @@ -34,31 +34,11 @@ 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-vdd-mic-bias-supply = <&pm2falcon_bob>; + qcom,cdc-vdd-mic-bias-voltage = <3300000 3300000>; + qcom,cdc-vdd-mic-bias-current = <30400>; - 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-static-supplies = "cdc-vdd-mic-bias"; qcom,cdc-micbias1-mv = <1800>; qcom,cdc-micbias2-mv = <1800>; @@ -86,31 +66,11 @@ 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>; + cdc-vdd-mic-bias-supply = <&pm2falcon_bob>; + qcom,cdc-vdd-mic-bias-voltage = <3300000 3300000>; + qcom,cdc-vdd-mic-bias-current = <30400>; - qcom,cdc-static-supplies = "cdc-vdd-buck", - "cdc-buck-sido", - "cdc-vdd-tx-h", - "cdc-vdd-rx-h", - "cdc-vddpx-1"; + qcom,cdc-static-supplies = "cdc-vdd-mic-bias"; qcom,cdc-micbias1-mv = <1800>; qcom,cdc-micbias2-mv = <1800>; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi index b3be67bd8c32..b2bad31d12d4 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi @@ -39,13 +39,15 @@ clocks = <&clock_gcc GCC_USB30_MASTER_CLK>, <&clock_gcc GCC_CFG_NOC_USB3_AXI_CLK>, <&clock_gcc GCC_AGGRE2_USB3_AXI_CLK>, + <&clock_rpmcc RPM_AGGR2_NOC_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"; + "noc_aggr_clk", "utmi_clk", "sleep_clk", + "cfg_ahb_clk", "xo"; resets = <&clock_gcc GCC_USB_30_BCR>; reset-names = "core_reset"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-gpu.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-gpu.dtsi new file mode 100644 index 000000000000..76fc9f9c5e31 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-gpu.dtsi @@ -0,0 +1,233 @@ +/* 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 { + pil_gpu: qcom,kgsl-hyp { + compatible = "qcom,pil-tz-generic"; + qcom,pas-id = <13>; + qcom,firmware-name = "a512_zap"; + }; + + msm_bus: qcom,kgsl-busmon{ + label = "kgsl-busmon"; + compatible = "qcom,kgsl-busmon"; + }; + + gpubw: qcom,gpubw { + compatible = "qcom,devbw"; + governor = "bw_vbif"; + qcom,src-dst-ports = <26 512>; + /* + * active-only flag is used while registering the bus + * governor. It helps release the bus vote when the CPU + * subsystem is inactive + */ + qcom,active-only; + qcom,bw-tbl = + < 0 /* off */ >, + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + msm_gpu: qcom,kgsl-3d0@5000000 { + label = "kgsl-3d0"; + compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d"; + status = "ok"; + reg = <0x5000000 0x40000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 300 0>; + interrupt-names = "kgsl_3d0_irq"; + qcom,id = <0>; + + qcom,chipid = <0x05010200>; + + qcom,initial-pwrlevel = <6>; + + /* <HZ/12> */ + qcom,idle-timeout = <80>; + + qcom,highest-bank-bit = <14>; + + /* size in bytes */ + qcom,snapshot-size = <1048576>; + + clocks = <&clock_gfx GPUCC_GFX3D_CLK>, + <&clock_gcc GCC_GPU_CFG_AHB_CLK>, + <&clock_gfx GPUCC_RBBMTIMER_CLK>, + <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, + <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>, + <&clock_gfx GPUCC_RBCPR_CLK>; + + clock-names = "core_clk", "iface_clk", "rbbmtimer_clk", + "mem_clk", "mem_iface_clk", "rbcpr_clk"; + + /* Bus Scale Settings */ + qcom,gpubw-dev = <&gpubw>; + qcom,bus-control; + qcom,bus-width = <16>; + qcom,msm-bus,name = "grp3d"; + qcom,msm-bus,num-cases = <14>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <26 512 0 0>, + + <26 512 0 800000>, /* 1 bus=100 */ + <26 512 0 1200000>, /* 2 bus=150 */ + <26 512 0 1600000>, /* 3 bus=200 */ + <26 512 0 2400000>, /* 4 bus=300 */ + <26 512 0 3296000>, /* 5 bus=412 */ + <26 512 0 4376000>, /* 6 bus=547 */ + <26 512 0 5448000>, /* 7 bus=681 */ + <26 512 0 6144000>, /* 8 bus=768 */ + <26 512 0 8136000>, /* 9 bus=1017 */ + <26 512 0 10368000>, /* 10 bus=1296 */ + <26 512 0 10824000>, /* 11 bus=1353 */ + <26 512 0 12440000>, /* 12 bus=1555 */ + <26 512 0 14432000>; /* 13 bus=1804 */ + + /* GDSC regulator names */ + regulator-names = "vddcx", "vdd"; + /* GDSC oxili regulators */ + vddcx-supply = <&gdsc_gpu_cx>; + vdd-supply = <&gdsc_gpu_gx>; + + /* Power levels */ + qcom,gpu-pwrlevels { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "qcom,gpu-pwrlevels"; + + /* TURBO */ + qcom,gpu-pwrlevel@0 { + reg = <0>; + qcom,gpu-freq = <750000000>; + qcom,bus-freq = <12>; + qcom,bus-min = <11>; + qcom,bus-max = <13>; + }; + + /* TURBO */ + qcom,gpu-pwrlevel@1 { + reg = <1>; + qcom,gpu-freq = <700000000>; + qcom,bus-freq = <11>; + qcom,bus-min = <10>; + qcom,bus-max = <13>; + }; + + /* NOM_L1 */ + qcom,gpu-pwrlevel@2 { + reg = <2>; + qcom,gpu-freq = <647000000>; + qcom,bus-freq = <10>; + qcom,bus-min = <10>; + qcom,bus-max = <12>; + }; + + /* NOM */ + qcom,gpu-pwrlevel@3 { + reg = <3>; + qcom,gpu-freq = <588000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <9>; + qcom,bus-max = <11>; + }; + + /* SVS_L1 */ + qcom,gpu-pwrlevel@4 { + reg = <4>; + qcom,gpu-freq = <465000000>; + qcom,bus-freq = <9>; + qcom,bus-min = <7>; + qcom,bus-max = <11>; + }; + + /* SVS */ + qcom,gpu-pwrlevel@5 { + reg = <5>; + qcom,gpu-freq = <370000000>; + qcom,bus-freq = <7>; + qcom,bus-min = <5>; + qcom,bus-max = <9>; + }; + + /* Low SVS */ + qcom,gpu-pwrlevel@6 { + reg = <6>; + qcom,gpu-freq = <266000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <3>; + qcom,bus-max = <6>; + }; + + /* Min SVS */ + qcom,gpu-pwrlevel@7 { + reg = <7>; + qcom,gpu-freq = <160000000>; + qcom,bus-freq = <3>; + qcom,bus-min = <2>; + qcom,bus-max = <5>; + }; + + /* XO */ + qcom,gpu-pwrlevel@8 { + reg = <8>; + qcom,gpu-freq = <19200000>; + qcom,bus-freq = <0>; + qcom,bus-min = <0>; + qcom,bus-max = <0>; + }; + }; + }; + + kgsl_msm_iommu: qcom,kgsl-iommu { + compatible = "qcom,kgsl-smmu-v2"; + + reg = <0x05040000 0x10000>; + qcom,protect = <0x40000 0x10000>; + qcom,micro-mmu-control = <0x6000>; + + clocks =<&clock_gcc GCC_GPU_CFG_AHB_CLK>, + <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, + <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>; + + clock-names = "iface_clk", "mem_clk", "mem_iface_clk"; + + qcom,secure_align_mask = <0xfff>; + qcom,retention; + qcom,hyp_secure_alloc; + + gfx3d_user: gfx3d_user { + compatible = "qcom,smmu-kgsl-cb"; + label = "gfx3d_user"; + iommus = <&kgsl_smmu 0>; + qcom,gpu-offset = <0x48000>; + }; + + gfx3d_secure: gfx3d_secure { + compatible = "qcom,smmu-kgsl-cb"; + iommus = <&kgsl_smmu 2>; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index 6ef443c4de11..a9b903e2f902 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -49,6 +49,22 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; qcom,ea = <&ea0>; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + /* A53 L2 dump not supported */ + qcom,dump-size = <0x0>; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU1: cpu@1 { @@ -58,6 +74,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; qcom,ea = <&ea1>; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU2: cpu@2 { @@ -67,6 +93,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; qcom,ea = <&ea2>; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU3: cpu@3 { @@ -76,6 +112,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; qcom,ea = <&ea3>; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU4: cpu@100 { @@ -85,6 +131,20 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile1>; qcom,ea = <&ea4>; + efficiency = <1536>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; }; CPU5: cpu@101 { @@ -94,6 +154,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile2>; qcom,ea = <&ea5>; + efficiency = <1536>; + next-level-cache = <&L2_1>; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; }; CPU6: cpu@102 { @@ -103,6 +173,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile3>; qcom,ea = <&ea6>; + efficiency = <1536>; + next-level-cache = <&L2_1>; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; }; CPU7: cpu@103 { @@ -112,6 +192,16 @@ enable-method = "psci"; qcom,limits-info = <&mitigation_profile4>; qcom,ea = <&ea7>; + efficiency = <1536>; + next-level-cache = <&L2_1>; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x12000>; + }; }; cpu-map { @@ -309,6 +399,74 @@ status = "ok"; }; + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + wdog: qcom,wdt@17817000 { status = "disabled"; compatible = "qcom,msm-watchdog"; @@ -681,6 +839,21 @@ }; }; + arm64-cpu-erp { + compatible = "arm,arm64-cpu-erp"; + interrupts = <0 43 4>, + <0 44 4>, + <0 41 4>, + <0 42 4>; + + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq"; + + poll-delay-ms = <5000>; + }; + clock_rpmcc: qcom,rpmcc { compatible = "qcom,rpmcc-msmfalcon", "qcom,rpmcc"; #clock-cells = <1>; @@ -1146,9 +1319,11 @@ <0x1f65000 0x008>, <0x1f64000 0x008>, <0x4180000 0x040>, - <0x00179000 0x004>; + <0x00179000 0x004>, + <0x01fe5048 0x004>; reg-names = "qdsp6_base", "halt_q6", "halt_modem", - "halt_nc", "rmb_base", "restart_reg"; + "halt_nc", "rmb_base", "restart_reg", + "cxip_lm_vote_clear"; clocks = <&clock_rpmcc RPM_XO_CLK_SRC>, <&clock_gcc GCC_MSS_CFG_AHB_CLK>, @@ -1179,6 +1354,7 @@ qcom,qdsp6v62-1-5; memory-region = <&modem_fw_mem>; qcom,mem-protect-id = <0xF>; + qcom,cx-ipeak-vote; /* GPIO inputs from mss */ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>; @@ -1210,6 +1386,11 @@ #address-cells = <1>; #size-cells = <1>; + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + dload_type@18 { compatible = "qcom,msm-imem-dload-type"; reg = <0x18 4>; @@ -1274,13 +1455,95 @@ <55 512 400000 1000000>; clock-names = "core_clk_src", "core_clk", "iface_clk", "bus_clk"; - clocks = <&clock_gcc QSEECOM_CE1_CLK>, - <&clock_gcc QSEECOM_CE1_CLK>, - <&clock_gcc QSEECOM_CE1_CLK>, - <&clock_gcc QSEECOM_CE1_CLK>; + clocks = <&clock_rpmcc QSEECOM_CE1_CLK>, + <&clock_rpmcc QSEECOM_CE1_CLK>, + <&clock_rpmcc QSEECOM_CE1_CLK>, + <&clock_rpmcc QSEECOM_CE1_CLK>; qcom,ce-opp-freq = <171430000>; qcom,qsee-reentrancy-support = <2>; }; + + qcom_cedev: qcedev@1de0000{ + compatible = "qcom,qcedev"; + reg = <0x1de0000 0x20000>, + <0x1dc4000 0x24000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 207 0>; + qcom,bam-pipe-pair = <1>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,ce-hw-shared; + qcom,bam-ee = <0>; + qcom,msm-bus,name = "qcedev-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "core_clk", + "iface_clk", "bus_clk"; + clocks = <&clock_rpmcc QCEDEV_CE1_CLK>, + <&clock_rpmcc QCEDEV_CE1_CLK>, + <&clock_rpmcc QCEDEV_CE1_CLK>, + <&clock_rpmcc QCEDEV_CE1_CLK>; + qcom,ce-opp-freq = <171430000>; + }; + + qcom_crypto: qcrypto@1de0000 { + compatible = "qcom,qcrypto"; + reg = <0x1de0000 0x20000>, + <0x1dc4000 0x24000>; + reg-names = "crypto-base","crypto-bam-base"; + interrupts = <0 207 0>; + qcom,bam-pipe-pair = <2>; + qcom,ce-hw-instance = <0>; + qcom,ce-device = <0>; + qcom,bam-ee = <0>; + qcom,ce-hw-shared; + qcom,clk-mgmt-sus-res; + qcom,msm-bus,name = "qcrypto-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <55 512 0 0>, + <55 512 393600 393600>; + clock-names = "core_clk_src", "core_clk", + "iface_clk", "bus_clk"; + clocks = <&clock_rpmcc QCRYPTO_CE1_CLK>, + <&clock_rpmcc QCRYPTO_CE1_CLK>, + <&clock_rpmcc QCRYPTO_CE1_CLK>, + <&clock_rpmcc QCRYPTO_CE1_CLK>; + qcom,ce-opp-freq = <171430000>; + qcom,use-sw-aes-cbc-ecb-ctr-algo; + qcom,use-sw-aes-xts-algo; + qcom,use-sw-aes-ccm-algo; + qcom,use-sw-ahash-algo; + qcom,use-sw-aead-algo; + qcom,use-sw-hmac-algo; + }; + + qcom_tzlog: tz-log@146bf720 { + compatible = "qcom,tz-log"; + reg = <0x146bf720 0x3000>; + qcom,hyplog-enabled; + hyplog-address-offset = <0x410>; + hyplog-size-offset = <0x414>; + }; + + qcom_rng: qrng@794000 { + compatible = "qcom,msm-rng"; + reg = <0x794000 0x1000>; + qcom,msm-rng-iface-clk; + qcom,no-qrng-config; + qcom,msm-bus,name = "msm-rng-noc"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <1 618 0 0>, /* No vote */ + <1 618 0 800>; /* 100 KHz */ + clocks = <&clock_gcc GCC_PRNG_AHB_CLK>; + clock-names = "iface_clk"; + }; }; #include "msmfalcon-ion.dtsi" @@ -1291,6 +1554,7 @@ #include "msm-pm2falcon-rpm-regulator.dtsi" #include "msmfalcon-regulator.dtsi" #include "msm-gdsc-falcon.dtsi" +#include "msmfalcon-gpu.dtsi" &gdsc_usb30 { status = "ok"; diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 2a22772c8d1d..d96531a5b35a 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -46,6 +46,22 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + /* A53 L2 dump not supported */ + qcom,dump-size = <0x0>; + }; + L1_I_100: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_100: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU1: cpu@101 { @@ -53,6 +69,16 @@ compatible = "arm,armv8"; reg = <0x0 0x101>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_1>; + L1_I_101: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_101: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU2: cpu@102 { @@ -60,6 +86,16 @@ compatible = "arm,armv8"; reg = <0x0 0x102>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_1>; + L1_I_102: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_102: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU3: cpu@103 { @@ -67,6 +103,16 @@ compatible = "arm,armv8"; reg = <0x0 0x103>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_1>; + L1_I_103: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_103: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU4: cpu@0 { @@ -74,6 +120,22 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + /* A53 L2 dump not supported */ + qcom,dump-size = <0x0>; + }; + L1_I_0: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_0: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU5: cpu@1 { @@ -81,6 +143,16 @@ compatible = "arm,armv8"; reg = <0x0 0x1>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_1: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_1: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU6: cpu@2 { @@ -88,6 +160,16 @@ compatible = "arm,armv8"; reg = <0x0 0x2>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_2: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_2: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; CPU7: cpu@3 { @@ -95,6 +177,16 @@ compatible = "arm,armv8"; reg = <0x0 0x3>; enable-method = "psci"; + efficiency = <1024>; + next-level-cache = <&L2_0>; + L1_I_3: l1-icache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; + L1_D_3: l1-dcache { + compatible = "arm,arch-cache"; + qcom,dump-size = <0x9040>; + }; }; cpu-map { @@ -248,6 +340,74 @@ reg-names = "pshold-base", "tcsr-boot-misc-detect"; }; + cpuss_dump { + compatible = "qcom,cpuss-dump"; + qcom,l1_i_cache0 { + qcom,dump-node = <&L1_I_0>; + qcom,dump-id = <0x60>; + }; + qcom,l1_i_cache1 { + qcom,dump-node = <&L1_I_1>; + qcom,dump-id = <0x61>; + }; + qcom,l1_i_cache2 { + qcom,dump-node = <&L1_I_2>; + qcom,dump-id = <0x62>; + }; + qcom,l1_i_cache3 { + qcom,dump-node = <&L1_I_3>; + qcom,dump-id = <0x63>; + }; + qcom,l1_i_cache100 { + qcom,dump-node = <&L1_I_100>; + qcom,dump-id = <0x64>; + }; + qcom,l1_i_cache101 { + qcom,dump-node = <&L1_I_101>; + qcom,dump-id = <0x65>; + }; + qcom,l1_i_cache102 { + qcom,dump-node = <&L1_I_102>; + qcom,dump-id = <0x66>; + }; + qcom,l1_i_cache103 { + qcom,dump-node = <&L1_I_103>; + qcom,dump-id = <0x67>; + }; + qcom,l1_d_cache0 { + qcom,dump-node = <&L1_D_0>; + qcom,dump-id = <0x80>; + }; + qcom,l1_d_cache1 { + qcom,dump-node = <&L1_D_1>; + qcom,dump-id = <0x81>; + }; + qcom,l1_d_cache2 { + qcom,dump-node = <&L1_D_2>; + qcom,dump-id = <0x82>; + }; + qcom,l1_d_cache3 { + qcom,dump-node = <&L1_D_3>; + qcom,dump-id = <0x83>; + }; + qcom,l1_d_cache100 { + qcom,dump-node = <&L1_D_100>; + qcom,dump-id = <0x84>; + }; + qcom,l1_d_cache101 { + qcom,dump-node = <&L1_D_101>; + qcom,dump-id = <0x85>; + }; + qcom,l1_d_cache102 { + qcom,dump-node = <&L1_D_102>; + qcom,dump-id = <0x86>; + }; + qcom,l1_d_cache103 { + qcom,dump-node = <&L1_D_103>; + qcom,dump-id = <0x87>; + }; + }; + qcom,sps { compatible = "qcom,msm_sps_4k"; qcom,pipe-attr-ee; @@ -367,6 +527,21 @@ }; }; + arm64-cpu-erp { + compatible = "arm,arm64-cpu-erp"; + interrupts = <0 43 4>, + <0 44 4>, + <0 41 4>, + <0 42 4>; + + interrupt-names = "pri-dbe-irq", + "sec-dbe-irq", + "pri-ext-irq", + "sec-ext-irq"; + + poll-delay-ms = <5000>; + }; + clock_rpmcc: qcom,rpmcc { compatible = "qcom,rpmcc-msmfalcon", "qcom,rpmcc"; #clock-cells = <1>; @@ -736,6 +911,11 @@ #address-cells = <1>; #size-cells = <1>; + mem_dump_table@10 { + compatible = "qcom,msm-imem-mem_dump_table"; + reg = <0x10 8>; + }; + dload_type@18 { compatible = "qcom,msm-imem-dload-type"; reg = <0x18 4>; @@ -785,6 +965,7 @@ #include "msmtriton-regulator.dtsi" #include "msm-gdsc-falcon.dtsi" #include "msmfalcon-common.dtsi" +#include "msm-arm-smmu-triton.dtsi" &gdsc_usb30 { status = "ok"; diff --git a/arch/arm/configs/msmfalcon-perf_defconfig b/arch/arm/configs/msmfalcon-perf_defconfig index 272f760117a7..86a9ac168d0e 100644 --- a/arch/arm/configs/msmfalcon-perf_defconfig +++ b/arch/arm/configs/msmfalcon-perf_defconfig @@ -164,6 +164,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -179,6 +180,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig index c09e02e53a07..6a3bcafa718a 100644 --- a/arch/arm/configs/msmfalcon_defconfig +++ b/arch/arm/configs/msmfalcon_defconfig @@ -163,6 +163,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -178,6 +179,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 80c4c50814d8..723e3925dc84 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1931,9 +1931,6 @@ static void arm_coherent_iommu_unmap_page(struct device *dev, dma_addr_t handle, int offset = handle & ~PAGE_MASK; int len = PAGE_ALIGN(size + offset); - if (!iova) - return; - iommu_unmap(mapping->domain, iova, len); __free_iova(mapping, iova, len); } @@ -1957,9 +1954,6 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, int offset = handle & ~PAGE_MASK; int len = PAGE_ALIGN(size + offset); - if (!iova) - return; - if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) __dma_page_dev_to_cpu(page, offset, size, dir); @@ -1975,9 +1969,6 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev, struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; - if (!iova) - return; - __dma_page_dev_to_cpu(page, offset, size, dir); } @@ -1989,9 +1980,6 @@ static void arm_iommu_sync_single_for_device(struct device *dev, struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; - if (!iova) - return; - __dma_page_cpu_to_dev(page, offset, size, dir); } diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 520a60c46106..42eb9054513a 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -156,6 +156,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -171,6 +172,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 6249b604466b..37f9f5e985ca 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -158,6 +158,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -173,6 +174,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 23287f8d06ea..3a1d78adabf6 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -165,6 +165,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -180,6 +181,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 9cec02c83936..aecae7c8074b 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -164,6 +164,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -179,6 +180,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig index 4d26ad79196d..f01f213f2710 100644 --- a/arch/arm64/configs/msmfalcon-perf_defconfig +++ b/arch/arm64/configs/msmfalcon-perf_defconfig @@ -164,6 +164,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -179,6 +180,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig index c568f005e70b..9b8873da047b 100644 --- a/arch/arm64/configs/msmfalcon_defconfig +++ b/arch/arm64/configs/msmfalcon_defconfig @@ -163,6 +163,7 @@ 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_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y @@ -178,6 +179,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index df083e9350c4..78319858f734 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -1796,9 +1796,6 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle, int offset = handle & ~PAGE_MASK; int len = PAGE_ALIGN(size + offset); - if (!iova) - return; - if (!(is_device_dma_coherent(dev) || dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))) __dma_page_dev_to_cpu(page, offset, size, dir); @@ -1816,9 +1813,6 @@ static void arm_iommu_sync_single_for_cpu(struct device *dev, mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; - if (!iova) - return; - if (!is_device_dma_coherent(dev)) __dma_page_dev_to_cpu(page, offset, size, dir); } @@ -1832,9 +1826,6 @@ static void arm_iommu_sync_single_for_device(struct device *dev, mapping->domain, iova)); unsigned int offset = handle & ~PAGE_MASK; - if (!iova) - return; - if (!is_device_dma_coherent(dev)) __dma_page_cpu_to_dev(page, offset, size, dir); } diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c index 9ce6a1430250..3b526c0db659 100644 --- a/drivers/clk/msm/clock-osm.c +++ b/drivers/clk/msm/clock-osm.c @@ -126,6 +126,7 @@ enum clk_osm_trace_packet_id { #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 L_VAL(freq_data) ((freq_data) & GENMASK(7, 0)) #define CC_ZERO_BEHAV_CTRL 0x100C #define SPM_CC_DCVS_DISABLE 0x1020 @@ -831,7 +832,7 @@ static void clk_osm_print_osm_table(struct clk_osm *c) 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); + lval = L_VAL(table[i].freq_data); core_count = (table[i].freq_data & GENMASK(18, 16)) >> 16; pr_debug("%3d, %11lu, %2u, %5u, %2u, %6u, %8u, %7u, %5u\n", @@ -1894,6 +1895,7 @@ static void clk_osm_program_apm_regs(struct clk_osm *c) static void clk_osm_program_mem_acc_regs(struct clk_osm *c) { + struct osm_entry *table = c->osm_table; int i, curr_level, j = 0; int mem_acc_level_map[MAX_MEM_ACC_LEVELS] = {0, 0, 0}; int threshold_vc[4]; @@ -1965,6 +1967,16 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) /* SEQ_REG(49) = SEQ_REG(28) init by TZ */ } + /* + * Program L_VAL corresponding to the first virtual + * corner with MEM ACC level 3. + */ + if (c->mem_acc_threshold_vc) + for (i = 0; i < c->num_entries; i++) + if (c->mem_acc_threshold_vc == table[i].virtual_corner) + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(32), + L_VAL(table[i].freq_data)); + return; } diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c index af89610f8c65..c13ff563c8bf 100644 --- a/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c +++ b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c @@ -29,6 +29,8 @@ int link2xclk_divsel_set_div(struct div_clk *clk, int div) int rc; u32 link2xclk_div_tx0, link2xclk_div_tx1; u32 phy_mode; + u8 orientation; + u32 spare_value; struct mdss_pll_resources *dp_res = clk->priv; rc = mdss_pll_resource_enable(dp_res, true); @@ -37,6 +39,11 @@ int link2xclk_divsel_set_div(struct div_clk *clk, int div) return rc; } + spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); + orientation = (spare_value & 0xF0) >> 4; + pr_debug("spare_value=0x%x, orientation=0x%x\n", spare_value, + orientation); + link2xclk_div_tx0 = MDSS_PLL_REG_R(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TX_BAND); link2xclk_div_tx1 = MDSS_PLL_REG_R(dp_res->phy_base, @@ -49,8 +56,12 @@ int link2xclk_divsel_set_div(struct div_clk *clk, int div) link2xclk_div_tx0 |= 0x4; link2xclk_div_tx1 |= 0x4; - /*configure DP PHY MODE */ - phy_mode = 0x58; + /* Configure DP PHY MODE depending on the plug orientation */ + if (orientation == ORIENTATION_CC2) + phy_mode = 0x48; + else + phy_mode = 0x58; + MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_TX_BAND, @@ -334,11 +345,9 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate) wmb(); if (orientation == ORIENTATION_CC2) - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_MODE, 0x48); + MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x48); else - MDSS_PLL_REG_W(dp_res->phy_base, - DP_PHY_MODE, 0x58); + MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_MODE, 0x58); MDSS_PLL_REG_W(dp_res->phy_base, DP_PHY_TX0_TX1_LANE_CTL, 0x05); @@ -452,7 +461,7 @@ static int dp_pll_enable(struct clk *c) struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c); struct mdss_pll_resources *dp_res = vco->priv; u8 orientation, ln_cnt; - u32 spare_value, bias_en, drvr_en; + u32 spare_value, bias_en, drvr_en, lane_mode; spare_value = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_SPARE0); ln_cnt = spare_value & 0x0F; @@ -562,12 +571,18 @@ static int dp_pll_enable(struct clk *c) */ wmb(); + if (vco->rate == DP_VCO_HSCLK_RATE_2700MHZDIV1000) + lane_mode = 0xc6; + else + lane_mode = 0xf6; + MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_LANE_MODE_1, - 0xf6); + lane_mode); MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX1_OFFSET + TXn_LANE_MODE_1, - 0xf6); + lane_mode); + MDSS_PLL_REG_W(dp_res->phy_base, QSERDES_TX0_OFFSET + TXn_CLKBUF_ENABLE, 0x1f); diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index ec3d02e8dcb1..cffaf46d732f 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -83,6 +83,15 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling, if (clk_branch_in_hwcg_mode(br)) return 0; + /* + * Some of the BRANCH_VOTED clocks could be controlled by other + * masters via voting registers, and would require to add delay + * polling for the status bit to allow previous clk_disable + * by the GDS controller to go through. + */ + if (enabling && voted) + udelay(5); + if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) { udelay(10); } else if (br->halt_check == BRANCH_HALT_ENABLE || diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 4589a3b6cec6..020bd351bbd8 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -187,5 +187,6 @@ extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_gfx3d_src_ops; +extern const struct clk_ops clk_dp_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 48ff5ea00040..4104a238c088 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -20,6 +20,7 @@ #include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/regmap.h> +#include <linux/rational.h> #include <linux/math64.h> #include <asm/div64.h> @@ -847,6 +848,66 @@ const struct clk_ops clk_pixel_ops = { }; EXPORT_SYMBOL_GPL(clk_pixel_ops); +static int clk_dp_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct freq_tbl f = { 0 }; + unsigned long src_rate; + unsigned long num, den; + u32 mask = BIT(rcg->hid_width) - 1; + u32 hid_div; + + src_rate = clk_get_rate(clk_hw_get_parent(hw)->clk); + if (src_rate <= 0) { + pr_err("Invalid RCG parent rate\n"); + return -EINVAL; + } + + rational_best_approximation(src_rate, rate, + (unsigned long)(1 << 16) - 1, + (unsigned long)(1 << 16) - 1, &den, &num); + + if (!num || !den) { + pr_err("Invalid MN values derived for requested rate %lu\n", + rate); + return -EINVAL; + } + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &hid_div); + f.pre_div = hid_div; + f.pre_div >>= CFG_SRC_DIV_SHIFT; + f.pre_div &= mask; + + if (num == den) { + f.m = 0; + f.n = 0; + } else { + f.m = num; + f.n = den; + } + + return clk_rcg2_configure(rcg, &f); +} + +static int clk_dp_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate, u8 index) +{ + return clk_dp_set_rate(hw, rate, parent_rate); +} + +const struct clk_ops clk_dp_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, + .recalc_rate = clk_rcg2_recalc_rate, + .set_rate = clk_dp_set_rate, + .set_rate_and_parent = clk_dp_set_rate_and_parent, + .determine_rate = clk_pixel_determine_rate, + .list_registers = clk_rcg2_list_registers, +}; +EXPORT_SYMBOL_GPL(clk_dp_ops); + static int clk_gfx3d_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c index c09d2f8c1947..bd93ded07131 100644 --- a/drivers/gpu/msm/adreno_a5xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c @@ -358,10 +358,12 @@ static const unsigned int a5xx_registers[] = { 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B, 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095, 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3, - 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807, + 0x04E0, 0x04F4, 0X04F6, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, + 0xF800, 0xF807, /* CP */ 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0, - 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, + 0x0B00, 0x0B12, 0x0B15, 0X0B1C, 0X0B1E, 0x0B28, 0x0B78, 0x0B7F, + 0x0BB0, 0x0BBD, /* VSC */ 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, /* GRAS */ @@ -412,6 +414,19 @@ static const unsigned int a5xx_registers[] = { 0xA800, 0xA8FF, 0xAC60, 0xAC60, }; +/* + * Set of registers to dump for A5XX before actually triggering crash dumper. + * Registers in pairs - first value is the start offset, second + * is the stop offset (inclusive) + */ +static const unsigned int a5xx_pre_crashdumper_registers[] = { + /* RBBM: RBBM_STATUS */ + 0x04F5, 0x04F5, + /* CP: CP_STATUS_1 */ + 0x0B1D, 0x0B1D, +}; + + struct a5xx_hlsq_sp_tp_regs { unsigned int statetype; unsigned int ahbaddr; @@ -634,6 +649,18 @@ static void a5xx_snapshot_shader(struct kgsl_device *device, } } +/* Dump registers which get affected by crash dumper trigger */ +static size_t a5xx_snapshot_pre_crashdump_regs(struct kgsl_device *device, + u8 *buf, size_t remain, void *priv) +{ + struct kgsl_snapshot_registers pre_cdregs = { + .regs = a5xx_pre_crashdumper_registers, + .count = ARRAY_SIZE(a5xx_pre_crashdumper_registers)/2, + }; + + return kgsl_snapshot_dump_registers(device, buf, remain, &pre_cdregs); +} + static size_t a5xx_legacy_snapshot_registers(struct kgsl_device *device, u8 *buf, size_t remain) { @@ -833,16 +860,22 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, /* Disable Clock gating temporarily for the debug bus to work */ a5xx_hwcg_set(adreno_dev, false); - /* Try to run the crash dumper */ - _a5xx_do_crashdump(device); - + /* Dump the registers which get affected by crash dumper trigger */ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, - snapshot, a5xx_snapshot_registers, NULL); + snapshot, a5xx_snapshot_pre_crashdump_regs, NULL); + /* Dump vbif registers as well which get affected by crash dumper */ adreno_snapshot_vbif_registers(device, snapshot, a5xx_vbif_snapshot_registers, ARRAY_SIZE(a5xx_vbif_snapshot_registers)); + /* Try to run the crash dumper */ + if (device->snapshot_crashdumper) + _a5xx_do_crashdump(device); + + kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, + snapshot, a5xx_snapshot_registers, NULL); + /* Dump SP TP HLSQ registers */ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, a5xx_snapshot_dump_hlsq_sp_tp_regs, NULL); diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 04935e8d0019..7d68c23ad5b7 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -264,6 +264,10 @@ struct kgsl_device { u32 snapshot_faultcount; /* Total number of faults since boot */ bool force_panic; /* Force panic after snapshot dump */ + + /* Use CP Crash dumper to get GPU snapshot*/ + bool snapshot_crashdumper; + struct kobject snapshot_kobj; struct kobject ppd_kobj; diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 13dc3017072d..1caa673db6ff 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -833,6 +833,32 @@ static ssize_t force_panic_store(struct kgsl_device *device, const char *buf, return (ssize_t) ret < 0 ? ret : count; } + +/* Show the snapshot_crashdumper request status */ +static ssize_t snapshot_crashdumper_show(struct kgsl_device *device, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", device->snapshot_crashdumper); +} + + +/* Store the value to snapshot_crashdumper*/ +static ssize_t snapshot_crashdumper_store(struct kgsl_device *device, + const char *buf, size_t count) +{ + unsigned int val = 0; + int ret; + + if (device && count > 0) + device->snapshot_crashdumper = 1; + + ret = kgsl_sysfs_store(buf, &val); + + if (!ret && device) + device->snapshot_crashdumper = (bool)val; + + return (ssize_t) ret < 0 ? ret : count; +} + /* Show the timestamp of the last collected snapshot */ static ssize_t timestamp_show(struct kgsl_device *device, char *buf) { @@ -859,6 +885,8 @@ struct kgsl_snapshot_attribute attr_##_name = { \ static SNAPSHOT_ATTR(timestamp, 0444, timestamp_show, NULL); static SNAPSHOT_ATTR(faultcount, 0644, faultcount_show, faultcount_store); static SNAPSHOT_ATTR(force_panic, 0644, force_panic_show, force_panic_store); +static SNAPSHOT_ATTR(snapshot_crashdumper, 0644, snapshot_crashdumper_show, + snapshot_crashdumper_store); static ssize_t snapshot_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -939,6 +967,7 @@ int kgsl_device_snapshot_init(struct kgsl_device *device) device->snapshot = NULL; device->snapshot_faultcount = 0; device->force_panic = 0; + device->snapshot_crashdumper = 1; ret = kobject_init_and_add(&device->snapshot_kobj, &ktype_snapshot, &device->dev->kobj, "snapshot"); @@ -959,6 +988,11 @@ int kgsl_device_snapshot_init(struct kgsl_device *device) ret = sysfs_create_file(&device->snapshot_kobj, &attr_force_panic.attr); + if (ret) + goto done; + + ret = sysfs_create_file(&device->snapshot_kobj, + &attr_snapshot_crashdumper.attr); done: return ret; } @@ -984,6 +1018,7 @@ void kgsl_device_snapshot_close(struct kgsl_device *device) device->snapshot_memory.size = 0; device->snapshot_faultcount = 0; device->force_panic = 0; + device->snapshot_crashdumper = 1; } EXPORT_SYMBOL(kgsl_device_snapshot_close); diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c index 266f7065fca4..411f52c5ae81 100644 --- a/drivers/iommu/dma-mapping-fast.c +++ b/drivers/iommu/dma-mapping-fast.c @@ -339,6 +339,30 @@ static void fast_smmu_unmap_page(struct device *dev, dma_addr_t iova, spin_unlock_irqrestore(&mapping->lock, flags); } +static void fast_smmu_sync_single_for_cpu(struct device *dev, + dma_addr_t iova, size_t size, enum dma_data_direction dir) +{ + struct dma_fast_smmu_mapping *mapping = dev->archdata.mapping->fast; + av8l_fast_iopte *pmd = iopte_pmd_offset(mapping->pgtbl_pmds, iova); + unsigned long offset = iova & ~FAST_PAGE_MASK; + struct page *page = phys_to_page((*pmd & FAST_PTE_ADDR_MASK)); + + if (!is_device_dma_coherent(dev)) + __fast_dma_page_dev_to_cpu(page, offset, size, dir); +} + +static void fast_smmu_sync_single_for_device(struct device *dev, + dma_addr_t iova, size_t size, enum dma_data_direction dir) +{ + struct dma_fast_smmu_mapping *mapping = dev->archdata.mapping->fast; + av8l_fast_iopte *pmd = iopte_pmd_offset(mapping->pgtbl_pmds, iova); + unsigned long offset = iova & ~FAST_PAGE_MASK; + struct page *page = phys_to_page((*pmd & FAST_PTE_ADDR_MASK)); + + if (!is_device_dma_coherent(dev)) + __fast_dma_page_cpu_to_dev(page, offset, size, dir); +} + static int fast_smmu_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) @@ -354,6 +378,18 @@ static void fast_smmu_unmap_sg(struct device *dev, WARN_ON_ONCE(1); } +static void fast_smmu_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir) +{ + WARN_ON_ONCE(1); +} + +static void fast_smmu_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nents, enum dma_data_direction dir) +{ + WARN_ON_ONCE(1); +} + static void __fast_smmu_free_pages(struct page **pages, int count) { while (count--) @@ -590,8 +626,12 @@ static const struct dma_map_ops fast_smmu_dma_ops = { .mmap = fast_smmu_mmap_attrs, .map_page = fast_smmu_map_page, .unmap_page = fast_smmu_unmap_page, + .sync_single_for_cpu = fast_smmu_sync_single_for_cpu, + .sync_single_for_device = fast_smmu_sync_single_for_device, .map_sg = fast_smmu_map_sg, .unmap_sg = fast_smmu_unmap_sg, + .sync_sg_for_cpu = fast_smmu_sync_sg_for_cpu, + .sync_sg_for_device = fast_smmu_sync_sg_for_device, .dma_supported = fast_smmu_dma_supported, .mapping_error = fast_smmu_mapping_error, }; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 13a7a398759b..1f860f2c5b12 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -95,11 +95,9 @@ struct msm_vfe_sof_info { struct msm_vfe_dual_hw_ms_info { /* type is Master/Slave */ enum msm_vfe_dual_hw_ms_type dual_hw_ms_type; - /* sof_info is resource from common_data. If NULL, then this INTF - * sof does not need to be saved */ - struct msm_vfe_sof_info *sof_info; - /* slave_id is index in common_data sof_info array for slaves */ - uint8_t slave_id; + enum msm_vfe_dual_cam_sync_mode sync_state; + struct msm_vfe_sof_info sof_info; + int index; }; struct vfe_subscribe_info { @@ -194,15 +192,12 @@ struct msm_vfe_axi_ops { uint8_t plane_idx); void (*clear_wm_xbar_reg)(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx); - - void (*cfg_ub)(struct vfe_device *vfe_dev); - + void (*cfg_ub)(struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src); void (*read_wm_ping_pong_addr)(struct vfe_device *vfe_dev); - void (*update_ping_pong_addr)(void __iomem *vfe_base, uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr, int32_t buf_size); - uint32_t (*get_wm_mask)(uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_comp_mask)(uint32_t irq_status0, uint32_t irq_status1); uint32_t (*get_pingpong_status)(struct vfe_device *vfe_dev); @@ -211,6 +206,8 @@ struct msm_vfe_axi_ops { uint32_t enable_camif); void (*update_cgc_override)(struct vfe_device *vfe_dev, uint8_t wm_idx, uint8_t cgc_override); + uint32_t (*ub_reg_offset)(struct vfe_device *vfe_dev, int idx); + uint32_t (*get_ub_size)(struct vfe_device *vfe_dev); }; struct msm_vfe_core_ops { @@ -245,7 +242,9 @@ struct msm_vfe_core_ops { struct msm_isp_ahb_clk_cfg *ahb_cfg); int (*start_fetch_eng_multi_pass)(struct vfe_device *vfe_dev, void *arg); + void (*set_halt_restart_mask)(struct vfe_device *vfe_dev); }; + struct msm_vfe_stats_ops { int (*get_stats_idx)(enum msm_isp_stats_type stats_type); int (*check_streams)(struct msm_vfe_stats_stream *stream_info); @@ -678,13 +677,14 @@ struct dual_vfe_resource { struct master_slave_resource_info { enum msm_vfe_dual_hw_type dual_hw_type; - struct msm_vfe_sof_info master_sof_info; - uint8_t master_active; uint32_t sof_delta_threshold; /* Updated by Master */ - uint32_t num_slave; - uint32_t reserved_slave_mask; - uint32_t slave_active_mask; - struct msm_vfe_sof_info slave_sof_info[MS_NUM_SLAVE_MAX]; + uint32_t active_src_mask; + uint32_t src_sof_mask; + int master_index; + int primary_slv_idx; + struct msm_vfe_src_info *src_info[MAX_VFE * VFE_SRC_MAX]; + uint32_t num_src; + enum msm_vfe_dual_cam_sync_mode dual_sync_mode; }; struct msm_vfe_common_dev_data { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c index 8b5a3d8d508d..8275f8cedf2e 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c @@ -60,6 +60,16 @@ static struct msm_cam_clk_info msm_vfe32_2_clk_info[] = { {"csi_vfe_clk", -1}, }; +static uint32_t msm_vfe32_ub_reg_offset(struct vfe_device *vfe_dev, int idx) +{ + return (VFE32_WM_BASE(idx) + 0x10); +} + +static uint32_t msm_vfe32_get_ub_size(struct vfe_device *vfe_dev) +{ + return MSM_ISP32_TOTAL_WM_UB; +} + static int32_t msm_vfe32_init_qos_parms(struct vfe_device *vfe_dev, struct msm_vfe_hw_init_parms *qos_parms, struct msm_vfe_hw_init_parms *ds_parms) @@ -1099,76 +1109,6 @@ static void msm_vfe32_axi_clear_wm_xbar_reg( msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm)); } -static void msm_vfe32_cfg_axi_ub_equal_default(struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t total_image_size = 0; - uint32_t num_used_wms = 0; - uint32_t prop_size = 0; - uint32_t wm_ub_size; - uint64_t delta; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; - } - } - prop_size = MSM_ISP32_TOTAL_WM_UB - - axi_data->hw_info->min_wm_ub * num_used_wms; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { - delta = - (uint64_t)(axi_data->wm_image_size[i] * - prop_size); - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; - msm_camera_io_w(ub_offset << 16 | - (wm_ub_size - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += wm_ub_size; - } else { - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC); - } - } -} - -static void msm_vfe32_cfg_axi_ub_equal_slicing(struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - uint32_t final_ub_slice_size; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (ub_offset + VFE32_EQUAL_SLICE_UB > VFE32_AXI_SLICE_UB) { - final_ub_slice_size = VFE32_AXI_SLICE_UB - ub_offset; - msm_camera_io_w(ub_offset << 16 | - (final_ub_slice_size - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += final_ub_slice_size; - } else { - msm_camera_io_w(ub_offset << 16 | - (VFE32_EQUAL_SLICE_UB - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += VFE32_EQUAL_SLICE_UB; - } - } -} - -static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev) -{ - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT; - if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) - msm_vfe32_cfg_axi_ub_equal_slicing(vfe_dev); - else - msm_vfe32_cfg_axi_ub_equal_default(vfe_dev); -} - static void msm_vfe32_update_ping_pong_addr(void __iomem *vfe_base, uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr, int32_t buf_size) @@ -1506,13 +1446,15 @@ struct msm_vfe_hardware_info vfe32_hw_info = { .clear_wm_reg = msm_vfe32_axi_clear_wm_reg, .cfg_wm_xbar_reg = msm_vfe32_axi_cfg_wm_xbar_reg, .clear_wm_xbar_reg = msm_vfe32_axi_clear_wm_xbar_reg, - .cfg_ub = msm_vfe32_cfg_axi_ub, + .cfg_ub = msm_vfe47_cfg_axi_ub, .update_ping_pong_addr = msm_vfe32_update_ping_pong_addr, .get_comp_mask = msm_vfe32_get_comp_mask, .get_wm_mask = msm_vfe32_get_wm_mask, .get_pingpong_status = msm_vfe32_get_pingpong_status, .halt = msm_vfe32_axi_halt, + .ub_reg_offset = msm_vfe40_ub_reg_offset, + .get_ub_size = msm_vfe40_get_ub_size, }, .core_ops = { .reg_update = msm_vfe32_reg_update, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 1375d3ce8c65..2d937fc3ed05 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -97,6 +97,20 @@ static uint8_t stats_pingpong_offset_map[] = { #define VFE40_CLK_IDX 2 +static uint32_t msm_vfe40_ub_reg_offset(struct vfe_device *vfe_dev, int idx) +{ + return (VFE40_WM_BASE(idx) + 0x10); +} + +static uint32_t msm_vfe40_get_ub_size(struct vfe_device *vfe_dev) +{ + if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION) { + vfe_dev->ub_info->wm_ub = VFE40_TOTAL_WM_UB_8916; + return VFE40_TOTAL_WM_UB_8916; + } + return VFE40_TOTAL_WM_UB; +} + static void msm_vfe40_config_irq(struct vfe_device *vfe_dev, uint32_t irq0_mask, uint32_t irq1_mask, enum msm_isp_irq_operation oper) @@ -740,7 +754,7 @@ static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev, msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->hw_info->vfe_ops.axi_ops. - reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0001FFFF); + reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0003FFFF); } @@ -1693,104 +1707,6 @@ static void msm_vfe40_axi_clear_wm_xbar_reg( vfe_dev->vfe_base + VFE40_XBAR_BASE(wm)); } -static void msm_vfe40_cfg_axi_ub_equal_default( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = - &vfe_dev->axi_data; - uint32_t total_image_size = 0; - uint8_t num_used_wms = 0; - uint32_t prop_size = 0; - uint32_t wm_ub_size; - uint32_t total_wm_ub; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; - } - } - - if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION) { - vfe_dev->ub_info->wm_ub = VFE40_TOTAL_WM_UB_8916; - total_wm_ub = VFE40_TOTAL_WM_UB_8916; - } else { - vfe_dev->ub_info->wm_ub = VFE40_TOTAL_WM_UB; - total_wm_ub = VFE40_TOTAL_WM_UB; - } - vfe_dev->ub_info->num_wm = axi_data->hw_info->num_wm; - prop_size = total_wm_ub - - axi_data->hw_info->min_wm_ub * num_used_wms; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { - uint64_t delta = 0; - uint64_t temp = (uint64_t)axi_data->wm_image_size[i] * - (uint64_t)prop_size; - do_div(temp, total_image_size); - delta = temp; - wm_ub_size = axi_data->hw_info->min_wm_ub + delta; - msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), - vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10); - - vfe_dev->ub_info->data[i] = - ub_offset << 16 | (wm_ub_size - 1); - vfe_dev->ub_info->addr[i] = VFE40_WM_BASE(i) + 0x10; - ub_offset += wm_ub_size; - } else { - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10); - vfe_dev->ub_info->data[i] = 0; - vfe_dev->ub_info->addr[i] = VFE40_WM_BASE(i) + 0x10; - } - } -} - -static void msm_vfe40_cfg_axi_ub_equal_slicing( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - uint32_t equal_slice_ub; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION || - vfe_dev->vfe_hw_version == VFE40_8952_VERSION) { - vfe_dev->ub_info->wm_ub = VFE40_EQUAL_SLICE_UB_8916; - equal_slice_ub = VFE40_EQUAL_SLICE_UB_8916; - } else { - vfe_dev->ub_info->wm_ub = VFE40_EQUAL_SLICE_UB; - equal_slice_ub = VFE40_EQUAL_SLICE_UB; - } - - vfe_dev->ub_info->num_wm = axi_data->hw_info->num_wm; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - msm_camera_io_w(ub_offset << 16 | (equal_slice_ub - 1), - vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10); - vfe_dev->ub_info->data[i] = - ub_offset << 16 | (equal_slice_ub - 1); - vfe_dev->ub_info->addr[i] = VFE40_WM_BASE(i) + 0x10; - ub_offset += equal_slice_ub; - } -} - -static void msm_vfe40_cfg_axi_ub(struct vfe_device *vfe_dev) -{ - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - axi_data->wm_ub_cfg_policy = - (enum msm_wm_ub_cfg_type)vfe_dev->vfe_ub_policy; - ISP_DBG("%s: ub_policy %d\n", __func__, axi_data->wm_ub_cfg_policy); - - if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) { - vfe_dev->ub_info->policy = MSM_WM_UB_EQUAL_SLICING; - msm_vfe40_cfg_axi_ub_equal_slicing(vfe_dev); - } else { - vfe_dev->ub_info->policy = MSM_WM_UB_CFG_DEFAULT; - msm_vfe40_cfg_axi_ub_equal_default(vfe_dev); - } -} - static void msm_vfe40_read_wm_ping_pong_addr( struct vfe_device *vfe_dev) { @@ -1808,6 +1724,11 @@ static void msm_vfe40_update_ping_pong_addr( VFE40_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe40_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe40_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1859,11 +1780,9 @@ static void msm_vfe40_axi_restart(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - - if (enable_camif) { + if (enable_camif) vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, ENABLE_CAMIF); - } + update_camif_state(vfe_dev, ENABLE_CAMIF); } static uint32_t msm_vfe40_get_wm_mask( @@ -2304,7 +2223,7 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .clear_wm_reg = msm_vfe40_axi_clear_wm_reg, .cfg_wm_xbar_reg = msm_vfe40_axi_cfg_wm_xbar_reg, .clear_wm_xbar_reg = msm_vfe40_axi_clear_wm_xbar_reg, - .cfg_ub = msm_vfe40_cfg_axi_ub, + .cfg_ub = msm_vfe47_cfg_axi_ub, .read_wm_ping_pong_addr = msm_vfe40_read_wm_ping_pong_addr, .update_ping_pong_addr = @@ -2316,6 +2235,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .restart = msm_vfe40_axi_restart, .update_cgc_override = msm_vfe40_axi_update_cgc_override, + .ub_reg_offset = msm_vfe40_ub_reg_offset, + .get_ub_size = msm_vfe40_get_ub_size, }, .core_ops = { .reg_update = msm_vfe40_reg_update, @@ -2340,6 +2261,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .ahb_clk_cfg = NULL, .start_fetch_eng_multi_pass = msm_vfe40_start_fetch_engine_multi_pass, + .set_halt_restart_mask = + msm_vfe40_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe40_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index a9940927d426..15820b5f398b 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -66,6 +66,16 @@ static uint8_t stats_pingpong_offset_map[] = { #define VFE44_CLK_IDX 2 +static uint32_t msm_vfe44_ub_reg_offset(struct vfe_device *vfe_dev, int wm_idx) +{ + return (VFE44_WM_BASE(wm_idx) + 0x10); +} + +static uint32_t msm_vfe44_get_ub_size(struct vfe_device *vfe_dev) +{ + return MSM_ISP44_TOTAL_IMAGE_UB; +} + static void msm_vfe44_config_irq(struct vfe_device *vfe_dev, uint32_t irq0_mask, uint32_t irq1_mask, enum msm_isp_irq_operation oper) @@ -577,7 +587,7 @@ static long msm_vfe44_reset_hardware(struct vfe_device *vfe_dev, msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->hw_info->vfe_ops.axi_ops. - reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0001FFFF); + reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0031FFFF); } if (blocking_call) { @@ -1262,68 +1272,6 @@ static void msm_vfe44_axi_clear_wm_xbar_reg( vfe_dev->vfe_base + VFE44_XBAR_BASE(wm)); } -static void msm_vfe44_cfg_axi_ub_equal_default( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = - &vfe_dev->axi_data; - uint32_t total_image_size = 0; - uint8_t num_used_wms = 0; - uint32_t prop_size = 0; - uint32_t wm_ub_size; - uint64_t delta; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; - } - } - prop_size = MSM_ISP44_TOTAL_IMAGE_UB - - axi_data->hw_info->min_wm_ub * num_used_wms; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { - delta = (uint64_t)axi_data->wm_image_size[i] * - (uint64_t)prop_size; - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; - msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), - vfe_dev->vfe_base + VFE44_WM_BASE(i) + 0x10); - ub_offset += wm_ub_size; - } else - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE44_WM_BASE(i) + 0x10); - } -} - -static void msm_vfe44_cfg_axi_ub_equal_slicing( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t ub_equal_slice = MSM_ISP44_TOTAL_IMAGE_UB / - axi_data->hw_info->num_wm; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - msm_camera_io_w(ub_offset << 16 | (ub_equal_slice - 1), - vfe_dev->vfe_base + VFE44_WM_BASE(i) + 0x10); - ub_offset += ub_equal_slice; - } -} - -static void msm_vfe44_cfg_axi_ub(struct vfe_device *vfe_dev) -{ - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT; - if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) - msm_vfe44_cfg_axi_ub_equal_slicing(vfe_dev); - else - msm_vfe44_cfg_axi_ub_equal_default(vfe_dev); -} - static void msm_vfe44_read_wm_ping_pong_addr( struct vfe_device *vfe_dev) { @@ -1341,6 +1289,12 @@ static void msm_vfe44_update_ping_pong_addr( VFE44_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe44_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe44_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + + static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1397,11 +1351,9 @@ static void msm_vfe44_axi_restart(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - - if (enable_camif) { + if (enable_camif) vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, ENABLE_CAMIF); - } + update_camif_state(vfe_dev, ENABLE_CAMIF); } static uint32_t msm_vfe44_get_wm_mask( @@ -1879,7 +1831,7 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .clear_wm_reg = msm_vfe44_axi_clear_wm_reg, .cfg_wm_xbar_reg = msm_vfe44_axi_cfg_wm_xbar_reg, .clear_wm_xbar_reg = msm_vfe44_axi_clear_wm_xbar_reg, - .cfg_ub = msm_vfe44_cfg_axi_ub, + .cfg_ub = msm_vfe47_cfg_axi_ub, .read_wm_ping_pong_addr = msm_vfe44_read_wm_ping_pong_addr, .update_ping_pong_addr = @@ -1891,6 +1843,8 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .restart = msm_vfe44_axi_restart, .update_cgc_override = msm_vfe44_axi_update_cgc_override, + .ub_reg_offset = msm_vfe44_ub_reg_offset, + .get_ub_size = msm_vfe44_get_ub_size, }, .core_ops = { .reg_update = msm_vfe44_reg_update, @@ -1913,6 +1867,8 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .is_module_cfg_lock_needed = msm_vfe44_is_module_cfg_lock_needed, .ahb_clk_cfg = NULL, + .set_halt_restart_mask = + msm_vfe44_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe44_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index d239c6069ad9..23fbc4f5e33a 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -88,6 +88,18 @@ static uint8_t stats_pingpong_offset_map[] = { #define VFE46_CLK_IDX 2 +uint32_t msm_vfe46_ub_reg_offset(struct vfe_device *vfe_dev, int wm_idx) +{ + return (VFE46_WM_BASE(wm_idx) + 0x10); +} + +uint32_t msm_vfe46_get_ub_size(struct vfe_device *vfe_dev) +{ + if (vfe_dev->pdev->id == ISP_VFE0) + return MSM_ISP46_TOTAL_IMAGE_UB_VFE0; + return MSM_ISP46_TOTAL_IMAGE_UB_VFE1; +} + static void msm_vfe46_config_irq(struct vfe_device *vfe_dev, uint32_t irq0_mask, uint32_t irq1_mask, enum msm_isp_irq_operation oper) @@ -514,7 +526,7 @@ static long msm_vfe46_reset_hardware(struct vfe_device *vfe_dev, msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); vfe_dev->hw_info->vfe_ops.axi_ops. - reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0001FFFF); + reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0031FFFF); } if (blocking_call) { @@ -1326,85 +1338,6 @@ static void msm_vfe46_axi_clear_wm_xbar_reg( vfe_dev->vfe_base + VFE46_XBAR_BASE(wm)); } - -static void msm_vfe46_cfg_axi_ub_equal_default( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = - &vfe_dev->axi_data; - uint32_t total_image_size = 0; - uint8_t num_used_wms = 0; - uint32_t prop_size = 0; - uint32_t wm_ub_size; - uint64_t delta; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; - } - } - if (vfe_dev->pdev->id == ISP_VFE0) { - prop_size = MSM_ISP46_TOTAL_IMAGE_UB_VFE0 - - axi_data->hw_info->min_wm_ub * num_used_wms; - } else if (vfe_dev->pdev->id == ISP_VFE1) { - prop_size = MSM_ISP46_TOTAL_IMAGE_UB_VFE1 - - axi_data->hw_info->min_wm_ub * num_used_wms; - } else { - pr_err("%s: incorrect VFE device\n", __func__); - } - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { - delta = (uint64_t)axi_data->wm_image_size[i] * - (uint64_t)prop_size; - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; - msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), - vfe_dev->vfe_base + VFE46_WM_BASE(i) + 0x10); - ub_offset += wm_ub_size; - } else - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE46_WM_BASE(i) + 0x10); - } -} - -static void msm_vfe46_cfg_axi_ub_equal_slicing( - struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t ub_equal_slice = 0; - if (vfe_dev->pdev->id == ISP_VFE0) { - ub_equal_slice = MSM_ISP46_TOTAL_IMAGE_UB_VFE0 / - axi_data->hw_info->num_wm; - } else if (vfe_dev->pdev->id == ISP_VFE1) { - ub_equal_slice = MSM_ISP46_TOTAL_IMAGE_UB_VFE1 / - axi_data->hw_info->num_wm; - } else { - pr_err("%s: incorrect VFE device\n ", __func__); - } - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - msm_camera_io_w(ub_offset << 16 | (ub_equal_slice - 1), - vfe_dev->vfe_base + VFE46_WM_BASE(i) + 0x10); - ub_offset += ub_equal_slice; - } -} - -static void msm_vfe46_cfg_axi_ub(struct vfe_device *vfe_dev) -{ - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT; - if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) - msm_vfe46_cfg_axi_ub_equal_slicing(vfe_dev); - else - msm_vfe46_cfg_axi_ub_equal_default(vfe_dev); -} - static void msm_vfe46_read_wm_ping_pong_addr( struct vfe_device *vfe_dev) { @@ -1423,6 +1356,11 @@ static void msm_vfe46_update_ping_pong_addr( VFE46_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe46_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe46_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1478,11 +1416,9 @@ static void msm_vfe46_axi_restart(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - - if (enable_camif) { + if (enable_camif) vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, ENABLE_CAMIF); - } + update_camif_state(vfe_dev, ENABLE_CAMIF); } static uint32_t msm_vfe46_get_wm_mask( @@ -1971,7 +1907,7 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .clear_wm_reg = msm_vfe46_axi_clear_wm_reg, .cfg_wm_xbar_reg = msm_vfe46_axi_cfg_wm_xbar_reg, .clear_wm_xbar_reg = msm_vfe46_axi_clear_wm_xbar_reg, - .cfg_ub = msm_vfe46_cfg_axi_ub, + .cfg_ub = msm_vfe47_cfg_axi_ub, .read_wm_ping_pong_addr = msm_vfe46_read_wm_ping_pong_addr, .update_ping_pong_addr = @@ -1983,6 +1919,8 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .restart = msm_vfe46_axi_restart, .update_cgc_override = msm_vfe46_axi_update_cgc_override, + .ub_reg_offset = msm_vfe46_ub_reg_offset, + .get_ub_size = msm_vfe46_get_ub_size, }, .core_ops = { .reg_update = msm_vfe46_reg_update, @@ -2005,6 +1943,8 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .is_module_cfg_lock_needed = msm_vfe46_is_module_cfg_lock_needed, .ahb_clk_cfg = NULL, + .set_halt_restart_mask = + msm_vfe46_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe46_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 98e73d48ad15..56056849e140 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -148,6 +148,18 @@ static struct msm_bus_scale_pdata msm_isp_bus_client_pdata = { .name = "msm_camera_isp", }; +uint32_t msm_vfe47_ub_reg_offset(struct vfe_device *vfe_dev, int wm_idx) +{ + return (VFE47_WM_BASE(wm_idx) + 0x18); +} + +uint32_t msm_vfe47_get_ub_size(struct vfe_device *vfe_dev) +{ + if (vfe_dev->pdev->id == ISP_VFE0) + return MSM_ISP47_TOTAL_IMAGE_UB_VFE0; + return MSM_ISP47_TOTAL_IMAGE_UB_VFE1; +} + void msm_vfe47_config_irq(struct vfe_device *vfe_dev, uint32_t irq0_mask, uint32_t irq1_mask, enum msm_isp_irq_operation oper) @@ -600,10 +612,14 @@ void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev, MSM_ISP_COMP_IRQ_REG_UPD); msm_isp_process_reg_upd_epoch_irq(vfe_dev, i, MSM_ISP_COMP_IRQ_REG_UPD, ts); - /* if 0 streams then force reg update */ - if (vfe_dev->axi_data.src_info - [i].stream_count == 0 && - vfe_dev->axi_data.src_info[i].active) + /* + * if only camif raw streams active then force + * reg update + */ + if (vfe_dev->axi_data.src_info[VFE_PIX_0]. + raw_stream_count > 0 && + vfe_dev->axi_data.src_info[VFE_PIX_0]. + stream_count == 0) vfe_dev->hw_info->vfe_ops.core_ops. reg_update(vfe_dev, i); break; @@ -739,12 +755,12 @@ long msm_vfe47_reset_hardware(struct vfe_device *vfe_dev, msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); vfe_dev->hw_info->vfe_ops.axi_ops. - reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0001FFFF); + reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0031FFFF); } if (blocking_call) { rc = wait_for_completion_timeout( - &vfe_dev->reset_complete, msecs_to_jiffies(50)); + &vfe_dev->reset_complete, msecs_to_jiffies(100)); if (rc <= 0) { pr_err("%s:%d failed: reset timeout\n", __func__, __LINE__); @@ -1717,7 +1733,8 @@ void msm_vfe47_axi_clear_wm_xbar_reg( void msm_vfe47_cfg_axi_ub_equal_default( - struct vfe_device *vfe_dev) + struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src) { int i; uint32_t ub_offset = 0; @@ -1729,34 +1746,75 @@ void msm_vfe47_cfg_axi_ub_equal_default( uint32_t wm_ub_size; uint64_t delta; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; + if (frame_src == VFE_PIX_0) { + for (i = 0; i < axi_data->hw_info->num_wm; i++) { + if (axi_data->free_wm[i] && + SRC_TO_INTF( + HANDLE_TO_IDX(axi_data->free_wm[i])) == + VFE_PIX_0) { + num_used_wms++; + total_image_size += + axi_data->wm_image_size[i]; + } } + ub_offset = (axi_data->hw_info->num_rdi * 2) * + axi_data->hw_info->min_wm_ub; + prop_size = vfe_dev->hw_info->vfe_ops.axi_ops. + get_ub_size(vfe_dev) - + axi_data->hw_info->min_wm_ub * (num_used_wms + + axi_data->hw_info->num_rdi * 2); } - if (vfe_dev->pdev->id == ISP_VFE0) { - prop_size = MSM_ISP47_TOTAL_IMAGE_UB_VFE0 - - axi_data->hw_info->min_wm_ub * num_used_wms; - } else if (vfe_dev->pdev->id == ISP_VFE1) { - prop_size = MSM_ISP47_TOTAL_IMAGE_UB_VFE1 - - axi_data->hw_info->min_wm_ub * num_used_wms; - } else { - pr_err("%s: incorrect VFE device\n", __func__); - } + for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { + if (!axi_data->free_wm[i]) { + msm_camera_io_w(0, + vfe_dev->vfe_base + + vfe_dev->hw_info->vfe_ops.axi_ops. + ub_reg_offset(vfe_dev, i)); + continue; + } + + if (frame_src != SRC_TO_INTF( + HANDLE_TO_IDX(axi_data->free_wm[i]))) + continue; + + if (frame_src == VFE_PIX_0) { delta = (uint64_t)axi_data->wm_image_size[i] * - (uint64_t)prop_size; - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + + (uint64_t)prop_size; + do_div(delta, total_image_size); + wm_ub_size = axi_data->hw_info->min_wm_ub + (uint32_t)delta; msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1), - vfe_dev->vfe_base + VFE47_WM_BASE(i) + 0x18); + vfe_dev->vfe_base + + vfe_dev->hw_info->vfe_ops.axi_ops. + ub_reg_offset(vfe_dev, i)); ub_offset += wm_ub_size; - } else - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE47_WM_BASE(i) + 0x18); + } else { + uint32_t rdi_ub_offset; + int plane; + int vfe_idx; + struct msm_vfe_axi_stream *stream_info; + + stream_info = msm_isp_get_stream_common_data(vfe_dev, + HANDLE_TO_IDX(axi_data->free_wm[i])); + vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, + stream_info); + for (plane = 0; plane < stream_info->num_planes; + plane++) + if (stream_info->wm[vfe_idx][plane] == + axi_data->free_wm[i]) + break; + + rdi_ub_offset = ((SRC_TO_INTF( + HANDLE_TO_IDX(axi_data->free_wm[i])) - + VFE_RAW_0 * 2) + plane) * + axi_data->hw_info->min_wm_ub; + wm_ub_size = axi_data->hw_info->min_wm_ub * 2; + msm_camera_io_w(rdi_ub_offset << 16 | (wm_ub_size - 1), + vfe_dev->vfe_base + + vfe_dev->hw_info->vfe_ops.axi_ops. + ub_reg_offset(vfe_dev, i)); + } } } @@ -1767,23 +1825,21 @@ void msm_vfe47_cfg_axi_ub_equal_slicing( uint32_t ub_offset = 0; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint32_t ub_equal_slice = 0; - if (vfe_dev->pdev->id == ISP_VFE0) { - ub_equal_slice = MSM_ISP47_TOTAL_IMAGE_UB_VFE0 / - axi_data->hw_info->num_wm; - } else if (vfe_dev->pdev->id == ISP_VFE1) { - ub_equal_slice = MSM_ISP47_TOTAL_IMAGE_UB_VFE1 / - axi_data->hw_info->num_wm; - } else { - pr_err("%s: incorrect VFE device\n ", __func__); - } + + ub_equal_slice = vfe_dev->hw_info->vfe_ops.axi_ops. + get_ub_size(vfe_dev) / + axi_data->hw_info->num_wm; for (i = 0; i < axi_data->hw_info->num_wm; i++) { msm_camera_io_w(ub_offset << 16 | (ub_equal_slice - 1), - vfe_dev->vfe_base + VFE47_WM_BASE(i) + 0x18); + vfe_dev->vfe_base + + vfe_dev->hw_info->vfe_ops.axi_ops. + ub_reg_offset(vfe_dev, i)); ub_offset += ub_equal_slice; } } -void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev) +void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src) { struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; @@ -1791,7 +1847,7 @@ void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev) if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) msm_vfe47_cfg_axi_ub_equal_slicing(vfe_dev); else - msm_vfe47_cfg_axi_ub_equal_default(vfe_dev); + msm_vfe47_cfg_axi_ub_equal_default(vfe_dev, frame_src); } void msm_vfe47_read_wm_ping_pong_addr( @@ -1821,6 +1877,11 @@ void msm_vfe47_update_ping_pong_addr( } +void msm_vfe47_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe47_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1882,13 +1943,9 @@ void msm_vfe47_axi_restart(struct vfe_device *vfe_dev, vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - - if (enable_camif) { + if (enable_camif) vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, ENABLE_CAMIF); - } - vfe_dev->hw_info->vfe_ops.irq_ops.config_irq(vfe_dev, - 0x810000E0, 0xFFFFFF7E, MSM_ISP_IRQ_ENABLE); + update_camif_state(vfe_dev, ENABLE_CAMIF); } uint32_t msm_vfe47_get_wm_mask( @@ -2773,6 +2830,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .restart = msm_vfe47_axi_restart, .update_cgc_override = msm_vfe47_axi_update_cgc_override, + .ub_reg_offset = msm_vfe47_ub_reg_offset, + .get_ub_size = msm_vfe47_get_ub_size, }, .core_ops = { .reg_update = msm_vfe47_reg_update, @@ -2797,6 +2856,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .ahb_clk_cfg = msm_isp47_ahb_clk_cfg, .start_fetch_eng_multi_pass = msm_vfe47_start_fetch_engine_multi_pass, + .set_halt_restart_mask = + msm_vfe47_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe47_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h index 6524ac84edf3..55cf6a17b18c 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h @@ -97,10 +97,12 @@ void msm_vfe47_axi_clear_wm_xbar_reg( struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx); void msm_vfe47_cfg_axi_ub_equal_default( - struct vfe_device *vfe_dev); + struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src); void msm_vfe47_cfg_axi_ub_equal_slicing( struct vfe_device *vfe_dev); -void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev); +void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src); void msm_vfe47_read_wm_ping_pong_addr( struct vfe_device *vfe_dev); void msm_vfe47_update_ping_pong_addr( @@ -197,4 +199,7 @@ void msm_vfe47_config_irq(struct vfe_device *vfe_dev, enum msm_isp_irq_operation oper); int msm_isp47_ahb_clk_cfg(struct vfe_device *vfe_dev, struct msm_isp_ahb_clk_cfg *ahb_cfg); +void msm_vfe47_set_halt_restart_mask(struct vfe_device *vfe_dev); +uint32_t msm_vfe47_ub_reg_offset(struct vfe_device *vfe_dev, int wm_idx); +uint32_t msm_vfe47_get_ub_size(struct vfe_device *vfe_dev); #endif /* __MSM_ISP47_H__ */ diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c index 568125e2d7c2..c533f23c1163 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c @@ -287,6 +287,8 @@ struct msm_vfe_hardware_info vfe48_hw_info = { .restart = msm_vfe47_axi_restart, .update_cgc_override = msm_vfe47_axi_update_cgc_override, + .ub_reg_offset = msm_vfe47_ub_reg_offset, + .get_ub_size = msm_vfe47_get_ub_size, }, .core_ops = { .reg_update = msm_vfe47_reg_update, @@ -311,6 +313,8 @@ struct msm_vfe_hardware_info vfe48_hw_info = { .ahb_clk_cfg = msm_isp47_ahb_clk_cfg, .start_fetch_eng_multi_pass = msm_vfe47_start_fetch_engine_multi_pass, + .set_halt_restart_mask = + msm_vfe47_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe47_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 3b9c3c9d3926..1bf628de4df0 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -19,10 +19,6 @@ #define HANDLE_TO_IDX(handle) (handle & 0xFF) #define ISP_SOF_DEBUG_COUNT 0 -static int msm_isp_update_dual_HW_ms_info_at_start( - struct vfe_device *vfe_dev, - enum msm_vfe_input_src stream_src); - static void msm_isp_reload_ping_pong_offset( struct msm_vfe_axi_stream *stream_info); @@ -704,7 +700,7 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, sof_info->regs_not_updated = vfe_dev->reg_update_requested; } - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { + for (i = 0; i < RDI_INTF_0; i++) { stream_info = msm_isp_get_stream_common_data(vfe_dev, i); stream_idx = HANDLE_TO_IDX(stream_info->stream_handle[0]); @@ -761,6 +757,71 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, } } +static void msm_isp_sync_dual_cam_frame_id( + struct vfe_device *vfe_dev, + struct master_slave_resource_info *ms_res, + enum msm_vfe_input_src frame_src, + struct msm_isp_timestamp *ts) +{ + struct msm_vfe_src_info *src_info = + &vfe_dev->axi_data.src_info[frame_src]; + int i; + uint32_t frame_id = src_info->frame_id; + uint32_t master_time = 0, current_time; + + if (src_info->dual_hw_ms_info.sync_state == + ms_res->dual_sync_mode) { + (frame_src == VFE_PIX_0) ? src_info->frame_id += + vfe_dev->axi_data.src_info[frame_src]. + sof_counter_step : + src_info->frame_id++; + return; + } + + WARN_ON(ms_res->dual_sync_mode == MSM_ISP_DUAL_CAM_ASYNC); + /* find highest frame id */ + for (i = 0; i < MAX_VFE * VFE_SRC_MAX; i++) { + if (ms_res->src_info[i] == NULL) + continue; + if (src_info == ms_res->src_info[i] || + ms_res->src_info[i]->active == 0) + continue; + if (frame_id >= ms_res->src_info[i]->frame_id) + continue; + frame_id = ms_res->src_info[i]->frame_id; + master_time = ms_res->src_info[i]-> + dual_hw_ms_info.sof_info.mono_timestamp_ms; + } + /* copy highest frame id to the intf based on sof delta */ + current_time = ts->buf_time.tv_sec * 1000 + + ts->buf_time.tv_usec / 1000; + + if (current_time > master_time && + (current_time - master_time) > ms_res->sof_delta_threshold) { + if (frame_src == VFE_PIX_0) + frame_id += vfe_dev->axi_data.src_info[frame_src]. + sof_counter_step; + else + frame_id += 1; + } else { + for (i = 0; i < MAX_VFE * VFE_SRC_MAX; i++) { + if (ms_res->src_info[i] == NULL) + continue; + if (src_info == ms_res->src_info[i] || + ((1 << ms_res->src_info[i]-> + dual_hw_ms_info.index) & + ms_res->active_src_mask) == 0) + continue; + if (ms_res->src_info[i]->frame_id == frame_id) + ms_res->src_sof_mask |= (1 << + ms_res->src_info[i]->dual_hw_ms_info.index); + } + } + ms_res->active_src_mask |= (1 << src_info->dual_hw_ms_info.index); + src_info->frame_id = frame_id; + src_info->dual_hw_ms_info.sync_state = MSM_ISP_DUAL_CAM_SYNC; +} + void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) { @@ -768,13 +829,9 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, struct msm_vfe_sof_info *sof_info = NULL; enum msm_vfe_dual_hw_type dual_hw_type; enum msm_vfe_dual_hw_ms_type ms_type; - struct msm_vfe_sof_info *master_sof_info = NULL; - int32_t time, master_time, delta; - uint32_t sof_incr = 0; unsigned long flags; - - if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0) - msm_isp_update_dual_HW_ms_info_at_start(vfe_dev, frame_src); + struct master_slave_resource_info *ms_res = + &vfe_dev->common_data->ms_resource; spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags); dual_hw_type = @@ -782,43 +839,41 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, ms_type = vfe_dev->axi_data.src_info[frame_src]. dual_hw_ms_info.dual_hw_ms_type; - /* - * Increment frame_id if - * 1. Not Master Slave - * 2. Master - * 3. Slave and Master is Inactive - * - * OR - * (in other words) - * If SLAVE and Master active, don't increment slave frame_id. - * Instead use Master frame_id for Slave. - */ - if ((dual_hw_type == DUAL_HW_MASTER_SLAVE) && - (ms_type == MS_TYPE_SLAVE) && - (vfe_dev->common_data->ms_resource.master_active == 1)) { - /* DUAL_HW_MS_SLAVE && MASTER active */ - time = ts->buf_time.tv_sec * 1000 + - ts->buf_time.tv_usec / 1000; - master_sof_info = &vfe_dev->common_data->ms_resource. - master_sof_info; - master_time = master_sof_info->mono_timestamp_ms; - delta = vfe_dev->common_data->ms_resource.sof_delta_threshold; - ISP_DBG("%s: vfe %d frame_src %d frame %d Slave time %d Master time %d delta %d\n", - __func__, vfe_dev->pdev->id, frame_src, - vfe_dev->axi_data.src_info[frame_src].frame_id, - time, master_time, time - master_time); - - if (time - master_time > delta) - sof_incr = 1; - /* - * If delta < 5ms, slave frame_id = master frame_id - * If delta > 5ms, slave frame_id = master frame_id + 1 - * CANNOT support Batch Mode with this logic currently. - */ - vfe_dev->axi_data.src_info[frame_src].frame_id = - master_sof_info->frame_id + sof_incr; + src_info = &vfe_dev->axi_data.src_info[frame_src]; + if (dual_hw_type == DUAL_HW_MASTER_SLAVE) { + msm_isp_sync_dual_cam_frame_id(vfe_dev, ms_res, frame_src, ts); + if (src_info->dual_hw_ms_info.sync_state == + MSM_ISP_DUAL_CAM_SYNC) { + /* + * for dual hw check that we recv sof from all + * linked intf + */ + if (ms_res->src_sof_mask & (1 << + src_info->dual_hw_ms_info.index)) { + pr_err("Frame out of sync on vfe %d\n", + vfe_dev->pdev->id); + msm_isp_halt_send_error(vfe_dev, + ISP_EVENT_BUF_FATAL_ERROR); + } + ms_res->src_sof_mask |= (1 << + src_info->dual_hw_ms_info.index); + if (ms_res->active_src_mask == ms_res->src_sof_mask) + ms_res->src_sof_mask = 0; + } + sof_info = &vfe_dev->axi_data.src_info[frame_src]. + dual_hw_ms_info.sof_info; + sof_info->frame_id = vfe_dev->axi_data.src_info[frame_src]. + frame_id; + sof_info->timestamp_ms = ts->event_time.tv_sec * 1000 + + ts->event_time.tv_usec / 1000; + sof_info->mono_timestamp_ms = ts->buf_time.tv_sec * 1000 + + ts->buf_time.tv_usec / 1000; + spin_unlock_irqrestore(&vfe_dev->common_data-> + common_dev_data_lock, flags); } else { + spin_unlock_irqrestore(&vfe_dev->common_data-> + common_dev_data_lock, flags); if (frame_src == VFE_PIX_0) { vfe_dev->axi_data.src_info[frame_src].frame_id += vfe_dev->axi_data.src_info[frame_src]. @@ -827,40 +882,27 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, vfe_dev->pdev->id, vfe_dev->axi_data.src_info[frame_src]. sof_counter_step); - src_info = &vfe_dev->axi_data.src_info[frame_src]; - - if (!src_info->frame_id && - !src_info->reg_update_frame_id && - ((src_info->frame_id - - src_info->reg_update_frame_id) > - (MAX_REG_UPDATE_THRESHOLD * - src_info->sof_counter_step))) { - pr_err("%s:%d reg_update not received for %d frames\n", - __func__, __LINE__, - src_info->frame_id - - src_info->reg_update_frame_id); - - msm_isp_halt_send_error(vfe_dev, - ISP_EVENT_REG_UPDATE_MISSING); - } - - } else + } else { vfe_dev->axi_data.src_info[frame_src].frame_id++; + } } - sof_info = vfe_dev->axi_data.src_info[frame_src]. - dual_hw_ms_info.sof_info; - if (dual_hw_type == DUAL_HW_MASTER_SLAVE && - sof_info != NULL) { - sof_info->frame_id = vfe_dev->axi_data.src_info[frame_src]. - frame_id; - sof_info->timestamp_ms = ts->event_time.tv_sec * 1000 + - ts->event_time.tv_usec / 1000; - sof_info->mono_timestamp_ms = ts->buf_time.tv_sec * 1000 + - ts->buf_time.tv_usec / 1000; + if (frame_src == VFE_PIX_0) { + if (!src_info->frame_id && + !src_info->reg_update_frame_id && + ((src_info->frame_id - + src_info->reg_update_frame_id) > + (MAX_REG_UPDATE_THRESHOLD * + src_info->sof_counter_step))) { + pr_err("%s:%d reg_update not received for %d frames\n", + __func__, __LINE__, + src_info->frame_id - + src_info->reg_update_frame_id); + + msm_isp_halt_send_error(vfe_dev, + ISP_EVENT_REG_UPDATE_MISSING); + } } - spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock, - flags); } void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, @@ -869,7 +911,6 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, struct msm_isp_event_data event_data; struct msm_vfe_sof_info *sof_info = NULL, *self_sof = NULL; enum msm_vfe_dual_hw_ms_type ms_type; - int i, j; unsigned long flags; memset(&event_data, 0, sizeof(event_data)); @@ -907,56 +948,44 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, * If need to support framedrop as well, move delta calculation * to userspace */ - if (vfe_dev->axi_data.src_info[frame_src].dual_hw_type == + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, + flags); + if (vfe_dev->common_data->ms_resource.dual_sync_mode == + MSM_ISP_DUAL_CAM_SYNC && + vfe_dev->axi_data.src_info[frame_src].dual_hw_type == DUAL_HW_MASTER_SLAVE) { - spin_lock_irqsave( - &vfe_dev->common_data->common_dev_data_lock, - flags); - self_sof = vfe_dev->axi_data.src_info[frame_src]. + struct master_slave_resource_info *ms_res = + &vfe_dev->common_data->ms_resource; + self_sof = &vfe_dev->axi_data.src_info[frame_src]. dual_hw_ms_info.sof_info; - if (!self_sof) { - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); - break; - } ms_type = vfe_dev->axi_data.src_info[frame_src]. dual_hw_ms_info.dual_hw_ms_type; - if (ms_type == MS_TYPE_MASTER) { - for (i = 0, j = 0; i < MS_NUM_SLAVE_MAX; i++) { - if (!(vfe_dev->common_data-> - ms_resource.slave_active_mask - & (1 << i))) - continue; - sof_info = &vfe_dev->common_data-> - ms_resource.slave_sof_info[i]; - event_data.u.sof_info.ms_delta_info. - delta[j] = - self_sof->mono_timestamp_ms - - sof_info->mono_timestamp_ms; - j++; - if (j == vfe_dev->common_data-> - ms_resource.num_slave) - break; - } - event_data.u.sof_info.ms_delta_info. - num_delta_info = j; - } else { - sof_info = &vfe_dev->common_data->ms_resource. - master_sof_info; + /* only send back time delta for primatry intf */ + if (ms_res->primary_slv_idx > 0 && + ms_type == MS_TYPE_MASTER) + sof_info = &ms_res->src_info[ + ms_res->primary_slv_idx]-> + dual_hw_ms_info.sof_info; + if (ms_type != MS_TYPE_MASTER && + ms_res->master_index > 0) + sof_info = &ms_res->src_info[ + ms_res->master_index]-> + dual_hw_ms_info.sof_info; + if (sof_info) { event_data.u.sof_info.ms_delta_info. - num_delta_info = 1; - event_data.u.sof_info.ms_delta_info.delta[0] = + delta[0] = self_sof->mono_timestamp_ms - sof_info->mono_timestamp_ms; - } - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); - } else { - if (frame_src <= VFE_RAW_2) { - msm_isp_check_for_output_error(vfe_dev, ts, - &event_data.u.sof_info); + event_data.u.sof_info.ms_delta_info. + num_delta_info = 1; } } + spin_unlock_irqrestore(&vfe_dev->common_data-> + common_dev_data_lock, flags); + if (frame_src == VFE_PIX_0) + msm_isp_check_for_output_error(vfe_dev, ts, + &event_data.u.sof_info); break; default: @@ -1559,6 +1588,7 @@ void msm_isp_halt_send_error(struct vfe_device *vfe_dev, uint32_t event) { struct msm_isp_event_data error_event; struct msm_vfe_axi_halt_cmd halt_cmd; + struct vfe_device *temp_dev = NULL; memset(&halt_cmd, 0, sizeof(struct msm_vfe_axi_halt_cmd)); memset(&error_event, 0, sizeof(struct msm_isp_event_data)); @@ -1571,8 +1601,21 @@ void msm_isp_halt_send_error(struct vfe_device *vfe_dev, uint32_t event) atomic_set(&vfe_dev->error_info.overflow_state, HALT_ENFORCED); + vfe_dev->hw_info->vfe_ops.core_ops.set_halt_restart_mask(vfe_dev); + if (vfe_dev->is_split) { + int other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0 ? + ISP_VFE1 : ISP_VFE0); + temp_dev = vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]; + atomic_set(&temp_dev->error_info.overflow_state, + HALT_ENFORCED); + temp_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(temp_dev); + } /* heavy spin lock in axi halt, avoid spin lock outside. */ msm_isp_axi_halt(vfe_dev, &halt_cmd); + if (temp_dev) + msm_isp_axi_halt(temp_dev, &halt_cmd); error_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; @@ -1781,7 +1824,7 @@ static int msm_isp_cfg_ping_pong_address( /* return if buffer already present */ if (stream_info->buf[!pingpong_bit]) { pr_err("stream %x buffer already set for pingpong %d\n", - stream_info->stream_src, pingpong_bit); + stream_info->stream_src, !pingpong_bit); return 0; } @@ -2067,18 +2110,19 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, * * If stream count on an input line is 0 then disable the input */ -static void msm_isp_input_disable(struct vfe_device *vfe_dev) +static void msm_isp_input_disable(struct vfe_device *vfe_dev, int cmd_type) { struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - int ext_read = - (axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ); int stream_count; int total_stream_count = 0; int i; + struct msm_vfe_src_info *src_info; + int ext_read = + (axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ); for (i = 0; i < VFE_SRC_MAX; i++) total_stream_count += axi_data->src_info[i].stream_count + - axi_data->src_info[i].raw_stream_count; + axi_data->src_info[i].raw_stream_count; for (i = 0; i < VFE_SRC_MAX; i++) { stream_count = axi_data->src_info[i].stream_count + @@ -2089,20 +2133,52 @@ static void msm_isp_input_disable(struct vfe_device *vfe_dev) continue; /* deactivate the input line */ axi_data->src_info[i].active = 0; + src_info = &axi_data->src_info[i]; + + if (src_info->dual_hw_type == DUAL_HW_MASTER_SLAVE) { + struct master_slave_resource_info *ms_res = + &vfe_dev->common_data->ms_resource; + unsigned long flags; + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, + flags); + if (src_info->dual_hw_ms_info.index == + ms_res->master_index) + ms_res->master_index = -1; + if (src_info->dual_hw_ms_info.index == + ms_res->primary_slv_idx) + ms_res->primary_slv_idx = -1; + ms_res->active_src_mask &= ~(1 << + src_info->dual_hw_ms_info.index); + ms_res->src_sof_mask &= ~(1 << + src_info->dual_hw_ms_info.index); + ms_res->src_info[src_info->dual_hw_ms_info.index] = + NULL; + ms_res->num_src--; + src_info->dual_hw_ms_info.sync_state = + MSM_ISP_DUAL_CAM_ASYNC; + src_info->dual_hw_type = DUAL_NONE; + src_info->dual_hw_ms_info.index = -1; + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); + } if (i != VFE_PIX_0 || ext_read) continue; - /* halt camif */ - if (total_stream_count == 0) { + if (total_stream_count == 0 || cmd_type == STOP_IMMEDIATELY) vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); - } else { + else vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, DISABLE_CAMIF); - } + update_camif_state(vfe_dev, + DISABLE_CAMIF); } - /* halt and reset hardware if all streams are disabled */ + /* + * halt and reset hardware if all streams are disabled, in this case + * ispif is halted immediately as well + */ if (total_stream_count == 0) { vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1); msm_isp_flush_tasklet(vfe_dev); @@ -2152,6 +2228,10 @@ static void msm_isp_input_enable(struct vfe_device *vfe_dev, axi_data->src_info[i].frame_id = axi_data->src_info[VFE_PIX_0].frame_id; } + /* when start reset overflow state and cfg ub for this intf */ + vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev, i); + atomic_set(&vfe_dev->error_info.overflow_state, + NO_OVERFLOW); if (i != VFE_PIX_0 || ext_read) continue; /* for camif input the camif needs enabling */ @@ -2256,15 +2336,22 @@ static int msm_isp_init_stream_ping_pong_reg( /* Set address for both PING & PO NG register */ rc = msm_isp_cfg_ping_pong_address( stream_info, VFE_PING_FLAG); + /* No buffer available on start is not error */ + if (rc == -ENOMEM && stream_info->stream_type != BURST_STREAM) + return 0; if (rc < 0) { pr_err("%s: No free buffer for ping\n", __func__); return rc; } if (stream_info->stream_type != BURST_STREAM || - stream_info->runtime_num_burst_capture > 1) + stream_info->runtime_num_burst_capture > 1) { rc = msm_isp_cfg_ping_pong_address( stream_info, VFE_PONG_FLAG); + /* No buffer available on start is not error */ + if (rc == -ENOMEM) + return 0; + } if (rc < 0) { pr_err("%s: No free buffer for pong\n", @@ -2291,45 +2378,22 @@ int msm_isp_axi_halt(struct vfe_device *vfe_dev, struct msm_vfe_axi_halt_cmd *halt_cmd) { int rc = 0; - int i; - struct vfe_device *halt_vfes[MAX_VFE] = { NULL, NULL }; - - if (vfe_dev->is_split) - for (i = 0; i < MAX_VFE; i++) - halt_vfes[i] = vfe_dev->common_data-> - dual_vfe_res->vfe_dev[i]; - else - halt_vfes[vfe_dev->pdev->id] = vfe_dev; - - for (i = 0; i < MAX_VFE; i++) { - vfe_dev = halt_vfes[i]; - if (!vfe_dev) - continue; - if (atomic_read(&vfe_dev->error_info.overflow_state) == - OVERFLOW_DETECTED) { - ISP_DBG("%s: VFE%d already halted, direct return\n", - __func__, vfe_dev->pdev->id); - continue; - } - if (halt_cmd->overflow_detected) { - atomic_cmpxchg(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW, OVERFLOW_DETECTED); - pr_err("%s: VFE%d Bus overflow detected: start recovery!\n", - __func__, vfe_dev->pdev->id); - } + if (atomic_read(&vfe_dev->error_info.overflow_state) == + OVERFLOW_DETECTED) + pr_err("%s: VFE%d Bus overflow detected: start recovery!\n", + __func__, vfe_dev->pdev->id); - if (halt_cmd->stop_camif) { - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, - DISABLE_CAMIF_IMMEDIATELY); - } - rc |= vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, - halt_cmd->blocking_halt); + /* take care of pending items in tasklet before halt */ + msm_isp_flush_tasklet(vfe_dev); - /* take care of pending items in tasklet after halt */ - msm_isp_flush_tasklet(vfe_dev); + if (halt_cmd->stop_camif) { + vfe_dev->hw_info->vfe_ops.core_ops. + update_camif_state(vfe_dev, + DISABLE_CAMIF_IMMEDIATELY); } + rc |= vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, + halt_cmd->blocking_halt); return rc; } @@ -2337,13 +2401,12 @@ int msm_isp_axi_halt(struct vfe_device *vfe_dev, int msm_isp_axi_reset(struct vfe_device *vfe_dev, struct msm_vfe_axi_reset_cmd *reset_cmd) { - int rc = 0, i, k, j; + int rc = 0, i, k; struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint32_t bufq_handle = 0, bufq_id = 0; struct msm_isp_timestamp timestamp; unsigned long flags; - struct vfe_device *update_vfes[MAX_VFE] = {0, 0}; int vfe_idx; if (!reset_cmd) { @@ -2352,148 +2415,143 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, return rc; } - rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, - 0, reset_cmd->blocking); - if (vfe_dev->is_split) { - for (i = 0; i < MAX_VFE; i++) - update_vfes[i] = vfe_dev->common_data->dual_vfe_res-> - vfe_dev[i]; - } else { - update_vfes[vfe_dev->pdev->id] = vfe_dev; - } - msm_isp_get_timestamp(×tamp, vfe_dev); - for (k = 0; k < MAX_VFE; k++) { - vfe_dev = update_vfes[k]; - if (!vfe_dev) + for (i = 0; i < VFE_AXI_SRC_MAX; i++) { + stream_info = msm_isp_get_stream_common_data( + vfe_dev, i); + if (stream_info->stream_src >= VFE_AXI_SRC_MAX) { + rc = -1; + pr_err("%s invalid stream src = %d\n", + __func__, + stream_info->stream_src); + break; + } + if (stream_info->state == AVAILABLE || + stream_info->state == INACTIVE) continue; - rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, - 0, reset_cmd->blocking); - - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { - stream_info = msm_isp_get_stream_common_data( - vfe_dev, i); - if (stream_info->stream_src >= VFE_AXI_SRC_MAX) { - rc = -1; - pr_err("%s invalid stream src = %d\n", - __func__, - stream_info->stream_src); - break; - } - if (stream_info->state == AVAILABLE || - stream_info->state == INACTIVE) - continue; + /* handle dual stream on ISP_VFE1 turn */ + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE0) + continue; - /* handle dual stream on ISP_VFE1 turn */ - if (stream_info->num_isp > 1 && - vfe_dev->pdev->id == ISP_VFE0) + /* set ping pong to scratch before flush */ + spin_lock_irqsave(&stream_info->lock, flags); + msm_isp_cfg_stream_scratch(stream_info, + VFE_PING_FLAG); + msm_isp_cfg_stream_scratch(stream_info, + VFE_PONG_FLAG); + spin_unlock_irqrestore(&stream_info->lock, + flags); + for (bufq_id = 0; bufq_id < VFE_BUF_QUEUE_MAX; + bufq_id++) { + bufq_handle = stream_info->bufq_handle[bufq_id]; + if (!bufq_handle) continue; + rc = vfe_dev->buf_mgr->ops->flush_buf( + vfe_dev->buf_mgr, + bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL, + ×tamp.buf_time, + reset_cmd->frame_id); + if (rc == -EFAULT) { + msm_isp_halt_send_error(vfe_dev, + ISP_EVENT_BUF_FATAL_ERROR); + return rc; + } + } - for (bufq_id = 0; bufq_id < VFE_BUF_QUEUE_MAX; - bufq_id++) { - bufq_handle = stream_info->bufq_handle[bufq_id]; - if (!bufq_handle) - continue; - - /* set ping pong to scratch before flush */ - spin_lock_irqsave(&stream_info->lock, flags); - msm_isp_cfg_stream_scratch(stream_info, - VFE_PING_FLAG); - msm_isp_cfg_stream_scratch(stream_info, - VFE_PONG_FLAG); - spin_unlock_irqrestore(&stream_info->lock, - flags); - rc = vfe_dev->buf_mgr->ops->flush_buf( - vfe_dev->buf_mgr, - bufq_handle, MSM_ISP_BUFFER_FLUSH_ALL, - ×tamp.buf_time, - reset_cmd->frame_id); - if (rc == -EFAULT) { - msm_isp_halt_send_error(vfe_dev, - ISP_EVENT_BUF_FATAL_ERROR); - return rc; - } - if (stream_info->num_planes > 1) { - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_comp_mask(vfe_dev, stream_info); - } else { - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_irq_mask(vfe_dev, stream_info); - } - vfe_idx = msm_isp_get_vfe_idx_for_stream( - vfe_dev, stream_info); - for (j = 0; j < stream_info->num_planes; j++) - vfe_dev->hw_info->vfe_ops.axi_ops. - enable_wm( - vfe_dev->vfe_base, - stream_info->wm[vfe_idx][j], 1); - - axi_data->src_info[SRC_TO_INTF(stream_info-> - stream_src)].frame_id = - reset_cmd->frame_id; - msm_isp_reset_burst_count_and_frame_drop( - vfe_dev, stream_info); + for (k = 0; k < stream_info->num_isp; k++) { + struct vfe_device *temp_vfe_dev = + stream_info->vfe_dev[k]; + vfe_idx = msm_isp_get_vfe_idx_for_stream( + temp_vfe_dev, stream_info); + if (stream_info->num_planes > 1) { + temp_vfe_dev->hw_info->vfe_ops.axi_ops. + cfg_comp_mask(temp_vfe_dev, + stream_info); + } else { + temp_vfe_dev->hw_info->vfe_ops.axi_ops. + cfg_wm_irq_mask(temp_vfe_dev, + stream_info); } + axi_data = &temp_vfe_dev->axi_data; + axi_data->src_info[SRC_TO_INTF(stream_info-> + stream_src)].frame_id = + reset_cmd->frame_id; } + msm_isp_reset_burst_count_and_frame_drop( + vfe_dev, stream_info); } + vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, + 0, reset_cmd->blocking); + /* + * call reset a second time for vfe48, calling + * only once causes bus error on camif enable + */ + if (msm_vfe_is_vfe48(vfe_dev)) + vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, + 0, reset_cmd->blocking); + if (rc < 0) pr_err("%s Error! reset hw Timed out\n", __func__); - return rc; + return 0; } -int msm_isp_axi_restart(struct vfe_device *vfe_dev_ioctl, +int msm_isp_axi_restart(struct vfe_device *vfe_dev, struct msm_vfe_axi_restart_cmd *restart_cmd) { int rc = 0, i, k, j; struct msm_vfe_axi_stream *stream_info; - uint32_t wm_reload_mask = 0; + uint32_t wm_reload_mask[MAX_VFE] = {0, 0}; unsigned long flags; - struct vfe_device *update_vfes[MAX_VFE] = {0, 0}; - struct vfe_device *vfe_dev; + int vfe_idx; - if (vfe_dev_ioctl->is_split) { - for (i = 0; i < MAX_VFE; i++) - update_vfes[i] = vfe_dev_ioctl->common_data-> - dual_vfe_res->vfe_dev[i]; - } else { - update_vfes[vfe_dev_ioctl->pdev->id] = vfe_dev_ioctl; + vfe_dev->buf_mgr->frameId_mismatch_recovery = 0; + for (i = 0; i < VFE_AXI_SRC_MAX; i++) { + stream_info = msm_isp_get_stream_common_data( + vfe_dev, i); + if (stream_info->state == AVAILABLE || + stream_info->state == INACTIVE) + continue; + /* handle dual stream on ISP_VFE1 turn */ + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE0) + continue; + spin_lock_irqsave(&stream_info->lock, flags); + for (j = 0; j < MSM_ISP_COMP_IRQ_MAX; j++) + stream_info->composite_irq[j] = 0; + for (k = 0; k < stream_info->num_isp; k++) { + struct vfe_device *temp_vfe_dev = + stream_info->vfe_dev[k]; + vfe_idx = msm_isp_get_vfe_idx_for_stream( + temp_vfe_dev, stream_info); + for (j = 0; j < stream_info->num_planes; j++) + temp_vfe_dev->hw_info->vfe_ops.axi_ops. + enable_wm( + temp_vfe_dev->vfe_base, + stream_info->wm[vfe_idx][j], 1); + msm_isp_get_stream_wm_mask(temp_vfe_dev, stream_info, + &wm_reload_mask[temp_vfe_dev->pdev->id]); + } + msm_isp_init_stream_ping_pong_reg(stream_info); + spin_unlock_irqrestore(&stream_info->lock, flags); } - vfe_dev_ioctl->buf_mgr->frameId_mismatch_recovery = 0; for (k = 0; k < MAX_VFE; k++) { - vfe_dev = update_vfes[k]; - if (!vfe_dev) - continue; - vfe_dev->buf_mgr->frameId_mismatch_recovery = 0; - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { - stream_info = msm_isp_get_stream_common_data( - vfe_dev, i); - if (stream_info->state == AVAILABLE || - stream_info->state == INACTIVE) - continue; - msm_isp_get_stream_wm_mask(vfe_dev, stream_info, - &wm_reload_mask); - /* handle dual stream on ISP_VFE1 turn */ - if (stream_info->num_isp > 1 && - vfe_dev->pdev->id == ISP_VFE0) - continue; - spin_lock_irqsave(&stream_info->lock, flags); - for (j = 0; j < MSM_ISP_COMP_IRQ_MAX; j++) - stream_info->composite_irq[j] = 0; - msm_isp_init_stream_ping_pong_reg(stream_info); - spin_unlock_irqrestore(&stream_info->lock, flags); - } - - vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, - vfe_dev->vfe_base, wm_reload_mask); - vfe_dev->hw_info->vfe_ops.axi_ops.restart(vfe_dev, 0, - restart_cmd->enable_camif); + struct vfe_device *temp_vfe_dev = + vfe_dev->common_data->dual_vfe_res->vfe_dev[k]; + if (wm_reload_mask[k]) + temp_vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm( + temp_vfe_dev, + temp_vfe_dev->vfe_base, wm_reload_mask[k]); } + vfe_dev->hw_info->vfe_ops.axi_ops.restart(vfe_dev, 0, + restart_cmd->enable_camif); + return rc; } @@ -2535,152 +2593,6 @@ static int msm_isp_axi_update_cgc_override(struct vfe_device *vfe_dev_ioctl, return 0; } -static int msm_isp_update_dual_HW_ms_info_at_start( - struct vfe_device *vfe_dev, - enum msm_vfe_input_src stream_src) -{ - int rc = 0; - uint32_t j, k, max_sof = 0; - uint8_t slave_id; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_src_info *src_info = NULL; - uint32_t vfe_id = 0; - unsigned long flags; - - if (stream_src >= VFE_SRC_MAX) { - pr_err("%s: Error! Invalid src %u\n", __func__, stream_src); - return -EINVAL; - } - - src_info = &axi_data->src_info[stream_src]; - if (src_info->dual_hw_type != DUAL_HW_MASTER_SLAVE) - return rc; - - spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags); - if (src_info->dual_hw_ms_info.dual_hw_ms_type == - MS_TYPE_MASTER) { - if (vfe_dev->common_data->ms_resource.master_active == 1) { - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); - return rc; - } - - vfe_dev->common_data->ms_resource.master_active = 1; - - /* - * If any slaves are active, then find the max slave - * frame_id and set it to Master, so master will start - * higher and then the slave can copy master frame_id - * without repeating. - */ - if (!vfe_dev->common_data->ms_resource.slave_active_mask) { - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); - return rc; - } - - for (j = 0, k = 0; k < MS_NUM_SLAVE_MAX; k++) { - if (!(vfe_dev->common_data->ms_resource. - reserved_slave_mask & (1 << k))) - continue; - - if (vfe_dev->common_data->ms_resource.slave_active_mask - & (1 << k) && - (vfe_dev->common_data->ms_resource. - slave_sof_info[k].frame_id > max_sof)) { - max_sof = vfe_dev->common_data->ms_resource. - slave_sof_info[k].frame_id; - } - j++; - if (j == vfe_dev->common_data->ms_resource.num_slave) - break; - } - vfe_dev->axi_data.src_info[stream_src].frame_id = - max_sof + 1; - if (vfe_dev->is_split) { - vfe_id = vfe_dev->pdev->id; - vfe_id = (vfe_id == 0) ? 1 : 0; - vfe_dev->common_data->dual_vfe_res->axi_data[vfe_id]-> - src_info[stream_src].frame_id = max_sof + 1; - } - - ISP_DBG("%s: Setting Master frame_id to %u\n", __func__, - max_sof + 1); - } else { - if (src_info->dual_hw_ms_info.sof_info != NULL) { - slave_id = src_info->dual_hw_ms_info.slave_id; - vfe_dev->common_data->ms_resource.slave_active_mask |= - (1 << slave_id); - } - } - spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock, - flags); - - return rc; -} - -static int msm_isp_update_dual_HW_ms_info_at_stop( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd) -{ - int i, rc = 0; - uint8_t slave_id; - struct msm_vfe_axi_stream *stream_info = NULL; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - enum msm_vfe_input_src stream_src = VFE_SRC_MAX; - struct msm_vfe_src_info *src_info = NULL; - unsigned long flags; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM || - stream_cfg_cmd->num_streams == 0) - return -EINVAL; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - VFE_AXI_SRC_MAX) { - return -EINVAL; - } - stream_info = msm_isp_get_stream_common_data(vfe_dev, - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])); - stream_src = SRC_TO_INTF(stream_info->stream_src); - - /* Remove PIX if DISABLE CAMIF */ - if (stream_src == VFE_PIX_0 && - axi_data->src_info[VFE_PIX_0].active) - continue; - - src_info = &axi_data->src_info[stream_src]; - if (src_info->dual_hw_type != DUAL_HW_MASTER_SLAVE) - continue; - - spin_lock_irqsave( - &vfe_dev->common_data->common_dev_data_lock, - flags); - if (src_info->dual_hw_ms_info.dual_hw_ms_type == - MS_TYPE_MASTER) { - /* - * Once Master is inactive, slave will increment - * its own frame_id - */ - vfe_dev->common_data->ms_resource.master_active = 0; - } else { - slave_id = src_info->dual_hw_ms_info.slave_id; - vfe_dev->common_data->ms_resource.reserved_slave_mask &= - ~(1 << slave_id); - vfe_dev->common_data->ms_resource.slave_active_mask &= - ~(1 << slave_id); - vfe_dev->common_data->ms_resource.num_slave--; - } - src_info->dual_hw_ms_info.sof_info = NULL; - spin_unlock_irqrestore( - &vfe_dev->common_data->common_dev_data_lock, - flags); - vfe_dev->vfe_ub_policy = 0; - } - - return rc; -} - /** * msm_isp_axi_wait_for_stream_cfg_done() - Wait for a stream completion * @stream_info: The stream to wait on @@ -2786,7 +2698,6 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev, int i; struct msm_vfe_axi_shared_data *axi_data; struct msm_isp_timestamp timestamp; - int total_stream_count = 0; uint32_t bufq_id = 0, bufq_handle = 0; struct msm_vfe_axi_stream *stream_info; unsigned long flags; @@ -2808,7 +2719,7 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev, for (k = 0; k < MAX_VFE; k++) { if (!update_vfes[k]) continue; - msm_isp_input_disable(update_vfes[k]); + msm_isp_input_disable(update_vfes[k], cmd_type); } for (i = 0; i < num_streams; i++) { @@ -2844,44 +2755,28 @@ static void __msm_isp_stop_axi_streams(struct vfe_device *vfe_dev, } for (k = 0; k < MAX_VFE; k++) { - int ext_read; - if (!update_vfes[k]) continue; vfe_dev = update_vfes[k]; axi_data = &vfe_dev->axi_data; - ext_read = - (axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ); - for (i = 0; i < VFE_SRC_MAX; i++) { - total_stream_count += - axi_data->src_info[i].stream_count + - axi_data->src_info[i].raw_stream_count; - if (i != VFE_PIX_0) - continue; - if (axi_data->src_info[i].stream_count == 0) { - vfe_dev->hw_info->vfe_ops.stats_ops. - enable_module(vfe_dev, 0xFF, 0); - /* reg update for PIX with 0 streams active */ - if (ext_read == 0) - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, VFE_PIX_0); - } + if (axi_data->src_info[VFE_PIX_0].active == 0) { + vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( + vfe_dev, 0xFF, 0); } - } for (i = 0; i < num_streams; i++) { stream_info = streams[i]; + spin_lock_irqsave(&stream_info->lock, flags); intf = SRC_TO_INTF(stream_info->stream_src); - if (total_stream_count == 0 || - ((stream_info->stream_type == BURST_STREAM) && - stream_info->runtime_num_burst_capture == 0)) { - spin_lock_irqsave(&stream_info->lock, flags); + if (((stream_info->stream_type == BURST_STREAM) && + stream_info->runtime_num_burst_capture == 0) || + (stream_info->vfe_dev[0]->axi_data.src_info[intf]. + active == 0)) { while (stream_info->state != INACTIVE) __msm_isp_axi_stream_update( stream_info, ×tamp); - spin_unlock_irqrestore(&stream_info->lock, flags); - continue; } + spin_unlock_irqrestore(&stream_info->lock, flags); } rc = msm_isp_axi_wait_for_streams(streams, num_streams, 0); @@ -2964,7 +2859,6 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl, struct msm_isp_timestamp timestamp; struct vfe_device *update_vfes[MAX_VFE] = {0, 0}; int k; - uint32_t num_active_streams[MAX_VFE] = {0, 0}; struct vfe_device *vfe_dev; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev_ioctl->axi_data; @@ -3010,9 +2904,6 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl, continue; update_vfes[stream_info->vfe_dev[k]->pdev->id] = stream_info->vfe_dev[k]; - num_active_streams[stream_info->vfe_dev[k]->pdev->id] = - stream_info->vfe_dev[k]->axi_data. - num_active_stream; } msm_isp_reset_framedrop(vfe_dev_ioctl, stream_info); rc = msm_isp_init_stream_ping_pong_reg(stream_info); @@ -3072,13 +2963,6 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev_ioctl, vfe_dev = update_vfes[i]; if (!vfe_dev) continue; - if (num_active_streams[i] == 0) { - /* Configure UB */ - vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev); - /* when start reset overflow state */ - atomic_set(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW); - } msm_isp_update_stream_bandwidth(vfe_dev); vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, vfe_dev->vfe_base, wm_reload_mask[i]); @@ -3141,7 +3025,7 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev_ioctl, int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg) { - int rc = 0, ret; + int rc = 0; struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd = arg; uint32_t stream_idx[MAX_NUM_STREAM]; int i; @@ -3190,11 +3074,6 @@ int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg) * Use different ret value to not overwrite the error from * msm_isp_stop_axi_stream */ - ret = msm_isp_update_dual_HW_ms_info_at_stop( - vfe_dev, stream_cfg_cmd); - if (ret < 0) - pr_warn("%s: Warning! Update dual_cam failed\n", - __func__); if (vfe_dev->axi_data.num_active_stream == 0) vfe_dev->hvx_cmd = HVX_DISABLE; if (vfe_dev->is_split) { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c index f1103183c326..22a7f6886964 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -595,13 +595,12 @@ void msm_isp_release_all_stats_stream(struct vfe_device *vfe_dev) } static int msm_isp_init_stats_ping_pong_reg( - struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info) { int rc = 0; stream_info->bufq_handle = - vfe_dev->buf_mgr->ops->get_bufq_handle( - vfe_dev->buf_mgr, stream_info->session_id, + stream_info->vfe_dev[0]->buf_mgr->ops->get_bufq_handle( + stream_info->vfe_dev[0]->buf_mgr, stream_info->session_id, stream_info->stream_id); if (stream_info->bufq_handle == 0) { pr_err("%s: no buf configured for stream: 0x%x\n", @@ -848,98 +847,78 @@ int msm_isp_stats_reset(struct vfe_device *vfe_dev) int i = 0, rc = 0; struct msm_vfe_stats_stream *stream_info = NULL; struct msm_isp_timestamp timestamp; - struct vfe_device *update_vfes[MAX_VFE] = {NULL, NULL}; unsigned long flags; - int k; msm_isp_get_timestamp(×tamp, vfe_dev); - if (vfe_dev->is_split) { - for (i = 0; i < MAX_VFE; i++) - update_vfes[i] = vfe_dev->common_data->dual_vfe_res-> - vfe_dev[i]; - } else { - update_vfes[vfe_dev->pdev->id] = vfe_dev; - } - - for (k = 0; k < MAX_VFE; k++) { - vfe_dev = update_vfes[k]; - if (!vfe_dev) + for (i = 0; i < MSM_ISP_STATS_MAX; i++) { + stream_info = msm_isp_get_stats_stream_common_data( + vfe_dev, i); + if (stream_info->state == STATS_AVAILABLE || + stream_info->state == STATS_INACTIVE) continue; - for (i = 0; i < MSM_ISP_STATS_MAX; i++) { - stream_info = msm_isp_get_stats_stream_common_data( - vfe_dev, i); - if (stream_info->state == STATS_AVAILABLE || - stream_info->state == STATS_INACTIVE) - continue; - - if (stream_info->num_isp > 1 && - vfe_dev->pdev->id == ISP_VFE0) - continue; - spin_lock_irqsave(&stream_info->lock, flags); - msm_isp_stats_cfg_stream_scratch(stream_info, - VFE_PING_FLAG); - msm_isp_stats_cfg_stream_scratch(stream_info, - VFE_PONG_FLAG); - spin_unlock_irqrestore(&stream_info->lock, flags); - rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, - stream_info->bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL, ×tamp.buf_time, - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); - if (rc == -EFAULT) { - msm_isp_halt_send_error(vfe_dev, - ISP_EVENT_BUF_FATAL_ERROR); - return rc; - } - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_irq_mask( - vfe_dev, stream_info); - vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( - vfe_dev, BIT(i), 1); + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE0) + continue; + spin_lock_irqsave(&stream_info->lock, flags); + msm_isp_stats_cfg_stream_scratch(stream_info, + VFE_PING_FLAG); + msm_isp_stats_cfg_stream_scratch(stream_info, + VFE_PONG_FLAG); + spin_unlock_irqrestore(&stream_info->lock, flags); + rc = vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, + stream_info->bufq_handle, + MSM_ISP_BUFFER_FLUSH_ALL, ×tamp.buf_time, + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); + if (rc == -EFAULT) { + msm_isp_halt_send_error(vfe_dev, + ISP_EVENT_BUF_FATAL_ERROR); + return rc; } } return rc; } -int msm_isp_stats_restart(struct vfe_device *vfe_dev_ioctl) +int msm_isp_stats_restart(struct vfe_device *vfe_dev) { int i = 0; struct msm_vfe_stats_stream *stream_info = NULL; unsigned long flags; - struct vfe_device *update_vfes[MAX_VFE] = {NULL, NULL}; - struct vfe_device *vfe_dev; - int k; int j; - if (vfe_dev_ioctl->is_split) { - for (i = 0; i < MAX_VFE; i++) - update_vfes[i] = vfe_dev_ioctl->common_data-> - dual_vfe_res->vfe_dev[i]; - } else { - update_vfes[vfe_dev_ioctl->pdev->id] = vfe_dev_ioctl; - } - - for (k = 0; k < MAX_VFE; k++) { - vfe_dev = update_vfes[k]; - if (!vfe_dev) + for (i = 0; i < MSM_ISP_STATS_MAX; i++) { + stream_info = msm_isp_get_stats_stream_common_data( + vfe_dev, i); + if (stream_info->state == STATS_AVAILABLE || + stream_info->state == STATS_INACTIVE) continue; - for (i = 0; i < MSM_ISP_STATS_MAX; i++) { - stream_info = msm_isp_get_stats_stream_common_data( - vfe_dev, i); - if (stream_info->state == STATS_AVAILABLE || - stream_info->state == STATS_INACTIVE) - continue; - if (stream_info->num_isp > 1 && - vfe_dev->pdev->id == ISP_VFE0) - continue; - spin_lock_irqsave(&stream_info->lock, flags); - for (j = 0; j < MSM_ISP_COMP_IRQ_MAX; j++) - stream_info->composite_irq[j] = 0; - msm_isp_init_stats_ping_pong_reg(vfe_dev_ioctl, - stream_info); - spin_unlock_irqrestore(&stream_info->lock, flags); + if (stream_info->num_isp > 1 && + vfe_dev->pdev->id == ISP_VFE0) + continue; + spin_lock_irqsave(&stream_info->lock, flags); + for (j = 0; j < MSM_ISP_COMP_IRQ_MAX; j++) + stream_info->composite_irq[j] = 0; + msm_isp_init_stats_ping_pong_reg( + stream_info); + for (j = 0; j < stream_info->num_isp; j++) { + struct vfe_device *temp_vfe_dev = + stream_info->vfe_dev[j]; + uint8_t comp_flag = stream_info->composite_flag; + + temp_vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( + temp_vfe_dev, BIT(i), 1); + if (comp_flag) + temp_vfe_dev->hw_info->vfe_ops.stats_ops. + cfg_comp_mask(temp_vfe_dev, BIT(i), + (comp_flag - 1), 1); + else + temp_vfe_dev->hw_info->vfe_ops.stats_ops. + cfg_wm_irq_mask( + temp_vfe_dev, stream_info); } + spin_unlock_irqrestore(&stream_info->lock, flags); } return 0; @@ -1098,7 +1077,7 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev_ioctl, spin_unlock_irqrestore(&stream_info->lock, flags); goto error; } - rc = msm_isp_init_stats_ping_pong_reg(vfe_dev_ioctl, + rc = msm_isp_init_stats_ping_pong_reg( stream_info); if (rc < 0) { spin_unlock_irqrestore(&stream_info->lock, flags); @@ -1116,12 +1095,12 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev_ioctl, stats_mask |= 1 << idx; for (k = 0; k < stream_info->num_isp; k++) { vfe_dev = stream_info->vfe_dev[k]; - if (update_vfes[vfe_dev->pdev->id]) - continue; - update_vfes[vfe_dev->pdev->id] = vfe_dev; stats_data = &vfe_dev->stats_data; - num_active_streams[vfe_dev->pdev->id] = - stats_data->num_active_stream; + if (update_vfes[vfe_dev->pdev->id] == NULL) { + update_vfes[vfe_dev->pdev->id] = vfe_dev; + num_active_streams[vfe_dev->pdev->id] = + stats_data->num_active_stream; + } stats_data->num_active_stream++; } diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 72eac5d81627..59b875d6e464 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -202,17 +202,17 @@ void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp, struct vfe_device *vfe_dev) { struct timespec ts; + do_gettimeofday(&(time_stamp->event_time)); if (vfe_dev->vt_enable) { msm_isp_get_avtimer_ts(time_stamp); time_stamp->buf_time.tv_sec = time_stamp->vt_time.tv_sec; time_stamp->buf_time.tv_usec = time_stamp->vt_time.tv_usec; - } else { + } else { get_monotonic_boottime(&ts); time_stamp->buf_time.tv_sec = ts.tv_sec; time_stamp->buf_time.tv_usec = ts.tv_nsec/1000; } - } static inline u32 msm_isp_evt_mask_to_isp_event(u32 evt_mask) @@ -548,18 +548,53 @@ int msm_isp_cfg_input(struct vfe_device *vfe_dev, void *arg) return rc; } +static int msm_isp_dual_hw_master_slave_sync(struct vfe_device *vfe_dev, + void *arg) +{ + int rc = 0; + + struct msm_isp_dual_hw_master_slave_sync *link = arg; + unsigned long flags; + struct master_slave_resource_info *ms_res = + &vfe_dev->common_data->ms_resource; + int i; + struct msm_vfe_src_info *src_info = NULL; + + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, + flags); + ms_res->dual_sync_mode = link->sync_mode; + if (ms_res->dual_sync_mode == MSM_ISP_DUAL_CAM_ASYNC) { + for (i = 0; i < MAX_VFE * VFE_SRC_MAX; i++) { + if (ms_res->src_info[i] == NULL) + continue; + src_info = ms_res->src_info[i]; + if (src_info->dual_hw_ms_info.sync_state == + MSM_ISP_DUAL_CAM_ASYNC) + continue; + ms_res->active_src_mask &= ~(1 << + src_info->dual_hw_ms_info.index); + ms_res->src_sof_mask &= ~(1 << + src_info->dual_hw_ms_info.index); + src_info->dual_hw_ms_info.sync_state = + MSM_ISP_DUAL_CAM_ASYNC; + } + } + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); + return rc; +} + static int msm_isp_set_dual_HW_master_slave_mode( struct vfe_device *vfe_dev, void *arg) { - /* - * This method assumes no 2 processes are accessing it simultaneously. - * Currently this is guaranteed by mutex lock in ioctl. - * If that changes, need to revisit this - */ - int rc = 0, i, j; + int rc = 0, i; struct msm_isp_set_dual_hw_ms_cmd *dual_hw_ms_cmd = NULL; struct msm_vfe_src_info *src_info = NULL; unsigned long flags; + struct master_slave_resource_info *ms_res = + &vfe_dev->common_data->ms_resource; if (!vfe_dev || !arg) { pr_err("%s: Error! Invalid input vfe_dev %pK arg %pK\n", @@ -567,6 +602,7 @@ static int msm_isp_set_dual_HW_master_slave_mode( return -EINVAL; } + spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags); dual_hw_ms_cmd = (struct msm_isp_set_dual_hw_ms_cmd *)arg; vfe_dev->common_data->ms_resource.dual_hw_type = DUAL_HW_MASTER_SLAVE; vfe_dev->vfe_ub_policy = MSM_WM_UB_EQUAL_SLICING; @@ -575,50 +611,20 @@ static int msm_isp_set_dual_HW_master_slave_mode( vfe_dev->pdev->id, dual_hw_ms_cmd->primary_intf); src_info = &vfe_dev->axi_data. src_info[dual_hw_ms_cmd->primary_intf]; + src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE; src_info->dual_hw_ms_info.dual_hw_ms_type = dual_hw_ms_cmd->dual_hw_ms_type; - } - - /* No lock needed here since ioctl lock protects 2 session from race */ - if (src_info != NULL && - dual_hw_ms_cmd->dual_hw_ms_type == MS_TYPE_MASTER) { - src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE; - ISP_DBG("%s: vfe %d Master\n", __func__, vfe_dev->pdev->id); - - src_info->dual_hw_ms_info.sof_info = - &vfe_dev->common_data->ms_resource.master_sof_info; - vfe_dev->common_data->ms_resource.sof_delta_threshold = - dual_hw_ms_cmd->sof_delta_threshold; - } else if (src_info != NULL) { - spin_lock_irqsave( - &vfe_dev->common_data->common_dev_data_lock, - flags); - src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE; - ISP_DBG("%s: vfe %d Slave\n", __func__, vfe_dev->pdev->id); - - for (j = 0; j < MS_NUM_SLAVE_MAX; j++) { - if (vfe_dev->common_data->ms_resource. - reserved_slave_mask & (1 << j)) - continue; - - vfe_dev->common_data->ms_resource.reserved_slave_mask |= - (1 << j); - vfe_dev->common_data->ms_resource.num_slave++; - src_info->dual_hw_ms_info.sof_info = - &vfe_dev->common_data->ms_resource. - slave_sof_info[j]; - src_info->dual_hw_ms_info.slave_id = j; - ISP_DBG("%s: Slave id %d\n", __func__, j); - break; - } - spin_unlock_irqrestore( - &vfe_dev->common_data->common_dev_data_lock, - flags); - - if (j == MS_NUM_SLAVE_MAX) { - pr_err("%s: Error! Cannot find free aux resource\n", - __func__); - return -EBUSY; + src_info->dual_hw_ms_info.index = dual_hw_ms_cmd-> + primary_intf + VFE_SRC_MAX * vfe_dev->pdev->id; + ms_res->src_info[src_info->dual_hw_ms_info.index] = src_info; + ms_res->num_src++; + if (dual_hw_ms_cmd->dual_hw_ms_type == MS_TYPE_MASTER) { + ms_res->master_index = src_info->dual_hw_ms_info.index; + ms_res->sof_delta_threshold = + dual_hw_ms_cmd->sof_delta_threshold; + } else { + ms_res->primary_slv_idx = + src_info->dual_hw_ms_info.index; } } ISP_DBG("%s: vfe %d num_src %d\n", __func__, vfe_dev->pdev->id, @@ -630,6 +636,8 @@ static int msm_isp_set_dual_HW_master_slave_mode( if (dual_hw_ms_cmd->input_src[i] >= VFE_SRC_MAX) { pr_err("%s: Error! Invalid SRC param %d\n", __func__, dual_hw_ms_cmd->input_src[i]); + spin_unlock_irqrestore(&vfe_dev->common_data-> + common_dev_data_lock, flags); return -EINVAL; } ISP_DBG("%s: vfe %d src %d type %d\n", __func__, @@ -640,8 +648,13 @@ static int msm_isp_set_dual_HW_master_slave_mode( src_info->dual_hw_type = DUAL_HW_MASTER_SLAVE; src_info->dual_hw_ms_info.dual_hw_ms_type = dual_hw_ms_cmd->dual_hw_ms_type; + src_info->dual_hw_ms_info.index = dual_hw_ms_cmd-> + input_src[i] + VFE_SRC_MAX * vfe_dev->pdev->id; + ms_res->src_info[src_info->dual_hw_ms_info.index] = src_info; + ms_res->num_src++; } - + spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock, + flags); return rc; } @@ -860,11 +873,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, break; case VIDIOC_MSM_ISP_AXI_RESET: mutex_lock(&vfe_dev->core_mutex); - /* For dual vfe reset both on vfe1 call */ - if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) { - mutex_unlock(&vfe_dev->core_mutex); - return 0; - } + MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev); if (atomic_read(&vfe_dev->error_info.overflow_state) != HALT_ENFORCED) { rc = msm_isp_stats_reset(vfe_dev); @@ -875,15 +884,12 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, pr_err_ratelimited("%s: no HW reset, halt enforced.\n", __func__); } + MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev); mutex_unlock(&vfe_dev->core_mutex); break; case VIDIOC_MSM_ISP_AXI_RESTART: mutex_lock(&vfe_dev->core_mutex); - /* For dual vfe restart both on vfe1 call */ - if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) { - mutex_unlock(&vfe_dev->core_mutex); - return 0; - } + MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev); if (atomic_read(&vfe_dev->error_info.overflow_state) != HALT_ENFORCED) { rc = msm_isp_stats_restart(vfe_dev); @@ -894,6 +900,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, pr_err_ratelimited("%s: no AXI restart, halt enforced.\n", __func__); } + MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev); mutex_unlock(&vfe_dev->core_mutex); break; case VIDIOC_MSM_ISP_INPUT_CFG: @@ -915,6 +922,11 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, rc = msm_isp_set_dual_HW_master_slave_mode(vfe_dev, arg); mutex_unlock(&vfe_dev->core_mutex); break; + case VIDIOC_MSM_ISP_DUAL_HW_MASTER_SLAVE_SYNC: + mutex_lock(&vfe_dev->core_mutex); + rc = msm_isp_dual_hw_master_slave_sync(vfe_dev, arg); + mutex_unlock(&vfe_dev->core_mutex); + break; case VIDIOC_MSM_ISP_FETCH_ENG_START: case VIDIOC_MSM_ISP_MAP_BUF_START_FE: mutex_lock(&vfe_dev->core_mutex); @@ -1773,7 +1785,7 @@ static inline void msm_isp_update_error_info(struct vfe_device *vfe_dev, vfe_dev->error_info.error_count++; } -static void msm_isp_process_overflow_irq( +static int msm_isp_process_overflow_irq( struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1) { @@ -1781,7 +1793,7 @@ static void msm_isp_process_overflow_irq( /* if there are no active streams - do not start recovery */ if (!vfe_dev->axi_data.num_active_stream) - return; + return 0; /*Mask out all other irqs if recovery is started*/ if (atomic_read(&vfe_dev->error_info.overflow_state) != NO_OVERFLOW) { @@ -1792,7 +1804,7 @@ static void msm_isp_process_overflow_irq( *irq_status0 &= halt_restart_mask0; *irq_status1 &= halt_restart_mask1; - return; + return 0; } /*Check if any overflow bit is set*/ @@ -1802,17 +1814,20 @@ static void msm_isp_process_overflow_irq( if (overflow_mask) { struct msm_isp_event_data error_event; - struct msm_vfe_axi_halt_cmd halt_cmd; uint32_t val = 0; int i; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + if (atomic_cmpxchg(&vfe_dev->error_info.overflow_state, + NO_OVERFLOW, OVERFLOW_DETECTED != NO_OVERFLOW)) + return 0; + if (vfe_dev->reset_pending == 1) { pr_err("%s:%d failed: overflow %x during reset\n", __func__, __LINE__, overflow_mask); /* Clear overflow bits since reset is pending */ *irq_status1 &= ~overflow_mask; - return; + return 0; } if (msm_vfe_is_vfe48(vfe_dev)) val = msm_camera_io_r(vfe_dev->vfe_base + 0xC94); @@ -1825,13 +1840,25 @@ static void msm_isp_process_overflow_irq( __func__, i, axi_data->free_wm[i]); } - halt_cmd.overflow_detected = 1; - halt_cmd.stop_camif = 1; - halt_cmd.blocking_halt = 0; - - msm_isp_axi_halt(vfe_dev, &halt_cmd); + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev); + /* mask off other vfe if dual vfe is used */ + if (vfe_dev->is_split) { + int other_vfe_id; + struct vfe_device *temp_vfe; + + other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0) ? + ISP_VFE1 : ISP_VFE0; + temp_vfe = vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]; + + atomic_set(&temp_vfe->error_info.overflow_state, + OVERFLOW_DETECTED); + temp_vfe->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(temp_vfe); + } - /*Update overflow state*/ + /* reset irq status so skip further process */ *irq_status0 = 0; *irq_status1 = 0; @@ -1845,7 +1872,9 @@ static void msm_isp_process_overflow_irq( msm_isp_send_event(vfe_dev, ISP_EVENT_ERROR, &error_event); } + return 1; } + return 0; } void msm_isp_reset_burst_count_and_frame_drop( @@ -1901,8 +1930,12 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data) return IRQ_HANDLED; } - msm_isp_process_overflow_irq(vfe_dev, - &irq_status0, &irq_status1); + if (msm_isp_process_overflow_irq(vfe_dev, + &irq_status0, &irq_status1)) { + /* if overflow initiated no need to handle the interrupts */ + pr_err("overflow processed\n"); + return IRQ_HANDLED; + } vfe_dev->hw_info->vfe_ops.core_ops. get_error_mask(&error_mask0, &error_mask1); @@ -2203,6 +2236,7 @@ void msm_isp_flush_tasklet(struct vfe_device *vfe_dev) queue_cmd->cmd_used = 0; } spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); + tasklet_kill(&vfe_dev->vfe_tasklet); return; } diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index f113bdc5de01..12d5d7eeb368 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -777,10 +777,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd, enum cci_i2c_queue_t queue = QUEUE_1; struct cci_device *cci_dev = NULL; struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL; + CDBG("%s line %d\n", __func__, __LINE__); cci_dev = v4l2_get_subdevdata(sd); master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; + + if (master >= MASTER_MAX || master < 0) { + pr_err("%s:%d Invalid I2C master %d\n", + __func__, __LINE__, master); + return -EINVAL; + } + mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* Set the I2C Frequency */ @@ -1005,11 +1013,6 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd, enum cci_i2c_master_t master; cci_dev = v4l2_get_subdevdata(sd); - if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX - || c_ctrl->cci_info->cci_i2c_master < 0) { - pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__); - return -EINVAL; - } if (cci_dev->cci_state != CCI_STATE_ENABLED) { pr_err("%s invalid cci state %d\n", __func__, cci_dev->cci_state); @@ -1547,6 +1550,11 @@ static int32_t msm_cci_write(struct v4l2_subdev *sd, return rc; } + if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX + || c_ctrl->cci_info->cci_i2c_master < 0) { + pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__); + return -EINVAL; + } master = c_ctrl->cci_info->cci_i2c_master; cci_master_info = &cci_dev->cci_master_info[master]; diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c index 8d7946db838a..e60947ecad21 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c +++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c @@ -619,6 +619,7 @@ static int msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl, struct msm_eeprom_cfg_data *cdata = (struct msm_eeprom_cfg_data *)argp; int rc = 0; + size_t length = 0; CDBG("%s E\n", __func__); switch (cdata->cfgtype) { @@ -631,9 +632,15 @@ static int msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl, } CDBG("%s E CFG_EEPROM_GET_INFO\n", __func__); cdata->is_supported = e_ctrl->is_supported; + length = strlen(e_ctrl->eboard_info->eeprom_name) + 1; + if (length > MAX_EEPROM_NAME) { + pr_err("%s:%d invalid eeprom_name length %d\n", + __func__, __LINE__, (int)length); + rc = -EINVAL; + break; + } memcpy(cdata->cfg.eeprom_name, - e_ctrl->eboard_info->eeprom_name, - sizeof(cdata->cfg.eeprom_name)); + e_ctrl->eboard_info->eeprom_name, length); break; case CFG_EEPROM_GET_CAL_DATA: CDBG("%s E CFG_EEPROM_GET_CAL_DATA\n", __func__); @@ -1400,6 +1407,16 @@ static int eeprom_init_config32(struct msm_eeprom_ctrl_t *e_ctrl, power_info = &(e_ctrl->eboard_info->power_info); + if ((power_setting_array32->size > MAX_POWER_CONFIG) || + (power_setting_array32->size_down > MAX_POWER_CONFIG) || + (!power_setting_array32->size) || + (!power_setting_array32->size_down)) { + pr_err("%s:%d invalid power setting size=%d size_down=%d\n", + __func__, __LINE__, power_setting_array32->size, + power_setting_array32->size_down); + rc = -EINVAL; + goto free_mem; + } msm_eeprom_copy_power_settings_compat( power_setting_array, power_setting_array32); @@ -1414,20 +1431,6 @@ static int eeprom_init_config32(struct msm_eeprom_ctrl_t *e_ctrl, power_info->power_down_setting_size = power_setting_array->size_down; - if ((power_info->power_setting_size > - MAX_POWER_CONFIG) || - (power_info->power_down_setting_size > - MAX_POWER_CONFIG) || - (!power_info->power_down_setting_size) || - (!power_info->power_setting_size)) { - rc = -EINVAL; - pr_err("%s:%d Invalid power setting size :%d, %d\n", - __func__, __LINE__, - power_info->power_setting_size, - power_info->power_down_setting_size); - goto free_mem; - } - if (e_ctrl->i2c_client.cci_client) { e_ctrl->i2c_client.cci_client->i2c_freq_mode = cdata32->cfg.eeprom_info.i2c_freq_mode; @@ -1477,6 +1480,7 @@ static int msm_eeprom_config32(struct msm_eeprom_ctrl_t *e_ctrl, struct msm_eeprom_cfg_data32 *cdata = (struct msm_eeprom_cfg_data32 *)argp; int rc = 0; + size_t length = 0; CDBG("%s E\n", __func__); switch (cdata->cfgtype) { @@ -1489,9 +1493,15 @@ static int msm_eeprom_config32(struct msm_eeprom_ctrl_t *e_ctrl, } CDBG("%s E CFG_EEPROM_GET_INFO\n", __func__); cdata->is_supported = e_ctrl->is_supported; + length = strlen(e_ctrl->eboard_info->eeprom_name) + 1; + if (length > MAX_EEPROM_NAME) { + pr_err("%s:%d invalid eeprom_name length %d\n", + __func__, __LINE__, (int)length); + rc = -EINVAL; + break; + } memcpy(cdata->cfg.eeprom_name, - e_ctrl->eboard_info->eeprom_name, - sizeof(cdata->cfg.eeprom_name)); + e_ctrl->eboard_info->eeprom_name, length); break; case CFG_EEPROM_GET_CAL_DATA: CDBG("%s E CFG_EEPROM_GET_CAL_DATA\n", __func__); diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c index 0d27de5c9b4b..800b2932854d 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c @@ -269,6 +269,16 @@ static int32_t msm_flash_i2c_init( flash_ctrl->power_info.power_down_setting_size = flash_ctrl->power_setting_array.size_down; + if ((flash_ctrl->power_info.power_setting_size > MAX_POWER_CONFIG) || + (flash_ctrl->power_info.power_down_setting_size > MAX_POWER_CONFIG)) { + pr_err("%s:%d invalid power setting size=%d size_down=%d\n", + __func__, __LINE__, + flash_ctrl->power_info.power_setting_size, + flash_ctrl->power_info.power_down_setting_size); + rc = -EINVAL; + goto msm_flash_i2c_init_fail; + } + rc = msm_camera_power_up(&flash_ctrl->power_info, flash_ctrl->flash_device_type, &flash_ctrl->flash_i2c_client); diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 7bc1fe1af26d..ac5f83f1d034 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -685,7 +685,11 @@ int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b) { struct msm_vidc_inst *inst = instance; - if (!inst || !b || !valid_v4l2_buffer(b, inst)) + if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) + return -EINVAL; + + if (inst->state == MSM_VIDC_CORE_INVALID || + inst->core->state == VIDC_CORE_INVALID) return -EINVAL; if (is_dynamic_output_buffer_mode(b, inst)) @@ -807,7 +811,11 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b) int rc = 0; int i; - if (!inst || !b || !valid_v4l2_buffer(b, inst)) + if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) + return -EINVAL; + + if (inst->state == MSM_VIDC_CORE_INVALID || + inst->core->state == VIDC_CORE_INVALID) return -EINVAL; rc = map_and_register_buf(inst, b); diff --git a/drivers/media/platform/msm/vidc/vmem/vmem.c b/drivers/media/platform/msm/vidc/vmem/vmem.c index e86740fdc5ac..0809256a2896 100644 --- a/drivers/media/platform/msm/vidc/vmem/vmem.c +++ b/drivers/media/platform/msm/vidc/vmem/vmem.c @@ -328,7 +328,7 @@ int vmem_allocate(size_t size, phys_addr_t *addr) goto exit; } if (!size) { - pr_err("%s Invalid size %ld\n", __func__, size); + pr_err("%s Invalid size %zu\n", __func__, size); rc = -EINVAL; goto exit; } diff --git a/drivers/phy/phy-qcom-ufs-qmp-v3.h b/drivers/phy/phy-qcom-ufs-qmp-v3.h index d5e49c281278..757ed7464e44 100644 --- a/drivers/phy/phy-qcom-ufs-qmp-v3.h +++ b/drivers/phy/phy-qcom-ufs-qmp-v3.h @@ -141,6 +141,7 @@ #define UFS_PHY_TX_SMALL_AMP_DRV_LVL PHY_OFF(0x34) #define UFS_PHY_LINECFG_DISABLE PHY_OFF(0x130) #define UFS_PHY_RX_SYM_RESYNC_CTRL PHY_OFF(0x134) +#define UFS_PHY_RX_MIN_HIBERN8_TIME PHY_OFF(0x138) #define UFS_PHY_RX_SIGDET_CTRL1 PHY_OFF(0x13C) #define UFS_PHY_RX_SIGDET_CTRL2 PHY_OFF(0x140) #define UFS_PHY_RX_PWM_GEAR_BAND PHY_OFF(0x14C) @@ -264,6 +265,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_0_0[] = { UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_LARGE_AMP_DRV_LVL, 0x0A), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_SMALL_AMP_DRV_LVL, 0x02), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SYM_RESYNC_CTRL, 0x03), + UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_HIBERN8_TIME, 0x9A), /* 8 us */ }; static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_1_0[] = { @@ -343,6 +345,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A_3_1_0[] = { UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SYM_RESYNC_CTRL, 0x03), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_MID_TERM_CTRL1, 0x43), UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SIGDET_CTRL1, 0x0F), + UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_HIBERN8_TIME, 0x9A), /* 8 us */ }; static struct ufs_qcom_phy_calibration phy_cal_table_rate_B[] = { diff --git a/drivers/regulator/cpr4-apss-regulator.c b/drivers/regulator/cpr4-apss-regulator.c index 5fd6d0ba1824..737511e250f1 100644 --- a/drivers/regulator/cpr4-apss-regulator.c +++ b/drivers/regulator/cpr4-apss-regulator.c @@ -35,10 +35,10 @@ #include "cpr3-regulator.h" -#define MSMTITANIUM_APSS_FUSE_CORNERS 4 +#define MSM8953_APSS_FUSE_CORNERS 4 /** - * struct cpr4_msmtitanium_apss_fuses - APSS specific fuse data for MSMTITANIUM + * struct cpr4_msm8953_apss_fuses - APSS specific fuse data for MSM8953 * @ro_sel: Ring oscillator select fuse parameter value for each * fuse corner * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value @@ -57,11 +57,11 @@ * * This struct holds the values for all of the fuses read from memory. */ -struct cpr4_msmtitanium_apss_fuses { - u64 ro_sel[MSMTITANIUM_APSS_FUSE_CORNERS]; - u64 init_voltage[MSMTITANIUM_APSS_FUSE_CORNERS]; - u64 target_quot[MSMTITANIUM_APSS_FUSE_CORNERS]; - u64 quot_offset[MSMTITANIUM_APSS_FUSE_CORNERS]; +struct cpr4_msm8953_apss_fuses { + u64 ro_sel[MSM8953_APSS_FUSE_CORNERS]; + u64 init_voltage[MSM8953_APSS_FUSE_CORNERS]; + u64 target_quot[MSM8953_APSS_FUSE_CORNERS]; + u64 quot_offset[MSM8953_APSS_FUSE_CORNERS]; u64 speed_bin; u64 cpr_fusing_rev; u64 boost_cfg; @@ -73,27 +73,27 @@ struct cpr4_msmtitanium_apss_fuses { * fuse combo = fusing revision + 8 * (speed bin) * where: fusing revision = 0 - 7 and speed bin = 0 - 7 */ -#define CPR4_MSMTITANIUM_APSS_FUSE_COMBO_COUNT 64 +#define CPR4_MSM8953_APSS_FUSE_COMBO_COUNT 64 /* * Constants which define the name of each fuse corner. */ -enum cpr4_msmtitanium_apss_fuse_corner { - CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS = 0, - CPR4_MSMTITANIUM_APSS_FUSE_CORNER_SVS = 1, - CPR4_MSMTITANIUM_APSS_FUSE_CORNER_NOM = 2, - CPR4_MSMTITANIUM_APSS_FUSE_CORNER_TURBO_L1 = 3, +enum cpr4_msm8953_apss_fuse_corner { + CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS = 0, + CPR4_MSM8953_APSS_FUSE_CORNER_SVS = 1, + CPR4_MSM8953_APSS_FUSE_CORNER_NOM = 2, + CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1 = 3, }; -static const char * const cpr4_msmtitanium_apss_fuse_corner_name[] = { - [CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS] = "LowSVS", - [CPR4_MSMTITANIUM_APSS_FUSE_CORNER_SVS] = "SVS", - [CPR4_MSMTITANIUM_APSS_FUSE_CORNER_NOM] = "NOM", - [CPR4_MSMTITANIUM_APSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", +static const char * const cpr4_msm8953_apss_fuse_corner_name[] = { + [CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS] = "LowSVS", + [CPR4_MSM8953_APSS_FUSE_CORNER_SVS] = "SVS", + [CPR4_MSM8953_APSS_FUSE_CORNER_NOM] = "NOM", + [CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", }; /* - * MSMTITANIUM APSS fuse parameter locations: + * MSM8953 APSS fuse parameter locations: * * Structs are organized with the following dimensions: * Outer: 0 to 3 for fuse corners from lowest to highest corner @@ -105,7 +105,7 @@ static const char * const cpr4_msmtitanium_apss_fuse_corner_name[] = { * a given parameter may correspond to different fuse rows. */ static const struct cpr3_fuse_param -msmtitanium_apss_ro_sel_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { +msm8953_apss_ro_sel_param[MSM8953_APSS_FUSE_CORNERS][2] = { {{73, 12, 15}, {} }, {{73, 8, 11}, {} }, {{73, 4, 7}, {} }, @@ -113,7 +113,7 @@ msmtitanium_apss_ro_sel_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmtitanium_apss_init_voltage_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { +msm8953_apss_init_voltage_param[MSM8953_APSS_FUSE_CORNERS][2] = { {{71, 24, 29}, {} }, {{71, 18, 23}, {} }, {{71, 12, 17}, {} }, @@ -121,7 +121,7 @@ msmtitanium_apss_init_voltage_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmtitanium_apss_target_quot_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { +msm8953_apss_target_quot_param[MSM8953_APSS_FUSE_CORNERS][2] = { {{72, 44, 55}, {} }, {{72, 32, 43}, {} }, {{72, 20, 31}, {} }, @@ -129,34 +129,34 @@ msmtitanium_apss_target_quot_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param -msmtitanium_apss_quot_offset_param[MSMTITANIUM_APSS_FUSE_CORNERS][2] = { +msm8953_apss_quot_offset_param[MSM8953_APSS_FUSE_CORNERS][2] = { {{} }, {{71, 46, 52}, {} }, {{71, 39, 45}, {} }, {{71, 32, 38}, {} }, }; -static const struct cpr3_fuse_param msmtitanium_cpr_fusing_rev_param[] = { +static const struct cpr3_fuse_param msm8953_cpr_fusing_rev_param[] = { {71, 53, 55}, {}, }; -static const struct cpr3_fuse_param msmtitanium_apss_speed_bin_param[] = { +static const struct cpr3_fuse_param msm8953_apss_speed_bin_param[] = { {36, 40, 42}, {}, }; -static const struct cpr3_fuse_param msmtitanium_cpr_boost_fuse_cfg_param[] = { +static const struct cpr3_fuse_param msm8953_cpr_boost_fuse_cfg_param[] = { {36, 43, 45}, {}, }; -static const struct cpr3_fuse_param msmtitanium_apss_boost_fuse_volt_param[] = { +static const struct cpr3_fuse_param msm8953_apss_boost_fuse_volt_param[] = { {71, 0, 5}, {}, }; -static const struct cpr3_fuse_param msmtitanium_misc_fuse_volt_adj_param[] = { +static const struct cpr3_fuse_param msm8953_misc_fuse_volt_adj_param[] = { {36, 54, 54}, {}, }; @@ -165,40 +165,40 @@ static const struct cpr3_fuse_param msmtitanium_misc_fuse_volt_adj_param[] = { * The number of possible values for misc fuse is * 2^(#bits defined for misc fuse) */ -#define MSMTITANIUM_MISC_FUSE_VAL_COUNT BIT(1) +#define MSM8953_MISC_FUSE_VAL_COUNT BIT(1) /* - * Open loop voltage fuse reference voltages in microvolts for MSMTITANIUM + * Open loop voltage fuse reference voltages in microvolts for MSM8953 */ -static const int msmtitanium_apss_fuse_ref_volt - [MSMTITANIUM_APSS_FUSE_CORNERS] = { +static const int msm8953_apss_fuse_ref_volt + [MSM8953_APSS_FUSE_CORNERS] = { 645000, 720000, 865000, 1065000, }; -#define MSMTITANIUM_APSS_FUSE_STEP_VOLT 10000 -#define MSMTITANIUM_APSS_VOLTAGE_FUSE_SIZE 6 -#define MSMTITANIUM_APSS_QUOT_OFFSET_SCALE 5 +#define MSM8953_APSS_FUSE_STEP_VOLT 10000 +#define MSM8953_APSS_VOLTAGE_FUSE_SIZE 6 +#define MSM8953_APSS_QUOT_OFFSET_SCALE 5 -#define MSMTITANIUM_APSS_CPR_SENSOR_COUNT 13 +#define MSM8953_APSS_CPR_SENSOR_COUNT 13 -#define MSMTITANIUM_APSS_CPR_CLOCK_RATE 19200000 +#define MSM8953_APSS_CPR_CLOCK_RATE 19200000 -#define MSMTITANIUM_APSS_MAX_TEMP_POINTS 3 -#define MSMTITANIUM_APSS_TEMP_SENSOR_ID_START 4 -#define MSMTITANIUM_APSS_TEMP_SENSOR_ID_END 13 +#define MSM8953_APSS_MAX_TEMP_POINTS 3 +#define MSM8953_APSS_TEMP_SENSOR_ID_START 4 +#define MSM8953_APSS_TEMP_SENSOR_ID_END 13 /* * Boost voltage fuse reference and ceiling voltages in microvolts for - * MSMTITANIUM. + * MSM8953. */ -#define MSMTITANIUM_APSS_BOOST_FUSE_REF_VOLT 1140000 -#define MSMTITANIUM_APSS_BOOST_CEILING_VOLT 1140000 -#define MSMTITANIUM_APSS_BOOST_FLOOR_VOLT 900000 +#define MSM8953_APSS_BOOST_FUSE_REF_VOLT 1140000 +#define MSM8953_APSS_BOOST_CEILING_VOLT 1140000 +#define MSM8953_APSS_BOOST_FLOOR_VOLT 900000 #define MAX_BOOST_CONFIG_FUSE_VALUE 8 -#define MSMTITANIUM_APSS_CPR_SDELTA_CORE_COUNT 15 +#define MSM8953_APSS_CPR_SDELTA_CORE_COUNT 15 /* * Array of integer values mapped to each of the boost config fuse values to @@ -207,26 +207,26 @@ static const int msmtitanium_apss_fuse_ref_volt static bool boost_fuse[MAX_BOOST_CONFIG_FUSE_VALUE] = {0, 1, 1, 1, 1, 1, 1, 1}; /** - * cpr4_msmtitanium_apss_read_fuse_data() - load APSS specific fuse parameter values + * cpr4_msm8953_apss_read_fuse_data() - load APSS specific fuse parameter values * @vreg: Pointer to the CPR3 regulator * - * This function allocates a cpr4_msmtitanium_apss_fuses struct, fills it with + * This function allocates a cpr4_msm8953_apss_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 cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) +static int cpr4_msm8953_apss_read_fuse_data(struct cpr3_regulator *vreg) { void __iomem *base = vreg->thread->ctrl->fuse_base; - struct cpr4_msmtitanium_apss_fuses *fuse; + struct cpr4_msm8953_apss_fuses *fuse; int i, rc; fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); if (!fuse) return -ENOMEM; - rc = cpr3_read_fuse_param(base, msmtitanium_apss_speed_bin_param, + rc = cpr3_read_fuse_param(base, msm8953_apss_speed_bin_param, &fuse->speed_bin); if (rc) { cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc); @@ -234,7 +234,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin); - rc = cpr3_read_fuse_param(base, msmtitanium_cpr_fusing_rev_param, + rc = cpr3_read_fuse_param(base, msm8953_cpr_fusing_rev_param, &fuse->cpr_fusing_rev); if (rc) { cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n", @@ -243,7 +243,7 @@ static int cpr4_msmtitanium_apss_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, msmtitanium_misc_fuse_volt_adj_param, + rc = cpr3_read_fuse_param(base, msm8953_misc_fuse_volt_adj_param, &fuse->misc); if (rc) { cpr3_err(vreg, "Unable to read misc voltage adjustment fuse, rc=%d\n", @@ -251,15 +251,15 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) return rc; } cpr3_info(vreg, "CPR misc fuse value = %llu\n", fuse->misc); - if (fuse->misc >= MSMTITANIUM_MISC_FUSE_VAL_COUNT) { + if (fuse->misc >= MSM8953_MISC_FUSE_VAL_COUNT) { cpr3_err(vreg, "CPR misc fuse value = %llu, should be < %lu\n", - fuse->misc, MSMTITANIUM_MISC_FUSE_VAL_COUNT); + fuse->misc, MSM8953_MISC_FUSE_VAL_COUNT); return -EINVAL; } - for (i = 0; i < MSMTITANIUM_APSS_FUSE_CORNERS; i++) { + for (i = 0; i < MSM8953_APSS_FUSE_CORNERS; i++) { rc = cpr3_read_fuse_param(base, - msmtitanium_apss_init_voltage_param[i], + msm8953_apss_init_voltage_param[i], &fuse->init_voltage[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n", @@ -268,7 +268,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmtitanium_apss_target_quot_param[i], + msm8953_apss_target_quot_param[i], &fuse->target_quot[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d target quotient fuse, rc=%d\n", @@ -277,7 +277,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmtitanium_apss_ro_sel_param[i], + msm8953_apss_ro_sel_param[i], &fuse->ro_sel[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d RO select fuse, rc=%d\n", @@ -286,7 +286,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msmtitanium_apss_quot_offset_param[i], + msm8953_apss_quot_offset_param[i], &fuse->quot_offset[i]); if (rc) { cpr3_err(vreg, "Unable to read fuse-corner %d quotient offset fuse, rc=%d\n", @@ -295,7 +295,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } } - rc = cpr3_read_fuse_param(base, msmtitanium_cpr_boost_fuse_cfg_param, + rc = cpr3_read_fuse_param(base, msm8953_cpr_boost_fuse_cfg_param, &fuse->boost_cfg); if (rc) { cpr3_err(vreg, "Unable to read CPR boost config fuse, rc=%d\n", @@ -307,7 +307,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) ? "enable" : "disable"); rc = cpr3_read_fuse_param(base, - msmtitanium_apss_boost_fuse_volt_param, + msm8953_apss_boost_fuse_volt_param, &fuse->boost_voltage); if (rc) { cpr3_err(vreg, "failed to read boost fuse voltage, rc=%d\n", @@ -316,7 +316,7 @@ static int cpr4_msmtitanium_apss_read_fuse_data(struct cpr3_regulator *vreg) } vreg->fuse_combo = fuse->cpr_fusing_rev + 8 * fuse->speed_bin; - if (vreg->fuse_combo >= CPR4_MSMTITANIUM_APSS_FUSE_COMBO_COUNT) { + if (vreg->fuse_combo >= CPR4_MSM8953_APSS_FUSE_COMBO_COUNT) { cpr3_err(vreg, "invalid CPR fuse combo = %d found\n", vreg->fuse_combo); return -EINVAL; @@ -324,7 +324,7 @@ static int cpr4_msmtitanium_apss_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 = MSMTITANIUM_APSS_FUSE_CORNERS; + vreg->fuse_corner_count = MSM8953_APSS_FUSE_CORNERS; vreg->platform_fuses = fuse; return 0; @@ -376,8 +376,8 @@ static int cpr4_apss_parse_misc_fuse_voltage_adjustments( struct cpr3_regulator *vreg, u32 *volt_adjust) { struct device_node *node = vreg->of_node; - struct cpr4_msmtitanium_apss_fuses *fuse = vreg->platform_fuses; - int tuple_list_size = MSMTITANIUM_MISC_FUSE_VAL_COUNT; + struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses; + int tuple_list_size = MSM8953_MISC_FUSE_VAL_COUNT; int i, offset, rc, len = 0; const char *prop_name = "qcom,cpr-misc-fuse-voltage-adjustment"; @@ -423,7 +423,7 @@ static int cpr4_apss_parse_misc_fuse_voltage_adjustments( } /** - * cpr4_msmtitanium_apss_calculate_open_loop_voltages() - calculate the open-loop + * cpr4_msm8953_apss_calculate_open_loop_voltages() - calculate the open-loop * voltage for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -439,11 +439,11 @@ static int cpr4_apss_parse_misc_fuse_voltage_adjustments( * * Return: 0 on success, errno on failure */ -static int cpr4_msmtitanium_apss_calculate_open_loop_voltages( +static int cpr4_msm8953_apss_calculate_open_loop_voltages( struct cpr3_regulator *vreg) { struct device_node *node = vreg->of_node; - struct cpr4_msmtitanium_apss_fuses *fuse = vreg->platform_fuses; + struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses; int i, j, rc = 0; bool allow_interpolation; u64 freq_low, volt_low, freq_high, volt_high; @@ -461,13 +461,13 @@ static int cpr4_msmtitanium_apss_calculate_open_loop_voltages( for (i = 0; i < vreg->fuse_corner_count; i++) { fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse( - msmtitanium_apss_fuse_ref_volt[i], - MSMTITANIUM_APSS_FUSE_STEP_VOLT, fuse->init_voltage[i], - MSMTITANIUM_APSS_VOLTAGE_FUSE_SIZE); + msm8953_apss_fuse_ref_volt[i], + MSM8953_APSS_FUSE_STEP_VOLT, fuse->init_voltage[i], + MSM8953_APSS_VOLTAGE_FUSE_SIZE); /* Log fused open-loop voltage values for debugging purposes. */ cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", - cpr4_msmtitanium_apss_fuse_corner_name[i], + cpr4_msm8953_apss_fuse_corner_name[i], fuse_volt[i]); } @@ -577,7 +577,7 @@ _exit: } /** - * cpr4_msmtitanium_apss_set_no_interpolation_quotients() - use the fused target + * cpr4_msm8953_apss_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 @@ -589,11 +589,11 @@ _exit: * * Return: 0 on success, errno on failure */ -static int cpr4_msmtitanium_apss_set_no_interpolation_quotients( +static int cpr4_msm8953_apss_set_no_interpolation_quotients( struct cpr3_regulator *vreg, int *volt_adjust, int *volt_adjust_fuse, int *ro_scale) { - struct cpr4_msmtitanium_apss_fuses *fuse = vreg->platform_fuses; + struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses; u32 quot, ro; int quot_adjust; int i, fuse_corner; @@ -620,7 +620,7 @@ static int cpr4_msmtitanium_apss_set_no_interpolation_quotients( } /** - * cpr4_msmtitanium_apss_calculate_target_quotients() - calculate the CPR target + * cpr4_msm8953_apss_calculate_target_quotients() - calculate the CPR target * quotient for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -636,10 +636,10 @@ static int cpr4_msmtitanium_apss_set_no_interpolation_quotients( * * Return: 0 on success, errno on failure */ -static int cpr4_msmtitanium_apss_calculate_target_quotients( +static int cpr4_msm8953_apss_calculate_target_quotients( struct cpr3_regulator *vreg) { - struct cpr4_msmtitanium_apss_fuses *fuse = vreg->platform_fuses; + struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses; int rc; bool allow_interpolation; u64 freq_low, freq_high, prev_quot; @@ -653,15 +653,15 @@ static int cpr4_msmtitanium_apss_calculate_target_quotients( /* Log fused quotient values for debugging purposes. */ cpr3_info(vreg, "fused LowSVS: quot[%2llu]=%4llu\n", - fuse->ro_sel[CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS], - fuse->target_quot[CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS]); - for (i = CPR4_MSMTITANIUM_APSS_FUSE_CORNER_SVS; - i <= CPR4_MSMTITANIUM_APSS_FUSE_CORNER_TURBO_L1; i++) + fuse->ro_sel[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS], + fuse->target_quot[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS]); + for (i = CPR4_MSM8953_APSS_FUSE_CORNER_SVS; + i <= CPR4_MSM8953_APSS_FUSE_CORNER_TURBO_L1; i++) cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu, quot_offset[%2llu]=%4llu\n", - cpr4_msmtitanium_apss_fuse_corner_name[i], + cpr4_msm8953_apss_fuse_corner_name[i], fuse->ro_sel[i], fuse->target_quot[i], fuse->ro_sel[i], fuse->quot_offset[i] * - MSMTITANIUM_APSS_QUOT_OFFSET_SCALE); + MSM8953_APSS_QUOT_OFFSET_SCALE); allow_interpolation = of_property_read_bool(vreg->of_node, "qcom,allow-quotient-interpolation"); @@ -718,7 +718,7 @@ static int cpr4_msmtitanium_apss_calculate_target_quotients( if (!allow_interpolation) { /* Use fused target quotients for lower frequencies. */ - return cpr4_msmtitanium_apss_set_no_interpolation_quotients( + return cpr4_msm8953_apss_set_no_interpolation_quotients( vreg, volt_adjust, volt_adjust_fuse, ro_scale); } @@ -740,7 +740,7 @@ static int cpr4_msmtitanium_apss_calculate_target_quotients( * Interpolation is not possible for corners mapped to the lowest fuse * corner so use the fuse corner value directly. */ - i = CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS; + i = CPR4_MSM8953_APSS_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; @@ -749,11 +749,11 @@ static int cpr4_msmtitanium_apss_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[CPR4_MSMTITANIUM_APSS_FUSE_CORNER_LOWSVS]; + for (i = 0; i <= fmax_corner[CPR4_MSM8953_APSS_FUSE_CORNER_LOWSVS]; i++) vreg->corner[i].target_quot[ro] = quot; - for (i = CPR4_MSMTITANIUM_APSS_FUSE_CORNER_SVS; + for (i = CPR4_MSM8953_APSS_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]) @@ -761,7 +761,7 @@ static int cpr4_msmtitanium_apss_calculate_target_quotients( else quot_low[i] = quot_high[i] - fuse->quot_offset[i] - * MSMTITANIUM_APSS_QUOT_OFFSET_SCALE; + * MSM8953_APSS_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], @@ -919,9 +919,9 @@ static int cpr4_apss_parse_temp_adj_properties(struct cpr3_controller *ctrl) temp_point_count = len / sizeof(u32); if (temp_point_count <= 0 - || temp_point_count > MSMTITANIUM_APSS_MAX_TEMP_POINTS) { + || temp_point_count > MSM8953_APSS_MAX_TEMP_POINTS) { cpr3_err(ctrl, "invalid number of temperature points %d > %d (max)\n", - temp_point_count, MSMTITANIUM_APSS_MAX_TEMP_POINTS); + temp_point_count, MSM8953_APSS_MAX_TEMP_POINTS); return -EINVAL; } @@ -963,8 +963,8 @@ static int cpr4_apss_parse_temp_adj_properties(struct cpr3_controller *ctrl) return -EINVAL; } - ctrl->temp_sensor_id_start = MSMTITANIUM_APSS_TEMP_SENSOR_ID_START; - ctrl->temp_sensor_id_end = MSMTITANIUM_APSS_TEMP_SENSOR_ID_END; + ctrl->temp_sensor_id_start = MSM8953_APSS_TEMP_SENSOR_ID_START; + ctrl->temp_sensor_id_end = MSM8953_APSS_TEMP_SENSOR_ID_END; ctrl->allow_temp_adj = true; return rc; } @@ -979,7 +979,7 @@ static int cpr4_apss_parse_temp_adj_properties(struct cpr3_controller *ctrl) static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) { struct cpr3_controller *ctrl = vreg->thread->ctrl; - struct cpr4_msmtitanium_apss_fuses *fuse = vreg->platform_fuses; + struct cpr4_msm8953_apss_fuses *fuse = vreg->platform_fuses; struct cpr3_corner *corner; int i, boost_voltage, final_boost_volt, rc = 0; int *boost_table = NULL, *boost_temp_adj = NULL; @@ -1003,10 +1003,10 @@ static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) } boost_voltage = cpr3_convert_open_loop_voltage_fuse( - MSMTITANIUM_APSS_BOOST_FUSE_REF_VOLT, - MSMTITANIUM_APSS_FUSE_STEP_VOLT, + MSM8953_APSS_BOOST_FUSE_REF_VOLT, + MSM8953_APSS_FUSE_STEP_VOLT, fuse->boost_voltage, - MSMTITANIUM_APSS_VOLTAGE_FUSE_SIZE); + MSM8953_APSS_VOLTAGE_FUSE_SIZE); /* Log boost voltage value for debugging purposes. */ cpr3_info(vreg, "Boost open-loop=%7d uV\n", boost_voltage); @@ -1029,8 +1029,8 @@ static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) } /* Limit boost voltage value between ceiling and floor voltage limits */ - boost_voltage = min(boost_voltage, MSMTITANIUM_APSS_BOOST_CEILING_VOLT); - boost_voltage = max(boost_voltage, MSMTITANIUM_APSS_BOOST_FLOOR_VOLT); + boost_voltage = min(boost_voltage, MSM8953_APSS_BOOST_CEILING_VOLT); + boost_voltage = max(boost_voltage, MSM8953_APSS_BOOST_FLOOR_VOLT); /* * The boost feature can only be used for the highest voltage corner. @@ -1060,7 +1060,7 @@ static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) } if (boost_num_cores <= 0 - || boost_num_cores > MSMTITANIUM_APSS_CPR_SDELTA_CORE_COUNT) { + || boost_num_cores > MSM8953_APSS_CPR_SDELTA_CORE_COUNT) { cpr3_err(vreg, "Invalid boost number of cores = %d\n", boost_num_cores); return -EINVAL; @@ -1099,9 +1099,9 @@ static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) * and floor voltage limits */ final_boost_volt = min(final_boost_volt, - MSMTITANIUM_APSS_BOOST_CEILING_VOLT); + MSM8953_APSS_BOOST_CEILING_VOLT); final_boost_volt = max(final_boost_volt, - MSMTITANIUM_APSS_BOOST_FLOOR_VOLT); + MSM8953_APSS_BOOST_FLOOR_VOLT); boost_table[i] = (corner->open_loop_volt - final_boost_volt) / ctrl->step_volt; @@ -1109,7 +1109,7 @@ static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg) i, boost_table[i]); } - corner->ceiling_volt = MSMTITANIUM_APSS_BOOST_CEILING_VOLT; + corner->ceiling_volt = MSM8953_APSS_BOOST_CEILING_VOLT; corner->sdelta->boost_table = boost_table; corner->sdelta->allow_boost = true; corner->sdelta->allow_core_count_adj = false; @@ -1129,10 +1129,10 @@ done: */ static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg) { - struct cpr4_msmtitanium_apss_fuses *fuse; + struct cpr4_msm8953_apss_fuses *fuse; int rc; - rc = cpr4_msmtitanium_apss_read_fuse_data(vreg); + rc = cpr4_msm8953_apss_read_fuse_data(vreg); if (rc) { cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc); return rc; @@ -1155,7 +1155,7 @@ static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cpr4_msmtitanium_apss_calculate_open_loop_voltages(vreg); + rc = cpr4_msm8953_apss_calculate_open_loop_voltages(vreg); if (rc) { cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n", rc); @@ -1177,7 +1177,7 @@ static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cpr4_msmtitanium_apss_calculate_target_quotients(vreg); + rc = cpr4_msm8953_apss_calculate_target_quotients(vreg); if (rc) { cpr3_err(vreg, "unable to calculate target quotients, rc=%d\n", rc); @@ -1193,7 +1193,7 @@ static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg) if (vreg->allow_core_count_adj && (vreg->max_core_count <= 0 || vreg->max_core_count > - MSMTITANIUM_APSS_CPR_SDELTA_CORE_COUNT)) { + MSM8953_APSS_CPR_SDELTA_CORE_COUNT)) { cpr3_err(vreg, "qcom,max-core-count has invalid value = %d\n", vreg->max_core_count); return -EINVAL; @@ -1287,7 +1287,7 @@ static int cpr4_apss_init_controller(struct cpr3_controller *ctrl) return rc; } - ctrl->sensor_count = MSMTITANIUM_APSS_CPR_SENSOR_COUNT; + ctrl->sensor_count = MSM8953_APSS_CPR_SENSOR_COUNT; /* * APSS only has one thread (0) per controller so the zeroed @@ -1298,7 +1298,7 @@ static int cpr4_apss_init_controller(struct cpr3_controller *ctrl) if (!ctrl->sensor_owner) return -ENOMEM; - ctrl->cpr_clock_rate = MSMTITANIUM_APSS_CPR_CLOCK_RATE; + ctrl->cpr_clock_rate = MSM8953_APSS_CPR_CLOCK_RATE; ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4; ctrl->supports_hw_closed_loop = true; ctrl->use_hw_closed_loop = of_property_read_bool(ctrl->dev->of_node, @@ -1403,7 +1403,7 @@ static int cpr4_apss_regulator_remove(struct platform_device *pdev) } static struct of_device_id cpr4_regulator_match_table[] = { - { .compatible = "qcom,cpr4-msmtitanium-apss-regulator", }, + { .compatible = "qcom,cpr4-msm8953-apss-regulator", }, {} }; diff --git a/drivers/regulator/msm_gfx_ldo.c b/drivers/regulator/msm_gfx_ldo.c index fe139cc0108b..3c0cc9a74cd7 100644 --- a/drivers/regulator/msm_gfx_ldo.c +++ b/drivers/regulator/msm_gfx_ldo.c @@ -45,6 +45,7 @@ #define PWRSWITCH_CTRL_REG 0x1C #define LDO_CLAMP_IO_BIT BIT(31) #define CPR_BYPASS_IN_LDO_MODE_BIT BIT(30) +#define EN_LDOAP_CTRL_CPR_BIT BIT(29) #define PWR_SRC_SEL_BIT BIT(9) #define ACK_SW_OVR_BIT BIT(8) #define LDO_PREON_SW_OVR_BIT BIT(7) @@ -62,7 +63,7 @@ #define LDO_READY_BIT BIT(2) #define BHS_EN_REST_ACK_BIT BIT(1) -#define MIN_LDO_VOLTAGE 345000 +#define MIN_LDO_VOLTAGE 375000 #define MAX_LDO_VOLTAGE 980000 #define LDO_STEP_VOLATGE 5000 @@ -72,10 +73,8 @@ #define MAX_FUSE_ROW_BIT 63 #define MIN_CORNER_OFFSET 1 -#define GFX_LDO_FUSE_STEP_VOLT 10 +#define GFX_LDO_FUSE_STEP_VOLT 10000 #define GFX_LDO_FUSE_SIZE 5 -#define GFX_LDO_BYPASS_FUSE_MASK 0xF -#define GFX_LDO_BYPASS_FUSE_VALUE 0xF enum regulator_mode { LDO, @@ -115,12 +114,11 @@ struct msm_gfx_ldo { u32 *ldo_corner_en_map; u32 *vdd_cx_corner_map; u32 *mem_acc_corner_map; - u8 *force_ldo_bypass; const int *ref_volt; const struct fuse_param *ldo_enable_param; const struct fuse_param **init_volt_param; - bool ldo_enable; - bool ldo_bypass_fuse_enable; + bool ldo_fuse_enable; + bool ldo_mode_disable; struct ldo_config *ldo_init_config; void __iomem *efuse_base; @@ -135,9 +133,9 @@ struct msm_gfx_ldo { struct mutex ldo_mutex; }; -#define MSMTITANIUM_LDO_FUSE_CORNERS 3 +#define MSM8953_LDO_FUSE_CORNERS 3 #define LDO_MAX_OFFSET 0xFFFF -static struct ldo_config msmtitanium_ldo_config[] = { +static struct ldo_config msm8953_ldo_config[] = { {LDO_ATEST_REG, 0x00000203}, {LDO_CFG0_REG, 0x05008600}, {LDO_CFG1_REG, 0x0}, @@ -146,19 +144,19 @@ static struct ldo_config msmtitanium_ldo_config[] = { {LDO_MAX_OFFSET, LDO_MAX_OFFSET}, }; -static struct fuse_param msmtitanium_ldo_enable_param[] = { - {65, 10, 10}, +static struct fuse_param msm8953_ldo_enable_param[] = { + {65, 11, 11}, {}, }; static const struct fuse_param -msmtitanium_init_voltage_param[MSMTITANIUM_LDO_FUSE_CORNERS][2] = { +msm8953_init_voltage_param[MSM8953_LDO_FUSE_CORNERS][2] = { { {73, 42, 46}, {} }, { {73, 37, 41}, {} }, { {73, 32, 36}, {} }, }; -static const int msmtitanium_fuse_ref_volt[MSMTITANIUM_LDO_FUSE_CORNERS] = { +static const int msm8953_fuse_ref_volt[MSM8953_LDO_FUSE_CORNERS] = { 580000, 650000, 720000, @@ -214,9 +212,8 @@ static int read_fuse_param(void __iomem *fuse_base_addr, static enum regulator_mode get_operating_mode(struct msm_gfx_ldo *ldo_vreg, int corner) { - if (ldo_vreg->ldo_enable - && ldo_vreg->ldo_corner_en_map[corner] - && !ldo_vreg->force_ldo_bypass[corner]) + if (!ldo_vreg->ldo_mode_disable && ldo_vreg->ldo_fuse_enable + && ldo_vreg->ldo_corner_en_map[corner]) return LDO; return BHS; @@ -248,7 +245,7 @@ static void dump_registers(struct msm_gfx_ldo *ldo_vreg, char *func) } } -#define GET_VREF(a) (1 + DIV_ROUND_UP(a - MIN_LDO_VOLTAGE, LDO_STEP_VOLATGE)) +#define GET_VREF(a) DIV_ROUND_UP(a - MIN_LDO_VOLTAGE, LDO_STEP_VOLATGE) static void configure_ldo_voltage(struct msm_gfx_ldo *ldo_vreg, int new_corner) { @@ -322,23 +319,23 @@ static int enable_ldo_mode(struct msm_gfx_ldo *ldo_vreg) /* Move BHS under SW control */ ctl |= BHS_UNDER_SW_CTL; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* Set LDO under gdsc control */ ctl &= ~LDO_UNDER_SW_CTRL_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* enable hw_pre-on to gdsc */ ctl |= LDO_PREON_SW_OVR_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* remove LDO bypass */ ctl &= ~LDO_BYPASS_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* set power-source as LDO */ ctl |= PWR_SRC_SEL_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* clear fake-sw ack to gdsc */ ctl &= ~ACK_SW_OVR_BIT; @@ -346,7 +343,7 @@ static int enable_ldo_mode(struct msm_gfx_ldo *ldo_vreg) /* put CPR in bypass mode */ ctl |= CPR_BYPASS_IN_LDO_MODE_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* complete all writes */ mb(); @@ -401,6 +398,15 @@ static int msm_gfx_ldo_enable(struct regulator_dev *rdev) ldo_vreg->corner + MIN_CORNER_OFFSET); if (ldo_vreg->vdd_cx) { + rc = regulator_set_voltage(ldo_vreg->vdd_cx, + ldo_vreg->vdd_cx_corner_map[ldo_vreg->corner], + INT_MAX); + if (rc) { + pr_err("Unable to set CX for corner %d rc=%d\n", + ldo_vreg->corner + MIN_CORNER_OFFSET, rc); + goto fail; + } + rc = regulator_enable(ldo_vreg->vdd_cx); if (rc) { pr_err("regulator_enable: vdd_cx: failed rc=%d\n", rc); @@ -538,7 +544,7 @@ static int switch_mode_to_ldo(struct msm_gfx_ldo *ldo_vreg, int new_corner) /* remove LDO bypass */ ctl &= ~LDO_BYPASS_BIT; - writel_relaxed(ctl, ldo_vreg + PWRSWITCH_CTRL_REG); + writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); /* expose LDO to gdsc */ ctl &= ~ACK_SW_OVR_BIT; @@ -649,17 +655,6 @@ static int msm_gfx_ldo_set_voltage(struct regulator_dev *rdev, else if (corner < ldo_vreg->corner) dir = DOWN; - if (ldo_vreg->vdd_cx) { - rc = regulator_set_voltage(ldo_vreg->vdd_cx, - ldo_vreg->vdd_cx_corner_map[corner], - INT_MAX); - if (rc) { - pr_err("Unable to set CX for corner %d rc=%d\n", - corner + MIN_CORNER_OFFSET, rc); - goto done; - } - } - if (ldo_vreg->mem_acc_vreg && dir == DOWN) { mem_acc_corner = ldo_vreg->mem_acc_corner_map[corner]; rc = regulator_set_voltage(ldo_vreg->mem_acc_vreg, @@ -671,6 +666,17 @@ static int msm_gfx_ldo_set_voltage(struct regulator_dev *rdev, goto done; } + if (ldo_vreg->vdd_cx) { + rc = regulator_set_voltage(ldo_vreg->vdd_cx, + ldo_vreg->vdd_cx_corner_map[corner], + INT_MAX); + if (rc) { + pr_err("Unable to set CX for corner %d rc=%d\n", + corner + MIN_CORNER_OFFSET, rc); + goto done; + } + } + new_mode = get_operating_mode(ldo_vreg, corner); if (new_mode == BHS) { @@ -737,6 +743,46 @@ static struct regulator_ops msm_gfx_ldo_corner_ops = { .get_voltage = msm_gfx_ldo_get_voltage, }; +static int msm_gfx_ldo_adjust_init_voltage(struct msm_gfx_ldo *ldo_vreg) +{ + int rc, len, size, i; + u32 *volt_adjust; + struct device_node *of_node = ldo_vreg->dev->of_node; + char *prop_name = "qcom,ldo-init-voltage-adjustment"; + + if (!of_find_property(of_node, prop_name, &len)) { + /* No initial voltage adjustment needed. */ + return 0; + } + + size = len / sizeof(u32); + if (size != ldo_vreg->num_ldo_corners) { + pr_err("%s length=%d is invalid: required:%d\n", + prop_name, size, ldo_vreg->num_ldo_corners); + return -EINVAL; + } + + volt_adjust = devm_kcalloc(ldo_vreg->dev, size, sizeof(*volt_adjust), + GFP_KERNEL); + rc = of_property_read_u32_array(of_node, prop_name, volt_adjust, size); + if (rc) { + pr_err("failed to read %s property rc=%d\n", prop_name, rc); + return rc; + } + + for (i = 0; i < ldo_vreg->num_corners; i++) { + if (volt_adjust[i]) { + ldo_vreg->open_loop_volt[i] += volt_adjust[i]; + pr_info("adjusted the open-loop voltage[%d] %d -> %d\n", + i + MIN_CORNER_OFFSET, + ldo_vreg->open_loop_volt[i] - volt_adjust[i], + ldo_vreg->open_loop_volt[i]); + } + } + + return 0; +} + static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg) { struct device_node *of_node = ldo_vreg->dev->of_node; @@ -754,12 +800,9 @@ static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg) ldo_vreg->floor_volt = devm_kcalloc(ldo_vreg->dev, len, sizeof(*ldo_vreg->floor_volt), GFP_KERNEL); - ldo_vreg->force_ldo_bypass = devm_kcalloc(ldo_vreg->dev, - len, sizeof(*ldo_vreg->force_ldo_bypass), - GFP_KERNEL); if (!ldo_vreg->open_loop_volt || !ldo_vreg->ceiling_volt - || !ldo_vreg->floor_volt || !ldo_vreg->force_ldo_bypass) + || !ldo_vreg->floor_volt) return -ENOMEM; rc = of_property_read_u32_array(of_node, "qcom,ldo-voltage-ceiling", @@ -784,13 +827,6 @@ static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg) pr_err("Unable to read init-voltage rc=%d\n", rc); return rc; } - if (ldo_vreg->ldo_bypass_fuse_enable && - ((efuse_bits & GFX_LDO_BYPASS_FUSE_MASK) == - GFX_LDO_BYPASS_FUSE_VALUE)) { - ldo_vreg->force_ldo_bypass[i] = true; - pr_info("LDO corner %d in force-bypass\n", - i + MIN_CORNER_OFFSET); - } ldo_vreg->open_loop_volt[i] = convert_open_loop_voltage_fuse( ldo_vreg->ref_volt[i], GFX_LDO_FUSE_STEP_VOLT, @@ -800,6 +836,12 @@ static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg) i + MIN_CORNER_OFFSET, ldo_vreg->open_loop_volt[i]); } + rc = msm_gfx_ldo_adjust_init_voltage(ldo_vreg); + if (rc) { + pr_err("Unable to adjust init voltages rc=%d\n", rc); + return rc; + } + for (i = 0; i < ldo_vreg->num_ldo_corners; i++) { if (ldo_vreg->open_loop_volt[i] > ldo_vreg->ceiling_volt[i]) { pr_info("Warning: initial voltage[%d] %d above ceiling %d\n", @@ -824,8 +866,8 @@ static int msm_gfx_ldo_voltage_init(struct msm_gfx_ldo *ldo_vreg) pr_err("Unable to read ldo_enable_param rc=%d\n", rc); return rc; } - ldo_vreg->ldo_enable = !!efuse_bits; - pr_info("LDO mode %s by default\n", ldo_vreg->ldo_enable ? + ldo_vreg->ldo_fuse_enable = !!efuse_bits; + pr_info("LDO-mode fuse %s by default\n", ldo_vreg->ldo_fuse_enable ? "enabled" : "disabled"); return rc; @@ -935,9 +977,10 @@ static int msm_gfx_ldo_init(struct platform_device *pdev, /* HW initialization */ - /* clear clamp_io */ + /* clear clamp_io, enable CPR in auto-bypass*/ ctl = readl_relaxed(ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); ctl &= ~LDO_CLAMP_IO_BIT; + ctl |= EN_LDOAP_CTRL_CPR_BIT; writel_relaxed(ctl, ldo_vreg->ldo_base + PWRSWITCH_CTRL_REG); i = 0; @@ -1063,25 +1106,48 @@ static int msm_gfx_ldo_target_init(struct msm_gfx_ldo *ldo_vreg) { int i; - /* MSMTITANIUM */ + /* MSM8953 */ ldo_vreg->init_volt_param = devm_kzalloc(ldo_vreg->dev, - (MSMTITANIUM_LDO_FUSE_CORNERS * + (MSM8953_LDO_FUSE_CORNERS * sizeof(struct fuse_param *)), GFP_KERNEL); if (!ldo_vreg->init_volt_param) return -ENOMEM; - for (i = 0; i < MSMTITANIUM_LDO_FUSE_CORNERS; i++) + for (i = 0; i < MSM8953_LDO_FUSE_CORNERS; i++) ldo_vreg->init_volt_param[i] = - msmtitanium_init_voltage_param[i]; + msm8953_init_voltage_param[i]; + + ldo_vreg->ldo_init_config = msm8953_ldo_config; + ldo_vreg->ref_volt = msm8953_fuse_ref_volt; + ldo_vreg->ldo_enable_param = msm8953_ldo_enable_param; - ldo_vreg->ldo_init_config = msmtitanium_ldo_config; - ldo_vreg->ref_volt = msmtitanium_fuse_ref_volt; - ldo_vreg->ldo_enable_param = msmtitanium_ldo_enable_param; - ldo_vreg->ldo_bypass_fuse_enable = true; + return 0; +} + +static int debugfs_ldo_mode_disable_set(void *data, u64 val) +{ + struct msm_gfx_ldo *ldo_vreg = data; + + ldo_vreg->ldo_mode_disable = !!val; + + pr_debug("LDO-mode %s\n", ldo_vreg->ldo_mode_disable ? + "disabled" : "enabled"); return 0; } +static int debugfs_ldo_mode_disable_get(void *data, u64 *val) +{ + struct msm_gfx_ldo *ldo_vreg = data; + + *val = ldo_vreg->ldo_mode_disable; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(ldo_mode_disable_fops, debugfs_ldo_mode_disable_get, + debugfs_ldo_mode_disable_set, "%llu\n"); + static int debugfs_ldo_set_voltage(void *data, u64 val) { struct msm_gfx_ldo *ldo_vreg = data; @@ -1126,6 +1192,10 @@ static int debugfs_ldo_set_voltage(void *data, u64 val) pr_err("LDO_VREF_SETTLED not set PWRSWITCH_STATUS = 0x%x\n", reg); rc = -EBUSY; + } else { + ldo_vreg->ldo_voltage_uv = val; + pr_debug("LDO voltage set to %d uV\n", + ldo_vreg->ldo_voltage_uv); } done: mutex_unlock(&ldo_vreg->ldo_mutex); @@ -1135,7 +1205,7 @@ done: static int debugfs_ldo_get_voltage(void *data, u64 *val) { struct msm_gfx_ldo *ldo_vreg = data; - int rc = -EINVAL; + int rc = 0; u32 reg; mutex_lock(&ldo_vreg->ldo_mutex); @@ -1148,7 +1218,7 @@ static int debugfs_ldo_get_voltage(void *data, u64 *val) reg = readl_relaxed(ldo_vreg->ldo_base + LDO_VREF_SET_REG); reg &= VREF_VAL_MASK; - rc = (reg * LDO_STEP_VOLATGE) + MIN_LDO_VOLTAGE; + *val = (reg * LDO_STEP_VOLATGE) + MIN_LDO_VOLTAGE; done: mutex_unlock(&ldo_vreg->ldo_mutex); return rc; @@ -1229,6 +1299,13 @@ static void msm_gfx_ldo_debugfs_init(struct msm_gfx_ldo *ldo_vreg) pr_err("ldo_voltage node creation failed\n"); return; } + + temp = debugfs_create_file("ldo_mode_disable", S_IRUGO | S_IWUSR, + ldo_vreg->debugfs, ldo_vreg, &ldo_mode_disable_fops); + if (IS_ERR_OR_NULL(temp)) { + pr_err("ldo_mode_disable node creation failed\n"); + return; + } } static void msm_gfx_ldo_debugfs_remove(struct msm_gfx_ldo *ldo_vreg) @@ -1332,7 +1409,7 @@ static int msm_gfx_ldo_remove(struct platform_device *pdev) } static struct of_device_id msm_gfx_ldo_match_table[] = { - { .compatible = "qcom,msmtitanium-gfx-ldo", }, + { .compatible = "qcom,msm8953-gfx-ldo", }, {} }; diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 382245eb90b6..21ff179b7c0b 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -1058,7 +1058,8 @@ static void glink_edge_ctx_release(struct rwref_lock *ch_st_lock) * it is not found. * @xprt_ctx: Transport to search for a matching edge. * - * Return: The edge ctx corresponding to edge of @xprt_ctx. + * Return: The edge ctx corresponding to edge of @xprt_ctx or + * NULL if memory allocation fails. */ static struct glink_core_edge_ctx *edge_name_to_ctx_create( struct glink_core_xprt_ctx *xprt_ctx) @@ -1074,6 +1075,10 @@ static struct glink_core_edge_ctx *edge_name_to_ctx_create( } } edge_ctx = kzalloc(sizeof(struct glink_core_edge_ctx), GFP_KERNEL); + if (!edge_ctx) { + mutex_unlock(&edge_list_lock_lhd0); + return NULL; + } strlcpy(edge_ctx->name, xprt_ctx->edge, GLINK_NAME_SIZE); rwref_lock_init(&edge_ctx->edge_ref_lock_lhd1, glink_edge_ctx_release); mutex_init(&edge_ctx->edge_migration_lock_lhd2); @@ -3909,6 +3914,10 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr, xprt_ptr->local_version_idx = cfg->versions_entries - 1; xprt_ptr->remote_version_idx = cfg->versions_entries - 1; xprt_ptr->edge_ctx = edge_name_to_ctx_create(xprt_ptr); + if (!xprt_ptr->edge_ctx) { + kfree(xprt_ptr); + return -ENOMEM; + } xprt_ptr->l_features = cfg->versions[cfg->versions_entries - 1].features; if (!if_ptr->poll) diff --git a/drivers/soc/qcom/mpm-of.c b/drivers/soc/qcom/mpm-of.c index 118e77503f6f..93f2de8a59dd 100644 --- a/drivers/soc/qcom/mpm-of.c +++ b/drivers/soc/qcom/mpm-of.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-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 @@ -69,8 +69,8 @@ struct mpm_irqs { char domain_name[MAX_DOMAIN_NAME]; }; +#define MAX_MPM_PIN_PER_IRQ 2 static struct mpm_irqs unlisted_irqs[MSM_MPM_NR_IRQ_DOMAINS]; - static int num_mpm_irqs = MSM_MPM_NR_MPM_IRQS; static struct hlist_head *irq_hash; static unsigned int *msm_mpm_irqs_m2a; @@ -244,9 +244,10 @@ static inline unsigned int msm_mpm_get_irq_m2a(unsigned int pin) return msm_mpm_irqs_m2a[pin]; } -static inline uint16_t msm_mpm_get_irq_a2m(struct irq_data *d) +static inline void msm_mpm_get_irq_a2m(struct irq_data *d, uint16_t *mpm_pins) { struct mpm_irqs_a2m *node = NULL; + int count = 0; hlist_for_each_entry(node, &irq_hash[hashfn(d->hwirq)], node) { if ((node->hwirq == d->hwirq) @@ -257,58 +258,71 @@ static inline uint16_t msm_mpm_get_irq_a2m(struct irq_data *d) */ if (node->pin != 0xff) msm_mpm_irqs_m2a[node->pin] = d->irq; - break; + if (count >= MAX_MPM_PIN_PER_IRQ) { + count--; + __WARN(); + } + mpm_pins[count] = node->pin; + count++; } } - return node ? node->pin : 0; } static int msm_mpm_enable_irq_exclusive( struct irq_data *d, bool enable, bool wakeset) { - uint16_t mpm_pin; + uint16_t num = 0; + uint16_t mpm_pins[MAX_MPM_PIN_PER_IRQ] = {0}; WARN_ON(!d); + if (!d) return 0; - mpm_pin = msm_mpm_get_irq_a2m(d); + msm_mpm_get_irq_a2m(d, mpm_pins); - if (mpm_pin == 0xff) - return 0; + for (num = 0; num < MAX_MPM_PIN_PER_IRQ; num++) { - if (mpm_pin) { - uint32_t *mpm_irq_masks = wakeset ? - msm_mpm_wake_irq : msm_mpm_enabled_irq; - uint32_t index = MSM_MPM_IRQ_INDEX(mpm_pin); - uint32_t mask = MSM_MPM_IRQ_MASK(mpm_pin); - - if (enable) - mpm_irq_masks[index] |= mask; - else - mpm_irq_masks[index] &= ~mask; - } else { - int i; - unsigned long *irq_apps; + if (mpm_pins[num] == 0xff) + break; - for (i = 0; i < MSM_MPM_NR_IRQ_DOMAINS; i++) { - if (d->domain == unlisted_irqs[i].domain) - break; - } + if (num && mpm_pins[num] == 0) + break; - if (i == MSM_MPM_NR_IRQ_DOMAINS) - return 0; - irq_apps = wakeset ? unlisted_irqs[i].wakeup_irqs : + if (mpm_pins[num]) { + uint32_t *mpm_irq_masks = wakeset ? + msm_mpm_wake_irq : msm_mpm_enabled_irq; + uint32_t index = MSM_MPM_IRQ_INDEX(mpm_pins[num]); + uint32_t mask = MSM_MPM_IRQ_MASK(mpm_pins[num]); + + if (enable) + mpm_irq_masks[index] |= mask; + else + mpm_irq_masks[index] &= ~mask; + } else { + int i; + unsigned long *irq_apps; + + for (i = 0; i < MSM_MPM_NR_IRQ_DOMAINS; i++) { + if (d->domain == unlisted_irqs[i].domain) + break; + } + + if (i == MSM_MPM_NR_IRQ_DOMAINS) + return 0; + + irq_apps = wakeset ? unlisted_irqs[i].wakeup_irqs : unlisted_irqs[i].enabled_irqs; - if (enable) - __set_bit(d->hwirq, irq_apps); - else - __clear_bit(d->hwirq, irq_apps); + if (enable) + __set_bit(d->hwirq, irq_apps); + else + __clear_bit(d->hwirq, irq_apps); - if ((msm_mpm_initialized & MSM_MPM_DEVICE_PROBED) + if ((msm_mpm_initialized & MSM_MPM_DEVICE_PROBED) && !wakeset && !msm_mpm_in_suspend) - complete(&wake_wq); + complete(&wake_wq); + } } return 0; @@ -337,27 +351,32 @@ static void msm_mpm_set_edge_ctl(int pin, unsigned int flow_type) static int msm_mpm_set_irq_type_exclusive( struct irq_data *d, unsigned int flow_type) { - uint32_t mpm_irq; + uint16_t num = 0; + uint16_t mpm_pins[MAX_MPM_PIN_PER_IRQ] = {0}; - mpm_irq = msm_mpm_get_irq_a2m(d); + msm_mpm_get_irq_a2m(d, mpm_pins); - if (mpm_irq == 0xff) - return 0; + for (num = 0; num < MAX_MPM_PIN_PER_IRQ; num++) { - if (mpm_irq) { - uint32_t index = MSM_MPM_IRQ_INDEX(mpm_irq); - uint32_t mask = MSM_MPM_IRQ_MASK(mpm_irq); + if (mpm_pins[num] == 0xff) + break; + + if (mpm_pins[num]) { + uint32_t index = MSM_MPM_IRQ_INDEX(mpm_pins[num]); + uint32_t mask = MSM_MPM_IRQ_MASK(mpm_pins[num]); - if (index >= MSM_MPM_REG_WIDTH) - return -EFAULT; + if (index >= MSM_MPM_REG_WIDTH) + return -EFAULT; - msm_mpm_set_edge_ctl(mpm_irq, flow_type); + msm_mpm_set_edge_ctl(mpm_pins[num], flow_type); - if (flow_type & IRQ_TYPE_LEVEL_HIGH) - msm_mpm_polarity[index] |= mask; - else - msm_mpm_polarity[index] &= ~mask; + if (flow_type & IRQ_TYPE_LEVEL_HIGH) + msm_mpm_polarity[index] |= mask; + else + msm_mpm_polarity[index] &= ~mask; + } } + return 0; } diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c index 00ab1ce3b6b4..3c3ae693f615 100644 --- a/drivers/soc/qcom/pil-msa.c +++ b/drivers/soc/qcom/pil-msa.c @@ -75,6 +75,9 @@ #define MSS_RESTART_ID 0xA #define MSS_MAGIC 0XAABADEAD +/* CX_IPEAK Parameters */ +#define CX_IPEAK_MSS BIT(5) + enum scm_cmd { PAS_MEM_SETUP_CMD = 2, }; @@ -304,6 +307,14 @@ int pil_mss_shutdown(struct pil_desc *pil) ret); } + /* + * If MSS was in turbo state before fatal error occurs, it would + * have set the vote bit. Since MSS is restarting, So PIL need to + * clear this bit. This may clear the throttle state. + */ + if (drv->cx_ipeak_vote) + writel_relaxed(CX_IPEAK_MSS, drv->cxip_lm_vote_clear); + ret = pil_mss_restart_reg(drv, 1); if (drv->is_booted) { diff --git a/drivers/soc/qcom/pil-q6v5-mss.c b/drivers/soc/qcom/pil-q6v5-mss.c index bf6b11194111..4ece8cf7907f 100644 --- a/drivers/soc/qcom/pil-q6v5-mss.c +++ b/drivers/soc/qcom/pil-q6v5-mss.c @@ -270,6 +270,17 @@ static int pil_mss_loadable_init(struct modem_data *drv, q6_desc->ops = &pil_msa_mss_ops_selfauth; } + q6->cx_ipeak_vote = of_property_read_bool(pdev->dev.of_node, + "qcom,cx-ipeak-vote"); + if (q6->cx_ipeak_vote) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "cxip_lm_vote_clear"); + q6->cxip_lm_vote_clear = devm_ioremap_resource(&pdev->dev, + res); + if (!q6->cxip_lm_vote_clear) + return -ENOMEM; + } + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg"); if (!res) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, diff --git a/drivers/soc/qcom/pil-q6v5.c b/drivers/soc/qcom/pil-q6v5.c index 5752aecb82bd..a1cd3b1eeaff 100644 --- a/drivers/soc/qcom/pil-q6v5.c +++ b/drivers/soc/qcom/pil-q6v5.c @@ -41,7 +41,7 @@ #define AXI_HALTACK 0x4 #define AXI_IDLE 0x8 -#define HALT_ACK_TIMEOUT_US 100000 +#define HALT_ACK_TIMEOUT_US 25000 /* QDSP6SS_RESET */ #define Q6SS_STOP_CORE BIT(0) diff --git a/drivers/soc/qcom/pil-q6v5.h b/drivers/soc/qcom/pil-q6v5.h index 9e8b8511e69b..23a7dfb62078 100644 --- a/drivers/soc/qcom/pil-q6v5.h +++ b/drivers/soc/qcom/pil-q6v5.h @@ -41,6 +41,7 @@ struct q6v5_data { void __iomem *axi_halt_mss; void __iomem *axi_halt_nc; void __iomem *restart_reg; + void __iomem *cxip_lm_vote_clear; struct regulator *vreg; struct regulator *vreg_cx; struct regulator *vreg_mx; @@ -69,6 +70,7 @@ struct q6v5_data { int override_acc_1; bool ahb_clk_vote; bool mx_spike_wa; + bool cx_ipeak_vote; }; int pil_q6v5_make_proxy_votes(struct pil_desc *pil); diff --git a/drivers/soc/qcom/service-notifier-private.h b/drivers/soc/qcom/service-notifier-private.h index b7bee86e5111..05336ad4b076 100644 --- a/drivers/soc/qcom/service-notifier-private.h +++ b/drivers/soc/qcom/service-notifier-private.h @@ -21,12 +21,14 @@ #define SERVREG_NOTIF_SERVICE_VERS_V01 0x01 #define QMI_SERVREG_NOTIF_REGISTER_LISTENER_REQ_V01 0x0020 -#define QMI_SERVREG_NOTIF_QUERY_STATE_REQ_V01 0x0021 #define QMI_SERVREG_NOTIF_REGISTER_LISTENER_RESP_V01 0x0020 +#define QMI_SERVREG_NOTIF_QUERY_STATE_REQ_V01 0x0021 #define QMI_SERVREG_NOTIF_QUERY_STATE_RESP_V01 0x0021 #define QMI_SERVREG_NOTIF_STATE_UPDATED_IND_V01 0x0022 -#define QMI_SERVREG_NOTIF_STATE_UPDATED_IND_ACK_RESP_V01 0x0023 #define QMI_SERVREG_NOTIF_STATE_UPDATED_IND_ACK_REQ_V01 0x0023 +#define QMI_SERVREG_NOTIF_STATE_UPDATED_IND_ACK_RESP_V01 0x0023 +#define QMI_SERVREG_NOTIF_RESTART_PD_REQ_V01 0x0024 +#define QMI_SERVREG_NOTIF_RESTART_PD_RESP_V01 0x0024 #define QMI_SERVREG_NOTIF_NAME_LENGTH_V01 64 @@ -80,6 +82,18 @@ struct qmi_servreg_notif_set_ack_resp_msg_v01 { #define QMI_SERVREG_NOTIF_SET_ACK_RESP_MSG_V01_MAX_MSG_LEN 7 struct elem_info qmi_servreg_notif_set_ack_resp_msg_v01_ei[]; +struct qmi_servreg_notif_restart_pd_req_msg_v01 { + char service_name[QMI_SERVREG_NOTIF_NAME_LENGTH_V01 + 1]; +}; +#define QMI_SERVREG_NOTIF_RESTART_PD_REQ_MSG_V01_MAX_MSG_LEN 67 +extern struct elem_info qmi_servreg_notif_restart_pd_req_msg_v01_ei[]; + +struct qmi_servreg_notif_restart_pd_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define QMI_SERVREG_NOTIF_RESTART_PD_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct elem_info qmi_servreg_notif_restart_pd_resp_msg_v01_ei[]; + struct elem_info qmi_servreg_notif_register_listener_req_msg_v01_ei[] = { { .data_type = QMI_UNSIGNED_1_BYTE, @@ -292,4 +306,40 @@ struct elem_info qmi_servreg_notif_set_ack_resp_msg_v01_ei[] = { }, }; +struct elem_info qmi_servreg_notif_restart_pd_req_msg_v01_ei[] = { + { + .data_type = QMI_STRING, + .elem_len = QMI_SERVREG_NOTIF_NAME_LENGTH_V01 + 1, + .elem_size = sizeof(char), + .is_array = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct + qmi_servreg_notif_restart_pd_req_msg_v01, + service_name), + }, + { + .data_type = QMI_EOTI, + .is_array = NO_ARRAY, + .is_array = QMI_COMMON_TLV_TYPE, + }, +}; + +struct elem_info qmi_servreg_notif_restart_pd_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 + qmi_servreg_notif_restart_pd_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, + }, +}; #endif diff --git a/drivers/soc/qcom/service-notifier.c b/drivers/soc/qcom/service-notifier.c index a244bc168136..84a2aeee8cf7 100644 --- a/drivers/soc/qcom/service-notifier.c +++ b/drivers/soc/qcom/service-notifier.c @@ -588,6 +588,75 @@ exit: return ERR_PTR(rc); } +static int send_pd_restart_req(const char *service_path, + struct qmi_client_info *data) +{ + struct qmi_servreg_notif_restart_pd_req_msg_v01 req; + struct qmi_servreg_notif_register_listener_resp_msg_v01 + resp = { { 0, 0 } }; + struct msg_desc req_desc, resp_desc; + int rc; + + snprintf(req.service_name, ARRAY_SIZE(req.service_name), "%s", + service_path); + + req_desc.msg_id = QMI_SERVREG_NOTIF_RESTART_PD_REQ_V01; + req_desc.max_msg_len = + QMI_SERVREG_NOTIF_RESTART_PD_REQ_MSG_V01_MAX_MSG_LEN; + req_desc.ei_array = qmi_servreg_notif_restart_pd_req_msg_v01_ei; + + resp_desc.msg_id = QMI_SERVREG_NOTIF_RESTART_PD_RESP_V01; + resp_desc.max_msg_len = + QMI_SERVREG_NOTIF_RESTART_PD_RESP_MSG_V01_MAX_MSG_LEN; + resp_desc.ei_array = qmi_servreg_notif_restart_pd_resp_msg_v01_ei; + + rc = qmi_send_req_wait(data->clnt_handle, &req_desc, &req, + sizeof(req), &resp_desc, &resp, sizeof(resp), + SERVER_TIMEOUT); + if (rc < 0) { + pr_err("%s: Message sending failed/server timeout, ret - %d\n", + service_path, rc); + return rc; + } + + /* Check the response */ + if (QMI_RESP_BIT_SHIFT(resp.resp.result) != QMI_RESULT_SUCCESS_V01) { + pr_err("QMI request for PD restart failed 0x%x\n", + QMI_RESP_BIT_SHIFT(resp.resp.error)); + return -EREMOTEIO; + } + + return rc; + +} + +/* service_notif_pd_restart() - Request PD restart + * @service_path: Individual service identifier path for which restart is + * being requested. + * @instance_id: Instance id specific to a subsystem. + * + * @return: >=0 on success, standard Linux error codes on failure. + */ +int service_notif_pd_restart(const char *service_path, int instance_id) +{ + struct qmi_client_info *tmp; + int rc = 0; + + list_for_each_entry(tmp, &qmi_client_list, list) { + if (tmp->instance_id == instance_id) { + if (tmp->service_connected) { + pr_info("Restarting service %s, instance-id %d\n", + service_path, instance_id); + rc = send_pd_restart_req(service_path, tmp); + } else + pr_info("Service %s is not connected\n", + service_path); + } + } + return rc; +} +EXPORT_SYMBOL(service_notif_pd_restart); + /* service_notif_register_notifier() - Register a notifier for a service * On success, it returns back a handle. It takes the following arguments: * service_path: Individual service identifier path for which a client diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index a21f6735808b..bb6afb6a7d6d 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -159,6 +159,7 @@ struct dwc3_msm { unsigned int utmi_clk_rate; struct clk *utmi_clk_src; struct clk *bus_aggr_clk; + struct clk *noc_aggr_clk; struct clk *cfg_ahb_clk; struct reset_control *core_reset; struct regulator *dwc3_gdsc; @@ -1956,6 +1957,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) clk_set_rate(mdwc->core_clk, 19200000); clk_disable_unprepare(mdwc->core_clk); + if (mdwc->noc_aggr_clk) + clk_disable_unprepare(mdwc->noc_aggr_clk); /* * Disable iface_clk only after core_clk as core_clk has FSM * depedency on iface_clk. Hence iface_clk should be turned off @@ -2070,6 +2073,8 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) * Turned ON iface_clk before core_clk due to FSM depedency. */ clk_prepare_enable(mdwc->iface_clk); + if (mdwc->noc_aggr_clk) + clk_prepare_enable(mdwc->noc_aggr_clk); clk_set_rate(mdwc->core_clk, mdwc->core_clk_rate); clk_prepare_enable(mdwc->core_clk); @@ -2416,6 +2421,10 @@ static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc) if (IS_ERR(mdwc->bus_aggr_clk)) mdwc->bus_aggr_clk = NULL; + mdwc->noc_aggr_clk = devm_clk_get(mdwc->dev, "noc_aggr_clk"); + if (IS_ERR(mdwc->noc_aggr_clk)) + mdwc->noc_aggr_clk = NULL; + if (of_property_match_string(mdwc->dev->of_node, "clock-names", "cfg_ahb_clk") >= 0) { mdwc->cfg_ahb_clk = devm_clk_get(mdwc->dev, "cfg_ahb_clk"); @@ -2965,6 +2974,8 @@ static int dwc3_msm_remove(struct platform_device *pdev) if (ret_pm < 0) { dev_err(mdwc->dev, "pm_runtime_get_sync failed with %d\n", ret_pm); + if (mdwc->noc_aggr_clk) + clk_prepare_enable(mdwc->noc_aggr_clk); clk_prepare_enable(mdwc->utmi_clk); clk_prepare_enable(mdwc->core_clk); clk_prepare_enable(mdwc->iface_clk); diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index 132dc0e028ae..032f4ca38e50 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -711,7 +711,7 @@ static int mdss_dp_config_gpios(struct mdss_dp_drv_pdata *dp, bool enable) } if (gpio_is_valid(dp->aux_sel_gpio)) { rc = gpio_direction_output( - dp->aux_sel_gpio, 0); + dp->aux_sel_gpio, dp->aux_sel_gpio_output); if (rc) pr_err("unable to set dir for aux_sel gpio\n"); } @@ -1076,11 +1076,6 @@ static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp, lane_map->lane1 = 0; lane_map->lane2 = 2; lane_map->lane3 = 3; - - if (gpio_is_valid(dp->usbplug_cc_gpio)) { - gpio_set_value(dp->usbplug_cc_gpio, 1); - pr_debug("Configured cc gpio for new Orientation\n"); - } } pr_debug("lane0 = %d, lane1 = %d, lane2 =%d, lane3 =%d\n", @@ -1196,7 +1191,6 @@ end: static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) { int ret = 0; - enum plug_orientation orientation = ORIENTATION_NONE; struct lane_mapping ln_map; /* wait until link training is completed */ @@ -1210,15 +1204,14 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) mutex_lock(&dp_drv->train_mutex); - orientation = usbpd_get_plug_orientation(dp_drv->pd); - pr_debug("plug orientation = %d\n", orientation); - - ret = mdss_dp_get_lane_mapping(dp_drv, orientation, &ln_map); + ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, + &ln_map); if (ret) goto exit; mdss_dp_phy_share_lane_config(&dp_drv->phy_io, - orientation, dp_drv->dpcd.max_lane_count); + dp_drv->orientation, + dp_drv->dpcd.max_lane_count); ret = mdss_dp_enable_mainlink_clocks(dp_drv); if (ret) @@ -1247,7 +1240,6 @@ exit: int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv) { int ret = 0; - enum plug_orientation orientation = ORIENTATION_NONE; struct lane_mapping ln_map; /* wait until link training is completed */ @@ -1267,10 +1259,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv) } mdss_dp_hpd_configure(&dp_drv->ctrl_io, true); - orientation = usbpd_get_plug_orientation(dp_drv->pd); - pr_debug("plug Orientation = %d\n", orientation); - - ret = mdss_dp_get_lane_mapping(dp_drv, orientation, &ln_map); + ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map); if (ret) goto exit; @@ -1289,8 +1278,8 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv) goto exit; } - mdss_dp_phy_share_lane_config(&dp_drv->phy_io, - orientation, dp_drv->dpcd.max_lane_count); + mdss_dp_phy_share_lane_config(&dp_drv->phy_io, dp_drv->orientation, + dp_drv->dpcd.max_lane_count); pr_debug("link_rate = 0x%x\n", dp_drv->link_rate); @@ -1478,6 +1467,12 @@ static int mdss_dp_notify_clients(struct mdss_dp_drv_pdata *dp, bool enable) return mdss_dp_send_cable_notification(dp, enable); } +static void mdss_dp_set_default_resolution(struct mdss_dp_drv_pdata *dp) +{ + hdmi_edid_set_video_resolution(dp->panel_data.panel_info.edid_data, + DEFAULT_VIDEO_RESOLUTION, true); +} + static int mdss_dp_edid_init(struct mdss_panel_data *pdata) { struct mdss_dp_drv_pdata *dp_drv = NULL; @@ -1512,6 +1507,8 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata) dp_drv->edid_buf = edid_init_data.buf; dp_drv->edid_buf_size = edid_init_data.buf_size; + mdss_dp_set_default_resolution(dp_drv); + return 0; } @@ -1532,12 +1529,22 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) pr_err("%s: host init done already\n", __func__); return 0; } + ret = mdss_dp_regulator_ctrl(dp_drv, true); if (ret) { pr_err("failed to enable regulators\n"); goto vreg_error; } + dp_drv->orientation = usbpd_get_plug_orientation(dp_drv->pd); + + dp_drv->aux_sel_gpio_output = 0; + if (dp_drv->orientation == ORIENTATION_CC2) + dp_drv->aux_sel_gpio_output = 1; + + pr_debug("orientation = %d, aux_sel_gpio_output = %d\n", + dp_drv->orientation, dp_drv->aux_sel_gpio_output); + mdss_dp_pinctrl_set_state(dp_drv, true); mdss_dp_config_gpios(dp_drv, true); @@ -1559,9 +1566,6 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io), mdss_dp_get_phy_hw_version(&dp_drv->phy_io)); - pr_debug("plug Orientation = %d\n", - usbpd_get_plug_orientation(dp_drv->pd)); - mdss_dp_phy_aux_setup(&dp_drv->phy_io); mdss_dp_irq_enable(dp_drv); @@ -1569,8 +1573,11 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) mdss_dp_dpcd_cap_read(dp_drv); ret = mdss_dp_edid_read(dp_drv); - if (ret) + if (ret) { + pr_info("edid read error, setting default resolution\n"); + mdss_dp_set_default_resolution(dp_drv); goto edid_error; + } pr_debug("edid_read success. buf_size=%d\n", dp_drv->edid_buf_size); @@ -1581,14 +1588,13 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata) goto edid_error; } +edid_error: mdss_dp_update_cable_status(dp_drv, true); mdss_dp_notify_clients(dp_drv, true); dp_drv->dp_initialized = true; return ret; -edid_error: - mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false); clk_error: mdss_dp_regulator_ctrl(dp_drv, false); mdss_dp_config_gpios(dp_drv, false); diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index dc84694f2238..00869e74d4ea 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -39,11 +39,6 @@ #define EDP_PORT_MAX 1 #define EDP_SINK_CAP_LEN 16 -#define EDP_AUX_ERR_NONE 0 -#define EDP_AUX_ERR_ADDR -1 -#define EDP_AUX_ERR_TOUT -2 -#define EDP_AUX_ERR_NACK -3 - /* 4 bits of aux command */ #define EDP_CMD_AUX_WRITE 0x8 #define EDP_CMD_AUX_READ 0x9 @@ -388,6 +383,7 @@ struct mdss_dp_drv_pdata { struct platform_device *ext_pdev; struct usbpd *pd; + enum plug_orientation orientation; struct dp_hdcp hdcp; struct usbpd_svid_handler svid_handler; struct dp_alt_mode alt_mode; @@ -438,6 +434,7 @@ struct mdss_dp_drv_pdata { struct dss_module_power power_data[DP_MAX_PM]; struct dp_pinctrl_res pin_res; int aux_sel_gpio; + int aux_sel_gpio_output; int aux_en_gpio; int usbplug_cc_gpio; int hpd_gpio; @@ -511,17 +508,52 @@ enum dp_lane_count { DP_LANE_COUNT_4 = 4, }; +enum dp_aux_error { + EDP_AUX_ERR_NONE = 0, + EDP_AUX_ERR_ADDR = -1, + EDP_AUX_ERR_TOUT = -2, + EDP_AUX_ERR_NACK = -3, + EDP_AUX_ERR_DEFER = -4, + EDP_AUX_ERR_NACK_DEFER = -5, +}; + +static inline char *mdss_dp_get_aux_error(u32 aux_error) +{ + switch (aux_error) { + case EDP_AUX_ERR_NONE: + return DP_ENUM_STR(EDP_AUX_ERR_NONE); + case EDP_AUX_ERR_ADDR: + return DP_ENUM_STR(EDP_AUX_ERR_ADDR); + case EDP_AUX_ERR_TOUT: + return DP_ENUM_STR(EDP_AUX_ERR_TOUT); + case EDP_AUX_ERR_NACK: + return DP_ENUM_STR(EDP_AUX_ERR_NACK); + case EDP_AUX_ERR_DEFER: + return DP_ENUM_STR(EDP_AUX_ERR_DEFER); + case EDP_AUX_ERR_NACK_DEFER: + return DP_ENUM_STR(EDP_AUX_ERR_NACK_DEFER); + default: + return "unknown"; + } +} + enum test_response { - TEST_NACK = 0x0, - TEST_ACK = 0x1, + TEST_ACK = 0x1, + TEST_NACK = 0x2, + TEST_EDID_CHECKSUM_WRITE = 0x4, }; static inline char *mdss_dp_get_test_response(u32 test_response) { switch (test_response) { - case TEST_NACK: return DP_ENUM_STR(TEST_NACK); - case TEST_ACK: return DP_ENUM_STR(TEST_ACK); - default: return "unknown"; + case TEST_NACK: + return DP_ENUM_STR(TEST_NACK); + case TEST_ACK: + return DP_ENUM_STR(TEST_ACK); + case TEST_EDID_CHECKSUM_WRITE: + return DP_ENUM_STR(TEST_EDID_CHECKSUM_WRITE); + default: + return "unknown"; } } diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index b64518194926..b216506fe2a9 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -34,6 +34,9 @@ #include "mdss_dp.h" #include "mdss_dp_util.h" +static void dp_sink_parse_test_request(struct mdss_dp_drv_pdata *ep); +static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep); + /* * edp buffer operation */ @@ -139,7 +142,6 @@ static int dp_cmd_fifo_tx(struct edp_buf *tp, unsigned char *base) data &= 0x00ff00; /* index = 0, write */ if (cnt == 0) data |= BIT(31); /* INDEX_WRITE */ - pr_debug("data=%x\n", data); dp_write(base + DP_AUX_DATA, data); cnt++; dp++; @@ -150,7 +152,6 @@ static int dp_cmd_fifo_tx(struct edp_buf *tp, unsigned char *base) data |= BIT(8); /* I2C */ data |= BIT(9); /* GO */ - pr_debug("data=%x\n", data); dp_write(base + DP_AUX_TRANS_CTRL, data); return tp->len; @@ -173,7 +174,6 @@ static int dp_cmd_fifo_rx(struct edp_buf *rp, int len, unsigned char *base) data = dp_read(base + DP_AUX_DATA); for (i = 0; i < len; i++) { data = dp_read(base + DP_AUX_DATA); - pr_debug("data=%x\n", data); *dp++ = (char)((data >> 8) & 0xff); } @@ -196,9 +196,6 @@ static int dp_aux_write_cmds(struct mdss_dp_drv_pdata *ep, cm = cmd; while (cm) { - pr_debug("i2c=%d read=%d addr=%x len=%d next=%d\n", - cm->i2c, cm->read, cm->addr, cm->len, - cm->next); ret = dp_buf_add_cmd(tp, cm); if (ret <= 0) break; @@ -254,9 +251,6 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep, cm = cmds; len = 0; while (cm) { - pr_debug("i2c=%d read=%d addr=%x len=%d next=%d\n", - cm->i2c, cm->read, cm->addr, cm->len, - cm->next); ret = dp_buf_add_cmd(tp, cm); len += cm->len; if (ret <= 0) @@ -302,9 +296,6 @@ int dp_aux_read(void *ep, struct edp_cmd *cmds) void dp_aux_native_handler(struct mdss_dp_drv_pdata *ep, u32 isr) { - - pr_debug("isr=%x\n", isr); - if (isr & EDP_INTR_AUX_I2C_DONE) ep->aux_error_num = EDP_AUX_ERR_NONE; else if (isr & EDP_INTR_WRONG_ADDR) @@ -319,9 +310,6 @@ void dp_aux_native_handler(struct mdss_dp_drv_pdata *ep, u32 isr) void dp_aux_i2c_handler(struct mdss_dp_drv_pdata *ep, u32 isr) { - - pr_debug("isr=%x\n", isr); - if (isr & EDP_INTR_AUX_I2C_DONE) { if (isr & (EDP_INTR_I2C_NACK | EDP_INTR_I2C_DEFER)) ep->aux_error_num = EDP_AUX_ERR_NACK; @@ -333,11 +321,11 @@ void dp_aux_i2c_handler(struct mdss_dp_drv_pdata *ep, u32 isr) else if (isr & EDP_INTR_TIMEOUT) ep->aux_error_num = EDP_AUX_ERR_TOUT; if (isr & EDP_INTR_NACK_DEFER) - ep->aux_error_num = EDP_AUX_ERR_NACK; + ep->aux_error_num = EDP_AUX_ERR_NACK_DEFER; if (isr & EDP_INTR_I2C_NACK) ep->aux_error_num = EDP_AUX_ERR_NACK; if (isr & EDP_INTR_I2C_DEFER) - ep->aux_error_num = EDP_AUX_ERR_NACK; + ep->aux_error_num = EDP_AUX_ERR_DEFER; } complete(&ep->aux_comp); @@ -707,7 +695,8 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) for (cnt = 5; cnt; cnt--) { ret = dp_aux_write_buf(ep, EDID_START_ADDRESS, &data, 1, 1); - pr_debug("ret=%d\n", ret); + pr_debug("ret = %d, aux_error = %s\n", + ret, mdss_dp_get_aux_error(ep->aux_error_num)); if (ret >= 0) break; msleep(100); @@ -721,6 +710,20 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) return 0; } +static void dp_aux_send_checksum(struct mdss_dp_drv_pdata *dp, u32 checksum) +{ + char data[4]; + + data[0] = checksum; + pr_debug("writing checksum %d\n", data[0]); + dp_aux_write_buf(dp, 0x261, data, 1, 0); + + data[0] = TEST_EDID_CHECKSUM_WRITE; + pr_debug("sending test response %s\n", + mdss_dp_get_test_response(data[0])); + dp_aux_write_buf(dp, 0x260, data, 1, 0); +} + int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) { struct edp_buf *rp = &dp->rxp; @@ -728,6 +731,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) int edid_blk = 0, blk_num = 0, retries = 10; bool edid_parsing_done = false; const u8 cea_tag = 0x02; + u32 checksum = 0; ret = dp_aux_chan_ready(dp); if (ret) { @@ -735,6 +739,12 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) return ret; } + /** + * Parse the test request vector to see whether there is a + * TEST_EDID_READ test request. + */ + dp_sink_parse_test_request(dp); + do { rlen = dp_aux_read_buf(dp, EDID_START_ADDRESS + (blk_num * EDID_BLOCK_SIZE), @@ -747,8 +757,11 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) pr_debug("blk_num=%d, rlen=%d\n", blk_num, rlen); if (dp_edid_is_valid_header(rp->data)) { - if (dp_edid_buf_error(rp->data, rp->len)) - continue; + ret = dp_edid_buf_error(rp->data, rp->len); + if (ret) { + pr_err("corrupt edid block detected\n"); + goto end; + } if (edid_parsing_done) { blk_num++; @@ -765,6 +778,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) rp->data); edid_parsing_done = true; + checksum = rp->data[rp->len - 1]; } else { edid_blk++; blk_num++; @@ -783,10 +797,17 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) rp->data, EDID_BLOCK_SIZE); if (edid_blk == dp->edid.ext_block_cnt) - return 0; + goto end; } while (retries--); - return 0; +end: + if (dp->test_data.test_requested == TEST_EDID_READ) { + pr_debug("sending checksum %d\n", checksum); + dp_aux_send_checksum(dp, checksum); + dp->test_data = (const struct dpcd_test_request){ 0 }; + } + + return ret; } static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep, @@ -935,6 +956,8 @@ static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep, cap->training_read_interval = 4000 * data; /* us */ pr_debug("training_interval=%d\n", cap->training_read_interval); + + dp_sink_parse_sink_count(ep); } static int dp_link_status_read(struct mdss_dp_drv_pdata *ep, int len) @@ -1141,7 +1164,8 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) */ static bool dp_is_test_supported(u32 test_requested) { - return test_requested == TEST_LINK_TRAINING; + return (test_requested == TEST_LINK_TRAINING) || + (test_requested == TEST_EDID_READ); } /** diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index 10962548c3c5..b1bfe2c548ba 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -312,8 +312,8 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, } if (tu_entry == tu_table + ARRAY_SIZE(tu_table)) { - pr_err("requested ln_cnt=%d, lrate=0x%x not supported\n", - ln_cnt, link_rate); + pr_err("requested res=%d, ln_cnt=%d, lrate=0x%x not supported\n", + res, ln_cnt, link_rate); return; } @@ -604,8 +604,9 @@ static u8 mdss_dp_calculate_parity_byte(u32 data) u8 iData = 0; u8 i = 0; u8 parityByte; + u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2; - for (i = 0; i < 8; i++) { + for (i = 0; i < num_byte; i++) { iData = (data >> i*4) & 0xF; ci = iData ^ x1; diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 82e9f9417662..5e238d5be2b4 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -245,6 +245,8 @@ static const struct dp_vc_tu_mapping_table tu_table[] = { 0x21, 0x001a, false, 0x00, 0x00, 0x00, 0x27}, {HDMI_VFRMT_1920x1080p60_16_9, 4, 06, 24, 0x16, 0x000f, false, 0x00, 0x00, 0x00, 0x1f}, + {HDMI_VFRMT_1920x1080p60_16_9, 4, 10, 24, + 0x21, 0x0013, false, 0x21, 0x8, 0x1, 0x26}, {HDMI_VFRMT_1920x1080p60_16_9, 2, 10, 24, 0x21, 0x0011, false, 0x00, 0x00, 0x00, 0x27}, {HDMI_VFRMT_1920x1080p60_16_9, 1, 20, 24, diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 8fbf2544f487..f925fd5296d4 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1703,10 +1703,12 @@ static void mdss_dsi_parse_dms_config(struct device_node *np, pr_debug("%s: default dms suspend/resume\n", __func__); mdss_dsi_parse_dcs_cmds(np, &ctrl->video2cmd, - "qcom,video-to-cmd-mode-switch-commands", NULL); + "qcom,video-to-cmd-mode-switch-commands", + "qcom,mode-switch-commands-state"); mdss_dsi_parse_dcs_cmds(np, &ctrl->cmd2video, - "qcom,cmd-to-video-mode-switch-commands", NULL); + "qcom,cmd-to-video-mode-switch-commands", + "qcom,mode-switch-commands-state"); mdss_dsi_parse_dcs_cmds(np, &ctrl->post_dms_on_cmds, "qcom,mdss-dsi-post-mode-switch-on-command", diff --git a/include/soc/qcom/service-notifier.h b/include/soc/qcom/service-notifier.h index eae879786d59..0106801fc173 100644 --- a/include/soc/qcom/service-notifier.h +++ b/include/soc/qcom/service-notifier.h @@ -52,21 +52,29 @@ void *service_notif_register_notifier(const char *service_path, int instance_id, int service_notif_unregister_notifier(void *service_notif_handle, struct notifier_block *nb); +int service_notif_pd_restart(const char *service_path, int instance_id); + #else -static void *service_notif_register_notifier(const char *service_path, +static inline void *service_notif_register_notifier(const char *service_path, int instance_id, struct notifier_block *nb, int *curr_state) { return ERR_PTR(-ENODEV); } -static int service_notif_unregister_notifier(void *service_notif_handle, +static inline int service_notif_unregister_notifier(void *service_notif_handle, struct notifier_block *nb) { return -ENODEV; } +static inline int service_notif_pd_restart(const char *service_path, + int instance_id) +{ + return -ENODEV; +} + #endif /* CONFIG_MSM_SERVICE_NOTIFIER */ #endif diff --git a/include/uapi/media/msm_cam_sensor.h b/include/uapi/media/msm_cam_sensor.h index 172545d34b7d..c6144cd8f355 100644 --- a/include/uapi/media/msm_cam_sensor.h +++ b/include/uapi/media/msm_cam_sensor.h @@ -305,7 +305,7 @@ struct msm_eeprom_cfg_data { enum eeprom_cfg_type_t cfgtype; uint8_t is_supported; union { - char eeprom_name[MAX_SENSOR_NAME]; + char eeprom_name[MAX_EEPROM_NAME]; struct eeprom_get_t get_data; struct eeprom_read_t read_data; struct eeprom_write_t write_data; diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index e4d41d4072c5..9399f6e84004 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -819,6 +819,16 @@ struct msm_isp_ahb_clk_cfg { uint32_t reserved[2]; }; +enum msm_vfe_dual_cam_sync_mode { + MSM_ISP_DUAL_CAM_ASYNC, + MSM_ISP_DUAL_CAM_SYNC, +}; + +struct msm_isp_dual_hw_master_slave_sync { + uint32_t sync_mode; + uint32_t reserved[2]; +}; + #define V4L2_PIX_FMT_QBGGR8 v4l2_fourcc('Q', 'B', 'G', '8') #define V4L2_PIX_FMT_QGBRG8 v4l2_fourcc('Q', 'G', 'B', '8') #define V4L2_PIX_FMT_QGRBG8 v4l2_fourcc('Q', 'G', 'R', '8') @@ -981,6 +991,10 @@ enum msm_isp_ioctl_cmd_code { #define VIDIOC_MSM_ISP_AHB_CLK_CFG \ _IOWR('V', BASE_VIDIOC_PRIVATE+25, struct msm_isp_ahb_clk_cfg) +#define VIDIOC_MSM_ISP_DUAL_HW_MASTER_SLAVE_SYNC \ + _IOWR('V', BASE_VIDIOC_PRIVATE+26, \ + struct msm_isp_dual_hw_master_slave_sync) + #define VIDIOC_MSM_ISP_FETCH_ENG_MULTI_PASS_START \ _IOWR('V', MSM_ISP_FETCH_ENG_MULTI_PASS_START, \ struct msm_vfe_fetch_eng_multi_pass_start) |
