Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/Documentation/devicetree/bindings/qdsp/msm-adsp-sensors.txt b/Documentation/devicetree/bindings/qdsp/msm-adsp-sensors.txt
- index ff0b1ef..4f1c10b 100644
- --- a/Documentation/devicetree/bindings/qdsp/msm-adsp-sensors.txt
- +++ b/Documentation/devicetree/bindings/qdsp/msm-adsp-sensors.txt
- @@ -3,17 +3,9 @@
- Required properties:
- - compatible: "qcom,msm-adsp-sensors"
- - - qcom,src-id: Master port id
- - - qcom,dst-id: Slave port id
- - - qcom,ab: Arbitrated bandwidth in bytes/s
- - - qcom,ib: Instantaneous bandwidth in bytes/s
- Example:
- qcom,msm-adsp-sensors {
- compatible = "qcom,msm-adsp-sensors";
- - qcom,src-id = <11>;
- - qcom,dst-id = <604>;
- - qcom,ab = <209715200>;
- - qcom,ib = <471859200>;
- };
- diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
- index 979819f..5fa7dde 100644
- --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
- +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
- @@ -82,9 +82,9 @@ Optional properties :
- - qcom,hsusb-l1-supported: If present, the device supports l1 (Link power
- management).
- - qcom,no-selective-suspend: If present selective suspend is disabled on hub ports.
- -- qcom,hsusb-otg-dpsehv-int: If present, indicates mpm interrupt to be configured
- +- qcom,hsusb-otg-mpm-dpsehv-int: If present, indicates mpm interrupt to be configured
- for detection of dp line transition during VDD minimization.
- -- qcom,hsusb-otg-dmsehv-int: If present, indicates mpm interrupt to be configured
- +- qcom,hsusb-otg-mpm-dmsehv-int: If present, indicates mpm interrupt to be configured
- for detection of dm line transition during VDD minimization.
- - qcom,ahb-async-bridge-bypass: If present, indicates that enable AHB2AHB By Pass
- mode with device controller for better throughput. With this mode, USB Core
- diff --git a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
- index 2cb528c..6ef897a 100644
- --- a/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
- +++ b/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt
- @@ -39,7 +39,7 @@ in TX data path.
- 1200 - WCN XO settling time (usec)
- 1 - WCN RPM power collapse enabled
- 1 - WCN standalone power collapse enabled
- -
- + 6 - GPIO strength value
- Example:
- @@ -64,5 +64,5 @@ Example:
- qcom,has-48mhz-xo;
- qcom,has-pronto-hw;
- qcom,wcnss-adc_tm = <&pm8226_adc_tm>;
- - qcom,wcnss-pm = <11 21 1200 1 1>;
- + qcom,wcnss-pm = <11 21 1200 1 1 6>;
- };
- diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h
- index 1f4e718..799b575 100644
- --- a/arch/arm/boot/compressed/libfdt_env.h
- +++ b/arch/arm/boot/compressed/libfdt_env.h
- @@ -1,6 +1,7 @@
- #ifndef _ARM_LIBFDT_ENV_H
- #define _ARM_LIBFDT_ENV_H
- +#include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/string.h>
- #include <asm/byteorder.h>
- diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
- index 15c6680..9b6e34b 100644
- --- a/arch/arm/boot/dts/msm-pm8226.dtsi
- +++ b/arch/arm/boot/dts/msm-pm8226.dtsi
- @@ -94,6 +94,8 @@
- qcom,cool-bat-decidegc = <100>;
- qcom,cool-bat-mv = <4100>;
- qcom,ibatmax-cool-ma = <350>;
- + qcom,chg-iadc = <&pm8226_iadc>;
- + qcom,ibat-calibration-enabled;
- pm8226_chg_chgr: qcom,chgr@1000 {
- status = "disabled";
- diff --git a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
- index 3734273..2f2eacb 100644
- --- a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
- +++ b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2015, 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
- @@ -155,6 +155,10 @@
- qcom,hsusb-otg-mode = <3>;
- vbus_otg-supply = <&pm8226_chg_otg>;
- +
- + qcom,hsusb-otg-mpm-dpsehv-int = <49>;
- + qcom,hsusb-otg-mpm-dmsehv-int = <58>;
- +
- };
- &sdcc1 {
- diff --git a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
- index 3f79fab..d8d3c44 100644
- --- a/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
- +++ b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2015, 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
- @@ -145,6 +145,9 @@
- qcom,hsusb-otg-mode = <3>;
- vbus_otg-supply = <&pm8226_chg_otg>;
- +
- + qcom,hsusb-otg-mpm-dpsehv-int = <49>;
- + qcom,hsusb-otg-mpm-dmsehv-int = <58>;
- };
- &sdcc1 {
- diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
- index 92285a7..1631bd6 100644
- --- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
- +++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
- @@ -174,80 +174,4 @@
- qcom,cci-master = <0>;
- status = "ok";
- };
- -
- - qcom,camera@6f {
- - compatible = "qcom,ov8825";
- - reg = <0x6f>;
- - qcom,slave-id = <0x6c 0x300a 0x8825>;
- - qcom,csiphy-sd-index = <0>;
- - qcom,csid-sd-index = <0>;
- - qcom,actuator-src = <&actuator0>;
- - qcom,led-flash-src = <&led_flash0>;
- - qcom,mount-angle = <270>;
- - qcom,sensor-name = "ov8825";
- - 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 35 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,csi-lane-assign = <0x4320>;
- - qcom,csi-lane-mask = <0x1f>;
- - qcom,sensor-position = <0>;
- - qcom,sensor-mode = <1>;
- - qcom,cci-master = <0>;
- - };
- -
- - qcom,camera@6d {
- - compatible = "qcom,ov9724";
- - reg = <0x6d>;
- - qcom,slave-id = <0x20 0x0 0x9724>;
- - qcom,csiphy-sd-index = <1>;
- - qcom,csid-sd-index = <1>;
- - qcom,mount-angle = <270>;
- - qcom,sensor-name = "ov9724";
- - cam_vdig-supply = <&pm8226_l5>;
- - cam_vana-supply = <&pm8226_l19>;
- - cam_vio-supply = <&pm8226_lvs1>;
- - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
- - qcom,cam-vreg-type = <0 1 0>;
- - qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
- - qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
- - qcom,cam-vreg-op-mode = <200000 0 80000>;
- - qcom,gpio-no-mux = <0>;
- - gpios = <&msmgpio 26 0>,
- - <&msmgpio 28 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_RESET",
- - "CAM_STANDBY";
- - qcom,gpio-set-tbl-num = <1 1>;
- - qcom,gpio-set-tbl-flags = <0 2>;
- - qcom,gpio-set-tbl-delay = <1000 4000>;
- - qcom,csi-lane-assign = <0x4320>;
- - qcom,csi-lane-mask = <0x3>;
- - qcom,sensor-position = <1>;
- - qcom,sensor-mode = <1>;
- - qcom,cci-master = <0>;
- - status = "ok";
- - };
- };
- diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
- index 8d2414c..f20c959 100644
- --- a/arch/arm/boot/dts/msm8226.dtsi
- +++ b/arch/arm/boot/dts/msm8226.dtsi
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -628,6 +628,13 @@
- qcom,msm-auxpcm-interface = "primary";
- };
- + qcom,avtimer@fe053000 {
- + compatible = "qcom,avtimer";
- + reg = <0xfe053008 0x4>,
- + <0xfe05300c 0x4>;
- + reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
- + };
- +
- qcom,wcnss-wlan@fb000000 {
- compatible = "qcom,wcnss_wlan";
- reg = <0xfb000000 0x280000>,
- @@ -652,10 +659,6 @@
- qcom,msm-adsp-sensors {
- compatible = "qcom,msm-adsp-sensors";
- - qcom,src-id = <11>;
- - qcom,dst-id = <604>;
- - qcom,ab = <32505856>;
- - qcom,ib = <32505856>;
- };
- qcom,wdt@f9017000 {
- diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
- index f8c9b46..5faa75c 100644
- --- a/arch/arm/boot/dts/msm8974.dtsi
- +++ b/arch/arm/boot/dts/msm8974.dtsi
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -1910,10 +1910,6 @@
- qcom,msm-adsp-sensors {
- compatible = "qcom,msm-adsp-sensors";
- - qcom,src-id = <11>;
- - qcom,dst-id = <604>;
- - qcom,ab = <32505856>;
- - qcom,ib = <32505856>;
- };
- qcom,mss@fc880000 {
- @@ -1987,7 +1983,7 @@
- gpios = <&msmgpio 36 0>, <&msmgpio 37 0>, <&msmgpio 38 0>, <&msmgpio 39 0>, <&msmgpio 40 0>;
- qcom,has-48mhz-xo;
- qcom,has-pronto-hw;
- - qcom,wcnss-pm = <11 21 1200 1 1>;
- + qcom,wcnss-pm = <11 19 1200 1 1 6>;
- };
- qcom,ocmem@fdd00000 {
- diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
- index 5134613..085b129 100644
- --- a/arch/arm/configs/msm8226-perf_defconfig
- +++ b/arch/arm/configs/msm8226-perf_defconfig
- @@ -415,6 +415,10 @@ CONFIG_RTC_DRV_QPNP=y
- CONFIG_UIO=y
- CONFIG_UIO_MSM_SHAREDMEM=y
- CONFIG_STAGING=y
- +CONFIG_ZRAM=y
- +# CONFIG_ZRAM_DEBUG is not set
- +CONFIG_ZSMALLOC=y
- +CONFIG_SWAP=y
- CONFIG_ANDROID=y
- CONFIG_ANDROID_BINDER_IPC=y
- CONFIG_ASHMEM=y
- @@ -429,6 +433,7 @@ CONFIG_QPNP_PWM=y
- CONFIG_QPNP_POWER_ON=y
- CONFIG_QPNP_VIBRATOR=y
- CONFIG_QPNP_REVID=y
- +CONFIG_MSM_AVTIMER=y
- CONFIG_MSM_IOMMU_V1=y
- CONFIG_MSM_IOMMU_VBIF_CHECK=y
- CONFIG_EXT2_FS=y
- diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
- index 68c47f0..ce6f806 100644
- --- a/arch/arm/configs/msm8226_defconfig
- +++ b/arch/arm/configs/msm8226_defconfig
- @@ -2,7 +2,7 @@
- CONFIG_EXPERIMENTAL=y
- CONFIG_SYSVIPC=y
- CONFIG_AUDIT=y
- -# CONFIG_RCU_FAST_NO_HZ=y
- +CONFIG_RCU_FAST_NO_HZ=y
- CONFIG_IKCONFIG=y
- CONFIG_IKCONFIG_PROC=y
- CONFIG_CGROUPS=y
- @@ -208,15 +208,15 @@ CONFIG_NET_SCH_HTB=y
- CONFIG_NET_SCH_PRIO=y
- CONFIG_NET_CLS_FW=y
- CONFIG_BT=y
- -# CONFIG_BT_RFCOMM is not set
- -# CONFIG_BT_RFCOMM is not set
- -# CONFIG_BT_BNEP is not set
- -#CONFIG_BT_BNEP_MC_FILTER is not set
- -# CONFIG_BT_BNEP_PROTO_FILTER is not set
- +CONFIG_BT_RFCOMM=y
- +CONFIG_BT_RFCOMM_TTY=y
- +CONFIG_BT_BNEP=y
- +CONFIG_BT_BNEP_MC_FILTER=y
- +CONFIG_BT_BNEP_PROTO_FILTER=y
- CONFIG_BT_HIDP=y
- -# CONFIG_BT_HCISMD is not set
- +CONFIG_BT_HCISMD=y
- CONFIG_CFG80211=y
- -# CONFIG_CFG80211_INTERNAL_REGDB is not set
- +CONFIG_CFG80211_INTERNAL_REGDB=y
- CONFIG_NL80211_TESTMODE=y
- CONFIG_CMA=y
- CONFIG_BLK_DEV_LOOP=y
- @@ -440,6 +440,10 @@ CONFIG_RTC_DRV_QPNP=y
- CONFIG_UIO=y
- CONFIG_UIO_MSM_SHAREDMEM=y
- CONFIG_STAGING=y
- +CONFIG_ZRAM=y
- +# CONFIG_ZRAM_DEBUG is not set
- +CONFIG_ZSMALLOC=y
- +CONFIG_SWAP=y
- CONFIG_ANDROID=y
- CONFIG_ANDROID_BINDER_IPC=y
- CONFIG_ASHMEM=y
- @@ -454,6 +458,7 @@ CONFIG_QPNP_PWM=y
- CONFIG_QPNP_POWER_ON=y
- CONFIG_QPNP_VIBRATOR=y
- CONFIG_QPNP_REVID=y
- +CONFIG_MSM_AVTIMER=y
- CONFIG_MSM_IOMMU_V1=y
- CONFIG_MSM_IOMMU_VBIF_CHECK=y
- CONFIG_CORESIGHT=y
- @@ -484,6 +489,8 @@ CONFIG_NLS_ASCII=y
- CONFIG_NLS_ISO8859_1=y
- CONFIG_PRINTK_TIME=y
- CONFIG_MAGIC_SYSRQ=y
- +CONFIG_LOCKUP_DETECTOR=y
- +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
- # CONFIG_SYSRQ_SCHED_DEBUG is not set
- CONFIG_SCHEDSTATS=y
- CONFIG_TIMER_STATS=y
- @@ -527,5 +534,4 @@ CONFIG_MOBICORE_SUPPORT=m
- CONFIG_MOBICORE_API=m
- CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
- CONFIG_MSM_RDBG=m
- -# DO NOT USE ROW IO-SCHEDULER
- -# CONFIG_DEFAULT_ROW is not set
- +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
- diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
- index 55bc185..931b272 100644
- --- a/arch/arm/configs/msm8610-perf_defconfig
- +++ b/arch/arm/configs/msm8610-perf_defconfig
- @@ -74,10 +74,9 @@ CONFIG_SCHED_MC=y
- CONFIG_ARM_ARCH_TIMER=y
- CONFIG_PREEMPT=y
- CONFIG_AEABI=y
- +CONFIG_HIGHMEM=y
- CONFIG_COMPACTION=y
- -CONFIG_KSM=y
- CONFIG_CC_STACKPROTECTOR=y
- -CONFIG_KSM=y
- CONFIG_CP_ACCESS=y
- CONFIG_USE_OF=y
- CONFIG_CPU_FREQ_GOV_POWERSAVE=y
- diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
- index b408aba..029ac2d 100644
- --- a/arch/arm/configs/msm8610_defconfig
- +++ b/arch/arm/configs/msm8610_defconfig
- @@ -75,10 +75,9 @@ CONFIG_SCHED_MC=y
- CONFIG_ARM_ARCH_TIMER=y
- CONFIG_PREEMPT=y
- CONFIG_AEABI=y
- +CONFIG_HIGHMEM=y
- CONFIG_COMPACTION=y
- -CONFIG_KSM=y
- CONFIG_CC_STACKPROTECTOR=y
- -CONFIG_KSM=y
- CONFIG_CP_ACCESS=y
- CONFIG_USE_OF=y
- CONFIG_CPU_FREQ_GOV_POWERSAVE=y
- @@ -507,6 +506,8 @@ CONFIG_NLS_ASCII=y
- CONFIG_NLS_ISO8859_1=y
- CONFIG_PRINTK_TIME=y
- CONFIG_MAGIC_SYSRQ=y
- +CONFIG_LOCKUP_DETECTOR=y
- +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
- # CONFIG_SYSRQ_SCHED_DEBUG is not set
- CONFIG_SCHEDSTATS=y
- CONFIG_TIMER_STATS=y
- @@ -562,3 +563,4 @@ CONFIG_SENSORS_CAPELLA_CM36283=y
- CONFIG_MSM_RDBG=m
- CONFIG_MOBICORE_SUPPORT=m
- CONFIG_MOBICORE_API=m
- +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
- diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
- index c7ebd60..b72527c 100755
- --- a/arch/arm/configs/msm8974-perf_defconfig
- +++ b/arch/arm/configs/msm8974-perf_defconfig
- @@ -459,6 +459,7 @@ CONFIG_QPNP_POWER_ON=y
- CONFIG_QPNP_CLKDIV=y
- CONFIG_QPNP_REVID=y
- CONFIG_QPNP_COINCELL=y
- +CONFIG_MSM_AVTIMER=y
- CONFIG_MSM_IOMMU_V1=y
- CONFIG_IOMMU_PGTABLES_L2=y
- CONFIG_MSM_IOMMU_VBIF_CHECK=y
- diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
- index d0cf629..c6fc8cd 100755
- --- a/arch/arm/configs/msm8974_defconfig
- +++ b/arch/arm/configs/msm8974_defconfig
- @@ -484,6 +484,7 @@ CONFIG_QPNP_POWER_ON=y
- CONFIG_QPNP_CLKDIV=y
- CONFIG_QPNP_REVID=y
- CONFIG_QPNP_COINCELL=y
- +CONFIG_MSM_AVTIMER=y
- CONFIG_MSM_IOMMU_V1=y
- CONFIG_MSM_IOMMU_PMON=y
- CONFIG_IOMMU_PGTABLES_L2=y
- @@ -523,6 +524,7 @@ CONFIG_NLS_ISO8859_1=y
- CONFIG_PRINTK_TIME=y
- CONFIG_MAGIC_SYSRQ=y
- CONFIG_LOCKUP_DETECTOR=y
- +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
- # CONFIG_DETECT_HUNG_TASK is not set
- # CONFIG_SYSRQ_SCHED_DEBUG is not set
- CONFIG_SCHEDSTATS=y
- @@ -570,3 +572,4 @@ CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
- CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
- CONFIG_MSM_RDBG=m
- CONFIG_MSM_AVTIMER=y
- +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
- diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
- index bdfdfa0..c6cf978 100644
- --- a/arch/arm/include/asm/arch_timer.h
- +++ b/arch/arm/include/asm/arch_timer.h
- @@ -5,6 +5,14 @@
- #include <linux/clocksource.h>
- #include <asm/errno.h>
- +#define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */
- +#define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */
- +#define ARCH_TIMER_VIRT_EVT_EN (1 << 2)
- +#define ARCH_TIMER_EVT_TRIGGER_SHIFT (4)
- +#define ARCH_TIMER_EVT_TRIGGER_MASK (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT)
- +#define ARCH_TIMER_USR_VT_ACCESS_EN (1 << 8) /* virtual timer registers */
- +#define ARCH_TIMER_USR_PT_ACCESS_EN (1 << 9) /* physical timer registers */
- +
- struct arch_timer {
- struct resource res[3];
- };
- @@ -13,6 +21,46 @@ struct arch_timer {
- int arch_timer_register(struct arch_timer *);
- int arch_timer_of_register(void);
- cycle_t arch_counter_get_cntpct(void);
- +
- +static inline u32 arch_timer_get_cntkctl(void)
- +{
- + u32 cntkctl;
- + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
- + return cntkctl;
- +}
- +
- +static inline void arch_timer_set_cntkctl(u32 cntkctl)
- +{
- + asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
- +}
- +
- +static inline void arch_counter_set_user_access(void)
- +{
- + u32 cntkctl = arch_timer_get_cntkctl();
- +
- + /* Disable user access to the timers and the physical counter */
- + /* Also disable virtual event stream */
- + cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
- + | ARCH_TIMER_USR_VT_ACCESS_EN
- + | ARCH_TIMER_VIRT_EVT_EN
- + | ARCH_TIMER_USR_PCT_ACCESS_EN);
- +
- + /* Enable user access to the virtual counter */
- + cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
- +
- + arch_timer_set_cntkctl(cntkctl);
- +}
- +
- +static inline void arch_timer_evtstrm_enable(int divider)
- +{
- + u32 cntkctl = arch_timer_get_cntkctl();
- + cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
- + /* Set the divider and enable virtual event stream */
- + cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
- + | ARCH_TIMER_VIRT_EVT_EN;
- + arch_timer_set_cntkctl(cntkctl);
- + elf_hwcap |= HWCAP_EVTSTRM;
- +}
- #else
- static inline int arch_timer_register(struct arch_timer *at)
- {
- diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
- index 9176261..ec3f3bb 100644
- --- a/arch/arm/include/asm/hwcap.h
- +++ b/arch/arm/include/asm/hwcap.h
- @@ -24,7 +24,8 @@
- #define HWCAP_IDIVA (1 << 17)
- #define HWCAP_IDIVT (1 << 18)
- #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
- -
- +#define HWCAP_LPAE (1 << 20)
- +#define HWCAP_EVTSTRM (1 << 21)
- #if defined(__KERNEL__)
- #if !defined(__ASSEMBLY__)
- /*
- diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
- index 3c463d0..7ac034e 100644
- --- a/arch/arm/kernel/arch_timer.c
- +++ b/arch/arm/kernel/arch_timer.c
- @@ -15,6 +15,7 @@
- #include <linux/device.h>
- #include <linux/smp.h>
- #include <linux/cpu.h>
- +#include <linux/cpu_pm.h>
- #include <linux/jiffies.h>
- #include <linux/clockchips.h>
- #include <linux/interrupt.h>
- @@ -259,6 +260,8 @@ static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
- if (arch_timer_ppi2)
- enable_percpu_irq(arch_timer_ppi2, 0);
- + arch_counter_set_user_access();
- +
- return 0;
- }
- @@ -408,6 +411,33 @@ static void __init arch_timer_counter_init(void)
- register_current_timer_delay(&arch_delay_timer);
- }
- +#ifdef CONFIG_CPU_PM
- +static unsigned int saved_cntkctl;
- +static int arch_timer_cpu_pm_notify(struct notifier_block *self,
- + unsigned long action, void *hcpu)
- +{
- + if (action == CPU_PM_ENTER)
- + saved_cntkctl = arch_timer_get_cntkctl();
- + else if (action == CPU_PM_ENTER_FAILED || action == CPU_PM_EXIT)
- + arch_timer_set_cntkctl(saved_cntkctl);
- + return NOTIFY_OK;
- +}
- +
- +static struct notifier_block arch_timer_cpu_pm_notifier = {
- + .notifier_call = arch_timer_cpu_pm_notify,
- +};
- +
- +static int __init arch_timer_cpu_pm_init(void)
- +{
- + return cpu_pm_register_notifier(&arch_timer_cpu_pm_notifier);
- +}
- +#else
- +static int __init arch_timer_cpu_pm_init(void)
- +{
- + return 0;
- +}
- +#endif
- +
- static int __init arch_timer_common_register(void)
- {
- int err;
- @@ -443,6 +473,10 @@ static int __init arch_timer_common_register(void)
- }
- }
- + err = arch_timer_cpu_pm_init();
- + if (err)
- + goto out_free_irq;
- +
- err = local_timer_register(&arch_timer_ops);
- if (err) {
- /*
- @@ -456,10 +490,12 @@ static int __init arch_timer_common_register(void)
- }
- if (err)
- - goto out_free_irq;
- + goto out_unreg_notify;
- return 0;
- +out_unreg_notify:
- + cpu_pm_unregister_notifier(&arch_timer_cpu_pm_notifier);
- out_free_irq:
- free_percpu_irq(arch_timer_ppi, arch_timer_evt);
- if (arch_timer_ppi2)
- diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
- index 317400a..9054e6e 100644
- --- a/arch/arm/kernel/entry-armv.S
- +++ b/arch/arm/kernel/entry-armv.S
- @@ -431,6 +431,12 @@ __und_usr:
- @ r0 - instruction
- @
- adr r9, BSYM(ret_from_exception)
- +
- + @ IRQs must be enabled before attempting to read the instruction from
- + @ user space since that could cause a page/translation fault if the
- + @ page table was modified by another CPU.
- + enable_irq
- +
- adr lr, BSYM(__und_usr_unknown)
- tst r3, #PSR_T_BIT @ Thumb mode?
- itet eq @ explicit IT needed for the 1f label
- @@ -639,7 +645,6 @@ call_fpe:
- #endif
- do_fpe:
- - enable_irq
- ldr r4, .LCfp
- add r10, r10, #TI_FPSTATE @ r10 = workspace
- ldr pc, [r4] @ Call FP module USR entry point
- @@ -663,7 +668,6 @@ ENTRY(no_fp)
- ENDPROC(no_fp)
- __und_usr_unknown:
- - enable_irq
- mov r0, sp
- adr lr, BSYM(ret_from_exception)
- b do_undefinstr
- diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
- index a087838..f07d42b 100644
- --- a/arch/arm/kernel/iwmmxt.S
- +++ b/arch/arm/kernel/iwmmxt.S
- @@ -61,7 +61,7 @@
- * r9 = ret_from_exception
- * lr = undefined instr exit
- *
- - * called from prefetch exception handler with interrupts disabled
- + * called from prefetch exception handler with interrupts enabled
- */
- ENTRY(iwmmxt_task_enable)
- diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
- index fe9abfe..58f132c 100644
- --- a/arch/arm/kernel/setup.c
- +++ b/arch/arm/kernel/setup.c
- @@ -1086,6 +1086,9 @@ static const char *hwcap_str[] = {
- "vfpv4",
- "idiva",
- "idivt",
- + "vfpd32",
- + "lpae",
- + "evtstrm",
- NULL
- };
- diff --git a/arch/arm/mach-ep93xx/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S
- index 0ec9bb4..1d5ced2 100644
- --- a/arch/arm/mach-ep93xx/crunch-bits.S
- +++ b/arch/arm/mach-ep93xx/crunch-bits.S
- @@ -62,7 +62,7 @@
- * r9 = ret_from_exception
- * lr = undefined instr exit
- *
- - * called from prefetch exception handler with interrupts disabled
- + * called from prefetch exception handler with interrupts enabled
- */
- ENTRY(crunch_task_enable)
- ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
- diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
- index 529e7d1..22a9fed 100644
- --- a/arch/arm/mach-msm/bam_dmux.c
- +++ b/arch/arm/mach-msm/bam_dmux.c
- @@ -2075,6 +2075,8 @@ static int bam_init(void)
- void *a2_virt_addr;
- int skip_iounmap = 0;
- + in_global_reset = 0;
- + in_ssr = 0;
- vote_dfab();
- /* init BAM */
- a2_virt_addr = ioremap_nocache((unsigned long)(a2_phys_base),
- diff --git a/arch/arm/mach-msm/include/mach/sensors_adsp.h b/arch/arm/mach-msm/include/mach/sensors_adsp.h
- deleted file mode 100644
- index 3c65e37..0000000
- --- a/arch/arm/mach-msm/include/mach/sensors_adsp.h
- +++ /dev/null
- @@ -1,111 +0,0 @@
- -/* Copyright (c) 2012, 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 SENSORS_ADSP_H
- -#define SENSORS_ADSP_H
- -
- -#include <linux/types.h>
- -
- -/** Maximum number of segments that may be mapped from DDR to OCMEM */
- -#define SNS_OCMEM_MAX_NUM_SEG_V01 16
- -
- -/** Maximum size of the ocmem_vectors structure */
- -#define SNS_OCMEM_MAX_VECTORS_SIZE_V01 512
- -
- -/* Sensor OCMEM message id */
- -
- -#define SNS_OCMEM_CANCEL_REQ_V01 0x0000
- -#define SNS_OCMEM_CANCEL_RESP_V01 0x0000
- -#define SNS_OCMEM_VERSION_REQ_V01 0x0001
- -#define SNS_OCMEM_VERSION_RESP_V01 0x0001
- -#define SNS_OCMEM_PHYS_ADDR_REQ_V01 0x0002
- -#define SNS_OCMEM_PHYS_ADDR_RESP_V01 0x0002
- -#define SNS_OCMEM_HAS_CLIENT_IND_V01 0x0002
- -#define SNS_OCMEM_BW_VOTE_REQ_V01 0x0003
- -#define SNS_OCMEM_BW_VOTE_RESP_V01 0x0003
- -#define SNS_OCMEM_BW_VOTE_IND_V01 0x0003
- -
- -enum {
- - SNS_OCMEM_MODULE_KERNEL = 0,
- - SNS_OCMEM_MODULE_ADSP
- -};
- -
- -/**
- - * Defines the types of response messages
- - */
- -enum {
- - SNS_OCMEM_MSG_TYPE_REQ = 0, /* Request */
- - SNS_OCMEM_MSG_TYPE_RESP, /* Response to a request */
- - SNS_OCMEM_MSG_TYPE_IND /* Asynchronous indication */
- -};
- -
- -/**
- - * The message header. Used in both incoming and outgoing messages
- - */
- -struct sns_ocmem_hdr_s {
- - int32_t msg_id ; /* Message ID, as defined in the IDL */
- - uint16_t msg_size; /* Size of message, in bytes */
- - uint8_t dst_module; /* Destination module */
- - uint8_t src_module; /* Source module */
- - uint8_t msg_type; /* The message type */
- -} __packed;
- -
- -struct sns_ocmem_common_resp_s_v01 {
- - /* This shall be the first element of every response message */
- - uint8_t sns_result_t;
- - /**< 0 == SUCCESS; 1 == FAILURE
- - A result of FAILURE indicates that that any data contained in the
- - response should not be used other than sns_err_t, to determine the
- - type of error */
- - uint8_t sns_err_t;
- - /**< See sns_ocmem_error_e in ocmem_sensors.h */
- -};
- -
- -/* This structure represents a single memory region that must be
- -mapped from DDR to OCMEM */
- -struct sns_mem_segment_s_v01 {
- -
- - uint64_t start_address; /* Physical start address of segment */
- - uint32_t size; /* Size (in bytes) of this segment */
- - uint16_t type; /* 1 == Read only; 2 == Read/Write Data */
- -} __packed;
- -
- -struct sns_ocmem_phys_addr_resp_msg_v01 {
- - struct sns_ocmem_common_resp_s_v01 resp; /* response */
- - uint32_t segments_len; /* number of elements in segments */
- - /* Segments mapped from DDR to OCMEM */
- - struct sns_mem_segment_s_v01 segments[SNS_OCMEM_MAX_NUM_SEG_V01];
- - uint8_t segments_valid; /* true if segments is being passed */
- -} __packed ;
- -
- -struct sns_ocmem_has_client_ind_msg_v01 {
- - uint16_t num_clients; /* Number of active clients on the ADSP */
- -} __packed;
- -
- -struct sns_ocmem_bw_vote_req_msg_v01 {
- - uint8_t is_map; /* True if mapping; false if unmapping */
- - uint8_t vectors_valid; /* True if vectors is being passed */
- - uint32_t vectors_len; /* Number of elements in vectors */
- - uint8_t vectors[SNS_OCMEM_MAX_VECTORS_SIZE_V01]; /* vectors */
- -} __packed;
- -
- -struct sns_ocmem_bw_vote_resp_msg_v01 {
- - struct sns_ocmem_common_resp_s_v01 resp;
- -};
- -
- -struct sns_ocmem_bw_vote_ind_msg_v01 {
- - /* If the ADSP just voted for, or took away its vote for
- - OCMEM bandwidth */
- - uint8_t is_vote_on;
- -} __packed;
- -
- -#endif /* SENSORS_ADSP_H */
- diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
- index bf7d036..75404c8 100644
- --- a/arch/arm/mach-msm/msm_rtb.c
- +++ b/arch/arm/mach-msm/msm_rtb.c
- @@ -1,5 +1,5 @@
- /*
- - * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- + * Copyright (c) 2013-2014, 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
- @@ -23,7 +23,7 @@
- #include <linux/string.h>
- #include <linux/atomic.h>
- #include <linux/of.h>
- -#include <asm/io.h>
- +#include <linux/io.h>
- #include <asm-generic/sizes.h>
- #include <mach/memory.h>
- #include <mach/msm_rtb.h>
- @@ -38,18 +38,20 @@
- /* Write
- * 1) 3 bytes sentinel
- * 2) 1 bytes of log type
- - * 3) 4 bytes of where the caller came from
- + * 3) 8 bytes of where the caller came from
- * 4) 4 bytes index
- - * 4) 4 bytes extra data from the caller
- + * 4) 8 bytes extra data from the caller
- + * 5) 8 bytes for timestamp
- *
- - * Total = 16 bytes.
- + * Total = 32 bytes.
- */
- struct msm_rtb_layout {
- unsigned char sentinel[3];
- unsigned char log_type;
- - void *caller;
- - unsigned long idx;
- - void *data;
- + uint32_t idx;
- + uint64_t caller;
- + uint64_t data;
- + uint64_t timestamp;
- } __attribute__ ((__packed__));
- @@ -70,7 +72,7 @@ DEFINE_PER_CPU(atomic_t, msm_rtb_idx_cpu);
- static atomic_t msm_rtb_idx;
- #endif
- -struct msm_rtb_state msm_rtb = {
- +static struct msm_rtb_state msm_rtb = {
- .filter = 1 << LOGK_LOGBUF,
- .enabled = 0,
- };
- @@ -109,24 +111,29 @@ static void msm_rtb_write_type(enum logk_event_type log_type,
- start->log_type = (char)log_type;
- }
- -static void msm_rtb_write_caller(void *caller, struct msm_rtb_layout *start)
- +static void msm_rtb_write_caller(uint64_t caller, struct msm_rtb_layout *start)
- {
- start->caller = caller;
- }
- -static void msm_rtb_write_idx(unsigned long idx,
- +static void msm_rtb_write_idx(uint32_t idx,
- struct msm_rtb_layout *start)
- {
- start->idx = idx;
- }
- -static void msm_rtb_write_data(void *data, struct msm_rtb_layout *start)
- +static void msm_rtb_write_data(uint64_t data, struct msm_rtb_layout *start)
- {
- start->data = data;
- }
- -static void uncached_logk_pc_idx(enum logk_event_type log_type, void *caller,
- - void *data, int idx)
- +static void msm_rtb_write_timestamp(struct msm_rtb_layout *start)
- +{
- + start->timestamp = sched_clock();
- +}
- +
- +static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller,
- + uint64_t data, int idx)
- {
- struct msm_rtb_layout *start;
- @@ -137,6 +144,7 @@ static void uncached_logk_pc_idx(enum logk_event_type log_type, void *caller,
- msm_rtb_write_caller(caller, start);
- msm_rtb_write_idx(idx, start);
- msm_rtb_write_data(data, start);
- + msm_rtb_write_timestamp(start);
- mb();
- return;
- @@ -145,13 +153,10 @@ static void uncached_logk_pc_idx(enum logk_event_type log_type, void *caller,
- static void uncached_logk_timestamp(int idx)
- {
- unsigned long long timestamp;
- - void *timestamp_upper, *timestamp_lower;
- timestamp = sched_clock();
- - timestamp_lower = (void *)lower_32_bits(timestamp);
- - timestamp_upper = (void *)upper_32_bits(timestamp);
- -
- - uncached_logk_pc_idx(LOGK_TIMESTAMP|LOGTYPE_NOPC, timestamp_lower,
- - timestamp_upper, idx);
- + uncached_logk_pc_idx(LOGK_TIMESTAMP|LOGTYPE_NOPC,
- + (uint64_t)lower_32_bits(timestamp),
- + (uint64_t)upper_32_bits(timestamp), idx);
- }
- #if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
- @@ -213,7 +218,8 @@ int notrace uncached_logk_pc(enum logk_event_type log_type, void *caller,
- i = msm_rtb_get_idx();
- - uncached_logk_pc_idx(log_type, caller, data, i);
- + uncached_logk_pc_idx(log_type, (uint64_t)((unsigned long) caller),
- + (uint64_t)((unsigned long) data), i);
- return 1;
- }
- @@ -225,7 +231,7 @@ noinline int notrace uncached_logk(enum logk_event_type log_type, void *data)
- }
- EXPORT_SYMBOL(uncached_logk);
- -int msm_rtb_probe(struct platform_device *pdev)
- +static int msm_rtb_probe(struct platform_device *pdev)
- {
- struct msm_rtb_platform_data *d = pdev->dev.platform_data;
- #if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
- @@ -297,7 +303,6 @@ static struct of_device_id msm_match_table[] = {
- {.compatible = RTB_COMPAT_STR},
- {},
- };
- -EXPORT_COMPAT(RTB_COMPAT_STR);
- static struct platform_driver msm_rtb_driver = {
- .driver = {
- diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
- index 109e120..7ccc0e3 100644
- --- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
- +++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
- @@ -24,9 +24,9 @@
- #include "audio_utils.h"
- #define MIN_FRAME_SIZE 1536
- -#define NUM_FRAMES 5
- -#define META_SIZE (sizeof(struct meta_out_dsp))
- -#define FRAME_SIZE (1 + ((MIN_FRAME_SIZE + META_SIZE) * NUM_FRAMES))
- +#define NUM_FRAMES 5
- +#define META_SIZE (sizeof(struct meta_out_dsp))
- +#define FRAME_SIZE (1 + ((MIN_FRAME_SIZE + META_SIZE) * NUM_FRAMES))
- static int audio_in_pause(struct q6audio_in *audio)
- {
- diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
- index 1c42020..99a1863 100644
- --- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
- +++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
- @@ -20,6 +20,7 @@
- #include <linux/input.h>
- #include <linux/uaccess.h>
- #include <linux/time.h>
- +#include <linux/kmemleak.h>
- #include <asm/mach-types.h>
- #include <sound/apr_audio.h>
- #include <mach/qdsp6v2/usf.h>
- @@ -572,6 +573,9 @@ static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config)
- if (config->params_data_size > 0) { /* transparent data copy */
- usf_xx->encdec_cfg.params = kzalloc(config->params_data_size,
- GFP_KERNEL);
- + /* False memory leak here - pointer in packed struct *
- + * is undetected by kmemleak tool */
- + kmemleak_ignore(usf_xx->encdec_cfg.params);
- if (usf_xx->encdec_cfg.params == NULL) {
- pr_err("%s: params memory alloc[%d] failure\n",
- __func__,
- diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
- index 1a1d587..6f473e2 100644
- --- a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
- +++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_b/q6usm_b.c
- @@ -745,7 +745,7 @@ static uint32_t q6usm_ext2int_format(uint32_t ext_format)
- int_format = US_RAW_FORMAT_V2;
- break;
- case FORMAT_USPROX:
- - int_format = US_PROX_FORMAT_V2;
- + int_format = US_PROX_FORMAT_V4;
- break;
- case FORMAT_USGES_SYNC:
- int_format = US_GES_SYNC_FORMAT;
- diff --git a/arch/arm/mach-msm/qdsp6v2/voice_svc.c b/arch/arm/mach-msm/qdsp6v2/voice_svc.c
- index 5bf86dc..9ea6a4c 100755
- --- a/arch/arm/mach-msm/qdsp6v2/voice_svc.c
- +++ b/arch/arm/mach-msm/qdsp6v2/voice_svc.c
- @@ -26,6 +26,7 @@
- #define DRIVER_NAME "voice_svc"
- #define MINOR_NUMBER 1
- #define APR_MAX_RESPONSE 10
- +#define TIMEOUT_MS 1000
- #define MAX(a, b) ((a) >= (b) ? (a) : (b))
- @@ -450,10 +451,26 @@ static long voice_svc_ioctl(struct file *file, unsigned int cmd,
- } else {
- spin_unlock_irqrestore(&prtd->response_lock,
- spin_flags);
- - wait_event_interruptible(prtd->response_wait,
- - !list_empty(&prtd->response_queue));
- - pr_debug("%s: Interupt recieved for response",
- - __func__);
- + pr_debug("%s: wait for a response\n", __func__);
- +
- + ret = wait_event_interruptible_timeout(
- + prtd->response_wait,
- + !list_empty(&prtd->response_queue),
- + msecs_to_jiffies(TIMEOUT_MS));
- + if (ret == 0) {
- + pr_debug("%s: Read timeout\n", __func__);
- + ret = -ETIMEDOUT;
- + goto done;
- + } else if (ret > 0 &&
- + !list_empty(&prtd->response_queue)) {
- + pr_debug("%s: Interrupt recieved for response\n",
- + __func__);
- + ret = 0;
- + } else if (ret < 0) {
- + pr_debug("%s: Interrupted by SIGNAL %d\n",
- + __func__, ret);
- + goto done;
- + }
- }
- } while(!apr_response);
- break;
- diff --git a/arch/arm/mach-msm/sensors_adsp.c b/arch/arm/mach-msm/sensors_adsp.c
- index 5159da0..80fe32f 100644
- --- a/arch/arm/mach-msm/sensors_adsp.c
- +++ b/arch/arm/mach-msm/sensors_adsp.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2013, 2015 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
- @@ -10,1022 +10,30 @@
- * GNU General Public License for more details.
- */
- -#include <linux/workqueue.h>
- -#include <linux/types.h>
- -#include <linux/delay.h>
- -#include <linux/bitops.h>
- -#include <linux/wait.h>
- -#include <linux/sched.h>
- -#include <linux/notifier.h>
- -#include <linux/slab.h>
- +#include <linux/msm_dsps.h>
- #include <linux/module.h>
- #include <linux/init.h>
- +#include <linux/slab.h>
- +#include <linux/platform_device.h>
- #include <linux/cdev.h>
- #include <linux/fs.h>
- -#include <linux/platform_device.h>
- -#include <linux/err.h>
- -#include <linux/io.h>
- -#include <linux/ctype.h>
- #include <linux/of_device.h>
- -#include <linux/msm_dsps.h>
- -#include <linux/uaccess.h>
- -#include <asm/mach-types.h>
- #include <asm/arch_timer.h>
- -#include <mach/subsystem_restart.h>
- -#include <mach/ocmem.h>
- -#include <mach/msm_smd.h>
- -#include <mach/sensors_adsp.h>
- -#include <mach/msm_bus.h>
- -#include <mach/msm_bus_board.h>
- +#include <linux/uaccess.h>
- #define CLASS_NAME "ssc"
- #define DRV_NAME "sensors"
- -#define DRV_VERSION "1.00"
- -
- -#define SNS_OCMEM_SMD_CHANNEL "SENSOR"
- -#define SNS_OCMEM_CLIENT_ID OCMEM_SENSORS
- -#define SNS_OCMEM_SIZE SZ_256K
- -#define SMD_BUF_SIZE 1024
- -#define SNS_TIMEOUT_MS 1000
- -
- -#define SNS_OCMEM_ALLOC_GROW 0x00000001
- -#define SNS_OCMEM_ALLOC_SHRINK 0x00000002
- -#define SNS_OCMEM_MAP_DONE 0x00000004
- -#define SNS_OCMEM_MAP_FAIL 0x00000008
- -#define SNS_OCMEM_UNMAP_DONE 0x00000010
- -#define SNS_OCMEM_UNMAP_FAIL 0x00000020
- -
- -#define DSPS_HAS_CLIENT 0x00000100
- -#define DSPS_HAS_NO_CLIENT 0x00000200
- -#define DSPS_BW_VOTE_ON 0x00000400
- -#define DSPS_BW_VOTE_OFF 0x00000800
- -#define DSPS_PHYS_ADDR_SET 0x00001000
- +#define DRV_VERSION "2.00"
- -/*
- - * Structure contains all state used by the sensors driver
- - */
- struct sns_adsp_control_s {
- - wait_queue_head_t sns_wait;
- - spinlock_t sns_lock;
- - struct workqueue_struct *sns_workqueue;
- - struct work_struct sns_work;
- - struct workqueue_struct *smd_wq;
- - struct work_struct smd_read_work;
- - smd_channel_t *smd_ch;
- - uint32_t sns_ocmem_status;
- - uint32_t mem_segments_size;
- - struct sns_mem_segment_s_v01 mem_segments[SNS_OCMEM_MAX_NUM_SEG_V01];
- - struct ocmem_buf *buf;
- - struct ocmem_map_list map_list;
- - struct ocmem_notifier *ocmem_handle;
- - bool ocmem_enabled;
- - struct notifier_block ocmem_nb;
- - uint32_t sns_ocmem_bus_client;
- - struct platform_device *pdev;
- - void *pil;
- struct class *dev_class;
- dev_t dev_num;
- struct device *dev;
- struct cdev *cdev;
- };
- -
- static struct sns_adsp_control_s sns_ctl;
- /*
- - * All asynchronous responses from the OCMEM driver are received
- - * by this function
- - */
- -int sns_ocmem_drv_cb(struct notifier_block *self,
- - unsigned long action,
- - void *dev)
- -{
- - unsigned long flags;
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- -
- - pr_debug("%s: Received OCMEM callback: action=%li\n",
- - __func__, action);
- -
- - switch (action) {
- - case OCMEM_MAP_DONE:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_MAP_DONE;
- - sns_ctl.sns_ocmem_status &= (~OCMEM_MAP_FAIL &
- - ~SNS_OCMEM_UNMAP_DONE &
- - ~SNS_OCMEM_UNMAP_FAIL);
- - break;
- - case OCMEM_MAP_FAIL:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_MAP_FAIL;
- - sns_ctl.sns_ocmem_status &= (~OCMEM_MAP_DONE &
- - ~SNS_OCMEM_UNMAP_DONE &
- - ~SNS_OCMEM_UNMAP_FAIL);
- - break;
- - case OCMEM_UNMAP_DONE:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_UNMAP_DONE;
- - sns_ctl.sns_ocmem_status &= (~SNS_OCMEM_UNMAP_FAIL &
- - ~SNS_OCMEM_MAP_DONE &
- - ~OCMEM_MAP_FAIL);
- - break;
- - case OCMEM_UNMAP_FAIL:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_UNMAP_FAIL;
- - sns_ctl.sns_ocmem_status &= (~SNS_OCMEM_UNMAP_DONE &
- - ~SNS_OCMEM_MAP_DONE &
- - ~OCMEM_MAP_FAIL);
- - break;
- - case OCMEM_ALLOC_GROW:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_ALLOC_GROW;
- - sns_ctl.sns_ocmem_status &= ~SNS_OCMEM_ALLOC_SHRINK;
- - break;
- - case OCMEM_ALLOC_SHRINK:
- - sns_ctl.sns_ocmem_status |= SNS_OCMEM_ALLOC_SHRINK;
- - sns_ctl.sns_ocmem_status &= ~SNS_OCMEM_ALLOC_GROW;
- - break;
- - default:
- - pr_err("%s: Unknown action received in OCMEM callback %lu\n",
- - __func__, action);
- - break;
- - }
- -
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- - wake_up(&sns_ctl.sns_wait);
- -
- - return 0;
- -}
- -
- -/*
- - * Processes messages received through SMD from the ADSP
- - *
- - * @param hdr The message header
- - * @param msg Message pointer
- - *
- - */
- -void sns_ocmem_smd_process(struct sns_ocmem_hdr_s *hdr, void *msg)
- -{
- - unsigned long flags;
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- -
- - pr_debug("%s: Received message from ADSP; id: %i type: %i (%08x)\n",
- - __func__, hdr->msg_id, hdr->msg_type,
- - sns_ctl.sns_ocmem_status);
- -
- - if (hdr->msg_id == SNS_OCMEM_PHYS_ADDR_RESP_V01 &&
- - hdr->msg_type == SNS_OCMEM_MSG_TYPE_RESP) {
- - struct sns_ocmem_phys_addr_resp_msg_v01 *msg_ptr =
- - (struct sns_ocmem_phys_addr_resp_msg_v01 *)msg;
- - pr_debug("%s: Received SNS_OCMEM_PHYS_ADDR_RESP_V01\n",
- - __func__);
- - pr_debug("%s: segments_valid=%d, segments_len=%d\n", __func__,
- - msg_ptr->segments_valid, msg_ptr->segments_len);
- -
- - if (msg_ptr->segments_valid) {
- - sns_ctl.mem_segments_size = msg_ptr->segments_len;
- - memcpy(sns_ctl.mem_segments, msg_ptr->segments,
- - sizeof(struct sns_mem_segment_s_v01) *
- - msg_ptr->segments_len);
- -
- - sns_ctl.sns_ocmem_status |= DSPS_PHYS_ADDR_SET;
- - } else {
- - pr_err("%s: Received invalid segment list\n", __func__);
- - }
- - } else if (hdr->msg_id == SNS_OCMEM_HAS_CLIENT_IND_V01 &&
- - hdr->msg_type == SNS_OCMEM_MSG_TYPE_IND) {
- - struct sns_ocmem_has_client_ind_msg_v01 *msg_ptr =
- - (struct sns_ocmem_has_client_ind_msg_v01 *)msg;
- -
- - pr_debug("%s: Received SNS_OCMEM_HAS_CLIENT_IND_V01\n",
- - __func__);
- - pr_debug("%s: ADSP has %i client(s)\n", __func__,
- - msg_ptr->num_clients);
- - if (msg_ptr->num_clients > 0) {
- - sns_ctl.sns_ocmem_status |= DSPS_HAS_CLIENT;
- - sns_ctl.sns_ocmem_status &= ~DSPS_HAS_NO_CLIENT;
- - } else {
- - sns_ctl.sns_ocmem_status |= DSPS_HAS_NO_CLIENT;
- - sns_ctl.sns_ocmem_status &= ~DSPS_HAS_CLIENT;
- - }
- - } else if (hdr->msg_id == SNS_OCMEM_BW_VOTE_RESP_V01 &&
- - hdr->msg_type == SNS_OCMEM_MSG_TYPE_RESP) {
- - /* no need to handle this response msg, just return */
- - pr_debug("%s: Received SNS_OCMEM_BW_VOTE_RESP_V01\n", __func__);
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- - return;
- - } else if (hdr->msg_id == SNS_OCMEM_BW_VOTE_IND_V01 &&
- - hdr->msg_type == SNS_OCMEM_MSG_TYPE_IND) {
- - struct sns_ocmem_bw_vote_ind_msg_v01 *msg_ptr =
- - (struct sns_ocmem_bw_vote_ind_msg_v01 *)msg;
- - pr_debug("%s: Received BW_VOTE_IND_V01, is_vote_on=%d\n",
- - __func__, msg_ptr->is_vote_on);
- -
- - if (msg_ptr->is_vote_on) {
- - sns_ctl.sns_ocmem_status |= DSPS_BW_VOTE_ON;
- - sns_ctl.sns_ocmem_status &= ~DSPS_BW_VOTE_OFF;
- - } else {
- - sns_ctl.sns_ocmem_status |= DSPS_BW_VOTE_OFF;
- - sns_ctl.sns_ocmem_status &= ~DSPS_BW_VOTE_ON;
- - }
- - } else {
- - pr_err("%s: Unknown message type received. id: %i; type: %i\n",
- - __func__, hdr->msg_id, hdr->msg_type);
- - }
- -
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- -
- - wake_up(&sns_ctl.sns_wait);
- -}
- -
- -static void sns_ocmem_smd_read(struct work_struct *ws)
- -{
- - struct smd_channel *ch = sns_ctl.smd_ch;
- - unsigned char *buf = NULL;
- - int sz, len;
- -
- - for (;;) {
- - sz = smd_cur_packet_size(ch);
- - BUG_ON(sz > SMD_BUF_SIZE);
- - len = smd_read_avail(ch);
- - pr_debug("%s: sz=%d, len=%d\n", __func__, sz, len);
- - if (len == 0 || len < sz)
- - break;
- - buf = kzalloc(SMD_BUF_SIZE, GFP_KERNEL);
- - if (buf == NULL) {
- - pr_err("%s: malloc failed", __func__);
- - break;
- - }
- -
- - if (smd_read(ch, buf, sz) != sz) {
- - pr_err("%s: not enough data?!\n", __func__);
- - kfree(buf);
- - continue;
- - }
- -
- - sns_ocmem_smd_process((struct sns_ocmem_hdr_s *)buf,
- - (void *)((char *)buf +
- - sizeof(struct sns_ocmem_hdr_s)));
- -
- - kfree(buf);
- -
- - }
- -}
- -
- -/*
- - * All SMD notifications and messages from Sensors on ADSP are
- - * received by this function
- - *
- - */
- -void sns_ocmem_smd_notify_data(void *data, unsigned int event)
- -{
- - if (event == SMD_EVENT_DATA) {
- - int sz;
- - pr_debug("%s: Received SMD event Data\n", __func__);
- - sz = smd_cur_packet_size(sns_ctl.smd_ch);
- - if ((sz > 0) && (sz <= smd_read_avail(sns_ctl.smd_ch)))
- - queue_work(sns_ctl.smd_wq, &sns_ctl.smd_read_work);
- - } else if (event == SMD_EVENT_OPEN) {
- - pr_debug("%s: Received SMD event Open\n", __func__);
- - } else if (event == SMD_EVENT_CLOSE) {
- - pr_debug("%s: Received SMD event Close\n", __func__);
- - }
- -}
- -
- -static bool sns_ocmem_is_status_set(uint32_t sns_ocmem_status)
- -{
- - unsigned long flags;
- - bool is_set;
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- - is_set = sns_ctl.sns_ocmem_status & sns_ocmem_status;
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- - return is_set;
- -}
- -
- -/*
- - * Wait for a response from ADSP or OCMEM Driver, timeout if necessary
- - *
- - * @param sns_ocmem_status Status flags to wait for.
- - * @param timeout_sec Seconds to wait before timeout
- - * @param timeout_nsec Nanoseconds to wait. Total timeout = nsec + sec
- - *
- - * @return 0 If any status flag is set at any time prior to a timeout.
- - * 0 if success or timedout ; <0 for failures
- - */
- -static int sns_ocmem_wait(uint32_t sns_ocmem_status,
- - uint32_t timeout_ms)
- -{
- - int err;
- - if (timeout_ms) {
- - err = wait_event_interruptible_timeout(sns_ctl.sns_wait,
- - sns_ocmem_is_status_set(sns_ocmem_status),
- - msecs_to_jiffies(timeout_ms));
- -
- - if (err == 0)
- - pr_err("%s: interruptible_timeout timeout err=%i\n",
- - __func__, err);
- - else if (err < 0)
- - pr_err("%s: interruptible_timeout failed err=%i\n",
- - __func__, err);
- - } else { /* no timeout */
- - err = wait_event_interruptible(sns_ctl.sns_wait,
- - sns_ocmem_is_status_set(sns_ocmem_status));
- - if (err < 0)
- - pr_err("%s: wait_event_interruptible failed err=%i\n",
- - __func__, err);
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Sends a message to the ADSP via SMD.
- - *
- - * @param hdr Specifies message type and other meta data
- - * @param msg_ptr Pointer to the message contents.
- - * Must be freed within this function if no error is returned.
- - *
- - * @return 0 upon success; < 0 upon error
- - */
- -static int
- -sns_ocmem_send_msg(struct sns_ocmem_hdr_s *hdr, void const *msg_ptr)
- -{
- - int rv = 0;
- - int err = 0;
- - void *temp = NULL;
- - int size = 0;
- -
- - if (hdr == NULL) {
- - pr_err("%s: NULL message header\n", __func__);
- - rv = -EINVAL;
- - goto out;
- - }
- -
- - size = sizeof(struct sns_ocmem_hdr_s) + hdr->msg_size;
- - temp = kzalloc(sizeof(struct sns_ocmem_hdr_s) + hdr->msg_size,
- - GFP_KERNEL);
- -
- - if (temp == NULL) {
- - pr_err("%s: allocation failure\n", __func__);
- - rv = -ENOMEM;
- - goto out;
- - }
- -
- - hdr->dst_module = SNS_OCMEM_MODULE_ADSP;
- - hdr->src_module = SNS_OCMEM_MODULE_KERNEL;
- -
- - memcpy(temp, hdr, sizeof(struct sns_ocmem_hdr_s));
- - memcpy((char *)temp + sizeof(struct sns_ocmem_hdr_s),
- - msg_ptr, hdr->msg_size);
- - pr_debug("%s: send msg type: %i size: %i id: %i dst: %i src: %i\n",
- - __func__, hdr->msg_type, hdr->msg_size,
- - hdr->msg_id, hdr->dst_module, hdr->src_module);
- -
- - if (sns_ctl.smd_ch == NULL) {
- - pr_err("%s: null smd_ch\n", __func__);
- - rv = -EINVAL;
- - }
- - err = smd_write(sns_ctl.smd_ch, temp, size);
- - if (err < 0) {
- - pr_err("%s: smd_write failed %i\n", __func__, err);
- - rv = -ECOMM;
- - } else {
- - pr_debug("%s smd_write successful ret=%d\n",
- - __func__, err);
- - }
- -
- - kfree(temp);
- -
- -out:
- - return rv;
- -}
- -
- -/*
- - * Load ADSP Firmware.
- - */
- -
- -static int sns_load_adsp(void)
- -{
- - sns_ctl.pil = subsystem_get("adsp");
- - if (IS_ERR(sns_ctl.pil)) {
- - pr_err("%s: fail to load ADSP firmware\n", __func__);
- - return -ENODEV;
- - }
- -
- - pr_debug("%s: Q6/ADSP image is loaded\n", __func__);
- -
- - return 0;
- -}
- -
- -static int sns_ocmem_platform_data_populate(struct platform_device *pdev)
- -{
- - int ret;
- - struct msm_bus_scale_pdata *sns_ocmem_bus_scale_pdata = NULL;
- - struct msm_bus_vectors *sns_ocmem_bus_vectors = NULL;
- - struct msm_bus_paths *ocmem_sns_bus_paths = NULL;
- - u32 val;
- -
- - if (!pdev->dev.of_node) {
- - pr_err("%s: device tree information missing\n", __func__);
- - return -ENODEV;
- - }
- -
- - sns_ocmem_bus_vectors = kzalloc(sizeof(struct msm_bus_vectors),
- - GFP_KERNEL);
- - if (!sns_ocmem_bus_vectors) {
- - dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
- - return -ENOMEM;
- - }
- -
- - ret = of_property_read_u32(pdev->dev.of_node,
- - "qcom,src-id", &val);
- - if (ret) {
- - dev_err(&pdev->dev, "%s: qcom,src-id missing in DT node\n",
- - __func__);
- - goto fail1;
- - }
- - sns_ocmem_bus_vectors->src = val;
- - ret = of_property_read_u32(pdev->dev.of_node,
- - "qcom,dst-id", &val);
- - if (ret) {
- - dev_err(&pdev->dev, "%s: qcom,dst-id missing in DT node\n",
- - __func__);
- - goto fail1;
- - }
- - sns_ocmem_bus_vectors->dst = val;
- - ret = of_property_read_u32(pdev->dev.of_node,
- - "qcom,ab", &val);
- - if (ret) {
- - dev_err(&pdev->dev, "%s: qcom,ab missing in DT node\n",
- - __func__);
- - goto fail1;
- - }
- - sns_ocmem_bus_vectors->ab = val;
- - ret = of_property_read_u32(pdev->dev.of_node,
- - "qcom,ib", &val);
- - if (ret) {
- - dev_err(&pdev->dev, "%s: qcom,ib missing in DT node\n",
- - __func__);
- - goto fail1;
- - }
- - sns_ocmem_bus_vectors->ib = val;
- - ocmem_sns_bus_paths = kzalloc(sizeof(struct msm_bus_paths),
- - GFP_KERNEL);
- -
- - if (!ocmem_sns_bus_paths) {
- - dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
- - goto fail1;
- - }
- - ocmem_sns_bus_paths->num_paths = 1;
- - ocmem_sns_bus_paths->vectors = sns_ocmem_bus_vectors;
- -
- - sns_ocmem_bus_scale_pdata =
- - kzalloc(sizeof(struct msm_bus_scale_pdata), GFP_KERNEL);
- - if (!sns_ocmem_bus_scale_pdata) {
- - dev_err(&pdev->dev, "Failed to allocate memory for platform data\n");
- - goto fail2;
- - }
- -
- - sns_ocmem_bus_scale_pdata->usecase = ocmem_sns_bus_paths;
- - sns_ocmem_bus_scale_pdata->num_usecases = 1;
- - sns_ocmem_bus_scale_pdata->name = "sensors-ocmem";
- -
- - dev_set_drvdata(&pdev->dev, sns_ocmem_bus_scale_pdata);
- - return ret;
- -
- -fail2:
- - kfree(ocmem_sns_bus_paths);
- -fail1:
- - kfree(sns_ocmem_bus_vectors);
- - return ret;
- -}
- -
- -
- -/*
- - * Initialize all sensors ocmem driver data fields and register with the
- - * ocmem driver.
- - *
- - * @return 0 upon success; < 0 upon error
- - */
- -static int sns_ocmem_init(void)
- -{
- - int i, err, ret;
- - struct sns_ocmem_hdr_s addr_req_hdr;
- - struct msm_bus_scale_pdata *sns_ocmem_bus_scale_pdata = NULL;
- -
- - /* register from OCMEM callack */
- - sns_ctl.ocmem_handle =
- - ocmem_notifier_register(SNS_OCMEM_CLIENT_ID,
- - &sns_ctl.ocmem_nb);
- - if (sns_ctl.ocmem_handle == NULL) {
- - pr_err("OCMEM notifier registration failed\n");
- - return -EFAULT;
- - }
- -
- - /* populate platform data */
- - ret = sns_ocmem_platform_data_populate(sns_ctl.pdev);
- - if (ret) {
- - dev_err(&sns_ctl.pdev->dev,
- - "%s: failed to populate platform data, rc = %d\n",
- - __func__, ret);
- - return -ENODEV;
- - }
- - sns_ocmem_bus_scale_pdata = dev_get_drvdata(&sns_ctl.pdev->dev);
- -
- - sns_ctl.sns_ocmem_bus_client =
- - msm_bus_scale_register_client(sns_ocmem_bus_scale_pdata);
- -
- - if (!sns_ctl.sns_ocmem_bus_client) {
- - pr_err("%s: msm_bus_scale_register_client() failed\n",
- - __func__);
- - return -EFAULT;
- - }
- -
- - /* load ADSP first */
- - if (sns_load_adsp() != 0) {
- - pr_err("%s: sns_load_adsp failed\n", __func__);
- - return -EFAULT;
- - }
- -
- - /*
- - * wait before open SMD channel from kernel to ensure
- - * channel has been openned already from ADSP side
- - */
- - msleep(1000);
- -
- - err = smd_named_open_on_edge(SNS_OCMEM_SMD_CHANNEL,
- - SMD_APPS_QDSP,
- - &sns_ctl.smd_ch,
- - NULL,
- - sns_ocmem_smd_notify_data);
- - if (err != 0) {
- - pr_err("%s: smd_named_open_on_edge failed %i\n", __func__, err);
- - return -EFAULT;
- - }
- -
- - pr_debug("%s: SMD channel openned successfuly!\n", __func__);
- - /* wait for the channel ready before writing data */
- - msleep(1000);
- - addr_req_hdr.msg_id = SNS_OCMEM_PHYS_ADDR_REQ_V01;
- - addr_req_hdr.msg_type = SNS_OCMEM_MSG_TYPE_REQ;
- - addr_req_hdr.msg_size = 0;
- -
- - err = sns_ocmem_send_msg(&addr_req_hdr, NULL);
- - if (err != 0) {
- - pr_err("%s: sns_ocmem_send_msg failed %i\n", __func__, err);
- - return -ECOMM;
- - }
- -
- - err = sns_ocmem_wait(DSPS_PHYS_ADDR_SET, 0);
- - if (err != 0) {
- - pr_err("%s: sns_ocmem_wait failed %i\n", __func__, err);
- - return -EFAULT;
- - }
- -
- - sns_ctl.map_list.num_chunks = sns_ctl.mem_segments_size;
- - for (i = 0; i < sns_ctl.mem_segments_size; i++) {
- - sns_ctl.map_list.chunks[i].ro =
- - sns_ctl.mem_segments[i].type == 1 ? true : false;
- - sns_ctl.map_list.chunks[i].ddr_paddr =
- - sns_ctl.mem_segments[i].start_address;
- - sns_ctl.map_list.chunks[i].size =
- - sns_ctl.mem_segments[i].size;
- -
- - pr_debug("%s: chunks[%d]: ro=%d, ddr_paddr=0x%lx, size=%li",
- - __func__, i,
- - sns_ctl.map_list.chunks[i].ro,
- - sns_ctl.map_list.chunks[i].ddr_paddr,
- - sns_ctl.map_list.chunks[i].size);
- - }
- -
- - return 0;
- -}
- -
- -/*
- - * Unmaps memory in ocmem back to DDR, indicates to the ADSP its completion,
- - * and waits for it to finish removing its bandwidth vote.
- - */
- -static void sns_ocmem_unmap(void)
- -{
- - unsigned long flags;
- - int err = 0;
- -
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf, OCMEM_ON);
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- - sns_ctl.sns_ocmem_status &= (~SNS_OCMEM_UNMAP_FAIL &
- - ~SNS_OCMEM_UNMAP_DONE);
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- -
- - err = ocmem_unmap(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf,
- - &sns_ctl.map_list);
- -
- - if (err != 0) {
- - pr_err("ocmem_unmap failed %i\n", err);
- - } else {
- - err = sns_ocmem_wait(SNS_OCMEM_UNMAP_DONE |
- - SNS_OCMEM_UNMAP_FAIL, 0);
- -
- - if (err == 0) {
- - if (sns_ocmem_is_status_set(SNS_OCMEM_UNMAP_DONE))
- - pr_debug("%s: OCMEM_UNMAP_DONE\n", __func__);
- - else if (sns_ocmem_is_status_set(
- - SNS_OCMEM_UNMAP_FAIL)) {
- - pr_err("%s: OCMEM_UNMAP_FAIL\n", __func__);
- - BUG_ON(true);
- - } else
- - pr_err("%s: status flag not set\n", __func__);
- - } else {
- - pr_err("%s: sns_ocmem_wait failed %i\n",
- - __func__, err);
- - }
- - }
- -
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf, OCMEM_OFF);
- -}
- -
- -/*
- - * Waits for allocation to succeed. This may take considerable time if the device
- - * is presently in a high-power use case.
- - *
- - * @return 0 on success; < 0 upon error
- - */
- -static int sns_ocmem_wait_for_alloc(void)
- -{
- - int err = 0;
- -
- - err = sns_ocmem_wait(SNS_OCMEM_ALLOC_GROW |
- - DSPS_HAS_NO_CLIENT, 0);
- -
- - if (err == 0) {
- - if (sns_ocmem_is_status_set(DSPS_HAS_NO_CLIENT)) {
- - pr_debug("%s: Lost client while waiting for GROW\n",
- - __func__);
- - ocmem_free(SNS_OCMEM_CLIENT_ID, sns_ctl.buf);
- - sns_ctl.buf = NULL;
- - return -EPIPE;
- - }
- - } else {
- - pr_err("sns_ocmem_wait failed %i\n", err);
- - return -EFAULT;
- - }
- -
- - return 0;
- -}
- -
- -/*
- - * Kicks-off the mapping of memory from DDR to ocmem. Waits for the process
- - * to complete, then indicates so to the ADSP.
- - *
- - * @return 0: Success; < 0: Other error
- - */
- -static int sns_ocmem_map(void)
- -{
- - int err = 0;
- - unsigned long flags;
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- - sns_ctl.sns_ocmem_status &=
- - (~SNS_OCMEM_MAP_FAIL & ~SNS_OCMEM_MAP_DONE);
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- -
- - /* vote for ocmem bus bandwidth */
- - err = msm_bus_scale_client_update_request(
- - sns_ctl.sns_ocmem_bus_client,
- - 0);
- - if (err)
- - pr_err("%s: failed to vote for bus bandwidth\n", __func__);
- -
- - err = ocmem_map(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf,
- - &sns_ctl.map_list);
- -
- - if (err != 0) {
- - pr_debug("ocmem_map failed %i\n", err);
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf, OCMEM_OFF);
- - ocmem_free(SNS_OCMEM_CLIENT_ID, sns_ctl.buf);
- - sns_ctl.buf = NULL;
- - } else {
- - err = sns_ocmem_wait(SNS_OCMEM_ALLOC_SHRINK |
- - DSPS_HAS_NO_CLIENT |
- - SNS_OCMEM_MAP_DONE |
- - SNS_OCMEM_MAP_FAIL, 0);
- -
- - if (err == 0) {
- - if (sns_ocmem_is_status_set(SNS_OCMEM_MAP_DONE))
- - pr_debug("%s: OCMEM mapping DONE\n", __func__);
- - else if (sns_ocmem_is_status_set(DSPS_HAS_NO_CLIENT)) {
- - pr_debug("%s: Lost client while waiting for MAP\n",
- - __func__);
- - sns_ocmem_unmap();
- - ocmem_free(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf);
- - sns_ctl.buf = NULL;
- - err = -EPIPE;
- - } else if (sns_ocmem_is_status_set(
- - SNS_OCMEM_ALLOC_SHRINK)) {
- - pr_debug("%s: SHRINK while wait for MAP\n",
- - __func__);
- - sns_ocmem_unmap();
- - err = ocmem_shrink(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf, 0);
- - BUG_ON(err != 0);
- - err = -EFAULT;
- - } else if (sns_ocmem_is_status_set(
- - SNS_OCMEM_MAP_FAIL)) {
- - pr_err("%s: OCMEM mapping fails\n", __func__);
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf,
- - OCMEM_OFF);
- - ocmem_free(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf);
- - sns_ctl.buf = NULL;
- - } else
- - pr_err("%s: status flag not set\n", __func__);
- - } else {
- - pr_err("sns_ocmem_wait failed %i\n", err);
- - }
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Allocates memory in ocmem and maps to it from DDR.
- - *
- - * @return 0 upon success; <0 upon failure;
- - */
- -static int sns_ocmem_alloc(void)
- -{
- - int err = 0;
- - unsigned long flags;
- -
- - if (sns_ctl.buf == NULL) {
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- - sns_ctl.sns_ocmem_status &= ~SNS_OCMEM_ALLOC_GROW &
- - ~SNS_OCMEM_ALLOC_SHRINK;
- - spin_unlock_irqrestore(&sns_ctl.sns_lock, flags);
- - sns_ctl.buf = ocmem_allocate_nb(SNS_OCMEM_CLIENT_ID,
- - SNS_OCMEM_SIZE);
- -
- - if (sns_ctl.buf == NULL) {
- - pr_err("ocmem_allocate_nb returned NULL\n");
- - sns_ctl.ocmem_enabled = false;
- - err = -EFAULT;
- - } else if (sns_ctl.buf->len != 0 &&
- - SNS_OCMEM_SIZE > sns_ctl.buf->len) {
- - pr_err("ocmem_allocate_nb: invalid len %li, Req: %i)\n",
- - sns_ctl.buf->len, SNS_OCMEM_SIZE);
- - sns_ctl.ocmem_enabled = false;
- - err = -EFAULT;
- - }
- - }
- -
- - pr_debug("%s OCMEM buf=%lx, buffer len=%li\n", __func__,
- - sns_ctl.buf->addr, sns_ctl.buf->len);
- -
- - while (sns_ctl.ocmem_enabled) {
- - if (sns_ctl.buf->len == 0) {
- - pr_debug("%s: Waiting for memory allocation\n",
- - __func__);
- - err = sns_ocmem_wait_for_alloc();
- - if (err == -EPIPE) {
- - pr_debug("%s:Lost client while wait for alloc\n",
- - __func__);
- - break;
- - } else if (err != 0) {
- - pr_err("sns_ocmem_wait_for_alloc failed %i\n",
- - err);
- - break;
- - }
- - }
- -
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf,
- - OCMEM_ON);
- -
- - err = sns_ocmem_map();
- -
- - if (err == -EPIPE) {
- - pr_debug("%s: Lost client while waiting for mapping\n",
- - __func__);
- - break;
- - } else if (err < 0) {
- - pr_debug("%s: Mapping failed, will try again\n",
- - __func__);
- - break;
- - } else if (err == 0) {
- - pr_debug("%s: Mapping finished\n", __func__);
- - break;
- - }
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Indicate to the ADSP that unmapping has completed, and wait for the response
- - * that its bandwidth vote has been removed.
- - *
- - * @return 0 Upon success; < 0 upon error
- - */
- -static int sns_ocmem_unmap_send(void)
- -{
- - int err;
- - struct sns_ocmem_hdr_s msg_hdr;
- - struct sns_ocmem_bw_vote_req_msg_v01 msg;
- -
- - memset(&msg, 0, sizeof(struct sns_ocmem_bw_vote_req_msg_v01));
- -
- - msg_hdr.msg_id = SNS_OCMEM_BW_VOTE_REQ_V01;
- - msg_hdr.msg_type = SNS_OCMEM_MSG_TYPE_REQ;
- - msg_hdr.msg_size = sizeof(struct sns_ocmem_bw_vote_req_msg_v01);
- - msg.is_map = 0;
- - msg.vectors_valid = 0;
- - msg.vectors_len = 0;
- -
- - pr_debug("%s: send bw_vote OFF\n", __func__);
- - err = sns_ocmem_send_msg(&msg_hdr, &msg);
- - if (err != 0) {
- - pr_err("%s: sns_ocmem_send_msg failed %i\n",
- - __func__, err);
- - } else {
- - err = sns_ocmem_wait(DSPS_BW_VOTE_OFF, 0);
- - if (err != 0)
- - pr_err("%s: sns_ocmem_wait failed %i\n", __func__, err);
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Indicate to the ADSP that mapping has completed, and wait for the response
- - * that its bandwidth vote has been made.
- - *
- - * @return 0 Upon success; < 0 upon error
- - */
- -static int sns_ocmem_map_send(void)
- -{
- - int err;
- - struct sns_ocmem_hdr_s msg_hdr;
- - struct sns_ocmem_bw_vote_req_msg_v01 msg;
- - struct ocmem_vectors *vectors;
- -
- - memset(&msg, 0, sizeof(struct sns_ocmem_bw_vote_req_msg_v01));
- -
- - msg_hdr.msg_id = SNS_OCMEM_BW_VOTE_REQ_V01;
- - msg_hdr.msg_type = SNS_OCMEM_MSG_TYPE_REQ;
- - msg_hdr.msg_size = sizeof(struct sns_ocmem_bw_vote_req_msg_v01);
- - msg.is_map = 1;
- -
- - vectors = ocmem_get_vectors(SNS_OCMEM_CLIENT_ID, sns_ctl.buf);
- - if ((vectors != NULL)) {
- - memcpy(&msg.vectors, vectors, sizeof(*vectors));
- - /* TODO: set vectors_len */
- - msg.vectors_valid = true;
- - msg.vectors_len = 0;
- - }
- -
- - pr_debug("%s: send bw_vote ON\n", __func__);
- - err = sns_ocmem_send_msg(&msg_hdr, &msg);
- - if (err != 0) {
- - pr_err("%s: sns_ocmem_send_msg failed %i\n", __func__, err);
- - } else {
- - err = sns_ocmem_wait(DSPS_BW_VOTE_ON |
- - SNS_OCMEM_ALLOC_SHRINK, 0);
- - if (err != 0)
- - pr_err("%s: sns_ocmem_wait failed %i\n", __func__, err);
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Perform the encessary operations to clean-up OCMEM after being notified that
- - * there is no longer a client; if sensors was evicted; or if some error
- - * has occurred.
- - *
- - * @param[i] do_free Whether the memory should be freed (true) or if shrink
- - * should be called instead (false).
- - */
- -static void sns_ocmem_evicted(bool do_free)
- -{
- - int err = 0;
- -
- - sns_ocmem_unmap();
- - if (do_free) {
- - ocmem_free(SNS_OCMEM_CLIENT_ID, sns_ctl.buf);
- - sns_ctl.buf = NULL;
- - } else {
- - err = ocmem_shrink(SNS_OCMEM_CLIENT_ID, sns_ctl.buf, 0);
- - BUG_ON(err != 0);
- - }
- -
- - err = sns_ocmem_unmap_send();
- - if (err != 0)
- - pr_err("sns_ocmem_unmap_send failed %i\n", err);
- -}
- -
- -/*
- - * After mapping has completed and the ADSP has reacted appropriately, wait
- - * for a shrink command or word from the ADSP that it no longer has a client.
- - *
- - * @return 0 If no clients; < 0 upon error;
- - */
- -static int sns_ocmem_map_done(void)
- -{
- - int err = 0;
- - unsigned long flags;
- -
- - err = sns_ocmem_map_send();
- - if (err != 0) {
- - pr_err("sns_ocmem_map_send failed %i\n", err);
- - sns_ocmem_evicted(true);
- - } else {
- - ocmem_set_power_state(SNS_OCMEM_CLIENT_ID,
- - sns_ctl.buf, OCMEM_OFF);
- -
- - pr_debug("%s: Waiting for shrink or 'no client' updates\n",
- - __func__);
- - err = sns_ocmem_wait(DSPS_HAS_NO_CLIENT |
- - SNS_OCMEM_ALLOC_SHRINK, 0);
- - if (err == 0) {
- - if (sns_ocmem_is_status_set(DSPS_HAS_NO_CLIENT)) {
- - pr_debug("%s: No longer have a client\n",
- - __func__);
- - sns_ocmem_evicted(true);
- - } else if (sns_ocmem_is_status_set(
- - SNS_OCMEM_ALLOC_SHRINK)) {
- - pr_debug("%s: Received SHRINK\n", __func__);
- - sns_ocmem_evicted(false);
- -
- - spin_lock_irqsave(&sns_ctl.sns_lock, flags);
- - sns_ctl.sns_ocmem_status &=
- - ~SNS_OCMEM_ALLOC_SHRINK;
- - spin_unlock_irqrestore(&sns_ctl.sns_lock,
- - flags);
- - err = -EFAULT;
- - }
- - } else {
- - pr_err("sns_ocmem_wait failed %i\n", err);
- - }
- - }
- -
- - return err;
- -}
- -
- -/*
- - * Main function.
- - * Initializes sensors ocmem feature, and waits for an ADSP client.
- - */
- -static void sns_ocmem_main(struct work_struct *work)
- -{
- - int err = 0;
- - pr_debug("%s\n", __func__);
- -
- - err = sns_ocmem_init();
- - if (err != 0) {
- - pr_err("%s: sns_ocmem_init failed %i\n", __func__, err);
- - return;
- - }
- -
- - while (true) {
- - pr_debug("%s: Waiting for sensor client\n", __func__);
- - if (sns_ocmem_is_status_set(DSPS_HAS_CLIENT) ||
- - !sns_ocmem_wait(DSPS_HAS_CLIENT, 0)) {
- - pr_debug("%s: DSPS_HAS_CLIENT\n", __func__);
- -
- - err = sns_ocmem_alloc();
- - if (err != 0) {
- - pr_err("sns_ocmem_alloc failed %i\n", err);
- - return;
- - } else {
- - err = sns_ocmem_map_done();
- - if (err != 0) {
- - pr_err("sns_ocmem_map_done failed %i",
- - err);
- - return;
- - }
- - }
- - }
- - }
- -
- - ocmem_notifier_unregister(sns_ctl.ocmem_handle,
- - &sns_ctl.ocmem_nb);
- -}
- -
- -static int sensors_adsp_open(struct inode *ip, struct file *fp)
- -{
- - int ret = 0;
- - return ret;
- -}
- -
- -static int sensors_adsp_release(struct inode *inode, struct file *file)
- -{
- - return 0;
- -}
- -
- -/*
- * Read QTimer clock ticks and scale down to 32KHz clock as used
- * in DSPS
- */
- @@ -1047,9 +55,16 @@ static u32 sns_read_qtimer(void)
- return (u32)val;
- }
- -/*
- - * IO Control - handle commands from client.
- - */
- +static int sensors_adsp_open(struct inode *ip, struct file *fp)
- +{
- + return 0;
- +}
- +
- +static int sensors_adsp_release(struct inode *inode, struct file *file)
- +{
- + return 0;
- +}
- +
- static long sensors_adsp_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
- {
- @@ -1070,41 +85,18 @@ static long sensors_adsp_ioctl(struct file *file,
- return ret;
- }
- -/*
- - * platform driver
- - */
- const struct file_operations sensors_adsp_fops = {
- .owner = THIS_MODULE,
- .open = sensors_adsp_open,
- .release = sensors_adsp_release,
- - .unlocked_ioctl = sensors_adsp_ioctl,
- + .unlocked_ioctl = sensors_adsp_ioctl
- };
- -#ifdef CONFIG_ADSP_FACTORY
- - struct class* get_adsp_sensor_class( void )
- -{
- -pr_err(" %s:",__func__);
- -if (sns_ctl.dev_class == NULL) {
- - sns_ctl.dev_class = class_create(THIS_MODULE, DRV_NAME);
- - if (sns_ctl.dev_class == NULL) {
- - pr_err("%s: class_create fail.\n", __func__);
- - }
- -}
- -
- -return sns_ctl.dev_class;
- -}
- -
- -EXPORT_SYMBOL(get_adsp_sensor_class);
- -#endif
- static int sensors_adsp_probe(struct platform_device *pdev)
- {
- int ret = 0;
- -#ifdef CONFIG_ADSP_FACTORY
- - pr_err("%s:++",__func__);
- - if (sns_ctl.dev_class == NULL) {
- - sns_ctl.dev_class = class_create(THIS_MODULE, DRV_NAME);
- - }
- -#endif
- +
- + sns_ctl.dev_class = class_create(THIS_MODULE, CLASS_NAME);
- if (sns_ctl.dev_class == NULL) {
- pr_err("%s: class_create fail.\n", __func__);
- goto res_err;
- @@ -1138,38 +130,6 @@ static int sensors_adsp_probe(struct platform_device *pdev)
- goto cdev_add_err;
- }
- - sns_ctl.sns_workqueue =
- - alloc_workqueue("sns_ocmem", WQ_NON_REENTRANT, 0);
- - if (!sns_ctl.sns_workqueue) {
- - pr_err("%s: Failed to create work queue\n",
- - __func__);
- - goto cdev_add_err;
- - }
- -
- - sns_ctl.smd_wq =
- - alloc_workqueue("smd_wq", WQ_NON_REENTRANT, 0);
- - if (!sns_ctl.smd_wq) {
- - pr_err("%s: Failed to create work queue\n",
- - __func__);
- - goto cdev_add_err;
- - }
- -
- - init_waitqueue_head(&sns_ctl.sns_wait);
- - spin_lock_init(&sns_ctl.sns_lock);
- -
- - sns_ctl.ocmem_handle = NULL;
- - sns_ctl.buf = NULL;
- - sns_ctl.sns_ocmem_status = 0;
- - sns_ctl.ocmem_enabled = true;
- - sns_ctl.ocmem_nb.notifier_call = sns_ocmem_drv_cb;
- - sns_ctl.smd_ch = NULL;
- - sns_ctl.pdev = pdev;
- -
- - INIT_WORK(&sns_ctl.sns_work, sns_ocmem_main);
- - INIT_WORK(&sns_ctl.smd_read_work, sns_ocmem_smd_read);
- -
- - queue_work(sns_ctl.sns_workqueue, &sns_ctl.sns_work);
- -
- return 0;
- cdev_add_err:
- @@ -1186,20 +146,6 @@ res_err:
- static int sensors_adsp_remove(struct platform_device *pdev)
- {
- - struct msm_bus_scale_pdata *sns_ocmem_bus_scale_pdata = NULL;
- -
- - sns_ocmem_bus_scale_pdata = (struct msm_bus_scale_pdata *)
- - dev_get_drvdata(&pdev->dev);
- -
- - kfree(sns_ocmem_bus_scale_pdata->usecase->vectors);
- - kfree(sns_ocmem_bus_scale_pdata->usecase);
- - kfree(sns_ocmem_bus_scale_pdata);
- -
- - ocmem_notifier_unregister(sns_ctl.ocmem_handle,
- - &sns_ctl.ocmem_nb);
- - destroy_workqueue(sns_ctl.sns_workqueue);
- - destroy_workqueue(sns_ctl.smd_wq);
- -
- cdev_del(sns_ctl.cdev);
- kfree(sns_ctl.cdev);
- sns_ctl.cdev = NULL;
- @@ -1211,12 +157,10 @@ static int sensors_adsp_remove(struct platform_device *pdev)
- }
- static const struct of_device_id msm_adsp_sensors_dt_match[] = {
- - {.compatible = "qcom,msm-adsp-sensors"},
- - {}
- + {.compatible = "qcom,msm-adsp-sensors"}
- };
- MODULE_DEVICE_TABLE(of, msm_adsp_sensors_dt_match);
- -
- static struct platform_driver sensors_adsp_driver = {
- .driver = {
- .name = "sensors-adsp",
- @@ -1227,16 +171,12 @@ static struct platform_driver sensors_adsp_driver = {
- .remove = sensors_adsp_remove,
- };
- -/*
- - * Module Init.
- - */
- -static int sensors_adsp_init(void)
- +static int __init sensors_adsp_init(void)
- {
- int rc;
- - pr_debug("%s driver version %s.\n", DRV_NAME, DRV_VERSION);
- + pr_debug("%s driver version %s.\n", DRV_NAME, DRV_VERSION);
- rc = platform_driver_register(&sensors_adsp_driver);
- -
- if (rc) {
- pr_err("%s: Failed to register sensors adsp driver\n",
- __func__);
- @@ -1246,16 +186,12 @@ static int sensors_adsp_init(void)
- return 0;
- }
- -/*
- - * Module Exit.
- - */
- -static void sensors_adsp_exit(void)
- +static void __exit sensors_adsp_exit(void)
- {
- platform_driver_unregister(&sensors_adsp_driver);
- }
- module_init(sensors_adsp_init);
- module_exit(sensors_adsp_exit);
- -
- MODULE_LICENSE("GPL v2");
- MODULE_DESCRIPTION("Sensors ADSP driver");
- diff --git a/arch/arm/mach-msm/smd_init_dt.c b/arch/arm/mach-msm/smd_init_dt.c
- index 640656c..1766a68 100644
- --- a/arch/arm/mach-msm/smd_init_dt.c
- +++ b/arch/arm/mach-msm/smd_init_dt.c
- @@ -126,7 +126,7 @@ static int msm_smsm_probe(struct platform_device *pdev)
- ret = request_irq(irq_line,
- private_irq->irq_handler,
- - IRQF_TRIGGER_RISING,
- + IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
- "smsm_dev",
- NULL);
- if (ret < 0) {
- @@ -160,7 +160,6 @@ static int msm_smd_probe(struct platform_device *pdev)
- uint32_t irq_offset;
- uint32_t irq_bitmask;
- uint32_t irq_line;
- - unsigned long irq_flags = IRQF_TRIGGER_RISING;
- const char *pilstr;
- struct interrupt_config_item *private_irq;
- struct device_node *node;
- @@ -222,11 +221,6 @@ static int msm_smd_probe(struct platform_device *pdev)
- if (pilstr)
- SMD_DBG("%s: %s = %s", __func__, key, pilstr);
- - key = "qcom,irq-no-suspend";
- - ret = of_property_read_bool(node, key);
- - if (ret)
- - irq_flags |= IRQF_NO_SUSPEND;
- -
- private_intr_config = smd_get_intr_config(edge);
- if (!private_intr_config) {
- pr_err("%s: invalid edge\n", __func__);
- @@ -242,7 +236,7 @@ static int msm_smd_probe(struct platform_device *pdev)
- ret = request_irq(irq_line,
- private_irq->irq_handler,
- - irq_flags,
- + IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
- "smd_dev",
- NULL);
- if (ret < 0) {
- diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
- index ff68d81..931ed58 100644
- --- a/arch/arm/mach-msm/smd_rpcrouter.c
- +++ b/arch/arm/mach-msm/smd_rpcrouter.c
- @@ -1,7 +1,7 @@
- /* arch/arm/mach-msm/smd_rpcrouter.c
- *
- * Copyright (C) 2007 Google, Inc.
- - * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
- + * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
- * Author: San Mehat <[email protected]>
- *
- * This software is licensed under the terms of the GNU General Public
- @@ -646,7 +646,7 @@ struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev)
- int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept)
- {
- int rc;
- - union rr_control_msg msg;
- + union rr_control_msg msg = { 0 };
- struct msm_rpc_reply *reply, *reply_tmp;
- unsigned long flags;
- struct rpcrouter_xprt_info *xprt_info;
- @@ -781,7 +781,7 @@ static void handle_server_restart(struct rr_server *server,
- static int process_control_msg(struct rpcrouter_xprt_info *xprt_info,
- union rr_control_msg *msg, int len)
- {
- - union rr_control_msg ctl;
- + union rr_control_msg ctl = { 0 };
- struct rr_server *server;
- struct rr_remote_endpoint *r_ept;
- int rc = 0;
- @@ -1212,7 +1212,7 @@ packet_complete:
- done:
- if (hdr.confirm_rx) {
- - union rr_control_msg msg;
- + union rr_control_msg msg = { 0 };
- msg.cmd = RPCROUTER_CTRL_CMD_RESUME_TX;
- msg.cli.pid = hdr.dst_pid;
- @@ -2071,7 +2071,7 @@ int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
- uint32_t prog, uint32_t vers)
- {
- int rc;
- - union rr_control_msg msg;
- + union rr_control_msg msg = { 0 };
- struct rr_server *server;
- struct rpcrouter_xprt_info *xprt_info;
- @@ -2152,7 +2152,7 @@ int msm_rpc_get_curr_pkt_size(struct msm_rpc_endpoint *ept)
- static int msm_rpcrouter_close(void)
- {
- struct rpcrouter_xprt_info *xprt_info;
- - union rr_control_msg ctl;
- + union rr_control_msg ctl = { 0 };
- ctl.cmd = RPCROUTER_CTRL_CMD_BYE;
- mutex_lock(&xprt_info_list_lock);
- diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
- index c1a9784..72156bb 100644
- --- a/arch/arm/vfp/entry.S
- +++ b/arch/arm/vfp/entry.S
- @@ -25,7 +25,6 @@ ENTRY(do_vfp)
- add r11, r4, #1 @ increment it
- str r11, [r10, #TI_PREEMPT]
- #endif
- - enable_irq
- str r2, [sp, #S_PC] @ update regs->ARM_pc for Thumb 2 case
- ldr r4, .LCvfp
- ldr r11, [r10, #TI_CPU] @ CPU number
- diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
- index 0857a5f..871864f 100644
- --- a/drivers/char/adsprpc.c
- +++ b/drivers/char/adsprpc.c
- @@ -43,7 +43,6 @@
- #define RPC_HASH_BITS 5
- #define RPC_HASH_SZ (1 << RPC_HASH_BITS)
- #define BALIGN 32
- -#define NUM_CHANNELS 1
- #define LOCK_MMAP(kernel)\
- do {\
- @@ -140,16 +139,15 @@ struct smq_invoke_ctx {
- struct hlist_node hn;
- struct completion work;
- int retval;
- - int cid;
- int pid;
- remote_arg_t *pra;
- remote_arg_t *rpra;
- struct fastrpc_buf obuf;
- struct fastrpc_buf *abufs;
- struct fastrpc_device *dev;
- - struct fastrpc_apps *apps;
- - int* fds;
- - struct ion_handle** handles;
- + struct fastrpc_apps *apps;
- + int *fds;
- + struct ion_handle **handles;
- int nbufs;
- bool smmu;
- uint32_t sc;
- @@ -168,24 +166,20 @@ struct fastrpc_smmu {
- bool enabled;
- };
- -struct fastrpc_channel_context {
- - smd_channel_t *chan;
- - struct device *dev;
- - struct completion work;
- - struct fastrpc_smmu smmu;
- - struct kref kref;
- -};
- -
- struct fastrpc_apps {
- - struct fastrpc_channel_context channel[NUM_CHANNELS];
- + smd_channel_t *chan;
- struct smq_context_list clst;
- + struct completion work;
- struct ion_client *iclient;
- struct cdev cdev;
- struct class *class;
- + struct device *dev;
- + struct fastrpc_smmu smmu;
- struct mutex smd_mutex;
- dev_t dev_no;
- spinlock_t wrlock;
- spinlock_t hlock;
- + struct kref kref;
- struct hlist_head htbl[RPC_HASH_SZ];
- };
- @@ -203,7 +197,6 @@ struct file_data {
- spinlock_t hlock;
- struct hlist_head hlst;
- uint32_t mode;
- - int cid;
- };
- struct fastrpc_device {
- @@ -212,32 +205,16 @@ struct fastrpc_device {
- struct fastrpc_buf buf;
- };
- -struct fastrpc_channel_info {
- - char *name;
- - char *node;
- - char *group;
- - int channel;
- -};
- -
- static struct fastrpc_apps gfa;
- -static const struct fastrpc_channel_info gcinfo[NUM_CHANNELS] = {
- - {
- - .name = "adsprpc-smd",
- - .node = "qcom,msm-audio-ion",
- - .group = "lpass_audio",
- - .channel = SMD_APPS_QDSP,
- - }
- -};
- -
- -static void free_mem(struct fastrpc_buf *buf, int cid)
- +static void free_mem(struct fastrpc_buf *buf)
- {
- struct fastrpc_apps *me = &gfa;
- if (!IS_ERR_OR_NULL(buf->handle)) {
- - if (me->channel[cid].smmu.enabled && buf->phys) {
- + if (me->smmu.enabled && buf->phys) {
- ion_unmap_iommu(me->iclient, buf->handle,
- - me->channel[cid].smmu.domain_id, 0);
- + me->smmu.domain_id, 0);
- buf->phys = 0;
- }
- if (!IS_ERR_OR_NULL(buf->virt)) {
- @@ -249,13 +226,13 @@ static void free_mem(struct fastrpc_buf *buf, int cid)
- }
- }
- -static void free_map(struct fastrpc_mmap *map, int cid)
- +static void free_map(struct fastrpc_mmap *map)
- {
- struct fastrpc_apps *me = &gfa;
- if (!IS_ERR_OR_NULL(map->handle)) {
- - if (me->channel[cid].smmu.enabled && map->phys) {
- + if (me->smmu.enabled && map->phys) {
- ion_unmap_iommu(me->iclient, map->handle,
- - me->channel[cid].smmu.domain_id, 0);
- + me->smmu.domain_id, 0);
- map->phys = 0;
- }
- if (!IS_ERR_OR_NULL(map->virt)) {
- @@ -267,7 +244,7 @@ static void free_map(struct fastrpc_mmap *map, int cid)
- map->handle = 0;
- }
- -static int alloc_mem(struct fastrpc_buf *buf, int cid)
- +static int alloc_mem(struct fastrpc_buf *buf)
- {
- struct fastrpc_apps *me = &gfa;
- struct ion_client *clnt = gfa.iclient;
- @@ -278,7 +255,7 @@ static int alloc_mem(struct fastrpc_buf *buf, int cid)
- buf->handle = 0;
- buf->virt = 0;
- buf->phys = 0;
- - heap = me->channel[cid].smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
- + heap = me->smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
- ION_HEAP(ION_ADSP_HEAP_ID) | ION_HEAP(ION_AUDIO_HEAP_ID);
- buf->handle = ion_alloc(clnt, buf->size, SZ_4K, heap, ION_FLAG_CACHED);
- VERIFY(err, 0 == IS_ERR_OR_NULL(buf->handle));
- @@ -288,11 +265,11 @@ static int alloc_mem(struct fastrpc_buf *buf, int cid)
- VERIFY(err, 0 == IS_ERR_OR_NULL(buf->virt));
- if (err)
- goto bail;
- - if (me->channel[cid].smmu.enabled) {
- + if (me->smmu.enabled) {
- len = buf->size;
- VERIFY(err, 0 == ion_map_iommu(clnt, buf->handle,
- - me->channel[cid].smmu.domain_id, 0,
- - SZ_4K, 0, &buf->phys, &len, 0, 0));
- + me->smmu.domain_id, 0, SZ_4K, 0,
- + &buf->phys, &len, 0, 0));
- if (err)
- goto bail;
- } else {
- @@ -303,35 +280,13 @@ static int alloc_mem(struct fastrpc_buf *buf, int cid)
- }
- bail:
- if (err && !IS_ERR_OR_NULL(buf->handle))
- - free_mem(buf, cid);
- + free_mem(buf);
- return err;
- }
- -static void context_list_ctor(struct smq_context_list *me)
- -{
- - INIT_HLIST_HEAD(&me->interrupted);
- - INIT_HLIST_HEAD(&me->pending);
- - spin_lock_init(&me->hlock);
- -}
- -
- -static void context_free(struct smq_invoke_ctx *ctx, bool lock);
- -
- -static void context_list_dtor(struct fastrpc_apps *me, struct smq_context_list *clst) {
- - struct smq_invoke_ctx *ictx = 0;
- - struct hlist_node *pos, *n;
- - spin_lock(&clst->hlock);
- - hlist_for_each_entry_safe(ictx, pos, n, &clst->interrupted, hn) {
- - context_free(ictx, 0);
- - }
- - hlist_for_each_entry_safe(ictx, pos, n, &clst->pending, hn) {
- - context_free(ictx, 0);
- - }
- - spin_unlock(&clst->hlock);
- -}
- -
- static int context_restore_interrupted(struct fastrpc_apps *me,
- struct fastrpc_ioctl_invoke_fd *invokefd,
- - int cid, struct smq_invoke_ctx **po)
- + struct smq_invoke_ctx **po)
- {
- int err = 0;
- struct smq_invoke_ctx *ctx = 0, *ictx = 0;
- @@ -339,8 +294,8 @@ static int context_restore_interrupted(struct fastrpc_apps *me,
- struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
- spin_lock(&me->clst.hlock);
- hlist_for_each_entry_safe(ictx, pos, n, &me->clst.interrupted, hn) {
- - if(ictx->pid == current->pid) {
- - if(invoke->sc != ictx->sc || ictx->cid != cid)
- + if (ictx->pid == current->pid) {
- + if (invoke->sc != ictx->sc)
- err = -1;
- else {
- ctx = ictx;
- @@ -351,15 +306,13 @@ static int context_restore_interrupted(struct fastrpc_apps *me,
- }
- }
- spin_unlock(&me->clst.hlock);
- - if(ctx) {
- + if (ctx)
- *po = ctx;
- - }
- return err;
- }
- static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
- struct fastrpc_ioctl_invoke_fd *invokefd,
- - int cid,
- struct smq_invoke_ctx **po)
- {
- int err = 0, bufs, size = 0;
- @@ -381,10 +334,10 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
- goto bail;
- INIT_HLIST_NODE(&ctx->hn);
- - ctx->pra = (remote_arg_t*)(&ctx[1]);
- - ctx->fds = invokefd->fds == 0 ? 0 : (int*)(&ctx->pra[bufs]);
- - ctx->handles = invokefd->fds == 0 ? 0 : (struct ion_handle**)(&ctx->fds[bufs]);
- -
- + ctx->pra = (remote_arg_t *)(&ctx[1]);
- + ctx->fds = invokefd->fds == 0 ? 0 : (int *)(&ctx->pra[bufs]);
- + ctx->handles = invokefd->fds == 0 ? 0 :
- + (struct ion_handle **)(&ctx->fds[bufs]);
- if (!kernel) {
- VERIFY(err, 0 == copy_from_user(ctx->pra, invoke->pra,
- bufs * sizeof(*ctx->pra)));
- @@ -407,7 +360,6 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
- }
- ctx->sc = invoke->sc;
- ctx->retval = -1;
- - ctx->cid = cid;
- ctx->pid = current->pid;
- ctx->apps = me;
- init_completion(&ctx->work);
- @@ -417,7 +369,7 @@ static int context_alloc(struct fastrpc_apps *me, uint32_t kernel,
- *po = ctx;
- bail:
- - if(ctx && err)
- + if (ctx && err)
- kfree(ctx);
- return err;
- }
- @@ -436,72 +388,93 @@ static void add_dev(struct fastrpc_apps *me, struct fastrpc_device *dev);
- static void context_free(struct smq_invoke_ctx *ctx, bool lock)
- {
- struct smq_context_list *clst = &ctx->apps->clst;
- - struct fastrpc_apps *apps = ctx->apps;
- + struct fastrpc_apps *apps = ctx->apps;
- + struct ion_client *clnt = apps->iclient;
- + struct fastrpc_smmu *smmu = &apps->smmu;
- struct fastrpc_buf *b;
- int i, bufs;
- if (ctx->smmu) {
- - bufs = REMOTE_SCALARS_INBUFS(ctx->sc) + REMOTE_SCALARS_OUTBUFS(ctx->sc);
- + bufs = REMOTE_SCALARS_INBUFS(ctx->sc) +
- + REMOTE_SCALARS_OUTBUFS(ctx->sc);
- if (ctx->fds) {
- for (i = 0; i < bufs; i++)
- if (!IS_ERR_OR_NULL(ctx->handles[i])) {
- - ion_unmap_iommu(apps->iclient, ctx->handles[i],
- - apps->channel[ctx->cid].smmu.domain_id,
- - 0);
- - ion_free(apps->iclient, ctx->handles[i]);
- + ion_unmap_iommu(clnt, ctx->handles[i],
- + smmu->domain_id, 0);
- + ion_free(clnt, ctx->handles[i]);
- }
- }
- - iommu_detach_group(apps->channel[ctx->cid].smmu.domain,
- - apps->channel[ctx->cid].smmu.group);
- + iommu_detach_group(smmu->domain, smmu->group);
- }
- for (i = 0, b = ctx->abufs; i < ctx->nbufs; ++i, ++b)
- - free_mem(b, ctx->cid);
- -
- + free_mem(b);
- +
- kfree(ctx->abufs);
- if (ctx->dev) {
- add_dev(apps, ctx->dev);
- if (ctx->obuf.handle != ctx->dev->buf.handle)
- - free_mem(&ctx->obuf, ctx->cid);
- + free_mem(&ctx->obuf);
- }
- - if(lock) {
- + if (lock)
- spin_lock(&clst->hlock);
- - }
- hlist_del(&ctx->hn);
- - if(lock) {
- + if (lock)
- spin_unlock(&clst->hlock);
- - }
- kfree(ctx);
- }
- -static void context_notify_user(struct smq_invoke_ctx *me, int retval)
- +static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
- {
- - me->retval = retval;
- - complete(&me->work);
- + ctx->retval = retval;
- + complete(&ctx->work);
- }
- -static void context_notify_all_users(struct smq_context_list *me, int cid)
- +static void context_notify_all_users(struct smq_context_list *me)
- {
- struct smq_invoke_ctx *ictx = 0;
- struct hlist_node *pos, *n;
- spin_lock(&me->hlock);
- hlist_for_each_entry_safe(ictx, pos, n, &me->pending, hn) {
- - if(ictx->cid == cid) {
- - complete(&ictx->work);
- - }
- + complete(&ictx->work);
- }
- hlist_for_each_entry_safe(ictx, pos, n, &me->interrupted, hn) {
- - if(ictx->cid == cid) {
- - complete(&ictx->work);
- - }
- + complete(&ictx->work);
- }
- spin_unlock(&me->hlock);
- }
- -static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- - struct fastrpc_buf *ibuf, struct fastrpc_buf *obuf, int cid)
- +static void context_list_ctor(struct smq_context_list *me)
- {
- + INIT_HLIST_HEAD(&me->interrupted);
- + INIT_HLIST_HEAD(&me->pending);
- + spin_lock_init(&me->hlock);
- +}
- +
- +static void context_list_dtor(struct fastrpc_apps *me,
- + struct smq_context_list *clst)
- +{
- + struct smq_invoke_ctx *ictx = 0;
- + struct hlist_node *pos, *n;
- + spin_lock(&clst->hlock);
- + hlist_for_each_entry_safe(ictx, pos, n, &clst->interrupted, hn) {
- + context_free(ictx, 0);
- + }
- + hlist_for_each_entry_safe(ictx, pos, n, &clst->pending, hn) {
- + context_free(ictx, 0);
- + }
- + spin_unlock(&clst->hlock);
- +}
- +
- +static int get_page_list(uint32_t kernel, struct smq_invoke_ctx *ctx)
- +{
- + struct fastrpc_apps *me = &gfa;
- struct smq_phy_page *pgstart, *pages;
- struct smq_invoke_buf *list;
- + struct fastrpc_buf *ibuf = &ctx->dev->buf;
- + struct fastrpc_buf *obuf = &ctx->obuf;
- + remote_arg_t *pra = ctx->pra;
- + uint32_t sc = ctx->sc;
- int i, rlen, err = 0;
- int inbufs = REMOTE_SCALARS_INBUFS(sc);
- int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
- @@ -516,7 +489,7 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- if (rlen < 0) {
- rlen = ((uint32_t)pages - (uint32_t)obuf->virt) - obuf->size;
- obuf->size += buf_page_size(rlen);
- - VERIFY(err, 0 == alloc_mem(obuf, cid));
- + VERIFY(err, 0 == alloc_mem(obuf));
- if (err)
- goto bail;
- goto retry;
- @@ -537,11 +510,21 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- continue;
- buf = pra[i].buf.pv;
- num = buf_num_pages(buf, len);
- - if (!kernel)
- - list[i].num = buf_get_pages(buf, len, num,
- - i >= inbufs, pages, rlen / sizeof(*pages));
- - else
- - list[i].num = 0;
- + if (!kernel) {
- + if (me->smmu.enabled) {
- + VERIFY(err, 0 != access_ok(i >= inbufs ?
- + VERIFY_WRITE : VERIFY_READ,
- + (void __user *)buf, len));
- + if (err)
- + goto bail;
- + if (ctx->fds && (ctx->fds[i] >= 0))
- + list[i].num = 1;
- + } else {
- + list[i].num = buf_get_pages(buf, len, num,
- + i >= inbufs, pages,
- + rlen / sizeof(*pages));
- + }
- + }
- VERIFY(err, list[i].num >= 0);
- if (err)
- goto bail;
- @@ -553,9 +536,9 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- pages = pages + 1;
- } else {
- if (obuf->handle != ibuf->handle)
- - free_mem(obuf, cid);
- + free_mem(obuf);
- obuf->size += buf_page_size(sizeof(*pages));
- - VERIFY(err, 0 == alloc_mem(obuf, cid));
- + VERIFY(err, 0 == alloc_mem(obuf));
- if (err)
- goto bail;
- goto retry;
- @@ -565,24 +548,28 @@ static int get_page_list(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- obuf->used = obuf->size - rlen;
- bail:
- if (err && (obuf->handle != ibuf->handle))
- - free_mem(obuf, cid);
- + free_mem(obuf);
- UNLOCK_MMAP(kernel);
- return err;
- }
- -static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- - remote_arg_t *rpra, remote_arg_t *upra,
- - struct fastrpc_buf *ibuf, struct fastrpc_buf **abufs,
- - int *nbufs, int *fds, struct ion_handle **handles, int cid)
- +static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
- + remote_arg_t *upra)
- {
- struct fastrpc_apps *me = &gfa;
- struct smq_invoke_buf *list;
- - struct fastrpc_buf *pbuf = ibuf, *obufs = 0;
- + struct fastrpc_buf *pbuf = &ctx->obuf, *obufs = 0;
- struct smq_phy_page *pages;
- + struct vm_area_struct *vma;
- + struct ion_handle **handles = ctx->handles;
- void *args;
- + remote_arg_t *pra = ctx->pra;
- + remote_arg_t *rpra = ctx->rpra;
- + uint32_t sc = ctx->sc, start;
- int i, rlen, size, used, inh, bufs = 0, err = 0;
- int inbufs = REMOTE_SCALARS_INBUFS(sc);
- int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
- + int *fds = ctx->fds, idx, num;
- unsigned long len;
- ion_phys_addr_t iova;
- @@ -596,21 +583,29 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- rpra[i].buf.len = pra[i].buf.len;
- if (!rpra[i].buf.len)
- continue;
- - if (me->channel[cid].smmu.enabled && fds && (fds[i] >= 0)) {
- + if (me->smmu.enabled && fds && (fds[i] >= 0)) {
- + start = buf_page_start(pra[i].buf.pv);
- len = buf_page_size(pra[i].buf.len);
- + num = buf_num_pages(pra[i].buf.pv, pra[i].buf.len);
- + idx = list[i].pgidx;
- handles[i] = ion_import_dma_buf(me->iclient, fds[i]);
- VERIFY(err, 0 == IS_ERR_OR_NULL(handles[i]));
- if (err)
- goto bail;
- VERIFY(err, 0 == ion_map_iommu(me->iclient, handles[i],
- - me->channel[cid].smmu.domain_id,
- - 0, SZ_4K, 0, &iova, &len, 0, 0));
- + me->smmu.domain_id, 0, SZ_4K, 0,
- + &iova, &len, 0, 0));
- + if (err)
- + goto bail;
- + VERIFY(err, (num << PAGE_SHIFT) <= len);
- + if (err)
- + goto bail;
- + VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
- if (err)
- goto bail;
- rpra[i].buf.pv = pra[i].buf.pv;
- - list[i].num = 1;
- - pages[list[i].pgidx].addr = iova;
- - pages[list[i].pgidx].size = len;
- + pages[idx].addr = iova + (start - vma->vm_start);
- + pages[idx].size = num << PAGE_SHIFT;
- continue;
- } else if (list[i].num) {
- rpra[i].buf.pv = pra[i].buf.pv;
- @@ -627,7 +622,7 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- pbuf = obufs + bufs;
- pbuf->size = buf_num_pages(0, pra[i].buf.len) *
- PAGE_SIZE;
- - VERIFY(err, 0 == alloc_mem(pbuf, cid));
- + VERIFY(err, 0 == alloc_mem(pbuf));
- if (err)
- goto bail;
- bufs++;
- @@ -636,7 +631,7 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- }
- list[i].num = 1;
- pages[list[i].pgidx].addr =
- - buf_page_start((void *)((uint32_t)pbuf->phys +
- + buf_page_start((void *)(pbuf->phys +
- (pbuf->size - rlen)));
- pages[list[i].pgidx].size =
- buf_page_size(pra[i].buf.len);
- @@ -674,8 +669,8 @@ static int get_args(uint32_t kernel, uint32_t sc, remote_arg_t *pra,
- }
- dmac_flush_range(rpra, (char *)rpra + used);
- bail:
- - *abufs = obufs;
- - *nbufs = bufs;
- + ctx->abufs = obufs;
- + ctx->nbufs = bufs;
- return err;
- }
- @@ -774,7 +769,7 @@ static int fastrpc_invoke_send(struct fastrpc_apps *me,
- msg.invoke.page.addr = buf->phys;
- msg.invoke.page.size = buf_page_size(buf->used);
- spin_lock(&me->wrlock);
- - len = smd_write(me->channel[ctx->cid].chan, &msg, sizeof(msg));
- + len = smd_write(me->chan, &msg, sizeof(msg));
- spin_unlock(&me->wrlock);
- VERIFY(err, len == sizeof(msg));
- return err;
- @@ -783,28 +778,22 @@ static int fastrpc_invoke_send(struct fastrpc_apps *me,
- static void fastrpc_deinit(void)
- {
- struct fastrpc_apps *me = &gfa;
- - int i;
- - for (i = 0; i < NUM_CHANNELS; i++) {
- - if (me->channel[i].chan) {
- - (void)smd_close(me->channel[i].chan);
- - me->channel[i].chan = 0;
- - }
- - }
- + smd_close(me->chan);
- ion_client_destroy(me->iclient);
- me->iclient = 0;
- + me->chan = 0;
- }
- -static void fastrpc_read_handler(int cid)
- +static void fastrpc_read_handler(void)
- {
- struct fastrpc_apps *me = &gfa;
- struct smq_invoke_rsp rsp;
- int err = 0;
- do {
- - VERIFY(err, sizeof(rsp) == smd_read_from_cb(
- - me->channel[cid].chan,
- - &rsp, sizeof(rsp)));
- + VERIFY(err, sizeof(rsp) ==
- + smd_read_from_cb(me->chan, &rsp, sizeof(rsp)));
- if (err)
- goto bail;
- context_notify_user(rsp.ctx, rsp.retval);
- @@ -815,76 +804,76 @@ static void fastrpc_read_handler(int cid)
- static void smd_event_handler(void *priv, unsigned event)
- {
- - struct fastrpc_apps *me = &gfa;
- - int cid = (int)priv;
- + struct fastrpc_apps *me = (struct fastrpc_apps *)priv;
- switch (event) {
- case SMD_EVENT_OPEN:
- - complete(&me->channel[cid].work);
- + complete(&(me->work));
- break;
- case SMD_EVENT_CLOSE:
- - context_notify_all_users(&me->clst, cid);
- + context_notify_all_users(&me->clst);
- break;
- case SMD_EVENT_DATA:
- - fastrpc_read_handler(cid);
- + fastrpc_read_handler();
- break;
- }
- }
- static int fastrpc_init(void)
- {
- - int i, err = 0;
- + int err = 0;
- struct fastrpc_apps *me = &gfa;
- struct device_node *node;
- - struct fastrpc_smmu *smmu;
- bool enabled = 0;
- - spin_lock_init(&me->hlock);
- - spin_lock_init(&me->wrlock);
- - mutex_init(&me->smd_mutex);
- - context_list_ctor(&me->clst);
- - for (i = 0; i < RPC_HASH_SZ; ++i)
- - INIT_HLIST_HEAD(&me->htbl[i]);
- - me->iclient = msm_ion_client_create(ION_HEAP_CARVEOUT_MASK,
- - DEVICE_NAME);
- - VERIFY(err, 0 == IS_ERR_OR_NULL(me->iclient));
- - if (err)
- - goto bail;
- - for (i = 0; i < NUM_CHANNELS; i++) {
- - init_completion(&me->channel[i].work);
- - if (!gcinfo[i].node)
- - continue;
- - smmu = &me->channel[i].smmu;
- - node = of_find_compatible_node(NULL, NULL, gcinfo[i].node);
- + if (me->chan == 0) {
- + int i;
- + spin_lock_init(&me->hlock);
- + spin_lock_init(&me->wrlock);
- + init_completion(&me->work);
- + mutex_init(&me->smd_mutex);
- + context_list_ctor(&me->clst);
- + for (i = 0; i < RPC_HASH_SZ; ++i)
- + INIT_HLIST_HEAD(&me->htbl[i]);
- + me->iclient = msm_ion_client_create(ION_HEAP_CARVEOUT_MASK,
- + DEVICE_NAME);
- + VERIFY(err, 0 == IS_ERR_OR_NULL(me->iclient));
- + if (err)
- + goto bail;
- + node = of_find_compatible_node(NULL, NULL,
- + "qcom,msm-audio-ion");
- if (node)
- enabled = of_property_read_bool(node,
- "qcom,smmu-enabled");
- if (enabled)
- - smmu->group = iommu_group_find(gcinfo[i].group);
- - if (smmu->group)
- - smmu->domain = iommu_group_get_iommudata(smmu->group);
- - if (!IS_ERR_OR_NULL(smmu->domain)) {
- - smmu->domain_id = msm_find_domain_no(smmu->domain);
- - if (smmu->domain_id >= 0)
- - smmu->enabled = enabled;
- + me->smmu.group = iommu_group_find("lpass_audio");
- + if (me->smmu.group)
- + me->smmu.domain = iommu_group_get_iommudata(
- + me->smmu.group);
- + if (!IS_ERR_OR_NULL(me->smmu.domain)) {
- + me->smmu.domain_id = msm_find_domain_no(
- + me->smmu.domain);
- + if (me->smmu.domain_id >= 0)
- + me->smmu.enabled = enabled;
- }
- }
- +
- return 0;
- bail:
- return err;
- }
- -static void free_dev(struct fastrpc_device *dev, int cid)
- +static void free_dev(struct fastrpc_device *dev)
- {
- if (dev) {
- - free_mem(&dev->buf, cid);
- + free_mem(&dev->buf);
- kfree(dev);
- module_put(THIS_MODULE);
- }
- }
- -static int alloc_dev(struct fastrpc_device **dev, int cid)
- +static int alloc_dev(struct fastrpc_device **dev)
- {
- int err = 0;
- struct fastrpc_device *fd = 0;
- @@ -899,7 +888,7 @@ static int alloc_dev(struct fastrpc_device **dev, int cid)
- INIT_HLIST_NODE(&fd->hn);
- fd->buf.size = PAGE_SIZE;
- - VERIFY(err, 0 == alloc_mem(&fd->buf, cid));
- + VERIFY(err, 0 == alloc_mem(&fd->buf));
- if (err)
- goto bail;
- fd->tgid = current->tgid;
- @@ -907,12 +896,11 @@ static int alloc_dev(struct fastrpc_device **dev, int cid)
- *dev = fd;
- bail:
- if (err)
- - free_dev(fd, cid);
- + free_dev(fd);
- return err;
- }
- -static int get_dev(struct fastrpc_apps *me, int cid,
- - struct fastrpc_device **rdev)
- +static int get_dev(struct fastrpc_apps *me, struct fastrpc_device **rdev)
- {
- struct hlist_head *head;
- struct fastrpc_device *dev = 0, *devfree = 0;
- @@ -936,8 +924,8 @@ static int get_dev(struct fastrpc_apps *me, int cid,
- *rdev = devfree;
- bail:
- if (err) {
- - free_dev(devfree, cid);
- - err = alloc_dev(rdev, cid);
- + free_dev(devfree);
- + err = alloc_dev(rdev);
- }
- return err;
- }
- @@ -954,48 +942,46 @@ static void add_dev(struct fastrpc_apps *me, struct fastrpc_device *dev)
- return;
- }
- -static int fastrpc_release_current_dsp_process(int cid);
- +static int fastrpc_release_current_dsp_process(void);
- static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
- - uint32_t kernel, struct fastrpc_ioctl_invoke_fd *invokefd,
- - int cid)
- + uint32_t kernel,
- + struct fastrpc_ioctl_invoke_fd *invokefd)
- {
- struct smq_invoke_ctx *ctx = 0;
- struct fastrpc_ioctl_invoke *invoke = &invokefd->inv;
- int interrupted = 0;
- int err = 0;
- - if(!kernel) {
- - VERIFY(err, 0 == context_restore_interrupted(me, invokefd, cid, &ctx));
- + if (!kernel) {
- + VERIFY(err, 0 == context_restore_interrupted(me, invokefd,
- + &ctx));
- if (err)
- goto bail;
- - if(ctx)
- + if (ctx)
- goto wait;
- }
- - VERIFY(err, 0 == context_alloc(me, kernel, invokefd, cid, &ctx));
- + VERIFY(err, 0 == context_alloc(me, kernel, invokefd, &ctx));
- if (err)
- goto bail;
- - if (me->channel[cid].smmu.enabled) {
- - VERIFY(err, 0 == iommu_attach_group(
- - me->channel[cid].smmu.domain,
- - me->channel[cid].smmu.group));
- + if (me->smmu.enabled) {
- + VERIFY(err, 0 == iommu_attach_group(me->smmu.domain,
- + me->smmu.group));
- if (err)
- goto bail;
- ctx->smmu = 1;
- }
- if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
- - VERIFY(err, 0 == get_dev(me, cid, &ctx->dev));
- + VERIFY(err, 0 == get_dev(me, &ctx->dev));
- if (err)
- goto bail;
- - VERIFY(err, 0 == get_page_list(kernel, ctx->sc, ctx->pra, &ctx->dev->buf,
- - &ctx->obuf, cid));
- + VERIFY(err, 0 == get_page_list(kernel, ctx));
- if (err)
- goto bail;
- ctx->rpra = (remote_arg_t *)ctx->obuf.virt;
- - VERIFY(err, 0 == get_args(kernel, ctx->sc, ctx->pra, ctx->rpra, invoke->pra,
- - &ctx->obuf, &ctx->abufs, &ctx->nbufs, ctx->fds, ctx->handles, cid));
- + VERIFY(err, 0 == get_args(kernel, ctx, invoke->pra));
- if (err)
- goto bail;
- }
- @@ -1003,15 +989,15 @@ static int fastrpc_internal_invoke(struct fastrpc_apps *me, uint32_t mode,
- inv_args_pre(ctx->sc, ctx->rpra);
- if (FASTRPC_MODE_SERIAL == mode)
- inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
- - VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle, ctx->sc,
- - ctx, &ctx->obuf));
- + VERIFY(err, 0 == fastrpc_invoke_send(me, kernel, invoke->handle,
- + ctx->sc, ctx, &ctx->obuf));
- if (err)
- goto bail;
- if (FASTRPC_MODE_PARALLEL == mode)
- inv_args(ctx->sc, ctx->rpra, ctx->obuf.used);
- -wait:
- - if(kernel)
- - wait_for_completion(&ctx->work);
- + wait:
- + if (kernel)
- + wait_for_completion(&ctx->work);
- else {
- interrupted = wait_for_completion_interruptible(&ctx->work);
- VERIFY(err, 0 == (err = interrupted));
- @@ -1021,20 +1007,19 @@ wait:
- VERIFY(err, 0 == (err = ctx->retval));
- if (err)
- goto bail;
- - VERIFY(err, 0 == put_args(kernel, ctx->sc, ctx->pra, ctx->rpra, invoke->pra));
- + VERIFY(err, 0 == put_args(kernel, ctx->sc, ctx->pra, ctx->rpra,
- + invoke->pra));
- if (err)
- goto bail;
- bail:
- - if (ctx && interrupted == -ERESTARTSYS) {
- + if (ctx && interrupted == -ERESTARTSYS)
- context_save_interrupted(ctx);
- - err = -ERESTARTSYS;
- - } else if(ctx) {
- + else if (ctx)
- context_free(ctx, 1);
- - }
- return err;
- }
- -static int fastrpc_create_current_dsp_process(int cid)
- +static int fastrpc_create_current_dsp_process(void)
- {
- int err = 0;
- struct fastrpc_ioctl_invoke_fd ioctl;
- @@ -1050,11 +1035,11 @@ static int fastrpc_create_current_dsp_process(int cid)
- ioctl.inv.pra = ra;
- ioctl.fds = 0;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
- - FASTRPC_MODE_PARALLEL, 1, &ioctl, cid)));
- + FASTRPC_MODE_PARALLEL, 1, &ioctl)));
- return err;
- }
- -static int fastrpc_release_current_dsp_process(int cid)
- +static int fastrpc_release_current_dsp_process(void)
- {
- int err = 0;
- struct fastrpc_apps *me = &gfa;
- @@ -1070,14 +1055,14 @@ static int fastrpc_release_current_dsp_process(int cid)
- ioctl.inv.pra = ra;
- ioctl.fds = 0;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
- - FASTRPC_MODE_PARALLEL, 1, &ioctl, cid)));
- + FASTRPC_MODE_PARALLEL, 1, &ioctl)));
- return err;
- }
- static int fastrpc_mmap_on_dsp(struct fastrpc_apps *me,
- struct fastrpc_ioctl_mmap *mmap,
- struct smq_phy_page *pages,
- - int cid, int num)
- + int num)
- {
- struct fastrpc_ioctl_invoke_fd ioctl;
- remote_arg_t ra[3];
- @@ -1110,7 +1095,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_apps *me,
- ioctl.inv.pra = ra;
- ioctl.fds = 0;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
- - FASTRPC_MODE_PARALLEL, 1, &ioctl, cid)));
- + FASTRPC_MODE_PARALLEL, 1, &ioctl)));
- mmap->vaddrout = routargs.vaddrout;
- if (err)
- goto bail;
- @@ -1119,7 +1104,7 @@ bail:
- }
- static int fastrpc_munmap_on_dsp(struct fastrpc_apps *me,
- - struct fastrpc_ioctl_munmap *munmap, int cid)
- + struct fastrpc_ioctl_munmap *munmap)
- {
- struct fastrpc_ioctl_invoke_fd ioctl;
- remote_arg_t ra[1];
- @@ -1141,7 +1126,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_apps *me,
- ioctl.inv.pra = ra;
- ioctl.fds = 0;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me,
- - FASTRPC_MODE_PARALLEL, 1, &ioctl, cid)));
- + FASTRPC_MODE_PARALLEL, 1, &ioctl)));
- return err;
- }
- @@ -1152,13 +1137,13 @@ static int fastrpc_internal_munmap(struct fastrpc_apps *me,
- int err = 0;
- struct fastrpc_mmap *map = 0, *mapfree = 0;
- struct hlist_node *pos, *n;
- - VERIFY(err, 0 == (err = fastrpc_munmap_on_dsp(me, munmap, fdata->cid)));
- + VERIFY(err, 0 == (err = fastrpc_munmap_on_dsp(me, munmap)));
- if (err)
- goto bail;
- spin_lock(&fdata->hlock);
- hlist_for_each_entry_safe(map, pos, n, &fdata->hlst, hn) {
- if (map->vaddrout == munmap->vaddrout &&
- - map->size == munmap->size) {
- + map->size == munmap->size) {
- hlist_del(&map->hn);
- mapfree = map;
- map = 0;
- @@ -1168,7 +1153,7 @@ static int fastrpc_internal_munmap(struct fastrpc_apps *me,
- spin_unlock(&fdata->hlock);
- bail:
- if (mapfree) {
- - free_map(mapfree, fdata->cid);
- + free_map(mapfree);
- kfree(mapfree);
- }
- return err;
- @@ -1182,7 +1167,6 @@ static int fastrpc_internal_mmap(struct fastrpc_apps *me,
- struct ion_client *clnt = gfa.iclient;
- struct fastrpc_mmap *map = 0;
- struct smq_phy_page *pages = 0;
- - struct ion_handle *handles;
- void *buf;
- unsigned long len;
- int num;
- @@ -1206,13 +1190,9 @@ static int fastrpc_internal_mmap(struct fastrpc_apps *me,
- if (err)
- goto bail;
- - if (me->channel[fdata->cid].smmu.enabled) {
- - handles = ion_import_dma_buf(clnt, mmap->fd);
- - VERIFY(err, 0 == IS_ERR_OR_NULL(handles));
- - if (err)
- - goto bail;
- - VERIFY(err, 0 == ion_map_iommu(clnt, handles,
- - me->channel[fdata->cid].smmu.domain_id, 0,
- + if (me->smmu.enabled) {
- + VERIFY(err, 0 == ion_map_iommu(clnt, map->handle,
- + me->smmu.domain_id, 0,
- SZ_4K, 0, &map->phys, &len, 0, 0));
- if (err)
- goto bail;
- @@ -1226,7 +1206,7 @@ static int fastrpc_internal_mmap(struct fastrpc_apps *me,
- goto bail;
- }
- - VERIFY(err, 0 == fastrpc_mmap_on_dsp(me, mmap, pages, fdata->cid, num));
- + VERIFY(err, 0 == fastrpc_mmap_on_dsp(me, mmap, pages, num));
- if (err)
- goto bail;
- map->vaddrin = mmap->vaddrin;
- @@ -1238,14 +1218,14 @@ static int fastrpc_internal_mmap(struct fastrpc_apps *me,
- spin_unlock(&fdata->hlock);
- bail:
- if (err && map) {
- - free_map(map, fdata->cid);
- + free_map(map);
- kfree(map);
- }
- kfree(pages);
- return err;
- }
- -static void cleanup_current_dev(int cid)
- +static void cleanup_current_dev(void)
- {
- struct fastrpc_apps *me = &gfa;
- uint32_t h = hash_32(current->tgid, RPC_HASH_BITS);
- @@ -1266,7 +1246,7 @@ static void cleanup_current_dev(int cid)
- }
- spin_unlock(&me->hlock);
- if (devfree) {
- - free_dev(devfree, cid);
- + free_dev(devfree);
- goto rnext;
- }
- return;
- @@ -1275,37 +1255,32 @@ static void cleanup_current_dev(int cid)
- static void fastrpc_channel_close(struct kref *kref)
- {
- struct fastrpc_apps *me = &gfa;
- - struct fastrpc_channel_context *ctx;
- - int cid;
- - ctx = container_of(kref, struct fastrpc_channel_context, kref);
- - smd_close(ctx->chan);
- - ctx->chan = 0;
- + smd_close(me->chan);
- + me->chan = 0;
- mutex_unlock(&me->smd_mutex);
- - cid = ctx - &me->channel[0];
- - pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
- - MAJOR(me->dev_no), cid);
- + pr_info("'closed /dev/%s c %d 0'\n", DEVICE_NAME,
- + MAJOR(me->dev_no));
- }
- static int fastrpc_device_release(struct inode *inode, struct file *file)
- {
- struct file_data *fdata = (struct file_data *)file->private_data;
- struct fastrpc_apps *me = &gfa;
- - int cid = MINOR(inode->i_rdev);
- - (void)fastrpc_release_current_dsp_process(cid);
- - cleanup_current_dev(cid);
- + (void)fastrpc_release_current_dsp_process();
- + cleanup_current_dev();
- if (fdata) {
- struct fastrpc_mmap *map = 0;
- - struct hlist_node *pos, *n;
- + struct hlist_node *n, *pos;
- file->private_data = 0;
- hlist_for_each_entry_safe(map, pos, n, &fdata->hlst, hn) {
- hlist_del(&map->hn);
- - free_map(map, cid);
- + free_map(map);
- kfree(map);
- }
- kfree(fdata);
- - kref_put_mutex(&me->channel[cid].kref, fastrpc_channel_close,
- + kref_put_mutex(&me->kref, fastrpc_channel_close,
- &me->smd_mutex);
- }
- return 0;
- @@ -1313,27 +1288,23 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
- static int fastrpc_device_open(struct inode *inode, struct file *filp)
- {
- - int cid = MINOR(inode->i_rdev);
- int err = 0;
- struct fastrpc_apps *me = &gfa;
- mutex_lock(&me->smd_mutex);
- - if (kref_get_unless_zero(&me->channel[cid].kref) == 0) {
- - VERIFY(err, 0 == smd_named_open_on_edge(
- - FASTRPC_SMD_GUID,
- - gcinfo[cid].channel,
- - &me->channel[cid].chan, (void*)cid,
- - smd_event_handler));
- + if (kref_get_unless_zero(&me->kref) == 0) {
- + VERIFY(err, 0 == smd_named_open_on_edge(FASTRPC_SMD_GUID,
- + SMD_APPS_QDSP, &me->chan,
- + me, smd_event_handler));
- if (err)
- goto smd_bail;
- - VERIFY(err, 0 != wait_for_completion_timeout(
- - &me->channel[cid].work,
- + VERIFY(err, 0 != wait_for_completion_timeout(&me->work,
- RPC_TIMEOUT));
- if (err)
- goto completion_bail;
- - kref_init(&me->channel[cid].kref);
- - pr_info("'opened /dev/%s c %d %d'\n", gcinfo[cid].name,
- - MAJOR(me->dev_no), cid);
- + kref_init(&me->kref);
- + pr_info("'opened /dev/%s c %d 0'\n", DEVICE_NAME,
- + MAJOR(me->dev_no));
- }
- mutex_unlock(&me->smd_mutex);
- @@ -1349,26 +1320,25 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
- spin_lock_init(&fdata->hlock);
- INIT_HLIST_HEAD(&fdata->hlst);
- - fdata->cid = cid;
- - VERIFY(err, 0 == fastrpc_create_current_dsp_process(cid));
- + VERIFY(err, 0 == fastrpc_create_current_dsp_process());
- if (err)
- goto bail;
- filp->private_data = fdata;
- bail:
- if (err) {
- - cleanup_current_dev(cid);
- + cleanup_current_dev();
- kfree(fdata);
- - kref_put_mutex(&me->channel[cid].kref,
- - fastrpc_channel_close, &me->smd_mutex);
- + kref_put_mutex(&me->kref, fastrpc_channel_close,
- + &me->smd_mutex);
- }
- module_put(THIS_MODULE);
- }
- return err;
- completion_bail:
- - smd_close(me->channel[cid].chan);
- - me->channel[cid].chan = 0;
- + smd_close(me->chan);
- + me->chan = 0;
- smd_bail:
- mutex_unlock(&me->smd_mutex);
- return err;
- @@ -1380,7 +1350,6 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
- {
- struct fastrpc_apps *me = &gfa;
- struct fastrpc_ioctl_invoke_fd invokefd;
- - struct fastrpc_ioctl_invoke *invoke = &invokefd.inv;
- struct fastrpc_ioctl_mmap mmap;
- struct fastrpc_ioctl_munmap munmap;
- void *param = (char *)ioctl_param;
- @@ -1392,12 +1361,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
- case FASTRPC_IOCTL_INVOKE:
- invokefd.fds = 0;
- size = (ioctl_num == FASTRPC_IOCTL_INVOKE) ?
- - sizeof(*invoke) : sizeof(invokefd);
- + sizeof(invokefd.inv) : sizeof(invokefd);
- VERIFY(err, 0 == copy_from_user(&invokefd, param, size));
- if (err)
- goto bail;
- VERIFY(err, 0 == (err = fastrpc_internal_invoke(me, fdata->mode,
- - 0, &invokefd, fdata->cid)));
- + 0, &invokefd)));
- if (err)
- goto bail;
- break;
- @@ -1407,7 +1376,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
- if (err)
- goto bail;
- VERIFY(err, 0 == (err = fastrpc_internal_mmap(me, fdata,
- - &mmap)));
- + &mmap)));
- if (err)
- goto bail;
- VERIFY(err, 0 == copy_to_user(param, &mmap, sizeof(mmap)));
- @@ -1452,34 +1421,29 @@ static const struct file_operations fops = {
- static int __init fastrpc_device_init(void)
- {
- struct fastrpc_apps *me = &gfa;
- - int i, err = 0;
- + int err = 0;
- memset(me, 0, sizeof(*me));
- VERIFY(err, 0 == fastrpc_init());
- if (err)
- goto fastrpc_bail;
- - VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, NUM_CHANNELS,
- - DEVICE_NAME));
- + VERIFY(err, 0 == alloc_chrdev_region(&me->dev_no, 0, 1, DEVICE_NAME));
- if (err)
- goto alloc_chrdev_bail;
- cdev_init(&me->cdev, &fops);
- me->cdev.owner = THIS_MODULE;
- - VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
- - NUM_CHANNELS));
- + VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0), 1));
- if (err)
- goto cdev_init_bail;
- me->class = class_create(THIS_MODULE, "fastrpc");
- VERIFY(err, !IS_ERR(me->class));
- if (err)
- goto class_create_bail;
- - for (i = 0; i < NUM_CHANNELS; i++) {
- - me->channel[i].dev = device_create(me->class, NULL,
- - MKDEV(MAJOR(me->dev_no), i),
- - NULL, gcinfo[i].name);
- - VERIFY(err, !IS_ERR(me->channel[i].dev));
- - if (err)
- - goto device_create_bail;
- - }
- + me->dev = device_create(me->class, NULL, MKDEV(MAJOR(me->dev_no), 0),
- + NULL, DEVICE_NAME);
- + VERIFY(err, !IS_ERR(me->dev));
- + if (err)
- + goto device_create_bail;
- return 0;
- @@ -1488,7 +1452,7 @@ device_create_bail:
- class_create_bail:
- cdev_del(&me->cdev);
- cdev_init_bail:
- - unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
- + unregister_chrdev_region(me->dev_no, 1);
- alloc_chrdev_bail:
- fastrpc_deinit();
- fastrpc_bail:
- @@ -1498,17 +1462,14 @@ fastrpc_bail:
- static void __exit fastrpc_device_exit(void)
- {
- struct fastrpc_apps *me = &gfa;
- - int i;
- context_list_dtor(me, &me->clst);
- fastrpc_deinit();
- - for (i = 0; i < NUM_CHANNELS; i++) {
- - cleanup_current_dev(i);
- - device_destroy(me->class, MKDEV(MAJOR(me->dev_no), i));
- - }
- + cleanup_current_dev();
- + device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
- class_destroy(me->class);
- cdev_del(&me->cdev);
- - unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
- + unregister_chrdev_region(me->dev_no, 1);
- }
- module_init(fastrpc_device_init);
- diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
- index 28b066b..37e40c5 100644
- --- a/drivers/char/diag/diag_dci.c
- +++ b/drivers/char/diag/diag_dci.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -567,6 +567,8 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
- struct diag_dci_buffer_t *rsp_buf = NULL;
- struct dci_pkt_req_entry_t *req_entry = NULL;
- unsigned char *temp = buf;
- + int save_req_uid = 0;
- + struct diag_dci_pkt_rsp_header_t pkt_rsp_header;
- if (!buf) {
- pr_err("diag: Invalid pointer in %s\n", __func__);
- @@ -608,6 +610,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
- return;
- }
- curr_client_pid = req_entry->pid;
- + save_req_uid = req_entry->uid;
- /* Remove the headers and send only the response to this function */
- mutex_lock(&driver->dci_mutex);
- @@ -647,15 +650,14 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
- }
- /* Fill in packet response header information */
- - *(int *)(rsp_buf->data + rsp_buf->data_len) = DCI_PKT_RSP_TYPE;
- - rsp_buf->data_len += sizeof(int);
- + pkt_rsp_header.type = DCI_PKT_RSP_TYPE;
- /* Packet Length = Response Length + Length of uid field (int) */
- - *(int *)(rsp_buf->data + rsp_buf->data_len) = rsp_len + sizeof(int);
- - rsp_buf->data_len += sizeof(int);
- - *(uint8_t *)(rsp_buf->data + rsp_buf->data_len) = delete_flag;
- - rsp_buf->data_len += sizeof(uint8_t);
- - *(int *)(rsp_buf->data + rsp_buf->data_len) = req_entry->uid;
- - rsp_buf->data_len += sizeof(int);
- + pkt_rsp_header.length = rsp_len + sizeof(int);
- + pkt_rsp_header.delete_flag = delete_flag;
- + pkt_rsp_header.uid = save_req_uid;
- + memcpy(rsp_buf->data, &pkt_rsp_header,
- + sizeof(struct diag_dci_pkt_rsp_header_t));
- + rsp_buf->data_len += sizeof(struct diag_dci_pkt_rsp_header_t);
- memcpy(rsp_buf->data + rsp_buf->data_len, temp, rsp_len);
- rsp_buf->data_len += rsp_len;
- rsp_buf->data_source = data_source;
- @@ -1289,9 +1291,11 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
- * registered on the Apps Processor
- */
- if (entry.cmd_code_lo == MODE_CMD &&
- - entry.cmd_code_hi == MODE_CMD)
- + entry.cmd_code_hi == MODE_CMD &&
- + header->subsys_id == RESET_ID) {
- if (entry.client_id != APPS_DATA)
- continue;
- + }
- ret = diag_send_dci_pkt(entry, buf, len,
- req_entry->tag);
- found = 1;
- diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
- index ccd1a71..5c90b60 100644
- --- a/drivers/char/diag/diag_dci.h
- +++ b/drivers/char/diag/diag_dci.h
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -128,6 +128,13 @@ struct diag_log_event_stats {
- int is_set;
- };
- +struct diag_dci_pkt_rsp_header_t {
- + int type;
- + int length;
- + uint8_t delete_flag;
- + int uid;
- +} __packed;
- +
- struct diag_dci_pkt_header_t {
- uint8_t start;
- uint8_t version;
- diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
- index de7d0af..3747895 100644
- --- a/drivers/char/diag/diagchar_core.c
- +++ b/drivers/char/diag/diagchar_core.c
- @@ -302,10 +302,12 @@ static int diagchar_close(struct inode *inode, struct file *file)
- #ifdef CONFIG_DIAG_OVER_USB
- /* If the SD logging process exits, change logging to USB mode */
- if (driver->logging_process_id == current->tgid) {
- + mutex_lock(&driver->diagchar_mutex);
- driver->logging_mode = USB_MODE;
- + diag_ws_reset();
- + mutex_unlock(&driver->diagchar_mutex);
- diag_update_proc_vote(DIAG_PROC_MEMORY_DEVICE, VOTE_DOWN);
- diagfwd_connect();
- - diag_ws_reset();
- #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
- diag_clear_hsic_tbl();
- diagfwd_cancel_hsic(REOPEN_HSIC);
- @@ -911,6 +913,7 @@ int diag_switch_logging(unsigned long ioarg)
- pr_err("socket process, status: %d\n",
- status);
- }
- + driver->socket_process = NULL;
- }
- } else if (driver->logging_mode == SOCKET_MODE) {
- driver->socket_process = current;
- @@ -1293,10 +1296,16 @@ drop:
- COPY_USER_SPACE_OR_EXIT(buf+ret,
- *(data->buf_in_1),
- data->write_ptr_1->length);
- + diag_ws_on_copy();
- + copy_data = 1;
- data->in_busy_1 = 0;
- }
- }
- }
- + if (!copy_data) {
- + diag_ws_on_copy();
- + copy_data = 1;
- + }
- #ifdef CONFIG_DIAG_SDIO_PIPE
- /* copy 9K data over SDIO */
- if (driver->in_busy_sdio == 1) {
- @@ -1460,6 +1469,7 @@ drop:
- exit:
- mutex_unlock(&driver->diagchar_mutex);
- if (copy_data) {
- + diag_ws_on_copy_complete();
- /*
- * Flush any work that is currently pending on the data
- * channels. This will ensure that the next read is not
- @@ -1468,7 +1478,6 @@ exit:
- for (i = 0; i < NUM_SMD_DATA_CHANNELS; i++)
- flush_workqueue(driver->smd_data[i].wq);
- wake_up(&driver->smd_wait_q);
- - diag_ws_on_copy_complete();
- }
- return ret;
- }
- diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
- index edf0216..9f2d5d3 100644
- --- a/drivers/char/diag/diagfwd.c
- +++ b/drivers/char/diag/diagfwd.c
- @@ -531,8 +531,11 @@ int diag_process_smd_read_data(struct diag_smd_info *smd_info, void *buf,
- return 0;
- err:
- - if (driver->logging_mode == MEMORY_DEVICE_MODE)
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE)
- diag_ws_on_read(0);
- +
- return 0;
- }
- @@ -541,6 +544,12 @@ void diag_smd_queue_read(struct diag_smd_info *smd_info)
- if (!smd_info || !smd_info->ch)
- return;
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE) {
- + diag_ws_on_notify();
- + }
- +
- switch (smd_info->type) {
- case SMD_DCI_TYPE:
- case SMD_DCI_CMD_TYPE:
- @@ -559,12 +568,12 @@ void diag_smd_queue_read(struct diag_smd_info *smd_info)
- default:
- pr_err("diag: In %s, invalid type: %d\n", __func__,
- smd_info->type);
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE)
- + diag_ws_on_read(0);
- return;
- }
- -
- - if (driver->logging_mode == MEMORY_DEVICE_MODE &&
- - smd_info->type == SMD_DATA_TYPE)
- - diag_ws_on_notify();
- }
- static int diag_smd_resize_buf(struct diag_smd_info *smd_info, void **buf,
- @@ -787,9 +796,11 @@ void diag_smd_send_req(struct diag_smd_info *smd_info)
- }
- }
- }
- - if (smd_info->type == SMD_DATA_TYPE &&
- - driver->logging_mode == MEMORY_DEVICE_MODE)
- - diag_ws_on_read(pkt_len);
- +
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE)
- + diag_ws_on_read(total_recd);
- if (total_recd > 0) {
- if (!buf) {
- @@ -814,12 +825,19 @@ void diag_smd_send_req(struct diag_smd_info *smd_info)
- } else if (smd_info->ch && !buf &&
- (driver->logging_mode == MEMORY_DEVICE_MODE)) {
- chk_logging_wakeup();
- + } else {
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE) {
- + diag_ws_on_read(0);
- + }
- }
- return;
- fail_return:
- - if (smd_info->type == SMD_DATA_TYPE &&
- - driver->logging_mode == MEMORY_DEVICE_MODE)
- + if ((smd_info->type == SMD_DATA_TYPE ||
- + smd_info->type == SMD_CMD_TYPE) &&
- + driver->logging_mode == MEMORY_DEVICE_MODE)
- diag_ws_on_read(0);
- if (smd_info->type == SMD_DCI_TYPE ||
- @@ -2214,11 +2232,11 @@ void diag_smd_notify(void *ctxt, unsigned event)
- diag_dci_notify_client(smd_info->peripheral_mask,
- DIAG_STATUS_OPEN);
- }
- - wake_up(&driver->smd_wait_q);
- diag_smd_queue_read(smd_info);
- - } else if (event == SMD_EVENT_DATA) {
- wake_up(&driver->smd_wait_q);
- + } else if (event == SMD_EVENT_DATA) {
- diag_smd_queue_read(smd_info);
- + wake_up(&driver->smd_wait_q);
- if (smd_info->type == SMD_DCI_TYPE ||
- smd_info->type == SMD_DCI_CMD_TYPE) {
- diag_dci_try_activate_wakeup_source();
- diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
- index 3521452..f61759b 100644
- --- a/drivers/crypto/msm/qcrypto.c
- +++ b/drivers/crypto/msm/qcrypto.c
- @@ -1,6 +1,6 @@
- /* Qualcomm Crypto driver
- *
- - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
- + * Copyright (c) 2010-2015, 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
- @@ -68,6 +68,7 @@ enum qcrypto_bus_state {
- BUS_BANDWIDTH_RELEASING,
- BUS_BANDWIDTH_ALLOCATING,
- BUS_SUSPENDED,
- + BUS_SUSPENDING,
- };
- struct crypto_stat {
- @@ -565,7 +566,7 @@ static void qcrypto_bw_reaper_work(struct work_struct *work)
- /* check if engine is stuck */
- if (pengine->req) {
- if (pengine->check_flag)
- - dev_err(&pengine->pdev->dev,
- + dev_warn(&pengine->pdev->dev,
- "The engine appears to be stuck seq %d req %p.\n",
- active_seq, pengine->req);
- pengine->check_flag = false;
- @@ -963,6 +964,7 @@ static void _qcrypto_remove_engine(struct crypto_engine *pengine)
- cancel_work_sync(&pengine->bw_reaper_ws);
- cancel_work_sync(&pengine->bw_allocate_ws);
- del_timer_sync(&pengine->bw_reaper_timer);
- + device_init_wakeup(&pengine->pdev->dev, false);
- if (pengine->bus_scale_handle != 0)
- msm_bus_scale_unregister_client(pengine->bus_scale_handle);
- @@ -1886,6 +1888,12 @@ again:
- backlog_eng = crypto_get_backlog(&pengine->req_queue);
- + /* make sure it is in high bandwidth state */
- + if (pengine->bw_state != BUS_HAS_BANDWIDTH) {
- + spin_unlock_irqrestore(&cp->lock, flags);
- + return 0;
- + }
- +
- /* try to get request from request queue of the engine first */
- async_req = crypto_dequeue_request(&pengine->req_queue);
- if (!async_req) {
- @@ -2037,6 +2045,7 @@ static int _qcrypto_queue_req(struct crypto_priv *cp,
- pengine = NULL;
- break;
- case BUS_SUSPENDED:
- + case BUS_SUSPENDING:
- default:
- pengine = NULL;
- break;
- @@ -4305,6 +4314,7 @@ static int _qcrypto_probe(struct platform_device *pdev)
- pengine->active_seq = 0;
- pengine->last_active_seq = 0;
- pengine->check_flag = false;
- + device_init_wakeup(&pengine->pdev->dev, true);
- tasklet_init(&pengine->done_tasklet, req_done, (unsigned long)pengine);
- crypto_init_queue(&pengine->req_queue, MSM_QCRYPTO_REQ_QUEUE_LENGTH);
- @@ -4657,6 +4667,25 @@ err:
- return rc;
- };
- +static int _qcrypto_engine_in_use(struct crypto_engine *pengine)
- +{
- + struct crypto_priv *cp = pengine->pcp;
- +
- + if (pengine->req || pengine->req_queue.qlen || cp->req_queue.qlen)
- + return 1;
- + return 0;
- +}
- +
- +static void _qcrypto_do_suspending(struct crypto_engine *pengine)
- +{
- + struct crypto_priv *cp = pengine->pcp;
- +
- + if (cp->platform_support.bus_scale_table == NULL)
- + return;
- + del_timer_sync(&pengine->bw_reaper_timer);
- + qcrypto_ce_set_bus(pengine, false);
- +}
- +
- static int _qcrypto_suspend(struct platform_device *pdev, pm_message_t state)
- {
- int ret = 0;
- @@ -4684,9 +4713,20 @@ static int _qcrypto_suspend(struct platform_device *pdev, pm_message_t state)
- ret = -EBUSY;
- break;
- case BUS_HAS_BANDWIDTH:
- + if (_qcrypto_engine_in_use(pengine)) {
- + ret = -EBUSY;
- + } else {
- + pengine->bw_state = BUS_SUSPENDING;
- + spin_unlock_irqrestore(&cp->lock, flags);
- + _qcrypto_do_suspending(pengine);
- + spin_lock_irqsave(&cp->lock, flags);
- + pengine->bw_state = BUS_SUSPENDED;
- + }
- + break;
- case BUS_BANDWIDTH_RELEASING:
- case BUS_BANDWIDTH_ALLOCATING:
- case BUS_SUSPENDED:
- + case BUS_SUSPENDING:
- default:
- ret = -EBUSY;
- break;
- @@ -4707,6 +4747,7 @@ static int _qcrypto_resume(struct platform_device *pdev)
- struct crypto_engine *pengine;
- struct crypto_priv *cp;
- unsigned long flags;
- + int ret = 0;
- pengine = platform_get_drvdata(pdev);
- @@ -4731,9 +4772,11 @@ static int _qcrypto_resume(struct platform_device *pdev)
- pengine->high_bw_req = true;
- }
- }
- - }
- + } else
- + ret = -EBUSY;
- +
- spin_unlock_irqrestore(&cp->lock, flags);
- - return 0;
- + return ret;
- }
- static struct of_device_id qcrypto_match[] = {
- diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
- index 5600c11..6f8919a 100644
- --- a/drivers/gpu/msm/adreno.c
- +++ b/drivers/gpu/msm/adreno.c
- @@ -78,7 +78,6 @@
- #define KGSL_LOG_LEVEL_DEFAULT 3
- -static void adreno_start_work(struct work_struct *work);
- static void adreno_input_work(struct work_struct *work);
- /*
- @@ -151,16 +150,12 @@ static struct adreno_device device_3d0 = {
- .ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY,
- .fast_hang_detect = 1,
- .long_ib_detect = 1,
- - .start_work = __WORK_INITIALIZER(device_3d0.start_work,
- - adreno_start_work),
- .input_work = __WORK_INITIALIZER(device_3d0.input_work,
- adreno_input_work),
- };
- unsigned int ft_detect_regs[FT_DETECT_REGS_COUNT];
- -static struct workqueue_struct *adreno_wq;
- -
- /*
- * This is the master list of all GPU cores that are supported by this
- * driver.
- @@ -255,7 +250,7 @@ static const struct {
- };
- /* Nice level for the higher priority GPU start thread */
- -static unsigned int _wake_nice = -7;
- +static int _wake_nice = -7;
- /* Number of milliseconds to stay active active after a wake on touch */
- static unsigned int _wake_timeout = 100;
- @@ -1937,9 +1932,6 @@ static int adreno_init(struct kgsl_device *device)
- int i;
- int ret;
- - /* Make a high priority workqueue for starting the GPU */
- - adreno_wq = alloc_workqueue("adreno", WQ_HIGHPRI | WQ_UNBOUND, 1);
- -
- kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
- /*
- * initialization only needs to be done once initially until
- @@ -2125,74 +2117,30 @@ error_clk_off:
- return status;
- }
- -static int _status;
- -
- -/**
- - * _adreno_start_work() - Work handler for the low latency adreno_start
- - * @work: Pointer to the work_struct for
- - *
- - * The work callbak for the low lantecy GPU start - this executes the core
- - * _adreno_start function in the workqueue.
- - */
- -static void adreno_start_work(struct work_struct *work)
- -{
- - struct adreno_device *adreno_dev = container_of(work,
- - struct adreno_device, start_work);
- - struct kgsl_device *device = &adreno_dev->dev;
- -
- - /* Nice ourselves to be higher priority but not too high priority */
- - set_user_nice(current, _wake_nice);
- -
- - kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- - /*
- - * If adreno start is already called, no need to call it again
- - * it can lead to unpredictable behavior if we try to start
- - * the device that is already started.
- - * Below is the sequence of events that can go bad without the check
- - * 1) thread 1 calls adreno_start to be scheduled on high priority wq
- - * 2) thread 2 calls adreno_start with normal priority
- - * 3) thread 1 after checking the device to be in slumber state gives
- - * up mutex to be scheduled on high priority wq
- - * 4) thread 2 after checking the device to be in slumber state gets
- - * the mutex and finishes adreno_start before thread 1 is scheduled
- - * on high priority wq.
- - * 5) thread 1 gets scheduled on high priority wq and executes
- - * adreno_start again. This leads to unpredictable behavior.
- - */
- - if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv))
- - _status = _adreno_start(adreno_dev);
- - else
- - _status = 0;
- - kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- -}
- -
- /**
- * adreno_start() - Power up and initialize the GPU
- * @device: Pointer to the KGSL device to power up
- * @priority: Boolean flag to specify of the start should be scheduled in a low
- * latency work queue
- *
- - * Power up the GPU and initialize it. If priority is specified then queue the
- - * start function in a high priority queue for lower latency.
- + * Power up the GPU and initialize it. If priority is specified then elevate
- + * the thread priority for the duration of the start operation
- */
- static int adreno_start(struct kgsl_device *device, int priority)
- {
- struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
- + int nice = task_nice(current);
- + int ret;
- - /* No priority (normal latency) call the core start function directly */
- - if (!priority)
- - return _adreno_start(adreno_dev);
- + if (priority && (_wake_nice < nice))
- + set_user_nice(current, _wake_nice);
- - /*
- - * If priority is specified (low latency) then queue the work in a
- - * higher priority work queue and wait for it to finish
- - */
- - queue_work(adreno_wq, &adreno_dev->start_work);
- - kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- - flush_work(&adreno_dev->start_work);
- - kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- + ret = _adreno_start(adreno_dev);
- +
- + if (priority)
- + set_user_nice(current, nice);
- - return _status;
- + return ret;
- }
- static int adreno_stop(struct kgsl_device *device)
- diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
- index aaf5935..c9335c3 100644
- --- a/drivers/gpu/msm/adreno.h
- +++ b/drivers/gpu/msm/adreno.h
- @@ -201,7 +201,6 @@ struct adreno_device {
- struct adreno_dispatcher dispatcher;
- struct adreno_busy_data busy_data;
- - struct work_struct start_work;
- struct work_struct input_work;
- unsigned int ram_cycles_lo;
- };
- diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
- index 9f5765d..c8f0101 100644
- --- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
- +++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
- @@ -463,14 +463,23 @@ void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
- size = (adreno_is_a330(adreno_dev) ||
- adreno_is_a305b(adreno_dev)) ? 0x2E : 0x14;
- - snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
- - remain, REG_CP_STATE_DEBUG_INDEX,
- - REG_CP_STATE_DEBUG_DATA, 0x0, size);
- -
- - /* CP_ME indexed registers */
- - snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
- - remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS,
- - 64, 44);
- + /* Skip indexed register dump for these chipsets 8974, 8x26, 8x10 */
- + if (adreno_is_a330(adreno_dev) ||
- + adreno_is_a330v2(adreno_dev) ||
- + adreno_is_a305b(adreno_dev) ||
- + adreno_is_a305c(adreno_dev) ) {
- + KGSL_DRV_ERR(device,
- + "Skipping indexed register dump\n");
- + } else {
- + snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
- + remain, REG_CP_STATE_DEBUG_INDEX,
- + REG_CP_STATE_DEBUG_DATA, 0x0, size);
- +
- + /* CP_ME indexed registers */
- + snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
- + remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS,
- + 64, 44);
- + }
- /* VPC memory */
- snapshot = kgsl_snapshot_add_section(device,
- @@ -482,10 +491,19 @@ void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
- KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
- a3xx_snapshot_cp_meq, NULL);
- - /* Shader working/shadow memory */
- - snapshot = kgsl_snapshot_add_section(device,
- + /* Skip shader memory dump for these chipsets: 8974, 8x26, 8x10 */
- + if (adreno_is_a330(adreno_dev) ||
- + adreno_is_a330v2(adreno_dev) ||
- + adreno_is_a305b(adreno_dev) ||
- + adreno_is_a305c(adreno_dev) ) {
- + KGSL_DRV_ERR(device,
- + "Skipping shader memory dump\n");
- + } else {
- + /* Shader working/shadow memory */
- + snapshot = kgsl_snapshot_add_section(device,
- KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
- a3xx_snapshot_shader_memory, NULL);
- + }
- /* CP PFP and PM4 */
- diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
- index bcab791..1527d83 100644
- --- a/drivers/gpu/msm/adreno_dispatch.c
- +++ b/drivers/gpu/msm/adreno_dispatch.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2015, 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
- @@ -145,6 +145,27 @@ static int fault_detect_read_compare(struct kgsl_device *device)
- return ret;
- }
- +static int _check_context_queue(struct adreno_context *drawctxt)
- +{
- + int ret;
- +
- + spin_lock(&drawctxt->lock);
- +
- + /*
- + * Wake up if there is room in the context or if the whole thing got
- + * invalidated while we were asleep
- + */
- +
- + if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID)
- + ret = 1;
- + else
- + ret = drawctxt->queued < _context_cmdqueue_size ? 1 : 0;
- +
- + spin_unlock(&drawctxt->lock);
- +
- + return ret;
- +}
- +
- /**
- * adreno_dispatcher_get_cmdbatch() - Get a new command from a context queue
- * @drawctxt: Pointer to the adreno draw context
- @@ -221,13 +242,17 @@ static inline int adreno_dispatcher_requeue_cmdbatch(
- struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch)
- {
- unsigned int prev;
- + struct kgsl_device *device;
- spin_lock(&drawctxt->lock);
- if (kgsl_context_detached(&drawctxt->base) ||
- drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
- spin_unlock(&drawctxt->lock);
- + device = cmdbatch->device;
- /* get rid of this cmdbatch since the context is bad */
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- kgsl_cmdbatch_destroy(cmdbatch);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- return -EINVAL;
- }
- @@ -414,7 +439,10 @@ static int dispatcher_context_sendcmds(struct adreno_device *adreno_dev,
- */
- if (cmdbatch->flags & KGSL_CONTEXT_SYNC) {
- + struct kgsl_device *device = cmdbatch->device;
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- kgsl_cmdbatch_destroy(cmdbatch);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- continue;
- }
- @@ -441,12 +469,11 @@ static int dispatcher_context_sendcmds(struct adreno_device *adreno_dev,
- }
- /*
- - * If the context successfully submitted commands there will be room
- - * in the context queue so wake up any snoozing threads that want to
- - * submit commands
- + * Wake up any snoozing threads if we have consumed any real commands
- + * or marker commands and we have room in the context queue.
- */
- - if (count)
- + if (_check_context_queue(drawctxt))
- wake_up_all(&drawctxt->wq);
- /*
- @@ -569,27 +596,6 @@ int adreno_dispatcher_issuecmds(struct adreno_device *adreno_dev)
- return ret;
- }
- -static int _check_context_queue(struct adreno_context *drawctxt)
- -{
- - int ret;
- -
- - spin_lock(&drawctxt->lock);
- -
- - /*
- - * Wake up if there is room in the context or if the whole thing got
- - * invalidated while we were asleep
- - */
- -
- - if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID)
- - ret = 1;
- - else
- - ret = drawctxt->queued < _context_cmdqueue_size ? 1 : 0;
- -
- - spin_unlock(&drawctxt->lock);
- -
- - return ret;
- -}
- -
- /**
- * get_timestamp() - Return the next timestamp for the context
- * @drawctxt - Pointer to an adreno draw context struct
- @@ -931,11 +937,8 @@ static void remove_invalidated_cmdbatches(struct kgsl_device *device,
- drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
- replay[i] = NULL;
- - kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- kgsl_cancel_events_timestamp(device, cmd->context,
- cmd->timestamp);
- - kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- -
- kgsl_cmdbatch_destroy(cmd);
- }
- }
- @@ -1084,7 +1087,8 @@ static int dispatcher_do_fault(struct kgsl_device *device)
- kgsl_device_snapshot(device, 1);
- }
- - kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- +
- /* Allocate memory to store the inflight commands */
- replay = kzalloc(sizeof(*replay) * dispatcher->inflight, GFP_KERNEL);
- @@ -1092,6 +1096,7 @@ static int dispatcher_do_fault(struct kgsl_device *device)
- if (replay == NULL) {
- unsigned int ptr = dispatcher->head;
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- /* Recovery failed - mark everybody guilty */
- mark_guilty_context(device, 0);
- @@ -1111,6 +1116,7 @@ static int dispatcher_do_fault(struct kgsl_device *device)
- */
- count = 0;
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- goto replay;
- }
- @@ -1168,7 +1174,9 @@ static int dispatcher_do_fault(struct kgsl_device *device)
- cmdbatch->context->id, cmdbatch->timestamp);
- mark_guilty_context(device, cmdbatch->context->id);
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- adreno_drawctxt_invalidate(device, cmdbatch->context);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- }
- /*
- @@ -1277,7 +1285,9 @@ static int dispatcher_do_fault(struct kgsl_device *device)
- mark_guilty_context(device, cmdbatch->context->id);
- /* Invalidate the context */
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- adreno_drawctxt_invalidate(device, cmdbatch->context);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- replay:
- @@ -1296,8 +1306,10 @@ replay:
- /* If adreno_reset() fails then what hope do we have for the future? */
- BUG_ON(ret);
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- /* Remove any pending command batches that have been invalidated */
- remove_invalidated_cmdbatches(device, replay, count);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- /* Replay the pending command buffers */
- for (i = 0; i < count; i++) {
- @@ -1339,9 +1351,11 @@ replay:
- /* Mark this context as guilty (failed recovery) */
- mark_guilty_context(device, replay[i]->context->id);
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- adreno_drawctxt_invalidate(device, replay[i]->context);
- remove_invalidated_cmdbatches(device, &replay[i],
- count - i);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- }
- }
- @@ -1449,8 +1463,10 @@ static void adreno_dispatcher_work(struct work_struct *work)
- dispatcher->head = CMDQUEUE_NEXT(dispatcher->head,
- ADRENO_DISPATCH_CMDQUEUE_SIZE);
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- /* Destroy the retired command batch */
- kgsl_cmdbatch_destroy(cmdbatch);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- /* Update the expire time for the next command batch */
- @@ -1695,16 +1711,19 @@ void adreno_dispatcher_stop(struct adreno_device *adreno_dev)
- void adreno_dispatcher_close(struct adreno_device *adreno_dev)
- {
- struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;
- + struct kgsl_device *device = &adreno_dev->dev;
- mutex_lock(&dispatcher->mutex);
- del_timer_sync(&dispatcher->timer);
- del_timer_sync(&dispatcher->fault_timer);
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- while (dispatcher->head != dispatcher->tail) {
- kgsl_cmdbatch_destroy(dispatcher->cmdqueue[dispatcher->head]);
- dispatcher->head = (dispatcher->head + 1)
- % ADRENO_DISPATCH_CMDQUEUE_SIZE;
- }
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- mutex_unlock(&dispatcher->mutex);
- diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
- index db4aa6a..df9d6ec 100644
- --- a/drivers/gpu/msm/adreno_drawctxt.c
- +++ b/drivers/gpu/msm/adreno_drawctxt.c
- @@ -367,14 +367,10 @@ int adreno_drawctxt_wait_global(struct adreno_device *adreno_dev,
- kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- if (timeout) {
- - ret = (int) wait_event_timeout(drawctxt->waiting,
- + if (0 == (int) wait_event_timeout(drawctxt->waiting,
- _check_global_timestamp(device, drawctxt, timestamp),
- - msecs_to_jiffies(timeout));
- -
- - if (ret == 0)
- + msecs_to_jiffies(timeout)))
- ret = -ETIMEDOUT;
- - else if (ret > 0)
- - ret = 0;
- } else {
- wait_event(drawctxt->waiting,
- _check_global_timestamp(device, drawctxt, timestamp));
- @@ -598,9 +594,14 @@ int adreno_drawctxt_detach(struct kgsl_context *context)
- */
- BUG_ON(!mutex_is_locked(&device->mutex));
- - /* Wait for the last global timestamp to pass before continuing */
- + /* Wait for the last global timestamp to pass before continuing.
- + * The maxumum wait time is 30s, some large IB's can take longer
- + * than 10s and if hang happens then the time for the context's
- + * commands to retire will be greater than 10s. 30s should be sufficient
- + * time to wait for the commands even if a hang happens.
- + */
- ret = adreno_drawctxt_wait_global(adreno_dev, context,
- - drawctxt->internal_timestamp, 10 * 1000);
- + drawctxt->internal_timestamp, 30 * 1000);
- /*
- * If the wait for global fails then nothing after this point is likely
- diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
- index bc37bf2..a11c63d 100644
- --- a/drivers/gpu/msm/adreno_snapshot.c
- +++ b/drivers/gpu/msm/adreno_snapshot.c
- @@ -599,11 +599,8 @@ static int ib_add_gpu_object(struct kgsl_device *device, phys_addr_t ptbase,
- unsigned int gpuaddr = src[i + 1];
- unsigned int size = src[i + 2];
- - ret = parse_ib(device, ptbase, gpuaddr, size);
- + parse_ib(device, ptbase, gpuaddr, size);
- - /* If adding the IB failed then stop parsing */
- - if (ret < 0)
- - goto done;
- } else {
- ret = ib_parse_type3(device, &src[i], ptbase);
- /*
- @@ -929,15 +926,16 @@ static int snapshot_ib(struct kgsl_device *device, void *snapshot,
- if ((obj->dwords - i) < type3_pkt_size(*src) + 1)
- continue;
- - if (adreno_cmd_is_ib(*src))
- - ret = parse_ib(device, obj->ptbase, src[1],
- + if (adreno_cmd_is_ib(*src)) {
- + parse_ib(device, obj->ptbase, src[1],
- src[2]);
- - else
- + } else {
- ret = ib_parse_type3(device, src, obj->ptbase);
- - /* Stop parsing if the type3 decode fails */
- - if (ret < 0)
- - break;
- + /* Stop parsing if the type3 decode fails */
- + if (ret < 0)
- + break;
- + }
- }
- }
- diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
- index e2ddde9..0b73419 100644
- --- a/drivers/gpu/msm/kgsl.c
- +++ b/drivers/gpu/msm/kgsl.c
- @@ -2311,8 +2311,11 @@ free_cmdbatch:
- * -EPROTO is a "success" error - it just tells the user that the
- * context had previously faulted
- */
- - if (result && result != -EPROTO)
- + if (result && result != -EPROTO) {
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- kgsl_cmdbatch_destroy(cmdbatch);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- + }
- done:
- kgsl_context_put(context);
- @@ -2363,8 +2366,11 @@ free_cmdbatch:
- * -EPROTO is a "success" error - it just tells the user that the
- * context had previously faulted
- */
- - if (result && result != -EPROTO)
- + if (result && result != -EPROTO) {
- + kgsl_mutex_lock(&device->mutex, &device->mutex_owner);
- kgsl_cmdbatch_destroy(cmdbatch);
- + kgsl_mutex_unlock(&device->mutex, &device->mutex_owner);
- + }
- done:
- kgsl_context_put(context);
- diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
- index cf03c7f..5763971 100644
- --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
- +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -19,11 +19,11 @@
- #include <linux/io.h>
- #include <linux/list.h>
- #include <linux/delay.h>
- +#include <linux/avtimer_kernel.h>
- #include <media/v4l2-subdev.h>
- #include <media/msmb_isp.h>
- #include <mach/msm_bus.h>
- #include <mach/msm_bus_board.h>
- -
- #include "msm_buf_mgr.h"
- #define MAX_IOMMU_CTX 2
- @@ -49,6 +49,16 @@ struct vfe_subscribe_info {
- uint32_t active;
- };
- +enum msm_isp_pack_fmt {
- + QCOM,
- + MIPI,
- + DPCM6,
- + DPCM8,
- + PLAIN8,
- + PLAIN16,
- + MAX_ISP_PACK_FMT,
- +};
- +
- enum msm_isp_camif_update_state {
- NO_UPDATE,
- ENABLE_CAMIF,
- @@ -56,9 +66,17 @@ enum msm_isp_camif_update_state {
- DISABLE_CAMIF_IMMEDIATELY
- };
- +enum msm_isp_reset_type {
- + ISP_RST_HARD,
- + ISP_RST_SOFT,
- + ISP_RST_MAX
- +};
- +
- struct msm_isp_timestamp {
- /*Monotonic clock for v4l2 buffer*/
- struct timeval buf_time;
- + /*Monotonic clock for VT */
- + struct timeval vt_time;
- /*Wall clock for userspace event*/
- struct timeval event_time;
- };
- @@ -89,8 +107,9 @@ struct msm_vfe_axi_ops {
- uint32_t reload_mask);
- void (*enable_wm) (struct vfe_device *vfe_dev,
- uint8_t wm_idx, uint8_t enable);
- - void (*cfg_io_format) (struct vfe_device *vfe_dev,
- - struct msm_vfe_axi_stream *stream_info);
- + int32_t (*cfg_io_format) (struct vfe_device *vfe_dev,
- + enum msm_vfe_axi_stream_src stream_src,
- + uint32_t io_format);
- void (*cfg_framedrop) (struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info);
- void (*clear_framedrop) (struct vfe_device *vfe_dev,
- @@ -124,12 +143,13 @@ struct msm_vfe_axi_ops {
- uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1);
- uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1);
- uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev);
- - long (*halt) (struct vfe_device *vfe_dev);
- + long (*halt) (struct vfe_device *vfe_dev, uint32_t blocking);
- };
- struct msm_vfe_core_ops {
- void (*reg_update) (struct vfe_device *vfe_dev);
- - long (*reset_hw) (struct vfe_device *vfe_dev);
- + long (*reset_hw) (struct vfe_device *vfe_dev,
- + enum msm_isp_reset_type reset_type, uint32_t blocking);
- int (*init_hw) (struct vfe_device *vfe_dev);
- void (*init_hw_reg) (struct vfe_device *vfe_dev);
- void (*release_hw) (struct vfe_device *vfe_dev);
- @@ -143,6 +163,12 @@ struct msm_vfe_core_ops {
- int (*get_platform_data) (struct vfe_device *vfe_dev);
- void (*get_error_mask) (uint32_t *error_mask0, uint32_t *error_mask1);
- void (*process_error_status) (struct vfe_device *vfe_dev);
- + void (*get_overflow_mask) (uint32_t *overflow_mask);
- + void (*get_irq_mask) (struct vfe_device *vfe_dev,
- + uint32_t *irq0_mask, uint32_t *irq1_mask);
- + void (*restore_irq_mask) (struct vfe_device *vfe_dev);
- + void (*get_halt_restart_mask) (uint32_t *irq0_mask,
- + uint32_t *irq1_mask);
- };
- struct msm_vfe_stats_ops {
- int (*get_stats_idx) (enum msm_isp_stats_type stats_type);
- @@ -252,7 +278,7 @@ struct msm_vfe_axi_stream {
- uint32_t stream_handle;
- uint8_t buf_divert;
- enum msm_vfe_axi_stream_type stream_type;
- -
- + uint32_t vt_enable;
- uint32_t frame_based;
- uint32_t framedrop_period;
- uint32_t framedrop_pattern;
- @@ -274,6 +300,15 @@ struct msm_vfe_axi_stream {
- uint32_t runtime_num_burst_capture;
- uint8_t runtime_framedrop_update;
- uint32_t runtime_output_format;
- + enum msm_vfe_frame_skip_pattern frame_skip_pattern;
- +
- +};
- +
- +enum msm_vfe_overflow_state {
- + NO_OVERFLOW,
- + OVERFLOW_DETECTED,
- + HALT_REQUESTED,
- + RESTART_REQUESTED,
- };
- struct msm_vfe_axi_composite_info {
- @@ -289,6 +324,8 @@ struct msm_vfe_src_info {
- enum msm_vfe_inputmux input_mux;
- uint32_t width;
- long pixel_clock;
- + uint32_t input_format;/*V4L2 pix format with bayer pattern*/
- + uint32_t last_updt_frm_id;
- };
- enum msm_wm_ub_cfg_type {
- @@ -314,6 +351,7 @@ struct msm_vfe_axi_shared_data {
- struct msm_vfe_src_info src_info[VFE_SRC_MAX];
- uint16_t stream_handle_cnt;
- unsigned long event_mask;
- + uint32_t burst_len;
- };
- struct msm_vfe_stats_hardware_info {
- @@ -355,6 +393,8 @@ struct msm_vfe_stats_shared_data {
- atomic_t stats_comp_mask;
- uint16_t stream_handle_cnt;
- atomic_t stats_update;
- + uint32_t stats_mask;
- + uint32_t stats_burst_len;
- };
- struct msm_vfe_tasklet_queue_cmd {
- @@ -368,6 +408,9 @@ struct msm_vfe_tasklet_queue_cmd {
- #define MSM_VFE_TASKLETQ_SIZE 200
- struct msm_vfe_error_info {
- + atomic_t overflow_state;
- + uint32_t overflow_recover_irq_mask0;
- + uint32_t overflow_recover_irq_mask1;
- uint32_t error_mask0;
- uint32_t error_mask1;
- uint32_t violation_status;
- @@ -378,16 +421,41 @@ struct msm_vfe_error_info {
- uint32_t error_count;
- };
- +struct msm_vfe_frame_ts {
- + struct timeval buf_time;
- + uint32_t frame_id;
- +};
- +
- +struct msm_isp_statistics {
- + int32_t imagemaster0_overflow;
- + int32_t imagemaster1_overflow;
- + int32_t imagemaster2_overflow;
- + int32_t imagemaster3_overflow;
- + int32_t imagemaster4_overflow;
- + int32_t imagemaster5_overflow;
- + int32_t imagemaster6_overflow;
- + int32_t be_overflow;
- + int32_t bg_overflow;
- + int32_t bf_overflow;
- + int32_t awb_overflow;
- + int32_t rs_overflow;
- + int32_t cs_overflow;
- + int32_t ihist_overflow;
- + int32_t skinbhist_overflow;
- +};
- +
- struct vfe_device {
- struct platform_device *pdev;
- struct msm_sd_subdev subdev;
- struct resource *vfe_irq;
- struct resource *vfe_mem;
- struct resource *vfe_vbif_mem;
- + struct resource *tcsr_mem;
- struct resource *vfe_io;
- struct resource *vfe_vbif_io;
- void __iomem *vfe_base;
- void __iomem *vfe_vbif_base;
- + void __iomem *tcsr_base;
- struct device *iommu_ctx[MAX_IOMMU_CTX];
- @@ -410,16 +478,22 @@ struct vfe_device {
- struct list_head tasklet_q;
- struct tasklet_struct vfe_tasklet;
- struct msm_vfe_tasklet_queue_cmd
- - tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
- -
- + tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
- + uint32_t soc_hw_version;
- uint32_t vfe_hw_version;
- struct msm_vfe_hardware_info *hw_info;
- struct msm_vfe_axi_shared_data axi_data;
- struct msm_vfe_stats_shared_data stats_data;
- struct msm_vfe_error_info error_info;
- + struct msm_vfe_frame_ts frame_ts;
- struct msm_isp_buf_mgr *buf_mgr;
- int dump_reg;
- + int vfe_clk_idx;
- uint32_t vfe_open_cnt;
- + uint8_t vt_enable;
- + uint8_t ignore_error;
- + struct msm_isp_statistics *stats;
- + uint32_t vfe_ub_size;
- };
- #endif
- diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
- index 73b4f4d..263d54d 100644
- --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
- +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -22,9 +22,10 @@
- #include "msm.h"
- #include "msm_camera_io_util.h"
- -#define VFE32_BURST_LEN 3
- +#define VFE32_BURST_LEN 2
- #define VFE32_UB_SIZE 1024
- -#define VFE32_EQUAL_SLICE_UB 204
- +#define VFE32_EQUAL_SLICE_UB 194
- +#define VFE32_AXI_SLICE_UB 792
- #define VFE32_WM_BASE(idx) (0x4C + 0x18 * idx)
- #define VFE32_RDI_BASE(idx) (idx ? 0x734 + 0x4 * (idx - 1) : 0x06FC)
- #define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4))
- @@ -40,7 +41,19 @@
- (~(ping_pong >> (idx + VFE32_STATS_PING_PONG_OFFSET)) & 0x1))
- #define VFE32_CLK_IDX 0
- -static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
- +#define MSM_ISP32_TOTAL_WM_UB 792
- +
- +static struct msm_cam_clk_info msm_vfe32_1_clk_info[] = {
- + /*vfe32 clock info for B-family: 8610 */
- + {"vfe_clk_src", 266670000},
- + {"vfe_clk", -1},
- + {"vfe_ahb_clk", -1},
- + {"csi_vfe_clk", -1},
- + {"bus_clk", -1},
- +};
- +
- +static struct msm_cam_clk_info msm_vfe32_2_clk_info[] = {
- + /*vfe32 clock info for A-family: 8960 */
- {"vfe_clk", 266667000},
- {"vfe_pclk", -1},
- {"csi_vfe_clk", -1},
- @@ -49,6 +62,7 @@ static struct msm_cam_clk_info msm_vfe32_clk_info[] = {
- static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
- {
- int rc = -1;
- + vfe_dev->vfe_clk_idx = 0;
- rc = msm_isp_init_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
- if (rc < 0) {
- pr_err("%s: Bandwidth registration Failed!\n", __func__);
- @@ -62,11 +76,21 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
- goto fs_failed;
- }
- }
- + else
- + goto fs_failed;
- - rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
- - vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 1);
- - if (rc < 0)
- - goto clk_enable_failed;
- + rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_1_clk_info,
- + vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_1_clk_info), 1);
- + if (rc < 0) {
- + rc = msm_cam_clk_enable(&vfe_dev->pdev->dev,
- + msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
- + ARRAY_SIZE(msm_vfe32_2_clk_info), 1);
- + if (rc < 0)
- + goto clk_enable_failed;
- + else
- + vfe_dev->vfe_clk_idx = 2;
- + } else
- + vfe_dev->vfe_clk_idx = 1;
- vfe_dev->vfe_base = ioremap(vfe_dev->vfe_mem->start,
- resource_size(vfe_dev->vfe_mem));
- @@ -87,8 +111,14 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
- irq_req_failed:
- iounmap(vfe_dev->vfe_base);
- vfe_remap_failed:
- - msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
- - vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
- + if (vfe_dev->vfe_clk_idx == 1)
- + msm_cam_clk_enable(&vfe_dev->pdev->dev,
- + msm_vfe32_1_clk_info, vfe_dev->vfe_clk,
- + ARRAY_SIZE(msm_vfe32_1_clk_info), 0);
- + if (vfe_dev->vfe_clk_idx == 2)
- + msm_cam_clk_enable(&vfe_dev->pdev->dev,
- + msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
- + ARRAY_SIZE(msm_vfe32_2_clk_info), 0);
- clk_enable_failed:
- regulator_disable(vfe_dev->fs_vfe);
- fs_failed:
- @@ -102,8 +132,14 @@ static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
- free_irq(vfe_dev->vfe_irq->start, vfe_dev);
- tasklet_kill(&vfe_dev->vfe_tasklet);
- iounmap(vfe_dev->vfe_base);
- - msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_clk_info,
- - vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_clk_info), 0);
- + if (vfe_dev->vfe_clk_idx == 1)
- + msm_cam_clk_enable(&vfe_dev->pdev->dev,
- + msm_vfe32_1_clk_info, vfe_dev->vfe_clk,
- + ARRAY_SIZE(msm_vfe32_1_clk_info), 0);
- + if (vfe_dev->vfe_clk_idx == 2)
- + msm_cam_clk_enable(&vfe_dev->pdev->dev,
- + msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
- + ARRAY_SIZE(msm_vfe32_2_clk_info), 0);
- regulator_disable(vfe_dev->fs_vfe);
- msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
- }
- @@ -113,11 +149,17 @@ static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
- /* CGC_OVERRIDE */
- msm_camera_io_w(0x07FFFFFF, vfe_dev->vfe_base + 0xC);
- /* BUS_CFG */
- - msm_camera_io_w(0x00000001, vfe_dev->vfe_base + 0x3C);
- + msm_camera_io_w(0x00000009, vfe_dev->vfe_base + 0x3C);
- msm_camera_io_w(0x01000025, vfe_dev->vfe_base + 0x1C);
- - msm_camera_io_w_mb(0x1DFFFFFF, vfe_dev->vfe_base + 0x20);
- + msm_camera_io_w_mb(0x1CFFFFFF, vfe_dev->vfe_base + 0x20);
- msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x24);
- msm_camera_io_w_mb(0x1FFFFFFF, vfe_dev->vfe_base + 0x28);
- + msm_camera_io_w(0x0, vfe_dev->vfe_base+0x6FC);
- + msm_camera_io_w( 0x10000000,vfe_dev->vfe_base + VFE32_RDI_BASE(1));
- + msm_camera_io_w( 0x10000000,vfe_dev->vfe_base + VFE32_RDI_BASE(2));
- + msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(0));
- + msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(4));
- +
- }
- static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev,
- @@ -130,23 +172,21 @@ static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev,
- static void msm_vfe32_process_halt_irq(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1)
- {
- - if (irq_status1 & BIT(24))
- - complete(&vfe_dev->halt_complete);
- }
- static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts)
- {
- + uint32_t cnt;
- if (!(irq_status0 & 0x1F))
- return;
- if (irq_status0 & BIT(0)) {
- ISP_DBG("%s: SOF IRQ\n", __func__);
- - if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
- - && vfe_dev->axi_data.src_info[VFE_PIX_0].
- - pix_stream_count == 0) {
- - msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
- + cnt = vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count;
- + if (cnt > 0) {
- + msm_isp_sof_notify(vfe_dev, VFE_RAW_0, ts);
- if (vfe_dev->axi_data.stream_update)
- msm_isp_axi_stream_update(vfe_dev);
- msm_isp_update_framedrop_reg(vfe_dev);
- @@ -215,7 +255,6 @@ static void msm_vfe32_process_violation_status(struct vfe_device *vfe_dev)
- static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
- {
- uint32_t error_status1 = vfe_dev->error_info.error_mask1;
- -
- if (error_status1 & BIT(0))
- pr_err("%s: camif error status: 0x%x\n",
- __func__, vfe_dev->error_info.camif_status);
- @@ -235,34 +274,62 @@ static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
- pr_err("%s: violation\n", __func__);
- msm_vfe32_process_violation_status(vfe_dev);
- }
- - if (error_status1 & BIT(8))
- + if (error_status1 & BIT(8)) {
- + vfe_dev->stats->imagemaster0_overflow++;
- pr_err("%s: image master 0 bus overflow\n", __func__);
- - if (error_status1 & BIT(9))
- + }
- + if (error_status1 & BIT(9)) {
- + vfe_dev->stats->imagemaster1_overflow++;
- pr_err("%s: image master 1 bus overflow\n", __func__);
- - if (error_status1 & BIT(10))
- + }
- + if (error_status1 & BIT(10)) {
- + vfe_dev->stats->imagemaster2_overflow++;
- pr_err("%s: image master 2 bus overflow\n", __func__);
- - if (error_status1 & BIT(11))
- + }
- + if (error_status1 & BIT(11)) {
- + vfe_dev->stats->imagemaster3_overflow++;
- pr_err("%s: image master 3 bus overflow\n", __func__);
- - if (error_status1 & BIT(12))
- + }
- + if (error_status1 & BIT(12)) {
- + vfe_dev->stats->imagemaster4_overflow++;
- pr_err("%s: image master 4 bus overflow\n", __func__);
- - if (error_status1 & BIT(13))
- + }
- + if (error_status1 & BIT(13)) {
- + vfe_dev->stats->imagemaster5_overflow++;
- pr_err("%s: image master 5 bus overflow\n", __func__);
- - if (error_status1 & BIT(14))
- + }
- + if (error_status1 & BIT(14)) {
- + vfe_dev->stats->imagemaster6_overflow++;
- pr_err("%s: image master 6 bus overflow\n", __func__);
- - if (error_status1 & BIT(15))
- + }
- + if (error_status1 & BIT(15)) {
- + vfe_dev->stats->bg_overflow++;
- pr_err("%s: status ae/bg bus overflow\n", __func__);
- - if (error_status1 & BIT(16))
- + }
- + if (error_status1 & BIT(16)) {
- + vfe_dev->stats->bf_overflow++;
- pr_err("%s: status af/bf bus overflow\n", __func__);
- - if (error_status1 & BIT(17))
- + }
- + if (error_status1 & BIT(17)) {
- + vfe_dev->stats->awb_overflow++;
- pr_err("%s: status awb bus overflow\n", __func__);
- - if (error_status1 & BIT(18))
- + }
- + if (error_status1 & BIT(18)) {
- + vfe_dev->stats->rs_overflow++;
- pr_err("%s: status rs bus overflow\n", __func__);
- - if (error_status1 & BIT(19))
- + }
- + if (error_status1 & BIT(19)) {
- + vfe_dev->stats->cs_overflow++;
- pr_err("%s: status cs bus overflow\n", __func__);
- - if (error_status1 & BIT(20))
- + }
- + if (error_status1 & BIT(20)) {
- + vfe_dev->stats->ihist_overflow++;
- pr_err("%s: status ihist bus overflow\n", __func__);
- - if (error_status1 & BIT(21))
- + }
- + if (error_status1 & BIT(21)) {
- + vfe_dev->stats->skinbhist_overflow++;
- pr_err("%s: status skin bhist bus overflow\n", __func__);
- + }
- if (error_status1 & BIT(22))
- pr_err("%s: axi error\n", __func__);
- }
- @@ -273,7 +340,7 @@ static void msm_vfe32_read_irq_status(struct vfe_device *vfe_dev,
- *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
- *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30);
- msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x24);
- - msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x28);
- + msm_camera_io_w_mb(*irq_status1, vfe_dev->vfe_base + 0x28);
- msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x18);
- if (*irq_status1 & BIT(0))
- @@ -319,18 +386,48 @@ static void msm_vfe32_reg_update(
- msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260);
- }
- -static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev)
- +static uint32_t msm_vfe32_reset_values[ISP_RST_MAX] =
- {
- - init_completion(&vfe_dev->reset_complete);
- - msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
- - return wait_for_completion_interruptible_timeout(
- - &vfe_dev->reset_complete, msecs_to_jiffies(50));
- + 0x3FF, /* ISP_RST_HARD reset everything */
- + 0x3EF /* ISP_RST_SOFT same as HARD RESET */
- +};
- +
- +static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev ,
- + enum msm_isp_reset_type reset_type, uint32_t blocking)
- +{
- +
- + uint32_t rst_val;
- + long rc = 0;
- + if (reset_type >= ISP_RST_MAX) {
- + pr_err("%s: Error Invalid parameter\n", __func__);
- + reset_type = ISP_RST_HARD;
- + }
- + rst_val = msm_vfe32_reset_values[reset_type];
- + if (blocking) {
- + init_completion(&vfe_dev->reset_complete);
- + msm_camera_io_w_mb(rst_val, vfe_dev->vfe_base + 0x4);
- + rc = wait_for_completion_timeout(
- + &vfe_dev->reset_complete, msecs_to_jiffies(50));
- + } else {
- + msm_camera_io_w_mb(0x3EF, vfe_dev->vfe_base + 0x4);
- + }
- + return rc;
- }
- static void msm_vfe32_axi_reload_wm(
- struct vfe_device *vfe_dev, uint32_t reload_mask)
- {
- - msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
- + if (!vfe_dev->pdev->dev.of_node) {
- + /*vfe32 A-family: 8960*/
- + msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
- + } else {
- + /*vfe32 B-family: 8610*/
- + msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x28);
- + msm_camera_io_w(0x1C800000, vfe_dev->vfe_base + 0x20);
- + msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x18);
- + msm_camera_io_w(0x9AAAAAAA , vfe_dev->vfe_base + 0x600);
- + msm_camera_io_w(reload_mask, vfe_dev->vfe_base + 0x38);
- + }
- }
- static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev,
- @@ -440,12 +537,17 @@ static void msm_vfe32_clear_framedrop(struct vfe_device *vfe_dev,
- }
- }
- -static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
- - struct msm_vfe_axi_stream *stream_info)
- +static int32_t msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
- + enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
- {
- - int bpp, bpp_reg = 0;
- + int bpp, bpp_reg = 0, pack_fmt = 0, pack_reg = 0;
- uint32_t io_format_reg;
- - bpp = msm_isp_get_bit_per_pixel(stream_info->output_format);
- + bpp = msm_isp_get_bit_per_pixel(io_format);
- + if (bpp < 0) {
- + pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
- + io_format, bpp);
- + return -EINVAL;
- + }
- switch (bpp) {
- case 8:
- @@ -457,27 +559,59 @@ static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
- case 12:
- bpp_reg = 1 << 1;
- break;
- + default:
- + pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
- + return -EINVAL;
- + }
- +
- + if (stream_src == IDEAL_RAW) {
- + pack_fmt = msm_isp_get_pack_format(io_format);
- + switch (pack_fmt) {
- + case QCOM:
- + pack_reg = 0x0;
- + break;
- + case MIPI:
- + pack_reg = 0x1;
- + break;
- + case DPCM6:
- + pack_reg = 0x2;
- + break;
- + case DPCM8:
- + pack_reg = 0x3;
- + break;
- + case PLAIN8:
- + pack_reg = 0x4;
- + break;
- + case PLAIN16:
- + pack_reg = 0x5;
- + break;
- + default:
- + pr_err("%s: invalid pack fmt!\n", __func__);
- + return -EINVAL;
- + }
- }
- +
- io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x6F8);
- - switch (stream_info->stream_src) {
- + switch (stream_src) {
- + case PIX_ENCODER:
- + case PIX_VIEWFINDER:
- case CAMIF_RAW:
- io_format_reg &= 0xFFFFCFFF;
- io_format_reg |= bpp_reg << 12;
- break;
- case IDEAL_RAW:
- io_format_reg &= 0xFFFFFFC8;
- - io_format_reg |= bpp_reg << 4;
- + io_format_reg |= bpp_reg << 4 | pack_reg;
- break;
- - case PIX_ENCODER:
- - case PIX_VIEWFINDER:
- case RDI_INTF_0:
- case RDI_INTF_1:
- case RDI_INTF_2:
- default:
- pr_err("%s: Invalid stream source\n", __func__);
- - return;
- + return -EINVAL;
- }
- msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x6F8);
- + return 0;
- }
- static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
- @@ -531,13 +665,14 @@ static void msm_vfe32_update_camif_state(
- val &= 0xFFFFFF3F;
- val = val | bus_en << 7 | vfe_en << 6;
- msm_camera_io_w(val, vfe_dev->vfe_base + 0x1E4);
- + msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x1E0);
- msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1E0);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
- } else if (update_state == DISABLE_CAMIF) {
- msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
- } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
- - msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x1E0);
- + msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x1E0);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
- }
- }
- @@ -611,6 +746,8 @@ static void msm_vfe32_axi_clear_wm_reg(
- {
- uint32_t val = 0;
- uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
- + /* FRAME BASED */
- + msm_camera_io_w(val, vfe_dev->vfe_base + wm_base);
- /*WR_IMAGE_SIZE*/
- msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
- /*WR_BUFFER_CFG*/
- @@ -686,18 +823,74 @@ static void msm_vfe32_axi_clear_wm_xbar_reg(
- msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
- }
- -static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev)
- +static void msm_vfe32_cfg_axi_ub_equal_default(struct vfe_device *vfe_dev)
- +{
- + int i;
- + uint32_t ub_offset = 0;
- + struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- + uint32_t total_image_size = 0;
- + uint32_t num_used_wms = 0;
- + uint32_t prop_size = 0;
- + uint32_t wm_ub_size;
- + uint64_t delta;
- + for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- + if (axi_data->free_wm[i] > 0) {
- + num_used_wms++;
- + total_image_size += axi_data->wm_image_size[i];
- + }
- + }
- + prop_size = MSM_ISP32_TOTAL_WM_UB -
- + axi_data->hw_info->min_wm_ub * num_used_wms;
- + for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- + if (axi_data->free_wm[i]) {
- + delta =
- + (uint64_t)(axi_data->wm_image_size[i] *
- + prop_size);
- + do_div(delta, total_image_size);
- + wm_ub_size = axi_data->hw_info->min_wm_ub +
- + (uint32_t)delta;
- + msm_camera_io_w(ub_offset << 16 |
- + (wm_ub_size - 1), vfe_dev->vfe_base +
- + VFE32_WM_BASE(i) + 0xC);
- + ub_offset += wm_ub_size;
- + } else
- + msm_camera_io_w(0,
- + vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC);
- + }
- +}
- +
- +static void msm_vfe32_cfg_axi_ub_equal_slicing(struct vfe_device *vfe_dev)
- {
- int i;
- uint32_t ub_offset = 0;
- + uint32_t final_ub_slice_size;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- - msm_camera_io_w(ub_offset << 16 | (VFE32_EQUAL_SLICE_UB - 1),
- - vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC);
- - ub_offset += VFE32_EQUAL_SLICE_UB;
- + if (ub_offset + VFE32_EQUAL_SLICE_UB > VFE32_AXI_SLICE_UB) {
- + final_ub_slice_size = VFE32_AXI_SLICE_UB - ub_offset;
- + msm_camera_io_w(ub_offset << 16 |
- + (final_ub_slice_size - 1), vfe_dev->vfe_base +
- + VFE32_WM_BASE(i) + 0xC);
- + ub_offset += final_ub_slice_size;
- + } else {
- + msm_camera_io_w(ub_offset << 16 |
- + (VFE32_EQUAL_SLICE_UB - 1), vfe_dev->vfe_base +
- + VFE32_WM_BASE(i) + 0xC);
- + ub_offset += VFE32_EQUAL_SLICE_UB;
- + }
- }
- }
- +static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev)
- +{
- + struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- + axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT;
- + if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING)
- + msm_vfe32_cfg_axi_ub_equal_slicing(vfe_dev);
- + else
- + msm_vfe32_cfg_axi_ub_equal_default(vfe_dev);
- +}
- +
- static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev,
- uint8_t wm_idx, uint32_t pingpong_status, unsigned long paddr)
- {
- @@ -705,17 +898,26 @@ static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev,
- VFE32_PING_PONG_BASE(wm_idx, pingpong_status));
- }
- -static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev)
- +static long msm_vfe32_axi_halt(struct vfe_device *vfe_dev,
- + uint32_t blocking)
- {
- uint32_t halt_mask;
- + uint32_t axi_busy_flag = false;
- + msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);
- + if (blocking) {
- + axi_busy_flag = true;
- + }
- + while (axi_busy_flag) {
- + if (msm_camera_io_r(
- + vfe_dev->vfe_base + 0x1DC) & 0x1)
- + axi_busy_flag = false;
- + }
- + msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x1D8);
- halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
- - halt_mask |= BIT(24);
- + halt_mask &= 0xFEFFFFFF;
- + /* Disable AXI IRQ */
- msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x20);
- - init_completion(&vfe_dev->halt_complete);
- - /*TD: Need to fix crashes with this*/
- - /*msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);*/
- - return wait_for_completion_interruptible_timeout(
- - &vfe_dev->halt_complete, msecs_to_jiffies(500));
- + return 0;
- }
- static uint32_t msm_vfe32_get_wm_mask(
- @@ -806,13 +1008,13 @@ static void msm_vfe32_stats_cfg_ub(struct vfe_device *vfe_dev)
- int i;
- uint32_t ub_offset = VFE32_UB_SIZE;
- uint32_t ub_size[VFE32_NUM_STATS_TYPE] = {
- - 64, /*MSM_ISP_STATS_BG*/
- - 64, /*MSM_ISP_STATS_BF*/
- - 16, /*MSM_ISP_STATS_AWB*/
- - 8, /*MSM_ISP_STATS_RS*/
- + 107, /*MSM_ISP_STATS_BG*/
- + 92, /*MSM_ISP_STATS_BF*/
- + 2, /*MSM_ISP_STATS_AWB*/
- + 7, /*MSM_ISP_STATS_RS*/
- 16, /*MSM_ISP_STATS_CS*/
- - 16, /*MSM_ISP_STATS_IHIST*/
- - 16, /*MSM_ISP_STATS_BHIST*/
- + 2, /*MSM_ISP_STATS_IHIST*/
- + 7, /*MSM_ISP_STATS_BHIST*/
- };
- for (i = 0; i < VFE32_NUM_STATS_TYPE; i++) {
- @@ -875,6 +1077,33 @@ static uint32_t msm_vfe32_stats_get_wm_mask(uint32_t irq_status0,
- return (irq_status0 >> 13) & 0x7F;
- }
- +static void msm_vfe32_get_overflow_mask(uint32_t *overflow_mask)
- +{
- + *overflow_mask = 0x002FFF7E;
- +}
- +
- +static void msm_vfe32_get_irq_mask(struct vfe_device *vfe_dev,
- + uint32_t *irq0_mask, uint32_t *irq1_mask)
- +{
- + *irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
- + *irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
- +}
- +
- +static void msm_vfe32_restore_irq_mask(struct vfe_device *vfe_dev)
- +{
- + msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
- + vfe_dev->vfe_base + 0x1C);
- + msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
- + vfe_dev->vfe_base + 0x20);
- +}
- +
- +static void msm_vfe32_get_halt_restart_mask(uint32_t *irq0_mask,
- + uint32_t *irq1_mask)
- +{
- + *irq0_mask = 0x0;
- + *irq1_mask = 0x01800000;
- +}
- +
- static uint32_t msm_vfe32_stats_get_comp_mask(uint32_t irq_status0,
- uint32_t irq_status1)
- {
- @@ -914,14 +1143,22 @@ static int msm_vfe32_get_platform_data(struct vfe_device *vfe_dev)
- goto vfe_no_resource;
- }
- - vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
- + if (!vfe_dev->pdev->dev.of_node)
- + vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
- + else
- + vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe0");
- +
- if (!vfe_dev->iommu_ctx[0]) {
- pr_err("%s: no iommux ctx resource?\n", __func__);
- rc = -ENODEV;
- goto vfe_no_resource;
- }
- - vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
- + if (!vfe_dev->pdev->dev.of_node)
- + vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
- + else
- + vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe0");
- +
- if (!vfe_dev->iommu_ctx[1]) {
- pr_err("%s: no iommux ctx resource?\n", __func__);
- rc = -ENODEV;
- @@ -940,10 +1177,11 @@ static void msm_vfe32_get_error_mask(uint32_t *error_mask0,
- }
- struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
- - .num_wm = 4,
- + .num_wm = 5,
- .num_comp_mask = 3,
- .num_rdi = 3,
- .num_rdi_master = 3,
- + .min_wm_ub = 64,
- };
- static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = {
- @@ -1019,6 +1257,11 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
- .release_hw = msm_vfe32_release_hardware,
- .get_platform_data = msm_vfe32_get_platform_data,
- .get_error_mask = msm_vfe32_get_error_mask,
- + .get_overflow_mask = msm_vfe32_get_overflow_mask,
- + .get_irq_mask = msm_vfe32_get_irq_mask,
- + .restore_irq_mask = msm_vfe32_restore_irq_mask,
- + .get_halt_restart_mask =
- + msm_vfe32_get_halt_restart_mask,
- .process_error_status = msm_vfe32_process_error_status,
- },
- .stats_ops = {
- diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
- index ac56efa..76d2118 100644
- --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
- +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -13,7 +13,7 @@
- #include <linux/module.h>
- #include <mach/iommu.h>
- #include <linux/ratelimit.h>
- -
- +#include <asm/div64.h>
- #include "msm_isp40.h"
- #include "msm_isp_util.h"
- #include "msm_isp_axi_util.h"
- @@ -30,13 +30,16 @@
- #define CDBG(fmt, args...) do { } while (0)
- #endif
- -#define VFE40_V1_VERSION 0x10000018
- -#define VFE40_V2_VERSION 0x1001001A
- +#define VFE40_8974V1_VERSION 0x10000018
- +#define VFE40_8974V2_VERSION 0x1001001A
- +#define VFE40_8974V3_VERSION 0x1001001B
- +#define VFE40_8x26_VERSION 0x20000013
- +#define VFE40_8x26V2_VERSION 0x20010014
- +
- +
- +/* STATS_SIZE (BE + BG + BF+ RS + CS + IHIST + BHIST ) = 392 */
- +#define VFE40_STATS_SIZE 392
- -#define VFE40_BURST_LEN 3
- -#define VFE40_STATS_BURST_LEN 2
- -#define VFE40_UB_SIZE 1536
- -#define VFE40_EQUAL_SLICE_UB 228
- #define VFE40_WM_BASE(idx) (0x6C + 0x24 * idx)
- #define VFE40_RDI_BASE(idx) (0x2E8 + 0x4 * idx)
- #define VFE40_XBAR_BASE(idx) (0x58 + 0x4 * (idx / 2))
- @@ -91,7 +94,10 @@ static struct msm_cam_clk_info msm_vfe40_clk_info[] = {
- static void msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev)
- {
- void __iomem *vfebase = vfe_dev->vfe_base;
- - if (vfe_dev->vfe_hw_version == VFE40_V1_VERSION) {
- +
- + if (vfe_dev->vfe_hw_version == VFE40_8974V1_VERSION ||
- + vfe_dev->vfe_hw_version == VFE40_8x26_VERSION ||
- + vfe_dev->vfe_hw_version == VFE40_8x26V2_VERSION) {
- msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_0);
- msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_1);
- msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_2);
- @@ -100,7 +106,8 @@ static void msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev)
- msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_5);
- msm_camera_io_w(0xAAAAAAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_6);
- msm_camera_io_w(0x0002AAAA, vfebase + VFE40_BUS_BDG_QOS_CFG_7);
- - } else if (vfe_dev->vfe_hw_version == VFE40_V2_VERSION) {
- + } else if (vfe_dev->vfe_hw_version == VFE40_8974V2_VERSION ||
- + vfe_dev->vfe_hw_version == VFE40_8974V3_VERSION) {
- msm_camera_io_w(0xAAA9AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_0);
- msm_camera_io_w(0xAAA9AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_1);
- msm_camera_io_w(0xAAA9AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_2);
- @@ -109,81 +116,140 @@ static void msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev)
- msm_camera_io_w(0xAAA9AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_5);
- msm_camera_io_w(0xAAA9AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_6);
- msm_camera_io_w(0x0001AAA9, vfebase + VFE40_BUS_BDG_QOS_CFG_7);
- + } else {
- + BUG();
- + pr_err("%s: QOS is NOT configured for HW Version %x\n",
- + __func__, vfe_dev->vfe_hw_version);
- }
- }
- -static void msm_vfe40_init_vbif_parms(struct vfe_device *vfe_dev)
- +static void msm_vfe40_init_vbif_parms_8974_v1(struct vfe_device *vfe_dev)
- {
- void __iomem *vfe_vbif_base = vfe_dev->vfe_vbif_base;
- - if (vfe_dev->vfe_hw_version == VFE40_V1_VERSION) {
- - msm_camera_io_w(0x1,
- - vfe_vbif_base + VFE40_VBIF_CLKON);
- - msm_camera_io_w(0x01010101,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- - msm_camera_io_w(0x01010101,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- - msm_camera_io_w(0x10010110,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
- - msm_camera_io_w(0x00001010,
- - vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- - msm_camera_io_w(0x00001010,
- - vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- - msm_camera_io_w(0x00000707,
- - vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- - msm_camera_io_w(0x00000707,
- - vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
- - msm_camera_io_w(0x00000030,
- - vfe_vbif_base + VFE40_VBIF_ARB_CTL);
- - msm_camera_io_w(0x00000FFF,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- - msm_camera_io_w(0x0FFF0FFF,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
- - msm_camera_io_w(0x00000001,
- - vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- - msm_camera_io_w(0x22222222,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
- - msm_camera_io_w(0x00002222,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
- - } else if (vfe_dev->vfe_hw_version == VFE40_V2_VERSION) {
- - msm_camera_io_w(0x1,
- - vfe_vbif_base + VFE40_VBIF_CLKON);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- - msm_camera_io_w(0x10101010,
- - vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
- - msm_camera_io_w(0x00000010,
- - vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- - msm_camera_io_w(0x00000010,
- - vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- - msm_camera_io_w(0x00000707,
- - vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- - msm_camera_io_w(0x00000010,
- - vfe_vbif_base + VFE40_VBIF_ARB_CTL);
- - msm_camera_io_w(0x00000FFF,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- - msm_camera_io_w(0x0FFF0FFF,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
- - msm_camera_io_w(0x00000003,
- - vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- - msm_camera_io_w(0x22222222,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
- - msm_camera_io_w(0x00002222,
- - vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
- + msm_camera_io_w(0x1,
- + vfe_vbif_base + VFE40_VBIF_CLKON);
- + msm_camera_io_w(0x01010101,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- + msm_camera_io_w(0x01010101,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- + msm_camera_io_w(0x10010110,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
- + msm_camera_io_w(0x00001010,
- + vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- + msm_camera_io_w(0x00001010,
- + vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- + msm_camera_io_w(0x00000707,
- + vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- + msm_camera_io_w(0x00000707,
- + vfe_vbif_base + VFE40_VBIF_OCMEM_OUT_MAX_BURST);
- + msm_camera_io_w(0x00000030,
- + vfe_vbif_base + VFE40_VBIF_ARB_CTL);
- + msm_camera_io_w(0x00000FFF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- + msm_camera_io_w(0x0FFF0FFF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
- + msm_camera_io_w(0x00000001,
- + vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- + msm_camera_io_w(0x22222222,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
- + msm_camera_io_w(0x00002222,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
- + return;
- +}
- +
- +static void msm_vfe40_init_vbif_parms_8974_v2(struct vfe_device *vfe_dev)
- +{
- + void __iomem *vfe_vbif_base = vfe_dev->vfe_vbif_base;
- + msm_camera_io_w(0x1,
- + vfe_vbif_base + VFE40_VBIF_CLKON);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF2);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF2);
- + msm_camera_io_w(0x00000010,
- + vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- + msm_camera_io_w(0x00000010,
- + vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- + msm_camera_io_w(0x00000707,
- + vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- + msm_camera_io_w(0x00000010,
- + vfe_vbif_base + VFE40_VBIF_ARB_CTL);
- + msm_camera_io_w(0x00000FFF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- + msm_camera_io_w(0x0FFF0FFF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
- + msm_camera_io_w(0x00000003,
- + vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- + msm_camera_io_w(0x22222222,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
- + msm_camera_io_w(0x00002222,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1);
- + return;
- +}
- +
- +static void msm_vfe40_init_vbif_parms_8x26(struct vfe_device *vfe_dev)
- +{
- + void __iomem *vfe_vbif_base = vfe_dev->vfe_vbif_base;
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF0);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_RD_LIM_CONF1);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF0);
- + msm_camera_io_w(0x10101010,
- + vfe_vbif_base + VFE40_VBIF_IN_WR_LIM_CONF1);
- + msm_camera_io_w(0x00000010,
- + vfe_vbif_base + VFE40_VBIF_OUT_RD_LIM_CONF0);
- + msm_camera_io_w(0x00000010,
- + vfe_vbif_base + VFE40_VBIF_OUT_WR_LIM_CONF0);
- + msm_camera_io_w(0x00000707,
- + vfe_vbif_base + VFE40_VBIF_DDR_OUT_MAX_BURST);
- + msm_camera_io_w(0x000000FF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO_EN);
- + msm_camera_io_w(0x00FF00FF,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AOOO);
- + msm_camera_io_w(0x00000003,
- + vfe_vbif_base + VFE40_VBIF_ROUND_ROBIN_QOS_ARB);
- + msm_camera_io_w(0x22222222,
- + vfe_vbif_base + VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0);
- + return;
- +}
- +
- +static void msm_vfe40_init_vbif_parms(struct vfe_device *vfe_dev)
- +{
- + switch (vfe_dev->vfe_hw_version) {
- + case VFE40_8974V1_VERSION:
- + msm_vfe40_init_vbif_parms_8974_v1(vfe_dev);
- + break;
- + case VFE40_8974V2_VERSION:
- + case VFE40_8974V3_VERSION:
- + msm_vfe40_init_vbif_parms_8974_v2(vfe_dev);
- + break;
- + case VFE40_8x26_VERSION:
- + case VFE40_8x26V2_VERSION:
- + msm_vfe40_init_vbif_parms_8x26(vfe_dev);
- + break;
- + default:
- + BUG();
- + pr_err("%s: VBIF is NOT configured for HW Version %x\n",
- + __func__, vfe_dev->vfe_hw_version);
- + break;
- }
- +
- }
- static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
- @@ -202,6 +268,8 @@ static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
- goto fs_failed;
- }
- }
- + else
- + goto fs_failed;
- rc = msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
- vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe40_clk_info), 1);
- @@ -224,6 +292,14 @@ static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
- goto vbif_remap_failed;
- }
- + vfe_dev->tcsr_base = ioremap(vfe_dev->tcsr_mem->start,
- + resource_size(vfe_dev->tcsr_mem));
- + if (!vfe_dev->tcsr_base) {
- + rc = -ENOMEM;
- + pr_err("%s: tcsr ioremap failed\n", __func__);
- + goto tcsr_remap_failed;
- + }
- +
- rc = request_irq(vfe_dev->vfe_irq->start, msm_isp_process_irq,
- IRQF_TRIGGER_RISING, "vfe", vfe_dev);
- if (rc < 0) {
- @@ -232,6 +308,8 @@ static int msm_vfe40_init_hardware(struct vfe_device *vfe_dev)
- }
- return rc;
- irq_req_failed:
- + iounmap(vfe_dev->tcsr_base);
- +tcsr_remap_failed:
- iounmap(vfe_dev->vfe_vbif_base);
- vbif_remap_failed:
- iounmap(vfe_dev->vfe_base);
- @@ -250,6 +328,7 @@ static void msm_vfe40_release_hardware(struct vfe_device *vfe_dev)
- {
- free_irq(vfe_dev->vfe_irq->start, vfe_dev);
- tasklet_kill(&vfe_dev->vfe_tasklet);
- + iounmap(vfe_dev->tcsr_base);
- iounmap(vfe_dev->vfe_vbif_base);
- iounmap(vfe_dev->vfe_base);
- msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe40_clk_info,
- @@ -271,6 +350,12 @@ static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
- msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x2C);
- msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
- msm_camera_io_w_mb(0xFEFFFFFF, vfe_dev->vfe_base + 0x34);
- + msm_camera_io_w(vfe_dev->stats_data.stats_mask,
- + vfe_dev->vfe_base + 0x44);
- + msm_camera_io_w(1, vfe_dev->vfe_base + 0x24);
- + msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
- + msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x34);
- + msm_camera_io_w(1, vfe_dev->vfe_base + 0x24);
- }
- static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
- @@ -283,23 +368,22 @@ static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
- static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1)
- {
- - if (irq_status1 & (1 << 8))
- - complete(&vfe_dev->halt_complete);
- }
- static void msm_vfe40_process_camif_irq(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts)
- {
- + int cnt;
- +
- if (!(irq_status0 & 0xF))
- return;
- if (irq_status0 & (1 << 0)) {
- ISP_DBG("%s: SOF IRQ\n", __func__);
- - if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
- - && vfe_dev->axi_data.src_info[VFE_PIX_0].
- - pix_stream_count == 0) {
- - msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
- + cnt = vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count;
- + if (cnt > 0) {
- + msm_isp_sof_notify(vfe_dev, VFE_RAW_0, ts);
- if (vfe_dev->axi_data.stream_update)
- msm_isp_axi_stream_update(vfe_dev);
- msm_isp_update_framedrop_reg(vfe_dev);
- @@ -380,65 +464,94 @@ static void msm_vfe40_process_violation_status(
- static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev)
- {
- - uint32_t halt_mask;
- uint32_t error_status1 = vfe_dev->error_info.error_mask1;
- - struct msm_isp_event_data error_event;
- - if (error_status1 & (1 << 0)) {
- - pr_err("%s: camif error status: 0x%x\n",
- + if (error_status1 & (1 << 0))
- + pr_err_ratelimited("%s: camif error status: 0x%x\n",
- __func__, vfe_dev->error_info.camif_status);
- - error_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
- - msm_isp_send_event(vfe_dev, ISP_EVENT_ERROR, &error_event);
- - halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
- - halt_mask &= ~(1 << 8);
- - msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x2C);
- - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
- - }
- if (error_status1 & (1 << 1))
- - pr_err("%s: stats bhist overwrite\n", __func__);
- + pr_err_ratelimited("%s: stats bhist overwrite\n", __func__);
- if (error_status1 & (1 << 2))
- - pr_err("%s: stats cs overwrite\n", __func__);
- + pr_err_ratelimited("%s: stats cs overwrite\n", __func__);
- if (error_status1 & (1 << 3))
- - pr_err("%s: stats ihist overwrite\n", __func__);
- + pr_err_ratelimited("%s: stats ihist overwrite\n", __func__);
- if (error_status1 & (1 << 4))
- - pr_err("%s: realign buf y overflow\n", __func__);
- + pr_err_ratelimited("%s: realign buf y overflow\n", __func__);
- if (error_status1 & (1 << 5))
- - pr_err("%s: realign buf cb overflow\n", __func__);
- + pr_err_ratelimited("%s: realign buf cb overflow\n", __func__);
- if (error_status1 & (1 << 6))
- - pr_err("%s: realign buf cr overflow\n", __func__);
- + pr_err_ratelimited("%s: realign buf cr overflow\n", __func__);
- if (error_status1 & (1 << 7)) {
- - pr_err("%s: violation\n", __func__);
- + pr_err_ratelimited("%s: violation\n", __func__);
- msm_vfe40_process_violation_status(vfe_dev);
- }
- - if (error_status1 & (1 << 9))
- - pr_err("%s: image master 0 bus overflow\n", __func__);
- - if (error_status1 & (1 << 10))
- - pr_err("%s: image master 1 bus overflow\n", __func__);
- - if (error_status1 & (1 << 11))
- - pr_err("%s: image master 2 bus overflow\n", __func__);
- - if (error_status1 & (1 << 12))
- - pr_err("%s: image master 3 bus overflow\n", __func__);
- - if (error_status1 & (1 << 13))
- - pr_err("%s: image master 4 bus overflow\n", __func__);
- - if (error_status1 & (1 << 14))
- - pr_err("%s: image master 5 bus overflow\n", __func__);
- - if (error_status1 & (1 << 15))
- - pr_err("%s: image master 6 bus overflow\n", __func__);
- - if (error_status1 & (1 << 16))
- - pr_err("%s: status be bus overflow\n", __func__);
- - if (error_status1 & (1 << 17))
- - pr_err("%s: status bg bus overflow\n", __func__);
- - if (error_status1 & (1 << 18))
- - pr_err("%s: status bf bus overflow\n", __func__);
- - if (error_status1 & (1 << 19))
- - pr_err("%s: status awb bus overflow\n", __func__);
- - if (error_status1 & (1 << 20))
- - pr_err("%s: status rs bus overflow\n", __func__);
- - if (error_status1 & (1 << 21))
- - pr_err("%s: status cs bus overflow\n", __func__);
- - if (error_status1 & (1 << 22))
- - pr_err("%s: status ihist bus overflow\n", __func__);
- - if (error_status1 & (1 << 23))
- - pr_err("%s: status skin bhist bus overflow\n", __func__);
- + if (error_status1 & (1 << 9)) {
- + vfe_dev->stats->imagemaster0_overflow++;
- + pr_err_ratelimited("%s: image master 0 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 10)) {
- + vfe_dev->stats->imagemaster1_overflow++;
- + pr_err_ratelimited("%s: image master 1 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 11)) {
- + vfe_dev->stats->imagemaster2_overflow++;
- + pr_err_ratelimited("%s: image master 2 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 12)) {
- + vfe_dev->stats->imagemaster3_overflow++;
- + pr_err_ratelimited("%s: image master 3 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 13)) {
- + vfe_dev->stats->imagemaster4_overflow++;
- + pr_err_ratelimited("%s: image master 4 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 14)) {
- + vfe_dev->stats->imagemaster5_overflow++;
- + pr_err_ratelimited("%s: image master 5 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 15)) {
- + vfe_dev->stats->imagemaster6_overflow++;
- + pr_err_ratelimited("%s: image master 6 bus overflow\n",
- + __func__);
- + }
- + if (error_status1 & (1 << 16)) {
- + vfe_dev->stats->be_overflow++;
- + pr_err_ratelimited("%s: status be bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 17)) {
- + vfe_dev->stats->bg_overflow++;
- + pr_err_ratelimited("%s: status bg bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 18)) {
- + vfe_dev->stats->bf_overflow++;
- + pr_err_ratelimited("%s: status bf bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 19)) {
- + vfe_dev->stats->awb_overflow++;
- + pr_err_ratelimited("%s: status awb bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 20)) {
- + vfe_dev->stats->imagemaster0_overflow++;
- + pr_err_ratelimited("%s: status rs bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 21)) {
- + vfe_dev->stats->cs_overflow++;
- + pr_err_ratelimited("%s: status cs bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 22)) {
- + vfe_dev->stats->ihist_overflow++;
- + pr_err_ratelimited("%s: status ihist bus overflow\n", __func__);
- + }
- + if (error_status1 & (1 << 23)) {
- + vfe_dev->stats->skinbhist_overflow++;
- + pr_err_ratelimited("%s: status skin bhist bus overflow\n",
- + __func__);
- + }
- }
- static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
- @@ -446,9 +559,11 @@ static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
- {
- *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
- *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
- - if (*irq_status0 & 0x6000000)
- - *irq_status0 &= ~(0x18000000);
- -
- + /*
- + * Ignore composite 2/3 irq which is used for dual VFE only
- + */
- + if (*irq_status0 & 0x6000000)
- + *irq_status0 &= ~(0x18000000);
- msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
- msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34);
- msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
- @@ -456,6 +571,7 @@ static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
- pr_err_ratelimited("%s: Protection triggered\n", __func__);
- *irq_status0 &= ~(0x18000000);
- }
- +
- if (*irq_status1 & (1 << 0))
- vfe_dev->error_info.camif_status =
- msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
- @@ -500,12 +616,32 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev)
- msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x378);
- }
- -static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev)
- +static uint32_t msm_vfe40_reset_values[ISP_RST_MAX] =
- +{
- + 0x1FF, /* ISP_RST_HARD reset everything */
- + 0x1EF /* ISP_RST_SOFT all modules without registers */
- +};
- +
- +
- +static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev ,
- + enum msm_isp_reset_type reset_type, uint32_t blocking)
- {
- + uint32_t rst_val;
- + long rc = 0;
- + if (reset_type >= ISP_RST_MAX) {
- + pr_err("%s: Error Invalid parameter\n", __func__);
- + reset_type = ISP_RST_HARD;
- + }
- + rst_val = msm_vfe40_reset_values[reset_type];
- init_completion(&vfe_dev->reset_complete);
- - msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
- - return wait_for_completion_interruptible_timeout(
- - &vfe_dev->reset_complete, msecs_to_jiffies(50));
- + if (blocking) {
- + msm_camera_io_w_mb(rst_val, vfe_dev->vfe_base + 0xC);
- + rc = wait_for_completion_timeout(
- + &vfe_dev->reset_complete, msecs_to_jiffies(50));
- + } else {
- + msm_camera_io_w_mb(0x1EF, vfe_dev->vfe_base + 0xC);
- + }
- + return rc;
- }
- static void msm_vfe40_axi_reload_wm(
- @@ -539,17 +675,29 @@ static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
- comp_mask &= ~(0x7F << (comp_mask_index * 8));
- comp_mask |= (axi_data->composite_info[comp_mask_index].
- stream_composite_mask << (comp_mask_index * 8));
- +
- + irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
- + irq_mask |= 1 << (comp_mask_index + 25);
- +
- + /*
- + * For dual VFE, composite 2/3 interrupt is used to trigger
- + * microcontroller to update certain VFE registers
- + */
- if (stream_info->plane_cfg[0].plane_addr_offset &&
- - stream_info->stream_type == CONTINUOUS_STREAM) {
- + stream_info->stream_src == PIX_VIEWFINDER) {
- + comp_mask |= (axi_data->composite_info[comp_mask_index].
- + stream_composite_mask << 16);
- + irq_mask |= BIT(27);
- + }
- +
- + if (stream_info->plane_cfg[0].plane_addr_offset &&
- + stream_info->stream_src == PIX_ENCODER) {
- comp_mask |= (axi_data->composite_info[comp_mask_index].
- stream_composite_mask << 24);
- + irq_mask |= BIT(28);
- }
- +
- msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
- - printk("%s comp mask:0x%x\n", __func__, comp_mask);
- - irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
- - irq_mask |= 1 << (comp_mask_index + 25);
- - if (stream_info->plane_cfg[0].plane_addr_offset && (comp_mask >> 24))
- - irq_mask |= 0x10000000;
- msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
- }
- @@ -558,24 +706,29 @@ static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
- {
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
- - uint32_t irq_mask, cur_comp_mask;
- + uint32_t irq_mask;
- comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
- - cur_comp_mask = (comp_mask >> (comp_mask_index * 8)) & 0x7F;
- comp_mask &= ~(0x7F << (comp_mask_index * 8));
- - comp_mask &= ~(cur_comp_mask << 24);
- +
- + irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
- + irq_mask &= ~(1 << (comp_mask_index + 25));
- +
- + if (stream_info->plane_cfg[0].plane_addr_offset &&
- + stream_info->stream_src == PIX_VIEWFINDER) {
- + comp_mask &= ~(axi_data->composite_info[comp_mask_index].
- + stream_composite_mask << 16);
- + irq_mask &= ~BIT(27);
- + }
- +
- if (stream_info->plane_cfg[0].plane_addr_offset &&
- - stream_info->stream_type == CONTINUOUS_STREAM) {
- + stream_info->stream_src == PIX_ENCODER) {
- comp_mask &= ~(axi_data->composite_info[comp_mask_index].
- stream_composite_mask << 24);
- + irq_mask &= ~BIT(28);
- }
- - msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
- - printk("%s comp mask:0x%x\n", __func__, comp_mask);
- - irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
- - irq_mask &= ~(1 << (comp_mask_index + 25));
- - if (stream_info->plane_cfg[0].plane_addr_offset && !(comp_mask >> 24))
- - irq_mask &= ~(0x10000000);
- + msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
- msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x28);
- }
- @@ -636,12 +789,18 @@ static void msm_vfe40_clear_framedrop(struct vfe_device *vfe_dev,
- VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
- }
- -static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
- - struct msm_vfe_axi_stream *stream_info)
- +static int32_t msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
- + enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
- {
- - int bpp, bpp_reg = 0;
- - uint32_t io_format_reg;
- - bpp = msm_isp_get_bit_per_pixel(stream_info->output_format);
- + int bpp, bpp_reg = 0, pack_reg = 0;
- + enum msm_isp_pack_fmt pack_fmt = 0;
- + uint32_t io_format_reg; /*io format register bit*/
- + bpp = msm_isp_get_bit_per_pixel(io_format);
- + if (bpp < 0) {
- + pr_err("%s:%d invalid io_format %d bpp %d", __func__, __LINE__,
- + io_format, bpp);
- + return -EINVAL;
- + }
- switch (bpp) {
- case 8:
- @@ -653,27 +812,60 @@ static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
- case 12:
- bpp_reg = 1 << 1;
- break;
- + default:
- + pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
- + return -EINVAL;
- }
- +
- + if (stream_src == IDEAL_RAW) {
- + /*use io_format(v4l2_pix_fmt) to get pack format*/
- + pack_fmt = msm_isp_get_pack_format(io_format);
- + switch (pack_fmt) {
- + case QCOM:
- + pack_reg = 0x0;
- + break;
- + case MIPI:
- + pack_reg = 0x1;
- + break;
- + case DPCM6:
- + pack_reg = 0x2;
- + break;
- + case DPCM8:
- + pack_reg = 0x3;
- + break;
- + case PLAIN8:
- + pack_reg = 0x4;
- + break;
- + case PLAIN16:
- + pack_reg = 0x5;
- + break;
- + default:
- + pr_err("%s: invalid pack fmt!\n", __func__);
- + return -EINVAL;
- + }
- + }
- +
- io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
- - switch (stream_info->stream_src) {
- + switch (stream_src) {
- + case PIX_ENCODER:
- + case PIX_VIEWFINDER:
- case CAMIF_RAW:
- io_format_reg &= 0xFFFFCFFF;
- io_format_reg |= bpp_reg << 12;
- break;
- case IDEAL_RAW:
- io_format_reg &= 0xFFFFFFC8;
- - io_format_reg |= bpp_reg << 4;
- + io_format_reg |= bpp_reg << 4 | pack_reg;
- break;
- - case PIX_ENCODER:
- - case PIX_VIEWFINDER:
- case RDI_INTF_0:
- case RDI_INTF_1:
- case RDI_INTF_2:
- default:
- pr_err("%s: Invalid stream source\n", __func__);
- - return;
- + return -EINVAL;
- }
- msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
- + return 0;
- }
- static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
- @@ -742,13 +934,14 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
- val &= 0xFFFFFF3F;
- val = val | bus_en << 7 | vfe_en << 6;
- msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
- + msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x2F4);
- msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
- } else if (update_state == DISABLE_CAMIF) {
- msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
- } else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
- - msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x2F4);
- + msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4);
- vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
- }
- }
- @@ -780,9 +973,15 @@ static void msm_vfe40_axi_cfg_wm_reg(
- uint8_t plane_idx)
- {
- uint32_t val;
- +
- + struct msm_vfe_axi_shared_data *axi_data =
- + &vfe_dev->axi_data;
- + uint32_t burst_len = axi_data->burst_len;
- +
- uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
- if (!stream_info->frame_based) {
- + msm_camera_io_w(0x0, vfe_dev->vfe_base + wm_base);
- /*WR_IMAGE_SIZE*/
- val =
- ((msm_isp_cal_word_per_line(
- @@ -800,7 +999,7 @@ static void msm_vfe40_axi_cfg_wm_reg(
- plane_idx].output_stride) << 16 |
- (stream_info->plane_cfg[
- plane_idx].output_height - 1) << 4 |
- - VFE40_BURST_LEN;
- + burst_len;
- msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
- } else {
- msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
- @@ -810,7 +1009,7 @@ static void msm_vfe40_axi_cfg_wm_reg(
- plane_idx].output_width) << 16 |
- (stream_info->plane_cfg[
- plane_idx].output_height - 1) << 4 |
- - VFE40_BURST_LEN;
- + burst_len;
- msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
- }
- @@ -925,7 +1124,7 @@ static void msm_vfe40_cfg_axi_ub_equal_default(
- uint8_t num_used_wms = 0;
- uint32_t prop_size = 0;
- uint32_t wm_ub_size;
- - uint32_t delta;
- + uint32_t axi_wm_ub;
- for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- if (axi_data->free_wm[i] > 0) {
- @@ -933,13 +1132,17 @@ static void msm_vfe40_cfg_axi_ub_equal_default(
- total_image_size += axi_data->wm_image_size[i];
- }
- }
- - prop_size = MSM_ISP40_TOTAL_WM_UB -
- + axi_wm_ub = vfe_dev->vfe_ub_size - VFE40_STATS_SIZE;
- +
- + prop_size = axi_wm_ub -
- axi_data->hw_info->min_wm_ub * num_used_wms;
- for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- if (axi_data->free_wm[i]) {
- - delta =
- - (axi_data->wm_image_size[i] *
- - prop_size)/total_image_size;
- + uint64_t delta = 0;
- + uint64_t temp = (uint64_t)axi_data->wm_image_size[i] *
- + (uint64_t)prop_size;
- + do_div(temp, total_image_size);
- + delta = temp;
- wm_ub_size = axi_data->hw_info->min_wm_ub + delta;
- msm_camera_io_w(ub_offset << 16 | (wm_ub_size - 1),
- vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
- @@ -956,17 +1159,21 @@ static void msm_vfe40_cfg_axi_ub_equal_slicing(
- int i;
- uint32_t ub_offset = 0;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- + uint32_t axi_equal_slice_ub =
- + (vfe_dev->vfe_ub_size - VFE40_STATS_SIZE)/
- + (axi_data->hw_info->num_wm - 1);
- +
- for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- - msm_camera_io_w(ub_offset << 16 | (VFE40_EQUAL_SLICE_UB - 1),
- + msm_camera_io_w(ub_offset << 16 | (axi_equal_slice_ub - 1),
- vfe_dev->vfe_base + VFE40_WM_BASE(i) + 0x10);
- - ub_offset += VFE40_EQUAL_SLICE_UB;
- + ub_offset += axi_equal_slice_ub;
- }
- }
- static void msm_vfe40_cfg_axi_ub(struct vfe_device *vfe_dev)
- {
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- - axi_data->wm_ub_cfg_policy = MSM_WM_UB_EQUAL_SLICING;
- + axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT;
- if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING)
- msm_vfe40_cfg_axi_ub_equal_slicing(vfe_dev);
- else
- @@ -981,16 +1188,31 @@ static void msm_vfe40_update_ping_pong_addr(
- VFE40_PING_PONG_BASE(wm_idx, pingpong_status));
- }
- -static long msm_vfe40_axi_halt(struct vfe_device *vfe_dev)
- +static long msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
- + uint32_t blocking)
- {
- - uint32_t halt_mask;
- - halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
- - halt_mask |= (1 << 8);
- - msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x2C);
- - init_completion(&vfe_dev->halt_complete);
- - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
- - return wait_for_completion_interruptible_timeout(
- - &vfe_dev->halt_complete, msecs_to_jiffies(500));
- + long rc = 0;
- + uint32_t axi_busy_flag = true;
- + /* Keep only restart mask and halt mask*/
- + msm_camera_io_w(BIT(31), vfe_dev->vfe_base + 0x28);
- + msm_camera_io_w(BIT(8), vfe_dev->vfe_base + 0x2C);
- + /* Clear IRQ Status*/
- + msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
- + msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
- + msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
- + if (blocking) {
- + init_completion(&vfe_dev->halt_complete);
- + /* Halt AXI Bus Bridge */
- + msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
- + atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
- + while (axi_busy_flag) {
- + if (msm_camera_io_r(
- + vfe_dev->vfe_base + 0x2E4) & 0x1)
- + axi_busy_flag = false;
- + }
- + }
- + msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C0);
- + return rc;
- }
- static uint32_t msm_vfe40_get_wm_mask(
- @@ -999,6 +1221,33 @@ static uint32_t msm_vfe40_get_wm_mask(
- return (irq_status0 >> 8) & 0x7F;
- }
- +static void msm_vfe40_get_overflow_mask(uint32_t *overflow_mask)
- +{
- + *overflow_mask = 0x00FFFE7E;
- +}
- +
- +static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev,
- + uint32_t *irq0_mask, uint32_t *irq1_mask)
- +{
- + *irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x28);
- + *irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
- +}
- +
- +static void msm_vfe40_restore_irq_mask(struct vfe_device *vfe_dev)
- +{
- + msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
- + vfe_dev->vfe_base + 0x28);
- + msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
- + vfe_dev->vfe_base + 0x2C);
- +}
- +
- +static void msm_vfe40_get_halt_restart_mask(uint32_t *irq0_mask,
- + uint32_t *irq1_mask)
- +{
- + *irq0_mask = BIT(31);
- + *irq1_mask = BIT(8);
- +}
- +
- static uint32_t msm_vfe40_get_comp_mask(
- uint32_t irq_status0, uint32_t irq_status1)
- {
- @@ -1046,6 +1295,7 @@ static void msm_vfe40_stats_cfg_comp_mask(struct vfe_device *vfe_dev,
- else
- comp_mask &= ~stats_mask;
- msm_camera_io_w(comp_mask << 16, vfe_dev->vfe_base + 0x44);
- + vfe_dev->stats_data.stats_mask = (comp_mask << 16);
- }
- static void msm_vfe40_stats_cfg_wm_irq_mask(
- @@ -1105,7 +1355,11 @@ static void msm_vfe40_stats_clear_wm_reg(
- static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
- {
- int i;
- - uint32_t ub_offset = VFE40_UB_SIZE;
- + struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
- + uint32_t ub_offset = vfe_dev->vfe_ub_size;
- + uint32_t stats_burst_len = stats_data->stats_burst_len;
- +
- +
- uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
- 64, /*MSM_ISP_STATS_BE*/
- 128, /*MSM_ISP_STATS_BG*/
- @@ -1119,7 +1373,7 @@ static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
- for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
- ub_offset -= ub_size[i];
- - msm_camera_io_w(VFE40_STATS_BURST_LEN << 30 |
- + msm_camera_io_w(stats_burst_len << 30 |
- ub_offset << 16 | (ub_size[i] - 1),
- vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
- }
- @@ -1210,6 +1464,14 @@ static int msm_vfe40_get_platform_data(struct vfe_device *vfe_dev)
- goto vfe_no_resource;
- }
- + vfe_dev->tcsr_mem = platform_get_resource_byname(vfe_dev->pdev,
- + IORESOURCE_MEM, "tcsr");
- + if (!vfe_dev->tcsr_mem) {
- + pr_err("%s: no mem resource?\n", __func__);
- + rc = -ENODEV;
- + goto vfe_no_resource;
- + }
- +
- vfe_dev->vfe_irq = platform_get_resource_byname(vfe_dev->pdev,
- IORESOURCE_IRQ, "vfe");
- if (!vfe_dev->vfe_irq) {
- @@ -1247,8 +1509,8 @@ static void msm_vfe40_get_error_mask(
- }
- static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = {
- - .num_wm = 5,
- - .num_comp_mask = 2,
- + .num_wm = 7,
- + .num_comp_mask = 3,
- .num_rdi = 3,
- .num_rdi_master = 3,
- .min_wm_ub = 64,
- @@ -1327,6 +1589,11 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
- .release_hw = msm_vfe40_release_hardware,
- .get_platform_data = msm_vfe40_get_platform_data,
- .get_error_mask = msm_vfe40_get_error_mask,
- + .get_overflow_mask = msm_vfe40_get_overflow_mask,
- + .get_irq_mask = msm_vfe40_get_irq_mask,
- + .restore_irq_mask = msm_vfe40_restore_irq_mask,
- + .get_halt_restart_mask =
- + msm_vfe40_get_halt_restart_mask,
- .process_error_status = msm_vfe40_process_error_status,
- },
- .stats_ops = {
- diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
- index 2fea23b..8e805ed 100644
- --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
- +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -11,6 +11,7 @@
- */
- #include <linux/io.h>
- #include <media/v4l2-subdev.h>
- +#include <asm/div64.h>
- #include "msm_isp_util.h"
- #include "msm_isp_axi_util.h"
- @@ -20,6 +21,9 @@
- #define HANDLE_TO_IDX(handle) (handle & 0xFF)
- +#define MSM_ISP_MIN_AB 450000000
- +#define MSM_ISP_MIN_IB 900000000
- +
- int msm_isp_axi_create_stream(
- struct msm_vfe_axi_shared_data *axi_data,
- struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
- @@ -68,11 +72,23 @@ int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data,
- struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
- {
- int rc = -1, i;
- - struct msm_vfe_axi_stream *stream_info =
- - &axi_data->stream_info[
- - HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
- + struct msm_vfe_axi_stream *stream_info = NULL;
- + uint32_t idx = 0;
- +
- + if (NULL == stream_cfg_cmd || NULL == axi_data)
- + return rc;
- +
- + idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
- + if (idx < MAX_NUM_STREAM)
- + stream_info = &axi_data->stream_info[idx];
- + else
- + return rc;
- switch (stream_cfg_cmd->output_format) {
- + case V4L2_PIX_FMT_YUYV:
- + case V4L2_PIX_FMT_YVYU:
- + case V4L2_PIX_FMT_UYVY:
- + case V4L2_PIX_FMT_VYUY:
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SGBRG8:
- case V4L2_PIX_FMT_SGRBG8:
- @@ -97,7 +113,7 @@ int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data,
- case V4L2_PIX_FMT_QGBRG12:
- case V4L2_PIX_FMT_QGRBG12:
- case V4L2_PIX_FMT_QRGGB12:
- - case V4L2_PIX_FMT_JPEG:
- + case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_META:
- stream_info->num_planes = 1;
- stream_info->format_factor = ISP_Q2;
- @@ -159,6 +175,10 @@ static uint32_t msm_isp_axi_get_plane_size(
- uint32_t size = 0;
- struct msm_vfe_axi_plane_cfg *plane_cfg = stream_info->plane_cfg;
- switch (stream_info->output_format) {
- + case V4L2_PIX_FMT_YUYV:
- + case V4L2_PIX_FMT_YVYU:
- + case V4L2_PIX_FMT_UYVY:
- + case V4L2_PIX_FMT_VYUY:
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SGBRG8:
- case V4L2_PIX_FMT_SGRBG8:
- @@ -167,7 +187,7 @@ static uint32_t msm_isp_axi_get_plane_size(
- case V4L2_PIX_FMT_QGBRG8:
- case V4L2_PIX_FMT_QGRBG8:
- case V4L2_PIX_FMT_QRGGB8:
- - case V4L2_PIX_FMT_JPEG:
- + case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_META:
- size = plane_cfg[plane_idx].output_height *
- plane_cfg[plane_idx].output_width;
- @@ -203,7 +223,7 @@ static uint32_t msm_isp_axi_get_plane_size(
- plane_cfg[plane_idx].output_width;
- else
- size = plane_cfg[plane_idx].output_height *
- - plane_cfg[plane_idx].output_width / 2;
- + plane_cfg[plane_idx].output_width;
- break;
- case V4L2_PIX_FMT_NV14:
- case V4L2_PIX_FMT_NV41:
- @@ -212,7 +232,7 @@ static uint32_t msm_isp_axi_get_plane_size(
- plane_cfg[plane_idx].output_width;
- else
- size = plane_cfg[plane_idx].output_height *
- - plane_cfg[plane_idx].output_width / 8;
- + plane_cfg[plane_idx].output_width;
- break;
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- @@ -227,6 +247,21 @@ static uint32_t msm_isp_axi_get_plane_size(
- return size;
- }
- +static void msm_isp_get_buffer_ts(struct vfe_device *vfe_dev,
- + struct msm_isp_timestamp *irq_ts, struct msm_isp_timestamp *ts)
- +{
- + struct msm_vfe_frame_ts *frame_ts = &vfe_dev->frame_ts;
- + uint32_t frame_count = vfe_dev->error_info.info_dump_frame_count;
- +
- + *ts = *irq_ts;
- + if (frame_count == frame_ts->frame_id) {
- + ts->buf_time = frame_ts->buf_time;
- + } else {
- + frame_ts->buf_time = irq_ts->buf_time;
- + frame_ts->frame_id = frame_count;
- + }
- +}
- +
- void msm_isp_axi_reserve_wm(struct msm_vfe_axi_shared_data *axi_data,
- struct msm_vfe_axi_stream *stream_info)
- {
- @@ -301,8 +336,13 @@ int msm_isp_axi_check_stream_state(
- enum msm_vfe_axi_state valid_state =
- (stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;
- + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
- + return -EINVAL;
- + }
- +
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= MAX_NUM_STREAM) {
- + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >=
- + MAX_NUM_STREAM) {
- return -EINVAL;
- }
- stream_info = &axi_data->stream_info[
- @@ -313,12 +353,14 @@ int msm_isp_axi_check_stream_state(
- stream_info->state == PAUSED ||
- stream_info->state == RESUME_PENDING ||
- stream_info->state == RESUMING) &&
- - stream_cfg_cmd->cmd == STOP_STREAM) {
- + (stream_cfg_cmd->cmd == STOP_STREAM ||
- + stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) {
- stream_info->state = ACTIVE;
- } else {
- + pr_err("%s: Invalid stream state: %d\n",
- + __func__, stream_info->state);
- spin_unlock_irqrestore(
- &stream_info->lock, flags);
- - pr_err("%s: Invalid stream state\n", __func__);
- rc = -EINVAL;
- break;
- }
- @@ -410,21 +452,35 @@ void msm_isp_sof_notify(struct vfe_device *vfe_dev,
- break;
- }
- + sof_event.input_intf = frame_src;
- sof_event.frame_id = vfe_dev->axi_data.src_info[frame_src].frame_id;
- sof_event.timestamp = ts->event_time;
- - msm_isp_send_event(vfe_dev, ISP_EVENT_SOF, &sof_event);
- + sof_event.mono_timestamp = ts->buf_time;
- + msm_isp_send_event(vfe_dev, ISP_EVENT_SOF + frame_src, &sof_event);
- }
- void msm_isp_calculate_framedrop(
- struct msm_vfe_axi_shared_data *axi_data,
- struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd)
- {
- - struct msm_vfe_axi_stream *stream_info =
- - &axi_data->stream_info[
- - HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
- - uint32_t framedrop_period = msm_isp_get_framedrop_period(
- - stream_cfg_cmd->frame_skip_pattern);
- + struct msm_vfe_axi_stream *stream_info = NULL;
- + uint32_t framedrop_period = 0;
- + uint8_t idx = 0;
- +
- + if (NULL == axi_data || NULL == stream_cfg_cmd)
- + return;
- + idx = HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle);
- +
- + if (idx < MAX_NUM_STREAM)
- + stream_info = &axi_data->stream_info[idx];
- + else
- + return;
- +
- + framedrop_period = msm_isp_get_framedrop_period(
- + stream_cfg_cmd->frame_skip_pattern);
- + stream_info->frame_skip_pattern =
- + stream_cfg_cmd->frame_skip_pattern;
- if (stream_cfg_cmd->frame_skip_pattern == SKIP_ALL)
- stream_info->framedrop_pattern = 0x0;
- else
- @@ -469,15 +525,64 @@ void msm_isp_calculate_bandwidth(
- stream_info->format_factor / ISP_Q2;
- } else {
- int rdi = SRC_TO_INTF(stream_info->stream_src);
- - stream_info->bandwidth = axi_data->src_info[rdi].pixel_clock;
- + if (rdi < VFE_SRC_MAX)
- + stream_info->bandwidth =
- + axi_data->src_info[rdi].pixel_clock;
- }
- }
- +#ifdef CONFIG_MSM_AVTIMER
- +void msm_isp_start_avtimer(void)
- +{
- + avcs_core_open();
- + avcs_core_disable_power_collapse(1);
- +}
- +static inline void msm_isp_get_avtimer_ts(
- + struct msm_isp_timestamp *time_stamp)
- +{
- + int rc = 0;
- + uint32_t avtimer_usec = 0;
- + uint64_t avtimer_tick = 0;
- +
- + rc = avcs_core_query_timer(&avtimer_tick);
- + if (rc < 0) {
- + pr_err("%s: Error: Invalid AVTimer Tick, rc=%d\n",
- + __func__, rc);
- + /* In case of error return zero AVTimer Tick Value */
- + time_stamp->vt_time.tv_sec = 0;
- + time_stamp->vt_time.tv_usec = 0;
- + } else {
- + avtimer_usec = do_div(avtimer_tick, USEC_PER_SEC);
- + time_stamp->vt_time.tv_sec = (uint32_t)(avtimer_tick);
- + time_stamp->vt_time.tv_usec = avtimer_usec;
- + pr_debug("%s: AVTimer TS = %u:%u\n", __func__,
- + (uint32_t)(avtimer_tick), avtimer_usec);
- + }
- +}
- +#else
- +void msm_isp_start_avtimer(void)
- +{
- + pr_err("AV Timer is not supported\n");
- +}
- +
- +static inline void msm_isp_get_avtimer_ts(
- + struct msm_isp_timestamp *time_stamp)
- +{
- + pr_err("%s: Error: AVTimer driver not available\n",__func__);
- + time_stamp->vt_time.tv_sec = 0;
- + time_stamp->vt_time.tv_usec = 0;
- +}
- +
- +#endif
- +
- +
- int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
- {
- int rc = 0, i;
- + uint32_t io_format = 0;
- struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd = arg;
- struct msm_vfe_axi_stream *stream_info;
- + struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- rc = msm_isp_axi_create_stream(
- &vfe_dev->axi_data, stream_cfg_cmd);
- @@ -490,8 +595,11 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
- &vfe_dev->axi_data, stream_cfg_cmd);
- if (rc) {
- pr_err("%s: Request validation failed\n", __func__);
- - if (HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle) < MAX_NUM_STREAM)
- - msm_isp_axi_destroy_stream(&vfe_dev->axi_data,HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle));
- + if (HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle) <
- + MAX_NUM_STREAM) {
- + msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
- + HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle));
- + }
- return rc;
- }
- @@ -499,13 +607,38 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
- stream_info[HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
- msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_info);
- - if (stream_cfg_cmd->stream_src == CAMIF_RAW ||
- - stream_cfg_cmd->stream_src == IDEAL_RAW)
- - vfe_dev->hw_info->vfe_ops.axi_ops.
- - cfg_io_format(vfe_dev, stream_info);
- + if (stream_info->stream_src < RDI_INTF_0) {
- + io_format = vfe_dev->axi_data.src_info[VFE_PIX_0].input_format;
- + if (stream_info->stream_src == CAMIF_RAW ||
- + stream_info->stream_src == IDEAL_RAW) {
- + if (stream_info->stream_src == CAMIF_RAW &&
- + io_format != stream_info->output_format)
- + pr_warn("%s: Overriding input format\n",
- + __func__);
- +
- + io_format = stream_info->output_format;
- + }
- + rc = vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
- + vfe_dev, stream_info->stream_src, io_format);
- + if (rc) {
- + pr_err("%s: cfg io format failed\n", __func__);
- + msm_isp_axi_free_wm(&vfe_dev->axi_data,
- + stream_info);
- + msm_isp_axi_destroy_stream(&vfe_dev->axi_data,
- + HANDLE_TO_IDX(
- + stream_cfg_cmd->axi_stream_handle));
- + return rc;
- + }
- + }
- msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
- + stream_info->vt_enable = stream_cfg_cmd->vt_enable;
- + axi_data->burst_len = stream_cfg_cmd->burst_len;
- + if (stream_info->vt_enable) {
- + vfe_dev->vt_enable = stream_info->vt_enable;
- + msm_isp_start_avtimer();
- + }
- if (stream_info->num_planes > 1) {
- msm_isp_axi_reserve_comp_mask(
- &vfe_dev->axi_data, stream_info);
- @@ -534,12 +667,14 @@ int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg)
- struct msm_vfe_axi_stream *stream_info;
- struct msm_vfe_axi_stream_cfg_cmd stream_cfg;
- - if (HANDLE_TO_IDX(stream_release_cmd->stream_handle) >= MAX_NUM_STREAM) {
- - pr_err("%s: Invalid stream handle\n", __func__);
- - return -EINVAL;
- + if(HANDLE_TO_IDX(stream_release_cmd->stream_handle) >=
- + MAX_NUM_STREAM) {
- + pr_err("%s: Invalid stream handle\n", __func__);
- + return -EINVAL;
- }
- - stream_info = &axi_data->stream_info[HANDLE_TO_IDX(stream_release_cmd->stream_handle)];
- + stream_info = &axi_data->stream_info[
- + HANDLE_TO_IDX(stream_release_cmd->stream_handle)];
- if (stream_info->state == AVALIABLE) {
- pr_err("%s: Stream already released\n", __func__);
- return -EINVAL;
- @@ -589,9 +724,18 @@ static void msm_isp_axi_stream_enable_cfg(
- stream_info->state == RESUME_PENDING)
- vfe_dev->hw_info->vfe_ops.axi_ops.
- enable_wm(vfe_dev, stream_info->wm[i], 1);
- - else
- + else {
- vfe_dev->hw_info->vfe_ops.axi_ops.
- enable_wm(vfe_dev, stream_info->wm[i], 0);
- + /* Issue a reg update for Raw Snapshot Case
- + * since we dont have reg update ack
- + */
- + if (stream_info->stream_src == CAMIF_RAW ||
- + stream_info->stream_src == IDEAL_RAW) {
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + reg_update(vfe_dev);
- + }
- + }
- }
- if (stream_info->state == START_PENDING)
- @@ -621,7 +765,9 @@ void msm_isp_axi_stream_update(struct vfe_device *vfe_dev)
- }
- }
- - if (vfe_dev->axi_data.pipeline_update == DISABLE_CAMIF) {
- + if (vfe_dev->axi_data.pipeline_update == DISABLE_CAMIF ||
- + (vfe_dev->axi_data.pipeline_update ==
- + DISABLE_CAMIF_IMMEDIATELY)) {
- vfe_dev->hw_info->vfe_ops.stats_ops.
- enable_module(vfe_dev, 0xFF, 0);
- vfe_dev->axi_data.pipeline_update = NO_UPDATE;
- @@ -636,15 +782,17 @@ static void msm_isp_reload_ping_pong_offset(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info)
- {
- int i, j;
- + uint32_t flag;
- struct msm_isp_buffer *buf;
- - uint32_t pingpong_flags[2]= {VFE_PING_FLAG, VFE_PONG_FLAG};
- for (i = 0; i < 2; i++) {
- buf = stream_info->buf[i];
- - for (j = 0; j < stream_info->num_planes; j++)
- + flag = i ? VFE_PONG_FLAG : VFE_PING_FLAG;
- + for (j = 0; j < stream_info->num_planes; j++) {
- vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
- - vfe_dev, stream_info->wm[j],
- - pingpong_flags[i], buf->mapped_info[j].paddr +
- + vfe_dev, stream_info->wm[j], flag,
- + buf->mapped_info[j].paddr +
- stream_info->plane_cfg[j].plane_addr_offset);
- + }
- }
- }
- @@ -725,8 +873,9 @@ static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
- vfe_dev->pdev->id, bufq_handle, &buf);
- if (rc < 0) {
- - vfe_dev->error_info.
- - stream_framedrop_count[stream_idx]++;
- + if(stream_idx < MAX_NUM_STREAM)
- + vfe_dev->error_info.
- + stream_framedrop_count[stream_idx]++;
- return rc;
- }
- @@ -736,12 +885,12 @@ static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- goto buf_error;
- }
- - for (i = 0; i < stream_info->num_planes; i++) {
- + for (i = 0; i < stream_info->num_planes; i++)
- vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
- vfe_dev, stream_info->wm[i],
- pingpong_status, buf->mapped_info[i].paddr +
- stream_info->plane_cfg[i].plane_addr_offset);
- - }
- +
- pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
- stream_info->buf[pingpong_bit] = buf;
- return 0;
- @@ -757,25 +906,41 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
- {
- int rc;
- struct msm_isp_event_data buf_event;
- + struct timeval *time_stamp;
- uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle);
- - uint32_t frame_id = vfe_dev->axi_data.
- - src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id;
- - if (stream_idx >= MAX_NUM_STREAM) {
- - pr_err("%s: Invalid stream_idx", __func__);
- + uint32_t src_intf = SRC_TO_INTF(stream_info->stream_src);
- + uint32_t frame_id = 0;
- + memset(&buf_event, 0, sizeof(buf_event) );
- +
- + if(stream_idx >= MAX_NUM_STREAM) {
- + pr_err("%s: Invalid stream_idx \n", __func__);
- return;
- }
- +
- + if (src_intf < VFE_SRC_MAX) {
- + frame_id = vfe_dev->axi_data.src_info[src_intf].frame_id;
- + }
- +
- if (buf && ts) {
- + if (vfe_dev->vt_enable) {
- + msm_isp_get_avtimer_ts(ts);
- + time_stamp = &ts->vt_time;
- + } else {
- + time_stamp = &ts->buf_time;
- + }
- if (stream_info->buf_divert) {
- rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
- buf->bufq_handle, buf->buf_idx,
- - &ts->buf_time, frame_id);
- + time_stamp, frame_id);
- /* Buf divert return value represent whether the buf
- * can be diverted. A positive return value means
- * other ISP hardware is still processing the frame.
- */
- if (rc == 0) {
- + buf_event.input_intf =
- + SRC_TO_INTF(stream_info->stream_src);
- buf_event.frame_id = frame_id;
- - buf_event.timestamp = ts->buf_time;
- + buf_event.timestamp = *time_stamp;
- buf_event.u.buf_done.session_id =
- stream_info->session_id;
- buf_event.u.buf_done.stream_id =
- @@ -792,13 +957,13 @@ static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
- } else {
- vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
- buf->bufq_handle, buf->buf_idx,
- - &ts->buf_time, frame_id,
- + time_stamp, frame_id,
- stream_info->runtime_output_format);
- }
- }
- }
- -enum msm_isp_camif_update_state
- +static enum msm_isp_camif_update_state
- msm_isp_get_camif_update_state(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
- {
- @@ -825,26 +990,36 @@ enum msm_isp_camif_update_state
- (cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
- stream_cfg_cmd->cmd == STOP_STREAM)
- return DISABLE_CAMIF;
- + else if (cur_pix_stream_cnt &&
- + (cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
- + stream_cfg_cmd->cmd == STOP_IMMEDIATELY)
- + return DISABLE_CAMIF_IMMEDIATELY;
- }
- return NO_UPDATE;
- }
- -void msm_isp_update_camif_output_count(
- +static void msm_isp_update_camif_output_count(
- struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
- {
- int i;
- struct msm_vfe_axi_stream *stream_info;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- +
- + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
- + return;
- + }
- +
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= MAX_NUM_STREAM) {
- + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
- + >= MAX_NUM_STREAM) {
- return;
- }
- stream_info =
- &axi_data->stream_info[
- HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- if (stream_info->stream_src >= RDI_INTF_0)
- - return;
- + continue;
- if (stream_info->stream_src == PIX_ENCODER ||
- stream_info->stream_src == PIX_VIEWFINDER ||
- stream_info->stream_src == IDEAL_RAW) {
- @@ -865,6 +1040,68 @@ void msm_isp_update_camif_output_count(
- }
- }
- +static void msm_isp_update_rdi_output_count(
- + struct vfe_device *vfe_dev,
- + struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
- +{
- + int i;
- + struct msm_vfe_axi_stream *stream_info;
- + struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- +
- + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
- + return;
- + }
- +
- + for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
- + >= MAX_NUM_STREAM) {
- + return;
- + }
- + stream_info =
- + &axi_data->stream_info[
- + HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- + if (stream_info->stream_src < RDI_INTF_0)
- + continue;
- + if (stream_info->stream_src == RDI_INTF_0) {
- + if (stream_cfg_cmd->cmd == START_STREAM)
- + vfe_dev->axi_data.src_info[VFE_RAW_0].
- + raw_stream_count++;
- + else
- + vfe_dev->axi_data.src_info[VFE_RAW_0].
- + raw_stream_count--;
- + } else if (stream_info->stream_src == RDI_INTF_1) {
- + if (stream_cfg_cmd->cmd == START_STREAM)
- + vfe_dev->axi_data.src_info[VFE_RAW_1].
- + raw_stream_count++;
- + else
- + vfe_dev->axi_data.src_info[VFE_RAW_1].
- + raw_stream_count--;
- + } else if (stream_info->stream_src == RDI_INTF_2) {
- + if (stream_cfg_cmd->cmd == START_STREAM)
- + vfe_dev->axi_data.src_info[VFE_RAW_2].
- + raw_stream_count++;
- + else
- + vfe_dev->axi_data.src_info[VFE_RAW_2].
- + raw_stream_count--;
- + }
- +
- + }
- +}
- +
- +static uint8_t msm_isp_get_curr_stream_cnt(
- + struct vfe_device *vfe_dev)
- +{
- + uint8_t curr_stream_cnt = 0;
- + curr_stream_cnt = vfe_dev->axi_data.src_info[VFE_RAW_0].
- + raw_stream_count + vfe_dev->axi_data.src_info[VFE_RAW_1].
- + raw_stream_count + vfe_dev->axi_data.src_info[VFE_RAW_2].
- + raw_stream_count + vfe_dev->axi_data.src_info[VFE_PIX_0].
- + pix_stream_count + vfe_dev->axi_data.src_info[VFE_PIX_0].
- + raw_stream_count;
- +
- + return curr_stream_cnt;
- +}
- +
- void msm_camera_io_dump_2(void __iomem *addr, int size)
- {
- char line_str[128], *p_str;
- @@ -902,6 +1139,8 @@ static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- uint32_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0;
- uint32_t num_pix_streams = 0;
- + uint32_t num_rdi_streams = 0;
- + uint32_t total_streams = 0;
- uint64_t total_bandwidth = 0;
- for (i = 0; i < MAX_NUM_STREAM; i++) {
- @@ -913,19 +1152,27 @@ static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
- num_pix_streams++;
- } else {
- total_rdi_bandwidth += stream_info->bandwidth;
- + num_rdi_streams++;
- }
- }
- }
- if (num_pix_streams > 0)
- total_pix_bandwidth = total_pix_bandwidth /
- num_pix_streams * (num_pix_streams - 1) +
- - axi_data->src_info[VFE_PIX_0].pixel_clock *
- - ISP_DEFAULT_FORMAT_FACTOR / ISP_Q2;
- + ((unsigned long)axi_data->src_info[VFE_PIX_0].
- + pixel_clock) * ISP_DEFAULT_FORMAT_FACTOR / ISP_Q2;
- total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
- -
- + total_streams = num_pix_streams + num_rdi_streams;
- + if (total_streams == 1) {
- + rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
- + (total_bandwidth - MSM_ISP_MIN_AB) , (total_bandwidth *
- + ISP_BUS_UTILIZATION_FACTOR / ISP_Q2 - MSM_ISP_MIN_IB));
- + }
- + else {
- rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
- total_bandwidth, total_bandwidth *
- ISP_BUS_UTILIZATION_FACTOR / ISP_Q2);
- + }
- if (rc < 0)
- pr_err("%s: update failed\n", __func__);
- @@ -942,7 +1189,7 @@ static int msm_isp_axi_wait_for_cfg_done(struct vfe_device *vfe_dev,
- vfe_dev->axi_data.pipeline_update = camif_update;
- vfe_dev->axi_data.stream_update = 2;
- spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
- - rc = wait_for_completion_interruptible_timeout(
- + rc = wait_for_completion_timeout(
- &vfe_dev->stream_config_complete,
- msecs_to_jiffies(VFE_MAX_CFG_TIMEOUT));
- if (rc == 0) {
- @@ -1015,18 +1262,25 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
- enum msm_isp_camif_update_state camif_update)
- {
- int i, rc = 0;
- - uint8_t src_state, wait_for_complete = 0;
- + uint8_t src_state = 0, wait_for_complete = 0;
- uint32_t wm_reload_mask = 0x0;
- struct msm_vfe_axi_stream *stream_info;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- +
- + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
- + return -EINVAL;
- + }
- +
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= MAX_NUM_STREAM) {
- + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
- + >= MAX_NUM_STREAM) {
- return -EINVAL;
- }
- stream_info = &axi_data->stream_info[
- HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- - src_state = axi_data->src_info[
- - SRC_TO_INTF(stream_info->stream_src)].active;
- + if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX)
- + src_state = axi_data->src_info[
- + SRC_TO_INTF(stream_info->stream_src)].active;
- msm_isp_calculate_bandwidth(axi_data, stream_info);
- msm_isp_reset_framedrop(vfe_dev, stream_info);
- @@ -1050,17 +1304,21 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
- msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info);
- stream_info->state = ACTIVE;
- }
- + vfe_dev->axi_data.src_info[
- + SRC_TO_INTF(stream_info->stream_src)].frame_id = 0;
- }
- msm_isp_update_stream_bandwidth(vfe_dev);
- vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, wm_reload_mask);
- vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
- msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
- + msm_isp_update_rdi_output_count(vfe_dev, stream_cfg_cmd);
- if (camif_update == ENABLE_CAMIF) {
- vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = 0;
- vfe_dev->hw_info->vfe_ops.core_ops.
- update_camif_state(vfe_dev, camif_update);
- }
- +
- if (wait_for_complete)
- rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update);
- @@ -1072,35 +1330,81 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
- enum msm_isp_camif_update_state camif_update)
- {
- int i, rc = 0;
- + uint8_t wait_for_complete = 0, cur_stream_cnt = 0;
- struct msm_vfe_axi_stream *stream_info;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- +
- + if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
- + return -EINVAL;
- + }
- +
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= MAX_NUM_STREAM) {
- + if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
- + >= MAX_NUM_STREAM) {
- return -EINVAL;
- }
- stream_info = &axi_data->stream_info[
- HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- - stream_info->state = STOP_PENDING;
- - }
- - rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update);
- - if (rc < 0) {
- - pr_err("%s: wait for config done failed\n", __func__);
- - pr_err("%s:<DEBUG00>timeout:no frame from sensor\n", __func__);
- - for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- - stream_info = &axi_data->stream_info[
- - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
- - stream_info->state = STOP_PENDING;
- - msm_isp_axi_stream_enable_cfg(
- - vfe_dev, stream_info);
- + stream_info->state = STOP_PENDING;
- + if (stream_info->stream_src == CAMIF_RAW ||
- + stream_info->stream_src == IDEAL_RAW) {
- + /* We dont get reg update IRQ for raw snapshot
- + * so frame skip cant be ocnfigured
- + */
- + wait_for_complete = 1;
- + } else if (stream_info->stream_type == BURST_STREAM &&
- + stream_info->runtime_num_burst_capture == 0) {
- + /* Configure AXI writemasters to stop immediately
- + * since for burst case, write masters already skip
- + * all frames.
- + */
- + if (stream_info->stream_src == RDI_INTF_0 ||
- + stream_info->stream_src == RDI_INTF_1 ||
- + stream_info->stream_src == RDI_INTF_2)
- + wait_for_complete = 1;
- + else {
- + msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info);
- stream_info->state = INACTIVE;
- + }
- + } else {
- + wait_for_complete = 1;
- + }
- + }
- + if (wait_for_complete) {
- + rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update);
- + if (rc < 0) {
- + pr_err("%s: wait for config done failed\n", __func__);
- + for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- + stream_info = &axi_data->stream_info[
- + HANDLE_TO_IDX(
- + stream_cfg_cmd->stream_handle[i])];
- + stream_info->state = STOP_PENDING;
- + msm_isp_axi_stream_enable_cfg(
- + vfe_dev, stream_info);
- + stream_info->state = INACTIVE;
- + }
- }
- }
- msm_isp_update_stream_bandwidth(vfe_dev);
- if (camif_update == DISABLE_CAMIF)
- vfe_dev->hw_info->vfe_ops.core_ops.
- update_camif_state(vfe_dev, DISABLE_CAMIF);
- + else if (camif_update == DISABLE_CAMIF_IMMEDIATELY)
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY);
- msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
- + msm_isp_update_rdi_output_count(vfe_dev, stream_cfg_cmd);
- + cur_stream_cnt = msm_isp_get_curr_stream_cnt(vfe_dev);
- + if (cur_stream_cnt == 0) {
- + vfe_dev->ignore_error = 1;
- + if (camif_update == DISABLE_CAMIF_IMMEDIATELY) {
- + vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1);
- + }
- + vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, ISP_RST_HARD, 1);
- + vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);
- + vfe_dev->ignore_error = 0;
- + }
- for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
- stream_info = &axi_data->stream_info[
- @@ -1156,9 +1460,16 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
- return -EBUSY;
- }
- + /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/
- + if (update_cmd->num_streams > MAX_NUM_STREAM) {
- + return -EINVAL;
- + }
- +
- for (i = 0; i < update_cmd->num_streams; i++) {
- update_info = &update_cmd->update_info[i];
- - if (HANDLE_TO_IDX(update_info->stream_handle) >= MAX_NUM_STREAM) {
- + /*check array reference bounds*/
- + if (HANDLE_TO_IDX(update_info->stream_handle)
- + >= MAX_NUM_STREAM) {
- return -EINVAL;
- }
- stream_info = &axi_data->stream_info[
- @@ -1169,7 +1480,10 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
- return -EINVAL;
- }
- if (stream_info->state == ACTIVE &&
- - stream_info->stream_type == BURST_STREAM) {
- + stream_info->stream_type == BURST_STREAM &&
- + (1 != update_cmd->num_streams ||
- + UPDATE_STREAM_FRAMEDROP_PATTERN !=
- + update_cmd->update_type)) {
- pr_err("%s: Cannot update active burst stream\n",
- __func__);
- return -EINVAL;
- @@ -1196,7 +1510,10 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
- msm_isp_get_framedrop_period(
- update_info->skip_pattern);
- stream_info->runtime_init_frame_drop = 0;
- - stream_info->framedrop_pattern = 0x1;
- + if (update_info->skip_pattern == SKIP_ALL)
- + stream_info->framedrop_pattern = 0x0;
- + else
- + stream_info->framedrop_pattern = 0x1;
- stream_info->framedrop_period = framedrop_period - 1;
- vfe_dev->hw_info->vfe_ops.axi_ops.
- cfg_framedrop(vfe_dev, stream_info);
- @@ -1243,6 +1560,7 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info;
- struct msm_vfe_axi_composite_info *comp_info;
- struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- + struct msm_isp_timestamp buf_ts;
- comp_mask = vfe_dev->hw_info->vfe_ops.axi_ops.
- get_comp_mask(irq_status0, irq_status1);
- @@ -1255,11 +1573,14 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
- pingpong_status =
- vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
- + msm_isp_get_buffer_ts(vfe_dev, ts, &buf_ts);
- +
- for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
- comp_info = &axi_data->composite_info[i];
- if (comp_mask & (1 << i)) {
- stream_idx = HANDLE_TO_IDX(comp_info->stream_handle);
- - if ((!comp_info->stream_handle) || (stream_idx >= MAX_NUM_STREAM)) {
- + if ((!comp_info->stream_handle) ||
- + (stream_idx >= MAX_NUM_STREAM)) {
- pr_err("%s: Invalid handle for composite irq\n",
- __func__);
- } else {
- @@ -1288,7 +1609,7 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
- }
- if (done_buf && !rc)
- msm_isp_process_done_buf(vfe_dev,
- - stream_info, done_buf, ts);
- + stream_info, done_buf, &buf_ts);
- }
- }
- wm_mask &= ~(comp_info->stream_composite_mask);
- @@ -1297,7 +1618,8 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
- for (i = 0; i < axi_data->hw_info->num_wm; i++) {
- if (wm_mask & (1 << i)) {
- stream_idx = HANDLE_TO_IDX(axi_data->free_wm[i]);
- - if ((!axi_data->free_wm[i]) || (stream_idx >= MAX_NUM_STREAM)) {
- + if ((!axi_data->free_wm[i]) ||
- + (stream_idx >= MAX_NUM_STREAM)) {
- pr_err("%s: Invalid handle for wm irq\n",
- __func__);
- continue;
- @@ -1320,7 +1642,7 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
- }
- if (done_buf && !rc)
- msm_isp_process_done_buf(vfe_dev,
- - stream_info, done_buf, ts);
- + stream_info, done_buf, &buf_ts);
- }
- }
- return;
- diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
- index 34ebf62..dbc27ad 100644
- --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
- +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -27,7 +27,7 @@ static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr;
- #define MSM_ISP_MIN_AB 300000000
- #define MSM_ISP_MIN_IB 450000000
- -
- +#define VFE40_8974V2_VERSION 0x1001001A
- static struct msm_bus_vectors msm_isp_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_VFE,
- @@ -76,6 +76,25 @@ static struct msm_bus_scale_pdata msm_isp_bus_client_pdata = {
- .name = "msm_camera_isp",
- };
- +static void msm_isp_print_fourcc_error(const char *origin,
- + uint32_t fourcc_format)
- +{
- + int i;
- + char text[5];
- + text[4] = '\0';
- + for (i = 0; i < 4; i++) {
- + text[i] = (char)(((fourcc_format) >> (i * 8)) & 0xFF);
- + if ((text[i] < '0') || (text[i] > 'z')) {
- + pr_err("%s: Invalid output format %d (unprintable)\n",
- + origin, fourcc_format);
- + return;
- + }
- + }
- + pr_err("%s: Invalid output format %s\n",
- + origin, text);
- + return;
- +}
- +
- int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client)
- {
- int rc = 0;
- @@ -113,6 +132,7 @@ int msm_isp_update_bandwidth(enum msm_isp_hw_client client,
- pr_err("%s:error bandwidth manager inactive use_cnt:%d bus_clnt:%d\n",
- __func__, isp_bandwidth_mgr.use_count,
- isp_bandwidth_mgr.bus_client);
- + mutex_unlock(&bandwidth_mgr_mutex);
- return -EINVAL;
- }
- @@ -236,6 +256,43 @@ int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- return rc;
- }
- +static int msm_isp_get_max_clk_rate(struct vfe_device *vfe_dev, long *rate)
- +{
- + int clk_idx = 0;
- + unsigned long max_value = ~0;
- + long round_rate = 0;
- +
- + if (!vfe_dev || !rate) {
- + pr_err("%s:%d failed: vfe_dev %p rate %p\n", __func__, __LINE__,
- + vfe_dev, rate);
- + return -EINVAL;
- + }
- +
- + *rate = 0;
- + if (!vfe_dev->hw_info) {
- + pr_err("%s:%d failed: vfe_dev->hw_info %p\n", __func__,
- + __LINE__, vfe_dev->hw_info);
- + return -EINVAL;
- + }
- +
- + clk_idx = vfe_dev->hw_info->vfe_clk_idx;
- + if (clk_idx >= ARRAY_SIZE(vfe_dev->vfe_clk)) {
- + pr_err("%s:%d failed: clk_idx %d max array size %d\n",
- + __func__, __LINE__, clk_idx,
- + ARRAY_SIZE(vfe_dev->vfe_clk));
- + return -EINVAL;
- + }
- +
- + round_rate = clk_round_rate(vfe_dev->vfe_clk[clk_idx], max_value);
- + if (round_rate < 0) {
- + pr_err("%s: Invalid vfe clock rate\n", __func__);
- + return -EINVAL;
- + }
- +
- + *rate = round_rate;
- + return 0;
- +}
- +
- static int msm_isp_set_clk_rate(struct vfe_device *vfe_dev, long *rate)
- {
- int rc = 0;
- @@ -279,6 +336,9 @@ int msm_isp_cfg_pix(struct vfe_device *vfe_dev,
- return rc;
- }
- + vfe_dev->axi_data.src_info[VFE_PIX_0].input_format =
- + input_cfg->d.pix_cfg.input_format;
- +
- vfe_dev->hw_info->vfe_ops.core_ops.cfg_camif(
- vfe_dev, &input_cfg->d.pix_cfg);
- return rc;
- @@ -298,13 +358,6 @@ int msm_isp_cfg_rdi(struct vfe_device *vfe_dev,
- input_cfg->input_pix_clk;
- vfe_dev->hw_info->vfe_ops.core_ops.cfg_rdi_reg(
- vfe_dev, &input_cfg->d.rdi_cfg, input_cfg->input_src);
- -
- - rc = msm_isp_set_clk_rate(vfe_dev,
- - &vfe_dev->axi_data.src_info[input_cfg->input_src].pixel_clock);
- - if (rc < 0) {
- - pr_err("%s: clock set rate failed\n", __func__);
- - return rc;
- - }
- return rc;
- }
- @@ -335,10 +388,6 @@ long msm_isp_ioctl(struct v4l2_subdev *sd,
- long rc = 0;
- struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
- - if (!vfe_dev) {
- - pr_err("%s: vfe_dev NULL\n", __func__);
- - return -EINVAL;
- - }
- /* Use real time mutex for hard real-time ioctls such as
- * buffer operations and register updates.
- * Use core mutex for other ioctls that could take
- @@ -383,7 +432,7 @@ long msm_isp_ioctl(struct v4l2_subdev *sd,
- break;
- case VIDIOC_MSM_ISP_SET_SRC_STATE:
- mutex_lock(&vfe_dev->core_mutex);
- - msm_isp_set_src_state(vfe_dev, arg);
- + rc = msm_isp_set_src_state(vfe_dev, arg);
- mutex_unlock(&vfe_dev->core_mutex);
- break;
- case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
- @@ -409,11 +458,10 @@ long msm_isp_ioctl(struct v4l2_subdev *sd,
- case MSM_SD_SHUTDOWN:
- while (vfe_dev->vfe_open_cnt != 0)
- msm_isp_close_node(sd, NULL);
- - rc = 0;
- break;
- default:
- - pr_err("%s: Invalid ISP command\n", __func__);
- + pr_err_ratelimited("%s: Invalid ISP command\n", __func__);
- rc = -EINVAL;
- }
- return rc;
- @@ -489,8 +537,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
- pr_err("%s:%d len %d\n",
- __func__, __LINE__,
- reg_cfg_cmd->u.dmi_info.len);
- - return -EINVAL;
- - }
- + return -EINVAL;
- + }
- if (((UINT_MAX -
- reg_cfg_cmd->u.dmi_info.hi_tbl_offset) <
- (reg_cfg_cmd->u.dmi_info.len -
- @@ -549,6 +597,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
- }
- temp = msm_camera_io_r(vfe_dev->vfe_base +
- reg_cfg_cmd->u.mask_info.reg_offset);
- +
- temp &= ~reg_cfg_cmd->u.mask_info.mask;
- temp |= reg_cfg_cmd->u.mask_info.val;
- msm_camera_io_w(temp, vfe_dev->vfe_base +
- @@ -565,10 +614,11 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
- hi_tbl_ptr = cfg_data +
- reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
- }
- -
- lo_tbl_ptr = cfg_data +
- reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
- -
- + if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT)
- + reg_cfg_cmd->u.dmi_info.len =
- + reg_cfg_cmd->u.dmi_info.len / 2;
- for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
- lo_val = *lo_tbl_ptr++;
- if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) {
- @@ -607,7 +657,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
- reg_cfg_cmd->u.dmi_info.len =
- reg_cfg_cmd->u.dmi_info.len / 2;
- - for (i = 0; i < reg_cfg_cmd->u.dmi_info.len / 4; i++) {
- + for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
- lo_val = msm_camera_io_r(vfe_dev->vfe_base +
- vfe_dev->hw_info->dmi_reg_offset + 0x4);
- @@ -627,17 +677,87 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
- }
- break;
- }
- + case VFE_HW_UPDATE_LOCK: {
- + uint32_t update_id =
- + vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id;
- + if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id != *cfg_data
- + || update_id == *cfg_data) {
- + ISP_DBG("hw update lock failed,acquire id %u\n",
- + *cfg_data);
- + ISP_DBG("hw update lock failed,current id %lu\n",
- + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
- + ISP_DBG("hw update lock failed,last id %u\n",
- + update_id);
- + return -EINVAL;
- + }
- + break;
- + }
- + case VFE_HW_UPDATE_UNLOCK: {
- + if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id
- + != *cfg_data) {
- + ISP_DBG("hw update across frame boundary,begin id %u\n",
- + *cfg_data);
- + ISP_DBG("hw update across frame boundary,end id %lu\n",
- + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
- + }
- + vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id =
- + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
- + break;
- + }
- case VFE_READ: {
- int i;
- uint32_t *data_ptr = cfg_data +
- reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
- for (i = 0; i < reg_cfg_cmd->u.rw_info.len/4; i++) {
- + if ((data_ptr < cfg_data) ||
- + (UINT_MAX / sizeof(*data_ptr) <
- + (data_ptr - cfg_data)) ||
- + (sizeof(*data_ptr) * (data_ptr - cfg_data) >=
- + cmd_len))
- + return -EINVAL;
- *data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base +
- reg_cfg_cmd->u.rw_info.reg_offset);
- reg_cfg_cmd->u.rw_info.reg_offset += 4;
- }
- break;
- }
- + case GET_SOC_HW_VER: {
- + if (cmd_len < sizeof(uint32_t)) {
- + pr_err("%s:%d failed: invalid cmd len %u exp %zu\n",
- + __func__, __LINE__, cmd_len,
- + sizeof(uint32_t));
- + return -EINVAL;
- + }
- + *cfg_data = vfe_dev->soc_hw_version;
- + break;
- + }
- + case GET_MAX_CLK_RATE: {
- + int rc = 0;
- +
- + if (cmd_len < sizeof(unsigned long)) {
- + pr_err("%s:%d failed: invalid cmd len %d exp %d\n",
- + __func__, __LINE__, cmd_len,
- + sizeof(unsigned long));
- + return -EINVAL;
- + }
- + rc = msm_isp_get_max_clk_rate(vfe_dev,
- + (unsigned long *)cfg_data);
- + if (rc < 0) {
- + pr_err("%s:%d failed: rc %d\n", __func__, __LINE__, rc);
- + return -EINVAL;
- + }
- + break;
- + }
- + case SET_WM_UB_SIZE: {
- + if (cmd_len < sizeof(uint32_t)) {
- + pr_err("%s:%d failed: invalid cmd len %u exp %zu\n",
- + __func__, __LINE__, cmd_len,
- + sizeof(uint32_t));
- + return -EINVAL;
- + }
- + vfe_dev->vfe_ub_size = *cfg_data;
- + break;
- + }
- }
- return 0;
- }
- @@ -649,6 +769,11 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
- struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd;
- uint32_t *cfg_data;
- + if (!proc_cmd->num_cfg) {
- + pr_err("%s: Passed num_cfg as 0\n", __func__);
- + return -EINVAL;
- + }
- +
- reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)*
- proc_cmd->num_cfg, GFP_KERNEL);
- if (!reg_cfg_cmd) {
- @@ -657,6 +782,12 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
- goto reg_cfg_failed;
- }
- + if (!proc_cmd->cmd_len) {
- + pr_err("%s: Passed cmd_len as 0\n", __func__);
- + rc = -EINVAL;
- + goto cfg_data_failed;
- + }
- +
- cfg_data = kzalloc(proc_cmd->cmd_len, GFP_KERNEL);
- if (!cfg_data) {
- pr_err("%s: cfg_data alloc failed\n", __func__);
- @@ -679,7 +810,7 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
- }
- for (i = 0; i < proc_cmd->num_cfg; i++)
- - msm_isp_send_hw_cmd(vfe_dev, ®_cfg_cmd[i],
- + rc = msm_isp_send_hw_cmd(vfe_dev, ®_cfg_cmd[i],
- cfg_data, proc_cmd->cmd_len);
- if (copy_to_user(proc_cmd->cfg_data,
- @@ -725,7 +856,7 @@ int msm_isp_cal_word_per_line(uint32_t output_format,
- case V4L2_PIX_FMT_QGBRG8:
- case V4L2_PIX_FMT_QGRBG8:
- case V4L2_PIX_FMT_QRGGB8:
- - case V4L2_PIX_FMT_JPEG:
- + case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_META:
- val = CAL_WORD(pixel_per_line, 1, 8);
- break;
- @@ -761,17 +892,63 @@ int msm_isp_cal_word_per_line(uint32_t output_format,
- case V4L2_PIX_FMT_NV61:
- val = CAL_WORD(pixel_per_line, 1, 8);
- break;
- + case V4L2_PIX_FMT_YUYV:
- + case V4L2_PIX_FMT_YVYU:
- + case V4L2_PIX_FMT_UYVY:
- + case V4L2_PIX_FMT_VYUY:
- + val = CAL_WORD(pixel_per_line, 2, 8);
- + break;
- /*TD: Add more image format*/
- default:
- - pr_err("%s: Invalid output format\n", __func__);
- + msm_isp_print_fourcc_error(__func__, output_format);
- break;
- }
- return val;
- }
- +enum msm_isp_pack_fmt msm_isp_get_pack_format(uint32_t output_format)
- +{
- + switch (output_format) {
- + case V4L2_PIX_FMT_SBGGR8:
- + case V4L2_PIX_FMT_SGBRG8:
- + case V4L2_PIX_FMT_SGRBG8:
- + case V4L2_PIX_FMT_SRGGB8:
- + case V4L2_PIX_FMT_SBGGR10:
- + case V4L2_PIX_FMT_SGBRG10:
- + case V4L2_PIX_FMT_SGRBG10:
- + case V4L2_PIX_FMT_SRGGB10:
- + case V4L2_PIX_FMT_SBGGR12:
- + case V4L2_PIX_FMT_SGBRG12:
- + case V4L2_PIX_FMT_SGRBG12:
- + case V4L2_PIX_FMT_SRGGB12:
- + return MIPI;
- + case V4L2_PIX_FMT_QBGGR8:
- + case V4L2_PIX_FMT_QGBRG8:
- + case V4L2_PIX_FMT_QGRBG8:
- + case V4L2_PIX_FMT_QRGGB8:
- + case V4L2_PIX_FMT_QBGGR10:
- + case V4L2_PIX_FMT_QGBRG10:
- + case V4L2_PIX_FMT_QGRBG10:
- + case V4L2_PIX_FMT_QRGGB10:
- + case V4L2_PIX_FMT_QBGGR12:
- + case V4L2_PIX_FMT_QGBRG12:
- + case V4L2_PIX_FMT_QGRBG12:
- + case V4L2_PIX_FMT_QRGGB12:
- + return QCOM;
- + default:
- + msm_isp_print_fourcc_error(__func__, output_format);
- + break;
- + }
- + return -EINVAL;
- +}
- +
- int msm_isp_get_bit_per_pixel(uint32_t output_format)
- {
- switch (output_format) {
- + case V4L2_PIX_FMT_Y4:
- + return 4;
- + case V4L2_PIX_FMT_Y6:
- + return 6;
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SGBRG8:
- case V4L2_PIX_FMT_SGRBG8:
- @@ -780,8 +957,31 @@ int msm_isp_get_bit_per_pixel(uint32_t output_format)
- case V4L2_PIX_FMT_QGBRG8:
- case V4L2_PIX_FMT_QGRBG8:
- case V4L2_PIX_FMT_QRGGB8:
- - case V4L2_PIX_FMT_JPEG:
- + case V4L2_PIX_FMT_JPEG:
- case V4L2_PIX_FMT_META:
- + case V4L2_PIX_FMT_NV12:
- + case V4L2_PIX_FMT_NV21:
- + case V4L2_PIX_FMT_NV14:
- + case V4L2_PIX_FMT_NV41:
- + case V4L2_PIX_FMT_YVU410:
- + case V4L2_PIX_FMT_YVU420:
- + case V4L2_PIX_FMT_YUYV:
- + case V4L2_PIX_FMT_YYUV:
- + case V4L2_PIX_FMT_YVYU:
- + case V4L2_PIX_FMT_UYVY:
- + case V4L2_PIX_FMT_VYUY:
- + case V4L2_PIX_FMT_YUV422P:
- + case V4L2_PIX_FMT_YUV411P:
- + case V4L2_PIX_FMT_Y41P:
- + case V4L2_PIX_FMT_YUV444:
- + case V4L2_PIX_FMT_YUV555:
- + case V4L2_PIX_FMT_YUV565:
- + case V4L2_PIX_FMT_YUV32:
- + case V4L2_PIX_FMT_YUV410:
- + case V4L2_PIX_FMT_YUV420:
- + case V4L2_PIX_FMT_GREY:
- + case V4L2_PIX_FMT_PAL8:
- + case MSM_V4L2_PIX_FMT_META:
- return 8;
- case V4L2_PIX_FMT_SBGGR10:
- case V4L2_PIX_FMT_SGBRG10:
- @@ -791,6 +991,8 @@ int msm_isp_get_bit_per_pixel(uint32_t output_format)
- case V4L2_PIX_FMT_QGBRG10:
- case V4L2_PIX_FMT_QGRBG10:
- case V4L2_PIX_FMT_QRGGB10:
- + case V4L2_PIX_FMT_Y10:
- + case V4L2_PIX_FMT_Y10BPACK:
- return 10;
- case V4L2_PIX_FMT_SBGGR12:
- case V4L2_PIX_FMT_SGBRG12:
- @@ -800,19 +1002,16 @@ int msm_isp_get_bit_per_pixel(uint32_t output_format)
- case V4L2_PIX_FMT_QGBRG12:
- case V4L2_PIX_FMT_QGRBG12:
- case V4L2_PIX_FMT_QRGGB12:
- + case V4L2_PIX_FMT_Y12:
- return 12;
- - case V4L2_PIX_FMT_NV12:
- - case V4L2_PIX_FMT_NV21:
- - case V4L2_PIX_FMT_NV14:
- - case V4L2_PIX_FMT_NV41:
- - return 8;
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- + case V4L2_PIX_FMT_Y16:
- return 16;
- /*TD: Add more image format*/
- default:
- - pr_err("%s: Invalid output format\n", __func__);
- - return 10;
- + msm_isp_print_fourcc_error(__func__, output_format);
- + return -EINVAL;
- }
- }
- @@ -827,15 +1026,16 @@ void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
- void msm_isp_process_error_info(struct vfe_device *vfe_dev)
- {
- int i;
- + uint8_t num_stats_type =
- + vfe_dev->hw_info->stats_hw_info->num_stats_type;
- struct msm_vfe_error_info *error_info = &vfe_dev->error_info;
- static DEFINE_RATELIMIT_STATE(rs,
- DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
- static DEFINE_RATELIMIT_STATE(rs_stats,
- DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
- -// if (error_info->error_count == 1 ||
- -// !(error_info->info_dump_frame_count % 100)) {
- - if (1) {
- + if (error_info->error_count == 1 ||
- + !(error_info->info_dump_frame_count % 100)) {
- vfe_dev->hw_info->vfe_ops.core_ops.
- process_error_status(vfe_dev);
- error_info->error_mask0 = 0;
- @@ -851,7 +1051,7 @@ void msm_isp_process_error_info(struct vfe_device *vfe_dev)
- error_info->stream_framedrop_count[i] = 0;
- }
- }
- - for (i = 0; i < MSM_ISP_STATS_MAX; i++) {
- + for (i = 0; i < num_stats_type; i++) {
- if (error_info->stats_framedrop_count[i] != 0 &&
- __ratelimit(&rs_stats)) {
- pr_err("%s: Stats stream[%d]: dropped %d frames\n",
- @@ -871,6 +1071,125 @@ static inline void msm_isp_update_error_info(struct vfe_device *vfe_dev,
- vfe_dev->error_info.error_count++;
- }
- +static inline void msm_isp_process_overflow_irq(
- + struct vfe_device *vfe_dev,
- + uint32_t *irq_status0, uint32_t *irq_status1)
- +{
- + uint32_t overflow_mask;
- + uint32_t halt_restart_mask0, halt_restart_mask1;
- + /*Mask out all other irqs if recovery is started*/
- + if (atomic_read(&vfe_dev->error_info.overflow_state) !=
- + NO_OVERFLOW) {
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + get_halt_restart_mask(&halt_restart_mask0,
- + &halt_restart_mask1);
- + *irq_status0 &= halt_restart_mask0;
- + *irq_status1 &= halt_restart_mask1;
- + return;
- + }
- +
- + /*Check if any overflow bit is set*/
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + get_overflow_mask(&overflow_mask);
- + overflow_mask &= *irq_status1;
- + if (overflow_mask) {
- + pr_warning("%s: Bus overflow detected: 0x%x\n",
- + __func__, overflow_mask);
- + atomic_set(&vfe_dev->error_info.overflow_state,
- + OVERFLOW_DETECTED);
- + pr_warning("%s: Start bus overflow recovery\n", __func__);
- + /*Store current IRQ mask*/
- + vfe_dev->hw_info->vfe_ops.core_ops.get_irq_mask(vfe_dev,
- + &vfe_dev->error_info.overflow_recover_irq_mask0,
- + &vfe_dev->error_info.overflow_recover_irq_mask1);
- + /*Stop CAMIF Immediately*/
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY);
- + /*Halt the hardware & Clear all other IRQ mask*/
- + vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0);
- + /*Update overflow state*/
- + atomic_set(&vfe_dev->error_info.overflow_state, HALT_REQUESTED);
- + *irq_status0 = 0;
- + *irq_status1 = 0;
- + }
- +}
- +
- +static inline void msm_isp_reset_burst_count(
- + struct vfe_device *vfe_dev)
- +{
- + int i;
- + struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
- + struct msm_vfe_axi_stream *stream_info;
- + struct msm_vfe_axi_stream_request_cmd framedrop_info;
- + for (i = 0; i < MAX_NUM_STREAM; i++) {
- + stream_info = &axi_data->stream_info[i];
- + if (stream_info->state != ACTIVE)
- + continue;
- + if (stream_info->stream_type == BURST_STREAM &&
- + stream_info->num_burst_capture != 0) {
- + framedrop_info.burst_count =
- + stream_info->num_burst_capture;
- + framedrop_info.frame_skip_pattern =
- + stream_info->frame_skip_pattern;
- + framedrop_info.init_frame_drop = 0;
- + msm_isp_calculate_framedrop(&vfe_dev->axi_data,
- + &framedrop_info);
- + }
- + }
- +}
- +
- +static void msm_isp_process_overflow_recovery(
- + struct vfe_device *vfe_dev,
- + uint32_t irq_status0, uint32_t irq_status1)
- +{
- + uint32_t halt_restart_mask0, halt_restart_mask1;
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + get_halt_restart_mask(&halt_restart_mask0,
- + &halt_restart_mask1);
- + irq_status0 &= halt_restart_mask0;
- + irq_status1 &= halt_restart_mask1;
- + if (irq_status0 == 0 && irq_status1 == 0)
- + return;
- +
- + switch (atomic_read(&vfe_dev->error_info.overflow_state)) {
- + case HALT_REQUESTED: {
- + pr_err("%s: Halt done, Restart Pending\n", __func__);
- + /*Reset the hardware*/
- + vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev,
- + ISP_RST_SOFT, 0);
- + /*Update overflow state*/
- + atomic_set(&vfe_dev->error_info.overflow_state,
- + RESTART_REQUESTED);
- + }
- + break;
- + case RESTART_REQUESTED: {
- + pr_err("%s: Restart done, Resuming\n", __func__);
- + /*Reset the burst stream frame drop pattern, in the
- + *case where bus overflow happens during the burstshot,
- + *the framedrop pattern might be updated after reg update
- + *to skip all the frames after the burst shot. The burst shot
- + *might not be completed due to the overflow, so the framedrop
- + *pattern need to change back to the original settings in order
- + *to recovr from overflow.
- + */
- + msm_isp_reset_burst_count(vfe_dev);
- + vfe_dev->hw_info->vfe_ops.axi_ops.
- + reload_wm(vfe_dev, 0xFFFFFFFF);
- + vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev);
- + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
- + memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
- + atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
- + vfe_dev->hw_info->vfe_ops.core_ops.
- + update_camif_state(vfe_dev, ENABLE_CAMIF);
- + }
- + break;
- + case NO_OVERFLOW:
- + case OVERFLOW_DETECTED:
- + default:
- + break;
- + }
- +}
- +
- irqreturn_t msm_isp_process_irq(int irq_num, void *data)
- {
- unsigned long flags;
- @@ -881,19 +1200,27 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
- vfe_dev->hw_info->vfe_ops.irq_ops.
- read_irq_status(vfe_dev, &irq_status0, &irq_status1);
- + if ((irq_status0 == 0) && (irq_status1 == 0)) {
- + pr_err_ratelimited("%s: irq_status0 & 1 are both 0\n",
- + __func__);
- + return IRQ_HANDLED;
- + }
- + msm_isp_process_overflow_irq(vfe_dev,
- + &irq_status0, &irq_status1);
- vfe_dev->hw_info->vfe_ops.core_ops.
- get_error_mask(&error_mask0, &error_mask1);
- error_mask0 &= irq_status0;
- error_mask1 &= irq_status1;
- irq_status0 &= ~error_mask0;
- irq_status1 &= ~error_mask1;
- - if ((error_mask0 != 0) || (error_mask1 != 0))
- + if (!vfe_dev->ignore_error &&
- + ((error_mask0 != 0) || (error_mask1 != 0)))
- msm_isp_update_error_info(vfe_dev, error_mask0, error_mask1);
- if ((irq_status0 == 0) && (irq_status1 == 0) &&
- (!((error_mask0 != 0) || (error_mask1 != 0)) &&
- vfe_dev->error_info.error_count == 1)) {
- - ISP_DBG("%s: irq_status0 & 1 are both 0!\n", __func__);
- + ISP_DBG("%s: error_mask0/1 & error_count are set!\n", __func__);
- return IRQ_HANDLED;
- }
- @@ -942,29 +1269,39 @@ void msm_isp_do_tasklet(unsigned long data)
- irq_status1 = queue_cmd->vfeInterruptStatus1;
- ts = queue_cmd->ts;
- spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
- + if (atomic_read(&vfe_dev->error_info.overflow_state) !=
- + NO_OVERFLOW) {
- + pr_err_ratelimited("There is Overflow, kicking up recovery !!!!");
- + msm_isp_process_overflow_recovery(vfe_dev,
- + irq_status0, irq_status1);
- + continue;
- + }
- ISP_DBG("%s: status0: 0x%x status1: 0x%x\n",
- __func__, irq_status0, irq_status1);
- irq_ops->process_reset_irq(vfe_dev,
- irq_status0, irq_status1);
- irq_ops->process_halt_irq(vfe_dev,
- irq_status0, irq_status1);
- + irq_ops->process_camif_irq(vfe_dev,
- + irq_status0, irq_status1, &ts);
- irq_ops->process_axi_irq(vfe_dev,
- irq_status0, irq_status1, &ts);
- irq_ops->process_stats_irq(vfe_dev,
- irq_status0, irq_status1, &ts);
- irq_ops->process_reg_update(vfe_dev,
- irq_status0, irq_status1, &ts);
- - irq_ops->process_camif_irq(vfe_dev,
- - irq_status0, irq_status1, &ts);
- msm_isp_process_error_info(vfe_dev);
- }
- }
- -void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
- +int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
- {
- struct msm_vfe_axi_src_state *src_state = arg;
- + if (src_state->input_src >= VFE_SRC_MAX)
- + return -EINVAL;
- vfe_dev->axi_data.src_info[src_state->input_src].active =
- src_state->src_active;
- + return 0;
- }
- int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- @@ -989,7 +1326,10 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- return -EBUSY;
- }
- - rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev);
- + memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
- + atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
- + rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev,
- + ISP_RST_HARD, 1);
- if (rc <= 0) {
- pr_err("%s: reset timeout\n", __func__);
- mutex_unlock(&vfe_dev->core_mutex);
- @@ -1003,6 +1343,15 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- vfe_dev->buf_mgr->ops->buf_mgr_init(vfe_dev->buf_mgr, "msm_isp", 28);
- + switch (vfe_dev->vfe_hw_version) {
- + case VFE40_8974V2_VERSION:
- + vfe_dev->soc_hw_version = msm_camera_io_r(vfe_dev->tcsr_base);
- + break;
- + default:
- + /* SOC HARDWARE VERSION NOT SUPPORTED */
- + vfe_dev->soc_hw_version = 0x00;
- + }
- +
- memset(&vfe_dev->axi_data, 0, sizeof(struct msm_vfe_axi_shared_data));
- memset(&vfe_dev->stats_data, 0,
- sizeof(struct msm_vfe_stats_shared_data));
- @@ -1010,18 +1359,30 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info;
- vfe_dev->vfe_open_cnt++;
- vfe_dev->taskletq_idx = 0;
- + vfe_dev->vt_enable = 0;
- mutex_unlock(&vfe_dev->core_mutex);
- mutex_unlock(&vfe_dev->realtime_mutex);
- return 0;
- }
- +#ifdef CONFIG_MSM_AVTIMER
- +void msm_isp_end_avtimer(void)
- +{
- + avcs_core_disable_power_collapse(0);
- +}
- +#else
- +void msm_isp_end_avtimer(void)
- +{
- + pr_err("AV Timer is not supported\n");
- +}
- +#endif
- +
- int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- {
- - long rc;
- struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
- - ISP_DBG("%s\n", __func__);
- mutex_lock(&vfe_dev->realtime_mutex);
- mutex_lock(&vfe_dev->core_mutex);
- +
- if (vfe_dev->vfe_open_cnt == 0) {
- pr_err("%s: Invalid close\n", __func__);
- mutex_unlock(&vfe_dev->core_mutex);
- @@ -1029,13 +1390,14 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- return -ENODEV;
- }
- - rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
- - if (rc <= 0)
- - pr_err("%s: halt timeout rc=%ld\n", __func__, rc);
- -
- + vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1);
- vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr);
- vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
- vfe_dev->vfe_open_cnt--;
- + if (vfe_dev->vt_enable) {
- + msm_isp_end_avtimer();
- + vfe_dev->vt_enable = 0;
- + }
- mutex_unlock(&vfe_dev->core_mutex);
- mutex_unlock(&vfe_dev->realtime_mutex);
- return 0;
- diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
- index ba85831..a38fd7a 100755
- --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
- +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -19,6 +19,7 @@
- #include <linux/platform_device.h>
- #include <linux/gpio.h>
- #include <linux/iopoll.h>
- +#include <linux/ratelimit.h>
- #include <media/msmb_isp.h>
- #include "msm_ispif.h"
- @@ -40,9 +41,7 @@
- #define ISPIF_INTF_CMD_DISABLE_IMMEDIATELY 0x02
- #define ISPIF_TIMEOUT_SLEEP_US 1000
- -#define ISPIF_TIMEOUT_ALL_US 500000
- -
- -#define CSID_VERSION_V30 0x30000000
- +#define ISPIF_TIMEOUT_ALL_US 1000000
- #undef CDBG
- #ifdef CONFIG_MSMB_CAMERA_DEBUG
- @@ -51,33 +50,6 @@
- #define CDBG(fmt, args...) do { } while (0)
- #endif
- -static void msm_camera_io_dump_3(void __iomem *addr, int size)
- -{
- - char line_str[128], *p_str;
- - int i;
- - u32 *p = (u32 *) addr;
- - u32 data;
- - printk("%s: %p %d\n", __func__, addr, size);
- - line_str[0] = '\0';
- - p_str = line_str;
- - for (i = 0; i < size/4; i++) {
- - if (i % 4 == 0) {
- - snprintf(p_str, 12, "%08x: ", (u32) p);
- - p_str += 10;
- - }
- - data = readl_relaxed(p++);
- - snprintf(p_str, 12, "%08x ", data);
- - p_str += 9;
- - if ((i + 1) % 4 == 0) {
- - printk("%s\n", line_str);
- - line_str[0] = '\0';
- - p_str = line_str;
- - }
- - }
- - if (line_str[0] != '\0')
- - printk("%s\n", line_str);
- -}
- -
- static void msm_ispif_io_dump_reg(struct ispif_device *ispif)
- {
- if (!ispif->enb_dump_reg)
- @@ -85,20 +57,32 @@ static void msm_ispif_io_dump_reg(struct ispif_device *ispif)
- msm_camera_io_dump(ispif->base, 0x250);
- }
- -static void msm_ispif_io_dump_start_reg(struct ispif_device *ispif)
- -{
- - if (!ispif->enb_dump_reg)
- - return;
- - msm_camera_io_dump_3(ispif->base, 0x270);
- -}
- -
- static inline int msm_ispif_is_intf_valid(uint32_t csid_version,
- uint8_t intf_type)
- {
- - return ((csid_version <= CSID_VERSION_V2 && intf_type != VFE0) ||
- - (intf_type >= VFE_MAX)) ? false : true;
- + return ((csid_version <= CSID_VERSION_V22 && intf_type != VFE0) ||
- + (intf_type >= VFE_MAX)) ? false : true;
- }
- +static struct msm_cam_clk_info ispif_8626_reset_clk_info[] = {
- + {"ispif_ahb_clk", NO_SET_RATE},
- + {"camss_top_ahb_clk", NO_SET_RATE},
- + {"csi0_ahb_clk", NO_SET_RATE},
- + {"csi0_src_clk", NO_SET_RATE},
- + {"csi0_phy_clk", NO_SET_RATE},
- + {"csi0_clk", NO_SET_RATE},
- + {"csi0_pix_clk", NO_SET_RATE},
- + {"csi0_rdi_clk", NO_SET_RATE},
- + {"csi1_ahb_clk", NO_SET_RATE},
- + {"csi1_src_clk", NO_SET_RATE},
- + {"csi1_phy_clk", NO_SET_RATE},
- + {"csi1_clk", NO_SET_RATE},
- + {"csi1_pix_clk", NO_SET_RATE},
- + {"csi1_rdi_clk", NO_SET_RATE},
- + {"camss_vfe_vfe_clk", NO_SET_RATE},
- + {"camss_csi_vfe_clk", NO_SET_RATE},
- +};
- +
- static struct msm_cam_clk_info ispif_8974_ahb_clk_info[] = {
- {"ispif_ahb_clk", -1},
- };
- @@ -133,19 +117,26 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
- int rc = 0;
- long timeout = 0;
- struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)];
- -
- - if (ispif->csid_version < CSID_VERSION_V30) {
- - /* currently reset is done only for 8974 */
- - return 0;
- -
- - }
- + struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)];
- + ispif->clk_idx = 0;
- rc = msm_cam_clk_enable(&ispif->pdev->dev,
- ispif_8974_reset_clk_info, reset_clk,
- ARRAY_SIZE(ispif_8974_reset_clk_info), 1);
- if (rc < 0) {
- - pr_err("%s: cannot enable clock, error = %d",
- - __func__, rc);
- + rc = msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8626_reset_clk_info, reset_clk1,
- + ARRAY_SIZE(ispif_8626_reset_clk_info), 1);
- + if (rc < 0){
- + pr_err("%s: cannot enable clock, error = %d",
- + __func__, rc);
- + } else {
- + /* This is set if device is 8x26 */
- + ispif->clk_idx = 2;
- + }
- + } else {
- + /* This is set if device is 8974 */
- + ispif->clk_idx = 1;
- }
- init_completion(&ispif->reset_complete[VFE0]);
- @@ -159,13 +150,23 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
- msm_camera_io_w(ISPIF_RST_CMD_1_MASK,
- ispif->base + ISPIF_RST_CMD_1_ADDR);
- - timeout = wait_for_completion_interruptible_timeout(
- + timeout = wait_for_completion_timeout(
- &ispif->reset_complete[VFE0], msecs_to_jiffies(500));
- CDBG("%s: VFE0 done\n", __func__);
- +
- if (timeout <= 0) {
- pr_err("%s: VFE0 reset wait timeout\n", __func__);
- - rc = -ETIMEDOUT;
- - goto end;
- + rc = msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8974_reset_clk_info, reset_clk,
- + ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
- + if (rc < 0){
- + rc = msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8626_reset_clk_info, reset_clk1,
- + ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
- + if (rc < 0)
- + pr_err("%s: VFE0 reset wait timeout\n", __func__);
- + }
- + return -ETIMEDOUT;
- }
- if (ispif->hw_num_isps > 1) {
- @@ -175,19 +176,33 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif)
- CDBG("%s: VFE1 done\n", __func__);
- if (timeout <= 0) {
- pr_err("%s: VFE1 reset wait timeout\n", __func__);
- - rc = -ETIMEDOUT;
- - goto end;
- + msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8974_reset_clk_info, reset_clk,
- + ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
- + return -ETIMEDOUT;
- }
- }
- - pr_info("%s: ISPIF reset hw done", __func__);
- -end:
- - rc = msm_cam_clk_enable(&ispif->pdev->dev,
- - ispif_8974_reset_clk_info, reset_clk,
- - ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
- - if (rc < 0) {
- - pr_err("%s: cannot disable clock, error = %d",
- - __func__, rc);
- +
- + if (ispif->clk_idx == 1){
- + rc = msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8974_reset_clk_info, reset_clk,
- + ARRAY_SIZE(ispif_8974_reset_clk_info), 0);
- + if (rc < 0) {
- + pr_err("%s: cannot disable clock, error = %d",
- + __func__, rc);
- + }
- }
- +
- + if (ispif->clk_idx == 2){
- + rc = msm_cam_clk_enable(&ispif->pdev->dev,
- + ispif_8626_reset_clk_info, reset_clk1,
- + ARRAY_SIZE(ispif_8626_reset_clk_info), 0);
- + if (rc < 0) {
- + pr_err("%s: cannot disable clock, error = %d",
- + __func__, rc);
- + }
- + }
- +
- return rc;
- }
- @@ -195,7 +210,7 @@ static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable)
- {
- int rc = 0;
- - if (ispif->csid_version < CSID_VERSION_V3) {
- + if (ispif->csid_version < CSID_VERSION_V30) {
- /* Older ISPIF versiond don't need ahb clokc */
- return 0;
- }
- @@ -221,7 +236,8 @@ static int msm_ispif_reset(struct ispif_device *ispif)
- memset(ispif->sof_count, 0, sizeof(ispif->sof_count));
- for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
- - msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT, ispif->base + ISPIF_VFE_m_CTRL_0(i));
- + msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT,
- + ispif->base + ISPIF_VFE_m_CTRL_0(i));
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i));
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i));
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i));
- @@ -231,24 +247,24 @@ static int msm_ispif_reset(struct ispif_device *ispif)
- ISPIF_VFE_m_IRQ_CLEAR_1(i));
- msm_camera_io_w(0xFFFFFFFF, ispif->base +
- ISPIF_VFE_m_IRQ_CLEAR_2(i));
- +
- msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i));
- - msm_camera_io_w(0xAAAAAAAA,
- + msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
- ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
- -
- - msm_camera_io_w(0xAAAAAAAA,
- + msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
- ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
- -
- + pr_debug("%s: base %lx", __func__, (unsigned long)ispif->base);
- msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
- msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
- msm_camera_io_w(0, ispif->base +
- - ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
- + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0));
- msm_camera_io_w(0, ispif->base +
- - ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
- + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1));
- msm_camera_io_w(0, ispif->base +
- - ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2));
- + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 2));
- msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0));
- @@ -508,9 +524,20 @@ static int msm_ispif_config(struct ispif_device *ispif,
- rc = -EPERM;
- return rc;
- }
- + if (params->num > MAX_PARAM_ENTRIES) {
- + pr_err("%s: invalid param entries %d\n", __func__,
- + params->num);
- + rc = -EINVAL;
- + return rc;
- + }
- for (i = 0; i < params->num; i++) {
- vfe_intf = params->entries[i].vfe_intf;
- + if (vfe_intf >= VFE_MAX) {
- + pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__,
- + __LINE__, i, vfe_intf);
- + return -EINVAL;
- + }
- if (!msm_ispif_is_intf_valid(ispif->csid_version,
- vfe_intf)) {
- pr_err("%s: invalid interface type\n", __func__);
- @@ -534,14 +561,14 @@ static int msm_ispif_config(struct ispif_device *ispif,
- if ((intftype >= INTF_MAX) ||
- (vfe_intf >= ispif->vfe_info.num_vfe) ||
- - (ispif->csid_version <= CSID_VERSION_V2 &&
- + (ispif->csid_version <= CSID_VERSION_V22 &&
- (vfe_intf > VFE0))) {
- pr_err("%s: VFEID %d and CSID version %d mismatch\n",
- __func__, vfe_intf, ispif->csid_version);
- return -EINVAL;
- }
- - if (ispif->csid_version >= CSID_VERSION_V3)
- + if (ispif->csid_version >= CSID_VERSION_V30)
- msm_ispif_select_clk_mux(ispif, intftype,
- params->entries[i].csid, vfe_intf);
- @@ -602,12 +629,27 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
- BUG_ON(!ispif);
- BUG_ON(!params);
- + if (params->num > MAX_PARAM_ENTRIES) {
- + pr_err("%s: invalid param entries %d\n", __func__,
- + params->num);
- + return;
- + }
- for (i = 0; i < params->num; i++) {
- vfe_intf = params->entries[i].vfe_intf;
- + if (vfe_intf >= VFE_MAX) {
- + pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__,
- + __LINE__, i, vfe_intf);
- + return;
- + }
- if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) {
- pr_err("%s: invalid interface type\n", __func__);
- return;
- }
- + if (params->entries[i].num_cids > MAX_CID_CH) {
- + pr_err("%s: out of range of cid_num %d\n",
- + __func__, params->entries[i].num_cids);
- + return;
- + }
- }
- for (i = 0; i < params->num; i++) {
- @@ -634,11 +676,10 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
- }
- /* cmd for PIX0, PIX1, RDI0, RDI1 */
- - if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF) {
- + if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF)
- msm_camera_io_w_mb(
- ispif->applied_intf_cmd[vfe_intf].intf_cmd,
- ispif->base + ISPIF_VFE_m_INTF_CMD_0(vfe_intf));
- - }
- /* cmd for RDI2 */
- if (ispif->applied_intf_cmd[vfe_intf].intf_cmd1 != 0xFFFFFFFF)
- @@ -664,6 +705,12 @@ static int msm_ispif_stop_immediately(struct ispif_device *ispif,
- return rc;
- }
- + if (params->num > MAX_PARAM_ENTRIES) {
- + pr_err("%s: invalid param entries %d\n", __func__,
- + params->num);
- + rc = -EINVAL;
- + return rc;
- + }
- msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_DISABLE_IMMEDIATELY, params);
- /* after stop the interface we need to unmask the CID enable bits */
- @@ -688,6 +735,12 @@ static int msm_ispif_start_frame_boundary(struct ispif_device *ispif,
- rc = -EPERM;
- return rc;
- }
- + if (params->num > MAX_PARAM_ENTRIES) {
- + pr_err("%s: invalid param entries %d\n", __func__,
- + params->num);
- + rc = -EINVAL;
- + return rc;
- + }
- msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params);
- @@ -714,6 +767,13 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
- return rc;
- }
- + if (params->num > MAX_PARAM_ENTRIES) {
- + pr_err("%s: invalid param entries %d\n", __func__,
- + params->num);
- + rc = -EINVAL;
- + return rc;
- + }
- +
- for (i = 0; i < params->num; i++) {
- if (!msm_ispif_is_intf_valid(ispif->csid_version,
- params->entries[i].vfe_intf)) {
- @@ -754,19 +814,13 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
- goto end;
- }
- -#if 0
- - /* todo_bug_fix? very bad. use readl_poll_timeout */
- - while ((msm_camera_io_r(ispif->base + intf_addr) & 0xF) != 0xF)
- - CDBG("%s: Wait for %d Idle\n", __func__,
- - params->entries[i].intftype);
- -#else
- rc = readl_poll_timeout(ispif->base + intf_addr, stop_flag,
- - (stop_flag & 0xF) == 0xF,
- - ISPIF_TIMEOUT_SLEEP_US,
- - ISPIF_TIMEOUT_ALL_US);
- + (stop_flag & 0xF) == 0xF,
- + ISPIF_TIMEOUT_SLEEP_US,
- + ISPIF_TIMEOUT_ALL_US);
- if (rc < 0)
- goto end;
- -#endif
- +
- /* disable CIDs in CID_MASK register */
- msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
- cid_mask, vfe_intf, 0);
- @@ -860,7 +914,7 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
- ispif_process_irq(ispif, out, VFE0);
- }
- - if (ispif->vfe_info.num_vfe > 1) {
- + if (ispif->hw_num_isps > 1) {
- if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ)
- complete(&ispif->reset_complete[VFE1]);
- @@ -919,7 +973,7 @@ static int msm_ispif_init(struct ispif_device *ispif,
- ispif->csid_version = csid_version;
- - if (ispif->csid_version >= CSID_VERSION_V3) {
- + if (ispif->csid_version >= CSID_VERSION_V30) {
- if (!ispif->clk_mux_mem || !ispif->clk_mux_io) {
- pr_err("%s csi clk mux mem %p io %p\n", __func__,
- ispif->clk_mux_mem, ispif->clk_mux_io);
- @@ -955,16 +1009,12 @@ static int msm_ispif_init(struct ispif_device *ispif,
- goto error_ahb;
- }
- - if(of_device_is_compatible(ispif->pdev->dev.of_node,
- - "qcom,ispif-v3.0")) {
- - /*Currently HW reset is implemented for 8974 only*/
- - msm_ispif_reset_hw(ispif);
- - }
- + msm_ispif_reset_hw(ispif);
- rc = msm_ispif_reset(ispif);
- if (rc == 0) {
- ispif->ispif_state = ISPIF_POWER_UP;
- - pr_info("%s: power up done\n", __func__);
- + CDBG("%s: power up done\n", __func__);
- goto end;
- }
- @@ -987,12 +1037,6 @@ static void msm_ispif_release(struct ispif_device *ispif)
- return;
- }
- - if(of_device_is_compatible(ispif->pdev->dev.of_node,
- - "qcom,ispif-v3.0")) {
- - /*Currently HW reset is implemented for 8974 only*/
- - msm_ispif_reset_hw(ispif);
- - }
- -
- /* make sure no streaming going on */
- msm_ispif_reset(ispif);
- @@ -1005,7 +1049,6 @@ static void msm_ispif_release(struct ispif_device *ispif)
- iounmap(ispif->clk_mux_base);
- ispif->ispif_state = ISPIF_POWER_DOWN;
- - pr_info("%s: power down done", __func__);
- }
- static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
- @@ -1033,7 +1076,7 @@ static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
- break;
- case ISPIF_START_FRAME_BOUNDARY:
- rc = msm_ispif_start_frame_boundary(ispif, &pcdata->params);
- - msm_ispif_io_dump_start_reg(ispif);
- + msm_ispif_io_dump_reg(ispif);
- break;
- case ISPIF_STOP_FRAME_BOUNDARY:
- rc = msm_ispif_stop_frame_boundary(ispif, &pcdata->params);
- @@ -1067,11 +1110,13 @@ static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
- case MSM_SD_SHUTDOWN: {
- struct ispif_device *ispif =
- (struct ispif_device *)v4l2_get_subdevdata(sd);
- - msm_ispif_release(ispif);
- + if (ispif && ispif->base)
- + msm_ispif_release(ispif);
- return 0;
- }
- default:
- - pr_err("%s: invalid cmd 0x%x received\n", __func__, cmd);
- + pr_err_ratelimited("%s: invalid cmd 0x%x received\n",
- + __func__, cmd);
- return -ENOIOCTLCMD;
- }
- }
- @@ -1158,6 +1203,7 @@ static int __devinit ispif_probe(struct platform_device *pdev)
- goto error_sd_register;
- }
- +
- if (pdev->dev.of_node) {
- of_property_read_u32((&pdev->dev)->of_node,
- "cell-index", &pdev->id);
- @@ -1218,6 +1264,7 @@ error_sd_register:
- static const struct of_device_id msm_ispif_dt_match[] = {
- {.compatible = "qcom,ispif"},
- + {}
- };
- MODULE_DEVICE_TABLE(of, msm_ispif_dt_match);
- diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
- index 652ee89..4dd8e5f 100644
- --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
- +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -35,15 +35,14 @@
- #include <media/v4l2-event.h>
- #include <media/v4l2-ioctl.h>
- #include <media/msmb_camera.h>
- -#include <media/msmb_pproc.h>
- #include <media/msmb_generic_buf_mgr.h>
- +#include <media/msmb_pproc.h>
- +#include <mach/clk-provider.h>
- #include "msm_cpp.h"
- #include "msm_isp_util.h"
- #include "msm_camera_io_util.h"
- #include <linux/debugfs.h>
- -#include <mach/clk-provider.h>
- -
- #define MSM_CPP_DRV_NAME "msm_cpp"
- #define MSM_CPP_MAX_BUFF_QUEUE 16
- @@ -51,33 +50,40 @@
- #define CONFIG_MSM_CPP_DBG 0
- #define CPP_CMD_TIMEOUT_MS 300
- -#define MSM_CPP_MAX_TIMEOUT_TRIAL 10
- +#define MSM_CPP_CORE_CLK_IDX 4
- +#define MSM_MICRO_IFACE_CLK_IDX 7
- #define MSM_CPP_NOMINAL_CLOCK 266670000
- #define MSM_CPP_TURBO_CLOCK 320000000
- -extern int poweroff_charging;
- +#define CPP_FW_VERSION_1_2_0 0x10020000
- +#define CPP_FW_VERSION_1_4_0 0x10040000
- +#define CPP_FW_VERSION_1_6_0 0x10060000
- +#define CPP_FW_VERSION_1_8_0 0x10080000
- +/* stripe information offsets in frame command */
- +#define STRIPE_BASE_FW_1_2_0 130
- +#define STRIPE_BASE_FW_1_4_0 140
- +#define STRIPE_BASE_FW_1_6_0 464
- -typedef struct _msm_cpp_timer_data_t {
- +struct msm_cpp_timer_data_t {
- struct cpp_device *cpp_dev;
- struct msm_cpp_frame_info_t *processed_frame;
- -} msm_cpp_timer_data_t;
- +};
- -typedef struct _msm_cpp_timer_t {
- - uint8_t used;
- - msm_cpp_timer_data_t data;
- +struct msm_cpp_timer_t {
- + atomic_t used;
- + struct msm_cpp_timer_data_t data;
- struct timer_list cpp_timer;
- -} msm_cpp_timer_t;
- +};
- -msm_cpp_timer_t cpp_timers[2];
- -static int del_timer_idx=0;
- -static int set_timer_idx=0;
- +struct msm_cpp_timer_t cpp_timer;
- /* dump the frame command before writing to the hardware */
- #define MSM_CPP_DUMP_FRM_CMD 0
- -static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info);
- +static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,
- + uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info);
- #if CONFIG_MSM_CPP_DBG
- #define CPP_DBG(fmt, args...) pr_err(fmt, ##args)
- @@ -104,6 +110,8 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,uint32_t buff_mgr_ops,
- qcmd; \
- })
- +#define MSM_CPP_MAX_TIMEOUT_TRIAL 3
- +
- static void msm_queue_init(struct msm_device_queue *queue, const char *name)
- {
- CPP_DBG("E\n");
- @@ -131,27 +139,6 @@ static void msm_enqueue(struct msm_device_queue *queue,
- spin_unlock_irqrestore(&queue->lock, flags);
- }
- -static void msm_cpp_empty_list_eventdata(struct msm_device_queue *queue)
- -{
- - unsigned long flags;
- - struct msm_queue_cmd *qcmd = NULL;
- - if (!queue)
- - return;
- -
- - spin_lock_irqsave(&queue->lock, flags);
- - while (!list_empty(&queue->list)) {
- - queue->len--;
- - qcmd = list_first_entry(&queue->list,
- - struct msm_queue_cmd, list_eventdata);
- - list_del_init(&qcmd->list_eventdata);
- - kfree(qcmd);
- - }
- - spin_unlock_irqrestore(&queue->lock, flags);
- -
- - return;
- -}
- -
- -
- static struct msm_cam_clk_info cpp_clk_info[] = {
- {"camss_top_ahb_clk", -1},
- {"vfe_clk_src", 266670000},
- @@ -162,11 +149,29 @@ static struct msm_cam_clk_info cpp_clk_info[] = {
- {"cpp_bus_clk", -1},
- {"micro_iface_clk", -1},
- };
- -static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev);
- +
- +#define msm_cpp_empty_list(queue, member) { \
- + unsigned long flags; \
- + struct msm_queue_cmd *qcmd = NULL; \
- + if (queue) { \
- + spin_lock_irqsave(&queue->lock, flags); \
- + while (!list_empty(&queue->list)) { \
- + queue->len--; \
- + qcmd = list_first_entry(&queue->list, \
- + struct msm_queue_cmd, member); \
- + list_del_init(&qcmd->member); \
- + kfree(qcmd); \
- + } \
- + spin_unlock_irqrestore(&queue->lock, flags); \
- + } \
- +}
- +
- +static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
- + uint32_t buff_mgr_ops);
- static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin);
- -void cpp_timer_callback(unsigned long data);
- +static void cpp_timer_callback(unsigned long data);
- -uint8_t induce_error = 0;
- +uint8_t induce_error;
- static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
- static void msm_cpp_write(u32 data, void __iomem *cpp_base)
- @@ -174,6 +179,14 @@ static void msm_cpp_write(u32 data, void __iomem *cpp_base)
- writel_relaxed((data), cpp_base + MSM_CPP_MICRO_FIFO_RX_DATA);
- }
- +static void msm_cpp_clear_timer(struct cpp_device *cpp_dev)
- +{
- + atomic_set(&cpp_timer.used, 0);
- + del_timer(&cpp_timer.cpp_timer);
- + cpp_timer.data.processed_frame = NULL;
- + cpp_dev->timeout_trial_cnt = 0;
- +}
- +
- static uint32_t msm_cpp_read(void __iomem *cpp_base)
- {
- uint32_t tmp, retry = 0;
- @@ -215,7 +228,7 @@ static struct msm_cpp_buff_queue_info_t *msm_cpp_get_buff_queue_entry(
- static unsigned long msm_cpp_get_phy_addr(struct cpp_device *cpp_dev,
- struct msm_cpp_buff_queue_info_t *buff_queue_info, uint32_t buff_index,
- - uint8_t native_buff)
- + uint8_t native_buff, int *fd)
- {
- unsigned long phy_add = 0;
- struct list_head *buff_head;
- @@ -229,6 +242,7 @@ static unsigned long msm_cpp_get_phy_addr(struct cpp_device *cpp_dev,
- list_for_each_entry_safe(buff, save, buff_head, entry) {
- if (buff->map_info.buff_info.index == buff_index) {
- phy_add = buff->map_info.phy_addr;
- + *fd = buff->map_info.buff_info.fd;
- break;
- }
- }
- @@ -285,8 +299,6 @@ static unsigned long msm_cpp_queue_buffer_info(struct cpp_device *cpp_dev,
- return buff->map_info.phy_addr;
- QUEUE_BUFF_ERROR2:
- - ion_unmap_iommu(cpp_dev->client, buff->map_info.ion_handle,
- - cpp_dev->domain_num, 0);
- ion_free(cpp_dev->client, buff->map_info.ion_handle);
- QUEUE_BUFF_ERROR1:
- buff->map_info.ion_handle = NULL;
- @@ -312,7 +324,7 @@ static void msm_cpp_dequeue_buffer_info(struct cpp_device *cpp_dev,
- static unsigned long msm_cpp_fetch_buffer_info(struct cpp_device *cpp_dev,
- struct msm_cpp_buffer_info_t *buffer_info, uint32_t session_id,
- - uint32_t stream_id)
- + uint32_t stream_id, int *fd)
- {
- unsigned long phy_addr = 0;
- struct msm_cpp_buff_queue_info_t *buff_queue_info;
- @@ -327,10 +339,11 @@ static unsigned long msm_cpp_fetch_buffer_info(struct cpp_device *cpp_dev,
- }
- phy_addr = msm_cpp_get_phy_addr(cpp_dev, buff_queue_info,
- - buffer_info->index, native_buff);
- + buffer_info->index, native_buff, fd);
- if ((phy_addr == 0) && (native_buff)) {
- phy_addr = msm_cpp_queue_buffer_info(cpp_dev, buff_queue_info,
- buffer_info);
- + *fd = buffer_info->fd;
- }
- return phy_addr;
- }
- @@ -624,23 +637,17 @@ void msm_cpp_do_tasklet(unsigned long data)
- if (msg_id == MSM_CPP_MSG_ID_FRAME_ACK) {
- CPP_DBG("Frame done!!\n");
- /* delete CPP timer */
- - CPP_DBG("deleting cpp_timer %d.\n", del_timer_idx);
- - del_timer(&cpp_timers[del_timer_idx].cpp_timer);
- - cpp_timers[del_timer_idx].used = 0;
- - cpp_timers[del_timer_idx].data.processed_frame = NULL;
- - del_timer_idx = 1 - del_timer_idx;
- - cpp_dev->timeout_trial_cnt = 0;
- - msm_cpp_notify_frame_done(cpp_dev);
- + CPP_DBG("delete timer.\n");
- + msm_cpp_clear_timer(cpp_dev);
- + msm_cpp_notify_frame_done(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_BUF_DONE);
- } else if (msg_id ==
- MSM_CPP_MSG_ID_FRAME_NACK) {
- pr_err("NACK error from hw!!\n");
- - CPP_DBG("deleting cpp_timer %d.\n", del_timer_idx);
- - del_timer(&cpp_timers[del_timer_idx].cpp_timer);
- - cpp_timers[del_timer_idx].used = 0;
- - cpp_timers[del_timer_idx].data.processed_frame = NULL;
- - del_timer_idx = 1 - del_timer_idx;
- - cpp_dev->timeout_trial_cnt = 0;
- - msm_cpp_notify_frame_done(cpp_dev);
- + CPP_DBG("delete timer.\n");
- + msm_cpp_clear_timer(cpp_dev);
- + msm_cpp_notify_frame_done(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_PUT_BUF);
- }
- i += cmd_len + 2;
- }
- @@ -648,43 +655,27 @@ void msm_cpp_do_tasklet(unsigned long data)
- }
- }
- -#if 0
- -static void msm_cpp_boot_hw(struct cpp_device *cpp_dev)
- +static void cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info)
- {
- - msm_camera_io_w(0x1, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
- - msm_camera_io_w(0x1, cpp_dev->base +
- - MSM_CPP_MICRO_BOOT_START);
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- + uint32_t count;
- + signed long freq_tbl_entry = 0;
- - /*Trigger MC to jump to start address*/
- - msm_cpp_write(MSM_CPP_CMD_EXEC_JUMP, cpp_dev->base);
- - msm_cpp_write(MSM_CPP_JUMP_ADDRESS, cpp_dev->base);
- -
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- - msm_cpp_poll(cpp_dev->base, 0x1);
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_JUMP_ACK);
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
- -
- - /*Get Bootloader Version*/
- - msm_cpp_write(MSM_CPP_CMD_GET_BOOTLOADER_VER, cpp_dev->base);
- - pr_info("MC Bootloader Version: 0x%x\n",
- - msm_cpp_read(cpp_dev->base));
- + if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
- + (clk->ops->list_rate == NULL)) {
- + pr_err("Bad parameter\n");
- + return;
- + }
- - /*Get Firmware Version*/
- - msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
- - msm_cpp_write(MSM_CPP_MSG_ID_CMD, cpp_dev->base);
- - msm_cpp_write(0x1, cpp_dev->base);
- - msm_cpp_write(MSM_CPP_CMD_GET_FW_VER, cpp_dev->base);
- - msm_cpp_write(MSM_CPP_MSG_ID_TRAILER, cpp_dev->base);
- + for (count = 0; count < MAX_FREQ_TBL; count++) {
- + freq_tbl_entry = clk->ops->list_rate(clk, count);
- + if (freq_tbl_entry >= 0)
- + hw_info->freq_tbl[count] = freq_tbl_entry;
- + else
- + break;
- + }
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- - msm_cpp_poll(cpp_dev->base, 0x2);
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
- - pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
- - msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
- + hw_info->freq_tbl_count = count;
- }
- -#endif
- -
- static int cpp_init_hardware(struct cpp_device *cpp_dev)
- {
- int rc = 0;
- @@ -710,33 +701,37 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
- }
- }
- - cpp_dev->cpp_clk[7] = clk_get(&cpp_dev->pdev->dev,
- - cpp_clk_info[7].clk_name);
- - if (IS_ERR(cpp_dev->cpp_clk[7])) {
- - pr_err("%s get failed\n", cpp_clk_info[7].clk_name);
- - rc = PTR_ERR(cpp_dev->cpp_clk[7]);
- + cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX] =
- + clk_get(&cpp_dev->pdev->dev,
- + cpp_clk_info[MSM_MICRO_IFACE_CLK_IDX].clk_name);
- + if (IS_ERR(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX])) {
- + pr_err("%s get failed\n",
- + cpp_clk_info[MSM_MICRO_IFACE_CLK_IDX].clk_name);
- + rc = PTR_ERR(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
- goto remap_failed;
- }
- - rc = clk_reset(cpp_dev->cpp_clk[7], CLK_RESET_ASSERT);
- + rc = clk_reset(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX],
- + CLK_RESET_ASSERT);
- if (rc) {
- - pr_err("%s:micro_iface_clk assert failed\n", __func__);
- - clk_put(cpp_dev->cpp_clk[7]);
- - goto remap_failed;
- + pr_err("%s:micro_iface_clk assert failed\n", __func__);
- + clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
- + goto remap_failed;
- }
- -
- +
- usleep_range(10000, 12000);
- -
- - rc = clk_reset(cpp_dev->cpp_clk[7], CLK_RESET_DEASSERT);
- +
- + rc = clk_reset(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX],
- + CLK_RESET_DEASSERT);
- if (rc) {
- pr_err("%s:micro_iface_clk assert failed\n", __func__);
- - clk_put(cpp_dev->cpp_clk[7]);
- + clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
- goto remap_failed;
- }
- usleep_range(1000, 1200);
- - clk_put(cpp_dev->cpp_clk[7]);
- + clk_put(cpp_dev->cpp_clk[MSM_MICRO_IFACE_CLK_IDX]);
- rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 1);
- @@ -778,8 +773,9 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
- goto req_irq_fail;
- }
- cpp_dev->buf_mgr_subdev = msm_buf_mngr_get_subdev();
- -
- - rc = msm_cpp_buffer_ops(cpp_dev,VIDIOC_MSM_BUF_MNGR_INIT, NULL);
- +
- + rc = msm_cpp_buffer_ops(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_INIT, NULL);
- if (rc < 0) {
- pr_err("buf mngr init failed\n");
- free_irq(cpp_dev->irq->start, cpp_dev);
- @@ -792,35 +788,24 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
- pr_debug("CPP HW Version: 0x%x\n", cpp_dev->hw_info.cpp_hw_version);
- cpp_dev->hw_info.cpp_hw_caps =
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4);
- + cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[MSM_CPP_CORE_CLK_IDX],
- + &cpp_dev->hw_info);
- pr_debug("CPP HW Caps: 0x%x\n", cpp_dev->hw_info.cpp_hw_caps);
- msm_camera_io_w(0x1, cpp_dev->vbif_base + 0x4);
- cpp_dev->taskletq_idx = 0;
- atomic_set(&cpp_dev->irq_cnt, 0);
- msm_cpp_create_buff_queue(cpp_dev, MSM_CPP_MAX_BUFF_QUEUE);
- - pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt);
- + pr_debug("stream_cnt:%d\n", cpp_dev->stream_cnt);
- cpp_dev->stream_cnt = 0;
- if (cpp_dev->is_firmware_loaded == 1) {
- - pr_err("cpp_dbg: is_firmware_loaded==1\n");
- disable_irq(cpp_dev->irq->start);
- - pr_err("cpp_dbg: disable_irq e\n");
- - //msm_cpp_boot_hw(cpp_dev);
- -
- - pr_err("cpp_dbg: cpp_load_fw e\n");
- - cpp_load_fw(cpp_dev, NULL);
- - pr_err("cpp_dbg: cpp_load_fw x\n");
- -
- + cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
- enable_irq(cpp_dev->irq->start);
- - pr_err("cpp_dbg: enable_irq e\n");
- -
- msm_camera_io_w_mb(0x7C8, cpp_dev->base +
- MSM_CPP_MICRO_IRQGEN_MASK);
- - pr_err("cpp_dbg: MSM_CPP_MICRO_IRQGEN_MASK\n");
- -
- msm_camera_io_w_mb(0xFFFF, cpp_dev->base +
- MSM_CPP_MICRO_IRQGEN_CLR);
- - pr_err("cpp_dbg: MSM_CPP_MICRO_IRQGEN_CLR\n");
- }
- - pr_err("cpp_dbg: end of cpp_init_hardware\n");
- return rc;
- req_irq_fail:
- iounmap(cpp_dev->cpp_hw_base);
- @@ -844,9 +829,10 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
- {
- int32_t rc;
- if (cpp_dev->state != CPP_STATE_BOOT) {
- - rc = msm_cpp_buffer_ops(cpp_dev,VIDIOC_MSM_BUF_MNGR_DEINIT, NULL);
- - if (rc < 0)
- - pr_err("error in buf mngr deinit rc=%d\n", rc);
- + rc = msm_cpp_buffer_ops(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_DEINIT, NULL);
- + if (rc < 0)
- + pr_err("error in buf mngr deinit rc=%d\n", rc);
- free_irq(cpp_dev->irq->start, cpp_dev);
- tasklet_kill(&cpp_dev->cpp_tasklet);
- atomic_set(&cpp_dev->irq_cnt, 0);
- @@ -857,37 +843,17 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
- iounmap(cpp_dev->cpp_hw_base);
- msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 0);
- - if (0) {
- - regulator_disable(cpp_dev->fs_cpp);
- - regulator_put(cpp_dev->fs_cpp);
- - cpp_dev->fs_cpp = NULL;
- + regulator_disable(cpp_dev->fs_cpp);
- + regulator_put(cpp_dev->fs_cpp);
- + cpp_dev->fs_cpp = NULL;
- + if (cpp_dev->stream_cnt > 0) {
- + pr_debug("error: stream count active\n");
- + msm_isp_update_bandwidth(ISP_CPP, 0, 0);
- }
- - if (cpp_dev->stream_cnt > 0)
- - pr_err("error: stream count active\n");
- cpp_dev->stream_cnt = 0;
- msm_isp_deinit_bandwidth_mgr(ISP_CPP);
- }
- -int check_clocks(struct cpp_device *cpp_dev)
- -{
- - struct clk** clkp;
- - int i, j, ret;
- -
- - ret = 0;
- - clkp = cpp_dev->cpp_clk;
- - for (i=0;i<8;i++) {
- - j = 0;
- - if (clkp[i]) {
- - j=(!!clkp[i]->prepare_count) | (!!clkp[i]->count);
- - if (!j) {
- - pr_err ("%s, %d clock : [%d:%d]\n", __func__, i, clkp[i]->prepare_count, clkp[i]->count);
- - ret = -1;
- - }
- - }
- - }
- - return ret;
- -}
- -
- static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- {
- uint32_t i;
- @@ -896,26 +862,9 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- const struct firmware *fw = NULL;
- struct device *dev = &cpp_dev->pdev->dev;
- - if (check_clocks(cpp_dev) < 0)
- - {
- - pr_err ("QCTKD: some clocks were off\n");
- - dump_stack();
- - //BUG();
- - pr_err ("QCTKD: emergency clock for Samsung H\n");
- - rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- - cpp_dev->cpp_clk, ARRAY_SIZE(cpp_clk_info), 1);
- - }
- -
- - pr_err("cpp_dbg: MSM_CPP_MICRO_CLKEN_CTL\n");
- msm_camera_io_w(0x1, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
- -
- - usleep(2000);
- -
- - pr_err("cpp_dbg: MSM_CPP_MICRO_BOOT_START\n");
- msm_camera_io_w(0x1, cpp_dev->base +
- MSM_CPP_MICRO_BOOT_START);
- -
- - pr_err("cpp_dbg: MSM_CPP_MSG_ID_CMD\n");
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- if (fw_name_bin) {
- @@ -923,7 +872,7 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- rc = request_firmware(&fw, fw_name_bin, dev);
- if (rc) {
- dev_err(dev,
- - "Failed to locate blob %s from device %p, Error: %d\n",
- + "Fail to loc blob %s from dev %p, Error: %d\n",
- fw_name_bin, dev, rc);
- }
- if (NULL != fw)
- @@ -932,11 +881,15 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- msm_camera_io_w(0x1, cpp_dev->base +
- MSM_CPP_MICRO_BOOT_START);
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- - msm_camera_io_w(0xFFFFFFFF, cpp_dev->base + MSM_CPP_MICRO_IRQGEN_CLR);
- + msm_camera_io_w(0xFFFFFFFF, cpp_dev->base +
- + MSM_CPP_MICRO_IRQGEN_CLR);
- /*Start firmware loading*/
- msm_cpp_write(MSM_CPP_CMD_FW_LOAD, cpp_dev->base);
- - msm_cpp_write(MSM_CPP_END_ADDRESS, cpp_dev->base);
- + if (fw)
- + msm_cpp_write(fw->size, cpp_dev->base);
- + else
- + msm_cpp_write(MSM_CPP_END_ADDRESS, cpp_dev->base);
- msm_cpp_write(MSM_CPP_START_ADDRESS, cpp_dev->base);
- if (ptr_bin) {
- @@ -947,22 +900,18 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- }
- if (fw)
- release_firmware(fw);
- + msm_camera_io_w_mb(0x00, cpp_dev->cpp_hw_base + 0xC);
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_OK);
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- }
- - pr_err("cpp_dbg: Trigger MC to jump to start address\n");
- /*Trigger MC to jump to start address*/
- msm_cpp_write(MSM_CPP_CMD_EXEC_JUMP, cpp_dev->base);
- msm_cpp_write(MSM_CPP_JUMP_ADDRESS, cpp_dev->base);
- - pr_err("cpp_dbg: msm_cpp_poll MSM_CPP_MSG_ID_CMD\n");
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- - pr_err("cpp_dbg: msm_cpp_poll 0x1\n");
- msm_cpp_poll(cpp_dev->base, 0x1);
- - pr_err("cpp_dbg: msm_cpp_poll MSM_CPP_MSG_ID_JUMP_ACK\n");
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_JUMP_ACK);
- - pr_err("cpp_dbg: msm_cpp_poll MSM_CPP_MSG_ID_TRAILER\n");
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
- /*Get Bootloader Version*/
- @@ -980,7 +929,8 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
- msm_cpp_poll(cpp_dev->base, 0x2);
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
- - pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
- + cpp_dev->fw_version = msm_cpp_read(cpp_dev->base);
- + pr_info("CPP FW Version: 0x%08x\n", cpp_dev->fw_version);
- msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
- /*Disable MC clock*/
- @@ -1018,6 +968,7 @@ static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- cpp_dev->cpp_open_cnt++;
- if (cpp_dev->cpp_open_cnt == 1) {
- cpp_init_hardware(cpp_dev);
- + iommu_attach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
- cpp_init_mem(cpp_dev);
- cpp_dev->state = CPP_STATE_IDLE;
- }
- @@ -1029,9 +980,19 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- {
- uint32_t i;
- struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
- + struct msm_device_queue *processing_q = NULL;
- + struct msm_device_queue *eventData_q = NULL;
- +
- + if (!cpp_dev) {
- + pr_err("failed: cpp_dev %p\n", cpp_dev);
- + return -EINVAL;
- + }
- mutex_lock(&cpp_dev->mutex);
- + processing_q = &cpp_dev->processing_q;
- + eventData_q = &cpp_dev->eventData_q;
- +
- if (cpp_dev->cpp_open_cnt == 0) {
- mutex_unlock(&cpp_dev->mutex);
- return 0;
- @@ -1052,39 +1013,43 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- cpp_dev->cpp_open_cnt--;
- if (cpp_dev->cpp_open_cnt == 0) {
- - pr_err("%s: irq_status: 0x%x\n", __func__,
- + pr_debug("irq_status: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4));
- - pr_err("%s: DEBUG_SP: 0x%x\n", __func__,
- + pr_debug("DEBUG_SP: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x40));
- - pr_err("%s: DEBUG_T: 0x%x\n", __func__,
- + pr_debug("DEBUG_T: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x44));
- - pr_err("%s: DEBUG_N: 0x%x\n", __func__,
- + pr_debug("DEBUG_N: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x48));
- - pr_err("%s: DEBUG_R: 0x%x\n", __func__,
- + pr_debug("DEBUG_R: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4C));
- - pr_err("%s: DEBUG_OPPC: 0x%x\n", __func__,
- + pr_debug("DEBUG_OPPC: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x50));
- - pr_err("%s: DEBUG_MO: 0x%x\n", __func__,
- + pr_debug("DEBUG_MO: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x54));
- - pr_err("%s: DEBUG_TIMER0: 0x%x\n", __func__,
- + pr_debug("DEBUG_TIMER0: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x60));
- - pr_err("%s: DEBUG_TIMER1: 0x%x\n", __func__,
- + pr_debug("DEBUG_TIMER1: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x64));
- - pr_err("%s: DEBUG_GPI: 0x%x\n", __func__,
- + pr_debug("DEBUG_GPI: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x70));
- - pr_err("%s: DEBUG_GPO: 0x%x\n", __func__,
- + pr_debug("DEBUG_GPO: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x74));
- - pr_err("%s: DEBUG_T0: 0x%x\n", __func__,
- + pr_debug("DEBUG_T0: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x80));
- - pr_err("%s: DEBUG_R0: 0x%x\n", __func__,
- + pr_debug("DEBUG_R0: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x84));
- - pr_err("%s: DEBUG_T1: 0x%x\n", __func__,
- + pr_debug("DEBUG_T1: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x88));
- - pr_err("%s: DEBUG_R1: 0x%x\n", __func__,
- + pr_debug("DEBUG_R1: 0x%x\n",
- msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C));
- msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
- + msm_cpp_clear_timer(cpp_dev);
- cpp_deinit_mem(cpp_dev);
- + iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
- cpp_release_hardware(cpp_dev);
- + msm_cpp_empty_list(processing_q, list_frame);
- + msm_cpp_empty_list(eventData_q, list_eventdata);
- cpp_dev->state = CPP_STATE_OFF;
- }
- @@ -1109,18 +1074,19 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,
- return rc;
- }
- -static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
- +static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
- + uint32_t buff_mgr_ops)
- {
- struct v4l2_event v4l2_evt;
- - struct msm_queue_cmd *frame_qcmd;
- - struct msm_queue_cmd *event_qcmd;
- - struct msm_cpp_frame_info_t *processed_frame;
- + struct msm_queue_cmd *frame_qcmd = NULL;
- + struct msm_queue_cmd *event_qcmd = NULL;
- + struct msm_cpp_frame_info_t *processed_frame = NULL;
- struct msm_device_queue *queue = &cpp_dev->processing_q;
- struct msm_buf_mngr_info buff_mgr_info;
- int rc = 0;
- - if (queue->len > 0) {
- - frame_qcmd = msm_dequeue(queue, list_frame);
- + frame_qcmd = msm_dequeue(queue, list_frame);
- + if (frame_qcmd) {
- processed_frame = frame_qcmd->command;
- do_gettimeofday(&(processed_frame->out_time));
- kfree(frame_qcmd);
- @@ -1145,7 +1111,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
- buff_mgr_info.index =
- processed_frame->output_buffer_info[0].index;
- rc = msm_cpp_buffer_ops(cpp_dev,
- - VIDIOC_MSM_BUF_MNGR_BUF_DONE,
- + buff_mgr_ops,
- &buff_mgr_info);
- if (rc < 0) {
- pr_err("error putting buffer\n");
- @@ -1153,26 +1119,26 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
- }
- }
- - if (!processed_frame->output_buffer_info[1].processed_divert) {
- - if (processed_frame->duplicate_output) {
- - memset(&buff_mgr_info, 0 ,
- - sizeof(struct msm_buf_mngr_info));
- - buff_mgr_info.session_id =
- - ((processed_frame->duplicate_identity >> 16) & 0xFFFF);
- - buff_mgr_info.stream_id =
- - (processed_frame->duplicate_identity & 0xFFFF);
- - buff_mgr_info.frame_id = processed_frame->frame_id;
- - buff_mgr_info.timestamp = processed_frame->timestamp;
- - buff_mgr_info.index =
- - processed_frame->output_buffer_info[1].index;
- + if (processed_frame->duplicate_output &&
- + !processed_frame->
- + output_buffer_info[1].processed_divert) {
- + memset(&buff_mgr_info, 0 ,
- + sizeof(struct msm_buf_mngr_info));
- + buff_mgr_info.session_id =
- + ((processed_frame->duplicate_identity >> 16) & 0xFFFF);
- + buff_mgr_info.stream_id =
- + (processed_frame->duplicate_identity & 0xFFFF);
- + buff_mgr_info.frame_id = processed_frame->frame_id;
- + buff_mgr_info.timestamp = processed_frame->timestamp;
- + buff_mgr_info.index =
- + processed_frame->output_buffer_info[1].index;
- rc = msm_cpp_buffer_ops(cpp_dev,
- - VIDIOC_MSM_BUF_MNGR_BUF_DONE,
- + buff_mgr_ops,
- &buff_mgr_info);
- if (rc < 0) {
- pr_err("error putting buffer\n");
- rc = -EINVAL;
- }
- - }
- }
- v4l2_evt.id = processed_frame->inst_id;
- v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
- @@ -1181,127 +1147,92 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
- return rc;
- }
- +#if MSM_CPP_DUMP_FRM_CMD
- +static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
- +{
- + int i;
- + pr_err("%s: -------- cpp frame cmd msg start --------", __func__);
- + for (i = 0; i < len; i++)
- + pr_err("%s: msg[%03d] = 0x%08x", __func__, i, cmd[i]);
- + pr_err("%s: --------- cpp frame cmd msg end ---------", __func__);
- + return 0;
- +}
- +#else
- +static int msm_cpp_dump_frame_cmd(uint32_t *cmd, int32_t len)
- +{
- + return 0;
- +}
- +#endif
- +
- static void msm_cpp_do_timeout_work(struct work_struct *work)
- {
- int ret;
- uint32_t i = 0;
- - struct msm_cpp_frame_info_t *this_frame =
- - cpp_timers[del_timer_idx].data.processed_frame;
- - struct msm_cpp_frame_info_t *second_frame = NULL;
- - struct msm_queue_cmd *frame_qcmd = NULL;
- - struct msm_cpp_frame_info_t *processed_frame = NULL;
- - struct msm_device_queue *queue = NULL;
- -
- - mutex_lock(&cpp_timers[0].data.cpp_dev->mutex);
- -
- - pr_err("cpp_timer_callback called idx:%d. (jiffies=%lu)\n",
- - del_timer_idx, jiffies);
- - cpp_timers[del_timer_idx].used = 0;
- - cpp_timers[del_timer_idx].data.processed_frame = NULL;
- - del_timer_idx = 1 - del_timer_idx;
- + struct msm_cpp_frame_info_t *this_frame = NULL;
- - if (!work || !this_frame) {
- - pr_err("Invalid work:%p, this_frame:%p, del_idx:%d\n",
- - work, this_frame, del_timer_idx);
- - mutex_unlock(&cpp_timers[0].data.cpp_dev->mutex);
- + pr_err("cpp_timer_callback called. (jiffies=%lu)\n",
- + jiffies);
- + if (!work || cpp_timer.data.cpp_dev->state != CPP_STATE_ACTIVE) {
- + pr_err("Invalid work:%p or state:%d\n", work,
- + cpp_timer.data.cpp_dev->state);
- return;
- }
- -
- -
- - /* If cpp_dev state is off we can safely clear the pending frame or
- - If the trial count exceed max attempts then clean the pending frame */
- - if ((cpp_timers[0].data.cpp_dev->state != CPP_STATE_ACTIVE) ||
- - (cpp_timers[0].data.cpp_dev->timeout_trial_cnt >
- - MSM_CPP_MAX_TIMEOUT_TRIAL)) {
- - pr_err("State:%d\n, timeout_trial_cnt:%d\n",
- - cpp_timers[0].data.cpp_dev->state,
- - cpp_timers[0].data.cpp_dev->timeout_trial_cnt);
- -
- - queue = &cpp_timers[0].data.cpp_dev->processing_q;
- - frame_qcmd = msm_dequeue(queue, list_frame);
- - if (frame_qcmd) {
- - processed_frame = frame_qcmd->command;
- - kfree(frame_qcmd);
- - if (processed_frame)
- - kfree(processed_frame->cpp_cmd_msg);
- - kfree(processed_frame);
- - }
- - mutex_unlock(&cpp_timers[0].data.cpp_dev->mutex);
- + if (!atomic_read(&cpp_timer.used)) {
- + pr_err("Delayed trigger, IRQ serviced\n");
- return;
- }
- - pr_err("fatal: cpp_timer expired for identity=0x%x, frame_id=%03d",
- - this_frame->identity, this_frame->frame_id);
- -
- - if (cpp_timers[del_timer_idx].used == 1) {
- - pr_err("deleting cpp_timer %d.\n", del_timer_idx);
- - del_timer(&cpp_timers[del_timer_idx].cpp_timer);
- - cpp_timers[del_timer_idx].used = 0;
- - second_frame = cpp_timers[del_timer_idx].data.processed_frame;
- - cpp_timers[del_timer_idx].data.processed_frame = NULL;
- - del_timer_idx = 1 - del_timer_idx;
- - }
- -
- - disable_irq(cpp_timers[del_timer_idx].data.cpp_dev->irq->start);
- + disable_irq(cpp_timer.data.cpp_dev->irq->start);
- pr_err("Reloading firmware\n");
- - cpp_load_fw(cpp_timers[del_timer_idx].data.cpp_dev, NULL);
- + cpp_load_fw(cpp_timer.data.cpp_dev, NULL);
- pr_err("Firmware loading done\n");
- - enable_irq(cpp_timers[del_timer_idx].data.cpp_dev->irq->start);
- - msm_camera_io_w_mb(0x8,cpp_timers[del_timer_idx].data.cpp_dev->base +
- + enable_irq(cpp_timer.data.cpp_dev->irq->start);
- + msm_camera_io_w_mb(0x8, cpp_timer.data.cpp_dev->base +
- MSM_CPP_MICRO_IRQGEN_MASK);
- - msm_camera_io_w_mb(0xFFFF, cpp_timers[del_timer_idx].data.cpp_dev->base +
- + msm_camera_io_w_mb(0xFFFF,
- + cpp_timer.data.cpp_dev->base +
- MSM_CPP_MICRO_IRQGEN_CLR);
- - cpp_timers[set_timer_idx].data.processed_frame = this_frame;
- - cpp_timers[set_timer_idx].used = 1;
- - pr_err("ReInstalling cpp_timer %d\n", set_timer_idx);
- - setup_timer(&cpp_timers[set_timer_idx].cpp_timer, cpp_timer_callback,
- - (unsigned long)&cpp_timers[0]);
- + if (!atomic_read(&cpp_timer.used)) {
- + pr_err("Delayed trigger, IRQ serviced\n");
- + return;
- + }
- +
- + if (cpp_timer.data.cpp_dev->timeout_trial_cnt >=
- + MSM_CPP_MAX_TIMEOUT_TRIAL) {
- + pr_info("Max trial reached\n");
- + msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_PUT_BUF);
- + cpp_timer.data.cpp_dev->timeout_trial_cnt = 0;
- + return;
- + }
- +
- + this_frame = cpp_timer.data.processed_frame;
- pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n",
- CPP_CMD_TIMEOUT_MS, jiffies);
- - ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
- + ret = mod_timer(&cpp_timer.cpp_timer,
- jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
- if (ret)
- pr_err("error in mod_timer\n");
- - set_timer_idx = 1 - set_timer_idx;
- - pr_err("Rescheduling for identity=0x%x, frame_id=%03d",
- + pr_err("Rescheduling for identity=0x%x, frame_id=%03d\n",
- this_frame->identity, this_frame->frame_id);
- - msm_cpp_write(0x6, cpp_timers[set_timer_idx].data.cpp_dev->base);
- + msm_cpp_write(0x6, cpp_timer.data.cpp_dev->base);
- + msm_cpp_dump_frame_cmd(this_frame->cpp_cmd_msg,
- + this_frame->msg_len);
- for (i = 0; i < this_frame->msg_len; i++)
- msm_cpp_write(this_frame->cpp_cmd_msg[i],
- - cpp_timers[set_timer_idx].data.cpp_dev->base);
- -
- -
- - if (second_frame != NULL) {
- - cpp_timers[set_timer_idx].data.processed_frame = second_frame;
- - cpp_timers[set_timer_idx].used = 1;
- - pr_err("ReInstalling cpp_timer %d\n", set_timer_idx);
- - setup_timer(&cpp_timers[set_timer_idx].cpp_timer, cpp_timer_callback,
- - (unsigned long)&cpp_timers[0]);
- - pr_err("Starting timer to fire in %d ms. (jiffies=%lu)\n",
- - CPP_CMD_TIMEOUT_MS, jiffies);
- - ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
- - jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
- - if (ret)
- - pr_err("error in mod_timer\n");
- -
- - set_timer_idx = 1 - set_timer_idx;
- - pr_err("Rescheduling for identity=0x%x, frame_id=%03d",
- - second_frame->identity, second_frame->frame_id);
- - msm_cpp_write(0x6, cpp_timers[set_timer_idx].data.cpp_dev->base);
- - for (i = 0; i < second_frame->msg_len; i++)
- - msm_cpp_write(second_frame->cpp_cmd_msg[i],
- - cpp_timers[set_timer_idx].data.cpp_dev->base);
- - }
- - cpp_timers[1 - set_timer_idx].data.cpp_dev->timeout_trial_cnt++;
- - mutex_unlock(&cpp_timers[0].data.cpp_dev->mutex);
- + cpp_timer.data.cpp_dev->base);
- + cpp_timer.data.cpp_dev->timeout_trial_cnt++;
- + return;
- }
- void cpp_timer_callback(unsigned long data)
- {
- - queue_work(cpp_timers[set_timer_idx].data.cpp_dev->timer_wq,
- - (struct work_struct *)cpp_timers[set_timer_idx].data.cpp_dev->work);
- + struct msm_cpp_work_t *work =
- + cpp_timer.data.cpp_dev->work;
- + queue_work(cpp_timer.data.cpp_dev->timer_wq,
- + (struct work_struct *)work);
- }
- static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
- @@ -1317,22 +1248,22 @@ static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev,
- msm_enqueue(&cpp_dev->processing_q,
- &frame_qcmd->list_frame);
- - cpp_timers[set_timer_idx].data.processed_frame = process_frame;
- - cpp_timers[set_timer_idx].used = 1;
- + cpp_timer.data.processed_frame = process_frame;
- + atomic_set(&cpp_timer.used, 1);
- /* install timer for cpp timeout */
- - CPP_DBG("Installing cpp_timer %d\n", set_timer_idx);
- - setup_timer(&cpp_timers[set_timer_idx].cpp_timer, cpp_timer_callback,
- - (unsigned long)&cpp_timers[0]);
- - CPP_DBG( "Starting timer to fire in %d ms. (jiffies=%lu)\n",
- + CPP_DBG("Installing cpp_timer\n");
- + setup_timer(&cpp_timer.cpp_timer,
- + cpp_timer_callback, (unsigned long)&cpp_timer);
- + CPP_DBG("Starting timer to fire in %d ms. (jiffies=%lu)\n",
- CPP_CMD_TIMEOUT_MS, jiffies);
- - ret = mod_timer(&cpp_timers[set_timer_idx].cpp_timer,
- + ret = mod_timer(&cpp_timer.cpp_timer,
- jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
- if (ret)
- pr_err("error in mod_timer\n");
- - set_timer_idx = 1 - set_timer_idx;
- -
- msm_cpp_write(0x6, cpp_dev->base);
- + msm_cpp_dump_frame_cmd(process_frame->cpp_cmd_msg,
- + process_frame->msg_len);
- for (i = 0; i < process_frame->msg_len; i++) {
- if ((induce_error) && (i == 1)) {
- pr_err("Induce error\n");
- @@ -1368,9 +1299,8 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- uint16_t num_stripes = 0;
- struct msm_buf_mngr_info buff_mgr_info, dup_buff_mgr_info;
- int32_t status = 0;
- - uint8_t fw_version_1_2_x = 0;
- - int32_t *ret_status = 0;
- -
- + int in_fd;
- + int32_t stripe_base = 0;
- int i = 0;
- if (!new_frame) {
- pr_err("Insufficient memory. return\n");
- @@ -1382,9 +1312,16 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- if (rc) {
- ERR_COPY_FROM_USER();
- rc = -EINVAL;
- - goto ERROR0;
- + goto ERROR1;
- + }
- +
- + if ((new_frame->msg_len == 0) ||
- + (new_frame->msg_len > MSM_CPP_MAX_FRAME_LENGTH)) {
- + pr_err("%s:%d: Invalid frame len:%d\n", __func__,
- + __LINE__, new_frame->msg_len);
- + rc = -EINVAL;
- + goto ERROR1;
- }
- - ret_status = new_frame->status;
- cpp_frame_msg = kzalloc(sizeof(uint32_t)*new_frame->msg_len,
- GFP_KERNEL);
- @@ -1404,19 +1341,26 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- }
- new_frame->cpp_cmd_msg = cpp_frame_msg;
- -
- + if (cpp_frame_msg == NULL ||
- + (new_frame->msg_len < MSM_CPP_MIN_FRAME_LENGTH)) {
- + pr_err("%s %d Length is not correct or frame message is missing\n",
- + __func__, __LINE__);
- + return -EINVAL;
- + }
- + if (cpp_frame_msg[new_frame->msg_len - 1] != MSM_CPP_MSG_ID_TRAILER) {
- + pr_err("%s %d Invalid frame message\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- in_phyaddr = msm_cpp_fetch_buffer_info(cpp_dev,
- &new_frame->input_buffer_info,
- - ((new_frame->identity >> 16) & 0xFFFF),
- - (new_frame->identity & 0xFFFF));
- + ((new_frame->input_buffer_info.identity >> 16) & 0xFFFF),
- + (new_frame->input_buffer_info.identity & 0xFFFF), &in_fd);
- if (!in_phyaddr) {
- pr_err("error gettting input physical address\n");
- rc = -EINVAL;
- goto ERROR2;
- }
- - memset(&new_frame->output_buffer_info[0], 0,
- - sizeof(struct msm_cpp_buffer_info_t));
- memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
- buff_mgr_info.session_id = ((new_frame->identity >> 16) & 0xFFFF);
- buff_mgr_info.stream_id = (new_frame->identity & 0xFFFF);
- @@ -1431,7 +1375,8 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- out_phyaddr0 = msm_cpp_fetch_buffer_info(cpp_dev,
- &new_frame->output_buffer_info[0],
- ((new_frame->identity >> 16) & 0xFFFF),
- - (new_frame->identity & 0xFFFF));
- + (new_frame->identity & 0xFFFF),
- + &new_frame->output_buffer_info[0].fd);
- if (!out_phyaddr0) {
- pr_err("error gettting output physical address\n");
- rc = -EINVAL;
- @@ -1441,12 +1386,15 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- /* get buffer for duplicate output */
- if (new_frame->duplicate_output) {
- - pr_debug("duplication enabled, dup_id=0x%x", new_frame->duplicate_identity);
- + CPP_DBG("duplication enabled, dup_id=0x%x",
- + new_frame->duplicate_identity);
- memset(&new_frame->output_buffer_info[1], 0,
- sizeof(struct msm_cpp_buffer_info_t));
- memset(&dup_buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
- - dup_buff_mgr_info.session_id = ((new_frame->duplicate_identity >> 16) & 0xFFFF);
- - dup_buff_mgr_info.stream_id = (new_frame->duplicate_identity & 0xFFFF);
- + dup_buff_mgr_info.session_id =
- + ((new_frame->duplicate_identity >> 16) & 0xFFFF);
- + dup_buff_mgr_info.stream_id =
- + (new_frame->duplicate_identity & 0xFFFF);
- rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF,
- &dup_buff_mgr_info);
- if (rc < 0) {
- @@ -1454,11 +1402,13 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- pr_debug("error getting buffer rc:%d\n", rc);
- goto ERROR3;
- }
- - new_frame->output_buffer_info[1].index = dup_buff_mgr_info.index;
- + new_frame->output_buffer_info[1].index =
- + dup_buff_mgr_info.index;
- out_phyaddr1 = msm_cpp_fetch_buffer_info(cpp_dev,
- &new_frame->output_buffer_info[1],
- ((new_frame->duplicate_identity >> 16) & 0xFFFF),
- - (new_frame->duplicate_identity & 0xFFFF));
- + (new_frame->duplicate_identity & 0xFFFF),
- + &new_frame->output_buffer_info[1].fd);
- if (!out_phyaddr1) {
- pr_err("error gettting output physical address\n");
- rc = -EINVAL;
- @@ -1469,25 +1419,41 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- /* set duplicate enable bit */
- cpp_frame_msg[5] |= 0x1;
- }
- -
- +
- num_stripes = ((cpp_frame_msg[12] >> 20) & 0x3FF) +
- ((cpp_frame_msg[12] >> 10) & 0x3FF) +
- (cpp_frame_msg[12] & 0x3FF);
- - fw_version_1_2_x = 0;
- - if (cpp_dev->hw_info.cpp_hw_version == 0x10010000) {
- - fw_version_1_2_x = 2;
- + if ((cpp_dev->fw_version & 0xffff0000) ==
- + CPP_FW_VERSION_1_2_0) {
- + stripe_base = STRIPE_BASE_FW_1_2_0;
- + } else if ((cpp_dev->fw_version & 0xffff0000) ==
- + CPP_FW_VERSION_1_4_0) {
- + stripe_base = STRIPE_BASE_FW_1_4_0;
- + } else if ((cpp_dev->fw_version & 0xffff0000) ==
- + CPP_FW_VERSION_1_6_0) {
- + stripe_base = STRIPE_BASE_FW_1_6_0;
- + } else {
- + pr_err("invalid fw version %08x", cpp_dev->fw_version);
- }
- +
- + if ((stripe_base + num_stripes*27 + 1) != new_frame->msg_len) {
- + pr_err("Invalid frame message\n");
- + rc = -EINVAL;
- + goto ERROR3;
- + }
- +
- +
- for (i = 0; i < num_stripes; i++) {
- - cpp_frame_msg[(133 + fw_version_1_2_x) + i * 27] +=
- + cpp_frame_msg[stripe_base + 5 + i*27] +=
- (uint32_t) in_phyaddr;
- - cpp_frame_msg[(139 + fw_version_1_2_x) + i * 27] +=
- + cpp_frame_msg[stripe_base + 11 + i * 27] +=
- (uint32_t) out_phyaddr0;
- - cpp_frame_msg[(140 + fw_version_1_2_x) + i * 27] +=
- + cpp_frame_msg[stripe_base + 12 + i * 27] +=
- (uint32_t) out_phyaddr1;
- - cpp_frame_msg[(141 + fw_version_1_2_x) + i * 27] +=
- + cpp_frame_msg[stripe_base + 13 + i * 27] +=
- (uint32_t) out_phyaddr0;
- - cpp_frame_msg[(142 + fw_version_1_2_x) + i * 27] +=
- + cpp_frame_msg[stripe_base + 14 + i * 27] +=
- (uint32_t) out_phyaddr1;
- }
- @@ -1509,7 +1475,7 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
- ioctl_ptr->trans_code = rc;
- status = rc;
- - rc = (copy_to_user((void __user *)ret_status, &status,
- + rc = (copy_to_user((void __user *)new_frame->status, &status,
- sizeof(int32_t)) ? -EFAULT : 0);
- if (rc) {
- ERR_COPY_FROM_USER();
- @@ -1527,14 +1493,33 @@ ERROR2:
- ERROR1:
- ioctl_ptr->trans_code = rc;
- status = rc;
- - if (copy_to_user((void __user *)ret_status, &status,
- + if (copy_to_user((void __user *)new_frame->status, &status,
- sizeof(int32_t)))
- pr_err("error cannot copy error\n");
- -ERROR0:
- kfree(new_frame);
- return rc;
- }
- +void msm_cpp_clean_queue(struct cpp_device *cpp_dev)
- +{
- + struct msm_queue_cmd *frame_qcmd = NULL;
- + struct msm_cpp_frame_info_t *processed_frame = NULL;
- + struct msm_device_queue *queue = NULL;
- +
- + while (cpp_dev->processing_q.len) {
- + pr_info("queue len:%d\n", cpp_dev->processing_q.len);
- + queue = &cpp_dev->processing_q;
- + frame_qcmd = msm_dequeue(queue, list_frame);
- + if (frame_qcmd) {
- + processed_frame = frame_qcmd->command;
- + kfree(frame_qcmd);
- + if (processed_frame)
- + kfree(processed_frame->cpp_cmd_msg);
- + kfree(processed_frame);
- + }
- + }
- +}
- +
- long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- unsigned int cmd, void *arg)
- {
- @@ -1550,17 +1535,17 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- pr_err("cpp_dev is null\n");
- return -EINVAL;
- }
- +
- + if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)){
- + pr_err("ioctl_ptr OR ioctl_ptr->len is NULL %p %d \n",
- + ioctl_ptr, ioctl_ptr->len);
- + return -EINVAL;
- + }
- +
- mutex_lock(&cpp_dev->mutex);
- CPP_DBG("E cmd: %d\n", cmd);
- switch (cmd) {
- case VIDIOC_MSM_CPP_GET_HW_INFO: {
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- -
- if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- &cpp_dev->hw_info,
- sizeof(struct cpp_hw_info))) {
- @@ -1572,31 +1557,31 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- case VIDIOC_MSM_CPP_LOAD_FIRMWARE: {
- if (cpp_dev->is_firmware_loaded == 0) {
- - if (cpp_dev->fw_name_bin) {
- + if (cpp_dev->fw_name_bin != NULL) {
- kfree(cpp_dev->fw_name_bin);
- cpp_dev->fw_name_bin = NULL;
- }
- -
- - if (ioctl_ptr->len == 0) {
- - pr_err("ioctl_ptr->len is 0\n");
- + if (ioctl_ptr->len >= MSM_CPP_MAX_FW_NAME_LEN) {
- + pr_err("Error: ioctl_ptr->len = %d \n",
- + ioctl_ptr->len);
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- }
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- -
- - cpp_dev->fw_name_bin = kzalloc(ioctl_ptr->len, GFP_KERNEL);
- + cpp_dev->fw_name_bin = kzalloc(ioctl_ptr->len+1,
- + GFP_KERNEL);
- if (!cpp_dev->fw_name_bin) {
- pr_err("%s:%d: malloc error\n", __func__,
- __LINE__);
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- }
- -
- + if (ioctl_ptr->ioctl_ptr == NULL) {
- + pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- + kfree(cpp_dev->fw_name_bin);
- + cpp_dev->fw_name_bin = NULL;
- + mutex_unlock(&cpp_dev->mutex);
- + return -EINVAL;
- + }
- rc = (copy_from_user(cpp_dev->fw_name_bin,
- (void __user *)ioctl_ptr->ioctl_ptr,
- ioctl_ptr->len) ? -EFAULT : 0);
- @@ -1607,7 +1592,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- }
- -
- + *(cpp_dev->fw_name_bin+ioctl_ptr->len) = '\0';
- disable_irq(cpp_dev->irq->start);
- cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
- enable_irq(cpp_dev->irq->start);
- @@ -1616,13 +1601,6 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- break;
- }
- case VIDIOC_MSM_CPP_CFG:
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- -
- rc = msm_cpp_cfg(cpp_dev, ioctl_ptr);
- break;
- case VIDIOC_MSM_CPP_FLUSH_QUEUE:
- @@ -1639,12 +1617,6 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- return -EINVAL;
- }
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- -
- u_stream_buff_info = kzalloc(ioctl_ptr->len, GFP_KERNEL);
- if (!u_stream_buff_info) {
- pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- @@ -1662,21 +1634,28 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- return -EINVAL;
- }
- + if (u_stream_buff_info->num_buffs == 0) {
- + pr_err("%s:%d: Invalid number of buffers\n", __func__,
- + __LINE__);
- + kfree(u_stream_buff_info);
- + mutex_unlock(&cpp_dev->mutex);
- + return -EINVAL;
- + }
- k_stream_buff_info.num_buffs = u_stream_buff_info->num_buffs;
- k_stream_buff_info.identity = u_stream_buff_info->identity;
- - k_stream_buff_info.buffer_info =
- - kzalloc(k_stream_buff_info.num_buffs *
- - sizeof(struct msm_cpp_buffer_info_t), GFP_KERNEL);
- - if (!k_stream_buff_info.buffer_info) {
- - pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- +
- + if (k_stream_buff_info.num_buffs > MSM_CAMERA_MAX_STREAM_BUF) {
- + pr_err("%s:%d: unexpected large num buff requested\n",
- + __func__, __LINE__);
- kfree(u_stream_buff_info);
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- }
- -
- - if (u_stream_buff_info->buffer_info == NULL) {
- - pr_err("u_stream_buff_info->buffer_info is NULL\n");
- - kfree(k_stream_buff_info.buffer_info);
- + k_stream_buff_info.buffer_info =
- + kzalloc(k_stream_buff_info.num_buffs *
- + sizeof(struct msm_cpp_buffer_info_t), GFP_KERNEL);
- + if (ZERO_OR_NULL_PTR(k_stream_buff_info.buffer_info)) {
- + pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- kfree(u_stream_buff_info);
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- @@ -1700,6 +1679,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- ((k_stream_buff_info.identity >> 16) & 0xFFFF),
- (k_stream_buff_info.identity & 0xFFFF));
- }
- +
- if (!rc)
- rc = msm_cpp_enqueue_buff_info_list(cpp_dev,
- &k_stream_buff_info);
- @@ -1707,65 +1687,23 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- kfree(k_stream_buff_info.buffer_info);
- kfree(u_stream_buff_info);
- if (cpp_dev->stream_cnt == 0) {
- - struct msm_queue_cmd *frame_qcmd = NULL;
- - struct msm_cpp_frame_info_t *processed_frame = NULL;
- - struct msm_device_queue *queue = NULL;
- - rc = msm_isp_update_bandwidth(ISP_CPP, 981345600, 1066680000);
- - if (rc < 0) {
- - pr_err("Bandwidth Set Failed!\n");
- - msm_isp_update_bandwidth(ISP_CPP, 0, 0);
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- cpp_dev->state = CPP_STATE_ACTIVE;
- - cpp_dev->timeout_trial_cnt = 0;
- - if (cpp_timers[0].used == 1) {
- - del_timer(&cpp_timers[0].cpp_timer);
- - cpp_timers[0].used = 0;
- - cpp_timers[0].data.processed_frame = NULL;
- - }
- - if (cpp_timers[1].used == 1) {
- - del_timer(&cpp_timers[1].cpp_timer);
- - cpp_timers[1].used = 0;
- - cpp_timers[1].data.processed_frame = NULL;
- - }
- - if (cpp_dev->processing_q.len) {
- - queue = &cpp_dev->processing_q;
- - frame_qcmd = msm_dequeue(queue, list_frame);
- - if (frame_qcmd) {
- - processed_frame = frame_qcmd->command;
- - kfree(frame_qcmd);
- - if (processed_frame)
- - kfree(processed_frame->cpp_cmd_msg);
- - kfree(processed_frame);
- - }
- - }
- - del_timer_idx = 0;
- - set_timer_idx = 0;
- + msm_cpp_clear_timer(cpp_dev);
- + msm_cpp_clean_queue(cpp_dev);
- + }
- + if (cmd != VIDIOC_MSM_CPP_APPEND_STREAM_BUFF_INFO) {
- + cpp_dev->stream_cnt++;
- + pr_debug("stream_cnt:%d\n", cpp_dev->stream_cnt);
- }
- - cpp_dev->stream_cnt++;
- - pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt);
- break;
- }
- case VIDIOC_MSM_CPP_DEQUEUE_STREAM_BUFF_INFO: {
- uint32_t identity;
- struct msm_cpp_buff_queue_info_t *buff_queue_info;
- - struct msm_queue_cmd *frame_qcmd = NULL;
- - struct msm_cpp_frame_info_t *processed_frame = NULL;
- - struct msm_device_queue *queue = NULL;
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- if ((ioctl_ptr->len == 0) ||
- - (ioctl_ptr->len > sizeof(uint32_t))) {
- - pr_err("ioctl_ptr->len is wrong : %d\n", ioctl_ptr->len);
- - mutex_unlock(&cpp_dev->mutex);
- + (ioctl_ptr->len > sizeof(uint32_t)))
- return -EINVAL;
- - }
- rc = (copy_from_user(&identity,
- (void __user *)ioctl_ptr->ioctl_ptr,
- @@ -1791,40 +1729,18 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- buff_queue_info->stream_id);
- if (cpp_dev->stream_cnt > 0) {
- cpp_dev->stream_cnt--;
- - pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt);
- + pr_debug("stream_cnt:%d\n", cpp_dev->stream_cnt);
- if (cpp_dev->stream_cnt == 0) {
- rc = msm_isp_update_bandwidth(ISP_CPP, 0, 0);
- if (rc < 0)
- pr_err("Bandwidth Reset Failed!\n");
- - cpp_dev->state = CPP_STATE_IDLE;
- - cpp_dev->timeout_trial_cnt = 0;
- - if (cpp_timers[0].used == 1) {
- - del_timer(&cpp_timers[0].cpp_timer);
- - cpp_timers[0].used = 0;
- - cpp_timers[0].data.processed_frame = NULL;
- - }
- - if (cpp_timers[1].used == 1) {
- - del_timer(&cpp_timers[1].cpp_timer);
- - cpp_timers[1].used = 0;
- - cpp_timers[1].data.processed_frame = NULL;
- - }
- -
- - if (cpp_dev->processing_q.len) {
- - queue = &cpp_dev->processing_q;
- - frame_qcmd = msm_dequeue(queue, list_frame);
- - if (frame_qcmd) {
- - processed_frame = frame_qcmd->command;
- - kfree(frame_qcmd);
- - if (processed_frame)
- - kfree(processed_frame->cpp_cmd_msg);
- - kfree(processed_frame);
- - }
- - }
- - del_timer_idx = 0;
- - set_timer_idx = 0;
- + cpp_dev->state = CPP_STATE_IDLE;
- + msm_cpp_clear_timer(cpp_dev);
- + msm_cpp_clean_queue(cpp_dev);
- }
- } else {
- - pr_err("error: stream count underflow %d\n", cpp_dev->stream_cnt);
- + pr_err("error: stream count underflow %d\n",
- + cpp_dev->stream_cnt);
- }
- break;
- }
- @@ -1833,31 +1749,36 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- struct msm_queue_cmd *event_qcmd;
- struct msm_cpp_frame_info_t *process_frame;
- event_qcmd = msm_dequeue(queue, list_eventdata);
- - process_frame = event_qcmd->command;
- - CPP_DBG("fid %d\n", process_frame->frame_id);
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- - }
- + if(event_qcmd) {
- + process_frame = event_qcmd->command;
- + CPP_DBG("fid %d\n", process_frame->frame_id);
- + if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- + process_frame,
- + sizeof(struct msm_cpp_frame_info_t))) {
- + kfree(process_frame->cpp_cmd_msg);
- + process_frame->cpp_cmd_msg = NULL;
- + kfree(process_frame);
- + process_frame = NULL;
- + kfree(event_qcmd);
- + event_qcmd = NULL;
- + mutex_unlock(&cpp_dev->mutex);
- + return -EINVAL;
- + }
- - if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- - process_frame,
- - sizeof(struct msm_cpp_frame_info_t))) {
- - mutex_unlock(&cpp_dev->mutex);
- - return -EINVAL;
- + kfree(process_frame->cpp_cmd_msg);
- + kfree(process_frame);
- + kfree(event_qcmd);
- + } else {
- + pr_err("Empty command list\n");
- + return -EFAULT;
- }
- -
- - kfree(process_frame->cpp_cmd_msg);
- - kfree(process_frame);
- - kfree(event_qcmd);
- break;
- }
- -
- case VIDIOC_MSM_CPP_SET_CLOCK: {
- - long clock_rate = 0;
- - if (ioctl_ptr->len == 0 || (ioctl_ptr->len > sizeof(long))) {
- + struct msm_cpp_clock_settings_t clock_settings;
- + unsigned long clock_rate = 0;
- + CPP_DBG("VIDIOC_MSM_CPP_SET_CLOCK\n");
- + if (ioctl_ptr->len == 0) {
- pr_err("ioctl_ptr->len is 0\n");
- mutex_unlock(&cpp_dev->mutex);
- return -EINVAL;
- @@ -1869,7 +1790,13 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- return -EINVAL;
- }
- - rc = (copy_from_user(&clock_rate,
- + if (ioctl_ptr->len != sizeof(struct msm_cpp_clock_settings_t)) {
- + pr_err("Not valid ioctl_ptr->len\n");
- + mutex_unlock(&cpp_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = (copy_from_user(&clock_settings,
- (void __user *)ioctl_ptr->ioctl_ptr,
- ioctl_ptr->len) ? -EFAULT : 0);
- if (rc) {
- @@ -1878,22 +1805,67 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
- return -EINVAL;
- }
- - if ((clock_rate == MSM_CPP_NOMINAL_CLOCK) ||
- - (clock_rate == MSM_CPP_TURBO_CLOCK)) {
- - pr_err("clk:%ld\n", clock_rate);
- - clk_set_rate(cpp_dev->cpp_clk[4], clock_rate);
- + if (clock_settings.clock_rate > 0) {
- + rc = msm_isp_update_bandwidth(ISP_CPP,
- + clock_settings.avg,
- + clock_settings.inst);
- + if (rc < 0) {
- + pr_err("Bandwidth Set Failed!\n");
- + msm_isp_update_bandwidth(ISP_CPP, 0, 0);
- + mutex_unlock(&cpp_dev->mutex);
- + return -EINVAL;
- + }
- + clock_rate = clk_round_rate(
- + cpp_dev->cpp_clk[MSM_CPP_CORE_CLK_IDX],
- + clock_settings.clock_rate);
- + if (clock_rate != clock_settings.clock_rate)
- + pr_err("clock rate differ from settings\n");
- + clk_set_rate(cpp_dev->cpp_clk[MSM_CPP_CORE_CLK_IDX],
- + clock_rate);
- }
- -
- break;
- }
- case MSM_SD_SHUTDOWN: {
- - msm_cpp_empty_list_eventdata(&cpp_dev->eventData_q);
- mutex_unlock(&cpp_dev->mutex);
- + pr_info("shutdown cpp node. open cnt:%d\n",
- + cpp_dev->cpp_open_cnt);
- +
- + if (atomic_read(&cpp_timer.used))
- + pr_info("Timer state not cleared\n");
- +
- while (cpp_dev->cpp_open_cnt != 0)
- cpp_close_node(sd, NULL);
- + mutex_lock(&cpp_dev->mutex);
- rc = 0;
- break;
- }
- + case VIDIOC_MSM_CPP_QUEUE_BUF: {
- + struct msm_pproc_queue_buf_info queue_buf_info;
- + rc = (copy_from_user(&queue_buf_info,
- + (void __user *)ioctl_ptr->ioctl_ptr,
- + sizeof(struct msm_pproc_queue_buf_info)) ?
- + -EFAULT : 0);
- + if (rc) {
- + ERR_COPY_FROM_USER();
- + break;
- + }
- +
- + if (queue_buf_info.is_buf_dirty) {
- + rc = msm_cpp_buffer_ops(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_PUT_BUF,
- + &queue_buf_info.buff_mgr_info);
- + } else {
- + rc = msm_cpp_buffer_ops(cpp_dev,
- + VIDIOC_MSM_BUF_MNGR_BUF_DONE,
- + &queue_buf_info.buff_mgr_info);
- + }
- + if (rc < 0) {
- + pr_err("error in buf done\n");
- + rc = -EINVAL;
- + }
- +
- + break;
- + }
- }
- mutex_unlock(&cpp_dev->mutex);
- CPP_DBG("X\n");
- @@ -1951,23 +1923,13 @@ static long msm_cpp_subdev_do_ioctl(
- struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
- struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
- struct msm_cpp_frame_info_t inst_info;
- + memset(&inst_info, 0, sizeof(struct msm_cpp_frame_info_t));
- for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
- if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
- inst_info.inst_id = i;
- break;
- }
- }
- -
- - if (ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr is null\n");
- - return -EINVAL;
- - }
- -
- - if (ioctl_ptr->ioctl_ptr == NULL) {
- - pr_err("ioctl_ptr->ioctl_ptr is NULL\n");
- - return -EINVAL;
- - }
- -
- if (copy_to_user(
- (void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
- sizeof(struct msm_cpp_frame_info_t))) {
- @@ -2004,17 +1966,12 @@ static int cpp_register_domain(void)
- return msm_register_domain(&cpp_fw_layout);
- }
- +
- static int __devinit cpp_probe(struct platform_device *pdev)
- {
- struct cpp_device *cpp_dev;
- int rc = 0;
- - if (poweroff_charging == 1)
- - {
- - pr_err("forced return cpp_probe at lpm mode\n");
- - return rc;
- - }
- -
- cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
- if (!cpp_dev) {
- pr_err("no enough memory\n");
- @@ -2102,9 +2059,9 @@ static int __devinit cpp_probe(struct platform_device *pdev)
- }
- cpp_dev->iommu_ctx = msm_iommu_get_ctx("cpp");
- - if (!cpp_dev->iommu_ctx) {
- + if (IS_ERR(cpp_dev->iommu_ctx)) {
- pr_err("%s: cannot get iommu_ctx\n", __func__);
- - rc = -ENODEV;
- + rc = -EPROBE_DEFER;
- goto ERROR3;
- }
- @@ -2124,7 +2081,6 @@ static int __devinit cpp_probe(struct platform_device *pdev)
- cpp_dev->msm_sd.sd.entity.revision = cpp_dev->msm_sd.sd.devnode->num;
- cpp_dev->state = CPP_STATE_BOOT;
- cpp_init_hardware(cpp_dev);
- - iommu_attach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
- msm_camera_io_w(0x0, cpp_dev->base +
- MSM_CPP_MICRO_IRQGEN_MASK);
- @@ -2141,24 +2097,21 @@ static int __devinit cpp_probe(struct platform_device *pdev)
- tasklet_init(&cpp_dev->cpp_tasklet, msm_cpp_do_tasklet,
- (unsigned long)cpp_dev);
- cpp_dev->timer_wq = create_workqueue("msm_cpp_workqueue");
- - if(!cpp_dev->timer_wq) {
- - pr_err("%s: cannot create msm_cpp_workqueue\n", __func__);
- - rc = -EINVAL;
- + cpp_dev->work = kmalloc(sizeof(struct msm_cpp_work_t),
- + GFP_KERNEL);
- + if (!cpp_dev->work) {
- + pr_err("cpp_dev->work is NULL\n");
- + rc = -ENOMEM;
- goto ERROR3;
- }
- - cpp_dev->work =
- - (struct msm_cpp_work_t *)kmalloc(sizeof(struct msm_cpp_work_t),
- - GFP_KERNEL);
- +
- INIT_WORK((struct work_struct *)cpp_dev->work, msm_cpp_do_timeout_work);
- cpp_dev->cpp_open_cnt = 0;
- cpp_dev->is_firmware_loaded = 0;
- - cpp_timers[0].data.cpp_dev = cpp_dev;
- - cpp_timers[1].data.cpp_dev = cpp_dev;
- - cpp_timers[0].used = 0;
- - cpp_timers[1].used = 0;
- + cpp_timer.data.cpp_dev = cpp_dev;
- + atomic_set(&cpp_timer.used, 0);
- cpp_dev->fw_name_bin = NULL;
- return rc;
- -
- ERROR3:
- release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
- ERROR2:
- @@ -2188,7 +2141,6 @@ static int cpp_device_remove(struct platform_device *dev)
- return 0;
- }
- - iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx);
- msm_sd_unregister(&cpp_dev->msm_sd);
- release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
- release_mem_region(cpp_dev->vbif_mem->start,
- diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
- new file mode 100644
- index 0000000..717771d
- --- /dev/null
- +++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
- @@ -0,0 +1,1666 @@
- +/* Copyright (c) 2012-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.
- + */
- +
- +#define pr_fmt(fmt) "MSM-VPE %s:%d " fmt, __func__, __LINE__
- +
- +#include <linux/module.h>
- +#include <linux/mutex.h>
- +#include <linux/videodev2.h>
- +#include <linux/msm_ion.h>
- +#include <linux/iommu.h>
- +#include <mach/iommu_domains.h>
- +#include <mach/iommu.h>
- +#include <media/v4l2-dev.h>
- +#include <media/v4l2-event.h>
- +#include <media/v4l2-fh.h>
- +#include <media/v4l2-ioctl.h>
- +#include <media/v4l2-subdev.h>
- +#include <media/media-entity.h>
- +#include <media/msmb_generic_buf_mgr.h>
- +#include <media/msmb_pproc.h>
- +#include "msm_vpe.h"
- +#include "msm_camera_io_util.h"
- +
- +#define MSM_VPE_IDENT_TO_SESSION_ID(identity) ((identity >> 16) & 0xFFFF)
- +#define MSM_VPE_IDENT_TO_STREAM_ID(identity) (identity & 0xFFFF)
- +
- +#define MSM_VPE_DRV_NAME "msm_vpe"
- +
- +#define MSM_VPE_MAX_BUFF_QUEUE 16
- +
- +#define CONFIG_MSM_VPE_DBG 0
- +
- +#if CONFIG_MSM_VPE_DBG
- +#define VPE_DBG(fmt, args...) pr_err(fmt, ##args)
- +#else
- +#define VPE_DBG(fmt, args...) pr_debug(fmt, ##args)
- +#endif
- +
- +static void vpe_mem_dump(const char * const name, const void * const addr,
- + int size)
- +{
- + char line_str[128], *p_str;
- + int i;
- + u32 *p = (u32 *) addr;
- + u32 data;
- + VPE_DBG("%s: (%s) %p %d\n", __func__, name, addr, size);
- + line_str[0] = '\0';
- + p_str = line_str;
- + for (i = 0; i < size/4; i++) {
- + if (i % 4 == 0) {
- + snprintf(p_str, 12, "%08x: ", (u32) p);
- + p_str += 10;
- + }
- + data = *p++;
- + snprintf(p_str, 12, "%08x ", data);
- + p_str += 9;
- + if ((i + 1) % 4 == 0) {
- + VPE_DBG("%s\n", line_str);
- + line_str[0] = '\0';
- + p_str = line_str;
- + }
- + }
- + if (line_str[0] != '\0')
- + VPE_DBG("%s\n", line_str);
- +}
- +
- +static inline long long vpe_do_div(long long num, long long den)
- +{
- + do_div(num, den);
- + return num;
- +}
- +
- +#define msm_dequeue(queue, member) ({ \
- + unsigned long flags; \
- + struct msm_device_queue *__q = (queue); \
- + struct msm_queue_cmd *qcmd = 0; \
- + spin_lock_irqsave(&__q->lock, flags); \
- + if (!list_empty(&__q->list)) { \
- + __q->len--; \
- + qcmd = list_first_entry(&__q->list, \
- + struct msm_queue_cmd, \
- + member); \
- + list_del_init(&qcmd->member); \
- + } \
- + spin_unlock_irqrestore(&__q->lock, flags); \
- + qcmd; \
- + })
- +
- +static void msm_queue_init(struct msm_device_queue *queue, const char *name)
- +{
- + spin_lock_init(&queue->lock);
- + queue->len = 0;
- + queue->max = 0;
- + queue->name = name;
- + INIT_LIST_HEAD(&queue->list);
- + init_waitqueue_head(&queue->wait);
- +}
- +
- +static struct msm_cam_clk_info vpe_clk_info[] = {
- + {"vpe_clk", 160000000},
- + {"vpe_pclk", -1},
- +};
- +
- +static int msm_vpe_notify_frame_done(struct vpe_device *vpe_dev);
- +
- +static void msm_enqueue(struct msm_device_queue *queue,
- + struct list_head *entry)
- +{
- + unsigned long flags;
- + spin_lock_irqsave(&queue->lock, flags);
- + queue->len++;
- + if (queue->len > queue->max) {
- + queue->max = queue->len;
- + pr_debug("queue %s new max is %d\n", queue->name, queue->max);
- + }
- + list_add_tail(entry, &queue->list);
- + wake_up(&queue->wait);
- + VPE_DBG("woke up %s\n", queue->name);
- + spin_unlock_irqrestore(&queue->lock, flags);
- +}
- +
- +static struct msm_vpe_buff_queue_info_t *msm_vpe_get_buff_queue_entry(
- + struct vpe_device *vpe_dev, uint32_t session_id, uint32_t stream_id)
- +{
- + uint32_t i = 0;
- + struct msm_vpe_buff_queue_info_t *buff_queue_info = NULL;
- +
- + for (i = 0; i < vpe_dev->num_buffq; i++) {
- + if ((vpe_dev->buff_queue[i].used == 1) &&
- + (vpe_dev->buff_queue[i].session_id == session_id) &&
- + (vpe_dev->buff_queue[i].stream_id == stream_id)) {
- + buff_queue_info = &vpe_dev->buff_queue[i];
- + break;
- + }
- + }
- +
- + if (buff_queue_info == NULL) {
- + pr_err("error buffer queue entry for sess:%d strm:%d not found\n",
- + session_id, stream_id);
- + }
- + return buff_queue_info;
- +}
- +
- +static unsigned long msm_vpe_get_phy_addr(struct vpe_device *vpe_dev,
- + struct msm_vpe_buff_queue_info_t *buff_queue_info, uint32_t buff_index,
- + uint8_t native_buff)
- +{
- + unsigned long phy_add = 0;
- + struct list_head *buff_head;
- + struct msm_vpe_buffer_map_list_t *buff, *save;
- +
- + if (native_buff)
- + buff_head = &buff_queue_info->native_buff_head;
- + else
- + buff_head = &buff_queue_info->vb2_buff_head;
- +
- + list_for_each_entry_safe(buff, save, buff_head, entry) {
- + if (buff->map_info.buff_info.index == buff_index) {
- + phy_add = buff->map_info.phy_addr;
- + break;
- + }
- + }
- +
- + return phy_add;
- +}
- +
- +static unsigned long msm_vpe_queue_buffer_info(struct vpe_device *vpe_dev,
- + struct msm_vpe_buff_queue_info_t *buff_queue,
- + struct msm_vpe_buffer_info_t *buffer_info)
- +{
- + struct list_head *buff_head;
- + struct msm_vpe_buffer_map_list_t *buff, *save;
- + int rc = 0;
- +
- + if (buffer_info->native_buff)
- + buff_head = &buff_queue->native_buff_head;
- + else
- + buff_head = &buff_queue->vb2_buff_head;
- +
- + list_for_each_entry_safe(buff, save, buff_head, entry) {
- + if (buff->map_info.buff_info.index == buffer_info->index) {
- + pr_err("error buffer index already queued\n");
- + return -EINVAL;
- + }
- + }
- +
- + buff = kzalloc(
- + sizeof(struct msm_vpe_buffer_map_list_t), GFP_KERNEL);
- + if (!buff) {
- + pr_err("error allocating memory\n");
- + return -EINVAL;
- + }
- +
- + buff->map_info.buff_info = *buffer_info;
- + buff->map_info.ion_handle = ion_import_dma_buf(vpe_dev->client,
- + buffer_info->fd);
- + if (IS_ERR_OR_NULL(buff->map_info.ion_handle)) {
- + pr_err("ION import failed\n");
- + goto queue_buff_error1;
- + }
- +
- + rc = ion_map_iommu(vpe_dev->client, buff->map_info.ion_handle,
- + vpe_dev->domain_num, 0, SZ_4K, 0,
- + (unsigned long *)&buff->map_info.phy_addr,
- + &buff->map_info.len, 0, 0);
- + if (rc < 0) {
- + pr_err("ION mmap failed\n");
- + goto queue_buff_error2;
- + }
- +
- + INIT_LIST_HEAD(&buff->entry);
- + list_add_tail(&buff->entry, buff_head);
- +
- + return buff->map_info.phy_addr;
- +
- +queue_buff_error2:
- + ion_unmap_iommu(vpe_dev->client, buff->map_info.ion_handle,
- + vpe_dev->domain_num, 0);
- +queue_buff_error1:
- + ion_free(vpe_dev->client, buff->map_info.ion_handle);
- + buff->map_info.ion_handle = NULL;
- + kzfree(buff);
- +
- + return 0;
- +}
- +
- +static void msm_vpe_dequeue_buffer_info(struct vpe_device *vpe_dev,
- + struct msm_vpe_buffer_map_list_t *buff)
- +{
- + ion_unmap_iommu(vpe_dev->client, buff->map_info.ion_handle,
- + vpe_dev->domain_num, 0);
- + ion_free(vpe_dev->client, buff->map_info.ion_handle);
- + buff->map_info.ion_handle = NULL;
- +
- + list_del_init(&buff->entry);
- + kzfree(buff);
- +
- + return;
- +}
- +
- +static unsigned long msm_vpe_fetch_buffer_info(struct vpe_device *vpe_dev,
- + struct msm_vpe_buffer_info_t *buffer_info, uint32_t session_id,
- + uint32_t stream_id)
- +{
- + unsigned long phy_addr = 0;
- + struct msm_vpe_buff_queue_info_t *buff_queue_info;
- + uint8_t native_buff = buffer_info->native_buff;
- +
- + buff_queue_info = msm_vpe_get_buff_queue_entry(vpe_dev, session_id,
- + stream_id);
- + if (buff_queue_info == NULL) {
- + pr_err("error finding buffer queue entry for sessid:%d strmid:%d\n",
- + session_id, stream_id);
- + return phy_addr;
- + }
- +
- + phy_addr = msm_vpe_get_phy_addr(vpe_dev, buff_queue_info,
- + buffer_info->index, native_buff);
- + if ((phy_addr == 0) && (native_buff)) {
- + phy_addr = msm_vpe_queue_buffer_info(vpe_dev, buff_queue_info,
- + buffer_info);
- + }
- + return phy_addr;
- +}
- +
- +static int32_t msm_vpe_enqueue_buff_info_list(struct vpe_device *vpe_dev,
- + struct msm_vpe_stream_buff_info_t *stream_buff_info)
- +{
- + uint32_t j;
- + struct msm_vpe_buff_queue_info_t *buff_queue_info;
- +
- + buff_queue_info = msm_vpe_get_buff_queue_entry(vpe_dev,
- + (stream_buff_info->identity >> 16) & 0xFFFF,
- + stream_buff_info->identity & 0xFFFF);
- + if (buff_queue_info == NULL) {
- + pr_err("error finding buffer queue entry for sessid:%d strmid:%d\n",
- + (stream_buff_info->identity >> 16) & 0xFFFF,
- + stream_buff_info->identity & 0xFFFF);
- + return -EINVAL;
- + }
- +
- + for (j = 0; j < stream_buff_info->num_buffs; j++) {
- + msm_vpe_queue_buffer_info(vpe_dev, buff_queue_info,
- + &stream_buff_info->buffer_info[j]);
- + }
- + return 0;
- +}
- +
- +static int32_t msm_vpe_dequeue_buff_info_list(struct vpe_device *vpe_dev,
- + struct msm_vpe_buff_queue_info_t *buff_queue_info)
- +{
- + struct msm_vpe_buffer_map_list_t *buff, *save;
- + struct list_head *buff_head;
- +
- + buff_head = &buff_queue_info->native_buff_head;
- + list_for_each_entry_safe(buff, save, buff_head, entry) {
- + msm_vpe_dequeue_buffer_info(vpe_dev, buff);
- + }
- +
- + buff_head = &buff_queue_info->vb2_buff_head;
- + list_for_each_entry_safe(buff, save, buff_head, entry) {
- + msm_vpe_dequeue_buffer_info(vpe_dev, buff);
- + }
- +
- + return 0;
- +}
- +
- +static int32_t msm_vpe_add_buff_queue_entry(struct vpe_device *vpe_dev,
- + uint16_t session_id, uint16_t stream_id)
- +{
- + uint32_t i;
- + struct msm_vpe_buff_queue_info_t *buff_queue_info;
- +
- + for (i = 0; i < vpe_dev->num_buffq; i++) {
- + if (vpe_dev->buff_queue[i].used == 0) {
- + buff_queue_info = &vpe_dev->buff_queue[i];
- + buff_queue_info->used = 1;
- + buff_queue_info->session_id = session_id;
- + buff_queue_info->stream_id = stream_id;
- + INIT_LIST_HEAD(&buff_queue_info->vb2_buff_head);
- + INIT_LIST_HEAD(&buff_queue_info->native_buff_head);
- + return 0;
- + }
- + }
- + pr_err("buffer queue full. error for sessionid: %d streamid: %d\n",
- + session_id, stream_id);
- + return -EINVAL;
- +}
- +
- +static int32_t msm_vpe_free_buff_queue_entry(struct vpe_device *vpe_dev,
- + uint32_t session_id, uint32_t stream_id)
- +{
- + struct msm_vpe_buff_queue_info_t *buff_queue_info;
- +
- + buff_queue_info = msm_vpe_get_buff_queue_entry(vpe_dev, session_id,
- + stream_id);
- + if (buff_queue_info == NULL) {
- + pr_err("error finding buffer queue entry for sessid:%d strmid:%d\n",
- + session_id, stream_id);
- + return -EINVAL;
- + }
- +
- + buff_queue_info->used = 0;
- + buff_queue_info->session_id = 0;
- + buff_queue_info->stream_id = 0;
- + INIT_LIST_HEAD(&buff_queue_info->vb2_buff_head);
- + INIT_LIST_HEAD(&buff_queue_info->native_buff_head);
- + return 0;
- +}
- +
- +static int32_t msm_vpe_create_buff_queue(struct vpe_device *vpe_dev,
- + uint32_t num_buffq)
- +{
- + struct msm_vpe_buff_queue_info_t *buff_queue;
- + buff_queue = kzalloc(
- + sizeof(struct msm_vpe_buff_queue_info_t) * num_buffq,
- + GFP_KERNEL);
- + if (!buff_queue) {
- + pr_err("Buff queue allocation failure\n");
- + return -ENOMEM;
- + }
- +
- + if (vpe_dev->buff_queue) {
- + pr_err("Buff queue not empty\n");
- + kzfree(buff_queue);
- + return -EINVAL;
- + } else {
- + vpe_dev->buff_queue = buff_queue;
- + vpe_dev->num_buffq = num_buffq;
- + }
- + return 0;
- +}
- +
- +static void msm_vpe_delete_buff_queue(struct vpe_device *vpe_dev)
- +{
- + uint32_t i;
- +
- + for (i = 0; i < vpe_dev->num_buffq; i++) {
- + if (vpe_dev->buff_queue[i].used == 1) {
- + pr_err("Queue not free sessionid: %d, streamid: %d\n",
- + vpe_dev->buff_queue[i].session_id,
- + vpe_dev->buff_queue[i].stream_id);
- + msm_vpe_free_buff_queue_entry(vpe_dev,
- + vpe_dev->buff_queue[i].session_id,
- + vpe_dev->buff_queue[i].stream_id);
- + }
- + }
- + kzfree(vpe_dev->buff_queue);
- + vpe_dev->buff_queue = NULL;
- + vpe_dev->num_buffq = 0;
- + return;
- +}
- +
- +void vpe_release_ion_client(struct kref *ref)
- +{
- + struct vpe_device *vpe_dev = container_of(ref,
- + struct vpe_device, refcount);
- + ion_client_destroy(vpe_dev->client);
- +}
- +
- +static int vpe_init_mem(struct vpe_device *vpe_dev)
- +{
- + kref_init(&vpe_dev->refcount);
- + kref_get(&vpe_dev->refcount);
- + vpe_dev->client = msm_ion_client_create(-1, "vpe");
- +
- + if (!vpe_dev->client) {
- + pr_err("couldn't create ion client\n");
- + return -ENODEV;
- + }
- +
- + return 0;
- +}
- +
- +static void vpe_deinit_mem(struct vpe_device *vpe_dev)
- +{
- + kref_put(&vpe_dev->refcount, vpe_release_ion_client);
- +}
- +
- +static irqreturn_t msm_vpe_irq(int irq_num, void *data)
- +{
- + unsigned long flags;
- + uint32_t irq_status;
- + struct msm_vpe_tasklet_queue_cmd *queue_cmd;
- + struct vpe_device *vpe_dev = (struct vpe_device *) data;
- +
- + irq_status = msm_camera_io_r_mb(vpe_dev->base +
- + VPE_INTR_STATUS_OFFSET);
- +
- + spin_lock_irqsave(&vpe_dev->tasklet_lock, flags);
- + queue_cmd = &vpe_dev->tasklet_queue_cmd[vpe_dev->taskletq_idx];
- + if (queue_cmd->cmd_used) {
- + VPE_DBG("%s: vpe tasklet queue overflow\n", __func__);
- + list_del(&queue_cmd->list);
- + } else {
- + atomic_add(1, &vpe_dev->irq_cnt);
- + }
- + queue_cmd->irq_status = irq_status;
- +
- + queue_cmd->cmd_used = 1;
- + vpe_dev->taskletq_idx =
- + (vpe_dev->taskletq_idx + 1) % MSM_VPE_TASKLETQ_SIZE;
- + list_add_tail(&queue_cmd->list, &vpe_dev->tasklet_q);
- + spin_unlock_irqrestore(&vpe_dev->tasklet_lock, flags);
- +
- + tasklet_schedule(&vpe_dev->vpe_tasklet);
- +
- + msm_camera_io_w_mb(irq_status, vpe_dev->base + VPE_INTR_CLEAR_OFFSET);
- + msm_camera_io_w(0, vpe_dev->base + VPE_INTR_ENABLE_OFFSET);
- + VPE_DBG("%s: irq_status=0x%x.\n", __func__, irq_status);
- +
- + return IRQ_HANDLED;
- +}
- +
- +static void msm_vpe_do_tasklet(unsigned long data)
- +{
- + unsigned long flags;
- + struct vpe_device *vpe_dev = (struct vpe_device *)data;
- + struct msm_vpe_tasklet_queue_cmd *queue_cmd;
- +
- + while (atomic_read(&vpe_dev->irq_cnt)) {
- + spin_lock_irqsave(&vpe_dev->tasklet_lock, flags);
- + queue_cmd = list_first_entry(&vpe_dev->tasklet_q,
- + struct msm_vpe_tasklet_queue_cmd, list);
- + if (!queue_cmd) {
- + atomic_set(&vpe_dev->irq_cnt, 0);
- + spin_unlock_irqrestore(&vpe_dev->tasklet_lock, flags);
- + return;
- + }
- + atomic_sub(1, &vpe_dev->irq_cnt);
- + list_del(&queue_cmd->list);
- + queue_cmd->cmd_used = 0;
- +
- + spin_unlock_irqrestore(&vpe_dev->tasklet_lock, flags);
- +
- + VPE_DBG("Frame done!!\n");
- + msm_vpe_notify_frame_done(vpe_dev);
- + }
- +}
- +
- +static int vpe_init_hardware(struct vpe_device *vpe_dev)
- +{
- + int rc = 0;
- +
- + if (vpe_dev->fs_vpe == NULL) {
- + vpe_dev->fs_vpe =
- + regulator_get(&vpe_dev->pdev->dev, "vdd");
- + if (IS_ERR(vpe_dev->fs_vpe)) {
- + pr_err("Regulator vpe vdd get failed %ld\n",
- + PTR_ERR(vpe_dev->fs_vpe));
- + vpe_dev->fs_vpe = NULL;
- + rc = -ENODEV;
- + goto fail;
- + } else if (regulator_enable(vpe_dev->fs_vpe)) {
- + pr_err("Regulator vpe vdd enable failed\n");
- + regulator_put(vpe_dev->fs_vpe);
- + vpe_dev->fs_vpe = NULL;
- + rc = -ENODEV;
- + goto fail;
- + }
- + }
- +
- + rc = msm_cam_clk_enable(&vpe_dev->pdev->dev, vpe_clk_info,
- + vpe_dev->vpe_clk, ARRAY_SIZE(vpe_clk_info), 1);
- + if (rc < 0) {
- + rc = -ENODEV;
- + pr_err("clk enable failed\n");
- + goto disable_and_put_regulator;
- + }
- +
- + vpe_dev->base = ioremap(vpe_dev->mem->start,
- + resource_size(vpe_dev->mem));
- + if (!vpe_dev->base) {
- + rc = -ENOMEM;
- + pr_err("ioremap failed\n");
- + goto disable_and_put_regulator;
- + }
- +
- + if (vpe_dev->state != VPE_STATE_BOOT) {
- + rc = request_irq(vpe_dev->irq->start, msm_vpe_irq,
- + IRQF_TRIGGER_RISING,
- + "vpe", vpe_dev);
- + if (rc < 0) {
- + pr_err("irq request fail! start=%u\n",
- + vpe_dev->irq->start);
- + rc = -EBUSY;
- + goto unmap_base;
- + } else {
- + VPE_DBG("Got irq! %d\n", vpe_dev->irq->start);
- + }
- + } else {
- + VPE_DBG("Skip requesting the irq since device is booting\n");
- + }
- + vpe_dev->buf_mgr_subdev = msm_buf_mngr_get_subdev();
- +
- + msm_vpe_create_buff_queue(vpe_dev, MSM_VPE_MAX_BUFF_QUEUE);
- + return rc;
- +
- +unmap_base:
- + iounmap(vpe_dev->base);
- +disable_and_put_regulator:
- + regulator_disable(vpe_dev->fs_vpe);
- + regulator_put(vpe_dev->fs_vpe);
- +fail:
- + return rc;
- +}
- +
- +static int vpe_release_hardware(struct vpe_device *vpe_dev)
- +{
- + if (vpe_dev->state != VPE_STATE_BOOT) {
- + free_irq(vpe_dev->irq->start, vpe_dev);
- + tasklet_kill(&vpe_dev->vpe_tasklet);
- + atomic_set(&vpe_dev->irq_cnt, 0);
- + }
- +
- + msm_vpe_delete_buff_queue(vpe_dev);
- + iounmap(vpe_dev->base);
- + msm_cam_clk_enable(&vpe_dev->pdev->dev, vpe_clk_info,
- + vpe_dev->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
- + return 0;
- +}
- +
- +static int vpe_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- +{
- + int rc = 0;
- + uint32_t i;
- + struct vpe_device *vpe_dev = v4l2_get_subdevdata(sd);
- +
- + mutex_lock(&vpe_dev->mutex);
- + if (vpe_dev->vpe_open_cnt == MAX_ACTIVE_VPE_INSTANCE) {
- + pr_err("No free VPE instance\n");
- + rc = -ENODEV;
- + goto err_mutex_unlock;
- + }
- +
- + for (i = 0; i < MAX_ACTIVE_VPE_INSTANCE; i++) {
- + if (vpe_dev->vpe_subscribe_list[i].active == 0) {
- + vpe_dev->vpe_subscribe_list[i].active = 1;
- + vpe_dev->vpe_subscribe_list[i].vfh = &fh->vfh;
- + break;
- + }
- + }
- + if (i == MAX_ACTIVE_VPE_INSTANCE) {
- + pr_err("No free instance\n");
- + rc = -ENODEV;
- + goto err_mutex_unlock;
- + }
- +
- + VPE_DBG("open %d %p\n", i, &fh->vfh);
- + vpe_dev->vpe_open_cnt++;
- + if (vpe_dev->vpe_open_cnt == 1) {
- + rc = vpe_init_hardware(vpe_dev);
- + if (rc < 0) {
- + pr_err("%s: Couldn't init vpe hardware\n", __func__);
- + vpe_dev->vpe_open_cnt--;
- + rc = -ENODEV;
- + goto err_fixup_sub_list;
- + }
- + rc = vpe_init_mem(vpe_dev);
- + if (rc < 0) {
- + pr_err("%s: Couldn't init mem\n", __func__);
- + vpe_dev->vpe_open_cnt--;
- + rc = -ENODEV;
- + goto err_release_hardware;
- + }
- + vpe_dev->state = VPE_STATE_IDLE;
- + }
- + mutex_unlock(&vpe_dev->mutex);
- +
- + return rc;
- +
- +err_release_hardware:
- + vpe_release_hardware(vpe_dev);
- +err_fixup_sub_list:
- + for (i = 0; i < MAX_ACTIVE_VPE_INSTANCE; i++) {
- + if (vpe_dev->vpe_subscribe_list[i].vfh == &fh->vfh) {
- + vpe_dev->vpe_subscribe_list[i].active = 0;
- + vpe_dev->vpe_subscribe_list[i].vfh = NULL;
- + break;
- + }
- + }
- +err_mutex_unlock:
- + mutex_unlock(&vpe_dev->mutex);
- + return rc;
- +}
- +
- +static int vpe_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
- +{
- + uint32_t i;
- + struct vpe_device *vpe_dev = v4l2_get_subdevdata(sd);
- + mutex_lock(&vpe_dev->mutex);
- + for (i = 0; i < MAX_ACTIVE_VPE_INSTANCE; i++) {
- + if (vpe_dev->vpe_subscribe_list[i].vfh == &fh->vfh) {
- + vpe_dev->vpe_subscribe_list[i].active = 0;
- + vpe_dev->vpe_subscribe_list[i].vfh = NULL;
- + break;
- + }
- + }
- + if (i == MAX_ACTIVE_VPE_INSTANCE) {
- + pr_err("Invalid close\n");
- + mutex_unlock(&vpe_dev->mutex);
- + return -ENODEV;
- + }
- +
- + VPE_DBG("close %d %p\n", i, &fh->vfh);
- + vpe_dev->vpe_open_cnt--;
- + if (vpe_dev->vpe_open_cnt == 0) {
- + vpe_deinit_mem(vpe_dev);
- + vpe_release_hardware(vpe_dev);
- + vpe_dev->state = VPE_STATE_OFF;
- + }
- + mutex_unlock(&vpe_dev->mutex);
- + return 0;
- +}
- +
- +static const struct v4l2_subdev_internal_ops msm_vpe_internal_ops = {
- + .open = vpe_open_node,
- + .close = vpe_close_node,
- +};
- +
- +static int msm_vpe_buffer_ops(struct vpe_device *vpe_dev,
- + uint32_t buff_mgr_ops, struct msm_buf_mngr_info *buff_mgr_info)
- +{
- + int rc = -EINVAL;
- +
- + rc = v4l2_subdev_call(vpe_dev->buf_mgr_subdev, core, ioctl,
- + buff_mgr_ops, buff_mgr_info);
- + if (rc < 0)
- + pr_err("%s: line %d rc = %d\n", __func__, __LINE__, rc);
- + return rc;
- +}
- +
- +static int msm_vpe_notify_frame_done(struct vpe_device *vpe_dev)
- +{
- + struct v4l2_event v4l2_evt;
- + struct msm_queue_cmd *frame_qcmd;
- + struct msm_queue_cmd *event_qcmd;
- + struct msm_vpe_frame_info_t *processed_frame;
- + struct msm_device_queue *queue = &vpe_dev->processing_q;
- + struct msm_buf_mngr_info buff_mgr_info;
- + int rc = 0;
- +
- + if (queue->len > 0) {
- + frame_qcmd = msm_dequeue(queue, list_frame);
- + if(frame_qcmd) {
- + processed_frame = frame_qcmd->command;
- + do_gettimeofday(&(processed_frame->out_time));
- + kfree(frame_qcmd);
- + event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_ATOMIC);
- + if (!event_qcmd) {
- + pr_err("%s: Insufficient memory\n", __func__);
- + return -ENOMEM;
- + }
- + atomic_set(&event_qcmd->on_heap, 1);
- + event_qcmd->command = processed_frame;
- + VPE_DBG("fid %d\n", processed_frame->frame_id);
- + msm_enqueue(&vpe_dev->eventData_q, &event_qcmd->list_eventdata);
- +
- + if (!processed_frame->output_buffer_info.processed_divert) {
- + memset(&buff_mgr_info, 0 ,
- + sizeof(buff_mgr_info));
- + buff_mgr_info.session_id =
- + ((processed_frame->identity >> 16) & 0xFFFF);
- + buff_mgr_info.stream_id =
- + (processed_frame->identity & 0xFFFF);
- + buff_mgr_info.frame_id = processed_frame->frame_id;
- + buff_mgr_info.timestamp = processed_frame->timestamp;
- + buff_mgr_info.index =
- + processed_frame->output_buffer_info.index;
- + rc = msm_vpe_buffer_ops(vpe_dev,
- + VIDIOC_MSM_BUF_MNGR_BUF_DONE,
- + &buff_mgr_info);
- + if (rc < 0) {
- + pr_err("%s: error doing VIDIOC_MSM_BUF_MNGR_BUF_DONE\n",
- + __func__);
- + rc = -EINVAL;
- + }
- + }
- +
- + v4l2_evt.id = processed_frame->inst_id;
- + v4l2_evt.type = V4L2_EVENT_VPE_FRAME_DONE;
- + v4l2_event_queue(vpe_dev->msm_sd.sd.devnode, &v4l2_evt);
- + }
- + else
- + rc = -EFAULT;
- + }
- + return rc;
- +}
- +
- +static void vpe_update_scaler_params(struct vpe_device *vpe_dev,
- + struct msm_vpe_frame_strip_info strip_info)
- +{
- + uint32_t out_ROI_width, out_ROI_height;
- + uint32_t src_ROI_width, src_ROI_height;
- +
- + /*
- + * phase_step_x, phase_step_y, phase_init_x and phase_init_y
- + * are represented in fixed-point, unsigned 3.29 format
- + */
- + uint32_t phase_step_x = 0;
- + uint32_t phase_step_y = 0;
- + uint32_t phase_init_x = 0;
- + uint32_t phase_init_y = 0;
- +
- + uint32_t src_roi, src_x, src_y, src_xy, temp;
- + uint32_t yscale_filter_sel, xscale_filter_sel;
- + uint32_t scale_unit_sel_x, scale_unit_sel_y;
- + uint64_t numerator, denominator;
- +
- + /*
- + * assumption is both direction need zoom. this can be
- + * improved.
- + */
- + temp = msm_camera_io_r(vpe_dev->base + VPE_OP_MODE_OFFSET) | 0x3;
- + msm_camera_io_w(temp, vpe_dev->base + VPE_OP_MODE_OFFSET);
- +
- + src_ROI_width = strip_info.src_w;
- + src_ROI_height = strip_info.src_h;
- + out_ROI_width = strip_info.dst_w;
- + out_ROI_height = strip_info.dst_h;
- +
- + VPE_DBG("src w = %u, h=%u, dst w = %u, h =%u.\n",
- + src_ROI_width, src_ROI_height, out_ROI_width,
- + out_ROI_height);
- + src_roi = (src_ROI_height << 16) + src_ROI_width;
- +
- + msm_camera_io_w(src_roi, vpe_dev->base + VPE_SRC_SIZE_OFFSET);
- +
- + src_x = strip_info.src_x;
- + src_y = strip_info.src_y;
- +
- + VPE_DBG("src_x = %d, src_y=%d.\n", src_x, src_y);
- +
- + src_xy = src_y*(1<<16) + src_x;
- + msm_camera_io_w(src_xy, vpe_dev->base +
- + VPE_SRC_XY_OFFSET);
- + VPE_DBG("src_xy = 0x%x, src_roi=0x%x.\n", src_xy, src_roi);
- +
- + /* decide whether to use FIR or M/N for scaling */
- + if ((out_ROI_width == 1 && src_ROI_width < 4) ||
- + (src_ROI_width < 4 * out_ROI_width - 3))
- + scale_unit_sel_x = 0;/* use FIR scalar */
- + else
- + scale_unit_sel_x = 1;/* use M/N scalar */
- +
- + if ((out_ROI_height == 1 && src_ROI_height < 4) ||
- + (src_ROI_height < 4 * out_ROI_height - 3))
- + scale_unit_sel_y = 0;/* use FIR scalar */
- + else
- + scale_unit_sel_y = 1;/* use M/N scalar */
- +
- + /* calculate phase step for the x direction */
- +
- + /*
- + * if destination is only 1 pixel wide, the value of
- + * phase_step_x is unimportant. Assigning phase_step_x to src
- + * ROI width as an arbitrary value.
- + */
- + if (out_ROI_width == 1)
- + phase_step_x = (uint32_t) ((src_ROI_width) <<
- + SCALER_PHASE_BITS);
- +
- + /* if using FIR scalar */
- + else if (scale_unit_sel_x == 0) {
- +
- + /*
- + * Calculate the quotient ( src_ROI_width - 1 ) (
- + * out_ROI_width - 1) with u3.29 precision. Quotient
- + * is rounded up to the larger 29th decimal point
- + */
- + numerator = (uint64_t)(src_ROI_width - 1) <<
- + SCALER_PHASE_BITS;
- + /*
- + * never equals to 0 because of the "(out_ROI_width ==
- + * 1 )"
- + */
- + denominator = (uint64_t)(out_ROI_width - 1);
- + /*
- + * divide and round up to the larger 29th decimal
- + * point.
- + */
- + phase_step_x = (uint32_t) vpe_do_div((numerator +
- + denominator - 1), denominator);
- + } else if (scale_unit_sel_x == 1) { /* if M/N scalar */
- + /*
- + * Calculate the quotient ( src_ROI_width ) / (
- + * out_ROI_width) with u3.29 precision. Quotient is
- + * rounded down to the smaller 29th decimal point.
- + */
- + numerator = (uint64_t)(src_ROI_width) <<
- + SCALER_PHASE_BITS;
- + denominator = (uint64_t)(out_ROI_width);
- + phase_step_x =
- + (uint32_t) vpe_do_div(numerator, denominator);
- + }
- + /* calculate phase step for the y direction */
- +
- + /*
- + * if destination is only 1 pixel wide, the value of
- + * phase_step_x is unimportant. Assigning phase_step_x to src
- + * ROI width as an arbitrary value.
- + */
- + if (out_ROI_height == 1)
- + phase_step_y =
- + (uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS);
- +
- + /* if FIR scalar */
- + else if (scale_unit_sel_y == 0) {
- + /*
- + * Calculate the quotient ( src_ROI_height - 1 ) / (
- + * out_ROI_height - 1) with u3.29 precision. Quotient
- + * is rounded up to the larger 29th decimal point.
- + */
- + numerator = (uint64_t)(src_ROI_height - 1) <<
- + SCALER_PHASE_BITS;
- + /*
- + * never equals to 0 because of the " ( out_ROI_height
- + * == 1 )" case
- + */
- + denominator = (uint64_t)(out_ROI_height - 1);
- + /*
- + * Quotient is rounded up to the larger 29th decimal
- + * point.
- + */
- + phase_step_y =
- + (uint32_t) vpe_do_div(
- + (numerator + denominator - 1), denominator);
- + } else if (scale_unit_sel_y == 1) { /* if M/N scalar */
- + /*
- + * Calculate the quotient ( src_ROI_height ) (
- + * out_ROI_height) with u3.29 precision. Quotient is
- + * rounded down to the smaller 29th decimal point.
- + */
- + numerator = (uint64_t)(src_ROI_height) <<
- + SCALER_PHASE_BITS;
- + denominator = (uint64_t)(out_ROI_height);
- + phase_step_y = (uint32_t) vpe_do_div(
- + numerator, denominator);
- + }
- +
- + /* decide which set of FIR coefficients to use */
- + if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
- + xscale_filter_sel = 0;
- + else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
- + xscale_filter_sel = 1;
- + else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
- + xscale_filter_sel = 2;
- + else
- + xscale_filter_sel = 3;
- +
- + if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
- + yscale_filter_sel = 0;
- + else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
- + yscale_filter_sel = 1;
- + else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
- + yscale_filter_sel = 2;
- + else
- + yscale_filter_sel = 3;
- +
- + /* calculate phase init for the x direction */
- +
- + /* if using FIR scalar */
- + if (scale_unit_sel_x == 0) {
- + if (out_ROI_width == 1)
- + phase_init_x =
- + (uint32_t) ((src_ROI_width - 1) <<
- + SCALER_PHASE_BITS);
- + else
- + phase_init_x = 0;
- + } else if (scale_unit_sel_x == 1) /* M over N scalar */
- + phase_init_x = 0;
- +
- + /*
- + * calculate phase init for the y direction if using FIR
- + * scalar
- + */
- + if (scale_unit_sel_y == 0) {
- + if (out_ROI_height == 1)
- + phase_init_y =
- + (uint32_t) ((src_ROI_height -
- + 1) << SCALER_PHASE_BITS);
- + else
- + phase_init_y = 0;
- + } else if (scale_unit_sel_y == 1) /* M over N scalar */
- + phase_init_y = 0;
- +
- + strip_info.phase_step_x = phase_step_x;
- + strip_info.phase_step_y = phase_step_y;
- + strip_info.phase_init_x = phase_init_x;
- + strip_info.phase_init_y = phase_init_y;
- + VPE_DBG("phase step x = %d, step y = %d.\n",
- + strip_info.phase_step_x, strip_info.phase_step_y);
- + VPE_DBG("phase init x = %d, init y = %d.\n",
- + strip_info.phase_init_x, strip_info.phase_init_y);
- +
- + msm_camera_io_w(strip_info.phase_step_x, vpe_dev->base +
- + VPE_SCALE_PHASEX_STEP_OFFSET);
- + msm_camera_io_w(strip_info.phase_step_y, vpe_dev->base +
- + VPE_SCALE_PHASEY_STEP_OFFSET);
- +
- + msm_camera_io_w(strip_info.phase_init_x, vpe_dev->base +
- + VPE_SCALE_PHASEX_INIT_OFFSET);
- + msm_camera_io_w(strip_info.phase_init_y, vpe_dev->base +
- + VPE_SCALE_PHASEY_INIT_OFFSET);
- +}
- +
- +static void vpe_program_buffer_addresses(
- + struct vpe_device *vpe_dev,
- + unsigned long srcP0,
- + unsigned long srcP1,
- + unsigned long outP0,
- + unsigned long outP1)
- +{
- + VPE_DBG("%s VPE Configured with:\n"
- + "Src %x, %x Dest %x, %x",
- + __func__, (uint32_t)srcP0, (uint32_t)srcP1,
- + (uint32_t)outP0, (uint32_t)outP1);
- +
- + msm_camera_io_w(srcP0, vpe_dev->base + VPE_SRCP0_ADDR_OFFSET);
- + msm_camera_io_w(srcP1, vpe_dev->base + VPE_SRCP1_ADDR_OFFSET);
- + msm_camera_io_w(outP0, vpe_dev->base + VPE_OUTP0_ADDR_OFFSET);
- + msm_camera_io_w(outP1, vpe_dev->base + VPE_OUTP1_ADDR_OFFSET);
- +}
- +
- +static int vpe_start(struct vpe_device *vpe_dev)
- +{
- + /* enable the frame irq, bit 0 = Display list 0 ROI done */
- + msm_camera_io_w_mb(1, vpe_dev->base + VPE_INTR_ENABLE_OFFSET);
- + msm_camera_io_dump(vpe_dev->base, 0x120);
- + msm_camera_io_dump(vpe_dev->base + 0x00400, 0x18);
- + msm_camera_io_dump(vpe_dev->base + 0x10000, 0x250);
- + msm_camera_io_dump(vpe_dev->base + 0x30000, 0x20);
- + msm_camera_io_dump(vpe_dev->base + 0x50000, 0x30);
- + msm_camera_io_dump(vpe_dev->base + 0x50400, 0x10);
- +
- + /*
- + * This triggers the operation. When the VPE is done,
- + * msm_vpe_irq will fire.
- + */
- + msm_camera_io_w_mb(1, vpe_dev->base + VPE_DL0_START_OFFSET);
- + return 0;
- +}
- +
- +static void vpe_config_axi_default(struct vpe_device *vpe_dev)
- +{
- + msm_camera_io_w(0x25, vpe_dev->base + VPE_AXI_ARB_2_OFFSET);
- +}
- +
- +static int vpe_reset(struct vpe_device *vpe_dev)
- +{
- + uint32_t vpe_version;
- + uint32_t rc = 0;
- +
- + vpe_version = msm_camera_io_r(
- + vpe_dev->base + VPE_HW_VERSION_OFFSET);
- + VPE_DBG("vpe_version = 0x%x\n", vpe_version);
- + /* disable all interrupts.*/
- + msm_camera_io_w(0, vpe_dev->base + VPE_INTR_ENABLE_OFFSET);
- + /* clear all pending interrupts*/
- + msm_camera_io_w(0x1fffff, vpe_dev->base + VPE_INTR_CLEAR_OFFSET);
- + /* write sw_reset to reset the core. */
- + msm_camera_io_w(0x10, vpe_dev->base + VPE_SW_RESET_OFFSET);
- + /* then poll the reset bit, it should be self-cleared. */
- + while (1) {
- + rc = msm_camera_io_r(vpe_dev->base + VPE_SW_RESET_OFFSET) \
- + & 0x10;
- + if (rc == 0)
- + break;
- + cpu_relax();
- + }
- + /*
- + * at this point, hardware is reset. Then pogram to default
- + * values.
- + */
- + msm_camera_io_w(VPE_AXI_RD_ARB_CONFIG_VALUE,
- + vpe_dev->base + VPE_AXI_RD_ARB_CONFIG_OFFSET);
- +
- + msm_camera_io_w(VPE_CGC_ENABLE_VALUE,
- + vpe_dev->base + VPE_CGC_EN_OFFSET);
- + msm_camera_io_w(1, vpe_dev->base + VPE_CMD_MODE_OFFSET);
- + msm_camera_io_w(VPE_DEFAULT_OP_MODE_VALUE,
- + vpe_dev->base + VPE_OP_MODE_OFFSET);
- + msm_camera_io_w(VPE_DEFAULT_SCALE_CONFIG,
- + vpe_dev->base + VPE_SCALE_CONFIG_OFFSET);
- + vpe_config_axi_default(vpe_dev);
- + return rc;
- +}
- +
- +static void vpe_update_scale_coef(struct vpe_device *vpe_dev, uint32_t *p)
- +{
- + uint32_t i, offset;
- + offset = *p;
- + for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) {
- + VPE_DBG("Setting scale table %d\n", i);
- + msm_camera_io_w(*(++p),
- + vpe_dev->base + VPE_SCALE_COEFF_LSBn(i));
- + msm_camera_io_w(*(++p),
- + vpe_dev->base + VPE_SCALE_COEFF_MSBn(i));
- + }
- +}
- +
- +static void vpe_input_plane_config(struct vpe_device *vpe_dev, uint32_t *p)
- +{
- + msm_camera_io_w(*p, vpe_dev->base + VPE_SRC_FORMAT_OFFSET);
- + msm_camera_io_w(*(++p),
- + vpe_dev->base + VPE_SRC_UNPACK_PATTERN1_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_SRC_IMAGE_SIZE_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_SRC_YSTRIDE1_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_SRC_SIZE_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_SRC_XY_OFFSET);
- +}
- +
- +static void vpe_output_plane_config(struct vpe_device *vpe_dev, uint32_t *p)
- +{
- + msm_camera_io_w(*p, vpe_dev->base + VPE_OUT_FORMAT_OFFSET);
- + msm_camera_io_w(*(++p),
- + vpe_dev->base + VPE_OUT_PACK_PATTERN1_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_OUT_YSTRIDE1_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_OUT_SIZE_OFFSET);
- + msm_camera_io_w(*(++p), vpe_dev->base + VPE_OUT_XY_OFFSET);
- +}
- +
- +static void vpe_operation_config(struct vpe_device *vpe_dev, uint32_t *p)
- +{
- + msm_camera_io_w(*p, vpe_dev->base + VPE_OP_MODE_OFFSET);
- +}
- +
- +/**
- + * msm_vpe_transaction_setup() - send setup for one frame to VPE
- + * @vpe_dev: vpe device
- + * @data: packed setup commands
- + *
- + * See msm_vpe.h for the expected format of `data'
- + */
- +static void msm_vpe_transaction_setup(struct vpe_device *vpe_dev, void *data)
- +{
- + int i;
- + void *iter = data;
- +
- + vpe_mem_dump("vpe_transaction", data, VPE_TRANSACTION_SETUP_CONFIG_LEN);
- +
- + for (i = 0; i < VPE_NUM_SCALER_TABLES; ++i) {
- + vpe_update_scale_coef(vpe_dev, (uint32_t *)iter);
- + iter += VPE_SCALER_CONFIG_LEN;
- + }
- + vpe_input_plane_config(vpe_dev, (uint32_t *)iter);
- + iter += VPE_INPUT_PLANE_CFG_LEN;
- + vpe_output_plane_config(vpe_dev, (uint32_t *)iter);
- + iter += VPE_OUTPUT_PLANE_CFG_LEN;
- + vpe_operation_config(vpe_dev, (uint32_t *)iter);
- +}
- +
- +static int msm_vpe_send_frame_to_hardware(struct vpe_device *vpe_dev,
- + struct msm_queue_cmd *frame_qcmd)
- +{
- + struct msm_vpe_frame_info_t *process_frame;
- +
- + if (vpe_dev->processing_q.len < MAX_VPE_PROCESSING_FRAME) {
- + process_frame = frame_qcmd->command;
- + msm_enqueue(&vpe_dev->processing_q,
- + &frame_qcmd->list_frame);
- +
- + vpe_update_scaler_params(vpe_dev, process_frame->strip_info);
- + vpe_program_buffer_addresses(
- + vpe_dev,
- + process_frame->src_phyaddr,
- + process_frame->src_phyaddr
- + + process_frame->src_chroma_plane_offset,
- + process_frame->dest_phyaddr,
- + process_frame->dest_phyaddr
- + + process_frame->dest_chroma_plane_offset);
- + vpe_start(vpe_dev);
- + do_gettimeofday(&(process_frame->in_time));
- + }
- + return 0;
- +}
- +
- +static int msm_vpe_cfg(struct vpe_device *vpe_dev,
- + struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
- +{
- + int rc = 0;
- + struct msm_queue_cmd *frame_qcmd = NULL;
- + struct msm_vpe_frame_info_t *new_frame =
- + kzalloc(sizeof(struct msm_vpe_frame_info_t), GFP_KERNEL);
- + unsigned long in_phyaddr, out_phyaddr;
- + struct msm_buf_mngr_info buff_mgr_info;
- +
- + if (!new_frame) {
- + pr_err("Insufficient memory. return\n");
- + return -ENOMEM;
- + }
- +
- + rc = copy_from_user(new_frame, (void __user *)ioctl_ptr->ioctl_ptr,
- + sizeof(struct msm_vpe_frame_info_t));
- + if (rc) {
- + pr_err("%s:%d copy from user\n", __func__, __LINE__);
- + rc = -EINVAL;
- + goto err_free_new_frame;
- + }
- +
- + in_phyaddr = msm_vpe_fetch_buffer_info(vpe_dev,
- + &new_frame->input_buffer_info,
- + ((new_frame->identity >> 16) & 0xFFFF),
- + (new_frame->identity & 0xFFFF));
- + if (!in_phyaddr) {
- + pr_err("error gettting input physical address\n");
- + rc = -EINVAL;
- + goto err_free_new_frame;
- + }
- +
- + memset(&new_frame->output_buffer_info, 0,
- + sizeof(struct msm_vpe_buffer_info_t));
- + memset(&buff_mgr_info, 0, sizeof(struct msm_buf_mngr_info));
- + buff_mgr_info.session_id = ((new_frame->identity >> 16) & 0xFFFF);
- + buff_mgr_info.stream_id = (new_frame->identity & 0xFFFF);
- + rc = msm_vpe_buffer_ops(vpe_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF,
- + &buff_mgr_info);
- + if (rc < 0) {
- + pr_err("error getting buffer\n");
- + rc = -EINVAL;
- + goto err_free_new_frame;
- + }
- +
- + new_frame->output_buffer_info.index = buff_mgr_info.index;
- + out_phyaddr = msm_vpe_fetch_buffer_info(vpe_dev,
- + &new_frame->output_buffer_info,
- + ((new_frame->identity >> 16) & 0xFFFF),
- + (new_frame->identity & 0xFFFF));
- + if (!out_phyaddr) {
- + pr_err("error gettting output physical address\n");
- + rc = -EINVAL;
- + goto err_put_buf;
- + }
- +
- + new_frame->src_phyaddr = in_phyaddr;
- + new_frame->dest_phyaddr = out_phyaddr;
- +
- + frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
- + if (!frame_qcmd) {
- + pr_err("Insufficient memory. return\n");
- + rc = -ENOMEM;
- + goto err_put_buf;
- + }
- +
- + atomic_set(&frame_qcmd->on_heap, 1);
- + frame_qcmd->command = new_frame;
- + rc = msm_vpe_send_frame_to_hardware(vpe_dev, frame_qcmd);
- + if (rc < 0) {
- + pr_err("error cannot send frame to hardware\n");
- + rc = -EINVAL;
- + goto err_free_frame_qcmd;
- + }
- +
- + return rc;
- +
- +err_free_frame_qcmd:
- + kfree(frame_qcmd);
- +err_put_buf:
- + msm_vpe_buffer_ops(vpe_dev, VIDIOC_MSM_BUF_MNGR_PUT_BUF,
- + &buff_mgr_info);
- +err_free_new_frame:
- + kfree(new_frame);
- + return rc;
- +}
- +
- +static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
- + unsigned int cmd, void *arg)
- +{
- + struct vpe_device *vpe_dev = v4l2_get_subdevdata(sd);
- + struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
- + int rc = 0;
- +
- + mutex_lock(&vpe_dev->mutex);
- + switch (cmd) {
- + case VIDIOC_MSM_VPE_TRANSACTION_SETUP: {
- + struct msm_vpe_transaction_setup_cfg *cfg;
- + VPE_DBG("VIDIOC_MSM_VPE_TRANSACTION_SETUP\n");
- + if (sizeof(*cfg) != ioctl_ptr->len) {
- + pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
- + __func__, cmd, ioctl_ptr->len,
- + sizeof(*cfg));
- + rc = -EINVAL;
- + break;
- + }
- +
- + cfg = kzalloc(ioctl_ptr->len, GFP_KERNEL);
- + if (!cfg) {
- + pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = copy_from_user(cfg, (void __user *)ioctl_ptr->ioctl_ptr,
- + ioctl_ptr->len);
- + if (rc) {
- + pr_err("%s:%d copy from user\n", __func__, __LINE__);
- + kfree(cfg);
- + break;
- + }
- +
- + msm_vpe_transaction_setup(vpe_dev, (void *)cfg);
- + kfree(cfg);
- + break;
- + }
- + case VIDIOC_MSM_VPE_CFG: {
- + VPE_DBG("VIDIOC_MSM_VPE_CFG\n");
- + rc = msm_vpe_cfg(vpe_dev, ioctl_ptr);
- + break;
- + }
- + case VIDIOC_MSM_VPE_ENQUEUE_STREAM_BUFF_INFO: {
- + struct msm_vpe_stream_buff_info_t *u_stream_buff_info;
- + struct msm_vpe_stream_buff_info_t k_stream_buff_info;
- +
- + VPE_DBG("VIDIOC_MSM_VPE_ENQUEUE_STREAM_BUFF_INFO\n");
- +
- + if (sizeof(struct msm_vpe_stream_buff_info_t) !=
- + ioctl_ptr->len) {
- + pr_err("%s:%d: invalid length\n", __func__, __LINE__);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + u_stream_buff_info = kzalloc(ioctl_ptr->len, GFP_KERNEL);
- + if (!u_stream_buff_info) {
- + pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = (copy_from_user(u_stream_buff_info,
- + (void __user *)ioctl_ptr->ioctl_ptr,
- + ioctl_ptr->len) ? -EFAULT : 0);
- + if (rc) {
- + pr_err("%s:%d copy from user\n", __func__, __LINE__);
- + kfree(u_stream_buff_info);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + if ((u_stream_buff_info->num_buffs == 0) ||
- + (u_stream_buff_info->num_buffs >
- + MSM_CAMERA_MAX_STREAM_BUF)) {
- + pr_err("%s:%d: Invalid number of buffers\n", __func__,
- + __LINE__);
- + kfree(u_stream_buff_info);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- + k_stream_buff_info.num_buffs = u_stream_buff_info->num_buffs;
- + k_stream_buff_info.identity = u_stream_buff_info->identity;
- + k_stream_buff_info.buffer_info =
- + kzalloc(k_stream_buff_info.num_buffs *
- + sizeof(struct msm_vpe_buffer_info_t), GFP_KERNEL);
- + if (!k_stream_buff_info.buffer_info) {
- + pr_err("%s:%d: malloc error\n", __func__, __LINE__);
- + kfree(u_stream_buff_info);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = (copy_from_user(k_stream_buff_info.buffer_info,
- + (void __user *)u_stream_buff_info->buffer_info,
- + k_stream_buff_info.num_buffs *
- + sizeof(struct msm_vpe_buffer_info_t)) ?
- + -EFAULT : 0);
- + if (rc) {
- + pr_err("%s:%d copy from user\n", __func__, __LINE__);
- + kfree(k_stream_buff_info.buffer_info);
- + kfree(u_stream_buff_info);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = msm_vpe_add_buff_queue_entry(vpe_dev,
- + ((k_stream_buff_info.identity >> 16) & 0xFFFF),
- + (k_stream_buff_info.identity & 0xFFFF));
- + if (!rc)
- + rc = msm_vpe_enqueue_buff_info_list(vpe_dev,
- + &k_stream_buff_info);
- +
- + kfree(k_stream_buff_info.buffer_info);
- + kfree(u_stream_buff_info);
- + break;
- + }
- + case VIDIOC_MSM_VPE_DEQUEUE_STREAM_BUFF_INFO: {
- + uint32_t identity;
- + struct msm_vpe_buff_queue_info_t *buff_queue_info;
- +
- + VPE_DBG("VIDIOC_MSM_VPE_DEQUEUE_STREAM_BUFF_INFO\n");
- + if (ioctl_ptr->len != sizeof(uint32_t)) {
- + pr_err("%s:%d Invalid len\n", __func__, __LINE__);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + rc = (copy_from_user(&identity,
- + (void __user *)ioctl_ptr->ioctl_ptr,
- + ioctl_ptr->len) ? -EFAULT : 0);
- + if (rc) {
- + pr_err("%s:%d copy from user\n", __func__, __LINE__);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + buff_queue_info = msm_vpe_get_buff_queue_entry(vpe_dev,
- + ((identity >> 16) & 0xFFFF), (identity & 0xFFFF));
- + if (buff_queue_info == NULL) {
- + pr_err("error finding buffer queue entry for identity:%d\n",
- + identity);
- + mutex_unlock(&vpe_dev->mutex);
- + return -EINVAL;
- + }
- +
- + msm_vpe_dequeue_buff_info_list(vpe_dev, buff_queue_info);
- + rc = msm_vpe_free_buff_queue_entry(vpe_dev,
- + buff_queue_info->session_id,
- + buff_queue_info->stream_id);
- + break;
- + }
- + case VIDIOC_MSM_VPE_GET_EVENTPAYLOAD: {
- + struct msm_device_queue *queue = &vpe_dev->eventData_q;
- + struct msm_queue_cmd *event_qcmd;
- + struct msm_vpe_frame_info_t *process_frame;
- + VPE_DBG("VIDIOC_MSM_VPE_GET_EVENTPAYLOAD\n");
- + event_qcmd = msm_dequeue(queue, list_eventdata);
- + if (NULL == event_qcmd)
- + break;
- + process_frame = event_qcmd->command;
- + VPE_DBG("fid %d\n", process_frame->frame_id);
- + if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
- + process_frame,
- + sizeof(struct msm_vpe_frame_info_t))) {
- + mutex_unlock(&vpe_dev->mutex);
- + kfree(process_frame);
- + kfree(event_qcmd);
- + return -EINVAL;
- + }
- +
- + kfree(process_frame);
- + kfree(event_qcmd);
- + break;
- + }
- + }
- + mutex_unlock(&vpe_dev->mutex);
- + return rc;
- +}
- +
- +static int msm_vpe_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- + struct v4l2_event_subscription *sub)
- +{
- + return v4l2_event_subscribe(fh, sub, MAX_VPE_V4l2_EVENTS);
- +}
- +
- +static int msm_vpe_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- + struct v4l2_event_subscription *sub)
- +{
- + return v4l2_event_unsubscribe(fh, sub);
- +}
- +
- +static struct v4l2_subdev_core_ops msm_vpe_subdev_core_ops = {
- + .ioctl = msm_vpe_subdev_ioctl,
- + .subscribe_event = msm_vpe_subscribe_event,
- + .unsubscribe_event = msm_vpe_unsubscribe_event,
- +};
- +
- +static const struct v4l2_subdev_ops msm_vpe_subdev_ops = {
- + .core = &msm_vpe_subdev_core_ops,
- +};
- +
- +static struct v4l2_file_operations msm_vpe_v4l2_subdev_fops;
- +
- +static long msm_vpe_subdev_do_ioctl(
- + struct file *file, unsigned int cmd, void *arg)
- +{
- + struct video_device *vdev = video_devdata(file);
- + struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- + struct v4l2_fh *vfh = file->private_data;
- +
- + switch (cmd) {
- + case VIDIOC_DQEVENT:
- + if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
- + return -ENOIOCTLCMD;
- +
- + return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
- +
- + case VIDIOC_SUBSCRIBE_EVENT:
- + return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
- +
- + case VIDIOC_UNSUBSCRIBE_EVENT:
- + return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
- + case VIDIOC_MSM_VPE_GET_INST_INFO: {
- + uint32_t i;
- + struct vpe_device *vpe_dev = v4l2_get_subdevdata(sd);
- + struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
- + struct msm_vpe_frame_info_t inst_info;
- + memset(&inst_info, 0, sizeof(struct msm_vpe_frame_info_t));
- + for (i = 0; i < MAX_ACTIVE_VPE_INSTANCE; i++) {
- + if (vpe_dev->vpe_subscribe_list[i].vfh == vfh) {
- + inst_info.inst_id = i;
- + break;
- + }
- + }
- + if (copy_to_user(
- + (void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
- + sizeof(struct msm_vpe_frame_info_t))) {
- + return -EINVAL;
- + }
- + }
- + default:
- + return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
- + }
- +
- + return 0;
- +}
- +
- +static long msm_vpe_subdev_fops_ioctl(struct file *file, unsigned int cmd,
- + unsigned long arg)
- +{
- + return video_usercopy(file, cmd, arg, msm_vpe_subdev_do_ioctl);
- +}
- +
- +static int vpe_register_domain(void)
- +{
- + struct msm_iova_partition vpe_iommu_partition = {
- + /* TODO: verify that these are correct? */
- + .start = SZ_128K,
- + .size = SZ_2G - SZ_128K,
- + };
- + struct msm_iova_layout vpe_iommu_layout = {
- + .partitions = &vpe_iommu_partition,
- + .npartitions = 1,
- + .client_name = "camera_vpe",
- + .domain_flags = 0,
- + };
- +
- + return msm_register_domain(&vpe_iommu_layout);
- +}
- +
- +static int __devinit vpe_probe(struct platform_device *pdev)
- +{
- + struct vpe_device *vpe_dev;
- + int rc = 0;
- +
- + vpe_dev = kzalloc(sizeof(struct vpe_device), GFP_KERNEL);
- + if (!vpe_dev) {
- + pr_err("not enough memory\n");
- + return -ENOMEM;
- + }
- +
- + vpe_dev->vpe_clk = kzalloc(sizeof(struct clk *) *
- + ARRAY_SIZE(vpe_clk_info), GFP_KERNEL);
- + if (!vpe_dev->vpe_clk) {
- + pr_err("not enough memory\n");
- + rc = -ENOMEM;
- + goto err_free_vpe_dev;
- + }
- +
- + v4l2_subdev_init(&vpe_dev->msm_sd.sd, &msm_vpe_subdev_ops);
- + vpe_dev->msm_sd.sd.internal_ops = &msm_vpe_internal_ops;
- + snprintf(vpe_dev->msm_sd.sd.name, ARRAY_SIZE(vpe_dev->msm_sd.sd.name),
- + "vpe");
- + vpe_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- + vpe_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
- + v4l2_set_subdevdata(&vpe_dev->msm_sd.sd, vpe_dev);
- + platform_set_drvdata(pdev, &vpe_dev->msm_sd.sd);
- + mutex_init(&vpe_dev->mutex);
- + spin_lock_init(&vpe_dev->tasklet_lock);
- +
- + vpe_dev->pdev = pdev;
- +
- + vpe_dev->mem = platform_get_resource_byname(pdev,
- + IORESOURCE_MEM, "vpe");
- + if (!vpe_dev->mem) {
- + pr_err("no mem resource?\n");
- + rc = -ENODEV;
- + goto err_free_vpe_clk;
- + }
- +
- + vpe_dev->irq = platform_get_resource_byname(pdev,
- + IORESOURCE_IRQ, "vpe");
- + if (!vpe_dev->irq) {
- + pr_err("%s: no irq resource?\n", __func__);
- + rc = -ENODEV;
- + goto err_release_mem;
- + }
- +
- + vpe_dev->domain_num = vpe_register_domain();
- + if (vpe_dev->domain_num < 0) {
- + pr_err("%s: could not register domain\n", __func__);
- + rc = -ENODEV;
- + goto err_release_mem;
- + }
- +
- + vpe_dev->domain =
- + msm_get_iommu_domain(vpe_dev->domain_num);
- + if (!vpe_dev->domain) {
- + pr_err("%s: cannot find domain\n", __func__);
- + rc = -ENODEV;
- + goto err_release_mem;
- + }
- +
- + vpe_dev->iommu_ctx_src = msm_iommu_get_ctx("vpe_src");
- + vpe_dev->iommu_ctx_dst = msm_iommu_get_ctx("vpe_dst");
- + if (!vpe_dev->iommu_ctx_src || !vpe_dev->iommu_ctx_dst) {
- + pr_err("%s: cannot get iommu_ctx\n", __func__);
- + rc = -ENODEV;
- + goto err_release_mem;
- + }
- +
- + media_entity_init(&vpe_dev->msm_sd.sd.entity, 0, NULL, 0);
- + vpe_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- + vpe_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_VPE;
- + vpe_dev->msm_sd.sd.entity.name = pdev->name;
- + msm_sd_register(&vpe_dev->msm_sd);
- + msm_vpe_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
- + msm_vpe_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
- + msm_vpe_v4l2_subdev_fops.unlocked_ioctl = msm_vpe_subdev_fops_ioctl;
- + msm_vpe_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
- + msm_vpe_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
- +
- + vpe_dev->msm_sd.sd.devnode->fops = &msm_vpe_v4l2_subdev_fops;
- + vpe_dev->msm_sd.sd.entity.revision = vpe_dev->msm_sd.sd.devnode->num;
- + vpe_dev->state = VPE_STATE_BOOT;
- + rc = vpe_init_hardware(vpe_dev);
- + if (rc < 0) {
- + pr_err("%s: Couldn't init vpe hardware\n", __func__);
- + rc = -ENODEV;
- + goto err_unregister_sd;
- + }
- + vpe_reset(vpe_dev);
- + vpe_release_hardware(vpe_dev);
- + vpe_dev->state = VPE_STATE_OFF;
- +
- + rc = iommu_attach_device(vpe_dev->domain, vpe_dev->iommu_ctx_src);
- + if (rc < 0) {
- + pr_err("Couldn't attach to vpe_src context bank\n");
- + rc = -ENODEV;
- + goto err_unregister_sd;
- + }
- + rc = iommu_attach_device(vpe_dev->domain, vpe_dev->iommu_ctx_dst);
- + if (rc < 0) {
- + pr_err("Couldn't attach to vpe_dst context bank\n");
- + rc = -ENODEV;
- + goto err_detach_src;
- + }
- +
- + vpe_dev->state = VPE_STATE_OFF;
- +
- + msm_queue_init(&vpe_dev->eventData_q, "vpe-eventdata");
- + msm_queue_init(&vpe_dev->processing_q, "vpe-frame");
- + INIT_LIST_HEAD(&vpe_dev->tasklet_q);
- + tasklet_init(&vpe_dev->vpe_tasklet, msm_vpe_do_tasklet,
- + (unsigned long)vpe_dev);
- + vpe_dev->vpe_open_cnt = 0;
- +
- + return rc;
- +
- +err_detach_src:
- + iommu_detach_device(vpe_dev->domain, vpe_dev->iommu_ctx_src);
- +err_unregister_sd:
- + msm_sd_unregister(&vpe_dev->msm_sd);
- +err_release_mem:
- + release_mem_region(vpe_dev->mem->start, resource_size(vpe_dev->mem));
- +err_free_vpe_clk:
- + kfree(vpe_dev->vpe_clk);
- +err_free_vpe_dev:
- + kfree(vpe_dev);
- + return rc;
- +}
- +
- +static int vpe_device_remove(struct platform_device *dev)
- +{
- + struct v4l2_subdev *sd = platform_get_drvdata(dev);
- + struct vpe_device *vpe_dev;
- + if (!sd) {
- + pr_err("%s: Subdevice is NULL\n", __func__);
- + return 0;
- + }
- +
- + vpe_dev = (struct vpe_device *)v4l2_get_subdevdata(sd);
- + if (!vpe_dev) {
- + pr_err("%s: vpe device is NULL\n", __func__);
- + return 0;
- + }
- +
- + iommu_detach_device(vpe_dev->domain, vpe_dev->iommu_ctx_dst);
- + iommu_detach_device(vpe_dev->domain, vpe_dev->iommu_ctx_src);
- + msm_sd_unregister(&vpe_dev->msm_sd);
- + release_mem_region(vpe_dev->mem->start, resource_size(vpe_dev->mem));
- + mutex_destroy(&vpe_dev->mutex);
- + kfree(vpe_dev);
- + return 0;
- +}
- +
- +static struct platform_driver vpe_driver = {
- + .probe = vpe_probe,
- + .remove = __devexit_p(vpe_device_remove),
- + .driver = {
- + .name = MSM_VPE_DRV_NAME,
- + .owner = THIS_MODULE,
- + },
- +};
- +
- +static int __init msm_vpe_init_module(void)
- +{
- + return platform_driver_register(&vpe_driver);
- +}
- +
- +static void __exit msm_vpe_exit_module(void)
- +{
- + platform_driver_unregister(&vpe_driver);
- +}
- +
- +module_init(msm_vpe_init_module);
- +module_exit(msm_vpe_exit_module);
- +MODULE_DESCRIPTION("MSM VPE driver");
- +MODULE_LICENSE("GPL v2");
- 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 7c6e4f0..e5d82fd 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
- @@ -43,96 +43,87 @@
- /* Max bytes that can be read per CCI read transaction */
- #define CCI_READ_MAX 12
- +#define CCI_I2C_READ_MAX_RETRIES 3
- +#define CCI_I2C_MAX_READ 8192
- +#define CCI_I2C_MAX_WRITE 8192
- static struct v4l2_subdev *g_cci_subdev;
- static void msm_cci_set_clk_param(struct cci_device *cci_dev)
- {
- - struct msm_cci_clk_params_t *clk_params = &cci_dev->cci_clk_params;
- -
- - msm_camera_io_w(clk_params->hw_thigh << 16 | clk_params->hw_tlow,
- - cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR);
- - msm_camera_io_w(clk_params->hw_tsu_sto << 16 | clk_params->hw_tsu_sta,
- - cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR);
- - msm_camera_io_w(clk_params->hw_thd_dat << 16 | clk_params->hw_thd_sta,
- - cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR);
- - msm_camera_io_w(clk_params->hw_tbuf,
- - cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR);
- - msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
- - clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
- - cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR);
- - msm_camera_io_w(clk_params->hw_thigh << 16 | clk_params->hw_tlow,
- - cci_dev->base + CCI_I2C_M1_SCL_CTL_ADDR);
- - msm_camera_io_w(clk_params->hw_tsu_sto << 16 | clk_params->hw_tsu_sta,
- - cci_dev->base + CCI_I2C_M1_SDA_CTL_0_ADDR);
- - msm_camera_io_w(clk_params->hw_thd_dat << 16 | clk_params->hw_thd_sta,
- - cci_dev->base + CCI_I2C_M1_SDA_CTL_1_ADDR);
- - msm_camera_io_w(clk_params->hw_tbuf,
- - cci_dev->base + CCI_I2C_M1_SDA_CTL_2_ADDR);
- - msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
- - clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
- - cci_dev->base + CCI_I2C_M1_MISC_CTL_ADDR);
- + struct msm_cci_clk_params_t *clk_params = NULL;
- + uint8_t count = 0;
- +
- + for (count = 0; count < MASTER_MAX; count++) {
- + if (MASTER_0 == count) {
- + clk_params = &cci_dev->cci_clk_params[count];
- + msm_camera_io_w(clk_params->hw_thigh << 16 |
- + clk_params->hw_tlow,
- + cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR);
- + msm_camera_io_w(clk_params->hw_tsu_sto << 16 |
- + clk_params->hw_tsu_sta,
- + cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR);
- + msm_camera_io_w(clk_params->hw_thd_dat << 16 |
- + clk_params->hw_thd_sta,
- + cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR);
- + msm_camera_io_w(clk_params->hw_tbuf,
- + cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR);
- + msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
- + clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
- + cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR);
- + } else if (MASTER_1 == count) {
- + clk_params = &cci_dev->cci_clk_params[count];
- + msm_camera_io_w(clk_params->hw_thigh << 16 |
- + clk_params->hw_tlow,
- + cci_dev->base + CCI_I2C_M1_SCL_CTL_ADDR);
- + msm_camera_io_w(clk_params->hw_tsu_sto << 16 |
- + clk_params->hw_tsu_sta,
- + cci_dev->base + CCI_I2C_M1_SDA_CTL_0_ADDR);
- + msm_camera_io_w(clk_params->hw_thd_dat << 16 |
- + clk_params->hw_thd_sta,
- + cci_dev->base + CCI_I2C_M1_SDA_CTL_1_ADDR);
- + msm_camera_io_w(clk_params->hw_tbuf,
- + cci_dev->base + CCI_I2C_M1_SDA_CTL_2_ADDR);
- + msm_camera_io_w(clk_params->hw_scl_stretch_en << 8 |
- + clk_params->hw_trdhld << 4 | clk_params->hw_tsp,
- + cci_dev->base + CCI_I2C_M1_MISC_CTL_ADDR);
- + }
- + }
- return;
- }
- -static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
- - struct msm_camera_cci_ctrl *c_ctrl)
- -{
- - struct cci_device *cci_dev;
- - cci_dev = v4l2_get_subdevdata(sd);
- - msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
- - CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
- - return 0;
- -}
- -
- -static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
- - struct msm_camera_cci_ctrl *c_ctrl)
- -{
- - struct cci_device *cci_dev;
- - uint32_t val;
- - cci_dev = v4l2_get_subdevdata(sd);
- - val = c_ctrl->cci_info->freq;
- - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
- - c_ctrl->cci_info->cci_i2c_master*0x100);
- - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
- - c_ctrl->cci_info->cci_i2c_master*0x100);
- - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
- - c_ctrl->cci_info->cci_i2c_master*0x100);
- - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
- - c_ctrl->cci_info->cci_i2c_master*0x100);
- - msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
- - c_ctrl->cci_info->cci_i2c_master*0x100);
- - return 0;
- -}
- -
- static void msm_cci_flush_queue(struct cci_device *cci_dev,
- enum cci_i2c_master_t master)
- {
- - uint32_t rc = 0;
- + int32_t rc = 0;
- msm_camera_io_w(1 << master, cci_dev->base + CCI_HALT_REQ_ADDR);
- - rc = wait_for_completion_interruptible_timeout(
- + rc = wait_for_completion_timeout(
- &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
- if (rc < 0) {
- - pr_err("%s: wait failed %d\n", __func__, __LINE__);
- - } else if (rc == 0) {
- - pr_err("%s:%d wait timeout\n", __func__, __LINE__);
- - /* Set reset pending flag to TRUE */
- - cci_dev->cci_master_info[master].reset_pending = TRUE;
- - /* Set proper mask to RESET CMD address based on MASTER */
- - if (master == MASTER_0)
- - msm_camera_io_w(CCI_M0_RESET_RMSK,
- - cci_dev->base + CCI_RESET_CMD_ADDR);
- - else
- - msm_camera_io_w(CCI_M1_RESET_RMSK,
- - cci_dev->base + CCI_RESET_CMD_ADDR);
- - /* wait for reset done irq */
- - rc = wait_for_completion_interruptible_timeout(
- - &cci_dev->cci_master_info[master].reset_complete,
- - CCI_TIMEOUT);
- - if (rc <= 0)
- - pr_err("%s:%d wait failed %d\n", __func__, __LINE__, rc);
- - }
- + pr_err("%s:%d wait failed\n", __func__, __LINE__);
- + } else if (rc == 0) {
- + pr_err("%s:%d wait timeout\n", __func__, __LINE__);
- +
- + /* Set reset pending flag to TRUE */
- + cci_dev->cci_master_info[master].reset_pending = TRUE;
- +
- + /* Set proper mask to RESET CMD address based on MASTER */
- + if (master == MASTER_0)
- + msm_camera_io_w(CCI_M0_RESET_RMSK,
- + cci_dev->base + CCI_RESET_CMD_ADDR);
- + else
- + msm_camera_io_w(CCI_M1_RESET_RMSK,
- + cci_dev->base + CCI_RESET_CMD_ADDR);
- +
- + /* wait for reset done irq */
- + rc = wait_for_completion_timeout(
- + &cci_dev->cci_master_info[master].reset_complete,
- + CCI_TIMEOUT);
- + if (rc <= 0)
- + pr_err("%s:%d wait failed %d\n", __func__, __LINE__,
- + rc);
- + }
- return;
- }
- @@ -167,10 +158,10 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
- msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR);
- CDBG("%s line %d wait_for_completion_interruptible\n",
- __func__, __LINE__);
- - rc = wait_for_completion_interruptible_timeout(&cci_dev->
- + rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].reset_complete, CCI_TIMEOUT);
- if (rc <= 0) {
- - pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
- + pr_err("%s: wait_for_completion_timeout %d\n",
- __func__, __LINE__);
- if (rc == 0)
- rc = -ETIMEDOUT;
- @@ -185,8 +176,7 @@ static int32_t msm_cci_validate_queue(struct cci_device *cci_dev,
- }
- static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
- - struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue,
- - uint8_t is_burst)
- + struct msm_camera_cci_ctrl *c_ctrl, enum cci_i2c_queue_t queue)
- {
- uint16_t i = 0, j = 0, k = 0, h = 0, len = 0;
- int32_t rc = 0;
- @@ -198,17 +188,46 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
- uint16_t cmd_size = i2c_msg->size;
- struct msm_camera_i2c_reg_array *i2c_cmd = i2c_msg->reg_setting;
- enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
- +
- + if (i2c_cmd == NULL) {
- + pr_err("%s:%d Failed line\n", __func__,
- + __LINE__);
- + return -EINVAL;
- + }
- +
- + if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) {
- + pr_err("%s:%d Failed line\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- +
- CDBG("%s addr type %d data type %d\n", __func__,
- i2c_msg->addr_type, i2c_msg->data_type);
- - /* assume total size within the max queue */
- + if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
- + pr_err("%s failed line %d\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- + if (i2c_msg->data_type >= MSM_CAMERA_I2C_DATA_TYPE_MAX) {
- + pr_err("%s failed line %d\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- +
- + reg_addr = i2c_cmd->reg_addr;
- while (cmd_size) {
- - CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
- + CDBG("%s cmd_size %d addr 0x%x data 0x%x\n", __func__,
- cmd_size, i2c_cmd->reg_addr, i2c_cmd->reg_data);
- delay = i2c_cmd->delay;
- data[i++] = CCI_I2C_WRITE_CMD;
- - if (i2c_cmd->reg_addr)
- +
- + /* in case of multiple command
- + * MSM_CCI_I2C_WRITE : address is not continuous, so update
- + * address for a new packet.
- + * MSM_CCI_I2C_WRITE_SEQ : address is continuous, need to keep
- + * the incremented address for a
- + * new packet */
- + if (c_ctrl->cmd == MSM_CCI_I2C_WRITE)
- reg_addr = i2c_cmd->reg_addr;
- +
- /* either byte or word addr */
- if (i2c_msg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
- data[i++] = reg_addr;
- @@ -218,24 +237,24 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
- }
- /* max of 10 data bytes */
- do {
- - if ((i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) ||
- - (i2c_msg->data_type == MSM_CAMERA_I2C_BURST_DATA)) {
- + if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
- data[i++] = i2c_cmd->reg_data;
- - if (!is_burst)
- - reg_addr++;
- + reg_addr++;
- } else {
- if ((i + 1) <= 10) {
- data[i++] = (i2c_cmd->reg_data &
- 0xFF00) >> 8; /* MSB */
- data[i++] = i2c_cmd->reg_data &
- 0x00FF; /* LSB */
- - if (!is_burst)
- - reg_addr += 2;
- + reg_addr += 2;
- } else
- break;
- }
- i2c_cmd++;
- - } while (--cmd_size && !i2c_cmd->reg_addr && (i <= 10));
- + --cmd_size;
- + } while ((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) &&
- + (cmd_size > 0) && (i <= 10));
- +
- data[0] |= ((i-1) << 4);
- len = ((i-1)/4) + 1;
- rc = msm_cci_validate_queue(cci_dev, len, master, queue);
- @@ -249,14 +268,10 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
- cmd |= (data[k++] << (j * 8));
- CDBG("%s CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x%x\n",
- __func__, cmd);
- -
- msm_camera_io_w(cmd, cci_dev->base +
- CCI_I2C_M0_Q0_LOAD_DATA_ADDR +
- master * 0x200 + queue * 0x100);
- }
- - if (delay > CCI_MAX_DELAY) {
- - pr_err("%s:%d invalid delay %d\n", __func__, __LINE__, delay);
- - }
- if ((delay > 0) && (delay < CCI_MAX_DELAY)) {
- cmd = (uint32_t)((delay * CYCLES_PER_MICRO_SEC) /
- 0x100);
- @@ -297,7 +312,7 @@ static int32_t msm_cci_write_i2c_queue(struct cci_device *cci_dev,
- 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;
- @@ -310,7 +325,7 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- cci_dev = v4l2_get_subdevdata(sd);
- master = c_ctrl->cci_info->cci_i2c_master;
- read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
- - mutex_lock(&cci_dev->mutex);
- + mutex_lock(&cci_dev->cci_master_info[master].mutex);
- /*
- * Call validate queue to make sure queue is empty before starting.
- @@ -326,6 +341,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- goto ERROR;
- }
- + if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
- + pr_err("%s:%d More than max retries\n", __func__,
- + __LINE__);
- + goto ERROR;
- + }
- +
- + if (read_cfg->data == NULL) {
- + pr_err("%s:%d Data ptr is NULL\n", __func__,
- + __LINE__);
- + goto ERROR;
- + }
- +
- CDBG("%s master %d, queue %d\n", __func__, master, queue);
- CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
- c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
- @@ -346,11 +373,16 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- goto ERROR;
- }
- + if (read_cfg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
- + CDBG("%s failed line %d\n", __func__, __LINE__);
- + goto ERROR;
- + }
- +
- if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
- - val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
- + val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) |
- ((read_cfg->addr & 0xFF) << 8);
- if (read_cfg->addr_type == MSM_CAMERA_I2C_WORD_ADDR)
- - val = CCI_I2C_WRITE_CMD | (read_cfg->addr_type << 4) |
- + val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) |
- (((read_cfg->addr & 0xFF00) >> 8) << 8) |
- ((read_cfg->addr & 0xFF) << 16);
- rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
- @@ -381,12 +413,12 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- val = 1 << ((master * 2) + queue);
- msm_camera_io_w(val, cci_dev->base + CCI_QUEUE_START_ADDR);
- - CDBG("%s:%d E wait_for_completion_interruptible_timeout\n", __func__,
- + CDBG("%s:%d E wait_for_completion_timeout\n", __func__,
- __LINE__);
- - rc = wait_for_completion_interruptible_timeout(&cci_dev->
- + rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].reset_complete, CCI_TIMEOUT);
- if (rc <= 0) {
- - pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
- + pr_err("%s: wait_for_completion_timeout %d\n",
- __func__, __LINE__);
- if (rc == 0)
- rc = -ETIMEDOUT;
- @@ -395,7 +427,7 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- } else {
- rc = 0;
- }
- - CDBG("%s:%d E wait_for_completion_interruptible_timeout\n", __func__,
- + CDBG("%s:%d E wait_for_completion_timeout\n", __func__,
- __LINE__);
- read_words = msm_camera_io_r(cci_dev->base +
- @@ -431,7 +463,7 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
- }
- } while (--read_words > 0);
- ERROR:
- - mutex_unlock(&cci_dev->mutex);
- + mutex_unlock(&cci_dev->cci_master_info[master].mutex);
- return rc;
- }
- @@ -459,9 +491,15 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
- return -EINVAL;
- }
- + if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX
- + || c_ctrl->cci_info->cci_i2c_master < 0) {
- + pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- +
- master = c_ctrl->cci_info->cci_i2c_master;
- read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
- - if (!read_cfg->num_byte) {
- + if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
- pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
- rc = -EINVAL;
- goto ERROR;
- @@ -491,7 +529,7 @@ ERROR:
- }
- static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- - struct msm_camera_cci_ctrl *c_ctrl, uint8_t is_burst)
- + struct msm_camera_cci_ctrl *c_ctrl)
- {
- int32_t rc = 0;
- struct cci_device *cci_dev;
- @@ -499,12 +537,17 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- enum cci_i2c_master_t master;
- enum cci_i2c_queue_t queue = QUEUE_0;
- cci_dev = v4l2_get_subdevdata(sd);
- + if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX
- + || c_ctrl->cci_info->cci_i2c_master < 0) {
- + pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- master = c_ctrl->cci_info->cci_i2c_master;
- CDBG("%s master %d, queue %d\n", __func__, master, queue);
- CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
- c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
- c_ctrl->cci_info->id_map);
- - mutex_lock(&cci_dev->mutex);
- + mutex_lock(&cci_dev->cci_master_info[master].mutex);
- /*
- * Call validate queue to make sure queue is empty before starting.
- @@ -519,6 +562,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- __LINE__, rc);
- goto ERROR;
- }
- + if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
- + pr_err("%s:%d More than max retries\n", __func__,
- + __LINE__);
- + goto ERROR;
- + }
- val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
- c_ctrl->cci_info->retries << 16 |
- @@ -538,7 +586,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- goto ERROR;
- }
- - msm_cci_data_queue(cci_dev, c_ctrl, queue, is_burst);
- + rc = msm_cci_data_queue(cci_dev, c_ctrl, queue);
- + if (rc < 0) {
- + CDBG("%s failed line %d\n", __func__, __LINE__);
- + goto ERROR;
- + }
- val = CCI_I2C_UNLOCK_CMD;
- CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
- rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
- @@ -568,10 +620,10 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- CDBG("%s:%d E wait_for_completion_interruptible\n",
- __func__, __LINE__);
- - rc = wait_for_completion_interruptible_timeout(&cci_dev->
- + rc = wait_for_completion_timeout(&cci_dev->
- cci_master_info[master].reset_complete, CCI_TIMEOUT);
- if (rc <= 0) {
- - pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
- + pr_err("%s: wait_for_completion_timeout %d\n",
- __func__, __LINE__);
- if (rc == 0)
- rc = -ETIMEDOUT;
- @@ -584,14 +636,18 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
- __LINE__);
- ERROR:
- - mutex_unlock(&cci_dev->mutex);
- + mutex_unlock(&cci_dev->cci_master_info[master].mutex);
- return rc;
- }
- static int msm_cci_subdev_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
- {
- - BUG_ON(!chip);
- + if (!chip) {
- + pr_err("%s:%d: NULL pointer supplied for chip ident\n",
- + __func__, __LINE__);
- + return -EINVAL;
- + }
- chip->ident = V4L2_IDENT_CCI;
- chip->revision = 0;
- return 0;
- @@ -605,34 +661,29 @@ static struct msm_cam_clk_info cci_clk_info[] = {
- };
- static int32_t msm_cci_init(struct v4l2_subdev *sd,
- - struct msm_camera_cci_ctrl *c_ctrl){
- - int rc = 0;
- + struct msm_camera_cci_ctrl *c_ctrl)
- +{
- + int32_t rc = 0;
- struct cci_device *cci_dev;
- enum cci_i2c_master_t master;
- cci_dev = v4l2_get_subdevdata(sd);
- - CDBG("%s line %d\n", __func__, __LINE__);
- -
- if (!cci_dev || !c_ctrl) {
- pr_err("%s:%d failed: invalid params %p %p\n", __func__,
- __LINE__, cci_dev, c_ctrl);
- -
- rc = -ENOMEM;
- return rc;
- }
- -
- - mutex_lock(&cci_dev->mutex);
- if (cci_dev->ref_count++) {
- CDBG("%s ref_count %d\n", __func__, cci_dev->ref_count);
- -
- master = c_ctrl->cci_info->cci_i2c_master;
- - CDBG("%s:%d master %d\n", __func__, __LINE__,
- - master);
- - if (master < MASTER_MAX) {
- + CDBG("%s:%d master %d\n", __func__, __LINE__, master);
- + if (master < MASTER_MAX && master >= 0) {
- + mutex_lock(&cci_dev->cci_master_info[master].mutex);
- /* Set reset pending flag to TRUE */
- cci_dev->cci_master_info[master].reset_pending = TRUE;
- - /* Set proper mask to RESET CMD address based on MASTER */
- + /* Set proper mask to RESET CMD address */
- if (master == MASTER_0)
- msm_camera_io_w(CCI_M0_RESET_RMSK,
- cci_dev->base + CCI_RESET_CMD_ADDR);
- @@ -640,30 +691,32 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
- msm_camera_io_w(CCI_M1_RESET_RMSK,
- cci_dev->base + CCI_RESET_CMD_ADDR);
- /* wait for reset done irq */
- - rc = wait_for_completion_interruptible_timeout(
- - &cci_dev->cci_master_info[master].reset_complete,
- + rc = wait_for_completion_timeout(
- + &cci_dev->cci_master_info[master].
- + reset_complete,
- CCI_TIMEOUT);
- if (rc <= 0)
- - pr_err("%s:%d wait failed %d\n", __func__, __LINE__, rc);
- + pr_err("%s:%d wait failed %d\n", __func__,
- + __LINE__, rc);
- + mutex_unlock(&cci_dev->cci_master_info[master].mutex);
- }
- - mutex_unlock(&cci_dev->mutex);
- -
- return 0;
- }
- rc = msm_camera_request_gpio_table(cci_dev->cci_gpio_tbl,
- cci_dev->cci_gpio_tbl_size, 1);
- if (rc < 0) {
- + cci_dev->ref_count--;
- CDBG("%s: request gpio failed\n", __func__);
- - goto ERROR;
- + goto request_gpio_failed;
- }
- rc = msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
- cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 1);
- if (rc < 0) {
- -
- + cci_dev->ref_count--;
- CDBG("%s: clk enable failed\n", __func__);
- - goto ERROR;
- + goto clk_enable_failed;
- }
- enable_irq(cci_dev->irq->start);
- @@ -672,15 +725,15 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
- cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
- msm_camera_io_w(CCI_RESET_CMD_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR);
- msm_camera_io_w(0x1, cci_dev->base + CCI_RESET_CMD_ADDR);
- - rc = wait_for_completion_interruptible_timeout(
- + rc = wait_for_completion_timeout(
- &cci_dev->cci_master_info[MASTER_0].reset_complete,
- CCI_TIMEOUT);
- if (rc <= 0) {
- - pr_err("%s: wait_for_completion_interruptible_timeout %d\n",
- + pr_err("%s: wait_for_completion_timeout %d\n",
- __func__, __LINE__);
- if (rc == 0)
- rc = -ETIMEDOUT;
- - goto ERROR;
- + goto reset_complete_failed;
- }
- msm_cci_set_clk_param(cci_dev);
- msm_camera_io_w(CCI_IRQ_MASK_0_RMSK,
- @@ -689,13 +742,18 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
- cci_dev->base + CCI_IRQ_CLEAR_0_ADDR);
- msm_camera_io_w(0x1, cci_dev->base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
- cci_dev->cci_state = CCI_STATE_ENABLED;
- - CDBG("%s:%d Exit\n", __func__, __LINE__);
- - mutex_unlock(&cci_dev->mutex);
- +
- return 0;
- -ERROR:
- +reset_complete_failed:
- + disable_irq(cci_dev->irq->start);
- + msm_cam_clk_enable(&cci_dev->pdev->dev, cci_clk_info,
- + cci_dev->cci_clk, ARRAY_SIZE(cci_clk_info), 0);
- +clk_enable_failed:
- + msm_camera_request_gpio_table(cci_dev->cci_gpio_tbl,
- + cci_dev->cci_gpio_tbl_size, 0);
- +request_gpio_failed:
- cci_dev->ref_count--;
- - mutex_unlock(&cci_dev->mutex);
- return rc;
- }
- @@ -703,7 +761,6 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
- {
- struct cci_device *cci_dev;
- cci_dev = v4l2_get_subdevdata(sd);
- - CDBG("%s:%d Enter\n", __func__, __LINE__);
- if (!cci_dev->ref_count || cci_dev->cci_state != CCI_STATE_ENABLED) {
- pr_err("%s invalid ref count %d / cci state %d\n",
- @@ -711,11 +768,8 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
- return -EINVAL;
- }
- - mutex_lock(&cci_dev->mutex);
- -
- if (--cci_dev->ref_count) {
- CDBG("%s ref_count Exit %d\n", __func__, cci_dev->ref_count);
- - mutex_unlock(&cci_dev->mutex);
- return 0;
- }
- @@ -728,8 +782,7 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
- cci_dev->cci_gpio_tbl_size, 0);
- cci_dev->cci_state = CCI_STATE_DISABLED;
- - CDBG("%s:%d Exit\n", __func__, __LINE__);
- - mutex_unlock(&cci_dev->mutex);
- +
- return 0;
- }
- @@ -746,22 +799,12 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd,
- case MSM_CCI_RELEASE:
- rc = msm_cci_release(sd);
- break;
- - case MSM_CCI_SET_SID:
- - break;
- - case MSM_CCI_SET_FREQ:
- - rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
- - break;
- - case MSM_CCI_SET_SYNC_CID:
- - rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
- - break;
- case MSM_CCI_I2C_READ:
- rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
- break;
- case MSM_CCI_I2C_WRITE:
- - rc = msm_cci_i2c_write(sd, cci_ctrl, 0);
- - break;
- - case MSM_CCI_I2C_WRITE_BURST:
- - rc = msm_cci_i2c_write(sd, cci_ctrl, 1);
- + case MSM_CCI_I2C_WRITE_SEQ:
- + rc = msm_cci_i2c_write(sd, cci_ctrl);
- break;
- case MSM_CCI_GPIO_WRITE:
- break;
- @@ -795,36 +838,36 @@ static irqreturn_t msm_cci_irq(int irq_num, void *data)
- complete(&cci_dev->cci_master_info[MASTER_1].
- reset_complete);
- }
- - }
- - if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
- + }
- + if ((irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) ||
- (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) ||
- (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK)) {
- cci_dev->cci_master_info[MASTER_0].status = 0;
- complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
- - }
- - if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
- + }
- + if ((irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) ||
- (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) ||
- (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK)) {
- cci_dev->cci_master_info[MASTER_1].status = 0;
- complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
- - }
- - if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
- + }
- + if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) {
- cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
- msm_camera_io_w(CCI_M0_RESET_RMSK,
- cci_dev->base + CCI_RESET_CMD_ADDR);
- - }
- - if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
- + }
- + if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) {
- cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE;
- msm_camera_io_w(CCI_M1_RESET_RMSK,
- cci_dev->base + CCI_RESET_CMD_ADDR);
- - }
- - if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
- + }
- + if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
- pr_err("%s:%d MASTER_0 error %x\n", __func__, __LINE__, irq);
- cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
- msm_camera_io_w(CCI_M0_HALT_REQ_RMSK,
- cci_dev->base + CCI_HALT_REQ_ADDR);
- - }
- - if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
- + }
- + if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
- pr_err("%s:%d MASTER_1 error %x\n", __func__, __LINE__, irq);
- cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
- msm_camera_io_w(CCI_M1_HALT_REQ_RMSK,
- @@ -855,7 +898,7 @@ static long msm_cci_subdev_ioctl(struct v4l2_subdev *sd,
- rc = msm_cci_config(sd, arg);
- break;
- case MSM_SD_SHUTDOWN: {
- - break;
- + return rc;
- }
- default:
- rc = -ENOIOCTLCMD;
- @@ -881,7 +924,7 @@ static void msm_cci_init_cci_params(struct cci_device *new_cci_dev)
- uint8_t i = 0, j = 0;
- for (i = 0; i < NUM_MASTERS; i++) {
- new_cci_dev->cci_master_info[i].status = 0;
- - mutex_init(&new_cci_dev->mutex);
- + mutex_init(&new_cci_dev->cci_master_info[i].mutex);
- init_completion(&new_cci_dev->
- cci_master_info[i].reset_complete);
- for (j = 0; j < NUM_QUEUES; j++) {
- @@ -970,58 +1013,96 @@ static void msm_cci_init_clk_params(struct cci_device *cci_dev)
- {
- int32_t rc = 0;
- uint32_t val = 0;
- + uint8_t count = 0;
- struct device_node *of_node = cci_dev->pdev->dev.of_node;
- + struct device_node *src_node = NULL;
- +
- + for (count = 0; count < MASTER_MAX; count++) {
- +
- + if (MASTER_0 == count)
- + src_node = of_find_node_by_name(of_node,
- + "qcom,cci-master0");
- + else if (MASTER_1 == count)
- + src_node = of_find_node_by_name(of_node,
- + "qcom,cci-master1");
- + else
- + return;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-thigh", &val);
- + CDBG("%s qcom,hw-thigh %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_thigh = val;
- + else
- + cci_dev->cci_clk_params[count].hw_thigh = 78;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-tlow", &val);
- + CDBG("%s qcom,hw-tlow %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_tlow = val;
- + else
- + cci_dev->cci_clk_params[count].hw_tlow = 114;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-tsu-sto", &val);
- + CDBG("%s qcom,hw-tsu-sto %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_tsu_sto = val;
- + else
- + cci_dev->cci_clk_params[count].hw_tsu_sto = 28;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-tsu-sta", &val);
- + CDBG("%s qcom,hw-tsu-sta %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_tsu_sta = val;
- + else
- + cci_dev->cci_clk_params[count].hw_tsu_sta = 28;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-thd-dat", &val);
- + CDBG("%s qcom,hw-thd-dat %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_thd_dat = val;
- + else
- + cci_dev->cci_clk_params[count].hw_thd_dat = 10;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-thd-sta", &val);
- + CDBG("%s qcom,hwthd-sta %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_thd_sta = val;
- + else
- + cci_dev->cci_clk_params[count].hw_thd_sta = 77;
- - rc = of_property_read_u32(of_node, "qcom,hw-thigh", &val);
- - CDBG("%s qcom,hw-thigh %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_thigh = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-tlow", &val);
- - CDBG("%s qcom,hw-tlow %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_tlow = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-tsu-sto", &val);
- - CDBG("%s qcom,hw-tsu-sto %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_tsu_sto = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-tsu-sta", &val);
- - CDBG("%s qcom,hw-tsu-sta %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_tsu_sta = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-thd-dat", &val);
- - CDBG("%s qcom,hw-thd-dat %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_thd_dat = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-thd-sta", &val);
- - CDBG("%s qcom,hwthd-sta %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_thd_sta = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-tbuf", &val);
- - CDBG("%s qcom,hw-tbuf %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_tbuf = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-scl-stretch-en", &val);
- - CDBG("%s qcom,hw-scl-stretch-en %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_scl_stretch_en = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-trdhld", &val);
- - CDBG("%s qcom,hw-trdhld %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_trdhld = val;
- -
- - rc = of_property_read_u32(of_node, "qcom,hw-tsp", &val);
- - CDBG("%s qcom,hw-tsp %d, rc %d\n", __func__, val, rc);
- - if (!rc)
- - cci_dev->cci_clk_params.hw_tsp = val;
- + rc = of_property_read_u32(src_node, "qcom,hw-tbuf", &val);
- + CDBG("%s qcom,hw-tbuf %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_tbuf = val;
- + else
- + cci_dev->cci_clk_params[count].hw_tbuf = 118;
- +
- + rc = of_property_read_u32(src_node,
- + "qcom,hw-scl-stretch-en", &val);
- + CDBG("%s qcom,hw-scl-stretch-en %d, rc %d\n",
- + __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_scl_stretch_en = val;
- + else
- + cci_dev->cci_clk_params[count].hw_scl_stretch_en = 0;
- + rc = of_property_read_u32(src_node, "qcom,hw-trdhld", &val);
- + CDBG("%s qcom,hw-trdhld %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_trdhld = val;
- + else
- + cci_dev->cci_clk_params[count].hw_trdhld = 6;
- +
- + rc = of_property_read_u32(src_node, "qcom,hw-tsp", &val);
- + CDBG("%s qcom,hw-tsp %d, rc %d\n", __func__, val, rc);
- + if (!rc)
- + cci_dev->cci_clk_params[count].hw_tsp = val;
- + else
- + cci_dev->cci_clk_params[count].hw_tsp = 1;
- +
- + of_node_put(src_node);
- + src_node = NULL;
- + }
- return;
- }
- @@ -1037,7 +1118,7 @@ static int __devinit msm_cci_probe(struct platform_device *pdev)
- CDBG("%s: pdev %p device id = %d\n", __func__, pdev, pdev->id);
- new_cci_dev = kzalloc(sizeof(struct cci_device), GFP_KERNEL);
- if (!new_cci_dev) {
- - pr_err("%s: no enough memory\n", __func__);
- + CDBG("%s: no enough memory\n", __func__);
- return -ENOMEM;
- }
- v4l2_subdev_init(&new_cci_dev->msm_sd.sd, &msm_cci_subdev_ops);
- @@ -1054,7 +1135,7 @@ static int __devinit msm_cci_probe(struct platform_device *pdev)
- new_cci_dev->mem = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "cci");
- if (!new_cci_dev->mem) {
- - pr_err("%s: no mem resource?\n", __func__);
- + CDBG("%s: no mem resource?\n", __func__);
- rc = -ENODEV;
- goto cci_no_resource;
- }
- @@ -1065,14 +1146,14 @@ static int __devinit msm_cci_probe(struct platform_device *pdev)
- new_cci_dev->irq->start,
- new_cci_dev->irq->end);
- if (!new_cci_dev->irq) {
- - pr_err("%s: no irq resource?\n", __func__);
- + CDBG("%s: no irq resource?\n", __func__);
- rc = -ENODEV;
- goto cci_no_resource;
- }
- new_cci_dev->io = request_mem_region(new_cci_dev->mem->start,
- resource_size(new_cci_dev->mem), pdev->name);
- if (!new_cci_dev->io) {
- - pr_err("%s: no valid mem region\n", __func__);
- + CDBG("%s: no valid mem region\n", __func__);
- rc = -EBUSY;
- goto cci_no_resource;
- }
- @@ -1080,19 +1161,18 @@ static int __devinit msm_cci_probe(struct platform_device *pdev)
- new_cci_dev->base = ioremap(new_cci_dev->mem->start,
- resource_size(new_cci_dev->mem));
- if (!new_cci_dev->base) {
- - pr_err("%s : cci_dev base is NULL", __func__);
- rc = -ENOMEM;
- goto cci_release_mem;
- }
- rc = request_irq(new_cci_dev->irq->start, msm_cci_irq,
- IRQF_TRIGGER_RISING, "cci", new_cci_dev);
- if (rc < 0) {
- - pr_err("%s: irq request fail\n", __func__);
- + CDBG("%s: irq request fail\n", __func__);
- rc = -EBUSY;
- - goto cci_ioremap_mem;
- + goto cci_release_mem;
- }
- disable_irq(new_cci_dev->irq->start);
- - new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x7;
- + new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
- msm_sd_register(&new_cci_dev->msm_sd);
- new_cci_dev->pdev = pdev;
- msm_cci_init_cci_params(new_cci_dev);
- @@ -1105,17 +1185,14 @@ static int __devinit msm_cci_probe(struct platform_device *pdev)
- g_cci_subdev = &new_cci_dev->msm_sd.sd;
- CDBG("%s cci subdev %p\n", __func__, &new_cci_dev->msm_sd.sd);
- CDBG("%s line %d\n", __func__, __LINE__);
- - pr_warn("%s : Succeed!", __func__);
- return 0;
- -cci_ioremap_mem:
- - iounmap(new_cci_dev->base);
- cci_release_mem:
- release_mem_region(new_cci_dev->mem->start,
- resource_size(new_cci_dev->mem));
- cci_no_resource:
- kfree(new_cci_dev);
- - return rc;
- + return 0;
- }
- static int __exit msm_cci_exit(struct platform_device *pdev)
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
- index 81293f2..e1012c6 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
- +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.h
- @@ -51,6 +51,7 @@ enum msm_cci_cmd_type {
- MSM_CCI_SET_SYNC_CID,
- MSM_CCI_I2C_READ,
- MSM_CCI_I2C_WRITE,
- + MSM_CCI_I2C_WRITE_SEQ,
- MSM_CCI_GPIO_WRITE,
- MSM_CCI_I2C_WRITE_BURST,
- };
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
- index e0659d6..53a5ed3 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
- +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
- @@ -13,6 +13,7 @@
- #include <linux/delay.h>
- #include <linux/module.h>
- #include <linux/of.h>
- +#include <linux/ratelimit.h>
- #include <linux/irqreturn.h>
- #include "msm_csid.h"
- #include "msm_csid_hwreg.h"
- @@ -20,8 +21,9 @@
- #include "msm_camera_io_util.h"
- #define V4L2_IDENT_CSID 50002
- -#define CSID_VERSION_V2 0x02000011
- -#define CSID_VERSION_V3 0x30000000
- +#define CSID_VERSION_V20 0x02000011
- +#define CSID_VERSION_V22 0x02001000
- +#define CSID_VERSION_V30 0x30000000
- #define MSM_CSID_DRV_NAME "msm_csid"
- #define DBG_CSID 0
- @@ -51,9 +53,9 @@ static int msm_csid_cid_lut(
- if (csid_lut_params->vc_cfg[i]->cid >=
- csid_lut_params->num_cid ||
- csid_lut_params->vc_cfg[i]->cid < 0) {
- - pr_err("%s: cid outside range %d\n",
- - __func__, csid_lut_params->vc_cfg[i]->cid);
- - return -EINVAL;
- + pr_err("%s: cid outside range %d\n",
- + __func__, csid_lut_params->vc_cfg[i]->cid);
- + return -EINVAL;
- }
- CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
- __func__,
- @@ -100,7 +102,7 @@ static void msm_csid_set_debug_reg(void __iomem *csidbase,
- static void msm_csid_reset(struct csid_device *csid_dev)
- {
- msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
- - wait_for_completion_interruptible(&csid_dev->reset_complete);
- + wait_for_completion(&csid_dev->reset_complete);
- return;
- }
- @@ -148,23 +150,14 @@ static int msm_csid_config(struct csid_device *csid_dev,
- static irqreturn_t msm_csid_irq(int irq_num, void *data)
- {
- uint32_t irq;
- - struct csid_device *csid_dev ;//prevent
- + struct csid_device *csid_dev = data;
- void __iomem *csidbase;
- + csidbase = csid_dev->base;
- - if (!data) {
- - pr_err("%s:%d data NULL\n", __func__, __LINE__);
- - return IRQ_HANDLED;
- - }//prevent
- -
- - csid_dev = data;
- -
- - if (!csid_dev || ! csid_dev->base) {
- + if (!csid_dev) {
- pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
- return IRQ_HANDLED;
- }
- -
- - csidbase = csid_dev->base;
- -
- irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
- CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
- __func__, csid_dev->pdev->id, irq);
- @@ -212,6 +205,27 @@ static struct msm_cam_clk_info csid_8974_clk_info[] = {
- {"csi_rdi_clk", -1},
- };
- +static struct msm_cam_clk_info csid_8610_clk_info[] = {
- + {"csi_ahb_clk", -1},
- + {"csi_src_clk", 200000000},
- + {"csi_clk", -1},
- + {"csi0phy_mux_clk", -1},
- + {"csi1phy_mux_clk", -1},
- + {"csi0pix_mux_clk", -1},
- + {"csi0rdi_mux_clk", -1},
- + {"csi1rdi_mux_clk", -1},
- + {"csi2rdi_mux_clk", -1},
- +};
- +
- +static struct msm_cam_clk_info csid_8610_clk_src_info[] = {
- + {"csi_phy_src_clk", 0},
- + {"csi_phy_src_clk", 0},
- + {"csi_pix_src_clk", 0},
- + {"csi_rdi_src_clk", 0},
- + {"csi_rdi_src_clk", 0},
- + {"csi_rdi_src_clk", 0},
- +};
- +
- static struct camera_vreg_t csid_8960_vreg_info[] = {
- {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
- };
- @@ -223,6 +237,7 @@ static struct camera_vreg_t csid_vreg_info[] = {
- static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
- {
- int rc = 0;
- + struct camera_vreg_t *cam_vreg;
- if (!csid_version) {
- pr_err("%s:%d csid_version NULL\n", __func__, __LINE__);
- @@ -245,31 +260,50 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
- return rc;
- }
- - if (CSID_VERSION <= CSID_VERSION_V2) {
- + if (CSID_VERSION == CSID_VERSION_V20)
- + cam_vreg = csid_8960_vreg_info;
- + else
- + cam_vreg = csid_vreg_info;
- +
- + if (CSID_VERSION < CSID_VERSION_V30) {
- rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
- - csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 1);
- if (rc < 0) {
- pr_err("%s: regulator on failed\n", __func__);
- goto vreg_config_failed;
- }
- -
- rc = msm_camera_enable_vreg(&csid_dev->pdev->dev,
- - csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 1);
- if (rc < 0) {
- pr_err("%s: regulator enable failed\n", __func__);
- goto vreg_enable_failed;
- }
- - rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
- - csid_8960_clk_info, csid_dev->csid_clk,
- - ARRAY_SIZE(csid_8960_clk_info), 1);
- - if (rc < 0) {
- - pr_err("%s: clock enable failed\n", __func__);
- - goto clk_enable_failed;
- + if (CSID_VERSION == CSID_VERSION_V20) {
- + rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
- + csid_8960_clk_info, csid_dev->csid_clk,
- + ARRAY_SIZE(csid_8960_clk_info), 1);
- + if (rc < 0) {
- + pr_err("%s: 8960: clock enable failed\n",
- + __func__);
- + goto clk_enable_failed;
- + }
- + } else {
- + msm_cam_clk_sel_src(&csid_dev->pdev->dev,
- + &csid_8610_clk_info[3], csid_8610_clk_src_info,
- + ARRAY_SIZE(csid_8610_clk_src_info));
- + rc = msm_cam_clk_enable(&csid_dev->pdev->dev,
- + csid_8610_clk_info, csid_dev->csid_clk,
- + ARRAY_SIZE(csid_8610_clk_info), 1);
- + if (rc < 0) {
- + pr_err("%s: 8610: clock enable failed\n",
- + __func__);
- + goto clk_enable_failed;
- + }
- }
- - } else if (CSID_VERSION >= CSID_VERSION_V3) {
- + } else if (CSID_VERSION >= CSID_VERSION_V30) {
- rc = msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 1);
- @@ -310,21 +344,21 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
- return rc;
- clk_enable_failed:
- - if (CSID_VERSION <= CSID_VERSION_V2) {
- + if (CSID_VERSION < CSID_VERSION_V30) {
- msm_camera_enable_vreg(&csid_dev->pdev->dev,
- - csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 0);
- - } else if (CSID_VERSION >= CSID_VERSION_V3) {
- + } else if (CSID_VERSION >= CSID_VERSION_V30) {
- msm_camera_enable_vreg(&csid_dev->pdev->dev,
- csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 0);
- }
- vreg_enable_failed:
- - if (CSID_VERSION <= CSID_VERSION_V2) {
- + if (CSID_VERSION < CSID_VERSION_V30) {
- msm_camera_config_vreg(&csid_dev->pdev->dev,
- - csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 0);
- - } else if (CSID_VERSION >= CSID_VERSION_V3) {
- + } else if (CSID_VERSION >= CSID_VERSION_V30) {
- msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 0);
- @@ -351,7 +385,7 @@ static int msm_csid_release(struct csid_device *csid_dev)
- disable_irq(csid_dev->irq->start);
- - if (csid_dev->hw_version <= CSID_VERSION_V2) {
- + if (csid_dev->hw_version == CSID_VERSION_V20) {
- msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info,
- csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0);
- @@ -362,7 +396,20 @@ static int msm_csid_release(struct csid_device *csid_dev)
- msm_camera_config_vreg(&csid_dev->pdev->dev,
- csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info),
- NULL, 0, &csid_dev->csi_vdd, 0);
- - } else if (csid_dev->hw_version >= CSID_VERSION_V3) {
- + } else if (csid_dev->hw_version == CSID_VERSION_V22) {
- + msm_cam_clk_enable(&csid_dev->pdev->dev,
- + csid_8610_clk_info,
- + csid_dev->csid_clk,
- + ARRAY_SIZE(csid_8610_clk_info), 0);
- +
- + msm_camera_enable_vreg(&csid_dev->pdev->dev,
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- + NULL, 0, &csid_dev->csi_vdd, 0);
- +
- + msm_camera_config_vreg(&csid_dev->pdev->dev,
- + csid_vreg_info, ARRAY_SIZE(csid_vreg_info),
- + NULL, 0, &csid_dev->csi_vdd, 0);
- + } else if (csid_dev->hw_version >= CSID_VERSION_V30) {
- msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info,
- csid_dev->csid_clk, ARRAY_SIZE(csid_8974_clk_info), 0);
- @@ -401,7 +448,7 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
- case CSID_CFG: {
- struct msm_camera_csid_params csid_params;
- struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
- - int32_t i = 0;
- + int8_t i = 0;
- if (copy_from_user(&csid_params,
- (void *)cdata->cfg.csid_params,
- sizeof(struct msm_camera_csid_params))) {
- @@ -409,10 +456,16 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
- rc = -EFAULT;
- break;
- }
- + if (csid_params.lut_params.num_cid < 1 ||
- + csid_params.lut_params.num_cid > 16) {
- + pr_err("%s: %d num_cid outside range\n",
- + __func__, __LINE__);
- + rc = -EINVAL;
- + break;
- + }
- for (i = 0; i < csid_params.lut_params.num_cid; i++) {
- - vc_cfg = kzalloc(csid_params.lut_params.num_cid *
- - sizeof(struct msm_camera_csid_vc_cfg),
- - GFP_KERNEL);
- + vc_cfg = kzalloc(sizeof(struct msm_camera_csid_vc_cfg),
- + GFP_KERNEL);
- if (!vc_cfg) {
- pr_err("%s: %d failed\n", __func__, __LINE__);
- for (i--; i >= 0; i--)
- @@ -422,8 +475,7 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
- }
- if (copy_from_user(vc_cfg,
- (void *)csid_params.lut_params.vc_cfg[i],
- - (csid_params.lut_params.num_cid *
- - sizeof(struct msm_camera_csid_vc_cfg)))) {
- + sizeof(struct msm_camera_csid_vc_cfg))) {
- pr_err("%s: %d failed\n", __func__, __LINE__);
- kfree(vc_cfg);
- for (i--; i >= 0; i--)
- @@ -442,7 +494,7 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
- rc = msm_csid_release(csid_dev);
- break;
- default:
- - pr_err("%s: %d failed\n", __func__, __LINE__);
- + pr_err_ratelimited("%s: %d failed\n", __func__, __LINE__);
- rc = -ENOIOCTLCMD;
- break;
- }
- @@ -582,13 +634,20 @@ static int __devinit csid_probe(struct platform_device *pdev)
- goto csid_no_resource;
- }
- disable_irq(new_csid_dev->irq->start);
- + if (rc < 0) {
- + release_mem_region(new_csid_dev->mem->start,
- + resource_size(new_csid_dev->mem));
- + pr_err("%s Error registering irq ", __func__);
- + goto csid_no_resource;
- + }
- +
- new_csid_dev->csid_state = CSID_POWER_DOWN;
- return 0;
- csid_no_resource:
- mutex_destroy(&new_csid_dev->mutex);
- kfree(new_csid_dev);
- - return rc;
- + return 0;
- }
- static const struct of_device_id msm_csid_dt_match[] = {
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
- index d844593..0ca94f9 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
- +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
- @@ -161,7 +161,7 @@ int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
- reg_conf_tbl[i].reg_data = data[i];
- reg_conf_tbl[i].delay = 0;
- }
- - cci_ctrl.cmd = MSM_CCI_I2C_WRITE;
- + cci_ctrl.cmd = MSM_CCI_I2C_WRITE_SEQ;
- cci_ctrl.cci_info = client->cci_client;
- cci_ctrl.cfg.cci_i2c_write_cfg.reg_setting = reg_conf_tbl;
- cci_ctrl.cfg.cci_i2c_write_cfg.data_type = MSM_CAMERA_I2C_BYTE_DATA;
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
- index 5e4805c..7d369ff 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
- +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
- @@ -21,8 +21,6 @@
- #include <mach/msm_bus.h>
- #include "msm_camera_io_util.h"
- -#include <mach/clk-provider.h>
- -
- #define BUFF_SIZE_128 128
- #undef CDBG
- @@ -120,17 +118,40 @@ void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
- msm_camera_io_w_mb(*s++, d++);
- }
- +int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
- + struct msm_cam_clk_info *clk_src_info, int num_clk)
- +{
- + int i;
- + int rc = 0;
- + struct clk *mux_clk = NULL;
- + struct clk *src_clk = NULL;
- +
- + for (i = 0; i < num_clk; i++) {
- + if (clk_src_info[i].clk_name) {
- + mux_clk = clk_get(dev, clk_info[i].clk_name);
- + if (IS_ERR(mux_clk)) {
- + pr_err("%s get failed\n",
- + clk_info[i].clk_name);
- + continue;
- + }
- + src_clk = clk_get(dev, clk_src_info[i].clk_name);
- + if (IS_ERR(src_clk)) {
- + pr_err("%s get failed\n",
- + clk_src_info[i].clk_name);
- + continue;
- + }
- + clk_set_parent(mux_clk, src_clk);
- + }
- + }
- + return rc;
- +}
- +
- int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
- struct clk **clk_ptr, int num_clk, int enable)
- {
- int i;
- int rc = 0;
- - int qctkd = 0;
- long clk_rate;
- -
- - if (num_clk == 8) //CPP use case
- - qctkd = 1;
- -
- if (enable) {
- for (i = 0; i < num_clk; i++) {
- CDBG("%s enable %s\n", __func__,
- @@ -141,7 +162,7 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
- rc = PTR_ERR(clk_ptr[i]);
- goto cam_clk_get_err;
- }
- - if (clk_info[i].clk_rate >= 0) {
- + if (clk_info[i].clk_rate > 0) {
- rc = clk_set_rate(clk_ptr[i],
- clk_info[i].clk_rate);
- if (rc < 0) {
- @@ -187,7 +208,6 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
- usleep_range(clk_info[i].delay * 1000,
- (clk_info[i].delay * 1000) + 1000);
- }
- - if (qctkd) printk (KERN_ERR "QCTKD: %s[%d:%d] Enable \n", clk_info[i].clk_name, clk_ptr[i]->prepare_count, clk_ptr[i]->count);
- }
- } else {
- for (i = num_clk - 1; i >= 0; i--) {
- @@ -198,7 +218,6 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
- clk_unprepare(clk_ptr[i]);
- clk_put(clk_ptr[i]);
- }
- - if (qctkd) printk (KERN_ERR "QCTKD: %s[%d:%d] Disable\n", clk_info[i].clk_name, clk_ptr[i]->prepare_count, clk_ptr[i]->count);
- }
- }
- return rc;
- @@ -466,13 +485,8 @@ int msm_camera_config_single_vreg(struct device *dev,
- struct camera_vreg_t *cam_vreg, struct regulator **reg_ptr, int config)
- {
- int rc = 0;
- -
- if (config) {
- - if (cam_vreg->reg_name == NULL) {
- - pr_err("%s : can't find reg name", __func__);
- - goto vreg_get_fail;
- - }
- - pr_info("%s enable %s\n", __func__, cam_vreg->reg_name);
- + CDBG("%s enable %s\n", __func__, cam_vreg->reg_name);
- *reg_ptr = regulator_get(dev, cam_vreg->reg_name);
- if (IS_ERR(*reg_ptr)) {
- pr_err("%s: %s get failed\n", __func__,
- @@ -508,7 +522,7 @@ int msm_camera_config_single_vreg(struct device *dev,
- }
- } else {
- if (*reg_ptr) {
- - pr_info("%s disable %s\n", __func__, cam_vreg->reg_name);
- + CDBG("%s disable %s\n", __func__, cam_vreg->reg_name);
- regulator_disable(*reg_ptr);
- if (cam_vreg->type == REG_LDO) {
- if (cam_vreg->op_mode >= 0)
- @@ -518,8 +532,7 @@ int msm_camera_config_single_vreg(struct device *dev,
- }
- regulator_put(*reg_ptr);
- *reg_ptr = NULL;
- - } else
- - pr_err("%s can't disable %s\n", __func__, cam_vreg->reg_name);
- + }
- }
- return 0;
- @@ -542,23 +555,31 @@ vreg_get_fail:
- int msm_camera_request_gpio_table(struct gpio *gpio_tbl, uint8_t size,
- int gpio_en)
- {
- - int rc = 0, i = 0;
- + int rc = 0, i = 0, err = 0;
- if (!gpio_tbl || !size) {
- pr_err("%s:%d invalid gpio_tbl %p / size %d\n", __func__,
- - __LINE__, gpio_tbl, size);
- - return -EINVAL;
- + __LINE__, gpio_tbl, size);
- + return -EINVAL;
- }
- for (i = 0; i < size; i++) {
- CDBG("%s:%d i %d, gpio %d dir %ld\n", __func__, __LINE__, i,
- gpio_tbl[i].gpio, gpio_tbl[i].flags);
- }
- if (gpio_en) {
- - rc = gpio_request_array(gpio_tbl, size);
- - if (rc < 0) {
- - pr_err("%s:%d camera gpio request failed\n", __func__,
- - __LINE__);
- - return rc;
- + for (i = 0; i < size; i++) {
- + err = gpio_request_one(gpio_tbl[i].gpio,
- + gpio_tbl[i].flags, gpio_tbl[i].label);
- + if (err) {
- + /*
- + * After GPIO request fails, contine to
- + * apply new gpios, outout a error message
- + * for driver bringup debug
- + */
- + pr_err("%s:%d gpio %d:%s request fails\n",
- + __func__, __LINE__,
- + gpio_tbl[i].gpio, gpio_tbl[i].label);
- + }
- }
- } else {
- gpio_free_array(gpio_tbl, size);
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
- index a5286bb..90925a9 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
- +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
- @@ -30,6 +30,8 @@ void msm_camera_io_memcpy(void __iomem *dest_addr,
- void __iomem *src_addr, u32 len);
- void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
- void __iomem *src_addr, u32 len);
- +int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
- + struct msm_cam_clk_info *clk_src_info, int num_clk);
- int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
- struct clk **clk_ptr, int num_clk, int enable);
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
- index c0358e9..06c1adc 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
- +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -10,8 +10,7 @@
- * GNU General Public License for more details.
- */
- -#define pr_fmt(fmt) "MSM-SENSOR-DRIVER %s:%d " fmt "\n", __func__, __LINE__
- -
- +#define SENSOR_DRIVER_I2C "camera"
- /* Header file declaration */
- #include "msm_sensor.h"
- #include "msm_sd.h"
- @@ -19,8 +18,8 @@
- #include "msm_cci.h"
- #include "msm_camera_dt_util.h"
- -//#define MSM_SENSOR_DRIVER_DEBUG
- /* Logging macro */
- +/*#define MSM_SENSOR_DRIVER_DEBUG*/
- #undef CDBG
- #ifdef MSM_SENSOR_DRIVER_DEBUG
- #define CDBG(fmt, args...) pr_err(fmt, ##args)
- @@ -28,9 +27,33 @@
- #define CDBG(fmt, args...) pr_debug(fmt, ##args)
- #endif
- +#define SENSOR_MAX_MOUNTANGLE (360)
- +
- /* Static declaration */
- static struct msm_sensor_ctrl_t *g_sctrl[MAX_CAMERAS];
- +static int msm_sensor_platform_remove(struct platform_device *pdev)
- +{
- + struct msm_sensor_ctrl_t *s_ctrl;
- +
- + pr_err("%s: sensor FREE\n", __func__);
- +
- + s_ctrl = g_sctrl[pdev->id];
- + if (!s_ctrl) {
- + pr_err("%s: sensor device is NULL\n", __func__);
- + return 0;
- + }
- +
- + msm_sensor_free_sensor_data(s_ctrl);
- + kfree(s_ctrl->msm_sensor_mutex);
- + kfree(s_ctrl->sensor_i2c_client);
- + kfree(s_ctrl);
- + g_sctrl[pdev->id] = NULL;
- +
- + return 0;
- +}
- +
- +
- static const struct of_device_id msm_sensor_driver_dt_match[] = {
- {.compatible = "qcom,camera"},
- {}
- @@ -44,6 +67,7 @@ static struct platform_driver msm_sensor_platform_driver = {
- .owner = THIS_MODULE,
- .of_match_table = msm_sensor_driver_dt_match,
- },
- + .remove = msm_sensor_platform_remove,
- };
- static struct v4l2_subdev_info msm_sensor_driver_subdev_info[] = {
- @@ -55,316 +79,574 @@ static struct v4l2_subdev_info msm_sensor_driver_subdev_info[] = {
- },
- };
- +static int32_t msm_sensor_driver_create_i2c_v4l_subdev
- + (struct msm_sensor_ctrl_t *s_ctrl)
- +{
- + int32_t rc = 0;
- + uint32_t session_id = 0;
- + struct i2c_client *client = s_ctrl->sensor_i2c_client->client;
- +
- + CDBG("%s %s I2c probe succeeded\n", __func__, client->name);
- + rc = camera_init_v4l2(&client->dev, &session_id);
- + if (rc < 0) {
- + pr_err("failed: camera_init_i2c_v4l2 rc %d", rc);
- + return rc;
- + }
- + CDBG("%s rc %d session_id %d\n", __func__, rc, session_id);
- + snprintf(s_ctrl->msm_sd.sd.name,
- + sizeof(s_ctrl->msm_sd.sd.name), "%s",
- + s_ctrl->sensordata->sensor_name);
- + v4l2_i2c_subdev_init(&s_ctrl->msm_sd.sd, client,
- + s_ctrl->sensor_v4l2_subdev_ops);
- + v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client);
- + s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- + media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
- + s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- + s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
- + s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
- + s_ctrl->sensordata->sensor_info->session_id = session_id;
- + s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- + msm_sd_register(&s_ctrl->msm_sd);
- + CDBG("%s:%d\n", __func__, __LINE__);
- + return rc;
- +}
- +
- +static int32_t msm_sensor_driver_create_v4l_subdev
- + (struct msm_sensor_ctrl_t *s_ctrl)
- +{
- + int32_t rc = 0;
- + uint32_t session_id = 0;
- +
- + rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
- + if (rc < 0) {
- + pr_err("failed: camera_init_v4l2 rc %d", rc);
- + return rc;
- + }
- + CDBG("rc %d session_id %d", rc, session_id);
- + s_ctrl->sensordata->sensor_info->session_id = session_id;
- +
- + /* Create /dev/v4l-subdevX device */
- + v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
- + snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
- + s_ctrl->sensordata->sensor_name);
- + v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
- + s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- + media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
- + s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- + s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
- + s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
- + s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- + msm_sd_register(&s_ctrl->msm_sd);
- + return rc;
- +}
- +
- +static int32_t msm_sensor_fill_eeprom_subdevid_by_name(
- + struct msm_sensor_ctrl_t *s_ctrl)
- +{
- + int32_t rc = 0;
- + const char *eeprom_name;
- + struct device_node *src_node = NULL;
- + uint32_t val = 0, count = 0, eeprom_name_len;
- + int i;
- + int32_t *eeprom_subdev_id;
- + struct msm_sensor_info_t *sensor_info;
- + struct device_node *of_node = s_ctrl->of_node;
- + const void *p;
- +
- + if (!s_ctrl->sensordata->eeprom_name || !of_node)
- + return -EINVAL;
- +
- + eeprom_name_len = strlen(s_ctrl->sensordata->eeprom_name);
- + if (eeprom_name_len >= MAX_SENSOR_NAME)
- + return -EINVAL;
- +
- + sensor_info = s_ctrl->sensordata->sensor_info;
- + eeprom_subdev_id = &sensor_info->subdev_id[SUB_MODULE_EEPROM];
- + /*
- + * string for eeprom name is valid, set sudev id to -1
- + * and try to found new id
- + */
- + *eeprom_subdev_id = -1;
- +
- + if (0 == eeprom_name_len)
- + return 0;
- +
- + CDBG("Try to find eeprom subdev for %s\n",
- + s_ctrl->sensordata->eeprom_name);
- + p = of_get_property(of_node, "qcom,eeprom-src", &count);
- + if (!p || !count)
- + return 0;
- +
- + count /= sizeof(uint32_t);
- + for (i = 0; i < count; i++) {
- + eeprom_name = NULL;
- + src_node = of_parse_phandle(of_node, "qcom,eeprom-src", i);
- + if (!src_node) {
- + pr_err("eeprom src node NULL\n");
- + continue;
- + }
- + rc = of_property_read_string(src_node, "qcom,eeprom-name",
- + &eeprom_name);
- + if (rc < 0) {
- + pr_err("failed\n");
- + of_node_put(src_node);
- + continue;
- + }
- + if (strcmp(eeprom_name, s_ctrl->sensordata->eeprom_name))
- + continue;
- +
- + rc = of_property_read_u32(src_node, "cell-index", &val);
- +
- + CDBG("%s qcom,eeprom cell index %d, rc %d\n", __func__,
- + val, rc);
- + if (rc < 0) {
- + pr_err("failed\n");
- + of_node_put(src_node);
- + continue;
- + }
- +
- + *eeprom_subdev_id = val;
- + CDBG("Done. Eeprom subdevice id is %d\n", val);
- + of_node_put(src_node);
- + src_node = NULL;
- + break;
- + }
- +
- + return rc;
- +}
- +
- +static int32_t msm_sensor_fill_actuator_subdevid_by_name(
- + struct msm_sensor_ctrl_t *s_ctrl)
- +{
- + int32_t rc = 0;
- + struct device_node *src_node = NULL;
- + uint32_t val = 0, actuator_name_len;
- + int32_t *actuator_subdev_id;
- + struct msm_sensor_info_t *sensor_info;
- + struct device_node *of_node = s_ctrl->of_node;
- +
- + if (!s_ctrl->sensordata->actuator_name || !of_node)
- + return -EINVAL;
- +
- + actuator_name_len = strlen(s_ctrl->sensordata->actuator_name);
- + if (actuator_name_len >= MAX_SENSOR_NAME)
- + return -EINVAL;
- +
- + sensor_info = s_ctrl->sensordata->sensor_info;
- + actuator_subdev_id = &sensor_info->subdev_id[SUB_MODULE_ACTUATOR];
- + /*
- + * string for actuator name is valid, set sudev id to -1
- + * and try to found new id
- + */
- + *actuator_subdev_id = -1;
- +
- + if (0 == actuator_name_len)
- + return 0;
- +
- + src_node = of_parse_phandle(of_node, "qcom,actuator-src", 0);
- + if (!src_node) {
- + CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
- + } else {
- + rc = of_property_read_u32(src_node, "cell-index", &val);
- + CDBG("%s qcom,actuator cell index %d, rc %d\n", __func__,
- + val, rc);
- + if (rc < 0) {
- + pr_err("%s failed %d\n", __func__, __LINE__);
- + return -EINVAL;
- + }
- + *actuator_subdev_id = val;
- + of_node_put(src_node);
- + src_node = NULL;
- + }
- +
- + return rc;
- +}
- +
- +static int32_t msm_sensor_fill_slave_info_init_params(
- + struct msm_camera_sensor_slave_info *slave_info,
- + struct msm_sensor_info_t *sensor_info)
- +{
- + struct msm_sensor_init_params *sensor_init_params;
- + if (!slave_info || !sensor_info)
- + return -EINVAL;
- +
- + if (!slave_info->is_init_params_valid)
- + return 0;
- +
- + sensor_init_params = &slave_info->sensor_init_params;
- + if (INVALID_CAMERA_B != sensor_init_params->position)
- + sensor_info->position =
- + sensor_init_params->position;
- +
- + if (SENSOR_MAX_MOUNTANGLE > sensor_init_params->sensor_mount_angle) {
- + sensor_info->sensor_mount_angle =
- + sensor_init_params->sensor_mount_angle;
- + sensor_info->is_mount_angle_valid = 1;
- + }
- +
- + if (CAMERA_MODE_INVALID != sensor_init_params->modes_supported)
- + sensor_info->modes_supported =
- + sensor_init_params->modes_supported;
- +
- + return 0;
- +}
- +
- +
- +static int32_t msm_sensor_validate_slave_info(
- + struct msm_sensor_info_t *sensor_info)
- +{
- + if (INVALID_CAMERA_B == sensor_info->position) {
- + sensor_info->position = BACK_CAMERA_B;
- + pr_err("%s Set dafault sensor position%d\n",
- + __func__, __LINE__);
- + }
- + if (CAMERA_MODE_INVALID == sensor_info->modes_supported) {
- + sensor_info->modes_supported = CAMERA_MODE_2D_B;
- + pr_err("%s Set dafault sensor modes_supported%d\n",
- + __func__, __LINE__);
- + }
- + if (SENSOR_MAX_MOUNTANGLE < sensor_info->sensor_mount_angle) {
- + sensor_info->sensor_mount_angle = 0;
- + pr_err("%s Set dafault sensor mount angle%d\n",
- + __func__, __LINE__);
- + sensor_info->is_mount_angle_valid = 1;
- + }
- + return 0;
- +}
- +
- /* static function definition */
- int32_t msm_sensor_driver_probe(void *setting)
- {
- - int32_t rc = 0;
- - int32_t is_power_off = 0;
- - uint16_t i = 0, size = 0, off_size = 0;
- - uint32_t session_id = 0;
- - struct msm_sensor_ctrl_t *s_ctrl = NULL;
- - struct msm_camera_cci_client *cci_client = NULL;
- - struct msm_camera_sensor_slave_info *slave_info = NULL;
- - struct msm_sensor_power_setting *power_setting = NULL;
- - struct msm_sensor_power_setting *power_off_setting = NULL;
- - struct msm_camera_slave_info *camera_info = NULL;
- - struct msm_camera_power_ctrl_t *power_info = NULL;
- -
- - /* Validate input parameters */
- - if (!setting) {
- - pr_err("failed: slave_info %p", setting);
- - return -EINVAL;
- - }
- -
- - /* Allocate memory for slave info */
- - slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
- - if (!slave_info) {
- - pr_err("failed: no memory slave_info %p", slave_info);
- - return -ENOMEM;
- - }
- -
- - if (copy_from_user(slave_info, (void *)setting, sizeof(*slave_info))) {
- - pr_err("failed: copy_from_user");
- - rc = -EFAULT;
- - goto FREE_SLAVE_INFO;
- - }
- -
- - /* Print slave info */
- - CDBG("camera id %d", slave_info->camera_id);
- - CDBG("slave_addr %x", slave_info->slave_addr);
- - CDBG("addr_type %d", slave_info->addr_type);
- - CDBG("sensor_id_reg_addr %x",
- - slave_info->sensor_id_info.sensor_id_reg_addr);
- - CDBG("sensor_id %x", slave_info->sensor_id_info.sensor_id);
- - CDBG("size %x", slave_info->power_setting_array.size);
- -
- - /* Validate camera id */
- - if (slave_info->camera_id >= MAX_CAMERAS) {
- - pr_err("failed: invalid camera id %d max %d",
- - slave_info->camera_id, MAX_CAMERAS);
- - rc = -EINVAL;
- - goto FREE_SLAVE_INFO;
- - }
- -
- - /* Extract s_ctrl from camera id */
- - s_ctrl = g_sctrl[slave_info->camera_id];
- - if (!s_ctrl) {
- - pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
- - slave_info->camera_id);
- - rc = -EINVAL;
- - goto FREE_SLAVE_INFO;
- - }
- -
- - CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);
- -
- - if (s_ctrl->is_probe_succeed == 1) {
- - /*
- - * Different sensor on this camera slot has been connected
- - * and probe already succeeded for that sensor. Ignore this
- - * probe
- - */
- - pr_err("slot %d has some other sensor", slave_info->camera_id);
- - kfree(slave_info);
- - return 0;
- - }
- -
- - size = slave_info->power_setting_array.size;
- - /* Allocate memory for power setting */
- - power_setting = kzalloc(sizeof(*power_setting) * size, GFP_KERNEL);
- - if (!power_setting) {
- - pr_err("failed: no memory power_setting %p", power_setting);
- - rc = -ENOMEM;
- - goto FREE_SLAVE_INFO;
- - }
- -
- - if (copy_from_user(power_setting,
- - (void *)slave_info->power_setting_array.power_setting,
- - sizeof(*power_setting) * size)) {
- - pr_err("failed: copy_from_user");
- - rc = -EFAULT;
- - goto FREE_POWER_SETTING;
- - }
- -
- - /* Print power setting */
- - for (i = 0; i < size; i++) {
- - CDBG("seq_type %d seq_val %d config_val %ld delay %d",
- - power_setting[i].seq_type, power_setting[i].seq_val,
- - power_setting[i].config_val, power_setting[i].delay);
- - }
- -
- - off_size = slave_info->power_setting_array.off_size;
- - if (off_size > 0) {
- - /* Allocate memory for power setting */
- - power_off_setting = kzalloc(sizeof(*power_off_setting) * off_size, GFP_KERNEL);
- - if (!power_off_setting) {
- - pr_err("failed: no memory power_setting %p", power_off_setting);
- - rc = -ENOMEM;
- - goto FREE_POWER_SETTING;
- - }
- -
- - if (copy_from_user(power_off_setting,
- - (void *)slave_info->power_setting_array.power_off_setting,
- - sizeof(*power_off_setting) * off_size)) {
- - pr_err("failed: copy_from_user");
- - rc = -EFAULT;
- - goto FREE_POWER_OFF_SETTING;
- - }
- -
- - /* Print power setting */
- - for (i = 0; i < off_size; i++) {
- - CDBG("seq_type %d seq_val %d config_val %ld delay %d",
- - power_off_setting[i].seq_type, power_off_setting[i].seq_val,
- - power_off_setting[i].config_val, power_off_setting[i].delay);
- - }
- - is_power_off = 1;
- - }
- -
- - camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
- - if (!camera_info) {
- - pr_err("failed: no memory slave_info %p", camera_info);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- -
- - /* Fill power up setting and power up setting size */
- - power_info = &s_ctrl->sensordata->power_info;
- - power_info->power_setting = power_setting;
- - power_info->power_setting_size = size;
- - power_info->power_off_setting = power_off_setting;
- - power_info->power_off_setting_size = off_size;
- -
- - s_ctrl->sensordata->slave_info = camera_info;
- -
- - /* Fill sensor slave info */
- - camera_info->sensor_slave_addr = slave_info->slave_addr;
- - camera_info->sensor_id_reg_addr =
- - slave_info->sensor_id_info.sensor_id_reg_addr;
- - camera_info->sensor_id = slave_info->sensor_id_info.sensor_id;
- -
- - /* Fill CCI master, slave address and CCI default params */
- - if (!s_ctrl->sensor_i2c_client) {
- - pr_err("failed: sensor_i2c_client %p",
- - s_ctrl->sensor_i2c_client);
- - rc = -EINVAL;
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- - /* Fill sensor address type */
- - s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
- -
- - cci_client = s_ctrl->sensor_i2c_client->cci_client;
- - if (!cci_client) {
- - pr_err("failed: cci_client %p", cci_client);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- - cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
- - cci_client->sid = slave_info->slave_addr >> 1;
- - cci_client->retries = 3;
- - cci_client->id_map = 0;
- -
- - /* Parse and fill vreg params */
- - rc = msm_camera_fill_vreg_params(
- - power_info->cam_vreg,
- - power_info->num_vreg,
- - power_info->power_setting,
- - power_info->power_setting_size);
- - if (rc < 0) {
- - pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
- - rc);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- -
- - if (power_info->power_off_setting && (power_info->power_off_setting_size > 0)) {
- - /* Parse and fill vreg params */
- - rc = msm_camera_fill_vreg_params(
- - power_info->cam_vreg,
- - power_info->num_vreg,
- - power_info->power_off_setting,
- - power_info->power_off_setting_size);
- - if (rc < 0) {
- - pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
- - rc);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- - }
- - /* remove this code for DFMS test */
- -#if 0
- - /* Power up and probe sensor */
- - rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl,
- - &s_ctrl->sensordata->power_info,
- - s_ctrl->sensor_i2c_client,
- - s_ctrl->sensordata->slave_info,
- - slave_info->sensor_name);
- - if (rc < 0) {
- - pr_err("%s power up failed", slave_info->sensor_name);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- -#endif
- + int32_t rc = 0;
- + uint16_t i = 0, size = 0, size_down = 0;
- + struct msm_sensor_ctrl_t *s_ctrl = NULL;
- + struct msm_camera_cci_client *cci_client = NULL;
- + struct msm_camera_sensor_slave_info *slave_info = NULL;
- + struct msm_sensor_power_setting *power_setting = NULL;
- + struct msm_sensor_power_setting *power_down_setting = NULL;
- + struct msm_camera_slave_info *camera_info = NULL;
- + struct msm_camera_power_ctrl_t *power_info = NULL;
- + int c, end;
- + struct msm_sensor_power_setting power_down_setting_t;
- + unsigned long mount_pos = 0;
- - /* Update sensor name in sensor control structure */
- - s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
- -
- - /*
- - Set probe succeeded flag to 1 so that no other camera shall
- - * probed on this slot
- - */
- - s_ctrl->is_probe_succeed = 1;
- -
- - /*
- - * Create /dev/videoX node, comment for now until dummy /dev/videoX
- - * node is created and used by HAL
- - */
- - rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);
- - if (rc < 0) {
- - pr_err("failed: camera_init_v4l2 rc %d", rc);
- - if (is_power_off)
- - goto FREE_POWER_OFF_SETTING;
- - else
- - goto FREE_POWER_SETTING;
- - }
- - s_ctrl->sensordata->sensor_info->session_id = session_id;
- -
- - /* Create /dev/v4l-subdevX device */
- - v4l2_subdev_init(&s_ctrl->msm_sd.sd, s_ctrl->sensor_v4l2_subdev_ops);
- - snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s",
- - s_ctrl->sensordata->sensor_name);
- - v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
- - s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- - media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0);
- - s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- - s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR;
- - s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name;
- - s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3;
- - msm_sd_register(&s_ctrl->msm_sd);
- -
- - memcpy(slave_info->subdev_name, s_ctrl->msm_sd.sd.entity.name,
- - sizeof(slave_info->subdev_name));
- - slave_info->is_probe_succeed = 1;
- -
- - slave_info->sensor_info.session_id =
- - s_ctrl->sensordata->sensor_info->session_id;
- - for (i = 0; i < SUB_MODULE_MAX; i++)
- - slave_info->sensor_info.subdev_id[i] =
- - s_ctrl->sensordata->sensor_info->subdev_id[i];
- - slave_info->sensor_info.is_mount_angle_valid =
- - s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
- - slave_info->sensor_info.sensor_mount_angle =
- - s_ctrl->sensordata->sensor_info->sensor_mount_angle;
- - CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
- - slave_info->sensor_info.sensor_name);
- - CDBG("%s:%d session id %d\n", __func__, __LINE__,
- - slave_info->sensor_info.session_id);
- - for (i = 0; i < SUB_MODULE_MAX; i++)
- - CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
- - slave_info->sensor_info.subdev_id[i]);
- - CDBG("%s:%d mount angle valid %d value %d\n", __func__,
- - __LINE__, slave_info->sensor_info.is_mount_angle_valid,
- - slave_info->sensor_info.sensor_mount_angle);
- -
- - if (copy_to_user((void __user *)setting,
- - (void *)slave_info, sizeof(*slave_info))) {
- - pr_err("%s:%d copy failed\n", __func__, __LINE__);
- - rc = -EFAULT;
- - }
- -
- - pr_warn("rc %d session_id %d", rc, session_id);
- - pr_warn("%s probe succeeded", slave_info->sensor_name);
- -
- - /* remove this code for DFMS test */
- -#if 0
- - /* Power down */
- - s_ctrl->func_tbl->sensor_power_down(
- - s_ctrl,
- - &s_ctrl->sensordata->power_info,
- - s_ctrl->sensor_device_type,
- - s_ctrl->sensor_i2c_client);
- -#endif
- + /* Validate input parameters */
- + if (!setting) {
- + pr_err("failed: slave_info %p", setting);
- + return -EINVAL;
- + }
- +
- + /* Allocate memory for slave info */
- + slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
- + if (!slave_info) {
- + pr_err("failed: no memory slave_info %p", slave_info);
- + return -ENOMEM;
- + }
- +
- + if (copy_from_user(slave_info, (void *)setting, sizeof(*slave_info))) {
- + pr_err("failed: copy_from_user");
- + rc = -EFAULT;
- + goto FREE_SLAVE_INFO;
- + }
- +
- + /* Print slave info */
- + CDBG("camera id %d", slave_info->camera_id);
- + CDBG("slave_addr %x", slave_info->slave_addr);
- + CDBG("addr_type %d", slave_info->addr_type);
- + CDBG("sensor_id_reg_addr %x",
- + slave_info->sensor_id_info.sensor_id_reg_addr);
- + CDBG("sensor_id %x", slave_info->sensor_id_info.sensor_id);
- + CDBG("size %d", slave_info->power_setting_array.size);
- + CDBG("size down %d", slave_info->power_setting_array.size_down);
- +
- + if (slave_info->is_init_params_valid) {
- + CDBG("position %d",
- + slave_info->sensor_init_params.position);
- + CDBG("mount %d",
- + slave_info->sensor_init_params.sensor_mount_angle);
- + }
- +
- + /* Validate camera id */
- + if (slave_info->camera_id >= MAX_CAMERAS) {
- + pr_err("failed: invalid camera id %d max %d",
- + slave_info->camera_id, MAX_CAMERAS);
- + rc = -EINVAL;
- + goto FREE_POWER_SETTING;
- + }
- +
- + /* Extract s_ctrl from camera id */
- + s_ctrl = g_sctrl[slave_info->camera_id];
- + if (!s_ctrl) {
- + pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
- + slave_info->camera_id);
- + rc = -EINVAL;
- + goto FREE_POWER_SETTING;
- + }
- +
- + CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);
- +
- + if (s_ctrl->is_probe_succeed == 1) {
- + /*
- + * Different sensor on this camera slot has been connected
- + * and probe already succeeded for that sensor. Ignore this
- + * probe
- + */
- + pr_err("slot %d has some other sensor", slave_info->camera_id);
- + kfree(slave_info);
- + return 0;
- + }
- +
- + size = slave_info->power_setting_array.size;
- + /* Validate size */
- + if (size > MAX_POWER_CONFIG) {
- + pr_err("failed: invalid number of power_up_setting %d\n", size);
- + rc = -EINVAL;
- + goto FREE_SLAVE_INFO;
- + }
- +
- + /* Allocate memory for power up setting */
- + power_setting = kzalloc(sizeof(*power_setting) * size, GFP_KERNEL);
- + if (!power_setting) {
- + pr_err("failed: no memory power_setting %p", power_setting);
- + rc = -ENOMEM;
- + goto FREE_SLAVE_INFO;
- + }
- +
- + if (copy_from_user(power_setting,
- + (void *)slave_info->power_setting_array.power_setting,
- + sizeof(*power_setting) * size)) {
- + pr_err("failed: copy_from_user");
- + rc = -EFAULT;
- + goto FREE_POWER_SETTING;
- + }
- +
- + /* Print power setting */
- + for (i = 0; i < size; i++) {
- + CDBG("UP seq_type %d seq_val %d config_val %ld delay %d",
- + power_setting[i].seq_type, power_setting[i].seq_val,
- + power_setting[i].config_val, power_setting[i].delay);
- + }
- + /*DOWN*/
- + size_down = slave_info->power_setting_array.size_down;
- + if (!size_down)
- + size_down = size;
- + /* Validate size_down */
- + if (size_down > MAX_POWER_CONFIG) {
- + pr_err("failed: invalid size_down %d", size_down);
- + rc = -EINVAL;
- + goto FREE_POWER_SETTING;
- + }
- + /* Allocate memory for power down setting */
- + power_down_setting =
- + kzalloc(sizeof(*power_setting) * size_down, GFP_KERNEL);
- + if (!power_down_setting) {
- + pr_err("failed: no memory power_setting %p",
- + power_down_setting);
- + rc = -ENOMEM;
- + goto FREE_POWER_SETTING;
- + }
- +
- + if (slave_info->power_setting_array.power_down_setting) {
- + if (copy_from_user(power_down_setting,
- + (void *)slave_info->power_setting_array.
- + power_down_setting,
- + sizeof(*power_down_setting) * size_down)) {
- + pr_err("failed: copy_from_user");
- + rc = -EFAULT;
- + goto FREE_POWER_DOWN_SETTING;
- + }
- + } else {
- + pr_err("failed: no power_down_setting");
- + if (copy_from_user(power_down_setting,
- + (void *)slave_info->power_setting_array.
- + power_setting,
- + sizeof(*power_down_setting) * size_down)) {
- + pr_err("failed: copy_from_user");
- + rc = -EFAULT;
- + goto FREE_POWER_DOWN_SETTING;
- + }
- +
- + /*reverce*/
- + end = size_down - 1;
- + for (c = 0; c < size_down/2; c++) {
- + power_down_setting_t = power_down_setting[c];
- + power_down_setting[c] = power_down_setting[end];
- + power_down_setting[end] = power_down_setting_t;
- + end--;
- + }
- +
- + }
- +
- + /* Print power setting */
- + for (i = 0; i < size_down; i++) {
- + CDBG("DOWN seq_type %d seq_val %d config_val %ld delay %d",
- + power_down_setting[i].seq_type,
- + power_down_setting[i].seq_val,
- + power_down_setting[i].config_val,
- + power_down_setting[i].delay);
- + }
- +
- + camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
- + if (!camera_info) {
- + pr_err("failed: no memory slave_info %p", camera_info);
- + goto FREE_POWER_DOWN_SETTING;
- +
- + }
- +
- + /* Fill power up setting and power up setting size */
- + power_info = &s_ctrl->sensordata->power_info;
- + power_info->power_setting = power_setting;
- + power_info->power_setting_size = size;
- + power_info->power_down_setting = power_down_setting;
- + power_info->power_down_setting_size = size_down;
- +
- + s_ctrl->sensordata->slave_info = camera_info;
- +
- + /* Fill sensor slave info */
- + camera_info->sensor_slave_addr = slave_info->slave_addr;
- + camera_info->sensor_id_reg_addr =
- + slave_info->sensor_id_info.sensor_id_reg_addr;
- + camera_info->sensor_id = slave_info->sensor_id_info.sensor_id;
- +
- + /* Fill CCI master, slave address and CCI default params */
- + if (!s_ctrl->sensor_i2c_client) {
- + pr_err("failed: sensor_i2c_client %p",
- + s_ctrl->sensor_i2c_client);
- + rc = -EINVAL;
- + goto FREE_CAMERA_INFO;
- + }
- + /* Fill sensor address type */
- + s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
- + if (s_ctrl->sensor_i2c_client->client)
- + s_ctrl->sensor_i2c_client->client->addr =
- + camera_info->sensor_slave_addr;
- +
- + cci_client = s_ctrl->sensor_i2c_client->cci_client;
- + if (!cci_client) {
- + pr_err("failed: cci_client %p", cci_client);
- + goto FREE_CAMERA_INFO;
- + }
- + cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
- + cci_client->sid = slave_info->slave_addr >> 1;
- + cci_client->retries = 3;
- + cci_client->id_map = 0;
- +
- + /* Parse and fill vreg params for powerup settings */
- + rc = msm_camera_fill_vreg_params(
- + power_info->cam_vreg,
- + power_info->num_vreg,
- + power_info->power_setting,
- + power_info->power_setting_size);
- + if (rc < 0) {
- + pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
- + rc);
- + goto FREE_CAMERA_INFO;
- + }
- +
- + /* Parse and fill vreg params for powerdown settings*/
- + rc = msm_camera_fill_vreg_params(
- + power_info->cam_vreg,
- + power_info->num_vreg,
- + power_info->power_down_setting,
- + power_info->power_down_setting_size);
- + if (rc < 0) {
- + pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
- + rc);
- + goto FREE_CAMERA_INFO;
- + }
- +
- + /*
- + * Update sensor, actuator and eeprom name in
- + * sensor control structure.
- + */
- + s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
- + s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
- + s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
- +
- + /*
- + * Update eeporm subdevice Id by input eeprom name
- + */
- + rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
- + if (rc < 0) {
- + pr_err("%s failed %d\n", __func__, __LINE__);
- + goto FREE_POWER_SETTING;
- + }
- + /*
- + * Update actuator subdevice Id by input actuator name
- + */
- + rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
- + if (rc < 0) {
- + pr_err("%s failed %d\n", __func__, __LINE__);
- + goto FREE_POWER_SETTING;
- + }
- +
- + /* Power up and probe sensor */
- + rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
- + if (rc < 0) {
- + pr_err("%s power up failed", slave_info->sensor_name);
- + goto FREE_CAMERA_INFO;
- + }
- +
- + pr_err("%s probe succeeded", slave_info->sensor_name);
- +
- + /*
- + Set probe succeeded flag to 1 so that no other camera shall
- + * probed on this slot
- + */
- + s_ctrl->is_probe_succeed = 1;
- +
- + /*
- + * Create /dev/videoX node, comment for now until dummy /dev/videoX
- + * node is created and used by HAL
- + */
- +
- + if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
- + rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
- + else
- + rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
- + if (rc < 0) {
- + pr_err("failed: camera creat v4l2 rc %d", rc);
- + goto CAMERA_POWER_DOWN;
- + }
- +
- + /* Power down */
- + s_ctrl->func_tbl->sensor_power_down(s_ctrl);
- +
- + rc = msm_sensor_fill_slave_info_init_params(
- + slave_info,
- + s_ctrl->sensordata->sensor_info);
- + if (rc < 0) {
- + pr_err("%s Fill slave info failed", slave_info->sensor_name);
- + goto FREE_CAMERA_INFO;
- + }
- + rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
- + if (rc < 0) {
- + pr_err("%s Validate slave info failed",
- + slave_info->sensor_name);
- + goto FREE_CAMERA_INFO;
- + }
- + /* Update sensor mount angle and position in media entity flag */
- + mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
- + mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
- + sensor_mount_angle / 90) << 8);
- + s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;
- - return rc;
- + /*Save sensor info*/
- + s_ctrl->sensordata->cam_slave_info = slave_info;
- -FREE_POWER_OFF_SETTING:
- - kfree(power_off_setting);
- + return rc;
- +
- +CAMERA_POWER_DOWN:
- + s_ctrl->func_tbl->sensor_power_down(s_ctrl);
- +FREE_CAMERA_INFO:
- + kfree(camera_info);
- +FREE_POWER_DOWN_SETTING:
- + kfree(power_down_setting);
- FREE_POWER_SETTING:
- - kfree(power_setting);
- + kfree(power_setting);
- FREE_SLAVE_INFO:
- - kfree(slave_info);
- - return rc;
- + kfree(slave_info);
- + return rc;
- }
- static int32_t msm_sensor_driver_get_gpio_data(
- @@ -431,12 +713,12 @@ FREE_GPIO_CONF:
- return rc;
- }
- -static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
- - struct platform_device *pdev)
- +static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl)
- {
- int32_t rc = 0;
- struct msm_camera_sensor_board_info *sensordata = NULL;
- - struct device_node *of_node = pdev->dev.of_node;
- + struct device_node *of_node = s_ctrl->of_node;
- + uint32_t cell_id;
- s_ctrl->sensordata = kzalloc(sizeof(*sensordata), GFP_KERNEL);
- if (!s_ctrl->sensordata) {
- @@ -446,27 +728,27 @@ static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
- sensordata = s_ctrl->sensordata;
- -
- /*
- * Read cell index - this cell index will be the camera slot where
- * this camera will be mounted
- */
- - rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
- + rc = of_property_read_u32(of_node, "cell-index", &cell_id);
- if (rc < 0) {
- pr_err("failed: cell-index rc %d", rc);
- goto FREE_SENSOR_DATA;
- }
- + s_ctrl->id = cell_id;
- - /* Validate pdev->id */
- - if (pdev->id >= MAX_CAMERAS) {
- - pr_err("failed: invalid pdev->id %d", pdev->id);
- + /* Validate cell_id */
- + if (cell_id >= MAX_CAMERAS) {
- + pr_err("failed: invalid cell_id %d", cell_id);
- rc = -EINVAL;
- goto FREE_SENSOR_DATA;
- }
- - /* Check whether g_sctrl is already filled for this pdev id */
- - if (g_sctrl[pdev->id]) {
- - pr_err("failed: sctrl already filled for id %d", pdev->id);
- + /* Check whether g_sctrl is already filled for this cell_id */
- + if (g_sctrl[cell_id]) {
- + pr_err("failed: sctrl already filled for cell_id %d", cell_id);
- rc = -EINVAL;
- goto FREE_SENSOR_DATA;
- }
- @@ -505,11 +787,13 @@ static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
- }
- /* Get mount angle */
- +
- rc = of_property_read_u32(of_node, "qcom,mount-angle",
- &sensordata->sensor_info->sensor_mount_angle);
- CDBG("%s qcom,mount-angle %d, rc %d\n", __func__,
- sensordata->sensor_info->sensor_mount_angle, rc);
- if (rc < 0) {
- + /* Invalidate mount angle flag */
- sensordata->sensor_info->is_mount_angle_valid = 0;
- sensordata->sensor_info->sensor_mount_angle = 0;
- rc = 0;
- @@ -517,6 +801,22 @@ static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl,
- sensordata->sensor_info->is_mount_angle_valid = 1;
- }
- + rc = of_property_read_u32(of_node, "qcom,sensor-position",
- + &sensordata->sensor_info->position);
- + if (rc < 0) {
- + pr_err("%s:%d Invalid sensor position\n", __func__, __LINE__);
- + sensordata->sensor_info->position = INVALID_CAMERA_B;
- + }
- +
- + rc = of_property_read_u32(of_node, "qcom,sensor-mode",
- + &sensordata->sensor_info->modes_supported);
- + if (rc < 0) {
- + pr_err("%s:%d Invalid sensor mode supported\n",
- + __func__, __LINE__);
- + sensordata->sensor_info->modes_supported = CAMERA_MODE_INVALID;
- + rc = 0;
- + }
- +
- /* Get vdd-cx regulator */
- /*Optional property, don't return error if absent */
- of_property_read_string(of_node, "qcom,vdd-cx-name",
- @@ -534,27 +834,13 @@ FREE_SENSOR_DATA:
- return rc;
- }
- -static int32_t msm_sensor_driver_parse(struct platform_device *pdev)
- +static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl)
- {
- int32_t rc = 0;
- - struct msm_sensor_ctrl_t *s_ctrl = NULL;
- CDBG("Enter");
- /* Validate input parameters */
- - if (!pdev || !pdev->dev.of_node) {
- - pr_err("failed: invalid params");
- - return -EINVAL;
- - }
- - /* Create sensor control structure */
- - s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- - if (!s_ctrl) {
- - pr_err("failed: no memory s_ctrl %p", s_ctrl);
- - return -ENOMEM;
- - }
- -
- - /* Fill platform device */
- - s_ctrl->pdev = pdev;
- /* Allocate memory for sensor_i2c_client */
- s_ctrl->sensor_i2c_client = kzalloc(sizeof(*s_ctrl->sensor_i2c_client),
- @@ -562,7 +848,7 @@ static int32_t msm_sensor_driver_parse(struct platform_device *pdev)
- if (!s_ctrl->sensor_i2c_client) {
- pr_err("failed: no memory sensor_i2c_client %p",
- s_ctrl->sensor_i2c_client);
- - goto FREE_SCTRL;
- + return -ENOMEM;
- }
- /* Allocate memory for mutex */
- @@ -575,15 +861,12 @@ static int32_t msm_sensor_driver_parse(struct platform_device *pdev)
- }
- /* Parse dt information and store in sensor control structure */
- - rc = msm_sensor_driver_get_dt_data(s_ctrl, pdev);
- + rc = msm_sensor_driver_get_dt_data(s_ctrl);
- if (rc < 0) {
- pr_err("failed: rc %d", rc);
- goto FREE_MUTEX;
- }
- - /* Fill device in power info */
- - s_ctrl->sensordata->power_info.dev = &pdev->dev;
- -
- /* Initialize mutex */
- mutex_init(s_ctrl->msm_sensor_mutex);
- @@ -600,8 +883,8 @@ static int32_t msm_sensor_driver_parse(struct platform_device *pdev)
- }
- /* Store sensor control structure in static database */
- - g_sctrl[pdev->id] = s_ctrl;
- - pr_warn("g_sctrl[%d] %p", pdev->id, g_sctrl[pdev->id]);
- + g_sctrl[s_ctrl->id] = s_ctrl;
- + pr_err("g_sctrl[%d] %p", s_ctrl->id, g_sctrl[s_ctrl->id]);
- return rc;
- @@ -615,20 +898,141 @@ FREE_MUTEX:
- kfree(s_ctrl->msm_sensor_mutex);
- FREE_SENSOR_I2C_CLIENT:
- kfree(s_ctrl->sensor_i2c_client);
- -FREE_SCTRL:
- + return rc;
- +}
- +
- +static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev)
- +{
- + int32_t rc = 0;
- + struct msm_sensor_ctrl_t *s_ctrl = NULL;
- +
- +
- + /* Create sensor control structure */
- + s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- + if (!s_ctrl) {
- + pr_err("failed: no memory s_ctrl %p", s_ctrl);
- + return -ENOMEM;
- + }
- +
- + platform_set_drvdata(pdev, s_ctrl);
- +
- + /* Initialize sensor device type */
- + s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
- + s_ctrl->of_node = pdev->dev.of_node;
- +
- + rc = msm_sensor_driver_parse(s_ctrl);
- + if (rc < 0) {
- + pr_err("failed: msm_sensor_driver_parse rc %d", rc);
- + goto FREE_S_CTRL;
- + }
- +
- + /* Fill platform device */
- + pdev->id = s_ctrl->id;
- + s_ctrl->pdev = pdev;
- +
- + /* Fill device in power info */
- + s_ctrl->sensordata->power_info.dev = &pdev->dev;
- +
- + return rc;
- +FREE_S_CTRL:
- kfree(s_ctrl);
- return rc;
- }
- +static int32_t msm_sensor_driver_i2c_probe(struct i2c_client *client,
- + const struct i2c_device_id *id)
- +{
- + int32_t rc = 0;
- + struct msm_sensor_ctrl_t *s_ctrl;
- +
- + CDBG("\n\nEnter: msm_sensor_driver_i2c_probe");
- + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- + pr_err("%s %s i2c_check_functionality failed\n",
- + __func__, client->name);
- + rc = -EFAULT;
- + return rc;
- + }
- +
- + /* Create sensor control structure */
- + s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
- + if (!s_ctrl) {
- + pr_err("failed: no memory s_ctrl %p", s_ctrl);
- + return -ENOMEM;
- + }
- +
- + i2c_set_clientdata(client, s_ctrl);
- +
- + /* Initialize sensor device type */
- + s_ctrl->sensor_device_type = MSM_CAMERA_I2C_DEVICE;
- + s_ctrl->of_node = client->dev.of_node;
- +
- + rc = msm_sensor_driver_parse(s_ctrl);
- + if (rc < 0) {
- + pr_err("failed: msm_sensor_driver_parse rc %d", rc);
- + goto FREE_S_CTRL;
- + }
- +
- + if (s_ctrl->sensor_i2c_client != NULL) {
- + s_ctrl->sensor_i2c_client->client = client;
- + s_ctrl->sensordata->power_info.dev = &client->dev;
- +
- + }
- +
- + return rc;
- +FREE_S_CTRL:
- + kfree(s_ctrl);
- + return rc;
- +}
- +
- +static int msm_sensor_driver_i2c_remove(struct i2c_client *client)
- +{
- + struct msm_sensor_ctrl_t *s_ctrl = i2c_get_clientdata(client);
- +
- + pr_err("%s: sensor FREE\n", __func__);
- +
- + if (!s_ctrl) {
- + pr_err("%s: sensor device is NULL\n", __func__);
- + return 0;
- + }
- +
- + g_sctrl[s_ctrl->id] = NULL;
- + msm_sensor_free_sensor_data(s_ctrl);
- + kfree(s_ctrl->msm_sensor_mutex);
- + kfree(s_ctrl->sensor_i2c_client);
- + kfree(s_ctrl);
- +
- + return 0;
- +}
- +
- +static const struct i2c_device_id i2c_id[] = {
- + {SENSOR_DRIVER_I2C, (kernel_ulong_t)NULL},
- + { }
- +};
- +
- +static struct i2c_driver msm_sensor_driver_i2c = {
- + .id_table = i2c_id,
- + .probe = msm_sensor_driver_i2c_probe,
- + .remove = msm_sensor_driver_i2c_remove,
- + .driver = {
- + .name = SENSOR_DRIVER_I2C,
- + },
- +};
- +
- static int __init msm_sensor_driver_init(void)
- {
- int32_t rc = 0;
- - pr_warn("%s : Enter", __func__);
- + CDBG("Enter");
- rc = platform_driver_probe(&msm_sensor_platform_driver,
- - msm_sensor_driver_parse);
- - if (!rc)
- - pr_warn("probe success");
- + msm_sensor_driver_platform_probe);
- + if (!rc) {
- + CDBG("probe success");
- + return rc;
- + } else {
- + CDBG("probe i2c");
- + rc = i2c_add_driver(&msm_sensor_driver_i2c);
- + }
- +
- return rc;
- }
- @@ -636,6 +1040,8 @@ static int __init msm_sensor_driver_init(void)
- static void __exit msm_sensor_driver_exit(void)
- {
- CDBG("Enter");
- + platform_driver_unregister(&msm_sensor_platform_driver);
- + i2c_del_driver(&msm_sensor_driver_i2c);
- return;
- }
- diff --git a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
- index 02ff7a2..367bdbe 100644
- --- a/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
- +++ b/drivers/media/platform/msm/camera_v2/sensor/mt9m114.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2011-2015, 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
- @@ -19,7 +19,7 @@
- /*#define CONFIG_MSMB_CAMERA_DEBUG*/
- #undef CDBG
- -#ifdef MT9M114_DEBUG
- +#ifdef CONFIG_MSMB_CAMERA_DEBUG
- #define CDBG(fmt, args...) pr_err(fmt, ##args)
- #else
- #define CDBG(fmt, args...) do { } while (0)
- @@ -36,6 +36,50 @@
- DEFINE_MSM_MUTEX(mt9m114_mut);
- static struct msm_sensor_ctrl_t mt9m114_s_ctrl;
- +static struct msm_sensor_power_setting mt9m114_power_setting[] = {
- + {
- + .seq_type = SENSOR_VREG,
- + .seq_val = CAM_VIO,
- + .config_val = 0,
- + .delay = 0,
- + },
- + {
- + .seq_type = SENSOR_VREG,
- + .seq_val = CAM_VDIG,
- + .config_val = 0,
- + .delay = 0,
- + },
- + {
- + .seq_type = SENSOR_VREG,
- + .seq_val = CAM_VANA,
- + .config_val = 0,
- + .delay = 0,
- + },
- + {
- + .seq_type = SENSOR_GPIO,
- + .seq_val = SENSOR_GPIO_RESET,
- + .config_val = GPIO_OUT_LOW,
- + .delay = 1,
- + },
- + {
- + .seq_type = SENSOR_GPIO,
- + .seq_val = SENSOR_GPIO_RESET,
- + .config_val = GPIO_OUT_HIGH,
- + .delay = 30,
- + },
- + {
- + .seq_type = SENSOR_CLK,
- + .seq_val = SENSOR_CAM_MCLK,
- + .config_val = 0,
- + .delay = 100,
- + },
- + {
- + .seq_type = SENSOR_I2C_MUX,
- + .seq_val = 0,
- + .config_val = 0,
- + .delay = 0,
- + },
- +};
- static struct msm_camera_i2c_reg_conf mt9m114_720p_settings[] = {
- {0xdc00, 0x50, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
- @@ -1068,6 +1112,7 @@ static int32_t msm_mt9m114_i2c_probe(struct i2c_client *client,
- {
- return msm_sensor_i2c_probe(client, id, &mt9m114_s_ctrl);
- }
- +
- static struct i2c_driver mt9m114_i2c_driver = {
- .id_table = mt9m114_i2c_id,
- .probe = msm_mt9m114_i2c_probe,
- @@ -1107,14 +1152,12 @@ static int32_t mt9m114_platform_probe(struct platform_device *pdev)
- static int __init mt9m114_init_module(void)
- {
- int32_t rc;
- - CDBG("%s:%d\n", __func__, __LINE__);
- + pr_info("%s:%d\n", __func__, __LINE__);
- rc = platform_driver_probe(&mt9m114_platform_driver,
- mt9m114_platform_probe);
- - if (!rc) {
- - pr_info("%s: probe success\n", __func__);
- + if (!rc)
- return rc;
- - }
- - CDBG("%s:%d rc %d\n", __func__, __LINE__, rc);
- + pr_err("%s:%d rc %d\n", __func__, __LINE__, rc);
- return i2c_add_driver(&mt9m114_i2c_driver);
- }
- @@ -1148,6 +1191,10 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- for (i = 0; i < SUB_MODULE_MAX; i++)
- cdata->cfg.sensor_info.subdev_id[i] =
- s_ctrl->sensordata->sensor_info->subdev_id[i];
- + cdata->cfg.sensor_info.is_mount_angle_valid =
- + s_ctrl->sensordata->sensor_info->is_mount_angle_valid;
- + cdata->cfg.sensor_info.sensor_mount_angle =
- + s_ctrl->sensordata->sensor_info->sensor_mount_angle;
- CDBG("%s:%d sensor name %s\n", __func__, __LINE__,
- cdata->cfg.sensor_info.sensor_name);
- CDBG("%s:%d session id %d\n", __func__, __LINE__,
- @@ -1155,6 +1202,9 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- for (i = 0; i < SUB_MODULE_MAX; i++)
- CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
- cdata->cfg.sensor_info.subdev_id[i]);
- + CDBG("%s:%d mount angle valid %d value %d\n", __func__,
- + __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid,
- + cdata->cfg.sensor_info.sensor_mount_angle);
- break;
- case CFG_SET_INIT_SETTING:
- @@ -1190,8 +1240,12 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- MSM_CAMERA_I2C_WORD_DATA);
- break;
- case CFG_GET_SENSOR_INIT_PARAMS:
- - cdata->cfg.sensor_init_params =
- - *s_ctrl->sensordata->sensor_init_params;
- + cdata->cfg.sensor_init_params.modes_supported =
- + s_ctrl->sensordata->sensor_info->modes_supported;
- + cdata->cfg.sensor_init_params.position =
- + s_ctrl->sensordata->sensor_info->position;
- + cdata->cfg.sensor_init_params.sensor_mount_angle =
- + s_ctrl->sensordata->sensor_info->sensor_mount_angle;
- CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__,
- __LINE__,
- cdata->cfg.sensor_init_params.modes_supported,
- @@ -1204,8 +1258,8 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t size;
- int slave_index = 0;
- if (copy_from_user(&sensor_slave_info,
- - (void *)cdata->cfg.setting,
- - sizeof(struct msm_camera_sensor_slave_info))) {
- + (void *)cdata->cfg.setting,
- + sizeof(struct msm_camera_sensor_slave_info))) {
- pr_err("%s:%d failed\n", __func__, __LINE__);
- rc = -EFAULT;
- break;
- @@ -1229,13 +1283,14 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- * size, GFP_KERNEL);
- if (!tmp) {
- pr_err("%s: failed to alloc mem\n", __func__);
- - rc = -ENOMEM;
- - break;
- + rc = -ENOMEM;
- + break;
- }
- kfree(p_ctrl->power_setting);
- p_ctrl->power_setting = tmp;
- }
- p_ctrl->power_setting_size = size;
- +
- rc = copy_from_user(p_ctrl->power_setting, (void *)
- sensor_slave_info.power_setting_array.power_setting,
- size * sizeof(struct msm_sensor_power_setting));
- @@ -1275,6 +1330,14 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- break;
- }
- + if (!conf_array.size ||
- + conf_array.size > I2C_SEQ_REG_DATA_MAX) {
- +
- + pr_err("%s:%d failed\n", __func__, __LINE__);
- + rc = -EFAULT;
- + break;
- + }
- +
- reg_setting = kzalloc(conf_array.size *
- (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
- if (!reg_setting) {
- @@ -1336,22 +1399,14 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- case CFG_POWER_UP:
- if (s_ctrl->func_tbl->sensor_power_up)
- - rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl,
- - &s_ctrl->sensordata->power_info,
- - s_ctrl->sensor_i2c_client,
- - s_ctrl->sensordata->slave_info,
- - s_ctrl->sensordata->sensor_name);
- + rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
- else
- rc = -EFAULT;
- break;
- case CFG_POWER_DOWN:
- if (s_ctrl->func_tbl->sensor_power_down)
- - rc = s_ctrl->func_tbl->sensor_power_down(
- - s_ctrl,
- - &s_ctrl->sensordata->power_info,
- - s_ctrl->sensor_device_type,
- - s_ctrl->sensor_i2c_client);
- + rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
- else
- rc = -EFAULT;
- break;
- @@ -1386,8 +1441,51 @@ int32_t mt9m114_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
- break;
- }
- break;
- - }
- - default:
- + }
- + case CFG_SET_SATURATION: {
- + int32_t sat_lev;
- + if (copy_from_user(&sat_lev, (void *)cdata->cfg.setting,
- + sizeof(int32_t))) {
- + pr_err("%s:%d failed\n", __func__, __LINE__);
- + rc = -EFAULT;
- + break;
- + }
- + pr_debug("%s: Saturation Value is %d", __func__, sat_lev);
- + break;
- + }
- + case CFG_SET_CONTRAST: {
- + int32_t con_lev;
- + if (copy_from_user(&con_lev, (void *)cdata->cfg.setting,
- + sizeof(int32_t))) {
- + pr_err("%s:%d failed\n", __func__, __LINE__);
- + rc = -EFAULT;
- + break;
- + }
- + pr_debug("%s: Contrast Value is %d", __func__, con_lev);
- + break;
- + }
- + case CFG_SET_SHARPNESS: {
- + int32_t shp_lev;
- + if (copy_from_user(&shp_lev, (void *)cdata->cfg.setting,
- + sizeof(int32_t))) {
- + pr_err("%s:%d failed\n", __func__, __LINE__);
- + rc = -EFAULT;
- + break;
- + }
- + pr_debug("%s: Sharpness Value is %d", __func__, shp_lev);
- + break;
- + }
- + case CFG_SET_AUTOFOCUS: {
- + /* TO-DO: set the Auto Focus */
- + pr_debug("%s: Setting Auto Focus", __func__);
- + break;
- + }
- + case CFG_CANCEL_AUTOFOCUS: {
- + /* TO-DO: Cancel the Auto Focus */
- + pr_debug("%s: Cancelling Auto Focus", __func__);
- + break;
- + }
- + default:
- rc = -EFAULT;
- break;
- }
- @@ -1406,6 +1504,8 @@ static struct msm_sensor_fn_t mt9m114_sensor_func_tbl = {
- static struct msm_sensor_ctrl_t mt9m114_s_ctrl = {
- .sensor_i2c_client = &mt9m114_sensor_i2c_client,
- + .power_setting_array.power_setting = mt9m114_power_setting,
- + .power_setting_array.size = ARRAY_SIZE(mt9m114_power_setting),
- .msm_sensor_mutex = &mt9m114_mut,
- .sensor_v4l2_subdev_info = mt9m114_subdev_info,
- .sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9m114_subdev_info),
- diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
- index 258009c..c0b3531 100644
- --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
- +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
- @@ -35,7 +35,7 @@
- V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE
- #define NUM_MBS_PER_SEC(__height, __width, __fps) ({\
- - (__height / 16) * (__width / 16) * __fps; \
- + (__height >> 4) * (__width >> 4) * __fps; \
- })
- #define VIDC_BUS_LOAD(__height, __width, __fps, __br) ({\
- @@ -50,9 +50,30 @@ static void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
- static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
- static void handle_session_error(enum command_response cmd, void *data);
- -static inline bool is_turbo_session(struct msm_vidc_inst *inst)
- +static bool is_turbo_requested(struct msm_vidc_core *core,
- + enum session_type type)
- {
- - return !!(inst->flags & VIDC_TURBO);
- + struct msm_vidc_inst *inst = NULL;
- + bool wants_turbo = false;
- +
- + mutex_lock(&core->lock);
- + list_for_each_entry(inst, &core->instances, list) {
- +
- + mutex_lock(&inst->lock);
- + if (inst->session_type == type &&
- + inst->state >= MSM_VIDC_OPEN_DONE &&
- + inst->state < MSM_VIDC_STOP_DONE) {
- + wants_turbo = inst->flags & VIDC_TURBO;
- + }
- + mutex_unlock(&inst->lock);
- +
- + if (wants_turbo)
- + break;
- + }
- +
- + mutex_unlock(&core->lock);
- +
- + return wants_turbo;
- }
- static bool is_thumbnail_session(struct msm_vidc_inst *inst)
- @@ -68,17 +89,6 @@ static bool is_thumbnail_session(struct msm_vidc_inst *inst)
- }
- return false;
- }
- -
- -static inline bool is_non_realtime_session(struct msm_vidc_inst *inst)
- -{
- - int rc = 0;
- - struct v4l2_control ctrl = {
- - .id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY
- - };
- - rc = v4l2_g_ctrl(&inst->ctrl_handler, &ctrl);
- - return (!rc && ctrl.value);
- -}
- -
- enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
- {
- if (inst->session_type == MSM_VIDC_DECODER) {
- @@ -97,57 +107,15 @@ enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
- static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
- {
- int height, width;
- - int fps, rc;
- - struct v4l2_control ctrl;
- height = max(inst->prop.height[CAPTURE_PORT],
- inst->prop.height[OUTPUT_PORT]);
- width = max(inst->prop.width[CAPTURE_PORT],
- inst->prop.width[OUTPUT_PORT]);
- - ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
- - rc = v4l2_g_ctrl(&inst->ctrl_handler, &ctrl);
- - if (!rc && ctrl.value) {
- - fps = (ctrl.value >> 16)? ctrl.value >> 16: 1;
- - return NUM_MBS_PER_SEC(height, width, fps);
- - } else
- - return NUM_MBS_PER_SEC(height, width, inst->prop.fps);
- -}
- -enum load_calc_quirks {
- - LOAD_CALC_NO_QUIRKS = 0,
- - LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0,
- - LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1,
- - LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2,
- -};
- -
- -static int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
- - enum load_calc_quirks quirks)
- -{
- - int load = 0;
- -
- - if (!(inst->state >= MSM_VIDC_OPEN_DONE &&
- - inst->state < MSM_VIDC_STOP_DONE))
- - return 0;
- -
- - load = msm_comm_get_mbs_per_sec(inst);
- -
- - if (is_thumbnail_session(inst)) {
- - if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD)
- - load = 0;
- - }
- -
- - if (is_turbo_session(inst)) {
- - if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD))
- - load = inst->core->resources.max_load;
- - }
- -
- - if (is_non_realtime_session(inst) &&
- - (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD))
- - load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps;
- -
- - return load;
- + return NUM_MBS_PER_SEC(height, width, inst->prop.fps);
- }
- static int msm_comm_get_load(struct msm_vidc_core *core,
- - enum session_type type, enum load_calc_quirks quirks)
- + enum session_type type)
- {
- struct msm_vidc_inst *inst = NULL;
- int num_mbs_per_sec = 0;
- @@ -157,11 +125,14 @@ static int msm_comm_get_load(struct msm_vidc_core *core,
- }
- mutex_lock(&core->lock);
- list_for_each_entry(inst, &core->instances, list) {
- - if (inst->session_type != type)
- - continue;
- -
- mutex_lock(&inst->lock);
- - num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks);
- + if (inst->session_type == type &&
- + inst->state >= MSM_VIDC_OPEN_DONE &&
- + inst->state < MSM_VIDC_STOP_DONE) {
- + if (!is_thumbnail_session(inst))
- + num_mbs_per_sec +=
- + msm_comm_get_mbs_per_sec(inst);
- + }
- mutex_unlock(&inst->lock);
- }
- mutex_unlock(&core->lock);
- @@ -186,7 +157,10 @@ static int msm_comm_scale_bus(struct msm_vidc_core *core,
- return -EINVAL;
- }
- - load = msm_comm_get_load(core, type, LOAD_CALC_NO_QUIRKS);
- + if (is_turbo_requested(core, type))
- + load = core->resources.max_load;
- + else
- + load = msm_comm_get_load(core, type);
- rc = call_hfi_op(hdev, scale_bus, hdev->hfi_device_data,
- load, type, mtype);
- @@ -649,11 +623,7 @@ static void handle_event_change(enum command_response cmd, void *data)
- rc = msm_vidc_check_session_supported(inst);
- if (!rc) {
- msm_vidc_queue_v4l2_event(inst, event);
- - } else if (rc) {
- - msm_vidc_queue_v4l2_event(inst,
- - V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
- }
- - wake_up(&inst->kernel_event_queue);
- return;
- } else {
- @@ -1544,7 +1514,6 @@ static int msm_comm_scale_clocks(struct msm_vidc_core *core)
- int num_mbs_per_sec;
- int rc = 0;
- struct hfi_device *hdev;
- -
- if (!core) {
- dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core);
- return -EINVAL;
- @@ -1557,10 +1526,13 @@ static int msm_comm_scale_clocks(struct msm_vidc_core *core)
- return -EINVAL;
- }
- - num_mbs_per_sec =
- - msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS) +
- - msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
- -
- + if (is_turbo_requested(core, MSM_VIDC_ENCODER) ||
- + is_turbo_requested(core, MSM_VIDC_DECODER)) {
- + num_mbs_per_sec = core->resources.max_load;
- + } else {
- + num_mbs_per_sec = msm_comm_get_load(core, MSM_VIDC_ENCODER);
- + num_mbs_per_sec += msm_comm_get_load(core, MSM_VIDC_DECODER);
- + }
- dprintk(VIDC_INFO, "num_mbs_per_sec = %d\n", num_mbs_per_sec);
- rc = call_hfi_op(hdev, scale_clocks,
- @@ -1894,9 +1866,6 @@ static int msm_vidc_load_resources(int flipped_state,
- int rc = 0;
- struct hfi_device *hdev;
- int num_mbs_per_sec = 0;
- - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
- - LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
- - LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
- if (!inst || !inst->core || !inst->core->device) {
- dprintk(VIDC_ERR, "%s invalid parameters", __func__);
- @@ -1915,19 +1884,16 @@ static int msm_vidc_load_resources(int flipped_state,
- return -EINVAL;
- }
- - num_mbs_per_sec =
- - msm_comm_get_load(inst->core, MSM_VIDC_DECODER, quirks) +
- - msm_comm_get_load(inst->core, MSM_VIDC_ENCODER, quirks);
- + num_mbs_per_sec = msm_comm_get_load(inst->core, MSM_VIDC_DECODER);
- + num_mbs_per_sec += msm_comm_get_load(inst->core, MSM_VIDC_ENCODER);
- if (num_mbs_per_sec > inst->core->resources.max_load) {
- dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
- num_mbs_per_sec, inst->core->resources.max_load);
- msm_vidc_print_running_insts(inst->core);
- -#if 0 /* Samsung skips the overloaded error return */
- inst->state = MSM_VIDC_CORE_INVALID;
- msm_comm_kill_session(inst);
- return -EBUSY;
- -#endif
- }
- hdev = inst->core->device;
- @@ -2459,8 +2425,10 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_OPEN_DONE:
- + mutex_unlock(&inst->sync_lock);
- rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
- SESSION_INIT_DONE);
- + mutex_lock(&inst->sync_lock);
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_LOAD_RESOURCES:
- @@ -2473,8 +2441,10 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_START_DONE:
- + mutex_unlock(&inst->sync_lock);
- rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
- SESSION_START_DONE);
- + mutex_lock(&inst->sync_lock);
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_STOP:
- @@ -2482,8 +2452,10 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_STOP_DONE:
- + mutex_unlock(&inst->sync_lock);
- rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
- SESSION_STOP_DONE);
- + mutex_lock(&inst->sync_lock);
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- dprintk(VIDC_DBG, "Moving to Stop Done state\n");
- @@ -2492,9 +2464,11 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_RELEASE_RESOURCES_DONE:
- + mutex_unlock(&inst->sync_lock);
- rc = wait_for_state(inst, flipped_state,
- MSM_VIDC_RELEASE_RESOURCES_DONE,
- SESSION_RELEASE_RESOURCE_DONE);
- + mutex_lock(&inst->sync_lock);
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- dprintk(VIDC_DBG,
- @@ -2504,8 +2478,10 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_CLOSE_DONE:
- + mutex_unlock(&inst->sync_lock);
- rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
- SESSION_END_DONE);
- + mutex_lock(&inst->sync_lock);
- if (rc || state <= get_flipped_state(inst->state, state))
- break;
- case MSM_VIDC_CORE_UNINIT:
- @@ -2595,15 +2571,6 @@ int msm_comm_qbuf(struct vb2_buffer *vb)
- dprintk(VIDC_DBG,
- "Received EOS on output capability\n");
- }
- - /*Start : Qualcomm Local Patch - 20131226 */
- - if (vb->v4l2_buf.flags &
- - V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP) {
- - frame_data.flags |=
- - HAL_BUFFERFLAG_YUV_601_709_CSC_CLAMP;
- - dprintk(VIDC_DBG,
- - "Received buff with 601to709 clamp\n");
- - }
- - /*End : Qualcomm Local Patch - 20131226 */
- if (vb->v4l2_buf.flags &
- V4L2_QCOM_BUF_FLAG_CODECCONFIG) {
- @@ -2704,7 +2671,6 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
- return -EINVAL;
- }
- hdev = inst->core->device;
- - mutex_lock(&inst->sync_lock);
- if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
- dprintk(VIDC_ERR,
- "Not in proper state to query buffer requirements\n");
- @@ -2733,7 +2699,6 @@ int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
- }
- rc = 0;
- exit:
- - mutex_unlock(&inst->sync_lock);
- return rc;
- }
- int msm_comm_release_output_buffers(struct msm_vidc_inst *inst)
- @@ -2947,7 +2912,6 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
- }
- hdev = inst->core->device;
- - mutex_lock(&inst->sync_lock);
- if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
- dprintk(VIDC_ERR, "Not in proper state to set property\n");
- rc = -EAGAIN;
- @@ -2958,7 +2922,6 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
- if (rc)
- dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
- exit:
- - mutex_unlock(&inst->sync_lock);
- return rc;
- }
- @@ -3394,26 +3357,19 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
- static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
- {
- int num_mbs_per_sec = 0;
- - enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
- - LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
- - LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
- if (inst->state == MSM_VIDC_OPEN_DONE) {
- num_mbs_per_sec = msm_comm_get_load(inst->core,
- - MSM_VIDC_DECODER, quirks);
- + MSM_VIDC_DECODER);
- num_mbs_per_sec += msm_comm_get_load(inst->core,
- - MSM_VIDC_ENCODER, quirks);
- + MSM_VIDC_ENCODER);
- if (num_mbs_per_sec > inst->core->resources.max_load) {
- dprintk(VIDC_ERR,
- "H/w is overloaded. needed: %d max: %d\n",
- num_mbs_per_sec,
- inst->core->resources.max_load);
- msm_vidc_print_running_insts(inst->core);
- -/* MMRND_AVRC. Start */
- -#if 0 // Samsung skips the overloaded error return
- return -EINVAL;
- -#endif
- -/* MMRND_AVRC. End */
- }
- }
- return 0;
- @@ -3532,8 +3488,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
- if (rc) {
- change_inst_state(inst, MSM_VIDC_CORE_INVALID);
- msm_comm_kill_session(inst);
- + msm_vidc_queue_v4l2_event(inst,
- + V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
- dprintk(VIDC_WARN,
- "%s: Hardware is overloaded\n", __func__);
- + wake_up(&inst->kernel_event_queue);
- }
- return rc;
- }
- @@ -3729,6 +3688,7 @@ void msm_vidc_fw_unload_handler(struct work_struct *work)
- dprintk(VIDC_ERR,
- "Failed to release core, id = %d\n",
- core->id);
- + mutex_unlock(&core->lock);
- return;
- }
- }
- diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
- index 59fb8f6..2371f3b 100644
- --- a/drivers/media/platform/msm/vidc/venus_hfi.c
- +++ b/drivers/media/platform/msm/vidc/venus_hfi.c
- @@ -1159,6 +1159,8 @@ static inline int venus_hfi_clk_enable(struct venus_hfi_device *device)
- }
- for (i = VCODEC_CLK; i <= device->clk_gating_level; i++) {
- + if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- + continue;
- cl = &device->resources.clock[i];
- rc = clk_enable(cl->clk);
- if (rc) {
- @@ -1175,6 +1177,8 @@ static inline int venus_hfi_clk_enable(struct venus_hfi_device *device)
- return 0;
- fail_clk_enable:
- for (i--; i >= VCODEC_CLK; i--) {
- + if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- + continue;
- cl = &device->resources.clock[i];
- usleep(100);
- clk_disable(cl->clk);
- @@ -1209,15 +1213,17 @@ static inline void venus_hfi_clk_disable(struct venus_hfi_device *device)
- if (rc)
- dprintk(VIDC_WARN, "Failed to set clock rate to min: %d\n", rc);
- + device->clk_state = DISABLED_PREPARED;
- + --device->clk_cnt;
- for (i = VCODEC_CLK; i <= device->clk_gating_level; i++) {
- + if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- + continue;
- cl = &device->resources.clock[i];
- usleep(100);
- clk_disable(cl->clk);
- dprintk(VIDC_DBG, "%s: Clock: %s disabled\n",
- __func__, cl->name);
- }
- - device->clk_state = DISABLED_PREPARED;
- - --device->clk_cnt;
- }
- static int venus_hfi_halt_axi(struct venus_hfi_device *device)
- @@ -1334,13 +1340,6 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device)
- goto err_iommu_attach;
- }
- - /* Reboot the firmware */
- - rc = venus_hfi_tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME);
- - if (rc) {
- - dprintk(VIDC_ERR, "Failed to resume video core %d\n", rc);
- - goto err_set_video_state;
- - }
- -
- /*
- * Re-program all of the registers that get reset as a result of
- * regulator_disable() and _enable()
- @@ -1362,6 +1361,13 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device)
- venus_hfi_write_register(device, VIDC_MMAP_ADDR,
- (u32)device->qdss.align_device_addr, 0);
- + /* Reboot the firmware */
- + rc = venus_hfi_tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME);
- + if (rc) {
- + dprintk(VIDC_ERR, "Failed to resume video core %d\n", rc);
- + goto err_set_video_state;
- + }
- +
- /* Wait for boot completion */
- rc = venus_hfi_reset_core(device);
- if (rc) {
- @@ -2024,6 +2030,7 @@ static int venus_hfi_core_release(void *device)
- return -ENODEV;
- }
- if (dev->hal_client) {
- + cancel_delayed_work_sync(&venus_hfi_pm_work);
- mutex_lock(&dev->clk_pwr_lock);
- rc = venus_hfi_clk_gating_off(device);
- if (rc) {
- @@ -2872,7 +2879,6 @@ err_pc_prep:
- static void venus_hfi_pm_hndlr(struct work_struct *work)
- {
- int rc = 0;
- - u32 ctrl_status = 0;
- struct venus_hfi_device *device = list_first_entry(
- &hal_ctxt.dev_head, struct venus_hfi_device, list);
- @@ -2934,13 +2940,12 @@ static void venus_hfi_pm_hndlr(struct work_struct *work)
- err_power_off:
- skip_power_off:
- - /* Reset PC_READY bit as power_off is skipped, if set by Venus */
- - ctrl_status = venus_hfi_read_register(device, VIDC_CPU_CS_SCIACMDARG0);
- - if (ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY) {
- - ctrl_status &= ~(VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY);
- - venus_hfi_write_register(device, VIDC_CPU_CS_SCIACMDARG0,
- - ctrl_status, 0);
- - }
- + /*
- + * When power collapse is escaped, driver no need to inform Venus.
- + * Venus is self-sufficient to come out of the power collapse at
- + * any stage. Driver can skip power collapse and continue with
- + * normal execution.
- + */
- /* Cancel pending delayed works if any */
- cancel_delayed_work(&venus_hfi_pm_work);
- @@ -3250,7 +3255,18 @@ static inline void venus_hfi_disable_unprepare_clks(
- }
- WARN_ON(!mutex_is_locked(&device->clk_pwr_lock));
- + /*
- + * Make the clock state variable as unprepared before actually
- + * unpreparing clocks. This will make sure that when we check
- + * the state, we have the right clock state. We are not taking
- + * any action based unprepare failures. So it is safe to do
- + * before the call. This is also in sync with prepare_enable
- + * state update.
- + */
- +
- + --device->clk_cnt;
- if (device->clk_state == ENABLED_PREPARED) {
- + device->clk_state = DISABLED_PREPARED;
- for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
- if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- continue;
- @@ -3261,8 +3277,11 @@ static inline void venus_hfi_disable_unprepare_clks(
- __func__, cl->name);
- }
- } else {
- + device->clk_state = DISABLED_PREPARED;
- for (i = device->clk_gating_level + 1;
- i < VCODEC_MAX_CLKS; i++) {
- + if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- + continue;
- cl = &device->resources.clock[i];
- usleep(100);
- clk_disable(cl->clk);
- @@ -3270,6 +3289,7 @@ static inline void venus_hfi_disable_unprepare_clks(
- __func__, cl->name);
- }
- }
- + device->clk_state = DISABLED_UNPREPARED;
- for (i = VCODEC_CLK; i < VCODEC_MAX_CLKS; i++) {
- if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- continue;
- @@ -3278,8 +3298,6 @@ static inline void venus_hfi_disable_unprepare_clks(
- dprintk(VIDC_DBG, "%s: Clock: %s unprepared\n",
- __func__, cl->name);
- }
- - device->clk_state = DISABLED_UNPREPARED;
- - --device->clk_cnt;
- }
- static inline int venus_hfi_prepare_enable_clks(struct venus_hfi_device *device)
- @@ -3316,6 +3334,8 @@ static inline int venus_hfi_prepare_enable_clks(struct venus_hfi_device *device)
- return rc;
- fail_clk_enable:
- for (; i >= VCODEC_CLK; i--) {
- + if (i == VCODEC_OCMEM_CLK && !device->res->ocmem_size)
- + continue;
- cl = &device->resources.clock[i];
- usleep(100);
- clk_disable_unprepare(cl->clk);
- diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
- index 8f0557a..92bfadc 100644
- --- a/drivers/misc/qseecom.c
- +++ b/drivers/misc/qseecom.c
- @@ -42,9 +42,6 @@
- #include <mach/socinfo.h>
- #include <mach/qseecomi.h>
- #include <asm/cacheflush.h>
- -#ifdef CONFIG_SEC_DEBUG
- -#include <mach/sec_debug.h>
- -#endif
- #include "qseecom_legacy.h"
- #include "qseecom_kernel.h"
- @@ -76,7 +73,6 @@
- #define QSEECOM_SEND_CMD_CRYPTO_TIMEOUT 2000
- #define QSEECOM_LOAD_APP_CRYPTO_TIMEOUT 2000
- -#define TWO 2
- enum qseecom_clk_definitions {
- CLK_DFAB = 0,
- @@ -1043,9 +1039,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
- }
- entry->app_id = app_id;
- entry->ref_cnt = 1;
- - memset((void *)entry->app_name, 0, MAX_APP_NAME_SIZE);
- - memcpy((void *)entry->app_name,
- - (void *)load_img_req.img_name, MAX_APP_NAME_SIZE);
- + memcpy(entry->app_name, load_img_req.img_name,
- + MAX_APP_NAME_SIZE);
- /* Deallocate the handle */
- if (!IS_ERR_OR_NULL(ihandle))
- ion_free(qseecom.ion_clnt, ihandle);
- @@ -1059,9 +1054,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
- (char *)(load_img_req.img_name));
- }
- data->client.app_id = app_id;
- - memset((void *)data->client.app_name, 0, MAX_APP_NAME_SIZE);
- - memcpy((void *)data->client.app_name,
- - (void *)load_img_req.img_name, MAX_APP_NAME_SIZE);
- + memcpy(data->client.app_name, load_img_req.img_name,
- + MAX_APP_NAME_SIZE);
- load_img_req.app_id = app_id;
- if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
- pr_err("copy_to_user failed\n");
- @@ -1119,8 +1113,8 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
- bool found_dead_app = false;
- if (!memcmp(data->client.app_name, "keymaste", strlen("keymaste"))) {
- - pr_warn("Do not unload keymaster app from tz\n");
- - return 0;
- + pr_debug("Do not unload keymaster app from tz\n");
- + goto unload_exit;
- }
- if (data->client.app_id > 0) {
- @@ -1215,6 +1209,7 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
- spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
- flags1);
- }
- +unload_exit:
- qseecom_unmap_ion_allocated_memory(data);
- data->released = true;
- return ret;
- @@ -1403,9 +1398,8 @@ static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
- pr_err("Client or client handle is not initialized\n");
- return -EINVAL;
- }
- -
- - if (((req->cmd_req_buf == NULL) && (req->resp_len != 0)) ||
- - (req->resp_buf == NULL)) {
- + if (((req->resp_buf == NULL) && (req->resp_len != 0)) ||
- + (req->cmd_req_buf == NULL)) {
- pr_err("cmd buffer or response buffer is null\n");
- return -EINVAL;
- }
- @@ -1415,23 +1409,19 @@ static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
- pr_err("cmd buffer address not within shared bufffer\n");
- return -EINVAL;
- }
- -
- -
- - if (((uintptr_t)req->cmd_req_buf <
- - data->client.user_virt_sb_base) ||
- - ((uintptr_t)req->cmd_req_buf >=
- - (data->client.user_virt_sb_base + data->client.sb_length))) {
- + if (((uintptr_t)req->resp_buf <
- + data->client.user_virt_sb_base) ||
- + ((uintptr_t)req->resp_buf >=
- + (data->client.user_virt_sb_base + data->client.sb_length))) {
- pr_err("response buffer address not within shared bufffer\n");
- return -EINVAL;
- }
- -
- if ((req->cmd_req_len == 0) ||
- (req->cmd_req_len > data->client.sb_length) ||
- (req->resp_len > data->client.sb_length)) {
- - pr_err("cmd buffer length or response buffer length not valid\n");
- + pr_err("cmd buf length or response buf length not valid\n");
- return -EINVAL;
- }
- -
- if (req->cmd_req_len > UINT_MAX - req->resp_len) {
- pr_err("Integer overflow detected in req_len & rsp_len\n");
- return -EINVAL;
- @@ -1441,7 +1431,7 @@ static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
- pr_debug("Not enough memory to fit cmd_buf.\n");
- pr_debug("resp_buf. Required: %u, Available: %zu\n",
- (req->cmd_req_len + req->resp_len),
- - data->client.sb_length);
- + data->client.sb_length);
- return -ENOMEM;
- }
- if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) {
- @@ -1468,7 +1458,7 @@ static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
- }
- return 0;
- }
- -
- +
- static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
- struct qseecom_send_cmd_req *req)
- {
- @@ -1489,8 +1479,8 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
- name_len = min(strlen(data->client.app_name),
- strlen(ptr_app->app_name));
- if ((ptr_app->app_id == data->client.app_id) &&
- - (!memcmp((void *)ptr_app->app_name,
- - (void *)data->client.app_name, name_len))) {
- + (!memcmp(ptr_app->app_name,
- + data->client.app_name, name_len))) {
- found_app = true;
- break;
- }
- @@ -1567,55 +1557,32 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
- return ret;
- }
- -int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req,
- +int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *cmd_req,
- struct qseecom_send_modfd_listener_resp *lstnr_resp,
- - struct qseecom_dev_handle *data, bool qteec,
- + struct qseecom_dev_handle *data, bool listener_svc,
- int i) {
- - if ((data->type != QSEECOM_LISTENER_SERVICE) &&
- - (req->ifd_data[i].fd > 0)) {
- - if (qteec) {
- - if ((req->cmd_req_len < (TWO * sizeof(uint32_t))) ||
- - (req->ifd_data[i].cmd_buf_offset >
- - req->cmd_req_len - (TWO * sizeof(uint32_t)))) {
- - pr_err("Invalid offset (QTEEC req len) 0x%x\n",
- - req->ifd_data[i].cmd_buf_offset);
- - return -EINVAL;
- - }
- - } else {
- - if ((req->cmd_req_len < sizeof(uint32_t)) ||
- - (req->ifd_data[i].cmd_buf_offset >
- - req->cmd_req_len - sizeof(uint32_t))) {
- - pr_err("Invalid offset (req len) 0x%x\n",
- - req->ifd_data[i].cmd_buf_offset);
- - return -EINVAL;
- - }
- + if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
- + if ((cmd_req->cmd_req_len < sizeof(uint32_t)) ||
- + (cmd_req->ifd_data[i].cmd_buf_offset >
- + cmd_req->cmd_req_len - sizeof(uint32_t))) {
- + pr_err("Invalid offset 0x%x\n",
- + cmd_req->ifd_data[i].cmd_buf_offset);
- + return -EINVAL;
- }
- - } else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
- - (lstnr_resp->ifd_data[i].fd > 0)) {
- - if (qteec) {
- - if ((lstnr_resp->resp_len < TWO * sizeof(uint32_t)) ||
- - (lstnr_resp->ifd_data[i].cmd_buf_offset >
- - lstnr_resp->resp_len - TWO*sizeof(uint32_t))) {
- - pr_err("Invalid offset (QTEEC resp len) 0x%x\n",
- - lstnr_resp->ifd_data[i].cmd_buf_offset);
- - return -EINVAL;
- - }
- - } else {
- - if ((lstnr_resp->resp_len < sizeof(uint32_t)) ||
- + } else if ((listener_svc) && (lstnr_resp->ifd_data[i].fd > 0)) {
- + if ((lstnr_resp->resp_len < sizeof(uint32_t)) ||
- (lstnr_resp->ifd_data[i].cmd_buf_offset >
- lstnr_resp->resp_len - sizeof(uint32_t))) {
- - pr_err("Invalid offset (lstnr resp len) 0x%x\n",
- + pr_err("Invalid offset 0x%x\n",
- lstnr_resp->ifd_data[i].cmd_buf_offset);
- - return -EINVAL;
- - }
- + return -EINVAL;
- }
- }
- return 0;
- }
- #define SG_ENTRY_SZ sizeof(struct qseecom_sg_entry)
- -
- static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
- struct qseecom_dev_handle *data,
- bool listener_svc)
- @@ -1691,7 +1658,7 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
- update = (uint32_t *) field;
- if (__boundary_checks_offset(cmd_req, lstnr_resp, data,
- - false, i))
- + listener_svc, i))
- goto err;
- if (cleanup)
- *update = 0;
- @@ -1703,21 +1670,24 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
- struct qseecom_sg_entry *update;
- int j = 0;
- - if ((data->type != QSEECOM_LISTENER_SERVICE) &&
- - (cmd_req->ifd_data[i].fd > 0)) {
- - if (cmd_req->ifd_data[i].cmd_buf_offset >
- - cmd_req->cmd_req_len -
- - sizeof(struct qseecom_sg_entry)) {
- + if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
- + if ((cmd_req->cmd_req_len <
- + SG_ENTRY_SZ * sg_ptr->nents) ||
- + (cmd_req->ifd_data[i].cmd_buf_offset >
- + (cmd_req->cmd_req_len -
- + SG_ENTRY_SZ * sg_ptr->nents))) {
- pr_err("Invalid offset = 0x%x\n",
- cmd_req->ifd_data[i].
- cmd_buf_offset);
- goto err;
- }
- - } else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
- + } else if ((listener_svc) &&
- (lstnr_resp->ifd_data[i].fd > 0)) {
- - if (lstnr_resp->ifd_data[i].cmd_buf_offset >
- - lstnr_resp->resp_len -
- - sizeof(struct qseecom_sg_entry)) {
- + if ((lstnr_resp->resp_len <
- + SG_ENTRY_SZ * sg_ptr->nents) ||
- + (lstnr_resp->ifd_data[i].cmd_buf_offset >
- + (lstnr_resp->resp_len -
- + SG_ENTRY_SZ * sg_ptr->nents))) {
- pr_err("Invalid offset = 0x%x\n",
- lstnr_resp->ifd_data[i].
- cmd_buf_offset);
- @@ -2214,6 +2184,11 @@ int qseecom_start_app(struct qseecom_handle **handle,
- uint32_t len;
- ion_phys_addr_t pa;
- + if (!app_name || strlen(app_name) >= MAX_APP_NAME_SIZE) {
- + pr_err("The app_name (%s) is not valid\n", app_name);
- + return -EINVAL;
- + }
- +
- *handle = kzalloc(sizeof(struct qseecom_handle), GFP_KERNEL);
- if (!(*handle)) {
- pr_err("failed to allocate memory for kernel client handle\n");
- @@ -2294,6 +2269,7 @@ int qseecom_start_app(struct qseecom_handle **handle,
- if (ret < 0)
- goto err;
- data->client.app_id = ret;
- + memcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE);
- }
- if (!found_app) {
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- @@ -2304,6 +2280,7 @@ int qseecom_start_app(struct qseecom_handle **handle,
- }
- entry->app_id = ret;
- entry->ref_cnt = 1;
- + memcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
- spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
- list_add_tail(&entry->list, &qseecom.registered_app_list_head);
- @@ -2367,6 +2344,9 @@ int qseecom_shutdown_app(struct qseecom_handle **handle)
- return -EINVAL;
- }
- data = (struct qseecom_dev_handle *) ((*handle)->dev);
- + mutex_lock(&app_access_lock);
- + atomic_inc(&data->ioctl_count);
- +
- spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
- list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
- list) {
- @@ -2399,12 +2379,16 @@ int qseecom_shutdown_app(struct qseecom_handle **handle)
- if (data->perf_enabled == true)
- qsee_disable_clock_vote(data, CLK_DFAB);
- }
- +
- + atomic_dec(&data->ioctl_count);
- + mutex_unlock(&app_access_lock);
- if (ret == 0) {
- kzfree(data);
- kzfree(*handle);
- kzfree(kclient);
- *handle = NULL;
- }
- +
- return ret;
- }
- EXPORT_SYMBOL(qseecom_shutdown_app);
- @@ -3056,9 +3040,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
- &qseecom.registered_app_list_lock, flags);
- data->client.app_id = ret;
- query_req.app_id = ret;
- - memset((void *)data->client.app_name, 0, MAX_APP_NAME_SIZE);
- - memcpy((void *)data->client.app_name,
- - (void *)query_req.app_name, MAX_APP_NAME_SIZE);
- + memcpy(data->client.app_name, query_req.app_name,
- + MAX_APP_NAME_SIZE);
- if (copy_to_user(argp, &query_req, sizeof(query_req))) {
- pr_err("copy_to_user failed\n");
- return -EFAULT;
- @@ -3111,7 +3094,6 @@ static int __qseecom_generate_and_save_key(struct qseecom_dev_handle *data,
- enum qseecom_key_management_usage_type usage,
- struct qseecom_key_generate_ireq *ireq)
- {
- -
- struct qseecom_command_scm_resp resp;
- int ret;
- @@ -3120,7 +3102,6 @@ static int __qseecom_generate_and_save_key(struct qseecom_dev_handle *data,
- pr_err("Error:: unsupported usage %d\n", usage);
- return -EFAULT;
- }
- -
- __qseecom_enable_clk(CLK_QSEE);
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
- @@ -3173,7 +3154,6 @@ static int __qseecom_delete_saved_key(struct qseecom_dev_handle *data,
- return -EFAULT;
- }
- -
- __qseecom_enable_clk(CLK_QSEE);
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
- @@ -3856,8 +3836,6 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
- ret = -EINVAL;
- break;
- }
- - pr_debug("%s : Perf Enable ioctl (Process:%s PID:%d)\n", __func__, \
- - current->comm, current->pid);
- atomic_inc(&data->ioctl_count);
- if (qseecom.support_bus_scaling) {
- mutex_lock(&qsee_bw_mutex);
- @@ -3886,8 +3864,6 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
- ret = -EINVAL;
- break;
- }
- - pr_debug("%s : Perf Disable ioctl (Process:%s PID:%d)\n", __func__, \
- - current->comm, current->pid);
- atomic_inc(&data->ioctl_count);
- if (!qseecom.support_bus_scaling) {
- qsee_disable_clock_vote(data, CLK_DFAB);
- @@ -4505,9 +4481,6 @@ static int __devinit qseecom_probe(struct platform_device *pdev)
- req.size = resource_size(resource);
- pr_warn("secure app region addr=0x%x size=0x%x",
- req.addr, req.size);
- -#ifdef CONFIG_SEC_DEBUG
- - sec_debug_secure_app_addr_size(req.addr, req.size);
- -#endif
- } else {
- pr_err("Fail to get secure app region info\n");
- rc = -EINVAL;
- @@ -4634,8 +4607,7 @@ static int qseecom_suspend(struct platform_device *pdev, pm_message_t state)
- mutex_lock(&qsee_bw_mutex);
- mutex_lock(&clk_access_lock);
- - if (qseecom.cumulative_mode != INACTIVE &&
- - qseecom.current_mode != INACTIVE) {
- + if (qseecom.current_mode != INACTIVE) {
- ret = msm_bus_scale_client_update_request(
- qseecom.qsee_perf_client, INACTIVE);
- if (ret)
- diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
- index 8fab5aa..1cbc66f 100644
- --- a/drivers/mmc/card/block.c
- +++ b/drivers/mmc/card/block.c
- @@ -3501,7 +3501,7 @@ static void mmc_blk_shutdown(struct mmc_card *card)
- mmc_claim_host(card->host);
- mmc_stop_bkops(card);
- mmc_release_host(card->host);
- - mmc_send_long_pon(card);
- + mmc_send_pon(card);
- mmc_rpm_release(card->host, &card->dev);
- }
- return;
- diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
- index da6f043..76c4fbe 100644
- --- a/drivers/mmc/core/mmc.c
- +++ b/drivers/mmc/core/mmc.c
- @@ -1378,10 +1378,7 @@ static int mmc_reboot_notify(struct notifier_block *notify_block,
- struct mmc_card *card = container_of(
- notify_block, struct mmc_card, reboot_notify);
- - if (event != SYS_RESTART)
- - card->issue_long_pon = true;
- - else
- - card->issue_long_pon = false;
- + card->pon_type = (event != SYS_RESTART) ? MMC_LONG_PON : MMC_SHRT_PON;
- return NOTIFY_OK;
- }
- @@ -1788,19 +1785,24 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
- return err;
- }
- -int mmc_send_long_pon(struct mmc_card *card)
- +int mmc_send_pon(struct mmc_card *card)
- {
- int err = 0;
- struct mmc_host *host = card->host;
- + if (!mmc_can_poweroff_notify(card))
- + goto out;
- +
- mmc_claim_host(host);
- - if (card->issue_long_pon && mmc_can_poweroff_notify(card)) {
- + if (card->pon_type & MMC_LONG_PON)
- err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_LONG);
- - if (err)
- - pr_warning("%s: error %d sending Long PON",
- - mmc_hostname(host), err);
- - }
- + else if (card->pon_type & MMC_SHRT_PON)
- + err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
- + if (err)
- + pr_warn("%s: error %d sending PON type %u",
- + mmc_hostname(host), err, card->pon_type);
- mmc_release_host(host);
- +out:
- return err;
- }
- diff --git a/drivers/net/wireless/wcnss/wcnss_vreg.c b/drivers/net/wireless/wcnss/wcnss_vreg.c
- index 9c65a63..6cfd8cb 100644
- --- a/drivers/net/wireless/wcnss/wcnss_vreg.c
- +++ b/drivers/net/wireless/wcnss/wcnss_vreg.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2011-2013,2015 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
- @@ -37,7 +37,6 @@ static int auto_detect;
- #define MSM_PRONTO_PHYS 0xfb21b000
- #define RIVA_PMU_OFFSET 0x28
- -#define PRONTO_PMU_OFFSET 0x1004
- #define RIVA_SPARE_OFFSET 0x0b4
- #define PRONTO_SPARE_OFFSET 0x1088
- @@ -48,7 +47,6 @@ static int auto_detect;
- #define WCNSS_PMU_CFG_IRIS_XO_CFG BIT(3)
- #define WCNSS_PMU_CFG_IRIS_XO_EN BIT(4)
- -#define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP BIT(5)
- #define WCNSS_PMU_CFG_IRIS_XO_CFG_STS BIT(6) /* 1: in progress, 0: done */
- #define WCNSS_PMU_CFG_IRIS_RESET BIT(7)
- @@ -100,7 +98,7 @@ static struct vregs_info iris_vregs_pronto[] = {
- {"qcom,iris-vddrfa", VREG_NULL_CONFIG, 1300000, 0,
- 1300000, 100000, NULL},
- {"qcom,iris-vddpa", VREG_NULL_CONFIG, 2900000, 0,
- - 3000000, 515000, NULL},
- + 3350000, 515000, NULL},
- {"qcom,iris-vdddig", VREG_NULL_CONFIG, 1225000, 0,
- 1800000, 10000, NULL},
- };
- diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
- index 985fb1f..07f4d13 100644
- --- a/drivers/net/wireless/wcnss/wcnss_wlan.c
- +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2011-2013,2015 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
- @@ -898,6 +898,22 @@ static void wcnss_log_iris_regs(void)
- }
- }
- +int wcnss_get_mux_control(void)
- +{
- + void __iomem *pmu_conf_reg;
- + u32 reg = 0;
- +
- + if (NULL == penv)
- + return 0;
- +
- + pmu_conf_reg = penv->msm_wcnss_base + PRONTO_PMU_OFFSET;
- + writel_relaxed(0, pmu_conf_reg);
- + reg = readl_relaxed(pmu_conf_reg);
- + reg |= WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP;
- + writel_relaxed(reg, pmu_conf_reg);
- + return 1;
- +}
- +
- void wcnss_log_debug_regs_on_bite(void)
- {
- struct platform_device *pdev = wcnss_get_platform_device();
- @@ -920,6 +936,8 @@ void wcnss_log_debug_regs_on_bite(void)
- if (clk_rate) {
- wcnss_pronto_log_debug_regs();
- + if (wcnss_get_mux_control())
- + wcnss_log_iris_regs();
- } else {
- pr_err("clock frequency is zero, cannot access PMU or other registers\n");
- wcnss_log_iris_regs();
- @@ -933,6 +951,8 @@ void wcnss_reset_intr(void)
- {
- if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
- wcnss_pronto_log_debug_regs();
- + if (wcnss_get_mux_control())
- + wcnss_log_iris_regs();
- wmb();
- __raw_writel(1 << 16, penv->fiq_reg);
- } else {
- @@ -990,20 +1010,20 @@ static void wcnss_remove_sysfs(struct device *dev)
- static void wcnss_pm_qos_add_request(void)
- {
- - pr_info("%s: add request", __func__);
- + pr_info("%s: add request\n", __func__);
- pm_qos_add_request(&penv->wcnss_pm_qos_request, PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
- }
- static void wcnss_pm_qos_remove_request(void)
- {
- - pr_info("%s: remove request", __func__);
- + pr_info("%s: remove request\n", __func__);
- pm_qos_remove_request(&penv->wcnss_pm_qos_request);
- }
- void wcnss_pm_qos_update_request(int val)
- {
- - pr_info("%s: update request %d", __func__, val);
- + pr_info("%s: update request %d\n", __func__, val);
- pm_qos_update_request(&penv->wcnss_pm_qos_request, val);
- }
- @@ -1810,8 +1830,10 @@ static void wcnssctrl_rx_handler(struct work_struct *worker)
- smd_read(penv->smd_ch, NULL, len);
- return;
- }
- - if (len <= 0)
- + if (len < sizeof(struct smd_msg_hdr)) {
- + pr_err("wcnss: incomplete header available len = %d\n", len);
- return;
- + }
- rc = smd_read(penv->smd_ch, buf, sizeof(struct smd_msg_hdr));
- if (rc < sizeof(struct smd_msg_hdr)) {
- @@ -1961,13 +1983,13 @@ static void wcnss_send_pm_config(struct work_struct *worker)
- return;
- }
- - pr_debug("%s:size=%d: <%d, %d, %d, %d, %d>\n", __func__,
- + pr_debug("%s:size=%d: <%d, %d, %d, %d, %d %d>\n", __func__,
- prop_len, *payload, *(payload+1), *(payload+2),
- - *(payload+3), *(payload+4));
- + *(payload+3), *(payload+4), *(payload+5));
- hdr = (struct smd_msg_hdr *)msg;
- hdr->msg_type = WCNSS_PM_CONFIG_REQ;
- - hdr->msg_len = sizeof(struct smd_msg_hdr) + prop_len;
- + hdr->msg_len = sizeof(struct smd_msg_hdr) + (prop_len * sizeof(int));
- rc = wcnss_smd_tx(msg, hdr->msg_len);
- if (rc < 0)
- diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
- index 776673f..b1681f1 100644
- --- a/drivers/nfc/nfc-nci.c
- +++ b/drivers/nfc/nfc-nci.c
- @@ -28,6 +28,7 @@
- #include <linux/regulator/consumer.h>
- #include "nfc-nci.h"
- #include <mach/gpiomux.h>
- +#include <linux/pm_runtime.h>
- struct qca199x_platform_data {
- unsigned int irq_gpio;
- @@ -60,8 +61,10 @@ MODULE_DEVICE_TABLE(of, msm_match_table);
- #define CORE_RESET_RSP_GID (0x60)
- #define CORE_RESET_OID (0x00)
- #define CORE_RST_NTF_LENGTH (0x02)
- -#define WAKE_TIMEOUT (10)
- +#define WAKE_TIMEOUT (1000)
- #define WAKE_REG (0x10)
- +#define EFUSE_REG (0xA0)
- +#define WAKEUP_SRC_TIMEOUT (2000)
- static void clk_req_update(struct work_struct *work);
- @@ -98,6 +101,8 @@ struct qca199x_dev {
- struct workqueue_struct *my_wq;
- };
- +static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
- + void *v);
- static int nfc_i2c_write(struct i2c_client *client, u8 *buf, int len);
- static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr);
- static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- @@ -121,7 +126,7 @@ static int ftm_werr_code;
- unsigned int disable_ctrl;
- -bool region2_sent;
- +bool region2_sent;
- static void qca199x_init_stat(struct qca199x_dev *qca199x_dev)
- {
- @@ -157,6 +162,21 @@ static irqreturn_t qca199x_dev_irq_handler(int irq, void *dev_id)
- struct qca199x_dev *qca199x_dev = dev_id;
- unsigned long flags;
- + if (device_may_wakeup(&qca199x_dev->client->dev) &&
- + (qca199x_dev->client->dev.power.is_suspended == true)) {
- + dev_dbg(&qca199x_dev->client->dev,
- + "%s: NFC:Processor in suspend state device_may_wakeup\n",
- + __func__);
- + /*
- + * Keep system awake long enough to allow userspace
- + * to process the packet.
- + */
- + pm_wakeup_event(&qca199x_dev->client->dev, WAKEUP_SRC_TIMEOUT);
- + } else {
- + dev_dbg(&qca199x_dev->client->dev,
- + "%s: NFC:Processor not in suspend state\n", __func__);
- + }
- +
- spin_lock_irqsave(&qca199x_dev->irq_enabled_lock, flags);
- qca199x_dev->count_irq++;
- spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock, flags);
- @@ -312,7 +332,12 @@ static ssize_t nfc_read(struct file *filp, char __user *buf,
- /* READ */
- if ((ftm_raw_write_mode == 0) && (ftm_werr_code == 0)) {
- ftm_rerr_code = i2c_master_recv(qca199x_dev->client,
- - &rd_byte, 1);
- + &rd_byte, sizeof(rd_byte));
- +
- + if (ftm_rerr_code != sizeof(rd_byte)) {
- + total = -EMSGSIZE;
- + goto err;
- + }
- if (ftm_rerr_code == 0x1)
- ftm_rerr_code = 0;
- tmp[0] = (unsigned char)ftm_rerr_code;
- @@ -371,8 +396,8 @@ static ssize_t nfc_read(struct file *filp, char __user *buf,
- if (total > 0) {
- if ((total > count) || copy_to_user(buf, tmp, total)) {
- dev_err(&qca199x_dev->client->dev,
- - "failed to copy to user space, total = %d\n",
- - total);
- + "%s: failed to copy to user space, total = %d\n",
- + __func__, total);
- total = -EFAULT;
- }
- }
- @@ -421,6 +446,9 @@ int nfcc_read_buff_svc(struct qca199x_dev *qca199x_dev)
- ret = i2c_master_recv(qca199x_dev->client, tmp, (length +
- PAYLOAD_HEADER_LENGTH));
- total = ret;
- + if (ret != (length + PAYLOAD_HEADER_LENGTH))
- + goto leave;
- +
- }
- dev_dbg(&qca199x_dev->client->dev, "%s : NfcNciRx %x %x %x\n",
- __func__, tmp[0], tmp[1], tmp[2]);
- @@ -439,12 +467,13 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf,
- int nfcc_buffer = 0;
- if (count > MAX_BUFFER_SIZE) {
- - dev_err(&qca199x_dev->client->dev, "out of memory\n");
- + dev_err(&qca199x_dev->client->dev, "%s: out of memory\n",
- + __func__);
- return -ENOMEM;
- }
- if (copy_from_user(tmp, buf, count)) {
- dev_err(&qca199x_dev->client->dev,
- - "nfc-nci write: failed to copy from user space\n");
- + "%s: failed to copy from user space\n", __func__);
- return -EFAULT;
- }
- /*
- @@ -460,7 +489,8 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf,
- /* There has been an error while reading from nfcc */
- if (nfcc_buffer < 0) {
- dev_err(&qca199x_dev->client->dev,
- - "nfc-nci write: error while servicing nfcc read buffer\n");
- + "%s: error while servicing nfcc read buffer\n"
- + , __func__);
- }
- qca199x_dev->sent_first_nci_write = true;
- qca199x_enable_irq(qca199x_dev);
- @@ -475,7 +505,7 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf,
- if (count == 1) {
- ftm_raw_write_mode = 0;
- ret = i2c_master_send(qca199x_dev->client, tmp, count);
- - if (ret == 1)
- + if (ret == count)
- ftm_werr_code = 0;
- else
- ftm_werr_code = ret;
- @@ -485,7 +515,7 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf,
- if (count == 2) {
- ftm_raw_write_mode = 1;
- ret = i2c_master_send(qca199x_dev->client, tmp, count);
- - if (ret == 2)
- + if (ret == count)
- ftm_werr_code = 0;
- else
- ftm_werr_code = ret;
- @@ -498,7 +528,7 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf,
- }
- if (ret != count) {
- dev_err(&qca199x_dev->client->dev,
- - "NFC: failed to write %d\n", ret);
- + "%s: failed to write %d\n", __func__, ret);
- ret = -EIO;
- }
- mutex_unlock(&qca199x_dev->read_mutex);
- @@ -532,7 +562,7 @@ static int nfc_open(struct inode *inode, struct file *filp)
- qca199x_enable_irq_clk_req(qca199x_dev);
- }
- dev_dbg(&qca199x_dev->client->dev,
- - "%d,%d\n", imajor(inode), iminor(inode));
- + "%s: %d,%d\n", __func__, imajor(inode), iminor(inode));
- return ret;
- }
- @@ -544,17 +574,21 @@ int nfcc_wake(int level, struct file *filp)
- int r = 0;
- int time_taken = 0;
- unsigned char raw_nci_sleep[] = {0x2F, 0x03, 0x00};
- - /* Change slave address to 0xE */
- unsigned char raw_nci_wake[] = {0x10, 0x0F};
- - unsigned short slave_addr = 0xE;
- + /* Change slave address to 0xE */
- + unsigned short slave_addr = 0xE;
- unsigned short curr_addr;
- - unsigned char wake_status = WAKE_REG;
- + unsigned char wake_status = WAKE_REG;
- struct qca199x_dev *qca199x_dev = filp->private_data;
- - dev_dbg(&qca199x_dev->client->dev, "nfcc_wake: %s: info: %p\n",
- + dev_dbg(&qca199x_dev->client->dev, "%s: info: %p\n",
- __func__, qca199x_dev);
- + curr_addr = qca199x_dev->client->addr;
- if (level == NFCC_SLEEP) {
- + /*
- + * Normal NCI write
- + */
- r = i2c_master_send(qca199x_dev->client, &raw_nci_sleep[0],
- sizeof(raw_nci_sleep));
- @@ -562,54 +596,79 @@ int nfcc_wake(int level, struct file *filp)
- return -EMSGSIZE;
- qca199x_dev->state = NFCC_STATE_NORMAL_SLEEP;
- } else {
- - curr_addr = qca199x_dev->client->addr;
- qca199x_dev->client->addr = slave_addr;
- r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
- sizeof(raw_nci_wake));
- + if (r != sizeof(raw_nci_wake)) {
- + r = -EMSGSIZE;
- + dev_err(&qca199x_dev->client->dev,
- + "%s: nci wake write failed. Check hardware\n",
- + __func__);
- + goto leave;
- + }
- do {
- wake_status = WAKE_REG;
- - r = nfc_i2c_write(qca199x_dev->client, &wake_status, 1);
- + r = nfc_i2c_write(qca199x_dev->client, &wake_status,
- + sizeof(wake_status));
- + if (r != sizeof(wake_status)) {
- + r = -EMSGSIZE;
- + dev_err(&qca199x_dev->client->dev,
- + "%s: wake status write fail.Check hardware\n",
- + __func__);
- + goto leave;
- + }
- /*
- - * NFCC chip needs to be at least
- - * 10usec high before make it low
- + * I2C line is low after ~10 usec
- */
- usleep_range(10, 15);
- r = i2c_master_recv(qca199x_dev->client, &wake_status,
- sizeof(wake_status));
- + if (r != sizeof(wake_status)) {
- + r = -EMSGSIZE;
- + dev_err(&qca199x_dev->client->dev,
- + "%s: wake status read fail.Check hardware\n",
- + __func__);
- + goto leave;
- + }
- time_taken++;
- + /*
- + * Each NFCC wakeup cycle
- + * takes about 0.5 ms
- + */
- if ((wake_status & NCI_WAKE) != 0)
- /* NFCC wakeup time is between 0.5 and .52 ms */
- - usleep_range(500, 520);
- + usleep_range(500, 550);
- } while ((wake_status & NCI_WAKE)
- && (time_taken < WAKE_TIMEOUT));
- - /* Restore original NFCC slave I2C address */
- - if (time_taken >= WAKE_TIMEOUT)
- + if (time_taken >= WAKE_TIMEOUT) {
- dev_err(&qca199x_dev->client->dev,
- - "nfc_ioctl_nfcc_version : TIMED OUT to get WAKEUP bit\n");
- -
- - qca199x_dev->client->addr = curr_addr;
- - if (r != sizeof(wake_status))
- - return -EMSGSIZE;
- + "%s: timed out to get wakeup bit\n", __func__);
- + r = -EIO;
- + goto leave;
- + }
- + r = 0;
- qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
- }
- -
- +leave:
- + /* Restore original NFCC slave I2C address */
- + qca199x_dev->client->addr = curr_addr;
- return r;
- }
- /*
- * Inside nfc_ioctl_power_states
- *
- - * @brief ioctl functions
- + * @brief ioctl functions
- *
- *
- * Device control
- * remove control via ioctl
- - * (arg = 0): NFC_DISABLE GPIO = 0
- - * (arg = 1): NFC_DISABLE GPIO = 1
- - * NOT USED (arg = 2): FW_DL GPIO = 0
- - * NOT USED (arg = 3): FW_DL GPIO = 1
- + * (arg = 0): NFC_DISABLE GPIO = 0
- + * (arg = 1): NFC_DISABLE GPIO = 1
- + * NOT USED (arg = 2): FW_DL GPIO = 0
- + * NOT USED (arg = 3): FW_DL GPIO = 1
- * (arg = 4): NFCC_WAKE = 1
- * (arg = 5): NFCC_WAKE = 0
- *
- @@ -628,7 +687,7 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd,
- dev_dbg(&qca199x_dev->client->dev, "gpio_set_value disable: %s: info: %p\n",
- __func__, qca199x_dev);
- gpio_set_value(qca199x_dev->dis_gpio, 0);
- - usleep(1000);
- + usleep_range(1000, 1100);
- } else if (arg == 1) {
- /*
- * We are attempting a hardware reset so let us disable
- @@ -650,7 +709,7 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd,
- dev_dbg(&qca199x_dev->client->dev, "gpio_set_value enable: %s: info: %p\n",
- __func__, qca199x_dev);
- gpio_set_value(qca199x_dev->dis_gpio, 1);
- - /*nfcc needs atleast 100ms for the chip to power cycle*/
- + /* NFCC needs at least 100 ms to power cycle*/
- msleep(100);
- } else if (arg == 2) {
- mutex_lock(&qca199x_dev->read_mutex);
- @@ -671,12 +730,12 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd,
- msleep(20);
- } else if (arg == 4) {
- mutex_lock(&qca199x_dev->read_mutex);
- - nfcc_wake(NFCC_WAKE, filp);
- + r = nfcc_wake(NFCC_WAKE, filp);
- dev_dbg(&qca199x_dev->client->dev, "nfcc wake: %s: info: %p\n",
- __func__, qca199x_dev);
- mutex_unlock(&qca199x_dev->read_mutex);
- } else if (arg == 5) {
- - nfcc_wake(NFCC_SLEEP, filp);
- + r = nfcc_wake(NFCC_SLEEP, filp);
- } else {
- r = -ENOIOCTLCMD;
- }
- @@ -688,14 +747,14 @@ err_req:
- /*
- * Inside nfc_ioctl_nfcc_mode
- *
- - * @brief nfc_ioctl_nfcc_mode
- + * @brief nfc_ioctl_nfcc_mode
- *
- * (arg = 0) ; NORMAL_MODE - Standard mode, unsolicited read behaviour
- * (arg = 1) ; SOLICITED_MODE - As above but reads are solicited from User Land
- * (arg = 2) ; UNSOLICITED_FTM_RAW MODE - NORMAL_MODE but messages from FTM and
- - * not NCI Host.
- + * not NCI Host.
- * (arg = 2) ; SOLICITED_FTM_RAW_MODE - As SOLICITED_MODE but messages from FTM
- - * and not NCI Host.
- + * and not NCI Host.
- *
- *
- *
- @@ -742,6 +801,61 @@ int nfc_ioctl_nfcc_mode(struct file *filp, unsigned int cmd, unsigned long arg)
- }
- /*
- + * Inside nfc_ioctl_nfcc_efuse
- + *
- + * @brief nfc_ioctl_nfcc_efuse
- + *
- + *
- + */
- +int nfc_ioctl_nfcc_efuse(struct file *filp, unsigned int cmd,
- + unsigned long arg)
- +{
- + int r = 0;
- + unsigned short slave_addr = 0xE;
- + unsigned short curr_addr;
- + unsigned char efuse_addr = EFUSE_REG;
- + unsigned char efuse_value = 0xFF;
- +
- + struct qca199x_dev *qca199x_dev = filp->private_data;
- +
- + curr_addr = qca199x_dev->client->addr;
- + qca199x_dev->client->addr = slave_addr;
- +
- + r = nfc_i2c_write(qca199x_dev->client,
- + &efuse_addr, 1);
- + if (r < 0) {
- + /* Restore original NFCC slave I2C address */
- + qca199x_dev->client->addr = curr_addr;
- + dev_err(&qca199x_dev->client->dev,
- + "ERROR_WRITE_FAIL : i2c write fail\n");
- + return -EIO;
- + }
- +
- + /*
- + * NFCC chip needs to be at least
- + * 10usec high before make it low
- + */
- + usleep_range(10, 15);
- +
- + r = i2c_master_recv(qca199x_dev->client, &efuse_value,
- + sizeof(efuse_value));
- + if (r < 0) {
- + /* Restore original NFCC slave I2C address */
- + qca199x_dev->client->addr = curr_addr;
- + dev_err(&qca199x_dev->client->dev,
- + "ERROR_I2C_RCV_FAIL : i2c recv fail\n");
- + return -EIO;
- + }
- +
- + dev_dbg(&qca199x_dev->client->dev, "%s : EFUSE_VALUE %02x\n",
- + __func__, efuse_value);
- +
- + /* Restore original NFCC slave I2C address */
- + qca199x_dev->client->addr = curr_addr;
- + return efuse_value;
- +}
- +
- +/*
- * Inside nfc_ioctl_nfcc_version
- *
- * @brief nfc_ioctl_nfcc_version
- @@ -752,11 +866,8 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd,
- unsigned long arg)
- {
- int r = 0;
- - int time_taken = 0;
- - unsigned short slave_addr = 0xE;
- + unsigned short slave_addr = 0xE;
- unsigned short curr_addr;
- - unsigned char raw_nci_wake[] = {0x10, 0x0F};
- - unsigned char raw_nci_read;
- unsigned char raw_chip_version_addr = 0x00;
- unsigned char raw_chip_rev_id_addr = 0x9C;
- unsigned char raw_chip_version = 0xFF;
- @@ -770,88 +881,56 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd,
- * Always wake up chip when reading 0x9C, otherwise this
- * register is not updated
- */
- + r = nfcc_wake(NFCC_WAKE, filp);
- curr_addr = qca199x_dev->client->addr;
- qca199x_dev->client->addr = slave_addr;
- - r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0],
- - sizeof(raw_nci_wake));
- -
- - if (r != sizeof(raw_nci_wake))
- - dev_err(&qca199x_dev->client->dev,
- - "nfc_ioctl_nfcc_version : failed to send wake command\n");
- -
- - /*
- - * After placing the NFCC to sleep by a PROP
- - * SLEEP NCI msg (2F 03) and we need to wake
- - * it back up to obtain some information (by
- - * setting the wake bit).We need to determine
- - * when it has in actual fact woken before we
- - * can read the required data. We do that by
- - * reading back & testing if that wake bit has
- - * been cleared.
- - */
- - do {
- - raw_nci_read = 0x10;
- - r = nfc_i2c_write(qca199x_dev->client, &raw_nci_read, 1);
- - /*
- - * NFCC chip needs to be at least
- - * 10usec high before make it low
- - */
- - usleep_range(10, 15);
- -
- - r = i2c_master_recv(qca199x_dev->client, &raw_nci_read,
- - sizeof(raw_nci_read));
- -
- - if ((raw_nci_read & NCI_WAKE) != 0)
- - /* NFCC wakeup time is between 0.5 and .52 ms */
- - usleep_range(500, 520);
- -
- - time_taken++;
- -
- - } while ((raw_nci_read & NCI_WAKE)
- - && (time_taken < WAKE_TIMEOUT));
- -
- - if (time_taken < WAKE_TIMEOUT)
- - qca199x_dev->state = NFCC_STATE_NORMAL_WAKE;
- - else
- - dev_err(&qca199x_dev->client->dev,
- - "nfc_ioctl_nfcc_version : TIMED OUT to get WAKEUP bit\n");
- - if (r != 1) {
- - /*
- - * r < 0 indicates an error, maybe chip isn't
- - * up yet.What should we do??? r = 0 indicates
- - * nothing read, maybe chip isn't up yet. (should
- - * not happen) r > 1 indicates too many bytes read,
- - * maybe ?(should not happen)
- - */
- + if (r) {
- dev_err(&qca199x_dev->client->dev,
- - "nfc_ioctl_nfcc_version : i2c error %d\n", r);
- + "%s: nfcc wake failed: %d\n", __func__, r);
- + r = -EIO;
- + goto leave;
- }
- if (arg == 0) {
- r = nfc_i2c_write(qca199x_dev->client,
- - &raw_chip_version_addr, 1);
- + &raw_chip_version_addr, sizeof(raw_chip_version_addr));
- + if (r != sizeof(raw_chip_version_addr)) {
- + r = -EMSGSIZE;
- + goto err;
- + }
- } else if (arg == 1) {
- r = nfc_i2c_write(qca199x_dev->client,
- - &raw_chip_rev_id_addr, 1);
- + &raw_chip_rev_id_addr, sizeof(raw_chip_rev_id_addr));
- + if (r != sizeof(raw_chip_version_addr)) {
- + r = -EMSGSIZE;
- + goto err;
- + }
- } else {
- - /* Restore original NFCC slave I2C address */
- - qca199x_dev->client->addr = curr_addr;
- - return -EINVAL;
- + r = -EINVAL;
- + goto err;
- }
- if (r < 0) {
- - /* Restore original NFCC slave I2C address */
- - qca199x_dev->client->addr = curr_addr;
- - dev_err(&qca199x_dev->client->dev,
- - "NFCC_INVALID_CHIP_VERSION : i2c write fail\n");
- - return -EIO;
- + r = -EIO;
- + goto err;
- }
- -
- - usleep(10);
- - r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1);
- -
- + /*
- + * I2C line is low after ~10 usec
- + */
- + usleep_range(10, 15);
- + r = i2c_master_recv(qca199x_dev->client, &raw_chip_version,
- + sizeof(raw_chip_version));
- + if (r != sizeof(raw_chip_version)) {
- + r = -EMSGSIZE;
- + goto err;
- + }
- + goto leave;
- +err:
- + dev_err(&qca199x_dev->client->dev,
- + "%s: i2c access failed\n", __func__);
- +leave:
- /* Restore original NFCC slave I2C address */
- qca199x_dev->client->addr = curr_addr;
- return raw_chip_version;
- @@ -860,12 +939,12 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd,
- /*
- * Inside nfc_ioctl_kernel_logging
- *
- - * @brief nfc_ioctl_kernel_logging
- + * @brief nfc_ioctl_kernel_logging
- *
- * (arg = 0) ; NO_LOGGING
- * (arg = 1) ; COMMS_LOGGING - BASIC LOGGING - Mainly just comms over I2C
- * (arg = 2) ; FULL_LOGGING - ENABLE ALL - DBG messages for handlers etc.
- - * ; ! Be aware as amount of logging could impact behaviour !
- + * ; ! Be aware as amount of logging could impact behaviour !
- *
- *
- */
- @@ -873,19 +952,19 @@ int nfc_ioctl_kernel_logging(unsigned long arg, struct file *filp)
- {
- int retval = 0;
- struct qca199x_dev *qca199x_dev = container_of(filp->private_data,
- - struct qca199x_dev,
- - qca199x_device);
- + struct qca199x_dev,
- + qca199x_device);
- if (arg == 0) {
- dev_dbg(&qca199x_dev->client->dev,
- - "nfc_ioctl_kernel_logging : level = NO_LOGGING\n");
- + "%s : level = NO_LOGGING\n", __func__);
- logging_level = 0;
- } else if (arg == 1) {
- dev_dbg(&qca199x_dev->client->dev,
- - "nfc_ioctl_kernel_logging: level = COMMS_LOGGING only\n");
- + "%s: level = COMMS_LOGGING only\n", __func__);
- logging_level = 1;
- } else if (arg == 2) {
- dev_dbg(&qca199x_dev->client->dev,
- - "nfc_ioctl_kernel_logging: level = FULL_LOGGING\n");
- + "%s: level = FULL_LOGGING\n", __func__);
- logging_level = 2;
- }
- return retval;
- @@ -894,7 +973,7 @@ int nfc_ioctl_kernel_logging(unsigned long arg, struct file *filp)
- /*
- * Inside nfc_ioctl_core_reset_ntf
- *
- - * @brief nfc_ioctl_core_reset_ntf
- + * @brief nfc_ioctl_core_reset_ntf
- *
- * Allows callers to determine if a CORE_RESET_NTF has arrived
- *
- @@ -906,22 +985,23 @@ int nfc_ioctl_core_reset_ntf(struct file *filp, unsigned int cmd,
- {
- struct qca199x_dev *qca199x_dev = filp->private_data;
- dev_dbg(&qca199x_dev->client->dev,
- - "nfc_ioctl_core_reset_ntf: returning = %d\n",
- + "%s: returning = %d\n",
- + __func__,
- qca199x_dev->core_reset_ntf);
- return qca199x_dev->core_reset_ntf;
- }
- -static long nfc_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
- +static long nfc_ioctl(struct file *pfile, unsigned int cmd,
- + unsigned long arg)
- {
- int r = 0;
- -
- + struct qca199x_dev *qca199x_dev = pfile->private_data;
- switch (cmd) {
- -
- case NFC_SET_PWR:
- - nfc_ioctl_power_states(pfile, cmd, arg);
- + r = nfc_ioctl_power_states(pfile, cmd, arg);
- break;
- case NFCC_MODE:
- - nfc_ioctl_nfcc_mode(pfile, cmd, arg);
- + r = nfc_ioctl_nfcc_mode(pfile, cmd, arg);
- break;
- case NFCC_VERSION:
- r = nfc_ioctl_nfcc_version(pfile, cmd, arg);
- @@ -936,6 +1016,14 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
- case NFCC_INITIAL_CORE_RESET_NTF:
- r = nfc_ioctl_core_reset_ntf(pfile, cmd, arg);
- break;
- + case NFC_GET_EFUSE:
- + r = nfc_ioctl_nfcc_efuse(pfile, cmd, arg);
- + if (r < 0) {
- + r = 0xFF;
- + dev_err(&qca199x_dev->client->dev,
- + "nfc_ioctl : FAILED TO READ EFUSE TYPE\n");
- + }
- + break;
- default:
- r = -ENOIOCTLCMD;
- }
- @@ -968,9 +1056,15 @@ void dumpqca1990(struct i2c_client *client)
- ((i > 0xF) && (i < 0x12)) || ((i > 0x39) && (i < 0x4d)) ||
- ((i > 0x69) && (i < 0x74)) || (i == 0x18) || (i == 0x30) ||
- (i == 0x58)) {
- - r = nfc_i2c_write(client, &raw_reg_rd, 1);
- + r = nfc_i2c_write(client, &raw_reg_rd,
- + sizeof(raw_reg_rd));
- + if (r != sizeof(raw_reg_rd))
- + break;
- msleep(20);
- - r = i2c_master_recv(client, &raw_reg_rd, 1);
- + r = i2c_master_recv(client, &raw_reg_rd,
- + sizeof(raw_reg_rd));
- + if (r != sizeof(raw_reg_rd))
- + break;
- }
- }
- client->addr = temp_addr;
- @@ -981,11 +1075,11 @@ static int nfc_i2c_write(struct i2c_client *client, u8 *buf, int len)
- int r;
- r = i2c_master_send(client, buf, len);
- - dev_dbg(&client->dev, "send: %d\n", r);
- + dev_dbg(&client->dev, "%s: send: %d\n", __func__, r);
- if (r == -EREMOTEIO) { /* Retry, chip was in standby */
- usleep_range(6000, 10000);
- r = i2c_master_send(client, buf, len);
- - dev_dbg(&client->dev, "send2: %d\n", r);
- + dev_dbg(&client->dev, "%s: send attempt 2: %d\n", __func__, r);
- }
- if (r != len)
- return -EREMOTEIO;
- @@ -1001,22 +1095,23 @@ static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr)
- client->addr = curr_addr;
- /* Set-up Addr 0. No data written */
- - r = i2c_master_send(client, &buf, 1);
- + r = i2c_master_send(client, &buf, sizeof(buf));
- if (r < 0)
- goto err_presence_check;
- buf = 0;
- /* Read back from Addr 0 */
- - r = i2c_master_recv(client, &buf, 1);
- + r = i2c_master_recv(client, &buf, sizeof(buf));
- if (r < 0)
- goto err_presence_check;
- r = 0;
- - return r;
- + goto leave;
- err_presence_check:
- r = -ENXIO;
- dev_err(&client->dev,
- - "nfc-nci nfcc_presence check - no NFCC available\n");
- + "%s: - no NFCC available\n", __func__);
- +leave:
- return r;
- }
- /* Initialise qca199x_ NFC controller hardware */
- @@ -1024,7 +1119,7 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- struct qca199x_dev *qca199x_dev)
- {
- int r = 0;
- - unsigned char raw_1p8_CONTROL_011[] = {0x11, XTAL_CLOCK};
- + unsigned char raw_1P8_CONTROL_011[] = {0x11, XTAL_CLOCK};
- unsigned char raw_1P8_CONTROL_010[] = {0x10, PWR_EN};
- unsigned char raw_1P8_X0_0B0[] = {0xB0, (FREQ_SEL)};
- unsigned char raw_slave1[] = {0x09, NCI_I2C_SLAVE};
- @@ -1041,12 +1136,17 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- client->addr = curr_addr;
- qca199x_dev->core_reset_ntf = DEFAULT_INITIAL_CORE_RESET_NTF;
- - r = i2c_master_send(client, &buf, 1);
- + r = i2c_master_send(client, &buf, sizeof(buf));
- if (r < 0)
- goto err_init;
- + /*
- + * I2C line is low after ~10 usec
- + */
- + usleep_range(10, 15);
- +
- buf = 0;
- - r = i2c_master_recv(client, &buf, 1);
- + r = i2c_master_recv(client, &buf, sizeof(buf));
- if (r < 0)
- goto err_init;
- @@ -1056,36 +1156,37 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- if (r < 0)
- goto err_init;
- - usleep(1000);
- - RAW(1p8_CONTROL_011, XTAL_CLOCK | 0x01);
- + usleep_range(1000, 1100);
- - r = nfc_i2c_write(client, &raw_1p8_CONTROL_011[0],
- - sizeof(raw_1p8_CONTROL_011));
- + RAW(1P8_CONTROL_011, XTAL_CLOCK | 0x01);
- +
- + r = nfc_i2c_write(client, &raw_1P8_CONTROL_011[0],
- + sizeof(raw_1P8_CONTROL_011));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- RAW(1P8_CONTROL_010, (0x8));
- r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
- sizeof(raw_1P8_CONTROL_010));
- if (r < 0)
- goto err_init;
- - usleep(10000); /* 10ms wait */
- + usleep_range(10000, 11000); /* 10 ms wait */
- RAW(1P8_CONTROL_010, (0xC));
- r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
- sizeof(raw_1P8_CONTROL_010));
- if (r < 0)
- goto err_init;
- - usleep(100); /* 100uS wait */
- + usleep_range(100, 110); /* 100 us wait */
- RAW(1P8_X0_0B0, (FREQ_SEL_19));
- r = nfc_i2c_write(client, &raw_1P8_X0_0B0[0],
- sizeof(raw_1P8_X0_0B0));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- /* PWR_EN = 1 */
- RAW(1P8_CONTROL_010, (0xd));
- @@ -1095,7 +1196,7 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- goto err_init;
- - usleep(20000); /* 20ms wait */
- + msleep(20); /* 20ms wait */
- /* LS_EN = 1 */
- RAW(1P8_CONTROL_010, 0xF);
- r = nfc_i2c_write(client, &raw_1P8_CONTROL_010[0],
- @@ -1103,41 +1204,43 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- if (r < 0)
- goto err_init;
- - usleep(20000); /* 20ms wait */
- + msleep(20); /* 20ms wait */
- /* Enable the PMIC clock */
- RAW(1P8_PAD_CFG_CLK_REQ, (0x1));
- r = nfc_i2c_write(client, &raw_1P8_PAD_CFG_CLK_REQ[0],
- - sizeof(raw_1P8_PAD_CFG_CLK_REQ));
- + sizeof(raw_1P8_PAD_CFG_CLK_REQ));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- RAW(1P8_PAD_CFG_PWR_REQ, (0x1));
- r = nfc_i2c_write(client, &raw_1P8_PAD_CFG_PWR_REQ[0],
- - sizeof(raw_1P8_PAD_CFG_PWR_REQ));
- + sizeof(raw_1P8_PAD_CFG_PWR_REQ));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- RAW(slave2, 0x10);
- r = nfc_i2c_write(client, &raw_slave2[0], sizeof(raw_slave2));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- RAW(slave1, NCI_I2C_SLAVE);
- r = nfc_i2c_write(client, &raw_slave1[0], sizeof(raw_slave1));
- if (r < 0)
- goto err_init;
- - usleep(1000);
- + usleep_range(1000, 1100); /* 1 ms wait */
- /* QCA199x NFCC CPU should now boot... */
- - r = i2c_master_recv(client, &raw_slave1_rd, 1);
- + r = i2c_master_recv(client, &raw_slave1_rd, sizeof(raw_slave1_rd));
- + if (r < 0)
- + goto err_init;
- /* Talk on NCI slave address NCI_I2C_SLAVE 0x2C*/
- client->addr = NCI_I2C_SLAVE;
- @@ -1146,35 +1249,37 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr,
- * get a core reset notification - This is time for chip
- * & NFCC controller to come-up.
- */
- - usleep(15000); /* 15 ms */
- + usleep_range(15000, 16500); /* 15 ms */
- do {
- - ret = i2c_master_recv(client, rsp, 5);
- + ret = i2c_master_recv(client, rsp, sizeof(rsp));
- + if (ret < 0)
- + goto err_init;
- /* Found core reset notification */
- - if (((rsp[0] == CORE_RESET_RSP_GID) &&
- + if ((rsp[0] == CORE_RESET_RSP_GID) &&
- (rsp[1] == CORE_RESET_OID) &&
- - (rsp[2] == CORE_RST_NTF_LENGTH))
- - || time_taken == NTF_TIMEOUT) {
- + (rsp[2] == CORE_RST_NTF_LENGTH)) {
- dev_dbg(&client->dev,
- - "NFC core reset recevd: %s: info: %p\n",
- + "NFC core reset recvd: %s: info: %p\n",
- __func__, client);
- core_reset_completed = true;
- } else {
- - usleep(2000); /* 2ms sleep before retry */
- + usleep_range(2000, 2200); /* 2 ms wait before retry */
- }
- time_taken++;
- - } while (!core_reset_completed);
- - if (time_taken == NTF_TIMEOUT)
- + } while (!core_reset_completed && (time_taken < NTF_TIMEOUT));
- + if (time_taken >= NTF_TIMEOUT) {
- qca199x_dev->core_reset_ntf = TIMEDOUT_INITIAL_CORE_RESET_NTF;
- - else
- - qca199x_dev->core_reset_ntf = ARRIVED_INITIAL_CORE_RESET_NTF;
- + goto err_init;
- + }
- + qca199x_dev->core_reset_ntf = ARRIVED_INITIAL_CORE_RESET_NTF;
- r = 0;
- return r;
- err_init:
- r = 1;
- dev_err(&client->dev,
- - "nfc-nci nfcc_initialise: failed. Check Hardware\n");
- + "%s: failed. Check Hardware\n", __func__);
- return r;
- }
- /*
- @@ -1185,19 +1290,20 @@ static int qca199x_clock_select(struct qca199x_dev *qca199x_dev)
- int r = 0;
- if (!strcmp(qca199x_dev->clk_src_name, "BBCLK2")) {
- - qca199x_dev->s_clk =
- + qca199x_dev->s_clk =
- clk_get(&qca199x_dev->client->dev, "ref_clk");
- if (qca199x_dev->s_clk == NULL)
- goto err_invalid_dis_gpio;
- } else if (!strcmp(qca199x_dev->clk_src_name, "RFCLK3")) {
- - qca199x_dev->s_clk =
- + qca199x_dev->s_clk =
- clk_get(&qca199x_dev->client->dev, "ref_clk_rf");
- if (qca199x_dev->s_clk == NULL)
- goto err_invalid_dis_gpio;
- } else if (!strcmp(qca199x_dev->clk_src_name, "GPCLK")) {
- if (gpio_is_valid(qca199x_dev->clk_src_gpio)) {
- - qca199x_dev->s_clk =
- - clk_get(&qca199x_dev->client->dev, "core_clk");
- + qca199x_dev->s_clk =
- + clk_get(&qca199x_dev->client->dev,
- + "core_clk");
- if (qca199x_dev->s_clk == NULL)
- goto err_invalid_dis_gpio;
- } else {
- @@ -1205,8 +1311,9 @@ static int qca199x_clock_select(struct qca199x_dev *qca199x_dev)
- }
- } else if (!strcmp(qca199x_dev->clk_src_name, "GPCLK2")) {
- if (gpio_is_valid(qca199x_dev->clk_src_gpio)) {
- - qca199x_dev->s_clk =
- - clk_get(&qca199x_dev->client->dev, "core_clk_pvt");
- + qca199x_dev->s_clk =
- + clk_get(&qca199x_dev->client->dev,
- + "core_clk_pvt");
- if (qca199x_dev->s_clk == NULL)
- goto err_invalid_dis_gpio;
- } else {
- @@ -1282,7 +1389,7 @@ static int nfc_parse_dt(struct device *dev, struct qca199x_platform_data *pdata)
- }
- if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
- - (!strcmp(pdata->clk_src_name, "GPCLK2"))) {
- + (!strcmp(pdata->clk_src_name, "GPCLK2"))) {
- pdata->clk_src_gpio = of_get_named_gpio(np,
- "qcom,clk-src-gpio", 0);
- if ((!gpio_is_valid(pdata->clk_src_gpio)))
- @@ -1311,7 +1418,7 @@ static int qca199x_probe(struct i2c_client *client,
- sizeof(struct qca199x_platform_data), GFP_KERNEL);
- if (!platform_data) {
- dev_err(&client->dev,
- - "nfc-nci probe: Failed to allocate memory\n");
- + "%s: Failed to allocate memory\n", __func__);
- return -ENOMEM;
- }
- r = nfc_parse_dt(&client->dev, platform_data);
- @@ -1323,20 +1430,20 @@ static int qca199x_probe(struct i2c_client *client,
- if (!platform_data)
- return -EINVAL;
- dev_dbg(&client->dev,
- - "nfc-nci probe: %s, inside nfc-nci flags = %x\n",
- + "%s, inside nfc-nci flags = %x\n",
- __func__, client->flags);
- if (platform_data == NULL) {
- - dev_err(&client->dev, "nfc-nci probe: failed\n");
- + dev_err(&client->dev, "%s: failed\n", __func__);
- return -ENODEV;
- }
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- - dev_err(&client->dev, "nfc-nci probe: need I2C_FUNC_I2C\n");
- + dev_err(&client->dev, "%s: need I2C_FUNC_I2C\n", __func__);
- return -ENODEV;
- }
- qca199x_dev = kzalloc(sizeof(*qca199x_dev), GFP_KERNEL);
- if (qca199x_dev == NULL) {
- dev_err(&client->dev,
- - "nfc-nci probe: failed to allocate memory for module data\n");
- + "%s: failed to allocate memory for module data\n", __func__);
- return -ENOMEM;
- }
- qca199x_dev->client = client;
- @@ -1354,27 +1461,29 @@ static int qca199x_probe(struct i2c_client *client,
- r = gpio_request(platform_data->dis_gpio, "nfc_reset_gpio");
- if (r) {
- dev_err(&client->dev,
- - "NFC: unable to request gpio [%d]\n",
- + "%s: unable to request gpio [%d]\n",
- + __func__,
- platform_data->dis_gpio);
- goto err_free_dev;
- }
- r = gpio_direction_output(platform_data->dis_gpio, 1);
- if (r) {
- dev_err(&client->dev,
- - "NFC: unable to set direction for gpio [%d]\n",
- + "%s: unable to set direction for gpio [%d]\n",
- + __func__,
- platform_data->dis_gpio);
- goto err_dis_gpio;
- }
- } else {
- - dev_err(&client->dev, "dis gpio not provided\n");
- + dev_err(&client->dev, "%s: dis gpio not provided\n", __func__);
- goto err_free_dev;
- }
- /* Guarantee that the NFCC starts in a clean state. */
- gpio_set_value(platform_data->dis_gpio, 1);/* HPD */
- - usleep(200);
- + usleep_range(200, 220);
- gpio_set_value(platform_data->dis_gpio, 0);/* ULPM */
- - usleep(200);
- + usleep_range(200, 220);
- r = nfcc_hw_check(client, platform_data->reg);
- if (r) {
- @@ -1386,7 +1495,8 @@ static int qca199x_probe(struct i2c_client *client,
- if (gpio_is_valid(platform_data->irq_gpio)) {
- r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
- if (r) {
- - dev_err(&client->dev, "unable to request gpio [%d]\n",
- + dev_err(&client->dev, "%s: unable to request gpio [%d]\n",
- + __func__,
- platform_data->irq_gpio);
- goto err_dis_gpio;
- }
- @@ -1394,7 +1504,8 @@ static int qca199x_probe(struct i2c_client *client,
- if (r) {
- dev_err(&client->dev,
- - "unable to set direction for gpio [%d]\n",
- + "%s: unable to set direction for gpio [%d]\n",
- + __func__,
- platform_data->irq_gpio);
- goto err_irq;
- }
- @@ -1406,7 +1517,7 @@ static int qca199x_probe(struct i2c_client *client,
- client->irq = irqn;
- } else {
- - dev_err(&client->dev, "irq gpio not provided\n");
- + dev_err(&client->dev, "%s: irq gpio not provided\n", __func__);
- goto err_dis_gpio;
- }
- /* Interrupt from NFCC CLK_REQ to handle REF_CLK
- @@ -1417,7 +1528,9 @@ static int qca199x_probe(struct i2c_client *client,
- r = gpio_request(platform_data->irq_gpio_clk_req,
- "nfc_irq_gpio_clk_en");
- if (r) {
- - dev_err(&client->dev, "unable to request CLK_EN gpio [%d]\n",
- + dev_err(&client->dev,
- + "%s: unable to request CLK_EN gpio [%d]\n",
- + __func__,
- platform_data->irq_gpio_clk_req);
- goto err_irq;
- }
- @@ -1425,8 +1538,8 @@ static int qca199x_probe(struct i2c_client *client,
- platform_data->irq_gpio_clk_req);
- if (r) {
- dev_err(&client->dev,
- - "unable to set direction for CLK_EN gpio [%d]\n",
- - platform_data->irq_gpio_clk_req);
- + "%s: cannot set direction CLK_EN gpio [%d]\n",
- + __func__, platform_data->irq_gpio_clk_req);
- goto err_irq_clk;
- }
- gpio_to_irq(0);
- @@ -1437,7 +1550,8 @@ static int qca199x_probe(struct i2c_client *client,
- }
- platform_data->clk_req_irq_num = irqn;
- } else {
- - dev_err(&client->dev, "irq CLK_EN gpio not provided\n");
- + dev_err(&client->dev,
- + "%s: irq CLK_EN gpio not provided\n", __func__);
- goto err_irq;
- }
- }
- @@ -1458,19 +1572,21 @@ static int qca199x_probe(struct i2c_client *client,
- r = gpio_request(platform_data->clkreq_gpio,
- "nfc_clkreq_gpio");
- if (r) {
- - dev_err(&client->dev, "unable to request gpio [%d]\n",
- - platform_data->clkreq_gpio);
- + dev_err(&client->dev,
- + "%s: unable to request gpio [%d]\n",
- + __func__, platform_data->clkreq_gpio);
- goto err_clkreq_gpio;
- }
- r = gpio_direction_input(platform_data->clkreq_gpio);
- if (r) {
- dev_err(&client->dev,
- - "unable to set direction for gpio [%d]\n",
- - platform_data->clkreq_gpio);
- + "%s: cannot set direction for gpio [%d]\n",
- + __func__, platform_data->clkreq_gpio);
- goto err_clkreq_gpio;
- }
- } else {
- - dev_err(&client->dev, "clkreq gpio not provided\n");
- + dev_err(&client->dev,
- + "%s: clkreq gpio not provided\n", __func__);
- goto err_clk;
- }
- qca199x_dev->clkreq_gpio = platform_data->clkreq_gpio;
- @@ -1497,7 +1613,7 @@ static int qca199x_probe(struct i2c_client *client,
- r = misc_register(&qca199x_dev->qca199x_device);
- if (r) {
- - dev_err(&client->dev, "misc_register failed\n");
- + dev_err(&client->dev, "%s: misc_register failed\n", __func__);
- goto err_misc_register;
- }
- @@ -1534,7 +1650,7 @@ static int qca199x_probe(struct i2c_client *client,
- r = request_irq(client->irq, qca199x_dev_irq_handler,
- IRQF_TRIGGER_RISING, client->name, qca199x_dev);
- if (r) {
- - dev_err(&client->dev, "nfc-nci probe: request_irq failed\n");
- + dev_err(&client->dev, "%s: request_irq failed\n", __func__);
- goto err_request_irq_failed;
- }
- qca199x_disable_irq(qca199x_dev);
- @@ -1547,7 +1663,8 @@ static int qca199x_probe(struct i2c_client *client,
- client->name, qca199x_dev);
- if (r) {
- dev_err(&client->dev,
- - "nfc-nci probe: request_irq failed. irq no = %d\n, main irq = %d",
- + "%s: request_irq failed. irq no = %d\n, main irq = %d",
- + __func__,
- qca199x_dev->clk_req_irq_num, client->irq);
- goto err_request_irq_failed;
- }
- @@ -1563,6 +1680,8 @@ static int qca199x_probe(struct i2c_client *client,
- INIT_WORK(&qca199x_dev->msm_clock_controll_work,
- clk_req_update);
- }
- + device_init_wakeup(&client->dev, true);
- + device_set_wakeup_capable(&client->dev, true);
- i2c_set_clientdata(client, qca199x_dev);
- gpio_set_value(platform_data->dis_gpio, 1);
- @@ -1570,13 +1689,13 @@ static int qca199x_probe(struct i2c_client *client,
- region2_sent = false;
- dev_dbg(&client->dev,
- - "nfc-nci probe: %s, probing qca1990 exited successfully\n",
- + "%s: probing qca1990 exited successfully\n",
- __func__);
- return 0;
- err_create_workq:
- dev_err(&client->dev,
- - "nfc-nci probe: %s, work_queue creation failure\n",
- + "%s: work_queue creation failure\n",
- __func__);
- free_irq(client->irq, qca199x_dev);
- err_nfcc_not_present:
- @@ -1594,7 +1713,8 @@ err_irq_clk:
- (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
- r = gpio_direction_input(platform_data->irq_gpio_clk_req);
- if (r)
- - dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
- + dev_err(&client->dev,
- + "%s: Unable to set direction\n", __func__);
- gpio_free(platform_data->irq_gpio_clk_req);
- }
- err_irq:
- @@ -1627,11 +1747,33 @@ static int qca199x_remove(struct i2c_client *client)
- return 0;
- }
- +static int qca199x_suspend(struct device *device)
- +{
- + struct i2c_client *client = to_i2c_client(device);
- +
- + if (device_may_wakeup(&client->dev))
- + enable_irq_wake(client->irq);
- + return 0;
- +}
- +
- +static int qca199x_resume(struct device *device)
- +{
- + struct i2c_client *client = to_i2c_client(device);
- +
- + if (device_may_wakeup(&client->dev))
- + disable_irq_wake(client->irq);
- + return 0;
- +}
- +
- static const struct i2c_device_id qca199x_id[] = {
- {"qca199x-i2c", 0},
- {}
- };
- +static const struct dev_pm_ops nfc_pm_ops = {
- + SET_SYSTEM_SLEEP_PM_OPS(qca199x_suspend, qca199x_resume)
- +};
- +
- static struct i2c_driver qca199x = {
- .id_table = qca199x_id,
- .probe = qca199x_probe,
- @@ -1640,12 +1782,13 @@ static struct i2c_driver qca199x = {
- .owner = THIS_MODULE,
- .name = "nfc-nci",
- .of_match_table = msm_match_table,
- + .pm = &nfc_pm_ops,
- },
- };
- static int nfcc_reboot(struct notifier_block *notifier, unsigned long val,
- - void *v)
- + void *v)
- {
- /*
- * Set DISABLE=1 *ONLY* if the NFC service has been disabled.
- diff --git a/drivers/nfc/nfc-nci.h b/drivers/nfc/nfc-nci.h
- index 8186861..398fa3f 100644
- --- a/drivers/nfc/nfc-nci.h
- +++ b/drivers/nfc/nfc-nci.h
- @@ -60,6 +60,7 @@ struct devicemode {
- #define SET_RX_BLOCK _IOW(0xE9, 0x04, unsigned int)
- #define SET_EMULATOR_TEST_POINT _IOW(0xE9, 0x05, unsigned int)
- #define NFCC_VERSION _IOW(0xE9, 0x08, unsigned int)
- +#define NFC_GET_EFUSE _IOW(0xE9, 0x09, unsigned int)
- #define NFCC_INITIAL_CORE_RESET_NTF _IOW(0xE9, 0x10, unsigned int)
- #define NFC_MAX_I2C_TRANSFER (0x0400)
- diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
- index 211e5cc..4b36555 100644
- --- a/drivers/power/qpnp-bms.c
- +++ b/drivers/power/qpnp-bms.c
- @@ -142,7 +142,9 @@ struct fcc_sample {
- struct bms_irq {
- unsigned int irq;
- unsigned long disabled;
- + unsigned long wake_enabled;
- bool ready;
- + bool is_wake;
- };
- struct bms_wakeup_source {
- @@ -455,6 +457,9 @@ static void enable_bms_irq(struct bms_irq *irq)
- if (irq->ready && __test_and_clear_bit(0, &irq->disabled)) {
- enable_irq(irq->irq);
- pr_debug("enabled irq %d\n", irq->irq);
- + if ((irq->is_wake) &&
- + !__test_and_set_bit(0, &irq->wake_enabled))
- + enable_irq_wake(irq->irq);
- }
- }
- @@ -463,6 +468,9 @@ static void disable_bms_irq(struct bms_irq *irq)
- if (irq->ready && !__test_and_set_bit(0, &irq->disabled)) {
- disable_irq(irq->irq);
- pr_debug("disabled irq %d\n", irq->irq);
- + if ((irq->is_wake) &&
- + __test_and_clear_bit(0, &irq->wake_enabled))
- + disable_irq_wake(irq->irq);
- }
- }
- @@ -471,6 +479,9 @@ static void disable_bms_irq_nosync(struct bms_irq *irq)
- if (irq->ready && !__test_and_set_bit(0, &irq->disabled)) {
- disable_irq_nosync(irq->irq);
- pr_debug("disabled irq %d\n", irq->irq);
- + if ((irq->is_wake) &&
- + __test_and_clear_bit(0, &irq->wake_enabled))
- + disable_irq_wake(irq->irq);
- }
- }
- @@ -2369,7 +2380,6 @@ skip_limits:
- rc_new_uah = (params->fcc_uah * pc_new) / 100;
- soc_new = (rc_new_uah - params->cc_uah - params->uuc_uah)*100
- / (params->fcc_uah - params->uuc_uah);
- - soc_new = bound_soc(soc_new);
- /*
- * if soc_new is ZERO force it higher so that phone doesnt report soc=0
- @@ -2684,6 +2694,8 @@ static int calculate_state_of_charge(struct qpnp_bms_chip *chip,
- /* always clamp soc due to BMS hw/sw immaturities */
- new_calculated_soc = clamp_soc_based_on_voltage(chip,
- new_calculated_soc);
- +
- + new_calculated_soc = bound_soc(new_calculated_soc);
- /*
- * If the battery is full, configure the cc threshold so the system
- * wakes up after SoC changes
- @@ -4507,11 +4519,11 @@ static int bms_request_irqs(struct qpnp_bms_chip *chip)
- int rc;
- SPMI_REQUEST_IRQ(chip, rc, sw_cc_thr);
- + chip->sw_cc_thr_irq.is_wake = true;
- disable_bms_irq(&chip->sw_cc_thr_irq);
- - enable_irq_wake(chip->sw_cc_thr_irq.irq);
- SPMI_REQUEST_IRQ(chip, rc, ocv_thr);
- + chip->ocv_thr_irq.is_wake = true;
- disable_bms_irq(&chip->ocv_thr_irq);
- - enable_irq_wake(chip->ocv_thr_irq.irq);
- return 0;
- }
- diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
- index 8b084e4..3029744 100644
- --- a/drivers/power/qpnp-charger.c
- +++ b/drivers/power/qpnp-charger.c
- @@ -10,11 +10,7 @@
- * GNU General Public License for more details.
- *
- */
- -#if defined(CONFIG_BATTERY_SAMSUNG)
- -#define pr_fmt(fmt) "qpnp-chg: %s: " fmt, __func__
- -#else
- #define pr_fmt(fmt) "%s: " fmt, __func__
- -#endif
- #include <linux/module.h>
- #include <linux/slab.h>
- @@ -39,16 +35,6 @@
- #include <linux/gpio.h>
- #include <linux/of_gpio.h>
- #include <linux/qpnp/pin.h>
- -#if defined(CONFIG_BATTERY_SAMSUNG)
- -#include <linux/battery/sec_charger.h>
- -#endif
- -#if defined(CONFIG_USB_SWITCH_RT8973)
- -#include <linux/platform_data/rt8973.h>
- -#endif
- -
- -#if defined(CONFIG_USB_SWITCH_RT8973)
- -extern int rt_uart_connecting;
- -#endif
- /* Interrupt offsets */
- #define INT_RT_STS(base) (base + 0x10)
- @@ -243,6 +229,7 @@ struct qpnp_chg_irq {
- int irq;
- unsigned long disabled;
- unsigned long wake_enable;
- + bool is_wake;
- };
- struct qpnp_chg_regulator {
- @@ -320,9 +307,7 @@ struct qpnp_chg_chip {
- struct qpnp_chg_irq chg_fastchg;
- struct qpnp_chg_irq chg_trklchg;
- struct qpnp_chg_irq chg_failed;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct qpnp_chg_irq chg_vbatdet_lo;
- - #endif
- struct qpnp_chg_irq batt_pres;
- struct qpnp_chg_irq batt_temp_ok;
- struct qpnp_chg_irq coarse_det_usb;
- @@ -383,37 +368,24 @@ struct qpnp_chg_chip {
- struct power_supply dc_psy;
- struct power_supply *usb_psy;
- struct power_supply *bms_psy;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct power_supply batt_psy;
- - #endif
- uint32_t flags;
- struct qpnp_adc_tm_btm_param adc_param;
- struct work_struct adc_measure_work;
- struct work_struct adc_disable_work;
- struct delayed_work arb_stop_work;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - struct delayed_work usbin_valid_work;
- - #endif
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct delayed_work eoc_work;
- - #endif
- struct delayed_work usbin_health_check;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct work_struct soc_check_work;
- - #endif
- struct delayed_work aicl_check_work;
- struct work_struct insertion_ocv_work;
- struct work_struct ocp_clear_work;
- struct qpnp_chg_regulator flash_wa_vreg;
- struct qpnp_chg_regulator otg_vreg;
- struct qpnp_chg_regulator boost_vreg;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct qpnp_chg_regulator batfet_vreg;
- - #endif
- bool batfet_ext_en;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- struct work_struct batfet_lcl_work;
- - #endif
- struct qpnp_vadc_chip *vadc_dev;
- struct qpnp_iadc_chip *iadc_dev;
- struct qpnp_adc_tm_chip *adc_tm_dev;
- @@ -476,7 +448,6 @@ module_param(ext_ovp_isns_present, int, 0444);
- static int ext_ovp_isns_r;
- module_param(ext_ovp_isns_r, int, 0444);
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static bool ext_ovp_isns_online;
- static long ext_ovp_isns_ua;
- #define MAX_CURRENT_LENGTH_9A 10
- @@ -546,7 +517,6 @@ static struct kernel_param_ops ext_ovp_en_ops = {
- };
- module_param_cb(ext_ovp_isns_online, &ext_ovp_en_ops,
- &ext_ovp_isns_online, 0664);
- -#endif
- static inline int
- get_bpd(const char *name)
- @@ -642,7 +612,6 @@ qpnp_chg_masked_write(struct qpnp_chg_chip *chip, u16 base,
- return 0;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static void
- qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
- {
- @@ -650,6 +619,10 @@ qpnp_chg_enable_irq(struct qpnp_chg_irq *irq)
- pr_debug("number = %d\n", irq->irq);
- enable_irq(irq->irq);
- }
- + if ((irq->is_wake) && (!__test_and_set_bit(0, &irq->wake_enable))) {
- + pr_debug("enable wake, number = %d\n", irq->irq);
- + enable_irq_wake(irq->irq);
- + }
- }
- static void
- @@ -659,8 +632,11 @@ qpnp_chg_disable_irq(struct qpnp_chg_irq *irq)
- pr_debug("number = %d\n", irq->irq);
- disable_irq_nosync(irq->irq);
- }
- + if ((irq->is_wake) && (__test_and_clear_bit(0, &irq->wake_enable))) {
- + pr_debug("disable wake, number = %d\n", irq->irq);
- + disable_irq_wake(irq->irq);
- + }
- }
- -#endif
- static void
- qpnp_chg_irq_wake_enable(struct qpnp_chg_irq *irq)
- @@ -669,6 +645,7 @@ qpnp_chg_irq_wake_enable(struct qpnp_chg_irq *irq)
- pr_debug("number = %d\n", irq->irq);
- enable_irq_wake(irq->irq);
- }
- + irq->is_wake = true;
- }
- static void
- @@ -678,6 +655,7 @@ qpnp_chg_irq_wake_disable(struct qpnp_chg_irq *irq)
- pr_debug("number = %d\n", irq->irq);
- disable_irq_wake(irq->irq);
- }
- + irq->is_wake = false;
- }
- #define USB_OTG_EN_BIT BIT(0)
- @@ -869,13 +847,8 @@ qpnp_chg_check_usbin_health(struct qpnp_chg_chip *chip)
- return rc;
- }
- - #if defined(CONFIG_BATTERY_SAMSUNG)
- - pr_err("chgr usb sts 0x%x, chgpth rt sts 0x%x\n",
- - usbin_chg_rt_sts, usb_chgpth_rt_sts);
- - #else
- pr_debug("chgr usb sts 0x%x, chgpth rt sts 0x%x\n",
- usbin_chg_rt_sts, usb_chgpth_rt_sts);
- - #endif
- if ((usbin_chg_rt_sts & USB_COARSE_DET) == USB_COARSE_DET) {
- if ((usbin_chg_rt_sts & USB_VALID_MASK)
- == USB_VALID_OVP_VALUE) {
- @@ -1017,9 +990,6 @@ qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
- {
- int rc = 0;
- u8 usb_reg = 0, temp = 8;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - union power_supply_propval val;
- - #endif
- if (mA < 0 || mA > QPNP_CHG_I_MAX_MAX_MA) {
- pr_err("bad mA=%d asked to set\n", mA);
- @@ -1041,14 +1011,6 @@ qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
- /* Impose input current limit */
- if (chip->maxinput_usb_ma)
- mA = (chip->maxinput_usb_ma) <= mA ? chip->maxinput_usb_ma : mA;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - psy_do_property("qpnp-chg", get,
- - POWER_SUPPLY_PROP_CURRENT_MAX, val);
- - if (mA > val.intval && val.intval) {
- - pr_err("force set to %d mA (<= %d)\n", val.intval, mA);
- - mA = val.intval;
- - }
- - #endif
- usb_reg = mA / QPNP_CHG_I_MAXSTEP_MA;
- @@ -1061,11 +1023,7 @@ qpnp_chg_iusbmax_set(struct qpnp_chg_chip *chip, int mA)
- 0x0C, 0x0C, 1);
- }
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - pr_err("current=%d setting 0x%x\n", mA, usb_reg);
- - #else
- pr_debug("current=%d setting 0x%x\n", mA, usb_reg);
- - #endif
- rc = qpnp_chg_write(chip, &usb_reg,
- chip->usb_chgpth_base + CHGR_I_MAX_REG, 1);
- @@ -1276,16 +1234,10 @@ qpnp_chg_force_run_on_batt(struct qpnp_chg_chip *chip, int disable)
- /* Don't run on battery for batteryless hardware */
- if (chip->use_default_batt_values)
- return 0;
- -
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - /* Don't force on battery and allow charge if battery is not present*/
- - if (!disable && !qpnp_chg_is_batt_present(chip))
- - return 0;
- - #else
- /* Don't force on battery if battery is not present */
- if (!qpnp_chg_is_batt_present(chip))
- return 0;
- - #endif
- +
- /* This bit forces the charger to run off of the battery rather
- * than a connected charger */
- return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_CHG_CTRL,
- @@ -1415,7 +1367,6 @@ qpnp_bat_if_adc_disable_work(struct work_struct *work)
- }
- #define EOC_CHECK_PERIOD_MS 10000
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static irqreturn_t
- qpnp_chg_vbatdet_lo_irq_handler(int irq, void *_chip)
- {
- @@ -1449,7 +1400,6 @@ qpnp_chg_vbatdet_lo_irq_handler(int irq, void *_chip)
- }
- return IRQ_HANDLED;
- }
- -#endif
- #define ARB_STOP_WORK_MS 1000
- static irqreturn_t
- @@ -1608,7 +1558,6 @@ qpnp_chg_vddmax_and_trim_set(struct qpnp_chg_chip *chip,
- return 0;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- qpnp_chg_vddmax_get(struct qpnp_chg_chip *chip)
- {
- @@ -1623,7 +1572,6 @@ qpnp_chg_vddmax_get(struct qpnp_chg_chip *chip)
- return QPNP_CHG_V_MIN_MV + (int)vddmax * QPNP_CHG_V_STEP_MV;
- }
- -#endif
- /* JEITA compliance logic */
- static void
- @@ -1640,32 +1588,6 @@ qpnp_chg_set_appropriate_vddmax(struct qpnp_chg_chip *chip)
- chip->delta_vddmax_mv);
- }
- -#define MIN_DELTA_MV_TO_INCREASE_VDD_MAX 8
- -#define MAX_DELTA_VDD_MAX_MV 80
- -#define VDD_MAX_CENTER_OFFSET 4
- -static void
- -qpnp_chg_adjust_vddmax(struct qpnp_chg_chip *chip, int vbat_mv)
- -{
- - int delta_mv, closest_delta_mv, sign;
- -
- - delta_mv = chip->max_voltage_mv - VDD_MAX_CENTER_OFFSET - vbat_mv;
- - if (delta_mv > 0 && delta_mv < MIN_DELTA_MV_TO_INCREASE_VDD_MAX) {
- - pr_debug("vbat is not low enough to increase vdd\n");
- - return;
- - }
- -
- - sign = delta_mv > 0 ? 1 : -1;
- - closest_delta_mv = ((delta_mv + sign * QPNP_CHG_BUCK_TRIM1_STEP / 2)
- - / QPNP_CHG_BUCK_TRIM1_STEP) * QPNP_CHG_BUCK_TRIM1_STEP;
- - pr_debug("max_voltage = %d, vbat_mv = %d, delta_mv = %d, closest = %d\n",
- - chip->max_voltage_mv, vbat_mv,
- - delta_mv, closest_delta_mv);
- - chip->delta_vddmax_mv = clamp(chip->delta_vddmax_mv + closest_delta_mv,
- - -MAX_DELTA_VDD_MAX_MV, MAX_DELTA_VDD_MAX_MV);
- - pr_debug("using delta_vddmax_mv = %d\n", chip->delta_vddmax_mv);
- - qpnp_chg_set_appropriate_vddmax(chip);
- -}
- -
- static void
- qpnp_usbin_health_check_work(struct work_struct *work)
- {
- @@ -1685,10 +1607,8 @@ qpnp_usbin_health_check_work(struct work_struct *work)
- psy_health_sts = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- else if (usbin_health == USBIN_OK)
- psy_health_sts = POWER_SUPPLY_HEALTH_GOOD;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_set_health_state(chip->usb_psy, psy_health_sts);
- power_supply_changed(chip->usb_psy);
- - #endif
- }
- /* enable OVP monitor in usb valid after coarse-det complete */
- chip->usb_valid_check_ovp = true;
- @@ -1696,123 +1616,6 @@ qpnp_usbin_health_check_work(struct work_struct *work)
- return;
- }
- -#ifdef CONFIG_BATTERY_SAMSUNG
- -int wait_muic_event = 0;
- -
- -static void
- -sec_qpnp_usbin_valid_work(struct work_struct *work)
- -{
- - struct delayed_work *dwork = to_delayed_work(work);
- - struct qpnp_chg_chip *chip = container_of(dwork,
- - struct qpnp_chg_chip, usbin_valid_work);
- -
- - int usb_present, host_mode, usbin_health;
- - u8 psy_health_sts;
- -#ifdef CONFIG_BATTERY_SAMSUNG
- - union power_supply_propval value;
- -#endif
- -
- - usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
- - host_mode = qpnp_chg_is_otg_en_set(chip);
- -#ifdef CONFIG_BATTERY_SAMSUNG
- - pr_err("usbin-valid triggered: %d->%d host_mode: %d\n",
- - chip->usb_present, usb_present, host_mode);
- -#else
- - pr_debug("usbin-valid triggered: %d host_mode: %d\n",
- - usb_present, host_mode);
- -#endif
- -
- - if (chip->usb_present ^ usb_present) {
- - chip->usb_present = usb_present;
- - if (!usb_present) {
- - /* when a valid charger inserted, and increase the
- - * charger voltage to OVP threshold, then
- - * usb_in_valid falling edge interrupt triggers.
- - * So we handle the OVP monitor here, and ignore
- - * other health state changes */
- - if (chip->ovp_monitor_enable &&
- - (chip->usb_valid_check_ovp)) {
- - usbin_health =
- - qpnp_chg_check_usbin_health(chip);
- - if ((chip->usbin_health != usbin_health)
- - && (usbin_health == USBIN_OVP)) {
- - chip->usbin_health = usbin_health;
- - psy_health_sts =
- - POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - value.intval = psy_health_sts;
- - psy_do_property("battery", set,
- - POWER_SUPPLY_PROP_HEALTH, value);
- - pr_info("%s overvoltage detected \n",__func__);
- - #else
- - power_supply_set_health_state(
- - chip->usb_psy,
- - psy_health_sts);
- - power_supply_changed(chip->usb_psy);
- - #endif
- - }
- - }
- - if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- - chip->chg_done = false;
- - }
- - qpnp_chg_usb_suspend_enable(chip, 0);
- - qpnp_chg_iusbmax_set(chip, QPNP_CHG_I_MAX_MIN_100);
- - chip->prev_usb_max_ma = -EINVAL;
- - chip->aicl_settled = false;
- - wait_muic_event = 1;
- - pr_info("%s disconnected vbus \n",__func__);
- - } else {
- - /* when OVP clamped usbin, and then decrease
- - * the charger voltage to lower than the OVP
- - * threshold, a usbin_valid rising edge
- - * interrupt triggered. So we change the usb
- - * psy health state back to good */
- - if (chip->ovp_monitor_enable &&
- - (chip->usb_valid_check_ovp)) {
- - usbin_health =
- - qpnp_chg_check_usbin_health(chip);
- - if ((chip->usbin_health != usbin_health)
- - && (usbin_health == USBIN_OK)) {
- - chip->usbin_health = usbin_health;
- - psy_health_sts =
- - POWER_SUPPLY_HEALTH_GOOD;
- -
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - value.intval = psy_health_sts;
- - psy_do_property("battery", set,
- - POWER_SUPPLY_PROP_HEALTH, value);
- - #else
- - power_supply_set_health_state(
- - chip->usb_psy,
- - psy_health_sts);
- - power_supply_changed(chip->usb_psy);
- - #endif
- - }
- - }
- -
- - if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- - }
- - wait_muic_event = 0;
- - pr_info("%s connected vbus \n",__func__);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- - schedule_delayed_work(&chip->eoc_work,
- - msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
- - schedule_work(&chip->soc_check_work);
- - #endif
- - }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- - power_supply_set_present(chip->usb_psy, chip->usb_present);
- - schedule_work(&chip->batfet_lcl_work);
- - #endif
- - }
- -
- -}
- -#endif
- -
- #define USB_VALID_DEBOUNCE_TIME_MASK 0x3
- #define USB_DEB_BYPASS 0x0
- #define USB_DEB_5MS 0x1
- @@ -1866,18 +1669,15 @@ qpnp_chg_coarse_det_usb_irq_handler(int irq, void *_chip)
- status to unknown */
- pr_debug("usb coarse det clear, set usb health to unknown\n");
- chip->usbin_health = USBIN_UNKNOW;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_set_health_state(chip->usb_psy,
- POWER_SUPPLY_HEALTH_UNKNOWN);
- power_supply_changed(chip->usb_psy);
- - #endif
- }
- }
- return IRQ_HANDLED;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- #define BATFET_LPM_MASK 0xC0
- #define BATFET_LPM 0x40
- #define BATFET_NO_LPM 0x00
- @@ -1902,42 +1702,11 @@ qpnp_chg_regulator_batfet_set(struct qpnp_chg_chip *chip, bool enable)
- return rc;
- }
- -#endif
- #define USB_WALL_THRESHOLD_MA 500
- #define ENUM_T_STOP_BIT BIT(0)
- #define USB_5V_UV 5000000
- #define USB_9V_UV 9000000
- -
- -#ifdef CONFIG_BATTERY_SAMSUNG
- -#define USBIN_VALID_WORK_MS 500
- -
- -static irqreturn_t
- -qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
- -{
- - struct qpnp_chg_chip *chip = _chip;
- - int usb_present, host_mode;
- -
- - usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
- - host_mode = qpnp_chg_is_otg_en_set(chip);
- -#ifdef CONFIG_BATTERY_SAMSUNG
- - pr_err("usbin-valid triggered: %d->%d host_mode: %d\n",
- - chip->usb_present, usb_present, host_mode);
- -#else
- - pr_debug("usbin-valid triggered: %d host_mode: %d\n",
- - usb_present, host_mode);
- -#endif
- -
- - /* In host mode notifications cmoe from USB supply */
- - if (host_mode)
- - return IRQ_HANDLED;
- -
- - schedule_delayed_work(&chip->usbin_valid_work,
- - msecs_to_jiffies(USBIN_VALID_WORK_MS));
- -
- - return IRQ_HANDLED;
- -}
- -#else
- static irqreturn_t
- qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
- {
- @@ -1947,13 +1716,8 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
- usb_present = qpnp_chg_is_usb_chg_plugged_in(chip);
- host_mode = qpnp_chg_is_otg_en_set(chip);
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - pr_err("usbin-valid triggered: %d->%d host_mode: %d\n",
- - chip->usb_present, usb_present, host_mode);
- - #else
- pr_debug("usbin-valid triggered: %d host_mode: %d\n",
- usb_present, host_mode);
- - #endif
- /* In host mode notifications cmoe from USB supply */
- if (host_mode)
- @@ -1977,19 +1741,14 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
- chip->usbin_health = usbin_health;
- psy_health_sts =
- POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_set_health_state(
- chip->usb_psy,
- psy_health_sts);
- power_supply_changed(chip->usb_psy);
- - #endif
- }
- }
- - if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- + if (!qpnp_chg_is_dc_chg_plugged_in(chip))
- chip->chg_done = false;
- - }
- if (!qpnp_is_dc_higher_prio(chip))
- qpnp_chg_idcmax_set(chip, chip->maxinput_dc_ma);
- @@ -2013,36 +1772,25 @@ qpnp_chg_usb_usbin_valid_irq_handler(int irq, void *_chip)
- chip->usbin_health = usbin_health;
- psy_health_sts =
- POWER_SUPPLY_HEALTH_GOOD;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_set_health_state(
- chip->usb_psy,
- psy_health_sts);
- power_supply_changed(chip->usb_psy);
- - #endif
- }
- }
- - if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- - }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- schedule_delayed_work(&chip->eoc_work,
- msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
- schedule_work(&chip->soc_check_work);
- - #endif
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- +
- power_supply_set_present(chip->usb_psy, chip->usb_present);
- schedule_work(&chip->batfet_lcl_work);
- - #endif
- }
- return IRQ_HANDLED;
- }
- -#endif
- -#ifndef CONFIG_BATTERY_SAMSUNG
- #define BUCK_VIN_LOOP_CMP_OVRD_MASK 0x30
- static int
- qpnp_chg_bypass_vchg_loop_debouncer(struct qpnp_chg_chip *chip, bool bypass)
- @@ -2083,7 +1831,6 @@ qpnp_chg_vchg_loop_debouncer_setting_get(struct qpnp_chg_chip *chip)
- return value & BUCK_VIN_LOOP_CMP_OVRD_MASK;
- }
- -#endif
- #define TEST_EN_SMBC_LOOP 0xE5
- #define IBAT_REGULATION_DISABLE BIT(2)
- @@ -2117,10 +1864,8 @@ qpnp_chg_bat_if_batt_temp_irq_handler(int irq, void *_chip)
- }
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- - #endif
- return IRQ_HANDLED;
- }
- @@ -2177,12 +1922,11 @@ qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
- qpnp_chg_charge_en(chip, 0);
- }
- chip->batt_present = batt_present;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- pr_debug("psy changed usb_psy\n");
- power_supply_changed(chip->usb_psy);
- - #endif
- +
- if ((chip->cool_bat_decidegc || chip->warm_bat_decidegc)
- && batt_present) {
- pr_debug("enabling vadc notifications\n");
- @@ -2192,13 +1936,6 @@ qpnp_chg_bat_if_batt_pres_irq_handler(int irq, void *_chip)
- schedule_work(&chip->adc_disable_work);
- pr_debug("disabling vadc notifications\n");
- }
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - {
- - union power_supply_propval val;
- - psy_do_property("battery", set,
- - POWER_SUPPLY_PROP_PRESENT, val);
- - }
- - #endif
- }
- return IRQ_HANDLED;
- @@ -2219,19 +1956,11 @@ qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
- qpnp_chg_force_run_on_batt(chip, !dc_present ? 1 : 0);
- if (!dc_present && (!qpnp_chg_is_usb_chg_plugged_in(chip) ||
- qpnp_chg_is_otg_en_set(chip))) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- chip->chg_done = false;
- } else {
- - if (!qpnp_chg_is_usb_chg_plugged_in(chip)) {
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- - }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- schedule_delayed_work(&chip->eoc_work,
- msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
- schedule_work(&chip->soc_check_work);
- - #endif
- }
- if (qpnp_is_dc_higher_prio(chip)) {
- @@ -2250,13 +1979,11 @@ qpnp_chg_dc_dcin_valid_irq_handler(int irq, void *_chip)
- }
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- pr_debug("psy changed dc_psy\n");
- power_supply_changed(&chip->dc_psy);
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- schedule_work(&chip->batfet_lcl_work);
- - #endif
- }
- return IRQ_HANDLED;
- @@ -2278,14 +2005,12 @@ qpnp_chg_chgr_chg_failed_irq_handler(int irq, void *_chip)
- if (rc)
- pr_err("Failed to write chg_fail clear bit!\n");
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (chip->bat_if_base) {
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- }
- pr_debug("psy changed usb_psy\n");
- power_supply_changed(chip->usb_psy);
- - #endif
- if (chip->dc_chgpth_base) {
- pr_debug("psy changed dc_psy\n");
- power_supply_changed(&chip->dc_psy);
- @@ -2301,12 +2026,11 @@ qpnp_chg_chgr_chg_trklchg_irq_handler(int irq, void *_chip)
- pr_debug("TRKL IRQ triggered\n");
- chip->chg_done = false;
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (chip->bat_if_base) {
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- }
- - #endif
- +
- return IRQ_HANDLED;
- }
- @@ -2345,6 +2069,7 @@ bypass_vbatdet_comp(struct qpnp_chg_chip *chip, bool bypass)
- pr_err("Failed to bypass vbatdet comp rc = %d\n", rc);
- return rc;
- }
- +
- return rc;
- }
- @@ -2360,13 +2085,10 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
- if (chip->fastchg_on ^ fastchg_on) {
- chip->fastchg_on = fastchg_on;
- -
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (chip->bat_if_base) {
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- }
- - #endif
- pr_debug("psy changed usb_psy\n");
- power_supply_changed(chip->usb_psy);
- @@ -2389,14 +2111,11 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
- qpnp_chg_set_appropriate_vbatdet(chip);
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (!chip->charging_disabled) {
- schedule_delayed_work(&chip->eoc_work,
- msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
- pm_stay_awake(chip->dev);
- }
- - #endif
- -
- if (chip->parallel_ovp_mode)
- switch_parallel_ovp_mode(chip, 1);
- @@ -2414,9 +2133,7 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
- }
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- qpnp_chg_enable_irq(&chip->chg_vbatdet_lo);
- - #endif
- return IRQ_HANDLED;
- }
- @@ -2435,7 +2152,6 @@ qpnp_dc_property_is_writeable(struct power_supply *psy,
- return 0;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- qpnp_batt_property_is_writeable(struct power_supply *psy,
- enum power_supply_property psp)
- @@ -2481,7 +2197,6 @@ qpnp_chg_buck_control(struct qpnp_chg_chip *chip, int enable)
- return rc;
- }
- -#endif
- static int
- switch_usb_to_charge_mode(struct qpnp_chg_chip *chip)
- @@ -2597,7 +2312,6 @@ static enum power_supply_property pm_power_props_mains[] = {
- POWER_SUPPLY_PROP_CURRENT_MAX,
- };
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static enum power_supply_property msm_batt_power_props[] = {
- POWER_SUPPLY_PROP_CHARGING_ENABLED,
- POWER_SUPPLY_PROP_STATUS,
- @@ -2626,17 +2340,14 @@ static enum power_supply_property msm_batt_power_props[] = {
- POWER_SUPPLY_PROP_CYCLE_COUNT,
- POWER_SUPPLY_PROP_VOLTAGE_OCV,
- };
- -#endif
- static char *pm_power_supplied_to[] = {
- "battery",
- };
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static char *pm_batt_supplied_to[] = {
- "bms",
- };
- -#endif
- static int charger_monitor;
- module_param(charger_monitor, int, 0644);
- @@ -2687,7 +2398,6 @@ qpnp_aicl_check_work(struct work_struct *work)
- ret.intval / 1000);
- qpnp_chg_iusbmax_set(chip, ret.intval / 1000);
- }
- - pr_err("charger_monitor is absent\n");
- } else {
- pr_debug("charger_monitor is present\n");
- }
- @@ -2847,7 +2557,6 @@ get_prop_current_now(struct qpnp_chg_chip *chip)
- return 0;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- get_prop_full_design(struct qpnp_chg_chip *chip)
- {
- @@ -2879,9 +2588,7 @@ get_prop_charge_full(struct qpnp_chg_chip *chip)
- return 0;
- }
- -#endif
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- get_prop_capacity(struct qpnp_chg_chip *chip)
- {
- @@ -2934,7 +2641,6 @@ get_prop_capacity(struct qpnp_chg_chip *chip)
- * from shutting down unecessarily */
- return DEFAULT_CAPACITY;
- }
- -#endif
- #define DEFAULT_TEMP 250
- #define MAX_TOLERABLE_BATT_TEMP_DDC 680
- @@ -2958,7 +2664,6 @@ get_prop_batt_temp(struct qpnp_chg_chip *chip)
- return (int)results.physical;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int get_prop_cycle_count(struct qpnp_chg_chip *chip)
- {
- union power_supply_propval ret = {0,};
- @@ -2968,7 +2673,6 @@ static int get_prop_cycle_count(struct qpnp_chg_chip *chip)
- POWER_SUPPLY_PROP_CYCLE_COUNT, &ret);
- return ret.intval;
- }
- -#endif
- static int get_prop_vchg_loop(struct qpnp_chg_chip *chip)
- {
- @@ -2992,7 +2696,6 @@ static int get_prop_online(struct qpnp_chg_chip *chip)
- return qpnp_chg_is_batfet_closed(chip);
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static void
- qpnp_batt_external_power_changed(struct power_supply *psy)
- {
- @@ -3039,7 +2742,8 @@ qpnp_batt_external_power_changed(struct power_supply *psy)
- OVP_USB_WALL_TRSH_MA);
- } else if (unlikely(
- ext_ovp_isns_present)) {
- - qpnp_chg_iusb_trim_set(chip, 0);
- + qpnp_chg_iusb_trim_set(chip,
- + chip->usb_trim_default);
- qpnp_chg_iusbmax_set(chip,
- IOVP_USB_WALL_TRSH_MA);
- } else {
- @@ -3162,7 +2866,6 @@ qpnp_batt_power_get_property(struct power_supply *psy,
- return 0;
- }
- -#endif
- #define BTC_CONFIG_ENABLED BIT(7)
- #define BTC_COLD BIT(1)
- @@ -3229,14 +2932,8 @@ qpnp_chg_ibatterm_set(struct qpnp_chg_chip *chip, int term_current)
- if (term_current < QPNP_CHG_ITERM_MIN_MA
- || term_current > QPNP_CHG_ITERM_MAX_MA) {
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - pr_err("bad mA=%d asked to set, so changed to %dmA\n",
- - term_current, QPNP_CHG_ITERM_MIN_MA);
- - term_current = QPNP_CHG_ITERM_MIN_MA;
- - #else
- pr_err("bad mA=%d asked to set\n", term_current);
- return -EINVAL;
- - #endif
- }
- temp = (term_current - QPNP_CHG_ITERM_MIN_MA)
- @@ -3259,9 +2956,6 @@ qpnp_chg_ibatmax_set(struct qpnp_chg_chip *chip, int chg_current)
- return -EINVAL;
- }
- temp = chg_current / QPNP_CHG_I_STEP_MA;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - pr_info("current=%d setting 0x%x\n", chg_current, temp);
- - #endif
- return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_IBAT_MAX,
- QPNP_CHG_I_MASK, temp, 1);
- }
- @@ -3395,6 +3089,17 @@ qpnp_chg_trim_ibat(struct qpnp_chg_chip *chip, u8 ibat_trim)
- IBAT_TRIM_HIGH_LIM))
- return;
- }
- +
- + if (chip->type == SMBBP) {
- + rc = qpnp_chg_masked_write(chip,
- + chip->buck_base + SEC_ACCESS,
- + 0xFF, 0xA5, 1);
- + if (rc) {
- + pr_err("failed to write SEC_ACCESS: %d\n", rc);
- + return;
- + }
- + }
- +
- ibat_trim |= IBAT_TRIM_GOOD_BIT;
- rc = qpnp_chg_write(chip, &ibat_trim,
- chip->buck_base + BUCK_CTRL_TRIM3, 1);
- @@ -3430,7 +3135,7 @@ qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
- if (!chip->ibat_calibration_enabled)
- return 0;
- - if (chip->type != SMBB)
- + if (chip->type != SMBB && chip->type != SMBBP)
- return 0;
- rc = qpnp_chg_read(chip, ®,
- @@ -3450,6 +3155,17 @@ qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
- pr_debug("Improper ibat_trim value=%x setting to value=%x\n",
- ibat_trim, IBAT_TRIM_MEAN);
- ibat_trim = IBAT_TRIM_MEAN;
- +
- + if (chip->type == SMBBP) {
- + rc = qpnp_chg_masked_write(chip,
- + chip->buck_base + SEC_ACCESS,
- + 0xFF, 0xA5, 1);
- + if (rc) {
- + pr_err("failed to write SEC_ACCESS: %d\n", rc);
- + return rc;
- + }
- + }
- +
- rc = qpnp_chg_masked_write(chip,
- chip->buck_base + BUCK_CTRL_TRIM3,
- IBAT_TRIM_OFFSET_MASK, ibat_trim, 1);
- @@ -3513,6 +3229,7 @@ qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
- return rc;
- }
- +
- #define BOOST_MIN_UV 4200000
- #define BOOST_MAX_UV 5500000
- #define BOOST_STEP_UV 50000
- @@ -3555,7 +3272,6 @@ qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
- return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static void
- qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
- {
- @@ -3572,7 +3288,6 @@ qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
- pr_err("Unsupported level selected %d\n", lvl_sel);
- }
- }
- -#endif
- /*
- * Increase the SMBB/SMBBP charger overtemp threshold to 150C while firing
- @@ -3714,13 +3429,12 @@ qpnp_chg_regulator_boost_enable(struct regulator_dev *rdev)
- /*
- * update battery status when charger is connected and state is full
- */
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (usb_present && (chip->chg_done
- || (get_batt_capacity(chip) == 100)
- || (get_prop_batt_status(chip) ==
- POWER_SUPPLY_STATUS_FULL)))
- power_supply_changed(&chip->batt_psy);
- - #endif
- +
- return rc;
- }
- @@ -3823,12 +3537,9 @@ qpnp_chg_regulator_boost_disable(struct regulator_dev *rdev)
- chip->chg_done = false;
- chip->resuming_charging = true;
- qpnp_chg_set_appropriate_vbatdet(chip);
- - }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- - else if (chip->chg_done) {
- + } else if (chip->chg_done) {
- power_supply_changed(&chip->batt_psy);
- }
- - #endif
- }
- if (ext_ovp_isns_present && chip->ext_ovp_ic_gpio_enabled) {
- @@ -3914,8 +3625,6 @@ static struct regulator_ops qpnp_chg_boost_reg_ops = {
- .list_voltage = qpnp_chg_regulator_boost_list_voltage,
- };
- -#define VBATDET_MAX_ERR_MV 50
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- qpnp_chg_bat_if_batfet_reg_enabled(struct qpnp_chg_chip *chip)
- {
- @@ -3998,6 +3707,32 @@ static struct regulator_ops qpnp_chg_batfet_vreg_ops = {
- .is_enabled = qpnp_chg_regulator_batfet_is_enabled,
- };
- +#define MIN_DELTA_MV_TO_INCREASE_VDD_MAX 8
- +#define MAX_DELTA_VDD_MAX_MV 80
- +#define VDD_MAX_CENTER_OFFSET 4
- +static void
- +qpnp_chg_adjust_vddmax(struct qpnp_chg_chip *chip, int vbat_mv)
- +{
- + int delta_mv, closest_delta_mv, sign;
- +
- + delta_mv = chip->max_voltage_mv - VDD_MAX_CENTER_OFFSET - vbat_mv;
- + if (delta_mv > 0 && delta_mv < MIN_DELTA_MV_TO_INCREASE_VDD_MAX) {
- + pr_debug("vbat is not low enough to increase vdd\n");
- + return;
- + }
- +
- + sign = delta_mv > 0 ? 1 : -1;
- + closest_delta_mv = ((delta_mv + sign * QPNP_CHG_BUCK_TRIM1_STEP / 2)
- + / QPNP_CHG_BUCK_TRIM1_STEP) * QPNP_CHG_BUCK_TRIM1_STEP;
- + pr_debug("max_voltage = %d, vbat_mv = %d, delta_mv = %d, closest = %d\n",
- + chip->max_voltage_mv, vbat_mv,
- + delta_mv, closest_delta_mv);
- + chip->delta_vddmax_mv = clamp(chip->delta_vddmax_mv + closest_delta_mv,
- + -MAX_DELTA_VDD_MAX_MV, MAX_DELTA_VDD_MAX_MV);
- + pr_debug("using delta_vddmax_mv = %d\n", chip->delta_vddmax_mv);
- + qpnp_chg_set_appropriate_vddmax(chip);
- +}
- +
- #define CONSECUTIVE_COUNT 3
- #define VBATDET_MAX_ERR_MV 50
- static void
- @@ -4094,8 +3829,6 @@ qpnp_eoc_work(struct work_struct *work)
- ? "cool" : "warm",
- qpnp_chg_vddmax_get(chip));
- }
- - chip->delta_vddmax_mv = 0;
- - qpnp_chg_set_appropriate_vddmax(chip);
- qpnp_chg_charge_en(chip, 0);
- /* sleep for a second before enabling */
- msleep(2000);
- @@ -4125,7 +3858,6 @@ stop_eoc:
- count = 0;
- pm_relax(chip->dev);
- }
- -#endif
- static void
- qpnp_chg_insertion_ocv_work(struct work_struct *work)
- @@ -4149,13 +3881,10 @@ qpnp_chg_insertion_ocv_work(struct work_struct *work)
- pr_debug("batfet sts = %02x, charge_en = %02x ocv = %d\n",
- bat_if_sts, charge_en, chip->insertion_ocv_uv);
- qpnp_chg_charge_en(chip, !chip->charging_disabled);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- pr_debug("psy changed batt_psy\n");
- power_supply_changed(&chip->batt_psy);
- - #endif
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static void
- qpnp_chg_soc_check_work(struct work_struct *work)
- {
- @@ -4164,7 +3893,6 @@ qpnp_chg_soc_check_work(struct work_struct *work)
- get_prop_capacity(chip);
- }
- -#endif
- #define HYSTERISIS_DECIDEGC 20
- static void
- @@ -4266,7 +3994,6 @@ qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
- pr_err("request ADC error\n");
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- #define MIN_COOL_TEMP -300
- #define MAX_WARM_TEMP 1000
- @@ -4328,7 +4055,6 @@ mutex_unlock:
- mutex_unlock(&chip->jeita_configure_lock);
- return rc;
- }
- -#endif
- #define POWER_STAGE_REDUCE_CHECK_PERIOD_SECONDS 20
- #define POWER_STAGE_REDUCE_MAX_VBAT_UV 3900000
- @@ -4505,7 +4231,6 @@ qpnp_chg_reduce_power_stage(struct qpnp_chg_chip *chip)
- }
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static void
- qpnp_chg_batfet_lcl_work(struct work_struct *work)
- {
- @@ -4524,7 +4249,6 @@ qpnp_chg_batfet_lcl_work(struct work_struct *work)
- }
- mutex_unlock(&chip->batfet_vreg_lock);
- }
- -#endif
- static void
- qpnp_chg_reduce_power_stage_work(struct work_struct *work)
- @@ -4575,7 +4299,6 @@ qpnp_dc_power_set_property(struct power_supply *psy,
- return rc;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- qpnp_batt_power_set_property(struct power_supply *psy,
- enum power_supply_property psp,
- @@ -4642,7 +4365,6 @@ qpnp_batt_power_set_property(struct power_supply *psy,
- power_supply_changed(&chip->batt_psy);
- return rc;
- }
- -#endif
- static int
- qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
- @@ -4679,25 +4401,6 @@ qpnp_chg_setup_flags(struct qpnp_chg_chip *chip)
- return 0;
- }
- -static void
- -sec_qpnp_chg_check_vddmax(struct qpnp_chg_chip *chip)
- -{
- - int rc;
- - u8 buck_sts = 0;
- - unsigned int batt_voltage;
- -
- - pr_info("%s \n",__func__);
- - batt_voltage = get_prop_battery_voltage_now(chip) / 1000;
- - rc = qpnp_chg_read(chip, &buck_sts, INT_RT_STS(chip->buck_base), 1);
- - if (!rc) {
- - if (buck_sts & VDD_LOOP_IRQ) {
- - qpnp_chg_adjust_vddmax(chip, batt_voltage);
- - }
- - } else {
- - pr_err("failed to read buck rc=%d\n", rc);
- - }
- -}
- -
- static int
- qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
- {
- @@ -4753,14 +4456,13 @@ qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
- return rc;
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- chip->chg_vbatdet_lo.irq = spmi_get_irq_byname(spmi,
- spmi_resource, "vbat-det-lo");
- if (chip->chg_vbatdet_lo.irq < 0) {
- pr_err("Unable to get fast-chg-on irq\n");
- return rc;
- }
- - #endif
- +
- rc |= devm_request_irq(chip->dev, chip->chg_failed.irq,
- qpnp_chg_chgr_chg_failed_irq_handler,
- IRQF_TRIGGER_RISING, "chg-failed", chip);
- @@ -4791,7 +4493,6 @@ qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
- return rc;
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- rc |= devm_request_irq(chip->dev,
- chip->chg_vbatdet_lo.irq,
- qpnp_chg_vbatdet_lo_irq_handler,
- @@ -4802,15 +4503,13 @@ qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
- chip->chg_vbatdet_lo.irq, rc);
- return rc;
- }
- - #endif
- +
- qpnp_chg_irq_wake_enable(&chip->chg_trklchg);
- qpnp_chg_irq_wake_enable(&chip->chg_failed);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- - qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
- qpnp_chg_irq_wake_enable(&chip->chg_vbatdet_lo);
- - #endif
- -
- + qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
- break;
- +
- case SMBB_BAT_IF_SUBTYPE:
- case SMBBP_BAT_IF_SUBTYPE:
- case SMBCL_BAT_IF_SUBTYPE:
- @@ -4963,7 +4662,6 @@ qpnp_chg_request_irqs(struct qpnp_chg_chip *chip)
- return rc;
- }
- -#ifndef CONFIG_BATTERY_SAMSUNG
- static int
- qpnp_chg_load_battery_data(struct qpnp_chg_chip *chip)
- {
- @@ -5003,7 +4701,6 @@ qpnp_chg_load_battery_data(struct qpnp_chg_chip *chip)
- return 0;
- }
- -#endif
- #define WDOG_EN_BIT BIT(7)
- static int
- @@ -5159,21 +4856,10 @@ qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
- reg = BAT_THM_EN;
- break;
- case BPD_TYPE_BAT_ID:
- -#if defined(CONFIG_USB_SWITCH_RT8973)
- - if (rt_check_jig_state() || rt_uart_connecting)
- - reg = !(BAT_ID_EN);
- - else
- -#endif
- - reg = BAT_ID_EN;
- + reg = BAT_ID_EN;
- break;
- case BPD_TYPE_BAT_THM_BAT_ID:
- -#if defined(CONFIG_USB_SWITCH_RT8973)
- - if (rt_check_jig_state() || rt_uart_connecting)
- - reg = !(BAT_ID_EN);
- - else
- -#endif
- - reg = BAT_THM_EN | BAT_ID_EN;
- -
- + reg = BAT_THM_EN | BAT_ID_EN;
- break;
- default:
- reg = BAT_THM_EN;
- @@ -5198,7 +4884,6 @@ qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
- return rc;
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- init_data = of_get_regulator_init_data(chip->dev,
- spmi_resource->of_node);
- @@ -5224,7 +4909,6 @@ qpnp_chg_hwinit(struct qpnp_chg_chip *chip, u8 subtype,
- return rc;
- }
- }
- - #endif
- break;
- case SMBB_USB_CHGPTH_SUBTYPE:
- case SMBBP_USB_CHGPTH_SUBTYPE:
- @@ -5533,338 +5217,6 @@ qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
- return rc;
- }
- -#ifdef CONFIG_BATTERY_SAMSUNG
- -#define CHG_ON 1
- -#define CHG_OFF 0
- -#define INPUT_ON 0
- -#define INPUT_OFF 1
- -static void
- -sec_qpnp_chg_control(struct qpnp_chg_chip *chip,
- - int chg_en, int input_en)
- -{
- - pr_info("chg_en : %d, input_en : %d\n", chg_en, input_en);
- - qpnp_chg_usb_suspend_enable(chip, input_en);
- - qpnp_chg_charge_en(chip, chg_en);
- - qpnp_chg_force_run_on_batt(chip, input_en);
- -}
- -
- -static enum power_supply_property sec_qpnp_chg_props[] = {
- - POWER_SUPPLY_PROP_STATUS,
- - POWER_SUPPLY_PROP_CHARGE_TYPE,
- - POWER_SUPPLY_PROP_HEALTH,
- - POWER_SUPPLY_PROP_ONLINE,
- - POWER_SUPPLY_PROP_CURRENT_MAX,
- - POWER_SUPPLY_PROP_CURRENT_AVG,
- - POWER_SUPPLY_PROP_CURRENT_NOW,
- - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- - POWER_SUPPLY_PROP_BATFET,
- - POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
- - POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
- - POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
- - POWER_SUPPLY_PROP_VOLTAGE_MIN,
- - POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION,
- -};
- -
- -static int
- -sec_qpnp_chg_property_is_writeable(struct power_supply *psy,
- - enum power_supply_property psp)
- -{
- - switch (psp) {
- - case POWER_SUPPLY_PROP_CHARGING_ENABLED:
- - case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
- - case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- - case POWER_SUPPLY_PROP_COOL_TEMP:
- - case POWER_SUPPLY_PROP_WARM_TEMP:
- - case POWER_SUPPLY_PROP_CAPACITY:
- - return 1;
- - default:
- - break;
- - }
- -
- - return 0;
- -}
- -
- -static int
- -sec_qpnp_chg_get_property(struct power_supply *psy,
- - enum power_supply_property psp,
- - union power_supply_propval *val)
- -{
- - struct sec_charger_info *charger =
- - container_of(psy, struct sec_charger_info, psy_chg);
- - struct qpnp_chg_chip *chip = charger->chip;
- - int ret;
- -
- - switch (psp) {
- - case POWER_SUPPLY_PROP_ONLINE:
- - val->intval = charger->cable_type;
- - break;
- - case POWER_SUPPLY_PROP_STATUS:
- - val->intval = get_prop_batt_status(chip);
- - break;
- - case POWER_SUPPLY_PROP_HEALTH:
- - ret = qpnp_chg_check_usbin_health(chip);
- - if (ret == USBIN_OVP)
- - val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
- - else if (ret == USBIN_UNKNOW && wait_muic_event)
- - val->intval = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
- - else
- - val->intval = POWER_SUPPLY_HEALTH_GOOD;
- - break;
- - case POWER_SUPPLY_PROP_CURRENT_MAX:
- - sec_qpnp_chg_check_vddmax(chip);
- - val->intval = charger->charging_current_max;
- - break;
- - case POWER_SUPPLY_PROP_CURRENT_AVG:
- - val->intval = charger->charging_current;
- - break;
- - case POWER_SUPPLY_PROP_CURRENT_NOW:
- - val->intval = get_prop_current_now(chip);
- - break;
- - case POWER_SUPPLY_PROP_CHARGE_TYPE:
- - val->intval = get_prop_charge_type(chip);
- - break;
- - case POWER_SUPPLY_PROP_PRESENT:
- - val->intval = qpnp_chg_is_batt_present(chip);
- - break;
- - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- - break;
- - case POWER_SUPPLY_PROP_BATFET:
- - val->intval = get_prop_online(chip);
- - break;
- - case POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION:
- - val->intval = get_prop_vchg_loop(chip);
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
- - val->intval = qpnp_chg_usb_iusbmax_get(chip) * 1000;
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
- - val->intval = qpnp_chg_iusb_trim_get(chip);
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
- - val->intval = chip->aicl_settled;
- - break;
- - case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- - val->intval = qpnp_chg_vinmin_get(chip) * 1000;
- - break;
- - default:
- - return -EINVAL;
- - }
- -
- - return 0;
- -}
- -
- -static int
- -sec_qpnp_chg_set_property(struct power_supply *psy,
- - enum power_supply_property psp,
- - const union power_supply_propval *val)
- -{
- - struct sec_charger_info *charger =
- - container_of(psy, struct sec_charger_info, psy_chg);
- - struct qpnp_chg_chip *chip = charger->chip;
- - union power_supply_propval value;
- - int set_charging_current, set_charging_current_max;
- -
- - switch (psp) {
- - case POWER_SUPPLY_PROP_STATUS:
- - charger->status = val->intval;
- - break;
- - /* val->intval : type */
- - case POWER_SUPPLY_PROP_ONLINE:
- - charger->cable_type = val->intval;
- - psy_do_property("battery", get,
- - POWER_SUPPLY_PROP_HEALTH, value);
- -
- - if (val->intval == POWER_SUPPLY_TYPE_BATTERY || \
- - val->intval == POWER_SUPPLY_TYPE_OTG) {
- - charger->is_charging = false;
- - set_charging_current = 0;
- - set_charging_current_max =
- - charger->pdata->charging_current[
- - POWER_SUPPLY_TYPE_USB].input_current_limit;
- - if (value.intval == POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) {
- - sec_qpnp_chg_control(chip, CHG_OFF, INPUT_OFF);
- - } else {
- - sec_qpnp_chg_control(chip, CHG_OFF, INPUT_ON);
- - }
- - } else {
- - charger->is_charging = true;
- - charger->charging_current_max =
- - charger->pdata->charging_current
- - [charger->cable_type].input_current_limit;
- - charger->charging_current =
- - charger->pdata->charging_current
- - [charger->cable_type].fast_charging_current;
- - set_charging_current_max =
- - charger->charging_current_max;
- - set_charging_current =
- - charger->charging_current * charger->siop_level / 100;
- -
- - if ((charger->status == POWER_SUPPLY_STATUS_CHARGING) ||
- - (charger->status == POWER_SUPPLY_STATUS_DISCHARGING) ||
- - (value.intval == POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)) {
- -
- - if (value.intval == POWER_SUPPLY_HEALTH_UNSPEC_FAILURE) {
- - sec_qpnp_chg_control(chip, CHG_OFF, INPUT_OFF);
- - } else {
- - sec_qpnp_chg_control(chip, CHG_ON, INPUT_ON);
- -
- - /* set USB_WALL_THRESHOLD_MA for working charger_monitor */
- - if (charger_monitor || !chip->charger_monitor_checked)
- - qpnp_chg_iusbmax_set(chip, USB_WALL_THRESHOLD_MA);
- - else
- - qpnp_chg_iusbmax_set(chip, charger->charging_current_max);
- - psy_do_property("ac", get, POWER_SUPPLY_PROP_ONLINE, value);
- - if (value.intval)
- - qpnp_chg_iusb_trim_set(chip, 48);
- - else
- - qpnp_chg_iusb_trim_set(chip, 40);
- -
- - if (charger->siop_level == 100)
- - qpnp_chg_ibatmax_set(chip, 2000);
- - else
- - qpnp_chg_ibatmax_set(chip, set_charging_current);
- - }
- - } else {
- - sec_qpnp_chg_control(chip, CHG_ON, INPUT_ON);
- - }
- - }
- - break;
- - /* val->intval : input charging current */
- - case POWER_SUPPLY_PROP_CURRENT_MAX:
- - break;
- - /* val->intval : charging current */
- - case POWER_SUPPLY_PROP_CURRENT_AVG:
- - break;
- - case POWER_SUPPLY_PROP_CURRENT_NOW:
- - break;
- - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- - charger->siop_level = val->intval;
- - if (charger->is_charging) {
- - /* decrease the charging current according to siop level */
- - if (charger->siop_level == 100)
- - qpnp_chg_ibatmax_set(chip, 2000);
- - else {
- - int current_now =
- - charger->charging_current * charger->siop_level / 100;
- - qpnp_chg_ibatmax_set(chip, current_now);
- - }
- - }
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
- - if (qpnp_chg_is_usb_chg_plugged_in(chip))
- - qpnp_chg_iusbmax_set(chip, val->intval / 1000);
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM:
- - qpnp_chg_iusb_trim_set(chip, val->intval);
- - break;
- - case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
- - qpnp_chg_input_current_settled(chip);
- - break;
- - case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- - qpnp_chg_vinmin_set(chip, val->intval / 1000);
- - break;
- - default:
- - return -EINVAL;
- - }
- -
- - pr_debug("psy changed psy_chg\n");
- - power_supply_changed(&charger->psy_chg);
- - return 0;
- -}
- -
- -
- -static int sec_qpnp_charger_read_u32_index_dt(const struct device_node *np,
- - const char *propname,
- - u32 index, u32 *out_value)
- -{
- - struct property *prop = of_find_property(np, propname, NULL);
- - u32 len = (index + 1) * sizeof(*out_value);
- -
- - if (!prop)
- - return (-EINVAL);
- - if (!prop->value)
- - return (-ENODATA);
- - if (len > prop->length)
- - return (-EOVERFLOW);
- -
- - *out_value = be32_to_cpup(((__be32 *)prop->value) + index);
- -
- - return 0;
- -}
- -
- -static int sec_qpnp_charger_parse_dt(struct sec_charger_info *charger)
- -{
- - struct device_node *np = of_find_node_by_name(NULL, "charger");
- - sec_battery_platform_data_t *pdata = charger->pdata;
- - int ret = 0;
- - int i, len;
- - const u32 *p;
- -
- - if (np == NULL) {
- - pr_err("%s np NULL\n", __func__);
- - return -1;
- - } else {
- - ret = of_property_read_u32(np, "battery,ovp_uvlo_check_type",
- - &pdata->ovp_uvlo_check_type);
- - if (ret < 0)
- - pr_err("%s: ovp_uvlo_check_type read failed (%d)\n", __func__, ret);
- -
- - ret = of_property_read_u32(np, "battery,full_check_type",
- - &pdata->full_check_type);
- - if (ret < 0)
- - pr_err("%s: full_check_type read failed (%d)\n", __func__, ret);
- -
- - p = of_get_property(np, "battery,input_current_limit", &len);
- - len = len / sizeof(u32);
- - pdata->charging_current = kzalloc(sizeof(sec_charging_current_t) * len,
- - GFP_KERNEL);
- -
- - for(i = 0; i < len; i++) {
- - ret = sec_qpnp_charger_read_u32_index_dt(np,
- - "battery,input_current_limit", i,
- - &pdata->charging_current[i].input_current_limit);
- - ret = sec_qpnp_charger_read_u32_index_dt(np,
- - "battery,fast_charging_current", i,
- - &pdata->charging_current[i].fast_charging_current);
- - ret = sec_qpnp_charger_read_u32_index_dt(np,
- - "battery,full_check_current_1st", i,
- - &pdata->charging_current[i].full_check_current_1st);
- - ret = sec_qpnp_charger_read_u32_index_dt(np,
- - "battery,full_check_current_2nd", i,
- - &pdata->charging_current[i].full_check_current_2nd);
- - }
- - }
- - return ret;
- -}
- -
- -static void sec_qpnp_cable_initial_check(struct sec_charger_info *charger)
- -{
- - union power_supply_propval val_cable, val_status;
- -
- - psy_do_property("battery", get,
- - POWER_SUPPLY_PROP_ONLINE, val_cable);
- -
- - if ((POWER_SUPPLY_TYPE_BATTERY != val_cable.intval)
- - && (charger->cable_type != val_cable.intval)) {
- - psy_do_property("battery", get,
- - POWER_SUPPLY_PROP_STATUS, val_status);
- -
- - pr_info("battert_staus(%d), battery_cable_type(%d), charger_cable_type(%d)\n",
- - val_status.intval, val_cable.intval, charger->cable_type);
- -
- - psy_do_property("qpnp-chg", set,
- - POWER_SUPPLY_PROP_STATUS, val_status);
- - psy_do_property("qpnp-chg", set,
- - POWER_SUPPLY_PROP_ONLINE, val_cable);
- - psy_do_property("bms", set,
- - POWER_SUPPLY_PROP_ONLINE, val_cable);
- - }
- -}
- -#endif
- -
- static int __devinit
- qpnp_charger_probe(struct spmi_device *spmi)
- {
- @@ -5873,10 +5225,6 @@ qpnp_charger_probe(struct spmi_device *spmi)
- struct resource *resource;
- struct spmi_resource *spmi_resource;
- int rc = 0;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - struct sec_charger_info *charger;
- - u8 val_bat_reg = 0;
- - #endif
- chip = devm_kzalloc(&spmi->dev,
- sizeof(struct qpnp_chg_chip), GFP_KERNEL);
- @@ -5890,23 +5238,6 @@ qpnp_charger_probe(struct spmi_device *spmi)
- chip->dev = &(spmi->dev);
- chip->spmi = spmi;
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - charger = kzalloc(sizeof(*charger), GFP_KERNEL);
- - if (!charger)
- - return -ENOMEM;
- -
- - charger->chip = chip;
- - if (chip->spmi->dev.of_node) {
- - void * pdata = kzalloc(sizeof(sec_battery_platform_data_t), GFP_KERNEL);
- - if (!pdata)
- - goto err_free1;
- - charger->pdata = pdata;
- - if (sec_qpnp_charger_parse_dt(charger))
- - pr_err("%s : Failed to get charger dt\n", __func__);
- - } else
- - charger->pdata = chip->spmi->dev.platform_data;
- - #endif
- -
- chip->usb_psy = power_supply_get_by_name("usb");
- if (!chip->usb_psy) {
- pr_err("usb supply not found deferring probe\n");
- @@ -5923,10 +5254,8 @@ qpnp_charger_probe(struct spmi_device *spmi)
- mutex_init(&chip->batfet_vreg_lock);
- INIT_WORK(&chip->ocp_clear_work,
- qpnp_chg_ocp_clear_work);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- INIT_WORK(&chip->batfet_lcl_work,
- qpnp_chg_batfet_lcl_work);
- - #endif
- INIT_WORK(&chip->insertion_ocv_work,
- qpnp_chg_insertion_ocv_work);
- @@ -5976,7 +5305,8 @@ qpnp_charger_probe(struct spmi_device *spmi)
- goto fail_chg_enable;
- }
- - if (subtype == SMBB_BAT_IF_SUBTYPE) {
- + if (subtype == SMBB_BAT_IF_SUBTYPE ||
- + subtype == SMBBP_BAT_IF_SUBTYPE) {
- chip->iadc_dev = qpnp_get_iadc(chip->dev,
- "chg");
- if (IS_ERR(chip->iadc_dev)) {
- @@ -5986,11 +5316,10 @@ qpnp_charger_probe(struct spmi_device *spmi)
- goto fail_chg_enable;
- }
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- +
- rc = qpnp_chg_load_battery_data(chip);
- if (rc)
- goto fail_chg_enable;
- - #endif
- }
- }
- @@ -6124,21 +5453,9 @@ qpnp_charger_probe(struct spmi_device *spmi)
- dev_set_drvdata(&spmi->dev, chip);
- device_init_wakeup(&spmi->dev, 1);
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - val_bat_reg = 0xA5;
- - qpnp_chg_write(chip, &val_bat_reg, 0x12D0, 1);
- - val_bat_reg = 0x28;
- - qpnp_chg_write(chip, &val_bat_reg, 0x12E5, 1);
- -
- - /* force set BATFET_NO_LPM */
- - val_bat_reg = 0x00;
- - qpnp_chg_write(chip, &val_bat_reg, 0x1293, 1);
- - #endif
- -
- chip->insertion_ocv_uv = -EINVAL;
- chip->batt_present = qpnp_chg_is_batt_present(chip);
- if (chip->bat_if_base) {
- - #ifndef CONFIG_BATTERY_SAMSUNG
- chip->batt_psy.name = "battery";
- chip->batt_psy.type = POWER_SUPPLY_TYPE_BATTERY;
- chip->batt_psy.properties = msm_batt_power_props;
- @@ -6159,25 +5476,17 @@ qpnp_charger_probe(struct spmi_device *spmi)
- pr_err("batt failed to register rc = %d\n", rc);
- goto fail_chg_enable;
- }
- - #endif
- INIT_WORK(&chip->adc_measure_work,
- qpnp_bat_if_adc_measure_work);
- INIT_WORK(&chip->adc_disable_work,
- qpnp_bat_if_adc_disable_work);
- }
- - #ifndef CONFIG_BATTERY_SAMSUNG
- INIT_DELAYED_WORK(&chip->eoc_work, qpnp_eoc_work);
- - #endif
- INIT_DELAYED_WORK(&chip->arb_stop_work, qpnp_arb_stop_work);
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - INIT_DELAYED_WORK(&chip->usbin_valid_work, sec_qpnp_usbin_valid_work);
- - #endif
- INIT_DELAYED_WORK(&chip->usbin_health_check,
- qpnp_usbin_health_check_work);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- INIT_WORK(&chip->soc_check_work, qpnp_chg_soc_check_work);
- - #endif
- INIT_DELAYED_WORK(&chip->aicl_check_work, qpnp_aicl_check_work);
- if (chip->dc_chgpth_base) {
- @@ -6199,24 +5508,6 @@ qpnp_charger_probe(struct spmi_device *spmi)
- }
- }
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - charger->siop_level = 100;
- - charger->psy_chg.name = "qpnp-chg";
- - charger->psy_chg.type = POWER_SUPPLY_TYPE_UNKNOWN;
- - charger->psy_chg.get_property = sec_qpnp_chg_get_property;
- - charger->psy_chg.set_property = sec_qpnp_chg_set_property;
- - charger->psy_chg.properties = sec_qpnp_chg_props;
- - charger->psy_chg.num_properties = ARRAY_SIZE(sec_qpnp_chg_props);
- - charger->psy_chg.property_is_writeable =
- - sec_qpnp_chg_property_is_writeable;
- -
- - rc = power_supply_register(chip->dev, &charger->psy_chg);
- - if (rc < 0) {
- - pr_err("power_supply_register qpnp-chg failed rc=%d\n", rc);
- - goto err_free;
- - }
- - #endif
- -
- /* Turn on appropriate workaround flags */
- rc = qpnp_chg_setup_flags(chip);
- if (rc < 0) {
- @@ -6270,11 +5561,6 @@ qpnp_charger_probe(struct spmi_device *spmi)
- goto unregister_dc_psy;
- }
- }
- - #ifdef CONFIG_BATTERY_SAMSUNG
- - /* if sec_battery probed before qpnp-charger,
- - charger driver cannot recognize cable type */
- - sec_qpnp_cable_initial_check(charger);
- - #endif
- rc = qpnp_chg_request_irqs(chip);
- if (rc) {
- @@ -6285,17 +5571,13 @@ qpnp_charger_probe(struct spmi_device *spmi)
- qpnp_chg_usb_chg_gone_irq_handler(chip->chg_gone.irq, chip);
- qpnp_chg_usb_usbin_valid_irq_handler(chip->usbin_valid.irq, chip);
- qpnp_chg_dc_dcin_valid_irq_handler(chip->dcin_valid.irq, chip);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_set_present(chip->usb_psy,
- qpnp_chg_is_usb_chg_plugged_in(chip));
- - #endif
- /* Set USB psy online to avoid userspace from shutting down if battery
- * capacity is at zero and no chargers online. */
- - #ifndef CONFIG_BATTERY_SAMSUNG
- if (qpnp_chg_is_usb_chg_plugged_in(chip))
- power_supply_set_online(chip->usb_psy, 1);
- - #endif
- schedule_delayed_work(&chip->aicl_check_work,
- msecs_to_jiffies(EOC_CHECK_PERIOD_MS));
- @@ -6312,16 +5594,8 @@ unregister_dc_psy:
- if (chip->dc_chgpth_base)
- power_supply_unregister(&chip->dc_psy);
- unregister_batt:
- -#ifndef CONFIG_BATTERY_SAMSUNG
- if (chip->bat_if_base)
- power_supply_unregister(&chip->batt_psy);
- -#endif
- -#ifdef CONFIG_BATTERY_SAMSUNG
- -err_free:
- - kfree(charger->pdata);
- -err_free1:
- - kfree(charger);
- -#endif
- fail_chg_enable:
- regulator_unregister(chip->otg_vreg.rdev);
- regulator_unregister(chip->boost_vreg.rdev);
- @@ -6340,20 +5614,14 @@ qpnp_charger_remove(struct spmi_device *spmi)
- cancel_delayed_work_sync(&chip->aicl_check_work);
- power_supply_unregister(&chip->dc_psy);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- cancel_work_sync(&chip->soc_check_work);
- - #endif
- cancel_delayed_work_sync(&chip->usbin_health_check);
- cancel_delayed_work_sync(&chip->arb_stop_work);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- cancel_delayed_work_sync(&chip->eoc_work);
- - #endif
- cancel_work_sync(&chip->adc_disable_work);
- cancel_work_sync(&chip->adc_measure_work);
- - #ifndef CONFIG_BATTERY_SAMSUNG
- power_supply_unregister(&chip->batt_psy);
- cancel_work_sync(&chip->batfet_lcl_work);
- - #endif
- cancel_work_sync(&chip->insertion_ocv_work);
- cancel_work_sync(&chip->reduce_power_stage_work);
- alarm_cancel(&chip->reduce_power_stage_alarm);
- @@ -6369,9 +5637,6 @@ qpnp_charger_remove(struct spmi_device *spmi)
- static int qpnp_chg_resume(struct device *dev)
- {
- -#ifdef CONFIG_BATTERY_SAMSUNG
- - return 0;
- -#else
- struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
- int rc = 0;
- @@ -6385,14 +5650,10 @@ static int qpnp_chg_resume(struct device *dev)
- }
- return rc;
- -#endif
- }
- static int qpnp_chg_suspend(struct device *dev)
- {
- -#ifdef CONFIG_BATTERY_SAMSUNG
- - return 0;
- -#else
- struct qpnp_chg_chip *chip = dev_get_drvdata(dev);
- int rc = 0;
- @@ -6406,7 +5667,6 @@ static int qpnp_chg_suspend(struct device *dev)
- }
- return rc;
- -#endif
- }
- static const struct dev_pm_ops qpnp_chg_pm_ops = {
- diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
- index c662a2b..924a028 100644
- --- a/drivers/slimbus/slim-msm-ctrl.c
- +++ b/drivers/slimbus/slim-msm-ctrl.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2011-2014, 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
- @@ -207,8 +207,7 @@ static irqreturn_t msm_slim_interrupt(int irq, void *d)
- * signalling completion/exiting ISR
- */
- mb();
- - if (dev->wr_comp)
- - complete(dev->wr_comp);
- + msm_slim_manage_tx_msgq(dev, false, NULL);
- }
- if (stat & MGR_INT_RX_MSG_RCVD) {
- u32 rx_buf[10];
- @@ -372,8 +371,7 @@ static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- }
- }
- txn->rl--;
- - pbuf = msm_get_msg_buf(dev, txn->rl);
- - dev->wr_comp = NULL;
- + pbuf = msm_get_msg_buf(dev, txn->rl, &done);
- dev->err = 0;
- if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
- @@ -438,11 +436,8 @@ static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- if (txn->mt == SLIM_MSG_MT_CORE &&
- mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION)
- dev->reconf_busy = true;
- - dev->wr_comp = &done;
- msm_send_msg_buf(dev, pbuf, txn->rl, MGR_TX_MSG);
- timeout = wait_for_completion_timeout(&done, HZ);
- - if (!timeout)
- - dev->wr_comp = NULL;
- if (mc == SLIM_MSG_MC_RECONFIGURE_NOW) {
- if ((txn->mc == (SLIM_MSG_MC_RECONFIGURE_NOW |
- SLIM_MSG_CLK_PAUSE_SEQ_FLG)) &&
- @@ -505,7 +500,9 @@ static int msm_set_laddr(struct slim_controller *ctrl, const u8 *ea,
- retry_laddr:
- init_completion(&done);
- mutex_lock(&dev->tx_lock);
- - buf = msm_get_msg_buf(dev, 9);
- + buf = msm_get_msg_buf(dev, 9, &done);
- + if (buf == NULL)
- + return -ENOMEM;
- buf[0] = SLIM_MSG_ASM_FIRST_WORD(9, SLIM_MSG_MT_CORE,
- SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS,
- SLIM_MSG_DEST_LOGICALADDR,
- @@ -513,7 +510,6 @@ retry_laddr:
- buf[1] = ea[3] | (ea[2] << 8) | (ea[1] << 16) | (ea[0] << 24);
- buf[2] = laddr;
- - dev->wr_comp = &done;
- ret = msm_send_msg_buf(dev, buf, 9, MGR_TX_MSG);
- timeout = wait_for_completion_timeout(&done, HZ);
- if (!timeout)
- @@ -521,7 +517,6 @@ retry_laddr:
- if (dev->err) {
- ret = dev->err;
- dev->err = 0;
- - dev->wr_comp = NULL;
- }
- mutex_unlock(&dev->tx_lock);
- if (ret) {
- @@ -1183,6 +1178,10 @@ static int __devinit msm_slim_probe(struct platform_device *pdev)
- ret = -ENOMEM;
- goto err_get_res_failed;
- }
- + dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
- + GFP_KERNEL);
- + if (!dev->wr_comp)
- + return -ENOMEM;
- dev->dev = &pdev->dev;
- platform_set_drvdata(pdev, dev);
- slim_set_ctrldata(&dev->ctrl, dev);
- @@ -1271,7 +1270,8 @@ static int __devinit msm_slim_probe(struct platform_device *pdev)
- dev->ctrl.dev.parent = &pdev->dev;
- dev->ctrl.dev.of_node = pdev->dev.of_node;
- - ret = request_irq(dev->irq, msm_slim_interrupt, IRQF_TRIGGER_HIGH,
- + ret = request_threaded_irq(dev->irq, NULL, msm_slim_interrupt,
- + IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- "msm_slim_irq", dev);
- if (ret) {
- dev_err(&pdev->dev, "request IRQ failed\n");
- @@ -1400,6 +1400,7 @@ err_of_init_failed:
- err_ioremap_bam_failed:
- iounmap(dev->base);
- err_ioremap_failed:
- + kfree(dev->wr_comp);
- kfree(dev);
- err_get_res_failed:
- release_mem_region(bam_mem->start, resource_size(bam_mem));
- @@ -1437,6 +1438,7 @@ static int __devexit msm_slim_remove(struct platform_device *pdev)
- kthread_stop(dev->rx_msgq_thread);
- iounmap(dev->bam.base);
- iounmap(dev->base);
- + kfree(dev->wr_comp);
- kfree(dev);
- bam_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "slimbus_bam_physical");
- diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
- index 1bfeca8..d31ae1b 100644
- --- a/drivers/slimbus/slim-msm-ngd.c
- +++ b/drivers/slimbus/slim-msm-ngd.c
- @@ -117,15 +117,13 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d)
- dev->err);
- /* Guarantee that error interrupts are cleared */
- mb();
- - if (dev->wr_comp)
- - complete(dev->wr_comp);
- + msm_slim_manage_tx_msgq(dev, false, NULL);
- } else if (stat & NGD_INT_TX_MSG_SENT) {
- writel_relaxed(NGD_INT_TX_MSG_SENT, ngd + NGD_INT_CLR);
- /* Make sure interrupt is cleared */
- mb();
- - if (dev->wr_comp)
- - complete(dev->wr_comp);
- + msm_slim_manage_tx_msgq(dev, false, NULL);
- }
- if (stat & NGD_INT_RX_MSG_RCVD) {
- u32 rx_buf[10];
- @@ -181,27 +179,51 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
- case QMI_SERVER_ARRIVE:
- schedule_work(&qmi->ssr_up);
- break;
- - case QMI_SERVER_EXIT:
- - dev->state = MSM_CTRL_DOWN;
- + default:
- + break;
- + }
- + return 0;
- +}
- +
- +static int dsp_ssr_notify_cb(struct notifier_block *n, unsigned long code,
- + void *_cmd)
- +{
- + struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
- + struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
- + dsp);
- +
- + switch (code) {
- + case SUBSYS_BEFORE_SHUTDOWN:
- + SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code);
- + /* wait for current transaction */
- + mutex_lock(&dev->tx_lock);
- /* make sure autosuspend is not called until ADSP comes up*/
- pm_runtime_get_noresume(dev->dev);
- + dev->state = MSM_CTRL_DOWN;
- /* Reset ctrl_up completion */
- init_completion(&dev->ctrl_up);
- - schedule_work(&qmi->ssr_down);
- + /* disconnect BAM pipes */
- + if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
- + dev->use_rx_msgqs = MSM_MSGQ_DOWN;
- + if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
- + dev->use_tx_msgqs = MSM_MSGQ_DOWN;
- + msm_slim_sps_exit(dev, false);
- + schedule_work(&dev->qmi.ssr_down);
- + mutex_unlock(&dev->tx_lock);
- break;
- default:
- break;
- }
- - return 0;
- + return NOTIFY_DONE;
- }
- static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
- void *_cmd)
- {
- void __iomem *ngd;
- - struct msm_slim_mdm *mdm = container_of(n, struct msm_slim_mdm, nb);
- - struct msm_slim_ctrl *dev = container_of(mdm, struct msm_slim_ctrl,
- - mdm);
- + struct msm_slim_ss *ext_mdm = container_of(n, struct msm_slim_ss, nb);
- + struct msm_slim_ctrl *dev = container_of(ext_mdm, struct msm_slim_ctrl,
- + ext_mdm);
- struct slim_controller *ctrl = &dev->ctrl;
- u32 laddr;
- struct slim_device *sbdev;
- @@ -216,11 +238,11 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
- * handover later
- */
- msm_slim_qmi_check_framer_request(dev);
- - dev->mdm.state = MSM_CTRL_DOWN;
- + dev->ext_mdm.state = MSM_CTRL_DOWN;
- msm_slim_put_ctrl(dev);
- break;
- case SUBSYS_AFTER_POWERUP:
- - if (dev->mdm.state != MSM_CTRL_DOWN)
- + if (dev->ext_mdm.state != MSM_CTRL_DOWN)
- return NOTIFY_DONE;
- SLIM_INFO(dev,
- "SLIM %lu external_modem SSR notify cb\n", code);
- @@ -231,19 +253,21 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
- ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
- laddr = readl_relaxed(ngd + NGD_STATUS);
- if (!(laddr & NGD_LADDR)) {
- + mutex_lock(&dev->tx_lock);
- /* runtime-pm state should be consistent with HW */
- pm_runtime_disable(dev->dev);
- pm_runtime_set_suspended(dev->dev);
- dev->state = MSM_CTRL_DOWN;
- + mutex_unlock(&dev->tx_lock);
- SLIM_INFO(dev,
- "SLIM MDM SSR (active framer on MDM) dev-down\n");
- list_for_each_entry(sbdev, &ctrl->devs, dev_list)
- slim_report_absent(sbdev);
- - ngd_slim_power_up(dev, true);
- + ngd_slim_runtime_resume(dev->dev);
- pm_runtime_set_active(dev->dev);
- pm_runtime_enable(dev->dev);
- }
- - dev->mdm.state = MSM_CTRL_AWAKE;
- + dev->ext_mdm.state = MSM_CTRL_AWAKE;
- msm_slim_put_ctrl(dev);
- break;
- default:
- @@ -302,12 +326,24 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- u16 txn_mc = txn->mc;
- u8 wbuf[SLIM_MSGQ_BUF_LEN];
- bool report_sat = false;
- + bool sync_wr = true;
- +
- + if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
- + return -EPROTONOSUPPORT;
- +
- + if (txn->mt == SLIM_MSG_MT_CORE &&
- + (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
- + txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
- + return 0;
- if (txn->mc == SLIM_USR_MC_REPORT_SATELLITE &&
- txn->mt == SLIM_MSG_MT_SRC_REFERRED_USER)
- report_sat = true;
- - if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
- - report_sat == false) {
- + else
- + mutex_lock(&dev->tx_lock);
- +
- + if (!report_sat && !pm_runtime_enabled(dev->dev) &&
- + dev->state == MSM_CTRL_ASLEEP) {
- /*
- * Counter-part of system-suspend when runtime-pm is not enabled
- * This way, resume can be left empty and device will be put in
- @@ -315,22 +351,24 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- * If the state was DOWN, SSR UP notification will take
- * care of putting the device in active state.
- */
- - ngd_slim_runtime_resume(dev->dev);
- - }
- -
- - else if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
- - return -EPROTONOSUPPORT;
- + mutex_unlock(&dev->tx_lock);
- + ret = ngd_slim_runtime_resume(dev->dev);
- - if (txn->mt == SLIM_MSG_MT_CORE &&
- - (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
- - txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW)) {
- - return 0;
- + if (ret) {
- + SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
- + ret, dev->state);
- + return -EREMOTEIO;
- + }
- + mutex_lock(&dev->tx_lock);
- }
- +
- /* If txn is tried when controller is down, wait for ADSP to boot */
- if (!report_sat) {
- +
- if (dev->state == MSM_CTRL_DOWN) {
- u8 mc = (u8)txn->mc;
- int timeout;
- + mutex_unlock(&dev->tx_lock);
- SLIM_INFO(dev, "ADSP slimbus not up yet\n");
- /*
- * Messages related to data channel management can't
- @@ -370,33 +408,31 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- return -EREMOTEIO;
- timeout = wait_for_completion_timeout(&dev->ctrl_up,
- HZ);
- - if (!timeout && dev->state == MSM_CTRL_DOWN)
- + if (!timeout)
- return -ETIMEDOUT;
- + mutex_lock(&dev->tx_lock);
- }
- +
- + mutex_unlock(&dev->tx_lock);
- ret = msm_slim_get_ctrl(dev);
- + mutex_lock(&dev->tx_lock);
- /*
- * Runtime-pm's callbacks are not called until runtime-pm's
- * error status is cleared
- * Setting runtime status to suspended clears the error
- * It also makes HW status cosistent with what SW has it here
- */
- - if (ret == -ENETRESET && dev->state == MSM_CTRL_DOWN) {
- + if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
- + dev->state == MSM_CTRL_DOWN) {
- + SLIM_ERR(dev, "slim ctrl vote failed ret:%d, state:%d",
- + ret, dev->state);
- pm_runtime_set_suspended(dev->dev);
- + mutex_unlock(&dev->tx_lock);
- msm_slim_put_ctrl(dev);
- return -EREMOTEIO;
- - } else if (ret >= 0) {
- - dev->state = MSM_CTRL_AWAKE;
- }
- }
- - mutex_lock(&dev->tx_lock);
- - if (report_sat == false && dev->state != MSM_CTRL_AWAKE) {
- - SLIM_ERR(dev, "controller not ready\n");
- - mutex_unlock(&dev->tx_lock);
- - pm_runtime_set_suspended(dev->dev);
- - msm_slim_put_ctrl(dev);
- - return -EREMOTEIO;
- - }
- if (txn->mt == SLIM_MSG_MT_CORE &&
- (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
- txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
- @@ -454,7 +490,25 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- txn->rl = txn->len + 4;
- }
- txn->rl--;
- - pbuf = msm_get_msg_buf(dev, txn->rl);
- +
- + if (txn->mt == SLIM_MSG_MT_CORE && txn->comp &&
- + dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
- + (txn_mc != SLIM_MSG_MC_REQUEST_INFORMATION &&
- + txn_mc != SLIM_MSG_MC_REQUEST_VALUE &&
- + txn_mc != SLIM_MSG_MC_REQUEST_CHANGE_VALUE &&
- + txn_mc != SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION)) {
- + sync_wr = false;
- + pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
- + } else if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
- + dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
- + txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
- + txn->comp) {
- + sync_wr = false;
- + pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
- + } else {
- + pbuf = msm_get_msg_buf(dev, txn->rl, &tx_sent);
- + }
- +
- if (!pbuf) {
- SLIM_ERR(dev, "Message buffer unavailable\n");
- ret = -ENOMEM;
- @@ -525,10 +579,9 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- */
- txn_mc = txn->mc;
- txn_mt = txn->mt;
- - dev->wr_comp = &tx_sent;
- ret = msm_send_msg_buf(dev, pbuf, txn->rl,
- NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_TX_MSG);
- - if (!ret) {
- + if (!ret && sync_wr) {
- int timeout = wait_for_completion_timeout(&tx_sent, HZ);
- if (!timeout) {
- ret = -ETIMEDOUT;
- @@ -537,14 +590,15 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- * transactions don't timeout due to unavailable
- * descriptors
- */
- - msm_slim_disconnect_endp(dev, &dev->tx_msgq,
- - &dev->use_tx_msgqs);
- - msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
- + if (dev->state != MSM_CTRL_DOWN) {
- + msm_slim_disconnect_endp(dev, &dev->tx_msgq,
- + &dev->use_tx_msgqs);
- + msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
- + }
- } else {
- ret = dev->err;
- }
- }
- - dev->wr_comp = NULL;
- if (ret) {
- u32 conf, stat, rx_msgq, int_stat, int_en, int_clr;
- void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr,
- @@ -585,9 +639,10 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
- return ret ? ret : dev->err;
- }
- ngd_xfer_err:
- - mutex_unlock(&dev->tx_lock);
- - if (!report_sat)
- + if (!report_sat) {
- + mutex_unlock(&dev->tx_lock);
- msm_slim_put_ctrl(dev);
- + }
- return ret ? ret : dev->err;
- }
- @@ -896,7 +951,6 @@ capability_retry:
- enum msm_ctrl_state prev_state = dev->state;
- SLIM_INFO(dev,
- "SLIM SAT: capability exchange successful\n");
- - dev->state = MSM_CTRL_AWAKE;
- if (prev_state >= MSM_CTRL_ASLEEP)
- complete(&dev->reconf);
- else
- @@ -980,8 +1034,10 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
- if (!mdm_restart && cur_state == MSM_CTRL_DOWN) {
- int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
- HZ);
- - if (!timeout)
- + if (!timeout) {
- SLIM_ERR(dev, "slimbus QMI init timed out\n");
- + return -EREMOTEIO;
- + }
- }
- /* No need to vote if contorller is not in low power mode */
- @@ -1068,11 +1124,11 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
- SLIM_ERR(dev, "Failed to receive master capability\n");
- return -ETIMEDOUT;
- }
- - if (cur_state == MSM_CTRL_DOWN) {
- - complete(&dev->ctrl_up);
- - /* Resetting the log level */
- - SLIM_RST_LOGLVL(dev);
- - }
- + /* mutliple transactions waiting on slimbus to power up? */
- + if (cur_state == MSM_CTRL_DOWN)
- + complete_all(&dev->ctrl_up);
- + /* Resetting the log level */
- + SLIM_RST_LOGLVL(dev);
- return 0;
- }
- @@ -1238,12 +1294,6 @@ static void ngd_adsp_down(struct work_struct *work)
- struct slim_device *sbdev;
- ngd_slim_enable(dev, false);
- - /* disconnect BAM pipes */
- - if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
- - dev->use_rx_msgqs = MSM_MSGQ_DOWN;
- - if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
- - dev->use_tx_msgqs = MSM_MSGQ_DOWN;
- - msm_slim_sps_exit(dev, false);
- /* device up should be called again after SSR */
- list_for_each_entry(sbdev, &ctrl->devs, dev_list)
- slim_report_absent(sbdev);
- @@ -1322,6 +1372,10 @@ static int __devinit ngd_slim_probe(struct platform_device *pdev)
- dev_err(&pdev->dev, "no memory for MSM slimbus controller\n");
- return PTR_ERR(dev);
- }
- + dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
- + GFP_KERNEL);
- + if (!dev->wr_comp)
- + return -ENOMEM;
- dev->dev = &pdev->dev;
- platform_set_drvdata(pdev, dev);
- slim_set_ctrldata(&dev->ctrl, dev);
- @@ -1405,6 +1459,7 @@ static int __devinit ngd_slim_probe(struct platform_device *pdev)
- init_completion(&dev->reconf);
- init_completion(&dev->ctrl_up);
- mutex_init(&dev->tx_lock);
- + mutex_init(&dev->tx_buf_lock);
- spin_lock_init(&dev->rx_lock);
- dev->ee = 1;
- dev->irq = irq->start;
- @@ -1432,8 +1487,9 @@ static int __devinit ngd_slim_probe(struct platform_device *pdev)
- dev->ctrl.dev.of_node = pdev->dev.of_node;
- dev->state = MSM_CTRL_DOWN;
- - ret = request_irq(dev->irq, ngd_slim_interrupt,
- - IRQF_TRIGGER_HIGH, "ngd_slim_irq", dev);
- + ret = request_threaded_irq(dev->irq, NULL,
- + ngd_slim_interrupt,
- + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "ngd_slim_irq", dev);
- if (ret) {
- dev_err(&pdev->dev, "request IRQ failed\n");
- @@ -1447,14 +1503,21 @@ static int __devinit ngd_slim_probe(struct platform_device *pdev)
- pm_runtime_set_suspended(dev->dev);
- pm_runtime_enable(dev->dev);
- + dev->dsp.nb.notifier_call = dsp_ssr_notify_cb;
- + dev->dsp.ssr = subsys_notif_register_notifier("adsp",
- + &dev->dsp.nb);
- + if (IS_ERR_OR_NULL(dev->dsp.ssr))
- + dev_err(dev->dev,
- + "subsys_notif_register_notifier failed %p",
- + dev->dsp.ssr);
- if (slim_mdm) {
- - dev->mdm.nb.notifier_call = mdm_ssr_notify_cb;
- - dev->mdm.ssr = subsys_notif_register_notifier(ext_modem_id,
- - &dev->mdm.nb);
- - if (IS_ERR_OR_NULL(dev->mdm.ssr))
- + dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
- + dev->ext_mdm.ssr = subsys_notif_register_notifier(ext_modem_id,
- + &dev->ext_mdm.nb);
- + if (IS_ERR_OR_NULL(dev->ext_mdm.ssr))
- dev_err(dev->dev,
- "subsys_notif_register_notifier failed %p",
- - dev->mdm.ssr);
- + dev->ext_mdm.ssr);
- }
- INIT_WORK(&dev->qmi.ssr_down, ngd_adsp_down);
- @@ -1496,6 +1559,7 @@ err_ioremap_failed:
- if (dev->sysfs_created)
- sysfs_remove_file(&dev->dev->kobj,
- &dev_attr_debug_mask.attr);
- + kfree(dev->wr_comp);
- kfree(dev);
- return ret;
- }
- @@ -1511,13 +1575,18 @@ static int __devexit ngd_slim_remove(struct platform_device *pdev)
- SLIMBUS_QMI_SVC_V1,
- SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
- pm_runtime_disable(&pdev->dev);
- - if (!IS_ERR_OR_NULL(dev->mdm.ssr))
- - subsys_notif_unregister_notifier(dev->mdm.ssr, &dev->mdm.nb);
- + if (!IS_ERR_OR_NULL(dev->dsp.ssr))
- + subsys_notif_unregister_notifier(dev->dsp.ssr,
- + &dev->dsp.nb);
- + if (!IS_ERR_OR_NULL(dev->ext_mdm.ssr))
- + subsys_notif_unregister_notifier(dev->ext_mdm.ssr,
- + &dev->ext_mdm.nb);
- free_irq(dev->irq, dev);
- slim_del_controller(&dev->ctrl);
- kthread_stop(dev->rx_msgq_thread);
- iounmap(dev->bam.base);
- iounmap(dev->base);
- + kfree(dev->wr_comp);
- kfree(dev);
- return 0;
- }
- @@ -1543,8 +1612,10 @@ static int ngd_slim_runtime_idle(struct device *device)
- {
- struct platform_device *pdev = to_platform_device(device);
- struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
- + mutex_lock(&dev->tx_lock);
- if (dev->state == MSM_CTRL_AWAKE)
- dev->state = MSM_CTRL_IDLE;
- + mutex_unlock(&dev->tx_lock);
- dev_dbg(device, "pm_runtime: idle...\n");
- pm_request_autosuspend(device);
- return -EAGAIN;
- @@ -1562,6 +1633,7 @@ static int ngd_slim_runtime_resume(struct device *device)
- struct platform_device *pdev = to_platform_device(device);
- struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
- int ret = 0;
- + mutex_lock(&dev->tx_lock);
- if (dev->state >= MSM_CTRL_ASLEEP)
- ret = ngd_slim_power_up(dev, false);
- if (ret) {
- @@ -1573,6 +1645,7 @@ static int ngd_slim_runtime_resume(struct device *device)
- } else {
- dev->state = MSM_CTRL_AWAKE;
- }
- + mutex_unlock(&dev->tx_lock);
- SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret);
- return ret;
- }
- @@ -1583,6 +1656,7 @@ static int ngd_slim_runtime_suspend(struct device *device)
- struct platform_device *pdev = to_platform_device(device);
- struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
- int ret = 0;
- + mutex_lock(&dev->tx_lock);
- ret = ngd_slim_power_down(dev);
- if (ret) {
- if (ret != -EBUSY)
- @@ -1591,6 +1665,7 @@ static int ngd_slim_runtime_suspend(struct device *device)
- } else {
- dev->state = MSM_CTRL_ASLEEP;
- }
- + mutex_unlock(&dev->tx_lock);
- SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret);
- return ret;
- }
- diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
- index f509f67..ec82375 100644
- --- a/drivers/slimbus/slim-msm.c
- +++ b/drivers/slimbus/slim-msm.c
- @@ -11,6 +11,7 @@
- */
- #include <linux/pm_runtime.h>
- #include <linux/dma-mapping.h>
- +#include <linux/delay.h>
- #include <linux/slimbus/slimbus.h>
- #include <mach/sps.h>
- #include "slim-msm.h"
- @@ -398,9 +399,9 @@ static int msm_slim_post_tx_msgq(struct msm_slim_ctrl *dev, u8 *buf, int len)
- struct msm_slim_endp *endpoint = &dev->tx_msgq;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_pipe *pipe = endpoint->sps;
- - int ix = (buf - (u8 *)mem->base) / SLIM_MSGQ_BUF_LEN;
- + int ix = (buf - (u8 *)mem->base);
- - phys_addr_t phys_addr = mem->phys_base + (SLIM_MSGQ_BUF_LEN * ix);
- + phys_addr_t phys_addr = mem->phys_base + ix;
- for (ret = 0; ret < ((len + 3) >> 2); ret++)
- pr_debug("BAM TX buf[%d]:0x%x", ret, ((u32 *)buf)[ret]);
- @@ -413,29 +414,110 @@ static int msm_slim_post_tx_msgq(struct msm_slim_ctrl *dev, u8 *buf, int len)
- return ret;
- }
- -static u32 *msm_slim_tx_msgq_return(struct msm_slim_ctrl *dev)
- +void msm_slim_tx_msg_return(struct msm_slim_ctrl *dev)
- {
- struct msm_slim_endp *endpoint = &dev->tx_msgq;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_pipe *pipe = endpoint->sps;
- struct sps_iovec iovec;
- - int ret;
- -
- - /* first transaction after establishing connection */
- - if (dev->tx_idx == -1) {
- - dev->tx_idx = 0;
- - return mem->base;
- + int idx, ret = 0;
- + if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
- + /* use 1 buffer, non-blocking writes are not possible */
- + if (dev->wr_comp[0]) {
- + struct completion *comp = dev->wr_comp[0];
- + dev->wr_comp[0] = NULL;
- + complete(comp);
- + }
- + return;
- }
- - ret = sps_get_iovec(pipe, &iovec);
- - if (ret || iovec.addr == 0) {
- - dev_err(dev->dev, "sps_get_iovec() failed 0x%x\n", ret);
- + while (!ret) {
- + ret = sps_get_iovec(pipe, &iovec);
- + if (ret || iovec.addr == 0) {
- + if (ret)
- + pr_err("SLIM TX get IOVEC failed:%d", ret);
- + return;
- + }
- + idx = (int) ((iovec.addr - mem->phys_base) / SLIM_MSGQ_BUF_LEN);
- + if (idx < MSM_TX_BUFS && dev->wr_comp[idx]) {
- + struct completion *comp = dev->wr_comp[idx];
- + dev->wr_comp[idx] = NULL;
- + complete(comp);
- + }
- + /* reclaim all packets that were delivered out of order */
- + if (idx != dev->tx_head)
- + pr_err("SLIM OUT OF ORDER TX:idx:%d, head:%d", idx,
- + dev->tx_head);
- + while (idx == dev->tx_head) {
- + dev->tx_head = (dev->tx_head + 1) % MSM_TX_BUFS;
- + idx++;
- + if (dev->tx_head == dev->tx_tail ||
- + dev->wr_comp[idx] != NULL)
- + break;
- + }
- + }
- +}
- +
- +static u32 *msm_slim_modify_tx_buf(struct msm_slim_ctrl *dev,
- + struct completion *comp)
- +{
- + struct msm_slim_endp *endpoint = &dev->tx_msgq;
- + struct sps_mem_buffer *mem = &endpoint->buf;
- + u32 *retbuf = NULL;
- + if ((dev->tx_tail + 1) % MSM_TX_BUFS == dev->tx_head)
- + return NULL;
- +
- + retbuf = (u32 *)((u8 *)mem->base +
- + (dev->tx_tail * SLIM_MSGQ_BUF_LEN));
- + dev->wr_comp[dev->tx_tail] = comp;
- + dev->tx_tail = (dev->tx_tail + 1) % MSM_TX_BUFS;
- + return retbuf;
- +}
- +u32 *msm_slim_manage_tx_msgq(struct msm_slim_ctrl *dev, bool getbuf,
- + struct completion *comp)
- +{
- + int ret = 0;
- + int retries = 0;
- + u32 *retbuf = NULL;
- +
- + mutex_lock(&dev->tx_buf_lock);
- + if (!getbuf) {
- + msm_slim_tx_msg_return(dev);
- + mutex_unlock(&dev->tx_buf_lock);
- return NULL;
- }
- - /* Calculate buffer index */
- - dev->tx_idx = ((int)(iovec.addr - mem->phys_base)) / SLIM_MSGQ_BUF_LEN;
- + retbuf = msm_slim_modify_tx_buf(dev, comp);
- + if (retbuf) {
- + mutex_unlock(&dev->tx_buf_lock);
- + return retbuf;
- + }
- - return (u32 *)((u8 *)mem->base + (dev->tx_idx * SLIM_MSGQ_BUF_LEN));
- + do {
- + msm_slim_tx_msg_return(dev);
- + retbuf = msm_slim_modify_tx_buf(dev, comp);
- + if (!retbuf)
- + ret = -EAGAIN;
- + else {
- + if (retries > 0)
- + SLIM_INFO(dev, "SLIM TX retrieved:%d retries",
- + retries);
- + mutex_unlock(&dev->tx_buf_lock);
- + return retbuf;
- + }
- +
- + /*
- + * superframe size will vary based on clock gear
- + * 1 superframe will consume at least 1 message
- + * if HW is in good condition. With MX_RETRIES,
- + * make sure we wait for a [3, 10] superframes
- + * before deciding HW couldn't process descriptors
- + */
- + usleep_range(100, 250);
- + retries++;
- + } while (ret && (retries < INIT_MX_RETRIES));
- +
- + mutex_unlock(&dev->tx_buf_lock);
- + return NULL;
- }
- int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg)
- @@ -453,16 +535,19 @@ int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg)
- return msm_slim_post_tx_msgq(dev, (u8 *)buf, len);
- }
- -u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len)
- +u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
- + struct completion *comp)
- {
- /*
- * Currently we block a transaction until the current one completes.
- * In case we need multiple transactions, use message Q
- */
- - if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED)
- + if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
- + dev->wr_comp[0] = comp;
- return dev->tx_buf;
- + }
- - return msm_slim_tx_msgq_return(dev);
- + return msm_slim_manage_tx_msgq(dev, true, comp);
- }
- static void
- @@ -612,7 +697,8 @@ int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
- }
- dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
- } else {
- - dev->tx_idx = -1;
- + dev->tx_tail = 0;
- + dev->tx_head = 0;
- dev->use_tx_msgqs = MSM_MSGQ_ENABLED;
- }
- @@ -719,16 +805,18 @@ static int msm_slim_init_tx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
- config->options = SPS_O_ERROR | SPS_O_NO_Q |
- SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
- + /* Desc and TX buf are circular queues */
- /* Allocate memory for the FIFO descriptors */
- ret = msm_slim_sps_mem_alloc(dev, descr,
- - MSM_TX_BUFS * sizeof(struct sps_iovec));
- + (MSM_TX_BUFS + 1) * sizeof(struct sps_iovec));
- if (ret) {
- dev_err(dev->dev, "unable to allocate SPS descriptors\n");
- goto alloc_descr_failed;
- }
- - /* Allocate memory for the message buffer(s), N descrs, 40-byte mesg */
- - ret = msm_slim_sps_mem_alloc(dev, mem, MSM_TX_BUFS * SLIM_MSGQ_BUF_LEN);
- + /* Allocate TX buffer from which descriptors are created */
- + ret = msm_slim_sps_mem_alloc(dev, mem, ((MSM_TX_BUFS + 1) *
- + SLIM_MSGQ_BUF_LEN));
- if (ret) {
- dev_err(dev->dev, "dma_alloc_coherent failed\n");
- goto alloc_buffer_failed;
- @@ -871,10 +959,16 @@ static void msm_slim_remove_ep(struct msm_slim_ctrl *dev,
- void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg)
- {
- + int i;
- +
- if (dev->use_rx_msgqs >= MSM_MSGQ_ENABLED)
- msm_slim_remove_ep(dev, &dev->rx_msgq, &dev->use_rx_msgqs);
- if (dev->use_tx_msgqs >= MSM_MSGQ_ENABLED)
- msm_slim_remove_ep(dev, &dev->tx_msgq, &dev->use_tx_msgqs);
- + for (i = dev->port_b; i < MSM_SLIM_NPORTS; i++) {
- + if (dev->pipes[i - dev->port_b].connected)
- + msm_slim_disconn_pipe_port(dev, i - dev->port_b);
- + }
- if (dereg) {
- int i;
- for (i = dev->port_b; i < MSM_SLIM_NPORTS; i++) {
- diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
- index 9673208..99297a9 100644
- --- a/drivers/slimbus/slim-msm.h
- +++ b/drivers/slimbus/slim-msm.h
- @@ -22,7 +22,7 @@
- /* Per spec.max 40 bytes per received message */
- #define SLIM_MSGQ_BUF_LEN 40
- -#define MSM_TX_BUFS 2
- +#define MSM_TX_BUFS 32
- #define SLIM_USR_MC_GENERIC_ACK 0x25
- #define SLIM_USR_MC_MASTER_CAPABILITY 0x0
- @@ -214,7 +214,7 @@ struct msm_slim_qmi {
- struct work_struct ssr_up;
- };
- -struct msm_slim_mdm {
- +struct msm_slim_ss {
- struct notifier_block nb;
- void *ssr;
- enum msm_ctrl_state state;
- @@ -236,14 +236,15 @@ struct msm_slim_ctrl {
- u8 msg_cnt;
- u32 tx_buf[10];
- u8 rx_msgs[MSM_CONCUR_MSG][SLIM_MSGQ_BUF_LEN];
- - int tx_idx;
- + int tx_tail;
- + int tx_head;
- spinlock_t rx_lock;
- int head;
- int tail;
- int irq;
- int err;
- int ee;
- - struct completion *wr_comp;
- + struct completion **wr_comp;
- struct msm_slim_sat *satd[MSM_MAX_NSATS];
- struct msm_slim_endp pipes[7];
- struct msm_slim_sps_bam bam;
- @@ -254,6 +255,7 @@ struct msm_slim_ctrl {
- struct clk *rclk;
- struct clk *hclk;
- struct mutex tx_lock;
- + struct mutex tx_buf_lock;
- u8 pgdla;
- enum msm_slim_msgq use_rx_msgqs;
- enum msm_slim_msgq use_tx_msgqs;
- @@ -267,7 +269,8 @@ struct msm_slim_ctrl {
- u32 ver;
- struct msm_slim_qmi qmi;
- struct msm_slim_pdata pdata;
- - struct msm_slim_mdm mdm;
- + struct msm_slim_ss ext_mdm;
- + struct msm_slim_ss dsp;
- int default_ipc_log_mask;
- int ipc_log_mask;
- bool sysfs_created;
- @@ -372,7 +375,10 @@ enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
- int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
- u32 len, struct completion *comp);
- int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg);
- -u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len);
- +u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
- + struct completion *comp);
- +u32 *msm_slim_manage_tx_msgq(struct msm_slim_ctrl *dev, bool getbuf,
- + struct completion *comp);
- int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
- int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
- u32 pipe_reg, bool remote);
- diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
- index 02f4b53..d5d49c5 100644
- --- a/drivers/slimbus/slimbus.c
- +++ b/drivers/slimbus/slimbus.c
- @@ -1102,7 +1102,7 @@ int slim_xfer_msg(struct slim_controller *ctrl, struct slim_device *sbdev,
- } else
- ret = slim_processtxn(ctrl, SLIM_MSG_DEST_LOGICALADDR, mc, ec,
- SLIM_MSG_MT_CORE, rbuf, wbuf, len, mlen,
- - NULL, sbdev->laddr, NULL);
- + msg->comp, sbdev->laddr, NULL);
- xfer_err:
- return ret;
- }
- diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
- index aa403a3..126b8b3 100644
- --- a/drivers/spi/spi_qsd.c
- +++ b/drivers/spi/spi_qsd.c
- @@ -2115,10 +2115,8 @@ static void msm_spi_process_message(struct msm_spi *dd)
- dd->num_xfrs_grped = 1;
- msm_spi_process_transfer(dd);
- }
- -
- if (dd->qup_ver)
- write_force_cs(dd, 0);
- -
- return;
- error:
- @@ -2890,17 +2888,6 @@ struct msm_spi_platform_data * __init msm_spi_dt_to_pdata(
- }
- }
- -#ifdef ENABLE_SENSORS_FPRINT_SECURE
- - /* Even if you set the bam setting, */
- - /* you can't access bam when you use tzspi */
- - if ((dd->cs_gpios[0].gpio_num) == FP_SPI_CS) {
- - pdata->use_bam = false;
- - pr_info("%s: disable bam for BLSP5 tzspi\n", __func__);
- - }
- -#endif
- - dev_warn(&pdev->dev,
- - "%s pdata->use_bam: %d", __func__, pdata->use_bam);
- -
- if (pdata->use_bam) {
- if (!pdata->bam_consumer_pipe_index) {
- dev_warn(&pdev->dev,
- @@ -2962,85 +2949,6 @@ static int __init msm_spi_bam_get_resources(struct msm_spi *dd,
- return 0;
- }
- -#ifdef ENABLE_SENSORS_FPRINT_SECURE
- -int fp_spi_clock_set_rate(struct spi_device *spidev)
- -{
- - struct msm_spi *dd;
- -
- - if (!spidev) {
- - pr_err("%s: spidev pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - dd = spi_master_get_devdata(spidev->master);
- - if (!dd) {
- - pr_err("%s: spi master pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - msm_spi_clock_set(dd, spidev->max_speed_hz);
- -
- - pr_info("%s sucess\n", __func__);
- - return 0;
- -}
- -EXPORT_SYMBOL_GPL(fp_spi_clock_set_rate);
- -
- -int fp_spi_clock_enable(struct spi_device *spidev)
- -{
- - struct msm_spi *dd;
- - int rc;
- -
- - if (!spidev) {
- - pr_err("%s: spidev pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - dd = spi_master_get_devdata(spidev->master);
- - if (!dd) {
- - pr_err("%s: spi master pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - rc = clk_prepare_enable(dd->clk);
- - if (rc) {
- - pr_err("%s: unable to enable core_clk\n", __func__);
- - return rc;
- - }
- -
- - rc = clk_prepare_enable(dd->pclk);
- - if (rc) {
- - pr_err("%s: unable to enable iface_clk\n", __func__);
- - return rc;
- - }
- - pr_info("%s sucess\n", __func__);
- - return 0;
- -}
- -EXPORT_SYMBOL_GPL(fp_spi_clock_enable);
- -
- -int fp_spi_clock_disable(struct spi_device *spidev)
- -{
- - struct msm_spi *dd;
- -
- - if (!spidev) {
- - pr_err("%s: spidev pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - dd = spi_master_get_devdata(spidev->master);
- - if (!dd) {
- - pr_err("%s: spi master pointer is NULL\n", __func__);
- - return -EFAULT;
- - }
- -
- - clk_disable_unprepare(dd->clk);
- - clk_disable_unprepare(dd->pclk);
- -
- - pr_info("%s sucess\n", __func__);
- - return 0;
- -}
- -EXPORT_SYMBOL_GPL(fp_spi_clock_disable);
- -#endif
- -
- static int __init msm_spi_probe(struct platform_device *pdev)
- {
- struct spi_master *master;
- diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
- index 92b971d..7a000a6 100644
- --- a/drivers/thermal/msm_thermal.c
- +++ b/drivers/thermal/msm_thermal.c
- @@ -1586,7 +1586,6 @@ static __ref int do_freq_mitigation(void *data)
- ;
- INIT_COMPLETION(freq_mitigation_complete);
- - get_online_cpus();
- for_each_possible_cpu(cpu) {
- max_freq_req = (cpus[cpu].max_freq) ?
- msm_thermal_info.freq_limit :
- @@ -1614,7 +1613,6 @@ reset_threshold:
- cpus[cpu].freq_thresh_clear = false;
- }
- }
- - put_online_cpus();
- }
- return ret;
- }
- diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
- index 3ba54e7..3b4221c 100644
- --- a/drivers/usb/dwc3/gadget.c
- +++ b/drivers/usb/dwc3/gadget.c
- @@ -2708,13 +2708,13 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
- {
- pr_info("usb:: %s\n", __func__);
- - /*
- - * TODO take core out of low power mode when that's
- - * implemented.
- - */
- + /* Only perform resume from L2 or Early suspend states */
- + if (dwc->link_state == DWC3_LINK_STATE_U3) {
- + dbg_event(0xFF, "WAKEUP", 0);
- + dwc->gadget_driver->resume(&dwc->gadget);
- + }
- - dbg_event(0xFF, "WAKEUP", 0);
- - dwc->gadget_driver->resume(&dwc->gadget);
- + dwc->link_state = DWC3_LINK_STATE_U0;
- }
- static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
- diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
- index 0e3cef2..859f188 100644
- --- a/drivers/usb/otg/msm_otg.c
- +++ b/drivers/usb/otg/msm_otg.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2009-2014, Linux Foundation. All rights reserved.
- +/* Copyright (c) 2009-2015, 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
- @@ -1081,7 +1081,8 @@ static int msm_otg_suspend(struct msm_otg *motg)
- phy_ctrl_val |= PHY_OTGSESSVLDHV_INTEN;
- }
- if (host_bus_suspend)
- - phy_ctrl_val |= PHY_CLAMP_DPDMSE_EN;
- + phy_ctrl_val |= (PHY_CLAMP_DPDMSE_EN |PHY_DMSE_INTEN |
- + PHY_DPSE_INTEN);
- if (!(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
- writel_relaxed(phy_ctrl_val & ~PHY_RETEN, USB_PHY_CTRL);
- @@ -1239,7 +1240,8 @@ static int msm_otg_resume(struct msm_otg *motg)
- /* Disable PHY HV interrupts */
- phy_ctrl_val &=
- ~(PHY_IDHV_INTEN | PHY_OTGSESSVLDHV_INTEN);
- - phy_ctrl_val &= ~(PHY_CLAMP_DPDMSE_EN);
- + phy_ctrl_val &= ~(PHY_CLAMP_DPDMSE_EN | PHY_DMSE_INTEN |
- + PHY_DPSE_INTEN);
- writel_relaxed(phy_ctrl_val, USB_PHY_CTRL);
- motg->lpm_flags &= ~PHY_RETENTIONED;
- }
- diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
- index da26a48..0219ce2 100644
- --- a/drivers/video/msm/mdss/dsi_host_v2.c
- +++ b/drivers/video/msm/mdss/dsi_host_v2.c
- @@ -682,14 +682,25 @@ int msm_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
- return rc;
- }
- +/* MIPI_DSI_MRPS, Maximum Return Packet Size */
- +static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
- +
- +static struct dsi_cmd_desc pkt_size_cmd = {
- + {DTYPE_MAX_PKTSIZE, 1, 0, 0, 0, sizeof(max_pktsize)},
- + max_pktsize,
- +};
- +
- int msm_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
- struct dsi_buf *rp, int rlen)
- {
- - u32 *lp, data;
- - int i, off, cnt;
- + u32 *lp, data, *temp;
- + int i, j = 0, off, cnt;
- unsigned char *ctrl_base = dsi_host_private->dsi_base;
- + char reg[16];
- + int repeated_bytes = 0;
- lp = (u32 *)rp->data;
- + temp = (u32 *)reg;
- cnt = rlen;
- cnt += 3;
- cnt >>= 2;
- @@ -697,16 +708,52 @@ int msm_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
- if (cnt > 4)
- cnt = 4; /* 4 x 32 bits registers only */
- + if (rlen == 4)
- + rp->read_cnt = 4;
- + else
- + rp->read_cnt = (max_pktsize[0] + 6);
- +
- + if (rp->read_cnt > 16) {
- + int bytes_shifted, data_lost = 0, rem_header_bytes = 0;
- + /* Any data more than 16 bytes will be shifted out */
- + bytes_shifted = rp->read_cnt - rlen;
- + if (bytes_shifted >= 4)
- + data_lost = bytes_shifted - 4; /* remove dcs header */
- + else
- + rem_header_bytes = 4 - bytes_shifted; /* rem header */
- + /*
- + * (rp->len - 4) -> current rx buffer data length.
- + * If data_lost > 0, then ((rp->len - 4) - data_lost) will be
- + * the number of repeating bytes.
- + * If data_lost == 0, then ((rp->len - 4) + rem_header_bytes)
- + * will be the number of bytes repeating in between rx buffer
- + * and the current RDBK_DATA registers. We need to skip the
- + * repeating bytes.
- + */
- + repeated_bytes = (rp->len - 4) - data_lost + rem_header_bytes;
- + }
- +
- off = DSI_RDBK_DATA0;
- off += ((cnt - 1) * 4);
- for (i = 0; i < cnt; i++) {
- data = (u32)MIPI_INP(ctrl_base + off);
- - *lp++ = ntohl(data); /* to network byte order */
- + /* to network byte order */
- + if (!repeated_bytes)
- + *lp++ = ntohl(data);
- + else
- + *temp++ = ntohl(data);
- pr_debug("%s: data = 0x%x and ntohl(data) = 0x%x\n",
- __func__, data, ntohl(data));
- off -= 4;
- - rp->len += sizeof(*lp);
- + if (rlen == 4)
- + rp->len += sizeof(*lp);
- + }
- +
- + /* Skip duplicates and append other data to the rx buffer */
- + if (repeated_bytes) {
- + for (i = repeated_bytes; i < 16; i++)
- + rp->data[j++] = reg[i];
- }
- return rlen;
- @@ -798,14 +845,6 @@ static int msm_dsi_parse_rx_response(struct dsi_buf *rp)
- return rc;
- }
- -/* MIPI_DSI_MRPS, Maximum Return Packet Size */
- -static char max_pktsize[2] = {0x00, 0x00}; /* LSB tx first, 10 bytes */
- -
- -static struct dsi_cmd_desc pkt_size_cmd = {
- - {DTYPE_MAX_PKTSIZE, 1, 0, 0, 0, sizeof(max_pktsize)},
- - max_pktsize,
- -};
- -
- static int msm_dsi_set_max_packet_size(struct mdss_dsi_ctrl_pdata *ctrl,
- int size)
- {
- @@ -843,10 +882,23 @@ static int msm_dsi_cmds_rx_1(struct mdss_dsi_ctrl_pdata *ctrl,
- {
- int rc;
- struct dsi_buf *tp, *rp;
- + int rx_byte = 0;
- +
- + if (rlen <= 2)
- + rx_byte = 4;
- + else
- + rx_byte = DSI_MAX_BYTES_TO_READ;
- tp = &ctrl->tx_buf;
- rp = &ctrl->rx_buf;
- mdss_dsi_buf_init(rp);
- + rc = msm_dsi_set_max_packet_size(ctrl, rlen);
- + if (rc) {
- + pr_err("%s: dsi_set_max_pkt failed\n", __func__);
- + rc = -EINVAL;
- + goto dsi_cmds_rx_1_error;
- + }
- +
- mdss_dsi_buf_init(tp);
- rc = mdss_dsi_cmd_dma_add(tp, cmds);
- @@ -869,10 +921,12 @@ static int msm_dsi_cmds_rx_1(struct mdss_dsi_ctrl_pdata *ctrl,
- }
- if (rlen <= DSI_SHORT_PKT_DATA_SIZE) {
- - msm_dsi_cmd_dma_rx(ctrl, rp, rlen);
- + msm_dsi_cmd_dma_rx(ctrl, rp, rx_byte);
- } else {
- - msm_dsi_cmd_dma_rx(ctrl, rp, rlen + DSI_HOST_HDR_SIZE);
- - rp->len = rlen + DSI_HOST_HDR_SIZE;
- + msm_dsi_cmd_dma_rx(ctrl, rp, rx_byte);
- + rp->len = rx_byte - 2; /*2 bytes for CRC*/
- + rp->len = rp->len - (DSI_MAX_PKT_SIZE - rlen);
- + rp->data = rp->start + (16 - (rlen + 2 + DSI_HOST_HDR_SIZE));
- }
- rc = msm_dsi_parse_rx_response(rp);
- @@ -889,16 +943,15 @@ static int msm_dsi_cmds_rx_2(struct mdss_dsi_ctrl_pdata *ctrl,
- {
- int rc;
- struct dsi_buf *tp, *rp;
- - int pkt_size, data_bytes, total;
- + int pkt_size, data_bytes, dlen, end = 0, diff;
- tp = &ctrl->tx_buf;
- rp = &ctrl->rx_buf;
- mdss_dsi_buf_init(rp);
- pkt_size = DSI_MAX_PKT_SIZE;
- data_bytes = MDSS_DSI_LEN;
- - total = 0;
- - while (true) {
- + while (!end) {
- rc = msm_dsi_set_max_packet_size(ctrl, pkt_size);
- if (rc)
- break;
- @@ -909,7 +962,7 @@ static int msm_dsi_cmds_rx_2(struct mdss_dsi_ctrl_pdata *ctrl,
- pr_err("%s: dsi_cmd_dma_add failed\n", __func__);
- rc = -EINVAL;
- break;
- - }
- + }
- rc = msm_dsi_wait4video_eng_busy(ctrl);
- if (rc) {
- pr_err("%s: wait4video_eng failed\n", __func__);
- @@ -923,19 +976,32 @@ static int msm_dsi_cmds_rx_2(struct mdss_dsi_ctrl_pdata *ctrl,
- }
- msm_dsi_cmd_dma_rx(ctrl, rp, DSI_MAX_BYTES_TO_READ);
- -
- - rp->data += DSI_MAX_BYTES_TO_READ - DSI_HOST_HDR_SIZE;
- - total += data_bytes;
- - if (total >= rlen)
- - break;
- -
- - data_bytes = DSI_MAX_BYTES_TO_READ - DSI_HOST_HDR_SIZE;
- - pkt_size += data_bytes;
- + if (rlen <= data_bytes) {
- + diff = data_bytes - rlen;
- + end = 1;
- + } else {
- + diff = 0;
- + rlen -= data_bytes;
- + }
- + dlen = DSI_MAX_BYTES_TO_READ - 2;
- + dlen -= diff;
- + rp->data += dlen;
- + rp->len += dlen;
- +
- + if (!end) {
- + data_bytes = 14;
- + if (rlen < data_bytes)
- + pkt_size += rlen;
- + else
- + pkt_size += data_bytes;
- + }
- + pr_debug("%s: rp data=%x len=%d dlen=%d diff=%d\n",
- + __func__, (int) (unsigned long) rp->data,
- + rp->len, dlen, diff);
- }
- if (!rc) {
- rp->data = rp->start;
- - rp->len = rlen + DSI_HOST_HDR_SIZE;
- rc = msm_dsi_parse_rx_response(rp);
- }
- diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
- index 28e3344..879fea8 100644
- --- a/drivers/video/msm/mdss/mdp3_ctrl.c
- +++ b/drivers/video/msm/mdss/mdp3_ctrl.c
- @@ -1615,8 +1615,9 @@ static int mdp3_ctrl_lut_update(struct msm_fb_data_type *mfd,
- lut_config.lut_sel = mdp3_session->lut_sel;
- lut_config.lut_position = 0;
- lut_config.lut_dirty = true;
- - lut.color0_lut = r;
- - lut.color1_lut = g;
- + /* In HW the order is color0 = g, color1 = r and color2 = b*/
- + lut.color0_lut = g;
- + lut.color1_lut = r;
- lut.color2_lut = b;
- mutex_lock(&mdp3_session->lock);
- diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
- index 2dd66f8..7afbf46 100644
- --- a/drivers/video/msm/mdss/mdp3_dma.c
- +++ b/drivers/video/msm/mdss/mdp3_dma.c
- @@ -16,6 +16,7 @@
- #include "mdp3.h"
- #include "mdp3_dma.h"
- #include "mdp3_hwio.h"
- +#include "mdss_debug.h"
- #define DMA_STOP_POLL_SLEEP_US 1000
- #define DMA_STOP_POLL_TIMEOUT_US 200000
- @@ -610,17 +611,20 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf,
- int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
- int rc = 0;
- + ATRACE_BEGIN(__func__);
- pr_debug("mdp3_dmap_update\n");
- if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
- cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
- if (intf->active) {
- + ATRACE_BEGIN("mdp3_wait_for_dma_comp");
- rc = wait_for_completion_timeout(&dma->dma_comp,
- KOFF_TIMEOUT);
- if (rc <= 0) {
- WARN(1, "cmd kickoff timed out (%d)\n", rc);
- rc = -1;
- }
- + ATRACE_END("mdp3_wait_for_dma_comp");
- }
- }
- if (dma->update_src_cfg) {
- @@ -652,12 +656,15 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf,
- mdp3_dma_callback_enable(dma, cb_type);
- pr_debug("mdp3_dmap_update wait for vsync_comp in\n");
- if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
- + ATRACE_BEGIN("mdp3_wait_for_vsync_comp");
- rc = wait_for_completion_timeout(&dma->vsync_comp,
- KOFF_TIMEOUT);
- if (rc <= 0)
- rc = -1;
- + ATRACE_END("mdp3_wait_for_vsync_comp");
- }
- pr_debug("mdp3_dmap_update wait for vsync_comp out\n");
- + ATRACE_END(__func__);
- return rc;
- }
- @@ -763,7 +770,7 @@ static int mdp3_dmap_histo_get(struct mdp3_dma *dma)
- MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_1);
- spin_lock_irqsave(&dma->histo_lock, flag);
- - init_completion(&dma->histo_comp);
- + INIT_COMPLETION(dma->histo_comp);
- MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1);
- wmb();
- dma->histo_state = MDP3_DMA_HISTO_STATE_START;
- @@ -781,7 +788,7 @@ static int mdp3_dmap_histo_start(struct mdp3_dma *dma)
- spin_lock_irqsave(&dma->histo_lock, flag);
- - init_completion(&dma->histo_comp);
- + INIT_COMPLETION(dma->histo_comp);
- MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1);
- wmb();
- dma->histo_state = MDP3_DMA_HISTO_STATE_START;
- @@ -800,7 +807,7 @@ static int mdp3_dmap_histo_reset(struct mdp3_dma *dma)
- spin_lock_irqsave(&dma->histo_lock, flag);
- - init_completion(&dma->histo_comp);
- + INIT_COMPLETION(dma->histo_comp);
- mdp3_dma_clk_auto_gating(dma, 0);
- diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
- index 0cb3c08..f21f3ef 100644
- --- a/drivers/video/msm/mdss/mdp3_ppp.c
- +++ b/drivers/video/msm/mdss/mdp3_ppp.c
- @@ -29,6 +29,7 @@
- #include "mdp3_ppp.h"
- #include "mdp3_hwio.h"
- #include "mdp3.h"
- +#include "mdss_debug.h"
- #define MDP_IS_IMGTYPE_BAD(x) ((x) >= MDP_IMGTYPE_LIMIT)
- #define MDP_RELEASE_BW_TIMEOUT 50
- @@ -332,7 +333,9 @@ void mdp3_ppp_kickoff(void)
- init_completion(&ppp_stat->ppp_comp);
- mdp3_irq_enable(MDP3_PPP_DONE);
- ppp_enable();
- + ATRACE_BEGIN("mdp3_wait_for_ppp_comp");
- mdp3_ppp_pipe_wait();
- + ATRACE_END("mdp3_wait_for_ppp_comp");
- mdp3_irq_disable(MDP3_PPP_DONE);
- }
- @@ -893,6 +896,7 @@ int mdp3_ppp_start_blit(struct msm_fb_data_type *mfd,
- void mdp3_ppp_wait_for_fence(struct blit_req_list *req)
- {
- int i, ret = 0;
- + ATRACE_BEGIN(__func__);
- /* buf sync */
- for (i = 0; i < req->acq_fen_cnt; i++) {
- ret = sync_fence_wait(req->acq_fen[i],
- @@ -904,7 +908,7 @@ void mdp3_ppp_wait_for_fence(struct blit_req_list *req)
- }
- sync_fence_put(req->acq_fen[i]);
- }
- -
- + ATRACE_END(__func__);
- if (ret < 0) {
- while (i < req->acq_fen_cnt) {
- sync_fence_put(req->acq_fen[i]);
- @@ -1062,6 +1066,7 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
- }
- while (req) {
- mdp3_ppp_wait_for_fence(req);
- + ATRACE_BEGIN("mdp3_ppp_start");
- for (i = 0; i < req->count; i++) {
- if (!(req->req_list[i].flags & MDP_NO_BLIT)) {
- /* Do the actual blit. */
- @@ -1077,6 +1082,7 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
- MDP3_CLIENT_PPP);
- }
- }
- + ATRACE_END("mdp3_ppp_start");
- /* Signal to release fence */
- mutex_lock(&ppp_stat->req_mutex);
- mdp3_ppp_signal_timeline(req);
- diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
- index ba8cabd..53ae680 100644
- --- a/drivers/video/msm/mdss/mdss_dsi.h
- +++ b/drivers/video/msm/mdss/mdss_dsi.h
- @@ -48,8 +48,6 @@
- #define MIPI_DSI_PANEL_720P_PT 8
- #define DSI_PANEL_MAX 8
- -//#define DSI_CLK_DEBUG
- -
- enum { /* mipi dsi panel */
- DSI_VIDEO_MODE,
- DSI_CMD_MODE,
- @@ -84,7 +82,6 @@ enum dsi_panel_bl_ctrl {
- BL_PWM,
- BL_WLED,
- BL_DCS_CMD,
- - BL_GPIO_SWING,
- UNKNOWN_CTRL,
- };
- @@ -160,7 +157,6 @@ enum dsi_lane_map_type {
- #define DSI_CMD_TERM BIT(0)
- extern struct device dsi_dev;
- -extern int mdss_dsi_clk_on;
- extern u32 dsi_irq;
- extern struct mdss_dsi_ctrl_pdata *ctrl_list[];
- @@ -205,20 +201,7 @@ struct dsi_clk_desc {
- u32 pre_div_func;
- };
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- -#define DEBUG_LDI_STATUS
- -#define DYNAMIC_FPS_USE_TE_CTRL
- -extern int dynamic_fps_use_te_ctrl;
- -#endif
- -struct dsi_cmd {
- - struct dsi_cmd_desc *cmd_desc;
- - char *read_size;
- - char *read_startoffset;
- - int num_of_cmds;
- - char *cmds_buff;
- - int cmds_len;
- -};
- struct dsi_panel_cmds {
- char *buf;
- int blen;
- @@ -227,8 +210,6 @@ struct dsi_panel_cmds {
- int link_state;
- };
- -#define CMD_REQ_SINGLE_TX 0x0010
- -
- struct dsi_kickoff_action {
- struct list_head act_entry;
- void (*action) (void *);
- @@ -239,7 +220,6 @@ struct dsi_drv_cm_data {
- struct regulator *vdd_vreg;
- struct regulator *vdd_io_vreg;
- struct regulator *vdda_vreg;
- - struct regulator *iovdd_vreg;
- int broadcast_enable;
- };
- @@ -266,20 +246,10 @@ struct mdss_dsi_ctrl_pdata {
- int ndx; /* panel_num */
- int (*on) (struct mdss_panel_data *pdata);
- int (*off) (struct mdss_panel_data *pdata);
- -#if defined (CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL)
- - int (*mtp) (struct mdss_panel_data *pdata);
- -#endif
- int (*partial_update_fnc) (struct mdss_panel_data *pdata);
- int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
- int (*cmdlist_commit)(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
- void (*switch_mode) (struct mdss_panel_data *pdata, int mode);
- - int (*registered) (struct mdss_panel_data *pdata);
- - int (*dimming_init) (struct mdss_panel_data *pdata);
- - int (*event_handler) (int e);
- - int (*panel_blank) (struct mdss_panel_data *pdata, int blank);
- - void (*panel_reset) (struct mdss_panel_data *pdata, int enable);
- - int (*panel_extra_power) (struct mdss_panel_data *pdata, int enable);
- - void (*bl_fnc) (struct mdss_panel_data *pdata, u32 level);
- struct mdss_panel_data panel_data;
- unsigned char *ctrl_base;
- struct dss_io_data ctrl_io;
- @@ -289,8 +259,6 @@ struct mdss_dsi_ctrl_pdata {
- u32 bus_clk_cnt;
- u32 link_clk_cnt;
- u32 flags;
- - u32 clk_cnt;
- - u32 clk_cnt_by_dsi1;
- struct clk *mdp_core_clk;
- struct clk *ahb_clk;
- struct clk *axi_clk;
- @@ -301,39 +269,11 @@ struct mdss_dsi_ctrl_pdata {
- u8 ctrl_state;
- int panel_mode;
- int irq_cnt;
- - int mdss_dsi_clk_on;
- int rst_gpio;
- int disp_en_gpio;
- - int disp_en_gpio2;
- -#if defined(CONFIG_FB_MSM_MDSS_HX8394C_TFT_VIDEO_720P_PANEL)
- - int disp_en_vsp_gpio;
- - int disp_en_vsn_gpio;
- -#endif
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6TNMR7_PT_PANEL)
- - int tcon_ready_gpio;
- -#endif
- -#if defined(CONFIG_FB_MSM_MDSS_MAGNA_OCTA_VIDEO_720P_PANEL)
- - int lcd_crack_det;
- - int expander_enble_gpio;
- -#endif
- -#if defined(CONFIG_FB_MSM_MDSS_SHARP_HD_PANEL)
- - int disp_en_gpio_p;
- - int disp_en_gpio_n;
- -#endif
- -#if defined(CONFIG_FB_MSM_MIPI_MAGNA_OCTA_VIDEO_WXGA_PT_DUAL_PANEL)
- - int lcd_crack_det_gpio;
- - int lcd_esd_det_gpio;
- - int lcd_sel_gpio;
- - struct regulator *lcd_3p0_vreg;
- - struct regulator *lcd_1p8_vreg;
- -#endif
- - int bl_on_gpio;
- int disp_te_gpio;
- int mode_gpio;
- - int rst_gpio_requested;
- - int disp_en_gpio_requested;
- int disp_te_gpio_requested;
- - int mode_gpio_requested;
- int bklt_ctrl; /* backlight ctrl */
- int pwm_period;
- int pwm_pmic_gpio;
- @@ -341,9 +281,7 @@ struct mdss_dsi_ctrl_pdata {
- int bklt_max;
- int new_fps;
- int pwm_enabled;
- -#if defined(CONFIG_CABC_TUNING_HX8394C)
- - int current_cabc_duty;
- -#endif
- + bool dmap_iommu_map;
- struct pwm_device *pwm_bl;
- struct dsi_drv_cm_data shared_pdata;
- u32 pclk_rate;
- @@ -357,20 +295,6 @@ struct mdss_dsi_ctrl_pdata {
- struct dsi_panel_cmds off_cmds;
- struct dsi_panel_cmds status_cmds;
- u32 status_value;
- - struct dsi_panel_cmds ce_on_cmds;
- - struct dsi_panel_cmds ce_off_cmds;
- - struct dsi_panel_cmds cabc_on_cmds;
- - struct dsi_panel_cmds cabc_off_cmds;
- -#if defined(CONFIG_CABC_TUNING_HX8394C)
- - struct dsi_panel_cmds cabc_duty_72;
- - struct dsi_panel_cmds cabc_duty_74;
- - struct dsi_panel_cmds cabc_duty_78;
- - struct dsi_panel_cmds cabc_duty_82;
- -#endif
- - struct dsi_panel_cmds cabc_tune_cmds;
- -#if defined(CONFIG_FB_MSM_MDSS_CPT_QHD_PANEL)
- - struct dsi_panel_cmds disp_on_cmd;
- -#endif
- struct dsi_panel_cmds video2cmd;
- struct dsi_panel_cmds cmd2video;
- @@ -385,8 +309,6 @@ struct mdss_dsi_ctrl_pdata {
- int mdp_busy;
- struct mutex mutex;
- struct mutex cmd_mutex;
- - struct mutex dfps_mutex;
- - int mdp_tg_on;
- bool ulps;
- @@ -394,10 +316,6 @@ struct mdss_dsi_ctrl_pdata {
- struct dsi_buf rx_buf;
- struct dsi_buf status_buf;
- int status_mode;
- - int dsi_err_cnt;
- -#if defined(CONFIG_FB_MSM_MDSS_TC_DSI2LVDS_WXGA_PANEL)
- - struct regulator *iovdd_vreg;
- -#endif
- };
- struct dsi_status_data {
- @@ -406,31 +324,6 @@ struct dsi_status_data {
- struct msm_fb_data_type *mfd;
- };
- -#if defined(CONFIG_FB_MSM_MDSS_MDP3)
- -enum {
- - MIPI_RESUME_STATE,
- - MIPI_SUSPEND_STATE,
- -};
- -
- -struct mdss_dsi_driver_data {
- - struct msm_fb_data_type *mfd;
- - struct mdss_panel_data *pdata;
- - struct mdss_dsi_ctrl_pdata *ctrl_pdata;
- - struct mutex lock;
- -#if defined(CONFIG_LCD_CLASS_DEVICE)
- - const char *panel_name;
- -#endif
- -#if defined(CONFIG_GET_LCD_ATTACHED)
- - unsigned int manufacture_id;
- - int lcd_attached;
- -#endif
- -};
- -#if defined(CONFIG_MDNIE_LITE_TUNING)
- -void mdss_dsi_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_cmd_desc *cmds, int cnt);
- -#endif
- -#endif /* CONFIG_FB_MSM_MDSS_MDP3 */
- -
- -extern unsigned int gv_manufacture_id;
- int dsi_panel_device_register(struct device_node *pan_node,
- struct mdss_dsi_ctrl_pdata *ctrl_pdata);
- @@ -452,7 +345,6 @@ int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
- u8 clk_type, int enable);
- void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl,
- int enable);
- -void mdss_dsi_clk_ctrl_mdp(int ndx, int enable);
- void mdss_dsi_controller_cfg(int enable,
- struct mdss_panel_data *pdata);
- void mdss_dsi_sw_reset(struct mdss_panel_data *pdata);
- @@ -468,11 +360,7 @@ int mdss_dsi_clk_init(struct platform_device *pdev,
- void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
- int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
- void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
- -#if defined(CONFIG_FB_MSM_MDSS_MDP3)
- int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
- -#else
- -void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
- -#endif
- void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl);
- void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
- void mdss_dsi_phy_sw_reset(unsigned char *ctrl_base);
- @@ -480,9 +368,6 @@ void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl);
- void mdss_dsi_video_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl);
- void mdss_dsi_panel_pwm_cfg(struct mdss_dsi_ctrl_pdata *ctrl);
- -int mdss_dsi_cmds_single_tx(struct mdss_dsi_ctrl_pdata *ctrl,
- - struct dsi_cmd_desc *cmds, int cnt);
- -
- void mdss_dsi_ctrl_init(struct mdss_dsi_ctrl_pdata *ctrl);
- void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
- void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
- @@ -543,11 +428,4 @@ static inline struct mdss_dsi_ctrl_pdata *mdss_dsi_get_ctrl_by_index(int ndx)
- return ctrl_list[ndx];
- }
- -void mdss_dsi_mdp_busy_wait(int panel_ndx);
- -void mdss_dsi_dump_power_clk(struct mdss_panel_data *pdata, int flag);
- -
- -/*for mondrian*/
- -void pwm_backlight_enable(void);
- -void pwm_backlight_disable(void);
- -
- #endif /* MDSS_DSI_H */
- diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.c b/drivers/video/msm/mdss/mdss_dsi_cmd.c
- index e055414..4084627 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_cmd.c
- +++ b/drivers/video/msm/mdss/mdss_dsi_cmd.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2014, 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
- @@ -66,6 +66,7 @@ char *mdss_dsi_buf_init(struct dsi_buf *dp)
- off = 8 - off;
- dp->data += off;
- dp->len = 0;
- + dp->read_cnt = 0;
- return dp->data;
- }
- @@ -121,6 +122,7 @@ int mdss_dsi_buf_alloc(struct dsi_buf *dp, int size)
- dp->data = dp->start;
- dp->len = 0;
- + dp->read_cnt = 0;
- return size;
- #endif
- }
- @@ -610,6 +612,7 @@ int mdss_dsi_short_read1_resp(struct dsi_buf *rp)
- /* strip out dcs type */
- rp->data++;
- rp->len = 1;
- + rp->read_cnt -= 3;
- return rp->len;
- }
- @@ -621,6 +624,7 @@ int mdss_dsi_short_read2_resp(struct dsi_buf *rp)
- /* strip out dcs type */
- rp->data++;
- rp->len = 2;
- + rp->read_cnt -= 2;
- return rp->len;
- }
- @@ -629,6 +633,7 @@ int mdss_dsi_long_read_resp(struct dsi_buf *rp)
- /* strip out dcs header */
- rp->data += 4;
- rp->len -= 4;
- + rp->read_cnt -= 6;
- return rp->len;
- }
- diff --git a/drivers/video/msm/mdss/mdss_dsi_cmd.h b/drivers/video/msm/mdss/mdss_dsi_cmd.h
- index f806e78..7ad2d71 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_cmd.h
- +++ b/drivers/video/msm/mdss/mdss_dsi_cmd.h
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2014, 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
- @@ -30,7 +30,7 @@ struct mdss_dsi_ctrl_pdata;
- #define MDSS_DSI_MRPS 0x04 /* Maximum Return Packet Size */
- -#define MDSS_DSI_LEN 8 /* 4 x 4 - 6 - 2, bytes dcs header+crc-align */
- +#define MDSS_DSI_LEN 10 /* 4 x 4 - 4 - 2, bytes dcs header+crc-align */
- struct dsi_buf {
- u32 *hdr; /* dsi host header */
- @@ -40,6 +40,7 @@ struct dsi_buf {
- char *data; /* buffer */
- int len; /* data length */
- dma_addr_t dmap; /* mapped dma addr */
- + int read_cnt;
- };
- /* dcs read/write */
- @@ -99,6 +100,7 @@ struct dsi_cmd_desc {
- #define CMD_CLK_CTRL 0x0004
- #define CMD_REQ_NO_MAX_PKT_SIZE 0x0008
- #define CMD_REQ_LP_MODE 0x0010
- +#define CMD_REQ_HS_MODE 0x0020
- struct dcs_cmd_req {
- struct dsi_cmd_desc *cmds;
- diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
- index 9f8d388..5119f54 100644
- --- a/drivers/video/msm/mdss/mdss_dsi_host.c
- +++ b/drivers/video/msm/mdss/mdss_dsi_host.c
- @@ -1345,6 +1345,7 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
- pr_err("unable to map dma memory to iommu(%d)\n", ret);
- return -ENOMEM;
- }
- + ctrl->dmap_iommu_map = true;
- } else {
- addr = tp->dmap;
- }
- @@ -1392,9 +1393,11 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
- } else
- ret = tp->len;
- - if (is_mdss_iommu_attached())
- + if (ctrl->dmap_iommu_map) {
- msm_iommu_unmap_contig_buffer(addr,
- mdss_get_iommu_domain(domain), 0, size);
- + ctrl->dmap_iommu_map = false;
- + }
- return ret;
- }
- @@ -1677,6 +1680,10 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
- mutex_unlock(&ctrl->cmd_mutex);
- return rc;
- }
- +
- + if (req->flags & CMD_REQ_HS_MODE)
- + mdss_dsi_set_tx_power_mode(0, &ctrl->panel_data);
- +
- if (req->flags & CMD_REQ_RX)
- ret = mdss_dsi_cmdlist_rx(ctrl, req);
- #if !defined(CONFIG_MACH_S3VE3G_EUR)
- @@ -1685,6 +1692,10 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
- #endif
- else
- ret = mdss_dsi_cmdlist_tx(ctrl, req);
- +
- + if (req->flags & CMD_REQ_HS_MODE)
- + mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data);
- +
- mdss_iommu_ctrl(0);
- mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
- mdss_bus_scale_set_quota(MDSS_HW_DSI0, 0, 0);
- diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
- index 3b36353..db66761 100644
- --- a/drivers/video/msm/mdss/mdss_fb.c
- +++ b/drivers/video/msm/mdss/mdss_fb.c
- @@ -2,7 +2,7 @@
- * Core MDSS framebuffer driver.
- *
- * Copyright (C) 2007 Google Incorporated
- - * Copyright (c) 2008-2014, The Linux Foundation. All rights reserved.
- + * Copyright (c) 2008-2015, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- @@ -54,8 +54,6 @@
- #include "mdss_fb.h"
- #include "mdss_mdp_splash_logo.h"
- -#include "mdss_debug.h"
- -#include "mdss_mdp_trace.h"
- #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
- #define MDSS_FB_NUM 3
- @@ -74,17 +72,6 @@ static u32 mdss_fb_pseudo_palette[16] = {
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
- };
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- -#if defined(CONFIG_SEC_KS01_PROJECT) || defined(CONFIG_SEC_ATLANTIC_PROJECT)
- -u8 prev_csc_update = 1;
- -#endif
- -u8 csc_update = 1;
- -#endif
- -
- -#if (defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)) && defined(CONFIG_ESD_ERR_FG_RECOVERY)
- -struct mutex esd_lock;
- -#endif
- -
- static struct msm_mdp_interface *mdp_instance;
- static int mdss_fb_register(struct msm_fb_data_type *mfd);
- @@ -114,12 +101,6 @@ static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd);
- static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
- int event, void *arg);
- static void mdss_fb_set_mdp_sync_pt_threshold(struct msm_fb_data_type *mfd);
- -
- -#if defined (CONFIG_FB_MSM_MIPI_SAMSUNG_TFT_VIDEO_WQXGA_PT_PANEL)|| \
- - defined (CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
- -int get_lcd_attached(void);
- -#endif
- -
- void mdss_fb_no_update_notify_timer_cb(unsigned long data)
- {
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
- @@ -249,63 +230,6 @@ static struct led_classdev backlight_led = {
- .brightness_set = mdss_fb_set_bl_brightness,
- };
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- -static ssize_t csc_read_cfg(struct device *dev,
- - struct device_attribute *attr, char *buf)
- -{
- - ssize_t ret = 0;
- -
- - ret = snprintf(buf, PAGE_SIZE, "%d\n", csc_update);
- - return ret;
- -}
- -
- -static ssize_t csc_write_cfg(struct device *dev,
- - struct device_attribute *attr, const char *buf, size_t count)
- -{
- - ssize_t ret = strnlen(buf, PAGE_SIZE);
- - int err;
- - int mode;
- -
- - err = kstrtoint(buf, 0, &mode);
- - if (err)
- - return ret;
- -
- - csc_update = !!(u8)mode;
- -
- - pr_info("%s: csc ctrl set to %d \n", __func__, mode);
- -
- - return ret;
- -}
- -
- -static DEVICE_ATTR(csc_cfg, S_IRUGO | S_IWUSR, csc_read_cfg, csc_write_cfg);
- -
- -static struct attribute *csc_fs_attrs[] = {
- - &dev_attr_csc_cfg.attr,
- - NULL,
- -};
- -
- -static struct attribute_group csc_fs_attr_group = {
- - .attrs = csc_fs_attrs,
- -};
- -
- -int mdp4_reg_csc_fs(struct msm_fb_data_type *mfd)
- -{
- - int ret = 0;
- - struct device *dev = mfd->fbi->dev;
- -
- - ret = sysfs_create_group(&dev->kobj,
- - &csc_fs_attr_group);
- - if (ret) {
- - pr_err("%s: sysfs group creation failed, ret=%d\n",
- - __func__, ret);
- - return ret;
- - }
- -
- - kobject_uevent(&dev->kobj, KOBJ_ADD);
- - pr_info("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
- - return ret;
- -}
- -#endif
- static ssize_t mdss_fb_get_type(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- @@ -350,22 +274,15 @@ static void mdss_fb_parse_dt(struct msm_fb_data_type *mfd)
- {
- u32 data[2] = {0};
- u32 panel_xres;
- - int coeff = 1;
- struct platform_device *pdev = mfd->pdev;
- - if (of_property_read_u32_array(pdev->dev.of_node, "qcom,mdss-fb-split",
- - data, 2))
- - return;
- -#if defined(CONFIG_FB_MSM_EDP_SAMSUNG)
- - coeff = 1;
- -#else
- - coeff = 2;
- -#endif
- + of_property_read_u32_array(pdev->dev.of_node,
- + "qcom,mdss-fb-split", data, 2);
- panel_xres = mfd->panel_info->xres;
- if (data[0] && data[1]) {
- if (mfd->split_display)
- - panel_xres *= coeff;
- + panel_xres *= 2;
- if (panel_xres == data[0] + data[1]) {
- mfd->split_fb_left = data[0];
- @@ -473,8 +390,8 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev,
- ret = scnprintf(buf, PAGE_SIZE,
- "pu_en=%d\nxstart=%d\nwalign=%d\nystart=%d\nhalign=%d\n"
- "min_w=%d\nmin_h=%d",
- - pinfo->partial_update_enabled, pinfo->xstart_pix_align,
- - pinfo->width_pix_align, pinfo->ystart_pix_align,
- + pinfo->partial_update_enabled, pinfo->xstart_pix_align,
- + pinfo->width_pix_align, pinfo->ystart_pix_align,
- pinfo->height_pix_align, pinfo->min_width,
- pinfo->min_height);
- @@ -650,11 +567,8 @@ static int mdss_fb_probe(struct platform_device *pdev)
- mfd->bl_level = 0;
- mfd->bl_level_prev_scaled = 0;
- mfd->bl_scale = 1024;
- -#if defined(CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL)
- - mfd->bl_min_lvl = 20;
- -#else
- - mfd->bl_min_lvl = 0;
- -#endif
- + mfd->bl_min_lvl = 30;
- + mfd->ad_bl_level = 0;
- mfd->fb_imgType = MDP_RGBA_8888;
- mfd->pdev = pdev;
- @@ -664,11 +578,7 @@ static int mdss_fb_probe(struct platform_device *pdev)
- INIT_LIST_HEAD(&mfd->proc_list);
- mutex_init(&mfd->bl_lock);
- -#if (defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)) && defined(CONFIG_ESD_ERR_FG_RECOVERY)
- - mutex_init(&esd_lock);
- -#endif
- - mutex_init(&mfd->power_state);
- - mutex_init(&mfd->ctx_lock);
- +
- fbi_list[fbi_list_index++] = fbi;
- platform_set_drvdata(pdev, mfd);
- @@ -703,9 +613,6 @@ static int mdss_fb_probe(struct platform_device *pdev)
- mdss_fb_create_sysfs(mfd);
- mdss_fb_send_panel_event(mfd, MDSS_EVENT_FB_REGISTERED, fbi);
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- - mdp4_reg_csc_fs(mfd);
- -#endif
- mfd->mdp_sync_pt_data.fence_name = "mdp-fence";
- if (mfd->mdp_sync_pt_data.timeline == NULL) {
- @@ -906,10 +813,7 @@ static int mdss_fb_pm_suspend(struct device *dev)
- return -ENODEV;
- dev_dbg(dev, "display pm suspend\n");
- - if(mfd->panel_info->type == DTV_PANEL) {
- - dev_dbg(dev, "Ignore Suspend\n");
- - return 0;
- - }
- +
- return mdss_fb_suspend_sub(mfd);
- }
- @@ -920,10 +824,7 @@ static int mdss_fb_pm_resume(struct device *dev)
- return -ENODEV;
- dev_dbg(dev, "display pm resume\n");
- - if(mfd->panel_info->type == DTV_PANEL) {
- - dev_dbg(dev, "Ignore Resume\n");
- - return 0;
- - }
- +
- return mdss_fb_resume_sub(mfd);
- }
- #endif
- @@ -986,31 +887,26 @@ static void mdss_fb_scale_bl(struct msm_fb_data_type *mfd, u32 *bl_lvl)
- void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
- {
- struct mdss_panel_data *pdata;
- - int (*update_ad_input)(struct msm_fb_data_type *mfd);
- u32 temp = bkl_lvl;
- - int ret = -EINVAL;
- - bool is_bl_changed = (bkl_lvl != mfd->bl_level);
- + bool bl_notify_needed = false;
- - if (((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER)
- - || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) {
- + if ((((!mfd->panel_power_on && mfd->dcm_state != DCM_ENTER)
- + || !mfd->bl_updated) && !IS_CALIB_MODE_BL(mfd)) ||
- + mfd->panel_info->cont_splash_enabled) {
- mfd->unset_bl_level = bkl_lvl;
- - pr_info("[BL1] bkl_lvl (%d), bl_updated(%d), power(%d)\n",
- - bkl_lvl, mfd->bl_updated, mfd->panel_power_on);
- return;
- } else {
- mfd->unset_bl_level = 0;
- - pr_info("[BL2] bkl_lvl (%d), bl_updated(%d)\n",
- - bkl_lvl, mfd->bl_updated);
- }
- pdata = dev_get_platdata(&mfd->pdev->dev);
- if ((pdata) && (pdata->set_backlight)) {
- - if (mfd->mdp.ad_attenuate_bl) {
- - ret = (*mfd->mdp.ad_attenuate_bl)(bkl_lvl, &temp, mfd);
- - if (ret)
- - pr_err("Failed to attenuate BL\n");
- - }
- + if (mfd->mdp.ad_calc_bl)
- + (*mfd->mdp.ad_calc_bl)(mfd, temp, &temp,
- + &bl_notify_needed);
- + if (bl_notify_needed)
- + mdss_fb_bl_update_notify(mfd);
- mfd->bl_level_prev_scaled = mfd->bl_level_scaled;
- if (!IS_CALIB_MODE_BL(mfd))
- @@ -1025,51 +921,33 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
- */
- if (mfd->bl_level_scaled == temp) {
- mfd->bl_level = bkl_lvl;
- - return;
- - }
- - if(mfd->panel_power_on == true)
- - pdata->set_backlight(pdata, temp);
- - mfd->bl_level = bkl_lvl;
- - mfd->bl_level_scaled = temp;
- -
- - if (mfd->mdp.update_ad_input && is_bl_changed) {
- - update_ad_input = mfd->mdp.update_ad_input;
- - mutex_unlock(&mfd->bl_lock);
- - /* Will trigger ad_setup which will grab bl_lock */
- - update_ad_input(mfd);
- - mutex_lock(&mfd->bl_lock);
- + } else {
- + pr_debug("backlight sent to panel :%d\n", temp);
- + pdata->set_backlight(pdata, temp);
- + mfd->bl_level = bkl_lvl;
- + mfd->bl_level_scaled = temp;
- }
- - mdss_fb_bl_update_notify(mfd);
- }
- }
- -static int fist_commit_flag = 1;
- -
- void mdss_fb_update_backlight(struct msm_fb_data_type *mfd)
- {
- struct mdss_panel_data *pdata;
- - int ret = 0;
- u32 temp;
- + bool bl_notify = false;
- mutex_lock(&mfd->bl_lock);
- if (mfd->unset_bl_level && !mfd->bl_updated) {
- pdata = dev_get_platdata(&mfd->pdev->dev);
- if ((pdata) && (pdata->set_backlight)) {
- -#if defined(CONFIG_MACH_KANAS3G_CTC)
- - pr_info("[TSP]extend 200ms delay from LCD backlight\n");
- - msleep(100);
- -#endif
- mfd->bl_level = mfd->unset_bl_level;
- temp = mfd->bl_level;
- - if (mfd->mdp.ad_attenuate_bl) {
- - ret = (*mfd->mdp.ad_attenuate_bl)(temp,
- - &temp, mfd);
- - if (ret)
- - pr_err("Failed to attenuate BL\n");
- - }
- - pr_info("mfd->bl_level (%d), bl_updated (%d)\n",
- - mfd->bl_level, mfd->bl_updated);
- - pdata->set_backlight(pdata, mfd->bl_level);
- + if (mfd->mdp.ad_calc_bl)
- + (*mfd->mdp.ad_calc_bl)(mfd, temp, &temp,
- + &bl_notify);
- + if (bl_notify)
- + mdss_fb_bl_update_notify(mfd);
- + pdata->set_backlight(pdata, temp);
- mfd->bl_level_scaled = mfd->unset_bl_level;
- mfd->bl_updated = 1;
- }
- @@ -1083,23 +961,15 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- int ret = 0;
- - pr_info("FB_NUM:%d, MDSS_FB_%s ++ \n", mfd->panel_info->fb_num,
- - blank_mode? "BLANK": "UNBLANK");
- -
- if (!op_enable)
- return -EPERM;
- if (mfd->dcm_state == DCM_ENTER)
- return -EPERM;
- - mfd->blank_mode = blank_mode;
- -
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- if (!mfd->panel_power_on && mfd->mdp.on_fnc) {
- -#if defined(CONFIG_CLK_TUNING)
- - load_clk_tuning_file();
- -#endif
- ret = mfd->mdp.on_fnc(mfd);
- if (ret == 0) {
- mfd->panel_power_on = true;
- @@ -1119,7 +989,7 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
- mutex_lock(&mfd->bl_lock);
- if (!mfd->bl_updated) {
- mfd->bl_updated = 1;
- - mdss_fb_set_backlight(mfd, mfd->unset_bl_level);
- + mdss_fb_set_backlight(mfd, mfd->bl_level_prev_scaled);
- }
- mutex_unlock(&mfd->bl_lock);
- break;
- @@ -1156,17 +1026,12 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
- mdss_fb_release_fences(mfd);
- mfd->op_enable = true;
- complete(&mfd->power_off_comp);
- -
- - fist_commit_flag = 1;
- }
- break;
- }
- /* Notify listeners */
- sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event");
- - pr_info("FB_NUM:%d, MDSS_FB_%s -- \n", mfd->panel_info->fb_num,
- - blank_mode ? "BLANK": "UNBLANK");
- -
- return ret;
- }
- @@ -1174,57 +1039,13 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info)
- {
- struct mdss_panel_data *pdata;
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- -#if (defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)) && defined(CONFIG_ESD_ERR_FG_RECOVERY)
- - static int nblank_mode = FB_BLANK_UNBLANK;
- - static int final_state = -1;
- - int ret;
- -
- - mutex_lock(&esd_lock);
- -
- - printk("%s : nblank_mode[%d], blank_mode[%d], final_state[%d], esd_active[%d]\n", __func__, nblank_mode, blank_mode, final_state, info->esd_active);
- - if(info->esd_active) {
- - if(nblank_mode == FB_BLANK_POWERDOWN) {
- -// if(final_state == FB_BLANK_UNBLANK)
- -// goto NEXT_STEP1;
- -// final_state = blank_mode;
- - if(blank_mode == FB_BLANK_UNBLANK)
- - final_state = -1;
- - mutex_unlock(&esd_lock);
- - return 0;
- - } else if(nblank_mode == FB_BLANK_UNBLANK) {
- - if(final_state == FB_BLANK_POWERDOWN && blank_mode == FB_BLANK_POWERDOWN) {
- - nblank_mode = blank_mode;
- - mutex_unlock(&esd_lock);
- - return 0;
- - }
- - if(blank_mode == FB_BLANK_UNBLANK)
- - final_state = -1;
- - else if(blank_mode == FB_BLANK_POWERDOWN)
- - final_state = blank_mode;
- - goto NEXT_STEP2;
- - }
- - }
- -
- -//NEXT_STEP1:
- -
- - if(blank_mode == FB_BLANK_UNBLANK || blank_mode == FB_BLANK_POWERDOWN) {
- - nblank_mode = blank_mode;
- -// final_state = -1;
- - }
- -
- -NEXT_STEP2:
- -#endif
- mdss_fb_pan_idle(mfd);
- if (mfd->op_enable == 0) {
- if (blank_mode == FB_BLANK_UNBLANK)
- mfd->suspend.panel_power_on = true;
- else
- mfd->suspend.panel_power_on = false;
- -
- -#if (defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)) && defined(CONFIG_ESD_ERR_FG_RECOVERY)
- - mutex_unlock(&esd_lock);
- -#endif
- return 0;
- }
- pr_debug("mode: %d\n", blank_mode);
- @@ -1239,34 +1060,7 @@ NEXT_STEP2:
- pdata->panel_info.is_lpm_mode = false;
- }
- -#if (defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)) && defined(CONFIG_ESD_ERR_FG_RECOVERY)
- - ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
- - mutex_unlock(&esd_lock);
- - return ret;
- -#else
- return mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
- -#endif
- -}
- -
- -/* Set VM page protection */
- -static inline void __mdss_fb_set_page_protection(struct vm_area_struct *vma,
- - struct msm_fb_data_type *mfd)
- -{
- - if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
- - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- - else if (mfd->mdp_fb_page_protection ==
- - MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE)
- - vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot);
- - else if (mfd->mdp_fb_page_protection ==
- - MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE)
- - vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot);
- - else if (mfd->mdp_fb_page_protection ==
- - MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE)
- - vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot);
- - else
- - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- -
- -
- }
- static inline int mdss_fb_create_ion_client(struct msm_fb_data_type *mfd)
- @@ -1451,7 +1245,10 @@ static int mdss_fb_fbmem_ion_mmap(struct fb_info *info,
- }
- len = min(len, remainder);
- - __mdss_fb_set_page_protection(vma, mfd);
- + if (mfd->mdp_fb_page_protection ==
- + MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
- + vma->vm_page_prot =
- + pgprot_writecombine(vma->vm_page_prot);
- pr_debug("vma=%p, addr=%x len=%ld",
- vma, (unsigned int)addr, len);
- @@ -1495,27 +1292,17 @@ static int mdss_fb_physical_mmap(struct fb_info *info,
- u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
- unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
- struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- - int ret = 0;
- -
- +
- if (!start) {
- pr_warn("No framebuffer memory is allocated\n");
- return -ENOMEM;
- }
- - if ((vma->vm_end <= vma->vm_start) || (off >= len) ||
- - ((vma->vm_end - vma->vm_start) > (len - off)))
- - return -EINVAL;
- - ret = mdss_fb_pan_idle(mfd);
- - if (ret) {
- - pr_err("Shutdown pending. Aborting operation\n");
- - return ret;
- - }
- -
- /* Set VM flags. */
- start &= PAGE_MASK;
- if ((vma->vm_end <= vma->vm_start) ||
- - (off >= len) ||
- - ((vma->vm_end - vma->vm_start) > (len - off)))
- + (off >= len) ||
- + ((vma->vm_end - vma->vm_start) > (len - off)))
- return -EINVAL;
- off += start;
- if (off < start)
- @@ -1524,10 +1311,13 @@ static int mdss_fb_physical_mmap(struct fb_info *info,
- /* This is an IO map - tell maydump to skip this VMA */
- vma->vm_flags |= VM_IO;
- + if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
- + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- +
- /* Remap the frame buffer I/O range */
- if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- - vma->vm_end - vma->vm_start,
- - vma->vm_page_prot))
- + vma->vm_end - vma->vm_start,
- + vma->vm_page_prot))
- return -EAGAIN;
- return 0;
- @@ -1571,29 +1361,32 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom)
- size_t size = 0;
- struct platform_device *pdev = mfd->pdev;
- int rc = 0;
- - //struct device_node *fbmem_pnode = NULL;
- + struct device_node *fbmem_pnode = NULL;
- if (!pdev || !pdev->dev.of_node) {
- pr_err("Invalid device node\n");
- return -ENODEV;
- }
- -
- - of_property_read_u32(pdev->dev.of_node,
- - "qcom,memory-reservation-size", &size);
- -
- - pr_info("boot_mode_lpm = %d, boot_mode_recovery = %d\n",
- - boot_mode_lpm, boot_mode_recovery);
- -
- - /* Incase of Normal Booting, Do not reserve FB memory */
- - if ((!boot_mode_lpm) && (!boot_mode_recovery)){
- - /* Normal Booting */
- + fbmem_pnode = of_parse_phandle(pdev->dev.of_node,
- + "linux,contiguous-region", 0);
- + if (!fbmem_pnode) {
- + pr_debug("fbmem is not reserved for %s\n", pdev->name);
- mfd->fbi->screen_base = NULL;
- mfd->fbi->fix.smem_start = 0;
- return 0;
- } else {
- - of_property_read_u32(pdev->dev.of_node,
- - "qcom,memory-alt-reservation-size", &size);
- + const u32 *addr;
- + u64 len;
- +
- + addr = of_get_address(fbmem_pnode, 0, &len, NULL);
- + if (!addr) {
- + pr_err("fbmem size is not specified\n");
- + of_node_put(fbmem_pnode);
- + return -EINVAL;
- + }
- + size = (size_t)len;
- + of_node_put(fbmem_pnode);
- }
- pr_debug("%s frame buffer reserve_size=0x%zx\n", __func__, size);
- @@ -1793,12 +1586,8 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd)
- var->yres = panel_info->yres;
- if (panel_info->physical_width)
- var->width = panel_info->physical_width;
- - else if(panel_info->width)
- - var->width = panel_info->width;
- if (panel_info->physical_height)
- var->height = panel_info->physical_height;
- - else if (panel_info->height)
- - var->height = panel_info->height;
- var->xres_virtual = var->xres;
- var->yres_virtual = panel_info->yres * mfd->fb_page;
- var->bits_per_pixel = bpp * 8; /* FrameBuffer color depth */
- @@ -2100,13 +1889,7 @@ void mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data)
- int i, ret = 0;
- pr_debug("%s: wait for fences\n", sync_pt_data->fence_name);
- -#if defined (CONFIG_FB_MSM_MIPI_SAMSUNG_TFT_VIDEO_WQXGA_PT_PANEL) || \
- - defined (CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
- - if (get_lcd_attached() == 0) {
- - pr_debug("%s : lcd is not attached..\n",__func__);
- - return;
- - }
- -#endif
- +
- mutex_lock(&sync_pt_data->sync_mutex);
- /*
- * Assuming that acq_fen_cnt is sanitized in bufsync ioctl
- @@ -2415,13 +2198,9 @@ static int __mdss_fb_perform_commit(struct msm_fb_data_type *mfd)
- sync_pt_data->flushed = false;
- if (fb_backup->disp_commit.flags & MDP_DISPLAY_COMMIT_OVERLAY) {
- - if (mfd->mdp.kickoff_fnc) {
- + if (mfd->mdp.kickoff_fnc)
- ret = mfd->mdp.kickoff_fnc(mfd,
- &fb_backup->disp_commit);
- -
- - if (fist_commit_flag)
- - pr_info("kickoff done!\n");
- - }
- else
- pr_warn("no kickoff function setup for fb%d\n",
- mfd->index);
- @@ -2436,14 +2215,10 @@ static int __mdss_fb_perform_commit(struct msm_fb_data_type *mfd)
- }
- if (!ret)
- mdss_fb_update_backlight(mfd);
- - else
- - pr_err("skip mdss_fb_update_backlight..\n");
- if (IS_ERR_VALUE(ret) || !sync_pt_data->flushed)
- mdss_fb_signal_timeline(sync_pt_data);
- - fist_commit_flag = 0;
- -
- return ret;
- }
- @@ -2460,7 +2235,6 @@ static int __mdss_fb_display_thread(void *data)
- mfd->index);
- while (1) {
- - ATRACE_BEGIN(__func__);
- wait_event(mfd->commit_wait_q,
- (atomic_read(&mfd->commits_pending) ||
- kthread_should_stop()));
- @@ -2471,7 +2245,6 @@ static int __mdss_fb_display_thread(void *data)
- ret = __mdss_fb_perform_commit(mfd);
- atomic_dec(&mfd->commits_pending);
- wake_up_all(&mfd->idle_wait_q);
- - ATRACE_END(__func__);
- }
- atomic_set(&mfd->commits_pending, 0);
- @@ -2797,14 +2570,6 @@ static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
- int retire_fen_fd;
- int val;
- -#if defined (CONFIG_FB_MSM_MIPI_SAMSUNG_TFT_VIDEO_WQXGA_PT_PANEL)|| \
- - defined (CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
- - if (get_lcd_attached() == 0) {
- - pr_debug("%s : lcd is not attached..\n",__func__);
- - return 0;
- - }
- -#endif
- -
- if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
- (sync_pt_data->timeline == NULL))
- return -EINVAL;
- @@ -2958,7 +2723,8 @@ static int __ioctl_wait_idle(struct msm_fb_data_type *mfd, u32 cmd)
- (cmd != MSMFB_OVERLAY_VSYNC_CTRL) &&
- (cmd != MSMFB_ASYNC_BLIT) &&
- (cmd != MSMFB_BLIT) &&
- - (cmd != MSMFB_NOTIFY_UPDATE)) {
- + (cmd != MSMFB_NOTIFY_UPDATE) &&
- + (cmd != MSMFB_OVERLAY_PREPARE)) {
- ret = mdss_fb_pan_idle(mfd);
- }
- @@ -2988,7 +2754,6 @@ static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
- if (mfd->shutdown_pending)
- return -EPERM;
- - ATRACE_BEGIN(__func__);
- atomic_inc(&mfd->ioctl_ref_cnt);
- mdss_fb_power_setting_idle(mfd);
- @@ -3041,9 +2806,7 @@ static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
- break;
- case MSMFB_DISPLAY_COMMIT:
- - ATRACE_BEGIN("MSMFB_DISPLAY_COMMIT");
- ret = mdss_fb_display_commit(info, argp);
- - ATRACE_END("MSMFB_DISPLAY_COMMIT");
- break;
- case MSMFB_LPM_ENABLE:
- @@ -3069,7 +2832,6 @@ exit:
- if (!atomic_dec_return(&mfd->ioctl_ref_cnt))
- wake_up_all(&mfd->ioctl_q);
- - ATRACE_END(__func__);
- return ret;
- }
- @@ -3163,30 +2925,6 @@ mdss_notfound:
- }
- EXPORT_SYMBOL(mdss_register_panel);
- -int mdss_panel_force_update(struct mdss_panel_data *pdata)
- -{
- - struct msm_fb_data_type *mfd = NULL;
- - int i;
- -
- - if (!pdata)
- - return -ENODEV;
- -
- - for (i = 0; i < fbi_list_index; i++) {
- - mfd = fbi_list[i]->par;
- -
- - if (mfd->panel_info == &pdata->panel_info)
- - break;
- - }
- -
- - if (i == fbi_list_index || !mfd)
- - return -ENOENT;
- -
- - mdss_fb_pan_display_ex(mfd->fbi, &mfd->msm_fb_backup.disp_commit);
- -
- - return 0;
- -}
- -EXPORT_SYMBOL(mdss_panel_force_update);
- -
- int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp)
- {
- if (mdp_instance) {
- @@ -3199,12 +2937,6 @@ int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp)
- }
- EXPORT_SYMBOL(mdss_fb_register_mdp_instance);
- -int mdss_fb_get_first_cmt_flag(void)
- -{
- - return fist_commit_flag;
- -}
- -EXPORT_SYMBOL(mdss_fb_get_first_cmt_flag);
- -
- int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num)
- {
- struct fb_info *info;
- @@ -3257,9 +2989,6 @@ int mdss_fb_suspres_panel(struct device *dev, void *data)
- if (!mfd)
- return 0;
- - if (mfd->index == 1)
- - return 0;
- -
- event = *((bool *) data) ? MDSS_EVENT_RESUME : MDSS_EVENT_SUSPEND;
- rc = mdss_fb_send_panel_event(mfd, event, NULL);
- diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
- index 760738a..a9def29 100644
- --- a/drivers/video/msm/mdss/mdss_fb.h
- +++ b/drivers/video/msm/mdss/mdss_fb.h
- @@ -28,19 +28,8 @@
- #define MSM_FB_MAX_DEV_LIST 32
- #define MSM_FB_ENABLE_DBGFS
- -/*
- - * This temporary work around of fence time-out modification is being added to handle
- - * screen being locked up/blank after resuming - being discussed in SR# 01515705.
- - * needs to be rolled back once a solution is found to address the issue at hand
- - */
- -#if defined(CONFIG_FB_MSM_MDSS_TC_DSI2LVDS_WXGA_PANEL) || defined(CONFIG_FB_MSM_MDSS_SDC_WXGA_PANEL)\
- - || defined(CONFIG_FB_MSM_MDSS_CPT_QHD_PANEL) || defined(CONFIG_FB_MSM_MDSS_MAGNA_OCTA_VIDEO_720P_PANEL)
- -#define WAIT_FENCE_FIRST_TIMEOUT (0.5 * MSEC_PER_SEC)
- -#define WAIT_FENCE_FINAL_TIMEOUT (1 * MSEC_PER_SEC)
- -#else
- #define WAIT_FENCE_FIRST_TIMEOUT (3 * MSEC_PER_SEC)
- #define WAIT_FENCE_FINAL_TIMEOUT (10 * MSEC_PER_SEC)
- -#endif
- /* Display op timeout should be greater than total timeout */
- #define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
- WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD)
- @@ -53,6 +42,9 @@
- #define MIN(x, y) (((x) < (y)) ? (x) : (y))
- #endif
- +#define MDP_PP_AD_BL_LINEAR 0x0
- +#define MDP_PP_AD_BL_LINEAR_INV 0x1
- +
- /**
- * enum mdp_notify_event - Different frame events to indicate frame update state
- *
- @@ -133,9 +125,8 @@ struct msm_mdp_interface {
- int (*lut_update)(struct msm_fb_data_type *mfd, struct fb_cmap *cmap);
- int (*do_histogram)(struct msm_fb_data_type *mfd,
- struct mdp_histogram *hist);
- - int (*update_ad_input)(struct msm_fb_data_type *mfd);
- - int (*ad_attenuate_bl)(u32 bl, u32 *bl_out,
- - struct msm_fb_data_type *mfd);
- + int (*ad_calc_bl)(struct msm_fb_data_type *mfd, int bl_in,
- + int *bl_out, bool *bl_out_notify);
- int (*panel_register_done)(struct mdss_panel_data *pdata);
- u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp);
- int (*splash_init_fnc)(struct msm_fb_data_type *mfd);
- @@ -186,7 +177,6 @@ struct msm_fb_data_type {
- int panel_reconfig;
- u32 dst_format;
- - int resume_state;
- int panel_power_on;
- struct disp_info_type_suspend suspend;
- @@ -199,8 +189,8 @@ struct msm_fb_data_type {
- int ext_ad_ctrl;
- u32 ext_bl_ctrl;
- u32 calib_mode;
- + u32 ad_bl_level;
- u32 bl_level;
- - u32 bl_previous;
- u32 bl_scale;
- u32 bl_min_lvl;
- u32 unset_bl_level;
- @@ -208,8 +198,6 @@ struct msm_fb_data_type {
- u32 bl_level_scaled;
- u32 bl_level_prev_scaled;
- struct mutex bl_lock;
- - struct mutex power_state;
- - struct mutex ctx_lock;
- struct platform_device *pdev;
- @@ -223,17 +211,6 @@ struct msm_fb_data_type {
- struct msm_sync_pt_data mdp_sync_pt_data;
- - u32 acq_fen_cnt;
- - struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
- - int cur_rel_fen_fd;
- - struct sync_pt *cur_rel_sync_pt;
- - struct sync_fence *cur_rel_fence;
- - struct sync_fence *last_rel_fence;
- - struct sw_sync_timeline *timeline;
- - int timeline_value;
- - u32 last_acq_fen_cnt;
- - struct sync_fence *last_acq_fen[MDP_MAX_FENCE_FD];
- - struct mutex sync_mutex;
- /* for non-blocking */
- struct task_struct *disp_thread;
- atomic_t commits_pending;
- @@ -257,8 +234,6 @@ struct msm_fb_data_type {
- u32 wait_for_kickoff;
- struct ion_client *fb_ion_client;
- struct ion_handle *fb_ion_handle;
- -
- - int blank_mode;
- };
- static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
- @@ -279,49 +254,8 @@ static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
- mutex_unlock(&mfd->no_update.lock);
- }
- }
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- -#if defined(CONFIG_SEC_KS01_PROJECT)|| defined(CONFIG_SEC_ATLANTIC_PROJECT)
- -extern u8 prev_csc_update;
- -#endif
- -extern u8 csc_update;
- -#if !defined(CONFIG_SEC_KS01_PROJECT) && !defined(CONFIG_SEC_ATLANTIC_PROJECT)
- -extern u8 pre_csc_update;
- -#endif
- -#endif
- -#if defined (CONFIG_FB_MSM_MDSS_DBG_SEQ_TICK)
- -
- -enum{
- - COMMIT,
- - KICKOFF,
- - PP_DONE
- -};
- -
- -struct mdss_tick_debug {
- - u64 commit[10];
- - u64 kickoff[10];
- - u64 pingpong_done[10];
- - u8 commit_cnt;
- - u8 kickoff_cnt;
- - u8 pingpong_done_cnt;
- -};
- -void mdss_dbg_tick_save(int op_name);
- -
- -#endif
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- -enum TE_SETTING {
- - TE_SET_INIT = -1,
- - TE_SET_READY,
- - TE_SET_START,
- - TE_SET_DONE,
- - TE_SET_FAIL,
- -};
- -#endif
- -
- -extern int boot_mode_lpm, boot_mode_recovery;
- int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
- -int mdss_fb_get_first_cmt_flag(void);
- void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
- void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
- void mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data);
- @@ -329,9 +263,6 @@ void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data);
- struct sync_fence *mdss_fb_sync_get_fence(struct sw_sync_timeline *timeline,
- const char *fence_name, int val);
- int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp);
- -#if defined(CONFIG_MDNIE_TFT_MSM8X26) || defined (CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL) || defined(CONFIG_MDNIE_VIDEO_ENHANCED)
- -void mdss_negative_color(int is_negative_on);
- -#endif
- int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state);
- int mdss_fb_suspres_panel(struct device *dev, void *data);
- #endif /* MDSS_FB_H */
- diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
- index 69e0198..cfd37a0 100644
- --- a/drivers/video/msm/mdss/mdss_mdp.h
- +++ b/drivers/video/msm/mdss/mdss_mdp.h
- @@ -333,7 +333,6 @@ struct mdss_ad_info {
- u32 last_bl;
- u32 bl_data;
- u32 calc_itr;
- - uint32_t bl_bright_shift;
- uint32_t bl_lin[AD_BL_LIN_LEN];
- uint32_t bl_lin_inv[AD_BL_LIN_LEN];
- uint32_t bl_att_lut[AD_BL_ATT_LUT_LEN];
- @@ -633,6 +632,7 @@ int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
- int mdss_mdp_pp_init(struct device *dev);
- void mdss_mdp_pp_term(struct device *dev);
- +int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd);
- int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 mixer_num);
- diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- index d7394b6..b0b5a61 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
- @@ -37,11 +37,9 @@ static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
- static inline u64 apply_fudge_factor(u64 val,
- struct mdss_fudge_factor *factor)
- {
- - return fudge_factor(val, factor->numer, factor->denom);
- + return fudge_factor(val, factor->numer, factor->denom);
- }
- -#ifdef CONFIG_VIDEO_MHL_V2
- -extern int hdmi_hpd_status(void);
- -#endif
- +
- static DEFINE_MUTEX(mdss_mdp_ctl_lock);
- static int mdss_mdp_mixer_free(struct mdss_mdp_mixer *mixer);
- @@ -735,7 +733,8 @@ static void mdss_mdp_perf_calc_ctl(struct mdss_mdp_ctl *ctl,
- left_plist, (left_plist ? MDSS_MDP_MAX_STAGE : 0),
- right_plist, (right_plist ? MDSS_MDP_MAX_STAGE : 0));
- - if (ctl->is_video_mode || mdss_mdp_video_mode_intf_connected(ctl)) {
- + if (ctl->is_video_mode || ((ctl->intf_type != MDSS_MDP_NO_INTF) &&
- + mdss_mdp_video_mode_intf_connected(ctl))) {
- perf->bw_ctl =
- max(apply_fudge_factor(perf->bw_overlap,
- &mdss_res->ib_factor_overlap),
- @@ -830,17 +829,6 @@ u32 mdss_mdp_ctl_perf_get_transaction_status(struct mdss_mdp_ctl *ctl)
- unsigned long flags;
- u32 transaction_status;
- - if (!ctl)
- - return PERF_STATUS_BUSY;
- -
- - /*
- - * If Rotator mode and bandwidth has been released; return STATUS_DONE
- - * so the bandwidth is re-calculated.
- - */
- - if (ctl->mixer_left && ctl->mixer_left->rotator_mode &&
- - !ctl->perf_release_ctl_bw)
- - return PERF_STATUS_DONE;
- -
- /*
- * If Video Mode or not valid data to determine the status, return busy
- * status, so the bandwidth cannot be freed by the caller
- @@ -877,8 +865,8 @@ static inline void mdss_mdp_ctl_perf_update_bus(struct mdss_mdp_ctl *ctl)
- ctl->cur_perf.bw_ctl);
- }
- }
- - bus_ib_quota = max(bw_sum_of_intfs, mdata->perf_tune.min_bus_vote);
- - bus_ab_quota = apply_fudge_factor(bus_ib_quota,
- + bus_ib_quota = bw_sum_of_intfs;
- + bus_ab_quota = apply_fudge_factor(bw_sum_of_intfs,
- &mdss_res->ab_factor);
- trace_mdp_perf_update_bus(bus_ab_quota, bus_ib_quota);
- ATRACE_INT("bus_quota", bus_ib_quota);
- @@ -923,7 +911,7 @@ void mdss_mdp_ctl_perf_release_bw(struct mdss_mdp_ctl *ctl)
- pr_debug("transaction_status=0x%x\n", transaction_status);
- /*Release the bandwidth only if there are no transactions pending*/
- - if (!transaction_status && mdata->enable_bw_release) {
- + if (!transaction_status) {
- trace_mdp_cmd_release_bw(ctl->num);
- ctl->cur_perf.bw_ctl = 0;
- ctl->new_perf.bw_ctl = 0;
- @@ -957,16 +945,6 @@ static int mdss_mdp_select_clk_lvl(struct mdss_mdp_ctl *ctl,
- return clk_rate;
- }
- -static void mdss_mdp_perf_release_ctl_bw(struct mdss_mdp_ctl *ctl,
- - struct mdss_mdp_perf_params *perf)
- -{
- - /* Set to zero controller bandwidth. */
- - memset(perf, 0, sizeof(*perf));
- - ctl->perf_release_ctl_bw = false;
- -}
- -
- -#define ADDING_BW_ROTATE_MODE 130
- -#define ADDING_BW_LANDSCAPE_MODE 107
- static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
- int params_changed)
- {
- @@ -991,10 +969,7 @@ static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
- is_bw_released = !mdss_mdp_ctl_perf_get_transaction_status(ctl);
- if (ctl->power_on) {
- - if (ctl->perf_release_ctl_bw &&
- - mdata->enable_rotator_bw_release)
- - mdss_mdp_perf_release_ctl_bw(ctl, new);
- - else if (is_bw_released || params_changed)
- + if (is_bw_released || params_changed)
- mdss_mdp_perf_calc_ctl(ctl, new);
- /*
- * if params have just changed delay the update until
- @@ -1309,31 +1284,6 @@ int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl, bool handoff)
- }
- }
- -#if defined(CONFIG_FB_MSM_EDP_SAMSUNG)
- -int mdss_mdp_scan_pipes(void)
- -{
- - unsigned long off;
- - u32 size;
- - int i, pnum = 0;
- -
- - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- - for (i = 0; i < 6; i++) {
- - off = MDSS_MDP_REG_SSPP_OFFSET(i) + MDSS_MDP_REG_SSPP_SRC_SIZE;
- -
- - size = MDSS_MDP_REG_READ(off);
- -
- - pr_debug("%s: i=%d: addr=%x hw=%x\n",
- - __func__, i, (int)off, (int)size);
- - if (size)
- - pnum++;
- -
- - }
- - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- -
- - return pnum;
- -}
- -#endif
- -
- static inline int mdss_mdp_set_split_ctl(struct mdss_mdp_ctl *ctl,
- struct mdss_mdp_ctl *split_ctl)
- {
- @@ -1546,7 +1496,6 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
- ctl->mfd = mfd;
- ctl->panel_data = pdata;
- ctl->is_video_mode = false;
- - ctl->perf_release_ctl_bw = false;
- switch (pdata->panel_info.type) {
- case EDP_PANEL:
- @@ -1581,16 +1530,9 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
- ctl->intf_type = MDSS_INTF_HDMI;
- ctl->opmode = MDSS_MDP_CTL_OP_VIDEO_MODE;
- ctl->start_fnc = mdss_mdp_video_start;
- -#ifndef CONFIG_VIDEO_MHL_V2
- -/*
- -* mdss_mdp_limited_lut_igc_config() is for make limited range
- -* but we use limited range in MHL driver side
- -* so comment that function
- -*/
- ret = mdss_mdp_limited_lut_igc_config(ctl);
- if (ret)
- pr_err("Unable to config IGC LUT data");
- -#endif
- break;
- case WRITEBACK_PANEL:
- ctl->intf_num = MDSS_MDP_NO_INTF;
- @@ -2515,11 +2457,6 @@ int mdss_mdp_display_wakeup_time(struct mdss_mdp_ctl *ctl,
- u32 time_of_line, time_to_vsync;
- ktime_t current_time = ktime_get();
- - if (!ctl) {
- - pr_err("%s : invalid ctl\n", __func__);
- - return -ENODEV;
- - }
- -
- if (!ctl->read_line_cnt_fnc)
- return -ENOSYS;
- @@ -2629,10 +2566,6 @@ int mdss_mdp_display_wait4pingpong(struct mdss_mdp_ctl *ctl)
- return ret;
- }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- -struct mdss_mdp_ctl *commit_ctl;
- -#endif
- -
- int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
- {
- struct mdss_mdp_ctl *sctl = NULL;
- @@ -2645,11 +2578,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg)
- return -ENODEV;
- }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - commit_ctl = ctl;
- -#endif
- -
- - ATRACE_BEGIN(__func__);
- mutex_lock(&ctl->lock);
- pr_debug("commit ctl=%d play_cnt=%d\n", ctl->num, ctl->play_cnt);
- @@ -2746,7 +2674,6 @@ done:
- mutex_unlock(&ctl->lock);
- - ATRACE_END(__func__);
- return ret;
- }
- @@ -2838,15 +2765,6 @@ static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer)
- }
- }
- -u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer)
- -{
- - if (!mixer && !mixer->ctl)
- - return 0;
- -
- - return mdss_mdp_ctl_read(mixer->ctl,
- - __mdss_mdp_ctl_get_mixer_off(mixer));
- -}
- -
- static int __mdss_mdp_mixer_handoff_helper(struct mdss_mdp_mixer *mixer,
- struct mdss_mdp_pipe *pipe)
- {
- @@ -2924,18 +2842,3 @@ static void mdss_mdp_xlog_mixer_reg(struct mdss_mdp_ctl *ctl)
- data[MDSS_MDP_INTF_LAYERMIXER2],
- data[MDSS_MDP_INTF_LAYERMIXER3], off);
- }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- -void mdss_mdp_mixer_read(void)
- -{
- - int i, off;
- - u32 data[4];
- -
- - for (i=0; i < 4; i++) {
- - off = MDSS_MDP_REG_CTL_LAYER(i);
- - data[i] = mdss_mdp_ctl_read(commit_ctl, off);
- - }
- - xlog(__func__, data[0], data[1], data[2], data[3], off, 0);
- -
- -}
- -#endif
- -
- diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- old mode 100644
- new mode 100755
- index ccdb603..70e2972
- --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -12,16 +12,13 @@
- */
- #include <linux/kernel.h>
- -#include <linux/bootmem.h>
- -#include <linux/memblock.h>
- #include "mdss_mdp.h"
- #include "mdss_panel.h"
- #include "mdss_debug.h"
- -#include "mdss_fb.h"
- #include "mdss_mdp_trace.h"
- -#define VSYNC_EXPIRE_TICK 6
- +#define VSYNC_EXPIRE_TICK 4
- #define MAX_SESSIONS 2
- @@ -31,34 +28,20 @@
- #define STOP_TIMEOUT(hz) msecs_to_jiffies((1000 / hz) * (VSYNC_EXPIRE_TICK + 2))
- #define ULPS_ENTER_TIME msecs_to_jiffies(100)
- -/*
- - * STOP_TIMEOUT need to wait for cmd stop depends on fps
- - * if the command panel support 60fps the timeout value
- - * generated using 16ms(1frame). If that support 15fps the timeout value
- - * generated by 40ms(1frame)
- - */
- -#define STOP_TIMEOUT_FOR_ALPM msecs_to_jiffies(40 * (VSYNC_EXPIRE_TICK + 2))
- -
- struct mdss_mdp_cmd_ctx {
- struct mdss_mdp_ctl *ctl;
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - u32 panel_ndx;
- -#endif
- u32 pp_num;
- u8 ref_cnt;
- - struct completion pp_comp;
- struct completion stop_comp;
- + wait_queue_head_t pp_waitq;
- struct list_head vsync_handlers;
- int panel_on;
- - int koff_cnt;
- + atomic_t koff_cnt;
- int clk_enabled;
- int vsync_enabled;
- int rdptr_enabled;
- struct mutex clk_mtx;
- spinlock_t clk_lock;
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - spinlock_t te_lock;
- -#endif
- struct work_struct clk_work;
- struct delayed_work ulps_work;
- struct work_struct pp_done_work;
- @@ -72,11 +55,13 @@ struct mdss_mdp_cmd_ctx {
- u32 vclk_line; /* vsync clock per line */
- struct mdss_panel_recovery recovery;
- bool ulps;
- + struct mdss_mdp_cmd_ctx *sync_ctx; /* for partial update */
- + u32 pp_timeout_report_cnt;
- };
- struct mdss_mdp_cmd_ctx mdss_mdp_cmd_ctx_list[MAX_SESSIONS];
- -extern char board_rev;
- -int get_lcd_attached(void);
- +
- +static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx);
- static inline u32 mdss_mdp_cmd_line_count(struct mdss_mdp_ctl *ctl)
- {
- @@ -164,10 +149,10 @@ static int mdss_mdp_cmd_tearcheck_cfg(struct mdss_mdp_ctl *ctl,
- cfg |= vclks_line;
- - pr_info("%s: te->tear_check_en = %d, res=%d vclks=%x height=%d init=%d rd=%d start=%d ",
- - __func__, te->tear_check_en, pinfo->yres, vclks_line, te->sync_cfg_height,
- + pr_debug("%s: yres=%d vclks=%x height=%d init=%d rd=%d start=%d ",
- + __func__, pinfo->yres, vclks_line, te->sync_cfg_height,
- te->vsync_init_val, te->rd_ptr_irq, te->start_pos);
- - pr_info("thrd_start =%d thrd_cont=%d\n",
- + pr_debug("thrd_start =%d thrd_cont=%d\n",
- te->sync_threshold_start, te->sync_threshold_continue);
- mdss_mdp_pingpong_write(mixer, MDSS_MDP_REG_PP_SYNC_CONFIG_VSYNC, cfg);
- @@ -210,14 +195,9 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx)
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- int rc;
- - if (!ctx->panel_on) {
- - pr_info("%s: Ignore clock on because the unblank does not finished\n", __func__);
- + if (!ctx->panel_on)
- return;
- - }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctx->panel_ndx, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0);
- -#endif
- mutex_lock(&ctx->clk_mtx);
- MDSS_XLOG(ctx->pp_num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled);
- @@ -261,9 +241,6 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx)
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- int set_clk_off = 0;
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__,ctx->panel_ndx, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0);
- -#endif
- mutex_lock(&ctx->clk_mtx);
- MDSS_XLOG(ctx->pp_num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled);
- @@ -272,7 +249,7 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx)
- set_clk_off = 1;
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- - if ((ctx->clk_enabled && set_clk_off) || (get_lcd_attached() == 0)) {
- + if (ctx->clk_enabled && set_clk_off) {
- ctx->clk_enabled = 0;
- mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_SUSPEND);
- mdss_mdp_ctl_intf_event
- @@ -285,21 +262,6 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx)
- }
- mutex_unlock(&ctx->clk_mtx);
- }
- -#if defined(DYNAMIC_FPS_USE_TE_CTRL)
- -int dynamic_fps_use_te_ctrl_value;
- -#endif
- -#if defined(CONFIG_LCD_HMT)
- -int skip_te_enable = 0;
- -static unsigned int skip_te = 0;
- -#endif
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- -int te;
- -int te_cnt;
- -int te_set_done;
- -struct completion te_check_comp;
- -int get_lcd_ldi_info(void);
- -#endif
- static void mdss_mdp_cmd_readptr_done(void *arg)
- {
- @@ -308,99 +270,15 @@ static void mdss_mdp_cmd_readptr_done(void *arg)
- struct mdss_mdp_vsync_handler *tmp;
- ktime_t vsync_time;
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - static ktime_t vsync_time1;
- - static ktime_t vsync_time2;
- - static int i = 0;
- - static int time1 = 0, time2 = 0;
- -#endif
- - static long long vsync[2];
- - long long duration = 16000;
- - static int index;
- - static int add_value = 1;
- -// pr_err("mdss_mdp_cmd_readptr_done\n");
- -#if defined(DYNAMIC_FPS_USE_TE_CTRL)
- - if(dynamic_fps_use_te_ctrl)
- - {
- - if(dynamic_fps_use_te_ctrl_value)
- - {
- - dynamic_fps_use_te_ctrl_value = 0;
- - return;
- - }
- - dynamic_fps_use_te_ctrl_value = 1;
- - }
- -#endif
- -
- if (!ctx) {
- pr_err("invalid ctx\n");
- return;
- }
- -#if defined(CONFIG_LCD_HMT)
- - if (skip_te_enable) {
- - if (skip_te) {
- - pr_debug("%s : Skip TE Signal \n",__func__);
- - skip_te = 0;
- - return;
- - }
- - skip_te = 1;
- - }
- -#endif
- -
- - ATRACE_BEGIN(__func__);
- vsync_time = ktime_get();
- - vsync[index] = ktime_to_us(vsync_time);
- -
- - index += add_value;
- - add_value *= -1;
- -
- - if (vsync[0] && vsync[1])
- - duration = vsync[index + add_value] - vsync[index];
- ctl->vsync_cnt++;
- - MDSS_XLOG(0xFFFF, ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- - ctx->rdptr_enabled, duration);
- -
- - if (duration <= 8000 || duration >= 22000)
- - pr_err("[DEBUG]%s:time : %lld, duration : %lld\n",
- - __func__, vsync[index + add_value], duration);
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - if (get_lcd_ldi_info()) {
- - if (te_set_done == TE_SET_START) {
- -
- - pr_debug("%s : TE_SET_START...",__func__);
- -
- - if (i % 2 == 0) {
- - vsync_time1 = ktime_get();
- - time1 = (int)ktime_to_us(vsync_time1);
- - te = time1 && time2 ? time1 - time2 : 0;
- - pr_debug("[%s] : ktime = %d\n",__func__, te);
- - } else {
- - vsync_time2 = ktime_get();
- - time2 = (int)ktime_to_us(vsync_time2);
- - te = time1 && time2 ? time2 - time1 : 0;
- - pr_debug("[%s] : ktime = %d\n",__func__, te);
- - }
- - i++;
- -
- - pr_debug("[%s] TE = %d\n",__func__, te);
- -
- - spin_lock(&ctx->te_lock);
- - te_cnt++;
- - if (te_cnt >= 2) { // check TE using only two signal..
- - pr_debug(">>>> te_check_comp COMPLETE (%d) <<<< \n", te_cnt);
- - complete(&te_check_comp);
- - }
- - spin_unlock(&ctx->te_lock);
- - } else {
- - pr_debug("%s : not TE_SET_START...",__func__);
- - }
- - }
- -#endif
- -
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__,ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0x88888);
- -#endif
- + MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- + ctx->rdptr_enabled);
- spin_lock(&ctx->clk_lock);
- list_for_each_entry(tmp, &ctx->vsync_handlers, list) {
- @@ -411,17 +289,9 @@ static void mdss_mdp_cmd_readptr_done(void *arg)
- if (!ctx->vsync_enabled) {
- if (ctx->rdptr_enabled)
- ctx->rdptr_enabled--;
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - if (get_lcd_ldi_info())
- - if (!(te_set_done == TE_SET_DONE || te_set_done == TE_SET_FAIL))
- - {
- - pr_info("now restoring TE/ rdptr_enabled++\n");
- - if (ctx->rdptr_enabled == 0)
- - ctx->rdptr_enabled++;
- - }
- -#endif
- +
- /* keep clk on during kickoff */
- - if (ctx->rdptr_enabled == 0 && ctx->koff_cnt)
- + if (ctx->rdptr_enabled == 0 && atomic_read(&ctx->koff_cnt))
- ctx->rdptr_enabled++;
- }
- @@ -430,12 +300,8 @@ static void mdss_mdp_cmd_readptr_done(void *arg)
- (MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
- complete(&ctx->stop_comp);
- schedule_work(&ctx->clk_work);
- - index = 0;
- - add_value = 1;
- - vsync[0] = vsync[1] = 0;
- }
- - ATRACE_END(__func__);
- spin_unlock(&ctx->clk_lock);
- }
- @@ -452,42 +318,16 @@ static void mdss_mdp_cmd_underflow_recovery(void *data)
- if (!ctx->ctl)
- return;
- spin_lock_irqsave(&ctx->clk_lock, flags);
- - if (ctx->koff_cnt) {
- + if (atomic_read(&ctx->koff_cnt)) {
- mdss_mdp_ctl_reset(ctx->ctl);
- pr_debug("%s: intf_num=%d\n", __func__,
- ctx->ctl->intf_num);
- - ctx->koff_cnt--;
- + atomic_dec(&ctx->koff_cnt);
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
- ctx->pp_num);
- - complete_all(&ctx->pp_comp);
- }
- spin_unlock_irqrestore(&ctx->clk_lock, flags);
- }
- -#if 0
- -static void mdss_mdp_cmd_pingpong_recovery(struct mdss_mdp_cmd_ctx *ctx)
- -{
- - unsigned long flags;
- -
- - if (!ctx) {
- - pr_err("%s: invalid ctx\n", __func__);
- - return;
- - }
- -
- - if (!ctx->ctl)
- - return;
- - spin_lock_irqsave(&ctx->clk_lock, flags);
- - if (ctx->koff_cnt) {
- - mdss_mdp_ctl_reset(ctx->ctl);
- - pr_debug("%s: intf_num=%d\n", __func__,
- - ctx->ctl->intf_num);
- - ctx->koff_cnt--;
- - mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
- - ctx->pp_num);
- - complete_all(&ctx->pp_comp);
- - }
- - spin_unlock_irqrestore(&ctx->clk_lock, flags);
- -}
- -#endif
- static void mdss_mdp_cmd_pingpong_done(void *arg)
- {
- @@ -496,9 +336,6 @@ static void mdss_mdp_cmd_pingpong_done(void *arg)
- struct mdss_mdp_vsync_handler *tmp;
- ktime_t vsync_time;
- -#if defined (CONFIG_FB_MSM_MDSS_DBG_SEQ_TICK)
- - mdss_dbg_tick_save(PP_DONE);
- -#endif
- if (!ctx) {
- pr_err("%s: invalid ctx\n", __func__);
- return;
- @@ -514,28 +351,27 @@ static void mdss_mdp_cmd_pingpong_done(void *arg)
- }
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
- - complete_all(&ctx->pp_comp);
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h);
- -#endif
- -
- - if (ctx->koff_cnt) {
- - atomic_inc(&ctx->pp_done_cnt);
- - schedule_work(&ctx->pp_done_work);
- - ctx->koff_cnt--;
- - if (ctx->koff_cnt) {
- +
- + if (atomic_add_unless(&ctx->koff_cnt, -1, 0)) {
- + if (atomic_read(&ctx->koff_cnt))
- pr_err("%s: too many kickoffs=%d!\n", __func__,
- - ctx->koff_cnt);
- - ctx->koff_cnt = 0;
- + atomic_read(&ctx->koff_cnt));
- + if (mdss_mdp_cmd_do_notifier(ctx)) {
- + atomic_inc(&ctx->pp_done_cnt);
- + schedule_work(&ctx->pp_done_work);
- }
- - } else
- + wake_up_all(&ctx->pp_waitq);
- + } else {
- pr_err("%s: should not have pingpong interrupt!\n", __func__);
- + }
- - trace_mdp_cmd_pingpong_done(ctl, ctx->pp_num, ctx->koff_cnt);
- + trace_mdp_cmd_pingpong_done(ctl, ctx->pp_num,
- + atomic_read(&ctx->koff_cnt));
- pr_debug("%s: ctl_num=%d intf_num=%d ctx=%d kcnt=%d\n", __func__,
- - ctl->num, ctl->intf_num, ctx->pp_num, ctx->koff_cnt);
- + ctl->num, ctl->intf_num, ctx->pp_num,
- + atomic_read(&ctx->koff_cnt));
- spin_unlock(&ctx->clk_lock);
- }
- @@ -549,9 +385,7 @@ static void pingpong_done_work(struct work_struct *work)
- while (atomic_add_unless(&ctx->pp_done_cnt, -1, 0))
- mdss_mdp_ctl_notify(ctx->ctl, MDP_NOTIFY_FRAME_DONE);
- -#if !defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_FHD_FA2_PT_PANEL)
- mdss_mdp_ctl_perf_release_bw(ctx->ctl);
- -#endif
- }
- }
- @@ -604,9 +438,6 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl,
- pr_err("%s: invalid ctx\n", __func__);
- return -ENODEV;
- }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0);
- -#endif
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled);
- @@ -642,9 +473,6 @@ static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled, 0x88888);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0x88888);
- -#endif
- spin_lock_irqsave(&ctx->clk_lock, flags);
- if (handle->enabled) {
- @@ -670,34 +498,10 @@ int mdss_mdp_cmd_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, bool handoff)
- pdata = ctl->panel_data;
- pdata->panel_info.cont_splash_enabled = 0;
- -#if !defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6TNMR7_PT_PANEL)
- +
- mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)0);
- -#endif
- - return ret;
- -}
- -void mdp5_dump_regs(void)
- -{
- - int i, z, start, len;
- - int offsets[] = {0x0};
- - int length[] = {19776};
- -
- - printk("%s: =============MDSS Reg DUMP==============\n", __func__);
- - for (i = 0; i < sizeof(offsets) / sizeof(int); i++) {
- - start = offsets[i];
- - len = length[i];
- - printk("-------- Address %05x: -------\n", start);
- - for (z = 0; z < len; z++) {
- - if ((z & 3) == 0)
- - printk("%05x:", start + (z * 4));
- - printk(" %08x", MDSS_MDP_REG_READ(start + (z * 4)));
- - if ((z & 3) == 3)
- - printk("\n");
- - }
- - if ((z & 3) != 0)
- - printk("\n");
- - }
- - printk("%s: ============= END ==============\n", __func__);
- + return ret;
- }
- static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
- @@ -705,9 +509,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
- struct mdss_mdp_cmd_ctx *ctx;
- struct mdss_panel_data *pdata;
- unsigned long flags;
- - int need_wait = 0;
- int rc = 0;
- - static int recovery_cnt;
- ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
- if (!ctx) {
- @@ -717,14 +519,6 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
- pdata = ctl->panel_data;
- - spin_lock_irqsave(&ctx->clk_lock, flags);
- - if (ctx->koff_cnt > 0)
- - need_wait = 1;
- - spin_unlock_irqrestore(&ctx->clk_lock, flags);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, ctl->roi_bkup.w, ctl->roi_bkup.h);
- -#endif
- -
- ctl->roi_bkup.w = ctl->width;
- ctl->roi_bkup.h = ctl->height;
- @@ -732,50 +526,95 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
- ctx->rdptr_enabled, ctl->roi_bkup.w,
- ctl->roi_bkup.h);
- - pr_debug("%s: need_wait=%d intf_num=%d ctx=%p\n",
- - __func__, need_wait, ctl->intf_num, ctx);
- -
- - if (need_wait) {
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6E3HA1_PT_PANEL)
- - if (!board_rev)
- - rc = wait_for_completion_timeout(
- - &ctx->pp_comp, msecs_to_jiffies(20));
- - else
- -#endif
- - rc = wait_for_completion_timeout(
- - &ctx->pp_comp, msecs_to_jiffies(1000));
- - trace_mdp_cmd_wait_pingpong(ctl->num, ctx->koff_cnt);
- -
- - if (rc <= 0) {
- - WARN(1, "cmd kickoff timed out (rc = %d, recovery_cnt = %d) ctl=%d\n",
- - rc, ++recovery_cnt, ctl->num);
- + pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__,
- + ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt));
- +
- + rc = wait_event_timeout(ctx->pp_waitq,
- + atomic_read(&ctx->koff_cnt) == 0,
- + KOFF_TIMEOUT);
- +
- + if (rc <= 0) {
- + u32 status, mask;
- +
- + mask = BIT(MDSS_MDP_IRQ_PING_PONG_COMP + ctx->pp_num);
- + status = mask & readl_relaxed(ctl->mdata->mdp_base +
- + MDSS_MDP_REG_INTR_STATUS);
- + if (status) {
- + WARN(1, "pp done but irq not triggered\n");
- + mdss_mdp_irq_clear(ctl->mdata,
- + MDSS_MDP_IRQ_PING_PONG_COMP,
- + ctx->pp_num);
- + local_irq_save(flags);
- + mdss_mdp_cmd_pingpong_done(ctl);
- + local_irq_restore(flags);
- + rc = 1;
- + }
- +
- + rc = atomic_read(&ctx->koff_cnt) == 0;
- + }
- +
- + if (rc <= 0) {
- + if (!ctx->pp_timeout_report_cnt) {
- + WARN(1, "cmd kickoff timed out (%d) ctl=%d\n",
- + rc, ctl->num);
- mdss_dsi_debug_check_te(pdata);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - dumpreg();
- - mdp5_dump_regs();
- - mdss_mdp_debug_bus();
- - xlog_dump();
- -#if 0
- - mdss_mdp_cmd_pingpong_recovery(ctx);
- -#else
- - panic("Pingpong Timeout");
- -#endif
- -#endif
- - rc = -EPERM;
- - mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
- - } else {
- - rc = 0;
- + MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0", "dsi1",
- + "edp", "hdmi", "panic");
- }
- + ctx->pp_timeout_report_cnt++;
- + rc = -EPERM;
- + mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
- + atomic_add_unless(&ctx->koff_cnt, -1, 0);
- + } else {
- + rc = 0;
- + ctx->pp_timeout_report_cnt = 0;
- }
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__,ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, rc);
- -#endif
- - MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- - ctx->rdptr_enabled, rc);
- + /* signal any pending ping pong done events */
- + while (atomic_add_unless(&ctx->pp_done_cnt, -1, 0))
- + mdss_mdp_ctl_notify(ctx->ctl, MDP_NOTIFY_FRAME_DONE);
- +
- + MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->clk_enabled,
- + ctx->rdptr_enabled, rc);
- +
- return rc;
- }
- +static int mdss_mdp_cmd_do_notifier(struct mdss_mdp_cmd_ctx *ctx)
- +{
- + struct mdss_mdp_cmd_ctx *sctx;
- + sctx = ctx->sync_ctx;
- +
- + if (!sctx || atomic_read(&sctx->koff_cnt) == 0)
- + return 1;
- +
- + return 0;
- +}
- +
- +static void mdss_mdp_cmd_set_sync_ctx(
- + struct mdss_mdp_ctl *ctl, struct mdss_mdp_ctl *sctl)
- +{
- + struct mdss_mdp_cmd_ctx *ctx, *sctx;
- +
- + ctx = (struct mdss_mdp_cmd_ctx *)ctl->priv_data;
- + if (!sctl) {
- + ctx->sync_ctx = NULL;
- + return;
- + }
- +
- + sctx = (struct mdss_mdp_cmd_ctx *)sctl->priv_data;
- +
- + if (!sctl->roi.w && !sctl->roi.h) {
- + /* left only */
- + ctx->sync_ctx = NULL;
- + sctx->sync_ctx = NULL;
- + } else {
- + /* left + right */
- + ctx->sync_ctx = sctx;
- + sctx->sync_ctx = ctx;
- + }
- +}
- +
- static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl)
- {
- int rc = 0;
- @@ -794,26 +633,18 @@ static int mdss_mdp_cmd_set_partial_roi(struct mdss_mdp_ctl *ctl)
- int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- {
- - struct mdss_mdp_cmd_ctx *ctx;
- - unsigned long flags;
- + struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
- int rc;
- - ATRACE_BEGIN(__func__);
- ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
- if (!ctx) {
- pr_err("invalid ctx\n");
- return -ENODEV;
- }
- - if (get_lcd_attached() == 0) {
- - pr_err("%s : lcd is not attached..\n",__func__);
- - return -ENODEV;
- - }
- mdss_mdp_ctl_perf_set_transaction_status(ctl,
- PERF_HW_MDP_STATE, PERF_STATUS_BUSY);
- - pr_debug("%s:+\n", __func__);
- -
- if (ctx->panel_on == 0) {
- rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL);
- WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc);
- @@ -830,14 +661,12 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- MDSS_XLOG(ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w,
- ctl->roi.h);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctl->roi.x, ctl->roi.y, ctl->roi.w, ctl->roi.h, 0x1234);
- -#endif
- - spin_lock_irqsave(&ctx->clk_lock, flags);
- - ctx->koff_cnt++;
- - spin_unlock_irqrestore(&ctx->clk_lock, flags);
- - trace_mdp_cmd_kickoff(ctl->num, ctx->koff_cnt);
- + atomic_inc(&ctx->koff_cnt);
- + if (sctx)
- + atomic_inc(&sctx->koff_cnt);
- +
- + trace_mdp_cmd_kickoff(ctl->num, atomic_read(&ctx->koff_cnt));
- mdss_mdp_cmd_clk_on(ctx);
- @@ -847,25 +676,16 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- * tx dcs command if had any
- */
- mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF, NULL);
- - INIT_COMPLETION(ctx->pp_comp);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0);
- -#endif
- +
- + mdss_mdp_cmd_set_sync_ctx(ctl, NULL);
- +
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num);
- mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1);
- mdss_mdp_ctl_perf_set_transaction_status(ctl,
- - PERF_SW_COMMIT_STATE, PERF_STATUS_DONE);
- + PERF_SW_COMMIT_STATE, PERF_STATUS_DONE);
- mb();
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - {
- - void mdss_mdp_mixer_read(void);
- - mdss_mdp_mixer_read();
- - }
- -#endif
- - ATRACE_END(__func__);
- - pr_debug("%s : -- \n", __func__);
- return 0;
- }
- @@ -873,21 +693,13 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
- int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- {
- struct mdss_mdp_cmd_ctx *ctx;
- - struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;
- + struct mdss_panel_info *pinfo;
- unsigned long flags;
- struct mdss_mdp_vsync_handler *tmp, *handle;
- int need_wait = 0;
- int ret = 0;
- - u8 timeout_status = 0;
- int hz;
- - pr_debug("%s:+\n", __func__);
- -
- - if (get_lcd_attached() == 0) {
- - pr_err("%s : lcd is not attached..\n",__func__);
- - return 0;
- - }
- -
- ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
- if (!ctx) {
- pr_err("invalid ctx\n");
- @@ -899,9 +711,6 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled, XLOG_FUNC_ENTRY);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0x11111);
- -#endif
- spin_lock_irqsave(&ctx->clk_lock, flags);
- if (ctx->rdptr_enabled) {
- INIT_COMPLETION(ctx->stop_comp);
- @@ -911,43 +720,22 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- hz = mdss_panel_get_framerate(&ctl->panel_data->panel_info);
- - if (need_wait) {
- - if (pinfo->alpm_event && pinfo->alpm_event(CHECK_CURRENT_STATUS))
- - timeout_status = wait_for_completion_timeout(&ctx->stop_comp,\
- - STOP_TIMEOUT_FOR_ALPM);
- - else
- - timeout_status = wait_for_completion_timeout(&ctx->stop_comp,\
- - STOP_TIMEOUT(hz)); /*msecs_to_jiffies(1000));*/ //STOP_TIMEOUT(16 * 4 frames) -> 1000
- - if (timeout_status <= 0) {
- + if (need_wait)
- + if (wait_for_completion_timeout(&ctx->stop_comp,
- + STOP_TIMEOUT(hz))
- + <= 0) {
- WARN(1, "stop cmd time out\n");
- +
- if (IS_ERR_OR_NULL(ctl->panel_data)) {
- pr_err("no panel data\n");
- } else {
- pinfo = &ctl->panel_data->panel_info;
- -
- -#if defined(CONFIG_MACH_KLTE_CUDUOS) || defined(CONFIG_MACH_H3G_CHN_OPEN) || defined(CONFIG_MACH_H3G_CHN_CMCC) || defined(CONFIG_MACH_HLTE_CHN_CMCC) || defined(CONFIG_MACH_HLTE_CHN_TDOPEN)
- mdss_mdp_irq_disable
- (MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- ctx->pp_num);
- ctx->rdptr_enabled = 0;
- -#else
- - if (pinfo->panel_dead) {
- - mdss_mdp_irq_disable
- - (MDSS_MDP_IRQ_PING_PONG_RD_PTR,
- - ctx->pp_num);
- - ctx->rdptr_enabled = 0;
- - }
- -#endif
- }
- }
- - }
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6E3HA1_PT_PANEL)
- - if (!board_rev) {
- - mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num);
- - if (ctx->rdptr_enabled)
- - ctx->rdptr_enabled = 0;
- - }
- -#endif
- if (cancel_work_sync(&ctx->clk_work))
- pr_debug("no pending clk work\n");
- @@ -973,13 +761,11 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- memset(ctx, 0, sizeof(*ctx));
- ctl->priv_data = NULL;
- - if (ctl->num == 0) {
- - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL);
- - WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_BLANK, NULL);
- + WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- - ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, NULL);
- - WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- - }
- + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_OFF, NULL);
- + WARN(ret, "intf %d unblank error (%d)\n", ctl->intf_num, ret);
- ctl->stop_fnc = NULL;
- ctl->display_fnc = NULL;
- @@ -989,9 +775,6 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
- MDSS_XLOG(ctl->num, ctx->koff_cnt, ctx->clk_enabled,
- ctx->rdptr_enabled, XLOG_FUNC_EXIT);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0x222222);
- -#endif
- pr_debug("%s:-\n", __func__);
- return 0;
- @@ -1030,16 +813,11 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl)
- }
- ctx->ctl = ctl;
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - ctx->panel_ndx = ctl->panel_ndx;
- -#endif
- ctx->pp_num = mixer->num;
- - init_completion(&ctx->pp_comp);
- + ctx->pp_timeout_report_cnt = 0;
- + init_waitqueue_head(&ctx->pp_waitq);
- init_completion(&ctx->stop_comp);
- spin_lock_init(&ctx->clk_lock);
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - spin_lock_init(&ctx->te_lock);
- -#endif
- mutex_init(&ctx->clk_mtx);
- INIT_WORK(&ctx->clk_work, clk_ctrl_work);
- INIT_DELAYED_WORK(&ctx->ulps_work, __mdss_mdp_cmd_ulps_work);
- @@ -1058,9 +836,6 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl)
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num,
- mdss_mdp_cmd_readptr_done, ctl);
- -#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
- - xlog(__func__, ctl->num, ctx->koff_cnt, ctx->clk_enabled, ctx->rdptr_enabled, 0, 0);
- -#endif
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num,
- mdss_mdp_cmd_pingpong_done, ctl);
- diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- index b0c609b..5b99105 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2014, 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
- @@ -46,25 +46,6 @@
- #define PP_CLK_CFG_OFF 0
- #define PP_CLK_CFG_ON 1
- -#ifdef __MDSS_DEBUG__
- -
- -#define ID_PRINTK(mdss_id, fmt, args...) if(mfd->index == mdss_id) printk(fmt, ##args);
- -#else
- -
- -#define ID_PRINTK(mdss_id, fmt, args...)
- -#endif
- -
- -enum mdss_id_state {
- - ID_LCD = 0,
- - ID_HDMI = 1
- -};
- -int get_lcd_attached(void);
- -
- -
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- -u8 pre_csc_update = 0xFF;
- -#endif
- -
- #define MEM_PROTECT_SD_CTRL 0xF
- #define OVERLAY_MAX 10
- @@ -73,23 +54,12 @@ struct sd_ctrl_req {
- unsigned int enable;
- } __attribute__ ((__packed__));
- -#if defined (CONFIG_FB_MSM_MDSS_DBG_SEQ_TICK)
- -static struct mdss_tick_debug mdss_dbg_tick;
- -#endif
- -struct list_head *pipes_used_dbg;
- -
- -DEFINE_MUTEX(free_list_purge_mutex);
- -
- static atomic_t ov_active_panels = ATOMIC_INIT(0);
- static int mdss_mdp_overlay_free_fb_pipe(struct msm_fb_data_type *mfd);
- static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd);
- static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd);
- static void __overlay_kickoff_requeue(struct msm_fb_data_type *mfd);
- static void __vsync_retire_signal(struct msm_fb_data_type *mfd, int val);
- -#if defined(CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL)
- -extern int err_fg_working;
- -extern int lcd_connected_status;
- -#endif
- static inline u32 left_lm_w_from_mfd(struct msm_fb_data_type *mfd)
- {
- @@ -409,8 +379,8 @@ static int __mdss_mdp_validate_pxl_extn(struct mdss_mdp_pipe *pipe)
- ((pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_420) ||
- (pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_H2V1))) {
- src_w >>= 1;
- - }
- -
- + }
- +
- if (plane == 1 && !pipe->vert_deci &&
- ((pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_420) ||
- (pipe->src_fmt->chroma_sample == MDSS_MDP_CHROMA_H1V2)))
- @@ -433,7 +403,8 @@ static int __mdss_mdp_validate_pxl_extn(struct mdss_mdp_pipe *pipe)
- vert_req_pixels = pipe->scale.num_ext_pxls_top[plane] +
- pipe->scale.num_ext_pxls_btm[plane];
- - vert_fetch_pixels = (pipe->scale.top_ftch[plane] >> pipe->vert_deci) +
- + vert_fetch_pixels =
- + (pipe->scale.top_ftch[plane] >> pipe->vert_deci) +
- pipe->scale.top_rpt[plane] +
- (pipe->scale.btm_ftch[plane] >> pipe->vert_deci)+
- pipe->scale.btm_rpt[plane];
- @@ -542,16 +513,9 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
- if (req->flags & MDP_ROT_90) {
- pr_err("unsupported inline rotation\n");
- - return -ENOTSUPP;
- + return -EOPNOTSUPP;
- }
- -#if defined(CONFIG_MDSS_UD_FLIP)
- - if (req->flags & MDP_FLIP_UD)
- - req->flags &= ~MDP_FLIP_UD;
- - else
- - req->flags |= MDP_FLIP_UD;
- -#endif
- -
- if ((req->dst_rect.w > MAX_DST_W) || (req->dst_rect.h > MAX_DST_H)) {
- pr_err("exceeded max mixer supported resolution %dx%d\n",
- req->dst_rect.w, req->dst_rect.h);
- @@ -632,7 +596,7 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
- if (pipe == NULL) {
- pr_err("error allocating pipe\n");
- - return -ENOMEM;
- + return -ENODEV;
- }
- ret = mdss_mdp_pipe_map(pipe);
- @@ -739,7 +703,6 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
- pipe->pp_cfg.igc_cfg.c0_c1_data,
- sizeof(uint32_t) * len);
- if (ret) {
- - pr_err("pp_cfg1 get from user was NULL \n");
- ret = -ENOMEM;
- goto exit_fail;
- }
- @@ -747,7 +710,6 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
- pipe->pp_cfg.igc_cfg.c2_data,
- sizeof(uint32_t) * len);
- if (ret) {
- - pr_err("pp_cfg2 get from user was NULL \n");
- ret = -ENOMEM;
- goto exit_fail;
- }
- @@ -775,7 +737,6 @@ int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
- pipe->pp_cfg.hist_lut_cfg.data,
- sizeof(uint32_t) * len);
- if (ret) {
- - pr_err("lut get from user was NULL \n");
- ret = -ENOMEM;
- goto exit_fail;
- }
- @@ -867,14 +828,6 @@ static int mdss_mdp_overlay_set(struct msm_fb_data_type *mfd,
- }
- if (req->flags & MDSS_MDP_ROT_ONLY) {
- -#if defined(CONFIG_MDSS_UD_FLIP)
- - if (req->flags & MDP_BWC_EN) {
- - if (req->flags & MDP_FLIP_LR)
- - req->flags &= ~MDP_FLIP_LR;
- - else
- - req->flags |= MDP_FLIP_LR;
- - }
- -#endif
- ret = mdss_mdp_rotator_setup(mfd, req);
- } else if (req->src.format == MDP_RGB_BORDERFILL) {
- req->id = BORDERFILL_NDX;
- @@ -900,7 +853,7 @@ int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd,
- int num_planes,
- u32 flags)
- {
- - int i, rc = 0;
- + int i, rc;
- if ((num_planes <= 0) || (num_planes > MAX_PLANES))
- return -EINVAL;
- @@ -960,14 +913,10 @@ static void __mdss_mdp_overlay_free_list_purge(struct msm_fb_data_type *mfd)
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- int i;
- - mutex_lock(&free_list_purge_mutex);
- -
- pr_debug("purging fb%d free list\n", mfd->index);
- for (i = 0; i < mdp5_data->free_list_size; i++)
- mdss_mdp_overlay_free_buf(&mdp5_data->free_list[i]);
- mdp5_data->free_list_size = 0;
- -
- - mutex_unlock(&free_list_purge_mutex);
- }
- /**
- @@ -992,24 +941,18 @@ static void __mdss_mdp_overlay_free_list_add(struct msm_fb_data_type *mfd,
- memset(buf, 0, sizeof(*buf));
- }
- -/**
- - * mdss_mdp_overlay_cleanup() - handles cleanup after frame commit
- - * @mfd: Msm frame buffer data structure for the associated fb
- - * @destroy_pipes: list of pipes that should be destroyed as part of cleanup
- - *
- - * Goes through destroy_pipes list and ensures they are ready to be destroyed
- - * and cleaned up. Also cleanup of any pipe buffers after flip.
- - */
- -static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd,
- - struct list_head *destroy_pipes)
- +static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd)
- {
- struct mdss_mdp_pipe *pipe, *tmp;
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
- bool recovery_mode = false;
- + LIST_HEAD(destroy_pipes);
- mutex_lock(&mdp5_data->list_lock);
- - list_for_each_entry(pipe, destroy_pipes, list) {
- + list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_cleanup, list) {
- + list_move(&pipe->list, &destroy_pipes);
- +
- /* make sure pipe fetch has been halted before freeing buffer */
- if (mdss_mdp_pipe_fetch_halt(pipe)) {
- /*
- @@ -1044,7 +987,7 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd,
- }
- }
- - list_for_each_entry_safe(pipe, tmp, destroy_pipes, list) {
- + list_for_each_entry_safe(pipe, tmp, &destroy_pipes, list) {
- /*
- * in case of secure UI, the buffer needs to be released as
- * soon as session is closed.
- @@ -1054,7 +997,6 @@ static void mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd,
- else
- __mdss_mdp_overlay_free_list_add(mfd, &pipe->front_buf);
- mdss_mdp_overlay_free_buf(&pipe->back_buf);
- - list_del_init(&pipe->list);
- mdss_mdp_pipe_destroy(pipe);
- }
- mutex_unlock(&mdp5_data->list_lock);
- @@ -1112,11 +1054,6 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd)
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- struct mdss_mdp_ctl *ctl = mdp5_data->ctl;
- - if (!ctl) {
- - pr_err("%s unable to access ctrl\n", __func__);
- - return -ENODEV;
- - }
- -
- if (ctl->power_on) {
- if (mdp5_data->mdata->ulps) {
- rc = mdss_mdp_footswitch_ctrl_ulps(1, &mfd->pdev->dev);
- @@ -1298,29 +1235,15 @@ static void __overlay_kickoff_requeue(struct msm_fb_data_type *mfd)
- mdss_mdp_display_wait4comp(ctl);
- }
- -#if defined(CONFIG_MDNIE_LITE_TUNING)
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_FULL_HD_PT_PANEL)
- -static bool mdss_first_init = true;
- -#endif
- -#endif
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- -int get_lcd_ldi_info(void);
- -#endif
- -
- int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
- struct mdp_display_commit *data)
- {
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- - struct mdss_mdp_pipe *pipe, *tmp;
- + struct mdss_mdp_pipe *pipe;
- struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
- int ret = 0;
- int sd_in_pipe = 0;
- bool need_cleanup = false;
- - LIST_HEAD(destroy_pipes);
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - int te_ret = 0;
- -#endif
- ATRACE_BEGIN(__func__);
- if (ctl->shared_lock) {
- @@ -1330,17 +1253,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
- }
- mutex_lock(&mdp5_data->ov_lock);
- - if (mfd->panel_info->type == DTV_PANEL) {
- - ret = mdss_mdp_overlay_start(mfd);
- - if (ret) {
- - pr_err("unable to start overlay %d (%d)\n",
- - mfd->index, ret);
- - mutex_unlock(&mdp5_data->ov_lock);
- - if (ctl->shared_lock)
- - mutex_unlock(ctl->shared_lock);
- - return ret;
- - }
- - }
- mutex_lock(&mdp5_data->list_lock);
- /*
- @@ -1374,10 +1286,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
- * Setup pipe in solid fill before unstaging,
- * to ensure no fetches are happening after dettach or reattach.
- */
- - list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_cleanup, list) {
- + list_for_each_entry(pipe, &mdp5_data->pipes_cleanup, list) {
- mdss_mdp_pipe_queue_data(pipe, NULL);
- mdss_mdp_mixer_pipe_unstage(pipe);
- - list_move(&pipe->list, &destroy_pipes);
- need_cleanup = true;
- }
- @@ -1391,7 +1302,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
- ret = mdss_mdp_wb_kickoff(mfd);
- ATRACE_END("wb_kickoff");
- } else {
- + ATRACE_BEGIN("display_commit");
- ret = mdss_mdp_display_commit(mdp5_data->ctl, NULL);
- + ATRACE_END("display_commit");
- }
- if (!need_cleanup) {
- @@ -1419,40 +1332,9 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
- }
- mdss_fb_update_notify_update(mfd);
- -#if defined(CONFIG_MDNIE_LITE_TUNING)
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_FULL_HD_PT_PANEL) \
- - || defined(CONFIG_FB_MSM_MIPI_SAMSUNG_YOUM_CMD_FULL_HD_PT_PANEL)
- - if(mdss_first_init)
- - {
- - mdss_mdp_ctl_intf_event(mdp5_data->ctl, MDSS_EVENT_MDNIE_DEFAULT_UPDATE, NULL);
- - mdss_first_init = false;
- - }
- -#endif
- -#endif
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)
- - if (get_lcd_ldi_info()) {
- - te_ret = mdss_mdp_ctl_intf_event(mdp5_data->ctl, MDSS_EVENT_TE_UPDATE, NULL);
- - if (te_ret < 0) {
- - mdss_mdp_ctl_intf_event(mdp5_data->ctl, MDSS_EVENT_TE_RESTORE, NULL);
- - }
- - }
- -#endif
- -
- -#if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_FULL_HD_PT_PANEL) || defined (CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQHD_PT_PANEL)\
- - || defined(CONFIG_FB_MSM_MIPI_SAMSUNG_YOUM_CMD_FULL_HD_PT_PANEL) || defined(CONFIG_FB_MSM_MIPI_JDI_TFT_VIDEO_FULL_HD_PT_PANEL)\
- - || defined (CONFIG_FB_MSM_MIPI_MAGNA_OCTA_CMD_HD_PT_PANEL) \
- - || defined (CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6TNMR7_PT_PANEL) \
- - || defined (CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6E3HA1_PT_PANEL)
- - mdss_mdp_ctl_intf_event(mdp5_data->ctl, MDSS_EVENT_FRAME_UPDATE, NULL);
- -#endif
- -#if defined(CONFIG_FB_MSM_MDSS_SDC_WXGA_PANEL) && !defined(CONFIG_MACH_DEGASLTE_SPR)
- - mdss_mdp_ctl_intf_event(mdp5_data->ctl, MDSS_EVENT_BACKLIGHT_LATE_ON, NULL);
- -#endif
- -
- commit_fail:
- ATRACE_BEGIN("overlay_cleanup");
- - mdss_mdp_overlay_cleanup(mfd, &destroy_pipes);
- + mdss_mdp_overlay_cleanup(mfd);
- ATRACE_END("overlay_cleanup");
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_FLUSHED);
- @@ -1537,21 +1419,10 @@ static int mdss_mdp_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
- goto done;
- }
- -#if defined(CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL)
- - if(lcd_connected_status == 1){
- - if (!mfd->panel_power_on && !err_fg_working) {
- - ret = -EPERM;
- - goto done;
- - }
- - }
- -
- -#else
- if (!mfd->panel_power_on) {
- ret = -EPERM;
- goto done;
- }
- -#endif
- -
- pr_debug("unset ndx=%x\n", ndx);
- @@ -1686,8 +1557,6 @@ static void mdss_mdp_overlay_force_cleanup(struct msm_fb_data_type *mfd)
- {
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- struct mdss_mdp_ctl *ctl = mdp5_data->ctl;
- - struct mdss_mdp_pipe *pipe, *tmp;
- - LIST_HEAD(destroy_pipes);
- int ret;
- pr_debug("forcing cleanup to unset dma pipes on fb%d\n", mfd->index);
- @@ -1702,12 +1571,7 @@ static void mdss_mdp_overlay_force_cleanup(struct msm_fb_data_type *mfd)
- mdss_mdp_display_wait4comp(ctl);
- }
- - mutex_lock(&mdp5_data->list_lock);
- - list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_cleanup, list) {
- - list_move(&pipe->list, &destroy_pipes);
- - }
- - mutex_unlock(&mdp5_data->list_lock);
- - mdss_mdp_overlay_cleanup(mfd, &destroy_pipes);
- + mdss_mdp_overlay_cleanup(mfd);
- }
- static void mdss_mdp_overlay_force_dma_cleanup(struct mdss_data_type *mdata)
- @@ -1891,6 +1755,7 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd)
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- +
- bpp = fbi->var.bits_per_pixel / 8;
- offset = fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
- @@ -2027,22 +1892,6 @@ static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl,
- }
- pr_debug("vsync on fb%d play_cnt=%d\n", mfd->index, ctl->play_cnt);
- -#if defined(CONFIG_SEC_KS01_PROJECT) ||defined(CONFIG_SEC_ATLANTIC_PROJECT)
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- - if (csc_update != prev_csc_update) {
- - struct mdss_mdp_pipe *pipe, *next;
- -
- - list_for_each_entry_safe(pipe, next, &mdp5_data->pipes_used,
- - list) {
- - if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) {
- - mdss_mdp_csc_setup(MDSS_MDP_BLOCK_SSPP, pipe->num, 1,
- - MDSS_MDP_CSC_YUV2RGB);
- - }
- - }
- - prev_csc_update = csc_update;
- - }
- -#endif
- -#endif
- mdp5_data->vsync_time = t;
- sysfs_notify_dirent(mdp5_data->vsync_event_sd);
- @@ -2837,21 +2686,16 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- switch (cmd) {
- case MSMFB_MDP_PP:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_MDP_PP\n", __func__);
- ret = mdss_mdp_pp_ioctl(mfd, argp);
- break;
- case MSMFB_HISTOGRAM_START:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_HISTOGRAM_START\n", __func__);
- case MSMFB_HISTOGRAM_STOP:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_HISTOGRAM_STOP\n", __func__);
- case MSMFB_HISTOGRAM:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_HISTOGRAM\n", __func__);
- ret = mdss_mdp_histo_ioctl(mfd, cmd, argp);
- break;
- case MSMFB_OVERLAY_GET:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_GET\n", __func__);
- req = kmalloc(sizeof(struct mdp_overlay), GFP_KERNEL);
- if (!req)
- return -ENOMEM;
- @@ -2868,13 +2712,9 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- break;
- case MSMFB_OVERLAY_SET:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_SET\n", __func__);
- req = kmalloc(sizeof(struct mdp_overlay), GFP_KERNEL);
- if (!req)
- - {
- - pr_err("MSMFB_OVERLAY_SET kmalloc result was NULL \n");
- return -ENOMEM;
- - }
- ret = copy_from_user(req, argp, sizeof(*req));
- if (!ret) {
- ret = mdss_mdp_overlay_set(mfd, req);
- @@ -2888,13 +2728,11 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- case MSMFB_OVERLAY_UNSET:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_UNSET\n", __func__);
- if (!IS_ERR_VALUE(copy_from_user(&val, argp, sizeof(val))))
- ret = mdss_mdp_overlay_unset(mfd, val);
- break;
- case MSMFB_OVERLAY_PLAY_ENABLE:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_PLAY_ENABLE\n", __func__);
- if (!copy_from_user(&val, argp, sizeof(val))) {
- mdp5_data->overlay_play_enable = val;
- ret = 0;
- @@ -2905,7 +2743,6 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- break;
- case MSMFB_OVERLAY_PLAY:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_PLAY\n", __func__);
- if (mdp5_data->overlay_play_enable) {
- struct msmfb_overlay_data data;
- @@ -2921,7 +2758,6 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- break;
- case MSMFB_OVERLAY_PLAY_WAIT:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_PLAY_WAIT\n", __func__);
- if (mdp5_data->overlay_play_enable) {
- struct msmfb_overlay_data data;
- @@ -2937,32 +2773,25 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- break;
- case MSMFB_VSYNC_CTRL:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_VSYNC_CTRL\n", __func__);
- case MSMFB_OVERLAY_VSYNC_CTRL:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_VSYNC_CTRL\n", __func__);
- if (!copy_from_user(&val, argp, sizeof(val))) {
- - mutex_lock(&mfd->ctx_lock);
- ret = mdss_mdp_overlay_vsync_ctrl(mfd, val);
- - mutex_unlock(&mfd->ctx_lock);
- } else {
- pr_err("MSMFB_OVERLAY_VSYNC_CTRL failed (%d)\n", ret);
- ret = -EFAULT;
- }
- break;
- case MSMFB_OVERLAY_COMMIT:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_OVERLAY_COMMIT\n", __func__);
- mdss_fb_wait_for_fence(&(mfd->mdp_sync_pt_data));
- ret = mfd->mdp.kickoff_fnc(mfd, NULL);
- break;
- case MSMFB_METADATA_SET:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_METADATA_SET\n", __func__);
- ret = copy_from_user(&metadata, argp, sizeof(metadata));
- if (ret)
- return ret;
- ret = mdss_fb_set_metadata(mfd, &metadata);
- break;
- case MSMFB_METADATA_GET:
- - ID_PRINTK(ID_HDMI, "%s() MSMFB_METADATA_GET\n", __func__);
- ret = copy_from_user(&metadata, argp, sizeof(metadata));
- if (ret)
- return ret;
- @@ -2974,7 +2803,6 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd,
- ret = __handle_ioctl_overlay_prepare(mfd, argp);
- break;
- default:
- - ID_PRINTK(ID_HDMI, "%s() default\n", __func__);
- if (mfd->panel.type == WRITEBACK_PANEL)
- ret = mdss_mdp_wb_ioctl_handler(mfd, cmd, argp);
- break;
- @@ -3050,7 +2878,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- int rc;
- struct mdss_overlay_private *mdp5_data;
- struct mdss_mdp_ctl *ctl = NULL;
- - struct mdss_panel_info *pinfo = mfd->panel_info;
- if (!mfd)
- return -ENODEV;
- @@ -3058,7 +2885,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- if (mfd->key != MFD_KEY)
- return -EINVAL;
- - pr_info("%s: ++ \n",__func__);
- mdp5_data = mfd_to_mdp5_data(mfd);
- if (!mdp5_data)
- return -EINVAL;
- @@ -3071,8 +2897,7 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- }
- if (!mfd->panel_info->cont_splash_enabled &&
- - (mfd->panel_info->type != DTV_PANEL) &&
- - !(pinfo->alpm_event && pinfo->alpm_event(CHECK_PREVIOUS_STATUS))) {
- + (mfd->panel_info->type != DTV_PANEL)) {
- rc = mdss_mdp_overlay_start(mfd);
- if (!IS_ERR_VALUE(rc) &&
- (mfd->panel_info->type != WRITEBACK_PANEL)) {
- @@ -3089,9 +2914,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd)
- pr_err("Failed to turn on fb%d\n", mfd->index);
- mdss_mdp_overlay_off(mfd);
- }
- -
- - pr_info("%s: -- \n",__func__);
- -
- return rc;
- }
- @@ -3101,7 +2923,6 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- struct mdss_overlay_private *mdp5_data;
- struct mdss_mdp_mixer *mixer;
- int need_cleanup;
- - struct mdss_panel_info *pinfo;
- if (!mfd)
- return -ENODEV;
- @@ -3109,8 +2930,6 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- if (mfd->key != MFD_KEY)
- return -EINVAL;
- - pinfo = mfd->panel_info;
- -
- mdp5_data = mfd_to_mdp5_data(mfd);
- if (!mdp5_data || !mdp5_data->ctl) {
- @@ -3136,13 +2955,8 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- mutex_unlock(&mdp5_data->list_lock);
- if (need_cleanup) {
- - if (pinfo->alpm_event && pinfo->alpm_event(CHECK_CURRENT_STATUS)) {
- - pr_debug("[ALPM_DEBUG] %s, Skip cleanup pipes on fb%d\n",\
- - __func__, mfd->index);
- - } else {
- - pr_debug("cleaning up pipes on fb%d\n", mfd->index);
- - mdss_mdp_overlay_kickoff(mfd, NULL);
- - }
- + pr_debug("cleaning up pipes on fb%d\n", mfd->index);
- + mdss_mdp_overlay_kickoff(mfd, NULL);
- }
- /*
- @@ -3184,15 +2998,9 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd)
- int mdss_panel_register_done(struct mdss_panel_data *pdata)
- {
- - static int first_register=true;
- - /*
- - * Clocks are already on if continuous splash is enabled,
- - * increasing ref_cnt to help balance clocks once done.
- - */
- - if (pdata->panel_info.cont_splash_enabled && first_register) {
- + if (pdata->panel_info.cont_splash_enabled)
- mdss_mdp_footswitch_ctrl_splash(1);
- - first_register=false;
- - }
- +
- return 0;
- }
- @@ -3273,11 +3081,6 @@ static int mdss_mdp_overlay_handoff(struct msm_fb_data_type *mfd)
- mdp5_data->ctl = ctl;
- }
- - if (IS_ERR_OR_NULL(ctl)) {
- - rc = PTR_ERR(ctl);
- - goto error;
- - }
- -
- /*
- * vsync interrupt needs on during continuous splash, this is
- * to initialize necessary ctl members here.
- @@ -3568,6 +3371,8 @@ int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd)
- }
- }
- + if (mdss_mdp_pp_overlay_init(mfd))
- + pr_warn("Failed to initialize pp overlay data.\n");
- return rc;
- init_fail:
- kfree(mdp5_data);
- @@ -3589,60 +3394,3 @@ static int mdss_mdp_overlay_fb_parse_dt(struct msm_fb_data_type *mfd)
- return rc;
- }
- -
- -#if defined (CONFIG_FB_MSM_MDSS_DBG_SEQ_TICK)
- -void mdss_dbg_tick_save(int op_name)
- -{
- - ktime_t tick;
- - tick = ktime_get();
- -
- - switch(op_name)
- - {
- - case COMMIT :
- - mdss_dbg_tick.commit[mdss_dbg_tick.commit_cnt] = ktime_to_ns(tick);
- - mdss_dbg_tick.commit_cnt++;
- - if(mdss_dbg_tick.commit_cnt > 9)
- - mdss_dbg_tick.commit_cnt = 0;
- - break;
- - case KICKOFF :
- - mdss_dbg_tick.kickoff[mdss_dbg_tick.kickoff_cnt] = ktime_to_ns(tick);
- - mdss_dbg_tick.kickoff_cnt++;
- - if(mdss_dbg_tick.kickoff_cnt > 9)
- - mdss_dbg_tick.kickoff_cnt = 0;
- - break;
- - case PP_DONE :
- - mdss_dbg_tick.pingpong_done[mdss_dbg_tick.pingpong_done_cnt] = ktime_to_ns(tick);
- - mdss_dbg_tick.pingpong_done_cnt++;
- - if(mdss_dbg_tick.pingpong_done_cnt > 9)
- - mdss_dbg_tick.pingpong_done_cnt = 0;
- - break;
- - }
- -}
- -
- -#endif
- -/*
- - * [srcx,srcy,srcw,srch]->[dstx,dsty,dstw,dsth][flags]|src_format|bpp|pipe_ndx|
- - * mdp_clk = %ld, bus_ab = %llu, bus_ib = %llu
- - */
- -void mdss_mdp_underrun_dump_info(struct msm_fb_data_type *mfd)
- -{
- - struct mdss_mdp_pipe *pipe;
- - struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
- -
- - pr_info(" ============ dump_start ===========\n");
- -
- - list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
- - if (pipe)
- - pr_info(" [%4d, %4d, %4d, %4d] -> [%4d, %4d, %4d, %4d]"
- - "|flags = %8d|src_format = %2d|bpp = %2d|ndx = %3d|\n",
- - pipe->src.x, pipe->src.y, pipe->src.w, pipe->src.h,
- - pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h,
- - pipe->flags, pipe->src_fmt->format, pipe->src_fmt->bpp,
- - pipe->ndx);
- - pr_info("pipe addr : %p\n", pipe);
- - }
- -
- - mdss_mdp_underrun_clk_info();
- - pr_info(" ============ dump_end =========== \n");
- -}
- -
- diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
- index 239c9d4..134a3d9 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
- @@ -76,7 +76,6 @@ static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map,
- if (i != 0 && n != i && !force_alloc) {
- pr_debug("Can't change mmb config, num_blks: %d alloc: %d\n",
- n, i);
- - pr_debug("Can't change mmb configuration in set call\n");
- return 0;
- }
- @@ -341,11 +340,11 @@ int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe)
- }
- if (reserved < num_blks) {
- - pr_err("insufficient MMB blocks\n");
- + pr_debug("insufficient MMB blocks\n");
- for (; i >= 0; i--)
- mdss_mdp_smp_mmb_free(pipe->smp_map[i].reserved,
- false);
- - rc = -ENOMEM;
- + rc = -ENOBUFS;
- }
- mutex_unlock(&mdss_mdp_smp_lock);
- @@ -697,42 +696,6 @@ static void mdss_mdp_pipe_free(struct kref *kref)
- pipe->mfd = NULL;
- memset(&pipe->scale, 0, sizeof(struct mdp_scale_data));
- }
- -static bool mdss_mdp_check_pipe_in_use(struct mdss_mdp_pipe *pipe)
- -{
- - int i;
- - u32 mixercfg, stage_off_mask = BIT(0) | BIT(1) | BIT(2);
- - bool in_use = false;
- - struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- - struct mdss_mdp_ctl *ctl;
- - struct mdss_mdp_mixer *mixer;
- -
- - if (pipe->num == MDSS_MDP_SSPP_VIG3 ||
- - pipe->num == MDSS_MDP_SSPP_RGB3)
- - stage_off_mask = stage_off_mask << ((3 * pipe->num) + 2);
- - else
- - stage_off_mask = stage_off_mask << (3 * pipe->num);
- -
- - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- - for (i = 0; i < mdata->nctl; i++) {
- - ctl = mdata->ctl_off + i;
- - if (!ctl || !ctl->ref_cnt)
- - continue;
- -
- - mixer = ctl->mixer_left;
- - if (mixer && mixer->rotator_mode)
- - continue;
- -
- - mixercfg = mdss_mdp_get_mixercfg(mixer);
- - if ((mixercfg & stage_off_mask) && ctl->play_cnt) {
- - pr_err("BUG. pipe%d is active. mcfg:0x%x mask:0x%x\n",
- - pipe->num, mixercfg, stage_off_mask);
- - BUG();
- - }
- - }
- - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
- -
- - return in_use;
- -}
- static int mdss_mdp_is_pipe_idle(struct mdss_mdp_pipe *pipe,
- bool ignore_force_on)
- @@ -795,15 +758,13 @@ exit:
- */
- int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe)
- {
- - bool is_idle, in_use = false;
- + bool is_idle;
- int rc = 0;
- u32 reg_val, idle_mask, status;
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- is_idle = mdss_mdp_is_pipe_idle(pipe, true);
- - if (!is_idle)
- - in_use = mdss_mdp_check_pipe_in_use(pipe);
- - if (!is_idle && !in_use) {
- + if (!is_idle) {
- pr_err("%pS: pipe%d is not idle. xin_id=%d\n",
- __builtin_return_address(0), pipe->num, pipe->xin_id);
- @@ -915,6 +876,8 @@ error:
- return rc;
- }
- +
- +
- static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
- struct mdss_mdp_data *data)
- {
- @@ -979,11 +942,7 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe,
- src_size = (src.h << 16) | src.w;
- src_xy = (src.y << 16) | src.x;
- dst_size = (dst.h << 16) | dst.w;
- -#if defined(CONFIG_MDSS_UD_FLIP)
- - dst_xy = (((pipe->mixer->height - pipe->dst.y - pipe->dst.h) << 16) | pipe->dst.x);
- -#else
- dst_xy = (dst.y << 16) | dst.x;
- -#endif
- ystride0 = (pipe->src_planes.ystride[0]) |
- (pipe->src_planes.ystride[1] << 16);
- @@ -1301,27 +1260,31 @@ static inline void __mdss_mdp_pipe_program_pixel_extn_helper(
- */
- if (plane == 1)
- src_h >>= pipe->chroma_sample_v;
- +
- lr_pe = ((pipe->scale.right_ftch[plane] & mask) << 24)|
- ((pipe->scale.right_rpt[plane] & mask) << 16)|
- ((pipe->scale.left_ftch[plane] & mask) << 8)|
- (pipe->scale.left_rpt[plane] & mask);
- - tb_pe = ((pipe->scale.btm_ftch[plane] & mask) << 24)|
- +
- + tb_pe = ((pipe->scale.btm_ftch[plane] & mask) << 24)|
- ((pipe->scale.btm_rpt[plane] & mask) << 16)|
- ((pipe->scale.top_ftch[plane] & mask) << 8)|
- (pipe->scale.top_rpt[plane] & mask);
- +
- writel_relaxed(lr_pe, pipe->base +
- MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_LR + off);
- writel_relaxed(tb_pe, pipe->base +
- MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_TB + off);
- +
- mask = 0xFFFF;
- tot_req_pixels = (((src_h + pipe->scale.num_ext_pxls_top[plane] +
- pipe->scale.num_ext_pxls_btm[plane]) & mask) << 16) |
- ((pipe->scale.roi_w[plane] +
- pipe->scale.num_ext_pxls_left[plane] +
- pipe->scale.num_ext_pxls_right[plane]) & mask);
- - writel_relaxed(tot_req_pixels, pipe->base +
- + writel_relaxed(tot_req_pixels, pipe->base +
- MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_REQ_PIXELS + off);
- -
- +
- pr_debug("pipe num=%d, plane=%d, LR PE=0x%x, TB PE=0x%x, req_pixels=0x0%x\n",
- pipe->num, plane, lr_pe, tb_pe, tot_req_pixels);
- }
- diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
- index ea133ee..a9e32d7 100644
- --- a/drivers/video/msm/mdss/mdss_mdp_pp.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
- @@ -21,20 +21,6 @@
- #include <linux/delay.h>
- #include <mach/msm_bus.h>
- #include <mach/msm_bus_board.h>
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- -struct mdp_csc_cfg mdp_csc_convert_wideband = {
- - 0,
- - {
- - 0x0200, 0x0000, 0x02CD,
- - 0x0200, 0xFF4F, 0xFE91,
- - 0x0200, 0x038B, 0x0000,
- - },
- - { 0x0, 0xFF80, 0xFF80,},
- - { 0x0, 0x0, 0x0,},
- - { 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF,},
- - { 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF,},
- -};
- -#endif
- struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
- [MDSS_MDP_CSC_RGB2RGB] = {
- @@ -87,29 +73,23 @@ struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
- },
- };
- -#if defined(CONFIG_MDNIE_TFT_MSM8X26) || defined (CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL) || defined(CONFIG_MDNIE_VIDEO_ENHANCED)
- -struct mdp_pcc_cfg_data pcc_reverse = {
- - .block = MDP_LOGICAL_BLOCK_DISP_0,
- - .ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE,
- - .r = { 0x00007ff8, 0xffff8000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- - .g = { 0x00007ff8, 0x00000000, 0xffff8000, 0x00000000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- - .b = { 0x00007ff8, 0x00000000, 0x00000000, 0xffff8000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- -};
- -
- -struct mdp_pcc_cfg_data pcc_normal = {
- - .block = MDP_LOGICAL_BLOCK_DISP_0,
- - .ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_DISABLE,
- - .r = { 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- - .g = { 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- - .b = { 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000,
- - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
- +/*
- + * To program a linear LUT we need to make the slope to be 1/16 to enable
- + * conversion from 12bit to 8bit. Also in cases where post blend values might
- + * cross 255, we need to cap them now to 255. The offset of the final segment
- + * would be programmed in such a case and we set the value to 32460 which is
- + * 255 in U8.7.
- + */
- +static struct mdp_ar_gc_lut_data lin_gc_data[GC_LUT_SEGMENTS] = {
- + { 0, 256, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 0},
- + {4095, 0, 0}, {4095, 0, 32640}
- };
- -#endif
- #define CSC_MV_OFF 0x0
- #define CSC_BV_OFF 0x2C
- @@ -117,6 +97,8 @@ struct mdp_pcc_cfg_data pcc_normal = {
- #define CSC_POST_OFF 0xC
- #define MDSS_BLOCK_DISP_NUM (MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
- +#define MDSS_MAX_MIXER_DISP_NUM (MDSS_BLOCK_DISP_NUM + \
- + MDSS_MDP_WB_MAX_LAYERMIXER)
- #define HIST_WAIT_TIMEOUT(frame) ((75 * HZ * (frame)) / 1000)
- #define HIST_KICKOFF_WAIT_FRACTION 4
- @@ -325,15 +307,15 @@ static struct msm_bus_scale_pdata mdp_pp_bus_scale_table = {
- struct mdss_pp_res_type {
- /* logical info */
- - u32 pp_disp_flags[MDSS_BLOCK_DISP_NUM];
- + u32 pp_disp_flags[MDSS_MAX_MIXER_DISP_NUM];
- u32 igc_lut_c0c1[MDSS_BLOCK_DISP_NUM][IGC_LUT_ENTRIES];
- u32 igc_lut_c2[MDSS_BLOCK_DISP_NUM][IGC_LUT_ENTRIES];
- struct mdp_ar_gc_lut_data
- - gc_lut_r[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
- + gc_lut_r[MDSS_MAX_MIXER_DISP_NUM][GC_LUT_SEGMENTS];
- struct mdp_ar_gc_lut_data
- - gc_lut_g[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
- + gc_lut_g[MDSS_MAX_MIXER_DISP_NUM][GC_LUT_SEGMENTS];
- struct mdp_ar_gc_lut_data
- - gc_lut_b[MDSS_BLOCK_DISP_NUM][GC_LUT_SEGMENTS];
- + gc_lut_b[MDSS_MAX_MIXER_DISP_NUM][GC_LUT_SEGMENTS];
- u32 enhist_lut[MDSS_BLOCK_DISP_NUM][ENHIST_LUT_ENTRIES];
- struct mdp_pa_cfg pa_disp_cfg[MDSS_BLOCK_DISP_NUM];
- struct mdp_pa_v2_data pa_v2_disp_cfg[MDSS_BLOCK_DISP_NUM];
- @@ -341,14 +323,14 @@ struct mdss_pp_res_type {
- u32 six_zone_lut_curve_p1[MDSS_BLOCK_DISP_NUM][MDP_SIX_ZONE_LUT_SIZE];
- struct mdp_pcc_cfg_data pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
- struct mdp_igc_lut_data igc_disp_cfg[MDSS_BLOCK_DISP_NUM];
- - struct mdp_pgc_lut_data argc_disp_cfg[MDSS_BLOCK_DISP_NUM];
- + struct mdp_pgc_lut_data argc_disp_cfg[MDSS_MAX_MIXER_DISP_NUM];
- struct mdp_pgc_lut_data pgc_disp_cfg[MDSS_BLOCK_DISP_NUM];
- struct mdp_hist_lut_data enhist_disp_cfg[MDSS_BLOCK_DISP_NUM];
- struct mdp_dither_cfg_data dither_disp_cfg[MDSS_BLOCK_DISP_NUM];
- struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM];
- uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE];
- u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE];
- - struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM];
- + struct pp_sts_type pp_disp_sts[MDSS_MAX_MIXER_DISP_NUM];
- /* physical info */
- struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP];
- };
- @@ -420,10 +402,11 @@ static int pp_read_pa_v2_regs(char __iomem *addr,
- u32 disp_num);
- static void pp_read_pa_mem_col_regs(char __iomem *addr,
- struct mdp_pa_mem_col_cfg *mem_col_cfg);
- +static struct msm_fb_data_type *mdss_get_mfd_from_index(int index);
- static int mdss_ad_init_checks(struct msm_fb_data_type *mfd);
- static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd,
- struct mdss_ad_info **ad);
- -static int pp_update_ad_input(struct msm_fb_data_type *mfd);
- +static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd);
- static void pp_ad_vsync_handler(struct mdss_mdp_ctl *ctl, ktime_t t);
- static void pp_ad_cfg_write(struct mdss_mdp_ad *ad_hw,
- struct mdss_ad_info *ad);
- @@ -437,8 +420,11 @@ static void pp_ad_bypass_config(struct mdss_ad_info *ad,
- struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode);
- static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd);
- static void pp_ad_cfg_lut(char __iomem *addr, u32 *data);
- -static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out,
- - struct msm_fb_data_type *mfd);
- +static int pp_ad_attenuate_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out);
- +static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out,
- + int inv);
- +static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out,
- + bool *bl_out_notify);
- static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num);
- static inline bool pp_sts_is_enabled(u32 sts, int side);
- static inline void pp_sts_set_split_bits(u32 *sts, u32 bits);
- @@ -549,20 +535,7 @@ int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type)
- pr_debug("csc type=%d blk=%d idx=%d tbl=%d\n", csc_type,
- block, blk_idx, tbl_idx);
- -#ifdef CONFIG_FB_MSM_CAMERA_CSC
- - if (csc_type == MDSS_MDP_CSC_YUV2RGB && !csc_update)
- - {
- - data = &mdp_csc_convert_wideband;
- - pr_debug("will do mdp_csc_convert_wideband\n");
- - }
- - else
- - {
- - data = &mdp_csc_convert[csc_type];
- - pr_debug("will do mdp_csc_convert(narrow band)\n");
- - }
- -#else
- data = &mdp_csc_convert[csc_type];
- -#endif
- return mdss_mdp_csc_setup_data(block, blk_idx, tbl_idx, data);
- }
- @@ -1069,11 +1042,11 @@ static int mdss_mdp_scale_setup(struct mdss_mdp_pipe *pipe)
- (chroma_sample == MDSS_MDP_CHROMA_H1V2)))
- chroma_shift_y = 1; /* 2x upsample chroma */
- - if (src_h <= pipe->dst.h) {
- + if (src_h <= pipe->dst.h)
- scale_config |= /* G/Y, A */
- (filter_mode << 10) |
- (MDSS_MDP_SCALE_FILTER_BIL << 18);
- - } else
- + else
- scale_config |= /* G/Y, A */
- (MDSS_MDP_SCALE_FILTER_PCMN << 10) |
- (MDSS_MDP_SCALE_FILTER_PCMN << 18);
- @@ -1350,44 +1323,69 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op)
- static int pp_mixer_setup(u32 disp_num,
- struct mdss_mdp_mixer *mixer)
- {
- - u32 flags, dspp_num, opmode = 0;
- + u32 flags, mixer_num, opmode = 0, lm_bitmask = 0;
- struct mdp_pgc_lut_data *pgc_config;
- struct pp_sts_type *pp_sts;
- struct mdss_mdp_ctl *ctl;
- char __iomem *addr;
- + struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- - if (!mixer || !mixer->ctl)
- + if (!mixer || !mixer->ctl || !mdata)
- return -EINVAL;
- - dspp_num = mixer->num;
- +
- + mixer_num = mixer->num;
- ctl = mixer->ctl;
- + lm_bitmask = (BIT(6) << mixer_num);
- - /* no corresponding dspp */
- - if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) ||
- - (dspp_num >= MDSS_MDP_MAX_DSPP))
- + /* Assign appropriate flags after mixer index validation */
- + if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
- + if (mixer_num >= mdata->nmixers_intf) {
- + pr_err("bad intf mixer index = %d total = %d\n",
- + mixer_num, mdata->nmixers_intf);
- + return 0;
- + }
- + if (mixer_num == MDSS_MDP_DSPP3)
- + lm_bitmask = BIT(20);
- + } else if (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK) {
- + if (mixer_num >= mdata->nmixers_wb +
- + mdata->nmixers_intf) {
- + pr_err("bad wb mixer index = %d total = %d\n",
- + mixer_num,
- + mdata->nmixers_intf + mdata->nmixers_wb);
- + return 0;
- + }
- + } else {
- return 0;
- - if (disp_num < MDSS_BLOCK_DISP_NUM)
- - flags = mdss_pp_res->pp_disp_flags[disp_num];
- - else
- - flags = 0;
- + }
- + flags = mdss_pp_res->pp_disp_flags[disp_num];
- pp_sts = &mdss_pp_res->pp_disp_sts[disp_num];
- /* GC_LUT is in layer mixer */
- if (flags & PP_FLAGS_DIRTY_ARGC) {
- pgc_config = &mdss_pp_res->argc_disp_cfg[disp_num];
- - if (pgc_config->flags & MDP_PP_OPS_WRITE) {
- - addr = mixer->base +
- - MDSS_MDP_REG_LM_GC_LUT_BASE;
- + addr = mixer->base + MDSS_MDP_REG_LM_GC_LUT_BASE;
- + /*
- + * ARGC will always be enabled. When user setting is
- + * disabled we program the linear ARGC data to enable
- + * rounding in HW.
- + */
- + pp_sts->argc_sts |= PP_STS_ENABLE;
- + if (pgc_config->flags & MDP_PP_OPS_WRITE)
- + pp_update_argc_lut(addr, pgc_config);
- + if (pgc_config->flags & MDP_PP_OPS_DISABLE) {
- + pgc_config->r_data = &lin_gc_data[0];
- + pgc_config->g_data = &lin_gc_data[0];
- + pgc_config->b_data = &lin_gc_data[0];
- + pgc_config->num_r_stages = GC_LUT_SEGMENTS;
- + pgc_config->num_g_stages = GC_LUT_SEGMENTS;
- + pgc_config->num_b_stages = GC_LUT_SEGMENTS;
- pp_update_argc_lut(addr, pgc_config);
- }
- - if (pgc_config->flags & MDP_PP_OPS_DISABLE)
- - pp_sts->argc_sts &= ~PP_STS_ENABLE;
- - else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
- - pp_sts->argc_sts |= PP_STS_ENABLE;
- - ctl->flush_bits |= BIT(6) << dspp_num; /* LAYER_MIXER */
- + ctl->flush_bits |= lm_bitmask;
- }
- +
- /* update LM opmode if LM needs flush */
- - if ((pp_sts->argc_sts & PP_STS_ENABLE) &&
- - (ctl->flush_bits & (BIT(6) << dspp_num))) {
- + if (flags & PP_FLAGS_DIRTY_ARGC) {
- addr = mixer->base + MDSS_MDP_REG_LM_OP_MODE;
- opmode = readl_relaxed(addr);
- opmode |= (1 << 0); /* GC_LUT_EN */
- @@ -1624,23 +1622,23 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
- pp_sts = &mdss_pp_res->pp_disp_sts[disp_num];
- - if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) {
- - pp_pa_v2_config(flags, base + MDSS_MDP_REG_DSPP_PA_BASE, pp_sts,
- - &mdss_pp_res->pa_v2_disp_cfg[disp_num],
- - PP_DSPP);
- - } else
- - pp_pa_config(flags, base + MDSS_MDP_REG_DSPP_PA_BASE, pp_sts,
- - &mdss_pp_res->pa_disp_cfg[disp_num]);
- -
- - pp_pcc_config(flags, base + MDSS_MDP_REG_DSPP_PCC_BASE, pp_sts,
- - &mdss_pp_res->pcc_disp_cfg[disp_num]);
- + if (disp_num < MDSS_BLOCK_DISP_NUM) {
- + if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) {
- + pp_pa_v2_config(flags, base + MDSS_MDP_REG_DSPP_PA_BASE, pp_sts,
- + &mdss_pp_res->pa_v2_disp_cfg[disp_num],
- + PP_DSPP);
- + } else
- + pp_pa_config(flags, base + MDSS_MDP_REG_DSPP_PA_BASE, pp_sts,
- + &mdss_pp_res->pa_disp_cfg[disp_num]);
- - pp_igc_config(flags, mdata->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE,
- + pp_pcc_config(flags, base + MDSS_MDP_REG_DSPP_PCC_BASE, pp_sts,
- + &mdss_pp_res->pcc_disp_cfg[disp_num]);
- + pp_igc_config(flags, mdata->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE,
- pp_sts, &mdss_pp_res->igc_disp_cfg[disp_num],
- dspp_num);
- -
- - pp_enhist_config(flags, base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE,
- - pp_sts, &mdss_pp_res->enhist_disp_cfg[disp_num]);
- + pp_enhist_config(flags, base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE,
- + pp_sts, &mdss_pp_res->enhist_disp_cfg[disp_num]);
- + }
- if (pp_sts->enhist_sts & PP_STS_ENABLE &&
- !(pp_sts->pa_sts & PP_STS_ENABLE)) {
- @@ -1651,26 +1649,29 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
- writel_relaxed(0, addr + 8);
- writel_relaxed(0, addr + 12);
- }
- - if (flags & PP_FLAGS_DIRTY_DITHER) {
- - addr = base + MDSS_MDP_REG_DSPP_DITHER_DEPTH;
- - pp_dither_config(addr, pp_sts,
- - &mdss_pp_res->dither_disp_cfg[disp_num]);
- - }
- - if (flags & PP_FLAGS_DIRTY_GAMUT)
- - pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num], base,
- - pp_sts);
- - if (flags & PP_FLAGS_DIRTY_PGC) {
- - pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
- - if (pgc_config->flags & MDP_PP_OPS_WRITE) {
- - addr = base + MDSS_MDP_REG_DSPP_GC_BASE;
- - pp_update_argc_lut(addr, pgc_config);
- + if (disp_num < MDSS_BLOCK_DISP_NUM) {
- + if (flags & PP_FLAGS_DIRTY_DITHER) {
- + addr = base + MDSS_MDP_REG_DSPP_DITHER_DEPTH;
- + pp_dither_config(addr, pp_sts,
- + &mdss_pp_res->dither_disp_cfg[disp_num]);
- + }
- + if (flags & PP_FLAGS_DIRTY_GAMUT)
- + pp_gamut_config(&mdss_pp_res->gamut_disp_cfg[disp_num], base,
- + pp_sts);
- +
- + if (flags & PP_FLAGS_DIRTY_PGC) {
- + pgc_config = &mdss_pp_res->pgc_disp_cfg[disp_num];
- + if (pgc_config->flags & MDP_PP_OPS_WRITE) {
- + addr = base + MDSS_MDP_REG_DSPP_GC_BASE;
- + pp_update_argc_lut(addr, pgc_config);
- + }
- + if (pgc_config->flags & MDP_PP_OPS_DISABLE)
- + pp_sts->pgc_sts &= ~PP_STS_ENABLE;
- + else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
- + pp_sts->pgc_sts |= PP_STS_ENABLE;
- + pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags);
- }
- - if (pgc_config->flags & MDP_PP_OPS_DISABLE)
- - pp_sts->pgc_sts &= ~PP_STS_ENABLE;
- - else if (pgc_config->flags & MDP_PP_OPS_ENABLE)
- - pp_sts->pgc_sts |= PP_STS_ENABLE;
- - pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags);
- }
- pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode);
- @@ -1734,14 +1735,22 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
- /* treat fb_num the same as block logical id*/
- disp_num = ctl->mfd->index;
- + if (disp_num >= MDSS_MAX_MIXER_DISP_NUM) {
- + pr_warn("Invalid display number found, %u", disp_num);
- + return -EINVAL;
- + }
- mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
- if (!mixer_cnt) {
- valid_mixers = false;
- - ret = -EINVAL;
- - pr_warn("Configuring post processing without mixers, err = %d",
- - ret);
- - goto exit;
- + /* exit if mixer is not writeback */
- + if (!ctl->mixer_left ||
- + (ctl->mixer_left->type == MDSS_MDP_MIXER_TYPE_INTF)) {
- + ret = -EINVAL;
- + pr_warn("No mixers for post processing err = %d\n",
- + ret);
- + goto exit;
- + }
- }
- if (mdata->nad_cfgs == 0)
- valid_mixers = false;
- @@ -1771,7 +1780,7 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl)
- pp_dspp_setup(disp_num, ctl->mixer_right);
- }
- /* clear dirty flag */
- - if (disp_num < MDSS_BLOCK_DISP_NUM) {
- + if (disp_num < MDSS_MAX_MIXER_DISP_NUM) {
- mdss_pp_res->pp_disp_flags[disp_num] = 0;
- if (disp_num < mdata->nad_cfgs)
- mdata->ad_cfgs[disp_num].reg_sts = 0;
- @@ -1791,41 +1800,12 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num)
- struct pp_sts_type pp_sts;
- struct mdss_ad_info *ad;
- struct mdss_data_type *mdata = ctl->mdata;
- + struct msm_fb_data_type *bl_mfd;
- if (dspp_num >= MDSS_MDP_MAX_DSPP) {
- pr_warn("invalid dspp_num");
- return -EINVAL;
- }
- disp_num = ctl->mfd->index;
- -
- - if (dspp_num < mdata->nad_cfgs) {
- - ret = mdss_mdp_get_ad(ctl->mfd, &ad);
- - if (ret)
- - return ret;
- -
- - if (PP_AD_STATE_CFG & ad->state)
- - pp_ad_cfg_write(&mdata->ad_off[dspp_num], ad);
- - if (PP_AD_STATE_INIT & ad->state)
- - pp_ad_init_write(&mdata->ad_off[dspp_num], ad, ctl);
- - if ((PP_AD_STATE_DATA & ad->state) &&
- - (ad->sts & PP_STS_ENABLE)) {
- - bl = ad->bl_mfd->bl_level;
- - ad->last_bl = bl;
- - if (ad->state & PP_AD_STATE_BL_LIN) {
- - bl = ad->bl_lin[bl >> ad->bl_bright_shift];
- - bl = bl << ad->bl_bright_shift;
- - ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd);
- - if (ret)
- - pr_err("Failed to attenuate BL\n");
- - }
- - linear_map(bl, &ad->bl_data,
- - ad->bl_mfd->panel_info->bl_max,
- - MDSS_MDP_AD_BL_SCALE);
- - pp_ad_input_write(&mdata->ad_off[dspp_num], ad);
- - }
- - if ((PP_AD_STATE_VSYNC & ad->state) && ad->calc_itr)
- - ctl->add_vsync_handler(ctl, &ad->handle);
- - }
- -
- pp_sts = mdss_pp_res->pp_disp_sts[disp_num];
- if (pp_sts.pa_sts & PP_STS_ENABLE) {
- @@ -1893,6 +1873,44 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num)
- }
- mdss_pp_res->pp_disp_flags[disp_num] |= flags;
- +
- + if (dspp_num < mdata->nad_cfgs) {
- + ret = mdss_mdp_get_ad(ctl->mfd, &ad);
- + if (ret) {
- + pr_warn("Failed to get AD info, err = %d\n", ret);
- + return ret;
- + }
- + if (ctl->mfd->panel_info->type == WRITEBACK_PANEL) {
- + bl_mfd = mdss_get_mfd_from_index(0);
- + if (!bl_mfd) {
- + ret = -EINVAL;
- + pr_warn("Failed to get primary FB bl handle, err = %d\n",
- + ret);
- + return ret;
- + }
- + } else {
- + bl_mfd = ctl->mfd;
- + }
- +
- + mutex_lock(&ad->lock);
- + bl = bl_mfd->ad_bl_level;
- + if (PP_AD_STATE_CFG & ad->state)
- + pp_ad_cfg_write(&mdata->ad_off[dspp_num], ad);
- + if (PP_AD_STATE_INIT & ad->state)
- + pp_ad_init_write(&mdata->ad_off[dspp_num], ad, ctl);
- + if ((PP_AD_STATE_DATA & ad->state) &&
- + (ad->sts & PP_STS_ENABLE)) {
- + ad->last_bl = bl;
- + linear_map(bl, &ad->bl_data,
- + ad->bl_mfd->panel_info->bl_max,
- + MDSS_MDP_AD_BL_SCALE);
- + pp_ad_input_write(&mdata->ad_off[dspp_num], ad);
- + }
- + if ((PP_AD_STATE_VSYNC & ad->state) && ad->calc_itr)
- + ctl->add_vsync_handler(ctl, &ad->handle);
- + mutex_unlock(&ad->lock);
- + }
- +
- return 0;
- }
- @@ -1902,6 +1920,10 @@ int mdss_mdp_pp_init(struct device *dev)
- struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- struct mdss_mdp_pipe *vig;
- struct msm_bus_scale_pdata *pp_bus_pdata;
- + struct mdp_pgc_lut_data *gc_cfg;
- +
- + if (!mdata)
- + return -EPERM;
- mutex_lock(&mdss_pp_mutex);
- if (!mdss_pp_res) {
- @@ -1921,6 +1943,17 @@ int mdss_mdp_pp_init(struct device *dev)
- init_completion(
- &mdss_pp_res->dspp_hist[i].first_kick);
- }
- +
- + /*
- + * Set LM ARGC flags to disable. This would program
- + * default GC which would allow for rounding in HW.
- + */
- + for (i = 0; i < MDSS_MAX_MIXER_DISP_NUM; i++) {
- + gc_cfg = &mdss_pp_res->argc_disp_cfg[i];
- + gc_cfg->flags = MDP_PP_OPS_DISABLE;
- + mdss_pp_res->pp_disp_flags[i] |=
- + PP_FLAGS_DIRTY_ARGC;
- + }
- }
- }
- if (mdata && mdata->vig_pipes) {
- @@ -1967,6 +2000,89 @@ void mdss_mdp_pp_term(struct device *dev)
- mutex_unlock(&mdss_pp_mutex);
- }
- }
- +int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd)
- +{
- + if (!mfd) {
- + pr_err("Invalid mfd.\n");
- + return -EPERM;
- + }
- +
- + mfd->mdp.ad_calc_bl = pp_ad_calc_bl;
- + return 0;
- +}
- +
- +static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out,
- + bool *bl_out_notify)
- +{
- + int ret = -1;
- + int temp = bl_in;
- + u32 ad_bl_out = 0;
- + struct mdss_ad_info *ad;
- +
- + ret = mdss_mdp_get_ad(mfd, &ad);
- + if (ret == -ENODEV) {
- + pr_debug("AD not supported on device.\n");
- + return ret;
- + } else if (ret || !ad) {
- + pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n",
- + ret, ad);
- + return ret;
- + }
- +
- + mutex_lock(&ad->lock);
- + if (!(ad->state & PP_AD_STATE_RUN)) {
- + pr_debug("AD is not running.\n");
- + mutex_unlock(&ad->lock);
- + return -EPERM;
- + }
- +
- + if (!ad->bl_mfd || !ad->bl_mfd->panel_info ||
- + !ad->bl_att_lut) {
- + pr_err("Invalid ad info: bl_mfd = 0x%p, ad->bl_mfd->panel_info = 0x%p, bl_att_lut = 0x%p\n",
- + ad->bl_mfd,
- + (!ad->bl_mfd) ? NULL : ad->bl_mfd->panel_info,
- + ad->bl_att_lut);
- + mutex_unlock(&ad->lock);
- + return -EINVAL;
- + }
- +
- + ret = pp_ad_linearize_bl(ad, bl_in, &temp,
- + MDP_PP_AD_BL_LINEAR);
- + if (ret) {
- + pr_err("Failed to linearize BL: %d\n", ret);
- + mutex_unlock(&ad->lock);
- + return ret;
- + }
- +
- + ret = pp_ad_attenuate_bl(ad, temp, &temp);
- + if (ret) {
- + pr_err("Failed to attenuate BL: %d\n", ret);
- + mutex_unlock(&ad->lock);
- + return ret;
- + }
- + ad_bl_out = temp;
- +
- + ret = pp_ad_linearize_bl(ad, temp, &temp, MDP_PP_AD_BL_LINEAR_INV);
- + if (ret) {
- + pr_err("Failed to inverse linearize BL: %d\n", ret);
- + mutex_unlock(&ad->lock);
- + return ret;
- + }
- + *bl_out = temp;
- +
- + if(!mfd->ad_bl_level)
- + mfd->ad_bl_level = bl_in;
- +
- + if (ad_bl_out != mfd->ad_bl_level) {
- + mfd->ad_bl_level = ad_bl_out;
- + *bl_out_notify = true;
- + }
- +
- + pp_ad_invalidate_input(mfd);
- + mutex_unlock(&ad->lock);
- + return 0;
- +}
- +
- static int pp_get_dspp_num(u32 disp_num, u32 *dspp_num)
- {
- int i;
- @@ -3435,7 +3551,6 @@ int mdss_mdp_hist_intr_setup(struct mdss_intr *intr, int type)
- return -EINVAL;
- }
- - return ret; // not used.
- mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- spin_lock_irqsave(&intr->lock, flag);
- @@ -4018,34 +4133,42 @@ static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd,
- return ret;
- }
- -static int pp_update_ad_input(struct msm_fb_data_type *mfd)
- +/* must call this function from within ad->lock */
- +static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd)
- {
- int ret;
- struct mdss_ad_info *ad;
- - struct mdss_ad_input input;
- struct mdss_mdp_ctl *ctl;
- - if (!mfd)
- + if (!mfd) {
- + pr_err("Invalid mfd\n");
- return -EINVAL;
- + }
- ctl = mfd_to_ctl(mfd);
- - if (!ctl)
- + if (!ctl) {
- + pr_err("Invalid ctl\n");
- return -EINVAL;
- + }
- ret = mdss_mdp_get_ad(mfd, &ad);
- - if (ret)
- - return ret;
- - if (!ad || ad->cfg.mode == MDSS_AD_MODE_AUTO_BL)
- + if (ret || !ad) {
- + pr_err("Fail to get ad: ret = %d, ad = 0x%p\n", ret, ad);
- return -EINVAL;
- + }
- + pr_debug("AD backlight level changed (%d), trigger update to AD\n",
- + mfd->ad_bl_level);
- + if (ad->cfg.mode == MDSS_AD_MODE_AUTO_BL) {
- + pr_err("AD auto backlight no longer supported.\n");
- + return -EINVAL;
- + }
- - pr_debug("backlight level changed (%d), trigger update to AD",
- - mfd->bl_level);
- - input.mode = ad->cfg.mode;
- - if (MDSS_AD_MODE_DATA_MATCH(ad->cfg.mode, MDSS_AD_INPUT_AMBIENT))
- - input.in.amb_light = ad->ad_data;
- - else
- - input.in.strength = ad->ad_data;
- - /* call to ad_input will trigger backlight read */
- - return mdss_mdp_ad_input(mfd, &input, 0);
- + if (ad->state & PP_AD_STATE_RUN) {
- + ad->calc_itr = ad->cfg.stab_itr;
- + ad->sts |= PP_AD_STS_DIRTY_VSYNC;
- + ad->sts |= PP_AD_STS_DIRTY_DATA;
- + }
- +
- + return 0;
- }
- int mdss_mdp_ad_config(struct msm_fb_data_type *mfd,
- @@ -4054,7 +4177,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd,
- struct mdss_ad_info *ad;
- struct msm_fb_data_type *bl_mfd;
- int lin_ret = -1, inv_ret = -1, att_ret = -1, ret = 0;
- - u32 ratio_temp, shift = 0, last_ops;
- + u32 last_ops;
- ret = mdss_mdp_get_ad(mfd, &ad);
- if (ret)
- @@ -4087,12 +4210,6 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd,
- sizeof(uint32_t));
- if (lin_ret || inv_ret)
- ret = -ENOMEM;
- - ratio_temp = mfd->panel_info->bl_max / AD_BL_LIN_LEN;
- - while (ratio_temp > 0) {
- - ratio_temp = ratio_temp >> 1;
- - shift++;
- - }
- - ad->bl_bright_shift = shift;
- } else {
- ret = -EINVAL;
- }
- @@ -4192,7 +4309,7 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
- goto error;
- }
- ad->ad_data_mode = MDSS_AD_INPUT_AMBIENT;
- - pr_debug("ambient = %d", input->in.amb_light);
- + pr_debug("ambient = %d\n", input->in.amb_light);
- ad->ad_data = input->in.amb_light;
- ad->calc_itr = ad->cfg.stab_itr;
- ad->sts |= PP_AD_STS_DIRTY_VSYNC;
- @@ -4211,7 +4328,7 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd,
- goto error;
- }
- ad->ad_data_mode = MDSS_AD_INPUT_STRENGTH;
- - pr_debug("strength = %d", input->in.strength);
- + pr_debug("strength = %d\n", input->in.strength);
- ad->ad_data = input->in.strength;
- ad->calc_itr = ad->cfg.stab_itr;
- ad->sts |= PP_AD_STS_DIRTY_VSYNC;
- @@ -4527,26 +4644,18 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
- */
- ad->sts &= ~PP_AD_STS_DIRTY_DATA;
- ad->state |= PP_AD_STATE_DATA;
- - mutex_lock(&bl_mfd->bl_lock);
- - bl = bl_mfd->bl_level;
- pr_debug("dirty data, last_bl = %d ", ad->last_bl);
- + bl = bl_mfd->ad_bl_level;
- +
- if ((ad->cfg.mode == MDSS_AD_MODE_AUTO_STR) &&
- (ad->last_bl != bl)) {
- ad->last_bl = bl;
- ad->calc_itr = ad->cfg.stab_itr;
- ad->sts |= PP_AD_STS_DIRTY_VSYNC;
- - if (ad->state & PP_AD_STATE_BL_LIN) {
- - bl = ad->bl_lin[bl >> ad->bl_bright_shift];
- - bl = bl << ad->bl_bright_shift;
- - ret = pp_ad_attenuate_bl(bl, &bl, ad->mfd);
- - if (ret)
- - pr_err("Failed to attenuate BL\n");
- - }
- linear_map(bl, &ad->bl_data,
- ad->bl_mfd->panel_info->bl_max,
- MDSS_MDP_AD_BL_SCALE);
- }
- - mutex_unlock(&bl_mfd->bl_lock);
- ad->reg_sts |= PP_AD_STS_DIRTY_DATA;
- }
- @@ -4590,14 +4699,9 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
- bypass = 0;
- ad->reg_sts |= PP_AD_STS_DIRTY_ENABLE;
- ad->state |= PP_AD_STATE_RUN;
- - mutex_lock(&bl_mfd->bl_lock);
- if (bl_mfd != mfd)
- bl_mfd->ext_ad_ctrl = mfd->index;
- - bl_mfd->mdp.update_ad_input = pp_update_ad_input;
- - bl_mfd->mdp.ad_attenuate_bl = pp_ad_attenuate_bl;
- bl_mfd->ext_bl_ctrl = ad->cfg.bl_ctrl_mode;
- - mutex_unlock(&bl_mfd->bl_lock);
- -
- } else {
- if (ad->state & PP_AD_STATE_RUN) {
- ad->reg_sts = PP_AD_STS_DIRTY_ENABLE;
- @@ -4608,7 +4712,6 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
- ad->state &= !PP_AD_STATE_CFG;
- ad->state &= !PP_AD_STATE_DATA;
- ad->state &= !PP_AD_STATE_BL_LIN;
- - ad->bl_bright_shift = 0;
- ad->ad_data = 0;
- ad->ad_data_mode = 0;
- ad->last_bl = 0;
- @@ -4622,12 +4725,8 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd)
- AD_BL_ATT_LUT_LEN);
- memset(&ad->init, 0, sizeof(struct mdss_ad_init));
- memset(&ad->cfg, 0, sizeof(struct mdss_ad_cfg));
- - mutex_lock(&bl_mfd->bl_lock);
- - bl_mfd->mdp.update_ad_input = NULL;
- - bl_mfd->mdp.ad_attenuate_bl = NULL;
- bl_mfd->ext_bl_ctrl = 0;
- bl_mfd->ext_ad_ctrl = -1;
- - mutex_unlock(&bl_mfd->bl_lock);
- }
- ad->state &= ~PP_AD_STATE_RUN;
- }
- @@ -4669,7 +4768,7 @@ static void pp_ad_calc_worker(struct work_struct *work)
- struct msm_fb_data_type *mfd, *bl_mfd;
- struct mdss_data_type *mdata;
- char __iomem *base;
- - u32 bl, calc_done = 0;
- + u32 calc_done = 0;
- ad = container_of(work, struct mdss_ad_info, calc_work);
- mutex_lock(&ad->lock);
- @@ -4711,22 +4810,8 @@ static void pp_ad_calc_worker(struct work_struct *work)
- if (calc_done) {
- ad->last_str = 0xFF & readl_relaxed(base +
- MDSS_MDP_REG_AD_STR_OUT);
- - if (MDSS_AD_RUNNING_AUTO_BL(ad)) {
- - bl = 0xFFFF & readl_relaxed(base +
- - MDSS_MDP_REG_AD_BL_OUT);
- - if (ad->state & PP_AD_STATE_BL_LIN) {
- - bl = bl >> ad->bl_bright_shift;
- - bl = min_t(u32, bl, (AD_BL_LIN_LEN-1));
- - bl = ad->bl_lin_inv[bl];
- - bl = bl << ad->bl_bright_shift;
- - }
- - pr_debug("calc bl = %d", bl);
- - ad->last_str |= bl << 16;
- - mutex_lock(&ad->bl_mfd->bl_lock);
- - if (ad->bl_mfd->bl_level)
- - mdss_fb_set_backlight(ad->bl_mfd, bl);
- - mutex_unlock(&ad->bl_mfd->bl_lock);
- - }
- + if (MDSS_AD_RUNNING_AUTO_BL(ad))
- + pr_err("AD auto backlight no longer supported.\n");
- pr_debug("calc_str = %d, calc_itr %d",
- ad->last_str & 0xFF,
- ad->calc_itr);
- @@ -4765,25 +4850,17 @@ static void pp_ad_cfg_lut(char __iomem *addr, u32 *data)
- addr + ((PP_AD_LUT_LEN - 1) * 2));
- }
- -static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out,
- - struct msm_fb_data_type *mfd)
- +/* must call this function from within ad->lock */
- +static int pp_ad_attenuate_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out)
- {
- u32 shift = 0, ratio_temp = 0;
- u32 n, lut_interval, bl_att;
- - int ret = -1;
- - struct mdss_ad_info *ad;
- if (bl < 0) {
- pr_err("Invalid backlight input\n");
- - return ret;
- + return -EINVAL;
- }
- - ret = mdss_mdp_get_ad(mfd, &ad);
- - if (ret || !ad || !ad->bl_mfd || !ad->bl_mfd->panel_info ||
- - !ad->bl_mfd->panel_info->bl_max || !ad->bl_att_lut) {
- - pr_err("Failed to get the ad.\n");
- - return ret;
- - }
- pr_debug("bl_in = %d\n", bl);
- /* map panel backlight range to AD backlight range */
- linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max,
- @@ -4798,7 +4875,7 @@ static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out,
- n = bl >> shift;
- if (n >= (AD_BL_ATT_LUT_LEN - 1)) {
- pr_err("Invalid index for BL attenuation: %d.\n", n);
- - return ret;
- + return -EINVAL;
- }
- lut_interval = (MDSS_MDP_AD_BL_SCALE + 1) / (AD_BL_ATT_LUT_LEN - 1);
- bl_att = ad->bl_att_lut[n] + (bl - lut_interval * n) *
- @@ -4821,6 +4898,63 @@ static int pp_ad_attenuate_bl(u32 bl, u32 *bl_out,
- return 0;
- }
- +/* must call this function from within ad->lock */
- +static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out,
- + int inv)
- +{
- +
- + u32 n;
- + int ret = -EINVAL;
- +
- + if (bl < 0 || bl > ad->bl_mfd->panel_info->bl_max) {
- + pr_err("Invalid backlight input: bl = %d, bl_max = %d\n", bl,
- + ad->bl_mfd->panel_info->bl_max);
- + return -EINVAL;
- + }
- +
- + pr_debug("bl_in = %d, inv = %d\n", bl, inv);
- +
- + /* map panel backlight range to AD backlight range */
- + linear_map(bl, &bl, ad->bl_mfd->panel_info->bl_max,
- + MDSS_MDP_AD_BL_SCALE);
- +
- + pr_debug("Before linearization = %d\n", bl);
- + n = bl * (AD_BL_LIN_LEN - 1) / MDSS_MDP_AD_BL_SCALE;
- + pr_debug("n = %d\n", n);
- + if (n > (AD_BL_LIN_LEN - 1)) {
- + pr_err("Invalid index for BL linearization: %d.\n", n);
- + return ret;
- + } else if (n == (AD_BL_LIN_LEN - 1)) {
- + if (inv == MDP_PP_AD_BL_LINEAR_INV)
- + *bl_out = ad->bl_lin_inv[n];
- + else if (inv == MDP_PP_AD_BL_LINEAR)
- + *bl_out = ad->bl_lin[n];
- + } else {
- + /* linear piece-wise interpolation */
- + if (inv == MDP_PP_AD_BL_LINEAR_INV) {
- + *bl_out = bl * (AD_BL_LIN_LEN - 1) *
- + (ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) /
- + MDSS_MDP_AD_BL_SCALE - n *
- + (ad->bl_lin_inv[n + 1] - ad->bl_lin_inv[n]) +
- + ad->bl_lin_inv[n];
- + } else if (inv == MDP_PP_AD_BL_LINEAR) {
- + *bl_out = bl * (AD_BL_LIN_LEN - 1) *
- + (ad->bl_lin[n + 1] - ad->bl_lin[n]) /
- + MDSS_MDP_AD_BL_SCALE -
- + n * (ad->bl_lin[n + 1] - ad->bl_lin[n]) +
- + ad->bl_lin[n];
- + }
- + }
- + pr_debug("After linearization = %d\n", *bl_out);
- +
- + /* map AD backlight range back to panel backlight range */
- + linear_map(*bl_out, bl_out, MDSS_MDP_AD_BL_SCALE,
- + ad->bl_mfd->panel_info->bl_max);
- +
- + pr_debug("bl_out = %d\n", *bl_out);
- + return 0;
- +}
- +
- int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets)
- {
- u32 i;
- @@ -5188,34 +5322,6 @@ int mdss_mdp_calib_mode(struct msm_fb_data_type *mfd,
- return 0;
- }
- -#if defined(CONFIG_MDNIE_TFT_MSM8X26) || defined (CONFIG_FB_MSM_MDSS_S6E8AA0A_HD_PANEL) || defined(CONFIG_MDNIE_VIDEO_ENHANCED)
- -void mdss_negative_color(int is_negative_on)
- -{
- - u32 copyback;
- - int i;
- - struct mdss_mdp_ctl *ctl;
- - struct mdss_mdp_ctl *ctl_d = NULL;
- - struct mdss_data_type *mdata;
- -
- - mdata = mdss_mdp_get_mdata();
- - for (i = 0; i < mdata->nctl; i++) {
- - ctl = mdata->ctl_off + i;
- - if ((ctl->power_on) && (ctl->mfd) && (ctl->mfd->index == 0)) {
- - ctl_d = ctl;
- - break;
- - }
- - }
- - if (ctl_d) {
- - if(is_negative_on)
- - mdss_mdp_pcc_config(&pcc_reverse, ©back);
- - else
- - mdss_mdp_pcc_config(&pcc_normal, ©back);
- - } else {
- - pr_info("%s:ctl_d is NULL ", __func__);
- - }
- -}
- -#endif
- -
- int mdss_mdp_calib_config_buffer(struct mdp_calib_config_buffer *cfg,
- u32 *copyback)
- {
- diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
- index b0b726f..41f7f94 100755
- --- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
- +++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2014, 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
- @@ -99,14 +99,14 @@ static struct mdss_mdp_pipe *mdss_mdp_rotator_pipe_alloc(void)
- mixer = mdss_mdp_wb_mixer_alloc(1);
- if (!mixer) {
- - pr_err("wb mixer alloc failed\n");
- + pr_debug("wb mixer alloc failed\n");
- return NULL;
- }
- pipe = mdss_mdp_pipe_alloc_dma(mixer);
- if (!pipe) {
- mdss_mdp_wb_mixer_destroy(mixer);
- - pr_err("dma pipe allocation failed\n");
- + pr_debug("dma pipe allocation failed\n");
- return NULL;
- }
- @@ -469,13 +469,14 @@ int mdss_mdp_rotator_setup(struct msm_fb_data_type *mfd,
- list_add(&rot->list, &mdp5_data->rot_proc_list);
- } else if (req->id & MDSS_MDP_ROT_SESSION_MASK) {
- rot = mdss_mdp_rotator_session_get(req->id);
- +
- if (!rot) {
- pr_err("rotator session=%x not found\n", req->id);
- ret = -ENODEV;
- goto rot_err;
- }
- - if (work_busy(&rot->commit_work)) {
- + if (work_pending(&rot->commit_work)) {
- mutex_unlock(&rotator_lock);
- flush_work(&rot->commit_work);
- mutex_lock(&rotator_lock);
- @@ -646,11 +647,12 @@ static int mdss_mdp_rotator_finish(struct mdss_mdp_rotator_session *rot)
- rot_pipe = rot->pipe;
- if (rot_pipe) {
- - if (work_busy(&rot->commit_work)) {
- + if (work_pending(&rot->commit_work)) {
- mutex_unlock(&rotator_lock);
- - flush_work(&rot->commit_work);
- + cancel_work_sync(&rot->commit_work);
- mutex_lock(&rotator_lock);
- }
- +
- mdss_mdp_rotator_busy_wait(rot);
- list_del(&rot->head);
- }
- @@ -754,17 +756,6 @@ int mdss_mdp_rotator_play(struct msm_fb_data_type *mfd,
- pr_err("rotator queue error session id=%x\n", req->id);
- dst_buf_fail:
- - if(ret){
- - if (rot && rot->use_sync_pt){
- - if (rot->rot_sync_pt_data) {
- - atomic_inc(&rot->rot_sync_pt_data->commit_cnt);
- - mdss_fb_signal_timeline(rot->rot_sync_pt_data);
- - pr_err("release fence as this commit is failed.\n");
- - } else {
- - pr_err("rot_sync_pt_data is NULL\n");
- - }
- - }
- - }
- mutex_unlock(&rotator_lock);
- return ret;
- }
- diff --git a/include/linux/avtimer_kernel.h b/include/linux/avtimer_kernel.h
- new file mode 100644
- index 0000000..5eff8cc
- --- /dev/null
- +++ b/include/linux/avtimer_kernel.h
- @@ -0,0 +1,24 @@
- +/*
- + * Copyright (c) 2014, 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 _AVTIMER_H
- +#define _AVTIMER_H
- +
- +#include <uapi/linux/avtimer.h>
- +
- +int avcs_core_open(void);
- +int avcs_core_disable_power_collapse(int disable);/* true or flase */
- +int avcs_core_query_timer(uint64_t *avtimer_tick);
- +
- +#endif
- diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
- index f8b849d..6a5f4c6 100644
- --- a/include/linux/mmc/card.h
- +++ b/include/linux/mmc/card.h
- @@ -326,6 +326,10 @@ struct mmc_bkops_info {
- #define BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK 1 /* 1% */
- };
- +enum mmc_pon_type {
- + MMC_LONG_PON = 1,
- + MMC_SHRT_PON,
- +};
- /*
- * MMC device
- */
- @@ -416,7 +420,7 @@ struct mmc_card {
- struct device_attribute rpm_attrib;
- unsigned int idle_timeout;
- struct notifier_block reboot_notify;
- - bool issue_long_pon;
- + enum mmc_pon_type pon_type;
- u8 *cached_ext_csd;
- };
- @@ -674,5 +678,5 @@ extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics(
- struct mmc_card *card);
- extern void mmc_blk_init_packed_statistics(struct mmc_card *card);
- extern void mmc_blk_disable_wr_packing(struct mmc_queue *mq);
- -extern int mmc_send_long_pon(struct mmc_card *card);
- +extern int mmc_send_pon(struct mmc_card *card);
- #endif /* LINUX_MMC_CARD_H */
- diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
- index 5fb6ffd..1045f14 100644
- --- a/include/linux/msm_mdp.h
- +++ b/include/linux/msm_mdp.h
- @@ -528,6 +528,7 @@ enum mdss_mdp_blend_op {
- BLEND_OP_COVERAGE,
- BLEND_OP_MAX,
- };
- +
- #define DECIMATED_DIMENSION(dim, deci) (((dim) + ((1 << (deci)) - 1)) >> (deci))
- #define MAX_PLANES 4
- struct mdp_scale_data {
- diff --git a/include/linux/prctl.h b/include/linux/prctl.h
- index 8879b34..23728f0 100644
- --- a/include/linux/prctl.h
- +++ b/include/linux/prctl.h
- @@ -128,9 +128,7 @@
- * arg2 slack value, 0 means "use default"
- * arg3 pid of the thread whose timer slack needs to be set
- */
- -#ifndef CONFIG_SEC_H_PROJECT
- - #define PR_SET_TIMERSLACK_PID 41
- -#endif
- +#define PR_SET_TIMERSLACK_PID 41
- #define PR_SET_VMA 0x53564d41
- # define PR_SET_VMA_ANON_NAME 0
- diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
- index 2a5ebd4..64cd4b4 100644
- --- a/include/linux/usb/msm_hsusb_hw.h
- +++ b/include/linux/usb/msm_hsusb_hw.h
- @@ -87,6 +87,8 @@
- #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */
- #define PHY_IDHV_INTEN (1 << 8) /* PHY ID HV interrupt */
- #define PHY_OTGSESSVLDHV_INTEN (1 << 9) /* PHY Session Valid HV int. */
- +#define PHY_DPSE_INTEN (1 << 14) /* PHY DPSE HV interrupt*/
- +#define PHY_DMSE_INTEN (1 << 20) /* PHY DMSE HV interrupt*/
- #define PHY_CLAMP_DPDMSE_EN (1 << 21) /* PHY mpm DP DM clamp enable */
- #define PHY_POR_BIT_MASK BIT(0)
- #define PHY_POR_ASSERT (1 << 0) /* USB2 28nm PHY POR ASSERT */
- diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
- index c64c59e..55d6b1e 100644
- --- a/include/linux/wcnss_wlan.h
- +++ b/include/linux/wcnss_wlan.h
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2011-2013,2015 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
- @@ -29,7 +29,6 @@ enum wcnss_hw_type {
- struct wcnss_wlan_config {
- int use_48mhz_xo;
- int is_pronto_v3;
- - void __iomem *msm_wcnss_base;
- };
- enum {
- @@ -44,7 +43,8 @@ enum {
- #define HAVE_WCNSS_CAL_DOWNLOAD 1
- #define HAVE_WCNSS_RX_BUFF_COUNT 1
- #define WLAN_MAC_ADDR_SIZE (6)
- -#define CONFIG_WCNSS_REGISTER_DUMP_ON_BITE 1
- +#define PRONTO_PMU_OFFSET 0x1004
- +#define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP BIT(5)
- void wcnss_get_monotonic_boottime(struct timespec *ts);
- struct device *wcnss_wlan_get_device(void);
- diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
- index eb02dcc..7c6d5be 100644
- --- a/include/media/msm_cam_sensor.h
- +++ b/include/media/msm_cam_sensor.h
- @@ -49,6 +49,7 @@
- #define MAX_EEPROM_NAME 32
- #define MAX_NUMBER_OF_STEPS 47
- +#define MAX_POWER_CONFIG 12
- //************************************* Native functionalities for YUV sensor added by jai.prakash
- #define EXT_CAM_EV 1
- diff --git a/include/sound/Kbuild b/include/sound/Kbuild
- index 62d56c6..170ef9e 100644
- --- a/include/sound/Kbuild
- +++ b/include/sound/Kbuild
- @@ -15,3 +15,4 @@ header-y += compress_offload.h
- header-y += lsm_params.h
- header-y += voice_params.h
- header-y += voice_svc.h
- +header-y += msmcal-hwdep.h
- diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
- index 184cff3..028f3d7 100644
- --- a/include/sound/apr_audio-v2.h
- +++ b/include/sound/apr_audio-v2.h
- @@ -7382,7 +7382,7 @@ struct afe_svc_cmd_set_clip_bank_selection {
- /* Ultrasound supported formats */
- #define US_POINT_EPOS_FORMAT_V2 0x0001272D
- #define US_RAW_FORMAT_V2 0x0001272C
- -#define US_PROX_FORMAT_V2 0x0001272E
- +#define US_PROX_FORMAT_V4 0x0001273B
- #define US_RAW_SYNC_FORMAT 0x0001272F
- #define US_GES_SYNC_FORMAT 0x00012730
- #endif /*_APR_AUDIO_V2_H_ */
- diff --git a/include/sound/asound.h b/include/sound/asound.h
- index 7bf01b6..244bb30 100644
- --- a/include/sound/asound.h
- +++ b/include/sound/asound.h
- @@ -95,9 +95,10 @@ enum {
- SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
- SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
- SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */
- + SNDRV_HWDEP_IFACE_AUDIO_CODEC, /* codec Audio Control */
- /* Don't forget to change the following: */
- - SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
- + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_AUDIO_CODEC
- };
- struct snd_hwdep_info {
- diff --git a/include/sound/compress_offload.h b/include/sound/compress_offload.h
- index 5a5599a..4292802 100644
- --- a/include/sound/compress_offload.h
- +++ b/include/sound/compress_offload.h
- @@ -131,6 +131,8 @@ struct snd_compr_codec_caps {
- enum {
- SNDRV_COMPRESS_ENCODER_PADDING = 1,
- SNDRV_COMPRESS_ENCODER_DELAY = 2,
- + SNDRV_COMPRESS_MIN_BLK_SIZE = 3,
- + SNDRV_COMPRESS_MAX_BLK_SIZE = 4,
- };
- /**
- diff --git a/include/sound/msmcal-hwdep.h b/include/sound/msmcal-hwdep.h
- new file mode 100644
- index 0000000..324b497
- --- /dev/null
- +++ b/include/sound/msmcal-hwdep.h
- @@ -0,0 +1,34 @@
- +/*
- + * Copyright (c) 2014, 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 _CALIB_HWDEP_H
- +#define _CALIB_HWDEP_H
- +
- +#define WCD9XXX_CODEC_HWDEP_NODE 1000
- +enum wcd_cal_type {
- + WCD9XXX_MIN_CAL,
- + WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL,
- + WCD9XXX_MAD_CAL,
- + WCD9XXX_MBHC_CAL,
- + WCD9XXX_MAX_CAL,
- +};
- +
- +struct wcdcal_ioctl_buffer {
- + __u32 size;
- + __u8 __user *buffer;
- + enum wcd_cal_type cal_type;
- +};
- +
- +#define SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE \
- + _IOW('U', 0x1, struct wcdcal_ioctl_buffer)
- +
- +#endif /*_CALIB_HWDEP_H*/
- diff --git a/include/sound/q6core.h b/include/sound/q6core.h
- old mode 100755
- new mode 100644
- diff --git a/include/uapi/linux/avtimer.h b/include/uapi/linux/avtimer.h
- new file mode 100644
- index 0000000..f688b38
- --- /dev/null
- +++ b/include/uapi/linux/avtimer.h
- @@ -0,0 +1,19 @@
- +#ifndef _UAPI_AVTIMER_H
- +#define _UAPI_AVTIMER_H
- +
- +#include <linux/ioctl.h>
- +
- +#define MAJOR_NUM 100
- +
- +#define IOCTL_GET_AVTIMER_TICK _IOR(MAJOR_NUM, 0, char *)
- +/*
- + * This IOCTL is used read the avtimer tick value.
- + * Avtimer is a 64 bit timer tick, hence the expected
- + * argument is of type uint64_t
- + */
- +struct dev_avtimer_data {
- + uint32_t avtimer_msw_phy_addr;
- + uint32_t avtimer_lsw_phy_addr;
- +};
- +
- +#endif
- diff --git a/kernel/sched/core.c b/kernel/sched/core.c
- index b873f1f..d847509 100644
- --- a/kernel/sched/core.c
- +++ b/kernel/sched/core.c
- @@ -1607,6 +1607,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
- {
- unsigned long flags;
- int cpu, src_cpu, success = 0;
- + int notify = 0;
- smp_wmb();
- raw_spin_lock_irqsave(&p->pi_lock, flags);
- @@ -1664,10 +1665,13 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
- ttwu_queue(p, cpu);
- stat:
- ttwu_stat(p, cpu, wake_flags);
- +
- + if (src_cpu != cpu && task_notify_on_migrate(p))
- + notify = 1;
- out:
- raw_spin_unlock_irqrestore(&p->pi_lock, flags);
- - if (src_cpu != cpu && task_notify_on_migrate(p))
- + if (notify)
- atomic_notifier_call_chain(&migration_notifier_head,
- cpu, (void *)src_cpu);
- return success;
- diff --git a/kernel/sys.c b/kernel/sys.c
- index fc5ec84..7d01c44 100644
- --- a/kernel/sys.c
- +++ b/kernel/sys.c
- @@ -50,9 +50,6 @@
- #include <linux/user_namespace.h>
- #include <linux/kmsg_dump.h>
- -#ifdef CONFIG_SEC_DEBUG
- -#include <mach/sec_debug.h>
- -#endif
- /* Move somewhere else to avoid recompiling? */
- #include <generated/utsrelease.h>
- @@ -129,54 +126,6 @@ EXPORT_SYMBOL(cad_pid);
- void (*pm_power_off_prepare)(void);
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- -int sec_check_execpath(struct mm_struct *mm, char *denypath);
- -#if defined CONFIG_SEC_RESTRICT_ROOTING_LOG
- -#define PRINT_LOG(...) printk(KERN_ERR __VA_ARGS__)
- -#else
- -#define PRINT_LOG(...)
- -#endif // End of CONFIG_SEC_RESTRICT_ROOTING_LOG
- -
- -static int sec_restrict_uid(void)
- -{
- - int ret = 0;
- - struct task_struct *parent_tsk;
- - const struct cred *parent_cred;
- -
- - read_lock(&tasklist_lock);
- - parent_tsk = current->parent;
- - if (!parent_tsk) {
- - read_unlock(&tasklist_lock);
- - return 0;
- - }
- -
- - get_task_struct(parent_tsk);
- - /* holding on to the task struct is enough so just release
- - * the tasklist lock here */
- - read_unlock(&tasklist_lock);
- -
- - parent_cred = get_task_cred(parent_tsk);
- - if (!parent_cred)
- - goto out;
- - if (parent_cred->euid == 0 || parent_tsk->pid == 1) {
- - ret = 0;
- - } else if (sec_check_execpath(current->mm, "/system/bin/pppd")) {
- - PRINT_LOG("VPN allowed to use root permission");
- - ret = 0;
- - } else {
- - PRINT_LOG("Restricted changing UID. PID = %d(%s) PPID = %d(%s)\n",
- - current->pid, current->comm,
- - parent_tsk->pid, parent_tsk->comm);
- - ret = 1;
- - }
- - put_cred(parent_cred);
- -out:
- - put_task_struct(parent_tsk);
- -
- - return ret;
- -}
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- /*
- * Returns true if current's euid is same as p's uid or euid,
- * or has CAP_SYS_NICE to p's user_ns.
- @@ -418,9 +367,6 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
- */
- void kernel_restart(char *cmd)
- {
- -#ifdef CONFIG_SEC_MONITOR_BATTERY_REMOVAL
- - kernel_sec_set_normal_pwroff(1);
- -#endif
- kernel_restart_prepare(cmd);
- if (!cmd)
- printk(KERN_EMERG "Restarting system.\n");
- @@ -462,9 +408,6 @@ EXPORT_SYMBOL_GPL(kernel_halt);
- */
- void kernel_power_off(void)
- {
- -#ifdef CONFIG_SEC_MONITOR_BATTERY_REMOVAL
- - kernel_sec_set_normal_pwroff(1);
- -#endif
- kernel_shutdown_prepare(SYSTEM_POWER_OFF);
- if (pm_power_off_prepare)
- pm_power_off_prepare();
- @@ -573,11 +516,8 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
- return ret;
- }
- -extern void do_emergency_remount(struct work_struct *work);
- -
- static void deferred_cad(struct work_struct *dummy)
- {
- - do_emergency_remount(NULL);
- kernel_restart(NULL);
- }
- @@ -620,14 +560,6 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(rgid == 0 || egid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -675,14 +607,6 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(gid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -753,14 +677,6 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(ruid == 0 || euid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -822,14 +738,6 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(uid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -871,14 +779,6 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(ruid == 0 || euid == 0 || suid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -944,14 +844,6 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
- struct cred *new;
- int retval;
- -#if defined CONFIG_SEC_RESTRICT_SETUID
- - if(rgid == 0 || egid == 0 || sgid == 0)
- - {
- - if(sec_restrict_uid())
- - return -EACCES;
- - }
- -#endif // End of CONFIG_SEC_RESTRICT_SETUID
- -
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
- @@ -1309,7 +1201,7 @@ static int override_release(char __user *release, size_t len)
- rest++;
- }
- v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
- - copy = clamp_t(size_t, len, 1, sizeof(buf));
- + copy = min(sizeof(buf), max_t(size_t, 1, len));
- copy = scnprintf(buf, copy, "2.6.%u%s", v, rest);
- ret = copy_to_user(release, buf, copy + 1);
- }
- @@ -2076,9 +1968,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
- unsigned long, arg4, unsigned long, arg5)
- {
- struct task_struct *me = current;
- -#ifndef CONFIG_SEC_H_PROJECT
- struct task_struct *tsk;
- -#endif
- unsigned char comm[sizeof(me->comm)];
- long error;
- @@ -2238,15 +2128,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
- case PR_SET_VMA:
- error = prctl_set_vma(arg2, arg3, arg4, arg5);
- break;
- - /* remove this case because of sidesync call mute for H-projects */
- -
- -#ifndef CONFIG_SEC_H_PROJECT
- case PR_SET_TIMERSLACK_PID:
- - if (current->pid != (pid_t)arg3 &&
- + if (task_pid_vnr(current) != (pid_t)arg3 &&
- !capable(CAP_SYS_NICE))
- return -EPERM;
- rcu_read_lock();
- - tsk = find_task_by_pid_ns((pid_t)arg3, &init_pid_ns);
- + tsk = find_task_by_vpid((pid_t)arg3);
- if (tsk == NULL) {
- rcu_read_unlock();
- return -EINVAL;
- @@ -2261,7 +2148,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
- put_task_struct(tsk);
- error = 0;
- break;
- -#endif
- default:
- error = -EINVAL;
- break;
- diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
- index ed0c66d..3cd6b12 100644
- --- a/kernel/time/timekeeping.c
- +++ b/kernel/time/timekeeping.c
- @@ -296,7 +296,7 @@ void ktime_get_ts(struct timespec *ts)
- } while (read_seqretry(&timekeeper.lock, seq));
- set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
- - (s64)ts->tv_nsec + tomono.tv_nsec + nsecs);
- + ts->tv_nsec + tomono.tv_nsec + nsecs);
- }
- EXPORT_SYMBOL_GPL(ktime_get_ts);
- @@ -1147,12 +1147,14 @@ out:
- */
- void getboottime(struct timespec *ts)
- {
- - time_t tv_sec = timekeeper.wall_to_monotonic.tv_sec +
- - timekeeper.total_sleep_time.tv_sec;
- - s64 tv_nsec = (s64)timekeeper.wall_to_monotonic.tv_nsec +
- - timekeeper.total_sleep_time.tv_nsec;
- -
- - set_normalized_timespec(ts, -tv_sec, -tv_nsec);
- + struct timespec boottime = {
- + .tv_sec = timekeeper.wall_to_monotonic.tv_sec +
- + timekeeper.total_sleep_time.tv_sec,
- + .tv_nsec = timekeeper.wall_to_monotonic.tv_nsec +
- + timekeeper.total_sleep_time.tv_nsec
- + };
- +
- + set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
- }
- EXPORT_SYMBOL_GPL(getboottime);
- @@ -1184,7 +1186,7 @@ void get_monotonic_boottime(struct timespec *ts)
- } while (read_seqretry(&timekeeper.lock, seq));
- set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec,
- - (s64)ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec + nsecs);
- + (s64)ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec + nsecs);
- }
- EXPORT_SYMBOL_GPL(get_monotonic_boottime);
- @@ -1254,7 +1256,7 @@ struct timespec get_monotonic_coarse(void)
- } while (read_seqretry(&timekeeper.lock, seq));
- set_normalized_timespec(&now, now.tv_sec + mono.tv_sec,
- - (s64)now.tv_nsec + mono.tv_nsec);
- + now.tv_nsec + mono.tv_nsec);
- return now;
- }
- diff --git a/mm/vmscan.c b/mm/vmscan.c
- index dbbc164..e2e43aa 100644
- --- a/mm/vmscan.c
- +++ b/mm/vmscan.c
- @@ -19,7 +19,6 @@
- #include <linux/pagemap.h>
- #include <linux/init.h>
- #include <linux/highmem.h>
- -#include <linux/vmpressure.h>
- #include <linux/vmstat.h>
- #include <linux/file.h>
- #include <linux/writeback.h>
- @@ -54,19 +53,6 @@
- #define CREATE_TRACE_POINTS
- #include <trace/events/vmscan.h>
- -#ifdef CONFIG_INCREASE_MAXIMUM_SWAPPINESS
- -int max_swappiness = 200;
- -#endif
- -
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- -struct rtcc_control {
- - int nr_anon;
- - int nr_file;
- - int swappiness;
- - int nr_swapped;
- -};
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- struct scan_control {
- /* Incremented by the number of inactive pages that were scanned */
- unsigned long nr_scanned;
- @@ -92,8 +78,6 @@ struct scan_control {
- int order;
- - int swappiness;
- -
- /* Scan (total_size >> priority) pages at once */
- int priority;
- @@ -108,10 +92,6 @@ struct scan_control {
- * are scanned.
- */
- nodemask_t *nodemask;
- -
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - struct rtcc_control *rc;
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- };
- struct mem_cgroup_zone {
- @@ -155,17 +135,6 @@ struct mem_cgroup_zone {
- int vm_swappiness = 60;
- long vm_total_pages; /* The total number of pages which the VM controls */
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- -extern int get_rtcc_status(void);
- -atomic_t kswapd_running = ATOMIC_INIT(1);
- -long nr_kswapd_swapped = 0;
- -
- -static bool rtcc_reclaim(struct scan_control *sc)
- -{
- - return (sc->rc != NULL);
- -}
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- static LIST_HEAD(shrinker_list);
- static DECLARE_RWSEM(shrinker_rwsem);
- @@ -196,11 +165,9 @@ unsigned long zone_reclaimable_pages(struct zone *zone)
- nr = zone_page_state(zone, NR_ACTIVE_FILE) +
- zone_page_state(zone, NR_INACTIVE_FILE);
- -#ifndef CONFIG_RUNTIME_COMPCACHE
- if (get_nr_swap_pages() > 0)
- nr += zone_page_state(zone, NR_ACTIVE_ANON) +
- zone_page_state(zone, NR_INACTIVE_ANON);
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- return nr;
- }
- @@ -293,7 +260,7 @@ unsigned long shrink_slab(struct shrink_control *shrink,
- list_for_each_entry(shrinker, &shrinker_list, list) {
- unsigned long long delta;
- - long total_scan, pages_got;
- + long total_scan;
- long max_pass;
- int shrink_ret = 0;
- long nr;
- @@ -359,14 +326,10 @@ unsigned long shrink_slab(struct shrink_control *shrink,
- batch_size);
- if (shrink_ret == -1)
- break;
- - if (shrink_ret < nr_before) {
- - pages_got = nr_before - shrink_ret;
- - ret += pages_got;
- - total_scan -= pages_got > batch_size ? pages_got : batch_size;
- - } else {
- - total_scan -= batch_size;
- - }
- + if (shrink_ret < nr_before)
- + ret += nr_before - shrink_ret;
- count_vm_events(SLABS_SCANNED, batch_size);
- + total_scan -= batch_size;
- cond_resched();
- }
- @@ -511,6 +474,18 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
- if (!PageWriteback(page)) {
- /* synchronous write or broken a_ops? */
- ClearPageReclaim(page);
- + if (PageError(page) && PageSwapCache(page)) {
- + ClearPageError(page);
- + /*
- + * We lock the page here because it is required
- + * to free the swp space later in
- + * shrink_page_list. But the page may be
- + * unclocked by functions like
- + * handle_write_error.
- + */
- + __set_page_locked(page);
- + return PAGE_ACTIVATE;
- + }
- }
- trace_mm_vmscan_writepage(page, trace_reclaim_flags(page));
- inc_zone_page_state(page, NR_VMSCAN_WRITE);
- @@ -1151,11 +1126,6 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
- mem_cgroup_lru_del_list(page, lru);
- list_move(&page->lru, dst);
- nr_taken += hpage_nr_pages(page);
- -#if defined(CONFIG_CMA_PAGE_COUNTING)
- - if (PageCMA(page))
- - __mod_zone_page_state(page_zone(page),
- - NR_FREE_CMA_PAGES + 1 + lru, -1);
- -#endif
- break;
- case -EBUSY:
- @@ -1233,11 +1203,6 @@ static int too_many_isolated(struct zone *zone, int file,
- {
- unsigned long inactive, isolated;
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - if (get_rtcc_status() == 1)
- - return 0;
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- if (current_is_kswapd())
- return 0;
- @@ -1414,15 +1379,6 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,
- (nr_taken >> (DEF_PRIORITY - sc->priority)))
- wait_iff_congested(zone, BLK_RW_ASYNC, HZ/10);
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - if (!file) {
- - if (rtcc_reclaim(sc))
- - sc->rc->nr_swapped += nr_reclaimed;
- - else
- - nr_kswapd_swapped += nr_reclaimed;
- - }
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- trace_mm_vmscan_lru_shrink_inactive(zone->zone_pgdat->node_id,
- zone_idx(zone),
- nr_scanned, nr_reclaimed,
- @@ -1456,9 +1412,6 @@ static void move_active_pages_to_lru(struct zone *zone,
- {
- unsigned long pgmoved = 0;
- struct page *page;
- -#if defined(CONFIG_CMA_PAGE_COUNTING)
- - unsigned long nr_cma = 0;
- -#endif
- while (!list_empty(list)) {
- struct lruvec *lruvec;
- @@ -1471,10 +1424,6 @@ static void move_active_pages_to_lru(struct zone *zone,
- lruvec = mem_cgroup_lru_add_list(zone, page, lru);
- list_move(&page->lru, &lruvec->lists[lru]);
- pgmoved += hpage_nr_pages(page);
- -#if defined(CONFIG_CMA_PAGE_COUNTING)
- - if (PageCMA(page))
- - nr_cma++;
- -#endif
- if (put_page_testzero(page)) {
- __ClearPageLRU(page);
- @@ -1490,10 +1439,6 @@ static void move_active_pages_to_lru(struct zone *zone,
- }
- }
- __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved);
- -#if defined(CONFIG_CMA_PAGE_COUNTING)
- - __mod_zone_page_state(zone, NR_FREE_CMA_PAGES + 1 + lru, nr_cma);
- -#endif
- -
- if (!is_active_lru(lru))
- __count_vm_events(PGDEACTIVATE, pgmoved);
- }
- @@ -1700,12 +1645,8 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
- static int vmscan_swappiness(struct scan_control *sc)
- {
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - if (rtcc_reclaim(sc))
- - return sc->rc->swappiness;
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- if (global_reclaim(sc))
- - return sc->swappiness;
- + return vm_swappiness;
- return mem_cgroup_swappiness(sc->target_mem_cgroup);
- }
- @@ -1775,11 +1716,7 @@ static void get_scan_count(struct mem_cgroup_zone *mz, struct scan_control *sc,
- * This scanning priority is essentially the inverse of IO cost.
- */
- anon_prio = vmscan_swappiness(sc);
- -#ifdef CONFIG_INCREASE_MAXIMUM_SWAPPINESS
- - file_prio = max_swappiness - vmscan_swappiness(sc);
- -#else
- file_prio = 200 - vmscan_swappiness(sc);
- -#endif
- /*
- * OK, so we have swap space and a fair amount of page cache
- @@ -1921,30 +1858,15 @@ static void shrink_mem_cgroup_zone(struct mem_cgroup_zone *mz,
- unsigned long nr_reclaimed, nr_scanned;
- unsigned long nr_to_reclaim = sc->nr_to_reclaim;
- struct blk_plug plug;
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - struct rtcc_control *rc = sc->rc;
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- restart:
- nr_reclaimed = 0;
- nr_scanned = sc->nr_scanned;
- get_scan_count(mz, sc, nr);
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - if (rtcc_reclaim(sc))
- - nr[LRU_INACTIVE_FILE] = nr[LRU_ACTIVE_FILE] = 0;
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- blk_start_plug(&plug);
- while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
- nr[LRU_INACTIVE_FILE]) {
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - if (rtcc_reclaim(sc)) {
- - if (rc->nr_swapped >= rc->nr_anon)
- - nr[LRU_INACTIVE_ANON] = nr[LRU_ACTIVE_ANON] = 0;
- - }
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- for_each_evictable_lru(lru) {
- if (nr[lru]) {
- nr_to_scan = min_t(unsigned long,
- @@ -1988,7 +1910,6 @@ restart:
- static void shrink_zone(struct zone *zone, struct scan_control *sc)
- {
- - unsigned long nr_reclaimed, nr_scanned;
- struct mem_cgroup *root = sc->target_mem_cgroup;
- struct mem_cgroup_reclaim_cookie reclaim = {
- .zone = zone,
- @@ -1996,9 +1917,6 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
- };
- struct mem_cgroup *memcg;
- - nr_reclaimed = sc->nr_reclaimed;
- - nr_scanned = sc->nr_scanned;
- -
- memcg = mem_cgroup_iter(root, NULL, &reclaim);
- do {
- struct mem_cgroup_zone mz = {
- @@ -2023,10 +1941,6 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
- }
- memcg = mem_cgroup_iter(root, memcg, &reclaim);
- } while (memcg);
- -
- - vmpressure(sc->gfp_mask, sc->target_mem_cgroup,
- - sc->nr_scanned - nr_scanned,
- - sc->nr_reclaimed - nr_reclaimed);
- }
- /* Returns true if compaction should go ahead for a high-order request */
- @@ -2172,140 +2086,6 @@ static bool all_unreclaimable(struct zonelist *zonelist,
- return true;
- }
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- -/*
- - * This is the main entry point to direct page reclaim for RTCC.
- - *
- - * If a full scan of the inactive list fails to free enough memory then we
- - * are "out of memory" and something needs to be killed.
- - *
- - * If the caller is !__GFP_FS then the probability of a failure is reasonably
- - * high - the zone may be full of dirty or under-writeback pages, which this
- - * caller can't do much about. We kick the writeback threads and take explicit
- - * naps in the hope that some of these pages can be written. But if the
- - * allocating task holds filesystem locks which prevent writeout this might not
- - * work, and the allocation attempt will fail.
- - *
- - * returns: 0, if no pages reclaimed
- - * else, the number of pages reclaimed
- - */
- -static unsigned long rtcc_do_try_to_free_pages(struct zonelist *zonelist, struct scan_control *sc, struct shrink_control *shrink)
- -{
- - unsigned long total_scanned = 0;
- - unsigned long writeback_threshold;
- - bool aborted_reclaim;
- -
- - delayacct_freepages_start();
- -
- - if (global_reclaim(sc))
- - count_vm_event(ALLOCSTALL);
- -
- - do {
- - sc->nr_scanned = 0;
- - aborted_reclaim = shrink_zones(zonelist, sc);
- -
- - total_scanned += sc->nr_scanned;
- - if (sc->nr_reclaimed >= sc->nr_to_reclaim)
- - goto out;
- -
- - /*
- - * Try to write back as many pages as we just scanned. This
- - * tends to cause slow streaming writers to write data to the
- - * disk smoothly, at the dirtying rate, which is nice. But
- - * that's undesirable in laptop mode, where we *want* lumpy
- - * writeout. So in laptop mode, write out the whole world.
- - */
- - writeback_threshold = sc->nr_to_reclaim + sc->nr_to_reclaim / 2;
- - if (total_scanned > writeback_threshold) {
- - wakeup_flusher_threads(laptop_mode ? 0 : total_scanned,
- - WB_REASON_TRY_TO_FREE_PAGES);
- - sc->may_writepage = 1;
- - }
- -
- - /* Take a nap, wait for some writeback to complete */
- - if (!sc->hibernation_mode && sc->nr_scanned &&
- - sc->priority < DEF_PRIORITY - 2) {
- - struct zone *preferred_zone;
- -
- - first_zones_zonelist(zonelist, gfp_zone(sc->gfp_mask),
- - &cpuset_current_mems_allowed,
- - &preferred_zone);
- - wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/10);
- - }
- - } while (--sc->priority >= 0);
- -
- -out:
- - delayacct_freepages_end();
- -
- - if (sc->nr_reclaimed)
- - return sc->nr_reclaimed;
- -
- - /*
- - * As hibernation is going on, kswapd is freezed so that it can't mark
- - * the zone into all_unreclaimable. Thus bypassing all_unreclaimable
- - * check.
- - */
- - if (oom_killer_disabled)
- - return 0;
- -
- - /* Aborted reclaim to try compaction? don't OOM, then */
- - if (aborted_reclaim)
- - return 1;
- -
- - /* top priority shrink_zones still had more to do? don't OOM, then */
- - if (global_reclaim(sc) && !all_unreclaimable(zonelist, sc))
- - return 1;
- -
- - return 0;
- -}
- -
- -unsigned long rtcc_reclaim_pages(unsigned long nr_to_reclaim, int swappiness, unsigned long *nr_swapped)
- -{
- - struct reclaim_state reclaim_state;
- -
- - struct scan_control sc = {
- - .gfp_mask = GFP_HIGHUSER_MOVABLE,
- - .may_swap = 1,
- - .may_unmap = 1,
- - .may_writepage = 1,
- - .nr_to_reclaim = nr_to_reclaim,
- - .target_mem_cgroup = NULL,
- - .order = 0,
- - .priority = DEF_PRIORITY/2,
- - };
- - struct shrink_control shrink = {
- - .gfp_mask = sc.gfp_mask,
- - };
- - struct zonelist *zonelist = node_zonelist(numa_node_id(), sc.gfp_mask);
- - struct task_struct *p = current;
- - unsigned long nr_reclaimed;
- - struct rtcc_control rc;
- -
- - rc.swappiness = swappiness;
- - rc.nr_anon = nr_to_reclaim * swappiness / 200;
- - rc.nr_file = nr_to_reclaim - rc.nr_anon;
- - rc.nr_swapped = 0;
- - sc.rc = &rc;
- -
- - if (swappiness <= 1)
- - sc.may_swap = 0;
- -
- - p->flags |= PF_MEMALLOC;
- - lockdep_set_current_reclaim_state(sc.gfp_mask);
- - reclaim_state.reclaimed_slab = 0;
- - p->reclaim_state = &reclaim_state;
- -
- - nr_reclaimed = rtcc_do_try_to_free_pages(zonelist, &sc, &shrink);
- - *nr_swapped = rc.nr_swapped;
- -
- - p->reclaim_state = NULL;
- - lockdep_clear_current_reclaim_state();
- - p->flags &= ~PF_MEMALLOC;
- -
- - return nr_reclaimed;
- -}
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- /*
- * This is the main entry point to direct page reclaim.
- *
- @@ -2339,7 +2119,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
- count_vm_event(ALLOCSTALL);
- do {
- - vmpressure_prio(sc->gfp_mask, sc->target_mem_cgroup, sc->priority);
- sc->nr_scanned = 0;
- aborted_reclaim = shrink_zones(zonelist, sc);
- @@ -2357,7 +2136,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
- lru_pages += zone_reclaimable_pages(zone);
- }
- - shrink->priority = sc->priority;
- shrink_slab(shrink, sc->nr_scanned, lru_pages);
- if (reclaim_state) {
- sc->nr_reclaimed += reclaim_state->reclaimed_slab;
- @@ -2428,16 +2206,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
- .may_writepage = !laptop_mode,
- .nr_to_reclaim = SWAP_CLUSTER_MAX,
- .may_unmap = 1,
- -#if defined(CONFIG_DIRECT_RECLAIM_FILE_PAGES_ONLY) || defined(CONFIG_RUNTIME_COMPCACHE)
- - .may_swap = 0,
- -#else
- .may_swap = 1,
- -#endif
- -#ifdef CONFIG_ZSWAP
- - .swappiness = vm_swappiness / 2,
- -#else
- - .swappiness = vm_swappiness,
- -#endif
- .order = order,
- .priority = DEF_PRIORITY,
- .target_mem_cgroup = NULL,
- @@ -2472,7 +2241,6 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg,
- .may_unmap = 1,
- .may_swap = !noswap,
- .order = 0,
- - .swappiness = vm_swappiness,
- .priority = 0,
- .target_mem_cgroup = memcg,
- };
- @@ -2516,7 +2284,6 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
- .may_swap = !noswap,
- .nr_to_reclaim = SWAP_CLUSTER_MAX,
- .order = 0,
- - .swappiness = vm_swappiness,
- .priority = DEF_PRIORITY,
- .target_mem_cgroup = memcg,
- .nodemask = NULL, /* we don't care the placement */
- @@ -2608,12 +2375,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages,
- for (i = 0; i <= classzone_idx; i++)
- present_pages += pgdat->node_zones[i].present_pages;
- -#ifdef CONFIG_TIGHT_PGDAT_BALANCE
- - return balanced_pages >= (present_pages >> 1);
- -#else
- /* A special case here: if zone has no page, we think it's balanced */
- return balanced_pages >= (present_pages >> 2);
- -#endif
- }
- /* is kswapd sleeping prematurely? */
- @@ -2687,7 +2450,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
- static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
- int *classzone_idx)
- {
- - struct zone *unbalanced_zone;
- + int all_zones_ok;
- unsigned long balanced;
- int i;
- int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */
- @@ -2698,18 +2461,13 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
- struct scan_control sc = {
- .gfp_mask = GFP_KERNEL,
- .may_unmap = 1,
- -#ifndef CONFIG_KSWAPD_NOSWAP
- .may_swap = 1,
- -#else
- - .may_swap = 0,
- -#endif /* CONFIG_KSWAPD_NOSWAP */
- /*
- * kswapd doesn't want to be bailed out while reclaim. because
- * we want to put equal scanning pressure on each zone.
- */
- .nr_to_reclaim = ULONG_MAX,
- .order = order,
- - .swappiness = vm_swappiness,
- .target_mem_cgroup = NULL,
- };
- struct shrink_control shrink = {
- @@ -2726,7 +2484,7 @@ loop_again:
- unsigned long lru_pages = 0;
- int has_under_min_watermark_zone = 0;
- - unbalanced_zone = NULL;
- + all_zones_ok = 1;
- balanced = 0;
- /*
- @@ -2841,7 +2599,6 @@ loop_again:
- shrink_zone(zone, &sc);
- reclaim_state->reclaimed_slab = 0;
- - shrink.priority = sc.priority;
- nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages);
- sc.nr_reclaimed += reclaim_state->reclaimed_slab;
- total_scanned += sc.nr_scanned;
- @@ -2864,7 +2621,7 @@ loop_again:
- }
- if (!zone_balanced(zone, testorder, 0, end_zone)) {
- - unbalanced_zone = zone;
- + all_zones_ok = 0;
- /*
- * We are still under min water mark. This
- * means that we have a GFP_ATOMIC allocation
- @@ -2887,7 +2644,7 @@ loop_again:
- }
- }
- - if (!unbalanced_zone || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))
- + if (all_zones_ok || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))
- break; /* kswapd: all done */
- /*
- * OK, kswapd is getting into trouble. Take a nap, then take
- @@ -2897,7 +2654,7 @@ loop_again:
- if (has_under_min_watermark_zone)
- count_vm_event(KSWAPD_SKIP_CONGESTION_WAIT);
- else
- - wait_iff_congested(unbalanced_zone, BLK_RW_ASYNC, HZ/10);
- + congestion_wait(BLK_RW_ASYNC, HZ/10);
- }
- /*
- @@ -2916,7 +2673,7 @@ out:
- * high-order: Balanced zones must make up at least 25% of the node
- * for the node to be balanced
- */
- - if (unbalanced_zone && (!order || !pgdat_balanced(pgdat, balanced, *classzone_idx))) {
- + if (!(all_zones_ok || (order && pgdat_balanced(pgdat, balanced, *classzone_idx)))) {
- cond_resched();
- try_to_freeze();
- @@ -3005,10 +2762,6 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
- if (!sleeping_prematurely(pgdat, order, remaining, classzone_idx)) {
- trace_mm_vmscan_kswapd_sleep(pgdat->node_id);
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - atomic_set(&kswapd_running, 0);
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- /*
- * vmstat counters are not perfectly accurate and the estimated
- * value for counters such as NR_FREE_PAGES can deviate from the
- @@ -3130,10 +2883,6 @@ static int kswapd(void *p)
- if (kthread_should_stop())
- break;
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - atomic_set(&kswapd_running, 1);
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- -
- /*
- * We can speed up thawing tasks if we don't call balance_pgdat
- * after returning from the refrigerator
- @@ -3174,6 +2923,27 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx)
- wake_up_interruptible(&pgdat->kswapd_wait);
- }
- +/*
- + * The reclaimable count would be mostly accurate.
- + * The less reclaimable pages may be
- + * - mlocked pages, which will be moved to unevictable list when encountered
- + * - mapped pages, which may require several travels to be reclaimed
- + * - dirty pages, which is not "instantly" reclaimable
- + */
- +unsigned long global_reclaimable_pages(void)
- +{
- + int nr;
- +
- + nr = global_page_state(NR_ACTIVE_FILE) +
- + global_page_state(NR_INACTIVE_FILE);
- +
- + if (get_nr_swap_pages() > 0)
- + nr += global_page_state(NR_ACTIVE_ANON) +
- + global_page_state(NR_INACTIVE_ANON);
- +
- + return nr;
- +}
- +
- #ifdef CONFIG_HIBERNATION
- /*
- * Try to free `nr_to_reclaim' of memory, system-wide, and return the number of
- @@ -3194,7 +2964,6 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
- .nr_to_reclaim = nr_to_reclaim,
- .hibernation_mode = 1,
- .order = 0,
- - .swappiness = vm_swappiness,
- .priority = DEF_PRIORITY,
- };
- struct shrink_control shrink = {
- @@ -3376,16 +3145,11 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
- struct scan_control sc = {
- .may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE),
- .may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP),
- -#ifdef CONFIG_RUNTIME_COMPCACHE
- - .may_swap = 0,
- -#else
- .may_swap = 1,
- -#endif /* CONFIG_RUNTIME_COMPCACHE */
- .nr_to_reclaim = max_t(unsigned long, nr_pages,
- SWAP_CLUSTER_MAX),
- .gfp_mask = gfp_mask,
- .order = order,
- - .swappiness = vm_swappiness,
- .priority = ZONE_RECLAIM_PRIORITY,
- };
- struct shrink_control shrink = {
- @@ -3430,7 +3194,6 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
- unsigned long lru_pages = zone_reclaimable_pages(zone);
- /* No reclaimable slab or very low memory pressure */
- - shrink.priority = sc.priority;
- if (!shrink_slab(&shrink, sc.nr_scanned, lru_pages))
- break;
- @@ -3577,11 +3340,6 @@ void check_move_unevictable_pages(struct page **pages, int nr_pages)
- LRU_UNEVICTABLE, lru);
- list_move(&page->lru, &lruvec->lists[lru]);
- __inc_zone_state(zone, NR_INACTIVE_ANON + lru);
- -#if defined(CONFIG_CMA_PAGE_COUNTING)
- - if (PageCMA(page))
- - __inc_zone_state(zone,
- - NR_FREE_CMA_PAGES + 1 + lru);
- -#endif
- pgrescued++;
- }
- }
- diff --git a/net/core/dev.c b/net/core/dev.c
- index cd46460..542d014 100644
- --- a/net/core/dev.c
- +++ b/net/core/dev.c
- @@ -6274,10 +6274,20 @@ static int dev_cpu_callback(struct notifier_block *nfb,
- oldsd->output_queue = NULL;
- oldsd->output_queue_tailp = &oldsd->output_queue;
- }
- - /* Append NAPI poll list from offline CPU. */
- - if (!list_empty(&oldsd->poll_list)) {
- - list_splice_init(&oldsd->poll_list, &sd->poll_list);
- - raise_softirq_irqoff(NET_RX_SOFTIRQ);
- + /* Append NAPI poll list from offline CPU, with one exception :
- + * process_backlog() must be called by cpu owning percpu backlog.
- + * We properly handle process_queue & input_pkt_queue later.
- + */
- + while (!list_empty(&oldsd->poll_list)) {
- + struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
- + struct napi_struct,
- + poll_list);
- +
- + list_del_init(&napi->poll_list);
- + if (napi->poll == process_backlog)
- + napi->state = 0;
- + else
- + ____napi_schedule(sd, napi);
- }
- raise_softirq_irqoff(NET_TX_SOFTIRQ);
- @@ -6288,7 +6298,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
- netif_rx(skb);
- input_queue_head_incr(oldsd);
- }
- - while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
- + while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
- netif_rx(skb);
- input_queue_head_incr(oldsd);
- }
- diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
- index 1f78f21..a5f6665 100644
- --- a/net/netfilter/xt_qtaguid.c
- +++ b/net/netfilter/xt_qtaguid.c
- @@ -1298,6 +1298,38 @@ static void iface_stat_update(struct net_device *net_dev, bool stash_only)
- spin_unlock_bh(&iface_stat_list_lock);
- }
- +/* Guarantied to return a net_device that has a name */
- +static void get_dev_and_dir(const struct sk_buff *skb,
- + struct xt_action_param *par,
- + enum ifs_tx_rx *direction,
- + const struct net_device **el_dev)
- +{
- + BUG_ON(!direction || !el_dev);
- +
- + if (par->in) {
- + *el_dev = par->in;
- + *direction = IFS_RX;
- + } else if (par->out) {
- + *el_dev = par->out;
- + *direction = IFS_TX;
- + } else {
- + pr_err("qtaguid[%d]: %s(): no par->in/out?!!\n",
- + par->hooknum, __func__);
- + BUG();
- + }
- + if (unlikely(!(*el_dev)->name)) {
- + pr_err("qtaguid[%d]: %s(): no dev->name?!!\n",
- + par->hooknum, __func__);
- + BUG();
- + }
- + if (skb->dev && *el_dev != skb->dev) {
- + MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs par->%s=%p %s\n",
- + par->hooknum, skb->dev, skb->dev->name,
- + *direction == IFS_RX ? "in" : "out", *el_dev,
- + (*el_dev)->name);
- + }
- +}
- +
- /*
- * Update stats for the specified interface from the skb.
- * Do nothing if the entry
- @@ -1309,50 +1341,27 @@ static void iface_stat_update_from_skb(const struct sk_buff *skb,
- {
- struct iface_stat *entry;
- const struct net_device *el_dev;
- - enum ifs_tx_rx direction = par->in ? IFS_RX : IFS_TX;
- + enum ifs_tx_rx direction;
- int bytes = skb->len;
- int proto;
- - if (!skb->dev) {
- - MT_DEBUG("qtaguid[%d]: no skb->dev\n", par->hooknum);
- - el_dev = par->in ? : par->out;
- - } else {
- - const struct net_device *other_dev;
- - el_dev = skb->dev;
- - other_dev = par->in ? : par->out;
- - if (el_dev != other_dev) {
- - MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs "
- - "par->(in/out)=%p %s\n",
- - par->hooknum, el_dev, el_dev->name, other_dev,
- - other_dev->name);
- - }
- - }
- -
- - if (unlikely(!el_dev)) {
- - pr_err_ratelimited("qtaguid[%d]: %s(): no par->in/out?!!\n",
- - par->hooknum, __func__);
- - BUG();
- - } else if (unlikely(!el_dev->name)) {
- - pr_err_ratelimited("qtaguid[%d]: %s(): no dev->name?!!\n",
- - par->hooknum, __func__);
- - BUG();
- - } else {
- - proto = ipx_proto(skb, par);
- - MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
- - par->hooknum, el_dev->name, el_dev->type,
- - par->family, proto);
- - }
- + get_dev_and_dir(skb, par, &direction, &el_dev);
- + proto = ipx_proto(skb, par);
- + MT_DEBUG("qtaguid[%d]: iface_stat: %s(%s): "
- + "type=%d fam=%d proto=%d dir=%d\n",
- + par->hooknum, __func__, el_dev->name, el_dev->type,
- + par->family, proto, direction);
- spin_lock_bh(&iface_stat_list_lock);
- entry = get_iface_entry(el_dev->name);
- if (entry == NULL) {
- - IF_DEBUG("qtaguid: iface_stat: %s(%s): not tracked\n",
- - __func__, el_dev->name);
- + IF_DEBUG("qtaguid[%d]: iface_stat: %s(%s): not tracked\n",
- + par->hooknum, __func__, el_dev->name);
- spin_unlock_bh(&iface_stat_list_lock);
- return;
- }
- - IF_DEBUG("qtaguid: %s(%s): entry=%p\n", __func__,
- + IF_DEBUG("qtaguid[%d]: %s(%s): entry=%p\n", par->hooknum, __func__,
- el_dev->name, entry);
- data_counters_update(&entry->totals_via_skb, 0, direction, proto,
- @@ -1415,15 +1424,18 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
- ifname, uid, sk, direction, proto, bytes);
- + spin_lock_bh(&iface_stat_list_lock);
- iface_entry = get_iface_entry(ifname);
- if (!iface_entry) {
- - pr_err_ratelimited("qtaguid: iface_stat: stat_update() "
- + spin_unlock_bh(&iface_stat_list_lock);
- + pr_err_ratelimited("qtaguid: tag_stat: stat_update() "
- "%s not found\n", ifname);
- return;
- }
- + spin_unlock_bh(&iface_stat_list_lock);
- /* It is ok to process data when an iface_entry is inactive */
- - MT_DEBUG("qtaguid: iface_stat: stat_update() dev=%s entry=%p\n",
- + MT_DEBUG("qtaguid: tag_stat: stat_update() dev=%s entry=%p\n",
- ifname, iface_entry);
- /*
- @@ -1440,7 +1452,7 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
- tag = combine_atag_with_uid(acct_tag, uid);
- uid_tag = make_tag_from_uid(uid);
- }
- - MT_DEBUG("qtaguid: iface_stat: stat_update(): "
- + MT_DEBUG("qtaguid: tag_stat: stat_update(): "
- " looking for tag=0x%llx (uid=%u) in ife=%p\n",
- tag, get_uid_from_tag(tag), iface_entry);
- /* Loop over tag list under this interface for {acct_tag,uid_tag} */
- @@ -1673,8 +1685,8 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
- struct sock *sk;
- unsigned int hook_mask = (1 << par->hooknum);
- - MT_DEBUG("qtaguid: find_sk(skb=%p) hooknum=%d family=%d\n", skb,
- - par->hooknum, par->family);
- + MT_DEBUG("qtaguid[%d]: find_sk(skb=%p) family=%d\n",
- + par->hooknum, skb, par->family);
- /*
- * Let's not abuse the the xt_socket_get*_sk(), or else it will
- @@ -1700,8 +1712,12 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
- * Not fixed in 3.0-r3 :(
- */
- if (sk) {
- - MT_DEBUG("qtaguid: %p->sk_proto=%u "
- - "->sk_state=%d\n", sk, sk->sk_protocol, sk->sk_state);
- + MT_DEBUG("qtaguid[%d]: %p->sk_proto=%u->sk_state=%d\n",
- + par->hooknum, sk, sk->sk_protocol, sk->sk_state);
- + /*
- + * When in TCP_TIME_WAIT the sk is not a "struct sock" but
- + * "struct inet_timewait_sock" which is missing fields.
- + */
- if (sk->sk_state == TCP_TIME_WAIT) {
- xt_socket_put_sk(sk);
- sk = NULL;
- @@ -1715,37 +1731,19 @@ static void account_for_uid(const struct sk_buff *skb,
- struct xt_action_param *par)
- {
- const struct net_device *el_dev;
- + enum ifs_tx_rx direction;
- + int proto;
- - if (!skb->dev) {
- - MT_DEBUG("qtaguid[%d]: no skb->dev\n", par->hooknum);
- - el_dev = par->in ? : par->out;
- - } else {
- - const struct net_device *other_dev;
- - el_dev = skb->dev;
- - other_dev = par->in ? : par->out;
- - if (el_dev != other_dev) {
- - MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs "
- - "par->(in/out)=%p %s\n",
- - par->hooknum, el_dev, el_dev->name, other_dev,
- - other_dev->name);
- - }
- - }
- -
- - if (unlikely(!el_dev)) {
- - pr_info("qtaguid[%d]: no par->in/out?!!\n", par->hooknum);
- - } else if (unlikely(!el_dev->name)) {
- - pr_info("qtaguid[%d]: no dev->name?!!\n", par->hooknum);
- - } else {
- - int proto = ipx_proto(skb, par);
- - MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
- - par->hooknum, el_dev->name, el_dev->type,
- - par->family, proto);
- + get_dev_and_dir(skb, par, &direction, &el_dev);
- + proto = ipx_proto(skb, par);
- + MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d dir=%d\n",
- + par->hooknum, el_dev->name, el_dev->type,
- + par->family, proto, direction);
- - if_tag_stat_update(el_dev->name, uid,
- - skb->sk ? skb->sk : alternate_sk,
- - par->in ? IFS_RX : IFS_TX,
- - proto, skb->len);
- - }
- + if_tag_stat_update(el_dev->name, uid,
- + skb->sk ? skb->sk : alternate_sk,
- + direction,
- + proto, skb->len);
- }
- static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
- @@ -1756,6 +1754,11 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
- struct sock *sk;
- uid_t sock_uid;
- bool res;
- + /*
- + * TODO: unhack how to force just accounting.
- + * For now we only do tag stats when the uid-owner is not requested
- + */
- + bool do_tag_stat = !(info->match & XT_QTAGUID_UID);
- if (unlikely(module_passive))
- return (info->match ^ info->invert) == 0;
- @@ -1822,12 +1825,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
- * couldn't find the owner, so for now we just count them
- * against the system.
- */
- - /*
- - * TODO: unhack how to force just accounting.
- - * For now we only do iface stats when the uid-owner is not
- - * requested.
- - */
- - if (!(info->match & XT_QTAGUID_UID))
- + if (do_tag_stat)
- account_for_uid(skb, sk, 0, par);
- MT_DEBUG("qtaguid[%d]: leaving (sk?sk->sk_socket)=%p\n",
- par->hooknum,
- @@ -1842,18 +1840,15 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
- filp = sk->sk_socket->file;
- if (filp == NULL) {
- MT_DEBUG("qtaguid[%d]: leaving filp=NULL\n", par->hooknum);
- - account_for_uid(skb, sk, 0, par);
- + if (do_tag_stat)
- + account_for_uid(skb, sk, 0, par);
- res = ((info->match ^ info->invert) &
- (XT_QTAGUID_UID | XT_QTAGUID_GID)) == 0;
- atomic64_inc(&qtu_events.match_no_sk_file);
- goto put_sock_ret_res;
- }
- sock_uid = filp->f_cred->fsuid;
- - /*
- - * TODO: unhack how to force just accounting.
- - * For now we only do iface stats when the uid-owner is not requested
- - */
- - if (!(info->match & XT_QTAGUID_UID))
- + if (do_tag_stat)
- account_for_uid(skb, sk, sock_uid, par);
- /*
- diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
- index e56833a..e591c54 100644
- --- a/scripts/dtc/libfdt/fdt.c
- +++ b/scripts/dtc/libfdt/fdt.c
- @@ -71,6 +71,20 @@ int fdt_check_header(const void *fdt)
- return -FDT_ERR_BADMAGIC;
- }
- + if (fdt_off_dt_struct(fdt) > (UINT_MAX - fdt_size_dt_struct(fdt)))
- + return FDT_ERR_BADOFFSET;
- +
- + if (fdt_off_dt_strings(fdt) > (UINT_MAX - fdt_size_dt_strings(fdt)))
- + return FDT_ERR_BADOFFSET;
- +
- + if ((fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt))
- + > fdt_totalsize(fdt))
- + return FDT_ERR_BADOFFSET;
- +
- + if ((fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))
- + > fdt_totalsize(fdt))
- + return FDT_ERR_BADOFFSET;
- +
- return 0;
- }
- diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
- index 24437df..d7d09fe 100644
- --- a/scripts/dtc/libfdt/fdt_rw.c
- +++ b/scripts/dtc/libfdt/fdt_rw.c
- @@ -394,7 +394,7 @@ int fdt_del_node(void *fdt, int nodeoffset)
- static void _fdt_packblocks(const char *old, char *new,
- int mem_rsv_size, int struct_size)
- {
- - int mem_rsv_off, struct_off, strings_off;
- + uint32_t mem_rsv_off, struct_off, strings_off;
- mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
- struct_off = mem_rsv_off + mem_rsv_size;
- diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
- index 32e7d35..185cbf8 100644
- --- a/sound/soc/codecs/Makefile
- +++ b/sound/soc/codecs/Makefile
- @@ -55,8 +55,8 @@ snd-soc-uda1380-objs := uda1380.o
- snd-soc-wcd9304-objs := wcd9304.o wcd9304-tables.o
- snd-soc-wcd9310-objs := wcd9310.o wcd9310-tables.o
- snd-soc-cs8427-objs := cs8427.o
- -snd-soc-wcd9320-objs := wcd9xxx-resmgr.o wcd9320.o wcd9320-tables.o wcd9xxx-mbhc.o wcd9xxx-common.o
- -snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o wcd9xxx-common.o
- +snd-soc-wcd9320-objs := wcd9xxx-resmgr.o wcd9320.o wcd9320-tables.o wcd9xxx-mbhc.o wcd9xxx-common.o wcdcal-hwdep.o
- +snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o wcd9xxx-common.o wcdcal-hwdep.o
- snd-soc-msm8x10-wcd-objs := msm8x10-wcd.o msm8x10-wcd-tables.o wcd9xxx-common.o
- snd-soc-es325-objs := es325.o
- snd-soc-es325_atlantic-objs := es325_atlantic.o
- diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
- index 42c1f3b..801286a 100644
- --- a/sound/soc/codecs/msm8x10-wcd.c
- +++ b/sound/soc/codecs/msm8x10-wcd.c
- @@ -1691,20 +1691,22 @@ static int msm8x10_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- char *internal1_text = "Internal1";
- char *internal2_text = "Internal2";
- char *internal3_text = "Internal3";
- + char *external_text = "External";
- enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
- dev_dbg(codec->dev, "%s %d\n", __func__, event);
- - switch (w->reg) {
- - case MSM8X10_WCD_A_MICB_1_CTL:
- +
- + if ((strnstr(w->name, internal1_text, 30)) ||
- + (strnstr(w->name, internal2_text, 30)) ||
- + (strnstr(w->name, internal3_text, 30)) ||
- + (strnstr(w->name, external_text, 30))) {
- micb_int_reg = MSM8X10_WCD_A_MICB_1_INT_RBIAS;
- e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
- e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
- e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
- - break;
- - default:
- + } else {
- dev_err(codec->dev,
- - "%s: Error, invalid micbias register 0x%x\n",
- - __func__, w->reg);
- + "%s: Error, invalid micbias %s\n", __func__, w->name);
- return -EINVAL;
- }
- @@ -1722,9 +1724,9 @@ static int msm8x10_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- /* Always pull up TxFe for TX2 to Micbias */
- snd_soc_update_bits(codec, micb_int_reg, 0x04, 0x04);
- - snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
- + if (++msm8x10_wcd->micb_en_count == 1)
- + snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
- 0x80, 0x80);
- - msm8x10_wcd->micb_en_count++;
- pr_debug("%s micb_en_count : %d", __func__,
- msm8x10_wcd->micb_en_count);
- break;
- @@ -1734,12 +1736,11 @@ static int msm8x10_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_on);
- break;
- case SND_SOC_DAPM_POST_PMD:
- - if (msm8x10_wcd->micb_en_count > 0)
- - msm8x10_wcd->micb_en_count--;
- + if (--msm8x10_wcd->micb_en_count == 0)
- + snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
- + 0x80, 0x00);
- pr_debug("%s micb_en_count : %d", __func__,
- msm8x10_wcd->micb_en_count);
- - snd_soc_update_bits(codec, MSM8X10_WCD_A_MICB_1_CTL,
- - 0x80, 0x00);
- /* Let MBHC module know so micbias switch to be off */
- wcd9xxx_resmgr_notifier_call(&msm8x10_wcd->resmgr, e_post_off);
- @@ -2553,7 +2554,7 @@ static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("AMIC1"),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal1",
- - MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
- + SND_SOC_NOPM, 7, 0,
- msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- #if defined(CONFIG_SEC_HEAT_PROJECT) /*Remove Intenal mic bias2*/
- @@ -2563,20 +2564,20 @@ static const struct snd_soc_dapm_widget msm8x10_wcd_dapm_widgets[] = {
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- #else
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal2",
- - MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
- + SND_SOC_NOPM, 7, 0,
- msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- #endif
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS Internal3",
- - MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
- + SND_SOC_NOPM, 7, 0,
- msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E("MIC BIAS External",
- - MSM8X10_WCD_A_MICB_1_CTL, 7, 0,
- + SND_SOC_NOPM, 7, 0,
- msm8x10_wcd_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS_EXTERNAL_STANDALONE,
- - MSM8X10_WCD_A_MICB_1_CTL,
- + SND_SOC_NOPM,
- 7, 0, msm8x10_wcd_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
- @@ -2864,7 +2865,6 @@ static int msm8x10_wcd_enable_mbhc_micbias(struct snd_soc_codec *codec,
- enum wcd9xxx_micbias_num micb_num)
- {
- int rc;
- - struct msm8x10_wcd_priv *msm8x10_wcd = snd_soc_codec_get_drvdata(codec);
- if (micb_num != MBHC_MICBIAS1) {
- rc = -EINVAL;
- @@ -2875,12 +2875,6 @@ static int msm8x10_wcd_enable_mbhc_micbias(struct snd_soc_codec *codec,
- rc = snd_soc_dapm_force_enable_pin(&codec->dapm,
- DAPM_MICBIAS_EXTERNAL_STANDALONE);
- else {
- - if (msm8x10_wcd->micb_en_count > 1) {
- - msm8x10_wcd->micb_en_count--;
- - pr_debug("%s micb_en_count : %d", __func__,
- - msm8x10_wcd->micb_en_count);
- - return 0;
- - }
- rc = snd_soc_dapm_disable_pin(&codec->dapm,
- DAPM_MICBIAS_EXTERNAL_STANDALONE);
- }
- diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
- index 23d9437..2ed6479 100644
- --- a/sound/soc/codecs/wcd9306.c
- +++ b/sound/soc/codecs/wcd9306.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -42,28 +42,7 @@
- #define TAPAN_HPH_PA_SETTLE_COMP_ON 3000
- #define TAPAN_HPH_PA_SETTLE_COMP_OFF 13000
- -#if defined(CONFIG_SND_SOC_ES705)
- -#include "audience/es705-export.h"
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- -#include "es325-export.h"
- -#endif
- -
- -#if defined(CONFIG_SND_SOC_ES705)
- -#define REMOTE_ROUTE_ENABLE_CB es705_remote_route_enable
- -#define SLIM_GET_CHANNEL_MAP_CB es705_slim_get_channel_map
- -#define SLIM_SET_CHANNEL_MAP_CB es705_slim_set_channel_map
- -#define SLIM_HW_PARAMS_CB es705_slim_hw_params
- -#define REMOTE_CFG_SLIM_RX_CB es705_remote_cfg_slim_rx
- -#define REMOTE_CLOSE_SLIM_RX_CB es705_remote_close_slim_rx
- -#define REMOTE_CFG_SLIM_TX_CB es705_remote_cfg_slim_tx
- -#define REMOTE_CLOSE_SLIM_TX_CB es705_remote_close_slim_tx
- -#define REMOTE_ADD_CODEC_CONTROLS_CB es705_remote_add_codec_controls
- -#endif
- -
- -#ifndef CONFIG_ARCH_MSM8226
- #define DAPM_MICBIAS2_EXTERNAL_STANDALONE "MIC BIAS2 External Standalone"
- -#endif
- -
- #define TAPAN_VALIDATE_RX_SBPORT_RANGE(port) ((port >= 16) && (port <= 20))
- #define TAPAN_CONVERT_RX_SBPORT_ID(port) (port - 16) /* RX1 port ID = 0 */
- @@ -312,6 +291,9 @@ struct tapan_priv {
- u32 anc_slot;
- bool anc_func;
- + /*track adie loopback mode*/
- + bool lb_mode;
- +
- /*track tapan interface type*/
- u8 intf_type;
- @@ -327,6 +309,8 @@ struct tapan_priv {
- u8 aux_l_gain;
- u8 aux_r_gain;
- + bool dec_active[NUM_DECIMATORS];
- +
- bool spkr_pa_widget_on;
- struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
- @@ -339,10 +323,6 @@ struct tapan_priv {
- /* class h specific data */
- struct wcd9xxx_clsh_cdc_data clsh_d;
- - int ldo_h_count;
- - int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool);
- - int micb_2_ref_cnt;
- -
- /* pointers to regulators required for chargepump */
- struct regulator *cp_regulators[CP_REG_MAX];
- @@ -537,6 +517,43 @@ static int tapan_put_anc_func(struct snd_kcontrol *kcontrol,
- return 0;
- }
- +static int tapan_loopback_mode_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- +
- + ucontrol->value.integer.value[0] = tapan->lb_mode;
- + dev_dbg(codec->dev, "%s: lb_mode = %d\n",
- + __func__, tapan->lb_mode);
- +
- + return 0;
- +}
- +
- +static int tapan_loopback_mode_put(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- +
- + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
- + __func__, ucontrol->value.integer.value[0]);
- +
- + switch (ucontrol->value.integer.value[0]) {
- + case 0:
- + tapan->lb_mode = false;
- + break;
- + case 1:
- + tapan->lb_mode = true;
- + break;
- + default:
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +
- static int tapan_pa_gain_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- @@ -1061,6 +1078,13 @@ static int tapan_config_compander(struct snd_soc_dapm_widget *w,
- return 0;
- }
- +static const char * const tapan_loopback_mode_ctrl_text[] = {
- + "DISABLE", "ENABLE"};
- +static const struct soc_enum tapan_loopback_mode_ctl_enum[] = {
- + SOC_ENUM_SINGLE_EXT(2, tapan_loopback_mode_ctrl_text),
- +};
- +
- +
- static const char * const tapan_ear_pa_gain_text[] = {"POS_6_DB", "POS_4P5_DB",
- "POS_3_DB", "POS_1P5_DB",
- "POS_0_DB", "NEG_2P5_DB",
- @@ -1113,11 +1137,33 @@ static const struct soc_enum class_h_dsm_enum =
- static const struct snd_kcontrol_new class_h_dsm_mux =
- SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
- +static int tapan_hph_impedance_get(struct snd_kcontrol *kcontrol,
- + struct snd_ctl_elem_value *ucontrol)
- +{
- + uint32_t zl, zr;
- + bool hphr;
- + struct soc_multi_mixer_control *mc;
- + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- + struct tapan_priv *priv = snd_soc_codec_get_drvdata(codec);
- +
- + mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
- +
- + hphr = mc->shift;
- + wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
- + pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
- + ucontrol->value.integer.value[0] = hphr ? zr : zl;
- +
- + return 0;
- +}
- +
- static const struct snd_kcontrol_new tapan_common_snd_controls[] = {
- SOC_ENUM_EXT("EAR PA Gain", tapan_ear_pa_gain_enum[0],
- tapan_pa_gain_get, tapan_pa_gain_put),
- + SOC_ENUM_EXT("LOOPBACK Mode", tapan_loopback_mode_ctl_enum[0],
- + tapan_loopback_mode_get, tapan_loopback_mode_put),
- +
- SOC_SINGLE_TLV("HPHL Volume", TAPAN_A_RX_HPH_L_GAIN, 0, 20, 1,
- line_gain),
- SOC_SINGLE_TLV("HPHR Volume", TAPAN_A_RX_HPH_R_GAIN, 0, 20, 1,
- @@ -1223,6 +1269,11 @@ static const struct snd_kcontrol_new tapan_common_snd_controls[] = {
- tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
- SOC_SINGLE_MULTI_EXT("IIR2 Band5", IIR2, BAND5, 255, 0, 5,
- tapan_get_iir_band_audio_mixer, tapan_put_iir_band_audio_mixer),
- +
- + SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
- + tapan_hph_impedance_get, NULL),
- + SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
- + tapan_hph_impedance_get, NULL),
- };
- static const struct snd_kcontrol_new tapan_9306_snd_controls[] = {
- @@ -2035,15 +2086,20 @@ static int tapan_codec_enable_lineout(struct snd_soc_dapm_widget *w,
- WCD9XXX_CLSH_STATE_LO,
- WCD9XXX_CLSH_REQ_ENABLE,
- WCD9XXX_CLSH_EVENT_POST_PA);
- - dev_dbg(codec->dev, "%s: sleeping 3 ms after %s PA turn on\n",
- + dev_dbg(codec->dev, "%s: sleeping 5 ms after %s PA turn on\n",
- __func__, w->name);
- - usleep_range(3000, 3010);
- + /* Wait for CnP time after PA enable */
- + usleep_range(5000, 5100);
- break;
- case SND_SOC_DAPM_POST_PMD:
- wcd9xxx_clsh_fsm(codec, &tapan->clsh_d,
- WCD9XXX_CLSH_STATE_LO,
- WCD9XXX_CLSH_REQ_DISABLE,
- WCD9XXX_CLSH_EVENT_POST_PA);
- + dev_dbg(codec->dev, "%s: sleeping 5 ms after %s PA turn on\n",
- + __func__, w->name);
- + /* Wait for CnP time after PA disable */
- + usleep_range(5000, 5100);
- break;
- }
- return 0;
- @@ -2250,40 +2306,36 @@ static int tapan_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- {
- struct snd_soc_codec *codec = w->codec;
- struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- - u16 micb_int_reg, micb_ctl_reg;
- + u16 micb_int_reg = 0, micb_ctl_reg = 0;
- u8 cfilt_sel_val = 0;
- char *internal1_text = "Internal1";
- char *internal2_text = "Internal2";
- char *internal3_text = "Internal3";
- enum wcd9xxx_notify_event e_post_off, e_pre_on, e_post_on;
- - dev_dbg(codec->dev, "%s %d, shift = %d\n", __func__, event, w->shift);
- - switch (w->shift) {
- - case 1:
- + pr_debug("%s: w->name %s event %d\n", __func__, w->name, event);
- + if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) {
- micb_ctl_reg = TAPAN_A_MICB_1_CTL;
- micb_int_reg = TAPAN_A_MICB_1_INT_RBIAS;
- cfilt_sel_val = tapan->resmgr.pdata->micbias.bias1_cfilt_sel;
- e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_1_ON;
- e_post_on = WCD9XXX_EVENT_POST_MICBIAS_1_ON;
- e_post_off = WCD9XXX_EVENT_POST_MICBIAS_1_OFF;
- - break;
- - case 2:
- + } else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) {
- micb_ctl_reg = TAPAN_A_MICB_2_CTL;
- micb_int_reg = TAPAN_A_MICB_2_INT_RBIAS;
- cfilt_sel_val = tapan->resmgr.pdata->micbias.bias2_cfilt_sel;
- e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_2_ON;
- e_post_on = WCD9XXX_EVENT_POST_MICBIAS_2_ON;
- e_post_off = WCD9XXX_EVENT_POST_MICBIAS_2_OFF;
- - break;
- - case 3:
- + } else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) {
- micb_ctl_reg = TAPAN_A_MICB_3_CTL;
- micb_int_reg = TAPAN_A_MICB_3_INT_RBIAS;
- cfilt_sel_val = tapan->resmgr.pdata->micbias.bias3_cfilt_sel;
- e_pre_on = WCD9XXX_EVENT_PRE_MICBIAS_3_ON;
- e_post_on = WCD9XXX_EVENT_POST_MICBIAS_3_ON;
- e_post_off = WCD9XXX_EVENT_POST_MICBIAS_3_OFF;
- - break;
- - default:
- + } else {
- pr_err("%s: Error, invalid micbias %s\n", __func__, w->name);
- return -EINVAL;
- }
- @@ -2319,33 +2371,27 @@ static int tapan_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- break;
- case SND_SOC_DAPM_POST_PMU:
- - if (w->shift ==2) {
- - if (++tapan->micb_2_ref_cnt == 1) {
- - snd_soc_update_bits(codec, micb_ctl_reg, 0x80, 0x80);
- - usleep_range(20000, 20000);
- - } else {
- - dev_dbg(codec->dev, "MIC BIAS2 already enabled, ref_count = %d",
- - tapan->micb_2_ref_cnt);
- - }
- - } else {
- - snd_soc_update_bits(codec, micb_ctl_reg, 0x80, 0x80);
- - usleep_range(20000, 20000);
- - }
- + usleep_range(20000, 20000);
- /* Let MBHC module know so micbias is on */
- wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_on);
- break;
- case SND_SOC_DAPM_POST_PMD:
- - if (w->shift ==2) {
- - if (--tapan->micb_2_ref_cnt <= 0) {
- - snd_soc_update_bits(codec, micb_ctl_reg, 0x80, 0x00);
- - tapan->micb_2_ref_cnt = 0;
- - dev_dbg(codec->dev, "MIC BIAS2 disabled\n");
- - } else {
- - dev_dbg(codec->dev, "micbias2 is still needed, do not turn off\n");
- - }
- - } else {
- - snd_soc_update_bits(codec, micb_ctl_reg, 0x80, 0x00);
- - }
- + if (micb_ctl_reg == TAPAN_A_MICB_2_CTL) {
- + if (--tapan->micb_2_users == 0)
- + wcd9xxx_resmgr_rm_cond_update_bits(
- + &tapan->resmgr,
- + WCD9XXX_COND_HPH_MIC,
- + micb_ctl_reg, 7,
- + false);
- + pr_debug("%s: micb_2_users %d\n", __func__,
- + tapan->micb_2_users);
- + WARN(tapan->micb_2_users < 0,
- + "Unexpected micbias users %d\n",
- + tapan->micb_2_users);
- + } else
- + snd_soc_update_bits(codec, micb_ctl_reg, 1 << w->shift,
- + 0);
- +
- /* Let MBHC module know so micbias switch to be off */
- wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_off);
- @@ -2364,7 +2410,6 @@ static int tapan_codec_enable_micbias(struct snd_soc_dapm_widget *w,
- return 0;
- }
- -#ifndef CONFIG_ARCH_MSM8226
- /* called under codec_resource_lock acquisition */
- static int tapan_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
- enum wcd9xxx_micbias_num micb_num)
- @@ -2388,7 +2433,6 @@ static int tapan_enable_mbhc_micbias(struct snd_soc_codec *codec, bool enable,
- pr_debug("%s: leave ret %d\n", __func__, rc);
- return rc;
- }
- -#endif
- static void tx_hpf_corner_freq_callback(struct work_struct *work)
- {
- @@ -2425,10 +2469,11 @@ static int tapan_codec_enable_dec(struct snd_soc_dapm_widget *w,
- {
- struct snd_soc_codec *codec = w->codec;
- unsigned int decimator;
- + struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
- char *dec_name = NULL;
- char *widget_name = NULL;
- char *temp;
- - int ret = 0;
- + int ret = 0, i;
- u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
- u8 dec_hpf_cut_of_freq;
- int offset;
- @@ -2480,6 +2525,10 @@ static int tapan_codec_enable_dec(struct snd_soc_dapm_widget *w,
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- + for (i = 0; i < NUM_DECIMATORS; i++) {
- + if (decimator == i + 1)
- + tapan_p->dec_active[i] = true;
- + }
- /* Enableable TX digital mute */
- snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x01);
- @@ -2510,8 +2559,11 @@ static int tapan_codec_enable_dec(struct snd_soc_dapm_widget *w,
- case SND_SOC_DAPM_POST_PMU:
- - /* Disable TX digital mute */
- - snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
- + if (tapan_p->lb_mode) {
- + pr_debug("%s: loopback mode unmute the DEC\n",
- + __func__);
- + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, 0x00);
- + }
- if (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq !=
- CF_MIN_3DB_150HZ) {
- @@ -2540,7 +2592,10 @@ static int tapan_codec_enable_dec(struct snd_soc_dapm_widget *w,
- snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x08, 0x08);
- snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x30,
- (tx_hpf_work[decimator - 1].tx_hpf_cut_of_freq) << 4);
- -
- + for (i = 0; i < NUM_DECIMATORS; i++) {
- + if (decimator == i + 1)
- + tapan_p->dec_active[i] = false;
- + }
- break;
- }
- out:
- @@ -2634,7 +2689,6 @@ static int tapan_codec_enable_interpolator(struct snd_soc_dapm_widget *w,
- return 0;
- }
- -#ifndef CONFIG_ARCH_MSM8226
- /* called under codec_resource_lock acquisition */
- static int __tapan_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
- @@ -2688,97 +2742,13 @@ static int __tapan_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
- pr_debug("%s: leave\n", __func__);
- return 0;
- }
- -#endif
- -void tapan_register_mclk_cb(struct snd_soc_codec *codec,
- - int (*mclk_cb_fn) (struct snd_soc_codec*, int, bool))
- -{
- - struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- - tapan->mclk_cb_fn = mclk_cb_fn;
- -}
- -
- -static void tapan_enable_ldo_h(struct snd_soc_codec *codec, u32 enable)
- -{
- - struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- -
- - if (enable) {
- - if (++tapan->ldo_h_count == 1)
- - snd_soc_update_bits(codec, TAPAN_A_LDO_H_MODE_1,
- - 0x80, 0x80);
- - } else {
- - if (--tapan->ldo_h_count <= 0) {
- - snd_soc_update_bits(codec, TAPAN_A_LDO_H_MODE_1,
- - 0x80, 0x00);
- - tapan->ldo_h_count = 0;
- - }
- - }
- -}
- -
- -static int tapan_codec_enable_micbias_power(struct snd_soc_dapm_widget *w,
- - struct snd_kcontrol *kcontrol,
- - int event)
- -{
- - struct snd_soc_codec *codec = w->codec;
- - struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- -
- - pr_debug("%s %d\n", __func__, event);
- -
- - if (!tapan->mclk_cb_fn) {
- - pr_err("%s: Callback to enable mclk is not registered\n",
- - __func__);
- - return -EINVAL;
- - }
- -
- - switch (event) {
- - case SND_SOC_DAPM_PRE_PMU:
- - tapan->mclk_cb_fn(codec, 1, true);
- - WCD9XXX_BCL_LOCK(&tapan->resmgr);
- - WCD9XXX_BG_CLK_LOCK(&tapan->resmgr);
- - wcd9xxx_resmgr_get_bandgap(&tapan->resmgr,
- - WCD9XXX_BANDGAP_AUDIO_MODE);
- - WCD9XXX_BG_CLK_UNLOCK(&tapan->resmgr);
- - WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
- - tapan_enable_ldo_h(codec, 1);
- - tapan_codec_enable_micbias(w, kcontrol, event);
- - break;
- - case SND_SOC_DAPM_POST_PMU:
- - tapan_codec_enable_micbias(w, kcontrol, event);
- - tapan->mclk_cb_fn(codec, 0, true);
- - break;
- - case SND_SOC_DAPM_POST_PMD:
- - tapan_codec_enable_micbias(w, kcontrol, event);
- - tapan_enable_ldo_h(codec, 0);
- - WCD9XXX_BCL_LOCK(&tapan->resmgr);
- - WCD9XXX_BG_CLK_LOCK(&tapan->resmgr);
- - wcd9xxx_resmgr_put_bandgap(&tapan->resmgr,
- - WCD9XXX_BANDGAP_AUDIO_MODE);
- - WCD9XXX_BG_CLK_UNLOCK(&tapan->resmgr);
- - WCD9XXX_BCL_UNLOCK(&tapan->resmgr);
- - break;
- - }
- - return 0;
- -}
- static int tapan_codec_enable_ldo_h(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
- {
- -#ifndef CONFIG_ARCH_MSM8226
- int rc;
- rc = __tapan_codec_enable_ldo_h(w, kcontrol, event);
- return rc;
- -#else
- - struct snd_soc_codec *codec = w->codec;
- - switch (event) {
- - case SND_SOC_DAPM_POST_PMU:
- - tapan_enable_ldo_h(codec, 1);
- - usleep_range(1000, 1000);
- - break;
- - case SND_SOC_DAPM_POST_PMD:
- - tapan_enable_ldo_h(codec, 0);
- - usleep_range(1000, 1000);
- - break;
- - }
- - return 0;
- -#endif
- }
- static int tapan_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
- @@ -2882,10 +2852,6 @@ static int tapan_hph_pa_event(struct snd_soc_dapm_widget *w,
- case SND_SOC_DAPM_PRE_PMU:
- /* Let MBHC module know PA is turning on */
- wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_pre_on);
- -#if defined(CONFIG_MACH_ATLANTICLTE_ATT) || defined(CONFIG_MACH_ATLANTICLTE_USC)
- - snd_soc_write(codec,TAPAN_A_CDC_CLSH_V_PA_HD_HPH,0x19);
- - snd_soc_write(codec,TAPAN_A_CDC_CLSH_V_PA_MIN_HPH, 0x26);
- -#endif
- break;
- case SND_SOC_DAPM_POST_PMU:
- dev_dbg(codec->dev, "%s: sleep %d ms after %s PA enable.\n",
- @@ -2912,10 +2878,6 @@ static int tapan_hph_pa_event(struct snd_soc_dapm_widget *w,
- req_clsh_state,
- WCD9XXX_CLSH_REQ_DISABLE,
- WCD9XXX_CLSH_EVENT_POST_PA);
- -#if defined(CONFIG_MACH_ATLANTICLTE_ATT) || defined(CONFIG_MACH_ATLANTICLTE_USC)
- - snd_soc_write(codec,TAPAN_A_CDC_CLSH_V_PA_HD_HPH,0x00);
- - snd_soc_write(codec,TAPAN_A_CDC_CLSH_V_PA_MIN_HPH, 0x00);
- -#endif
- break;
- }
- return 0;
- @@ -3366,9 +3328,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
- {"MIC BIAS2 Internal2", NULL, "LDO_H"},
- {"MIC BIAS2 Internal3", NULL, "LDO_H"},
- {"MIC BIAS2 External", NULL, "LDO_H"},
- -#ifndef CONFIG_ARCH_MSM8226
- {DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
- -#endif
- /*sidetone path enable*/
- {"IIR1", NULL, "IIR1 INP1 MUX"},
- @@ -3588,8 +3548,6 @@ static unsigned int tapan_read(struct snd_soc_codec *codec,
- return val;
- }
- -#ifdef CONFIG_SND_SOC_ES325_ATLANTIC
- -
- static int tapan_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- @@ -3600,25 +3558,10 @@ static int tapan_startup(struct snd_pcm_substream *substream,
- (tapan_core->dev != NULL) &&
- (tapan_core->dev->parent != NULL))
- pm_runtime_get_sync(tapan_core->dev->parent);
- - es325_wrapper_wakeup(dai);
- return 0;
- }
- -#else
- -static int tapan_startup(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - struct wcd9xxx *tapan_core = dev_get_drvdata(dai->codec->dev->parent);
- - dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n",
- - __func__, substream->name, substream->stream);
- - if ((tapan_core != NULL) &&
- - (tapan_core->dev != NULL) &&
- - (tapan_core->dev->parent != NULL))
- - pm_runtime_get_sync(tapan_core->dev->parent);
- - return 0;
- -}
- -#endif
- static void tapan_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- @@ -3637,13 +3580,6 @@ static void tapan_shutdown(struct snd_pcm_substream *substream,
- tapan->dai[dai->id].ch_mask);
- }
- }
- -#ifdef CONFIG_SND_SOC_ES325_ATLANTIC
- - if ((tapan_core != NULL) &&
- - (tapan_core->dev != NULL) &&
- - (tapan_core->dev->parent != NULL)) {
- - es325_wrapper_sleep(dai->id);
- - }
- -#endif
- if ((tapan_core != NULL) &&
- (tapan_core->dev != NULL) &&
- (tapan_core->dev->parent != NULL) &&
- @@ -4160,239 +4096,63 @@ static int tapan_hw_params(struct snd_pcm_substream *substream,
- return 0;
- }
- -#if defined(CONFIG_SND_SOC_ES705)
- -int (*remote_route_enable)(struct snd_soc_dai *dai) = REMOTE_ROUTE_ENABLE_CB;
- -int (*slim_get_channel_map)(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- - = SLIM_GET_CHANNEL_MAP_CB;
- -int (*slim_set_channel_map)(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- - = SLIM_SET_CHANNEL_MAP_CB;
- -int (*slim_hw_params)(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- - = SLIM_HW_PARAMS_CB;
- -int (*remote_cfg_slim_rx)(int dai_id) = REMOTE_CFG_SLIM_RX_CB;
- -int (*remote_close_slim_rx)(int dai_id) = REMOTE_CLOSE_SLIM_RX_CB;
- -int (*remote_cfg_slim_tx)(int dai_id) = REMOTE_CFG_SLIM_TX_CB;
- -int (*remote_close_slim_tx)(int dai_id) = REMOTE_CLOSE_SLIM_TX_CB;
- -int (*remote_add_codec_controls)(struct snd_soc_codec *codec)
- - = REMOTE_ADD_CODEC_CONTROLS_CB;
- -
- -static int tapan_esxxx_startup(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - tapan_startup(substream, dai);
- -/*
- - if (es705_remote_route_enable(dai))
- - es705_slim_startup(substream, dai);
- -*/
- -
- - return 0;
- -}
- -
- -static void tapan_esxxx_shutdown(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - tapan_shutdown(substream, dai);
- -
- -/*
- - if (es705_remote_route_enable(dai))
- - es705_slim_shutdown(substream, dai);
- -*/
- -}
- -
- -static int tapan_esxxx_hw_params(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- +int tapan_digital_mute(struct snd_soc_dai *dai, int mute)
- {
- - int rc = 0;
- - pr_info("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- - dai->name, dai->id, params_rate(params),
- - params_channels(params));
- -
- - rc = tapan_hw_params(substream, params, dai);
- + struct snd_soc_codec *codec = NULL;
- + u16 tx_vol_ctl_reg = 0;
- + u8 decimator = 0, i;
- + struct tapan_priv *tapan_p;
- - if (remote_route_enable(dai))
- - rc = slim_hw_params(substream, params, dai);
- + pr_debug("%s: Digital Mute val = %d\n", __func__, mute);
- - return rc;
- -}
- -static int tapan_esxxx_set_channel_map(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- -
- -{
- - unsigned int tapan_tx_num = 0;
- - unsigned int tapan_tx_slot[6];
- - unsigned int tapan_rx_num = 0;
- - unsigned int tapan_rx_slot[6];
- - int rc = 0;
- - pr_info("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n",
- - __func__, dai->name, dai->id, tx_num, rx_num);
- -
- - if (remote_route_enable(dai)) {
- - rc = tapan_get_channel_map(dai, &tapan_tx_num, tapan_tx_slot,
- - &tapan_rx_num, tapan_rx_slot);
- -
- - rc = tapan_set_channel_map(dai, tx_num, tapan_tx_slot, rx_num, tapan_rx_slot);
- -
- - rc = slim_set_channel_map(dai, tx_num, tx_slot, rx_num,
- - rx_slot);
- - } else
- - rc = tapan_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -
- -static int tapan_esxxx_get_channel_map(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- -
- -{
- - int rc = 0;
- -
- - pr_info("%s(): dai_name = %s DAI-ID %d tx_ch %d rx_ch %d\n",
- - __func__, dai->name, dai->id, *tx_num, *rx_num);
- -
- - if (remote_route_enable(dai))
- - rc = slim_get_channel_map(dai, tx_num, tx_slot, rx_num,
- - rx_slot);
- - else
- - rc = tapan_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -static struct snd_soc_dai_ops tapan_dai_ops = {
- - .startup = tapan_esxxx_startup, /* tapan_startup, */
- - .shutdown = tapan_esxxx_shutdown, /* tapan_shutdown, */
- - .hw_params = tapan_esxxx_hw_params, /* tapan_hw_params, */
- - .set_sysclk = tapan_set_dai_sysclk,
- - .set_fmt = tapan_set_dai_fmt,
- - .set_channel_map = tapan_esxxx_set_channel_map,
- - /* tapan_set_channel_map, */
- - .get_channel_map = tapan_esxxx_get_channel_map,
- - /* tapan_get_channel_map, */
- -};
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- -static int tapan_es325_hw_params(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- -{
- - int rc = 0;
- - dev_err(dai->dev,"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- - dai->name, dai->id, params_rate(params),
- - params_channels(params));
- -
- - rc = tapan_hw_params(substream, params, dai);
- -
- - if (es325_remote_route_enable(dai))
- - rc = es325_slim_hw_params(substream, params, dai);
- -
- - return rc;
- -}
- -
- -#define SLIM_BUGFIX
- -static int tapan_es325_set_channel_map(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- -
- -{
- -#if !defined(SLIM_BUGFIX)
- - unsigned int tapan_tx_num = 0;
- -#endif
- -#if !defined(SLIM_BUGFIX)
- - unsigned int tapan_rx_num = 0;
- -#endif
- -
- -#if defined(SLIM_BUGFIX)
- - unsigned int temp_tx_num = 0;
- - unsigned int temp_rx_num = 0;
- -#endif
- - int rc = 0;
- -
- - if (es325_remote_route_enable(dai)) {
- - unsigned int tapan_tx_slot[6];
- - unsigned int tapan_rx_slot[6];
- -#if defined(SLIM_BUGFIX)
- - rc = tapan_get_channel_map(dai, &temp_tx_num, tapan_tx_slot,
- - &temp_rx_num, tapan_rx_slot);
- - if (rc < 0 )
- - pr_err ("error statement");
- - goto out;
- -
- -#else
- - rc = tapan_get_channel_map(dai, &tapan_tx_num, tapan_tx_slot,
- - &tapan_rx_num, tapan_rx_slot);
- - if (rc < 0 )
- - pr_err ("error statement");
- - goto out;
- -
- -#endif
- -
- - rc = tapan_set_channel_map(dai, tx_num, tapan_tx_slot, rx_num, tapan_rx_slot);
- - if (rc < 0 )
- - pr_err ("error statement");
- - goto out;
- -
- - rc = es325_slim_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- - if (rc < 0 )
- - pr_err ("error statement");
- - goto out;
- -
- -
- - } else
- - rc = tapan_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- - if (rc < 0 )
- - pr_err ("error statement");
- - goto out;
- -
- -out:
- - return rc;
- -}
- -static int tapan_es325_get_channel_map(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- + if (!dai || !dai->codec) {
- + pr_err("%s: Invalid params\n", __func__);
- + return -EINVAL;
- + }
- + codec = dai->codec;
- + tapan_p = snd_soc_codec_get_drvdata(codec);
- -{
- - int rc = 0;
- + if (dai->id != AIF1_CAP) {
- + dev_dbg(codec->dev, "%s: Not capture use case skip\n",
- + __func__);
- + return 0;
- + }
- - if (es325_remote_route_enable(dai))
- - rc = es325_slim_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- - else
- - rc = tapan_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- + mute = (mute) ? 1 : 0;
- + if (!mute) {
- + /*
- + * 5 ms is an emperical value for the mute time
- + * that was arrived by checking the pop level
- + * to be inaudible
- + */
- + usleep_range(5000, 5010);
- + }
- - return rc;
- + for (i = 0; i < NUM_DECIMATORS; i++) {
- + if (tapan_p->dec_active[i])
- + decimator = i + 1;
- + if (decimator && decimator <= NUM_DECIMATORS) {
- + pr_debug("%s: Mute = %d Decimator = %d", __func__,
- + mute, decimator);
- + tx_vol_ctl_reg = TAPAN_A_CDC_TX1_VOL_CTL_CFG +
- + 8 * (decimator - 1);
- + snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x01, mute);
- + }
- + decimator = 0;
- + }
- + return 0;
- }
- static struct snd_soc_dai_ops tapan_dai_ops = {
- .startup = tapan_startup,
- .shutdown = tapan_shutdown,
- - .hw_params = tapan_es325_hw_params, /* tabla_hw_params, */
- - .set_sysclk = tapan_set_dai_sysclk,
- - .set_fmt = tapan_set_dai_fmt,
- - .set_channel_map = tapan_set_channel_map, /* tabla_set_channel_map, */
- - .get_channel_map = tapan_es325_get_channel_map, /* tabla_get_channel_map, */
- -};
- -static struct snd_soc_dai_ops tapan_es325_dai_ops = {
- - .startup = tapan_startup,
- - .hw_params = tapan_es325_hw_params,
- - .set_channel_map = tapan_es325_set_channel_map,
- - .get_channel_map = tapan_es325_get_channel_map,
- -};
- -#else
- -static struct snd_soc_dai_ops tapan_dai_ops = {
- - .startup = tapan_startup,
- - .shutdown = tapan_shutdown,
- .hw_params = tapan_hw_params,
- .set_sysclk = tapan_set_dai_sysclk,
- .set_fmt = tapan_set_dai_fmt,
- .set_channel_map = tapan_set_channel_map,
- .get_channel_map = tapan_get_channel_map,
- + .digital_mute = tapan_digital_mute,
- };
- -#endif
- static struct snd_soc_dai_driver tapan9302_dai[] = {
- {
- @@ -4479,50 +4239,6 @@ static struct snd_soc_dai_driver tapan9302_dai[] = {
- },
- .ops = &tapan_dai_ops,
- },
- -#ifdef CONFIG_SND_SOC_ES325_ATLANTIC
- - {
- - .name = "tapan_es325_rx1",
- - .id = AIF1_PB + ES325_DAI_ID_OFFSET,
- - .playback = {
- - .stream_name = "AIF1 Playback",
- - .rates = WCD9306_RATES,
- - .formats = TAPAN_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &tapan_es325_dai_ops,
- - },
- - {
- - .name = "tapan_es325_tx1",
- - .id = AIF1_CAP + ES325_DAI_ID_OFFSET,
- - .capture = {
- - .stream_name = "AIF1 Capture",
- - .rates = WCD9306_RATES,
- - .formats = TAPAN_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &tapan_es325_dai_ops,
- - },
- - {
- - .name = "tapan_es325_rx2",
- - .id = AIF2_PB + ES325_DAI_ID_OFFSET,
- - .playback = {
- - .stream_name = "AIF2 Playback",
- - .rates = WCD9306_RATES,
- - .formats = TAPAN_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &tapan_es325_dai_ops,
- - },
- -#endif
- };
- static struct snd_soc_dai_driver tapan_dai[] = {
- @@ -4710,21 +4426,11 @@ static int tapan_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
- case SND_SOC_DAPM_POST_PMU:
- dai->bus_down_in_recovery = false;
- (void) tapan_codec_enable_slim_chmask(dai, true);
- -#if defined(CONFIG_SND_SOC_ES705)
- - ret = remote_cfg_slim_rx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- - ret = es325_remote_cfg_slim_rx(w->shift);
- -#endif
- ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
- dai->rate, dai->bit_width,
- &dai->grph);
- break;
- case SND_SOC_DAPM_POST_PMD:
- -#if defined(CONFIG_SND_SOC_ES705)
- - ret = remote_close_slim_rx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- - ret = es325_remote_close_slim_rx(w->shift);
- -#endif
- ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
- dai->grph);
- if (!dai->bus_down_in_recovery)
- @@ -4756,14 +4462,11 @@ static int tapan_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
- struct wcd9xxx *core;
- struct snd_soc_codec *codec = w->codec;
- struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
- - int ret = 0;
- + u32 ret = 0;
- struct wcd9xxx_codec_dai_data *dai;
- core = dev_get_drvdata(codec->dev->parent);
- - if (!core) {
- - dev_err(codec->dev,"core is NULL\n");
- - return -ENOMEM;
- - }
- +
- dev_dbg(codec->dev, "%s: event called! codec name %s\n",
- __func__, w->codec->name);
- dev_dbg(codec->dev, "%s: num_dai %d stream name %s\n",
- @@ -4783,18 +4486,8 @@ static int tapan_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
- ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
- dai->rate, dai->bit_width,
- &dai->grph);
- -#if defined(CONFIG_SND_SOC_ES705)
- - ret = remote_cfg_slim_tx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- - ret = es325_remote_cfg_slim_tx(w->shift);
- -#endif
- break;
- case SND_SOC_DAPM_POST_PMD:
- -#if defined(CONFIG_SND_SOC_ES705)
- - ret = remote_close_slim_tx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- - ret = es325_remote_close_slim_tx(w->shift);
- -#endif
- ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
- dai->grph);
- if (!dai->bus_down_in_recovery)
- @@ -5013,7 +4706,6 @@ static int tapan_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
- return 0;
- }
- -
- static const struct snd_soc_dapm_widget tapan_9306_dapm_widgets[] = {
- /* RX4 MIX1 mux inputs */
- SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
- @@ -5078,13 +4770,13 @@ static const struct snd_soc_dapm_widget tapan_9306_dapm_widgets[] = {
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 3, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 3, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 3, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- @@ -5309,11 +5001,10 @@ static const struct snd_soc_dapm_widget tapan_common_dapm_widgets[] = {
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_SUPPLY("LDO_H", SND_SOC_NOPM, 0, 0,
- - tapan_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_POST_PMD),
- + SND_SOC_DAPM_SUPPLY("LDO_H", SND_SOC_NOPM, 7, 0,
- + tapan_codec_enable_ldo_h,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- -#ifndef CONFIG_ARCH_MSM8226
- /*
- * DAPM 'LDO_H Standalone' is to be powered by mbhc driver after
- * acquring codec_resource lock.
- @@ -5322,24 +5013,18 @@ static const struct snd_soc_dapm_widget tapan_common_dapm_widgets[] = {
- SND_SOC_DAPM_SUPPLY("LDO_H Standalone", SND_SOC_NOPM, 7, 0,
- __tapan_codec_enable_ldo_h,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- -#endif
- +
- SND_SOC_DAPM_INPUT("AMIC1"),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 1, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 1, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 1, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Power External",
- - SND_SOC_NOPM, 2, 0,
- - tapan_codec_enable_micbias_power,
- - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_POST_PMD),
- -
- SND_SOC_DAPM_ADC_E("ADC1", NULL, TAPAN_A_TX_1_EN, 7, 0,
- tapan_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- @@ -5358,24 +5043,24 @@ static const struct snd_soc_dapm_widget tapan_common_dapm_widgets[] = {
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_INPUT("AMIC2"),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 2, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 2, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 2, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 2, 0,
- + SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", SND_SOC_NOPM, 7, 0,
- tapan_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- -#ifndef CONFIG_ARCH_MSM8226
- +
- SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_EXTERNAL_STANDALONE, SND_SOC_NOPM,
- 7, 0, tapan_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
- -#endif
- +
- SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
- AIF1_CAP, 0, tapan_codec_enable_slimtx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- @@ -5398,10 +5083,12 @@ static const struct snd_soc_dapm_widget tapan_common_dapm_widgets[] = {
- SND_SOC_DAPM_POST_PMD),
- /* Sidetone */
- - //SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
- - SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAPAN_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,&iir1_inp1_mux, tapan_codec_iir_mux_event,SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - //SND_SOC_DAPM_PGA("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
- - SND_SOC_DAPM_PGA_E("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0,tapan_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAPAN_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
- + &iir1_inp1_mux, tapan_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_PGA_E("IIR1", TAPAN_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
- + tapan_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_MUX_E("IIR1 INP2 MUX", TAPAN_A_CDC_IIR1_GAIN_B2_CTL, 0, 0,
- &iir1_inp2_mux, tapan_codec_iir_mux_event,
- @@ -5545,10 +5232,10 @@ static int tapan_handle_pdata(struct tapan_priv *tapan)
- rc = -ENODEV;
- goto done;
- }
- -
- txfe_bypass = pdata->amic_settings.txfe_enable;
- txfe_buff = pdata->amic_settings.txfe_buff;
- flag = pdata->amic_settings.use_pdata;
- +
- /* Make sure settings are correct */
- if ((pdata->micbias.ldoh_v > WCD9XXX_LDOH_3P0_V) ||
- (pdata->micbias.bias1_cfilt_sel > WCD9XXX_CFILT3_SEL) ||
- @@ -5765,13 +5452,7 @@ static const struct tapan_reg_mask_val tapan_reg_defaults[] = {
- /*Reduce EAR DAC bias to 70% */
- TAPAN_REG_VAL(TAPAN_A_RX_EAR_BIAS_PA, 0x76),
- /* Reduce LINE DAC bias to 70% */
- -#if defined(CONFIG_SEC_MATISSE_PROJECT) || defined(CONFIG_SEC_T10_PROJECT)
- TAPAN_REG_VAL(TAPAN_A_RX_LINE_BIAS_PA, 0x78),
- -#elif defined(CONFIG_MACH_MS01_EUR_3G)
- - TAPAN_REG_VAL(TAPAN_A_RX_LINE_BIAS_PA, 0x7A),
- -#else
- - TAPAN_REG_VAL(TAPAN_A_RX_LINE_BIAS_PA, 0x7B),
- -#endif
- /*
- * There is a diode to pull down the micbias while doing
- @@ -5805,8 +5486,8 @@ static const struct tapan_reg_mask_val tapan_2_x_reg_reset_values[] = {
- TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_B3_CTL, 0x00),
- TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_BUCK_NCP_VARS, 0x00),
- TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_HD_EAR, 0x00),
- - TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_MIN_EAR, 0x00),
- TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_HD_HPH, 0x00),
- + TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_MIN_EAR, 0x00),
- TAPAN_REG_VAL(TAPAN_A_CDC_CLSH_V_PA_MIN_HPH, 0x00),
- };
- @@ -5865,11 +5546,7 @@ static const struct tapan_reg_mask_val tapan_codec_reg_init_val[] = {
- /* Initialize current threshold to 365MA
- * number of wait and run cycles to 4096
- */
- -#if defined (CONFIG_MACH_MILLETLTE_KOR)
- - {TAPAN_A_RX_HPH_OCP_CTL, 0xEB, 0x6B},
- -#else
- {TAPAN_A_RX_HPH_OCP_CTL, 0xE9, 0x69},
- -#endif
- {TAPAN_A_RX_COM_OCP_COUNT, 0xFF, 0xFF},
- {TAPAN_A_RX_HPH_L_TEST, 0x01, 0x01},
- {TAPAN_A_RX_HPH_R_TEST, 0x01, 0x01},
- @@ -5928,24 +5605,6 @@ static const struct tapan_reg_mask_val tapan_codec_reg_init_val[] = {
- {TAPAN_A_RX_HPH_CHOP_CTL, 0xFF, 0x24},
- };
- -#if defined (CONFIG_MACH_RUBENSLTE_OPEN)
- -static const struct tapan_reg_mask_val tapan_codec_reg_mib3_int_rbias_init_val[] = {
- - {TAPAN_A_MICB_3_INT_RBIAS, 0x20, 0x00},
- -};
- -#endif
- -
- -#if defined(CONFIG_MACH_MILLETLTE_VZW)
- -static const struct tapan_reg_mask_val tapan_codec_reg_mib2_ctl_init_val[] = {
- - {TAPAN_A_MICB_2_CTL, 0x01, 0x01},
- -};
- -#endif
- -
- -#if defined(CONFIG_MACH_ATLANTICLTE_ATT) || defined(CONFIG_SEC_ATLANTIC3G_COMMON) || defined(CONFIG_MACH_ATLANTICLTE_USC) || defined(CONFIG_SEC_RUBENS_PROJECT)
- -static const struct tapan_reg_mask_val tapan_codec_reg_hph_ocp_ctl_init_val[] = {
- - {TAPAN_A_RX_HPH_OCP_CTL, 0xEB, 0x6B},
- -};
- -#endif
- -
- void *tapan_get_afe_config(struct snd_soc_codec *codec,
- enum afe_config_type config_type)
- {
- @@ -5986,7 +5645,6 @@ static void tapan_init_slim_slave_cfg(struct snd_soc_codec *codec)
- pr_debug("%s: slimbus logical address 0x%llx\n", __func__, eaddr);
- }
- -extern int system_rev;
- static void tapan_codec_init_reg(struct snd_soc_codec *codec)
- {
- u32 i;
- @@ -5995,27 +5653,6 @@ static void tapan_codec_init_reg(struct snd_soc_codec *codec)
- snd_soc_update_bits(codec, tapan_codec_reg_init_val[i].reg,
- tapan_codec_reg_init_val[i].mask,
- tapan_codec_reg_init_val[i].val);
- -#if defined (CONFIG_MACH_RUBENSLTE_OPEN)
- - snd_soc_update_bits(codec,tapan_codec_reg_mib3_int_rbias_init_val[0].reg,
- - tapan_codec_reg_mib3_int_rbias_init_val[0].mask,
- - tapan_codec_reg_mib3_int_rbias_init_val[0].val);
- -#endif
- -
- -#if defined(CONFIG_MACH_MILLETLTE_VZW)
- - if (system_rev > 1)
- - {
- - snd_soc_update_bits(codec,tapan_codec_reg_mib2_ctl_init_val[0].reg,
- - tapan_codec_reg_mib2_ctl_init_val[0].mask,
- - tapan_codec_reg_mib2_ctl_init_val[0].val);
- - }
- -#endif
- -
- -#if defined(CONFIG_MACH_ATLANTICLTE_ATT) || defined(CONFIG_SEC_ATLANTIC3G_COMMON) || defined(CONFIG_MACH_ATLANTICLTE_USC) || defined(CONFIG_SEC_RUBENS_PROJECT)
- - snd_soc_update_bits(codec,tapan_codec_reg_hph_ocp_ctl_init_val[0].reg,
- - tapan_codec_reg_hph_ocp_ctl_init_val[0].mask,
- - tapan_codec_reg_hph_ocp_ctl_init_val[0].val);
- -#endif
- -
- }
- static void tapan_slim_interface_init_reg(struct snd_soc_codec *codec)
- {
- @@ -6111,7 +5748,6 @@ static void wcd9xxx_prepare_hph_pa(struct wcd9xxx_mbhc *mbhc,
- int i;
- struct snd_soc_codec *codec = mbhc->codec;
- u32 delay;
- - int ret = 0;
- const struct wcd9xxx_reg_mask_val reg_set_paon[] = {
- {WCD9XXX_A_CDC_CLSH_B1_CTL, 0x0F, 0x00},
- @@ -6177,14 +5813,10 @@ static void wcd9xxx_prepare_hph_pa(struct wcd9xxx_mbhc *mbhc,
- delay = 1000;
- else
- delay = 0;
- - ret = wcd9xxx_soc_update_bits_push(codec, lh,
- + wcd9xxx_soc_update_bits_push(codec, lh,
- reg_set_paon[i].reg,
- reg_set_paon[i].mask,
- reg_set_paon[i].val, delay);
- - if (ret < 0) {
- - pr_debug("%s: wcd9xxx_soc_update_bits_push failed\n", __func__);
- - return;
- - }
- }
- pr_debug("%s: PAs are prepared\n", __func__);
- return;
- @@ -6466,16 +6098,11 @@ static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
- rco_clk_rate = TAPAN_MCLK_CLK_12P288MHZ;
- else
- rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;
- -#ifndef CONFIG_ARCH_MSM8226
- +
- ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec,
- tapan_enable_mbhc_micbias,
- &mbhc_cb, &cdc_intr_ids, rco_clk_rate,
- TAPAN_CDC_ZDET_SUPPORTED);
- -#else
- - ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec,NULL,
- - &mbhc_cb, &cdc_intr_ids, rco_clk_rate,
- - TAPAN_CDC_ZDET_SUPPORTED);
- -#endif
- if (ret)
- pr_err("%s: mbhc init failed %d\n", __func__, ret);
- else
- @@ -6588,11 +6215,11 @@ static void tapan_enable_config_rco(struct wcd9xxx *core, bool enable)
- }
- -static int tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
- +static bool tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
- {
- struct wcd9xxx *core = dev_get_drvdata(cdc_dev->parent);
- u8 reg_val;
- - int ret = 1;
- + bool ret = true;
- unsigned long timeout;
- bool timedout;
- struct wcd9xxx_core_resource *core_res = &core->core_res;
- @@ -6619,7 +6246,7 @@ static int tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
- if (wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT1) ||
- wcd9xxx_reg_read(core_res, TAPAN_A_QFUSE_DATA_OUT2)) {
- dev_info(cdc_dev, "%s: wcd9302 detected\n", __func__);
- - ret = 0;
- + ret = false;
- } else
- dev_info(cdc_dev, "%s: wcd9306 detected\n", __func__);
- @@ -6627,16 +6254,6 @@ static int tapan_check_wcd9306(struct device *cdc_dev, bool sensed)
- return ret;
- };
- -#ifdef CONFIG_ARCH_MSM8226
- -bool codec_probe_done = false;
- -
- -bool is_codec_probe_done(void)
- -{
- - return codec_probe_done;
- -}
- -EXPORT_SYMBOL(is_codec_probe_done);
- -#endif
- -
- static int tapan_codec_probe(struct snd_soc_codec *codec)
- {
- struct wcd9xxx *control;
- @@ -6671,7 +6288,6 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- snd_soc_codec_set_drvdata(codec, tapan);
- - tapan->ldo_h_count = 0;
- /* codec resmgr module init */
- wcd9xxx = codec->control_data;
- core_res = &wcd9xxx->core_res;
- @@ -6681,7 +6297,6 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- WCD9XXX_CDC_TYPE_TAPAN);
- if (ret) {
- pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
- - kfree(tapan);
- return ret;
- }
- @@ -6705,10 +6320,8 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- else
- rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;
- - tapan->micb_2_ref_cnt = 0;
- -
- -#ifndef CONFIG_SAMSUNG_JACK //Comment Disable MBHC
- - ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec, NULL,
- + ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec,
- + tapan_enable_mbhc_micbias,
- &mbhc_cb, &cdc_intr_ids, rco_clk_rate,
- TAPAN_CDC_ZDET_SUPPORTED);
- @@ -6716,7 +6329,6 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- pr_err("%s: mbhc init failed %d\n", __func__, ret);
- return ret;
- }
- -#endif
- tapan->codec = codec;
- for (i = 0; i < COMPANDER_MAX; i++) {
- @@ -6729,6 +6341,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- tapan->aux_r_gain = 0x1F;
- tapan->ldo_h_users = 0;
- tapan->micb_2_users = 0;
- + tapan->lb_mode = false;
- tapan_update_reg_defaults(codec);
- tapan_update_reg_mclk_rate(wcd9xxx);
- tapan_codec_init_reg(codec);
- @@ -6745,11 +6358,6 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- WCD9XXX_BG_CLK_UNLOCK(&tapan->resmgr);
- }
- -#if defined(CONFIG_SND_SOC_ES705)
- - remote_add_codec_controls(codec);
- -#elif defined(CONFIG_SND_SOC_ES325_ATLANTIC)
- - es325_remote_add_codec_controls(codec);
- -#endif
- ptr = kmalloc((sizeof(tapan_rx_chs) +
- sizeof(tapan_tx_chs)), GFP_KERNEL);
- if (!ptr) {
- @@ -6813,10 +6421,6 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
- if (ret)
- tapan_cleanup_irqs(tapan);
- -#ifdef CONFIG_ARCH_MSM8226
- - codec_probe_done = true;
- -#endif
- -
- return ret;
- err_pdata:
- @@ -6841,10 +6445,8 @@ static int tapan_codec_remove(struct snd_soc_codec *codec)
- tapan_cleanup_irqs(tapan);
- -#ifndef CONFIG_SAMSUNG_JACK //Comment Disable MBHC
- /* cleanup MBHC */
- wcd9xxx_mbhc_deinit(&tapan->mbhc);
- -#endif
- /* cleanup resmgr */
- wcd9xxx_resmgr_deinit(&tapan->resmgr);
- @@ -6903,13 +6505,13 @@ static const struct dev_pm_ops tapan_pm_ops = {
- static int __devinit tapan_probe(struct platform_device *pdev)
- {
- int ret = 0;
- - int is_wcd9306;
- + bool is_wcd9306;
- is_wcd9306 = tapan_check_wcd9306(&pdev->dev, false);
- if (is_wcd9306 < 0) {
- dev_info(&pdev->dev, "%s: cannot find codec type, default to 9306\n",
- __func__);
- - is_wcd9306 = 1;
- + is_wcd9306 = true;
- }
- codec_ver = is_wcd9306 ? WCD9306 : WCD9302;
- diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
- index 69844c0..4474ee0 100644
- --- a/sound/soc/codecs/wcd9320.c
- +++ b/sound/soc/codecs/wcd9320.c
- @@ -19,7 +19,6 @@
- #include <linux/ratelimit.h>
- #include <linux/debugfs.h>
- #include <linux/wait.h>
- -#include <linux/bitops.h>
- #include <linux/mfd/wcd9xxx/core.h>
- #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
- #include <linux/mfd/wcd9xxx/wcd9320_registers.h>
- @@ -41,26 +40,8 @@
- #include "wcd9320.h"
- #include "wcd9xxx-resmgr.h"
- #include "wcd9xxx-common.h"
- +#include "wcdcal-hwdep.h"
- -#if defined(CONFIG_SND_SOC_ES705)
- -#include "audience/es705-export.h"
- -#elif defined(CONFIG_SND_SOC_ES325)
- -#include "es325-export.h"
- -#endif
- -
- -#if defined(CONFIG_SND_SOC_ES705)
- -
- -#define CONFIG_SND_SOC_ESXXX
- -#define REMOTE_ROUTE_ENABLE_CB es705_remote_route_enable
- -#define SLIM_GET_CHANNEL_MAP_CB es705_slim_get_channel_map
- -#define SLIM_SET_CHANNEL_MAP_CB es705_slim_set_channel_map
- -#define SLIM_HW_PARAMS_CB es705_slim_hw_params
- -#define REMOTE_CFG_SLIM_RX_CB es705_remote_cfg_slim_rx
- -#define REMOTE_CLOSE_SLIM_RX_CB es705_remote_close_slim_rx
- -#define REMOTE_CFG_SLIM_TX_CB es705_remote_cfg_slim_tx
- -#define REMOTE_CLOSE_SLIM_TX_CB es705_remote_close_slim_tx
- -#define REMOTE_ADD_CODEC_CONTROLS_CB es705_remote_add_codec_controls
- -#endif
- #define TAIKO_MAD_SLIMBUS_TX_PORT 12
- #define TAIKO_MAD_AUDIO_FIRMWARE_PATH "wcd9320/wcd9320_mad_audio.bin"
- @@ -81,10 +62,6 @@ static int spkr_drv_wrnd_param_set(const char *val,
- const struct kernel_param *kp);
- static int spkr_drv_wrnd = 1;
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- -static int sub_mic_rec_delay = 0;
- -#endif
- -
- static struct kernel_param_ops spkr_drv_wrnd_param_ops = {
- .set = spkr_drv_wrnd_param_set,
- .get = param_get_int,
- @@ -477,6 +454,8 @@ struct taiko_priv {
- */
- struct list_head reg_save_restore;
- struct pm_qos_request pm_qos_req;
- + /* cal info for codec */
- + struct fw_info *fw_data;
- };
- static const u32 comp_shift[] = {
- @@ -690,23 +669,6 @@ static int taiko_get_iir_enable_audio_mixer(
- return 0;
- }
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- -static int taiko_get_sub_mic_delay_set(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - return 0;
- -}
- -
- -static int taiko_put_sub_mic_delay_set(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - sub_mic_rec_delay = ucontrol->value.integer.value[0];
- - pr_info("%s : sub_mic_rec_delay : %d\n", __func__, sub_mic_rec_delay);
- -
- - return 0;
- -}
- -#endif
- -
- static int taiko_put_iir_enable_audio_mixer(
- struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- @@ -1104,12 +1066,6 @@ static const char *const taiko_anc_func_text[] = {"OFF", "ON"};
- static const struct soc_enum taiko_anc_func_enum =
- SOC_ENUM_SINGLE_EXT(2, taiko_anc_func_text);
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- -static const char *const taiko_sub_mic_delay_text[] = {"OFF", "ON"};
- -static const struct soc_enum taiko_sub_mic_delay_enum =
- - SOC_ENUM_SINGLE_EXT(2, taiko_sub_mic_delay_text);
- -#endif
- -
- static const char *const tabla_ear_pa_gain_text[] = {"POS_6_DB", "POS_2_DB"};
- static const struct soc_enum tabla_ear_pa_gain_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, tabla_ear_pa_gain_text),
- @@ -1181,6 +1137,24 @@ static const struct soc_enum class_h_dsm_enum =
- static const struct snd_kcontrol_new class_h_dsm_mux =
- SOC_DAPM_ENUM("CLASS_H_DSM MUX Mux", class_h_dsm_enum);
- +static const char * const rx1_interpolator_text[] = {
- + "ZERO", "RX1 MIX2"
- +};
- +static const struct soc_enum rx1_interpolator_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 2, rx1_interpolator_text);
- +
- +static const struct snd_kcontrol_new rx1_interpolator =
- + SOC_DAPM_ENUM("RX1 INTERP Mux", rx1_interpolator_enum);
- +
- +static const char * const rx2_interpolator_text[] = {
- + "ZERO", "RX2 MIX2"
- +};
- +static const struct soc_enum rx2_interpolator_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 2, rx2_interpolator_text);
- +
- +static const struct snd_kcontrol_new rx2_interpolator =
- + SOC_DAPM_ENUM("RX2 INTERP Mux", rx2_interpolator_enum);
- +
- static const char *const taiko_conn_mad_text[] = {
- "ADC_MB", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "NOTUSED1",
- "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", "DMIC6", "NOTUSED2",
- @@ -1360,10 +1334,6 @@ static const struct snd_kcontrol_new taiko_snd_controls[] = {
- taiko_put_anc_slot),
- SOC_ENUM_EXT("ANC Function", taiko_anc_func_enum, taiko_get_anc_func,
- taiko_put_anc_func),
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - SOC_ENUM_EXT("SUB_MIC_REC_DELAY", taiko_sub_mic_delay_enum, taiko_get_sub_mic_delay_set,
- - taiko_put_sub_mic_delay_set),
- -#endif
- SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
- SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
- @@ -1573,45 +1543,9 @@ static const struct snd_kcontrol_new taiko_2_x_analog_gain_controls[] = {
- analog_gain),
- };
- -#if defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KLTE_KOR)
- -extern unsigned int system_rev;
- -#endif
- -
- static int taiko_hph_impedance_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- -#if defined(CONFIG_MACH_KLTE_KOR)
- - if (system_rev >= 13) {
- - uint32_t zl, zr;
- - bool hphr;
- - struct soc_multi_mixer_control *mc;
- - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- - struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
- -
- - mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
- -
- - hphr = mc->shift;
- - wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
- - pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
- - ucontrol->value.integer.value[0] = hphr ? zr : zl;
- - }
- -#elif defined(CONFIG_MACH_KLTE_JPN)
- - if (system_rev >= 11) {
- - uint32_t zl, zr;
- - bool hphr;
- - struct soc_multi_mixer_control *mc;
- - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- - struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
- -
- - mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
- -
- - hphr = mc->shift;
- - wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
- - pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
- - ucontrol->value.integer.value[0] = hphr ? zr : zl;
- - }
- -#else
- -#if !defined(CONFIG_SAMSUNG_JACK) && !defined(CONFIG_MUIC_DET_JACK)
- uint32_t zl, zr;
- bool hphr;
- struct soc_multi_mixer_control *mc;
- @@ -1624,9 +1558,7 @@ static int taiko_hph_impedance_get(struct snd_kcontrol *kcontrol,
- wcd9xxx_mbhc_get_impedance(&priv->mbhc, &zl, &zr);
- pr_debug("%s: zl %u, zr %u\n", __func__, zl, zr);
- ucontrol->value.integer.value[0] = hphr ? zr : zl;
- -#endif
- -#endif
- - ucontrol->value.integer.value[0] = 0;
- +
- return 0;
- }
- @@ -1745,6 +1677,21 @@ static const char * const iir_inp1_text[] = {
- "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
- };
- +static const char * const iir_inp2_text[] = {
- + "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
- + "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
- +};
- +
- +static const char * const iir_inp3_text[] = {
- + "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
- + "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
- +};
- +
- +static const char * const iir_inp4_text[] = {
- + "ZERO", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6", "DEC7", "DEC8",
- + "DEC9", "DEC10", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
- +};
- +
- static const struct soc_enum rx_mix1_inp1_chain_enum =
- SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_RX1_B1_CTL, 0, 12, rx_mix1_text);
- @@ -1893,6 +1840,24 @@ static const struct soc_enum iir1_inp1_mux_enum =
- static const struct soc_enum iir2_inp1_mux_enum =
- SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B1_CTL, 0, 18, iir_inp1_text);
- +static const struct soc_enum iir1_inp2_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B2_CTL, 0, 18, iir_inp2_text);
- +
- +static const struct soc_enum iir2_inp2_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B2_CTL, 0, 18, iir_inp2_text);
- +
- +static const struct soc_enum iir1_inp3_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B3_CTL, 0, 18, iir_inp3_text);
- +
- +static const struct soc_enum iir2_inp3_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B3_CTL, 0, 18, iir_inp3_text);
- +
- +static const struct soc_enum iir1_inp4_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ1_B4_CTL, 0, 18, iir_inp4_text);
- +
- +static const struct soc_enum iir2_inp4_mux_enum =
- + SOC_ENUM_SINGLE(TAIKO_A_CDC_CONN_EQ2_B4_CTL, 0, 18, iir_inp4_text);
- +
- static const struct snd_kcontrol_new rx_mix1_inp1_mux =
- SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum);
- @@ -2118,6 +2083,24 @@ static const struct snd_kcontrol_new iir1_inp1_mux =
- static const struct snd_kcontrol_new iir2_inp1_mux =
- SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
- +static const struct snd_kcontrol_new iir1_inp2_mux =
- + SOC_DAPM_ENUM("IIR1 INP2 Mux", iir1_inp2_mux_enum);
- +
- +static const struct snd_kcontrol_new iir2_inp2_mux =
- + SOC_DAPM_ENUM("IIR2 INP2 Mux", iir2_inp2_mux_enum);
- +
- +static const struct snd_kcontrol_new iir1_inp3_mux =
- + SOC_DAPM_ENUM("IIR1 INP3 Mux", iir1_inp3_mux_enum);
- +
- +static const struct snd_kcontrol_new iir2_inp3_mux =
- + SOC_DAPM_ENUM("IIR2 INP3 Mux", iir2_inp3_mux_enum);
- +
- +static const struct snd_kcontrol_new iir1_inp4_mux =
- + SOC_DAPM_ENUM("IIR1 INP4 Mux", iir1_inp4_mux_enum);
- +
- +static const struct snd_kcontrol_new iir2_inp4_mux =
- + SOC_DAPM_ENUM("IIR2 INP4 Mux", iir2_inp4_mux_enum);
- +
- static const struct snd_kcontrol_new anc1_mux =
- SOC_DAPM_ENUM("ANC1 MUX Mux", anc1_mux_enum);
- @@ -2499,10 +2482,6 @@ static int taiko_codec_enable_adc(struct snd_soc_dapm_widget *w,
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - if ((sub_mic_rec_delay == 1) && ((w->reg) == TAIKO_A_CDC_TX_3_GAIN))
- - usleep_range(400000, 400000);
- -#endif
- taiko_codec_enable_adc_block(codec, 1);
- snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
- 1 << init_bit_shift);
- @@ -2704,8 +2683,11 @@ static int taiko_codec_config_mad(struct snd_soc_codec *codec)
- int ret;
- const struct firmware *fw;
- struct mad_audio_cal *mad_cal;
- + struct firmware_cal *hwdep_cal = NULL;
- + const void *data;
- const char *filename = TAIKO_MAD_AUDIO_FIRMWARE_PATH;
- struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
- + size_t cal_size;
- pr_debug("%s: enter\n", __func__);
- /* wakeup for codec calibration access */
- @@ -2714,24 +2696,46 @@ static int taiko_codec_config_mad(struct snd_soc_codec *codec)
- PM_QOS_DEFAULT_VALUE);
- pm_qos_update_request(&taiko->pm_qos_req,
- msm_cpuidle_get_deep_idle_latency());
- - ret = request_firmware(&fw, filename, codec->dev);
- - if (ret != 0) {
- - pr_err("Failed to acquire MAD firwmare data %s: %d\n", filename,
- - ret);
- + if (!taiko->fw_data) {
- + dev_err(codec->dev, "%s: invalid cal data\n",
- + __func__);
- return -ENODEV;
- }
- -
- - if (fw->size < sizeof(struct mad_audio_cal)) {
- - pr_err("%s: incorrect firmware size %u\n", __func__, fw->size);
- - release_firmware(fw);
- - return -ENOMEM;
- + hwdep_cal = wcdcal_get_fw_cal(taiko->fw_data, WCD9XXX_MAD_CAL);
- + if (hwdep_cal) {
- + data = hwdep_cal->data;
- + cal_size = hwdep_cal->size;
- + dev_dbg(codec->dev, "%s: using hwdep calibration\n",
- + __func__);
- + } else {
- + ret = request_firmware(&fw, filename, codec->dev);
- + if (ret != 0) {
- + pr_err("Failed to acquire MAD firwmare data %s: %d\n",
- + filename, ret);
- + return -ENODEV;
- + }
- + if (!fw) {
- + dev_err(codec->dev, "failed to get mad fw");
- + return -ENODEV;
- + }
- + data = fw->data;
- + cal_size = fw->size;
- + dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
- + __func__);
- + }
- + if (cal_size < sizeof(struct mad_audio_cal)) {
- + pr_err("%s: incorrect hwdep cal size %zu\n",
- + __func__, cal_size);
- + ret = -ENOMEM;
- + goto err;
- }
- - mad_cal = (struct mad_audio_cal *)(fw->data);
- + mad_cal = (struct mad_audio_cal *)(data);
- if (!mad_cal) {
- - pr_err("%s: Invalid calibration data\n", __func__);
- - release_firmware(fw);
- - return -EINVAL;
- + dev_err(codec->dev, "%s: Invalid calibration data\n",
- + __func__);
- + ret = -EINVAL;
- + goto err;
- }
- snd_soc_write(codec, TAIKO_A_CDC_MAD_MAIN_CTL_2,
- @@ -2781,11 +2785,13 @@ static int taiko_codec_config_mad(struct snd_soc_codec *codec)
- snd_soc_write(codec, TAIKO_A_CDC_MAD_ULTR_CTL_6,
- mad_cal->ultrasound_info.rms_threshold_msb);
- - release_firmware(fw);
- pr_debug("%s: leave ret %d\n", __func__, ret);
- pm_qos_update_request(&taiko->pm_qos_req,
- PM_QOS_DEFAULT_VALUE);
- pm_qos_remove_request(&taiko->pm_qos_req);
- +err:
- + if (!hwdep_cal)
- + release_firmware(fw);
- return ret;
- }
- @@ -3279,8 +3285,8 @@ static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
- {
- struct snd_soc_codec *codec = w->codec;
- struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
- - /* uint32_t impedl, impedr; */
- - /* int ret = 0; */
- + uint32_t impedl, impedr;
- + int ret = 0;
- pr_debug("%s %s %d\n", __func__, w->name, event);
- @@ -3292,18 +3298,18 @@ static int taiko_hphl_dac_event(struct snd_soc_dapm_widget *w,
- WCD9XXX_CLSH_STATE_HPHL,
- WCD9XXX_CLSH_REQ_ENABLE,
- WCD9XXX_CLSH_EVENT_PRE_DAC);
- -
- - /*ret = wcd9xxx_mbhc_get_impedance(&taiko_p->mbhc,
- + ret = wcd9xxx_mbhc_get_impedance(&taiko_p->mbhc,
- &impedl, &impedr);
- - if (!ret) */
- - wcd9xxx_clsh_imped_config(codec, 0);
- - /* else
- + if (!ret)
- + wcd9xxx_clsh_imped_config(codec, impedl);
- + else
- dev_err(codec->dev, "Failed to get mbhc impedance %d\n",
- - ret); */
- + ret);
- break;
- case SND_SOC_DAPM_POST_PMD:
- snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL,
- 0x02, 0x00);
- + break;
- }
- return 0;
- }
- @@ -3342,15 +3348,18 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- const char *filename;
- const struct firmware *fw;
- int i;
- - int ret;
- + int ret =0;
- int num_anc_slots;
- struct wcd9xxx_anc_header *anc_head;
- struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
- + struct firmware_cal *hwdep_cal = NULL;
- u32 anc_writes_size = 0;
- int anc_size_remaining;
- u32 *anc_ptr;
- u16 reg;
- u8 mask, val, old_val;
- + size_t cal_size;
- + const void *data;
- if (taiko->anc_func == 0)
- @@ -3359,38 +3368,53 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- switch (event) {
- case SND_SOC_DAPM_PRE_PMU:
- filename = "wcd9320/wcd9320_anc.bin";
- + hwdep_cal = wcdcal_get_fw_cal(taiko->fw_data, WCD9XXX_ANC_CAL);
- + if (hwdep_cal) {
- + data = hwdep_cal->data;
- + cal_size = hwdep_cal->size;
- + dev_dbg(codec->dev, "%s: using hwdep calibration\n",
- + __func__);
- + } else {
- + ret = request_firmware(&fw, filename, codec->dev);
- + if (ret != 0) {
- + dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
- + ret);
- + return -ENODEV;
- + }
- + if (!fw) {
- + dev_err(codec->dev, "failed to get anc fw");
- + return -ENODEV;
- + }
- + data = fw->data;
- + cal_size = fw->size;
- + dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
- + __func__);
- - ret = request_firmware(&fw, filename, codec->dev);
- - if (ret != 0) {
- - dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
- - ret);
- - return -ENODEV;
- }
- - if (fw->size < sizeof(struct wcd9xxx_anc_header)) {
- + if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
- dev_err(codec->dev, "Not enough data\n");
- - release_firmware(fw);
- - return -ENOMEM;
- + goto err;
- }
- /* First number is the number of register writes */
- - anc_head = (struct wcd9xxx_anc_header *)(fw->data);
- - anc_ptr = (u32 *)((u32)fw->data +
- + anc_head = (struct wcd9xxx_anc_header *)(data);
- + anc_ptr = (u32 *)(data +
- sizeof(struct wcd9xxx_anc_header));
- - anc_size_remaining = fw->size -
- + anc_size_remaining = cal_size -
- sizeof(struct wcd9xxx_anc_header);
- num_anc_slots = anc_head->num_anc_slots;
- if (taiko->anc_slot >= num_anc_slots) {
- dev_err(codec->dev, "Invalid ANC slot selected\n");
- - release_firmware(fw);
- - return -EINVAL;
- + ret = -EINVAL;
- + goto err;
- }
- for (i = 0; i < num_anc_slots; i++) {
- if (anc_size_remaining < TAIKO_PACKED_REG_SIZE) {
- dev_err(codec->dev, "Invalid register format\n");
- - release_firmware(fw);
- - return -EINVAL;
- + ret = -EINVAL;
- + goto err;
- }
- anc_writes_size = (u32)(*anc_ptr);
- anc_size_remaining -= sizeof(u32);
- @@ -3399,8 +3423,8 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- if (anc_writes_size * TAIKO_PACKED_REG_SIZE
- > anc_size_remaining) {
- dev_err(codec->dev, "Invalid register format\n");
- - release_firmware(fw);
- - return -ENOMEM;
- + ret = -EINVAL;
- + goto err;
- }
- if (taiko->anc_slot == i)
- @@ -3412,8 +3436,8 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- }
- if (i == num_anc_slots) {
- dev_err(codec->dev, "Selected ANC slot not present\n");
- - release_firmware(fw);
- - return -ENOMEM;
- + ret = -EINVAL;
- + goto err;
- }
- for (i = 0; i < anc_writes_size; i++) {
- TAIKO_CODEC_UNPACK_ENTRY(anc_ptr[i], reg,
- @@ -3422,7 +3446,8 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- snd_soc_write(codec, reg, (old_val & ~mask) |
- (val & mask));
- }
- - release_firmware(fw);
- + if (!hwdep_cal)
- + release_firmware(fw);
- break;
- case SND_SOC_DAPM_PRE_PMD:
- msleep(40);
- @@ -3435,6 +3460,11 @@ static int taiko_codec_enable_anc(struct snd_soc_dapm_widget *w,
- break;
- }
- return 0;
- +err:
- + if (!hwdep_cal)
- + release_firmware(fw);
- + return ret;
- +
- }
- static int taiko_hph_pa_event(struct snd_soc_dapm_widget *w,
- @@ -3808,8 +3838,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
- {"CLASS_H_DSM MUX", "DSM_HPHL_RX1", "RX1 CHAIN"},
- - {"RX1 CHAIN", NULL, "RX1 MIX2"},
- - {"RX2 CHAIN", NULL, "RX2 MIX2"},
- + {"RX1 INTERP", NULL, "RX1 MIX2"},
- + {"RX1 CHAIN", NULL, "RX1 INTERP"},
- + {"RX2 INTERP", NULL, "RX2 MIX2"},
- + {"RX2 CHAIN", NULL, "RX2 INTERP"},
- {"RX1 MIX2", NULL, "ANC1 MUX"},
- {"RX2 MIX2", NULL, "ANC2 MUX"},
- @@ -4129,6 +4161,120 @@ static const struct snd_soc_dapm_route audio_map[] = {
- {"IIR2 INP1 MUX", "RX6", "SLIM RX6"},
- {"IIR2 INP1 MUX", "RX7", "SLIM RX7"},
- + {"IIR1", NULL, "IIR1 INP2 MUX"},
- + {"IIR1 INP2 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR1 INP2 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR1 INP2 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR1 INP2 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR1 INP2 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR1 INP2 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR1 INP2 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR1 INP2 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR1 INP2 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR1 INP2 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR1 INP2 MUX", "RX1", "SLIM RX1"},
- + {"IIR1 INP2 MUX", "RX2", "SLIM RX2"},
- + {"IIR1 INP2 MUX", "RX3", "SLIM RX3"},
- + {"IIR1 INP2 MUX", "RX4", "SLIM RX4"},
- + {"IIR1 INP2 MUX", "RX5", "SLIM RX5"},
- + {"IIR1 INP2 MUX", "RX6", "SLIM RX6"},
- + {"IIR1 INP2 MUX", "RX7", "SLIM RX7"},
- +
- + {"IIR2", NULL, "IIR2 INP2 MUX"},
- + {"IIR2 INP2 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR2 INP2 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR2 INP2 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR2 INP2 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR2 INP2 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR2 INP2 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR2 INP2 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR2 INP2 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR2 INP2 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR2 INP2 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR2 INP2 MUX", "RX1", "SLIM RX1"},
- + {"IIR2 INP2 MUX", "RX2", "SLIM RX2"},
- + {"IIR2 INP2 MUX", "RX3", "SLIM RX3"},
- + {"IIR2 INP2 MUX", "RX4", "SLIM RX4"},
- + {"IIR2 INP2 MUX", "RX5", "SLIM RX5"},
- + {"IIR2 INP2 MUX", "RX6", "SLIM RX6"},
- + {"IIR2 INP2 MUX", "RX7", "SLIM RX7"},
- +
- + {"IIR1", NULL, "IIR1 INP3 MUX"},
- + {"IIR1 INP3 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR1 INP3 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR1 INP3 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR1 INP3 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR1 INP3 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR1 INP3 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR1 INP3 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR1 INP3 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR1 INP3 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR1 INP3 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR1 INP3 MUX", "RX1", "SLIM RX1"},
- + {"IIR1 INP3 MUX", "RX2", "SLIM RX2"},
- + {"IIR1 INP3 MUX", "RX3", "SLIM RX3"},
- + {"IIR1 INP3 MUX", "RX4", "SLIM RX4"},
- + {"IIR1 INP3 MUX", "RX5", "SLIM RX5"},
- + {"IIR1 INP3 MUX", "RX6", "SLIM RX6"},
- + {"IIR1 INP3 MUX", "RX7", "SLIM RX7"},
- +
- + {"IIR2", NULL, "IIR2 INP3 MUX"},
- + {"IIR2 INP3 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR2 INP3 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR2 INP3 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR2 INP3 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR2 INP3 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR2 INP3 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR2 INP3 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR2 INP3 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR2 INP3 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR2 INP3 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR2 INP3 MUX", "RX1", "SLIM RX1"},
- + {"IIR2 INP3 MUX", "RX2", "SLIM RX2"},
- + {"IIR2 INP3 MUX", "RX3", "SLIM RX3"},
- + {"IIR2 INP3 MUX", "RX4", "SLIM RX4"},
- + {"IIR2 INP3 MUX", "RX5", "SLIM RX5"},
- + {"IIR2 INP3 MUX", "RX6", "SLIM RX6"},
- + {"IIR2 INP3 MUX", "RX7", "SLIM RX7"},
- +
- + {"IIR1", NULL, "IIR1 INP4 MUX"},
- + {"IIR1 INP4 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR1 INP4 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR1 INP4 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR1 INP4 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR1 INP4 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR1 INP4 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR1 INP4 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR1 INP4 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR1 INP4 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR1 INP4 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR1 INP4 MUX", "RX1", "SLIM RX1"},
- + {"IIR1 INP4 MUX", "RX2", "SLIM RX2"},
- + {"IIR1 INP4 MUX", "RX3", "SLIM RX3"},
- + {"IIR1 INP4 MUX", "RX4", "SLIM RX4"},
- + {"IIR1 INP4 MUX", "RX5", "SLIM RX5"},
- + {"IIR1 INP4 MUX", "RX6", "SLIM RX6"},
- + {"IIR1 INP4 MUX", "RX7", "SLIM RX7"},
- +
- + {"IIR2", NULL, "IIR2 INP4 MUX"},
- + {"IIR2 INP4 MUX", "DEC1", "DEC1 MUX"},
- + {"IIR2 INP4 MUX", "DEC2", "DEC2 MUX"},
- + {"IIR2 INP4 MUX", "DEC3", "DEC3 MUX"},
- + {"IIR2 INP4 MUX", "DEC4", "DEC4 MUX"},
- + {"IIR2 INP4 MUX", "DEC5", "DEC5 MUX"},
- + {"IIR2 INP4 MUX", "DEC6", "DEC6 MUX"},
- + {"IIR2 INP4 MUX", "DEC7", "DEC7 MUX"},
- + {"IIR2 INP4 MUX", "DEC8", "DEC8 MUX"},
- + {"IIR2 INP4 MUX", "DEC9", "DEC9 MUX"},
- + {"IIR2 INP4 MUX", "DEC10", "DEC10 MUX"},
- + {"IIR2 INP4 MUX", "RX1", "SLIM RX1"},
- + {"IIR2 INP4 MUX", "RX2", "SLIM RX2"},
- + {"IIR2 INP4 MUX", "RX3", "SLIM RX3"},
- + {"IIR2 INP4 MUX", "RX4", "SLIM RX4"},
- + {"IIR2 INP4 MUX", "RX5", "SLIM RX5"},
- + {"IIR2 INP4 MUX", "RX6", "SLIM RX6"},
- + {"IIR2 INP4 MUX", "RX7", "SLIM RX7"},
- +
- {"MIC BIAS1 Internal1", NULL, "LDO_H"},
- {"MIC BIAS1 Internal2", NULL, "LDO_H"},
- {"MIC BIAS1 External", NULL, "LDO_H"},
- @@ -4140,10 +4286,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
- {"MIC BIAS3 Internal2", NULL, "LDO_H"},
- {"MIC BIAS3 External", NULL, "LDO_H"},
- {"MIC BIAS4 External", NULL, "LDO_H"},
- - {"Main Mic Bias", NULL, "LDO_H"},
- {DAPM_MICBIAS2_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
- {DAPM_MICBIAS3_EXTERNAL_STANDALONE, NULL, "LDO_H Standalone"},
- - {"Ear Mic Bias", NULL, "LDO_H"},
- };
- static int taiko_readable(struct snd_soc_codec *ssc, unsigned int reg)
- @@ -4289,129 +4433,20 @@ static unsigned int taiko_read(struct snd_soc_codec *codec,
- return val;
- }
- -#ifdef CONFIG_SND_SOC_ES325
- static int taiko_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- - struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
- pr_debug("%s(): substream = %s stream = %d\n" , __func__,
- substream->name, substream->stream);
- - if ((taiko_core != NULL) &&
- - (taiko_core->dev != NULL) &&
- - (taiko_core->dev->parent != NULL)) {
- - es325_wrapper_wakeup(dai);
- - }
- return 0;
- }
- -#else
- -static int taiko_startup(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- -// struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
- - pr_debug("%s(): substream = %s stream = %d\n" , __func__,
- - substream->name, substream->stream);
- - return 0;
- -}
- -#endif
- static void taiko_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- - struct wcd9xxx *taiko_core = dev_get_drvdata(dai->codec->dev->parent);
- pr_debug("%s(): substream = %s stream = %d\n" , __func__,
- substream->name, substream->stream);
- - if ((taiko_core != NULL) &&
- - (taiko_core->dev != NULL) &&
- - (taiko_core->dev->parent != NULL)) {
- -#ifdef CONFIG_SND_SOC_ES325
- - es325_wrapper_sleep(dai->id);
- -#endif
- - }
- -}
- -
- -static int taiko_prepare(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - int paths, i;
- - struct snd_soc_dapm_widget_list *wlist;
- - struct snd_soc_codec *codec = dai->codec;
- - struct taiko_priv *taiko_p = snd_soc_codec_get_drvdata(codec);
- - int found_hs_pa = 0;
- -
- - if (substream->stream)
- - return 0;
- -
- - pr_debug("%s(): substream = %s. stream = %d. dai->name = %s."
- - " dai->driver->name = %s. dai stream_name = %s\n",
- - __func__, substream->name, substream->stream,
- - dai->name, dai->driver->name,
- - substream->stream ? dai->driver->capture.stream_name :
- - dai->driver->playback.stream_name);
- -
- - pr_debug("%s(): dai AIF widget = %s. dai playback stream_name = %s.\n"
- - " rate = %u. bit_width = %u. hs compander_enabled = %u\n",
- - __func__, dai->playback_aif ? dai->playback_aif->name : "NULL",
- - dai->driver->playback.stream_name, taiko_p->dai[dai->id].rate,
- - taiko_p->dai[dai->id].bit_width,
- - taiko_p->comp_enabled[COMPANDER_1]);
- -
- - if ((!(taiko_p->dai[dai->id].rate == 192000 ||
- - taiko_p->dai[dai->id].rate == 96000)) ||
- - !(taiko_p->dai[dai->id].bit_width == 24) ||
- - !(taiko_p->comp_enabled[COMPANDER_1])) {
- -
- - taiko_p->clsh_d.hs_perf_mode_enabled = false;
- - snd_soc_update_bits(codec, TAIKO_A_RX_HPH_CHOP_CTL, 0x20, 0x20);
- -
- - dev_dbg(dai->dev ,"%s(): high performnce mode not needed\n",
- - __func__);
- - return 0;
- - }
- -
- - paths = snd_soc_dapm_codec_dai_get_playback_connected_widgets(dai, &wlist);
- -
- - if (!paths) {
- - dev_err(dai->dev, "%s(): found no audio playback paths\n",
- - __func__);
- - return 0;
- - }
- -
- - for (i = 0; i < wlist->num_widgets; i++) {
- - dev_dbg(dai->dev, " dai stream_name = %s, widget name = %s\n",
- - dai->driver->playback.stream_name, wlist->widgets[i]->name);
- -
- - if (!strcmp(wlist->widgets[i]->name, "HPHL") ||
- - !strcmp(wlist->widgets[i]->name, "HPHR")) {
- - found_hs_pa = 1;
- - break;
- - }
- - }
- -
- - kfree(wlist);
- -
- - if (!found_hs_pa)
- - return 0;
- -
- - pr_debug("%s(): rate = %u. bit_width = %u. hs compander_enabled = %u",
- - __func__, taiko_p->dai[dai->id].rate,
- - taiko_p->dai[dai->id].bit_width,
- - taiko_p->comp_enabled[COMPANDER_1]);
- -
- - if ((taiko_p->dai[dai->id].rate == 192000 ||
- - taiko_p->dai[dai->id].rate == 96000) &&
- - (taiko_p->dai[dai->id].bit_width == 24) &&
- - (taiko_p->comp_enabled[COMPANDER_1])) {
- -
- - pr_debug("%s(): HS peformance mode enabled", __func__);
- - taiko_p->clsh_d.hs_perf_mode_enabled = true;
- - snd_soc_update_bits(codec, TAIKO_A_RX_HPH_CHOP_CTL, 0x20, 0x00);
- - } else {
- - taiko_p->clsh_d.hs_perf_mode_enabled = false;
- - snd_soc_update_bits(codec, TAIKO_A_RX_HPH_CHOP_CTL, 0x20, 0x20);
- - }
- -
- - return 0;
- }
- int taiko_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, bool dapm)
- @@ -4787,7 +4822,7 @@ static int taiko_hw_params(struct snd_pcm_substream *substream,
- u32 compander_fs;
- int ret;
- - pr_info("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- + pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- dai->name, dai->id, params_rate(params),
- params_channels(params));
- @@ -4904,223 +4939,15 @@ static int taiko_hw_params(struct snd_pcm_substream *substream,
- return 0;
- }
- -#if defined(CONFIG_SND_SOC_ESXXX)
- -int (*remote_route_enable)(struct snd_soc_dai *dai) = REMOTE_ROUTE_ENABLE_CB;
- -int (*slim_get_channel_map)(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- - = SLIM_GET_CHANNEL_MAP_CB;
- -int (*slim_set_channel_map)(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- - = SLIM_SET_CHANNEL_MAP_CB;
- -int (*slim_hw_params)(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- - = SLIM_HW_PARAMS_CB;
- -int (*remote_cfg_slim_rx)(int dai_id) = REMOTE_CFG_SLIM_RX_CB;
- -int (*remote_close_slim_rx)(int dai_id) = REMOTE_CLOSE_SLIM_RX_CB;
- -int (*remote_cfg_slim_tx)(int dai_id) = REMOTE_CFG_SLIM_TX_CB;
- -int (*remote_close_slim_tx)(int dai_id) = REMOTE_CLOSE_SLIM_TX_CB;
- -int (*remote_add_codec_controls)(struct snd_soc_codec *codec)
- - = REMOTE_ADD_CODEC_CONTROLS_CB;
- -
- -static int taiko_esxxx_startup(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - taiko_startup(substream, dai);
- -/*
- - if (es705_remote_route_enable(dai))
- - es705_slim_startup(substream, dai);
- -*/
- -
- - return 0;
- -}
- -
- -static void taiko_esxxx_shutdown(struct snd_pcm_substream *substream,
- - struct snd_soc_dai *dai)
- -{
- - taiko_shutdown(substream, dai);
- -
- -/*
- - if (es705_remote_route_enable(dai))
- - es705_slim_shutdown(substream, dai);
- -*/
- -}
- -
- -static int taiko_esxxx_hw_params(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- -{
- - int rc = 0;
- - pr_info("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- - dai->name, dai->id, params_rate(params),
- - params_channels(params));
- -
- - rc = taiko_hw_params(substream, params, dai);
- -
- - if (remote_route_enable(dai))
- - rc = slim_hw_params(substream, params, dai);
- -
- - return rc;
- -}
- -static int taiko_esxxx_set_channel_map(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- -
- -{
- - unsigned int taiko_tx_num = 0;
- - unsigned int taiko_tx_slot[6];
- - unsigned int taiko_rx_num = 0;
- - unsigned int taiko_rx_slot[6];
- - int rc = 0;
- - pr_info("%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n",
- - __func__, dai->name, dai->id, tx_num, rx_num);
- -
- - if (remote_route_enable(dai)) {
- - rc = taiko_get_channel_map(dai, &taiko_tx_num, taiko_tx_slot,
- - &taiko_rx_num, taiko_rx_slot);
- -
- - rc = taiko_set_channel_map(dai, tx_num, taiko_tx_slot, rx_num, taiko_rx_slot);
- -
- - rc = slim_set_channel_map(dai, tx_num, tx_slot, rx_num,
- - rx_slot);
- - } else
- - rc = taiko_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -
- -static int taiko_esxxx_get_channel_map(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- -
- -{
- - int rc = 0;
- -
- - pr_info("%s(): dai_name = %s DAI-ID %d tx_ch %d rx_ch %d\n",
- - __func__, dai->name, dai->id, *tx_num, *rx_num);
- -
- - if (remote_route_enable(dai))
- - rc = slim_get_channel_map(dai, tx_num, tx_slot, rx_num,
- - rx_slot);
- - else
- - rc = taiko_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -static struct snd_soc_dai_ops taiko_dai_ops = {
- - .startup = taiko_esxxx_startup, /* taiko_startup, */
- - .shutdown = taiko_esxxx_shutdown, /* taiko_shutdown, */
- - .prepare = taiko_prepare,
- - .hw_params = taiko_esxxx_hw_params, /* taiko_hw_params, */
- - .set_sysclk = taiko_set_dai_sysclk,
- - .set_fmt = taiko_set_dai_fmt,
- - .set_channel_map = taiko_esxxx_set_channel_map,
- - /* taiko_set_channel_map, */
- - .get_channel_map = taiko_esxxx_get_channel_map,
- - /* taiko_get_channel_map, */
- -};
- -#elif defined(CONFIG_SND_SOC_ES325)
- -static int taiko_es325_hw_params(struct snd_pcm_substream *substream,
- - struct snd_pcm_hw_params *params,
- - struct snd_soc_dai *dai)
- -{
- - int rc = 0;
- - dev_info(dai->dev,"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
- - dai->name, dai->id, params_rate(params),
- - params_channels(params));
- -
- - rc = taiko_hw_params(substream, params, dai);
- -
- - if (es325_remote_route_enable(dai))
- - rc = es325_slim_hw_params(substream, params, dai);
- -
- - return rc;
- -}
- -
- -#define SLIM_BUGFIX
- -static int taiko_es325_set_channel_map(struct snd_soc_dai *dai,
- - unsigned int tx_num, unsigned int *tx_slot,
- - unsigned int rx_num, unsigned int *rx_slot)
- -
- -{
- -#if !defined(SLIM_BUGFIX)
- - unsigned int taiko_tx_num = 0;
- -#endif
- - unsigned int taiko_tx_slot[6];
- -#if !defined(SLIM_BUGFIX)
- - unsigned int taiko_rx_num = 0;
- -#endif
- - unsigned int taiko_rx_slot[6];
- -#if defined(SLIM_BUGFIX)
- - unsigned int temp_tx_num = 0;
- - unsigned int temp_rx_num = 0;
- -#endif
- - int rc = 0;
- -
- - if (es325_remote_route_enable(dai)) {
- -#if defined(SLIM_BUGFIX)
- - rc = taiko_get_channel_map(dai, &temp_tx_num, taiko_tx_slot,
- - &temp_rx_num, taiko_rx_slot);
- -#else
- - rc = taiko_get_channel_map(dai, &taiko_tx_num, taiko_tx_slot,
- - &taiko_rx_num, taiko_rx_slot);
- -#endif
- -
- - rc = taiko_set_channel_map(dai, tx_num, taiko_tx_slot, rx_num, taiko_rx_slot);
- -
- - rc = es325_slim_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- - } else
- - rc = taiko_set_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -
- -static int taiko_es325_get_channel_map(struct snd_soc_dai *dai,
- - unsigned int *tx_num, unsigned int *tx_slot,
- - unsigned int *rx_num, unsigned int *rx_slot)
- -
- -{
- - int rc = 0;
- -
- - if (es325_remote_route_enable(dai))
- - rc = es325_slim_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- - else
- - rc = taiko_get_channel_map(dai, tx_num, tx_slot, rx_num, rx_slot);
- -
- - return rc;
- -}
- -
- -static struct snd_soc_dai_ops taiko_dai_ops = {
- - .startup = taiko_startup,
- - .shutdown = taiko_shutdown,
- - .prepare = taiko_prepare,
- - .hw_params = taiko_es325_hw_params, /* tabla_hw_params, */
- - .set_sysclk = taiko_set_dai_sysclk,
- - .set_fmt = taiko_set_dai_fmt,
- - .set_channel_map = taiko_set_channel_map, /* tabla_set_channel_map, */
- - .get_channel_map = taiko_es325_get_channel_map, /* tabla_get_channel_map, */
- -};
- -
- -static struct snd_soc_dai_ops taiko_es325_dai_ops = {
- - .startup = taiko_startup,
- - .hw_params = taiko_es325_hw_params,
- - .set_channel_map = taiko_es325_set_channel_map,
- - .get_channel_map = taiko_es325_get_channel_map,
- -};
- -#else
- static struct snd_soc_dai_ops taiko_dai_ops = {
- .startup = taiko_startup,
- .shutdown = taiko_shutdown,
- - .prepare = taiko_prepare,
- .hw_params = taiko_hw_params,
- .set_sysclk = taiko_set_dai_sysclk,
- .set_fmt = taiko_set_dai_fmt,
- .set_channel_map = taiko_set_channel_map,
- .get_channel_map = taiko_get_channel_map,
- };
- -#endif
- static struct snd_soc_dai_driver taiko_dai[] = {
- {
- @@ -5235,50 +5062,6 @@ static struct snd_soc_dai_driver taiko_dai[] = {
- },
- .ops = &taiko_dai_ops,
- },
- -#ifdef CONFIG_SND_SOC_ES325
- - {
- - .name = "taiko_es325_rx1",
- - .id = AIF1_PB + ES325_DAI_ID_OFFSET,
- - .playback = {
- - .stream_name = "AIF1 Playback",
- - .rates = WCD9320_RATES,
- - .formats = TAIKO_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &taiko_es325_dai_ops,
- - },
- - {
- - .name = "taiko_es325_tx1",
- - .id = AIF1_CAP + ES325_DAI_ID_OFFSET,
- - .capture = {
- - .stream_name = "AIF1 Capture",
- - .rates = WCD9320_RATES,
- - .formats = TAIKO_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &taiko_es325_dai_ops,
- - },
- - {
- - .name = "taiko_es325_rx2",
- - .id = AIF2_PB + ES325_DAI_ID_OFFSET,
- - .playback = {
- - .stream_name = "AIF2 Playback",
- - .rates = WCD9320_RATES,
- - .formats = TAIKO_FORMATS,
- - .rate_max = 192000,
- - .rate_min = 8000,
- - .channels_min = 1,
- - .channels_max = 2,
- - },
- - .ops = &taiko_es325_dai_ops,
- - },
- -#endif
- };
- static struct snd_soc_dai_driver taiko_i2s_dai[] = {
- @@ -5440,21 +5223,11 @@ static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
- dai->bus_down_in_recovery = false;
- taiko_codec_enable_int_port(dai, codec);
- (void) taiko_codec_enable_slim_chmask(dai, true);
- -#if defined(CONFIG_SND_SOC_ESXXX)
- - ret = remote_cfg_slim_rx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325)
- - ret = es325_remote_cfg_slim_rx(w->shift);
- -#endif
- ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
- dai->rate, dai->bit_width,
- &dai->grph);
- break;
- case SND_SOC_DAPM_POST_PMD:
- -#if defined(CONFIG_SND_SOC_ESXXX)
- - ret = remote_close_slim_rx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325)
- - ret = es325_remote_close_slim_rx(w->shift);
- -#endif
- ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
- dai->grph);
- if (!dai->bus_down_in_recovery)
- @@ -5583,18 +5356,8 @@ static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
- ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
- dai->rate, dai->bit_width,
- &dai->grph);
- -#if defined(CONFIG_SND_SOC_ESXXX)
- - ret = remote_cfg_slim_tx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325)
- - ret = es325_remote_cfg_slim_tx(w->shift);
- -#endif
- break;
- case SND_SOC_DAPM_POST_PMD:
- -#if defined(CONFIG_SND_SOC_ESXXX)
- - ret = remote_close_slim_tx(w->shift);
- -#elif defined(CONFIG_SND_SOC_ES325)
- - ret = es325_remote_close_slim_tx(w->shift);
- -#endif
- ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
- dai->grph);
- if (!dai->bus_down_in_recovery)
- @@ -5661,6 +5424,24 @@ static int taiko_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
- return 0;
- }
- +static int taiko_codec_iir_mux_event(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- +
- + pr_debug("%s: event = %d\n", __func__, event);
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
- + break;
- + case SND_SOC_DAPM_POST_PMD:
- + snd_soc_write(codec, w->reg, snd_soc_read(codec, w->reg));
- + break;
- + }
- + return 0;
- +}
- +
- static int taiko_codec_dsm_mux_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
- {
- @@ -5719,6 +5500,24 @@ static int taiko_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
- return ret;
- }
- +static int taiko_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
- + struct snd_kcontrol *kcontrol, int event)
- +{
- + struct snd_soc_codec *codec = w->codec;
- + int value = 0;
- +
- + switch (event) {
- + case SND_SOC_DAPM_POST_PMU:
- + value = snd_soc_read(codec, TAIKO_A_CDC_IIR1_GAIN_B1_CTL);
- + snd_soc_write(codec, TAIKO_A_CDC_IIR1_GAIN_B1_CTL, value);
- + break;
- + default:
- + pr_info("%s: event = %d not expected\n", __func__, event);
- + break;
- + }
- + return 0;
- +}
- +
- /* Todo: Have seperate dapm widgets for I2S and Slimbus.
- * Might Need to have callbacks registered only for slimbus
- */
- @@ -5836,12 +5635,8 @@ static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
- SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("RX7 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
- - SND_SOC_DAPM_MIXER_E("RX1 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
- - 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
- - SND_SOC_DAPM_POST_PMU),
- - SND_SOC_DAPM_MIXER_E("RX2 MIX2", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
- - 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
- - SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MIXER("RX1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
- + SND_SOC_DAPM_MIXER("RX2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
- SND_SOC_DAPM_MIXER_E("RX3 MIX1", TAIKO_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
- 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
- @@ -5859,6 +5654,13 @@ static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
- 0, taiko_codec_enable_interpolator, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("RX1 INTERP", TAIKO_A_CDC_CLK_RX_B1_CTL, 0, 0,
- + &rx1_interpolator, taiko_codec_enable_interpolator,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
- + SND_SOC_DAPM_MUX_E("RX2 INTERP", TAIKO_A_CDC_CLK_RX_B1_CTL, 1, 0,
- + &rx2_interpolator, taiko_codec_enable_interpolator,
- + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
- +
- SND_SOC_DAPM_MIXER("RX1 CHAIN", TAIKO_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("RX2 CHAIN", TAIKO_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
- @@ -5962,18 +5764,10 @@ static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
- taiko_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("Main Mic Bias", 0, 0, 0,
- - 0, SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_INPUT("AMIC3"),
- SND_SOC_DAPM_INPUT("AMIC4"),
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- - SND_SOC_DAPM_MICBIAS_E("Sub Mic Bias", 0, 0, 0,
- - 0, SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_POST_PMD),
- -#endif
- SND_SOC_DAPM_INPUT("AMIC5"),
- @@ -6089,9 +5883,6 @@ static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
- 0, taiko_codec_enable_micbias,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MICBIAS_E("Ear Mic Bias", 0, 0, 0,
- - 0, SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMU |
- - SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
- AIF1_CAP, 0, taiko_codec_enable_slimtx,
- @@ -6170,10 +5961,42 @@ static const struct snd_soc_dapm_widget taiko_dapm_widgets[] = {
- SND_SOC_DAPM_POST_PMD),
- /* Sidetone */
- - SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
- - SND_SOC_DAPM_MIXER("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
- + SND_SOC_DAPM_MUX_E("IIR1 INP1 MUX", TAIKO_A_CDC_IIR1_GAIN_B1_CTL, 0, 0,
- + &iir1_inp1_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_PGA_E("IIR1", TAIKO_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
- + taiko_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
- +
- + SND_SOC_DAPM_MUX_E("IIR1 INP2 MUX", TAIKO_A_CDC_IIR1_GAIN_B2_CTL, 0, 0,
- + &iir1_inp2_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_MUX_E("IIR1 INP3 MUX", TAIKO_A_CDC_IIR1_GAIN_B3_CTL, 0, 0,
- + &iir1_inp3_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_MUX_E("IIR1 INP4 MUX", TAIKO_A_CDC_IIR1_GAIN_B4_CTL, 0, 0,
- + &iir1_inp4_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- +
- + SND_SOC_DAPM_MUX_E("IIR2 INP1 MUX", TAIKO_A_CDC_IIR2_GAIN_B1_CTL, 0, 0,
- + &iir2_inp1_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_MUX_E("IIR2 INP2 MUX", TAIKO_A_CDC_IIR2_GAIN_B2_CTL, 0, 0,
- + &iir2_inp2_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_MUX_E("IIR2 INP3 MUX", TAIKO_A_CDC_IIR2_GAIN_B3_CTL, 0, 0,
- + &iir2_inp3_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- +
- + SND_SOC_DAPM_MUX_E("IIR2 INP4 MUX", TAIKO_A_CDC_IIR2_GAIN_B4_CTL, 0, 0,
- + &iir2_inp4_mux, taiko_codec_iir_mux_event,
- + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- - SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
- SND_SOC_DAPM_MIXER("IIR2", TAIKO_A_CDC_CLK_SD_CTL, 1, 0, NULL, 0),
- /* AUX PGA */
- @@ -6580,10 +6403,10 @@ static const struct wcd9xxx_reg_mask_val taiko_reg_defaults[] = {
- TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL, 0x00),
- TAIKO_REG_VAL(TAIKO_A_CDC_CLK_OTHR_CTL, 0x00),
- TAIKO_REG_VAL(TAIKO_A_CDC_CONN_MAD, 0x01),
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_SEC_H_PROJECT) && !defined(CONFIG_SEC_FRESCO_PROJECT) && !defined(CONFIG_MACH_KS01EUR)
- +
- /* Set HPH Path to low power mode */
- TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x55),
- -#endif
- +
- /* BUCK default */
- TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
- TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
- @@ -6613,13 +6436,7 @@ static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
- /*Reduce EAR DAC bias to 70% */
- TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
- /* Reduce LINE DAC bias to 70% */
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_SEC_H_PROJECT) && !defined(CONFIG_SEC_FRESCO_PROJECT) && !defined(CONFIG_MACH_KS01EUR)
- TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
- -#else
- - TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x7A),
- - /* Reduce HPH DAC bias to 70% */
- - TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
- -#endif
- /*
- * There is a diode to pull down the micbias while doing
- @@ -6657,21 +6474,12 @@ static const struct wcd9xxx_reg_mask_val taiko_2_0_reg_defaults[] = {
- TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x51),
- TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
- TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_SEC_H_PROJECT) && !defined(CONFIG_SEC_FRESCO_PROJECT) && !defined(CONFIG_MACH_KS01EUR)
- - TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x6B),
- -#else
- - TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x7A),
- - TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x6B),
- -#endif
- + TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
- TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_CTL, 0xDA),
- TAIKO_REG_VAL(TAIKO_A_RX_HPH_CNP_WG_TIME, 0x15),
- TAIKO_REG_VAL(TAIKO_A_RX_EAR_BIAS_PA, 0x76),
- TAIKO_REG_VAL(TAIKO_A_RX_EAR_CNP, 0xC0),
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_SEC_H_PROJECT) && !defined(CONFIG_SEC_FRESCO_PROJECT) && !defined(CONFIG_MACH_KS01EUR)
- TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x78),
- -#else
- - TAIKO_REG_VAL(TAIKO_A_RX_LINE_BIAS_PA, 0x7A),
- -#endif
- TAIKO_REG_VAL(TAIKO_A_RX_LINE_1_TEST, 0x2),
- TAIKO_REG_VAL(TAIKO_A_RX_LINE_2_TEST, 0x2),
- TAIKO_REG_VAL(TAIKO_A_RX_LINE_3_TEST, 0x2),
- @@ -6800,6 +6608,8 @@ static const struct wcd9xxx_reg_mask_val taiko_codec_reg_init_val[] = {
- /* set MAD input MIC to DMIC1 */
- {TAIKO_A_CDC_CONN_MAD, 0x0F, 0x08},
- + /* set DMIC CLK drive strength to 4mA */
- + {TAIKO_A_HDRIVE_OVERRIDE, 0x07, 0x01},
- };
- static void taiko_codec_init_reg(struct snd_soc_codec *codec)
- @@ -6850,6 +6660,27 @@ static void taiko_cleanup_irqs(struct taiko_priv *taiko)
- wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, taiko);
- }
- +static
- +struct firmware_cal *taiko_get_hwdep_fw_cal(struct snd_soc_codec *codec,
- + enum wcd_cal_type type)
- +{
- + struct taiko_priv *taiko;
- + struct firmware_cal *hwdep_cal;
- +
- + if (!codec) {
- + pr_err("%s: NULL codec pointer\n", __func__);
- + return NULL;
- + }
- + taiko = snd_soc_codec_get_drvdata(codec);
- + hwdep_cal = wcdcal_get_fw_cal(taiko->fw_data, type);
- + if (!hwdep_cal) {
- + dev_err(codec->dev, "%s: cal not sent by %d\n",
- + __func__, type);
- + return NULL;
- + }
- +
- + return hwdep_cal;
- +}
- int taiko_hs_detect(struct snd_soc_codec *codec,
- struct wcd9xxx_mbhc_config *mbhc_cfg)
- @@ -7104,6 +6935,7 @@ static const struct wcd9xxx_mbhc_cb mbhc_cb = {
- .get_cdc_type = taiko_get_cdc_type,
- .setup_zdet = taiko_setup_zdet,
- .compute_impedance = taiko_compute_impedance,
- + .get_hwdep_fw_cal = taiko_get_hwdep_fw_cal,
- };
- static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
- @@ -7180,7 +7012,7 @@ static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
- ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
- taiko_enable_mbhc_micbias,
- &mbhc_cb, &cdc_intr_ids,
- - rco_clk_rate, false);
- + rco_clk_rate, true);
- if (ret)
- pr_err("%s: mbhc init failed %d\n", __func__, ret);
- else
- @@ -7320,9 +7152,6 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- struct wcd9xxx_pdata *pdata;
- struct wcd9xxx *wcd9xxx;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - extern unsigned int system_rev;
- -#endif
- int ret = 0;
- int i, rco_clk_rate;
- void *ptr = NULL;
- @@ -7360,7 +7189,7 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- WCD9XXX_CDC_TYPE_TAIKO);
- if (ret) {
- pr_err("%s: wcd9xxx init failed %d\n", __func__, ret);
- - goto err_init;
- + goto err_nomem_slimch;
- }
- taiko->clsh_d.buck_mv = taiko_codec_get_buck_mv(codec);
- @@ -7372,58 +7201,29 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- rco_clk_rate = TAIKO_MCLK_CLK_12P288MHZ;
- else
- rco_clk_rate = TAIKO_MCLK_CLK_9P6MHZ;
- -
- -#if defined(CONFIG_MACH_KLTE_KOR)
- - if (system_rev >= 13) {
- - /* init and start mbhc */
- - ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
- - taiko_enable_mbhc_micbias,
- - &mbhc_cb, &cdc_intr_ids,
- - rco_clk_rate, false);
- - if (ret) {
- - pr_err("%s: mbhc init failed %d\n", __func__, ret);
- - goto err_init;
- - }
- + taiko->fw_data = kzalloc(sizeof(*(taiko->fw_data)), GFP_KERNEL);
- + if (!taiko->fw_data) {
- + dev_err(codec->dev, "Failed to allocate fw_data\n");
- + goto err_nomem_slimch;
- }
- -#elif defined(CONFIG_MACH_KLTE_JPN)
- - if (system_rev >= 11) {
- - /* init and start mbhc */
- - ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
- - taiko_enable_mbhc_micbias,
- - &mbhc_cb, &cdc_intr_ids,
- - rco_clk_rate, false);
- - if (ret) {
- - pr_err("%s: mbhc init failed %d\n", __func__, ret);
- - goto err_init;
- - }
- + set_bit(WCD9XXX_ANC_CAL, taiko->fw_data->cal_bit);
- + set_bit(WCD9XXX_MAD_CAL, taiko->fw_data->cal_bit);
- + set_bit(WCD9XXX_MBHC_CAL, taiko->fw_data->cal_bit);
- + ret = wcd_cal_create_hwdep(taiko->fw_data,
- + WCD9XXX_CODEC_HWDEP_NODE, codec);
- + if (ret < 0) {
- + dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
- + goto err_hwdep;
- }
- -#else
- -#if !defined(CONFIG_SAMSUNG_JACK) && !defined(CONFIG_MUIC_DET_JACK)
- /* init and start mbhc */
- ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
- taiko_enable_mbhc_micbias,
- &mbhc_cb, &cdc_intr_ids,
- - rco_clk_rate, false);
- + rco_clk_rate, true);
- if (ret) {
- pr_err("%s: mbhc init failed %d\n", __func__, ret);
- - goto err_init;
- - }
- -#elif defined(CONFIG_SEC_JACTIVE_PROJECT)
- -/* init and start mbhc */
- - pr_info("taiko_codec_probe system_rev %d",system_rev);
- - if(system_rev < 3)
- - {
- - ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
- - taiko_enable_mbhc_micbias,
- - &mbhc_cb, &cdc_intr_ids,
- - rco_clk_rate, false);
- - if (ret) {
- - pr_err("%s: mbhc init failed %d\n", __func__, ret);
- - goto err_init;
- - }
- + goto err_hwdep;
- }
- -#endif
- -#endif
- taiko->codec = codec;
- for (i = 0; i < COMPANDER_MAX; i++) {
- @@ -7446,7 +7246,7 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- ret = taiko_handle_pdata(taiko);
- if (IS_ERR_VALUE(ret)) {
- pr_err("%s: bad pdata\n", __func__);
- - goto err_pdata;
- + goto err_hwdep;
- }
- taiko->spkdrv_reg = taiko_codec_find_regulator(codec,
- @@ -7459,18 +7259,12 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- WCD9XXX_BG_CLK_UNLOCK(&taiko->resmgr);
- }
- -#if defined(CONFIG_SND_SOC_ESXXX)
- - remote_add_codec_controls(codec);
- -#elif defined(CONFIG_SND_SOC_ES325)
- - es325_remote_add_codec_controls(codec);
- -#endif
- -
- ptr = kmalloc((sizeof(taiko_rx_chs) +
- sizeof(taiko_tx_chs)), GFP_KERNEL);
- if (!ptr) {
- pr_err("%s: no mem for slim chan ctl data\n", __func__);
- ret = -ENOMEM;
- - goto err_nomem_slimch;
- + goto err_hwdep;
- }
- if (taiko->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
- @@ -7548,19 +7342,17 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
- err_irq:
- taiko_cleanup_irqs(taiko);
- -err_pdata:
- - kfree(ptr);
- + kfree(ptr);
- +err_hwdep:
- + kfree(taiko->fw_data);
- err_nomem_slimch:
- kfree(taiko);
- -err_init:
- return ret;
- }
- static int taiko_codec_remove(struct snd_soc_codec *codec)
- {
- struct taiko_priv *taiko = snd_soc_codec_get_drvdata(codec);
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - extern unsigned int system_rev;
- -#endif
- +
- WCD9XXX_BG_CLK_LOCK(&taiko->resmgr);
- atomic_set(&kp_taiko_priv, 0);
- @@ -7571,33 +7363,14 @@ static int taiko_codec_remove(struct snd_soc_codec *codec)
- taiko_cleanup_irqs(taiko);
- -#if defined(CONFIG_MACH_KLTE_KOR)
- - if (system_rev >= 13) {
- - /* cleanup MBHC */
- - wcd9xxx_mbhc_deinit(&taiko->mbhc);
- - }
- -#elif defined(CONFIG_MACH_KLTE_JPN)
- - if (system_rev >= 11) {
- - /* cleanup MBHC */
- - wcd9xxx_mbhc_deinit(&taiko->mbhc);
- - }
- -#else
- -#if !defined(CONFIG_SAMSUNG_JACK) && !defined(CONFIG_MUIC_DET_JACK)
- /* cleanup MBHC */
- wcd9xxx_mbhc_deinit(&taiko->mbhc);
- -#elif defined(CONFIG_SEC_JACTIVE_PROJECT)
- - pr_info("taiko_codec_remove system_rev %d",system_rev);
- - if(system_rev < 3)
- - {
- - wcd9xxx_mbhc_deinit(&taiko->mbhc);
- - }
- -#endif
- -#endif
- /* cleanup resmgr */
- wcd9xxx_resmgr_deinit(&taiko->resmgr);
- taiko->spkdrv_reg = NULL;
- + kfree(taiko->fw_data);
- kfree(taiko);
- return 0;
- }
- diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
- index c4ed685..ea0c58f 100644
- --- a/sound/soc/codecs/wcd9xxx-mbhc.c
- +++ b/sound/soc/codecs/wcd9xxx-mbhc.c
- @@ -36,6 +36,7 @@
- #include <linux/kernel.h>
- #include <linux/gpio.h>
- #include <linux/input.h>
- +#include "wcdcal-hwdep.h"
- #include "wcd9320.h"
- #include "wcd9306.h"
- #include "wcd9xxx-mbhc.h"
- @@ -75,7 +76,7 @@
- #define OCP_ATTEMPT 1
- #define FW_READ_ATTEMPTS 15
- -#define FW_READ_TIMEOUT 2000000
- +#define FW_READ_TIMEOUT 4000000
- #define BUTTON_POLLING_SUPPORTED true
- @@ -189,6 +190,10 @@ static void wcd9xxx_get_z(struct wcd9xxx_mbhc *mbhc, s16 *dce_z, s16 *sta_z,
- static void wcd9xxx_mbhc_calc_thres(struct wcd9xxx_mbhc *mbhc);
- +static u16 wcd9xxx_codec_v_sta_dce(struct wcd9xxx_mbhc *mbhc,
- + enum meas_type dce, s16 vin_mv,
- + bool cs_enable);
- +
- static bool wcd9xxx_mbhc_polling(struct wcd9xxx_mbhc *mbhc)
- {
- return (snd_soc_read(mbhc->codec, WCD9XXX_A_CDC_MBHC_EN_CTL) & 0x1);
- @@ -1148,10 +1153,6 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
- struct snd_soc_codec *codec = mbhc->codec;
- short bias_value;
- u8 cfilt_mode;
- - s16 reg;
- - int change;
- - struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
- - s16 sta_z = 0, dce_z = 0;
- WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
- @@ -1161,7 +1162,6 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
- return -ENODEV;
- }
- - btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
- /* Enable external voltage source to micbias if present */
- if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
- mbhc->mbhc_cb->enable_mb_source(codec, true, true);
- @@ -1221,6 +1221,21 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
- snd_soc_write(codec, mbhc_micb_regs->cfilt_ctl, cfilt_mode);
- snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
- + return bias_value;
- +}
- +
- +static void wcd9xxx_recalibrate(struct wcd9xxx_mbhc *mbhc,
- + struct mbhc_micbias_regs *mbhc_micb_regs,
- + bool is_cs_enable)
- +{
- + struct snd_soc_codec *codec = mbhc->codec;
- + s16 reg;
- + int change;
- + struct wcd9xxx_mbhc_btn_detect_cfg *btn_det;
- + s16 sta_z = 0, dce_z = 0;
- +
- + btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
- +
- if (mbhc->mbhc_cfg->do_recalibration) {
- /* recalibrate dce_z and sta_z */
- reg = snd_soc_read(codec, WCD9XXX_A_CDC_MBHC_B1_CTL);
- @@ -1255,17 +1270,24 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
- snd_soc_write(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL,
- reg);
- if (dce_z) {
- - pr_debug("%s: dce_nsc_cs_z 0x%x -> 0x%x\n",
- - __func__, mbhc->mbhc_data.dce_nsc_cs_z,
- - dce_z & 0xffff);
- mbhc->mbhc_data.dce_nsc_cs_z = dce_z;
- + /* update v_cs_ins_h with new dce_nsc_cs_z */
- + mbhc->mbhc_data.v_cs_ins_h =
- + wcd9xxx_codec_v_sta_dce(
- + mbhc, DCE,
- + WCD9XXX_V_CS_HS_MAX,
- + is_cs_enable);
- + pr_debug("%s: dce_nsc_cs_z 0x%x -> 0x%x, v_cs_ins_h 0x%x\n",
- + __func__,
- + mbhc->mbhc_data.dce_nsc_cs_z,
- + dce_z & 0xffff,
- + mbhc->mbhc_data.v_cs_ins_h);
- } else {
- pr_debug("%s: failed get new dce_nsc_cs_z\n",
- __func__);
- }
- }
- }
- - return bias_value;
- }
- static void wcd9xxx_shutdown_hs_removal_detect(struct wcd9xxx_mbhc *mbhc)
- @@ -1822,6 +1844,9 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
- wcd9xxx_codec_hphr_gnd_switch(codec, false);
- }
- + /* recalibrate DCE/STA GND voltages */
- + wcd9xxx_recalibrate(mbhc, &mbhc->mbhc_bias_regs, true);
- +
- type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph,
- mbhc->event_state);
- @@ -1902,6 +1927,8 @@ wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph)
- if (rt[i].swap_gnd)
- wcd9xxx_codec_hphr_gnd_switch(codec, false);
- }
- + /* recalibrate DCE/STA GND voltages */
- + wcd9xxx_recalibrate(mbhc, &mbhc->mbhc_bias_regs, false);
- if (vddioon)
- __wcd9xxx_switch_micbias(mbhc, 1, false, false);
- @@ -2812,35 +2839,39 @@ static void wcd9xxx_mbhc_insert_work(struct work_struct *work)
- wcd9xxx_unlock_sleep(core_res);
- }
- -static bool wcd9xxx_mbhc_fw_validate(const struct firmware *fw)
- +static bool wcd9xxx_mbhc_fw_validate(const void *data, size_t size)
- {
- u32 cfg_offset;
- struct wcd9xxx_mbhc_imped_detect_cfg *imped_cfg;
- struct wcd9xxx_mbhc_btn_detect_cfg *btn_cfg;
- + struct firmware_cal fw;
- +
- + fw.data = (void *)data;
- + fw.size = size;
- - if (fw->size < WCD9XXX_MBHC_CAL_MIN_SIZE)
- + if (fw.size < WCD9XXX_MBHC_CAL_MIN_SIZE)
- return false;
- /*
- * Previous check guarantees that there is enough fw data up
- * to num_btn
- */
- - btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(fw->data);
- - cfg_offset = (u32) ((void *) btn_cfg - (void *) fw->data);
- - if (fw->size < (cfg_offset + WCD9XXX_MBHC_CAL_BTN_SZ(btn_cfg)))
- + btn_cfg = WCD9XXX_MBHC_CAL_BTN_DET_PTR(fw.data);
- + cfg_offset = (u32) ((void *) btn_cfg - (void *) fw.data);
- + if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_BTN_SZ(btn_cfg)))
- return false;
- /*
- * Previous check guarantees that there is enough fw data up
- * to start of impedance detection configuration
- */
- - imped_cfg = WCD9XXX_MBHC_CAL_IMPED_DET_PTR(fw->data);
- - cfg_offset = (u32) ((void *) imped_cfg - (void *) fw->data);
- + imped_cfg = WCD9XXX_MBHC_CAL_IMPED_DET_PTR(fw.data);
- + cfg_offset = (u32) ((void *) imped_cfg - (void *) fw.data);
- - if (fw->size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_MIN_SZ))
- + if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_MIN_SZ))
- return false;
- - if (fw->size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_SZ(imped_cfg)))
- + if (fw.size < (cfg_offset + WCD9XXX_MBHC_CAL_IMPED_SZ(imped_cfg)))
- return false;
- return true;
- @@ -4178,7 +4209,9 @@ static void wcd9xxx_mbhc_fw_read(struct work_struct *work)
- struct wcd9xxx_mbhc *mbhc;
- struct snd_soc_codec *codec;
- const struct firmware *fw;
- + struct firmware_cal *fw_data = NULL;
- int ret = -1, retry = 0;
- + bool use_default_cal = false;
- dwork = to_delayed_work(work);
- mbhc = container_of(dwork, struct wcd9xxx_mbhc, mbhc_firmware_dwork);
- @@ -4186,29 +4219,62 @@ static void wcd9xxx_mbhc_fw_read(struct work_struct *work)
- while (retry < FW_READ_ATTEMPTS) {
- retry++;
- - pr_info("%s:Attempt %d to request MBHC firmware\n",
- - __func__, retry);
- - ret = request_firmware(&fw, "wcd9320/wcd9320_mbhc.bin",
- - codec->dev);
- -
- - if (ret != 0) {
- + pr_debug("%s:Attempt %d to request MBHC firmware\n",
- + __func__, retry);
- + if (mbhc->mbhc_cb->get_hwdep_fw_cal)
- + fw_data = mbhc->mbhc_cb->get_hwdep_fw_cal(codec,
- + WCD9XXX_MBHC_CAL);
- + if (!fw_data)
- + ret = request_firmware(&fw, "wcd9320/wcd9320_mbhc.bin",
- + codec->dev);
- + /*
- + * if request_firmware and hwdep cal both fail then
- + * retry for few times before bailing out
- + */
- + if ((ret != 0) && !fw_data) {
- usleep_range(FW_READ_TIMEOUT, FW_READ_TIMEOUT);
- } else {
- pr_info("%s: MBHC Firmware read succesful\n", __func__);
- break;
- }
- }
- -
- - if (ret != 0) {
- + if (!fw_data)
- + pr_debug("%s: using request_firmware\n", __func__);
- + else
- + pr_debug("%s: using hwdep cal\n", __func__);
- + if (ret != 0 && !fw_data) {
- pr_err("%s: Cannot load MBHC firmware use default cal\n",
- - __func__);
- - } else if (wcd9xxx_mbhc_fw_validate(fw) == false) {
- - pr_err("%s: Invalid MBHC cal data size use default cal\n",
- - __func__);
- - release_firmware(fw);
- - } else {
- - mbhc->mbhc_cfg->calibration = (void *)fw->data;
- - mbhc->mbhc_fw = fw;
- + __func__);
- + use_default_cal = true;
- + }
- + if (!use_default_cal) {
- + const void *data;
- + size_t size;
- +
- + if (fw_data) {
- + data = fw_data->data;
- + size = fw_data->size;
- + } else {
- + data = fw->data;
- + size = fw->size;
- + }
- + if (wcd9xxx_mbhc_fw_validate(data, size) == false) {
- + pr_err("%s: Invalid MBHC cal data size use default cal\n",
- + __func__);
- + if (!fw_data)
- + release_firmware(fw);
- + } else {
- + if (fw_data) {
- + mbhc->mbhc_cfg->calibration =
- + (void *)fw_data->data;
- + mbhc->mbhc_cal = fw_data;
- + } else {
- + mbhc->mbhc_cfg->calibration =
- + (void *)fw->data;
- + mbhc->mbhc_fw = fw;
- + }
- + }
- +
- }
- (void) wcd9xxx_init_and_calibrate(mbhc);
- @@ -4398,15 +4464,16 @@ int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc,
- mbhc->mbhc_cb->enable_clock_gate(mbhc->codec, true);
- if (!mbhc->mbhc_cfg->read_fw_bin ||
- - (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw)) {
- + (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw) ||
- + (mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_cal)) {
- rc = wcd9xxx_init_and_calibrate(mbhc);
- } else {
- - if (!mbhc->mbhc_fw)
- + if (!mbhc->mbhc_fw || !mbhc->mbhc_cal)
- schedule_delayed_work(&mbhc->mbhc_firmware_dwork,
- usecs_to_jiffies(FW_READ_TIMEOUT));
- else
- - pr_debug("%s: Skipping to read mbhc fw, 0x%p\n",
- - __func__, mbhc->mbhc_fw);
- + pr_debug("%s: Skipping to read mbhc fw, 0x%p 0x%p\n",
- + __func__, mbhc->mbhc_fw, mbhc->mbhc_cal);
- }
- pr_debug("%s: leave %d\n", __func__, rc);
- @@ -4416,10 +4483,12 @@ EXPORT_SYMBOL(wcd9xxx_mbhc_start);
- void wcd9xxx_mbhc_stop(struct wcd9xxx_mbhc *mbhc)
- {
- - if (mbhc->mbhc_fw) {
- + if (mbhc->mbhc_fw || mbhc->mbhc_cal) {
- cancel_delayed_work_sync(&mbhc->mbhc_firmware_dwork);
- - release_firmware(mbhc->mbhc_fw);
- + if (!mbhc->mbhc_cal)
- + release_firmware(mbhc->mbhc_fw);
- mbhc->mbhc_fw = NULL;
- + mbhc->mbhc_cal = NULL;
- }
- }
- EXPORT_SYMBOL(wcd9xxx_mbhc_stop);
- diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h
- index 91edaca..7eba649 100644
- --- a/sound/soc/codecs/wcd9xxx-mbhc.h
- +++ b/sound/soc/codecs/wcd9xxx-mbhc.h
- @@ -13,6 +13,7 @@
- #define __WCD9XXX_MBHC_H__
- #include "wcd9xxx-resmgr.h"
- +#include "wcdcal-hwdep.h"
- #define WCD9XXX_CFILT_FAST_MODE 0x00
- #define WCD9XXX_CFILT_SLOW_MODE 0x40
- @@ -285,6 +286,9 @@ struct wcd9xxx_mbhc_cb {
- int (*enable_mb_source) (struct snd_soc_codec *, bool, bool);
- void (*setup_int_rbias) (struct snd_soc_codec *, bool);
- void (*pull_mb_to_vddio) (struct snd_soc_codec *, bool);
- + struct firmware_cal * (*get_hwdep_fw_cal) (struct snd_soc_codec *,
- + enum wcd_cal_type);
- +
- };
- struct wcd9xxx_mbhc {
- @@ -312,6 +316,7 @@ struct wcd9xxx_mbhc {
- const struct firmware *mbhc_fw;
- struct delayed_work mbhc_insert_dwork;
- + struct firmware_cal *mbhc_cal;
- u8 current_plug;
- struct work_struct correct_plug_swch;
- diff --git a/sound/soc/codecs/wcdcal-hwdep.c b/sound/soc/codecs/wcdcal-hwdep.c
- new file mode 100644
- index 0000000..1132a3c
- --- /dev/null
- +++ b/sound/soc/codecs/wcdcal-hwdep.c
- @@ -0,0 +1,221 @@
- +/*
- + * Copyright (c) 2014, 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/slab.h>
- +#include <linux/module.h>
- +#include <linux/ioctl.h>
- +#include <linux/bitops.h>
- +#include <sound/hwdep.h>
- +#include <sound/msmcal-hwdep.h>
- +#include <sound/soc.h>
- +#include "wcdcal-hwdep.h"
- +
- +const int cal_size_info[WCD9XXX_MAX_CAL] = {
- + [WCD9XXX_ANC_CAL] = 4096,
- + [WCD9XXX_MBHC_CAL] = 4096,
- + [WCD9XXX_MAD_CAL] = 4096,
- +};
- +
- +const char *cal_name_info[WCD9XXX_MAX_CAL] = {
- + [WCD9XXX_ANC_CAL] = "anc",
- + [WCD9XXX_MBHC_CAL] = "mbhc",
- + [WCD9XXX_MAD_CAL] = "mad",
- +};
- +
- +struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data,
- + enum wcd_cal_type type)
- +{
- + if (!fw_data) {
- + pr_err("%s: fw_data is NULL\n", __func__);
- + return NULL;
- + }
- + if (type >= WCD9XXX_MAX_CAL ||
- + type < WCD9XXX_MIN_CAL) {
- + pr_err("%s: wrong cal type sent %d\n", __func__, type);
- + return NULL;
- + }
- + mutex_lock(&fw_data->lock);
- + if (!test_bit(WCDCAL_RECIEVED,
- + &fw_data->wcdcal_state[type])) {
- + pr_err("%s: cal not sent by userspace %d\n",
- + __func__, type);
- + mutex_unlock(&fw_data->lock);
- + return NULL;
- + }
- + mutex_unlock(&fw_data->lock);
- + return fw_data->fw[type];
- +}
- +EXPORT_SYMBOL(wcdcal_get_fw_cal);
- +
- +static int wcdcal_hwdep_ioctl_shared(struct snd_hwdep *hw,
- + struct wcdcal_ioctl_buffer fw_user)
- +{
- + struct fw_info *fw_data = hw->private_data;
- + struct firmware_cal **fw = fw_data->fw;
- + void *data;
- +
- + if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
- + pr_err("%s: codec didn't set this %d!!\n",
- + __func__, fw_user.cal_type);
- + return -EFAULT;
- + }
- + if (fw_user.cal_type >= WCD9XXX_MAX_CAL ||
- + fw_user.cal_type < WCD9XXX_MIN_CAL) {
- + pr_err("%s: wrong cal type sent %d\n",
- + __func__, fw_user.cal_type);
- + return -EFAULT;
- + }
- + if (fw_user.size > cal_size_info[fw_user.cal_type] ||
- + fw_user.size <= 0) {
- + pr_err("%s: incorrect firmware size %d for %s\n",
- + __func__, fw_user.size,
- + cal_name_info[fw_user.cal_type]);
- + return -EFAULT;
- + }
- + data = fw[fw_user.cal_type]->data;
- + memcpy(data, fw_user.buffer, fw_user.size);
- + fw[fw_user.cal_type]->size = fw_user.size;
- + mutex_lock(&fw_data->lock);
- + set_bit(WCDCAL_RECIEVED, &fw_data->wcdcal_state[fw_user.cal_type]);
- + mutex_unlock(&fw_data->lock);
- + return 0;
- +}
- +
- +#ifdef CONFIG_COMPAT
- +struct wcdcal_ioctl_buffer32 {
- + u32 size;
- + compat_uptr_t buffer;
- + enum wcd_cal_type cal_type;
- +};
- +
- +enum {
- + SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32 =
- + _IOW('U', 0x1, struct wcdcal_ioctl_buffer32),
- +};
- +
- +static int wcdcal_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
- + unsigned int cmd, unsigned long arg)
- +{
- + struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg;
- + struct wcdcal_ioctl_buffer32 fw_user32;
- + struct wcdcal_ioctl_buffer fw_user_compat;
- +
- + if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32) {
- + pr_err("%s: wrong ioctl command sent %u!\n", __func__, cmd);
- + return -ENOIOCTLCMD;
- + }
- + if (copy_from_user(&fw_user32, argp, sizeof(fw_user32))) {
- + pr_err("%s: failed to copy\n", __func__);
- + return -EFAULT;
- + }
- + fw_user_compat.size = fw_user32.size;
- + fw_user_compat.buffer = compat_ptr(fw_user32.buffer);
- + fw_user_compat.cal_type = fw_user32.cal_type;
- + return wcdcal_hwdep_ioctl_shared(hw, fw_user_compat);
- +}
- +#else
- +#define wcdcal_hwdep_ioctl_compat NULL
- +#endif
- +
- +static int wcdcal_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- + unsigned int cmd, unsigned long arg)
- +{
- + struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg;
- + struct wcdcal_ioctl_buffer fw_user;
- +
- + if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE) {
- + pr_err("%s: wrong ioctl command sent %d!\n", __func__, cmd);
- + return -ENOIOCTLCMD;
- + }
- + if (copy_from_user(&fw_user, argp, sizeof(fw_user))) {
- + pr_err("%s: failed to copy\n", __func__);
- + return -EFAULT;
- + }
- + return wcdcal_hwdep_ioctl_shared(hw, fw_user);
- +}
- +
- +static int wcdcal_hwdep_release(struct snd_hwdep *hw, struct file *file)
- +{
- + struct fw_info *fw_data = hw->private_data;
- + mutex_lock(&fw_data->lock);
- + /* clear all the calibrations */
- + memset(fw_data->wcdcal_state, 0,
- + sizeof(fw_data->wcdcal_state));
- + mutex_unlock(&fw_data->lock);
- + return 0;
- +}
- +
- +int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec)
- +{
- + char hwname[40];
- + struct snd_hwdep *hwdep;
- + struct firmware_cal **fw;
- + struct fw_info *fw_data = data;
- + int err, cal_bit;
- +
- + if (!fw_data || !codec) {
- + pr_err("%s: wrong arguments passed\n", __func__);
- + return -EINVAL;
- + }
- +
- + fw = fw_data->fw;
- + snprintf(hwname, strlen("Codec %s"), "Codec %s", codec->name);
- + err = snd_hwdep_new(codec->card->snd_card, hwname, node, &hwdep);
- + if (err < 0) {
- + dev_err(codec->dev, "%s: new hwdep failed %d\n",
- + __func__, err);
- + return err;
- + }
- + snprintf(hwdep->name, strlen("Codec %s"), "Codec %s", codec->name);
- + hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_CODEC;
- + hwdep->private_data = fw_data;
- + hwdep->ops.ioctl_compat = wcdcal_hwdep_ioctl_compat;
- + hwdep->ops.ioctl = wcdcal_hwdep_ioctl;
- + hwdep->ops.release = wcdcal_hwdep_release;
- + mutex_init(&fw_data->lock);
- +
- + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
- + set_bit(WCDCAL_UNINITIALISED,
- + &fw_data->wcdcal_state[cal_bit]);
- + fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL);
- + if (!fw[cal_bit]) {
- + dev_err(codec->dev, "%s: no memory for %s cal\n",
- + __func__, cal_name_info[cal_bit]);
- + goto end;
- + }
- + }
- + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
- + fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit],
- + GFP_KERNEL);
- + if (!fw[cal_bit]->data) {
- + dev_err(codec->dev, "%s: no memory for %s cal data\n",
- + __func__, cal_name_info[cal_bit]);
- + goto exit;
- + }
- + set_bit(WCDCAL_INITIALISED,
- + &fw_data->wcdcal_state[cal_bit]);
- + }
- + return 0;
- +exit:
- + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
- + kfree(fw[cal_bit]->data);
- + fw[cal_bit]->data = NULL;
- + }
- +end:
- + for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
- + kfree(fw[cal_bit]);
- + fw[cal_bit] = NULL;
- + }
- + return -ENOMEM;
- +}
- +EXPORT_SYMBOL(wcd_cal_create_hwdep);
- diff --git a/sound/soc/codecs/wcdcal-hwdep.h b/sound/soc/codecs/wcdcal-hwdep.h
- new file mode 100644
- index 0000000..632e2f1
- --- /dev/null
- +++ b/sound/soc/codecs/wcdcal-hwdep.h
- @@ -0,0 +1,40 @@
- +/*
- + * Copyright (c) 2014, 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 __WCD9XXX_HWDEP_H__
- +#define __WCD9XXX_HWDEP_H__
- +#include <sound/msmcal-hwdep.h>
- +
- +enum wcd_cal_states {
- + WCDCAL_UNINITIALISED,
- + WCDCAL_INITIALISED,
- + WCDCAL_RECIEVED
- +};
- +
- +struct fw_info {
- + struct firmware_cal *fw[WCD9XXX_MAX_CAL];
- + DECLARE_BITMAP(cal_bit, WCD9XXX_MAX_CAL);
- + /* for calibration tracking */
- + unsigned long wcdcal_state[WCD9XXX_MAX_CAL];
- + struct mutex lock;
- +};
- +
- +struct firmware_cal {
- + u8 *data;
- + size_t size;
- +};
- +
- +struct snd_soc_codec;
- +int wcd_cal_create_hwdep(void *fw, int node, struct snd_soc_codec *codec);
- +struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data,
- + enum wcd_cal_type type);
- +#endif /* __WCD9XXX_HWDEP_H__ */
- diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
- index 7bb86d9e..7fe63cb 100644
- --- a/sound/soc/msm/Kconfig
- +++ b/sound/soc/msm/Kconfig
- @@ -183,6 +183,7 @@ config SND_SOC_MSM8974
- select SND_DYNAMIC_MINORS
- select AUDIO_OCMEM
- select DOLBY_DAP
- + select SND_HWDEP
- help
- To add support for SoC audio on MSM8974.
- This will enable sound soc drivers which
- diff --git a/sound/soc/msm/msm-pcm-loopback.c b/sound/soc/msm/msm-pcm-loopback.c
- index ecf8394..f2024d8 100644
- --- a/sound/soc/msm/msm-pcm-loopback.c
- +++ b/sound/soc/msm/msm-pcm-loopback.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2014, 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
- @@ -200,19 +200,23 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
- static void stop_pcm(struct msm_pcm_loopback *pcm)
- {
- - struct snd_soc_pcm_runtime *soc_pcm_rx =
- - pcm->playback_substream->private_data;
- - struct snd_soc_pcm_runtime *soc_pcm_tx =
- - pcm->capture_substream->private_data;
- + struct snd_soc_pcm_runtime *soc_pcm_rx;
- + struct snd_soc_pcm_runtime *soc_pcm_tx;
- if (pcm->audio_client == NULL)
- return;
- q6asm_cmd(pcm->audio_client, CMD_CLOSE);
- - msm_pcm_routing_dereg_phy_stream(soc_pcm_rx->dai_link->be_id,
- - SNDRV_PCM_STREAM_PLAYBACK);
- - msm_pcm_routing_dereg_phy_stream(soc_pcm_tx->dai_link->be_id,
- - SNDRV_PCM_STREAM_CAPTURE);
- + if (pcm->playback_substream != NULL) {
- + soc_pcm_rx = pcm->playback_substream->private_data;
- + msm_pcm_routing_dereg_phy_stream(soc_pcm_rx->dai_link->be_id,
- + SNDRV_PCM_STREAM_PLAYBACK);
- + }
- + if (pcm->capture_substream != NULL) {
- + soc_pcm_tx = pcm->capture_substream->private_data;
- + msm_pcm_routing_dereg_phy_stream(soc_pcm_tx->dai_link->be_id,
- + SNDRV_PCM_STREAM_CAPTURE);
- + }
- q6asm_audio_client_free(pcm->audio_client);
- pcm->audio_client = NULL;
- }
- diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
- index 0009a49..40b4f0d 100644
- --- a/sound/soc/msm/msm8226.c
- +++ b/sound/soc/msm/msm8226.c
- @@ -495,7 +495,7 @@ static const struct soc_enum msm_enum[] = {
- SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
- };
- -static const char *const btsco_rate_text[] = {"8000", "16000"};
- +static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ", "BTSCO_RATE_16KHZ"};
- static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
- };
- diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
- index 05e0b0d..1a37e45 100644
- --- a/sound/soc/msm/msm8974.c
- +++ b/sound/soc/msm/msm8974.c
- @@ -34,11 +34,6 @@
- #include "../codecs/wcd9xxx-common.h"
- #include "../codecs/wcd9320.h"
- -#if defined(CONFIG_SND_SOC_ES705)
- -#include "../codecs/audience/es705-export.h"
- -#elif defined(CONFIG_SND_SOC_ES325)
- -#include "../codecs/es325-export.h"
- -#endif
- #define DRV_NAME "msm8974-asoc-taiko"
- #define MSM8974_SPK_ON 1
- @@ -67,7 +62,7 @@ static int msm8974_auxpcm_rate = 8000;
- #define I2S_PCM_SEL 1
- #define I2S_PCM_SEL_OFFSET 1
- -#define WCD9XXX_MBHC_DEF_BUTTONS 3
- +#define WCD9XXX_MBHC_DEF_BUTTONS 8
- #define WCD9XXX_MBHC_DEF_RLOADS 5
- #define TAIKO_EXT_CLK_RATE 9600000
- @@ -81,12 +76,6 @@ static int msm8974_auxpcm_rate = 8000;
- #define EXT_CLASS_AB_DIS_DELAY 1000
- #define EXT_CLASS_AB_DELAY_DELTA 1000
- -#if defined (CONFIG_SND_SOC_MAX98504)
- -#define GPIO_SECOND_MI2S_SCK 79
- -#define GPIO_SECOND_MI2S_WS 80
- -#define GPIO_SECOND_MI2S_DATA0 81
- -#define GPIO_SECOND_MI2S_DATA1 82
- -#endif
- #define NUM_OF_AUXPCM_GPIOS 4
- static void *adsp_state_notifier;
- @@ -126,12 +115,7 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
- bool dapm);
- static struct wcd9xxx_mbhc_config mbhc_cfg = {
- -#if defined(CONFIG_MACH_KS01EUR) || defined(CONFIG_MACH_KS01SKT) || \
- -defined(CONFIG_MACH_KS01KTT) || defined(CONFIG_MACH_KS01LGT)
- .read_fw_bin = false,
- -#else
- - .read_fw_bin = true,
- -#endif
- .calibration = NULL,
- .micbias = MBHC_MICBIAS2,
- .anc_micbias = MBHC_MICBIAS2,
- @@ -139,23 +123,16 @@ defined(CONFIG_MACH_KS01KTT) || defined(CONFIG_MACH_KS01LGT)
- .mclk_rate = TAIKO_EXT_CLK_RATE,
- .gpio = 0,
- .gpio_irq = 0,
- - .gpio_level_insert = 0,
- + .gpio_level_insert = 1,
- .detect_extn_cable = true,
- -#if defined(CONFIG_SEC_FACTORY)
- - /* Micbias for MBHC is always on in factory test */
- - .micbias_enable_flags = (1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET |
- - 1 << MBHC_MICBIAS_ENABLE_REGULAR_HEADSET),
- -#else
- .micbias_enable_flags = 1 << MBHC_MICBIAS_ENABLE_THRESHOLD_HEADSET,
- -#endif
- .insert_detect = true,
- .swap_gnd_mic = NULL,
- -#if (defined(CONFIG_MACH_KLTE_KOR) || defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KACTIVELTE_DCM) || defined(CONFIG_MACH_CHAGALL_KDI) || defined(CONFIG_MACH_KLIMT_LTE_DCM)) && !defined(CONFIG_SEC_FACTORY)
- - .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING),
- -#else
- - .cs_enable_flags = 0,
- -#endif
- - .do_recalibration = false,
- + .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING |
- + 1 << MBHC_CS_ENABLE_INSERTION |
- + 1 << MBHC_CS_ENABLE_REMOVAL |
- + 1 << MBHC_CS_ENABLE_DET_ANC),
- + .do_recalibration = true,
- .use_vddio_meas = true,
- .enable_anc_mic_detect = false,
- .hw_jack_type = SIX_POLE_JACK,
- @@ -239,61 +216,7 @@ static struct clk *codec_clk;
- static int clk_users;
- static atomic_t prim_auxpcm_rsc_ref;
- static atomic_t sec_auxpcm_rsc_ref;
- -static int mainmic_bias_gpio = 0;
- -static int micbias_en_msm_gpio = 0;
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- -static int submic_bias_gpio = 0;
- -#endif
- -#if defined(CONFIG_LDO_EARMIC_BIAS)
- -static int earmic_bias_gpio = 0;
- -#endif
- -
- -static int spkamp_en_gpio = 0;
- -static int main_mic_delay = 0;
- -#ifdef CONFIG_SEC_JACTIVE_PROJECT
- -static int ear_jack_fsa8038_en = 0;
- -#endif
- -#if defined(CONFIG_SEC_H_PROJECT)
- -int speaker_status = 0;
- -EXPORT_SYMBOL(speaker_status);
- -#endif
- -#if defined(CONFIG_MACH_KLTE_KOR) || defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KACTIVELTE_DCM) || defined(CONFIG_MACH_CHAGALL_KDI) || defined(CONFIG_MACH_KLIMT_LTE_DCM)
- -static int fsa_en_gpio;
- -#endif
- -
- -#if defined (CONFIG_SND_SOC_MAX98504)
- -struct request_gpio {
- - unsigned gpio_no;
- - char *gpio_name;
- -};
- -static struct request_gpio pri_mi2s_gpio[] = {
- - {
- - .gpio_no = GPIO_SECOND_MI2S_SCK,
- - .gpio_name = "SECOND_MI2S_SCK",
- - },
- - {
- - .gpio_no = GPIO_SECOND_MI2S_WS,
- - .gpio_name = "SECOND_MI2S_WS",
- - },
- - {
- - .gpio_no = GPIO_SECOND_MI2S_DATA0,
- - .gpio_name = "SECOND_MI2S_DATA0",
- - },
- - {
- - .gpio_no = GPIO_SECOND_MI2S_DATA1,
- - .gpio_name = "SECOND_MI2S_DATA1",
- - },
- -};
- -/* MI2S clock */
- -struct mi2s_clk {
- - struct clk *core_clk;
- - struct clk *osr_clk;
- - struct clk *bit_clk;
- - atomic_t mi2s_rsc_ref;
- -};
- -static struct mi2s_clk pri_mi2s_clk;
- -#endif
- static int msm8974_liquid_ext_spk_power_amp_init(void)
- {
- @@ -467,22 +390,20 @@ static int msm8974_liquid_init_docking(struct snd_soc_dapm_context *dapm)
- msm8974_liquid_dock_dev->dapm = dapm;
- - INIT_WORK(
- - &msm8974_liquid_dock_dev->irq_work,
- - msm8974_liquid_docking_irq_work);
- -
- ret = request_irq(msm8974_liquid_dock_dev->dock_plug_irq,
- msm8974_liquid_docking_irq_handler,
- dock_plug_irq_flags,
- "liquid_dock_plug_irq",
- msm8974_liquid_dock_dev);
- + INIT_WORK(
- + &msm8974_liquid_dock_dev->irq_work,
- + msm8974_liquid_docking_irq_work);
- }
- return 0;
- }
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_V2_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_MACH_MONDRIAN) && !defined(CONFIG_MACH_CHAGALL) && !defined(CONFIG_MACH_KLIMT)
- static int msm8974_liquid_ext_spk_power_amp_on(u32 spk)
- {
- int rc;
- @@ -589,7 +510,6 @@ static void msm8974_ext_spk_power_amp_off(u32 spk)
- else if (gpio_is_valid(ext_ult_lo_amp_gpio))
- msm8974_fluid_ext_us_amp_off(spk);
- }
- -#endif
- static void msm8974_ext_control(struct snd_soc_codec *codec)
- {
- @@ -637,7 +557,6 @@ static int msm8974_set_spk(struct snd_kcontrol *kcontrol,
- }
- -#if !defined(CONFIG_MACH_VIENNA_LTE) && !defined(CONFIG_MACH_V2_LTE) && !defined(CONFIG_MACH_LT03_LTE) && !defined(CONFIG_MACH_PICASSO_LTE) && !defined(CONFIG_MACH_MONDRIAN) && !defined(CONFIG_MACH_CHAGALL) && !defined(CONFIG_MACH_KLIMT)
- static int msm_ext_spkramp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
- {
- @@ -676,18 +595,6 @@ static int msm_ext_spkramp_event(struct snd_soc_dapm_widget *w,
- return 0;
- }
- -#else
- -static int msm_ext_spkramp_event(struct snd_soc_dapm_widget *w,
- - struct snd_kcontrol *k, int event)
- -{
- - pr_info("%s() : control =%d\n", __func__, event);
- -
- - gpio_direction_output(spkamp_en_gpio,
- - SND_SOC_DAPM_EVENT_ON(event));
- -
- - return 0;
- -}
- -#endif
- static int msm_ext_spkramp_ultrasound_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
- @@ -777,63 +684,6 @@ static int msm8974_mclk_event(struct snd_soc_dapm_widget *w,
- return 0;
- }
- -#if !defined(CONFIG_SEC_KS01_PROJECT)
- -static int msm_mainmic_bias_event(struct snd_soc_dapm_widget *w,
- - struct snd_kcontrol *k, int event)
- -{
- - pr_info("%s : Event %d, SND_SOC_DAPM:%d\n",
- - __func__, (event), SND_SOC_DAPM_EVENT_ON(event));
- -
- - if (mainmic_bias_gpio < 0) {
- - gpio_set_value_cansleep(micbias_en_msm_gpio,
- - SND_SOC_DAPM_EVENT_ON(event));
- - } else {
- - gpio_direction_output(mainmic_bias_gpio,
- - SND_SOC_DAPM_EVENT_ON(event));
- - }
- -
- - if(main_mic_delay) {
- - if(main_mic_delay != 100)
- - main_mic_delay *= 50;
- - msleep(main_mic_delay);
- - pr_info("%s: main_mic_delay = %d\n", __func__, main_mic_delay);
- - main_mic_delay = 0;
- - }
- -
- - return 0;
- -}
- -#endif
- -
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- -static int msm_submic_bias_event(struct snd_soc_dapm_widget *w,
- - struct snd_kcontrol *k, int event)
- -{
- - pr_info("%s : Event %d, SND_SOC_DAPM:%d\n",
- - __func__, (event), SND_SOC_DAPM_EVENT_ON(event));
- -
- - gpio_direction_output(submic_bias_gpio,
- - SND_SOC_DAPM_EVENT_ON(event));
- -
- - return 0;
- -}
- -#endif
- -
- -#if defined(CONFIG_LDO_EARMIC_BIAS)
- -static int msm_earmic_bias_event(struct snd_soc_dapm_widget *w,
- - struct snd_kcontrol *k, int event)
- -{
- - pr_info("%s : Event %d, SND_SOC_DAPM:%d\n",
- - __func__, (event), SND_SOC_DAPM_EVENT_ON(event));
- -
- - gpio_direction_output(earmic_bias_gpio,
- - SND_SOC_DAPM_EVENT_ON(event));
- -
- - return 0;
- -}
- -#endif
- -
- -
- -#ifdef CONFIG_SEC_K_PROJECT
- static const struct snd_soc_dapm_widget msm8974_dapm_widgets[] = {
- SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
- @@ -856,101 +706,12 @@ static const struct snd_soc_dapm_widget msm8974_dapm_widgets[] = {
- SND_SOC_DAPM_MIC("Analog Mic7", NULL),
- SND_SOC_DAPM_MIC("Digital Mic1", NULL),
- - SND_SOC_DAPM_MIC("Main Mic", msm_mainmic_bias_event),
- - SND_SOC_DAPM_MIC("Digital Mic3", NULL),
- - SND_SOC_DAPM_MIC("Sub Mic", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic5", NULL),
- - SND_SOC_DAPM_MIC("Third Mic", NULL),
- -};
- -#elif defined (CONFIG_SEC_JACTIVE_PROJECT)
- -static const struct snd_soc_dapm_widget msm8974_dapm_widgets_01[] = {
- -
- - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
- - msm8974_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- -
- - SND_SOC_DAPM_SPK("Lineout_1 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_3 amp", msm_ext_spkramp_event),
- -
- - SND_SOC_DAPM_SPK("Lineout_2 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_4 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("SPK_ultrasound amp",
- - msm_ext_spkramp_ultrasound_event),
- -
- - SND_SOC_DAPM_MIC("Main Mic", NULL),
- - SND_SOC_DAPM_MIC("Headset Mic", NULL),
- - SND_SOC_DAPM_MIC("Sub Mic", NULL),
- - SND_SOC_DAPM_MIC("Third Mic", NULL),
- -
- - SND_SOC_DAPM_MIC("Digital Mic1", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic2", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic3", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic4", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic5", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic6", NULL),
- -};
- -
- -static const struct snd_soc_dapm_widget msm8974_dapm_widgets[] = {
- -
- - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
- - msm8974_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- -
- - SND_SOC_DAPM_SPK("Lineout_1 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_3 amp", msm_ext_spkramp_event),
- -
- - SND_SOC_DAPM_SPK("Lineout_2 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_4 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("SPK_ultrasound amp",
- - msm_ext_spkramp_ultrasound_event),
- - SND_SOC_DAPM_MIC("Main Mic", msm_mainmic_bias_event),
- - SND_SOC_DAPM_MIC("Headset Mic", NULL),
- - SND_SOC_DAPM_MIC("Sub Mic", NULL),
- - SND_SOC_DAPM_MIC("Third Mic", NULL),
- -
- - SND_SOC_DAPM_MIC("Digital Mic1", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic2", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic3", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic4", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic5", NULL),
- - SND_SOC_DAPM_MIC("Digital Mic6", NULL),
- -};
- -#else
- -static const struct snd_soc_dapm_widget msm8974_dapm_widgets[] = {
- -
- - SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
- - msm8974_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- -
- - SND_SOC_DAPM_SPK("Lineout_1 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_3 amp", msm_ext_spkramp_event),
- -
- - SND_SOC_DAPM_SPK("Lineout_2 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("Lineout_4 amp", msm_ext_spkramp_event),
- - SND_SOC_DAPM_SPK("SPK_ultrasound amp",
- - msm_ext_spkramp_ultrasound_event),
- -#if defined(CONFIG_SEC_KS01_PROJECT)
- - SND_SOC_DAPM_MIC("Main Mic", NULL),
- -#else
- - SND_SOC_DAPM_MIC("Main Mic", msm_mainmic_bias_event),
- -#endif
- -#if defined(CONFIG_LDO_EARMIC_BIAS)
- - SND_SOC_DAPM_MIC("Headset Mic", msm_earmic_bias_event),
- -#else
- - SND_SOC_DAPM_MIC("Headset Mic", NULL),
- -#endif
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- - SND_SOC_DAPM_MIC("Sub Mic", msm_submic_bias_event),
- -#else
- - SND_SOC_DAPM_MIC("Sub Mic", NULL),
- -#endif
- - SND_SOC_DAPM_MIC("Third Mic", NULL),
- -
- - SND_SOC_DAPM_MIC("Digital Mic1", NULL),
- SND_SOC_DAPM_MIC("Digital Mic2", NULL),
- SND_SOC_DAPM_MIC("Digital Mic3", NULL),
- SND_SOC_DAPM_MIC("Digital Mic4", NULL),
- SND_SOC_DAPM_MIC("Digital Mic5", NULL),
- SND_SOC_DAPM_MIC("Digital Mic6", NULL),
- };
- -#endif
- static const char *const spk_function[] = {"Off", "On"};
- static const char *const slim0_rx_ch_text[] = {"One", "Two"};
- @@ -967,8 +728,7 @@ static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four",
- static char const *hdmi_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
- "KHZ_192"};
- -
- -static const char *const btsco_rate_text[] = {"8000", "16000"};
- +static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ", "BTSCO_RATE_16KHZ"};
- static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
- };
- @@ -1018,7 +778,7 @@ static int slim0_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
- slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
- }
- - pr_info("%s: slim0_rx_sample_rate = %d\n", __func__,
- + pr_debug("%s: slim0_rx_sample_rate = %d\n", __func__,
- slim0_rx_sample_rate);
- return 0;
- @@ -1110,10 +870,10 @@ static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- switch (ucontrol->value.integer.value[0]) {
- - case 8000:
- + case 0:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
- break;
- - case 16000:
- + case 1:
- msm_btsco_rate = BTSCO_RATE_16KHZ;
- break;
- default:
- @@ -1239,11 +999,6 @@ static int hdmi_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
- return 0;
- }
- -static const struct snd_kcontrol_new int_btsco_rate_mixer_controls[] = {
- - SOC_ENUM_EXT("Internal BTSCO SampleRate", msm_btsco_enum[0],
- - msm_btsco_rate_get, msm_btsco_rate_put),
- -};
- -
- static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
- {
- @@ -1272,58 +1027,16 @@ static int msm8974_auxpcm_rate_put(struct snd_kcontrol *kcontrol,
- switch (ucontrol->value.integer.value[0]) {
- case 0:
- msm8974_auxpcm_rate = 8000;
- - msm_btsco_rate = BTSCO_RATE_8KHZ;
- break;
- case 1:
- msm8974_auxpcm_rate = 16000;
- - msm_btsco_rate = BTSCO_RATE_16KHZ;
- break;
- default:
- msm8974_auxpcm_rate = 8000;
- - msm_btsco_rate = BTSCO_RATE_8KHZ;
- break;
- }
- - pr_info("%s: BT sample rate = %d ====\n",__func__, msm8974_auxpcm_rate);
- return 0;
- }
- -
- -static int main_mic_delay_get(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - pr_debug("%s: main_mic_delay = %d\n", __func__,
- - main_mic_delay);
- - ucontrol->value.integer.value[0] = main_mic_delay;
- - return 0;
- -}
- -
- -static int main_mic_delay_put(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - main_mic_delay = ucontrol->value.integer.value[0];
- -
- - pr_debug("%s: main_mic_delay = %d\n", __func__,
- - main_mic_delay);
- - return 1;
- -}
- -
- -#if defined(CONFIG_SEC_H_PROJECT)
- -static int speaker_status_get(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - pr_info("%s: speaker_status = %d\n", __func__, speaker_status);
- - ucontrol->value.integer.value[0] = speaker_status;
- - return 0;
- -}
- -
- -static int speaker_status_put(struct snd_kcontrol *kcontrol,
- - struct snd_ctl_elem_value *ucontrol)
- -{
- - speaker_status = ucontrol->value.integer.value[0];
- - pr_info("%s: speaker_status = %d\n", __func__, speaker_status);
- - return 1;
- -}
- -#endif
- -
- static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- @@ -1357,22 +1070,6 @@ static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
- return 0;
- }
- -#if defined( CONFIG_PCM_ROUTE_VOICE_STUB ) || defined(CONFIG_BT_CALL_FORWARDING)
- -static int msm_auxpcm2_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
- - struct snd_pcm_hw_params *params)
- -{
- - struct snd_interval *rate =
- - hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- -
- - struct snd_interval *channels =
- - hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- -
- - rate->min = rate->max = 8000;
- - channels->min = channels->max = 1;
- -
- - return 0;
- -}
- -#endif
- static int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
- {
- @@ -1410,7 +1107,7 @@ static int msm8974_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_interval *channels = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
- - pr_info("%s channels->min %u channels->max %u ()\n", __func__,
- + pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
- channels->min, channels->max);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- @@ -1418,9 +1115,7 @@ static int msm8974_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- if (channels->max < 2)
- channels->min = channels->max = 2;
- rate->min = rate->max = hdmi_rx_sample_rate;
- -
- - if (channels->min != channels->max)
- - channels->min = channels->max;
- + channels->min = channels->max = msm_hdmi_rx_ch;
- return 0;
- }
- @@ -1606,7 +1301,7 @@ static int msm_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- rate->min = rate->max = slim0_rx_sample_rate;
- channels->min = channels->max = msm_slim_0_rx_ch;
- - pr_info("%s: format = %d, rate = %d, channels = %d\n",
- + pr_debug("%s: format = %d, rate = %d, channels = %d\n",
- __func__, params_format(params), params_rate(params),
- msm_slim_0_rx_ch);
- @@ -1628,10 +1323,6 @@ static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- rate->min = rate->max = 48000;
- channels->min = channels->max = msm_slim_0_tx_ch;
- - pr_info("%s: format = %d, rate = %d, channels = %d\n",
- - __func__, params_format(params), params_rate(params),
- - msm_slim_0_tx_ch);
- -
- return 0;
- }
- @@ -1690,29 +1381,6 @@ static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- return 0;
- }
- -#if defined(CONFIG_SND_SOC_MAX98504) || defined(CONFIG_SND_SOC_MAX98505)
- -static int msm8974_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- - struct snd_pcm_hw_params *params)
- -{
- - struct snd_interval *rate = hw_param_interval(params,
- - SNDRV_PCM_HW_PARAM_RATE);
- - struct snd_interval *channels = hw_param_interval(params,
- - SNDRV_PCM_HW_PARAM_CHANNELS);
- - pr_debug("%s: enter\n", __func__);
- -
- - rate->min = rate->max = 48000;
- -
- -
- - param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- - SNDRV_PCM_FORMAT_S16_LE);
- -
- - channels->min = channels->max = 2;
- -
- - return 0;
- -}
- -#endif
- -
- -
- static int msm_be_fm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
- {
- @@ -1763,12 +1431,6 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
- msm_btsco_rate_get, msm_btsco_rate_put),
- SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[7],
- hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put),
- - SOC_SINGLE_EXT("Main Mic Delay",SND_SOC_NOPM, 0, 100, 0,
- - main_mic_delay_get, main_mic_delay_put),
- -#if defined(CONFIG_SEC_H_PROJECT)
- - SOC_SINGLE_EXT("SPK Status",SND_SOC_NOPM, 0, 1, 0,
- - speaker_status_get, speaker_status_put),
- -#endif
- };
- static bool msm8974_swap_gnd_mic(struct snd_soc_codec *codec)
- @@ -1876,10 +1538,6 @@ static int msm8974_taiko_event_cb(struct snd_soc_codec *codec,
- }
- }
- -#if defined(CONFIG_MACH_KLTE_KOR) || defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KACTIVELTE_DCM) || defined(CONFIG_MACH_CHAGALL_KDI) || defined(CONFIG_MACH_KLIMT_LTE_DCM)
- -extern unsigned int system_rev;
- -#endif
- -
- static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- {
- int err;
- @@ -1888,9 +1546,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- struct snd_soc_dapm_context *dapm = &codec->dapm;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - extern unsigned int system_rev;
- -#endif
- /* Taiko SLIMBUS configuration
- * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
- @@ -1926,21 +1581,10 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- __func__, err);
- return err;
- }
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - pr_info("1. msm_audrx_init system_rev %d",system_rev);
- - if(system_rev < 3) {
- - snd_soc_dapm_new_controls(dapm, msm8974_dapm_widgets_01,
- - ARRAY_SIZE(msm8974_dapm_widgets_01));
- - }
- - else
- - {
- - snd_soc_dapm_new_controls(dapm, msm8974_dapm_widgets,
- - ARRAY_SIZE(msm8974_dapm_widgets));
- - }
- -#else
- +
- snd_soc_dapm_new_controls(dapm, msm8974_dapm_widgets,
- ARRAY_SIZE(msm8974_dapm_widgets));
- -#endif
- +
- snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
- snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
- snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
- @@ -1988,37 +1632,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- return err;
- }
- }
- -
- -#if defined(CONFIG_MACH_KLTE_KOR)
- - if (system_rev >= 13) {
- - pr_info("%s: USE MBHC revision %d\n", __func__, system_rev);
- - /* start mbhc */
- - mbhc_cfg.calibration = def_taiko_mbhc_cal();
- - if (mbhc_cfg.calibration) {
- - err = taiko_hs_detect(codec, &mbhc_cfg);
- - if (err)
- - goto out;
- - } else {
- - err = -ENOMEM;
- - goto out;
- - }
- - }
- -#elif defined(CONFIG_MACH_KLTE_JPN)
- - if (system_rev >= 11) {
- - pr_info("%s: USE MBHC revision %d\n", __func__, system_rev);
- - /* start mbhc */
- - mbhc_cfg.calibration = def_taiko_mbhc_cal();
- - if (mbhc_cfg.calibration) {
- - err = taiko_hs_detect(codec, &mbhc_cfg);
- - if (err)
- - goto out;
- - } else {
- - err = -ENOMEM;
- - goto out;
- - }
- - }
- -#else
- -#if !defined(CONFIG_SAMSUNG_JACK) && !defined(CONFIG_MUIC_DET_JACK)
- /* start mbhc */
- mbhc_cfg.calibration = def_taiko_mbhc_cal();
- if (mbhc_cfg.calibration) {
- @@ -2029,23 +1642,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- err = -ENOMEM;
- goto out;
- }
- -#elif defined(CONFIG_SEC_JACTIVE_PROJECT)
- - pr_info("2. msm_audrx_init system_rev %d",system_rev);
- - if(system_rev < 3) {
- - mbhc_cfg.calibration = def_taiko_mbhc_cal();
- - if (mbhc_cfg.calibration) {
- - err = taiko_hs_detect(codec, &mbhc_cfg);
- - if (err)
- - goto out;
- - else
- - return err;
- - } else {
- - err = -ENOMEM;
- - goto out;
- - }
- - }
- -#endif
- -#endif /* CONFIG_MACH_KLTE_KOR */
- adsp_state_notifier =
- subsys_notif_register_notifier("adsp",
- &adsp_state_notifier_block);
- @@ -2053,19 +1649,7 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
- pr_err("%s: Failed to register adsp state notifier\n",
- __func__);
- err = -EFAULT;
- -#if defined(CONFIG_MACH_KLTE_KOR)
- - if (system_rev >= 13) {
- - taiko_hs_detect_exit(codec);
- - }
- -#elif defined(CONFIG_MACH_KLTE_JPN)
- - if (system_rev >= 11) {
- - taiko_hs_detect_exit(codec);
- - }
- -#else
- -#if !defined(CONFIG_SAMSUNG_JACK) && !defined(CONFIG_MUIC_DET_JACK)
- taiko_hs_detect_exit(codec);
- -#endif
- -#endif /* CONFIG_MACH_KLTE_KOR */
- goto out;
- }
- @@ -2113,8 +1697,8 @@ void *def_taiko_mbhc_cal(void)
- S(t_ins_retry, 200);
- #undef S
- #define S(X, Y) ((WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(taiko_cal)->X) = (Y))
- - S(v_no_mic, 950);
- - S(v_hs_max, 3000);
- + S(v_no_mic, 30);
- + S(v_hs_max, 2400);
- #undef S
- #define S(X, Y) ((WCD9XXX_MBHC_CAL_BTN_DET_PTR(taiko_cal)->X) = (Y))
- S(c[0], 62);
- @@ -2133,11 +1717,21 @@ void *def_taiko_mbhc_cal(void)
- btn_high = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg,
- MBHC_BTN_DET_V_BTN_HIGH);
- btn_low[0] = -50;
- - btn_high[0] = 160;
- - btn_low[1] = 161;
- - btn_high[1] = 330;
- - btn_low[2] = 331;
- - btn_high[2] = 730;
- + btn_high[0] = 20;
- + btn_low[1] = 21;
- + btn_high[1] = 61;
- + btn_low[2] = 62;
- + btn_high[2] = 104;
- + btn_low[3] = 105;
- + btn_high[3] = 148;
- + btn_low[4] = 149;
- + btn_high[4] = 189;
- + btn_low[5] = 190;
- + btn_high[5] = 228;
- + btn_low[6] = 229;
- + btn_high[6] = 269;
- + btn_low[7] = 270;
- + btn_high[7] = 500;
- n_ready = wcd9xxx_mbhc_cal_btn_det_mp(btn_cfg, MBHC_BTN_DET_N_READY);
- n_ready[0] = 80;
- n_ready[1] = 68;
- @@ -2188,26 +1782,16 @@ static int msm_snd_hw_params(struct snd_pcm_substream *substream,
- pr_err("%s: failed to get codec chan map\n", __func__);
- goto end;
- }
- -
- /* For tabla_tx1 case */
- -#if defined(CONFIG_SND_SOC_ES705)
- if (codec_dai->id == 1)
- user_set_tx_ch = msm_slim_0_tx_ch;
- -#elif defined(CONFIG_SND_SOC_ES325)
- - if ((codec_dai->id == 1) ||(codec_dai->id == 11)) {
- - user_set_tx_ch = msm_slim_0_tx_ch;
- - }
- -#else
- - if (codec_dai->id == 1)
- - user_set_tx_ch = msm_slim_0_tx_ch;
- -#endif
- -
- - /* For tabla_tx2 case */
- + /* For tabla_tx2 case */
- else if (codec_dai->id == 3)
- user_set_tx_ch = params_channels(params);
- else
- user_set_tx_ch = tx_ch_cnt;
- - pr_info("%s: msm_slim_0_tx_ch(%d)user_set_tx_ch(%d)tx_ch_cnt(%d)\n",
- +
- + pr_debug("%s: msm_slim_0_tx_ch(%d)user_set_tx_ch(%d)tx_ch_cnt(%d)\n",
- __func__, msm_slim_0_tx_ch, user_set_tx_ch, tx_ch_cnt);
- ret = snd_soc_dai_set_channel_map(cpu_dai,
- @@ -2228,124 +1812,6 @@ static void msm8974_snd_shudown(struct snd_pcm_substream *substream)
- }
- -#if defined (CONFIG_SND_SOC_MAX98504)
- -static int msm8974_pri_mi2s_free_gpios(void)
- -{
- - int i;
- - for (i = 0; i < ARRAY_SIZE(pri_mi2s_gpio); i++)
- - gpio_free(pri_mi2s_gpio[i].gpio_no);
- - return 0;
- -}
- -
- -static struct afe_clk_cfg lpass_mi2s_enable = {
- - AFE_API_VERSION_I2S_CONFIG,
- - Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
- - Q6AFE_LPASS_OSR_CLK_12_P288_MHZ,
- - Q6AFE_LPASS_CLK_SRC_INTERNAL,
- - Q6AFE_LPASS_CLK_ROOT_DEFAULT,
- - Q6AFE_LPASS_MODE_BOTH_VALID,
- - 0,
- -};
- -static struct afe_clk_cfg lpass_mi2s_disable = {
- - AFE_API_VERSION_I2S_CONFIG,
- - 0,
- - 0,
- - Q6AFE_LPASS_CLK_SRC_INTERNAL,
- - Q6AFE_LPASS_CLK_ROOT_DEFAULT,
- - Q6AFE_LPASS_MODE_BOTH_VALID,
- - 0,
- -};
- -
- -
- -static void msm8974_mi2s_shutdown(struct snd_pcm_substream *substream)
- -{
- -
- -
- - if (atomic_dec_return(&pri_mi2s_clk.mi2s_rsc_ref) == 0) {
- - int ret =0;
- - pr_debug("[MAX98504_DEBUG] %s: free mi2s resources\n", __func__);
- - if(substream->stream==0)
- - ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &lpass_mi2s_disable);
- - else if(substream->stream==1)
- - ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_TX, &lpass_mi2s_disable);
- -
- - if (ret < 0) {
- - pr_err("%s: afe_set_lpass_clock failed\n", __func__);
- -
- - }
- - msm8974_pri_mi2s_free_gpios();
- - }
- -}
- -
- -static int msm8974_configure_pri_mi2s_gpio(void)
- -{
- - int rtn;
- - int i;
- - for (i = 0; i < ARRAY_SIZE(pri_mi2s_gpio); i++) {
- -
- - rtn = gpio_request(pri_mi2s_gpio[i].gpio_no,
- - pri_mi2s_gpio[i].gpio_name);
- -
- - pr_debug("%s: gpio = %d, gpio name = %s, rtn = %d\n", __func__,
- - pri_mi2s_gpio[i].gpio_no, pri_mi2s_gpio[i].gpio_name, rtn);
- - if (rtn) {
- - pr_err("%s: Failed to request gpio %d\n",
- - __func__,
- - pri_mi2s_gpio[i].gpio_no);
- - while( i >= 0) {
- - gpio_free(pri_mi2s_gpio[i].gpio_no);
- - i--;
- - }
- - break;
- - }
- - }
- -
- - return rtn;
- -}
- -static int msm8974_mi2s_startup(struct snd_pcm_substream *substream)
- -{
- - int ret = 0;
- - struct snd_soc_pcm_runtime *rtd = substream->private_data;
- - struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- - struct snd_soc_dai *codec_dai = rtd->codec_dai;
- -
- - pr_debug("%s: dai name %s %p\n", __func__, cpu_dai->name, cpu_dai->dev);
- -
- - if (atomic_inc_return(&pri_mi2s_clk.mi2s_rsc_ref) == 1) {
- - pr_info("%s: acquire mi2s resources\n", __func__);
- - msm8974_configure_pri_mi2s_gpio();
- - if(substream->stream==0)
- - ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_RX, &lpass_mi2s_enable);
- - else if(substream->stream==1)
- - ret = afe_set_lpass_clock(AFE_PORT_ID_SECONDARY_MI2S_TX, &lpass_mi2s_enable);
- - if (ret < 0) {
- - pr_err("%s: afe_set_lpass_clock failed\n", __func__);
- - return ret;
- - }
- - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS);
- - if (ret < 0)
- - dev_err(cpu_dai->dev, "set format for CPU dai"
- - " failed\n");
- -
- - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- - SND_SOC_DAIFMT_CBS_CFS);
- - if (ret < 0)
- - dev_err(codec_dai->dev, "set format for codec dai"
- - " failed\n");
- -
- - ret = 0;
- - }
- - return ret;
- -}
- -
- -
- -
- -static struct snd_soc_ops msm8974_mi2s_be_ops = {
- - .startup = msm8974_mi2s_startup,
- - .shutdown = msm8974_mi2s_shutdown
- -};
- -#endif
- -
- static struct snd_soc_ops msm8974_be_ops = {
- .startup = msm8974_snd_startup,
- .hw_params = msm_snd_hw_params,
- @@ -3042,38 +2508,6 @@ static struct snd_soc_dai_link msm8974_common_dai_links[] = {
- .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
- .ignore_suspend = 1,
- },
- -#if defined( CONFIG_PCM_ROUTE_VOICE_STUB ) || defined(CONFIG_BT_CALL_FORWARDING)
- - {
- - .name = "Voice Stub",
- - .stream_name = "Voice Stub",
- - .cpu_dai_name = "VOICE_STUB",
- - .platform_name = "msm-pcm-hostless",
- - .dynamic = 1,
- - .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
- - .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- - .ignore_suspend = 1,
- - .ignore_pmdown_time = 1, /* this dainlink has playback support */
- - .codec_dai_name = "snd-soc-dummy-dai",
- - .codec_name = "snd-soc-dummy",
- - },
- -#endif /* CONFIG_PCM_ROUTE_VOICE_STUB || CONFIG_BT_CALL_FORWARDING */
- -#ifdef CONFIG_JACK_AUDIO
- - {
- - .name = "MSM8974 JACK LowLatency",
- - .stream_name = "MultiMedia10",
- - .cpu_dai_name = "MultiMedia10",
- - .platform_name = "msm-pcm-dsp.1",
- - .dynamic = 1,
- - .codec_dai_name = "snd-soc-dummy-dai",
- - .codec_name = "snd-soc-dummy",
- - .trigger = {SND_SOC_DPCM_TRIGGER_POST,
- - SND_SOC_DPCM_TRIGGER_POST},
- - .ignore_suspend = 1,
- - /* this dainlink has playback support */
- - .ignore_pmdown_time = 1,
- - .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
- - },
- -#endif
- /* Primary AUX PCM Backend DAI Links */
- {
- .name = LPASS_BE_AUXPCM_RX,
- @@ -3103,37 +2537,6 @@ static struct snd_soc_dai_link msm8974_common_dai_links[] = {
- .ops = &msm_pri_auxpcm_be_ops,
- .ignore_suspend = 1,
- },
- -#if defined( CONFIG_PCM_ROUTE_VOICE_STUB ) || defined(CONFIG_BT_CALL_FORWARDING)
- - /* Secondary AUX PCM Backend DAI Links */
- - {
- - .name = LPASS_BE_SEC_AUXPCM_RX,
- - .stream_name = "Sec AUX PCM Playback",
- - .cpu_dai_name = "msm-dai-q6-auxpcm.2",
- - .platform_name = "msm-pcm-routing",
- - .codec_name = "msm-stub-codec.1",
- - .codec_dai_name = "msm-stub-rx",
- - .no_pcm = 1,
- - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
- - .be_hw_params_fixup = msm_auxpcm2_be_params_fixup,
- - .ops = &msm_sec_auxpcm_be_ops,
- - .ignore_pmdown_time = 1,
- - .ignore_suspend = 1,
- - /* this dainlink has playback support */
- - },
- - {
- - .name = LPASS_BE_SEC_AUXPCM_TX,
- - .stream_name = "Sec AUX PCM Capture",
- - .cpu_dai_name = "msm-dai-q6-auxpcm.2",
- - .platform_name = "msm-pcm-routing",
- - .codec_name = "msm-stub-codec.1",
- - .codec_dai_name = "msm-stub-tx",
- - .no_pcm = 1,
- - .be_id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
- - .be_hw_params_fixup = msm_auxpcm2_be_params_fixup,
- - .ops = &msm_sec_auxpcm_be_ops,
- - .ignore_suspend = 1,
- - },
- -#else
- /* Secondary AUX PCM Backend DAI Links */
- {
- .name = LPASS_BE_SEC_AUXPCM_RX,
- @@ -3163,7 +2566,7 @@ static struct snd_soc_dai_link msm8974_common_dai_links[] = {
- .ops = &msm_sec_auxpcm_be_ops,
- .ignore_suspend = 1,
- },
- -#endif
- +
- /* Backend DAI Links */
- {
- .name = LPASS_BE_SLIMBUS_0_RX,
- @@ -3316,7 +2719,7 @@ static struct snd_soc_dai_link msm8974_common_dai_links[] = {
- .be_hw_params_fixup = msm_be_hw_params_fixup,
- .ignore_suspend = 1,
- },
- - /* Incall Music 2 BACK END DAI Link */
- + /* Incall Music 2 BACK END DAI Link */
- {
- .name = LPASS_BE_VOICE2_PLAYBACK_TX,
- .stream_name = "Voice2 Farend Playback",
- @@ -3328,21 +2731,7 @@ static struct snd_soc_dai_link msm8974_common_dai_links[] = {
- .be_id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
- .ignore_suspend = 1,
- - },
- -#ifdef CONFIG_SND_SOC_MAX98504
- - {
- - .name = LPASS_BE_SEC_MI2S_TX,
- - .stream_name = "Secondary MI2S Capture",
- - .cpu_dai_name = "msm-dai-q6-mi2s.1",
- - .platform_name = "msm-pcm-routing",
- - .codec_name = "max98504.18-0031",//"msm-stub-codec.1",
- - .codec_dai_name = "max98504-aif1",//"msm-stub-tx",
- - .no_pcm = 1,
- - .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
- - .be_hw_params_fixup = msm8974_mi2s_be_hw_params_fixup,
- - .ops = &msm8974_mi2s_be_ops,
- - },
- -#endif
- + }
- };
- static struct snd_soc_dai_link msm8974_hdmi_dai_link[] = {
- @@ -3470,101 +2859,6 @@ static int msm8974_prepare_us_euro(struct snd_soc_card *card)
- return 0;
- }
- -static int msm8974_prepare_mainmic(void)
- -{
- - int ret;
- - if (mainmic_bias_gpio) {
- - pr_debug("%s : mainmic bias gpio request %d", __func__,
- - mainmic_bias_gpio);
- - ret = gpio_request(mainmic_bias_gpio, "TAIKO_MAINMIC_BIAS");
- - if (ret) {
- - pr_debug("%s: Failed to request taiko mainmic bias gpio %d error %d\n",
- - __func__, mainmic_bias_gpio, ret);
- - return ret;
- - }
- - gpio_direction_output(mainmic_bias_gpio, 0);
- - }
- -
- - return 0;
- -}
- -
- -
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- -static int msm8974_prepare_submic(void)
- -{
- - int ret;
- - if (submic_bias_gpio) {
- - pr_debug("%s : submic bias gpio request %d", __func__,
- - submic_bias_gpio);
- - ret = gpio_request(submic_bias_gpio, "TAIKO_SUBMIC_BIAS");
- - if (ret) {
- - pr_debug("%s: Failed to request taiko submic bias gpio %d error %d\n",
- - __func__, submic_bias_gpio, ret);
- - return ret;
- - }
- - gpio_direction_output(submic_bias_gpio, 0);
- - }
- -
- - return 0;
- -}
- -#endif
- -
- -#if defined(CONFIG_LDO_EARMIC_BIAS)
- -static int msm8974_prepare_earmic(void)
- -{
- - int ret;
- - if (earmic_bias_gpio) {
- - pr_debug("%s : earmic bias gpio request %d", __func__,
- - earmic_bias_gpio);
- - ret = gpio_request(earmic_bias_gpio, "TAIKO_EARMIC_BIAS");
- - if (ret) {
- - pr_debug("%s: Failed to request taiko earmic bias gpio %d error %d\n",
- - __func__, earmic_bias_gpio, ret);
- - return ret;
- - }
- - gpio_direction_output(earmic_bias_gpio, 0);
- - }
- -
- - return 0;
- -}
- -#endif
- -
- -static int msm8974_prepare_spkamp(void)
- -{
- - int ret;
- - if (spkamp_en_gpio) {
- - pr_debug("%s : spkamp en gpio request %d", __func__,
- - spkamp_en_gpio);
- - ret = gpio_request(spkamp_en_gpio, "SPKAMP_EN");
- - if (ret) {
- - pr_debug("%s: Failed to request spkamp en gpio %d error %d\n",
- - __func__, spkamp_en_gpio, ret);
- - return ret;
- - }
- - gpio_direction_output(spkamp_en_gpio, 0);
- - }
- -
- - return 0;
- -}
- -
- -static int msm8974_prepare_micbias_to_codec(void)
- -{
- - int ret;
- - if (micbias_en_msm_gpio) {
- - pr_debug("%s : micbias en msm gpio request %d", __func__,
- - micbias_en_msm_gpio);
- - ret = gpio_request(micbias_en_msm_gpio, "MICBIAS_TO_CODEC");
- - if (ret) {
- - pr_debug("%s: Failed to request taiko micbias en msm gpio %d error %d\n",
- - __func__, micbias_en_msm_gpio, ret);
- - return ret;
- - }
- - gpio_direction_output(micbias_en_msm_gpio, 0);
- - }
- -
- - return 0;
- -}
- -
- static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
- {
- struct snd_soc_card *card = &snd_soc_card_msm8974;
- @@ -3576,9 +2870,6 @@ static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
- size_t n = strlen("4-pole-jack");
- struct resource *pri_muxsel;
- struct resource *sec_muxsel;
- -#if defined(CONFIG_SEC_JACTIVE_PROJECT)
- - extern unsigned int system_rev;
- -#endif
- if (!pdev->dev.of_node) {
- dev_err(&pdev->dev, "No platform supplied from device tree\n");
- @@ -3751,151 +3042,6 @@ static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
- dev_err(&pdev->dev, "msm8974_prepare_us_euro failed (%d)\n",
- ret);
- -#ifdef CONFIG_SEC_JACTIVE_PROJECT
- - if(system_rev < 3) {
- - ear_jack_fsa8038_en = of_get_named_gpio(pdev->dev.of_node, "qcom,fsa8038_enable", 0);
- -
- - if (ear_jack_fsa8038_en < 0) {
- - dev_err(&pdev->dev, "Looking up %s property in node %s failed",
- - "qcom,fsa8038_enable",
- - pdev->dev.of_node->full_name);
- - } else {
- - ret = gpio_request(ear_jack_fsa8038_en, "fsa8038 enable");
- -
- - if (ret) {
- - dev_err(&pdev->dev, "Looking up %s property in node %s failed",
- - "qcom,fsa8038_enable",
- - pdev->dev.of_node->full_name);
- - gpio_free(ear_jack_fsa8038_en);
- - } else {
- - gpio_direction_output(ear_jack_fsa8038_en, 1);
- - }
- - }
- - }
- -#endif
- -
- - /* the ldo of main mic bias */
- - mainmic_bias_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,mainmic-bias-gpio", 0);
- - if (mainmic_bias_gpio < 0) {
- - dev_err(&pdev->dev, "Looking up %s property in node %s failed",
- - "qcom,mainmic-bias-gpio",
- - pdev->dev.of_node->full_name);
- - } else {
- - pr_info("%s : mic bias = %d\n", __func__, mainmic_bias_gpio);
- -
- - ret = msm8974_prepare_mainmic();
- - if (ret) {
- - dev_err(&pdev->dev, "msm8974_prepare_mainmic failed (%d)\n",
- - ret);
- - gpio_free(mainmic_bias_gpio);
- - mainmic_bias_gpio = 0;
- - }
- - }
- -
- -#if defined(CONFIG_LDO_SUBMIC_BIAS)
- - /* the ldo of sub mic bias */
- - submic_bias_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,submic-bias-gpio", 0);
- - pr_info("%s :sub mic bias = %d\n", __func__, submic_bias_gpio);
- -
- - ret = msm8974_prepare_submic();
- - if (ret) {
- - dev_err(&pdev->dev, "msm8974_prepare_submic failed (%d)\n",
- - ret);
- - gpio_free(submic_bias_gpio);
- - submic_bias_gpio = 0;
- - }
- -#endif
- -
- -#if defined(CONFIG_LDO_EARMIC_BIAS)
- - /* the ldo of ear mic bias */
- - earmic_bias_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,earmic-bias-gpio", 0);
- - pr_info("%s :ear mic bias = %d\n", __func__, earmic_bias_gpio);
- -
- - ret = msm8974_prepare_earmic();
- - if (ret) {
- - dev_err(&pdev->dev, "msm8974_prepare_earmic failed (%d)\n",
- - ret);
- - gpio_free(earmic_bias_gpio);
- - earmic_bias_gpio = 0;
- - }
- -#endif
- -
- -
- -#if defined(CONFIG_MACH_KLTE_KOR) || defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KACTIVELTE_DCM) || defined(CONFIG_MACH_CHAGALL_KDI) || defined(CONFIG_MACH_KLIMT_LTE_DCM)
- - /* enable FSA8039 for jack detection */
- - pr_info("%s: Check to enable FSA8039\n", __func__);
- - fsa_en_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,earjack-fsa_en-gpio", 0);
- - if (fsa_en_gpio < 0)
- - of_property_read_u32(pdev->dev.of_node,
- - "qcom,earjack-fsa_en-expander-gpio", &fsa_en_gpio);
- - if (fsa_en_gpio < 0)
- - pr_info("%s: No support FSA8039 chip\n", __func__);
- - else
- - pr_info("%s: earjack-fsa_en-gpio =%d\n",
- - __func__, fsa_en_gpio);
- -
- - if (fsa_en_gpio > 0) {
- - ret = gpio_request(fsa_en_gpio, "fsa_en");
- - if (ret) {
- - pr_err("%s : gpio_request failed for %d, ret %d\n",
- - __func__, fsa_en_gpio, ret);
- - goto err;
- - }
- - gpio_direction_output(fsa_en_gpio, 1);
- - }
- -#endif
- - /* the switch to connect the main mic to the codec or es705 */
- -#if defined(CONFIG_MACH_KLTE_JPN) || defined(CONFIG_MACH_KACTIVELTE_DCM) || defined(CONFIG_MACH_CHAGALL_KDI) || defined(CONFIG_MACH_KLIMT_LTE_DCM)
- -#if defined(CONFIG_MACH_KLTE_MAX77828_JPN)
- - micbias_en_msm_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,micbias-en-msm-gpio", 0);
- -#else
- - micbias_en_msm_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,micbias-en-msm-jpn-gpio", 0);
- -#endif
- -#else
- - micbias_en_msm_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,micbias-en-msm-gpio", 0);
- -#endif
- - if (micbias_en_msm_gpio < 0) {
- - dev_err(&pdev->dev, "Looking up %s property in node %s failed",
- - "qcom,micbias-en-msm-gpio",
- - pdev->dev.of_node->full_name);
- - } else {
- - pr_info("%s : micbias en msm = %d\n", __func__, micbias_en_msm_gpio);
- -
- - ret = msm8974_prepare_micbias_to_codec();
- - if (ret) {
- - dev_err(&pdev->dev, "msm8974_prepare_micbias_to_codec failed (%d)\n",
- - ret);
- - gpio_free(micbias_en_msm_gpio);
- - micbias_en_msm_gpio = 0;
- - }
- - }
- -
- - spkamp_en_gpio = of_get_named_gpio(pdev->dev.of_node,
- - "qcom,spkamp-en-gpio", 0);
- - if (spkamp_en_gpio < 0) {
- - dev_err(&pdev->dev, "Looking up %s property in node %s failed",
- - "qcom,spkamp-en-gpio",
- - pdev->dev.of_node->full_name);
- - } else {
- - pr_info("%s : spkamp_en_ gpio = %d\n", __func__, spkamp_en_gpio);
- -
- - ret = msm8974_prepare_spkamp();
- - if (ret) {
- - dev_err(&pdev->dev, "msm8974_prepare_spkamp_en_ gpio failed (%d)\n",
- - ret);
- - gpio_free(spkamp_en_gpio);
- - spkamp_en_gpio = 0;
- - }
- - }
- -
- -
- ret = of_property_read_string(pdev->dev.of_node,
- "qcom,prim-auxpcm-gpio-set", &auxpcm_pri_gpio_set);
- if (ret) {
- @@ -3929,14 +3075,9 @@ static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
- goto err1;
- }
- }
- -#if defined( CONFIG_PCM_ROUTE_VOICE_STUB ) || defined(CONFIG_BT_CALL_FORWARDING)
- - sec_muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- - "lpaif_quat_mode_muxsel");
- -#else
- +
- sec_muxsel = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "lpaif_sec_mode_muxsel");
- -#endif /* CONFIG_PCM_ROUTE_VOICE_STUB || CONFIG_BT_CALL_FORWARDING*/
- -
- if (!sec_muxsel) {
- dev_err(&pdev->dev, "MUX addr invalid for secondary AUXPCM\n");
- ret = -ENODEV;
- @@ -3949,10 +3090,6 @@ static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
- ret = -EINVAL;
- goto err2;
- }
- -#if defined (CONFIG_SND_SOC_MAX98504)
- - atomic_set(&pri_mi2s_clk.mi2s_rsc_ref, 0);
- -#endif
- -
- return 0;
- err2:
- diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
- index ad9b9db..a74f69f 100644
- --- a/sound/soc/msm/msm8x10.c
- +++ b/sound/soc/msm/msm8x10.c
- @@ -385,7 +385,7 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- }
- -static const char *const btsco_rate_text[] = {"8000", "16000"};
- +static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ", "BTSCO_RATE_16KHZ"};
- static const struct soc_enum msm_btsco_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
- };
- @@ -405,10 +405,10 @@ static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- switch (ucontrol->value.integer.value[0]) {
- - case 8000:
- + case 0:
- msm_btsco_rate = BTSCO_RATE_8KHZ;
- break;
- - case 16000:
- + case 1:
- msm_btsco_rate = BTSCO_RATE_16KHZ;
- break;
- default:
- diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
- index 659d5a2..8ecb147 100644
- --- a/sound/soc/msm/qdsp6/q6asm.c
- +++ b/sound/soc/msm/qdsp6/q6asm.c
- @@ -57,6 +57,7 @@
- #define OUT_BUFFER_SIZE 56
- #define IN_BUFFER_SIZE 24
- #endif
- +#define FRAME_NUM (8)
- static DEFINE_MUTEX(session_lock);
- /* session id: 0 reserved */
- @@ -509,6 +510,9 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
- pr_debug("%s: buffer already allocated\n", __func__);
- return 0;
- }
- +
- + if (bufcnt != FRAME_NUM)
- + goto fail;
- mutex_lock(&ac->cmd_lock);
- buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
- GFP_KERNEL);
- diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
- index 5e4d9d3..2fc4949 100644
- --- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
- +++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2013-2015, 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
- @@ -621,6 +621,11 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
- }
- for (j = 0; j < eq->config.num_bands; j++) {
- idx = *values++;
- + if (idx >= MAX_EQ_BANDS) {
- + pr_err("EQ_CONFIG:invalid band index\n");
- + rc = -EINVAL;
- + goto invalid_config;
- + }
- eq->per_band_cfg[idx].band_idx = idx;
- eq->per_band_cfg[idx].filter_type = *values++;
- eq->per_band_cfg[idx].freq_millihertz =
- diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
- index fadebb4..74346da 100644
- --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
- +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
- @@ -1,4 +1,4 @@
- -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- +/* Copyright (c) 2012-2015, 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
- @@ -304,6 +304,7 @@ static void compr_event_handler(uint32_t opcode,
- uint32_t sample_rate = 0;
- int bytes_available, stream_id;
- uint32_t stream_index;
- + unsigned long flags;
- pr_debug("%s opcode =%08x\n", __func__, opcode);
- switch (opcode) {
- @@ -476,11 +477,17 @@ static void compr_event_handler(uint32_t opcode,
- case RESET_EVENTS:
- pr_err("%s: Received reset events CB, move to error state",
- __func__);
- - spin_lock(&prtd->lock);
- + spin_lock_irqsave(&prtd->lock, flags);
- snd_compr_fragment_elapsed(cstream);
- prtd->copied_total = prtd->bytes_received;
- atomic_set(&prtd->error, 1);
- - spin_unlock(&prtd->lock);
- + wake_up(&prtd->drain_wait);
- + if (atomic_read(&prtd->eos)) {
- + pr_debug("%s:unblock eos wait queues", __func__);
- + wake_up(&prtd->eos_wait);
- + atomic_set(&prtd->eos, 0);
- + }
- + spin_unlock_irqrestore(&prtd->lock, flags);
- break;
- default:
- pr_debug("%s: Not Supported Event opcode[0x%x]\n",
- @@ -624,6 +631,11 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream)
- pr_err("%s: Send SoftVolume Param failed ret=%d\n",
- __func__, ret);
- + ret = q6asm_set_softpause(ac, &softpause);
- + if (ret < 0)
- + pr_err("%s: Send SoftPause Param failed ret=%d\n",
- + __func__, ret);
- +
- ret = q6asm_set_io_mode(ac, (COMPRESSED_STREAM_IO | ASYNC_IO_MODE));
- if (ret < 0) {
- pr_err("%s: Set IO mode failed\n", __func__);
- @@ -941,14 +953,19 @@ static int msm_compr_drain_buffer(struct msm_compr_audio *prtd,
- rc = wait_event_interruptible(prtd->drain_wait,
- prtd->drain_ready ||
- prtd->cmd_interrupt ||
- - atomic_read(&prtd->xrun));
- - pr_debug("%s: out of buffer drain wait\n", __func__);
- + atomic_read(&prtd->xrun) ||
- + atomic_read(&prtd->error));
- + pr_debug("%s: out of buffer drain wait with ret %d\n", __func__, rc);
- spin_lock_irqsave(&prtd->lock, *flags);
- if (prtd->cmd_interrupt) {
- pr_debug("%s: buffer drain interrupted by flush)\n", __func__);
- rc = -EINTR;
- prtd->cmd_interrupt = 0;
- }
- + if (atomic_read(&prtd->error)) {
- + pr_err("%s: Got RESET EVENTS notification, return\n", __func__);
- + rc = -ENETRESET;
- + }
- return rc;
- }
- @@ -1253,7 +1270,9 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
- /* Wait indefinitely for DRAIN. Flush can also signal this*/
- rc = wait_event_interruptible(prtd->eos_wait,
- - (prtd->cmd_ack || prtd->cmd_interrupt));
- + (prtd->cmd_ack ||
- + prtd->cmd_interrupt ||
- + atomic_read(&prtd->error)));
- if (rc < 0)
- pr_err("%s: EOS wait failed\n", __func__);
- @@ -1264,6 +1283,11 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
- if (prtd->cmd_interrupt)
- rc = -EINTR;
- + if (atomic_read(&prtd->error)) {
- + pr_err("%s: Got RESET EVENTS notification, return\n", __func__);
- + rc = -ENETRESET;
- + }
- +
- /*FIXME : what if a flush comes while PC is here */
- if (rc == 0) {
- /*
- diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
- index 30506ef..e7b908d 100644
- --- a/sound/soc/msm/qdsp6v2/q6adm.c
- +++ b/sound/soc/msm/qdsp6v2/q6adm.c
- @@ -439,7 +439,7 @@ int adm_get_params(int port_id, uint32_t module_id, uint32_t param_id,
- }
- if ((params_data) && (ARRAY_SIZE(adm_get_parameters) >=
- (1+adm_get_parameters[0])) &&
- - (params_length/sizeof(int) >=
- + (params_length/sizeof(uint32_t) >=
- adm_get_parameters[0])) {
- for (i = 0; i < adm_get_parameters[0]; i++)
- params_data[i] = adm_get_parameters[1+i];
- @@ -650,16 +650,23 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
- /* is big enough and has a valid param size */
- if ((payload[0] == 0) && (data->payload_size >
- (4 * sizeof(*payload))) &&
- - (data->payload_size/sizeof(*payload)-4 >=
- + (data->payload_size - 4 >=
- payload[3]) &&
- (ARRAY_SIZE(adm_get_parameters)-1 >=
- payload[3])) {
- - adm_get_parameters[0] = payload[3];
- + adm_get_parameters[0] = payload[3] /
- + sizeof(uint32_t);
- + /*
- + * payload[3] is param_size which is
- + * expressed in number of bytes
- + */
- pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n",
- __func__, adm_get_parameters[0]);
- /* storing param size then params */
- - for (i = 0; i < payload[3]; i++)
- - adm_get_parameters[1+i] = payload[4+i];
- + for (i = 0; i < payload[3] /
- + sizeof(uint32_t); i++)
- + adm_get_parameters[1+i] =
- + payload[4+i];
- } else {
- adm_get_parameters[0] = -1;
- pr_err("%s: GET_PP_PARAMS failed, setting size to %d\n",
- diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
- index 57aee34..bfe64db 100644
- --- a/sound/soc/msm/qdsp6v2/q6afe.c
- +++ b/sound/soc/msm/qdsp6v2/q6afe.c
- @@ -64,6 +64,7 @@ struct afe_ctl {
- struct afe_spkr_prot_calib_get_resp calib_data;
- #endif
- int vi_tx_port;
- + int vi_rx_port;
- uint32_t afe_sample_rates[AFE_MAX_PORTS];
- struct aanc_data aanc_info;
- };
- @@ -513,7 +514,7 @@ int afe_unmap_cal_blocks(void)
- return result;
- }
- -static int afe_spk_prot_prepare(int port, int param_id,
- +static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
- union afe_spkr_prot_config *prot_config)
- {
- int ret = -EINVAL;
- @@ -525,17 +526,28 @@ static int afe_spk_prot_prepare(int port, int param_id,
- pr_err("%s Invalid params\n", __func__);
- goto fail_cmd;
- }
- - if ((q6audio_validate_port(port) < 0)) {
- - pr_err("%s invalid port %d", __func__, port);
- + ret = q6audio_validate_port(src_port);
- + if (ret < 0) {
- + pr_err("%s: Invalid src port 0x%x ret %d",
- + __func__, src_port, ret);
- + ret = -EINVAL;
- goto fail_cmd;
- }
- - index = q6audio_get_port_index(port);
- + ret = q6audio_validate_port(dst_port);
- + if (ret < 0) {
- + pr_err("%s: Invalid dst port 0x%x ret %d", __func__,
- + dst_port, ret);
- + ret = -EINVAL;
- + goto fail_cmd;
- + }
- + index = q6audio_get_port_index(src_port);
- switch (param_id) {
- case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
- config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_RX;
- break;
- case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
- - this_afe.vi_tx_port = port;
- + this_afe.vi_tx_port = src_port;
- + this_afe.vi_rx_port = dst_port;
- case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG:
- case AFE_PARAM_ID_MODE_VI_PROC_CFG:
- config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC;
- @@ -553,7 +565,7 @@ static int afe_spk_prot_prepare(int port, int param_id,
- config.hdr.token = index;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- - config.param.port_id = q6audio_get_port_id(port);
- + config.param.port_id = q6audio_get_port_id(src_port);
- config.param.payload_size = sizeof(config) - sizeof(config.hdr)
- - sizeof(config.param);
- config.pdata.param_id = param_id;
- @@ -562,8 +574,8 @@ static int afe_spk_prot_prepare(int port, int param_id,
- atomic_set(&this_afe.state, 1);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
- if (ret < 0) {
- - pr_err("%s: Setting param for port %d param[0x%x]failed\n",
- - __func__, port, param_id);
- + pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
- + __func__, src_port, param_id, ret);
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- @@ -581,8 +593,8 @@ static int afe_spk_prot_prepare(int port, int param_id,
- }
- ret = 0;
- fail_cmd:
- - pr_debug("%s config.pdata.param_id %x status %d\n",
- - __func__, config.pdata.param_id, ret);
- + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n",
- + __func__, config.pdata.param_id, ret, src_port);
- return ret;
- }
- @@ -683,7 +695,7 @@ static void afe_send_cal_spkr_prot_tx(int port_id)
- else
- afe_spk_config.mode_rx_cfg.mode =
- Q6AFE_MSM_SPKR_PROCESSING;
- - if (afe_spk_prot_prepare(port_id,
- + if (afe_spk_prot_prepare(port_id, 0,
- AFE_PARAM_ID_MODE_VI_PROC_CFG,
- &afe_spk_config))
- pr_err("%s TX VI_PROC_CFG failed\n", __func__);
- @@ -693,7 +705,7 @@ static void afe_send_cal_spkr_prot_tx(int port_id)
- (uint32_t) prot_cfg.r0;
- afe_spk_config.vi_proc_cfg.t0_cali_q6 =
- (uint32_t) prot_cfg.t0;
- - if (afe_spk_prot_prepare(port_id,
- + if (afe_spk_prot_prepare(port_id, 0,
- AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG,
- &afe_spk_config))
- pr_err("%s SPKR_CALIB_VI_PROC_CFG failed\n",
- @@ -710,7 +722,8 @@ static void afe_send_cal_spkr_prot_rx(int port_id)
- /*Get spkr protection cfg data*/
- get_spk_protection_cfg(&prot_cfg);
- - if (prot_cfg.mode != MSM_SPKR_PROT_DISABLED) {
- + if ((prot_cfg.mode != MSM_SPKR_PROT_DISABLED) &&
- + (this_afe.vi_rx_port == port_id)) {
- if (prot_cfg.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
- afe_spk_config.mode_rx_cfg.mode =
- Q6AFE_MSM_SPKR_CALIBRATION;
- @@ -718,7 +731,7 @@ static void afe_send_cal_spkr_prot_rx(int port_id)
- afe_spk_config.mode_rx_cfg.mode =
- Q6AFE_MSM_SPKR_PROCESSING;
- afe_spk_config.mode_rx_cfg.minor_version = 1;
- - if (afe_spk_prot_prepare(port_id,
- + if (afe_spk_prot_prepare(port_id, 0,
- AFE_PARAM_ID_FBSP_MODE_RX_CFG,
- &afe_spk_config))
- pr_err("%s RX MODE_VI_PROC_CFG failed\n",
- @@ -794,7 +807,7 @@ fail_cmd:
- void afe_send_cal(u16 port_id)
- {
- - pr_debug("%s\n", __func__);
- + pr_debug("%s: port_id=0x%x\n", __func__, port_id);
- if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) {
- afe_send_cal_spkr_prot_tx(port_id);
- @@ -3377,6 +3390,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
- if (!enable) {
- pr_debug("%s Disable Feedback tx path", __func__);
- this_afe.vi_tx_port = -1;
- + this_afe.vi_rx_port = -1;
- return 0;
- }
- @@ -3405,7 +3419,7 @@ int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
- }
- prot_config.feedback_path_cfg.num_channels = index;
- prot_config.feedback_path_cfg.minor_version = 1;
- - ret = afe_spk_prot_prepare(src_port,
- + ret = afe_spk_prot_prepare(src_port, dst_port,
- AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config);
- fail_cmd:
- return ret;
- @@ -3607,6 +3621,7 @@ static int __init afe_init(void)
- this_afe.dtmf_gen_rx_portid = -1;
- this_afe.mmap_handle = 0;
- this_afe.vi_tx_port = -1;
- + this_afe.vi_rx_port = -1;
- for (i = 0; i < AFE_MAX_PORTS; i++)
- init_waitqueue_head(&this_afe.wait[i]);
- diff --git a/sound/soc/msm/qdsp6v2/q6core.h b/sound/soc/msm/qdsp6v2/q6core.h
- deleted file mode 100644
- index e5a59bc..0000000
- --- a/sound/soc/msm/qdsp6v2/q6core.h
- +++ /dev/null
- @@ -1,106 +0,0 @@
- -/* Copyright (c) 2012-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 __Q6CORE_H__
- -#define __Q6CORE_H__
- -#include <mach/qdsp6v2/apr.h>
- -#include <mach/ocmem.h>
- -
- -
- -#define AVCS_CMD_GET_LOW_POWER_SEGMENTS_INFO 0x00012903
- -
- -struct avcs_cmd_get_low_power_segments_info {
- - struct apr_hdr hdr;
- -} __packed;
- -
- -
- -#define AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO 0x00012904
- -
- -#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C
- -#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D
- -
- -/* @brief AVCS_CMDRSP_GET_LOW_POWER_SEGMENTS_INFO payload
- - * structure. Payload for this event comprises one instance of
- - * avcs_cmd_rsp_get_low_power_segments_info_t, followed
- - * immediately by num_segments number of instances of the
- - * avcs_mem_segment_t structure.
- - */
- -
- -/* Types of Low Power Memory Segments. */
- -#define READ_ONLY_SEGMENT 1
- -/*< Read Only memory segment. */
- -#define READ_WRITE_SEGMENT 2
- -/*< Read Write memory segment. */
- -/*Category indicates whether audio/os/sensor segments. */
- -#define AUDIO_SEGMENT 1
- -/*< Audio memory segment. */
- -#define OS_SEGMENT 2
- -/*< QDSP6's OS memory segment. */
- -
- -/* @brief Payload structure for AVS low power memory segment
- - * structure.
- - */
- -struct avcs_mem_segment_t {
- - uint16_t type;
- -/*< Indicates which type of memory this segment is.
- - *Allowed values: READ_ONLY_SEGMENT or READ_WRITE_SEGMENT only.
- - */
- - uint16_t category;
- -/*< Indicates whether audio or OS segments.
- - *Allowed values: AUDIO_SEGMENT or OS_SEGMENT only.
- - */
- - uint32_t size;
- -/*< Size (in bytes) of this segment.
- - * Will be a non-zero value.
- - */
- - uint32_t start_address_lsw;
- -/*< Lower 32 bits of the 64-bit physical start address
- - * of this segment.
- - */
- - uint32_t start_address_msw;
- -/*< Upper 32 bits of the 64-bit physical start address
- - * of this segment.
- - */
- -};
- -
- -struct avcs_cmd_rsp_get_low_power_segments_info_t {
- - uint32_t num_segments;
- -/*< Number of segments in this response.
- - * 0: there are no known sections that should be mapped
- - * from DDR to OCMEM.
- - * >0: the number of memory segments in the following list.
- - */
- -
- - uint32_t bandwidth;
- -/*< Required OCMEM read/write bandwidth (in bytes per second)
- - * if OCMEM is granted.
- - * 0 if num_segments = 0
- - * >0 if num_segments > 0.
- - */
- - struct avcs_mem_segment_t mem_segment[OCMEM_MAX_CHUNKS];
- -};
- -
- -
- -int core_get_low_power_segments(
- - struct avcs_cmd_rsp_get_low_power_segments_info_t **);
- -bool q6core_is_adsp_ready(void);
- -
- -#define ADSP_CMD_SET_DOLBY_MANUFACTURER_ID 0x00012918
- -
- -struct adsp_dolby_manufacturer_id {
- - struct apr_hdr hdr;
- - int manufacturer_id;
- -};
- -
- -uint32_t core_set_dolby_manufacturer_id(int manufacturer_id);
- -
- -#endif /* __Q6CORE_H__ */
- diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
- index 84d4c84..87c68e4 100644
- --- a/sound/soc/msm/qdsp6v2/q6voice.c
- +++ b/sound/soc/msm/qdsp6v2/q6voice.c
- @@ -29,7 +29,7 @@
- #include "q6voice.h"
- -#define TIMEOUT_MS 300
- +#define TIMEOUT_MS 500
- #define CMD_STATUS_SUCCESS 0
Advertisement
Add Comment
Please, Sign In to add comment