Merge "msm: ipc: Send Resume_Tx from the client/server context"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 3684a3f..d97d3c3 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -5,7 +5,11 @@
KERNEL_OUT := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ
KERNEL_CONFIG := $(KERNEL_OUT)/.config
+ifeq ($(TARGET_KERNEL_APPEND_DTB), true)
+TARGET_PREBUILT_INT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage-dtb
+else
TARGET_PREBUILT_INT_KERNEL := $(KERNEL_OUT)/arch/arm/boot/zImage
+endif
KERNEL_HEADERS_INSTALL := $(KERNEL_OUT)/usr
KERNEL_MODULES_INSTALL := system
KERNEL_MODULES_OUT := $(TARGET_OUT)/lib/modules
diff --git a/Documentation/devicetree/bindings/dma/sps/sps.txt b/Documentation/devicetree/bindings/dma/sps/sps.txt
index a979c56..26102c8 100644
--- a/Documentation/devicetree/bindings/dma/sps/sps.txt
+++ b/Documentation/devicetree/bindings/dma/sps/sps.txt
@@ -7,7 +7,11 @@
- compatible: should be "qcom,msm_sps"
Optional properties:
- - reg: offset and size of the register set in the memory map
+ - reg: offset and size for the memory mapping, including maps for
+ BAM DMA BAM, BAM DMA peripheral, pipe memory and reserved memory.
+ - reg-names: indicates various resources passed to driver (via reg
+ property) by name. "reg-names" examples are "bam_mem", "core_mem"
+ , "pipe_mem" and "res_mem".
- interrupts: IRQ line
- qcom,device-type: specify the device configuration of BAM DMA and
pipe memory. Can be one of
diff --git a/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt b/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt
new file mode 100644
index 0000000..aa50140
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/misc/stk-stk3x1x.txt
@@ -0,0 +1,46 @@
+Sensortek stk301x, stk321x and stk331x ambient light/proximity 3-in-1 sensor
+
+Required properties:
+
+ - compatible : Should be "stk,stk3x1x".
+ - reg : i2c slave address of the device.
+ - interrupt-parent : Parent of interrupt.
+ - interrupts : Sensor will issue interrupt when preset condition is met,
+ typically when proximity sensor detect a change on near/far state.
+ - vdd-supply : Main power supply to power sensor.
+ - vio-supply : Power supply required to pullup I2C bus.
+ - stk,irq-gpio : irq gpio which is to provide interrupts to host, same as
+ "interrupts" node.
+ - stk,transmittance : Transmittance rate of glass above the ambient light
+ detection window. The value may not be equal to real transmittance
+ but just a relative value.
+ - stk,state-reg : The default setting of state register.
+ - stk,psctrl-reg : The default setting for proximity sensor.
+ - stk,alsctrl-reg : The default setting for ambient light sensor.
+ - stk,ledctrl-reg : The default setting for IR LED.
+ - stk,wait-reg : The default setting for wait time.
+ - stk,ps-thdh : High threshold for proximity sensor, sensor will report
+ "near" if the proximity sensor reading is larger or equal to this
+ value.
+ - stk,ps-thdl : Low threshold for proximity sensor, sensor will report
+ "far" if the proximity sensor reading is larger than this value.
+
+Example:
+ i2c@f9925000 {
+ stk@48 {
+ compatible = "stk,stk3x1x";
+ reg = <0x48>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <80 0x2>;
+ vdd-supply = <&pm8110_l19>;
+ vio-supply = <&pm8110_l14>;
+ stk,irq-gpio = <&msmgpio 80 0x02>;
+ stk,transmittance = <500>;
+ stk,state-reg = <0x00>;
+ stk,psctrl-reg = <0x71>;
+ stk,alsctrl-reg = <0x38>;
+ stk,ledctrl-reg = <0xFF>;
+ stk,wait-reg = <0x07>;
+ stk,ps-thdh = <1700>;
+ stk,ps-thdl = <1500>;
+ };
diff --git a/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
index 72b32be..d848baf 100644
--- a/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-camera-flash.txt
@@ -13,6 +13,10 @@
- qcom,flash-source : Should contain array of phandles to flash source nodes.
- pm8941_flash0 pm8941_flash1
+Optional properties:
+-qcom,torch-source : Should contain phandle to torch source node.
+ -pm8941_torch
+
Example:
qcom,camera-led-flash {
@@ -20,4 +24,5 @@
compatible = "qcom,camera-led-flash";
qcom,flash-type = <1>;
qcom,flash-source = <&pm8941_flash0 &pm8941_flash1>;
+ qcom,torch-source = <&pm8941_torch>;
};
diff --git a/Documentation/devicetree/bindings/media/video/msm-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cci.txt
index b8156c3..c60441f 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cci.txt
@@ -49,6 +49,7 @@
Required properties:
- compatible : should be manufacturer name followed by sensor name
- "qcom,s5k3l1yx"
+ - "qcom,imx135"
- "shinetech,gc0339"
- "shinetech,hi256"
- "shinetech,s5k4e1"
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index a3a3807..527c50c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -42,6 +42,7 @@
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
+stk Sensortek Technology Corporation.(formerly Sitronix Technology Co., Ltd.)
shinetech Shine Tech Corporation, Ltd.
sil Silicon Image
simtek
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8226e43..69b2cd2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2015,6 +2015,21 @@
help
Include support for flattened device tree machine descriptions.
+config BUILD_ARM_APPENDED_DTB_IMAGE
+ bool "Build a concatenated zImage/dtb by default"
+ depends on OF
+ help
+ Enabling this option will cause a concatenated zImage and list of
+ DTBs to be built by default (instead of a standalone zImage.)
+ The image will built in arch/arm/boot/zImage-dtb
+
+config BUILD_ARM_APPENDED_DTB_IMAGE_NAMES
+ string "Default dtb names"
+ depends on BUILD_ARM_APPENDED_DTB_IMAGE
+ help
+ Space separated list of names of dtbs to append when
+ building a concatenated zImage-dtb.
+
# Compressed boot loader in ROM. Yes, we really want to ask about
# TEXT and BSS so we preserve their values in the config files.
config ZBOOT_ROM_TEXT
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2f2603f..d43e69bf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -261,6 +261,8 @@
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
KBUILD_IMAGE := xipImage
+else ifeq ($(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE),y)
+KBUILD_IMAGE := zImage-dtb
else
KBUILD_IMAGE := zImage
endif
@@ -292,6 +294,9 @@
dtbs: scripts
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+zImage-dtb: vmlinux scripts
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
@@ -306,7 +311,7 @@
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
echo ' uImage - U-Boot wrapped zImage'
- echo ' bootpImage - Combined zImage and initial RAM disk'
+ echo ' bootpImage - Combined zImage and initial RAM disk'
echo ' (supply initrd image via make variable INITRD=<path>)'
echo '* dtbs - Build device tree blobs for enabled boards'
echo ' install - Install uncompressed kernel'
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
index 3c79f85..ad7a025 100644
--- a/arch/arm/boot/.gitignore
+++ b/arch/arm/boot/.gitignore
@@ -4,3 +4,4 @@
bootpImage
uImage
*.dtb
+zImage-dtb
\ No newline at end of file
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index c877087..bc8ee6c 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -27,6 +27,14 @@
targets := Image zImage xipImage bootpImage uImage
+DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE_NAMES))
+ifneq ($(DTB_NAMES),)
+DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES))
+else
+DTB_LIST := $(dtb-y)
+endif
+DTB_OBJS := $(addprefix $(obj)/,$(DTB_LIST))
+
ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
@@ -55,15 +63,19 @@
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
+$(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS) FORCE
+ $(call if_changed,cat)
+ @echo ' Kernel: $@ is ready'
+
endif
-targets += $(dtb-y)
+targets += $(DTB_LIST)
# Rule to build device tree blobs
$(obj)/%.dtb: $(src)/dts/%.dts FORCE
$(call if_changed_dep,dtc)
-$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
+$(obj)/dtbs: $(DTB_OBJS)
clean-files := *.dtb
diff --git a/arch/arm/boot/dts/apq8026-v1-mtp.dts b/arch/arm/boot/dts/apq8026-v1-mtp.dts
index b89c676..7900ddf 100644
--- a/arch/arm/boot/dts/apq8026-v1-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-v1-mtp.dts
@@ -20,3 +20,10 @@
compatible = "qcom,apq8026-mtp", "qcom,apq8026", "qcom,mtp";
qcom,msm-id = <199 8 0>;
};
+
+&cci {
+ /* Rotate rear camera to 0 degrees */
+ qcom,camera@6f {
+ qcom,mount-angle = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/apq8084-coresight.dtsi b/arch/arm/boot/dts/apq8084-coresight.dtsi
index 6cd238a..22c260f 100644
--- a/arch/arm/boot/dts/apq8084-coresight.dtsi
+++ b/arch/arm/boot/dts/apq8084-coresight.dtsi
@@ -348,4 +348,29 @@
coresight-name = "coresight-cti-cpu3";
coresight-nr-inports = <0>;
};
+
+ hwevent: hwevent@fd828018 {
+ compatible = "qcom,coresight-hwevent";
+ reg = <0xfd828018 0x80>,
+ <0xf9011080 0x80>,
+ <0xfd4ab160 0x80>,
+ <0xfc401600 0x80>;
+ reg-names = "mmss-mux", "apcs-mux", "ppss-mux", "gcc-mux";
+
+ coresight-id = <29>;
+ coresight-name = "coresight-hwevent";
+ coresight-nr-inports = <0>;
+
+ qcom,hwevent-clks = "core_mmss_clk";
+ };
+
+ fuse: fuse@fc4be024 {
+ compatible = "arm,coresight-fuse";
+ reg = <0xfc4be024 0x8>;
+ reg-names = "fuse-base";
+
+ coresight-id = <30>;
+ coresight-name = "coresight-fuse";
+ coresight-nr-inports = <0>;
+ };
};
diff --git a/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi
new file mode 100644
index 0000000..5b7cc79
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-nt35521-720p-video.dtsi
@@ -0,0 +1,275 @@
+/* Copyright (c) 2013, 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.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+&soc {
+ qcom,mdss_dsi_nt35521_720p_video {
+ compatible = "qcom,mdss-dsi-panel";
+ status = "disable";
+ qcom,mdss-dsi-panel-name = "nt35521 720p video mode dsi panel";
+ qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+ qcom,mdss-dsi-panel-type = "dsi_video_mode";
+ qcom,mdss-dsi-panel-destination = "display_1";
+ qcom,mdss-dsi-panel-framerate = <60>;
+ qcom,mdss-dsi-virtual-channel-id = <0>;
+ qcom,mdss-dsi-stream = <0>;
+ qcom,mdss-dsi-panel-width = <720>;
+ qcom,mdss-dsi-panel-height = <1280>;
+ qcom,mdss-dsi-h-front-porch = <44>;
+ qcom,mdss-dsi-h-back-porch = <55>;
+ qcom,mdss-dsi-h-pulse-width = <11>;
+ qcom,mdss-dsi-h-sync-skew = <0>;
+ qcom,mdss-dsi-v-back-porch = <15>;
+ qcom,mdss-dsi-v-front-porch = <14>;
+ qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-h-left-border = <0>;
+ qcom,mdss-dsi-h-right-border = <0>;
+ qcom,mdss-dsi-v-top-border = <0>;
+ qcom,mdss-dsi-v-bottom-border = <0>;
+ qcom,mdss-dsi-bpp = <24>;
+ qcom,mdss-dsi-color-order = <0>;
+ qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-border-color = <0>;
+ qcom,mdss-dsi-pixel-packing = <0>;
+ qcom,mdss-dsi-on-command = [29 01 00 00 00 00 06 F0 55 AA 52 08 00
+ 29 01 00 00 00 00 03 B1 68 21
+ 23 01 00 00 00 00 02 B5 C8
+ 29 01 00 00 00 00 02 B6 0F
+ 29 01 00 00 00 00 05 B8 00 00 0A 00
+ 23 01 00 00 00 00 02 B9 00
+ 23 01 00 00 00 00 02 BA 02
+ 29 01 00 00 00 00 03 BB 63 63
+ 29 01 00 00 00 00 03 BC 00 00
+ 29 01 00 00 00 00 06 BD 02 7F 0D 0B 00
+ 29 01 00 00 00 00 11 CC 41 36 87 54 46 65 10 12 14 10 12 14 40 08 15 05
+ 23 01 00 00 00 00 02 D0 00
+ 29 01 00 00 00 00 11 D1 00 04 08 0C 10 14 18 1C 20 24 28 2C 30 34 38 3C
+ 23 01 00 00 00 00 02 D3 00
+ 29 01 00 00 00 00 03 D6 44 44
+ 29 01 00 00 00 00 0D D7 00 00 00 00 00 00 00 00 00 00 00 00
+ 29 01 00 00 00 00 0E D8 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 29 01 00 00 00 00 03 D9 00 28
+ 29 01 00 00 00 00 03 E5 00 FF
+ 29 01 00 00 00 00 05 E6 F3 EC E7 DF
+ 29 01 00 00 00 00 0B E7 F3 D9 CC CD B3 A6 99 99 99 95
+ 29 01 00 00 00 00 0B E8 F3 D9 CC CD B3 A6 99 99 99 95
+ 29 01 00 00 00 00 03 E9 00 04
+ 23 01 00 00 00 00 02 EA 00
+ 29 01 00 00 00 00 05 EE 87 78 00 00
+ 29 01 00 00 00 00 03 EF 07 FF
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 01
+ 29 01 00 00 00 00 03 B0 0D 0D
+ 29 01 00 00 00 00 03 B1 0D 0D
+ 29 01 00 00 00 00 03 B3 2D 2D
+ 29 01 00 00 00 00 03 B4 19 19
+ 29 01 00 00 00 00 03 B5 06 06
+ 29 01 00 00 00 00 03 B6 05 05
+ 29 01 00 00 00 00 03 B7 05 05
+ 29 01 00 00 00 00 03 B8 05 05
+ 29 01 00 00 00 00 03 B9 44 44
+ 29 01 00 00 00 00 03 BA 36 36
+ 29 01 00 00 00 00 03 BC 50 00
+ 29 01 00 00 00 00 03 BD 50 00
+ 23 01 00 00 00 00 02 BE 39
+ 23 01 00 00 00 00 02 BF 39
+ 23 01 00 00 00 00 02 C0 0C
+ 23 01 00 00 00 00 02 C1 00
+ 29 01 00 00 00 00 03 C2 19 19
+ 29 01 00 00 00 00 03 C3 0A 0A
+ 29 01 00 00 00 00 03 C4 23 23
+ 29 01 00 00 00 00 04 C7 00 80 00
+ 29 01 00 00 00 00 07 C9 00 00 00 00 00 00
+ 23 01 00 00 00 00 02 CA 01
+ 29 01 00 00 00 00 03 CB 0B 53
+ 23 01 00 00 00 00 02 CC 00
+ 29 01 00 00 00 00 04 CD 0B 52 53
+ 23 01 00 00 00 00 02 CE 44
+ 29 01 00 00 00 00 04 CF 00 50 50
+ 29 01 00 00 00 00 03 D0 50 50
+ 29 01 00 00 00 00 03 D1 50 50
+ 23 01 00 00 00 00 02 D2 39
+ 23 01 00 00 00 00 02 D3 39
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 02
+ 29 01 00 00 00 00 11 B0 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 B1 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 B2 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 B3 03 CC 03 CC
+ 29 01 00 00 00 00 11 B4 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 B5 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 B6 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 B7 03 CC 03 CC
+ 29 01 00 00 00 00 11 B8 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 B9 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 BA 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 BB 03 CC 03 CC
+ 29 01 00 00 00 00 11 BC 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 BD 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 BE 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 BF 03 CC 03 CC
+ 29 01 00 00 00 00 11 C0 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 C1 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 C2 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 C3 03 CC 03 CC
+ 29 01 00 00 00 00 11 C4 00 AC 00 BA 00 D9 00 ED 01 01 01 1E 01 3A 01 62
+ 29 01 00 00 00 00 11 C5 01 85 01 B8 01 E4 02 27 02 5B 02 5D 02 8C 02 BE
+ 29 01 00 00 00 00 11 C6 02 DF 03 0C 03 2A 03 51 03 6D 03 8D 03 A4 03 BE
+ 29 01 00 00 00 00 05 C7 03 CC 03 CC
+ 23 01 00 00 00 00 02 EE 00
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 03
+ 29 01 00 00 00 00 03 B0 00 00
+ 29 01 00 00 00 00 03 B1 00 00
+ 29 01 00 00 00 00 06 B2 03 00 00 00 00
+ 29 01 00 00 00 00 06 B3 03 00 00 00 00
+ 29 01 00 00 00 00 06 B4 03 00 00 00 00
+ 29 01 00 00 00 00 06 B5 03 00 00 00 00
+ 29 01 00 00 00 00 06 B6 03 00 00 00 00
+ 29 01 00 00 00 00 06 B7 03 00 00 00 00
+ 29 01 00 00 00 00 06 B8 03 00 00 00 00
+ 29 01 00 00 00 00 06 B9 03 00 00 00 00
+ 29 01 00 00 00 00 06 BA 35 10 00 00 00
+ 29 01 00 00 00 00 06 BB 35 10 00 00 00
+ 29 01 00 00 00 00 06 BC 35 10 00 00 00
+ 29 01 00 00 00 00 06 BD 35 10 00 00 00
+ 29 01 00 00 00 00 05 C0 00 34 00 00
+ 29 01 00 00 00 00 05 C1 00 34 00 00
+ 29 01 00 00 00 00 05 C2 00 34 00 00
+ 29 01 00 00 00 00 05 C3 00 34 00 00
+ 23 01 00 00 00 00 02 C4 40
+ 23 01 00 00 00 00 02 C5 40
+ 23 01 00 00 00 00 02 C6 40
+ 23 01 00 00 00 00 02 C7 40
+ 23 01 00 00 00 00 02 EF 00
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 05
+ 29 01 00 00 00 00 03 B0 1B 10
+ 29 01 00 00 00 00 03 B1 1B 10
+ 29 01 00 00 00 00 03 B2 1B 10
+ 29 01 00 00 00 00 03 B3 1B 10
+ 29 01 00 00 00 00 03 B4 1B 10
+ 29 01 00 00 00 00 03 B5 1B 10
+ 29 01 00 00 00 00 03 B6 1B 10
+ 29 01 00 00 00 00 03 B7 1B 10
+ 23 01 00 00 00 00 02 B8 00
+ 23 01 00 00 00 00 02 B9 00
+ 23 01 00 00 00 00 02 BA 00
+ 23 01 00 00 00 00 02 BB 00
+ 23 01 00 00 00 00 02 BC 00
+ 29 01 00 00 00 00 06 BD 03 03 03 00 01
+ 23 01 00 00 00 00 02 C0 03
+ 23 01 00 00 00 00 02 C1 05
+ 23 01 00 00 00 00 02 C2 03
+ 23 01 00 00 00 00 02 C3 05
+ 23 01 00 00 00 00 02 C4 80
+ 23 01 00 00 00 00 02 C5 A2
+ 23 01 00 00 00 00 02 C6 80
+ 23 01 00 00 00 00 02 C7 A2
+ 29 01 00 00 00 00 03 C8 01 20
+ 29 01 00 00 00 00 03 C9 00 20
+ 29 01 00 00 00 00 03 CA 01 00
+ 29 01 00 00 00 00 03 CB 00 00
+ 29 01 00 00 00 00 04 CC 00 00 01
+ 29 01 00 00 00 00 04 CD 00 00 01
+ 29 01 00 00 00 00 04 CE 00 00 01
+ 29 01 00 00 00 00 04 CF 00 00 01
+ 23 01 00 00 00 00 02 D0 00
+ 29 01 00 00 00 00 06 D1 03 00 00 07 10
+ 29 01 00 00 00 00 06 D2 13 00 00 07 11
+ 29 01 00 00 00 00 06 D3 23 00 00 07 10
+ 29 01 00 00 00 00 06 D4 33 00 00 07 11
+ 23 01 00 00 00 00 02 E5 06
+ 23 01 00 00 00 00 02 E6 06
+ 23 01 00 00 00 00 02 E7 06
+ 23 01 00 00 00 00 02 E8 06
+ 23 01 00 00 00 00 02 E9 06
+ 23 01 00 00 00 00 02 EA 06
+ 23 01 00 00 00 00 02 EB 06
+ 23 01 00 00 00 00 02 EC 06
+ 23 01 00 00 00 00 02 ED 31
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 06
+ 29 01 00 00 00 00 03 B0 10 11
+ 29 01 00 00 00 00 03 B1 12 13
+ 29 01 00 00 00 00 03 B2 08 00
+ 29 01 00 00 00 00 03 B3 2D 2D
+ 29 01 00 00 00 00 03 B4 2D 34
+ 29 01 00 00 00 00 03 B5 34 2D
+ 29 01 00 00 00 00 03 B6 2D 34
+ 29 01 00 00 00 00 03 B7 34 34
+ 29 01 00 00 00 00 03 B8 02 0A
+ 29 01 00 00 00 00 03 B9 00 08
+ 29 01 00 00 00 00 03 BA 09 01
+ 29 01 00 00 00 00 03 BB 0B 03
+ 29 01 00 00 00 00 03 BC 34 34
+ 29 01 00 00 00 00 03 BD 34 2D
+ 29 01 00 00 00 00 03 BE 2D 34
+ 29 01 00 00 00 00 03 BF 34 2D
+ 29 01 00 00 00 00 03 C0 2D 2D
+ 29 01 00 00 00 00 03 C1 01 09
+ 29 01 00 00 00 00 03 C2 19 18
+ 29 01 00 00 00 00 03 C3 17 16
+ 29 01 00 00 00 00 03 C4 19 18
+ 29 01 00 00 00 00 03 C5 17 16
+ 29 01 00 00 00 00 03 C6 01 09
+ 29 01 00 00 00 00 03 C7 2D 2D
+ 29 01 00 00 00 00 03 C8 2D 34
+ 29 01 00 00 00 00 03 C9 34 2D
+ 29 01 00 00 00 00 03 CA 2D 34
+ 29 01 00 00 00 00 03 CB 34 34
+ 29 01 00 00 00 00 03 CC 0B 03
+ 29 01 00 00 00 00 03 CD 09 01
+ 29 01 00 00 00 00 03 CE 00 08
+ 29 01 00 00 00 00 03 CF 02 0A
+ 29 01 00 00 00 00 03 D0 34 34
+ 29 01 00 00 00 00 03 D1 34 2D
+ 29 01 00 00 00 00 03 D2 2D 34
+ 29 01 00 00 00 00 03 D3 34 2D
+ 29 01 00 00 00 00 03 D4 2D 2D
+ 29 01 00 00 00 00 03 D5 08 00
+ 29 01 00 00 00 00 03 D6 10 11
+ 29 01 00 00 00 00 03 D7 12 13
+ 29 01 00 00 00 00 06 D8 55 55 55 55 55
+ 29 01 00 00 00 00 06 D9 55 55 55 55 55
+ 29 01 00 00 00 00 03 E5 34 34
+ 29 01 00 00 00 00 03 E6 34 34
+ 23 01 00 00 00 00 02 E7 05
+ 29 01 00 00 00 00 06 F0 55 AA 52 00 00
+ 05 01 00 00 32 00 02 11 00
+ 05 01 00 00 96 00 02 29 00
+ 29 01 00 00 00 00 06 F0 55 AA 52 08 01
+ 29 01 00 00 00 00 06 F0 55 AA 52 00 00
+ 29 01 00 00 00 00 02 53 2C];
+ qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
+ 05 01 00 00 78 00 02 10 00];
+ qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+ qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-h-sync-pulse = <1>;
+ qcom,mdss-dsi-traffic-mode = <2>;
+ qcom,mdss-dsi-lane-map = <0>;
+ qcom,mdss-dsi-bllp-eof-power-mode;
+ qcom,mdss-dsi-bllp-power-mode;
+ qcom,mdss-dsi-lane-0-state;
+ qcom,mdss-dsi-lane-1-state;
+ qcom,mdss-dsi-lane-2-state;
+ qcom,mdss-dsi-lane-3-state;
+ qcom,mdss-dsi-panel-timings = [93 1F 17 00 2F 2E 1C 21 26 03 04 00];
+ qcom,mdss-dsi-t-clk-post = <0x20>;
+ qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <255>;
+ qcom,mdss-dsi-dma-trigger = <4>;
+ qcom,mdss-dsi-mdp-trigger = <0>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs";
+
+ };
+};
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 52bcb2c..9a37316 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -229,6 +229,15 @@
qcom,current-limit = <800>;
};
+ qcom,sps@f9980000 {
+ compatible = "qcom,msm_sps";
+ reg = <0xf9984000 0x15000>,
+ <0xf9999000 0xb000>;
+ reg-names = "bam_mem", "core_mem";
+ interrupts = <0 94 0>;
+ qcom,pipe-attr-ee;
+ };
+
sata: sata@fc580000 {
compatible = "qcom,msm-ahci";
reg = <0xfc580000 0x17c>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index d4b605b..f807814 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -68,6 +68,47 @@
qcom,cci-master = <0>;
};
+ qcom,camera@20 {
+ compatible = "qcom,imx135";
+ reg = <0x20>;
+ qcom,slave-id = <0x20 0x0016 0x0135>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "imx135";
+ cam_vdig-supply = <&pm8226_l5>;
+ cam_vana-supply = <&pm8226_l19>;
+ cam_vio-supply = <&pm8226_lvs1>;
+ cam_vaf-supply = <&pm8226_l15>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ gpios = <&msmgpio 26 0>,
+ <&msmgpio 37 0>,
+ <&msmgpio 36 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 30000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x1F>;
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,sensor-type = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ };
+
qcom,camera@6d {
compatible = "qcom,ov9724";
reg = <0x6d>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index 53860ac..56e8a09 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -38,7 +38,7 @@
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
- qcom,mount-angle = <0>;
+ qcom,mount-angle = <90>;
qcom,sensor-name = "ov8825";
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
diff --git a/arch/arm/boot/dts/msm8226-sim.dts b/arch/arm/boot/dts/msm8226-sim.dts
index 2405646..1da94b3 100644
--- a/arch/arm/boot/dts/msm8226-sim.dts
+++ b/arch/arm/boot/dts/msm8226-sim.dts
@@ -12,7 +12,6 @@
/dts-v1/;
/include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
/ {
model = "Qualcomm MSM 8226 Simulator";
diff --git a/arch/arm/boot/dts/msm8226-v1-mtp.dts b/arch/arm/boot/dts/msm8226-v1-mtp.dts
index b1d46b1..6f03dca 100644
--- a/arch/arm/boot/dts/msm8226-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-mtp.dts
@@ -23,3 +23,10 @@
<198 8 0>,
<205 8 0>;
};
+
+&cci {
+ /* Rotate rear camera to 0 degrees */
+ qcom,camera@6f {
+ qcom,mount-angle = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
index 936f87f..3e0e4e4 100644
--- a/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v1-qrd-skuf.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8226-v1.dtsi"
/include/ "msm8226-qrd.dtsi"
-/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "dsi-panel-nt35521-720p-video.dtsi"
/ {
model = "Qualcomm MSM 8226 QRD";
@@ -26,9 +26,9 @@
};
&soc {
- qcom,mdss_dsi_nt35590_720p_video {
+ qcom,mdss_dsi_nt35521_720p_video {
status = "ok";
- qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
+ qcom,cont-splash-enabled;
};
sound {
diff --git a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
index b34fb94..0a4657d 100644
--- a/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
+++ b/arch/arm/boot/dts/msm8226-v2-qrd-skuf.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8226-v2.dtsi"
/include/ "msm8226-qrd.dtsi"
-/include/ "dsi-panel-nt35590-720p-video.dtsi"
+/include/ "dsi-panel-nt35521-720p-video.dtsi"
/ {
model = "Qualcomm MSM 8226v2 QRD";
@@ -27,9 +27,9 @@
};
&soc {
- qcom,mdss_dsi_nt35590_720p_video {
+ qcom,mdss_dsi_nt35521_720p_video {
status = "ok";
- qcom,mdss-pan-bl-ctrl = "bl_ctrl_dcs";
+ qcom,cont-splash-enabled;
};
sound {
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index 1dab78a..2b3b7c2 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -17,7 +17,6 @@
*/
/include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
&pm8226_l3 {
regulator-min-microvolt = <750000>;
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index f46b714..013da90a 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -17,7 +17,6 @@
*/
/include/ "msm8226.dtsi"
-/include/ "msm8226-camera.dtsi"
/ {
model = "Qualcomm MSM 8926";
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index fa57244..9badf6d 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -271,11 +271,11 @@
qcom,default-state = "on";
qcom,max-current = <25>;
qcom,ctrl-delay-us = <0>;
- qcom,boost-curr-lim = <3>;
+ qcom,boost-curr-lim = <5>;
qcom,cp-sel = <0>;
qcom,switch-freq = <11>;
qcom,ovp-val = <2>;
- qcom,num-strings = <1>;
+ qcom,num-strings = <3>;
qcom,id = <0>;
};
};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 3d20f7c..9c2509a 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -269,11 +269,11 @@
qcom,default-state = "on";
qcom,max-current = <25>;
qcom,ctrl-delay-us = <0>;
- qcom,boost-curr-lim = <3>;
+ qcom,boost-curr-lim = <5>;
qcom,cp-sel = <0>;
qcom,switch-freq = <11>;
qcom,ovp-val = <2>;
- qcom,num-strings = <1>;
+ qcom,num-strings = <3>;
qcom,id = <0>;
};
};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index c1a8792..6955597 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -210,11 +210,11 @@
qcom,default-state = "on";
qcom,max-current = <25>;
qcom,ctrl-delay-us = <0>;
- qcom,boost-curr-lim = <3>;
+ qcom,boost-curr-lim = <5>;
qcom,cp-sel = <0>;
qcom,switch-freq = <11>;
qcom,ovp-val = <2>;
- qcom,num-strings = <1>;
+ qcom,num-strings = <3>;
qcom,id = <0>;
};
};
diff --git a/arch/arm/boot/dts/msmsamarium-regulator.dtsi b/arch/arm/boot/dts/msmsamarium-regulator.dtsi
new file mode 100644
index 0000000..ae4dc8d
--- /dev/null
+++ b/arch/arm/boot/dts/msmsamarium-regulator.dtsi
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/* QPNP controlled regulators: */
+
+&spmi_bus {
+ qcom,pma8084@1 {
+ pma8084_s1: regulator@1400 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ /* PMA8084 S2 + S12 = 2 phase VDD_CX supply */
+ pma8084_s2: regulator@1700 {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_s3: regulator@1a00 {
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_s4: regulator@1d00 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ /* Output of PMA8084 S5 and L25 is tied together. */
+ pma8084_s5: regulator@2000 {
+ regulator-min-microvolt = <2150000>;
+ regulator-max-microvolt = <2150000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_s6: regulator@2300 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_s7: regulator@2600 {
+ regulator-min-microvolt = <815000>;
+ regulator-max-microvolt = <900000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_s8: regulator@2900 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_s9: regulator@2c00 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_s10: regulator@2f00 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_s11: regulator@3200 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,enable-time = <500>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <100000>;
+ status = "okay";
+ };
+
+ pma8084_l1: regulator@4000 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ regulator-always-on;
+ qcom,system-load = <10000>;
+ status = "okay";
+ };
+
+ pma8084_l2: regulator@4100 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1175000>;
+ regulator-max-microvolt = <1175000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l3: regulator@4200 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l4: regulator@4300 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1225000>;
+ regulator-max-microvolt = <1225000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l6: regulator@4500 {
+ parent-supply = <&pma8084_s5>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l8: regulator@4700 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l9: regulator@4800 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l10: regulator@4900 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l11: regulator@4a00 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l12: regulator@4b00 {
+ parent-supply = <&pma8084_s5>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l13: regulator@4c00 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l14: regulator@4d00 {
+ parent-supply = <&pma8084_s5>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l15: regulator@4e00 {
+ parent-supply = <&pma8084_s5>;
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l16: regulator@4f00 {
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l17: regulator@5000 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l18: regulator@5100 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l19: regulator@5200 {
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l20: regulator@5300 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l21: regulator@5400 {
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l22: regulator@5500 {
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l23: regulator@5600 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l24: regulator@5700 {
+ regulator-min-microvolt = <3075000>;
+ regulator-max-microvolt = <3075000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l26: regulator@5900 {
+ parent-supply = <&pma8084_s5>;
+ regulator-min-microvolt = <2050000>;
+ regulator-max-microvolt = <2050000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_l27: regulator@5a00 {
+ parent-supply = <&pma8084_s3>;
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_lvs1: regulator@8000 {
+ parent-supply = <&pma8084_s4>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_lvs2: regulator@8100 {
+ parent-supply = <&pma8084_s4>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_lvs3: regulator@8200 {
+ parent-supply = <&pma8084_s4>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_lvs4: regulator@8300 {
+ parent-supply = <&pma8084_s4>;
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+
+ pma8084_mvs1: regulator@8400 {
+ qcom,enable-time = <200>;
+ qcom,pull-down-enable = <1>;
+ status = "okay";
+ };
+ };
+};
+
+&soc {
+ pma8084_s2_corner: s2_corner_vreg {
+ compatible = "qcom,stub-regulator";
+ regulator-name = "8084_s2_corner";
+ regulator-min-microvolt = <1>;
+ regulator-max-microvolt = <7>;
+ qcom,hpm-min-load = <100000>;
+ qcom,consumer-supplies = "vdd_dig", "";
+ };
+};
diff --git a/arch/arm/boot/dts/msmsamarium.dtsi b/arch/arm/boot/dts/msmsamarium.dtsi
index d76c2c1..a492561 100644
--- a/arch/arm/boot/dts/msmsamarium.dtsi
+++ b/arch/arm/boot/dts/msmsamarium.dtsi
@@ -257,3 +257,4 @@
};
/include/ "msm-pma8084.dtsi"
+/include/ "msmsamarium-regulator.dtsi"
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 4315d3f..f4ad0c4 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -402,9 +402,11 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_FUSE=y
CONFIG_CORESIGHT_TMC=y
CONFIG_CORESIGHT_FUNNEL=y
CONFIG_CORESIGHT_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_HWEVENT=y
CONFIG_CORESIGHT_ETM=y
CONFIG_USB_BAM=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index f2f6558..7901e93 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -480,3 +480,4 @@
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 71742a5..8520f23 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -514,3 +514,4 @@
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index cd71104..e4a647f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -24,7 +24,7 @@
obj-y += acpuclock.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_trace_counters.o
-obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o
+obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o clock-krait.o
ifdef CONFIG_ARCH_MSM_KRAIT
obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o
endif
diff --git a/arch/arm/mach-msm/board-samarium.c b/arch/arm/mach-msm/board-samarium.c
index 9f865a9..52a947b 100644
--- a/arch/arm/mach-msm/board-samarium.c
+++ b/arch/arm/mach-msm/board-samarium.c
@@ -36,6 +36,10 @@
#include "modem_notifier.h"
static struct clk_lookup msm_clocks_dummy[] = {
+ CLK_DUMMY("xo", CXO_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("bus_clk", MSS_BIMC_Q6_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("iface_clk", MSS_CFG_AHB_CLK, "fc880000.qcom,mss", OFF),
+ CLK_DUMMY("mem_clk", BOOT_ROM_AHB_CLK, "fc880000.qcom,mss", OFF),
CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
CLK_DUMMY("core_clk", SDC1_CLK, "msm_sdcc.1", OFF),
diff --git a/arch/arm/mach-msm/clock-8084.c b/arch/arm/mach-msm/clock-8084.c
index fd1714c..939a637 100644
--- a/arch/arm/mach-msm/clock-8084.c
+++ b/arch/arm/mach-msm/clock-8084.c
@@ -415,6 +415,7 @@
CLK_DUMMY("core_clk", qdss_clk.c, "fc342000.cti", OFF),
CLK_DUMMY("core_clk", qdss_clk.c, "fc343000.cti", OFF),
CLK_DUMMY("core_clk", qdss_clk.c, "fc344000.cti", OFF),
+ CLK_DUMMY("core_clk", qdss_clk.c, "fd828018.hwevent", OFF),
CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc326000.tmc", OFF),
CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc324000.replicator", OFF),
@@ -444,6 +445,10 @@
CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc342000.cti", OFF),
CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc343000.cti", OFF),
CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fc344000.cti", OFF),
+ CLK_DUMMY("core_a_clk", qdss_a_clk.c, "fd828018.hwevent", OFF),
+
+ CLK_DUMMY("core_mmss_clk", mmss_misc_ahb_clk.c, "fd828018.hwevent",
+ OFF),
CLK_DUMMY("iface_clk", gcc_prng_ahb_clk.c,
"f9bff000.qcom,msm-rng", OFF),
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 383af54..8a79687 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3389,11 +3389,13 @@
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6d.qcom,camera"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6a.qcom,camera"),
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6f.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "90.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6d.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6a.qcom,camera"),
CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6c.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
/* eeprom clocks */
CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,eeprom"),
diff --git a/arch/arm/mach-msm/clock-krait.c b/arch/arm/mach-msm/clock-krait.c
new file mode 100644
index 0000000..b96ba62
--- /dev/null
+++ b/arch/arm/mach-msm/clock-krait.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+
+#include <linux/clk.h>
+#include <mach/clk-provider.h>
+#include <mach/clk.h>
+#include <mach/clock-generic.h>
+#include <mach/msm-krait-l2-accessors.h>
+#include "clock-krait.h"
+#include "avs.h"
+
+static DEFINE_SPINLOCK(kpss_clock_reg_lock);
+
+static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
+{
+ unsigned long flags;
+ u32 regval;
+
+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+ regval = get_l2_indirect_reg(mux->offset);
+ regval &= ~(mux->mask << mux->shift);
+ regval |= (sel & mux->mask) << mux->shift;
+ set_l2_indirect_reg(mux->offset, regval);
+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+
+ /* Wait for switch to complete. */
+ mb();
+ udelay(1);
+}
+static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
+{
+ mux->en_mask = sel;
+ if (mux->c.count)
+ __kpss_mux_set_sel(mux, sel);
+ return 0;
+}
+
+static int kpss_mux_get_sel(struct mux_clk *mux)
+{
+ u32 sel;
+
+ sel = get_l2_indirect_reg(mux->offset);
+ sel >>= mux->shift;
+ sel &= mux->mask;
+ mux->en_mask = sel;
+
+ return sel;
+}
+
+static int kpss_mux_enable(struct mux_clk *mux)
+{
+ __kpss_mux_set_sel(mux, mux->en_mask);
+ return 0;
+}
+
+static void kpss_mux_disable(struct mux_clk *mux)
+{
+ __kpss_mux_set_sel(mux, mux->safe_sel);
+}
+
+struct clk_mux_ops clk_mux_ops_kpss = {
+ .enable = kpss_mux_enable,
+ .disable = kpss_mux_disable,
+ .set_mux_sel = kpss_mux_set_sel,
+ .get_mux_sel = kpss_mux_get_sel,
+};
+
+/*
+ * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
+ * force it to div-2 during handoff and treat it like a fixed div-2 clock.
+ */
+static int kpss_div2_get_div(struct div_clk *div)
+{
+ unsigned long flags;
+ u32 regval;
+ int val;
+
+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+ regval = get_l2_indirect_reg(div->offset);
+ val = (regval >> div->shift) && div->mask;
+ regval &= ~(div->mask << div->shift);
+ set_l2_indirect_reg(div->offset, regval);
+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+
+ val = (val + 1) * 2;
+ WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
+ div->c.dbg_name, val);
+
+ return 2;
+}
+
+struct clk_div_ops clk_div_ops_kpss_div2 = {
+ .get_div = kpss_div2_get_div,
+};
+
+#define LOCK_BIT BIT(16)
+
+/* Initialize a HFPLL at a given rate and enable it. */
+static void __hfpll_clk_init_once(struct clk *c)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+
+ if (likely(h->init_done))
+ return;
+
+ /* Configure PLL parameters for integer mode. */
+ writel_relaxed(hd->config_val, h->base + hd->config_offset);
+ writel_relaxed(0, h->base + hd->m_offset);
+ writel_relaxed(1, h->base + hd->n_offset);
+
+ if (hd->user_offset) {
+ u32 regval = hd->user_val;
+ unsigned long rate;
+
+ rate = readl_relaxed(h->base + hd->l_offset) * h->src_rate;
+
+ /* Pick the right VCO. */
+ if (rate > hd->low_vco_max_rate)
+ regval |= hd->user_vco_mask;
+ writel_relaxed(regval, h->base + hd->user_offset);
+ }
+
+ if (hd->droop_offset)
+ writel_relaxed(hd->droop_val, h->base + hd->droop_offset);
+
+ h->init_done = true;
+}
+
+/* Enable an already-configured HFPLL. */
+static int hfpll_clk_enable(struct clk *c)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+
+ if (!h->base)
+ return -ENODEV;
+
+ __hfpll_clk_init_once(c);
+
+ /* Disable PLL bypass mode. */
+ writel_relaxed(0x2, h->base + hd->mode_offset);
+
+ /*
+ * H/W requires a 5us delay between disabling the bypass and
+ * de-asserting the reset. Delay 10us just to be safe.
+ */
+ mb();
+ udelay(10);
+
+ /* De-assert active-low PLL reset. */
+ writel_relaxed(0x6, h->base + hd->mode_offset);
+
+ /* Wait for PLL to lock. */
+ if (hd->status_offset) {
+ while (!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT))
+ ;
+ } else {
+ mb();
+ udelay(60);
+ }
+
+ /* Enable PLL output. */
+ writel_relaxed(0x7, h->base + hd->mode_offset);
+
+ /* Make sure the enable is done before returning. */
+ mb();
+
+ return 0;
+}
+
+static void hfpll_clk_disable(struct clk *c)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+
+ /*
+ * Disable the PLL output, disable test mode, enable the bypass mode,
+ * and assert the reset.
+ */
+ writel_relaxed(0, h->base + hd->mode_offset);
+}
+
+static long hfpll_clk_round_rate(struct clk *c, unsigned long rate)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+ unsigned long rrate;
+
+ if (!h->src_rate)
+ return 0;
+
+ rate = max(rate, hd->min_rate);
+ rate = min(rate, hd->max_rate);
+
+ rrate = DIV_ROUND_UP(rate, h->src_rate) * h->src_rate;
+ if (rrate > hd->max_rate)
+ rrate -= h->src_rate;
+
+ return rrate;
+}
+
+/*
+ * For optimization reasons, assumes no downstream clocks are actively using
+ * it.
+ */
+static int hfpll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+ unsigned long flags;
+ u32 l_val;
+
+ if (!h->base)
+ return -ENODEV;
+
+ if (rate != hfpll_clk_round_rate(c, rate))
+ return -EINVAL;
+
+ l_val = rate / h->src_rate;
+
+ spin_lock_irqsave(&c->lock, flags);
+
+ if (c->count)
+ hfpll_clk_disable(c);
+
+ /* Pick the right VCO. */
+ if (hd->user_offset) {
+ u32 regval;
+ regval = readl_relaxed(h->base + hd->user_offset);
+ if (rate <= hd->low_vco_max_rate)
+ regval &= ~hd->user_vco_mask;
+ else
+ regval |= hd->user_vco_mask;
+ writel_relaxed(regval, h->base + hd->user_offset);
+ }
+
+ writel_relaxed(l_val, h->base + hd->l_offset);
+
+ if (c->count)
+ hfpll_clk_enable(c);
+
+ spin_unlock_irqrestore(&c->lock, flags);
+
+ return 0;
+}
+
+static enum handoff hfpll_clk_handoff(struct clk *c)
+{
+ struct hfpll_clk *h = to_hfpll_clk(c);
+ struct hfpll_data const *hd = h->d;
+ u32 l_val, mode;
+
+ if (!hd)
+ return HANDOFF_DISABLED_CLK;
+
+ if (!h->base)
+ return HANDOFF_DISABLED_CLK;
+
+ /* Assume parent rate doesn't change and cache it. */
+ h->src_rate = clk_get_rate(c->parent);
+ l_val = readl_relaxed(h->base + hd->l_offset);
+ c->rate = l_val * h->src_rate;
+
+ mode = readl_relaxed(h->base + hd->mode_offset) & 0x7;
+ if (mode != 0x7) {
+ __hfpll_clk_init_once(c);
+ return HANDOFF_DISABLED_CLK;
+ }
+
+ if (hd->status_offset &&
+ !(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT)) {
+ WARN(1, "HFPLL %s is ON, but not locked!\n", c->dbg_name);
+ hfpll_clk_disable(c);
+ __hfpll_clk_init_once(c);
+ return HANDOFF_DISABLED_CLK;
+ }
+
+ WARN(c->rate < hd->min_rate || c->rate > hd->max_rate,
+ "HFPLL %s rate %lu outside spec!\n", c->dbg_name, c->rate);
+
+ return HANDOFF_ENABLED_CLK;
+}
+
+struct clk_ops clk_ops_hfpll = {
+ .enable = hfpll_clk_enable,
+ .disable = hfpll_clk_disable,
+ .round_rate = hfpll_clk_round_rate,
+ .set_rate = hfpll_clk_set_rate,
+ .handoff = hfpll_clk_handoff,
+};
+
+struct cpu_hwcg_action {
+ bool read;
+ bool enable;
+};
+
+static void cpu_hwcg_rw(void *info)
+{
+ struct cpu_hwcg_action *action = info;
+
+ u32 val;
+ asm volatile ("mrc p15, 7, %[cpmr0], c15, c0, 5\n\t"
+ : [cpmr0]"=r" (val));
+
+ if (action->read) {
+ action->enable = !(val & BIT(0));
+ return;
+ }
+
+ if (action->enable)
+ val &= ~BIT(0);
+ else
+ val |= BIT(0);
+
+ asm volatile ("mcr p15, 7, %[cpmr0], c15, c0, 5\n\t"
+ : : [cpmr0]"r" (val));
+}
+
+static void kpss_cpu_enable_hwcg(struct clk *c)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+ struct cpu_hwcg_action action = { .enable = true };
+
+ smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+}
+
+static void kpss_cpu_disable_hwcg(struct clk *c)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+ struct cpu_hwcg_action action = { .enable = false };
+
+ smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+}
+
+static int kpss_cpu_in_hwcg_mode(struct clk *c)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+ struct cpu_hwcg_action action = { .read = true };
+
+ smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
+ return action.enable;
+}
+
+static enum handoff kpss_cpu_handoff(struct clk *c)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+
+ c->rate = clk_get_rate(c->parent);
+
+ /*
+ * Don't unnecessarily turn on the parents for an offline CPU and
+ * then have them turned off at late init.
+ */
+ return (cpu_online(cpu->id) ?
+ HANDOFF_ENABLED_CLK : HANDOFF_DISABLED_CLK);
+}
+
+u32 find_dscr(struct avs_data *t, unsigned long rate)
+{
+ int i;
+
+ if (!t)
+ return 0;
+
+ for (i = 0; i < t->num; i++) {
+ if (t->rate[i] == rate)
+ return t->dscr[i];
+ }
+
+ return 0;
+}
+
+static int kpss_cpu_pre_set_rate(struct clk *c, unsigned long new_rate)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+ u32 dscr = find_dscr(cpu->avs_tbl, c->rate);
+
+ if (!c->prepare_count)
+ return -ENODEV;
+
+ if (dscr)
+ AVS_DISABLE(cpu->id);
+ return 0;
+}
+
+static long kpss_core_round_rate(struct clk *c, unsigned long rate)
+{
+ if (c->fmax && c->num_fmax)
+ rate = min(rate, c->fmax[c->num_fmax-1]);
+
+ return clk_round_rate(c->parent, rate);
+}
+
+static int kpss_core_set_rate(struct clk *c, unsigned long rate)
+{
+ if (!c->prepare_count)
+ return -ENODEV;
+
+ return clk_set_rate(c->parent, rate);
+}
+
+static void kpss_cpu_post_set_rate(struct clk *c, unsigned long old_rate)
+{
+ struct kpss_core_clk *cpu = to_kpss_core_clk(c);
+ u32 dscr = find_dscr(cpu->avs_tbl, c->rate);
+
+ /*
+ * FIXME: If AVS enable/disable needs to be done in the
+ * enable/disable op to correctly handle power collapse, then might
+ * need to grab the spinlock here.
+ */
+ if (dscr)
+ AVS_ENABLE(cpu->id, dscr);
+}
+
+static unsigned long kpss_core_get_rate(struct clk *c)
+{
+ return clk_get_rate(c->parent);
+}
+
+static long kpss_core_list_rate(struct clk *c, unsigned n)
+{
+ if (!c->fmax || c->num_fmax <= n)
+ return -ENXIO;
+
+ return c->fmax[n];
+}
+
+struct clk_ops clk_ops_kpss_cpu = {
+ .enable_hwcg = kpss_cpu_enable_hwcg,
+ .disable_hwcg = kpss_cpu_disable_hwcg,
+ .in_hwcg_mode = kpss_cpu_in_hwcg_mode,
+ .pre_set_rate = kpss_cpu_pre_set_rate,
+ .round_rate = kpss_core_round_rate,
+ .set_rate = kpss_core_set_rate,
+ .post_set_rate = kpss_cpu_post_set_rate,
+ .get_rate = kpss_core_get_rate,
+ .list_rate = kpss_core_list_rate,
+ .handoff = kpss_cpu_handoff,
+};
+
+#define SLPDLY_SHIFT 10
+#define SLPDLY_MASK 0x3
+static void kpss_l2_enable_hwcg(struct clk *c)
+{
+ struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+ u32 regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+ regval = get_l2_indirect_reg(l2->cp15_iaddr);
+ regval &= ~(SLPDLY_MASK << SLPDLY_SHIFT);
+ regval |= l2->l2_slp_delay;
+ set_l2_indirect_reg(l2->cp15_iaddr, regval);
+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+}
+
+static void kpss_l2_disable_hwcg(struct clk *c)
+{
+ struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+ u32 regval;
+ unsigned long flags;
+
+ /*
+ * NOTE: Should not be called when HW clock gating is already
+ * disabled.
+ */
+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
+ regval = get_l2_indirect_reg(l2->cp15_iaddr);
+ l2->l2_slp_delay = regval & (SLPDLY_MASK << SLPDLY_SHIFT);
+ regval |= (SLPDLY_MASK << SLPDLY_SHIFT);
+ set_l2_indirect_reg(l2->cp15_iaddr, regval);
+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
+}
+
+static int kpss_l2_in_hwcg_mode(struct clk *c)
+{
+ struct kpss_core_clk *l2 = to_kpss_core_clk(c);
+ u32 regval;
+
+ regval = get_l2_indirect_reg(l2->cp15_iaddr);
+ regval >>= SLPDLY_SHIFT;
+ regval &= SLPDLY_MASK;
+ return (regval != SLPDLY_MASK);
+}
+
+static enum handoff kpss_l2_handoff(struct clk *c)
+{
+ c->rate = clk_get_rate(c->parent);
+ return HANDOFF_ENABLED_CLK;
+}
+
+struct clk_ops clk_ops_kpss_l2 = {
+ .enable_hwcg = kpss_l2_enable_hwcg,
+ .disable_hwcg = kpss_l2_disable_hwcg,
+ .in_hwcg_mode = kpss_l2_in_hwcg_mode,
+ .round_rate = kpss_core_round_rate,
+ .set_rate = kpss_core_set_rate,
+ .get_rate = kpss_core_get_rate,
+ .list_rate = kpss_core_list_rate,
+ .handoff = kpss_l2_handoff,
+};
diff --git a/arch/arm/mach-msm/clock-krait.h b/arch/arm/mach-msm/clock-krait.h
new file mode 100644
index 0000000..2691a8c
--- /dev/null
+++ b/arch/arm/mach-msm/clock-krait.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, 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 __ARCH_ARM_MACH_MSM_CLOCK_KRAIT_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_KRAIT_H
+
+#include <mach/clk-provider.h>
+#include <mach/clock-generic.h>
+
+extern struct clk_mux_ops clk_mux_ops_kpss;
+extern struct clk_div_ops clk_div_ops_kpss_div2;
+
+#define DEFINE_KPSS_DIV2_CLK(clk_name, _parent, _offset) \
+static struct div_clk clk_name = { \
+ .div = 2, \
+ .min_div = 2, \
+ .max_div = 2, \
+ .ops = &clk_div_ops_kpss_div2, \
+ .offset = _offset, \
+ .mask = 0x3, \
+ .shift = 6, \
+ .c = { \
+ .parent = _parent, \
+ .dbg_name = #clk_name, \
+ .ops = &clk_ops_div, \
+ .flags = CLKFLAG_NO_RATE_CACHE, \
+ CLK_INIT(clk_name.c), \
+ } \
+}
+
+struct hfpll_data {
+ const u32 mode_offset;
+ const u32 l_offset;
+ const u32 m_offset;
+ const u32 n_offset;
+ const u32 user_offset;
+ const u32 droop_offset;
+ const u32 config_offset;
+ const u32 status_offset;
+
+ const u32 droop_val;
+ const u32 config_val;
+ const u32 user_val;
+ const u32 user_vco_mask;
+ unsigned long low_vco_max_rate;
+
+ unsigned long min_rate;
+ unsigned long max_rate;
+};
+
+struct hfpll_clk {
+ void * __iomem base;
+ struct hfpll_data const *d;
+ unsigned long src_rate;
+ int init_done;
+
+ struct clk c;
+};
+
+static inline struct hfpll_clk *to_hfpll_clk(struct clk *c)
+{
+ return container_of(c, struct hfpll_clk, c);
+}
+
+extern struct clk_ops clk_ops_hfpll;
+
+struct avs_data {
+ unsigned long *rate;
+ u32 *dscr;
+ int num;
+};
+
+struct kpss_core_clk {
+ int id;
+ u32 cp15_iaddr;
+ u32 l2_slp_delay;
+ struct avs_data *avs_tbl;
+ struct clk c;
+};
+
+static inline struct kpss_core_clk *to_kpss_core_clk(struct clk *c)
+{
+ return container_of(c, struct kpss_core_clk, c);
+}
+
+extern struct clk_ops clk_ops_kpss_cpu;
+extern struct clk_ops clk_ops_kpss_l2;
+
+#endif
diff --git a/arch/arm/mach-msm/clock-krypton.c b/arch/arm/mach-msm/clock-krypton.c
index 0b615cc..176dc32 100644
--- a/arch/arm/mach-msm/clock-krypton.c
+++ b/arch/arm/mach-msm/clock-krypton.c
@@ -18,12 +18,12 @@
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/clk.h>
-#include <linux/iopoll.h>
#include <linux/regulator/consumer.h>
+#include <linux/iopoll.h>
+#include <mach/clk.h>
#include <mach/rpm-regulator-smd.h>
#include <mach/socinfo.h>
-#include <mach/rpm-smd.h>
#include "clock-local2.h"
#include "clock-pll.h"
@@ -31,97 +31,2051 @@
#include "clock-voter.h"
#include "clock.h"
-static struct clk_lookup msm_clocks_dummy[] = {
- CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
- CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
- CLK_DUMMY("core_clk", SPI_CLK, "f9928000.spi", OFF),
- CLK_DUMMY("iface_clk", SPI_P_CLK, "f9928000.spi", OFF),
-
- CLK_DUMMY("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc", OFF),
- CLK_DUMMY("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc", OFF),
- CLK_DUMMY("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc", OFF),
- CLK_DUMMY("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc", OFF),
- CLK_DUMMY("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc", OFF),
- CLK_DUMMY("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc", OFF),
- CLK_DUMMY("mem_clk", bimc_msmbus_clk.c, "msm_bimc", OFF),
- CLK_DUMMY("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc", OFF),
- CLK_DUMMY("mem_clk", bimc_acpu_a_clk.c, "", OFF),
- CLK_DUMMY("dfab_clk", DFAB_CLK, "msm_sps", OFF),
- CLK_DUMMY("dma_bam_pclk", DMA_BAM_P_CLK, "msm_sps", OFF),
-
- CLK_DUMMY("clktype", gcc_imem_axi_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_imem_cfg_ahb_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_mss_cfg_ahb_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_mss_q6_bimc_axi_clk , "drivername", OFF),
- CLK_DUMMY("mem_clk", gcc_usb30_master_clk , "drivername", OFF),
- CLK_DUMMY("sleep_clk", gcc_usb30_sleep_clk , "drivername", OFF),
- CLK_DUMMY("utmi_clk", gcc_usb30_mock_utmi_clk , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_usb_hsic_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_usb_hsic_system_clk , "drivername", OFF),
- CLK_DUMMY("phyclk", gcc_usb_hsic_clk , "drivername", OFF),
- CLK_DUMMY("cal_clk", gcc_usb_hsic_io_cal_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_usb_hs_system_clk , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_usb_hs_ahb_clk , "drivername", OFF),
- CLK_DUMMY("sleep_a_clk", gcc_usb2a_phy_sleep_clk , "drivername", OFF),
- CLK_DUMMY("sleep_b_clk", gcc_usb2b_phy_sleep_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_sdcc2_apps_clk , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_sdcc2_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_sdcc3_apps_clk , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_sdcc3_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", sdcc3_apps_clk_src , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_blsp1_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup1_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup1_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart1_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup2_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup2_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart2_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup3_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup3_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart3_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup4_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup4_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart4_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup5_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup5_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart5_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup6_spi_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_qup6_i2c_apps_clk, "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_blsp1_uart6_apps_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", blsp1_uart6_apps_clk_src , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_pdm_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_pdm2_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_prng_ahb_clk , "drivername", OFF),
- CLK_DUMMY("dma_bam_pclk", gcc_bam_dma_ahb_clk , "drivername", OFF),
- CLK_DUMMY("mem_clk", gcc_boot_rom_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_ce1_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_ce1_axi_clk , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_ce1_ahb_clk , "drivername", OFF),
- CLK_DUMMY("core_clk_src", ce1_clk_src , "drivername", OFF),
- CLK_DUMMY("bus_clk", gcc_lpass_q6_axi_clk , "drivername", OFF),
- CLK_DUMMY("clktype", pcie_pipe_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_gp1_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gp1_clk_src , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_gp2_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gp2_clk_src , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_gp3_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gp3_clk_src , "drivername", OFF),
- CLK_DUMMY("core_clk", gcc_ipa_clk , "drivername", OFF),
- CLK_DUMMY("iface_clk", gcc_ipa_cnoc_clk , "drivername", OFF),
- CLK_DUMMY("inactivity_clk", gcc_ipa_sleep_clk , "drivername", OFF),
- CLK_DUMMY("core_clk_src", ipa_clk_src , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_dcs_clk , "drivername", OFF),
- CLK_DUMMY("clktype", dcs_clk_src , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_pcie_cfg_ahb_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_pcie_pipe_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_pcie_axi_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_pcie_sleep_clk , "drivername", OFF),
- CLK_DUMMY("clktype", gcc_pcie_axi_mstr_clk , "drivername", OFF),
- CLK_DUMMY("clktype", pcie_pipe_clk_src , "drivername", OFF),
- CLK_DUMMY("clktype", pcie_aux_clk_src , "drivername", OFF),
+enum {
+ GCC_BASE,
+ LPASS_BASE,
+ APCS_GLB_BASE,
+ APCS_GCC_BASE,
+ APCS_ACC_BASE,
+ N_BASES,
};
+static void __iomem *virt_bases[N_BASES];
+
+#define GCC_REG_BASE(x) (void __iomem *)(virt_bases[GCC_BASE] + (x))
+#define APCS_GCC_BASE(x) (void __iomem *)(virt_bases[APCS_GCC_BASE] + (x))
+
+/* Mux source select values */
+#define xo_source_val 0
+#define gpll0_source_val 1
+#define gpll1_source_val 4
+#define gnd_source_val 5
+
+#define usb3_pipe_clk_source_val 2
+#define pcie_pipe_clk_source_val 2
+
+/* Prevent a divider of -1 */
+#define FIXDIV(div) (div ? (2 * (div) - 1) : (0))
+
+#define F(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .src_clk = &s.c, \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+ | BVAL(10, 8, s##_source_val), \
+ }
+
+#define F_EXT_SRC(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(FIXDIV(div))) \
+ | BVAL(10, 8, s##_source_val), \
+ }
+
+#define VDD_DIG_FMAX_MAP1(l1, f1) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \
+ .vdd_class = &vdd_dig, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ [VDD_DIG_##l3] = (f3), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+
+enum vdd_dig_levels {
+ VDD_DIG_NONE,
+ VDD_DIG_LOW,
+ VDD_DIG_NOMINAL,
+ VDD_DIG_HIGH,
+ VDD_DIG_NUM
+};
+
+static int vdd_corner[] = {
+ RPM_REGULATOR_CORNER_NONE, /* VDD_DIG_NONE */
+ RPM_REGULATOR_CORNER_SVS_SOC, /* VDD_DIG_LOW */
+ RPM_REGULATOR_CORNER_NORMAL, /* VDD_DIG_NOMINAL */
+ RPM_REGULATOR_CORNER_SUPER_TURBO, /* VDD_DIG_HIGH */
+};
+
+static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
+
+#define RPM_MISC_CLK_TYPE 0x306b6c63
+#define RPM_BUS_CLK_TYPE 0x316b6c63
+#define RPM_MEM_CLK_TYPE 0x326b6c63
+#define RPM_QPIC_CLK_TYPE 0x63697071
+
+#define RPM_SMD_KEY_ENABLE 0x62616E45
+
+#define CXO_ID 0x0
+#define QDSS_ID 0x1
+
+#define PNOC_ID 0x0
+#define SNOC_ID 0x1
+#define CNOC_ID 0x2
+
+#define BIMC_ID 0x0
+#define QPIC_ID 0x0
+
+#define D0_ID 1
+#define D1_ID 2
+#define A0_ID 3
+#define A1_ID 4
+#define A2_ID 5
+
+#define APCS_CLK_DIAG (0x001C)
+#define GPLL0_MODE (0x0000)
+#define GPLL1_MODE (0x0040)
+#define SYS_NOC_USB3_AXI_CBCR (0x0108)
+#define MSS_CFG_AHB_CBCR (0x0280)
+#define MSS_Q6_BIMC_AXI_CBCR (0x0284)
+#define USB_30_BCR (0x03C0)
+#define USB30_MASTER_CBCR (0x03C8)
+#define USB30_SLEEP_CBCR (0x03CC)
+#define USB30_MOCK_UTMI_CBCR (0x03D0)
+#define USB30_MASTER_CMD_RCGR (0x03D4)
+#define USB30_MOCK_UTMI_CMD_RCGR (0x03E8)
+#define USB3_PIPE_CBCR (0x1B90)
+#define USB3_AUX_CBCR (0x1B94)
+#define USB3_PIPE_CMD_RCGR (0x1B98)
+#define USB3_AUX_CMD_RCGR (0x1BC0)
+#define USB_HS_HSIC_BCR (0x0400)
+#define USB_HSIC_AHB_CBCR (0x0408)
+#define USB_HSIC_SYSTEM_CMD_RCGR (0x041C)
+#define USB_HSIC_SYSTEM_CBCR (0x040C)
+#define USB_HSIC_CMD_RCGR (0x0440)
+#define USB_HSIC_CBCR (0x0410)
+#define USB_HSIC_IO_CAL_CMD_RCGR (0x0458)
+#define USB_HSIC_IO_CAL_CBCR (0x0414)
+#define USB_HSIC_IO_CAL_SLEEP_CBCR (0x0418)
+#define USB_HSIC_XCVR_FS_CMD_RCGR (0x0424)
+#define USB_HSIC_XCVR_FS_CBCR (0x042C)
+#define USB_HS_BCR (0x0480)
+#define USB_HS_SYSTEM_CBCR (0x0484)
+#define USB_HS_AHB_CBCR (0x0488)
+#define USB_HS_SYSTEM_CMD_RCGR (0x0490)
+#define SDCC2_APPS_CMD_RCGR (0x0510)
+#define SDCC2_APPS_CBCR (0x0504)
+#define SDCC2_AHB_CBCR (0x0508)
+#define SDCC3_APPS_CMD_RCGR (0x0550)
+#define SDCC3_APPS_CBCR (0x0544)
+#define SDCC3_AHB_CBCR (0x0548)
+#define BLSP1_AHB_CBCR (0x05C4)
+#define BLSP1_QUP1_SPI_APPS_CBCR (0x0644)
+#define BLSP1_QUP1_I2C_APPS_CBCR (0x0648)
+#define BLSP1_QUP1_I2C_APPS_CMD_RCGR (0x0660)
+#define BLSP1_QUP2_I2C_APPS_CMD_RCGR (0x06E0)
+#define BLSP1_QUP3_I2C_APPS_CMD_RCGR (0x0760)
+#define BLSP1_QUP4_I2C_APPS_CMD_RCGR (0x07E0)
+#define BLSP1_QUP5_I2C_APPS_CMD_RCGR (0x0860)
+#define BLSP1_QUP6_I2C_APPS_CMD_RCGR (0x08E0)
+#define BLSP1_QUP1_SPI_APPS_CMD_RCGR (0x064C)
+#define BLSP1_UART1_APPS_CBCR (0x0684)
+#define BLSP1_UART1_APPS_CMD_RCGR (0x068C)
+#define BLSP1_QUP2_SPI_APPS_CBCR (0x06C4)
+#define BLSP1_QUP2_I2C_APPS_CBCR (0x06C8)
+#define BLSP1_QUP2_SPI_APPS_CMD_RCGR (0x06CC)
+#define BLSP1_UART2_APPS_CBCR (0x0704)
+#define BLSP1_UART2_APPS_CMD_RCGR (0x070C)
+#define BLSP1_QUP3_SPI_APPS_CBCR (0x0744)
+#define BLSP1_QUP3_I2C_APPS_CBCR (0x0748)
+#define BLSP1_QUP3_SPI_APPS_CMD_RCGR (0x074C)
+#define BLSP1_UART3_APPS_CBCR (0x0784)
+#define BLSP1_UART3_APPS_CMD_RCGR (0x078C)
+#define BLSP1_QUP4_SPI_APPS_CBCR (0x07C4)
+#define BLSP1_QUP4_I2C_APPS_CBCR (0x07C8)
+#define BLSP1_QUP4_SPI_APPS_CMD_RCGR (0x07CC)
+#define BLSP1_UART4_APPS_CBCR (0x0804)
+#define BLSP1_UART4_APPS_CMD_RCGR (0x080C)
+#define BLSP1_QUP5_SPI_APPS_CBCR (0x0844)
+#define BLSP1_QUP5_I2C_APPS_CBCR (0x0848)
+#define BLSP1_QUP5_SPI_APPS_CMD_RCGR (0x084C)
+#define BLSP1_UART5_APPS_CBCR (0x0884)
+#define BLSP1_UART5_APPS_CMD_RCGR (0x088C)
+#define BLSP1_QUP6_SPI_APPS_CBCR (0x08C4)
+#define BLSP1_QUP6_I2C_APPS_CBCR (0x08C8)
+#define BLSP1_QUP6_SPI_APPS_CMD_RCGR (0x08CC)
+#define BLSP1_UART6_APPS_CBCR (0x0904)
+#define BLSP1_UART6_APPS_CMD_RCGR (0x090C)
+#define PDM_AHB_CBCR (0x0CC4)
+#define PDM2_CBCR (0x0CCC)
+#define PDM2_CMD_RCGR (0x0CD0)
+#define PRNG_AHB_CBCR (0x0D04)
+#define BAM_DMA_AHB_CBCR (0x0D44)
+#define BAM_DMA_INACTIVITY_TIMERS_CBCR (0x0D48)
+#define BOOT_ROM_AHB_CBCR (0x0E04)
+#define RPM_MISC (0x0F24)
+#define CE1_CMD_RCGR (0x1050)
+#define CE1_CBCR (0x1044)
+#define CE1_AXI_CBCR (0x1048)
+#define CE1_AHB_CBCR (0x104C)
+#define GCC_XO_DIV4_CBCR (0x10C8)
+#define LPASS_Q6_AXI_CBCR (0x11C0)
+#define APCS_GPLL_ENA_VOTE (0x1480)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x1484)
+#define GCC_DEBUG_CLK_CTL (0x1880)
+#define CLOCK_FRQ_MEASURE_CTL (0x1884)
+#define CLOCK_FRQ_MEASURE_STATUS (0x1888)
+#define PLLTEST_PAD_CFG (0x188C)
+#define PCIE_CFG_AHB_CBCR (0x1C04)
+#define PCIE_PIPE_CBCR (0x1C08)
+#define PCIE_AXI_CBCR (0x1C0C)
+#define PCIE_SLEEP_CBCR (0x1C10)
+#define PCIE_AXI_MSTR_CBCR (0x1C2C)
+#define PCIE_PIPE_CMD_RCGR (0x1C14)
+#define PCIE_AUX_CMD_RCGR (0x1E00)
+#define Q6SS_AHB_LFABIF_CBCR (0x22000)
+#define Q6SS_AHBM_CBCR (0x22004)
+
+DEFINE_CLK_RPM_SMD_BRANCH(xo, xo_a_clk, RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
+
+static unsigned int soft_vote_gpll0;
+
+static struct pll_vote_clk gpll0 = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)GPLL0_MODE,
+ .status_mask = BIT(31),
+ .soft_vote = &soft_vote_gpll0,
+ .soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 600000000,
+ .parent = &xo.c,
+ .dbg_name = "gpll0",
+ .ops = &clk_ops_pll_acpu_vote,
+ CLK_INIT(gpll0.c),
+ },
+};
+
+/* Don't vote for xo if using this clock to allow xo shutdown */
+static struct pll_vote_clk gpll0_ao = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void __iomem *)GPLL0_MODE,
+ .status_mask = BIT(31),
+ .soft_vote = &soft_vote_gpll0,
+ .soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 600000000,
+ .dbg_name = "gpll0_ao",
+ .ops = &clk_ops_pll_acpu_vote,
+ CLK_INIT(gpll0_ao.c),
+ },
+};
+
+static struct pll_vote_clk gpll1 = {
+ .en_reg = (void __iomem *)APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(1),
+ .status_reg = (void __iomem *)GPLL1_MODE,
+ .status_mask = BIT(31),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .rate = 480000000,
+ .parent = &xo.c,
+ .dbg_name = "gpll1",
+ .ops = &clk_ops_pll_vote,
+ CLK_INIT(gpll1.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
+ F( 125000000, gpll0, 1, 5, 24),
+ F_END
+};
+
+static struct rcg_clk usb30_master_clk_src = {
+ .cmd_rcgr_reg = USB30_MASTER_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_usb30_master_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb30_master_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 125000000),
+ CLK_INIT(usb30_master_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = {
+ F( 19200000, xo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP1_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup1_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup1_i2c_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
+ F( 960000, xo, 10, 1, 2),
+ F( 4800000, xo, 4, 0, 0),
+ F( 9600000, xo, 2, 0, 0),
+ F( 15000000, gpll0, 10, 1, 4),
+ F( 19200000, xo, 1, 0, 0),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP1_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup1_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup1_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP2_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup2_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup2_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP2_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup2_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup2_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP3_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup3_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup3_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP3_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup3_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup3_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP4_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup4_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup4_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP4_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup4_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup4_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP5_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup5_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup5_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup5_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP5_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup5_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup5_spi_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP6_I2C_APPS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup6_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 19200000),
+ CLK_INIT(blsp1_qup6_i2c_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_qup6_spi_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_QUP6_SPI_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_qup6_spi_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 25000000, NOMINAL, 50000000),
+ CLK_INIT(blsp1_qup6_spi_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = {
+ F( 3686400, gpll0, 1, 96, 15625),
+ F( 7372800, gpll0, 1, 192, 15625),
+ F( 14745600, gpll0, 1, 384, 15625),
+ F( 16000000, gpll0, 5, 2, 15),
+ F( 19200000, xo, 1, 0, 0),
+ F( 24000000, gpll0, 5, 1, 5),
+ F( 32000000, gpll0, 1, 4, 75),
+ F( 40000000, gpll0, 15, 0, 0),
+ F( 46400000, gpll0, 1, 29, 375),
+ F( 48000000, gpll0, 12.5, 0, 0),
+ F( 51200000, gpll0, 1, 32, 375),
+ F( 56000000, gpll0, 1, 7, 75),
+ F( 58982400, gpll0, 1, 1536, 15625),
+ F( 60000000, gpll0, 10, 0, 0),
+ F_END
+};
+
+static struct rcg_clk blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART1_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart1_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart1_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart3_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart3_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart4_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART4_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart4_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart4_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart5_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART5_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart5_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart5_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk blsp1_uart6_apps_clk_src = {
+ .cmd_rcgr_reg = BLSP1_UART6_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "blsp1_uart6_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 31580000, NOMINAL, 63160000),
+ CLK_INIT(blsp1_uart6_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+ F( 50000000, gpll0, 12, 0, 0),
+ F( 85710000, gpll0, 7, 0, 0),
+ F( 100000000, gpll0, 6, 0, 0),
+ F( 171430000, gpll0, 3.5, 0, 0),
+ F( 200000000, gpll0, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+ .cmd_rcgr_reg = CE1_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "ce1_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP3(LOW, 85710000, NOMINAL, 171430000, HIGH,
+ 200000000),
+ CLK_INIT(ce1_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_pcie_sleep_clk[] = {
+ F( 1000000, xo, 1, 5, 96),
+ F_END
+};
+
+static struct rcg_clk pcie_aux_clk_src = {
+ .cmd_rcgr_reg = PCIE_AUX_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_pcie_sleep_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "pcie_aux_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 1000000),
+ CLK_INIT(pcie_aux_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_pcie_pipe_clk[] = {
+ F_EXT_SRC( 62500000, pcie_pipe_clk, 2, 0, 0),
+ F_EXT_SRC( 125000000, pcie_pipe_clk, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk pcie_pipe_clk_src = {
+ .cmd_rcgr_reg = PCIE_PIPE_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_pcie_pipe_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "pcie_pipe_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
+ CLK_INIT(pcie_pipe_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_pdm2_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F_END
+};
+
+static struct rcg_clk pdm2_clk_src = {
+ .cmd_rcgr_reg = PDM2_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_pdm2_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "pdm2_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 60000000),
+ CLK_INIT(pdm2_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_sdcc2_3_apps_clk[] = {
+ F( 144000, xo, 16, 3, 25),
+ F( 400000, xo, 12, 1, 4),
+ F( 20000000, gpll0, 15, 1, 2),
+ F( 25000000, gpll0, 12, 1, 2),
+ F( 50000000, gpll0, 12, 0, 0),
+ F( 100000000, gpll0, 6, 0, 0),
+ F( 200000000, gpll0, 3, 0, 0),
+ F_END
+};
+
+static struct rcg_clk sdcc2_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC2_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_3_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc2_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 100000000, NOMINAL, 200000000),
+ CLK_INIT(sdcc2_apps_clk_src.c),
+ },
+};
+
+static struct rcg_clk sdcc3_apps_clk_src = {
+ .cmd_rcgr_reg = SDCC3_APPS_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc2_3_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "sdcc3_apps_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 100000000),
+ CLK_INIT(sdcc3_apps_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb3_aux_clk[] = {
+ F( 1000000, xo, 1, 5, 96),
+ F_END
+};
+
+static struct rcg_clk usb3_aux_clk_src = {
+ .cmd_rcgr_reg = USB3_AUX_CMD_RCGR,
+ .set_rate = set_rate_mnd,
+ .freq_tbl = ftbl_gcc_usb3_aux_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb3_aux_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ VDD_DIG_FMAX_MAP1(LOW, 1000000),
+ CLK_INIT(usb3_aux_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb3_pipe_clk[] = {
+ F_EXT_SRC( 125000000, usb3_pipe_clk, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb3_pipe_clk_src = {
+ .cmd_rcgr_reg = USB3_PIPE_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb3_pipe_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb3_pipe_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 125000000),
+ CLK_INIT(usb3_pipe_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb30_mock_utmi_clk_src = {
+ .cmd_rcgr_reg = USB30_MOCK_UTMI_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb30_mock_utmi_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 60000000),
+ CLK_INIT(usb30_mock_utmi_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F( 75000000, gpll0, 8, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src = {
+ .cmd_rcgr_reg = USB_HS_SYSTEM_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hs_system_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 75000000),
+ CLK_INIT(usb_hs_system_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_clk[] = {
+ F( 480000000, gpll1, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_clk_src = {
+ .cmd_rcgr_reg = USB_HSIC_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hsic_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hsic_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 480000000),
+ CLK_INIT(usb_hsic_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = {
+ F( 9600000, xo, 2, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_io_cal_clk_src = {
+ .cmd_rcgr_reg = USB_HSIC_IO_CAL_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hsic_io_cal_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 9600000),
+ CLK_INIT(usb_hsic_io_cal_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_system_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F( 75000000, gpll0, 8, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_system_clk_src = {
+ .cmd_rcgr_reg = USB_HSIC_SYSTEM_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hsic_system_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hsic_system_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP2(LOW, 60000000, NOMINAL, 75000000),
+ CLK_INIT(usb_hsic_system_clk_src.c),
+ },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb_hsic_xcvr_fs_clk[] = {
+ F( 60000000, gpll0, 10, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hsic_xcvr_fs_clk_src = {
+ .cmd_rcgr_reg = USB_HSIC_XCVR_FS_CMD_RCGR,
+ .set_rate = set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hsic_xcvr_fs_clk,
+ .current_freq = &rcg_dummy_freq,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "usb_hsic_xcvr_fs_clk_src",
+ .ops = &clk_ops_rcg,
+ VDD_DIG_FMAX_MAP1(LOW, 60000000),
+ CLK_INIT(usb_hsic_xcvr_fs_clk_src.c),
+ },
+};
+
+DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(cnoc_clk, cnoc_a_clk, RPM_BUS_CLK_TYPE, CNOC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD_QDSS(qdss_clk, qdss_a_clk, RPM_MISC_CLK_TYPE, QDSS_ID);
+
+DEFINE_CLK_RPM_SMD(qpic_clk, qpic_a_clk, RPM_QPIC_CLK_TYPE, QPIC_ID, NULL);
+
+DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
+
+static struct local_vote_clk gcc_bam_dma_ahb_clk = {
+ .cbcr_reg = BAM_DMA_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(12),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_bam_dma_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_bam_dma_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_bam_dma_inactivity_timers_clk = {
+ .cbcr_reg = BAM_DMA_INACTIVITY_TIMERS_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_bam_dma_inactivity_timers_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_bam_dma_inactivity_timers_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = BLSP1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(17),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_blsp1_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .parent = &blsp1_qup1_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup1_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP1_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup1_spi_apps_clk",
+ .parent = &blsp1_qup1_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup1_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .parent = &blsp1_qup2_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup2_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP2_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup2_spi_apps_clk",
+ .parent = &blsp1_qup2_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup2_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .parent = &blsp1_qup3_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup3_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP3_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup3_spi_apps_clk",
+ .parent = &blsp1_qup3_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup3_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .parent = &blsp1_qup4_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup4_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP4_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup4_spi_apps_clk",
+ .parent = &blsp1_qup4_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup4_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup5_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP5_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup5_i2c_apps_clk",
+ .parent = &blsp1_qup5_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup5_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup5_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP5_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup5_spi_apps_clk",
+ .parent = &blsp1_qup5_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup5_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup6_i2c_apps_clk = {
+ .cbcr_reg = BLSP1_QUP6_I2C_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup6_i2c_apps_clk",
+ .parent = &blsp1_qup6_i2c_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup6_i2c_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_qup6_spi_apps_clk = {
+ .cbcr_reg = BLSP1_QUP6_SPI_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_qup6_spi_apps_clk",
+ .parent = &blsp1_qup6_spi_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_qup6_spi_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart1_apps_clk = {
+ .cbcr_reg = BLSP1_UART1_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart1_apps_clk",
+ .parent = &blsp1_uart1_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart1_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk = {
+ .cbcr_reg = BLSP1_UART2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart2_apps_clk",
+ .parent = &blsp1_uart2_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart3_apps_clk = {
+ .cbcr_reg = BLSP1_UART3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart3_apps_clk",
+ .parent = &blsp1_uart3_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart4_apps_clk = {
+ .cbcr_reg = BLSP1_UART4_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart4_apps_clk",
+ .parent = &blsp1_uart4_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart4_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart5_apps_clk = {
+ .cbcr_reg = BLSP1_UART5_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart5_apps_clk",
+ .parent = &blsp1_uart5_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart5_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart6_apps_clk = {
+ .cbcr_reg = BLSP1_UART6_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_blsp1_uart6_apps_clk",
+ .parent = &blsp1_uart6_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_blsp1_uart6_apps_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_boot_rom_ahb_clk = {
+ .cbcr_reg = BOOT_ROM_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(10),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_boot_rom_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_boot_rom_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_ahb_clk = {
+ .cbcr_reg = CE1_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(3),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_axi_clk = {
+ .cbcr_reg = CE1_AXI_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(4),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_axi_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_axi_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_ce1_clk = {
+ .cbcr_reg = CE1_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(5),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_ce1_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_ce1_clk.c),
+ },
+};
+
+static struct branch_clk gcc_lpass_q6_axi_clk = {
+ .cbcr_reg = LPASS_Q6_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_lpass_q6_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_lpass_q6_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_mss_cfg_ahb_clk = {
+ .cbcr_reg = MSS_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_cfg_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_mss_q6_bimc_axi_clk = {
+ .cbcr_reg = MSS_Q6_BIMC_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_mss_q6_bimc_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_mss_q6_bimc_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pcie_axi_clk = {
+ .cbcr_reg = PCIE_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pcie_axi_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pcie_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pcie_axi_mstr_clk = {
+ .cbcr_reg = PCIE_AXI_MSTR_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pcie_axi_mstr_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pcie_axi_mstr_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pcie_cfg_ahb_clk = {
+ .cbcr_reg = PCIE_CFG_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pcie_cfg_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pcie_cfg_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pcie_pipe_clk = {
+ .cbcr_reg = PCIE_PIPE_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pcie_pipe_clk",
+ .parent = &pcie_pipe_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pcie_pipe_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pcie_sleep_clk = {
+ .cbcr_reg = PCIE_SLEEP_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pcie_sleep_clk",
+ .parent = &pcie_aux_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pcie_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm2_clk = {
+ .cbcr_reg = PDM2_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pdm2_clk",
+ .parent = &pdm2_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm2_clk.c),
+ },
+};
+
+static struct branch_clk gcc_pdm_ahb_clk = {
+ .cbcr_reg = PDM_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_pdm_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_pdm_ahb_clk.c),
+ },
+};
+
+static struct local_vote_clk gcc_prng_ahb_clk = {
+ .cbcr_reg = PRNG_AHB_CBCR,
+ .vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(13),
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_prng_ahb_clk",
+ .ops = &clk_ops_vote,
+ CLK_INIT(gcc_prng_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+ .cbcr_reg = SDCC2_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc2_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+ .cbcr_reg = SDCC2_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc2_apps_clk",
+ .parent = &sdcc2_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc2_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc3_ahb_clk = {
+ .cbcr_reg = SDCC3_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc3_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc3_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sdcc3_apps_clk = {
+ .cbcr_reg = SDCC3_APPS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sdcc3_apps_clk",
+ .parent = &sdcc3_apps_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sdcc3_apps_clk.c),
+ },
+};
+
+static struct branch_clk gcc_sys_noc_usb3_axi_clk = {
+ .cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_sys_noc_usb3_axi_clk",
+ .parent = &usb30_master_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb3_aux_clk = {
+ .cbcr_reg = USB3_AUX_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb3_aux_clk",
+ .parent = &usb3_aux_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb3_aux_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb3_pipe_clk = {
+ .cbcr_reg = USB3_PIPE_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb3_pipe_clk",
+ .parent = &usb3_pipe_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb3_pipe_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb30_master_clk = {
+ .cbcr_reg = USB30_MASTER_CBCR,
+ .bcr_reg = USB_30_BCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb30_master_clk",
+ .parent = &usb30_master_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb30_master_clk.c),
+ .depends = &gcc_sys_noc_usb3_axi_clk.c,
+ },
+};
+
+static struct branch_clk gcc_usb30_mock_utmi_clk = {
+ .cbcr_reg = USB30_MOCK_UTMI_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb30_mock_utmi_clk",
+ .parent = &usb30_mock_utmi_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb30_mock_utmi_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb30_sleep_clk = {
+ .cbcr_reg = USB30_SLEEP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb30_sleep_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb30_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk = {
+ .cbcr_reg = USB_HS_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hs_system_clk = {
+ .cbcr_reg = USB_HS_SYSTEM_CBCR,
+ .has_sibling = 0,
+ .bcr_reg = USB_HS_BCR,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hs_system_clk",
+ .parent = &usb_hs_system_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hs_system_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_ahb_clk = {
+ .cbcr_reg = USB_HSIC_AHB_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_ahb_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_ahb_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_clk = {
+ .cbcr_reg = USB_HSIC_CBCR,
+ .has_sibling = 0,
+ .bcr_reg = USB_HS_HSIC_BCR,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_clk",
+ .parent = &usb_hsic_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_io_cal_clk = {
+ .cbcr_reg = USB_HSIC_IO_CAL_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_io_cal_clk",
+ .parent = &usb_hsic_io_cal_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_io_cal_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_io_cal_sleep_clk = {
+ .cbcr_reg = USB_HSIC_IO_CAL_SLEEP_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_io_cal_sleep_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_io_cal_sleep_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_system_clk = {
+ .cbcr_reg = USB_HSIC_SYSTEM_CBCR,
+ .has_sibling = 0,
+ .bcr_reg = USB_HS_HSIC_BCR,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_system_clk",
+ .parent = &usb_hsic_system_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_system_clk.c),
+ },
+};
+
+static struct branch_clk gcc_usb_hsic_xcvr_fs_clk = {
+ .cbcr_reg = USB_HSIC_XCVR_FS_CBCR,
+ .has_sibling = 0,
+ .base = &virt_bases[GCC_BASE],
+ .c = {
+ .dbg_name = "gcc_usb_hsic_xcvr_fs_clk",
+ .parent = &usb_hsic_xcvr_fs_clk_src.c,
+ .ops = &clk_ops_branch,
+ CLK_INIT(gcc_usb_hsic_xcvr_fs_clk.c),
+ },
+};
+
+static struct branch_clk q6ss_ahb_lfabif_clk = {
+ .cbcr_reg = Q6SS_AHB_LFABIF_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "q6ss_ahb_lfabif_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(q6ss_ahb_lfabif_clk.c),
+ },
+};
+
+static struct branch_clk q6ss_ahbm_clk = {
+ .cbcr_reg = Q6SS_AHBM_CBCR,
+ .has_sibling = 1,
+ .base = &virt_bases[LPASS_BASE],
+ .c = {
+ .dbg_name = "q6ss_ahbm_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(q6ss_ahbm_clk.c),
+ },
+};
+
+static DEFINE_CLK_VOTER(pnoc_msmbus_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_clk, &snoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_clk, &cnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, &pnoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, &snoc_a_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, &cnoc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sdcc2_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(pnoc_sdcc3_clk, &pnoc_clk.c, LONG_MAX);
+
+static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, &xo.c);
+static DEFINE_CLK_BRANCH_VOTER(cxo_pil_mss_clk, &xo.c);
+
+static DEFINE_CLK_MEASURE(a7_m_clk);
+
+#ifdef CONFIG_DEBUG_FS
+
+struct measure_mux_entry {
+ struct clk *c;
+ int base;
+ u32 debug_mux;
+};
+
+struct measure_mux_entry measure_mux[] = {
+ {&gcc_mss_cfg_ahb_clk.c, GCC_BASE, 0x0030},
+ {&gcc_mss_q6_bimc_axi_clk.c, GCC_BASE, 0x0031},
+ {&gcc_usb30_master_clk.c, GCC_BASE, 0x0050},
+ {&gcc_usb30_sleep_clk.c, GCC_BASE, 0x0051},
+ {&gcc_usb30_mock_utmi_clk.c, GCC_BASE, 0x0052},
+ {&gcc_usb3_pipe_clk.c, GCC_BASE, 0x0054},
+ {&gcc_usb3_aux_clk.c, GCC_BASE, 0x0055},
+ {&gcc_usb_hsic_ahb_clk.c, GCC_BASE, 0x0058},
+ {&gcc_usb_hsic_system_clk.c, GCC_BASE, 0x0059},
+ {&gcc_usb_hsic_clk.c, GCC_BASE, 0x005a},
+ {&gcc_usb_hsic_io_cal_clk.c, GCC_BASE, 0x005b},
+ {&gcc_usb_hsic_io_cal_sleep_clk.c, GCC_BASE, 0x005c},
+ {&gcc_usb_hsic_xcvr_fs_clk.c, GCC_BASE, 0x005d},
+ {&gcc_usb_hs_system_clk.c, GCC_BASE, 0x0060},
+ {&gcc_usb_hs_ahb_clk.c, GCC_BASE, 0x0061},
+ {&gcc_sdcc2_apps_clk.c, GCC_BASE, 0x0070},
+ {&gcc_sdcc2_ahb_clk.c, GCC_BASE, 0x0071},
+ {&gcc_sdcc3_apps_clk.c, GCC_BASE, 0x0078},
+ {&gcc_sdcc3_ahb_clk.c, GCC_BASE, 0x0079},
+ {&gcc_blsp1_ahb_clk.c, GCC_BASE, 0x0088},
+ {&gcc_blsp1_qup1_spi_apps_clk.c, GCC_BASE, 0x008a},
+ {&gcc_blsp1_qup1_i2c_apps_clk.c, GCC_BASE, 0x008b},
+ {&gcc_blsp1_uart1_apps_clk.c, GCC_BASE, 0x008c},
+ {&gcc_blsp1_qup2_spi_apps_clk.c, GCC_BASE, 0x008e},
+ {&gcc_blsp1_qup2_i2c_apps_clk.c, GCC_BASE, 0x0090},
+ {&gcc_blsp1_uart2_apps_clk.c, GCC_BASE, 0x0091},
+ {&gcc_blsp1_qup3_spi_apps_clk.c, GCC_BASE, 0x0093},
+ {&gcc_blsp1_qup3_i2c_apps_clk.c, GCC_BASE, 0x0094},
+ {&gcc_blsp1_uart3_apps_clk.c, GCC_BASE, 0x0095},
+ {&gcc_blsp1_qup4_spi_apps_clk.c, GCC_BASE, 0x0098},
+ {&gcc_blsp1_qup4_i2c_apps_clk.c, GCC_BASE, 0x0099},
+ {&gcc_blsp1_uart4_apps_clk.c, GCC_BASE, 0x009a},
+ {&gcc_blsp1_qup5_spi_apps_clk.c, GCC_BASE, 0x009c},
+ {&gcc_blsp1_qup5_i2c_apps_clk.c, GCC_BASE, 0x009d},
+ {&gcc_blsp1_uart5_apps_clk.c, GCC_BASE, 0x009e},
+ {&gcc_blsp1_qup6_spi_apps_clk.c, GCC_BASE, 0x00a1},
+ {&gcc_blsp1_qup6_i2c_apps_clk.c, GCC_BASE, 0x00a2},
+ {&gcc_blsp1_uart6_apps_clk.c, GCC_BASE, 0x00a3},
+ {&gcc_pdm_ahb_clk.c, GCC_BASE, 0x00d0},
+ {&gcc_pdm2_clk.c, GCC_BASE, 0x00d2},
+ {&gcc_prng_ahb_clk.c, GCC_BASE, 0x00d8},
+ {&gcc_bam_dma_ahb_clk.c, GCC_BASE, 0x00e0},
+ {&gcc_bam_dma_inactivity_timers_clk.c, GCC_BASE, 0x00e1},
+ {&gcc_boot_rom_ahb_clk.c, GCC_BASE, 0x00f8},
+ {&gcc_ce1_clk.c, GCC_BASE, 0x0138},
+ {&gcc_ce1_axi_clk.c, GCC_BASE, 0x0139},
+ {&gcc_ce1_ahb_clk.c, GCC_BASE, 0x013a},
+ {&gcc_lpass_q6_axi_clk.c, GCC_BASE, 0x0160},
+ {&gcc_pcie_cfg_ahb_clk.c, GCC_BASE, 0x01f0},
+ {&gcc_pcie_pipe_clk.c, GCC_BASE, 0x01f1},
+ {&gcc_pcie_axi_clk.c, GCC_BASE, 0x01f2},
+ {&gcc_pcie_sleep_clk.c, GCC_BASE, 0x01f3},
+ {&gcc_pcie_axi_mstr_clk.c, GCC_BASE, 0x01f4},
+
+ {&bimc_clk.c, GCC_BASE, 0x0155},
+ {&cnoc_clk.c, GCC_BASE, 0x0008},
+ {&pnoc_clk.c, GCC_BASE, 0x0010},
+ {&snoc_clk.c, GCC_BASE, 0x0000},
+
+ {&q6ss_ahbm_clk.c, LPASS_BASE, 0x001d},
+ {&q6ss_ahb_lfabif_clk.c, LPASS_BASE, 0x001e},
+
+ {&a7_m_clk, APCS_GCC_BASE, 0x3},
+ {&dummy_clk, N_BASES, 0x0000},
+};
+
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
+{
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned long flags;
+ u32 regval, clk_sel, i;
+
+ if (!parent)
+ return -EINVAL;
+
+ for (i = 0; i < (ARRAY_SIZE(measure_mux) - 1); i++)
+ if (measure_mux[i].c == parent)
+ break;
+
+ if (measure_mux[i].c == &dummy_clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+ /*
+ * Program the test vector, measurement period (sample_ticks)
+ * and scaling multiplier.
+ */
+ clk->sample_ticks = 0x10000;
+ clk->multiplier = 1;
+
+ writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ switch (measure_mux[i].base) {
+
+ case GCC_BASE:
+ clk_sel = measure_mux[i].debug_mux;
+ break;
+
+ case APCS_GCC_BASE:
+ clk_sel = 0x16A;
+ regval = BVAL(5, 3, measure_mux[i].debug_mux);
+ writel_relaxed(regval, APCS_GCC_BASE(APCS_CLK_DIAG));
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Set debug mux clock index */
+ regval = BVAL(9, 0, clk_sel);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Activate debug clock output */
+ regval |= BIT(16);
+ writel_relaxed(regval, GCC_REG_BASE(GCC_DEBUG_CLK_CTL));
+
+ /* Make sure test vector is set before starting measurements. */
+ mb();
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ return 0;
+}
+
+/* Sample clock for 'ticks' reference clock ticks. */
+static u32 run_measurement(unsigned ticks)
+{
+ /* Stop counters and set the XO4 counter start value. */
+ writel_relaxed(ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+
+ /* Wait for timer to become ready. */
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) != 0)
+ cpu_relax();
+
+ /* Run measurement and wait for completion. */
+ writel_relaxed(BIT(20)|ticks, GCC_REG_BASE(CLOCK_FRQ_MEASURE_CTL));
+ while ((readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BIT(25)) == 0)
+ cpu_relax();
+
+ /* Return measured ticks. */
+ return readl_relaxed(GCC_REG_BASE(CLOCK_FRQ_MEASURE_STATUS)) &
+ BM(24, 0);
+}
+
+/*
+ * Perform a hardware rate measurement for a given clock.
+ * FOR DEBUG USE ONLY: Measurements take ~15 ms!
+ */
+static unsigned long measure_clk_get_rate(struct clk *c)
+{
+ unsigned long flags;
+ u32 gcc_xo4_reg_backup;
+ u64 raw_count_short, raw_count_full;
+ struct measure_clk *clk = to_measure_clk(c);
+ unsigned ret;
+
+ ret = clk_prepare_enable(&xo.c);
+ if (ret) {
+ pr_warning("CXO clock failed to enable. Can't measure\n");
+ return 0;
+ }
+
+ spin_lock_irqsave(&local_clock_reg_lock, flags);
+
+ /* Enable CXO/4 and RINGOSC branch. */
+ gcc_xo4_reg_backup = readl_relaxed(GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+ writel_relaxed(0x1, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /*
+ * The ring oscillator counter will not reset if the measured clock
+ * is not running. To detect this, run a short measurement before
+ * the full measurement. If the raw results of the two are the same
+ * then the clock must be off.
+ */
+
+ /* Run a short measurement. (~1 ms) */
+ raw_count_short = run_measurement(0x1000);
+ /* Run a full measurement. (~14 ms) */
+ raw_count_full = run_measurement(clk->sample_ticks);
+
+ writel_relaxed(gcc_xo4_reg_backup, GCC_REG_BASE(GCC_XO_DIV4_CBCR));
+
+ /* Return 0 if the clock is off. */
+ if (raw_count_full == raw_count_short) {
+ ret = 0;
+ } else {
+ /* Compute rate in Hz. */
+ raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+ do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
+ ret = (raw_count_full * clk->multiplier);
+ }
+
+ writel_relaxed(0x51A00, GCC_REG_BASE(PLLTEST_PAD_CFG));
+ spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+
+ clk_disable_unprepare(&xo.c);
+
+ return ret;
+}
+#else /* !CONFIG_DEBUG_FS */
+static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ return -EINVAL;
+}
+
+static unsigned long measure_clk_get_rate(struct clk *clk)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static struct clk_ops clk_ops_measure = {
+ .set_parent = measure_clk_set_parent,
+ .get_rate = measure_clk_get_rate,
+};
+
+static struct measure_clk measure_clk = {
+ .c = {
+ .dbg_name = "measure_clk",
+ .ops = &clk_ops_measure,
+ CLK_INIT(measure_clk.c),
+ },
+ .multiplier = 1,
+};
+
+static struct clk_lookup msm_clocks_krypton[] = {
+ CLK_LOOKUP("xo", xo.c, ""),
+ CLK_LOOKUP("measure", measure_clk.c, "debug"),
+
+ /* PLLS */
+ CLK_LOOKUP("", gpll0.c, ""),
+ CLK_LOOKUP("", gpll1.c, ""),
+ CLK_LOOKUP("", gpll0_ao.c, ""),
+
+ /* PIL-LPASS */
+ CLK_LOOKUP("xo", cxo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("bus_clk", gcc_lpass_q6_axi_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("core_clk", cxo_pil_lpass_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("iface_clk", q6ss_ahb_lfabif_clk.c, "fe200000.qcom,lpass"),
+ CLK_LOOKUP("reg_clk", q6ss_ahbm_clk.c, "fe200000.qcom,lpass"),
+
+ /* PIL-MODEM */
+ CLK_LOOKUP("xo", cxo_pil_mss_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "fc880000.qcom,mss"),
+ CLK_LOOKUP("mem_clk", gcc_boot_rom_ahb_clk.c, "fc880000.qcom,mss"),
+
+ /* SPS */
+ CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
+ CLK_LOOKUP("inactivity_clk", gcc_bam_dma_inactivity_timers_clk.c,
+ "msm_sps"),
+ CLK_LOOKUP("dfab_clk", pnoc_sps_clk.c, "msm_sps"),
+
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991f000.serial"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart3_apps_clk.c, "f991f000.serial"),
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9928000.spi"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, "f9928000.spi"),
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9925000.i2c"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup3_i2c_apps_clk.c, "f9925000.i2c"),
+
+ CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f991d000.uart"),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart1_apps_clk.c, "f991d000.uart"),
+
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup1_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup2_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup2_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup3_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup4_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup4_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup5_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup5_spi_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup6_i2c_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_qup6_spi_apps_clk.c, ""),
+
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart2_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart4_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart5_apps_clk.c, ""),
+ CLK_LOOKUP("core_clk", gcc_blsp1_uart6_apps_clk.c, ""),
+
+ CLK_LOOKUP("iface_clk", gcc_prng_ahb_clk.c, "f9bff000.qcom,msm-rng"),
+
+ CLK_LOOKUP("core_clk", gcc_pdm2_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gcc_pdm_ahb_clk.c, ""),
+
+ CLK_LOOKUP("iface_clk", gcc_sdcc2_ahb_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("core_clk", gcc_sdcc2_apps_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("bus_clk", pnoc_sdcc2_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("iface_clk", gcc_sdcc3_ahb_clk.c, "msm_sdcc.3"),
+ CLK_LOOKUP("core_clk", gcc_sdcc3_apps_clk.c, "msm_sdcc.3"),
+ CLK_LOOKUP("bus_clk", pnoc_sdcc3_clk.c, "msm_sdcc.3"),
+
+ CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c, "f9a55000.usb"),
+ CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c, "f9a55000.usb"),
+ CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c, ""),
+ CLK_LOOKUP("inactivity_clk", gcc_usb_hsic_io_cal_sleep_clk.c,
+ "msm_hsic_host"),
+
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcedev"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcedev"),
+
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcrypto"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcrypto"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "fd400000.qcom,qcrypto"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "fd400000.qcom,qcrypto"),
+
+ /* RPM and voter clocks */
+ CLK_LOOKUP("bus_clk", snoc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", pnoc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", cnoc_clk.c, ""),
+ CLK_LOOKUP("mem_clk", bimc_clk.c, ""),
+ CLK_LOOKUP("bus_clk", snoc_a_clk.c, ""),
+ CLK_LOOKUP("bus_clk", pnoc_a_clk.c, ""),
+ CLK_LOOKUP("bus_clk", cnoc_a_clk.c, ""),
+ CLK_LOOKUP("mem_clk", bimc_a_clk.c, ""),
+
+ CLK_LOOKUP("bus_clk", cnoc_msmbus_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_a_clk", cnoc_msmbus_a_clk.c, "msm_config_noc"),
+ CLK_LOOKUP("bus_clk", snoc_msmbus_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_a_clk", snoc_msmbus_a_clk.c, "msm_sys_noc"),
+ CLK_LOOKUP("bus_clk", pnoc_msmbus_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("bus_a_clk", pnoc_msmbus_a_clk.c, "msm_periph_noc"),
+ CLK_LOOKUP("mem_clk", bimc_msmbus_clk.c, "msm_bimc"),
+ CLK_LOOKUP("mem_a_clk", bimc_msmbus_a_clk.c, "msm_bimc"),
+
+ CLK_LOOKUP("a7_m_clk", a7_m_clk, ""),
+
+ /* CoreSight clocks */
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc322000.tmc"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc318000.tpiu"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31c000.replicator"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc307000.tmc"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31b000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc319000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc31a000.funnel"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc321000.stm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.etm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc332000.jtagmm"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc308000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc309000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30a000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30b000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30c000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30d000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30e000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc30f000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc310000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "fc333000.cti"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "f9011038.hwevent"),
+
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc322000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc318000.tpiu"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31c000.replicator"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc307000.tmc"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31b000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc319000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc31a000.funnel"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc321000.stm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.etm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc332000.jtagmm"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc308000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc309000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30a000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30b000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30c000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30d000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30e000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc30f000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc310000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "fc333000.cti"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "f9011038.hwevent"),
+
+ /* Misc rcgs without clients */
+ CLK_LOOKUP("", usb30_master_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup1_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup1_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup2_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup2_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup3_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup3_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup4_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup4_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup5_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup5_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup6_i2c_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_qup6_spi_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart1_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart2_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart3_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart4_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart5_apps_clk_src.c, ""),
+ CLK_LOOKUP("", blsp1_uart6_apps_clk_src.c, ""),
+ CLK_LOOKUP("", pcie_aux_clk_src.c, ""),
+ CLK_LOOKUP("", pcie_pipe_clk_src.c, ""),
+ CLK_LOOKUP("", pdm2_clk_src.c, ""),
+ CLK_LOOKUP("", sdcc2_apps_clk_src.c, ""),
+ CLK_LOOKUP("", sdcc3_apps_clk_src.c, ""),
+ CLK_LOOKUP("", usb3_aux_clk_src.c, ""),
+ CLK_LOOKUP("", usb3_pipe_clk_src.c, ""),
+ CLK_LOOKUP("", usb30_mock_utmi_clk_src.c, ""),
+ CLK_LOOKUP("", usb_hs_system_clk_src.c, ""),
+ CLK_LOOKUP("", usb_hsic_clk_src.c, ""),
+ CLK_LOOKUP("", usb_hsic_io_cal_clk_src.c, ""),
+ CLK_LOOKUP("", usb_hsic_system_clk_src.c, ""),
+ CLK_LOOKUP("", usb_hsic_xcvr_fs_clk_src.c, ""),
+
+ CLK_LOOKUP("", gcc_pcie_axi_clk.c, ""),
+ CLK_LOOKUP("", gcc_pcie_axi_mstr_clk.c, ""),
+ CLK_LOOKUP("", gcc_pcie_cfg_ahb_clk.c, ""),
+ CLK_LOOKUP("", gcc_pcie_pipe_clk.c, ""),
+ CLK_LOOKUP("", gcc_pcie_sleep_clk.c, ""),
+ CLK_LOOKUP("", gcc_sys_noc_usb3_axi_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb3_aux_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb3_pipe_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb30_master_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb30_mock_utmi_clk.c, ""),
+ CLK_LOOKUP("", gcc_usb30_sleep_clk.c, ""),
+};
+
+static void __init reg_init(void)
+{
+ u32 regval;
+
+ /* Vote for GPLL0 to turn on. Needed by acpuclock. */
+ regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+ regval |= BIT(0);
+ writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));
+}
+
+static void __init msmkrypton_clock_post_init(void)
+{
+ /*
+ * Hold an active set vote for CXO; this is because CXO is expected
+ * to remain on whenever CPUs aren't power collapsed.
+ */
+ clk_prepare_enable(&xo_a_clk.c);
+}
+
+#define GCC_CC_PHYS 0xFC400000
+#define GCC_CC_SIZE SZ_8K
+
+#define LPASS_CC_PHYS 0xFE000000
+#define LPASS_CC_SIZE SZ_256K
+
+#define APCS_GLB_PHYS 0xF9010000
+#define APCS_GLB_SIZE 0x38
+
+#define APCS_GCC_PHYS 0xF9011000
+#define APCS_GCC_SIZE 0x1C
+
+#define APCS_ACC_PHYS 0xF9008000
+#define APCS_ACC_SIZE 0x40
+
+static void __init msmkrypton_clock_pre_init(void)
+{
+ virt_bases[GCC_BASE] = ioremap(GCC_CC_PHYS, GCC_CC_SIZE);
+ if (!virt_bases[GCC_BASE])
+ panic("clock-krypton: Unable to ioremap GCC memory!");
+
+ virt_bases[LPASS_BASE] = ioremap(LPASS_CC_PHYS, LPASS_CC_SIZE);
+ if (!virt_bases[LPASS_BASE])
+ panic("clock-8226: Unable to ioremap LPASS_CC memory!");
+
+ virt_bases[APCS_GLB_BASE] = ioremap(APCS_GLB_PHYS, APCS_GLB_SIZE);
+ if (!virt_bases[APCS_GLB_BASE])
+ panic("clock-krypton: Unable to ioremap APCS_GLB memory!");
+
+ virt_bases[APCS_GCC_BASE] = ioremap(APCS_GCC_PHYS, APCS_GCC_SIZE);
+ if (!virt_bases[APCS_GCC_BASE])
+ panic("clock-krypton: Unable to ioremap APCS_GCC memory!");
+
+ virt_bases[APCS_ACC_BASE] = ioremap(APCS_ACC_PHYS, APCS_ACC_SIZE);
+ if (!virt_bases[APCS_ACC_BASE])
+ panic("clock-krypton: Unable to ioremap APCS_PLL memory!");
+
+ vdd_dig.regulator[0] = regulator_get(NULL, "vdd_dig");
+ if (IS_ERR(vdd_dig.regulator[0]))
+ panic("clock-krypton: Unable to get the vdd_dig regulator!");
+
+ enable_rpm_scaling();
+
+ reg_init();
+}
+
struct clock_init_data msmkrypton_clock_init_data __initdata = {
- .table = msm_clocks_dummy,
- .size = ARRAY_SIZE(msm_clocks_dummy),
+ .table = msm_clocks_krypton,
+ .size = ARRAY_SIZE(msm_clocks_krypton),
+ .pre_init = msmkrypton_clock_pre_init,
+ .post_init = msmkrypton_clock_post_init,
};
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 6efab5b..16338a9 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -136,7 +136,7 @@
}
EXPORT_SYMBOL(msm_qdss_csr_disable_flush);
-int coresight_csr_hwctrl_set(phys_addr_t addr, uint32_t val)
+int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val)
{
struct csr_drvdata *drvdata = csrdrvdata;
int ret = 0;
diff --git a/drivers/coresight/coresight-hwevent.c b/drivers/coresight/coresight-hwevent.c
index 269d56e..4f75bcd 100644
--- a/drivers/coresight/coresight-hwevent.c
+++ b/drivers/coresight/coresight-hwevent.c
@@ -130,11 +130,11 @@
{
struct hwevent_drvdata *drvdata = dev_get_drvdata(dev->parent);
void *hwereg;
- phys_addr_t addr;
- uint32_t val;
+ unsigned long long addr;
+ unsigned long val;
int ret, i;
- if (sscanf(buf, "%x %x", &addr, &val) != 2)
+ if (sscanf(buf, "%llx %lx", &addr, &val) != 2)
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -153,7 +153,7 @@
drvdata->hmux[i].end -
drvdata->hmux[i].start);
if (!hwereg) {
- dev_err(dev, "unable to map address 0x%x\n",
+ dev_err(dev, "unable to map address 0x%llx\n",
addr);
ret = -ENOMEM;
goto err;
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index 3ad1f34..fae1232 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -47,13 +47,13 @@
extern void msm_qdss_csr_enable_bam_to_usb(void);
extern void msm_qdss_csr_disable_bam_to_usb(void);
extern void msm_qdss_csr_disable_flush(void);
-extern int coresight_csr_hwctrl_set(phys_addr_t addr, uint32_t val);
+extern int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val);
extern void coresight_csr_set_byte_cntr(uint32_t);
#else
static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
static inline void msm_qdss_csr_disable_flush(void) {}
-static inline int coresight_csr_hwctrl_set(phys_addr_t addr,
+static inline int coresight_csr_hwctrl_set(uint64_t addr,
uint32_t val) { return -ENOSYS; }
static inline void coresight_csr_set_byte_cntr(uint32_t val) {}
#endif
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index a052bd3..aaa2fc8 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -692,4 +692,16 @@
default "0"
help
this provide the sensor position setting , value is between 0~7
+
+config SENSORS_STK3X1X
+ tristate "STK3X1X device driver"
+ depends on I2C
+ default n
+ help
+ Say Y here you want to enable for the sitronix stk3x1x
+ light and proximity sensors driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called stk3x1x.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 4f29e05..445fba0 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -64,3 +64,4 @@
obj-$(CONFIG_BMP18X) += bmp18x-core.o
obj-$(CONFIG_BMP18X_I2C) += bmp18x-i2c.o
obj-$(CONFIG_SENSORS_MMA8X5X) += mma8x5x.o
+obj-$(CONFIG_SENSORS_STK3X1X) += stk3x1x.o
diff --git a/drivers/input/misc/stk3x1x.c b/drivers/input/misc/stk3x1x.c
index 6e6b9ea..61f3530 100644
--- a/drivers/input/misc/stk3x1x.c
+++ b/drivers/input/misc/stk3x1x.c
@@ -43,6 +43,10 @@
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
+#include <linux/regulator/consumer.h>
+#ifdef CONFIG_OF
+#include <linux/of_gpio.h>
+#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
@@ -169,6 +173,12 @@
#define ALS_NAME "lightsensor-level"
#define PS_NAME "proximity"
+/* POWER SUPPLY VOLTAGE RANGE */
+#define STK3X1X_VDD_MIN_UV 2000000
+#define STK3X1X_VDD_MAX_UV 3300000
+#define STK3X1X_VIO_MIN_UV 1750000
+#define STK3X1X_VIO_MAX_UV 1950000
+
struct stk3x1x_data {
struct i2c_client *client;
#if (!defined(STK_POLL_PS) || !defined(STK_POLL_ALS))
@@ -205,6 +215,9 @@
struct work_struct stk_als_work;
struct workqueue_struct *stk_als_wq;
#endif
+ struct regulator *vdd;
+ struct regulator *vio;
+ bool power_enabled;
};
#if( !defined(CONFIG_STK_PS_ALS_USE_CHANGE_THRESHOLD))
@@ -1412,15 +1425,14 @@
return size;
}
-
static struct device_attribute als_enable_attribute = __ATTR(enable,0664,stk_als_enable_show,stk_als_enable_store);
static struct device_attribute als_lux_attribute = __ATTR(lux,0664,stk_als_lux_show,stk_als_lux_store);
static struct device_attribute als_code_attribute = __ATTR(code, 0444, stk_als_code_show, NULL);
static struct device_attribute als_transmittance_attribute = __ATTR(transmittance,0664,stk_als_transmittance_show,stk_als_transmittance_store);
-static struct device_attribute als_poll_delay_attribute = __ATTR(delay,0664,stk_als_delay_show,stk_als_delay_store);
+static struct device_attribute als_poll_delay_attribute =
+ __ATTR(poll_delay, 0664, stk_als_delay_show, stk_als_delay_store);
static struct device_attribute als_ir_code_attribute = __ATTR(ircode,0444,stk_als_ir_code_show,NULL);
-
static struct attribute *stk_als_attrs [] =
{
&als_enable_attribute.attr,
@@ -1433,7 +1445,6 @@
};
static struct attribute_group stk_als_attribute_group = {
- .name = "driver",
.attrs = stk_als_attrs,
};
@@ -1465,7 +1476,6 @@
};
static struct attribute_group stk_ps_attribute_group = {
- .name = "driver",
.attrs = stk_ps_attrs,
};
@@ -1793,6 +1803,205 @@
}
#endif //#ifdef CONFIG_HAS_EARLYSUSPEND
+static int stk3x1x_power_on(struct stk3x1x_data *data, bool on)
+{
+ int ret = 0;
+
+ if (!on && data->power_enabled) {
+ ret = regulator_disable(data->vdd);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator vdd disable failed ret=%d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_disable(data->vio);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator vio disable failed ret=%d\n", ret);
+ regulator_enable(data->vdd);
+ }
+ } else if (on && !data->power_enabled) {
+
+ ret = regulator_enable(data->vdd);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator vdd enable failed ret=%d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_enable(data->vio);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator vio enable failed ret=%d\n", ret);
+ regulator_disable(data->vdd);
+ }
+ } else {
+ dev_warn(&data->client->dev,
+ "Power on=%d. enabled=%d\n",
+ on, data->power_enabled);
+ }
+
+ return ret;
+}
+
+static int stk3x1x_power_init(struct stk3x1x_data *data, bool on)
+{
+ int ret;
+
+ if (!on) {
+ if (regulator_count_voltages(data->vdd) > 0)
+ regulator_set_voltage(data->vdd,
+ 0, STK3X1X_VDD_MAX_UV);
+
+ regulator_put(data->vdd);
+
+ if (regulator_count_voltages(data->vio) > 0)
+ regulator_set_voltage(data->vio,
+ 0, STK3X1X_VIO_MAX_UV);
+
+ regulator_put(data->vio);
+ } else {
+ data->vdd = regulator_get(&data->client->dev, "vdd");
+ if (IS_ERR(data->vdd)) {
+ ret = PTR_ERR(data->vdd);
+ dev_err(&data->client->dev,
+ "Regulator get failed vdd ret=%d\n", ret);
+ return ret;
+ }
+
+ if (regulator_count_voltages(data->vdd) > 0) {
+ ret = regulator_set_voltage(data->vdd,
+ STK3X1X_VDD_MIN_UV,
+ STK3X1X_VDD_MAX_UV);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator set failed vdd ret=%d\n",
+ ret);
+ goto reg_vdd_put;
+ }
+ }
+
+ data->vio = regulator_get(&data->client->dev, "vio");
+ if (IS_ERR(data->vio)) {
+ ret = PTR_ERR(data->vio);
+ dev_err(&data->client->dev,
+ "Regulator get failed vio ret=%d\n", ret);
+ goto reg_vdd_set;
+ }
+
+ if (regulator_count_voltages(data->vio) > 0) {
+ ret = regulator_set_voltage(data->vio,
+ STK3X1X_VIO_MIN_UV,
+ STK3X1X_VIO_MAX_UV);
+ if (ret) {
+ dev_err(&data->client->dev,
+ "Regulator set failed vio ret=%d\n", ret);
+ goto reg_vio_put;
+ }
+ }
+ }
+
+ return 0;
+
+reg_vio_put:
+ regulator_put(data->vio);
+reg_vdd_set:
+ if (regulator_count_voltages(data->vdd) > 0)
+ regulator_set_voltage(data->vdd, 0, STK3X1X_VDD_MAX_UV);
+reg_vdd_put:
+ regulator_put(data->vdd);
+ return ret;
+}
+
+#ifdef CONFIG_OF
+static int stk3x1x_parse_dt(struct device *dev,
+ struct stk3x1x_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ u32 temp_val;
+
+ pdata->int_pin = of_get_named_gpio_flags(np, "stk,irq-gpio",
+ 0, &pdata->int_flags);
+ if (pdata->int_pin < 0) {
+ dev_err(dev, "Unable to read irq-gpio\n");
+ return pdata->int_pin;
+ }
+
+ rc = of_property_read_u32(np, "stk,transmittance", &temp_val);
+ if (!rc)
+ pdata->transmittance = temp_val;
+ else {
+ dev_err(dev, "Unable to read transmittance\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,state-reg", &temp_val);
+ if (!rc)
+ pdata->state_reg = temp_val;
+ else {
+ dev_err(dev, "Unable to read state-reg\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,psctrl-reg", &temp_val);
+ if (!rc)
+ pdata->psctrl_reg = (u8)temp_val;
+ else {
+ dev_err(dev, "Unable to read psctrl-reg\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,alsctrl-reg", &temp_val);
+ if (!rc)
+ pdata->alsctrl_reg = (u8)temp_val;
+ else {
+ dev_err(dev, "Unable to read alsctrl-reg\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,ledctrl-reg", &temp_val);
+ if (!rc)
+ pdata->ledctrl_reg = (u8)temp_val;
+ else {
+ dev_err(dev, "Unable to read ledctrl-reg\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,wait-reg", &temp_val);
+ if (!rc)
+ pdata->wait_reg = (u8)temp_val;
+ else {
+ dev_err(dev, "Unable to read wait-reg\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,ps-thdh", &temp_val);
+ if (!rc)
+ pdata->ps_thd_h = (u16)temp_val;
+ else {
+ dev_err(dev, "Unable to read ps-thdh\n");
+ return rc;
+ }
+
+ rc = of_property_read_u32(np, "stk,ps-thdl", &temp_val);
+ if (!rc)
+ pdata->ps_thd_l = (u16)temp_val;
+ else {
+ dev_err(dev, "Unable to read ps-thdl\n");
+ return rc;
+ }
+
+ return 0;
+}
+#else
+static int stk3x1x_parse_dt(struct device *dev,
+ struct stk3x1x_platform_data *pdata)
+{
+ return -ENODEV;
+}
+#endif /* !CONFIG_OF */
static int stk3x1x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -1827,20 +2036,33 @@
#ifdef STK_POLL_PS
wake_lock_init(&ps_data->ps_nosuspend_wl,WAKE_LOCK_SUSPEND, "stk_nosuspend_wakelock");
#endif
- if(client->dev.platform_data != NULL)
- {
- plat_data = client->dev.platform_data;
- ps_data->als_transmittance = plat_data->transmittance;
- ps_data->int_pin = plat_data->int_pin;
- if(ps_data->als_transmittance == 0)
- {
- printk(KERN_ERR "%s: Please set als_transmittance in platform data\n", __func__);
- goto err_als_input_allocate;
+ if (client->dev.of_node) {
+ plat_data = devm_kzalloc(&client->dev,
+ sizeof(struct stk3x1x_platform_data), GFP_KERNEL);
+ if (!plat_data) {
+ dev_err(&client->dev, "Failed to allocate memory\n");
+ return -ENOMEM;
}
+
+ err = stk3x1x_parse_dt(&client->dev, plat_data);
+ dev_err(&client->dev,
+ "%s: stk3x1x_parse_dt ret=%d\n", __func__, err);
+ if (err)
+ return err;
+ } else
+ plat_data = client->dev.platform_data;
+
+ if (!plat_data) {
+ dev_err(&client->dev,
+ "%s: no stk3x1x platform data!\n", __func__);
+ goto err_als_input_allocate;
}
- else
- {
- printk(KERN_ERR "%s: no stk3x1x platform data!\n", __func__);
+ ps_data->als_transmittance = plat_data->transmittance;
+ ps_data->int_pin = plat_data->int_pin;
+
+ if (ps_data->als_transmittance == 0) {
+ dev_err(&client->dev,
+ "%s: Please set als_transmittance\n", __func__);
goto err_als_input_allocate;
}
@@ -1913,6 +2135,14 @@
goto err_stk3x1x_setup_irq;
#endif
+ err = stk3x1x_power_init(ps_data, true);
+ if (err)
+ goto err_power_init;
+
+ err = stk3x1x_power_on(ps_data, true);
+ if (err)
+ goto err_power_on;
+
err = stk3x1x_init_all_setting(client, plat_data);
if(err < 0)
goto err_init_all_setting;
@@ -1926,6 +2156,10 @@
return 0;
err_init_all_setting:
+ stk3x1x_power_on(ps_data, false);
+err_power_on:
+ stk3x1x_power_init(ps_data, false);
+err_power_init:
#ifndef STK_POLL_PS
free_irq(ps_data->irq, ps_data);
gpio_free(plat_data->int_pin);
@@ -2001,11 +2235,17 @@
};
MODULE_DEVICE_TABLE(i2c, stk_ps_id);
+static struct of_device_id stk_match_table[] = {
+ { .compatible = "stk,stk3x1x", },
+ { },
+};
+
static struct i2c_driver stk_ps_driver =
{
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
+ .of_match_table = stk_match_table,
},
.probe = stk3x1x_probe,
.remove = stk3x1x_remove,
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index c70e151..0313161 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -353,6 +353,7 @@
set_fmt_fail:
kzfree(sp->vb2_q.drv_priv);
+ sp->vb2_q.drv_priv = NULL;
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index aa6f034..2ea4388 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -501,7 +501,8 @@
(int) buf_cmd.vaddr, buf_cmd.y_len);
buf_p->y_buffer_addr = msm_jpeg_platform_v2p(pgmn_dev, buf_cmd.fd,
- buf_cmd.y_len + buf_cmd.cbcr_len + buf_cmd.pln2_len,
+ buf_cmd.y_len + buf_cmd.cbcr_len +
+ buf_cmd.pln2_len + buf_cmd.offset,
&buf_p->file, &buf_p->handle, pgmn_dev->domain_num) +
buf_cmd.offset + buf_cmd.y_off;
buf_p->y_len = buf_cmd.y_len;
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 4fa3085..7f4f231 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
@@ -292,7 +292,7 @@
static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
struct msm_camera_cci_ctrl *c_ctrl)
{
- uint32_t rc = 0;
+ int32_t rc = 0;
uint32_t val = 0;
int32_t read_words = 0, exp_words = 0;
int32_t index = 0, first_byte = 0;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
index ac697fb..c713c85 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -19,7 +19,7 @@
#include <media/msm_cam_sensor.h>
#include "msm_sd.h"
-#define MAX_LED_TRIGGERS 2
+#define MAX_LED_TRIGGERS 3
struct msm_led_flash_ctrl_t;
@@ -38,10 +38,14 @@
struct msm_sd_subdev msm_sd;
struct platform_device *pdev;
struct msm_flash_fn_t *func_tbl;
- const char *led_trigger_name[MAX_LED_TRIGGERS];
- struct led_trigger *led_trigger[MAX_LED_TRIGGERS];
- uint32_t op_current[MAX_LED_TRIGGERS];
+ const char *flash_trigger_name[MAX_LED_TRIGGERS];
+ struct led_trigger *flash_trigger[MAX_LED_TRIGGERS];
+ uint32_t flash_op_current[MAX_LED_TRIGGERS];
+ const char *torch_trigger_name;
+ struct led_trigger *torch_trigger;
+ uint32_t torch_op_current;
void *data;
+ uint32_t num_sources;
};
int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
index c6f1f72..1b0ec44 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -46,29 +46,45 @@
{
int rc = 0;
struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data;
+ uint32_t i;
CDBG("called led_state %d\n", cfg->cfgtype);
- if (!fctrl->led_trigger[0]) {
+ if (!fctrl) {
pr_err("failed\n");
return -EINVAL;
}
+
switch (cfg->cfgtype) {
case MSM_CAMERA_LED_OFF:
- led_trigger_event(fctrl->led_trigger[0], 0);
+ for (i = 0; i < fctrl->num_sources; i++)
+ if (fctrl->flash_trigger[i])
+ led_trigger_event(fctrl->flash_trigger[i], 0);
+ if (fctrl->torch_trigger)
+ led_trigger_event(fctrl->torch_trigger, 0);
break;
case MSM_CAMERA_LED_LOW:
- led_trigger_event(fctrl->led_trigger[0],
- fctrl->op_current[0] / 2);
+ if (fctrl->torch_trigger)
+ led_trigger_event(fctrl->torch_trigger,
+ fctrl->torch_op_current);
break;
case MSM_CAMERA_LED_HIGH:
- led_trigger_event(fctrl->led_trigger[0], fctrl->op_current[0]);
+ if (fctrl->torch_trigger)
+ led_trigger_event(fctrl->torch_trigger, 0);
+ for (i = 0; i < fctrl->num_sources; i++)
+ if (fctrl->flash_trigger[i])
+ led_trigger_event(fctrl->flash_trigger[i],
+ fctrl->flash_op_current[i]);
break;
case MSM_CAMERA_LED_INIT:
case MSM_CAMERA_LED_RELEASE:
- led_trigger_event(fctrl->led_trigger[0], 0);
+ for (i = 0; i < fctrl->num_sources; i++)
+ if (fctrl->flash_trigger[i])
+ led_trigger_event(fctrl->flash_trigger[i], 0);
+ if (fctrl->torch_trigger)
+ led_trigger_event(fctrl->torch_trigger, 0);
break;
default:
@@ -109,6 +125,7 @@
}
fctrl.pdev = pdev;
+ fctrl.num_sources = 0;
rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
if (rc < 0) {
@@ -124,6 +141,7 @@
pr_err("failed\n");
return -EINVAL;
}
+ fctrl.num_sources = count;
for (i = 0; i < count; i++) {
flash_src_node = of_parse_phandle(of_node,
"qcom,flash-source", i);
@@ -134,17 +152,18 @@
rc = of_property_read_string(flash_src_node,
"linux,default-trigger",
- &fctrl.led_trigger_name[i]);
+ &fctrl.flash_trigger_name[i]);
if (rc < 0) {
pr_err("failed\n");
of_node_put(flash_src_node);
continue;
}
- CDBG("default trigger %s\n", fctrl.led_trigger_name[i]);
+ CDBG("default trigger %s\n",
+ fctrl.flash_trigger_name[i]);
rc = of_property_read_u32(flash_src_node,
- "qcom,current", &fctrl.op_current[i]);
+ "qcom,current", &fctrl.flash_op_current[i]);
if (rc < 0) {
pr_err("failed rc %d\n", rc);
of_node_put(flash_src_node);
@@ -153,10 +172,41 @@
of_node_put(flash_src_node);
- CDBG("max_current[%d] %d\n", i, fctrl.op_current[i]);
+ CDBG("max_current[%d] %d\n",
+ i, fctrl.flash_op_current[i]);
- led_trigger_register_simple(fctrl.led_trigger_name[i],
- &fctrl.led_trigger[i]);
+ led_trigger_register_simple(fctrl.flash_trigger_name[i],
+ &fctrl.flash_trigger[i]);
+ }
+
+ /* Torch source */
+ flash_src_node = of_parse_phandle(of_node, "qcom,torch-source",
+ 0);
+ if (flash_src_node) {
+ rc = of_property_read_string(flash_src_node,
+ "linux,default-trigger",
+ &fctrl.torch_trigger_name);
+ if (rc < 0) {
+ pr_err("failed\n");
+ } else {
+ CDBG("default trigger %s\n",
+ fctrl.torch_trigger_name);
+
+ rc = of_property_read_u32(flash_src_node,
+ "qcom,current",
+ &fctrl.torch_op_current);
+ if (rc < 0) {
+ pr_err("failed rc %d\n", rc);
+ } else {
+ CDBG("torch max_current %d\n",
+ fctrl.torch_op_current);
+
+ led_trigger_register_simple(
+ fctrl.torch_trigger_name,
+ &fctrl.torch_trigger);
+ }
+ }
+ of_node_put(flash_src_node);
}
}
rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 7897068..cddca74 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -683,6 +683,18 @@
.qmenu = perf_level,
.step = 0,
},
+ {
+ .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
+ .name = "Intra Refresh CIR MBS",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = MAX_INTRA_REFRESH_MBS,
+ .default_value = 0,
+ .step = 1,
+ .menu_skip_mask = 0,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_INTRA_REFRESH,
+ }
};
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1641,8 +1653,8 @@
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
- property_id =
- HAL_PARAM_VENC_INTRA_REFRESH;
+ property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
intra_refresh.air_mbs = ctrl->val;
intra_refresh.mode = ir_mode->val;
intra_refresh.air_ref = air_ref->val;
@@ -1658,8 +1670,8 @@
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
- property_id =
- HAL_PARAM_VENC_INTRA_REFRESH;
+ property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
intra_refresh.air_ref = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
intra_refresh.mode = ir_mode->val;
@@ -1676,8 +1688,7 @@
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
- property_id =
- HAL_PARAM_VENC_INTRA_REFRESH;
+ property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.cir_mbs = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
@@ -1687,6 +1698,22 @@
pdata = &intra_refresh;
break;
}
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: {
+ struct v4l2_ctrl *air_mbs, *air_ref;
+
+ air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
+ air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
+
+ property_id = HAL_PARAM_VENC_INTRA_REFRESH;
+
+ intra_refresh.cir_mbs = ctrl->val;
+ intra_refresh.air_mbs = air_mbs->val;
+ intra_refresh.air_ref = air_ref->val;
+ intra_refresh.mode = HAL_INTRA_REFRESH_CYCLIC;
+
+ pdata = &intra_refresh;
+ break;
+ }
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
property_id =
HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index b9eb8f9..de6f1d5 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -126,6 +126,11 @@
struct rds_grp_data rds_buf);
static void hci_ev_ert(struct iris_device *radio);
static int update_spur_table(struct iris_device *radio);
+static int initialise_recv(struct iris_device *radio);
+static int initialise_trans(struct iris_device *radio);
+static int is_enable_rx_possible(struct iris_device *radio);
+static int is_enable_tx_possible(struct iris_device *radio);
+
static struct v4l2_queryctrl iris_v4l2_queryctrl[] = {
{
.id = V4L2_CID_AUDIO_VOLUME,
@@ -1633,13 +1638,16 @@
__u8 status = *((__u8 *) skb->data);
struct iris_device *radio = video_get_drvdata(video_get_dev());
- if (status)
- return;
- if ((radio->mode != FM_CALIB) && (radio->mode != FM_OFF))
+ if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
- radio->mode = FM_OFF;
-
- radio_hci_req_complete(hdev, status);
+ radio_hci_req_complete(hdev, status);
+ radio->mode = FM_OFF;
+ } else if (radio->mode == FM_CALIB) {
+ radio_hci_req_complete(hdev, status);
+ } else if ((radio->mode == FM_RECV) || (radio->mode == FM_TRANS)) {
+ iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+ radio->mode = FM_OFF;
+ }
}
static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
@@ -1673,11 +1681,18 @@
struct hci_fm_conf_rsp *rsp = (void *)skb->data;
struct iris_device *radio = video_get_drvdata(video_get_dev());
- if (rsp->status)
+ if (rsp->status) {
+ radio_hci_req_complete(hdev, rsp->status);
return;
- if (radio->mode != FM_CALIB)
- iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ }
+ if (radio->mode == FM_RECV_TURNING_ON) {
+ radio->mode = FM_RECV;
+ iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ } else if (radio->mode == FM_TRANS_TURNING_ON) {
+ radio->mode = FM_TRANS;
+ iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ }
radio_hci_req_complete(hdev, rsp->status);
}
@@ -2695,7 +2710,9 @@
radio->fm_hdev);
if (retval < 0)
FMDERR("Disable Failed after calibration %d", retval);
- radio->mode = FM_TURNING_OFF;
+ else
+ radio->mode = FM_OFF;
+
return retval;
}
static int iris_vidioc_g_ctrl(struct file *file, void *priv,
@@ -3177,82 +3194,60 @@
case V4L2_CID_PRIVATE_IRIS_STATE:
switch (ctrl->value) {
case FM_RECV:
+ if (is_enable_rx_possible(radio) != 0)
+ return -EINVAL;
+ radio->mode = FM_RECV_TURNING_ON;
retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error while enabling RECV FM"
" %d\n", retval);
+ radio->mode = FM_OFF;
return retval;
+ } else {
+ initialise_recv(radio);
}
- radio->mode = FM_RECV;
- radio->mute_mode.soft_mute = CTRL_ON;
- retval = hci_set_fm_mute_mode(
- &radio->mute_mode,
- radio->fm_hdev);
- if (retval < 0) {
- FMDERR("Failed to enable Smute\n");
- return retval;
- }
- radio->stereo_mode.stereo_mode = CTRL_OFF;
- radio->stereo_mode.sig_blend = CTRL_ON;
- radio->stereo_mode.intf_blend = CTRL_ON;
- radio->stereo_mode.most_switch = CTRL_ON;
- retval = hci_set_fm_stereo_mode(
- &radio->stereo_mode,
- radio->fm_hdev);
- if (retval < 0) {
- FMDERR("Failed to set stereo mode\n");
- return retval;
- }
- radio->event_mask = SIG_LEVEL_INTR |
- RDS_SYNC_INTR | AUDIO_CTRL_INTR;
- retval = hci_conf_event_mask(&radio->event_mask,
- radio->fm_hdev);
- if (retval < 0) {
- FMDERR("Enable Async events failed");
- return retval;
- }
- retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
- radio->fm_hdev);
- if (retval < 0)
- FMDERR("Failed to get the Recv Config\n");
break;
case FM_TRANS:
+ if (!is_enable_tx_possible(radio) != 0)
+ return -EINVAL;
+ radio->mode = FM_TRANS_TURNING_ON;
retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Error while enabling TRANS FM"
" %d\n", retval);
+ radio->mode = FM_OFF;
return retval;
+ } else {
+ initialise_trans(radio);
}
- radio->mode = FM_TRANS;
- retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
- if (retval < 0)
- FMDERR("get frequency failed %d\n", retval);
break;
case FM_OFF:
radio->spur_table_size = 0;
switch (radio->mode) {
case FM_RECV:
+ radio->mode = FM_TURNING_OFF;
retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Err on disable recv FM"
" %d\n", retval);
+ radio->mode = FM_RECV;
return retval;
}
- radio->mode = FM_TURNING_OFF;
break;
case FM_TRANS:
+ radio->mode = FM_TURNING_OFF;
retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
radio->fm_hdev);
if (retval < 0) {
FMDERR("Err disabling trans FM"
" %d\n", retval);
+ radio->mode = FM_TRANS;
return retval;
}
- radio->mode = FM_TURNING_OFF;
break;
default:
retval = -EINVAL;
@@ -4132,6 +4127,73 @@
return 0;
}
+static int initialise_recv(struct iris_device *radio)
+{
+ int retval;
+
+ radio->mute_mode.soft_mute = CTRL_ON;
+ retval = hci_set_fm_mute_mode(&radio->mute_mode,
+ radio->fm_hdev);
+
+ if (retval < 0) {
+ FMDERR("Failed to enable Smute\n");
+ return retval;
+ }
+
+ radio->stereo_mode.stereo_mode = CTRL_OFF;
+ radio->stereo_mode.sig_blend = CTRL_ON;
+ radio->stereo_mode.intf_blend = CTRL_ON;
+ radio->stereo_mode.most_switch = CTRL_ON;
+ retval = hci_set_fm_stereo_mode(&radio->stereo_mode,
+ radio->fm_hdev);
+
+ if (retval < 0) {
+ FMDERR("Failed to set stereo mode\n");
+ return retval;
+ }
+
+ radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+ retval = hci_conf_event_mask(&radio->event_mask, radio->fm_hdev);
+ if (retval < 0) {
+ FMDERR("Enable Async events failed");
+ return retval;
+ }
+
+ retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("Failed to get the Recv Config\n");
+ return retval;
+}
+
+static int initialise_trans(struct iris_device *radio)
+{
+
+ int retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+ if (retval < 0)
+ FMDERR("get frequency failed %d\n", retval);
+
+ return retval;
+}
+
+static int is_enable_rx_possible(struct iris_device *radio)
+{
+ int retval = 1;
+
+ if (radio->mode == FM_OFF || radio->mode == FM_RECV)
+ retval = 0;
+
+ return retval;
+}
+
+static int is_enable_tx_possible(struct iris_device *radio)
+{
+ int retval = 1;
+
+ if (radio->mode == FM_OFF || radio->mode == FM_TRANS)
+ retval = 0;
+
+ return retval;
+}
static const struct v4l2_ioctl_ops iris_ioctl_ops = {
.vidioc_querycap = iris_vidioc_querycap,
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 657fc2f..1262306 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -81,9 +81,16 @@
#define PRONTO_PMU_SPARE_OFFSET 0x1088
-#define PRONTO_PMU_GDSCR_OFFSET 0x0024
-#define PRONTO_PMU_GDSCR_SW_COLLAPSE BIT(0)
-#define PRONTO_PMU_GDSCR_HW_CTRL BIT(1)
+#define PRONTO_PMU_COM_GDSCR_OFFSET 0x0024
+#define PRONTO_PMU_COM_GDSCR_SW_COLLAPSE BIT(0)
+#define PRONTO_PMU_COM_GDSCR_HW_CTRL BIT(1)
+
+#define PRONTO_PMU_WLAN_BCR_OFFSET 0x0050
+#define PRONTO_PMU_WLAN_BCR_BLK_ARES BIT(0)
+
+#define PRONTO_PMU_WLAN_GDSCR_OFFSET 0x0054
+#define PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE BIT(0)
+
#define PRONTO_PMU_CBCR_OFFSET 0x0008
#define PRONTO_PMU_CBCR_CLK_EN BIT(0)
@@ -118,6 +125,9 @@
#define MSM_PRONTO_PLL_BASE 0xfb21b1c0
#define PRONTO_PLL_STATUS_OFFSET 0x1c
+#define MSM_PRONTO_TXP_PHY_ABORT 0xfb080488
+#define MSM_PRONTO_BRDG_ERR_SRC 0xfb080fb0
+
#define WCNSS_DEF_WLAN_RX_BUFF_COUNT 1024
#define WCNSS_CTRL_CHANNEL "WCNSS_CTRL"
@@ -296,6 +306,8 @@
void __iomem *pronto_ccpu_base;
void __iomem *pronto_saw2_base;
void __iomem *pronto_pll_base;
+ void __iomem *wlan_tx_phy_aborts;
+ void __iomem *wlan_brdg_err_source;
void __iomem *fiq_reg;
int ssr_boot;
int nv_downloaded;
@@ -435,14 +447,14 @@
void wcnss_pronto_log_debug_regs(void)
{
void __iomem *reg_addr, *tst_addr, *tst_ctrl_addr;
- u32 reg = 0;
+ u32 reg = 0, reg2 = 0;
reg_addr = penv->msm_wcnss_base + PRONTO_PMU_SPARE_OFFSET;
reg = readl_relaxed(reg_addr);
pr_info_ratelimited("%s: PRONTO_PMU_SPARE %08x\n", __func__, reg);
- reg_addr = penv->msm_wcnss_base + PRONTO_PMU_GDSCR_OFFSET;
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_COM_GDSCR_OFFSET;
reg = readl_relaxed(reg_addr);
reg >>= 31;
@@ -451,7 +463,8 @@
__func__);
return;
}
- reg &= ~(PRONTO_PMU_GDSCR_SW_COLLAPSE | PRONTO_PMU_GDSCR_HW_CTRL);
+ reg &= ~(PRONTO_PMU_COM_GDSCR_SW_COLLAPSE
+ | PRONTO_PMU_COM_GDSCR_HW_CTRL);
writel_relaxed(reg, reg_addr);
reg_addr = penv->msm_wcnss_base + PRONTO_PMU_CBCR_OFFSET;
@@ -557,6 +570,26 @@
reg = readl_relaxed(tst_addr);
pr_info_ratelimited("%s: CTRL SEL CFG1 testbus %08x\n", __func__, reg);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_BCR_OFFSET;
+ reg = readl_relaxed(reg_addr);
+
+ reg_addr = penv->msm_wcnss_base + PRONTO_PMU_WLAN_GDSCR_OFFSET;
+ reg2 = readl_relaxed(reg_addr);
+
+ if ((reg & PRONTO_PMU_WLAN_BCR_BLK_ARES) ||
+ (reg2 & PRONTO_PMU_WLAN_GDSCR_SW_COLLAPSE)) {
+ pr_info_ratelimited("%s: Cannot log, wlan domain is power collapsed\n",
+ __func__);
+ return;
+ }
+
+ reg = readl_relaxed(penv->wlan_tx_phy_aborts);
+ pr_info_ratelimited("%s: WLAN_TX_PHY_ABORTS %08x\n", __func__, reg);
+
+ reg = readl_relaxed(penv->wlan_brdg_err_source);
+ pr_info_ratelimited("%s: WLAN_BRDG_ERR_SOURCE %08x\n", __func__, reg);
+
}
EXPORT_SYMBOL(wcnss_pronto_log_debug_regs);
@@ -1716,6 +1749,21 @@
goto fail_ioremap6;
}
+ penv->wlan_tx_phy_aborts = ioremap(MSM_PRONTO_TXP_PHY_ABORT,
+ SZ_8);
+ if (!penv->wlan_tx_phy_aborts) {
+ ret = -ENOMEM;
+ pr_err("%s: ioremap wlan TX PHY failed\n", __func__);
+ goto fail_ioremap7;
+ }
+ penv->wlan_brdg_err_source = ioremap(MSM_PRONTO_BRDG_ERR_SRC,
+ SZ_8);
+ if (!penv->wlan_brdg_err_source) {
+ ret = -ENOMEM;
+ pr_err("%s: ioremap wlan BRDG ERR failed\n", __func__);
+ goto fail_ioremap8;
+ }
+
}
/* trigger initialization of the WCNSS */
@@ -1732,6 +1780,12 @@
fail_pil:
if (penv->riva_ccu_base)
iounmap(penv->riva_ccu_base);
+ if (penv->wlan_brdg_err_source)
+ iounmap(penv->wlan_brdg_err_source);
+fail_ioremap8:
+ if (penv->wlan_tx_phy_aborts)
+ iounmap(penv->wlan_tx_phy_aborts);
+fail_ioremap7:
if (penv->pronto_pll_base)
iounmap(penv->pronto_pll_base);
fail_ioremap6:
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 408681c..8bb4f90 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -162,6 +162,11 @@
struct work_struct finish_suspend_work;
};
+struct usb_bam_hsic_host_info {
+ struct device *dev;
+ bool in_lpm;
+};
+
static spinlock_t usb_bam_ipa_handshake_info_lock;
static struct usb_bam_ipa_handshake_info info;
static spinlock_t usb_bam_peer_handshake_info_lock;
@@ -169,8 +174,7 @@
static spinlock_t usb_bam_lock; /* Protect ctx and usb_bam_connections */
static struct usb_bam_pipe_connect *usb_bam_connections;
static struct usb_bam_ctx_type ctx;
-
-static struct device *hsic_host_dev;
+static struct usb_bam_hsic_host_info hsic_host_info;
static int __usb_bam_register_wake_cb(u8 idx, int (*callback)(void *user),
void *param, bool trigger_cb_per_pipe);
@@ -184,15 +188,16 @@
pr_debug("%s: Getting hsic device %x\n", __func__,
(int)dev);
pm_runtime_get(dev);
- } else if (hsic_host_dev) {
+ } else if (hsic_host_info.dev) {
pr_debug("%s: Putting hsic device %x\n", __func__,
- (int)hsic_host_dev);
+ (int)hsic_host_info.dev);
/* Just free previous device*/
info.in_lpm[HSIC_BAM] = true;
- pm_runtime_put(hsic_host_dev);
+ pm_runtime_put(hsic_host_info.dev);
}
- hsic_host_dev = dev;
+ hsic_host_info.dev = dev;
+ hsic_host_info.in_lpm = false;
}
static int get_bam_type_from_core_name(const char *name)
@@ -847,18 +852,24 @@
return;
}
+/**
+ * usb_bam_resume_hsic_host: vote for hsic host core resume.
+ * In addition also resume all hsic pipes that are connected to
+ * the ipa peer bam.
+ *
+ * NOTE: This function should be called in a context that hold
+ * usb_bam_lock.
+ */
static void usb_bam_resume_hsic_host(void)
{
int i;
struct usb_bam_pipe_connect *pipe_iter;
- spin_lock(&usb_bam_lock);
-
/* Exit from "full suspend" in case of hsic host */
- if (hsic_host_dev && info.in_lpm[HSIC_BAM]) {
+ if (hsic_host_info.dev && info.in_lpm[HSIC_BAM]) {
pr_debug("%s: Getting hsic device %x\n", __func__,
- (int)hsic_host_dev);
- pm_runtime_get(hsic_host_dev);
+ (int)hsic_host_info.dev);
+ pm_runtime_get(hsic_host_info.dev);
info.in_lpm[HSIC_BAM] = false;
for (i = 0; i < ctx.max_connections; i++) {
@@ -873,8 +884,6 @@
}
}
}
-
- spin_unlock(&usb_bam_lock);
}
static int cons_request_resource(enum usb_bam cur_bam)
@@ -905,16 +914,26 @@
break;
case HSIC_BAM:
+ /*
+ * Vote for hsic resume, however the core
+ * resume may not be completed yet or on the other hand
+ * hsic core might already be resumed, due to a vote
+ * by other driver, in this case we will just renew our
+ * vote here.
+ */
+ usb_bam_resume_hsic_host();
- usb_bam_resume_hsic_host();
+ /*
+ * Return sucess if there are pipes connected
+ * and hsic core is actually not in lpm.
+ * If in lpm, grant will occur on resume
+ * finish (see msm_bam_hsic_notify_on_resume)
+ */
+ if (ctx.pipes_enabled_per_bam[cur_bam] &&
+ !hsic_host_info.in_lpm) {
+ ret = 0;
+ }
- /*
- * Return sucess if there are pipes connected
- * and not in lpm
- */
- if (ctx.pipes_enabled_per_bam[cur_bam] &&
- !info.in_lpm[cur_bam])
- ret = 0;
break;
case SSUSB_BAM:
default:
@@ -926,6 +945,7 @@
if (ret == -EINPROGRESS)
pr_debug("%s: EINPROGRESS on cons_request", __func__);
+
return ret;
}
@@ -968,10 +988,10 @@
* Allow to go to lpm for now. Actual state will be checked
* in msm_bam_hsic_lpm_ok() just before going to lpm.
*/
- if (hsic_host_dev && !info.in_lpm[HSIC_BAM]) {
+ if (hsic_host_info.dev && !info.in_lpm[HSIC_BAM]) {
pr_debug("%s: Putting hsic device %x\n", __func__,
- (int)hsic_host_dev);
- pm_runtime_put(hsic_host_dev);
+ (int)hsic_host_info.dev);
+ pm_runtime_put(hsic_host_info.dev);
info.in_lpm[HSIC_BAM] = true;
}
}
@@ -1315,6 +1335,8 @@
void msm_bam_wait_for_hsic_prod_granted(void)
{
+ spin_lock(&usb_bam_lock);
+
ctx.is_bam_inactivity[HSIC_BAM] = false;
/* Get back to resume state including wakeup ipa */
@@ -1322,10 +1344,19 @@
/* Ensure getting the producer resource */
wait_for_prod_granted(HSIC_BAM);
+
+ spin_unlock(&usb_bam_lock);
}
void msm_bam_hsic_notify_on_resume(void)
{
+ spin_lock(&usb_bam_lock);
+
+ hsic_host_info.in_lpm = false;
+
+ /* HSIC resume completed. Notify CONS grant if CONS was requested */
+ notify_usb_connected(HSIC_BAM);
+
/*
* This function is called to notify the usb bam driver
* that the hsic core and hsic bam hw are fully resumed
@@ -1334,6 +1365,8 @@
*/
if (ctx.inactivity_timer_ms[HSIC_BAM])
usb_bam_set_inactivity_timer(HSIC_BAM);
+
+ spin_unlock(&usb_bam_lock);
}
bool msm_bam_hsic_lpm_ok(void)
@@ -1341,7 +1374,7 @@
int i;
struct usb_bam_pipe_connect *pipe_iter;
- if (hsic_host_dev) {
+ if (hsic_host_info.dev) {
pr_debug("%s: Starting hsic full suspend sequence\n",
__func__);
@@ -1363,7 +1396,7 @@
/* HSIC host will go now to lpm */
pr_debug("%s: vote for suspend hsic %x\n",
- __func__, (int)hsic_host_dev);
+ __func__, (int)hsic_host_info.dev);
for (i = 0; i < ctx.max_connections; i++) {
pipe_iter =
@@ -1379,6 +1412,8 @@
}
}
+ hsic_host_info.in_lpm = true;
+
spin_unlock(&usb_bam_lock);
return true;
}
@@ -1392,7 +1427,7 @@
info.cur_cons_state[HSIC_BAM],
info.cur_prod_state[HSIC_BAM],
info.in_lpm[HSIC_BAM]);
- pm_runtime_get(hsic_host_dev);
+ pm_runtime_get(hsic_host_info.dev);
info.in_lpm[HSIC_BAM] = false;
spin_unlock(&usb_bam_lock);
} else
@@ -1469,11 +1504,11 @@
sps_device_reset(ctx.h_bam[cur_bam]);
/* On re-connect assume out from lpm for HSIC BAM */
- if (cur_bam == HSIC_BAM && hsic_host_dev &&
+ if (cur_bam == HSIC_BAM && hsic_host_info.dev &&
info.in_lpm[HSIC_BAM]) {
pr_debug("%s: Getting hsic device %x\n",
- __func__, (int)hsic_host_dev);
- pm_runtime_get(hsic_host_dev);
+ __func__, (int)hsic_host_info.dev);
+ pm_runtime_get(hsic_host_info.dev);
}
/* On re-connect assume out from lpm for all BAMs */
@@ -1583,8 +1618,10 @@
* until we complete releasing the hsic consumer and producer
* resources against the ipa resource manager.
*/
+ spin_lock(&usb_bam_lock);
if (pipe_connect->bam_type == HSIC_BAM)
usb_bam_resume_hsic_host();
+ spin_unlock(&usb_bam_lock);
/* Notify about wakeup / activity of the bam */
if (event_info->callback)
@@ -1660,12 +1697,12 @@
* If consumer is up, we will wait to the release consumer
* notification.
*/
- if (hsic_host_dev &&
+ if (hsic_host_info.dev &&
info.cur_cons_state[HSIC_BAM] ==
IPA_RM_RESOURCE_RELEASED && !info.in_lpm[HSIC_BAM]) {
pr_debug("%s: Putting hsic device %x\n", __func__,
- (int)hsic_host_dev);
- pm_runtime_put(hsic_host_dev);
+ (int)hsic_host_info.dev);
+ pm_runtime_put(hsic_host_info.dev);
info.in_lpm[HSIC_BAM] = true;
}
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 43d17c2..b46bbaf 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -25,6 +25,14 @@
tristate "Android log driver"
default n
+config LOGCAT_SIZE
+ int "Adjust android log buffer sizes"
+ default 256
+ depends on ANDROID_LOGGER
+ help
+ Set logger buffer size. Enter a number greater than zero.
+ Any value less than 256 is recommended. Reduce value to save kernel static memory size.
+
config ANDROID_PERSISTENT_RAM
bool
depends on HAVE_MEMBLOCK
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index e1e886c..267a8ec 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -29,6 +29,10 @@
#include <asm/ioctls.h>
+#ifndef CONFIG_LOGCAT_SIZE
+#define CONFIG_LOGCAT_SIZE 256
+#endif
+
/*
* struct logger_log - represents a specific log, such as 'main' or 'radio'
*
@@ -728,10 +732,10 @@
.size = SIZE, \
};
-DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
-DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 64*1024)
-DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
-DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024)
+DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, CONFIG_LOGCAT_SIZE*1024)
+DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, CONFIG_LOGCAT_SIZE*1024)
static struct logger_log *get_log_from_minor(int minor)
{
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 974cadc..8c3b291 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -37,7 +37,8 @@
#define MAX_RAILS 5
static struct msm_thermal_data msm_thermal_info;
-static uint32_t limited_max_freq = MSM_CPUFREQ_NO_LIMIT;
+static uint32_t limited_max_freq = UINT_MAX;
+static uint32_t limited_min_freq;
static struct delayed_work check_temp_work;
static bool core_control_enabled;
static uint32_t cpus_offlined;
@@ -139,6 +140,25 @@
#define PSM_REG_MODE_FROM_ATTRIBS(attr) \
(container_of(attr, struct psm_rail, mode_attr));
+
+static int msm_thermal_cpufreq_callback(struct notifier_block *nfb,
+ unsigned long event, void *data)
+{
+ struct cpufreq_policy *policy = data;
+
+ switch (event) {
+ case CPUFREQ_INCOMPATIBLE:
+ cpufreq_verify_within_limits(policy, limited_min_freq,
+ limited_max_freq);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msm_thermal_cpufreq_notifier = {
+ .notifier_call = msm_thermal_cpufreq_callback,
+};
+
/* If freq table exists, then we can send freq request */
static int check_freq_table(void)
{
@@ -159,37 +179,26 @@
{
int cpu = 0;
int ret = 0;
- struct cpufreq_policy *policy = NULL;
if (!freq_table_get) {
ret = check_freq_table();
if (ret) {
- pr_err("%s:Fail to get freq table\n", __func__);
+ pr_err("%s:Fail to get freq table\n", KBUILD_MODNAME);
return ret;
}
}
/* If min is larger than allowed max */
- if (min != MSM_CPUFREQ_NO_LIMIT &&
- min > table[limit_idx_high].frequency)
- min = table[limit_idx_high].frequency;
+ min = min(min, table[limit_idx_high].frequency);
- for_each_possible_cpu(cpu) {
- ret = msm_cpufreq_set_freq_limits(cpu, min, limited_max_freq);
- if (ret) {
- pr_err("%s:Fail to set limits for cpu%d\n",
- __func__, cpu);
- return ret;
- }
+ limited_min_freq = min;
- if (cpu_online(cpu)) {
- policy = cpufreq_cpu_get(cpu);
- if (!policy)
- continue;
- cpufreq_driver_target(policy, policy->cur,
- CPUFREQ_RELATION_L);
- cpufreq_cpu_put(policy);
- }
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ if (cpufreq_update_policy(cpu))
+ pr_info("%s: Unable to update policy for cpu:%d\n",
+ KBUILD_MODNAME, cpu);
}
+ put_online_cpus();
return ret;
}
@@ -584,26 +593,19 @@
{
int ret = 0;
- ret = msm_cpufreq_set_freq_limits(cpu, MSM_CPUFREQ_NO_LIMIT, max_freq);
- if (ret)
- return ret;
-
- limited_max_freq = max_freq;
- if (max_freq != MSM_CPUFREQ_NO_LIMIT)
+ if (max_freq != UINT_MAX)
pr_info("%s: Limiting cpu%d max frequency to %d\n",
KBUILD_MODNAME, cpu, max_freq);
else
pr_info("%s: Max frequency reset for cpu%d\n",
KBUILD_MODNAME, cpu);
-
- if (cpu_online(cpu)) {
- struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
- if (!policy)
- return ret;
- ret = cpufreq_driver_target(policy, policy->cur,
- CPUFREQ_RELATION_H);
- cpufreq_cpu_put(policy);
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ if (cpufreq_update_policy(cpu))
+ pr_info("%s: Unable to update policy for cpu:%d\n",
+ KBUILD_MODNAME, cpu);
}
+ put_online_cpus();
return ret;
}
@@ -764,7 +766,6 @@
static void __ref do_freq_control(long temp)
{
- int ret = 0;
int cpu = 0;
uint32_t max_freq = limited_max_freq;
@@ -784,7 +785,7 @@
limit_idx += msm_thermal_info.freq_step;
if (limit_idx >= limit_idx_high) {
limit_idx = limit_idx_high;
- max_freq = MSM_CPUFREQ_NO_LIMIT;
+ max_freq = UINT_MAX;
} else
max_freq = table[limit_idx].frequency;
}
@@ -792,17 +793,13 @@
if (max_freq == limited_max_freq)
return;
+ limited_max_freq = max_freq;
/* Update new limits */
for_each_possible_cpu(cpu) {
if (!(msm_thermal_info.freq_control_mask & BIT(cpu)))
continue;
- ret = update_cpu_max_freq(cpu, max_freq);
- if (ret)
- pr_debug(
- "%s: Unable to limit cpu%d max freq to %d\n",
- KBUILD_MODNAME, cpu, max_freq);
+ update_cpu_max_freq(cpu, max_freq);
}
-
}
static void __ref check_temp(struct work_struct *work)
@@ -909,12 +906,17 @@
cancel_delayed_work(&check_temp_work);
flush_scheduled_work();
- if (limited_max_freq == MSM_CPUFREQ_NO_LIMIT)
+ if (limited_max_freq == UINT_MAX)
return;
- for_each_possible_cpu(cpu) {
- update_cpu_max_freq(cpu, MSM_CPUFREQ_NO_LIMIT);
+ limited_max_freq = UINT_MAX;
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ if (cpufreq_update_policy(cpu))
+ pr_info("%s: Unable to update policy for cpu:%d\n",
+ KBUILD_MODNAME, cpu);
}
+ put_online_cpus();
}
static int __ref set_enabled(const char *val, const struct kernel_param *kp)
@@ -926,7 +928,7 @@
disable_msm_thermal();
else
pr_info("%s: no action for enabled = %d\n",
- KBUILD_MODNAME, enabled);
+ KBUILD_MODNAME, enabled);
pr_info("%s: enabled = %d\n", KBUILD_MODNAME, enabled);
@@ -1190,6 +1192,11 @@
return -EINVAL;
enabled = 1;
+ ret = cpufreq_register_notifier(&msm_thermal_cpufreq_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+ if (ret)
+ pr_err("%s: cannot register cpufreq notifier\n",
+ KBUILD_MODNAME);
if (num_possible_cpus() > 1)
core_control_enabled = 1;
INIT_DELAYED_WORK(&check_temp_work, check_temp);
@@ -1505,7 +1512,7 @@
key = "qcom,freq-req";
rails[i].freq_req = of_property_read_bool(child_node, key);
if (rails[i].freq_req)
- rails[i].min_level = MSM_CPUFREQ_NO_LIMIT;
+ rails[i].min_level = 0;
else {
key = "qcom,min-level";
ret = of_property_read_u32(child_node, key,
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index d1b911a..bccc504 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -626,6 +626,7 @@
struct usb_function *f)
{
struct diag_context *ctxt = func_to_diag(f);
+ unsigned long flags;
if (gadget_is_superspeed(c->cdev->gadget))
usb_free_descriptors(f->ss_descriptors);
@@ -643,7 +644,9 @@
ctxt->ch->priv_usb = NULL;
list_del(&ctxt->list_item);
/* Free any pending USB requests from last session */
+ spin_lock_irqsave(&ctxt->lock, flags);
free_reqs(ctxt);
+ spin_unlock_irqrestore(&ctxt->lock, flags);
kfree(ctxt);
}
diff --git a/include/linux/stk3x1x.h b/include/linux/stk3x1x.h
index 33625bd..d9d2cf6 100644
--- a/include/linux/stk3x1x.h
+++ b/include/linux/stk3x1x.h
@@ -23,6 +23,7 @@
uint16_t ps_thd_l;
int int_pin;
uint32_t transmittance;
+ uint32_t int_flags;
};
#endif /* __STK3X1X_H__ */
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 419e055..d28a8c0 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -627,7 +627,9 @@
FM_TRANS,
FM_RESET,
FM_CALIB,
- FM_TURNING_OFF
+ FM_TURNING_OFF,
+ FM_RECV_TURNING_ON,
+ FM_TRANS_TURNING_ON,
};
enum emphasis_type {
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0be6f11..b1dd350 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -266,6 +266,12 @@
quiet_cmd_dtc = DTC $@
cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $<
+# cat
+# ---------------------------------------------------------------------------
+# Concatentate multiple files together
+quiet_cmd_cat = CAT $@
+cmd_cat = (cat $(filter-out FORCE,$^) > $@) || (rm -f $@; false)
+
# Bzip2
# ---------------------------------------------------------------------------
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 46b0a91..8844b21 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -1157,6 +1157,16 @@
"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
};
+/*
+ * There is only one bit to select RX2 (0) or RX3 (1) so add 'ZERO' won't
+ * cause any issue to select the right input, but it eliminates that lineout
+ * is powered-up when HPH is enabled if the 'ZERO" is used in the disable
+ * sequence for lineout.
+ */
+static const char * const rx_rdac4_text[] = {
+ "ZERO", "RX3", "RX2"
+};
+
static const struct soc_enum rx_mix1_inp1_chain_enum =
SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text);
@@ -1194,6 +1204,10 @@
SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_EQ1_B1_CTL, 0, 6,
iir1_inp1_text);
+static const struct soc_enum rx_rdac4_enum =
+ SOC_ENUM_SINGLE(MSM8X10_WCD_A_CDC_CONN_LO_DAC_CTL, 0, 3,
+ rx_rdac4_text);
+
static const struct snd_kcontrol_new rx_mix1_inp1_mux =
SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
@@ -1221,6 +1235,9 @@
static const struct snd_kcontrol_new rx2_mix2_inp1_mux =
SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+static const struct snd_kcontrol_new rx_dac4_mux =
+ SOC_DAPM_ENUM("RDAC4 MUX Mux", rx_rdac4_enum);
+
static int msm8x10_wcd_put_dec_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1312,6 +1329,10 @@
SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
};
+static const struct snd_kcontrol_new spkr_switch[] = {
+ SOC_DAPM_SINGLE("Switch", MSM8X10_WCD_A_SPKR_DRV_DAC_CTL, 2, 1, 0)
+};
+
static void msm8x10_wcd_codec_enable_adc_block(struct snd_soc_codec *codec,
int enable)
{
@@ -1791,13 +1812,6 @@
return 0;
}
-static int msm8x10_wcd_spk_dac_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- dev_dbg(w->codec->dev, "%s %s %d\n", __func__, w->name, event);
- return 0;
-}
-
static const struct snd_soc_dapm_route audio_map[] = {
{"RX_I2S_CLK", NULL, "CDC_CONN"},
{"I2S RX1", NULL, "RX_I2S_CLK"},
@@ -1837,11 +1851,15 @@
{"LINEOUT PA", NULL, "CP"},
{"LINEOUT PA", NULL, "LINEOUT DAC"},
+ {"LINEOUT DAC", NULL, "RDAC4 MUX"},
+
+ {"RDAC4 MUX", "RX2", "RX2 CHAIN"},
+ {"RDAC4 MUX", "RX3", "RX3 CHAIN"},
{"CP", NULL, "CP_REGULATOR"},
{"CP", NULL, "RX_BIAS"},
{"SPK PA", NULL, "SPK DAC"},
- {"SPK DAC", NULL, "RX3 CHAIN"},
+ {"SPK DAC", "Switch", "RX3 CHAIN"},
{"RX1 CHAIN", NULL, "RX1 CLK"},
{"RX2 CHAIN", NULL, "RX2 CLK"},
@@ -2270,6 +2288,9 @@
msm8x10_wcd_hphr_dac_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0,
+ spkr_switch, ARRAY_SIZE(spkr_switch)),
+
/* Speaker */
SND_SOC_DAPM_OUTPUT("LINEOUT"),
SND_SOC_DAPM_OUTPUT("SPK_OUT"),
@@ -2289,10 +2310,6 @@
msm8x10_wcd_lineout_dac_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_DAC_E("SPK DAC", NULL, SND_SOC_NOPM, 0, 0,
- msm8x10_wcd_spk_dac_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -2340,6 +2357,8 @@
&rx1_mix2_inp1_mux),
SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0,
&rx2_mix2_inp1_mux),
+ SND_SOC_DAPM_MUX("RDAC4 MUX", SND_SOC_NOPM, 0, 0,
+ &rx_dac4_mux),
SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
ON_DEMAND_MICBIAS, 0,
@@ -2512,6 +2531,8 @@
/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
{MSM8X10_WCD_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
+ /* Disable REF_EN for MSM8X10_WCD_A_SPKR_DRV_DAC_CTL */
+ {MSM8X10_WCD_A_SPKR_DRV_DAC_CTL, 0x04, 0x00},
};
static void msm8x10_wcd_codec_init_reg(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index ff190cd..af2c53e 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -4589,7 +4589,7 @@
struct wcd9xxx_mbhc *mbhc)
{
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
- 0x0C, 0x04);
+ 0x04, 0x04);
snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0xE0, 0xE0);
}
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index f09e643..7820cd0 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -91,6 +91,22 @@
#define WCD9XXX_MEAS_DELTA_MAX_MV 50
#define WCD9XXX_MEAS_INVALD_RANGE_LOW_MV 20
#define WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV 80
+
+/*
+ * Invalid voltage range for the detection
+ * of plug type with current source
+ */
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 110
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV 265
+
+/*
+ * Threshold used to detect euro headset
+ * with current source
+ */
+#define WCD9XXX_CS_GM_SWAP_THRES_MIN_MV 10
+#define WCD9XXX_CS_GM_SWAP_THRES_MAX_MV 40
+
+#define WCD9XXX_MBHC_NSC_CS 9
#define WCD9XXX_GM_SWAP_THRES_MIN_MV 150
#define WCD9XXX_GM_SWAP_THRES_MAX_MV 650
#define WCD9XXX_THRESHOLD_MIC_THRESHOLD 200
@@ -102,6 +118,11 @@
#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_DEFAULT 28
+#define WCD9XXX_V_CS_HS_MAX 500
+#define WCD9XXX_V_CS_NO_MIC 5
+#define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80
+#define WCD9XXX_CS_MEAS_DELTA_MAX_MV 10
+
static bool detect_use_vddio_switch = true;
struct wcd9xxx_mbhc_detect {
@@ -111,6 +132,7 @@
bool swap_gnd;
bool vddio;
bool hwvalue;
+ bool mic_bias;
/* internal purpose from here */
bool _above_no_mic;
bool _below_v_hs_max;
@@ -970,7 +992,7 @@
}
static s32 __wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce,
- u16 bias_value, s16 z)
+ u16 bias_value, s16 z, u32 micb_mv)
{
s16 value, mb;
s32 mv;
@@ -978,10 +1000,10 @@
value = bias_value;
if (dce) {
mb = (mbhc->mbhc_data.dce_mb);
- mv = (value - z) * (s32)mbhc->mbhc_data.micb_mv / (mb - z);
+ mv = (value - z) * (s32)micb_mv / (mb - z);
} else {
mb = (mbhc->mbhc_data.sta_mb);
- mv = (value - z) * (s32)mbhc->mbhc_data.micb_mv / (mb - z);
+ mv = (value - z) * (s32)micb_mv / (mb - z);
}
return mv;
@@ -992,11 +1014,13 @@
{
s16 z;
z = dce ? (s16)mbhc->mbhc_data.dce_z : (s16)mbhc->mbhc_data.sta_z;
- return __wcd9xxx_codec_sta_dce_v(mbhc, dce, bias_value, z);
+ return __wcd9xxx_codec_sta_dce_v(mbhc, dce, bias_value, z,
+ mbhc->mbhc_data.micb_mv);
}
/* called only from interrupt which is under codec_resource_lock acquisition */
-static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc)
+static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
+ bool is_cs_enable)
{
struct snd_soc_codec *codec = mbhc->codec;
short bias_value;
@@ -1048,7 +1072,8 @@
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x2, 0x2);
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x8, 0x8);
- wcd9xxx_calibrate_hs_polling(mbhc);
+ if (!is_cs_enable)
+ wcd9xxx_calibrate_hs_polling(mbhc);
/* don't flip override */
bias_value = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
@@ -1144,6 +1169,158 @@
return status;
}
+static enum wcd9xxx_mbhc_plug_type
+wcd9xxx_cs_find_plug_type(struct wcd9xxx_mbhc *mbhc,
+ struct wcd9xxx_mbhc_detect *dt, const int size,
+ bool highhph,
+ unsigned long event_state)
+{
+ int i;
+ int vdce, mb_mv;
+ int ch, sz, delta_thr;
+ int minv = 0, maxv = INT_MIN;
+ struct wcd9xxx_mbhc_detect *d = dt;
+ struct wcd9xxx_mbhc_detect *dprev = d, *dmicbias = NULL, *dgnd = NULL;
+ enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
+
+ const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
+ WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
+ s16 hs_max, no_mic, dce_z;
+
+ pr_debug("%s: enter\n", __func__);
+ pr_debug("%s: event_state 0x%lx\n", __func__, event_state);
+
+ sz = size - 1;
+ for (i = 0, d = dt, ch = 0; i < sz; i++, d++) {
+ if (d->mic_bias) {
+ dce_z = mbhc->mbhc_data.dce_z;
+ mb_mv = mbhc->mbhc_data.micb_mv;
+ hs_max = plug_type->v_hs_max;
+ no_mic = plug_type->v_no_mic;
+ } else {
+ dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
+ mb_mv = VDDIO_MICBIAS_MV;
+ hs_max = WCD9XXX_V_CS_HS_MAX;
+ no_mic = WCD9XXX_V_CS_NO_MIC;
+ }
+
+ vdce = __wcd9xxx_codec_sta_dce_v(mbhc, true, d->dce,
+ dce_z, (u32)mb_mv);
+
+ d->_vdces = vdce;
+ if (d->_vdces < no_mic)
+ d->_type = PLUG_TYPE_HEADPHONE;
+ else if (d->_vdces >= hs_max)
+ d->_type = PLUG_TYPE_HIGH_HPH;
+ else
+ d->_type = PLUG_TYPE_HEADSET;
+
+ pr_debug("%s: DCE #%d, %04x, V %04d(%04d), HPHL %d TYPE %d\n",
+ __func__, i, d->dce, vdce, d->_vdces,
+ d->hphl_status & 0x01,
+ d->_type);
+
+ ch += d->hphl_status & 0x01;
+ if (!d->swap_gnd && !d->mic_bias) {
+ if (maxv < d->_vdces)
+ maxv = d->_vdces;
+ if (!minv || minv > d->_vdces)
+ minv = d->_vdces;
+ }
+ if ((!d->mic_bias &&
+ (d->_vdces >= WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV &&
+ d->_vdces <= WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV)) ||
+ (d->mic_bias &&
+ (d->_vdces >= WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
+ d->_vdces <= WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV))) {
+ pr_debug("%s: within invalid range\n", __func__);
+ type = PLUG_TYPE_INVALID;
+ goto exit;
+ }
+ }
+
+ if (event_state & (1 << MBHC_EVENT_PA_HPHL)) {
+ pr_debug("%s: HPHL PA was ON\n", __func__);
+ } else if (ch != sz && ch > 0) {
+ pr_debug("%s: Invalid, inconsistent HPHL\n", __func__);
+ type = PLUG_TYPE_INVALID;
+ goto exit;
+ }
+
+ delta_thr = highhph ? WCD9XXX_MB_MEAS_DELTA_MAX_MV :
+ WCD9XXX_CS_MEAS_DELTA_MAX_MV;
+
+ for (i = 0, d = dt; i < sz; i++, d++) {
+ if ((i > 0) && !d->mic_bias && !d->swap_gnd &&
+ (d->_type != dprev->_type)) {
+ pr_debug("%s: Invalid, inconsistent types\n", __func__);
+ type = PLUG_TYPE_INVALID;
+ goto exit;
+ }
+
+ if (!d->swap_gnd && !d->mic_bias &&
+ (abs(minv - d->_vdces) > delta_thr ||
+ abs(maxv - d->_vdces) > delta_thr)) {
+ pr_debug("%s: Invalid, delta %dmv, %dmv and %dmv\n",
+ __func__, d->_vdces, minv, maxv);
+ type = PLUG_TYPE_INVALID;
+ goto exit;
+ } else if (d->swap_gnd) {
+ dgnd = d;
+ }
+
+ if (!d->mic_bias && !d->swap_gnd)
+ dprev = d;
+ else if (d->mic_bias)
+ dmicbias = d;
+ }
+ if (dgnd && dt->_type != PLUG_TYPE_HEADSET &&
+ dt->_type != dgnd->_type) {
+ pr_debug("%s: Invalid, inconsistent types\n", __func__);
+ type = PLUG_TYPE_INVALID;
+ goto exit;
+ }
+
+ type = dt->_type;
+ if (dmicbias) {
+ if (dmicbias->_type == PLUG_TYPE_HEADSET &&
+ (dt->_type == PLUG_TYPE_HIGH_HPH ||
+ dt->_type == PLUG_TYPE_HEADSET)) {
+ type = PLUG_TYPE_HEADSET;
+ if (dt->_type == PLUG_TYPE_HIGH_HPH) {
+ pr_debug("%s: Headset with threshold on MIC detected\n",
+ __func__);
+ if (mbhc->mbhc_cfg->micbias_enable_flags &
+ (1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET))
+ mbhc->micbias_enable = true;
+ }
+ }
+ }
+
+ if (!(event_state & (1UL << MBHC_EVENT_PA_HPHL))) {
+ if (((type == PLUG_TYPE_HEADSET ||
+ type == PLUG_TYPE_HEADPHONE) && ch != sz)) {
+ pr_debug("%s: Invalid, not fully inserted, TYPE %d\n",
+ __func__, type);
+ type = PLUG_TYPE_INVALID;
+ }
+ }
+ if (type == PLUG_TYPE_HEADSET && dgnd && !dgnd->mic_bias) {
+ if ((dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MIN_MV <
+ minv) &&
+ (dgnd->_vdces + WCD9XXX_CS_GM_SWAP_THRES_MAX_MV >
+ maxv))
+ type = PLUG_TYPE_GND_MIC_SWAP;
+ else if (dgnd->_type != PLUG_TYPE_HEADSET) {
+ pr_debug("%s: Invalid, inconsistent types\n", __func__);
+ type = PLUG_TYPE_INVALID;
+ }
+ }
+exit:
+ pr_debug("%s: Plug type %d detected\n", __func__, type);
+ return type;
+}
+
/*
* wcd9xxx_find_plug_type : Find out and return the best plug type with given
* list of wcd9xxx_mbhc_detect structure.
@@ -1329,6 +1506,112 @@
return 0;
}
+void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on,
+ bool highhph)
+{
+
+ struct snd_soc_codec *codec;
+ struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
+ const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
+ WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
+
+ btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
+ codec = mbhc->codec;
+
+ if (on) {
+ pr_debug("%s: enabling current source\n", __func__);
+ /* Nsc to 9 */
+ snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
+ 0x78, 0x48);
+ /* pull down diode bit to 0 */
+ snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ 0x01, 0x00);
+ /*
+ * Keep the low power insertion/removal
+ * detection (reg 0x3DD) disabled
+ */
+ snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL,
+ 0x01, 0x00);
+ /*
+ * Enable the Mic Bias current source
+ * Write bits[6:5] of register MICB_2_MBHC to 0x3 (V_20_UA)
+ * Write bit[7] of register MICB_2_MBHC to 1
+ * (INS_DET_ISRC_EN__ENABLE)
+ * MICB_2_MBHC__SCHT_TRIG_EN to 1
+ */
+ snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ 0xF0, 0xF0);
+ /* Disconnect MBHC Override from MicBias and LDOH */
+ snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x00);
+ } else {
+ pr_debug("%s: disabling current source\n", __func__);
+ /* Connect MBHC Override from MicBias and LDOH */
+ snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x10);
+ /* INS_DET_ISRC_CTL to acdb value */
+ snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg,
+ 0x60, plug_det->mic_current << 5);
+ if (!highhph) {
+ /* INS_DET_ISRC_EN__ENABLE to 0 */
+ snd_soc_update_bits(codec,
+ mbhc->mbhc_bias_regs.mbhc_reg,
+ 0x80, 0x00);
+ /* MICB_2_MBHC__SCHT_TRIG_EN to 0 */
+ snd_soc_update_bits(codec,
+ mbhc->mbhc_bias_regs.mbhc_reg,
+ 0x10, 0x00);
+ }
+ /* Nsc to acdb value */
+ snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
+ btn_det->mbhc_nsc << 3);
+ }
+}
+
+static enum wcd9xxx_mbhc_plug_type
+wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
+{
+ struct snd_soc_codec *codec = mbhc->codec;
+ struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT];
+ enum wcd9xxx_mbhc_plug_type type = PLUG_TYPE_INVALID;
+ int i;
+
+ pr_debug("%s: enter\n", __func__);
+ WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
+
+ BUG_ON(NUM_DCE_PLUG_INS_DETECT < 4);
+
+ rt[0].swap_gnd = false;
+ rt[0].vddio = false;
+ rt[0].hwvalue = true;
+ rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
+ rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, true);
+ rt[0].mic_bias = false;
+
+ for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) {
+ rt[i].swap_gnd = (i == NUM_DCE_PLUG_INS_DETECT - 3);
+ rt[i].mic_bias = ((i == NUM_DCE_PLUG_INS_DETECT - 4) &&
+ highhph);
+ rt[i].hphl_status = wcd9xxx_hphl_status(mbhc);
+ if (rt[i].swap_gnd)
+ wcd9xxx_codec_hphr_gnd_switch(codec, true);
+
+ if (rt[i].mic_bias)
+ wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
+ rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, !highhph, true);
+ if (rt[i].mic_bias)
+ wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ if (rt[i].swap_gnd)
+ wcd9xxx_codec_hphr_gnd_switch(codec, false);
+ }
+
+ type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph,
+ mbhc->event_state);
+
+ pr_debug("%s: plug_type:%d\n", __func__, type);
+
+ return type;
+}
+
static enum wcd9xxx_mbhc_plug_type
wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
{
@@ -1365,7 +1648,7 @@
(void) wcd9xxx_pull_down_micbias(mbhc,
WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US);
rt[0].hphl_status = wcd9xxx_hphl_status(mbhc);
- rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc);
+ rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, false);
rt[0].swap_gnd = false;
rt[0].vddio = false;
rt[0].hwvalue = true;
@@ -1635,14 +1918,23 @@
{
enum wcd9xxx_mbhc_plug_type plug_type;
struct snd_soc_codec *codec = mbhc->codec;
+ bool current_source_enable;
pr_debug("%s: enter\n", __func__);
WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
+ current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+ (1 << MBHC_CS_ENABLE_INSERTION)) != 0);
- wcd9xxx_turn_onoff_override(codec, true);
- plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
- wcd9xxx_turn_onoff_override(codec, false);
+ if (current_source_enable) {
+ wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+ plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, false);
+ wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+ } else {
+ wcd9xxx_turn_onoff_override(codec, true);
+ plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
+ wcd9xxx_turn_onoff_override(codec, false);
+ }
if (wcd9xxx_swch_level_remove(mbhc)) {
pr_debug("%s: Switch level is low when determining plug\n",
@@ -1672,26 +1964,9 @@
/* called under codec_resource_lock acquisition */
static void wcd9xxx_mbhc_detect_plug_type(struct wcd9xxx_mbhc *mbhc)
{
- struct snd_soc_codec *codec = mbhc->codec;
- const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det =
- WCD9XXX_MBHC_CAL_PLUG_DET_PTR(mbhc->mbhc_cfg->calibration);
-
pr_debug("%s: enter\n", __func__);
WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
- /*
- * Turn on the override,
- * wcd9xxx_mbhc_setup_hs_polling requires override on
- */
- wcd9xxx_turn_onoff_override(codec, true);
- if (plug_det->t_ins_complete > 20)
- msleep(plug_det->t_ins_complete);
- else
- usleep_range(plug_det->t_ins_complete * 1000,
- plug_det->t_ins_complete * 1000);
- /* Turn off the override */
- wcd9xxx_turn_onoff_override(codec, false);
-
if (wcd9xxx_swch_level_remove(mbhc))
pr_debug("%s: Switch level low when determining plug\n",
__func__);
@@ -1740,14 +2015,21 @@
}
}
-static bool is_valid_mic_voltage(struct wcd9xxx_mbhc *mbhc, s32 mic_mv)
+static bool is_valid_mic_voltage(struct wcd9xxx_mbhc *mbhc, s32 mic_mv,
+ bool cs_enable)
{
const struct wcd9xxx_mbhc_plug_type_cfg *plug_type =
WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
const s16 v_hs_max = wcd9xxx_get_current_v_hs_max(mbhc);
- return (!(mic_mv > 10 && mic_mv < 80) && (mic_mv > plug_type->v_no_mic)
- && (mic_mv < v_hs_max)) ? true : false;
+ if (cs_enable)
+ return ((mic_mv > WCD9XXX_V_CS_NO_MIC) &&
+ (mic_mv < WCD9XXX_V_CS_HS_MAX)) ? true : false;
+ else
+ return (!(mic_mv > WCD9XXX_MEAS_INVALD_RANGE_LOW_MV &&
+ mic_mv < WCD9XXX_MEAS_INVALD_RANGE_HIGH_MV) &&
+ (mic_mv > plug_type->v_no_mic) &&
+ (mic_mv < v_hs_max)) ? true : false;
}
/*
@@ -1762,6 +2044,13 @@
s32 mic_mv[NUM_DCE_PLUG_DETECT];
short mb_v[NUM_DCE_PLUG_DETECT];
unsigned long retry = 0, timeout;
+ bool cs_enable;
+
+ cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+ (1 << MBHC_CS_ENABLE_REMOVAL)) != 0);
+
+ if (cs_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, true, false);
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
while (!(timedout = time_after(jiffies, timeout))) {
@@ -1781,11 +2070,28 @@
break;
}
- for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
- mb_v[i] = wcd9xxx_codec_sta_dce(mbhc, 1, true);
- mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1 , mb_v[i]);
- pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
- __func__, retry, mic_mv[i], mb_v[i]);
+ if (cs_enable) {
+ for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
+ mb_v[i] = __wcd9xxx_codec_sta_dce(mbhc, 1,
+ true, true);
+ mic_mv[i] = __wcd9xxx_codec_sta_dce_v(mbhc,
+ true,
+ mb_v[i],
+ mbhc->mbhc_data.dce_nsc_cs_z,
+ (u32)VDDIO_MICBIAS_MV);
+ pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
+ __func__, retry, mic_mv[i], mb_v[i]);
+ }
+ } else {
+ for (i = 0; i < NUM_DCE_PLUG_DETECT; i++) {
+ mb_v[i] = wcd9xxx_codec_sta_dce(mbhc, 1,
+ true);
+ mic_mv[i] = wcd9xxx_codec_sta_dce_v(mbhc, 1,
+ mb_v[i]);
+ pr_debug("%s : DCE run %lu, mic_mv = %d(%x)\n",
+ __func__, retry, mic_mv[i],
+ mb_v[i]);
+ }
}
if (wcd9xxx_swch_level_remove(mbhc)) {
@@ -1800,7 +2106,7 @@
}
for (i = 0; i < NUM_DCE_PLUG_DETECT; i++)
- if (!is_valid_mic_voltage(mbhc, mic_mv[i]))
+ if (!is_valid_mic_voltage(mbhc, mic_mv[i], cs_enable))
break;
if (i == NUM_DCE_PLUG_DETECT) {
@@ -1811,6 +2117,9 @@
}
}
+ if (cs_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
if (timedout)
pr_debug("%s: Microphone did not settle in %d seconds\n",
__func__, HS_DETECT_PLUG_TIME_MS);
@@ -1829,12 +2138,15 @@
/* called only from interrupt which is under codec_resource_lock acquisition */
static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc)
{
- s16 dce;
+ s16 dce, dcez;
unsigned long timeout;
bool removed = true;
struct snd_soc_codec *codec = mbhc->codec;
const struct wcd9xxx_mbhc_general_cfg *generic =
WCD9XXX_MBHC_CAL_GENERAL_PTR(mbhc->mbhc_cfg->calibration);
+ bool cs_enable;
+ s16 cur_v_ins_h;
+ u32 mb_mv;
pr_debug("%s: enter\n", __func__);
if (mbhc->current_plug != PLUG_TYPE_HEADSET) {
@@ -1848,13 +2160,32 @@
usleep_range(generic->t_shutdown_plug_rem,
generic->t_shutdown_plug_rem);
+ cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+ (1 << MBHC_CS_ENABLE_REMOVAL)) != 0);
+ if (cs_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, true, false);
+
timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS);
do {
- dce = wcd9xxx_codec_sta_dce(mbhc, 1, true);
+ if (cs_enable) {
+ dce = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true);
+ dcez = mbhc->mbhc_data.dce_nsc_cs_z;
+ mb_mv = VDDIO_MICBIAS_MV;
+ } else {
+ dce = wcd9xxx_codec_sta_dce(mbhc, 1, true);
+ dcez = mbhc->mbhc_data.dce_z;
+ mb_mv = mbhc->mbhc_data.micb_mv;
+ }
+
pr_debug("%s: DCE 0x%x,%d\n", __func__, dce,
- wcd9xxx_codec_sta_dce_v(mbhc, 1, dce));
- if (dce <
- wcd9xxx_get_current_v(mbhc, WCD9XXX_CURRENT_V_INS_H)) {
+ __wcd9xxx_codec_sta_dce_v(mbhc, true, dce,
+ dcez, mb_mv));
+
+ cur_v_ins_h = cs_enable ? (s16) mbhc->mbhc_data.v_cs_ins_h :
+ (wcd9xxx_get_current_v(mbhc,
+ WCD9XXX_CURRENT_V_INS_H));
+
+ if (dce < cur_v_ins_h) {
removed = false;
break;
}
@@ -1862,6 +2193,9 @@
pr_debug("%s: headset %sactually removed\n", __func__,
removed ? "" : "not ");
+ if (cs_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, false, false);
+
if (removed) {
if (mbhc->mbhc_cfg->detect_extn_cable) {
if (!wcd9xxx_swch_level_remove(mbhc)) {
@@ -2070,22 +2404,29 @@
}
static u16 wcd9xxx_codec_v_sta_dce(struct wcd9xxx_mbhc *mbhc,
- enum meas_type dce, s16 vin_mv)
+ enum meas_type dce, s16 vin_mv,
+ bool cs_enable)
{
s16 diff, zero;
u32 mb_mv, in;
u16 value;
+ s16 dce_z;
mb_mv = mbhc->mbhc_data.micb_mv;
+ dce_z = mbhc->mbhc_data.dce_z;
if (mb_mv == 0) {
pr_err("%s: Mic Bias voltage is set to zero\n", __func__);
return -EINVAL;
}
+ if (cs_enable) {
+ mb_mv = VDDIO_MICBIAS_MV;
+ dce_z = mbhc->mbhc_data.dce_nsc_cs_z;
+ }
if (dce) {
- diff = (mbhc->mbhc_data.dce_mb) - (mbhc->mbhc_data.dce_z);
- zero = (mbhc->mbhc_data.dce_z);
+ diff = (mbhc->mbhc_data.dce_mb) - (dce_z);
+ zero = (dce_z);
} else {
diff = (mbhc->mbhc_data.sta_mb) - (mbhc->mbhc_data.sta_z);
zero = (mbhc->mbhc_data.sta_z);
@@ -2112,9 +2453,9 @@
plug_type = WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration);
mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_CFILT] =
- wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_hs_max);
+ wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_hs_max, false);
mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_CFILT] =
- wcd9xxx_codec_v_sta_dce(mbhc, DCE, plug_type->v_hs_max);
+ wcd9xxx_codec_v_sta_dce(mbhc, DCE, plug_type->v_hs_max, false);
mbhc->mbhc_data.v_inval_ins_low = FAKE_INS_LOW;
mbhc->mbhc_data.v_inval_ins_high = FAKE_INS_HIGH;
@@ -2123,9 +2464,9 @@
adj_v_hs_max = scale_v_micb_vddio(mbhc, plug_type->v_hs_max,
true);
mbhc->mbhc_data.v_ins_hu[MBHC_V_IDX_VDDIO] =
- wcd9xxx_codec_v_sta_dce(mbhc, STA, adj_v_hs_max);
+ wcd9xxx_codec_v_sta_dce(mbhc, STA, adj_v_hs_max, false);
mbhc->mbhc_data.v_ins_h[MBHC_V_IDX_VDDIO] =
- wcd9xxx_codec_v_sta_dce(mbhc, DCE, adj_v_hs_max);
+ wcd9xxx_codec_v_sta_dce(mbhc, DCE, adj_v_hs_max, false);
mbhc->mbhc_data.v_inval_ins_low =
scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_low,
false);
@@ -2133,6 +2474,11 @@
scale_v_micb_vddio(mbhc, mbhc->mbhc_data.v_inval_ins_high,
false);
}
+ mbhc->mbhc_data.v_cs_ins_h = wcd9xxx_codec_v_sta_dce(mbhc, DCE,
+ WCD9XXX_V_CS_HS_MAX,
+ true);
+ pr_debug("%s: v_ins_h for current source: 0x%x\n", __func__,
+ mbhc->mbhc_data.v_cs_ins_h);
btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_det,
MBHC_BTN_DET_V_BTN_HIGH);
@@ -2147,13 +2493,17 @@
scale_v_micb_vddio(mbhc, btn_mv_dce[MBHC_V_IDX_CFILT], true);
mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_CFILT] =
- wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_CFILT]);
+ wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_CFILT],
+ false);
mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT] =
- wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_CFILT]);
+ wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_CFILT],
+ false);
mbhc->mbhc_data.v_b1_hu[MBHC_V_IDX_VDDIO] =
- wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_VDDIO]);
+ wcd9xxx_codec_v_sta_dce(mbhc, STA, btn_mv_sta[MBHC_V_IDX_VDDIO],
+ false);
mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_VDDIO] =
- wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_VDDIO]);
+ wcd9xxx_codec_v_sta_dce(mbhc, DCE, btn_mv_dce[MBHC_V_IDX_VDDIO],
+ false);
mbhc->mbhc_data.v_brh[MBHC_V_IDX_CFILT] =
mbhc->mbhc_data.v_b1_h[MBHC_V_IDX_CFILT];
@@ -2163,7 +2513,7 @@
mbhc->mbhc_data.v_brl = BUTTON_MIN;
mbhc->mbhc_data.v_no_mic =
- wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_no_mic);
+ wcd9xxx_codec_v_sta_dce(mbhc, STA, plug_type->v_no_mic, false);
pr_debug("%s: leave\n", __func__);
}
@@ -2177,6 +2527,16 @@
mbhc->mbhc_cfg->mclk_cb_fn(mbhc->codec, on, false);
}
+/*
+ * Mic Bias Enable Decision
+ * Return true if high_hph_cnt is a power of 2 (!= 2)
+ * otherwise return false
+ */
+static bool wcd9xxx_mbhc_enable_mb_decision(int high_hph_cnt)
+{
+ return (high_hph_cnt > 2) && !(high_hph_cnt & (high_hph_cnt - 1));
+}
+
static void wcd9xxx_correct_swch_plug(struct work_struct *work)
{
struct wcd9xxx_mbhc *mbhc;
@@ -2184,13 +2544,17 @@
enum wcd9xxx_mbhc_plug_type plug_type = PLUG_TYPE_INVALID;
unsigned long timeout;
int retry = 0, pt_gnd_mic_swap_cnt = 0;
+ int highhph_cnt = 0;
bool correction = false;
- bool wrk_complete = true;
+ bool current_source_enable;
+ bool wrk_complete = true, highhph = false;
pr_debug("%s: enter\n", __func__);
mbhc = container_of(work, struct wcd9xxx_mbhc, correct_plug_swch);
codec = mbhc->codec;
+ current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
+ (1 << MBHC_CS_ENABLE_POLLING)) != 0);
wcd9xxx_onoff_ext_mclk(mbhc, true);
@@ -2204,7 +2568,11 @@
* DAPM doesn't use any MBHC block as this work only runs with
* headphone detection.
*/
- wcd9xxx_turn_onoff_override(codec, true);
+ if (current_source_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, true,
+ false);
+ else
+ wcd9xxx_turn_onoff_override(codec, true);
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
while (!time_after(jiffies, timeout)) {
@@ -2225,11 +2593,20 @@
/* can race with removal interrupt */
WCD9XXX_BCL_LOCK(mbhc->resmgr);
- plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
+ if (current_source_enable)
+ plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc,
+ highhph);
+ else
+ plug_type = wcd9xxx_codec_get_plug_type(mbhc, true);
WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
pr_debug("%s: attempt(%d) current_plug(%d) new_plug(%d)\n",
__func__, retry, mbhc->current_plug, plug_type);
+
+ highhph_cnt = (plug_type == PLUG_TYPE_HIGH_HPH) ?
+ (highhph_cnt + 1) :
+ 0;
+ highhph = wcd9xxx_mbhc_enable_mb_decision(highhph_cnt);
if (plug_type == PLUG_TYPE_INVALID) {
pr_debug("Invalid plug in attempt # %d\n", retry);
if (!mbhc->mbhc_cfg->detect_extn_cable &&
@@ -2275,8 +2652,12 @@
pt_gnd_mic_swap_cnt = 0;
WCD9XXX_BCL_LOCK(mbhc->resmgr);
- /* Turn off override */
- wcd9xxx_turn_onoff_override(codec, false);
+ /* Turn off override/current source */
+ if (current_source_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, false,
+ false);
+ else
+ wcd9xxx_turn_onoff_override(codec, false);
/*
* The valid plug also includes PLUG_TYPE_GND_MIC_SWAP
*/
@@ -2289,15 +2670,19 @@
}
}
- if (plug_type == PLUG_TYPE_HIGH_HPH) {
+ highhph = false;
+ if (wrk_complete && plug_type == PLUG_TYPE_HIGH_HPH) {
pr_debug("%s: polling is done, still HPH, so enabling MIC trigger\n",
__func__);
WCD9XXX_BCL_LOCK(mbhc->resmgr);
wcd9xxx_find_plug_and_report(mbhc, plug_type);
+ highhph = true;
WCD9XXX_BCL_UNLOCK(mbhc->resmgr);
}
- /* Turn off override */
- if (!correction)
+
+ if (!correction && current_source_enable)
+ wcd9xxx_turn_onoff_current_source(mbhc, false, highhph);
+ else if (!correction)
wcd9xxx_turn_onoff_override(codec, false);
wcd9xxx_onoff_ext_mclk(mbhc, false);
@@ -2566,11 +2951,11 @@
pr_debug("%s: reprogram vb1hu/vbrh to %dmv\n", __func__, mv);
/* update LSB first so mbhc hardware block doesn't see too low value */
- v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv);
+ v_b1_hu = wcd9xxx_codec_v_sta_dce(mbhc, STA, mv, false);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL, v_b1_hu & 0xFF);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL,
(v_b1_hu >> 8) & 0xFF);
- v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv);
+ v_brh = wcd9xxx_codec_v_sta_dce(mbhc, DCE, mv, false);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL, v_brh & 0xFF);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL,
(v_brh >> 8) & 0xFF);
@@ -2642,14 +3027,15 @@
pr_debug("%s: Button is released without resume",
__func__);
wcd9xxx_get_z(mbhc, &dce_z, &sta_z);
- stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z);
+ stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
+ mbhc->mbhc_data.micb_mv);
if (vddio)
stamv_s = scale_v_micb_vddio(mbhc, stamv,
false);
else
stamv_s = stamv;
mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0],
- dce_z);
+ dce_z, mbhc->mbhc_data.micb_mv);
mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0],
false) : mv[0];
btn = wcd9xxx_determine_button(mbhc, mv_s[0]);
@@ -2665,7 +3051,8 @@
wcd9xxx_get_z(mbhc, &dce_z, &sta_z);
- stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z);
+ stamv = __wcd9xxx_codec_sta_dce_v(mbhc, 0, sta, sta_z,
+ mbhc->mbhc_data.micb_mv);
if (vddio)
stamv_s = scale_v_micb_vddio(mbhc, stamv, false);
else
@@ -2674,7 +3061,8 @@
sta & 0xFFFF, stamv, stamv_s);
/* determine pressed button */
- mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0], dce_z);
+ mv[0] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[0], dce_z,
+ mbhc->mbhc_data.micb_mv);
mv_s[0] = vddio ? scale_v_micb_vddio(mbhc, mv[0], false) : mv[0];
btnmeas[0] = wcd9xxx_determine_button(mbhc, mv_s[0]);
pr_debug("%s: Meas HW - DCE 0x%x,%d,%d button %d\n", __func__,
@@ -2683,7 +3071,8 @@
btn = btnmeas[0];
for (meas = 1; (n_btn_meas && d->n_btn_meas &&
(meas < (d->n_btn_meas + 1))); meas++) {
- mv[meas] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[meas], dce_z);
+ mv[meas] = __wcd9xxx_codec_sta_dce_v(mbhc, 1, dce[meas], dce_z,
+ mbhc->mbhc_data.micb_mv);
mv_s[meas] = vddio ? scale_v_micb_vddio(mbhc, mv[meas], false) :
mv[meas];
btnmeas[meas] = wcd9xxx_determine_button(mbhc, mv_s[meas]);
@@ -2925,7 +3314,7 @@
static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
{
u8 cfilt_mode;
- u16 reg0, reg1;
+ u16 reg0, reg1, reg2;
struct snd_soc_codec *codec = mbhc->codec;
pr_debug("%s: enter\n", __func__);
@@ -2988,10 +3377,26 @@
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
mbhc->mbhc_data.dce_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true, false);
+
+ /* compute dce_z for current source */
+ reg2 = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
+ snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78,
+ WCD9XXX_MBHC_NSC_CS << 3);
+
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+ mbhc->mbhc_data.dce_nsc_cs_z = __wcd9xxx_codec_sta_dce(mbhc, 1, true,
+ false);
+ pr_debug("%s: dce_z with nsc cs: 0x%x\n", __func__,
+ mbhc->mbhc_data.dce_nsc_cs_z);
+
+ snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, reg2);
+
/* STA measurement for 0 voltage */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
mbhc->mbhc_data.sta_z = __wcd9xxx_codec_sta_dce(mbhc, 0, true, false);
+
/* Restore registers */
snd_soc_write(codec, mbhc->mbhc_bias_regs.ctl_reg, reg0);
snd_soc_write(codec, WCD9XXX_A_MAD_ANA_CTRL, reg1);
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h
index 0599ccb..88c911f 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.h
+++ b/sound/soc/codecs/wcd9xxx-mbhc.h
@@ -43,6 +43,7 @@
/* Data used by MBHC */
struct mbhc_internal_cal_data {
u16 dce_z;
+ u16 dce_nsc_cs_z;
u16 dce_mb;
u16 sta_z;
u16 sta_mb;
@@ -59,6 +60,7 @@
u16 v_no_mic;
s16 v_inval_ins_low;
s16 v_inval_ins_high;
+ u16 v_cs_ins_h;
};
enum wcd9xxx_mbhc_plug_type {
@@ -83,6 +85,12 @@
MBHC_MICBIAS_ENABLE_REGULAR_HEADSET,
};
+enum wcd9xx_mbhc_cs_enable_bits {
+ MBHC_CS_ENABLE_POLLING,
+ MBHC_CS_ENABLE_INSERTION,
+ MBHC_CS_ENABLE_REMOVAL,
+};
+
enum wcd9xxx_mbhc_state {
MBHC_STATE_NONE = -1,
MBHC_STATE_POTENTIAL,
@@ -210,6 +218,7 @@
unsigned long micbias_enable_flags;
/* swap_gnd_mic returns true if extern GND/MIC swap switch toggled */
bool (*swap_gnd_mic) (struct snd_soc_codec *);
+ unsigned long cs_enable_flags;
};
struct wcd9xxx_cfilt_mode {
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 85ed869..19d717e 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -83,6 +83,9 @@
.micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
.insert_detect = true,
.swap_gnd_mic = NULL,
+ .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
+ 1 << MBHC_CS_ENABLE_INSERTION |
+ 1 << MBHC_CS_ENABLE_REMOVAL),
};
struct msm_auxpcm_gpio {
@@ -788,7 +791,7 @@
S(c[1], 124);
S(nc, 1);
S(n_meas, 5);
- S(mbhc_nsc, 11);
+ S(mbhc_nsc, 10);
S(n_btn_meas, 1);
S(n_btn_con, 2);
S(num_btn, WCD9XXX_MBHC_DEF_BUTTONS);
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index b28f0f49..769b8eb 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -133,6 +133,9 @@
.micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
.insert_detect = true,
.swap_gnd_mic = NULL,
+ .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
+ 1 << MBHC_CS_ENABLE_INSERTION |
+ 1 << MBHC_CS_ENABLE_REMOVAL),
};
struct msm_auxpcm_gpio {
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 340d3db..9150751 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -180,6 +180,39 @@
return 0;
}
+static const char *const btsco_rate_text[] = {"8000", "16000"};
+static const struct soc_enum msm_btsco_enum[] = {
+ SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
+};
+
+static int msm_btsco_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_btsco_rate = %d", __func__, msm_btsco_rate);
+
+ ucontrol->value.integer.value[0] = msm_btsco_rate;
+ return 0;
+}
+
+static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 8000:
+ msm_btsco_rate = BTSCO_RATE_8KHZ;
+ break;
+ case 16000:
+ msm_btsco_rate = BTSCO_RATE_16KHZ;
+ break;
+ default:
+ msm_btsco_rate = BTSCO_RATE_8KHZ;
+ break;
+ }
+
+ pr_debug("%s: msm_btsco_rate = %d\n", __func__, msm_btsco_rate);
+ return 0;
+}
+
static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -318,6 +351,11 @@
return ret;
}
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
+ msm_btsco_rate_get, msm_btsco_rate_put),
+};
+
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
@@ -334,6 +372,11 @@
snd_soc_dapm_enable_pin(dapm, "Lineout amp");
snd_soc_dapm_sync(dapm);
+ ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+ if (ret < 0)
+ return ret;
+
ret = snd_soc_jack_new(codec, "Headset Jack",
SND_JACK_HEADSET, &hs_jack);
if (ret) {
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
index 1685894..d9c1210 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.h
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -19,7 +19,6 @@
enum {
RX_CAL,
TX_CAL,
- AANC_TX_CAL,
MAX_AUDPROC_TYPES
};
diff --git a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
index 58ea36d..113d85f 100644
--- a/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
+++ b/sound/soc/msm/qdsp6v2/msm-dolby-dap-config.h
@@ -223,7 +223,7 @@
DOLBY_PARAM_VEN_LENGTH)
#define DOLBY_PARAM_INT_ENDP_LENGTH 1
-#define DOLBY_PARAM_PAYLOAD_SIZE 4
+#define DOLBY_PARAM_PAYLOAD_SIZE 3
#define DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM 329
#define DOLBY_NUM_ENDP_DEPENDENT_PARAMS 1
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index df0fa6a..b1f968d 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -35,6 +35,16 @@
#define INVALID_COPP_ID 0xFF
#define ADM_GET_PARAMETER_LENGTH 350
+
+enum {
+ ADM_RX_AUDPROC_CAL,
+ ADM_TX_AUDPROC_CAL,
+ ADM_RX_AUDVOL_CAL,
+ ADM_TX_AUDVOL_CAL,
+ ADM_CUSTOM_TOP_CAL,
+ ADM_MAX_CAL_TYPES
+};
+
struct adm_ctl {
void *apr;
atomic_t copp_id[AFE_MAX_PORTS];
@@ -48,10 +58,7 @@
struct acdb_cal_block mem_addr_audproc[MAX_AUDPROC_TYPES];
struct acdb_cal_block mem_addr_audvol[MAX_AUDPROC_TYPES];
-/* 0 - (MAX_AUDPROC_TYPES -1): audproc handles */
-/* (MAX_AUDPROC_TYPES -1) - (2 * MAX_AUDPROC_TYPES -1): audvol handles */
-/* + 1 for custom ADM topology */
- atomic_t mem_map_cal_handles[(2 * MAX_AUDPROC_TYPES) + 1];
+ atomic_t mem_map_cal_handles[ADM_MAX_CAL_TYPES];
atomic_t mem_map_cal_index;
int set_custom_topology;
@@ -626,7 +633,7 @@
if (this_adm.set_custom_topology) {
/* specific index 4 for adm topology memory */
- atomic_set(&this_adm.mem_map_cal_index, 4);
+ atomic_set(&this_adm.mem_map_cal_index, ADM_CUSTOM_TOP_CAL);
/* Only call this once */
this_adm.set_custom_topology = 0;
@@ -656,7 +663,8 @@
adm_top.hdr.opcode = ADM_CMD_ADD_TOPOLOGIES;
adm_top.payload_addr_lsw = cal_block.cal_paddr;
adm_top.payload_addr_msw = 0;
- adm_top.mem_map_handle = atomic_read(&this_adm.mem_map_cal_handles[4]);
+ adm_top.mem_map_handle =
+ atomic_read(&this_adm.mem_map_cal_handles[ADM_CUSTOM_TOP_CAL]);
adm_top.payload_size = cal_block.cal_size;
atomic_set(&this_adm.copp_stat[index], 0);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 1810770..6dfe5b3 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -25,6 +25,14 @@
#include "audio_acdb.h"
+enum {
+ AFE_RX_CAL,
+ AFE_TX_CAL,
+ AFE_AANC_TX_CAL,
+ MAX_AFE_CAL_TYPES
+};
+
+
struct afe_ctl {
void *apr;
atomic_t state;
@@ -39,8 +47,8 @@
void *rx_private_data;
uint32_t mmap_handle;
- struct acdb_cal_block afe_cal_addr[MAX_AUDPROC_TYPES];
- atomic_t mem_map_cal_handles[MAX_AUDPROC_TYPES];
+ struct acdb_cal_block afe_cal_addr[MAX_AFE_CAL_TYPES];
+ atomic_t mem_map_cal_handles[MAX_AFE_CAL_TYPES];
atomic_t mem_map_cal_index;
u16 dtmf_gen_rx_portid;
struct afe_spkr_prot_calib_get_resp calib_data;
@@ -94,7 +102,7 @@
pr_debug("q6afe: reset event = %d %d apr[%p]\n",
data->reset_event, data->reset_proc, this_afe.apr);
- for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
+ for (i = 0; i < MAX_AFE_CAL_TYPES; i++) {
this_afe.afe_cal_addr[i].cal_paddr = 0;
this_afe.afe_cal_addr[i].cal_size = 0;
}
@@ -384,7 +392,7 @@
u32 handle;
pr_debug("%s: path %d\n", __func__, path);
- if (path == AANC_TX_CAL) {
+ if (path == AFE_AANC_TX_CAL) {
get_aanc_cal(&cal_block);
} else {
get_afe_cal(path, &cal_block);
@@ -600,10 +608,10 @@
if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
afe_send_cal_spkr_prot_tx(port_id);
- afe_send_cal_block(TX_CAL, port_id);
+ afe_send_cal_block(AFE_TX_CAL, port_id);
} else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
afe_send_cal_spkr_prot_rx(port_id);
- afe_send_cal_block(RX_CAL, port_id);
+ afe_send_cal_block(AFE_RX_CAL, port_id);
}
}
@@ -1149,7 +1157,7 @@
__func__, ret);
goto fail_cmd;
}
- afe_send_cal_block(AANC_TX_CAL, tx_port_id);
+ afe_send_cal_block(AFE_AANC_TX_CAL, tx_port_id);
fail_cmd:
return ret;
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index c5483ee..aec048e 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -735,7 +735,7 @@
int rc = -EINVAL;
if (!client)
- goto fail;
+ return rc;
mutex_lock(&client->cmd_lock);
if (!client->sound_model.data) {
@@ -744,7 +744,6 @@
if (IS_ERR_OR_NULL(client->sound_model.client)) {
pr_err("%s: ION create client for AUDIO failed\n",
__func__);
- mutex_unlock(&client->cmd_lock);
goto fail;
}
client->sound_model.handle =
@@ -753,7 +752,6 @@
if (IS_ERR_OR_NULL(client->sound_model.handle)) {
pr_err("%s: ION memory allocation for AUDIO failed\n",
__func__);
- mutex_unlock(&client->cmd_lock);
goto fail;
}
@@ -764,7 +762,6 @@
if (rc) {
pr_err("%s: ION get physical mem failed, rc%d\n",
__func__, rc);
- mutex_unlock(&client->cmd_lock);
goto fail;
}
@@ -773,7 +770,6 @@
client->sound_model.handle);
if (IS_ERR_OR_NULL(client->sound_model.data)) {
pr_err("%s: ION memory mapping failed\n", __func__);
- mutex_unlock(&client->cmd_lock);
goto fail;
}
memset(client->sound_model.data, 0, len);
@@ -789,11 +785,13 @@
&client->sound_model.mem_map_handle);
if (rc < 0) {
pr_err("%s:CMD Memory_map_regions failed\n", __func__);
- goto fail;
+ goto exit;
}
return 0;
fail:
+ mutex_unlock(&client->cmd_lock);
+exit:
q6lsm_snd_model_buf_free(client);
return rc;
}