aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-09-11 04:57:17 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-09-11 04:57:17 -0700
commit9e9b453cf04e1ed7a6c0f3c12ab6aaeffba44180 (patch)
treea7cb63470182cb62af69043d1b4849aa635fb6e4
parentfd6ec63d84c41eb6ebb6b23d856d6925d57e09fb (diff)
parentc53d4be98bc51c34e9a73a155f9b4e0d405db809 (diff)
Merge c53d4be98bc51c34e9a73a155f9b4e0d405db809 on remote branchLA.UM.7.8.r3-01900-SDM710.0
Change-Id: Ie0c01d4455936d50a31d3652c3500270ed9e8037
-rw-r--r--Documentation/devicetree/bindings/arm/msm/msm.txt4
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt102
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/boot/compressed/head.S2
-rw-r--r--arch/arm/configs/msm8937-perf_defconfig1
-rw-r--r--arch/arm/configs/msm8937_defconfig1
-rw-r--r--arch/arm/configs/msm8937go-perf_defconfig1
-rw-r--r--arch/arm/configs/msm8937go_defconfig1
-rw-r--r--arch/arm/configs/msm8953-perf_defconfig1
-rw-r--r--arch/arm/configs/msm8953_defconfig1
-rw-r--r--arch/arm/configs/sdm670-perf_defconfig1
-rw-r--r--arch/arm/configs/sdm670_defconfig1
-rw-r--r--arch/arm/include/asm/arch_timer.h7
-rw-r--r--drivers/char/adsprpc.c10
-rw-r--r--drivers/clocksource/Kconfig2
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c7
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c3
-rw-r--r--drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c10
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c18
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_core/cam_hw_mgr_intf.h12
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c23
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c8
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h537
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_cpas/include/cam_cpas_api.h1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/a5_hw/a5_core.c6
-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.c7
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/ipe_hw/ipe_core.c6
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c571
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h73
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c448
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c33
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h20
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile1
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c58
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h32
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c404
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h103
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c147
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h22
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c304
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h23
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h13
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h5
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h11
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c3
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c26
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c20
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c7
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c33
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c167
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h10
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c4
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c20
-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.c10
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c2
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c32
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h11
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c164
-rw-r--r--drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h16
-rw-r--r--drivers/media/platform/msm/vidc/hfi_response_handler.c36
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi.h4
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h1
-rw-r--r--drivers/media/platform/msm/vidc_3x/hfi_response_handler.c30
-rw-r--r--drivers/media/platform/msm/vidc_3x/vidc_hfi.h4
-rw-r--r--drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h1
-rw-r--r--drivers/misc/qseecom.c49
-rw-r--r--drivers/soc/qcom/socinfo.c9
-rw-r--r--drivers/tty/serial/msm_geni_serial.c6
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c11
-rw-r--r--drivers/usb/dwc3/gadget.c12
-rw-r--r--include/soc/qcom/socinfo.h4
-rw-r--r--include/uapi/media/cam_isp.h57
-rw-r--r--include/uapi/sound/compress_params.h5
-rw-r--r--kernel/sched/core.c1
-rw-r--r--kernel/sched/fair.c31
-rw-r--r--kernel/sched/features.h6
84 files changed, 3488 insertions, 382 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index 771ca5a937af..ca5bf4069dc6 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -149,6 +149,9 @@ SoCs:
- QM215
compatible = "qcom, qm215"
+- QCM2150
+ compatible = "qcom, qcm2150"
+
- MDM9640
compatible = "qcom,mdm9640"
@@ -373,6 +376,7 @@ compatible = "qcom,sdm439-qrd"
compatible = "qcom,sda439-cdp"
compatible = "qcom,sda439-mtp"
compatible = "qcom,qm215-qrd"
+compatible = "qcom,qcm2150-qrd"
compatible = "qcom,msm8953-rumi"
compatible = "qcom,msm8953-sim"
compatible = "qcom,msm8953-cdp"
diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt
new file mode 100644
index 000000000000..aeed60fa6055
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/video/msm-cam-ppi.txt
@@ -0,0 +1,102 @@
+* Qualcomm Technologies, Inc. MSM camera PPI
+
+=======================
+Required Node Structure
+=======================
+The camera PPI node must be described in First level of device nodes. The
+first level describe the overall PPI node structure.
+
+======================================
+First Level Node - PPI device
+======================================
+
+- compatible
+ Usage: required
+ Value type: <string>
+ Definition: Should be "qcom,ppi-v1.0",
+ "qcom,ppi-v1.1", "qcom,ppi-v1.2",
+ "qcom,ppi-v2.0", "qcom,ppi".
+
+- cell-index: ppi hardware core index
+ Usage: required
+ Value type: <u32>
+ Definition: Should specify the Hardware index id.
+
+- reg
+ Usage: required
+ Value type: <u32>
+ Definition: offset and length of the register set
+ for the device for the ppi operating in
+ compatible mode.
+
+- reg-names
+ Usage: required
+ Value type: <string>
+ Definition: Should specify relevant names to each
+ reg property defined.
+
+- reg-cam-base
+ Usage: required
+ Value type: <string>
+ Definition: offset of PPI in camera hw block
+
+- interrupts
+ Usage: required
+ Value type: <u32>
+ Definition: Interrupt associated with PPI HW.
+
+- interrupt-names
+ Usage: required
+ Value type: <string>
+ Definition: Name of the interrupt.
+
+- clock-names
+ Usage: required
+ Value type: <string>
+ Definition: List of clock names required for PPI HW.
+
+- clock-rates
+ Usage: required
+ Value type: <u32>
+ Definition: List of clock rates in Hz for PPI HW.
+
+- clock-cntl-level
+ Usage: required
+ Value type: <string>
+ Definition: All different clock level node can support.
+
+- clocks
+ Usage: required
+ Value type: <phandle>
+ Definition: all clock phandle and source clocks.
+
+- regulator-names
+ Usage: required
+ Value type: <string>
+ Definition: name of the voltage regulators required for the device.
+
+- gdscr-supply
+ Usage: required
+ Value type: <phandle>
+ Definition: should contain gdsr regulator used for PPI clocks.
+
+Example:
+ qcom,ppi0@ace0000 {
+ cell-index = <0>;
+ compatible = "qcom,ppi170";
+ reg-names = "ppi";
+ reg = <0xace0000 0x200>;
+ reg-cam-base = <0xe0000>;
+ interrupt-names = "ppi";
+ interrupts = <0 202 0>;
+ regulator-names = "gdscr", "refgen";
+ gdscr-supply = <&titan_top_gdsc>;
+ clocks = <&clock_camcc CAM_CC_CPHY_RX_CLK_SRC>,
+ <&clock_camcc CAM_CC_PPI0_CLK>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+ <&clock_camcc CAM_CC_CSI0PHYTIMER_CLK>;
+ clock-names = "cphy_rx_clk_src", "ppi0_clk"
+ clock-rates = <400000000 0 300000000 0>;
+ clock-cntl-level = "turbo";
+ status = "ok";
+};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b7b2864e9f01..353563e02342 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2175,6 +2175,17 @@ config AUTO_ZRELADDR
config EFI_STUB
bool
+config ARM_DECOMPRESSOR_LIMIT
+ hex "Limit the decompressor memory area"
+ default 0x3200000
+ help
+ Allows overriding of the memory size that decompressor maps with
+ read, write and execute permissions to avoid speculative prefetch.
+
+ By default ARM_DECOMPRESSOR_LIMIT maps first 1GB of memory
+ with read, write and execute permissions and reset of the memory
+ as strongly ordered.
+
config EFI
bool "UEFI runtime support"
depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 51fc9fb6dc2c..6f7128ee33a2 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -690,7 +690,7 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
mov r0, r3
mov r9, r0, lsr #18
mov r9, r9, lsl #18 @ start of RAM
- add r10, r9, #0x10000000 @ a reasonable RAM size
+ add r10, r9, #CONFIG_ARM_DECOMPRESSOR_LIMIT
mov r1, #0x12 @ XN|U + section mapping
orr r1, r1, #3 << 10 @ AP=11
add r2, r3, #16384
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index 1afcf46ced40..2fcdde2d362c 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -553,6 +553,7 @@ CONFIG_USB_BAM=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig
index b65fbac85719..5e6b5db5ed0a 100644
--- a/arch/arm/configs/msm8937_defconfig
+++ b/arch/arm/configs/msm8937_defconfig
@@ -564,6 +564,7 @@ CONFIG_MSM_EXT_DISPLAY=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/msm8937go-perf_defconfig b/arch/arm/configs/msm8937go-perf_defconfig
index 6be2749963db..75925ad4619a 100644
--- a/arch/arm/configs/msm8937go-perf_defconfig
+++ b/arch/arm/configs/msm8937go-perf_defconfig
@@ -550,6 +550,7 @@ CONFIG_USB_BAM=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/msm8937go_defconfig b/arch/arm/configs/msm8937go_defconfig
index b76c4183a762..17ff762f368e 100644
--- a/arch/arm/configs/msm8937go_defconfig
+++ b/arch/arm/configs/msm8937go_defconfig
@@ -559,6 +559,7 @@ CONFIG_MSM_EXT_DISPLAY=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 5973e99f4bcc..26f6c8511975 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -557,6 +557,7 @@ CONFIG_USB_BAM=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 72c12458721c..b15db9e4e07f 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -567,6 +567,7 @@ CONFIG_MSM_EXT_DISPLAY=y
CONFIG_MSM_RMNET_BAM=y
CONFIG_MSM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig
index 2f003b94a83f..59933a6aaefe 100644
--- a/arch/arm/configs/sdm670-perf_defconfig
+++ b/arch/arm/configs/sdm670-perf_defconfig
@@ -455,6 +455,7 @@ CONFIG_MSM_GPUCC_SDM845=y
CONFIG_MSM_CLK_AOP_QMP=y
CONFIG_QCOM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MSM_QMP=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig
index 702f62213e13..0e5024c3a462 100644
--- a/arch/arm/configs/sdm670_defconfig
+++ b/arch/arm/configs/sdm670_defconfig
@@ -469,6 +469,7 @@ CONFIG_MSM_GPUCC_SDM845=y
CONFIG_MSM_CLK_AOP_QMP=y
CONFIG_QCOM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_TIMER_LEAP=y
CONFIG_MSM_QMP=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_LAZY_MAPPING=y
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index d4ebf5679f1f..1d85857771fd 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -92,7 +92,14 @@ static inline u64 arch_counter_get_cntvct(void)
u64 cval;
isb();
+#if IS_ENABLED(CONFIG_MSM_TIMER_LEAP)
+#define L32_BITS 0x00000000FFFFFFFF
+ do {
+ asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
+ } while ((cval & L32_BITS) == L32_BITS);
+#else
asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
+#endif
return cval;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index a7fe093a63dc..5907254c577e 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -807,7 +807,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
struct fastrpc_session_ctx *sess;
struct fastrpc_apps *apps = fl->apps;
int cid = fl->cid;
- struct fastrpc_channel_ctx *chan = &apps->channel[cid];
+ struct fastrpc_channel_ctx *chan = NULL;
struct fastrpc_mmap *map = NULL;
unsigned long attrs;
dma_addr_t region_phys = 0;
@@ -815,6 +815,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
unsigned long flags;
int err = 0, vmid;
+ VERIFY(err, cid >= 0 && cid < NUM_CHANNELS);
+ if (err)
+ goto bail;
+ chan = &apps->channel[cid];
+
if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
return 0;
map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -2380,6 +2385,9 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
ioctl.crc = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
+ if (err)
+ pr_err("adsprpc: %s: releasing DSP process failed for %s, returned 0x%x",
+ __func__, current->comm, err);
bail:
return err;
}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 91cf85785782..863be4358a58 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -334,7 +334,7 @@ config ARM_ARCH_TIMER_VCT_ACCESS
config MSM_TIMER_LEAP
bool "ARCH TIMER counter rollover"
default n
- depends on ARM_ARCH_TIMER && ARM64
+ depends on ARM_ARCH_TIMER
help
This option enables a check for least significant 32 bits of
counter rollover. On every counter read if least significant
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 378ef4c3e4eb..e06ec87d11a6 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-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
@@ -121,6 +121,9 @@ static ssize_t debugfs_state_info_read(struct file *file,
dsi_ctrl->clk_freq.pix_clk_rate,
dsi_ctrl->clk_freq.esc_clk_rate);
+ if (len > count)
+ len = count;
+
/* TODO: make sure that this does not exceed 4K */
if (copy_to_user(buff, buf, len)) {
kfree(buf);
@@ -176,6 +179,8 @@ static ssize_t debugfs_reg_dump_read(struct file *file,
return rc;
}
+ if (len > count)
+ len = count;
/* TODO: make sure that this does not exceed 4K */
if (copy_to_user(buff, buf, len)) {
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
index 4914df2e6bc1..6c6286de99a1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw_v3_0.c
@@ -403,7 +403,8 @@ int dsi_phy_hw_v3_0_wait_for_lane_idle(
pr_debug("%s: polling for lanes to be in stop state, mask=0x%08x\n",
__func__, stop_state_mask);
rc = readl_poll_timeout(phy->base + DSIPHY_CMN_LANE_STATUS1, val,
- (val == stop_state_mask), sleep_us, timeout_us);
+ ((val & stop_state_mask) == stop_state_mask),
+ sleep_us, timeout_us);
if (rc) {
pr_err("%s: lanes not in stop state, LANE_STATUS=0x%08x\n",
__func__, val);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index 6797ba4e58d6..20976afd9c22 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -974,7 +974,7 @@ int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
&eeprom_cap,
sizeof(struct cam_eeprom_query_cap_t))) {
CAM_ERR(CAM_EEPROM, "Failed Copy to User");
- return -EFAULT;
+ rc = -EFAULT;
goto release_mutex;
}
CAM_DBG(CAM_EEPROM, "eeprom_cap: ID: %d", eeprom_cap.slot_info);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 576d5d6742dd..e63c79abcdbb 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1571,12 +1571,6 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C));
- /* Update bandwidth usage to enable AXI/ABH clock,
- * which will help to reset CPP AXI.Bandwidth will be
- * made zero at cpp_release_hardware.
- */
- msm_cpp_update_bandwidth(cpp_dev, 0x1000, 0x1000);
-
/* mask IRQ status */
msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC);
@@ -3657,6 +3651,8 @@ STREAM_BUFF_END:
} else {
ioctl_cmd = VIDIOC_MSM_BUF_MNGR_IOCTL_CMD;
idx = MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX;
+ buff_mgr_info.index =
+ frame_info.output_buffer_info[0].index;
}
rc = msm_cpp_buffer_ops(cpp_dev, ioctl_cmd, idx,
&buff_mgr_info);
@@ -4370,6 +4366,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
memset(&k64_frame_info, 0, sizeof(k64_frame_info));
k64_frame_info.identity = k32_frame_info.identity;
k64_frame_info.frame_id = k32_frame_info.frame_id;
+ k64_frame_info.output_buffer_info[0].index =
+ k32_frame_info.output_buffer_info[0].index;
kp_ioctl.ioctl_ptr = (__force void __user *)&k64_frame_info;
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 7600cbb77cee..11bad5dd4647 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
@@ -462,6 +462,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
ctx->dev_name, ctx->ctx_id, req->request_id);
for (j = 0; j < req->num_in_map_entries; j++) {
+ rc = cam_sync_check_valid(
+ req->in_map_entries[j].sync_id);
+ if (rc) {
+ CAM_ERR(CAM_CTXT,
+ "invalid in map sync object %d",
+ req->in_map_entries[j].sync_id);
+ goto put_ref;
+ }
+ }
+
+ for (j = 0; j < req->num_in_map_entries; j++) {
cam_context_getref(ctx);
rc = cam_sync_register_callback(
cam_context_sync_callback,
@@ -482,7 +493,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
ctx->dev_name, ctx->ctx_id,
req->request_id);
- goto put_ctx_ref;
+ cam_context_putref(ctx);
+ goto put_ref;
+
}
CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
req->in_map_entries[j].sync_id, rc);
@@ -491,9 +504,6 @@ 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);
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 6b7a9007cff9..2afdafb03184 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
@@ -262,6 +262,16 @@ struct cam_hw_dump_pf_args {
bool *mem_found;
};
+/**
+ * struct cam_hw_reset_args -hw reset arguments
+ *
+ * @ctxt_to_hw_map: HW context from the acquire
+ *
+ */
+struct cam_hw_reset_args {
+ void *ctxt_to_hw_map;
+};
+
/* enum cam_hw_mgr_command - Hardware manager command type */
enum cam_hw_mgr_command {
CAM_HW_MGR_CMD_INTERNAL,
@@ -313,6 +323,7 @@ struct cam_hw_cmd_args {
* @hw_open: Function pointer for HW init
* @hw_close: Function pointer for HW deinit
* @hw_flush: Function pointer for HW flush
+ * @hw_reset: Function pointer for HW reset
*
*/
struct cam_hw_mgr_intf {
@@ -333,6 +344,7 @@ struct cam_hw_mgr_intf {
int (*hw_open)(void *hw_priv, void *fw_download_args);
int (*hw_close)(void *hw_priv, void *hw_close_args);
int (*hw_flush)(void *hw_priv, void *hw_flush_args);
+ int (*hw_reset)(void *hw_priv, void *hw_reset_args);
};
#endif /* _CAM_HW_MGR_INTF_H_ */
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 4276b356da73..a68e20745b1a 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
@@ -980,8 +980,10 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
return -EINVAL;
}
- if (!CAM_CPAS_CLIENT_VALID(client_indx))
+ if (!CAM_CPAS_CLIENT_VALID(client_indx)) {
+ CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx);
return -EINVAL;
+ }
mutex_lock(&cpas_hw->hw_mutex);
mutex_lock(&cpas_core->client_mutex[client_indx]);
@@ -1099,8 +1101,10 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args,
cmd_hw_stop = (struct cam_cpas_hw_cmd_stop *)stop_args;
client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_stop->client_handle);
- if (!CAM_CPAS_CLIENT_VALID(client_indx))
+ if (!CAM_CPAS_CLIENT_VALID(client_indx)) {
+ CAM_ERR(CAM_CPAS, "Client index invalid %d", client_indx);
return -EINVAL;
+ }
mutex_lock(&cpas_hw->hw_mutex);
mutex_lock(&cpas_core->client_mutex[client_indx]);
@@ -1162,14 +1166,20 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args,
ahb_vote.vote.level = CAM_SUSPEND_VOTE;
rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client,
&ahb_vote, NULL);
- if (rc)
+ if (rc) {
+ CAM_ERR(CAM_CPAS, "ahb vote failed for %s rc %d",
+ cpas_client->data.identifier, rc);
goto done;
+ }
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);
+ if (rc)
+ CAM_ERR(CAM_CPAS, "axi vote failed for %s rc %d",
+ cpas_client->data.identifier, rc);
done:
mutex_unlock(&cpas_core->client_mutex[client_indx]);
@@ -1234,6 +1244,13 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw,
rc = cam_common_util_get_string_index(soc_private->client_name,
soc_private->num_clients, client_name, &client_indx);
+ if (rc) {
+ CAM_ERR(CAM_CPAS, "No match found for client %s",
+ client_name);
+ mutex_unlock(&cpas_hw->hw_mutex);
+ return rc;
+ }
+
mutex_lock(&cpas_core->client_mutex[client_indx]);
if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) ||
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
index 719fb12d7353..aaa435d34f4c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
@@ -21,6 +21,7 @@
#include "cam_cpas_soc.h"
#include "cpastop100.h"
#include "cpastop_v150_100.h"
+#include "cpastop_v150_110.h"
#include "cpastop_v170_110.h"
#include "cpastop_v175_100.h"
#include "cpastop_v175_101.h"
@@ -117,6 +118,10 @@ static int cam_cpastop_get_hw_info(struct cam_hw_info *cpas_hw,
(hw_caps->cpas_version.minor == 0) &&
(hw_caps->cpas_version.incr == 0))
soc_info->hw_version = CAM_CPAS_TITAN_150_V100;
+ else if ((hw_caps->cpas_version.major == 1) &&
+ (hw_caps->cpas_version.minor == 1) &&
+ (hw_caps->cpas_version.incr == 0))
+ soc_info->hw_version = CAM_CPAS_TITAN_150_V110;
}
CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_info->hw_version);
@@ -668,6 +673,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
case CAM_CPAS_TITAN_150_V100:
camnoc_info = &cam150_cpas100_camnoc_info;
break;
+ case CAM_CPAS_TITAN_150_V110:
+ camnoc_info = &cam150_cpas110_camnoc_info;
+ break;
default:
CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
hw_caps->camera_version.major,
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h
new file mode 100644
index 000000000000..734f3784ef6c
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cpastop_v150_110.h
@@ -0,0 +1,537 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CPASTOP_V150_110_H_
+#define _CPASTOP_V150_110_H_
+
+#define TEST_IRQ_ENABLE 0
+
+static struct cam_camnoc_irq_sbm cam_cpas_v150_110_irq_sbm = {
+ .sbm_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2040, /* SBM_FAULTINEN0_LOW */
+ .value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
+ 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
+ 0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
+ 0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
+ 0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
+ 0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
+ (TEST_IRQ_ENABLE ?
+ 0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
+ 0x0),
+ },
+ .sbm_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
+ },
+ .sbm_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
+ .value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
+ }
+};
+
+static struct cam_camnoc_irq_err
+ cam_cpas_v150_110_irq_err[] = {
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
+ .enable = true,
+ .sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x1190,
+ /* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
+ .enable = true,
+ .sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
+ .enable = TEST_IRQ_ENABLE ? true : false,
+ .sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x5,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+};
+
+static struct cam_camnoc_specific
+ cam_cpas_v150_110_camnoc_specific[] = {
+ {
+ .port_type = CAM_CAMNOC_CDM,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
+ .mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
+ .shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
+ .value = 0x2,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE02,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
+ .value = 0x1,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE13,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
+ .value = 0x1,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
+ .mask = 0x7,
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
+ .shift = 0x0,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
+ .value = 0x5,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_JPEG,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
+ .value = 0x22,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_FD,
+ .enable = false,
+ },
+ {
+ .port_type = CAM_CAMNOC_ICP,
+ .enable = true,
+ .flag_out_set0_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_WRITE,
+ .masked_value = 0,
+ .offset = 0x2088,
+ .value = 0x100000,
+ },
+ },
+};
+
+static struct cam_camnoc_err_logger_info cam150_cpas110_err_logger_offsets = {
+ .mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ .errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ .errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
+ .errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
+ .errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
+ .errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
+ .errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
+ .errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
+ .errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
+ .errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
+};
+
+static struct cam_cpas_hw_errata_wa_list cam150_cpas110_errata_wa_list = {
+ .camnoc_flush_slave_pending_trans = {
+ .enable = false,
+ .data.reg_info = {
+ .access_type = CAM_REG_TYPE_READ,
+ .offset = 0x2100, /* SidebandManager_SenseIn0_Low */
+ .mask = 0xE0000, /* Bits 17, 18, 19 */
+ .value = 0, /* expected to be 0 */
+ },
+ },
+};
+
+static struct cam_camnoc_info cam150_cpas110_camnoc_info = {
+ .specific = &cam_cpas_v150_110_camnoc_specific[0],
+ .specific_size = sizeof(cam_cpas_v150_110_camnoc_specific) /
+ sizeof(cam_cpas_v150_110_camnoc_specific[0]),
+ .irq_sbm = &cam_cpas_v150_110_irq_sbm,
+ .irq_err = &cam_cpas_v150_110_irq_err[0],
+ .irq_err_size = sizeof(cam_cpas_v150_110_irq_err) /
+ sizeof(cam_cpas_v150_110_irq_err[0]),
+ .err_logger = &cam150_cpas110_err_logger_offsets,
+ .errata_wa_list = &cam150_cpas110_errata_wa_list,
+};
+
+#endif /* _CPASTOP_V150_110_H_ */
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 7b534a93c71d..f2858631ce29 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
@@ -43,6 +43,7 @@ enum cam_cpas_reg_base {
enum cam_cpas_hw_version {
CAM_CPAS_TITAN_NONE = 0,
CAM_CPAS_TITAN_150_V100 = 0x150100,
+ CAM_CPAS_TITAN_150_V110 = 0x150110,
CAM_CPAS_TITAN_170_V100 = 0x170100,
CAM_CPAS_TITAN_170_V110 = 0x170110,
CAM_CPAS_TITAN_170_V120 = 0x170120,
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 e13d7f2edcee..4dbc8f1bd991 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
@@ -464,7 +464,11 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ICP_A5_CMD_CPAS_STOP:
if (core_info->cpas_start) {
- cam_cpas_stop(core_info->cpas_handle);
+ rc = cam_cpas_stop(core_info->cpas_handle);
+ if (rc) {
+ CAM_ERR(CAM_ICP, "cpas stop failed %d", rc);
+ return rc;
+ }
core_info->cpas_start = false;
}
break;
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 c94276ce8778..f522f7138765 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
@@ -347,7 +347,11 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ICP_BPS_CMD_CPAS_STOP:
if (core_info->cpas_start) {
- cam_cpas_stop(core_info->cpas_handle);
+ rc = cam_cpas_stop(core_info->cpas_handle);
+ if (rc) {
+ CAM_ERR(CAM_ICP, "cpas stop failed %d", rc);
+ return rc;
+ }
core_info->cpas_start = false;
}
break;
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 cfc474afc633..03b93acbd847 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
@@ -4077,8 +4077,13 @@ static void cam_icp_mgr_print_io_bufs(struct cam_packet *packet,
for (i = 0; i < packet->num_io_configs; i++) {
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
- if (!io_cfg[i].mem_handle[j])
+ if (!io_cfg[i].mem_handle[j]) {
+ CAM_ERR(CAM_ICP,
+ "Mem Handle %d is NULL for %d io config",
+ j, i);
break;
+ }
+
if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
GET_FD_FROM_HANDLE(pf_buf_info)) {
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 ae3d1343c1c4..ae58b34062d6 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
@@ -342,7 +342,11 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ICP_IPE_CMD_CPAS_STOP:
if (core_info->cpas_start) {
- cam_cpas_stop(core_info->cpas_handle);
+ rc = cam_cpas_stop(core_info->cpas_handle);
+ if (rc) {
+ CAM_ERR(CAM_ICP, "CPAS stop failed %d", rc);
+ return rc;
+ }
core_info->cpas_start = false;
}
break;
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 57375c4ad50f..53c1c0fd54a9 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
@@ -38,18 +38,26 @@ static int cam_isp_context_dump_active_request(void *data, unsigned long iova,
static void __cam_isp_ctx_update_state_monitor_array(
struct cam_isp_context *ctx_isp,
- enum cam_isp_state_change_trigger trigger_type,
- uint32_t req_id)
+ enum cam_isp_hw_event_type hw_event,
+ enum cam_isp_ctx_activated_substate curr_state,
+ enum cam_isp_ctx_activated_substate next_state)
{
int iterator = 0;
iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head);
ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
- ctx_isp->substate_activated;
- ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger =
- trigger_type;
- ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id =
- req_id;
+ curr_state;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].next_state =
+ next_state;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].hw_event =
+ hw_event;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].last_reported_id =
+ ctx_isp->req_info.reported_req_id;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].last_applied_req_id =
+ ctx_isp->req_info.last_applied_req_id;
+ ctx_isp->cam_isp_ctx_state_monitor[iterator].frame_id =
+ ctx_isp->frame_id;
+
ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
jiffies_to_msecs(jiffies);
}
@@ -79,17 +87,17 @@ static const char *__cam_isp_hw_evt_val_to_type(
uint32_t evt_id)
{
switch (evt_id) {
- case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR:
+ case CAM_ISP_HW_EVENT_ERROR:
return "ERROR";
- case CAM_ISP_STATE_CHANGE_TRIGGER_SOF:
+ case CAM_ISP_HW_EVENT_SOF:
return "SOF";
- case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE:
+ case CAM_ISP_HW_EVENT_REG_UPDATE:
return "REG_UPDATE";
- case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH:
+ case CAM_ISP_HW_EVENT_EPOCH:
return "EPOCH";
- case CAM_ISP_STATE_CHANGE_TRIGGER_EOF:
+ case CAM_ISP_HW_EVENT_EOF:
return "EOF";
- case CAM_ISP_STATE_CHANGE_TRIGGER_DONE:
+ case CAM_ISP_HW_EVENT_DONE:
return "DONE";
default:
return "CAM_ISP_EVENT_INVALID";
@@ -97,29 +105,58 @@ static const char *__cam_isp_hw_evt_val_to_type(
}
static void __cam_isp_ctx_dump_state_monitor_array(
- struct cam_isp_context *ctx_isp)
+ struct cam_isp_context *ctx_isp, bool log_rate_limit)
{
int i = 0;
uint64_t state_head = 0;
uint64_t index;
+ struct cam_isp_context_state_monitor *ctx_monitor;
state_head = atomic64_read(&ctx_isp->state_monitor_head);
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "Dumping state information for preceding requests");
+
+ ctx_monitor = ctx_isp->cam_isp_ctx_state_monitor;
+
+ if (log_rate_limit)
+ CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
+ "Dumping state information for preceding requests");
+ else
+ CAM_INFO(CAM_ISP,
+ "Dumping state information for preceding requests");
for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
i--) {
index = (((state_head - i) +
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES);
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "time[0x%llx] req_id[%u] state[%s] evt_type[%s]",
- ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp,
- ctx_isp->cam_isp_ctx_state_monitor[index].req_id,
- __cam_isp_ctx_substate_val_to_type(
- ctx_isp->cam_isp_ctx_state_monitor[index].curr_state),
- __cam_isp_hw_evt_val_to_type(
- ctx_isp->cam_isp_ctx_state_monitor[index].trigger));
+
+ if (log_rate_limit) {
+ CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
+ "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]",
+ ctx_monitor[index].evt_time_stamp,
+ ctx_monitor[index].last_reported_id,
+ ctx_monitor[index].frame_id,
+ ctx_monitor[index].last_applied_req_id,
+ __cam_isp_ctx_substate_val_to_type(
+ ctx_monitor[index].curr_state),
+ __cam_isp_ctx_substate_val_to_type(
+ ctx_monitor[index].next_state),
+ __cam_isp_hw_evt_val_to_type(
+ ctx_monitor[index].hw_event));
+
+ } else {
+ CAM_INFO(CAM_ISP,
+ "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]",
+ ctx_monitor[index].evt_time_stamp,
+ ctx_monitor[index].last_reported_id,
+ ctx_monitor[index].frame_id,
+ ctx_monitor[index].last_applied_req_id,
+ __cam_isp_ctx_substate_val_to_type(
+ ctx_monitor[index].curr_state),
+ __cam_isp_ctx_substate_val_to_type(
+ ctx_monitor[index].next_state),
+ __cam_isp_hw_evt_val_to_type(
+ ctx_monitor[index].hw_event));
+ }
}
}
@@ -403,7 +440,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
struct cam_context *ctx = ctx_isp->base;
if (list_empty(&ctx->active_req_list)) {
- CAM_DBG(CAM_ISP, "Buf done with no active request!");
+ CAM_WARN(CAM_ISP, "Buf done with no active request!");
goto end;
}
@@ -415,6 +452,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
trace_cam_buf_done("ISP", ctx, req);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = done->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((done->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = done->irq_mono_boot_time;
+
for (i = 0; i < done->num_handles; i++) {
for (j = 0; j < req_isp->num_fence_map_out; j++) {
if (done->resource_handle[i] ==
@@ -508,6 +553,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
CAM_DBG(CAM_REQ,
"Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u",
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_HW_EVENT_DONE,
+ ctx_isp->substate_activated,
+ ctx_isp->substate_activated);
} else {
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_req_list);
@@ -515,32 +564,59 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
CAM_DBG(CAM_REQ,
"Move active request %lld to free list(cnt = %d) [all fences done], ctx %u",
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
+ ctx_isp->req_info.last_bufdone_req_id = req->request_id;
+ ctx_isp->req_info.last_bufdone_time_stamp =
+ jiffies_to_msecs(jiffies);
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp,
+ CAM_ISP_HW_EVENT_DONE,
+ ctx_isp->substate_activated,
+ ctx_isp->substate_activated);
}
+ if (ctx_isp->active_req_cnt && ctx_isp->irq_delay_detect) {
+ CAM_ERR(CAM_ISP, "isp req[%lld] IRQ buf done got delayed",
+ req->request_id);
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+
+ for (j = 0; j < req_isp->num_fence_map_out; j++) {
+ rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
+ CAM_SYNC_STATE_SIGNALED_ERROR);
+ if (rc)
+ CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
+ rc);
+ req_isp->fence_map_out[j].sync_id = -1;
+ }
+ list_del_init(&req->list);
+ list_add_tail(&req->list, &ctx->free_req_list);
+ ctx_isp->active_req_cnt--;
+ }
+ ctx_isp->irq_delay_detect = false;
end:
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
- ctx_isp->base->req_list->request_id);
return rc;
}
static void __cam_isp_ctx_send_sof_boot_timestamp(
struct cam_isp_context *ctx_isp, uint64_t request_id,
- uint32_t sof_event_status)
+ uint32_t sof_event_status, uint64_t delta_ts)
{
struct cam_req_mgr_message req_msg;
req_msg.session_hdl = ctx_isp->base->session_hdl;
req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
req_msg.u.frame_msg.request_id = request_id;
- req_msg.u.frame_msg.timestamp = ctx_isp->boot_timestamp;
req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl;
req_msg.u.frame_msg.sof_status = sof_event_status;
+ req_msg.u.frame_msg.timestamp = ctx_isp->prev_boot_timestamp + delta_ts;
+
CAM_DBG(CAM_ISP,
- "request id:%lld frame number:%lld boot time stamp:0x%llx",
- request_id, ctx_isp->frame_id,
- ctx_isp->boot_timestamp);
+ "req id:%lld frame num:%lld bt_ts:0x%llx pre_bt_ts:0x%llx diff:0x%llx",
+ request_id, ctx_isp->frame_id,
+ ctx_isp->boot_timestamp, ctx_isp->prev_boot_timestamp,
+ delta_ts);
+
if (cam_req_mgr_notify_message(&req_msg,
V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS,
@@ -548,6 +624,8 @@ static void __cam_isp_ctx_send_sof_boot_timestamp(
CAM_ERR(CAM_ISP,
"Error in notifying the boot time for req id:%lld",
request_id);
+
+ ctx_isp->prev_boot_timestamp = req_msg.u.frame_msg.timestamp;
}
@@ -556,6 +634,7 @@ static void __cam_isp_ctx_send_sof_timestamp(
uint32_t sof_event_status)
{
struct cam_req_mgr_message req_msg;
+ uint64_t delta_ts;
req_msg.session_hdl = ctx_isp->base->session_hdl;
req_msg.u.frame_msg.frame_id = ctx_isp->frame_id;
@@ -565,9 +644,9 @@ static void __cam_isp_ctx_send_sof_timestamp(
req_msg.u.frame_msg.sof_status = sof_event_status;
CAM_DBG(CAM_ISP,
- "request id:%lld frame number:%lld SOF time stamp:0x%llx",
+ "request id:%lld frame number:%lld SOF time stamp:0x%llx, Prev SOF time:0x%llx",
request_id, ctx_isp->frame_id,
- ctx_isp->sof_timestamp_val);
+ ctx_isp->sof_timestamp_val, ctx_isp->prev_sof_timestamp_val);
CAM_DBG(CAM_ISP, "sof status:%d", sof_event_status);
if (cam_req_mgr_notify_message(&req_msg,
@@ -575,21 +654,64 @@ static void __cam_isp_ctx_send_sof_timestamp(
CAM_ERR(CAM_ISP,
"Error in notifying the sof time for req id:%lld",
request_id);
+ delta_ts = ctx_isp->sof_timestamp_val -
+ ctx_isp->prev_sof_timestamp_val;
__cam_isp_ctx_send_sof_boot_timestamp(ctx_isp,
- request_id, sof_event_status);
+ request_id, sof_event_status,
+ (ctx_isp->prev_sof_timestamp_val == 0) ?
+ ctx_isp->boot_timestamp :
+ delta_ts);
+
+ ctx_isp->prev_sof_timestamp_val =
+ ctx_isp->sof_timestamp_val;
}
static int __cam_isp_ctx_reg_upd_in_epoch_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
- if (ctx_isp->frame_id == 1)
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
+
+ struct cam_context *ctx = ctx_isp->base;
+ struct cam_ctx_request *req = NULL;
+ struct cam_isp_ctx_req *req_isp = NULL;
+
+ if (ctx_isp->frame_id == 1) {
CAM_DBG(CAM_ISP, "Reg update for early PCR");
- else
+ if (!list_empty(&ctx->active_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ } else if (!list_empty(&ctx->wait_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ }
+ } else {
+ if (!list_empty(&ctx->wait_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ }
CAM_WARN(CAM_ISP,
"Unexpected reg update in activated substate:%d for frame_id:%lld",
ctx_isp->substate_activated, ctx_isp->frame_id);
+ }
+
+ if (req_isp && req_isp->hw_update_data.fps) {
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+ CAM_DBG(CAM_ISP, "req_isp %pK, Upadting ctx_isp->fps %d",
+ req_isp, ctx_isp->fps);
+ }
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
return 0;
}
@@ -599,7 +721,8 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
int rc = 0;
struct cam_ctx_request *req;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
if (list_empty(&ctx->wait_req_list)) {
CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
@@ -624,13 +747,22 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
/*
* This function only called directly from applied and bubble applied
* state so change substate here.
*/
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
end:
return rc;
}
@@ -658,6 +790,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u",
@@ -665,9 +798,12 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
}
list_for_each_entry(req, &ctx->active_req_list, list) {
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id >
+ ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
break;
}
}
@@ -675,6 +811,17 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
request_id = 0;
+ if (request_id && ctx_isp->req_info.reported_req_id &&
+ ((request_id - ctx_isp->req_info.reported_req_id) >
+ 1)){
+ CAM_INFO(CAM_ISP,
+ "ctx:%d curr req id: %lld last reported id:%lld",
+ ctx->ctx_id, request_id,
+ ctx_isp->req_info.reported_req_id);
+
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
+ }
+
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
} else {
@@ -742,8 +889,15 @@ static int __cam_isp_ctx_sof_in_activated_state(
ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
@@ -755,8 +909,9 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
{
int rc = 0;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
CAM_DBG(CAM_ISP, "invalid RUP");
@@ -778,11 +933,17 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
CAM_ERR(CAM_ISP,
"receive rup in unexpected state");
}
- if (req != NULL) {
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
- req->request_id);
- }
+
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
end:
return rc;
}
@@ -791,16 +952,18 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
void *evt_data)
{
struct cam_ctx_request *req;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
uint64_t request_id = 0;
+ struct cam_isp_hw_epoch_event_data *epoch_hw_event_data = evt_data;
if (list_empty(&ctx->wait_req_list)) {
/*
* If no wait req in epoch, this is an error case.
* The recovery is to go back to sof state
*/
- CAM_ERR(CAM_ISP, "No wait request");
+ CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/* Send SOF event as empty frame*/
@@ -815,7 +978,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true;
- CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
+ CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
+ ctx->ctx_id, req_isp->bubble_report, req->request_id);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
@@ -842,9 +1007,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->active_req_list);
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id > ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
}
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR);
@@ -853,15 +1020,16 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated);
end:
- if (request_id == 0) {
- req = list_last_entry(&ctx->active_req_list,
- struct cam_ctx_request, list);
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
- } else {
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
- }
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps =
+ epoch_hw_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((epoch_hw_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = epoch_hw_event_data->irq_mono_boot_time;
+
return 0;
}
@@ -884,7 +1052,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
int rc = 0;
struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
- struct cam_ctx_request *req;
if (!evt_data) {
CAM_ERR(CAM_ISP, "in valid sof event data");
@@ -895,17 +1062,19 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+
if (list_empty(&ctx->active_req_list))
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
else
CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
- req = list_last_entry(&ctx->active_req_list,
- struct cam_ctx_request, list);
- if (req)
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
- ctx->req_list->request_id);
CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated);
@@ -952,7 +1121,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
* If no pending req in epoch, this is an error case.
* Just go back to the bubble state.
*/
- CAM_ERR(CAM_ISP, "No pending request.");
+ CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -964,6 +1134,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true;
+ CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
+ ctx->ctx_id, req_isp->bubble_report, req->request_id);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
@@ -992,9 +1165,11 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
list_add_tail(&req->list, &ctx->active_req_list);
if (!req_isp->bubble_report) {
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id > ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR);
} else
@@ -1007,11 +1182,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
end:
- req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
- list);
- if (req)
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
+
return 0;
}
@@ -1023,9 +1194,7 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied(
(struct cam_isp_hw_done_event_data *) evt_data;
rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
- ctx_isp->base->req_list->request_id);
+
return rc;
}
@@ -1083,9 +1252,6 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
if (error_event_data->enable_reg_dump)
cam_isp_ctx_dump_req(req_isp);
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req_to_dump->request_id);
-
list_for_each_entry_safe(req, req_temp,
&ctx->active_req_list, list) {
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
@@ -1176,14 +1342,15 @@ move_to_pending:
end:
do {
if (list_empty(&ctx->pending_req_list)) {
- error_request_id = ctx_isp->last_applied_req_id + 1;
+ error_request_id =
+ ctx_isp->req_info.last_applied_req_id + 1;
req_isp = NULL;
break;
}
req = list_first_entry(&ctx->pending_req_list,
struct cam_ctx_request, list);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
- error_request_id = ctx_isp->last_applied_req_id;
+ error_request_id = ctx_isp->req_info.last_applied_req_id;
if (req_isp->bubble_report) {
req_to_report = req;
@@ -1201,7 +1368,8 @@ end:
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_req_list);
- } while (req->request_id < ctx_isp->last_applied_req_id);
+ } while (req->request_id <
+ ctx_isp->req_info.last_applied_req_id);
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
notify.link_hdl = ctx->link_hdl;
@@ -1240,8 +1408,8 @@ end:
V4L_EVENT_CAM_REQ_MGR_EVENT))
CAM_ERR(CAM_ISP,
"Error in notifying the error time for req id:%lld ctx %u",
- ctx_isp->last_applied_req_id,
- ctx->ctx_id);
+ ctx_isp->req_info.last_applied_req_id,
+ ctx->ctx_id);
}
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR;
} else {
@@ -1278,8 +1446,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
+
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
@@ -1293,6 +1460,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
@@ -1300,9 +1468,12 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
}
list_for_each_entry(req, &ctx->active_req_list, list) {
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id >
+ ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
break;
}
}
@@ -1343,8 +1514,10 @@ static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp,
CAM_DBG(CAM_ISP, "No request, move to SOF");
ctx_isp->substate_activated =
CAM_ISP_CTX_ACTIVATED_SOF;
- if (ctx_isp->reported_req_id < curr_req_id) {
- ctx_isp->reported_req_id = curr_req_id;
+ if (ctx_isp->req_info.reported_req_id < curr_req_id) {
+ ctx_isp->req_info.reported_req_id = curr_req_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
__cam_isp_ctx_send_sof_timestamp(ctx_isp,
curr_req_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -1379,7 +1552,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
{
int rc = 0;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
@@ -1402,11 +1575,10 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
CAM_ERR(CAM_ISP,
"receive rup in unexpected state");
}
- if (req != NULL) {
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
- req->request_id);
- }
+
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
end:
return rc;
}
@@ -1417,7 +1589,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
int rc = 0;
struct cam_ctx_request *req = NULL;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_req_mgr_trigger_notify notify;
uint64_t request_id = 0;
@@ -1440,6 +1612,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
list_add_tail(&req->list, &ctx->free_req_list);
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
/*
* This function only called directly from applied and bubble applied
* state so change substate here.
@@ -1451,9 +1626,12 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
ctx_isp->active_req_cnt <= 2) {
list_for_each_entry(req, &ctx->active_req_list, list) {
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id >
+ ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
break;
}
}
@@ -1466,6 +1644,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
@@ -1478,11 +1657,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
end:
- if (req != NULL && !rc) {
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH,
- req->request_id);
- }
+
return rc;
}
@@ -1729,19 +1904,19 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
} else {
spin_lock_bh(&ctx->lock);
ctx_isp->substate_activated = next_state;
- ctx_isp->last_applied_req_id = apply->request_id;
+ ctx_isp->req_info.last_applied_req_id =
+ apply->request_id;
+ ctx_isp->req_info.last_applied_time_stamp =
+ jiffies_to_msecs(jiffies);
list_del_init(&req->list);
list_add_tail(&req->list, &ctx->wait_req_list);
CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld",
- next_state, ctx_isp->last_applied_req_id);
+ next_state,
+ ctx_isp->req_info.last_applied_req_id);
spin_unlock_bh(&ctx->lock);
}
end:
- if (ctx_isp != NULL) {
- __cam_isp_ctx_update_state_monitor_array(ctx_isp,
- CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
- ctx->req_list->request_id);
- }
+
return rc;
}
@@ -1863,21 +2038,92 @@ static int __cam_isp_ctx_flush_req_in_top_state(
struct cam_req_mgr_flush_request *flush_req)
{
int rc = 0;
- struct cam_isp_context *ctx_isp;
-
- ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
+ struct cam_isp_context *ctx_isp =
+ (struct cam_isp_context *) ctx->ctx_priv;
+ struct cam_isp_stop_args stop_isp;
+ struct cam_hw_stop_args stop_args;
+ struct cam_isp_start_args start_isp;
+ struct cam_hw_reset_args reset_args;
if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
- CAM_INFO(CAM_ISP, "Last request id to flush is %lld",
- flush_req->req_id);
+ CAM_INFO(CAM_ISP, "ctx id:%d Last request id to flush is %lld",
+ ctx->ctx_id, flush_req->req_id);
ctx->last_flush_req = flush_req->req_id;
}
- CAM_DBG(CAM_ISP, "try to flush pending list");
+ CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list", ctx->ctx_id);
spin_lock_bh(&ctx->lock);
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
+
+ if (!list_empty(&ctx->active_req_list)) {
+ CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
+ "ctx:%d last applied id:%lld, reported req id:%lld, buf done id:%lld",
+ ctx->ctx_id,
+ ctx_isp->req_info.last_applied_req_id,
+ ctx_isp->req_info.reported_req_id,
+ ctx_isp->req_info.last_bufdone_req_id);
+ CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
+ "current time:%u last apply time:%lld, reported req time:%lld, buf done time:%lld",
+ jiffies_to_msecs(jiffies),
+ ctx_isp->req_info.last_applied_time_stamp,
+ ctx_isp->req_info.last_reported_id_time_stamp,
+ ctx_isp->req_info.last_bufdone_time_stamp);
+
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
+ }
spin_unlock_bh(&ctx->lock);
atomic_set(&ctx_isp->process_bubble, 0);
+ if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
+ /* if active and wait list are empty, return */
+ spin_lock_bh(&ctx->lock);
+ if ((list_empty(&ctx->wait_req_list)) &&
+ (list_empty(&ctx->active_req_list))) {
+ spin_unlock_bh(&ctx->lock);
+ CAM_DBG(CAM_ISP, "ctx id:%d active,wait list are empty",
+ ctx->ctx_id);
+ goto end;
+ }
+ spin_unlock_bh(&ctx->lock);
+
+ /* Stop hw first before active list flush */
+ CAM_DBG(CAM_ISP, "ctx id:%d try to stop hw", ctx->ctx_id);
+ stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY;
+ stop_isp.stop_only = true;
+ stop_args.args = (void *)&stop_isp;
+ ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
+ &stop_args);
+
+ spin_lock_bh(&ctx->lock);
+ CAM_DBG(CAM_ISP, "try to flush wait list");
+ rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,
+ flush_req);
+ CAM_DBG(CAM_ISP, "try to flush active list");
+ rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
+ flush_req);
+ ctx_isp->active_req_cnt = 0;
+ spin_unlock_bh(&ctx->lock);
+
+ CAM_DBG(CAM_ISP, "try to reset hw");
+ /* Reset hw */
+ reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv,
+ &reset_args);
+ if (rc)
+ goto end;
+
+ CAM_DBG(CAM_ISP, "ctx id%d try to start hw", ctx->ctx_id);
+ /* Start hw */
+ start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ start_isp.start_only = true;
+ start_isp.hw_config.priv = NULL;
+
+ rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
+ &start_isp);
+ }
+
+end:
+ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
return rc;
}
@@ -2041,6 +2287,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
@@ -2133,8 +2380,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true;
+ CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
+ ctx->ctx_id, req_isp->bubble_report, req->request_id);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
- CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
@@ -2161,9 +2410,11 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
req->request_id, ctx_isp->active_req_cnt);
if (!req_isp->bubble_report) {
- if (req->request_id > ctx_isp->reported_req_id) {
+ if (req->request_id > ctx_isp->req_info.reported_req_id) {
request_id = req->request_id;
- ctx_isp->reported_req_id = request_id;
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR);
} else
@@ -2228,6 +2479,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
@@ -2257,7 +2509,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
{
struct cam_ctx_request *req;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_req_mgr_trigger_notify notify;
uint64_t request_id = 0;
@@ -2298,6 +2550,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
notify.dev_hdl = ctx->dev_hdl;
notify.frame_id = ctx_isp->frame_id;
notify.trigger = CAM_TRIGGER_POINT_SOF;
+ notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
ctx->ctx_crm_intf->notify_trigger(&notify);
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld",
@@ -2305,8 +2558,14 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
} else {
CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
}
- if (request_id)
- ctx_isp->reported_req_id = request_id;
+ if (request_id) {
+ ctx_isp->req_info.reported_req_id = request_id;
+ ctx_isp->req_info.last_reported_id_time_stamp =
+ jiffies_to_msecs(jiffies);
+ }
+
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -2481,9 +2740,14 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
ctx->last_flush_req = 0;
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
- ctx_isp->reported_req_id = 0;
ctx_isp->hw_acquired = false;
ctx_isp->init_received = false;
+ ctx_isp->req_info.reported_req_id = 0;
+ ctx_isp->req_info.last_applied_req_id = 0;
+ ctx_isp->req_info.last_bufdone_req_id = 0;
+ ctx_isp->req_info.last_applied_time_stamp = 0;
+ ctx_isp->req_info.last_bufdone_time_stamp = 0;
+ ctx_isp->req_info.last_reported_id_time_stamp = 0;
/*
* Ideally, we should never have any active request here.
@@ -2538,11 +2802,16 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
ctx->last_flush_req = 0;
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
- 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;
+ ctx_isp->req_info.reported_req_id = 0;
+ ctx_isp->req_info.last_applied_req_id = 0;
+ ctx_isp->req_info.last_bufdone_req_id = 0;
+ ctx_isp->req_info.last_applied_time_stamp = 0;
+ ctx_isp->req_info.last_bufdone_time_stamp = 0;
+ ctx_isp->req_info.last_reported_id_time_stamp = 0;
/*
* Ideally, we should never have any active request here.
@@ -2573,7 +2842,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
{
int rc = 0, i;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
uintptr_t packet_addr;
struct cam_packet *packet;
size_t len = 0;
@@ -2662,6 +2931,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
rc = -EFAULT;
goto free_cpu_buf;
}
+
req_isp->num_cfg = cfg.num_hw_update_entries;
req_isp->num_fence_map_out = cfg.num_out_map_entries;
req_isp->num_fence_map_in = cfg.num_in_map_entries;
@@ -2718,6 +2988,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
}
}
+
if (rc)
goto put_ref;
@@ -3169,7 +3440,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
atomic_set(&ctx_isp->process_bubble, 0);
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
- ctx_isp->reported_req_id = 0;
+ ctx_isp->req_info.reported_req_id = 0;
ctx_isp->substate_activated = ctx_isp->rdi_only_context ?
CAM_ISP_CTX_ACTIVATED_APPLIED :
(req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH :
@@ -3301,7 +3572,15 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
}
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
- ctx_isp->reported_req_id = 0;
+ ctx_isp->req_info.reported_req_id = 0;
+ ctx_isp->req_info.last_applied_req_id = 0;
+ ctx_isp->req_info.last_bufdone_req_id = 0;
+ ctx_isp->req_info.last_applied_time_stamp = 0;
+ ctx_isp->req_info.last_bufdone_time_stamp = 0;
+ ctx_isp->req_info.last_reported_id_time_stamp = 0;
+ ctx_isp->prev_sof_timestamp_val = 0;
+ ctx_isp->prev_boot_timestamp = 0;
+
atomic_set(&ctx_isp->process_bubble, 0);
CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u",
@@ -3478,8 +3757,9 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
rc = ctx_ops->crm_ops.apply_req(ctx, apply);
} else {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "No handle function in activated substate %d",
- ctx_isp->substate_activated);
+ "Ctx:%d No handle function in activated substate %d",
+ ctx->ctx_id, ctx_isp->substate_activated);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
rc = -EFAULT;
}
@@ -3490,8 +3770,6 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
return rc;
}
-
-
static int __cam_isp_ctx_handle_irq_in_activated(void *context,
uint32_t evt_id, void *evt_data)
{
@@ -3500,22 +3778,27 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
struct cam_context *ctx = (struct cam_context *)context;
struct cam_isp_context *ctx_isp =
(struct cam_isp_context *)ctx->ctx_priv;
+ enum cam_isp_ctx_activated_substate curr_state;
spin_lock(&ctx->lock);
trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
__cam_isp_ctx_get_event_ts(evt_id, evt_data));
+ curr_state = ctx_isp->substate_activated;
CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
ctx->state, ctx_isp->substate_activated, evt_id);
irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
if (irq_ops->irq_ops[evt_id]) {
rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
} else {
- CAM_DBG(CAM_ISP, "No handle function for substate %d",
- ctx_isp->substate_activated);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp);
+ CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d",
+ ctx->ctx_id, ctx_isp->substate_activated);
+ __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
}
+ if (evt_id != CAM_ISP_HW_EVENT_DONE)
+ __cam_isp_ctx_update_state_monitor_array(ctx_isp, evt_id,
+ curr_state, ctx_isp->substate_activated);
CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
ctx->state, ctx_isp->substate_activated);
@@ -3677,7 +3960,13 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
ctx->base = ctx_base;
ctx->frame_id = 0;
ctx->active_req_cnt = 0;
- ctx->reported_req_id = 0;
+ ctx->req_info.reported_req_id = 0;
+ ctx->req_info.last_applied_req_id = 0;
+ ctx->req_info.last_bufdone_req_id = 0;
+ ctx->req_info.last_applied_time_stamp = 0;
+ ctx->req_info.last_bufdone_time_stamp = 0;
+ ctx->req_info.last_reported_id_time_stamp = 0;
+
ctx->hw_ctx = NULL;
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
ctx->substate_machine = cam_isp_ctx_activated_state_machine;
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h
index 4954f2034144..cb73252363db 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h
@@ -35,6 +35,11 @@
#define CAM_ISP_CTX_CFG_MAX 22
/*
+ * Defalut fps value set to 30
+ */
+#define CAM_ISP_CTX_DEFAULT_FPS 30
+
+/*
* Maximum entries in state monitoring array for error logging
*/
#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 20
@@ -62,20 +67,6 @@ enum cam_isp_ctx_activated_substate {
};
/**
- * enum cam_isp_state_change_trigger - Different types of ISP events
- *
- */
-enum cam_isp_state_change_trigger {
- CAM_ISP_STATE_CHANGE_TRIGGER_ERROR,
- CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
- CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
- CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH,
- CAM_ISP_STATE_CHANGE_TRIGGER_EOF,
- CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
- CAM_ISP_STATE_CHANGE_TRIGGER_MAX
-};
-
-/**
* struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks
*
* @irq_ops: Array of handle function pointers.
@@ -125,20 +116,47 @@ struct cam_isp_ctx_req {
* debug purposes
*
*@curr_state: Current sub state that received req
- *@req_type: Event type of incoming req
- *@req_id: Request id
- *@evt_time_stamp Current time stamp
+ *@next_state: Next sub state that received req
+ *@hw_event: Hw Event type of incoming req
+ *@last_reported_id: Last_reported_id to userspace
+ *@last_applied_req_id Last applied request id to hardware
+ *@frame_id: Current Frame id
+ *@evt_time_stamp Current time stamp of this event logged
*
*/
struct cam_isp_context_state_monitor {
enum cam_isp_ctx_activated_substate curr_state;
- enum cam_isp_state_change_trigger trigger;
- uint32_t req_id;
+ enum cam_isp_ctx_activated_substate next_state;
+ enum cam_isp_hw_event_type hw_event;
+ int64_t last_reported_id;
+ int64_t last_applied_req_id;
int64_t frame_id;
uint64_t evt_time_stamp;
};
/**
+ * struct cam_isp_context_req_id_info - ISP context request id
+ * information for last applied, reported and bufdone.
+ *
+ *@last_applied_req_id: Last applied request id
+ *@last_bufdone_req_id: Last bufdone request id
+ *@reported_req_id: Last reported request id to userspace
+ *@last_applied_time_stamp: Last applied request time stamp information
+ *@last_bufdone_time_stamp Last bufdone request time stamp information
+ *@last_reported_id_time_stamp: Last reported request time stamp information
+ *
+ */
+
+struct cam_isp_context_req_id_info {
+ int64_t last_applied_req_id;
+ int64_t last_bufdone_req_id;
+ int64_t reported_req_id;
+ int64_t last_applied_time_stamp;
+ int64_t last_bufdone_time_stamp;
+ int64_t last_reported_id_time_stamp;
+
+};
+/**
* struct cam_isp_context - ISP context object
*
* @base: Common context object pointer
@@ -152,19 +170,24 @@ struct cam_isp_context_state_monitor {
* @req_isp: ISP private request object storage
* @hw_ctx: HW object returned by the acquire device command
* @sof_timestamp_val: Captured time stamp value at sof hw event
+ * @prev_sof_timestamp_val Holds last notified sof time stamp
* @boot_timestamp: Boot time stamp for a given req_id
+ * @prev_boot_timestamp Holds last notified boot time stamp
* @active_req_cnt: Counter for the active request
- * @reported_req_id: Last reported request id
* @subscribe_event: The irq event mask that CRM subscribes to, IFE
* will invoke CRM cb at those event.
- * @last_applied_req_id: Last applied request id
* @state_monitor_head: Write index to the state monitoring array
+ * @req_info Request id information about last applied,
+ * reported and buf done
* @cam_isp_ctx_state_monitor: State monitoring array
* @rdi_only_context: Get context type information.
* true, if context is rdi only context
* @hw_acquired: Indicate whether HW resources are acquired
* @init_received: Indicate whether init config packet is received
* @split_acquire: Indicate whether a separate acquire is expected
+ * @irq_delay_detect: Indicate whether a irq delay has detected or not
+ * @irq_timestamps: Timestamp from last handled IRQ
+ * @fps: Current FPS for the activated state.
*
*/
struct cam_isp_context {
@@ -181,18 +204,22 @@ struct cam_isp_context {
void *hw_ctx;
uint64_t sof_timestamp_val;
+ uint64_t prev_sof_timestamp_val;
uint64_t boot_timestamp;
+ uint64_t prev_boot_timestamp;
int32_t active_req_cnt;
- int64_t reported_req_id;
uint32_t subscribe_event;
- int64_t last_applied_req_id;
atomic64_t state_monitor_head;
struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
+ struct cam_isp_context_req_id_info req_info;
bool rdi_only_context;
bool hw_acquired;
bool init_received;
bool split_acquire;
+ bool irq_delay_detect;
+ uint64_t irq_timestamps;
+ uint32_t fps;
};
/**
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 fe3d2f12a6e2..91e1e74f7360 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
@@ -146,6 +146,74 @@ static int cam_ife_hw_mgr_is_rdi_res(uint32_t res_id)
return rc;
}
+static const char *cam_ife_hw_mgr_get_res_id(
+ enum cam_ife_pix_path_res_id csid_res_id)
+{
+ char *res_name = NULL;
+
+ switch (csid_res_id) {
+ case CAM_IFE_PIX_PATH_RES_RDI_0:
+ res_name = "RDI_0";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_1:
+ res_name = "RDI_1";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_2:
+ res_name = "RDI_2";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_3:
+ res_name = "RDI_3";
+ break;
+ case CAM_IFE_PIX_PATH_RES_IPP:
+ res_name = "IPP";
+ break;
+ case CAM_IFE_PIX_PATH_RES_PPP:
+ res_name = "PPP";
+ break;
+ case CAM_IFE_PIX_PATH_RES_MAX:
+ res_name = "Invalid Max res";
+ break;
+ default:
+ res_name = "Invalid";
+ break;
+ }
+ return res_name;
+}
+
+static const char *cam_ife_hw_mgr_get_res_type(
+ enum cam_isp_resource_type csid_res_type)
+{
+ char *res_type = NULL;
+
+ switch (csid_res_type) {
+ case CAM_ISP_RESOURCE_UNINT:
+ res_type = "Unint";
+ break;
+ case CAM_ISP_RESOURCE_SRC:
+ res_type = "Src";
+ break;
+ case CAM_ISP_RESOURCE_CID:
+ res_type = "Cid";
+ break;
+ case CAM_ISP_RESOURCE_PIX_PATH:
+ res_type = "Pix Path";
+ break;
+ case CAM_ISP_RESOURCE_VFE_IN:
+ res_type = "Vfe In";
+ break;
+ case CAM_ISP_RESOURCE_VFE_OUT:
+ res_type = "Vfe Out";
+ break;
+ case CAM_ISP_RESOURCE_MAX:
+ res_type = "Invalid Max res";
+ break;
+ default:
+ res_type = "Invalid";
+ break;
+ }
+ return res_type;
+}
+
static int cam_ife_hw_mgr_reset_csid_res(
struct cam_ife_hw_mgr_res *isp_hw_res)
{
@@ -599,6 +667,61 @@ static int cam_ife_hw_mgr_get_ctx(
return rc;
}
+static void cam_ife_hw_mgr_dump_all_ctx(
+ struct cam_ife_hw_mgr_ctx *ife_ctx)
+{
+ uint32_t i;
+ struct cam_ife_hw_mgr_ctx *ctx;
+ struct cam_ife_hw_mgr_res *hw_mgr;
+
+ mutex_lock(&g_ife_hw_mgr.ctx_mutex);
+ list_for_each_entry(ctx, &g_ife_hw_mgr.used_ctx_list, list) {
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d",
+ ctx->ctx_index,
+ ctx->res_list_ife_in.is_dual_vfe,
+ ctx->res_list_ife_in.res_id,
+ ctx->num_base, ctx->is_rdi_only_context);
+ list_for_each_entry(hw_mgr, &ctx->res_list_ife_csid,
+ list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr->hw_res[i])
+ continue;
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "csid:%d res_type:%s id:%s state:%d",
+ hw_mgr->hw_res[i]->hw_intf->hw_idx,
+ cam_ife_hw_mgr_get_res_type(
+ hw_mgr->hw_res[i]->res_type),
+ cam_ife_hw_mgr_get_res_id(
+ hw_mgr->hw_res[i]->res_id),
+ hw_mgr->hw_res[i]->res_state);
+ }
+ }
+ list_for_each_entry(hw_mgr, &ctx->res_list_ife_src,
+ list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr->hw_res[i])
+ continue;
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "Src IFE:%d res_type:%s id:%s state:%d",
+ hw_mgr->hw_res[i]->hw_intf->hw_idx,
+ cam_ife_hw_mgr_get_res_type(
+ hw_mgr->hw_res[i]->res_type),
+ cam_ife_hw_mgr_get_res_id(
+ hw_mgr->hw_res[i]->res_id),
+ hw_mgr->hw_res[i]->res_state);
+ }
+ }
+ }
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "Current ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d",
+ ife_ctx->ctx_index,
+ ife_ctx->res_list_ife_in.is_dual_vfe,
+ ife_ctx->res_list_ife_in.res_id,
+ ife_ctx->num_base, ife_ctx->is_rdi_only_context);
+ mutex_unlock(&g_ife_hw_mgr.ctx_mutex);
+}
+
static void cam_ife_mgr_add_base_info(
struct cam_ife_hw_mgr_ctx *ctx,
enum cam_isp_hw_split_id split_id,
@@ -1509,8 +1632,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl(
&csid_acquire, sizeof(csid_acquire));
if (rc) {
CAM_ERR(CAM_ISP,
- "Cannot acquire ife csid pxl path rsrc %s",
- (is_ipp) ? "IPP" : "PPP");
+ "Cannot acquire ife csid pxl path rsrc %s, hw=%d rc=%d",
+ (is_ipp) ? "IPP" : "PPP",
+ hw_intf->hw_idx, rc);
goto put_res;
}
@@ -1622,7 +1746,6 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
"CSID Path reserve failed hw=%d rc=%d cid=%d",
hw_intf->hw_idx, rc,
cid_res->hw_res[0]->res_id);
-
goto put_res;
}
@@ -2018,6 +2141,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
return 0;
free_res:
+ /*Dump all the current acquired resources */
+ cam_ife_hw_mgr_dump_all_ctx(ife_ctx);
cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
free_cdm:
cam_cdm_release(ife_ctx->cdm_handle);
@@ -2172,11 +2297,13 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
ife_ctx->ctx_in_use = 1;
cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->used_ctx_list, &ife_ctx);
-
CAM_DBG(CAM_ISP, "Exit...(success)");
return 0;
+
free_res:
+ /*Dump all the current acquired resources */
+ cam_ife_hw_mgr_dump_all_ctx(ife_ctx);
cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
cam_cdm_release(ife_ctx->cdm_handle);
free_ctx:
@@ -2572,6 +2699,11 @@ static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx)
return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE);
}
+static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
+{
+ return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
+}
+
/* entry function: stop_hw */
static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
{
@@ -2637,7 +2769,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
/* Stop the master CSID path first */
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
- master_base_idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY);
+ master_base_idx, csid_halt_type);
/* stop rest of the CSID paths */
for (i = 0; i < ctx->num_base; i++) {
@@ -2647,7 +2779,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
ctx->base[i].idx, i, master_base_idx);
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
- ctx->base[i].idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY);
+ ctx->base[i].idx, csid_halt_type);
}
CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx);
@@ -2925,6 +3057,9 @@ start_only:
CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d",
ctx->ctx_index);
+ if (start_isp->start_only)
+ cam_ife_mgr_resume_hw(ctx);
+
/* start the IFE out devices */
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
rc = cam_ife_hw_mgr_start_hw_res(
@@ -3025,6 +3160,44 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args)
return -EPERM;
}
+static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args)
+{
+ struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv;
+ struct cam_hw_reset_args *reset_args = hw_reset_args;
+ struct cam_ife_hw_mgr_ctx *ctx;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ uint32_t i;
+ int rc = 0;
+
+ if (!hw_mgr_priv || !hw_reset_args) {
+ CAM_ERR(CAM_ISP, "Invalid arguments");
+ return -EINVAL;
+ }
+
+ ctx = (struct cam_ife_hw_mgr_ctx *)reset_args->ctxt_to_hw_map;
+ if (!ctx || !ctx->ctx_in_use) {
+ CAM_ERR(CAM_ISP, "Invalid context is used");
+ return -EPERM;
+ }
+
+ CAM_DBG(CAM_ISP, "reset csid and vfe hw");
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid,
+ list) {
+ rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "Failed RESET (%d) rc:%d",
+ hw_mgr_res->res_id, rc);
+ goto end;
+ }
+ }
+
+ for (i = 0; i < ctx->num_base; i++)
+ rc = cam_ife_mgr_reset_vfe_hw(hw_mgr, ctx->base[i].idx);
+
+end:
+ return rc;
+}
+
static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
void *release_hw_args)
{
@@ -3152,6 +3325,54 @@ static int cam_isp_blob_fe_update(
return rc;
}
+static int cam_isp_blob_fps_config(
+ uint32_t blob_type,
+ struct cam_isp_generic_blob_info *blob_info,
+ struct cam_fps_config *fps_config,
+ struct cam_hw_prepare_update_args *prepare)
+{
+ struct cam_ife_hw_mgr_ctx *ctx = NULL;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ struct cam_vfe_fps_config_args fps_config_args;
+ int rc = -EINVAL;
+ uint32_t i;
+
+ ctx = prepare->ctxt_to_hw_map;
+
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+
+ if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) {
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf && hw_intf->hw_ops.process_cmd) {
+ fps_config_args.fps =
+ fps_config->fps;
+ fps_config_args.node_res =
+ hw_mgr_res->hw_res[i];
+
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_ISP_HW_CMD_FPS_CONFIG,
+ &fps_config_args,
+ sizeof(
+ struct cam_vfe_fps_config_args)
+ );
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Failed fps config:%d",
+ fps_config->fps);
+ } else
+ CAM_WARN(CAM_ISP, "NULL hw_intf!");
+ }
+ }
+ }
+
+ return rc;
+}
+
static int cam_isp_blob_ubwc_update(
uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info,
@@ -3528,6 +3749,75 @@ static int cam_isp_blob_clock_update(
return rc;
}
+static int cam_isp_blob_sensor_config(
+ uint32_t blob_type,
+ struct cam_isp_generic_blob_info *blob_info,
+ struct cam_isp_sensor_config *dim_config,
+ struct cam_hw_prepare_update_args *prepare)
+{
+ struct cam_ife_hw_mgr_ctx *ctx = NULL;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ struct cam_ife_sensor_dimension_update_args update_args;
+ int rc = -EINVAL, found = 0;
+ uint32_t i, j;
+ struct cam_isp_sensor_dimension *path_config;
+
+ ctx = prepare->ctxt_to_hw_map;
+
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+ found = 1;
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf && hw_intf->hw_ops.process_cmd) {
+ path_config = &(dim_config->ipp_path);
+ update_args.ipp_path.width =
+ path_config->width;
+ update_args.ipp_path.height =
+ path_config->height;
+ update_args.ipp_path.measure_enabled =
+ path_config->measure_enabled;
+ path_config = &(dim_config->ppp_path);
+ update_args.ppp_path.width =
+ path_config->width;
+ update_args.ppp_path.height =
+ path_config->height;
+ update_args.ppp_path.measure_enabled =
+ path_config->measure_enabled;
+ for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) {
+ path_config =
+ &(dim_config->rdi_path[j]);
+ update_args.rdi_path[j].width =
+ path_config->width;
+ update_args.rdi_path[j].height =
+ path_config->height;
+ update_args.rdi_path[j].measure_enabled =
+ path_config->measure_enabled;
+ }
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
+ &update_args,
+ sizeof(
+ struct
+ cam_ife_sensor_dimension_update_args)
+ );
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Dimension Update failed");
+ } else
+ CAM_ERR(CAM_ISP, "hw_intf is NULL");
+ }
+ if (found)
+ break;
+ }
+
+ return rc;
+}
+
+
void fill_res_bitmap(uint32_t resource_type, unsigned long *res_bitmap)
{
@@ -3620,12 +3910,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
return -EINVAL;
}
- if (blob_type >= CAM_ISP_GENERIC_BLOB_TYPE_MAX) {
- CAM_WARN(CAM_ISP, "Invalid Blob Type %d Max %d", blob_type,
- CAM_ISP_GENERIC_BLOB_TYPE_MAX);
- return 0;
- }
-
prepare = blob_info->prepare;
if (!prepare) {
CAM_ERR(CAM_ISP, "Failed. prepare is NULL, blob_type %d",
@@ -3633,7 +3917,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
return -EINVAL;
}
- CAM_DBG(CAM_ISP, "FS2: BLOB Type: %d", blob_type);
switch (blob_type) {
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG: {
struct cam_isp_resource_hfr_config *hfr_config;
@@ -3868,6 +4151,50 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
CAM_ERR(CAM_ISP, "Init Frame drop Update Failed");
}
break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: {
+ struct cam_isp_sensor_config *csid_dim_config;
+
+ if (blob_size < sizeof(struct cam_isp_sensor_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size,
+ sizeof(struct cam_isp_sensor_config));
+ return -EINVAL;
+ }
+
+ csid_dim_config =
+ (struct cam_isp_sensor_config *)blob_data;
+
+ rc = cam_isp_blob_sensor_config(blob_type, blob_info,
+ csid_dim_config, prepare);
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Sensor Dimension Update Failed rc: %d", rc);
+ }
+ break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: {
+ struct cam_fps_config *fps_config;
+ struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+
+ if (blob_size < sizeof(struct cam_fps_config)) {
+ CAM_ERR(CAM_ISP,
+ "Invalid fps blob size %u expected %lu",
+ blob_size, sizeof(struct cam_fps_config));
+ return -EINVAL;
+ }
+
+ fps_config = (struct cam_fps_config *)blob_data;
+ prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
+ prepare->priv;
+
+ prepare_hw_data->fps = fps_config->fps;
+
+ rc = cam_isp_blob_fps_config(blob_type, blob_info,
+ fps_config, prepare);
+ if (rc)
+ CAM_ERR(CAM_ISP, "FPS Update Failed rc: %d", rc);
+
+ }
+ break;
default:
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
break;
@@ -4025,10 +4352,6 @@ end:
return rc;
}
-static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
-{
- return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
-}
static int cam_ife_mgr_sof_irq_debug(
struct cam_ife_hw_mgr_ctx *ctx,
@@ -4097,8 +4420,12 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
for (i = 0; i < packet->num_io_configs; i++) {
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
- if (!io_cfg[i].mem_handle[j])
+ if (!io_cfg[i].mem_handle[j]) {
+ CAM_ERR(CAM_ISP,
+ "Mem Handle %d is NULL for %d io config",
+ j, i);
break;
+ }
if (pf_buf_info &&
GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
@@ -4261,45 +4588,44 @@ static int cam_ife_mgr_cmd_get_sof_timestamp(
struct cam_hw_intf *hw_intf;
struct cam_csid_get_time_stamp_args csid_get_time;
- list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) {
- for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
- if (!hw_mgr_res->hw_res[i])
- continue;
+ hw_mgr_res = list_first_entry(&ife_ctx->res_list_ife_csid,
+ struct cam_ife_hw_mgr_res, list);
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+
+ /*
+ * Get the SOF time stamp from left resource only.
+ * Left resource is master for dual vfe case and
+ * Rdi only context case left resource only hold
+ * the RDI resource
+ */
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf->hw_ops.process_cmd) {
/*
- * Get the SOF time stamp from left resource only.
- * Left resource is master for dual vfe case and
- * Rdi only context case left resource only hold
- * the RDI resource
+ * Single VFE case, Get the time stamp from
+ * available one csid hw in the context
+ * Dual VFE case, get the time stamp from
+ * master(left) would be sufficient
*/
- hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
- if (hw_intf->hw_ops.process_cmd) {
- /*
- * Single VFE case, Get the time stamp from
- * available one csid hw in the context
- * Dual VFE case, get the time stamp from
- * master(left) would be sufficient
- */
-
- csid_get_time.node_res =
- hw_mgr_res->hw_res[i];
- rc = hw_intf->hw_ops.process_cmd(
- hw_intf->hw_priv,
- CAM_IFE_CSID_CMD_GET_TIME_STAMP,
- &csid_get_time,
- sizeof(
- struct cam_csid_get_time_stamp_args));
- if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) {
- *time_stamp =
- csid_get_time.time_stamp_val;
- *boot_time_stamp =
- csid_get_time.boot_timestamp;
- }
+ csid_get_time.node_res =
+ hw_mgr_res->hw_res[i];
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_IFE_CSID_CMD_GET_TIME_STAMP,
+ &csid_get_time,
+ sizeof(
+ struct cam_csid_get_time_stamp_args));
+ if (!rc && (i == CAM_ISP_HW_SPLIT_LEFT)) {
+ *time_stamp =
+ csid_get_time.time_stamp_val;
+ *boot_time_stamp =
+ csid_get_time.boot_timestamp;
}
}
}
-
if (rc)
CAM_ERR(CAM_ISP, "Getting sof time stamp failed");
@@ -4763,6 +5089,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
break;
if (!rup_status) {
+ rup_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_rup_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_REG_UPDATE,
@@ -4792,6 +5120,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
if (!rup_status) {
+ rup_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
/* Send the Reg update hw event */
ife_hwr_irq_rup_cb(
ife_hwr_mgr_ctx->common.cb_priv,
@@ -5151,6 +5481,8 @@ static int cam_ife_hw_mgr_handle_sof(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp,
&sof_done_event_data.boot_time);
+ sof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hw_irq_sof_cb(
ife_hw_mgr_ctx->common.cb_priv,
@@ -5174,6 +5506,8 @@ static int cam_ife_hw_mgr_handle_sof(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp,
&sof_done_event_data.boot_time);
+ sof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hw_irq_sof_cb(
ife_hw_mgr_ctx->common.cb_priv,
@@ -5259,13 +5593,15 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
if (atomic_read(
&ife_hwr_mgr_ctx->overflow_pending))
break;
- if (!eof_status)
+ if (!eof_status) {
+ eof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_eof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF,
&eof_done_event_data);
+ }
}
-
break;
/* Handling dual VFE Scenario */
case 1:
@@ -5306,11 +5642,14 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
- if (!rc)
+ if (!rc) {
+ eof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_eof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF,
&eof_done_event_data);
+ }
break;
@@ -5410,6 +5749,8 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
+ buf_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
/* Report for Successful buf_done event if any */
if (buf_done_event_data.num_handles > 0 &&
ife_hwr_irq_wm_done_cb) {
@@ -5849,6 +6190,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update;
hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
+ hw_mgr_intf->hw_reset = cam_ife_mgr_reset;
if (iommu_hdl)
*iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
index 0b3c3874a704..21f67bac9efe 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
@@ -467,6 +467,7 @@ int cam_isp_add_io_buffers(
int32_t hdl;
int mmu_hdl;
bool mode, is_buf_secure;
+ uint64_t req_id;
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&prepare->packet->payload +
@@ -475,6 +476,7 @@ int cam_isp_add_io_buffers(
num_in_buf = 0;
io_cfg_used_bytes = 0;
prepare->pf_data->packet = prepare->packet;
+ req_id = prepare->packet->header.request_id;
/* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >=
@@ -489,7 +491,7 @@ int cam_isp_add_io_buffers(
CAM_DBG(CAM_ISP, "======= io config idx %d ============", i);
CAM_DBG(CAM_REQ,
"i %d req_id %llu resource_type:%d fence:%d direction %d",
- i, prepare->packet->header.request_id,
+ i, req_id,
io_cfg[i].resource_type, io_cfg[i].fence,
io_cfg[i].direction);
CAM_DBG(CAM_ISP, "format: %d", io_cfg[i].format);
@@ -616,12 +618,37 @@ int cam_isp_add_io_buffers(
mmu_hdl, &io_addr[plane_id], &size);
if (rc) {
CAM_ERR(CAM_ISP,
- "no io addr for plane%d",
- plane_id);
+ "no io addr for plane%d Bufhdl:%d, Size =%d",
+ plane_id,
+ io_cfg[i].mem_handle[plane_id],
+ (int)size);
+ CAM_ERR(CAM_ISP,
+ "Port i %d Reqid %llu res_type:%d fence:%d dir %d",
+ i, req_id,
+ io_cfg[i].resource_type,
+ io_cfg[i].fence,
+ io_cfg[i].direction);
rc = -ENOMEM;
return rc;
}
+ if (j == 0) {
+ rc = cam_packet_validate_plane_size(
+ &io_cfg[i],
+ plane_id,
+ size);
+ if (rc) {
+ CAM_ERR(CAM_ISP,
+ "Invalid buffer size, port 0x%x plane %d req_id %llu format %d memh 0x%x",
+ io_cfg[i].resource_type,
+ plane_id,
+ req_id,
+ io_cfg[i].format,
+ io_cfg[i].mem_handle[plane_id]);
+ return -EINVAL;
+ }
+ }
+
/* need to update with offset */
io_addr[plane_id] +=
io_cfg[i].offsets[plane_id];
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 096e0f186bbf..1ab9361af1d1 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
@@ -130,6 +130,7 @@ struct cam_isp_bw_config_internal {
* @bw_config: BW config information
* @bw_config_valid: Flag indicating whether the bw_config at the index
* is valid or not
+ * @fps: fps vaue which has been updated in hw
*
*/
struct cam_isp_prepare_hw_update_data {
@@ -137,40 +138,47 @@ struct cam_isp_prepare_hw_update_data {
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];
+ uint32_t fps;
};
/**
* struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
*
- * @timestamp: Time stamp for the sof event
- * @boot_time: Boot time stamp for the sof event
+ * @timestamp: Time stamp for the sof event
+ * @boot_time: Boot time stamp for the sof event
+ * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started
*
*/
struct cam_isp_hw_sof_event_data {
uint64_t timestamp;
uint64_t boot_time;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_reg_update_event_data - Event payload for
* CAM_HW_EVENT_REG_UPDATE
*
- * @timestamp: Time stamp for the reg update event
+ * @timestamp: Time stamp for the reg update event
+ * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started
*
*/
struct cam_isp_hw_reg_update_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH
*
- * @timestamp: Time stamp for the epoch event
+ * @timestamp: Time stamp for the epoch event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_epoch_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
@@ -179,6 +187,7 @@ struct cam_isp_hw_epoch_event_data {
* @num_handles: Number of resource handeles
* @resource_handle: Resource handle array
* @timestamp: Timestamp for the buf done event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_done_event_data {
@@ -186,16 +195,19 @@ struct cam_isp_hw_done_event_data {
uint32_t resource_handle[
CAM_NUM_OUT_PER_COMP_IRQ_MAX];
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF
*
* @timestamp: Timestamp for the eof event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_eof_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
index 25bdc51d369f..719bbe7aa941 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
@@ -8,5 +8,6 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/in
ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/camera_v3/cam_req_mgr/
+obj-$(CONFIG_SPECTRA_CAMERA) += cam_csid_ppi_dev.o cam_csid_ppi_core.o cam_csid_ppi170.o
obj-$(CONFIG_SPECTRA_CAMERA) += cam_ife_csid_dev.o cam_ife_csid_soc.o cam_ife_csid_core.o
obj-$(CONFIG_SPECTRA_CAMERA) += cam_ife_csid17x.o cam_ife_csid_lite17x.o
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c
new file mode 100644
index 000000000000..2051292be5be
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c
@@ -0,0 +1,58 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi170.h"
+#include "cam_csid_ppi_dev.h"
+
+#define CAM_PPI_DRV_NAME "ppi_170"
+#define CAM_PPI_VERSION_V170 0x10070000
+
+static struct cam_csid_ppi_hw_info cam_csid_ppi170_hw_info = {
+ .ppi_reg = &cam_csid_ppi_170_reg_offset,
+};
+
+static const struct of_device_id cam_csid_ppi170_dt_match[] = {
+ {
+ .compatible = "qcom,ppi170",
+ .data = &cam_csid_ppi170_hw_info,
+ },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, cam_csid_ppi170_dt_match);
+
+static struct platform_driver cam_csid_ppi170_driver = {
+ .probe = cam_csid_ppi_probe,
+ .remove = cam_csid_ppi_remove,
+ .driver = {
+ .name = CAM_PPI_DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = cam_csid_ppi170_dt_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init cam_csid_ppi170_init_module(void)
+{
+ return platform_driver_register(&cam_csid_ppi170_driver);
+}
+
+static void __exit cam_csid_ppi170_exit_module(void)
+{
+ platform_driver_unregister(&cam_csid_ppi170_driver);
+}
+
+module_init(cam_csid_ppi170_init_module);
+MODULE_DESCRIPTION("CAM CSID_PPI170 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h
new file mode 100644
index 000000000000..0ec767204914
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h
@@ -0,0 +1,32 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_170_H_
+#define _CAM_CSID_PPI_170_H_
+
+#include "cam_csid_ppi_core.h"
+
+static struct cam_csid_ppi_reg_offset cam_csid_ppi_170_reg_offset = {
+ .ppi_hw_version_addr = 0,
+ .ppi_module_cfg_addr = 0x60,
+ .ppi_irq_status_addr = 0x68,
+ .ppi_irq_mask_addr = 0x6c,
+ .ppi_irq_set_addr = 0x70,
+ .ppi_irq_clear_addr = 0x74,
+ .ppi_irq_cmd_addr = 0x78,
+ .ppi_rst_cmd_addr = 0x7c,
+ .ppi_test_bus_ctrl_addr = 0x1f4,
+ .ppi_debug_addr = 0x1f8,
+ .ppi_spare_addr = 0x1fc,
+};
+
+#endif /*_CAM_CSID_PPI_170_H_ */
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c
new file mode 100644
index 000000000000..058a4e955b38
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c
@@ -0,0 +1,404 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <uapi/media/cam_defs.h>
+
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi_dev.h"
+#include "cam_soc_util.h"
+#include "cam_debug_util.h"
+#include "cam_io_util.h"
+
+static int cam_csid_ppi_reset(struct cam_csid_ppi_hw *ppi_hw)
+{
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ int rc = 0;
+
+ uint32_t val = 0;
+ uint32_t clear_mask;
+ uint32_t status;
+
+ soc_info = &ppi_hw->hw_info->soc_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+
+ CAM_DBG(CAM_ISP, "PPI:%d reset", ppi_hw->hw_intf->hw_idx);
+
+ /* Mask all interrupts */
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+
+ /* clear all interrupts */
+ clear_mask = PPI_IRQ_FIFO0_OVERFLOW | PPI_IRQ_FIFO1_OVERFLOW |
+ PPI_IRQ_FIFO2_OVERFLOW;
+ cam_io_w_mb(clear_mask, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+ cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ /* perform the top PPI HW registers reset */
+ cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_rst_cmd_addr);
+
+ rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_status_addr, status,
+ (status & 0x1) == 0x1, 1000, 100000);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d ppi_reset fail rc = %d",
+ ppi_hw->hw_intf->hw_idx, rc);
+ rc = -ETIMEDOUT;
+ }
+ CAM_DBG(CAM_ISP, "PPI: reset status %d", status);
+
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+ if (val != 0)
+ CAM_ERR(CAM_ISP, "PPI:%d IRQ value after reset rc = %d",
+ ppi_hw->hw_intf->hw_idx, val);
+
+ return rc;
+}
+
+static int cam_csid_ppi_enable_hw(struct cam_csid_ppi_hw *ppi_hw)
+{
+ int rc = 0;
+ uint32_t i;
+ uint64_t val;
+
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ struct cam_hw_soc_info *soc_info;
+
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ soc_info = &ppi_hw->hw_info->soc_info;
+
+ CAM_DBG(CAM_ISP, "PPI:%d init PPI HW", ppi_hw->hw_intf->hw_idx);
+
+ for (i = 0; i < soc_info->num_clk; i++) {
+ /* Passing zero in clk_rate results in setting no clk_rate */
+ rc = cam_soc_util_clk_enable(soc_info->clk[i],
+ soc_info->clk_name[i], 0);
+ if (rc)
+ goto clk_disable;
+ }
+
+ rc = cam_soc_util_irq_enable(soc_info);
+ if (rc)
+ goto clk_disable;
+
+ /* Reset PPI */
+ rc = cam_csid_ppi_reset(ppi_hw);
+ if (rc)
+ goto irq_disable;
+
+ /* Clear the RST done IRQ */
+ cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+ cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_hw_version_addr);
+ CAM_DBG(CAM_ISP, "PPI:%d PPI HW version: 0x%x",
+ ppi_hw->hw_intf->hw_idx, val);
+
+ ppi_hw->device_enabled = 1;
+ return 0;
+irq_disable:
+ cam_soc_util_irq_disable(soc_info);
+clk_disable:
+ for (i--; i >= 0; i--) {
+ cam_soc_util_clk_disable(soc_info->clk[i],
+ soc_info->clk_name[i]);
+ }
+ return rc;
+}
+
+static int cam_csid_ppi_disable_hw(struct cam_csid_ppi_hw *ppi_hw)
+{
+ int rc = 0;
+ int i;
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ uint64_t ppi_cfg_val = 0;
+
+ CAM_DBG(CAM_ISP, "PPI:%d De-init PPI HW",
+ ppi_hw->hw_intf->hw_idx);
+
+ soc_info = &ppi_hw->hw_info->soc_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+
+ CAM_DBG(CAM_ISP, "%s:Calling PPI Reset\n", __func__);
+ cam_csid_ppi_reset(ppi_hw);
+ CAM_DBG(CAM_ISP, "%s:PPI Reset Done\n", __func__);
+
+ /* disable the clocks */
+ for (i = 0; i < soc_info->num_clk; i++) {
+ cam_soc_util_clk_disable(soc_info->clk[i],
+ soc_info->clk_name[i]);
+ }
+
+ /* disable the interrupt */
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+ cam_soc_util_irq_disable(soc_info);
+
+ /* disable lanes */
+ for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
+ ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
+
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+
+ ppi_hw->device_enabled = 0;
+
+ return rc;
+}
+
+static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
+ uint32_t arg_size)
+{
+ int i, rc = 0;
+ uint32_t num_lanes;
+ uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0};
+ uint32_t cphy;
+ bool dl0, dl1;
+ uint32_t ppi_cfg_val = 0;
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_info *ppi_hw_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ struct cam_hw_soc_info *soc_info;
+ struct cam_csid_ppi_cfg ppi_cfg;
+
+ if (!hw_priv || !init_args ||
+ (arg_size != sizeof(struct cam_csid_ppi_cfg))) {
+ CAM_ERR(CAM_ISP, "PPI: Invalid args");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ dl0 = dl1 = false;
+ ppi_hw_info = (struct cam_hw_info *)hw_priv;
+ ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ ppi_cfg = *((struct cam_csid_ppi_cfg *)init_args);
+
+ /* Initialize the ppi hardware */
+ rc = cam_csid_ppi_enable_hw(ppi_hw);
+ if (rc)
+ goto end;
+
+ /* Do lane configuration here*/
+ num_lanes = ppi_cfg.lane_num;
+ /* lane_type = 1 refers to cphy */
+ cphy = ppi_cfg.lane_type;
+ CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x",
+ ppi_cfg.lane_cfg, num_lanes, cphy);
+
+ for (i = 0; i < num_lanes; i++) {
+ lanes[i] = ppi_cfg.lane_cfg & (0x3 << (4 * i));
+ (lanes[i] < 2) ? (dl0 = true) : (dl1 = true);
+ CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]);
+ }
+
+ if (num_lanes) {
+ if (cphy) {
+ for (i = 0; i < num_lanes; i++) {
+ /* Select Cphy */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]);
+ /* Enable lane Cphy */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]);
+ }
+ } else {
+ if (dl0)
+ /* Enable lane 0 */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0);
+ if (dl1)
+ /* Enable lane 1 */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1);
+ }
+ } else {
+ CAM_ERR(CAM_ISP,
+ "Number of lanes to enable is cannot be zero");
+ rc = -1;
+ goto end;
+ }
+
+ CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val);
+ soc_info = &ppi_hw->hw_info->soc_info;
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+end:
+ return rc;
+}
+
+static int cam_csid_ppi_deinit_hw(void *hw_priv, void *deinit_args,
+ uint32_t arg_size)
+{
+ int rc = 0;
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_info *ppi_hw_info;
+
+ CAM_DBG(CAM_ISP, "Enter");
+
+ if (!hw_priv) {
+ CAM_ERR(CAM_ISP, "PPI:Invalid arguments");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ ppi_hw_info = (struct cam_hw_info *)hw_priv;
+ ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
+
+ CAM_DBG(CAM_ISP, "Disabling PPI Hw\n");
+ rc = cam_csid_ppi_disable_hw(ppi_hw);
+ if (rc < 0)
+ CAM_DBG(CAM_ISP, "%s: Exit with %d\n", __func__, rc);
+end:
+ return rc;
+}
+
+int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
+ uint32_t ppi_idx)
+{
+ int rc = -EINVAL;
+ struct cam_hw_info *ppi_hw_info;
+ struct cam_csid_ppi_hw *csid_ppi_hw = NULL;
+
+ if (ppi_idx >= CAM_CSID_PPI_HW_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid ppi index:%d", ppi_idx);
+ goto err;
+ }
+
+ ppi_hw_info = (struct cam_hw_info *) ppi_hw_intf->hw_priv;
+ csid_ppi_hw = (struct cam_csid_ppi_hw *) ppi_hw_info->core_info;
+
+ csid_ppi_hw->hw_intf = ppi_hw_intf;
+ csid_ppi_hw->hw_info = ppi_hw_info;
+
+ CAM_DBG(CAM_ISP, "type %d index %d",
+ csid_ppi_hw->hw_intf->hw_type, ppi_idx);
+
+ rc = cam_csid_ppi_init_soc_resources(&csid_ppi_hw->hw_info->soc_info,
+ cam_csid_ppi_irq, csid_ppi_hw);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d Failed to init_soc", ppi_idx);
+ goto err;
+ }
+
+ csid_ppi_hw->hw_intf->hw_ops.init = cam_csid_ppi_init_hw;
+ csid_ppi_hw->hw_intf->hw_ops.deinit = cam_csid_ppi_deinit_hw;
+ return 0;
+err:
+ return rc;
+}
+
+int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
+ irq_handler_t ppi_irq_handler, void *irq_data)
+{
+ int rc = 0;
+
+ rc = cam_soc_util_get_dt_properties(soc_info);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "PPI: Failed to get dt properties");
+ goto end;
+ }
+
+ rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler,
+ irq_data);
+ if (rc) {
+ CAM_ERR(CAM_ISP,
+ "PPI: Error Request platform resources failed rc=%d",
+ rc);
+ goto err;
+ }
+end:
+ return rc;
+err:
+ cam_soc_util_release_platform_resource(soc_info);
+ return rc;
+}
+
+irqreturn_t cam_csid_ppi_irq(int irq_num, void *data)
+{
+ uint32_t irq_status = 0;
+ uint32_t i, ppi_cfg_val = 0;
+ bool fatal_err_detected = false;
+
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+
+ if (!data) {
+ CAM_ERR(CAM_ISP, "PPI: Invalid arguments");
+ return IRQ_HANDLED;
+ }
+
+ ppi_hw = (struct cam_csid_ppi_hw *)data;
+ CAM_DBG(CAM_ISP, "PPI %d IRQ Handling", ppi_hw->hw_intf->hw_idx);
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ soc_info = &ppi_hw->hw_info->soc_info;
+
+ /* read */
+ irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_status_addr);
+
+ /* clear */
+ cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+
+ cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ CAM_DBG(CAM_ISP, "PPI %d irq status 0x%x", ppi_hw->hw_intf->hw_idx,
+ irq_status);
+
+ if (ppi_hw->device_enabled == 1) {
+ if (irq_status & PPI_IRQ_RST_DONE) {
+ CAM_DBG(CAM_ISP, "PPI Reset Done");
+ goto ret;
+ }
+ if ((irq_status & PPI_IRQ_FIFO0_OVERFLOW) ||
+ (irq_status & PPI_IRQ_FIFO1_OVERFLOW) ||
+ (irq_status & PPI_IRQ_FIFO2_OVERFLOW)) {
+ fatal_err_detected = true;
+ goto handle_fatal_error;
+ }
+ }
+
+handle_fatal_error:
+ if (fatal_err_detected) {
+ CAM_ERR(CAM_ISP, "PPI: %d irq_status:0x%x",
+ ppi_hw->hw_intf->hw_idx, irq_status);
+ /* disable lanes */
+ for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
+ ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
+
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+ }
+ret:
+ CAM_DBG(CAM_ISP, "IRQ Handling exit");
+ return IRQ_HANDLED;
+}
+
+int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw)
+{
+ if (!csid_ppi_hw) {
+ CAM_ERR(CAM_ISP, "Invalid param");
+ return -EINVAL;
+ }
+ /* release the privdate data memory from resources */
+ return cam_soc_util_release_platform_resource(
+ &csid_ppi_hw->hw_info->soc_info);
+}
+
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h
new file mode 100644
index 000000000000..058c2421b6da
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_HW_H_
+#define _CAM_CSID_PPI_HW_H_
+
+#include "cam_hw.h"
+#include "cam_hw_intf.h"
+
+#define CAM_CSID_PPI_HW_MAX 4
+#define CAM_CSID_PPI_LANES_MAX 3
+
+#define PPI_IRQ_RST_DONE BIT(0)
+#define PPI_IRQ_FIFO0_OVERFLOW BIT(1)
+#define PPI_IRQ_FIFO1_OVERFLOW BIT(2)
+#define PPI_IRQ_FIFO2_OVERFLOW BIT(3)
+
+#define PPI_IRQ_CMD_SET BIT(0)
+
+#define PPI_IRQ_CMD_CLEAR BIT(0)
+
+#define PPI_RST_CONTROL BIT(0)
+/*
+ * Select the PHY (CPHY set '1' or DPHY set '0')
+ */
+#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0)
+
+#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X)
+
+struct cam_csid_ppi_reg_offset {
+ uint32_t ppi_hw_version_addr;
+ uint32_t ppi_module_cfg_addr;
+
+ uint32_t ppi_irq_status_addr;
+ uint32_t ppi_irq_mask_addr;
+ uint32_t ppi_irq_set_addr;
+ uint32_t ppi_irq_clear_addr;
+ uint32_t ppi_irq_cmd_addr;
+ uint32_t ppi_rst_cmd_addr;
+ uint32_t ppi_test_bus_ctrl_addr;
+ uint32_t ppi_debug_addr;
+ uint32_t ppi_spare_addr;
+};
+
+/**
+ * struct cam_csid_ppi_hw_info- ppi HW info
+ *
+ * @ppi_reg: ppi register offsets
+ *
+ */
+struct cam_csid_ppi_hw_info {
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+};
+
+/**
+ * struct cam_csid_ppi_hw- ppi hw device resources data
+ *
+ * @hw_intf: contain the ppi hw interface information
+ * @hw_info: ppi hw device information
+ * @ppi_info: ppi hw specific information
+ * @device_enabled Device enabled will set once ppi powered on and
+ * initial configuration are done.
+ * @lock_state ppi spin lock
+ *
+ */
+struct cam_csid_ppi_hw {
+ struct cam_hw_intf *hw_intf;
+ struct cam_hw_info *hw_info;
+ struct cam_csid_ppi_hw_info *ppi_info;
+ uint32_t device_enabled;
+};
+
+/**
+ * struct cam_csid_ppi_cfg - ppi lane configuration data
+ * @lane_type: lane type: c-phy or d-phy
+ * @lane_num : active lane number
+ * @lane_cfg: lane configurations: 4 bits per lane
+ *
+ */
+struct cam_csid_ppi_cfg {
+ uint32_t lane_type;
+ uint32_t lane_num;
+ uint32_t lane_cfg;
+};
+
+int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
+ uint32_t ppi_idx);
+int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw);
+int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
+ irq_handler_t ppi_irq_handler, void *irq_data);
+int cam_csid_ppi_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
+int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
+ uint32_t hw_idx);
+#endif /* _CAM_CSID_PPI_HW_H_ */
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c
new file mode 100644
index 000000000000..1a4e14525bc3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c
@@ -0,0 +1,147 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+
+#include "cam_isp_hw.h"
+#include "cam_hw_intf.h"
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi_dev.h"
+#include "cam_debug_util.h"
+
+static struct cam_hw_intf *cam_csid_ppi_hw_list[CAM_CSID_PPI_HW_MAX] = {
+ 0, 0, 0, 0};
+static char ppi_dev_name[8];
+
+int cam_csid_ppi_probe(struct platform_device *pdev)
+{
+ struct cam_hw_intf *ppi_hw_intf;
+ struct cam_hw_info *ppi_hw_info;
+ struct cam_csid_ppi_hw *ppi_dev = NULL;
+ const struct of_device_id *match_dev = NULL;
+ struct cam_csid_ppi_hw_info *ppi_hw_data = NULL;
+ uint32_t ppi_dev_idx;
+ int rc = 0;
+
+ CAM_DBG(CAM_ISP, "PPI probe called");
+
+ ppi_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
+ if (!ppi_hw_intf) {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ ppi_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
+ if (!ppi_hw_info) {
+ rc = -ENOMEM;
+ goto free_hw_intf;
+ }
+
+ ppi_dev = kzalloc(sizeof(struct cam_csid_ppi_hw), GFP_KERNEL);
+ if (!ppi_dev) {
+ rc = -ENOMEM;
+ goto free_hw_info;
+ }
+
+ /* get csid ppi hw index */
+ of_property_read_u32(pdev->dev.of_node, "cell-index", &ppi_dev_idx);
+
+ /* get csid ppi hw information */
+ match_dev = of_match_device(pdev->dev.driver->of_match_table,
+ &pdev->dev);
+ if (!match_dev) {
+ CAM_ERR(CAM_ISP, "No matching table for the CSID PPI HW!");
+ rc = -EINVAL;
+ goto free_dev;
+ }
+
+ memset(ppi_dev_name, 0, sizeof(ppi_dev_name));
+ snprintf(ppi_dev_name, sizeof(ppi_dev_name), "ppi%1u", ppi_dev_idx);
+
+ ppi_hw_intf->hw_idx = ppi_dev_idx;
+ ppi_hw_intf->hw_priv = ppi_hw_info;
+
+ ppi_hw_info->core_info = ppi_dev;
+ ppi_hw_info->soc_info.pdev = pdev;
+ ppi_hw_info->soc_info.dev = &pdev->dev;
+ ppi_hw_info->soc_info.dev_name = ppi_dev_name;
+ ppi_hw_info->soc_info.index = ppi_dev_idx;
+
+ ppi_hw_data = (struct cam_csid_ppi_hw_info *)match_dev->data;
+ /* need to setup the pdev before call the csid ppi hw probe init */
+ ppi_dev->ppi_info = ppi_hw_data;
+
+ rc = cam_csid_ppi_hw_probe_init(ppi_hw_intf, ppi_dev_idx);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "PPI: Probe init failed!");
+ goto free_dev;
+ }
+
+ platform_set_drvdata(pdev, ppi_dev);
+ CAM_DBG(CAM_ISP, "PPI:%d probe successful",
+ ppi_hw_intf->hw_idx);
+
+ if (ppi_hw_intf->hw_idx < CAM_CSID_PPI_HW_MAX)
+ cam_csid_ppi_hw_list[ppi_hw_intf->hw_idx] = ppi_hw_intf;
+ else
+ goto free_dev;
+
+ return 0;
+free_dev:
+ kfree(ppi_dev);
+free_hw_info:
+ kfree(ppi_hw_info);
+free_hw_intf:
+ kfree(ppi_hw_intf);
+err:
+ return rc;
+}
+
+int cam_csid_ppi_remove(struct platform_device *pdev)
+{
+ struct cam_csid_ppi_hw *ppi_dev = NULL;
+ struct cam_hw_intf *ppi_hw_intf;
+ struct cam_hw_info *ppi_hw_info;
+
+ ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev);
+ ppi_hw_intf = ppi_dev->hw_intf;
+ ppi_hw_info = ppi_dev->hw_info;
+
+ CAM_DBG(CAM_ISP, "PPI:%d remove", ppi_dev->hw_intf->hw_idx);
+
+ cam_csid_ppi_hw_deinit(ppi_dev);
+
+ /* release the ppi device memory */
+ kfree(ppi_dev);
+ kfree(ppi_hw_info);
+ kfree(ppi_hw_intf);
+ return 0;
+}
+
+int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
+ uint32_t hw_idx)
+{
+ int rc = 0;
+
+ if (cam_csid_ppi_hw_list[hw_idx]) {
+ *csid_ppi_hw = cam_csid_ppi_hw_list[hw_idx];
+ } else {
+ *csid_ppi_hw = NULL;
+ rc = -1;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(cam_csid_ppi_hw_init);
+
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h
new file mode 100644
index 000000000000..b2ebeaf92947
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_DEV_H_
+#define _CAM_CSID_PPI_DEV_H_
+
+#include "cam_isp_hw.h"
+
+irqreturn_t cam_csid_ppi_irq(int irq_num, void *data);
+int cam_csid_ppi_probe(struct platform_device *pdev);
+int cam_csid_ppi_remove(struct platform_device *pdev);
+
+#endif /*_CAM_CSID_PPI_DEV_H_ */
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
index 576e8cb8d3b8..6254b97c436a 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
@@ -293,6 +293,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0x0,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = {
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
index 42f0f290a166..ed2857bd78ed 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
@@ -334,6 +334,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = {
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
index 8a78fe0b9b0d..d430ceef3360 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
@@ -350,6 +350,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = {
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 5610f6d267ff..7541d06e7ede 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
@@ -16,6 +16,7 @@
#include <uapi/media/cam_defs.h>
#include "cam_ife_csid_core.h"
+#include "cam_csid_ppi_core.h"
#include "cam_isp_hw.h"
#include "cam_soc_util.h"
#include "cam_io_util.h"
@@ -78,7 +79,7 @@ static int cam_ife_csid_is_ipp_ppp_format_supported(
static int cam_ife_csid_get_format_rdi(
uint32_t in_format, uint32_t out_format,
- uint32_t *decode_fmt, uint32_t *plain_fmt)
+ uint32_t *decode_fmt, uint32_t *plain_fmt, uint32_t *in_bpp)
{
int rc = 0;
@@ -96,6 +97,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 6;
break;
case CAM_FORMAT_MIPI_RAW_8:
switch (out_format) {
@@ -111,6 +113,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 8;
break;
case CAM_FORMAT_MIPI_RAW_10:
switch (out_format) {
@@ -126,6 +129,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 10;
break;
case CAM_FORMAT_MIPI_RAW_12:
switch (out_format) {
@@ -140,6 +144,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 12;
break;
case CAM_FORMAT_MIPI_RAW_14:
switch (out_format) {
@@ -154,6 +159,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 14;
break;
case CAM_FORMAT_MIPI_RAW_16:
switch (out_format) {
@@ -168,6 +174,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 16;
break;
case CAM_FORMAT_MIPI_RAW_20:
switch (out_format) {
@@ -182,6 +189,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 20;
break;
case CAM_FORMAT_DPCM_10_6_10:
*decode_fmt = 0x7;
@@ -467,6 +475,7 @@ static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
CAM_ERR(CAM_ISP, "CSID:%d IRQ value after reset rc = %d",
csid_hw->hw_intf->hw_idx, val);
csid_hw->error_irq_count = 0;
+ csid_hw->first_sof_ts = 0;
for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
csid_hw->res_sof_cnt[i] = 0;
@@ -565,10 +574,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
init_completion(complete);
reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
- /* Enable the Test gen before reset */
- cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
- csid_reg->tpg_reg->csid_tpg_ctrl_addr);
-
/* Reset the corresponding ife csid path */
cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
reset_strb_addr);
@@ -583,10 +588,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
rc = -ETIMEDOUT;
}
- /* Disable Test Gen after reset*/
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
- csid_reg->tpg_reg->csid_tpg_ctrl_addr);
-
end:
return rc;
@@ -1165,8 +1166,14 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
csid_hw->res_sof_cnt[i] = 0;
+ csid_hw->ipp_path_config.measure_enabled = 0;
+ csid_hw->ppp_path_config.measure_enabled = 0;
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+ csid_hw->rdi_path_config[i].measure_enabled = 0;
+
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
csid_hw->error_irq_count = 0;
+ csid_hw->first_sof_ts = 0;
return rc;
}
@@ -1420,10 +1427,12 @@ static int cam_ife_csid_enable_csi2(
struct cam_isp_resource_node *res)
{
int rc = 0;
- const struct cam_ife_csid_reg_offset *csid_reg;
- struct cam_hw_soc_info *soc_info;
- struct cam_ife_csid_cid_data *cid_data;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_cid_data *cid_data;
+ struct cam_csid_ppi_cfg ppi_lane_cfg;
uint32_t val = 0;
+ uint32_t ppi_index = 0;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
@@ -1514,6 +1523,24 @@ static int cam_ife_csid_enable_csi2(
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
+ ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
+ if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
+ ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type;
+ ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num;
+ ppi_lane_cfg.lane_cfg = csid_hw->csi2_rx_cfg.lane_cfg;
+
+ CAM_DBG(CAM_ISP, "ppi_index to init %d", ppi_index);
+ rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.init(
+ csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
+ &ppi_lane_cfg,
+ sizeof(struct cam_csid_ppi_cfg));
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d Init Failed",
+ ppi_index);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -1521,8 +1548,10 @@ static int cam_ife_csid_disable_csi2(
struct cam_ife_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
{
- const struct cam_ife_csid_reg_offset *csid_reg;
- struct cam_hw_soc_info *soc_info;
+ int rc = 0;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ struct cam_hw_soc_info *soc_info;
+ uint32_t ppi_index = 0;
if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
@@ -1553,6 +1582,19 @@ static int cam_ife_csid_disable_csi2(
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+ ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
+ if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
+ /* De-Initialize the PPI bridge */
+ CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index);
+ rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.deinit(
+ csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
+ NULL, 0);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d De-Init Failed", ppi_index);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -1587,6 +1629,7 @@ static int cam_ife_csid_init_config_pxl_path(
const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
bool is_ipp;
uint32_t decode_format = 0, plain_format = 0, val = 0;
+ struct cam_isp_sensor_dimension *path_config;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1595,9 +1638,11 @@ static int cam_ife_csid_init_config_pxl_path(
if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
is_ipp = true;
pxl_reg = csid_reg->ipp_reg;
+ path_config = &(csid_hw->ipp_path_config);
} else {
is_ipp = false;
pxl_reg = csid_reg->ppp_reg;
+ path_config = &(csid_hw->ppp_path_config);
}
if (!pxl_reg) {
@@ -1666,6 +1711,24 @@ static int cam_ife_csid_init_config_pxl_path(
}
}
+ /* configure pixel format measure */
+ if (path_config->measure_enabled) {
+ val = (((path_config->height &
+ csid_reg->cmn_reg->format_measure_height_mask_val) <<
+ csid_reg->cmn_reg->format_measure_height_shift_val) |
+ (path_config->width &
+ csid_reg->cmn_reg->format_measure_width_mask_val));
+ CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+ csid_hw->hw_intf->hw_idx, val);
+
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_format_measure_cfg1_addr);
+
+ /* enable pixel and line counter */
+ cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_format_measure_cfg0_addr);
+ }
+
/* set frame drop pattern to 0 and period to 1 */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_frm_drop_period_addr);
@@ -1811,6 +1874,7 @@ static int cam_ife_csid_enable_pxl_path(
const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
bool is_ipp;
uint32_t val = 0, path_status;
+ struct cam_isp_sensor_dimension *path_config;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1819,9 +1883,11 @@ static int cam_ife_csid_enable_pxl_path(
if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
is_ipp = true;
pxl_reg = csid_reg->ipp_reg;
+ path_config = &(csid_hw->ipp_path_config);
} else {
is_ipp = false;
pxl_reg = csid_reg->ppp_reg;
+ path_config = &(csid_hw->ppp_path_config);
}
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
@@ -1882,6 +1948,10 @@ static int cam_ife_csid_enable_pxl_path(
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
+ if (path_config->measure_enabled)
+ val |= (CSID_PATH_ERROR_PIX_COUNT |
+ CSID_PATH_ERROR_LINE_COUNT);
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_irq_mask_addr);
@@ -1982,7 +2052,7 @@ static int cam_ife_csid_init_config_rdi_path(
struct cam_ife_csid_path_cfg *path_data;
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
- uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
+ uint32_t path_format = 0, plain_fmt = 0, val = 0, id, in_bpp = 0;
uint32_t format_measure_addr;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
@@ -1997,7 +2067,7 @@ static int cam_ife_csid_init_config_rdi_path(
}
rc = cam_ife_csid_get_format_rdi(path_data->in_format,
- path_data->out_format, &path_format, &plain_fmt);
+ path_data->out_format, &path_format, &plain_fmt, &in_bpp);
if (rc)
return rc;
@@ -2046,6 +2116,32 @@ static int cam_ife_csid_init_config_rdi_path(
CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
csid_hw->hw_intf->hw_idx, val);
}
+
+ /* configure pixel format measure */
+ if (csid_hw->rdi_path_config[id].measure_enabled) {
+ val = ((csid_hw->rdi_path_config[id].height &
+ csid_reg->cmn_reg->format_measure_height_mask_val) <<
+ csid_reg->cmn_reg->format_measure_height_shift_val);
+
+ if (path_format == 0xF)
+ val |= (((csid_hw->rdi_path_config[id].width *
+ in_bpp) / 8) &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ else
+ val |= (csid_hw->rdi_path_config[id].width &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+
+ CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+ csid_hw->hw_intf->hw_idx, val);
+
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr);
+
+ /* enable pixel and line counter */
+ cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
+ }
+
/* set frame drop pattern to 0 and period to 1 */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
@@ -2218,6 +2314,10 @@ static int cam_ife_csid_enable_rdi_path(
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
+ if (csid_hw->rdi_path_config[id].measure_enabled)
+ val |= (CSID_PATH_ERROR_PIX_COUNT |
+ CSID_PATH_ERROR_LINE_COUNT);
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
@@ -2454,9 +2554,16 @@ static int cam_ife_csid_get_time_stamp(
CAM_IFE_CSID_QTIMER_MUL_FACTOR,
CAM_IFE_CSID_QTIMER_DIV_FACTOR);
- get_monotonic_boottime64(&ts);
- time_stamp->boot_timestamp = (uint64_t)((ts.tv_sec * 1000000000) +
- ts.tv_nsec);
+ if (!csid_hw->first_sof_ts) {
+ get_monotonic_boottime64(&ts);
+ time_stamp->boot_timestamp =
+ (uint64_t)((ts.tv_sec * 1000000000) +
+ ts.tv_nsec);
+ CAM_DBG(CAM_ISP, "timestamp:%lld",
+ time_stamp->boot_timestamp);
+ csid_hw->first_sof_ts = 1;
+ } else
+ time_stamp->boot_timestamp = 0;
return 0;
}
@@ -2664,6 +2771,13 @@ static int cam_ife_csid_release(void *hw_priv,
case CAM_ISP_RESOURCE_PIX_PATH:
res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
cam_ife_csid_reset_init_frame_drop(csid_hw);
+ if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
+ csid_hw->ipp_path_config.measure_enabled = 0;
+ else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP)
+ csid_hw->ppp_path_config.measure_enabled = 0;
+ else
+ csid_hw->rdi_path_config[res->res_id].measure_enabled
+ = 0;
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
@@ -3094,6 +3208,57 @@ static int cam_ife_csid_set_csid_clock(
return 0;
}
+static int cam_ife_csid_set_sensor_dimension(
+ struct cam_ife_csid_hw *csid_hw, void *cmd_args)
+{
+ struct cam_ife_sensor_dimension_update_args *dimension_update = NULL;
+ uint32_t i;
+
+ if (!csid_hw)
+ return -EINVAL;
+
+ dimension_update =
+ (struct cam_ife_sensor_dimension_update_args *)cmd_args;
+ csid_hw->ipp_path_config.measure_enabled =
+ dimension_update->ipp_path.measure_enabled;
+ if (dimension_update->ipp_path.measure_enabled) {
+ csid_hw->ipp_path_config.width =
+ dimension_update->ipp_path.width;
+ csid_hw->ipp_path_config.height =
+ dimension_update->ipp_path.height;
+ CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d",
+ csid_hw->ipp_path_config.width,
+ csid_hw->ipp_path_config.height);
+ }
+ csid_hw->ppp_path_config.measure_enabled =
+ dimension_update->ppp_path.measure_enabled;
+ if (dimension_update->ppp_path.measure_enabled) {
+ csid_hw->ppp_path_config.width =
+ dimension_update->ppp_path.width;
+ csid_hw->ppp_path_config.height =
+ dimension_update->ppp_path.height;
+ CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d",
+ csid_hw->ppp_path_config.width,
+ csid_hw->ppp_path_config.height);
+ }
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) {
+ csid_hw->rdi_path_config[i].measure_enabled
+ = dimension_update->rdi_path[i].measure_enabled;
+ if (csid_hw->rdi_path_config[i].measure_enabled) {
+ csid_hw->rdi_path_config[i].width =
+ dimension_update->rdi_path[i].width;
+ csid_hw->rdi_path_config[i].height =
+ dimension_update->rdi_path[i].height;
+ CAM_DBG(CAM_ISP,
+ "CSID rdi path[%d] width %d height %d",
+ i, csid_hw->rdi_path_config[i].width,
+ csid_hw->rdi_path_config[i].height);
+ }
+ }
+
+ return 0;
+}
+
static int cam_ife_csid_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -3131,6 +3296,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
case CAM_IFE_CSID_SET_INIT_FRAME_DROP:
rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args);
break;
+ case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
+ rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);
@@ -3153,20 +3321,19 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
const struct cam_ife_csid_rdi_reg_offset *rdi_reg;
uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
- uint32_t val, irq_status_ppp = 0;
+ uint32_t val, val2, irq_status_ppp = 0;
bool fatal_err_detected = false;
uint32_t sof_irq_debug_en = 0;
unsigned long flags;
- csid_hw = (struct cam_ife_csid_hw *)data;
-
- CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
-
if (!data) {
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
return IRQ_HANDLED;
}
+ csid_hw = (struct cam_ife_csid_hw *)data;
+ CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
+
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
csi2_reg = csid_reg->csi2_reg;
@@ -3209,7 +3376,7 @@ 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,
+ CAM_ERR_RATE_LIMIT(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,
@@ -3446,6 +3613,25 @@ handle_fatal_error:
csid_reg->ipp_reg->csid_pxl_ctrl_addr);
}
}
+
+ if ((irq_status_ipp & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_ipp & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_pxl_format_measure0_addr);
+
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_ipp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ipp);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ csid_hw->ipp_path_config.height,
+ csid_hw->ipp_path_config.width,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
/*read PPP errors */
@@ -3527,6 +3713,25 @@ handle_fatal_error:
csid_reg->ppp_reg->csid_pxl_ctrl_addr);
}
}
+
+ if ((irq_status_ppp & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_ppp & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ppp_reg->csid_pxl_format_measure0_addr);
+
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_ppp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ppp);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ csid_hw->ppp_path_config.height,
+ csid_hw->ppp_path_config.width,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
@@ -3593,6 +3798,31 @@ handle_fatal_error:
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
}
+
+ if ((irq_status_rdi[i] & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_rdi[i] & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr);
+ val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr
+ );
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_rdi[%d]:0x%x",
+ csid_hw->hw_intf->hw_idx, i,
+ irq_status_rdi[i]);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ ((val2 >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val2 &
+ csid_reg->cmn_reg->format_measure_width_mask_val,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
@@ -3629,7 +3859,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
CAM_DBG(CAM_ISP, "type %d index %d",
ife_csid_hw->hw_intf->hw_type, csid_idx);
-
ife_csid_hw->device_enabled = 0;
ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
mutex_init(&ife_csid_hw->hw_info->hw_mutex);
@@ -3644,7 +3873,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
init_completion(&ife_csid_hw->csid_rdin_complete[i]);
-
rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
cam_ife_csid_irq, ife_csid_hw);
if (rc < 0) {
@@ -3737,8 +3965,28 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
ife_csid_hw->csid_debug = 0;
ife_csid_hw->error_irq_count = 0;
+ ife_csid_hw->first_sof_ts = 0;
+ ife_csid_hw->ipp_path_config.measure_enabled = 0;
+ ife_csid_hw->ppp_path_config.measure_enabled = 0;
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+ ife_csid_hw->rdi_path_config[i].measure_enabled = 0;
+
+ /* Check if ppi bridge is present or not? */
+ ife_csid_hw->ppi_enable = of_property_read_bool(
+ csid_hw_info->soc_info.pdev->dev.of_node,
+ "ppi-enable");
+
+ if (!ife_csid_hw->ppi_enable)
+ return 0;
- return 0;
+ /* Initialize the PPI bridge */
+ for (i = 0; i < CAM_CSID_PPI_HW_MAX; i++) {
+ rc = cam_csid_ppi_hw_init(&ife_csid_hw->ppi_hw_intf[i], i);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI init failed for PPI %d", i);
+ break;
+ }
+ }
err:
if (rc) {
kfree(ife_csid_hw->ipp_res.res_priv);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index 600deb245f32..f2173f13f0c4 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -16,6 +16,7 @@
#include "cam_hw.h"
#include "cam_ife_csid_hw_intf.h"
#include "cam_ife_csid_soc.h"
+#include "cam_csid_ppi_core.h"
#define CAM_IFE_CSID_HW_RES_MAX 4
#define CAM_IFE_CSID_CID_RES_MAX 4
@@ -309,6 +310,10 @@ struct cam_ife_csid_common_reg_offset {
uint32_t ppp_irq_mask_all;
uint32_t measure_en_hbi_vbi_cnt_mask;
uint32_t format_measure_en_val;
+ uint32_t format_measure_width_shift_val;
+ uint32_t format_measure_width_mask_val;
+ uint32_t format_measure_height_shift_val;
+ uint32_t format_measure_height_mask_val;
};
/**
@@ -468,6 +473,11 @@ struct cam_ife_csid_path_cfg {
* @csid_debug: csid debug information to enable the SOT, EOT,
* SOF, EOF, measure etc in the csid hw
* @clk_rate Clock rate
+ * @ipp_path ipp path configuration
+ * @ppp_path ppp path configuration
+ * @rdi_path RDI path configuration
+ * @hbi Horizontal blanking
+ * @vbi Vertical blanking
* @sof_irq_triggered: Flag is set on receiving event to enable sof irq
* incase of SOF freeze.
* @irq_debug_cnt: Counter to track sof irq's when above flag is set.
@@ -480,7 +490,10 @@ struct cam_ife_csid_path_cfg {
* @init_frame_drop Initial frame drop number
* @res_sof_cnt path resource sof count value. it used for initial
* frame drop
- *
+ * @first_sof_ts flag to mark the first sof has been registered
+ * @ppi_hw_intf interface to ppi hardware
+ * @ppi_enabled flag to specify if the hardware has ppi bridge
+ * or not
*/
struct cam_ife_csid_hw {
struct cam_hw_intf *hw_intf;
@@ -503,6 +516,11 @@ struct cam_ife_csid_hw {
struct completion csid_rdin_complete[CAM_IFE_CSID_RDI_MAX];
uint64_t csid_debug;
uint64_t clk_rate;
+ struct cam_isp_sensor_dimension ipp_path_config;
+ struct cam_isp_sensor_dimension ppp_path_config;
+ struct cam_isp_sensor_dimension rdi_path_config[4];
+ uint32_t hbi;
+ uint32_t vbi;
bool sof_irq_triggered;
uint32_t irq_debug_cnt;
uint32_t error_irq_count;
@@ -511,6 +529,9 @@ struct cam_ife_csid_hw {
uint32_t dual_usage;
uint32_t init_frame_drop;
uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX];
+ uint32_t first_sof_ts;
+ struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];
+ bool ppi_enable;
};
int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
index 0c45bd1268b9..8d340207a0a1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
@@ -158,6 +158,7 @@ enum cam_ife_csid_cmd_type {
CAM_IFE_CSID_SET_CSID_DEBUG,
CAM_IFE_CSID_SOF_IRQ_DEBUG,
CAM_IFE_CSID_SET_INIT_FRAME_DROP,
+ CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
CAM_IFE_CSID_CMD_MAX,
};
@@ -181,5 +182,17 @@ struct cam_ife_csid_clock_update_args {
uint64_t clk_rate;
};
+/*
+ * struct cam_ife_sensor_dim_update_args:
+ *
+ * @ppp_path: expected ppp path configuration
+ * @ipp_path: expected ipp path configuration
+ * @rdi_path: expected rdi path configuration
+ */
+struct cam_ife_sensor_dimension_update_args {
+ struct cam_isp_sensor_dimension ppp_path;
+ struct cam_isp_sensor_dimension ipp_path;
+ struct cam_isp_sensor_dimension rdi_path[4];
+};
#endif /* _CAM_CSID_HW_INTF_H_ */
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index b23014773022..d90030d9ed16 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -20,17 +20,21 @@
#include "cam_irq_controller.h"
#include <uapi/media/cam_isp.h>
+#define CAM_ISP_FPS_60 60
+
/*
* struct cam_isp_timestamp:
*
* @mono_time: Monotonic boot time
* @vt_time: AV Timer time
* @ticks: Qtimer ticks
+ * @time_usecs: time in micro seconds
*/
struct cam_isp_timestamp {
struct timeval mono_time;
struct timeval vt_time;
uint64_t ticks;
+ uint64_t time_usecs;
};
/*
@@ -105,6 +109,7 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_FE_UPDATE_IN_RD,
CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD,
CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
+ CAM_ISP_HW_CMD_FPS_CONFIG,
CAM_ISP_HW_CMD_MAX,
};
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 9d6bcb71bb69..3bcedc948a18 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
@@ -178,6 +178,17 @@ struct cam_vfe_clock_update_args {
};
/*
+ * struct cam_vfe_fps_config_args:
+ *
+ * @node_res: Resource to get the fps value
+ * @fps: FPS value to configure EPOCH
+ */
+struct cam_vfe_fps_config_args {
+ struct cam_isp_resource_node *node_res;
+ uint32_t fps;
+};
+
+/*
* struct cam_vfe_bw_update_args:
*
* @node_res: Resource to get the BW
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index a26c11264d2c..162ddadd744f 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -444,6 +444,8 @@ void cam_isp_hw_get_timestamp(struct cam_isp_timestamp *time_stamp)
get_monotonic_boottime(&ts);
time_stamp->mono_time.tv_sec = ts.tv_sec;
time_stamp->mono_time.tv_usec = ts.tv_nsec/1000;
+ time_stamp->time_usecs = ts.tv_sec * 1000000 +
+ time_stamp->mono_time.tv_usec;
}
static int cam_vfe_irq_top_half(uint32_t evt_id,
@@ -761,6 +763,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_BW_UPDATE:
case CAM_ISP_HW_CMD_BW_CONTROL:
case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
rc = core_info->vfe_top->hw_ops.process_cmd(
core_info->vfe_top->top_priv, cmd_type, cmd_args,
arg_size);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 4e9a97501749..a70f0bbd1340 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -44,6 +44,7 @@ struct cam_vfe_mux_camif_data {
bool enable_sof_irq_debug;
uint32_t irq_debug_cnt;
uint32_t camif_debug;
+ uint32_t fps;
};
static int cam_vfe_camif_validate_pix_pattern(uint32_t pattern)
@@ -265,9 +266,15 @@ static int cam_vfe_camif_resource_start(
case CAM_CPAS_TITAN_170_V110:
case CAM_CPAS_TITAN_170_V120:
default:
- epoch0_irq_mask = (((rsrc_data->last_line -
+ if (rsrc_data->fps == CAM_ISP_FPS_60) {
+ epoch0_irq_mask = ((rsrc_data->last_line -
+ rsrc_data->first_line) / 2) +
+ rsrc_data->first_line;
+ } else {
+ epoch0_irq_mask = (((rsrc_data->last_line -
rsrc_data->first_line) * 2) / 3) +
rsrc_data->first_line;
+ }
epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
0xFFFF;
computed_epoch_line_cfg = (epoch0_irq_mask << 16) |
@@ -514,6 +521,20 @@ static int cam_vfe_camif_sof_irq_debug(
return 0;
}
+static int cam_vfe_camif_set_fps_config(
+ struct cam_isp_resource_node *rsrc_node, void *cmd_args)
+{
+ struct cam_vfe_mux_camif_data *camif_priv = NULL;
+ struct cam_vfe_fps_config_args *fps_args = cmd_args;
+
+ camif_priv =
+ (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
+
+ camif_priv->fps = fps_args->fps;
+
+ return 0;
+
+}
static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
@@ -545,6 +566,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
break;
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
+ rc = cam_vfe_camif_set_fps_config(rsrc_node, cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP,
"unsupported process command:%d", cmd_type);
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 b0ac94b895f1..9d03cbad7ff0 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
@@ -283,6 +283,22 @@ static int cam_vfe_top_fs_update(
return 0;
}
+static int cam_vfe_top_fps_config(
+ struct cam_vfe_top_ver2_priv *top_priv,
+ void *cmd_args, uint32_t arg_size)
+{
+ struct cam_vfe_fps_config_args *cmd_update = NULL;
+
+ cmd_update =
+ (struct cam_vfe_fps_config_args *)cmd_args;
+
+ if (cmd_update->node_res->process_cmd)
+ return cmd_update->node_res->process_cmd(cmd_update->node_res,
+ CAM_ISP_HW_CMD_FPS_CONFIG, cmd_args, arg_size);
+
+ return 0;
+}
+
static int cam_vfe_top_clock_update(
struct cam_vfe_top_ver2_priv *top_priv,
void *cmd_args, uint32_t arg_size)
@@ -740,6 +756,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
rc = cam_vfe_get_irq_register_dump(top_priv,
cmd_args, arg_size);
break;
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
+ rc = cam_vfe_top_fps_config(top_priv, cmd_args,
+ arg_size);
+ break;
default:
rc = -EINVAL;
CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type);
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 f7b42d5a7699..1a3a7cb38878 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
@@ -634,8 +634,13 @@ static void cam_jpeg_mgr_print_io_bufs(struct cam_packet *packet,
for (i = 0; i < packet->num_io_configs; i++) {
for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
- if (!io_cfg[i].mem_handle[j])
+ if (!io_cfg[i].mem_handle[j]) {
+ CAM_ERR(CAM_JPEG,
+ "Mem Handle %d is NULL for %d io config",
+ j, i);
break;
+ }
+
if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
GET_FD_FROM_HANDLE(pf_buf_info)) {
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 52907cd6803e..225f859674f1 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
@@ -91,6 +91,9 @@ int cam_jpeg_enc_init_hw(void *device_priv,
CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc);
goto soc_failed;
}
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_UP;
+ spin_unlock(&jpeg_enc_dev->hw_lock);
mutex_unlock(&core_info->core_mutex);
@@ -140,6 +143,9 @@ int cam_jpeg_enc_deinit_hw(void *device_priv,
return -EFAULT;
}
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_DOWN;
+ spin_unlock(&jpeg_enc_dev->hw_lock);
rc = cam_jpeg_enc_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_JPEG, "soc disable failed %d", rc);
@@ -173,12 +179,19 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) {
+ CAM_ERR(CAM_JPEG, "JPEG HW is in off state");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ return -EINVAL;
+ }
irq_status = cam_io_r_mb(mem_base +
core_info->jpeg_enc_hw_info->reg_offset.int_status);
cam_io_w_mb(irq_status,
soc_info->reg_map[0].mem_base +
core_info->jpeg_enc_hw_info->reg_offset.int_clr);
+ spin_unlock(&jpeg_enc_dev->hw_lock);
CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d",
irq_num, irq_status, core_info->core_state);
@@ -268,6 +281,12 @@ int cam_jpeg_enc_reset_hw(void *data,
mutex_lock(&core_info->core_mutex);
spin_lock(&jpeg_enc_dev->hw_lock);
+ if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) {
+ CAM_ERR(CAM_JPEG, "JPEG HW is in off state");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ mutex_unlock(&core_info->core_mutex);
+ return -EINVAL;
+ }
if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
CAM_ERR(CAM_JPEG, "alrady resetting");
spin_unlock(&jpeg_enc_dev->hw_lock);
@@ -319,10 +338,18 @@ int cam_jpeg_enc_start_hw(void *data,
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) {
+ CAM_ERR(CAM_JPEG, "JPEG HW is in off state");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ return -EINVAL;
+ }
if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) {
CAM_ERR(CAM_JPEG, "Error not ready");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
return -EINVAL;
}
+ spin_unlock(&jpeg_enc_dev->hw_lock);
cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
mem_base + hw_info->reg_offset.hw_cmd);
@@ -352,6 +379,12 @@ int cam_jpeg_enc_stop_hw(void *data,
mutex_lock(&core_info->core_mutex);
spin_lock(&jpeg_enc_dev->hw_lock);
+ if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) {
+ CAM_ERR(CAM_JPEG, "JPEG HW is in off state");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ mutex_unlock(&core_info->core_mutex);
+ return -EINVAL;
+ }
if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
CAM_ERR(CAM_JPEG, "alrady stopping");
spin_unlock(&jpeg_enc_dev->hw_lock);
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 c8e2a023b0d4..b2994d52d83c 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
@@ -48,6 +48,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
link->last_flush_id = 0;
link->initial_sync_req = -1;
link->in_msync_mode = false;
+ link->initial_skip = true;
+ link->sof_timestamp = 0;
+ link->prev_sof_timestamp = 0;
}
void cam_req_mgr_handle_core_shutdown(void)
@@ -610,6 +613,19 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link,
traverse_data.open_req_cnt = link->open_req_cnt;
/*
+ * Some no-sync mode requests are processed after link config,
+ * then process the sync mode requests after no-sync mode requests
+ * are handled, the initial_skip should be false when processing
+ * the sync mode requests.
+ */
+ if (link->initial_skip) {
+ CAM_DBG(CAM_CRM,
+ "Set initial_skip to false for link %x",
+ link->link_hdl);
+ link->initial_skip = false;
+ }
+
+ /*
* Traverse through all pd tables, if result is success,
* apply the settings
*/
@@ -894,9 +910,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
struct cam_req_mgr_slot *slot)
{
struct cam_req_mgr_core_link *sync_link = NULL;
- int64_t req_id = 0;
+ struct cam_req_mgr_slot *sync_rd_slot = NULL;
+ int64_t req_id = 0, sync_req_id = 0;
int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
int32_t sync_num_slots = 0;
+ uint64_t sync_frame_duration = 0;
bool ready = true, sync_ready = true;
if (!link->sync_link) {
@@ -907,11 +925,65 @@ 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;
+ sync_rd_idx = sync_link->req.in_q->rd_idx;
+ sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx];
+ sync_req_id = sync_rd_slot->req_id;
CAM_DBG(CAM_REQ,
"link_hdl %x req %lld frame_skip_flag %d ",
link->link_hdl, req_id, link->sync_link_sof_skip);
+ if (sync_link->initial_skip) {
+ link->initial_skip = false;
+ __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
+ CAM_DBG(CAM_CRM,
+ "sync link %x not streamed on",
+ sync_link->link_hdl);
+ return -EAGAIN;
+ }
+
+ if (sync_link->prev_sof_timestamp)
+ sync_frame_duration = sync_link->sof_timestamp
+ - sync_link->prev_sof_timestamp;
+ else
+ sync_frame_duration = DEFAULT_FRAME_DURATION;
+
+ CAM_DBG(CAM_CRM,
+ "sync link %x last frame duration is %d ns",
+ sync_link->link_hdl, sync_frame_duration);
+
+ if (link->initial_skip) {
+ link->initial_skip = false;
+
+ if (link->sof_timestamp > sync_link->sof_timestamp &&
+ sync_link->sof_timestamp > 0 &&
+ link->sof_timestamp - sync_link->sof_timestamp <
+ sync_frame_duration / 2) {
+ /*
+ * If this frame sync with the previous frame of sync
+ * link, then we need to skip this frame, since the
+ * previous frame of sync link is also skipped.
+ */
+ __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
+ CAM_DBG(CAM_CRM,
+ "This frame sync with previous sync_link %x frame",
+ sync_link->link_hdl);
+ return -EAGAIN;
+ } else if (link->sof_timestamp <= sync_link->sof_timestamp) {
+ /*
+ * Sometimes, link receives the SOF event is eariler
+ * than sync link in IFE CSID side, but link's SOF
+ * event is processed later than sync link's, then
+ * we need to skip this SOF event since the sync
+ * link's SOF event is also skipped.
+ */
+ __cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
+ CAM_DBG(CAM_CRM,
+ "The previous frame of sync link is skipped");
+ return -EAGAIN;
+ }
+ }
+
if (sync_link->sync_link_sof_skip) {
CAM_DBG(CAM_REQ,
"No req applied on corresponding SOF on sync link: %x",
@@ -937,12 +1009,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
sync_ready = false;
}
- 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 + sync_num_slots) %
sync_num_slots) >= 1) &&
- (sync_link->req.in_q->slot[sync_rd_idx].status !=
+ (sync_rd_slot->status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
"Req: %lld [other link] not next req to be applied on link: %x",
@@ -975,7 +1046,15 @@ static int __cam_req_mgr_check_sync_req_is_ready(
CAM_DBG(CAM_CRM,
"Req: %lld ready %d sync_ready %d, ignore sync link next SOF",
req_id, ready, sync_ready);
- link->sync_link_sof_skip = true;
+
+ /*
+ * Only skip the frames if current frame sync with
+ * next frame of sync link.
+ */
+ if (link->sof_timestamp - sync_link->sof_timestamp >
+ sync_frame_duration / 2)
+ link->sync_link_sof_skip = true;
+
return -EINVAL;
} else if (ready == false) {
CAM_DBG(CAM_CRM,
@@ -984,6 +1063,61 @@ static int __cam_req_mgr_check_sync_req_is_ready(
return -EINVAL;
}
+ /*
+ * Do the self-correction when the frames are sync,
+ * we consider that the frames are synced if the
+ * difference of two SOF timestamp less than
+ * (sync_frame_duration / 5).
+ */
+ if ((link->sof_timestamp > sync_link->sof_timestamp) &&
+ (sync_link->sof_timestamp > 0) &&
+ (link->sof_timestamp - sync_link->sof_timestamp <
+ sync_frame_duration / 5) &&
+ (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
+
+ /*
+ * This means current frame should sync with next
+ * frame of sync link, then the request id of in
+ * rd slot of two links should be same.
+ */
+ CAM_DBG(CAM_CRM,
+ "link %x req_id %lld, sync_link %x req_id %lld",
+ link->link_hdl, req_id,
+ sync_link->link_hdl, sync_req_id);
+
+ if (req_id > sync_req_id) {
+ CAM_DBG(CAM_CRM,
+ "link %x too quickly, skip this frame",
+ link->link_hdl);
+ return -EAGAIN;
+ } else if (req_id < sync_req_id) {
+ CAM_DBG(CAM_CRM,
+ "sync link %x too quickly, skip next frame of sync link",
+ sync_link->link_hdl);
+ link->sync_link_sof_skip = true;
+ }
+ } else if ((sync_link->sof_timestamp > 0) &&
+ (link->sof_timestamp < sync_link->sof_timestamp) &&
+ (sync_link->sof_timestamp - link->sof_timestamp <
+ sync_frame_duration / 5) &&
+ (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) {
+
+ /*
+ * There is a timing issue once enter this condition,
+ * it means link receives the SOF event earlier than
+ * sync link in IFE CSID side, but the process in CRM
+ * is sync_link earlier than link, then previous SOF
+ * event of sync link is skipped, so we also need to
+ * skip this SOF event.
+ */
+ if (req_id >= sync_req_id) {
+ CAM_DBG(CAM_CRM,
+ "Timing issue, the sof event of link %x is delayed",
+ link->link_hdl);
+ return -EAGAIN;
+ }
+ }
+
CAM_DBG(CAM_REQ,
"Req: %lld ready to apply on link: %x [validation successful]",
req_id, link->link_hdl);
@@ -1011,10 +1145,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
*
*/
static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
- uint32_t trigger)
+ struct cam_req_mgr_trigger_notify *trigger_data)
{
int rc = 0, idx, last_app_idx;
int reset_step = 0;
+ uint32_t trigger = trigger_data->trigger;
struct cam_req_mgr_slot *slot = NULL;
struct cam_req_mgr_req_queue *in_q;
struct cam_req_mgr_core_session *session;
@@ -1052,6 +1187,13 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
}
if (trigger == CAM_TRIGGER_POINT_SOF) {
+ /*
+ * Update the timestamp in session lock protection
+ * to avoid timing issue.
+ */
+ link->prev_sof_timestamp = link->sof_timestamp;
+ link->sof_timestamp = trigger_data->sof_timestamp_val;
+
if (link->trigger_mask) {
CAM_ERR_RATE_LIMIT(CAM_CRM,
"Applying for last EOF fails");
@@ -2141,7 +2283,7 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
__cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots);
}
- rc = __cam_req_mgr_process_req(link, trigger_data->trigger);
+ rc = __cam_req_mgr_process_req(link, trigger_data);
release_lock:
mutex_unlock(&link->req.lock);
@@ -2372,6 +2514,7 @@ static int cam_req_mgr_cb_notify_trigger(
notify_trigger->link_hdl = trigger_data->link_hdl;
notify_trigger->dev_hdl = trigger_data->dev_hdl;
notify_trigger->trigger = trigger_data->trigger;
+ notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val;
task->process_cb = &cam_req_mgr_process_trigger;
rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);
@@ -3125,8 +3268,6 @@ int cam_req_mgr_sync_config(
link1->is_master = false;
link2->is_master = false;
- link1->initial_skip = false;
- link2->initial_skip = false;
link1->in_msync_mode = false;
link2->in_msync_mode = false;
@@ -3137,6 +3278,16 @@ int cam_req_mgr_sync_config(
link1->sync_link = link2;
link2->sync_link = link1;
__cam_req_mgr_set_master_link(link1, link2);
+ } else {
+ /*
+ * Reset below info after the mode is configured
+ * to NO-SYNC mode since they may be overridden
+ * if the sync config is invoked after SOF comes.
+ */
+ link1->initial_skip = true;
+ link2->initial_skip = true;
+ link1->sof_timestamp = 0;
+ link2->sof_timestamp = 0;
}
cam_session->sync_mode = sync_info->sync_mode;
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
index 05fe0860bfa0..94f26dee8917 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
@@ -32,6 +32,9 @@
#define MAX_SYNC_COUNT 65535
+/* Default frame rate is 30 */
+#define DEFAULT_FRAME_DURATION 33333333
+
#define SYNC_LINK_SOF_CNT_MAX_LMT 1
#define MAXIMUM_LINKS_PER_SESSION 4
@@ -321,7 +324,10 @@ struct cam_req_mgr_connected_device {
* master-slave sync
* @in_msync_mode : Flag to determine if a link is in master-slave mode
* @initial_sync_req : The initial req which is required to sync with the
- * other link
+ * other link, it means current hasn't receive any
+ * stream after streamon if it is true
+ * @sof_timestamp_value : SOF timestamp value
+ * @prev_sof_timestamp : Previous SOF timestamp value
*
*/
struct cam_req_mgr_core_link {
@@ -349,6 +355,8 @@ struct cam_req_mgr_core_link {
bool initial_skip;
bool in_msync_mode;
int64_t initial_sync_req;
+ uint64_t sof_timestamp;
+ uint64_t prev_sof_timestamp;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h
index 1d1df45c6ea5..934bc76014a5 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_interface.h
@@ -201,12 +201,14 @@ enum cam_req_mgr_link_evt_type {
* @frame_id : frame id for internal tracking
* @trigger : trigger point of this notification, CRM will send apply
* only to the devices which subscribe to this point.
+ * @sof_timestamp_val: Captured time stamp value at sof hw event
*/
struct cam_req_mgr_trigger_notify {
int32_t link_hdl;
int32_t dev_hdl;
int64_t frame_id;
uint32_t trigger;
+ uint64_t sof_timestamp_val;
};
/**
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 0181a4d8e2ff..f66d86ce091e 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
@@ -410,7 +410,9 @@ int cam_cci_soc_release(struct cci_device *cci_dev)
cci_dev->cci_state = CCI_STATE_DISABLED;
cci_dev->cycles_per_us = 0;
- cam_cpas_stop(cci_dev->cpas_handle);
+ rc = cam_cpas_stop(cci_dev->cpas_handle);
+ if (rc)
+ CAM_ERR(CAM_CCI, "cpas stop failed %d", rc);
return rc;
}
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 8074ecd9112a..b8605596aa6c 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
@@ -551,7 +551,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
{
struct cam_hw_soc_info *soc_info;
- int32_t i = 0;
+ int32_t i = 0, rc = 0;
if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT)
return;
@@ -574,7 +574,10 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
cam_csiphy_reset(csiphy_dev);
cam_soc_util_disable_platform_resource(soc_info, true, true);
- cam_cpas_stop(csiphy_dev->cpas_handle);
+ rc = cam_cpas_stop(csiphy_dev->cpas_handle);
+ if (rc)
+ CAM_ERR(CAM_CSIPHY, "cpas stop failed %d", rc);
+
csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE;
}
@@ -934,7 +937,10 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (rc < 0) {
csiphy_dev->csiphy_info.secure_mode[offset] =
CAM_SECURE_MODE_NON_SECURE;
- cam_cpas_stop(csiphy_dev->cpas_handle);
+ rc = cam_cpas_stop(csiphy_dev->cpas_handle);
+ if (rc < 0)
+ CAM_ERR(CAM_CSIPHY,
+ "de-voting CPAS: %d", rc);
goto release_mutex;
}
}
@@ -942,7 +948,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
rc = cam_csiphy_enable_hw(csiphy_dev);
if (rc != 0) {
CAM_ERR(CAM_CSIPHY, "cam_csiphy_enable_hw failed");
- cam_cpas_stop(csiphy_dev->cpas_handle);
+ rc = cam_cpas_stop(csiphy_dev->cpas_handle);
+ if (rc < 0)
+ CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc);
goto release_mutex;
}
rc = cam_csiphy_config_dev(csiphy_dev);
@@ -952,7 +960,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (rc < 0) {
CAM_ERR(CAM_CSIPHY, "cam_csiphy_config_dev failed");
cam_csiphy_disable_hw(csiphy_dev);
- cam_cpas_stop(csiphy_dev->cpas_handle);
+ rc = cam_cpas_stop(csiphy_dev->cpas_handle);
+ if (rc < 0)
+ CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc);
goto release_mutex;
}
csiphy_dev->start_dev_count++;
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 06d6bd49b3b0..bcd3823a357c 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
@@ -1016,7 +1016,7 @@ int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
&eeprom_cap,
sizeof(struct cam_eeprom_query_cap_t))) {
CAM_ERR(CAM_EEPROM, "Failed Copy to User");
- return -EFAULT;
+ rc = -EFAULT;
goto release_mutex;
}
CAM_DBG(CAM_EEPROM, "eeprom_cap: ID: %d", eeprom_cap.slot_info);
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 a2a738d85714..94bc611a9120 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
@@ -927,6 +927,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
}
break;
case CAM_CONFIG_DEV: {
+ if (s_ctrl->sensor_state < CAM_SENSOR_ACQUIRE) {
+ rc = -EINVAL;
+ CAM_ERR(CAM_SENSOR,
+ "sensor_id:[0x%x] not acquired to configure [%d] ",
+ s_ctrl->sensordata->slave_info.sensor_id,
+ s_ctrl->sensor_state
+ );
+ goto release_mutex;
+ }
+
rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg);
if (rc < 0) {
CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc);
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 626473f8769a..77a7204cfe55 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
@@ -191,7 +191,7 @@ static struct cam_iommu_cb_set iommu_cb_set;
static struct dentry *smmu_dentry;
-static bool smmu_fatal_flag;
+static bool smmu_fatal_flag = true;
static enum dma_data_direction cam_smmu_translate_dir(
enum cam_smmu_map_dir dir);
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 d4487efbf090..93d39e3c360a 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
@@ -288,6 +288,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
int rc;
long idx = 0;
bool bit;
+ int i = 0;
if (!sync_obj || !merged_obj) {
CAM_ERR(CAM_SYNC, "Invalid pointer(s)");
@@ -305,6 +306,14 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
return -EINVAL;
}
+ for (i = 0; i < num_objs; i++) {
+ rc = cam_sync_check_valid(sync_obj[i]);
+ if (rc) {
+ CAM_ERR(CAM_SYNC, "Sync_obj[%d] %d valid check fail",
+ i, sync_obj[i]);
+ return rc;
+ }
+ }
do {
idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
if (idx >= CAM_SYNC_MAX_OBJS)
@@ -376,6 +385,29 @@ int cam_sync_destroy(int32_t sync_obj)
return cam_sync_deinit_object(sync_dev->sync_table, sync_obj);
}
+int cam_sync_check_valid(int32_t sync_obj)
+{
+ struct sync_table_row *row = NULL;
+
+ if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
+ return -EINVAL;
+
+ row = sync_dev->sync_table + sync_obj;
+
+ if (!test_bit(sync_obj, sync_dev->bitmap)) {
+ CAM_ERR(CAM_SYNC, "Error: Released sync obj received %d",
+ sync_obj);
+ return -EINVAL;
+ }
+
+ if (row->state == CAM_SYNC_STATE_INVALID) {
+ CAM_ERR(CAM_SYNC,
+ "Error: accessing an uninitialized sync obj = %d",
+ sync_obj);
+ return -EINVAL;
+ }
+ return 0;
+}
int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms)
{
unsigned long timeleft;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h
index c735d51fe462..f2f67cb3eb7b 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_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
@@ -147,5 +147,14 @@ int cam_sync_destroy(int32_t sync_obj);
*/
int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms);
+/**
+ * @brief: Check if sync object is valid
+ *
+ * @param sync_obj: int referencing the sync object to be checked
+ *
+ * @return 0 upon success, -EINVAL if sync object is in bad state or arguments
+ * are invalid
+ */
+int cam_sync_check_valid(int32_t sync_obj);
#endif /* __CAM_SYNC_API_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 0f910c9e8273..185e0608e547 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
@@ -182,11 +182,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
int i;
int rc = 0;
int32_t hdl;
+ uint64_t requestId;
+ uint32_t num_patches;
/* process patch descriptor */
patch_desc = (struct cam_patch_desc *)
((uint32_t *) &packet->payload +
packet->patch_offset/4);
+ requestId = packet->header.request_id;
+ num_patches = packet->num_patches;
CAM_DBG(CAM_UTIL, "packet = %pK patch_desc = %pK size = %lu",
(void *)packet, (void *)patch_desc,
sizeof(struct cam_patch_desc));
@@ -197,7 +201,16 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
rc = cam_mem_get_io_buf(patch_desc[i].src_buf_hdl,
hdl, &iova_addr, &src_buf_size);
if (rc < 0) {
- CAM_ERR(CAM_UTIL, "unable to get src buf address");
+ CAM_ERR(CAM_UTIL,
+ "unable to get src buf address ReqId: %llu, num_patches = %d",
+ requestId, num_patches);
+ CAM_ERR(CAM_UTIL,
+ "i = %d patch info = %x %x %x %x src_bfsz:0x%x",
+ i, patch_desc[i].dst_buf_hdl,
+ patch_desc[i].dst_offset,
+ patch_desc[i].src_buf_hdl,
+ patch_desc[i].src_offset,
+ (uint32_t)src_buf_size);
return rc;
}
src_buf_iova_addr = (uint32_t *)iova_addr;
@@ -206,18 +219,37 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
rc = cam_mem_get_cpu_buf(patch_desc[i].dst_buf_hdl,
&cpu_addr, &dst_buf_len);
if (rc < 0 || !cpu_addr || (dst_buf_len == 0)) {
- CAM_ERR(CAM_UTIL, "unable to get dst buf address");
+ CAM_ERR(CAM_UTIL,
+ "unable to get dst buf address ReqId: %llu, num_patches = %d",
+ requestId, num_patches);
+ CAM_ERR(CAM_UTIL,
+ "i = %d patch info = %x %x %x %x dst_bfsz:0x%x",
+ i, patch_desc[i].dst_buf_hdl,
+ patch_desc[i].dst_offset,
+ patch_desc[i].src_buf_hdl,
+ patch_desc[i].src_offset,
+ (uint32_t)dst_buf_len);
return rc;
}
dst_cpu_addr = (uint32_t *)cpu_addr;
- CAM_DBG(CAM_UTIL, "i = %d patch info = %x %x %x %x", i,
- patch_desc[i].dst_buf_hdl, patch_desc[i].dst_offset,
+ CAM_DBG(CAM_UTIL,
+ "ReqId: %llu, i = %d patch info = %x %x %x %x",
+ requestId, i, patch_desc[i].dst_buf_hdl,
+ patch_desc[i].dst_offset,
patch_desc[i].src_buf_hdl, patch_desc[i].src_offset);
if ((size_t)patch_desc[i].src_offset >= src_buf_size) {
CAM_ERR(CAM_UTIL,
- "Invalid src buf patch offset");
+ "Invalid src buf patch offset ReqId: %llu, num_patches = %d",
+ requestId, num_patches);
+ CAM_ERR(CAM_UTIL,
+ "i = %d patch info = %x %x %x %x src_bfsz:0x%x",
+ i, patch_desc[i].dst_buf_hdl,
+ patch_desc[i].dst_offset,
+ patch_desc[i].src_buf_hdl,
+ patch_desc[i].src_offset,
+ (uint32_t)src_buf_size);
return -EINVAL;
}
@@ -225,7 +257,15 @@ int cam_packet_util_process_patches(struct cam_packet *packet,
((dst_buf_len - sizeof(void *)) <
(size_t)patch_desc[i].dst_offset)) {
CAM_ERR(CAM_UTIL,
- "Invalid dst buf patch offset");
+ "Invalid dst buf patch offset ReqId: %llu, num_patches = %d",
+ requestId, num_patches);
+ CAM_ERR(CAM_UTIL,
+ "i = %d patch info = %x %x %x %x dst_bfsz:0x%x",
+ i, patch_desc[i].dst_buf_hdl,
+ patch_desc[i].dst_offset,
+ patch_desc[i].src_buf_hdl,
+ patch_desc[i].src_offset,
+ (uint32_t)dst_buf_len);
return -EINVAL;
}
@@ -353,3 +393,115 @@ rel_cmd_buf:
return rc;
}
+
+int32_t cam_packet_validate_plane_size(
+ struct cam_buf_io_cfg *io_cfg,
+ int plane_index,
+ size_t size)
+{
+ int rc = 0;
+ uint32_t kmd_plane_size = 0;
+ uint32_t plane_stride = 0;
+ uint32_t slice_height = 0;
+ uint32_t metadata_size = 0;
+ uint32_t format = io_cfg->format;
+ uint32_t plane_pixel_size = 0;
+
+ if (plane_index < CAM_PACKET_MAX_PLANES) {
+ plane_stride = io_cfg->planes[plane_index].plane_stride;
+ slice_height = io_cfg->planes[plane_index].slice_height;
+ }
+
+ if (!(plane_stride && slice_height)) {
+ CAM_ERR(CAM_ISP,
+ "Invalid values from UMD stride %d, slice height %d",
+ plane_stride,
+ slice_height);
+ return -EINVAL;
+ }
+
+ switch (format) {
+ case CAM_FORMAT_MIPI_RAW_6:
+ case CAM_FORMAT_MIPI_RAW_8:
+ kmd_plane_size = ((plane_stride * slice_height) + 16 - 1)
+ / 16 * 16;
+ break;
+ case CAM_FORMAT_MIPI_RAW_10:
+ if (plane_stride % 4 == 0)
+ kmd_plane_size = ((plane_stride * slice_height)
+ + 16 - 1) / 16 * 16;
+ break;
+ case CAM_FORMAT_MIPI_RAW_12:
+ if (plane_stride % 2 == 0)
+ kmd_plane_size = ((plane_stride * slice_height)
+ + 16 - 1) / 16 * 16;
+ break;
+ case CAM_FORMAT_MIPI_RAW_14:
+ if (plane_stride % 4 == 0)
+ kmd_plane_size = plane_stride * slice_height * 7 / 4;
+ break;
+ case CAM_FORMAT_PLAIN16_8:
+ case CAM_FORMAT_PLAIN16_10:
+ case CAM_FORMAT_PLAIN16_12:
+ case CAM_FORMAT_PLAIN16_14:
+ case CAM_FORMAT_PLAIN16_16:
+ case CAM_FORMAT_PLAIN64:
+ kmd_plane_size = plane_stride * slice_height;
+ break;
+ case CAM_FORMAT_NV21:
+ case CAM_FORMAT_NV12:
+ if (plane_index < CAM_PACKET_MAX_PLANES)
+ kmd_plane_size = plane_stride * slice_height;
+ break;
+ case CAM_FORMAT_PD10:
+ if (plane_index < CAM_PACKET_MAX_PLANES)
+ kmd_plane_size = plane_stride * slice_height;
+ break;
+ case CAM_FORMAT_UBWC_NV12:
+ case CAM_FORMAT_UBWC_NV12_4R:
+ case CAM_FORMAT_UBWC_TP10:
+ metadata_size = io_cfg->planes[plane_index].meta_size;
+ plane_pixel_size = ((plane_stride * slice_height) +
+ (4096 - 1)) & ~((uint32_t) 4096 - 1);
+ kmd_plane_size = metadata_size + plane_pixel_size;
+ break;
+ case CAM_FORMAT_UBWC_P010:
+ case CAM_FORMAT_PLAIN32_20:
+ case CAM_FORMAT_TP10:
+ case CAM_FORMAT_YUV422:
+ case CAM_FORMAT_PD8:
+ case CAM_FORMAT_PLAIN128:
+ case CAM_FORMAT_ARGB:
+ case CAM_FORMAT_ARGB_10:
+ case CAM_FORMAT_ARGB_12:
+ case CAM_FORMAT_ARGB_14:
+ case CAM_FORMAT_MIPI_RAW_16:
+ case CAM_FORMAT_MIPI_RAW_20:
+ case CAM_FORMAT_QTI_RAW_8:
+ case CAM_FORMAT_QTI_RAW_10:
+ case CAM_FORMAT_QTI_RAW_12:
+ case CAM_FORMAT_QTI_RAW_14:
+ case CAM_FORMAT_PLAIN8:
+ case CAM_FORMAT_PLAIN8_SWAP:
+ case CAM_FORMAT_PLAIN8_10:
+ case CAM_FORMAT_PLAIN8_10_SWAP:
+ kmd_plane_size = plane_stride * slice_height;
+ break;
+ default:
+ kmd_plane_size = plane_stride * slice_height;
+ break;
+ }
+ if (!kmd_plane_size ||
+ kmd_plane_size > (size - io_cfg->offsets[plane_index])) {
+ CAM_ERR(CAM_ISP,
+ "kmd size: %d umd size: %zu width: %d height: %d stride: %d sliceheight: %d ",
+ kmd_plane_size,
+ size,
+ io_cfg->planes[plane_index].width,
+ io_cfg->planes[plane_index].height,
+ plane_stride,
+ slice_height);
+ return -EINVAL;
+ }
+ 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 33c07ad89f4e..e49968e6a291 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
@@ -135,4 +135,20 @@ int cam_packet_util_process_generic_cmd_buffer(
struct cam_cmd_buf_desc *cmd_buf,
cam_packet_generic_blob_handler blob_handler_cb, void *user_data);
+/**
+ * cam_packet_validate_plane_size()
+ *
+ * @brief: Utility function to calculate and validate size of buffer
+ * required for a format.
+ * @io_cfg: Contains IO config info
+ * @plane_index Plane index for which size is to be calculated
+ *
+ * @return: Size of buffer
+ *
+ */
+int32_t cam_packet_validate_plane_size(
+ struct cam_buf_io_cfg *io_cfg,
+ int plane_index,
+ size_t size);
+
#endif /* _CAM_PACKET_UTIL_H_ */
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 5b0cec43d3eb..6c2eebef23c5 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -370,6 +370,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id,
"hal_process_session_init_done: bad_pkt_size\n");
return -E2BIG;
}
+ if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32)
+ + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) {
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, pkt->size);
+ return -E2BIG;
+ }
data = (struct hfi_msg_release_buffer_ref_event_packet *)
pkt->rg_ext_event_data;
@@ -1558,15 +1564,13 @@ static int hfi_process_session_etb_done(u32 device_id,
struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt;
struct msm_vidc_cb_data_done data_done = {0};
struct hfi_picture_type *hfi_picture_type = NULL;
+ u32 is_sync_frame;
dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);
if (!pkt || pkt->size <
- sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
- dprintk(VIDC_ERR,
- "hal_process_session_etb_done: bad_pkt_size\n");
- return -E2BIG;
- }
+ sizeof(struct hfi_msg_session_empty_buffer_done_packet))
+ goto bad_packet_size;
data_done.device_id = device_id;
data_done.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -1586,8 +1590,13 @@ static int hfi_process_session_etb_done(u32 device_id,
data_done.input_done.extra_data_buffer = pkt->extra_data_buffer;
data_done.input_done.status =
hfi_map_err_status(pkt->error_type);
- hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
- if (hfi_picture_type->is_sync_frame) {
+ is_sync_frame = pkt->rgData[0];
+ if (is_sync_frame == 1) {
+ if (pkt->size <
+ sizeof(struct hfi_msg_session_empty_buffer_done_packet)
+ + sizeof(struct hfi_picture_type))
+ goto bad_packet_size;
+ hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1];
if (hfi_picture_type->picture_type)
data_done.input_done.flags =
hfi_picture_type->picture_type;
@@ -1604,6 +1613,10 @@ static int hfi_process_session_etb_done(u32 device_id,
info->response.data = data_done;
return 0;
+bad_packet_size:
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, pkt ? pkt->size : 0);
+ return -E2BIG;
}
static int hfi_process_session_ftb_done(
@@ -1838,13 +1851,8 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type);
- if (pkt->rg_buffer_info) {
- cmd_done.data.buffer_info =
- *(struct hal_buffer_info *)pkt->rg_buffer_info;
- cmd_done.size = sizeof(struct hal_buffer_info);
- } else {
- dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
- }
+ cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info;
+ cmd_done.size = sizeof(struct hal_buffer_info);
info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE;
info->response.cmd = cmd_done;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 0cfe6934520a..949eb0d4ab40 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -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
@@ -601,7 +601,7 @@ struct hfi_msg_session_empty_buffer_done_packet {
u32 extra_data_buffer;
u32 flags;
struct hfi_frame_cr_stats_type ubwc_cr_stats;
- u32 rgData[0];
+ u32 rgData[1];
};
struct hfi_msg_session_fill_buffer_done_compressed_packet {
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 77a2cc0b3d2c..44363f7f50b1 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -653,7 +653,6 @@ struct hfi_bit_depth {
};
struct hfi_picture_type {
- u32 is_sync_frame;
u32 picture_type;
};
diff --git a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
index 0e8f12369924..f6499e1584e4 100644
--- a/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
@@ -287,6 +287,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id,
"hal_process_session_init_done: bad_pkt_size\n");
return -E2BIG;
}
+ if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32)
+ + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) {
+ dprintk(VIDC_ERR,
+ "hfi_msg_release_buffer_ref_event: bad_pkt_size\n");
+ return -E2BIG;
+ }
data = (struct hfi_msg_release_buffer_ref_event_packet *)
pkt->rg_ext_event_data;
@@ -1540,15 +1546,13 @@ static int hfi_process_session_etb_done(u32 device_id,
struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt;
struct msm_vidc_cb_data_done data_done = {0};
struct hfi_picture_type *hfi_picture_type = NULL;
+ u32 is_sync_frame;
dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);
if (!pkt || pkt->size <
- sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
- dprintk(VIDC_ERR,
- "hal_process_session_etb_done: bad_pkt_size\n");
- return -E2BIG;
- }
+ sizeof(struct hfi_msg_session_empty_buffer_done_packet))
+ goto bad_packet_size;
data_done.device_id = device_id;
data_done.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -1563,8 +1567,13 @@ static int hfi_process_session_etb_done(u32 device_id,
(ion_phys_addr_t)pkt->extra_data_buffer;
data_done.input_done.status =
hfi_map_err_status(pkt->error_type);
- hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
- if (hfi_picture_type->is_sync_frame) {
+ is_sync_frame = pkt->rgData[0];
+ if (is_sync_frame == 1) {
+ if (pkt->size <
+ sizeof(struct hfi_msg_session_empty_buffer_done_packet)
+ + sizeof(struct hfi_picture_type))
+ goto bad_packet_size;
+ hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1];
if (hfi_picture_type->picture_type)
data_done.input_done.flags =
hfi_picture_type->picture_type;
@@ -1583,6 +1592,10 @@ static int hfi_process_session_etb_done(u32 device_id,
};
return 0;
+bad_packet_size:
+ dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n",
+ __func__, pkt ? pkt->size : 0);
+ return -E2BIG;
}
static int hfi_process_session_ftb_done(
@@ -1823,8 +1836,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type);
if (pkt->rg_buffer_info) {
- cmd_done.data.buffer_info =
- *(struct hal_buffer_info *)pkt->rg_buffer_info;
+ cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info;
cmd_done.size = sizeof(struct hal_buffer_info);
} else {
dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
diff --git a/drivers/media/platform/msm/vidc_3x/vidc_hfi.h b/drivers/media/platform/msm/vidc_3x/vidc_hfi.h
index d0fd4934e67a..903603bcac07 100644
--- a/drivers/media/platform/msm/vidc_3x/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc_3x/vidc_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -662,7 +662,7 @@ struct hfi_msg_session_empty_buffer_done_packet {
u32 input_tag;
u32 packet_buffer;
u32 extra_data_buffer;
- u32 rgData[0];
+ u32 rgData[1];
};
struct hfi_msg_session_fill_buffer_done_compressed_packet {
diff --git a/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h
index c09cf84c5d39..16c390a9781e 100644
--- a/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h
@@ -701,7 +701,6 @@ struct hfi_bit_depth {
};
struct hfi_picture_type {
- u32 is_sync_frame;
u32 picture_type;
};
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8c774bd72a6d..5f4716bb99e3 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -535,7 +535,7 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
smc_id = TZ_OS_APP_SHUTDOWN_ID;
desc.arginfo = TZ_OS_APP_SHUTDOWN_ID_PARAM_ID;
desc.args[0] = req->app_id;
- ret = __qseecom_scm_call2_locked(smc_id, &desc);
+ ret = scm_call2(smc_id, &desc);
break;
}
case QSEOS_APP_LOOKUP_COMMAND: {
@@ -1234,7 +1234,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
pr_debug("register %d has to wait\n",
rcvd_lstnr.listener_id);
mutex_unlock(&listener_access_lock);
- ret = wait_event_freezable(
+ ret = wait_event_interruptible(
qseecom.register_lsnr_pending_wq,
list_empty(
&qseecom.unregister_lsnr_pending_list_head));
@@ -1309,7 +1309,7 @@ static int __qseecom_unregister_listener(struct qseecom_dev_handle *data,
}
while (atomic_read(&data->ioctl_count) > 1) {
- if (wait_event_freezable(data->abort_wq,
+ if (wait_event_interruptible(data->abort_wq,
atomic_read(&data->ioctl_count) <= 1)) {
pr_err("Interrupted from abort\n");
ret = -ERESTARTSYS;
@@ -1417,7 +1417,7 @@ static void __wakeup_unregister_listener_kthread(void)
static int __qseecom_unregister_listener_kthread_func(void *data)
{
while (!kthread_should_stop()) {
- wait_event_freezable(
+ wait_event_interruptible(
qseecom.unregister_lsnr_kthread_wq,
atomic_read(&qseecom.unregister_lsnr_kthread_state)
== LSNR_UNREG_KT_WAKEUP);
@@ -1845,14 +1845,14 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
* send_resp_flag.
*/
if (!qseecom.qsee_reentrancy_support &&
- !wait_event_freezable(qseecom.send_resp_wq,
+ !wait_event_interruptible(qseecom.send_resp_wq,
__qseecom_listener_has_sent_rsp(
data, ptr_svc))) {
break;
}
if (qseecom.qsee_reentrancy_support &&
- !wait_event_freezable(qseecom.send_resp_wq,
+ !wait_event_interruptible(qseecom.send_resp_wq,
__qseecom_reentrancy_listener_has_sent_rsp(
data, ptr_svc))) {
break;
@@ -1953,6 +1953,7 @@ exit:
}
qseecom.app_block_ref_cnt--;
+ wake_up_interruptible_all(&qseecom.app_block_wq);
if (rc)
return rc;
@@ -2036,7 +2037,7 @@ static int __qseecom_process_reentrancy_blocked_on_listener(
ptr_app->app_blocked = true;
mutex_unlock(&listener_access_lock);
mutex_unlock(&app_access_lock);
- wait_event_freezable(
+ wait_event_interruptible(
list_ptr->listener_block_app_wq,
!list_ptr->listener_in_use);
mutex_lock(&app_access_lock);
@@ -2169,7 +2170,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
mutex_unlock(&listener_access_lock);
mutex_unlock(&app_access_lock);
do {
- if (!wait_event_freezable(qseecom.send_resp_wq,
+ if (!wait_event_interruptible(qseecom.send_resp_wq,
__qseecom_reentrancy_listener_has_sent_rsp(
data, ptr_svc))) {
break;
@@ -2305,23 +2306,15 @@ exit:
*/
static void __qseecom_reentrancy_check_if_no_app_blocked(uint32_t smc_id)
{
- sigset_t new_sigset, old_sigset;
-
if (qseecom.qsee_reentrancy_support > QSEE_REENTRANCY_PHASE_0 &&
qseecom.qsee_reentrancy_support < QSEE_REENTRANCY_PHASE_3 &&
IS_OWNER_TRUSTED_OS(TZ_SYSCALL_OWNER_ID(smc_id))) {
/* thread sleep until this app unblocked */
while (qseecom.app_block_ref_cnt > 0) {
- sigfillset(&new_sigset);
- sigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);
mutex_unlock(&app_access_lock);
- do {
- if (!wait_event_freezable(qseecom.app_block_wq,
- (qseecom.app_block_ref_cnt == 0)))
- break;
- } while (1);
+ wait_event_interruptible(qseecom.app_block_wq,
+ (!qseecom.app_block_ref_cnt));
mutex_lock(&app_access_lock);
- sigprocmask(SIG_SETMASK, &old_sigset, NULL);
}
}
}
@@ -2334,23 +2327,15 @@ static void __qseecom_reentrancy_check_if_no_app_blocked(uint32_t smc_id)
static void __qseecom_reentrancy_check_if_this_app_blocked(
struct qseecom_registered_app_list *ptr_app)
{
- sigset_t new_sigset, old_sigset;
-
if (qseecom.qsee_reentrancy_support) {
ptr_app->check_block++;
while (ptr_app->app_blocked || qseecom.app_block_ref_cnt > 1) {
/* thread sleep until this app unblocked */
- sigfillset(&new_sigset);
- sigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);
mutex_unlock(&app_access_lock);
- do {
- if (!wait_event_freezable(qseecom.app_block_wq,
- (!ptr_app->app_blocked &&
- qseecom.app_block_ref_cnt <= 1)))
- break;
- } while (1);
+ wait_event_interruptible(qseecom.app_block_wq,
+ (!ptr_app->app_blocked &&
+ qseecom.app_block_ref_cnt <= 1));
mutex_lock(&app_access_lock);
- sigprocmask(SIG_SETMASK, &old_sigset, NULL);
}
ptr_app->check_block--;
}
@@ -2675,7 +2660,7 @@ static int __qseecom_cleanup_app(struct qseecom_dev_handle *data)
if (qseecom.qsee_reentrancy_support)
mutex_unlock(&app_access_lock);
while (atomic_read(&data->ioctl_count) > 1) {
- if (wait_event_freezable(data->abort_wq,
+ if (wait_event_interruptible(data->abort_wq,
atomic_read(&data->ioctl_count) <= 1)) {
pr_err("Interrupted from abort\n");
ret = -ERESTARTSYS;
@@ -3252,7 +3237,7 @@ int __qseecom_process_reentrancy(struct qseecom_command_scm_resp *resp,
ret = __qseecom_reentrancy_process_incomplete_cmd(data, resp);
ptr_app->app_blocked = false;
qseecom.app_block_ref_cnt--;
- wake_up_interruptible(&qseecom.app_block_wq);
+ wake_up_interruptible_all(&qseecom.app_block_wq);
if (ret)
pr_err("process_incomplete_cmd failed err: %d\n",
ret);
@@ -4014,7 +3999,7 @@ static int qseecom_receive_req(struct qseecom_dev_handle *data)
mutex_unlock(&listener_access_lock);
while (1) {
- if (wait_event_freezable(this_lstnr->rcv_req_wq,
+ if (wait_event_interruptible(this_lstnr->rcv_req_wq,
__qseecom_listener_has_rcvd_req(data,
this_lstnr))) {
pr_warn("Interrupted: exiting Listener Service = %d\n",
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index cad75e76f1fe..c2946d840b68 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-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
@@ -641,6 +641,9 @@ static struct msm_soc_info cpu_of_id[] = {
/* QM215 ID */
[386] = {MSM_CPU_QM215, "QM215"},
+
+ /* QCM2150 ID */
+ [436] = {MSM_CPU_QCM2150, "QCM2150"},
/* Uninitialized IDs are not known to run Linux.
* MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
* considered as unknown CPU.
@@ -1636,6 +1639,10 @@ static void * __init setup_dummy_socinfo(void)
dummy_socinfo.id = 386;
strlcpy(dummy_socinfo.build_id, "qm215 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_qcm2150()) {
+ dummy_socinfo.id = 436;
+ strlcpy(dummy_socinfo.build_id, "qcm2150 - ",
+ sizeof(dummy_socinfo.build_id));
}
strlcat(dummy_socinfo.build_id, "Dummy socinfo",
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index 6352d54a0b87..bc390c8fec26 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -1911,7 +1911,7 @@ static void msm_geni_serial_set_termios(struct uart_port *uport,
break;
}
-
+ uport->status &= ~(UPSTAT_AUTOCTS);
/* stop bits */
if (termios->c_cflag & CSTOPB)
stop_bit_len = TX_STOP_BIT_LEN_2;
@@ -1919,8 +1919,10 @@ static void msm_geni_serial_set_termios(struct uart_port *uport,
stop_bit_len = TX_STOP_BIT_LEN_1;
/* flow control, clear the CTS_MASK bit if using flow control. */
- if (termios->c_cflag & CRTSCTS)
+ if (termios->c_cflag & CRTSCTS) {
tx_trans_cfg &= ~UART_CTS_MASK;
+ uport->status |= UPSTAT_AUTOCTS;
+ }
else
tx_trans_cfg |= UART_CTS_MASK;
/* status bits to ignore */
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 10ae7eb1e67a..47a2a7152794 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -44,6 +44,7 @@
#define DWC3_EP0_BOUNCE_SIZE 512
#define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2
+#define MAX_ERROR_RECOVERY_TRIES 3
#define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */
#define DWC3_EVENT_BUFFERS_SIZE 4096
@@ -1173,6 +1174,7 @@ struct dwc3 {
bool create_reg_debugfs;
u32 xhci_imod_value;
int core_id;
+ int retries_on_error;
};
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 985ad904255f..f54904764a0e 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.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
@@ -1860,8 +1860,13 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event,
reg |= DWC3_GCTL_CORESOFTRESET;
dwc3_msm_write_reg(mdwc->base, DWC3_GCTL, reg);
- /* restart USB which performs full reset and reconnect */
- schedule_work(&mdwc->restart_usb_work);
+ /*
+ * If the core could not recover after MAX_ERROR_RECOVERY_TRIES,
+ * skip the restart USB work and keep the core in softreset
+ * state.
+ */
+ if (dwc->retries_on_error < MAX_ERROR_RECOVERY_TRIES)
+ schedule_work(&mdwc->restart_usb_work);
break;
case DWC3_CONTROLLER_RESET_EVENT:
dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESET_EVENT received\n");
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index e6c89a3d807b..06c436a24461 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2032,6 +2032,13 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
} else {
dbg_event(0xFF, "Pullup_disable", is_on);
dwc3_gadget_disable_irq(dwc);
+
+ /*
+ * Reset the err_evt_seen so that the interrupts on
+ * next connect/session is processed correctly.
+ */
+ dwc->err_evt_seen = false;
+
__dwc3_gadget_ep_disable(dwc->eps[0]);
__dwc3_gadget_ep_disable(dwc->eps[1]);
@@ -3217,6 +3224,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
speed = reg & DWC3_DSTS_CONNECTSPD;
dwc->speed = speed;
+ /* Reset the retry on erratic error event count */
+ dwc->retries_on_error = 0;
dwc3_update_ram_clk_sel(dwc, speed);
switch (speed) {
@@ -3588,7 +3597,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
break;
case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
dwc3_trace(trace_dwc3_gadget, "Erratic Error");
- dbg_event(0xFF, "ERROR", 0);
+ dbg_event(0xFF, "ERROR", dwc->retries_on_error);
dwc->dbg_gadget_events.erratic_error++;
break;
case DWC3_DEVICE_EVENT_CMD_CMPL:
@@ -3670,6 +3679,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc)
if (dwc3_notify_event(dwc,
DWC3_CONTROLLER_ERROR_EVENT, 0))
dwc->err_evt_seen = 0;
+ dwc->retries_on_error++;
break;
}
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index 862153eae123..e8b2bb31f3b0 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -142,6 +142,8 @@
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,mdm9650")
#define early_machine_is_qm215() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qm215")
+#define early_machine_is_qcm2150() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcm2150")
#else
#define of_board_is_sim() 0
#define of_board_is_rumi() 0
@@ -201,6 +203,7 @@
#define early_machine_is_sda429() 0
#define early_machine_is_mdm9650() 0
#define early_machine_is_qm215() 0
+#define early_machine_is_qcm2150() 0
#define early_machine_is_sdm712() 0
#endif
@@ -285,6 +288,7 @@ enum msm_cpu {
MSM_CPU_SDA429,
MSM_CPU_9650,
MSM_CPU_QM215,
+ MSM_CPU_QCM2150,
};
struct msm_soc_info {
diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h
index 7489b72031b7..50d95c4da9d8 100644
--- a/include/uapi/media/cam_isp.h
+++ b/include/uapi/media/cam_isp.h
@@ -84,14 +84,16 @@
#define CAM_ISP_DSP_MODE_ROUND 2
/* ISP Generic Cmd Buffer Blob types */
-#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0
-#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1
-#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2
-#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
-#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10
+#define CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG 0
+#define CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG 1
+#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG 2
+#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
+#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10
+#define CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG 11
+#define CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG 12
/* Per Path Usage Data */
#define CAM_ISP_USAGE_INVALID 0
@@ -464,6 +466,36 @@ struct cam_fe_config {
uint32_t latency_buf_size;
} __attribute__((packed));
+/**
+ * struct cam_isp_sensor_path_dimension
+ *
+ * @width expected width
+ * @height expected height
+ * @measure_enabled flag to indicate if pixel measurement is to be enabled
+ */
+struct cam_isp_sensor_dimension {
+ uint32_t width;
+ uint32_t height;
+ uint32_t measure_enabled;
+} __attribute__((packed));
+
+/**
+ * struct cam_isp_sensor_config - Sensor Dimension configuration
+ *
+ * @pix_path: expected ppp path configuration
+ * @pix_path: expected ipp path configuration
+ * @rdi_path: expected rdi path configuration
+ * @hbi: HBI value
+ * @vbi: VBI value
+ */
+struct cam_isp_sensor_config {
+ struct cam_isp_sensor_dimension ppp_path;
+ struct cam_isp_sensor_dimension ipp_path;
+ struct cam_isp_sensor_dimension rdi_path[4];
+ uint32_t hbi;
+ uint32_t vbi;
+} __attribute__((packed));
+
/* Acquire Device/HW v2 */
/**
@@ -489,6 +521,15 @@ struct cam_isp_acquire_hw_info {
uint64_t data;
};
+/**
+ * struct cam_fps_config - FPS blob support
+ *
+ * @fps: FPS value
+ */
+struct cam_fps_config {
+ uint32_t fps;
+} __attribute__((packed));
+
#define CAM_ISP_ACQUIRE_COMMON_VER0 0x1000
#define CAM_ISP_ACQUIRE_COMMON_SIZE_VER0 0x0
diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h
index 8c8405391c7c..278bf12b7b14 100644
--- a/include/uapi/sound/compress_params.h
+++ b/include/uapi/sound/compress_params.h
@@ -406,6 +406,10 @@ struct snd_dec_aptx {
__u32 nap;
};
+struct snd_dec_amrwb_plus {
+ __u32 bit_stream_fmt;
+};
+
union snd_codec_options {
struct snd_enc_wma wma;
struct snd_enc_vorbis vorbis;
@@ -418,6 +422,7 @@ union snd_codec_options {
struct snd_dec_alac alac;
struct snd_dec_ape ape;
struct snd_dec_aptx aptx_dec;
+ struct snd_dec_amrwb_plus amrwbplus;
};
/** struct snd_codec_desc - description of codec capabilities
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e9bed0bd202d..07c511d6760d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8092,6 +8092,7 @@ int sched_cpu_starting(unsigned int cpu)
{
set_cpu_rq_start_time(cpu);
sched_rq_cpu_starting(cpu);
+ clear_walt_request(cpu);
return 0;
}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index fcb62fe15eee..55dcde161763 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3910,6 +3910,7 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
{
struct sched_entity *left = __pick_first_entity(cfs_rq);
struct sched_entity *se;
+ bool strict_skip = false;
/*
* If curr is set we have to see if its left of the leftmost entity
@@ -3929,13 +3930,16 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
if (se == curr) {
second = __pick_first_entity(cfs_rq);
+ if (sched_feat(STRICT_SKIP_BUDDY))
+ strict_skip = true;
} else {
second = __pick_next_entity(se);
if (!second || (curr && entity_before(curr, second)))
second = curr;
}
- if (second && wakeup_preempt_entity(second, left) < 1)
+ if (second && (strict_skip ||
+ wakeup_preempt_entity(second, left) < 1))
se = second;
}
@@ -6167,6 +6171,12 @@ static inline bool task_fits_max(struct task_struct *p, int cpu)
return __task_fits(p, cpu, 0);
}
+static inline bool cpu_check_overutil_condition(int cpu,
+ unsigned long util)
+{
+ return (capacity_orig_of(cpu) * 1024) < (util * capacity_margin);
+}
+
bool __cpu_overutilized(int cpu, int delta)
{
return (capacity_orig_of(cpu) * 1024) <
@@ -7016,7 +7026,7 @@ retry:
*/
min_capped_util = max(new_util, capacity_min_of(i));
- if (new_util > capacity_orig)
+ if (cpu_check_overutil_condition(i, new_util))
continue;
/*
@@ -8544,7 +8554,17 @@ redo:
if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed)
goto next;
- if ((load / 2) > env->imbalance)
+ /*
+ * p is not running task when we goes until here, so if p is one
+ * of the 2 task in src cpu rq and not the running one,
+ * that means it is the only task that can be balanced.
+ * So only when there is other tasks can be balanced or
+ * there is situation to ignore big task, it is needed
+ * to skip the task load bigger than 2*imbalance.
+ */
+ if (((cpu_rq(env->src_cpu)->nr_running > 2) ||
+ (env->flags & LBF_IGNORE_BIG_TASKS)) &&
+ ((load / 2) > env->imbalance))
goto next;
detach_task(p, env);
@@ -9948,8 +9968,10 @@ static int need_active_balance(struct lb_env *env)
* It's worth migrating the task if the src_cpu's capacity is reduced
* because of other sched_class or IRQs if more capacity stays
* available on dst_cpu.
+ * Avoid pulling the CFS task if it is the only task running.
*/
if ((env->idle != CPU_NOT_IDLE) &&
+ (env->src_rq->nr_running > 1) &&
(env->src_rq->cfs.h_nr_running == 1)) {
if ((check_cpu_capacity(env->src_rq, sd)) &&
(capacity_of(env->src_cpu)*sd->imbalance_pct < capacity_of(env->dst_cpu)*100))
@@ -10241,6 +10263,7 @@ no_move:
busiest->active_balance = 1;
busiest->push_cpu = this_cpu;
active_balance = 1;
+ mark_reserved(this_cpu);
}
raw_spin_unlock_irqrestore(&busiest->lock, flags);
@@ -10565,6 +10588,7 @@ out_unlock:
busiest_rq->active_balance = 0;
push_task = busiest_rq->push_task;
target_cpu = busiest_rq->push_cpu;
+ clear_reserved(target_cpu);
if (push_task)
busiest_rq->push_task = NULL;
@@ -10575,7 +10599,6 @@ out_unlock:
if (push_task_detached)
attach_one_task(target_rq, push_task);
put_task_struct(push_task);
- clear_reserved(target_cpu);
}
if (p)
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index ef52be469284..9f012ea5a3fc 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -26,6 +26,12 @@ SCHED_FEAT(NEXT_BUDDY, false)
SCHED_FEAT(LAST_BUDDY, true)
/*
+ * skip buddy i.e task called yield() is always skipped and the
+ * next entity is selected to run irrespective of the vruntime
+ */
+SCHED_FEAT(STRICT_SKIP_BUDDY, true)
+
+/*
* Consider buddies to be cache hot, decreases the likelyness of a
* cache buddy being migrated away, increases cache locality.
*/