msm: camera: isp: Use single stream for dual vfe

Restructure code to handle dual vfe cases in a more streamline
manner. Instead of using 2 streams in case of dual vfe only
1 stream is used and the vfe devices are added under the
stream. All stream operations that refer to vfe will operate
on all the vfe devices present under stream. It is now not
nessasary to check whether dual vfe is used in multiple places
to decide which hardware needs to be updated, instead just
loop through the list of vfe hardware under the stream

Change-Id: I40ba5c9fe8bf96f81fc5256042b4a70731520e1d
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
This commit is contained in:
Shubhraprakash Das 2016-08-16 10:55:11 -07:00
parent 26ea3057fc
commit f6cb7eca5a
16 changed files with 3126 additions and 2419 deletions

View file

@ -654,95 +654,35 @@ static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr,
return rc;
}
static int msm_isp_update_put_buf_cnt_unsafe(
struct msm_isp_buf_mgr *buf_mgr,
uint32_t id, uint32_t bufq_handle, int32_t buf_index,
struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit)
static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index,
struct timeval *tv, uint32_t frame_id)
{
int rc = -1;
unsigned long flags;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
uint8_t *put_buf_mask = NULL;
bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
if (!bufq) {
pr_err("Invalid bufq\n");
return rc;
return -EINVAL;
}
put_buf_mask = &bufq->put_buf_mask[pingpong_bit];
if (buf_index >= 0) {
buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index);
if (!buf_info) {
pr_err("%s: buf not found\n", __func__);
return -EFAULT;
}
if (buf_info->state != MSM_ISP_BUFFER_STATE_DEQUEUED) {
pr_err(
"%s: Invalid state, bufq_handle %x stream id %x, state %d\n",
__func__, bufq_handle,
bufq->stream_id, buf_info->state);
return -EFAULT;
}
if (buf_info->pingpong_bit != pingpong_bit) {
pr_err("%s: Pingpong bit mismatch\n", __func__);
return -EFAULT;
}
}
if (bufq->buf_type != ISP_SHARE_BUF ||
(*put_buf_mask == 0)) {
if (buf_info)
buf_info->frame_id = frame_id;
}
if (bufq->buf_type == ISP_SHARE_BUF &&
((*put_buf_mask & (1 << id)) == 0)) {
*put_buf_mask |= (1 << id);
if (*put_buf_mask != ISP_SHARE_BUF_MASK) {
rc = *put_buf_mask;
return 1;
}
*put_buf_mask = 0;
rc = 0;
} else if (bufq->buf_type == ISP_SHARE_BUF &&
(*put_buf_mask & (1 << id)) != 0) {
return -ENOTEMPTY;
}
if (buf_info &&
MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) {
buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
buf_info->tv = tv;
}
return 0;
}
static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr,
uint32_t id, uint32_t bufq_handle, int32_t buf_index,
struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit)
{
int rc = -1;
struct msm_isp_bufq *bufq = NULL;
unsigned long flags;
bufq = msm_isp_get_bufq(buf_mgr, bufq_handle);
if (!bufq) {
pr_err("Invalid bufq\n");
return rc;
buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index);
if (!buf_info) {
pr_err("%s: buf not found\n", __func__);
return -EINVAL;
}
spin_lock_irqsave(&bufq->bufq_lock, flags);
rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr, id, bufq_handle,
buf_index, tv, frame_id, pingpong_bit);
if (-ENOTEMPTY == rc) {
pr_err("%s: Error! Uncleared put_buf_mask for pingpong(%d) from vfe %d bufq 0x%x buf_idx %d\n",
__func__, pingpong_bit, id, bufq_handle, buf_index);
rc = -EFAULT;
buf_info->frame_id = frame_id;
if (BUF_SRC(bufq->stream_id) == MSM_ISP_BUFFER_SRC_NATIVE) {
buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED;
buf_info->tv = tv;
}
spin_unlock_irqrestore(&bufq->bufq_lock, flags);
return rc;
return 0;
}
static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr,
@ -800,11 +740,11 @@ done:
return rc;
}
static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type,
struct timeval *tv, uint32_t frame_id)
{
int rc = 0, i;
int i;
struct msm_isp_bufq *bufq = NULL;
struct msm_isp_buffer *buf_info = NULL;
unsigned long flags;
@ -822,43 +762,27 @@ static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
pr_err("%s: buf not found\n", __func__);
continue;
}
if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED &&
buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
switch (flush_type) {
case MSM_ISP_BUFFER_FLUSH_DIVERTED:
if (buf_info->state !=
MSM_ISP_BUFFER_STATE_DIVERTED)
continue;
buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED;
msm_isp_put_buf_unsafe(buf_mgr,
bufq_handle, buf_info->buf_idx);
} else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL) {
if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) {
CDBG("%s: no need to queue Diverted buffer\n",
__func__);
} else if (buf_info->state ==
MSM_ISP_BUFFER_STATE_DEQUEUED) {
rc = msm_isp_update_put_buf_cnt_unsafe(buf_mgr,
id, bufq_handle, buf_info->buf_idx, tv,
frame_id, buf_info->pingpong_bit);
if (-ENOTEMPTY == rc) {
rc = 0;
continue;
}
if (rc == 0) {
buf_info->buf_debug.put_state[
buf_info->buf_debug.
put_state_last]
= MSM_ISP_BUFFER_STATE_FLUSH;
buf_info->buf_debug.put_state_last ^= 1;
buf_info->state =
MSM_ISP_BUFFER_STATE_PREPARED;
rc = msm_isp_put_buf_unsafe(buf_mgr,
bufq_handle, buf_info->buf_idx);
if (rc == -EFAULT) {
spin_unlock_irqrestore(
&bufq->bufq_lock,
flags);
return rc;
}
}
}
bufq_handle, buf_info->buf_idx);
break;
case MSM_ISP_BUFFER_FLUSH_ALL:
if (buf_info->state ==
MSM_ISP_BUFFER_STATE_DIVERTED)
continue;
if (buf_info->state !=
MSM_ISP_BUFFER_STATE_DEQUEUED)
continue;
msm_isp_put_buf_unsafe(buf_mgr,
bufq_handle, buf_info->buf_idx);
break;
default:
WARN(1, "Invalid flush type %d\n", flush_type);
}
}
@ -1036,8 +960,6 @@ static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr,
bufq->stream_id = buf_request->stream_id;
bufq->num_bufs = buf_request->num_buf;
bufq->buf_type = buf_request->buf_type;
for (i = 0; i < ISP_NUM_BUF_MASK; i++)
bufq->put_buf_mask[i] = 0;
INIT_LIST_HEAD(&bufq->head);
for (i = 0; i < buf_request->num_buf; i++) {
@ -1453,7 +1375,7 @@ static struct msm_isp_buf_ops isp_buf_ops = {
.buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr,
.buf_mgr_debug = msm_isp_buf_mgr_debug,
.get_bufq = msm_isp_get_bufq,
.update_put_buf_cnt = msm_isp_update_put_buf_cnt,
.buf_divert = msm_isp_buf_divert,
};
int msm_isp_create_isp_buf_mgr(

View file

@ -117,7 +117,6 @@ struct msm_isp_bufq {
enum msm_isp_buf_type buf_type;
struct msm_isp_buffer *bufs;
spinlock_t bufq_lock;
uint8_t put_buf_mask[ISP_NUM_BUF_MASK];
/*Native buffer queue*/
struct list_head head;
};
@ -157,7 +156,7 @@ struct msm_isp_buf_ops {
int (*put_buf)(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index);
int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type,
struct timeval *tv, uint32_t frame_id);
@ -174,9 +173,9 @@ struct msm_isp_buf_ops {
unsigned long fault_addr);
struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle);
int (*update_put_buf_cnt)(struct msm_isp_buf_mgr *buf_mgr,
uint32_t id, uint32_t bufq_handle, int32_t buf_index,
struct timeval *tv, uint32_t frame_id, uint32_t pingpong_bit);
int (*buf_divert)(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index,
struct timeval *tv, uint32_t frame_id);
};
struct msm_isp_buf_mgr {

View file

@ -498,7 +498,12 @@ static int vfe_probe(struct platform_device *pdev)
vfe_parent_dev->common_sd->common_data = &vfe_common_data;
memset(&vfe_common_data, 0, sizeof(vfe_common_data));
mutex_init(&vfe_common_data.vfe_common_mutex);
spin_lock_init(&vfe_common_data.common_dev_data_lock);
for (i = 0; i < (VFE_AXI_SRC_MAX * MAX_VFE); i++)
spin_lock_init(&(vfe_common_data.streams[i].lock));
for (i = 0; i < (MSM_ISP_STATS_MAX * MAX_VFE); i++)
spin_lock_init(&(vfe_common_data.stats_streams[i].lock));
of_property_read_u32(pdev->dev.of_node,
"num_child", &vfe_parent_dev->num_hw_sd);

View file

@ -169,7 +169,7 @@ struct msm_vfe_axi_ops {
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)(void __iomem *vfe_base,
void (*cfg_framedrop)(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info,
uint32_t framedrop_pattern, uint32_t framedrop_period);
void (*clear_framedrop)(struct vfe_device *vfe_dev,
@ -207,7 +207,7 @@ struct msm_vfe_axi_ops {
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,
void (*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);
@ -270,7 +270,7 @@ struct msm_vfe_stats_ops {
void (*enable_module)(struct vfe_device *vfe_dev,
uint32_t stats_mask, uint8_t enable);
void (*update_ping_pong_addr)(void __iomem *vfe_base,
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);
@ -373,12 +373,6 @@ enum msm_vfe_axi_state {
UPDATING,
};
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
@ -398,6 +392,14 @@ struct msm_vfe_frame_request_queue {
uint8_t cmd_used;
};
enum msm_isp_comp_irq_types {
MSM_ISP_COMP_IRQ_REG_UPD = 0,
MSM_ISP_COMP_IRQ_EPOCH = 1,
MSM_ISP_COMP_IRQ_PING_BUFDONE = 2,
MSM_ISP_COMP_IRQ_PONG_BUFDONE = 3,
MSM_ISP_COMP_IRQ_MAX = 4
};
#define MSM_VFE_REQUESTQ_SIZE 8
struct msm_vfe_axi_stream {
@ -405,10 +407,10 @@ struct msm_vfe_axi_stream {
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];
uint8_t wm[MAX_VFE][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_vfe_axi_plane_cfg plane_cfg[MAX_VFE][MAX_PLANES_PER_STREAM];
uint8_t comp_mask_index[MAX_VFE];
struct msm_isp_buffer *buf[2];
uint32_t session_id;
uint32_t stream_id;
@ -420,7 +422,7 @@ struct msm_vfe_axi_stream {
struct list_head request_q;
struct msm_vfe_frame_request_queue
request_queue_cmd[MSM_VFE_REQUESTQ_SIZE];
uint32_t stream_handle;
uint32_t stream_handle[MAX_VFE];
uint8_t buf_divert;
enum msm_vfe_axi_stream_type stream_type;
uint32_t frame_based;
@ -433,16 +435,28 @@ struct msm_vfe_axi_stream {
spinlock_t lock;
/*Bandwidth calculation info*/
uint32_t max_width;
uint32_t max_width[MAX_VFE];
/*Based on format plane size in Q2. e.g NV12 = 1.5*/
uint32_t format_factor;
uint32_t bandwidth;
uint32_t bandwidth[MAX_VFE];
uint32_t runtime_num_burst_capture;
uint32_t runtime_output_format;
enum msm_stream_memory_input_t memory_input;
struct msm_isp_sw_framskip sw_skip;
uint8_t sw_ping_pong_bit;
struct vfe_device *vfe_dev[MAX_VFE];
int num_isp;
struct completion active_comp;
struct completion inactive_comp;
uint32_t update_vfe_mask;
/*
* bits in this mask are set that correspond to vfe_id of
* the vfe on which this stream operates
*/
uint32_t vfe_mask;
uint32_t composite_irq[MSM_ISP_COMP_IRQ_MAX];
};
struct msm_vfe_axi_composite_info {
@ -451,17 +465,15 @@ struct msm_vfe_axi_composite_info {
};
enum msm_vfe_camif_state {
CAMIF_STOPPED,
CAMIF_ENABLE,
CAMIF_DISABLE,
CAMIF_STOPPING,
};
struct msm_vfe_src_info {
uint32_t frame_id;
uint32_t reg_update_frame_id;
uint8_t active;
uint8_t pix_stream_count;
uint8_t stream_count;
uint8_t raw_stream_count;
enum msm_vfe_inputmux input_mux;
uint32_t width;
@ -492,7 +504,6 @@ enum msm_wm_ub_cfg_type {
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;
@ -504,14 +515,11 @@ struct msm_vfe_axi_shared_data {
struct msm_vfe_axi_composite_info
composite_info[MAX_NUM_COMPOSITE_MASK];
uint8_t num_used_composite_mask;
uint32_t stream_update[VFE_SRC_MAX];
atomic_t axi_cfg_update[VFE_SRC_MAX];
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;
uint8_t enable_frameid_recovery;
enum msm_vfe_camif_state camif_state;
};
struct msm_vfe_stats_hardware_info {
@ -523,7 +531,7 @@ struct msm_vfe_stats_hardware_info {
};
enum msm_vfe_stats_state {
STATS_AVALIABLE,
STATS_AVAILABLE,
STATS_INACTIVE,
STATS_ACTIVE,
STATS_START_PENDING,
@ -535,7 +543,7 @@ enum msm_vfe_stats_state {
struct msm_vfe_stats_stream {
uint32_t session_id;
uint32_t stream_id;
uint32_t stream_handle;
uint32_t stream_handle[MAX_VFE];
uint32_t composite_flag;
enum msm_isp_stats_type stats_type;
enum msm_vfe_stats_state state;
@ -545,17 +553,27 @@ struct msm_vfe_stats_stream {
uint32_t init_stats_frame_drop;
struct msm_isp_sw_framskip sw_skip;
uint32_t buffer_offset;
uint32_t buffer_offset[MAX_VFE];
struct msm_isp_buffer *buf[2];
uint32_t bufq_handle;
spinlock_t lock;
struct vfe_device *vfe_dev[MAX_VFE];
int num_isp;
struct completion active_comp;
struct completion inactive_comp;
/*
* bits in this mask are set that correspond to vfe_id of
* the vfe on which this stream operates
*/
uint32_t vfe_mask;
uint32_t composite_irq[MSM_ISP_COMP_IRQ_MAX];
};
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];
uint16_t stream_handle_cnt;
atomic_t stats_update;
};
struct msm_vfe_tasklet_queue_cmd {
@ -654,7 +672,6 @@ struct dual_vfe_resource {
struct msm_vfe_stats_shared_data *stats_data[MAX_VFE];
struct msm_vfe_axi_shared_data *axi_data[MAX_VFE];
uint32_t wm_reload_mask[MAX_VFE];
uint32_t epoch_sync_mask;
};
struct master_slave_resource_info {
@ -672,6 +689,9 @@ struct msm_vfe_common_dev_data {
spinlock_t common_dev_data_lock;
struct dual_vfe_resource *dual_vfe_res;
struct master_slave_resource_info ms_resource;
struct msm_vfe_axi_stream streams[VFE_AXI_SRC_MAX * MAX_VFE];
struct msm_vfe_stats_stream stats_streams[MSM_ISP_STATS_MAX * MAX_VFE];
struct mutex vfe_common_mutex;
};
struct msm_vfe_common_subdev {
@ -714,8 +734,6 @@ struct vfe_device {
/* Sync variables*/
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;
spinlock_t shared_data_lock;

View file

@ -412,10 +412,9 @@ 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].
pix_stream_count == 0) {
stream_count == 0) {
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
if (vfe_dev->axi_data.stream_update[VFE_PIX_0])
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0);
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0, ts);
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
}
}
@ -608,15 +607,14 @@ static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
if ((rdi_status & BIT(7)) && (!(irq_status0 & 0x20)))
return;
}
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_REG_UPD);
}
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);
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
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,
@ -693,8 +691,9 @@ 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;
stream_info->comp_mask_index[vfe_idx];
uint32_t irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
@ -711,7 +710,9 @@ 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)
{
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
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 irq_mask;
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x34);
@ -727,8 +728,10 @@ 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[0] + 6);
irq_mask |= BIT(stream_info->wm[vfe_idx][0] + 6);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
}
@ -736,15 +739,19 @@ 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[0] + 6);
irq_mask &= ~BIT(stream_info->wm[vfe_idx][0] + 6);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
}
static void msm_vfe32_cfg_framedrop(void __iomem *vfe_base,
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)
{
void __iomem *vfe_base = vfe_dev->vfe_base;
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);
@ -929,7 +936,7 @@ static void msm_vfe32_update_camif_state(
VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
vfe_en =
((vfe_dev->axi_data.src_info[
VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
VFE_PIX_0].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);
@ -971,16 +978,17 @@ static void msm_vfe32_axi_cfg_wm_reg(
uint8_t plane_idx)
{
uint32_t val;
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
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]);
if (!stream_info->frame_based) {
/*WR_IMAGE_SIZE*/
val =
((msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width)+1)/2 - 1) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
@ -988,9 +996,9 @@ static void msm_vfe32_axi_cfg_wm_reg(
val =
msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_stride) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1) << 4 | VFE32_BURST_LEN;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
} else {
@ -998,9 +1006,9 @@ static void msm_vfe32_axi_cfg_wm_reg(
val =
msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1) << 4 | VFE32_BURST_LEN;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
}
@ -1012,7 +1020,8 @@ static void msm_vfe32_axi_clear_wm_reg(
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint32_t val = 0;
uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]);
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]);
/*WR_IMAGE_SIZE*/
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10);
/*WR_BUFFER_CFG*/
@ -1024,9 +1033,10 @@ 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[plane_idx];
uint8_t wm = stream_info->wm[plane_idx];
&stream_info->plane_cfg[vfe_idx][plane_idx];
uint8_t wm = stream_info->wm[vfe_idx][plane_idx];
uint32_t xbar_cfg = 0;
uint32_t xbar_reg_cfg = 0;
@ -1080,7 +1090,8 @@ 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)
{
uint8_t wm = stream_info->wm[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];
uint32_t xbar_reg_cfg = 0;
xbar_reg_cfg = msm_camera_io_r(vfe_dev->vfe_base + VFE32_XBAR_BASE(wm));
@ -1098,6 +1109,7 @@ static void msm_vfe32_cfg_axi_ub_equal_default(struct vfe_device *vfe_dev)
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++;
@ -1243,9 +1255,11 @@ static void msm_vfe32_stats_cfg_comp_mask(struct vfe_device *vfe_dev,
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) + 13);
irq_mask |= BIT(STATS_IDX(stream_info->stream_handle[vfe_idx]) + 13);
msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C);
return;
}
@ -1342,12 +1356,15 @@ static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev,
msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x10);
}
static void msm_vfe32_stats_update_ping_pong_addr(void __iomem *vfe_base,
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)
{
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);
int stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
msm_camera_io_w(paddr32, vfe_base +
VFE32_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
}

View file

@ -599,7 +599,6 @@ static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
return;
/* Shift status bits so that PIX REG UPDATE is 1st bit */
shift_irq = ((irq_status0 & 0xF0) >> 4);
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
if (shift_irq & BIT(i)) {
reg_updated |= BIT(i);
@ -607,15 +606,17 @@ static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
(uint32_t)BIT(i));
switch (i) {
case VFE_PIX_0:
msm_isp_save_framedrop_values(vfe_dev,
VFE_PIX_0);
msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
VFE_PIX_0, ts);
if (atomic_read(
&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
if (vfe_dev->axi_data.camif_state ==
CAMIF_STOPPING)
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_REG_UPD);
if (vfe_dev->axi_data.src_info[i].stream_count
== 0 &&
vfe_dev->axi_data.src_info[i].
raw_stream_count == 0 &&
vfe_dev->axi_data.src_info[i].active)
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, i);
break;
@ -624,29 +625,22 @@ static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
case VFE_RAW_2:
msm_isp_increment_frame_id(vfe_dev, i, ts);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
msm_isp_update_framedrop_reg(vfe_dev, i);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
/*
* Reg Update is pseudo SOF for RDI,
* so request every frame
*/
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, i);
/* reg upd is also epoch for RDI */
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_EPOCH, ts);
break;
default:
pr_err("%s: Error case\n", __func__);
return;
}
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(
&vfe_dev->axi_data.axi_cfg_update[i]) ==
0)
msm_isp_notify(vfe_dev,
ISP_EVENT_STREAM_UPDATE_DONE,
i, ts);
}
}
}
@ -695,7 +689,9 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev,
vfe_dev->vfe_base + 0x378);
} else if (!vfe_dev->is_split ||
((frame_src == VFE_PIX_0) &&
(vfe_dev->axi_data.camif_state == CAMIF_STOPPING)) ||
(vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
(vfe_dev->axi_data.src_info[VFE_PIX_0].
raw_stream_count == 0)) ||
(frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
msm_camera_io_w_mb(update_mask,
vfe_dev->vfe_base + 0x378);
@ -713,16 +709,18 @@ static void msm_vfe40_process_epoch_irq(struct vfe_device *vfe_dev,
if (irq_status0 & BIT(2)) {
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
msm_isp_update_stats_framedrop_reg(vfe_dev);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_EPOCH, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_EPOCH);
msm_isp_update_error_frame_count(vfe_dev);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
pix_stream_count == 0) {
stream_count == 0) {
ISP_DBG("%s: SOF IRQ\n", __func__);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
if (vfe_dev->axi_data.stream_update[VFE_PIX_0])
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, VFE_PIX_0);
}
@ -791,8 +789,10 @@ static void msm_vfe40_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;
uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -807,8 +807,11 @@ static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
vfe_dev->irq0_mask &= ~BIT(27);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
vfe_dev->irq0_mask &= ~BIT(27);
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -821,32 +824,38 @@ static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe40_config_irq(vfe_dev, 1 << (stream_info->wm[0] + 8), 0,
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe40_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[0] + 8));
msm_vfe40_config_irq(vfe_dev, (1 << (stream_info->wm[0] + 8)), 0,
MSM_ISP_IRQ_DISABLE);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[vfe_idx][0] + 8));
msm_vfe40_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
0, MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe40_cfg_framedrop(void __iomem *vfe_base,
static void msm_vfe40_cfg_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
uint32_t framedrop_period)
{
void __iomem *vfe_base = vfe_dev->vfe_base;
uint32_t i, temp;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++) {
msm_camera_io_w(framedrop_pattern, vfe_base +
VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
temp = msm_camera_io_r(vfe_base +
VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
temp &= 0xFFFFFF83;
msm_camera_io_w(temp | (framedrop_period - 1) << 2,
vfe_base + VFE40_WM_BASE(stream_info->wm[i]) + 0xC);
vfe_base + VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
}
msm_camera_io_w_mb(0x1, vfe_base + 0x378);
@ -856,9 +865,11 @@ static void msm_vfe40_clear_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t i;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++)
msm_camera_io_w(0, vfe_dev->vfe_base +
VFE40_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
}
static int32_t msm_vfe40_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
@ -1374,7 +1385,7 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
vfe_en =
((vfe_dev->axi_data.
src_info[VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
val &= 0xFFFFFF3F;
val = val | bus_en << 7 | vfe_en << 6;
@ -1443,7 +1454,10 @@ static void msm_vfe40_axi_cfg_wm_reg(
{
uint32_t val;
uint32_t burst_len, wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION;
uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
vfe_dev->vfe_hw_version == VFE40_8939_VERSION) {
@ -1468,18 +1482,18 @@ static void msm_vfe40_axi_cfg_wm_reg(
val =
((msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width)+1)/2 - 1) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
/*WR_BUFFER_CFG*/
val =
msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[
stream_info->plane_cfg[vfe_idx][
plane_idx].output_stride) << 16 |
(stream_info->plane_cfg[
(stream_info->plane_cfg[vfe_idx][
plane_idx].output_height - 1) << wm_bit_shift |
burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
@ -1487,9 +1501,9 @@ static void msm_vfe40_axi_cfg_wm_reg(
msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
val =
msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[
stream_info->plane_cfg[vfe_idx][
plane_idx].output_width) << 16 |
(stream_info->plane_cfg[
(stream_info->plane_cfg[vfe_idx][
plane_idx].output_height - 1) << 4 |
burst_len;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
@ -1507,7 +1521,10 @@ static void msm_vfe40_axi_clear_wm_reg(
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint32_t val = 0;
uint32_t wm_base = VFE40_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
/*WR_ADDR_CFG*/
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
/*WR_IMAGE_SIZE*/
@ -1524,12 +1541,15 @@ static void msm_vfe40_axi_cfg_wm_xbar_reg(
struct msm_vfe_axi_stream *stream_info,
uint8_t plane_idx)
{
struct msm_vfe_axi_plane_cfg *plane_cfg =
&stream_info->plane_cfg[plane_idx];
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
struct msm_vfe_axi_plane_cfg *plane_cfg;
uint8_t wm;
uint32_t xbar_cfg = 0;
uint32_t xbar_reg_cfg = 0;
plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
wm = stream_info->wm[vfe_idx][plane_idx];
switch (stream_info->stream_src) {
case PIX_ENCODER:
case PIX_VIEWFINDER: {
@ -1584,9 +1604,12 @@ static void msm_vfe40_axi_clear_wm_xbar_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint8_t wm;
uint32_t xbar_reg_cfg = 0;
wm = stream_info->wm[vfe_idx][plane_idx];
xbar_reg_cfg =
msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
@ -1714,6 +1737,7 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
{
int rc = 0;
enum msm_vfe_input_src i;
struct msm_isp_timestamp ts;
/* Keep only halt and restart mask */
msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
@ -1722,30 +1746,16 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
msm_isp_get_timestamp(&ts);
/* if any stream is waiting for update, signal complete */
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
/* if any stream is waiting for update, signal complete */
if (vfe_dev->axi_data.stream_update[i]) {
ISP_DBG("%s: complete stream update\n", __func__);
msm_isp_axi_stream_update(vfe_dev, i);
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
}
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
ISP_DBG("%s: complete on axi config update\n",
__func__);
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i]))
msm_isp_axi_cfg_update(vfe_dev, i);
}
msm_isp_axi_stream_update(vfe_dev, i, &ts);
msm_isp_axi_stream_update(vfe_dev, i, &ts);
}
if (atomic_read(&vfe_dev->stats_data.stats_update)) {
ISP_DBG("%s: complete on stats update\n", __func__);
msm_isp_stats_stream_update(vfe_dev);
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
}
msm_isp_stats_stream_update(vfe_dev);
msm_isp_stats_stream_update(vfe_dev);
if (blocking) {
init_completion(&vfe_dev->halt_complete);
@ -1764,7 +1774,7 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
return rc;
}
static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
static void msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif)
{
msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
@ -1786,8 +1796,6 @@ static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, ENABLE_CAMIF);
}
return 0;
}
static uint32_t msm_vfe40_get_wm_mask(
@ -1903,27 +1911,37 @@ static void msm_vfe40_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);
msm_vfe40_config_irq(vfe_dev,
1 << (STATS_IDX(stream_info->stream_handle) + 16), 0,
MSM_ISP_IRQ_ENABLE);
1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe40_stats_clear_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);
msm_vfe40_config_irq(vfe_dev,
(1 << (STATS_IDX(stream_info->stream_handle) + 16)), 0,
MSM_ISP_IRQ_DISABLE);
(1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16)), 0,
MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe40_stats_cfg_wm_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE40_STATS_BASE(stats_idx);
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE40_STATS_BASE(stats_idx);
/*WR_ADDR_CFG*/
msm_camera_io_w(stream_info->framedrop_period << 2,
vfe_dev->vfe_base + stats_base + 0x8);
@ -1939,9 +1957,14 @@ static void msm_vfe40_stats_clear_wm_reg(
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 val = 0;
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE40_STATS_BASE(stats_idx);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE40_STATS_BASE(stats_idx);
/*WR_ADDR_CFG*/
msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x8);
@ -2095,11 +2118,16 @@ static void msm_vfe40_stats_enable_module(struct vfe_device *vfe_dev,
}
static void msm_vfe40_stats_update_ping_pong_addr(
void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info,
struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
uint32_t pingpong_status, 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);
int stats_idx;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
msm_camera_io_w(paddr32, vfe_base +
VFE40_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
}

View file

@ -437,15 +437,17 @@ static void msm_vfe44_process_reg_update(struct vfe_device *vfe_dev,
(uint32_t)BIT(i));
switch (i) {
case VFE_PIX_0:
msm_isp_save_framedrop_values(vfe_dev,
VFE_PIX_0);
msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
VFE_PIX_0, ts);
if (atomic_read(
&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
if (vfe_dev->axi_data.camif_state ==
CAMIF_STOPPING)
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_REG_UPD);
if (vfe_dev->axi_data.src_info[i].stream_count
== 0 &&
vfe_dev->axi_data.src_info[i].
raw_stream_count == 0 &&
vfe_dev->axi_data.src_info[i].active)
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, i);
break;
@ -454,29 +456,22 @@ static void msm_vfe44_process_reg_update(struct vfe_device *vfe_dev,
case VFE_RAW_2:
msm_isp_increment_frame_id(vfe_dev, i, ts);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
msm_isp_update_framedrop_reg(vfe_dev, i);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
/*
* Reg Update is pseudo SOF for RDI,
* so request every frame
*/
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, i);
/* reg upd is epoch for rdi */
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_EPOCH, ts);
break;
default:
pr_err("%s: Error case\n", __func__);
return;
}
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(
&vfe_dev->axi_data.axi_cfg_update[i]) ==
0)
msm_isp_notify(vfe_dev,
ISP_EVENT_STREAM_UPDATE_DONE,
i, ts);
}
}
}
@ -498,17 +493,19 @@ static void msm_vfe44_process_epoch_irq(struct vfe_device *vfe_dev,
if (irq_status0 & BIT(2)) {
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
msm_isp_update_stats_framedrop_reg(vfe_dev);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_EPOCH, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_EPOCH);
msm_isp_update_error_frame_count(vfe_dev);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
pix_stream_count == 0) {
stream_count == 0) {
ISP_DBG("%s: SOF IRQ\n", __func__);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
if (vfe_dev->axi_data.stream_update[VFE_PIX_0])
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0);
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, VFE_PIX_0);
}
}
@ -550,7 +547,9 @@ static void msm_vfe44_reg_update(struct vfe_device *vfe_dev,
vfe_dev->vfe_base + 0x378);
} else if (!vfe_dev->is_split ||
((frame_src == VFE_PIX_0) &&
(vfe_dev->axi_data.camif_state == CAMIF_STOPPING)) ||
(vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
(vfe_dev->axi_data.src_info[VFE_PIX_0].
raw_stream_count == 0)) ||
(frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
msm_camera_io_w_mb(update_mask,
vfe_dev->vfe_base + 0x378);
@ -628,8 +627,10 @@ static void msm_vfe44_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;
uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -644,7 +645,10 @@ static void msm_vfe44_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe44_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -657,31 +661,38 @@ static void msm_vfe44_axi_clear_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe44_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe44_config_irq(vfe_dev, 1 << (stream_info->wm[0] + 8), 0,
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe44_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe44_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe44_config_irq(vfe_dev, (1 << (stream_info->wm[0] + 8)), 0,
MSM_ISP_IRQ_DISABLE);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe44_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
0, MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe44_cfg_framedrop(void __iomem *vfe_base,
static void msm_vfe44_cfg_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
uint32_t framedrop_period)
{
void __iomem *vfe_base = vfe_dev->vfe_base;
uint32_t i, temp;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++) {
msm_camera_io_w(framedrop_pattern, vfe_base +
VFE44_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE44_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
temp = msm_camera_io_r(vfe_base +
VFE44_WM_BASE(stream_info->wm[i]) + 0xC);
VFE44_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
temp &= 0xFFFFFF83;
msm_camera_io_w(temp | (framedrop_period - 1) << 2,
vfe_base + VFE44_WM_BASE(stream_info->wm[i]) + 0xC);
vfe_base +
VFE44_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
}
}
@ -689,9 +700,11 @@ static void msm_vfe44_clear_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t i;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++)
msm_camera_io_w(0, vfe_dev->vfe_base +
VFE44_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE44_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
}
static int32_t msm_vfe44_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
@ -1039,7 +1052,7 @@ static void msm_vfe44_update_camif_state(struct vfe_device *vfe_dev,
src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
vfe_en =
((vfe_dev->axi_data.
src_info[VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
val &= 0xFFFFFF3F;
val = val | bus_en << 7 | vfe_en << 6;
@ -1101,7 +1114,10 @@ static void msm_vfe44_axi_cfg_wm_reg(
uint8_t plane_idx)
{
uint32_t val;
uint32_t wm_base = VFE44_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE44_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
if (!stream_info->frame_based) {
msm_camera_io_w(0x0, vfe_dev->vfe_base + wm_base);
@ -1109,28 +1125,30 @@ static void msm_vfe44_axi_cfg_wm_reg(
val =
((msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width)+1)/2 - 1) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
/*WR_BUFFER_CFG*/
val = (stream_info->plane_cfg[plane_idx].output_height - 1);
val = (stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
val = (((val & 0xfff) << 2) | ((val >> 12) & 0x3));
val = val << 2 |
msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[
stream_info->plane_cfg[vfe_idx][
plane_idx].output_stride) << 16 |
VFE44_BURST_LEN;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
} else {
msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
val = (stream_info->plane_cfg[plane_idx].output_height - 1);
val = (stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
val = (((val & 0xfff) << 2) | ((val >> 12) & 0x3));
val = val << 2 |
msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[
stream_info->plane_cfg[vfe_idx][
plane_idx].output_width) << 16 |
VFE44_BURST_LEN;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
@ -1147,8 +1165,10 @@ static void msm_vfe44_axi_clear_wm_reg(
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint32_t val = 0;
uint32_t wm_base = VFE44_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE44_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
/*WR_ADDR_CFG*/
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
/*WR_IMAGE_SIZE*/
@ -1164,12 +1184,15 @@ static void msm_vfe44_axi_cfg_wm_xbar_reg(
struct msm_vfe_axi_stream *stream_info,
uint8_t plane_idx)
{
struct msm_vfe_axi_plane_cfg *plane_cfg =
&stream_info->plane_cfg[plane_idx];
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
struct msm_vfe_axi_plane_cfg *plane_cfg;
uint8_t wm;
uint32_t xbar_cfg = 0;
uint32_t xbar_reg_cfg = 0;
plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
wm = stream_info->wm[vfe_idx][plane_idx];
switch (stream_info->stream_src) {
case PIX_ENCODER:
case PIX_VIEWFINDER: {
@ -1223,9 +1246,12 @@ static void msm_vfe44_axi_clear_wm_xbar_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint8_t wm;
uint32_t xbar_reg_cfg = 0;
wm = stream_info->wm[vfe_idx][plane_idx];
xbar_reg_cfg =
msm_camera_io_r(vfe_dev->vfe_base + VFE44_XBAR_BASE(wm));
xbar_reg_cfg &= ~(0xFFFF << VFE44_XBAR_SHIFT(wm));
@ -1245,6 +1271,7 @@ static void msm_vfe44_cfg_axi_ub_equal_default(
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++;
@ -1316,6 +1343,7 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev,
{
int rc = 0;
enum msm_vfe_input_src i;
struct msm_isp_timestamp ts;
/* Keep only halt and restart mask */
msm_vfe44_config_irq(vfe_dev, (1 << 31), (1 << 8),
@ -1349,34 +1377,20 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
}
msm_isp_get_timestamp(&ts);
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
/* if any stream is waiting for update, signal complete */
if (vfe_dev->axi_data.stream_update[i]) {
ISP_DBG("%s: complete stream update\n", __func__);
msm_isp_axi_stream_update(vfe_dev, i);
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
}
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
ISP_DBG("%s: complete on axi config update\n",
__func__);
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i]))
msm_isp_axi_cfg_update(vfe_dev, i);
}
msm_isp_axi_stream_update(vfe_dev, i, &ts);
msm_isp_axi_stream_update(vfe_dev, i, &ts);
}
if (atomic_read(&vfe_dev->stats_data.stats_update)) {
ISP_DBG("%s: complete on stats update\n", __func__);
msm_isp_stats_stream_update(vfe_dev);
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
}
msm_isp_stats_stream_update(vfe_dev);
msm_isp_stats_stream_update(vfe_dev);
return rc;
}
static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev,
static void msm_vfe44_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif)
{
msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
@ -1397,8 +1411,6 @@ static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, ENABLE_CAMIF);
}
return 0;
}
static uint32_t msm_vfe44_get_wm_mask(
@ -1450,15 +1462,15 @@ static int msm_vfe44_stats_check_streams(
struct msm_vfe_stats_stream *stream_info)
{
if (stream_info[STATS_IDX_BF].state ==
STATS_AVALIABLE &&
STATS_AVAILABLE &&
stream_info[STATS_IDX_BF_SCALE].state !=
STATS_AVALIABLE) {
STATS_AVAILABLE) {
pr_err("%s: does not support BF_SCALE while BF is disabled\n",
__func__);
return -EINVAL;
}
if (stream_info[STATS_IDX_BF].state != STATS_AVALIABLE &&
stream_info[STATS_IDX_BF_SCALE].state != STATS_AVALIABLE &&
if (stream_info[STATS_IDX_BF].state != STATS_AVAILABLE &&
stream_info[STATS_IDX_BF_SCALE].state != STATS_AVAILABLE &&
stream_info[STATS_IDX_BF].composite_flag !=
stream_info[STATS_IDX_BF_SCALE].composite_flag) {
pr_err("%s: Different composite flag for BF and BF_SCALE\n",
@ -1541,27 +1553,37 @@ static void msm_vfe44_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);
msm_vfe44_config_irq(vfe_dev,
1 << (STATS_IDX(stream_info->stream_handle) + 15), 0,
MSM_ISP_IRQ_ENABLE);
1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 15), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe44_stats_clear_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);
msm_vfe44_config_irq(vfe_dev,
(1 << (STATS_IDX(stream_info->stream_handle) + 15)), 0,
MSM_ISP_IRQ_DISABLE);
(1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 15)), 0,
MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe44_stats_cfg_wm_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE44_STATS_BASE(stats_idx);
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE44_STATS_BASE(stats_idx);
/* BF_SCALE does not have its own WR_ADDR_CFG,
* IRQ_FRAMEDROP_PATTERN and IRQ_SUBSAMPLE_PATTERN;
* it's using the same from BF */
@ -1582,9 +1604,14 @@ static void msm_vfe44_stats_clear_wm_reg(
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 val = 0;
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE44_STATS_BASE(stats_idx);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE44_STATS_BASE(stats_idx);
/* BF_SCALE does not have its own WR_ADDR_CFG,
* IRQ_FRAMEDROP_PATTERN and IRQ_SUBSAMPLE_PATTERN;
* it's using the same from BF */
@ -1742,12 +1769,16 @@ static void msm_vfe44_stats_update_cgc_override(struct vfe_device *vfe_dev,
}
static void msm_vfe44_stats_update_ping_pong_addr(
void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info,
struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
uint32_t pingpong_status, 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);
int stats_idx;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
msm_camera_io_w(paddr32, vfe_base +
VFE44_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
}

View file

@ -376,46 +376,40 @@ static void msm_vfe46_process_reg_update(struct vfe_device *vfe_dev,
switch (i) {
case VFE_PIX_0:
msm_isp_save_framedrop_values(vfe_dev,
VFE_PIX_0);
msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
VFE_PIX_0, ts);
if (atomic_read(
&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
if (vfe_dev->axi_data.camif_state ==
CAMIF_STOPPING)
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_REG_UPD);
msm_isp_stats_stream_update(vfe_dev);
if (vfe_dev->axi_data.src_info[i].stream_count
== 0 &&
vfe_dev->axi_data.src_info[i].active)
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, i);
reg_update(vfe_dev, i);
break;
case VFE_RAW_0:
case VFE_RAW_1:
case VFE_RAW_2:
msm_isp_increment_frame_id(vfe_dev, i, ts);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
msm_isp_update_framedrop_reg(vfe_dev, i);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
/*
* Reg Update is pseudo SOF for RDI,
* so request every frame
*/
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, i);
/* reg upd is also epoch for rdi */
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_EPOCH, ts);
break;
default:
pr_err("%s: Error case\n", __func__);
return;
}
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(
&vfe_dev->axi_data.axi_cfg_update[i]) ==
0)
msm_isp_notify(vfe_dev,
ISP_EVENT_STREAM_UPDATE_DONE,
i, ts);
}
}
}
@ -437,14 +431,16 @@ static void msm_vfe46_process_epoch_irq(struct vfe_device *vfe_dev,
if (irq_status0 & BIT(2)) {
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
msm_isp_update_stats_framedrop_reg(vfe_dev);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_EPOCH, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_EPOCH);
msm_isp_update_error_frame_count(vfe_dev);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
pix_stream_count == 0) {
if (vfe_dev->axi_data.stream_update[VFE_PIX_0])
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0);
stream_count == 0) {
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, VFE_PIX_0);
}
@ -488,7 +484,9 @@ static void msm_vfe46_reg_update(struct vfe_device *vfe_dev,
vfe_dev->vfe_base + 0x3D8);
} else if (!vfe_dev->is_split ||
((frame_src == VFE_PIX_0) &&
(vfe_dev->axi_data.camif_state == CAMIF_STOPPING)) ||
(vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
(vfe_dev->axi_data.src_info[VFE_PIX_0].
raw_stream_count == 0)) ||
(frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
msm_camera_io_w_mb(update_mask,
vfe_dev->vfe_base + 0x3D8);
@ -567,8 +565,10 @@ static void msm_vfe46_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;
uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -583,7 +583,10 @@ static void msm_vfe46_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe46_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
@ -596,31 +599,37 @@ static void msm_vfe46_axi_clear_comp_mask(struct vfe_device *vfe_dev,
static void msm_vfe46_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe46_config_irq(vfe_dev, 1 << (stream_info->wm[0] + 8), 0,
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe46_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe46_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe46_config_irq(vfe_dev, (1 << (stream_info->wm[0] + 8)), 0,
MSM_ISP_IRQ_DISABLE);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe46_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
0, MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe46_cfg_framedrop(void __iomem *vfe_base,
static void msm_vfe46_cfg_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
uint32_t framedrop_period)
{
uint32_t i, temp;
void __iomem *vfe_base = vfe_dev->vfe_base;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++) {
msm_camera_io_w(framedrop_pattern, vfe_base +
VFE46_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE46_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
temp = msm_camera_io_r(vfe_base +
VFE46_WM_BASE(stream_info->wm[i]) + 0xC);
VFE46_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
temp &= 0xFFFFFF83;
msm_camera_io_w(temp | (framedrop_period - 1) << 2,
vfe_base + VFE46_WM_BASE(stream_info->wm[i]) + 0xC);
vfe_base + VFE46_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
}
}
@ -628,10 +637,11 @@ static void msm_vfe46_clear_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t i;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++)
msm_camera_io_w(0, vfe_dev->vfe_base +
VFE46_WM_BASE(stream_info->wm[i]) + 0x1C);
VFE46_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
}
static int32_t msm_vfe46_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
@ -1114,7 +1124,7 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev,
src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
vfe_en =
((vfe_dev->axi_data.
src_info[VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x3AC);
val &= 0xFFFFFF3F;
val = val | bus_en << 7 | vfe_en << 6;
@ -1178,7 +1188,10 @@ static void msm_vfe46_axi_cfg_wm_reg(
uint8_t plane_idx)
{
uint32_t val;
uint32_t wm_base = VFE46_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE46_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
val = msm_camera_io_r(vfe_dev->vfe_base + wm_base + 0xC);
val &= ~0x2;
@ -1190,17 +1203,18 @@ static void msm_vfe46_axi_cfg_wm_reg(
val =
((msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width)+3)/4 - 1) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
/* WR_BUFFER_CFG */
val = VFE46_BURST_LEN |
(stream_info->plane_cfg[plane_idx].output_height - 1) <<
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1) <<
2 |
((msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_stride)+1)/2) << 16;
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
}
@ -1215,7 +1229,10 @@ static void msm_vfe46_axi_clear_wm_reg(
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint32_t val = 0;
uint32_t wm_base = VFE46_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE46_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
/* WR_ADDR_CFG */
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
@ -1232,12 +1249,15 @@ static void msm_vfe46_axi_cfg_wm_xbar_reg(
struct msm_vfe_axi_stream *stream_info,
uint8_t plane_idx)
{
struct msm_vfe_axi_plane_cfg *plane_cfg =
&stream_info->plane_cfg[plane_idx];
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
struct msm_vfe_axi_plane_cfg *plane_cfg;
uint8_t wm;
uint32_t xbar_cfg = 0;
uint32_t xbar_reg_cfg = 0;
plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
wm = stream_info->wm[vfe_idx][plane_idx];
switch (stream_info->stream_src) {
case PIX_VIDEO:
case PIX_ENCODER:
@ -1295,9 +1315,12 @@ static void msm_vfe46_axi_clear_wm_xbar_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint8_t wm;
uint32_t xbar_reg_cfg = 0;
wm = stream_info->wm[vfe_idx][plane_idx];
xbar_reg_cfg =
msm_camera_io_r(vfe_dev->vfe_base + VFE46_XBAR_BASE(wm));
xbar_reg_cfg &= ~(0xFFFF << VFE46_XBAR_SHIFT(wm));
@ -1407,6 +1430,7 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev,
{
int rc = 0;
enum msm_vfe_input_src i;
struct msm_isp_timestamp ts;
/* Keep only halt and restart mask */
msm_vfe46_config_irq(vfe_dev, (1 << 31), (1 << 8),
@ -1440,34 +1464,19 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x374);
}
msm_isp_get_timestamp(&ts);
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
/* if any stream is waiting for update, signal complete */
if (vfe_dev->axi_data.stream_update[i]) {
ISP_DBG("%s: complete stream update\n", __func__);
msm_isp_axi_stream_update(vfe_dev, i);
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
}
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
ISP_DBG("%s: complete on axi config update\n",
__func__);
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i]))
msm_isp_axi_cfg_update(vfe_dev, i);
}
msm_isp_axi_stream_update(vfe_dev, i, &ts);
msm_isp_axi_stream_update(vfe_dev, i, &ts);
}
if (atomic_read(&vfe_dev->stats_data.stats_update)) {
ISP_DBG("%s: complete on stats update\n", __func__);
msm_isp_stats_stream_update(vfe_dev);
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
}
msm_isp_stats_stream_update(vfe_dev);
msm_isp_stats_stream_update(vfe_dev);
return rc;
}
static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev,
static void msm_vfe46_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif)
{
msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
@ -1488,8 +1497,6 @@ static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, ENABLE_CAMIF);
}
return 0;
}
static uint32_t msm_vfe46_get_wm_mask(
@ -1541,15 +1548,15 @@ static int msm_vfe46_stats_check_streams(
struct msm_vfe_stats_stream *stream_info)
{
if (stream_info[STATS_IDX_BF].state ==
STATS_AVALIABLE &&
STATS_AVAILABLE &&
stream_info[STATS_IDX_BF_SCALE].state !=
STATS_AVALIABLE) {
STATS_AVAILABLE) {
pr_err("%s: does not support BF_SCALE while BF is disabled\n",
__func__);
return -EINVAL;
}
if (stream_info[STATS_IDX_BF].state != STATS_AVALIABLE &&
stream_info[STATS_IDX_BF_SCALE].state != STATS_AVALIABLE &&
if (stream_info[STATS_IDX_BF].state != STATS_AVAILABLE &&
stream_info[STATS_IDX_BF_SCALE].state != STATS_AVAILABLE &&
stream_info[STATS_IDX_BF].composite_flag !=
stream_info[STATS_IDX_BF_SCALE].composite_flag) {
pr_err("%s: Different composite flag for BF and BF_SCALE\n",
@ -1632,26 +1639,37 @@ static void msm_vfe46_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);
msm_vfe46_config_irq(vfe_dev,
1 << (STATS_IDX(stream_info->stream_handle) + 15), 0,
MSM_ISP_IRQ_ENABLE);
1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 15), 0,
MSM_ISP_IRQ_ENABLE);
}
static void msm_vfe46_stats_clear_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);
msm_vfe46_config_irq(vfe_dev,
1 << (STATS_IDX(stream_info->stream_handle) + 15), 0,
MSM_ISP_IRQ_DISABLE);
1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 15), 0,
MSM_ISP_IRQ_DISABLE);
}
static void msm_vfe46_stats_cfg_wm_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE46_STATS_BASE(stats_idx);
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE46_STATS_BASE(stats_idx);
/*
* BF_SCALE does not have its own WR_ADDR_CFG,
@ -1676,10 +1694,14 @@ static void msm_vfe46_stats_clear_wm_reg(
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 val = 0;
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE46_STATS_BASE(stats_idx);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE46_STATS_BASE(stats_idx);
/*
* BF_SCALE does not have its own WR_ADDR_CFG,
* IRQ_FRAMEDROP_PATTERN and IRQ_SUBSAMPLE_PATTERN;
@ -1845,12 +1867,16 @@ static void msm_vfe46_stats_enable_module(struct vfe_device *vfe_dev,
}
static void msm_vfe46_stats_update_ping_pong_addr(
void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info,
struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
uint32_t pingpong_status, 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);
int stats_idx;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
msm_camera_io_w(paddr32, vfe_base +
VFE46_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
}

View file

@ -562,19 +562,20 @@ void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev,
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
if (shift_irq & BIT(i)) {
reg_updated |= BIT(i);
ISP_DBG("%s REG_UPDATE IRQ %x\n", __func__,
(uint32_t)BIT(i));
ISP_DBG("%s REG_UPDATE IRQ %x vfe %d\n", __func__,
(uint32_t)BIT(i), vfe_dev->pdev->id);
switch (i) {
case VFE_PIX_0:
msm_isp_save_framedrop_values(vfe_dev,
VFE_PIX_0);
msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
VFE_PIX_0, ts);
if (atomic_read(
&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
if (vfe_dev->axi_data.camif_state ==
CAMIF_STOPPING)
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_REG_UPD);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
/* if 0 streams then force reg update */
if (vfe_dev->axi_data.src_info
[i].stream_count == 0 &&
vfe_dev->axi_data.src_info[i].active)
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, i);
break;
@ -582,31 +583,23 @@ void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev,
case VFE_RAW_1:
case VFE_RAW_2:
msm_isp_increment_frame_id(vfe_dev, i, ts);
msm_isp_save_framedrop_values(vfe_dev, i);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
msm_isp_update_framedrop_reg(vfe_dev, i);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
/*
* Reg Update is pseudo SOF for RDI,
* so request every frame
*/
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, i);
/* reg upd is also epoch for RDI */
msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
MSM_ISP_COMP_IRQ_EPOCH, ts);
break;
default:
pr_err("%s: Error case\n", __func__);
return;
}
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(
&vfe_dev->axi_data.axi_cfg_update[i]) ==
0)
msm_isp_notify(vfe_dev,
ISP_EVENT_STREAM_UPDATE_DONE,
i, ts);
}
}
}
@ -627,15 +620,17 @@ void msm_vfe47_process_epoch_irq(struct vfe_device *vfe_dev,
if (irq_status0 & BIT(2)) {
ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0);
msm_isp_update_stats_framedrop_reg(vfe_dev);
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_EPOCH, ts);
msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
MSM_ISP_COMP_IRQ_EPOCH);
msm_isp_update_error_frame_count(vfe_dev);
msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
&& vfe_dev->axi_data.src_info[VFE_PIX_0].
pix_stream_count == 0) {
if (vfe_dev->axi_data.stream_update[VFE_PIX_0])
msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0);
stream_count == 0) {
msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
MSM_ISP_COMP_IRQ_REG_UPD, ts);
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
vfe_dev, VFE_PIX_0);
}
@ -679,7 +674,9 @@ void msm_vfe47_reg_update(struct vfe_device *vfe_dev,
vfe_dev->vfe_base + 0x4AC);
} else if (!vfe_dev->is_split ||
((frame_src == VFE_PIX_0) &&
(vfe_dev->axi_data.camif_state == CAMIF_STOPPING)) ||
(vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
(vfe_dev->axi_data.src_info[VFE_PIX_0].
raw_stream_count == 0)) ||
(frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
msm_camera_io_w_mb(update_mask,
vfe_dev->vfe_base + 0x4AC);
@ -768,9 +765,10 @@ void msm_vfe47_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;
uint32_t comp_mask, comp_mask_index =
stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
comp_mask |= (axi_data->composite_info[comp_mask_index].
@ -784,8 +782,10 @@ void msm_vfe47_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
void msm_vfe47_axi_clear_comp_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t comp_mask, comp_mask_index = stream_info->comp_mask_index;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t comp_mask, comp_mask_index;
comp_mask_index = stream_info->comp_mask_index[vfe_idx];
comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x74);
comp_mask &= ~(0x7F << (comp_mask_index * 8));
msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x74);
@ -797,31 +797,37 @@ void msm_vfe47_axi_clear_comp_mask(struct vfe_device *vfe_dev,
void msm_vfe47_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe47_config_irq(vfe_dev, 1 << (stream_info->wm[0] + 8), 0,
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe47_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
MSM_ISP_IRQ_ENABLE);
}
void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
msm_vfe47_config_irq(vfe_dev, (1 << (stream_info->wm[0] + 8)), 0,
MSM_ISP_IRQ_DISABLE);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
msm_vfe47_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
0, MSM_ISP_IRQ_DISABLE);
}
void msm_vfe47_cfg_framedrop(void __iomem *vfe_base,
void msm_vfe47_cfg_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
uint32_t framedrop_period)
{
void __iomem *vfe_base = vfe_dev->vfe_base;
uint32_t i, temp;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++) {
msm_camera_io_w(framedrop_pattern, vfe_base +
VFE47_WM_BASE(stream_info->wm[i]) + 0x24);
VFE47_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x24);
temp = msm_camera_io_r(vfe_base +
VFE47_WM_BASE(stream_info->wm[i]) + 0x14);
VFE47_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x14);
temp &= 0xFFFFFF83;
msm_camera_io_w(temp | (framedrop_period - 1) << 2,
vfe_base + VFE47_WM_BASE(stream_info->wm[i]) + 0x14);
vfe_base + VFE47_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x14);
}
}
@ -829,10 +835,11 @@ void msm_vfe47_clear_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
uint32_t i;
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
for (i = 0; i < stream_info->num_planes; i++)
msm_camera_io_w(0, vfe_dev->vfe_base +
VFE47_WM_BASE(stream_info->wm[i]) + 0x24);
VFE47_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x24);
}
static int32_t msm_vfe47_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
@ -1395,7 +1402,7 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
vfe_en =
((vfe_dev->axi_data.
src_info[VFE_PIX_0].pix_stream_count > 0) ? 1 : 0);
src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
val = msm_camera_io_r(vfe_dev->vfe_base + 0x47C);
val &= 0xFFFFFF3F;
val = val | bus_en << 7 | vfe_en << 6;
@ -1404,7 +1411,6 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x478);
/* configure EPOCH0 for 20 lines */
msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x4A0);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
/* testgen GO*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1, vfe_dev->vfe_base + 0xC58);
@ -1427,7 +1433,6 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
poll_val, poll_val & 0x80000000, 1000, 2000000))
pr_err("%s: camif disable failed %x\n",
__func__, poll_val);
vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
/* testgen OFF*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xC58);
@ -1469,8 +1474,10 @@ void msm_vfe47_axi_cfg_wm_reg(
uint8_t plane_idx)
{
uint32_t val;
uint32_t wm_base = VFE47_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE47_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
val = msm_camera_io_r(vfe_dev->vfe_base + wm_base + 0x14);
val &= ~0x2;
if (stream_info->frame_based)
@ -1480,17 +1487,18 @@ void msm_vfe47_axi_cfg_wm_reg(
/* WR_IMAGE_SIZE */
val = ((msm_isp_cal_word_per_line(
stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_width)+3)/4 - 1) << 16 |
(stream_info->plane_cfg[plane_idx].
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1);
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x1C);
/* WR_BUFFER_CFG */
val = VFE47_BURST_LEN |
(stream_info->plane_cfg[plane_idx].output_height - 1) <<
(stream_info->plane_cfg[vfe_idx][plane_idx].
output_height - 1) <<
2 |
((msm_isp_cal_word_per_line(stream_info->output_format,
stream_info->plane_cfg[plane_idx].
stream_info->plane_cfg[vfe_idx][plane_idx].
output_stride)+1)/2) << 16;
}
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x20);
@ -1504,8 +1512,10 @@ void msm_vfe47_axi_clear_wm_reg(
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint32_t val = 0;
uint32_t wm_base = VFE47_WM_BASE(stream_info->wm[plane_idx]);
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint32_t wm_base;
wm_base = VFE47_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
/* WR_ADDR_CFG */
msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
/* WR_IMAGE_SIZE */
@ -1521,12 +1531,14 @@ void msm_vfe47_axi_cfg_wm_xbar_reg(
struct msm_vfe_axi_stream *stream_info,
uint8_t plane_idx)
{
struct msm_vfe_axi_plane_cfg *plane_cfg =
&stream_info->plane_cfg[plane_idx];
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
struct msm_vfe_axi_plane_cfg *plane_cfg;
uint8_t wm;
uint32_t xbar_cfg = 0;
uint32_t xbar_reg_cfg = 0;
plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
wm = stream_info->wm[vfe_idx][plane_idx];
switch (stream_info->stream_src) {
case PIX_VIDEO:
case PIX_ENCODER:
@ -1585,9 +1597,11 @@ void msm_vfe47_axi_clear_wm_xbar_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
{
uint8_t wm = stream_info->wm[plane_idx];
int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
uint8_t wm;
uint32_t xbar_reg_cfg = 0;
wm = stream_info->wm[vfe_idx][plane_idx];
xbar_reg_cfg =
msm_camera_io_r(vfe_dev->vfe_base + VFE47_XBAR_BASE(wm));
xbar_reg_cfg &= ~(0xFFFF << VFE47_XBAR_SHIFT(wm));
@ -1707,6 +1721,7 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
int rc = 0;
enum msm_vfe_input_src i;
uint32_t val = 0;
struct msm_isp_timestamp ts;
val = msm_camera_io_r(vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET);
val |= 0x1;
@ -1746,34 +1761,20 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x400);
}
msm_isp_get_timestamp(&ts);
for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
/* if any stream is waiting for update, signal complete */
if (vfe_dev->axi_data.stream_update[i]) {
ISP_DBG("%s: complete stream update\n", __func__);
msm_isp_axi_stream_update(vfe_dev, i);
if (vfe_dev->axi_data.stream_update[i])
msm_isp_axi_stream_update(vfe_dev, i);
}
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i])) {
ISP_DBG("%s: complete on axi config update\n",
__func__);
msm_isp_axi_cfg_update(vfe_dev, i);
if (atomic_read(&vfe_dev->axi_data.axi_cfg_update[i]))
msm_isp_axi_cfg_update(vfe_dev, i);
}
/* if any stream is waiting for update, signal fake completes */
msm_isp_axi_stream_update(vfe_dev, i, &ts);
msm_isp_axi_stream_update(vfe_dev, i, &ts);
}
if (atomic_read(&vfe_dev->stats_data.stats_update)) {
ISP_DBG("%s: complete on stats update\n", __func__);
msm_isp_stats_stream_update(vfe_dev);
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
}
msm_isp_stats_stream_update(vfe_dev);
msm_isp_stats_stream_update(vfe_dev);
return rc;
}
int msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
void msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif)
{
msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask,
@ -1793,8 +1794,6 @@ int msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, ENABLE_CAMIF);
}
return 0;
}
uint32_t msm_vfe47_get_wm_mask(
@ -1912,7 +1911,10 @@ void msm_vfe47_stats_cfg_wm_irq_mask(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
switch (STATS_IDX(stream_info->stream_handle)) {
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
switch (STATS_IDX(stream_info->stream_handle[vfe_idx])) {
case STATS_COMP_IDX_AEC_BG:
msm_vfe47_config_irq(vfe_dev, 1 << 15, 0, MSM_ISP_IRQ_ENABLE);
break;
@ -1943,7 +1945,7 @@ void msm_vfe47_stats_cfg_wm_irq_mask(
break;
default:
pr_err("%s: Invalid stats idx %d\n", __func__,
STATS_IDX(stream_info->stream_handle));
STATS_IDX(stream_info->stream_handle[vfe_idx]));
}
}
@ -1951,12 +1953,10 @@ void msm_vfe47_stats_clear_wm_irq_mask(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
uint32_t irq_mask, irq_mask_1;
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
irq_mask = vfe_dev->irq0_mask;
irq_mask_1 = vfe_dev->irq1_mask;
switch (STATS_IDX(stream_info->stream_handle)) {
switch (STATS_IDX(stream_info->stream_handle[vfe_idx])) {
case STATS_COMP_IDX_AEC_BG:
msm_vfe47_config_irq(vfe_dev, 1 << 15, 0, MSM_ISP_IRQ_DISABLE);
break;
@ -1987,7 +1987,7 @@ void msm_vfe47_stats_clear_wm_irq_mask(
break;
default:
pr_err("%s: Invalid stats idx %d\n", __func__,
STATS_IDX(stream_info->stream_handle));
STATS_IDX(stream_info->stream_handle[vfe_idx]));
}
}
@ -1995,8 +1995,13 @@ void msm_vfe47_stats_cfg_wm_reg(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE47_STATS_BASE(stats_idx);
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
stream_info);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE47_STATS_BASE(stats_idx);
/* WR_ADDR_CFG */
msm_camera_io_w(stream_info->framedrop_period << 2,
@ -2013,9 +2018,14 @@ void msm_vfe47_stats_clear_wm_reg(
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 val = 0;
int stats_idx = STATS_IDX(stream_info->stream_handle);
uint32_t stats_base = VFE47_STATS_BASE(stats_idx);
int stats_idx;
uint32_t stats_base;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
stats_base = VFE47_STATS_BASE(stats_idx);
/* WR_ADDR_CFG */
msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x10);
@ -2171,11 +2181,16 @@ void msm_vfe47_stats_enable_module(struct vfe_device *vfe_dev,
}
void msm_vfe47_stats_update_ping_pong_addr(
void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info,
struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
uint32_t pingpong_status, 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);
int stats_idx;
stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
msm_camera_io_w(paddr32, vfe_base +
VFE47_STATS_PING_PONG_BASE(stats_idx, pingpong_status));

View file

@ -56,7 +56,7 @@ void msm_vfe47_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info);
void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info);
void msm_vfe47_cfg_framedrop(void __iomem *vfe_base,
void msm_vfe47_cfg_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
uint32_t framedrop_period);
void msm_vfe47_clear_framedrop(struct vfe_device *vfe_dev,
@ -107,7 +107,7 @@ void msm_vfe47_update_ping_pong_addr(
int32_t buf_size);
int msm_vfe47_axi_halt(struct vfe_device *vfe_dev,
uint32_t blocking);
int msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
void msm_vfe47_axi_restart(struct vfe_device *vfe_dev,
uint32_t blocking, uint32_t enable_camif);
uint32_t msm_vfe47_get_wm_mask(
uint32_t irq_status0, uint32_t irq_status1);
@ -141,7 +141,7 @@ bool msm_vfe47_is_module_cfg_lock_needed(
void msm_vfe47_stats_enable_module(struct vfe_device *vfe_dev,
uint32_t stats_mask, uint8_t enable);
void msm_vfe47_stats_update_ping_pong_addr(
void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info,
struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
uint32_t pingpong_status, dma_addr_t paddr);
uint32_t msm_vfe47_stats_get_wm_mask(
uint32_t irq_status0, uint32_t irq_status1);

File diff suppressed because it is too large Load diff

View file

@ -14,37 +14,15 @@
#include "msm_isp.h"
#define HANDLE_TO_IDX(handle) (handle & 0xFF)
#define SRC_TO_INTF(src) \
((src < RDI_INTF_0 || src == VFE_AXI_SRC_MAX) ? VFE_PIX_0 : \
(VFE_RAW_0 + src - RDI_INTF_0))
int msm_isp_axi_create_stream(struct vfe_device *vfe_dev,
struct msm_vfe_axi_shared_data *axi_data,
struct msm_vfe_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_vfe_axi_stream_request_cmd *stream_cfg_cmd);
void msm_isp_axi_reserve_wm(
struct vfe_device *vfe_dev,
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);
int msm_isp_calculate_framedrop(
struct msm_vfe_axi_shared_data *axi_data,
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd);
void msm_isp_reset_framedrop(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info);
@ -62,10 +40,13 @@ int msm_isp_axi_restart(struct vfe_device *vfe_dev,
struct msm_vfe_axi_restart_cmd *restart_cmd);
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src);
enum msm_vfe_input_src frame_src,
struct msm_isp_timestamp *ts);
void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src);
void msm_isp_process_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src,
enum msm_isp_comp_irq_types irq,
struct msm_isp_timestamp *ts);
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);
@ -94,6 +75,34 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
uint32_t pingpong_status,
struct msm_isp_timestamp *ts);
void msm_isp_release_all_axi_stream(struct vfe_device *vfe_dev);
static inline int msm_isp_get_vfe_idx_for_stream_user(
struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
int vfe_idx;
for (vfe_idx = 0; vfe_idx < stream_info->num_isp; vfe_idx++) {
if (stream_info->vfe_dev[vfe_idx] == vfe_dev)
return vfe_idx;
}
return -ENOTTY;
}
static inline int msm_isp_get_vfe_idx_for_stream(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
int vfe_idx = msm_isp_get_vfe_idx_for_stream_user(vfe_dev, stream_info);
if (vfe_idx < 0) {
WARN(1, "%s vfe index misssing for stream %d, vfe %d\n",
__func__, stream_info->stream_src, vfe_dev->pdev->id);
vfe_idx = 0;
}
return vfe_idx;
}
static inline void msm_isp_cfg_wm_scratch(struct vfe_device *vfe_dev,
int wm,
uint32_t pingpong_bit)
@ -103,18 +112,48 @@ static inline void msm_isp_cfg_wm_scratch(struct vfe_device *vfe_dev,
pingpong_bit, vfe_dev->buf_mgr->scratch_buf_addr, 0);
}
static inline void msm_isp_cfg_stream_scratch(struct vfe_device *vfe_dev,
static inline void msm_isp_cfg_stream_scratch(
struct msm_vfe_axi_stream *stream_info,
uint32_t pingpong_status)
{
int i;
int j;
uint32_t pingpong_bit;
int vfe_idx;
pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
for (i = 0; i < stream_info->num_planes; i++)
msm_isp_cfg_wm_scratch(vfe_dev, stream_info->wm[i],
pingpong_bit = (~(pingpong_status >> stream_info->wm[0][0]) & 0x1);
for (i = 0; i < stream_info->num_planes; i++) {
for (j = 0; j < stream_info->num_isp; j++) {
vfe_idx = msm_isp_get_vfe_idx_for_stream(
stream_info->vfe_dev[j], stream_info);
msm_isp_cfg_wm_scratch(stream_info->vfe_dev[j],
stream_info->wm[vfe_idx][i],
~pingpong_bit);
}
}
stream_info->buf[pingpong_bit] = NULL;
}
static inline struct msm_vfe_axi_stream *msm_isp_get_stream_common_data(
struct vfe_device *vfe_dev, int stream_idx)
{
struct msm_vfe_common_dev_data *common_data = vfe_dev->common_data;
struct msm_vfe_axi_stream *stream_info;
if (vfe_dev->is_split && stream_idx < RDI_INTF_0)
stream_info = &common_data->streams[stream_idx];
else
stream_info = &common_data->streams[VFE_AXI_SRC_MAX *
vfe_dev->pdev->id + stream_idx];
return stream_info;
}
static inline struct msm_vfe_axi_stream *msm_isp_vfe_get_stream(
struct dual_vfe_resource *dual_vfe_res,
int vfe_id, uint32_t index)
{
return msm_isp_get_stream_common_data(dual_vfe_res->vfe_dev[vfe_id],
index);
}
#endif /* __MSM_ISP_AXI_UTIL_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2016, 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
@ -23,8 +23,58 @@ 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);
void msm_isp_stats_disable(struct vfe_device *vfe_dev);
int msm_isp_stats_reset(struct vfe_device *vfe_dev);
int msm_isp_stats_restart(struct vfe_device *vfe_dev);
void msm_isp_release_all_stats_stream(struct vfe_device *vfe_dev);
void msm_isp_process_stats_reg_upd_epoch_irq(struct vfe_device *vfe_dev,
enum msm_isp_comp_irq_types irq);
static inline int msm_isp_get_vfe_idx_for_stats_stream_user(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int vfe_idx;
for (vfe_idx = 0; vfe_idx < stream_info->num_isp; vfe_idx++)
if (stream_info->vfe_dev[vfe_idx] == vfe_dev)
return vfe_idx;
return -ENOTTY;
}
static inline int msm_isp_get_vfe_idx_for_stats_stream(
struct vfe_device *vfe_dev,
struct msm_vfe_stats_stream *stream_info)
{
int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream_user(vfe_dev,
stream_info);
if (vfe_idx < 0) {
WARN(1, "%s vfe index missing for stream %d vfe %d\n",
__func__, stream_info->stats_type, vfe_dev->pdev->id);
vfe_idx = 0;
}
return vfe_idx;
}
static inline struct msm_vfe_stats_stream *
msm_isp_get_stats_stream_common_data(
struct vfe_device *vfe_dev,
enum msm_isp_stats_type idx)
{
if (vfe_dev->is_split)
return &vfe_dev->common_data->stats_streams[idx];
else
return &vfe_dev->common_data->stats_streams[idx +
MSM_ISP_STATS_MAX * vfe_dev->pdev->id];
}
static inline struct msm_vfe_stats_stream *
msm_isp_get_stats_stream(struct dual_vfe_resource *dual_vfe_res,
int vfe_id,
enum msm_isp_stats_type idx)
{
return msm_isp_get_stats_stream_common_data(
dual_vfe_res->vfe_dev[vfe_id], idx);
}
#endif /* __MSM_ISP_STATS_UTIL_H__ */

View file

@ -25,6 +25,22 @@
static DEFINE_MUTEX(bandwidth_mgr_mutex);
static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr;
#define MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev) { \
if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) { \
struct vfe_device *vfe1_dev = vfe_dev->common_data-> \
dual_vfe_res->vfe_dev[ISP_VFE1]; \
mutex_lock(&vfe1_dev->core_mutex); \
} \
}
#define MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev) { \
if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) { \
struct vfe_device *vfe1_dev = vfe_dev->common_data-> \
dual_vfe_res->vfe_dev[ISP_VFE1]; \
mutex_unlock(&vfe1_dev->core_mutex); \
} \
}
static uint64_t msm_isp_cpp_clk_rate;
#define VFE40_8974V2_VERSION 0x1001001A
@ -762,26 +778,39 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
}
case VIDIOC_MSM_ISP_REQUEST_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_request_axi_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_RELEASE_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_release_axi_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_CFG_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_cfg_axi_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_AXI_HALT:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_axi_halt(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_AXI_RESET:
mutex_lock(&vfe_dev->core_mutex);
/* For dual vfe reset both on vfe1 call */
if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) {
mutex_unlock(&vfe_dev->core_mutex);
return 0;
}
if (atomic_read(&vfe_dev->error_info.overflow_state)
!= HALT_ENFORCED) {
rc = msm_isp_stats_reset(vfe_dev);
@ -796,6 +825,11 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
break;
case VIDIOC_MSM_ISP_AXI_RESTART:
mutex_lock(&vfe_dev->core_mutex);
/* For dual vfe restart both on vfe1 call */
if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE0) {
mutex_unlock(&vfe_dev->core_mutex);
return 0;
}
if (atomic_read(&vfe_dev->error_info.overflow_state)
!= HALT_ENFORCED) {
rc = msm_isp_stats_restart(vfe_dev);
@ -848,27 +882,37 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
break;
case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_request_stats_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_RELEASE_STATS_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_release_stats_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_CFG_STATS_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_cfg_stats_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_UPDATE_STATS_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_update_stats_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_UPDATE_STREAM:
mutex_lock(&vfe_dev->core_mutex);
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
rc = msm_isp_update_axi_stream(vfe_dev, arg);
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_SMMU_ATTACH:
@ -883,10 +927,7 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
vfe_dev->isp_raw2_debug = 0;
break;
case MSM_SD_UNNOTIFY_FREEZE:
break;
case MSM_SD_SHUTDOWN:
while (vfe_dev->vfe_open_cnt != 0)
msm_isp_close_node(sd, NULL);
break;
default:
@ -1631,8 +1672,8 @@ static int msm_isp_process_iommu_page_fault(struct vfe_device *vfe_dev)
{
int rc = vfe_dev->buf_mgr->pagefault_debug_disable;
pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %pK\n", __func__,
__LINE__, vfe_dev->pdev->id, vfe_dev);
pr_err("%s:%d] VFE%d Handle Page fault!\n", __func__,
__LINE__, vfe_dev->pdev->id);
msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT);
@ -1899,6 +1940,7 @@ static void msm_vfe_iommu_fault_handler(struct iommu_domain *domain,
if (vfe_dev->vfe_open_cnt > 0) {
atomic_set(&vfe_dev->error_info.overflow_state,
HALT_ENFORCED);
pr_err("%s: fault address is %lx\n", __func__, iova);
msm_isp_process_iommu_page_fault(vfe_dev);
} else {
pr_err("%s: no handling, vfe open cnt = %d\n",
@ -1928,9 +1970,6 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return -EINVAL;
}
if (vfe_dev->pdev->id == ISP_VFE0)
vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0;
mutex_lock(&vfe_dev->realtime_mutex);
mutex_lock(&vfe_dev->core_mutex);
@ -2032,6 +2071,10 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
mutex_unlock(&vfe_dev->realtime_mutex);
return 0;
}
MSM_ISP_DUAL_VFE_MUTEX_LOCK(vfe_dev);
msm_isp_release_all_axi_stream(vfe_dev);
msm_isp_release_all_stats_stream(vfe_dev);
/* Unregister page fault handler */
cam_smmu_reg_client_page_fault_handler(
vfe_dev->buf_mgr->iommu_hdl,
@ -2059,6 +2102,7 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
msm_isp_end_avtimer();
vfe_dev->vt_enable = 0;
}
MSM_ISP_DUAL_VFE_MUTEX_UNLOCK(vfe_dev);
vfe_dev->is_split = 0;
mutex_unlock(&vfe_dev->core_mutex);
@ -2088,25 +2132,3 @@ void msm_isp_flush_tasklet(struct vfe_device *vfe_dev)
return;
}
void msm_isp_save_framedrop_values(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src)
{
struct msm_vfe_axi_stream *stream_info = NULL;
uint32_t j = 0;
unsigned long flags;
for (j = 0; j < VFE_AXI_SRC_MAX; j++) {
stream_info = &vfe_dev->axi_data.stream_info[j];
if (stream_info->state != ACTIVE)
continue;
if (frame_src != SRC_TO_INTF(stream_info->stream_src))
continue;
stream_info =
&vfe_dev->axi_data.stream_info[j];
spin_lock_irqsave(&stream_info->lock, flags);
stream_info->activated_framedrop_period =
stream_info->requested_framedrop_period;
spin_unlock_irqrestore(&stream_info->lock, flags);
}
}

View file

@ -70,7 +70,5 @@ void msm_isp_fetch_engine_done_notify(struct vfe_device *vfe_dev,
struct msm_vfe_fetch_engine_info *fetch_engine_info);
void msm_isp_print_fourcc_error(const char *origin, uint32_t fourcc_format);
void msm_isp_flush_tasklet(struct vfe_device *vfe_dev);
void msm_isp_save_framedrop_values(struct vfe_device *vfe_dev,
enum msm_vfe_input_src frame_src);
void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp);
#endif /* __MSM_ISP_UTIL_H__ */