summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/bcl.txt27
-rw-r--r--Documentation/devicetree/bindings/arm/msm/msm.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,gpucc.txt3
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt6
-rw-r--r--Documentation/devicetree/bindings/gpu/adreno.txt2
-rw-r--r--Documentation/devicetree/bindings/input/qpnp-power-on.txt13
-rw-r--r--Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt4
-rw-r--r--Documentation/devicetree/bindings/regulator/cpr4-apss-regulator.txt10
-rw-r--r--Documentation/devicetree/bindings/regulator/msm_gfx_ldo.txt17
-rw-r--r--Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt250
-rw-r--r--Documentation/devicetree/bindings/usb/msm-phy.txt1
-rw-r--r--Documentation/devicetree/bindings/usb/msm-ssusb.txt5
-rw-r--r--arch/arm/boot/dts/qcom/Makefile5
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-jdi-dualmipi-cmd.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/fg-gen3-batterydata-ascent-3450mah.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/fg-gen3-batterydata-demo-6000mah.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/fg-gen3-batterydata-itech-3000mah.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/fg-gen3-batterydata-qrd-skuk-4v4-3000mah.dtsi (renamed from arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi)2
-rw-r--r--arch/arm/boot/dts/qcom/msm-arm-smmu-falcon.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/msm-arm-smmu-triton.dtsi45
-rw-r--r--arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/msm-audio.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon-rpm-regulator.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm2falcon.dtsi43
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi37
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8998.dtsi15
-rw-r--r--arch/arm/boot/dts/qcom/msm-smb138x.dtsi112
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-audio.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-cdp.dtsi62
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-coresight.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-gpu.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-cdp.dtsi202
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-camera-sensor-mtp.dtsi202
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-audio.dtsi46
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi63
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi91
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-pmfalcon.dtsi20
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-mtp.dtsi90
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi64
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-pm.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi54
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd.dtsi22
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-cdp.dts63
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-mtp.dts92
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts211
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi29
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-vidc.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi56
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-cdp.dts23
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi24
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-common.dtsi36
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-gpu.dtsi253
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-mtp.dts23
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi24
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-pm.dtsi821
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-rcm.dts23
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi36
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-rumi.dts6
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-sim.dts1
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon.dtsi371
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi77
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton-rumi.dts7
-rw-r--r--arch/arm/boot/dts/qcom/msmtriton.dtsi237
-rw-r--r--arch/arm/configs/msmcortex_defconfig1
-rw-r--r--arch/arm/configs/msmfalcon-perf_defconfig9
-rw-r--r--arch/arm/configs/msmfalcon_defconfig10
-rw-r--r--arch/arm/include/asm/etmv4x.h387
-rw-r--r--arch/arm/include/asm/hardware/debugv8.h247
-rw-r--r--arch/arm/mm/dma-mapping.c12
-rw-r--r--arch/arm64/configs/msm-perf_defconfig5
-rw-r--r--arch/arm64/configs/msm_defconfig5
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig3
-rw-r--r--arch/arm64/configs/msmcortex_defconfig3
-rw-r--r--arch/arm64/configs/msmfalcon-perf_defconfig9
-rw-r--r--arch/arm64/configs/msmfalcon_defconfig9
-rw-r--r--arch/arm64/mm/dma-mapping.c9
-rw-r--r--drivers/clk/clk.c11
-rw-r--r--drivers/clk/msm/clock-osm.c21
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c35
-rw-r--r--drivers/clk/qcom/clk-branch.c9
-rw-r--r--drivers/clk/qcom/clk-rcg.h1
-rw-r--r--drivers/clk/qcom/clk-rcg2.c61
-rw-r--r--drivers/clk/qcom/gcc-msmfalcon.c16
-rw-r--r--drivers/clk/qcom/gpucc-msmfalcon.c42
-rw-r--r--drivers/clk/qcom/mmcc-msmfalcon.c11
-rw-r--r--drivers/clk/qcom/vdd-level-falcon.h9
-rw-r--r--drivers/gpu/msm/adreno.h2
-rw-r--r--drivers/gpu/msm/adreno_a5xx_snapshot.c45
-rw-r--r--drivers/gpu/msm/adreno_coresight.c12
-rw-r--r--drivers/gpu/msm/kgsl_device.h4
-rw-r--r--drivers/gpu/msm/kgsl_snapshot.c35
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc.c2
-rw-r--r--drivers/input/misc/hbtp_input.c17
-rw-r--r--drivers/input/qpnp-power-on.c84
-rw-r--r--drivers/input/touchscreen/ft5x06_ts.c4
-rw-r--r--drivers/iommu/arm-smmu.c73
-rw-r--r--drivers/iommu/dma-mapping-fast.c40
-rw-r--r--drivers/iommu/io-pgtable-arm.c7
-rw-r--r--drivers/iommu/iommu-debug.c4
-rw-r--r--drivers/leds/leds-qpnp-wled.c366
-rw-r--r--drivers/media/dvb-core/dvb_demux.c5
-rw-r--r--drivers/media/platform/msm/camera_v2/common/Makefile3
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c20
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.c351
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.h91
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h32
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp32.c84
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp40.c131
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp44.c92
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp46.c110
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c153
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.h9
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp48.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c823
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c141
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c182
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c22
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c18
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c46
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c10
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c533
-rw-r--r--drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c16
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c16
-rw-r--r--drivers/media/platform/msm/vidc/venus_boot.c4
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c11
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.h5
-rw-r--r--drivers/media/platform/msm/vidc/vmem/vmem.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c30
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h3
-rw-r--r--drivers/nfc/nq-nci.c135
-rw-r--r--drivers/nfc/nq-nci.h2
-rw-r--r--drivers/phy/phy-qcom-ufs-qmp-v3.h3
-rw-r--r--drivers/phy/phy-qcom-ufs.c9
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_utils.c22
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c55
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c10
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c32
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h5
-rw-r--r--drivers/power/power_supply_sysfs.c1
-rw-r--r--drivers/power/qcom-charger/battery_current_limit.c37
-rw-r--r--drivers/power/qcom-charger/fg-core.h5
-rw-r--r--drivers/power/qcom-charger/qpnp-fg-gen3.c23
-rw-r--r--drivers/power/qcom-charger/smb-lib.c11
-rw-r--r--drivers/power/qcom/msm-core.c4
-rw-r--r--drivers/regulator/Kconfig9
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/cpr4-apss-regulator.c222
-rw-r--r--drivers/regulator/msm_gfx_ldo.c197
-rw-r--r--drivers/regulator/qpnp-lcdb-regulator.c1692
-rw-r--r--drivers/scsi/ufs/ufshcd.c32
-rw-r--r--drivers/scsi/ufs/ufshcd.h1
-rw-r--r--drivers/soc/qcom/glink.c11
-rw-r--r--drivers/soc/qcom/icnss.c10
-rw-r--r--drivers/soc/qcom/mpm-of.c117
-rw-r--r--drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c4
-rw-r--r--drivers/soc/qcom/pil-msa.c11
-rw-r--r--drivers/soc/qcom/pil-q6v5-mss.c16
-rw-r--r--drivers/soc/qcom/pil-q6v5.c2
-rw-r--r--drivers/soc/qcom/pil-q6v5.h2
-rw-r--r--drivers/soc/qcom/service-notifier-private.h54
-rw-r--r--drivers/soc/qcom/service-notifier.c69
-rw-r--r--drivers/soc/qcom/spcom.c69
-rw-r--r--drivers/soc/qcom/subsys-pil-tz.c41
-rw-r--r--drivers/soc/qcom/wcd-dsp-glink.c25
-rw-r--r--drivers/thermal/msm_lmh_dcvs.c32
-rw-r--r--drivers/thermal/msm_thermal.c5
-rw-r--r--drivers/thermal/thermal_core.c47
-rw-r--r--drivers/usb/dwc3/dbm.c22
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c222
-rw-r--r--drivers/usb/dwc3/gadget.c3
-rw-r--r--drivers/usb/gadget/function/f_gsi.c4
-rw-r--r--drivers/usb/gadget/function/u_data_ipa.c4
-rw-r--r--drivers/usb/gadget/function/u_qdss.c3
-rw-r--r--drivers/usb/phy/phy-msm-qusb-v2.c47
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c56
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h52
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c70
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_panel.c6
-rw-r--r--include/dt-bindings/clock/audio-ext-clk.h4
-rw-r--r--include/linux/clk-provider.h4
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/msm_thermal.h13
-rw-r--r--include/linux/power_supply.h1
-rw-r--r--include/linux/usb/msm_hsusb.h6
-rw-r--r--include/soc/qcom/icnss.h3
-rw-r--r--include/soc/qcom/service-notifier.h12
-rw-r--r--include/sound/apr_audio-v2.h1
-rw-r--r--include/uapi/media/msm_cam_sensor.h2
-rw-r--r--include/uapi/media/msmb_isp.h14
-rw-r--r--kernel/sched/core.c87
-rw-r--r--kernel/sched/rt.c8
-rw-r--r--mm/gup.c14
-rw-r--r--sound/soc/codecs/wcd-spi.c10
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c10
-rw-r--r--sound/soc/msm/Kconfig11
-rw-r--r--sound/soc/msm/msm8998.c246
-rw-r--r--sound/soc/msm/qdsp6v2/Makefile1
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c32
-rw-r--r--sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c4
-rw-r--r--sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h8
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dts-eagle.c3
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c26
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h2
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c10
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c22
-rw-r--r--sound/soc/msm/qdsp6v2/q6audio-v2.c3
-rw-r--r--sound/soc/msm/qdsp6v2/q6core.c44
-rw-r--r--sound/usb/usb_audio_qmi_svc.c6
216 files changed, 9521 insertions, 3248 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/bcl.txt b/Documentation/devicetree/bindings/arm/msm/bcl.txt
index 42acaa49c2a5..710c70a57840 100644
--- a/Documentation/devicetree/bindings/arm/msm/bcl.txt
+++ b/Documentation/devicetree/bindings/arm/msm/bcl.txt
@@ -38,17 +38,19 @@ Optional parameters:
- qcom,bcl-framework-interface: If this property is defined, then the BCL uses
the BCL framework for monitoring battery voltage and current.
When this property is defined, the 'qcom,high-threshold-uamp',
- 'qcom,low-threshold-uamp', 'qcom,mitigation-freq-khz',
- 'qcom,vph-high-threshold-uv', 'qcom,vph-low-threshold-uv' and
- 'qcom,thermal-handle' properties should be defined in the
- 'qcom,ibat-monitor' node.
+ 'qcom,low-threshold-uamp', 'qcom,vph-high-threshold-uv',
+ 'qcom,vph-low-threshold-uv' and 'qcom,thermal-handle' properties
+ should be defined in the 'qcom,ibat-monitor' node.
- qcom,bcl-hotplug-list = <hotplug-phandle-list>: List of phandles to the cores
that are to be hotplugged, when battery current limit condition
is reached.
- qcom,bcl-soc-hotplug-list: List of phandles to the cores that are to be hotplugged,
when battery SOC limit condition is reached.
-- qcom,bcl-freq-control-list: List of phandles to the cores that are to be frequency
- mitigated when BCL condition is reached.
+- qcom,bcl-freq-control-list: This optional property takes list of phandles to the
+ cores that are to be frequency mitigated when BCL condition is
+ reached. When this property is defined, 'qcom,mitigation-freq-khz'
+ and 'qcom,thermal-handle' should be defined in the
+ 'qcom,ibat-monitor' node.
- qcom,bcl-no-bms: This is an optional node for BCL IAVAIL monitor mode.
If this property is defined, BCL IAVAIL monitor gets rbat value
from power supply battery module instead of bms module.
@@ -65,10 +67,12 @@ Optional nodes:
which the BCL driver should cap the maximum frequency.
* qcom,low-threshold-uamp: The battery current, in microampere, below
which the BCL driver should clear the CPU frequency mitigation.
- * qcom,mitigation-freq-khz: The maximum frequency value the BCL driver
- should mitigate the CPUS's with. This frequency shouldn't be
- less than the minimum frequency request that the kernel thermal
- monitor driver places during vdd restriction.
+ * qcom,mitigation-freq-khz: This optional property defines the maximum
+ frequency value the BCL driver should mitigate the CPUS's with.
+ This property is valid only if 'qcom,bcl-freq-control-list' is
+ defined in bcl parent node. This frequency shouldn't be less than
+ the minimum frequency request that the kernel thermal monitor
+ driver places during vdd restriction.
* qcom,ibat-channel: The ADC hardware's Ibat channel number.
* qcom,uv-to-ua-numerator: The conversion parameter required for converting
the voltage measure from ADC hardware to current value.
@@ -92,7 +96,8 @@ Optional nodes:
used by BCL driver to get the minimum frequency request that the
thermal driver places during vdd restriction. This frequency
value will be the lowest max frequency value the BCL driver can
- request.
+ request. This property is valid only if 'qcom,bcl-freq-control-list'
+ is defined in bcl parent node.
* qcom,soc-low-threshold: The battery SOC percentage threshold below which
mitigation needs to be applied.
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index de99a5636ef3..ce7bfa24490a 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -262,6 +262,8 @@ compatible = "qcom,msmhamster-cdp"
compatible = "qcom,msmhamster-mtp"
compatible = "qcom,msmfalcon-sim"
compatible = "qcom,msmfalcon-rumi"
+compatible = "qcom,msmfalcon-cdp"
+compatible = "qcom,msmfalcon-mtp"
compatible = "qcom,msmtriton-rumi"
compatible = "qcom,msm8952-rumi"
compatible = "qcom,msm8952-sim"
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
index 9f8ea0d6ef8f..4d8f87225230 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
@@ -4,7 +4,8 @@ Qualcomm Technologies, Inc Graphics Clock & Reset Controller Binding
Required properties :
- compatible : shall contain only one of the following:
- "qcom,gpucc-msmfalcon"
+ "qcom,gpucc-msmfalcon",
+ "qcom,gpucc-msmtriton"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
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/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 8a79626125d9..f5ae85d27692 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -187,7 +187,7 @@ Documentation/devicetree/bindings/coresight/coresight.txt
- coresight-child-list List of phandles pointing to the children of this
component.
- coresight-child-ports List of input port numbers of the children.
-
+- coresight-atid The unique ATID value of the coresight device
Example of A330 GPU in MSM8916:
diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
index 5b364d0a77ba..a596aa1c595d 100644
--- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
@@ -24,11 +24,14 @@ Required properties:
Optional properties:
- qcom,pon-dbc-delay The debounce delay for the power-key interrupt
- specified in us. The value ranges from 2
- seconds to 1/64 of a second. Possible values
- are:
- - 2, 1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64
- - Intermediate value is rounded down to the
+ specified in us.
+ Possible values for GEN1 PON are:
+ 15625, 31250, 62500, 125000, 250000, 500000,
+ 1000000 and 2000000.
+ Possible values for GEN2 PON are:
+ 62, 123, 245, 489, 977, 1954, 3907, 7813,
+ 15625, 31250, 62500, 125000 and 250000.
+ Intermediate value is rounded down to the
nearest valid value.
- qcom,pon_1 ...pon_n These represent the child nodes which describe
the properties (reset, key) for each of the pon
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/regulator/qpnp-lcdb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
new file mode 100644
index 000000000000..68d23d0f5523
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
@@ -0,0 +1,250 @@
+QPNP LCDB (LCD Bias) Regulator
+
+QPNP LCDB module provides voltage bias to the LCD display panel. The biases
+are positive (VDISP - supported by LDO) and negative (VDISN - supported by
+NCP) voltage signals. The module also supports TTW (touch-to-wake) capability.
+
+This document describes the bindings for QPNP LCDB module.
+
+=======================
+Required Node Structure
+=======================
+
+LCDB module must be described in two level of device nodes.
+
+==============================
+First Level Node - LCDB module
+==============================
+
+- compatible
+ Usage: required
+ Value type: <string>
+ Definition: should be "qcom,qpnp-lcdb-regulator"
+
+- reg
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Base address of the LCDB SPMI peripheral.
+
+Touch-to-wake (TTW) properties:
+
+TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable
+logic is controlled by an external signal (pin) where as in the SW mode it is
+is controlled by a pre-configured timer (ton/toff) programmed in the TTW
+register.
+
+Properties below are specific to TTW mode only. They are sepecified in the
+main node.
+
+- qcom,ttw-enable
+ Usage: optional
+ Value type: <bool>
+ Definition: Touch to wake-up support enabled.
+
+- qcom,ttw-mode-sw
+ Usage: optional
+ Value type: <bool>
+ Definition: Touch to wake supported in SW mode.
+ If not defined, ttw is enabled by HW pin.
+
+- qcom,attw-toff-ms
+ Usage: required if 'qcom,ttw-mode-sw' is true.
+ Value type: <bool>
+ Definition: Off time (in mS) for the VDISP/VDISN signals.
+ Possible values are 4, 8, 16, 32.
+
+- qcom,attw-ton-ms
+ Usage: required if 'qcom,ttw-mode-sw' is true.
+ Value type: <bool>
+ Definition: ON time (in mS) for the VDISP/VDISN signals.
+ Possible values are 4, 8, 16, 32.
+
+
+========================================
+Second Level Nodes - LDO/NCP/BOOST block
+========================================
+
+LDO / NCP subnode common properties:
+
+Properties below are common to the LDO and NCP bias.
+
+- label
+ Usage: required
+ Value type: <string>
+ Definition: A string used to describe the bias type.
+ Possible values are ldo, ncp, bst.
+
+- regulator-name
+ Usage: required
+ Value type: <string>
+ Definition: A string used to describe the regulator.
+
+- regulator-min-microvolt
+ Usage: required
+ Value type: <u32>
+ Definition: Minimum voltage (in uV) supported by the bias.
+
+- regulator-max-microvolt
+ Usage: required
+ Value type: <u32>
+ Definition: Maximum voltage (in uV) supported by the bias.
+
+
+LDO subnode properties:
+
+Properties below are specific to LDO bias only.
+
+- qcom,ldo-voltage-mv
+ Usage: optional
+ Value type: <u32>
+ Definition: Voltage (in mV) progammed for the LDO (VDISP).
+ Possile values are 4000mV to 6000mV. The range
+ 4000mV to 4900mV is in 100mV steps and 4900mV to
+ 6000mV is in 50mV steps.
+
+- qcom,ldo-pd
+ Usage: optional
+ Value type: <u32>
+ Definition: Pull-down configuration of LDO. Possible values are:
+ 1 - Enable pull-down
+ 0 - Disable pull-down
+
+- qcom,ldo-pd-strength
+ Usage: optional
+ Value type: <u32>
+ Definition: Pull-down strength. Possible values are:
+ 0 - Weak pull-down
+ 1 - Strong pull-down
+
+- qcom,ldo-ilim-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: Current limit (in mA) of the LDO bias.
+ Possible values are 110, 160, 210, 260, 310, 360, 410, 460.
+
+- qcom,ldo-soft-start-us
+ Usage: optional
+ Value type: <u32>
+ Definition: Soft-start time (in uS) of the LDO bias.
+ Possible values are 0, 500, 1000, 2000.
+
+
+NCP subnode properties:
+
+Properties below are specific to NCP bias only.
+
+- qcom,ncp-voltage-mv
+ Usage: optional
+ Value type: <u32>
+ Definition: Voltage (in mV) progammed for the NCP (VDISN).
+ Possile values are 4000mV to 6000mV. The range
+ 4000mV to 4900mV is in 100mV steps and 4900mV to
+ 6000mV is in 50mV steps.
+
+- qcom,ncp-pd
+ Usage: optional
+ Value type: <u32>
+ Definition: Pull-down configuration of NCP. Possible values are:
+ 1 - Enable pull-down
+ 0 - Disable pull-down
+
+- qcom,ncp-pd-strength
+ Usage: optional
+ Value type: <u32>
+ Definition: Pull-down strength. Possible values are:
+ 0 - Weak pull-down
+ 1 - Strong pull-down
+
+- qcom,ncp-ilim-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: Current limit (in mA) of the NCP bias.
+ Possible values are 260, 460, 640, 810.
+
+- qcom,ncp-soft-start-us
+ Usage: optional
+ Value type: <u32>
+ Definition: Soft-start time (in uS) of the NCP bias.
+ Possible values are 0, 500, 1000, 2000.
+
+
+BOOST subnode properties:
+
+Properties below are specific to BOOST subnode only.
+
+- qcom,bst-pd
+ Usage: optional
+ Value type: <bool>
+ Definition: Pull-down configuration of BOOST. Possible values are:
+ 1 - Enable pull-down
+ 0 - Disable pull-down
+
+- qcom,bst-pd-strength
+ Usage: optional
+ Value type: <u32>
+ Definition: Pull-down strength. Possible values are:
+ 0 - Weak pull-down
+ 1 - Strong pull-down
+
+- qcom,bst-ps
+ Usage: optional
+ Value type: <u32>
+ Definition: Pulse-skip configuration for boost. Possible values are:
+ 1 - Enable Pulse-skip
+ 0 - Disable Pulse-skip
+
+- qcom,bst-ps-threshold-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: Current threshold (in mA) at which pulse-skip is entered.
+ Possible values are 50, 60, 70, 80.
+
+- qcom,bst-ilim-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: Current limit (in mA) of the BOOST rail.
+ Possible values are 200 to 1600mA in 200mA steps.
+
+=======
+Example
+=======
+
+pm2falcon_lcdb: qpnp-lcdb@ec00 {
+ compatible = "qcom,qpnp-lcdb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec00 0x100>;
+
+ qcom,ttw-enable;
+
+ lcdb_ldo_vreg: ldo {
+ label = "ldo";
+ regulator-name = "lcdb_ldo";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,ldo-voltage-mv = <5400>;
+ qcom,ldo-pd = <1>;
+ qcom,ldo-pd-strength = <1>;
+ };
+
+ lcdb_ncp_vreg: ncp {
+ label = "ncp";
+ regulator-name = "lcdb_ncp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,ncp-voltage-mv = <5400>;
+ qcom,ncp-pd = <1>;
+ qcom,ncp-pd-strength = <1>;
+ };
+
+ lcdb_bst: bst {
+ label = "bst";
+
+ qcom,bst-pd = <1>;
+ qcom,bst-pd-strength = <1>;
+ qcom,bst-ps = <1>;
+ qcom,bst-ps-threshold-ma = <50>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index b45ee910258e..032f07535415 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -178,6 +178,7 @@ Required properties:
"vdd" : vdd supply for digital circuit operation
"vdda18" : 1.8v high-voltage analog supply
"vdda33" : 3.3v high-voltage analog supply
+ "vdda12" : 1.2v high-voltage analog supply
- qcom,vdd-voltage-level: This property must be a list of three integer
values (no, min, max) where each value represents either a voltage in
microvolts or a value corresponding to voltage corner
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/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 730b76846c9d..4d82f51be778 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -135,7 +135,10 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \
dtb-$(CONFIG_ARCH_MSMHAMSTER) += msmhamster-rumi.dtb
dtb-$(CONFIG_ARCH_MSMFALCON) += msmfalcon-sim.dtb \
- msmfalcon-rumi.dtb
+ msmfalcon-rumi.dtb \
+ msmfalcon-cdp.dtb \
+ msmfalcon-mtp.dtb \
+ msmfalcon-rcm.dtb
dtb-$(CONFIG_ARCH_MSMTRITON) += msmtriton-rumi.dtb
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/fg-gen3-batterydata-ascent-3450mah.dtsi b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-ascent-3450mah.dtsi
index 364b83320015..76f7c498d2cd 100644
--- a/arch/arm/boot/dts/qcom/fg-gen3-batterydata-ascent-3450mah.dtsi
+++ b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-ascent-3450mah.dtsi
@@ -14,7 +14,7 @@ qcom,ascent_3450mah {
/* Ascent_with_connector_3450mAh_averaged_MasterSlave_Nov28th2016 */
qcom,max-voltage-uv = <4350000>;
qcom,fg-cc-cv-threshold-mv = <4340>;
- qcom,nom-batt-capacity-mah = <3450>;
+ qcom,fastchg-current-ma = <3450>;
qcom,batt-id-kohm = <60>;
qcom,battery-beta = <3435>;
qcom,battery-type = "ascent_3450mah_averaged_masterslave_nov28th2016";
diff --git a/arch/arm/boot/dts/qcom/fg-gen3-batterydata-demo-6000mah.dtsi b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-demo-6000mah.dtsi
index b107918a8e98..bc43fb0549cb 100644
--- a/arch/arm/boot/dts/qcom/fg-gen3-batterydata-demo-6000mah.dtsi
+++ b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-demo-6000mah.dtsi
@@ -13,7 +13,7 @@
qcom,demo_6000mah {
qcom,max-voltage-uv = <4350000>;
qcom,fg-cc-cv-threshold-mv = <4340>;
- qcom,nom-batt-capacity-mah = <6000>;
+ qcom,fastchg-current-ma = <6000>;
qcom,batt-id-kohm = <75>;
qcom,battery-beta = <3435>;
qcom,battery-type = "Demo_battery_6000mah";
diff --git a/arch/arm/boot/dts/qcom/fg-gen3-batterydata-itech-3000mah.dtsi b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-itech-3000mah.dtsi
index c3f23b75fa9c..d196a8074d8a 100644
--- a/arch/arm/boot/dts/qcom/fg-gen3-batterydata-itech-3000mah.dtsi
+++ b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-itech-3000mah.dtsi
@@ -14,7 +14,7 @@ qcom,itech_3000mah {
/* #Itech_B00826LF_3000mAh_ver1660_averaged_MasterSlave_Jul20th2016*/
qcom,max-voltage-uv = <4350000>;
qcom,fg-cc-cv-threshold-mv = <4340>;
- qcom,nom-batt-capacity-mah = <3000>;
+ qcom,fastchg-current-ma = <3000>;
qcom,batt-id-kohm = <100>;
qcom,battery-beta = <3450>;
qcom,battery-type = "itech_b00826lf_3000mah_ver1660";
diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-qrd-skuk-4v4-3000mah.dtsi
index ba3b33361ba1..e023a7700437 100644
--- a/arch/arm/boot/dts/qcom/batterydata-qrd-skuk-4v4-3000mah.dtsi
+++ b/arch/arm/boot/dts/qcom/fg-gen3-batterydata-qrd-skuk-4v4-3000mah.dtsi
@@ -12,7 +12,7 @@
qcom,qrd_msm8998_skuk_3000mah {
qcom,max-voltage-uv = <4400000>;
- qcom,nom-batt-capacity-mah = <3000>;
+ qcom,fastchg-current-ma = <3000>;
qcom,batt-id-kohm = <68>;
qcom,battery-beta = <3380>;
qcom,battery-type = "qrd_msm8998_skuk_300mah";
diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-falcon.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-falcon.dtsi
index e4824418409b..ff4db75d9aff 100644
--- a/arch/arm/boot/dts/qcom/msm-arm-smmu-falcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-falcon.dtsi
@@ -13,7 +13,6 @@
#include <dt-bindings/clock/qcom,gcc-msmfalcon.h>
#include <dt-bindings/clock/qcom,mmcc-msmfalcon.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
-#include <dt-bindings/msm/msm-bus-ids.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
&soc {
@@ -61,7 +60,6 @@
};
lpass_q6_smmu: arm,smmu-lpass_q6@5100000 {
- status = "disabled";
compatible = "qcom,smmu-v2";
reg = <0x5100000 0x40000>;
#iommu-cells = <1>;
@@ -94,11 +92,11 @@
};
mmss_bimc_smmu: arm,smmu-mmss@cd00000 {
- status = "disabled";
compatible = "qcom,smmu-v2";
reg = <0xcd00000 0x40000>;
#iommu-cells = <1>;
qcom,register-save;
+ qcom,no-smr-check;
qcom,skip-init;
#global-interrupts = <2>;
interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
@@ -129,7 +127,7 @@
<GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
vdd-supply = <&gdsc_bimc_smmu>;
clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>,
- <&clock_gcc MMSSNOC_AXI_CLK>,
+ <&clock_rpmcc MMSSNOC_AXI_CLK>,
<&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>,
<&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>;
clock-names = "mmss_mnoc_ahb_clk",
@@ -137,11 +135,9 @@
"mmss_bimc_smmu_ahb_clk",
"mmss_bimc_smmu_axi_clk";
#clock-cells = <1>;
- qcom,bus-master-id = <MSM_BUS_MNOC_BIMC_MAS>;
};
kgsl_smmu: arm,smmu-kgsl@5040000 {
- status = "disabled";
compatible = "qcom,smmu-v2";
reg = <0x5040000 0x10000>;
#iommu-cells = <1>;
@@ -170,7 +166,6 @@
};
turing_q6_smmu: arm,smmu-turing_q6@5180000 {
- status = "disabled";
compatible = "qcom,smmu-v2";
reg = <0x5180000 0x40000>;
#iommu-cells = <1>;
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-lpass.dtsi b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
index eb8a7a98b6b4..067f2c35eecd 100644
--- a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
@@ -187,6 +187,11 @@
qcom,msm-dai-q6-dev-id = <16393>;
};
+ sb_4_tx_vi: qcom,msm-dai-q6-sb-4-tx-vi {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <20233>;
+ };
+
sb_5_tx: qcom,msm-dai-q6-sb-5-tx {
compatible = "qcom,msm-dai-q6-dev";
qcom,msm-dai-q6-dev-id = <16395>;
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..8ec542d953e2 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";
@@ -222,15 +222,12 @@
pm2falcon_wled: qcom,leds@d800 {
compatible = "qcom,qpnp-wled";
reg = <0xd800 0x100>,
- <0xd900 0x100>,
- <0xdc00 0x100>,
- <0xde00 0x100>;
+ <0xd900 0x100>;
reg-names = "qpnp-wled-ctrl-base",
- "qpnp-wled-sink-base",
- "qpnp-wled-ibb-base",
- "qpnp-wled-lab-base";
- interrupts = <0x3 0xd8 0x2>;
- interrupt-names = "sc-irq";
+ "qpnp-wled-sink-base";
+ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "ovp-irq", "sc-irq";
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
@@ -270,7 +267,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";
@@ -367,5 +363,26 @@
qcom,default-led-trigger = "switch1_trigger";
};
};
+
+ pm2falcon_lcdb: qpnp-lcdb@ec00 {
+ compatible = "qcom,qpnp-lcdb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec00 0x100>;
+
+ lcdb_ldo_vreg: ldo {
+ label = "ldo";
+ regulator-name = "lcdb_ldo";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ };
+
+ lcdb_ncp_vreg: ncp {
+ label = "ncp";
+ regulator-name = "lcdb_ncp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi b/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi
index dcf7030a78e4..f9a33fdc3e85 100644
--- a/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm3falcon.dtsi
@@ -14,3 +14,8 @@
&pm2falcon_wled {
status = "disabled";
};
+
+/* disable LCDB */
+&pm2falcon_lcdb {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
index 08248794ffdb..1cc31380604b 100644
--- a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
@@ -550,6 +550,20 @@
"dma-grant";
};
};
+
+ bcl@4200 {
+ compatible = "qcom,msm-bcl-lmh";
+ reg = <0x4200 0xff>,
+ <0x4300 0xff>;
+ reg-names = "fg_user_adc",
+ "fg_lmh";
+ interrupts = <0x0 0x42 0x0 IRQ_TYPE_NONE>,
+ <0x0 0x42 0x2 IRQ_TYPE_NONE>;
+ interrupt-names = "bcl-high-ibat-int",
+ "bcl-low-vbat-int";
+ qcom,vbat-polling-delay-ms = <100>;
+ qcom,ibat-polling-delay-ms = <100>;
+ };
};
qcom,pmfalcon@1 {
@@ -557,5 +571,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-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
index 725c129a28da..0dc9da9289e2 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
@@ -585,16 +585,12 @@
pmi8998_wled: qcom,leds@d800 {
compatible = "qcom,qpnp-wled";
reg = <0xd800 0x100>,
- <0xd900 0x100>,
- <0xdc00 0x100>,
- <0xde00 0x100>;
+ <0xd900 0x100>;
reg-names = "qpnp-wled-ctrl-base",
- "qpnp-wled-sink-base",
- "qpnp-wled-ibb-base",
- "qpnp-wled-lab-base";
- interrupts = <0x3 0xd8 0x2>;
- interrupt-names = "sc-irq";
- status = "okay";
+ "qpnp-wled-sink-base";
+ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x3 0xd8 0x2 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "ovp-irq", "sc-irq";
linux,name = "wled";
linux,default-trigger = "bkl-trigger";
qcom,fdbk-output = "auto";
@@ -614,6 +610,7 @@
qcom,en-ext-pfet-sc-pro;
qcom,pmic-revid = <&pmi8998_revid>;
qcom,loop-auto-gm-en;
+ status = "okay";
};
pmi8998_haptics: qcom,haptic@c000 {
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..e6e04f19d7ea
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
@@ -0,0 +1,112 @@
+/* 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";
+ smb138x: qcom,smb138x@8 {
+ compatible = "qcom,i2c-pmic";
+ reg = <0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ 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>;
+ interrupt-parent = <&smb138x>;
+ 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>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&smb138x>;
+ io-channels = <&smb138x_tadc 2>,
+ <&smb138x_tadc 12>,
+ <&smb138x_tadc 3>;
+ io-channel-names = "charger_temp",
+ "charger_temp_max",
+ "batt_i";
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog-bark";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
index 506e37c2349a..bf4cfedd7e84 100644
--- a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
@@ -53,6 +53,8 @@
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
"MADINPUT", "MCLK",
+ "hifi amp", "LINEOUT1",
+ "hifi amp", "LINEOUT2",
"AMIC2", "MIC BIAS2",
"MIC BIAS2", "Headset Mic",
"AMIC3", "MIC BIAS2",
@@ -81,6 +83,8 @@
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
qcom,us-euro-gpios = <&wcd_us_euro_gpio>;
+ qcom,hph-en0-gpio = <&hph_en0_gpio>;
+ qcom,hph-en1-gpio = <&hph_en1_gpio>;
qcom,tasha-mclk-clk-freq = <9600000>;
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
@@ -101,7 +105,8 @@
<&dai_tert_auxpcm>, <&dai_quat_auxpcm>,
<&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
<&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
- <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>,
+ <&sb_4_rx>, <&sb_4_tx>, <&sb_4_tx_vi>,
+ <&sb_5_tx>,
<&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
<&afe_proxy_tx>, <&incall_record_rx>,
<&incall_record_tx>, <&incall_music_rx>,
@@ -122,6 +127,7 @@
"msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389",
"msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
"msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.20233",
"msm-dai-q6-dev.16395", "msm-dai-q6-dev.224",
"msm-dai-q6-dev.225", "msm-dai-q6-dev.241",
"msm-dai-q6-dev.240", "msm-dai-q6-dev.32771",
@@ -142,6 +148,20 @@
<&wsa881x_213>, <&wsa881x_214>;
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
"SpkrLeft", "SpkrRight";
+
+ hph_en0_gpio: msm_cdc_pinctrl@67 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&hph_en0_active>;
+ pinctrl-1 = <&hph_en0_idle>;
+ };
+
+ hph_en1_gpio: msm_cdc_pinctrl@68 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&hph_en1_active>;
+ pinctrl-1 = <&hph_en1_idle>;
+ };
};
sound-tavil {
@@ -165,6 +185,8 @@
qcom,audio-routing =
"RX_BIAS", "MCLK",
"MADINPUT", "MCLK",
+ "hifi amp", "LINEOUT1",
+ "hifi amp", "LINEOUT2",
"AMIC2", "MIC BIAS2",
"MIC BIAS2", "Headset Mic",
"AMIC3", "MIC BIAS2",
@@ -212,7 +234,8 @@
<&dai_tert_auxpcm>, <&dai_quat_auxpcm>,
<&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
<&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
- <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>,
+ <&sb_4_rx>, <&sb_4_tx>, <&sb_4_tx_vi>,
+ <&sb_5_tx>,
<&afe_pcm_rx>, <&afe_pcm_tx>, <&afe_proxy_rx>,
<&afe_proxy_tx>, <&incall_record_rx>,
<&incall_record_tx>, <&incall_music_rx>,
@@ -233,6 +256,7 @@
"msm-dai-q6-dev.16388", "msm-dai-q6-dev.16389",
"msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
"msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.20233",
"msm-dai-q6-dev.16395", "msm-dai-q6-dev.224",
"msm-dai-q6-dev.225", "msm-dai-q6-dev.241",
"msm-dai-q6-dev.240", "msm-dai-q6-dev.32771",
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-coresight.dtsi b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi
index aeb6bf6141d8..75a90b0499e1 100644
--- a/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi
@@ -277,6 +277,14 @@
<&funnel_apss_merg_out_funnel_in1>;
};
};
+ port@6 {
+ reg = <7>;
+ funnel_in1_in_gfx: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&gfx_out_funnel_in1>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi b/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi
index 8739e8f22549..9a497a473a56 100644
--- a/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-gpu.dtsi
@@ -122,6 +122,15 @@
vddcx-supply = <&gdsc_gpu_cx>;
vdd-supply = <&gdsc_gpu_gx>;
+ /* Trace bus */
+ coresight-name = "coresight-gfx";
+ coresight-atid = <3>;
+ port {
+ gfx_out_funnel_in1: endpoint {
+ remote-endpoint = <&funnel_in1_in_gfx>;
+ };
+ };
+
/* GPU Mempools */
qcom,gpu-mempools {
#address-cells= <1>;
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..1a7f759f4b63 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,54 @@
*/
&soc {
+ tlmm: pinctrl@03400000 {
+ cam_sensor_rear_active: cam_sensor_rear_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30", "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30", "gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_suspend: cam_sensor_rear_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30", "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30", "gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+ };
+
+ 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>;
@@ -28,51 +76,75 @@
};
qcom,csid@ca30000 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30400 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30800 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30c00 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
};
&cci {
+ /delete-node/qcom,camera@0;
+ /delete-node/qcom,camera@1;
+ /delete-node/qcom,camera@2;
+ /delete-node/qcom,eeprom@0;
+ /delete-node/qcom,eeprom@1;
+ /delete-node/qcom,eeprom@2;
+ /delete-node/qcom,actuator@0;
+ /delete-node/qcom,actuator@1;
+ /delete-node/qcom,ois@0;
+};
+
+&cci {
actuator0: qcom,actuator@0 {
cell-index = <0>;
reg = <0x0>;
@@ -127,9 +199,9 @@
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,cam-vreg-min-voltage = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_active
@@ -140,8 +212,8 @@
&cam_actuator_vaf_suspend>;
gpios = <&tlmm 13 0>,
<&tlmm 30 0>,
- <&pmfalcon_gpios 4 0>,
- <&tlmm 29 0>,
+ <&pm2falcon_gpios 4 0>,
+ <&tlmm 8 0>,
<&tlmm 27 0>;
qcom,gpio-reset = <1>;
qcom,gpio-vdig = <2>;
@@ -164,6 +236,51 @@
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 = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active
+ &cam_actuator_vaf_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend
+ &cam_actuator_vaf_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&pmfalcon_gpios 3 0>,
+ <&tlmm 29 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vana = <3>;
+ qcom,gpio-vaf = <4>;
+ qcom,gpio-req-tbl-num = <0 1 2 3 4>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG",
+ "CAM_VANA",
+ "CAM_VAF";
+ 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";
@@ -178,9 +295,9 @@
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,cam-vreg-min-voltage = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_active
@@ -189,8 +306,8 @@
&cam_sensor_rear_suspend>;
gpios = <&tlmm 13 0>,
<&tlmm 30 0>,
- <&pmfalcon_gpios 4 0>,
- <&tlmm 29 0>;
+ <&pm2falcon_gpios 4 0>,
+ <&tlmm 8 0>;
qcom,gpio-reset = <1>;
qcom,gpio-vdig = <2>;
qcom,gpio-vana = <3>;
@@ -209,9 +326,54 @@
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,actuator-src = <&actuator1>;
+ qcom,eeprom-src = <&eeprom2>;
+ 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 = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 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>,
+ <&pm2falcon_gpios 3 0>,
+ <&tlmm 8 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 {
+&pm2falcon_gpios {
gpio@c300 { /* GPIO4 -CAMERA SENSOR 0 VDIG*/
qcom,mode = <1>; /* Output */
qcom,pull = <5>; /* No Pull */
@@ -221,4 +383,14 @@
qcom,master-en = <1>; /* Enable GPIO */
status = "ok";
};
+
+ gpio@c200 { /* GPIO3 -CAMERA SENSOR 2 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..1a7f759f4b63 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,54 @@
*/
&soc {
+ tlmm: pinctrl@03400000 {
+ cam_sensor_rear_active: cam_sensor_rear_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30", "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30", "gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_suspend: cam_sensor_rear_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30", "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30", "gpio8";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+ };
+
+ 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>;
@@ -28,51 +76,75 @@
};
qcom,csid@ca30000 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30400 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30800 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
qcom,csid@ca30c00 {
- qcom,csi-vdd-voltage = <1225000>;
+ qcom,csi-vdd-voltage = <1200000>;
qcom,mipi-csi-vdd-supply = <&pmfalcon_l1>;
gdscr-supply = <&gdsc_camss_top>;
vdd_sec-supply = <&pm2falcon_l1>;
bimc_smmu-supply = <&gdsc_bimc_smmu>;
qcom,cam-vreg-name = "vdd_sec", "gdscr", "bimc_smmu";
+ qcom,cam-vreg-min-voltage = <925000 0 0>;
+ qcom,cam-vreg-max-voltage = <925000 0 0>;
+ qcom,cam-vreg-op-mode = <0 0 0>;
qcom,clock-rates = <0 0 0 0 0 0 0 384000000 384000000
0 0 0 0 0>;
};
};
&cci {
+ /delete-node/qcom,camera@0;
+ /delete-node/qcom,camera@1;
+ /delete-node/qcom,camera@2;
+ /delete-node/qcom,eeprom@0;
+ /delete-node/qcom,eeprom@1;
+ /delete-node/qcom,eeprom@2;
+ /delete-node/qcom,actuator@0;
+ /delete-node/qcom,actuator@1;
+ /delete-node/qcom,ois@0;
+};
+
+&cci {
actuator0: qcom,actuator@0 {
cell-index = <0>;
reg = <0x0>;
@@ -127,9 +199,9 @@
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,cam-vreg-min-voltage = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_active
@@ -140,8 +212,8 @@
&cam_actuator_vaf_suspend>;
gpios = <&tlmm 13 0>,
<&tlmm 30 0>,
- <&pmfalcon_gpios 4 0>,
- <&tlmm 29 0>,
+ <&pm2falcon_gpios 4 0>,
+ <&tlmm 8 0>,
<&tlmm 27 0>;
qcom,gpio-reset = <1>;
qcom,gpio-vdig = <2>;
@@ -164,6 +236,51 @@
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 = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_front_active
+ &cam_actuator_vaf_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_front_suspend
+ &cam_actuator_vaf_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&pmfalcon_gpios 3 0>,
+ <&tlmm 29 0>,
+ <&tlmm 27 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-vana = <3>;
+ qcom,gpio-vaf = <4>;
+ qcom,gpio-req-tbl-num = <0 1 2 3 4>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG",
+ "CAM_VANA",
+ "CAM_VAF";
+ 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";
@@ -178,9 +295,9 @@
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,cam-vreg-min-voltage = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 80000 105000>;
qcom,gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk0_active
@@ -189,8 +306,8 @@
&cam_sensor_rear_suspend>;
gpios = <&tlmm 13 0>,
<&tlmm 30 0>,
- <&pmfalcon_gpios 4 0>,
- <&tlmm 29 0>;
+ <&pm2falcon_gpios 4 0>,
+ <&tlmm 8 0>;
qcom,gpio-reset = <1>;
qcom,gpio-vdig = <2>;
qcom,gpio-vana = <3>;
@@ -209,9 +326,54 @@
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,actuator-src = <&actuator1>;
+ qcom,eeprom-src = <&eeprom2>;
+ 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 = <1780000 3300000 1350000>;
+ qcom,cam-vreg-max-voltage = <1950000 3600000 1350000>;
+ qcom,cam-vreg-op-mode = <105000 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>,
+ <&pm2falcon_gpios 3 0>,
+ <&tlmm 8 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 {
+&pm2falcon_gpios {
gpio@c300 { /* GPIO4 -CAMERA SENSOR 0 VDIG*/
qcom,mode = <1>; /* Output */
qcom,pull = <5>; /* No Pull */
@@ -221,4 +383,14 @@
qcom,master-en = <1>; /* Enable GPIO */
status = "ok";
};
+
+ gpio@c200 { /* GPIO3 -CAMERA SENSOR 2 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..437b054a6ad0 100644
--- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-cdp.dtsi
@@ -14,6 +14,7 @@
#include "msm8998-camera-sensor-cdp.dtsi"
/ {
bluetooth: bt_wcn3990 {
+ status = "disabled";
compatible = "qca,wcn3990";
qca,bt-vdd-io-supply = <&pm8998_s3>;
qca,bt-vdd-xtal-supply = <&pm8998_s5>;
@@ -205,68 +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_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..e9c64c12c419 100644
--- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon-mtp.dtsi
@@ -15,6 +15,7 @@
#include "msm8998-camera-sensor-mtp.dtsi"
/ {
bluetooth: bt_wcn3990 {
+ status = "disabled";
compatible = "qca,wcn3990";
qca,bt-vdd-io-supply = <&pm8998_s3>;
qca,bt-vdd-xtal-supply = <&pm8998_s5>;
@@ -206,96 +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_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..6ecda1a9548d 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;
@@ -255,20 +252,3 @@
#include "msm-pmfalcon-rpm-regulator.dtsi"
#include "msm-pm2falcon-rpm-regulator.dtsi"
#include "msmfalcon-regulator.dtsi"
-
-/* dummy LCDB regulator nodes */
-&soc {
- lcdb_ldo_vreg: regulator-vdisp-vreg {
- compatible = "qcom,stub-regulator";
- regulator-name = "lcdb_ldo";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- };
-
- lcdb_ncp_vreg: regulator-vdisn-vreg {
- compatible = "qcom,stub-regulator";
- regulator-name = "lcdb_ncp";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- };
-};
diff --git a/arch/arm/boot/dts/qcom/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..d4a2290c9b0a 100644
--- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
@@ -587,6 +587,60 @@
};
};
+ hph_en0_ctrl {
+ hph_en0_idle: hph_en0_idle {
+ mux {
+ pins = "gpio67";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio67";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+ hph_en0_active: hph_en0_active {
+ mux {
+ pins = "gpio67";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio67";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
+ hph_en1_ctrl {
+ hph_en1_idle: hph_en1_idle {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio68";
+ drive-strength = <2>;
+ bias-pull-down;
+ output-low;
+ };
+ };
+ hph_en1_active: hph_en1_active {
+ mux {
+ pins = "gpio68";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio68";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
+ };
+ };
+ };
+
wcd_gnd_mic_swap {
wcd_gnd_mic_swap_idle: wcd_gnd_mic_swap_idle {
mux {
@@ -1347,14 +1401,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 +1562,7 @@
mdss_dp_usbplug_cc_active: mdss_dp_usbplug_cc_active {
mux {
pins = "gpio38";
- function = "usb_phy";
+ function = "gpio";
};
config {
@@ -1521,7 +1575,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-pm.dtsi b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi
index c6d7defbf35c..8fd75c369c53 100644
--- a/arch/arm/boot/dts/qcom/msm8998-pm.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi
@@ -343,7 +343,8 @@
<0x2 216>, /* tsens1_upper_lower_int */
<0x34 275>, /* qmp_usb3_lfps_rxterm_irq_cx */
<0x57 358>, /* spmi_periph_irq[0] */
- <0x4f 379>, /* usb2phy_intr */
+ <0x4f 379>, /* usb2phy_intr: qusb2phy_dmse_hv */
+ <0x51 379>, /* usb2phy_intr: qusb2phy_dpse_hv */
<0x50 384>, /* sp_rmb_sp2soc_irq */
<0xff 16>, /* APC0_qgicQTmrHypPhysIrptReq */
<0xff 17>, /* APC3_qgicQTmrSecPhysIrptReq */
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
index c09900597d87..dcd84e79ba1b 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
@@ -153,6 +153,24 @@
qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>;
qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft";
};
+
+ hbtp {
+ compatible = "qcom,hbtp-input";
+ pinctrl-names = "pmx_ts_active","pmx_ts_suspend";
+ pinctrl-0 = <&ts_rst_active>;
+ pinctrl-1 = <&ts_rst_suspend>;
+ vcc_ana-supply = <&pm8998_l28>;
+ vcc_dig-supply = <&pm8998_l6>;
+ qcom,afe-load = <20000>;
+ qcom,afe-vtg-min = <2850000>;
+ qcom,afe-vtg-max = <3000000>;
+ qcom,dig-load = <40000>;
+ qcom,dig-vtg-min = <1800000>;
+ qcom,dig-vtg-max = <1800000>;
+ qcom,fb-resume-delay-us = <10000>;
+ qcom,afe-power-on-delay-us = <1000>;
+ qcom,afe-power-off-delay-us = <6>;
+ };
};
&pmx_mdss {
@@ -225,8 +243,7 @@
/{
qrd_batterydata: qcom,battery-data {
qcom,batt-id-range-pct = <15>;
-
- #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ #include "fg-gen3-batterydata-qrd-skuk-4v4-3000mah.dtsi"
};
};
@@ -238,6 +255,39 @@
status = "okay";
};
+&tlmm {
+ /* add pingrp for touchscreen */
+ pmx_ts_rst_active {
+ ts_rst_active: ts_rst_active {
+ mux {
+ pins = "gpio89";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio89";
+ drive-strength = <16>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ pmx_ts_rst_suspend {
+ ts_rst_suspend: ts_rst_suspend {
+ mux {
+ pins = "gpio89";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio89";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
+};
+
&pm8998_vadc {
chan@83 {
label = "vph_pwr";
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
index bd9d8147dd82..2d1616412caa 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
@@ -159,8 +159,7 @@
/{
qrd_batterydata: qcom,battery-data {
qcom,batt-id-range-pct = <15>;
-
- #include "batterydata-qrd-skuk-4v4-3000mah.dtsi"
+ #include "fg-gen3-batterydata-qrd-skuk-4v4-3000mah.dtsi"
};
};
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..e88ee107e280 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,66 @@
parent-supply = <&pm2falcon_s3_level>;
status = "ok";
};
+
+&usb3 {
+ extcon = <&pmfalcon_pdphy>;
+};
+
+&qusb_phy0 {
+ vdd-supply = <&pm2falcon_l1>;
+ vdda18-supply = <&pmfalcon_l10>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ vdda33-supply = <&pm2falcon_l7>;
+};
+
+&ssphy {
+ vdd-supply = <&pm2falcon_l1>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ core-supply = <&pmfalcon_l1>;
+};
+
+&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..ccc94307277d 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,95 @@
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>;
+};
+
+&usb3 {
+ extcon = <&pmfalcon_pdphy>;
+};
+
+&qusb_phy0 {
+ vdd-supply = <&pm2falcon_l1>;
+ vdda18-supply = <&pmfalcon_l10>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ vdda33-supply = <&pm2falcon_l7>;
+};
+
+&ssphy {
+ vdd-supply = <&pm2falcon_l1>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ core-supply = <&pmfalcon_l1>;
+};
+
+&pm2falcon_gpios {
+ /* GPIO 7 for VOL_UP */
+ gpio@c600 {
+ status = "okay";
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <0>;
+ qcom,out-strength = <1>;
+ };
+};
+
+&soc {
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ status = "okay";
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&pm2falcon_gpios 7 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts
index ddae02812731..013c849c4936 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts
@@ -14,6 +14,9 @@
/dts-v1/;
#include "msm8998-v2.1-interposer-msmfalcon-qrd.dtsi"
+#include "msm8998-interposer-pmfalcon.dtsi"
+#include "msm8998-interposer-msmfalcon-audio.dtsi"
+#include "msm8998-interposer-camera-sensor-mtp.dtsi"
/ {
model =
@@ -41,174 +44,72 @@
};
&clock_gcc {
- /delete-property/vdd_dig-supply;
- /delete-property/vdd_dig_ao-supply;
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_dig_ao-supply = <&pm2falcon_s3_level_ao>;
};
&clock_mmss {
- /delete-property/vdd_dig-supply;
- /delete-property/vdd_mmsscc_mx-supply;
+ vdd_dig-supply = <&pm2falcon_s3_level>;
+ vdd_mmsscc_mx-supply = <&pm2falcon_s5_level>;
};
&clock_gpu {
- /delete-property/vdd_dig-supply;
+ vdd_dig-supply = <&pm2falcon_s3_level>;
};
&clock_gfx {
- /delete-property/vdd_mx-supply;
- /delete-property/vdd_gpu_mx-supply;
-};
-
-&pcie0 {
- /delete-property/vreg-1.8-supply;
- /delete-property/vreg-0.9-supply;
- /delete-property/vreg-cx-supply;
+ /* GFX Rail = CX */
+ vdd_gpucc-supply = <&pm2falcon_s3_level>;
+ vdd_mx-supply = <&pm2falcon_s5_level>;
+ vdd_gpu_mx-supply = <&pm2falcon_s5_level>;
+ qcom,gfxfreq-speedbin0 =
+ < 0 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_MIN_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_LOW_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS_PLUS
+ RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM_PLUS
+ RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO
+ RPM_SMD_REGULATOR_LEVEL_TURBO >;
+ qcom,gfxfreq-mx-speedbin0 =
+ < 0 0 >,
+ < 180000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 257000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 342000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 414000000 RPM_SMD_REGULATOR_LEVEL_SVS >,
+ < 515000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 596000000 RPM_SMD_REGULATOR_LEVEL_NOM >,
+ < 670000000 RPM_SMD_REGULATOR_LEVEL_TURBO >,
+ < 710000000 RPM_SMD_REGULATOR_LEVEL_TURBO >;
+};
+
+&gdsc_gpu_gx {
+ clock-names = "core_root_clk";
+ clocks = <&clock_gfx clk_gfx3d_clk_src>;
+ qcom,force-enable-root-clk;
+ /* GFX Rail = CX */
+ parent-supply = <&pm2falcon_s3_level>;
+ status = "ok";
};
&qusb_phy0 {
- /delete-property/vdd-supply;
- /delete-property/vdda18-supply;
- /delete-property/vdda33-supply;
+ vdd-supply = <&pm2falcon_l1>;
+ vdda18-supply = <&pmfalcon_l10>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ vdda33-supply = <&pm2falcon_l7>;
};
&ssphy {
- /delete-property/vdd-supply;
- /delete-property/core-supply;
-};
-
-&usb3 {
- /delete-property/extcon;
-};
-
-&mdss_dsi {
- /delete-property/vdda-1p2-supply;
- /delete-property/vdda-0p9-supply;
-};
-
-&mdss_dsi0 {
- /delete-property/wqhd-vddio-supply;
- /delete-property/lab-supply;
- /delete-property/ibb-supply;
-};
-
-&mdss_dsi1 {
- /delete-property/wqhd-vddio-supply;
- /delete-property/lab-supply;
- /delete-property/ibb-supply;
-};
-
-&mdss_hdmi_pll {
- /delete-property/vdda-pll-supply;
- /delete-property/vdda-phy-supply;
-};
-
-&mdss_dp_ctrl {
- /delete-property/vdda-1p2-supply;
- /delete-property/vdda-0p9-supply;
- /delete-property/qcom,dp-usbpd-detection;
-};
-
-&apc0_cpr {
- /* disable aging and closed-loop */
- /delete-property/vdd-supply;
- /delete-property/qcom,cpr-enable;
- /delete-property/qcom,cpr-hw-closed-loop;
- /delete-property/qcom,cpr-aging-ref-voltage;
-};
-
-&apc0_pwrcl_vreg {
- /delete-property/qcom,cpr-aging-max-voltage-adjustment;
- /delete-property/qcom,cpr-aging-ref-corner;
- /delete-property/qcom,cpr-aging-ro-scaling-factor;
- /delete-property/qcom,allow-aging-voltage-adjustment;
- /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
-};
-
-&apc1_cpr {
- /* disable aging and closed-loop */
- /delete-property/vdd-supply;
- /delete-property/qcom,cpr-enable;
- /delete-property/qcom,cpr-hw-closed-loop;
- /delete-property/qcom,cpr-aging-ref-voltage;
-};
-
-&apc1_perfcl_vreg {
- /delete-property/qcom,cpr-aging-max-voltage-adjustment;
- /delete-property/qcom,cpr-aging-ref-corner;
- /delete-property/qcom,cpr-aging-ro-scaling-factor;
- /delete-property/qcom,allow-aging-voltage-adjustment;
- /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
-};
-
-&gfx_cpr {
- reg = <0x05061000 0x4000>,
- <0x00784000 0x1000>;
- reg-names = "cpr_ctrl", "fuse_base";
-
- /* disable aging and closed-loop */
- /delete-property/vdd-supply;
- /delete-property/qcom,cpr-enable;
- /delete-property/qcom,cpr-aging-ref-voltage;
- /delete-property/qcom,cpr-aging-allowed-reg-mask;
- /delete-property/qcom,cpr-aging-allowed-reg-value;
-};
-
-&gfx_vreg {
- /delete-property/qcom,cpr-aging-max-voltage-adjustment;
- /delete-property/qcom,cpr-aging-ref-corner;
- /delete-property/qcom,cpr-aging-ro-scaling-factor;
- /delete-property/qcom,allow-aging-voltage-adjustment;
- /delete-property/qcom,allow-aging-open-loop-voltage-adjustment;
-};
-
-&clock_audio {
- /delete-property/qcom,audio-ref-clk-gpio;
+ vdd-supply = <&pm2falcon_l1>;
+ qcom,vdd-voltage-level = <0 925000 925000>;
+ core-supply = <&pmfalcon_l1>;
};
-
-&soc {
- /delete-node/qcom,csid@ca30000;
- /delete-node/qcom,csid@ca30400;
- /delete-node/qcom,csid@ca30800;
- /delete-node/qcom,csid@ca30c00;
-
- /delete-node/qcom,lpass@17300000;
- /delete-node/qcom,mss@4080000;
- /delete-node/qcom,spss@1d00000;
- /delete-node/qcom,bcl;
- /delete-node/qcom,msm-thermal;
- /delete-node/qcom,ssc@5c00000;
- /delete-node/qcom,icnss@18800000;
- /delete-node/qcom,wil6210;
- /delete-node/qcom,rpm-smd;
- /delete-node/qcom,spmi@800f000;
-
-
- rpm_bus: qcom,rpm-smd {
- compatible = "qcom,rpm-glink";
- qcom,glink-edge = "rpm";
- rpm-channel-name = "rpm_requests";
- };
-
- spmi_bus: qcom,spmi@800f000 {
- compatible = "qcom,spmi-pmic-arb";
- reg = <0x800f000 0x1000>,
- <0x8400000 0x1000000>,
- <0x9400000 0x1000000>,
- <0xa400000 0x220000>,
- <0x800a000 0x3000>;
- reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
- interrupt-names = "periph_irq";
- interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>;
- qcom,ee = <0>;
- qcom,channel = <0>;
- #address-cells = <2>;
- #size-cells = <0>;
- interrupt-controller;
- #interrupt-cells = <4>;
- cell-index = <0>;
- };
-};
-
-#include "msm-pmfalcon.dtsi"
-#include "msm-pm2falcon.dtsi"
-#include "msmfalcon-regulator.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi
index 0c49c4246f10..83368136a8b3 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi
@@ -12,6 +12,35 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include "msm8998-v2.1-interposer-msmfalcon.dtsi"
+#include "msm8998-camera-sensor-mtp.dtsi"
+
+/ {
+ bluetooth: bt_wcn3990 {
+ status = "disabled";
+ compatible = "qca,wcn3990";
+ qca,bt-vdd-io-supply = <&pmfalcon_l13>;
+ qca,bt-vdd-xtal-supply = <&pmfalcon_l9>;
+ qca,bt-vdd-core-supply = <&pmfalcon_l9>;
+ qca,bt-vdd-pa-supply = <&pmfalcon_l6>;
+ qca,bt-vdd-ldo-supply = <&pmfalcon_l19>;
+ qca,bt-chip-pwd-supply = <&pm2falcon_bob_pin1>;
+ clocks = <&clock_gcc clk_rf_clk2>;
+ clock-names = "rf_clk2";
+
+ qca,bt-vdd-io-voltage-level = <1800000 1800000>;
+ qca,bt-vdd-xtal-voltage-level = <1800000 1800000>;
+ qca,bt-vdd-core-voltage-level = <1800000 1800000>;
+ qca,bt-vdd-pa-voltage-level = <1304000 1304000>;
+ qca,bt-vdd-ldo-voltage-level = <3312000 3312000>;
+ qca,bt-chip-pwd-voltage-level = <3600000 3600000>;
+
+ qca,bt-vdd-io-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-xtal-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
+ };
+};
&uartblsp2dm1 {
status = "ok";
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..c265eafcdd30 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -1762,6 +1762,7 @@
reg-names = "qusb_phy_base",
"tcsr_clamp_dig_n_1p8";
vdd-supply = <&pm8998_l1>;
+ vdda12-supply = <&pm8998_l2>;
vdda18-supply = <&pm8998_l12>;
vdda33-supply = <&pm8998_l24>;
qcom,vdd-voltage-level = <0 880000 880000>;
@@ -3200,3 +3201,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-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts
new file mode 100644
index 000000000000..76fa0bbc0fe8
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts
@@ -0,0 +1,23 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "msmfalcon.dtsi"
+#include "msmfalcon-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM FALCON CDP";
+ compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp";
+ qcom,board-id = <1 0>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi
new file mode 100644
index 000000000000..3ec991b82bba
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi
@@ -0,0 +1,24 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msmfalcon-pinctrl.dtsi"
+/ {
+};
+
+&uartblsp1dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
+
+&soc {
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi
index b3be67bd8c32..334158ea285a 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-common.dtsi
@@ -35,17 +35,22 @@
<61 512 240000 800000>;
qcom,dwc-usb3-msm-tx-fifo-size = <21288>;
+ extcon = <&pmfalcon_pdphy>;
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";
+
+ qcom,core-clk-rate = <133330000>;
resets = <&clock_gcc GCC_USB_30_BCR>;
reset-names = "core_reset";
@@ -57,7 +62,6 @@
interrupts = <0 131 0>;
usb-phy = <&qusb_phy0>, <&ssphy>;
tx-fifo-resize;
- snps,usb3-u1u2-disable;
snps,nominal-elastic-buffer;
snps,is-utmi-l1-suspend;
snps,hird-threshold = /bits/ 8 <0x0>;
@@ -70,7 +74,7 @@
interrupts = <0 132 0>;
qcom,bam-type = <0>;
- qcom,usb-bam-fifo-baseaddr = <0x066bb000>;
+ qcom,usb-bam-fifo-baseaddr = <0x146bb000>;
qcom,usb-bam-num-pipes = <8>;
qcom,ignore-core-reset-ack;
qcom,disable-clk-gating;
@@ -129,16 +133,15 @@
qusb_phy0: qusb@c012000 {
compatible = "qcom,qusb2phy";
reg = <0x0c012000 0x180>,
+ <0x01fcb24c 0x4>,
<0x00188018 0x4>;
reg-names = "qusb_phy_base",
+ "tcsr_clamp_dig_n_1p8",
"ref_clk_addr";
vdd-supply = <&pm2falcon_l1>;
vdda18-supply = <&pmfalcon_l10>;
vdda33-supply = <&pm2falcon_l7>;
qcom,vdd-voltage-level = <0 925000 925000>;
- qcom,tune2-efuse-bit-pos = <21>;
- qcom,tune2-efuse-num-bits = <4>;
- qcom,enable-dpdm-pulsing;
qcom,qusb-phy-init-seq = <0xf8 0x80
0xb3 0x84
0x83 0x88
@@ -150,6 +153,8 @@
0x9f 0x1c
0x00 0x18>;
phy_type= "utmi";
+ qcom,phy-clk-scheme = "cml";
+ qcom,major-rev = <1>;
clocks = <&clock_rpmcc RPM_LN_BB_CLK1>,
<&clock_gcc GCC_RX0_USB2_CLKREF_CLK>,
@@ -163,7 +168,7 @@
ssphy: ssphy@c010000 {
compatible = "qcom,usb-ssphy-qmp-v2";
- reg = <0xc010000 0x7a8>,
+ reg = <0xc010000 0xe18>,
<0x01fcb244 0x4>,
<0x01fcb248 0x4>;
reg-names = "qmp_phy_base",
@@ -172,8 +177,18 @@
vdd-supply = <&pm2falcon_l1>;
core-supply = <&pmfalcon_l10>;
qcom,vdd-voltage-level = <0 925000 925000>;
+ vdd-core-voltage-level = <0 1800000 1800000>;
qcom,vbus-valid-override;
+ qcom,qmp-phy-reg-offset =
+ <0xd74 /* USB3_PHY_PCS_STATUS */
+ 0xcd8 /* USB3_PHY_AUTONOMOUS_MODE_CTRL */
+ 0xcdc /* USB3_PHY_LFPS_RXTERM_IRQ_CLEAR */
+ 0xc04 /* USB3_PHY_POWER_DOWN_CONTROL */
+ 0xc00 /* USB3_PHY_SW_RESET */
+ 0xc08 /* USB3_PHY_START */
+ 0xa00>; /* USB3PHY_PCS_MISC_TYPEC_CTRL */
+
clocks = <&clock_gcc GCC_USB3_PHY_AUX_CLK>,
<&clock_gcc GCC_USB3_PHY_PIPE_CLK>,
<&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
@@ -188,6 +203,13 @@
reset-names = "phy_reset", "phy_phy_reset";
};
+ usb_audio_qmi_dev {
+ compatible = "qcom,usb-audio-qmi-dev";
+ iommus = <&lpass_q6_smmu 6>;
+ qcom,usb-audio-stream-id = <6>;
+ qcom,usb-audio-intr-num = <2>;
+ };
+
dbm_1p5: dbm@a8f8000 {
compatible = "qcom,usb-dbm-1p5";
reg = <0xa8f8000 0x300>;
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..111eca7aef22
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-gpu.dtsi
@@ -0,0 +1,253 @@
+/* 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>;
+
+ /* GPU Mempools */
+ qcom,gpu-mempools {
+ #address-cells= <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-mempools";
+
+ qcom,mempool-max-pages = <32768>;
+
+ /* 4K Page Pool configuration */
+ qcom,gpu-mempool@0 {
+ reg = <0>;
+ qcom,mempool-page-size = <4096>;
+ };
+ /* 64K Page Pool configuration */
+ qcom,gpu-mempool@1 {
+ reg = <1>;
+ qcom,mempool-page-size = <65536>;
+ };
+ };
+
+ /* 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-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts
new file mode 100644
index 000000000000..1d4aaa2333cb
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts
@@ -0,0 +1,23 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "msmfalcon.dtsi"
+#include "msmfalcon-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM FALCON MTP";
+ compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp";
+ qcom,board-id = <8 0>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi
new file mode 100644
index 000000000000..3ec991b82bba
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi
@@ -0,0 +1,24 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msmfalcon-pinctrl.dtsi"
+/ {
+};
+
+&uartblsp1dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
+
+&soc {
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
index a029d8689111..6951cdf96815 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi
@@ -760,5 +760,33 @@
bias-disable;
};
};
+
+ tlmm_gpio_key {
+ gpio_key_active: gpio_key_active {
+ mux {
+ pins = "gpio64", "gpio113";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio64", "gpio113";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ gpio_key_suspend: gpio_key_suspend {
+ mux {
+ pins = "gpio64", "gpio113";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio64", "gpio113";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pm.dtsi
new file mode 100644
index 000000000000..39c766613b30
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-pm.dtsi
@@ -0,0 +1,821 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&soc {
+ qcom,spm@178120000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x17812000 0x1000>;
+ qcom,name = "gold-l2"; /* Gold L2 SAW */
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,cpu-vctl-list = <&CPU4 &CPU5 &CPU6 &CPU7>;
+ qcom,vctl-timeout-us = <500>;
+ qcom,vctl-port = <0x0>;
+ qcom,phase-port = <0x1>;
+ qcom,saw2-avs-ctl = <0x1010031>;
+ qcom,saw2-avs-limit = <0x4580458>;
+ qcom,pfm-port = <0x2>;
+ };
+
+ qcom,spm@179120000 {
+ compatible = "qcom,spm-v2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x17912000 0x1000>;
+ qcom,name = "silver-l2"; /* Silver L2 SAW */
+ qcom,saw2-ver-reg = <0xfd0>;
+ qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>;
+ qcom,vctl-timeout-us = <500>;
+ qcom,vctl-port = <0x0>;
+ qcom,phase-port = <0x1>;
+ qcom,saw2-avs-ctl = <0x1010031>;
+ qcom,saw2-avs-limit = <0x4580458>;
+ qcom,pfm-port = <0x2>;
+ };
+
+ qcom,lpm-levels {
+ compatible = "qcom,lpm-levels";
+ qcom,use-psci;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,pm-cluster@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ label = "system";
+ qcom,spm-device-names = "cci";
+ qcom,psci-mode-shift = <8>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cluster-level@0{
+ reg = <0>;
+ label = "system-wfi";
+ qcom,psci-mode = <0x0>;
+ qcom,latency-us = <100>;
+ qcom,ss-power = <725>;
+ qcom,energy-overhead = <85000>;
+ qcom,time-overhead = <120>;
+ };
+
+ qcom,pm-cluster-level@1{ /* E3 */
+ reg = <1>;
+ label = "system-pc";
+ qcom,psci-mode = <0x3>;
+ qcom,latency-us = <350>;
+ qcom,ss-power = <530>;
+ qcom,energy-overhead = <160000>;
+ qcom,time-overhead = <550>;
+ qcom,min-child-idx = <3>;
+ qcom,is-reset;
+ qcom,notify-rpm;
+ };
+
+ qcom,pm-cluster@0{
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ label = "pwr";
+ qcom,spm-device-names = "l2";
+ qcom,cpu = <&CPU0 &CPU1 &CPU2 &CPU3>;
+ qcom,psci-mode-shift = <4>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cluster-level@0{ /* D1 */
+ reg = <0>;
+ label = "pwr-l2-wfi";
+ qcom,psci-mode = <0x1>;
+ qcom,latency-us = <40>;
+ qcom,ss-power = <740>;
+ qcom,energy-overhead = <65000>;
+ qcom,time-overhead = <85>;
+ };
+ qcom,pm-cluster-level@1{ /* D2D */
+ reg = <1>;
+ label = "pwr-l2-dynret";
+ qcom,psci-mode = <0x2>;
+ qcom,latency-us = <60>;
+ qcom,ss-power = <700>;
+ qcom,energy-overhead = <85000>;
+ qcom,time-overhead = <85>;
+ qcom,min-child-idx = <1>;
+ };
+
+ qcom,pm-cluster-level@2{ /* D2E */
+ reg = <2>;
+ label = "pwr-l2-ret";
+ qcom,psci-mode = <0x3>;
+ qcom,latency-us = <100>;
+ qcom,ss-power = <640>;
+ qcom,energy-overhead = <135000>;
+ qcom,time-overhead = <85>;
+ qcom,min-child-idx = <2>;
+ };
+
+ qcom,pm-cluster-level@3{ /* D4 */
+ reg = <3>;
+ label = "pwr-l2-pc";
+ qcom,psci-mode = <0x4>;
+ qcom,latency-us = <700>;
+ qcom,ss-power = <450>;
+ qcom,energy-overhead = <210000>;
+ qcom,time-overhead = <11500>;
+ qcom,min-child-idx = <2>;
+ qcom,is-reset;
+ };
+
+ qcom,pm-cpu {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,psci-mode-shift = <0>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cpu-level@0 { /* C1 */
+ reg = <0>;
+ qcom,spm-cpu-mode = "wfi";
+ qcom,psci-cpu-mode = <0x1>;
+ qcom,latency-us = <20>;
+ qcom,ss-power = <750>;
+ qcom,energy-overhead = <32000>;
+ qcom,time-overhead = <60>;
+ };
+
+ qcom,pm-cpu-level@1 { /* C2D */
+ reg = <1>;
+ qcom,psci-cpu-mode = <2>;
+ qcom,spm-cpu-mode = "ret";
+ qcom,latency-us = <40>;
+ qcom,ss-power = <730>;
+ qcom,energy-overhead = <85500>;
+ qcom,time-overhead = <110>;
+ };
+
+ qcom,pm-cpu-level@2 { /* C3 */
+ reg = <2>;
+ qcom,spm-cpu-mode = "pc";
+ qcom,psci-cpu-mode = <0x3>;
+ qcom,latency-us = <80>;
+ qcom,ss-power = <700>;
+ qcom,energy-overhead = <126480>;
+ qcom,time-overhead = <160>;
+ qcom,is-reset;
+ };
+ };
+ };
+
+ qcom,pm-cluster@1{
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ label = "perf";
+ qcom,spm-device-names = "l2";
+ qcom,cpu = <&CPU4 &CPU5 &CPU6 &CPU7>;
+ qcom,psci-mode-shift = <4>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cluster-level@0{ /* D1 */
+ reg = <0>;
+ label = "perf-l2-wfi";
+ qcom,psci-mode = <0x1>;
+ qcom,latency-us = <40>;
+ qcom,ss-power = <740>;
+ qcom,energy-overhead = <70000>;
+ qcom,time-overhead = <80>;
+ };
+
+ qcom,pm-cluster-level@1{ /* D2D */
+ reg = <1>;
+ label = "perf-l2-dynret";
+ qcom,psci-mode = <2>;
+ qcom,latency-us = <60>;
+ qcom,ss-power = <700>;
+ qcom,energy-overhead = <85000>;
+ qcom,time-overhead = <85>;
+ qcom,min-child-idx = <1>;
+ };
+
+ qcom,pm-cluster-level@2{ /* D2E */
+ reg = <2>;
+ label = "perf-l2-ret";
+ qcom,psci-mode = <3>;
+ qcom,latency-us = <100>;
+ qcom,ss-power = <640>;
+ qcom,energy-overhead = <135000>;
+ qcom,time-overhead = <85>;
+ qcom,min-child-idx = <2>;
+ };
+
+ qcom,pm-cluster-level@3{ /* D4 */
+ reg = <3>;
+ label = "perf-l2-pc";
+ qcom,psci-mode = <0x4>;
+ qcom,latency-us = <800>;
+ qcom,ss-power = <450>;
+ qcom,energy-overhead = <240000>;
+ qcom,time-overhead = <11500>;
+ qcom,min-child-idx = <2>;
+ qcom,is-reset;
+ };
+
+ qcom,pm-cpu {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,psci-mode-shift = <0>;
+ qcom,psci-mode-mask = <0xf>;
+
+ qcom,pm-cpu-level@0 { /* C1 */
+ reg = <0>;
+ qcom,spm-cpu-mode = "wfi";
+ qcom,psci-cpu-mode = <0x1>;
+ qcom,latency-us = <25>;
+ qcom,ss-power = <750>;
+ qcom,energy-overhead = <37000>;
+ qcom,time-overhead = <50>;
+ };
+
+ qcom,pm-cpu-level@1 { /* C2D */
+ reg = <1>;
+ qcom,psci-cpu-mode = <2>;
+ qcom,spm-cpu-mode = "ret";
+ qcom,latency-us = <40>;
+ qcom,ss-power = <730>;
+ qcom,energy-overhead = <85500>;
+ qcom,time-overhead = <110>;
+ };
+
+ qcom,pm-cpu-level@2 { /* C3 */
+ reg = <2>;
+ qcom,spm-cpu-mode = "pc";
+ qcom,psci-cpu-mode = <0x3>;
+ qcom,latency-us = <80>;
+ qcom,ss-power = <700>;
+ qcom,energy-overhead = <136480>;
+ qcom,time-overhead = <160>;
+ qcom,is-reset;
+ };
+ };
+ };
+ };
+ };
+
+ qcom,rpm-stats@200000 {
+ compatible = "qcom,rpm-stats";
+ reg = <0x200000 0x1000>,
+ <0x290014 0x4>,
+ <0x29001c 0x4>;
+ reg-names = "phys_addr_base",
+ "offset_addr",
+ "heap_phys_addrbase";
+ qcom,sleep-stats-version = <2>;
+ };
+
+ qcom,rpm-rail-stats@200000 {
+ compatible = "qcom,rpm-rail-stats";
+ reg = <0x200000 0x100>,
+ <0x29000c 0x4>;
+ reg-names = "phys_addr_base",
+ "offset_addr";
+ };
+
+ qcom,rpm-log@200000 {
+ compatible = "qcom,rpm-log";
+ reg = <0x200000 0x4000>,
+ <0x290018 0x4>;
+ qcom,rpm-addr-phys = <0x200000>;
+ qcom,offset-version = <4>;
+ qcom,offset-page-buffer-addr = <36>;
+ qcom,offset-log-len = <40>;
+ qcom,offset-log-len-mask = <44>;
+ qcom,offset-page-indices = <56>;
+ };
+
+ qcom,rpm-master-stats@778150 {
+ compatible = "qcom,rpm-master-stats";
+ reg = <0x778150 0x5000>;
+ qcom,masters = "APSS", "MPSS", "ADSP", "CDSP", "TZ";
+ qcom,master-stats-version = <2>;
+ qcom,master-offset = <4096>;
+ };
+
+ rpm_msg_ram: memory@0x200000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0x200000 0x1000>,
+ <0x290000 0x1000>;
+ };
+
+ rpm_code_ram: rpm-memory@0x778000 {
+ compatible = "qcom,rpm-code-ram";
+ reg = <0x778000 0x5000>;
+ };
+
+ qcom,system-stats {
+ compatible = "qcom,system-stats";
+ qcom,rpm-msg-ram = <&rpm_msg_ram>;
+ qcom,rpm-code-ram = <&rpm_code_ram>;
+ qcom,masters = "APSS", "MPSS", "ADSP", "CDSP", "TZ";
+ };
+
+ qcom,mpm@7781b8 {
+ compatible = "qcom,mpm-v2";
+ reg = <0x7781b8 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+ <0x17911008 0x4>; /* MSM_APCS_GCC_BASE 4K */
+ reg-names = "vmpm", "ipc";
+ interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clock_rpmcc CXO_LPM_CLK>;
+ clock-names = "xo";
+ qcom,num-mpm-irqs = <96>;
+
+ qcom,ipc-bit-offset = <1>;
+
+ qcom,gic-parent = <&intc>;
+ qcom,gic-map =
+ <0x02 216>, /* tsens1_tsens_upper_lower_int */
+ <0x31 212>, /* usb30_power_event_irq */
+ <0x34 275>, /* qmp_usb3_lfps_rxterm_irq_cx */
+ <0x4f 379>, /* qusb2phy_intr */
+ <0x57 358>, /* ee0_apps_hlos_spmi_periph_irq */
+ <0xff 16>, /* APC[0-7]_qgicQTmrHypPhysIrptReq */
+ <0xff 17>, /* APC[0-7]_qgicQTmrSecPhysIrptReq */
+ <0xff 18>, /* APC[0-7]_qgicQTmrNonSecPhysIrptReq */
+ <0xff 19>, /* APC[0-7]_qgicQTmrVirtIrptReq */
+ <0xff 20>, /* APC[0-7]_dbgCommRxFull */
+ <0xff 21>, /* APC[0-7]_dbgCommTxEmpty */
+ <0xff 22>, /* APC[0-7]_qgicPerfMonIrptReq */
+ <0xff 23>, /* corespm_vote_int[0-7] */
+ <0xff 24>, /* APC[0-3]_qgicExtFaultIrptReq */
+ <0xff 28>, /* qgicWakeupSync[0-7] */
+ <0xff 29>, /* APCC_cti_SPI_intx[0-7] */
+ <0xff 30>, /* APCC_cti_SPI_inty[0-7] */
+ <0xff 32>, /* l2spm_vote_int[0] */
+ <0xff 33>, /* l2spm_vote_int[1] */
+ <0xff 34>, /* APCC_qgicL2ErrorIrptReq */
+ <0xff 35>, /* WDT_barkInt */
+ <0xff 36>, /* WDT_biteExpired */
+ <0xff 39>, /* QTMR_qgicFrm0VirtIrq */
+ <0xff 40>, /* QTMR_qgicFrm0PhyIrq */
+ <0xff 41>, /* QTMR_qgicFrm1PhyIrq */
+ <0xff 42>, /* QTMR_qgicFrm2PhyIrq */
+ <0xff 43>, /* QTMR_qgicFrm3PhyIrq */
+ <0xff 44>, /* QTMR_qgicFrm4PhyIrq */
+ <0xff 45>, /* QTMR_qgicFrm5PhyIrq */
+ <0xff 46>, /* QTMR_qgicFrm6PhyIrq */
+ <0xff 47>, /* rbif_Irq[0] */
+ <0xff 48>, /* rbif_Irq[1] */
+ <0xff 49>, /* rbif_Irq[2] */
+ <0xff 50>, /* rbif_Irq[3] */
+ <0xff 51>, /* rbif_Irq[4] */
+ <0xff 52>, /* cci_spm_vote_summary_int */
+ <0xff 54>, /* nERRORIRQ */
+ <0xff 55>, /* nEVNTCNTOVERFLOW_cci */
+ <0xff 56>, /* QTMR_qgicFrm0VirtIrq */
+ <0xff 57>, /* QTMR_qgicFrm0PhyIrq */
+ <0xff 58>, /* QTMR_qgicFrm1PhyIrq */
+ <0xff 59>, /* QTMR_qgicFrm2PhyIrq */
+ <0xff 60>, /* QTMR_qgicFrm3PhyIrq */
+ <0xff 61>, /* QTMR_qgicFrm4PhyIrq */
+ <0xff 62>, /* QTMR_qgicFrm5PhyIrq */
+ <0xff 63>, /* QTMR_qgicFrm6PhyIrq */
+ <0xff 64>, /* wakeup_counter_irq_OR */
+ <0xff 65>, /* APC[0-3]_vs_alarm */
+ <0xff 66>, /* apc1_vs_alarm */
+ <0xff 67>, /* o_pwr_osm_irq */
+ <0xff 68>, /* o_perf_osm_irq */
+ <0xff 69>, /* o_pwr_dcvsh_interrupt */
+ <0xff 70>, /* o_perf_dcvsh_interrupt */
+ <0xff 73>, /* L2_EXTERRIRQ_C0 */
+ <0xff 74>, /* L2_EXTERRIRQ_C1 */
+ <0xff 75>, /* L2_INTERRIRQ_C0 */
+ <0xff 76>, /* L2_INTERRIRQ_C1 */
+ <0xff 77>, /* L2SPM_svicInt[0] */
+ <0xff 78>, /* L2SPM_svicInt[1] */
+ <0xff 79>, /* L2SPM_svicIntSwDone[0] */
+ <0xff 80>, /* L2SPM_svicIntSwDone[1] */
+ <0xff 81>, /* l2_avs_err[0] */
+ <0xff 82>, /* l2_avs_err[1] */
+ <0xff 83>, /* l2_avs_ack[0] */
+ <0xff 84>, /* l2_avs_ack[1] */
+ <0xff 98>, /* o_qm_interrupt */
+ <0xff 100>, /* camss_vbif_1_irpt */
+ <0xff 101>, /* processor_1_user_int */
+ <0xff 102>, /* processor_1_kernel_int */
+ <0xff 106>, /* dir_conn_irq_lpa_dsp[2] */
+ <0xff 107>, /* dir_conn_irq_lpa_dsp[1] */
+ <0xff 109>, /* camss_vbif_0_irpt */
+ <0xff 110>, /* csiphy_0_irq */
+ <0xff 111>, /* csiphy_1_irq */
+ <0xff 112>, /* csiphy_2_irq */
+ <0xff 115>, /* mdss_irq */
+ <0xff 116>, /* mdss_vbif_irpt */
+ <0xff 117>, /* dir_conn_irq_lpa_dsp[0] */
+ <0xff 119>, /* lpass_irq_out_apcs[11] */
+ <0xff 122>, /* o_pimem_tpdm_bc_irq_ofsat */
+ <0xff 123>, /* o_pimem_tpdm_tc_irq_ofsat */
+ <0xff 124>, /* dir_conn_irq_sensors[1] */
+ <0xff 125>, /* dir_conn_irq_sensors[0] */
+ <0xff 127>, /* peripheral_irq[2] */
+ <0xff 128>, /* peripheral_irq[3] */
+ <0xff 129>, /* peripheral_irq[4] */
+ <0xff 130>, /* peripheral_irq[5] */
+ <0xff 133>, /* peripheral_irq[2] */
+ <0xff 134>, /* peripheral_irq[3] */
+ <0xff 135>, /* peripheral_irq[4] */
+ <0xff 136>, /* peripheral_irq[5] */
+ <0xff 139>, /* peripheral_irq[0] */
+ <0xff 140>, /* peripheral_irq[1] */
+ <0xff 142>, /* sdcc_irq[0] */
+ <0xff 143>, /* sdcc_irq[1] */
+ <0xff 144>, /* sdcc_pwr_cmd_irq */
+ <0xff 145>, /* peripheral_irq[0] */
+ <0xff 146>, /* peripheral_irq[1] */
+ <0xff 148>, /* osmmu_CIrpt[4] */
+ <0xff 149>, /* osmmu_CIrpt[5] */
+ <0xff 150>, /* sdio_wakeup_irq */
+ <0xff 151>, /* acvremoval_int */
+ <0xff 152>, /* trs_int */
+ <0xff 155>, /* dir_conn_irq_lpa_dsp[5] */
+ <0xff 156>, /* dir_conn_irq_lpa_dsp[4] */
+ <0xff 157>, /* sdcc_irq[0] */
+ <0xff 158>, /* sdcc_irq[1] */
+ <0xff 159>, /* lpass_irq_out_apcs[39] */
+ <0xff 160>, /* lpass_irq_out_apcs[38] */
+ <0xff 163>, /* usb30_ctrl_irq[0] */
+ <0xff 164>, /* usb30_bam_irq[0] */
+ <0xff 165>, /* usb30_hs_phy_irq */
+ <0xff 166>, /* o_lm_int_2qgic */
+ <0xff 169>, /* lpass_irq_out_apcs[33] */
+ <0xff 171>, /* usb20s_hs_phy_irq */
+ <0xff 172>, /* dcvs_int[6] */
+ <0xff 173>, /* dcvs_int[7] */
+ <0xff 175>, /* usb20s_ee1_irq */
+ <0xff 176>, /* usb20s_power_event_irq */
+ <0xff 184>, /* dir_conn_irq_lpa_dsp[3] */
+ <0xff 185>, /* camss_vbif_2_irpt */
+ <0xff 186>, /* mnoc_obs_mainfault */
+ <0xff 188>, /* lpass_irq_out_apcs[00] */
+ <0xff 189>, /* lpass_irq_out_apcs[01] */
+ <0xff 190>, /* lpass_irq_out_apcs[02] */
+ <0xff 191>, /* lpass_irq_out_apcs[03] */
+ <0xff 192>, /* lpass_irq_out_apcs[04] */
+ <0xff 193>, /* lpass_irq_out_apcs[05] */
+ <0xff 194>, /* lpass_irq_out_apcs[06] */
+ <0xff 195>, /* lpass_irq_out_apcs[07] */
+ <0xff 196>, /* lpass_irq_out_apcs[08] */
+ <0xff 197>, /* lpass_irq_out_apcs[09] */
+ <0xff 199>, /* qdss_usb_trace_bam_irq[0] */
+ <0xff 200>, /* rpm_ipc[4] */
+ <0xff 201>, /* rpm_ipc[5] */
+ <0xff 202>, /* rpm_ipc[6] */
+ <0xff 203>, /* rpm_ipc[7] */
+ <0xff 204>, /* rpm_ipc[20] */
+ <0xff 205>, /* rpm_ipc[21] */
+ <0xff 206>, /* rpm_ipc[22] */
+ <0xff 207>, /* rpm_ipc[23] */
+ <0xff 208>, /* lpi_dir_conn_irq_apps[0] */
+ <0xff 209>, /* lpi_dir_conn_irq_apps[1] */
+ <0xff 210>, /* lpi_dir_conn_irq_apps[2] */
+ <0xff 213>, /* secure_wdog_bark_irq */
+ <0xff 214>, /* tsens1_tsens_max_min_int */
+ <0xff 215>, /* o_bimc_intr[0] */
+ <0xff 217>, /* o_ocimem_nonsec_irq */
+ <0xff 218>, /* cpr_irq[1] */
+ <0xff 219>, /* lpass_irq_out_vmm[00] */
+ <0xff 220>, /* spmi_protocol_irq */
+ <0xff 221>, /* lpass_irq_out_vmm[01] */
+ <0xff 222>, /* lpass_irq_out_vmm[02] */
+ <0xff 223>, /* spdm_offline_irq */
+ <0xff 224>, /* spdm_realtime_irq[1] */
+ <0xff 225>, /* snoc_obs_mainFault */
+ <0xff 226>, /* cnoc_obs_mainFault */
+ <0xff 227>, /* o_tcsr_xpu3_sec_summary_intr */
+ <0xff 228>, /* o_tcsr_xpu3_non_sec_summary_intr */
+ <0xff 229>, /* o_timeout_slave_hmss_summary_intr */
+ <0xff 230>, /* o_tcsr_vmidmt_client_sec_summary_intr */
+ <0xff 231>, /* o_tcsr_vmidmt_client_nsec_summary_intr */
+ <0xff 232>, /* o_tcsr_vmidmt_cfg_sec_summary_intr */
+ <0xff 233>, /* o_tcsr_vmidmt_cfg_non_sec_summary_intr */
+ <0xff 234>, /* lpass_irq_out_vmm[03] */
+ <0xff 235>, /* cpr_irq[0] */
+ <0xff 236>, /* crypto_core_irq[0] */
+ <0xff 237>, /* crypto_core_irq[1] */
+ <0xff 238>, /* crypto_bam_irq[0] */
+ <0xff 239>, /* crypto_bam_irq[1] */
+ <0xff 240>, /* summary_irq_hmss */
+ <0xff 241>, /* dir_conn_irq_hmss[7] */
+ <0xff 242>, /* dir_conn_irq_hmss[6] */
+ <0xff 243>, /* dir_conn_irq_hmss[5] */
+ <0xff 244>, /* dir_conn_irq_hmss[4] */
+ <0xff 245>, /* dir_conn_irq_hmss[3] */
+ <0xff 246>, /* dir_conn_irq_hmss[2] */
+ <0xff 247>, /* dir_conn_irq_hmss[1] */
+ <0xff 248>, /* dir_conn_irq_hmss[0] */
+ <0xff 249>, /* summary_irq_hmss_tz */
+ <0xff 250>, /* cpr_irq[3] */
+ <0xff 251>, /* cpr_irq[2] */
+ <0xff 252>, /* cpr_irq[1] */
+ <0xff 253>, /* sdcc_pwr_cmd_irq */
+ <0xff 254>, /* sdio_wakeup_irq */
+ <0xff 255>, /* cpr_irq[0] */
+ <0xff 256>, /* lpass_irq_out_apcs[34] */
+ <0xff 257>, /* lpass_irq_out_apcs[35] */
+ <0xff 258>, /* lpass_irq_out_apcs[21] */
+ <0xff 261>, /* o_tcsr_mmu_nsgcfglrpt_summary_intr */
+ <0xff 262>, /* o_tcsr_mmu_gcfglrpt_summary_intr */
+ <0xff 263>, /* o_tcsr_mmu_nsglrpt_summary_intr */
+ <0xff 264>, /* o_tcsr_mmu_glrpt_summary_intr */
+ <0xff 265>, /* vbif_irpt */
+ <0xff 266>, /* lpass_irq_out_apcs[20] */
+ <0xff 267>, /* lpass_irq_out_apcs[19] */
+ <0xff 269>, /* rpm_wdog_expired_irq */
+ <0xff 270>, /* bam_irq[0] */
+ <0xff 271>, /* bam_irq[0] */
+ <0xff 276>, /* mmss_bimc_smmu_cirpt[4] */
+ <0xff 277>, /* mmss_bimc_smmu_cirpt[5] */
+ <0xff 278>, /* usb30_ctrl_irq[1] */
+ <0xff 279>, /* mmss_bimc_smmu_cirpt[6] */
+ <0xff 280>, /* mmss_bimc_smmu_cirpt[7] */
+ <0xff 281>, /* mmss_bimc_smmu_cirpt[8] */
+ <0xff 282>, /* mmss_bimc_smmu_cirpt[9] */
+ <0xff 283>, /* mmss_bimc_smmu_cirpt[10] */
+ <0xff 284>, /* mmss_bimc_smmu_cirpt[11] */
+ <0xff 285>, /* mmss_bimc_smmu_cirpt[12] */
+ <0xff 286>, /* mmss_bimc_smmu_cirpt[13] */
+ <0xff 287>, /* mmss_bimc_smmu_cirpt[14] */
+ <0xff 288>, /* mmss_bimc_smmu_cirpt[15] */
+ <0xff 289>, /* ufs_ice_sec_level_irq */
+ <0xff 291>, /* lpass_irq_out_apcs[18] */
+ <0xff 292>, /* mmss_bimc_smmu_cirpt[16] */
+ <0xff 293>, /* mmss_bimc_smmu_cirpt[17] */
+ <0xff 294>, /* mmss_bimc_smmu_cirpt[18] */
+ <0xff 295>, /* mmss_bimc_smmu_cirpt[0] */
+ <0xff 296>, /* mmss_bimc_smmu_pmirpt */
+ <0xff 297>, /* ufs_intrq */
+ <0xff 298>, /* mmss_bimc_smmu_cirpt[1] */
+ <0xff 299>, /* mmss_bimc_smmu_cirpt[2] */
+ <0xff 300>, /* mmss_bimc_smmu_cirpt[3] */
+ <0xff 301>, /* lpass_irq_out_apcs[17] */
+ <0xff 302>, /* qdss_etrbytecnt_irq */
+ <0xff 303>, /* lpass_irq_out_apcs[16] */
+ <0xff 304>, /* mmss_bimc_smmu_cirpt[19] */
+ <0xff 305>, /* mmss_bimc_smmu_cirpt[20] */
+ <0xff 306>, /* mmss_bimc_smmu_cirpt[21] */
+ <0xff 307>, /* mmss_bimc_smmu_cirpt[22] */
+ <0xff 308>, /* mmss_bimc_smmu_cirpt[23] */
+ <0xff 316>, /* lpass_irq_out_apcs[13] */
+ <0xff 317>, /* rbif_irq */
+ <0xff 318>, /* gpu_cc_gpu_cx_gds_hw_ctrl_irq_out */
+ <0xff 319>, /* venus0_irq */
+ <0xff 323>, /* lpass_irq_out_apcs[14] */
+ <0xff 324>, /* lpass_irq_out_apcs[15] */
+ <0xff 325>, /* camss_irq18 */
+ <0xff 326>, /* camss_irq0 */
+ <0xff 327>, /* camss_irq1 */
+ <0xff 328>, /* camss_irq2 */
+ <0xff 329>, /* camss_irq3 */
+ <0xff 330>, /* camss_irq4 */
+ <0xff 331>, /* camss_irq5 */
+ <0xff 332>, /* GC_SYS_irq[0] */
+ <0xff 333>, /* GC_SYS_irq[1] */
+ <0xff 334>, /* GC_SYS_irq[2] */
+ <0xff 335>, /* GC_SYS_irq[3] */
+ <0xff 336>, /* camss_irq13 */
+ <0xff 337>, /* camss_irq14 */
+ <0xff 338>, /* camss_irq15 */
+ <0xff 339>, /* camss_irq16 */
+ <0xff 340>, /* camss_irq17 */
+ <0xff 341>, /* camss_irq6 */
+ <0xff 342>, /* lpass_irq_out_apcs[36] */
+ <0xff 345>, /* camss_irq7 */
+ <0xff 346>, /* camss_irq8 */
+ <0xff 347>, /* camss_irq9 */
+ <0xff 348>, /* camss_irq10 */
+ <0xff 350>, /* camss_irq12 */
+ <0xff 351>, /* lpass_irq_out_apcs[12] */
+ <0xff 357>, /* o_pimem_nonfatal_irq */
+ <0xff 359>, /* ee1_apps_trustzone_spmi_periph_irq */
+ <0xff 360>, /* o_pimem_fatal_irq */
+ <0xff 361>, /* osmmu_CIrpt[0] */
+ <0xff 362>, /* osmmu_CIrpt[1] */
+ <0xff 363>, /* osmmu_CIrpt[2] */
+ <0xff 364>, /* osmmu_CIrpt[3] */
+ <0xff 365>, /* ipa_irq[0] */
+ <0xff 366>, /* osmmu_PMIrpt */
+ <0xff 380>, /* qusb2phy_intr */
+ <0xff 381>, /* osmmu_CIrpt[6] */
+ <0xff 382>, /* osmmu_CIrpt[7] */
+ <0xff 385>, /* osmmu_CIrpt[12] */
+ <0xff 386>, /* osmmu_CIrpt[13] */
+ <0xff 387>, /* osmmu_CIrpt[14] */
+ <0xff 388>, /* osmmu_CIrpt[15] */
+ <0xff 389>, /* osmmu_CIrpt[16] */
+ <0xff 390>, /* osmmu_CIrpt[17] */
+ <0xff 391>, /* osmmu_CIrpt[18] */
+ <0xff 392>, /* osmmu_CIrpt[19] */
+ <0xff 393>, /* o_dcc_crc_fail_int */
+ <0xff 404>, /* aggre2noc_obs_mainFault */
+ <0xff 405>, /* osmmu_CIrpt[0] */
+ <0xff 406>, /* osmmu_CIrpt[1] */
+ <0xff 407>, /* osmmu_CIrpt[2] */
+ <0xff 408>, /* osmmu_CIrpt[3] */
+ <0xff 409>, /* osmmu_CIrpt[4] */
+ <0xff 410>, /* osmmu_CIrpt[5] */
+ <0xff 411>, /* o_dcc_task_done_int */
+ <0xff 412>, /* vsense_apps_alarm_irq */
+ <0xff 413>, /* osmmu_PMIrpt */
+ <0xff 414>, /* channel0_apps_hlos_trans_done_irq */
+ <0xff 415>, /* channel1_apps_trustzone_trans_done_irq */
+ <0xff 416>, /* rpm_ipc[28] */
+ <0xff 417>, /* rpm_ipc[29] */
+ <0xff 418>, /* rpm_ipc[30] */
+ <0xff 419>, /* rpm_ipc[31] */
+ <0xff 423>, /* lpass_irq_out_apcs[40] */
+ <0xff 424>, /* ipa_irq[2] */
+ <0xff 425>, /* lpass_irq_out_apcs[22] */
+ <0xff 426>, /* lpass_irq_out_apcs[23] */
+ <0xff 427>, /* lpass_irq_out_apcs[24] */
+ <0xff 428>, /* lpass_irq_out_apcs[25] */
+ <0xff 429>, /* lpass_irq_out_apcs[26] */
+ <0xff 430>, /* lpass_irq_out_apcs[27] */
+ <0xff 431>, /* lpass_irq_out_apcs[28] */
+ <0xff 432>, /* lpass_irq_out_apcs[29] */
+ <0xff 433>, /* lpass_irq_out_apcs[30] */
+ <0xff 434>, /* lpass_irq_out_apcs[31] */
+ <0xff 435>, /* lpass_irq_out_apcs[32] */
+ <0xff 436>, /* lpass_irq_out_apcs[37] */
+ <0xff 445>, /* wcss_apss_ce_intr[0] */
+ <0xff 446>, /* wcss_apss_ce_intr[1] */
+ <0xff 447>, /* wcss_apss_ce_intr[2] */
+ <0xff 448>, /* wcss_apss_ce_intr[3] */
+ <0xff 449>, /* wcss_apss_ce_intr[4] */
+ <0xff 450>, /* wcss_apss_ce_intr[5] */
+ <0xff 452>, /* wcss_apss_ce_intr[6] */
+ <0xff 453>, /* wcss_apss_ce_intr[7] */
+ <0xff 454>, /* wcss_apss_ce_intr[8] */
+ <0xff 455>, /* wcss_apss_ce_intr[9] */
+ <0xff 456>, /* wcss_apss_ce_intr[10] */
+ <0xff 457>, /* wcss_apss_ce_intr[11] */
+ <0xff 458>, /* wcss_apss_status_intr */
+ <0xff 462>, /* tsens1_tsens_critical_int */
+ <0xff 464>, /* ipa_bam_irq[0] */
+ <0xff 465>, /* ipa_bam_irq[2] */
+ <0xff 466>, /* ssc_uart_int */
+ <0xff 468>, /* cri_cm_irq_tz */
+ <0xff 469>, /* cri_cm_irq_hyp */
+ <0xff 471>, /* mmss_bimc_smmu_gds_hw_ctrl_irq_out */
+ <0xff 472>, /* gcc_gds_hw_ctrl_irq_out */
+ <0xff 474>, /* osmmu_CIrpt[20] */
+ <0xff 475>, /* osmmu_CIrpt[21] */
+ <0xff 476>, /* osmmu_CIrpt[22] */
+ <0xff 477>, /* tsens0_tsens_critical_int */
+ <0xff 478>, /* tsens0_tsens_max_min_int */
+ <0xff 479>, /* osmmu_CIrpt[23] */
+ <0xff 480>, /* q6_wdog_expired_irq */
+ <0xff 481>, /* mss_ipc_out_irq[4] */
+ <0xff 482>, /* mss_ipc_out_irq[5] */
+ <0xff 483>, /* mss_ipc_out_irq[6] */
+ <0xff 484>, /* mss_ipc_out_irq[7] */
+ <0xff 485>, /* mss_ipc_out_irq[28] */
+ <0xff 486>, /* mss_ipc_out_irq[29] */
+ <0xff 487>, /* mss_ipc_out_irq[30] */
+ <0xff 488>, /* mss_ipc_out_irq[31] */
+ <0xff 490>, /* tsens0_tsens_upper_lower_int */
+ <0xff 491>, /* qspi_irq0 */
+ <0xff 492>, /* sdcc_ice_sec_level_irq */
+ <0xff 494>, /* osmmu_CIrpt[6] */
+ <0xff 495>, /* osmmu_CIrpt[7] */
+ <0xff 496>, /* osmmu_CIrpt[8] */
+ <0xff 497>, /* osmmu_CIrpt[9] */
+ <0xff 498>, /* osmmu_CIrpt[10] */
+ <0xff 499>, /* osmmu_CIrpt[11] */
+ <0xff 500>, /* osmmu_CIrpt[24] */
+ <0xff 501>, /* osmmu_CIrpt[25] */
+ <0xff 503>, /* o_bimc_intr[1] */
+ <0xff 504>, /* osmmu_CIrpt[26] */
+ <0xff 505>, /* osmmu_CIrpt[27] */
+ <0xff 506>, /* osmmu_CIrpt[28] */
+ <0xff 512>, /* turing_irq_out_vmm[0] */
+ <0xff 513>, /* turing_irq_out_vmm[1] */
+ <0xff 514>, /* turing_irq_out_vmm[2] */
+ <0xff 515>, /* turing_irq_out_vmm[3] */
+ <0xff 516>, /* lpass_irq_out_apcs[41] */
+ <0xff 517>, /* lpass_irq_out_apcs[42] */
+ <0xff 519>, /* lpass_irq_out_apcs[44] */
+ <0xff 520>, /* lpass_irq_out_apcs[45] */
+ <0xff 544>, /* turing_irq_out_apcs[00] */
+ <0xff 545>, /* turing_irq_out_apcs[01] */
+ <0xff 546>, /* turing_irq_out_apcs[02] */
+ <0xff 547>, /* turing_irq_out_apcs[03] */
+ <0xff 548>, /* turing_irq_out_apcs[04] */
+ <0xff 549>, /* turing_irq_out_apcs[05] */
+ <0xff 550>, /* turing_irq_out_apcs[06] */
+ <0xff 551>, /* turing_irq_out_apcs[07] */
+ <0xff 552>, /* turing_irq_out_apcs[08] */
+ <0xff 553>, /* turing_irq_out_apcs[09] */
+ <0xff 554>, /* turing_irq_out_apcs[10] */
+ <0xff 556>, /* turing_irq_out_apcs[12] */
+ <0xff 557>, /* turing_irq_out_apcs[13] */
+ <0xff 558>, /* turing_irq_out_apcs[14] */
+ <0xff 559>, /* turing_irq_out_apcs[15] */
+ <0xff 560>, /* turing_irq_out_apcs[16] */
+ <0xff 561>, /* turing_irq_out_apcs[17] */
+ <0xff 562>, /* turing_irq_out_apcs[18] */
+ <0xff 563>, /* turing_irq_out_apcs[19] */
+ <0xff 564>, /* turing_irq_out_apcs[20] */
+ <0xff 565>, /* turing_irq_out_apcs[21] */
+ <0xff 566>, /* turing_irq_out_apcs[22] */
+ <0xff 567>, /* turing_irq_out_apcs[23] */
+ <0xff 568>, /* turing_irq_out_apcs[24] */
+ <0xff 569>, /* turing_irq_out_apcs[25] */
+ <0xff 570>, /* turing_irq_out_apcs[26] */
+ <0xff 571>, /* turing_irq_out_apcs[27] */
+ <0xff 572>, /* turing_irq_out_apcs[28] */
+ <0xff 573>, /* turing_irq_out_apcs[29] */
+ <0xff 574>, /* turing_irq_out_apcs[30] */
+ <0xff 575>, /* turing_irq_out_apcs[31] */
+ <0xff 576>, /* turing_irq_out_apcs[32] */
+ <0xff 577>, /* turing_irq_out_apcs[33] */
+ <0xff 578>, /* turing_irq_out_apcs[34] */
+ <0xff 579>, /* turing_irq_out_apcs[35] */
+ <0xff 580>, /* turing_irq_out_apcs[36] */
+ <0xff 581>, /* turing_irq_out_apcs[37] */
+ <0xff 582>, /* turing_irq_out_apcs[38] */
+ <0xff 583>, /* turing_irq_out_apcs[39] */
+ <0xff 584>; /* turing_irq_out_apcs[40] */
+
+ qcom,gpio-parent = <&tlmm>;
+ qcom,gpio-map =
+ <3 1>,
+ <4 5>,
+ <5 9>,
+ <6 10>,
+ <7 66>,
+ <8 22>,
+ <9 25>,
+ <10 28>,
+ <11 58>,
+ <13 41>,
+ <14 43>,
+ <15 40>,
+ <16 42>,
+ <17 46>,
+ <18 50>,
+ <19 44>,
+ <21 56>,
+ <22 45>,
+ <23 68>,
+ <24 69>,
+ <25 70>,
+ <26 71>,
+ <27 72>,
+ <28 73>,
+ <29 64>,
+ <30 2>,
+ <31 13>,
+ <32 111>,
+ <33 74>,
+ <34 75>,
+ <35 76>,
+ <36 82>,
+ <37 17>,
+ <38 77>,
+ <39 47>,
+ <40 54>,
+ <41 48>,
+ <42 101>,
+ <43 49>,
+ <44 51>,
+ <45 86>,
+ <46 90>,
+ <47 91>,
+ <48 52>,
+ <50 55>,
+ <51 6>,
+ <53 65>,
+ <55 67>,
+ <56 83>,
+ <57 84>,
+ <58 85>,
+ <59 87>,
+ <63 21>,
+ <64 78>,
+ <65 113>,
+ <66 60>,
+ <67 98>,
+ <68 30>,
+ <70 31>,
+ <71 29>,
+ <76 107>,
+ <83 109>,
+ <84 103>,
+ <85 105>;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts
new file mode 100644
index 000000000000..140be9311e8a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts
@@ -0,0 +1,23 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "msmfalcon.dtsi"
+#include "msmfalcon-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM FALCON RCM";
+ compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp";
+ qcom,board-id = <21 0>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
index 0ab76c273ac3..02e61bcdd95c 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon-regulator.dtsi
@@ -176,6 +176,18 @@
regulator-max-microvolt = <1370000>;
status = "okay";
};
+
+ pmfalcon_l6_pin_ctrl: regulator-l6-pin-ctrl {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l6_pin_ctrl";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1370000>;
+ /* Force NPM follows HW_EN1 */
+ qcom,init-pin-ctrl-mode = <2>;
+ /* Enable follows HW_EN1 */
+ qcom,enable-with-pin-ctrl = <0 2>;
+ };
};
rpm-regulator-ldoa7 {
@@ -203,6 +215,18 @@
regulator-max-microvolt = <1900000>;
status = "okay";
};
+
+ pmfalcon_l9_pin_ctrl: regulator-l9-pin-ctrl {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l9_pin_ctrl";
+ qcom,set = <3>;
+ regulator-min-microvolt = <1750000>;
+ regulator-max-microvolt = <1900000>;
+ /* Force NPM follows HW_EN1 */
+ qcom,init-pin-ctrl-mode = <2>;
+ /* Enable follows HW_EN1 */
+ qcom,enable-with-pin-ctrl = <0 2>;
+ };
};
rpm-regulator-ldoa10 {
@@ -275,6 +299,18 @@
regulator-max-microvolt = <3400000>;
status = "okay";
};
+
+ pmfalcon_l19_pin_ctrl: regulator-l19-pin-ctrl {
+ compatible = "qcom,rpm-smd-regulator";
+ regulator-name = "pmfalcon_l19_pin_ctrl";
+ qcom,set = <3>;
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3400000>;
+ /* Force NPM follows HW_EN1 */
+ qcom,init-pin-ctrl-mode = <2>;
+ /* Enable follows HW_EN1 */
+ qcom,enable-with-pin-ctrl = <0 2>;
+ };
};
rpm-regulator-ldob1 {
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
index 2b8a78ee1fdc..d952c3b5e299 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts
@@ -28,6 +28,7 @@
&usb3 {
/delete-property/ USB3_GDSC-supply;
+ /delete-property/ extcon;
dwc3@a800000 {
maximum-speed = "high-speed";
};
@@ -111,3 +112,8 @@
&pmfalcon_pdphy {
status = "disabled";
};
+
+&clock_mmss {
+ compatible = "qcom,dummycc";
+ clock-output-names = "mmss_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
index d279e742c23a..fe92f40d786f 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
+++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts
@@ -29,6 +29,7 @@
&usb3 {
reg = <0xa800000 0xfc000>;
reg-names = "core_base";
+ /delete-property/ extcon;
dwc3@a800000 {
maximum-speed = "high-speed";
};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
index 6ef443c4de11..de0c11147c45 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 {
@@ -232,6 +322,25 @@
size = <0x0 0x5c00000>;
};
};
+
+ bluetooth: bt_wcn3990 {
+ compatible = "qca,wcn3990";
+ qca,bt-vdd-core-supply = <&pmfalcon_l9_pin_ctrl>;
+ qca,bt-vdd-pa-supply = <&pmfalcon_l6_pin_ctrl>;
+ qca,bt-vdd-ldo-supply = <&pmfalcon_l19_pin_ctrl>;
+ qca,bt-chip-pwd-supply = <&pm2falcon_bob_pin1>;
+ clocks = <&clock_rpmcc RPM_RF_CLK1>;
+ clock-names = "rf_clk1";
+
+ qca,bt-vdd-core-voltage-level = <1800000 1900000>;
+ qca,bt-vdd-pa-voltage-level = <1304000 1370000>;
+ qca,bt-vdd-ldo-voltage-level = <3312000 3400000>;
+ qca,bt-chip-pwd-voltage-level = <3600000 3600000>;
+
+ qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
+ };
};
#include "msmfalcon-smp2p.dtsi"
@@ -309,6 +418,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 +858,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>;
@@ -696,8 +888,11 @@
};
clock_mmss: clock-controller@c8c0000 {
- compatible = "qcom,dummycc";
- clock-output-names = "mmss_clocks";
+ compatible = "qcom,mmcc-msmfalcon";
+ reg = <0xc8c0000 0x40000>;
+ vdd_mx_mmss-supply = <&pm2falcon_s5_level>;
+ vdd_dig_mmss-supply = <&pm2falcon_s3_level>;
+ vdda-supply = <&pmfalcon_l10>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -831,7 +1026,7 @@
<0x10b4000 0x800>;
reg-names = "dcc-base", "dcc-ram-base";
- clocks = <&clock_rpmcc GCC_DCC_AHB_CLK>;
+ clocks = <&clock_gcc GCC_DCC_AHB_CLK>;
clock-names = "dcc_clk";
};
@@ -1146,9 +1341,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 +1376,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 +1408,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 +1477,113 @@
<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";
+ };
+
+ qcom,chd_silver {
+ compatible = "qcom,core-hang-detect";
+ label = "silver";
+ qcom,threshold-arr = <0x179880b0 0x179980b0
+ 0x179a80b0 0x179b80b0>;
+ qcom,config-arr = <0x179880b8 0x179980b8
+ 0x179a80b8 0x179b80b8>;
+ };
+
+ qcom,chd_gold {
+ compatible = "qcom,core-hang-detect";
+ label = "gold";
+ qcom,threshold-arr = <0x178880b0 0x178980b0
+ 0x178a80b0 0x178b80b0>;
+ qcom,config-arr = <0x178880b8 0x178980b8
+ 0x178a80b8 0x178b80b8>;
+ };
};
#include "msmfalcon-ion.dtsi"
@@ -1291,6 +1594,8 @@
#include "msm-pm2falcon-rpm-regulator.dtsi"
#include "msmfalcon-regulator.dtsi"
#include "msm-gdsc-falcon.dtsi"
+#include "msmfalcon-gpu.dtsi"
+#include "msmfalcon-pm.dtsi"
&gdsc_usb30 {
status = "ok";
@@ -1371,3 +1676,51 @@
#include "msmfalcon-common.dtsi"
#include "msmfalcon-blsp.dtsi"
#include "msmfalcon-vidc.dtsi"
+
+&pm2falcon_gpios {
+ /* GPIO 7 for VOL_UP */
+ gpio@c600 {
+ status = "okay";
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <0>;
+ qcom,out-strength = <1>;
+ };
+};
+
+&soc {
+ gpio_keys {
+ status = "okay";
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+ pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
+ pinctrl-0 = <&gpio_key_active>;
+ pinctrl-1 = <&gpio_key_suspend>;
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&tlmm 64 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ debounce-interval = <15>;
+ };
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&tlmm 113 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ debounce-interval = <15>;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&pm2falcon_gpios 7 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi b/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi
new file mode 100644
index 000000000000..017483c36866
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi
@@ -0,0 +1,77 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "msmfalcon-coresight.dtsi"
+
+&etm0 {
+ cpu = <&CPU4>;
+};
+
+&etm1 {
+ cpu = <&CPU5>;
+};
+
+&etm2 {
+ cpu = <&CPU6>;
+};
+
+&etm3 {
+ cpu = <&CPU7>;
+};
+
+&etm4 {
+ cpu = <&CPU0>;
+};
+
+&etm5 {
+ cpu = <&CPU1>;
+};
+
+&etm6 {
+ cpu = <&CPU2>;
+};
+
+&etm7 {
+ cpu = <&CPU3>;
+};
+
+&cti_cpu0 {
+ cpu = <&CPU4>;
+};
+
+&cti_cpu1 {
+ cpu = <&CPU5>;
+};
+
+&cti_cpu2 {
+ cpu = <&CPU6>;
+};
+
+&cti_cpu3 {
+ cpu = <&CPU7>;
+};
+
+&cti_cpu4 {
+ cpu = <&CPU0>;
+};
+
+&cti_cpu5 {
+ cpu = <&CPU1>;
+};
+
+&cti_cpu6 {
+ cpu = <&CPU2>;
+};
+
+&cti_cpu7 {
+ cpu = <&CPU3>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
index 491b55aab9a6..094d1ef6812c 100644
--- a/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
+++ b/arch/arm/boot/dts/qcom/msmtriton-rumi.dts
@@ -23,6 +23,8 @@
};
&usb3 {
+ /delete-property/ USB3_GDSC-supply;
+ /delete-property/ extcon;
dwc3@a800000 {
maximum-speed = "high-speed";
};
@@ -68,3 +70,8 @@
compatible = "qcom,dummycc";
clock-output-names = "gfx_clocks";
};
+
+&clock_mmss {
+ compatible = "qcom,dummycc";
+ clock-output-names = "mmss_clocks";
+};
diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi
index 2a22772c8d1d..dfa592c16643 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 {
@@ -212,6 +304,7 @@
};
#include "msmtriton-smp2p.dtsi"
+#include "msmtriton-coresight.dtsi"
&soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -248,6 +341,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;
@@ -288,6 +449,18 @@
qcom,sensors = <12>;
};
+ wdog: qcom,wdt@17817000 {
+ status = "disabled";
+ compatible = "qcom,msm-watchdog";
+ reg = <0x17817000 0x1000>;
+ reg-names = "wdt-base";
+ interrupts = <0 3 0>, <0 4 0>;
+ qcom,bark-time = <11000>;
+ qcom,pet-time = <10000>;
+ qcom,ipi-ping;
+ qcom,wakeup-enable;
+ };
+
uartblsp1dm1: serial@0c170000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0xc170000 0x1000>;
@@ -367,6 +540,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>;
@@ -382,14 +570,17 @@
};
clock_mmss: clock-controller@c8c0000 {
- compatible = "qcom,dummycc";
- clock-output-names = "mmss_clocks";
+ compatible = "qcom,mmcc-msmfalcon";
+ reg = <0xc8c0000 0x40000>;
+ vdd_mx_mmss-supply = <&pm2falcon_s5_level>;
+ vdd_dig_mmss-supply = <&pm2falcon_s3_level>;
+ vdda-supply = <&pmfalcon_l10>;
#clock-cells = <1>;
#reset-cells = <1>;
};
clock_gfx: clock-controller@5065000 {
- compatible = "qcom,gpucc-msmfalcon";
+ compatible = "qcom,gpucc-msmtriton";
reg = <0x5065000 0x10000>;
vdd_dig_gfx-supply = <&pm2falcon_s3_level>;
vdd_mx_gfx-supply = <&pm2falcon_s5_level>;
@@ -397,13 +588,13 @@
qcom,gfxfreq-corner =
< 0 0>,
< 160000000 1>, /* MinSVS */
- < 266000000 2>, /* LowSVS */
+ < 240000000 2>, /* LowSVS */
< 370000000 3>, /* SVS */
< 465000000 4>, /* SVS_L1 */
< 588000000 5>, /* NOM */
< 647000000 6>, /* NOM_L1 */
- < 700000000 7>, /* TURBO */
- < 750000000 7>; /* TURBO */
+ < 700000000 7>, /* TURBO */
+ < 775000000 7>; /* TURBO */
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -425,6 +616,16 @@
qcom,mpu-enabled;
};
+ dcc: dcc@10b3000 {
+ compatible = "qcom,dcc";
+ reg = <0x10b3000 0x1000>,
+ <0x10b4000 0x800>;
+ reg-names = "dcc-base", "dcc-ram-base";
+
+ clocks = <&clock_gcc GCC_DCC_AHB_CLK>;
+ clock-names = "dcc_clk";
+ };
+
qcom,glink-smem-native-xprt-modem@86000000 {
compatible = "qcom,glink-smem-native-xprt";
reg = <0x86000000 0x200000>,
@@ -736,6 +937,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>;
@@ -779,12 +985,31 @@
qcom,irq-is-percpu;
interrupts = <1 6 4>;
};
+
+ qcom,chd_silver {
+ compatible = "qcom,core-hang-detect";
+ label = "silver";
+ qcom,threshold-arr = <0x179880b0 0x179980b0
+ 0x179a80b0 0x179b80b0>;
+ qcom,config-arr = <0x179880b8 0x179980b8
+ 0x179a80b8 0x179b80b8>;
+ };
+
+ qcom,chd_gold {
+ compatible = "qcom,core-hang-detect";
+ label = "gold";
+ qcom,threshold-arr = <0x178880b0 0x178980b0
+ 0x178a80b0 0x178b80b0>;
+ qcom,config-arr = <0x178880b8 0x178980b8
+ 0x178a80b8 0x178b80b8>;
+ };
};
#include "msmtriton-ion.dtsi"
#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/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index b55857fd7cc4..9eaa449d4df6 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -312,6 +312,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
diff --git a/arch/arm/configs/msmfalcon-perf_defconfig b/arch/arm/configs/msmfalcon-perf_defconfig
index 272f760117a7..72c65b1cea66 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
@@ -247,6 +249,7 @@ CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -359,6 +362,8 @@ CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA=y
CONFIG_MSM_CAMERA_DEBUG=y
@@ -410,11 +415,14 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
@@ -546,6 +554,7 @@ CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_EXT4_FS_ENCRYPTION=y
+CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_EXT4_DEBUG=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig
index c09e02e53a07..aa3ee39e616b 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
@@ -246,6 +248,7 @@ CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_UFSHCD=y
CONFIG_SCSI_UFSHCD_PLATFORM=y
CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -344,6 +347,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
@@ -357,6 +361,8 @@ CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA=y
CONFIG_MSM_CAMERA_DEBUG=y
@@ -410,11 +416,14 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
@@ -469,6 +478,7 @@ CONFIG_SEEMP_CORE=y
CONFIG_USB_BAM=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_MSM_GPUCC_FALCON=y
+CONFIG_MSM_MMCC_FALCON=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_ARM_SMMU=y
CONFIG_IOMMU_DEBUG=y
diff --git a/arch/arm/include/asm/etmv4x.h b/arch/arm/include/asm/etmv4x.h
new file mode 100644
index 000000000000..5251d55df3b3
--- /dev/null
+++ b/arch/arm/include/asm/etmv4x.h
@@ -0,0 +1,387 @@
+/* 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.
+ */
+
+#ifndef __ASM_ETMV4X_H
+#define __ASM_ETMV4X_H
+
+#include <linux/types.h>
+
+
+/* 32 bit register read for AArch32 */
+#define trc_readl(reg) RSYSL_##reg()
+#define trc_readq(reg) RSYSL_##reg()
+
+/* 32 bit register write for AArch32 */
+#define trc_write(val, reg) WSYS_##reg(val)
+
+#define MRC(op0, op1, crn, crm, op2) \
+({ \
+uint32_t val; \
+asm volatile("mrc p"#op0", "#op1", %0, "#crn", "#crm", "#op2 : "=r" (val)); \
+val; \
+})
+
+#define MCR(val, op0, op1, crn, crm, op2) \
+({ \
+asm volatile("mcr p"#op0", "#op1", %0, "#crn", "#crm", "#op2 : : "r" (val));\
+})
+
+/* Clock and Power Management Register */
+#define RSYSL_CPMR_EL1() MRC(15, 7, c15, c0, 5)
+#define WSYS_CPMR_EL1(val) MCR(val, 15, 7, c15, c0, 5)
+
+/*
+ * ETMv4 Registers
+ *
+ * Read only
+ * ETMAUTHSTATUS, ETMDEVARCH, ETMDEVID, ETMIDRn[0-13], ETMOSLSR, ETMSTATR
+ *
+ * Write only
+ * ETMOSLAR
+ */
+/* 32 bit registers */
+#define RSYSL_ETMAUTHSTATUS() MRC(14, 1, c7, c14, 6)
+#define RSYSL_ETMAUXCTLR() MRC(14, 1, c0, c6, 0)
+#define RSYSL_ETMCCCTLR() MRC(14, 1, c0, c14, 0)
+#define RSYSL_ETMCIDCCTLR0() MRC(14, 1, c3, c0, 2)
+#define RSYSL_ETMCNTCTLR0() MRC(14, 1, c0, c4, 5)
+#define RSYSL_ETMCNTCTLR1() MRC(14, 1, c0, c5, 5)
+#define RSYSL_ETMCNTCTLR2() MRC(14, 1, c0, c6, 5)
+#define RSYSL_ETMCNTCTLR3() MRC(14, 1, c0, c7, 5)
+#define RSYSL_ETMCNTRLDVR0() MRC(14, 1, c0, c0, 5)
+#define RSYSL_ETMCNTRLDVR1() MRC(14, 1, c0, c1, 5)
+#define RSYSL_ETMCNTRLDVR2() MRC(14, 1, c0, c2, 5)
+#define RSYSL_ETMCNTRLDVR3() MRC(14, 1, c0, c3, 5)
+#define RSYSL_ETMCNTVR0() MRC(14, 1, c0, c8, 5)
+#define RSYSL_ETMCNTVR1() MRC(14, 1, c0, c9, 5)
+#define RSYSL_ETMCNTVR2() MRC(14, 1, c0, c10, 5)
+#define RSYSL_ETMCNTVR3() MRC(14, 1, c0, c11, 5)
+#define RSYSL_ETMCONFIGR() MRC(14, 1, c0, c4, 0)
+#define RSYSL_ETMDEVARCH() MRC(14, 1, c7, c15, 6)
+#define RSYSL_ETMDEVID() MRC(14, 1, c7, c2, 7)
+#define RSYSL_ETMEVENTCTL0R() MRC(14, 1, c0, c8, 0)
+#define RSYSL_ETMEVENTCTL1R() MRC(14, 1, c0, c9, 0)
+#define RSYSL_ETMEXTINSELR() MRC(14, 1, c0, c8, 4)
+#define RSYSL_ETMIDR0() MRC(14, 1, c0, c8, 7)
+#define RSYSL_ETMIDR1() MRC(14, 1, c0, c9, 7)
+#define RSYSL_ETMIDR10() MRC(14, 1, c0, c2, 6)
+#define RSYSL_ETMIDR11() MRC(14, 1, c0, c3, 6)
+#define RSYSL_ETMIDR12() MRC(14, 1, c0, c4, 6)
+#define RSYSL_ETMIDR13() MRC(14, 1, c0, c5, 6)
+#define RSYSL_ETMIDR2() MRC(14, 1, c0, c10, 7)
+#define RSYSL_ETMIDR3() MRC(14, 1, c0, c11, 7)
+#define RSYSL_ETMIDR4() MRC(14, 1, c0, c12, 7)
+#define RSYSL_ETMIDR5() MRC(14, 1, c0, c13, 7)
+#define RSYSL_ETMIDR6() MRC(14, 1, c0, c14, 7)
+#define RSYSL_ETMIDR7() MRC(14, 1, c0, c15, 7)
+#define RSYSL_ETMIDR8() MRC(14, 1, c0, c0, 6)
+#define RSYSL_ETMIDR9() MRC(14, 1, c0, c1, 6)
+#define RSYSL_ETMIMSPEC0() MRC(14, 1, c0, c0, 7)
+#define RSYSL_ETMOSLSR() MRC(14, 1, c1, c1, 4)
+#define RSYSL_ETMPRGCTLR() MRC(14, 1, c0, c1, 0)
+#define RSYSL_ETMRSCTLR10() MRC(14, 1, c1, c10, 0)
+#define RSYSL_ETMRSCTLR11() MRC(14, 1, c1, c11, 0)
+#define RSYSL_ETMRSCTLR12() MRC(14, 1, c1, c12, 0)
+#define RSYSL_ETMRSCTLR13() MRC(14, 1, c1, c13, 0)
+#define RSYSL_ETMRSCTLR14() MRC(14, 1, c1, c14, 0)
+#define RSYSL_ETMRSCTLR15() MRC(14, 1, c1, c15, 0)
+#define RSYSL_ETMRSCTLR2() MRC(14, 1, c1, c2, 0)
+#define RSYSL_ETMRSCTLR3() MRC(14, 1, c1, c3, 0)
+#define RSYSL_ETMRSCTLR4() MRC(14, 1, c1, c4, 0)
+#define RSYSL_ETMRSCTLR5() MRC(14, 1, c1, c5, 0)
+#define RSYSL_ETMRSCTLR6() MRC(14, 1, c1, c6, 0)
+#define RSYSL_ETMRSCTLR7() MRC(14, 1, c1, c7, 0)
+#define RSYSL_ETMRSCTLR8() MRC(14, 1, c1, c8, 0)
+#define RSYSL_ETMRSCTLR9() MRC(14, 1, c1, c9, 0)
+#define RSYSL_ETMRSCTLR16() MRC(14, 1, c1, c0, 1)
+#define RSYSL_ETMRSCTLR17() MRC(14, 1, c1, c1, 1)
+#define RSYSL_ETMRSCTLR18() MRC(14, 1, c1, c2, 1)
+#define RSYSL_ETMRSCTLR19() MRC(14, 1, c1, c3, 1)
+#define RSYSL_ETMRSCTLR20() MRC(14, 1, c1, c4, 1)
+#define RSYSL_ETMRSCTLR21() MRC(14, 1, c1, c5, 1)
+#define RSYSL_ETMRSCTLR22() MRC(14, 1, c1, c6, 1)
+#define RSYSL_ETMRSCTLR23() MRC(14, 1, c1, c7, 1)
+#define RSYSL_ETMRSCTLR24() MRC(14, 1, c1, c8, 1)
+#define RSYSL_ETMRSCTLR25() MRC(14, 1, c1, c9, 1)
+#define RSYSL_ETMRSCTLR26() MRC(14, 1, c1, c10, 1)
+#define RSYSL_ETMRSCTLR27() MRC(14, 1, c1, c11, 1)
+#define RSYSL_ETMRSCTLR28() MRC(14, 1, c1, c12, 1)
+#define RSYSL_ETMRSCTLR29() MRC(14, 1, c1, c13, 1)
+#define RSYSL_ETMRSCTLR30() MRC(14, 1, c1, c14, 1)
+#define RSYSL_ETMRSCTLR31() MRC(14, 1, c1, c15, 1)
+#define RSYSL_ETMSEQEVR0() MRC(14, 1, c0, c0, 4)
+#define RSYSL_ETMSEQEVR1() MRC(14, 1, c0, c1, 4)
+#define RSYSL_ETMSEQEVR2() MRC(14, 1, c0, c2, 4)
+#define RSYSL_ETMSEQRSTEVR() MRC(14, 1, c0, c6, 4)
+#define RSYSL_ETMSEQSTR() MRC(14, 1, c0, c7, 4)
+#define RSYSL_ETMSTALLCTLR() MRC(14, 1, c0, c11, 0)
+#define RSYSL_ETMSTATR() MRC(14, 1, c0, c3, 0)
+#define RSYSL_ETMSYNCPR() MRC(14, 1, c0, c13, 0)
+#define RSYSL_ETMTRACEIDR() MRC(14, 1, c0, c0, 1)
+#define RSYSL_ETMTSCTLR() MRC(14, 1, c0, c12, 0)
+#define RSYSL_ETMVICTLR() MRC(14, 1, c0, c0, 2)
+#define RSYSL_ETMVIIECTLR() MRC(14, 1, c0, c1, 2)
+#define RSYSL_ETMVISSCTLR() MRC(14, 1, c0, c2, 2)
+#define RSYSL_ETMSSCCR0() MRC(14, 1, c1, c0, 2)
+#define RSYSL_ETMSSCCR1() MRC(14, 1, c1, c1, 2)
+#define RSYSL_ETMSSCCR2() MRC(14, 1, c1, c2, 2)
+#define RSYSL_ETMSSCCR3() MRC(14, 1, c1, c3, 2)
+#define RSYSL_ETMSSCCR4() MRC(14, 1, c1, c4, 2)
+#define RSYSL_ETMSSCCR5() MRC(14, 1, c1, c5, 2)
+#define RSYSL_ETMSSCCR6() MRC(14, 1, c1, c6, 2)
+#define RSYSL_ETMSSCCR7() MRC(14, 1, c1, c7, 2)
+#define RSYSL_ETMSSCSR0() MRC(14, 1, c1, c8, 2)
+#define RSYSL_ETMSSCSR1() MRC(14, 1, c1, c9, 2)
+#define RSYSL_ETMSSCSR2() MRC(14, 1, c1, c10, 2)
+#define RSYSL_ETMSSCSR3() MRC(14, 1, c1, c11, 2)
+#define RSYSL_ETMSSCSR4() MRC(14, 1, c1, c12, 2)
+#define RSYSL_ETMSSCSR5() MRC(14, 1, c1, c13, 2)
+#define RSYSL_ETMSSCSR6() MRC(14, 1, c1, c14, 2)
+#define RSYSL_ETMSSCSR7() MRC(14, 1, c1, c15, 2)
+#define RSYSL_ETMSSPCICR0() MRC(14, 1, c1, c0, 3)
+#define RSYSL_ETMSSPCICR1() MRC(14, 1, c1, c1, 3)
+#define RSYSL_ETMSSPCICR2() MRC(14, 1, c1, c2, 3)
+#define RSYSL_ETMSSPCICR3() MRC(14, 1, c1, c3, 3)
+#define RSYSL_ETMSSPCICR4() MRC(14, 1, c1, c4, 3)
+#define RSYSL_ETMSSPCICR5() MRC(14, 1, c1, c5, 3)
+#define RSYSL_ETMSSPCICR6() MRC(14, 1, c1, c6, 3)
+#define RSYSL_ETMSSPCICR7() MRC(14, 1, c1, c7, 3)
+
+/*
+ * 64 bit registers, ignore the upper 32bit
+ * A read from a 32-bit register location using a 64-bit access result
+ * in the upper 32bits being return as RES0.
+ */
+#define RSYSL_ETMACATR0() MRC(14, 1, c2, c0, 2)
+#define RSYSL_ETMACATR1() MRC(14, 1, c2, c2, 2)
+#define RSYSL_ETMACATR2() MRC(14, 1, c2, c4, 2)
+#define RSYSL_ETMACATR3() MRC(14, 1, c2, c6, 2)
+#define RSYSL_ETMACATR4() MRC(14, 1, c2, c8, 2)
+#define RSYSL_ETMACATR5() MRC(14, 1, c2, c10, 2)
+#define RSYSL_ETMACATR6() MRC(14, 1, c2, c12, 2)
+#define RSYSL_ETMACATR7() MRC(14, 1, c2, c14, 2)
+#define RSYSL_ETMACATR8() MRC(14, 1, c2, c0, 3)
+#define RSYSL_ETMACATR9() MRC(14, 1, c2, c2, 3)
+#define RSYSL_ETMACATR10() MRC(14, 1, c2, c4, 3)
+#define RSYSL_ETMACATR11() MRC(14, 1, c2, c6, 3)
+#define RSYSL_ETMACATR12() MRC(14, 1, c2, c8, 3)
+#define RSYSL_ETMACATR13() MRC(14, 1, c2, c10, 3)
+#define RSYSL_ETMACATR14() MRC(14, 1, c2, c12, 3)
+#define RSYSL_ETMACATR15() MRC(14, 1, c2, c14, 3)
+#define RSYSL_ETMCIDCVR0() MRC(14, 1, c3, c0, 0)
+#define RSYSL_ETMCIDCVR1() MRC(14, 1, c3, c2, 0)
+#define RSYSL_ETMCIDCVR2() MRC(14, 1, c3, c4, 0)
+#define RSYSL_ETMCIDCVR3() MRC(14, 1, c3, c6, 0)
+#define RSYSL_ETMCIDCVR4() MRC(14, 1, c3, c8, 0)
+#define RSYSL_ETMCIDCVR5() MRC(14, 1, c3, c10, 0)
+#define RSYSL_ETMCIDCVR6() MRC(14, 1, c3, c12, 0)
+#define RSYSL_ETMCIDCVR7() MRC(14, 1, c3, c14, 0)
+#define RSYSL_ETMACVR0() MRC(14, 1, c2, c0, 0)
+#define RSYSL_ETMACVR1() MRC(14, 1, c2, c2, 0)
+#define RSYSL_ETMACVR2() MRC(14, 1, c2, c4, 0)
+#define RSYSL_ETMACVR3() MRC(14, 1, c2, c6, 0)
+#define RSYSL_ETMACVR4() MRC(14, 1, c2, c8, 0)
+#define RSYSL_ETMACVR5() MRC(14, 1, c2, c10, 0)
+#define RSYSL_ETMACVR6() MRC(14, 1, c2, c12, 0)
+#define RSYSL_ETMACVR7() MRC(14, 1, c2, c14, 0)
+#define RSYSL_ETMACVR8() MRC(14, 1, c2, c0, 1)
+#define RSYSL_ETMACVR9() MRC(14, 1, c2, c2, 1)
+#define RSYSL_ETMACVR10() MRC(14, 1, c2, c4, 1)
+#define RSYSL_ETMACVR11() MRC(14, 1, c2, c6, 1)
+#define RSYSL_ETMACVR12() MRC(14, 1, c2, c8, 1)
+#define RSYSL_ETMACVR13() MRC(14, 1, c2, c10, 1)
+#define RSYSL_ETMACVR14() MRC(14, 1, c2, c12, 1)
+#define RSYSL_ETMACVR15() MRC(14, 1, c2, c14, 1)
+#define RSYSL_ETMVMIDCVR0() MRC(14, 1, c3, c0, 1)
+#define RSYSL_ETMVMIDCVR1() MRC(14, 1, c3, c2, 1)
+#define RSYSL_ETMVMIDCVR2() MRC(14, 1, c3, c4, 1)
+#define RSYSL_ETMVMIDCVR3() MRC(14, 1, c3, c6, 1)
+#define RSYSL_ETMVMIDCVR4() MRC(14, 1, c3, c8, 1)
+#define RSYSL_ETMVMIDCVR5() MRC(14, 1, c3, c10, 1)
+#define RSYSL_ETMVMIDCVR6() MRC(14, 1, c3, c12, 1)
+#define RSYSL_ETMVMIDCVR7() MRC(14, 1, c3, c14, 1)
+#define RSYSL_ETMDVCVR0() MRC(14, 1, c2, c0, 4)
+#define RSYSL_ETMDVCVR1() MRC(14, 1, c2, c4, 4)
+#define RSYSL_ETMDVCVR2() MRC(14, 1, c2, c8, 4)
+#define RSYSL_ETMDVCVR3() MRC(14, 1, c2, c12, 4)
+#define RSYSL_ETMDVCVR4() MRC(14, 1, c2, c0, 5)
+#define RSYSL_ETMDVCVR5() MRC(14, 1, c2, c4, 5)
+#define RSYSL_ETMDVCVR6() MRC(14, 1, c2, c8, 5)
+#define RSYSL_ETMDVCVR7() MRC(14, 1, c2, c12, 5)
+#define RSYSL_ETMDVCMR0() MRC(14, 1, c2, c0, 6)
+#define RSYSL_ETMDVCMR1() MRC(14, 1, c2, c4, 6)
+#define RSYSL_ETMDVCMR2() MRC(14, 1, c2, c8, 6)
+#define RSYSL_ETMDVCMR3() MRC(14, 1, c2, c12, 6)
+#define RSYSL_ETMDVCMR4() MRC(14, 1, c2, c0, 7)
+#define RSYSL_ETMDVCMR5() MRC(14, 1, c2, c4, 7)
+#define RSYSL_ETMDVCMR6() MRC(14, 1, c2, c8, 7)
+#define RSYSL_ETMDVCMR7() MRC(14, 1, c2, c12, 7)
+
+/*
+ * 32 and 64 bit registers
+ * A write to a 32-bit register location using a 64-bit access result
+ * in the upper 32bit of access
+ */
+#define WSYS_ETMAUXCTLR(val) MCR(val, 14, 1, c0, c6, 0)
+#define WSYS_ETMACATR0(val) MCR(val, 14, 1, c2, c0, 2)
+#define WSYS_ETMACATR1(val) MCR(val, 14, 1, c2, c2, 2)
+#define WSYS_ETMACATR2(val) MCR(val, 14, 1, c2, c4, 2)
+#define WSYS_ETMACATR3(val) MCR(val, 14, 1, c2, c6, 2)
+#define WSYS_ETMACATR4(val) MCR(val, 14, 1, c2, c8, 2)
+#define WSYS_ETMACATR5(val) MCR(val, 14, 1, c2, c10, 2)
+#define WSYS_ETMACATR6(val) MCR(val, 14, 1, c2, c12, 2)
+#define WSYS_ETMACATR7(val) MCR(val, 14, 1, c2, c14, 2)
+#define WSYS_ETMACATR8(val) MCR(val, 14, 1, c2, c0, 3)
+#define WSYS_ETMACATR9(val) MCR(val, 14, 1, c2, c2, 3)
+#define WSYS_ETMACATR10(val) MCR(val, 14, 1, c2, c4, 3)
+#define WSYS_ETMACATR11(val) MCR(val, 14, 1, c2, c6, 3)
+#define WSYS_ETMACATR12(val) MCR(val, 14, 1, c2, c8, 3)
+#define WSYS_ETMACATR13(val) MCR(val, 14, 1, c2, c10, 3)
+#define WSYS_ETMACATR14(val) MCR(val, 14, 1, c2, c12, 3)
+#define WSYS_ETMACATR15(val) MCR(val, 14, 1, c2, c14, 3)
+#define WSYS_ETMACVR0(val) MCR(val, 14, 1, c2, c0, 0)
+#define WSYS_ETMACVR1(val) MCR(val, 14, 1, c2, c2, 0)
+#define WSYS_ETMACVR2(val) MCR(val, 14, 1, c2, c4, 0)
+#define WSYS_ETMACVR3(val) MCR(val, 14, 1, c2, c6, 0)
+#define WSYS_ETMACVR4(val) MCR(val, 14, 1, c2, c8, 0)
+#define WSYS_ETMACVR5(val) MCR(val, 14, 1, c2, c10, 0)
+#define WSYS_ETMACVR6(val) MCR(val, 14, 1, c2, c12, 0)
+#define WSYS_ETMACVR7(val) MCR(val, 14, 1, c2, c14, 0)
+#define WSYS_ETMACVR8(val) MCR(val, 14, 1, c2, c0, 1)
+#define WSYS_ETMACVR9(val) MCR(val, 14, 1, c2, c2, 1)
+#define WSYS_ETMACVR10(val) MCR(val, 14, 1, c2, c4, 1)
+#define WSYS_ETMACVR11(val) MCR(val, 14, 1, c2, c6, 1)
+#define WSYS_ETMACVR12(val) MCR(val, 14, 1, c2, c8, 1)
+#define WSYS_ETMACVR13(val) MCR(val, 14, 1, c2, c10, 1)
+#define WSYS_ETMACVR14(val) MCR(val, 14, 1, c2, c12, 1)
+#define WSYS_ETMACVR15(val) MCR(val, 14, 1, c2, c14, 1)
+#define WSYS_ETMCCCTLR(val) MCR(val, 14, 1, c0, c14, 0)
+#define WSYS_ETMCIDCCTLR0(val) MCR(val, 14, 1, c3, c0, 2)
+#define WSYS_ETMCIDCVR0(val) MCR(val, 14, 1, c3, c0, 0)
+#define WSYS_ETMCIDCVR1(val) MCR(val, 14, 1, c3, c2, 0)
+#define WSYS_ETMCIDCVR2(val) MCR(val, 14, 1, c3, c4, 0)
+#define WSYS_ETMCIDCVR3(val) MCR(val, 14, 1, c3, c6, 0)
+#define WSYS_ETMCIDCVR4(val) MCR(val, 14, 1, c3, c8, 0)
+#define WSYS_ETMCIDCVR5(val) MCR(val, 14, 1, c3, c10, 0)
+#define WSYS_ETMCIDCVR6(val) MCR(val, 14, 1, c3, c12, 0)
+#define WSYS_ETMCIDCVR7(val) MCR(val, 14, 1, c3, c14, 0)
+#define WSYS_ETMCNTCTLR0(val) MCR(val, 14, 1, c0, c4, 5)
+#define WSYS_ETMCNTCTLR1(val) MCR(val, 14, 1, c0, c5, 5)
+#define WSYS_ETMCNTCTLR2(val) MCR(val, 14, 1, c0, c6, 5)
+#define WSYS_ETMCNTCTLR3(val) MCR(val, 14, 1, c0, c7, 5)
+#define WSYS_ETMCNTRLDVR0(val) MCR(val, 14, 1, c0, c0, 5)
+#define WSYS_ETMCNTRLDVR1(val) MCR(val, 14, 1, c0, c1, 5)
+#define WSYS_ETMCNTRLDVR2(val) MCR(val, 14, 1, c0, c2, 5)
+#define WSYS_ETMCNTRLDVR3(val) MCR(val, 14, 1, c0, c3, 5)
+#define WSYS_ETMCNTVR0(val) MCR(val, 14, 1, c0, c8, 5)
+#define WSYS_ETMCNTVR1(val) MCR(val, 14, 1, c0, c9, 5)
+#define WSYS_ETMCNTVR2(val) MCR(val, 14, 1, c0, c10, 5)
+#define WSYS_ETMCNTVR3(val) MCR(val, 14, 1, c0, c11, 5)
+#define WSYS_ETMCONFIGR(val) MCR(val, 14, 1, c0, c4, 0)
+#define WSYS_ETMEVENTCTL0R(val) MCR(val, 14, 1, c0, c8, 0)
+#define WSYS_ETMEVENTCTL1R(val) MCR(val, 14, 1, c0, c9, 0)
+#define WSYS_ETMEXTINSELR(val) MCR(val, 14, 1, c0, c8, 4)
+#define WSYS_ETMIMSPEC0(val) MCR(val, 14, 1, c0, c0, 7)
+#define WSYS_ETMOSLAR(val) MCR(val, 14, 1, c1, c0, 4)
+#define WSYS_ETMPRGCTLR(val) MCR(val, 14, 1, c0, c1, 0)
+#define WSYS_ETMRSCTLR10(val) MCR(val, 14, 1, c1, c10, 0)
+#define WSYS_ETMRSCTLR11(val) MCR(val, 14, 1, c1, c11, 0)
+#define WSYS_ETMRSCTLR12(val) MCR(val, 14, 1, c1, c12, 0)
+#define WSYS_ETMRSCTLR13(val) MCR(val, 14, 1, c1, c13, 0)
+#define WSYS_ETMRSCTLR14(val) MCR(val, 14, 1, c1, c14, 0)
+#define WSYS_ETMRSCTLR15(val) MCR(val, 14, 1, c1, c15, 0)
+#define WSYS_ETMRSCTLR2(val) MCR(val, 14, 1, c1, c2, 0)
+#define WSYS_ETMRSCTLR3(val) MCR(val, 14, 1, c1, c3, 0)
+#define WSYS_ETMRSCTLR4(val) MCR(val, 14, 1, c1, c4, 0)
+#define WSYS_ETMRSCTLR5(val) MCR(val, 14, 1, c1, c5, 0)
+#define WSYS_ETMRSCTLR6(val) MCR(val, 14, 1, c1, c6, 0)
+#define WSYS_ETMRSCTLR7(val) MCR(val, 14, 1, c1, c7, 0)
+#define WSYS_ETMRSCTLR8(val) MCR(val, 14, 1, c1, c8, 0)
+#define WSYS_ETMRSCTLR9(val) MCR(val, 14, 1, c1, c9, 0)
+#define WSYS_ETMRSCTLR16(val) MCR(val, 14, 1, c1, c0, 1)
+#define WSYS_ETMRSCTLR17(val) MCR(val, 14, 1, c1, c1, 1)
+#define WSYS_ETMRSCTLR18(val) MCR(val, 14, 1, c1, c2, 1)
+#define WSYS_ETMRSCTLR19(val) MCR(val, 14, 1, c1, c3, 1)
+#define WSYS_ETMRSCTLR20(val) MCR(val, 14, 1, c1, c4, 1)
+#define WSYS_ETMRSCTLR21(val) MCR(val, 14, 1, c1, c5, 1)
+#define WSYS_ETMRSCTLR22(val) MCR(val, 14, 1, c1, c6, 1)
+#define WSYS_ETMRSCTLR23(val) MCR(val, 14, 1, c1, c7, 1)
+#define WSYS_ETMRSCTLR24(val) MCR(val, 14, 1, c1, c8, 1)
+#define WSYS_ETMRSCTLR25(val) MCR(val, 14, 1, c1, c9, 1)
+#define WSYS_ETMRSCTLR26(val) MCR(val, 14, 1, c1, c10, 1)
+#define WSYS_ETMRSCTLR27(val) MCR(val, 14, 1, c1, c11, 1)
+#define WSYS_ETMRSCTLR28(val) MCR(val, 14, 1, c1, c12, 1)
+#define WSYS_ETMRSCTLR29(val) MCR(val, 14, 1, c1, c13, 1)
+#define WSYS_ETMRSCTLR30(val) MCR(val, 14, 1, c1, c14, 1)
+#define WSYS_ETMRSCTLR31(val) MCR(val, 14, 1, c1, c15, 1)
+#define WSYS_ETMSEQEVR0(val) MCR(val, 14, 1, c0, c0, 4)
+#define WSYS_ETMSEQEVR1(val) MCR(val, 14, 1, c0, c1, 4)
+#define WSYS_ETMSEQEVR2(val) MCR(val, 14, 1, c0, c2, 4)
+#define WSYS_ETMSEQRSTEVR(val) MCR(val, 14, 1, c0, c6, 4)
+#define WSYS_ETMSEQSTR(val) MCR(val, 14, 1, c0, c7, 4)
+#define WSYS_ETMSTALLCTLR(val) MCR(val, 14, 1, c0, c11, 0)
+#define WSYS_ETMSYNCPR(val) MCR(val, 14, 1, c0, c13, 0)
+#define WSYS_ETMTRACEIDR(val) MCR(val, 14, 1, c0, c0, 1)
+#define WSYS_ETMTSCTLR(val) MCR(val, 14, 1, c0, c12, 0)
+#define WSYS_ETMVICTLR(val) MCR(val, 14, 1, c0, c0, 2)
+#define WSYS_ETMVIIECTLR(val) MCR(val, 14, 1, c0, c1, 2)
+#define WSYS_ETMVISSCTLR(val) MCR(val, 14, 1, c0, c2, 2)
+#define WSYS_ETMVMIDCVR0(val) MCR(val, 14, 1, c3, c0, 1)
+#define WSYS_ETMVMIDCVR1(val) MCR(val, 14, 1, c3, c2, 1)
+#define WSYS_ETMVMIDCVR2(val) MCR(val, 14, 1, c3, c4, 1)
+#define WSYS_ETMVMIDCVR3(val) MCR(val, 14, 1, c3, c6, 1)
+#define WSYS_ETMVMIDCVR4(val) MCR(val, 14, 1, c3, c8, 1)
+#define WSYS_ETMVMIDCVR5(val) MCR(val, 14, 1, c3, c10, 1)
+#define WSYS_ETMVMIDCVR6(val) MCR(val, 14, 1, c3, c12, 1)
+#define WSYS_ETMVMIDCVR7(val) MCR(val, 14, 1, c3, c14, 1)
+#define WSYS_ETMDVCVR0(val) MCR(val, 14, 1, c2, c0, 4)
+#define WSYS_ETMDVCVR1(val) MCR(val, 14, 1, c2, c4, 4)
+#define WSYS_ETMDVCVR2(val) MCR(val, 14, 1, c2, c8, 4)
+#define WSYS_ETMDVCVR3(val) MCR(val, 14, 1, c2, c12, 4)
+#define WSYS_ETMDVCVR4(val) MCR(val, 14, 1, c2, c0, 5)
+#define WSYS_ETMDVCVR5(val) MCR(val, 14, 1, c2, c4, 5)
+#define WSYS_ETMDVCVR6(val) MCR(val, 14, 1, c2, c8, 5)
+#define WSYS_ETMDVCVR7(val) MCR(val, 14, 1, c2, c12, 5)
+#define WSYS_ETMDVCMR0(val) MCR(val, 14, 1, c2, c0, 6)
+#define WSYS_ETMDVCMR1(val) MCR(val, 14, 1, c2, c4, 6)
+#define WSYS_ETMDVCMR2(val) MCR(val, 14, 1, c2, c8, 6)
+#define WSYS_ETMDVCMR3(val) MCR(val, 14, 1, c2, c12, 6)
+#define WSYS_ETMDVCMR4(val) MCR(val, 14, 1, c2, c0, 7)
+#define WSYS_ETMDVCMR5(val) MCR(val, 14, 1, c2, c4, 7)
+#define WSYS_ETMDVCMR6(val) MCR(val, 14, 1, c2, c8, 7)
+#define WSYS_ETMDVCMR7(val) MCR(val, 14, 1, c2, c12, 7)
+#define WSYS_ETMSSCCR0(val) MCR(val, 14, 1, c1, c0, 2)
+#define WSYS_ETMSSCCR1(val) MCR(val, 14, 1, c1, c1, 2)
+#define WSYS_ETMSSCCR2(val) MCR(val, 14, 1, c1, c2, 2)
+#define WSYS_ETMSSCCR3(val) MCR(val, 14, 1, c1, c3, 2)
+#define WSYS_ETMSSCCR4(val) MCR(val, 14, 1, c1, c4, 2)
+#define WSYS_ETMSSCCR5(val) MCR(val, 14, 1, c1, c5, 2)
+#define WSYS_ETMSSCCR6(val) MCR(val, 14, 1, c1, c6, 2)
+#define WSYS_ETMSSCCR7(val) MCR(val, 14, 1, c1, c7, 2)
+#define WSYS_ETMSSCSR0(val) MCR(val, 14, 1, c1, c8, 2)
+#define WSYS_ETMSSCSR1(val) MCR(val, 14, 1, c1, c9, 2)
+#define WSYS_ETMSSCSR2(val) MCR(val, 14, 1, c1, c10, 2)
+#define WSYS_ETMSSCSR3(val) MCR(val, 14, 1, c1, c11, 2)
+#define WSYS_ETMSSCSR4(val) MCR(val, 14, 1, c1, c12, 2)
+#define WSYS_ETMSSCSR5(val) MCR(val, 14, 1, c1, c13, 2)
+#define WSYS_ETMSSCSR6(val) MCR(val, 14, 1, c1, c14, 2)
+#define WSYS_ETMSSCSR7(val) MCR(val, 14, 1, c1, c15, 2)
+#define WSYS_ETMSSPCICR0(val) MCR(val, 14, 1, c1, c0, 3)
+#define WSYS_ETMSSPCICR1(val) MCR(val, 14, 1, c1, c1, 3)
+#define WSYS_ETMSSPCICR2(val) MCR(val, 14, 1, c1, c2, 3)
+#define WSYS_ETMSSPCICR3(val) MCR(val, 14, 1, c1, c3, 3)
+#define WSYS_ETMSSPCICR4(val) MCR(val, 14, 1, c1, c4, 3)
+#define WSYS_ETMSSPCICR5(val) MCR(val, 14, 1, c1, c5, 3)
+#define WSYS_ETMSSPCICR6(val) MCR(val, 14, 1, c1, c6, 3)
+#define WSYS_ETMSSPCICR7(val) MCR(val, 14, 1, c1, c7, 3)
+
+#endif
diff --git a/arch/arm/include/asm/hardware/debugv8.h b/arch/arm/include/asm/hardware/debugv8.h
new file mode 100644
index 000000000000..054226cbe7ce
--- /dev/null
+++ b/arch/arm/include/asm/hardware/debugv8.h
@@ -0,0 +1,247 @@
+/* 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.
+ */
+
+#ifndef __ASM_HARDWARE_DEBUGV8_H
+#define __ASM_HARDWARE_DEBUGV8_H
+
+#include <linux/types.h>
+
+/* Accessors for CP14 registers */
+#define dbg_read(reg) RCP14_##reg()
+#define dbg_write(val, reg) WCP14_##reg(val)
+
+/* MRC14 registers */
+#define MRC14(op1, crn, crm, op2) \
+({ \
+uint32_t val; \
+asm volatile("mrc p14, "#op1", %0, "#crn", "#crm", "#op2 : "=r" (val)); \
+val; \
+})
+
+/* MCR14 registers */
+#define MCR14(val, op1, crn, crm, op2) \
+({ \
+asm volatile("mcr p14, "#op1", %0, "#crn", "#crm", "#op2 : : "r" (val));\
+})
+
+/*
+ * Debug Registers
+ *
+ * Read only
+ * DBGDIDR, DBGDSCRint, DBGDTRRXint, DBGDRAR, DBGOSLSR, DBGOSSRR, DBGDSAR,
+ * DBGAUTHSTATUS, DBGDEVID2, DBGDEVID1, DBGDEVID
+ *
+ * Write only
+ * DBGDTRTXint, DBGOSLAR
+ */
+#define RCP14_DBGDIDR() MRC14(0, c0, c0, 0)
+#define RCP14_DBGDSCRint() MRC14(0, c0, c1, 0)
+#define RCP14_DBGDCCINT() MRC14(0, c0, c2, 0)
+#define RCP14_DBGDTRRXint() MRC14(0, c0, c5, 0)
+#define RCP14_DBGWFAR() MRC14(0, c0, c6, 0)
+#define RCP14_DBGVCR() MRC14(0, c0, c7, 0)
+#define RCP14_DBGDTRRXext() MRC14(0, c0, c0, 2)
+#define RCP14_DBGDSCRext() MRC14(0, c0, c2, 2)
+#define RCP14_DBGDTRTXext() MRC14(0, c0, c3, 2)
+#define RCP14_DBGOSECCR() MRC14(0, c0, c6, 2)
+#define RCP14_DBGBVR0() MRC14(0, c0, c0, 4)
+#define RCP14_DBGBVR1() MRC14(0, c0, c1, 4)
+#define RCP14_DBGBVR2() MRC14(0, c0, c2, 4)
+#define RCP14_DBGBVR3() MRC14(0, c0, c3, 4)
+#define RCP14_DBGBVR4() MRC14(0, c0, c4, 4)
+#define RCP14_DBGBVR5() MRC14(0, c0, c5, 4)
+#define RCP14_DBGBVR6() MRC14(0, c0, c6, 4)
+#define RCP14_DBGBVR7() MRC14(0, c0, c7, 4)
+#define RCP14_DBGBVR8() MRC14(0, c0, c8, 4)
+#define RCP14_DBGBVR9() MRC14(0, c0, c9, 4)
+#define RCP14_DBGBVR10() MRC14(0, c0, c10, 4)
+#define RCP14_DBGBVR11() MRC14(0, c0, c11, 4)
+#define RCP14_DBGBVR12() MRC14(0, c0, c12, 4)
+#define RCP14_DBGBVR13() MRC14(0, c0, c13, 4)
+#define RCP14_DBGBVR14() MRC14(0, c0, c14, 4)
+#define RCP14_DBGBVR15() MRC14(0, c0, c15, 4)
+#define RCP14_DBGBCR0() MRC14(0, c0, c0, 5)
+#define RCP14_DBGBCR1() MRC14(0, c0, c1, 5)
+#define RCP14_DBGBCR2() MRC14(0, c0, c2, 5)
+#define RCP14_DBGBCR3() MRC14(0, c0, c3, 5)
+#define RCP14_DBGBCR4() MRC14(0, c0, c4, 5)
+#define RCP14_DBGBCR5() MRC14(0, c0, c5, 5)
+#define RCP14_DBGBCR6() MRC14(0, c0, c6, 5)
+#define RCP14_DBGBCR7() MRC14(0, c0, c7, 5)
+#define RCP14_DBGBCR8() MRC14(0, c0, c8, 5)
+#define RCP14_DBGBCR9() MRC14(0, c0, c9, 5)
+#define RCP14_DBGBCR10() MRC14(0, c0, c10, 5)
+#define RCP14_DBGBCR11() MRC14(0, c0, c11, 5)
+#define RCP14_DBGBCR12() MRC14(0, c0, c12, 5)
+#define RCP14_DBGBCR13() MRC14(0, c0, c13, 5)
+#define RCP14_DBGBCR14() MRC14(0, c0, c14, 5)
+#define RCP14_DBGBCR15() MRC14(0, c0, c15, 5)
+#define RCP14_DBGWVR0() MRC14(0, c0, c0, 6)
+#define RCP14_DBGWVR1() MRC14(0, c0, c1, 6)
+#define RCP14_DBGWVR2() MRC14(0, c0, c2, 6)
+#define RCP14_DBGWVR3() MRC14(0, c0, c3, 6)
+#define RCP14_DBGWVR4() MRC14(0, c0, c4, 6)
+#define RCP14_DBGWVR5() MRC14(0, c0, c5, 6)
+#define RCP14_DBGWVR6() MRC14(0, c0, c6, 6)
+#define RCP14_DBGWVR7() MRC14(0, c0, c7, 6)
+#define RCP14_DBGWVR8() MRC14(0, c0, c8, 6)
+#define RCP14_DBGWVR9() MRC14(0, c0, c9, 6)
+#define RCP14_DBGWVR10() MRC14(0, c0, c10, 6)
+#define RCP14_DBGWVR11() MRC14(0, c0, c11, 6)
+#define RCP14_DBGWVR12() MRC14(0, c0, c12, 6)
+#define RCP14_DBGWVR13() MRC14(0, c0, c13, 6)
+#define RCP14_DBGWVR14() MRC14(0, c0, c14, 6)
+#define RCP14_DBGWVR15() MRC14(0, c0, c15, 6)
+#define RCP14_DBGWCR0() MRC14(0, c0, c0, 7)
+#define RCP14_DBGWCR1() MRC14(0, c0, c1, 7)
+#define RCP14_DBGWCR2() MRC14(0, c0, c2, 7)
+#define RCP14_DBGWCR3() MRC14(0, c0, c3, 7)
+#define RCP14_DBGWCR4() MRC14(0, c0, c4, 7)
+#define RCP14_DBGWCR5() MRC14(0, c0, c5, 7)
+#define RCP14_DBGWCR6() MRC14(0, c0, c6, 7)
+#define RCP14_DBGWCR7() MRC14(0, c0, c7, 7)
+#define RCP14_DBGWCR8() MRC14(0, c0, c8, 7)
+#define RCP14_DBGWCR9() MRC14(0, c0, c9, 7)
+#define RCP14_DBGWCR10() MRC14(0, c0, c10, 7)
+#define RCP14_DBGWCR11() MRC14(0, c0, c11, 7)
+#define RCP14_DBGWCR12() MRC14(0, c0, c12, 7)
+#define RCP14_DBGWCR13() MRC14(0, c0, c13, 7)
+#define RCP14_DBGWCR14() MRC14(0, c0, c14, 7)
+#define RCP14_DBGWCR15() MRC14(0, c0, c15, 7)
+#define RCP14_DBGDRAR() MRC14(0, c1, c0, 0)
+#define RCP14_DBGBXVR0() MRC14(0, c1, c0, 1)
+#define RCP14_DBGBXVR1() MRC14(0, c1, c1, 1)
+#define RCP14_DBGBXVR2() MRC14(0, c1, c2, 1)
+#define RCP14_DBGBXVR3() MRC14(0, c1, c3, 1)
+#define RCP14_DBGBXVR4() MRC14(0, c1, c4, 1)
+#define RCP14_DBGBXVR5() MRC14(0, c1, c5, 1)
+#define RCP14_DBGBXVR6() MRC14(0, c1, c6, 1)
+#define RCP14_DBGBXVR7() MRC14(0, c1, c7, 1)
+#define RCP14_DBGBXVR8() MRC14(0, c1, c8, 1)
+#define RCP14_DBGBXVR9() MRC14(0, c1, c9, 1)
+#define RCP14_DBGBXVR10() MRC14(0, c1, c10, 1)
+#define RCP14_DBGBXVR11() MRC14(0, c1, c11, 1)
+#define RCP14_DBGBXVR12() MRC14(0, c1, c12, 1)
+#define RCP14_DBGBXVR13() MRC14(0, c1, c13, 1)
+#define RCP14_DBGBXVR14() MRC14(0, c1, c14, 1)
+#define RCP14_DBGBXVR15() MRC14(0, c1, c15, 1)
+#define RCP14_DBGOSLSR() MRC14(0, c1, c1, 4)
+#define RCP14_DBGOSSRR() MRC14(0, c1, c2, 4)
+#define RCP14_DBGOSDLR() MRC14(0, c1, c3, 4)
+#define RCP14_DBGPRCR() MRC14(0, c1, c4, 4)
+#define RCP14_DBGPRSR() MRC14(0, c1, c5, 4)
+#define RCP14_DBGDSAR() MRC14(0, c2, c0, 0)
+#define RCP14_DBGITCTRL() MRC14(0, c7, c0, 4)
+#define RCP14_DBGCLAIMSET() MRC14(0, c7, c8, 6)
+#define RCP14_DBGCLAIMCLR() MRC14(0, c7, c9, 6)
+#define RCP14_DBGAUTHSTATUS() MRC14(0, c7, c14, 6)
+#define RCP14_DBGDEVID2() MRC14(0, c7, c0, 7)
+#define RCP14_DBGDEVID1() MRC14(0, c7, c1, 7)
+#define RCP14_DBGDEVID() MRC14(0, c7, c2, 7)
+
+#define WCP14_DBGDCCINT(val) MCR14(val, 0, c0, c2, 0)
+#define WCP14_DBGDTRTXint(val) MCR14(val, 0, c0, c5, 0)
+#define WCP14_DBGWFAR(val) MCR14(val, 0, c0, c6, 0)
+#define WCP14_DBGVCR(val) MCR14(val, 0, c0, c7, 0)
+#define WCP14_DBGDTRRXext(val) MCR14(val, 0, c0, c0, 2)
+#define WCP14_DBGDSCRext(val) MCR14(val, 0, c0, c2, 2)
+#define WCP14_DBGDTRTXext(val) MCR14(val, 0, c0, c3, 2)
+#define WCP14_DBGOSECCR(val) MCR14(val, 0, c0, c6, 2)
+#define WCP14_DBGBVR0(val) MCR14(val, 0, c0, c0, 4)
+#define WCP14_DBGBVR1(val) MCR14(val, 0, c0, c1, 4)
+#define WCP14_DBGBVR2(val) MCR14(val, 0, c0, c2, 4)
+#define WCP14_DBGBVR3(val) MCR14(val, 0, c0, c3, 4)
+#define WCP14_DBGBVR4(val) MCR14(val, 0, c0, c4, 4)
+#define WCP14_DBGBVR5(val) MCR14(val, 0, c0, c5, 4)
+#define WCP14_DBGBVR6(val) MCR14(val, 0, c0, c6, 4)
+#define WCP14_DBGBVR7(val) MCR14(val, 0, c0, c7, 4)
+#define WCP14_DBGBVR8(val) MCR14(val, 0, c0, c8, 4)
+#define WCP14_DBGBVR9(val) MCR14(val, 0, c0, c9, 4)
+#define WCP14_DBGBVR10(val) MCR14(val, 0, c0, c10, 4)
+#define WCP14_DBGBVR11(val) MCR14(val, 0, c0, c11, 4)
+#define WCP14_DBGBVR12(val) MCR14(val, 0, c0, c12, 4)
+#define WCP14_DBGBVR13(val) MCR14(val, 0, c0, c13, 4)
+#define WCP14_DBGBVR14(val) MCR14(val, 0, c0, c14, 4)
+#define WCP14_DBGBVR15(val) MCR14(val, 0, c0, c15, 4)
+#define WCP14_DBGBCR0(val) MCR14(val, 0, c0, c0, 5)
+#define WCP14_DBGBCR1(val) MCR14(val, 0, c0, c1, 5)
+#define WCP14_DBGBCR2(val) MCR14(val, 0, c0, c2, 5)
+#define WCP14_DBGBCR3(val) MCR14(val, 0, c0, c3, 5)
+#define WCP14_DBGBCR4(val) MCR14(val, 0, c0, c4, 5)
+#define WCP14_DBGBCR5(val) MCR14(val, 0, c0, c5, 5)
+#define WCP14_DBGBCR6(val) MCR14(val, 0, c0, c6, 5)
+#define WCP14_DBGBCR7(val) MCR14(val, 0, c0, c7, 5)
+#define WCP14_DBGBCR8(val) MCR14(val, 0, c0, c8, 5)
+#define WCP14_DBGBCR9(val) MCR14(val, 0, c0, c9, 5)
+#define WCP14_DBGBCR10(val) MCR14(val, 0, c0, c10, 5)
+#define WCP14_DBGBCR11(val) MCR14(val, 0, c0, c11, 5)
+#define WCP14_DBGBCR12(val) MCR14(val, 0, c0, c12, 5)
+#define WCP14_DBGBCR13(val) MCR14(val, 0, c0, c13, 5)
+#define WCP14_DBGBCR14(val) MCR14(val, 0, c0, c14, 5)
+#define WCP14_DBGBCR15(val) MCR14(val, 0, c0, c15, 5)
+#define WCP14_DBGWVR0(val) MCR14(val, 0, c0, c0, 6)
+#define WCP14_DBGWVR1(val) MCR14(val, 0, c0, c1, 6)
+#define WCP14_DBGWVR2(val) MCR14(val, 0, c0, c2, 6)
+#define WCP14_DBGWVR3(val) MCR14(val, 0, c0, c3, 6)
+#define WCP14_DBGWVR4(val) MCR14(val, 0, c0, c4, 6)
+#define WCP14_DBGWVR5(val) MCR14(val, 0, c0, c5, 6)
+#define WCP14_DBGWVR6(val) MCR14(val, 0, c0, c6, 6)
+#define WCP14_DBGWVR7(val) MCR14(val, 0, c0, c7, 6)
+#define WCP14_DBGWVR8(val) MCR14(val, 0, c0, c8, 6)
+#define WCP14_DBGWVR9(val) MCR14(val, 0, c0, c9, 6)
+#define WCP14_DBGWVR10(val) MCR14(val, 0, c0, c10, 6)
+#define WCP14_DBGWVR11(val) MCR14(val, 0, c0, c11, 6)
+#define WCP14_DBGWVR12(val) MCR14(val, 0, c0, c12, 6)
+#define WCP14_DBGWVR13(val) MCR14(val, 0, c0, c13, 6)
+#define WCP14_DBGWVR14(val) MCR14(val, 0, c0, c14, 6)
+#define WCP14_DBGWVR15(val) MCR14(val, 0, c0, c15, 6)
+#define WCP14_DBGWCR0(val) MCR14(val, 0, c0, c0, 7)
+#define WCP14_DBGWCR1(val) MCR14(val, 0, c0, c1, 7)
+#define WCP14_DBGWCR2(val) MCR14(val, 0, c0, c2, 7)
+#define WCP14_DBGWCR3(val) MCR14(val, 0, c0, c3, 7)
+#define WCP14_DBGWCR4(val) MCR14(val, 0, c0, c4, 7)
+#define WCP14_DBGWCR5(val) MCR14(val, 0, c0, c5, 7)
+#define WCP14_DBGWCR6(val) MCR14(val, 0, c0, c6, 7)
+#define WCP14_DBGWCR7(val) MCR14(val, 0, c0, c7, 7)
+#define WCP14_DBGWCR8(val) MCR14(val, 0, c0, c8, 7)
+#define WCP14_DBGWCR9(val) MCR14(val, 0, c0, c9, 7)
+#define WCP14_DBGWCR10(val) MCR14(val, 0, c0, c10, 7)
+#define WCP14_DBGWCR11(val) MCR14(val, 0, c0, c11, 7)
+#define WCP14_DBGWCR12(val) MCR14(val, 0, c0, c12, 7)
+#define WCP14_DBGWCR13(val) MCR14(val, 0, c0, c13, 7)
+#define WCP14_DBGWCR14(val) MCR14(val, 0, c0, c14, 7)
+#define WCP14_DBGWCR15(val) MCR14(val, 0, c0, c15, 7)
+#define WCP14_DBGBXVR0(val) MCR14(val, 0, c1, c0, 1)
+#define WCP14_DBGBXVR1(val) MCR14(val, 0, c1, c1, 1)
+#define WCP14_DBGBXVR2(val) MCR14(val, 0, c1, c2, 1)
+#define WCP14_DBGBXVR3(val) MCR14(val, 0, c1, c3, 1)
+#define WCP14_DBGBXVR4(val) MCR14(val, 0, c1, c4, 1)
+#define WCP14_DBGBXVR5(val) MCR14(val, 0, c1, c5, 1)
+#define WCP14_DBGBXVR6(val) MCR14(val, 0, c1, c6, 1)
+#define WCP14_DBGBXVR7(val) MCR14(val, 0, c1, c7, 1)
+#define WCP14_DBGBXVR8(val) MCR14(val, 0, c1, c8, 1)
+#define WCP14_DBGBXVR9(val) MCR14(val, 0, c1, c9, 1)
+#define WCP14_DBGBXVR10(val) MCR14(val, 0, c1, c10, 1)
+#define WCP14_DBGBXVR11(val) MCR14(val, 0, c1, c11, 1)
+#define WCP14_DBGBXVR12(val) MCR14(val, 0, c1, c12, 1)
+#define WCP14_DBGBXVR13(val) MCR14(val, 0, c1, c13, 1)
+#define WCP14_DBGBXVR14(val) MCR14(val, 0, c1, c14, 1)
+#define WCP14_DBGBXVR15(val) MCR14(val, 0, c1, c15, 1)
+#define WCP14_DBGOSLAR(val) MCR14(val, 0, c1, c0, 4)
+#define WCP14_DBGOSSRR(val) MCR14(val, 0, c1, c2, 4)
+#define WCP14_DBGOSDLR(val) MCR14(val, 0, c1, c3, 4)
+#define WCP14_DBGPRCR(val) MCR14(val, 0, c1, c4, 4)
+#define WCP14_DBGITCTRL(val) MCR14(val, 0, c7, c0, 4)
+#define WCP14_DBGCLAIMSET(val) MCR14(val, 0, c7, c8, 6)
+#define WCP14_DBGCLAIMCLR(val) MCR14(val, 0, c7, c9, 6)
+
+#endif
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..4226060cb6fc 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
@@ -256,6 +258,7 @@ CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_TUN=y
CONFIG_MSM_RMNET_MHI=y
+CONFIG_RNDIS_IPA=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
@@ -432,7 +435,9 @@ CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index 6249b604466b..720dc8ba3be4 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
@@ -248,6 +250,7 @@ CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_TUN=y
CONFIG_MSM_RMNET_MHI=y
+CONFIG_RNDIS_IPA=y
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
@@ -417,7 +420,9 @@ CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 23287f8d06ea..60bb033be6df 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
@@ -341,6 +343,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 9cec02c83936..1ef2d90f13de 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
@@ -344,6 +346,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig
index 4d26ad79196d..10c988472268 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
@@ -344,6 +346,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
@@ -357,6 +360,8 @@ CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA=y
CONFIG_MSM_CAMERA_DEBUG=y
@@ -438,11 +443,14 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
@@ -490,6 +498,7 @@ CONFIG_SEEMP_CORE=y
CONFIG_USB_BAM=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_MSM_GPUCC_FALCON=y
+CONFIG_MSM_MMCC_FALCON=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_ARM_SMMU=y
diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig
index c568f005e70b..4d641012da4e 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
@@ -346,6 +348,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_SPM=y
CONFIG_REGULATOR_CPR3_HMSS=y
CONFIG_REGULATOR_CPR3_MMSS=y
@@ -359,6 +362,8 @@ CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA=y
CONFIG_MSM_CAMERA_DEBUG=y
@@ -439,11 +444,14 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=500
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_QCRNDIS=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
@@ -499,6 +507,7 @@ CONFIG_SEEMP_CORE=y
CONFIG_USB_BAM=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_MSM_GPUCC_FALCON=y
+CONFIG_MSM_MMCC_FALCON=y
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y
diff --git a/arch/arm64/mm/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/clk.c b/drivers/clk/clk.c
index c1865f9ee8b3..eb44cf9ddd17 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -656,7 +656,7 @@ static int clk_update_vdd(struct clk_vdd_class *vdd_class)
pr_debug("Set Voltage level Min %d, Max %d\n", uv[new_base + i],
uv[max_lvl + i]);
rc = regulator_set_voltage(r[i], uv[new_base + i],
- uv[max_lvl + i]);
+ vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]);
if (rc)
goto set_voltage_fail;
@@ -677,11 +677,13 @@ static int clk_update_vdd(struct clk_vdd_class *vdd_class)
return rc;
enable_disable_fail:
- regulator_set_voltage(r[i], uv[cur_base + i], uv[max_lvl + i]);
+ regulator_set_voltage(r[i], uv[cur_base + i],
+ vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]);
set_voltage_fail:
for (i--; i >= 0; i--) {
- regulator_set_voltage(r[i], uv[cur_base + i], uv[max_lvl + i]);
+ regulator_set_voltage(r[i], uv[cur_base + i],
+ vdd_class->use_max_uV ? INT_MAX : uv[max_lvl + i]);
if (cur_lvl == 0 || cur_lvl == vdd_class->num_levels)
regulator_disable(r[i]);
else if (level == 0)
@@ -792,6 +794,9 @@ static int clk_vdd_class_init(struct clk_vdd_class *vdd)
{
struct clk_handoff_vdd *v;
+ if (vdd->skip_handoff)
+ return 0;
+
list_for_each_entry(v, &clk_handoff_vdd_list, list) {
if (v->vdd_class == vdd)
return 0;
diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c
index 9ce6a1430250..7094fb4d40af 100644
--- a/drivers/clk/msm/clock-osm.c
+++ b/drivers/clk/msm/clock-osm.c
@@ -81,7 +81,6 @@ enum clk_osm_trace_packet_id {
#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n)))
#define SEQ_REG1_MSM8998_V2 0x1048
#define VERSION_REG 0x0
-#define VERSION_1P1 0x00010100
#define OSM_TABLE_SIZE 40
#define MAX_CLUSTER_CNT 2
@@ -126,6 +125,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
@@ -352,7 +352,6 @@ struct clk_osm {
unsigned long pbases[NUM_BASES];
spinlock_t lock;
- u32 version;
u32 cpu_reg_mask;
u32 num_entries;
u32 cluster_num;
@@ -831,7 +830,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 +1893,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 +1965,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;
}
@@ -2557,7 +2567,7 @@ static int debugfs_set_wdog_trace(void *data, u64 val)
struct clk_osm *c = data;
int regval;
- if (c->version >= VERSION_1P1) {
+ if (msm8998_v2) {
regval = clk_osm_read_reg(c, TRACE_CTRL);
regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS :
regval & ~TRACE_CTRL_ENABLE_WDOG_STATUS;
@@ -3348,9 +3358,6 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
goto exit2;
}
- pwrcl_clk.version = clk_osm_read_reg(&pwrcl_clk, VERSION_REG);
- perfcl_clk.version = clk_osm_read_reg(&perfcl_clk, VERSION_REG);
-
populate_opp_table(pdev);
populate_debugfs_dir(&pwrcl_clk);
populate_debugfs_dir(&perfcl_clk);
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..0bd7e6413a6b 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);
@@ -821,8 +836,8 @@ enum handoff dp_vco_handoff(struct clk *c)
io->handoff_resources = true;
ret = HANDOFF_ENABLED_CLK;
} else {
- io->handoff_resources = false;
mdss_pll_resource_enable(io, false);
+ ret = HANDOFF_DISABLED_CLK;
DEV_DBG("%s: PLL not locked\n", __func__);
}
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/clk/qcom/gcc-msmfalcon.c b/drivers/clk/qcom/gcc-msmfalcon.c
index b5f7e18cf495..5a48fb79c8b2 100644
--- a/drivers/clk/qcom/gcc-msmfalcon.c
+++ b/drivers/clk/qcom/gcc-msmfalcon.c
@@ -705,6 +705,7 @@ static const struct freq_tbl ftbl_hmss_ahb_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+ F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
{ }
};
@@ -820,7 +821,7 @@ static const struct freq_tbl ftbl_qspi_ser_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(80200000, P_PLL1_EARLY_DIV_CLK_SRC, 5, 0, 0),
F(160400000, P_GPLL1_OUT_MAIN, 5, 0, 0),
- F(320800000, P_GPLL1_OUT_MAIN, 2.5, 0, 0),
+ F(267333333, P_GPLL1_OUT_MAIN, 3, 0, 0),
{ }
};
@@ -838,7 +839,7 @@ static struct clk_rcg2 qspi_ser_clk_src = {
VDD_DIG_FMAX_MAP3(
LOWER, 80200000,
LOW, 160400000,
- NOMINAL, 320800000),
+ NOMINAL, 267333333),
},
};
@@ -876,6 +877,7 @@ static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
F(75000000, P_PLL0_EARLY_DIV_CLK_SRC, 4, 0, 0),
F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+ F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
{ }
};
@@ -905,6 +907,7 @@ static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = {
F(50000000, P_PLL0_EARLY_DIV_CLK_SRC, 6, 0, 0),
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
F(192000000, P_GPLL4_OUT_MAIN, 8, 0, 0),
+ F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
{ }
};
@@ -929,6 +932,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
static const struct freq_tbl ftbl_ufs_axi_clk_src[] = {
F(50000000, P_PLL0_EARLY_DIV_CLK_SRC, 6, 0, 0),
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+ F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
{ }
@@ -1045,12 +1049,18 @@ static struct clk_rcg2 usb20_master_clk_src = {
},
};
+static const struct freq_tbl ftbl_usb20_mock_utmi_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+ { }
+};
+
static struct clk_rcg2 usb20_mock_utmi_clk_src = {
.cmd_rcgr = 0x2f024,
.mnd_width = 0,
.hid_width = 5,
.parent_map = gcc_parent_map_0,
- .freq_tbl = ftbl_hmss_rbcpr_clk_src,
+ .freq_tbl = ftbl_usb20_mock_utmi_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "usb20_mock_utmi_clk_src",
.parent_names = gcc_parent_names_0,
diff --git a/drivers/clk/qcom/gpucc-msmfalcon.c b/drivers/clk/qcom/gpucc-msmfalcon.c
index fe7cff443250..9b7dd907a6f3 100644
--- a/drivers/clk/qcom/gpucc-msmfalcon.c
+++ b/drivers/clk/qcom/gpucc-msmfalcon.c
@@ -113,13 +113,7 @@ static struct clk_alpha_pll gpu_pll0_pll_out_main = {
.parent_names = (const char *[]){ "xo" },
.num_parents = 1,
.ops = &clk_alpha_pll_ops,
- VDD_GPU_PLL_FMAX_MAP6(
- MIN, 266000000,
- LOWER, 432000000,
- LOW, 640000000,
- LOW_L1, 800000000,
- NOMINAL, 1020000000,
- HIGH, 1500000000),
+ VDD_GPU_PLL_FMAX_MAP1(LOW_L1, 1500000000),
},
},
};
@@ -136,13 +130,7 @@ static struct clk_alpha_pll gpu_pll1_pll_out_main = {
.parent_names = (const char *[]){ "xo" },
.num_parents = 1,
.ops = &clk_alpha_pll_ops,
- VDD_GPU_PLL_FMAX_MAP6(
- MIN, 266000000,
- LOWER, 432000000,
- LOW, 640000000,
- LOW_L1, 800000000,
- NOMINAL, 1020000000,
- HIGH, 1500000000),
+ VDD_GPU_PLL_FMAX_MAP1(LOW_L1, 1500000000),
},
},
};
@@ -199,6 +187,19 @@ static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
{ }
};
+static const struct freq_tbl ftbl_gfx3d_clk_src_triton[] = {
+ F_GFX( 19200000, 0, 1, 0, 0, 0),
+ F_GFX(160000000, 0, 2, 0, 0, 640000000),
+ F_GFX(240000000, 0, 2, 0, 0, 480000000),
+ F_GFX(370000000, 0, 2, 0, 0, 740000000),
+ F_GFX(465000000, 0, 2, 0, 0, 930000000),
+ F_GFX(588000000, 0, 2, 0, 0, 1176000000),
+ F_GFX(647000000, 0, 2, 0, 0, 1294000000),
+ F_GFX(700000000, 0, 2, 0, 0, 1400000000),
+ F_GFX(775000000, 0, 2, 0, 0, 1550000000),
+ { }
+};
+
static struct clk_rcg2 gfx3d_clk_src = {
.cmd_rcgr = 0x1070,
.mnd_width = 0,
@@ -343,6 +344,7 @@ static const struct qcom_cc_desc gpucc_falcon_desc = {
static const struct of_device_id gpucc_falcon_match_table[] = {
{ .compatible = "qcom,gpucc-msmfalcon" },
+ { .compatible = "qcom,gpucc-msmtriton" },
{ }
};
MODULE_DEVICE_TABLE(of, gpucc_falcon_match_table);
@@ -409,6 +411,7 @@ static int gpucc_falcon_probe(struct platform_device *pdev)
{
int ret = 0;
struct regmap *regmap;
+ bool is_triton = 0;
regmap = qcom_cc_map(pdev, &gpucc_falcon_desc);
if (IS_ERR(regmap))
@@ -441,6 +444,17 @@ static int gpucc_falcon_probe(struct platform_device *pdev)
return PTR_ERR(vdd_gfx.regulator[0]);
}
+ is_triton = of_device_is_compatible(pdev->dev.of_node,
+ "qcom,gpucc-msmtriton");
+ if (is_triton) {
+ gpu_pll0_pll_out_main.clkr.hw.init->rate_max[VDD_DIG_LOW_L1]
+ = 1550000000;
+ gpu_pll1_pll_out_main.clkr.hw.init->rate_max[VDD_DIG_LOW_L1]
+ = 1550000000;
+ /* Add new frequency table */
+ gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_triton;
+ }
+
/* GFX rail fmax data linked to branch clock */
of_get_fmax_vdd_class(pdev, &gpucc_gfx3d_clk.clkr.hw,
"qcom,gfxfreq-corner", 1);
diff --git a/drivers/clk/qcom/mmcc-msmfalcon.c b/drivers/clk/qcom/mmcc-msmfalcon.c
index e4a84765430a..1d874f6db464 100644
--- a/drivers/clk/qcom/mmcc-msmfalcon.c
+++ b/drivers/clk/qcom/mmcc-msmfalcon.c
@@ -906,7 +906,7 @@ static struct clk_rcg2 dp_crypto_clk_src = {
static const struct freq_tbl ftbl_dp_gtc_clk_src[] = {
F(40000000, P_GPLL0_OUT_MAIN_DIV, 7.5, 0, 0),
- F(300000000, P_GPLL0_OUT_MAIN_DIV, 1, 0, 0),
+ F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
{ }
};
@@ -923,7 +923,7 @@ static struct clk_rcg2 dp_gtc_clk_src = {
.ops = &clk_rcg2_ops,
VDD_DIG_FMAX_MAP2(
LOWER, 40000000,
- LOW, 300000000),
+ LOW, 60000000),
},
};
@@ -1136,9 +1136,10 @@ static struct clk_rcg2 mdp_clk_src = {
.parent_names = mmcc_parent_names_7,
.num_parents = 7,
.ops = &clk_rcg2_ops,
- VDD_DIG_FMAX_MAP4(
+ VDD_DIG_FMAX_MAP5(
LOWER, 171428571,
LOW, 275000000,
+ LOW_L1, 300000000,
NOMINAL, 330000000,
HIGH, 412500000),
},
@@ -1183,6 +1184,7 @@ static struct clk_rcg2 pclk1_clk_src = {
static const struct freq_tbl ftbl_rot_clk_src[] = {
F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
F(275000000, P_MMPLL5_PLL_OUT_MAIN, 3, 0, 0),
+ F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
F(330000000, P_MMPLL5_PLL_OUT_MAIN, 2.5, 0, 0),
F(412500000, P_MMPLL5_PLL_OUT_MAIN, 2, 0, 0),
{ }
@@ -1199,9 +1201,10 @@ static struct clk_rcg2 rot_clk_src = {
.parent_names = mmcc_parent_names_7,
.num_parents = 7,
.ops = &clk_rcg2_ops,
- VDD_DIG_FMAX_MAP4(
+ VDD_DIG_FMAX_MAP5(
LOWER, 171428571,
LOW, 275000000,
+ LOW_L1, 300000000,
NOMINAL, 330000000,
HIGH, 412500000),
},
diff --git a/drivers/clk/qcom/vdd-level-falcon.h b/drivers/clk/qcom/vdd-level-falcon.h
index 8f9eefe3a89c..75567dbe2329 100644
--- a/drivers/clk/qcom/vdd-level-falcon.h
+++ b/drivers/clk/qcom/vdd-level-falcon.h
@@ -104,15 +104,10 @@
}, \
.num_rate_max = VDD_DIG_NUM
-#define VDD_GPU_PLL_FMAX_MAP6(l1, f1, l2, f2, l3, f3, l4, f4, l5, f5, l6, f6) \
+#define VDD_GPU_PLL_FMAX_MAP1(l1, f1) \
.vdd_class = &vdd_mx, \
- .rate_max = (unsigned long[VDD_DIG_NUM]) { \
+ .rate_max = (unsigned long[VDD_DIG_NUM]) { \
[VDD_DIG_##l1] = (f1), \
- [VDD_DIG_##l2] = (f2), \
- [VDD_DIG_##l3] = (f3), \
- [VDD_DIG_##l4] = (f4), \
- [VDD_DIG_##l5] = (f5), \
- [VDD_DIG_##l6] = (f6), \
}, \
.num_rate_max = VDD_DIG_NUM
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 1c30b43fdfcf..2c8345aadc07 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -676,11 +676,13 @@ ssize_t adreno_coresight_store_register(struct device *dev,
* @registers - Array of GPU specific registers to configure trace bus output
* @count - Number of registers in the array
* @groups - Pointer to an attribute list of control files
+ * @atid - The unique ATID value of the coresight device
*/
struct adreno_coresight {
struct adreno_coresight_register *registers;
unsigned int count;
const struct attribute_group **groups;
+ unsigned int atid;
};
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/adreno_coresight.c b/drivers/gpu/msm/adreno_coresight.c
index 02a39278ccb3..901e2144c6d8 100644
--- a/drivers/gpu/msm/adreno_coresight.c
+++ b/drivers/gpu/msm/adreno_coresight.c
@@ -200,6 +200,9 @@ static int _adreno_coresight_set(struct adreno_device *adreno_dev)
kgsl_regwrite(device, coresight->registers[i].offset,
coresight->registers[i].value);
+ kgsl_property_read_u32(device, "coresight-atid",
+ (unsigned int *)&(coresight->atid));
+
return 0;
}
/**
@@ -281,7 +284,16 @@ void adreno_coresight_start(struct adreno_device *adreno_dev)
_adreno_coresight_set(adreno_dev);
}
+static int adreno_coresight_trace_id(struct coresight_device *csdev)
+{
+ struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
+ struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(ADRENO_DEVICE(device));
+
+ return gpudev->coresight->atid;
+}
+
static const struct coresight_ops_source adreno_coresight_source_ops = {
+ .trace_id = adreno_coresight_trace_id,
.enable = adreno_coresight_enable,
.disable = adreno_coresight_disable,
};
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/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index cc8d957e0581..34b12e015768 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -562,7 +562,7 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
writel_relaxed(drvdata->paddr, drvdata->base + TMC_DBALO);
- writel_relaxed(((dma_addr_t)drvdata->paddr >> 32) & 0xFF,
+ writel_relaxed(((u64)drvdata->paddr >> 32) & 0xFF,
drvdata->base + TMC_DBAHI);
writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c
index f94ecf02d9cb..05cd1edefb7f 100644
--- a/drivers/input/misc/hbtp_input.c
+++ b/drivers/input/misc/hbtp_input.c
@@ -54,6 +54,7 @@ struct hbtp_data {
struct pinctrl *ts_pinctrl;
struct pinctrl_state *gpio_state_active;
struct pinctrl_state *gpio_state_suspend;
+ bool ddic_rst_enabled;
struct pinctrl_state *ddic_rst_state_active;
struct pinctrl_state *ddic_rst_state_suspend;
u32 ts_pinctrl_seq_delay;
@@ -521,15 +522,17 @@ static int hbtp_pinctrl_enable(struct hbtp_data *ts, bool on)
if (rc < 0)
return -EINVAL;
- rc = hbtp_ddic_rst_select(ts, true);
- if (rc < 0)
- goto err_ddic_rst_pinctrl_enable;
+ if (ts->ddic_rst_enabled) {
+ rc = hbtp_ddic_rst_select(ts, true);
+ if (rc < 0)
+ goto err_ddic_rst_pinctrl_enable;
+ }
return rc;
pinctrl_suspend:
- if (ts->ddic_rst_state_suspend)
- hbtp_ddic_rst_select(ts, true);
+ if (ts->ddic_rst_enabled)
+ hbtp_ddic_rst_select(ts, false);
err_ddic_rst_pinctrl_enable:
hbtp_gpio_select(ts, false);
return rc;
@@ -1078,8 +1081,10 @@ static int hbtp_pinctrl_init(struct hbtp_data *data)
dev_err(&data->pdev->dev, "count(%u) is not same as %u\n",
(u32)count, HBTP_PINCTRL_DDIC_SEQ_NUM);
}
+
+ data->ddic_rst_enabled = true;
} else {
- dev_err(&data->pdev->dev, "ddic pinctrl act/sus not found\n");
+ dev_warn(&data->pdev->dev, "ddic pinctrl act/sus not found\n");
}
data->manage_pin_ctrl = true;
diff --git a/drivers/input/qpnp-power-on.c b/drivers/input/qpnp-power-on.c
index a4057045e3e4..760c92a47a36 100644
--- a/drivers/input/qpnp-power-on.c
+++ b/drivers/input/qpnp-power-on.c
@@ -32,11 +32,6 @@
#include <linux/regulator/of_regulator.h>
#include <linux/qpnp/power-on.h>
-#define CREATE_MASK(NUM_BITS, POS) \
- ((unsigned char) (((1 << (NUM_BITS)) - 1) << (POS)))
-#define PON_MASK(MSB_BIT, LSB_BIT) \
- CREATE_MASK(MSB_BIT - LSB_BIT + 1, LSB_BIT)
-
#define PMIC_VER_8941 0x01
#define PMIC_VERSION_REG 0x0105
#define PMIC_VERSION_REV4_REG 0x0103
@@ -109,6 +104,7 @@
#define QPNP_PON_S2_CNTL_EN BIT(7)
#define QPNP_PON_S2_RESET_ENABLE BIT(7)
#define QPNP_PON_DELAY_BIT_SHIFT 6
+#define QPNP_PON_GEN2_DELAY_BIT_SHIFT 14
#define QPNP_PON_S1_TIMER_MASK (0xF)
#define QPNP_PON_S2_TIMER_MASK (0x7)
@@ -135,7 +131,7 @@
#define QPNP_PON_S3_SRC_KPDPWR_AND_RESIN 2
#define QPNP_PON_S3_SRC_KPDPWR_OR_RESIN 3
#define QPNP_PON_S3_SRC_MASK 0x3
-#define QPNP_PON_HARD_RESET_MASK PON_MASK(7, 5)
+#define QPNP_PON_HARD_RESET_MASK GENMASK(7, 5)
#define QPNP_PON_UVLO_DLOAD_EN BIT(7)
#define QPNP_PON_SMPL_EN BIT(7)
@@ -149,6 +145,8 @@
#define PON_S1_COUNT_MAX 0xF
#define QPNP_PON_MIN_DBC_US (USEC_PER_SEC / 64)
#define QPNP_PON_MAX_DBC_US (USEC_PER_SEC * 2)
+#define QPNP_PON_GEN2_MIN_DBC_US 62
+#define QPNP_PON_GEN2_MAX_DBC_US (USEC_PER_SEC / 4)
#define QPNP_KEY_STATUS_DELAY msecs_to_jiffies(250)
@@ -227,7 +225,7 @@ static DEFINE_SPINLOCK(spon_list_slock);
static LIST_HEAD(spon_dev_list);
static u32 s1_delay[PON_S1_COUNT_MAX + 1] = {
- 0 , 32, 56, 80, 138, 184, 272, 408, 608, 904, 1352, 2048,
+ 0, 32, 56, 80, 138, 184, 272, 408, 608, 904, 1352, 2048,
3072, 4480, 6720, 10256
};
@@ -292,14 +290,6 @@ static const char * const qpnp_poff_reason[] = {
[39] = "Triggered from S3_RESET_KPDPWR_ANDOR_RESIN (power key and/or reset line)",
};
-/*
- * On the kernel command line specify
- * qpnp-power-on.warm_boot=1 to indicate a warm
- * boot of the device.
- */
-static int warm_boot;
-module_param(warm_boot, int, 0);
-
static int
qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val)
{
@@ -349,10 +339,10 @@ int qpnp_pon_set_restart_reason(enum pon_restart_reason reason)
if (is_pon_gen2(pon))
rc = qpnp_pon_masked_write(pon, QPNP_PON_SOFT_RB_SPARE(pon),
- PON_MASK(7, 1), (reason << 1));
+ GENMASK(7, 1), (reason << 1));
else
rc = qpnp_pon_masked_write(pon, QPNP_PON_SOFT_RB_SPARE(pon),
- PON_MASK(7, 2), (reason << 2));
+ GENMASK(7, 2), (reason << 2));
if (rc)
dev_err(&pon->pdev->dev,
@@ -383,23 +373,31 @@ EXPORT_SYMBOL(qpnp_pon_check_hard_reset_stored);
static int qpnp_pon_set_dbc(struct qpnp_pon *pon, u32 delay)
{
int rc = 0;
- u32 delay_reg;
+ u32 val;
if (delay == pon->dbc)
goto out;
+
if (pon->pon_input)
mutex_lock(&pon->pon_input->mutex);
- if (delay < QPNP_PON_MIN_DBC_US)
- delay = QPNP_PON_MIN_DBC_US;
- else if (delay > QPNP_PON_MAX_DBC_US)
- delay = QPNP_PON_MAX_DBC_US;
+ if (is_pon_gen2(pon)) {
+ if (delay < QPNP_PON_GEN2_MIN_DBC_US)
+ delay = QPNP_PON_GEN2_MIN_DBC_US;
+ else if (delay > QPNP_PON_GEN2_MAX_DBC_US)
+ delay = QPNP_PON_GEN2_MAX_DBC_US;
+ val = (delay << QPNP_PON_GEN2_DELAY_BIT_SHIFT) / USEC_PER_SEC;
+ } else {
+ if (delay < QPNP_PON_MIN_DBC_US)
+ delay = QPNP_PON_MIN_DBC_US;
+ else if (delay > QPNP_PON_MAX_DBC_US)
+ delay = QPNP_PON_MAX_DBC_US;
+ val = (delay << QPNP_PON_DELAY_BIT_SHIFT) / USEC_PER_SEC;
+ }
- delay_reg = (delay << QPNP_PON_DELAY_BIT_SHIFT) / USEC_PER_SEC;
- delay_reg = ilog2(delay_reg);
+ val = ilog2(val);
rc = qpnp_pon_masked_write(pon, QPNP_PON_DBC_CTL(pon),
- QPNP_PON_DBC_DELAY_MASK(pon),
- delay_reg);
+ QPNP_PON_DBC_DELAY_MASK(pon), val);
if (rc) {
dev_err(&pon->pdev->dev, "Unable to set PON debounce\n");
goto unlock;
@@ -795,7 +793,8 @@ qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type)
cfg->key_code, pon_rt_sts);
key_status = pon_rt_sts & pon_rt_bit;
- /* simulate press event in case release event occured
+ /*
+ * simulate press event in case release event occurred
* without a press event
*/
if (!cfg->old_state && !key_status) {
@@ -1207,8 +1206,6 @@ qpnp_pon_config_input(struct qpnp_pon *pon, struct qpnp_pon_config *cfg)
pon->pon_input->phys = "qpnp_pon/input0";
}
- /* don't send dummy release event when system resumes */
- __set_bit(INPUT_PROP_NO_DUMMY_RELEASE, pon->pon_input->propbit);
input_set_capability(pon->pon_input, EV_KEY, cfg->key_code);
return 0;
@@ -1258,7 +1255,7 @@ static int qpnp_pon_config_init(struct qpnp_pon *pon)
if (rc == -EINVAL) {
dev_dbg(&pon->pdev->dev,
"'qcom,support-reset' DT property doesn't exist\n");
- } else {
+ } else {
dev_err(&pon->pdev->dev,
"Unable to read 'qcom,support-reset'\n");
return rc;
@@ -1280,10 +1277,12 @@ static int qpnp_pon_config_init(struct qpnp_pon *pon)
}
}
- /* If the value read from REVISION2 register is 0x00,
- then there is a single register to control s2 reset.
- Otherwise there are separate registers for s2 reset
- type and s2 reset enable */
+ /*
+ * If the value read from REVISION2 register is 0x00,
+ * then there is a single register to control s2 reset.
+ * Otherwise there are separate registers for s2 reset
+ * type and s2 reset enable.
+ */
if (pon->pon_ver == QPNP_PON_GEN1_V1) {
cfg->s2_cntl_addr = cfg->s2_cntl2_addr =
QPNP_PON_KPDPWR_S2_CNTL(pon);
@@ -1344,8 +1343,10 @@ static int qpnp_pon_config_init(struct qpnp_pon *pon)
return rc;
}
- /*PM8941 V3 does not have harware bug. Hence
- bark is not required from PMIC versions 3.0*/
+ /*
+ * PM8941 V3 does not have hardware bug. Hence
+ * bark is not required from PMIC versions 3.0.
+ */
if (!(revid_rev4 == PMIC8941_V1_REV4 ||
revid_rev4 == PMIC8941_V2_REV4)) {
cfg->support_reset = false;
@@ -1669,7 +1670,8 @@ static int pon_regulator_init(struct qpnp_pon *pon)
return rc;
}
- init_data = of_get_regulator_init_data(dev, node, &pon_reg->rdesc);
+ init_data = of_get_regulator_init_data(dev, node,
+ &pon_reg->rdesc);
if (!init_data) {
dev_err(dev, "regulator init data is missing\n");
return -EINVAL;
@@ -1847,8 +1849,7 @@ static void qpnp_pon_debugfs_init(struct platform_device *pdev)
dev_err(&pon->pdev->dev,
"Unable to create debugfs directory\n");
} else {
- ent = debugfs_create_file("uvlo_panic",
- S_IFREG | S_IWUSR | S_IRUGO,
+ ent = debugfs_create_file("uvlo_panic", 0644,
pon->debugfs, pon, &qpnp_pon_debugfs_uvlo_fops);
if (!ent)
dev_err(&pon->pdev->dev,
@@ -2203,8 +2204,7 @@ static int qpnp_pon_probe(struct platform_device *pdev)
if (rc) {
if (rc != -EINVAL) {
dev_err(&pdev->dev,
- "Unable to read debounce delay rc: %d\n",
- rc);
+ "Unable to read debounce delay rc: %d\n", rc);
return rc;
}
} else {
@@ -2308,7 +2308,7 @@ static int qpnp_pon_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,qpnp-power-on", },
{}
};
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 499ba692d53c..fc4bc283ccaf 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -1936,7 +1936,7 @@ static int ft5x06_debug_data_get(void *_data, u64 *val)
{
struct ft5x06_ts_data *data = _data;
int rc;
- u8 reg;
+ u8 reg = 0;
mutex_lock(&data->input_dev->mutex);
@@ -2255,7 +2255,7 @@ static int ft5x06_ts_probe(struct i2c_client *client,
struct ft5x06_ts_data *data;
struct input_dev *input_dev;
struct dentry *temp;
- u8 reg_value;
+ u8 reg_value = 0;
u8 reg_addr;
int err, len, retval, attr_count;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index eac6d07e6097..791f2fe70236 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -407,6 +407,9 @@ struct arm_smmu_device {
unsigned int clock_refs_count;
spinlock_t clock_refs_lock;
+ struct mutex power_lock;
+ unsigned int power_count;
+
struct msm_bus_client_handle *bus_client;
char *bus_client_name;
@@ -919,17 +922,43 @@ static int arm_smmu_unrequest_bus(struct arm_smmu_device *smmu)
static int arm_smmu_disable_regulators(struct arm_smmu_device *smmu)
{
+ int ret = 0;
+
+ mutex_lock(&smmu->power_lock);
+ if (smmu->power_count == 0) {
+ WARN(1, "%s: Mismatched power count\n", dev_name(smmu->dev));
+ mutex_unlock(&smmu->power_lock);
+ return -EINVAL;
+ } else if (smmu->power_count > 1) {
+ smmu->power_count -= 1;
+ mutex_unlock(&smmu->power_lock);
+ return 0;
+ }
+
arm_smmu_unprepare_clocks(smmu);
arm_smmu_unrequest_bus(smmu);
- if (!smmu->gdsc)
- return 0;
- return regulator_disable(smmu->gdsc);
+ if (smmu->gdsc) {
+ ret = regulator_disable(smmu->gdsc);
+ WARN(ret, "%s: Regulator disable failed\n",
+ dev_name(smmu->dev));
+ }
+
+ smmu->power_count = 0;
+ mutex_unlock(&smmu->power_lock);
+ return ret;
}
static int arm_smmu_enable_regulators(struct arm_smmu_device *smmu)
{
int ret;
+ mutex_lock(&smmu->power_lock);
+ if (smmu->power_count) {
+ smmu->power_count++;
+ mutex_unlock(&smmu->power_lock);
+ return 0;
+ }
+
if (smmu->gdsc) {
ret = regulator_enable(smmu->gdsc);
if (WARN_ON_ONCE(ret))
@@ -944,6 +973,8 @@ static int arm_smmu_enable_regulators(struct arm_smmu_device *smmu)
if (WARN_ON_ONCE(ret))
goto out_bus;
+ smmu->power_count = 1;
+ mutex_unlock(&smmu->power_lock);
return ret;
out_bus:
@@ -952,6 +983,7 @@ out_reg:
if (smmu->gdsc)
regulator_disable(smmu->gdsc);
out:
+ mutex_unlock(&smmu->power_lock);
return ret;
}
@@ -2217,8 +2249,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
* refcounting) is that we never disable regulators while a
* client is attached in these cases.
*/
- if (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE) ||
- atomic_ctx) {
+ if (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE)) {
ret = arm_smmu_enable_regulators(smmu);
if (ret)
goto err_unlock;
@@ -2235,12 +2266,18 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
}
smmu->attach_count++;
+ if (atomic_ctx) {
+ ret = arm_smmu_enable_regulators(smmu);
+ if (ret)
+ goto err_disable_clocks;
+ }
+
if (arm_smmu_is_static_cb(smmu)) {
ret = arm_smmu_populate_cb(smmu, smmu_domain, dev);
if (ret) {
dev_err(dev, "Failed to get valid context bank\n");
- goto err_disable_clocks;
+ goto err_atomic_ctx;
}
smmu_domain->slave_side_secure = true;
}
@@ -2248,13 +2285,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
cfg = find_smmu_master_cfg(dev);
if (!cfg) {
ret = -ENODEV;
- goto err_disable_clocks;
+ goto err_atomic_ctx;
}
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu, cfg);
if (IS_ERR_VALUE(ret))
- goto err_disable_clocks;
+ goto err_atomic_ctx;
/*
* Sanity check the domain. We don't support domains across
@@ -2280,12 +2317,15 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
err_destroy_domain_context:
arm_smmu_destroy_domain_context(domain);
+err_atomic_ctx:
+ if (atomic_ctx)
+ arm_smmu_disable_regulators(smmu);
err_disable_clocks:
arm_smmu_disable_clocks(smmu);
--smmu->attach_count;
err_disable_regulators:
if (!smmu->attach_count &&
- (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE) || atomic_ctx))
+ (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE)))
arm_smmu_disable_regulators(smmu);
err_unlock:
mutex_unlock(&smmu->attach_lock);
@@ -2293,8 +2333,7 @@ err_unlock:
return ret;
}
-static void arm_smmu_power_off(struct arm_smmu_device *smmu,
- bool force_regulator_disable)
+static void arm_smmu_power_off(struct arm_smmu_device *smmu)
{
/* Turn the thing off */
if (arm_smmu_enable_clocks(smmu))
@@ -2302,8 +2341,7 @@ static void arm_smmu_power_off(struct arm_smmu_device *smmu,
writel_relaxed(sCR0_CLIENTPD,
ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
arm_smmu_disable_clocks(smmu);
- if (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE)
- || force_regulator_disable)
+ if (!(smmu->options & ARM_SMMU_OPT_REGISTER_SAVE))
arm_smmu_disable_regulators(smmu);
}
@@ -2345,6 +2383,8 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
if (smmu_domain->attributes & (1 << DOMAIN_ATTR_DYNAMIC)) {
arm_smmu_detach_dynamic(domain, smmu);
mutex_unlock(&smmu_domain->init_mutex);
+ if (atomic_ctx)
+ arm_smmu_disable_regulators(smmu);
return;
}
@@ -2358,7 +2398,9 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
arm_smmu_domain_remove_master(smmu_domain, cfg);
arm_smmu_destroy_domain_context(domain);
if (!--smmu->attach_count)
- arm_smmu_power_off(smmu, atomic_ctx);
+ arm_smmu_power_off(smmu);
+ if (atomic_ctx)
+ arm_smmu_disable_regulators(smmu);
unlock:
mutex_unlock(&smmu->attach_lock);
mutex_unlock(&smmu_domain->init_mutex);
@@ -3789,6 +3831,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
}
smmu->dev = dev;
mutex_init(&smmu->attach_lock);
+ mutex_init(&smmu->power_lock);
spin_lock_init(&smmu->atos_lock);
spin_lock_init(&smmu->clock_refs_lock);
INIT_LIST_HEAD(&smmu->static_cbndx_list);
@@ -3970,7 +4013,7 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
* still powered on. Power off now.
*/
if (smmu->attach_count)
- arm_smmu_power_off(smmu, false);
+ arm_smmu_power_off(smmu);
mutex_unlock(&smmu->attach_lock);
msm_bus_scale_unregister(smmu->bus_client);
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/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 3333f15f7f16..1cd1a18dd037 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -69,9 +69,12 @@
#define ARM_LPAE_PGD_IDX(l,d) \
((l) == ARM_LPAE_START_LVL(d) ? ilog2(ARM_LPAE_PAGES_PER_PGD(d)) : 0)
+#define ARM_LPAE_LVL_MASK(l, d) \
+ ((l) == ARM_LPAE_START_LVL(d) ? (1 << (d)->pgd_bits) - 1 : \
+ (1 << (d)->bits_per_level) - 1)
#define ARM_LPAE_LVL_IDX(a,l,d) \
(((u64)(a) >> ARM_LPAE_LVL_SHIFT(l,d)) & \
- ((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
+ ARM_LPAE_LVL_MASK(l, d))
/* Calculate the block/page mapping size at level l for pagetable in d. */
#define ARM_LPAE_BLOCK_SIZE(l,d) \
@@ -197,6 +200,7 @@ struct arm_lpae_io_pgtable {
struct io_pgtable iop;
int levels;
+ unsigned int pgd_bits;
size_t pgd_size;
unsigned long pg_shift;
unsigned long bits_per_level;
@@ -913,6 +917,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
/* Calculate the actual size of our pgd (without concatenation) */
pgd_bits = va_bits - (data->bits_per_level * (data->levels - 1));
+ data->pgd_bits = pgd_bits;
data->pgd_size = 1UL << (pgd_bits + ilog2(sizeof(arm_lpae_iopte)));
data->iop.ops = (struct io_pgtable_ops) {
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 7b0c1ae5a48d..a2b89c9d347a 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -454,13 +454,13 @@ static inline void iommu_debug_destroy_tracking(void) { }
#ifdef CONFIG_64BIT
#define kstrtoux kstrtou64
-#define kstrtox_from_user kstrtoll_from_user
+#define kstrtox_from_user kstrtoull_from_user
#define kstrtosize_t kstrtoul
#else
#define kstrtoux kstrtou32
-#define kstrtox_from_user kstrtoint_from_user
+#define kstrtox_from_user kstrtouint_from_user
#define kstrtosize_t kstrtouint
#endif
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 9695c35c56b4..85b1133df4f5 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -27,17 +27,12 @@
#include <linux/leds-qpnp-wled.h>
#include <linux/qpnp/qpnp-revid.h>
-#define QPNP_IRQ_FLAGS (IRQF_TRIGGER_RISING | \
- IRQF_TRIGGER_FALLING | \
- IRQF_ONESHOT)
-
/* base addresses */
#define QPNP_WLED_CTRL_BASE "qpnp-wled-ctrl-base"
#define QPNP_WLED_SINK_BASE "qpnp-wled-sink-base"
/* ctrl registers */
-#define QPNP_WLED_INT_EN_SET(b) (b + 0x15)
-#define QPNP_WLED_INT_EN_CLR(b) (b + 0x16)
+#define QPNP_WLED_FAULT_STATUS(b) (b + 0x08)
#define QPNP_WLED_EN_REG(b) (b + 0x46)
#define QPNP_WLED_FDBK_OP_REG(b) (b + 0x48)
#define QPNP_WLED_VREF_REG(b) (b + 0x49)
@@ -114,8 +109,6 @@
#define QPNP_WLED_SWITCH_FREQ_OVERWRITE 0x80
#define QPNP_WLED_OVP_MASK GENMASK(1, 0)
#define QPNP_WLED_TEST4_EN_VREF_UP 0x32
-#define QPNP_WLED_INT_EN_SET_OVP_EN 0x02
-#define QPNP_WLED_OVP_FLT_SLEEP_US 10
#define QPNP_WLED_TEST4_EN_IIND_UP 0x1
/* sink registers */
@@ -183,7 +176,7 @@
#define QPNP_WLED_MODULE_EN_REG(b) (b + 0x46)
#define QPNP_WLED_MODULE_RDY_MASK 0x7F
#define QPNP_WLED_MODULE_RDY_SHIFT 7
-#define QPNP_WLED_MODULE_EN_MASK 0x7F
+#define QPNP_WLED_MODULE_EN_MASK BIT(7)
#define QPNP_WLED_MODULE_EN_SHIFT 7
#define QPNP_WLED_DISP_SEL_MASK 0x7F
#define QPNP_WLED_DISP_SEL_SHIFT 7
@@ -312,8 +305,6 @@ static struct wled_vref_setting vref_setting_pmi8998 = {
* @ avdd_target_voltage_mv - target voltage for AVDD module in mV
* @ ctrl_base - base address for wled ctrl
* @ sink_base - base address for wled sink
- * @ ibb_base - base address for IBB(Inverting Buck Boost)
- * @ lab_base - base address for LAB(LCD/AMOLED Boost)
* @ mod_freq_khz - modulator frequency in KHZ
* @ hyb_thres - threshold for hybrid dimming
* @ sync_dly_us - sync delay in us
@@ -341,8 +332,6 @@ static struct wled_vref_setting vref_setting_pmi8998 = {
* @ en_phase_stag - enable or disable phase staggering
* @ en_cabc - enable or disable cabc
* @ disp_type_amoled - type of display: LCD/AMOLED
- * @ ibb_bias_active - activate display bias
- * @ lab_fast_precharge - fast/slow precharge
* @ en_ext_pfet_sc_pro - enable sc protection on external pfet
*/
struct qpnp_wled {
@@ -390,10 +379,11 @@ struct qpnp_wled {
bool disp_type_amoled;
bool en_ext_pfet_sc_pro;
bool prev_state;
+ bool ovp_irq_disabled;
};
/* helper to read a pmic register */
-static int qpnp_wled_read_reg(struct qpnp_wled *wled, u8 *data, u16 addr)
+static int qpnp_wled_read_reg(struct qpnp_wled *wled, u16 addr, u8 *data)
{
int rc;
uint val;
@@ -410,7 +400,7 @@ static int qpnp_wled_read_reg(struct qpnp_wled *wled, u8 *data, u16 addr)
}
/* helper to write a pmic register */
-static int qpnp_wled_write_reg(struct qpnp_wled *wled, u8 data, u16 addr)
+static int qpnp_wled_write_reg(struct qpnp_wled *wled, u16 addr, u8 data)
{
int rc;
@@ -428,25 +418,26 @@ out:
return rc;
}
-static int qpnp_wled_masked_write_reg(struct qpnp_wled *wled, u8 mask, u8 *data,
- u16 addr)
+static int qpnp_wled_masked_write_reg(struct qpnp_wled *wled, u16 addr,
+ u8 mask, u8 data)
{
- u8 reg;
int rc;
- rc = qpnp_wled_read_reg(wled, &reg, addr);
- if (rc < 0)
- return rc;
-
- reg &= ~mask;
- reg |= *data & mask;
-
- rc = qpnp_wled_write_reg(wled, reg, addr);
+ mutex_lock(&wled->bus_lock);
+ rc = regmap_update_bits(wled->regmap, addr, mask, data);
+ if (rc < 0) {
+ dev_err(&wled->pdev->dev, "Error writing address: %x(%d)\n",
+ addr, rc);
+ goto out;
+ }
+ dev_dbg(&wled->pdev->dev, "wrote: WLED_0x%x = 0x%x\n", addr, data);
+out:
+ mutex_unlock(&wled->bus_lock);
return rc;
}
-static int qpnp_wled_sec_write_reg(struct qpnp_wled *wled, u8 data, u16 addr)
+static int qpnp_wled_sec_write_reg(struct qpnp_wled *wled, u16 addr, u8 data)
{
int rc;
u8 reg = QPNP_WLED_SEC_UNLOCK;
@@ -481,8 +472,8 @@ static int qpnp_wled_sync_reg_toggle(struct qpnp_wled *wled)
/* sync */
reg = QPNP_WLED_SYNC;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SYNC_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_SYNC_REG(wled->sink_base),
+ reg);
if (rc < 0)
return rc;
@@ -491,8 +482,8 @@ static int qpnp_wled_sync_reg_toggle(struct qpnp_wled *wled)
wled->cons_sync_write_delay_us + 1);
reg = QPNP_WLED_SYNC_RESET;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SYNC_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_SYNC_REG(wled->sink_base),
+ reg);
if (rc < 0)
return rc;
@@ -508,17 +499,17 @@ static int qpnp_wled_set_level(struct qpnp_wled *wled, int level)
/* set brightness registers */
for (i = 0; i < wled->num_strings; i++) {
reg = level & QPNP_WLED_BRIGHT_LSB_MASK;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_BRIGHT_LSB_REG(wled->sink_base,
- wled->strings[i]));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_BRIGHT_LSB_REG(wled->sink_base,
+ wled->strings[i]), reg);
if (rc < 0)
return rc;
reg = level >> QPNP_WLED_BRIGHT_MSB_SHIFT;
reg = reg & QPNP_WLED_BRIGHT_MSB_MASK;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_BRIGHT_MSB_REG(wled->sink_base,
- wled->strings[i]));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_BRIGHT_MSB_REG(wled->sink_base,
+ wled->strings[i]), reg);
if (rc < 0)
return rc;
}
@@ -536,36 +527,29 @@ static int qpnp_wled_module_en(struct qpnp_wled *wled,
u16 base_addr, bool state)
{
int rc;
- u8 reg;
- /* disable OVP fault interrupt */
- if (state) {
- reg = QPNP_WLED_INT_EN_SET_OVP_EN;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_INT_EN_CLR(base_addr));
- if (rc)
- return rc;
- }
-
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_MODULE_EN_REG(base_addr));
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(base_addr),
+ QPNP_WLED_MODULE_EN_MASK,
+ state << QPNP_WLED_MODULE_EN_SHIFT);
if (rc < 0)
return rc;
- reg &= QPNP_WLED_MODULE_EN_MASK;
- reg |= (state << QPNP_WLED_MODULE_EN_SHIFT);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_MODULE_EN_REG(base_addr));
- if (rc)
- return rc;
- /* enable OVP fault interrupt */
- if (state && (wled->ovp_irq > 0)) {
- udelay(QPNP_WLED_OVP_FLT_SLEEP_US);
- reg = QPNP_WLED_INT_EN_SET_OVP_EN;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_INT_EN_SET(base_addr));
- if (rc)
- return rc;
+ if (wled->ovp_irq > 0) {
+ if (state && wled->ovp_irq_disabled) {
+ /*
+ * Wait for at least 10ms before enabling OVP fault
+ * interrupt after enabling the module so that soft
+ * start is completed. Keep OVP interrupt disabled
+ * when the module is disabled.
+ */
+ usleep_range(10000, 11000);
+ enable_irq(wled->ovp_irq);
+ wled->ovp_irq_disabled = false;
+ } else if (!state && !wled->ovp_irq_disabled) {
+ disable_irq(wled->ovp_irq);
+ wled->ovp_irq_disabled = true;
+ }
}
return 0;
@@ -656,8 +640,7 @@ static int qpnp_wled_dump_regs(struct qpnp_wled *wled, u16 base_addr,
u8 reg;
for (i = 0; i < size; i++) {
- rc = qpnp_wled_read_reg(wled, &reg,
- base_addr + dbg_regs[i]);
+ rc = qpnp_wled_read_reg(wled, base_addr + dbg_regs[i], &reg);
if (rc < 0)
return rc;
@@ -783,8 +766,7 @@ static ssize_t qpnp_wled_dim_mode_store(struct device *dev,
if (temp == wled->dim_mode)
return count;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_MOD_REG(wled->sink_base));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_MOD_REG(wled->sink_base), &reg);
if (rc < 0)
return rc;
@@ -798,8 +780,7 @@ static ssize_t qpnp_wled_dim_mode_store(struct device *dev,
reg |= temp;
}
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_MOD_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_MOD_REG(wled->sink_base), reg);
if (rc)
return rc;
@@ -834,17 +815,17 @@ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev,
else if (data > QPNP_WLED_FS_CURR_MAX_UA)
data = QPNP_WLED_FS_CURR_MAX_UA;
- rc = qpnp_wled_read_reg(wled, &reg,
+ rc = qpnp_wled_read_reg(wled,
QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_FS_CURR_MASK;
temp = data / QPNP_WLED_FS_CURR_STEP_UA;
reg |= temp;
- rc = qpnp_wled_write_reg(wled, reg,
+ rc = qpnp_wled_write_reg(wled,
QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), reg);
if (rc)
return rc;
}
@@ -950,16 +931,15 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
u8 reg;
/* display type */
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_DISP_SEL_REG(base_addr));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_DISP_SEL_REG(base_addr), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_DISP_SEL_MASK;
reg |= (wled->disp_type_amoled << QPNP_WLED_DISP_SEL_SHIFT);
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_DISP_SEL_REG(base_addr));
+ rc = qpnp_wled_sec_write_reg(wled, QPNP_WLED_DISP_SEL_REG(base_addr),
+ reg);
if (rc)
return rc;
@@ -970,8 +950,8 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
else if (wled->vref_psm_mv > QPNP_WLED_VREF_PSM_MAX_MV)
wled->vref_psm_mv = QPNP_WLED_VREF_PSM_MAX_MV;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_PSM_CTRL_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_PSM_CTRL_REG(wled->ctrl_base), &reg);
if (rc < 0)
return rc;
@@ -979,8 +959,8 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
reg |= ((wled->vref_psm_mv - QPNP_WLED_VREF_PSM_MIN_MV)/
QPNP_WLED_VREF_PSM_STEP_MV);
reg |= QPNP_WLED_PSM_CTRL_OVERWRITE;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_PSM_CTRL_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_PSM_CTRL_REG(wled->ctrl_base), reg);
if (rc)
return rc;
@@ -993,8 +973,9 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
wled->loop_comp_res_kohm =
QPNP_WLED_LOOP_COMP_RES_MAX_KOHM;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_VLOOP_COMP_RES_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_VLOOP_COMP_RES_REG(wled->ctrl_base),
+ &reg);
if (rc < 0)
return rc;
@@ -1003,20 +984,21 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
QPNP_WLED_LOOP_COMP_RES_MIN_KOHM)/
QPNP_WLED_LOOP_COMP_RES_STEP_KOHM);
reg |= QPNP_WLED_VLOOP_COMP_RES_OVERWRITE;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_VLOOP_COMP_RES_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_VLOOP_COMP_RES_REG(wled->ctrl_base),
+ reg);
if (rc)
return rc;
/* Configure the CTRL TEST4 register for AMOLED */
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_TEST4_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_TEST4_REG(wled->ctrl_base), &reg);
if (rc < 0)
return rc;
reg |= QPNP_WLED_TEST4_EN_IIND_UP;
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_TEST4_REG(base_addr));
+ rc = qpnp_wled_sec_write_reg(wled,
+ QPNP_WLED_TEST4_REG(base_addr), reg);
if (rc)
return rc;
} else {
@@ -1024,8 +1006,8 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
* enable VREF_UP to avoid false ovp on low brightness for LCD
*/
reg = QPNP_WLED_TEST4_EN_VREF_UP;
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_TEST4_REG(base_addr));
+ rc = qpnp_wled_sec_write_reg(wled,
+ QPNP_WLED_TEST4_REG(base_addr), reg);
if (rc)
return rc;
}
@@ -1034,26 +1016,44 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
}
/* ovp irq handler */
-static irqreturn_t qpnp_wled_ovp_irq(int irq, void *_wled)
+static irqreturn_t qpnp_wled_ovp_irq_handler(int irq, void *_wled)
{
struct qpnp_wled *wled = _wled;
+ int rc;
+ u8 val;
- dev_dbg(&wled->pdev->dev, "ovp detected\n");
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_FAULT_STATUS(wled->ctrl_base), &val);
+ if (rc < 0) {
+ pr_err("Error in reading WLED_FAULT_STATUS rc=%d\n", rc);
+ return IRQ_HANDLED;
+ }
+ pr_err("WLED OVP fault detected, fault_status= %x\n", val);
return IRQ_HANDLED;
}
/* short circuit irq handler */
-static irqreturn_t qpnp_wled_sc_irq(int irq, void *_wled)
+static irqreturn_t qpnp_wled_sc_irq_handler(int irq, void *_wled)
{
struct qpnp_wled *wled = _wled;
+ int rc;
+ u8 val;
- dev_err(&wled->pdev->dev,
- "Short circuit detected %d times\n", ++wled->sc_cnt);
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_FAULT_STATUS(wled->ctrl_base), &val);
+ if (rc < 0) {
+ pr_err("Error in reading WLED_FAULT_STATUS rc=%d\n", rc);
+ return IRQ_HANDLED;
+ }
+ pr_err("WLED short circuit detected %d times fault_status=%x\n",
+ ++wled->sc_cnt, val);
+ mutex_lock(&wled->lock);
qpnp_wled_module_en(wled, wled->ctrl_base, false);
msleep(QPNP_WLED_SC_DLY_MS);
qpnp_wled_module_en(wled, wled->ctrl_base, true);
+ mutex_unlock(&wled->lock);
return IRQ_HANDLED;
}
@@ -1079,8 +1079,8 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled)
if (!wled->disp_type_amoled)
return false;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_CTRL_SPARE_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_CTRL_SPARE_REG(wled->ctrl_base), &reg);
if (rc < 0)
return false;
@@ -1118,8 +1118,9 @@ static int qpnp_wled_gm_config(struct qpnp_wled *wled)
mask |= QPNP_WLED_VLOOP_COMP_GM_MASK |
QPNP_WLED_VLOOP_COMP_GM_OVERWRITE;
- rc = qpnp_wled_masked_write_reg(wled, mask, &reg,
- QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base));
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base), mask,
+ reg);
if (rc)
pr_err("write VLOOP_COMP_GM_REG failed, rc=%d]\n", rc);
@@ -1156,8 +1157,9 @@ static int qpnp_wled_ovp_config(struct qpnp_wled *wled)
}
reg = i & QPNP_WLED_OVP_MASK;
- rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_OVP_MASK, &reg,
- QPNP_WLED_OVP_REG(wled->ctrl_base));
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_OVP_REG(wled->ctrl_base),
+ QPNP_WLED_OVP_MASK, reg);
if (rc)
return rc;
@@ -1183,14 +1185,15 @@ static int qpnp_wled_avdd_trim_config(struct qpnp_wled *wled)
/* Update WLED_OVP register based on desired target voltage */
reg = qpnp_wled_ovp_reg_settings[i];
- rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_OVP_MASK, &reg,
- QPNP_WLED_OVP_REG(wled->ctrl_base));
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_OVP_REG(wled->ctrl_base),
+ QPNP_WLED_OVP_MASK, reg);
if (rc)
return rc;
/* Update WLED_TRIM register based on desired target voltage */
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base), &reg);
if (rc)
return rc;
@@ -1207,8 +1210,8 @@ static int qpnp_wled_avdd_trim_config(struct qpnp_wled *wled)
}
reg &= QPNP_WLED_7P7_TRIM_MASK;
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base));
+ rc = qpnp_wled_sec_write_reg(wled,
+ QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base), reg);
if (rc < 0)
dev_err(&wled->pdev->dev, "Write to 7P7_TRIM register failed, rc=%d\n",
rc);
@@ -1247,11 +1250,13 @@ static int qpnp_wled_avdd_mode_config(struct qpnp_wled *wled)
if (wled->avdd_mode_spmi) {
reg |= QPNP_WLED_AVDD_SEL_SPMI_BIT;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_AMOLED_VOUT_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_AMOLED_VOUT_REG(wled->ctrl_base),
+ reg);
} else {
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SWIRE_AVDD_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_SWIRE_AVDD_REG(wled->ctrl_base),
+ reg);
}
if (rc < 0)
@@ -1292,8 +1297,8 @@ static int qpnp_wled_ilim_config(struct qpnp_wled *wled)
reg = (i & QPNP_WLED_ILIM_MASK) | QPNP_WLED_ILIM_OVERWRITE;
rc = qpnp_wled_masked_write_reg(wled,
- QPNP_WLED_ILIM_MASK | QPNP_WLED_ILIM_OVERWRITE,
- &reg, QPNP_WLED_ILIM_REG(wled->ctrl_base));
+ QPNP_WLED_ILIM_REG(wled->ctrl_base),
+ QPNP_WLED_ILIM_MASK | QPNP_WLED_ILIM_OVERWRITE, reg);
if (rc < 0)
dev_err(&wled->pdev->dev, "Write to ILIM register failed, rc=%d\n",
rc);
@@ -1321,8 +1326,9 @@ static int qpnp_wled_vref_config(struct qpnp_wled *wled)
reg |= DIV_ROUND_CLOSEST(wled->vref_uv - vref_setting.min_uv,
vref_setting.step_uv);
- rc = qpnp_wled_masked_write_reg(wled, QPNP_WLED_VREF_MASK,
- &reg, QPNP_WLED_VREF_REG(wled->ctrl_base));
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_VREF_REG(wled->ctrl_base),
+ QPNP_WLED_VREF_MASK, reg);
if (rc)
pr_err("Write VREF_REG failed, rc=%d\n", rc);
@@ -1341,14 +1347,14 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
return rc;
/* Configure the FEEDBACK OUTPUT register */
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_FDBK_OP_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_FDBK_OP_REG(wled->ctrl_base),
+ &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_FDBK_OP_MASK;
reg |= wled->fdbk_op;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_FDBK_OP_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_FDBK_OP_REG(wled->ctrl_base),
+ reg);
if (rc)
return rc;
@@ -1382,9 +1388,9 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
reg |= wled->lcd_auto_pfm_en <<
QPNP_WLED_LCD_AUTO_PFM_EN_SHIFT;
rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_LCD_AUTO_PFM_REG(wled->ctrl_base),
QPNP_WLED_LCD_AUTO_PFM_EN_BIT |
- QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK, &reg,
- QPNP_WLED_LCD_AUTO_PFM_REG(wled->ctrl_base));
+ QPNP_WLED_LCD_AUTO_PFM_THRESH_MASK, reg);
if (rc < 0) {
pr_err("Write LCD_AUTO_PFM failed, rc=%d\n", rc);
return rc;
@@ -1393,8 +1399,8 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
/* Configure the Soft start Ramp delay: for AMOLED - 0,for LCD - 2 */
reg = (wled->disp_type_amoled) ? 0 : 2;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SOFTSTART_RAMP_DLY(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_SOFTSTART_RAMP_DLY(wled->ctrl_base), reg);
if (rc)
return rc;
@@ -1404,14 +1410,14 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
else if (wled->boost_duty_ns > QPNP_WLED_BOOST_DUTY_MAX_NS)
wled->boost_duty_ns = QPNP_WLED_BOOST_DUTY_MAX_NS;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base),
+ &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_BOOST_DUTY_MASK;
reg |= (wled->boost_duty_ns / QPNP_WLED_BOOST_DUTY_STEP_NS);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_BOOST_DUTY_REG(wled->ctrl_base), reg);
if (rc)
return rc;
@@ -1421,14 +1427,14 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
else
temp = QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_SWITCH_FREQ_MASK;
reg |= (temp | QPNP_WLED_SWITCH_FREQ_OVERWRITE);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base), reg);
if (rc)
return rc;
@@ -1466,8 +1472,7 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
temp = 1;
}
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_MOD_REG(wled->sink_base));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_MOD_REG(wled->sink_base), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_MOD_FREQ_MASK;
@@ -1492,8 +1497,7 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
reg |= wled->dim_mode;
}
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_MOD_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_MOD_REG(wled->sink_base), reg);
if (rc)
return rc;
@@ -1503,15 +1507,15 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
else if (wled->hyb_thres > QPNP_WLED_HYB_THRES_MAX)
wled->hyb_thres = QPNP_WLED_HYB_THRES_MAX;
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_HYB_THRES_REG(wled->sink_base));
+ rc = qpnp_wled_read_reg(wled, QPNP_WLED_HYB_THRES_REG(wled->sink_base),
+ &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_HYB_THRES_MASK;
temp = fls(wled->hyb_thres / QPNP_WLED_HYB_THRES_MIN) - 1;
reg |= temp;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_HYB_THRES_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_HYB_THRES_REG(wled->sink_base),
+ reg);
if (rc)
return rc;
@@ -1521,15 +1525,15 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
else
reg = QPNP_WLED_SINK_TEST5_HYB;
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_SINK_TEST5_REG(wled->sink_base));
+ rc = qpnp_wled_sec_write_reg(wled,
+ QPNP_WLED_SINK_TEST5_REG(wled->sink_base), reg);
if (rc)
return rc;
/* disable all current sinks and enable selected strings */
reg = 0x00;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_CURR_SINK_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled, QPNP_WLED_CURR_SINK_REG(wled->sink_base),
+ reg);
for (i = 0; i < wled->num_strings; i++) {
if (wled->strings[i] >= QPNP_WLED_MAX_STRINGS) {
@@ -1538,9 +1542,9 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
}
/* MODULATOR */
- rc = qpnp_wled_read_reg(wled, &reg,
+ rc = qpnp_wled_read_reg(wled,
QPNP_WLED_MOD_EN_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_MOD_EN_MASK;
@@ -1551,9 +1555,9 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
else
reg |= ~QPNP_WLED_GATE_DRV_MASK;
- rc = qpnp_wled_write_reg(wled, reg,
+ rc = qpnp_wled_write_reg(wled,
QPNP_WLED_MOD_EN_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), reg);
if (rc)
return rc;
@@ -1561,17 +1565,17 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
if (wled->sync_dly_us > QPNP_WLED_SYNC_DLY_MAX_US)
wled->sync_dly_us = QPNP_WLED_SYNC_DLY_MAX_US;
- rc = qpnp_wled_read_reg(wled, &reg,
+ rc = qpnp_wled_read_reg(wled,
QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_SYNC_DLY_MASK;
temp = wled->sync_dly_us / QPNP_WLED_SYNC_DLY_STEP_US;
reg |= temp;
- rc = qpnp_wled_write_reg(wled, reg,
+ rc = qpnp_wled_write_reg(wled,
QPNP_WLED_SYNC_DLY_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), reg);
if (rc)
return rc;
@@ -1579,43 +1583,43 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
if (wled->fs_curr_ua > QPNP_WLED_FS_CURR_MAX_UA)
wled->fs_curr_ua = QPNP_WLED_FS_CURR_MAX_UA;
- rc = qpnp_wled_read_reg(wled, &reg,
+ rc = qpnp_wled_read_reg(wled,
QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_FS_CURR_MASK;
temp = wled->fs_curr_ua / QPNP_WLED_FS_CURR_STEP_UA;
reg |= temp;
- rc = qpnp_wled_write_reg(wled, reg,
+ rc = qpnp_wled_write_reg(wled,
QPNP_WLED_FS_CURR_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), reg);
if (rc)
return rc;
/* CABC */
- rc = qpnp_wled_read_reg(wled, &reg,
+ rc = qpnp_wled_read_reg(wled,
QPNP_WLED_CABC_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_CABC_MASK;
reg |= (wled->en_cabc << QPNP_WLED_CABC_SHIFT);
- rc = qpnp_wled_write_reg(wled, reg,
+ rc = qpnp_wled_write_reg(wled,
QPNP_WLED_CABC_REG(wled->sink_base,
- wled->strings[i]));
+ wled->strings[i]), reg);
if (rc)
return rc;
/* Enable CURRENT SINK */
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_CURR_SINK_REG(wled->sink_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), &reg);
if (rc < 0)
return rc;
temp = wled->strings[i] + QPNP_WLED_CURR_SINK_SHIFT;
reg |= (1 << temp);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_CURR_SINK_REG(wled->sink_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_CURR_SINK_REG(wled->sink_base), reg);
if (rc)
return rc;
}
@@ -1628,11 +1632,9 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
/* setup ovp and sc irqs */
if (wled->ovp_irq >= 0) {
- rc = devm_request_threaded_irq(&wled->pdev->dev,
- wled->ovp_irq,
- NULL, qpnp_wled_ovp_irq,
- QPNP_IRQ_FLAGS,
- "qpnp_wled_ovp_irq", wled);
+ rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq,
+ NULL, qpnp_wled_ovp_irq_handler, IRQF_ONESHOT,
+ "qpnp_wled_ovp_irq", wled);
if (rc < 0) {
dev_err(&wled->pdev->dev,
"Unable to request ovp(%d) IRQ(err:%d)\n",
@@ -1644,9 +1646,8 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
if (wled->sc_irq >= 0) {
wled->sc_cnt = 0;
rc = devm_request_threaded_irq(&wled->pdev->dev, wled->sc_irq,
- NULL, qpnp_wled_sc_irq,
- QPNP_IRQ_FLAGS,
- "qpnp_wled_sc_irq", wled);
+ NULL, qpnp_wled_sc_irq_handler, IRQF_ONESHOT,
+ "qpnp_wled_sc_irq", wled);
if (rc < 0) {
dev_err(&wled->pdev->dev,
"Unable to request sc(%d) IRQ(err:%d)\n",
@@ -1654,8 +1655,8 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
return rc;
}
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_SC_PRO_REG(wled->ctrl_base), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_EN_SC_DEB_CYCLES_MASK;
@@ -1671,21 +1672,22 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
if (wled->disp_type_amoled)
reg |= QPNP_WLED_SC_PRO_EN_DSCHGR;
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_SC_PRO_REG(wled->ctrl_base), reg);
if (rc)
return rc;
if (wled->en_ext_pfet_sc_pro) {
reg = QPNP_WLED_EXT_FET_DTEST2;
- rc = qpnp_wled_sec_write_reg(wled, reg,
- QPNP_WLED_TEST1_REG(wled->ctrl_base));
+ rc = qpnp_wled_sec_write_reg(wled,
+ QPNP_WLED_TEST1_REG(wled->ctrl_base),
+ reg);
if (rc)
return rc;
}
} else {
- rc = qpnp_wled_read_reg(wled, &reg,
- QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_SC_PRO_REG(wled->ctrl_base), &reg);
if (rc < 0)
return rc;
reg &= QPNP_WLED_EN_DEB_CYCLES_MASK;
@@ -1697,8 +1699,8 @@ static int qpnp_wled_config(struct qpnp_wled *wled)
temp = fls(wled->sc_deb_cycles) - QPNP_WLED_SC_DEB_CYCLES_SUB;
reg |= (temp << 1);
- rc = qpnp_wled_write_reg(wled, reg,
- QPNP_WLED_SC_PRO_REG(wled->ctrl_base));
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_SC_PRO_REG(wled->ctrl_base), reg);
if (rc)
return rc;
}
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index 7809770bd1ae..60f7cfbd9f9b 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -2840,6 +2840,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
mutex_lock(&dvbdmx->mutex);
+ if (dvbdmxfeed->state < DMX_STATE_GO) {
+ mutex_unlock(&dvbdmx->mutex);
+ return -EINVAL;
+ }
+
if (!dvbdmx->stop_feed) {
mutex_unlock(&dvbdmx->mutex);
return -ENODEV;
diff --git a/drivers/media/platform/msm/camera_v2/common/Makefile b/drivers/media/platform/msm/camera_v2/common/Makefile
index 2e9028480145..74fe58f430e0 100644
--- a/drivers/media/platform/msm/camera_v2/common/Makefile
+++ b/drivers/media/platform/msm/camera_v2/common/Makefile
@@ -1,2 +1,3 @@
ccflags-y += -Idrivers/media/platform/msm/camera_v2/
-obj-$(CONFIG_MSMB_CAMERA) += msm_camera_io_util.o cam_smmu_api.o cam_hw_ops.o cam_soc_api.o
+ccflags-y += -Idrivers/misc/
+obj-$(CONFIG_MSMB_CAMERA) += msm_camera_io_util.o cam_smmu_api.o cam_hw_ops.o cam_soc_api.o msm_camera_tz_util.o
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
index d6b32036f31c..3e3143be0a13 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
@@ -26,6 +26,7 @@
#include <linux/workqueue.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/secure_buffer.h>
+#include <msm_camera_tz_util.h>
#include "cam_smmu_api.h"
#define SCRATCH_ALLOC_START SZ_128K
@@ -883,16 +884,26 @@ static int cam_smmu_attach_sec_cpp(int idx)
* all cpp sids are shared in SCM call. so no need of
* attach again.
*/
-
if (cam_smmu_send_syscall_cpp_intf(VMID_CP_CAMERA, idx)) {
pr_err("error: syscall failed\n");
return -EINVAL;
}
+
+ msm_camera_tz_set_mode(MSM_CAMERA_TZ_MODE_SECURE,
+ MSM_CAMERA_TZ_HW_BLOCK_CPP);
+
+ iommu_cb_set.cb_info[idx].state = CAM_SMMU_ATTACH;
+
return 0;
}
static int cam_smmu_detach_sec_cpp(int idx)
{
+ msm_camera_tz_set_mode(MSM_CAMERA_TZ_MODE_NON_SECURE,
+ MSM_CAMERA_TZ_HW_BLOCK_CPP);
+
+ iommu_cb_set.cb_info[idx].state = CAM_SMMU_DETACH;
+
/*
* When exiting secure, do scm call to attach
* with CPP SID in NS mode.
@@ -921,11 +932,18 @@ static int cam_smmu_attach_sec_vfe_ns_stats(int idx)
return -EINVAL;
}
}
+
+ msm_camera_tz_set_mode(MSM_CAMERA_TZ_MODE_SECURE,
+ MSM_CAMERA_TZ_HW_BLOCK_ISP);
+
return 0;
}
static int cam_smmu_detach_sec_vfe_ns_stats(int idx)
{
+ msm_camera_tz_set_mode(MSM_CAMERA_TZ_MODE_NON_SECURE,
+ MSM_CAMERA_TZ_HW_BLOCK_ISP);
+
/*
*While exiting from secure mode for secure pixel and non-secure stats,
*localizing detach/scm of non-secure SID's to detach secure
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.c
new file mode 100644
index 000000000000..d0843fb3a32c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.c
@@ -0,0 +1,351 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/ktime.h>
+#include <linux/mutex.h>
+#include <soc/qcom/camera2.h>
+#include "qseecom_kernel.h"
+#include "msm_camera_tz_util.h"
+
+#define EMPTY_QSEECOM_HANDLE NULL
+#define QSEECOM_SBUFF_SIZE SZ_128K
+
+#define MSM_CAMERA_TZ_UTIL_VERBOSE
+
+#define MSM_CAMERA_TZ_BOOT_PROTECTED (false)
+
+/* Update version major number in case the HLOS-TA interface is changed*/
+#define TA_IF_VERSION_MAJ 1
+#define TA_IF_VERSION_MIN 2
+
+#undef CDBG
+#ifdef MSM_CAMERA_TZ_UTIL_VERBOSE
+ #define CDBG(fmt, args...) \
+ pr_info(CONFIG_MSM_SEC_CCI_TA_NAME "::%s:%d - " fmt,\
+ __func__, __LINE__, ##args)
+#else /* MSM_CAMERA_TZ_UTIL_VERBOSE */
+ #define CDBG(fmt, args...) \
+ pr_debug("%s:%d - " fmt, __func__, __LINE__, ##args)
+#endif /* MSM_CAMERA_TZ_UTIL_VERBOSE */
+
+#pragma pack(push, msm_camera_tz_util, 1)
+
+/* MSM_CAMERA_TZ_CMD_GET_IF_VERSION */
+#define msm_camera_tz_i2c_get_if_version_req_t msm_camera_tz_generic_req_t
+
+struct msm_camera_tz_i2c_get_if_version_rsp_t {
+ enum msm_camera_tz_status_t rc;
+ uint32_t if_version_maj;
+ uint32_t if_version_min;
+};
+
+/* MSM_CAMERA_TZ_CMD_SET_MODE */
+struct msm_camera_tz_set_mode_req_t {
+ enum msm_camera_tz_cmd_id_t cmd_id;
+ uint32_t mode;
+ uint32_t hw_block;
+};
+
+#define msm_camera_tz_set_mode_rsp_t msm_camera_tz_generic_rsp_t
+
+#pragma pack(pop, msm_camera_tz_util)
+
+/* TA communication control structure */
+struct msm_camera_tz_ctrl_t {
+ uint32_t ta_enabled;
+ struct qseecom_handle *ta_qseecom_handle;
+ const char *ta_name;
+ uint32_t secure_hw_blocks;
+};
+
+static struct msm_camera_tz_ctrl_t msm_camera_tz_ctrl = {
+ 0, NULL, CONFIG_MSM_CAMERA_TZ_TA_NAME, 0
+};
+
+static DEFINE_MUTEX(msm_camera_tz_util_lock);
+
+struct qseecom_handle *msm_camera_tz_get_ta_handle()
+{
+ return msm_camera_tz_ctrl.ta_qseecom_handle;
+}
+
+void msm_camera_tz_lock(void)
+{
+ mutex_lock(&msm_camera_tz_util_lock);
+}
+
+void msm_camera_tz_unlock(void)
+{
+ mutex_unlock(&msm_camera_tz_util_lock);
+}
+
+int32_t get_cmd_rsp_buffers(
+ struct qseecom_handle *ta_qseecom_handle,
+ void **cmd, int *cmd_len,
+ void **rsp, int *rsp_len)
+{
+ if ((ta_qseecom_handle == NULL) ||
+ (cmd == NULL) || (cmd_len == NULL) ||
+ (rsp == NULL) || (rsp_len == NULL)) {
+ pr_err("%s:%d - Bad parameters\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ if (*cmd_len & QSEECOM_ALIGN_MASK)
+ *cmd_len = QSEECOM_ALIGN(*cmd_len);
+
+ if (*rsp_len & QSEECOM_ALIGN_MASK)
+ *rsp_len = QSEECOM_ALIGN(*rsp_len);
+
+ if ((*rsp_len + *cmd_len) > QSEECOM_SBUFF_SIZE) {
+ pr_err("%s:%d - Shared buffer too small to hold cmd=%d and rsp=%d\n",
+ __func__, __LINE__,
+ *cmd_len, *rsp_len);
+ return -ENOMEM;
+ }
+
+ *cmd = ta_qseecom_handle->sbuf;
+ *rsp = ta_qseecom_handle->sbuf + *cmd_len;
+ return 0;
+}
+
+static int32_t msm_camera_tz_i2c_ta_get_if_version(
+ struct qseecom_handle *ta_qseecom_handle,
+ uint32_t *if_version_maj,
+ uint32_t *if_version_min)
+{
+ int32_t cmd_len, rsp_len;
+ struct msm_camera_tz_i2c_get_if_version_req_t *cmd;
+ struct msm_camera_tz_i2c_get_if_version_rsp_t *rsp;
+ int32_t rc = 0;
+
+ CDBG("Enter\n");
+ if ((ta_qseecom_handle == NULL) ||
+ (if_version_maj == NULL) || (if_version_min == NULL)) {
+ pr_err("%s:%d - Bad parameters\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ cmd_len = sizeof(struct msm_camera_tz_i2c_get_if_version_req_t);
+ rsp_len = sizeof(struct msm_camera_tz_i2c_get_if_version_rsp_t);
+
+ rc = get_cmd_rsp_buffers(ta_qseecom_handle,
+ (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
+ if (!rc) {
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_GET_IF_VERSION;
+
+ rc = qseecom_send_command(ta_qseecom_handle,
+ (void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+ if (rc < 0) {
+ pr_err("%s:%d - Unable to get if version info, rc=%d\n",
+ __func__, __LINE__,
+ rc);
+ return rc;
+ }
+
+ if (rsp->rc < 0) {
+ CDBG("TZ App error, rc=%d\n", rsp->rc);
+ rc = -EFAULT;
+ } else {
+ *if_version_maj = rsp->if_version_maj;
+ *if_version_min = rsp->if_version_min;
+ CDBG("TZ If version %d.%d\n", *if_version_maj,
+ *if_version_min);
+ }
+ }
+ return rc;
+}
+
+int32_t msm_camera_tz_load_ta(void)
+{
+ int32_t rc = 0;
+
+ if (MSM_CAMERA_TZ_BOOT_PROTECTED &&
+ msm_camera_tz_ctrl.ta_enabled > 0) {
+ CDBG("TA loaded from boot(TA %s - %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+ return 0;
+ }
+
+ CDBG("Enter (TA name = %s, %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+
+ msm_camera_tz_lock();
+ if (msm_camera_tz_ctrl.ta_enabled == 0) {
+ ktime_t startTime = ktime_get();
+
+ /* Start the TA */
+ if ((msm_camera_tz_ctrl.ta_qseecom_handle == NULL) &&
+ (msm_camera_tz_ctrl.ta_name != NULL) &&
+ ('\0' != msm_camera_tz_ctrl.ta_name[0])) {
+ uint32_t if_version_maj = 0;
+ uint32_t if_version_min = 0;
+
+ rc = qseecom_start_app(
+ &msm_camera_tz_ctrl.ta_qseecom_handle,
+ (char *)msm_camera_tz_ctrl.ta_name,
+ QSEECOM_SBUFF_SIZE);
+ if (!rc)
+ rc = msm_camera_tz_i2c_ta_get_if_version(
+ msm_camera_tz_ctrl.ta_qseecom_handle,
+ &if_version_maj, &if_version_min);
+
+ if (!rc) {
+ if (if_version_maj != TA_IF_VERSION_MAJ) {
+ CDBG("TA ver mismatch %d.%d != %d.%d\n",
+ if_version_maj, if_version_min,
+ TA_IF_VERSION_MAJ,
+ TA_IF_VERSION_MIN);
+ rc = qseecom_shutdown_app(
+ &msm_camera_tz_ctrl.
+ ta_qseecom_handle);
+ msm_camera_tz_ctrl.ta_qseecom_handle
+ = EMPTY_QSEECOM_HANDLE;
+ rc = -EFAULT;
+ } else {
+ msm_camera_tz_ctrl.ta_enabled = 1;
+ }
+ }
+ }
+ CDBG("Load TA %s - %s(%d) - %lluus\n",
+ msm_camera_tz_ctrl.ta_name,
+ (msm_camera_tz_ctrl.ta_enabled)?"Ok" :
+ "Failed", rc,
+ ktime_us_delta(ktime_get(), startTime));
+ } else {
+ msm_camera_tz_ctrl.ta_enabled++;
+ CDBG("TA already loaded (TA %s - %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+ }
+ msm_camera_tz_unlock();
+ return rc;
+}
+
+int32_t msm_camera_tz_unload_ta(void)
+{
+ int32_t rc = -EFAULT;
+
+ if (MSM_CAMERA_TZ_BOOT_PROTECTED) {
+ CDBG("TA loaded from boot(TA %s - %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+ return 0;
+ }
+
+ CDBG("Enter (TA name = %s, %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+
+ msm_camera_tz_lock();
+ if (msm_camera_tz_ctrl.ta_enabled == 1) {
+ ktime_t startTime = ktime_get();
+
+ rc = qseecom_shutdown_app(&msm_camera_tz_ctrl.
+ ta_qseecom_handle);
+ msm_camera_tz_ctrl.ta_qseecom_handle
+ = EMPTY_QSEECOM_HANDLE;
+ msm_camera_tz_ctrl.ta_enabled = 0;
+ CDBG("Unload TA %s - %s(%d) - %lluus\n",
+ msm_camera_tz_ctrl.ta_name,
+ (!rc)?"Ok":"Failed", rc,
+ ktime_us_delta(ktime_get(), startTime));
+ } else {
+ msm_camera_tz_ctrl.ta_enabled--;
+ CDBG("TA still loaded (TA %s - %d)\n",
+ msm_camera_tz_ctrl.ta_name,
+ msm_camera_tz_ctrl.ta_enabled);
+ }
+ msm_camera_tz_unlock();
+ return rc;
+}
+
+int32_t msm_camera_tz_ta_set_mode(uint32_t mode,
+ uint32_t hw_block)
+{
+ int32_t cmd_len, rsp_len;
+ struct msm_camera_tz_set_mode_req_t *cmd;
+ struct msm_camera_tz_set_mode_rsp_t *rsp;
+ int32_t rc = 0;
+ struct qseecom_handle *ta_qseecom_handle =
+ msm_camera_tz_get_ta_handle();
+ ktime_t startTime = ktime_get();
+
+ if (ta_qseecom_handle == NULL) {
+ pr_err("%s:%d - Bad parameters\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ cmd_len = sizeof(struct msm_camera_tz_set_mode_req_t);
+ rsp_len = sizeof(struct msm_camera_tz_set_mode_rsp_t);
+
+ rc = get_cmd_rsp_buffers(ta_qseecom_handle,
+ (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
+ if (!rc) {
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_SET_MODE;
+ cmd->mode = mode;
+ cmd->hw_block = hw_block;
+
+ rc = qseecom_send_command(ta_qseecom_handle,
+ (void *)cmd, cmd_len, (void *)rsp, rsp_len);
+
+ if (rc < 0) {
+ pr_err("%s:%d - Failed: rc=%d\n",
+ __func__, __LINE__,
+ rc);
+ return rc;
+ }
+ rc = rsp->rc;
+ }
+ CDBG("Done: rc=%d, Mode=0x%08X - %lluus\n",
+ rc, mode,
+ ktime_us_delta(ktime_get(), startTime));
+ return rc;
+}
+
+uint32_t msm_camera_tz_set_mode(uint32_t mode,
+ uint32_t hw_block)
+{
+ uint32_t rc = 0;
+
+ switch (mode) {
+ case MSM_CAMERA_TZ_MODE_SECURE:
+ rc = msm_camera_tz_load_ta();
+ if (!rc) {
+ rc = msm_camera_tz_ta_set_mode(mode, hw_block);
+ if (rc)
+ msm_camera_tz_ctrl.secure_hw_blocks |= hw_block;
+ }
+ break;
+ case MSM_CAMERA_TZ_MODE_NON_SECURE:
+ msm_camera_tz_ta_set_mode(mode, hw_block);
+ if (rc)
+ msm_camera_tz_ctrl.secure_hw_blocks &= ~hw_block;
+ rc = msm_camera_tz_unload_ta();
+ break;
+ default:
+ pr_err("%s:%d - Incorrect mode: %d (hw: 0x%08X)\n",
+ __func__, __LINE__,
+ mode, hw_block);
+ return -EINVAL;
+ }
+ CDBG("Set Mode - rc=%d, Mode: 0x%08X\n",
+ rc, mode);
+ return rc;
+}
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.h b/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.h
new file mode 100644
index 000000000000..146b7d029984
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_tz_util.h
@@ -0,0 +1,91 @@
+/* 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.
+ */
+
+#ifndef __MSM_CAMERA_TZ_UTIL_H
+#define __MSM_CAMERA_TZ_UTIL_H
+
+#include <soc/qcom/camera2.h>
+
+#ifndef CONFIG_MSM_CAMERA_TZ_TA_NAME
+#define CONFIG_MSM_CAMERA_TZ_TA_NAME "seccamdemo64"
+#endif /* CONFIG_MSM_CAMERA_TZ_TA_NAME */
+
+#define MSM_CAMERA_TZ_MODE_NON_SECURE 0x0000000000
+#define MSM_CAMERA_TZ_MODE_SECURE 0x0000000001
+
+#define MSM_CAMERA_TZ_HW_BLOCK_CSIDCORE 0x0000000001
+#define MSM_CAMERA_TZ_HW_BLOCK_ISPIF 0x0000000002
+#define MSM_CAMERA_TZ_HW_BLOCK_CCI 0x0000000004
+#define MSM_CAMERA_TZ_HW_BLOCK_ISP 0x0000000008
+#define MSM_CAMERA_TZ_HW_BLOCK_CPP 0x0000000010
+
+enum msm_camera_tz_cmd_id_t {
+ MSM_CAMERA_TZ_CMD_NONE,
+ MSM_CAMERA_TZ_CMD_GET_IF_VERSION,
+ MSM_CAMERA_TZ_CMD_POWER_UP,
+ MSM_CAMERA_TZ_CMD_POWER_DOWN,
+ MSM_CAMERA_TZ_CMD_CCI_GENERIC,
+ MSM_CAMERA_TZ_CMD_CCI_READ,
+ MSM_CAMERA_TZ_CMD_CCI_READ_SEQ,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_SEQ,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_ASYNC,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_SYNC,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_SYNC_BLOCK,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_SEQ_TABLE,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_W_MICRODELAY,
+ MSM_CAMERA_TZ_CMD_CCI_POLL,
+ MSM_CAMERA_TZ_CMD_CCI_WRITE_CONF_TBL,
+ MSM_CAMERA_TZ_CMD_CCI_UTIL,
+ MSM_CAMERA_TZ_CMD_SET_MODE,
+ MSM_CAMERA_TZ_CMD_FRAME_NOTIFICATION,
+};
+
+enum msm_camera_tz_status_t {
+ MSM_CAMERA_TZ_STATUS_SUCCESS = 0,
+ MSM_CAMERA_TZ_STATUS_GENERAL_FAILURE = -1,
+ MSM_CAMERA_TZ_STATUS_INVALID_INPUT_PARAMS = -2,
+ MSM_CAMERA_TZ_STATUS_INVALID_SENSOR_ID = -3,
+ MSM_CAMERA_TZ_STATUS_BYPASS = -4,
+ MSM_CAMERA_TZ_STATUS_TIMEOUT = -5,
+
+ MSM_CAMERA_TZ_STATUS_RESET_DONE = 1,
+ MSM_CAMERA_TZ_STATUS_ERR_SIZE = 0x7FFFFFFF
+};
+
+#pragma pack(push, msm_camera_tz, 1)
+
+struct msm_camera_tz_generic_req_t {
+ enum msm_camera_tz_cmd_id_t cmd_id;
+};
+
+struct msm_camera_tz_generic_rsp_t {
+ enum msm_camera_tz_status_t rc;
+};
+
+#pragma pack(pop, msm_camera_tz)
+
+uint32_t msm_camera_tz_set_mode(
+ uint32_t mode, uint32_t hw_block);
+
+struct qseecom_handle *msm_camera_tz_get_ta_handle(void);
+int32_t get_cmd_rsp_buffers(
+ struct qseecom_handle *ta_qseecom_handle,
+ void **cmd, int *cmd_len,
+ void **rsp, int *rsp_len);
+int32_t msm_camera_tz_load_ta(void);
+int32_t msm_camera_tz_unload_ta(void);
+void msm_camera_tz_lock(void);
+void msm_camera_tz_unlock(void);
+
+#endif /* __MSM_CAMERA_TZ_UTIL_H */
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(&timestamp, 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,
+ &timestamp.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,
- &timestamp.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, &timestamp);
- 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(&timestamp, 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, &timestamp.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, &timestamp.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/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index a700f836061c..b413bf3855b8 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -1396,7 +1396,7 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
{
struct msm_actuator_cfg_data *cdata =
(struct msm_actuator_cfg_data *)argp;
- int32_t rc = 0;
+ int32_t rc = -EINVAL;
mutex_lock(a_ctrl->actuator_mutex);
CDBG("Enter\n");
CDBG("%s type %d\n", __func__, cdata->cfgtype);
@@ -1406,7 +1406,7 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
a_ctrl->actuator_state == ACT_DISABLE_STATE) {
pr_err("actuator disabled %d\n", rc);
mutex_unlock(a_ctrl->actuator_mutex);
- return -EINVAL;
+ return rc;
}
switch (cdata->cfgtype) {
@@ -1427,15 +1427,19 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
break;
case CFG_SET_DEFAULT_FOCUS:
- rc = a_ctrl->func_tbl->actuator_set_default_focus(a_ctrl,
- &cdata->cfg.move);
+ if (a_ctrl->func_tbl &&
+ a_ctrl->func_tbl->actuator_set_default_focus)
+ rc = a_ctrl->func_tbl->actuator_set_default_focus(
+ a_ctrl, &cdata->cfg.move);
if (rc < 0)
pr_err("move focus failed %d\n", rc);
break;
case CFG_MOVE_FOCUS:
- rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl,
- &cdata->cfg.move);
+ if (a_ctrl->func_tbl &&
+ a_ctrl->func_tbl->actuator_move_focus)
+ rc = a_ctrl->func_tbl->actuator_move_focus(a_ctrl,
+ &cdata->cfg.move);
if (rc < 0)
pr_err("move focus failed %d\n", rc);
break;
@@ -1446,8 +1450,10 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
break;
case CFG_SET_POSITION:
- rc = a_ctrl->func_tbl->actuator_set_position(a_ctrl,
- &cdata->cfg.setpos);
+ if (a_ctrl->func_tbl &&
+ a_ctrl->func_tbl->actuator_set_position)
+ rc = a_ctrl->func_tbl->actuator_set_position(a_ctrl,
+ &cdata->cfg.setpos);
if (rc < 0)
pr_err("actuator_set_position failed %d\n", rc);
break;
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/camera_v2/sensor/io/msm_camera_tz_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
index 5a330db0f9a5..b3e5dc7f9cb8 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c
@@ -15,113 +15,62 @@
#include <soc/qcom/camera2.h>
#include "qseecom_kernel.h"
#include "msm_camera_i2c.h"
-#include "msm_camera_io_util.h"
+#include "msm_camera_tz_util.h"
#include "msm_cci.h"
#include "msm_sensor.h"
-#define QSEECOM_SBUFF_SIZE SZ_128K
-#define MAX_TA_NAME 32
-#define EMPTY_QSEECOM_HANDLE NULL
-
-#ifndef CONFIG_MSM_SEC_CCI_TA_NAME
- #define CONFIG_MSM_SEC_CCI_TA_NAME "seccamdemo64"
-#endif /* CONFIG_MSM_SEC_CCI_TA_NAME */
-
-/* Update version major number in case the HLOS-TA interface is changed*/
-#define TA_IF_VERSION_MAJ 0
-#define TA_IF_VERSION_MIN 1
-
#undef CDBG
-#ifdef CONFIG_MSM_SEC_CCI_DEBUG
-
-#define CDBG(fmt, args...) pr_info(CONFIG_MSM_SEC_CCI_TA_NAME "::%s:%d - " fmt,\
- __func__, __LINE__, ##args)
-#define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \
- ((ret < 0) ? i2c_fn(__VA_ARGS__):ret)
+#define MSM_CAMERA_TZ_I2C_VERBOSE
+#ifdef CONFIG_MSM_SEC_CCI_DEBUG
+ #define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \
+ ((ret < 0) ? i2c_fn(__VA_ARGS__):ret)
#else /* CONFIG_MSM_SEC_CCI_DEBUG */
-
-#define CDBG(fmt, args...) pr_info("%s:%d - " fmt, __func__, __LINE__, ##args)
-#define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \
- ((ret < 0) ? -EFAULT:ret)
-
+ #define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \
+ ((ret < 0) ? -EFAULT:ret)
#endif /* CONFIG_MSM_SEC_CCI_DEBUG */
-#pragma pack(push, msm_camera_tz_i2c, 1)
-
-enum msm_camera_tz_i2c_cmd_id_t {
- TZ_I2C_CMD_GET_NONE,
- TZ_I2C_CMD_GET_IF_VERSION,
- TZ_I2C_CMD_POWER_UP,
- TZ_I2C_CMD_POWER_DOWN,
- TZ_I2C_CMD_CCI_GENERIC,
- TZ_I2C_CMD_CCI_READ,
- TZ_I2C_CMD_CCI_READ_SEQ,
- TZ_I2C_CMD_CCI_WRITE,
- TZ_I2C_CMD_CCI_WRITE_SEQ,
- TZ_I2C_CMD_CCI_WRITE_TABLE_ASYNC,
- TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC,
- TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC_BLOCK,
- TZ_I2C_CMD_CCI_WRITE_TABLE,
- TZ_I2C_CMD_CCI_WRITE_SEQ_TABLE,
- TZ_I2C_CMD_CCI_WRITE_TABLE_W_MICRODELAY,
- TZ_I2C_CMD_CCI_POLL,
- TZ_I2C_CMD_CCI_WRITE_CONF_TBL,
- TZ_I2C_CMD_CCI_UTIL,
-};
-
-enum msm_camera_tz_i2c_status_t {
- TZ_I2C_STATUS_SUCCESS = 0,
- TZ_I2C_STATUS_GENERAL_FAILURE = -1,
- TZ_I2C_STATUS_INVALID_INPUT_PARAMS = -2,
- TZ_I2C_STATUS_INVALID_SENSOR_ID = -3,
- TZ_I2C_STATUS_BYPASS = -4,
- TZ_I2C_STATUS_ERR_SIZE = 0x7FFFFFFF
-};
+#ifdef MSM_CAMERA_TZ_I2C_VERBOSE
+ #define CDBG(fmt, args...) \
+ pr_info(CONFIG_MSM_SEC_CCI_TA_NAME "::%s:%d - " fmt, \
+ __func__, __LINE__, ##args)
+#else /* MSM_CAMERA_TZ_I2C_VERBOSE */
+ #define CDBG(fmt, args...) \
+ pr_debug("%s:%d - " fmt, __func__, __LINE__, ##args)
+#endif /* MSM_CAMERA_TZ_I2C_VERBOSE */
-struct msm_camera_tz_i2c_generic_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
-};
+#pragma pack(push, msm_camera_tz_i2c, 1)
-struct msm_camera_tz_i2c_generic_rsp_t {
- enum msm_camera_tz_i2c_status_t rc;
+struct msm_camera_tz_i2c_cci_generic_req_t {
+ enum msm_camera_tz_cmd_id_t cmd_id;
+ int32_t sensor_id;
+ enum msm_camera_tz_cmd_id_t cci_cmd_id;
+ uint32_t cci_i2c_master;
+ uint16_t sid;
+ uint16_t cid;
};
-#define msm_camera_tz_i2c_get_if_version_req_t msm_camera_tz_i2c_generic_req_t
-
-struct msm_camera_tz_i2c_get_if_version_rsp_t {
- enum msm_camera_tz_i2c_status_t rc;
- uint32_t if_version_maj;
- uint32_t if_version_min;
-};
+#define msm_camera_tz_i2c_cci_generic_rsp_t msm_camera_tz_generic_rsp_t
+/* MSM_CAMERA_TZ_CMD_POWER_UP */
struct msm_camera_tz_i2c_power_up_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
+ enum msm_camera_tz_cmd_id_t cmd_id;
int32_t sensor_id;
};
-#define msm_camera_tz_i2c_power_up_rsp_t msm_camera_tz_i2c_generic_rsp_t
+#define msm_camera_tz_i2c_power_up_rsp_t msm_camera_tz_generic_rsp_t
+/* MSM_CAMERA_TZ_CMD_POWER_DOWN */
struct msm_camera_tz_i2c_power_down_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
- int32_t sensor_id;
-};
-
-#define msm_camera_tz_i2c_power_down_rsp_t msm_camera_tz_i2c_generic_rsp_t
-
-struct msm_camera_tz_i2c_cci_generic_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
+ enum msm_camera_tz_cmd_id_t cmd_id;
int32_t sensor_id;
- enum msm_camera_tz_i2c_cmd_id_t cci_cmd_id;
- uint32_t cci_i2c_master;
- uint16_t sid;
- uint16_t cid;
};
-#define msm_camera_tz_i2c_cci_generic_rsp_t msm_camera_tz_i2c_generic_rsp_t
+#define msm_camera_tz_i2c_power_down_rsp_t msm_camera_tz_generic_rsp_t
+/* MSM_CAMERA_TZ_CMD_CCI_READ */
struct msm_camera_tz_i2c_cci_read_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
+ enum msm_camera_tz_cmd_id_t cmd_id;
int32_t sensor_id;
uint32_t cci_i2c_master;
uint16_t sid;
@@ -131,12 +80,13 @@ struct msm_camera_tz_i2c_cci_read_req_t {
};
struct msm_camera_tz_i2c_cci_read_rsp_t {
- enum msm_camera_tz_i2c_status_t rc;
+ enum msm_camera_tz_status_t rc;
uint16_t data;
};
+/* MSM_CAMERA_TZ_CMD_CCI_WRITE */
struct msm_camera_tz_i2c_cci_write_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
+ enum msm_camera_tz_cmd_id_t cmd_id;
int32_t sensor_id;
uint32_t cci_i2c_master;
uint16_t sid;
@@ -146,10 +96,11 @@ struct msm_camera_tz_i2c_cci_write_req_t {
uint32_t data_type;
};
-#define msm_camera_tz_i2c_cci_write_rsp_t msm_camera_tz_i2c_generic_rsp_t
+#define msm_camera_tz_i2c_cci_write_rsp_t msm_camera_tz_generic_rsp_t
+/* MSM_CAMERA_TZ_CMD_CCI_UTIL */
struct msm_camera_tz_i2c_cci_util_req_t {
- enum msm_camera_tz_i2c_cmd_id_t cmd_id;
+ enum msm_camera_tz_cmd_id_t cmd_id;
int32_t sensor_id;
uint32_t cci_i2c_master;
uint16_t sid;
@@ -157,33 +108,19 @@ struct msm_camera_tz_i2c_cci_util_req_t {
uint16_t cci_cmd;
};
-#define msm_camera_tz_i2c_cci_util_rsp_t msm_camera_tz_i2c_generic_rsp_t
+#define msm_camera_tz_i2c_cci_util_rsp_t msm_camera_tz_generic_rsp_t
#pragma pack(pop, msm_camera_tz_i2c)
+/* Camera control structure */
struct msm_camera_tz_i2c_sensor_info_t {
struct msm_sensor_ctrl_t *s_ctrl;
struct msm_camera_i2c_fn_t *saved_sensor_i2c_fn;
uint32_t secure;
- uint32_t ta_enabled;
- struct qseecom_handle *ta_qseecom_handle;
- const char *ta_name;
+ uint32_t ready;
};
-struct msm_camera_tz_i2c_ctrl_t {
- struct mutex lock;
- uint32_t lock_ready;
- uint32_t secure_mode;
-};
-
-static struct msm_camera_tz_i2c_ctrl_t msm_camera_tz_i2c_ctrl;
-
-static struct msm_camera_tz_i2c_sensor_info_t sensor_info[MAX_CAMERAS] = {
- {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME},
- {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME},
- {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME},
- {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME},
-};
+static struct msm_camera_tz_i2c_sensor_info_t sensor_info[MAX_CAMERAS];
static int32_t msm_camera_tz_i2c_is_sensor_secure(
struct msm_camera_i2c_client *client)
@@ -196,7 +133,6 @@ static int32_t msm_camera_tz_i2c_is_sensor_secure(
return -EINVAL;
}
- CDBG("Enter\n");
for (index = 0; index < MAX_CAMERAS; index++) {
if ((sensor_info[index].s_ctrl != NULL) &&
sensor_info[index].secure &&
@@ -210,88 +146,6 @@ static int32_t msm_camera_tz_i2c_is_sensor_secure(
return -EINVAL;
}
-static int32_t get_cmd_rsp_buffers(
- struct qseecom_handle *ta_qseecom_handle,
- void **cmd, int *cmd_len,
- void **rsp, int *rsp_len)
-{
-
- CDBG("Enter\n");
- if ((ta_qseecom_handle == NULL) ||
- (cmd == NULL) || (cmd_len == NULL) ||
- (rsp == NULL) || (rsp_len == NULL)) {
- pr_err("%s:%d - Bad parameters\n",
- __func__, __LINE__);
- return -EINVAL;
- }
-
- if (*cmd_len & QSEECOM_ALIGN_MASK)
- *cmd_len = QSEECOM_ALIGN(*cmd_len);
-
- if (*rsp_len & QSEECOM_ALIGN_MASK)
- *rsp_len = QSEECOM_ALIGN(*rsp_len);
-
- if ((*rsp_len + *cmd_len) > QSEECOM_SBUFF_SIZE) {
- pr_err("%s:%d - Shared buffer too small to hold cmd=%d and rsp=%d\n",
- __func__, __LINE__,
- *cmd_len, *rsp_len);
- return -ENOMEM;
- }
-
- *cmd = ta_qseecom_handle->sbuf;
- *rsp = ta_qseecom_handle->sbuf + *cmd_len;
- return 0;
-}
-
-static int32_t msm_camera_tz_i2c_ta_get_if_version(
- struct qseecom_handle *ta_qseecom_handle,
- uint32_t *if_version_maj,
- uint32_t *if_version_min)
-{
- int32_t cmd_len, rsp_len;
- struct msm_camera_tz_i2c_get_if_version_req_t *cmd;
- struct msm_camera_tz_i2c_get_if_version_rsp_t *rsp;
- int32_t rc = 0;
-
- CDBG("Enter\n");
- if ((ta_qseecom_handle == NULL) ||
- (if_version_maj == NULL) || (if_version_min == NULL)) {
- pr_err("%s:%d - Bad parameters\n",
- __func__, __LINE__);
- return -EINVAL;
- }
-
- cmd_len = sizeof(struct msm_camera_tz_i2c_get_if_version_req_t);
- rsp_len = sizeof(struct msm_camera_tz_i2c_get_if_version_rsp_t);
-
- rc = get_cmd_rsp_buffers(ta_qseecom_handle,
- (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
- if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_GET_IF_VERSION;
-
- rc = qseecom_send_command(ta_qseecom_handle,
- (void *)cmd, cmd_len, (void *)rsp, rsp_len);
-
- if (rc < 0) {
- pr_err("%s:%d - Unable to get if version info, rc=%d\n",
- __func__, __LINE__,
- rc);
- return rc;
- }
-
- if (rsp->rc < 0) {
- CDBG("TZ I2C App error, rc=%d\n", rsp->rc);
- rc = -EFAULT;
- } else {
- *if_version_maj = rsp->if_version_maj;
- *if_version_min = rsp->if_version_min;
- CDBG("TZ I2C If version %d.%d\n", *if_version_maj,
- *if_version_min);
- }
- }
- return rc;
-}
-
static int32_t msm_camera_tz_i2c_ta_power_up(
struct qseecom_handle *ta_qseecom_handle,
int32_t sensor_id,
@@ -304,12 +158,14 @@ static int32_t msm_camera_tz_i2c_ta_power_up(
CDBG("Enter\n");
- if (sensor_secure == NULL)
+ if (sensor_secure == NULL) {
+ pr_err("%s:%d - Bad parameter\n",
+ __func__, __LINE__);
return -EINVAL;
-
+ }
*sensor_secure = 0;
+
if ((ta_qseecom_handle == NULL) ||
- (sensor_secure == NULL) ||
(sensor_id < 0) ||
(sensor_id >= MAX_CAMERAS)) {
pr_err("%s:%d - Bad parameters\n",
@@ -323,7 +179,7 @@ static int32_t msm_camera_tz_i2c_ta_power_up(
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_POWER_UP;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_POWER_UP;
cmd->sensor_id = sensor_id;
rc = qseecom_send_command(ta_qseecom_handle,
@@ -336,7 +192,7 @@ static int32_t msm_camera_tz_i2c_ta_power_up(
return rc;
}
- if (rsp->rc == TZ_I2C_STATUS_SUCCESS)
+ if (rsp->rc == MSM_CAMERA_TZ_STATUS_SUCCESS)
*sensor_secure = 1;
CDBG("Sensor %d is %s\n", sensor_id,
(*sensor_secure)?"SECURE":"NON-SECURE");
@@ -369,7 +225,7 @@ static int32_t msm_camera_tz_i2c_ta_power_down(
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_POWER_DOWN;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_POWER_DOWN;
cmd->sensor_id = sensor_id;
rc = qseecom_send_command(ta_qseecom_handle,
@@ -387,7 +243,7 @@ static int32_t msm_camera_tz_i2c_ta_power_down(
static int32_t msm_camera_tz_i2c_ta_cci_generic(
struct msm_camera_i2c_client *client,
- enum msm_camera_tz_i2c_cmd_id_t cci_cmd_id)
+ enum msm_camera_tz_cmd_id_t cci_cmd_id)
{
int32_t cmd_len, rsp_len;
struct msm_camera_tz_i2c_cci_generic_req_t *cmd;
@@ -395,6 +251,7 @@ static int32_t msm_camera_tz_i2c_ta_cci_generic(
int32_t rc = 0;
struct qseecom_handle *ta_qseecom_handle;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
+ ktime_t startTime = ktime_get();
if ((client == NULL) ||
(sensor_id < 0) ||
@@ -404,21 +261,14 @@ static int32_t msm_camera_tz_i2c_ta_cci_generic(
return -EINVAL;
}
- CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, cci_cmd_id=%d\n",
- sensor_id,
- client->cci_client->cci_i2c_master,
- client->cci_client->sid,
- client->cci_client->cid,
- cci_cmd_id);
-
- ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle;
+ ta_qseecom_handle = msm_camera_tz_get_ta_handle();
cmd_len = sizeof(struct msm_camera_tz_i2c_cci_generic_req_t);
rsp_len = sizeof(struct msm_camera_tz_i2c_cci_generic_rsp_t);
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_CCI_GENERIC;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_CCI_GENERIC;
cmd->sensor_id = sensor_id;
cmd->cci_cmd_id = cci_cmd_id;
cmd->cci_i2c_master = client->cci_client->cci_i2c_master;
@@ -435,8 +285,15 @@ static int32_t msm_camera_tz_i2c_ta_cci_generic(
return rc;
}
rc = rsp->rc;
- CDBG("Done: rc=%d, cci_cmd_id=%d\n", rc, cci_cmd_id);
}
+ CDBG("Done: rc=%d, SN=%d, MS=%d, SID=%d, CID=%d, CMD=%d - %lluus\n",
+ rc, sensor_id,
+ client->cci_client->cci_i2c_master,
+ client->cci_client->sid,
+ client->cci_client->cid,
+ cci_cmd_id,
+ ktime_us_delta(ktime_get(), startTime));
+
return rc;
}
@@ -452,6 +309,7 @@ static int32_t msm_camera_tz_i2c_ta_cci_read(
int32_t rc = 0;
struct qseecom_handle *ta_qseecom_handle;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
+ ktime_t startTime = ktime_get();
if ((client == NULL) ||
(data == NULL) ||
@@ -462,22 +320,14 @@ static int32_t msm_camera_tz_i2c_ta_cci_read(
return -EINVAL;
}
- CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, Addr=0x%X, Type=%d\n",
- sensor_id,
- client->cci_client->cci_i2c_master,
- client->cci_client->sid,
- client->cci_client->cid,
- addr,
- data_type);
-
- ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle;
+ ta_qseecom_handle = msm_camera_tz_get_ta_handle();
cmd_len = sizeof(struct msm_camera_tz_i2c_cci_read_req_t);
rsp_len = sizeof(struct msm_camera_tz_i2c_cci_read_rsp_t);
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_CCI_READ;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_CCI_READ;
cmd->sensor_id = sensor_id;
cmd->cci_i2c_master = client->cci_client->cci_i2c_master;
cmd->sid = client->cci_client->sid;
@@ -496,10 +346,17 @@ static int32_t msm_camera_tz_i2c_ta_cci_read(
}
rc = rsp->rc;
*data = rsp->data;
-
- CDBG("Done: rc=%d, addr=0x%X, data=0x%X\n", rc,
- addr, *data);
}
+ CDBG("Done: rc=%d, SN=%d, MS=%d, SID=%d, CID=%d, ", rc,
+ sensor_id,
+ client->cci_client->cci_i2c_master,
+ client->cci_client->sid,
+ client->cci_client->cid);
+
+ CDBG("Addr=0x%X, Type=%d, Data=0x%X - %lluus\n",
+ addr, data_type, *data,
+ ktime_us_delta(ktime_get(), startTime));
+
return rc;
}
@@ -515,6 +372,7 @@ static int32_t msm_camera_tz_i2c_ta_cci_write(
int32_t rc = 0;
struct qseecom_handle *ta_qseecom_handle;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
+ ktime_t startTime = ktime_get();
if ((client == NULL) ||
(sensor_id < 0) ||
@@ -524,23 +382,14 @@ static int32_t msm_camera_tz_i2c_ta_cci_write(
return -EINVAL;
}
- CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, Addr=0x%X, Data=0x%X Type=%d\n",
- sensor_id,
- client->cci_client->cci_i2c_master,
- client->cci_client->sid,
- client->cci_client->cid,
- addr,
- data,
- data_type);
-
- ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle;
+ ta_qseecom_handle = msm_camera_tz_get_ta_handle();
cmd_len = sizeof(struct msm_camera_tz_i2c_cci_write_req_t);
rsp_len = sizeof(struct msm_camera_tz_i2c_cci_write_rsp_t);
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_CCI_WRITE;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_CCI_WRITE;
cmd->sensor_id = sensor_id;
cmd->cci_i2c_master = client->cci_client->cci_i2c_master;
cmd->sid = client->cci_client->sid;
@@ -559,10 +408,17 @@ static int32_t msm_camera_tz_i2c_ta_cci_write(
return rc;
}
rc = rsp->rc;
-
- CDBG("Done: rc=%d, addr=0x%X, data=0x%X\n", rc,
- addr, data);
}
+ CDBG("Done: rc=%d, SN=%d, MS=%d, SID=%d, CID=%d, ", rc,
+ sensor_id,
+ client->cci_client->cci_i2c_master,
+ client->cci_client->sid,
+ client->cci_client->cid);
+
+ CDBG("Addr=0x%X, Data=0x%X Type=%d - %lluus\n",
+ addr, data, data_type,
+ ktime_us_delta(ktime_get(), startTime));
+
return rc;
}
@@ -576,6 +432,7 @@ static int32_t msm_camera_tz_i2c_ta_cci_util(
int32_t rc = 0;
struct qseecom_handle *ta_qseecom_handle;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
+ ktime_t startTime = ktime_get();
if ((client == NULL) ||
(sensor_id < 0) ||
@@ -585,21 +442,14 @@ static int32_t msm_camera_tz_i2c_ta_cci_util(
return -EINVAL;
}
- CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, cci_cmd=%d\n",
- sensor_id,
- client->cci_client->cci_i2c_master,
- client->cci_client->sid,
- client->cci_client->cid,
- cci_cmd);
-
- ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle;
+ ta_qseecom_handle = msm_camera_tz_get_ta_handle();
cmd_len = sizeof(struct msm_camera_tz_i2c_cci_util_req_t);
rsp_len = sizeof(struct msm_camera_tz_i2c_cci_util_rsp_t);
rc = get_cmd_rsp_buffers(ta_qseecom_handle,
(void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len);
if (!rc) {
- cmd->cmd_id = TZ_I2C_CMD_CCI_UTIL;
+ cmd->cmd_id = MSM_CAMERA_TZ_CMD_CCI_UTIL;
cmd->sensor_id = sensor_id;
cmd->cci_i2c_master = client->cci_client->cci_i2c_master;
cmd->sid = client->cci_client->sid;
@@ -616,8 +466,15 @@ static int32_t msm_camera_tz_i2c_ta_cci_util(
return rc;
}
rc = rsp->rc;
- CDBG("Done: rc=%d, cci_cmd=%d\n", rc, cci_cmd);
}
+ CDBG("Done: rc=%d, SN=%d, MS=%d, SID=%d, CID=%d, CMD=%d - %lluus\n",
+ rc, sensor_id,
+ client->cci_client->cci_i2c_master,
+ client->cci_client->sid,
+ client->cci_client->cid,
+ cci_cmd,
+ ktime_us_delta(ktime_get(), startTime));
+
return rc;
}
@@ -628,9 +485,10 @@ static int32_t msm_camera_tz_i2c_ta_probe(
CDBG("Enter\n");
sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
- if ((sensor_id >= 0) && sensor_info[sensor_id].ta_enabled
- && msm_camera_tz_i2c_ctrl.lock_ready) {
- mutex_lock(&msm_camera_tz_i2c_ctrl.lock);
+ if ((sensor_id >= 0) &&
+ (sensor_id < MAX_CAMERAS) &&
+ (sensor_info[sensor_id].ready != 0)) {
+ msm_camera_tz_lock();
return sensor_id;
}
return -EINVAL;
@@ -638,143 +496,74 @@ static int32_t msm_camera_tz_i2c_ta_probe(
static int32_t msm_camera_tz_i2c_ta_done(void)
{
- int32_t rc = 0;
-
CDBG("Enter\n");
- if (msm_camera_tz_i2c_ctrl.lock_ready)
- mutex_unlock(&msm_camera_tz_i2c_ctrl.lock);
- return rc;
+ msm_camera_tz_unlock();
+ return 0;
}
int32_t msm_camera_tz_i2c_power_up(
struct msm_camera_i2c_client *client)
{
- int32_t rc = -EFAULT;
+ int32_t rc = 0;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
-
- if (!msm_camera_tz_i2c_ctrl.lock_ready) {
- msm_camera_tz_i2c_ctrl.lock_ready = 1;
- mutex_init(&msm_camera_tz_i2c_ctrl.lock);
- }
+ ktime_t startTime = ktime_get();
CDBG("Enter (sensor_id=%d)\n", sensor_id);
- if (sensor_id >= 0) {
- ktime_t startTime;
-
- mutex_lock(&msm_camera_tz_i2c_ctrl.lock);
- if (msm_camera_tz_i2c_ctrl.secure_mode) {
- mutex_unlock(&msm_camera_tz_i2c_ctrl.lock);
- return rc;
- }
- startTime = ktime_get();
-
- CDBG("Switch to secure mode (secure sensor=%d)\n",
- sensor_id);
- /* Start the TA */
- if ((sensor_info[sensor_id].ta_qseecom_handle == NULL)
- && (sensor_info[sensor_id].ta_name != NULL) &&
- ('\0' != sensor_info[sensor_id].ta_name[0])) {
- uint32_t if_version_maj = 0;
- uint32_t if_version_min = 0;
-
- sensor_info[sensor_id].ta_enabled = 0;
- rc = qseecom_start_app(
- &sensor_info[sensor_id].ta_qseecom_handle,
- (char *)sensor_info[sensor_id].ta_name,
- QSEECOM_SBUFF_SIZE);
- if (!rc) {
- rc = msm_camera_tz_i2c_ta_get_if_version(
- sensor_info[sensor_id].
- ta_qseecom_handle,
- &if_version_maj, &if_version_min);
- }
-
- if (!rc) {
- if (if_version_maj != TA_IF_VERSION_MAJ) {
- CDBG("TA ver mismatch %d.%d != %d.%d\n",
- if_version_maj, if_version_min,
- TA_IF_VERSION_MAJ,
- TA_IF_VERSION_MIN);
- rc = qseecom_shutdown_app(
- &sensor_info[sensor_id].
- ta_qseecom_handle);
- sensor_info[sensor_id].ta_qseecom_handle
- = EMPTY_QSEECOM_HANDLE;
- rc = -EFAULT;
- } else {
- uint32_t sensor_secure = 0;
- /*Notify TA & get sensor secure status*/
- rc = msm_camera_tz_i2c_ta_power_up(
- sensor_info[sensor_id].
- ta_qseecom_handle,
- sensor_id,
- &sensor_secure);
- if (!rc && sensor_secure)
- /* Sensor validated by TA*/
- sensor_info[sensor_id].
- ta_enabled = 1;
- else {
- qseecom_shutdown_app(
- &sensor_info[sensor_id].
- ta_qseecom_handle);
- sensor_info[sensor_id].
- ta_qseecom_handle
- = EMPTY_QSEECOM_HANDLE;
- rc = -EFAULT;
- }
- }
+ if ((sensor_id >= 0) && (sensor_id < MAX_CAMERAS)) {
+ rc = msm_camera_tz_load_ta();
+ if (!rc) {
+ uint32_t sensor_secure = 0;
+
+ msm_camera_tz_lock();
+ /* Notify TA & get sensor secure status */
+ rc = msm_camera_tz_i2c_ta_power_up(
+ msm_camera_tz_get_ta_handle(),
+ sensor_id,
+ &sensor_secure);
+ if (!rc && sensor_secure)
+ /* Sensor validated by TA*/
+ sensor_info[sensor_id].ready++;
+ else {
+ msm_camera_tz_unload_ta();
+ rc = -EFAULT;
}
+ msm_camera_tz_unlock();
}
- CDBG("Init TA %s - %s(%d) - %llu\n",
- sensor_info[sensor_id].ta_name,
- (sensor_info[sensor_id].ta_enabled)?"Ok" :
- "Failed", rc, ktime_us_delta(ktime_get(),
- startTime));
- if (!rc)
- msm_camera_tz_i2c_ctrl.secure_mode++;
- mutex_unlock(&msm_camera_tz_i2c_ctrl.lock);
- }
+ } else
+ rc = -EFAULT;
+ CDBG("Power UP sensor = %d, %s(%d) - %lluus\n",
+ sensor_id,
+ (!rc)?"Ok":"Failed", rc,
+ ktime_us_delta(ktime_get(), startTime));
return rc;
}
int32_t msm_camera_tz_i2c_power_down(
struct msm_camera_i2c_client *client)
{
- int32_t rc = -EFAULT;
+ int32_t rc = 0;
int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client);
-
- if (!msm_camera_tz_i2c_ctrl.lock_ready) {
- msm_camera_tz_i2c_ctrl.lock_ready = 1;
- mutex_init(&msm_camera_tz_i2c_ctrl.lock);
- }
+ ktime_t startTime = ktime_get();
CDBG("Enter (sensor_id=%d)\n", sensor_id);
- if ((sensor_id >= 0) && (msm_camera_tz_i2c_ctrl.secure_mode != 0)) {
- mutex_lock(&msm_camera_tz_i2c_ctrl.lock);
- if (msm_camera_tz_i2c_ctrl.secure_mode == 1) {
- ktime_t startTime = ktime_get();
-
- CDBG("Switch to non-secure mode (secure sensor=%d)\n",
- sensor_id);
- /* Shutdown the TA */
- if (sensor_info[sensor_id].ta_qseecom_handle != NULL) {
- msm_camera_tz_i2c_ta_power_down(
- sensor_info[sensor_id].
- ta_qseecom_handle,
- sensor_id);
- rc = qseecom_shutdown_app(&sensor_info[
- sensor_id].ta_qseecom_handle);
- sensor_info[sensor_id].ta_qseecom_handle
- = EMPTY_QSEECOM_HANDLE;
- }
- CDBG("Unload TA %s - %s(%d) - %llu\n",
- sensor_info[sensor_id].ta_name,
- (!rc)?"Ok":"Failed", rc,
- ktime_us_delta(ktime_get(), startTime));
- }
- msm_camera_tz_i2c_ctrl.secure_mode--;
- mutex_unlock(&msm_camera_tz_i2c_ctrl.lock);
- }
+ if ((sensor_id >= 0) &&
+ (sensor_id < MAX_CAMERAS) &&
+ (sensor_info[sensor_id].ready != 0)) {
+
+ msm_camera_tz_lock();
+ rc = msm_camera_tz_i2c_ta_power_down(
+ msm_camera_tz_get_ta_handle(),
+ sensor_id);
+ sensor_info[sensor_id].ready--;
+ msm_camera_tz_unlock();
+ if (!sensor_info[sensor_id].ready)
+ rc = msm_camera_tz_unload_ta();
+ } else
+ rc = -EFAULT;
+ CDBG("Power DOWN sensor = %d, %s(%d) - %lluus\n",
+ sensor_id,
+ (!rc)?"Ok":"Failed", rc,
+ ktime_us_delta(ktime_get(), startTime));
return rc;
}
@@ -839,7 +628,7 @@ int32_t msm_camera_tz_i2c_read_seq(struct msm_camera_i2c_client *client,
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_READ_SEQ);
+ client, MSM_CAMERA_TZ_CMD_CCI_READ_SEQ);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -885,7 +674,7 @@ int32_t msm_camera_tz_i2c_write_seq(struct msm_camera_i2c_client *client,
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_SEQ);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_SEQ);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -907,7 +696,7 @@ int32_t msm_camera_tz_i2c_write_table_async(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_TABLE_ASYNC);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_ASYNC);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -929,7 +718,7 @@ int32_t msm_camera_tz_i2c_write_table_sync(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_SYNC);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -951,7 +740,7 @@ int32_t msm_camera_tz_i2c_write_table_sync_block(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC_BLOCK);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_SYNC_BLOCK);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -974,7 +763,7 @@ int32_t msm_camera_tz_i2c_write_table(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_TABLE);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -996,7 +785,7 @@ int32_t msm_camera_tz_i2c_write_seq_table(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_SEQ_TABLE);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_SEQ_TABLE);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -1018,7 +807,7 @@ int32_t msm_camera_tz_i2c_write_table_w_microdelay(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_TABLE_W_MICRODELAY);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_TABLE_W_MICRODELAY);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -1041,7 +830,7 @@ int32_t msm_camera_tz_i2c_poll(struct msm_camera_i2c_client *client,
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_POLL);
+ client, MSM_CAMERA_TZ_CMD_CCI_POLL);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
@@ -1064,7 +853,7 @@ int32_t msm_camera_tz_i2c_write_conf_tbl(
if (sensor_id >= 0) {
rc = msm_camera_tz_i2c_ta_cci_generic(
- client, TZ_I2C_CMD_CCI_WRITE_CONF_TBL);
+ client, MSM_CAMERA_TZ_CMD_CCI_WRITE_CONF_TBL);
msm_camera_tz_i2c_ta_done();
}
return TZ_I2C_FN_RETURN(rc,
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index fb8f0c4bae37..0188637af85c 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -928,7 +928,7 @@ static int mpq_map_buffer_to_kernel(
MPQ_DVB_DBG_PRINT("%s: secured buffer\n", __func__);
*kernel_mem = NULL;
} else {
- unsigned long tmp;
+ size_t tmp;
*kernel_mem = ion_map_kernel(client, ion_handle);
if (IS_ERR_OR_NULL(*kernel_mem)) {
ret = PTR_ERR(*kernel_mem);
@@ -940,7 +940,7 @@ static int mpq_map_buffer_to_kernel(
}
ion_handle_get_size(client, ion_handle, &tmp);
MPQ_DVB_DBG_PRINT(
- "%s: mapped to address 0x%p, size=%lu\n",
+ "%s: mapped to address 0x%p, size=%zu\n",
__func__, *kernel_mem, tmp);
}
@@ -1801,7 +1801,11 @@ int mpq_dmx_terminate_feed(struct dvb_demux_feed *feed)
}
mpq_sdmx_close_session(mpq_demux);
- mpq_demux->num_secure_feeds--;
+ if (mpq_demux->num_secure_feeds > 0)
+ mpq_demux->num_secure_feeds--;
+ else
+ MPQ_DVB_DBG_PRINT("%s: Invalid secure feed count= %u\n",
+ __func__, mpq_demux->num_secure_feeds);
}
if (dvb_dmx_is_video_feed(feed)) {
@@ -1818,7 +1822,11 @@ int mpq_dmx_terminate_feed(struct dvb_demux_feed *feed)
}
mpq_sdmx_terminate_metadata_buffer(mpq_feed);
- mpq_demux->num_active_feeds--;
+ if (mpq_demux->num_active_feeds > 0)
+ mpq_demux->num_active_feeds--;
+ else
+ MPQ_DVB_DBG_PRINT("%s: Invalid num_active_feeds count = %u\n",
+ __func__, mpq_demux->num_active_feeds);
mutex_unlock(&mpq_demux->mutex);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 7bc1fe1af26d..28faa1436ef5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -318,6 +318,10 @@ err_invalid_input:
static inline void populate_buf_info(struct buffer_info *binfo,
struct v4l2_buffer *b, u32 i)
{
+ if (i >= VIDEO_MAX_PLANES) {
+ dprintk(VIDC_ERR, "%s: Invalid input\n", __func__);
+ return;
+ }
binfo->type = b->type;
binfo->fd[i] = b->m.planes[i].reserved[0];
binfo->buff_off[i] = b->m.planes[i].reserved[1];
@@ -685,7 +689,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 +815,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/venus_boot.c b/drivers/media/platform/msm/vidc/venus_boot.c
index 85c3e15edded..ea53c09ce9a1 100644
--- a/drivers/media/platform/msm/vidc/venus_boot.c
+++ b/drivers/media/platform/msm/vidc/venus_boot.c
@@ -137,11 +137,11 @@ static int venus_clock_prepare_enable(void)
static void venus_clock_disable_unprepare(void)
{
- int i;
struct msm_vidc_platform_resources *res = venus_data->resources;
struct clock_info *cl;
+ int i = res->clock_set.count;
- for (i = 0; i < res->clock_set.count; i++) {
+ for (i--; i >= 0; i--) {
cl = &res->clock_set.clock_tbl[i];
clk_disable_unprepare(cl->clk);
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 520e71fdc272..eceb86b01a7c 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3767,8 +3767,8 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device)
return;
}
- venus_hfi_for_each_clock(device, cl) {
- usleep_range(100, 500);
+ venus_hfi_for_each_clock_reverse(device, cl) {
+ usleep_range(100, 500);
dprintk(VIDC_DBG, "Clock: %s disable and unprepare\n",
cl->name);
clk_disable_unprepare(cl->clk);
@@ -3778,7 +3778,7 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device)
static inline int __prepare_enable_clks(struct venus_hfi_device *device)
{
struct clock_info *cl = NULL, *cl_fail = NULL;
- int rc = 0;
+ int rc = 0, c = 0;
if (!device) {
dprintk(VIDC_ERR, "Invalid params: %pK\n", device);
return -EINVAL;
@@ -3816,6 +3816,7 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device)
goto fail_clk_enable;
}
+ c++;
dprintk(VIDC_DBG, "Clock: %s prepared and enabled\n", cl->name);
}
@@ -3824,9 +3825,7 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device)
return rc;
fail_clk_enable:
- venus_hfi_for_each_clock(device, cl) {
- if (cl_fail == cl)
- break;
+ venus_hfi_for_each_clock_reverse_continue(device, cl, c) {
usleep_range(100, 500);
dprintk(VIDC_ERR, "Clock: %s disable and unprepare\n",
cl->name);
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 8ba763a3b61a..048f247fb0a4 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -187,6 +187,11 @@ struct vidc_iface_q_info {
#define venus_hfi_for_each_clock_reverse(__device, __cinfo) \
venus_hfi_for_each_thing_reverse(__device, __cinfo, clock)
+#define venus_hfi_for_each_clock_reverse_continue(__device, __rinfo, \
+ __from) \
+ venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
+ clock, __from)
+
/* Bus set helpers */
#define venus_hfi_for_each_bus(__device, __binfo) \
venus_hfi_for_each_thing(__device, __binfo, bus)
diff --git a/drivers/media/platform/msm/vidc/vmem/vmem.c b/drivers/media/platform/msm/vidc/vmem/vmem.c
index e86740fdc5ac..428524661695 100644
--- a/drivers/media/platform/msm/vidc/vmem/vmem.c
+++ b/drivers/media/platform/msm/vidc/vmem/vmem.c
@@ -226,9 +226,9 @@ exit:
static inline int __power_off(struct vmem *v)
{
- int c = 0;
+ int c = v->num_clocks;
- for (c = 0; c < v->num_clocks; ++c) {
+ for (c--; c >= 0; --c) {
clk_disable_unprepare(v->clocks[c].clk);
pr_debug("Disabled clock %s\n", v->clocks[c].name);
}
@@ -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/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index c3853a63b083..64046e0bd0a2 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -141,7 +141,7 @@ static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
unmask_halp ? WIL6210_IMC_MISC : WIL6210_IMC_MISC_NO_HALP);
}
-void wil6210_unmask_halp(struct wil6210_priv *wil)
+static void wil6210_unmask_halp(struct wil6210_priv *wil)
{
wil_dbg_irq(wil, "%s()\n", __func__);
@@ -149,7 +149,7 @@ void wil6210_unmask_halp(struct wil6210_priv *wil)
BIT_DMA_EP_MISC_ICR_HALP);
}
-void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
+static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
{
wil_dbg_irq(wil, "%s()\n", __func__);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 94e5b67abd59..5285ebc8b9af 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -875,29 +875,19 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
flush_workqueue(wil->wq_service);
flush_workqueue(wil->wmi_wq);
- wil6210_unmask_irq_pseudo(wil);
- wil6210_unmask_halp(wil);
- wil_halp_vote(wil);
-
wil_bl_crash_info(wil, false);
rc = wil_target_reset(wil);
- /* wil_target_reset clears the HALP IRQ, need to set it again.
- * Call wil_halp_unvote to clear the HALP reference counter
- * and unmask the HALP interrupt before setting it again
- */
- wil_halp_unvote(wil);
- wil_halp_vote(wil);
wil_rx_fini(wil);
if (rc) {
wil_bl_crash_info(wil, true);
- goto out;
+ return rc;
}
rc = wil_get_bl_info(wil);
if (rc == -EAGAIN && !load_fw) /* ignore RF error if not going up */
rc = 0;
if (rc)
- goto out;
+ return rc;
wil_set_oob_mode(wil, oob_mode);
if (load_fw) {
@@ -909,19 +899,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
/* Loading f/w from the file */
rc = wil_request_firmware(wil, WIL_FW_NAME, true);
if (rc)
- goto out;
+ return rc;
rc = wil_request_firmware(wil, WIL_FW2_NAME, true);
if (rc)
- goto out;
+ return rc;
/* Mark FW as loaded from host */
wil_s(wil, RGF_USER_USAGE_6, 1);
- /* Clear the HALP while in BL, before clearing all the IRQs
- * and running the FW.
- */
- wil_halp_unvote(wil);
-
/* clear any interrupts which on-card-firmware
* may have set
*/
@@ -932,9 +917,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
wil_w(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0);
wil_release_cpu(wil);
- } else {
- /* Allow XTAL off when going down */
- wil_halp_unvote(wil);
}
/* init after reset */
@@ -973,10 +955,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
}
return rc;
-
-out:
- wil_halp_unvote(wil);
- return rc;
}
void wil_fw_error_recovery(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 8961b4ce4898..a19dba5b9e5f 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -837,7 +837,6 @@ void wil_configure_interrupt_moderation(struct wil6210_priv *wil);
void wil_disable_irq(struct wil6210_priv *wil);
void wil_enable_irq(struct wil6210_priv *wil);
void wil6210_mask_halp(struct wil6210_priv *wil);
-void wil6210_unmask_halp(struct wil6210_priv *wil);
/* P2P */
bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
@@ -903,8 +902,6 @@ void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
void wil_rx_handle(struct wil6210_priv *wil, int *quota);
void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
-void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil);
-
int wil_iftype_nl2wmi(enum nl80211_iftype type);
int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd);
diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c
index 2dd18dd78677..17b6d1aea4c7 100644
--- a/drivers/nfc/nq-nci.c
+++ b/drivers/nfc/nq-nci.c
@@ -47,6 +47,7 @@ MODULE_DEVICE_TABLE(of, msm_match_table);
#define MAX_BUFFER_SIZE (320)
#define WAKEUP_SRC_TIMEOUT (2000)
+#define MAX_RETRY_COUNT 3
struct nqx_dev {
wait_queue_head_t read_wq;
@@ -264,6 +265,35 @@ out:
return ret;
}
+/**
+ * nqx_standby_write()
+ * @buf: pointer to data buffer
+ * @len: # of bytes need to transfer
+ *
+ * write data buffer over I2C and retry
+ * if NFCC is in stand by mode
+ *
+ * Return: # of bytes written or -ve value in case of error
+ */
+static int nqx_standby_write(struct nqx_dev *nqx_dev,
+ const unsigned char *buf, size_t len)
+{
+ int ret = -EINVAL;
+ int retry_cnt;
+
+ for (retry_cnt = 1; retry_cnt <= MAX_RETRY_COUNT; retry_cnt++) {
+ ret = i2c_master_send(nqx_dev->client, buf, len);
+ if (ret < 0) {
+ dev_err(&nqx_dev->client->dev,
+ "%s: write failed, Maybe in Standby Mode - Retry(%d)\n",
+ __func__, retry_cnt);
+ usleep_range(1000, 1100);
+ } else if (ret == len)
+ break;
+ }
+ return ret;
+}
+
/*
* Power management of the eSE
* NFC & eSE ON : NFC_EN high and eSE_pwr_req high.
@@ -273,39 +303,95 @@ out:
static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg)
{
int r = -1;
+ const unsigned char svdd_off_cmd_warn[] = {0x2F, 0x31, 0x01, 0x01};
+ const unsigned char svdd_off_cmd_done[] = {0x2F, 0x31, 0x01, 0x00};
+
+ if (!gpio_is_valid(nqx_dev->ese_gpio)) {
+ dev_err(&nqx_dev->client->dev,
+ "%s: ese_gpio is not valid\n", __func__);
+ return -EINVAL;
+ }
- /* Let's store the NFC_EN pin state */
if (arg == 0) {
/*
* We want to power on the eSE and to do so we need the
* eSE_pwr_req pin and the NFC_EN pin to be high
*/
- nqx_dev->nfc_ven_enabled = gpio_get_value(nqx_dev->en_gpio);
- if (!nqx_dev->nfc_ven_enabled) {
- gpio_set_value(nqx_dev->en_gpio, 1);
- /* hardware dependent delay */
- usleep_range(1000, 1100);
- }
- if (gpio_is_valid(nqx_dev->ese_gpio)) {
+ if (gpio_get_value(nqx_dev->ese_gpio)) {
+ dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n");
+ r = 0;
+ } else {
+ /**
+ * Let's store the NFC_EN pin state
+ * only if the eSE is not yet on
+ */
+ nqx_dev->nfc_ven_enabled =
+ gpio_get_value(nqx_dev->en_gpio);
+ if (!nqx_dev->nfc_ven_enabled) {
+ gpio_set_value(nqx_dev->en_gpio, 1);
+ /* hardware dependent delay */
+ usleep_range(1000, 1100);
+ }
+ gpio_set_value(nqx_dev->ese_gpio, 1);
if (gpio_get_value(nqx_dev->ese_gpio)) {
- dev_dbg(&nqx_dev->client->dev, "ese_gpio is already high\n");
+ dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n");
r = 0;
- } else {
- gpio_set_value(nqx_dev->ese_gpio, 1);
- if (gpio_get_value(nqx_dev->ese_gpio)) {
- dev_dbg(&nqx_dev->client->dev, "ese_gpio is enabled\n");
- r = 0;
- }
}
}
} else if (arg == 1) {
- if (gpio_is_valid(nqx_dev->ese_gpio)) {
+ if (nqx_dev->nfc_ven_enabled &&
+ ((nqx_dev->nqx_info.info.chip_type == NFCC_NQ_220) ||
+ (nqx_dev->nqx_info.info.chip_type == NFCC_PN66T))) {
+ /**
+ * Let's inform the CLF we're
+ * powering off the eSE
+ */
+ r = nqx_standby_write(nqx_dev, svdd_off_cmd_warn,
+ sizeof(svdd_off_cmd_warn));
+ if (r < 0) {
+ dev_err(&nqx_dev->client->dev,
+ "%s: write failed after max retry\n",
+ __func__);
+ return -ENXIO;
+ }
+ dev_dbg(&nqx_dev->client->dev,
+ "%s: svdd_off_cmd_warn sent\n", __func__);
+
+ /* let's power down the eSE */
gpio_set_value(nqx_dev->ese_gpio, 0);
- if (!gpio_get_value(nqx_dev->ese_gpio)) {
- dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n");
- r = 0;
+ dev_dbg(&nqx_dev->client->dev,
+ "%s: nqx_dev->ese_gpio set to 0\n", __func__);
+
+ /**
+ * Time needed for the SVDD capacitor
+ * to get discharged
+ */
+ usleep_range(8000, 8100);
+
+ /* Let's inform the CLF the eSE is now off */
+ r = nqx_standby_write(nqx_dev, svdd_off_cmd_done,
+ sizeof(svdd_off_cmd_done));
+ if (r < 0) {
+ dev_err(&nqx_dev->client->dev,
+ "%s: write failed after max retry\n",
+ __func__);
+ return -ENXIO;
}
+ dev_dbg(&nqx_dev->client->dev,
+ "%s: svdd_off_cmd_done sent\n", __func__);
+ } else {
+ /**
+ * In case the NFC is off,
+ * there's no need to send the i2c commands
+ */
+ gpio_set_value(nqx_dev->ese_gpio, 0);
}
+
+ if (!gpio_get_value(nqx_dev->ese_gpio)) {
+ dev_dbg(&nqx_dev->client->dev, "ese_gpio is disabled\n");
+ r = 0;
+ }
+
if (!nqx_dev->nfc_ven_enabled) {
/* hardware dependent delay */
usleep_range(1000, 1100);
@@ -313,12 +399,7 @@ static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg)
gpio_set_value(nqx_dev->en_gpio, 0);
}
} else if (arg == 3) {
- if (!nqx_dev->nfc_ven_enabled)
- r = 0;
- else {
- if (gpio_is_valid(nqx_dev->ese_gpio))
- r = gpio_get_value(nqx_dev->ese_gpio);
- }
+ r = gpio_get_value(nqx_dev->ese_gpio);
}
return r;
}
@@ -624,6 +705,10 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
dev_dbg(&client->dev,
"%s: ## NFCC == NQ330 ##\n", __func__);
break;
+ case NFCC_PN66T:
+ dev_dbg(&client->dev,
+ "%s: ## NFCC == PN66T ##\n", __func__);
+ break;
default:
dev_err(&client->dev,
"%s: - NFCC HW not Supported\n", __func__);
diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h
index c635e818b1f3..f34c4d987143 100644
--- a/drivers/nfc/nq-nci.h
+++ b/drivers/nfc/nq-nci.h
@@ -48,7 +48,7 @@ enum nfcc_chip_variant {
NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */
NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */
NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */
+ NFCC_PN66T = 0x18, /**< NFCC PN66T */
NFCC_NOT_SUPPORTED = 0xFF /**< NFCC is not supported */
};
-
#endif
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/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index e0cab3a683d6..6e06fef81849 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -15,8 +15,8 @@
#include "phy-qcom-ufs-i.h"
#define MAX_PROP_NAME 32
-#define VDDA_PHY_MIN_UV 1000000
-#define VDDA_PHY_MAX_UV 1000000
+#define VDDA_PHY_MIN_UV 800000
+#define VDDA_PHY_MAX_UV 925000
#define VDDA_PLL_MIN_UV 1200000
#define VDDA_PLL_MAX_UV 1800000
#define VDDP_REF_CLK_MIN_UV 1200000
@@ -239,7 +239,6 @@ ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
struct ufs_qcom_phy *phy_common)
{
int err;
- int vdda_phy_uV;
err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_pll,
"vdda-pll");
@@ -251,10 +250,6 @@ ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
if (err)
goto out;
- vdda_phy_uV = regulator_get_voltage(phy_common->vdda_phy.reg);
- phy_common->vdda_phy.max_uV = vdda_phy_uV;
- phy_common->vdda_phy.min_uV = vdda_phy_uV;
-
/* vddp-ref-clk-* properties are optional */
__ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vddp_ref_clk,
"vddp-ref-clk", true);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index 9813fa417c3a..8968d5d4509f 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -450,6 +450,10 @@ int ipa_get_clients_from_rm_resource(
case IPA_RM_RESOURCE_MHI_CONS:
clients->names[i++] = IPA_CLIENT_MHI_CONS;
break;
+ case IPA_RM_RESOURCE_ODU_ADAPT_CONS:
+ clients->names[i++] = IPA_CLIENT_ODU_EMB_CONS;
+ clients->names[i++] = IPA_CLIENT_ODU_TETH_CONS;
+ break;
case IPA_RM_RESOURCE_USB_PROD:
clients->names[i++] = IPA_CLIENT_USB_PROD;
break;
@@ -459,6 +463,8 @@ int ipa_get_clients_from_rm_resource(
case IPA_RM_RESOURCE_MHI_PROD:
clients->names[i++] = IPA_CLIENT_MHI_PROD;
break;
+ case IPA_RM_RESOURCE_ODU_ADAPT_PROD:
+ clients->names[i++] = IPA_CLIENT_ODU_PROD;
default:
break;
}
@@ -490,13 +496,15 @@ bool ipa_should_pipe_be_suspended(enum ipa_client_type client)
if (ep->keep_ipa_awake)
return false;
- if (client == IPA_CLIENT_USB_CONS ||
- client == IPA_CLIENT_MHI_CONS ||
- client == IPA_CLIENT_HSIC1_CONS ||
- client == IPA_CLIENT_WLAN1_CONS ||
- client == IPA_CLIENT_WLAN2_CONS ||
- client == IPA_CLIENT_WLAN3_CONS ||
- client == IPA_CLIENT_WLAN4_CONS)
+ if (client == IPA_CLIENT_USB_CONS ||
+ client == IPA_CLIENT_MHI_CONS ||
+ client == IPA_CLIENT_HSIC1_CONS ||
+ client == IPA_CLIENT_WLAN1_CONS ||
+ client == IPA_CLIENT_WLAN2_CONS ||
+ client == IPA_CLIENT_WLAN3_CONS ||
+ client == IPA_CLIENT_WLAN4_CONS ||
+ client == IPA_CLIENT_ODU_EMB_CONS ||
+ client == IPA_CLIENT_ODU_TETH_CONS)
return true;
return false;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
index ab4911462ddf..e38f6f2860cf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -1356,6 +1356,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
u32 prod_hdl;
int i;
+ u32 rx_door_bell_value;
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -1367,28 +1368,6 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
if (result)
return result;
- /* checking rdy_ring_rp_pa matches the rdy_comp_ring_wp_pa on WDI2.0 */
- if (ipa3_ctx->ipa_wdi2) {
- for (i = 0; i < IPA_UC_FINISH_MAX; i++) {
- IPADBG("(%d) rp_value(%u), comp_wp_value(%u)\n",
- i,
- *ipa3_ctx->uc_ctx.rdy_ring_rp_va,
- *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va);
- if (*ipa3_ctx->uc_ctx.rdy_ring_rp_va !=
- *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va) {
- usleep_range(IPA_UC_WAIT_MIN_SLEEP,
- IPA_UC_WAII_MAX_SLEEP);
- } else {
- break;
- }
- }
- /* In case ipa_uc still haven't processed all
- * pending descriptors, we have to assert
- */
- if (i == IPA_UC_FINISH_MAX)
- WARN_ON(1);
- }
-
IPADBG("ep=%d\n", clnt_hdl);
ep = &ipa3_ctx->ep[clnt_hdl];
@@ -1429,10 +1408,40 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
}
usleep_range(IPA_UC_POLL_SLEEP_USEC * IPA_UC_POLL_SLEEP_USEC,
IPA_UC_POLL_SLEEP_USEC * IPA_UC_POLL_SLEEP_USEC);
+
+ /*
+ * checking rdy_ring_rp_pa matches the
+ * rdy_comp_ring_wp_pa on WDI2.0
+ */
+ if (ipa3_ctx->ipa_wdi2) {
+ for (i = 0; i < IPA_UC_FINISH_MAX; i++) {
+ rx_door_bell_value = ipahal_read_reg_mn(
+ IPA_UC_MAILBOX_m_n,
+ IPA_HW_WDI_RX_MBOX_START_INDEX/32,
+ IPA_HW_WDI_RX_MBOX_START_INDEX % 32);
+ IPADBG("(%d)rx_DB(%u)rp(%u),comp_wp(%u)\n",
+ i,
+ rx_door_bell_value,
+ *ipa3_ctx->uc_ctx.rdy_ring_rp_va,
+ *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va);
+ if (rx_door_bell_value !=
+ *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va) {
+ usleep_range(IPA_UC_WAIT_MIN_SLEEP,
+ IPA_UC_WAII_MAX_SLEEP);
+ } else {
+ break;
+ }
+ }
+ /*
+ * In case ipa_uc still haven't processed all
+ * pending descriptors, we have to assert
+ */
+ if (i == IPA_UC_FINISH_MAX)
+ ipa_assert();
+ }
}
disable.params.ipa_pipe_number = clnt_hdl;
-
result = ipa3_uc_send_cmd(disable.raw32b,
IPA_CPU_2_HW_CMD_WDI_CH_DISABLE,
IPA_HW_2_CPU_WDI_CMD_STATUS_SUCCESS,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index db60829bce69..c5b5d1892485 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -507,6 +507,10 @@ int ipa3_get_clients_from_rm_resource(
case IPA_RM_RESOURCE_MHI_CONS:
clients->names[i++] = IPA_CLIENT_MHI_CONS;
break;
+ case IPA_RM_RESOURCE_ODU_ADAPT_CONS:
+ clients->names[i++] = IPA_CLIENT_ODU_EMB_CONS;
+ clients->names[i++] = IPA_CLIENT_ODU_TETH_CONS;
+ break;
case IPA_RM_RESOURCE_USB_PROD:
clients->names[i++] = IPA_CLIENT_USB_PROD;
break;
@@ -516,6 +520,8 @@ int ipa3_get_clients_from_rm_resource(
case IPA_RM_RESOURCE_MHI_PROD:
clients->names[i++] = IPA_CLIENT_MHI_PROD;
break;
+ case IPA_RM_RESOURCE_ODU_ADAPT_PROD:
+ clients->names[i++] = IPA_CLIENT_ODU_PROD;
default:
break;
}
@@ -554,7 +560,9 @@ bool ipa3_should_pipe_be_suspended(enum ipa_client_type client)
client == IPA_CLIENT_WLAN1_CONS ||
client == IPA_CLIENT_WLAN2_CONS ||
client == IPA_CLIENT_WLAN3_CONS ||
- client == IPA_CLIENT_WLAN4_CONS)
+ client == IPA_CLIENT_WLAN4_CONS ||
+ client == IPA_CLIENT_ODU_EMB_CONS ||
+ client == IPA_CLIENT_ODU_TETH_CONS)
return true;
return false;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index cef9f7ef3fe4..347a8c418ebb 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1287,6 +1287,38 @@ u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n)
}
/*
+ * ipahal_read_reg_mn() - Get mn parameterized reg value
+ */
+u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n)
+{
+ u32 offset;
+
+ if (reg >= IPA_REG_MAX) {
+ IPAHAL_ERR("Invalid register reg=%u\n", reg);
+ return -EFAULT;
+ }
+
+ IPAHAL_DBG_LOW("read %s m=%u n=%u\n",
+ ipahal_reg_name_str(reg), m, n);
+ offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
+ if (offset == -1) {
+ IPAHAL_ERR("Read access to obsolete reg=%s\n",
+ ipahal_reg_name_str(reg));
+ WARN_ON_ONCE(1);
+ return -EFAULT;
+ }
+ /*
+ * Currently there is one register with m and n parameters
+ * IPA_UC_MAILBOX_m_n. The m value of it is 0x80.
+ * If more such registers will be added in the future,
+ * we can move the m parameter to the table above.
+ */
+ offset += 0x80 * m;
+ offset += ipahal_reg_objs[ipahal_ctx->hw_type][reg].n_ofst * n;
+ return ioread32(ipahal_ctx->base + offset);
+}
+
+/*
* ipahal_write_reg_mn() - Write to m/n parameterized reg a raw value
*/
void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
index 8fb9040360ea..5f1e3fe410b1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
@@ -341,6 +341,11 @@ const char *ipahal_reg_name_str(enum ipahal_reg_name reg_name);
u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n);
/*
+ * ipahal_read_reg_mn() - Get mn parameterized reg value
+ */
+u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n);
+
+/*
* ipahal_write_reg_mn() - Write to m/n parameterized reg a raw value
*/
void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val);
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 2718ea93bd45..d83928901a77 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -250,6 +250,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(update_now),
POWER_SUPPLY_ATTR(esr_count),
POWER_SUPPLY_ATTR(buck_freq),
+ POWER_SUPPLY_ATTR(boost_current),
POWER_SUPPLY_ATTR(safety_timer_enabled),
POWER_SUPPLY_ATTR(charge_done),
POWER_SUPPLY_ATTR(flash_active),
diff --git a/drivers/power/qcom-charger/battery_current_limit.c b/drivers/power/qcom-charger/battery_current_limit.c
index 951d0544efa0..d2c25bfbf66c 100644
--- a/drivers/power/qcom-charger/battery_current_limit.c
+++ b/drivers/power/qcom-charger/battery_current_limit.c
@@ -1495,10 +1495,7 @@ static int probe_bcl_periph_prop(struct bcl_context *bcl)
bcl->ibat_high_thresh.trip_value);
if (ret)
goto ibat_probe_exit;
- BCL_FETCH_DT_U32(ibat_node, key, "qcom,mitigation-freq-khz", ret,
- bcl->bcl_p_freq_max);
- if (ret)
- goto ibat_probe_exit;
+
BCL_FETCH_DT_U32(ibat_node, key, "qcom,vph-high-threshold-uv", ret,
bcl->vbat_high_thresh.trip_value);
if (ret)
@@ -1520,7 +1517,18 @@ static int probe_bcl_periph_prop(struct bcl_context *bcl)
= bcl->ibat_low_thresh.trip_notify = bcl_periph_ibat_notify;
bcl->ibat_high_thresh.trip_data
= bcl->ibat_low_thresh.trip_data = (void *) bcl;
- get_vdd_rstr_freq(bcl, ibat_node);
+
+ if (bcl_frequency_mask) {
+ BCL_FETCH_DT_U32(ibat_node, key, "qcom,mitigation-freq-khz",
+ ret, bcl->bcl_p_freq_max);
+ if (ret)
+ goto ibat_probe_exit;
+ get_vdd_rstr_freq(bcl, ibat_node);
+ } else {
+ bcl->bcl_p_freq_max = UINT_MAX;
+ bcl->thermal_freq_limit = 0;
+ }
+
bcl->bcl_p_freq_max = max(bcl->bcl_p_freq_max, bcl->thermal_freq_limit);
bcl->btm_mode = BCL_MONITOR_DISABLED;
@@ -1574,11 +1582,6 @@ static int probe_btm_properties(struct bcl_context *bcl)
goto btm_probe_exit;
bcl->btm_high_threshold_uv = current_to_voltage(bcl, curr_ua);
- key = "qcom,mitigation-freq-khz";
- ret = of_property_read_u32(ibat_node, key, &bcl->btm_freq_max);
- if (ret < 0)
- goto btm_probe_exit;
-
key = "qcom,ibat-channel";
ret = of_property_read_u32(ibat_node, key, &bcl->btm_ibat_chan);
if (ret < 0)
@@ -1618,7 +1621,17 @@ static int probe_btm_properties(struct bcl_context *bcl)
ret = PTR_ERR(bcl->btm_vadc_dev);
goto btm_probe_exit;
}
- get_vdd_rstr_freq(bcl, ibat_node);
+
+ if (bcl_frequency_mask) {
+ key = "qcom,mitigation-freq-khz";
+ ret = of_property_read_u32(ibat_node, key, &bcl->btm_freq_max);
+ if (ret < 0)
+ goto btm_probe_exit;
+ get_vdd_rstr_freq(bcl, ibat_node);
+ } else {
+ bcl->btm_freq_max = UINT_MAX;
+ bcl->thermal_freq_limit = 0;
+ }
bcl->btm_freq_max = max(bcl->btm_freq_max, bcl->thermal_freq_limit);
bcl->btm_mode = BCL_MONITOR_DISABLED;
@@ -1738,6 +1751,8 @@ static int bcl_probe(struct platform_device *pdev)
}
}
for_each_possible_cpu(cpu) {
+ if (!(bcl_frequency_mask & BIT(cpu)))
+ continue;
snprintf(cpu_str, MAX_CPU_NAME, "cpu%d", cpu);
bcl->cpufreq_handle[cpu] = devmgr_register_mitigation_client(
&pdev->dev, cpu_str, NULL);
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index f0de532f196c..9ddd18800f9d 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -188,6 +188,10 @@ struct fg_alg_flag {
bool invalid;
};
+enum wa_flags {
+ PMI8998_V1_REV_WA = BIT(0),
+};
+
/* DT parameters for FG device */
struct fg_dt_props {
bool force_load_profile;
@@ -306,6 +310,7 @@ struct fg_chip {
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
+ u32 wa_flags;
int batt_id_kohms;
int charge_status;
int prev_charge_status;
diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c
index 4d2cfc84d455..74fa041738ff 100644
--- a/drivers/power/qcom-charger/qpnp-fg-gen3.c
+++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c
@@ -550,7 +550,7 @@ static int fg_get_battery_esr(struct fg_chip *chip, int *val)
return rc;
}
- if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)
+ if (chip->wa_flags & PMI8998_V1_REV_WA)
temp = ((buf[0] & ESR_MSB_MASK) << 8) |
(buf[1] & ESR_LSB_MASK);
else
@@ -597,7 +597,7 @@ static int fg_get_battery_current(struct fg_chip *chip, int *val)
return rc;
}
- if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)
+ if (chip->wa_flags & PMI8998_V1_REV_WA)
temp = buf[0] << 8 | buf[1];
else
temp = buf[1] << 8 | buf[0];
@@ -624,7 +624,7 @@ static int fg_get_battery_voltage(struct fg_chip *chip, int *val)
return rc;
}
- if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)
+ if (chip->wa_flags & PMI8998_V1_REV_WA)
temp = buf[0] << 8 | buf[1];
else
temp = buf[1] << 8 | buf[0];
@@ -824,10 +824,10 @@ static int fg_get_batt_profile(struct fg_chip *chip)
chip->bp.float_volt_uv = -EINVAL;
}
- rc = of_property_read_u32(profile_node, "qcom,nom-batt-capacity-mah",
+ rc = of_property_read_u32(profile_node, "qcom,fastchg-current-ma",
&chip->bp.fastchg_curr_ma);
if (rc < 0) {
- pr_err("battery nominal capacity unavailable, rc:%d\n", rc);
+ pr_err("battery fastchg current unavailable, rc:%d\n", rc);
chip->bp.fastchg_curr_ma = -EINVAL;
}
@@ -2401,8 +2401,8 @@ static int fg_hw_init(struct fg_chip *chip)
}
/* This SRAM register is only present in v2.0 and above */
- if (chip->pmic_rev_id->rev4 >= PMI8998_V2P0_REV4 &&
- chip->bp.float_volt_uv > 0) {
+ if (!(chip->wa_flags & PMI8998_V1_REV_WA) &&
+ chip->bp.float_volt_uv > 0) {
fg_encode(chip->sp, FG_SRAM_FLOAT_VOLT,
chip->bp.float_volt_uv / 1000, buf);
rc = fg_sram_write(chip, chip->sp[FG_SRAM_FLOAT_VOLT].addr_word,
@@ -2482,8 +2482,8 @@ static int fg_hw_init(struct fg_chip *chip)
}
/* This configuration is available only for pmicobalt v2.0 and above */
- if (chip->pmic_rev_id->rev4 >= PMI8998_V2P0_REV4 &&
- chip->dt.recharge_volt_thr_mv > 0) {
+ if (!(chip->wa_flags & PMI8998_V1_REV_WA) &&
+ chip->dt.recharge_volt_thr_mv > 0) {
fg_encode(chip->sp, FG_SRAM_RECHARGE_VBATT_THR,
chip->dt.recharge_volt_thr_mv, buf);
rc = fg_sram_write(chip,
@@ -3013,6 +3013,7 @@ static int fg_parse_dt(struct fg_chip *chip)
if (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4) {
chip->sp = pmi8998_v1_sram_params;
chip->alg_flags = pmi8998_v1_alg_flags;
+ chip->wa_flags |= PMI8998_V1_REV_WA;
} else if (chip->pmic_rev_id->rev4 == PMI8998_V2P0_REV4) {
chip->sp = pmi8998_v2_sram_params;
chip->alg_flags = pmi8998_v2_alg_flags;
@@ -3020,6 +3021,10 @@ static int fg_parse_dt(struct fg_chip *chip)
return -EINVAL;
}
break;
+ case PMFALCON_SUBTYPE:
+ chip->sp = pmi8998_v2_sram_params;
+ chip->alg_flags = pmi8998_v2_alg_flags;
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 0faf8aee8aa0..507704dd469a 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -2452,12 +2452,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
rc);
}
} else {
- if (chg->wa_flags & BOOST_BACK_WA) {
+ if (chg->wa_flags & BOOST_BACK_WA)
vote(chg->usb_suspend_votable,
BOOST_BACK_VOTER, false, 0);
- vote(chg->dc_suspend_votable,
- BOOST_BACK_VOTER, false, 0);
- }
if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) {
smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n");
@@ -2941,14 +2938,12 @@ irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data)
get_effective_result(chg->usb_suspend_votable))
return IRQ_HANDLED;
- if ((stat & USE_DCIN_BIT) &&
- get_effective_result(chg->dc_suspend_votable))
+ if (stat & USE_DCIN_BIT)
return IRQ_HANDLED;
if (is_storming(&irq_data->storm_data)) {
- smblib_dbg(chg, PR_MISC, "reverse boost detected; suspending input\n");
+ smblib_err(chg, "Reverse boost detected: suspending input\n");
vote(chg->usb_suspend_votable, BOOST_BACK_VOTER, true, 0);
- vote(chg->dc_suspend_votable, BOOST_BACK_VOTER, true, 0);
}
return IRQ_HANDLED;
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index 727a768e63eb..3ac4611da9bd 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -486,9 +486,9 @@ static long msm_core_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
get_user(cluster, &argp->cluster);
- mpidr = (argp->cluster << (MAX_CORES_PER_CLUSTER *
+ mpidr = (cluster << (MAX_CORES_PER_CLUSTER *
MAX_NUM_OF_CLUSTERS));
- cpumask = argp->cpumask;
+ get_user(cpumask, &argp->cpumask);
switch (cmd) {
case EA_LEAKAGE:
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 409fa4ad9c9c..ba1bf3b5f492 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -826,6 +826,15 @@ config REGULATOR_QPNP_LABIBB
negative boost regulator. LAB/IBB regulators can also be used
together for LCD or AMOLED.
+config REGULATOR_QPNP_LCDB
+ depends on SPMI
+ tristate "Qualcomm Technologies, Inc QPNP LCDB support"
+ help
+ Supports the LCDB module in the Qualcomm Technologies, Inc
+ QPNP PMIC. Exposes regulators to control the positive and
+ negative voltage bias for the LCD display panel. It also
+ allows configurability for the various bias-voltage parameters.
+
config REGULATOR_SPM
bool "SPM regulator driver"
depends on SPMI
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 4dc9b4d4c5b7..79a203418a0b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_REGULATOR_CPR3_MMSS) += cpr3-mmss-regulator.o
obj-$(CONFIG_REGULATOR_CPR4_APSS) += cpr4-apss-regulator.o
obj-$(CONFIG_REGULATOR_CPRH_KBSS) += cprh-kbss-regulator.o
obj-$(CONFIG_REGULATOR_QPNP_LABIBB) += qpnp-labibb-regulator.o
+obj-$(CONFIG_REGULATOR_QPNP_LCDB) += qpnp-lcdb-regulator.o
obj-$(CONFIG_REGULATOR_STUB) += stub-regulator.o
obj-$(CONFIG_REGULATOR_KRYO) += kryo-regulator.o
obj-$(CONFIG_REGULATOR_CPR2_GFX) += cpr2-gfx-regulator.o
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/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
new file mode 100644
index 000000000000..daa4e8e74d5b
--- /dev/null
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -0,0 +1,1692 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "LCDB: %s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
+
+#define QPNP_LCDB_REGULATOR_DRIVER_NAME "qcom,qpnp-lcdb-regulator"
+
+/* LCDB */
+#define LCDB_STS1_REG 0x08
+
+#define INT_RT_STATUS_REG 0x10
+#define VREG_OK_RT_STS_BIT BIT(0)
+
+#define LCDB_AUTO_TOUCH_WAKE_CTL_REG 0x40
+#define EN_AUTO_TOUCH_WAKE_BIT BIT(7)
+#define ATTW_TOFF_TIME_MASK GENMASK(3, 2)
+#define ATTW_TON_TIME_MASK GENMASK(1, 0)
+#define ATTW_TOFF_TIME_SHIFT 2
+#define ATTW_MIN_MS 4
+#define ATTW_MAX_MS 32
+
+#define LCDB_BST_OUTPUT_VOLTAGE_REG 0x41
+
+#define LCDB_MODULE_RDY_REG 0x45
+#define MODULE_RDY_BIT BIT(7)
+
+#define LCDB_ENABLE_CTL1_REG 0x46
+#define MODULE_EN_BIT BIT(7)
+#define HWEN_RDY_BIT BIT(6)
+
+/* BST */
+#define LCDB_BST_PD_CTL_REG 0x47
+#define BOOST_DIS_PULLDOWN_BIT BIT(1)
+#define BOOST_PD_STRENGTH_BIT BIT(0)
+
+#define LCDB_BST_ILIM_CTL_REG 0x4B
+#define EN_BST_ILIM_BIT BIT(7)
+#define SET_BST_ILIM_MASK GENMASK(2, 0)
+#define MIN_BST_ILIM_MA 200
+#define MAX_BST_ILIM_MA 1600
+
+#define LCDB_PS_CTL_REG 0x50
+#define EN_PS_BIT BIT(7)
+#define PS_THRESHOLD_MASK GENMASK(1, 0)
+#define MIN_BST_PS_MA 50
+#define MAX_BST_PS_MA 80
+
+#define LCDB_RDSON_MGMNT_REG 0x53
+#define NFET_SW_SIZE_MASK GENMASK(3, 2)
+#define NFET_SW_SIZE_SHIFT 2
+#define PFET_SW_SIZE_MASK GENMASK(1, 0)
+
+#define LCDB_BST_VREG_OK_CTL_REG 0x55
+#define BST_VREG_OK_DEB_MASK GENMASK(1, 0)
+
+#define LCDB_SOFT_START_CTL_REG 0x5F
+
+#define LCDB_MISC_CTL_REG 0x60
+#define AUTO_GM_EN_BIT BIT(4)
+#define EN_TOUCH_WAKE_BIT BIT(3)
+#define DIS_SCP_BIT BIT(0)
+
+#define LCDB_PFM_CTL_REG 0x62
+#define EN_PFM_BIT BIT(7)
+#define BYP_BST_SOFT_START_COMP_BIT BIT(0)
+#define PFM_HYSTERESIS_SHIFT 4
+#define PFM_CURRENT_SHIFT 2
+
+#define LCDB_PWRUP_PWRDN_CTL_REG 0x66
+
+/* LDO */
+#define LCDB_LDO_OUTPUT_VOLTAGE_REG 0x71
+#define SET_OUTPUT_VOLTAGE_MASK GENMASK(4, 0)
+
+#define LCDB_LDO_VREG_OK_CTL_REG 0x75
+#define VREG_OK_DEB_MASK GENMASK(1, 0)
+
+#define LCDB_LDO_PD_CTL_REG 0x77
+#define LDO_DIS_PULLDOWN_BIT BIT(1)
+#define LDO_PD_STRENGTH_BIT BIT(0)
+
+#define LCDB_LDO_ILIM_CTL1_REG 0x7B
+#define EN_LDO_ILIM_BIT BIT(7)
+#define SET_LDO_ILIM_MASK GENMASK(2, 0)
+#define MIN_LDO_ILIM_MA 110
+#define MAX_LDO_ILIM_MA 460
+#define LDO_ILIM_STEP_MA 50
+
+#define LCDB_LDO_ILIM_CTL2_REG 0x7C
+
+#define LCDB_LDO_SOFT_START_CTL_REG 0x7F
+#define SOFT_START_MASK GENMASK(1, 0)
+
+/* NCP */
+#define LCDB_NCP_OUTPUT_VOLTAGE_REG 0x81
+
+#define LCDB_NCP_VREG_OK_CTL_REG 0x85
+
+#define LCDB_NCP_PD_CTL_REG 0x87
+#define NCP_DIS_PULLDOWN_BIT BIT(1)
+#define NCP_PD_STRENGTH_BIT BIT(0)
+
+#define LCDB_NCP_ILIM_CTL1_REG 0x8B
+#define EN_NCP_ILIM_BIT BIT(7)
+#define SET_NCP_ILIM_MASK GENMASK(1, 0)
+#define MIN_NCP_ILIM_MA 260
+#define MAX_NCP_ILIM_MA 810
+
+#define LCDB_NCP_ILIM_CTL2_REG 0x8C
+
+#define LCDB_NCP_SOFT_START_CTL_REG 0x8F
+
+/* common for BST/NCP/LDO */
+#define MIN_DBC_US 2
+#define MAX_DBC_US 32
+
+#define MIN_SOFT_START_US 0
+#define MAX_SOFT_START_US 2000
+
+struct ldo_regulator {
+ struct regulator_desc rdesc;
+ struct regulator_dev *rdev;
+ struct device_node *node;
+
+ /* LDO DT params */
+ int pd;
+ int pd_strength;
+ int ilim_ma;
+ int soft_start_us;
+ int vreg_ok_dbc_us;
+ int voltage_mv;
+};
+
+struct ncp_regulator {
+ struct regulator_desc rdesc;
+ struct regulator_dev *rdev;
+ struct device_node *node;
+
+ /* NCP DT params */
+ int pd;
+ int pd_strength;
+ int ilim_ma;
+ int soft_start_us;
+ int vreg_ok_dbc_us;
+ int voltage_mv;
+};
+
+struct bst_params {
+ struct device_node *node;
+
+ /* BST DT params */
+ int pd;
+ int pd_strength;
+ int ilim_ma;
+ int ps;
+ int ps_threshold;
+ int soft_start_us;
+ int vreg_ok_dbc_us;
+ int voltage_mv;
+};
+
+struct qpnp_lcdb {
+ struct device *dev;
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ u32 base;
+
+ /* TTW params */
+ bool ttw_enable;
+ bool ttw_mode_sw;
+
+ /* status parameters */
+ bool lcdb_enabled;
+ bool settings_saved;
+
+ struct mutex lcdb_mutex;
+ struct mutex read_write_mutex;
+ struct bst_params bst;
+ struct ldo_regulator ldo;
+ struct ncp_regulator ncp;
+};
+
+struct settings {
+ u16 address;
+ u8 value;
+ bool sec_access;
+};
+
+enum lcdb_module {
+ LDO,
+ NCP,
+ BST,
+};
+
+enum pfm_hysteresis {
+ PFM_HYST_15MV,
+ PFM_HYST_25MV,
+ PFM_HYST_35MV,
+ PFM_HYST_45MV,
+};
+
+enum pfm_peak_current {
+ PFM_PEAK_CURRENT_300MA,
+ PFM_PEAK_CURRENT_400MA,
+ PFM_PEAK_CURRENT_500MA,
+ PFM_PEAK_CURRENT_600MA,
+};
+
+enum rdson_fet_size {
+ RDSON_QUARTER,
+ RDSON_HALF,
+ RDSON_THREE_FOURTH,
+ RDSON_FULLSIZE,
+};
+
+enum lcdb_settings_index {
+ LCDB_BST_PD_CTL = 0,
+ LCDB_RDSON_MGMNT,
+ LCDB_MISC_CTL,
+ LCDB_SOFT_START_CTL,
+ LCDB_PFM_CTL,
+ LCDB_PWRUP_PWRDN_CTL,
+ LCDB_LDO_PD_CTL,
+ LCDB_LDO_SOFT_START_CTL,
+ LCDB_NCP_PD_CTL,
+ LCDB_NCP_SOFT_START_CTL,
+ LCDB_SETTING_MAX,
+};
+
+static u32 soft_start_us[] = {
+ 0,
+ 500,
+ 1000,
+ 2000,
+};
+
+static u32 dbc_us[] = {
+ 2,
+ 4,
+ 16,
+ 32,
+};
+
+static u32 ncp_ilim_ma[] = {
+ 260,
+ 460,
+ 640,
+ 810,
+};
+
+#define SETTING(_id, _sec_access) \
+ [_id] = { \
+ .address = _id##_REG, \
+ .sec_access = _sec_access, \
+ } \
+
+static bool is_between(int value, int min, int max)
+{
+ if (value < min || value > max)
+ return false;
+ return true;
+}
+
+static int qpnp_lcdb_read(struct qpnp_lcdb *lcdb,
+ u16 addr, u8 *value, u8 count)
+{
+ int rc = 0;
+
+ mutex_lock(&lcdb->read_write_mutex);
+ rc = regmap_bulk_read(lcdb->regmap, addr, value, count);
+ if (rc < 0)
+ pr_err("Failed to read from addr=0x%02x rc=%d\n", addr, rc);
+ mutex_unlock(&lcdb->read_write_mutex);
+
+ return rc;
+}
+
+static int qpnp_lcdb_write(struct qpnp_lcdb *lcdb,
+ u16 addr, u8 *value, u8 count)
+{
+ int rc;
+
+ mutex_lock(&lcdb->read_write_mutex);
+ rc = regmap_bulk_write(lcdb->regmap, addr, value, count);
+ if (rc < 0)
+ pr_err("Failed to write to addr=0x%02x rc=%d\n", addr, rc);
+ mutex_unlock(&lcdb->read_write_mutex);
+
+ return rc;
+}
+
+#define SEC_ADDRESS_REG 0xD0
+#define SECURE_UNLOCK_VALUE 0xA5
+static int qpnp_lcdb_secure_write(struct qpnp_lcdb *lcdb,
+ u16 addr, u8 value)
+{
+ int rc;
+ u8 val = SECURE_UNLOCK_VALUE;
+
+ mutex_lock(&lcdb->read_write_mutex);
+ rc = regmap_write(lcdb->regmap, lcdb->base + SEC_ADDRESS_REG, val);
+ if (rc < 0) {
+ pr_err("Failed to unlock register rc=%d\n", rc);
+ goto fail_write;
+ }
+ rc = regmap_write(lcdb->regmap, addr, value);
+ if (rc < 0)
+ pr_err("Failed to write to addr=0x%02x rc=%d\n", addr, rc);
+
+fail_write:
+ mutex_unlock(&lcdb->read_write_mutex);
+ return rc;
+}
+
+static int qpnp_lcdb_masked_write(struct qpnp_lcdb *lcdb,
+ u16 addr, u8 mask, u8 value)
+{
+ int rc = 0;
+
+ mutex_lock(&lcdb->read_write_mutex);
+ rc = regmap_update_bits(lcdb->regmap, addr, mask, value);
+ if (rc < 0)
+ pr_err("Failed to write addr=0x%02x value=0x%02x rc=%d\n",
+ addr, value, rc);
+ mutex_unlock(&lcdb->read_write_mutex);
+
+ return rc;
+}
+
+static bool is_lcdb_enabled(struct qpnp_lcdb *lcdb)
+{
+ int rc;
+ u8 val = 0;
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1);
+ if (rc < 0)
+ pr_err("Failed to read ENABLE_CTL1 rc=%d\n", rc);
+
+ return rc ? false : !!(val & MODULE_EN_BIT);
+}
+
+static int dump_status_registers(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ u8 sts[6] = {0};
+
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_STS1_REG, &sts[0], 6);
+ if (rc < 0) {
+ pr_err("Failed to write to STS registers rc=%d\n", rc);
+ } else {
+ rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_STS1_REG, sts, 6);
+ if (rc < 0)
+ pr_err("Failed to read lcdb status rc=%d\n", rc);
+ else
+ pr_err("STS1=0x%02x STS2=0x%02x STS3=0x%02x STS4=0x%02x STS5=0x%02x, STS6=0x%02x\n",
+ sts[0], sts[1], sts[2], sts[3], sts[4], sts[5]);
+ }
+
+ return rc;
+}
+
+static struct settings lcdb_settings[] = {
+ SETTING(LCDB_BST_PD_CTL, false),
+ SETTING(LCDB_RDSON_MGMNT, false),
+ SETTING(LCDB_MISC_CTL, false),
+ SETTING(LCDB_SOFT_START_CTL, false),
+ SETTING(LCDB_PFM_CTL, false),
+ SETTING(LCDB_PWRUP_PWRDN_CTL, true),
+ SETTING(LCDB_LDO_PD_CTL, false),
+ SETTING(LCDB_LDO_SOFT_START_CTL, false),
+ SETTING(LCDB_NCP_PD_CTL, false),
+ SETTING(LCDB_NCP_SOFT_START_CTL, false),
+};
+
+static int qpnp_lcdb_save_settings(struct qpnp_lcdb *lcdb)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(lcdb_settings); i++) {
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ lcdb_settings[i].address,
+ &lcdb_settings[i].value, 1);
+ if (rc < 0) {
+ pr_err("Failed to read lcdb register address=%x\n",
+ lcdb_settings[i].address);
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+static int qpnp_lcdb_restore_settings(struct qpnp_lcdb *lcdb)
+{
+ int i, rc = 0;
+
+ for (i = 0; i < ARRAY_SIZE(lcdb_settings); i++) {
+ if (lcdb_settings[i].sec_access)
+ rc = qpnp_lcdb_secure_write(lcdb, lcdb->base +
+ lcdb_settings[i].address,
+ lcdb_settings[i].value);
+ else
+ rc = qpnp_lcdb_write(lcdb, lcdb->base +
+ lcdb_settings[i].address,
+ &lcdb_settings[i].value, 1);
+ if (rc < 0) {
+ pr_err("Failed to write register address=%x\n",
+ lcdb_settings[i].address);
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+static int qpnp_lcdb_ttw_enter(struct qpnp_lcdb *lcdb)
+{
+ int rc;
+ u8 val;
+
+ if (!lcdb->settings_saved) {
+ rc = qpnp_lcdb_save_settings(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to save LCDB settings rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->settings_saved = true;
+ }
+
+ val = BOOST_DIS_PULLDOWN_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_BST_PD_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set BST PD rc=%d\n", rc);
+ return rc;
+ }
+
+ val = (RDSON_HALF << NFET_SW_SIZE_SHIFT) | RDSON_HALF;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_RDSON_MGMNT_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set RDSON MGMT rc=%d\n", rc);
+ return rc;
+ }
+
+ val = AUTO_GM_EN_BIT | EN_TOUCH_WAKE_BIT | DIS_SCP_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_MISC_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set MISC CTL rc=%d\n", rc);
+ return rc;
+ }
+
+ val = 0;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_SOFT_START_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set LCDB_SOFT_START rc=%d\n", rc);
+ return rc;
+ }
+
+ val = EN_PFM_BIT | (PFM_HYST_25MV << PFM_HYSTERESIS_SHIFT) |
+ (PFM_PEAK_CURRENT_400MA << PFM_CURRENT_SHIFT) |
+ BYP_BST_SOFT_START_COMP_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_PFM_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set PFM_CTL rc=%d\n", rc);
+ return rc;
+ }
+
+ val = 0;
+ rc = qpnp_lcdb_secure_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG,
+ val);
+ if (rc < 0) {
+ pr_err("Failed to set PWRUP_PWRDN_CTL rc=%d\n", rc);
+ return rc;
+ }
+
+ val = LDO_DIS_PULLDOWN_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_PD_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set LDO_PD_CTL rc=%d\n", rc);
+ return rc;
+ }
+
+ val = 0;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_SOFT_START_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set LDO_SOFT_START rc=%d\n", rc);
+ return rc;
+ }
+
+ val = NCP_DIS_PULLDOWN_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_NCP_PD_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set NCP_PD_CTL rc=%d\n", rc);
+ return rc;
+ }
+
+ val = 0;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_NCP_SOFT_START_CTL_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to set NCP_SOFT_START rc=%d\n", rc);
+ return rc;
+ }
+
+ if (lcdb->ttw_mode_sw) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_AUTO_TOUCH_WAKE_CTL_REG,
+ EN_AUTO_TOUCH_WAKE_BIT,
+ EN_AUTO_TOUCH_WAKE_BIT);
+ if (rc < 0)
+ pr_err("Failed to enable auto(sw) TTW\n rc = %d\n", rc);
+ } else {
+ val = HWEN_RDY_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
+ &val, 1);
+ if (rc < 0)
+ pr_err("Failed to hw_enable lcdb rc= %d\n", rc);
+ }
+
+ return rc;
+}
+
+static int qpnp_lcdb_ttw_exit(struct qpnp_lcdb *lcdb)
+{
+ int rc;
+
+ if (lcdb->settings_saved) {
+ rc = qpnp_lcdb_restore_settings(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to restore lcdb settings rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->settings_saved = false;
+ }
+
+ return 0;
+}
+
+static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0, timeout, delay;
+ u8 val = 0;
+
+ if (lcdb->lcdb_enabled)
+ return 0;
+
+ if (lcdb->ttw_enable) {
+ rc = qpnp_lcdb_ttw_exit(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to exit TTW mode rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ val = MODULE_EN_BIT;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to enable lcdb rc= %d\n", rc);
+ goto fail_enable;
+ }
+
+ /* poll for vreg_ok */
+ timeout = 10;
+ delay = lcdb->bst.soft_start_us + lcdb->ldo.soft_start_us +
+ lcdb->ncp.soft_start_us;
+ delay += lcdb->bst.vreg_ok_dbc_us + lcdb->ldo.vreg_ok_dbc_us +
+ lcdb->ncp.vreg_ok_dbc_us;
+ while (timeout--) {
+ rc = qpnp_lcdb_read(lcdb, lcdb->base + INT_RT_STATUS_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to poll for vreg-ok status rc=%d\n", rc);
+ break;
+ }
+ if (val & VREG_OK_RT_STS_BIT)
+ break;
+
+ usleep_range(delay, delay + 100);
+ }
+
+ if (rc || !timeout) {
+ if (!timeout) {
+ pr_err("lcdb-vreg-ok status failed to change\n");
+ rc = -ETIMEDOUT;
+ }
+ goto fail_enable;
+ }
+
+ lcdb->lcdb_enabled = true;
+ pr_debug("lcdb enabled successfully!\n");
+
+ return 0;
+
+fail_enable:
+ dump_status_registers(lcdb);
+ pr_err("Failed to enable lcdb rc=%d\n", rc);
+ return rc;
+}
+
+static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ u8 val;
+
+ if (!lcdb->lcdb_enabled)
+ return 0;
+
+ if (lcdb->ttw_enable) {
+ rc = qpnp_lcdb_ttw_enter(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to enable TTW mode rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->lcdb_enabled = false;
+
+ return 0;
+ }
+
+ val = 0;
+ rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
+ &val, 1);
+ if (rc < 0)
+ pr_err("Failed to disable lcdb rc= %d\n", rc);
+ else
+ lcdb->lcdb_enabled = false;
+
+ return rc;
+}
+
+#define MIN_BST_VOLTAGE_MV 4700
+#define MAX_BST_VOLTAGE_MV 6250
+#define MIN_VOLTAGE_MV 4000
+#define MAX_VOLTAGE_MV 6000
+#define VOLTAGE_MIN_STEP_100_MV 4000
+#define VOLTAGE_MIN_STEP_50_MV 4950
+#define VOLTAGE_STEP_100_MV 100
+#define VOLTAGE_STEP_50_MV 50
+#define VOLTAGE_STEP_50MV_OFFSET 0xA
+static int qpnp_lcdb_set_bst_voltage(struct qpnp_lcdb *lcdb,
+ int voltage_mv)
+{
+ int rc = 0;
+ u8 val = 0;
+
+ if (voltage_mv < MIN_BST_VOLTAGE_MV)
+ voltage_mv = MIN_BST_VOLTAGE_MV;
+ else if (voltage_mv > MAX_BST_VOLTAGE_MV)
+ voltage_mv = MAX_BST_VOLTAGE_MV;
+
+ val = DIV_ROUND_UP(voltage_mv - MIN_BST_VOLTAGE_MV,
+ VOLTAGE_STEP_50_MV);
+
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_BST_OUTPUT_VOLTAGE_REG,
+ SET_OUTPUT_VOLTAGE_MASK, val);
+ if (rc < 0)
+ pr_err("Failed to set boost voltage %d mv rc=%d\n",
+ voltage_mv, rc);
+ else
+ pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
+ voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
+
+ return rc;
+}
+
+static int qpnp_lcdb_get_bst_voltage(struct qpnp_lcdb *lcdb,
+ int *voltage_mv)
+{
+ int rc;
+ u8 val = 0;
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_BST_OUTPUT_VOLTAGE_REG,
+ &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to reat BST voltage rc=%d\n", rc);
+ return rc;
+ }
+
+ val &= SET_OUTPUT_VOLTAGE_MASK;
+ *voltage_mv = (val * VOLTAGE_STEP_50_MV) + MIN_BST_VOLTAGE_MV;
+
+ return 0;
+}
+
+static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
+ int voltage_mv, u8 type)
+{
+ int rc = 0;
+ u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
+ u8 val = 0;
+
+ if (type == BST)
+ return qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv);
+
+ if (type == NCP)
+ offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
+
+ if (!is_between(voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV)) {
+ pr_err("Invalid voltage %dmv (min=%d max=%d)\n",
+ voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
+ return -EINVAL;
+ }
+
+ /* Change the BST voltage to LDO + 100mV */
+ if (type == LDO) {
+ rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv + 100);
+ if (rc < 0) {
+ pr_err("Failed to set boost voltage rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* Below logic is only valid for LDO and NCP type */
+ if (voltage_mv < VOLTAGE_MIN_STEP_50_MV) {
+ val = DIV_ROUND_UP(voltage_mv - VOLTAGE_MIN_STEP_100_MV,
+ VOLTAGE_STEP_100_MV);
+ } else {
+ val = DIV_ROUND_UP(voltage_mv - VOLTAGE_MIN_STEP_50_MV,
+ VOLTAGE_STEP_50_MV);
+ val += VOLTAGE_STEP_50MV_OFFSET;
+ }
+
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + offset,
+ SET_OUTPUT_VOLTAGE_MASK, val);
+ if (rc < 0)
+ pr_err("Failed to set output voltage %d mv for %s rc=%d\n",
+ voltage_mv, (type == LDO) ? "LDO" : "NCP", rc);
+ else
+ pr_debug("%s voltage set = %d mv (0x%02x = 0x%02x)\n",
+ (type == LDO) ? "LDO" : "NCP", voltage_mv, offset, val);
+
+ return rc;
+}
+
+static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb,
+ u32 *voltage_mv, u8 type)
+{
+ int rc = 0;
+ u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
+ u8 val = 0;
+
+ if (type == BST)
+ return qpnp_lcdb_get_bst_voltage(lcdb, voltage_mv);
+
+ if (type == NCP)
+ offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base + offset, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read %s volatge rc=%d\n",
+ (type == LDO) ? "LDO" : "NCP", rc);
+ return rc;
+ }
+
+ if (val < VOLTAGE_STEP_50MV_OFFSET) {
+ *voltage_mv = VOLTAGE_MIN_STEP_100_MV +
+ (val * VOLTAGE_STEP_100_MV);
+ } else {
+ *voltage_mv = VOLTAGE_MIN_STEP_50_MV +
+ ((val - VOLTAGE_STEP_50MV_OFFSET) * VOLTAGE_STEP_50_MV);
+ }
+
+ if (!rc)
+ pr_debug("%s voltage read-back = %d mv (0x%02x = 0x%02x)\n",
+ (type == LDO) ? "LDO" : "NCP",
+ *voltage_mv, offset, val);
+
+ return rc;
+}
+
+static int qpnp_lcdb_set_soft_start(struct qpnp_lcdb *lcdb,
+ u32 ss_us, u8 type)
+{
+ int rc = 0, i = 0;
+ u16 offset = LCDB_LDO_SOFT_START_CTL_REG;
+ u8 val = 0;
+
+ if (type == NCP)
+ offset = LCDB_NCP_SOFT_START_CTL_REG;
+
+ if (!is_between(ss_us, MIN_SOFT_START_US, MAX_SOFT_START_US)) {
+ pr_err("Invalid soft_start_us %d (min=%d max=%d)\n",
+ ss_us, MIN_SOFT_START_US, MAX_SOFT_START_US);
+ return -EINVAL;
+ }
+
+ i = 0;
+ while (ss_us > soft_start_us[i])
+ i++;
+ val = ((i == 0) ? 0 : i - 1) & SOFT_START_MASK;
+
+ rc = qpnp_lcdb_masked_write(lcdb,
+ lcdb->base + offset, SOFT_START_MASK, val);
+ if (rc < 0)
+ pr_err("Failed to write %s soft-start time %d rc=%d",
+ (type == LDO) ? "LDO" : "NCP", soft_start_us[i], rc);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ldo_regulator_enable(struct regulator_dev *rdev)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ mutex_lock(&lcdb->lcdb_mutex);
+ rc = qpnp_lcdb_enable(lcdb);
+ if (rc < 0)
+ pr_err("Failed to enable lcdb rc=%d\n", rc);
+ mutex_unlock(&lcdb->lcdb_mutex);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ldo_regulator_disable(struct regulator_dev *rdev)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ mutex_lock(&lcdb->lcdb_mutex);
+ rc = qpnp_lcdb_disable(lcdb);
+ if (rc < 0)
+ pr_err("Failed to disable lcdb rc=%d\n", rc);
+ mutex_unlock(&lcdb->lcdb_mutex);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ldo_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ return lcdb->lcdb_enabled;
+}
+
+static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
+ if (rc < 0)
+ pr_err("Failed to set LDO voltage rc=%c\n", rc);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ldo_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ int rc = 0;
+ u32 voltage_mv = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ rc = qpnp_lcdb_get_voltage(lcdb, &voltage_mv, LDO);
+ if (rc < 0) {
+ pr_err("Failed to get ldo voltage rc=%d\n", rc);
+ return rc;
+ }
+
+ return voltage_mv * 1000;
+}
+
+static struct regulator_ops qpnp_lcdb_ldo_ops = {
+ .enable = qpnp_lcdb_ldo_regulator_enable,
+ .disable = qpnp_lcdb_ldo_regulator_disable,
+ .is_enabled = qpnp_lcdb_ldo_regulator_is_enabled,
+ .set_voltage = qpnp_lcdb_ldo_regulator_set_voltage,
+ .get_voltage = qpnp_lcdb_ldo_regulator_get_voltage,
+};
+
+static int qpnp_lcdb_ncp_regulator_enable(struct regulator_dev *rdev)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ mutex_lock(&lcdb->lcdb_mutex);
+ rc = qpnp_lcdb_enable(lcdb);
+ if (rc < 0)
+ pr_err("Failed to enable lcdb rc=%d\n", rc);
+ mutex_unlock(&lcdb->lcdb_mutex);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ncp_regulator_disable(struct regulator_dev *rdev)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ mutex_lock(&lcdb->lcdb_mutex);
+ rc = qpnp_lcdb_disable(lcdb);
+ if (rc < 0)
+ pr_err("Failed to disable lcdb rc=%d\n", rc);
+ mutex_unlock(&lcdb->lcdb_mutex);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ncp_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ return lcdb->lcdb_enabled;
+}
+
+static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ int rc = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
+ if (rc < 0)
+ pr_err("Failed to set LDO voltage rc=%c\n", rc);
+
+ return rc;
+}
+
+static int qpnp_lcdb_ncp_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ int rc;
+ u32 voltage_mv = 0;
+ struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
+
+ rc = qpnp_lcdb_get_voltage(lcdb, &voltage_mv, NCP);
+ if (rc < 0) {
+ pr_err("Failed to get ncp voltage rc=%d\n", rc);
+ return rc;
+ }
+
+ return voltage_mv * 1000;
+}
+
+static struct regulator_ops qpnp_lcdb_ncp_ops = {
+ .enable = qpnp_lcdb_ncp_regulator_enable,
+ .disable = qpnp_lcdb_ncp_regulator_disable,
+ .is_enabled = qpnp_lcdb_ncp_regulator_is_enabled,
+ .set_voltage = qpnp_lcdb_ncp_regulator_set_voltage,
+ .get_voltage = qpnp_lcdb_ncp_regulator_get_voltage,
+};
+
+static int qpnp_lcdb_regulator_register(struct qpnp_lcdb *lcdb, u8 type)
+{
+ int rc = 0;
+ struct regulator_init_data *init_data;
+ struct regulator_config cfg = {};
+ struct regulator_desc *rdesc;
+ struct regulator_dev *rdev;
+ struct device_node *node;
+
+ if (type == LDO) {
+ node = lcdb->ldo.node;
+ rdesc = &lcdb->ldo.rdesc;
+ rdesc->ops = &qpnp_lcdb_ldo_ops;
+ rdev = lcdb->ldo.rdev;
+ } else if (type == NCP) {
+ node = lcdb->ncp.node;
+ rdesc = &lcdb->ncp.rdesc;
+ rdesc->ops = &qpnp_lcdb_ncp_ops;
+ rdev = lcdb->ncp.rdev;
+ } else {
+ pr_err("Invalid regulator type %d\n", type);
+ return -EINVAL;
+ }
+
+ init_data = of_get_regulator_init_data(lcdb->dev, node, rdesc);
+ if (!init_data) {
+ pr_err("Failed to get regulator_init_data for %s\n",
+ (type == LDO) ? "LDO" : "NCP");
+ return -ENOMEM;
+ }
+
+ if (init_data->constraints.name) {
+ rdesc->owner = THIS_MODULE;
+ rdesc->type = REGULATOR_VOLTAGE;
+ rdesc->name = init_data->constraints.name;
+
+ cfg.dev = lcdb->dev;
+ cfg.init_data = init_data;
+ cfg.driver_data = lcdb;
+ cfg.of_node = node;
+
+ if (of_get_property(lcdb->dev->of_node, "parent-supply", NULL))
+ init_data->supply_regulator = "parent";
+
+ init_data->constraints.valid_ops_mask
+ |= REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_STATUS;
+
+ rdev = devm_regulator_register(lcdb->dev, rdesc, &cfg);
+ if (IS_ERR(rdev)) {
+ rc = PTR_ERR(rdev);
+ rdev = NULL;
+ pr_err("Failed to register lcdb_%s regulator rc = %d\n",
+ (type == LDO) ? "LDO" : "NCP", rc);
+ return rc;
+ }
+ } else {
+ pr_err("%s_regulator name missing\n",
+ (type == LDO) ? "LDO" : "NCP");
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int qpnp_lcdb_parse_ttw(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ u32 temp;
+ u8 val = 0;
+ struct device_node *node = lcdb->dev->of_node;
+
+ if (of_property_read_bool(node, "qcom,ttw-mode-sw")) {
+ lcdb->ttw_mode_sw = true;
+ rc = of_property_read_u32(node, "qcom,attw-toff-ms", &temp);
+ if (!rc) {
+ if (!is_between(temp, ATTW_MIN_MS, ATTW_MAX_MS)) {
+ pr_err("Invalid TOFF val %d (min=%d max=%d)\n",
+ temp, ATTW_MIN_MS, ATTW_MAX_MS);
+ return -EINVAL;
+ }
+ val = ilog2(temp / 4) << ATTW_TOFF_TIME_SHIFT;
+ } else {
+ pr_err("qcom,attw-toff-ms not specified for TTW SW mode\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(node, "qcom,attw-ton-ms", &temp);
+ if (!rc) {
+ if (!is_between(temp, ATTW_MIN_MS, ATTW_MAX_MS)) {
+ pr_err("Invalid TON value %d (min=%d max=%d)\n",
+ temp, ATTW_MIN_MS, ATTW_MAX_MS);
+ return -EINVAL;
+ }
+ val |= ilog2(temp / 4);
+ } else {
+ pr_err("qcom,attw-ton-ms not specified for TTW SW mode\n");
+ return rc;
+ }
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_AUTO_TOUCH_WAKE_CTL_REG,
+ ATTW_TON_TIME_MASK | ATTW_TOFF_TIME_MASK, val);
+ if (rc < 0) {
+ pr_err("Failed to write ATTW ON/OFF rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static int qpnp_lcdb_ldo_dt_init(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ struct device_node *node = lcdb->ldo.node;
+
+ /* LDO output voltage */
+ lcdb->ldo.voltage_mv = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ldo-voltage-mv",
+ &lcdb->ldo.voltage_mv);
+ if (!rc && !is_between(lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV,
+ MAX_VOLTAGE_MV)) {
+ pr_err("Invalid LDO voltage %dmv (min=%d max=%d)\n",
+ lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
+ return -EINVAL;
+ }
+
+ /* LDO PD configuration */
+ lcdb->ldo.pd = -EINVAL;
+ of_property_read_u32(node, "qcom,ldo-pd", &lcdb->ldo.pd);
+
+ lcdb->ldo.pd_strength = -EINVAL;
+ of_property_read_u32(node, "qcom,ldo-pd-strength",
+ &lcdb->ldo.pd_strength);
+
+ /* LDO ILIM configuration */
+ lcdb->ldo.ilim_ma = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ldo-ilim-ma", &lcdb->ldo.ilim_ma);
+ if (!rc && !is_between(lcdb->ldo.ilim_ma, MIN_LDO_ILIM_MA,
+ MAX_LDO_ILIM_MA)) {
+ pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
+ lcdb->ldo.ilim_ma, MIN_LDO_ILIM_MA,
+ MAX_LDO_ILIM_MA);
+ return -EINVAL;
+ }
+
+ /* LDO soft-start (SS) configuration */
+ lcdb->ldo.soft_start_us = -EINVAL;
+ of_property_read_u32(node, "qcom,ldo-soft-start-us",
+ &lcdb->ldo.soft_start_us);
+
+ return 0;
+}
+
+static int qpnp_lcdb_ncp_dt_init(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ struct device_node *node = lcdb->ncp.node;
+
+ /* NCP output voltage */
+ lcdb->ncp.voltage_mv = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ncp-voltage-mv",
+ &lcdb->ncp.voltage_mv);
+ if (!rc && !is_between(lcdb->ncp.voltage_mv, MIN_VOLTAGE_MV,
+ MAX_VOLTAGE_MV)) {
+ pr_err("Invalid NCP voltage %dmv (min=%d max=%d)\n",
+ lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
+ return -EINVAL;
+ }
+
+ /* NCP PD configuration */
+ lcdb->ncp.pd = -EINVAL;
+ of_property_read_u32(node, "qcom,ncp-pd", &lcdb->ncp.pd);
+
+ lcdb->ncp.pd_strength = -EINVAL;
+ of_property_read_u32(node, "qcom,ncp-pd-strength",
+ &lcdb->ncp.pd_strength);
+
+ /* NCP ILIM configuration */
+ lcdb->ncp.ilim_ma = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,ncp-ilim-ma", &lcdb->ncp.ilim_ma);
+ if (!rc && !is_between(lcdb->ncp.ilim_ma, MIN_NCP_ILIM_MA,
+ MAX_NCP_ILIM_MA)) {
+ pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
+ lcdb->ncp.ilim_ma, MIN_NCP_ILIM_MA, MAX_NCP_ILIM_MA);
+ return -EINVAL;
+ }
+
+ /* NCP soft-start (SS) configuration */
+ lcdb->ncp.soft_start_us = -EINVAL;
+ of_property_read_u32(node, "qcom,ncp-soft-start-us",
+ &lcdb->ncp.soft_start_us);
+
+ return 0;
+}
+
+static int qpnp_lcdb_bst_dt_init(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ struct device_node *node = lcdb->bst.node;
+
+ /* Boost PD configuration */
+ lcdb->bst.pd = -EINVAL;
+ of_property_read_u32(node, "qcom,bst-pd", &lcdb->bst.pd);
+
+ lcdb->bst.pd_strength = -EINVAL;
+ of_property_read_u32(node, "qcom,bst-pd-strength",
+ &lcdb->bst.pd_strength);
+
+ /* Boost ILIM */
+ lcdb->bst.ilim_ma = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,bst-ilim-ma", &lcdb->bst.ilim_ma);
+ if (!rc && !is_between(lcdb->bst.ilim_ma, MIN_BST_ILIM_MA,
+ MAX_BST_ILIM_MA)) {
+ pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
+ lcdb->bst.ilim_ma, MIN_BST_ILIM_MA, MAX_BST_ILIM_MA);
+ return -EINVAL;
+ }
+
+ /* Boost PS configuration */
+ lcdb->bst.ps = -EINVAL;
+ of_property_read_u32(node, "qcom,bst-ps", &lcdb->bst.ps);
+
+ lcdb->bst.ps_threshold = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,bst-ps-threshold-ma",
+ &lcdb->bst.ps_threshold);
+ if (!rc && !is_between(lcdb->bst.ps_threshold,
+ MIN_BST_PS_MA, MAX_BST_PS_MA)) {
+ pr_err("Invalid bst ps_threshold %d (min=%d, max=%d)\n",
+ lcdb->bst.ps_threshold, MIN_BST_PS_MA, MAX_BST_PS_MA);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int qpnp_lcdb_init_ldo(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0, ilim_ma;
+ u8 val = 0;
+
+ /* configure parameters only if LCDB is disabled */
+ if (!is_lcdb_enabled(lcdb)) {
+ if (lcdb->ldo.voltage_mv != -EINVAL) {
+ rc = qpnp_lcdb_set_voltage(lcdb,
+ lcdb->ldo.voltage_mv, LDO);
+ if (rc < 0) {
+ pr_err("Failed to set voltage rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ldo.pd != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_LDO_PD_CTL_REG, LDO_DIS_PULLDOWN_BIT,
+ lcdb->ldo.pd ? 0 : LDO_DIS_PULLDOWN_BIT);
+ if (rc < 0) {
+ pr_err("Failed to configure LDO PD rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ldo.pd_strength != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_LDO_PD_CTL_REG, LDO_PD_STRENGTH_BIT,
+ lcdb->ldo.pd_strength ?
+ LDO_PD_STRENGTH_BIT : 0);
+ if (rc < 0) {
+ pr_err("Failed to configure LDO PD strength %s rc=%d",
+ lcdb->ldo.pd_strength ?
+ "(strong)" : "(weak)", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ldo.ilim_ma != -EINVAL) {
+ ilim_ma = lcdb->ldo.ilim_ma - MIN_LDO_ILIM_MA;
+ ilim_ma /= LDO_ILIM_STEP_MA;
+ val = (ilim_ma & SET_LDO_ILIM_MASK) | EN_LDO_ILIM_BIT;
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_LDO_ILIM_CTL1_REG,
+ SET_LDO_ILIM_MASK | EN_LDO_ILIM_BIT,
+ val);
+ if (rc < 0) {
+ pr_err("Failed to configure LDO ilim_ma (CTL1=%d) rc=%d",
+ val, rc);
+ return rc;
+ }
+
+ val = ilim_ma & SET_LDO_ILIM_MASK;
+ rc = qpnp_lcdb_masked_write(lcdb,
+ lcdb->base + LCDB_LDO_ILIM_CTL2_REG,
+ SET_LDO_ILIM_MASK, val);
+ if (rc < 0) {
+ pr_err("Failed to configure LDO ilim_ma (CTL2=%d) rc=%d",
+ val, rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ldo.soft_start_us != -EINVAL) {
+ rc = qpnp_lcdb_set_soft_start(lcdb,
+ lcdb->ldo.soft_start_us, LDO);
+ if (rc < 0) {
+ pr_err("Failed to set LDO soft_start rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+ }
+
+ rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->ldo.voltage_mv, LDO);
+ if (rc < 0) {
+ pr_err("Failed to get LDO volatge rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_LDO_VREG_OK_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read ldo_vreg_ok rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->ldo.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_LDO_SOFT_START_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read ldo_soft_start_ctl rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->ldo.soft_start_us = soft_start_us[val & SOFT_START_MASK];
+
+ rc = qpnp_lcdb_regulator_register(lcdb, LDO);
+ if (rc < 0)
+ pr_err("Failed to register ldo rc=%d\n", rc);
+
+ return rc;
+}
+
+static int qpnp_lcdb_init_ncp(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0, i = 0;
+ u8 val = 0;
+
+ /* configure parameters only if LCDB is disabled */
+ if (!is_lcdb_enabled(lcdb)) {
+ if (lcdb->ncp.voltage_mv != -EINVAL) {
+ rc = qpnp_lcdb_set_voltage(lcdb,
+ lcdb->ncp.voltage_mv, NCP);
+ if (rc < 0) {
+ pr_err("Failed to set voltage rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ncp.pd != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_NCP_PD_CTL_REG, NCP_DIS_PULLDOWN_BIT,
+ lcdb->ncp.pd ? 0 : NCP_DIS_PULLDOWN_BIT);
+ if (rc < 0) {
+ pr_err("Failed to configure NCP PD rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ncp.pd_strength != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_NCP_PD_CTL_REG, NCP_PD_STRENGTH_BIT,
+ lcdb->ncp.pd_strength ?
+ NCP_PD_STRENGTH_BIT : 0);
+ if (rc < 0) {
+ pr_err("Failed to configure NCP PD strength %s rc=%d",
+ lcdb->ncp.pd_strength ?
+ "(strong)" : "(weak)", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ncp.ilim_ma != -EINVAL) {
+ while (lcdb->ncp.ilim_ma > ncp_ilim_ma[i])
+ i++;
+ val = (i == 0) ? 0 : i - 1;
+ val = (lcdb->ncp.ilim_ma & SET_NCP_ILIM_MASK) |
+ EN_NCP_ILIM_BIT;
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_NCP_ILIM_CTL1_REG,
+ SET_NCP_ILIM_MASK | EN_NCP_ILIM_BIT, val);
+ if (rc < 0) {
+ pr_err("Failed to configure NCP ilim_ma (CTL1=%d) rc=%d",
+ val, rc);
+ return rc;
+ }
+ val = lcdb->ncp.ilim_ma & SET_NCP_ILIM_MASK;
+ rc = qpnp_lcdb_masked_write(lcdb,
+ lcdb->base + LCDB_NCP_ILIM_CTL2_REG,
+ SET_NCP_ILIM_MASK, val);
+ if (rc < 0) {
+ pr_err("Failed to configure NCP ilim_ma (CTL2=%d) rc=%d",
+ val, rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->ncp.soft_start_us != -EINVAL) {
+ rc = qpnp_lcdb_set_soft_start(lcdb,
+ lcdb->ncp.soft_start_us, NCP);
+ if (rc < 0) {
+ pr_err("Failed to set NCP soft_start rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+ }
+
+ rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->ncp.voltage_mv, NCP);
+ if (rc < 0) {
+ pr_err("Failed to get NCP volatge rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_NCP_VREG_OK_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read ncp_vreg_ok rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->ncp.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_NCP_SOFT_START_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read ncp_soft_start_ctl rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->ncp.soft_start_us = soft_start_us[val & SOFT_START_MASK];
+
+ rc = qpnp_lcdb_regulator_register(lcdb, NCP);
+ if (rc < 0)
+ pr_err("Failed to register NCP rc=%d\n", rc);
+
+ return rc;
+}
+
+static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ u8 val = 0;
+
+ /* configure parameters only if LCDB is disabled */
+ if (!is_lcdb_enabled(lcdb)) {
+ if (lcdb->bst.pd != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_BST_PD_CTL_REG, BOOST_DIS_PULLDOWN_BIT,
+ lcdb->bst.pd ? 0 : BOOST_DIS_PULLDOWN_BIT);
+ if (rc < 0) {
+ pr_err("Failed to configure BST PD rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->bst.pd_strength != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_NCP_PD_CTL_REG, BOOST_PD_STRENGTH_BIT,
+ lcdb->bst.pd_strength ?
+ BOOST_PD_STRENGTH_BIT : 0);
+ if (rc < 0) {
+ pr_err("Failed to configure NCP PD strength %s rc=%d",
+ lcdb->bst.pd_strength ?
+ "(strong)" : "(weak)", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->bst.ilim_ma != -EINVAL) {
+ val = (lcdb->bst.ilim_ma / MIN_BST_ILIM_MA) - 1;
+ val = (lcdb->bst.ilim_ma & SET_BST_ILIM_MASK) |
+ EN_BST_ILIM_BIT;
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_BST_ILIM_CTL_REG,
+ SET_BST_ILIM_MASK | EN_BST_ILIM_BIT, val);
+ if (rc < 0) {
+ pr_err("Failed to configure BST ilim_ma rc=%d",
+ rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->bst.ps != -EINVAL) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_PS_CTL_REG, EN_PS_BIT,
+ &lcdb->bst.ps ? EN_PS_BIT : 0);
+ if (rc < 0) {
+ pr_err("Failed to disable BST PS rc=%d", rc);
+ return rc;
+ }
+ }
+
+ if (lcdb->bst.ps_threshold != -EINVAL) {
+ val = (lcdb->bst.ps_threshold - MIN_BST_PS_MA) / 10;
+ val = (lcdb->bst.ps_threshold & PS_THRESHOLD_MASK) |
+ EN_PS_BIT;
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_PS_CTL_REG,
+ PS_THRESHOLD_MASK | EN_PS_BIT,
+ val);
+ if (rc < 0) {
+ pr_err("Failed to configure BST PS threshold rc=%d",
+ rc);
+ return rc;
+ }
+ }
+ }
+
+ rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->bst.voltage_mv, BST);
+ if (rc < 0) {
+ pr_err("Failed to get BST volatge rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_BST_VREG_OK_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read bst_vreg_ok rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->bst.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
+
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_SOFT_START_CTL_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read ncp_soft_start_ctl rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->bst.soft_start_us = (val & SOFT_START_MASK) * 200 + 200;
+
+ return 0;
+}
+
+static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ u8 val = 0;
+
+ rc = qpnp_lcdb_init_bst(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to initialize BOOST rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_init_ldo(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to initialize LDO rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_init_ncp(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to initialize NCP rc=%d\n", rc);
+ return rc;
+ }
+
+ if (!is_lcdb_enabled(lcdb)) {
+ rc = qpnp_lcdb_read(lcdb, lcdb->base +
+ LCDB_MODULE_RDY_REG, &val, 1);
+ if (rc < 0) {
+ pr_err("Failed to read MODULE_RDY rc=%d\n", rc);
+ return rc;
+ }
+ if (!(val & MODULE_RDY_BIT)) {
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_MODULE_RDY_REG, MODULE_RDY_BIT,
+ MODULE_RDY_BIT);
+ if (rc < 0) {
+ pr_err("Failed to set MODULE RDY rc=%d\n", rc);
+ return rc;
+ }
+ }
+ } else {
+ /* module already enabled */
+ lcdb->lcdb_enabled = true;
+ }
+
+ return 0;
+}
+
+static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
+{
+ int rc = 0;
+ const char *label;
+ struct device_node *temp, *node = lcdb->dev->of_node;
+
+ for_each_available_child_of_node(node, temp) {
+ rc = of_property_read_string(temp, "label", &label);
+ if (rc < 0) {
+ pr_err("Failed to read label rc=%d\n", rc);
+ return rc;
+ }
+
+ if (!strcmp(label, "ldo")) {
+ lcdb->ldo.node = temp;
+ rc = qpnp_lcdb_ldo_dt_init(lcdb);
+ } else if (!strcmp(label, "ncp")) {
+ lcdb->ncp.node = temp;
+ rc = qpnp_lcdb_ncp_dt_init(lcdb);
+ } else if (!strcmp(label, "bst")) {
+ lcdb->bst.node = temp;
+ rc = qpnp_lcdb_bst_dt_init(lcdb);
+ } else {
+ pr_err("Failed to identify label %s\n", label);
+ return -EINVAL;
+ }
+ if (rc < 0) {
+ pr_err("Failed to register %s module\n", label);
+ return rc;
+ }
+ }
+
+ if (of_property_read_bool(node, "qcom,ttw-enable")) {
+ rc = qpnp_lcdb_parse_ttw(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to parse ttw-params rc=%d\n", rc);
+ return rc;
+ }
+ lcdb->ttw_enable = true;
+ }
+
+ return rc;
+}
+
+static int qpnp_lcdb_regulator_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct device_node *node;
+ struct qpnp_lcdb *lcdb;
+
+ node = pdev->dev.of_node;
+ if (!node) {
+ pr_err("No nodes defined\n");
+ return -ENODEV;
+ }
+
+ lcdb = devm_kzalloc(&pdev->dev, sizeof(*lcdb), GFP_KERNEL);
+ if (!lcdb)
+ return -ENOMEM;
+
+ rc = of_property_read_u32(node, "reg", &lcdb->base);
+ if (rc < 0) {
+ pr_err("Failed to find reg node rc=%d\n", rc);
+ return rc;
+ }
+
+ lcdb->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!lcdb->regmap) {
+ pr_err("Failed to get the regmap handle rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ lcdb->dev = &pdev->dev;
+ lcdb->pdev = pdev;
+ mutex_init(&lcdb->lcdb_mutex);
+ mutex_init(&lcdb->read_write_mutex);
+
+ rc = qpnp_lcdb_parse_dt(lcdb);
+ if (rc < 0) {
+ pr_err("Failed to parse dt rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_lcdb_hw_init(lcdb);
+ if (rc < 0)
+ pr_err("Failed to initialize LCDB module rc=%d\n", rc);
+ else
+ pr_info("LCDB module successfully registered! lcdb_en=%d ldo_voltage=%dmV ncp_voltage=%dmV bst_voltage=%dmV\n",
+ lcdb->lcdb_enabled, lcdb->ldo.voltage_mv,
+ lcdb->ncp.voltage_mv, lcdb->bst.voltage_mv);
+
+ return rc;
+}
+
+static int qpnp_lcdb_regulator_remove(struct platform_device *pdev)
+{
+ struct qpnp_lcdb *lcdb = dev_get_drvdata(&pdev->dev);
+
+ mutex_destroy(&lcdb->lcdb_mutex);
+ mutex_destroy(&lcdb->read_write_mutex);
+
+ return 0;
+}
+
+static const struct of_device_id lcdb_match_table[] = {
+ { .compatible = QPNP_LCDB_REGULATOR_DRIVER_NAME, },
+ { },
+};
+
+static struct platform_driver qpnp_lcdb_regulator_driver = {
+ .driver = {
+ .name = QPNP_LCDB_REGULATOR_DRIVER_NAME,
+ .of_match_table = lcdb_match_table,
+ },
+ .probe = qpnp_lcdb_regulator_probe,
+ .remove = qpnp_lcdb_regulator_remove,
+};
+
+static int __init qpnp_lcdb_regulator_init(void)
+{
+ return platform_driver_register(&qpnp_lcdb_regulator_driver);
+}
+arch_initcall(qpnp_lcdb_regulator_init);
+
+static void __exit qpnp_lcdb_regulator_exit(void)
+{
+ platform_driver_unregister(&qpnp_lcdb_regulator_driver);
+}
+module_exit(qpnp_lcdb_regulator_exit);
+
+MODULE_DESCRIPTION("QPNP LCDB regulator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 06defae6d5ba..2c86606ecd2e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2697,10 +2697,9 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id)
* Lock is predominantly held by shutdown context thus, ensuring
* that no requests from any other context may sneak through.
*/
-static void ufshcd_get_write_lock(struct ufs_hba *hba)
+static inline void ufshcd_get_write_lock(struct ufs_hba *hba)
{
down_write(&hba->lock);
- hba->issuing_task = current;
}
/**
@@ -2710,18 +2709,19 @@ static void ufshcd_get_write_lock(struct ufs_hba *hba)
*
* Returns 1 if acquired, < 0 on contention
*
- * After shutdown's initiated, allow requests only from shutdown
- * context. The sync between scaling & issue is maintained
+ * After shutdown's initiated, allow requests only directed to the
+ * well known device lun. The sync between scaling & issue is maintained
* as is and this restructuring syncs shutdown with these too.
*/
-static int ufshcd_get_read_lock(struct ufs_hba *hba)
+static int ufshcd_get_read_lock(struct ufs_hba *hba, u64 lun)
{
int err = 0;
err = down_read_trylock(&hba->lock);
if (err > 0)
goto out;
- if (hba->issuing_task == current)
+ /* let requests for well known device lun to go through */
+ if (ufshcd_scsi_to_upiu_lun(lun) == UFS_UPIU_UFS_DEVICE_WLUN)
return 0;
else if (!ufshcd_is_shutdown_ongoing(hba))
return -EAGAIN;
@@ -2729,7 +2729,6 @@ static int ufshcd_get_read_lock(struct ufs_hba *hba)
return -EPERM;
out:
- hba->issuing_task = current;
return err;
}
@@ -2742,10 +2741,7 @@ out:
*/
static inline void ufshcd_put_read_lock(struct ufs_hba *hba)
{
- if (!ufshcd_is_shutdown_ongoing(hba)) {
- hba->issuing_task = NULL;
- up_read(&hba->lock);
- }
+ up_read(&hba->lock);
}
/**
@@ -2762,6 +2758,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
unsigned long flags;
int tag;
int err = 0;
+ bool has_read_lock = false;
hba = shost_priv(host);
@@ -2773,7 +2770,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
BUG();
}
- err = ufshcd_get_read_lock(hba);
+ err = ufshcd_get_read_lock(hba, cmd->device->lun);
if (unlikely(err < 0)) {
if (err == -EPERM) {
set_host_byte(cmd, DID_ERROR);
@@ -2782,6 +2779,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
}
if (err == -EAGAIN)
return SCSI_MLQUEUE_HOST_BUSY;
+ } else if (err == 1) {
+ has_read_lock = true;
}
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -2922,7 +2921,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
out_unlock:
spin_unlock_irqrestore(hba->host->host_lock, flags);
out:
- ufshcd_put_read_lock(hba);
+ if (has_read_lock)
+ ufshcd_put_read_lock(hba);
return err;
}
@@ -8808,13 +8808,13 @@ int ufshcd_shutdown(struct ufs_hba *hba)
pm_runtime_get_sync(hba->dev);
ufshcd_hold_all(hba);
/**
- * (1) Acquire the lock to stop any more requests
- * (2) Set state to shutting down
+ * (1) Set state to shutting down
+ * (2) Acquire the lock to stop any more requests
* (3) Suspend clock scaling
* (4) Wait for all issued requests to complete
*/
- ufshcd_get_write_lock(hba);
ufshcd_mark_shutdown_ongoing(hba);
+ ufshcd_get_write_lock(hba);
ufshcd_scsi_block_requests(hba);
ufshcd_suspend_clkscaling(hba);
ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c5eb21d8a0fe..81eab2cbb6cb 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -897,7 +897,6 @@ struct ufs_hba {
/* sync b/w diff contexts */
struct rw_semaphore lock;
- struct task_struct *issuing_task;
unsigned long shutdown_in_prog;
struct reset_control *core_reset;
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/icnss.c b/drivers/soc/qcom/icnss.c
index 37204dcbc065..7067c5733773 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -3557,18 +3557,16 @@ unsigned int icnss_socinfo_get_serial_number(struct device *dev)
}
EXPORT_SYMBOL(icnss_socinfo_get_serial_number);
-int icnss_set_wlan_mac_address(struct device *dev,
- const u8 *in, uint32_t len)
+int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len)
{
- struct icnss_priv *priv = dev_get_drvdata(dev);
+ struct icnss_priv *priv = penv;
uint32_t no_of_mac_addr;
struct icnss_wlan_mac_addr *addr = NULL;
int iter;
u8 *temp = NULL;
- if (priv->magic != ICNSS_MAGIC) {
- icnss_pr_err("Invalid drvdata: dev %p, data %p, magic 0x%x\n",
- dev, priv, priv->magic);
+ if (!priv) {
+ icnss_pr_err("Priv data is NULL\n");
return -EINVAL;
}
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/msm_bus/msm_bus_fabric_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c
index fdb84b634254..06657a666f2e 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c
@@ -515,12 +515,12 @@ static int msm_bus_disable_node_qos_clk(struct msm_bus_node_device_type *node)
goto exit_disable_node_qos_clk;
}
- for (i = 0; i < node->num_node_qos_clks; i++)
+ for (i = node->num_node_qos_clks - 1; i >= 0; i--)
ret = disable_nodeclk(&node->node_qos_clks[i]);
bus_node = to_msm_bus_node(node->node_info->bus_device);
- for (i = 0; i < bus_node->num_node_qos_clks; i++)
+ for (i = bus_node->num_node_qos_clks - 1; i >= 0; i--)
ret = disable_nodeclk(&bus_node->node_qos_clks[i]);
exit_disable_node_qos_clk:
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index 26bb88c29565..f966d8c11f6e 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..dc803bdfd554 100644
--- a/drivers/soc/qcom/pil-q6v5-mss.c
+++ b/drivers/soc/qcom/pil-q6v5-mss.c
@@ -270,10 +270,26 @@ 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,
"restart_reg_sec");
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get resource for restart reg\n");
+ return -EINVAL;
+ }
+
q6->restart_reg_sec = true;
}
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/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c
index 0c5f3b84162b..fcdcf0b6953e 100644
--- a/drivers/soc/qcom/spcom.c
+++ b/drivers/soc/qcom/spcom.c
@@ -1333,6 +1333,16 @@ static int spcom_handle_send_command(struct spcom_channel *ch,
pr_debug("send req/resp ch [%s] size [%d] .\n", ch->name, size);
+ /*
+ * check that cmd buf size is at least struct size,
+ * to allow access to struct fields.
+ */
+ if (size < sizeof(*cmd)) {
+ pr_err("ch [%s] invalid cmd buf.\n",
+ ch->name);
+ return -EINVAL;
+ }
+
/* Check if remote side connect */
if (!spcom_is_channel_connected(ch)) {
pr_err("ch [%s] remote side not connect.\n", ch->name);
@@ -1344,6 +1354,18 @@ static int spcom_handle_send_command(struct spcom_channel *ch,
buf_size = cmd->buf_size;
timeout_msec = cmd->timeout_msec;
+ /* Check param validity */
+ if (buf_size > SPCOM_MAX_RESPONSE_SIZE) {
+ pr_err("ch [%s] invalid buf size [%d].\n",
+ ch->name, buf_size);
+ return -EINVAL;
+ }
+ if (size != sizeof(*cmd) + buf_size) {
+ pr_err("ch [%s] invalid cmd size [%d].\n",
+ ch->name, size);
+ return -EINVAL;
+ }
+
/* Allocate Buffers*/
tx_buf_size = sizeof(*hdr) + buf_size;
tx_buf = kzalloc(tx_buf_size, GFP_KERNEL);
@@ -1407,6 +1429,11 @@ static int modify_ion_addr(void *buf,
return -ENODEV;
}
+ if (buf_size < sizeof(uint64_t)) {
+ pr_err("buf size too small [%d].\n", buf_size);
+ return -ENODEV;
+ }
+
if (buf_offset > buf_size - sizeof(uint64_t)) {
pr_err("invalid buf_offset [%d].\n", buf_offset);
return -ENODEV;
@@ -1469,6 +1496,16 @@ static int spcom_handle_send_modified_command(struct spcom_channel *ch,
pr_debug("send req/resp ch [%s] size [%d] .\n", ch->name, size);
+ /*
+ * check that cmd buf size is at least struct size,
+ * to allow access to struct fields.
+ */
+ if (size < sizeof(*cmd)) {
+ pr_err("ch [%s] invalid cmd buf.\n",
+ ch->name);
+ return -EINVAL;
+ }
+
/* Check if remote side connect */
if (!spcom_is_channel_connected(ch)) {
pr_err("ch [%s] remote side not connect.\n", ch->name);
@@ -1481,6 +1518,18 @@ static int spcom_handle_send_modified_command(struct spcom_channel *ch,
timeout_msec = cmd->timeout_msec;
memcpy(ion_info, cmd->ion_info, sizeof(ion_info));
+ /* Check param validity */
+ if (buf_size > SPCOM_MAX_RESPONSE_SIZE) {
+ pr_err("ch [%s] invalid buf size [%d].\n",
+ ch->name, buf_size);
+ return -EINVAL;
+ }
+ if (size != sizeof(*cmd) + buf_size) {
+ pr_err("ch [%s] invalid cmd size [%d].\n",
+ ch->name, size);
+ return -EINVAL;
+ }
+
/* Allocate Buffers*/
tx_buf_size = sizeof(*hdr) + buf_size;
tx_buf = kzalloc(tx_buf_size, GFP_KERNEL);
@@ -1539,13 +1588,18 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch,
struct ion_handle *ion_handle;
int i;
+ if (size != sizeof(*cmd)) {
+ pr_err("cmd size [%d] , expected [%d].\n",
+ (int) size, (int) sizeof(*cmd));
+ return -EINVAL;
+ }
+
/* Check ION client */
if (spcom_dev->ion_client == NULL) {
pr_err("invalid ion client.\n");
return -ENODEV;
}
-
/* Get ION handle from fd - this increments the ref count */
ion_handle = ion_import_dma_buf(spcom_dev->ion_client, fd);
if (ion_handle == NULL) {
@@ -1591,6 +1645,12 @@ static int spcom_handle_unlock_ion_buf_command(struct spcom_channel *ch,
struct ion_client *ion_client = spcom_dev->ion_client;
int i;
+ if (size != sizeof(*cmd)) {
+ pr_err("cmd size [%d] , expected [%d].\n",
+ (int) size, (int) sizeof(*cmd));
+ return -EINVAL;
+ }
+
/* Check ION client */
if (ion_client == NULL) {
pr_err("fail to create ion client.\n");
@@ -1746,6 +1806,13 @@ static int spcom_handle_read_req_resp(struct spcom_channel *ch,
return -ENOTCONN;
}
+ /* Check param validity */
+ if (size > SPCOM_MAX_RESPONSE_SIZE) {
+ pr_err("ch [%s] inavlid size [%d].\n",
+ ch->name, size);
+ return -EINVAL;
+ }
+
/* Allocate Buffers*/
rx_buf_size = sizeof(*hdr) + size;
rx_buf = kzalloc(rx_buf_size, GFP_KERNEL);
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index 1fa731776926..e70a56e7ce2e 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -911,7 +911,7 @@ static irqreturn_t subsys_stop_ack_intr_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void check_pbl_done(struct pil_tz_data *d)
+static void clear_pbl_done(struct pil_tz_data *d)
{
uint32_t err_value;
@@ -938,17 +938,18 @@ static void check_pbl_done(struct pil_tz_data *d)
__raw_writel(BIT(d->bits_arr[PBL_DONE]), d->irq_clear);
}
-static void check_err_ready(struct pil_tz_data *d)
+static void clear_err_ready(struct pil_tz_data *d)
{
- uint32_t err_value;
-
- err_value = __raw_readl(d->err_status_spare);
- if (!err_value) {
- pr_debug("Subsystem error services up received from %s!\n",
+ pr_debug("Subsystem error services up received from %s!\n",
d->subsys_desc.name);
- __raw_writel(BIT(d->bits_arr[ERR_READY]), d->irq_clear);
- complete_err_ready(d->subsys);
- } else if (err_value == 0x44554d50) {
+ __raw_writel(BIT(d->bits_arr[ERR_READY]), d->irq_clear);
+ complete_err_ready(d->subsys);
+}
+
+static void clear_wdog(struct pil_tz_data *d)
+{
+ /* Check crash status to know if device is restarting*/
+ if (!subsys_get_crash_status(d->subsys)) {
pr_err("wdog bite received from %s!\n", d->subsys_desc.name);
__raw_writel(BIT(d->bits_arr[ERR_READY]), d->irq_clear);
subsys_set_crash_status(d->subsys, true);
@@ -960,17 +961,21 @@ static void check_err_ready(struct pil_tz_data *d)
static irqreturn_t subsys_generic_handler(int irq, void *dev_id)
{
struct pil_tz_data *d = subsys_to_data(dev_id);
- uint32_t status_val;
-
- if (subsys_get_crash_status(d->subsys))
- return IRQ_HANDLED;
+ uint32_t status_val, err_value;
+ err_value = __raw_readl(d->err_status_spare);
status_val = __raw_readl(d->irq_status);
- if (status_val & BIT(d->bits_arr[ERR_READY]))
- check_err_ready(d);
- else if (status_val & BIT(d->bits_arr[PBL_DONE]))
- check_pbl_done(d);
+ if ((status_val & BIT(d->bits_arr[ERR_READY])) && !err_value)
+ clear_err_ready(d);
+
+ if ((status_val & BIT(d->bits_arr[ERR_READY])) &&
+ err_value == 0x44554d50)
+ clear_wdog(d);
+
+ if (status_val & BIT(d->bits_arr[PBL_DONE]))
+ clear_pbl_done(d);
+
return IRQ_HANDLED;
}
diff --git a/drivers/soc/qcom/wcd-dsp-glink.c b/drivers/soc/qcom/wcd-dsp-glink.c
index 6bc815862541..27e66dc5d204 100644
--- a/drivers/soc/qcom/wcd-dsp-glink.c
+++ b/drivers/soc/qcom/wcd-dsp-glink.c
@@ -185,6 +185,24 @@ static void wdsp_glink_notify_tx_done(void *handle, const void *priv,
}
/*
+ * wdsp_glink_notify_tx_abort - Glink notify tx abort callback to
+ * free tx buffer
+ * handle: Opaque Channel handle returned by GLink
+ * priv: Private pointer to the channel
+ * pkt_priv: Private pointer to the packet
+ */
+static void wdsp_glink_notify_tx_abort(void *handle, const void *priv,
+ const void *pkt_priv)
+{
+ if (!pkt_priv) {
+ pr_err("%s: Invalid parameter\n", __func__);
+ return;
+ }
+ /* Free tx pkt */
+ kfree(pkt_priv);
+}
+
+/*
* wdsp_glink_notify_rx_intent_req - Glink notify rx intent request callback
* to queue buffer to receive from remote client
* handle: Opaque channel handle returned by GLink
@@ -318,9 +336,6 @@ static void wdsp_glink_notify_state(void *handle, const void *priv,
if (ch->free_mem) {
kfree(ch);
ch = NULL;
- } else {
- /* Open the glink channel again */
- queue_work(wpriv->work_queue, &ch->lcl_ch_open_wrk);
}
} else if (event == GLINK_REMOTE_DISCONNECTED) {
dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n",
@@ -382,6 +397,7 @@ static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch)
open_cfg.edge = WDSP_EDGE;
open_cfg.notify_rx = wdsp_glink_notify_rx;
open_cfg.notify_tx_done = wdsp_glink_notify_tx_done;
+ open_cfg.notify_tx_abort = wdsp_glink_notify_tx_abort;
open_cfg.notify_state = wdsp_glink_notify_state;
open_cfg.notify_rx_intent_req = wdsp_glink_notify_rx_intent_req;
open_cfg.priv = ch;
@@ -607,6 +623,7 @@ static void wdsp_glink_tx_buf_work(struct work_struct *work)
mutex_lock(&tx_buf->ch->mutex);
if (ch->channel_state == GLINK_CONNECTED) {
+ mutex_unlock(&tx_buf->ch->mutex);
ret = glink_tx(ch->handle, tx_buf,
cpkt->payload, cpkt->payload_size,
GLINK_TX_REQ_INTENT);
@@ -621,6 +638,7 @@ static void wdsp_glink_tx_buf_work(struct work_struct *work)
kfree(tx_buf);
}
} else {
+ mutex_unlock(&tx_buf->ch->mutex);
dev_err(wpriv->dev, "%s: channel %s is not in connected state\n",
__func__, ch->ch_cfg.name);
/*
@@ -629,7 +647,6 @@ static void wdsp_glink_tx_buf_work(struct work_struct *work)
*/
kfree(tx_buf);
}
- mutex_unlock(&tx_buf->ch->mutex);
}
/*
diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c
index 3758e39a1c02..ac1da854ab32 100644
--- a/drivers/thermal/msm_lmh_dcvs.c
+++ b/drivers/thermal/msm_lmh_dcvs.c
@@ -25,6 +25,8 @@
#include <linux/timer.h>
#include <linux/pm_opp.h>
#include <linux/cpu_cooling.h>
+#include <linux/bitmap.h>
+#include <linux/msm_thermal.h>
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
@@ -83,6 +85,7 @@ struct msm_lmh_dcvs_hw {
uint32_t max_freq;
uint32_t hw_freq_limit;
struct list_head list;
+ DECLARE_BITMAP(is_irq_enabled, 1);
};
LIST_HEAD(lmh_dcvs_hw_list);
@@ -145,6 +148,7 @@ static void msm_lmh_dcvs_poll(unsigned long data)
if (max_limit >= hw->max_freq) {
del_timer(&hw->poll_timer);
writel_relaxed(0xFF, hw->int_clr_reg);
+ set_bit(1, hw->is_irq_enabled);
enable_irq(hw->irq_num);
} else {
mod_timer(&hw->poll_timer, jiffies + msecs_to_jiffies(
@@ -152,15 +156,21 @@ static void msm_lmh_dcvs_poll(unsigned long data)
}
}
+static void lmh_dcvs_notify(struct msm_lmh_dcvs_hw *hw)
+{
+ if (test_and_clear_bit(1, hw->is_irq_enabled)) {
+ disable_irq_nosync(hw->irq_num);
+ msm_lmh_mitigation_notify(hw);
+ mod_timer(&hw->poll_timer, jiffies + msecs_to_jiffies(
+ MSM_LIMITS_POLLING_DELAY_MS));
+ }
+}
+
static irqreturn_t lmh_dcvs_handle_isr(int irq, void *data)
{
struct msm_lmh_dcvs_hw *hw = data;
- disable_irq_nosync(irq);
- msm_lmh_mitigation_notify(hw);
- mod_timer(&hw->poll_timer, jiffies + msecs_to_jiffies(
- MSM_LIMITS_POLLING_DELAY_MS));
-
+ lmh_dcvs_notify(hw);
return IRQ_HANDLED;
}
@@ -314,6 +324,17 @@ static struct cpu_cooling_ops cd_ops = {
.ceil_limit = lmh_set_max_limit,
};
+int msm_lmh_dcvsh_sw_notify(int cpu)
+{
+ struct msm_lmh_dcvs_hw *hw = get_dcvsh_hw_from_cpu(cpu);
+
+ if (!hw)
+ return -EINVAL;
+
+ lmh_dcvs_notify(hw);
+ return 0;
+}
+
static int msm_lmh_dcvs_probe(struct platform_device *pdev)
{
int ret;
@@ -460,6 +481,7 @@ static int msm_lmh_dcvs_probe(struct platform_device *pdev)
pr_err("Error getting IRQ number. err:%d\n", ret);
return ret;
}
+ set_bit(1, hw->is_irq_enabled);
ret = devm_request_threaded_irq(&pdev->dev, hw->irq_num, NULL,
lmh_dcvs_handle_isr, IRQF_TRIGGER_HIGH | IRQF_ONESHOT
| IRQF_NO_SUSPEND, sensor_name, hw);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 002cafb08f37..7158fb1239df 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1056,6 +1056,11 @@ static int msm_lmh_dcvs_update(int cpu)
MSM_LIMITS_DOMAIN_MIN, min_freq);
if (ret)
return ret;
+ /*
+ * Notify LMH dcvs driver about the new software limit. This will
+ * trigger LMH DCVS driver polling for the mitigated frequency.
+ */
+ msm_lmh_dcvsh_sw_notify(cpu);
return ret;
}
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index e03d3b41c25b..2b49608756a0 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -212,29 +212,38 @@ static DEFINE_MUTEX(sensor_list_lock);
static struct sensor_info *get_sensor(uint32_t sensor_id)
{
- struct sensor_info *pos, *var;
+ struct sensor_info *pos = NULL, *matching_sensor = NULL;
- list_for_each_entry_safe(pos, var, &sensor_info_list, sensor_list) {
- if (pos->sensor_id == sensor_id)
- return pos;
+ rcu_read_lock();
+ list_for_each_entry_rcu(pos, &sensor_info_list, sensor_list) {
+ if (pos->sensor_id == sensor_id) {
+ matching_sensor = pos;
+ break;
+ }
}
+ rcu_read_unlock();
- return NULL;
+ return matching_sensor;
}
int sensor_get_id(char *name)
{
- struct sensor_info *pos, *var;
+ struct sensor_info *pos = NULL;
+ int matching_id = -ENODEV;
if (!name)
- return -ENODEV;
+ return matching_id;
- list_for_each_entry_safe(pos, var, &sensor_info_list, sensor_list) {
- if (!strcmp(pos->tz->type, name))
- return pos->sensor_id;
+ rcu_read_lock();
+ list_for_each_entry_rcu(pos, &sensor_info_list, sensor_list) {
+ if (!strcmp(pos->tz->type, name)) {
+ matching_id = pos->sensor_id;
+ break;
+ }
}
+ rcu_read_unlock();
- return -ENODEV;
+ return matching_id;
}
EXPORT_SYMBOL(sensor_get_id);
@@ -572,7 +581,7 @@ int sensor_init(struct thermal_zone_device *tz)
sensor->max_idx = -1;
sensor->min_idx = -1;
mutex_init(&sensor->lock);
- INIT_LIST_HEAD(&sensor->sensor_list);
+ INIT_LIST_HEAD_RCU(&sensor->sensor_list);
INIT_LIST_HEAD_RCU(&sensor->threshold_list);
INIT_LIST_HEAD(&tz->tz_threshold[0].list);
INIT_LIST_HEAD(&tz->tz_threshold[1].list);
@@ -582,7 +591,7 @@ int sensor_init(struct thermal_zone_device *tz)
tz->tz_threshold[1].notify = tz_notify_trip;
tz->tz_threshold[1].data = tz;
tz->tz_threshold[1].trip = THERMAL_TRIP_CONFIGURABLE_LOW;
- list_add(&sensor->sensor_list, &sensor_info_list);
+ list_add_rcu(&sensor->sensor_list, &sensor_info_list);
INIT_WORK(&sensor->work, sensor_update_work);
init_completion(&sensor->sysfs_notify_complete);
sensor->sysfs_notify_thread = kthread_run(sensor_sysfs_notify,
@@ -2378,7 +2387,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
}
mutex_lock(&thermal_list_lock);
- list_add_tail(&tz->node, &thermal_tz_list);
+ list_add_tail_rcu(&tz->node, &thermal_tz_list);
sensor_init(tz);
mutex_unlock(&thermal_list_lock);
@@ -2426,7 +2435,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
mutex_unlock(&thermal_list_lock);
return;
}
- list_del(&tz->node);
+ list_del_rcu(&tz->node);
/* Unbind all cdevs associated with 'this' thermal zone */
list_for_each_entry(cdev, &thermal_cdev_list, node) {
@@ -2464,7 +2473,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
flush_work(&tz->sensor.work);
kthread_stop(tz->sensor.sysfs_notify_thread);
mutex_lock(&thermal_list_lock);
- list_del(&tz->sensor.sensor_list);
+ list_del_rcu(&tz->sensor.sensor_list);
mutex_unlock(&thermal_list_lock);
release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
idr_destroy(&tz->idr);
@@ -2492,13 +2501,13 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name)
if (!name)
goto exit;
- mutex_lock(&thermal_list_lock);
- list_for_each_entry(pos, &thermal_tz_list, node)
+ rcu_read_lock();
+ list_for_each_entry_rcu(pos, &thermal_tz_list, node)
if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) {
found++;
ref = pos;
}
- mutex_unlock(&thermal_list_lock);
+ rcu_read_unlock();
/* nothing has been found, thus an error code for it */
if (found == 0)
diff --git a/drivers/usb/dwc3/dbm.c b/drivers/usb/dwc3/dbm.c
index 285cd5a47d82..34a1b6259d1b 100644
--- a/drivers/usb/dwc3/dbm.c
+++ b/drivers/usb/dwc3/dbm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -312,9 +312,6 @@ int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer,
return -ENODEV;
}
- /* First, reset the dbm endpoint */
- ep_soft_reset(dbm, dbm_ep, 0);
-
/* Set ioc bit for dbm_ep if needed */
msm_dbm_write_reg_field(dbm, DBM_DBG_CNFG,
DBM_ENABLE_IOC_MASK & 1 << dbm_ep, ioc ? 1 : 0);
@@ -391,23 +388,10 @@ int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep)
data &= (~0x1);
msm_dbm_write_ep_reg(dbm, DBM_EP_CFG, dbm_ep, data);
- /* Reset the dbm endpoint */
- ep_soft_reset(dbm, dbm_ep, true);
/*
- * The necessary delay between asserting and deasserting the dbm ep
- * reset is based on the number of active endpoints. If there is more
- * than one endpoint, a 1 msec delay is required. Otherwise, a shorter
- * delay will suffice.
- *
- * As this function can be called in atomic context, sleeping variants
- * for delay are not possible - albeit a 1ms delay.
+ * ep_soft_reset is not required during disconnect as pipe reset on
+ * next connect will take care of the same.
*/
- if (dbm_get_num_of_eps_configured(dbm) > 1)
- udelay(1000);
- else
- udelay(10);
- ep_soft_reset(dbm, dbm_ep, false);
-
return 0;
}
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index a21f6735808b..15c994294c63 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;
@@ -209,6 +210,8 @@ struct dwc3_msm {
struct notifier_block vbus_nb;
struct notifier_block id_nb;
+ struct notifier_block host_nb;
+
int pwr_event_irq;
atomic_t in_p3;
unsigned int lpm_to_suspend_delay;
@@ -621,18 +624,36 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
struct dwc3_msm_req_complete *req_complete;
unsigned long flags;
int ret = 0, size;
- u8 bam_pipe;
- bool producer;
- bool disable_wb;
- bool internal_mem;
- bool ioc;
bool superspeed;
+ /*
+ * We must obtain the lock of the dwc3 core driver,
+ * including disabling interrupts, so we will be sure
+ * that we are the only ones that configure the HW device
+ * core and ensure that we queuing the request will finish
+ * as soon as possible so we will release back the lock.
+ */
+ spin_lock_irqsave(&dwc->lock, flags);
+ if (!dep->endpoint.desc) {
+ dev_err(mdwc->dev,
+ "%s: trying to queue request %p to disabled ep %s\n",
+ __func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EPERM;
+ }
+
+ if (!request) {
+ dev_err(mdwc->dev, "%s: request is NULL\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EINVAL;
+ }
+
if (!(request->udc_priv & MSM_SPS_MODE)) {
/* Not SPS mode, call original queue */
dev_vdbg(mdwc->dev, "%s: not sps mode, use regular queue\n",
__func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return (mdwc->original_ep_ops[dep->number])->queue(ep,
request,
gfp_flags);
@@ -641,9 +662,29 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
/* HW restriction regarding TRB size (8KB) */
if (req->request.length < 0x2000) {
dev_err(mdwc->dev, "%s: Min TRB size is 8KB\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -EINVAL;
}
+ if (dep->number == 0 || dep->number == 1) {
+ dev_err(mdwc->dev,
+ "%s: trying to queue dbm request %p to control ep %s\n",
+ __func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EPERM;
+ }
+
+ if (dep->busy_slot != dep->free_slot || !list_empty(&dep->request_list)
+ || !list_empty(&dep->req_queued)) {
+ dev_err(mdwc->dev,
+ "%s: trying to queue dbm request %p tp ep %s\n",
+ __func__, request, ep->name);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return -EPERM;
+ }
+ dep->busy_slot = 0;
+ dep->free_slot = 0;
+
/*
* Override req->complete function, but before doing that,
* store it's original pointer in the req_complete_list.
@@ -651,6 +692,7 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
req_complete = kzalloc(sizeof(*req_complete), gfp_flags);
if (!req_complete) {
dev_err(mdwc->dev, "%s: not enough memory\n", __func__);
+ spin_unlock_irqrestore(&dwc->lock, flags);
return -ENOMEM;
}
req_complete->req = request;
@@ -658,23 +700,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
request->complete = dwc3_msm_req_complete_func;
- /*
- * Configure the DBM endpoint
- */
- bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
- producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
- disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
- internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
- ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
-
- ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
- disable_wb, internal_mem, ioc);
- if (ret < 0) {
- dev_err(mdwc->dev,
- "error %d after calling dbm_ep_config\n", ret);
- return ret;
- }
-
dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
__func__, request, ep->name, request->length);
size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
@@ -683,43 +708,6 @@ static int dwc3_msm_ep_queue(struct usb_ep *ep,
dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTADRHI(0)),
DWC3_GEVNTSIZ_SIZE(size));
- /*
- * We must obtain the lock of the dwc3 core driver,
- * including disabling interrupts, so we will be sure
- * that we are the only ones that configure the HW device
- * core and ensure that we queuing the request will finish
- * as soon as possible so we will release back the lock.
- */
- spin_lock_irqsave(&dwc->lock, flags);
- if (!dep->endpoint.desc) {
- dev_err(mdwc->dev,
- "%s: trying to queue request %p to disabled ep %s\n",
- __func__, request, ep->name);
- ret = -EPERM;
- goto err;
- }
-
- if (dep->number == 0 || dep->number == 1) {
- dev_err(mdwc->dev,
- "%s: trying to queue dbm request %p to control ep %s\n",
- __func__, request, ep->name);
- ret = -EPERM;
- goto err;
- }
-
-
- if (dep->busy_slot != dep->free_slot || !list_empty(&dep->request_list)
- || !list_empty(&dep->req_queued)) {
- dev_err(mdwc->dev,
- "%s: trying to queue dbm request %p tp ep %s\n",
- __func__, request, ep->name);
- ret = -EPERM;
- goto err;
- } else {
- dep->busy_slot = 0;
- dep->free_slot = 0;
- }
-
ret = __dwc3_msm_ep_queue(dep, req);
if (ret < 0) {
dev_err(mdwc->dev,
@@ -1345,12 +1333,19 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep,
*
* @return int - 0 on success, negetive on error.
*/
-int msm_ep_config(struct usb_ep *ep)
+int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags)
{
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
struct usb_ep_ops *new_ep_ops;
+ int ret = 0;
+ u8 bam_pipe;
+ bool producer;
+ bool disable_wb;
+ bool internal_mem;
+ bool ioc;
/* Save original ep ops for future restore*/
@@ -1363,7 +1358,7 @@ int msm_ep_config(struct usb_ep *ep)
mdwc->original_ep_ops[dep->number] = ep->ops;
/* Set new usb ops as we like */
- new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), GFP_ATOMIC);
+ new_ep_ops = kzalloc(sizeof(struct usb_ep_ops), gfp_flags);
if (!new_ep_ops) {
dev_err(mdwc->dev,
"%s: unable to allocate mem for new usb ep ops\n",
@@ -1375,10 +1370,25 @@ int msm_ep_config(struct usb_ep *ep)
new_ep_ops->gsi_ep_op = dwc3_msm_gsi_ep_op;
ep->ops = new_ep_ops;
+ if (!mdwc->dbm || !request || (dep->endpoint.ep_type == EP_TYPE_GSI))
+ return 0;
+
/*
- * Do HERE more usb endpoint configurations
- * which are specific to MSM.
+ * Configure the DBM endpoint if required.
*/
+ bam_pipe = request->udc_priv & MSM_PIPE_ID_MASK;
+ producer = ((request->udc_priv & MSM_PRODUCER) ? true : false);
+ disable_wb = ((request->udc_priv & MSM_DISABLE_WB) ? true : false);
+ internal_mem = ((request->udc_priv & MSM_INTERNAL_MEM) ? true : false);
+ ioc = ((request->udc_priv & MSM_ETD_IOC) ? true : false);
+
+ ret = dbm_ep_config(mdwc->dbm, dep->number, bam_pipe, producer,
+ disable_wb, internal_mem, ioc);
+ if (ret < 0) {
+ dev_err(mdwc->dev,
+ "error %d after calling dbm_ep_config\n", ret);
+ return ret;
+ }
return 0;
}
@@ -1747,6 +1757,7 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc)
{
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
u32 val;
+ int ret;
/* Configure AHB2PHY for one wait state read/write */
if (mdwc->ahb2phy_base) {
@@ -1765,7 +1776,11 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc)
if (!mdwc->init) {
dbg_event(0xFF, "dwc3 init",
atomic_read(&mdwc->dev->power.usage_count));
- dwc3_core_pre_init(dwc);
+ ret = dwc3_core_pre_init(dwc);
+ if (ret) {
+ dev_err(mdwc->dev, "dwc3_core_pre_init failed\n");
+ return;
+ }
mdwc->init = true;
}
@@ -1956,6 +1971,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 +2087,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);
@@ -2376,12 +2395,15 @@ static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc)
return ret;
}
- if (!of_property_read_u32(mdwc->dev->of_node, "qcom,core-clk-rate",
+ if (of_property_read_u32(mdwc->dev->of_node, "qcom,core-clk-rate",
(u32 *)&mdwc->core_clk_rate)) {
- mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk,
- mdwc->core_clk_rate);
+ dev_err(mdwc->dev, "USB core-clk-rate is not present\n");
+ return -EINVAL;
}
+ mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk,
+ mdwc->core_clk_rate);
+
dev_dbg(mdwc->dev, "USB core frequency = %ld\n",
mdwc->core_clk_rate);
ret = clk_set_rate(mdwc->core_clk, mdwc->core_clk_rate);
@@ -2416,6 +2438,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");
@@ -2520,8 +2546,12 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc)
struct extcon_dev *edev;
int ret = 0;
- if (!of_property_read_bool(node, "extcon"))
- return 0;
+ if (!of_property_read_bool(node, "extcon")) {
+ if (usb_get_dr_mode(&mdwc->dwc3->dev) == USB_DR_MODE_HOST)
+ return 0;
+ dev_err(mdwc->dev, "extcon property doesn't exist\n");
+ return -EINVAL;
+ }
edev = extcon_get_edev_by_phandle(mdwc->dev, 0);
if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV)
@@ -2965,6 +2995,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);
@@ -3012,6 +3044,53 @@ static int dwc3_msm_remove(struct platform_device *pdev)
return 0;
}
+static int dwc3_msm_host_notifier(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, host_nb);
+ struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
+ struct usb_device *udev = ptr;
+ union power_supply_propval pval;
+ unsigned max_power;
+
+ if (event != USB_DEVICE_ADD && event != USB_DEVICE_REMOVE)
+ return NOTIFY_DONE;
+
+ if (!mdwc->usb_psy) {
+ mdwc->usb_psy = power_supply_get_by_name("usb");
+ if (!mdwc->usb_psy)
+ return NOTIFY_DONE;
+ }
+
+ /*
+ * For direct-attach devices, new udev is direct child of root hub
+ * i.e. dwc -> xhci -> root_hub -> udev
+ * root_hub's udev->parent==NULL, so traverse struct device hierarchy
+ */
+ if (udev->parent && !udev->parent->parent &&
+ udev->dev.parent->parent == &dwc->xhci->dev) {
+ if (event == USB_DEVICE_ADD && udev->actconfig) {
+ if (udev->speed >= USB_SPEED_SUPER)
+ max_power = udev->actconfig->desc.bMaxPower * 8;
+ else
+ max_power = udev->actconfig->desc.bMaxPower * 2;
+ dev_dbg(mdwc->dev, "%s configured bMaxPower:%d (mA)\n",
+ dev_name(&udev->dev), max_power);
+
+ /* inform PMIC of max power so it can optimize boost */
+ pval.intval = max_power * 1000;
+ power_supply_set_property(mdwc->usb_psy,
+ POWER_SUPPLY_PROP_BOOST_CURRENT, &pval);
+ } else {
+ pval.intval = 0;
+ power_supply_set_property(mdwc->usb_psy,
+ POWER_SUPPLY_PROP_BOOST_CURRENT, &pval);
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
#define VBUS_REG_CHECK_DELAY (msecs_to_jiffies(1000))
/**
@@ -3072,6 +3151,9 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
+ mdwc->host_nb.notifier_call = dwc3_msm_host_notifier;
+ usb_register_notify(&mdwc->host_nb);
+
/*
* FIXME If micro A cable is disconnected during system suspend,
* xhci platform device will be removed before runtime pm is
@@ -3092,6 +3174,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
pm_runtime_put_sync(mdwc->dev);
dbg_event(0xFF, "pdeverr psync",
atomic_read(&mdwc->dev->power.usage_count));
+ usb_unregister_notify(&mdwc->host_nb);
return ret;
}
@@ -3128,6 +3211,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
mdwc->hs_phy->flags &= ~PHY_HOST_MODE;
mdwc->ss_phy->flags &= ~PHY_HOST_MODE;
platform_device_del(dwc->xhci);
+ usb_unregister_notify(&mdwc->host_nb);
/*
* Perform USB hardware RESET (both core reset and DBM reset)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2450cc52fa24..b6442fad550a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -213,7 +213,8 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
* use mult as 3 for GSI IN endpoint always irrespective
* USB speed.
*/
- if (dep->endpoint.ep_type == EP_TYPE_GSI)
+ if (dep->endpoint.ep_type == EP_TYPE_GSI ||
+ dep->endpoint.endless)
mult = 3;
if (!(dep->flags & DWC3_EP_ENABLED)) {
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index af20033b621f..84b60ec771a4 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2245,7 +2245,7 @@ skip_string_id_alloc:
if (!ep)
goto fail;
gsi->d_port.in_ep = ep;
- msm_ep_config(gsi->d_port.in_ep);
+ msm_ep_config(gsi->d_port.in_ep, NULL, GFP_KERNEL);
ep->driver_data = cdev; /* claim */
}
@@ -2255,7 +2255,7 @@ skip_string_id_alloc:
if (!ep)
goto fail;
gsi->d_port.out_ep = ep;
- msm_ep_config(gsi->d_port.out_ep);
+ msm_ep_config(gsi->d_port.out_ep, NULL, GFP_KERNEL);
ep->driver_data = cdev; /* claim */
}
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index 2da0c59fdfc2..1850aa6ea19d 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -457,7 +457,7 @@ static void ipa_data_connect_work(struct work_struct *w)
configure_fifo(port->usb_bam_type,
port->src_connection_idx,
port->port_usb->out);
- ret = msm_ep_config(gport->out);
+ ret = msm_ep_config(gport->out, port->rx_req, GFP_ATOMIC);
if (ret) {
pr_err("msm_ep_config() failed for OUT EP\n");
usb_bam_free_fifos(port->usb_bam_type,
@@ -475,7 +475,7 @@ static void ipa_data_connect_work(struct work_struct *w)
port->tx_req->udc_priv = sps_params;
configure_fifo(port->usb_bam_type,
port->dst_connection_idx, gport->in);
- ret = msm_ep_config(gport->in);
+ ret = msm_ep_config(gport->in, port->tx_req, GFP_ATOMIC);
if (ret) {
pr_err("msm_ep_config() failed for IN EP\n");
goto unconfig_msm_ep_out;
diff --git a/drivers/usb/gadget/function/u_qdss.c b/drivers/usb/gadget/function/u_qdss.c
index 8f5fcc16eb15..e26f0977b9b7 100644
--- a/drivers/usb/gadget/function/u_qdss.c
+++ b/drivers/usb/gadget/function/u_qdss.c
@@ -94,11 +94,12 @@ int set_qdss_data_connection(struct usb_gadget *gadget,
static int init_data(struct usb_ep *ep)
{
+ struct f_qdss *qdss = ep->driver_data;
int res = 0;
pr_debug("init_data\n");
- res = msm_ep_config(ep);
+ res = msm_ep_config(ep, qdss->endless_req, GFP_ATOMIC);
if (res)
pr_err("msm_ep_config failed\n");
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 5a768ee4d061..86908d2ce9d5 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -51,6 +51,10 @@
#define QUSB2PHY_PORT_TUNE1 0x23c
+#define QUSB2PHY_1P2_VOL_MIN 1200000 /* uV */
+#define QUSB2PHY_1P2_VOL_MAX 1200000 /* uV */
+#define QUSB2PHY_1P2_HPM_LOAD 23000
+
#define QUSB2PHY_1P8_VOL_MIN 1800000 /* uV */
#define QUSB2PHY_1P8_VOL_MAX 1800000 /* uV */
#define QUSB2PHY_1P8_HPM_LOAD 30000 /* uA */
@@ -83,6 +87,7 @@ struct qusb_phy {
struct regulator *vdd;
struct regulator *vdda33;
struct regulator *vdda18;
+ struct regulator *vdda12;
int vdd_levels[3]; /* none, low, high */
int init_seq_len;
int *qusb_phy_init_seq;
@@ -184,10 +189,30 @@ static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on,
}
}
+ ret = regulator_set_load(qphy->vdda12, QUSB2PHY_1P2_HPM_LOAD);
+ if (ret < 0) {
+ dev_err(qphy->phy.dev, "Unable to set HPM of vdda12:%d\n", ret);
+ goto disable_vdd;
+ }
+
+ ret = regulator_set_voltage(qphy->vdda12, QUSB2PHY_1P2_VOL_MIN,
+ QUSB2PHY_1P2_VOL_MAX);
+ if (ret) {
+ dev_err(qphy->phy.dev,
+ "Unable to set voltage for vdda12:%d\n", ret);
+ goto put_vdda12_lpm;
+ }
+
+ ret = regulator_enable(qphy->vdda12);
+ if (ret) {
+ dev_err(qphy->phy.dev, "Unable to enable vdda12:%d\n", ret);
+ goto unset_vdda12;
+ }
+
ret = regulator_set_load(qphy->vdda18, QUSB2PHY_1P8_HPM_LOAD);
if (ret < 0) {
dev_err(qphy->phy.dev, "Unable to set HPM of vdda18:%d\n", ret);
- goto disable_vdd;
+ goto disable_vdda12;
}
ret = regulator_set_voltage(qphy->vdda18, QUSB2PHY_1P8_VOL_MIN,
@@ -262,6 +287,20 @@ put_vdda18_lpm:
if (ret < 0)
dev_err(qphy->phy.dev, "Unable to set LPM of vdda18\n");
+disable_vdda12:
+ ret = regulator_disable(qphy->vdda12);
+ if (ret)
+ dev_err(qphy->phy.dev, "Unable to disable vdda12:%d\n", ret);
+unset_vdda12:
+ ret = regulator_set_voltage(qphy->vdda12, 0, QUSB2PHY_1P2_VOL_MAX);
+ if (ret)
+ dev_err(qphy->phy.dev,
+ "Unable to set (0) voltage for vdda12:%d\n", ret);
+put_vdda12_lpm:
+ ret = regulator_set_load(qphy->vdda12, 0);
+ if (ret < 0)
+ dev_err(qphy->phy.dev, "Unable to set LPM of vdda12\n");
+
disable_vdd:
if (toggle_vdd) {
ret = regulator_disable(qphy->vdd);
@@ -985,6 +1024,12 @@ static int qusb_phy_probe(struct platform_device *pdev)
return PTR_ERR(qphy->vdda18);
}
+ qphy->vdda12 = devm_regulator_get(dev, "vdda12");
+ if (IS_ERR(qphy->vdda12)) {
+ dev_err(dev, "unable to get vdda12 supply\n");
+ return PTR_ERR(qphy->vdda12);
+ }
+
platform_set_drvdata(pdev, qphy);
qphy->phy.label = "msm-qusb-phy-v2";
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/dt-bindings/clock/audio-ext-clk.h b/include/dt-bindings/clock/audio-ext-clk.h
index c9a8286d7c7f..a384ddf68ea0 100644
--- a/include/dt-bindings/clock/audio-ext-clk.h
+++ b/include/dt-bindings/clock/audio-ext-clk.h
@@ -14,19 +14,17 @@
#define __AUDIO_EXT_CLK_H
/* Audio External Clocks */
-#ifdef CONFIG_COMMON_CLK_QCOM
#define AUDIO_PMI_CLK 0
#define AUDIO_PMIC_LNBB_CLK 1
#define AUDIO_AP_CLK 2
#define AUDIO_AP_CLK2 3
#define AUDIO_LPASS_MCLK 4
#define AUDIO_LPASS_MCLK2 5
-#else
+
#define clk_audio_ap_clk 0x9b5727cb
#define clk_audio_pmi_clk 0xcbfe416d
#define clk_audio_ap_clk2 0x454d1e91
#define clk_audio_lpass_mclk 0xf0f2a284
#define clk_audio_pmi_lnbb_clk 0x57312343
-#endif
#endif
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index aed90a4902c7..5cd588fa9f6a 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -269,6 +269,8 @@ struct regulator;
regulator
* @level_votes: array of votes for each level
* @num_levels: specifies the size of level_votes array
+ * @skip_handoff: do not vote for the max possible voltage during init
+ * @use_max_uV: use INT_MAX for max_uV when calling regulator_set_voltage
* @cur_level: the currently set voltage level
* @lock: lock to protect this struct
*/
@@ -280,6 +282,8 @@ struct clk_vdd_class {
int *vdd_uv;
int *level_votes;
int num_levels;
+ bool skip_handoff;
+ bool use_max_uV;
unsigned long cur_level;
struct mutex lock;
};
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6c1ea7f327c4..0c4178e5b656 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2128,6 +2128,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
#define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */
#define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */
#define FOLL_MLOCK 0x1000 /* lock present pages */
+#define FOLL_COW 0x4000 /* internal GUP flag */
typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
void *data);
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index f3ec960536aa..33286c2d81fc 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -255,6 +255,15 @@ extern int devmgr_client_request_mitigation(struct device_clnt_data *clnt,
extern void devmgr_unregister_mitigation_client(
struct device *dev,
struct device_clnt_data *clnt);
+#ifdef CONFIG_QCOM_THERMAL_LIMITS_DCVS
+extern int msm_lmh_dcvsh_sw_notify(int cpu);
+#else
+static inline int msm_lmh_dcvsh_sw_notify(int cpu)
+{
+ return -ENODEV;
+}
+#endif
+
#else
static inline int msm_thermal_init(struct msm_thermal_data *pdata)
{
@@ -330,6 +339,10 @@ static inline void devmgr_unregister_mitigation_client(
struct device_clnt_data *clnt)
{
}
+static inline int msm_lmh_dcvsh_sw_notify(int cpu)
+{
+ return -ENODEV;
+}
#endif
#endif /*__MSM_THERMAL_H*/
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 18e1a979db76..125568f7862c 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -199,6 +199,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_UPDATE_NOW,
POWER_SUPPLY_PROP_ESR_COUNT,
POWER_SUPPLY_PROP_BUCK_FREQ,
+ POWER_SUPPLY_PROP_BOOST_CURRENT,
POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE,
POWER_SUPPLY_PROP_CHARGE_DONE,
POWER_SUPPLY_PROP_FLASH_ACTIVE,
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 44b6222db9a3..1eb442f8dc6c 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -296,7 +296,8 @@ static inline void msm_usb_irq_disable(bool disable)
#endif
#ifdef CONFIG_USB_DWC3_QCOM
-int msm_ep_config(struct usb_ep *ep);
+int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags);
int msm_ep_unconfig(struct usb_ep *ep);
void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable);
int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, u32 size,
@@ -311,7 +312,8 @@ static inline int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr,
return -ENODEV;
}
-static inline int msm_ep_config(struct usb_ep *ep)
+static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request,
+ gfp_t gfp_flags)
{
return -ENODEV;
}
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 29990f036552..9c38b9aa5627 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -124,8 +124,7 @@ extern int icnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 *ch_count,
extern int icnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int icnss_wlan_get_dfs_nol(void *info, u16 info_len);
extern bool icnss_is_qmi_disable(void);
-extern int icnss_set_wlan_mac_address(struct device *dev,
- const u8 *in, uint32_t len);
+extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len);
extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
#endif /* _ICNSS_WLAN_H_ */
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/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index e01e16e5cebe..06d952a07c2a 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -788,6 +788,7 @@ struct adm_cmd_connect_afe_port_v5 {
#define SLIMBUS_3_TX 0x4007
#define SLIMBUS_4_RX 0x4008
#define SLIMBUS_4_TX 0x4009
+#define SLIMBUS_TX_VI 0x4f09
#define SLIMBUS_5_RX 0x400a
#define SLIMBUS_5_TX 0x400b
#define SLIMBUS_6_RX 0x400c
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)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d7846edd7a79..ee708909dc17 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1248,15 +1248,16 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,
goto out;
cpumask_andnot(&allowed_mask, new_mask, cpu_isolated_mask);
+ cpumask_and(&allowed_mask, &allowed_mask, cpu_active_mask);
- dest_cpu = cpumask_any_and(cpu_active_mask, &allowed_mask);
+ dest_cpu = cpumask_any(&allowed_mask);
if (dest_cpu >= nr_cpu_ids) {
- dest_cpu = cpumask_any_and(cpu_active_mask, new_mask);
+ cpumask_and(&allowed_mask, cpu_active_mask, new_mask);
+ dest_cpu = cpumask_any(&allowed_mask);
if (dest_cpu >= nr_cpu_ids) {
ret = -EINVAL;
goto out;
}
- cpumask_copy(&allowed_mask, new_mask);
}
do_set_cpus_allowed(p, new_mask);
@@ -4635,6 +4636,8 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
cpumask_var_t cpus_allowed, new_mask;
struct task_struct *p;
int retval;
+ int dest_cpu;
+ cpumask_t allowed_mask;
rcu_read_lock();
@@ -4696,20 +4699,26 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
}
#endif
again:
- retval = __set_cpus_allowed_ptr(p, new_mask, true);
-
- if (!retval) {
- cpuset_cpus_allowed(p, cpus_allowed);
- if (!cpumask_subset(new_mask, cpus_allowed)) {
- /*
- * We must have raced with a concurrent cpuset
- * update. Just reset the cpus_allowed to the
- * cpuset's cpus_allowed
- */
- cpumask_copy(new_mask, cpus_allowed);
- goto again;
+ cpumask_andnot(&allowed_mask, new_mask, cpu_isolated_mask);
+ dest_cpu = cpumask_any_and(cpu_active_mask, &allowed_mask);
+ if (dest_cpu < nr_cpu_ids) {
+ retval = __set_cpus_allowed_ptr(p, new_mask, true);
+ if (!retval) {
+ cpuset_cpus_allowed(p, cpus_allowed);
+ if (!cpumask_subset(new_mask, cpus_allowed)) {
+ /*
+ * We must have raced with a concurrent cpuset
+ * update. Just reset the cpus_allowed to the
+ * cpuset's cpus_allowed
+ */
+ cpumask_copy(new_mask, cpus_allowed);
+ goto again;
+ }
}
+ } else {
+ retval = -EINVAL;
}
+
out_free_new_mask:
free_cpumask_var(new_mask);
out_free_cpus_allowed:
@@ -5455,6 +5464,37 @@ static struct task_struct fake_task = {
};
/*
+ * Remove a task from the runqueue and pretend that it's migrating. This
+ * should prevent migrations for the detached task and disallow further
+ * changes to tsk_cpus_allowed.
+ */
+static void
+detach_one_task(struct task_struct *p, struct rq *rq, struct list_head *tasks)
+{
+ lockdep_assert_held(&rq->lock);
+
+ p->on_rq = TASK_ON_RQ_MIGRATING;
+ deactivate_task(rq, p, 0);
+ list_add(&p->se.group_node, tasks);
+}
+
+static void attach_tasks(struct list_head *tasks, struct rq *rq)
+{
+ struct task_struct *p;
+
+ lockdep_assert_held(&rq->lock);
+
+ while (!list_empty(tasks)) {
+ p = list_first_entry(tasks, struct task_struct, se.group_node);
+ list_del_init(&p->se.group_node);
+
+ BUG_ON(task_rq(p) != rq);
+ activate_task(rq, p, 0);
+ p->on_rq = TASK_ON_RQ_QUEUED;
+ }
+}
+
+/*
* Migrate all tasks (not pinned if pinned argument say so) from the rq,
* sleeping tasks will be migrated by try_to_wake_up()->select_task_rq().
*
@@ -5468,6 +5508,7 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
struct task_struct *next, *stop = rq->stop;
int dest_cpu;
unsigned int num_pinned_kthreads = 1; /* this thread */
+ LIST_HEAD(tasks);
cpumask_t avail_cpus;
cpumask_andnot(&avail_cpus, cpu_online_mask, cpu_isolated_mask);
@@ -5492,12 +5533,10 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
for (;;) {
/*
- * There's this thread running + pinned threads, bail when
- * that's the only remaining threads.
+ * There's this thread running, bail when that's the only
+ * remaining thread.
*/
- if ((migrate_pinned_tasks && rq->nr_running == 1) ||
- (!migrate_pinned_tasks &&
- rq->nr_running <= num_pinned_kthreads))
+ if (rq->nr_running == 1)
break;
/*
@@ -5510,8 +5549,9 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
if (!migrate_pinned_tasks && next->flags & PF_KTHREAD &&
!cpumask_intersects(&avail_cpus, &next->cpus_allowed)) {
- lockdep_unpin_lock(&rq->lock);
+ detach_one_task(next, rq, &tasks);
num_pinned_kthreads += 1;
+ lockdep_unpin_lock(&rq->lock);
continue;
}
@@ -5559,6 +5599,9 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks)
}
rq->stop = stop;
+
+ if (num_pinned_kthreads > 1)
+ attach_tasks(&tasks, rq);
}
static void set_rq_online(struct rq *rq);
@@ -5600,6 +5643,7 @@ int do_isolation_work_cpu_stop(void *data)
*/
nohz_balance_clear_nohz_mask(cpu);
+ clear_hmp_request(cpu);
local_irq_enable();
return 0;
}
@@ -5724,7 +5768,6 @@ int sched_isolate_cpu(int cpu)
migrate_sync_cpu(cpu, cpumask_first(&avail_cpus));
stop_cpus(cpumask_of(cpu), do_isolation_work_cpu_stop, 0);
- clear_hmp_request(cpu);
calc_load_migrate(rq);
update_max_interval();
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 12a04f30ef77..52edd6b158ed 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1970,11 +1970,11 @@ retry:
goto retry;
}
- deactivate_task(rq, next_task, 0);
next_task->on_rq = TASK_ON_RQ_MIGRATING;
+ deactivate_task(rq, next_task, 0);
set_task_cpu(next_task, lowest_rq->cpu);
- next_task->on_rq = TASK_ON_RQ_QUEUED;
activate_task(lowest_rq, next_task, 0);
+ next_task->on_rq = TASK_ON_RQ_QUEUED;
ret = 1;
resched_curr(lowest_rq);
@@ -2226,11 +2226,11 @@ static void pull_rt_task(struct rq *this_rq)
resched = true;
- deactivate_task(src_rq, p, 0);
p->on_rq = TASK_ON_RQ_MIGRATING;
+ deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
- p->on_rq = TASK_ON_RQ_QUEUED;
activate_task(this_rq, p, 0);
+ p->on_rq = TASK_ON_RQ_QUEUED;
/*
* We continue with the search, just in
* case there's an even higher prio task
diff --git a/mm/gup.c b/mm/gup.c
index deafa2c91b36..4b0b7e7d1136 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -58,6 +58,16 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address,
return -EEXIST;
}
+/*
+ * FOLL_FORCE can write to even unwritable pte's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
+{
+ return pte_write(pte) ||
+ ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
+}
+
static struct page *follow_page_pte(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmd, unsigned int flags)
{
@@ -92,7 +102,7 @@ retry:
}
if ((flags & FOLL_NUMA) && pte_protnone(pte))
goto no_page;
- if ((flags & FOLL_WRITE) && !pte_write(pte)) {
+ if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
pte_unmap_unlock(ptep, ptl);
return NULL;
}
@@ -352,7 +362,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
* reCOWed by userspace write).
*/
if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
- *flags &= ~FOLL_WRITE;
+ *flags |= FOLL_COW;
return 0;
}
diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c
index 70be9c98b481..614410c26a91 100644
--- a/sound/soc/codecs/wcd-spi.c
+++ b/sound/soc/codecs/wcd-spi.c
@@ -855,12 +855,22 @@ static int wdsp_spi_event_handler(struct device *dev, void *priv_data,
void *data)
{
struct spi_device *spi = to_spi_device(dev);
+ struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi);
int ret = 0;
dev_dbg(&spi->dev, "%s: event type %d\n",
__func__, event);
switch (event) {
+ case WDSP_EVENT_POST_SHUTDOWN:
+ cancel_delayed_work_sync(&wcd_spi->clk_dwork);
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ if (test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask))
+ wcd_spi_clk_disable(spi);
+ wcd_spi->clk_users = 0;
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ break;
+
case WDSP_EVENT_PRE_DLOAD_CODE:
case WDSP_EVENT_PRE_DLOAD_DATA:
ret = wcd_spi_clk_ctrl(spi, WCD_SPI_CLK_ENABLE,
diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
index 9898c1fc7471..aa180fa3159f 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
+++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
@@ -401,6 +401,8 @@ static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl)
__func__, ret);
goto done;
}
+ /* Pull CPAR out of reset */
+ snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x00);
/* Configure and Enable CPE FLL clock */
ret = wcd_cntl_cpe_fll_ctrl(cntl, true);
@@ -422,6 +424,7 @@ err_cpe_clk:
if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en)
cntl->cdc_cb->cdc_clk_en(codec, false);
+ snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04);
WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex);
return ret;
}
@@ -458,6 +461,9 @@ static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl)
ret = -EINVAL;
cntl->is_clk_enabled = false;
+
+ /* Put CPAR in reset */
+ snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x04, 0x04);
done:
WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex);
return ret;
@@ -469,9 +475,9 @@ static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl,
struct snd_soc_codec *codec = cntl->codec;
if (enable)
- snd_soc_write(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03);
+ snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x03);
else
- snd_soc_write(codec, WCD934X_CPE_SS_CPAR_CTL, 0x00);
+ snd_soc_update_bits(codec, WCD934X_CPE_SS_CPAR_CTL, 0x03, 0x00);
}
static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl,
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index a5cd94f91cfc..a5a81df49d69 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -50,6 +50,15 @@ config DOLBY_DS2
device, end point dependent post processing parameters and
the various posrt processing parameters
+config DOLBY_LICENSE
+ bool "Enable Dolby LICENSE"
+ depends on SND_SOC_MSM_QDSP6V2_INTF
+ help
+ To add support for dolby DAP post processing,
+ and retain DAP set license functionality only.
+ This is required by Dolby GEF implementation which needs
+ nothing but dolby license validation functionality in driver.
+
config DTS_EAGLE
bool "Enable DTS Eagle Support"
depends on SND_SOC_MSM_QDSP6V2_INTF
@@ -211,7 +220,7 @@ config SND_SOC_MSM8998
select QTI_PP
select SND_SOC_CPE
select MSM_ULTRASOUND
- select DOLBY_DS2
+ select DOLBY_LICENSE
select SND_HWDEP
select DTS_EAGLE
help
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index 1df839333d09..7f43ef401a4f 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/switch.h>
#include <linux/input.h>
+#include <linux/of_device.h>
#include <linux/mfd/msm-cdc-pinctrl.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -74,6 +75,8 @@
#define TDM_CHANNEL_MAX 8
#define TDM_SLOT_OFFSET_MAX 8
+#define MSM_HIFI_ON 1
+
enum {
SLIM_RX_0 = 0,
SLIM_RX_1,
@@ -158,8 +161,6 @@ struct msm_wsa881x_dev_info {
struct msm_asoc_mach_data {
u32 mclk_freq;
- int hph_en1_gpio;
- int hph_en0_gpio;
int us_euro_gpio; /* used by gpio driver API */
struct device_node *us_euro_gpio_p; /* used by pinctrl API */
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
@@ -415,6 +416,7 @@ static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
"Five", "Six", "Seven",
"Eight"};
+static const char *const hifi_text[] = {"Off", "On"};
static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
@@ -474,8 +476,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
static struct platform_device *spdev;
+static int msm_hifi_control;
static bool is_initial_boot;
static bool codec_reg_done;
@@ -2340,6 +2344,56 @@ static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
return 1;
}
+static int msm_hifi_ctrl(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ pr_debug("%s: msm_hifi_control = %d", __func__,
+ msm_hifi_control);
+
+ if (!pdata || !pdata->hph_en1_gpio_p) {
+ pr_err("%s: hph_en1_gpio is invalid\n", __func__);
+ return -EINVAL;
+ }
+ if (msm_hifi_control == MSM_HIFI_ON) {
+ msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p);
+ /* 5msec delay needed as per HW requirement */
+ usleep_range(5000, 5010);
+ } else {
+ msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p);
+ }
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static int msm_hifi_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_hifi_control = %d\n",
+ __func__, msm_hifi_control);
+ ucontrol->value.integer.value[0] = msm_hifi_control;
+
+ return 0;
+}
+
+static int msm_hifi_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ pr_debug("%s() ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ msm_hifi_control = ucontrol->value.integer.value[0];
+ msm_hifi_ctrl(codec);
+
+ return 0;
+}
+
static const struct snd_kcontrol_new msm_snd_controls[] = {
SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
msm_slim_rx_ch_get, msm_slim_rx_ch_put),
@@ -2542,6 +2596,8 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
+ msm_hifi_put),
};
static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
@@ -2608,6 +2664,39 @@ static int msm_mclk_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ pr_debug("%s: msm_hifi_control = %d", __func__, msm_hifi_control);
+
+ if (!pdata || !pdata->hph_en0_gpio_p) {
+ pr_err("%s: hph_en0_gpio is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+ if (msm_hifi_control != MSM_HIFI_ON) {
+ pr_debug("%s: HiFi mixer control is not set\n",
+ __func__);
+ return 0;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p);
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
@@ -2621,6 +2710,7 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
+ SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
@@ -2765,6 +2855,7 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
break;
case MSM_BACKEND_DAI_SLIMBUS_4_TX:
+ case MSM_BACKEND_DAI_SLIMBUS_TX_VI:
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_FORMAT_S32_LE);
rate->min = rate->max = SAMPLING_RATE_8KHZ;
@@ -3207,28 +3298,6 @@ static struct notifier_block service_nb = {
.priority = -INT_MAX,
};
-static int msm_config_hph_en0_gpio(struct snd_soc_codec *codec, bool high)
-{
- struct snd_soc_card *card = codec->component.card;
- struct msm_asoc_mach_data *pdata;
- int val;
-
- if (!card)
- return 0;
-
- pdata = snd_soc_card_get_drvdata(card);
- if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio))
- return 0;
-
- val = gpio_get_value_cansleep(pdata->hph_en0_gpio);
- if ((!!val) == high)
- return 0;
-
- gpio_direction_output(pdata->hph_en0_gpio, (int)high);
-
- return 1;
-}
-
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -3560,7 +3629,8 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream,
/* For <codec>_tx3 case */
else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
user_set_tx_ch = slim_tx_cfg[1].channels;
- else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
+ else if (dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_4_TX ||
+ dai_link->be_id == MSM_BACKEND_DAI_SLIMBUS_TX_VI)
user_set_tx_ch = msm_vi_feed_tx_ch;
else
user_set_tx_ch = tx_ch_cnt;
@@ -5259,6 +5329,22 @@ static struct snd_soc_dai_link msm_tasha_be_dai_links[] = {
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
+ /* Slimbus VI Recording */
+ {
+ .name = LPASS_BE_SLIMBUS_TX_VI,
+ .stream_name = "Slimbus VI Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.20233",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_vifeedback",
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_TX_VI,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .ignore_pmdown_time = 1,
+ },
};
static struct snd_soc_dai_link msm_tavil_be_dai_links[] = {
@@ -5431,6 +5517,23 @@ static struct snd_soc_dai_link msm_tavil_be_dai_links[] = {
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
+
+ /* Slimbus VI Recording */
+ {
+ .name = LPASS_BE_SLIMBUS_TX_VI,
+ .stream_name = "Slimbus VI Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.20233",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_vifeedback",
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_TX_VI,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .ignore_pmdown_time = 1,
+ },
};
static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
@@ -5800,8 +5903,6 @@ static int msm_snd_card_late_probe(struct snd_soc_card *card)
goto err_pcm_runtime;
}
- tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, rtd->codec);
-
mbhc_calibration = def_tasha_mbhc_cal();
if (!mbhc_calibration) {
ret = -ENOMEM;
@@ -5976,37 +6077,6 @@ static int msm_prepare_us_euro(struct snd_soc_card *card)
return ret;
}
-static int msm_prepare_hifi(struct snd_soc_card *card)
-{
- struct msm_asoc_mach_data *pdata =
- snd_soc_card_get_drvdata(card);
- int ret = 0;
-
- if (gpio_is_valid(pdata->hph_en1_gpio)) {
- dev_dbg(card->dev, "%s: hph_en1_gpio request %d\n", __func__,
- pdata->hph_en1_gpio);
- ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio");
- if (ret) {
- dev_err(card->dev,
- "%s: hph_en1_gpio request failed, ret:%d\n",
- __func__, ret);
- goto err;
- }
- }
- if (gpio_is_valid(pdata->hph_en0_gpio)) {
- dev_dbg(card->dev, "%s: hph_en0_gpio request %d\n", __func__,
- pdata->hph_en0_gpio);
- ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio");
- if (ret)
- dev_err(card->dev,
- "%s: hph_en0_gpio request failed, ret:%d\n",
- __func__, ret);
- }
-
-err:
- return ret;
-}
-
static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -6666,30 +6736,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
if (ret)
goto err;
- pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,hph-en1-gpio", 0);
- if (!gpio_is_valid(pdata->hph_en1_gpio))
- pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
- "qcom,hph-en1-gpio", 0);
- if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) {
- dev_dbg(&pdev->dev, "property %s not detected in node %s",
- "qcom,hph-en1-gpio", pdev->dev.of_node->full_name);
- }
-
- pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,hph-en0-gpio", 0);
- if (!gpio_is_valid(pdata->hph_en0_gpio))
- pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
- "qcom,hph-en0-gpio", 0);
- if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) {
- dev_dbg(&pdev->dev, "property %s not detected in node %s",
- "qcom,hph-en0-gpio", pdev->dev.of_node->full_name);
- }
-
- ret = msm_prepare_hifi(card);
- if (ret)
- dev_dbg(&pdev->dev, "msm_prepare_hifi failed (%d)\n",
- ret);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret == -EPROBE_DEFER) {
if (codec_reg_done)
@@ -6703,6 +6749,28 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
spdev = pdev;
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n",
+ __func__, ret);
+ } else {
+ pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en1-gpio", 0);
+ if (!pdata->hph_en1_gpio_p) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en1-gpio",
+ pdev->dev.of_node->full_name);
+ }
+
+ pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en0-gpio", 0);
+ if (!pdata->hph_en0_gpio_p) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en0-gpio",
+ pdev->dev.of_node->full_name);
+ }
+ }
+
ret = of_property_read_string(pdev->dev.of_node,
"qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
if (ret) {
@@ -6761,18 +6829,6 @@ err:
gpio_free(pdata->us_euro_gpio);
pdata->us_euro_gpio = 0;
}
- if (pdata->hph_en1_gpio > 0) {
- dev_dbg(&pdev->dev, "%s free hph_en1_gpio %d\n",
- __func__, pdata->hph_en1_gpio);
- gpio_free(pdata->hph_en1_gpio);
- pdata->hph_en1_gpio = 0;
- }
- if (pdata->hph_en0_gpio > 0) {
- dev_dbg(&pdev->dev, "%s free hph_en0_gpio %d\n",
- __func__, pdata->hph_en0_gpio);
- gpio_free(pdata->hph_en0_gpio);
- pdata->hph_en0_gpio = 0;
- }
devm_kfree(&pdev->dev, pdata);
return ret;
}
@@ -6784,8 +6840,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
snd_soc_card_get_drvdata(card);
gpio_free(pdata->us_euro_gpio);
- gpio_free(pdata->hph_en1_gpio);
- gpio_free(pdata->hph_en0_gpio);
i2s_auxpcm_deinit();
snd_soc_unregister_card(card);
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 461c09db2937..469ab1a19c5b 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SND_HWDEP) += msm-pcm-routing-devdep.o
obj-$(CONFIG_DTS_EAGLE) += msm-dts-eagle.o
obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o
obj-$(CONFIG_DOLBY_DS2) += msm-ds2-dap-config.o
+obj-$(CONFIG_DOLBY_LICENSE) += msm-ds2-dap-config.o
obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o
obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o
obj-y += audio_calibration.o audio_cal_utils.o q6adm.o q6afe.o q6asm.o \
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index f1f2fd908eca..26cdd0fa7ad7 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1757,6 +1757,7 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream,
case SLIMBUS_2_TX:
case SLIMBUS_3_TX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_TX:
case SLIMBUS_6_TX:
case SLIMBUS_7_TX:
@@ -1906,6 +1907,7 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
case SLIMBUS_2_TX:
case SLIMBUS_3_TX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_TX:
case SLIMBUS_6_TX:
case SLIMBUS_7_TX:
@@ -2284,6 +2286,9 @@ static const struct snd_kcontrol_new sb_config_controls[] = {
msm_dai_q6_cal_info_put),
SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0],
msm_dai_q6_sb_format_get,
+ msm_dai_q6_sb_format_put),
+ SOC_ENUM_EXT("SLIM_TX_VI Format", sb_config_enum[0],
+ msm_dai_q6_sb_format_get,
msm_dai_q6_sb_format_put)
};
@@ -2336,6 +2341,11 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
snd_ctl_new1(&sb_config_controls[0],
dai_data));
break;
+ case SLIMBUS_TX_VI:
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(&sb_config_controls[3],
+ dai_data));
+ break;
case SLIMBUS_2_RX:
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(&sb_config_controls[1],
@@ -3218,6 +3228,25 @@ static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai[] = {
},
{
.capture = {
+ .stream_name = "Slimbus VI Capture",
+ .aif_name = "SLIMBUS_TX_VI",
+ .rates = SNDRV_PCM_RATE_8000_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 1,
+ .channels_max = 4,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_ops,
+ .id = SLIMBUS_TX_VI,
+ .probe = msm_dai_q6_dai_probe,
+ .remove = msm_dai_q6_dai_remove,
+ },
+ {
+ .capture = {
.stream_name = "Slimbus5 Capture",
.aif_name = "SLIMBUS_5_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
@@ -4523,6 +4552,9 @@ register_slim_playback:
case SLIMBUS_4_TX:
strlcpy(stream_name, "Slimbus4 Capture", 80);
goto register_slim_capture;
+ case SLIMBUS_TX_VI:
+ strlcpy(stream_name, "Slimbus VI Capture", 80);
+ goto register_slim_capture;
case SLIMBUS_5_TX:
strlcpy(stream_name, "Slimbus5 Capture", 80);
goto register_slim_capture;
diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
index ad2f2e9865c3..2441cabc07a7 100644
--- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
@@ -20,7 +20,7 @@
#include <sound/q6core.h>
-#ifdef CONFIG_DOLBY_DS2
+#if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE)
/* ramp up/down for 30ms */
#define DOLBY_SOFT_VOLUME_PERIOD 40
@@ -2284,4 +2284,4 @@ int msm_ds2_dap_ioctl_shared(struct snd_hwdep *hw, struct file *file,
{
return 0;
}
-#endif /*CONFIG_DOLBY_DS2*/
+#endif /* CONFIG_DOLBY_DS2 || CONFIG_DOLBY_LICENSE */
diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h
index 82794ee768a8..0eb6017fd383 100644
--- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h
+++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
@@ -45,7 +45,7 @@ struct dolby_param_license32 {
_IOR('U', 0x15, struct dolby_param_data32)
#endif
-#ifdef CONFIG_DOLBY_DS2
+#if defined(CONFIG_DOLBY_DS2) || defined(CONFIG_DOLBY_LICENSE)
/* DOLBY DOLBY GUIDS */
#define DS2_MODULE_ID 0x00010775
@@ -86,11 +86,11 @@ int msm_ds2_dap_set_custom_stereo_onoff(int port_id, int copp_idx,
/* Dolby DOLBY end */
#else
-static inline void msm_ds2_dap_update_port_parameters(struct snd_hwdep *hw,
+static inline int msm_ds2_dap_update_port_parameters(struct snd_hwdep *hw,
struct file *file,
bool open)
{
- return;
+ return 0;
}
static inline int msm_ds2_dap_ioctl(struct snd_hwdep *hw, struct file *file,
diff --git a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c
index 7a23a170be67..dfa4bb23c45d 100644
--- a/sound/soc/msm/qdsp6v2/msm-dts-eagle.c
+++ b/sound/soc/msm/qdsp6v2/msm-dts-eagle.c
@@ -234,7 +234,8 @@ static s32 _volume_cmds_alloc1(s32 size)
if (_vol_cmds) {
_vol_cmds_d = kzalloc(_vol_cmd_cnt * sizeof(struct vol_cmds_d),
GFP_KERNEL);
- }
+ } else
+ _vol_cmd_cnt = 0;
if (_vol_cmds_d)
return 0;
_volume_cmds_free();
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index a456cc2ab857..01902f7f571d 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -46,6 +46,16 @@
#include "q6voice.h"
#include "sound/q6lsm.h"
+#ifndef CONFIG_DOLBY_DAP
+#undef DOLBY_ADM_COPP_TOPOLOGY_ID
+#define DOLBY_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFE
+#endif
+
+#ifndef CONFIG_DOLBY_DS2
+#undef DS2_ADM_COPP_TOPOLOGY_ID
+#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF
+#endif
+
static int get_cal_path(int path_type);
static struct mutex routing_lock;
@@ -80,14 +90,15 @@ enum {
#define SLIMBUS_2_TX_TEXT "SLIMBUS_2_TX"
#define SLIMBUS_3_TX_TEXT "SLIMBUS_3_TX"
#define SLIMBUS_4_TX_TEXT "SLIMBUS_4_TX"
+#define SLIMBUS_TX_VI_TEXT "SLIMBUS_TX_VI"
#define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX"
#define TERT_MI2S_TX_TEXT "TERT_MI2S_TX"
#define LSM_FUNCTION_TEXT "LSM Function"
static const char * const mad_audio_mux_text[] = {
"None",
SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT,
- SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT,
- TERT_MI2S_TX_TEXT
+ SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_TX_VI_TEXT,
+ SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT
};
struct msm_pcm_route_bdai_pp_params {
@@ -110,6 +121,9 @@ static int msm_routing_get_bit_width(unsigned int format)
int bit_width;
switch (format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bit_width = 32;
+ break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
bit_width = 24;
@@ -495,6 +509,7 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
LPASS_BE_INT6_MI2S_RX},
{ AFE_PORT_ID_INT6_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT6_MI2S_TX},
+ { SLIMBUS_TX_VI, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI},
};
/* Track ASM playback & capture sessions of DAI */
@@ -4741,6 +4756,9 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
SOC_SINGLE_EXT("SLIM_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SLIM_TX_VI", MSM_BACKEND_DAI_SLIMBUS_TX_VI,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -8864,6 +8882,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIMBUS_4_TX", "Slimbus4 Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SLIMBUS_TX_VI", "Slimbus VI Capture",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SENARY_TX", "Senary_mi2s Capture",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIMBUS_5_TX", "Slimbus5 Capture", 0, 0, 0, 0),
@@ -9545,6 +9565,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia4 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
{"MultiMedia8 Mixer", "VOC_REC_DL", "INCALL_RECORD_RX"},
{"MultiMedia1 Mixer", "SLIM_4_TX", "SLIMBUS_4_TX"},
+ {"MultiMedia1 Mixer", "SLIM_TX_VI", "SLIMBUS_TX_VI"},
{"MultiMedia1 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"},
{"MultiMedia1 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia1 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
@@ -11281,6 +11302,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_1_TX", NULL, "BE_IN" },
{"SLIMBUS_3_TX", NULL, "BE_IN" },
{"SLIMBUS_4_TX", NULL, "BE_IN" },
+ {"SLIMBUS_TX_VI", NULL, "BE_IN" },
{"SLIMBUS_5_TX", NULL, "BE_IN" },
{"SLIMBUS_6_TX", NULL, "BE_IN" },
{"SLIMBUS_7_TX", NULL, "BE_IN" },
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index d64fd640618e..0bb069154512 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -65,6 +65,7 @@
#define LPASS_BE_SLIMBUS_4_RX "SLIMBUS_4_RX"
#define LPASS_BE_SLIMBUS_4_TX "SLIMBUS_4_TX"
#define LPASS_BE_SLIMBUS_5_RX "SLIMBUS_5_RX"
+#define LPASS_BE_SLIMBUS_TX_VI "SLIMBUS_TX_VI"
#define LPASS_BE_SLIMBUS_5_TX "SLIMBUS_5_TX"
#define LPASS_BE_SLIMBUS_6_RX "SLIMBUS_6_RX"
#define LPASS_BE_SLIMBUS_6_TX "SLIMBUS_6_TX"
@@ -355,6 +356,7 @@ enum {
MSM_BACKEND_DAI_INT5_MI2S_TX,
MSM_BACKEND_DAI_INT6_MI2S_RX,
MSM_BACKEND_DAI_INT6_MI2S_TX,
+ MSM_BACKEND_DAI_SLIMBUS_TX_VI,
MSM_BACKEND_DAI_MAX,
};
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 8f99a73fd29f..30876b52ec9e 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -39,6 +39,16 @@
#define ULL_SUPPORTED_BITS_PER_SAMPLE 16
#define ULL_SUPPORTED_SAMPLE_RATE 48000
+#ifndef CONFIG_DOLBY_DAP
+#undef DOLBY_ADM_COPP_TOPOLOGY_ID
+#define DOLBY_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFE
+#endif
+
+#ifndef CONFIG_DOLBY_DS2
+#undef DS2_ADM_COPP_TOPOLOGY_ID
+#define DS2_ADM_COPP_TOPOLOGY_ID 0xFFFFFFFF
+#endif
+
/* ENUM for adm_status */
enum adm_cal_status {
ADM_STATUS_CALIBRATION_REQUIRED = 0,
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 75dc7cf059e3..b87dcd36958f 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -503,6 +503,7 @@ int afe_get_port_type(u16 port_id)
case SLIMBUS_2_TX:
case SLIMBUS_3_TX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_TX:
case SLIMBUS_6_TX:
case SLIMBUS_7_TX:
@@ -607,6 +608,7 @@ int afe_sizeof_cfg_cmd(u16 port_id)
case SLIMBUS_3_TX:
case SLIMBUS_4_RX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_RX:
case SLIMBUS_5_TX:
case SLIMBUS_6_RX:
@@ -2785,6 +2787,13 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
return ret;
}
+ /*
+ * Virtual SLIMBUS_TX_VI shares afe port with SLIMBUS_4_TX.
+ * port_id changes to physical port of SLIMBUS_4_TX.
+ */
+ if (port_id == SLIMBUS_TX_VI)
+ port_id = SLIMBUS_4_TX;
+
if ((port_id == RT_PROXY_DAI_001_RX) ||
(port_id == RT_PROXY_DAI_002_TX)) {
pr_debug("%s: before incrementing pcm_afe_instance %d"\
@@ -2950,6 +2959,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
case SLIMBUS_3_TX:
case SLIMBUS_4_RX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_RX:
case SLIMBUS_5_TX:
case SLIMBUS_6_RX:
@@ -3143,6 +3153,7 @@ int afe_get_port_index(u16 port_id)
case RT_PROXY_PORT_001_TX: return IDX_RT_PROXY_PORT_001_TX;
case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
+ case SLIMBUS_TX_VI: return IDX_SLIMBUS_4_TX;
case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX;
case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX;
case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX;
@@ -5070,6 +5081,14 @@ int afe_close(int port_id)
goto fail_cmd;
}
pr_debug("%s: port_id = 0x%x\n", __func__, port_id);
+
+ /*
+ * Virtual SLIMBUS_TX_VI shares afe port with SLIMBUS_4_TX.
+ * port_id changes to physical port of SLIMBUS_4_TX.
+ */
+ if (port_id == SLIMBUS_TX_VI)
+ port_id = SLIMBUS_4_TX;
+
if ((port_id == RT_PROXY_DAI_001_RX) ||
(port_id == RT_PROXY_DAI_002_TX)) {
pr_debug("%s: before decrementing pcm_afe_instance %d\n",
@@ -6360,6 +6379,7 @@ static int afe_map_cal_data(int32_t cal_type,
}
+ mutex_lock(&this_afe.afe_cmd_lock);
atomic_set(&this_afe.mem_map_cal_index, cal_index);
ret = afe_cmd_memory_map(cal_block->cal_data.paddr,
cal_block->map_data.map_size);
@@ -6372,10 +6392,12 @@ static int afe_map_cal_data(int32_t cal_type,
__func__,
&cal_block->cal_data.paddr,
cal_block->map_data.map_size);
+ mutex_unlock(&this_afe.afe_cmd_lock);
goto done;
}
cal_block->map_data.q6map_handle = atomic_read(&this_afe.
mem_map_cal_handles[cal_index]);
+ mutex_unlock(&this_afe.afe_cmd_lock);
done:
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 84e1178dc354..a4951dc77378 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -64,6 +64,7 @@ int q6audio_get_port_index(u16 port_id)
case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
case SLIMBUS_4_RX: return IDX_SLIMBUS_4_RX;
case SLIMBUS_4_TX: return IDX_SLIMBUS_4_TX;
+ case SLIMBUS_TX_VI: return IDX_SLIMBUS_4_TX;
case SLIMBUS_5_RX: return IDX_SLIMBUS_5_RX;
case SLIMBUS_5_TX: return IDX_SLIMBUS_5_TX;
case SLIMBUS_6_RX: return IDX_SLIMBUS_6_RX;
@@ -311,6 +312,7 @@ int q6audio_get_port_id(u16 port_id)
case SLIMBUS_3_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX;
case SLIMBUS_4_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX;
case SLIMBUS_4_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX;
+ case SLIMBUS_TX_VI: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX;
case SLIMBUS_5_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX;
case SLIMBUS_5_TX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX;
case SLIMBUS_6_RX: return AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX;
@@ -688,6 +690,7 @@ int q6audio_validate_port(u16 port_id)
case SLIMBUS_3_TX:
case SLIMBUS_4_RX:
case SLIMBUS_4_TX:
+ case SLIMBUS_TX_VI:
case SLIMBUS_5_RX:
case SLIMBUS_5_TX:
case SLIMBUS_6_RX:
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index cc7616f1d897..9782fa26a2e9 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -193,6 +193,31 @@ void ocm_core_open(void)
pr_err("%s: Unable to register CORE\n", __func__);
}
+struct cal_block_data *cal_utils_get_cal_block_by_key(
+ struct cal_type_data *cal_type, uint32_t key)
+{
+ struct list_head *ptr, *next;
+ struct cal_block_data *cal_block = NULL;
+ struct audio_cal_info_metainfo *metainfo;
+
+ list_for_each_safe(ptr, next,
+ &cal_type->cal_blocks) {
+
+ cal_block = list_entry(ptr,
+ struct cal_block_data, list);
+ metainfo = (struct audio_cal_info_metainfo *)
+ cal_block->cal_info;
+ if (metainfo->nKey != key) {
+ pr_debug("%s: metainfo key mismatch!!! found:%x, needed:%x\n",
+ __func__, metainfo->nKey, key);
+ } else {
+ pr_debug("%s: metainfo key match found", __func__);
+ return cal_block;
+ }
+ }
+ return NULL;
+}
+
int32_t core_set_license(uint32_t key, uint32_t module_id)
{
struct avcs_cmd_set_license *cmd_setl = NULL;
@@ -210,8 +235,8 @@ int32_t core_set_license(uint32_t key, uint32_t module_id)
}
mutex_lock(&((q6core_lcl.cal_data[META_CAL])->lock));
- cal_block =
- cal_utils_get_only_cal_block(q6core_lcl.cal_data[META_CAL]);
+ cal_block = cal_utils_get_cal_block_by_key(
+ q6core_lcl.cal_data[META_CAL], key);
if (cal_block == NULL ||
cal_block->cal_data.kvaddr == NULL ||
cal_block->cal_data.size <= 0) {
@@ -219,21 +244,6 @@ int32_t core_set_license(uint32_t key, uint32_t module_id)
rc = -EINVAL;
goto cal_data_unlock;
}
- metainfo = (struct audio_cal_info_metainfo *)cal_block->cal_info;
- if (metainfo == NULL) {
- pr_err("%s: No metainfo!!!", __func__);
- rc = -EINVAL;
- goto cal_data_unlock;
- }
- if (metainfo->nKey != key) {
- pr_err("%s: metainfo key mismatch!!! found:%x, needed:%x\n",
- __func__, metainfo->nKey, key);
- rc = -EINVAL;
- goto cal_data_unlock;
- } else if (key == 0) {
- pr_err("%s: metainfo key is %d a invalid key", __func__, key);
- goto cal_data_unlock;
- }
packet_size = sizeof(struct avcs_cmd_set_license) +
cal_block->cal_data.size;
diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c
index 22468eee62db..8ce87195548e 100644
--- a/sound/usb/usb_audio_qmi_svc.c
+++ b/sound/usb/usb_audio_qmi_svc.c
@@ -495,9 +495,8 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
if (subs->sync_endpoint) {
ep = usb_pipe_endpoint(subs->dev, subs->sync_endpoint->pipe);
if (!ep) {
- pr_err("%s: sync ep # %d context is null\n", __func__,
- subs->sync_endpoint->ep_num);
- goto err;
+ pr_debug("%s: implicit fb on data ep\n", __func__);
+ goto skip_sync_ep;
}
memcpy(&resp->std_as_sync_ep_desc, &ep->desc, sizeof(ep->desc));
resp->std_as_sync_ep_desc_valid = 1;
@@ -511,6 +510,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
resp->xhci_mem_info.tr_sync.pa = xhci_pa;
}
+skip_sync_ep:
resp->interrupter_num = uaudio_qdev->intr_num;
resp->interrupter_num_valid = 1;