Merge "defconfig: Enable PMIC and SPMI MFD drivers for msm8953"
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
index 7496f4d..64154590 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
@@ -21,27 +21,27 @@
Usage: required
Value type: <stringlist>
Definition: Address names. Must be "osm_l3_base", "osm_pwrcl_base",
- "osm_perfcl_base", and "cpr_rc".
+ "osm_perfcl_base".
Must be specified in the same order as the corresponding
addresses are specified in the reg property.
-- vdd_l3_mx_ao-supply
- Usage: required
- Value type: <phandle>
- Definition: Phandle to the MX active-only regulator device.
-
-- vdd_pwrcl_mx_ao-supply
- Usage: required
- Value type: <phandle>
- Definition: Phandle to the MX active-only regulator device.
-
- qcom,mx-turbo-freq
- Usage: required
+ Usage: optional
Value type: <array>
Definition: List of frequencies for the 3 clock domains (following the
order of L3, power, and performance clusters) that denote
the lowest rate that requires a TURBO vote on the MX rail.
+- vdd_l3_mx_ao-supply
+ Usage: required if qcom,mx-turbo-freq is specified
+ Value type: <phandle>
+ Definition: Phandle to the MX active-only regulator device.
+
+- vdd_pwrcl_mx_ao-supply
+ Usage: required if qcom,mx-turbo-freq is specified
+ Value type: <phandle>
+ Definition: Phandle to the MX active-only regulator device.
+
- l3-devs
Usage: optional
Value type: <phandle>
@@ -63,10 +63,8 @@
compatible = "qcom,clk-cpu-osm";
reg = <0x17d41000 0x1400>,
<0x17d43000 0x1400>,
- <0x17d45800 0x1400>,
- <0x784248 0x4>;
- reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
- "cpr_rc";
+ <0x17d45800 0x1400>;
+ reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
vdd_l3_mx_ao-supply = <&pm8998_s6_level_ao>;
vdd_pwrcl_mx_ao-supply = <&pm8998_s6_level_ao>;
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index 9ee2cc6..6716785 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -176,6 +176,8 @@
- qcom,hold-reset: Indicates that hold QUSB PHY into reset state.
- qcom,phy-clk-scheme: Should be one of "cml" or "cmos" if ref_clk_addr is provided.
- qcom,major-rev: provide major revision number to differentiate power up sequence. default is 2.0
+ - pinctrl-names/pinctrl-0/1: The GPIOs configured as output function. Names represents "active"
+ state when attached in host mode and "suspend" state when detached.
Example:
qusb_phy: qusb@f9b39000 {
diff --git a/arch/Kconfig b/arch/Kconfig
index babac73..a364ece 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -224,6 +224,14 @@
An architecture should select this when it can successfully
build and run with CONFIG_FORTIFY_SOURCE.
+config FORTIFY_COMPILE_CHECK
+ depends on ARCH_HAS_FORTIFY_SOURCE
+ bool
+ help
+ Disable compile time size check for string routines as part
+ of fortify source. Selecting this option will not enforce compile
+ time size check for string functions.
+
# Select if arch init_task initializer is different to init/init_task.c
config ARCH_INIT_TASK
bool
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
index d1d44ec..7819d26 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
@@ -59,7 +59,7 @@
bcm_ip0: bcm-ip0 {
cell-id = <MSM_BUS_BCM_IP0>;
label = "IP0";
- qcom,bcm-name = "CE";
+ qcom,bcm-name = "IP0";
qcom,rscs = <&rsc_apps>;
qcom,bcm-dev;
};
@@ -240,8 +240,8 @@
label = "fab-system_noc";
qcom,fab-dev;
qcom,base-name = "system_noc-base";
- qcom,qos-off = <0>;
- qcom,base-offset = <0>;
+ qcom,qos-off = <4096>;
+ qcom,base-offset = <45056>;
qcom,bypass-qos-prg;
qcom,bus-type = <1>;
clocks = <>;
@@ -261,7 +261,7 @@
mas_llcc_mc: mas-llcc-mc {
cell-id = <MSM_BUS_MASTER_LLCC>;
label = "mas-llcc-mc";
- qcom,buswidth = <16>;
+ qcom,buswidth = <4>;
qcom,agg-ports = <1>;
qcom,connections = <&slv_ebi>;
qcom,bus-dev = <&fab_mc_virt>;
@@ -277,7 +277,7 @@
qcom,bus-dev = <&fab_mem_noc>;
qcom,bcms = <&bcm_sh1>;
qcom,ap-owned;
- qcom,prio = <0>;
+ qcom,prio = <6>;
};
mas_qnm_snoc_gc: mas-qnm-snoc-gc {
@@ -290,6 +290,7 @@
qcom,bus-dev = <&fab_mem_noc>;
qcom,ap-owned;
qcom,prio = <0>;
+ qcom,forwarding;
};
mas_xm_apps_rdwr: mas-xm-apps-rdwr {
@@ -310,9 +311,12 @@
label = "mas-qhm-audio";
qcom,buswidth = <4>;
qcom,agg-ports = <1>;
+ qcom,qport = <9>;
qcom,connections = <&slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_pn2>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_qhm_blsp1: mas-qhm-blsp1 {
@@ -320,9 +324,12 @@
label = "mas-qhm-blsp1";
qcom,buswidth = <4>;
qcom,agg-ports = <1>;
+ qcom,qport = <10>;
qcom,connections = <&slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_pn3>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_qhm_qdss_bam: mas-qhm-qdss-bam {
@@ -330,20 +337,22 @@
label = "mas-qhm-qdss-bam";
qcom,buswidth = <4>;
qcom,agg-ports = <1>;
+ qcom,qport = <11>;
qcom,connections = <&slv_qhs_crypto_cfg
- &slv_qhs_snoc_cfg &slv_qhs_emac_cfg
- &slv_qhs_aoss &slv_qhs_spmi_fetcher
- &slv_qhs_pdm &slv_qns_snoc_memnoc
- &slv_qhs_tcsr &slv_qhs_qpic
- &slv_qxs_imem &slv_qhs_ipa
- &slv_qhs_usb3_phy &slv_qhs_aop
- &slv_qhs_blsp1 &slv_qhs_sdc1
- &slv_qhs_pcie_parf &slv_qhs_audio
- &slv_qhs_tlmm &slv_qhs_prng
- &slv_xs_sys_tcu_cfg &slv_qhs_clk_ctl
- &slv_qhs_usb3>;
+ &slv_qhs_pdm &slv_qhs_pcie_parf
+ &slv_qhs_tlmm &slv_qhs_spmi_fetcher
+ &slv_qhs_prng &slv_qhs_qpic
+ &slv_qxs_imem &slv_qhs_snoc_cfg
+ &slv_qhs_audio &slv_qhs_sdc1
+ &slv_qhs_aoss &slv_qhs_ipa
+ &slv_qns_snoc_memnoc &slv_qhs_usb3_phy
+ &slv_qhs_aop &slv_qhs_tcsr
+ &slv_qhs_blsp1 &slv_xs_sys_tcu_cfg
+ &slv_qhs_usb3 &slv_qhs_clk_ctl>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_sn8>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_qhm_qpic: mas-qhm-qpic {
@@ -381,18 +390,17 @@
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
qcom,connections = <&slv_qhs_crypto_cfg
- &slv_qhs_snoc_cfg &slv_qhs_emac_cfg
+ &slv_qhs_snoc_cfg &slv_qhs_sdc1
&slv_qhs_aoss &slv_qhs_spmi_fetcher
&slv_qhs_pdm &slv_qns_snoc_memnoc
&slv_qhs_tcsr &slv_xs_qdss_stm
&slv_qhs_qpic &slv_qxs_imem
&slv_qhs_ipa &slv_qhs_usb3_phy
&slv_qhs_aop &slv_qhs_blsp1
- &slv_qhs_sdc1 &slv_qhs_pcie_parf
- &slv_qhs_audio &slv_qxs_pcie
- &slv_qhs_tlmm &slv_qhs_prng
- &slv_xs_sys_tcu_cfg &slv_qhs_clk_ctl
- &slv_qhs_usb3>;
+ &slv_qhs_pcie_parf &slv_qhs_audio
+ &slv_qxs_pcie &slv_qhs_tlmm
+ &slv_qhs_prng &slv_xs_sys_tcu_cfg
+ &slv_qhs_clk_ctl &slv_qhs_usb3>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_sn7>;
};
@@ -403,17 +411,17 @@
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
qcom,connections = <&slv_qhs_crypto_cfg
- &slv_qhs_snoc_cfg &slv_qhs_emac_cfg
+ &slv_qhs_snoc_cfg &slv_qhs_sdc1
&slv_qhs_aoss &slv_qhs_spmi_fetcher
&slv_qhs_pdm &slv_qns_snoc_memnoc
&slv_qhs_tcsr &slv_xs_qdss_stm
&slv_qhs_qpic &slv_qxs_imem
&slv_qhs_ipa &slv_qhs_usb3_phy
&slv_qhs_aop &slv_qhs_blsp1
- &slv_qhs_sdc1 &slv_qhs_pcie_parf
- &slv_qhs_audio &slv_qhs_tlmm
- &slv_qhs_prng &slv_xs_sys_tcu_cfg
- &slv_qhs_clk_ctl &slv_qhs_usb3>;
+ &slv_qhs_pcie_parf &slv_qhs_audio
+ &slv_qhs_tlmm &slv_qhs_prng
+ &slv_xs_sys_tcu_cfg &slv_qhs_clk_ctl
+ &slv_qhs_usb3>;
qcom,bus-dev = <&fab_system_noc>;
};
@@ -423,17 +431,16 @@
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
qcom,connections = <&slv_qhs_crypto_cfg
- &slv_qhs_snoc_cfg &slv_qhs_emac_cfg
- &slv_qhs_aoss &slv_qhs_spmi_fetcher
- &slv_qhs_pdm &slv_qhs_tcsr
- &slv_xs_qdss_stm &slv_qhs_qpic
- &slv_qxs_imem &slv_qhs_ipa
+ &slv_qhs_pdm &slv_qhs_pcie_parf
+ &slv_qhs_tlmm &slv_qhs_spmi_fetcher
+ &slv_qhs_prng &slv_qhs_qpic
+ &slv_qxs_imem &slv_qhs_snoc_cfg
+ &slv_qhs_audio &slv_qhs_sdc1
+ &slv_qhs_aoss &slv_qhs_ipa
&slv_qhs_usb3_phy &slv_qhs_aop
- &slv_qhs_blsp1 &slv_qhs_sdc1
- &slv_qhs_pcie_parf &slv_qhs_audio
- &slv_qhs_tlmm &slv_qhs_prng
- &slv_xs_sys_tcu_cfg &slv_qhs_clk_ctl
- &slv_qhs_usb3>;
+ &slv_qhs_tcsr &slv_qhs_blsp1
+ &slv_xs_sys_tcu_cfg &slv_qhs_usb3
+ &slv_xs_qdss_stm &slv_qhs_clk_ctl>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_sn9>;
};
@@ -443,9 +450,12 @@
label = "mas-qxm-crypto";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <1>;
qcom,connections = <&slv_qhs_aoss &slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
- qcom,bcms = <&bcm_ce>;
+ qcom,bcms = <&bcm_ce>, <&bcm_pn5>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
};
mas_qxm_ipa: mas-qxm-ipa {
@@ -453,9 +463,25 @@
label = "mas-qxm-ipa";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <5>;
qcom,connections = <&slv_qns_aggre_noc_ipa>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_sn11>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
+ qcom,forwarding;
+ };
+
+ mas_qxm_ipa2pcie_slv: mas-qxm-ipa2pcie-slv {
+ cell-id = <MSM_BUS_MASTER_IPA_PCIE>;
+ label = "mas-qxm-ipa2pcie-slv";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <6>;
+ qcom,connections = <&slv_qxs_pcie>;
+ qcom,bus-dev = <&fab_system_noc>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
};
mas_xm_emac: mas-xm-emac {
@@ -463,8 +489,11 @@
label = "mas-xm-emac";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <7>;
qcom,connections = <&slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_xm_pcie: mas-xm-pcie {
@@ -472,8 +501,12 @@
label = "mas-xm-pcie";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <2>;
qcom,connections = <&slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
+ qcom,forwarding;
};
mas_xm_qdss_etr: mas-xm-qdss-etr {
@@ -481,20 +514,22 @@
label = "mas-xm-qdss-etr";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <3>;
qcom,connections = <&slv_qhs_crypto_cfg
- &slv_qhs_snoc_cfg &slv_qhs_emac_cfg
- &slv_qhs_aoss &slv_qhs_spmi_fetcher
- &slv_qhs_pdm &slv_qns_snoc_memnoc
- &slv_qhs_tcsr &slv_qhs_qpic
- &slv_qxs_imem &slv_qhs_ipa
- &slv_qhs_usb3_phy &slv_qhs_aop
- &slv_qhs_blsp1 &slv_qhs_sdc1
- &slv_qhs_pcie_parf &slv_qhs_audio
- &slv_qhs_tlmm &slv_qhs_prng
- &slv_xs_sys_tcu_cfg &slv_qhs_clk_ctl
- &slv_qhs_usb3>;
+ &slv_qhs_pdm &slv_qhs_pcie_parf
+ &slv_qhs_tlmm &slv_qhs_spmi_fetcher
+ &slv_qhs_prng &slv_qhs_qpic
+ &slv_qxs_imem &slv_qhs_snoc_cfg
+ &slv_qhs_audio &slv_qhs_sdc1
+ &slv_qhs_aoss &slv_qhs_ipa
+ &slv_qns_snoc_memnoc &slv_qhs_usb3_phy
+ &slv_qhs_aop &slv_qhs_tcsr
+ &slv_qhs_blsp1 &slv_xs_sys_tcu_cfg
+ &slv_qhs_usb3 &slv_qhs_clk_ctl>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_sn8>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_xm_sdc1: mas-xm-sdc1 {
@@ -502,9 +537,12 @@
label = "mas-xm-sdc1";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <8>;
qcom,connections = <&slv_qhs_aoss &slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
qcom,bcms = <&bcm_pn1>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
};
mas_xm_usb3: mas-xm-usb3 {
@@ -512,8 +550,11 @@
label = "mas-xm-usb3";
qcom,buswidth = <8>;
qcom,agg-ports = <1>;
+ qcom,qport = <4>;
qcom,connections = <&slv_qns_aggre_noc>;
qcom,bus-dev = <&fab_system_noc>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
};
/*Internal nodes*/
@@ -532,7 +573,7 @@
slv_ebi:slv-ebi {
cell-id = <MSM_BUS_SLAVE_EBI_CH0>;
label = "slv-ebi";
- qcom,buswidth = <16>;
+ qcom,buswidth = <4>;
qcom,agg-ports = <1>;
qcom,bus-dev = <&fab_mc_virt>;
qcom,bcms = <&bcm_mc0>;
@@ -612,15 +653,6 @@
qcom,bcms = <&bcm_pn0>;
};
- slv_qhs_emac_cfg:slv-qhs-emac-cfg {
- cell-id = <MSM_BUS_SLAVE_EMAC_CFG>;
- label = "slv-qhs-emac-cfg";
- qcom,buswidth = <4>;
- qcom,agg-ports = <1>;
- qcom,bus-dev = <&fab_system_noc>;
- qcom,bcms = <&bcm_pn0>;
- };
-
slv_qhs_ipa:slv-qhs-ipa {
cell-id = <MSM_BUS_SLAVE_IPA_CFG>;
label = "slv-qhs-ipa";
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-rumi.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-rumi.dts
index aa9e7f2..227a120 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-rumi.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-rumi.dts
@@ -61,6 +61,10 @@
compatible = "regulator-fixed";
};
+&ipa_hw {
+ qcom,ipa-hw-mode = <1>; /* IPA hw type = Virtual */
+};
+
&usb {
/delete-property/ qcom,usb-dbm;
qcom,charging-disabled;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi
index f9ad6f4..fbfaa0d 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi
@@ -105,5 +105,28 @@
interrupt-controller;
#interrupt-cells = <2>;
};
+
+ /* ipa - outbound entry to mss */
+ smp2pgpio_ipa_1_out: qcom,smp2pgpio-ipa-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "ipa";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ipa - inbound entry from mss */
+ smp2pgpio_ipa_1_in: qcom,smp2pgpio-ipa-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "ipa";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
index be2b63e..def0e13 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
@@ -92,8 +92,10 @@
/* USB port for Super Speed PHY */
usb3_qmp_phy: ssphy@ff0000 {
compatible = "qcom,usb-ssphy-qmp-v2";
- reg = <0xff0000 0x1000>;
- reg-names = "qmp_phy_base";
+ reg = <0xff0000 0x1000>,
+ <0x01fcb244 0x4>;
+ reg-names = "qmp_phy_base",
+ "vls_clamp_reg";
vdd-supply = <&pmxpoorwills_l4>;
core-supply = <&pmxpoorwills_l1>;
@@ -101,112 +103,108 @@
qcom,vbus-valid-override;
qcom,qmp-phy-init-seq =
/* <reg_offset, value, delay> */
- <0x048 0x07 0x00 /* QSERDES_COM_PLL_IVCO */
- 0x080 0x14 0x00 /* QSERDES_COM_SYSCLK_EN_SEL */
- 0x034 0x04 0x00 /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */
- 0x138 0x30 0x00 /* QSERDES_COM_CLK_SELECT */
- 0x03c 0x02 0x00 /* QSERDES_COM_SYS_CLK_CTRL */
- 0x08c 0x08 0x00 /* QSERDES_COM_RESETSM_CNTRL2 */
- 0x15c 0x06 0x00 /* QSERDES_COM_CMN_CONFIG */
- 0x164 0x01 0x00 /* QSERDES_COM_SVS_MODE_CLK_SEL */
- 0x13c 0x80 0x00 /* QSERDES_COM_HSCLK_SEL */
- 0x0b0 0x82 0x00 /* QSERDES_COM_DEC_START_MODE0 */
- 0x0b8 0xab 0x00 /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
- 0x0bc 0xea 0x00 /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
- 0x0c0 0x02 0x00 /* QSERDES_COM_DIV_FRAC_START3_MODE0 */
- 0x060 0x06 0x00 /* QSERDES_COM_CP_CTRL_MODE0 */
- 0x068 0x16 0x00 /* QSERDES_COM_PLL_RCTRL_MODE0 */
- 0x070 0x36 0x00 /* QSERDES_COM_PLL_CCTRL_MODE0 */
- 0x0dc 0x00 0x00 /* QSERDES_COM_INTEGLOOP_GAIN1_MODE0 */
- 0x0d8 0x3f 0x00 /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */
- 0x0f8 0x01 0x00 /* QSERDES_COM_VCO_TUNE2_MODE0 */
- 0x0f4 0xc9 0x00 /* QSERDES_COM_VCO_TUNE1_MODE0 */
- 0x148 0x0a 0x00 /* QSERDES_COM_CORECLK_DIV_MODE0 */
- 0x0a0 0x00 0x00 /* QSERDES_COM_LOCK_CMP3_MODE0 */
- 0x09c 0x34 0x00 /* QSERDES_COM_LOCK_CMP2_MODE0 */
- 0x098 0x15 0x00 /* QSERDES_COM_LOCK_CMP1_MODE0 */
- 0x090 0x04 0x00 /* QSERDES_COM_LOCK_CMP_EN */
- 0x154 0x00 0x00 /* QSERDES_COM_CORE_CLK_EN */
- 0x094 0x00 0x00 /* QSERDES_COM_LOCK_CMP_CFG */
- 0x0f0 0x00 0x00 /* QSERDES_COM_VCO_TUNE_MAP */
- 0x040 0x0a 0x00 /* QSERDES_COM_SYSCLK_BUF_ENABLE */
- 0x0d0 0x80 0x00 /* QSERDES_COM_INTEGLOOP_INITVAL */
+ <0x058 0x07 0x00 /* QSERDES_COM_PLL_IVCO */
+ 0x094 0x1a 0x00 /* QSERDES_COM_SYSCLK_EN_SEL */
+ 0x044 0x14 0x00 /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */
+ 0x154 0x31 0x00 /* QSERDES_COM_CLK_SELECT */
+ 0x04c 0x02 0x00 /* QSERDES_COM_SYS_CLK_CTRL */
+ 0x0a0 0x08 0x00 /* QSERDES_COM_RESETSM_CNTRL2 */
+ 0x17c 0x06 0x00 /* QSERDES_COM_CMN_CONFIG */
+ 0x184 0x05 0x00 /* QSERDES_COM_SVS_MODE_CLK_SEL */
+ 0x1bc 0x11 0x00 /* QSERDES_COM_BIN_VCOCAL_HSCLK_SEL*/
+ 0x158 0x01 0x00 /* QSERDES_COM_HSCLK_SEL */
+ 0x0bc 0x82 0x00 /* QSERDES_COM_DEC_START_MODE0 */
+ 0x0cc 0xab 0x00 /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
+ 0x0d0 0xea 0x00 /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
+ 0x0d4 0x02 0x00 /* COM_DIV_FRAC_START3_MODE0 */
+ 0x1ac 0xca 0x00 /* COM_BIN_VCOCAL_CMP_CODE1_MODE0 */
+ 0x1b0 0x1e 0x00 /* COM_BIN_VCOCAL_CMP_CODE2_MODE0 */
+ 0x074 0x06 0x00 /* QSERDES_COM_CP_CTRL_MODE0 */
+ 0x07c 0x16 0x00 /* QSERDES_COM_PLL_RCTRL_MODE0 */
+ 0x084 0x36 0x00 /* QSERDES_COM_PLL_CCTRL_MODE0 */
+ 0x0f0 0x00 0x00 /* QSERDES_COM_INTEGLOOP_GAIN1_MODE0 */
+ 0x0ec 0x3f 0x00 /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */
+ 0x114 0x02 0x00 /* QSERDES_COM_VCO_TUNE2_MODE0 */
+ 0x110 0x24 0x00 /* QSERDES_COM_VCO_TUNE1_MODE0 */
+ 0x168 0x0a 0x00 /* QSERDES_COM_CORECLK_DIV_MODE0 */
+ 0x0b0 0x34 0x00 /* QSERDES_COM_LOCK_CMP2_MODE0 */
+ 0x0ac 0x14 0x00 /* QSERDES_COM_LOCK_CMP1_MODE0 */
+ 0x0a4 0x04 0x00 /* QSERDES_COM_LOCK_CMP_EN */
+ 0x174 0x00 0x00 /* QSERDES_COM_CORE_CLK_EN */
+ 0x0a8 0x00 0x00 /* QSERDES_COM_LOCK_CMP_CFG */
+ 0x10c 0x00 0x00 /* QSERDES_COM_VCO_TUNE_MAP */
+ 0x050 0x0a 0x00 /* QSERDES_COM_SYSCLK_BUF_ENABLE */
+ 0x00c 0x0a 0x00 /* QSERDES_COM_BG_TIMER */
0x010 0x01 0x00 /* QSERDES_COM_SSC_EN_CENTER */
0x01c 0x31 0x00 /* QSERDES_COM_SSC_PER1 */
0x020 0x01 0x00 /* QSERDES_COM_SSC_PER2 */
0x014 0x00 0x00 /* QSERDES_COM_SSC_ADJ_PER1 */
0x018 0x00 0x00 /* QSERDES_COM_SSC_ADJ_PER2 */
- 0x024 0x85 0x00 /* QSERDES_COM_SSC_STEP_SIZE1 */
- 0x028 0x07 0x00 /* QSERDES_COM_SSC_STEP_SIZE2 */
- 0x4c0 0x0c 0x00 /* QSERDES_RX_VGA_CAL_CNTRL2 */
- 0x564 0x50 0x00 /* QSERDES_RX_RX_MODE_00 */
- 0x430 0x0b 0x00 /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */
- 0x4d4 0x0e 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
- 0x4d8 0x4e 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
- 0x4dc 0x18 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
- 0x4f8 0x77 0x00 /* RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
- 0x4fc 0x80 0x00 /* RX_RX_OFFSET_ADAPTOR_CNTRL2 */
- 0x504 0x03 0x00 /* QSERDES_RX_SIGDET_CNTRL */
- 0x50c 0x1c 0x00 /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
- 0x434 0x75 0x00 /* RX_UCDR_SO_SATURATION_AND_ENABLE */
- 0x444 0x80 0x00 /* QSERDES_RX_UCDR_PI_CONTROLS */
+ 0x030 0xde 0x00 /* QSERDES_COM_SSC_STEP_SIZE1_MODE1 */
+ 0x034 0x07 0x00 /* QSERDES_COM_SSC_STEP_SIZE2_MODE1 */
+ 0x024 0xde 0x00 /* QSERDES_COM_SSC_STEP_SIZE1_MODE0 */
+ 0x028 0x07 0x00 /* QSERDES_COM_SSC_STEP_SIZE1_MODE0 */
+ 0x4a4 0x3f 0x00 /* QSERDES_RX_RX_IDAC_ENABLES */
+ 0x594 0xbf 0x00 /* QSERDES_RX_RX_MODE_01_HIGH4 */
+ 0x590 0x09 0x00 /* QSERDES_RX_RX_MODE_01_HIGH3 */
+ 0x58c 0xc8 0x00 /* QSERDES_RX_RX_MODE_01_HIGH2 */
+ 0x588 0xc8 0x00 /* QSERDES_RX_RX_MODE_01_HIGH */
+ 0x584 0xe0 0x00 /* QSERDES_RX_RX_MODE_01_LOW */
+ 0x444 0x01 0x00 /* QSERDES_RX_UCDR_PI_CONTROLS */
0x408 0x0a 0x00 /* QSERDES_RX_UCDR_FO_GAIN */
- 0x40c 0x06 0x00 /* QSERDES_RX_UCDR_SO_GAIN */
- 0x500 0x00 0x00 /* QSERDES_RX_SIGDET_ENABLES */
- 0x260 0x10 0x00 /* QSERDES_TX_HIGHZ_DRVR_EN */
- 0x2a4 0x12 0x00 /* QSERDES_TX_RCV_DETECT_LVL_2 */
- 0x28c 0xc6 0x00 /* QSERDES_TX_LANE_MODE_1 */
- 0x248 0x09 0x00 /* TX_RES_CODE_LANE_OFFSET_RX */
- 0x244 0x0d 0x00 /* TX_RES_CODE_LANE_OFFSET_TX */
- 0x8c8 0x83 0x00 /* USB3_UNI_PCS_FLL_CNTRL2 */
- 0x8cc 0x09 0x00 /* USB3_UNI_PCS_FLL_CNT_VAL_L */
- 0x8d0 0xa2 0x00 /* USB3_UNI_PCS_FLL_CNT_VAL_H_TOL */
- 0x8d4 0x40 0x00 /* USB3_UNI_PCS_FLL_MAN_CODE */
- 0x8c4 0x02 0x00 /* USB3_UNI_PCS_FLL_CNTRL1 */
- 0x864 0x1b 0x00 /* USB3_UNI_PCS_POWER_STATE_CONFIG2 */
- 0x80c 0x9f 0x00 /* USB3_UNI_PCS_TXMGN_V0 */
- 0x810 0x9f 0x00 /* USB3_UNI_PCS_TXMGN_V1 */
- 0x814 0xb5 0x00 /* USB3_UNI_PCS_TXMGN_V2 */
- 0x818 0x4c 0x00 /* USB3_UNI_PCS_TXMGN_V3 */
- 0x81c 0x64 0x00 /* USB3_UNI_PCS_TXMGN_V4 */
- 0x820 0x6a 0x00 /* USB3_UNI_PCS_TXMGN_LS */
- 0x824 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_V0 */
- 0x828 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_V0 */
- 0x82c 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_V1 */
- 0x830 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_V1 */
- 0x834 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_V2 */
- 0x838 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_V2 */
- 0x83c 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_V3 */
- 0x840 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_V3 */
- 0x844 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_V4 */
- 0x848 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_V4 */
- 0x84c 0x15 0x00 /* USB3_UNI_PCS_TXDEEMPH_M6DB_LS */
- 0x850 0x0d 0x00 /* USB3_UNI_PCS_TXDEEMPH_M3P5DB_LS */
- 0x85c 0x02 0x00 /* USB3_UNI_PCS_RATE_SLEW_CNTRL */
- 0x8a0 0x04 0x00 /* PCS_PWRUP_RESET_DLY_TIME_AUXCLK */
- 0x88c 0x44 0x00 /* USB3_UNI_PCS_TSYNC_RSYNC_TIME */
- 0x880 0xd1 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG1 */
- 0x884 0x1f 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG2 */
- 0x888 0x47 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG3 */
- 0x870 0xe7 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_P1U2_L */
- 0x874 0x03 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_P1U2_H */
- 0x878 0x40 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_U3_L */
- 0x87c 0x00 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_U3_H */
- 0x9d8 0xba 0x00 /* USB3_UNI_PCS_RX_SIGDET_LVL */
- 0x8b8 0x75 0x00 /* RXEQTRAINING_WAIT_TIME */
- 0x8b0 0x86 0x00 /* PCS_LFPS_TX_ECSTART_EQTLOCK */
- 0x8bc 0x13 0x00 /* PCS_RXEQTRAINING_RUN_TIME */
- 0xa0c 0x21 0x00 /* USB3_UNI_PCS_REFGEN_REQ_CONFIG1 */
- 0xa10 0x60 0x00 /* USB3_UNI_PCS_REFGEN_REQ_CONFIG2 */
+ 0x414 0x06 0x00 /* QSERDES_RX_UCDR_SO_GAIN */
+ 0x430 0x2f 0x00 /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */
+ 0x43c 0xff 0x00 /* RX_UCDR_FASTLOCK_COUNT_LOW */
+ 0x440 0x0f 0x00 /* RX_UCDR_FASTLOCK_COUNT_HIGH */
+ 0x420 0x0a 0x00 /* QSERDES_RX_UCDR_SVS_FO_GAIN */
+ 0x42c 0x06 0x00 /* QSERDES_RX_UCDR_SVS_SO_GAIN */
+ 0x434 0x7f 0x00 /* RX_UCDR_SO_SATURATION_AND_ENABLE */
+ 0x4d8 0x0c 0x00 /* QSERDES_RX_VGA_CAL_CNTRL2 */
+ 0x4ec 0x0e 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
+ 0x4f0 0x4e 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
+ 0x4f4 0x18 0x00 /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
+ 0x5b4 0x04 0x00 /* QSERDES_RX_DFE_EN_TIMER */
+ 0x510 0x77 0x00 /* RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
+ 0x514 0x80 0x00 /* RX_RX_OFFSET_ADAPTOR_CNTRL2 */
+ 0x51c 0x04 0x00 /* QSERDES_RX_SIGDET_CNTRL */
+ 0x524 0x1a 0x00 /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
+ 0x4fc 0x00 0x00 /* QSERDES_RX_RX_IDAC_TSETTLE_HIGH */
+ 0x4f8 0xc0 0x00 /* QSERDES_RX_RX_IDAC_TSETTLE_LOW */
+ 0x258 0x10 0x00 /* QSERDES_TX_HIGHZ_DRVR_EN */
+ 0x29c 0x12 0x00 /* QSERDES_TX_RCV_DETECT_LVL_2 */
+ 0x284 0x05 0x00 /* QSERDES_TX_LANE_MODE_1 */
+ 0x288 0x02 0x00 /* QSERDES_TX_LANE_MODE_2 */
+ 0x28c 0x00 0x00 /* QSERDES_TX_LANE_MODE_3*/
+ 0x89c 0x83 0x00 /* USB3_UNI_PCS_FLL_CNTRL2 */
+ 0x8a0 0x09 0x00 /* USB3_UNI_PCS_FLL_CNT_VAL_L */
+ 0x8a4 0xa2 0x00 /* USB3_UNI_PCS_FLL_CNT_VAL_H_TOL */
+ 0x8a8 0x40 0x00 /* USB3_UNI_PCS_FLL_MAN_CODE */
+ 0x898 0x02 0x00 /* USB3_UNI_PCS_FLL_CNTRL1 */
+ 0x8c4 0xd0 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG1 */
+ 0x8c8 0x17 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG2 */
+ 0x8cc 0x20 0x00 /* USB3_UNI_PCS_LOCK_DETECT_CONFIG3 */
+ 0x890 0x4f 0x00 /* USB3_UNI_PCS_POWER_STATE_CONFIG1 */
+ 0x990 0xe7 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_P1U2_L */
+ 0x994 0x03 0x00 /* USB3_UNI_PCS_RCVR_DTCT_DLY_P1U2_H */
+ 0x988 0xba 0x00 /* USB3_UNI_PCS_RX_SIGDET_LVL */
+ 0xe2c 0x75 0x00 /* USB3_RXEQTRAINING_WAIT_TIME */
+ 0xe38 0x07 0x00 /* USB3_RXEQTRAINING_DFE_TIME_S2 */
+ 0xe18 0x64 0x00 /* USB3_LFPS_DET_HIGH_COUNT_VAL */
+ 0x9c0 0x88 0x00 /* USB3_UNI_PCS_ALIGN_DETECT_CONFIG1 */
+ 0x9c4 0x13 0x00 /* USB3_UNI_PCS_ALIGN_DETECT_CONFIG2 */
+ 0x9dc 0x0d 0x00 /* USB3_UNI_PCS_EQ_CONFIG1 */
+ 0x9e0 0x0d 0x00 /* USB3_UNI_PCS_EQ_CONFIG2 */
+ 0x8dc 0x21 0x00 /* USB3_UNI_PCS_REFGEN_REQ_CONFIG1 */
+ 0x8e0 0x60 0x00 /* USB3_UNI_PCS_REFGEN_REQ_CONFIG2 */
0xffffffff 0xffffffff 0x00>;
qcom,qmp-phy-reg-offset =
- <0x974 /* USB3_UNI_PCS_PCS_STATUS */
- 0x8d8 /* USB3_UNI_PCS_AUTONOMOUS_MODE_CTRL */
- 0x8dc /* USB3_UNI_PCS_LFPS_RXTERM_IRQ_CLEAR */
- 0x804 /* USB3_UNI_PCS_POWER_DOWN_CONTROL */
+ <0x814 /* USB3_UNI_PCS_PCS_STATUS */
+ 0xe08 /* USB3_UNI_PCS_AUTONOMOUS_MODE_CTRL */
+ 0xe14 /* USB3_UNI_PCS_LFPS_RXTERM_IRQ_CLEAR */
+ 0x840 /* USB3_UNI_PCS_POWER_DOWN_CONTROL */
0x800 /* USB3_UNI_PCS_SW_RESET */
- 0x808>; /* USB3_UNI_PCS_START_CONTROL */
+ 0x844>; /* USB3_UNI_PCS_START_CONTROL */
clocks = <&clock_gcc GCC_USB3_PHY_AUX_CLK>,
<&clock_gcc GCC_USB3_PHY_PIPE_CLK>,
@@ -215,5 +213,8 @@
clock-names = "aux_clk", "pipe_clk", "ref_clk_src",
"cfg_ahb_clk";
+ resets = <&clock_gcc GCC_USB3_PHY_BCR>,
+ <&clock_gcc GCC_USB3PHY_PHY_BCR>;
+ reset-names = "phy_reset", "phy_phy_reset";
};
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index 3d2dc66..ae8b5e4 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -206,6 +206,16 @@
mbox-names = "apps";
};
+ snoc_cnoc_keepalive: qcom,snoc_cnoc_keepalive {
+ compatible = "qcom,devbw";
+ governor = "powersave";
+ qcom,src-dst-ports = <53 747>;
+ qcom,active-only;
+ status = "ok";
+ qcom,bw-tbl =
+ < 1 >;
+ };
+
blsp1_uart2: serial@831000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x831000 0x200>;
@@ -484,11 +494,177 @@
reg = <0xc37000c 8>;
};
+ qcom,msm_gsi {
+ compatible = "qcom,msm_gsi";
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa3";
+ qcom,rmnet-ipa-ssr;
+ qcom,ipa-loaduC;
+ qcom,ipa-advertise-sg-support;
+ };
+
system_pm {
compatible = "qcom,system-pm";
mboxes = <&apps_rsc 0>;
};
+ ipa_hw: qcom,ipa@01e00000 {
+ compatible = "qcom,ipa";
+ reg = <0x1e00000 0x34000>,
+ <0x1e04000 0x28000>;
+ reg-names = "ipa-base", "gsi-base";
+ interrupts =
+ <0 241 0>,
+ <0 47 0>;
+ interrupt-names = "ipa-irq", "gsi-irq";
+ qcom,ipa-hw-ver = <14>; /* IPA core version = IPAv4.0 */
+ qcom,ipa-hw-mode = <0>;
+ qcom,ee = <0>;
+ qcom,use-ipa-tethering-bridge;
+ qcom,modem-cfg-emb-pipe-flt;
+ qcom,use-ipa-pm;
+ qcom,bandwidth-vote-for-ipa;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <5>;
+ qcom,msm-bus,num-paths = <4>;
+ qcom,msm-bus,vectors-KBps =
+ /* No vote */
+ <90 512 0 0>,
+ <90 585 0 0>,
+ <1 676 0 0>,
+ <143 777 0 0>,
+ /* SVS2 */
+ <90 512 3616000 7232000>,
+ <90 585 300000 600000>,
+ <1 676 90000 180000>, /*gcc_config_noc_clk_src */
+ <143 777 0 120>, /* IB defined for IPA2X_clk in MHz*/
+ /* SVS */
+ <90 512 6640000 13280000>,
+ <90 585 400000 800000>,
+ <1 676 100000 200000>,
+ <143 777 0 250>, /* IB defined for IPA2X_clk in MHz*/
+ /* NOMINAL */
+ <90 512 10400000 20800000>,
+ <90 585 800000 1600000>,
+ <1 676 200000 400000>,
+ <143 777 0 440>, /* IB defined for IPA2X_clk in MHz*/
+ /* TURBO */
+ <90 512 10400000 20800000>,
+ <90 585 960000 1920000>,
+ <1 676 266000 532000>,
+ <143 777 0 500>; /* IB defined for IPA clk in MHz*/
+ qcom,bus-vector-names = "MIN", "SVS2", "SVS", "NOMINAL",
+ "TURBO";
+ qcom,throughput-threshold = <310 600 1000>;
+ qcom,scaling-exceptions = <>;
+
+
+ /* IPA RAM mmap */
+ qcom,ipa-ram-mmap = <
+ 0x280 /* ofst_start; */
+ 0x0 /* nat_ofst; */
+ 0x0 /* nat_size; */
+ 0x288 /* v4_flt_hash_ofst; */
+ 0x78 /* v4_flt_hash_size; */
+ 0x4000 /* v4_flt_hash_size_ddr; */
+ 0x308 /* v4_flt_nhash_ofst; */
+ 0x78 /* v4_flt_nhash_size; */
+ 0x4000 /* v4_flt_nhash_size_ddr; */
+ 0x388 /* v6_flt_hash_ofst; */
+ 0x78 /* v6_flt_hash_size; */
+ 0x4000 /* v6_flt_hash_size_ddr; */
+ 0x408 /* v6_flt_nhash_ofst; */
+ 0x78 /* v6_flt_nhash_size; */
+ 0x4000 /* v6_flt_nhash_size_ddr; */
+ 0xf /* v4_rt_num_index; */
+ 0x0 /* v4_modem_rt_index_lo; */
+ 0x7 /* v4_modem_rt_index_hi; */
+ 0x8 /* v4_apps_rt_index_lo; */
+ 0xe /* v4_apps_rt_index_hi; */
+ 0x488 /* v4_rt_hash_ofst; */
+ 0x78 /* v4_rt_hash_size; */
+ 0x4000 /* v4_rt_hash_size_ddr; */
+ 0x508 /* v4_rt_nhash_ofst; */
+ 0x78 /* v4_rt_nhash_size; */
+ 0x4000 /* v4_rt_nhash_size_ddr; */
+ 0xf /* v6_rt_num_index; */
+ 0x0 /* v6_modem_rt_index_lo; */
+ 0x7 /* v6_modem_rt_index_hi; */
+ 0x8 /* v6_apps_rt_index_lo; */
+ 0xe /* v6_apps_rt_index_hi; */
+ 0x588 /* v6_rt_hash_ofst; */
+ 0x78 /* v6_rt_hash_size; */
+ 0x4000 /* v6_rt_hash_size_ddr; */
+ 0x608 /* v6_rt_nhash_ofst; */
+ 0x78 /* v6_rt_nhash_size; */
+ 0x4000 /* v6_rt_nhash_size_ddr; */
+ 0x688 /* modem_hdr_ofst; */
+ 0x140 /* modem_hdr_size; */
+ 0x7c8 /* apps_hdr_ofst; */
+ 0x0 /* apps_hdr_size; */
+ 0x800 /* apps_hdr_size_ddr; */
+ 0x7d0 /* modem_hdr_proc_ctx_ofst; */
+ 0x200 /* modem_hdr_proc_ctx_size; */
+ 0x9d0 /* apps_hdr_proc_ctx_ofst; */
+ 0x200 /* apps_hdr_proc_ctx_size; */
+ 0x0 /* apps_hdr_proc_ctx_size_ddr; */
+ 0x0 /* modem_comp_decomp_ofst; diff */
+ 0x0 /* modem_comp_decomp_size; diff */
+ 0x13f0 /* modem_ofst; */
+ 0x100c /* modem_size; */
+ 0x23fc /* apps_v4_flt_hash_ofst; */
+ 0x0 /* apps_v4_flt_hash_size; */
+ 0x23fc /* apps_v4_flt_nhash_ofst; */
+ 0x0 /* apps_v4_flt_nhash_size; */
+ 0x23fc /* apps_v6_flt_hash_ofst; */
+ 0x0 /* apps_v6_flt_hash_size; */
+ 0x23fc /* apps_v6_flt_nhash_ofst; */
+ 0x0 /* apps_v6_flt_nhash_size; */
+ 0x80 /* uc_info_ofst; */
+ 0x200 /* uc_info_size; */
+ 0x2800 /* end_ofst; */
+ 0x23fc /* apps_v4_rt_hash_ofst; */
+ 0x0 /* apps_v4_rt_hash_size; */
+ 0x23fc /* apps_v4_rt_nhash_ofst; */
+ 0x0 /* apps_v4_rt_nhash_size; */
+ 0x23fc /* apps_v6_rt_hash_ofst; */
+ 0x0 /* apps_v6_rt_hash_size; */
+ 0x23fc /* apps_v6_rt_nhash_ofst; */
+ 0x0 /* apps_v6_rt_nhash_size; */
+ 0x2400 /* uc_event_ring_ofst; */
+ 0x400 /* uc_event_ring_size;*/
+ 0xbd8 /* pdn_config_ofst; */
+ 0x50 /* pdn_config_size; */
+ 0xc30 /* stats_quota_ofst */
+ 0x60 /* stats_quota_size */
+ 0xc90 /* stats_tethering_ofst */
+ 0x140 /* stats_tethering_size */
+ 0xdd0 /* stats_flt_v4_ofst */
+ 0x180 /* stats_flt_v4_size */
+ 0xf50 /* stats_flt_v6_ofst */
+ 0x180 /* stats_flt_v6_size */
+ 0x10d0 /* stats_rt_v4_ofst */
+ 0x180 /* stats_rt_v4_size */
+ 0x1250 /* stats_rt_v6_ofst */
+ 0x180 /* stats_rt_v6_size */
+ 0x13d0 /* stats_drop_ofst */
+ 0x20 /* stats_drop_size */
+ >;
+
+ /* smp2p gpio information */
+ qcom,smp2pgpio_map_ipa_1_out {
+ compatible = "qcom,smp2pgpio-map-ipa-1-out";
+ gpios = <&smp2pgpio_ipa_1_out 0 0>;
+ };
+
+ qcom,smp2pgpio_map_ipa_1_in {
+ compatible = "qcom,smp2pgpio-map-ipa-1-in";
+ gpios = <&smp2pgpio_ipa_1_in 0 0>;
+ };
+ };
+
emac_hw: qcom,emac@00020000 {
compatible = "qcom,emac-dwc-eqos";
reg = <0x20000 0x10000>,
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 067878b..944fe67 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -25,6 +25,7 @@
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 46f3e0c..c744f9e 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -29,6 +29,7 @@
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 8edfbf2..6531949 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -144,6 +144,7 @@
depends on ARCH_QCOM
select COMMON_CLK_QCOM
select QCOM_GDSC
+ select CPU_FREQ_QCOM
help
This enables support for the MSM8953 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
@@ -153,6 +154,7 @@
depends on ARCH_QCOM
select COMMON_CLK_QCOM
select QCOM_GDSC
+ select CPU_FREQ_QCOM
help
This enables support for the sdm450 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 3df7439..5a7e17e 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -126,7 +126,8 @@
sda670-pm660a-mtp-overlay.dtbo \
qcs605-cdp-overlay.dtbo \
qcs605-mtp-overlay.dtbo \
- qcs605-external-codec-mtp-overlay.dtbo
+ qcs605-external-codec-mtp-overlay.dtbo \
+ qcs605-lc-mtp-overlay.dtbo
sdm670-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-mtp-overlay.dtbo-base := sdm670.dtb
@@ -154,6 +155,7 @@
qcs605-cdp-overlay.dtbo-base := qcs605.dtb
qcs605-mtp-overlay.dtbo-base := qcs605.dtb
qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
+qcs605-lc-mtp-overlay.dtbo-base := qcs605.dtb
else
dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
@@ -182,7 +184,8 @@
qcs605-360camera.dtb \
qcs605-mtp.dtb \
qcs605-cdp.dtb \
- qcs605-external-codec-mtp.dtb
+ qcs605-external-codec-mtp.dtb \
+ qcs605-lc-mtp.dtb
endif
ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
index 1b78fdd..8d80a40 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
@@ -58,6 +58,7 @@
reg = <0x0>;
enable-method = "psci";
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
compatible = "arm,arch-cache";
@@ -81,6 +82,7 @@
enable-method = "psci";
reg = <0x1>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_1: l1-icache {
compatible = "arm,arch-cache";
@@ -98,6 +100,7 @@
enable-method = "psci";
reg = <0x2>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_2: l1-icache {
compatible = "arm,arch-cache";
@@ -115,6 +118,7 @@
enable-method = "psci";
reg = <0x3>;
efficiency = <1024>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
next-level-cache = <&L2_0>;
L1_I_3: l1-icache {
compatible = "arm,arch-cache";
@@ -132,6 +136,7 @@
enable-method = "psci";
reg = <0x100>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
compatible = "arm,arch-cache";
@@ -155,6 +160,7 @@
enable-method = "psci";
reg = <0x101>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_101: l1-icache {
compatible = "arm,arch-cache";
@@ -172,6 +178,7 @@
enable-method = "psci";
reg = <0x102>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_102: l1-icache {
compatible = "arm,arch-cache";
@@ -189,6 +196,7 @@
enable-method = "psci";
reg = <0x103>;
efficiency = <1126>;
+ sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
next-level-cache = <&L2_1>;
L1_I_103: l1-icache {
compatible = "arm,arch-cache";
@@ -200,6 +208,77 @@
};
};
};
+
+ energy_costs: energy-costs {
+ compatible = "sched-energy";
+
+ CPU_COST_0: core-cost0 {
+ busy-cost-data = <
+ 652800 5
+ 883200 8
+ 1036800 10
+ 1248000 13
+ 1401600 16
+ 1536000 19
+ 1689600 22
+ 1804800 26
+ 1843200 27
+ 1958400 33
+ 2016000 36
+ 2150400 43
+ 2208000 44
+ 2304000 54
+ 2400000 65
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ CLUSTER_COST_0: cluster-cost0 {
+ busy-cost-data = <
+ 652800 69
+ 883200 72
+ 1036800 74
+ 1248000 77
+ 1401600 80
+ 1536000 90
+ 1689600 100
+ 1804800 110
+ 1843200 120
+ 1958400 130
+ 2016000 140
+ 2150400 150
+ 2208000 160
+ 2304000 170
+ 2400000 180
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ CLUSTER_COST_1: cluster-cost1 {
+ busy-cost-data = <
+ 652800 5
+ 883200 8
+ 1036800 10
+ 1248000 13
+ 1401600 16
+ 1536000 85
+ 1689600 95
+ 1804800 105
+ 1843200 115
+ 1958400 125
+ 2016000 135
+ 2150400 145
+ 2208000 155
+ 2304000 165
+ 2400000 175
+ >;
+ idle-cost-data = <
+ 4 3 2 1
+ >;
+ };
+ };
};
&soc {
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index c7b578b..a9ca87c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -619,7 +619,12 @@
reg = <0x6b0 32>;
};
- pil@94c {
+ kaslr_offset@6d0 {
+ compatible = "qcom,msm-imem-kaslr_offset";
+ reg = <0x6d0 12>;
+ };
+
+ pil@94c {
compatible = "qcom,msm-imem-pil";
reg = <0x94c 200>;
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp-overlay.dts
new file mode 100644
index 0000000..e27baba
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp-overlay.dts
@@ -0,0 +1,30 @@
+/*
+ * 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 <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "qcs605-lc-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,msm-id = <347 0x0>;
+ qcom,board-id = <8 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dts
new file mode 100644
index 0000000..194bfeb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.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/;
+
+#include "qcs605.dtsi"
+#include "qcs605-lc-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,board-id = <8 4>;
+
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
new file mode 100644
index 0000000..b46cbfd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
@@ -0,0 +1,113 @@
+/* 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.
+ */
+
+/ {
+ cpus {
+ /delete-node/ cpu@200;
+ /delete-node/ cpu@300;
+ /delete-node/ cpu@400;
+ /delete-node/ cpu@500;
+
+ cpu-map {
+ cluster0 {
+ /delete-node/ core2;
+ /delete-node/ core3;
+ /delete-node/ core4;
+ /delete-node/ core5;
+ };
+ };
+ };
+
+
+};
+
+&soc {
+ /delete-node/ jtagmm@7240000;
+ /delete-node/ jtagmm@7340000;
+ /delete-node/ jtagmm@7440000;
+ /delete-node/ jtagmm@7540000;
+ /delete-node/ cti@7220000;
+ /delete-node/ cti@7320000;
+ /delete-node/ cti@7420000;
+ /delete-node/ cti@7520000;
+ /delete-node/ etm@7240000;
+ /delete-node/ etm@7340000;
+ /delete-node/ etm@7440000;
+ /delete-node/ etm@7540000;
+ cpuss_dump {
+ /delete-node/ qcom,l1_i_cache200;
+ /delete-node/ qcom,l1_i_cache300;
+ /delete-node/ qcom,l1_i_cache400;
+ /delete-node/ qcom,l1_i_cache500;
+ /delete-node/ qcom,l1_d_cache200;
+ /delete-node/ qcom,l1_d_cache300;
+ /delete-node/ qcom,l1_d_cache400;
+ /delete-node/ qcom,l1_d_cache500;
+ /delete-node/ qcom,l1_tlb_dump200;
+ /delete-node/ qcom,l1_tlb_dump300;
+ /delete-node/ qcom,l1_tlb_dump400;
+ /delete-node/ qcom,l1_tlb_dump500;
+ };
+
+ devfreq_memlat_0: qcom,cpu0-memlat-mon {
+ qcom,cpulist = <&CPU0 &CPU1>;
+ };
+
+ devfreq_l3lat_0: qcom,cpu0-l3lat-mon {
+ qcom,cpulist = <&CPU0 &CPU1>;
+ };
+ devfreq_compute0: qcom,devfreq-compute0 {
+ qcom,cpulist = <&CPU0 &CPU1>;
+ };
+
+ funnel_apss: funnel@7800000 {
+ ports {
+ /delete-node/ port@3;
+ /delete-node/ port@4;
+ /delete-node/ port@5;
+ /delete-node/ port@6;
+ };
+ };
+
+ qcom,lpm-levels {
+ qcom,pm-cluster@0 {
+ qcom,pm-cpu@0 {
+ qcom,cpu = <&CPU0 &CPU1>;
+ };
+ };
+ };
+};
+
+&pm660_temp_alarm {
+ cooling-maps {
+ /delete-node/ trip0_cpu2;
+ /delete-node/ trip0_cpu3;
+ /delete-node/ trip0_cpu4;
+ /delete-node/ trip0_cpu5;
+ /delete-node/ trip1_cpu2;
+ /delete-node/ trip1_cpu3;
+ /delete-node/ trip1_cpu4;
+ /delete-node/ trip1_cpu5;
+ };
+};
+
+&thermal_zones {
+
+ xo-therm-cpu-step {
+ cooling-maps {
+ /delete-node/ skin_cpu2;
+ /delete-node/ skin_cpu3;
+ /delete-node/ skin_cpu4;
+ /delete-node/ skin_cpu5;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera.dtsi
index 110e626..1f40e20 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera.dtsi
@@ -875,7 +875,6 @@
"soc_ahb_clk",
"cpas_ahb_clk",
"camnoc_axi_clk",
- "icp_apb_clk",
"icp_clk",
"icp_clk_src";
clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>,
@@ -884,7 +883,6 @@
<&clock_camcc CAM_CC_SOC_AHB_CLK>,
<&clock_camcc CAM_CC_CPAS_AHB_CLK>,
<&clock_camcc CAM_CC_CAMNOC_AXI_CLK>,
- <&clock_camcc CAM_CC_ICP_APB_CLK>,
<&clock_camcc CAM_CC_ICP_CLK>,
<&clock_camcc CAM_CC_ICP_CLK_SRC>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
index 8323476..f8a8e15 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
@@ -63,6 +63,9 @@
clocks = <&clock_aop QDSS_CLK>;
clock-names = "apb_pclk";
+ interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "byte-cntr-irq";
+
port {
tmc_etr_in_replicator: endpoint {
slave-mode;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index e9924e2..c136752 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -371,4 +371,7 @@
xo-therm-mdm-step {
status = "disabled";
};
+ xo-therm-batt-step {
+ status = "disabled";
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
index 0a7e25d..5d3975c 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -385,3 +385,63 @@
vbus_dwc3-supply = <&smb2_vbus>;
qcom,no-vbus-vote-with-type-C;
};
+
+&thermal_zones {
+ xo-therm-batt-step {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm660_adc_tm 0x4c>;
+ thermal-governor = "step_wise";
+
+ trips {
+ batt_trip1: batt-trip1 {
+ temperature = <40000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip2: batt-trip2 {
+ temperature = <45000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip3: batt-trip3 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "passive";
+ };
+ batt_trip4: batt-trip4 {
+ temperature = <50000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ batt_trip5: batt-trip5 {
+ temperature = <52000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ battery_lvl1 {
+ trip = <&batt_trip1>;
+ cooling-device = <&pm660_charger 1 1>;
+ };
+ battery_lvl2 {
+ trip = <&batt_trip2>;
+ cooling-device = <&pm660_charger 2 2>;
+ };
+ battery_lvl3 {
+ trip = <&batt_trip3>;
+ cooling-device = <&pm660_charger 3 3>;
+ };
+ battery_lvl4 {
+ trip = <&batt_trip4>;
+ cooling-device = <&pm660_charger 4 4>;
+ };
+ battery_lvl5 {
+ trip = <&batt_trip5>;
+ cooling-device = <&pm660_charger 5 5>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index 3c84314..9898ada 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -459,9 +459,9 @@
pm660_l19: regulator-pm660-l19 {
regulator-name = "pm660_l19";
qcom,set = <RPMH_REGULATOR_SET_ALL>;
- regulator-min-microvolt = <3312000>;
+ regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3312000>;
- qcom,init-voltage = <3312000>;
+ qcom,init-voltage = <3000000>;
qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
index 6324b64..8cbc84f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
@@ -1539,7 +1539,7 @@
type = "passive";
};
silver_trip1: silver-trip1 {
- temperature = <48000>;
+ temperature = <50000>;
hysteresis = <0>;
type = "passive";
};
@@ -1606,7 +1606,7 @@
};
modem_trip2: modem-trip2 {
temperature = <48000>;
- hysteresis = <2000>;
+ hysteresis = <3000>;
type = "passive";
};
modem_trip3: modem-trip3 {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 771e599..0b8ddf3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -488,22 +488,28 @@
reg = <0 0x92e00000 0 0x500000>;
};
- pil_cdsp_mem: cdsp_regions@93300000 {
+ wlan_msa_mem: wlan_msa_region@93300000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x93300000 0 0x800000>;
+ reg = <0 0x93300000 0 0x100000>;
};
- pil_mba_mem: pil_mba_region@0x93b00000 {
+ pil_cdsp_mem: cdsp_regions@93400000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x93b00000 0 0x200000>;
+ reg = <0 0x93400000 0 0x800000>;
};
- pil_adsp_mem: pil_adsp_region@93d00000 {
+ pil_mba_mem: pil_mba_region@0x93c00000 {
compatible = "removed-dma-pool";
no-map;
- reg = <0 0x93d00000 0 0x1e00000>;
+ reg = <0 0x93c00000 0 0x200000>;
+ };
+
+ pil_adsp_mem: pil_adsp_region@93e00000 {
+ compatible = "removed-dma-pool";
+ no-map;
+ reg = <0 0x93e00000 0 0x1e00000>;
};
adsp_mem: adsp_region {
@@ -565,6 +571,8 @@
#include "sdm670-smp2p.dtsi"
+#include "msm-rdbg.dtsi"
+
#include "sdm670-qupv3.dtsi"
#include "sdm670-coresight.dtsi"
@@ -1034,14 +1042,12 @@
compatible = "qcom,clk-cpu-osm-sdm670";
reg = <0x17d41000 0x1400>,
<0x17d43000 0x1400>,
- <0x17d45800 0x1400>,
- <0x784248 0x4>;
- reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
- "cpr_rc";
+ <0x17d45800 0x1400>;
+ reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
vdd_l3_mx_ao-supply = <&pm660l_s1_level_ao>;
vdd_pwrcl_mx_ao-supply = <&pm660l_s1_level_ao>;
- qcom,mx-turbo-freq = <1478400000 1689600000 3300000001>;
+ qcom,mx-turbo-freq = <3300000001 3300000001 3300000001>;
l3-devs = <&l3_cpu0 &l3_cpu6>;
clock-names = "xo_ao";
@@ -1110,7 +1116,7 @@
reg-names = "wdt-base";
interrupts = <0 0 0>, <0 1 0>;
qcom,bark-time = <11000>;
- qcom,pet-time = <10000>;
+ qcom,pet-time = <9360>;
qcom,ipi-ping;
qcom,wakeup-enable;
};
@@ -2471,6 +2477,7 @@
vdd-1.8-xo-supply = <&pm660_l9>;
vdd-1.3-rfa-supply = <&pm660_l6>;
vdd-3.3-ch0-supply = <&pm660_l19>;
+ qcom,vdd-3.3-ch0-config = <3000000 3312000>;
qcom,wlan-msa-memory = <0x100000>;
qcom,smmu-s1-bypass;
};
@@ -2547,6 +2554,16 @@
< MHZ_TO_MBPS(1804, 4) >; /* 6881 MB/s */
};
+ snoc_cnoc_keepalive: qcom,snoc_cnoc_keepalive {
+ compatible = "qcom,devbw";
+ governor = "powersave";
+ qcom,src-dst-ports = <139 627>;
+ qcom,active-only;
+ status = "ok";
+ qcom,bw-tbl =
+ < 1 >;
+ };
+
devfreq_memlat_0: qcom,cpu0-memlat-mon {
compatible = "qcom,arm-memlat-mon";
qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3 &CPU4 &CPU5>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 4ecb49a..d12a954 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -515,6 +515,13 @@
qcom,mdss-dsi-pan-enable-dynamic-fps;
qcom,mdss-dsi-pan-fps-update =
"dfps_immediate_porch_mode_vfp";
+ qcom,esd-check-enabled;
+ qcom,mdss-dsi-panel-status-check-mode = "reg_read";
+ qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-panel-status-value = <0x9c>;
+ qcom,mdss-dsi-panel-on-check-value = <0x9c>;
+ qcom,mdss-dsi-panel-status-read-length = <1>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
@@ -529,6 +536,13 @@
&dsi_dual_nt35597_truly_cmd {
qcom,mdss-dsi-t-clk-post = <0x0D>;
qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,esd-check-enabled;
+ qcom,mdss-dsi-panel-status-check-mode = "reg_read";
+ qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-panel-status-value = <0x9c>;
+ qcom,mdss-dsi-panel-on-check-value = <0x9c>;
+ qcom,mdss-dsi-panel-status-read-length = <1>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
@@ -544,6 +558,13 @@
qcom,mdss-dsi-t-clk-post = <0x0b>;
qcom,mdss-dsi-t-clk-pre = <0x23>;
qcom,ulps-enabled;
+ qcom,esd-check-enabled;
+ qcom,mdss-dsi-panel-status-check-mode = "reg_read";
+ qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-panel-status-value = <0x9c>;
+ qcom,mdss-dsi-panel-on-check-value = <0x9c>;
+ qcom,mdss-dsi-panel-status-read-length = <1>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
@@ -564,6 +585,13 @@
qcom,mdss-dsi-pan-enable-dynamic-fps;
qcom,mdss-dsi-pan-fps-update =
"dfps_immediate_porch_mode_vfp";
+ qcom,esd-check-enabled;
+ qcom,mdss-dsi-panel-status-check-mode = "reg_read";
+ qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
+ qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
+ qcom,mdss-dsi-panel-status-value = <0x9c>;
+ qcom,mdss-dsi-panel-on-check-value = <0x9c>;
+ qcom,mdss-dsi-panel-status-read-length = <1>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
index 1fcf893..947d28b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
@@ -81,12 +81,6 @@
&clock_cpucc {
compatible = "qcom,clk-cpu-osm-v2";
- reg = <0x17d41000 0x1400>,
- <0x17d43000 0x1400>,
- <0x17d45800 0x1400>,
- <0x78425c 0x4>;
- reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
- "cpr_rc";
};
&pcie1 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 5b050c5..5b3178d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1229,10 +1229,8 @@
compatible = "qcom,clk-cpu-osm";
reg = <0x17d41000 0x1400>,
<0x17d43000 0x1400>,
- <0x17d45800 0x1400>,
- <0x784248 0x4>;
- reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base",
- "cpr_rc";
+ <0x17d45800 0x1400>;
+ reg-names = "osm_l3_base", "osm_pwrcl_base", "osm_perfcl_base";
vdd_l3_mx_ao-supply = <&pm8998_s6_level_ao>;
vdd_pwrcl_mx_ao-supply = <&pm8998_s6_level_ao>;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index 784041f..2539aa2 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -26,6 +26,7 @@
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
@@ -65,6 +66,7 @@
CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
# CONFIG_ARM64_VHE is not set
+CONFIG_RANDOMIZE_BASE=y
CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_COMPAT=y
@@ -415,6 +417,8 @@
CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_EUD=y
CONFIG_QCOM_WATCHDOG_V2=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 6a89221..52f9976 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -30,6 +30,7 @@
# CONFIG_PID_NS is not set
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
# CONFIG_RD_LZO is not set
@@ -71,6 +72,7 @@
CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
# CONFIG_ARM64_VHE is not set
+CONFIG_RANDOMIZE_BASE=y
CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_COMPAT=y
@@ -429,6 +431,8 @@
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_DEBUG_TRACKING=y
CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_MSM_CORE_HANG_DETECT=y
CONFIG_MSM_GLADIATOR_HANG_DETECT=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 822324d..ab7268f 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -314,6 +314,7 @@
CONFIG_HW_RANDOM_MSM_LEGACY=y
# CONFIG_DEVPORT is not set
CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_QCOM_GENI=y
CONFIG_SPI=y
diff --git a/drivers/bluetooth/btfm_slim.c b/drivers/bluetooth/btfm_slim.c
index 8f0e632..64d7ac7 100644
--- a/drivers/bluetooth/btfm_slim.c
+++ b/drivers/bluetooth/btfm_slim.c
@@ -130,17 +130,25 @@
BTFMSLIM_DBG("port: %d ch: %d", ch->port, ch->ch);
/* Define the channel with below parameters */
- prop.prot = SLIM_AUTO_ISO;
- prop.baser = SLIM_RATE_4000HZ;
- prop.dataf = (rates == 48000) ? SLIM_CH_DATAF_NOT_DEFINED
- : SLIM_CH_DATAF_LPCM_AUDIO;
+ prop.prot = SLIM_AUTO_ISO;
+ prop.baser = ((rates == 44100) || (rates == 88200)) ?
+ SLIM_RATE_11025HZ : SLIM_RATE_4000HZ;
+ prop.dataf = ((rates == 48000) || (rates == 44100) ||
+ (rates == 88200) || (rates == 96000)) ?
+ SLIM_CH_DATAF_NOT_DEFINED : SLIM_CH_DATAF_LPCM_AUDIO;
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
- prop.ratem = (rates/4000);
+ prop.ratem = ((rates == 44100) || (rates == 88200)) ?
+ (rates/11025) : (rates/4000);
prop.sampleszbits = 16;
ch_h[0] = ch->ch_hdl;
ch_h[1] = (grp) ? (ch+1)->ch_hdl : 0;
+ BTFMSLIM_INFO("channel define - prot:%d, dataf:%d, auxf:%d",
+ prop.prot, prop.dataf, prop.auxf);
+ BTFMSLIM_INFO("channel define - rates:%d, baser:%d, ratem:%d",
+ rates, prop.baser, prop.ratem);
+
ret = slim_define_ch(btfmslim->slim_pgd, &prop, ch_h, nchan, grp,
&ch->grph);
if (ret < 0) {
diff --git a/drivers/bluetooth/btfm_slim_codec.c b/drivers/bluetooth/btfm_slim_codec.c
index 309648f..53388ed 100644
--- a/drivers/bluetooth/btfm_slim_codec.c
+++ b/drivers/bluetooth/btfm_slim_codec.c
@@ -385,10 +385,12 @@
.id = BTFM_BT_SCO_A2DP_SLIM_RX,
.playback = {
.stream_name = "SCO A2DP RX Playback",
+ /* 8/16/44.1/48/88.2/96 Khz */
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000
- | SNDRV_PCM_RATE_48000, /* 8 or 16 or 48 Khz*/
+ | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000
+ | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */
- .rate_max = 48000,
+ .rate_max = 96000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 1,
diff --git a/drivers/bluetooth/btfm_slim_wcn3990.c b/drivers/bluetooth/btfm_slim_wcn3990.c
index f0a6d9e..2dbba83 100644
--- a/drivers/bluetooth/btfm_slim_wcn3990.c
+++ b/drivers/bluetooth/btfm_slim_wcn3990.c
@@ -83,22 +83,31 @@
{
int ret = 0;
uint8_t reg_val = 0, en;
- uint8_t port_bit = 0;
+ uint8_t rxport_num = 0;
uint16_t reg;
BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
if (rxport) {
if (enable) {
/* For SCO Rx, A2DP Rx */
- reg_val = 0x1;
- port_bit = port_num - 0x10;
- reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(port_bit);
+ if (port_num < 24) {
+ rxport_num = port_num - 16;
+ reg_val = 0x01 << rxport_num;
+ reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(
+ rxport_num);
+ } else {
+ rxport_num = port_num - 24;
+ reg_val = 0x01 << rxport_num;
+ reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_1(
+ rxport_num);
+ }
+
BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
- reg_val, reg);
+ reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
- ret, reg);
+ ret, reg);
goto error;
}
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 35eea02..8a28212 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -238,13 +238,13 @@
int ramdumpenabled;
void *remoteheap_ramdump_dev;
struct fastrpc_glink_info link;
- struct mutex mut;
};
struct fastrpc_apps {
struct fastrpc_channel_ctx *channel;
struct cdev cdev;
struct class *class;
+ struct mutex smd_mutex;
struct smq_phy_page range;
struct hlist_head maps;
uint32_t staticpd_flags;
@@ -654,10 +654,6 @@
if (err)
goto bail;
- map->uncached = !ION_IS_CACHED(flags);
- if (map->attr & FASTRPC_ATTR_NOVA)
- map->uncached = 1;
-
map->secure = flags & ION_FLAG_SECURE;
if (map->secure) {
if (!fl->secsctx)
@@ -670,9 +666,15 @@
sess = fl->secsctx;
else
sess = fl->sctx;
+
VERIFY(err, !IS_ERR_OR_NULL(sess));
if (err)
goto bail;
+
+ map->uncached = !ION_IS_CACHED(flags);
+ if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
+ map->uncached = 1;
+
VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
if (err)
goto bail;
@@ -1496,12 +1498,12 @@
INIT_HLIST_HEAD(&me->drivers);
spin_lock_init(&me->hlock);
+ mutex_init(&me->smd_mutex);
me->channel = &gcinfo[0];
for (i = 0; i < NUM_CHANNELS; i++) {
init_completion(&me->channel[i].work);
init_completion(&me->channel[i].workport);
me->channel[i].sesscount = 0;
- mutex_init(&me->channel[i].mut);
}
}
@@ -1619,7 +1621,7 @@
int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
int hlosVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
- VERIFY(err, !fastrpc_channel_open(fl));
+ VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
if (err)
goto bail;
if (init->flags == FASTRPC_INIT_ATTACH) {
@@ -2122,7 +2124,7 @@
ctx->chan = NULL;
glink_unregister_link_state_cb(ctx->link.link_notify_handle);
ctx->link.link_notify_handle = NULL;
- mutex_unlock(&ctx->mut);
+ mutex_unlock(&me->smd_mutex);
pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
MAJOR(me->dev_no), cid);
}
@@ -2215,15 +2217,6 @@
link->port_state = FASTRPC_LINK_DISCONNECTED;
break;
case GLINK_REMOTE_DISCONNECTED:
- mutex_lock(&me->channel[cid].mut);
- if (me->channel[cid].chan) {
- link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
- fastrpc_glink_close(me->channel[cid].chan, cid);
- me->channel[cid].chan = NULL;
- } else {
- link->port_state = FASTRPC_LINK_DISCONNECTED;
- }
- mutex_unlock(&me->channel[cid].mut);
break;
default:
break;
@@ -2234,20 +2227,23 @@
struct fastrpc_session_ctx **session)
{
int err = 0;
+ struct fastrpc_apps *me = &gfa;
- mutex_lock(&chan->mut);
+ mutex_lock(&me->smd_mutex);
if (!*session)
err = fastrpc_session_alloc_locked(chan, secure, session);
- mutex_unlock(&chan->mut);
+ mutex_unlock(&me->smd_mutex);
return err;
}
static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
struct fastrpc_session_ctx *session)
{
- mutex_lock(&chan->mut);
+ struct fastrpc_apps *me = &gfa;
+
+ mutex_lock(&me->smd_mutex);
session->used = 0;
- mutex_unlock(&chan->mut);
+ mutex_unlock(&me->smd_mutex);
}
static int fastrpc_file_free(struct fastrpc_file *fl)
@@ -2280,7 +2276,7 @@
}
if (fl->ssrcount == fl->apps->channel[cid].ssrcount)
kref_put_mutex(&fl->apps->channel[cid].kref,
- fastrpc_channel_close, &fl->apps->channel[cid].mut);
+ fastrpc_channel_close, &fl->apps->smd_mutex);
if (fl->sctx)
fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
if (fl->secsctx)
@@ -2357,20 +2353,6 @@
return err;
}
-static void fastrpc_glink_stop(int cid)
-{
- int err = 0;
- struct fastrpc_glink_info *link;
-
- VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
- if (err)
- return;
- link = &gfa.channel[cid].link;
-
- if (link->port_state == FASTRPC_LINK_CONNECTED)
- link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
-}
-
static void fastrpc_glink_close(void *chan, int cid)
{
int err = 0;
@@ -2548,20 +2530,23 @@
struct fastrpc_apps *me = &gfa;
int cid, err = 0;
+ mutex_lock(&me->smd_mutex);
+
VERIFY(err, fl && fl->sctx);
if (err)
- return err;
+ goto bail;
cid = fl->cid;
VERIFY(err, cid >= 0 && cid < NUM_CHANNELS);
if (err)
goto bail;
- mutex_lock(&me->channel[cid].mut);
if (me->channel[cid].ssrcount !=
me->channel[cid].prevssrcount) {
if (!me->channel[cid].issubsystemup) {
VERIFY(err, 0);
- if (err)
+ if (err) {
+ err = -ENOTCONN;
goto bail;
+ }
}
}
fl->ssrcount = me->channel[cid].ssrcount;
@@ -2574,11 +2559,9 @@
if (err)
goto bail;
- mutex_unlock(&me->channel[cid].mut);
VERIFY(err,
wait_for_completion_timeout(&me->channel[cid].workport,
RPC_TIMEOUT));
- mutex_lock(&me->channel[cid].mut);
if (err) {
me->channel[cid].chan = NULL;
goto bail;
@@ -2603,7 +2586,7 @@
}
bail:
- mutex_unlock(&me->channel[cid].mut);
+ mutex_unlock(&me->smd_mutex);
return err;
}
@@ -2866,7 +2849,7 @@
p.init.init.memlen < INIT_MEMLEN_MAX);
if (err)
goto bail;
- VERIFY(err, 0 == fastrpc_init_process(fl, &p.init));
+ VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
if (err)
goto bail;
break;
@@ -2892,14 +2875,16 @@
ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
cid = ctx - &me->channel[0];
if (code == SUBSYS_BEFORE_SHUTDOWN) {
- mutex_lock(&ctx->mut);
+ mutex_lock(&me->smd_mutex);
ctx->ssrcount++;
ctx->issubsystemup = 0;
- pr_info("'restart notifier: /dev/%s c %d %d'\n",
- gcinfo[cid].name, MAJOR(me->dev_no), cid);
- if (ctx->chan)
- fastrpc_glink_stop(cid);
- mutex_unlock(&ctx->mut);
+ if (ctx->chan) {
+ fastrpc_glink_close(ctx->chan, cid);
+ ctx->chan = NULL;
+ pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
+ gcinfo[cid].name, MAJOR(me->dev_no), cid);
+ }
+ mutex_unlock(&me->smd_mutex);
if (cid == 0)
me->staticpd_flags = 0;
fastrpc_notify_drivers(me, cid);
@@ -3071,15 +3056,15 @@
static void fastrpc_deinit(void)
{
+ struct fastrpc_apps *me = &gfa;
struct fastrpc_channel_ctx *chan = gcinfo;
int i, j;
for (i = 0; i < NUM_CHANNELS; i++, chan++) {
if (chan->chan) {
kref_put_mutex(&chan->kref,
- fastrpc_channel_close, &chan->mut);
+ fastrpc_channel_close, &me->smd_mutex);
chan->chan = NULL;
- mutex_destroy(&chan->mut);
}
for (j = 0; j < NUM_SESSIONS; j++) {
struct fastrpc_session_ctx *sess = &chan->session[j];
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index da13912..f157a2f 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1687,10 +1687,10 @@
break;
case TYPE_CMD:
if (peripheral >= 0 && peripheral < NUM_PERIPHERALS) {
- diagfwd_write_done(peripheral, type, num);
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
"Marking buffer as free after write done p: %d, t: %d, buf_num: %d\n",
peripheral, type, num);
+ diagfwd_write_done(peripheral, type, num);
}
if (peripheral == APPS_DATA ||
ctxt == DIAG_MEMORY_DEVICE_MODE) {
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index 4d6ae23..c7bd2205 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -205,7 +205,8 @@
}
if (buf->len < max_size) {
- if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE) {
+ if (driver->logging_mode == DIAG_MEMORY_DEVICE_MODE ||
+ driver->logging_mode == DIAG_MULTI_MODE) {
ch = &diag_md[DIAG_LOCAL_PROC];
for (i = 0; ch != NULL &&
i < ch->num_tbl_entries; i++) {
@@ -478,7 +479,8 @@
flag_buf_1 = 1;
temp_fwdinfo_cpd = fwd_info->buf_1;
if (fwd_info->type == TYPE_DATA) {
- for (i = 0; i <= (fwd_info->num_pd - 2); i++)
+ for (i = 0; (i <= (fwd_info->num_pd - 2)) &&
+ fwd_info->buf_upd[i][0]; i++)
temp_buf_upd[i] =
fwd_info->buf_upd[i][0]->data_raw;
}
@@ -487,7 +489,8 @@
flag_buf_2 = 1;
temp_fwdinfo_cpd = fwd_info->buf_2;
if (fwd_info->type == TYPE_DATA) {
- for (i = 0; i <= (fwd_info->num_pd - 2); i++)
+ for (i = 0; (i <= (fwd_info->num_pd - 2)) &&
+ fwd_info->buf_upd[i][1]; i++)
temp_buf_upd[i] =
fwd_info->buf_upd[i][1]->data_raw;
}
@@ -557,6 +560,8 @@
else
temp_fwdinfo_upd =
fwd_info->buf_upd[i][1];
+ if (!temp_fwdinfo_upd)
+ break;
temp_fwdinfo_upd->ctxt &= 0x00FFFFFF;
temp_fwdinfo_upd->ctxt |=
(SET_PD_CTXT(ctxt_upd[i]));
@@ -1631,6 +1636,10 @@
fail_return:
diag_ws_release();
atomic_set(&temp_buf->in_busy, 0);
+ DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
+ "Buffer for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
+ fwd_info->peripheral, fwd_info->type,
+ GET_BUF_NUM(temp_buf->ctxt));
}
static void diagfwd_queue_read(struct diagfwd_info *fwd_info)
diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c
index fb0b504..b6204cb 100644
--- a/drivers/clk/qcom/clk-cpu-osm.c
+++ b/drivers/clk/qcom/clk-cpu-osm.c
@@ -55,9 +55,6 @@
#define VOLT_REG 0x114
#define CORE_DCVS_CTRL 0xbc
-#define EFUSE_SHIFT(v1) ((v1) ? 3 : 2)
-#define EFUSE_MASK 0x7
-
#define DCVS_PERF_STATE_DESIRED_REG_0_V1 0x780
#define DCVS_PERF_STATE_DESIRED_REG_0_V2 0x920
#define DCVS_PERF_STATE_DESIRED_REG(n, v1) \
@@ -77,6 +74,7 @@
u16 virtual_corner;
u16 open_loop_volt;
long frequency;
+ u16 ccount;
};
struct clk_osm {
@@ -90,11 +88,11 @@
u32 num_entries;
u32 cluster_num;
u32 core_num;
+ unsigned long rate;
u64 total_cycle_counter;
u32 prev_cycle_counter;
u32 max_core_count;
u32 mx_turbo_freq;
- unsigned int cpr_rc;
};
static bool is_sdm845v1;
@@ -153,6 +151,24 @@
return -EINVAL;
}
+static int clk_osm_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_osm *c = to_clk_osm(hw);
+
+ c->rate = rate;
+
+ return 0;
+}
+
+static unsigned long clk_osm_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_osm *c = to_clk_osm(hw);
+
+ return c->rate;
+}
+
static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
@@ -294,7 +310,7 @@
return cpuclk->osm_table[index].frequency;
}
-static struct clk_ops clk_ops_l3_osm = {
+static const struct clk_ops clk_ops_l3_osm = {
.round_rate = clk_osm_round_rate,
.list_rate = clk_osm_list_rate,
.recalc_rate = l3_clk_recalc_rate,
@@ -302,8 +318,20 @@
.debug_init = clk_debug_measure_add,
};
-static struct clk_ops clk_ops_core;
-static struct clk_ops clk_ops_cpu_osm;
+static const struct clk_ops clk_ops_core = {
+ .set_rate = clk_cpu_set_rate,
+ .round_rate = clk_cpu_round_rate,
+ .recalc_rate = clk_cpu_recalc_rate,
+ .debug_init = clk_debug_measure_add,
+};
+
+static const struct clk_ops clk_ops_cpu_osm = {
+ .set_rate = clk_osm_set_rate,
+ .round_rate = clk_osm_round_rate,
+ .recalc_rate = clk_osm_recalc_rate,
+ .list_rate = clk_osm_list_rate,
+ .debug_init = clk_debug_measure_add,
+};
static struct clk_init_data osm_clks_init[] = {
[0] = {
@@ -639,7 +667,7 @@
struct clk_osm *c, *parent;
struct clk_hw *p_hw;
int ret;
- unsigned int i;
+ unsigned int i, prev_cc = 0;
unsigned int xo_kHz;
c = osm_configure_policy(policy);
@@ -686,8 +714,12 @@
if (core_count != parent->max_core_count)
table[i].frequency = CPUFREQ_ENTRY_INVALID;
- /* Two of the same frequencies means end of table */
- if (i > 0 && table[i - 1].driver_data == table[i].driver_data) {
+ /*
+ * Two of the same frequencies with the same core counts means
+ * end of table.
+ */
+ if (i > 0 && table[i - 1].driver_data == table[i].driver_data
+ && prev_cc == core_count) {
struct cpufreq_frequency_table *prev = &table[i - 1];
if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
@@ -697,6 +729,7 @@
break;
}
+ prev_cc = core_count;
}
table[i].frequency = CPUFREQ_TABLE_END;
@@ -940,6 +973,7 @@
data = clk_osm_read_reg(c, FREQ_REG + i * OSM_REG_SIZE);
src = ((data & GENMASK(31, 30)) >> 30);
lval = (data & GENMASK(7, 0));
+ c->osm_table[i].ccount = CORE_COUNT_VAL(data);
if (!src)
c->osm_table[i].frequency = OSM_INIT_RATE;
@@ -956,8 +990,10 @@
c->osm_table[i].virtual_corner,
c->osm_table[i].open_loop_volt);
- if (i > 0 && j == OSM_TABLE_SIZE && c->osm_table[i].frequency ==
- c->osm_table[i - 1].frequency)
+ if (i > 0 && j == OSM_TABLE_SIZE &&
+ c->osm_table[i].frequency ==
+ c->osm_table[i - 1].frequency &&
+ c->osm_table[i].ccount == c->osm_table[i - 1].ccount)
j = i;
}
@@ -979,8 +1015,7 @@
return -ENOMEM;
for (i = 0; i < j; i++) {
- if (c->osm_table[i].frequency < c->mx_turbo_freq ||
- (c->cpr_rc > 1))
+ if (c->osm_table[i].frequency < c->mx_turbo_freq)
vdd->vdd_uv[i] = RPMH_REGULATOR_LEVEL_NOM;
else
vdd->vdd_uv[i] = RPMH_REGULATOR_LEVEL_TURBO;
@@ -1071,19 +1106,68 @@
perfcl_clk.max_core_count = 2;
}
+/* Request MX supply if configured in device tree */
+static int clk_cpu_osm_request_mx_supply(struct device *dev)
+{
+ u32 *array;
+ int rc;
+
+ if (!of_find_property(dev->of_node, "qcom,mx-turbo-freq", NULL)) {
+ osm_clks_init[l3_clk.cluster_num].vdd_class = NULL;
+ osm_clks_init[pwrcl_clk.cluster_num].vdd_class = NULL;
+ return 0;
+ }
+
+ vdd_l3_mx_ao.regulator[0] = devm_regulator_get(dev, "vdd_l3_mx_ao");
+ if (IS_ERR(vdd_l3_mx_ao.regulator[0])) {
+ rc = PTR_ERR(vdd_l3_mx_ao.regulator[0]);
+ if (rc != -EPROBE_DEFER)
+ dev_err(dev, "Unable to get vdd_l3_mx_ao regulator, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ vdd_pwrcl_mx_ao.regulator[0] = devm_regulator_get(dev,
+ "vdd_pwrcl_mx_ao");
+ if (IS_ERR(vdd_pwrcl_mx_ao.regulator[0])) {
+ rc = PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]);
+ if (rc != -EPROBE_DEFER)
+ dev_err(dev, "Unable to get vdd_pwrcl_mx_ao regulator, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ array = kcalloc(MAX_CLUSTER_CNT, sizeof(*array), GFP_KERNEL);
+ if (!array)
+ return -ENOMEM;
+
+ rc = of_property_read_u32_array(dev->of_node, "qcom,mx-turbo-freq",
+ array, MAX_CLUSTER_CNT);
+ if (rc) {
+ dev_err(dev, "unable to read qcom,mx-turbo-freq property, rc=%d\n",
+ rc);
+ kfree(array);
+ return rc;
+ }
+
+ l3_clk.mx_turbo_freq = array[l3_clk.cluster_num];
+ pwrcl_clk.mx_turbo_freq = array[pwrcl_clk.cluster_num];
+ perfcl_clk.mx_turbo_freq = array[perfcl_clk.cluster_num];
+
+ kfree(array);
+
+ return 0;
+}
+
static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
{
int rc = 0, i, cpu;
- bool is_sdm670 = false;
- u32 *array;
- u32 val, pte_efuse;
- void __iomem *vbase;
+ u32 val;
int num_clks = ARRAY_SIZE(osm_qcom_clk_hws);
struct clk *ext_xo_clk, *clk;
struct clk_osm *osm_clk;
struct device *dev = &pdev->dev;
struct clk_onecell_data *clk_data;
- struct resource *res;
struct cpu_cycle_counter_cb cb = {
.get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter,
};
@@ -1103,68 +1187,12 @@
"qcom,clk-cpu-osm");
if (of_device_is_compatible(pdev->dev.of_node,
- "qcom,clk-cpu-osm-sdm670")) {
- is_sdm670 = true;
+ "qcom,clk-cpu-osm-sdm670"))
clk_cpu_osm_driver_sdm670_fixup();
- }
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cpr_rc");
- if (res) {
- vbase = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!vbase) {
- dev_err(&pdev->dev, "Unable to map in cpr_rc base\n");
- return -ENOMEM;
- }
- pte_efuse = readl_relaxed(vbase);
- l3_clk.cpr_rc = pwrcl_clk.cpr_rc = perfcl_clk.cpr_rc =
- ((pte_efuse >> EFUSE_SHIFT(is_sdm845v1 | is_sdm670))
- & EFUSE_MASK);
- pr_info("LOCAL_CPR_RC: %u\n", l3_clk.cpr_rc);
- devm_iounmap(&pdev->dev, vbase);
- } else {
- dev_err(&pdev->dev,
- "Unable to get platform resource for cpr_rc\n");
- return -ENOMEM;
- }
-
- vdd_l3_mx_ao.regulator[0] = devm_regulator_get(&pdev->dev,
- "vdd_l3_mx_ao");
- if (IS_ERR(vdd_l3_mx_ao.regulator[0])) {
- if (PTR_ERR(vdd_l3_mx_ao.regulator[0]) != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "Unable to get vdd_l3_mx_ao regulator\n");
- return PTR_ERR(vdd_l3_mx_ao.regulator[0]);
- }
-
- vdd_pwrcl_mx_ao.regulator[0] = devm_regulator_get(&pdev->dev,
- "vdd_pwrcl_mx_ao");
- if (IS_ERR(vdd_pwrcl_mx_ao.regulator[0])) {
- if (PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]) != -EPROBE_DEFER)
- dev_err(&pdev->dev,
- "Unable to get vdd_pwrcl_mx_ao regulator\n");
- return PTR_ERR(vdd_pwrcl_mx_ao.regulator[0]);
- }
-
- array = devm_kcalloc(&pdev->dev, MAX_CLUSTER_CNT, sizeof(*array),
- GFP_KERNEL);
- if (!array)
- return -ENOMEM;
-
- rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,mx-turbo-freq",
- array, MAX_CLUSTER_CNT);
- if (rc) {
- dev_err(&pdev->dev, "unable to find qcom,mx-turbo-freq property, rc=%d\n",
- rc);
- devm_kfree(&pdev->dev, array);
+ rc = clk_cpu_osm_request_mx_supply(dev);
+ if (rc)
return rc;
- }
-
- l3_clk.mx_turbo_freq = array[l3_clk.cluster_num];
- pwrcl_clk.mx_turbo_freq = array[pwrcl_clk.cluster_num];
- perfcl_clk.mx_turbo_freq = array[perfcl_clk.cluster_num];
-
- devm_kfree(&pdev->dev, array);
clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
GFP_KERNEL);
@@ -1220,16 +1248,6 @@
spin_lock_init(&pwrcl_clk.lock);
spin_lock_init(&perfcl_clk.lock);
- clk_ops_core = clk_dummy_ops;
- clk_ops_core.set_rate = clk_cpu_set_rate;
- clk_ops_core.round_rate = clk_cpu_round_rate;
- clk_ops_core.recalc_rate = clk_cpu_recalc_rate;
-
- clk_ops_cpu_osm = clk_dummy_ops;
- clk_ops_cpu_osm.round_rate = clk_osm_round_rate;
- clk_ops_cpu_osm.list_rate = clk_osm_list_rate;
- clk_ops_cpu_osm.debug_init = clk_debug_measure_add;
-
/* Register OSM l3, pwr and perf clocks with Clock Framework */
for (i = 0; i < num_clks; i++) {
if (!osm_qcom_clk_hws[i])
diff --git a/drivers/clk/qcom/gcc-sdxpoorwills.c b/drivers/clk/qcom/gcc-sdxpoorwills.c
index 1b5cf61..a62a9a8 100644
--- a/drivers/clk/qcom/gcc-sdxpoorwills.c
+++ b/drivers/clk/qcom/gcc-sdxpoorwills.c
@@ -1353,6 +1353,19 @@
},
};
+static struct clk_branch gcc_pcie_0_clkref_clk = {
+ .halt_reg = 0x88004,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x88004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_clkref_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_pcie_aux_clk = {
.halt_reg = 0x37020,
.halt_check = BRANCH_HALT_VOTED,
@@ -1695,14 +1708,26 @@
},
};
-static struct clk_branch gcc_usb3_phy_pipe_clk = {
- .halt_reg = 0xb054,
- .halt_check = BRANCH_HALT,
+static struct clk_gate2 gcc_usb3_phy_pipe_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0xb054,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb3_phy_pipe_clk",
+ .ops = &clk_gate2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+ .halt_reg = 0x88000,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x88000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb3_prim_clkref_clk",
.ops = &clk_branch2_ops,
},
},
@@ -1782,6 +1807,7 @@
[GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+ [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr,
[GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr,
[GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr,
[GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr,
@@ -1813,6 +1839,7 @@
[GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
[GCC_USB3_PHY_AUX_CLK_SRC] = &gcc_usb3_phy_aux_clk_src.clkr,
[GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+ [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
[GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
[GPLL0] = &gpll0.clkr,
[GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
@@ -1837,6 +1864,8 @@
[GCC_SDCC1_BCR] = { 0xf000 },
[GCC_SPMI_FETCHER_BCR] = { 0x3f000 },
[GCC_USB30_BCR] = { 0xb000 },
+ [GCC_USB3_PHY_BCR] = { 0xc000 },
+ [GCC_USB3PHY_PHY_BCR] = { 0xc004 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0xe000 },
};
@@ -1903,7 +1932,7 @@
{
return platform_driver_register(&gcc_sdxpoorwills_driver);
}
-core_initcall(gcc_sdxpoorwills_init);
+subsys_initcall(gcc_sdxpoorwills_init);
static void __exit gcc_sdxpoorwills_exit(void)
{
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
index dd02a8f..3f9fcd9 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
@@ -33,24 +33,52 @@
/* Register Offsets from PLL base address */
#define PLL_ANALOG_CONTROLS_ONE 0x000
#define PLL_ANALOG_CONTROLS_TWO 0x004
+#define PLL_INT_LOOP_SETTINGS 0x008
+#define PLL_INT_LOOP_SETTINGS_TWO 0x00c
#define PLL_ANALOG_CONTROLS_THREE 0x010
+#define PLL_ANALOG_CONTROLS_FOUR 0x014
+#define PLL_INT_LOOP_CONTROLS 0x018
#define PLL_DSM_DIVIDER 0x01c
#define PLL_FEEDBACK_DIVIDER 0x020
#define PLL_SYSTEM_MUXES 0x024
+#define PLL_FREQ_UPDATE_CONTROL_OVERRIDES 0x028
#define PLL_CMODE 0x02c
#define PLL_CALIBRATION_SETTINGS 0x030
+#define PLL_BAND_SEL_CAL_TIMER_LOW 0x034
+#define PLL_BAND_SEL_CAL_TIMER_HIGH 0x038
+#define PLL_BAND_SEL_CAL_SETTINGS 0x03c
+#define PLL_BAND_SEL_MIN 0x040
+#define PLL_BAND_SEL_MAX 0x044
+#define PLL_BAND_SEL_PFILT 0x048
+#define PLL_BAND_SEL_IFILT 0x04c
+#define PLL_BAND_SEL_CAL_SETTINGS_TWO 0x050
#define PLL_BAND_SEL_CAL_SETTINGS_THREE 0x054
+#define PLL_BAND_SEL_CAL_SETTINGS_FOUR 0x058
+#define PLL_BAND_SEL_ICODE_HIGH 0x05c
+#define PLL_BAND_SEL_ICODE_LOW 0x060
#define PLL_FREQ_DETECT_SETTINGS_ONE 0x064
#define PLL_PFILT 0x07c
#define PLL_IFILT 0x080
+#define PLL_GAIN 0x084
+#define PLL_ICODE_LOW 0x088
+#define PLL_ICODE_HIGH 0x08c
+#define PLL_LOCKDET 0x090
#define PLL_OUTDIV 0x094
+#define PLL_FASTLOCK_CONTROL 0x098
+#define PLL_PASS_OUT_OVERRIDE_ONE 0x09c
+#define PLL_PASS_OUT_OVERRIDE_TWO 0x0a0
#define PLL_CORE_OVERRIDE 0x0a4
#define PLL_CORE_INPUT_OVERRIDE 0x0a8
+#define PLL_RATE_CHANGE 0x0ac
+#define PLL_PLL_DIGITAL_TIMERS 0x0b0
#define PLL_PLL_DIGITAL_TIMERS_TWO 0x0b4
+#define PLL_DEC_FRAC_MUXES 0x0c8
#define PLL_DECIMAL_DIV_START_1 0x0cc
#define PLL_FRAC_DIV_START_LOW_1 0x0d0
#define PLL_FRAC_DIV_START_MID_1 0x0d4
#define PLL_FRAC_DIV_START_HIGH_1 0x0d8
+#define PLL_MASH_CONTROL 0x0ec
+#define PLL_SSC_MUX_CONTROL 0x108
#define PLL_SSC_STEPSIZE_LOW_1 0x10c
#define PLL_SSC_STEPSIZE_HIGH_1 0x110
#define PLL_SSC_DIV_PER_LOW_1 0x114
@@ -64,9 +92,16 @@
#define PLL_PLL_BAND_SET_RATE_1 0x154
#define PLL_PLL_INT_GAIN_IFILT_BAND_1 0x15c
#define PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 0x164
+#define PLL_FASTLOCK_EN_BAND 0x16c
+#define PLL_FREQ_TUNE_ACCUM_INIT_MUX 0x17c
#define PLL_PLL_LOCK_OVERRIDE 0x180
#define PLL_PLL_LOCK_DELAY 0x184
+#define PLL_PLL_LOCK_MIN_DELAY 0x188
#define PLL_CLOCK_INVERTERS 0x18c
+#define PLL_SPARE_AND_JPC_OVERRIDES 0x190
+#define PLL_BIAS_CONTROL_1 0x194
+#define PLL_BIAS_CONTROL_2 0x198
+#define PLL_ALOG_OBSV_BUS_CTRL_1 0x19c
#define PLL_COMMON_STATUS_ONE 0x1a0
/* Register Offsets from PHY base address */
@@ -249,7 +284,7 @@
if (rc)
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
else
- *val = (MDSS_PLL_REG_R(rsc->pll_base, reg) & 0x3);
+ *val = (MDSS_PLL_REG_R(rsc->phy_base, reg) & 0x3);
(void)mdss_pll_resource_enable(rsc, false);
return rc;
@@ -503,6 +538,49 @@
MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x3f);
}
+static void dsi_pll_init_val(struct mdss_pll_resources *rsc)
+{
+ void __iomem *pll_base = rsc->pll_base;
+
+ MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x10);
+ MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS, 0x3f);
+ MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS_TWO, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FOUR, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_CONTROLS, 0x80);
+ MDSS_PLL_REG_W(pll_base, PLL_FREQ_UPDATE_CONTROL_OVERRIDES, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_LOW, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_HIGH, 0x02);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS, 0x82);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MIN, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MAX, 0xff);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_PFILT, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_IFILT, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_TWO, 0x25);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_FOUR, 0x4f);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_HIGH, 0x0a);
+ MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_LOW, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_GAIN, 0x42);
+ MDSS_PLL_REG_W(pll_base, PLL_ICODE_LOW, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_ICODE_HIGH, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_LOCKDET, 0x30);
+ MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_CONTROL, 0x04);
+ MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_ONE, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_TWO, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_RATE_CHANGE, 0x01);
+ MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS, 0x08);
+ MDSS_PLL_REG_W(pll_base, PLL_DEC_FRAC_MUXES, 0x00);
+ MDSS_PLL_REG_W(pll_base, PLL_MASH_CONTROL, 0x03);
+ MDSS_PLL_REG_W(pll_base, PLL_SSC_MUX_CONTROL, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_EN_BAND, 0x03);
+ MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MUX, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_MIN_DELAY, 0x19);
+ MDSS_PLL_REG_W(pll_base, PLL_SPARE_AND_JPC_OVERRIDES, 0x0);
+ MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x40);
+ MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_2, 0x20);
+ MDSS_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_CTRL_1, 0x0);
+}
+
static void dsi_pll_commit(struct dsi_pll_10nm *pll,
struct mdss_pll_resources *rsc)
{
@@ -559,6 +637,8 @@
return rc;
}
+ dsi_pll_init_val(rsc);
+
dsi_pll_setup_config(pll, rsc);
dsi_pll_calc_dec_frac(pll, rsc);
@@ -741,12 +821,32 @@
pr_err("dsi pll resources not available\n");
return;
}
- pll->cached_cfg0 = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0);
- pll->cached_outdiv = MDSS_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE);
- pr_debug("cfg0=%d,cfg1=%d, outdiv=%d\n", pll->cached_cfg0,
- pll->cached_cfg1, pll->cached_outdiv);
- pll->vco_cached_rate = clk_hw_get_rate(hw);
+ /*
+ * During unprepare in continuous splash use case we want driver
+ * to pick all dividers instead of retaining bootloader configurations.
+ */
+ if (!pll->handoff_resources) {
+ pll->cached_cfg0 = MDSS_PLL_REG_R(pll->phy_base,
+ PHY_CMN_CLK_CFG0);
+ pll->cached_outdiv = MDSS_PLL_REG_R(pll->pll_base,
+ PLL_PLL_OUTDIV_RATE);
+ pr_debug("cfg0=%d,cfg1=%d, outdiv=%d\n", pll->cached_cfg0,
+ pll->cached_cfg1, pll->cached_outdiv);
+
+ pll->vco_cached_rate = clk_hw_get_rate(hw);
+ }
+
+ /*
+ * When continuous splash screen feature is enabled, we need to cache
+ * the mux configuration for the pixel_clk_src mux clock. The clock
+ * framework does not call back to re-configure the mux value if it is
+ * does not change.For such usecases, we need to ensure that the cached
+ * value is programmed prior to PLL being locked
+ */
+ if (pll->handoff_resources)
+ pll->cached_cfg1 = MDSS_PLL_REG_R(pll->phy_base,
+ PHY_CMN_CLK_CFG1);
dsi_pll_disable(vco);
mdss_pll_resource_enable(pll, false);
}
@@ -1026,8 +1126,8 @@
.reg_read = pll_reg_read,
};
-static struct regmap_bus pclk_mux_regmap_bus = {
- .reg_read = phy_reg_read,
+static struct regmap_bus pclk_src_mux_regmap_bus = {
+ .reg_read = pclk_mux_read_sel,
.reg_write = pclk_mux_write_sel,
};
@@ -1472,7 +1572,7 @@
pll_res, &dsi_pll_10nm_config);
dsi0pll_pclk_mux.clkr.regmap = rmap;
- rmap = devm_regmap_init(&pdev->dev, &pclk_mux_regmap_bus,
+ rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus,
pll_res, &dsi_pll_10nm_config);
dsi0pll_pclk_src_mux.clkr.regmap = rmap;
rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus,
@@ -1510,11 +1610,11 @@
pll_res, &dsi_pll_10nm_config);
dsi1pll_pclk_src.clkr.regmap = rmap;
- rmap = devm_regmap_init(&pdev->dev, &pclk_mux_regmap_bus,
+ rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus,
pll_res, &dsi_pll_10nm_config);
dsi1pll_pclk_mux.clkr.regmap = rmap;
- rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus,
+ rmap = devm_regmap_init(&pdev->dev, &pclk_src_mux_regmap_bus,
pll_res, &dsi_pll_10nm_config);
dsi1pll_pclk_src_mux.clkr.regmap = rmap;
rmap = devm_regmap_init(&pdev->dev, &mdss_mux_regmap_bus,
diff --git a/drivers/cpufreq/qcom-cpufreq.c b/drivers/cpufreq/qcom-cpufreq.c
index d310380..90fac32 100644
--- a/drivers/cpufreq/qcom-cpufreq.c
+++ b/drivers/cpufreq/qcom-cpufreq.c
@@ -410,7 +410,7 @@
if (!IS_ERR(ftbl)) {
for_each_possible_cpu(cpu)
per_cpu(freq_table, cpu) = ftbl;
- return 0;
+ goto out_register;
}
/*
@@ -450,6 +450,7 @@
per_cpu(freq_table, cpu) = ftbl;
}
+out_register:
ret = register_pm_notifier(&msm_cpufreq_pm_notifier);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
index 0ddb47f..f2c2985 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
@@ -83,6 +83,7 @@
dsi_ctrl_hw_14_reg_dump_to_buffer;
ctrl->ops.schedule_dma_cmd = NULL;
ctrl->ops.get_cont_splash_status = NULL;
+ ctrl->ops.kickoff_command_non_embedded_mode = NULL;
break;
case DSI_CTRL_VERSION_2_0:
ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
@@ -97,6 +98,7 @@
ctrl->ops.clamp_disable = NULL;
ctrl->ops.schedule_dma_cmd = NULL;
ctrl->ops.get_cont_splash_status = NULL;
+ ctrl->ops.kickoff_command_non_embedded_mode = NULL;
break;
case DSI_CTRL_VERSION_2_2:
ctrl->ops.phy_reset_config = dsi_ctrl_hw_22_phy_reset_config;
@@ -113,6 +115,8 @@
ctrl->ops.clamp_enable = NULL;
ctrl->ops.clamp_disable = NULL;
ctrl->ops.schedule_dma_cmd = dsi_ctrl_hw_22_schedule_dma_cmd;
+ ctrl->ops.kickoff_command_non_embedded_mode =
+ dsi_ctrl_hw_kickoff_non_embedded_mode;
break;
default:
break;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
index 735f61f..f7756dc 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
@@ -213,6 +213,9 @@
ssize_t dsi_ctrl_hw_20_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
char *buf,
u32 size);
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags);
/* Definitions specific to 2.2 DSI controller hardware */
bool dsi_ctrl_hw_22_get_cont_splash_status(struct dsi_ctrl_hw *ctrl);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 1f10e3c..609ae52 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -940,6 +940,62 @@
udelay(sleep_ms * 1000);
}
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl,
+ u32 cmd_len,
+ u32 *flags)
+{
+ /**
+ * Setup the mode of transmission
+ * override cmd fetch mode during secure session
+ */
+ if (dsi_ctrl->secure_mode) {
+ *flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
+ *flags |= DSI_CTRL_CMD_FIFO_STORE;
+ pr_debug("[%s] override to TPG during secure session\n",
+ dsi_ctrl->name);
+ return;
+ }
+
+ /* Check to see if cmd len plus header is greater than fifo size */
+ if ((cmd_len + 4) > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) {
+ *flags |= DSI_CTRL_CMD_NON_EMBEDDED_MODE;
+ pr_debug("[%s] override to non-embedded mode,cmd len =%d\n",
+ dsi_ctrl->name, cmd_len);
+ return;
+ }
+}
+
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl,
+ u32 cmd_len,
+ u32 *flags)
+{
+ int rc = 0;
+
+ if (*flags & DSI_CTRL_CMD_FIFO_STORE) {
+ /* if command size plus header is greater than fifo size */
+ if ((cmd_len + 4) > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE) {
+ pr_err("Cannot transfer Cmd in FIFO config\n");
+ return -ENOTSUPP;
+ }
+ if (!dsi_ctrl->hw.ops.kickoff_fifo_command) {
+ pr_err("Cannot transfer command,ops not defined\n");
+ return -ENOTSUPP;
+ }
+ }
+
+ if (*flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ if (*flags & DSI_CTRL_CMD_BROADCAST) {
+ pr_err("Non embedded not supported with broadcast\n");
+ return -ENOTSUPP;
+ }
+ if (!dsi_ctrl->hw.ops.kickoff_command_non_embedded_mode) {
+ pr_err(" Cannot transfer command,ops not defined\n");
+ return -ENOTSUPP;
+ }
+ }
+ return rc;
+}
+
static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
const struct mipi_dsi_msg *msg,
u32 flags)
@@ -955,12 +1011,34 @@
u8 *cmdbuf;
struct dsi_mode_info *timing;
- /* override cmd fetch mode during secure session */
- if (dsi_ctrl->secure_mode) {
- flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
- flags |= DSI_CTRL_CMD_FIFO_STORE;
- pr_debug("[%s] override to TPG during secure session\n",
- dsi_ctrl->name);
+ /* Select the tx mode to transfer the command */
+ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+
+ /* Validate the mode before sending the command */
+ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+ if (rc) {
+ pr_err(" Cmd tx validation failed, cannot transfer cmd\n");
+ rc = -ENOTSUPP;
+ goto error;
+ }
+
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
+ cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
+ true : false;
+ cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
+ true : false;
+ cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
+ true : false;
+ cmd_mem.datatype = msg->type;
+ cmd_mem.length = msg->tx_len;
+
+ dsi_ctrl->cmd_len = msg->tx_len;
+ memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len);
+ pr_debug(" non-embedded mode , size of command =%zd\n",
+ msg->tx_len);
+
+ goto kickoff;
}
rc = mipi_dsi_create_packet(&packet, msg);
@@ -969,16 +1047,6 @@
goto error;
}
- /* fail cmds more than the supported size in TPG mode */
- if ((flags & DSI_CTRL_CMD_FIFO_STORE) &&
- (msg->tx_len > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE)) {
- pr_err("[%s] TPG cmd size:%zd not supported, secure:%d\n",
- dsi_ctrl->name, msg->tx_len,
- dsi_ctrl->secure_mode);
- rc = -ENOTSUPP;
- goto error;
- }
-
rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
&packet,
&buffer,
@@ -993,6 +1061,7 @@
buffer[3] |= BIT(7);//set the last cmd bit in header.
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+ /* Embedded mode config is selected */
cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
true : false;
@@ -1026,6 +1095,7 @@
true : false;
}
+kickoff:
timing = &(dsi_ctrl->host_config.video_timing);
if (timing)
line_no += timing->v_back_porch + timing->v_sync_width +
@@ -1045,9 +1115,18 @@
if (flags & DSI_CTRL_CMD_DEFER_TRIGGER) {
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
- dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.
+ kickoff_command_non_embedded_mode(
+ &dsi_ctrl->hw,
&cmd_mem,
hw_flags);
+ } else {
+ dsi_ctrl->hw.ops.kickoff_command(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ }
} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
&cmd,
@@ -1065,9 +1144,18 @@
reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
- dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
- &cmd_mem,
- hw_flags);
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.
+ kickoff_command_non_embedded_mode(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ } else {
+ dsi_ctrl->hw.ops.kickoff_command(
+ &dsi_ctrl->hw,
+ &cmd_mem,
+ hw_flags);
+ }
} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
&cmd,
@@ -1106,6 +1194,16 @@
dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
BIT(DSI_FIFO_OVERFLOW), false);
dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw);
+
+ /*
+ * DSI 2.2 needs a soft reset whenever we send non-embedded
+ * mode command followed by embedded mode. Otherwise it will
+ * result in smmu write faults with DSI as client.
+ */
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+ dsi_ctrl->cmd_len = 0;
+ }
}
error:
if (buffer)
@@ -2682,6 +2780,11 @@
if (dsi_ctrl->hw.ops.mask_error_intr)
dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
BIT(DSI_FIFO_OVERFLOW), false);
+
+ if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+ dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+ dsi_ctrl->cmd_len = 0;
+ }
}
mutex_unlock(&dsi_ctrl->ctrl_lock);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f5b08a0..80b91ca 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -37,6 +37,7 @@
* and transfer it.
* @DSI_CTRL_CMD_LAST_COMMAND: Trigger the DMA cmd transfer if this is last
* command in the batch.
+ * @DSI_CTRL_CMD_NON_EMBEDDED_MODE:Trasfer cmd packets in non embedded mode.
*/
#define DSI_CTRL_CMD_READ 0x1
#define DSI_CTRL_CMD_BROADCAST 0x2
@@ -45,6 +46,12 @@
#define DSI_CTRL_CMD_FIFO_STORE 0x10
#define DSI_CTRL_CMD_FETCH_MEMORY 0x20
#define DSI_CTRL_CMD_LAST_COMMAND 0x40
+#define DSI_CTRL_CMD_NON_EMBEDDED_MODE 0x80
+
+/* DSI embedded mode fifo size
+ * If the command is greater than 256 bytes it is sent in non-embedded mode.
+ */
+#define DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES 256
/* max size supported for dsi cmd transfer using TPG */
#define DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE 64
@@ -680,4 +687,20 @@
*/
int dsi_ctrl_vid_engine_en(struct dsi_ctrl *dsi_ctrl, bool on);
+/**
+ * @dsi_ctrl: DSI controller handle.
+ * cmd_len: Length of command.
+ * flags: Config mode flags.
+ */
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+ u32 *flags);
+
+/**
+ * @dsi_ctrl: DSI controller handle.
+ * cmd_len: Length of command.
+ * flags: Config mode flags.
+ */
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+ u32 *flags);
+
#endif /* _DSI_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
index c77065c..567f289 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
@@ -296,6 +296,7 @@
* struct dsi_ctrl_cmd_dma_info - command buffer information
* @offset: IOMMU VA for command buffer address.
* @length: Length of the command buffer.
+ * @datatype: Datatype of cmd.
* @en_broadcast: Enable broadcast mode if set to true.
* @is_master: Is master in broadcast mode.
* @use_lpm: Use low power mode for command transmission.
@@ -303,6 +304,7 @@
struct dsi_ctrl_cmd_dma_info {
u32 offset;
u32 length;
+ u8 datatype;
bool en_broadcast;
bool is_master;
bool use_lpm;
@@ -497,6 +499,25 @@
u32 flags);
/**
+ * kickoff_command_non_embedded_mode() - cmd in non embedded mode
+ * @ctrl: Pointer to the controller host hardware.
+ * @cmd: Command information.
+ * @flags: Modifiers for command transmission.
+ *
+ * If command length is greater than DMA FIFO size of 256 bytes we use
+ * this non- embedded mode.
+ * The controller hardware is programmed with address and size of the
+ * command buffer. The transmission is kicked off if
+ * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
+ * set, caller should make a separate call to trigger_command_dma() to
+ * transmit the command.
+ */
+
+ void (*kickoff_command_non_embedded_mode)(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags);
+
+ /**
* kickoff_fifo_command() - transmits a command using FIFO in dsi
* hardware.
* @ctrl: Pointer to the controller host hardware.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
index 650c2e0..d94d6f7b 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
@@ -79,3 +79,48 @@
reg = DSI_R32(ctrl, DSI_SCRATCH_REGISTER_1);
return reg == 0x1 ? true : false;
}
+
+/*
+ * dsi_ctrl_hw_kickoff_non_embedded_mode()-Kickoff cmd in non-embedded mode
+ * @ctrl: - Pointer to the controller host hardware.
+ * @dsi_ctrl_cmd_dma_info: - command buffer information.
+ * @flags: - DSI CTRL Flags.
+ */
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+ struct dsi_ctrl_cmd_dma_info *cmd,
+ u32 flags)
+{
+ u32 reg = 0;
+
+ reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
+
+ reg &= ~BIT(31);/* disable broadcast */
+ reg &= ~BIT(30);
+
+ if (cmd->use_lpm)
+ reg |= BIT(26);
+ else
+ reg &= ~BIT(26);
+
+ /* Select non EMBEDDED_MODE, pick the packet header from register */
+ reg &= ~BIT(28);
+ reg |= BIT(24);/* long packet */
+ reg |= BIT(29);/* wc_sel = 1 */
+ reg |= (((cmd->datatype) & 0x03f) << 16);/* data type */
+ DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+
+ /* Enable WRITE_WATERMARK_DISABLE and READ_WATERMARK_DISABLE bits */
+ reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+ reg |= BIT(20);
+ reg |= BIT(16);
+ DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
+
+ DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
+ DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, ((cmd->length) & 0xFFFFFF));
+
+ /* wait for writes to complete before kick off */
+ wmb();
+
+ if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
+ DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index c2c8f57..c753c80 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -612,9 +612,17 @@
else
reg &= ~BIT(26);
- reg |= BIT(28);
+ reg |= BIT(28);/* Select embedded mode */
+ reg &= ~BIT(24);/* packet type */
+ reg &= ~BIT(29);/* WC_SEL to 0 */
DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+ reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+ reg &= ~BIT(20);/* Enable write watermark*/
+ reg &= ~BIT(16);/* Enable read watermark */
+
+
+ DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->length & 0xFFFFFF));
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 2c758a2..d92a71d 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -214,6 +214,135 @@
return rc;
}
+static void dsi_display_aspace_cb_locked(void *cb_data, bool is_detach)
+{
+ struct dsi_display *display;
+ struct dsi_display_ctrl *display_ctrl;
+ int rc, cnt;
+
+ if (!cb_data) {
+ pr_err("aspace cb called with invalid cb_data\n");
+ return;
+ }
+ display = (struct dsi_display *)cb_data;
+
+ /*
+ * acquire panel_lock to make sure no commands are in-progress
+ * while detaching the non-secure context banks
+ */
+ dsi_panel_acquire_panel_lock(display->panel);
+
+ if (is_detach) {
+ /* invalidate the stored iova */
+ display->cmd_buffer_iova = 0;
+
+ /* return the virtual address mapping */
+ msm_gem_put_vaddr_locked(display->tx_cmd_buf);
+ msm_gem_vunmap(display->tx_cmd_buf);
+
+ } else {
+ rc = msm_gem_get_iova_locked(display->tx_cmd_buf,
+ display->aspace, &(display->cmd_buffer_iova));
+ if (rc) {
+ pr_err("failed to get the iova rc %d\n", rc);
+ goto end;
+ }
+
+ display->vaddr =
+ (void *) msm_gem_get_vaddr_locked(display->tx_cmd_buf);
+
+ if (IS_ERR_OR_NULL(display->vaddr)) {
+ pr_err("failed to get va rc %d\n", rc);
+ goto end;
+ }
+ }
+
+ for (cnt = 0; cnt < display->ctrl_count; cnt++) {
+ display_ctrl = &display->ctrl[cnt];
+ display_ctrl->ctrl->cmd_buffer_size = display->cmd_buffer_size;
+ display_ctrl->ctrl->cmd_buffer_iova = display->cmd_buffer_iova;
+ display_ctrl->ctrl->vaddr = display->vaddr;
+ }
+
+end:
+ /* release panel_lock */
+ dsi_panel_release_panel_lock(display->panel);
+}
+
+/* Allocate memory for cmd dma tx buffer */
+static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display)
+{
+ int rc = 0, cnt = 0;
+ struct dsi_display_ctrl *display_ctrl;
+
+ mutex_lock(&display->drm_dev->struct_mutex);
+ display->tx_cmd_buf = msm_gem_new(display->drm_dev,
+ SZ_4K,
+ MSM_BO_UNCACHED);
+ mutex_unlock(&display->drm_dev->struct_mutex);
+
+ if ((display->tx_cmd_buf) == NULL) {
+ pr_err("Failed to allocate cmd tx buf memory\n");
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ display->cmd_buffer_size = SZ_4K;
+
+ display->aspace = msm_gem_smmu_address_space_get(
+ display->drm_dev, MSM_SMMU_DOMAIN_UNSECURE);
+ if (!display->aspace) {
+ pr_err("failed to get aspace\n");
+ rc = -EINVAL;
+ goto free_gem;
+ }
+ /* register to aspace */
+ rc = msm_gem_address_space_register_cb(display->aspace,
+ dsi_display_aspace_cb_locked, (void *)display);
+ if (rc) {
+ pr_err("failed to register callback %d", rc);
+ goto free_gem;
+ }
+
+ rc = msm_gem_get_iova(display->tx_cmd_buf, display->aspace,
+ &(display->cmd_buffer_iova));
+ if (rc) {
+ pr_err("failed to get the iova rc %d\n", rc);
+ goto free_aspace_cb;
+ }
+
+ display->vaddr =
+ (void *) msm_gem_get_vaddr(display->tx_cmd_buf);
+ if (IS_ERR_OR_NULL(display->vaddr)) {
+ pr_err("failed to get va rc %d\n", rc);
+ rc = -EINVAL;
+ goto put_iova;
+ }
+
+ for (cnt = 0; cnt < display->ctrl_count; cnt++) {
+ display_ctrl = &display->ctrl[cnt];
+ display_ctrl->ctrl->cmd_buffer_size = SZ_4K;
+ display_ctrl->ctrl->cmd_buffer_iova =
+ display->cmd_buffer_iova;
+ display_ctrl->ctrl->vaddr = display->vaddr;
+ display_ctrl->ctrl->tx_cmd_buf = display->tx_cmd_buf;
+ }
+
+ return rc;
+
+put_iova:
+ msm_gem_put_iova(display->tx_cmd_buf, display->aspace);
+free_aspace_cb:
+ msm_gem_address_space_unregister_cb(display->aspace,
+ dsi_display_aspace_cb_locked, display);
+free_gem:
+ mutex_lock(&display->drm_dev->struct_mutex);
+ msm_gem_free_object(display->tx_cmd_buf);
+ mutex_unlock(&display->drm_dev->struct_mutex);
+error:
+ return rc;
+}
+
static bool dsi_display_validate_reg_read(struct dsi_panel *panel)
{
int i, j = 0;
@@ -330,6 +459,14 @@
m_ctrl = &display->ctrl[display->cmd_master_idx];
+ if (display->tx_cmd_buf == NULL) {
+ rc = dsi_host_alloc_cmd_tx_buffer(display);
+ if (rc) {
+ pr_err("failed to allocate cmd tx buffer memory\n");
+ goto done;
+ }
+ }
+
rc = dsi_display_cmd_engine_enable(display);
if (rc) {
pr_err("cmd engine enable failed\n");
@@ -358,9 +495,9 @@
goto exit;
}
}
-
exit:
dsi_display_cmd_engine_disable(display);
+done:
return rc;
}
@@ -1943,62 +2080,6 @@
return rc;
}
-static void dsi_display_aspace_cb_locked(void *cb_data, bool is_detach)
-{
- struct dsi_display *display;
- struct dsi_display_ctrl *display_ctrl;
- int rc, cnt;
-
- if (!cb_data) {
- pr_err("aspace cb called with invalid cb_data\n");
- return;
- }
- display = (struct dsi_display *)cb_data;
-
- /*
- * acquire panel_lock to make sure no commands are in-progress
- * while detaching the non-secure context banks
- */
- dsi_panel_acquire_panel_lock(display->panel);
-
- if (is_detach) {
- /* invalidate the stored iova */
- display->cmd_buffer_iova = 0;
-
- /* return the virtual address mapping */
- msm_gem_put_vaddr_locked(display->tx_cmd_buf);
- msm_gem_vunmap(display->tx_cmd_buf);
-
- } else {
- rc = msm_gem_get_iova_locked(display->tx_cmd_buf,
- display->aspace, &(display->cmd_buffer_iova));
- if (rc) {
- pr_err("failed to get the iova rc %d\n", rc);
- goto end;
- }
-
- display->vaddr =
- (void *) msm_gem_get_vaddr_locked(display->tx_cmd_buf);
-
- if (IS_ERR_OR_NULL(display->vaddr)) {
- pr_err("failed to get va rc %d\n", rc);
- goto end;
- }
- }
-
- for (cnt = 0; cnt < display->ctrl_count; cnt++) {
- display_ctrl = &display->ctrl[cnt];
- display_ctrl->ctrl->cmd_buffer_size = display->cmd_buffer_size;
- display_ctrl->ctrl->cmd_buffer_iova = display->cmd_buffer_iova;
- display_ctrl->ctrl->vaddr = display->vaddr;
- display_ctrl->ctrl->secure_mode = is_detach ? true : false;
- }
-
-end:
- /* release panel_lock */
- dsi_panel_release_panel_lock(display->panel);
-}
-
static int dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *dsi)
{
@@ -2015,8 +2096,7 @@
const struct mipi_dsi_msg *msg)
{
struct dsi_display *display = to_dsi_display(host);
- struct dsi_display_ctrl *display_ctrl;
- int rc = 0, cnt = 0;
+ int rc = 0;
if (!host || !msg) {
pr_err("Invalid params\n");
@@ -2046,58 +2126,11 @@
}
if (display->tx_cmd_buf == NULL) {
- mutex_lock(&display->drm_dev->struct_mutex);
- display->tx_cmd_buf = msm_gem_new(display->drm_dev,
- SZ_4K,
- MSM_BO_UNCACHED);
- mutex_unlock(&display->drm_dev->struct_mutex);
-
- display->cmd_buffer_size = SZ_4K;
-
- if ((display->tx_cmd_buf) == NULL) {
- pr_err("value of display->tx_cmd_buf is NULL");
+ rc = dsi_host_alloc_cmd_tx_buffer(display);
+ if (rc) {
+ pr_err("failed to allocate cmd tx buffer memory\n");
goto error_disable_cmd_engine;
}
-
- display->aspace = msm_gem_smmu_address_space_get(
- display->drm_dev, MSM_SMMU_DOMAIN_UNSECURE);
- if (!display->aspace) {
- pr_err("failed to get aspace\n");
- rc = -EINVAL;
- goto free_gem;
- }
-
- /* register to aspace */
- rc = msm_gem_address_space_register_cb(display->aspace,
- dsi_display_aspace_cb_locked, (void *)display);
- if (rc) {
- pr_err("failed to register callback %d", rc);
- goto free_gem;
- }
-
- rc = msm_gem_get_iova(display->tx_cmd_buf, display->aspace,
- &(display->cmd_buffer_iova));
- if (rc) {
- pr_err("failed to get the iova rc %d\n", rc);
- goto free_aspace_cb;
- }
-
- display->vaddr =
- (void *) msm_gem_get_vaddr(display->tx_cmd_buf);
-
- if (IS_ERR_OR_NULL(display->vaddr)) {
- pr_err("failed to get va rc %d\n", rc);
- rc = -EINVAL;
- goto put_iova;
- }
-
- for (cnt = 0; cnt < display->ctrl_count; cnt++) {
- display_ctrl = &display->ctrl[cnt];
- display_ctrl->ctrl->cmd_buffer_size = SZ_4K;
- display_ctrl->ctrl->cmd_buffer_iova =
- display->cmd_buffer_iova;
- display_ctrl->ctrl->vaddr = display->vaddr;
- }
}
if (display->ctrl_count > 1 && !(msg->flags & MIPI_DSI_MSG_UNICAST)) {
@@ -2129,16 +2162,6 @@
pr_err("[%s] failed to disable all DSI clocks, rc=%d\n",
display->name, rc);
}
- return rc;
-put_iova:
- msm_gem_put_iova(display->tx_cmd_buf, display->aspace);
-free_aspace_cb:
- msm_gem_address_space_unregister_cb(display->aspace,
- dsi_display_aspace_cb_locked, display);
-free_gem:
- mutex_lock(&display->drm_dev->struct_mutex);
- msm_gem_free_object(display->tx_cmd_buf);
- mutex_unlock(&display->drm_dev->struct_mutex);
error:
return rc;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 133b4d5..7671496 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -506,7 +506,8 @@
goto error;
}
if (cmds->post_wait_ms)
- msleep(cmds->post_wait_ms);
+ usleep_range(cmds->post_wait_ms*1000,
+ ((cmds->post_wait_ms*1000)+10));
cmds++;
}
error:
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_pwr.c b/drivers/gpu/drm/msm/dsi-staging/dsi_pwr.c
index e2219aa..5635346 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_pwr.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_pwr.c
@@ -341,6 +341,11 @@
{
int rc = 0;
+ if (!regs->vregs) {
+ pr_err("Invalid params\n");
+ return -EINVAL;
+ }
+
if (enable) {
if (regs->refcount == 0) {
rc = dsi_pwr_enable_vregs(regs, true);
@@ -350,7 +355,8 @@
regs->refcount++;
} else {
if (regs->refcount == 0) {
- pr_err("Unbalanced regulator off\n");
+ pr_err("Unbalanced regulator off:%s\n",
+ regs->vregs->vreg_name);
} else {
regs->refcount--;
if (regs->refcount == 0) {
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index f8c3df5..a015379 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -104,12 +104,13 @@
msm_obj->pages = p;
- /* For non-cached buffers, ensure the new pages are clean
- * because display controller, GPU, etc. are not coherent:
+ /*
+ * Make sure to flush the CPU cache for newly allocated memory
+ * so we don't get ourselves into trouble with a dirty cache
*/
if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
- dma_map_sg(dev->dev, msm_obj->sgt->sgl,
- msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+ dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
+ msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
}
return msm_obj->pages;
@@ -120,12 +121,6 @@
struct msm_gem_object *msm_obj = to_msm_bo(obj);
if (msm_obj->pages) {
- /* For non-cached buffers, ensure the new pages are clean
- * because display controller, GPU, etc. are not coherent:
- */
- if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
- dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
- msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
sg_free_table(msm_obj->sgt);
kfree(msm_obj->sgt);
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 0baba62..e2d937b 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -490,12 +490,10 @@
return rc;
}
-static int _sde_connector_update_bl_scale(struct sde_connector *c_conn, int idx)
+static int _sde_connector_update_bl_scale(struct sde_connector *c_conn)
{
- struct drm_connector conn;
struct dsi_display *dsi_display;
struct dsi_backlight_config *bl_config;
- uint64_t value;
int rc = 0;
if (!c_conn) {
@@ -503,7 +501,6 @@
return -EINVAL;
}
- conn = c_conn->base;
dsi_display = c_conn->display;
if (!dsi_display || !dsi_display->panel) {
SDE_ERROR("Invalid params(s) dsi_display %pK, panel %pK\n",
@@ -513,22 +510,16 @@
}
bl_config = &dsi_display->panel->bl_config;
- value = sde_connector_get_property(conn.state, idx);
- if (idx == CONNECTOR_PROP_BL_SCALE) {
- if (value > MAX_BL_SCALE_LEVEL)
- bl_config->bl_scale = MAX_BL_SCALE_LEVEL;
- else
- bl_config->bl_scale = (u32)value;
- } else if (idx == CONNECTOR_PROP_AD_BL_SCALE) {
- if (value > MAX_AD_BL_SCALE_LEVEL)
- bl_config->bl_scale_ad = MAX_AD_BL_SCALE_LEVEL;
- else
- bl_config->bl_scale_ad = (u32)value;
- } else {
- SDE_DEBUG("invalid idx %d\n", idx);
- return 0;
- }
+ if (c_conn->bl_scale > MAX_BL_SCALE_LEVEL)
+ bl_config->bl_scale = MAX_BL_SCALE_LEVEL;
+ else
+ bl_config->bl_scale = c_conn->bl_scale;
+
+ if (c_conn->bl_scale_ad > MAX_AD_BL_SCALE_LEVEL)
+ bl_config->bl_scale_ad = MAX_AD_BL_SCALE_LEVEL;
+ else
+ bl_config->bl_scale_ad = c_conn->bl_scale_ad;
SDE_DEBUG("bl_scale = %u, bl_scale_ad = %u, bl_level = %u\n",
bl_config->bl_scale, bl_config->bl_scale_ad,
@@ -570,7 +561,7 @@
break;
case CONNECTOR_PROP_BL_SCALE:
case CONNECTOR_PROP_AD_BL_SCALE:
- _sde_connector_update_bl_scale(c_conn, idx);
+ _sde_connector_update_bl_scale(c_conn);
break;
default:
/* nothing to do for most properties */
@@ -578,6 +569,12 @@
}
}
+ /* Special handling for postproc properties */
+ if (c_conn->bl_scale_dirty) {
+ _sde_connector_update_bl_scale(c_conn);
+ c_conn->bl_scale_dirty = false;
+ }
+
if (!c_conn->ops.pre_kickoff)
return 0;
@@ -1041,6 +1038,19 @@
if (rc)
SDE_ERROR_CONN(c_conn, "invalid roi_v1, rc: %d\n", rc);
break;
+ /* CONNECTOR_PROP_BL_SCALE and CONNECTOR_PROP_AD_BL_SCALE are
+ * color-processing properties. These two properties require
+ * special handling since they don't quite fit the current standard
+ * atomic set property framework.
+ */
+ case CONNECTOR_PROP_BL_SCALE:
+ c_conn->bl_scale = val;
+ c_conn->bl_scale_dirty = true;
+ break;
+ case CONNECTOR_PROP_AD_BL_SCALE:
+ c_conn->bl_scale_ad = val;
+ c_conn->bl_scale_dirty = true;
+ break;
default:
break;
}
@@ -1913,6 +1923,10 @@
0x0, 0, MAX_AD_BL_SCALE_LEVEL, MAX_AD_BL_SCALE_LEVEL,
CONNECTOR_PROP_AD_BL_SCALE);
+ c_conn->bl_scale_dirty = false;
+ c_conn->bl_scale = MAX_BL_SCALE_LEVEL;
+ c_conn->bl_scale_ad = MAX_AD_BL_SCALE_LEVEL;
+
/* enum/bitmask properties */
msm_property_install_enum(&c_conn->property_info, "topology_name",
DRM_MODE_PROP_IMMUTABLE, 0, e_topology_name,
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index f6dee6b..b92c342 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -287,6 +287,9 @@
* @bl_device: backlight device node
* @status_work: work object to perform status checks
* @force_panel_dead: variable to trigger forced ESD recovery
+ * @bl_scale_dirty: Flag to indicate PP BL scale value(s) is changed
+ * @bl_scale: BL scale value for ABA feature
+ * @bl_scale_ad: BL scale value for AD feature
*/
struct sde_connector {
struct drm_connector base;
@@ -323,6 +326,10 @@
struct backlight_device *bl_device;
struct delayed_work status_work;
u32 force_panel_dead;
+
+ bool bl_scale_dirty;
+ u32 bl_scale;
+ u32 bl_scale_ad;
};
/**
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c
index 6b36745..3879d4d 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c
@@ -170,6 +170,15 @@
}
SDE_EVT32(crtc->base.id, perf->core_clk_rate);
+ trace_sde_perf_calc_crtc(crtc->base.id,
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ perf->core_clk_rate);
+
SDE_DEBUG(
"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu llcc_ib=%llu llcc_ab=%llu mem_ib=%llu mem_ab=%llu\n",
crtc->base.id, perf->core_clk_rate,
@@ -552,19 +561,32 @@
* 2. new bandwidth vote - "ab or ib vote" is lower
* than current vote at end of commit or stop.
*/
- if ((params_changed && ((new->bw_ctl[i] >
- old->bw_ctl[i]) ||
- (new->max_per_pipe_ib[i] >
- old->max_per_pipe_ib[i]))) ||
- (!params_changed && ((new->bw_ctl[i] <
- old->bw_ctl[i]) ||
- (new->max_per_pipe_ib[i] <
- old->max_per_pipe_ib[i])))) {
+
+ if ((params_changed &&
+ (new->bw_ctl[i] > old->bw_ctl[i])) ||
+ (!params_changed &&
+ (new->bw_ctl[i] < old->bw_ctl[i]))) {
+
SDE_DEBUG(
"crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
crtc->base.id, params_changed,
new->bw_ctl[i], old->bw_ctl[i]);
old->bw_ctl[i] = new->bw_ctl[i];
+ update_bus |= BIT(i);
+ }
+
+ if ((params_changed &&
+ (new->max_per_pipe_ib[i] >
+ old->max_per_pipe_ib[i])) ||
+ (!params_changed &&
+ (new->max_per_pipe_ib[i] <
+ old->max_per_pipe_ib[i]))) {
+
+ SDE_DEBUG(
+ "crtc=%d p=%d new_ib=%llu,old_ib=%llu\n",
+ crtc->base.id, params_changed,
+ new->max_per_pipe_ib[i],
+ old->max_per_pipe_ib[i]);
old->max_per_pipe_ib[i] =
new->max_per_pipe_ib[i];
update_bus |= BIT(i);
@@ -608,11 +630,14 @@
update_clk = 1;
}
trace_sde_perf_crtc_update(crtc->base.id,
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
- new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
- new->core_clk_rate, stop_req,
- update_bus, update_clk);
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+ new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+ new->core_clk_rate, stop_req,
+ update_bus, update_clk, params_changed);
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
if (update_bus & BIT(i))
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 4d09642..b6888df 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -199,6 +199,7 @@
* @rsc_config: rsc configuration for display vtotal, fps, etc.
* @cur_conn_roi: current connector roi
* @prv_conn_roi: previous connector roi to optimize if unchanged
+ * @crtc pointer to drm_crtc
*/
struct sde_encoder_virt {
struct drm_encoder base;
@@ -243,6 +244,7 @@
struct sde_rsc_cmd_config rsc_config;
struct sde_rect cur_conn_roi;
struct sde_rect prv_conn_roi;
+ struct drm_crtc *crtc;
};
#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
@@ -1315,14 +1317,23 @@
struct drm_display_mode *adj_mode;
struct sde_rect roi;
- if (!drm_enc || !drm_enc->crtc || !drm_enc->crtc->state)
+ if (!drm_enc) {
+ SDE_ERROR("invalid encoder parameter\n");
return -EINVAL;
+ }
+
sde_enc = to_sde_encoder_virt(drm_enc);
-
- if (!sde_enc->cur_master)
+ if (!sde_enc->crtc || !sde_enc->crtc->state) {
+ SDE_ERROR("invalid crtc parameter\n");
return -EINVAL;
+ }
- adj_mode = &sde_enc->base.crtc->state->adjusted_mode;
+ if (!sde_enc->cur_master) {
+ SDE_ERROR("invalid cur_master parameter\n");
+ return -EINVAL;
+ }
+
+ adj_mode = &sde_enc->cur_master->cached_mode;
drm_conn = sde_enc->cur_master->connector;
_sde_encoder_get_connector_roi(sde_enc, &roi);
@@ -1367,8 +1378,8 @@
sde_enc->prv_conn_roi.y,
sde_enc->prv_conn_roi.w,
sde_enc->prv_conn_roi.h,
- sde_enc->base.crtc->state->adjusted_mode.hdisplay,
- sde_enc->base.crtc->state->adjusted_mode.vdisplay);
+ sde_enc->cur_master->cached_mode.hdisplay,
+ sde_enc->cur_master->cached_mode.vdisplay);
if (sde_kms_rect_is_equal(&sde_enc->cur_conn_roi,
&sde_enc->prv_conn_roi))
@@ -1501,14 +1512,20 @@
struct drm_crtc *primary_crtc;
int pipe = -1;
int rc = 0;
+ int wait_refcount;
- if (!drm_enc || !drm_enc->crtc || !drm_enc->dev) {
- SDE_ERROR("invalid arguments\n");
+ if (!drm_enc || !drm_enc->dev) {
+ SDE_ERROR("invalid encoder arguments\n");
return -EINVAL;
}
sde_enc = to_sde_encoder_virt(drm_enc);
- crtc = drm_enc->crtc;
+ crtc = sde_enc->crtc;
+
+ if (!sde_enc->crtc) {
+ SDE_ERROR("invalid crtc parameter\n");
+ return -EINVAL;
+ }
disp_info = &sde_enc->disp_info;
rsc_config = &sde_enc->rsc_config;
@@ -1583,6 +1600,12 @@
return ret;
}
+ if (wait_vblank_crtc_id)
+ wait_refcount =
+ sde_rsc_client_get_vsync_refcount(sde_enc->rsc_client);
+ SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+ SDE_EVTLOG_FUNC_ENTRY);
+
if (crtc->base.id != wait_vblank_crtc_id) {
primary_crtc = drm_crtc_find(drm_enc->dev, wait_vblank_crtc_id);
if (!primary_crtc) {
@@ -1620,6 +1643,11 @@
SDE_EVT32(DRMID(drm_enc), wait_vblank_crtc_id, wait_count,
SDE_EVTLOG_ERROR);
+ if (wait_refcount)
+ sde_rsc_client_reset_vsync_refcount(sde_enc->rsc_client);
+ SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+ SDE_EVTLOG_FUNC_EXIT);
+
return ret;
}
@@ -1697,10 +1725,21 @@
struct drm_encoder *drm_enc, bool enable)
{
struct sde_encoder_rsc_config rsc_cfg = { 0 };
+ struct sde_encoder_virt *sde_enc;
+
+ if (!drm_enc) {
+ SDE_ERROR("invalid encoder argument\n");
+ return;
+ }
+ sde_enc = to_sde_encoder_virt(drm_enc);
+ if (!sde_enc->crtc) {
+ SDE_ERROR("invalid crtc\n");
+ return;
+ }
if (enable) {
rsc_cfg.inline_rotate_prefill =
- sde_crtc_get_inline_prefill(drm_enc->crtc);
+ sde_crtc_get_inline_prefill(sde_enc->crtc);
_sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
} else {
@@ -1788,9 +1827,9 @@
int ret;
bool is_vid_mode = false;
- if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
- !drm_enc->crtc) {
- SDE_ERROR("invalid parameters\n");
+ if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
+ SDE_ERROR("invalid encoder parameters, sw_event:%u\n",
+ sw_event);
return -EINVAL;
}
sde_enc = to_sde_encoder_virt(drm_enc);
@@ -1798,12 +1837,6 @@
is_vid_mode = sde_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;
- if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
- SDE_ERROR("invalid crtc index\n");
- return -EINVAL;
- }
- disp_thread = &priv->disp_thread[drm_enc->crtc->index];
-
/*
* when idle_pc is not supported, process only KICKOFF, STOP and MODESET
* events and return early for other events (ie wb display).
@@ -1877,6 +1910,18 @@
break;
case SDE_ENC_RC_EVENT_FRAME_DONE:
+ if (!sde_enc->crtc) {
+ SDE_ERROR("invalid crtc, sw_event:%u\n", sw_event);
+ return -EINVAL;
+ }
+
+ if (sde_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
+ SDE_ERROR("invalid crtc index :%u\n",
+ sde_enc->crtc->index);
+ return -EINVAL;
+ }
+ disp_thread = &priv->disp_thread[sde_enc->crtc->index];
+
/*
* mutex lock is not used as this event happens at interrupt
* context. And locking is not required as, the other events
@@ -1895,7 +1940,7 @@
* schedule off work item only when there are no
* frames pending
*/
- if (sde_crtc_frame_pending(drm_enc->crtc) > 1) {
+ if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
SDE_DEBUG_ENC(sde_enc, "skip schedule work");
SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
SDE_EVTLOG_FUNC_CASE2);
@@ -2380,6 +2425,16 @@
return;
}
+ /*
+ * cache the crtc in sde_enc on enable for duration of use case
+ * for correctly servicing asynchronous irq events and timers
+ */
+ if (!drm_enc->crtc) {
+ SDE_ERROR("invalid crtc\n");
+ return;
+ }
+ sde_enc->crtc = drm_enc->crtc;
+
ret = _sde_encoder_get_mode_info(drm_enc, &mode_info);
if (ret) {
SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
@@ -2539,6 +2594,11 @@
}
sde_enc->cur_master = NULL;
+ /*
+ * clear the cached crtc in sde_enc on use case finish, after all the
+ * outstanding events and timers have been completed
+ */
+ sde_enc->crtc = NULL;
SDE_DEBUG_ENC(sde_enc, "encoder disabled\n");
@@ -3264,12 +3324,7 @@
ktime_t cur_time;
sde_enc = to_sde_encoder_virt(drm_enc);
-
- if (!drm_enc->crtc || !drm_enc->crtc->state) {
- SDE_ERROR("crtc/crtc state object is NULL\n");
- return -EINVAL;
- }
- mode = &drm_enc->crtc->state->adjusted_mode;
+ mode = &sde_enc->cur_master->cached_mode;
line_time = _sde_encoder_calculate_linetime(sde_enc, mode);
if (!line_time)
@@ -3307,23 +3362,27 @@
struct msm_drm_private *priv;
struct msm_drm_thread *event_thread;
- if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
- !drm_enc->crtc) {
- SDE_ERROR("invalid parameters\n");
+ if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
+ SDE_ERROR("invalid encoder parameters\n");
return;
}
sde_enc = to_sde_encoder_virt(drm_enc);
priv = drm_enc->dev->dev_private;
-
- if (drm_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
- SDE_ERROR("invalid crtc index\n");
+ if (!sde_enc->crtc) {
+ SDE_ERROR("invalid crtc");
return;
}
- event_thread = &priv->event_thread[drm_enc->crtc->index];
+
+ if (sde_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
+ SDE_ERROR("invalid crtc index:%u\n",
+ sde_enc->crtc->index);
+ return;
+ }
+ event_thread = &priv->event_thread[sde_enc->crtc->index];
if (!event_thread) {
SDE_ERROR("event_thread not found for crtc:%d\n",
- drm_enc->crtc->index);
+ sde_enc->crtc->index);
return;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index cfe2126..a877eb5 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -379,6 +379,7 @@
* @end_time: End time of writeback latest request
* @bo_disable: Buffer object(s) to use during the disabling state
* @fb_disable: Frame buffer to use during the disabling state
+ * @crtc Pointer to drm_crtc
*/
struct sde_encoder_phys_wb {
struct sde_encoder_phys base;
@@ -403,6 +404,7 @@
ktime_t end_time;
struct drm_gem_object *bo_disable[SDE_MAX_PLANES];
struct drm_framebuffer *fb_disable;
+ struct drm_crtc *crtc;
};
/**
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
index 42cf015..9a90075 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
@@ -124,7 +124,12 @@
}
wb_enc = to_sde_encoder_phys_wb(phys_enc);
- crtc = phys_enc->parent->crtc;
+ if (!wb_enc->crtc) {
+ SDE_ERROR("invalid crtc");
+ return;
+ }
+
+ crtc = wb_enc->crtc;
if (!wb_enc->hw_wb || !wb_enc->hw_wb->caps) {
SDE_ERROR("invalid writeback hardware\n");
@@ -1141,6 +1146,12 @@
wb_enc->wb_dev = sde_wb_connector_get_wb(connector);
phys_enc->enable_state = SDE_ENC_ENABLED;
+
+ /*
+ * cache the crtc in wb_enc on enable for duration of use case
+ * for correctly servicing asynchronous irq events and timers
+ */
+ wb_enc->crtc = phys_enc->parent->crtc;
}
/**
@@ -1186,6 +1197,7 @@
sde_encoder_phys_wb_wait_for_commit_done(phys_enc);
exit:
phys_enc->enable_state = SDE_ENC_DISABLED;
+ wb_enc->crtc = NULL;
}
/**
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
index 426ecf1..4437987 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
@@ -610,6 +610,35 @@
SDE_REG_WRITE(c, CTL_TOP, intf_cfg);
}
+static inline u32 sde_hw_ctl_read_ctl_top(struct sde_hw_ctl *ctx)
+{
+ struct sde_hw_blk_reg_map *c;
+ u32 ctl_top;
+
+ if (!ctx) {
+ pr_err("Invalid input argument\n");
+ return 0;
+ }
+ c = &ctx->hw;
+ ctl_top = SDE_REG_READ(c, CTL_TOP);
+ return ctl_top;
+}
+
+static inline u32 sde_hw_ctl_read_ctl_layers(struct sde_hw_ctl *ctx, int index)
+{
+ struct sde_hw_blk_reg_map *c;
+ u32 ctl_top;
+
+ if (!ctx) {
+ pr_err("Invalid input argument\n");
+ return 0;
+ }
+ c = &ctx->hw;
+ ctl_top = SDE_REG_READ(c, CTL_LAYER(index));
+ pr_debug("Ctl_layer value = 0x%x\n", ctl_top);
+ return ctl_top;
+}
+
static void sde_hw_ctl_setup_sbuf_cfg(struct sde_hw_ctl *ctx,
struct sde_ctl_sbuf_cfg *cfg)
{
@@ -640,6 +669,8 @@
ops->get_flush_register = sde_hw_ctl_get_flush_register;
ops->trigger_start = sde_hw_ctl_trigger_start;
ops->trigger_pending = sde_hw_ctl_trigger_pending;
+ ops->read_ctl_top = sde_hw_ctl_read_ctl_top;
+ ops->read_ctl_layers = sde_hw_ctl_read_ctl_layers;
ops->setup_intf_cfg = sde_hw_ctl_intf_cfg;
ops->reset = sde_hw_ctl_reset_control;
ops->hard_reset = sde_hw_ctl_hard_reset;
@@ -663,27 +694,6 @@
}
};
-#define CTL_BASE_OFFSET 0x2000
-#define CTL_TOP_OFFSET(index) (CTL_BASE_OFFSET + (0x200 * (index)) + CTL_TOP)
-
-void sde_get_ctl_top_for_cont_splash(void __iomem *mmio,
- struct ctl_top *top, int index)
-{
- if (!mmio || !top) {
- SDE_ERROR("invalid input parameters\n");
- return;
- }
-
- top->value = readl_relaxed(mmio + CTL_TOP_OFFSET(index));
- top->intf_sel = (top->value >> 4) & 0xf;
- top->pp_sel = (top->value >> 8) & 0x7;
- top->dspp_sel = (top->value >> 11) & 0x3;
- top->mode_sel = (top->value >> 17) & 0x1;
-
- SDE_DEBUG("ctl[%d]_top->0x%x,pp_sel=0x%x,dspp_sel=0x%x,intf_sel=0x%x\n",
- index, top->value, top->pp_sel, top->dspp_sel, top->intf_sel);
-}
-
static struct sde_hw_blk_ops sde_hw_ops = {
.start = NULL,
.stop = NULL,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
index f8594da..a9bd104 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.h
@@ -201,6 +201,23 @@
enum sde_rot blk);
/**
+ * read CTL_TOP register value and return
+ * the data.
+ * @ctx : ctl path ctx pointer
+ * @return : CTL top register value
+ */
+ u32 (*read_ctl_top)(struct sde_hw_ctl *ctx);
+
+ /**
+ * read CTL layers register value and return
+ * the data.
+ * @ctx : ctl path ctx pointer
+ * @index : layer index for this ctl path
+ * @return : CTL layers register value
+ */
+ u32 (*read_ctl_layers)(struct sde_hw_ctl *ctx, int index);
+
+ /**
* Set all blend stages to disabled
* @ctx : ctl path ctx pointer
*/
@@ -269,15 +286,6 @@
void __iomem *mmio);
/**
- * sde_get_ctl_top_for_cont_splash - retrieve the current LM blocks
- * @mmio: mapped register io address of MDP
- * @top: pointer to the current "ctl_top" structure thats needs update
- * @index: ctl_top index
- */
-void sde_get_ctl_top_for_cont_splash(void __iomem *mmio,
- struct ctl_top *top, int index);
-
-/**
* sde_hw_ctl - convert base object sde_hw_base to container
* @hw: Pointer to base hardware block
* return: Pointer to hardware block container
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.c b/drivers/gpu/drm/msm/sde/sde_hw_lm.c
index 134db51..4e677c2 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_lm.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.c
@@ -278,43 +278,6 @@
}
};
-#define CTL_BASE_OFFSET 0x2000
-#define CTL_TOP_LM_OFFSET(index, lm) \
- (CTL_BASE_OFFSET + (0x200 * index) + (lm * 0x4))
-
-int sde_get_ctl_lm_for_cont_splash(void __iomem *mmio, int max_lm_cnt,
- u8 lm_cnt, u8 *lm_ids, struct ctl_top *top, int index)
-{
- int j;
- struct sde_splash_lm_hw *lm;
-
- if (!mmio || !top || !lm_ids) {
- SDE_ERROR("invalid input parameters\n");
- return 0;
- }
-
- lm = top->lm;
- for (j = 0; j < max_lm_cnt; j++) {
- lm[top->ctl_lm_cnt].lm_reg_value = readl_relaxed(mmio
- + CTL_TOP_LM_OFFSET(index, j));
- SDE_DEBUG("ctl[%d]_top --> lm[%d]=0x%x, j=%d\n",
- index, top->ctl_lm_cnt,
- lm[top->ctl_lm_cnt].lm_reg_value, j);
- SDE_DEBUG("lm_cnt = %d\n", lm_cnt);
- if (lm[top->ctl_lm_cnt].lm_reg_value) {
- lm[top->ctl_lm_cnt].ctl_id = index;
- lm_ids[lm_cnt++] = j + LM_0;
- lm[top->ctl_lm_cnt].lm_id = j + LM_0;
- SDE_DEBUG("ctl_id=%d, lm[%d].lm_id = %d\n",
- lm[top->ctl_lm_cnt].ctl_id,
- top->ctl_lm_cnt,
- lm[top->ctl_lm_cnt].lm_id);
- top->ctl_lm_cnt++;
- }
- }
- return top->ctl_lm_cnt;
-}
-
static struct sde_hw_blk_ops sde_hw_ops = {
.start = NULL,
.stop = NULL,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_lm.h b/drivers/gpu/drm/msm/sde/sde_hw_lm.h
index a2307ec..8a146bd 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_lm.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_lm.h
@@ -117,19 +117,6 @@
}
/**
- * sde_get_ctl_lm_for_cont_splash - retrieve the current LM blocks
- * @mmio: mapped register io address of MDP
- * @max_lm_cnt: number of LM blocks supported in the hw
- * @lm_cnt: number of LM blocks already active
- * @lm_ids: pointer to store the active LM block IDs
- * @top: pointer to the current "ctl_top" structure
- * @index: ctl_top index
- * return: number of active LM blocks for this CTL block
- */
-int sde_get_ctl_lm_for_cont_splash(void __iomem *mmio, int max_lm_cnt,
- u8 lm_cnt, u8 *lm_ids, struct ctl_top *top, int index);
-
-/**
* sde_hw_lm_init(): Initializes the mixer hw driver object.
* should be called once before accessing every mixer.
* @idx: mixer index for which driver object is required
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
index 3125ebf..7977294 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
@@ -581,6 +581,7 @@
* @ctl_top_cnt:stores the active number of MDSS "top" blks of the current mode
* @lm_cnt: stores the active number of MDSS "LM" blks for the current mode
* @dsc_cnt: stores the active number of MDSS "dsc" blks for the current mode
+ * @cont_splash_en: Stores the cont_splash status (enabled/disbled)
*/
struct sde_splash_data {
bool smmu_handoff_pending;
@@ -593,6 +594,7 @@
u8 ctl_top_cnt;
u8 lm_cnt;
u8 dsc_cnt;
+ bool cont_splash_en;
};
#endif /* _SDE_HW_MDSS_H */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
index 050e21b..2a03785 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.c
@@ -162,6 +162,17 @@
SDE_REG_WRITE(c, PP_DSC_MODE, 1);
}
+static u32 sde_hw_pp_get_dsc_status(struct sde_hw_pingpong *pp)
+{
+ struct sde_hw_blk_reg_map *c;
+
+ if (!pp)
+ return 0;
+
+ c = &pp->hw;
+ return SDE_REG_READ(c, PP_DSC_MODE);
+}
+
static void sde_hw_pp_dsc_disable(struct sde_hw_pingpong *pp)
{
struct sde_hw_blk_reg_map *c;
@@ -342,6 +353,7 @@
ops->setup_dsc = sde_hw_pp_setup_dsc;
ops->enable_dsc = sde_hw_pp_dsc_enable;
ops->disable_dsc = sde_hw_pp_dsc_disable;
+ ops->get_dsc_status = sde_hw_pp_get_dsc_status;
ops->get_autorefresh = sde_hw_pp_get_autorefresh_config;
ops->poll_timeout_wr_ptr = sde_hw_pp_poll_timeout_wr_ptr;
ops->get_line_count = sde_hw_pp_get_line_count;
@@ -357,49 +369,6 @@
}
};
-#define MDP_PP_DSC_OFFSET(index) (0x71000 + (0x800 * index) + 0x0a0)
-#define MDP_PP_AUTOREFRESH_OFFSET(index) (0x71000 + (0x800 * index) + 0x030)
-
-int sde_get_pp_dsc_for_cont_splash(void __iomem *mmio,
- int max_dsc_cnt, u8 *dsc_ids)
-{
- int index;
- int value, dsc_cnt = 0;
-
- if (!mmio || !dsc_ids) {
- SDE_ERROR("invalid input parameters\n");
- return 0;
- }
-
- SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt);
- for (index = 0; index < max_dsc_cnt; index++) {
- value = readl_relaxed(mmio
- + MDP_PP_DSC_OFFSET(index));
- SDE_DEBUG("DSC[%d]=0x%x\n",
- index, value);
- SDE_DEBUG("dsc_cnt = %d\n", dsc_cnt);
- if (value) {
- dsc_ids[dsc_cnt] = index + DSC_0;
- dsc_cnt++;
- }
- value = readl_relaxed(mmio
- + MDP_PP_AUTOREFRESH_OFFSET(index));
- SDE_DEBUG("AUTOREFRESH[%d]=0x%x\n",
- index, value);
- if (value) {
- SDE_DEBUG("Disabling autoreferesh\n");
- writel_relaxed(0x0, mmio
- + MDP_PP_AUTOREFRESH_OFFSET(index));
- /*
- * Wait for one frame update so that auto refresh
- * disable is through
- */
- usleep_range(16000, 20000);
- }
- }
- return dsc_cnt;
-}
-
static struct sde_hw_blk_ops sde_hw_ops = {
.start = NULL,
.stop = NULL,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
index fef49f4..4911658 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_pingpong.h
@@ -128,6 +128,12 @@
void (*disable_dsc)(struct sde_hw_pingpong *pp);
/**
+ * Get DSC status
+ * @Return: register value of DSC config
+ */
+ u32 (*get_dsc_status)(struct sde_hw_pingpong *pp);
+
+ /**
* Program the dither hw block
*/
int (*setup_dither)(struct sde_hw_pingpong *pp, void *cfg, size_t len);
@@ -161,16 +167,6 @@
}
/**
- * sde_get_pp_dsc_for_cont_splash - retrieve the current dsc enabled blocks
- * @mmio: mapped register io address of MDP
- * @max_dsc_cnt: number of DSC blocks supported in the hw
- * @dsc_ids: pointer to store the active DSC block IDs
- * return: number of active DSC blocks
- */
-int sde_get_pp_dsc_for_cont_splash(void __iomem *mmio,
- int max_dsc_cnt, u8 *dsc_ids);
-
-/**
* sde_hw_pingpong_init - initializes the pingpong driver for the passed
* pingpong idx.
* @idx: Pingpong index for which driver object is required
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_vbif.c b/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
index 90a2ca9..6e6a542 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
@@ -266,10 +266,14 @@
/* no need to register sub-range in sde dbg, dump entire vbif io base */
+ mutex_init(&c->mutex);
+
return c;
}
void sde_hw_vbif_destroy(struct sde_hw_vbif *vbif)
{
+ if (vbif)
+ mutex_destroy(&vbif->mutex);
kfree(vbif);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_vbif.h b/drivers/gpu/drm/msm/sde/sde_hw_vbif.h
index 84f0e04..3b650fe 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_vbif.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_vbif.h
@@ -111,6 +111,12 @@
/* ops */
struct sde_hw_vbif_ops ops;
+
+ /*
+ * vbif is common across all displays, lock to serialize access.
+ * must be take by client before using any ops
+ */
+ struct mutex mutex;
};
/**
diff --git a/drivers/gpu/drm/msm/sde/sde_irq.c b/drivers/gpu/drm/msm/sde/sde_irq.c
index 10435da..e25d8fb 100644
--- a/drivers/gpu/drm/msm/sde/sde_irq.c
+++ b/drivers/gpu/drm/msm/sde/sde_irq.c
@@ -104,7 +104,7 @@
}
/* disable irq until power event enables it */
- if (!sde_kms->cont_splash_en)
+ if (!sde_kms->splash_data.cont_splash_en)
irq_set_status_flags(sde_kms->irq_num, IRQ_NOAUTOEN);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index a54e39a9..f4b362f 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -666,9 +666,9 @@
SDE_EVT32_VERBOSE(SDE_EVTLOG_FUNC_EXIT);
- if (sde_kms->cont_splash_en) {
+ if (sde_kms->splash_data.cont_splash_en) {
SDE_DEBUG("Disabling cont_splash feature\n");
- sde_kms->cont_splash_en = false;
+ sde_kms->splash_data.cont_splash_en = false;
sde_power_resource_enable(&priv->phandle,
sde_kms->core_client, false);
SDE_DEBUG("removing Vote for MDP Resources\n");
@@ -2165,7 +2165,7 @@
return -EINVAL;
}
- if (!sde_kms->cont_splash_en) {
+ if (!sde_kms->splash_data.cont_splash_en) {
DRM_INFO("cont_splash feature not enabled\n");
return rc;
}
@@ -2489,68 +2489,6 @@
return ret;
}
-/* the caller api needs to turn on clock before calling this function */
-static int _sde_kms_cont_splash_res_init(struct sde_kms *sde_kms)
-{
- struct sde_mdss_cfg *cat;
- struct drm_device *dev;
- struct msm_drm_private *priv;
- struct sde_splash_data *splash_data;
- int i;
- int ctl_top_cnt;
-
- if (!sde_kms || !sde_kms->catalog) {
- SDE_ERROR("invalid kms\n");
- return -EINVAL;
- }
- cat = sde_kms->catalog;
- dev = sde_kms->dev;
- priv = dev->dev_private;
- splash_data = &sde_kms->splash_data;
- SDE_DEBUG("mixer_count=%d, ctl_count=%d, dsc_count=%d\n",
- cat->mixer_count,
- cat->ctl_count,
- cat->dsc_count);
-
- ctl_top_cnt = cat->ctl_count;
-
- if (ctl_top_cnt > ARRAY_SIZE(splash_data->top)) {
- SDE_ERROR("Mismatch in ctl_top array size\n");
- return -EINVAL;
- }
- for (i = 0; i < ctl_top_cnt; i++) {
- sde_get_ctl_top_for_cont_splash(sde_kms->mmio,
- &splash_data->top[i], i);
- if (splash_data->top[i].intf_sel) {
- splash_data->lm_cnt +=
- sde_get_ctl_lm_for_cont_splash
- (sde_kms->mmio,
- sde_kms->catalog->mixer_count,
- splash_data->lm_cnt,
- splash_data->lm_ids,
- &splash_data->top[i], i);
- splash_data->ctl_ids[splash_data->ctl_top_cnt]
- = i + CTL_0;
- splash_data->ctl_top_cnt++;
- sde_kms->cont_splash_en = true;
- }
- }
-
- /* Skip DSC blk reads if cont_splash is disabled */
- if (!sde_kms->cont_splash_en)
- return 0;
-
- splash_data->dsc_cnt =
- sde_get_pp_dsc_for_cont_splash(sde_kms->mmio,
- sde_kms->catalog->dsc_count,
- splash_data->dsc_ids);
- SDE_DEBUG("splash_data: ctl_top_cnt=%d, lm_cnt=%d, dsc_cnt=%d\n",
- splash_data->ctl_top_cnt, splash_data->lm_cnt,
- splash_data->dsc_cnt);
-
- return 0;
-}
-
static void sde_kms_handle_power_event(u32 event_type, void *usr)
{
struct sde_kms *sde_kms = usr;
@@ -2663,6 +2601,7 @@
struct sde_kms *sde_kms;
struct drm_device *dev;
struct msm_drm_private *priv;
+ struct sde_rm *rm = NULL;
bool splash_mem_found = false;
int i, rc = -EINVAL;
@@ -2787,12 +2726,24 @@
sde_dbg_init_dbg_buses(sde_kms->core_rev);
+ rm = &sde_kms->rm;
+ rc = sde_rm_init(rm, sde_kms->catalog, sde_kms->mmio,
+ sde_kms->dev);
+ if (rc) {
+ SDE_ERROR("rm init failed: %d\n", rc);
+ goto power_error;
+ }
+
+ sde_kms->rm_init = true;
+
/*
* Attempt continuous splash handoff only if reserved
* splash memory is found.
*/
if (splash_mem_found)
- _sde_kms_cont_splash_res_init(sde_kms);
+ sde_rm_cont_splash_res_init(&sde_kms->rm,
+ &sde_kms->splash_data,
+ sde_kms->catalog);
/* Initialize reg dma block which is a singleton */
rc = sde_reg_dma_init(sde_kms->reg_dma, sde_kms->catalog,
@@ -2807,16 +2758,6 @@
SDE_ERROR("sde_kms_mmu_init failed: %d\n", rc);
goto power_error;
}
-
- rc = sde_rm_init(&sde_kms->rm, sde_kms->catalog, sde_kms->mmio,
- sde_kms->dev);
- if (rc) {
- SDE_ERROR("rm init failed: %d\n", rc);
- goto power_error;
- }
-
- sde_kms->rm_init = true;
-
sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm);
if (IS_ERR_OR_NULL(sde_kms->hw_mdp)) {
rc = PTR_ERR(sde_kms->hw_mdp);
@@ -2925,7 +2866,7 @@
SDE_DEBUG("added genpd provider %s\n", sde_kms->genpd.name);
}
- if (sde_kms->cont_splash_en)
+ if (sde_kms->splash_data.cont_splash_en)
SDE_DEBUG("Skipping MDP Resources disable\n");
else
sde_power_resource_enable(&priv->phandle,
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 501797b..48f85bf 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -216,7 +216,6 @@
struct sde_rm rm;
bool rm_init;
struct sde_splash_data splash_data;
- bool cont_splash_en;
struct sde_hw_vbif *hw_vbif[VBIF_MAX];
struct sde_hw_mdp *hw_mdp;
int dsi_display_count;
diff --git a/drivers/gpu/drm/msm/sde/sde_rm.c b/drivers/gpu/drm/msm/sde/sde_rm.c
index c2c1f75..1b71a82 100644
--- a/drivers/gpu/drm/msm/sde/sde_rm.c
+++ b/drivers/gpu/drm/msm/sde/sde_rm.c
@@ -1129,6 +1129,204 @@
return ret;
}
+/**
+ * sde_rm_get_pp_dsc_for_cont_splash - retrieve the current dsc enabled blocks
+ * and disable autorefresh if enabled.
+ * @mmio: mapped register io address of MDP
+ * @max_dsc_cnt: number of DSC blocks supported in the hw
+ * @dsc_ids: pointer to store the active DSC block IDs
+ * return: number of active DSC blocks
+ */
+static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm,
+ int max_dsc_cnt, u8 *dsc_ids)
+{
+ int index = 0;
+ int value, dsc_cnt = 0;
+ struct sde_hw_autorefresh cfg;
+ struct sde_rm_hw_iter iter_pp;
+
+ if (!rm || !dsc_ids) {
+ SDE_ERROR("invalid input parameters\n");
+ return 0;
+ }
+
+ SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt);
+ sde_rm_init_hw_iter(&iter_pp, 0, SDE_HW_BLK_PINGPONG);
+ while (_sde_rm_get_hw_locked(rm, &iter_pp)) {
+ struct sde_hw_pingpong *pp =
+ to_sde_hw_pingpong(iter_pp.blk->hw);
+
+ if (!pp->ops.get_dsc_status) {
+ SDE_ERROR("get_dsc_status ops not initialized\n");
+ return 0;
+ }
+ value = pp->ops.get_dsc_status(pp);
+ SDE_DEBUG("DSC[%d]=0x%x, dsc_cnt = %d\n",
+ index, value, dsc_cnt);
+ if (value) {
+ dsc_ids[dsc_cnt] = index + DSC_0;
+ dsc_cnt++;
+ }
+ index++;
+
+ if (!pp->ops.get_autorefresh) {
+ SDE_ERROR("get_autorefresh api not supported\n");
+ return 0;
+ }
+ memset(&cfg, 0, sizeof(cfg));
+ if (!pp->ops.get_autorefresh(pp, &cfg)
+ && (cfg.enable)
+ && (pp->ops.setup_autorefresh)) {
+ cfg.enable = false;
+ SDE_DEBUG("Disabling autoreferesh\n");
+ pp->ops.setup_autorefresh(pp, &cfg);
+ /*
+ * Wait for one frame update so that
+ * auto refresh disable is through
+ */
+ usleep_range(16000, 20000);
+ }
+ }
+
+ return dsc_cnt;
+}
+
+/**
+ * _sde_rm_get_ctl_lm_for_cont_splash - retrieve the current LM blocks
+ * @ctl: Pointer to CTL hardware block
+ * @max_lm_cnt: number of LM blocks supported in the hw
+ * @lm_cnt: number of LM blocks already active
+ * @lm_ids: pointer to store the active LM block IDs
+ * @top: pointer to the current "ctl_top" structure
+ * @index: ctl_top index
+ * return: number of active LM blocks for this CTL block
+ */
+static int _sde_rm_get_ctl_lm_for_cont_splash(struct sde_hw_ctl *ctl,
+ int max_lm_cnt, u8 lm_cnt,
+ u8 *lm_ids, struct ctl_top *top,
+ int index)
+{
+ int j;
+ struct sde_splash_lm_hw *lm;
+
+ if (!ctl || !top || !lm_ids) {
+ SDE_ERROR("invalid input parameters\n");
+ return 0;
+ }
+
+ lm = top->lm;
+ for (j = 0; j < max_lm_cnt; j++) {
+ lm[top->ctl_lm_cnt].lm_reg_value =
+ ctl->ops.read_ctl_layers(ctl, j + LM_0);
+ SDE_DEBUG("ctl[%d]_top --> lm[%d]=0x%x, j=%d\n",
+ index, top->ctl_lm_cnt,
+ lm[top->ctl_lm_cnt].lm_reg_value, j);
+ SDE_DEBUG("lm_cnt = %d\n", lm_cnt);
+ if (lm[top->ctl_lm_cnt].lm_reg_value) {
+ lm[top->ctl_lm_cnt].ctl_id = index;
+ lm_ids[lm_cnt++] = j + LM_0;
+ lm[top->ctl_lm_cnt].lm_id = j + LM_0;
+ SDE_DEBUG("ctl_id=%d, lm[%d].lm_id = %d\n",
+ lm[top->ctl_lm_cnt].ctl_id,
+ top->ctl_lm_cnt,
+ lm[top->ctl_lm_cnt].lm_id);
+ top->ctl_lm_cnt++;
+ }
+ }
+ return top->ctl_lm_cnt;
+}
+
+/**
+ * _sde_rm_get_ctl_top_for_cont_splash - retrieve the current LM blocks
+ * @ctl: Pointer to CTL hardware block
+ * @top: pointer to the current "ctl_top" structure thats needs update
+ * @index: ctl_top index
+ */
+static void _sde_rm_get_ctl_top_for_cont_splash(struct sde_hw_ctl *ctl,
+ struct ctl_top *top)
+{
+ if (!ctl || !top) {
+ SDE_ERROR("invalid input parameters\n");
+ return;
+ }
+
+ if (!ctl->ops.read_ctl_top) {
+ SDE_ERROR("read_ctl_top not initialized\n");
+ return;
+ }
+
+ top->value = ctl->ops.read_ctl_top(ctl);
+ top->intf_sel = (top->value >> 4) & 0xf;
+ top->pp_sel = (top->value >> 8) & 0x7;
+ top->dspp_sel = (top->value >> 11) & 0x3;
+ top->mode_sel = (top->value >> 17) & 0x1;
+
+ SDE_DEBUG("id=%d,top->0x%x,pp_sel=0x%x,dspp_sel=0x%x,intf_sel=%d\n",
+ ctl->idx, top->value, top->pp_sel,
+ top->dspp_sel, top->intf_sel);
+}
+
+int sde_rm_cont_splash_res_init(struct sde_rm *rm,
+ struct sde_splash_data *splash_data,
+ struct sde_mdss_cfg *cat)
+{
+ struct sde_rm_hw_iter iter_c;
+ int index = 0, ctl_top_cnt;
+
+ if (!rm || !cat || !splash_data) {
+ SDE_ERROR("invalid input parameters\n");
+ return -EINVAL;
+ }
+
+ SDE_DEBUG("mixer_count=%d, ctl_count=%d, dsc_count=%d\n",
+ cat->mixer_count,
+ cat->ctl_count,
+ cat->dsc_count);
+
+ ctl_top_cnt = cat->ctl_count;
+
+ if (ctl_top_cnt > ARRAY_SIZE(splash_data->top)) {
+ SDE_ERROR("Mismatch in ctl_top array size\n");
+ return -EINVAL;
+ }
+
+ sde_rm_init_hw_iter(&iter_c, 0, SDE_HW_BLK_CTL);
+ while (_sde_rm_get_hw_locked(rm, &iter_c)) {
+ struct sde_hw_ctl *ctl = to_sde_hw_ctl(iter_c.blk->hw);
+
+ _sde_rm_get_ctl_top_for_cont_splash(ctl,
+ &splash_data->top[index]);
+ if (splash_data->top[index].intf_sel) {
+ splash_data->lm_cnt +=
+ _sde_rm_get_ctl_lm_for_cont_splash
+ (ctl,
+ cat->mixer_count,
+ splash_data->lm_cnt,
+ splash_data->lm_ids,
+ &splash_data->top[index], index);
+ splash_data->ctl_ids[splash_data->ctl_top_cnt]
+ = index + CTL_0;
+ splash_data->ctl_top_cnt++;
+ splash_data->cont_splash_en = true;
+ }
+ index++;
+ }
+
+ /* Skip DSC blk reads if cont_splash is disabled */
+ if (!splash_data->cont_splash_en)
+ return 0;
+
+ splash_data->dsc_cnt =
+ _sde_rm_get_pp_dsc_for_cont_splash(rm,
+ cat->dsc_count,
+ splash_data->dsc_ids);
+ SDE_DEBUG("splash_data: ctl_top_cnt=%d, lm_cnt=%d, dsc_cnt=%d\n",
+ splash_data->ctl_top_cnt, splash_data->lm_cnt,
+ splash_data->dsc_cnt);
+
+ return 0;
+}
+
static int _sde_rm_make_next_rsvp_for_cont_splash(
struct sde_rm *rm,
struct drm_encoder *enc,
@@ -1484,7 +1682,7 @@
sde_kms = to_sde_kms(priv->kms);
/* Check if this is just a page-flip */
- if (!sde_kms->cont_splash_en &&
+ if (!sde_kms->splash_data.cont_splash_en &&
!drm_atomic_crtc_needs_modeset(crtc_state))
return 0;
@@ -1536,7 +1734,7 @@
}
/* Check the proposed reservation, store it in hw's "next" field */
- if (sde_kms->cont_splash_en) {
+ if (sde_kms->splash_data.cont_splash_en) {
SDE_DEBUG("cont_splash feature enabled\n");
ret = _sde_rm_make_next_rsvp_for_cont_splash
(rm, enc, crtc_state, conn_state, rsvp_nxt, &reqs);
diff --git a/drivers/gpu/drm/msm/sde/sde_rm.h b/drivers/gpu/drm/msm/sde/sde_rm.h
index 0545609..b2dd87d 100644
--- a/drivers/gpu/drm/msm/sde/sde_rm.h
+++ b/drivers/gpu/drm/msm/sde/sde_rm.h
@@ -126,7 +126,7 @@
*/
int sde_rm_init(struct sde_rm *rm,
struct sde_mdss_cfg *cat,
- void *mmio,
+ void __iomem *mmio,
struct drm_device *dev);
/**
@@ -207,6 +207,19 @@
int sde_rm_check_property_topctl(uint64_t val);
/**
+ * sde_rm_cont_splash_res_init - Read the current MDSS configuration
+ * to update the splash data structure with the topology
+ * configured by the bootloader.
+ * @rm: SDE Resource Manager handle
+ * @splash_data: Pointer to the splash_data structure to be updated.
+ * @cat: Pointer to the SDE catalog
+ * @Return: 0 on success or error
+ */
+int sde_rm_cont_splash_res_init(struct sde_rm *rm,
+ struct sde_splash_data *splash_data,
+ struct sde_mdss_cfg *cat);
+
+/**
* sde_rm_update_topology - sets topology property of the connector
* @conn_state: drm state of the connector
* @topology: topology selected for the display
diff --git a/drivers/gpu/drm/msm/sde/sde_trace.h b/drivers/gpu/drm/msm/sde/sde_trace.h
index ef4cdeb..2909778 100644
--- a/drivers/gpu/drm/msm/sde/sde_trace.h
+++ b/drivers/gpu/drm/msm/sde/sde_trace.h
@@ -93,21 +93,24 @@
)
TRACE_EVENT(sde_perf_update_bus,
- TP_PROTO(int client, unsigned long long ab_quota,
+ TP_PROTO(int client, u32 bus_id, unsigned long long ab_quota,
unsigned long long ib_quota),
- TP_ARGS(client, ab_quota, ib_quota),
+ TP_ARGS(client, bus_id, ab_quota, ib_quota),
TP_STRUCT__entry(
__field(int, client)
+ __field(u32, bus_id);
__field(u64, ab_quota)
__field(u64, ib_quota)
),
TP_fast_assign(
__entry->client = client;
+ __entry->bus_id = bus_id;
__entry->ab_quota = ab_quota;
__entry->ib_quota = ib_quota;
),
- TP_printk("Request client:%d ab=%llu ib=%llu",
+ TP_printk("Request client:%d bus_id:%d ab=%llu ib=%llu",
__entry->client,
+ __entry->bus_id,
__entry->ab_quota,
__entry->ib_quota)
)
@@ -209,41 +212,111 @@
)
TRACE_EVENT(sde_perf_crtc_update,
- TP_PROTO(u32 crtc, u64 bw_ctl_mnoc, u64 bw_ctl_llcc,
- u64 bw_ctl_ebi, u32 core_clk_rate,
- bool stop_req, u32 update_bus, u32 update_clk),
- TP_ARGS(crtc, bw_ctl_mnoc, bw_ctl_llcc, bw_ctl_ebi, core_clk_rate,
- stop_req, update_bus, update_clk),
+ TP_PROTO(u32 crtc,
+ u64 bw_ctl_mnoc, u64 per_pipe_ib_mnoc,
+ u64 bw_ctl_llcc, u64 per_pipe_ib_llcc,
+ u64 bw_ctl_ebi, u64 per_pipe_ib_ebi,
+ u32 core_clk_rate, bool stop_req,
+ u32 update_bus, u32 update_clk, int params),
+ TP_ARGS(crtc,
+ bw_ctl_mnoc, per_pipe_ib_mnoc,
+ bw_ctl_llcc, per_pipe_ib_llcc,
+ bw_ctl_ebi, per_pipe_ib_ebi,
+ core_clk_rate, stop_req,
+ update_bus, update_clk, params),
+ TP_STRUCT__entry(
+ __field(u32, crtc)
+ __field(u64, bw_ctl_mnoc)
+ __field(u64, per_pipe_ib_mnoc)
+ __field(u64, bw_ctl_llcc)
+ __field(u64, per_pipe_ib_llcc)
+ __field(u64, bw_ctl_ebi)
+ __field(u64, per_pipe_ib_ebi)
+ __field(u32, core_clk_rate)
+ __field(bool, stop_req)
+ __field(u32, update_bus)
+ __field(u32, update_clk)
+ __field(int, params)
+ ),
+ TP_fast_assign(
+ __entry->crtc = crtc;
+ __entry->bw_ctl_mnoc = bw_ctl_mnoc;
+ __entry->per_pipe_ib_mnoc = per_pipe_ib_mnoc;
+ __entry->bw_ctl_llcc = bw_ctl_llcc;
+ __entry->per_pipe_ib_llcc = per_pipe_ib_llcc;
+ __entry->bw_ctl_ebi = bw_ctl_ebi;
+ __entry->per_pipe_ib_ebi = per_pipe_ib_ebi;
+ __entry->core_clk_rate = core_clk_rate;
+ __entry->stop_req = stop_req;
+ __entry->update_bus = update_bus;
+ __entry->update_clk = update_clk;
+ __entry->params = params;
+ ),
+ TP_printk(
+ "crtc=%d mnoc=[%llu %llu] llcc=[%llu %llu] ebi=[%llu %llu] clk=%u stop=%d ubus=%d uclk=%d %d",
+ __entry->crtc,
+ __entry->bw_ctl_mnoc,
+ __entry->per_pipe_ib_mnoc,
+ __entry->bw_ctl_llcc,
+ __entry->per_pipe_ib_llcc,
+ __entry->bw_ctl_ebi,
+ __entry->per_pipe_ib_ebi,
+ __entry->core_clk_rate,
+ __entry->stop_req,
+ __entry->update_bus,
+ __entry->update_clk,
+ __entry->params)
+);
+
+TRACE_EVENT(sde_perf_calc_crtc,
+ TP_PROTO(u32 crtc,
+ u64 bw_ctl_mnoc,
+ u64 bw_ctl_llcc,
+ u64 bw_ctl_ebi,
+ u64 ib_mnoc,
+ u64 ib_llcc,
+ u64 ib_ebi,
+ u32 core_clk_rate
+ ),
+ TP_ARGS(crtc,
+ bw_ctl_mnoc,
+ bw_ctl_llcc,
+ bw_ctl_ebi,
+ ib_mnoc,
+ ib_llcc,
+ ib_ebi,
+ core_clk_rate),
TP_STRUCT__entry(
__field(u32, crtc)
__field(u64, bw_ctl_mnoc)
__field(u64, bw_ctl_llcc)
__field(u64, bw_ctl_ebi)
+ __field(u64, ib_mnoc)
+ __field(u64, ib_llcc)
+ __field(u64, ib_ebi)
__field(u32, core_clk_rate)
- __field(bool, stop_req)
- __field(u32, update_bus)
- __field(u32, update_clk)
+
),
TP_fast_assign(
__entry->crtc = crtc;
__entry->bw_ctl_mnoc = bw_ctl_mnoc;
__entry->bw_ctl_llcc = bw_ctl_llcc;
__entry->bw_ctl_ebi = bw_ctl_ebi;
+ __entry->ib_mnoc = ib_mnoc;
+ __entry->ib_llcc = ib_llcc;
+ __entry->ib_ebi = ib_ebi;
__entry->core_clk_rate = core_clk_rate;
- __entry->stop_req = stop_req;
- __entry->update_bus = update_bus;
- __entry->update_clk = update_clk;
),
TP_printk(
- "crtc=%d bw_mnoc=%llu bw_llcc=%llu bw_ebi=%llu clk_rate=%u stop_req=%d u_bus=%d u_clk=%d",
+ "crtc=%d mnoc=[%llu, %llu] llcc=[%llu %llu] ebi=[%llu, %llu] clk_rate=%u",
__entry->crtc,
__entry->bw_ctl_mnoc,
+ __entry->ib_mnoc,
__entry->bw_ctl_llcc,
+ __entry->ib_llcc,
__entry->bw_ctl_ebi,
- __entry->core_clk_rate,
- __entry->stop_req,
- __entry->update_bus,
- __entry->update_clk)
+ __entry->ib_ebi,
+ __entry->core_clk_rate)
);
#define SDE_ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0)
diff --git a/drivers/gpu/drm/msm/sde/sde_vbif.c b/drivers/gpu/drm/msm/sde/sde_vbif.c
index 0dbc027..c19ee82 100644
--- a/drivers/gpu/drm/msm/sde/sde_vbif.c
+++ b/drivers/gpu/drm/msm/sde/sde_vbif.c
@@ -82,16 +82,22 @@
return -EINVAL;
}
+ mutex_lock(&vbif->mutex);
+
+ SDE_EVT32_VERBOSE(vbif->idx, xin_id);
+
/*
* If status is 0, then make sure client clock is not gated
* while halting by forcing it ON only if it was not previously
* forced on. If status is 1 then its already halted.
*/
status = vbif->ops.get_halt_ctrl(vbif, xin_id);
- if (status == 0)
- forced_on = mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, true);
- else
+ if (status) {
+ mutex_unlock(&vbif->mutex);
return 0;
+ }
+
+ forced_on = mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, true);
/* send halt request for unused plane's xin client */
vbif->ops.set_halt_ctrl(vbif, xin_id, true);
@@ -109,6 +115,8 @@
if (forced_on)
mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, false);
+ mutex_unlock(&vbif->mutex);
+
return rc;
}
@@ -238,6 +246,10 @@
!vbif->ops.set_halt_ctrl)
return;
+ mutex_lock(&vbif->mutex);
+
+ SDE_EVT32_VERBOSE(vbif->idx, params->xin_id);
+
/* set write_gather_en for all write clients */
if (vbif->ops.set_write_gather_en && !params->rd)
vbif->ops.set_write_gather_en(vbif, params->xin_id);
@@ -265,6 +277,7 @@
if (forced_on)
mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false);
exit:
+ mutex_unlock(&vbif->mutex);
return;
}
@@ -300,6 +313,10 @@
!vbif->ops.set_halt_ctrl)
return false;
+ mutex_lock(&vbif->mutex);
+
+ SDE_EVT32_VERBOSE(vbif->idx, params->xin_id);
+
if (params->enable) {
forced_on = mdp->ops.setup_clk_force_ctrl(mdp,
params->clk_ctrl, true);
@@ -317,6 +334,8 @@
params->clk_ctrl, false);
}
+ mutex_unlock(&vbif->mutex);
+
return forced_on;
}
@@ -361,6 +380,8 @@
return;
}
+ mutex_lock(&vbif->mutex);
+
forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true);
for (i = 0; i < qos_tbl->npriority_lvl; i++) {
@@ -373,6 +394,8 @@
if (forced_on)
mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false);
+
+ mutex_unlock(&vbif->mutex);
}
void sde_vbif_clear_errors(struct sde_kms *sde_kms)
@@ -388,12 +411,14 @@
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
vbif = sde_kms->hw_vbif[i];
if (vbif && vbif->ops.clear_errors) {
+ mutex_lock(&vbif->mutex);
vbif->ops.clear_errors(vbif, &pnd, &src);
if (pnd || src) {
SDE_EVT32(i, pnd, src);
SDE_DEBUG("VBIF %d: pnd 0x%X, src 0x%X\n",
vbif->idx - VBIF_0, pnd, src);
}
+ mutex_unlock(&vbif->mutex);
}
}
}
@@ -411,9 +436,11 @@
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
vbif = sde_kms->hw_vbif[i];
if (vbif && vbif->cap && vbif->ops.set_mem_type) {
+ mutex_lock(&vbif->mutex);
for (j = 0; j < vbif->cap->memtype_count; j++)
vbif->ops.set_mem_type(
vbif, j, vbif->cap->memtype[j]);
+ mutex_unlock(&vbif->mutex);
}
}
}
diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c
index 34a826d..4244c00 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.c
+++ b/drivers/gpu/drm/msm/sde_power_handle.c
@@ -470,7 +470,7 @@
pclient->ab[bus_client] = ab_quota;
pclient->ib[bus_client] = ib_quota;
- trace_sde_perf_update_bus(bus_client, ab_quota, ib_quota);
+ trace_sde_perf_update_bus(bus_client, bus_id, ab_quota, ib_quota);
list_for_each_entry(client, &phandle->power_client_clist, list) {
for (i = 0; i < SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index 82b1199..429ab01 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -561,6 +561,23 @@
msleep(PRIMARY_VBLANK_WORST_CASE_MS);
} else {
*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+ /* increase refcount, so we wait for the next vsync */
+ atomic_inc(&rsc->rsc_vsync_wait);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+ }
+ } else if (atomic_read(&rsc->rsc_vsync_wait)) {
+ SDE_EVT32(rsc->primary_client, rsc->current_state,
+ atomic_read(&rsc->rsc_vsync_wait));
+
+ /* Wait for the vsync, if the refcount is set */
+ rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+ atomic_read(&rsc->rsc_vsync_wait) == 0,
+ msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+ if (!rc) {
+ pr_err("Timeout waiting for vsync\n");
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+ SDE_EVTLOG_ERROR);
}
}
end:
@@ -600,6 +617,23 @@
msleep(PRIMARY_VBLANK_WORST_CASE_MS);
} else {
*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+ /* increase refcount, so we wait for the next vsync */
+ atomic_inc(&rsc->rsc_vsync_wait);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+ }
+ } else if (atomic_read(&rsc->rsc_vsync_wait)) {
+ SDE_EVT32(rsc->primary_client, rsc->current_state,
+ atomic_read(&rsc->rsc_vsync_wait));
+
+ /* Wait for the vsync, if the refcount is set */
+ rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+ atomic_read(&rsc->rsc_vsync_wait) == 0,
+ msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+ if (!rc) {
+ pr_err("Timeout waiting for vsync\n");
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+ SDE_EVTLOG_ERROR);
}
}
@@ -608,6 +642,65 @@
}
/**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: value of the vsync refcount.
+ */
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ struct sde_rsc_priv *rsc;
+
+ if (!caller_client) {
+ pr_err("invalid client for rsc state update\n");
+ return -EINVAL;
+ } else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+ pr_err("invalid rsc index\n");
+ return -EINVAL;
+ }
+
+ rsc = rsc_prv_list[caller_client->rsc_index];
+ if (!rsc)
+ return 0;
+
+ return atomic_read(&rsc->rsc_vsync_wait);
+}
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: zero if refcount was already zero.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ struct sde_rsc_priv *rsc;
+ int ret;
+
+ if (!caller_client) {
+ pr_err("invalid client for rsc state update\n");
+ return -EINVAL;
+ } else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+ pr_err("invalid rsc index\n");
+ return -EINVAL;
+ }
+
+ rsc = rsc_prv_list[caller_client->rsc_index];
+ if (!rsc)
+ return 0;
+
+ ret = atomic_add_unless(&rsc->rsc_vsync_wait, -1, 0);
+ wake_up_all(&rsc->rsc_vsync_waitq);
+ SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+
+ return ret;
+}
+
+/**
* sde_rsc_client_is_state_update_complete() - check if state update is complete
* RSC state transition is not complete until HW receives VBLANK signal. This
* function checks RSC HW to determine whether that signal has been received.
@@ -1307,6 +1400,7 @@
INIT_LIST_HEAD(&rsc->client_list);
INIT_LIST_HEAD(&rsc->event_list);
mutex_init(&rsc->client_lock);
+ init_waitqueue_head(&rsc->rsc_vsync_waitq);
pr_info("sde rsc index:%d probed successfully\n",
SDE_RSC_INDEX + counter);
diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h
index 64b0216..5c62466 100644
--- a/drivers/gpu/drm/msm/sde_rsc_priv.h
+++ b/drivers/gpu/drm/msm/sde_rsc_priv.h
@@ -149,6 +149,8 @@
* and ab/ib vote on display rsc
* master_drm: Primary client waits for vsync on this drm object based
* on crtc id
+ * rsc_vsync_wait: Refcount to indicate if we have to wait for the vsync.
+ * rsc_vsync_waitq: Queue to wait for the vsync.
*/
struct sde_rsc_priv {
u32 version;
@@ -177,6 +179,8 @@
struct sde_rsc_client *primary_client;
struct drm_device *master_drm;
+ atomic_t rsc_vsync_wait;
+ wait_queue_head_t rsc_vsync_waitq;
};
/**
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index b81be8f..6876796 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -424,16 +424,6 @@
return ERR_PTR(ret);
}
- if (gpudev->preemption_context_init) {
- ret = gpudev->preemption_context_init(&drawctxt->base);
- if (ret != 0) {
- kgsl_context_detach(&drawctxt->base);
- kgsl_context_put(&drawctxt->base);
- kfree(drawctxt);
- return ERR_PTR(ret);
- }
- }
-
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp),
0);
@@ -445,6 +435,14 @@
INIT_LIST_HEAD(&drawctxt->active_node);
+ if (gpudev->preemption_context_init) {
+ ret = gpudev->preemption_context_init(&drawctxt->base);
+ if (ret != 0) {
+ kgsl_context_detach(&drawctxt->base);
+ return ERR_PTR(ret);
+ }
+ }
+
/* copy back whatever flags we dediced were valid */
*flags = drawctxt->base.flags;
return &drawctxt->base;
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 5bd52e4..1a2aea9 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -731,7 +731,8 @@
#define FLASH_VDIP_MARGIN 50000
#define BOB_EFFICIENCY 900LL
#define VIN_FLASH_MIN_UV 3300000LL
-static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led,
+ int *max_current)
{
int ocv_uv, ibat_now, voltage_hdrm_mv, rc;
int rbatt_uohm = 0;
@@ -747,8 +748,10 @@
}
/* If no battery is connected, return max possible flash current */
- if (!rbatt_uohm)
- return FLASH_LED_MAX_TOTAL_CURRENT_MA;
+ if (!rbatt_uohm) {
+ *max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA;
+ return 0;
+ }
rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
if (rc < 0) {
@@ -785,7 +788,7 @@
/* Wait for LMH mitigation to take effect */
udelay(100);
- return qpnp_flash_led_calc_max_current(led);
+ return qpnp_flash_led_calc_max_current(led, max_current);
}
/*
@@ -825,13 +828,14 @@
avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
- return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
+ *max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
(int)(div64_s64(avail_flash_ua, MCONV)));
+ return 0;
}
-static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led,
+ int *thermal_current_lim)
{
- int thermal_current_lim = 0;
int rc;
u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status;
@@ -888,7 +892,7 @@
/* Look up current limit based on THERMAL_OTST status */
if (otst_status)
- thermal_current_lim =
+ *thermal_current_lim =
led->pdata->thermal_derate_current[otst_status >> 1];
/* Restore THERMAL_THRESHx registers to original values */
@@ -913,23 +917,36 @@
if (rc < 0)
return rc;
- return thermal_current_lim;
+ return 0;
}
-static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led,
+ int *max_avail_current)
{
- int max_avail_current, thermal_current_lim = 0;
+ int thermal_current_lim = 0, rc;
led->trigger_lmh = false;
- max_avail_current = qpnp_flash_led_calc_max_current(led);
- if (led->pdata->thermal_derate_en)
- thermal_current_lim =
- qpnp_flash_led_calc_thermal_current_lim(led);
+ rc = qpnp_flash_led_calc_max_current(led, max_avail_current);
+ if (rc < 0) {
+ pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc);
+ return rc;
+ }
+
+ if (led->pdata->thermal_derate_en) {
+ rc = qpnp_flash_led_calc_thermal_current_lim(led,
+ &thermal_current_lim);
+ if (rc < 0) {
+ pr_err("Couldn't calculate thermal_current_lim, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
if (thermal_current_lim)
- max_avail_current = min(max_avail_current, thermal_current_lim);
+ *max_avail_current = min(*max_avail_current,
+ thermal_current_lim);
- return max_avail_current;
+ return 0;
}
static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode)
@@ -1237,12 +1254,11 @@
}
if (options & QUERY_MAX_CURRENT) {
- rc = qpnp_flash_led_get_max_avail_current(led);
+ rc = qpnp_flash_led_get_max_avail_current(led, max_current);
if (rc < 0) {
pr_err("query max current failed, rc=%d\n", rc);
return rc;
}
- *max_current = rc;
}
return 0;
@@ -1291,7 +1307,7 @@
static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int rc;
+ int rc, max_current = 0;
struct flash_switch_data *snode;
struct qpnp_flash_led *led;
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -1299,11 +1315,11 @@
snode = container_of(led_cdev, struct flash_switch_data, cdev);
led = dev_get_drvdata(&snode->pdev->dev);
- rc = qpnp_flash_led_get_max_avail_current(led);
+ rc = qpnp_flash_led_get_max_avail_current(led, &max_current);
if (rc < 0)
pr_err("query max current failed, rc=%d\n", rc);
- return snprintf(buf, PAGE_SIZE, "%d\n", rc);
+ return snprintf(buf, PAGE_SIZE, "%d\n", max_current);
}
/* sysfs attributes exported by flash_led */
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
index f1dfc7c..00ead5d 100644
--- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
@@ -585,7 +585,7 @@
if (rc) {
CAM_ERR(CAM_CPAS,
"Failed camnoc vote ab[%llu] ib[%llu] rc=%d",
- 0, camnoc_bw, rc);
+ (uint64_t)0, camnoc_bw, rc);
goto unlock_axi_port;
}
}
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
index bff42f4..e57066d 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
@@ -402,7 +402,7 @@
(struct cam_fd_hw_cmd_prestart_args *)user_data;
if (!blob_data || (blob_size == 0)) {
- CAM_ERR(CAM_FD, "Invalid blob info %pK %d", blob_data,
+ CAM_ERR(CAM_FD, "Invalid blob info %pK %u", blob_data,
blob_size);
return -EINVAL;
}
@@ -417,7 +417,7 @@
uint32_t *get_raw_results = (uint32_t *)blob_data;
if (sizeof(uint32_t) != blob_size) {
- CAM_ERR(CAM_FD, "Invalid blob size %d %d",
+ CAM_ERR(CAM_FD, "Invalid blob size %lu %u",
sizeof(uint32_t), blob_size);
return -EINVAL;
}
@@ -430,7 +430,7 @@
(struct cam_fd_soc_clock_bw_request *)blob_data;
if (sizeof(struct cam_fd_soc_clock_bw_request) != blob_size) {
- CAM_ERR(CAM_FD, "Invalid blob size %d %d",
+ CAM_ERR(CAM_FD, "Invalid blob size %lu %u",
sizeof(struct cam_fd_soc_clock_bw_request),
blob_size);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
index 51c8e4a..640c6f6 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_core.c
@@ -127,7 +127,7 @@
time_left = wait_for_completion_timeout(&fd_core->reset_complete,
msecs_to_jiffies(CAM_FD_HW_HALT_RESET_TIMEOUT));
if (time_left <= 0)
- CAM_WARN(CAM_FD, "HW reset timeout time_left=%d", time_left);
+ CAM_WARN(CAM_FD, "HW reset timeout time_left=%ld", time_left);
CAM_DBG(CAM_FD, "FD Wrapper SW Sync Reset complete");
@@ -157,7 +157,7 @@
time_left = wait_for_completion_timeout(&fd_core->halt_complete,
msecs_to_jiffies(CAM_FD_HW_HALT_RESET_TIMEOUT));
if (time_left <= 0)
- CAM_WARN(CAM_FD, "HW halt timeout time_left=%d", time_left);
+ CAM_WARN(CAM_FD, "HW halt timeout time_left=%ld", time_left);
CAM_DBG(CAM_FD, "FD Wrapper Halt complete");
@@ -651,7 +651,7 @@
}
if (arg_size != sizeof(struct cam_fd_hw_init_args)) {
- CAM_ERR(CAM_FD, "Invalid arg size %d, %d", arg_size,
+ CAM_ERR(CAM_FD, "Invalid arg size %u, %lu", arg_size,
sizeof(struct cam_fd_hw_init_args));
return -EINVAL;
}
@@ -735,7 +735,7 @@
}
if (arg_size != sizeof(struct cam_fd_hw_deinit_args)) {
- CAM_ERR(CAM_FD, "Invalid arg size %d, %d", arg_size,
+ CAM_ERR(CAM_FD, "Invalid arg size %u, %lu", arg_size,
sizeof(struct cam_fd_hw_deinit_args));
return -EINVAL;
}
@@ -859,7 +859,7 @@
}
if (arg_size != sizeof(struct cam_fd_hw_cmd_start_args)) {
- CAM_ERR(CAM_FD, "Invalid arg size %d, %d", arg_size,
+ CAM_ERR(CAM_FD, "Invalid arg size %u, %lu", arg_size,
sizeof(struct cam_fd_hw_cmd_start_args));
return -EINVAL;
}
@@ -1010,7 +1010,7 @@
}
if (arg_size != sizeof(struct cam_fd_hw_reserve_args)) {
- CAM_ERR(CAM_FD, "Invalid arg size %d, %d", arg_size,
+ CAM_ERR(CAM_FD, "Invalid arg size %u, %lu", arg_size,
sizeof(struct cam_fd_hw_reserve_args));
return -EINVAL;
}
@@ -1079,7 +1079,7 @@
}
if (arg_size != sizeof(struct cam_fd_hw_release_args)) {
- CAM_ERR(CAM_FD, "Invalid arg size %d, %d", arg_size,
+ CAM_ERR(CAM_FD, "Invalid arg size %u, %lu", arg_size,
sizeof(struct cam_fd_hw_release_args));
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index d407771..9bdde9c 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -1008,8 +1008,7 @@
rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
&csid_res);
if (rc) {
- CAM_ERR(CAM_ISP, "No more free hw mgr resource",
- __func__);
+ CAM_ERR(CAM_ISP, "No more free hw mgr resource");
goto err;
}
cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_csid, &csid_res);
@@ -2015,6 +2014,7 @@
/* clean context */
list_del_init(&ctx->list);
ctx->ctx_in_use = 0;
+ ctx->is_rdi_only_context = 0;
CAM_DBG(CAM_ISP, "Exit...ctx id:%d",
ctx->ctx_index);
cam_ife_hw_mgr_put_ctx(&hw_mgr->free_ctx_list, &ctx);
@@ -2761,8 +2761,7 @@
CAM_DBG(CAM_ISP, "Enter");
if (!recovery_data) {
- CAM_ERR(CAM_ISP, "recovery_data parameter is NULL",
- __func__);
+ CAM_ERR(CAM_ISP, "recovery_data parameter is NULL");
return -EINVAL;
}
recovery_data->no_of_context = 0;
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index 44dc5c4..4bee732 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -88,7 +88,7 @@
* @th_list_head: List of handlers sorted by priority
* @hdl_idx: Unique identity of handler assigned on Subscribe.
* Used to Unsubscribe.
- * @rw_lock: Read-Write Lock for use by controller
+ * @lock: Lock for use by controller
*/
struct cam_irq_controller {
const char *name;
@@ -101,7 +101,7 @@
struct list_head evt_handler_list_head;
struct list_head th_list_head[CAM_IRQ_PRIORITY_MAX];
uint32_t hdl_idx;
- rwlock_t rw_lock;
+ spinlock_t lock;
struct cam_irq_th_payload th_payload;
};
@@ -208,7 +208,7 @@
for (i = 0; i < CAM_IRQ_PRIORITY_MAX; i++)
INIT_LIST_HEAD(&controller->th_list_head[i]);
- rwlock_init(&controller->rw_lock);
+ spin_lock_init(&controller->lock);
controller->hdl_idx = 1;
*irq_controller = controller;
@@ -304,7 +304,7 @@
need_lock = !in_irq();
if (need_lock)
- write_lock_irqsave(&controller->rw_lock, flags);
+ spin_lock_irqsave(&controller->lock, flags);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_register_arr[i].top_half_enable_mask[priority]
|= evt_bit_mask_arr[i];
@@ -317,7 +317,7 @@
controller->irq_register_arr[i].mask_reg_offset);
}
if (need_lock)
- write_unlock_irqrestore(&controller->rw_lock, flags);
+ spin_unlock_irqrestore(&controller->lock, flags);
list_add_tail(&evt_handler->list_node,
&controller->evt_handler_list_head);
@@ -363,7 +363,7 @@
need_lock = !in_irq();
if (need_lock)
- write_lock_irqsave(&controller->rw_lock, flags);
+ spin_lock_irqsave(&controller->lock, flags);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_register_arr[i].
top_half_enable_mask[evt_handler->priority] |=
@@ -378,7 +378,7 @@
controller->irq_register_arr[i].mask_reg_offset);
}
if (need_lock)
- write_unlock_irqrestore(&controller->rw_lock, flags);
+ spin_unlock_irqrestore(&controller->lock, flags);
return rc;
}
@@ -413,7 +413,7 @@
need_lock = !in_irq();
if (need_lock)
- write_lock_irqsave(&controller->rw_lock, flags);
+ spin_lock_irqsave(&controller->lock, flags);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_register_arr[i].
top_half_enable_mask[evt_handler->priority] &=
@@ -441,7 +441,7 @@
controller->global_clear_offset);
}
if (need_lock)
- write_unlock_irqrestore(&controller->rw_lock, flags);
+ spin_unlock_irqrestore(&controller->lock, flags);
return rc;
}
@@ -475,7 +475,7 @@
if (found) {
if (need_lock)
- write_lock_irqsave(&controller->rw_lock, flags);
+ spin_lock_irqsave(&controller->lock, flags);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_register_arr[i].
top_half_enable_mask[evt_handler->priority] &=
@@ -502,7 +502,7 @@
controller->global_clear_offset);
}
if (need_lock)
- write_unlock_irqrestore(&controller->rw_lock, flags);
+ spin_unlock_irqrestore(&controller->lock, flags);
kfree(evt_handler->evt_bit_mask_arr);
kfree(evt_handler);
@@ -607,9 +607,9 @@
if (!controller)
return IRQ_NONE;
- CAM_DBG(CAM_ISP, "locking controller %pK name %s rw_lock %pK",
- controller, controller->name, &controller->rw_lock);
- read_lock(&controller->rw_lock);
+ CAM_DBG(CAM_ISP, "locking controller %pK name %s lock %pK",
+ controller, controller->name, &controller->lock);
+ spin_lock(&controller->lock);
for (i = 0; i < controller->num_registers; i++) {
controller->irq_status_arr[i] = cam_io_r_mb(
controller->mem_base +
@@ -630,8 +630,8 @@
i, j, need_th_processing[j]);
}
}
- CAM_DBG(CAM_ISP, "unlocked controller %pK name %s rw_lock %pK",
- controller, controller->name, &controller->rw_lock);
+ CAM_DBG(CAM_ISP, "unlocked controller %pK name %s lock %pK",
+ controller, controller->name, &controller->lock);
CAM_DBG(CAM_ISP, "Status Registers read Successful");
@@ -648,7 +648,7 @@
&controller->th_list_head[i]);
}
}
- read_unlock(&controller->rw_lock);
+ spin_unlock(&controller->lock);
return IRQ_HANDLED;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index daf515a..4a7eb00 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -2778,7 +2778,8 @@
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->
csid_csi2_rx_captured_short_pkt_1_addr);
- CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d", val);
+ CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d",
+ csid_hw->hw_intf->hw_idx, val);
}
if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
index ed58b41..05ae7cc 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
@@ -172,7 +172,7 @@
cam_jpeg_dma_irq,
jpeg_dma_dev);
if (rc) {
- CAM_ERR(CAM_JPEG, "%failed to init_soc %d", rc);
+ CAM_ERR(CAM_JPEG, "failed to init_soc %d", rc);
goto error_init_soc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
index d7a6504..9a711ec 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -119,7 +119,8 @@
rc = wait_for_completion_timeout(&cci_dev->
cci_master_info[master].report_q[queue], CCI_TIMEOUT);
if (rc <= 0) {
- CAM_ERR(CAM_CCI, "Wait_for_completion_timeout %d");
+ CAM_ERR(CAM_CCI, "Wait_for_completion_timeout: rc: %d",
+ rc);
if (rc == 0)
rc = -ETIMEDOUT;
cam_cci_flush_queue(cci_dev, master);
@@ -312,7 +313,7 @@
if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) {
rc = cam_cci_lock_queue(cci_dev, master, queue, 0);
if (rc < 0) {
- CAM_ERR(CAM_CCI, "failed line %d");
+ CAM_ERR(CAM_CCI, "failed rc: %d", rc);
return rc;
}
rc = cam_cci_wait_report_cmd(cci_dev, master, queue);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index 72b1779..3abdd80 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -128,7 +128,6 @@
i2c_reg_settings.reg_setting = &i2c_reg_array;
rc = camera_io_dev_write(&e_ctrl->io_master_info,
&i2c_reg_settings);
-
if (rc) {
CAM_ERR(CAM_EEPROM,
"page disable failed rc %d",
@@ -410,10 +409,12 @@
static int32_t cam_eeprom_parse_memory_map(
struct cam_eeprom_memory_block_t *data,
void *cmd_buf, int cmd_length, uint16_t *cmd_length_bytes,
- int16_t num_map)
+ int *num_map)
{
int32_t rc = 0;
+ int32_t cnt = 0;
int32_t processed_size = 0;
+ uint8_t generic_op_code;
struct cam_eeprom_memory_map_t *map = data->map;
struct common_header *cmm_hdr =
(struct common_header *)cmd_buf;
@@ -421,19 +422,30 @@
struct cam_cmd_i2c_random_wr *i2c_random_wr = NULL;
struct cam_cmd_i2c_continuous_rd *i2c_cont_rd = NULL;
struct cam_cmd_conditional_wait *i2c_poll = NULL;
+ struct cam_cmd_unconditional_wait *i2c_uncond_wait = NULL;
+ generic_op_code = cmm_hdr->third_byte;
switch (cmm_hdr->cmd_type) {
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
- cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr);
+ cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) +
+ ((i2c_random_wr->header.count - 1) *
+ sizeof(struct i2c_random_wr_payload));
- map[num_map].page.addr =
- i2c_random_wr->random_wr_payload[0].reg_addr;
- map[num_map].page.addr_type = i2c_random_wr->header.addr_type;
- map[num_map].page.data =
- i2c_random_wr->random_wr_payload[0].reg_data;
- map[num_map].page.data_type = i2c_random_wr->header.data_type;
- map[num_map].page.valid_size = 1;
+ for (cnt = 0; cnt < (i2c_random_wr->header.count);
+ cnt++) {
+ map[*num_map + cnt].page.addr =
+ i2c_random_wr->random_wr_payload[cnt].reg_addr;
+ map[*num_map + cnt].page.addr_type =
+ i2c_random_wr->header.addr_type;
+ map[*num_map + cnt].page.data =
+ i2c_random_wr->random_wr_payload[cnt].reg_data;
+ map[*num_map + cnt].page.data_type =
+ i2c_random_wr->header.data_type;
+ map[*num_map + cnt].page.valid_size = 1;
+ }
+
+ *num_map += (i2c_random_wr->header.count - 1);
cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
processed_size +=
cmd_length_in_bytes;
@@ -442,30 +454,62 @@
i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
- map[num_map].mem.addr = i2c_cont_rd->reg_addr;
- map[num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
- map[num_map].mem.data_type = i2c_cont_rd->header.data_type;
- map[num_map].mem.valid_size =
+ map[*num_map].mem.addr = i2c_cont_rd->reg_addr;
+ map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
+ map[*num_map].mem.data_type = i2c_cont_rd->header.data_type;
+ map[*num_map].mem.valid_size =
i2c_cont_rd->header.count;
cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
processed_size +=
cmd_length_in_bytes;
- data->num_data += map[num_map].mem.valid_size;
+ data->num_data += map[*num_map].mem.valid_size;
break;
case CAMERA_SENSOR_CMD_TYPE_WAIT:
- i2c_poll = (struct cam_cmd_conditional_wait *)cmd_buf;
- cmd_length_in_bytes = sizeof(struct cam_cmd_conditional_wait);
+ if (generic_op_code ==
+ CAMERA_SENSOR_WAIT_OP_HW_UCND ||
+ generic_op_code ==
+ CAMERA_SENSOR_WAIT_OP_SW_UCND) {
+ i2c_uncond_wait =
+ (struct cam_cmd_unconditional_wait *)cmd_buf;
+ cmd_length_in_bytes =
+ sizeof(struct cam_cmd_unconditional_wait);
- map[num_map].poll.addr = i2c_poll->reg_addr;
- map[num_map].poll.addr_type = i2c_poll->addr_type;
- map[num_map].poll.data = i2c_poll->reg_data;
- map[num_map].poll.data_type = i2c_poll->data_type;
- map[num_map].poll.delay = i2c_poll->timeout;
- map[num_map].poll.valid_size = 1;
+ if (*num_map < 1) {
+ CAM_ERR(CAM_EEPROM,
+ "invalid map number, num_map=%d",
+ *num_map);
+ return -EINVAL;
+ }
+
+ /*
+ * Though delay is added all of them, but delay will
+ * be applicable to only one of them as only one of
+ * them will have valid_size set to >= 1.
+ */
+ map[*num_map - 1].mem.delay = i2c_uncond_wait->delay;
+ map[*num_map - 1].page.delay = i2c_uncond_wait->delay;
+ map[*num_map - 1].pageen.delay = i2c_uncond_wait->delay;
+ } else if (generic_op_code ==
+ CAMERA_SENSOR_WAIT_OP_COND) {
+ i2c_poll = (struct cam_cmd_conditional_wait *)cmd_buf;
+ cmd_length_in_bytes =
+ sizeof(struct cam_cmd_conditional_wait);
+
+ map[*num_map].poll.addr = i2c_poll->reg_addr;
+ map[*num_map].poll.addr_type = i2c_poll->addr_type;
+ map[*num_map].poll.data = i2c_poll->reg_data;
+ map[*num_map].poll.data_type = i2c_poll->data_type;
+ map[*num_map].poll.delay = i2c_poll->timeout;
+ map[*num_map].poll.valid_size = 1;
+ }
+ cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
+ processed_size +=
+ cmd_length_in_bytes;
break;
default:
break;
}
+
*cmd_length_bytes = processed_size;
return rc;
}
@@ -536,8 +580,8 @@
switch (cmm_hdr->cmd_type) {
case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
- num_map++;
- map[num_map].saddr = i2c_info->slave_addr;
+ /* Configure the following map slave address */
+ map[num_map + 1].saddr = i2c_info->slave_addr;
rc = cam_eeprom_update_slaveInfo(e_ctrl,
cmd_buf);
cmd_length_in_bytes =
@@ -545,7 +589,6 @@
processed_cmd_buf_in_bytes +=
cmd_length_in_bytes;
cmd_buf += cmd_length_in_bytes/4;
- e_ctrl->cal_data.num_map = num_map + 1;
break;
case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN:
@@ -564,10 +607,11 @@
case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
case CAMERA_SENSOR_CMD_TYPE_WAIT:
+ num_map++;
rc = cam_eeprom_parse_memory_map(
&e_ctrl->cal_data, cmd_buf,
total_cmd_buf_in_bytes,
- &cmd_length_in_bytes, num_map);
+ &cmd_length_in_bytes, &num_map);
processed_cmd_buf_in_bytes +=
cmd_length_in_bytes;
cmd_buf += cmd_length_in_bytes/4;
@@ -576,6 +620,7 @@
break;
}
}
+ e_ctrl->cal_data.num_map = num_map + 1;
}
return rc;
}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index 55da264..c977fc4 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -17,7 +17,7 @@
#include "cam_res_mgr_api.h"
int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
- enum cam_flash_state state)
+ bool regulator_enable)
{
int rc = 0;
@@ -26,7 +26,7 @@
return -EINVAL;
}
- if ((state == CAM_FLASH_STATE_START) &&
+ if (regulator_enable &&
(flash_ctrl->is_regulator_enabled == false)) {
rc = qpnp_flash_led_prepare(flash_ctrl->switch_trigger,
ENABLE_REGULATOR, NULL);
@@ -37,7 +37,7 @@
}
flash_ctrl->is_regulator_enabled = true;
flash_ctrl->flash_state = CAM_FLASH_STATE_START;
- } else if ((state == CAM_FLASH_STATE_STOP) &&
+ } else if ((!regulator_enable) &&
(flash_ctrl->is_regulator_enabled == true)) {
rc = qpnp_flash_led_prepare(flash_ctrl->switch_trigger,
DISABLE_REGULATOR, NULL);
@@ -323,18 +323,13 @@
rc);
goto nrt_del_req;
}
- fctrl->flash_state =
- CAM_FLASH_STATE_LOW;
} else if (flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_OFF) {
- if (fctrl->flash_state ==
- CAM_FLASH_STATE_LOW) {
- rc = cam_flash_off(fctrl);
- if (rc)
- CAM_ERR(CAM_FLASH,
- "LED off failed: %d",
- rc);
- }
+ rc = cam_flash_off(fctrl);
+ if (rc)
+ CAM_ERR(CAM_FLASH,
+ "LED off failed: %d",
+ rc);
}
} else if (fctrl->nrt_info.cmn_attr.cmd_type ==
CAMERA_SENSOR_FLASH_CMD_TYPE_RER) {
@@ -360,8 +355,6 @@
"Fire Torch Failed");
goto nrt_del_req;
}
- fctrl->flash_state =
- CAM_FLASH_STATE_LOW;
usleep_range(
flash_data->led_on_delay_ms * 1000,
@@ -398,7 +391,6 @@
rc);
goto apply_setting_err;
}
- fctrl->flash_state = CAM_FLASH_STATE_HIGH;
}
} else if ((flash_data->opcode ==
CAMERA_SENSOR_FLASH_OP_FIRELOW) &&
@@ -413,19 +405,15 @@
rc);
goto apply_setting_err;
}
- fctrl->flash_state = CAM_FLASH_STATE_LOW;
}
} else if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) &&
(flash_data->cmn_attr.is_settings_valid) &&
(flash_data->cmn_attr.request_id == req_id)) {
- if ((fctrl->flash_state == CAM_FLASH_STATE_LOW) ||
- (fctrl->flash_state == CAM_FLASH_STATE_HIGH)) {
- rc = cam_flash_off(fctrl);
- if (rc) {
- CAM_ERR(CAM_FLASH,
- "Flash off failed %d", rc);
- goto apply_setting_err;
- }
+ rc = cam_flash_off(fctrl);
+ if (rc) {
+ CAM_ERR(CAM_FLASH,
+ "Flash off failed %d", rc);
+ goto apply_setting_err;
}
} else {
CAM_DBG(CAM_FLASH, "NOP opcode: req_id: %u", req_id);
@@ -553,6 +541,13 @@
case CAMERA_SENSOR_FLASH_CMD_TYPE_FIRE: {
CAM_DBG(CAM_FLASH,
"CAMERA_FLASH_CMD_TYPE_OPS case called");
+ if (fctrl->flash_state != CAM_FLASH_STATE_START) {
+ CAM_ERR(CAM_FLASH,
+ "Rxed Update packets without linking");
+ fctrl->per_frame[frame_offset].
+ cmn_attr.is_settings_valid = false;
+ return -EINVAL;
+ }
flash_operation_info =
(struct cam_flash_set_on_off *) cmd_buf;
if (!flash_operation_info) {
@@ -668,6 +663,14 @@
break;
}
case CAM_PKT_NOP_OPCODE: {
+ if (fctrl->flash_state != CAM_FLASH_STATE_START) {
+ CAM_ERR(CAM_FLASH,
+ "Rxed Update packets without linking");
+ fctrl->per_frame[frame_offset].
+ cmn_attr.is_settings_valid = false;
+ return -EINVAL;
+ }
+
CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
csl_packet->header.request_id);
goto update_req_mgr;
@@ -739,9 +742,7 @@
{
int rc = 0, i, j;
- if ((fctrl->flash_state == CAM_FLASH_STATE_LOW) ||
- (fctrl->flash_state == CAM_FLASH_STATE_HIGH))
- cam_flash_off(fctrl);
+ cam_flash_off(fctrl);
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
fctrl->per_frame[i].cmn_attr.request_id = 0;
@@ -760,7 +761,7 @@
if ((fctrl->flash_state == CAM_FLASH_STATE_START) &&
(fctrl->is_regulator_enabled == true)) {
- rc = cam_flash_prepare(fctrl, CAM_FLASH_STATE_STOP);
+ rc = cam_flash_prepare(fctrl, false);
if (rc)
CAM_ERR(CAM_FLASH, "Disable Regulator Failed rc: %d",
rc);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
index d5ea04c..f73409a 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.h
@@ -28,7 +28,7 @@
int cam_flash_flush_request(struct cam_req_mgr_flush_request *flush);
int cam_flash_off(struct cam_flash_ctrl *fctrl);
int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
- enum cam_flash_state state);
+ bool regulator_enable);
void cam_flash_shutdown(struct cam_flash_ctrl *flash_ctrl);
int cam_flash_stop_dev(struct cam_flash_ctrl *flash_ctrl);
int cam_flash_release_dev(struct cam_flash_ctrl *fctrl);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
index 2b371a3..e00d4fd 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.c
@@ -139,7 +139,7 @@
goto release_mutex;
}
- rc = cam_flash_prepare(fctrl, CAM_FLASH_STATE_START);
+ rc = cam_flash_prepare(fctrl, true);
if (rc) {
CAM_ERR(CAM_FLASH,
"Enable Regulator Failed rc = %d", rc);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
index bacf088..a1f8f67 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
@@ -51,9 +51,6 @@
CAM_FLASH_STATE_INIT,
CAM_FLASH_STATE_ACQUIRE,
CAM_FLASH_STATE_START,
- CAM_FLASH_STATE_LOW,
- CAM_FLASH_STATE_HIGH,
- CAM_FLASH_STATE_STOP,
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 97158e4..ec37c84 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -165,6 +165,11 @@
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE: {
+ if (s_ctrl->sensor_state != CAM_SENSOR_START) {
+ CAM_ERR(CAM_SENSOR,
+ "Rxed Update packets without linking");
+ return -EINVAL;
+ }
i2c_reg_settings =
&i2c_data->
per_frame[csl_packet->header.request_id %
@@ -185,6 +190,12 @@
break;
}
case CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP: {
+ if (s_ctrl->sensor_state != CAM_SENSOR_START) {
+ CAM_ERR(CAM_SENSOR,
+ "Rxed Update packets without linking");
+ return -EINVAL;
+ }
+
cam_sensor_update_req_mgr(s_ctrl, csl_packet);
return rc;
}
@@ -1000,7 +1011,6 @@
return rc;
}
}
- i2c_set->is_settings_valid = 0;
}
} else {
offset = req_id % MAX_PER_FRAME_ARRAY;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
index d69ff47..7a6d7fd 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.c
@@ -15,8 +15,8 @@
int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
uint32_t addr, uint16_t data, uint32_t data_mask,
- enum camera_sensor_i2c_type data_type,
enum camera_sensor_i2c_type addr_type,
+ enum camera_sensor_i2c_type data_type,
uint32_t delay_ms)
{
int16_t mask = data_mask & 0xFF;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.h
index f6620c0..ec5ed25 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_io/cam_sensor_io.h
@@ -110,8 +110,8 @@
*/
int32_t camera_io_dev_poll(struct camera_io_master *io_master_info,
uint32_t addr, uint16_t data, uint32_t data_mask,
- enum camera_sensor_i2c_type data_type,
enum camera_sensor_i2c_type addr_type,
+ enum camera_sensor_i2c_type data_type,
uint32_t delay_ms);
#include "cam_sensor_i2c.h"
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index 37784b4..535264d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -421,7 +421,7 @@
if (power_setting[i].seq_type < SENSOR_MCLK ||
power_setting[i].seq_type >= SENSOR_SEQ_TYPE_MAX) {
- CAM_ERR(CAM_SENSOR, "failed: Invalid Seq type\n",
+ CAM_ERR(CAM_SENSOR, "failed: Invalid Seq type: %d",
power_setting[i].seq_type);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c
index f451155..26f2ba1 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.c
@@ -94,43 +94,19 @@
return name;
}
-void cam_debug_log(unsigned int module_id, enum cam_debug_level dbg_level,
- const char *func, const int line, const char *fmt, ...)
+void cam_debug_log(unsigned int module_id, const char *func, const int line,
+ const char *fmt, ...)
{
char str_buffer[STR_BUFFER_MAX_LENGTH];
va_list args;
va_start(args, fmt);
- switch (dbg_level) {
- case CAM_LEVEL_DBG:
- if (debug_mdl & module_id) {
- vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args);
- pr_info("CAM_DBG: %s: %s: %d: %s\n",
- cam_get_module_name(module_id),
- func, line, str_buffer);
- va_end(args);
- }
- break;
- case CAM_LEVEL_ERR:
+ if (debug_mdl & module_id) {
vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args);
- pr_err("CAM_ERR: %s: %s: %d: %s\n",
- cam_get_module_name(module_id), func, line, str_buffer);
+ pr_info("CAM_DBG: %s: %s: %d: %s\n",
+ cam_get_module_name(module_id),
+ func, line, str_buffer);
va_end(args);
- break;
- case CAM_LEVEL_INFO:
- vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args);
- pr_info("CAM_INFO: %s: %s: %d: %s\n",
- cam_get_module_name(module_id), func, line, str_buffer);
- va_end(args);
- break;
- case CAM_LEVEL_WARN:
- vsnprintf(str_buffer, STR_BUFFER_MAX_LENGTH, fmt, args);
- pr_warn("CAM_WARN: %s: %s: %d: %s\n",
- cam_get_module_name(module_id), func, line, str_buffer);
- va_end(args);
- break;
- default:
- break;
}
}
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
index c0160c4..4e97100 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_debug_util.h
@@ -38,13 +38,6 @@
#define STR_BUFFER_MAX_LENGTH 1024
-enum cam_debug_level {
- CAM_LEVEL_INFO,
- CAM_LEVEL_WARN,
- CAM_LEVEL_ERR,
- CAM_LEVEL_DBG,
-};
-
/*
* cam_debug_log()
*
@@ -52,15 +45,14 @@
* respective debug logs
*
* @module_id : Respective Module ID which is calling this function
- * @dbg_level : Debug level from cam_module_debug_level enum entries
* @func : Function which is calling to print logs
* @line : Line number associated with the function which is calling
* to print log
* @fmt : Formatted string which needs to be print in the log
*
*/
-void cam_debug_log(unsigned int module_id, enum cam_debug_level dbg_level,
- const char *func, const int line, const char *fmt, ...);
+void cam_debug_log(unsigned int module_id, const char *func, const int line,
+ const char *fmt, ...);
/*
* cam_get_module_name()
@@ -80,8 +72,8 @@
* @args : Arguments which needs to be print in log
*/
#define CAM_ERR(__module, fmt, args...) \
- cam_debug_log(__module, CAM_LEVEL_ERR, __func__, __LINE__, fmt, ##args)
-
+ pr_err("CAM_ERR: %s: %s: %d " fmt "\n", \
+ cam_get_module_name(__module), __func__, __LINE__, ##args)
/*
* CAM_WARN
* @brief : This Macro will print warning logs
@@ -91,8 +83,8 @@
* @args : Arguments which needs to be print in log
*/
#define CAM_WARN(__module, fmt, args...) \
- cam_debug_log(__module, CAM_LEVEL_WARN, __func__, __LINE__, fmt, ##args)
-
+ pr_warn("CAM_WARN: %s: %s: %d " fmt "\n", \
+ cam_get_module_name(__module), __func__, __LINE__, ##args)
/*
* CAM_INFO
* @brief : This Macro will print Information logs
@@ -102,8 +94,8 @@
* @args : Arguments which needs to be print in log
*/
#define CAM_INFO(__module, fmt, args...) \
- cam_debug_log(__module, CAM_LEVEL_INFO, __func__, __LINE__, fmt, ##args)
-
+ pr_info("CAM_INFO: %s: %s: %d " fmt "\n", \
+ cam_get_module_name(__module), __func__, __LINE__, ##args)
/*
* CAM_DBG
* @brief : This Macro will print debug logs when enabled using GROUP
@@ -113,14 +105,14 @@
* @args : Arguments which needs to be print in log
*/
#define CAM_DBG(__module, fmt, args...) \
- cam_debug_log(__module, CAM_LEVEL_DBG, __func__, __LINE__, fmt, ##args)
+ cam_debug_log(__module, __func__, __LINE__, fmt, ##args)
/*
* CAM_ERR_RATE_LIMIT
* @brief : This Macro will prevent error print logs with ratelimit
*/
#define CAM_ERR_RATE_LIMIT(__module, fmt, args...) \
- pr_err_ratelimited("CAM_ERR: %s: %s: %d" fmt "\n", \
+ pr_err_ratelimited("CAM_ERR: %s: %s: %d " fmt "\n", \
cam_get_module_name(__module), __func__, __LINE__, ##args)
#endif /* _CAM_DEBUG_UTIL_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
index aecce12..30ab075 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_packet_util.c
@@ -211,7 +211,7 @@
rc = cam_mem_get_cpu_buf(cmd_buf->mem_handle, &cpu_addr, &buf_size);
if (rc || !cpu_addr || (buf_size == 0)) {
CAM_ERR(CAM_UTIL, "Failed in Get cpu addr, rc=%d, cpu_addr=%pK",
- rc, cpu_addr);
+ rc, (void *)cpu_addr);
return rc;
}
@@ -219,7 +219,7 @@
CAM_DBG(CAM_UTIL,
"GenericCmdBuffer cpuaddr=%pK, blobptr=%pK, len=%d",
- cpu_addr, blob_ptr, cmd_buf->length);
+ (void *)cpu_addr, (void *)blob_ptr, cmd_buf->length);
len_read = 0;
while (len_read < cmd_buf->length) {
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 07fb944..786107b 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
@@ -132,7 +132,7 @@
uint32_t clk_index, unsigned long clk_rate)
{
if (!soc_info || (clk_index >= soc_info->num_clk) || (clk_rate == 0)) {
- CAM_ERR(CAM_UTIL, "Invalid input params %pK, %d %lld",
+ CAM_ERR(CAM_UTIL, "Invalid input params %pK, %d %lu",
soc_info, clk_index, clk_rate);
return clk_rate;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index dd0c04d..43d17d9 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -1337,7 +1337,23 @@
int sde_rotator_inline_get_dst_pixfmt(struct platform_device *pdev,
u32 src_pixfmt, u32 *dst_pixfmt)
{
- return sde_rot_get_base_tilea5x_pixfmt(src_pixfmt, dst_pixfmt);
+ int rc;
+
+ if (!src_pixfmt || !dst_pixfmt)
+ return -EINVAL;
+
+ rc = sde_rot_get_base_tilea5x_pixfmt(src_pixfmt, dst_pixfmt);
+ if (rc)
+ return rc;
+
+ /*
+ * Currently, NV21 tile is not supported as output; hence,
+ * override with NV12 tile.
+ */
+ if (*dst_pixfmt == SDE_PIX_FMT_Y_CRCB_H2V2_TILE)
+ *dst_pixfmt = SDE_PIX_FMT_Y_CBCR_H2V2_TILE;
+
+ return 0;
}
EXPORT_SYMBOL(sde_rotator_inline_get_dst_pixfmt);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 01aa1e4..c94830a 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -421,6 +421,7 @@
static const u32 sde_hw_rotator_v4_inpixfmts_sbuf[] = {
SDE_PIX_FMT_Y_CBCR_H2V2_P010,
SDE_PIX_FMT_Y_CBCR_H2V2,
+ SDE_PIX_FMT_Y_CRCB_H2V2,
SDE_PIX_FMT_Y_CBCR_H2V2_TP10_UBWC,
SDE_PIX_FMT_Y_CBCR_H2V2_P010_UBWC,
SDE_PIX_FMT_Y_CBCR_H2V2_UBWC,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4c000b7..80914e8 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -5488,8 +5488,9 @@
input_height = inst->prop.height[OUTPUT_PORT];
input_width = inst->prop.width[OUTPUT_PORT];
- if (input_width % 2 != 0 || input_height % 2 != 0 ||
- output_width % 2 != 0 || output_height % 2 != 0) {
+ if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 ||
+ input_height % 2 != 0 || output_width % 2 != 0 ||
+ output_height % 2 != 0)) {
dprintk(VIDC_ERR,
"Height and Width should be even numbers for NV12\n");
dprintk(VIDC_ERR,
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 4c4835d..a1ae681 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1943,7 +1943,7 @@
}
static int __qseecom_process_blocked_on_listener_smcinvoke(
- struct qseecom_command_scm_resp *resp)
+ struct qseecom_command_scm_resp *resp, uint32_t app_id)
{
struct qseecom_registered_listener_list *list_ptr;
int ret = 0;
@@ -1990,9 +1990,18 @@
&ireq, sizeof(ireq),
&continue_resp, sizeof(continue_resp));
if (ret) {
- pr_err("scm_call for continue blocked req for session %d failed, ret %d\n",
- session_id, ret);
- goto exit;
+ /* retry with legacy cmd */
+ qseecom.smcinvoke_support = false;
+ ireq.app_or_session_id = app_id;
+ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
+ &ireq, sizeof(ireq),
+ &continue_resp, sizeof(continue_resp));
+ qseecom.smcinvoke_support = true;
+ if (ret) {
+ pr_err("cont block req for app %d or session %d fail\n",
+ app_id, session_id);
+ goto exit;
+ }
}
resp->result = QSEOS_RESULT_INCOMPLETE;
exit:
@@ -2009,7 +2018,7 @@
resp, ptr_app, data);
else
return __qseecom_process_blocked_on_listener_smcinvoke(
- resp);
+ resp, data->client.app_id);
}
static int __qseecom_reentrancy_process_incomplete_cmd(
struct qseecom_dev_handle *data,
@@ -4790,6 +4799,9 @@
resp.resp_type = desc->ret[1]; /*incomplete:unused;blocked:session_id*/
resp.data = desc->ret[2]; /*listener_id*/
+ dummy_private_data.client.app_id = desc->ret[1];
+ dummy_app_entry.app_id = desc->ret[1];
+
mutex_lock(&app_access_lock);
if (qseecom.qsee_reentrancy_support)
ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c172be9..89edc6d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2320,8 +2320,10 @@
spin_unlock_irqrestore(&host->lock, flags);
remove_wait_queue(&host->wq, &wait);
- if (pm)
+ if (pm) {
+ mmc_host_clk_hold(host);
pm_runtime_get_sync(mmc_dev(host));
+ }
if (host->ops->enable && !stop && host->claim_cnt == 1)
host->ops->enable(host);
@@ -2360,8 +2362,10 @@
mmc_delay(10);
} while (!claimed_host && retry_cnt--);
- if (pm)
+ if (pm) {
+ mmc_host_clk_hold(host);
pm_runtime_get_sync(mmc_dev(host));
+ }
if (host->ops->enable && claimed_host && host->claim_cnt == 1)
host->ops->enable(host);
@@ -2396,6 +2400,7 @@
wake_up(&host->wq);
pm_runtime_mark_last_busy(mmc_dev(host));
pm_runtime_put_autosuspend(mmc_dev(host));
+ mmc_host_clk_release(host);
}
}
EXPORT_SYMBOL(mmc_release_host);
diff --git a/drivers/net/wireless/cnss_utils/cnss_utils.c b/drivers/net/wireless/cnss_utils/cnss_utils.c
index 4955130..77a58c8 100644
--- a/drivers/net/wireless/cnss_utils/cnss_utils.c
+++ b/drivers/net/wireless/cnss_utils/cnss_utils.c
@@ -13,8 +13,10 @@
#define pr_fmt(fmt) "cnss_utils: " fmt
#include <linux/module.h>
+#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/etherdevice.h>
+#include <linux/debugfs.h>
#include <net/cnss_utils.h>
#define CNSS_MAX_CH_NUM 45
@@ -29,6 +31,7 @@
};
#define MAX_NO_OF_MAC_ADDR 4
+#define MAC_PREFIX_LEN 2
struct cnss_wlan_mac_addr {
u8 mac_addr[MAX_NO_OF_MAC_ADDR][ETH_ALEN];
u32 no_of_mac_addr_set;
@@ -50,6 +53,7 @@
struct cnss_wlan_mac_addr wlan_mac_addr;
struct cnss_wlan_mac_addr wlan_der_mac_addr;
enum cnss_utils_cc_src cc_source;
+ struct dentry *root_dentry;
} *cnss_utils_priv;
int cnss_utils_set_wlan_unsafe_channel(struct device *dev,
@@ -317,6 +321,137 @@
}
EXPORT_SYMBOL(cnss_utils_get_cc_source);
+static ssize_t cnss_utils_mac_write(struct file *fp,
+ const char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ struct cnss_utils_priv *priv =
+ ((struct seq_file *)fp->private_data)->private;
+ char buf[128];
+ char *input, *mac_type, *mac_address;
+ u8 *dest_mac;
+ u8 val;
+ const char *delim = " \n";
+ size_t len = 0;
+ char temp[3] = "";
+
+ len = min_t(size_t, count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EINVAL;
+ buf[len] = '\0';
+
+ input = buf;
+
+ mac_type = strsep(&input, delim);
+ if (!mac_type)
+ return -EINVAL;
+ if (!input)
+ return -EINVAL;
+
+ mac_address = strsep(&input, delim);
+ if (!mac_address)
+ return -EINVAL;
+ if (strncmp("0x", mac_address, MAC_PREFIX_LEN)) {
+ pr_err("Invalid MAC prefix\n");
+ return -EINVAL;
+ }
+
+ len = strlen(mac_address);
+ mac_address += MAC_PREFIX_LEN;
+ len -= MAC_PREFIX_LEN;
+ if (len < ETH_ALEN * 2 || len > ETH_ALEN * 2 * MAX_NO_OF_MAC_ADDR ||
+ len % (ETH_ALEN * 2) != 0) {
+ pr_err("Invalid MAC address length %zu\n", len);
+ return -EINVAL;
+ }
+
+ if (!strcmp("provisioned", mac_type)) {
+ dest_mac = &priv->wlan_mac_addr.mac_addr[0][0];
+ priv->wlan_mac_addr.no_of_mac_addr_set = len / (ETH_ALEN * 2);
+ } else if (!strcmp("derived", mac_type)) {
+ dest_mac = &priv->wlan_der_mac_addr.mac_addr[0][0];
+ priv->wlan_der_mac_addr.no_of_mac_addr_set =
+ len / (ETH_ALEN * 2);
+ } else {
+ pr_err("Invalid MAC address type %s\n", mac_type);
+ return -EINVAL;
+ }
+
+ while (len--) {
+ temp[0] = *mac_address++;
+ temp[1] = *mac_address++;
+ if (kstrtou8(temp, 16, &val))
+ return -EINVAL;
+ *dest_mac++ = val;
+ }
+ return count;
+}
+
+static int cnss_utils_mac_show(struct seq_file *s, void *data)
+{
+ u8 mac[6];
+ int i;
+ struct cnss_utils_priv *priv = s->private;
+ struct cnss_wlan_mac_addr *addr = NULL;
+
+ addr = &priv->wlan_mac_addr;
+ if (addr->no_of_mac_addr_set) {
+ seq_puts(s, "\nProvisioned MAC addresseses\n");
+ for (i = 0; i < addr->no_of_mac_addr_set; i++) {
+ ether_addr_copy(mac, addr->mac_addr[i]);
+ seq_printf(s, "MAC_ADDR:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+ }
+ }
+
+ addr = &priv->wlan_der_mac_addr;
+ if (addr->no_of_mac_addr_set) {
+ seq_puts(s, "\nDerived MAC addresseses\n");
+ for (i = 0; i < addr->no_of_mac_addr_set; i++) {
+ ether_addr_copy(mac, addr->mac_addr[i]);
+ seq_printf(s, "MAC_ADDR:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+ }
+ }
+
+ return 0;
+}
+
+static int cnss_utils_mac_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cnss_utils_mac_show, inode->i_private);
+}
+
+static const struct file_operations cnss_utils_mac_fops = {
+ .read = seq_read,
+ .write = cnss_utils_mac_write,
+ .release = single_release,
+ .open = cnss_utils_mac_open,
+ .owner = THIS_MODULE,
+ .llseek = seq_lseek,
+};
+
+static int cnss_utils_debugfs_create(struct cnss_utils_priv *priv)
+{
+ int ret = 0;
+ struct dentry *root_dentry;
+
+ root_dentry = debugfs_create_dir("cnss_utils", NULL);
+
+ if (IS_ERR(root_dentry)) {
+ ret = PTR_ERR(root_dentry);
+ pr_err("Unable to create debugfs %d\n", ret);
+ goto out;
+ }
+ priv->root_dentry = root_dentry;
+ debugfs_create_file("mac_address", 0600, root_dentry, priv,
+ &cnss_utils_mac_fops);
+out:
+ return ret;
+}
+
static int __init cnss_utils_init(void)
{
struct cnss_utils_priv *priv = NULL;
@@ -329,7 +464,7 @@
mutex_init(&priv->unsafe_channel_list_lock);
spin_lock_init(&priv->dfs_nol_info_lock);
-
+ cnss_utils_debugfs_create(priv);
cnss_utils_priv = priv;
return 0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index fb29d00..86d50f6 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1205,25 +1205,25 @@
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 18, 12, 6, 9, IPA_EE_AP } },
+ { 18, 11, 6, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_WLAN2_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 20, 14, 9, 9, IPA_EE_AP } },
+ { 20, 13, 9, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_WLAN3_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 21, 15, 9, 9, IPA_EE_AP } },
+ { 21, 14, 9, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_USB_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 19, 13, 9, 9, IPA_EE_AP } },
+ { 19, 12, 9, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_USB_DPL_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
@@ -1291,19 +1291,19 @@
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 18, 12, 6, 9, IPA_EE_AP } },
+ { 18, 11, 6, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_TEST3_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 20, 14, 9, 9, IPA_EE_AP } },
+ { 20, 13, 9, 9, IPA_EE_AP } },
[IPA_4_0][IPA_CLIENT_TEST4_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 21, 15, 9, 9, IPA_EE_AP } },
+ { 21, 14, 9, 9, IPA_EE_AP } },
/* Dummy consumer (pipe 31) is used in L2TP rt rule */
[IPA_4_0][IPA_CLIENT_DUMMY_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
@@ -1404,7 +1404,7 @@
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 19, 13, 9, 9, IPA_EE_AP } },
+ { 19, 12, 9, 9, IPA_EE_AP } },
[IPA_4_0_MHI][IPA_CLIENT_USB_DPL_CONS] = {
true, IPA_v4_0_MHI_GROUP_DDR,
false,
@@ -1446,13 +1446,13 @@
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 20, 14, 9, 9, IPA_EE_AP } },
+ { 20, 13, 9, 9, IPA_EE_AP } },
[IPA_4_0_MHI][IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS] = {
true, IPA_v4_0_MHI_GROUP_DMA,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 21, 15, 9, 9, IPA_EE_AP } },
+ { 21, 14, 9, 9, IPA_EE_AP } },
[IPA_4_0_MHI][IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
@@ -1477,19 +1477,19 @@
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 18, 12, 6, 9, IPA_EE_AP } },
+ { 18, 11, 6, 9, IPA_EE_AP } },
[IPA_4_0_MHI][IPA_CLIENT_TEST3_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_DDR,
- { 20, 14, 9, 9, IPA_EE_AP } },
+ { 20, 13, 9, 9, IPA_EE_AP } },
[IPA_4_0_MHI][IPA_CLIENT_TEST4_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
false,
IPA_DPS_HPS_SEQ_TYPE_INVALID,
QMB_MASTER_SELECT_PCIE,
- { 21, 15, 9, 9, IPA_EE_AP } },
+ { 21, 14, 9, 9, IPA_EE_AP } },
/* Dummy consumer (pipe 31) is used in L2TP rt rule */
[IPA_4_0_MHI][IPA_CLIENT_DUMMY_CONS] = {
true, IPA_v4_0_GROUP_UL_DL,
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 66d4b10..0444b67 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -2455,8 +2455,14 @@
ret);
goto config_err;
}
+
+ /*
+ * for IPA 4.0 offline charge is not needed and we need to prevent
+ * power collapse until IPA uC is loaded.
+ */
atomic_set(&rmnet_ipa3_ctx->is_initialized, 1);
- if (!atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
+ if (!atomic_read(&rmnet_ipa3_ctx->is_ssr) && ipa3_ctx->ipa_hw_type !=
+ IPA_HW_v4_0) {
/* offline charging mode */
ipa3_proxy_clk_unvote();
}
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index f64e9de..4c0531f 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -33,16 +33,14 @@
#include "wil_platform.h"
#include "msm_11ad.h"
-#define WIGIG_VENDOR (0x1ae9)
-#define WIGIG_DEVICE (0x0310)
-
#define SMMU_BASE 0x20000000 /* Device address range base */
#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE)
#define WIGIG_ENABLE_DELAY 50
#define WIGIG_SUBSYS_NAME "WIGIG"
-#define WIGIG_RAMDUMP_SIZE 0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_SPARROW 0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_TALYN 0x400000 /* maximum ramdump size */
#define WIGIG_DUMP_FORMAT_VER 0x1
#define WIGIG_DUMP_MAGIC_VER_V1 0x57474947
#define VDD_MIN_UV 1028000
@@ -61,6 +59,18 @@
static const char * const gpio_en_name = "qcom,wigig-en";
static const char * const sleep_clk_en_name = "qcom,sleep-clk-en";
+struct wigig_pci {
+ struct pci_device_id pci_dev;
+ u32 ramdump_sz;
+};
+
+static const struct wigig_pci wigig_pci_tbl[] = {
+ { .pci_dev = { PCI_DEVICE(0x1ae9, 0x0310) },
+ .ramdump_sz = WIGIG_RAMDUMP_SIZE_SPARROW},
+ { .pci_dev = { PCI_DEVICE(0x17cb, 0x1201) },
+ .ramdump_sz = WIGIG_RAMDUMP_SIZE_TALYN},
+};
+
struct msm11ad_vreg {
const char *name;
struct regulator *reg;
@@ -113,6 +123,7 @@
void *ramdump_addr;
struct msm_dump_data dump_data;
struct ramdump_device *ramdump_dev;
+ u32 ramdump_size;
/* external vregs and clocks */
struct msm11ad_vreg vdd;
@@ -859,7 +870,7 @@
{
if (ctx->rops.ramdump && ctx->wil_handle) {
int rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
- WIGIG_RAMDUMP_SIZE);
+ ctx->ramdump_size);
if (rc) {
dev_err(ctx->dev, "ramdump failed : %d\n", rc);
return -EINVAL;
@@ -898,7 +909,7 @@
memset(&segment, 0, sizeof(segment));
segment.v_address = ctx->ramdump_addr;
- segment.size = WIGIG_RAMDUMP_SIZE;
+ segment.size = ctx->ramdump_size;
return do_ramdump(ctx->ramdump_dev, &segment, 1);
}
@@ -961,14 +972,14 @@
}
/* register ramdump area */
- ctx->ramdump_addr = kmalloc(WIGIG_RAMDUMP_SIZE, GFP_KERNEL);
+ ctx->ramdump_addr = kmalloc(ctx->ramdump_size, GFP_KERNEL);
if (!ctx->ramdump_addr) {
rc = -ENOMEM;
goto out_rc;
}
ctx->dump_data.addr = virt_to_phys(ctx->ramdump_addr);
- ctx->dump_data.len = WIGIG_RAMDUMP_SIZE;
+ ctx->dump_data.len = ctx->ramdump_size;
dump_entry.id = MSM_DUMP_DATA_WIGIG;
dump_entry.addr = virt_to_phys(&ctx->dump_data);
@@ -1031,8 +1042,9 @@
struct device_node *rc_node;
struct pci_dev *pcidev = NULL;
u32 smmu_mapping[2];
- int rc;
+ int rc, i;
u32 val;
+ bool pcidev_found = false;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -1118,7 +1130,7 @@
rc = msm_11ad_init_vregs(ctx);
if (rc) {
dev_err(ctx->dev, "msm_11ad_init_vregs failed: %d\n", rc);
- goto out_bus_scale;
+ return rc;
}
rc = msm_11ad_enable_vregs(ctx);
if (rc) {
@@ -1161,21 +1173,32 @@
goto out_rc;
}
/* search for PCIE device in our domain */
- do {
- pcidev = pci_get_device(WIGIG_VENDOR, WIGIG_DEVICE, pcidev);
- if (!pcidev)
- break;
+ for (i = 0; i < ARRAY_SIZE(wigig_pci_tbl); ++i) {
+ do {
+ pcidev = pci_get_device(wigig_pci_tbl[i].pci_dev.vendor,
+ wigig_pci_tbl[i].pci_dev.device,
+ pcidev);
+ if (!pcidev)
+ break;
- if (pci_domain_nr(pcidev->bus) == ctx->rc_index)
+ if (pci_domain_nr(pcidev->bus) == ctx->rc_index) {
+ ctx->ramdump_size = wigig_pci_tbl[i].ramdump_sz;
+ pcidev_found = true;
+ break;
+ }
+ } while (true);
+
+ if (pcidev_found)
break;
- } while (true);
- if (!pcidev) {
+ }
+ if (!pcidev_found) {
rc = -ENODEV;
- dev_err(ctx->dev, "Wigig device %4x:%4x not found\n",
- WIGIG_VENDOR, WIGIG_DEVICE);
+ dev_err(ctx->dev, "Wigig device not found\n");
goto out_rc;
}
ctx->pcidev = pcidev;
+ dev_dbg(ctx->dev, "Wigig device %4x:%4x found\n",
+ ctx->pcidev->vendor, ctx->pcidev->device);
rc = msm_pcie_pm_control(MSM_PCIE_RESUME, pcidev->bus->number,
pcidev, NULL, 0);
@@ -1267,8 +1290,6 @@
msm_11ad_release_clocks(ctx);
msm_11ad_disable_vregs(ctx);
msm_11ad_release_vregs(ctx);
-out_bus_scale:
- msm_bus_cl_clear_pdata(ctx->bus_scale);
return rc;
}
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index bca4be3..1e5e136 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -687,6 +687,7 @@
vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0);
vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
+ vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, false, 0);
cancel_delayed_work_sync(&chg->hvdcp_detect_work);
@@ -1461,14 +1462,18 @@
if (!chg->usb_icl_votable) {
chg->usb_icl_votable = find_votable("USB_ICL");
- if (!chg->usb_icl_votable)
- return -EINVAL;
+ if (!chg->usb_icl_votable) {
+ rc = -EINVAL;
+ goto unlock;
+ }
}
vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, true, 0);
rc = _smblib_vbus_regulator_enable(rdev);
if (rc >= 0)
chg->otg_en = true;
+ else
+ vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, false, 0);
unlock:
mutex_unlock(&chg->otg_oc_lock);
@@ -4072,6 +4077,7 @@
vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0);
vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
+ vote(chg->usb_icl_votable, USBIN_USBIN_BOOST_VOTER, false, 0);
chg->vconn_attempts = 0;
chg->otg_attempts = 0;
chg->pulse_cnt = 0;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e463117..1f60635 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4184,6 +4184,7 @@
debugfs_remove_recursive(rdev->debugfs);
if (rdev->debug_consumer)
rdev->debug_consumer->debugfs = NULL;
+ rdev->debugfs = NULL;
regulator_put(rdev->debug_consumer);
}
}
@@ -4225,9 +4226,10 @@
regulator = regulator_get(NULL, rdev_get_name(rdev));
if (IS_ERR(regulator)) {
- debugfs_remove_recursive(rdev->debugfs);
- rdev_err(rdev, "regulator get failed, ret=%ld\n",
- PTR_ERR(regulator));
+ rdev_deinit_debugfs(rdev);
+ if (PTR_ERR(regulator) != -EPROBE_DEFER)
+ rdev_err(rdev, "regulator get failed, ret=%ld\n",
+ PTR_ERR(regulator));
return;
}
rdev->debug_consumer = regulator;
diff --git a/drivers/soc/qcom/pil-q6v5-mss.c b/drivers/soc/qcom/pil-q6v5-mss.c
index 2ca0615..728a68c 100644
--- a/drivers/soc/qcom/pil-q6v5-mss.c
+++ b/drivers/soc/qcom/pil-q6v5-mss.c
@@ -60,9 +60,6 @@
strlcpy(reason, smem_reason, min(size, MAX_SSR_REASON_LEN));
pr_err("modem subsystem failure reason: %s.\n", reason);
-
- smem_reason[0] = '\0';
- wmb();
}
static void restart_modem(struct modem_data *drv)
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index 86f314a..b7472a4 100644
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -471,7 +471,7 @@
case QBT1000_SEND_TZCMD:
{
struct qbt1000_send_tz_cmd tzcmd;
- void *rsp_buf;
+ void *rsp_buf = NULL;
if (copy_from_user(&tzcmd, priv_arg,
sizeof(tzcmd))
@@ -861,8 +861,8 @@
static irqreturn_t qbt1000_ipc_irq_handler(int irq, void *dev_id)
{
uint8_t *msg_buffer;
- struct fw_ipc_cmd *rx_cmd;
- struct fw_ipc_header *header;
+ struct fw_ipc_cmd *rx_cmd = NULL;
+ struct fw_ipc_header *header = NULL;
int i, j;
uint32_t rxipc = FP_APP_CMD_RX_IPC;
struct qbt1000_drvdata *drvdata = (struct qbt1000_drvdata *)dev_id;
diff --git a/drivers/soc/qcom/service-notifier.c b/drivers/soc/qcom/service-notifier.c
index f4c67f1..dc45b20 100644
--- a/drivers/soc/qcom/service-notifier.c
+++ b/drivers/soc/qcom/service-notifier.c
@@ -105,6 +105,7 @@
struct work_struct ind_ack;
struct work_struct qmi_handle_free;
struct workqueue_struct *svc_event_wq;
+ struct rw_semaphore qmi_client_handle_rwlock;
struct qmi_handle *clnt_handle;
struct notifier_block notifier;
void *ssr_handle;
@@ -115,7 +116,6 @@
};
static LIST_HEAD(qmi_client_list);
static DEFINE_MUTEX(qmi_list_lock);
-static DEFINE_MUTEX(qmi_client_release_lock);
static DEFINE_MUTEX(notif_add_lock);
@@ -128,11 +128,11 @@
struct qmi_client_info *data = container_of(work,
struct qmi_client_info, qmi_handle_free);
- mutex_lock(&qmi_client_release_lock);
+ down_write(&data->qmi_client_handle_rwlock);
data->service_connected = false;
qmi_handle_destroy(data->clnt_handle);
data->clnt_handle = NULL;
- mutex_unlock(&qmi_client_release_lock);
+ up_write(&data->qmi_client_handle_rwlock);
}
static struct service_notif_info *_find_service_info(const char *service_path)
@@ -170,10 +170,12 @@
struct qmi_client_info *data = container_of(work,
struct qmi_client_info, svc_rcv_msg);
+ down_read(&data->qmi_client_handle_rwlock);
do {
pr_debug("Polling for QMI recv msg(instance-id: %d)\n",
data->instance_id);
} while ((ret = qmi_recv_msg(data->clnt_handle)) == 0);
+ up_read(&data->qmi_client_handle_rwlock);
pr_debug("Notified about a Receive event (instance-id: %d)\n",
data->instance_id);
@@ -237,9 +239,11 @@
resp_desc.max_msg_len = SERVREG_NOTIF_SET_ACK_RESP_MSG_LEN;
resp_desc.ei_array = qmi_servreg_notif_set_ack_resp_msg_v01_ei;
+ down_read(&data->qmi_client_handle_rwlock);
rc = qmi_send_req_wait(data->clnt_handle, &req_desc,
&req, sizeof(req), &resp_desc, &resp,
sizeof(resp), SERVER_TIMEOUT);
+ up_read(&data->qmi_client_handle_rwlock);
if (rc < 0) {
pr_err("%s: Sending Ack failed/server timeout, ret - %d\n",
data->ind_msg.service_path, rc);
@@ -308,9 +312,11 @@
resp_desc.ei_array =
qmi_servreg_notif_register_listener_resp_msg_v01_ei;
+ down_read(&data->qmi_client_handle_rwlock);
rc = qmi_send_req_wait(data->clnt_handle, &req_desc, &req, sizeof(req),
&resp_desc, &resp, sizeof(resp),
SERVER_TIMEOUT);
+ up_read(&data->qmi_client_handle_rwlock);
if (rc < 0) {
pr_err("%s: Message sending failed/server timeout, ret - %d\n",
service_notif->service_path, rc);
@@ -349,13 +355,13 @@
int rc;
int curr_state;
- mutex_lock(&qmi_client_release_lock);
+ down_read(&data->qmi_client_handle_rwlock);
/* Create a Local client port for QMI communication */
data->clnt_handle = qmi_handle_create(root_service_clnt_notify, work);
if (!data->clnt_handle) {
pr_err("QMI client handle alloc failed (instance-id: %d)\n",
data->instance_id);
- mutex_unlock(&qmi_client_release_lock);
+ up_read(&data->qmi_client_handle_rwlock);
return;
}
@@ -368,11 +374,11 @@
data->instance_id, rc);
qmi_handle_destroy(data->clnt_handle);
data->clnt_handle = NULL;
- mutex_unlock(&qmi_client_release_lock);
+ up_read(&data->qmi_client_handle_rwlock);
return;
}
data->service_connected = true;
- mutex_unlock(&qmi_client_release_lock);
+ up_read(&data->qmi_client_handle_rwlock);
pr_info("Connection established between QMI handle and %d service\n",
data->instance_id);
/* Register for indication messages about service */
@@ -554,6 +560,7 @@
}
qmi_data->instance_id = instance_id;
+ init_rwsem(&qmi_data->qmi_client_handle_rwlock);
qmi_data->clnt_handle = NULL;
qmi_data->notifier.notifier_call = service_event_notify;
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index 5b600f6..01b4790 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -857,9 +857,6 @@
strlcpy(reason, smem_reason, min(size, MAX_SSR_REASON_LEN));
pr_err("%s subsystem failure reason: %s.\n", name, reason);
-
- smem_reason[0] = '\0';
- wmb();
}
static int subsys_shutdown(const struct subsys_desc *subsys, bool force_stop)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 7aaf08b..186e7ae 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -230,8 +230,8 @@
u32 cpha = geni_read_reg(mas->base, SE_SPI_CPHA);
u32 demux_sel = 0;
u32 demux_output_inv = 0;
- u32 clk_sel = geni_read_reg(mas->base, SE_GENI_CLK_SEL);
- u32 m_clk_cfg = geni_read_reg(mas->base, GENI_SER_M_CLK_CFG);
+ u32 clk_sel = 0;
+ u32 m_clk_cfg = 0;
int ret = 0;
int idx;
int div;
@@ -884,8 +884,8 @@
/* Speed and bits per word can be overridden per transfer */
if (xfer->speed_hz != mas->cur_speed_hz) {
int ret = 0;
- u32 clk_sel = geni_read_reg(mas->base, SE_GENI_CLK_SEL);
- u32 m_clk_cfg = geni_read_reg(mas->base, GENI_SER_M_CLK_CFG);
+ u32 clk_sel = 0;
+ u32 m_clk_cfg = 0;
int idx = 0;
int div = 0;
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 89c1681..67a71ba 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -493,6 +493,7 @@
} else {
pm_runtime_get_noresume(uport->dev);
pm_runtime_set_active(uport->dev);
+ enable_irq(uport->irq);
}
pm_runtime_enable(uport->dev);
if (lock)
@@ -2576,7 +2577,8 @@
SE_UART_MANUAL_RFR);
/* Ensure that the Rx is running before enabling interrupts */
mb();
- enable_irq(port->uport.irq);
+ if (pm_runtime_enabled(dev))
+ enable_irq(port->uport.irq);
IPC_LOG_MSG(port->ipc_log_pwr, "%s:\n", __func__);
exit_runtime_resume:
return ret;
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index a5e050a..64ed834 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1243,7 +1243,7 @@
dwc->dwc_wq = alloc_ordered_workqueue("dwc_wq", WQ_HIGHPRI);
if (!dwc->dwc_wq) {
pr_err("%s: Unable to create workqueue dwc_wq\n", __func__);
- return -ENOMEM;
+ goto err0;
}
INIT_WORK(&dwc->bh_work, dwc3_bh_work);
@@ -1290,7 +1290,7 @@
ret = dwc3_core_init_mode(dwc);
if (ret)
- goto err0;
+ goto err1;
ret = dwc3_debugfs_init(dwc);
if (ret) {
@@ -1312,6 +1312,8 @@
err_core_init:
dwc3_core_exit_mode(dwc);
+err1:
+ destroy_workqueue(dwc->dwc_wq);
err0:
/*
* restore res->start back to its original value so that, in case the
@@ -1319,7 +1321,6 @@
* memory region the next time probe is called.
*/
res->start -= DWC3_GLOBALS_REGS_START;
- destroy_workqueue(dwc->dwc_wq);
return ret;
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 5571374..51504b0 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -989,7 +989,7 @@
*/
if (speed == USB_SPEED_HIGH) {
struct usb_ep *ep = &dep->endpoint;
- unsigned int mult = ep->mult - 1;
+ unsigned int mult = 2;
unsigned int maxp;
maxp = usb_endpoint_maxp(ep->desc) & 0x07ff;
@@ -1058,6 +1058,9 @@
{
u8 tmp = index;
+ if (!dep->trb_pool)
+ return NULL;
+
if (!tmp)
tmp = DWC3_TRB_NUM - 1;
@@ -1163,7 +1166,7 @@
static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
{
struct dwc3_gadget_ep_cmd_params params;
- struct dwc3_request *req;
+ struct dwc3_request *req, *req1, *n;
struct dwc3 *dwc = dep->dwc;
int starting;
int ret;
@@ -1193,6 +1196,30 @@
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
if (ret < 0) {
+ if ((ret == -EAGAIN) && starting &&
+ usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+ /* If bit13 in Command complete event is set, software
+ * must issue ENDTRANDFER command and wait for
+ * Xfernotready event to queue the requests again.
+ */
+ if (!dep->resource_index) {
+ dep->resource_index =
+ dwc3_gadget_ep_get_transfer_index(dep);
+ WARN_ON_ONCE(!dep->resource_index);
+ }
+ dwc3_stop_active_transfer(dwc, dep->number, true);
+
+ list_for_each_entry_safe_reverse(req1, n,
+ &dep->started_list, list) {
+ req1->trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
+ req1->trb = NULL;
+ dwc3_gadget_move_pending_list_front(req1);
+ dwc3_ep_inc_deq(dep);
+ }
+
+ return ret;
+ }
+
/*
* FIXME we need to iterate over the list of requests
* here and stop, unmap, free and del each of the linked
@@ -1240,7 +1267,7 @@
* Schedule the first trb for one interval in the future or at
* least 4 microframes.
*/
- uf = cur_uf + max_t(u32, 4, dep->interval);
+ uf = cur_uf + max_t(u32, 16, dep->interval);
ret = __dwc3_gadget_kick_transfer(dep, uf);
if (ret < 0)
@@ -1570,7 +1597,11 @@
else
trb = &dwc->ep0_trb[dep->trb_enqueue];
- transfer_in_flight = trb->ctrl & DWC3_TRB_CTRL_HWO;
+ if (trb)
+ transfer_in_flight = trb->ctrl & DWC3_TRB_CTRL_HWO;
+ else
+ transfer_in_flight = false;
+
started = !list_empty(&dep->started_list);
if (!protocol && ((dep->direction && transfer_in_flight) ||
@@ -2638,6 +2669,9 @@
unsigned actual;
int chain;
+ if (req->trb->ctrl & DWC3_TRB_CTRL_HWO)
+ return 0;
+
length = req->request.length;
chain = req->num_pending_sgs > 0;
if (chain) {
@@ -2696,18 +2730,17 @@
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
list_empty(&dep->started_list)) {
- if (list_empty(&dep->pending_list)) {
+ if (list_empty(&dep->pending_list))
/*
* If there is no entry in request list then do
* not issue END TRANSFER now. Just set PENDING
* flag, so that END TRANSFER is issued when an
* entry is added into request list.
*/
- dep->flags = DWC3_EP_PENDING_REQUEST;
- } else {
+ dep->flags |= DWC3_EP_PENDING_REQUEST;
+ else
dwc3_stop_active_transfer(dwc, dep->number, true);
- dep->flags = DWC3_EP_ENABLED;
- }
+ dep->flags &= ~DWC3_EP_MISSED_ISOC;
return 1;
}
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 8d0a5eb..25d8d8f 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -68,6 +68,14 @@
return list_first_entry(list, struct dwc3_request, list);
}
+static inline void dwc3_gadget_move_pending_list_front(struct dwc3_request *req)
+{
+ struct dwc3_ep *dep = req->dep;
+
+ req->started = false;
+ list_move(&req->list, &dep->pending_list);
+}
+
static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
{
struct dwc3_ep *dep = req->dep;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 31b2731..4aee8c8 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -35,6 +35,12 @@
(speed == USB_SPEED_SUPER ?\
SSUSB_GADGET_VBUS_DRAW : CONFIG_USB_GADGET_VBUS_DRAW)
+/* disable LPM by default */
+static bool disable_l1_for_hs = true;
+module_param(disable_l1_for_hs, bool, 0644);
+MODULE_PARM_DESC(disable_l1_for_hs,
+ "Disable support for L1 LPM for HS devices");
+
/**
* struct usb_os_string - represents OS String to be reported by a gadget
* @bLength: total length of the entire descritor, always 0x12
@@ -357,8 +363,11 @@
spin_lock_irqsave(&cdev->lock, flags);
- if (cdev->deactivations == 0)
+ if (cdev->deactivations == 0) {
+ spin_unlock_irqrestore(&cdev->lock, flags);
status = usb_gadget_deactivate(cdev->gadget);
+ spin_lock_irqsave(&cdev->lock, flags);
+ }
if (status == 0)
cdev->deactivations++;
@@ -389,8 +398,11 @@
status = -EINVAL;
else {
cdev->deactivations--;
- if (cdev->deactivations == 0)
+ if (cdev->deactivations == 0) {
+ spin_unlock_irqrestore(&cdev->lock, flags);
status = usb_gadget_activate(cdev->gadget);
+ spin_lock_irqsave(&cdev->lock, flags);
+ }
}
spin_unlock_irqrestore(&cdev->lock, flags);
@@ -1718,10 +1730,10 @@
if (gadget->speed >= USB_SPEED_SUPER) {
cdev->desc.bcdUSB = cpu_to_le16(0x0310);
cdev->desc.bMaxPacketSize0 = 9;
- } else {
+ } else if (!disable_l1_for_hs) {
cdev->desc.bcdUSB = cpu_to_le16(0x0210);
}
- } else if (gadget->l1_supported) {
+ } else if (!disable_l1_for_hs) {
cdev->desc.bcdUSB = cpu_to_le16(0x0210);
DBG(cdev, "Config HS device with LPM(L1)\n");
}
@@ -1755,7 +1767,7 @@
break;
case USB_DT_BOS:
if (gadget_is_superspeed(gadget) ||
- gadget->l1_supported) {
+ !disable_l1_for_hs) {
value = bos_desc(cdev);
value = min(w_length, (u16) value);
}
diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c
index 4cb2817..0e86d28 100644
--- a/drivers/usb/gadget/function/f_cdev.c
+++ b/drivers/usb/gadget/function/f_cdev.c
@@ -48,7 +48,7 @@
#define DEVICE_NAME "at_usb"
#define MODULE_NAME "msm_usb_bridge"
-#define NUM_INSTANCE 2
+#define NUM_INSTANCE 3
#define MAX_CDEV_INST_NAME 15
#define MAX_CDEV_FUNC_NAME 5
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index bdd0dfa..295f681 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -572,7 +572,7 @@
static struct usb_endpoint_descriptor rndis_gsi_fs_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
-
+ .wMaxPacketSize = cpu_to_le16(64),
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
@@ -580,7 +580,7 @@
static struct usb_endpoint_descriptor rndis_gsi_fs_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
-
+ .wMaxPacketSize = cpu_to_le16(64),
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index aea32e4..239d9bf 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -1464,6 +1464,7 @@
mtp_ss_out_comp_desc.bMaxBurst = max_burst;
}
+ fi_mtp->func_inst.f = &dev->function;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full"),
@@ -1475,9 +1476,10 @@
mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct mtp_dev *dev = func_to_mtp(f);
+ struct mtp_instance *fi_mtp;
struct usb_request *req;
int i;
-
+ fi_mtp = container_of(f->fi, struct mtp_instance, func_inst);
mtp_string_defs[INTERFACE_STRING_INDEX].id = 0;
mutex_lock(&dev->read_mutex);
while ((req = mtp_req_get(dev, &dev->tx_idle)))
@@ -1490,6 +1492,7 @@
dev->state = STATE_OFFLINE;
kfree(f->os_desc_table);
f->os_desc_n = 0;
+ fi_mtp->func_inst.f = NULL;
}
static int mtp_function_set_alt(struct usb_function *f,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 5434902..643e087 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -23,6 +23,7 @@
#include <linux/gfp.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
+#include <linux/usb/phy.h>
#include "xhci.h"
#include "xhci-trace.h"
@@ -1065,6 +1066,7 @@
u16 wake_mask = 0;
u16 timeout = 0;
u16 test_mode = 0;
+ enum usb_device_speed s = hcd->self.root_hub->speed;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -1314,6 +1316,10 @@
writel(temp, port_array[wIndex]);
temp = readl(port_array[wIndex]);
+
+ if (s == USB_SPEED_HIGH)
+ usb_phy_start_port_reset(hcd->usb_phy);
+
xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 44ab6d6..0091f41 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -477,6 +477,21 @@
}
EXPORT_SYMBOL(usbpd_get_plug_orientation);
+static unsigned int get_connector_type(struct usbpd *pd)
+{
+ int ret;
+ union power_supply_propval val;
+
+ ret = power_supply_get_property(pd->usb_psy,
+ POWER_SUPPLY_PROP_CONNECTOR_TYPE, &val);
+
+ if (ret) {
+ dev_err(&pd->dev, "Unable to read CONNECTOR TYPE: %d\n", ret);
+ return ret;
+ }
+ return val.intval;
+}
+
static inline void stop_usb_host(struct usbpd *pd)
{
extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 0);
@@ -894,7 +909,7 @@
/* allocate new message if first chunk */
rx_msg = kzalloc(sizeof(*rx_msg) +
PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr),
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!rx_msg)
return NULL;
@@ -947,7 +962,7 @@
pd->rx_ext_msg = rx_msg;
- req = kzalloc(sizeof(*req), GFP_KERNEL);
+ req = kzalloc(sizeof(*req), GFP_ATOMIC);
if (!req)
goto queue_rx; /* return what we have anyway */
@@ -1021,7 +1036,7 @@
PD_MSG_HDR_TYPE(header), PD_MSG_HDR_COUNT(header));
if (!PD_MSG_HDR_IS_EXTENDED(header)) {
- rx_msg = kzalloc(sizeof(*rx_msg) + len, GFP_KERNEL);
+ rx_msg = kzalloc(sizeof(*rx_msg) + len, GFP_ATOMIC);
if (!rx_msg)
return;
@@ -3906,6 +3921,11 @@
goto destroy_wq;
}
+ if (get_connector_type(pd) == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
+ usbpd_dbg(&pd->dev, "USB connector is microAB hence failing pdphy_probe\n");
+ ret = -EINVAL;
+ goto put_psy;
+ }
/*
* associate extcon with the parent dev as it could have a DT
* node which will be useful for extcon_get_edev_by_phandle()
diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c
index 8a4f3d4..2997976 100644
--- a/drivers/usb/pd/qpnp-pdphy.c
+++ b/drivers/usb/pd/qpnp-pdphy.c
@@ -675,7 +675,7 @@
BIST_MODE_MASK | BIST_ENABLE, bist_mode | BIST_ENABLE);
}
-static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
+static irqreturn_t pdphy_msg_rx_irq(int irq, void *data)
{
u8 size, rx_status, frame_type;
u8 buf[32];
@@ -816,8 +816,8 @@
return ret;
ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
- &pdphy->msg_rx_irq, "msg-rx", NULL,
- pdphy_msg_rx_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
+ &pdphy->msg_rx_irq, "msg-rx", pdphy_msg_rx_irq,
+ NULL, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
if (ret < 0)
return ret;
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 81c39a3..cce17e0 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -27,6 +27,7 @@
#include <linux/usb/phy.h>
#include <linux/reset.h>
#include <linux/debugfs.h>
+#include <linux/hrtimer.h>
/* QUSB2PHY_PWR_CTRL1 register related bits */
#define PWR_CTRL1_POWR_DOWN BIT(0)
@@ -126,6 +127,10 @@
u32 sq_ctrl2_default;
bool chirp_disable;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *atest_usb13_suspend;
+ struct pinctrl_state *atest_usb13_active;
+
/* emulation targets specific */
void __iomem *emu_phy_base;
bool emulation;
@@ -139,6 +144,8 @@
/* override TUNEX registers value */
struct dentry *root;
u8 tune[5];
+
+ struct hrtimer timer;
};
static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
@@ -511,6 +518,42 @@
return 0;
}
+static enum hrtimer_restart qusb_dis_ext_pulldown_timer(struct hrtimer *timer)
+{
+ struct qusb_phy *qphy = container_of(timer, struct qusb_phy, timer);
+ int ret = 0;
+
+ if (qphy->pinctrl && qphy->atest_usb13_suspend) {
+ ret = pinctrl_select_state(qphy->pinctrl,
+ qphy->atest_usb13_suspend);
+ if (ret < 0)
+ dev_err(qphy->phy.dev,
+ "pinctrl state suspend select failed\n");
+ }
+
+ return HRTIMER_NORESTART;
+}
+
+static void qusb_phy_enable_ext_pulldown(struct usb_phy *phy)
+{
+ struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
+ int ret = 0;
+
+ dev_dbg(phy->dev, "%s\n", __func__);
+
+ if (qphy->pinctrl && qphy->atest_usb13_active) {
+ ret = pinctrl_select_state(qphy->pinctrl,
+ qphy->atest_usb13_active);
+ if (ret < 0) {
+ dev_err(phy->dev,
+ "pinctrl state active select failed\n");
+ return;
+ }
+
+ hrtimer_start(&qphy->timer, ms_to_ktime(10), HRTIMER_MODE_REL);
+ }
+}
+
static void qusb_phy_shutdown(struct usb_phy *phy)
{
struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
@@ -1082,6 +1125,30 @@
return PTR_ERR(qphy->vdda18);
}
+ qphy->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(qphy->pinctrl)) {
+ ret = PTR_ERR(qphy->pinctrl);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+ dev_err(dev, "pinctrl not available\n");
+ goto skip_pinctrl_config;
+ }
+ qphy->atest_usb13_suspend = pinctrl_lookup_state(qphy->pinctrl,
+ "atest_usb13_suspend");
+ if (IS_ERR(qphy->atest_usb13_suspend)) {
+ dev_err(dev, "pinctrl lookup atest_usb13_suspend failed\n");
+ goto skip_pinctrl_config;
+ }
+
+ qphy->atest_usb13_active = pinctrl_lookup_state(qphy->pinctrl,
+ "atest_usb13_active");
+ if (IS_ERR(qphy->atest_usb13_active))
+ dev_err(dev, "pinctrl lookup atest_usb13_active failed\n");
+
+ hrtimer_init(&qphy->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ qphy->timer.function = qusb_dis_ext_pulldown_timer;
+
+skip_pinctrl_config:
mutex_init(&qphy->lock);
platform_set_drvdata(pdev, qphy);
@@ -1093,6 +1160,7 @@
qphy->phy.notify_connect = qusb_phy_notify_connect;
qphy->phy.notify_disconnect = qusb_phy_notify_disconnect;
qphy->phy.disable_chirp = qusb_phy_disable_chirp;
+ qphy->phy.start_port_reset = qusb_phy_enable_ext_pulldown;
ret = usb_add_phy_dev(&qphy->phy);
if (ret)
diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c
index 2d18faf..fd84889 100644
--- a/drivers/usb/phy/phy-msm-snps-hs.c
+++ b/drivers/usb/phy/phy-msm-snps-hs.c
@@ -74,7 +74,7 @@
#define USB_HSPHY_3P3_HPM_LOAD 16000 /* uA */
#define USB_HSPHY_3P3_VOL_FSHOST 3150000 /* uV */
-#define USB_HSPHY_1P8_VOL_MIN 1800000 /* uV */
+#define USB_HSPHY_1P8_VOL_MIN 1704000 /* uV */
#define USB_HSPHY_1P8_VOL_MAX 1800000 /* uV */
#define USB_HSPHY_1P8_HPM_LOAD 19000 /* uA */
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7d4b557..6cb3a8c 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -276,11 +276,11 @@
goto loop;
end_loop:
- write_unlock(&journal->j_state_lock);
del_timer_sync(&journal->j_commit_timer);
journal->j_task = NULL;
wake_up(&journal->j_wait_done_commit);
jbd_debug(1, "Journal thread exiting.\n");
+ write_unlock(&journal->j_state_lock);
return 0;
}
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index 4a971e2..8ed0ea1 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -600,7 +600,7 @@
static int sdcardfs_permission_wrn(struct inode *inode, int mask)
{
- WARN_RATELIMIT(1, "sdcardfs does not support permission. Use permission2.\n");
+ pr_debug("sdcardfs does not support permission. Use permission2.\n");
return -EINVAL;
}
diff --git a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
index 950811f..7e1394c 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
@@ -65,43 +65,44 @@
#define GCC_MSS_CFG_AHB_CLK 47
#define GCC_MSS_GPLL0_DIV_CLK_SRC 48
#define GCC_MSS_SNOC_AXI_CLK 49
-#define GCC_PCIE_AUX_CLK 50
-#define GCC_PCIE_AUX_PHY_CLK_SRC 51
-#define GCC_PCIE_CFG_AHB_CLK 52
-#define GCC_PCIE_MSTR_AXI_CLK 53
-#define GCC_PCIE_PHY_REFGEN_CLK 54
-#define GCC_PCIE_PHY_REFGEN_CLK_SRC 55
-#define GCC_PCIE_PIPE_CLK 56
-#define GCC_PCIE_SLEEP_CLK 57
-#define GCC_PCIE_SLV_AXI_CLK 58
-#define GCC_PCIE_SLV_Q2A_AXI_CLK 59
-#define GCC_PDM2_CLK 60
-#define GCC_PDM2_CLK_SRC 61
-#define GCC_PDM_AHB_CLK 62
-#define GCC_PDM_XO4_CLK 63
-#define GCC_PRNG_AHB_CLK 64
-#define GCC_SDCC1_AHB_CLK 65
-#define GCC_SDCC1_APPS_CLK 66
-#define GCC_SDCC1_APPS_CLK_SRC 67
-#define GCC_SPMI_FETCHER_AHB_CLK 68
-#define GCC_SPMI_FETCHER_CLK 69
-#define GCC_SPMI_FETCHER_CLK_SRC 70
-#define GCC_SYS_NOC_CPUSS_AHB_CLK 71
-#define GCC_SYS_NOC_USB3_CLK 72
-#define GCC_USB30_MASTER_CLK 73
-#define GCC_USB30_MASTER_CLK_SRC 74
-#define GCC_USB30_MOCK_UTMI_CLK 75
-#define GCC_USB30_MOCK_UTMI_CLK_SRC 76
-#define GCC_USB30_SLEEP_CLK 77
-#define GCC_USB3_PHY_AUX_CLK 78
-#define GCC_USB3_PHY_AUX_CLK_SRC 79
-#define GCC_USB3_PHY_PIPE_CLK 80
-#define GCC_USB_PHY_CFG_AHB2PHY_CLK 81
-#define GPLL0 82
-#define GPLL0_OUT_EVEN 83
-#define GPLL4 84
-#define GPLL4_OUT_EVEN 85
-#define GCC_USB3_PRIM_CLKREF_CLK 86
+#define GCC_PCIE_0_CLKREF_CLK 50
+#define GCC_PCIE_AUX_CLK 51
+#define GCC_PCIE_AUX_PHY_CLK_SRC 52
+#define GCC_PCIE_CFG_AHB_CLK 53
+#define GCC_PCIE_MSTR_AXI_CLK 54
+#define GCC_PCIE_PHY_REFGEN_CLK 55
+#define GCC_PCIE_PHY_REFGEN_CLK_SRC 56
+#define GCC_PCIE_PIPE_CLK 57
+#define GCC_PCIE_SLEEP_CLK 58
+#define GCC_PCIE_SLV_AXI_CLK 59
+#define GCC_PCIE_SLV_Q2A_AXI_CLK 60
+#define GCC_PDM2_CLK 61
+#define GCC_PDM2_CLK_SRC 62
+#define GCC_PDM_AHB_CLK 63
+#define GCC_PDM_XO4_CLK 64
+#define GCC_PRNG_AHB_CLK 65
+#define GCC_SDCC1_AHB_CLK 66
+#define GCC_SDCC1_APPS_CLK 67
+#define GCC_SDCC1_APPS_CLK_SRC 68
+#define GCC_SPMI_FETCHER_AHB_CLK 69
+#define GCC_SPMI_FETCHER_CLK 70
+#define GCC_SPMI_FETCHER_CLK_SRC 71
+#define GCC_SYS_NOC_CPUSS_AHB_CLK 72
+#define GCC_SYS_NOC_USB3_CLK 73
+#define GCC_USB30_MASTER_CLK 74
+#define GCC_USB30_MASTER_CLK_SRC 75
+#define GCC_USB30_MOCK_UTMI_CLK 76
+#define GCC_USB30_MOCK_UTMI_CLK_SRC 77
+#define GCC_USB30_SLEEP_CLK 78
+#define GCC_USB3_PHY_AUX_CLK 79
+#define GCC_USB3_PHY_AUX_CLK_SRC 80
+#define GCC_USB3_PHY_PIPE_CLK 81
+#define GCC_USB3_PRIM_CLKREF_CLK 82
+#define GCC_USB_PHY_CFG_AHB2PHY_CLK 83
+#define GPLL0 84
+#define GPLL0_OUT_EVEN 85
+#define GPLL4 86
+#define GPLL4_OUT_EVEN 87
/* CPU clocks */
#define CLOCK_A7SS 0
diff --git a/include/dt-bindings/msm/msm-bus-ids.h b/include/dt-bindings/msm/msm-bus-ids.h
index ffa4bb0..f43b73b 100644
--- a/include/dt-bindings/msm/msm-bus-ids.h
+++ b/include/dt-bindings/msm/msm-bus-ids.h
@@ -262,7 +262,7 @@
#define MSM_BUS_MASTER_SPMI_FETCHER 151
#define MSM_BUS_MASTER_ANOC_SNOC 152
#define MSM_BUS_MASTER_ANOC_IPA 153
-#define MSM_BUS_MASTER_MASTER_LAST 154
+#define MSM_BUS_MASTER_IPA_PCIE 154
#define MSM_BUS_MASTER_LLCC_DISPLAY 20000
#define MSM_BUS_MASTER_MNOC_HF_MEM_NOC_DISPLAY 20001
@@ -343,10 +343,8 @@
#define MSM_BUS_SNOC_INT_2 10066
#define MSM_BUS_A0NOC_QDSS_INT 10067
#define MSM_BUS_SLAVE_ANOC_PCIE_A1NOC_SNOC 10068
-#define MSM_BUS_INT_LAST 10069
#define MSM_BUS_INT_TEST_ID 20000
-#define MSM_BUS_INT_TEST_LAST 20050
#define MSM_BUS_SLAVE_FIRST 512
#define MSM_BUS_SLAVE_EBI_CH0 512
@@ -607,7 +605,6 @@
#define MSM_BUS_SLAVE_ANOC_IPA 780
#define MSM_BUS_SLAVE_EMAC_CFG 781
#define MSM_BUS_SLAVE_EMMC_CFG 782
-#define MSM_BUS_SLAVE_LAST 783
#define MSM_BUS_SLAVE_EBI_CH0_DISPLAY 20512
#define MSM_BUS_SLAVE_LLCC_DISPLAY 20513
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9b21e2a..907e029 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1164,8 +1164,6 @@
struct address_space *check_mapping; /* Check page->mapping if set */
pgoff_t first_index; /* Lowest page->index to unmap */
pgoff_t last_index; /* Highest page->index to unmap */
- bool ignore_dirty; /* Ignore dirty pages */
- bool check_swap_entries; /* Check also swap entries */
};
struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/linux/sde_rsc.h b/include/linux/sde_rsc.h
index cda2654..d2c1a95 100644
--- a/include/linux/sde_rsc.h
+++ b/include/linux/sde_rsc.h
@@ -186,6 +186,26 @@
int *wait_vblank_crtc_id);
/**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client);
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client: Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client);
+
+/**
* sde_rsc_client_is_state_update_complete() - check if state update is complete
* RSC state transition is not complete until HW receives VBLANK signal. This
* function checks RSC HW to determine whether that signal has been received.
@@ -265,6 +285,18 @@
return 0;
}
+int sde_rsc_client_get_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ return 0;
+}
+
+int sde_rsc_client_reset_vsync_refcount(
+ struct sde_rsc_client *caller_client)
+{
+ return 0;
+}
+
static inline bool sde_rsc_client_is_state_update_complete(
struct sde_rsc_client *caller_client)
{
diff --git a/include/linux/string.h b/include/linux/string.h
index 0463dfb..4691e7f 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -173,9 +173,16 @@
#define __RENAME(x) __asm__(#x)
void fortify_panic(const char *name) __noreturn __cold;
+
+#ifdef CONFIG_FORTIFY_COMPILE_CHECK
void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
+#else
+#define __read_overflow(void) do { } while (0)
+#define __read_overflow2(void) do { } while (0)
+#define __write_overflow(void) do { } while (0)
+#endif
#if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index ddd8f4d..4f56e98 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -520,7 +520,6 @@
unsigned is_selfpowered:1;
unsigned deactivated:1;
unsigned connected:1;
- bool l1_supported;
bool remote_wakeup;
};
#define work_to_gadget(w) (container_of((w), struct usb_gadget, work))
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index 092c32e..742ef8d 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -114,6 +114,8 @@
/* enable/disable VBUS */
int (*set_vbus)(struct usb_phy *x, int on);
+ /* callback to indicate port is being reset or reset the port */
+ void (*start_port_reset)(struct usb_phy *x);
/* effective for B devices, ignored for A-peripheral */
int (*set_power)(struct usb_phy *x,
@@ -213,6 +215,15 @@
return x->set_vbus(x, false);
}
+static inline void
+usb_phy_start_port_reset(struct usb_phy *x)
+{
+ if (!x || !x->start_port_reset)
+ return;
+
+ x->start_port_reset(x);
+}
+
static inline int
usb_phy_reset(struct usb_phy *x)
{
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 1e97498..beddb19 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -27,6 +27,85 @@
__entry->pid, __entry->comm, __entry->oom_score_adj)
);
+TRACE_EVENT(mark_victim,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(wake_reaper,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(start_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(finish_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(skip_task_reaping,
+ TP_PROTO(int pid),
+
+ TP_ARGS(pid),
+
+ TP_STRUCT__entry(
+ __field(int, pid)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ ),
+
+ TP_printk("pid=%d", __entry->pid)
+);
#endif
/* This part must be outside protection */
diff --git a/kernel/compat.c b/kernel/compat.c
index 333d364..1cd7051 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -109,7 +109,7 @@
struct timezone __user *, tz)
{
struct timeval user_tv;
- struct timespec new_ts;
+ struct timespec new_ts = {0};
struct timezone new_tz;
if (tv) {
diff --git a/kernel/fork.c b/kernel/fork.c
index 610aded..b83adf9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -879,7 +879,6 @@
}
if (mm->binfmt)
module_put(mm->binfmt->module);
- set_bit(MMF_OOM_SKIP, &mm->flags);
mmdrop(mm);
}
diff --git a/kernel/time/time.c b/kernel/time/time.c
index bd62fb8..1b2d209 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -194,7 +194,7 @@
struct timezone __user *, tz)
{
struct timeval user_tv;
- struct timespec new_ts;
+ struct timespec new_ts = {0};
struct timezone new_tz;
if (tv) {
diff --git a/mm/internal.h b/mm/internal.h
index 0ee4f54..6aa1c51 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -41,6 +41,11 @@
void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
unsigned long floor, unsigned long ceiling);
+static inline bool can_madv_dontneed_vma(struct vm_area_struct *vma)
+{
+ return !(vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP));
+}
+
void unmap_page_range(struct mmu_gather *tlb,
struct vm_area_struct *vma,
unsigned long addr, unsigned long end,
diff --git a/mm/madvise.c b/mm/madvise.c
index 088a5b22..8b25167 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -25,6 +25,8 @@
#include <asm/tlb.h>
+#include "internal.h"
+
/*
* Any behaviour which results in changes to the vma->vm_flags needs to
* take mmap_sem for writing. Others, which simply traverse vmas, need
@@ -474,7 +476,7 @@
unsigned long start, unsigned long end)
{
*prev = vma;
- if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
+ if (!can_madv_dontneed_vma(vma))
return -EINVAL;
zap_page_range(vma, start, end - start, NULL);
diff --git a/mm/memory.c b/mm/memory.c
index 378ebc0..82d2000 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1154,12 +1154,6 @@
if (!PageAnon(page)) {
if (pte_dirty(ptent)) {
- /*
- * oom_reaper cannot tear down dirty
- * pages
- */
- if (unlikely(details && details->ignore_dirty))
- continue;
force_flush = 1;
set_page_dirty(page);
}
@@ -1179,8 +1173,8 @@
}
continue;
}
- /* only check swap_entries if explicitly asked for in details */
- if (unlikely(details && !details->check_swap_entries))
+ /* If details->check_mapping, we leave swap entries. */
+ if (unlikely(details))
continue;
entry = pte_to_swp_entry(ptent);
diff --git a/mm/mmap.c b/mm/mmap.c
index 6f90f07..7e6c049 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -44,6 +44,7 @@
#include <linux/userfaultfd_k.h>
#include <linux/moduleparam.h>
#include <linux/pkeys.h>
+#include <linux/oom.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
@@ -2983,6 +2984,23 @@
/* Use -1 here to ensure all VMAs in the mm are unmapped */
unmap_vmas(&tlb, vma, 0, -1);
+ set_bit(MMF_OOM_SKIP, &mm->flags);
+ if (unlikely(tsk_is_oom_victim(current))) {
+ /*
+ * Wait for oom_reap_task() to stop working on this
+ * mm. Because MMF_OOM_SKIP is already set before
+ * calling down_read(), oom_reap_task() will not run
+ * on this "mm" post up_write().
+ *
+ * tsk_is_oom_victim() cannot be set from under us
+ * either because current->mm is already set to NULL
+ * under task_lock before calling mmput and oom_mm is
+ * set not NULL by the OOM killer only if current->mm
+ * is found not NULL while holding the task_lock.
+ */
+ down_write(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
+ }
free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
tlb_finish_mmu(&tlb, 0, -1);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 1f13413..af9a8a6 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -470,8 +470,6 @@
{
struct mmu_gather tlb;
struct vm_area_struct *vma;
- struct zap_details details = {.check_swap_entries = true,
- .ignore_dirty = true};
bool ret = true;
/*
@@ -492,6 +490,7 @@
if (!down_read_trylock(&mm->mmap_sem)) {
ret = false;
+ trace_skip_task_reaping(tsk->pid);
goto unlock_oom;
}
@@ -511,15 +510,19 @@
}
/*
- * increase mm_users only after we know we will reap something so
- * that the mmput_async is called only when we have reaped something
- * and delayed __mmput doesn't matter that much
+ * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't
+ * work on the mm anymore. The check for MMF_OOM_SKIP must run
+ * under mmap_sem for reading because it serializes against the
+ * down_write();up_write() cycle in exit_mmap().
*/
- if (!mmget_not_zero(mm)) {
+ if (test_bit(MMF_OOM_SKIP, &mm->flags)) {
up_read(&mm->mmap_sem);
+ trace_skip_task_reaping(tsk->pid);
goto unlock_oom;
}
+ trace_start_task_reaping(tsk->pid);
+
/*
* Tell all users of get_user/copy_from_user etc... that the content
* is no longer stable. No barriers really needed because unmapping
@@ -528,16 +531,8 @@
*/
set_bit(MMF_UNSTABLE, &mm->flags);
- tlb_gather_mmu(&tlb, mm, 0, -1);
for (vma = mm->mmap ; vma; vma = vma->vm_next) {
- if (is_vm_hugetlb_page(vma))
- continue;
-
- /*
- * mlocked VMAs require explicit munlocking before unmap.
- * Let's keep it simple here and skip such VMAs.
- */
- if (vma->vm_flags & VM_LOCKED)
+ if (!can_madv_dontneed_vma(vma))
continue;
/*
@@ -550,11 +545,13 @@
* we do not want to block exit_mmap by keeping mm ref
* count elevated without a good reason.
*/
- if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED))
+ if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) {
+ tlb_gather_mmu(&tlb, mm, vma->vm_start, vma->vm_end);
unmap_page_range(&tlb, vma, vma->vm_start, vma->vm_end,
- &details);
+ NULL);
+ tlb_finish_mmu(&tlb, vma->vm_start, vma->vm_end);
+ }
}
- tlb_finish_mmu(&tlb, 0, -1);
pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
task_pid_nr(tsk), tsk->comm,
K(get_mm_counter(mm, MM_ANONPAGES)),
@@ -562,12 +559,7 @@
K(get_mm_counter(mm, MM_SHMEMPAGES)));
up_read(&mm->mmap_sem);
- /*
- * Drop our reference but make sure the mmput slow path is called from a
- * different context because we shouldn't risk we get stuck there and
- * put the oom_reaper out of the way.
- */
- mmput_async(mm);
+ trace_finish_task_reaping(tsk->pid);
unlock_oom:
mutex_unlock(&oom_lock);
return ret;
@@ -644,6 +636,7 @@
tsk->oom_reaper_list = oom_reaper_list;
oom_reaper_list = tsk;
spin_unlock(&oom_reaper_lock);
+ trace_wake_reaper(tsk->pid);
wake_up(&oom_reaper_wait);
}
@@ -695,6 +688,7 @@
*/
__thaw_task(tsk);
atomic_inc(&oom_victims);
+ trace_mark_victim(tsk->pid);
}
/**
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bcfc58b..baf31df 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7428,10 +7428,10 @@
}
/* Make sure the range is really isolated. */
- if (test_pages_isolated(outer_start, end, false)) {
+ ret = test_pages_isolated(outer_start, end, false);
+ if (ret) {
pr_info_ratelimited("%s: [%lx, %lx) PFNs busy\n",
__func__, outer_start, end);
- ret = -EBUSY;
goto done;
}