Merge "ARM: dts: msm: Define thermal zone for pm8998_tz sensor in PM8998" into msm-4.9
diff --git a/Documentation/devicetree/bindings/arm/msm/cmd-db.txt b/Documentation/devicetree/bindings/arm/msm/cmd-db.txt
index b989d8a..e704d70 100644
--- a/Documentation/devicetree/bindings/arm/msm/cmd-db.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cmd-db.txt
@@ -24,10 +24,12 @@
Value type: <prop-encoded-array>
Definition: First element is the base address of shared memory
Second element is the size of the shared memory region
+ Points to the dictionary address that houses the command DB
+ start address and the size of the command DB region
Example:
qcom,cmd-db@861e0000 {
compatible = "qcom,cmd-db";
- reg = <0x861e0000 0x4000>;
+ reg = <0xc3f000c 0x8>;
}
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index ea828da..bc844de 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -16,6 +16,10 @@
If "halt_base" is in same 4K pages this register then
this will be defined else "halt_q6", "halt_modem",
"halt_nc" is required.
+ "pdc_sync" is the power domain register introduced in
+ sdm845 for power domain of subsystems.
+ If alternative reset is required, "alt_reset" maps to
+ mss_alt_ares.
- interrupts: The modem watchdog interrupt
- vdd_cx-supply: Reference to the regulator that supplies the vdd_cx domain.
- vdd_cx-voltage: Voltage corner/level(max) for cx rail.
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index c32324f..ff2cc3e 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -11,7 +11,8 @@
sdm845-v2-cdp.dtb \
sdm845-qrd.dtb \
sdm845-4k-panel-mtp.dtb \
- sdm845-4k-panel-cdp.dtb
+ sdm845-4k-panel-cdp.dtb \
+ sdm845-4k-panel-qrd.dtb
dtb-$(CONFIG_ARCH_SDM830) += sdm830-sim.dtb \
sdm830-rumi.dtb \
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
index f1501fa..16d2474 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
@@ -61,7 +61,7 @@
reg = <0x15000000 0x80000>,
<0x150c2000 0x20>;
reg-names = "base", "tcu-base";
- #iommu-cells = <1>;
+ #iommu-cells = <2>;
qcom,skip-init;
#global-interrupts = <1>;
#size-cells = <1>;
@@ -339,6 +339,6 @@
* This SID belongs to PCIE. We can't use a fake SID for
* the apps_smmu device.
*/
- iommus = <&apps_smmu 0x1c03>;
+ iommus = <&apps_smmu 0x1c03 0>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
index 4036ce5..655f447 100644
--- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi
@@ -362,7 +362,7 @@
compatible = "qcom,msm-audio-ion";
qcom,smmu-version = <2>;
qcom,smmu-enabled;
- iommus = <&apps_smmu 0x1821>;
+ iommus = <&apps_smmu 0x1821 0x0>;
};
qcom,msm-adsp-loader {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts
new file mode 100644
index 0000000..6171c7b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-qrd.dts
@@ -0,0 +1,23 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm845.dtsi"
+#include "sdm845-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. sdm845 4K Display Panel QRD";
+ compatible = "qcom,sdm845-qrd", "qcom,sdm845", "qcom,qrd";
+ qcom,board-id = <11 1>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
index 9d59a16..69dfe46 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
@@ -17,7 +17,7 @@
#include <dt-bindings/clock/qcom,audio-ext-clk.h>
&msm_audio_ion {
- iommus = <&apps_smmu 0x1821>;
+ iommus = <&apps_smmu 0x1821 0x0>;
qcom,smmu-sid-mask = /bits/ 64 <0xf>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
index 1d471f5..4d0c9b2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
@@ -1305,6 +1305,30 @@
};
};
+ cti_ddr0: cti@69e1000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b969>;
+ reg = <0x69e1000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-name = "coresight-cti-ddr0";
+
+ clocks = <&clock_aop QDSS_CLK>;
+ clock-names = "apb_pclk";
+ };
+
+ cti_ddr1: cti@69e4000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b969>;
+ reg = <0x69e4000 0x1000>;
+ reg-names = "cti-base";
+
+ coresight-name = "coresight-cti-ddr1";
+
+ clocks = <&clock_aop QDSS_CLK>;
+ clock-names = "apb_pclk";
+ };
+
cti0: cti@6010000 {
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index bfbaabb..5e21756 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -248,13 +248,13 @@
clocks = <&clock_gpucc GPU_CC_CX_GMU_CLK>,
- <&clock_gcc GCC_GPU_CFG_AHB_CLK>,
<&clock_gpucc GPU_CC_CXO_CLK>,
<&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
- <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>;
+ <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&clock_gpucc GPU_CC_AHB_CLK>;
- clock-names = "gmu_clk", "ahb_clk", "cxo_clk",
- "axi_clk", "memnoc_clk";
+ clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+ "memnoc_clk", "ahb_clk";
qcom,gmu-pwrlevels {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
index cb5d924..02041af 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
@@ -37,8 +37,8 @@
interrupts = <0 83 0>;
interrupt-controller;
#interrupt-cells = <1>;
- iommus = <&apps_smmu 0x880>, <&apps_smmu 0x888>,
- <&apps_smmu 0xc80>, <&apps_smmu 0xc88>;
+ iommus = <&apps_smmu 0x880 0x0>, <&apps_smmu 0x888 0x0>,
+ <&apps_smmu 0xc80 0x0>, <&apps_smmu 0xc88 0x0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -260,14 +260,14 @@
smmu_rot_unsec: qcom,smmu_rot_unsec_cb {
compatible = "qcom,smmu_sde_rot_unsec";
- iommus = <&apps_smmu 0x1090>;
+ iommus = <&apps_smmu 0x1090 0x0>;
gdsc-mdss-supply = <&hlos1_vote_mmnoc_mmu_tbu_sf_gdsc>;
};
smmu_rot_sec: qcom,smmu_rot_sec_cb {
status = "disabled";
compatible = "qcom,smmu_sde_rot_sec";
- iommus = <&apps_smmu 0x1091>;
+ iommus = <&apps_smmu 0x1091 0x0>;
gdsc-mdss-supply = <&hlos1_vote_mmnoc_mmu_tbu_sf_gdsc>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi b/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
index b9dc816..6f4b4ca 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-vidc.dtsi
@@ -97,9 +97,9 @@
compatible = "qcom,msm-vidc,context-bank";
label = "venus_ns";
iommus =
- <&apps_smmu 0x10a0>,
- <&apps_smmu 0x10a8>,
- <&apps_smmu 0x10b0>;
+ <&apps_smmu 0x10a0 0x0>,
+ <&apps_smmu 0x10a8 0x0>,
+ <&apps_smmu 0x10b0 0x0>;
buffer-types = <0xfff>;
virtual-addr-pool = <0x70800000 0x6f800000>;
};
@@ -108,10 +108,10 @@
compatible = "qcom,msm-vidc,context-bank";
label = "venus_sec_bitstream";
iommus =
- <&apps_smmu 0x10a1>,
- <&apps_smmu 0x10a9>,
- <&apps_smmu 0x10a5>,
- <&apps_smmu 0x10ad>;
+ <&apps_smmu 0x10a1 0x0>,
+ <&apps_smmu 0x10a9 0x0>,
+ <&apps_smmu 0x10a5 0x0>,
+ <&apps_smmu 0x10ad 0x0>;
buffer-types = <0x241>;
virtual-addr-pool = <0x4b000000 0x25800000>;
qcom,secure-context-bank;
@@ -121,8 +121,8 @@
compatible = "qcom,msm-vidc,context-bank";
label = "venus_sec_pixel";
iommus =
- <&apps_smmu 0x10a3>,
- <&apps_smmu 0x10ab>;
+ <&apps_smmu 0x10a3 0x0>,
+ <&apps_smmu 0x10ab 0x0>;
buffer-types = <0x106>;
virtual-addr-pool = <0x25800000 0x25800000>;
qcom,secure-context-bank;
@@ -132,9 +132,9 @@
compatible = "qcom,msm-vidc,context-bank";
label = "venus_sec_non_pixel";
iommus =
- <&apps_smmu 0x10a4>,
- <&apps_smmu 0x10ac>,
- <&apps_smmu 0x10b4>;
+ <&apps_smmu 0x10a4 0x0>,
+ <&apps_smmu 0x10ac 0x0>,
+ <&apps_smmu 0x10b4 0x0>;
buffer-types = <0x480>;
virtual-addr-pool = <0x1000000 0x24800000>;
qcom,secure-context-bank;
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 0eec0d5..87d8a56 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1290,9 +1290,12 @@
<0x1f65000 0x008>,
<0x1f64000 0x008>,
<0x4180000 0x020>,
- <0xc2b0000 0x004>;
+ <0xc2b0000 0x004>,
+ <0xb2e0100 0x004>,
+ <0x4180044 0x004>;
reg-names = "qdsp6_base", "halt_q6", "halt_modem",
- "halt_nc", "rmb_base", "restart_reg";
+ "halt_nc", "rmb_base", "restart_reg",
+ "pdc_sync", "alt_reset";
clocks = <&clock_rpmh RPMH_CXO_CLK>,
<&clock_gcc GCC_MSS_CFG_AHB_CLK>,
@@ -1537,76 +1540,76 @@
qcom,msm_fastrpc_compute_cb1 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1401>,
- <&apps_smmu 0x1421>;
+ iommus = <&apps_smmu 0x1401 0x0>,
+ <&apps_smmu 0x1421 0x0>;
};
qcom,msm_fastrpc_compute_cb2 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1402>,
- <&apps_smmu 0x1422>;
+ iommus = <&apps_smmu 0x1402 0x0>,
+ <&apps_smmu 0x1422 0x0>;
};
qcom,msm_fastrpc_compute_cb3 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1403>,
- <&apps_smmu 0x1423>;
+ iommus = <&apps_smmu 0x1403 0x0>,
+ <&apps_smmu 0x1423 0x0>;
};
qcom,msm_fastrpc_compute_cb4 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1404>,
- <&apps_smmu 0x1424>;
+ iommus = <&apps_smmu 0x1404 0x0>,
+ <&apps_smmu 0x1424 0x0>;
};
qcom,msm_fastrpc_compute_cb5 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1405>,
- <&apps_smmu 0x1425>;
+ iommus = <&apps_smmu 0x1405 0x0>,
+ <&apps_smmu 0x1425 0x0>;
};
qcom,msm_fastrpc_compute_cb6 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1406>,
- <&apps_smmu 0x1426>;
+ iommus = <&apps_smmu 0x1406 0x0>,
+ <&apps_smmu 0x1426 0x0>;
};
qcom,msm_fastrpc_compute_cb7 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1407>,
- <&apps_smmu 0x1427>;
+ iommus = <&apps_smmu 0x1407 0x0>,
+ <&apps_smmu 0x1427 0x0>;
};
qcom,msm_fastrpc_compute_cb8 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
- iommus = <&apps_smmu 0x1408>,
- <&apps_smmu 0x1428>;
+ iommus = <&apps_smmu 0x1408 0x0>,
+ <&apps_smmu 0x1428 0x0>;
};
qcom,msm_fastrpc_compute_cb9 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
qcom,secure-context-bank;
- iommus = <&apps_smmu 0x1409>,
- <&apps_smmu 0x1419>,
- <&apps_smmu 0x1429>;
+ iommus = <&apps_smmu 0x1409 0x0>,
+ <&apps_smmu 0x1419 0x0>,
+ <&apps_smmu 0x1429 0x0>;
};
qcom,msm_fastrpc_compute_cb10 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "cdsprpc-smd";
qcom,secure-context-bank;
- iommus = <&apps_smmu 0x140A>,
- <&apps_smmu 0x141A>,
- <&apps_smmu 0x142A>;
+ iommus = <&apps_smmu 0x140A 0x0>,
+ <&apps_smmu 0x141A 0x0>,
+ <&apps_smmu 0x142A 0x0>;
};
qcom,msm_fastrpc_compute_cb11 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "adsprpc-smd";
- iommus = <&apps_smmu 0x1823>;
+ iommus = <&apps_smmu 0x1823 0x0>;
};
qcom,msm_fastrpc_compute_cb12 {
compatible = "qcom,msm-fastrpc-compute-cb";
label = "adsprpc-smd";
- iommus = <&apps_smmu 0x1824>;
+ iommus = <&apps_smmu 0x1824 0x0>;
};
};
@@ -2301,18 +2304,18 @@
ipa_smmu_ap: ipa_smmu_ap {
compatible = "qcom,ipa-smmu-ap-cb";
- iommus = <&apps_smmu 0x720>;
+ iommus = <&apps_smmu 0x720 0x0>;
qcom,iova-mapping = <0x20000000 0x40000000>;
};
ipa_smmu_wlan: ipa_smmu_wlan {
compatible = "qcom,ipa-smmu-wlan-cb";
- iommus = <&apps_smmu 0x721>;
+ iommus = <&apps_smmu 0x721 0x0>;
};
ipa_smmu_uc: ipa_smmu_uc {
compatible = "qcom,ipa-smmu-uc-cb";
- iommus = <&apps_smmu 0x722>;
+ iommus = <&apps_smmu 0x722 0x0>;
qcom,iova-mapping = <0x40000000 0x20000000>;
};
};
@@ -2356,7 +2359,7 @@
cmd_db: qcom,cmd-db@861e0000 {
compatible = "qcom,cmd-db";
- reg = <0x861e0000 0x4000>;
+ reg = <0xc3f000c 8>;
};
dcc: dcc_v2@10a2000 {
@@ -2379,8 +2382,8 @@
<0xa0000000 0x10000000>,
<0xb0000000 0x10000>;
reg-names = "membase", "smmu_iova_base", "smmu_iova_ipa";
- iommus = <&apps_smmu 0x0040>,
- <&apps_smmu 0x0041>;
+ iommus = <&apps_smmu 0x0040 0x0>,
+ <&apps_smmu 0x0041 0x0>;
interrupts = <0 414 0 /* CE0 */ >,
<0 415 0 /* CE1 */ >,
<0 416 0 /* CE2 */ >,
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index fa6bae8..c5cfa18 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -473,6 +473,7 @@
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_ICNSS=y
CONFIG_QCOM_COMMAND_DB=y
+CONFIG_MSM_ADSP_LOADER=y
CONFIG_MSM_AVTIMER=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 1f0418f..100ca68 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -493,6 +493,7 @@
CONFIG_ICNSS=y
CONFIG_ICNSS_DEBUG=y
CONFIG_QCOM_COMMAND_DB=y
+CONFIG_MSM_ADSP_LOADER=y
CONFIG_MSM_AVTIMER=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_PM=y
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index a95e1e5..f18ae62 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -229,20 +229,22 @@
static int fw_lookup_and_allocate_buf(const char *fw_name,
struct firmware_cache *fwc,
struct firmware_buf **buf, void *dbuf,
- size_t size)
+ size_t size, unsigned int opt_flags)
{
struct firmware_buf *tmp;
spin_lock(&fwc->lock);
- tmp = __fw_lookup_buf(fw_name);
- if (tmp) {
- kref_get(&tmp->ref);
- spin_unlock(&fwc->lock);
- *buf = tmp;
- return 1;
+ if (!(opt_flags & FW_OPT_NOCACHE)) {
+ tmp = __fw_lookup_buf(fw_name);
+ if (tmp) {
+ kref_get(&tmp->ref);
+ spin_unlock(&fwc->lock);
+ *buf = tmp;
+ return 1;
+ }
}
tmp = __allocate_fw_buf(fw_name, fwc, dbuf, size);
- if (tmp)
+ if (tmp && !(opt_flags & FW_OPT_NOCACHE))
list_add(&tmp->list, &fwc->head);
spin_unlock(&fwc->lock);
@@ -1051,7 +1053,8 @@
*/
static int
_request_firmware_prepare(struct firmware **firmware_p, const char *name,
- struct device *device, void *dbuf, size_t size)
+ struct device *device, void *dbuf, size_t size,
+ unsigned int opt_flags)
{
struct firmware *firmware;
struct firmware_buf *buf;
@@ -1069,7 +1072,8 @@
return 0; /* assigned */
}
- ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf, dbuf, size);
+ ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf, dbuf, size,
+ opt_flags);
/*
* bind with 'buf' now to avoid warning in failure path
@@ -1147,7 +1151,8 @@
goto out;
}
- ret = _request_firmware_prepare(&fw, name, device, buf, size);
+ ret = _request_firmware_prepare(&fw, name, device, buf, size,
+ opt_flags);
if (ret <= 0) /* error or already assigned */
goto out;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index beffe35..1b545d6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1709,8 +1709,14 @@
}
}
+ /*
+ * The Fabia PLLs only have 16 bits to program the fractional divider.
+ * Hence the programmed rate might be slightly different than the
+ * requested one.
+ */
if ((core->flags & CLK_SET_RATE_PARENT) && parent &&
- best_parent_rate != parent->rate)
+ (DIV_ROUND_CLOSEST(best_parent_rate, 1000) !=
+ DIV_ROUND_CLOSEST(parent->rate, 1000)))
top = clk_calc_new_rates(parent, best_parent_rate);
out:
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 6ff621d..d15d1bb 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -307,6 +307,15 @@
u64 quotient;
int alpha_bw = ALPHA_BITWIDTH;
+ /*
+ * The PLLs parent rate is zero probably since the parent hasn't
+ * registered yet. Return early with the requested rate.
+ */
+ if (!prate) {
+ pr_debug("PLLs parent rate hasn't been initialized.\n");
+ return rate;
+ }
+
quotient = rate;
remainder = do_div(quotient, prate);
*l = quotient;
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
index 9ce0afc..2cb9d05 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
@@ -1241,7 +1241,7 @@
static struct clk_regmap_mux dsi0pll_byteclk_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi0_phy_pll_out_byteclk",
@@ -1255,7 +1255,7 @@
static struct clk_regmap_mux dsi1pll_byteclk_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi1_phy_pll_out_byteclk",
@@ -1269,7 +1269,7 @@
static struct clk_regmap_mux dsi0pll_pclk_src_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi0pll_pclk_src_mux",
@@ -1284,7 +1284,7 @@
static struct clk_regmap_mux dsi1pll_pclk_src_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi1pll_pclk_src_mux",
@@ -1329,7 +1329,7 @@
static struct clk_regmap_mux dsi0pll_pclk_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi0_phy_pll_out_dsiclk",
@@ -1343,7 +1343,7 @@
static struct clk_regmap_mux dsi1pll_pclk_mux = {
.shift = 0,
- .width = 0,
+ .width = 1,
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "dsi1_phy_pll_out_dsiclk",
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
index d5289c0..6a91a65 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
@@ -109,6 +109,15 @@
#define SDE_INTR_PING_PONG_3_TE_DETECTED BIT(27)
/**
+ * Ctl start interrupt status bit definitions
+ */
+#define SDE_INTR_CTL_0_START BIT(9)
+#define SDE_INTR_CTL_1_START BIT(10)
+#define SDE_INTR_CTL_2_START BIT(11)
+#define SDE_INTR_CTL_3_START BIT(12)
+#define SDE_INTR_CTL_4_START BIT(13)
+
+/**
* Concurrent WB overflow interrupt status bit definitions
*/
#define SDE_INTR_CWB_2_OVERFLOW BIT(14)
@@ -325,15 +334,21 @@
{ SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
{ SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
{ SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 40-43 */
+ /* irq_idx: 40 */
{ SDE_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_S0,
SDE_INTR_PING_PONG_S0_RD_PTR, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- /* irq_idx: 44-47 */
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
- { SDE_IRQ_TYPE_RESERVED, 0, 0, 1},
+ /* irq_idx: 41-45 */
+ { SDE_IRQ_TYPE_CTL_START, CTL_0,
+ SDE_INTR_CTL_0_START, 1},
+ { SDE_IRQ_TYPE_CTL_START, CTL_1,
+ SDE_INTR_CTL_1_START, 1},
+ { SDE_IRQ_TYPE_CTL_START, CTL_2,
+ SDE_INTR_CTL_2_START, 1},
+ { SDE_IRQ_TYPE_CTL_START, CTL_3,
+ SDE_INTR_CTL_3_START, 1},
+ { SDE_IRQ_TYPE_CTL_START, CTL_4,
+ SDE_INTR_CTL_4_START, 1},
+ /* irq_idx: 46-47 */
{ SDE_IRQ_TYPE_CWB_OVERFLOW, CWB_2, SDE_INTR_CWB_2_OVERFLOW, 1},
{ SDE_IRQ_TYPE_CWB_OVERFLOW, CWB_3, SDE_INTR_CWB_3_OVERFLOW, 1},
/* irq_idx: 48-51 */
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
index 7805df1..7991994 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
@@ -55,6 +55,7 @@
* @SDE_IRQ_TYPE_SFI_CMD_2_OUT: DSI CMD2 static frame INTR out-of static
* @SDE_IRQ_TYPE_PROG_LINE: Programmable Line interrupt
* @SDE_IRQ_TYPE_AD4_BL_DONE: AD4 backlight
+ * @SDE_IRQ_TYPE_CTL_START: Control start
* @SDE_IRQ_TYPE_RESERVED: Reserved for expansion
*/
enum sde_intr_type {
@@ -84,6 +85,7 @@
SDE_IRQ_TYPE_SFI_CMD_2_OUT,
SDE_IRQ_TYPE_PROG_LINE,
SDE_IRQ_TYPE_AD4_BL_DONE,
+ SDE_IRQ_TYPE_CTL_START,
SDE_IRQ_TYPE_RESERVED,
};
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_rot.c b/drivers/gpu/drm/msm/sde/sde_hw_rot.c
index 01fe3c8..d15b804 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_rot.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_rot.c
@@ -574,9 +574,16 @@
rot_cmd.video_mode = data->video_mode;
rot_cmd.fps = data->fps;
+
+ /*
+ * DRM rotation property is specified in counter clockwise direction
+ * whereas rotator h/w rotates in clockwise direction.
+ * Convert rotation property to clockwise 90 by toggling h/v flip
+ */
rot_cmd.rot90 = data->rot90;
- rot_cmd.hflip = data->hflip;
- rot_cmd.vflip = data->vflip;
+ rot_cmd.hflip = data->rot90 ? !data->hflip : data->hflip;
+ rot_cmd.vflip = data->rot90 ? !data->vflip : data->vflip;
+
rot_cmd.secure = data->secure;
rot_cmd.clkrate = data->clkrate;
rot_cmd.data_bw = 0;
diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c
index 3618479..1e4f6b1 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.c
+++ b/drivers/gpu/drm/msm/sde_power_handle.c
@@ -841,7 +841,15 @@
goto data_bus_hdl_err;
}
- if (!phandle->rsc_client_init) {
+ /*
+ * - When the target is RSCC enabled, regulator should
+ * be enabled by the s/w only for the first time during
+ * bootup. After that, RSCC hardware takes care of enabling/
+ * disabling it.
+ * - When the target is not RSCC enabled, regulator should
+ * be totally handled by the software.
+ */
+ if (!phandle->rsc_client) {
rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
enable);
if (rc) {
@@ -883,7 +891,7 @@
sde_power_reg_bus_update(phandle->reg_bus_hdl,
max_usecase_ndx);
- if (!phandle->rsc_client_init)
+ if (!phandle->rsc_client)
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
enable);
sde_power_data_bus_update(&phandle->data_bus_handle, enable);
@@ -901,7 +909,7 @@
rsc_err:
sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
reg_bus_hdl_err:
- if (!phandle->rsc_client_init)
+ if (!phandle->rsc_client)
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
vreg_err:
sde_power_data_bus_update(&phandle->data_bus_handle, 0);
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index ed5b714..1cb0259 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1045,6 +1045,13 @@
*/
if (drawctxt->base.flags & KGSL_CONTEXT_NO_FAULT_TOLERANCE)
set_bit(KGSL_FT_DISABLE, &cmdobj->fault_policy);
+ /*
+ * Set the fault tolerance policy to FT_REPLAY - As context wants
+ * to invalidate it after a replay attempt fails. This doesn't
+ * require to execute the default FT policy.
+ */
+ else if (drawctxt->base.flags & KGSL_CONTEXT_INVALIDATE_ON_FAULT)
+ set_bit(KGSL_FT_REPLAY, &cmdobj->fault_policy);
else
cmdobj->fault_policy = adreno_dev->ft_policy;
}
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index f77d438..ab574d8 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -349,6 +349,7 @@
KGSL_CONTEXT_PER_CONTEXT_TS |
KGSL_CONTEXT_USER_GENERATED_TS |
KGSL_CONTEXT_NO_FAULT_TOLERANCE |
+ KGSL_CONTEXT_INVALIDATE_ON_FAULT |
KGSL_CONTEXT_CTX_SWITCH |
KGSL_CONTEXT_PRIORITY_MASK |
KGSL_CONTEXT_TYPE_MASK |
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index d955aa0..db105c5 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -80,6 +80,7 @@
{ KGSL_CONTEXT_PER_CONTEXT_TS, "PER_CONTEXT_TS" }, \
{ KGSL_CONTEXT_USER_GENERATED_TS, "USER_TS" }, \
{ KGSL_CONTEXT_NO_FAULT_TOLERANCE, "NO_FT" }, \
+ { KGSL_CONTEXT_INVALIDATE_ON_FAULT, "INVALIDATE_ON_FAULT" }, \
{ KGSL_CONTEXT_PWR_CONSTRAINT, "PWR" }, \
{ KGSL_CONTEXT_SAVE_GMEM, "SAVE_GMEM" }
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 86d4d61..d635519 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1608,6 +1608,8 @@
ret = PTR_ERR(mmu->defaultpagetable);
mmu->defaultpagetable = NULL;
return ret;
+ } else if (mmu->defaultpagetable == NULL) {
+ return -ENOMEM;
}
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 8bd5d4d..6233b46 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -293,7 +293,7 @@
SDEROT_DBG("core_clk %lu\n", total_clk_rate);
ATRACE_INT("core_clk", total_clk_rate);
- sde_rotator_set_clk_rate(mgr, total_clk_rate, SDE_ROTATOR_CLK_ROT_CORE);
+ sde_rotator_set_clk_rate(mgr, total_clk_rate, SDE_ROTATOR_CLK_MDSS_ROT);
return 0;
}
@@ -406,13 +406,13 @@
if (ret)
goto error_mdss_axi;
ret = sde_rotator_enable_clk(mgr,
- SDE_ROTATOR_CLK_ROT_CORE);
- if (ret)
- goto error_rot_core;
- ret = sde_rotator_enable_clk(mgr,
SDE_ROTATOR_CLK_MDSS_ROT);
if (ret)
goto error_mdss_rot;
+ ret = sde_rotator_enable_clk(mgr,
+ SDE_ROTATOR_CLK_MDSS_ROT_SUB);
+ if (ret)
+ goto error_rot_sub;
/* Active+Sleep */
msm_bus_scale_client_update_context(
@@ -420,8 +420,9 @@
mgr->data_bus.curr_bw_uc_idx);
trace_rot_bw_ao_as_context(0);
} else {
+ sde_rotator_disable_clk(mgr,
+ SDE_ROTATOR_CLK_MDSS_ROT_SUB);
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_ROT);
- sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_ROT_CORE);
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_AXI);
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_AHB);
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_GCC_AXI);
@@ -437,9 +438,9 @@
}
return ret;
+error_rot_sub:
+ sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_ROT);
error_mdss_rot:
- sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_ROT_CORE);
-error_rot_core:
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_AXI);
error_mdss_axi:
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MDSS_AHB);
@@ -550,6 +551,12 @@
if (!input)
dir = DMA_FROM_DEVICE;
+ if (buffer->plane_count > SDE_ROT_MAX_PLANES) {
+ SDEROT_ERR("buffer plane_count exceeds MAX_PLANE limit:%d\n",
+ buffer->plane_count);
+ return -EINVAL;
+ }
+
data->sbuf = buffer->sbuf;
data->scid = buffer->scid;
data->writeback = buffer->writeback;
@@ -2730,11 +2737,19 @@
sde_rotator_search_dt_clk(pdev, mgr, "axi_clk",
SDE_ROTATOR_CLK_MDSS_AXI, true) ||
sde_rotator_search_dt_clk(pdev, mgr, "rot_core_clk",
- SDE_ROTATOR_CLK_ROT_CORE, true) ||
- sde_rotator_search_dt_clk(pdev, mgr, "rot_clk",
- SDE_ROTATOR_CLK_MDSS_ROT, true))
+ SDE_ROTATOR_CLK_MDSS_ROT, false))
rc = -EINVAL;
+ /*
+ * If 'MDSS_ROT' is already present, place 'rot_clk' under
+ * MDSS_ROT_SUB. Otherwise, place it directly into MDSS_ROT.
+ */
+ if (sde_rotator_get_clk(mgr, SDE_ROTATOR_CLK_MDSS_ROT))
+ rc = sde_rotator_search_dt_clk(pdev, mgr, "rot_clk",
+ SDE_ROTATOR_CLK_MDSS_ROT_SUB, true);
+ else
+ rc = sde_rotator_search_dt_clk(pdev, mgr, "rot_clk",
+ SDE_ROTATOR_CLK_MDSS_ROT, true);
clk_err:
return rc;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
index 819f57b..13e7739 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
@@ -125,7 +125,7 @@
enum sde_rotator_clk_type {
SDE_ROTATOR_CLK_MDSS_AHB,
SDE_ROTATOR_CLK_MDSS_AXI,
- SDE_ROTATOR_CLK_ROT_CORE,
+ SDE_ROTATOR_CLK_MDSS_ROT_SUB,
SDE_ROTATOR_CLK_MDSS_ROT,
SDE_ROTATOR_CLK_MNOC_AHB,
SDE_ROTATOR_CLK_GCC_AHB,
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 15ecc10..90b7194 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -438,6 +438,8 @@
{
struct sde_rotator_ctx *ctx = vb2_get_drv_priv(q);
struct sde_rotator_device *rot_dev = ctx->rot_dev;
+ struct sde_rotator_request *request;
+ struct list_head *curr, *next;
int i;
int ret;
@@ -458,6 +460,21 @@
sde_rot_mgr_lock(rot_dev->mgr);
sde_rotator_cancel_all_requests(rot_dev->mgr, ctx->private);
sde_rot_mgr_unlock(rot_dev->mgr);
+ list_for_each_safe(curr, next, &ctx->pending_list) {
+ request = container_of(curr, struct sde_rotator_request,
+ list);
+
+ SDEDEV_DBG(rot_dev->dev, "cancel request s:%d\n",
+ ctx->session_id);
+ mutex_unlock(q->lock);
+ cancel_work_sync(&request->submit_work);
+ cancel_work_sync(&request->retire_work);
+ mutex_lock(q->lock);
+ spin_lock(&ctx->list_lock);
+ list_del_init(&request->list);
+ list_add_tail(&request->list, &ctx->retired_list);
+ spin_unlock(&ctx->list_lock);
+ }
}
sde_rotator_return_all_buffers(q, VB2_BUF_STATE_ERROR);
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 2672f1e..1bab010 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -3082,9 +3082,9 @@
goto error_hw_rev_init;
/* set rotator CBCR to shutoff memory/periphery on clock off.*/
- clk_set_flags(mgr->rot_clk[SDE_ROTATOR_CLK_ROT_CORE].clk,
+ clk_set_flags(mgr->rot_clk[SDE_ROTATOR_CLK_MDSS_ROT].clk,
CLKFLAG_NORETAIN_MEM);
- clk_set_flags(mgr->rot_clk[SDE_ROTATOR_CLK_ROT_CORE].clk,
+ clk_set_flags(mgr->rot_clk[SDE_ROTATOR_CLK_MDSS_ROT].clk,
CLKFLAG_NORETAIN_PERIPH);
mdata->sde_rot_hw = rot;
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 6c49ff5..7215fdf 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -920,6 +920,8 @@
pkt->session_id = hash32_ptr(session);
pkt->num_properties = 1;
+ dprintk(VIDC_DBG, "Setting HAL Property = 0x%x\n", ptype);
+
switch (ptype) {
case HAL_CONFIG_FRAME_RATE:
{
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 3d3b7e9..a86c677 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -23,7 +23,6 @@
#define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS MIN_NUM_CAPTURE_BUFFERS
#define DEFAULT_VIDEO_CONCEAL_COLOR_BLACK 0x8010
#define MB_SIZE_IN_PIXEL (16 * 16)
-#define MAX_OPERATING_FRAME_RATE (300 << 16)
#define OPERATING_FRAME_RATE_STEP (1 << 16)
static const char *const mpeg_video_stream_format[] = {
@@ -360,7 +359,7 @@
.name = "Set Decoder Operating rate",
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
- .maximum = MAX_OPERATING_FRAME_RATE,
+ .maximum = INT_MAX,
.default_value = 0,
.step = OPERATING_FRAME_RATE_STEP,
},
@@ -368,17 +367,6 @@
#define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls)
-static u32 get_frame_size_nv12(int plane,
- u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
-}
-
-static u32 get_frame_size_nv12_ubwc(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
-}
-
static u32 get_frame_size_compressed_full_yuv(int plane,
u32 max_mbs_per_frame, u32 size_per_mb)
{
@@ -391,11 +379,6 @@
return (max_mbs_per_frame * size_per_mb * 3/2)/2;
}
-static u32 get_frame_size_nv12_ubwc_10bit(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
-}
-
static u32 get_frame_size(struct msm_vidc_inst *inst,
const struct msm_vidc_format *fmt,
int fmt_type, int plane)
@@ -446,7 +429,7 @@
.name = "UBWC YCbCr Semiplanar 4:2:0 10bit",
.description = "UBWC Y/CbCr 4:2:0 10bit",
.fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC,
- .get_frame_size = get_frame_size_nv12_ubwc_10bit,
+ .get_frame_size = get_frame_size_tp10_ubwc,
.type = CAPTURE_PORT,
},
{
@@ -681,7 +664,7 @@
inst->bufq[OUTPUT_PORT].num_planes = 1;
inst->bufq[CAPTURE_PORT].num_planes = 1;
inst->prop.fps = DEFAULT_FPS;
- inst->operating_rate = 0;
+ inst->clk_data.operating_rate = 0;
memcpy(&inst->fmts[OUTPUT_PORT], &vdec_formats[2],
sizeof(struct msm_vidc_format));
memcpy(&inst->fmts[CAPTURE_PORT], &vdec_formats[0],
@@ -968,8 +951,12 @@
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
dprintk(VIDC_DBG,
"inst(%pK) operating rate changed from %d to %d\n",
- inst, inst->operating_rate >> 16, ctrl->val >> 16);
- inst->operating_rate = ctrl->val;
+ inst, inst->clk_data.operating_rate >> 16,
+ ctrl->val >> 16);
+ inst->clk_data.operating_rate = ctrl->val;
+
+ msm_vidc_update_operating_rate(inst);
+
break;
default:
break;
@@ -980,8 +967,8 @@
if (!rc && property_id) {
dprintk(VIDC_DBG,
- "Control: HAL property=%#x,ctrl: id=%#x,value=%#x\n",
- property_id, ctrl->id, ctrl->val);
+ "Control: Name = %s, ID = 0x%x Value = %d\n",
+ ctrl->name, ctrl->id, ctrl->val);
rc = call_hfi_op(hdev, session_set_property, (void *)
inst->session, property_id, pdata);
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 91d657d..19a21ab 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -23,7 +23,6 @@
#define DEFAULT_BIT_RATE 64000
#define BIT_RATE_STEP 100
#define DEFAULT_FRAME_RATE 15
-#define MAX_OPERATING_FRAME_RATE (300 << 16)
#define OPERATING_FRAME_RATE_STEP (1 << 16)
#define MAX_SLICE_BYTE_SIZE ((MAX_BIT_RATE)>>3)
#define MIN_SLICE_BYTE_SIZE 512
@@ -878,7 +877,7 @@
.name = "Set Encoder Operating rate",
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
- .maximum = MAX_OPERATING_FRAME_RATE,
+ .maximum = INT_MAX,
.default_value = 0,
.step = OPERATING_FRAME_RATE_STEP,
},
@@ -994,26 +993,6 @@
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
-static u32 get_frame_size_nv12(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
-}
-
-static u32 get_frame_size_nv12_ubwc(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
-}
-
-static u32 get_frame_size_rgba(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_RGBA8888, width, height);
-}
-
-static u32 get_frame_size_nv21(int plane, u32 height, u32 width)
-{
- return VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
-}
-
static u32 get_frame_size_compressed(int plane, u32 height, u32 width)
{
int sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2;
@@ -1071,6 +1050,13 @@
.get_frame_size = get_frame_size_nv21,
.type = OUTPUT_PORT,
},
+ {
+ .name = "TP10 UBWC 4:2:0",
+ .description = "TP10 UBWC 4:2:0",
+ .fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC,
+ .get_frame_size = get_frame_size_tp10_ubwc,
+ .type = OUTPUT_PORT,
+ },
};
static int msm_venc_set_csc(struct msm_vidc_inst *inst);
@@ -1235,7 +1221,7 @@
bitrate.bit_rate = ctrl->val;
bitrate.layer_id = 0;
pdata = &bitrate;
- inst->bitrate = ctrl->val;
+ inst->clk_data.bitrate = ctrl->val;
break;
}
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
@@ -1747,8 +1733,12 @@
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
dprintk(VIDC_DBG,
"inst(%pK) operating rate changed from %d to %d\n",
- inst, inst->operating_rate >> 16, ctrl->val >> 16);
- inst->operating_rate = ctrl->val;
+ inst, inst->clk_data.operating_rate >> 16,
+ ctrl->val >> 16);
+ inst->clk_data.operating_rate = ctrl->val;
+
+ msm_vidc_update_operating_rate(inst);
+
break;
case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE:
{
@@ -1831,6 +1821,7 @@
else
enable.enable = 0;
pdata = &enable;
+ inst->clk_data.low_latency_mode = (bool) enable.enable;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8:
@@ -1868,9 +1859,9 @@
#undef TRY_GET_CTRL
if (!rc && property_id) {
- dprintk(VIDC_DBG, "Control: HAL property=%x,ctrl_value=%d\n",
- property_id,
- ctrl->val);
+ dprintk(VIDC_DBG,
+ "Control: Name = %s, ID = 0x%x Value = %d\n",
+ ctrl->name, ctrl->id, ctrl->val);
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session, property_id, pdata);
}
@@ -2083,7 +2074,7 @@
/* To start with, both ports are 1 plane each */
inst->bufq[OUTPUT_PORT].num_planes = 1;
inst->bufq[CAPTURE_PORT].num_planes = 1;
- inst->operating_rate = 0;
+ inst->clk_data.operating_rate = 0;
memcpy(&inst->fmts[CAPTURE_PORT], &venc_formats[4],
sizeof(struct msm_vidc_format));
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index e071037..8f97b15 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1433,7 +1433,9 @@
"Failed to move inst: %pK to start done state\n", inst);
goto fail_start;
}
- msm_dcvs_init(inst);
+
+ msm_clock_data_reset(inst);
+
if (msm_comm_get_stream_output_mode(inst) ==
HAL_VIDEO_DECODER_SECONDARY) {
rc = msm_comm_queue_output_buffers(inst);
@@ -1519,6 +1521,9 @@
dprintk(VIDC_ERR,
"Failed to move inst: %pK to state %d\n",
inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+
+ msm_clock_data_reset(inst);
+
return rc;
}
@@ -1971,10 +1976,11 @@
inst->session_type = session_type;
inst->state = MSM_VIDC_CORE_UNINIT_DONE;
inst->core = core;
- inst->freq = 0;
- inst->core_id = VIDC_CORE_ID_DEFAULT;
+ inst->clk_data.min_freq = 0;
+ inst->clk_data.curr_freq = 0;
+ inst->clk_data.bitrate = 0;
+ inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
- inst->bitrate = 0;
inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
inst->colour_space = MSM_VIDC_BT601_6_525;
inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
@@ -2037,6 +2043,8 @@
goto fail_init;
}
+ msm_comm_scale_clocks_and_bus(inst);
+
inst->debugfs_root =
msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index d43ae5a..cd518fb 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -23,17 +23,12 @@
struct msm_vidc_inst *inst = NULL;
struct vidc_bus_vote_data *vote_data = NULL;
- if (!core) {
+ if (!core || !core->device) {
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
return -EINVAL;
}
hdev = core->device;
- if (!hdev) {
- dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
- __func__, hdev);
- return -EINVAL;
- }
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list)
@@ -65,12 +60,17 @@
vote_data[i].height = max(inst->prop.height[CAPTURE_PORT],
inst->prop.height[OUTPUT_PORT]);
- if (inst->operating_rate)
- vote_data[i].fps = (inst->operating_rate >> 16) ?
- inst->operating_rate >> 16 : 1;
+ if (inst->clk_data.operating_rate)
+ vote_data[i].fps =
+ (inst->clk_data.operating_rate >> 16) ?
+ inst->clk_data.operating_rate >> 16 : 1;
else
vote_data[i].fps = inst->prop.fps;
+ if (!msm_vidc_clock_scaling ||
+ inst->clk_data.buffer_counter < DCVS_FTB_WINDOW)
+ vote_data[i].power_mode = VIDC_POWER_TURBO;
+
/*
* TODO: support for OBP-DBP split mode hasn't been yet
* implemented, once it is, this part of code needs to be
@@ -126,18 +126,19 @@
int buffers_outside_fw = 0;
struct msm_vidc_core *core;
struct hal_buffer_requirements *output_buf_req;
- struct dcvs_stats *dcvs;
+ struct clock_data *dcvs;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
return -EINVAL;
}
- if (!inst->dcvs_mode) {
+
+ if (!inst->clk_data.dcvs_mode) {
dprintk(VIDC_DBG, "DCVS is not enabled\n");
return 0;
}
- dcvs = &inst->dcvs;
+ dcvs = &inst->clk_data;
core = inst->core;
mutex_lock(&inst->lock);
@@ -210,7 +211,7 @@
}
mutex_unlock(&inst->freqs.lock);
- inst->dcvs.buffer_counter++;
+ inst->clk_data.buffer_counter++;
}
@@ -227,12 +228,13 @@
/* If current requirement is within DCVS limits, try DCVS. */
- if (freq < inst->dcvs.load_high) {
+ if (freq < inst->clk_data.load_high) {
dprintk(VIDC_DBG, "Calling DCVS now\n");
// TODO calling DCVS here may reduce the residency. Re-visit.
msm_dcvs_scale_clocks(inst);
- freq = inst->dcvs.load;
+ freq = inst->clk_data.load;
}
+ dprintk(VIDC_PROF, "%s Inst %pK : Freq = %lu\n", __func__, inst, freq);
return freq;
}
@@ -274,9 +276,10 @@
unsigned long freq = 0;
unsigned long vpp_cycles = 0, vsp_cycles = 0;
u32 vpp_cycles_per_mb;
- u32 mbs_per_frame;
+ u32 mbs_per_second;
- mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
+ mbs_per_second = msm_comm_get_inst_load(inst,
+ LOAD_CALC_NO_QUIRKS);
/*
* Calculate vpp, vsp cycles separately for encoder and decoder.
@@ -286,17 +289,17 @@
if (inst->session_type == MSM_VIDC_ENCODER) {
vpp_cycles_per_mb = inst->flags & VIDC_LOW_POWER ?
- inst->entry->low_power_cycles :
- inst->entry->vpp_cycles;
+ inst->clk_data.entry->low_power_cycles :
+ inst->clk_data.entry->vpp_cycles;
- vsp_cycles = mbs_per_frame * inst->entry->vsp_cycles;
+ vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles;
/* 10 / 7 is overhead factor */
- vsp_cycles += (inst->bitrate * 10) / 7;
+ vsp_cycles += (inst->clk_data.bitrate * 10) / 7;
} else if (inst->session_type == MSM_VIDC_DECODER) {
- vpp_cycles = mbs_per_frame * inst->entry->vpp_cycles;
+ vpp_cycles = mbs_per_second * inst->clk_data.entry->vpp_cycles;
- vsp_cycles = mbs_per_frame * inst->entry->vsp_cycles;
+ vsp_cycles = mbs_per_second * inst->clk_data.entry->vsp_cycles;
/* 10 / 7 is overhead factor */
vsp_cycles += (inst->prop.fps * filled_len * 8 * 10) / 7;
@@ -306,6 +309,8 @@
return freq;
}
+ dprintk(VIDC_PROF, "%s Inst %pK : Freq = %lu\n", __func__, inst, freq);
+
freq = max(vpp_cycles, vsp_cycles);
return freq;
@@ -321,7 +326,7 @@
hdev = core->device;
allowed_clks_tbl = core->resources.allowed_clks_tbl;
- if (!hdev || !allowed_clks_tbl) {
+ if (!allowed_clks_tbl) {
dprintk(VIDC_ERR,
"%s Invalid parameters\n", __func__);
return -EINVAL;
@@ -329,35 +334,104 @@
mutex_lock(&core->lock);
list_for_each_entry(temp, &core->instances, list) {
- freq += temp->freq;
+ freq += temp->clk_data.curr_freq;
}
for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) {
rate = allowed_clks_tbl[i].clock_rate;
if (rate >= freq)
break;
}
+ core->min_freq = freq;
+ core->curr_freq = rate;
mutex_unlock(&core->lock);
- core->freq = rate;
- dprintk(VIDC_PROF, "Voting for freq = %lu", freq);
+ dprintk(VIDC_PROF, "Min freq = %lu Current Freq = %lu\n",
+ core->min_freq, core->curr_freq);
rc = call_hfi_op(hdev, scale_clocks,
- hdev->hfi_device_data, rate);
+ hdev->hfi_device_data, core->curr_freq);
return rc;
}
-static unsigned long msm_vidc_max_freq(struct msm_vidc_inst *inst)
+static unsigned long msm_vidc_max_freq(struct msm_vidc_core *core)
{
struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
unsigned long freq = 0;
- allowed_clks_tbl = inst->core->resources.allowed_clks_tbl;
+ allowed_clks_tbl = core->resources.allowed_clks_tbl;
freq = allowed_clks_tbl[0].clock_rate;
dprintk(VIDC_PROF, "Max rate = %lu", freq);
return freq;
}
+int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst)
+{
+ struct v4l2_ctrl *ctrl = NULL;
+ struct msm_vidc_inst *temp;
+ struct msm_vidc_core *core;
+ unsigned long max_freq, freq_left, ops_left, load, cycles, freq = 0;
+ unsigned long mbs_per_frame;
+
+ if (!inst || !inst->core) {
+ dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
+ return -EINVAL;
+ }
+ core = inst->core;
+
+ mutex_lock(&core->lock);
+ max_freq = msm_vidc_max_freq(core);
+ list_for_each_entry(temp, &core->instances, list) {
+ if (temp == inst ||
+ temp->state < MSM_VIDC_START_DONE ||
+ temp->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)
+ continue;
+
+ freq += temp->clk_data.min_freq;
+ }
+
+ freq_left = max_freq - freq;
+
+ list_for_each_entry(temp, &core->instances, list) {
+
+ mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
+ cycles = temp->clk_data.entry->vpp_cycles;
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ cycles = temp->flags & VIDC_LOW_POWER ?
+ inst->clk_data.entry->low_power_cycles :
+ cycles;
+
+ load = cycles * mbs_per_frame;
+
+ ops_left = load ? (freq_left / load) : 0;
+ /* Convert remaining operating rate to Q16 format */
+ ops_left = ops_left << 16;
+
+ ctrl = v4l2_ctrl_find(&temp->ctrl_handler,
+ V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE);
+ if (ctrl) {
+ dprintk(VIDC_DBG,
+ "%s: Before Range = %lld --> %lld\n",
+ ctrl->name, ctrl->minimum, ctrl->maximum);
+ dprintk(VIDC_DBG,
+ "%s: Before Def value = %lld Cur val = %d\n",
+ ctrl->name, ctrl->default_value, ctrl->val);
+ v4l2_ctrl_modify_range(ctrl, ctrl->minimum,
+ ctrl->val + ops_left, ctrl->step,
+ ctrl->minimum);
+ dprintk(VIDC_DBG,
+ "%s: Updated Range = %lld --> %lld\n",
+ ctrl->name, ctrl->minimum, ctrl->maximum);
+ dprintk(VIDC_DBG,
+ "%s: Updated Def value = %lld Cur val = %d\n",
+ ctrl->name, ctrl->default_value, ctrl->val);
+ }
+ }
+ mutex_unlock(&core->lock);
+
+ return 0;
+}
+
int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
{
struct vb2_buf_entry *temp, *next;
@@ -365,9 +439,10 @@
u32 filled_len = 0;
ion_phys_addr_t device_addr = 0;
- if (inst->dcvs.buffer_counter < DCVS_FTB_WINDOW) {
- freq = msm_vidc_max_freq(inst);
- goto decision_done;
+ if (!inst || !inst->core) {
+ dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
+ __func__, inst);
+ return -EINVAL;
}
mutex_lock(&inst->pendingq.lock);
@@ -381,7 +456,7 @@
mutex_unlock(&inst->pendingq.lock);
if (!filled_len || !device_addr) {
- freq = inst->freq;
+ dprintk(VIDC_PROF, "No Change in frequency\n");
goto decision_done;
}
@@ -391,8 +466,15 @@
freq = msm_vidc_adjust_freq(inst);
+ inst->clk_data.min_freq = freq;
+
+ if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW ||
+ !msm_vidc_clock_scaling)
+ inst->clk_data.curr_freq = msm_vidc_max_freq(inst->core);
+ else
+ inst->clk_data.curr_freq = freq;
+
decision_done:
- inst->freq = freq;
msm_vidc_set_clocks(inst->core);
return 0;
}
@@ -422,29 +504,29 @@
int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
{
- bool force_disable = false;
-
if (!inst) {
dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, inst);
return -EINVAL;
}
- force_disable = inst->session_type == MSM_VIDC_ENCODER ?
- !msm_vidc_enc_dcvs_mode :
- !msm_vidc_dec_dcvs_mode;
-
- if (force_disable || inst->flags & VIDC_THUMBNAIL) {
- dprintk(VIDC_PROF, "Thumbnail sessions don't need DCVS : %pK\n",
- inst);
- inst->dcvs.extra_capture_buffer_count = 0;
- inst->dcvs.extra_output_buffer_count = 0;
+ if (!msm_vidc_clock_scaling ||
+ inst->flags & VIDC_THUMBNAIL ||
+ inst->clk_data.low_latency_mode) {
+ dprintk(VIDC_PROF,
+ "This session doesn't need DCVS : %pK\n",
+ inst);
+ inst->clk_data.extra_capture_buffer_count = 0;
+ inst->clk_data.extra_output_buffer_count = 0;
+ inst->clk_data.dcvs_mode = false;
return false;
}
- inst->dcvs_mode = true;
+ inst->clk_data.dcvs_mode = true;
// TODO : Update with proper number based on on-target tuning.
- inst->dcvs.extra_capture_buffer_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
- inst->dcvs.extra_output_buffer_count = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
+ inst->clk_data.extra_capture_buffer_count =
+ DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
+ inst->clk_data.extra_output_buffer_count =
+ DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
return true;
}
@@ -482,6 +564,12 @@
struct clock_profile_entry *entry = NULL;
int fourcc;
+ if (!inst || !inst->core) {
+ dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
+ __func__, inst);
+ return -EINVAL;
+ }
+
clk_freq_tbl = &inst->core->resources.clock_freq_tbl;
fourcc = inst->session_type == MSM_VIDC_DECODER ?
inst->fmts[OUTPUT_PORT].fourcc :
@@ -498,7 +586,7 @@
inst->session_type);
if (matched) {
- inst->entry = entry;
+ inst->clk_data.entry = entry;
break;
}
}
@@ -512,7 +600,7 @@
return rc;
}
-static inline void msm_dcvs_print_dcvs_stats(struct dcvs_stats *dcvs)
+static inline void msm_dcvs_print_dcvs_stats(struct clock_data *dcvs)
{
dprintk(VIDC_DBG,
"DCVS: Load_Low %d, Load High %d\n",
@@ -524,31 +612,31 @@
dcvs->min_threshold, dcvs->max_threshold);
}
-void msm_dcvs_init(struct msm_vidc_inst *inst)
+void msm_clock_data_reset(struct msm_vidc_inst *inst)
{
struct msm_vidc_core *core;
- int i = 0;
+ int i = 0, rc = 0;
struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
u64 total_freq = 0, rate = 0, load;
int cycles;
- struct dcvs_stats *dcvs;
+ struct clock_data *dcvs;
dprintk(VIDC_DBG, "Init DCVS Load\n");
if (!inst || !inst->core) {
- dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
+ dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
+ __func__, inst);
return;
}
core = inst->core;
- dcvs = &inst->dcvs;
- inst->dcvs = (struct dcvs_stats){0};
+ dcvs = &inst->clk_data;
load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
- cycles = inst->entry->vpp_cycles;
+ cycles = inst->clk_data.entry->vpp_cycles;
allowed_clks_tbl = core->resources.allowed_clks_tbl;
if (inst->session_type == MSM_VIDC_ENCODER) {
cycles = inst->flags & VIDC_LOW_POWER ?
- inst->entry->low_power_cycles :
+ inst->clk_data.entry->low_power_cycles :
cycles;
dcvs->buffer_type = HAL_BUFFER_INPUT;
@@ -573,7 +661,17 @@
dcvs->load = dcvs->load_high = rate;
dcvs->load_low = allowed_clks_tbl[i+1].clock_rate;
+ inst->clk_data.buffer_counter = 0;
+
msm_dcvs_print_dcvs_stats(dcvs);
+
+ msm_vidc_update_operating_rate(inst);
+
+ rc = msm_comm_scale_clocks_and_bus(inst);
+
+ if (rc)
+ dprintk(VIDC_ERR, "%s Failed to scale Clocks and Bus\n",
+ __func__);
}
int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst,
@@ -585,23 +683,26 @@
}
return buffer_type == HAL_BUFFER_INPUT ?
- inst->dcvs.extra_output_buffer_count :
- inst->dcvs.extra_capture_buffer_count;
+ inst->clk_data.extra_output_buffer_count :
+ inst->clk_data.extra_capture_buffer_count;
}
int msm_vidc_decide_work_mode(struct msm_vidc_inst *inst)
{
int rc = 0;
- bool low_latency_mode;
struct hfi_device *hdev;
struct hal_video_work_mode pdata;
struct hal_enable latency;
- hdev = inst->core->device;
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR,
+ "%s Invalid args: Inst = %pK\n",
+ __func__, inst);
+ return -EINVAL;
+ }
- low_latency_mode = msm_comm_g_ctrl_for_id(inst,
- V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE);
- if (low_latency_mode) {
+ hdev = inst->core->device;
+ if (inst->clk_data.low_latency_mode) {
pdata.video_work_mode = VIDC_WORK_MODE_1;
goto decision_done;
}
@@ -636,7 +737,7 @@
decision_done:
- inst->work_mode = pdata.video_work_mode;
+ inst->clk_data.work_mode = pdata.video_work_mode;
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session, HAL_PARAM_VIDEO_WORK_MODE,
(void *)&pdata);
@@ -646,7 +747,8 @@
/* For WORK_MODE_1, set Low Latency mode by default to HW. */
- if (inst->work_mode == VIDC_WORK_MODE_1) {
+ if (inst->session_type == MSM_VIDC_ENCODER &&
+ inst->clk_data.work_mode == VIDC_WORK_MODE_1) {
latency.enable = 1;
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session, HAL_PARAM_VENC_LOW_LATENCY,
@@ -675,8 +777,8 @@
return 0;
}
mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
- if (inst->core->resources.max_hq_mbs_per_frame > mbs_per_frame ||
- inst->core->resources.max_hq_fps > inst->prop.fps) {
+ if (mbs_per_frame >= inst->core->resources.max_hq_mbs_per_frame ||
+ inst->prop.fps >= inst->core->resources.max_hq_fps) {
enable = true;
}
@@ -692,9 +794,12 @@
__func__, inst);
goto fail_power_mode_set;
}
- inst->flags |= VIDC_LOW_POWER;
- dprintk(VIDC_PROF, "Power Save Mode set for inst: %pK\n", inst);
+ inst->flags = enable ?
+ inst->flags | VIDC_LOW_POWER :
+ inst->flags & ~VIDC_LOW_POWER;
+ dprintk(VIDC_PROF,
+ "Power Save Mode for inst: %pK Enable = %d\n", inst, enable);
fail_power_mode_set:
return rc;
}
@@ -704,15 +809,10 @@
{
struct msm_vidc_inst *inst = NULL;
- if (!core) {
- dprintk(VIDC_ERR, "Invalid args: %pK\n", core);
- return -EINVAL;
- }
-
dprintk(VIDC_PROF, "Core %d : Moving all inst to LP mode\n", core_id);
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
- if (inst->core_id == core_id &&
+ if (inst->clk_data.core_id == core_id &&
inst->session_type == MSM_VIDC_ENCODER)
msm_vidc_power_save_mode_enable(inst, true);
}
@@ -731,19 +831,19 @@
list_for_each_entry(inst, &core->instances, list) {
u32 cycles, lp_cycles;
- if (!inst->core_id && core_id)
+ if (!(inst->clk_data.core_id && core_id))
continue;
if (inst->session_type == MSM_VIDC_DECODER) {
- cycles = lp_cycles = inst->entry->vpp_cycles;
+ cycles = lp_cycles = inst->clk_data.entry->vpp_cycles;
} else if (inst->session_type == MSM_VIDC_ENCODER) {
lp_mode |= inst->flags & VIDC_LOW_POWER;
cycles = lp_mode ?
- inst->entry->low_power_cycles :
- inst->entry->vpp_cycles;
+ inst->clk_data.entry->low_power_cycles :
+ inst->clk_data.entry->vpp_cycles;
} else {
continue;
}
- if (inst->core_id == 3)
+ if (inst->clk_data.core_id == 3)
cycles = cycles / 2;
current_inst_mbs_per_sec = msm_comm_get_inst_load(inst,
@@ -768,10 +868,17 @@
min_load = 0, min_lp_load = 0;
u32 min_core_id, min_lp_core_id;
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR,
+ "%s Invalid args: Inst = %pK\n",
+ __func__, inst);
+ return -EINVAL;
+ }
+
core = inst->core;
hdev = core->device;
- max_freq = msm_vidc_max_freq(inst);
- inst->core_id = 0;
+ max_freq = msm_vidc_max_freq(inst->core);
+ inst->clk_data.core_id = 0;
core0_load = get_core_load(core, VIDC_CORE_ID_1, false);
core1_load = get_core_load(core, VIDC_CORE_ID_2, false);
@@ -786,11 +893,11 @@
VIDC_CORE_ID_1 : VIDC_CORE_ID_2;
lp_cycles = inst->session_type == MSM_VIDC_ENCODER ?
- inst->entry->low_power_cycles :
- inst->entry->vpp_cycles;
+ inst->clk_data.entry->low_power_cycles :
+ inst->clk_data.entry->vpp_cycles;
current_inst_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS) *
- inst->entry->vpp_cycles;
+ inst->clk_data.entry->vpp_cycles;
current_inst_lp_load = msm_comm_get_inst_load(inst,
LOAD_CALC_NO_QUIRKS) * lp_cycles;
@@ -814,7 +921,7 @@
if (inst->session_type == MSM_VIDC_ENCODER && hier_mode) {
if (current_inst_load / 2 + core0_load <= max_freq &&
current_inst_load / 2 + core1_load <= max_freq) {
- inst->core_id = VIDC_CORE_ID_3;
+ inst->clk_data.core_id = VIDC_CORE_ID_3;
msm_vidc_power_save_mode_enable(inst, false);
goto decision_done;
}
@@ -825,32 +932,32 @@
core0_lp_load <= max_freq &&
current_inst_lp_load / 2 +
core1_lp_load <= max_freq) {
- inst->core_id = VIDC_CORE_ID_3;
+ inst->clk_data.core_id = VIDC_CORE_ID_3;
msm_vidc_power_save_mode_enable(inst, true);
goto decision_done;
}
}
if (current_inst_load + min_load < max_freq) {
- inst->core_id = min_core_id;
+ inst->clk_data.core_id = min_core_id;
dprintk(VIDC_DBG,
"Selected normally : Core ID = %d\n",
- inst->core_id);
+ inst->clk_data.core_id);
msm_vidc_power_save_mode_enable(inst, false);
} else if (current_inst_lp_load + min_load < max_freq) {
/* Move current instance to LP and return */
- inst->core_id = min_core_id;
+ inst->clk_data.core_id = min_core_id;
dprintk(VIDC_DBG,
"Selected by moving current to LP : Core ID = %d\n",
- inst->core_id);
+ inst->clk_data.core_id);
msm_vidc_power_save_mode_enable(inst, true);
} else if (current_inst_lp_load + min_lp_load < max_freq) {
/* Move all instances to LP mode and return */
- inst->core_id = min_lp_core_id;
+ inst->clk_data.core_id = min_lp_core_id;
dprintk(VIDC_DBG,
"Moved all inst's to LP: Core ID = %d\n",
- inst->core_id);
+ inst->clk_data.core_id);
msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id);
} else {
rc = -EINVAL;
@@ -860,7 +967,7 @@
}
decision_done:
- core_info.video_core_enable_mask = inst->core_id;
+ core_info.video_core_enable_mask = inst->clk_data.core_id;
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session,
@@ -874,3 +981,4 @@
return rc;
}
+
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
index d01f074..fe4822b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.h
@@ -31,7 +31,8 @@
/* Considering one safeguard buffer */
#define DCVS_BUFFER_SAFEGUARD (DCVS_DEC_EXTRA_OUTPUT_BUFFERS - 1)
-void msm_dcvs_init(struct msm_vidc_inst *inst);
+void msm_clock_data_reset(struct msm_vidc_inst *inst);
+int msm_vidc_update_operating_rate(struct msm_vidc_inst *inst);
int msm_vidc_get_extra_buff_count(struct msm_vidc_inst *inst,
enum hal_buffer buffer_type);
int msm_dcvs_try_enable(struct msm_vidc_inst *inst);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 853edf5..d4562ce 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -584,9 +584,9 @@
capture_port_mbs = NUM_MBS_PER_FRAME(inst->prop.width[CAPTURE_PORT],
inst->prop.height[CAPTURE_PORT]);
- if (inst->operating_rate) {
- fps = (inst->operating_rate >> 16) ?
- inst->operating_rate >> 16 : 1;
+ if (inst->clk_data.operating_rate) {
+ fps = (inst->clk_data.operating_rate >> 16) ?
+ inst->clk_data.operating_rate >> 16 : 1;
/*
* Check if operating rate is less than fps.
* If Yes, then use fps to scale clocks
@@ -2510,7 +2510,7 @@
}
tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
- freq = core->freq;
+ freq = core->curr_freq;
is_turbo = is_core_turbo(core, freq);
dprintk(VIDC_DBG,
@@ -4738,9 +4738,9 @@
return 0;
}
- // Finish FLUSH As Soon As Possible.
- inst->dcvs.buffer_counter = 0;
- msm_comm_scale_clocks_and_bus(inst);
+ /* Finish FLUSH As Soon As Possible. */
+
+ msm_clock_data_reset(inst);
msm_comm_flush_dynamic_buffers(inst);
@@ -5474,7 +5474,7 @@
}
core = inst->core;
- dprintk(VIDC_ERR, "Venus core frequency = %lu", core->freq);
+ dprintk(VIDC_ERR, "Venus core frequency = %lu", core->curr_freq);
mutex_lock(&core->lock);
dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
msm_comm_print_inst_info(inst);
@@ -5520,3 +5520,28 @@
mutex_unlock(&inst->lock);
return rc;
}
+
+u32 get_frame_size_nv12(int plane, u32 height, u32 width)
+{
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+}
+
+u32 get_frame_size_nv12_ubwc(int plane, u32 height, u32 width)
+{
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+}
+
+u32 get_frame_size_rgba(int plane, u32 height, u32 width)
+{
+ return VENUS_BUFFER_SIZE(COLOR_FMT_RGBA8888, width, height);
+}
+
+u32 get_frame_size_nv21(int plane, u32 height, u32 width)
+{
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
+}
+
+u32 get_frame_size_tp10_ubwc(int plane, u32 height, u32 width)
+{
+ return VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 9c7eec5..098063d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -98,4 +98,9 @@
int msm_comm_v4l2_to_hal(int id, int value);
int msm_comm_hal_to_v4l2(int id, int value);
int msm_comm_session_continue(void *instance);
+u32 get_frame_size_nv12(int plane, u32 height, u32 width);
+u32 get_frame_size_nv12_ubwc(int plane, u32 height, u32 width);
+u32 get_frame_size_rgba(int plane, u32 height, u32 width);
+u32 get_frame_size_nv21(int plane, u32 height, u32 width);
+u32 get_frame_size_tp10_ubwc(int plane, u32 height, u32 width);
#endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 15ee8a8..f62c132 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -26,12 +26,10 @@
int msm_vidc_fw_low_power_mode = 1;
int msm_vidc_hw_rsp_timeout = 2000;
bool msm_vidc_fw_coverage = !true;
-bool msm_vidc_dec_dcvs_mode = true;
-bool msm_vidc_enc_dcvs_mode = true;
bool msm_vidc_sys_idle_indicator = !true;
int msm_vidc_firmware_unload_delay = 15000;
bool msm_vidc_thermal_mitigation_disabled = !true;
-bool msm_vidc_bitrate_clock_scaling = true;
+bool msm_vidc_clock_scaling = true;
bool msm_vidc_debug_timeout = !true;
#define MAX_DBG_BUF_SIZE 4096
@@ -174,8 +172,6 @@
__debugfs_create(x32, "fw_level", &msm_vidc_fw_debug) &&
__debugfs_create(u32, "fw_debug_mode", &msm_vidc_fw_debug_mode) &&
__debugfs_create(bool, "fw_coverage", &msm_vidc_fw_coverage) &&
- __debugfs_create(bool, "dcvs_dec_mode", &msm_vidc_dec_dcvs_mode) &&
- __debugfs_create(bool, "dcvs_enc_mode", &msm_vidc_enc_dcvs_mode) &&
__debugfs_create(u32, "fw_low_power_mode",
&msm_vidc_fw_low_power_mode) &&
__debugfs_create(u32, "debug_output", &msm_vidc_debug_out) &&
@@ -186,8 +182,8 @@
&msm_vidc_firmware_unload_delay) &&
__debugfs_create(bool, "disable_thermal_mitigation",
&msm_vidc_thermal_mitigation_disabled) &&
- __debugfs_create(bool, "bitrate_clock_scaling",
- &msm_vidc_bitrate_clock_scaling) &&
+ __debugfs_create(bool, "clock_scaling",
+ &msm_vidc_clock_scaling) &&
__debugfs_create(bool, "debug_timeout",
&msm_vidc_debug_timeout);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index cf5ce22..f5c8e5a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -59,12 +59,10 @@
extern int msm_vidc_fw_low_power_mode;
extern int msm_vidc_hw_rsp_timeout;
extern bool msm_vidc_fw_coverage;
-extern bool msm_vidc_dec_dcvs_mode;
-extern bool msm_vidc_enc_dcvs_mode;
extern bool msm_vidc_sys_idle_indicator;
extern int msm_vidc_firmware_unload_delay;
extern bool msm_vidc_thermal_mitigation_disabled;
-extern bool msm_vidc_bitrate_clock_scaling;
+extern bool msm_vidc_clock_scaling;
extern bool msm_vidc_debug_timeout;
#define VIDC_MSG_PRIO2STRING(__level) ({ \
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 53bc068..37bccbd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -52,7 +52,7 @@
/* Maintains the number of FTB's between each FBD over a window */
-#define DCVS_FTB_WINDOW 32
+#define DCVS_FTB_WINDOW 16
#define V4L2_EVENT_VIDC_BASE 10
@@ -205,7 +205,7 @@
int ebd;
};
-struct dcvs_stats {
+struct clock_data {
int buffer_counter;
int load;
int load_low;
@@ -215,6 +215,15 @@
unsigned int extra_capture_buffer_count;
unsigned int extra_output_buffer_count;
enum hal_buffer buffer_type;
+ bool dcvs_mode;
+ unsigned long bitrate;
+ unsigned long min_freq;
+ unsigned long curr_freq;
+ u32 operating_rate;
+ struct clock_profile_entry *entry;
+ u32 core_id;
+ enum hal_work_mode work_mode;
+ bool low_latency_mode;
};
struct profile_data {
@@ -259,7 +268,8 @@
struct msm_vidc_capability *capabilities;
struct delayed_work fw_unload_work;
bool smmu_fault_handled;
- unsigned long freq;
+ unsigned long min_freq;
+ unsigned long curr_freq;
};
struct msm_vidc_inst {
@@ -293,28 +303,21 @@
void *priv;
struct msm_vidc_debug debug;
struct buf_count count;
- struct dcvs_stats dcvs;
+ struct clock_data clk_data;
enum msm_vidc_modes flags;
struct msm_vidc_capability capability;
u32 buffer_size_limit;
enum buffer_mode_type buffer_mode_set[MAX_PORT_NUM];
struct v4l2_ctrl **ctrls;
- bool dcvs_mode;
enum msm_vidc_pixel_depth bit_depth;
struct kref kref;
- unsigned long bitrate;
- unsigned long freq;
u32 buffers_held_in_driver;
atomic_t in_flush;
u32 pic_struct;
u32 colour_space;
- u32 operating_rate;
u32 profile;
u32 level;
u32 entropy_mode;
- struct clock_profile_entry *entry;
- u32 core_id;
- enum hal_work_mode work_mode;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index bacecbd..2afa1eb 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -360,6 +360,10 @@
if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
copy_in_user(&up->data_offset, &up32->data_offset,
+ sizeof(__u32)) ||
+ copy_in_user(up->reserved, up32->reserved,
+ sizeof(up->reserved)) ||
+ copy_in_user(&up->length, &up32->length,
sizeof(__u32)))
return -EFAULT;
@@ -386,7 +390,9 @@
{
if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
copy_in_user(&up32->data_offset, &up->data_offset,
- sizeof(__u32)))
+ sizeof(__u32)) ||
+ copy_in_user(up32->reserved, up->reserved,
+ sizeof(up32->reserved)))
return -EFAULT;
/* For MMAP, driver might've set up the offset, so copy it back.
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 2c02d2d..877c4d1 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -5869,7 +5869,8 @@
* It will return false if it is GPCE based crypto instance or
* ICE is setup properly
*/
- if (qseecom_enable_ice_setup(create_key_req.usage))
+ ret = qseecom_enable_ice_setup(create_key_req.usage);
+ if (ret)
goto free_buf;
do {
@@ -5998,7 +5999,8 @@
* It will return false if it is GPCE based crypto instance or
* ICE is setup properly
*/
- if (qseecom_enable_ice_setup(wipe_key_req.usage))
+ ret = qseecom_enable_ice_setup(wipe_key_req.usage);
+ if (ret)
goto free_buf;
ret = __qseecom_set_clear_ce_key(data, wipe_key_req.usage,
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 6523cb0..16c9096 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -6764,12 +6764,12 @@
PCIE_DBG(pcie_dev, "RC%d: PM_Enter_L23 is NOT received\n",
pcie_dev->rc_idx);
- msm_pcie_disable(pcie_dev, PM_PIPE_CLK | PM_CLK | PM_VREG);
-
if (pcie_dev->use_pinctrl && pcie_dev->pins_sleep)
pinctrl_select_state(pcie_dev->pinctrl,
pcie_dev->pins_sleep);
+ msm_pcie_disable(pcie_dev, PM_PIPE_CLK | PM_CLK | PM_VREG);
+
PCIE_DBG(pcie_dev, "RC%d: exit\n", pcie_dev->rc_idx);
return ret;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index e474a40..b60c7a6 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -1480,17 +1480,24 @@
void ipa_delete_dflt_flt_rules(u32 ipa_ep_idx)
{
+ struct ipa_flt_tbl *tbl;
struct ipa_ep_context *ep = &ipa_ctx->ep[ipa_ep_idx];
mutex_lock(&ipa_ctx->lock);
if (ep->dflt_flt4_rule_hdl) {
+ tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4];
__ipa_del_flt_rule(ep->dflt_flt4_rule_hdl);
ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4);
+ /* Reset the sticky flag. */
+ tbl->sticky_rear = false;
ep->dflt_flt4_rule_hdl = 0;
}
if (ep->dflt_flt6_rule_hdl) {
+ tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6];
__ipa_del_flt_rule(ep->dflt_flt6_rule_hdl);
ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6);
+ /* Reset the sticky flag. */
+ tbl->sticky_rear = false;
ep->dflt_flt6_rule_hdl = 0;
}
mutex_unlock(&ipa_ctx->lock);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 9d25e4a..89dd274 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -1004,6 +1004,7 @@
struct ipa3_ep_context *ep;
int empty;
int result;
+ int i;
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -1038,7 +1039,17 @@
if (IPA_CLIENT_IS_CONS(ep->client))
cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
flush_workqueue(ep->sys->wq);
- result = ipa3_stop_gsi_channel(clnt_hdl);
+ /* channel stop might fail on timeout if IPA is busy */
+ for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
+ result = ipa3_stop_gsi_channel(clnt_hdl);
+ if (result == GSI_STATUS_SUCCESS)
+ break;
+
+ if (result != -GSI_STATUS_AGAIN &&
+ result != -GSI_STATUS_TIMED_OUT)
+ break;
+ }
+
if (result != GSI_STATUS_SUCCESS) {
IPAERR("GSI stop chan err: %d.\n", result);
ipa_assert();
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index 0cc1206..ff763c4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -1389,16 +1389,23 @@
void ipa3_delete_dflt_flt_rules(u32 ipa_ep_idx)
{
struct ipa3_ep_context *ep = &ipa3_ctx->ep[ipa_ep_idx];
+ struct ipa3_flt_tbl *tbl;
mutex_lock(&ipa3_ctx->lock);
if (ep->dflt_flt4_rule_hdl) {
+ tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4];
__ipa_del_flt_rule(ep->dflt_flt4_rule_hdl);
ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4);
+ /* Reset the sticky flag. */
+ tbl->sticky_rear = false;
ep->dflt_flt4_rule_hdl = 0;
}
if (ep->dflt_flt6_rule_hdl) {
+ tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6];
__ipa_del_flt_rule(ep->dflt_flt6_rule_hdl);
ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6);
+ /* Reset the sticky flag. */
+ tbl->sticky_rear = false;
ep->dflt_flt6_rule_hdl = 0;
}
mutex_unlock(&ipa3_ctx->lock);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5a38db3..f066d94 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4352,21 +4352,30 @@
memset(&mem, 0, sizeof(mem));
- for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
- IPADBG("Calling gsi_stop_channel\n");
+ if (IPA_CLIENT_IS_PROD(ep->client)) {
+ IPADBG("Calling gsi_stop_channel ch:%lu\n",
+ ep->gsi_chan_hdl);
res = gsi_stop_channel(ep->gsi_chan_hdl);
- IPADBG("gsi_stop_channel returned %d\n", res);
+ IPADBG("gsi_stop_channel ch: %lu returned %d\n",
+ ep->gsi_chan_hdl, res);
+ goto end_sequence;
+ }
+
+ for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
+ IPADBG("Calling gsi_stop_channel ch:%lu\n",
+ ep->gsi_chan_hdl);
+ res = gsi_stop_channel(ep->gsi_chan_hdl);
+ IPADBG("gsi_stop_channel ch: %lu returned %d\n",
+ ep->gsi_chan_hdl, res);
if (res != -GSI_STATUS_AGAIN && res != -GSI_STATUS_TIMED_OUT)
goto end_sequence;
- if (IPA_CLIENT_IS_CONS(ep->client)) {
- IPADBG("Inject a DMA_TASK with 1B packet to IPA\n");
- /* Send a 1B packet DMA_TASK to IPA and try again */
- res = ipa3_inject_dma_task_for_gsi();
- if (res) {
- IPAERR("Failed to inject DMA TASk for GSI\n");
- goto end_sequence;
- }
+ IPADBG("Inject a DMA_TASK with 1B packet to IPA\n");
+ /* Send a 1B packet DMA_TASK to IPA and try again */
+ res = ipa3_inject_dma_task_for_gsi();
+ if (res) {
+ IPAERR("Failed to inject DMA TASk for GSI\n");
+ goto end_sequence;
}
/* sleep for short period to flush IPA */
diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index 0c2ba4d..5cc04c0 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -241,18 +241,28 @@
static int cmd_db_dev_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct resource res;
+ void __iomem *dict;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
+ dict = of_iomap(pdev->dev.of_node, 0);
+ if (!dict) {
cmd_db_status = -ENOMEM;
goto failed;
}
- start_addr = devm_ioremap_resource(&pdev->dev, res);
+ /*
+ * Read start address and size of the command DB address from
+ * shared dictionary location
+ */
+ res.start = readl_relaxed(dict);
+ res.end = res.start + readl_relaxed(dict + 0x4);
+ res.flags = IORESOURCE_MEM;
+ iounmap(dict);
- cmd_db_header = devm_kzalloc(&pdev->dev, sizeof(*cmd_db_header),
- GFP_KERNEL);
+ start_addr = devm_ioremap_resource(&pdev->dev, &res);
+
+ cmd_db_header = devm_kzalloc(&pdev->dev,
+ sizeof(*cmd_db_header), GFP_KERNEL);
if (!cmd_db_header) {
cmd_db_status = -ENOMEM;
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index fb3d7d9..c5ba279 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -75,6 +75,10 @@
#define MSS_RESTART_ID 0xA
#define MSS_MAGIC 0XAABADEAD
+
+#define MSS_PDC_OFFSET 8
+#define MSS_PDC_MASK BIT(MSS_PDC_OFFSET)
+
enum scm_cmd {
PAS_MEM_SETUP_CMD = 2,
};
@@ -204,6 +208,33 @@
clk_disable_unprepare(drv->ahb_clk);
}
+static void pil_mss_pdc_sync(struct q6v5_data *drv, bool pdc_sync)
+{
+ u32 val = 0;
+
+ if (drv->pdc_sync) {
+ val = readl_relaxed(drv->pdc_sync);
+ if (pdc_sync)
+ val |= MSS_PDC_MASK;
+ else
+ val &= ~MSS_PDC_MASK;
+ writel_relaxed(val, drv->pdc_sync);
+ /* Ensure PDC is written before next write */
+ wmb();
+ udelay(2);
+ }
+}
+
+static void pil_mss_alt_reset(struct q6v5_data *drv, u32 val)
+{
+ if (drv->alt_reset) {
+ writel_relaxed(val, drv->alt_reset);
+ /* Ensure alt reset is written before restart reg */
+ wmb();
+ udelay(2);
+ }
+}
+
static int pil_mss_restart_reg(struct q6v5_data *drv, u32 mss_restart)
{
int ret = 0;
@@ -235,6 +266,32 @@
return ret;
}
+static int pil_mss_assert_resets(struct q6v5_data *drv)
+{
+ int ret = 0;
+
+ pil_mss_pdc_sync(drv, 1);
+ pil_mss_alt_reset(drv, 1);
+ ret = pil_mss_restart_reg(drv, true);
+
+ return ret;
+}
+
+static int pil_mss_deassert_resets(struct q6v5_data *drv)
+{
+ int ret = 0;
+
+ ret = pil_mss_restart_reg(drv, 0);
+ if (ret)
+ return ret;
+ /* Wait 6 32kHz sleep cycles for reset */
+ udelay(200);
+ pil_mss_alt_reset(drv, 0);
+ pil_mss_pdc_sync(drv, false);
+
+ return ret;
+}
+
static int pil_msa_wait_for_mba_ready(struct q6v5_data *drv)
{
struct device *dev = drv->desc.dev;
@@ -304,7 +361,10 @@
ret);
}
- ret = pil_mss_restart_reg(drv, 1);
+ pil_mss_assert_resets(drv);
+ /* Wait 6 32kHz sleep cycles for reset */
+ udelay(200);
+ ret = pil_mss_deassert_resets(drv);
if (drv->is_booted) {
pil_mss_disable_clks(drv);
@@ -450,6 +510,7 @@
{
struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
phys_addr_t start_addr = pil_get_entry_addr(pil);
+ u32 debug_val;
int ret;
if (drv->mba_dp_phys)
@@ -463,15 +524,22 @@
if (ret)
goto err_power;
- /* Deassert reset to subsystem and wait for propagation */
- ret = pil_mss_restart_reg(drv, 0);
- if (ret)
- goto err_restart;
-
ret = pil_mss_enable_clks(drv);
if (ret)
goto err_clks;
+ /* Save state of modem debug register before full reset */
+ debug_val = readl_relaxed(drv->reg_base + QDSP6SS_DBG_CFG);
+
+ /* Assert reset to subsystem */
+ pil_mss_assert_resets(drv);
+ /* Wait 6 32kHz sleep cycles for reset */
+ udelay(200);
+ ret = pil_mss_deassert_resets(drv);
+ if (ret)
+ goto err_restart;
+
+ writel_relaxed(debug_val, drv->reg_base + QDSP6SS_DBG_CFG);
if (modem_dbg_cfg)
writel_relaxed(modem_dbg_cfg, drv->reg_base + QDSP6SS_DBG_CFG);
@@ -519,12 +587,11 @@
err_q6v5_reset:
modem_log_rmb_regs(drv->rmb_base);
+err_restart:
pil_mss_disable_clks(drv);
if (drv->ahb_clk_vote)
clk_disable_unprepare(drv->ahb_clk);
err_clks:
- pil_mss_restart_reg(drv, 1);
-err_restart:
pil_mss_power_down(drv);
err_power:
return ret;
diff --git a/drivers/soc/qcom/pil-q6v5-mss.c b/drivers/soc/qcom/pil-q6v5-mss.c
index bbde4b6..df0c609c 100644
--- a/drivers/soc/qcom/pil-q6v5-mss.c
+++ b/drivers/soc/qcom/pil-q6v5-mss.c
@@ -284,6 +284,20 @@
if (!q6->restart_reg)
return -ENOMEM;
+ q6->pdc_sync = NULL;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdc_sync");
+ if (res) {
+ q6->pdc_sync = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ }
+
+ q6->alt_reset = NULL;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "alt_reset");
+ if (res) {
+ q6->alt_reset = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ }
+
q6->vreg = NULL;
prop = of_find_property(pdev->dev.of_node, "vdd_mss-supply", NULL);
diff --git a/drivers/soc/qcom/pil-q6v5.h b/drivers/soc/qcom/pil-q6v5.h
index 1725253..9b4c811 100644
--- a/drivers/soc/qcom/pil-q6v5.h
+++ b/drivers/soc/qcom/pil-q6v5.h
@@ -44,6 +44,8 @@
void __iomem *axi_halt_mss;
void __iomem *axi_halt_nc;
void __iomem *restart_reg;
+ void __iomem *pdc_sync;
+ void __iomem *alt_reset;
struct regulator *vreg;
struct regulator *vreg_cx;
struct regulator *vreg_mx;
diff --git a/drivers/soc/qcom/system_pm.c b/drivers/soc/qcom/system_pm.c
index 2855a15..d8c5a8f 100644
--- a/drivers/soc/qcom/system_pm.c
+++ b/drivers/soc/qcom/system_pm.c
@@ -56,9 +56,13 @@
* Set up the wake up value offset from the current time.
* Convert us to ns to allow div by 19.2 Mhz tick timer.
*/
- sleep_val *= NSEC_PER_USEC;
- do_div(sleep_val, NSEC_PER_SEC/ARCH_TIMER_HZ);
- sleep_val += arch_counter_get_cntvct();
+ if (sleep_val) {
+ sleep_val *= NSEC_PER_USEC;
+ do_div(sleep_val, NSEC_PER_SEC/ARCH_TIMER_HZ);
+ sleep_val += arch_counter_get_cntvct();
+ } else {
+ sleep_val = ~0ULL;
+ }
return setup_wakeup(sleep_val);
}
diff --git a/drivers/thermal/qcom/msm_lmh_dcvs.c b/drivers/thermal/qcom/msm_lmh_dcvs.c
index 74f5ce0..bfaf7c7 100644
--- a/drivers/thermal/qcom/msm_lmh_dcvs.c
+++ b/drivers/thermal/qcom/msm_lmh_dcvs.c
@@ -57,6 +57,7 @@
#define LIMITS_DOMAIN_MIN 0x444D494E
#define LIMITS_TEMP_DEFAULT 75000
+#define LIMITS_TEMP_HIGH_THRESH_MAX 120000
#define LIMITS_LOW_THRESHOLD_OFFSET 500
#define LIMITS_POLLING_DELAY_MS 10
#define LIMITS_CLUSTER_0_REQ 0x179C1B04
@@ -259,7 +260,7 @@
struct limits_dcvs_hw *hw = (struct limits_dcvs_hw *)data;
int ret = 0;
- if (high < LIMITS_LOW_THRESHOLD_OFFSET || low < 0) {
+ if (high >= LIMITS_TEMP_HIGH_THRESH_MAX || low < 0) {
pr_err("Value out of range low:%d high:%d\n",
low, high);
return -EINVAL;
diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h
index c190446..f05155b 100644
--- a/include/uapi/linux/msm_kgsl.h
+++ b/include/uapi/linux/msm_kgsl.h
@@ -67,6 +67,8 @@
#define KGSL_CONTEXT_TYPE_RS 4
#define KGSL_CONTEXT_TYPE_UNKNOWN 0x1E
+#define KGSL_CONTEXT_INVALIDATE_ON_FAULT 0x10000000
+
#define KGSL_CONTEXT_INVALID 0xffffffff
/*
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index f93db0e..a0d45ef 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2438,15 +2438,6 @@
$herecurr);
}
$shorttext = AFTER_SHORTTEXT;
- } elsif (length($line) > (SHORTTEXT_LIMIT +
- $shorttext_exspc)
- && $line !~ /^:([0-7]{6}\s){2}
- ([[:xdigit:]]+\.*
- \s){2}\w+\s\w+/xms) {
- WARN("LONG_COMMIT_TEXT",
- "commit text line over " .
- SHORTTEXT_LIMIT .
- " characters\n" . $herecurr);
} elsif ($line=~/^\s*change-id:/i ||
$line=~/^\s*signed-off-by:/i ||
$line=~/^\s*crs-fixed:/i ||
diff --git a/sound/soc/msm/sdm845.c b/sound/soc/msm/sdm845.c
index 0f41387..304bf47 100644
--- a/sound/soc/msm/sdm845.c
+++ b/sound/soc/msm/sdm845.c
@@ -155,6 +155,21 @@
u32 index;
};
+enum pinctrl_pin_state {
+ STATE_DISABLE = 0, /* All pins are in sleep state */
+ STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */
+ STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */
+};
+
+struct msm_pinctrl_info {
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *mi2s_disable;
+ struct pinctrl_state *tdm_disable;
+ struct pinctrl_state *mi2s_active;
+ struct pinctrl_state *tdm_active;
+ enum pinctrl_pin_state curr_state;
+};
+
struct msm_asoc_mach_data {
u32 mclk_freq;
int us_euro_gpio; /* used by gpio driver API */
@@ -162,6 +177,7 @@
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
struct snd_info_entry *codec_root;
+ struct msm_pinctrl_info pinctrl_info;
};
struct msm_asoc_wcd93xx_codec {
@@ -170,6 +186,9 @@
void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec);
};
+static const char *const pin_states[] = {"sleep", "i2s-active",
+ "tdm-active"};
+
enum {
TDM_0 = 0,
TDM_1,
@@ -3803,6 +3822,275 @@
return ret;
}
+static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info,
+ enum pinctrl_pin_state new_state)
+{
+ int ret = 0;
+ int curr_state = 0;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ curr_state = pinctrl_info->curr_state;
+ pinctrl_info->curr_state = new_state;
+ pr_debug("%s: curr_state = %s new_state = %s\n", __func__,
+ pin_states[curr_state], pin_states[pinctrl_info->curr_state]);
+
+ if (curr_state == pinctrl_info->curr_state) {
+ pr_debug("%s: Already in same state\n", __func__);
+ goto err;
+ }
+
+ if (curr_state != STATE_DISABLE &&
+ pinctrl_info->curr_state != STATE_DISABLE) {
+ pr_debug("%s: state already active cannot switch\n", __func__);
+ ret = -EIO;
+ goto err;
+ }
+
+ switch (pinctrl_info->curr_state) {
+ case STATE_MI2S_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_active);
+ if (ret) {
+ pr_err("%s: MI2S state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_TDM_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_active);
+ if (ret) {
+ pr_err("%s: TDM state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_DISABLE:
+ if (curr_state == STATE_MI2S_ACTIVE) {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ } else {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_disable);
+ }
+ if (ret) {
+ pr_err("%s: state disable failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ default:
+ pr_err("%s: TLMM pin state is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+err:
+ return ret;
+}
+
+static void msm_release_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info->pinctrl) {
+ devm_pinctrl_put(pinctrl_info->pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ }
+}
+
+static int msm_get_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = NULL;
+ struct pinctrl *pinctrl;
+ int ret;
+
+ pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR_OR_NULL(pinctrl)) {
+ pr_err("%s: Unable to get pinctrl handle\n", __func__);
+ return -EINVAL;
+ }
+ pinctrl_info->pinctrl = pinctrl;
+
+ /* get all the states handles from Device Tree */
+ pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-sleep");
+ if (IS_ERR(pinctrl_info->mi2s_disable)) {
+ pr_err("%s: could not get mi2s_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-active");
+ if (IS_ERR(pinctrl_info->mi2s_active)) {
+ pr_err("%s: could not get mi2s_active pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-sleep");
+ if (IS_ERR(pinctrl_info->tdm_disable)) {
+ pr_err("%s: could not get tdm_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-active");
+ if (IS_ERR(pinctrl_info->tdm_active)) {
+ pr_err("%s: could not get tdm_active pinstate\n",
+ __func__);
+ goto err;
+ }
+ /* Reset the TLMM pins to a default state */
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ if (ret != 0) {
+ pr_err("%s: Disable TLMM pins failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ pinctrl_info->curr_state = STATE_DISABLE;
+
+ return 0;
+
+err:
+ devm_pinctrl_put(pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ return -EINVAL;
+}
+
+static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
+ } else {
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
+static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ /*2 slot config - bits 0 and 1 set for the first two slots */
+ slot_mask = 0x0000FFFF >> (16-slots);
+ slot_width = 32;
+ channels = slots;
+
+ pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("%s: slot_width %d\n", __func__, slot_width);
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ 0, NULL, channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ pr_err("%s: invalid use case, err:%d\n",
+ __func__, ret);
+ }
+
+end:
+ return ret;
+}
+
+static int sdm845_tdm_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static void sdm845_tdm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+
+}
+
+static struct snd_soc_ops sdm845_tdm_be_ops = {
+ .hw_params = sdm845_tdm_snd_hw_params,
+ .startup = sdm845_tdm_snd_startup,
+ .shutdown = sdm845_tdm_snd_shutdown
+};
+
static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
{
int ret = 0;
@@ -3810,6 +4098,9 @@
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int index = cpu_dai->id;
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
dev_dbg(rtd->card->dev,
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
@@ -3823,6 +4114,14 @@
__func__, cpu_dai->id);
goto err;
}
+ if (index == QUAT_MI2S) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE);
+ if (ret) {
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
/*
* Muxtex protection in case the same MI2S
* interface using for both TX and RX so
@@ -3875,6 +4174,9 @@
int ret;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
int index = rtd->cpu_dai->id;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
pr_debug("%s(): substream = %s stream = %d\n", __func__,
substream->name, substream->stream);
@@ -3893,6 +4195,13 @@
}
}
mutex_unlock(&mi2s_intf_conf[index].lock);
+
+ if (index == QUAT_MI2S) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
}
static struct snd_soc_ops msm_mi2s_be_ops = {
@@ -4930,8 +5239,8 @@
.no_pcm = 1,
.dpcm_playback = 1,
.id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &sdm845_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -6297,6 +6606,17 @@
dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
ret);
+ /* Parse pinctrl info from devicetree */
+ ret = msm_get_pinctrl(pdev);
+ if (!ret) {
+ pr_debug("%s: pinctrl parsing successful\n", __func__);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: Parsing pinctrl failed with %d. Cannot use Ports\n",
+ __func__, ret);
+ ret = 0;
+ }
+
msm_i2s_auxpcm_init(pdev);
is_initial_boot = true;
@@ -6308,6 +6628,7 @@
return 0;
err:
+ msm_release_pinctrl(pdev);
devm_kfree(&pdev->dev, pdata);
return ret;
}
@@ -6324,6 +6645,7 @@
}
msm_i2s_auxpcm_deinit();
+ msm_release_pinctrl(pdev);
snd_soc_unregister_card(card);
return 0;
}