Merge "msm: camera: isp: Add VFE HW driver support" into msm-4.9
diff --git a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
index b043a93..669997c 100644
--- a/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
@@ -333,8 +333,13 @@
as below:
--> Reset GPIO value
--> Sleep value (in ms)
-- qcom,partial-update-enabled: Boolean used to enable partial
+- qcom,partial-update-enabled: String used to enable partial
panel update for command mode panels.
+ "none": partial update is disabled
+ "single_roi": default enable mode, only single roi is sent to panel
+ "dual_roi": two rois are merged into one big roi. Panel ddic should be able
+ to process two roi's along with the DCS command to send two rois.
+ disabled if property is not specified.
- qcom,mdss-dsi-horizontal-line-idle: List of width ranges (EC - SC) in pixels indicating
additional idle time in dsi clock cycles that is needed
to compensate for smaller line width.
@@ -630,7 +635,7 @@
qcom,mdss-tear-check-rd-ptr-trigger-intr = <1281>;
qcom,mdss-tear-check-frame-rate = <6000>;
qcom,mdss-dsi-reset-sequence = <1 2>, <0 10>, <1 10>;
- qcom,partial-update-enabled;
+ qcom,partial-update-enabled = "single_roi";
qcom,dcs-cmd-by-left;
qcom,mdss-dsi-lp11-init;
qcom,mdss-dsi-init-delay-us = <100>;
diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
index a596aa1..c2550e6 100644
--- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
@@ -82,6 +82,8 @@
- qcom,shutdown-poweroff-type Same description as qcom,warm-reset-poweroff-
type but this applies for the system shutdown
case.
+- qcom,kpdpwr-sw-debounce Boolean property to enable the debounce logic
+ on the KPDPWR_N rising edge.
All the below properties are in the sub-node section (properties of the child
diff --git a/Documentation/timers/timer_stats.txt b/Documentation/timers/timer_stats.txt
deleted file mode 100644
index de835ee..0000000
--- a/Documentation/timers/timer_stats.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-timer_stats - timer usage statistics
-------------------------------------
-
-timer_stats is a debugging facility to make the timer (ab)usage in a Linux
-system visible to kernel and userspace developers. If enabled in the config
-but not used it has almost zero runtime overhead, and a relatively small
-data structure overhead. Even if collection is enabled runtime all the
-locking is per-CPU and lookup is hashed.
-
-timer_stats should be used by kernel and userspace developers to verify that
-their code does not make unduly use of timers. This helps to avoid unnecessary
-wakeups, which should be avoided to optimize power consumption.
-
-It can be enabled by CONFIG_TIMER_STATS in the "Kernel hacking" configuration
-section.
-
-timer_stats collects information about the timer events which are fired in a
-Linux system over a sample period:
-
-- the pid of the task(process) which initialized the timer
-- the name of the process which initialized the timer
-- the function where the timer was initialized
-- the callback function which is associated to the timer
-- the number of events (callbacks)
-
-timer_stats adds an entry to /proc: /proc/timer_stats
-
-This entry is used to control the statistics functionality and to read out the
-sampled information.
-
-The timer_stats functionality is inactive on bootup.
-
-To activate a sample period issue:
-# echo 1 >/proc/timer_stats
-
-To stop a sample period issue:
-# echo 0 >/proc/timer_stats
-
-The statistics can be retrieved by:
-# cat /proc/timer_stats
-
-While sampling is enabled, each readout from /proc/timer_stats will see
-newly updated statistics. Once sampling is disabled, the sampled information
-is kept until a new sample period is started. This allows multiple readouts.
-
-Sample output of /proc/timer_stats:
-
-Timerstats sample period: 3.888770 s
- 12, 0 swapper hrtimer_stop_sched_tick (hrtimer_sched_tick)
- 15, 1 swapper hcd_submit_urb (rh_timer_func)
- 4, 959 kedac schedule_timeout (process_timeout)
- 1, 0 swapper page_writeback_init (wb_timer_fn)
- 28, 0 swapper hrtimer_stop_sched_tick (hrtimer_sched_tick)
- 22, 2948 IRQ 4 tty_flip_buffer_push (delayed_work_timer_fn)
- 3, 3100 bash schedule_timeout (process_timeout)
- 1, 1 swapper queue_delayed_work_on (delayed_work_timer_fn)
- 1, 1 swapper queue_delayed_work_on (delayed_work_timer_fn)
- 1, 1 swapper neigh_table_init_no_netlink (neigh_periodic_timer)
- 1, 2292 ip __netdev_watchdog_up (dev_watchdog)
- 1, 23 events/1 do_cache_clean (delayed_work_timer_fn)
-90 total events, 30.0 events/sec
-
-The first column is the number of events, the second column the pid, the third
-column is the name of the process. The forth column shows the function which
-initialized the timer and in parenthesis the callback function which was
-executed on expiry.
-
- Thomas, Ingo
-
-Added flag to indicate 'deferrable timer' in /proc/timer_stats. A deferrable
-timer will appear as follows
- 10D, 1 swapper queue_delayed_work_on (delayed_work_timer_fn)
-
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index bcef117..1921325 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -284,7 +284,6 @@
CONFIG_PANIC_TIMEOUT=5
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_IPC_LOGGING=y
CONFIG_BLK_DEV_IO_TRACE=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 5601276..0a875b1 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -135,6 +135,10 @@
CONFIG_BRIDGE=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_PRIO=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
CONFIG_RFKILL=y
CONFIG_IPC_ROUTER=y
CONFIG_IPC_ROUTER_SECURITY=y
@@ -278,7 +282,6 @@
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index ff2cc3e..cd13516 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -14,6 +14,15 @@
sdm845-4k-panel-cdp.dtb \
sdm845-4k-panel-qrd.dtb
+ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
+ dtbo-$(CONFIG_ARCH_SDM845) += \
+ sdm845-cdp-overlay.dtbo \
+ sdm845-mtp-overlay.dtbo
+
+sdm845-cdp-overlay.dtbo-base := sdm845.dtb
+sdm845-mtp-overlay.dtbo-base := sdm845.dtb
+endif
+
dtb-$(CONFIG_ARCH_SDM830) += sdm830-sim.dtb \
sdm830-rumi.dtb \
sdm830-mtp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
index b53f7ac..886e792 100644
--- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
@@ -76,6 +76,7 @@
compatible = "qcom,qpnp-smb2";
#address-cells = <1>;
#size-cells = <1>;
+ #cooling-cells = <2>;
qcom,pmic-revid = <&pmi8998_revid>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
index 9ead234..e3f7036 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
@@ -373,11 +373,13 @@
client-id-based;
client-names =
"csiphy0", "csiphy1", "csiphy2", "cci0",
+ "csid0", "csid1", "csid2",
"ife0", "ife1", "ife2", "ipe0",
"ipe1", "cam-cdm-intf0", "cpas-cdm0", "bps0",
"icp0", "jpeg-dma0", "jpeg0", "fd0";
client-axi-port-names =
"cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1",
+ "cam_hf_1", "cam_hf_2", "cam_hf_2",
"cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1",
"cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1",
"cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
new file mode 100644
index 0000000..fff9160
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp-overlay.dts
@@ -0,0 +1,24 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "sdm845.dtsi"
+#include "sdm845-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v1 CDP";
+ compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <1 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
index 2c9c012..106d0c6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
@@ -374,30 +374,110 @@
qcom,hw-settle-time = <0>;
qcom,btm-channel-number = <0x60>;
};
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x68>;
+ qcom,thermal-node;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm1";
+ reg = <0x4f>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x78>;
+ qcom,thermal-node;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x80>;
+ qcom,thermal-node;
+ };
};
&thermal_zones {
xo-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4c>;
+ thermal-sensors = <&pm8998_adc_tm 0x4c>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
msm-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4d>;
+ thermal-sensors = <&pm8998_adc_tm 0x4d>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
pa-therm1-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4f>;
+ thermal-sensors = <&pm8998_adc_tm 0x4f>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
quiet-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x51>;
+ thermal-sensors = <&pm8998_adc_tm 0x51>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
new file mode 100644
index 0000000..79fa580
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp-overlay.dts
@@ -0,0 +1,24 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "sdm845.dtsi"
+#include "sdm845-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v1 MTP";
+ compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
+ qcom,msm-id = <321 0x0>;
+ qcom,board-id = <8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
index e4261e2..3dc45ae 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
@@ -357,30 +357,110 @@
qcom,hw-settle-time = <0>;
qcom,btm-channel-number = <0x60>;
};
+
+ chan@4c {
+ label = "xo_therm";
+ reg = <0x4c>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x68>;
+ qcom,thermal-node;
+ };
+
+ chan@4d {
+ label = "msm_therm";
+ reg = <0x4d>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x70>;
+ qcom,thermal-node;
+ };
+
+ chan@4f {
+ label = "pa_therm1";
+ reg = <0x4f>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x78>;
+ qcom,thermal-node;
+ };
+
+ chan@51 {
+ label = "quiet_therm";
+ reg = <0x51>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,btm-channel-number = <0x80>;
+ qcom,thermal-node;
+ };
};
&thermal_zones {
xo-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4c>;
+ thermal-sensors = <&pm8998_adc_tm 0x4c>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
msm-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4d>;
+ thermal-sensors = <&pm8998_adc_tm 0x4d>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
pa-therm1-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x4f>;
+ thermal-sensors = <&pm8998_adc_tm 0x4f>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
quiet-therm-adc {
polling-delay-passive = <0>;
polling-delay = <0>;
- thermal-sensors = <&pm8998_vadc 0x51>;
+ thermal-sensors = <&pm8998_adc_tm 0x51>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
index aac63ee..6fb6fb8 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
@@ -305,7 +305,7 @@
usb_audio_qmi_dev {
compatible = "qcom,usb-audio-qmi-dev";
- iommus = <&apps_smmu 0x182c>;
+ iommus = <&apps_smmu 0x182c 0x0>;
qcom,usb-audio-stream-id = <0xc>;
qcom,usb-audio-intr-num = <2>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dts b/arch/arm64/boot/dts/qcom/sdm845.dts
new file mode 100644
index 0000000..a3fa3af
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845.dts
@@ -0,0 +1,21 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "sdm845.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM845 v1 SoC";
+ compatible = "qcom,sdm845";
+ qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 67e0493..5ae733b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -741,7 +741,9 @@
< 1363200 >,
< 1440000 >,
< 1516800 >,
- < 1593600 >;
+ < 1593600 >,
+ < 1651200 >,
+ < 1708800 >;
qcom,cpufreq-table-4 =
< 300000 >,
@@ -765,7 +767,9 @@
< 1728000 >,
< 1804800 >,
< 1881600 >,
- < 1958400 >;
+ < 1958400 >,
+ < 2035200 >,
+ < 2092800 >;
};
cpubw: qcom,cpubw {
@@ -886,7 +890,9 @@
< 729600 >,
< 806400 >,
< 883200 >,
- < 960000 >;
+ < 960000 >,
+ < 1036800 >,
+ < 1094400 >;
};
l3_cpu4: qcom,l3-cpu4 {
@@ -904,7 +910,9 @@
< 729600 >,
< 806400 >,
< 883200 >,
- < 960000 >;
+ < 960000 >,
+ < 1036800 >,
+ < 1094400 >;
};
devfreq_l3lat_0: qcom,cpu0-l3lat-mon {
@@ -1021,11 +1029,14 @@
<0x178b0000 0x1000>,
<0x17d42400 0x0c00>,
<0x17d44400 0x0c00>,
- <0x17d46c00 0x0c00>;
+ <0x17d46c00 0x0c00>,
+ <0x00784130 0x4>,
+ <0x00784130 0x4>,
+ <0x00784130 0x4>;
reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
- "l3_pll", "pwrcl_pll", "perfcl_pll",
- "l3_sequencer", "pwrcl_sequencer",
- "perfcl_sequencer";
+ "l3_pll", "pwrcl_pll", "perfcl_pll", "l3_sequencer",
+ "pwrcl_sequencer", "perfcl_sequencer", "l3_efuse",
+ "pwrcl_efuse", "perfcl_efuse";
vdd-l3-supply = <&apc0_l3_vreg>;
vdd-pwrcl-supply = <&apc0_pwrcl_vreg>;
@@ -1038,7 +1049,22 @@
< 576000000 0x5014031e 0x00002020 0x1 4 >,
< 652800000 0x401c0422 0x00002020 0x1 5 >,
< 729600000 0x401c0526 0x00002020 0x1 6 >,
- < 806400000 0x401c062a 0x00002222 0x1 7 >;
+ < 806400000 0x401c062a 0x00002222 0x1 7 >,
+ < 883200000 0x4024072e 0x00002525 0x2 8 >,
+ < 960000000 0x40240832 0x00002828 0x2 9 >;
+
+ qcom,l3-speedbin1-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 422400000 0x50140116 0x00002020 0x1 2 >,
+ < 499200000 0x5014021a 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 729600000 0x401c0526 0x00002020 0x1 6 >,
+ < 806400000 0x401c062a 0x00002222 0x1 7 >,
+ < 883200000 0x4024072e 0x00002525 0x2 8 >,
+ < 960000000 0x40240832 0x00002828 0x2 9 >,
+ < 1036800000 0x40240936 0x00002b2b 0x3 10 >,
+ < 1094400000 0x402c0a39 0x00002e2e 0x3 11 >;
qcom,pwrcl-speedbin0-v0 =
< 300000000 0x000c000f 0x00002020 0x1 1 >,
@@ -1052,7 +1078,33 @@
< 979200000 0x40240833 0x00002929 0x1 9 >,
< 1056000000 0x402c0937 0x00002c2c 0x1 10 >,
< 1132800000 0x402c0a3b 0x00002f2f 0x1 11 >,
- < 1209600000 0x402c0b3f 0x00003333 0x1 12 >;
+ < 1209600000 0x402c0b3f 0x00003232 0x1 12 >,
+ < 1286400000 0x40340c43 0x00003636 0x2 13 >,
+ < 1363200000 0x40340d47 0x00003939 0x2 14 >,
+ < 1440000000 0x40340e4b 0x00003c3c 0x2 15 >,
+ < 1516800000 0x403c0f4f 0x00003f3f 0x2 16 >,
+ < 1593600000 0x403c1053 0x00004242 0x2 17 >;
+
+ qcom,pwrcl-speedbin1-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 422400000 0x50140116 0x00002020 0x1 2 >,
+ < 499200000 0x5014021a 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 748800000 0x401c0527 0x00002020 0x1 6 >,
+ < 825600000 0x401c062b 0x00002222 0x1 7 >,
+ < 902400000 0x4024072f 0x00002626 0x1 8 >,
+ < 979200000 0x40240833 0x00002929 0x1 9 >,
+ < 1056000000 0x402c0937 0x00002c2c 0x1 10 >,
+ < 1132800000 0x402c0a3b 0x00002f2f 0x1 11 >,
+ < 1209600000 0x402c0b3f 0x00003232 0x1 12 >,
+ < 1286400000 0x40340c43 0x00003636 0x2 13 >,
+ < 1363200000 0x40340d47 0x00003939 0x2 14 >,
+ < 1440000000 0x40340e4b 0x00003c3c 0x2 15 >,
+ < 1516800000 0x403c0f4f 0x00003f3f 0x2 16 >,
+ < 1593600000 0x403c1053 0x00004242 0x2 17 >,
+ < 1651200000 0x403c1156 0x00004545 0x3 18 >,
+ < 1708800000 0x40441259 0x00004747 0x3 19 >;
qcom,perfcl-speedbin0-v0 =
< 300000000 0x000c000f 0x00002020 0x1 1 >,
@@ -1066,7 +1118,43 @@
< 960000000 0x40240832 0x00002828 0x1 9 >,
< 1036800000 0x40240936 0x00002b2b 0x1 10 >,
< 1113600000 0x402c0a3a 0x00002e2e 0x1 11 >,
- < 1190400000 0x402c0b3e 0x00003232 0x1 12 >;
+ < 1190400000 0x402c0b3e 0x00003232 0x1 12 >,
+ < 1267200000 0x40340c42 0x00003535 0x2 13 >,
+ < 1344000000 0x40340d46 0x00003838 0x2 14 >,
+ < 1420800000 0x40340e4a 0x00003b3b 0x2 15 >,
+ < 1497600000 0x403c0f4e 0x00003e3e 0x2 16 >,
+ < 1574400000 0x403c1052 0x00004242 0x2 17 >,
+ < 1651200000 0x403c1156 0x00004545 0x2 18 >,
+ < 1728000000 0x4044125a 0x00004848 0x3 19 >,
+ < 1804800000 0x4044135e 0x00004b4b 0x3 20 >,
+ < 1881600000 0x404c1462 0x00004e4e 0x3 21 >,
+ < 1958400000 0x404c1566 0x00005252 0x3 22 >;
+
+ qcom,perfcl-speedbin1-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 422400000 0x50140116 0x00002020 0x1 2 >,
+ < 499200000 0x5014021a 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 729600000 0x401c0526 0x00002020 0x1 6 >,
+ < 806400000 0x401c062a 0x00002222 0x1 7 >,
+ < 883200000 0x4024072e 0x00002525 0x1 8 >,
+ < 960000000 0x40240832 0x00002828 0x1 9 >,
+ < 1036800000 0x40240936 0x00002b2b 0x1 10 >,
+ < 1113600000 0x402c0a3a 0x00002e2e 0x1 11 >,
+ < 1190400000 0x402c0b3e 0x00003232 0x1 12 >,
+ < 1267200000 0x40340c42 0x00003535 0x2 13 >,
+ < 1344000000 0x40340d46 0x00003838 0x2 14 >,
+ < 1420800000 0x40340e4a 0x00003b3b 0x2 15 >,
+ < 1497600000 0x403c0f4e 0x00003e3e 0x2 16 >,
+ < 1574400000 0x403c1052 0x00004242 0x2 17 >,
+ < 1651200000 0x403c1156 0x00004545 0x2 18 >,
+ < 1728000000 0x4044125a 0x00004848 0x3 19 >,
+ < 1804800000 0x4044135e 0x00004b4b 0x3 20 >,
+ < 1881600000 0x404c1462 0x00004e4e 0x3 21 >,
+ < 1958400000 0x404c1566 0x00005252 0x3 22 >,
+ < 2035200000 0x404c166a 0x00005555 0x3 23 >,
+ < 2092800000 0x4054176d 0x00005757 0x3 24 >;
qcom,l3-min-cpr-vc-bin0 = <7>;
qcom,pwrcl-min-cpr-vc-bin0 = <6>;
@@ -2605,10 +2693,17 @@
<0 424 0 /* CE10 */ >,
<0 425 0 /* CE11 */ >;
qcom,wlan-msa-memory = <0x100000>;
+
+ vdd-0.8-cx-mx-supply = <&pm8998_l5>;
+ vdd-1.8-xo-supply = <&pm8998_l7>;
+ vdd-1.3-rfa-supply = <&pm8998_l17>;
+ vdd-3.3-ch0-supply = <&pm8998_l25>;
+ qcom,vdd-0.8-cx-mx-config = <800000 800000>;
+ qcom,vdd-3.3-ch0-config = <3104000 3312000>;
};
thermal_zones: thermal-zones {
- aoss0-ts0-h {
+ aoss0-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -2622,7 +2717,7 @@
};
};
- cpu0-silver-ts0-h {
+ cpu0-silver-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -2636,7 +2731,7 @@
};
};
- cpu1-silver-ts0-h {
+ cpu1-silver-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -2650,7 +2745,7 @@
};
};
- cpu2-silver-ts0-h {
+ cpu2-silver-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -2664,7 +2759,7 @@
};
};
- cpu3-silver-ts0-h {
+ cpu3-silver-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 4>;
@@ -2678,7 +2773,7 @@
};
};
- kryo-l3-0-ts0-h {
+ kryo-l3-0-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 5>;
@@ -2692,7 +2787,7 @@
};
};
- kryo-l3-1-ts0-h {
+ kryo-l3-1-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 6>;
@@ -2706,7 +2801,7 @@
};
};
- cpu0-gold-ts0-h {
+ cpu0-gold-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 7>;
@@ -2720,7 +2815,7 @@
};
};
- cpu1-gold-ts0-h {
+ cpu1-gold-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 8>;
@@ -2734,7 +2829,7 @@
};
};
- cpu2-gold-ts0-h {
+ cpu2-gold-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 9>;
@@ -2748,7 +2843,7 @@
};
};
- cpu3-gold-ts0-h {
+ cpu3-gold-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 10>;
@@ -2762,7 +2857,7 @@
};
};
- gpu0-ts0-h {
+ gpu0-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
@@ -2776,7 +2871,7 @@
};
};
- gpu1-ts0-h {
+ gpu1-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "user_space";
@@ -2790,7 +2885,7 @@
};
};
- aoss1-ts1-h {
+ aoss1-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 0>;
@@ -2804,7 +2899,7 @@
};
};
- mdm-dsp-ts1-h {
+ mdm-dsp-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 1>;
@@ -2820,7 +2915,7 @@
- ddr-ts1-h {
+ ddr-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
@@ -2834,7 +2929,7 @@
};
};
- wlan-ts1-h {
+ wlan-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 3>;
@@ -2848,7 +2943,7 @@
};
};
- compute-hvx-ts1-h {
+ compute-hvx-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 4>;
@@ -2862,7 +2957,7 @@
};
};
- camera-ts1-h {
+ camera-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 5>;
@@ -2876,7 +2971,7 @@
};
};
- mmss-ts1-h {
+ mmss-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 6>;
@@ -2890,7 +2985,7 @@
};
};
- mdm-core-ts1-h {
+ mdm-core-usr {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&tsens1 7>;
@@ -2904,7 +2999,7 @@
};
};
- gpu0 {
+ gpu0-step {
polling-delay-passive = <10>;
polling-delay = <0>;
thermal-sensors = <&tsens0 11>;
@@ -2925,7 +3020,7 @@
};
};
- gpu1 {
+ gpu1-step {
polling-delay-passive = <10>;
polling-delay = <0>;
thermal-sensors = <&tsens0 12>;
@@ -2946,7 +3041,7 @@
};
};
- pop-mem {
+ pop-mem-step {
polling-delay-passive = <10>;
polling-delay = <0>;
thermal-sensors = <&tsens1 2>;
@@ -2967,7 +3062,7 @@
};
};
- aoss0-ts0-l {
+ aoss0-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -2996,7 +3091,7 @@
};
};
- cpu0-silver-ts0-l {
+ cpu0-silver-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3025,7 +3120,7 @@
};
};
- cpu1-silver-ts0-l {
+ cpu1-silver-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3054,7 +3149,7 @@
};
};
- cpu2-silver-ts0-l {
+ cpu2-silver-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3083,7 +3178,7 @@
};
};
- cpu3-silver-ts0-l {
+ cpu3-silver-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3112,7 +3207,7 @@
};
};
- kryo-l3-0-ts0-l {
+ kryo-l3-0-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3141,7 +3236,7 @@
};
};
- kryo-l3-1-ts0-l {
+ kryo-l3-1-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3170,7 +3265,7 @@
};
};
- cpu0-gold-ts0-l {
+ cpu0-gold-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3199,7 +3294,7 @@
};
};
- cpu1-gold-ts0-l {
+ cpu1-gold-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3228,7 +3323,7 @@
};
};
- cpu2-gold-ts0-l {
+ cpu2-gold-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3257,11 +3352,11 @@
};
};
- cpu3-gold-ts0-l {
+ cpu3-gold-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
- thermal-sensors = <&tsens0 9>;
+ thermal-sensors = <&tsens0 10>;
tracks-low;
trips {
cpug3_trip: cpug3-trip {
@@ -3286,11 +3381,11 @@
};
};
- gpu0-ts0-l {
+ gpu0-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
- thermal-sensors = <&tsens0 10>;
+ thermal-sensors = <&tsens0 11>;
tracks-low;
trips {
gpu0_trip_l: gpu0-trip {
@@ -3315,11 +3410,11 @@
};
};
- gpu1-ts0-l {
+ gpu1-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
- thermal-sensors = <&tsens0 11>;
+ thermal-sensors = <&tsens0 12>;
tracks-low;
trips {
gpu1_trip_l: gpu1-trip_l {
@@ -3344,7 +3439,7 @@
};
};
- aoss1-ts1-l {
+ aoss1-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3373,7 +3468,7 @@
};
};
- mdm-dsp-ts1-l {
+ mdm-dsp-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3402,7 +3497,7 @@
};
};
- ddr-ts1-l {
+ ddr-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3431,7 +3526,7 @@
};
};
- wlan-ts1-l {
+ wlan-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3460,7 +3555,7 @@
};
};
- compute-hvx-ts1-l {
+ compute-hvx-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3489,7 +3584,7 @@
};
};
- camera-ts1-l {
+ camera-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3518,7 +3613,7 @@
};
};
- mmss-ts1-l {
+ mmss-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
@@ -3547,7 +3642,7 @@
};
};
- mdm-core-ts1-l {
+ mdm-core-lowf {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-governor = "low_limits_floor";
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index 9b5de00..86bae12 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -527,7 +527,6 @@
CONFIG_MAGIC_SYSRQ=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_IPC_LOGGING=y
CONFIG_CPU_FREQ_SWITCH_PROFILER=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 615150a..1436a40 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -576,7 +576,6 @@
CONFIG_PANIC_ON_RT_THROTTLING=y
CONFIG_SCHEDSTATS=y
CONFIG_SCHED_STACK_END_CHECK=y
-CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
index 6296c40..adbabea 100644
--- a/drivers/clk/qcom/camcc-sdm845.c
+++ b/drivers/clk/qcom/camcc-sdm845.c
@@ -764,7 +764,8 @@
};
static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = {
- F(24000000, P_CAM_CC_PLL3_OUT_EVEN, 16, 0, 0),
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(24000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 2),
F(33333333, P_CAM_CC_PLL0_OUT_EVEN, 2, 1, 9),
F(34285714, P_CAM_CC_PLL2_OUT_EVEN, 14, 0, 0),
{ }
diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c
index 61067ca..5fb870b 100644
--- a/drivers/clk/qcom/clk-cpu-osm.c
+++ b/drivers/clk/qcom/clk-cpu-osm.c
@@ -54,10 +54,10 @@
#define OSM_REG_SIZE 32
-#define L3_EFUSE_SHIFT 0
-#define L3_EFUSE_MASK 0
-#define PWRCL_EFUSE_SHIFT 0
-#define PWRCL_EFUSE_MASK 0
+#define L3_EFUSE_SHIFT 29
+#define L3_EFUSE_MASK 0x7
+#define PWRCL_EFUSE_SHIFT 29
+#define PWRCL_EFUSE_MASK 0x7
#define PERFCL_EFUSE_SHIFT 29
#define PERFCL_EFUSE_MASK 0x7
@@ -2149,6 +2149,20 @@
/* efuse speed bin fuses are optional */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "l3_efuse");
+ if (res) {
+ pbase = (unsigned long)res->start;
+ vbase = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!vbase) {
+ dev_err(&pdev->dev, "Unable to map in l3_efuse base\n");
+ return -ENOMEM;
+ }
+ l3_clk.pbases[EFUSE_BASE] = pbase;
+ l3_clk.vbases[EFUSE_BASE] = vbase;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"pwrcl_efuse");
if (res) {
pbase = (unsigned long)res->start;
@@ -2250,7 +2264,7 @@
static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
{
int rc = 0, cpu, i;
- int speedbin = 0, pvs_ver = 0;
+ int pvs_ver = 0;
u32 pte_efuse, val;
int num_clks = ARRAY_SIZE(osm_qcom_clk_hws);
struct clk *ext_xo_clk, *clk;
@@ -2307,11 +2321,11 @@
l3_clk.speedbin = ((pte_efuse >> L3_EFUSE_SHIFT) &
L3_EFUSE_MASK);
snprintf(l3speedbinstr, ARRAY_SIZE(l3speedbinstr),
- "qcom,l3-speedbin%d-v%d", speedbin, pvs_ver);
+ "qcom,l3-speedbin%d-v%d", l3_clk.speedbin, pvs_ver);
}
dev_info(&pdev->dev, "using L3 speed bin %u and pvs_ver %d\n",
- speedbin, pvs_ver);
+ l3_clk.speedbin, pvs_ver);
rc = clk_osm_get_lut(pdev, &l3_clk, l3speedbinstr);
if (rc) {
@@ -2326,11 +2340,12 @@
pwrcl_clk.speedbin = ((pte_efuse >> PWRCL_EFUSE_SHIFT) &
PWRCL_EFUSE_MASK);
snprintf(pwrclspeedbinstr, ARRAY_SIZE(pwrclspeedbinstr),
- "qcom,pwrcl-speedbin%d-v%d", speedbin, pvs_ver);
+ "qcom,pwrcl-speedbin%d-v%d", pwrcl_clk.speedbin,
+ pvs_ver);
}
dev_info(&pdev->dev, "using pwrcl speed bin %u and pvs_ver %d\n",
- speedbin, pvs_ver);
+ pwrcl_clk.speedbin, pvs_ver);
rc = clk_osm_get_lut(pdev, &pwrcl_clk, pwrclspeedbinstr);
if (rc) {
@@ -2345,11 +2360,12 @@
perfcl_clk.speedbin = ((pte_efuse >> PERFCL_EFUSE_SHIFT) &
PERFCL_EFUSE_MASK);
snprintf(perfclspeedbinstr, ARRAY_SIZE(perfclspeedbinstr),
- "qcom,perfcl-speedbin%d-v%d", speedbin, pvs_ver);
+ "qcom,perfcl-speedbin%d-v%d", perfcl_clk.speedbin,
+ pvs_ver);
}
dev_info(&pdev->dev, "using perfcl speed bin %u and pvs_ver %d\n",
- speedbin, pvs_ver);
+ perfcl_clk.speedbin, pvs_ver);
rc = clk_osm_get_lut(pdev, &perfcl_clk, perfclspeedbinstr);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index c7260f9..f187ad1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1556,19 +1556,9 @@
return rc;
}
-/**
- * dsi_ctrl_setup() - Setup DSI host hardware while coming out of idle screen.
- * @dsi_ctrl: DSI controller handle.
- *
- * Initializes DSI controller hardware with host configuration provided by
- * dsi_ctrl_update_host_config(). Initialization can be performed only during
- * DSI_CTRL_POWER_CORE_CLK_ON state and after the PHY SW reset has been
- * performed.
- *
- * Return: error code.
- */
int dsi_ctrl_setup(struct dsi_ctrl *dsi_ctrl)
{
+ struct dsi_mode_info video_timing;
int rc = 0;
if (!dsi_ctrl) {
@@ -1578,6 +1568,12 @@
mutex_lock(&dsi_ctrl->ctrl_lock);
+ /* replace video mode width with actual roi width */
+ memcpy(&video_timing, &dsi_ctrl->host_config.video_timing,
+ sizeof(video_timing));
+ video_timing.h_active = dsi_ctrl->roi.w;
+ video_timing.v_active = dsi_ctrl->roi.h;
+
dsi_ctrl->hw.ops.setup_lane_map(&dsi_ctrl->hw,
&dsi_ctrl->host_config.lane_map);
@@ -1590,8 +1586,8 @@
&dsi_ctrl->host_config.u.cmd_engine);
dsi_ctrl->hw.ops.setup_cmd_stream(&dsi_ctrl->hw,
- &dsi_ctrl->host_config.video_timing,
- dsi_ctrl->host_config.video_timing.h_active * 3,
+ &video_timing,
+ video_timing.h_active * 3,
0x0);
dsi_ctrl->hw.ops.cmd_engine_en(&dsi_ctrl->hw, true);
} else {
@@ -1611,6 +1607,26 @@
return rc;
}
+int dsi_ctrl_set_roi(struct dsi_ctrl *dsi_ctrl, struct dsi_rect *roi,
+ bool *changed)
+{
+ int rc = 0;
+
+ if (!dsi_ctrl || !roi || !changed) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&dsi_ctrl->ctrl_lock);
+ if (!dsi_rect_is_equal(&dsi_ctrl->roi, roi)) {
+ *changed = true;
+ memcpy(&dsi_ctrl->roi, roi, sizeof(dsi_ctrl->roi));
+ } else
+ *changed = false;
+ mutex_unlock(&dsi_ctrl->ctrl_lock);
+ return rc;
+}
+
/**
* dsi_ctrl_phy_reset_config() - Mask/unmask propagation of ahb reset signal
* to DSI PHY hardware.
@@ -1789,6 +1805,13 @@
pr_debug("[DSI_%d]Host config updated\n", ctrl->cell_index);
memcpy(&ctrl->host_config, config, sizeof(ctrl->host_config));
+ ctrl->mode_bounds.x = ctrl->host_config.video_timing.h_active *
+ ctrl->horiz_index;
+ ctrl->mode_bounds.y = 0;
+ ctrl->mode_bounds.w = ctrl->host_config.video_timing.h_active;
+ ctrl->mode_bounds.h = ctrl->host_config.video_timing.v_active;
+ memcpy(&ctrl->roi, &ctrl->mode_bounds, sizeof(ctrl->mode_bounds));
+ ctrl->roi.x = 0;
error:
mutex_unlock(&ctrl->ctrl_lock);
return rc;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f8adbea..f89cb68 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -168,6 +168,7 @@
* struct dsi_ctrl - DSI controller object
* @pdev: Pointer to platform device.
* @cell_index: Instance cell id.
+ * @horiz_index: Index in physical horizontal CTRL layout, 0 = leftmost
* @name: Name of the controller instance.
* @refcount: ref counter.
* @ctrl_lock: Mutex for hardware and object access.
@@ -182,6 +183,10 @@
* @pwr_info: Power information.
* @axi_bus_info: AXI bus information.
* @host_config: Current host configuration.
+ * @mode_bounds: Boundaries of the default mode ROI.
+ * Origin is at top left of all CTRLs.
+ * @roi: Partial update region of interest.
+ * Origin is top left of this CTRL.
* @tx_cmd_buf: Tx command buffer.
* @cmd_buffer_size: Size of command buffer.
* @debugfs_root: Root for debugfs entries.
@@ -189,6 +194,7 @@
struct dsi_ctrl {
struct platform_device *pdev;
u32 cell_index;
+ u32 horiz_index;
const char *name;
u32 refcount;
struct mutex ctrl_lock;
@@ -209,6 +215,9 @@
struct dsi_ctrl_bus_scale_info axi_bus_info;
struct dsi_host_config host_config;
+ struct dsi_rect mode_bounds;
+ struct dsi_rect roi;
+
/* Command tx and rx */
struct drm_gem_object *tx_cmd_buf;
u32 cmd_buffer_size;
@@ -387,11 +396,25 @@
* DSI_CTRL_POWER_CORE_CLK_ON state and after the PHY SW reset has been
* performed.
*
+ * Also used to program the video mode timing values.
+ *
* Return: error code.
*/
int dsi_ctrl_setup(struct dsi_ctrl *dsi_ctrl);
/**
+ * dsi_ctrl_set_roi() - Set DSI controller's region of interest
+ * @dsi_ctrl: DSI controller handle.
+ * @roi: Region of interest rectangle, must be less than mode bounds
+ * @changed: Output parameter, set to true of the controller's ROI was
+ * dirtied by setting the new ROI, and DCS cmd update needed
+ *
+ * Return: error code.
+ */
+int dsi_ctrl_set_roi(struct dsi_ctrl *dsi_ctrl, struct dsi_rect *roi,
+ bool *changed);
+
+/**
* dsi_ctrl_set_tpg_state() - enable/disable test pattern on the controller
* @dsi_ctrl: DSI controller handle.
* @on: enable/disable test pattern.
@@ -401,7 +424,6 @@
*
* Return: error code.
*/
-
int dsi_ctrl_set_tpg_state(struct dsi_ctrl *dsi_ctrl, bool on);
/**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
index 563285d..cf36315 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
@@ -411,4 +411,40 @@
struct msm_mode_info *mode_info;
};
+/**
+ * struct dsi_rect - dsi rectangle representation
+ * Note: sde_rect is also using u16, this must be maintained for memcpy
+ */
+struct dsi_rect {
+ u16 x;
+ u16 y;
+ u16 w;
+ u16 h;
+};
+
+/**
+ * dsi_rect_intersect - intersect two rectangles
+ * @r1: first rectangle
+ * @r2: scissor rectangle
+ * @result: result rectangle, all 0's on no intersection found
+ */
+void dsi_rect_intersect(const struct dsi_rect *r1,
+ const struct dsi_rect *r2,
+ struct dsi_rect *result);
+
+/**
+ * dsi_rect_is_equal - compares two rects
+ * @r1: rect value to compare
+ * @r2: rect value to compare
+ *
+ * Returns true if the rects are same
+ */
+static inline bool dsi_rect_is_equal(struct dsi_rect *r1,
+ struct dsi_rect *r2)
+{
+ return r1->x == r2->x && r1->y == r2->y && r1->w == r2->w &&
+ r1->h == r2->h;
+}
+
+
#endif /* _DSI_DEFS_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 231f29b..c2cf2cb 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -38,6 +38,30 @@
static struct dsi_display *main_display;
+void dsi_rect_intersect(const struct dsi_rect *r1,
+ const struct dsi_rect *r2,
+ struct dsi_rect *result)
+{
+ int l, t, r, b;
+
+ if (!r1 || !r2 || !result)
+ return;
+
+ l = max(r1->x, r2->x);
+ t = max(r1->y, r2->y);
+ r = min((r1->x + r1->w), (r2->x + r2->w));
+ b = min((r1->y + r1->h), (r2->y + r2->h));
+
+ if (r <= l || b <= t) {
+ memset(result, 0, sizeof(*result));
+ } else {
+ result->x = l;
+ result->y = t;
+ result->w = r - l;
+ result->h = b - t;
+ }
+}
+
int dsi_display_set_backlight(void *display, u32 bl_lvl)
{
struct dsi_display *dsi_display = display;
@@ -2285,6 +2309,7 @@
display->name, i, rc);
goto error_ctrl_deinit;
}
+ display_ctrl->ctrl->horiz_index = i;
rc = dsi_phy_drv_init(display_ctrl->phy);
if (rc) {
@@ -2750,6 +2775,10 @@
display->panel->mode.panel_mode);
break;
}
+
+ memcpy(&info->roi_caps, &display->panel->roi_caps,
+ sizeof(info->roi_caps));
+
error:
mutex_unlock(&display->display_lock);
return rc;
@@ -3036,10 +3065,110 @@
return rc;
}
+static int dsi_display_calc_ctrl_roi(const struct dsi_display *display,
+ const struct dsi_display_ctrl *ctrl,
+ const struct msm_roi_list *req_rois,
+ struct dsi_rect *out_roi)
+{
+ const struct dsi_rect *bounds = &ctrl->ctrl->mode_bounds;
+ struct dsi_rect req_roi = { 0 };
+ int rc = 0;
+
+ if (req_rois->num_rects > display->panel->roi_caps.num_roi) {
+ pr_err("request for %d rois greater than max %d\n",
+ req_rois->num_rects,
+ display->panel->roi_caps.num_roi);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ /**
+ * if no rois, user wants to reset back to full resolution
+ * note: h_active is already divided by ctrl_count
+ */
+ if (!req_rois->num_rects) {
+ *out_roi = *bounds;
+ goto exit;
+ }
+
+ /* intersect with the bounds */
+ req_roi.x = req_rois->roi[0].x1;
+ req_roi.y = req_rois->roi[0].y1;
+ req_roi.w = req_rois->roi[0].x2 - req_rois->roi[0].x1;
+ req_roi.h = req_rois->roi[0].y2 - req_rois->roi[0].y1;
+ dsi_rect_intersect(&req_roi, bounds, out_roi);
+
+exit:
+ /* adjust the ctrl origin to be top left within the ctrl */
+ out_roi->x = out_roi->x - bounds->x;
+
+ pr_debug("ctrl%d:%d: req (%d,%d,%d,%d) bnd (%d,%d,%d,%d) out (%d,%d,%d,%d)\n",
+ ctrl->dsi_ctrl_idx, ctrl->ctrl->cell_index,
+ req_roi.x, req_roi.y, req_roi.w, req_roi.h,
+ bounds->x, bounds->y, bounds->w, bounds->h,
+ out_roi->x, out_roi->y, out_roi->w, out_roi->h);
+
+ return rc;
+}
+
+static int dsi_display_set_roi(struct dsi_display *display,
+ struct msm_roi_list *rois)
+{
+ int rc = 0;
+ int i;
+
+ if (!display || !rois || !display->panel)
+ return -EINVAL;
+
+ if (!display->panel->roi_caps.enabled)
+ return 0;
+
+ for (i = 0; i < display->ctrl_count; i++) {
+ struct dsi_display_ctrl *ctrl = &display->ctrl[i];
+ struct dsi_rect ctrl_roi;
+ bool changed = false;
+
+ rc = dsi_display_calc_ctrl_roi(display, ctrl, rois, &ctrl_roi);
+ if (rc) {
+ pr_err("dsi_display_calc_ctrl_roi failed rc %d\n", rc);
+ return rc;
+ }
+
+ rc = dsi_ctrl_set_roi(ctrl->ctrl, &ctrl_roi, &changed);
+ if (rc) {
+ pr_err("dsi_ctrl_set_roi failed rc %d\n", rc);
+ return rc;
+ }
+
+ if (!changed)
+ continue;
+
+ /* send the new roi to the panel via dcs commands */
+ rc = dsi_panel_send_roi_dcs(display->panel, i, &ctrl_roi);
+ if (rc) {
+ pr_err("dsi_panel_set_roi failed rc %d\n", rc);
+ return rc;
+ }
+
+ /* re-program the ctrl with the timing based on the new roi */
+ rc = dsi_ctrl_setup(ctrl->ctrl);
+ if (rc) {
+ pr_err("dsi_ctrl_setup failed rc %d\n", rc);
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
int dsi_display_pre_kickoff(struct dsi_display *display,
struct msm_display_kickoff_params *params)
{
- return 0;
+ int rc = 0;
+
+ rc = dsi_display_set_roi(display, params->rois);
+
+ return rc;
}
int dsi_display_enable(struct dsi_display *display)
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
index 3f4bb5a5..53f0098 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_drm.c
@@ -379,6 +379,25 @@
break;
}
+ if (panel->roi_caps.enabled) {
+ sde_kms_info_add_keyint(info, "partial_update_num_roi",
+ panel->roi_caps.num_roi);
+ sde_kms_info_add_keyint(info, "partial_update_xstart",
+ panel->roi_caps.align.xstart_pix_align);
+ sde_kms_info_add_keyint(info, "partial_update_walign",
+ panel->roi_caps.align.width_pix_align);
+ sde_kms_info_add_keyint(info, "partial_update_wmin",
+ panel->roi_caps.align.min_width);
+ sde_kms_info_add_keyint(info, "partial_update_ystart",
+ panel->roi_caps.align.ystart_pix_align);
+ sde_kms_info_add_keyint(info, "partial_update_halign",
+ panel->roi_caps.align.height_pix_align);
+ sde_kms_info_add_keyint(info, "partial_update_hmin",
+ panel->roi_caps.align.min_height);
+ sde_kms_info_add_keyint(info, "partial_update_roimerge",
+ panel->roi_caps.merge_rois);
+ }
+
end:
return 0;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index deb718c..dcb787b 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -12,10 +12,12 @@
*
*/
+#define pr_fmt(fmt) "msm-dsi-panel:[%s:%d] " fmt, __func__, __LINE__
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
+#include <video/mipi_display.h>
#include "dsi_panel.h"
#include "dsi_ctrl_hw.h"
@@ -1289,6 +1291,8 @@
"qcom,video-to-cmd-mode-switch-commands",
"qcom,video-to-cmd-mode-post-switch-commands",
"qcom,mdss-dsi-panel-status-command",
+ "PPS not parsed from DTSI, generated dynamically",
+ "ROI not parsed from DTSI, generated dynamically",
};
const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
@@ -1306,6 +1310,8 @@
"qcom,video-to-cmd-mode-switch-commands-state",
"qcom,video-to-cmd-mode-post-switch-commands-state",
"qcom,mdss-dsi-panel-status-command-state",
+ "PPS not parsed from DTSI, generated dynamically",
+ "ROI not parsed from DTSI, generated dynamically",
};
static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt)
@@ -1348,6 +1354,7 @@
cmd[i].last_command = (data[1] == 1 ? true : false);
cmd[i].msg.channel = data[2];
cmd[i].msg.flags |= (data[3] == 1 ? MIPI_DSI_MSG_REQ_ACK : 0);
+ cmd[i].msg.ctrl = 0;
cmd[i].post_wait_ms = data[4];
cmd[i].msg.tx_len = ((data[5] << 8) | (data[6]));
@@ -1376,7 +1383,7 @@
return rc;
}
-static void dsi_panel_destroy_cmd_packets(struct dsi_panel_cmd_set *set)
+void dsi_panel_destroy_cmd_packets(struct dsi_panel_cmd_set *set)
{
u32 i = 0;
struct dsi_cmd_desc *cmd;
@@ -1471,6 +1478,8 @@
for (i = DSI_CMD_SET_PRE_ON; i < DSI_CMD_SET_MAX; i++) {
set = &panel->cmd_sets[i];
set->type = i;
+ set->count = 0;
+
if (i == DSI_CMD_SET_PPS) {
rc = dsi_panel_alloc_cmd_packets(set, 1);
if (rc)
@@ -2175,6 +2184,87 @@
return rc;
}
+static int dsi_panel_parse_roi_alignment(struct device_node *of_node,
+ struct msm_roi_alignment *align)
+{
+ int len = 0, rc = 0;
+ u32 value[6];
+ struct property *data;
+
+ if (!align || !of_node)
+ return -EINVAL;
+
+ memset(align, 0, sizeof(*align));
+
+ data = of_find_property(of_node, "qcom,panel-roi-alignment", &len);
+ len /= sizeof(u32);
+ if (!data) {
+ pr_err("panel roi alignment not found\n");
+ rc = -EINVAL;
+ } else if (len != 6) {
+ pr_err("incorrect roi alignment len %d\n", len);
+ rc = -EINVAL;
+ } else {
+ rc = of_property_read_u32_array(of_node,
+ "qcom,panel-roi-alignment", value, len);
+ if (rc)
+ pr_debug("error reading panel roi alignment values\n");
+ else {
+ align->xstart_pix_align = value[0];
+ align->ystart_pix_align = value[1];
+ align->width_pix_align = value[2];
+ align->height_pix_align = value[3];
+ align->min_width = value[4];
+ align->min_height = value[5];
+ }
+
+ pr_info("roi alignment: [%d, %d, %d, %d, %d, %d]\n",
+ align->xstart_pix_align,
+ align->width_pix_align,
+ align->ystart_pix_align,
+ align->height_pix_align,
+ align->min_width,
+ align->min_height);
+ }
+
+ return rc;
+}
+
+static int dsi_panel_parse_partial_update_caps(struct dsi_panel *panel,
+ struct device_node *of_node)
+{
+ struct msm_roi_caps *roi_caps = &panel->roi_caps;
+ const char *data;
+ int rc = 0;
+
+ memset(roi_caps, 0, sizeof(*roi_caps));
+
+ data = of_get_property(of_node, "qcom,partial-update-enabled", NULL);
+ if (data) {
+ if (!strcmp(data, "dual_roi"))
+ roi_caps->num_roi = 2;
+ else
+ roi_caps->num_roi = 1;
+ }
+
+ roi_caps->merge_rois = of_property_read_bool(of_node,
+ "qcom,partial-update-roi-merge");
+
+ roi_caps->enabled = roi_caps->num_roi > 0;
+
+ pr_info("partial update num_rois=%d enabled=%d\n", roi_caps->num_roi,
+ roi_caps->enabled);
+
+ if (roi_caps->enabled)
+ rc = dsi_panel_parse_roi_alignment(of_node,
+ &panel->roi_caps.align);
+
+ if (rc)
+ memset(roi_caps, 0, sizeof(*roi_caps));
+
+ return rc;
+}
+
struct dsi_panel *dsi_panel_get(struct device *parent,
struct device_node *of_node)
{
@@ -2291,6 +2381,10 @@
if (rc)
pr_err("failed to parse hdr config, rc=%d\n", rc);
+ rc = dsi_panel_parse_partial_update_caps(panel, of_node);
+ if (rc)
+ pr_debug("failed to partial update caps, rc=%d\n", rc);
+
panel->panel_of_node = of_node;
drm_panel_init(&panel->drm_panel);
mutex_init(&panel->panel_lock);
@@ -2624,6 +2718,114 @@
return rc;
}
+static int dsi_panel_roi_prepare_dcs_cmds(struct dsi_panel *panel,
+ struct dsi_rect *roi, int ctrl_idx, int unicast)
+{
+ static const int ROI_CMD_LEN = 5;
+ struct dsi_panel_cmd_set *set = &panel->cmd_sets[DSI_CMD_SET_ROI];
+ int rc = 0;
+
+ /* DTYPE_DCS_LWRITE */
+ static char *caset, *paset;
+
+ set->cmds = NULL;
+
+ caset = kzalloc(ROI_CMD_LEN, GFP_KERNEL);
+ if (!caset) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+ caset[0] = 0x2a;
+ caset[1] = (roi->x & 0xFF00) >> 8;
+ caset[2] = roi->x & 0xFF;
+ caset[3] = ((roi->x - 1 + roi->w) & 0xFF00) >> 8;
+ caset[4] = (roi->x - 1 + roi->w) & 0xFF;
+
+ paset = kzalloc(ROI_CMD_LEN, GFP_KERNEL);
+ if (!paset) {
+ rc = -ENOMEM;
+ goto error_free_mem;
+ }
+ paset[0] = 0x2b;
+ paset[1] = (roi->y & 0xFF00) >> 8;
+ paset[2] = roi->y & 0xFF;
+ paset[3] = ((roi->y - 1 + roi->h) & 0xFF00) >> 8;
+ paset[4] = (roi->y - 1 + roi->h) & 0xFF;
+
+ set->type = DSI_CMD_SET_ROI;
+ set->state = DSI_CMD_SET_STATE_LP;
+ set->count = 2; /* send caset + paset together */
+ set->cmds = kcalloc(set->count, sizeof(*set->cmds), GFP_KERNEL);
+ if (!set->cmds) {
+ rc = -ENOMEM;
+ goto error_free_mem;
+ }
+ set->cmds[0].msg.channel = 0;
+ set->cmds[0].msg.type = MIPI_DSI_DCS_LONG_WRITE;
+ set->cmds[0].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST : 0;
+ set->cmds[0].msg.ctrl = unicast ? ctrl_idx : 0;
+ set->cmds[0].msg.tx_len = ROI_CMD_LEN;
+ set->cmds[0].msg.tx_buf = caset;
+ set->cmds[0].msg.rx_len = 0;
+ set->cmds[0].msg.rx_buf = 0;
+ set->cmds[0].last_command = 0;
+ set->cmds[0].post_wait_ms = 1;
+
+ set->cmds[1].msg.channel = 0;
+ set->cmds[1].msg.type = MIPI_DSI_DCS_LONG_WRITE;
+ set->cmds[1].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST : 0;
+ set->cmds[1].msg.ctrl = unicast ? ctrl_idx : 0;
+ set->cmds[1].msg.tx_len = ROI_CMD_LEN;
+ set->cmds[1].msg.tx_buf = paset;
+ set->cmds[1].msg.rx_len = 0;
+ set->cmds[1].msg.rx_buf = 0;
+ set->cmds[1].last_command = 1;
+ set->cmds[1].post_wait_ms = 1;
+
+ goto exit;
+
+error_free_mem:
+ kfree(caset);
+ kfree(paset);
+ kfree(set->cmds);
+
+exit:
+ return rc;
+}
+
+int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx,
+ struct dsi_rect *roi)
+{
+ int rc = 0;
+
+ if (!panel) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
+ rc = dsi_panel_roi_prepare_dcs_cmds(panel, roi, ctrl_idx, true);
+ if (rc) {
+ pr_err("[%s] failed to prepare DSI_CMD_SET_ROI cmds, rc=%d\n",
+ panel->name, rc);
+ return rc;
+ }
+ pr_debug("[%s] send roi x %d y %d w %d h %d\n", panel->name,
+ roi->x, roi->y, roi->w, roi->h);
+
+ mutex_lock(&panel->panel_lock);
+
+ rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_ROI);
+ if (rc)
+ pr_err("[%s] failed to send DSI_CMD_SET_ROI cmds, rc=%d\n",
+ panel->name, rc);
+
+ mutex_unlock(&panel->panel_lock);
+
+ dsi_panel_destroy_cmd_packets(&panel->cmd_sets[DSI_CMD_SET_ROI]);
+
+ return rc;
+}
+
int dsi_panel_enable(struct dsi_panel *panel)
{
int rc = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
index de2b5b1..4c9fbbe 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
@@ -28,6 +28,7 @@
#include "dsi_ctrl_hw.h"
#include "dsi_clk.h"
#include "dsi_pwr.h"
+#include "msm_drv.h"
#define MAX_BL_LEVEL 4096
#define DSI_CMD_PPS_SIZE 135
@@ -55,6 +56,7 @@
DSI_CMD_SET_POST_VID_TO_CMD_SWITCH,
DSI_CMD_SET_PANEL_STATUS,
DSI_CMD_SET_PPS,
+ DSI_CMD_SET_ROI,
DSI_CMD_SET_MAX
};
@@ -162,6 +164,7 @@
struct dsi_cmd_engine_cfg cmd_config;
struct dsi_dfps_capabilities dfps_caps;
+ struct msm_roi_caps roi_caps;
struct dsi_panel_cmd_set cmd_sets[DSI_CMD_SET_MAX];
struct dsi_panel_phy_props phy_props;
@@ -242,4 +245,8 @@
int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl);
int dsi_panel_update_pps(struct dsi_panel *panel);
+
+int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx,
+ struct dsi_rect *roi);
+
#endif /* _DSI_PANEL_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_dspp.c b/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
index 8df4de2..586d1f1 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_dspp.c
@@ -151,5 +151,7 @@
void sde_hw_dspp_destroy(struct sde_hw_dspp *dspp)
{
+ if (dspp)
+ reg_dmav1_deinit_dspp_ops(dspp->idx);
kfree(dspp);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
index 49af946..c33e520 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.c
@@ -553,3 +553,26 @@
BIT(0));
SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->gc.base, reg);
}
+
+int reg_dmav1_deinit_dspp_ops(enum sde_dspp idx)
+{
+ int i;
+ struct sde_hw_reg_dma_ops *dma_ops;
+
+ dma_ops = sde_reg_dma_get_ops();
+ if (IS_ERR_OR_NULL(dma_ops))
+ return -ENOTSUPP;
+
+ if (idx >= DSPP_MAX) {
+ DRM_ERROR("invalid dspp idx %x max %xd\n", idx, DSPP_MAX);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < REG_DMA_FEATURES_MAX; i++) {
+ if (!dspp_buf[i][idx])
+ continue;
+ dma_ops->dealloc_reg_dma(dspp_buf[i][idx]);
+ dspp_buf[i][idx] = NULL;
+ }
+ return 0;
+}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
index e3bf142..94e1a5c 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_reg_dma_v1_color_proc.h
@@ -51,4 +51,11 @@
* @cfg: pointer to struct sde_hw_cp_cfg
*/
void reg_dmav1_setup_dspp_gcv18(struct sde_hw_dspp *ctx, void *cfg);
+
+/**
+ * reg_dmav1_deinit_dspp_ops() - deinitialize the dspp feature op for sde v4
+ * which were initialized.
+ * @idx: dspp idx
+ */
+int reg_dmav1_deinit_dspp_ops(enum sde_dspp idx);
#endif /* _SDE_HW_REG_DMA_V1_COLOR_PROC_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index b68d736..8cc196a 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1472,6 +1472,16 @@
sde_dbg_init_dbg_buses(sde_kms->core_rev);
+ /*
+ * Now we need to read the HW catalog and initialize resources such as
+ * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
+ */
+ rc = _sde_kms_mmu_init(sde_kms);
+ if (rc) {
+ SDE_ERROR("sde_kms_mmu_init failed: %d\n", rc);
+ goto power_error;
+ }
+
/* Initialize reg dma block which is a singleton */
rc = sde_reg_dma_init(sde_kms->reg_dma, sde_kms->catalog,
sde_kms->dev);
@@ -1521,15 +1531,6 @@
sde_kms->iclient = NULL;
}
- /*
- * Now we need to read the HW catalog and initialize resources such as
- * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
- */
- rc = _sde_kms_mmu_init(sde_kms);
- if (rc) {
- SDE_ERROR("sde_kms_mmu_init failed: %d\n", rc);
- goto power_error;
- }
rc = sde_core_perf_init(&sde_kms->perf, dev, sde_kms->catalog,
&priv->phandle, priv->pclient, "core_clk");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 01dc5e1..f9449fe 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -64,6 +64,7 @@
void tmc_enable_hw(struct tmc_drvdata *drvdata)
{
drvdata->enable = true;
+ drvdata->sticky_enable = true;
writel_relaxed(TMC_CTL_CAPT_EN, drvdata->base + TMC_CTL);
}
@@ -77,6 +78,9 @@
{
int ret = 0;
+ if (!drvdata->sticky_enable)
+ return -EPERM;
+
switch (drvdata->config_type) {
case TMC_CONFIG_TYPE_ETB:
case TMC_CONFIG_TYPE_ETF:
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 3d6e823..a9de0e8 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -183,6 +183,7 @@
struct usb_qdss_ch *usbch;
struct tmc_etr_bam_data *bamdata;
bool enable_to_bam;
+ bool sticky_enable;
};
diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c
index e1c16aa..62e34cc 100644
--- a/drivers/input/misc/qpnp-power-on.c
+++ b/drivers/input/misc/qpnp-power-on.c
@@ -207,7 +207,7 @@
int pon_power_off_reason;
int num_pon_reg;
int num_pon_config;
- u32 dbc;
+ u32 dbc_time_us;
u32 uvlo;
int warm_reset_poff_type;
int hard_reset_poff_type;
@@ -219,6 +219,8 @@
u8 warm_reset_reason2;
bool is_spon;
bool store_hard_reset_reason;
+ bool kpdpwr_dbc_enable;
+ ktime_t kpdpwr_last_release_time;
};
static int pon_ship_mode_en;
@@ -381,7 +383,7 @@
int rc = 0;
u32 val;
- if (delay == pon->dbc)
+ if (delay == pon->dbc_time_us)
goto out;
if (pon->pon_input)
@@ -409,7 +411,7 @@
goto unlock;
}
- pon->dbc = delay;
+ pon->dbc_time_us = delay;
unlock:
if (pon->pon_input)
@@ -418,12 +420,34 @@
return rc;
}
+static int qpnp_pon_get_dbc(struct qpnp_pon *pon, u32 *delay)
+{
+ int rc;
+ unsigned int val;
+
+ rc = regmap_read(pon->regmap, QPNP_PON_DBC_CTL(pon), &val);
+ if (rc) {
+ pr_err("Unable to read pon_dbc_ctl rc=%d\n", rc);
+ return rc;
+ }
+ val &= QPNP_PON_DBC_DELAY_MASK(pon);
+
+ if (is_pon_gen2(pon))
+ *delay = USEC_PER_SEC /
+ (1 << (QPNP_PON_GEN2_DELAY_BIT_SHIFT - val));
+ else
+ *delay = USEC_PER_SEC /
+ (1 << (QPNP_PON_DELAY_BIT_SHIFT - val));
+
+ return rc;
+}
+
static ssize_t qpnp_pon_dbc_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct qpnp_pon *pon = dev_get_drvdata(dev);
- return snprintf(buf, QPNP_PON_BUFFER_SIZE, "%d\n", pon->dbc);
+ return snprintf(buf, QPNP_PON_BUFFER_SIZE, "%d\n", pon->dbc_time_us);
}
static ssize_t qpnp_pon_dbc_store(struct device *dev,
@@ -777,6 +801,7 @@
u8 pon_rt_bit = 0;
u32 key_status;
uint pon_rt_sts;
+ u64 elapsed_us;
cfg = qpnp_get_cfg(pon, pon_type);
if (!cfg)
@@ -786,6 +811,15 @@
if (!cfg->key_code)
return 0;
+ if (pon->kpdpwr_dbc_enable && cfg->pon_type == PON_KPDPWR) {
+ elapsed_us = ktime_us_delta(ktime_get(),
+ pon->kpdpwr_last_release_time);
+ if (elapsed_us < pon->dbc_time_us) {
+ pr_debug("Ignoring kpdpwr event - within debounce time\n");
+ return 0;
+ }
+ }
+
/* check the RT status to get the current status of the line */
rc = regmap_read(pon->regmap, QPNP_PON_RT_STS(pon), &pon_rt_sts);
if (rc) {
@@ -814,6 +848,11 @@
cfg->key_code, pon_rt_sts);
key_status = pon_rt_sts & pon_rt_bit;
+ if (pon->kpdpwr_dbc_enable && cfg->pon_type == PON_KPDPWR) {
+ if (!key_status)
+ pon->kpdpwr_last_release_time = ktime_get();
+ }
+
/*
* simulate press event in case release event occurred
* without a press event
@@ -2230,7 +2269,21 @@
}
} else {
rc = qpnp_pon_set_dbc(pon, delay);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "Unable to set PON debounce delay rc=%d\n", rc);
+ return rc;
+ }
}
+ rc = qpnp_pon_get_dbc(pon, &pon->dbc_time_us);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "Unable to get PON debounce delay rc=%d\n", rc);
+ return rc;
+ }
+
+ pon->kpdpwr_dbc_enable = of_property_read_bool(pon->pdev->dev.of_node,
+ "qcom,kpdpwr-sw-debounce");
rc = of_property_read_u32(pon->pdev->dev.of_node,
"qcom,warm-reset-poweroff-type",
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index bea5f03..0c49a64 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -81,330 +81,58 @@
static DEFINE_MUTEX(iommu_debug_attachments_lock);
static LIST_HEAD(iommu_debug_attachments);
-static struct dentry *debugfs_attachments_dir;
+/*
+ * Each group may have more than one domain; but each domain may
+ * only have one group.
+ * Used by debug tools to display the name of the device(s) associated
+ * with a particular domain.
+ */
struct iommu_debug_attachment {
struct iommu_domain *domain;
- struct device *dev;
- struct dentry *dentry;
+ struct iommu_group *group;
struct list_head list;
- unsigned long reg_offset;
};
-static int iommu_debug_attachment_info_show(struct seq_file *s, void *ignored)
-{
- struct iommu_debug_attachment *attach = s->private;
- int secure_vmid;
-
- seq_printf(s, "Domain: 0x%p\n", attach->domain);
-
- seq_puts(s, "SECURE_VMID: ");
- if (iommu_domain_get_attr(attach->domain,
- DOMAIN_ATTR_SECURE_VMID,
- &secure_vmid))
- seq_puts(s, "(Unknown)\n");
- else
- seq_printf(s, "%s (0x%x)\n",
- msm_secure_vmid_to_string(secure_vmid), secure_vmid);
-
- return 0;
-}
-
-static int iommu_debug_attachment_info_open(struct inode *inode,
- struct file *file)
-{
- return single_open(file, iommu_debug_attachment_info_show,
- inode->i_private);
-}
-
-static const struct file_operations iommu_debug_attachment_info_fops = {
- .open = iommu_debug_attachment_info_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static ssize_t iommu_debug_attachment_reg_offset_write(
- struct file *file, const char __user *ubuf, size_t count,
- loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long reg_offset;
-
- if (kstrtoul_from_user(ubuf, count, 0, ®_offset)) {
- pr_err("Invalid reg_offset format\n");
- return -EFAULT;
- }
-
- attach->reg_offset = reg_offset;
-
- return count;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_offset_fops = {
- .open = simple_open,
- .write = iommu_debug_attachment_reg_offset_write,
-};
-
-static ssize_t iommu_debug_attachment_reg_read_read(
- struct file *file, char __user *ubuf, size_t count, loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long val;
- char *val_str;
- ssize_t val_str_len;
-
- if (*offset)
- return 0;
-
- val = iommu_reg_read(attach->domain, attach->reg_offset);
- val_str = kasprintf(GFP_KERNEL, "0x%lx\n", val);
- if (!val_str)
- return -ENOMEM;
- val_str_len = strlen(val_str);
-
- if (copy_to_user(ubuf, val_str, val_str_len)) {
- pr_err("copy_to_user failed\n");
- val_str_len = -EFAULT;
- goto out;
- }
- *offset = 1; /* non-zero means we're done */
-
-out:
- kfree(val_str);
- return val_str_len;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_read_fops = {
- .open = simple_open,
- .read = iommu_debug_attachment_reg_read_read,
-};
-
-static ssize_t iommu_debug_attachment_reg_write_write(
- struct file *file, const char __user *ubuf, size_t count,
- loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long val;
-
- if (kstrtoul_from_user(ubuf, count, 0, &val)) {
- pr_err("Invalid val format\n");
- return -EFAULT;
- }
-
- iommu_reg_write(attach->domain, attach->reg_offset, val);
-
- return count;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_write_fops = {
- .open = simple_open,
- .write = iommu_debug_attachment_reg_write_write,
-};
-
-/* should be called with iommu_debug_attachments_lock locked */
-static int iommu_debug_attach_add_debugfs(
- struct iommu_debug_attachment *attach)
-{
- const char *attach_name;
- struct device *dev = attach->dev;
- struct iommu_domain *domain = attach->domain;
- int is_dynamic;
-
- if (iommu_domain_get_attr(domain, DOMAIN_ATTR_DYNAMIC, &is_dynamic))
- is_dynamic = 0;
-
- if (is_dynamic) {
- uuid_le uuid;
-
- uuid_le_gen(&uuid);
- attach_name = kasprintf(GFP_KERNEL, "%s-%pUl", dev_name(dev),
- uuid.b);
- if (!attach_name)
- return -ENOMEM;
- } else {
- attach_name = dev_name(dev);
- }
-
- attach->dentry = debugfs_create_dir(attach_name,
- debugfs_attachments_dir);
- if (!attach->dentry) {
- pr_err("Couldn't create iommu/attachments/%s debugfs directory for domain 0x%p\n",
- attach_name, domain);
- if (is_dynamic)
- kfree(attach_name);
- return -EIO;
- }
-
- if (is_dynamic)
- kfree(attach_name);
-
- if (!debugfs_create_file(
- "info", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_info_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/info debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_offset", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_offset_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_offset debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_read", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_read_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_read debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_write", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_write_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_write debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- return 0;
-
-err_rmdir:
- debugfs_remove_recursive(attach->dentry);
- return -EIO;
-}
-
-void iommu_debug_domain_add(struct iommu_domain *domain)
-{
- struct iommu_debug_attachment *attach;
-
- mutex_lock(&iommu_debug_attachments_lock);
-
- attach = kmalloc(sizeof(*attach), GFP_KERNEL);
- if (!attach)
- goto out_unlock;
-
- attach->domain = domain;
- attach->dev = NULL;
- list_add(&attach->list, &iommu_debug_attachments);
-
-out_unlock:
- mutex_unlock(&iommu_debug_attachments_lock);
-}
-
-void iommu_debug_domain_remove(struct iommu_domain *domain)
-{
- struct iommu_debug_attachment *it;
-
- mutex_lock(&iommu_debug_attachments_lock);
- list_for_each_entry(it, &iommu_debug_attachments, list)
- if (it->domain == domain && it->dev == NULL)
- break;
-
- if (&it->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p",
- domain);
- } else {
- list_del(&it->list);
- kfree(it);
- }
- mutex_unlock(&iommu_debug_attachments_lock);
-}
-
void iommu_debug_attach_device(struct iommu_domain *domain,
struct device *dev)
{
struct iommu_debug_attachment *attach;
+ struct iommu_group *group;
+
+ group = iommu_group_get(dev);
+ if (!group)
+ return;
+
+ attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+ if (!attach)
+ return;
+
+ attach->domain = domain;
+ attach->group = group;
+ INIT_LIST_HEAD(&attach->list);
mutex_lock(&iommu_debug_attachments_lock);
+ list_add(&attach->list, &iommu_debug_attachments);
+ mutex_unlock(&iommu_debug_attachments_lock);
+}
- list_for_each_entry(attach, &iommu_debug_attachments, list)
- if (attach->domain == domain && attach->dev == NULL)
- break;
+void iommu_debug_domain_remove(struct iommu_domain *domain)
+{
+ struct iommu_debug_attachment *it, *tmp;
- if (&attach->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
- domain, dev_name(dev));
- } else {
- attach->dev = dev;
-
- /*
- * we might not init until after other drivers start calling
- * iommu_attach_device. Only set up the debugfs nodes if we've
- * already init'd to avoid polluting the top-level debugfs
- * directory (by calling debugfs_create_dir with a NULL
- * parent). These will be flushed out later once we init.
- */
-
- if (debugfs_attachments_dir)
- iommu_debug_attach_add_debugfs(attach);
+ mutex_lock(&iommu_debug_attachments_lock);
+ list_for_each_entry_safe(it, tmp, &iommu_debug_attachments, list) {
+ if (it->domain != domain)
+ continue;
+ list_del(&it->list);
+ iommu_group_put(it->group);
+ kfree(it);
}
mutex_unlock(&iommu_debug_attachments_lock);
}
-void iommu_debug_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
- struct iommu_debug_attachment *it;
-
- mutex_lock(&iommu_debug_attachments_lock);
- list_for_each_entry(it, &iommu_debug_attachments, list)
- if (it->domain == domain && it->dev == dev)
- break;
-
- if (&it->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
- domain, dev_name(dev));
- } else {
- /*
- * Just remove debugfs entry and mark dev as NULL on
- * iommu_detach call. We would remove the actual
- * attachment entry from the list only on domain_free call.
- * This is to ensure we keep track of unattached domains too.
- */
-
- debugfs_remove_recursive(it->dentry);
- it->dev = NULL;
- }
- mutex_unlock(&iommu_debug_attachments_lock);
-}
-
-static int iommu_debug_init_tracking(void)
-{
- int ret = 0;
- struct iommu_debug_attachment *attach;
-
- mutex_lock(&iommu_debug_attachments_lock);
- debugfs_attachments_dir = debugfs_create_dir("attachments",
- iommu_debugfs_top);
- if (!debugfs_attachments_dir) {
- pr_err("Couldn't create iommu/attachments debugfs directory\n");
- ret = -ENODEV;
- goto out_unlock;
- }
-
- /* set up debugfs entries for attachments made during early boot */
- list_for_each_entry(attach, &iommu_debug_attachments, list)
- if (attach->dev)
- iommu_debug_attach_add_debugfs(attach);
-
-out_unlock:
- mutex_unlock(&iommu_debug_attachments_lock);
- return ret;
-}
-
-static void iommu_debug_destroy_tracking(void)
-{
- debugfs_remove_recursive(debugfs_attachments_dir);
-}
-#else
-static inline int iommu_debug_init_tracking(void) { return 0; }
-static inline void iommu_debug_destroy_tracking(void) { }
#endif
#ifdef CONFIG_IOMMU_TESTS
@@ -2045,9 +1773,6 @@
static int iommu_debug_init(void)
{
- if (iommu_debug_init_tracking())
- return -ENODEV;
-
if (iommu_debug_init_tests())
return -ENODEV;
@@ -2057,7 +1782,6 @@
static void iommu_debug_exit(void)
{
platform_driver_unregister(&iommu_debug_driver);
- iommu_debug_destroy_tracking();
iommu_debug_destroy_tests();
}
diff --git a/drivers/iommu/iommu-debug.h b/drivers/iommu/iommu-debug.h
index 94a97bf..91c418d 100644
--- a/drivers/iommu/iommu-debug.h
+++ b/drivers/iommu/iommu-debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -16,8 +16,6 @@
#ifdef CONFIG_IOMMU_DEBUG_TRACKING
void iommu_debug_attach_device(struct iommu_domain *domain, struct device *dev);
-void iommu_debug_detach_device(struct iommu_domain *domain, struct device *dev);
-void iommu_debug_domain_add(struct iommu_domain *domain);
void iommu_debug_domain_remove(struct iommu_domain *domain);
#else /* !CONFIG_IOMMU_DEBUG_TRACKING */
@@ -27,15 +25,6 @@
{
}
-static inline void iommu_debug_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
-}
-
-static inline void iommu_debug_domain_add(struct iommu_domain *domain)
-{
-}
-
static inline void iommu_debug_domain_remove(struct iommu_domain *domain)
{
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 7f9d9e1..e81bb48 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1067,8 +1067,6 @@
/* Assume all sizes by default; the driver may override this later */
domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap;
- iommu_debug_domain_add(domain);
-
return domain;
}
@@ -1132,8 +1130,6 @@
static void __iommu_detach_device(struct iommu_domain *domain,
struct device *dev)
{
- iommu_debug_detach_device(domain, dev);
-
if (unlikely(domain->ops->detach_dev == NULL))
return;
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop100.h b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop100.h
index 8686bd5..12c8e66 100644
--- a/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop100.h
+++ b/drivers/media/platform/msm/camera/cam_cpas/cpas_top/cpastop100.h
@@ -39,7 +39,7 @@
.access_type = CAM_REG_TYPE_WRITE,
.enable = true,
.offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
- .value = TEST_IRQ_ENABLE ? 0x7 : 0x3,
+ .value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
}
};
@@ -164,7 +164,7 @@
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
- .value = 0x7,
+ .value = 0x1,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
@@ -191,7 +191,7 @@
.access_type = CAM_REG_TYPE_READ_WRITE,
.enable = true,
.offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
- .value = 0x7,
+ .value = 0x5,
},
.err_status = {
.access_type = CAM_REG_TYPE_READ,
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
index b16e37e..2dfb90a 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
@@ -267,7 +267,7 @@
of_node = pdev->dev.of_node;
- rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
+ rc = of_property_read_u32(of_node, "cell-index", &soc_info->index);
if (rc) {
pr_err("device %s failed to read cell-index\n", pdev->name);
return rc;
@@ -317,11 +317,13 @@
}
}
- rc = of_property_read_u32_array(of_node, "reg-cam-base",
- soc_info->mem_block_cam_base, soc_info->num_mem_block);
- if (rc) {
- pr_err("Error reading register offsets\n");
- return rc;
+ if (soc_info->num_mem_block > 0) {
+ rc = of_property_read_u32_array(of_node, "reg-cam-base",
+ soc_info->mem_block_cam_base, soc_info->num_mem_block);
+ if (rc) {
+ pr_err("Error reading register offsets\n");
+ return rc;
+ }
}
rc = of_property_read_string_index(of_node, "interrupt-names", 0,
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
index 3e8226f..e556bba 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+
#include "cam_io_util.h"
#define NO_SET_RATE -1
@@ -54,7 +55,7 @@
* Camera hardware driver module
*
* @pdev: Platform device pointer
- * @hw_version; Camera device version
+ * @hw_version: Camera device version
* @index: Instance id for the camera device
* @irq_name: Name of the irq associated with the device
* @irq_line: Irq resource
@@ -76,7 +77,7 @@
* @clk: Array of associated clock resources
* @clk_rate: Array of default clock rates
* @src_clk_idx: Source clock index that is rate-controllable
- * @soc_private; Soc private data
+ * @soc_private: Soc private data
*
*/
struct cam_hw_soc_info {
@@ -172,7 +173,6 @@
*/
int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info);
-
/**
* cam_soc_util_request_platform_resource()
*
@@ -208,7 +208,7 @@
* TRUE: Enable all clocks in soc_info Now.
* False: Don't enable clocks Now. Driver will
* enable independently.
- @enable_irq: Boolean flag:
+ * @enable_irq: Boolean flag:
* TRUE: Enable IRQ in soc_info Now.
* False: Don't enable IRQ Now. Driver will
* enable independently.
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4f53850..9dda0d2 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -476,7 +476,7 @@
for (; idx < num_ctrls; idx++) {
struct v4l2_ctrl *ctrl = NULL;
- if (1) {
+ if (IS_PRIV_CTRL(drv_ctrls[idx].id)) {
/*add private control*/
ctrl_cfg.def = drv_ctrls[idx].default_value;
ctrl_cfg.flags = 0;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 098063d..61df652 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -61,7 +61,7 @@
struct hal_buffer_requirements *get_buff_req_buffer(
struct msm_vidc_inst *inst, u32 buffer_type);
#define IS_PRIV_CTRL(idx) (\
- (V4L2_CTRL_ID2CLASS(idx) == V4L2_CTRL_CLASS_MPEG) && \
+ (V4L2_CTRL_ID2WHICH(idx) == V4L2_CTRL_CLASS_MPEG) && \
V4L2_CTRL_DRIVER_PRIV(idx))
void msm_comm_session_clean(struct msm_vidc_inst *inst);
int msm_comm_kill_session(struct msm_vidc_inst *inst);
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index d16e3e8..077d237 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -123,6 +123,7 @@
}
EXPORT_SYMBOL_GPL(power_supply_changed);
+static int psy_register_cooler(struct device *dev, struct power_supply *psy);
/*
* Notify that power supply was registered after parent finished the probing.
*
@@ -130,6 +131,8 @@
* calling power_supply_changed() directly from power_supply_register()
* would lead to execution of get_property() function provided by the driver
* too early - before the probe ends.
+ * Also, registering cooling device from the probe will execute the
+ * get_property() function. So register the cooling device after the probe.
*
* Avoid that by waiting on parent's mutex.
*/
@@ -141,6 +144,7 @@
if (psy->dev.parent)
mutex_lock(&psy->dev.parent->mutex);
+ psy_register_cooler(psy->dev.parent, psy);
power_supply_changed(psy);
if (psy->dev.parent)
@@ -776,10 +780,6 @@
if (rc)
goto register_thermal_failed;
- rc = psy_register_cooler(parent, psy);
- if (rc)
- goto register_cooler_failed;
-
rc = power_supply_create_triggers(psy);
if (rc)
goto create_triggers_failed;
@@ -803,8 +803,6 @@
return psy;
create_triggers_failed:
- psy_unregister_cooler(psy);
-register_cooler_failed:
psy_unregister_thermal(psy);
register_thermal_failed:
device_del(dev);
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 217b7ca..25b2cdd 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -180,6 +180,15 @@
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
+static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = {
+ .bLength = sizeof(ss_bulk_comp_desc),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+
+ /* the following 2 values can be tweaked if necessary */
+ /* .bMaxBurst = 0, */
+ /* .bmAttributes = 0, */
+};
+
/* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */
static struct usb_ms_endpoint_descriptor_16 ms_in_desc = {
/* .bLength = DYNAMIC */
@@ -846,6 +855,7 @@
static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_descriptor_header **midi_function;
+ struct usb_descriptor_header **midi_ss_function;
struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
@@ -853,7 +863,7 @@
struct usb_composite_dev *cdev = c->cdev;
struct f_midi *midi = func_to_midi(f);
struct usb_string *us;
- int status, n, jack = 1, i = 0;
+ int status, n, jack = 1, i = 0, j = 0;
midi->gadget = cdev->gadget;
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
@@ -894,11 +904,20 @@
if (!midi->out_ep)
goto fail;
+ /* allocate temporary function list for ss */
+ midi_ss_function = kcalloc((MAX_PORTS * 4) + 11,
+ sizeof(*midi_ss_function), GFP_KERNEL);
+ if (!midi_ss_function) {
+ status = -ENOMEM;
+ goto fail;
+ }
+
/* allocate temporary function list */
midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
GFP_KERNEL);
if (!midi_function) {
status = -ENOMEM;
+ kfree(midi_ss_function);
goto fail;
}
@@ -912,6 +931,12 @@
midi_function[i++] = (struct usb_descriptor_header *) &ac_interface_desc;
midi_function[i++] = (struct usb_descriptor_header *) &ac_header_desc;
midi_function[i++] = (struct usb_descriptor_header *) &ms_interface_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ac_interface_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ac_header_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ms_interface_desc;
/* calculate the header's wTotalLength */
n = USB_DT_MS_HEADER_SIZE
@@ -920,6 +945,8 @@
ms_header_desc.wTotalLength = cpu_to_le16(n);
midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ms_header_desc;
/* configure the external IN jacks, each linked to an embedded OUT jack */
for (n = 0; n < midi->in_ports; n++) {
@@ -933,6 +960,7 @@
in_ext->bJackID = jack++;
in_ext->iJack = 0;
midi_function[i++] = (struct usb_descriptor_header *) in_ext;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) in_ext;
out_emb->bLength = USB_DT_MIDI_OUT_SIZE(1);
out_emb->bDescriptorType = USB_DT_CS_INTERFACE;
@@ -944,6 +972,8 @@
out_emb->pins[0].baSourceID = in_ext->bJackID;
out_emb->iJack = 0;
midi_function[i++] = (struct usb_descriptor_header *) out_emb;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) out_emb;
/* link it to the endpoint */
ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
@@ -961,6 +991,7 @@
in_emb->bJackID = jack++;
in_emb->iJack = 0;
midi_function[i++] = (struct usb_descriptor_header *) in_emb;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) in_emb;
out_ext->bLength = USB_DT_MIDI_OUT_SIZE(1);
out_ext->bDescriptorType = USB_DT_CS_INTERFACE;
@@ -972,6 +1003,8 @@
out_ext->pins[0].baSourceID = in_emb->bJackID;
out_ext->pins[0].baSourcePin = 1;
midi_function[i++] = (struct usb_descriptor_header *) out_ext;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) out_ext;
/* link it to the endpoint */
ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
@@ -991,6 +1024,16 @@
midi_function[i++] = (struct usb_descriptor_header *) &ms_in_desc;
midi_function[i++] = NULL;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) &bulk_out_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ss_bulk_comp_desc;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) &ms_out_desc;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) &bulk_in_desc;
+ midi_ss_function[j++] =
+ (struct usb_descriptor_header *) &ss_bulk_comp_desc;
+ midi_ss_function[j++] = (struct usb_descriptor_header *) &ms_in_desc;
+ midi_ss_function[j++] = NULL;
+
/*
* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
@@ -1009,13 +1052,23 @@
goto fail_f_midi;
}
+ if (gadget_is_superspeed(c->cdev->gadget)) {
+ bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024);
+ bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024);
+ f->ss_descriptors = usb_copy_descriptors(midi_ss_function);
+ if (!f->ss_descriptors)
+ goto fail_f_midi;
+ }
+
kfree(midi_function);
+ kfree(midi_ss_function);
return 0;
fail_f_midi:
kfree(midi_function);
usb_free_descriptors(f->hs_descriptors);
+ kfree(midi_ss_function);
fail:
f_midi_unregister_card(midi);
fail_register:
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6012da3..918f659 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -435,8 +435,8 @@
#define PORT_L1_TIMEOUT(p)(((p) & 0xff) << 2)
#define PORT_BESLD(p)(((p) & 0xf) << 10)
-/* use 512 microseconds as USB2 LPM L1 default timeout. */
-#define XHCI_L1_TIMEOUT 512
+/* use 128 microseconds as USB2 LPM L1 default timeout. */
+#define XHCI_L1_TIMEOUT 128
/* Set default HIRD/BESL value to 4 (350/400us) for USB2 L1 LPM resume latency.
* Safe to use with mixed HIRD and BESL systems (host and device) and is used
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index d3b4cf4..9523c60 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -91,12 +91,6 @@
* @base: pointer to the timer base (per cpu and per clock)
* @state: state information (See bit values above)
* @is_rel: Set if the timer was armed relative
- * @start_pid: timer statistics field to store the pid of the task which
- * started the timer
- * @start_site: timer statistics field to store the site where the timer
- * was started
- * @start_comm: timer statistics field to store the name of the process which
- * started the timer
*
* The hrtimer structure must be initialized by hrtimer_init()
*/
@@ -107,11 +101,6 @@
struct hrtimer_clock_base *base;
u8 state;
u8 is_rel;
-#ifdef CONFIG_TIMER_STATS
- int start_pid;
- void *start_site;
- char start_comm[16];
-#endif
};
/**
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 3e354fd..56dde53 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -20,11 +20,6 @@
unsigned long data;
u32 flags;
-#ifdef CONFIG_TIMER_STATS
- int start_pid;
- void *start_site;
- char start_comm[16];
-#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
@@ -200,46 +195,6 @@
/* To be used from cpusets, only */
extern void timer_quiesce_cpu(void *cpup);
-/*
- * Timer-statistics info:
- */
-#ifdef CONFIG_TIMER_STATS
-
-extern int timer_stats_active;
-
-extern void init_timer_stats(void);
-
-extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
- void *timerf, char *comm, u32 flags);
-
-extern void __timer_stats_timer_set_start_info(struct timer_list *timer,
- void *addr);
-
-static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
-{
- if (likely(!timer_stats_active))
- return;
- __timer_stats_timer_set_start_info(timer, __builtin_return_address(0));
-}
-
-static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
-{
- timer->start_site = NULL;
-}
-#else
-static inline void init_timer_stats(void)
-{
-}
-
-static inline void timer_stats_timer_set_start_info(struct timer_list *timer)
-{
-}
-
-static inline void timer_stats_timer_clear_start_info(struct timer_list *timer)
-{
-}
-#endif
-
extern void add_timer(struct timer_list *timer);
extern int try_to_del_timer_sync(struct timer_list *timer);
diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild
index 478f7fe..98844ac 100644
--- a/include/uapi/media/Kbuild
+++ b/include/uapi/media/Kbuild
@@ -1,5 +1,6 @@
header-y += cam_cpas.h
header-y += cam_defs.h
+header-y += cam_icp.h
header-y += cam_isp.h
header-y += cam_isp_vfe.h
header-y += cam_isp_ife.h
diff --git a/include/uapi/media/cam_defs.h b/include/uapi/media/cam_defs.h
index cf56211..a4557d1 100644
--- a/include/uapi/media/cam_defs.h
+++ b/include/uapi/media/cam_defs.h
@@ -121,9 +121,6 @@
#define CAM_FORMAT_Y_ONLY 45
#define CAM_FORMAT_MAX 46
-
-/* camera packet */
-
/* camera rotaion */
#define CAM_ROTATE_CW_0_DEGREE 0
#define CAM_ROTATE_CW_90_DEGREE 1
@@ -343,7 +340,6 @@
};
-/* Release Device */
/**
* struct cam_release_dev_cmd - Control payload for release devices
*
@@ -355,7 +351,6 @@
int32_t dev_handle;
};
-/* Start/Stop device */
/**
* struct cam_start_stop_dev_cmd - Control payload for start/stop device
*
@@ -368,7 +363,6 @@
int32_t dev_handle;
};
-/* Configure Device */
/**
* struct cam_config_dev_cmd - Command payload for configure device
*
@@ -386,7 +380,6 @@
uint64_t packet_handle;
};
-/* Query Device Caps */
/**
* struct cam_query_cap_cmd - Payload for query device capability
*
@@ -401,7 +394,6 @@
uint64_t caps_handle;
};
-/* Acquire Device */
/**
* struct cam_acquire_dev_cmd - Control payload for acquire devices
*
diff --git a/include/uapi/media/cam_icp.h b/include/uapi/media/cam_icp.h
new file mode 100644
index 0000000..9351d2d
--- /dev/null
+++ b/include/uapi/media/cam_icp.h
@@ -0,0 +1,155 @@
+#ifndef __UAPI_CAM_ICP_H__
+#define __UAPI_CAM_ICP_H__
+
+#include "cam_defs.h"
+
+/* icp, ipe, bps, cdm(ipe/bps) are used in querycap */
+#define CAM_ICP_DEV_TYPE_A5 1
+#define CAM_ICP_DEV_TYPE_IPE 2
+#define CAM_ICP_DEV_TYPE_BPS 3
+#define CAM_ICP_DEV_TYPE_IPE_CDM 4
+#define CAM_ICP_DEV_TYPE_BPS_CDM 5
+#define CAM_ICP_DEV_TYPE_MAX 5
+
+/* definitions needed for icp aquire device */
+#define CAM_ICP_RES_TYPE_BPS 1
+#define CAM_ICP_RES_TYPE_IPE_RT 2
+#define CAM_ICP_RES_TYPE_IPE 3
+#define CAM_ICP_RES_TYPE_MAX 4
+
+/* packet opcode types */
+#define CAM_ICP_OPCODE_IPE_UPDATE 0
+#define CAM_ICP_OPCODE_BPS_UPDATE 1
+
+/* IPE input port resource type */
+#define CAM_ICP_IPE_INPUT_IMAGE_FULL 0x0
+#define CAM_ICP_IPE_INPUT_IMAGE_DS4 0x1
+#define CAM_ICP_IPE_INPUT_IMAGE_DS16 0x2
+#define CAM_ICP_IPE_INPUT_IMAGE_DS64 0x3
+#define CAM_ICP_IPE_INPUT_IMAGE_FULL_REF 0x4
+#define CAM_ICP_IPE_INPUT_IMAGE_DS4_REF 0x5
+#define CAM_ICP_IPE_INPUT_IMAGE_DS16_REF 0x6
+#define CAM_ICP_IPE_INPUT_IMAGE_DS64_REF 0x7
+
+/* IPE output port resource type */
+#define CAM_ICP_IPE_OUTPUT_IMAGE_DISPLAY 0x8
+#define CAM_ICP_IPE_OUTPUT_IMAGE_VIDEO 0x9
+#define CAM_ICP_IPE_OUTPUT_IMAGE_FULL_REF 0xA
+#define CAM_ICP_IPE_OUTPUT_IMAGE_DS4_REF 0xB
+#define CAM_ICP_IPE_OUTPUT_IMAGE_DS16_REF 0xC
+#define CAM_ICP_IPE_OUTPUT_IMAGE_DS64_REF 0xD
+
+#define CAM_ICP_IPE_IMAGE_MAX 0xE
+
+/* BPS input port resource type */
+#define CAM_ICP_BPS_INPUT_IMAGE 0x0
+
+/* BPS output port resource type */
+#define CAM_ICP_BPS_OUTPUT_IMAGE_FULL 0x1
+#define CAM_ICP_BPS_OUTPUT_IMAGE_DS4 0x2
+#define CAM_ICP_BPS_OUTPUT_IMAGE_DS16 0x3
+#define CAM_ICP_BPS_OUTPUT_IMAGE_DS64 0x4
+#define CAM_ICP_BPS_OUTPUT_IMAGE_STATS_BG 0x5
+#define CAM_ICP_BPS_OUTPUT_IMAGE_STATS_BHIST 0x6
+#define CAM_ICP_BPS_OUTPUT_IMAGE_REG1 0x7
+#define CAM_ICP_BPS_OUTPUT_IMAGE_REG2 0x8
+
+#define CAM_ICP_BPS_IO_IMAGES_MAX 0x9
+
+/**
+ * struct cam_icp_dev_ver - Device information for particular hw type
+ *
+ * This is used to get device version info of
+ * ICP, IPE, BPS and CDM related IPE and BPS from firmware
+ * and use this info in CAM_QUERY_CAP IOCTL
+ *
+ * @dev_type: hardware type for the cap info(icp, ipe, bps, cdm(ipe/bps))
+ * @reserved: reserved field
+ * @hw_ver: major, minor and incr values of a device version
+ */
+struct cam_icp_dev_ver {
+ uint32_t dev_type;
+ uint32_t reserved;
+ struct cam_hw_version hw_ver;
+};
+
+/**
+ * struct cam_icp_ver - ICP version info
+ *
+ * This strcuture is used for fw and api version
+ * this is used to get firmware version and api version from firmware
+ * and use this info in CAM_QUERY_CAP IOCTL
+ *
+ * @major: FW version major
+ * @minor: FW version minor
+ * @revision: FW version increment
+ */
+struct cam_icp_ver {
+ uint32_t major;
+ uint32_t minor;
+ uint32_t revision;
+ uint32_t reserved;
+};
+
+/**
+ * struct cam_icp_query_cap_cmd - ICP query device capability payload
+ *
+ * @dev_iommu_handle: icp iommu handles for secure/non secure modes
+ * @cdm_iommu_handle: iommu handles for secure/non secure modes
+ * @fw_version: firmware version info
+ * @api_version: api version info
+ * @num_ipe: number of ipes
+ * @num_bps: number of bps
+ * @dev_ver: returned device capability array
+ */
+struct cam_icp_query_cap_cmd {
+ struct cam_iommu_handle dev_iommu_handle;
+ struct cam_iommu_handle cdm_iommu_handle;
+ struct cam_icp_ver fw_version;
+ struct cam_icp_ver api_version;
+ uint32_t num_ipe;
+ uint32_t num_bps;
+ struct cam_icp_dev_ver dev_ver[CAM_ICP_DEV_TYPE_MAX];
+};
+
+/**
+ * struct cam_icp_res_info - ICP output resource info
+ *
+ * @format: format of the resource
+ * @width: width in pixels
+ * @height: height in lines
+ * @fps: fps
+ */
+struct cam_icp_res_info {
+ uint32_t format;
+ uint32_t width;
+ uint32_t height;
+ uint32_t fps;
+};
+
+/**
+ * struct cam_icp_acquire_dev_info - An ICP device info
+ *
+ * @scratch_mem_size: Output param - size of scratch memory
+ * @dev_type: device type (IPE_RT/IPE_NON_RT/BPS)
+ * @io_config_cmd_size: size of IO config command
+ * @io_config_cmd_handle: IO config command for each acquire
+ * @secure_mode: camera mode (secure/non secure)
+ * @chain_info: chaining info of FW device handles
+ * @in_res: resource info used for clock and bandwidth calculation
+ * @num_out_res: number of output resources
+ * @out_res: output resource
+ */
+struct cam_icp_acquire_dev_info {
+ uint32_t scratch_mem_size;
+ uint32_t dev_type;
+ uint32_t io_config_cmd_size;
+ int32_t io_config_cmd_handle;
+ uint32_t secure_mode;
+ int32_t chain_info;
+ struct cam_icp_res_info in_res;
+ uint32_t num_out_res;
+ struct cam_icp_res_info out_res[1];
+} __attribute__((__packed__));
+
+#endif /* __UAPI_CAM_ICP_H__ */
diff --git a/include/uapi/media/cam_sensor.h b/include/uapi/media/cam_sensor.h
index bb4805c..83f1a02 100644
--- a/include/uapi/media/cam_sensor.h
+++ b/include/uapi/media/cam_sensor.h
@@ -6,7 +6,7 @@
#include <media/cam_defs.h>
#define CAM_SENSOR_PROBE_CMD (CAM_COMMON_OPCODE_MAX + 1)
-
+#define CAM_SENSOR_MAX_LED_TRIGGERS 3
/**
* struct cam_sensor_query_cap - capabilities info for sensor
*
@@ -42,6 +42,7 @@
* @version : CSIphy version
* @clk lane : Of the 5 lanes, informs lane configured
* as clock lane
+ * @reserved
*/
struct cam_csiphy_query_cap {
uint32_t slot_info;
@@ -54,6 +55,7 @@
* struct cam_actuator_query_cap - capabilities info for actuator
*
* @slot_info : Indicates about the slotId or cell Index
+ * @reserved
*/
struct cam_actuator_query_cap {
uint32_t slot_info;
@@ -85,6 +87,7 @@
* @data_mask : Data mask if only few bits are valid
* @camera_id : Indicates the slot to which camera
* needs to be probed
+ * @reserved
*/
struct cam_cmd_probe {
uint8_t data_type;
@@ -99,9 +102,10 @@
} __attribute__((packed));
/**
- * struct cam_power_settings - Contains sensor slave info
+ * struct cam_power_settings - Contains sensor power setting info
*
* @power_seq_type : Type of power sequence
+ * @reserved
* @config_val_low : Lower 32 bit value configuration value
* @config_val_high : Higher 32 bit value configuration value
*
@@ -117,8 +121,9 @@
* struct cam_cmd_power - Explains about the power settings
*
* @count : Number of power settings follows
+ * @reserved
* @cmd_type : Explains type of command
- *
+ * @power_settings : Contains power setting info
*/
struct cam_cmd_power {
uint16_t count;
@@ -135,7 +140,7 @@
* @ cmd_type : Command buffer type
* @ data_type : I2C data type
* @ addr_type : I2C address type
- *
+ * @ reserved
*/
struct i2c_rdwr_header {
uint16_t count;
@@ -160,7 +165,8 @@
/**
* struct cam_cmd_i2c_random_wr - I2C random write command
- *
+ * @ header : header of READ/WRITE I2C command
+ * @ random_wr_payload : payload for I2C random write
*/
struct cam_cmd_i2c_random_wr {
struct i2c_rdwr_header header;
@@ -170,7 +176,7 @@
/**
* struct cam_cmd_read - I2C read command
* @ reg_data : Register data
- *
+ * @ reserved
*/
struct cam_cmd_read {
uint32_t reg_data;
@@ -179,8 +185,9 @@
/**
* struct cam_cmd_i2c_continuous_wr - I2C continuous write command
+ * @ header : header of READ/WRITE I2C command
* @ reg_addr : Register address
- *
+ * @ data_read : I2C read command
*/
struct cam_cmd_i2c_continuous_wr {
struct i2c_rdwr_header header;
@@ -190,7 +197,8 @@
/**
* struct cam_cmd_i2c_random_rd - I2C random read command
- *
+ * @ header : header of READ/WRITE I2C command
+ * @ data_read : I2C read command
*/
struct cam_cmd_i2c_random_rd {
struct i2c_rdwr_header header;
@@ -199,6 +207,7 @@
/**
* struct cam_cmd_i2c_continuous_rd - I2C continuous continuous read command
+ * @ header : header of READ/WRITE I2C command
* @ reg_addr : Register address
*
*/
@@ -214,6 +223,7 @@
* @op_code : Opcode
* @cmd_type : Explains type of command
* @timeout : Timeout for retries
+ * @reserved
* @reg_addr : Register Address
* @reg_data : Register data
* @data_mask : Data mask if only few bits are valid
@@ -237,7 +247,7 @@
* struct cam_cmd_unconditional_wait - Un-conditional wait command
* @delay : Delay
* @op_code : Opcode
- *
+ * @cmd_type : Explains type of command
*/
struct cam_cmd_unconditional_wait {
int16_t delay;
@@ -252,6 +262,7 @@
* @csiphy_3phase : Total number of lanes
* @combo_mode : Info regarding combo_mode is enable / disable
* @lane_cnt : Total number of lanes
+ * @reserved
* @3phase : Details whether 3Phase / 2Phase operation
* @settle_time : Settling time in ms
* @data_rate : Data rate
@@ -272,6 +283,7 @@
* cam_csiphy_acquire_dev_info : Information needed for
* csiphy at the time of acquire
* @combo_mode : Indicates the device mode of operation
+ * @reserved
*
*/
struct cam_csiphy_acquire_dev_info {
@@ -284,6 +296,7 @@
* @device_handle : Updates device handle
* @session_handle : Session handle for acquiring device
* @handle_type : Resource handle type
+ * @reserved
* @info_handle : Handle to additional info
* needed for sensor sub modules
*
@@ -301,6 +314,7 @@
* @session_handle : Session handle for acquiring device
* @device_handle : Updates device handle
* @handle_type : Resource handle type
+ * @reserved
* @info_handle : Information Needed at the time of streamOn
*
*/
@@ -312,4 +326,92 @@
uint64_t info_handle;
} __attribute__((packed));
+/**
+ * struct cam_flash_init : Init command for the flash
+ * @flash_type : flash hw type
+ * @reserved
+ * @cmd_type : command buffer type
+ */
+struct cam_flash_init {
+ uint8_t flash_type;
+ uint16_t reserved;
+ uint8_t cmd_type;
+} __attribute__((packed));
+
+/**
+ * struct cam_flash_set_rer : RedEyeReduction command buffer
+ *
+ * @count : Number of flash leds
+ * @opcode : Command buffer opcode
+ * CAM_FLASH_FIRE_RER
+ * @cmd_type : command buffer operation type
+ * @num_iteration : Number of led turn on/off sequence
+ * @reserved
+ * @led_on_delay_ms : flash led turn on time in ms
+ * @led_off_delay_ms : flash led turn off time in ms
+ * @led_current_ma : flash led current in ma
+ *
+ */
+struct cam_flash_set_rer {
+ uint16_t count;
+ uint8_t opcode;
+ uint8_t cmd_type;
+ uint16_t num_iteration;
+ uint16_t reserved;
+ uint32_t led_on_delay_ms;
+ uint32_t led_off_delay_ms;
+ uint32_t led_current_ma[CAM_SENSOR_MAX_LED_TRIGGERS];
+} __attribute__((packed));
+
+/**
+ * struct cam_flash_set_on_off : led turn on/off command buffer
+ *
+ * @count : Number of Flash leds
+ * @opcode : command buffer opcodes
+ * CAM_FLASH_FIRE_LOW
+ * CAM_FLASH_FIRE_HIGH
+ * CAM_FLASH_OFF
+ * @cmd_type : command buffer operation type
+ * @led_current_ma : flash led current in ma
+ *
+ */
+struct cam_flash_set_on_off {
+ uint16_t count;
+ uint8_t opcode;
+ uint8_t cmd_type;
+ uint32_t led_current_ma[CAM_SENSOR_MAX_LED_TRIGGERS];
+} __attribute__((packed));
+
+/**
+ * struct cam_flash_query_curr : query current command buffer
+ *
+ * @reserved
+ * @opcode : command buffer opcode
+ * @cmd_type : command buffer operation type
+ * @query_current_ma : battery current in ma
+ *
+ */
+struct cam_flash_query_curr {
+ uint16_t reserved;
+ uint8_t opcode;
+ uint8_t cmd_type;
+ uint32_t query_current_ma;
+} __attribute__ ((packed));
+
+/**
+ * struct cam_flash_query_cap : capabilities info for flash
+ *
+ * @slot_info : Indicates about the slotId or cell Index
+ * @max_current_flash : max supported current for flash
+ * @max_duration_flash : max flash turn on duration
+ * @max_current_torch : max supported current for torch
+ *
+ */
+struct cam_flash_query_cap_info {
+ uint32_t slot_info;
+ uint32_t max_current_flash[CAM_SENSOR_MAX_LED_TRIGGERS];
+ uint32_t max_duration_flash[CAM_SENSOR_MAX_LED_TRIGGERS];
+ uint32_t max_current_torch[CAM_SENSOR_MAX_LED_TRIGGERS];
+} __attribute__ ((packed));
+
#endif
diff --git a/kernel/kthread.c b/kernel/kthread.c
index c2c911a..b65854c 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -854,7 +854,6 @@
list_add(&work->node, &worker->delayed_work_list);
work->worker = worker;
- timer_stats_timer_set_start_info(&dwork->timer);
timer->expires = jiffies + delay;
add_timer(timer);
}
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 5819ca0..b9b881eb 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -9,7 +9,6 @@
endif
obj-$(CONFIG_GENERIC_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o tick-sched.o
-obj-$(CONFIG_TIMER_STATS) += timer_stats.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index b1c7852..9792763 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -767,34 +767,6 @@
clock_was_set_delayed();
}
-static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer)
-{
-#ifdef CONFIG_TIMER_STATS
- if (timer->start_site)
- return;
- timer->start_site = __builtin_return_address(0);
- memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
- timer->start_pid = current->pid;
-#endif
-}
-
-static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer)
-{
-#ifdef CONFIG_TIMER_STATS
- timer->start_site = NULL;
-#endif
-}
-
-static inline void timer_stats_account_hrtimer(struct hrtimer *timer)
-{
-#ifdef CONFIG_TIMER_STATS
- if (likely(!timer_stats_active))
- return;
- timer_stats_update_stats(timer, timer->start_pid, timer->start_site,
- timer->function, timer->start_comm, 0);
-#endif
-}
-
/*
* Counterpart to lock_hrtimer_base above:
*/
@@ -938,7 +910,6 @@
* rare case and less expensive than a smp call.
*/
debug_deactivate(timer);
- timer_stats_hrtimer_clear_start_info(timer);
reprogram = base->cpu_base == this_cpu_ptr(&hrtimer_bases);
if (!restart)
@@ -997,8 +968,6 @@
/* Switch the timer base, if necessary: */
new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
- timer_stats_hrtimer_set_start_info(timer);
-
/* Update pinned state */
timer->state &= ~HRTIMER_STATE_PINNED;
timer->state |= (!!(mode & HRTIMER_MODE_PINNED)) << HRTIMER_PINNED_SHIFT;
@@ -1139,12 +1108,6 @@
base = hrtimer_clockid_to_base(clock_id);
timer->base = &cpu_base->clock_base[base];
timerqueue_init(&timer->node);
-
-#ifdef CONFIG_TIMER_STATS
- timer->start_site = NULL;
- timer->start_pid = -1;
- memset(timer->start_comm, 0, TASK_COMM_LEN);
-#endif
}
/**
@@ -1228,7 +1191,6 @@
raw_write_seqcount_barrier(&cpu_base->seq);
__remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
- timer_stats_account_hrtimer(timer);
fn = timer->function;
/*
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 5463c3b..adede73 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -575,38 +575,6 @@
trigger_dyntick_cpu(base, timer);
}
-#ifdef CONFIG_TIMER_STATS
-void __timer_stats_timer_set_start_info(struct timer_list *timer, void *addr)
-{
- if (timer->start_site)
- return;
-
- timer->start_site = addr;
- memcpy(timer->start_comm, current->comm, TASK_COMM_LEN);
- timer->start_pid = current->pid;
-}
-
-static void timer_stats_account_timer(struct timer_list *timer)
-{
- void *site;
-
- /*
- * start_site can be concurrently reset by
- * timer_stats_timer_clear_start_info()
- */
- site = READ_ONCE(timer->start_site);
- if (likely(!site))
- return;
-
- timer_stats_update_stats(timer, timer->start_pid, site,
- timer->function, timer->start_comm,
- timer->flags);
-}
-
-#else
-static void timer_stats_account_timer(struct timer_list *timer) {}
-#endif
-
#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
static struct debug_obj_descr timer_debug_descr;
@@ -793,11 +761,6 @@
{
timer->entry.pprev = NULL;
timer->flags = flags | raw_smp_processor_id();
-#ifdef CONFIG_TIMER_STATS
- timer->start_site = NULL;
- timer->start_pid = -1;
- memset(timer->start_comm, 0, TASK_COMM_LEN);
-#endif
lockdep_init_map(&timer->lockdep_map, name, key, 0);
}
@@ -1011,8 +974,6 @@
base = lock_timer_base(timer, &flags);
}
- timer_stats_timer_set_start_info(timer);
-
ret = detach_if_pending(timer, base, false);
if (!ret && pending_only)
goto out_unlock;
@@ -1140,7 +1101,6 @@
struct timer_base *new_base, *base;
unsigned long flags;
- timer_stats_timer_set_start_info(timer);
BUG_ON(timer_pending(timer) || !timer->function);
new_base = get_timer_cpu_base(timer->flags, cpu);
@@ -1186,7 +1146,6 @@
debug_assert_init(timer);
- timer_stats_timer_clear_start_info(timer);
if (timer_pending(timer)) {
base = lock_timer_base(timer, &flags);
ret = detach_if_pending(timer, base, true);
@@ -1214,10 +1173,9 @@
base = lock_timer_base(timer, &flags);
- if (base->running_timer != timer) {
- timer_stats_timer_clear_start_info(timer);
+ if (base->running_timer != timer)
ret = detach_if_pending(timer, base, true);
- }
+
spin_unlock_irqrestore(&base->lock, flags);
return ret;
@@ -1341,7 +1299,6 @@
unsigned long data;
timer = hlist_entry(head->first, struct timer_list, entry);
- timer_stats_account_timer(timer);
base->running_timer = timer;
detach_timer(timer, true);
@@ -1916,7 +1873,6 @@
void __init init_timers(void)
{
init_timer_cpus();
- init_timer_stats();
open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
}
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index ba7d8b2..83aa1f8 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -62,21 +62,11 @@
print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
int idx, u64 now)
{
-#ifdef CONFIG_TIMER_STATS
- char tmp[TASK_COMM_LEN + 1];
-#endif
SEQ_printf(m, " #%d: ", idx);
print_name_offset(m, taddr);
SEQ_printf(m, ", ");
print_name_offset(m, timer->function);
SEQ_printf(m, ", S:%02x", timer->state);
-#ifdef CONFIG_TIMER_STATS
- SEQ_printf(m, ", ");
- print_name_offset(m, timer->start_site);
- memcpy(tmp, timer->start_comm, TASK_COMM_LEN);
- tmp[TASK_COMM_LEN] = 0;
- SEQ_printf(m, ", %s/%d", tmp, timer->start_pid);
-#endif
SEQ_printf(m, "\n");
SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n",
(unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)),
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
deleted file mode 100644
index 087204c..0000000
--- a/kernel/time/timer_stats.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * kernel/time/timer_stats.c
- *
- * Collect timer usage statistics.
- *
- * Copyright(C) 2006, Red Hat, Inc., Ingo Molnar
- * Copyright(C) 2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
- *
- * timer_stats is based on timer_top, a similar functionality which was part of
- * Con Kolivas dyntick patch set. It was developed by Daniel Petrini at the
- * Instituto Nokia de Tecnologia - INdT - Manaus. timer_top's design was based
- * on dynamic allocation of the statistics entries and linear search based
- * lookup combined with a global lock, rather than the static array, hash
- * and per-CPU locking which is used by timer_stats. It was written for the
- * pre hrtimer kernel code and therefore did not take hrtimers into account.
- * Nevertheless it provided the base for the timer_stats implementation and
- * was a helpful source of inspiration. Kudos to Daniel and the Nokia folks
- * for this effort.
- *
- * timer_top.c is
- * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus
- * Written by Daniel Petrini <d.pensator@gmail.com>
- * timer_top.c was released under the GNU General Public License version 2
- *
- * We export the addresses and counting of timer functions being called,
- * the pid and cmdline from the owner process if applicable.
- *
- * Start/stop data collection:
- * # echo [1|0] >/proc/timer_stats
- *
- * Display the information collected so far:
- * # cat /proc/timer_stats
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/seq_file.h>
-#include <linux/kallsyms.h>
-
-#include <asm/uaccess.h>
-
-/*
- * This is our basic unit of interest: a timer expiry event identified
- * by the timer, its start/expire functions and the PID of the task that
- * started the timer. We count the number of times an event happens:
- */
-struct entry {
- /*
- * Hash list:
- */
- struct entry *next;
-
- /*
- * Hash keys:
- */
- void *timer;
- void *start_func;
- void *expire_func;
- pid_t pid;
-
- /*
- * Number of timeout events:
- */
- unsigned long count;
- u32 flags;
-
- /*
- * We save the command-line string to preserve
- * this information past task exit:
- */
- char comm[TASK_COMM_LEN + 1];
-
-} ____cacheline_aligned_in_smp;
-
-/*
- * Spinlock protecting the tables - not taken during lookup:
- */
-static DEFINE_RAW_SPINLOCK(table_lock);
-
-/*
- * Per-CPU lookup locks for fast hash lookup:
- */
-static DEFINE_PER_CPU(raw_spinlock_t, tstats_lookup_lock);
-
-/*
- * Mutex to serialize state changes with show-stats activities:
- */
-static DEFINE_MUTEX(show_mutex);
-
-/*
- * Collection status, active/inactive:
- */
-int __read_mostly timer_stats_active;
-
-/*
- * Beginning/end timestamps of measurement:
- */
-static ktime_t time_start, time_stop;
-
-/*
- * tstat entry structs only get allocated while collection is
- * active and never freed during that time - this simplifies
- * things quite a bit.
- *
- * They get freed when a new collection period is started.
- */
-#define MAX_ENTRIES_BITS 10
-#define MAX_ENTRIES (1UL << MAX_ENTRIES_BITS)
-
-static unsigned long nr_entries;
-static struct entry entries[MAX_ENTRIES];
-
-static atomic_t overflow_count;
-
-/*
- * The entries are in a hash-table, for fast lookup:
- */
-#define TSTAT_HASH_BITS (MAX_ENTRIES_BITS - 1)
-#define TSTAT_HASH_SIZE (1UL << TSTAT_HASH_BITS)
-#define TSTAT_HASH_MASK (TSTAT_HASH_SIZE - 1)
-
-#define __tstat_hashfn(entry) \
- (((unsigned long)(entry)->timer ^ \
- (unsigned long)(entry)->start_func ^ \
- (unsigned long)(entry)->expire_func ^ \
- (unsigned long)(entry)->pid ) & TSTAT_HASH_MASK)
-
-#define tstat_hashentry(entry) (tstat_hash_table + __tstat_hashfn(entry))
-
-static struct entry *tstat_hash_table[TSTAT_HASH_SIZE] __read_mostly;
-
-static void reset_entries(void)
-{
- nr_entries = 0;
- memset(entries, 0, sizeof(entries));
- memset(tstat_hash_table, 0, sizeof(tstat_hash_table));
- atomic_set(&overflow_count, 0);
-}
-
-static struct entry *alloc_entry(void)
-{
- if (nr_entries >= MAX_ENTRIES)
- return NULL;
-
- return entries + nr_entries++;
-}
-
-static int match_entries(struct entry *entry1, struct entry *entry2)
-{
- return entry1->timer == entry2->timer &&
- entry1->start_func == entry2->start_func &&
- entry1->expire_func == entry2->expire_func &&
- entry1->pid == entry2->pid;
-}
-
-/*
- * Look up whether an entry matching this item is present
- * in the hash already. Must be called with irqs off and the
- * lookup lock held:
- */
-static struct entry *tstat_lookup(struct entry *entry, char *comm)
-{
- struct entry **head, *curr, *prev;
-
- head = tstat_hashentry(entry);
- curr = *head;
-
- /*
- * The fastpath is when the entry is already hashed,
- * we do this with the lookup lock held, but with the
- * table lock not held:
- */
- while (curr) {
- if (match_entries(curr, entry))
- return curr;
-
- curr = curr->next;
- }
- /*
- * Slowpath: allocate, set up and link a new hash entry:
- */
- prev = NULL;
- curr = *head;
-
- raw_spin_lock(&table_lock);
- /*
- * Make sure we have not raced with another CPU:
- */
- while (curr) {
- if (match_entries(curr, entry))
- goto out_unlock;
-
- prev = curr;
- curr = curr->next;
- }
-
- curr = alloc_entry();
- if (curr) {
- *curr = *entry;
- curr->count = 0;
- curr->next = NULL;
- memcpy(curr->comm, comm, TASK_COMM_LEN);
-
- smp_mb(); /* Ensure that curr is initialized before insert */
-
- if (prev)
- prev->next = curr;
- else
- *head = curr;
- }
- out_unlock:
- raw_spin_unlock(&table_lock);
-
- return curr;
-}
-
-/**
- * timer_stats_update_stats - Update the statistics for a timer.
- * @timer: pointer to either a timer_list or a hrtimer
- * @pid: the pid of the task which set up the timer
- * @startf: pointer to the function which did the timer setup
- * @timerf: pointer to the timer callback function of the timer
- * @comm: name of the process which set up the timer
- * @tflags: The flags field of the timer
- *
- * When the timer is already registered, then the event counter is
- * incremented. Otherwise the timer is registered in a free slot.
- */
-void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
- void *timerf, char *comm, u32 tflags)
-{
- /*
- * It doesn't matter which lock we take:
- */
- raw_spinlock_t *lock;
- struct entry *entry, input;
- unsigned long flags;
-
- if (likely(!timer_stats_active))
- return;
-
- lock = &per_cpu(tstats_lookup_lock, raw_smp_processor_id());
-
- input.timer = timer;
- input.start_func = startf;
- input.expire_func = timerf;
- input.pid = pid;
- input.flags = tflags;
-
- raw_spin_lock_irqsave(lock, flags);
- if (!timer_stats_active)
- goto out_unlock;
-
- entry = tstat_lookup(&input, comm);
- if (likely(entry))
- entry->count++;
- else
- atomic_inc(&overflow_count);
-
- out_unlock:
- raw_spin_unlock_irqrestore(lock, flags);
-}
-
-static void print_name_offset(struct seq_file *m, unsigned long addr)
-{
- char symname[KSYM_NAME_LEN];
-
- if (lookup_symbol_name(addr, symname) < 0)
- seq_printf(m, "<%p>", (void *)addr);
- else
- seq_printf(m, "%s", symname);
-}
-
-static int tstats_show(struct seq_file *m, void *v)
-{
- struct timespec64 period;
- struct entry *entry;
- unsigned long ms;
- long events = 0;
- ktime_t time;
- int i;
-
- mutex_lock(&show_mutex);
- /*
- * If still active then calculate up to now:
- */
- if (timer_stats_active)
- time_stop = ktime_get();
-
- time = ktime_sub(time_stop, time_start);
-
- period = ktime_to_timespec64(time);
- ms = period.tv_nsec / 1000000;
-
- seq_puts(m, "Timer Stats Version: v0.3\n");
- seq_printf(m, "Sample period: %ld.%03ld s\n", (long)period.tv_sec, ms);
- if (atomic_read(&overflow_count))
- seq_printf(m, "Overflow: %d entries\n", atomic_read(&overflow_count));
- seq_printf(m, "Collection: %s\n", timer_stats_active ? "active" : "inactive");
-
- for (i = 0; i < nr_entries; i++) {
- entry = entries + i;
- if (entry->flags & TIMER_DEFERRABLE) {
- seq_printf(m, "%4luD, %5d %-16s ",
- entry->count, entry->pid, entry->comm);
- } else {
- seq_printf(m, " %4lu, %5d %-16s ",
- entry->count, entry->pid, entry->comm);
- }
-
- print_name_offset(m, (unsigned long)entry->start_func);
- seq_puts(m, " (");
- print_name_offset(m, (unsigned long)entry->expire_func);
- seq_puts(m, ")\n");
-
- events += entry->count;
- }
-
- ms += period.tv_sec * 1000;
- if (!ms)
- ms = 1;
-
- if (events && period.tv_sec)
- seq_printf(m, "%ld total events, %ld.%03ld events/sec\n",
- events, events * 1000 / ms,
- (events * 1000000 / ms) % 1000);
- else
- seq_printf(m, "%ld total events\n", events);
-
- mutex_unlock(&show_mutex);
-
- return 0;
-}
-
-/*
- * After a state change, make sure all concurrent lookup/update
- * activities have stopped:
- */
-static void sync_access(void)
-{
- unsigned long flags;
- int cpu;
-
- for_each_online_cpu(cpu) {
- raw_spinlock_t *lock = &per_cpu(tstats_lookup_lock, cpu);
-
- raw_spin_lock_irqsave(lock, flags);
- /* nothing */
- raw_spin_unlock_irqrestore(lock, flags);
- }
-}
-
-static ssize_t tstats_write(struct file *file, const char __user *buf,
- size_t count, loff_t *offs)
-{
- char ctl[2];
-
- if (count != 2 || *offs)
- return -EINVAL;
-
- if (copy_from_user(ctl, buf, count))
- return -EFAULT;
-
- mutex_lock(&show_mutex);
- switch (ctl[0]) {
- case '0':
- if (timer_stats_active) {
- timer_stats_active = 0;
- time_stop = ktime_get();
- sync_access();
- }
- break;
- case '1':
- if (!timer_stats_active) {
- reset_entries();
- time_start = ktime_get();
- smp_mb();
- timer_stats_active = 1;
- }
- break;
- default:
- count = -EINVAL;
- }
- mutex_unlock(&show_mutex);
-
- return count;
-}
-
-static int tstats_open(struct inode *inode, struct file *filp)
-{
- return single_open(filp, tstats_show, NULL);
-}
-
-static const struct file_operations tstats_fops = {
- .open = tstats_open,
- .read = seq_read,
- .write = tstats_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-void __init init_timer_stats(void)
-{
- int cpu;
-
- for_each_possible_cpu(cpu)
- raw_spin_lock_init(&per_cpu(tstats_lookup_lock, cpu));
-}
-
-static int __init init_tstats_procfs(void)
-{
- struct proc_dir_entry *pe;
-
- pe = proc_create("timer_stats", 0644, NULL, &tstats_fops);
- if (!pe)
- return -ENOMEM;
- return 0;
-}
-__initcall(init_tstats_procfs);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7ae9b24..812b8f8 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1529,8 +1529,6 @@
return;
}
- timer_stats_timer_set_start_info(&dwork->timer);
-
dwork->wq = wq;
dwork->cpu = cpu;
timer->expires = jiffies + delay;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 64ec3fd..22eff06 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1003,20 +1003,6 @@
If unsure, say N.
-config TIMER_STATS
- bool "Collect kernel timers statistics"
- depends on DEBUG_KERNEL && PROC_FS
- help
- If you say Y here, additional code will be inserted into the
- timer routines to collect statistics about kernel timers being
- reprogrammed. The statistics can be read from /proc/timer_stats.
- The statistics collection is started by writing 1 to /proc/timer_stats,
- writing 0 stops it. This feature is useful to collect information
- about timer usage patterns in kernel and userspace. This feature
- is lightweight if enabled in the kernel config but not activated
- (it defaults to deactivated on bootup and will only be activated
- if some application like powertop activates it explicitly).
-
config DEBUG_TASK_STACK_SCAN_OFF
bool "Disable kmemleak task stack scan by default"
depends on DEBUG_KMEMLEAK