msm: camera: Add camera support for apq8009
Initial snapshot of camera drivers are taken from msm-3.18 kernel
version @ 'commit cb28f8462e97 ("Merge PM / devfreq: memlat: Remove
kfree() on probe fails")'. Make required changes in camera
drivers to support camera modules on apq8009.
Change-Id: I3324684bcb866a9c67c1ba53d24fabd2bd98be43
Signed-off-by: Sundara Vinayagam <sundvi@codeaurora.org>
This commit is contained in:
parent
53de164494
commit
16b4b35144
24 changed files with 8192 additions and 265 deletions
|
|
@ -95,13 +95,22 @@ config MSM_EEPROM
|
|||
and also provides support for writing data in case of FLASH ROM.
|
||||
Currently supports I2C, CCI and SPI protocol
|
||||
|
||||
config MSM_ISP_V1
|
||||
bool "QTI MSM Image Signal Processing interface support"
|
||||
depends on MSMB_CAMERA
|
||||
---help---
|
||||
Enable support for Image Signal Processing interface module.
|
||||
This module acts as a crossbar between CSID and VFE. Output
|
||||
of any CID of CSID can be routed to of pix or raw
|
||||
data interface in VFE.
|
||||
|
||||
config MSM_ISPIF
|
||||
bool "QTI MSM Image Signal Processing interface support"
|
||||
depends on MSMB_CAMERA
|
||||
---help---
|
||||
Enable support for Image Signal Processing interface module.
|
||||
This module acts as a crossbar between CSID and VFE. Output
|
||||
of any CID of CSID can be routed to of of pix or raw
|
||||
of any CID of CSID can be routed to of pix or raw
|
||||
data interface in VFE.
|
||||
|
||||
config MSM_ISPIF_V1
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
#define EMPTY_QSEECOM_HANDLE NULL
|
||||
#define QSEECOM_SBUFF_SIZE SZ_128K
|
||||
|
||||
#define MSM_CAMERA_TZ_UTIL_VERBOSE
|
||||
|
||||
#define MSM_CAMERA_TZ_BOOT_PROTECTED (false)
|
||||
|
||||
/* Update version major number in case the HLOS-TA interface is changed*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
ccflags-y += -Idrivers/media/platform/msm/camera_v2
|
||||
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
|
||||
ccflags-y += -Idrivers/media/platform/msm/camera_v2/common/
|
||||
ifeq ($(CONFIG_MSM_ISP_V1),y)
|
||||
obj-$(CONFIG_MSMB_CAMERA) += msm_isp_32.o msm_buf_mgr.o msm_isp_util_32.o msm_isp_axi_util_32.o msm_isp_stats_util_32.o
|
||||
obj-$(CONFIG_MSMB_CAMERA) += msm_isp32.o
|
||||
else
|
||||
obj-$(CONFIG_MSMB_CAMERA) += msm_buf_mgr.o msm_isp_util.o msm_isp_axi_util.o msm_isp_stats_util.o
|
||||
obj-$(CONFIG_MSMB_CAMERA) += msm_isp48.o msm_isp47.o msm_isp46.o msm_isp44.o msm_isp40.o msm_isp.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -189,7 +189,9 @@ static int msm_isp_prepare_v4l2_buf(struct msm_isp_buf_mgr *buf_mgr,
|
|||
int i, rc = -1;
|
||||
int ret;
|
||||
struct msm_isp_buffer_mapped_info *mapped_info;
|
||||
#ifndef CONFIG_MSM_ISP_V1
|
||||
uint32_t accu_length = 0;
|
||||
#endif
|
||||
struct msm_isp_bufq *bufq = NULL;
|
||||
|
||||
bufq = msm_isp_get_bufq(buf_mgr, buf_info->bufq_handle);
|
||||
|
|
@ -228,8 +230,12 @@ static int msm_isp_prepare_v4l2_buf(struct msm_isp_buf_mgr *buf_mgr,
|
|||
goto get_phy_err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MSM_ISP_V1
|
||||
mapped_info->paddr += qbuf_buf->planes[i].offset;
|
||||
#else
|
||||
mapped_info->paddr += accu_length;
|
||||
accu_length += qbuf_buf->planes[i].length;
|
||||
#endif
|
||||
|
||||
CDBG("%s: plane: %d addr:%pK\n",
|
||||
__func__, i, (void *)mapped_info->paddr);
|
||||
|
|
@ -732,10 +738,17 @@ static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr,
|
|||
spin_lock_irqsave(&bufq->bufq_lock, flags);
|
||||
|
||||
buf_info->frame_id = frame_id;
|
||||
#ifdef CONFIG_MSM_ISP_V1
|
||||
if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
|
||||
buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
|
||||
buf_info->tv = tv;
|
||||
}
|
||||
#else
|
||||
if (BUF_SRC(bufq->stream_id) == MSM_ISP_BUFFER_SRC_NATIVE) {
|
||||
buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
|
||||
buf_info->tv = tv;
|
||||
}
|
||||
#endif
|
||||
spin_unlock_irqrestore(&bufq->bufq_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1077,7 +1090,6 @@ static void msm_isp_release_all_bufq(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* msm_isp_buf_put_scratch() - Release scratch buffers
|
||||
* @buf_mgr: The buffer structure for h/w
|
||||
|
|
@ -1220,7 +1232,6 @@ err1:
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int msm_isp_init_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,
|
||||
const char *ctx_name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,21 +12,15 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "msm_isp32.h"
|
||||
#include "msm_isp_util.h"
|
||||
#include "msm_isp_axi_util.h"
|
||||
#include "msm_isp_stats_util.h"
|
||||
#include "msm_isp.h"
|
||||
#include "msm_isp_util_32.h"
|
||||
#include "msm_isp_axi_util_32.h"
|
||||
#include "msm_isp_stats_util_32.h"
|
||||
#include "msm_isp_32.h"
|
||||
#include "msm.h"
|
||||
#include "msm_camera_io_util.h"
|
||||
|
||||
static const struct platform_device_id msm_vfe32_dev_id[] = {
|
||||
{"msm_vfe32", (kernel_ulong_t) &vfe32_hw_info},
|
||||
{}
|
||||
};
|
||||
|
||||
#define VFE32_BURST_LEN 2
|
||||
#define VFE32_BURST_LEN 3
|
||||
#define VFE32_UB_SIZE 1024
|
||||
#define VFE32_UB_SIZE_32KB 2048
|
||||
#define VFE32_EQUAL_SLICE_UB 194
|
||||
|
|
@ -36,7 +30,7 @@ static const struct platform_device_id msm_vfe32_dev_id[] = {
|
|||
#define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4))
|
||||
#define VFE32_XBAR_SHIFT(idx) ((idx % 4) * 8)
|
||||
#define VFE32_PING_PONG_BASE(wm, ping_pong) \
|
||||
(VFE32_WM_BASE(wm) + 0x4 * (1 + ((~ping_pong) & 0x1)))
|
||||
(VFE32_WM_BASE(wm) + 0x4 * (1 + (~(ping_pong >> wm) & 0x1)))
|
||||
|
||||
static uint8_t stats_pingpong_offset_map[] = {
|
||||
7, 8, 9, 10, 11, 12, 13};
|
||||
|
|
@ -60,16 +54,6 @@ static struct msm_cam_clk_info msm_vfe32_2_clk_info[] = {
|
|||
{"csi_vfe_clk", -1},
|
||||
};
|
||||
|
||||
static uint32_t msm_vfe32_ub_reg_offset(struct vfe_device *vfe_dev, int idx)
|
||||
{
|
||||
return (VFE32_WM_BASE(idx) + 0x10);
|
||||
}
|
||||
|
||||
static uint32_t msm_vfe32_get_ub_size(struct vfe_device *vfe_dev)
|
||||
{
|
||||
return MSM_ISP32_TOTAL_WM_UB;
|
||||
}
|
||||
|
||||
static int32_t msm_vfe32_init_qos_parms(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_hw_init_parms *qos_parms,
|
||||
struct msm_vfe_hw_init_parms *ds_parms)
|
||||
|
|
@ -284,8 +268,6 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev)
|
|||
pr_err("%s: vfe ioremap failed\n", __func__);
|
||||
goto vfe_remap_failed;
|
||||
}
|
||||
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] =
|
||||
vfe_dev->vfe_base;
|
||||
|
||||
vfe_dev->vfe_vbif_base = ioremap(vfe_dev->vfe_vbif_mem->start,
|
||||
resource_size(vfe_dev->vfe_vbif_mem));
|
||||
|
|
@ -330,14 +312,12 @@ bus_scale_register_failed:
|
|||
|
||||
static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
|
||||
{
|
||||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1C);
|
||||
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x20);
|
||||
disable_irq(vfe_dev->vfe_irq->start);
|
||||
free_irq(vfe_dev->vfe_irq->start, vfe_dev);
|
||||
tasklet_kill(&vfe_dev->vfe_tasklet);
|
||||
msm_isp_flush_tasklet(vfe_dev);
|
||||
iounmap(vfe_dev->vfe_vbif_base);
|
||||
vfe_dev->vfe_vbif_base = NULL;
|
||||
iounmap(vfe_dev->vfe_base);
|
||||
vfe_dev->vfe_base = NULL;
|
||||
if (vfe_dev->vfe_clk_idx == 1)
|
||||
msm_cam_clk_enable(&vfe_dev->pdev->dev,
|
||||
msm_vfe32_1_clk_info, vfe_dev->vfe_clk,
|
||||
|
|
@ -346,9 +326,6 @@ static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev)
|
|||
msm_cam_clk_enable(&vfe_dev->pdev->dev,
|
||||
msm_vfe32_2_clk_info, vfe_dev->vfe_clk,
|
||||
ARRAY_SIZE(msm_vfe32_2_clk_info), 0);
|
||||
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
|
||||
iounmap(vfe_dev->vfe_base);
|
||||
vfe_dev->vfe_base = NULL;
|
||||
kfree(vfe_dev->vfe_clk);
|
||||
regulator_disable(vfe_dev->fs_vfe);
|
||||
msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
|
||||
|
|
@ -369,7 +346,6 @@ static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
|
|||
ds_parms.entries = "ds-entries";
|
||||
ds_parms.regs = "ds-regs";
|
||||
ds_parms.settings = "ds-settings";
|
||||
|
||||
msm_vfe32_init_qos_parms(vfe_dev, &qos_parms, &ds_parms);
|
||||
msm_vfe32_init_vbif_parms(vfe_dev, &vbif_parms);
|
||||
|
||||
|
|
@ -381,6 +357,11 @@ static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev)
|
|||
msm_camera_io_w_mb(0x1CFFFFFF, vfe_dev->vfe_base + 0x20);
|
||||
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x24);
|
||||
msm_camera_io_w_mb(0x1FFFFFFF, vfe_dev->vfe_base + 0x28);
|
||||
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x6FC);
|
||||
msm_camera_io_w(0x10000000, vfe_dev->vfe_base + VFE32_RDI_BASE(1));
|
||||
msm_camera_io_w(0x10000000, vfe_dev->vfe_base + VFE32_RDI_BASE(2));
|
||||
msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(0));
|
||||
msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(4));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -396,13 +377,30 @@ static void msm_vfe32_clear_status_reg(struct vfe_device *vfe_dev)
|
|||
static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1)
|
||||
{
|
||||
if (irq_status1 & BIT(23))
|
||||
if (irq_status1 & BIT(23)) {
|
||||
if (vfe_dev->vfe_reset_timeout_processed == 1) {
|
||||
pr_err("%s:vfe reset was processed.\n", __func__);
|
||||
return;
|
||||
}
|
||||
complete(&vfe_dev->reset_complete);
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_halt_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1)
|
||||
{
|
||||
if (irq_status1 & (1 << 24))
|
||||
msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x1D8);
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_epoch_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
{
|
||||
if (!(irq_status0 & 0x18))
|
||||
return;
|
||||
if (irq_status0 & (1 << 3))
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
|
||||
|
|
@ -416,10 +414,12 @@ static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
|
|||
ISP_DBG("%s: SOF IRQ\n", __func__);
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
|
||||
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
|
||||
stream_count == 0) {
|
||||
pix_stream_count == 0) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
|
||||
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0, ts);
|
||||
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
|
||||
if (vfe_dev->axi_data.stream_update)
|
||||
msm_isp_axi_stream_update(vfe_dev,
|
||||
(1 << VFE_PIX_0));
|
||||
msm_isp_update_framedrop_reg(vfe_dev, (1 << VFE_PIX_0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -485,7 +485,20 @@ static void msm_vfe32_process_violation_status(struct vfe_device *vfe_dev)
|
|||
|
||||
static void msm_vfe32_get_overflow_mask(uint32_t *overflow_mask)
|
||||
{
|
||||
*overflow_mask = 0x0;
|
||||
*overflow_mask = 0x003FFF7E;
|
||||
}
|
||||
|
||||
static void msm_vfe32_get_rdi_wm_mask(struct vfe_device *vfe_dev,
|
||||
uint32_t *rdi_wm_mask)
|
||||
{
|
||||
*rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask;
|
||||
}
|
||||
|
||||
static void msm_vfe32_get_irq_mask(struct vfe_device *vfe_dev,
|
||||
uint32_t *irq0_mask, uint32_t *irq1_mask)
|
||||
{
|
||||
*irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
*irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
|
||||
|
|
@ -571,7 +584,7 @@ static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev)
|
|||
pr_err("%s: axi error\n", __func__);
|
||||
}
|
||||
|
||||
static void msm_vfe32_read_and_clear_irq_status(struct vfe_device *vfe_dev,
|
||||
static void msm_vfe32_read_irq_status(struct vfe_device *vfe_dev,
|
||||
uint32_t *irq_status0, uint32_t *irq_status1)
|
||||
{
|
||||
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
|
||||
|
|
@ -589,122 +602,127 @@ static void msm_vfe32_read_and_clear_irq_status(struct vfe_device *vfe_dev,
|
|||
msm_camera_io_r(vfe_dev->vfe_base + 0x7B4);
|
||||
}
|
||||
|
||||
static void msm_vfe32_read_irq_status(struct vfe_device *vfe_dev,
|
||||
uint32_t *irq_status0, uint32_t irq_status1)
|
||||
{
|
||||
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x2C);
|
||||
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30);
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
{
|
||||
uint32_t rdi_status;
|
||||
enum msm_vfe_input_src i;
|
||||
uint8_t input_src = 0x0;
|
||||
|
||||
if (!(irq_status0 & 0x20) && !(irq_status1 & 0x1C000000))
|
||||
return;
|
||||
|
||||
if (irq_status0 & BIT(5)) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev,
|
||||
VFE_PIX_0);
|
||||
if (vfe_dev->axi_data.stream_update[VFE_PIX_0]) {
|
||||
rdi_status = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
VFE32_XBAR_BASE(0));
|
||||
rdi_status |= msm_camera_io_r(vfe_dev->vfe_base +
|
||||
VFE32_XBAR_BASE(4));
|
||||
|
||||
if ((rdi_status & BIT(7)) && (!(irq_status0 & 0x20)))
|
||||
return;
|
||||
}
|
||||
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
|
||||
MSM_ISP_COMP_IRQ_REG_UPD);
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE, VFE_PIX_0, ts);
|
||||
input_src |= (1 << VFE_PIX_0);
|
||||
}
|
||||
if (irq_status1 & BIT(26)) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_0, ts);
|
||||
input_src |= (1 << VFE_RAW_0);
|
||||
}
|
||||
if (irq_status1 & BIT(27)) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_1, ts);
|
||||
input_src |= (1 << VFE_RAW_1);
|
||||
}
|
||||
if (irq_status1 & BIT(28)) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_2, ts);
|
||||
input_src |= (1 << VFE_RAW_2);
|
||||
}
|
||||
|
||||
for (i = VFE_RAW_0; i <= VFE_RAW_2; i++) {
|
||||
if (irq_status1 & BIT(26 + (i - VFE_RAW_0))) {
|
||||
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
|
||||
msm_isp_axi_stream_update(vfe_dev, i, ts);
|
||||
msm_isp_update_framedrop_reg(vfe_dev, i);
|
||||
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev,
|
||||
i);
|
||||
if (vfe_dev->axi_data.stream_update)
|
||||
msm_isp_axi_stream_update(vfe_dev, input_src);
|
||||
if (atomic_read(&vfe_dev->stats_data.stats_update))
|
||||
msm_isp_stats_stream_update(vfe_dev);
|
||||
if (vfe_dev->axi_data.stream_update ||
|
||||
atomic_read(&vfe_dev->stats_data.stats_update)) {
|
||||
if (input_src & (1 << VFE_PIX_0)) {
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.
|
||||
reg_update(vfe_dev, (1 << VFE_PIX_0));
|
||||
}
|
||||
}
|
||||
|
||||
msm_isp_update_framedrop_reg(vfe_dev, input_src);
|
||||
msm_isp_update_stats_framedrop_reg(vfe_dev);
|
||||
msm_isp_update_error_frame_count(vfe_dev);
|
||||
|
||||
}
|
||||
|
||||
static void msm_vfe32_process_epoch_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
{
|
||||
/* Not supported */
|
||||
}
|
||||
|
||||
static void msm_vfe32_reg_update(struct vfe_device *vfe_dev,
|
||||
enum msm_vfe_input_src frame_src)
|
||||
{
|
||||
if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) {
|
||||
msm_camera_io_w_mb(0xF,
|
||||
vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]
|
||||
+ 0x260);
|
||||
msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260);
|
||||
} else if (!vfe_dev->is_split) {
|
||||
msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260);
|
||||
if ((input_src & (1 << VFE_RAW_0)) ||
|
||||
(input_src & (1 << VFE_RAW_1)) ||
|
||||
(input_src & (1 << VFE_RAW_2))) {
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.
|
||||
reg_update(vfe_dev, input_src);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_reg_update(
|
||||
struct vfe_device *vfe_dev, uint32_t input_src)
|
||||
{
|
||||
msm_camera_io_w_mb(input_src, vfe_dev->vfe_base + 0x260);
|
||||
}
|
||||
|
||||
static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev,
|
||||
uint32_t first_start, uint32_t blocking)
|
||||
{
|
||||
init_completion(&vfe_dev->reset_complete);
|
||||
msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
|
||||
return wait_for_completion_timeout(
|
||||
&vfe_dev->reset_complete, msecs_to_jiffies(50));
|
||||
long rc = 0;
|
||||
uint32_t irq_status1;
|
||||
|
||||
if (blocking) {
|
||||
init_completion(&vfe_dev->reset_complete);
|
||||
msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
|
||||
vfe_dev->vfe_reset_timeout_processed = 0;
|
||||
rc = wait_for_completion_timeout(
|
||||
&vfe_dev->reset_complete, msecs_to_jiffies(500));
|
||||
} else {
|
||||
msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4);
|
||||
}
|
||||
|
||||
if (blocking && rc <= 0) {
|
||||
/*read ISP status register*/
|
||||
irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30);
|
||||
pr_err("%s: handling vfe reset time out error. irq_status1 0x%x\n",
|
||||
__func__, irq_status1);
|
||||
if (irq_status1 & BIT(23)) {
|
||||
pr_err("%s: vfe reset has done actually\n", __func__);
|
||||
vfe_dev->vfe_reset_timeout_processed = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_reload_wm(
|
||||
struct vfe_device *vfe_dev, void __iomem *vfe_base,
|
||||
uint32_t reload_mask)
|
||||
struct vfe_device *vfe_dev, uint32_t reload_mask)
|
||||
{
|
||||
if (!vfe_dev->pdev->dev.of_node) {
|
||||
/*vfe32 A-family: 8960*/
|
||||
msm_camera_io_w_mb(reload_mask, vfe_base + 0x38);
|
||||
msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38);
|
||||
} else {
|
||||
/*vfe32 B-family: 8610*/
|
||||
msm_camera_io_w(0x0, vfe_base + 0x24);
|
||||
msm_camera_io_w(0x0, vfe_base + 0x28);
|
||||
msm_camera_io_w(0x0, vfe_base + 0x20);
|
||||
msm_camera_io_w_mb(0x1, vfe_base + 0x18);
|
||||
msm_camera_io_w(0x9AAAAAAA, vfe_base + 0x600);
|
||||
msm_camera_io_w(reload_mask, vfe_base + 0x38);
|
||||
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x28);
|
||||
msm_camera_io_w(0x1C800000, vfe_dev->vfe_base + 0x20);
|
||||
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x18);
|
||||
msm_camera_io_w(0x9AAAAAAA, vfe_dev->vfe_base + 0x600);
|
||||
msm_camera_io_w(reload_mask, vfe_dev->vfe_base + 0x38);
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_enable_wm(void __iomem *vfe_base,
|
||||
static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev,
|
||||
uint8_t wm_idx, uint8_t enable)
|
||||
{
|
||||
uint32_t val = msm_camera_io_r(
|
||||
vfe_base + VFE32_WM_BASE(wm_idx));
|
||||
vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
|
||||
if (enable)
|
||||
val |= 0x1;
|
||||
else
|
||||
val &= ~0x1;
|
||||
msm_camera_io_w_mb(val,
|
||||
vfe_base + VFE32_WM_BASE(wm_idx));
|
||||
vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx));
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info)
|
||||
{
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
uint32_t comp_mask, comp_mask_index =
|
||||
stream_info->comp_mask_index[vfe_idx];
|
||||
stream_info->comp_mask_index;
|
||||
uint32_t irq_mask;
|
||||
|
||||
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
|
||||
|
|
@ -721,9 +739,7 @@ static void msm_vfe32_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
|
|||
static void msm_vfe32_axi_clear_comp_mask(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info)
|
||||
{
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
uint32_t comp_mask, comp_mask_index =
|
||||
stream_info->comp_mask_index[vfe_idx];
|
||||
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
|
||||
uint32_t irq_mask;
|
||||
|
||||
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
|
||||
|
|
@ -739,10 +755,9 @@ static void msm_vfe32_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
|
|||
struct msm_vfe_axi_stream *stream_info)
|
||||
{
|
||||
uint32_t irq_mask;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
|
||||
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
irq_mask |= BIT(stream_info->wm[vfe_idx][0] + 6);
|
||||
irq_mask |= BIT(stream_info->wm[0] + 6);
|
||||
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
|
||||
}
|
||||
|
||||
|
|
@ -750,31 +765,40 @@ static void msm_vfe32_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
|
|||
struct msm_vfe_axi_stream *stream_info)
|
||||
{
|
||||
uint32_t irq_mask;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
|
||||
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
irq_mask &= ~BIT(stream_info->wm[vfe_idx][0] + 6);
|
||||
irq_mask &= ~BIT(stream_info->wm[0] + 6);
|
||||
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
|
||||
}
|
||||
|
||||
static void msm_vfe32_cfg_framedrop(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
|
||||
uint32_t framedrop_period)
|
||||
struct msm_vfe_axi_stream *stream_info)
|
||||
{
|
||||
void __iomem *vfe_base = vfe_dev->vfe_base;
|
||||
uint32_t framedrop_pattern = 0, framedrop_period = 0;
|
||||
|
||||
if (stream_info->runtime_init_frame_drop == 0) {
|
||||
framedrop_pattern = stream_info->framedrop_pattern;
|
||||
framedrop_period = stream_info->framedrop_period;
|
||||
}
|
||||
|
||||
if (stream_info->stream_type == BURST_STREAM &&
|
||||
stream_info->runtime_burst_frame_count == 0) {
|
||||
framedrop_pattern = 0;
|
||||
framedrop_period = 0;
|
||||
}
|
||||
|
||||
if (stream_info->stream_src == PIX_ENCODER) {
|
||||
msm_camera_io_w(framedrop_period - 1, vfe_base + 0x504);
|
||||
msm_camera_io_w(framedrop_period - 1, vfe_base + 0x508);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_base + 0x50C);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_base + 0x510);
|
||||
msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x504);
|
||||
msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x508);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x50C);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x510);
|
||||
} else if (stream_info->stream_src == PIX_VIEWFINDER) {
|
||||
msm_camera_io_w(framedrop_period - 1, vfe_base + 0x514);
|
||||
msm_camera_io_w(framedrop_period - 1, vfe_base + 0x518);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_base + 0x51C);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_base + 0x520);
|
||||
msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x514);
|
||||
msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x518);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x51C);
|
||||
msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x520);
|
||||
}
|
||||
msm_camera_io_w_mb(0x1, vfe_base + 0x260);
|
||||
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x260);
|
||||
}
|
||||
|
||||
static void msm_vfe32_clear_framedrop(struct vfe_device *vfe_dev,
|
||||
|
|
@ -877,6 +901,7 @@ static void msm_vfe32_cfg_fetch_engine(struct vfe_device *vfe_dev,
|
|||
struct msm_vfe_pix_cfg *pix_cfg)
|
||||
{
|
||||
pr_err("%s: Fetch engine not supported\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_cfg_camif(struct vfe_device *vfe_dev,
|
||||
|
|
@ -924,6 +949,7 @@ static void msm_vfe32_cfg_input_mux(struct vfe_device *vfe_dev,
|
|||
pr_err("%s: Unsupported input mux %d\n",
|
||||
__func__, pix_cfg->input_mux);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_update_camif_state(
|
||||
|
|
@ -938,19 +964,20 @@ static void msm_vfe32_update_camif_state(
|
|||
|
||||
if (update_state == ENABLE_CAMIF) {
|
||||
val = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
val |= 0x1;
|
||||
val |= 0x19;
|
||||
msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x1C);
|
||||
|
||||
msm_camera_io_w_mb(0xA, vfe_dev->vfe_base + 0x200);
|
||||
val = msm_camera_io_r(vfe_dev->vfe_base + 0x1E4);
|
||||
bus_en =
|
||||
((vfe_dev->axi_data.src_info[
|
||||
VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
|
||||
vfe_en =
|
||||
((vfe_dev->axi_data.src_info[
|
||||
VFE_PIX_0].stream_count > 0) ? 1 : 0);
|
||||
VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
|
||||
val &= 0xFFFFFF3F;
|
||||
val = val | bus_en << 7 | vfe_en << 6;
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + 0x1E4);
|
||||
msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x1E0);
|
||||
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1E0);
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
|
||||
} else if (update_state == DISABLE_CAMIF) {
|
||||
|
|
@ -990,17 +1017,16 @@ static void msm_vfe32_axi_cfg_wm_reg(
|
|||
uint8_t plane_idx)
|
||||
{
|
||||
uint32_t val;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
|
||||
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
|
||||
|
||||
if (!stream_info->frame_based) {
|
||||
/*WR_IMAGE_SIZE*/
|
||||
val =
|
||||
((msm_isp_cal_word_per_line(
|
||||
stream_info->output_format,
|
||||
stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
stream_info->plane_cfg[plane_idx].
|
||||
output_width)+1)/2 - 1) << 16 |
|
||||
(stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
(stream_info->plane_cfg[plane_idx].
|
||||
output_height - 1);
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
|
||||
|
||||
|
|
@ -1008,9 +1034,9 @@ static void msm_vfe32_axi_cfg_wm_reg(
|
|||
val =
|
||||
msm_isp_cal_word_per_line(
|
||||
stream_info->output_format,
|
||||
stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
stream_info->plane_cfg[plane_idx].
|
||||
output_stride) << 16 |
|
||||
(stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
(stream_info->plane_cfg[plane_idx].
|
||||
output_height - 1) << 4 | VFE32_BURST_LEN;
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
|
||||
} else {
|
||||
|
|
@ -1018,12 +1044,13 @@ static void msm_vfe32_axi_cfg_wm_reg(
|
|||
val =
|
||||
msm_isp_cal_word_per_line(
|
||||
stream_info->output_format,
|
||||
stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
stream_info->plane_cfg[plane_idx].
|
||||
output_width) << 16 |
|
||||
(stream_info->plane_cfg[vfe_idx][plane_idx].
|
||||
(stream_info->plane_cfg[plane_idx].
|
||||
output_height - 1) << 4 | VFE32_BURST_LEN;
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_clear_wm_reg(
|
||||
|
|
@ -1031,22 +1058,24 @@ static void msm_vfe32_axi_clear_wm_reg(
|
|||
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
|
||||
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
|
||||
|
||||
/* FRAME BASED */
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base);
|
||||
/*WR_IMAGE_SIZE*/
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
|
||||
/*WR_BUFFER_CFG*/
|
||||
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_cfg_wm_xbar_reg(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
|
||||
{
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
struct msm_vfe_axi_plane_cfg *plane_cfg =
|
||||
&stream_info->plane_cfg[vfe_idx][plane_idx];
|
||||
uint8_t wm = stream_info->wm[vfe_idx][plane_idx];
|
||||
&stream_info->plane_cfg[plane_idx];
|
||||
uint8_t wm = stream_info->wm[plane_idx];
|
||||
uint32_t xbar_cfg = 0;
|
||||
uint32_t xbar_reg_cfg = 0;
|
||||
|
||||
|
|
@ -1093,14 +1122,14 @@ static void msm_vfe32_axi_cfg_wm_xbar_reg(
|
|||
xbar_reg_cfg &= ~(0xFF << VFE32_XBAR_SHIFT(wm));
|
||||
xbar_reg_cfg |= (xbar_cfg << VFE32_XBAR_SHIFT(wm));
|
||||
msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_axi_clear_wm_xbar_reg(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
|
||||
{
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
|
||||
uint8_t wm = stream_info->wm[vfe_idx][plane_idx];
|
||||
uint8_t wm = stream_info->wm[plane_idx];
|
||||
uint32_t xbar_reg_cfg = 0;
|
||||
|
||||
xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
|
||||
|
|
@ -1108,21 +1137,95 @@ static void msm_vfe32_axi_clear_wm_xbar_reg(
|
|||
msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
|
||||
}
|
||||
|
||||
static void msm_vfe32_update_ping_pong_addr(void __iomem *vfe_base,
|
||||
uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr,
|
||||
int32_t buf_size)
|
||||
static void msm_vfe32_cfg_axi_ub_equal_default(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int i;
|
||||
uint32_t ub_offset = 0;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
uint32_t total_image_size = 0;
|
||||
uint32_t num_used_wms = 0;
|
||||
uint32_t prop_size = 0;
|
||||
uint32_t wm_ub_size;
|
||||
uint64_t delta;
|
||||
|
||||
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
|
||||
if (axi_data->free_wm[i] > 0) {
|
||||
num_used_wms++;
|
||||
total_image_size += axi_data->wm_image_size[i];
|
||||
}
|
||||
}
|
||||
prop_size = MSM_ISP32_TOTAL_WM_UB -
|
||||
axi_data->hw_info->min_wm_ub * num_used_wms;
|
||||
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
|
||||
if (axi_data->free_wm[i]) {
|
||||
delta =
|
||||
(uint64_t)(axi_data->wm_image_size[i] *
|
||||
prop_size);
|
||||
do_div(delta, total_image_size);
|
||||
wm_ub_size = axi_data->hw_info->min_wm_ub +
|
||||
(uint32_t)delta;
|
||||
msm_camera_io_w(ub_offset << 16 |
|
||||
(wm_ub_size - 1), vfe_dev->vfe_base +
|
||||
VFE32_WM_BASE(i) + 0xC);
|
||||
ub_offset += wm_ub_size;
|
||||
} else {
|
||||
msm_camera_io_w(0,
|
||||
vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_vfe32_cfg_axi_ub_equal_slicing(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int i;
|
||||
uint32_t ub_offset = 0;
|
||||
uint32_t final_ub_slice_size;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
|
||||
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
|
||||
if (ub_offset + VFE32_EQUAL_SLICE_UB > VFE32_AXI_SLICE_UB) {
|
||||
final_ub_slice_size = VFE32_AXI_SLICE_UB - ub_offset;
|
||||
msm_camera_io_w(ub_offset << 16 |
|
||||
(final_ub_slice_size - 1), vfe_dev->vfe_base +
|
||||
VFE32_WM_BASE(i) + 0xC);
|
||||
ub_offset += final_ub_slice_size;
|
||||
} else {
|
||||
msm_camera_io_w(ub_offset << 16 |
|
||||
(VFE32_EQUAL_SLICE_UB - 1), vfe_dev->vfe_base +
|
||||
VFE32_WM_BASE(i) + 0xC);
|
||||
ub_offset += VFE32_EQUAL_SLICE_UB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev)
|
||||
{
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
|
||||
axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT;
|
||||
if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING)
|
||||
msm_vfe32_cfg_axi_ub_equal_slicing(vfe_dev);
|
||||
else
|
||||
msm_vfe32_cfg_axi_ub_equal_default(vfe_dev);
|
||||
}
|
||||
|
||||
static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev,
|
||||
uint8_t wm_idx, uint32_t pingpong_status, dma_addr_t paddr)
|
||||
{
|
||||
uint32_t paddr32 = (paddr & 0xFFFFFFFF);
|
||||
|
||||
msm_camera_io_w(paddr32, vfe_base +
|
||||
VFE32_PING_PONG_BASE(wm_idx, pingpong_bit));
|
||||
msm_camera_io_w(paddr32, vfe_dev->vfe_base +
|
||||
VFE32_PING_PONG_BASE(wm_idx, pingpong_status));
|
||||
}
|
||||
|
||||
static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking)
|
||||
{
|
||||
uint32_t halt_mask;
|
||||
uint32_t axi_busy_flag = true;
|
||||
|
||||
/* Keep only halt and restart mask */
|
||||
msm_camera_io_w(0x01800000, vfe_dev->vfe_base + 0x20);
|
||||
/*Clear IRQ Status */
|
||||
msm_camera_io_w(0xFE7FFFFF, vfe_dev->vfe_base + 0x28);
|
||||
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);
|
||||
while (axi_busy_flag) {
|
||||
if (msm_camera_io_r(
|
||||
|
|
@ -1130,10 +1233,27 @@ static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking)
|
|||
axi_busy_flag = false;
|
||||
}
|
||||
msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x1D8);
|
||||
halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20);
|
||||
halt_mask &= 0xFEFFFFFF;
|
||||
/* Disable AXI IRQ */
|
||||
msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vfe32_axi_restart(struct vfe_device *vfe_dev,
|
||||
uint32_t blocking, uint32_t enable_camif)
|
||||
{
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev);
|
||||
|
||||
/*Clear IRQ Status */
|
||||
msm_camera_io_w(0xFE7FFFFF, vfe_dev->vfe_base + 0x28);
|
||||
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8);
|
||||
msm_camera_io_w_mb(0xA, vfe_dev->vfe_base + 0x200);
|
||||
/* Start AXI */
|
||||
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x1D8);
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, 0xF);
|
||||
memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
|
||||
atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
|
||||
if (enable_camif) {
|
||||
vfe_dev->hw_info->vfe_ops.core_ops.
|
||||
update_camif_state(vfe_dev, ENABLE_CAMIF);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1187,20 +1307,36 @@ static int msm_vfe32_stats_check_streams(
|
|||
}
|
||||
|
||||
static void msm_vfe32_stats_cfg_comp_mask(struct vfe_device *vfe_dev,
|
||||
uint32_t stats_mask, uint8_t comp_idx, uint8_t enable)
|
||||
uint32_t stats_mask, uint8_t enable)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
atomic_t *stats_comp;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
|
||||
stats_mask = stats_mask & 0x7F;
|
||||
|
||||
for (i = 0;
|
||||
i < vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; i++) {
|
||||
stats_comp = &stats_data->stats_comp_mask[i];
|
||||
if (enable)
|
||||
atomic_add(stats_mask, stats_comp);
|
||||
else
|
||||
atomic_sub(stats_mask, stats_comp);
|
||||
ISP_DBG("%s: comp_mask: %x\n",
|
||||
__func__, atomic_read(&stats_data->stats_comp_mask[i]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info)
|
||||
{
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
|
||||
stream_info);
|
||||
uint32_t irq_mask;
|
||||
|
||||
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
irq_mask |= BIT(STATS_IDX(stream_info->stream_handle[vfe_idx]) + 13);
|
||||
irq_mask |= BIT(STATS_IDX(stream_info->stream_handle) + 13);
|
||||
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_clear_wm_irq_mask(struct vfe_device *vfe_dev,
|
||||
|
|
@ -1211,18 +1347,21 @@ static void msm_vfe32_stats_clear_wm_irq_mask(struct vfe_device *vfe_dev,
|
|||
irq_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
|
||||
irq_mask &= ~(BIT(STATS_IDX(stream_info->stream_handle) + 13));
|
||||
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_cfg_wm_reg(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info)
|
||||
{
|
||||
/*Nothing to configure for VFE3.x*/
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_clear_wm_reg(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info)
|
||||
{
|
||||
/*Nothing to configure for VFE3.x*/
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_cfg_ub(struct vfe_device *vfe_dev)
|
||||
|
|
@ -1247,12 +1386,7 @@ static void msm_vfe32_stats_cfg_ub(struct vfe_device *vfe_dev)
|
|||
msm_camera_io_w(ub_offset << 16 | (ub_size[i] - 1),
|
||||
vfe_dev->vfe_base + VFE32_STATS_BASE(i) + 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
static bool msm_vfe32_is_module_cfg_lock_needed(
|
||||
uint32_t reg_offset)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev,
|
||||
|
|
@ -1294,15 +1428,13 @@ static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev,
|
|||
|
||||
static void msm_vfe32_stats_update_ping_pong_addr(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status,
|
||||
dma_addr_t paddr, uint32_t buf_sz)
|
||||
dma_addr_t paddr)
|
||||
{
|
||||
void __iomem *vfe_base = vfe_dev->vfe_base;
|
||||
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
|
||||
stream_info);
|
||||
uint32_t paddr32 = (paddr & 0xFFFFFFFF);
|
||||
int stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
|
||||
|
||||
msm_camera_io_w(paddr32, vfe_base +
|
||||
int stats_idx = STATS_IDX(stream_info->stream_handle);
|
||||
|
||||
msm_camera_io_w(paddr32, vfe_dev->vfe_base +
|
||||
VFE32_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
|
||||
}
|
||||
|
||||
|
|
@ -1361,28 +1493,6 @@ static int msm_vfe32_get_platform_data(struct vfe_device *vfe_dev)
|
|||
goto vfe_no_resource;
|
||||
}
|
||||
|
||||
if (!vfe_dev->pdev->dev.of_node)
|
||||
vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe_imgwr");
|
||||
else
|
||||
vfe_dev->iommu_ctx[0] = msm_iommu_get_ctx("vfe");
|
||||
|
||||
if (!vfe_dev->iommu_ctx[0]) {
|
||||
pr_err("%s: no iommux ctx resource?\n", __func__);
|
||||
rc = -ENODEV;
|
||||
goto vfe_no_resource;
|
||||
}
|
||||
|
||||
if (!vfe_dev->pdev->dev.of_node)
|
||||
vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe_misc");
|
||||
else
|
||||
vfe_dev->iommu_ctx[1] = msm_iommu_get_ctx("vfe");
|
||||
|
||||
if (!vfe_dev->iommu_ctx[1]) {
|
||||
pr_err("%s: no iommux ctx resource?\n", __func__);
|
||||
rc = -ENODEV;
|
||||
goto vfe_no_resource;
|
||||
}
|
||||
|
||||
vfe_no_resource:
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1394,13 +1504,27 @@ static void msm_vfe32_get_error_mask(uint32_t *error_mask0,
|
|||
*error_mask1 = 0x007FFFFF;
|
||||
}
|
||||
|
||||
struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
|
||||
.num_wm = 5,
|
||||
|
||||
static void msm_vfe32_restore_irq_mask(struct vfe_device *vfe_dev)
|
||||
{
|
||||
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0,
|
||||
vfe_dev->vfe_base + 0x1C);
|
||||
msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1,
|
||||
vfe_dev->vfe_base + 0x20);
|
||||
}
|
||||
|
||||
static void msm_vfe32_get_halt_restart_mask(uint32_t *irq0_mask,
|
||||
uint32_t *irq1_mask)
|
||||
{
|
||||
*irq1_mask = 0x01800000;
|
||||
}
|
||||
|
||||
static struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = {
|
||||
.num_wm = 6,
|
||||
.num_comp_mask = 3,
|
||||
.num_rdi = 3,
|
||||
.num_rdi_master = 3,
|
||||
.min_wm_ub = 64,
|
||||
.scratch_buf_range = SZ_32M,
|
||||
};
|
||||
|
||||
static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = {
|
||||
|
|
@ -1412,7 +1536,22 @@ static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = {
|
|||
1 << MSM_ISP_STATS_SKIN | 1 << MSM_ISP_STATS_BHIST,
|
||||
.stats_ping_pong_offset = stats_pingpong_offset_map,
|
||||
.num_stats_type = VFE32_NUM_STATS_TYPE,
|
||||
.num_stats_comp_mask = 0,
|
||||
.num_stats_comp_mask = 1,
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_core_ops msm_vfe32_subdev_core_ops = {
|
||||
.ioctl = msm_isp_ioctl,
|
||||
.subscribe_event = msm_isp_subscribe_event,
|
||||
.unsubscribe_event = msm_isp_unsubscribe_event,
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_ops msm_vfe32_subdev_ops = {
|
||||
.core = &msm_vfe32_subdev_core_ops,
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_internal_ops msm_vfe32_internal_ops = {
|
||||
.open = msm_isp_open_node,
|
||||
.close = msm_isp_close_node,
|
||||
};
|
||||
|
||||
struct msm_vfe_hardware_info vfe32_hw_info = {
|
||||
|
|
@ -1421,16 +1560,14 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
|
|||
.vfe_clk_idx = VFE32_CLK_IDX,
|
||||
.vfe_ops = {
|
||||
.irq_ops = {
|
||||
.read_and_clear_irq_status =
|
||||
msm_vfe32_read_and_clear_irq_status,
|
||||
.read_irq_status = msm_vfe32_read_irq_status,
|
||||
.process_camif_irq = msm_vfe32_process_camif_irq,
|
||||
.process_reset_irq = msm_vfe32_process_reset_irq,
|
||||
.process_halt_irq = msm_vfe32_process_halt_irq,
|
||||
.process_reg_update = msm_vfe32_process_reg_update,
|
||||
.process_epoch_irq = msm_vfe32_process_epoch_irq,
|
||||
.process_axi_irq = msm_isp_process_axi_irq,
|
||||
.process_stats_irq = msm_isp_process_stats_irq,
|
||||
.process_epoch_irq = msm_vfe32_process_epoch_irq,
|
||||
},
|
||||
.axi_ops = {
|
||||
.reload_wm = msm_vfe32_axi_reload_wm,
|
||||
|
|
@ -1446,15 +1583,14 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
|
|||
.clear_wm_reg = msm_vfe32_axi_clear_wm_reg,
|
||||
.cfg_wm_xbar_reg = msm_vfe32_axi_cfg_wm_xbar_reg,
|
||||
.clear_wm_xbar_reg = msm_vfe32_axi_clear_wm_xbar_reg,
|
||||
.cfg_ub = msm_vfe47_cfg_axi_ub,
|
||||
.cfg_ub = msm_vfe32_cfg_axi_ub,
|
||||
.update_ping_pong_addr =
|
||||
msm_vfe32_update_ping_pong_addr,
|
||||
.get_comp_mask = msm_vfe32_get_comp_mask,
|
||||
.get_wm_mask = msm_vfe32_get_wm_mask,
|
||||
.get_pingpong_status = msm_vfe32_get_pingpong_status,
|
||||
.halt = msm_vfe32_axi_halt,
|
||||
.ub_reg_offset = msm_vfe40_ub_reg_offset,
|
||||
.get_ub_size = msm_vfe40_get_ub_size,
|
||||
.restart = msm_vfe32_axi_restart,
|
||||
},
|
||||
.core_ops = {
|
||||
.reg_update = msm_vfe32_reg_update,
|
||||
|
|
@ -1469,13 +1605,13 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
|
|||
.release_hw = msm_vfe32_release_hardware,
|
||||
.get_platform_data = msm_vfe32_get_platform_data,
|
||||
.get_error_mask = msm_vfe32_get_error_mask,
|
||||
.process_error_status = msm_vfe32_process_error_status,
|
||||
.get_overflow_mask = msm_vfe32_get_overflow_mask,
|
||||
.is_module_cfg_lock_needed =
|
||||
msm_vfe32_is_module_cfg_lock_needed,
|
||||
.ahb_clk_cfg = NULL,
|
||||
.set_bus_err_ign_mask = NULL,
|
||||
.get_bus_err_mask = NULL,
|
||||
.get_rdi_wm_mask = msm_vfe32_get_rdi_wm_mask,
|
||||
.get_irq_mask = msm_vfe32_get_irq_mask,
|
||||
.restore_irq_mask = msm_vfe32_restore_irq_mask,
|
||||
.get_halt_restart_mask =
|
||||
msm_vfe32_get_halt_restart_mask,
|
||||
.process_error_status = msm_vfe32_process_error_status,
|
||||
},
|
||||
.stats_ops = {
|
||||
.get_stats_idx = msm_vfe32_get_stats_idx,
|
||||
|
|
@ -1493,47 +1629,12 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
|
|||
.get_wm_mask = msm_vfe32_stats_get_wm_mask,
|
||||
.get_frame_id = msm_vfe32_stats_get_frame_id,
|
||||
.get_pingpong_status = msm_vfe32_get_pingpong_status,
|
||||
.enable_stats_wm = NULL,
|
||||
},
|
||||
},
|
||||
.dmi_reg_offset = 0x5A0,
|
||||
.axi_hw_info = &msm_vfe32_axi_hw_info,
|
||||
.stats_hw_info = &msm_vfe32_stats_hw_info,
|
||||
.subdev_ops = &msm_vfe32_subdev_ops,
|
||||
.subdev_internal_ops = &msm_vfe32_internal_ops,
|
||||
};
|
||||
EXPORT_SYMBOL(vfe32_hw_info);
|
||||
|
||||
static const struct of_device_id msm_vfe32_dt_match[] = {
|
||||
{
|
||||
.compatible = "qcom,vfe32",
|
||||
.data = &vfe32_hw_info,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, msm_vfe32_dt_match);
|
||||
|
||||
static struct platform_driver vfe32_driver = {
|
||||
.probe = vfe_hw_probe,
|
||||
.driver = {
|
||||
.name = "msm_vfe32",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = msm_vfe32_dt_match,
|
||||
},
|
||||
.id_table = msm_vfe32_dev_id,
|
||||
};
|
||||
|
||||
static int __init msm_vfe32_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&vfe32_driver);
|
||||
}
|
||||
|
||||
static void __exit msm_vfe32_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&vfe32_driver);
|
||||
}
|
||||
|
||||
module_init(msm_vfe32_init_module);
|
||||
module_exit(msm_vfe32_exit_module);
|
||||
MODULE_DESCRIPTION("MSM VFE32 driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
|
|
|
|||
557
drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c
Normal file
557
drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c
Normal file
|
|
@ -0,0 +1,557 @@
|
|||
/* Copyright (c) 2013-2018, 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/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/sched_clock.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
||||
#include "msm_isp_32.h"
|
||||
#include "msm_isp_util_32.h"
|
||||
#include "msm_isp_axi_util_32.h"
|
||||
#include "msm_isp_stats_util_32.h"
|
||||
#include "msm_sd.h"
|
||||
#include "msm_isp32.h"
|
||||
|
||||
static struct msm_sd_req_vb2_q vfe_vb2_ops;
|
||||
|
||||
static const struct of_device_id msm_vfe_dt_match[] = {
|
||||
{
|
||||
.compatible = "qcom,vfe32",
|
||||
.data = &vfe32_hw_info,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, msm_vfe_dt_match);
|
||||
|
||||
static const struct platform_device_id msm_vfe_dev_id[] = {
|
||||
{"msm_vfe32", (kernel_ulong_t) &vfe32_hw_info},
|
||||
{}
|
||||
};
|
||||
#define MAX_OVERFLOW_COUNTERS 29
|
||||
#define OVERFLOW_LENGTH 1024
|
||||
#define OVERFLOW_BUFFER_LENGTH 64
|
||||
static char stat_line[OVERFLOW_LENGTH];
|
||||
|
||||
static struct msm_isp_buf_mgr vfe_buf_mgr;
|
||||
static int msm_isp_enable_debugfs(struct vfe_device *vfe_dev,
|
||||
struct msm_isp_bw_req_info *isp_req_hist);
|
||||
static char *stats_str[MAX_OVERFLOW_COUNTERS] = {
|
||||
"imgmaster0_overflow_cnt",
|
||||
"imgmaster1_overflow_cnt",
|
||||
"imgmaster2_overflow_cnt",
|
||||
"imgmaster3_overflow_cnt",
|
||||
"imgmaster4_overflow_cnt",
|
||||
"imgmaster5_overflow_cnt",
|
||||
"imgmaster6_overflow_cnt",
|
||||
"be_overflow_cnt",
|
||||
"bg_overflow_cnt",
|
||||
"bf_overflow_cnt",
|
||||
"awb_overflow_cnt",
|
||||
"rs_overflow_cnt",
|
||||
"cs_overflow_cnt",
|
||||
"ihist_overflow_cnt",
|
||||
"skinbhist_overflow_cnt",
|
||||
"bfscale_overflow_cnt",
|
||||
"ISP_VFE0_client_info.active",
|
||||
"ISP_VFE0_client_info.ab",
|
||||
"ISP_VFE0_client_info.ib",
|
||||
"ISP_VFE1_client_info.active",
|
||||
"ISP_VFE1_client_info.ab",
|
||||
"ISP_VFE1_client_info.ib",
|
||||
"ISP_CPP_client_info.active",
|
||||
"ISP_CPP_client_info.ab",
|
||||
"ISP_CPP_client_info.ib",
|
||||
"ISP_last_overflow.ab",
|
||||
"ISP_last_overflow.ib",
|
||||
"ISP_VFE_CLK_RATE",
|
||||
"ISP_CPP_CLK_RATE",
|
||||
};
|
||||
|
||||
#define MAX_DEPTH_BW_REQ_HISTORY 25
|
||||
#define MAX_BW_HISTORY_BUFF_LEN 6144
|
||||
#define MAX_BW_HISTORY_LINE_BUFF_LEN 512
|
||||
|
||||
#define MAX_UB_INFO_BUFF_LEN 1024
|
||||
#define MAX_UB_INFO_LINE_BUFF_LEN 256
|
||||
|
||||
static struct msm_isp_bw_req_info
|
||||
msm_isp_bw_request_history[MAX_DEPTH_BW_REQ_HISTORY];
|
||||
static int msm_isp_bw_request_history_idx;
|
||||
static char bw_request_history_buff[MAX_BW_HISTORY_BUFF_LEN];
|
||||
static char ub_info_buffer[MAX_UB_INFO_BUFF_LEN];
|
||||
static spinlock_t req_history_lock;
|
||||
static int vfe_debugfs_statistics_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t vfe_debugfs_statistics_read(struct file *t_file,
|
||||
char __user *t_char, size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
int i;
|
||||
uint64_t *ptr;
|
||||
char buffer[OVERFLOW_BUFFER_LENGTH] = {0};
|
||||
struct vfe_device *vfe_dev = (struct vfe_device *)
|
||||
t_file->private_data;
|
||||
struct msm_isp_statistics *stats = vfe_dev->stats;
|
||||
|
||||
memset(stat_line, 0, sizeof(stat_line));
|
||||
msm_isp_util_get_bandwidth_stats(vfe_dev, stats);
|
||||
ptr = (uint64_t *)(stats);
|
||||
for (i = 0; i < MAX_OVERFLOW_COUNTERS; i++) {
|
||||
strlcat(stat_line, stats_str[i], sizeof(stat_line));
|
||||
strlcat(stat_line, " ", sizeof(stat_line));
|
||||
snprintf(buffer, sizeof(buffer), "%llu", ptr[i]);
|
||||
strlcat(stat_line, buffer, sizeof(stat_line));
|
||||
strlcat(stat_line, "\r\n", sizeof(stat_line));
|
||||
}
|
||||
return simple_read_from_buffer(t_char, t_size_t,
|
||||
t_loff_t, stat_line, strlen(stat_line));
|
||||
}
|
||||
|
||||
static ssize_t vfe_debugfs_statistics_write(struct file *t_file,
|
||||
const char __user *t_char, size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
struct vfe_device *vfe_dev = (struct vfe_device *)
|
||||
t_file->private_data;
|
||||
struct msm_isp_statistics *stats = vfe_dev->stats;
|
||||
|
||||
memset(stats, 0, sizeof(struct msm_isp_statistics));
|
||||
|
||||
return sizeof(struct msm_isp_statistics);
|
||||
}
|
||||
|
||||
static int bw_history_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t bw_history_read(struct file *t_file, char __user *t_char,
|
||||
size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
int i;
|
||||
char *out_buffer = bw_request_history_buff;
|
||||
char line_buffer[MAX_BW_HISTORY_LINE_BUFF_LEN] = {0};
|
||||
struct msm_isp_bw_req_info *isp_req_hist =
|
||||
(struct msm_isp_bw_req_info *) t_file->private_data;
|
||||
|
||||
memset(out_buffer, 0, MAX_BW_HISTORY_BUFF_LEN);
|
||||
|
||||
snprintf(line_buffer, sizeof(line_buffer),
|
||||
"Bus bandwidth request history in chronological order:\n");
|
||||
strlcat(out_buffer, line_buffer, sizeof(bw_request_history_buff));
|
||||
|
||||
snprintf(line_buffer, sizeof(line_buffer),
|
||||
"MSM_ISP_MIN_AB = %u, MSM_ISP_MIN_IB = %u\n\n",
|
||||
MSM_ISP_MIN_AB, MSM_ISP_MIN_IB);
|
||||
strlcat(out_buffer, line_buffer, sizeof(bw_request_history_buff));
|
||||
|
||||
for (i = 0; i < MAX_DEPTH_BW_REQ_HISTORY; i++) {
|
||||
snprintf(line_buffer, sizeof(line_buffer),
|
||||
"idx = %d, client = %u, timestamp = %llu, ab = %llu, ib = %llu\n"
|
||||
"ISP0.active = %x, ISP0.ab = %llu, ISP0.ib = %llu\n"
|
||||
"ISP1.active = %x, ISP1.ab = %llu, ISP1.ib = %llu\n"
|
||||
"CPP.active = %x, CPP.ab = %llu, CPP.ib = %llu\n\n",
|
||||
i, isp_req_hist[i].client, isp_req_hist[i].timestamp,
|
||||
isp_req_hist[i].total_ab, isp_req_hist[i].total_ib,
|
||||
isp_req_hist[i].client_info[0].active,
|
||||
isp_req_hist[i].client_info[0].ab,
|
||||
isp_req_hist[i].client_info[0].ib,
|
||||
isp_req_hist[i].client_info[1].active,
|
||||
isp_req_hist[i].client_info[1].ab,
|
||||
isp_req_hist[i].client_info[1].ib,
|
||||
isp_req_hist[i].client_info[2].active,
|
||||
isp_req_hist[i].client_info[2].ab,
|
||||
isp_req_hist[i].client_info[2].ib);
|
||||
strlcat(out_buffer, line_buffer,
|
||||
sizeof(bw_request_history_buff));
|
||||
}
|
||||
return simple_read_from_buffer(t_char, t_size_t,
|
||||
t_loff_t, out_buffer, strlen(out_buffer));
|
||||
}
|
||||
|
||||
static ssize_t bw_history_write(struct file *t_file,
|
||||
const char __user *t_char, size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
struct msm_isp_bw_req_info *isp_req_hist =
|
||||
(struct msm_isp_bw_req_info *) t_file->private_data;
|
||||
|
||||
memset(isp_req_hist, 0, sizeof(msm_isp_bw_request_history));
|
||||
msm_isp_bw_request_history_idx = 0;
|
||||
return sizeof(msm_isp_bw_request_history);
|
||||
}
|
||||
|
||||
static int ub_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ub_info_read(struct file *t_file, char __user *t_char,
|
||||
size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
int i;
|
||||
char *out_buffer = ub_info_buffer;
|
||||
char line_buffer[MAX_UB_INFO_LINE_BUFF_LEN] = {0};
|
||||
struct vfe_device *vfe_dev =
|
||||
(struct vfe_device *) t_file->private_data;
|
||||
struct msm_isp_ub_info *ub_info = vfe_dev->ub_info;
|
||||
|
||||
memset(out_buffer, 0, MAX_UB_INFO_LINE_BUFF_LEN);
|
||||
snprintf(line_buffer, sizeof(line_buffer),
|
||||
"wm_ub_policy_type = %d\n"
|
||||
"num_wm = %d\n"
|
||||
"wm_ub = %d\n",
|
||||
ub_info->policy, ub_info->num_wm, ub_info->wm_ub);
|
||||
strlcat(out_buffer, line_buffer,
|
||||
sizeof(ub_info_buffer));
|
||||
for (i = 0; i < ub_info->num_wm; i++) {
|
||||
snprintf(line_buffer, sizeof(line_buffer),
|
||||
"data[%d] = 0x%x, addr[%d] = 0x%llx\n",
|
||||
i, ub_info->data[i], i, ub_info->addr[i]);
|
||||
strlcat(out_buffer, line_buffer,
|
||||
sizeof(ub_info_buffer));
|
||||
}
|
||||
|
||||
return simple_read_from_buffer(t_char, t_size_t,
|
||||
t_loff_t, out_buffer, strlen(out_buffer));
|
||||
}
|
||||
|
||||
static ssize_t ub_info_write(struct file *t_file,
|
||||
const char __user *t_char, size_t t_size_t, loff_t *t_loff_t)
|
||||
{
|
||||
struct vfe_device *vfe_dev =
|
||||
(struct vfe_device *) t_file->private_data;
|
||||
struct msm_isp_ub_info *ub_info = vfe_dev->ub_info;
|
||||
|
||||
memset(ub_info, 0, sizeof(struct msm_isp_ub_info));
|
||||
|
||||
return sizeof(struct msm_isp_ub_info);
|
||||
}
|
||||
|
||||
static const struct file_operations vfe_debugfs_error = {
|
||||
.open = vfe_debugfs_statistics_open,
|
||||
.read = vfe_debugfs_statistics_read,
|
||||
.write = vfe_debugfs_statistics_write,
|
||||
};
|
||||
|
||||
static const struct file_operations bw_history_ops = {
|
||||
.open = bw_history_open,
|
||||
.read = bw_history_read,
|
||||
.write = bw_history_write,
|
||||
};
|
||||
|
||||
static const struct file_operations ub_info_ops = {
|
||||
.open = ub_info_open,
|
||||
.read = ub_info_read,
|
||||
.write = ub_info_write,
|
||||
};
|
||||
|
||||
static int msm_isp_enable_debugfs(struct vfe_device *vfe_dev,
|
||||
struct msm_isp_bw_req_info *isp_req_hist)
|
||||
{
|
||||
struct dentry *debugfs_base;
|
||||
char dirname[32] = {0};
|
||||
|
||||
snprintf(dirname, sizeof(dirname), "msm_isp%d", vfe_dev->pdev->id);
|
||||
debugfs_base = debugfs_create_dir(dirname, NULL);
|
||||
if (!debugfs_base)
|
||||
return -ENOMEM;
|
||||
if (!debugfs_create_file("stats", 0644, debugfs_base,
|
||||
vfe_dev, &vfe_debugfs_error))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!debugfs_create_file("bw_req_history", 0644,
|
||||
debugfs_base, isp_req_hist, &bw_history_ops))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!debugfs_create_file("ub_info", 0644,
|
||||
debugfs_base, vfe_dev, &ub_info_ops))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msm_isp_update_req_history(uint32_t client, uint64_t ab,
|
||||
uint64_t ib,
|
||||
struct msm_isp_bandwidth_info *client_info,
|
||||
unsigned long long ts)
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock(&req_history_lock);
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].client =
|
||||
client;
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].timestamp =
|
||||
ts;
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].total_ab =
|
||||
ab;
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].total_ib =
|
||||
ib;
|
||||
|
||||
for (i = 0; i < MAX_ISP_CLIENT; i++) {
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].
|
||||
client_info[i].active = client_info[i].active;
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].
|
||||
client_info[i].ab = client_info[i].ab;
|
||||
msm_isp_bw_request_history[msm_isp_bw_request_history_idx].
|
||||
client_info[i].ib = client_info[i].ib;
|
||||
}
|
||||
|
||||
msm_isp_bw_request_history_idx = (msm_isp_bw_request_history_idx + 1)
|
||||
% MAX_DEPTH_BW_REQ_HISTORY;
|
||||
spin_unlock(&req_history_lock);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg)
|
||||
{
|
||||
long rc;
|
||||
|
||||
if (is_compat_task()) {
|
||||
struct msm_isp32_event_data32 *event_data32;
|
||||
struct msm_isp32_event_data *event_data;
|
||||
struct v4l2_event isp_event;
|
||||
struct v4l2_event *isp_event_user;
|
||||
|
||||
memset(&isp_event, 0, sizeof(isp_event));
|
||||
rc = v4l2_event_dequeue(vfh, &isp_event,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
if (rc)
|
||||
return rc;
|
||||
event_data = (struct msm_isp32_event_data *)
|
||||
isp_event.u.data;
|
||||
isp_event_user = (struct v4l2_event *)arg;
|
||||
memcpy(isp_event_user, &isp_event,
|
||||
sizeof(*isp_event_user));
|
||||
event_data32 = (struct msm_isp32_event_data32 *)
|
||||
isp_event_user->u.data;
|
||||
memset(event_data32, 0,
|
||||
sizeof(struct msm_isp32_event_data32));
|
||||
event_data32->timestamp.tv_sec =
|
||||
event_data->timestamp.tv_sec;
|
||||
event_data32->timestamp.tv_usec =
|
||||
event_data->timestamp.tv_usec;
|
||||
event_data32->mono_timestamp.tv_sec =
|
||||
event_data->mono_timestamp.tv_sec;
|
||||
event_data32->mono_timestamp.tv_usec =
|
||||
event_data->mono_timestamp.tv_usec;
|
||||
event_data32->input_intf = event_data->input_intf;
|
||||
event_data32->frame_id = event_data->frame_id;
|
||||
memcpy(&(event_data32->u), &(event_data->u),
|
||||
sizeof(event_data32->u));
|
||||
} else {
|
||||
rc = v4l2_event_dequeue(vfh, arg,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg)
|
||||
{
|
||||
return v4l2_event_dequeue(vfh, arg,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
static long msm_isp_subdev_do_ioctl(
|
||||
struct file *file, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
|
||||
struct v4l2_fh *vfh = file->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_DQEVENT: {
|
||||
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
|
||||
return -ENOIOCTLCMD;
|
||||
return msm_isp_dqevent(file, vfh, arg);
|
||||
}
|
||||
break;
|
||||
case VIDIOC_SUBSCRIBE_EVENT:
|
||||
return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
|
||||
|
||||
case VIDIOC_UNSUBSCRIBE_EVENT:
|
||||
return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
|
||||
|
||||
default:
|
||||
return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static long msm_isp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return video_usercopy(file, cmd, arg, msm_isp_subdev_do_ioctl);
|
||||
}
|
||||
|
||||
static struct v4l2_file_operations msm_isp_v4l2_subdev_fops = {
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl32 = msm_isp_subdev_fops_ioctl,
|
||||
#endif
|
||||
.unlocked_ioctl = msm_isp_subdev_fops_ioctl
|
||||
};
|
||||
|
||||
static int vfe_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct vfe_device *vfe_dev;
|
||||
/*struct msm_cam_subdev_info sd_info;*/
|
||||
const struct of_device_id *match_dev;
|
||||
int rc = 0;
|
||||
|
||||
vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL);
|
||||
if (!vfe_dev) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
vfe_dev->stats = kzalloc(sizeof(struct msm_isp_statistics), GFP_KERNEL);
|
||||
if (!vfe_dev->stats) {
|
||||
rc = -ENOMEM;
|
||||
goto probe_fail1;
|
||||
}
|
||||
|
||||
vfe_dev->ub_info = kzalloc(sizeof(struct msm_isp_ub_info), GFP_KERNEL);
|
||||
if (!vfe_dev->ub_info) {
|
||||
rc = -ENOMEM;
|
||||
goto probe_fail2;
|
||||
}
|
||||
if (pdev->dev.of_node) {
|
||||
of_property_read_u32((&pdev->dev)->of_node,
|
||||
"cell-index", &pdev->id);
|
||||
match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev);
|
||||
if (!match_dev) {
|
||||
pr_err("%s: No vfe hardware info\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto probe_fail3;
|
||||
}
|
||||
vfe_dev->hw_info =
|
||||
(struct msm_vfe_hardware_info *) match_dev->data;
|
||||
} else {
|
||||
vfe_dev->hw_info = (struct msm_vfe_hardware_info *)
|
||||
platform_get_device_id(pdev)->driver_data;
|
||||
}
|
||||
|
||||
if (!vfe_dev->hw_info) {
|
||||
pr_err("%s: No vfe hardware info\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto probe_fail3;
|
||||
}
|
||||
ISP_DBG("%s: device id = %d\n", __func__, pdev->id);
|
||||
|
||||
vfe_dev->pdev = pdev;
|
||||
rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: failed to get platform resources\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto probe_fail3;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&vfe_dev->tasklet_q);
|
||||
tasklet_init(&vfe_dev->vfe_tasklet,
|
||||
msm_isp_do_tasklet, (unsigned long)vfe_dev);
|
||||
|
||||
v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops);
|
||||
vfe_dev->subdev.sd.internal_ops =
|
||||
vfe_dev->hw_info->subdev_internal_ops;
|
||||
snprintf(vfe_dev->subdev.sd.name,
|
||||
ARRAY_SIZE(vfe_dev->subdev.sd.name),
|
||||
"vfe");
|
||||
vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev);
|
||||
platform_set_drvdata(pdev, &vfe_dev->subdev.sd);
|
||||
mutex_init(&vfe_dev->realtime_mutex);
|
||||
mutex_init(&vfe_dev->core_mutex);
|
||||
spin_lock_init(&vfe_dev->tasklet_lock);
|
||||
spin_lock_init(&vfe_dev->shared_data_lock);
|
||||
spin_lock_init(&req_history_lock);
|
||||
media_entity_pads_init(&vfe_dev->subdev.sd.entity, 0, NULL);
|
||||
vfe_dev->subdev.sd.entity.function = MSM_CAMERA_SUBDEV_VFE;
|
||||
vfe_dev->subdev.sd.entity.name = pdev->name;
|
||||
vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2;
|
||||
rc = msm_sd_register(&vfe_dev->subdev);
|
||||
if (rc != 0) {
|
||||
pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
|
||||
goto probe_fail3;
|
||||
}
|
||||
|
||||
msm_isp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
|
||||
msm_isp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
|
||||
msm_isp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
|
||||
msm_isp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
|
||||
|
||||
vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_subdev_fops;
|
||||
|
||||
vfe_dev->buf_mgr = &vfe_buf_mgr;
|
||||
v4l2_subdev_notify(&vfe_dev->subdev.sd,
|
||||
MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops);
|
||||
rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr,
|
||||
&vfe_vb2_ops, &pdev->dev,
|
||||
vfe_dev->hw_info->axi_hw_info->scratch_buf_range);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: Unable to create buffer manager\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto probe_fail3;
|
||||
}
|
||||
msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history);
|
||||
|
||||
vfe_dev->buf_mgr->init_done = 1;
|
||||
vfe_dev->vfe_open_cnt = 0;
|
||||
return rc;
|
||||
|
||||
probe_fail3:
|
||||
kfree(vfe_dev->ub_info);
|
||||
probe_fail2:
|
||||
kfree(vfe_dev->stats);
|
||||
probe_fail1:
|
||||
kfree(vfe_dev);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct platform_driver vfe_driver = {
|
||||
.probe = vfe_probe,
|
||||
.driver = {
|
||||
.name = "msm_vfe",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = msm_vfe_dt_match,
|
||||
},
|
||||
.id_table = msm_vfe_dev_id,
|
||||
};
|
||||
|
||||
static int __init msm_vfe_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&vfe_driver);
|
||||
}
|
||||
|
||||
static void __exit msm_vfe_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&vfe_driver);
|
||||
}
|
||||
|
||||
module_init(msm_vfe_init_module);
|
||||
module_exit(msm_vfe_exit_module);
|
||||
MODULE_DESCRIPTION("MSM VFE driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
599
drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h
Normal file
599
drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
/* Copyright (c) 2013-2018, 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 __MSM_VFE_H__
|
||||
#define __MSM_VFE_H__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/delay.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/msmb_isp.h>
|
||||
#include <linux/msm-bus.h>
|
||||
#include <linux/msm-bus-board.h>
|
||||
|
||||
#include "msm_buf_mgr.h"
|
||||
|
||||
#define VFE40_8974V1_VERSION 0x10000018
|
||||
#define VFE40_8974V2_VERSION 0x1001001A
|
||||
#define VFE40_8974V3_VERSION 0x1001001B
|
||||
#define VFE40_8x26_VERSION 0x20000013
|
||||
#define VFE40_8x26V2_VERSION 0x20010014
|
||||
#define VFE40_8916_VERSION 0x10030000
|
||||
#define VFE40_8939_VERSION 0x10040000
|
||||
#define VFE32_8909_VERSION 0x30600
|
||||
|
||||
#define MAX_IOMMU_CTX 2
|
||||
#define MAX_NUM_WM 7
|
||||
#define MAX_NUM_RDI 3
|
||||
#define MAX_NUM_RDI_MASTER 3
|
||||
#define MAX_NUM_COMPOSITE_MASK 4
|
||||
#define MAX_NUM_STATS_COMP_MASK 2
|
||||
#define MAX_INIT_FRAME_DROP 31
|
||||
#define ISP_Q2 (1 << 2)
|
||||
#define ISP_Q10 (1 << 10)
|
||||
|
||||
#define VFE_PING_FLAG 0xFFFFFFFF
|
||||
#define VFE_PONG_FLAG 0x0
|
||||
|
||||
#define VFE_MAX_CFG_TIMEOUT 3000
|
||||
#define VFE_CLK_INFO_MAX 16
|
||||
#define STATS_COMP_BIT_MASK 0xFF0000
|
||||
|
||||
#define MSM_ISP_MIN_AB 11000000
|
||||
#define MSM_ISP_MIN_IB 11000000
|
||||
|
||||
struct vfe_device;
|
||||
struct msm_vfe_axi_stream;
|
||||
struct msm_vfe_stats_stream;
|
||||
|
||||
struct vfe_subscribe_info {
|
||||
struct v4l2_fh *vfh;
|
||||
uint32_t active;
|
||||
};
|
||||
|
||||
enum msm_isp_pack_fmt {
|
||||
QCOM,
|
||||
MIPI,
|
||||
DPCM6,
|
||||
DPCM8,
|
||||
PLAIN8,
|
||||
PLAIN16,
|
||||
MAX_ISP_PACK_FMT,
|
||||
};
|
||||
|
||||
enum msm_isp_camif_update_state {
|
||||
NO_UPDATE,
|
||||
ENABLE_CAMIF,
|
||||
DISABLE_CAMIF,
|
||||
DISABLE_CAMIF_IMMEDIATELY
|
||||
};
|
||||
|
||||
struct msm_isp_timestamp {
|
||||
/*Monotonic clock for v4l2 buffer*/
|
||||
struct timeval buf_time;
|
||||
/*Monotonic clock for VT */
|
||||
struct timeval vt_time;
|
||||
/*Wall clock for userspace event*/
|
||||
struct timeval event_time;
|
||||
};
|
||||
|
||||
struct msm_vfe_irq_ops {
|
||||
void (*read_irq_status)(struct vfe_device *vfe_dev,
|
||||
uint32_t *irq_status0, uint32_t *irq_status1);
|
||||
void (*process_reg_update)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*process_epoch_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*process_reset_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1);
|
||||
void (*process_halt_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1);
|
||||
void (*process_camif_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*process_axi_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void (*process_stats_irq)(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_ops {
|
||||
void (*reload_wm)(struct vfe_device *vfe_dev,
|
||||
uint32_t reload_mask);
|
||||
void (*enable_wm)(struct vfe_device *vfe_dev,
|
||||
uint8_t wm_idx, uint8_t enable);
|
||||
int32_t (*cfg_io_format)(struct vfe_device *vfe_dev,
|
||||
enum msm_vfe_axi_stream_src stream_src,
|
||||
uint32_t io_format);
|
||||
void (*cfg_framedrop)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
void (*clear_framedrop)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
void (*cfg_comp_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
void (*clear_comp_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
void (*cfg_wm_irq_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
void (*clear_wm_irq_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
|
||||
void (*cfg_wm_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info,
|
||||
uint8_t plane_idx);
|
||||
void (*clear_wm_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx);
|
||||
|
||||
void (*cfg_wm_xbar_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info,
|
||||
uint8_t plane_idx);
|
||||
void (*clear_wm_xbar_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx);
|
||||
|
||||
void (*cfg_ub)(struct vfe_device *vfe_dev);
|
||||
|
||||
void (*update_ping_pong_addr)(struct vfe_device *vfe_dev,
|
||||
uint8_t wm_idx, uint32_t pingpong_status, dma_addr_t paddr);
|
||||
|
||||
uint32_t (*get_wm_mask)(uint32_t irq_status0, uint32_t irq_status1);
|
||||
uint32_t (*get_comp_mask)(uint32_t irq_status0, uint32_t irq_status1);
|
||||
uint32_t (*get_pingpong_status)(struct vfe_device *vfe_dev);
|
||||
int (*halt)(struct vfe_device *vfe_dev, uint32_t blocking);
|
||||
int (*restart)(struct vfe_device *vfe_dev, uint32_t blocking,
|
||||
uint32_t enable_camif);
|
||||
void (*update_cgc_override)(struct vfe_device *vfe_dev,
|
||||
uint8_t wm_idx, uint8_t cgc_override);
|
||||
};
|
||||
|
||||
struct msm_vfe_core_ops {
|
||||
void (*reg_update)(struct vfe_device *vfe_dev, uint32_t input_src);
|
||||
long (*reset_hw)(struct vfe_device *vfe_dev, uint32_t first_start,
|
||||
uint32_t blocking_call);
|
||||
int (*init_hw)(struct vfe_device *vfe_dev);
|
||||
void (*init_hw_reg)(struct vfe_device *vfe_dev);
|
||||
void (*clear_status_reg)(struct vfe_device *vfe_dev);
|
||||
void (*release_hw)(struct vfe_device *vfe_dev);
|
||||
void (*cfg_input_mux)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_pix_cfg *pix_cfg);
|
||||
int (*start_fetch_eng)(struct vfe_device *vfe_dev,
|
||||
void *arg);
|
||||
void (*update_camif_state)(struct vfe_device *vfe_dev,
|
||||
enum msm_isp_camif_update_state update_state);
|
||||
void (*cfg_rdi_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_rdi_cfg *rdi_cfg,
|
||||
enum msm_vfe_input_src input_src);
|
||||
int (*get_platform_data)(struct vfe_device *vfe_dev);
|
||||
void (*get_error_mask)(uint32_t *error_mask0, uint32_t *error_mask1);
|
||||
void (*process_error_status)(struct vfe_device *vfe_dev);
|
||||
void (*get_overflow_mask)(uint32_t *overflow_mask);
|
||||
void (*get_irq_mask)(struct vfe_device *vfe_dev,
|
||||
uint32_t *irq0_mask, uint32_t *irq1_mask);
|
||||
void (*restore_irq_mask)(struct vfe_device *vfe_dev);
|
||||
void (*get_halt_restart_mask)(uint32_t *irq0_mask,
|
||||
uint32_t *irq1_mask);
|
||||
void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev,
|
||||
uint32_t *rdi_wm_mask);
|
||||
};
|
||||
struct msm_vfe_stats_ops {
|
||||
int (*get_stats_idx)(enum msm_isp_stats_type stats_type);
|
||||
int (*check_streams)(struct msm_vfe_stats_stream *stream_info);
|
||||
void (*cfg_framedrop)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
void (*clear_framedrop)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
void (*cfg_comp_mask)(struct vfe_device *vfe_dev,
|
||||
uint32_t stats_mask, uint8_t enable);
|
||||
void (*cfg_wm_irq_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
void (*clear_wm_irq_mask)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
|
||||
void (*cfg_wm_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
void (*clear_wm_reg)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info);
|
||||
|
||||
void (*cfg_ub)(struct vfe_device *vfe_dev);
|
||||
|
||||
void (*enable_module)(struct vfe_device *vfe_dev,
|
||||
uint32_t stats_mask, uint8_t enable);
|
||||
|
||||
void (*update_ping_pong_addr)(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info,
|
||||
uint32_t pingpong_status, dma_addr_t paddr);
|
||||
|
||||
uint32_t (*get_frame_id)(struct vfe_device *vfe_dev);
|
||||
uint32_t (*get_wm_mask)(uint32_t irq_status0, uint32_t irq_status1);
|
||||
uint32_t (*get_comp_mask)(uint32_t irq_status0, uint32_t irq_status1);
|
||||
uint32_t (*get_pingpong_status)(struct vfe_device *vfe_dev);
|
||||
|
||||
void (*update_cgc_override)(struct vfe_device *vfe_dev,
|
||||
uint32_t stats_mask, uint8_t enable);
|
||||
};
|
||||
|
||||
struct msm_vfe_ops {
|
||||
struct msm_vfe_irq_ops irq_ops;
|
||||
struct msm_vfe_axi_ops axi_ops;
|
||||
struct msm_vfe_core_ops core_ops;
|
||||
struct msm_vfe_stats_ops stats_ops;
|
||||
};
|
||||
|
||||
struct msm_vfe_hardware_info {
|
||||
int num_iommu_ctx;
|
||||
/* secure iommu ctx nums */
|
||||
int num_iommu_secure_ctx;
|
||||
int vfe_clk_idx;
|
||||
struct msm_vfe_ops vfe_ops;
|
||||
struct msm_vfe_axi_hardware_info *axi_hw_info;
|
||||
struct msm_vfe_stats_hardware_info *stats_hw_info;
|
||||
struct v4l2_subdev_internal_ops *subdev_internal_ops;
|
||||
struct v4l2_subdev_ops *subdev_ops;
|
||||
uint32_t dmi_reg_offset;
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_hardware_info {
|
||||
uint8_t num_wm;
|
||||
uint8_t num_rdi;
|
||||
uint8_t num_rdi_master;
|
||||
uint8_t num_comp_mask;
|
||||
uint32_t min_wm_ub;
|
||||
uint32_t scratch_buf_range;
|
||||
};
|
||||
|
||||
enum msm_vfe_axi_state {
|
||||
AVAILABLE,
|
||||
INACTIVE,
|
||||
ACTIVE,
|
||||
PAUSED,
|
||||
START_PENDING,
|
||||
STOP_PENDING,
|
||||
PAUSE_PENDING,
|
||||
RESUME_PENDING,
|
||||
STARTING,
|
||||
STOPPING,
|
||||
PAUSING,
|
||||
RESUMING,
|
||||
};
|
||||
|
||||
enum msm_vfe_axi_cfg_update_state {
|
||||
NO_AXI_CFG_UPDATE,
|
||||
APPLYING_UPDATE_RESUME,
|
||||
UPDATE_REQUESTED,
|
||||
};
|
||||
|
||||
#define VFE_NO_DROP 0xFFFFFFFF
|
||||
#define VFE_DROP_EVERY_2FRAME 0x55555555
|
||||
#define VFE_DROP_EVERY_4FRAME 0x11111111
|
||||
#define VFE_DROP_EVERY_8FRAME 0x01010101
|
||||
#define VFE_DROP_EVERY_16FRAME 0x00010001
|
||||
#define VFE_DROP_EVERY_32FRAME 0x00000001
|
||||
|
||||
enum msm_vfe_axi_stream_type {
|
||||
CONTINUOUS_STREAM,
|
||||
BURST_STREAM,
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_stream {
|
||||
uint32_t frame_id;
|
||||
enum msm_vfe_axi_state state;
|
||||
enum msm_vfe_axi_stream_src stream_src;
|
||||
uint8_t num_planes;
|
||||
uint8_t wm[MAX_PLANES_PER_STREAM];
|
||||
uint32_t output_format;/*Planar/RAW/Misc*/
|
||||
struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM];
|
||||
uint8_t comp_mask_index;
|
||||
struct msm_isp_buffer *buf[2];
|
||||
uint32_t session_id;
|
||||
uint32_t stream_id;
|
||||
uint32_t bufq_handle;
|
||||
uint32_t bufq_scratch_handle;
|
||||
uint32_t controllable_output;
|
||||
uint32_t stream_handle;
|
||||
uint32_t request_frm_num;
|
||||
uint8_t buf_divert;
|
||||
enum msm_vfe_axi_stream_type stream_type;
|
||||
uint32_t frame_based;
|
||||
enum msm_vfe_frame_skip_pattern frame_skip_pattern;
|
||||
uint32_t framedrop_period;
|
||||
uint32_t framedrop_pattern;
|
||||
uint32_t num_burst_capture;/*number of frame to capture*/
|
||||
uint32_t init_frame_drop;
|
||||
uint32_t burst_frame_count;/*number of sof before burst stop*/
|
||||
uint8_t framedrop_update;
|
||||
spinlock_t lock;
|
||||
|
||||
/*Bandwidth calculation info*/
|
||||
uint32_t max_width;
|
||||
/*Based on format plane size in Q2. e.g NV12 = 1.5*/
|
||||
uint32_t format_factor;
|
||||
uint32_t bandwidth;
|
||||
|
||||
/*Run time update variables*/
|
||||
uint32_t runtime_init_frame_drop;
|
||||
uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/
|
||||
uint32_t runtime_num_burst_capture;
|
||||
uint8_t runtime_framedrop_update;
|
||||
uint8_t runtime_framedrop_update_burst;
|
||||
uint32_t runtime_output_format;
|
||||
enum msm_stream_memory_input_t memory_input;
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_composite_info {
|
||||
uint32_t stream_handle;
|
||||
uint32_t stream_composite_mask;
|
||||
};
|
||||
|
||||
struct msm_vfe_src_info {
|
||||
uint32_t frame_id;
|
||||
uint8_t active;
|
||||
uint8_t pix_stream_count;
|
||||
uint8_t raw_stream_count;
|
||||
enum msm_vfe_inputmux input_mux;
|
||||
uint32_t width;
|
||||
long pixel_clock;
|
||||
uint32_t input_format;/*V4L2 pix format with bayer pattern*/
|
||||
uint32_t last_updt_frm_id;
|
||||
};
|
||||
|
||||
struct msm_vfe_fetch_engine_info {
|
||||
uint32_t session_id;
|
||||
uint32_t stream_id;
|
||||
uint32_t bufq_handle;
|
||||
uint32_t buf_idx;
|
||||
uint8_t is_busy;
|
||||
};
|
||||
|
||||
enum msm_wm_ub_cfg_type {
|
||||
MSM_WM_UB_CFG_DEFAULT,
|
||||
MSM_WM_UB_EQUAL_SLICING,
|
||||
MSM_WM_UB_CFG_MAX_NUM
|
||||
};
|
||||
|
||||
struct msm_vfe_axi_shared_data {
|
||||
struct msm_vfe_axi_hardware_info *hw_info;
|
||||
struct msm_vfe_axi_stream stream_info[VFE_AXI_SRC_MAX];
|
||||
uint32_t free_wm[MAX_NUM_WM];
|
||||
uint32_t wm_image_size[MAX_NUM_WM];
|
||||
enum msm_wm_ub_cfg_type wm_ub_cfg_policy;
|
||||
uint8_t num_used_wm;
|
||||
uint8_t num_active_stream;
|
||||
uint8_t num_rdi_stream;
|
||||
uint8_t num_pix_stream;
|
||||
uint32_t rdi_wm_mask;
|
||||
struct msm_vfe_axi_composite_info
|
||||
composite_info[MAX_NUM_COMPOSITE_MASK];
|
||||
uint8_t num_used_composite_mask;
|
||||
uint32_t stream_update;
|
||||
atomic_t axi_cfg_update;
|
||||
enum msm_isp_camif_update_state pipeline_update;
|
||||
struct msm_vfe_src_info src_info[VFE_SRC_MAX];
|
||||
uint16_t stream_handle_cnt;
|
||||
uint32_t event_mask;
|
||||
};
|
||||
|
||||
struct msm_vfe_stats_hardware_info {
|
||||
uint32_t stats_capability_mask;
|
||||
uint8_t *stats_ping_pong_offset;
|
||||
uint8_t num_stats_type;
|
||||
uint8_t num_stats_comp_mask;
|
||||
};
|
||||
|
||||
enum msm_vfe_stats_state {
|
||||
STATS_AVAILABLE,
|
||||
STATS_INACTIVE,
|
||||
STATS_ACTIVE,
|
||||
STATS_START_PENDING,
|
||||
STATS_STOP_PENDING,
|
||||
STATS_STARTING,
|
||||
STATS_STOPPING,
|
||||
};
|
||||
|
||||
struct msm_vfe_stats_stream {
|
||||
uint32_t session_id;
|
||||
uint32_t stream_id;
|
||||
uint32_t stream_handle;
|
||||
uint32_t composite_flag;
|
||||
enum msm_isp_stats_type stats_type;
|
||||
enum msm_vfe_stats_state state;
|
||||
uint32_t framedrop_pattern;
|
||||
uint32_t framedrop_period;
|
||||
uint32_t irq_subsample_pattern;
|
||||
uint32_t init_stats_frame_drop;
|
||||
|
||||
uint32_t buffer_offset;
|
||||
struct msm_isp_buffer *buf[2];
|
||||
uint32_t bufq_handle;
|
||||
};
|
||||
|
||||
struct msm_vfe_stats_shared_data {
|
||||
struct msm_vfe_stats_stream stream_info[MSM_ISP_STATS_MAX];
|
||||
uint8_t num_active_stream;
|
||||
atomic_t stats_comp_mask[MAX_NUM_STATS_COMP_MASK];
|
||||
uint32_t reg_mask;
|
||||
uint16_t stream_handle_cnt;
|
||||
atomic_t stats_update;
|
||||
};
|
||||
|
||||
struct msm_vfe_tasklet_queue_cmd {
|
||||
struct list_head list;
|
||||
uint32_t vfeInterruptStatus0;
|
||||
uint32_t vfeInterruptStatus1;
|
||||
struct msm_isp_timestamp ts;
|
||||
uint8_t cmd_used;
|
||||
};
|
||||
|
||||
#define MSM_VFE_TASKLETQ_SIZE 200
|
||||
|
||||
enum msm_vfe_overflow_state {
|
||||
NO_OVERFLOW,
|
||||
OVERFLOW_DETECTED,
|
||||
HALT_REQUESTED,
|
||||
RESTART_REQUESTED,
|
||||
};
|
||||
|
||||
struct msm_vfe_error_info {
|
||||
atomic_t overflow_state;
|
||||
uint32_t overflow_recover_irq_mask0;
|
||||
uint32_t overflow_recover_irq_mask1;
|
||||
uint32_t error_mask0;
|
||||
uint32_t error_mask1;
|
||||
uint32_t violation_status;
|
||||
uint32_t camif_status;
|
||||
uint32_t stream_framedrop_count[MAX_NUM_STREAM];
|
||||
uint32_t stats_framedrop_count[MSM_ISP_STATS_MAX];
|
||||
uint32_t info_dump_frame_count;
|
||||
uint32_t error_count;
|
||||
};
|
||||
|
||||
struct msm_isp_statistics {
|
||||
int64_t imagemaster0_overflow;
|
||||
int64_t imagemaster1_overflow;
|
||||
int64_t imagemaster2_overflow;
|
||||
int64_t imagemaster3_overflow;
|
||||
int64_t imagemaster4_overflow;
|
||||
int64_t imagemaster5_overflow;
|
||||
int64_t imagemaster6_overflow;
|
||||
int64_t be_overflow;
|
||||
int64_t bg_overflow;
|
||||
int64_t bf_overflow;
|
||||
int64_t awb_overflow;
|
||||
int64_t rs_overflow;
|
||||
int64_t cs_overflow;
|
||||
int64_t ihist_overflow;
|
||||
int64_t skinbhist_overflow;
|
||||
int64_t bfscale_overflow;
|
||||
|
||||
int64_t isp_vfe0_active;
|
||||
int64_t isp_vfe0_ab;
|
||||
int64_t isp_vfe0_ib;
|
||||
|
||||
int64_t isp_vfe1_active;
|
||||
int64_t isp_vfe1_ab;
|
||||
int64_t isp_vfe1_ib;
|
||||
|
||||
int64_t isp_cpp_active;
|
||||
int64_t isp_cpp_ab;
|
||||
int64_t isp_cpp_ib;
|
||||
|
||||
int64_t last_overflow_ab;
|
||||
int64_t last_overflow_ib;
|
||||
|
||||
int64_t vfe_clk_rate;
|
||||
int64_t cpp_clk_rate;
|
||||
};
|
||||
|
||||
enum msm_isp_hw_client {
|
||||
ISP_VFE0,
|
||||
ISP_VFE1,
|
||||
ISP_CPP,
|
||||
MAX_ISP_CLIENT,
|
||||
};
|
||||
|
||||
struct msm_isp_bandwidth_info {
|
||||
uint32_t active;
|
||||
uint64_t ab;
|
||||
uint64_t ib;
|
||||
};
|
||||
|
||||
struct msm_isp_bw_req_info {
|
||||
uint32_t client;
|
||||
unsigned long long timestamp;
|
||||
uint64_t total_ab;
|
||||
uint64_t total_ib;
|
||||
struct msm_isp_bandwidth_info client_info[MAX_ISP_CLIENT];
|
||||
};
|
||||
|
||||
#define MSM_ISP_MAX_WM 7
|
||||
struct msm_isp_ub_info {
|
||||
enum msm_wm_ub_cfg_type policy;
|
||||
uint8_t num_wm;
|
||||
uint32_t wm_ub;
|
||||
uint32_t data[MSM_ISP_MAX_WM];
|
||||
uint64_t addr[MSM_ISP_MAX_WM];
|
||||
};
|
||||
|
||||
struct msm_vfe_hw_init_parms {
|
||||
const char *entries;
|
||||
const char *regs;
|
||||
const char *settings;
|
||||
};
|
||||
|
||||
struct vfe_device {
|
||||
struct platform_device *pdev;
|
||||
struct msm_sd_subdev subdev;
|
||||
struct resource *vfe_irq;
|
||||
struct resource *vfe_mem;
|
||||
struct resource *vfe_vbif_mem;
|
||||
struct resource *vfe_io;
|
||||
struct resource *vfe_vbif_io;
|
||||
void __iomem *vfe_base;
|
||||
void __iomem *vfe_vbif_base;
|
||||
|
||||
struct device *iommu_ctx[MAX_IOMMU_CTX];
|
||||
/*Add secure context banks*/
|
||||
struct device *iommu_secure_ctx[MAX_IOMMU_CTX];
|
||||
|
||||
struct regulator *fs_vfe;
|
||||
struct clk **vfe_clk;
|
||||
uint32_t num_clk;
|
||||
|
||||
uint32_t bus_perf_client;
|
||||
|
||||
struct completion reset_complete;
|
||||
struct completion halt_complete;
|
||||
struct completion stream_config_complete;
|
||||
struct completion stats_config_complete;
|
||||
struct mutex realtime_mutex;
|
||||
struct mutex core_mutex;
|
||||
|
||||
atomic_t irq_cnt;
|
||||
uint8_t taskletq_idx;
|
||||
spinlock_t tasklet_lock;
|
||||
spinlock_t shared_data_lock;
|
||||
struct list_head tasklet_q;
|
||||
struct tasklet_struct vfe_tasklet;
|
||||
struct msm_vfe_tasklet_queue_cmd
|
||||
tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE];
|
||||
|
||||
uint32_t vfe_hw_version;
|
||||
struct msm_vfe_hardware_info *hw_info;
|
||||
struct msm_vfe_axi_shared_data axi_data;
|
||||
struct msm_vfe_stats_shared_data stats_data;
|
||||
struct msm_vfe_error_info error_info;
|
||||
struct msm_isp_buf_mgr *buf_mgr;
|
||||
int dump_reg;
|
||||
int vfe_clk_idx;
|
||||
uint32_t vfe_open_cnt;
|
||||
uint8_t vt_enable;
|
||||
uint8_t ignore_error;
|
||||
struct msm_isp_statistics *stats;
|
||||
struct msm_vfe_fetch_engine_info fetch_engine_info;
|
||||
uint64_t msm_isp_last_overflow_ab;
|
||||
uint64_t msm_isp_last_overflow_ib;
|
||||
uint64_t msm_isp_vfe_clk_rate;
|
||||
struct msm_isp_ub_info *ub_info;
|
||||
uint32_t vfe_ub_policy;
|
||||
uint32_t isp_sof_debug;
|
||||
uint8_t reset_pending;
|
||||
uint32_t bus_util_factor;
|
||||
uint8_t vfe_reset_timeout_processed;
|
||||
};
|
||||
|
||||
#endif
|
||||
2095
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c
Normal file
2095
drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (c) 2013-2018, 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 __MSM_ISP_AXI_UTIL_H__
|
||||
#define __MSM_ISP_AXI_UTIL_H__
|
||||
|
||||
#include "msm_isp_32.h"
|
||||
|
||||
int msm_isp_axi_create_stream(
|
||||
struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd);
|
||||
|
||||
void msm_isp_axi_destroy_stream(
|
||||
struct msm_vfe_axi_shared_data *axi_data, int stream_idx);
|
||||
|
||||
int msm_isp_validate_axi_request(
|
||||
struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd);
|
||||
|
||||
void msm_isp_axi_reserve_wm(
|
||||
struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
|
||||
void msm_isp_axi_reserve_comp_mask(
|
||||
struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
|
||||
int msm_isp_axi_check_stream_state(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd);
|
||||
|
||||
void msm_isp_calculate_framedrop(
|
||||
struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd);
|
||||
void msm_isp_reset_framedrop(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
|
||||
void msm_isp_start_avtimer(void);
|
||||
int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev);
|
||||
int msm_isp_axi_halt(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_halt_cmd *halt_cmd);
|
||||
int msm_isp_axi_reset(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_reset_cmd *reset_cmd);
|
||||
int msm_isp_axi_restart(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_axi_restart_cmd *restart_cmd);
|
||||
int msm_isp_user_buf_done(struct vfe_device *vfe_dev,
|
||||
struct msm_isp32_event_data *buf_cmd);
|
||||
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev,
|
||||
uint8_t input_src);
|
||||
|
||||
void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev,
|
||||
uint8_t input_src);
|
||||
void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
|
||||
enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts);
|
||||
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
void msm_isp_axi_free_wm(struct msm_vfe_axi_shared_data *axi_data,
|
||||
struct msm_vfe_axi_stream *stream_info);
|
||||
#endif /* __MSM_ISP_AXI_UTIL_H__ */
|
||||
709
drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c
Normal file
709
drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c
Normal file
|
|
@ -0,0 +1,709 @@
|
|||
/* Copyright (c) 2013-2018, 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/io.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/msmb_isp.h>
|
||||
#include "msm_isp_util_32.h"
|
||||
#include "msm_isp_stats_util_32.h"
|
||||
|
||||
static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status,
|
||||
struct msm_isp_buffer **done_buf)
|
||||
{
|
||||
int rc = -1;
|
||||
struct msm_isp_buffer *buf;
|
||||
uint32_t pingpong_bit = 0;
|
||||
uint32_t bufq_handle = stream_info->bufq_handle;
|
||||
uint32_t stats_pingpong_offset;
|
||||
uint32_t stats_idx = STATS_IDX(stream_info->stream_handle);
|
||||
|
||||
if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type ||
|
||||
stats_idx >= MSM_ISP_STATS_MAX) {
|
||||
pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stats_pingpong_offset =
|
||||
vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[
|
||||
stats_idx];
|
||||
|
||||
pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1);
|
||||
rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
|
||||
vfe_dev->pdev->id, bufq_handle,
|
||||
MSM_ISP_INVALID_BUF_INDEX, &buf);
|
||||
if (rc < 0) {
|
||||
vfe_dev->error_info.stats_framedrop_count[stats_idx]++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (buf->num_planes != 1) {
|
||||
pr_err("%s: Invalid buffer\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto buf_error;
|
||||
}
|
||||
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr(
|
||||
vfe_dev, stream_info,
|
||||
pingpong_status, buf->mapped_info[0].paddr +
|
||||
stream_info->buffer_offset);
|
||||
|
||||
if (stream_info->buf[pingpong_bit] && done_buf)
|
||||
*done_buf = stream_info->buf[pingpong_bit];
|
||||
|
||||
stream_info->buf[pingpong_bit] = buf;
|
||||
return 0;
|
||||
buf_error:
|
||||
vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
|
||||
buf->bufq_handle, buf->buf_idx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts)
|
||||
{
|
||||
int i, j, rc;
|
||||
struct msm_isp32_event_data buf_event;
|
||||
struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
|
||||
struct msm_isp_buffer *done_buf;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
uint32_t pingpong_status;
|
||||
uint32_t comp_stats_type_mask = 0, atomic_stats_mask = 0;
|
||||
uint32_t stats_comp_mask = 0, stats_irq_mask = 0;
|
||||
uint32_t num_stats_comp_mask =
|
||||
vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;
|
||||
stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
get_comp_mask(irq_status0, irq_status1);
|
||||
stats_irq_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
get_wm_mask(irq_status0, irq_status1);
|
||||
if (!(stats_comp_mask || stats_irq_mask))
|
||||
return;
|
||||
ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
|
||||
|
||||
/*
|
||||
* If any of composite mask is set, clear irq bits from mask,
|
||||
* they will be restored by comp mask
|
||||
*/
|
||||
if (stats_comp_mask) {
|
||||
for (j = 0; j < num_stats_comp_mask; j++) {
|
||||
stats_irq_mask &= ~atomic_read(
|
||||
&vfe_dev->stats_data.stats_comp_mask[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < num_stats_comp_mask; j++) {
|
||||
atomic_stats_mask = atomic_read(
|
||||
&vfe_dev->stats_data.stats_comp_mask[j]);
|
||||
if (!stats_comp_mask) {
|
||||
stats_irq_mask &= ~atomic_stats_mask;
|
||||
} else {
|
||||
/* restore irq bits from composite mask */
|
||||
if (stats_comp_mask & (1 << j))
|
||||
stats_irq_mask |= atomic_stats_mask;
|
||||
}
|
||||
/* if no irq bits set from this composite mask continue*/
|
||||
if (!stats_irq_mask)
|
||||
continue;
|
||||
memset(&buf_event, 0, sizeof(struct msm_isp32_event_data));
|
||||
buf_event.timestamp = ts->event_time;
|
||||
buf_event.frame_id =
|
||||
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
|
||||
buf_event.input_intf = VFE_PIX_0;
|
||||
pingpong_status = vfe_dev->hw_info->
|
||||
vfe_ops.stats_ops.get_pingpong_status(vfe_dev);
|
||||
|
||||
for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type;
|
||||
i++) {
|
||||
if (!(stats_irq_mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
stats_irq_mask &= ~(1 << i);
|
||||
stream_info = &vfe_dev->stats_data.stream_info[i];
|
||||
done_buf = NULL;
|
||||
msm_isp_stats_cfg_ping_pong_address(vfe_dev,
|
||||
stream_info, pingpong_status, &done_buf);
|
||||
if (done_buf) {
|
||||
rc = vfe_dev->buf_mgr->ops->buf_divert(
|
||||
vfe_dev->buf_mgr, done_buf->bufq_handle,
|
||||
done_buf->buf_idx, &ts->buf_time,
|
||||
vfe_dev->axi_data.
|
||||
src_info[VFE_PIX_0].frame_id);
|
||||
if (rc != 0)
|
||||
continue;
|
||||
|
||||
stats_event->stats_buf_idxs
|
||||
[stream_info->stats_type] =
|
||||
done_buf->buf_idx;
|
||||
if (!stream_info->composite_flag) {
|
||||
stats_event->stats_mask =
|
||||
1 << stream_info->stats_type;
|
||||
ISP_DBG("%s: stats frameid: 0x%x %d\n",
|
||||
__func__, buf_event.frame_id,
|
||||
stream_info->stats_type);
|
||||
msm_isp_send_event(vfe_dev,
|
||||
ISP_EVENT_STATS_NOTIFY +
|
||||
stream_info->stats_type,
|
||||
&buf_event);
|
||||
} else {
|
||||
comp_stats_type_mask |=
|
||||
1 << stream_info->stats_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (comp_stats_type_mask) {
|
||||
ISP_DBG("%s: comp_stats frameid: 0x%x, 0x%x\n",
|
||||
__func__, buf_event.frame_id,
|
||||
comp_stats_type_mask);
|
||||
stats_event->stats_mask = comp_stats_type_mask;
|
||||
msm_isp_send_event(vfe_dev,
|
||||
ISP_EVENT_COMP_STATS_NOTIFY, &buf_event);
|
||||
comp_stats_type_mask = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream_request_cmd *stream_req_cmd)
|
||||
{
|
||||
int rc = -1;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
uint32_t stats_idx;
|
||||
|
||||
if (!(vfe_dev->hw_info->stats_hw_info->stats_capability_mask &
|
||||
(1 << stream_req_cmd->stats_type))) {
|
||||
pr_err("%s: Stats type not supported\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
stats_idx = vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
get_stats_idx(stream_req_cmd->stats_type);
|
||||
|
||||
if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
if (stream_info->state != STATS_AVAILABLE) {
|
||||
pr_err("%s: Stats already requested\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (stream_req_cmd->framedrop_pattern >= MAX_SKIP) {
|
||||
pr_err("%s: Invalid framedrop pattern\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (stream_req_cmd->irq_subsample_pattern >= MAX_SKIP) {
|
||||
pr_err("%s: Invalid irq subsample pattern\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
stream_info->session_id = stream_req_cmd->session_id;
|
||||
stream_info->stream_id = stream_req_cmd->stream_id;
|
||||
stream_info->composite_flag = stream_req_cmd->composite_flag;
|
||||
stream_info->stats_type = stream_req_cmd->stats_type;
|
||||
stream_info->buffer_offset = stream_req_cmd->buffer_offset;
|
||||
stream_info->framedrop_pattern = stream_req_cmd->framedrop_pattern;
|
||||
stream_info->init_stats_frame_drop = stream_req_cmd->init_frame_drop;
|
||||
stream_info->irq_subsample_pattern =
|
||||
stream_req_cmd->irq_subsample_pattern;
|
||||
stream_info->state = STATS_INACTIVE;
|
||||
|
||||
if ((vfe_dev->stats_data.stream_handle_cnt << 8) == 0)
|
||||
vfe_dev->stats_data.stream_handle_cnt++;
|
||||
|
||||
stream_req_cmd->stream_handle =
|
||||
(++vfe_dev->stats_data.stream_handle_cnt) << 8 | stats_idx;
|
||||
|
||||
stream_info->stream_handle = stream_req_cmd->stream_handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
int rc = -1;
|
||||
struct msm_vfe_stats_stream_request_cmd *stream_req_cmd = arg;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
uint32_t framedrop_period;
|
||||
uint32_t stats_idx;
|
||||
|
||||
rc = msm_isp_stats_create_stream(vfe_dev, stream_req_cmd);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: create stream failed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
stats_idx = STATS_IDX(stream_req_cmd->stream_handle);
|
||||
|
||||
if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
|
||||
framedrop_period = msm_isp_get_framedrop_period(
|
||||
stream_req_cmd->framedrop_pattern);
|
||||
|
||||
if (stream_req_cmd->framedrop_pattern == SKIP_ALL)
|
||||
stream_info->framedrop_pattern = 0x0;
|
||||
else
|
||||
stream_info->framedrop_pattern = 0x1;
|
||||
stream_info->framedrop_period = framedrop_period - 1;
|
||||
|
||||
if (!stream_info->composite_flag)
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
cfg_wm_irq_mask(vfe_dev, stream_info);
|
||||
|
||||
if (stream_info->init_stats_frame_drop == 0)
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(vfe_dev,
|
||||
stream_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
int rc = -1;
|
||||
struct msm_vfe_stats_stream_cfg_cmd stream_cfg_cmd;
|
||||
struct msm_vfe_stats_stream_release_cmd *stream_release_cmd = arg;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
int stats_idx = STATS_IDX(stream_release_cmd->stream_handle);
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
|
||||
if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
if (stream_info->state == STATS_AVAILABLE) {
|
||||
pr_err("%s: stream already release\n", __func__);
|
||||
return rc;
|
||||
} else if (stream_info->state != STATS_INACTIVE) {
|
||||
stream_cfg_cmd.enable = 0;
|
||||
stream_cfg_cmd.num_streams = 1;
|
||||
stream_cfg_cmd.stream_handle[0] =
|
||||
stream_release_cmd->stream_handle;
|
||||
rc = msm_isp_cfg_stats_stream(vfe_dev, &stream_cfg_cmd);
|
||||
}
|
||||
|
||||
if (!stream_info->composite_flag)
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
clear_wm_irq_mask(vfe_dev, stream_info);
|
||||
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.clear_wm_reg(vfe_dev, stream_info);
|
||||
memset(stream_info, 0, sizeof(struct msm_vfe_stats_stream));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_isp_init_stats_ping_pong_reg(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
stream_info->bufq_handle =
|
||||
vfe_dev->buf_mgr->ops->get_bufq_handle(
|
||||
vfe_dev->buf_mgr, stream_info->session_id,
|
||||
stream_info->stream_id);
|
||||
if (stream_info->bufq_handle == 0) {
|
||||
pr_err("%s: no buf configured for stream: 0x%x\n",
|
||||
__func__, stream_info->stream_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev,
|
||||
stream_info, VFE_PING_FLAG, NULL);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: No free buffer for ping\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev,
|
||||
stream_info, VFE_PONG_FLAG, NULL);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: No free buffer for pong\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void msm_isp_deinit_stats_ping_pong_reg(
|
||||
struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream *stream_info)
|
||||
{
|
||||
int i;
|
||||
struct msm_isp_buffer *buf;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
buf = stream_info->buf[i];
|
||||
if (buf)
|
||||
vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
|
||||
buf->bufq_handle, buf->buf_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void msm_isp_update_stats_framedrop_reg(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int i;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
|
||||
for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
|
||||
stream_info = &stats_data->stream_info[i];
|
||||
if (stream_info->state != STATS_ACTIVE)
|
||||
continue;
|
||||
|
||||
if (stream_info->init_stats_frame_drop) {
|
||||
stream_info->init_stats_frame_drop--;
|
||||
if (stream_info->init_stats_frame_drop == 0) {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(
|
||||
vfe_dev, stream_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm_isp_stats_stream_update(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int i;
|
||||
uint32_t stats_mask = 0, comp_stats_mask = 0;
|
||||
uint32_t enable = 0;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
|
||||
for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
|
||||
if (stats_data->stream_info[i].state == STATS_START_PENDING ||
|
||||
stats_data->stream_info[i].state ==
|
||||
STATS_STOP_PENDING) {
|
||||
stats_mask |= i;
|
||||
enable = stats_data->stream_info[i].state ==
|
||||
STATS_START_PENDING ? 1 : 0;
|
||||
stats_data->stream_info[i].state =
|
||||
stats_data->stream_info[i].state ==
|
||||
STATS_START_PENDING ?
|
||||
STATS_STARTING : STATS_STOPPING;
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.enable_module(
|
||||
vfe_dev, BIT(i), enable);
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask(
|
||||
vfe_dev, BIT(i), enable);
|
||||
} else if (stats_data->stream_info[i].state == STATS_STARTING ||
|
||||
stats_data->stream_info[i].state == STATS_STOPPING) {
|
||||
if (stats_data->stream_info[i].composite_flag)
|
||||
comp_stats_mask |= i;
|
||||
stats_data->stream_info[i].state =
|
||||
stats_data->stream_info[i].state ==
|
||||
STATS_STARTING ? STATS_ACTIVE : STATS_INACTIVE;
|
||||
}
|
||||
}
|
||||
atomic_sub(1, &stats_data->stats_update);
|
||||
if (!atomic_read(&stats_data->stats_update))
|
||||
complete(&vfe_dev->stats_config_complete);
|
||||
}
|
||||
|
||||
static int msm_isp_stats_wait_for_cfg_done(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
init_completion(&vfe_dev->stats_config_complete);
|
||||
atomic_set(&vfe_dev->stats_data.stats_update, 2);
|
||||
rc = wait_for_completion_timeout(
|
||||
&vfe_dev->stats_config_complete,
|
||||
msecs_to_jiffies(VFE_MAX_CFG_TIMEOUT));
|
||||
if (rc == 0) {
|
||||
pr_err("%s: wait timeout\n", __func__);
|
||||
rc = -1;
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_isp_stats_update_cgc_override(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd)
|
||||
{
|
||||
int i;
|
||||
uint32_t stats_mask = 0, idx;
|
||||
|
||||
if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) {
|
||||
pr_err("%s invalid num_streams %d\n", __func__,
|
||||
stream_cfg_cmd->num_streams);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
|
||||
if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
stats_mask |= 1 << idx;
|
||||
}
|
||||
|
||||
if (vfe_dev->hw_info->vfe_ops.stats_ops.update_cgc_override) {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.update_cgc_override(
|
||||
vfe_dev, stats_mask, stream_cfg_cmd->enable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint32_t stats_mask = 0, idx;
|
||||
uint32_t comp_stats_mask[MAX_NUM_STATS_COMP_MASK] = {0};
|
||||
uint32_t num_stats_comp_mask = 0;
|
||||
struct msm_vfe_stats_stream *stream_info;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
|
||||
if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) {
|
||||
pr_err("%s invalid num_streams %d\n", __func__,
|
||||
stream_cfg_cmd->num_streams);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_stats_comp_mask =
|
||||
vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;
|
||||
rc = vfe_dev->hw_info->vfe_ops.stats_ops.check_streams(
|
||||
stats_data->stream_info);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
|
||||
if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
if (stream_info->stream_handle !=
|
||||
stream_cfg_cmd->stream_handle[i]) {
|
||||
pr_err("%s: Invalid stream handle: 0x%x received\n",
|
||||
__func__, stream_cfg_cmd->stream_handle[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stream_info->composite_flag > num_stats_comp_mask) {
|
||||
pr_err("%s: comp grp %d exceed max %d\n",
|
||||
__func__, stream_info->composite_flag,
|
||||
num_stats_comp_mask);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = msm_isp_init_stats_ping_pong_reg(vfe_dev, stream_info);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: No buffer for stream%d type:%d stmID:0x%x\n",
|
||||
__func__, idx, stream_info->stats_type,
|
||||
stream_info->stream_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].active)
|
||||
stream_info->state = STATS_START_PENDING;
|
||||
else
|
||||
stream_info->state = STATS_ACTIVE;
|
||||
|
||||
stats_data->num_active_stream++;
|
||||
stats_mask |= 1 << idx;
|
||||
|
||||
if (stream_info->composite_flag > 0)
|
||||
comp_stats_mask[stream_info->composite_flag-1] |=
|
||||
1 << idx;
|
||||
|
||||
ISP_DBG("%s: stats_mask %x %x active streams %d\n",
|
||||
__func__, comp_stats_mask[0],
|
||||
comp_stats_mask[1],
|
||||
stats_data->num_active_stream);
|
||||
|
||||
}
|
||||
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) {
|
||||
rc = msm_isp_stats_wait_for_cfg_done(vfe_dev);
|
||||
} else {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.enable_module(
|
||||
vfe_dev, stats_mask, stream_cfg_cmd->enable);
|
||||
for (i = 0; i < num_stats_comp_mask; i++) {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask(
|
||||
vfe_dev, comp_stats_mask[i], 1);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint32_t stats_mask = 0, idx;
|
||||
uint32_t comp_stats_mask[MAX_NUM_STATS_COMP_MASK] = {0};
|
||||
uint32_t num_stats_comp_mask = 0;
|
||||
struct msm_vfe_stats_stream *stream_info;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
|
||||
num_stats_comp_mask =
|
||||
vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask;
|
||||
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
|
||||
if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
if (stream_info->stream_handle !=
|
||||
stream_cfg_cmd->stream_handle[i]) {
|
||||
pr_err("%s: Invalid stream handle: 0x%x received\n",
|
||||
__func__, stream_cfg_cmd->stream_handle[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stream_info->composite_flag > num_stats_comp_mask) {
|
||||
pr_err("%s: comp grp %d exceed max %d\n",
|
||||
__func__, stream_info->composite_flag,
|
||||
num_stats_comp_mask);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].active)
|
||||
stream_info->state = STATS_STOP_PENDING;
|
||||
else
|
||||
stream_info->state = STATS_INACTIVE;
|
||||
|
||||
stats_data->num_active_stream--;
|
||||
stats_mask |= 1 << idx;
|
||||
|
||||
if (stream_info->composite_flag > 0)
|
||||
comp_stats_mask[stream_info->composite_flag-1] |=
|
||||
1 << idx;
|
||||
|
||||
ISP_DBG("%s: stats_mask %x %x active streams %d\n",
|
||||
__func__, comp_stats_mask[0],
|
||||
comp_stats_mask[1],
|
||||
stats_data->num_active_stream);
|
||||
}
|
||||
|
||||
if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) {
|
||||
rc = msm_isp_stats_wait_for_cfg_done(vfe_dev);
|
||||
} else {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.enable_module(
|
||||
vfe_dev, stats_mask, stream_cfg_cmd->enable);
|
||||
for (i = 0; i < num_stats_comp_mask; i++) {
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask(
|
||||
vfe_dev, comp_stats_mask[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
|
||||
if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
msm_isp_deinit_stats_ping_pong_reg(vfe_dev, stream_info);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg;
|
||||
|
||||
if (vfe_dev->stats_data.num_active_stream == 0)
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev);
|
||||
|
||||
if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) {
|
||||
pr_err("%s invalid num_streams %d\n", __func__,
|
||||
stream_cfg_cmd->num_streams);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stream_cfg_cmd->enable) {
|
||||
msm_isp_stats_update_cgc_override(vfe_dev, stream_cfg_cmd);
|
||||
|
||||
rc = msm_isp_start_stats_stream(vfe_dev, stream_cfg_cmd);
|
||||
} else {
|
||||
rc = msm_isp_stop_stats_stream(vfe_dev, stream_cfg_cmd);
|
||||
|
||||
msm_isp_stats_update_cgc_override(vfe_dev, stream_cfg_cmd);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
int rc = 0, i;
|
||||
struct msm_vfe_stats_stream *stream_info;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
struct msm_vfe_axi_stream_update_cmd *update_cmd = arg;
|
||||
struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL;
|
||||
|
||||
/*validate request*/
|
||||
for (i = 0; i < update_cmd->num_streams; i++) {
|
||||
update_info = &update_cmd->update_info[i];
|
||||
/*check array reference bounds*/
|
||||
if (STATS_IDX(update_info->stream_handle)
|
||||
> vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
pr_err("%s: stats idx %d out of bound!", __func__,
|
||||
STATS_IDX(update_info->stream_handle));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < update_cmd->num_streams; i++) {
|
||||
update_info = &update_cmd->update_info[i];
|
||||
stream_info = &stats_data->stream_info[
|
||||
STATS_IDX(update_info->stream_handle)];
|
||||
if (stream_info->stream_handle !=
|
||||
update_info->stream_handle) {
|
||||
pr_err("%s: stats stream handle %x %x mismatch!\n",
|
||||
__func__, stream_info->stream_handle,
|
||||
update_info->stream_handle);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (update_cmd->update_type) {
|
||||
case UPDATE_STREAM_STATS_FRAMEDROP_PATTERN: {
|
||||
uint32_t framedrop_period =
|
||||
msm_isp_get_framedrop_period(
|
||||
update_info->skip_pattern);
|
||||
if (update_info->skip_pattern == SKIP_ALL)
|
||||
stream_info->framedrop_pattern = 0x0;
|
||||
else
|
||||
stream_info->framedrop_pattern = 0x1;
|
||||
stream_info->framedrop_period = framedrop_period - 1;
|
||||
if (stream_info->init_stats_frame_drop == 0)
|
||||
vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(
|
||||
vfe_dev, stream_info);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
pr_err("%s: Invalid update type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* Copyright (c) 2013-2018, 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 __MSM_ISP_STATS_UTIL_H__
|
||||
#define __MSM_ISP_STATS_UTIL_H__
|
||||
|
||||
#include "msm_isp_32.h"
|
||||
#define STATS_IDX(idx) (idx & 0xFF)
|
||||
|
||||
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
|
||||
uint32_t irq_status0, uint32_t irq_status1,
|
||||
struct msm_isp_timestamp *ts);
|
||||
int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_stream_request_cmd *stream_req_cmd);
|
||||
void msm_isp_stats_stream_update(struct vfe_device *vfe_dev);
|
||||
int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg);
|
||||
void msm_isp_update_stats_framedrop_reg(struct vfe_device *vfe_dev);
|
||||
#endif /* __MSM_ISP_STATS_UTIL_H__ */
|
||||
1939
drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c
Normal file
1939
drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c
Normal file
File diff suppressed because it is too large
Load diff
84
drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h
Normal file
84
drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* Copyright (c) 2013-2018, 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 __MSM_ISP_UTIL_H__
|
||||
#define __MSM_ISP_UTIL_H__
|
||||
|
||||
#include "msm_isp_32.h"
|
||||
#include <soc/qcom/camera2.h>
|
||||
|
||||
/* #define CONFIG_MSM_ISP_DBG 1 */
|
||||
|
||||
#ifdef CONFIG_MSM_ISP_DBG
|
||||
#define ISP_DBG(fmt, args...) printk(fmt, ##args)
|
||||
#else
|
||||
#define ISP_DBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#endif
|
||||
|
||||
#define ALT_VECTOR_IDX(x) {x = 3 - x; }
|
||||
|
||||
struct msm_isp_bandwidth_mgr {
|
||||
uint32_t bus_client;
|
||||
uint32_t bus_vector_active_idx;
|
||||
uint32_t use_count;
|
||||
struct msm_isp_bandwidth_info client_info[MAX_ISP_CLIENT];
|
||||
};
|
||||
|
||||
uint32_t msm_isp_get_framedrop_period(
|
||||
enum msm_vfe_frame_skip_pattern frame_skip_pattern);
|
||||
void msm_isp_reset_burst_count_and_frame_drop(
|
||||
struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info);
|
||||
|
||||
int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client);
|
||||
int msm_isp_update_bandwidth(enum msm_isp_hw_client client,
|
||||
uint64_t ab, uint64_t ib);
|
||||
void msm_isp_util_get_bandwidth_stats(struct vfe_device *vfe_dev,
|
||||
struct msm_isp_statistics *stats);
|
||||
void msm_isp_util_update_last_overflow_ab_ib(struct vfe_device *vfe_dev);
|
||||
void msm_isp_util_update_clk_rate(long clock_rate);
|
||||
void msm_isp_update_req_history(uint32_t client, uint64_t ab,
|
||||
uint64_t ib,
|
||||
struct msm_isp_bandwidth_info *client_info,
|
||||
unsigned long long ts);
|
||||
void msm_isp_deinit_bandwidth_mgr(enum msm_isp_hw_client client);
|
||||
|
||||
int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
struct v4l2_event_subscription *sub);
|
||||
|
||||
int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
struct v4l2_event_subscription *sub);
|
||||
|
||||
int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg);
|
||||
int msm_isp_send_event(struct vfe_device *vfe_dev,
|
||||
uint32_t type, struct msm_isp32_event_data *event_data);
|
||||
int msm_isp_cal_word_per_line(uint32_t output_format,
|
||||
uint32_t pixel_per_line);
|
||||
int msm_isp_get_bit_per_pixel(uint32_t output_format);
|
||||
enum msm_isp_pack_fmt msm_isp_get_pack_format(uint32_t output_format);
|
||||
irqreturn_t msm_isp_process_irq(int irq_num, void *data);
|
||||
int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
|
||||
void msm_isp_do_tasklet(unsigned long data);
|
||||
void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev);
|
||||
void msm_isp_process_error_info(struct vfe_device *vfe_dev);
|
||||
int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
|
||||
int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
|
||||
long msm_isp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
|
||||
int msm_isp_get_clk_info(struct vfe_device *vfe_dev,
|
||||
struct platform_device *pdev, struct msm_cam_clk_info *vfe_clk_info);
|
||||
void msm_isp_fetch_engine_done_notify(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_fetch_engine_info *fetch_engine_info);
|
||||
void msm_camera_io_dump_2(void __iomem *addr, int size);
|
||||
void msm_isp_print_fourcc_error(const char *origin, uint32_t fourcc_format);
|
||||
void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp,
|
||||
struct vfe_device *vfe_dev);
|
||||
void msm_isp_get_avtimer_ts(struct msm_isp_timestamp *time_stamp);
|
||||
int msm_isp_cfg_input(struct vfe_device *vfe_dev, void *arg);
|
||||
#endif /* __MSM_ISP_UTIL_H__ */
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
ccflags-y += -Idrivers/media/platform/msm/camera_v2
|
||||
ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
|
||||
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
|
||||
ifeq ($(CONFIG_MSM_ISP_V1),y)
|
||||
obj-$(CONFIG_MSM_CSID) += msm_ispif_32.o
|
||||
else
|
||||
obj-$(CONFIG_MSM_CSID) += msm_ispif.o
|
||||
endif
|
||||
|
|
|
|||
1581
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c
Normal file
1581
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c
Normal file
File diff suppressed because it is too large
Load diff
69
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h
Normal file
69
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* Copyright (c) 2013-2018, 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 MSM_ISPIF_H
|
||||
#define MSM_ISPIF_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/msmb_ispif.h>
|
||||
#include "msm_sd.h"
|
||||
|
||||
#define ISPIF_CLK_INFO_MAX 24
|
||||
|
||||
struct ispif_irq_status {
|
||||
uint32_t ispifIrqStatus0;
|
||||
uint32_t ispifIrqStatus1;
|
||||
uint32_t ispifIrqStatus2;
|
||||
};
|
||||
|
||||
enum msm_ispif_state_t {
|
||||
ISPIF_POWER_UP,
|
||||
ISPIF_POWER_DOWN,
|
||||
};
|
||||
struct ispif_sof_count {
|
||||
uint32_t sof_cnt[INTF_MAX];
|
||||
};
|
||||
|
||||
struct ispif_intf_cmd {
|
||||
uint32_t intf_cmd;
|
||||
uint32_t intf_cmd1;
|
||||
};
|
||||
|
||||
struct ispif_device {
|
||||
struct platform_device *pdev;
|
||||
struct msm_sd_subdev msm_sd;
|
||||
struct resource *mem;
|
||||
struct resource *clk_mux_mem;
|
||||
struct resource *irq;
|
||||
struct resource *io;
|
||||
struct resource *clk_mux_io;
|
||||
void __iomem *base;
|
||||
void __iomem *clk_mux_base;
|
||||
struct mutex mutex;
|
||||
uint8_t start_ack_pending;
|
||||
uint32_t csid_version;
|
||||
int enb_dump_reg;
|
||||
uint32_t open_cnt;
|
||||
struct ispif_sof_count sof_count[VFE_MAX];
|
||||
struct ispif_intf_cmd applied_intf_cmd[VFE_MAX];
|
||||
enum msm_ispif_state_t ispif_state;
|
||||
struct msm_ispif_vfe_info vfe_info;
|
||||
struct clk *ahb_clk[ISPIF_CLK_INFO_MAX];
|
||||
struct completion reset_complete[VFE_MAX];
|
||||
uint32_t hw_num_isps;
|
||||
uint32_t num_ahb_clk;
|
||||
uint32_t clk_idx;
|
||||
uint32_t ispif_sof_debug;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -2077,14 +2077,8 @@ static struct platform_driver msm_actuator_platform_driver = {
|
|||
|
||||
static int __init msm_actuator_init_module(void)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
|
||||
CDBG("Enter\n");
|
||||
rc = platform_driver_register(&msm_actuator_platform_driver);
|
||||
if (!rc)
|
||||
return rc;
|
||||
|
||||
CDBG("%s:%d rc %d\n", __func__, __LINE__, rc);
|
||||
platform_driver_register(&msm_actuator_platform_driver);
|
||||
return i2c_add_driver(&msm_actuator_i2c_driver);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,8 +323,7 @@ static int msm_csid_config(struct csid_device *csid_dev,
|
|||
if (!msm_csid_find_max_clk_rate(csid_dev))
|
||||
pr_err("msm_csid_find_max_clk_rate failed\n");
|
||||
|
||||
clk_rate = (csid_params->csi_clk > 0) ?
|
||||
(csid_params->csi_clk) : csid_dev->csid_max_clk;
|
||||
clk_rate = csid_dev->csid_max_clk;
|
||||
|
||||
clk_rate = msm_camera_clk_set_rate(&csid_dev->pdev->dev,
|
||||
csid_dev->csid_clk[csid_dev->csid_clk_index], clk_rate);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include "include/msm_csiphy_5_0_hwreg.h"
|
||||
#include "include/msm_csiphy_5_0_1_hwreg.h"
|
||||
#include "include/msm_csiphy_10_0_0_hwreg.h"
|
||||
|
||||
#include "cam_hw_ops.h"
|
||||
|
||||
#define DBG_CSIPHY 0
|
||||
|
|
@ -1248,9 +1247,7 @@ static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
|
|||
return rc;
|
||||
}
|
||||
|
||||
clk_rate = (csiphy_params->csiphy_clk > 0)
|
||||
? csiphy_params->csiphy_clk :
|
||||
csiphy_dev->csiphy_max_clk;
|
||||
clk_rate = csiphy_dev->csiphy_max_clk;
|
||||
clk_rate = msm_camera_clk_set_rate(&csiphy_dev->pdev->dev,
|
||||
csiphy_dev->csiphy_clk[csiphy_dev->csiphy_clk_index],
|
||||
clk_rate);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "msm_sensor.h"
|
||||
|
||||
#undef CDBG
|
||||
#define MSM_CAMERA_TZ_I2C_VERBOSE
|
||||
|
||||
#ifdef CONFIG_MSM_SEC_CCI_DEBUG
|
||||
#define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue