aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-06-21 03:16:55 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-06-21 03:16:55 -0700
commitd96dd278eb4cb0755bc77ea866d9ea75bd169b3c (patch)
treee69ef3ba8cb663c3e78331a59b1ace911a571001
parentcb2608fb6c759ccab3470f841778a7130fa10a09 (diff)
parentc6f5ddba623003a06b373def156264fa993723df (diff)
Merge c6f5ddba623003a06b373def156264fa993723df on remote branchLA.UM.7.3.r1-07900-sdm845.0
Change-Id: I05e169bcbc3c51c7205311c29bb9418fd65afe88
-rw-r--r--arch/arm64/boot/dts/qcom/qcs605.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/qm215-regulator.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sdm670-sde.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts3
-rw-r--r--arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts3
-rw-r--r--arch/arm64/configs/sdm670-perf_defconfig1
-rw-r--r--arch/arm64/configs/sdm670_defconfig1
-rw-r--r--arch/arm64/include/asm/pgtable.h1
-rw-r--r--arch/arm64/mm/mmu.c33
-rw-r--r--drivers/char/adsprpc.c63
-rw-r--r--drivers/char/diag/diag_dci.c18
-rw-r--r--drivers/char/diag/diag_masks.c4
-rw-r--r--drivers/char/diag/diagfwd.c9
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_display.c3
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c27
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder.c20
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder.h9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys.h2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c9
-rw-r--r--drivers/gpu/msm/kgsl.c4
-rw-r--r--drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c79
-rw-r--r--drivers/media/platform/msm/camera_v2/camera/camera.c33
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c9
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c11
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c20
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm.h13
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_hw_core.c40
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_core/cam_context.c2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c9
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c40
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c10
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c16
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/hfi.c13
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c6
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c220
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c104
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h25
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c133
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c68
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c8
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c23
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c74
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h43
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c71
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h157
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c11
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c6
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c41
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_debug_util.h44
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c10
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c9
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c5
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_clocks.c4
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c10
-rw-r--r--drivers/mmc/core/sd.c5
-rw-r--r--drivers/nvmem/Kconfig10
-rw-r--r--drivers/nvmem/Makefile3
-rw-r--r--drivers/nvmem/core.c237
-rw-r--r--drivers/nvmem/nvmem-sysfs.c230
-rw-r--r--drivers/nvmem/nvmem.h62
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c35
-rw-r--r--drivers/soc/qcom/icnss.c17
-rw-r--r--drivers/soc/qcom/msm_smem.c167
-rw-r--r--drivers/soc/qcom/smcinvoke.c6
-rw-r--r--include/uapi/media/cam_isp.h20
-rw-r--r--kernel/sched/fair.c47
90 files changed, 1897 insertions, 602 deletions
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dtsi b/arch/arm64/boot/dts/qcom/qcs605.dtsi
index c437ef1dbfac..6f46c7ed2886 100644
--- a/arch/arm64/boot/dts/qcom/qcs605.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605.dtsi
@@ -84,6 +84,10 @@
status = "disabled";
};
+&sde_dp {
+ qcom,max-pclk-frequency-khz = <675000>;
+};
+
&mem_dump {
rpmh {
qcom,dump-size = <0x400000>;
diff --git a/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi b/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi
index a6dc66a7621e..6b44215b8ab9 100644
--- a/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/qm215-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 2018-2019, 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
@@ -549,9 +549,15 @@
qcom,cpr-voltage-scaling-factor-max = <0 2000 2000>;
qcom,cpr-scaled-init-voltage-as-ceiling;
qcom,cpr-fuse-revision = <69 39 3 0>;
+ qcom,pvs-version-fuse-sel = <37 40 3 0>; /* foundry */
+ qcom,cpr-fuse-version-map =
+ <(-1) 1 (-1) (-1) (-1) (-1)>,
+ <(-1) (-1) (-1) (-1) (-1) (-1)>;
qcom,cpr-quotient-adjustment =
+ <30 20 0>,
<50 40 50>;
qcom,cpr-init-voltage-adjustment =
+ <0 0 0>,
<30000 5000 10000>;
qcom,cpr-enable;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
index cef55344925f..867193af64cc 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019 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
@@ -15,6 +15,8 @@
&blsp1_uart2 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
};
&pm8953_gpios {
diff --git a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
index 913d079bdb98..e1623e0b960d 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, 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
@@ -15,6 +15,8 @@
&blsp1_uart2 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
};
&pm8953_gpios {
diff --git a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
index 4da0e524e9cb..537d9fc278d8 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,8 @@
&blsp1_uart2 {
status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
};
&sdhc_1 {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
index 9a567a39ff3d..cf31c40f7076 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -605,7 +605,7 @@
qcom,aux-cfg8-settings = [40 bb];
qcom,aux-cfg9-settings = [44 03];
- qcom,max-pclk-frequency-khz = <675000>;
+ qcom,max-pclk-frequency-khz = <300000>;
qcom,ctrl-supply-entries {
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
index 109c72006b88..7c69f192d6cc 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-apq8009w-wtp.dts
@@ -25,7 +25,8 @@
compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
qcom,msm-id = <265 0>,
<301 0>;
- qcom,board-id = <8 0x10f>;
+ qcom,board-id = <8 0x10f>,
+ <8 0x117>;
qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>,
<0x0001011b 0x0 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
index 34c887dc2915..7bd95f164690 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-1gb-wtp.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,7 +27,8 @@
<258 0>,
<275 0>,
<300 0>;
- qcom,board-id = <8 0xf>;
+ qcom,board-id = <8 0xf>,
+ <8 0x17>;
qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>,
<0x0001011b 0x0 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
index 5df6dc42f122..e271b89c6b49 100644
--- a/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdw3100-msm8909w-wtp.dts
@@ -26,8 +26,7 @@
qcom,msm-id = <245 0>,
<258 0>,
<275 0>,
- <300 0>,
- <301 0>;
+ <300 0>;
qcom,board-id = <8 0x10f>,
<8 0x117>;
qcom,pmic-id = <0x0001001b 0x0 0x0 0x0>,
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index 5c305104dd12..2d7eb0f59ac2 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -580,6 +580,7 @@ CONFIG_ARM_GIC_V3_ACL=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_NVMEM=y
+# CONFIG_NVMEM_SYSFS is not set
CONFIG_QCOM_QFPROM=y
CONFIG_SENSORS_SSC=y
CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 35539f0aaba2..9e588c5ccd7b 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -600,6 +600,7 @@ CONFIG_PHY_XGENE=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_NVMEM=y
+# CONFIG_NVMEM_SYSFS is not set
CONFIG_QCOM_QFPROM=y
CONFIG_SENSORS_SSC=y
CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9f1bba621829..cd63d71551fe 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -386,6 +386,7 @@ static inline int pmd_protnone(pmd_t pmd)
#define pud_write(pud) pte_write(pud_pte(pud))
#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pud(pfn,prot) (__pud(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6e989ebdb9ca..a9dbfc9893a7 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -135,6 +135,17 @@ static phys_addr_t __init early_pgtable_alloc(void)
return phys;
}
+static bool pgattr_change_is_safe(u64 old, u64 new)
+{
+ /*
+ * The following mapping attributes may be updated in live
+ * kernel mappings without the need for break-before-make.
+ */
+ static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE;
+
+ return old == 0 || new == 0 || ((old ^ new) & ~mask) == 0;
+}
+
static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
pgprot_t prot,
@@ -826,23 +837,33 @@ int __init arch_ioremap_pmd_supported(void)
int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot)
{
- /* ioremap_page_range doesn't honour BBM */
- if (pud_present(READ_ONCE(*pud)))
+ pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
+ pgprot_val(mk_sect_prot(prot)));
+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), sect_prot);
+
+ /* Only allow permission changes for now */
+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pud)),
+ pud_val(new_pud)))
return 0;
BUG_ON(phys & ~PUD_MASK);
- set_pud(pud, __pud(phys | PUD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ set_pud(pud, new_pud);
return 1;
}
int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot)
{
- /* ioremap_page_range doesn't honour BBM */
- if (pmd_present(READ_ONCE(*pmd)))
+ pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
+ pgprot_val(mk_sect_prot(prot)));
+ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), sect_prot);
+
+ /* Only allow permission changes for now */
+ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmd)),
+ pmd_val(new_pmd)))
return 0;
BUG_ON(phys & ~PMD_MASK);
- set_pmd(pmd, __pmd(phys | PMD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ set_pmd(pmd, new_pmd);
return 1;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 2d0574200459..b066cb03e811 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -224,9 +224,11 @@ struct smq_invoke_ctx {
int tgid;
remote_arg_t *lpra;
remote_arg64_t *rpra;
+ remote_arg64_t *lrpra; /* Local copy of rpra for put_args */
int *fds;
struct fastrpc_mmap **maps;
struct fastrpc_buf *buf;
+ struct fastrpc_buf *lbuf;
size_t used;
struct fastrpc_file *fl;
uint32_t sc;
@@ -620,8 +622,13 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
if (va >= map->va &&
va + len <= map->va + map->len &&
map->fd == fd) {
- if (refs)
+ if (refs) {
+ if (map->refs + 1 == INT_MAX) {
+ spin_unlock(&me->hlock);
+ return -ETOOMANYREFS;
+ }
map->refs++;
+ }
match = map;
break;
}
@@ -632,8 +639,11 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
if (va >= map->va &&
va + len <= map->va + map->len &&
map->fd == fd) {
- if (refs)
+ if (refs) {
+ if (map->refs + 1 == INT_MAX)
+ return -ETOOMANYREFS;
map->refs++;
+ }
match = map;
break;
}
@@ -1272,6 +1282,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
mutex_unlock(&ctx->fl->fl_map_mutex);
fastrpc_buf_free(ctx->buf, 1);
+ fastrpc_buf_free(ctx->lbuf, 1);
ctx->magic = 0;
ctx->ctxid = 0;
@@ -1418,7 +1429,7 @@ static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
{
struct fastrpc_apps *me = &gfa;
- remote_arg64_t *rpra;
+ remote_arg64_t *rpra, *lrpra;
remote_arg_t *lpra = ctx->lpra;
struct smq_invoke_buf *list;
struct smq_phy_page *pages, *ipage;
@@ -1427,7 +1438,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
int handles, bufs = inbufs + outbufs;
uintptr_t args;
- size_t rlen = 0, copylen = 0, metalen = 0;
+ size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
int i, oix;
int err = 0;
int mflags = 0;
@@ -1485,7 +1496,20 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
metalen = copylen = (size_t)&ipage[0];
}
- /* calculate len requreed for copying */
+ /* allocate new local rpra buffer */
+ lrpralen = (size_t)&list[0];
+ if (lrpralen) {
+ err = fastrpc_buf_alloc(ctx->fl, lrpralen, 0, 0, 0, &ctx->lbuf);
+ if (err)
+ goto bail;
+ }
+ if (ctx->lbuf->virt)
+ memset(ctx->lbuf->virt, 0, lrpralen);
+
+ lrpra = ctx->lbuf->virt;
+ ctx->lrpra = lrpra;
+
+ /* calculate len required for copying */
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
uintptr_t mstart, mend;
@@ -1536,13 +1560,13 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
/* map ion buffers */
PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_MAP),
- for (i = 0; rpra && i < inbufs + outbufs; ++i) {
+ for (i = 0; rpra && lrpra && i < inbufs + outbufs; ++i) {
struct fastrpc_mmap *map = ctx->maps[i];
uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
size_t len = lpra[i].buf.len;
- rpra[i].buf.pv = 0;
- rpra[i].buf.len = len;
+ rpra[i].buf.pv = lrpra[i].buf.pv = 0;
+ rpra[i].buf.len = lrpra[i].buf.len = len;
if (!len)
continue;
if (map) {
@@ -1570,7 +1594,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
pages[idx].addr = map->phys + offset;
pages[idx].size = num << PAGE_SHIFT;
}
- rpra[i].buf.pv = buf;
+ rpra[i].buf.pv = lrpra[i].buf.pv = buf;
}
PERF_END);
for (i = bufs; i < bufs + handles; ++i) {
@@ -1590,7 +1614,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
/* copy non ion buffers */
PERF(ctx->fl->profile, GET_COUNTER(perf_counter, PERF_COPY),
rlen = copylen - metalen;
- for (oix = 0; rpra && oix < inbufs + outbufs; ++oix) {
+ for (oix = 0; rpra && lrpra && oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
struct fastrpc_mmap *map = ctx->maps[i];
size_t mlen;
@@ -1609,7 +1633,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
VERIFY(err, rlen >= mlen);
if (err)
goto bail;
- rpra[i].buf.pv = (args - ctx->overps[oix]->offset);
+ rpra[i].buf.pv = lrpra[i].buf.pv =
+ (args - ctx->overps[oix]->offset);
pages[list[i].pgidx].addr = ctx->buf->phys -
ctx->overps[oix]->offset +
(copylen - rlen);
@@ -1641,7 +1666,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
if (map && (map->attr & FASTRPC_ATTR_COHERENT))
continue;
- if (rpra && rpra[i].buf.len && ctx->overps[oix]->mstart) {
+ if (rpra && lrpra && rpra[i].buf.len &&
+ ctx->overps[oix]->mstart) {
if (map && map->handle)
msm_ion_do_cache_op(ctx->fl->apps->client,
map->handle,
@@ -1655,10 +1681,11 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
}
}
PERF_END);
- for (i = bufs; rpra && i < bufs + handles; i++) {
- rpra[i].dma.fd = ctx->fds[i];
- rpra[i].dma.len = (uint32_t)lpra[i].buf.len;
- rpra[i].dma.offset = (uint32_t)(uintptr_t)lpra[i].buf.pv;
+ for (i = bufs; rpra && lrpra && i < bufs + handles; i++) {
+ rpra[i].dma.fd = lrpra[i].dma.fd = ctx->fds[i];
+ rpra[i].dma.len = lrpra[i].dma.len = (uint32_t)lpra[i].buf.len;
+ rpra[i].dma.offset = lrpra[i].dma.offset =
+ (uint32_t)(uintptr_t)lpra[i].buf.pv;
}
bail:
@@ -1676,7 +1703,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
uint64_t *fdlist = NULL;
uint32_t *crclist = NULL;
- remote_arg64_t *rpra = ctx->rpra;
+ remote_arg64_t *rpra = ctx->lrpra;
int i, inbufs, outbufs, handles;
int err = 0;
@@ -1783,7 +1810,7 @@ static void inv_args(struct smq_invoke_ctx *ctx)
{
int i, inbufs, outbufs;
uint32_t sc = ctx->sc;
- remote_arg64_t *rpra = ctx->rpra;
+ remote_arg64_t *rpra = ctx->lrpra;
inbufs = REMOTE_SCALARS_INBUFS(sc);
outbufs = REMOTE_SCALARS_OUTBUFS(sc);
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 5a1afd0e41c7..bb4c16b4fa07 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -986,7 +986,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
int save_req_uid = 0;
struct diag_dci_pkt_rsp_header_t pkt_rsp_header;
- if (!buf) {
+ if (!buf || len <= 0) {
pr_err("diag: Invalid pointer in %s\n", __func__);
return;
}
@@ -1000,6 +1000,8 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
dci_cmd_code);
return;
}
+ if (len < (cmd_code_len + sizeof(int)))
+ return;
temp += cmd_code_len;
tag = *(int *)temp;
temp += sizeof(int);
@@ -1008,10 +1010,16 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
* The size of the response is (total length) - (length of the command
* code, the tag (int)
*/
- rsp_len = len - (cmd_code_len + sizeof(int));
- if ((rsp_len == 0) || (rsp_len > (len - 5))) {
- pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d",
- __func__, len, rsp_len);
+ if (len >= cmd_code_len + sizeof(int)) {
+ rsp_len = len - (cmd_code_len + sizeof(int));
+ if ((rsp_len == 0) || (rsp_len > (len - 5))) {
+ pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d\n",
+ __func__, len, rsp_len);
+ return;
+ }
+ } else {
+ pr_err("diag:%s: Invalid length(%d) for calculating rsp_len\n",
+ __func__, len);
return;
}
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 8d53a06c62a3..27aa81948423 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2019, 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
@@ -703,7 +703,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
mask_info = (!info) ? &msg_mask : info->msg_mask;
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
- !mask_info) {
+ !mask_info || (src_len < sizeof(struct diag_build_mask_req_t))) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
__func__, src_buf, src_len, dest_buf, dest_len,
mask_info);
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index d637405a71d1..b930d476ce55 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -707,7 +707,8 @@ int diag_process_time_sync_query_cmd(unsigned char *src_buf, int src_len,
struct diag_cmd_time_sync_query_req_t *req = NULL;
struct diag_cmd_time_sync_query_rsp_t rsp;
- if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
+ if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
+ src_len < sizeof(struct diag_cmd_time_sync_query_req_t)) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d",
__func__, src_buf, src_len, dest_buf, dest_len);
return -EINVAL;
@@ -737,7 +738,8 @@ int diag_process_diag_id_query_cmd(unsigned char *src_buf, int src_len,
int num_entries = 0;
uint8_t process_name_len = 0;
- if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
+ if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
+ src_len < sizeof(struct diag_cmd_diag_id_query_req_t)) {
pr_err("diag: Invalid input in %s, src_buf:%pK, src_len:%d, dest_buf:%pK, dest_len:%d\n",
__func__, src_buf, src_len, dest_buf, dest_len);
return -EINVAL;
@@ -783,7 +785,8 @@ int diag_process_time_sync_switch_cmd(unsigned char *src_buf, int src_len,
int msg_size = sizeof(struct diag_ctrl_msg_time_sync);
int err = 0, write_len = 0;
- if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
+ if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
+ src_len < sizeof(struct diag_cmd_time_sync_switch_req_t)) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d",
__func__, src_buf, src_len, dest_buf, dest_len);
return -EINVAL;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 612cea70f4f1..1d4cc994de3d 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -1036,6 +1036,9 @@ static ssize_t debugfs_dump_info_read(struct file *file,
"\tClock master = %s\n",
display->ctrl[display->clk_master_idx].ctrl->name);
+ if (len > user_len)
+ len = user_len;
+
if (copy_to_user(user_buf, buf, len)) {
kfree(buf);
return -EFAULT;
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index e0094d7ec766..bb7c63e37645 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -757,6 +757,25 @@ static bool sde_crtc_mode_fixup(struct drm_crtc *crtc,
return true;
}
+static int _sde_crtc_get_ctlstart_timeout(struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder;
+ int rc = 0;
+
+ if (!crtc || !crtc->dev)
+ return 0;
+
+ list_for_each_entry(encoder,
+ &crtc->dev->mode_config.encoder_list, head) {
+ if (encoder->crtc != crtc)
+ continue;
+
+ if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_CMD)
+ rc += sde_encoder_get_ctlstart_timeout_state(encoder);
+ }
+
+ return rc;
+}
static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer,
struct sde_plane_state *pstate, struct sde_format *format)
@@ -3160,7 +3179,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
if (unlikely(!sde_crtc->num_mixers))
return;
- _sde_crtc_blend_setup(crtc, old_state, true);
+ if (_sde_crtc_get_ctlstart_timeout(crtc)) {
+ _sde_crtc_blend_setup(crtc, old_state, false);
+ SDE_ERROR("border fill only commit after ctlstart timeout\n");
+ } else {
+ _sde_crtc_blend_setup(crtc, old_state, true);
+ }
+
_sde_crtc_dest_scaler_setup(crtc);
/* cancel the idle notify delayed work */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 122f319c7c00..4dd37dc11f00 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -3114,6 +3114,24 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc)
return 0;
}
+int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *drm_enc)
+{
+ struct sde_encoder_virt *sde_enc = NULL;
+ int i, count = 0;
+
+ if (!drm_enc)
+ return 0;
+
+ sde_enc = to_sde_encoder_virt(drm_enc);
+
+ for (i = 0; i < sde_enc->num_phys_encs; i++) {
+ count += atomic_read(&sde_enc->phys_encs[i]->ctlstart_timeout);
+ atomic_set(&sde_enc->phys_encs[i]->ctlstart_timeout, 0);
+ }
+
+ return count;
+}
+
/**
* _sde_encoder_trigger_flush - trigger flush for a physical encoder
* drm_enc: Pointer to drm encoder structure
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h
index c40db41adecf..38ae13cae082 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -264,4 +264,11 @@ int sde_encoder_in_clone_mode(struct drm_encoder *enc);
*/
void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable);
+/**
+ * sde_encoder_get_ctlstart_timeout_state - checks if ctl start timeout happened
+ * @drm_enc: Pointer to drm encoder structure
+ * @Return: non zero value if ctl start timeout occurred
+ */
+int sde_encoder_get_ctlstart_timeout_state(struct drm_encoder *enc);
+
#endif /* __SDE_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index 953106ee9823..ab007b61e59a 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -267,6 +267,7 @@ struct sde_encoder_irq {
* @pending_retire_fence_cnt: Atomic counter tracking the pending retire
* fences that have to be signalled.
* @pending_kickoff_wq: Wait queue for blocking until kickoff completes
+ * @ctlstart_timeout: Indicates if ctl start timeout occurred
* @irq: IRQ tracking structures
* @cont_splash_single_flush Variable to check if single flush is enabled.
* @cont_splash_settings Variable to store continuous splash settings.
@@ -301,6 +302,7 @@ struct sde_encoder_phys {
atomic_t pending_kickoff_cnt;
atomic_t pending_retire_fence_cnt;
wait_queue_head_t pending_kickoff_wq;
+ atomic_t ctlstart_timeout;
struct sde_encoder_irq irq[INTR_IDX_MAX];
u32 cont_splash_single_flush;
bool cont_splash_settings;
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
index 4409408ba3fe..d6e8fd34e051 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019 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
@@ -193,6 +193,7 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
phys_enc,
SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE);
atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
+ atomic_set(&phys_enc->ctlstart_timeout, 0);
}
/* notify all synchronous clients first, then asynchronous clients */
@@ -292,6 +293,7 @@ static void sde_encoder_phys_cmd_ctl_start_irq(void *arg, int irq_idx)
ctl = phys_enc->hw_ctl;
atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
+ atomic_set(&phys_enc->ctlstart_timeout, 0);
time_diff_us = ktime_us_delta(ktime_get(), cmd_enc->rd_ptr_timestamp);
@@ -1054,6 +1056,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
SDE_ERROR("invalid encoder\n");
return;
}
+ atomic_set(&phys_enc->ctlstart_timeout, 0);
SDE_DEBUG_CMDENC(cmd_enc, "pp %d state %d\n",
phys_enc->hw_pp->idx - PINGPONG_0,
phys_enc->enable_state);
@@ -1176,6 +1179,9 @@ static int _sde_encoder_phys_cmd_wait_for_ctl_start(
"ctl start interrupt wait failed\n");
else
ret = 0;
+
+ if (sde_encoder_phys_cmd_is_master(phys_enc))
+ atomic_inc_return(&phys_enc->ctlstart_timeout);
}
return ret;
@@ -1476,6 +1482,7 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
atomic_set(&cmd_enc->pending_rd_ptr_cnt, 0);
atomic_set(&cmd_enc->pending_vblank_cnt, 0);
+ atomic_set(&phys_enc->ctlstart_timeout, 0);
init_waitqueue_head(&phys_enc->pending_kickoff_wq);
init_waitqueue_head(&cmd_enc->pending_vblank_wq);
atomic_set(&cmd_enc->autorefresh.kickoff_cnt, 0);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index eb4c29d535d5..596d17381799 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2019, 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
@@ -327,7 +327,7 @@ kgsl_mem_entry_destroy(struct kref *kref)
entry->memdesc.sgt->nents, i) {
page = sg_page(sg);
for (j = 0; j < (sg->length >> PAGE_SHIFT); j++)
- set_page_dirty(nth_page(page, j));
+ set_page_dirty_lock(nth_page(page, j));
}
}
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 45f88b3e79da..48f4a95d5603 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
@@ -2580,8 +2580,8 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
struct cam_hw_prepare_update_args *prepare = NULL;
if (!blob_data || (blob_size == 0) || !blob_info) {
- CAM_ERR(CAM_ISP, "Invalid info blob %pK %d prepare %pK",
- blob_data, blob_size, prepare);
+ CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK",
+ blob_data, blob_size, blob_info);
return -EINVAL;
}
@@ -2600,8 +2600,29 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
switch (blob_type) {
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: {
- struct cam_isp_resource_hfr_config *hfr_config =
- (struct cam_isp_resource_hfr_config *)blob_data;
+ struct cam_isp_resource_hfr_config *hfr_config;
+
+ if (blob_size < sizeof(struct cam_isp_resource_hfr_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
+ return -EINVAL;
+ }
+
+ hfr_config = (struct cam_isp_resource_hfr_config *)blob_data;
+
+ if (hfr_config->num_ports > CAM_ISP_IFE_OUT_RES_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid num_ports %u in hfr config",
+ hfr_config->num_ports);
+ return -EINVAL;
+ }
+
+ if (blob_size < (sizeof(uint32_t) * 2 + hfr_config->num_ports *
+ sizeof(struct cam_isp_port_hfr_config))) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size, (unsigned long)(sizeof(uint32_t)
+ * 2 + sizeof(struct cam_isp_port_hfr_config) *
+ hfr_config->num_ports));
+ return -EINVAL;
+ }
rc = cam_isp_blob_hfr_update(blob_type, blob_info,
hfr_config, prepare);
@@ -2610,8 +2631,29 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG: {
- struct cam_isp_clock_config *clock_config =
- (struct cam_isp_clock_config *)blob_data;
+ struct cam_isp_clock_config *clock_config;
+
+ if (blob_size < sizeof(struct cam_isp_clock_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
+ return -EINVAL;
+ }
+
+ clock_config = (struct cam_isp_clock_config *)blob_data;
+
+ if (clock_config->num_rdi > CAM_IFE_RDI_NUM_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid num_rdi %u in clock config",
+ clock_config->num_rdi);
+ return -EINVAL;
+ }
+
+ if (blob_size < (sizeof(uint32_t) * 2 + sizeof(uint64_t) *
+ (clock_config->num_rdi + 2))) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size, (unsigned long)(sizeof(uint32_t)
+ * 2 + sizeof(uint64_t) *
+ (clock_config->num_rdi + 2)));
+ return -EINVAL;
+ }
rc = cam_isp_blob_clock_update(blob_type, blob_info,
clock_config, prepare);
@@ -2620,10 +2662,31 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG: {
- struct cam_isp_bw_config *bw_config =
- (struct cam_isp_bw_config *)blob_data;
+ struct cam_isp_bw_config *bw_config;
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+ if (blob_size < sizeof(struct cam_isp_bw_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
+ return -EINVAL;
+ }
+
+ bw_config = (struct cam_isp_bw_config *)blob_data;
+
+ if (bw_config->num_rdi > CAM_IFE_RDI_NUM_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config",
+ bw_config->num_rdi);
+ return -EINVAL;
+ }
+
+ if (blob_size < (sizeof(uint32_t) * 2 + (bw_config->num_rdi + 2)
+ * sizeof(struct cam_isp_bw_vote))) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size, (unsigned long)(sizeof(uint32_t)
+ * 2 + (bw_config->num_rdi + 2)
+ * sizeof(struct cam_isp_bw_vote)));
+ return -EINVAL;
+ }
+
if (!prepare || !prepare->priv ||
(bw_config->usage_type >= CAM_IFE_HW_NUM_MAX)) {
CAM_ERR(CAM_ISP, "Invalid inputs");
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 01ee5d45b024..cd1c7f10b4ec 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -369,9 +369,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- if (WARN_ON(!sp->vb2_q.drv_priv))
- return -ENOMEM;
-
+ mutex_lock(sp->vb2_q.lock);
+ if (WARN_ON(!sp->vb2_q.drv_priv)) {
+ rc = -ENOMEM;
+ mutex_unlock(sp->vb2_q.lock);
+ goto done;
+ }
memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data,
sizeof(struct msm_v4l2_format_data));
user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv;
@@ -381,27 +384,29 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
/* num_planes need to bound checked, otherwise for loop
* can execute forever
*/
- if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES))
- return -EINVAL;
+ if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) {
+ rc = -EINVAL;
+ mutex_unlock(sp->vb2_q.lock);
+ goto done;
+ }
for (i = 0; i < user_fmt->num_planes; i++)
pr_debug("%s: plane size[%d]\n", __func__,
user_fmt->plane_sizes[i]);
-
+ mutex_unlock(sp->vb2_q.lock);
if (msm_is_daemon_present() != false) {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
MSM_CAMERA_PRIV_S_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
- return rc;
-
+ goto done;
rc = camera_check_event_status(&event);
if (rc < 0)
- return rc;
+ goto done;
}
sp->is_vb2_valid = 1;
}
-
+done:
return rc;
}
@@ -600,6 +605,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep)
pr_err("%s : memory not available\n", __func__);
return -ENOMEM;
}
+ q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
+ if (!q->lock) {
+ kzfree(q->drv_priv);
+ return -ENOMEM;
+ }
+ mutex_init(q->lock);
q->mem_ops = msm_vb2_get_q_mem_ops();
q->ops = msm_vb2_get_q_ops();
@@ -619,6 +630,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep)
kzfree(sp->vb2_q.drv_priv);
mutex_lock(&sp->lock);
vb2_queue_release(&sp->vb2_q);
+ mutex_destroy(sp->vb2_q.lock);
+ kzfree(sp->vb2_q.lock);
mutex_unlock(&sp->lock);
}
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index 9a21282531f9..f1ed1c90085a 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation.
- * All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2019, 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
@@ -367,12 +366,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
CDBG("%s disable %s\n", __func__,
clk_info[i].clk_name);
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
}
@@ -386,10 +386,11 @@ cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 1ddbb94d66b9..4d4fd78c6a6e 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, 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
@@ -538,6 +538,12 @@ static void msm_isp_cfg_framedrop_reg(
enum msm_vfe_input_src frame_src = SRC_TO_INTF(stream_info->stream_src);
int i;
+ if (vfe_dev == NULL) {
+ pr_err("%s %d returning vfe_dev is NULL\n",
+ __func__, __LINE__);
+ return;
+ }
+
if (vfe_dev->axi_data.src_info[frame_src].frame_id >=
stream_info->init_frame_drop)
runtime_init_frame_drop = 0;
@@ -3550,7 +3556,8 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
/* As MCT is still processing it, need to drop the additional requests*/
- if (vfe_dev->isp_page->drop_reconfig) {
+ if (vfe_dev->isp_page->drop_reconfig &&
+ frame_src == VFE_PIX_0) {
pr_err("%s: MCT has not yet delayed %d drop request %d\n",
__func__, vfe_dev->isp_page->drop_reconfig, frame_id);
goto error;
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 6e528a65ecc3..b29a6f65ee41 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_ctxs[])
{
int i;
- struct msm_v4l2_format_data *data = q->drv_priv;
+ struct msm_v4l2_format_data *data = NULL;
+ int rc = -EINVAL;
+
+ mutex_lock(q->lock);
+ data = q->drv_priv;
if (!data) {
pr_err("%s: drv_priv NULL\n", __func__);
- return -EINVAL;
+ goto done;
}
if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES))
- return -EINVAL;
+ goto done;
*num_planes = data->num_planes;
@@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
} else {
pr_err("%s: Unsupported buf type :%d\n", __func__,
data->type);
- return -EINVAL;
+ goto done;
}
- return 0;
+ rc = 0;
+
+done:
+ mutex_unlock(q->lock);
+ return rc;
}
static int msm_vb2_buf_init(struct vb2_buffer *vb)
diff --git a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm.h b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm.h
index ff8be3570bc5..178d33dee308 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm.h
+++ b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -251,6 +251,17 @@ struct cam_cdm_intf_mgr {
int32_t refcount;
};
+/**
+ * struct cam_cdm_debugfs_entry : debugfs entry struct
+ *
+ * @dentry : entry of debugfs
+ * @dump_register : flag to dump registers
+ */
+struct cam_cdm_debugfs_entry {
+ struct dentry *dentry;
+ bool dump_register;
+};
+
int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t *index);
diff --git a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c
index 506de5e88309..b1f4fe87e8fa 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_core_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -280,6 +280,7 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_hw_core.c
index e1809a1d789c..af83aba7a0bc 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_hw_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cdm/cam_cdm_hw_core.c
@@ -38,6 +38,8 @@
static void cam_hw_cdm_work(struct work_struct *work);
+static struct cam_cdm_debugfs_entry debugfs_entry;
+
/* DT match table entry for all CDM variants*/
static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
{
@@ -69,6 +71,31 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb(struct cam_hw_info *cdm_hw,
return rc;
}
+static int cam_hw_cdm_create_debugfs_entry(void)
+{
+ int rc = 0;
+
+ debugfs_entry.dentry = debugfs_create_dir("camera_cdm", NULL);
+ if (!debugfs_entry.dentry)
+ return -ENOMEM;
+
+ if (!debugfs_create_bool("dump_register",
+ 0644,
+ debugfs_entry.dentry,
+ &debugfs_entry.dump_register)) {
+ CAM_ERR(CAM_CDM,
+ "failed to create dump_register entry");
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ return rc;
+err:
+ debugfs_remove_recursive(debugfs_entry.dentry);
+ debugfs_entry.dentry = NULL;
+ return rc;
+}
+
static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw,
bool enable)
{
@@ -186,6 +213,9 @@ void cam_hw_cdm_dump_core_debug_registers(
{
uint32_t dump_reg, core_dbg, loop_cnt;
+ if (!debugfs_entry.dump_register)
+ return;
+
mutex_lock(&cdm_hw->hw_mutex);
cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg);
CAM_ERR(CAM_CDM, "CDM HW core status=%x", dump_reg);
@@ -482,6 +512,14 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
if ((!rc) && (hw_vaddr_ptr) && (len) &&
(len >= cdm_cmd->cmd[i].offset)) {
+
+ if ((len - cdm_cmd->cmd[i].offset) <
+ cdm_cmd->cmd[i].len) {
+ CAM_ERR(CAM_CDM, "Not enough buffer");
+ rc = -EINVAL;
+ break;
+ }
+
CAM_DBG(CAM_CDM, "Got the HW VA");
if (core->bl_tag >=
(CAM_CDM_HWFIFO_SIZE - 1))
@@ -947,6 +985,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(cdm_core->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
@@ -1011,6 +1050,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
}
cdm_hw->open_count--;
mutex_unlock(&cdm_hw->hw_mutex);
+ cam_hw_cdm_create_debugfs_entry();
CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx);
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c
index 98f72da87df6..42f5a840de46 100644
--- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c
+++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context.c
@@ -248,7 +248,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
rc = ctx->state_machine[ctx->state].pagefault_ops(ctx, iova,
buf_info);
} else {
- CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
+ CAM_INFO(CAM_CORE, "No dump ctx in dev %d, state %d",
ctx->dev_hdl, ctx->state);
}
mutex_unlock(&ctx->ctx_mutex);
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
index 174469e473da..330491256754 100644
--- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
@@ -482,9 +482,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
ctx->dev_name, ctx->ctx_id,
req->request_id);
- cam_context_putref(ctx);
-
- goto put_ref;
+ goto put_ctx_ref;
}
CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
req->in_map_entries[j].sync_id, rc);
@@ -493,7 +491,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
}
return rc;
-
+put_ctx_ref:
+ for (--j; j >= 0; j--)
+ cam_context_putref(ctx);
put_ref:
for (--i; i >= 0; i--) {
rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id);
@@ -1018,6 +1018,7 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
cmd_args.u.pf_args.pf_data.packet = packet;
+ cmd_args.u.pf_args.pf_data.ctx_id = ctx->ctx_id;
cmd_args.u.pf_args.iova = iova;
cmd_args.u.pf_args.buf_info = buf_info;
cmd_args.u.pf_args.mem_found = mem_found;
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h
index c3d1c2eff4e9..6b7a9007cff9 100644
--- a/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h
@@ -144,9 +144,11 @@ struct cam_hw_stop_args {
* struct cam_hw_mgr_dump_pf_data - page fault debug data
*
* packet: pointer to packet
+ * ctx_id: context id
*/
struct cam_hw_mgr_dump_pf_data {
void *packet;
+ uint32_t ctx_id;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
index 017e810e07c0..a05901afba71 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
@@ -620,7 +620,7 @@ static int cam_cpas_util_apply_client_axi_vote(
struct cam_cpas_client *temp_client;
struct cam_axi_vote req_axi_vote = *axi_vote;
struct cam_cpas_axi_port *axi_port = cpas_client->axi_port;
- uint64_t camnoc_bw = 0, mnoc_bw = 0;
+ uint64_t camnoc_bw = 0, mnoc_bw = 0, mnoc_bw_ab = 0;
int rc = 0;
if (!axi_port) {
@@ -632,14 +632,21 @@ static int cam_cpas_util_apply_client_axi_vote(
* Make sure we use same bw for both compressed, uncompressed
* in case client has requested either of one only
*/
- if (req_axi_vote.compressed_bw == 0)
+ if (req_axi_vote.compressed_bw == 0) {
req_axi_vote.compressed_bw = req_axi_vote.uncompressed_bw;
+ req_axi_vote.compressed_bw_ab = req_axi_vote.uncompressed_bw;
+ }
+
+ if (req_axi_vote.compressed_bw_ab == 0)
+ req_axi_vote.compressed_bw_ab = req_axi_vote.compressed_bw;
if (req_axi_vote.uncompressed_bw == 0)
req_axi_vote.uncompressed_bw = req_axi_vote.compressed_bw;
if ((cpas_client->axi_vote.compressed_bw ==
req_axi_vote.compressed_bw) &&
+ (cpas_client->axi_vote.compressed_bw_ab ==
+ req_axi_vote.compressed_bw_ab) &&
(cpas_client->axi_vote.uncompressed_bw ==
req_axi_vote.uncompressed_bw))
return 0;
@@ -651,23 +658,27 @@ static int cam_cpas_util_apply_client_axi_vote(
&axi_port->clients_list_head, axi_sibling_client) {
camnoc_bw += curr_client->axi_vote.uncompressed_bw;
mnoc_bw += curr_client->axi_vote.compressed_bw;
+ mnoc_bw_ab += curr_client->axi_vote.compressed_bw_ab;
}
if ((!soc_private->axi_camnoc_based) && (mnoc_bw < camnoc_bw))
mnoc_bw = camnoc_bw;
+ if ((!soc_private->axi_camnoc_based) && (mnoc_bw_ab < camnoc_bw))
+ mnoc_bw_ab = mnoc_bw;
+
axi_port->consolidated_axi_vote.compressed_bw = mnoc_bw;
axi_port->consolidated_axi_vote.uncompressed_bw = camnoc_bw;
CAM_DBG(CAM_CPAS,
- "axi[(%d, %d),(%d, %d)] : camnoc_bw[%llu], mnoc_bw[%llu]",
+ "axi[(%d, %d),(%d, %d)] : camnoc_bw[%llu], mnoc_bw[ab: %llu, ib: %llu]",
axi_port->mnoc_bus.src, axi_port->mnoc_bus.dst,
axi_port->camnoc_bus.src, axi_port->camnoc_bus.dst,
- camnoc_bw, mnoc_bw);
+ camnoc_bw, mnoc_bw_ab, mnoc_bw);
if (axi_port->ib_bw_voting_needed)
rc = cam_cpas_util_vote_bus_client_bw(&axi_port->mnoc_bus,
- mnoc_bw, mnoc_bw, false);
+ mnoc_bw_ab, mnoc_bw, false);
else
rc = cam_cpas_util_vote_bus_client_bw(&axi_port->mnoc_bus,
mnoc_bw, 0, false);
@@ -675,9 +686,7 @@ static int cam_cpas_util_apply_client_axi_vote(
if (rc) {
CAM_ERR(CAM_CPAS,
"Failed in mnoc vote ab[%llu] ib[%llu] rc=%d",
- mnoc_bw,
- (axi_port->ib_bw_voting_needed ? mnoc_bw : 0),
- rc);
+ mnoc_bw_ab, mnoc_bw, rc);
goto unlock_axi_port;
}
@@ -723,11 +732,13 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
axi_vote = *client_axi_vote;
if ((axi_vote.compressed_bw == 0) &&
- (axi_vote.uncompressed_bw == 0)) {
+ (axi_vote.uncompressed_bw == 0) &&
+ (axi_vote.compressed_bw_ab == 0)) {
CAM_DBG(CAM_CPAS, "0 vote from client_handle=%d",
client_handle);
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
}
if (!CAM_CPAS_CLIENT_VALID(client_indx))
@@ -746,10 +757,10 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
}
CAM_DBG(CAM_PERF,
- "Client=[%d][%s][%d] Requested compressed[%llu], uncompressed[%llu]",
+ "Client=[%d][%s][%d] Req comp[%llu], comp_ab[%llu], uncomp[%llu]",
client_indx, cpas_client->data.identifier,
cpas_client->data.cell_index, axi_vote.compressed_bw,
- axi_vote.uncompressed_bw);
+ axi_vote.compressed_bw_ab, axi_vote.uncompressed_bw);
rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
cpas_core->cpas_client[client_indx], &axi_vote);
@@ -1001,11 +1012,11 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
if (rc)
goto done;
- CAM_DBG(CAM_CPAS,
- "AXI client=[%d][%s][%d] compressed_bw[%llu], uncompressed_bw[%llu]",
+ CAM_INFO(CAM_CPAS,
+ "AXI client=[%d][%s][%d] comp[%llu], comp_ab[%llu], uncomp[%llu]",
client_indx, cpas_client->data.identifier,
cpas_client->data.cell_index, axi_vote->compressed_bw,
- axi_vote->uncompressed_bw);
+ axi_vote->compressed_bw_ab, axi_vote->uncompressed_bw);
rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
cpas_client, axi_vote);
if (rc)
@@ -1156,6 +1167,7 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args,
axi_vote.uncompressed_bw = 0;
axi_vote.compressed_bw = 0;
+ axi_vote.compressed_bw_ab = 0;
rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
cpas_client, &axi_vote);
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h b/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h
index 5dbd94a1fa9b..7b534a93c71d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -348,6 +348,7 @@ struct cam_ahb_vote {
struct cam_axi_vote {
uint64_t uncompressed_bw;
uint64_t compressed_bw;
+ uint64_t compressed_bw_ab;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
index 8403d4dbe533..887783321d19 100644
--- a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
@@ -595,6 +595,14 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
return -ENOMEM;
}
+ if (io_cfg[i].offsets[plane] >= size) {
+ CAM_ERR(CAM_FD,
+ "Invalid cpu buf %d %d %d",
+ io_cfg[i].direction,
+ io_cfg[i].resource_type, plane);
+ return -EINVAL;
+ }
+
io_addr[plane] += io_cfg[i].offsets[plane];
}
@@ -1598,7 +1606,7 @@ static int cam_fd_mgr_hw_prepare_update(void *hw_mgr_priv,
/* We do not expect any patching, but just do it anyway */
rc = cam_packet_util_process_patches(prepare->packet,
- hw_mgr->device_iommu.non_secure, -1);
+ hw_mgr->device_iommu.non_secure, -1, 0);
if (rc) {
CAM_ERR(CAM_FD, "Patch FD packet failed, rc=%d", rc);
return rc;
diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c
index adfd4d839a59..3b16789eece6 100644
--- a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -151,6 +151,7 @@ int cam_fd_soc_enable_resources(struct cam_hw_soc_info *soc_info)
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = 7200000;
+ axi_vote.compressed_bw_ab = 7200000;
axi_vote.uncompressed_bw = 7200000;
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c
index cd50cfb3f613..15574ba6a3f1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/cam_icp_context.c
@@ -45,6 +45,14 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
return -EINVAL;
}
+ mutex_lock(&ctx->ctx_mutex);
+
+ if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) {
+ CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d",
+ ctx->ctx_id, ctx->state);
+ goto end;
+ }
+
CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d",
ctx->ctx_id, ctx->state);
@@ -63,6 +71,8 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
req->request_id, rc);
}
+end:
+ mutex_unlock(&ctx->ctx_mutex);
return rc;
}
@@ -137,6 +147,12 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
return rc;
}
+ if ((len < sizeof(struct cam_packet)) ||
+ (cmd->offset >= (len - sizeof(struct cam_packet)))) {
+ CAM_ERR(CAM_CTXT, "Not enough buf");
+ return -EINVAL;
+ }
+
packet = (struct cam_packet *) ((uint8_t *)packet_addr +
(uint32_t)cmd->offset);
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/hfi.c b/drivers/media/platform/msm/camera_v3/cam_icp/hfi.c
index bf80938985f1..74b7aabb7655 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/hfi.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/hfi.c
@@ -43,7 +43,7 @@
#define HFI_MAX_POLL_TRY 5
#define HFI_MAX_PC_POLL_TRY 150
-#define HFI_POLL_TRY_SLEEP 2
+#define HFI_POLL_TRY_SLEEP 1
static struct hfi_info *g_hfi;
unsigned int g_icp_mmu_hdl;
@@ -73,24 +73,28 @@ void cam_hfi_queue_dump(void)
qtbl_hdr->qtbl_num_q, qtbl_hdr->qtbl_qhdr_size);
cmd_q_hdr = &qtbl->q_hdr[Q_CMD];
- CAM_DBG(CAM_HFI, "cmd: size = %u r_idx = %u w_idx = %u addr = %x",
+ CAM_INFO(CAM_HFI, "cmd: size = %u r_idx = %u w_idx = %u addr = %x",
cmd_q_hdr->qhdr_q_size, cmd_q_hdr->qhdr_read_idx,
cmd_q_hdr->qhdr_write_idx, hfi_mem->cmd_q.iova);
read_q = (uint32_t *)g_hfi->map.cmd_q.kva;
read_ptr = (uint32_t *)(read_q + 0);
+ CAM_INFO(CAM_HFI, "CMD Q %p", read_q);
CAM_DBG(CAM_HFI, "CMD Q START");
for (i = 0; i < ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; i++)
CAM_DBG(CAM_HFI, "Word: %d Data: 0x%08x ", i, read_ptr[i]);
+ CAM_DBG(CAM_HFI, "CMD Q END");
msg_q_hdr = &qtbl->q_hdr[Q_MSG];
- CAM_DBG(CAM_HFI, "msg: size = %u r_idx = %u w_idx = %u addr = %x",
+ CAM_INFO(CAM_HFI, "msg: size = %u r_idx = %u w_idx = %u addr = %x",
msg_q_hdr->qhdr_q_size, msg_q_hdr->qhdr_read_idx,
msg_q_hdr->qhdr_write_idx, hfi_mem->msg_q.iova);
read_q = (uint32_t *)g_hfi->map.msg_q.kva;
read_ptr = (uint32_t *)(read_q + 0);
+ CAM_INFO(CAM_HFI, "MSG Q %p", read_ptr);
CAM_DBG(CAM_HFI, "MSG Q START");
for (i = 0; i < ICP_MSG_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; i++)
CAM_DBG(CAM_HFI, "Word: %d Data: 0x%08x ", i, read_ptr[i]);
+ CAM_DBG(CAM_HFI, "MSG Q END");
}
int hfi_write_cmd(void *cmd_ptr)
@@ -526,7 +530,8 @@ void cam_hfi_disable_cpu(void __iomem *icp_base)
* and Host can the proceed. No interrupt is expected from FW
* at this time.
*/
- msleep_interruptible(HFI_POLL_TRY_SLEEP);
+ usleep_range(HFI_POLL_TRY_SLEEP * 1000,
+ (HFI_POLL_TRY_SLEEP * 1000) + 1000);
try++;
}
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c
index 18bd6d8dd2c7..e13d7f2edcee 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -268,6 +268,7 @@ int cam_a5_init_hw(void *device_priv,
cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
cpas_vote.axi_vote.compressed_bw = CAM_ICP_A5_BW_BYTES_VOTE;
+ cpas_vote.axi_vote.compressed_bw_ab = CAM_ICP_A5_BW_BYTES_VOTE;
cpas_vote.axi_vote.uncompressed_bw = CAM_ICP_A5_BW_BYTES_VOTE;
rc = cam_cpas_start(core_info->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c
index a330cff293d6..c94276ce8778 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/bps_hw/bps_core.c
@@ -164,11 +164,9 @@ static int cam_bps_handle_pc(struct cam_hw_info *bps_dev)
CAM_CPAS_REG_CPASTOP,
hw_info->pwr_ctrl, true, 0x1);
- if ((pwr_status >> BPS_PWR_ON_MASK)) {
- CAM_ERR(CAM_ICP, "BPS: pwr_status(%x):pwr_ctrl(%x)",
+ if ((pwr_status >> BPS_PWR_ON_MASK))
+ CAM_WARN(CAM_ICP, "BPS: pwr_status(%x):pwr_ctrl(%x)",
pwr_status, pwr_ctrl);
- return -EINVAL;
- }
}
cam_bps_get_gdsc_control(soc_info);
cam_cpas_reg_read(core_info->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 3a2d854fb1f4..b90fcd0be3c6 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -64,6 +64,37 @@ static struct cam_icp_hw_mgr icp_hw_mgr;
static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl);
+static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
+ int32_t buf_handle)
+{
+ uintptr_t vaddr_ptr;
+ uint32_t *ptr;
+ size_t len;
+ int rc, i;
+ char buf[512];
+ int used = 0;
+
+ rc = cam_mem_get_cpu_buf(buf_handle, &vaddr_ptr, &len);
+ if (rc) {
+ CAM_ERR(CAM_ICP, "Unable to get io_cfg buf address for %d",
+ ctx_data->ctx_id);
+ return rc;
+ }
+
+ len = len / sizeof(uint32_t);
+ ptr = (uint32_t *)vaddr_ptr;
+ for (i = 0; i < len; i++) {
+ used += snprintf(buf + used,
+ sizeof(buf) - used, "0X%08X-", ptr[i]);
+ if (!(i % 8)) {
+ CAM_INFO(CAM_ICP, "%s: %s", __func__, buf);
+ used = 0;
+ }
+ }
+
+ return rc;
+}
+
static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
{
struct cam_hw_intf *a5_dev_intf = NULL;
@@ -109,6 +140,7 @@ static void cam_icp_hw_mgr_reset_clk_info(struct cam_icp_hw_mgr *hw_mgr)
hw_mgr->clk_info[i].over_clked = 0;
hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ hw_mgr->clk_info[i].compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
}
hw_mgr->icp_default_clk = ICP_CLK_SVS_HZ;
}
@@ -245,6 +277,7 @@ static int cam_icp_ctx_clk_info_init(struct cam_icp_hw_ctx_data *ctx_data)
ctx_data->clk_info.base_clk = 0;
ctx_data->clk_info.uncompressed_bw = 0;
ctx_data->clk_info.compressed_bw = 0;
+ ctx_data->clk_info.compressed_bw_ab = 0;
cam_icp_supported_clk_rates(&icp_hw_mgr, ctx_data);
return 0;
@@ -403,10 +436,11 @@ static int32_t cam_icp_ctx_timer(void *priv, void *data)
}
CAM_DBG(CAM_ICP,
- "E :ctx_id = %d ubw = %lld cbw = %lld curr_fc = %u bc = %u",
+ "E :ctx_id %d, ubw %lld, cbw %lld, cbw_a %ld, curr_fc %u, bc %u",
ctx_data->ctx_id,
ctx_data->clk_info.uncompressed_bw,
ctx_data->clk_info.compressed_bw,
+ ctx_data->clk_info.compressed_bw_ab,
ctx_data->clk_info.curr_fc, ctx_data->clk_info.base_clk);
ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
@@ -436,9 +470,11 @@ static int32_t cam_icp_ctx_timer(void *priv, void *data)
}
clk_info->compressed_bw -= ctx_data->clk_info.compressed_bw;
+ clk_info->compressed_bw_ab -= ctx_data->clk_info.compressed_bw_ab;
clk_info->uncompressed_bw -= ctx_data->clk_info.uncompressed_bw;
ctx_data->clk_info.uncompressed_bw = 0;
ctx_data->clk_info.compressed_bw = 0;
+ ctx_data->clk_info.compressed_bw_ab = 0;
ctx_data->clk_info.curr_fc = 0;
ctx_data->clk_info.base_clk = 0;
@@ -446,16 +482,18 @@ static int32_t cam_icp_ctx_timer(void *priv, void *data)
clk_update.ahb_vote.vote.freq = 0;
clk_update.ahb_vote_valid = false;
clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
+ clk_update.axi_vote.compressed_bw_ab = clk_info->compressed_bw;
clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
clk_update.axi_vote_valid = true;
dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
&clk_update, sizeof(clk_update));
CAM_DBG(CAM_ICP,
- "X :ctx_id = %d ubw = %lld cbw = %lld curr_fc = %u bc = %u",
+ "X :ctx_id %d, ubw %lld cbw %lld abw_a %lld, curr_fc %u, bc %u",
ctx_data->ctx_id,
ctx_data->clk_info.uncompressed_bw,
ctx_data->clk_info.compressed_bw,
+ ctx_data->clk_info.compressed_bw_ab,
ctx_data->clk_info.curr_fc, ctx_data->clk_info.base_clk);
mutex_unlock(&ctx_data->ctx_mutex);
@@ -523,6 +561,7 @@ static int cam_icp_clk_info_init(struct cam_icp_hw_mgr *hw_mgr,
hw_mgr->clk_info[i].over_clked = 0;
hw_mgr->clk_info[i].uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
hw_mgr->clk_info[i].compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ hw_mgr->clk_info[i].compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
hw_mgr->clk_info[i].hw_type = i;
hw_mgr->clk_info[i].watch_dog_reset_counter = 0;
}
@@ -812,6 +851,7 @@ static bool cam_icp_debug_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_debug_clk;
hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_debug_clk;
+ hw_mgr_clk_info->compressed_bw_ab = icp_hw_mgr.icp_debug_clk;
CAM_DBG(CAM_ICP, "bc = %d cc = %d",
hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
return true;
@@ -827,6 +867,7 @@ static bool cam_icp_default_clk_update(struct cam_icp_clk_info *hw_mgr_clk_info)
hw_mgr_clk_info->curr_clk = icp_hw_mgr.icp_default_clk;
hw_mgr_clk_info->uncompressed_bw = icp_hw_mgr.icp_default_clk;
hw_mgr_clk_info->compressed_bw = icp_hw_mgr.icp_default_clk;
+ hw_mgr_clk_info->compressed_bw_ab = icp_hw_mgr.icp_default_clk;
CAM_DBG(CAM_ICP, "bc = %d cc = %d",
hw_mgr_clk_info->base_clk, hw_mgr_clk_info->curr_clk);
return true;
@@ -864,8 +905,10 @@ static bool cam_icp_update_bw(struct cam_icp_hw_mgr *hw_mgr,
ctx_data->clk_info.uncompressed_bw = clk_info->uncompressed_bw;
ctx_data->clk_info.compressed_bw = clk_info->compressed_bw;
+ ctx_data->clk_info.compressed_bw_ab = clk_info->compressed_bw;
hw_mgr_clk_info->uncompressed_bw = 0;
hw_mgr_clk_info->compressed_bw = 0;
+ hw_mgr_clk_info->compressed_bw_ab = 0;
for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
ctx = &hw_mgr->ctx_data[i];
if (ctx->state == CAM_ICP_CTX_STATE_ACQUIRED &&
@@ -877,9 +920,12 @@ static bool cam_icp_update_bw(struct cam_icp_hw_mgr *hw_mgr,
ctx->clk_info.uncompressed_bw;
hw_mgr_clk_info->compressed_bw +=
ctx->clk_info.compressed_bw;
- CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld",
+ hw_mgr_clk_info->compressed_bw_ab +=
+ ctx->clk_info.compressed_bw_ab;
+ CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld cbw_ab",
hw_mgr_clk_info->uncompressed_bw,
- hw_mgr_clk_info->compressed_bw);
+ hw_mgr_clk_info->compressed_bw,
+ hw_mgr_clk_info->compressed_bw_ab);
}
}
@@ -960,9 +1006,10 @@ static bool cam_icp_check_bw_update(struct cam_icp_hw_mgr *hw_mgr,
rc = cam_icp_update_bw(hw_mgr, ctx_data, hw_mgr_clk_info,
clk_info, busy);
- CAM_DBG(CAM_ICP, "ubw = %lld, cbw = %lld, update_bw = %d",
+ CAM_DBG(CAM_ICP, "ubw %lld, cbw %lld, cbw_a %lld, update_bw %d",
hw_mgr_clk_info->uncompressed_bw,
- hw_mgr_clk_info->compressed_bw, rc);
+ hw_mgr_clk_info->compressed_bw,
+ hw_mgr_clk_info->compressed_bw_ab, rc);
return rc;
}
@@ -1050,6 +1097,7 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
clk_update.ahb_vote.vote.freq = 0;
clk_update.ahb_vote_valid = false;
clk_update.axi_vote.compressed_bw = clk_info->compressed_bw;
+ clk_update.axi_vote.compressed_bw_ab = clk_info->compressed_bw;
clk_update.axi_vote.uncompressed_bw = clk_info->uncompressed_bw;
clk_update.axi_vote_valid = true;
dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
@@ -1063,8 +1111,10 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
* anyway.
*/
- CAM_DBG(CAM_ICP, "compress_bw %llu uncompress_bw %llu dev_type %d",
- clk_info->compressed_bw, clk_info->uncompressed_bw,
+ CAM_DBG(CAM_ICP,
+ "comp_bw %llu comp_bw_ab %lld uncomp_bw %llu dev_type %d",
+ clk_info->compressed_bw, clk_info->compressed_bw_ab,
+ clk_info->uncompressed_bw,
ctx_data->icp_dev_acquire_info->dev_type);
return 0;
@@ -1835,6 +1885,10 @@ static int cam_icp_mgr_process_fatal_error(
if (event_notify->event_id == HFI_EVENT_SYS_ERROR) {
CAM_INFO(CAM_ICP, "received HFI_EVENT_SYS_ERROR");
+ if (event_notify->event_data1 == HFI_ERR_SYS_FATAL) {
+ CAM_ERR(CAM_ICP, "received HFI_ERR_SYS_FATAL");
+ BUG();
+ }
rc = cam_icp_mgr_trigger_recovery(hw_mgr);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl);
}
@@ -3386,6 +3440,17 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
goto rel_cmd_buf;
}
*fw_cmd_buf_iova_addr = addr;
+
+ if (cmd_desc[i].offset >= len ||
+ ((len - cmd_desc[i].offset) <
+ cmd_desc[i].size)){
+ CAM_ERR(CAM_ICP,
+ "Invalid offset/length, i %d offset 0x%x len %u size 0x%x",
+ i, cmd_desc[i].offset,
+ (uint32_t)len, cmd_desc[i].size);
+ goto rel_cmd_buf;
+ }
+
*fw_cmd_buf_iova_addr =
(*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
@@ -3890,14 +3955,19 @@ static void cam_icp_mgr_print_io_bufs(struct cam_packet *packet,
}
CAM_INFO(CAM_ICP,
- "pln %d dir %d w %d h %d s %u sh %u sz %d addr 0x%x off 0x%x memh %x",
+ "pln %d dir %d w %d h %d s %u sh %u sz %d",
j, io_cfg[i].direction,
io_cfg[i].planes[j].width,
io_cfg[i].planes[j].height,
io_cfg[i].planes[j].plane_stride,
io_cfg[i].planes[j].slice_height,
- (int32_t)src_buf_size,
+ (uint32_t)src_buf_size);
+
+ CAM_INFO(CAM_ICP,
+ "addr (0x%x, 0x%x) off 0x%x memh %x",
(unsigned int)iova_addr,
+ ((unsigned int)iova_addr +
+ (uint32_t)src_buf_size),
io_cfg[i].offsets[j],
io_cfg[i].mem_handle[j]);
@@ -3982,8 +4052,12 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
packet = prepare_args->packet;
- if (cam_packet_util_validate_packet(packet, prepare_args->remain_len))
+ if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
+ mutex_unlock(&ctx_data->ctx_mutex);
+ CAM_ERR(CAM_ICP, "ctx id: %u packet req id %lld validate fail",
+ ctx_data->ctx_id, packet->header.request_id);
return -EINVAL;
+ }
rc = cam_icp_mgr_pkt_validation(packet);
if (rc) {
@@ -4004,7 +4078,7 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
packet->header.request_id, ctx_data->ctx_id);
/* Update Buffer Address from handles and patch information */
rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl,
- hw_mgr->iommu_sec_hdl);
+ hw_mgr->iommu_sec_hdl, 0);
if (rc) {
mutex_unlock(&ctx_data->ctx_mutex);
return rc;
@@ -4426,8 +4500,9 @@ static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr,
return -EINVAL;
}
- if (icp_dev_acquire_info.num_out_res > ICP_MAX_OUTPUT_SUPPORTED) {
- CAM_ERR(CAM_ICP, "num of out resources exceeding : %u",
+ if ((icp_dev_acquire_info.num_out_res > ICP_MAX_OUTPUT_SUPPORTED) ||
+ (icp_dev_acquire_info.num_out_res <= 0)) {
+ CAM_ERR(CAM_ICP, "Invalid num of out resources: %u",
icp_dev_acquire_info.num_out_res);
return -EINVAL;
}
@@ -4603,6 +4678,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
if (rc) {
CAM_ERR(CAM_ICP, "IO Config command failed %d", rc);
+ cam_icp_dump_io_cfg(ctx_data,
+ icp_dev_acquire_info->io_config_cmd_handle);
goto ioconfig_failed;
}
@@ -4932,6 +5009,110 @@ cmd_work_failed:
return rc;
}
+static int cam_icp_util_dump_frame_data(struct cam_packet *packet,
+ struct cam_icp_hw_mgr *hw_mgr, uint32_t ctx_id)
+{
+ int num_cmd_buf = 0, i = 0, rc = 0;
+ size_t len;
+ struct cam_cmd_buf_desc *cmd_desc = NULL;
+ uintptr_t cpu_addr = 0;
+ struct ipe_frame_process_data *ipe_frame_process_data = NULL;
+ struct bps_frame_process_data *bps_frame_process_data = NULL;
+ struct cam_icp_hw_ctx_data *ctx_data;
+
+ cmd_desc = (struct cam_cmd_buf_desc *)
+ ((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
+ ctx_data = &hw_mgr->ctx_data[ctx_id];
+
+ for (i = 0; i < packet->num_cmd_buf; i++, num_cmd_buf++) {
+ if (cmd_desc[i].type == CAM_CMD_BUF_FW) {
+ rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
+ &cpu_addr, &len);
+ if (rc || !cpu_addr) {
+ CAM_ERR(CAM_ICP, "get cmd buf failed %x",
+ hw_mgr->iommu_hdl);
+ return -EINVAL;
+ }
+ cpu_addr = cpu_addr + cmd_desc[i].offset;
+ break;
+ }
+ }
+
+ if (!cpu_addr) {
+ CAM_ERR(CAM_ICP, "CPU address is NULL");
+ return -ENOMEM;
+ }
+
+ if (ctx_data->icp_dev_acquire_info->dev_type !=
+ CAM_ICP_RES_TYPE_BPS) {
+ ipe_frame_process_data =
+ (struct ipe_frame_process_data *)cpu_addr;
+ CAM_INFO(CAM_ICP,
+ "IPE: requestID %d, maxCores %d, targetTime %d, batchSize %d",
+ ipe_frame_process_data->request_id,
+ ipe_frame_process_data->max_num_cores,
+ ipe_frame_process_data->target_time,
+ ipe_frame_process_data->frames_in_batch);
+ CAM_INFO(CAM_ICP,
+ "IPE: scratch 0x%016x sz %d ubwc addr 0x%016x sz %d",
+ ipe_frame_process_data->scratch_buffer_addr,
+ ipe_frame_process_data->scratch_buffer_size,
+ ipe_frame_process_data->ubwc_stats_buffer_addr,
+ ipe_frame_process_data->ubwc_stats_buffer_size);
+ CAM_INFO(CAM_ICP,
+ "IPE: iqSet 0x%016x striping 0x%016x cdm addr 0x%016x sz %d",
+ ipe_frame_process_data->iq_settings_addr,
+ ipe_frame_process_data->strip_lib_out_addr,
+ ipe_frame_process_data->cdm_buffer_addr,
+ ipe_frame_process_data->cdm_buffer_size);
+ CAM_INFO(CAM_ICP,
+ "IPE: cdmProgBase 0x%016x cdmPreLtm 0x%016x cdmPost:tm 0x%016x",
+ ipe_frame_process_data->cdm_prog_base,
+ ipe_frame_process_data->cdm_pre_ltm,
+ ipe_frame_process_data->cdm_post_ltm);
+ CAM_INFO(CAM_ICP,
+ "IPE: ANR 0x%016x, 0x%016x, 0x%016x, 0x%016x",
+ ipe_frame_process_data->cdm_anr_full_pass,
+ ipe_frame_process_data->cdm_anr_ds4,
+ ipe_frame_process_data->cdm_anr_ds16,
+ ipe_frame_process_data->cdm_anr_ds64);
+ CAM_INFO(CAM_ICP,
+ "IPE: TF 0x%016x, 0x%016x, 0x%016x, 0x%016x",
+ ipe_frame_process_data->cdm_tf_full_pass,
+ ipe_frame_process_data->cdm_tf_ds4,
+ ipe_frame_process_data->cdm_tf_ds16,
+ ipe_frame_process_data->cdm_tf_ds64);
+ for (i = 0; i < ipe_frame_process_data->frames_in_batch; i++) {
+ CAM_INFO(CAM_ICP,
+ "IPE: frame %d, ICA1Buf 0x%016x, ICA2Buf 0x%016x",
+ i+1,
+ ipe_frame_process_data->framesets[i].cdm_ica1_addr,
+ ipe_frame_process_data->framesets[i].cdm_ica2_addr);
+ }
+ } else {
+ bps_frame_process_data =
+ (struct bps_frame_process_data *)cpu_addr;
+ CAM_INFO(CAM_ICP,
+ "BPS: requestId %d targetTime %d maxCores %d",
+ bps_frame_process_data->request_id,
+ bps_frame_process_data->target_time,
+ bps_frame_process_data->max_num_cores);
+ CAM_INFO(CAM_ICP,
+ "BPS: ubwc addr 0x%016x sz %d cdm buff addr 0x%016x sz %d",
+ bps_frame_process_data->ubwc_stats_buffer_addr,
+ bps_frame_process_data->ubwc_stats_buffer_size,
+ bps_frame_process_data->cdm_buffer_addr,
+ bps_frame_process_data->cdm_buffer_size);
+ CAM_INFO(CAM_ICP,
+ "BPS: iqSet 0x%016x Striping 0x%016x cdmProgAddr 0x%016x",
+ bps_frame_process_data->iq_settings_addr,
+ bps_frame_process_data->strip_lib_out_addr,
+ bps_frame_process_data->cdm_prog_addr);
+ }
+
+ return rc;
+}
+
static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
int rc = 0;
@@ -4952,6 +5133,17 @@ static int cam_icp_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
hw_cmd_args->u.pf_args.buf_info,
hw_cmd_args->u.pf_args.mem_found);
+ cam_packet_util_process_patches(
+ hw_cmd_args->u.pf_args.pf_data.packet,
+ hw_mgr->iommu_hdl,
+ hw_mgr->iommu_sec_hdl,
+ 1);
+
+ cam_icp_util_dump_frame_data(
+ hw_cmd_args->u.pf_args.pf_data.packet,
+ hw_mgr,
+ hw_cmd_args->u.pf_args.pf_data.ctx_id);
+
break;
default:
CAM_ERR(CAM_ICP, "Invalid cmd");
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
index 5a93df33925f..9af4ccc96003 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
@@ -185,6 +185,7 @@ struct cam_ctx_clk_info {
uint32_t reserved;
uint64_t uncompressed_bw;
uint64_t compressed_bw;
+ uint64_t compressed_bw_ab;
int32_t clk_rate[CAM_MAX_VOTE];
};
/**
@@ -249,6 +250,7 @@ struct icp_cmd_generic_blob {
* @over_clked: Over clock count
* @uncompressed_bw: Current bandwidth voting
* @compressed_bw: Current compressed bandwidth voting
+ * @compressed_bw_ab: Current absolute compressed bandwidth voting
* @hw_type: IPE/BPS device type
* @watch_dog: watchdog timer handle
* @watch_dog_reset_counter: Counter for watch dog reset
@@ -260,6 +262,7 @@ struct cam_icp_clk_info {
uint32_t over_clked;
uint64_t uncompressed_bw;
uint64_t compressed_bw;
+ uint64_t compressed_bw_ab;
uint32_t hw_type;
struct cam_req_mgr_timer *watch_dog;
uint32_t watch_dog_reset_counter;
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c
index 1f71c7d4cd36..ae3d1343c1c4 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c
@@ -78,6 +78,7 @@ int cam_ipe_init_hw(void *device_priv,
cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
cpas_vote.axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ cpas_vote.axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
cpas_vote.axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(core_info->cpas_handle,
@@ -162,7 +163,8 @@ static int cam_ipe_handle_pc(struct cam_hw_info *ipe_dev)
hw_info->pwr_ctrl, true, 0x1);
if (pwr_status >> IPE_PWR_ON_MASK)
- return -EINVAL;
+ CAM_WARN(CAM_ICP, "BPS: pwr_status(%x):pwr_ctrl(%x)",
+ pwr_status, pwr_ctrl);
}
cam_ipe_get_gdsc_control(soc_info);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
index 8685e34e0ea9..2982ce027aa7 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
@@ -2541,6 +2541,8 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
ctx_isp->reported_req_id = 0;
ctx_isp->hw_acquired = false;
ctx_isp->init_received = false;
+ ctx_isp->rdi_only_context = false;
+ ctx_isp->split_acquire = false;
/*
* Ideally, we should never have any active request here.
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 582d4858e18b..177538acd0b0 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -43,7 +43,7 @@
(CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON + 1)
#define CAM_ISP_GENERIC_BLOB_TYPE_MAX \
- (CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG + 1)
+ (CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 + 1)
static uint32_t blob_type_hw_cmd_map[CAM_ISP_GENERIC_BLOB_TYPE_MAX] = {
CAM_ISP_HW_CMD_GET_HFR_UPDATE,
@@ -1691,6 +1691,14 @@ static int cam_ife_mgr_check_and_update_fe(
((uint8_t *)&acquire_hw_info->data +
acquire_hw_info->input_info_offset);
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
+
+ if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
+ (in_port->num_out_res <= 0)) {
+ CAM_ERR(CAM_ISP, "Invalid num output res %u",
+ in_port->num_out_res);
+ return -EINVAL;
+ }
+
in_port_length = sizeof(struct cam_isp_in_port_info) +
(in_port->num_out_res - 1) *
sizeof(struct cam_isp_out_port_info);
@@ -1927,7 +1935,6 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
cdm_acquire.base_array_cnt = j;
-
cdm_acquire.id = CAM_CDM_VIRTUAL;
cdm_acquire.cam_cdm_callback = cam_ife_cam_cdm_callback;
rc = cam_cdm_acquire(&cdm_acquire);
@@ -1943,21 +1950,23 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
acquire_hw_info =
(struct cam_isp_acquire_hw_info *)acquire_args->acquire_info;
- in_port = (struct cam_isp_in_port_info *)
- ((uint8_t *)&acquire_hw_info->data +
- acquire_hw_info->input_info_offset);
rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info);
if (rc) {
CAM_ERR(CAM_ISP, "buffer size is not enough");
- goto free_ctx;
+ goto free_cdm;
}
+ in_port = (struct cam_isp_in_port_info *)
+ ((uint8_t *)&acquire_hw_info->data +
+ acquire_hw_info->input_info_offset);
+
/* acquire HW resources */
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
- if (in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) {
- CAM_ERR(CAM_ISP, "too many output res %d",
+ if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
+ (in_port->num_out_res <= 0)) {
+ CAM_ERR(CAM_ISP, "Invalid num output res %u",
in_port->num_out_res);
rc = -EINVAL;
goto free_res;
@@ -2010,6 +2019,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
return 0;
free_res:
cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
+free_cdm:
cam_cdm_release(ife_ctx->cdm_handle);
free_ctx:
cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->free_ctx_list, &ife_ctx);
@@ -2202,6 +2212,7 @@ static int cam_ife_mgr_acquire(void *hw_mgr_priv,
static int cam_isp_blob_bw_update(
struct cam_isp_bw_config *bw_config,
+ struct cam_isp_bw_config_ab *bw_config_ab,
struct cam_ife_hw_mgr_ctx *ctx)
{
struct cam_ife_hw_mgr_res *hw_mgr_res;
@@ -2209,6 +2220,7 @@ static int cam_isp_blob_bw_update(
struct cam_vfe_bw_update_args bw_upd_args;
uint64_t cam_bw_bps = 0;
uint64_t ext_bw_bps = 0;
+ uint64_t ext_bw_bps_ab = 0;
int rc = -EINVAL;
uint32_t i;
bool camif_l_bw_updated = false;
@@ -2238,6 +2250,8 @@ static int cam_isp_blob_bw_update(
bw_config->left_pix_vote.cam_bw_bps;
ext_bw_bps =
bw_config->left_pix_vote.ext_bw_bps;
+ ext_bw_bps_ab =
+ bw_config_ab->left_pix_vote_ab;
camif_l_bw_updated = true;
} else {
@@ -2248,6 +2262,8 @@ static int cam_isp_blob_bw_update(
bw_config->right_pix_vote.cam_bw_bps;
ext_bw_bps =
bw_config->right_pix_vote.ext_bw_bps;
+ ext_bw_bps_ab =
+ bw_config_ab->right_pix_vote_ab;
camif_r_bw_updated = true;
}
@@ -2263,6 +2279,8 @@ static int cam_isp_blob_bw_update(
bw_config->rdi_vote[idx].cam_bw_bps;
ext_bw_bps =
bw_config->rdi_vote[idx].ext_bw_bps;
+ ext_bw_bps_ab =
+ bw_config_ab->rdi_vote_ab[idx];
} else if (hw_mgr_res->res_id ==
CAM_ISP_HW_VFE_IN_CAMIF_LITE) {
if (i == CAM_ISP_HW_SPLIT_LEFT) {
@@ -2273,6 +2291,8 @@ static int cam_isp_blob_bw_update(
bw_config->left_pix_vote.cam_bw_bps;
ext_bw_bps =
bw_config->left_pix_vote.ext_bw_bps;
+ ext_bw_bps_ab =
+ bw_config_ab->left_pix_vote_ab;
camif_l_bw_updated = true;
} else {
@@ -2283,6 +2303,9 @@ static int cam_isp_blob_bw_update(
bw_config->right_pix_vote.cam_bw_bps;
ext_bw_bps =
bw_config->right_pix_vote.ext_bw_bps;
+ ext_bw_bps_ab =
+ bw_config_ab->right_pix_vote_ab;
+
camif_r_bw_updated = true;
}
@@ -2301,6 +2324,8 @@ static int cam_isp_blob_bw_update(
bw_upd_args.camnoc_bw_bytes = cam_bw_bps;
bw_upd_args.external_bw_bytes = ext_bw_bps;
+ bw_upd_args.external_bw_bytes_ab =
+ ext_bw_bps_ab;
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
@@ -2351,10 +2376,15 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
hw_update_data = (struct cam_isp_prepare_hw_update_data *) cfg->priv;
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
+ CAM_DBG(CAM_ISP, "hw_update_data->bw_config_valid[%d]:%d", i,
+ hw_update_data->bw_config_valid[i]);
if (hw_update_data->bw_config_valid[i] == true) {
rc = cam_isp_blob_bw_update(
(struct cam_isp_bw_config *)
- &hw_update_data->bw_config[i], ctx);
+ &hw_update_data->bw_config[i],
+ (struct cam_isp_bw_config_ab *)
+ &hw_update_data->bw_config_ab[i],
+ ctx);
if (rc)
CAM_ERR(CAM_ISP, "Bandwidth Update Failed");
}
@@ -3557,9 +3587,9 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
}
if (blob_type >= CAM_ISP_GENERIC_BLOB_TYPE_MAX) {
- CAM_ERR(CAM_ISP, "Invalid Blob Type %d Max %d", blob_type,
+ CAM_WARN(CAM_ISP, "Invalid Blob Type %d Max %d", blob_type,
CAM_ISP_GENERIC_BLOB_TYPE_MAX);
- return -EINVAL;
+ return 0;
}
prepare = blob_info->prepare;
@@ -3668,13 +3698,60 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
prepare->priv;
-
memcpy(&prepare_hw_data->bw_config[bw_config->usage_type],
bw_config, sizeof(prepare_hw_data->bw_config[0]));
+ memset(&prepare_hw_data->bw_config_ab[bw_config->usage_type],
+ 0, sizeof(prepare_hw_data->bw_config_ab[0]));
prepare_hw_data->bw_config_valid[bw_config->usage_type] = true;
}
break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2: {
+ struct cam_isp_bw_config_ab *bw_config_ab;
+
+ struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+
+ if (blob_size < sizeof(struct cam_isp_bw_config_ab)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
+ return -EINVAL;
+ }
+
+ bw_config_ab = (struct cam_isp_bw_config_ab *)blob_data;
+
+ if (bw_config_ab->num_rdi > CAM_IFE_RDI_NUM_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid num_rdi %u in bw config ab",
+ bw_config_ab->num_rdi);
+ return -EINVAL;
+ }
+
+ if (blob_size < (sizeof(uint32_t) * 2
+ + (bw_config_ab->num_rdi + 2)
+ * sizeof(struct cam_isp_bw_vote))) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size,
+ sizeof(uint32_t) * 2
+ + (bw_config_ab->num_rdi + 2)
+ * sizeof(struct cam_isp_bw_vote));
+ return -EINVAL;
+ }
+ CAM_DBG(CAM_ISP, "AB L:%lld R:%lld usage_type %d",
+ bw_config_ab->left_pix_vote_ab,
+ bw_config_ab->right_pix_vote_ab,
+ bw_config_ab->usage_type);
+
+ if (!prepare || !prepare->priv ||
+ (bw_config_ab->usage_type >= CAM_IFE_HW_NUM_MAX)) {
+ CAM_ERR(CAM_ISP, "Invalid inputs");
+ rc = -EINVAL;
+ break;
+ }
+ prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
+ prepare->priv;
+
+ memcpy(&prepare_hw_data->bw_config_ab[bw_config_ab->usage_type],
+ bw_config_ab, sizeof(prepare_hw_data->bw_config_ab[0]));
+ }
+ break;
case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: {
struct cam_ubwc_config *ubwc_config;
@@ -3789,7 +3866,8 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
rc = cam_packet_util_process_patches(prepare->packet,
hw_mgr->mgr_common.cmd_iommu_hdl,
- hw_mgr->mgr_common.cmd_iommu_hdl_secure);
+ hw_mgr->mgr_common.cmd_iommu_hdl_secure,
+ 0);
if (rc) {
CAM_ERR(CAM_ISP, "Patch ISP packet failed.");
return rc;
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
index e9bcc98a8956..096e0f186bbf 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
@@ -95,6 +95,14 @@ struct cam_isp_start_args {
bool start_only;
};
+struct cam_isp_bw_config_internal_ab {
+ uint32_t usage_type;
+ uint32_t num_rdi;
+ uint64_t left_pix_vote_ab;
+ uint64_t right_pix_vote_ab;
+ uint64_t rdi_vote_ab[CAM_IFE_RDI_NUM_MAX];
+};
+
/**
* struct cam_isp_bw_config_internal - Internal Bandwidth configuration
*
@@ -106,11 +114,11 @@ struct cam_isp_start_args {
*/
struct cam_isp_bw_config_internal {
- uint32_t usage_type;
- uint32_t num_rdi;
- struct cam_isp_bw_vote left_pix_vote;
- struct cam_isp_bw_vote right_pix_vote;
- struct cam_isp_bw_vote rdi_vote[CAM_IFE_RDI_NUM_MAX];
+ uint32_t usage_type;
+ uint32_t num_rdi;
+ struct cam_isp_bw_vote left_pix_vote;
+ struct cam_isp_bw_vote right_pix_vote;
+ struct cam_isp_bw_vote rdi_vote[CAM_IFE_RDI_NUM_MAX];
};
/**
@@ -125,9 +133,10 @@ struct cam_isp_bw_config_internal {
*
*/
struct cam_isp_prepare_hw_update_data {
- uint32_t packet_opcode_type;
- struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX];
- bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
+ uint32_t packet_opcode_type;
+ struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX];
+ struct cam_isp_bw_config_internal_ab bw_config_ab[CAM_IFE_HW_NUM_MAX];
+ bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 2d6e23cb7961..8fba017cfe27 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -46,7 +46,7 @@
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12
/* Max CSI Rx irq error count threshold value */
-#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100
+#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 5
static int cam_ife_csid_is_ipp_ppp_format_supported(
uint32_t in_format)
@@ -1478,15 +1478,13 @@ static void cam_ife_csid_halt_csi2(
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
- CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
- csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
/* Disable the CSI2 rx inerrupts */
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ cam_io_w(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
/* Reset the Rx CFG registers */
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ cam_io_w(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
@@ -3091,13 +3089,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
- CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
- CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
- CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
- CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", irq_status_ppp);
- CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]);
- CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]);
- CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]);
+ CAM_DBG(CAM_ISP,
+ "CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_top,
+ irq_status_rx, irq_status_ipp, irq_status_ppp,
+ irq_status_rdi[0], irq_status_rdi[1], irq_status_rdi[2]);
if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
CAM_DBG(CAM_ISP, "csi rx reset complete");
@@ -3107,71 +3103,38 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
spin_lock_irqsave(&csid_hw->lock_state, flags);
if (csid_hw->device_enabled == 1) {
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d CPHY_EOT_RECEPTION",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d CPHY_SOT_RECEPTION",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
- if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
- csid_hw->hw_intf->hw_idx);
- }
if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d ERROR_STREAM_UNDERFLOW",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
}
- spin_unlock_irqrestore(&csid_hw->lock_state, flags);
if (csid_hw->error_irq_count >
CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
@@ -3179,8 +3142,15 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
csid_hw->error_irq_count = 0;
}
- if (fatal_err_detected)
+handle_fatal_error:
+ spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+ if (fatal_err_detected) {
+ CAM_INFO(CAM_ISP,
+ "CSID: %d cnt: %d Halt csi2 rx irq_status_rx:0x%x",
+ csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt,
+ irq_status_rx);
cam_ife_csid_halt_csi2(csid_hw);
+ }
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
@@ -3281,7 +3251,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
/* IPP reset done bit */
if (irq_status_ipp &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID IPP reset complete");
complete(&csid_hw->csid_ipp_complete);
}
@@ -3298,19 +3267,17 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
csid_hw->hw_intf->hw_idx);
- if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSID:%d IPP CCIF violation",
- csid_hw->hw_intf->hw_idx);
-
- if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d IPP fifo over flow",
- csid_hw->hw_intf->hw_idx);
- /* Stop IPP path immediately */
- cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
- soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+ "CSID:%d irq_status_ipp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ipp);
+ if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ /* Stop IPP path immediately */
+ cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+ }
}
}
@@ -3319,7 +3286,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
/* PPP reset done bit */
if (irq_status_ppp &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID PPP reset complete");
complete(&csid_hw->csid_ppp_complete);
}
@@ -3336,26 +3302,23 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
csid_hw->hw_intf->hw_idx);
- if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSID:%d PPP CCIF violation",
- csid_hw->hw_intf->hw_idx);
-
- if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_ppp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d PPP fifo over flow",
- csid_hw->hw_intf->hw_idx);
- /* Stop PPP path immediately */
- cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
- soc_info->reg_map[0].mem_base +
- csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+ "CSID:%d irq_status_ppp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ppp);
+ if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ /* Stop PPP path immediately */
+ cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+ }
}
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
if (irq_status_rdi[i] &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
complete(&csid_hw->csid_rdin_complete[i]);
}
@@ -3372,14 +3335,14 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID RDI:%d EOF received", i);
- if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSIDi RDI :%d CCIF violation", i);
-
- if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d RDI fifo over flow",
- csid_hw->hw_intf->hw_idx);
+ "CSID:%d irq_status_rdi[%d]:0x%x",
+ csid_hw->hw_intf->hw_idx, i,
+ irq_status_rdi[i]);
+ }
+ if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
/* Stop RDI path immediately */
cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c
index 5e02609088c4..eb9e63f30ba6 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c
@@ -129,6 +129,7 @@ int cam_ife_csid_enable_soc_resources(
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
CAM_DBG(CAM_ISP, "csid vote compressed_bw:%lld uncompressed_bw:%lld",
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
index f60bf6e4b3d4..9d6bcb71bb69 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
@@ -189,6 +189,7 @@ struct cam_vfe_bw_update_args {
struct cam_isp_resource_node *node_res;
uint64_t camnoc_bw_bytes;
uint64_t external_bw_bytes;
+ uint64_t external_bw_bytes_ab;
};
/*
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
index b57762644082..78dd64c4cccf 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
@@ -235,6 +235,7 @@ int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = 10640000000L;
+ axi_vote.compressed_bw_ab = 10640000000L;
axi_vote.uncompressed_bw = 10640000000L;
rc = cam_cpas_start(soc_private->cpas_handle[0], &ahb_vote, &axi_vote);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 569bbb6b2ce0..c5acbe5dbd16 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -34,7 +34,7 @@ struct cam_vfe_top_ver2_priv {
struct cam_vfe_top_ver2_common_data common_data;
struct cam_isp_resource_node mux_rsrc[CAM_VFE_TOP_VER2_MUX_MAX];
unsigned long hw_clk_rate;
- struct cam_axi_vote applied_axi_vote;
+ struct cam_axi_vote applied_axi_vote;
struct cam_axi_vote req_axi_vote[CAM_VFE_TOP_VER2_MUX_MAX];
unsigned long req_clk_rate[CAM_VFE_TOP_VER2_MUX_MAX];
struct cam_axi_vote last_vote[CAM_CPAS_HANDLE_MAX]
@@ -127,8 +127,8 @@ static int cam_vfe_top_set_axi_bw_vote(
struct cam_vfe_top_ver2_priv *top_priv,
bool start_stop)
{
- struct cam_axi_vote sum = {0, 0};
- struct cam_axi_vote to_be_applied_axi_vote = {0, 0};
+ struct cam_axi_vote sum = {0, 0, 0};
+ struct cam_axi_vote to_be_applied_axi_vote = {0, 0, 0};
int i, rc = 0;
struct cam_hw_soc_info *soc_info =
top_priv->common_data.soc_info;
@@ -137,6 +137,7 @@ static int cam_vfe_top_set_axi_bw_vote(
bool apply_bw_update = false;
enum cam_cpas_handle_id cpashdl_type;
struct cam_axi_vote *last_vote = NULL;
+ struct cam_axi_vote *applied_axi_vote = NULL;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Error soc_private NULL");
@@ -151,8 +152,10 @@ static int cam_vfe_top_set_axi_bw_vote(
continue;
sum.uncompressed_bw = sum.compressed_bw = 0;
+ sum.compressed_bw_ab = 0;
to_be_applied_axi_vote.uncompressed_bw = 0;
to_be_applied_axi_vote.compressed_bw = 0;
+ to_be_applied_axi_vote.compressed_bw_ab = 0;
apply_bw_update = false;
for (i = 0; i < CAM_VFE_TOP_VER2_MUX_MAX; i++) {
@@ -164,14 +167,20 @@ static int cam_vfe_top_set_axi_bw_vote(
top_priv->req_axi_vote[i].uncompressed_bw;
sum.compressed_bw +=
top_priv->req_axi_vote[i].compressed_bw;
+ sum.compressed_bw_ab +=
+ top_priv->req_axi_vote[i].compressed_bw_ab;
}
}
+ applied_axi_vote = &top_priv->applied_axi_vote;
- CAM_DBG(CAM_ISP, "Updating BW from (%llu %llu) to (%llu %llu)",
- top_priv->applied_axi_vote.uncompressed_bw,
- top_priv->applied_axi_vote.compressed_bw,
+ CAM_DBG(CAM_ISP,
+ "Updating BW (ib, ib, ab) from (%llu %llu %llu) to (%llu %llu %llu)",
+ applied_axi_vote->uncompressed_bw,
+ applied_axi_vote->compressed_bw,
+ applied_axi_vote->compressed_bw_ab,
sum.uncompressed_bw,
- sum.compressed_bw);
+ sum.compressed_bw,
+ sum.compressed_bw_ab);
last_vote = top_priv->last_vote[cpashdl_type];
@@ -181,13 +190,16 @@ static int cam_vfe_top_set_axi_bw_vote(
(CAM_VFE_TOP_VER2_MUX_MAX *
CAM_VFE_DELAY_BW_REDUCTION_NUM_FRAMES);
- if ((top_priv->applied_axi_vote.uncompressed_bw ==
+ if ((applied_axi_vote->uncompressed_bw ==
sum.uncompressed_bw) &&
- (top_priv->applied_axi_vote.compressed_bw ==
- sum.compressed_bw)) {
- CAM_DBG(CAM_ISP, "BW config unchanged %llu %llu",
- top_priv->applied_axi_vote.uncompressed_bw,
- top_priv->applied_axi_vote.compressed_bw);
+ (applied_axi_vote->compressed_bw ==
+ sum.compressed_bw) &&
+ (applied_axi_vote->compressed_bw_ab ==
+ sum.compressed_bw_ab)) {
+ CAM_DBG(CAM_ISP, "BW config unchanged %llu %llu %llu",
+ applied_axi_vote->uncompressed_bw,
+ applied_axi_vote->compressed_bw,
+ applied_axi_vote->compressed_bw_ab);
return 0;
}
@@ -196,10 +208,12 @@ static int cam_vfe_top_set_axi_bw_vote(
soc_private->cpas_handle[cpashdl_type],
&to_be_applied_axi_vote);
if (!rc) {
- top_priv->applied_axi_vote.uncompressed_bw =
+ applied_axi_vote->uncompressed_bw =
to_be_applied_axi_vote.uncompressed_bw;
- top_priv->applied_axi_vote.compressed_bw =
+ applied_axi_vote->compressed_bw =
to_be_applied_axi_vote.compressed_bw;
+ applied_axi_vote->compressed_bw_ab =
+ to_be_applied_axi_vote.compressed_bw_ab;
}
return rc;
}
@@ -215,6 +229,11 @@ static int cam_vfe_top_set_axi_bw_vote(
to_be_applied_axi_vote.compressed_bw =
last_vote[i].compressed_bw;
+ if (to_be_applied_axi_vote.compressed_bw_ab <
+ last_vote[i].compressed_bw_ab)
+ to_be_applied_axi_vote.compressed_bw_ab =
+ last_vote[i].compressed_bw_ab;
+
if (to_be_applied_axi_vote.uncompressed_bw <
last_vote[i].uncompressed_bw)
to_be_applied_axi_vote.uncompressed_bw =
@@ -222,9 +241,11 @@ static int cam_vfe_top_set_axi_bw_vote(
}
if ((to_be_applied_axi_vote.uncompressed_bw !=
- top_priv->applied_axi_vote.uncompressed_bw) ||
+ applied_axi_vote->uncompressed_bw) ||
(to_be_applied_axi_vote.compressed_bw !=
- top_priv->applied_axi_vote.compressed_bw))
+ applied_axi_vote->compressed_bw) ||
+ (to_be_applied_axi_vote.compressed_bw_ab !=
+ applied_axi_vote->compressed_bw_ab))
apply_bw_update = true;
CAM_DBG(CAM_ISP, "apply_bw_update=%d", apply_bw_update);
@@ -234,10 +255,12 @@ static int cam_vfe_top_set_axi_bw_vote(
soc_private->cpas_handle[cpashdl_type],
&to_be_applied_axi_vote);
if (!rc) {
- top_priv->applied_axi_vote.uncompressed_bw =
- to_be_applied_axi_vote.uncompressed_bw;
- top_priv->applied_axi_vote.compressed_bw =
+ applied_axi_vote->uncompressed_bw =
+ to_be_applied_axi_vote.uncompressed_bw;
+ applied_axi_vote->compressed_bw =
to_be_applied_axi_vote.compressed_bw;
+ applied_axi_vote->compressed_bw_ab =
+ to_be_applied_axi_vote.compressed_bw_ab;
} else {
CAM_ERR(CAM_ISP, "BW request failed, rc=%d",
rc);
@@ -338,6 +361,8 @@ static int cam_vfe_top_bw_update(
bw_update->camnoc_bw_bytes;
top_priv->req_axi_vote[i].compressed_bw =
bw_update->external_bw_bytes;
+ top_priv->req_axi_vote[i].compressed_bw_ab =
+ bw_update->external_bw_bytes_ab;
top_priv->axi_vote_control[i] =
CAM_VFE_BW_CONTROL_INCLUDE;
break;
@@ -639,6 +664,7 @@ int cam_vfe_top_stop(void *device_priv,
if (top_priv->mux_rsrc[i].res_id == mux_res->res_id) {
top_priv->req_clk_rate[i] = 0;
top_priv->req_axi_vote[i].compressed_bw = 0;
+ top_priv->req_axi_vote[i].compressed_bw_ab = 0;
top_priv->req_axi_vote[i].uncompressed_bw = 0;
top_priv->axi_vote_control[i] =
CAM_VFE_BW_CONTROL_EXCLUDE;
@@ -742,6 +768,7 @@ int cam_vfe_top_ver2_init(
vfe_top->top_priv = top_priv;
top_priv->hw_clk_rate = 0;
top_priv->applied_axi_vote.compressed_bw = 0;
+ top_priv->applied_axi_vote.compressed_bw_ab = 0;
top_priv->applied_axi_vote.uncompressed_bw = 0;
memset(top_priv->last_vote, 0x0, sizeof(struct cam_axi_vote) *
(CAM_VFE_TOP_VER2_MUX_MAX * CAM_CPAS_HANDLE_MAX *
@@ -756,6 +783,7 @@ int cam_vfe_top_ver2_init(
CAM_ISP_RESOURCE_STATE_AVAILABLE;
top_priv->req_clk_rate[i] = 0;
top_priv->req_axi_vote[i].compressed_bw = 0;
+ top_priv->req_axi_vote[i].compressed_bw_ab = 0;
top_priv->req_axi_vote[i].uncompressed_bw = 0;
top_priv->axi_vote_control[i] = CAM_VFE_BW_CONTROL_EXCLUDE;
diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index f27b54a81e4a..f7b42d5a7699 100644
--- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -156,6 +156,12 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
cmd_buf_kaddr = (uint32_t *)kaddr;
+ if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset /
+ sizeof(uint32_t)) >= cmd_buf_len) {
+ CAM_ERR(CAM_JPEG, "Not enough buf");
+ return -EINVAL;
+ }
+
cmd_buf_kaddr =
(cmd_buf_kaddr +
(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
@@ -740,7 +746,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
(void *)packet, (void *)cmd_desc,
sizeof(struct cam_cmd_buf_desc));
- rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl, -1);
+ rc = cam_packet_util_process_patches(packet, hw_mgr->iommu_hdl, -1, 0);
if (rc) {
CAM_ERR(CAM_JPEG, "Patch processing failed %d", rc);
return rc;
diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
index b6f1d56de67f..9a523f7479d9 100644
--- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -65,6 +65,7 @@ int cam_jpeg_dma_init_hw(void *device_priv,
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = JPEG_VOTE;
+ axi_vote.compressed_bw_ab = JPEG_VOTE;
axi_vote.uncompressed_bw = JPEG_VOTE;
rc = cam_cpas_start(core_info->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
index 7fcc1ada1a36..52907cd6803e 100644
--- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -76,6 +76,7 @@ int cam_jpeg_enc_init_hw(void *device_priv,
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = JPEG_VOTE;
+ axi_vote.compressed_bw_ab = JPEG_VOTE;
axi_vote.uncompressed_bw = JPEG_VOTE;
rc = cam_cpas_start(core_info->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
index 11e9069b3c79..f46426f50e97 100644
--- a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
@@ -871,7 +871,8 @@ static int cam_lrme_mgr_hw_prepare_update(void *hw_mgr_priv,
kmd_buf.size, kmd_buf.used_bytes);
rc = cam_packet_util_process_patches(args->packet,
- hw_mgr->device_iommu.non_secure, hw_mgr->device_iommu.secure);
+ hw_mgr->device_iommu.non_secure,
+ hw_mgr->device_iommu.secure, 0);
if (rc) {
CAM_ERR(CAM_LRME, "Patch packet failed, rc=%d", rc);
return rc;
diff --git a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c
index 8c58685696ad..d32e5f7edc1a 100644
--- a/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -33,6 +33,7 @@ int cam_lrme_soc_enable_resources(struct cam_hw_info *lrme_hw)
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = 7200000;
+ axi_vote.compressed_bw_ab = 7200000;
axi_vote.uncompressed_bw = 7200000;
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
index 234c51453476..f1b3ccefe62c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
@@ -680,6 +680,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
struct cam_req_mgr_slot *sync_slot = NULL;
int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0;
int64_t req_id = 0, sync_req_id = 0;
+ int32_t sync_num_slots = 0;
if (!link->sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
@@ -688,6 +689,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
sync_link = link->sync_link;
req_id = slot->req_id;
+ sync_num_slots = sync_link->req.in_q->num_slots;
sync_rd_idx = sync_link->req.in_q->rd_idx;
CAM_DBG(CAM_CRM,
@@ -765,7 +767,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - rd_idx) >= 1) &&
+ (((sync_slot_idx - rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
@@ -831,7 +834,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - rd_idx) >= 1) &&
+ (((sync_slot_idx - rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
@@ -888,6 +892,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
struct cam_req_mgr_core_link *sync_link = NULL;
int64_t req_id = 0;
int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
+ int32_t sync_num_slots = 0;
if (!link->sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
@@ -896,6 +901,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
sync_link = link->sync_link;
req_id = slot->req_id;
+ sync_num_slots = sync_link->req.in_q->num_slots;
CAM_DBG(CAM_REQ,
"link_hdl %x req %lld frame_skip_flag %d ",
@@ -940,7 +946,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
sync_rd_idx = sync_link->req.in_q->rd_idx;
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - sync_rd_idx) >= 1) &&
+ (((sync_slot_idx - sync_rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[sync_rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
@@ -1886,7 +1893,9 @@ int cam_req_mgr_process_add_req(void *priv, void *data)
mutex_lock(&link->req.lock);
idx = __cam_req_mgr_find_slot_for_req(link->req.in_q, add_req->req_id);
if (idx < 0) {
- CAM_ERR(CAM_CRM, "req %lld not found in in_q", add_req->req_id);
+ CAM_ERR(CAM_CRM,
+ "req %lld not found in in_q for dev %s on link 0x%x",
+ add_req->req_id, device->dev_info.name, link->link_hdl);
rc = -EBADSLT;
mutex_unlock(&link->req.lock);
goto end;
@@ -1906,8 +1915,10 @@ int cam_req_mgr_process_add_req(void *priv, void *data)
if (slot->state != CRM_REQ_STATE_PENDING &&
slot->state != CRM_REQ_STATE_EMPTY) {
- CAM_WARN(CAM_CRM, "Unexpected state %d for slot %d map %x",
- slot->state, idx, slot->req_ready_map);
+ CAM_WARN(CAM_CRM,
+ "Unexpected state %d for slot %d map %x for dev %s on link 0x%x",
+ slot->state, idx, slot->req_ready_map,
+ device->dev_info.name, link->link_hdl);
}
slot->state = CRM_REQ_STATE_PENDING;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
index 7d71cd57573e..fa290c0b982c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
@@ -81,6 +81,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(cci_dev->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 17499489184b..318ea555e98c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -232,13 +232,18 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
csiphy_dev->csiphy_info.csiphy_3phase =
cam_cmd_csiphy_info->csiphy_3phase;
csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode;
- if (cam_cmd_csiphy_info->combo_mode == 1)
+ if (cam_cmd_csiphy_info->combo_mode == 1) {
csiphy_dev->csiphy_info.settle_time_combo_sensor =
cam_cmd_csiphy_info->settle_time;
- else
+ csiphy_dev->csiphy_info.data_rate_combo_sensor =
+ cam_cmd_csiphy_info->data_rate;
+ } else {
csiphy_dev->csiphy_info.settle_time =
cam_cmd_csiphy_info->settle_time;
- csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
+ csiphy_dev->csiphy_info.data_rate =
+ cam_cmd_csiphy_info->data_rate;
+ }
+
if (cam_cmd_csiphy_info->secure_mode == 1)
cam_csiphy_update_secure_info(csiphy_dev,
@@ -269,6 +274,65 @@ void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev)
csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
}
+void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device)
+{
+ int i = 0, j = 0;
+ uint64_t phy_data_rate = 0;
+ void __iomem *csiphybase = NULL;
+ ssize_t num_table_entries = 0;
+ struct data_rate_settings_t *settings_table = NULL;
+
+ if ((csiphy_device == NULL) ||
+ (csiphy_device->ctrl_reg == NULL) ||
+ (csiphy_device->ctrl_reg->data_rates_settings_table == NULL)) {
+ CAM_DBG(CAM_CSIPHY,
+ "Data rate specific register table not found");
+ return;
+ }
+
+ phy_data_rate = csiphy_device->csiphy_info.data_rate;
+ csiphybase =
+ csiphy_device->soc_info.reg_map[0].mem_base;
+ settings_table =
+ csiphy_device->ctrl_reg->data_rates_settings_table;
+ num_table_entries =
+ settings_table->num_data_rate_settings;
+
+ CAM_DBG(CAM_CSIPHY, "required data rate : %llu", phy_data_rate);
+ for (i = 0; i < num_table_entries; i++) {
+ struct data_rate_reg_info_t *drate_settings =
+ settings_table->data_rate_settings;
+ uint64_t bandwidth =
+ drate_settings[i].bandwidth;
+ ssize_t num_reg_entries =
+ drate_settings[i].data_rate_reg_array_size;
+
+ if (phy_data_rate > bandwidth) {
+ CAM_DBG(CAM_CSIPHY,
+ "Skipping table [%d] %llu required: %llu",
+ i, bandwidth, phy_data_rate);
+ continue;
+ }
+
+ CAM_DBG(CAM_CSIPHY,
+ "table[%d] BW : %llu Selected", i, bandwidth);
+ for (j = 0; j < num_reg_entries; j++) {
+ uint32_t reg_addr =
+ drate_settings[i].csiphy_data_rate_regs[j].reg_addr;
+
+ uint32_t reg_data =
+ drate_settings[i].csiphy_data_rate_regs[j].reg_data;
+
+ CAM_DBG(CAM_CSIPHY,
+ "writing reg : %x val : %x",
+ reg_addr, reg_data);
+ cam_io_w_mb(reg_data,
+ csiphybase + reg_addr);
+ }
+ break;
+ }
+}
+
void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
{
int32_t i;
@@ -476,6 +540,9 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
lane_pos++;
}
+ if (csiphy_dev->csiphy_info.csiphy_3phase)
+ cam_csiphy_cphy_data_rate_config(csiphy_dev);
+
cam_csiphy_cphy_irq_config(csiphy_dev);
return rc;
@@ -850,6 +917,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
+ axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
rc = cam_cpas_start(csiphy_dev->cpas_handle,
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
index 51cf9e953a41..cf81924d970a 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
@@ -44,8 +44,10 @@
#define MAX_CSIPHY_REG_ARRAY 70
#define MAX_CSIPHY_CMN_REG_ARRAY 5
-#define MAX_LANES 5
-#define MAX_SETTINGS_PER_LANE 43
+#define MAX_LANES 5
+#define MAX_SETTINGS_PER_LANE 43
+#define MAX_DATA_RATES 3
+#define MAX_DATA_RATE_REGS 30
#define MAX_REGULATOR 5
#define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver"
@@ -155,6 +157,32 @@ struct csiphy_reg_t {
uint32_t csiphy_param_type;
};
+struct csiphy_device;
+
+/*
+ * struct data_rate_reg_info_t
+ * @bandwidth: max bandwidth supported by this reg settings
+ * @data_rate_reg_array_size: number of reg value pairs in the array
+ * @csiphy_data_rate_regs: array of data rate specific reg value pairs
+ */
+struct data_rate_reg_info_t {
+ uint64_t bandwidth;
+ ssize_t data_rate_reg_array_size;
+ struct csiphy_reg_t csiphy_data_rate_regs[MAX_DATA_RATE_REGS];
+};
+
+/**
+ * struct data_rate_settings_t
+ * @num_data_rate_settings: number of valid settings
+ * present in the data rate settings array
+ * @data_rate_settings: array of regsettings which are specific to
+ * data rate
+ */
+struct data_rate_settings_t {
+ ssize_t num_data_rate_settings;
+ struct data_rate_reg_info_t data_rate_settings[MAX_DATA_RATES];
+};
+
/**
* struct csiphy_ctrl_t
* @csiphy_reg: Register address
@@ -166,6 +194,12 @@ struct csiphy_reg_t {
* @csiphy_3ph_reg: 3phase register set
* @csiphy_2ph_3ph_mode_reg:
* 2 phase 3phase combo register set
+ * @getclockvoting: function pointer which
+ * is used to find the clock voting
+ * for the sensor output data rate
+ * @data_rate_settings_table:
+ * Table which maintains the resgister
+ * settings specific to data rate
*/
struct csiphy_ctrl_t {
struct csiphy_reg_parms_t csiphy_reg;
@@ -176,6 +210,8 @@ struct csiphy_ctrl_t {
struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE];
+ enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev);
+ struct data_rate_settings_t *data_rates_settings_table;
};
/**
@@ -190,6 +226,8 @@ struct csiphy_ctrl_t {
* @settle_time : Settling time in ms
* @settle_time_combo_sensor : Settling time in ms
* @data_rate : Data rate in mbps
+ * @data_rate_combo_sensor: data rate of combo sensor
+ * in the the same phy
*
*/
struct cam_csiphy_param {
@@ -202,6 +240,7 @@ struct cam_csiphy_param {
uint64_t settle_time;
uint64_t settle_time_combo_sensor;
uint64_t data_rate;
+ uint64_t data_rate_combo_sensor;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
index 0902601cebd5..0bf5aac2f090 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -17,6 +17,9 @@
#include "include/cam_csiphy_1_2_hwreg.h"
#include "include/cam_csiphy_2_0_hwreg.h"
+#define CSIPHY_3PH_DIVISOR 16
+#define CSIPHY_3PH_DIVISOR_12 32
+#define CSIPHY_2PH_DIVISOR 8
#define BYTES_PER_REGISTER 4
#define NUM_REGISTER_PER_LINE 4
#define REG_OFFSET(__start, __i) ((__start) + ((__i) * BYTES_PER_REGISTER))
@@ -79,10 +82,62 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
return rc;
}
+enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev)
+{
+ CAM_DBG(CAM_CSIPHY, "voting for SVS");
+ return CAM_SVS_VOTE;
+}
+
+enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
+{
+ uint32_t cam_vote_level = 0;
+ uint32_t last_valid_vote = 0;
+ struct cam_hw_soc_info *soc_info;
+ uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate;
+
+ soc_info = &csiphy_dev->soc_info;
+
+ if (csiphy_dev->is_acquired_dev_combo_mode)
+ phy_data_rate = max(phy_data_rate,
+ csiphy_dev->csiphy_info.data_rate_combo_sensor);
+
+ if (csiphy_dev->csiphy_info.csiphy_3phase) {
+ if (csiphy_dev->is_csiphy_3phase_hw == CSI_3PHASE_HW_12)
+ do_div(phy_data_rate, CSIPHY_3PH_DIVISOR_12);
+ else
+ do_div(phy_data_rate, CSIPHY_3PH_DIVISOR);
+ } else {
+ do_div(phy_data_rate, CSIPHY_2PH_DIVISOR);
+ }
+
+ /* round off to next integer */
+ phy_data_rate += 1;
+
+ for (cam_vote_level = 0;
+ cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) {
+ if (soc_info->clk_level_valid[cam_vote_level] != true)
+ continue;
+
+ if (soc_info->clk_rate[cam_vote_level][0] >
+ phy_data_rate) {
+ CAM_DBG(CAM_CSIPHY,
+ "match detected %s : %llu:%d level : %d",
+ soc_info->clk_name[0],
+ phy_data_rate,
+ soc_info->clk_rate[cam_vote_level][0],
+ cam_vote_level);
+ return cam_vote_level;
+ }
+ last_valid_vote = cam_vote_level;
+ }
+ return last_valid_vote;
+}
+
int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
{
int32_t rc = 0;
struct cam_hw_soc_info *soc_info;
+ enum cam_vote_level vote_level = CAM_SVS_VOTE;
soc_info = &csiphy_dev->soc_info;
@@ -92,8 +147,9 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
return rc;
}
+ vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev);
rc = cam_soc_util_enable_platform_resource(soc_info, true,
- CAM_SVS_VOTE, ENABLE_IRQ);
+ vote_level, ENABLE_IRQ);
if (rc < 0) {
CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d",
rc);
@@ -174,9 +230,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_1_0;
csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_0;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_0;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->hw_version = CSIPHY_VERSION_V10;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v1.1")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_1_reg;
@@ -191,9 +249,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_reset_reg =
csiphy_reset_reg_1_1;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_1;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->hw_version = CSIPHY_VERSION_V11;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v1.2")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg;
@@ -206,10 +266,13 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_common_reg_1_2;
csiphy_dev->ctrl_reg->csiphy_reset_reg =
csiphy_reset_reg_1_2;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2;
- csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
+ csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12;
csiphy_dev->hw_version = CSIPHY_VERSION_V12;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table =
+ &data_rate_delta_table;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v2.0")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v2_0_reg;
@@ -221,9 +284,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_2_0;
csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_2_0;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v2_0;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->hw_version = CSIPHY_VERSION_V20;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else {
CAM_ERR(CAM_CSIPHY, "invalid hw version : 0x%x",
csiphy_dev->hw_version);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
index 68ca68ced31b..64d05616d2e3 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -34,6 +34,7 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define CSI_3PHASE_HW 1
+#define CSI_3PHASE_HW_12 0x12
#define CSIPHY_VERSION_V35 0x35
#define CSIPHY_VERSION_V10 0x10
#define CSIPHY_VERSION_V11 0x11
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
index 945910e96a55..67653e81fde1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
@@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
.mipi_csiphy_interrupt_status0_addr = 0x8B0,
.mipi_csiphy_interrupt_clear0_addr = 0x858,
.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
- .csiphy_common_array_size = 4,
+ .csiphy_common_array_size = 6,
.csiphy_reset_array_size = 5,
.csiphy_2ph_config_array_size = 21,
- .csiphy_3ph_config_array_size = 31,
+ .csiphy_3ph_config_array_size = 38,
.csiphy_2ph_clock_lane = 0x1,
.csiphy_2ph_combo_ck_ln = 0x10,
};
@@ -30,8 +30,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
struct csiphy_reg_t csiphy_common_reg_1_2[] = {
{0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE},
{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x081C, 0x02, 0x00, CSIPHY_2PH_REGS},
+ {0x081C, 0x52, 0x00, CSIPHY_3PH_REGS},
+ {0x0800, 0x02, 0x00, CSIPHY_2PH_REGS},
+ {0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS},
};
struct csiphy_reg_t csiphy_reset_reg_1_2[] = {
@@ -297,7 +299,7 @@ struct csiphy_reg_t
struct
csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{
- {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x015C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -305,10 +307,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x098C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0168, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x016C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x010C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -321,27 +323,34 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0144, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
- {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x035C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0368, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x036C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x030C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -354,16 +363,23 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0344, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0AB0, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
- {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x055C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -371,10 +387,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0568, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x056C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x050C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -387,14 +403,107 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0544, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0BB0, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
};
+struct data_rate_settings_t data_rate_delta_table = {
+ .num_data_rate_settings = 3,
+ .data_rate_settings = {
+ {
+ /* (2.5 * 10**3 * 2.28) rounded value*/
+ .bandwidth = 5700000000,
+ .data_rate_reg_array_size = 12,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ }
+ },
+ {
+ /* (3.5 * 10**3 * 2.28) rounded value */
+ .bandwidth = 7980000000,
+ .data_rate_reg_array_size = 24,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ },
+ },
+ {
+ /* (4.5 * 10**3 * 2.28) rounded value */
+ .bandwidth = 10260000000,
+ .data_rate_reg_array_size = 24,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ },
+ }
+ }
+};
#endif /* _CAM_CSIPHY_1_2_HWREG_H_ */
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index 220cd1598922..a04d97143592 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -913,7 +913,7 @@ error:
vfree(e_ctrl->cal_data.map);
e_ctrl->cal_data.num_data = 0;
e_ctrl->cal_data.num_map = 0;
- e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
+ e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
release_buf:
if (cam_mem_put_cpu_buf(dev_config.packet_handle))
CAM_WARN(CAM_EEPROM, "Put cpu buffer failed : %llu",
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 5f77ca0a5293..111f121757c1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -937,9 +937,13 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
rc = cam_sensor_apply_settings(s_ctrl, 0,
CAM_SENSOR_PACKET_OPCODE_SENSOR_INITIAL_CONFIG);
+
+ s_ctrl->i2c_data.init_settings.request_id = -1;
+
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"cannot apply init settings");
+ delete_request(&s_ctrl->i2c_data.init_settings);
goto release_mutex;
}
rc = delete_request(&s_ctrl->i2c_data.init_settings);
@@ -948,16 +952,20 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
"Fail in deleting the Init settings");
goto release_mutex;
}
- s_ctrl->i2c_data.init_settings.request_id = -1;
}
if (s_ctrl->i2c_data.config_settings.is_settings_valid &&
(s_ctrl->i2c_data.config_settings.request_id == 0)) {
rc = cam_sensor_apply_settings(s_ctrl, 0,
CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG);
+
+ s_ctrl->i2c_data.config_settings.request_id = -1;
+
if (rc < 0) {
CAM_ERR(CAM_SENSOR,
"cannot apply config settings");
+ delete_request(
+ &s_ctrl->i2c_data.config_settings);
goto release_mutex;
}
rc = delete_request(&s_ctrl->i2c_data.config_settings);
@@ -967,7 +975,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
goto release_mutex;
}
s_ctrl->sensor_state = CAM_SENSOR_CONFIG;
- s_ctrl->i2c_data.config_settings.request_id = -1;
}
}
break;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index 7f6f3aa40998..4d314964effd 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -37,8 +37,7 @@ static struct i2c_settings_list*
return NULL;
tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *)
- kcalloc(size, sizeof(struct cam_sensor_i2c_reg_array),
- GFP_KERNEL);
+ vzalloc(size * sizeof(struct cam_sensor_i2c_reg_array));
if (tmp->i2c_settings.reg_setting == NULL) {
list_del(&(tmp->list));
kfree(tmp);
@@ -61,7 +60,7 @@ int32_t delete_request(struct i2c_settings_array *i2c_array)
list_for_each_entry_safe(i2c_list, i2c_next,
&(i2c_array->list_head), list) {
- kfree(i2c_list->i2c_settings.reg_setting);
+ vfree(i2c_list->i2c_settings.reg_setting);
list_del(&(i2c_list->list));
kfree(i2c_list);
}
@@ -338,6 +337,7 @@ int cam_sensor_i2c_command_parser(
cmd_buf = (uint32_t *)generic_ptr;
cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
+ remain_len -= cmd_desc[i].offset;
if (remain_len < cmd_desc[i].length) {
CAM_ERR(CAM_SENSOR, "buffer provided too small");
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c
index 7ddfa3d2ec56..62b81aad8dd0 100644
--- a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c
@@ -24,6 +24,7 @@
#include <soc/qcom/scm.h>
#include <soc/qcom/secure_buffer.h>
#include <uapi/media/cam_req_mgr.h>
+#include <linux/debugfs.h>
#include "cam_smmu_api.h"
#include "cam_debug_util.h"
@@ -188,6 +189,10 @@ static const char *qdss_region_name = "qdss";
static struct cam_iommu_cb_set iommu_cb_set;
+static struct dentry *smmu_dentry;
+
+static bool smmu_fatal_flag;
+
static enum dma_data_direction cam_smmu_translate_dir(
enum cam_smmu_map_dir dir);
@@ -297,6 +302,30 @@ static void cam_smmu_page_fault_work(struct work_struct *work)
kfree(payload);
}
+static int cam_smmu_create_debugfs_entry(void)
+{
+ int rc = 0;
+
+ smmu_dentry = debugfs_create_dir("camera_smmu", NULL);
+ if (!smmu_dentry)
+ return -ENOMEM;
+
+ if (!debugfs_create_bool("cam_smmu_fatal",
+ 0644,
+ smmu_dentry,
+ &smmu_fatal_flag)) {
+ CAM_ERR(CAM_SMMU, "failed to create cam_smmu_fatal entry");
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ return rc;
+err:
+ debugfs_remove_recursive(smmu_dentry);
+ smmu_dentry = NULL;
+ return rc;
+}
+
static void cam_smmu_print_user_list(int idx)
{
struct cam_dma_buff_info *mapping;
@@ -682,10 +711,6 @@ static int cam_smmu_create_add_handle_in_table(char *name,
if (!strcmp(iommu_cb_set.cb_info[i].name, name)) {
mutex_lock(&iommu_cb_set.cb_info[i].lock);
if (iommu_cb_set.cb_info[i].handle != HANDLE_INIT) {
- CAM_ERR(CAM_SMMU,
- "Error: %s already got handle 0x%x",
- name,
- iommu_cb_set.cb_info[i].handle);
if (iommu_cb_set.cb_info[i].is_secure)
iommu_cb_set.cb_info[i].secure_count++;
@@ -695,6 +720,11 @@ static int cam_smmu_create_add_handle_in_table(char *name,
*hdl = iommu_cb_set.cb_info[i].handle;
return 0;
}
+
+ CAM_ERR(CAM_SMMU,
+ "Error: %s already got handle 0x%x",
+ name, iommu_cb_set.cb_info[i].handle);
+
return -EINVAL;
}
@@ -3150,7 +3180,7 @@ static int cam_smmu_setup_cb(struct cam_context_bank_info *cb,
goto end;
}
- iommu_cb_set.non_fatal_fault = 1;
+ iommu_cb_set.non_fatal_fault = smmu_fatal_flag;
if (iommu_domain_set_attr(cb->mapping->domain,
DOMAIN_ATTR_NON_FATAL_FAULTS,
&iommu_cb_set.non_fatal_fault) < 0) {
@@ -3509,6 +3539,7 @@ static struct platform_driver cam_smmu_driver = {
static int __init cam_smmu_init_module(void)
{
+ cam_smmu_create_debugfs_entry();
return platform_driver_register(&cam_smmu_driver);
}
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
index 1be244bb7c3a..d3f62d6a3e20 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
@@ -322,7 +322,7 @@ int cam_sync_get_obj_ref(int32_t sync_obj)
if (row->state != CAM_SYNC_STATE_ACTIVE) {
spin_unlock(&sync_dev->row_spinlocks[sync_obj]);
- CAM_ERR(CAM_SYNC,
+ CAM_ERR_RATE_LIMIT_CUSTOM(CAM_SYNC, 1, 5,
"accessing an uninitialized sync obj = %d state = %d",
sync_obj, row->state);
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_debug_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_debug_util.h
index 9093517de1e4..0aa898f8e11f 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_debug_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_debug_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -120,6 +120,27 @@ const char *cam_get_module_name(unsigned int module_id);
cam_get_module_name(__module), __func__, __LINE__, ##args)
/*
+ * CAM_INFO_RATE_LIMIT_CUSTOM
+ * @brief : This Macro will print info logs with custom ratelimit
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @interval : Time interval in seconds
+ * @burst : No of logs to print in interval time
+ * @fmt : Formatted string which needs to be print in log
+ * @args : Arguments which needs to be print in log
+ */
+#define CAM_INFO_RATE_LIMIT_CUSTOM(__module, interval, burst, fmt, args...) \
+ ({ \
+ static DEFINE_RATELIMIT_STATE(_rs, \
+ (interval * HZ), \
+ burst); \
+ if (__ratelimit(&_rs)) \
+ 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
*
@@ -138,4 +159,25 @@ const char *cam_get_module_name(unsigned int module_id);
pr_err_ratelimited("CAM_ERR: %s: %s: %d " fmt "\n", \
cam_get_module_name(__module), __func__, __LINE__, ##args)
+/*
+ * CAM_ERR_RATE_LIMIT_CUSTOM
+ * @brief : This Macro will print error logs with custom ratelimit
+ *
+ * @__module : Respective module id which is been calling this Macro
+ * @interval : Time interval in seconds
+ * @burst : No of logs to print in interval time
+ * @fmt : Formatted string which needs to be print in log
+ * @args : Arguments which needs to be print in log
+ */
+#define CAM_ERR_RATE_LIMIT_CUSTOM(__module, interval, burst, fmt, args...) \
+ ({ \
+ static DEFINE_RATELIMIT_STATE(_rs, \
+ (interval * HZ), \
+ burst); \
+ if (__ratelimit(&_rs)) \
+ pr_err("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_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
index ba244e780336..0f910c9e8273 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
@@ -169,7 +169,7 @@ rel_kmd_buf:
}
int cam_packet_util_process_patches(struct cam_packet *packet,
- int32_t iommu_hdl, int32_t sec_mmu_hdl)
+ int32_t iommu_hdl, int32_t sec_mmu_hdl, int pf_dump_flag)
{
struct cam_patch_desc *patch_desc = NULL;
dma_addr_t iova_addr;
@@ -242,6 +242,14 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
if (cam_mem_put_cpu_buf(patch_desc[i].dst_buf_hdl))
CAM_WARN(CAM_UTIL, "unable to put dst buf address:0x%x",
patch_desc[i].dst_buf_hdl);
+
+ if (pf_dump_flag) {
+ CAM_INFO(CAM_UTIL,
+ "patch[%d]: patched addr %llx sz 0x%x offset:0x%x",
+ i, *((uint64_t *)dst_cpu_addr),
+ (uint32_t)src_buf_size,
+ patch_desc[i].src_offset);
+ }
}
return rc;
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h
index 412eba52b05a..33c07ad89f4e 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h
@@ -106,12 +106,14 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet,
* @iommu_hdl: IOMMU handle of the HW Device that received the packet
* @sec_iommu_hdl: Secure IOMMU handle of the HW Device that
* received the packet
+ * @pf_dump_flag: if set, it will dump the info,
+ * otherwise will do patching
*
* @return: 0: Success
* Negative: Failure
*/
int cam_packet_util_process_patches(struct cam_packet *packet,
- int32_t iommu_hdl, int32_t sec_mmu_hdl);
+ int32_t iommu_hdl, int32_t sec_mmu_hdl, int pf_dump_flag);
/**
* cam_packet_util_process_generic_cmd_buffer()
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
index 693b0da29be2..f3af61936625 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
@@ -490,14 +490,17 @@ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
int32_t src_clk_idx;
struct clk *clk = NULL;
int32_t apply_level;
+ uint32_t clk_level_override = 0;
if (!soc_info || (soc_info->src_clk_idx < 0))
return -EINVAL;
- if (soc_info->clk_level_override && clk_rate)
- clk_rate = soc_info->clk_level_override;
-
src_clk_idx = soc_info->src_clk_idx;
+ clk_level_override = soc_info->clk_level_override;
+ if (clk_level_override && clk_rate)
+ clk_rate =
+ soc_info->clk_rate[clk_level_override][src_clk_idx];
+
clk = soc_info->clk[src_clk_idx];
if (soc_info->cam_cx_ipeak_enable && clk_rate >= 0) {
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index faa47a6d538b..c2b259907cd4 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 2019 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
@@ -685,7 +685,8 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
if (inst->fmts[fmt->type].fourcc == f->fmt.pix_mp.pixelformat &&
inst->prop.width[OUTPUT_PORT] == f->fmt.pix_mp.width &&
inst->prop.height[OUTPUT_PORT] ==
- f->fmt.pix_mp.height) {
+ f->fmt.pix_mp.height &&
+ !inst->buffer_size_limit) {
dprintk(VIDC_DBG, "No change in OUTPUT port params\n");
return 0;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 802e58140d85..1b711b33873b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -953,7 +953,7 @@ void msm_clock_data_reset(struct msm_vidc_inst *inst)
dprintk(VIDC_DBG, "Init DCVS Load\n");
- if (!inst || !inst->core) {
+ if (!inst || !inst->core || !inst->clk_data.entry) {
dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
__func__, inst);
return;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index e38439778329..ab7381305179 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -5231,6 +5231,14 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
"Invalid params, inst %pK\n", inst);
return -EINVAL;
}
+
+ if (inst->state < MSM_VIDC_OPEN_DONE) {
+ dprintk(VIDC_ERR,
+ "Invalid state to call flush, inst %pK, state %#x\n",
+ inst, inst->state);
+ return -EINVAL;
+ }
+
core = inst->core;
hdev = core->device;
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6dd88ff389a3..13a3a971610d 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1210,6 +1210,8 @@ static void mmc_sd_detect(struct mmc_host *host)
goto out;
}
+ mmc_power_up(host, host->ocr_avail);
+
/*
* Just check if our card has been removed.
*/
@@ -1349,6 +1351,9 @@ static int _mmc_sd_resume(struct mmc_host *host)
mmc_card_set_removed(host->card);
mmc_detect_change(host, msecs_to_jiffies(200));
} else if (err) {
+ pr_err("%s: %s: mmc_sd_init_card_failed (%d)\n",
+ mmc_hostname(host), __func__, err);
+ mmc_power_off(host);
goto out;
}
mmc_card_clr_suspended(host->card);
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 5b5ad0f5578a..7fc220aaff14 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -13,6 +13,16 @@ menuconfig NVMEM
if NVMEM
+config NVMEM_SYSFS
+ bool "/sys/bus/nvmem/devices/*/nvmem (sysfs interface)"
+ depends on SYSFS
+ default y
+ help
+ Say Y here to add a sysfs interface for NVMEM.
+
+ This interface is mostly used by userspace applications to
+ read/write directly into nvmem.
+
config NVMEM_IMX_OCOTP
tristate "i.MX6 On-Chip OTP Controller support"
depends on SOC_IMX6 || COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 1e99e8cc0ed2..248ac34b6e72 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -5,6 +5,9 @@
obj-$(CONFIG_NVMEM) += nvmem_core.o
nvmem_core-y := core.o
+obj-$(CONFIG_NVMEM_SYSFS) += nvmem_sysfs.o
+nvmem_sysfs-y := nvmem-sysfs.o
+
# Devices
obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o
nvmem-imx-ocotp-y := imx-ocotp.o
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 1b4d93e9157e..3e3f599e53b7 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -25,26 +25,7 @@
#include <linux/of.h>
#include <linux/slab.h>
-struct nvmem_device {
- const char *name;
- struct module *owner;
- struct device dev;
- int stride;
- int word_size;
- int ncells;
- int id;
- int users;
- size_t size;
- bool read_only;
- int flags;
- struct bin_attribute eeprom;
- struct device *base_dev;
- nvmem_reg_read_t reg_read;
- nvmem_reg_write_t reg_write;
- void *priv;
-};
-
-#define FLAG_COMPAT BIT(0)
+#include "nvmem.h"
struct nvmem_cell {
const char *name;
@@ -62,11 +43,6 @@ static DEFINE_IDA(nvmem_ida);
static LIST_HEAD(nvmem_cells);
static DEFINE_MUTEX(nvmem_cells_mutex);
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-static struct lock_class_key eeprom_lock_key;
-#endif
-
-#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
void *val, size_t bytes)
{
@@ -85,168 +61,6 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
return -EINVAL;
}
-static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t pos, size_t count)
-{
- struct device *dev;
- struct nvmem_device *nvmem;
- int rc;
-
- if (attr->private)
- dev = attr->private;
- else
- dev = container_of(kobj, struct device, kobj);
- nvmem = to_nvmem_device(dev);
-
- /* Stop the user from reading */
- if (pos >= nvmem->size)
- return 0;
-
- if (count < nvmem->word_size)
- return -EINVAL;
-
- if (pos + count > nvmem->size)
- count = nvmem->size - pos;
-
- count = round_down(count, nvmem->word_size);
-
- rc = nvmem_reg_read(nvmem, pos, buf, count);
-
- if (rc)
- return rc;
-
- return count;
-}
-
-static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t pos, size_t count)
-{
- struct device *dev;
- struct nvmem_device *nvmem;
- int rc;
-
- if (attr->private)
- dev = attr->private;
- else
- dev = container_of(kobj, struct device, kobj);
- nvmem = to_nvmem_device(dev);
-
- /* Stop the user from writing */
- if (pos >= nvmem->size)
- return 0;
-
- if (count < nvmem->word_size)
- return -EINVAL;
-
- if (pos + count > nvmem->size)
- count = nvmem->size - pos;
-
- count = round_down(count, nvmem->word_size);
-
- rc = nvmem_reg_write(nvmem, pos, buf, count);
-
- if (rc)
- return rc;
-
- return count;
-}
-
-/* default read/write permissions */
-static struct bin_attribute bin_attr_rw_nvmem = {
- .attr = {
- .name = "nvmem",
- .mode = S_IWUSR | S_IRUGO,
- },
- .read = bin_attr_nvmem_read,
- .write = bin_attr_nvmem_write,
-};
-
-static struct bin_attribute *nvmem_bin_rw_attributes[] = {
- &bin_attr_rw_nvmem,
- NULL,
-};
-
-static const struct attribute_group nvmem_bin_rw_group = {
- .bin_attrs = nvmem_bin_rw_attributes,
-};
-
-static const struct attribute_group *nvmem_rw_dev_groups[] = {
- &nvmem_bin_rw_group,
- NULL,
-};
-
-/* read only permission */
-static struct bin_attribute bin_attr_ro_nvmem = {
- .attr = {
- .name = "nvmem",
- .mode = S_IRUGO,
- },
- .read = bin_attr_nvmem_read,
-};
-
-static struct bin_attribute *nvmem_bin_ro_attributes[] = {
- &bin_attr_ro_nvmem,
- NULL,
-};
-
-static const struct attribute_group nvmem_bin_ro_group = {
- .bin_attrs = nvmem_bin_ro_attributes,
-};
-
-static const struct attribute_group *nvmem_ro_dev_groups[] = {
- &nvmem_bin_ro_group,
- NULL,
-};
-
-/* default read/write permissions, root only */
-static struct bin_attribute bin_attr_rw_root_nvmem = {
- .attr = {
- .name = "nvmem",
- .mode = S_IWUSR | S_IRUSR,
- },
- .read = bin_attr_nvmem_read,
- .write = bin_attr_nvmem_write,
-};
-
-static struct bin_attribute *nvmem_bin_rw_root_attributes[] = {
- &bin_attr_rw_root_nvmem,
- NULL,
-};
-
-static const struct attribute_group nvmem_bin_rw_root_group = {
- .bin_attrs = nvmem_bin_rw_root_attributes,
-};
-
-static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
- &nvmem_bin_rw_root_group,
- NULL,
-};
-
-/* read only permission, root only */
-static struct bin_attribute bin_attr_ro_root_nvmem = {
- .attr = {
- .name = "nvmem",
- .mode = S_IRUSR,
- },
- .read = bin_attr_nvmem_read,
-};
-
-static struct bin_attribute *nvmem_bin_ro_root_attributes[] = {
- &bin_attr_ro_root_nvmem,
- NULL,
-};
-
-static const struct attribute_group nvmem_bin_ro_root_group = {
- .bin_attrs = nvmem_bin_ro_root_attributes,
-};
-
-static const struct attribute_group *nvmem_ro_root_dev_groups[] = {
- &nvmem_bin_ro_root_group,
- NULL,
-};
-
static void nvmem_release(struct device *dev)
{
struct nvmem_device *nvmem = to_nvmem_device(dev);
@@ -388,43 +202,6 @@ err:
return rval;
}
-/*
- * nvmem_setup_compat() - Create an additional binary entry in
- * drivers sys directory, to be backwards compatible with the older
- * drivers/misc/eeprom drivers.
- */
-static int nvmem_setup_compat(struct nvmem_device *nvmem,
- const struct nvmem_config *config)
-{
- int rval;
-
- if (!config->base_dev)
- return -EINVAL;
-
- if (nvmem->read_only)
- nvmem->eeprom = bin_attr_ro_root_nvmem;
- else
- nvmem->eeprom = bin_attr_rw_root_nvmem;
- nvmem->eeprom.attr.name = "eeprom";
- nvmem->eeprom.size = nvmem->size;
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
- nvmem->eeprom.attr.key = &eeprom_lock_key;
-#endif
- nvmem->eeprom.private = &nvmem->dev;
- nvmem->base_dev = config->base_dev;
-
- rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
- if (rval) {
- dev_err(&nvmem->dev,
- "Failed to create eeprom binary file %d\n", rval);
- return rval;
- }
-
- nvmem->flags |= FLAG_COMPAT;
-
- return 0;
-}
-
/**
* nvmem_register() - Register a nvmem device for given nvmem_config.
* Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -473,15 +250,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->read_only = of_property_read_bool(np, "read-only") |
config->read_only;
- if (config->root_only)
- nvmem->dev.groups = nvmem->read_only ?
- nvmem_ro_root_dev_groups :
- nvmem_rw_root_dev_groups;
- else
- nvmem->dev.groups = nvmem->read_only ?
- nvmem_ro_dev_groups :
- nvmem_rw_dev_groups;
-
+ nvmem->dev.groups = nvmem_sysfs_get_groups(nvmem, config);
device_initialize(&nvmem->dev);
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
@@ -491,7 +260,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
goto err_put_device;
if (config->compat) {
- rval = nvmem_setup_compat(nvmem, config);
+ rval = nvmem_sysfs_setup_compat(nvmem, config);
if (rval)
goto err_device_del;
}
diff --git a/drivers/nvmem/nvmem-sysfs.c b/drivers/nvmem/nvmem-sysfs.c
new file mode 100644
index 000000000000..cb1fbafc52ce
--- /dev/null
+++ b/drivers/nvmem/nvmem-sysfs.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, Linaro Limited
+ */
+#include "nvmem.h"
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key eeprom_lock_key;
+#endif
+
+static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t pos, size_t count)
+{
+ struct device *dev;
+ struct nvmem_device *nvmem;
+ int rc;
+
+ if (attr->private)
+ dev = attr->private;
+ else
+ dev = container_of(kobj, struct device, kobj);
+ nvmem = to_nvmem_device(dev);
+
+ /* Stop the user from reading */
+ if (pos >= nvmem->size)
+ return 0;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+ if (pos + count > nvmem->size)
+ count = nvmem->size - pos;
+
+ count = round_down(count, nvmem->word_size);
+
+ rc = nvmem->reg_read(nvmem->priv, pos, buf, count);
+
+ if (rc)
+ return rc;
+
+ return count;
+}
+
+static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t pos, size_t count)
+{
+ struct device *dev;
+ struct nvmem_device *nvmem;
+ int rc;
+
+ if (attr->private)
+ dev = attr->private;
+ else
+ dev = container_of(kobj, struct device, kobj);
+ nvmem = to_nvmem_device(dev);
+
+ /* Stop the user from writing */
+ if (pos >= nvmem->size)
+ return -EFBIG;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+ if (pos + count > nvmem->size)
+ count = nvmem->size - pos;
+
+ count = round_down(count, nvmem->word_size);
+
+ rc = nvmem->reg_write(nvmem->priv, pos, buf, count);
+
+ if (rc)
+ return rc;
+
+ return count;
+}
+
+/* default read/write permissions */
+static struct bin_attribute bin_attr_rw_nvmem = {
+ .attr = {
+ .name = "nvmem",
+ .mode = S_IWUSR | S_IRUGO,
+ },
+ .read = bin_attr_nvmem_read,
+ .write = bin_attr_nvmem_write,
+};
+
+static struct bin_attribute *nvmem_bin_rw_attributes[] = {
+ &bin_attr_rw_nvmem,
+ NULL,
+};
+
+static const struct attribute_group nvmem_bin_rw_group = {
+ .bin_attrs = nvmem_bin_rw_attributes,
+};
+
+static const struct attribute_group *nvmem_rw_dev_groups[] = {
+ &nvmem_bin_rw_group,
+ NULL,
+};
+
+/* read only permission */
+static struct bin_attribute bin_attr_ro_nvmem = {
+ .attr = {
+ .name = "nvmem",
+ .mode = S_IRUGO,
+ },
+ .read = bin_attr_nvmem_read,
+};
+
+static struct bin_attribute *nvmem_bin_ro_attributes[] = {
+ &bin_attr_ro_nvmem,
+ NULL,
+};
+
+static const struct attribute_group nvmem_bin_ro_group = {
+ .bin_attrs = nvmem_bin_ro_attributes,
+};
+
+static const struct attribute_group *nvmem_ro_dev_groups[] = {
+ &nvmem_bin_ro_group,
+ NULL,
+};
+
+/* default read/write permissions, root only */
+static struct bin_attribute bin_attr_rw_root_nvmem = {
+ .attr = {
+ .name = "nvmem",
+ .mode = S_IWUSR | S_IRUSR,
+ },
+ .read = bin_attr_nvmem_read,
+ .write = bin_attr_nvmem_write,
+};
+
+static struct bin_attribute *nvmem_bin_rw_root_attributes[] = {
+ &bin_attr_rw_root_nvmem,
+ NULL,
+};
+
+static const struct attribute_group nvmem_bin_rw_root_group = {
+ .bin_attrs = nvmem_bin_rw_root_attributes,
+};
+
+static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
+ &nvmem_bin_rw_root_group,
+ NULL,
+};
+
+/* read only permission, root only */
+static struct bin_attribute bin_attr_ro_root_nvmem = {
+ .attr = {
+ .name = "nvmem",
+ .mode = S_IRUSR,
+ },
+ .read = bin_attr_nvmem_read,
+};
+
+static struct bin_attribute *nvmem_bin_ro_root_attributes[] = {
+ &bin_attr_ro_root_nvmem,
+ NULL,
+};
+
+static const struct attribute_group nvmem_bin_ro_root_group = {
+ .bin_attrs = nvmem_bin_ro_root_attributes,
+};
+
+static const struct attribute_group *nvmem_ro_root_dev_groups[] = {
+ &nvmem_bin_ro_root_group,
+ NULL,
+};
+
+const struct attribute_group **nvmem_sysfs_get_groups(
+ struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+ if (config->root_only)
+ return nvmem->read_only ?
+ nvmem_ro_root_dev_groups :
+ nvmem_rw_root_dev_groups;
+
+ return nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups;
+}
+
+/*
+ * nvmem_setup_compat() - Create an additional binary entry in
+ * drivers sys directory, to be backwards compatible with the older
+ * drivers/misc/eeprom drivers.
+ */
+int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+ int rval;
+
+ if (!config->compat)
+ return 0;
+
+ if (!config->base_dev)
+ return -EINVAL;
+
+ if (nvmem->read_only)
+ nvmem->eeprom = bin_attr_ro_root_nvmem;
+ else
+ nvmem->eeprom = bin_attr_rw_root_nvmem;
+ nvmem->eeprom.attr.name = "eeprom";
+ nvmem->eeprom.size = nvmem->size;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ nvmem->eeprom.attr.key = &eeprom_lock_key;
+#endif
+ nvmem->eeprom.private = &nvmem->dev;
+ nvmem->base_dev = config->base_dev;
+
+ rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
+ if (rval) {
+ dev_err(&nvmem->dev,
+ "Failed to create eeprom binary file %d\n", rval);
+ return rval;
+ }
+
+ nvmem->flags |= FLAG_COMPAT;
+
+ return 0;
+}
+
+void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+ if (config->compat)
+ device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
+}
diff --git a/drivers/nvmem/nvmem.h b/drivers/nvmem/nvmem.h
new file mode 100644
index 000000000000..d020479cd0b1
--- /dev/null
+++ b/drivers/nvmem/nvmem.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DRIVERS_NVMEM_H
+#define _DRIVERS_NVMEM_H
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
+
+struct nvmem_device {
+ const char *name;
+ struct module *owner;
+ struct device dev;
+ int stride;
+ int word_size;
+ int ncells;
+ int id;
+ int users;
+ size_t size;
+ bool read_only;
+ int flags;
+ struct bin_attribute eeprom;
+ struct device *base_dev;
+ nvmem_reg_read_t reg_read;
+ nvmem_reg_write_t reg_write;
+ void *priv;
+};
+
+#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
+#define FLAG_COMPAT BIT(0)
+
+#ifdef CONFIG_NVMEM_SYSFS
+const struct attribute_group **nvmem_sysfs_get_groups(
+ struct nvmem_device *nvmem,
+ const struct nvmem_config *config);
+int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config);
+void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config);
+#else
+static inline const struct attribute_group **nvmem_sysfs_get_groups(
+ struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+ return NULL;
+}
+
+static inline int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+ return -ENOSYS;
+}
+static inline void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
+ const struct nvmem_config *config)
+{
+}
+#endif /* CONFIG_NVMEM_SYSFS */
+
+#endif /* _DRIVERS_NVMEM_H */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 3aa8a01f75af..25152eacb855 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, 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
@@ -794,7 +794,7 @@ int ipa3_qmi_ul_filter_request_send(
{
struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
- int rc;
+ int rc, i;
IPAWANDBG("IPACM pass %u rules to Q6\n",
req->firewall_rules_list_len);
@@ -814,6 +814,37 @@ int ipa3_qmi_ul_filter_request_send(
}
mutex_unlock(&ipa3_qmi_lock);
+ /* check if modem is up */
+ if (!ipa3_qmi_indication_fin ||
+ !ipa3_qmi_modem_init_fin ||
+ !ipa_q6_clnt) {
+ IPAWANDBG("modem QMI service is not up yet\n");
+ return -EINVAL;
+ }
+
+ /* Passing 0 rules means that firewall is disabled */
+ if (req->firewall_rules_list_len == 0)
+ IPAWANDBG("IPACM passed 0 rules to Q6\n");
+
+ if (req->firewall_rules_list_len >= QMI_IPA_MAX_UL_FIREWALL_RULES_V01) {
+ IPAWANERR(
+ "Number of rules passed by IPACM, %d, exceed limit %d\n",
+ req->firewall_rules_list_len,
+ QMI_IPA_MAX_UL_FIREWALL_RULES_V01);
+ return -EINVAL;
+ }
+
+ /* Check for valid IP type */
+ for (i = 0; i < req->firewall_rules_list_len; i++) {
+ if (req->firewall_rules_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01 &&
+ req->firewall_rules_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01)
+ IPAWANERR("Invalid IP type %d\n",
+ req->firewall_rules_list[i].ip_type);
+ return -EINVAL;
+ }
+
req_desc.max_msg_len =
QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01;
req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01;
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index f3acd4113b06..c895d219cf85 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -1326,6 +1326,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
struct wlfw_msa_info_req_msg_v01 req;
struct wlfw_msa_info_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
+ uint64_t max_mapped_addr;
if (!penv || !penv->wlfw_clnt)
return -ENODEV;
@@ -1372,9 +1373,23 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
goto out;
}
+ max_mapped_addr = penv->msa_pa + penv->msa_mem_size;
penv->stats.msa_info_resp++;
penv->nr_mem_region = resp.mem_region_info_len;
for (i = 0; i < resp.mem_region_info_len; i++) {
+
+ if (resp.mem_region_info[i].size > penv->msa_mem_size ||
+ resp.mem_region_info[i].region_addr > max_mapped_addr ||
+ resp.mem_region_info[i].region_addr < penv->msa_pa ||
+ resp.mem_region_info[i].size +
+ resp.mem_region_info[i].region_addr > max_mapped_addr) {
+ icnss_pr_dbg("Received out of range Addr: 0x%llx Size: 0x%x\n",
+ resp.mem_region_info[i].region_addr,
+ resp.mem_region_info[i].size);
+ ret = -EINVAL;
+ goto fail_unwind;
+ }
+
penv->mem_region[i].reg_addr =
resp.mem_region_info[i].region_addr;
penv->mem_region[i].size =
@@ -1389,6 +1404,8 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
return 0;
+fail_unwind:
+ memset(&penv->mem_region[0], 0, sizeof(penv->mem_region[0]) * i);
out:
penv->stats.msa_info_err++;
ICNSS_QMI_ASSERT();
diff --git a/drivers/soc/qcom/msm_smem.c b/drivers/soc/qcom/msm_smem.c
index 959aab998ee1..e4b40347490b 100644
--- a/drivers/soc/qcom/msm_smem.c
+++ b/drivers/soc/qcom/msm_smem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, 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
@@ -182,6 +182,20 @@ static struct restart_notifier_block restart_notifiers[] = {
static int init_smem_remote_spinlock(void);
/**
+ * smem_get_toc() - Used for getting partitions TOC
+ *
+ * @return - Base address off partitions TOC
+ *
+ * Helper function to get base address of partition TOC,
+ * that is present in top 4K of first smem region.
+ */
+static struct smem_toc __iomem *smem_get_toc(void)
+{
+ return smem_areas[0].virt_addr +
+ smem_areas[0].size - 4 * 1024;
+}
+
+/**
* is_probe_done() - Did the probe function successfully complete
*
* @return - true if probe successfully completed, false if otherwise
@@ -315,6 +329,7 @@ static void *__smem_get_entry_nonsecure(unsigned int id, unsigned int *size,
int use_spinlocks = spinlocks_initialized && use_rspinlock;
void *ret = 0;
unsigned long flags = 0;
+ uint32_t e_size;
int rc;
if (!skip_init_check && !smem_initialized_check())
@@ -333,7 +348,11 @@ static void *__smem_get_entry_nonsecure(unsigned int id, unsigned int *size,
if (toc[id].allocated) {
phys_addr_t phys_base;
- *size = toc[id].size;
+ e_size = toc[id].size;
+ if (e_size > smem_ram_size)
+ return ret;
+ *size = e_size;
+
barrier();
phys_base = toc[id].reserved & BASE_ADDR_MASK;
@@ -368,12 +387,19 @@ static void *__smem_get_entry_secure(unsigned int id,
bool skip_init_check,
bool use_rspinlock)
{
+ struct smem_partition_allocation_header *alloc_hdr;
struct smem_partition_header *hdr;
+ uint32_t offset_free_uncached;
+ struct smem_toc __iomem *toc;
+ uint32_t offset_free_cached;
unsigned long lflags = 0;
- void *item = NULL;
- struct smem_partition_allocation_header *alloc_hdr;
+ uint32_t partition_size;
uint32_t partition_num;
+ uint32_t padding_data;
+ uint32_t padding_hdr;
uint32_t a_hdr_size;
+ uint32_t item_size;
+ void *item = NULL;
int rc;
SMEM_DBG("%s(%u, %u, %u, %d, %d)\n", __func__, id, to_proc,
@@ -393,9 +419,13 @@ static void *__smem_get_entry_secure(unsigned int id,
return NULL;
}
+ toc = smem_get_toc();
+
if (flags & SMEM_ANY_HOST_FLAG || !partitions[to_proc].offset) {
if (use_comm_partition) {
partition_num = comm_partition.partition_num;
+ partition_size =
+ readl_relaxed(&toc->entry[partition_num].size);
hdr = smem_areas[0].virt_addr + comm_partition.offset;
} else {
return __smem_get_entry_nonsecure(id, size,
@@ -403,6 +433,7 @@ static void *__smem_get_entry_secure(unsigned int id,
}
} else {
partition_num = partitions[to_proc].partition_num;
+ partition_size = readl_relaxed(&toc->entry[partition_num].size);
hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
}
if (unlikely(!spinlocks_initialized)) {
@@ -433,11 +464,20 @@ static void *__smem_get_entry_secure(unsigned int id,
if (flags & SMEM_ITEM_CACHED_FLAG) {
a_hdr_size = ALIGN(sizeof(*alloc_hdr),
partitions[to_proc].size_cacheline);
- for (alloc_hdr = (void *)(hdr) + hdr->size - a_hdr_size;
+ offset_free_cached = hdr->offset_free_cached;
+ if (WARN_ON(offset_free_cached > partition_size))
+ return NULL;
+
+ for (alloc_hdr = (void *)(hdr) + partition_size - a_hdr_size;
(void *)(alloc_hdr) > (void *)(hdr) +
- hdr->offset_free_cached;
+ offset_free_cached;
alloc_hdr = (void *)(alloc_hdr) -
- alloc_hdr->size - a_hdr_size) {
+ item_size - a_hdr_size) {
+ item_size = alloc_hdr->size;
+ padding_data = alloc_hdr->padding_data;
+ if (WARN_ON(padding_data > item_size
+ || item_size > partition_size))
+ return NULL;
if (alloc_hdr->canary != SMEM_ALLOCATION_CANARY) {
LOG_ERR(
"%s: SMEM corruption detected. Partition %d to %d at %p\n",
@@ -450,20 +490,30 @@ static void *__smem_get_entry_secure(unsigned int id,
}
if (alloc_hdr->smem_type == id) {
/* 8 byte alignment to match legacy */
- *size = ALIGN(alloc_hdr->size -
- alloc_hdr->padding_data, 8);
- item = (void *)(alloc_hdr) - alloc_hdr->size;
+ *size = ALIGN(item_size - padding_data, 8);
+ item = (void *)(alloc_hdr) - item_size;
break;
}
}
} else {
+ offset_free_uncached = hdr->offset_free_uncached;
+ if (WARN_ON(offset_free_uncached > partition_size))
+ return NULL;
+
for (alloc_hdr = (void *)(hdr) + sizeof(*hdr);
(void *)(alloc_hdr) < (void *)(hdr) +
- hdr->offset_free_uncached;
+ offset_free_uncached;
alloc_hdr = (void *)(alloc_hdr) +
sizeof(*alloc_hdr) +
- alloc_hdr->padding_hdr +
- alloc_hdr->size) {
+ padding_hdr +
+ item_size) {
+ padding_hdr = alloc_hdr->padding_hdr;
+ padding_data = alloc_hdr->padding_data;
+ item_size = alloc_hdr->size;
+ if (WARN_ON(padding_hdr > partition_size
+ || item_size > partition_size
+ || padding_data > item_size))
+ return NULL;
if (alloc_hdr->canary != SMEM_ALLOCATION_CANARY) {
LOG_ERR(
"%s: SMEM corruption detected. Partition %d to %d at %p\n",
@@ -476,11 +526,10 @@ static void *__smem_get_entry_secure(unsigned int id,
}
if (alloc_hdr->smem_type == id) {
/* 8 byte alignment to match legacy */
- *size = ALIGN(alloc_hdr->size -
- alloc_hdr->padding_data, 8);
+ *size = ALIGN(item_size - padding_data, 8);
item = (void *)(alloc_hdr) +
sizeof(*alloc_hdr) +
- alloc_hdr->padding_hdr;
+ padding_hdr;
break;
}
}
@@ -571,10 +620,17 @@ static void *alloc_item_nonsecure(unsigned int id, unsigned int size_in)
void *smem_base = smem_ram_base;
struct smem_shared *shared = smem_base;
struct smem_heap_entry *toc = shared->heap_toc;
+ uint32_t free_offset, heap_remaining;
void *ret = NULL;
- if (shared->heap_info.heap_remaining >= size_in) {
- toc[id].offset = shared->heap_info.free_offset;
+ heap_remaining = shared->heap_info.heap_remaining;
+ free_offset = shared->heap_info.free_offset;
+ if (WARN_ON(heap_remaining > smem_ram_size
+ || free_offset > smem_ram_size))
+ return NULL;
+
+ if (heap_remaining >= size_in) {
+ toc[id].offset = free_offset;
toc[id].size = size_in;
/*
* wmb() is necessary to ensure the allocation data is
@@ -586,7 +642,7 @@ static void *alloc_item_nonsecure(unsigned int id, unsigned int size_in)
shared->heap_info.free_offset += size_in;
shared->heap_info.heap_remaining -= size_in;
- ret = smem_base + toc[id].offset;
+ ret = smem_base + free_offset;
/*
* wmb() is necessary to ensure the heap data is consistent
* before continuing to prevent race conditions with remote
@@ -622,11 +678,15 @@ static void *alloc_item_secure(unsigned int id, unsigned int size_in,
void *smem_base = smem_ram_base;
struct smem_partition_header *hdr;
struct smem_partition_allocation_header *alloc_hdr;
+ uint32_t offset_free_uncached;
+ struct smem_toc __iomem *toc;
+ uint32_t offset_free_cached;
+ uint32_t partition_size;
+ uint32_t partition_num;
uint32_t a_hdr_size;
uint32_t a_data_size;
uint32_t size_cacheline;
uint32_t free_space;
- uint32_t partition_num;
void *ret = NULL;
if (to_proc == SMEM_COMM_HOST) {
@@ -653,27 +713,35 @@ static void *alloc_item_secure(unsigned int id, unsigned int size_in,
BUG();
}
- free_space = hdr->offset_free_cached -
- hdr->offset_free_uncached;
+ toc = smem_get_toc();
+ partition_size = readl_relaxed(&toc->entry[partition_num].size);
+
+ offset_free_cached = hdr->offset_free_cached;
+ offset_free_uncached = hdr->offset_free_uncached;
+ if (WARN_ON(offset_free_uncached > offset_free_cached
+ || offset_free_cached > partition_size))
+ return NULL;
+
+ free_space = offset_free_cached - offset_free_uncached;
if (flags & SMEM_ITEM_CACHED_FLAG) {
a_hdr_size = ALIGN(sizeof(*alloc_hdr), size_cacheline);
a_data_size = ALIGN(size_in, size_cacheline);
- if (free_space < a_hdr_size + a_data_size) {
+ if (free_space < a_hdr_size + a_data_size
+ || free_space < size_in) {
SMEM_INFO(
- "%s: id %u not enough memory %u (required %u)\n",
- __func__, id, free_space,
- a_hdr_size + a_data_size);
+ "%s: id %u not enough memory %u (required %u), (size_in %u)\n",
+ __func__, id, free_space,
+ a_hdr_size + a_data_size, size_in);
return ret;
}
- alloc_hdr = (void *)(hdr) + hdr->offset_free_cached -
- a_hdr_size;
+ alloc_hdr = (void *)(hdr) + offset_free_cached - a_hdr_size;
alloc_hdr->canary = SMEM_ALLOCATION_CANARY;
alloc_hdr->smem_type = id;
alloc_hdr->size = a_data_size;
alloc_hdr->padding_data = a_data_size - size_in;
alloc_hdr->padding_hdr = a_hdr_size - sizeof(*alloc_hdr);
- hdr->offset_free_cached = hdr->offset_free_cached -
+ hdr->offset_free_cached = offset_free_cached -
a_hdr_size - a_data_size;
ret = (void *)(alloc_hdr) - a_data_size;
/*
@@ -688,20 +756,21 @@ static void *alloc_item_secure(unsigned int id, unsigned int size_in,
} else {
a_hdr_size = sizeof(*alloc_hdr);
a_data_size = ALIGN(size_in, 8);
- if (free_space < a_hdr_size + a_data_size) {
+ if (free_space < a_hdr_size + a_data_size
+ || free_space < size_in) {
SMEM_INFO(
- "%s: id %u not enough memory %u (required %u)\n",
- __func__, id, free_space,
- a_hdr_size + a_data_size);
+ "%s: id %u not enough memory %u (required %u) (size_in %u)\n",
+ __func__, id, free_space,
+ a_hdr_size + a_data_size, size_in);
return ret;
}
- alloc_hdr = (void *)(hdr) + hdr->offset_free_uncached;
+ alloc_hdr = (void *)(hdr) + offset_free_uncached;
alloc_hdr->canary = SMEM_ALLOCATION_CANARY;
alloc_hdr->smem_type = id;
alloc_hdr->size = a_data_size;
alloc_hdr->padding_data = a_data_size - size_in;
alloc_hdr->padding_hdr = a_hdr_size - sizeof(*alloc_hdr);
- hdr->offset_free_uncached = hdr->offset_free_uncached +
+ hdr->offset_free_uncached = offset_free_uncached +
a_hdr_size + a_data_size;
ret = alloc_hdr + 1;
}
@@ -892,6 +961,12 @@ unsigned int smem_get_free_space(unsigned int to_proc)
{
struct smem_partition_header *hdr;
struct smem_shared *shared;
+ uint32_t offset_free_uncached;
+ struct smem_toc __iomem *toc;
+ uint32_t offset_free_cached;
+ uint32_t heap_remaining;
+ uint32_t p_size;
+ uint32_t p_num;
if (to_proc >= NUM_SMEM_SUBSYSTEMS) {
pr_err("%s: invalid to_proc:%d\n", __func__, to_proc);
@@ -906,10 +981,24 @@ unsigned int smem_get_free_space(unsigned int to_proc)
return UINT_MAX;
}
hdr = smem_areas[0].virt_addr + partitions[to_proc].offset;
- return hdr->offset_free_cached - hdr->offset_free_uncached;
+ offset_free_cached = hdr->offset_free_cached;
+ offset_free_uncached = hdr->offset_free_uncached;
+
+ toc = smem_get_toc();
+ p_num = partitions[to_proc].partition_num;
+ p_size = readl_relaxed(&toc->entry[p_num].size);
+ if (WARN_ON(offset_free_uncached > offset_free_cached
+ || offset_free_cached > p_size))
+ return -EINVAL;
+
+ return offset_free_cached - offset_free_uncached;
}
shared = smem_ram_base;
- return shared->heap_info.heap_remaining;
+ heap_remaining = shared->heap_info.heap_remaining;
+ if (WARN_ON(heap_remaining > smem_ram_size))
+ return -EINVAL;
+
+ return heap_remaining;
}
EXPORT_SYMBOL(smem_get_free_space);
@@ -1216,8 +1305,8 @@ static void smem_init_security_partition(struct smem_toc_entry *entry,
LOG_ERR("Smem partition %d hdr magic is bad\n", num);
BUG();
}
- if (!hdr->size) {
- LOG_ERR("Smem partition %d size is 0\n", num);
+ if (hdr->size != entry->size) {
+ LOG_ERR("Smem partition %d size is invalid\n", num);
BUG();
}
if (hdr->offset_free_uncached > hdr->size) {
diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c
index 3f31fb1216b2..b99d6133aaea 100644
--- a/drivers/soc/qcom/smcinvoke.c
+++ b/drivers/soc/qcom/smcinvoke.c
@@ -1,7 +1,7 @@
/*
* SMC Invoke driver
*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017,2019 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
@@ -306,7 +306,7 @@ static int marshal_in(const struct smcinvoke_cmd_req *req,
const union smcinvoke_arg *args_buf, uint32_t tzhandle,
uint8_t *buf, size_t buf_size, struct file **arr_filp)
{
- int ret = -EINVAL, i = 0;
+ int ret = -EINVAL, i = 0, j = 0;
union smcinvoke_tz_args *tz_args = NULL;
struct smcinvoke_msg_hdr msg_hdr = {tzhandle, req->op, req->counts};
uint32_t offset = sizeof(struct smcinvoke_msg_hdr) +
@@ -351,7 +351,7 @@ static int marshal_in(const struct smcinvoke_cmd_req *req,
}
FOR_ARGS(i, req->counts, OI) {
if (get_tzhandle_from_fd(args_buf[i].o.fd,
- &arr_filp[i], &(tz_args->tzhandle)))
+ &arr_filp[j++], &(tz_args->tzhandle)))
goto out;
tz_args++;
}
diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h
index 91360e240b49..995d6ec7e4b2 100644
--- a/include/uapi/media/cam_isp.h
+++ b/include/uapi/media/cam_isp.h
@@ -90,6 +90,7 @@
#define CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG 3
#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4
#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5
+#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6
/* Query devices */
/**
@@ -387,6 +388,25 @@ struct cam_isp_bw_config {
struct cam_isp_bw_vote rdi_vote[1];
} __attribute__((packed));
+
+/**
+ * struct cam_isp_bw_config_ab - Bandwidth configuration
+ *
+ * @usage_type: Usage type (Single/Dual)
+ * @num_rdi: Number of RDI votes
+ * @left_pix_vote_ab: AB Bandwidth vote for left ISP
+ * @right_pix_vote_ab: AB Bandwidth vote for right ISP
+ * @rdi_vote_ab: AB RDI bandwidth requirements
+ */
+
+struct cam_isp_bw_config_ab {
+ uint32_t usage_type;
+ uint32_t num_rdi;
+ uint64_t left_pix_vote_ab;
+ uint64_t right_pix_vote_ab;
+ uint64_t rdi_vote_ab[1];
+} __attribute__((packed));
+
/**
* struct cam_fe_config - Fetch Engine configuration
*
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index e213b3e498d8..fcb62fe15eee 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -169,6 +169,7 @@ unsigned int sysctl_sched_capacity_margin_down = 1205; /* ~15% margin */
#ifdef CONFIG_SCHED_WALT
unsigned int sysctl_sched_min_task_util_for_boost_colocation;
#endif
+static unsigned int __maybe_unused sched_small_task_threshold = 102;
static inline void update_load_add(struct load_weight *lw, unsigned long inc)
{
@@ -9854,6 +9855,18 @@ static struct rq *find_busiest_queue(struct lb_env *env,
capacity = capacity_of(i);
+ /*
+ * For ASYM_CPUCAPACITY domains, don't pick a cpu that could
+ * eventually lead to active_balancing high->low capacity.
+ * Higher per-cpu capacity is considered better than balancing
+ * average load.
+ */
+ if (env->sd->flags & SD_ASYM_CPUCAPACITY &&
+ capacity_of(env->dst_cpu) < capacity &&
+ (rq->nr_running == 1 || (rq->nr_running == 2 &&
+ task_util(rq->curr) < sched_small_task_threshold)))
+ continue;
+
wl = weighted_cpuload(i);
/*
@@ -10328,6 +10341,27 @@ update_next_balance(struct sched_domain *sd, unsigned long *next_balance)
*next_balance = next;
}
+#ifdef CONFIG_SCHED_WALT
+static inline bool min_cap_cluster_has_misfit_task(void)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ if (!is_min_capacity_cpu(cpu))
+ break;
+ if (cpu_rq(cpu)->walt_stats.nr_big_tasks)
+ return true;
+ }
+
+ return false;
+}
+#else
+static inline bool min_cap_cluster_has_misfit_task(void)
+{
+ return false;
+}
+#endif
+
/*
* idle_balance is called by schedule() if this_cpu is about to become
* idle. Attempts to pull tasks from other CPUs.
@@ -10339,17 +10373,25 @@ static int idle_balance(struct rq *this_rq)
struct sched_domain *sd;
int pulled_task = 0;
u64 curr_cost = 0;
+ bool force_lb = false;
if (cpu_isolated(this_cpu))
return 0;
/*
+ * Force higher capacity CPUs doing load balance, when the lower
+ * capacity CPUs has some misfit tasks.
+ */
+ if (!is_min_capacity_cpu(this_cpu) && min_cap_cluster_has_misfit_task())
+ force_lb = true;
+
+ /*
* We must set idle_stamp _before_ calling idle_balance(), such that we
* measure the duration of idle_balance() as idle time.
*/
this_rq->idle_stamp = rq_clock(this_rq);
- if (!energy_aware() &&
+ if (!energy_aware() && !force_lb &&
(this_rq->avg_idle < sysctl_sched_migration_cost ||
!this_rq->rd->overload)) {
rcu_read_lock();
@@ -10372,7 +10414,8 @@ static int idle_balance(struct rq *this_rq)
if (!(sd->flags & SD_LOAD_BALANCE))
continue;
- if (this_rq->avg_idle < curr_cost + sd->max_newidle_lb_cost) {
+ if (!force_lb &&
+ this_rq->avg_idle < curr_cost + sd->max_newidle_lb_cost) {
update_next_balance(sd, &next_balance);
break;
}