Lines Matching +full:sm8250 +full:- +full:camss
1 // SPDX-License-Identifier: GPL-2.0
3 * camss-vfe-480.c
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v480 (SM8250)
7 * Copyright (C) 2020-2021 Linaro Ltd.
15 #include "camss.h"
16 #include "camss-vfe.h"
97 u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION); in vfe_hw_version()
103 dev_dbg(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step); in vfe_hw_version()
110 writel_relaxed(IRQ_MASK_0_RESET_ACK, vfe->base + VFE_IRQ_MASK(0)); in vfe_global_reset()
111 writel_relaxed(GLOBAL_RESET_HW_AND_REG, vfe->base + VFE_GLOBAL_RESET_CMD); in vfe_global_reset()
117 &line->video_out.active_fmt.fmt.pix_mp; in vfe_wm_start()
122 writel_relaxed(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE); in vfe_wm_start()
124 writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL); in vfe_wm_start()
126 writel_relaxed(pix->plane_fmt[0].bytesperline * pix->height, in vfe_wm_start()
127 vfe->base + VFE_BUS_WM_FRAME_INCR(wm)); in vfe_wm_start()
128 writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm)); in vfe_wm_start()
130 vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm)); in vfe_wm_start()
131 writel_relaxed(pix->plane_fmt[0].bytesperline, in vfe_wm_start()
132 vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm)); in vfe_wm_start()
133 writel_relaxed(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); in vfe_wm_start()
136 writel_relaxed(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm)); in vfe_wm_start()
137 writel_relaxed(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm)); in vfe_wm_start()
138 writel_relaxed(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm)); in vfe_wm_start()
139 writel_relaxed(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm)); in vfe_wm_start()
142 vfe->base + VFE_BUS_WM_CFG(wm)); in vfe_wm_start()
148 writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm)); in vfe_wm_stop()
155 writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); in vfe_wm_update()
160 vfe->reg_update |= REG_UPDATE_RDI(vfe, line_id); in vfe_reg_update()
161 writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD); in vfe_reg_update()
167 vfe->reg_update &= ~REG_UPDATE_RDI(vfe, line_id); in vfe_reg_update_clear()
174 vfe->base + VFE_IRQ_MASK(0)); in vfe_enable_irq_common()
184 if (vfe->line[i].output.state == VFE_OUTPUT_RESERVED || in vfe_enable_lines_irq()
185 vfe->line[i].output.state == VFE_OUTPUT_ON) { in vfe_enable_lines_irq()
191 writel_relaxed(bus_irq_mask, vfe->base + VFE_BUS_IRQ_MASK(0)); in vfe_enable_lines_irq()
198 * vfe_isr - VFE module interrupt handler
210 status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(0)); in vfe_isr()
211 writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(0)); in vfe_isr()
212 writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD); in vfe_isr()
218 u32 status = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(0)); in vfe_isr()
220 writel_relaxed(status, vfe->base + VFE_BUS_IRQ_CLEAR(0)); in vfe_isr()
221 writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL); in vfe_isr()
237 * vfe_halt - Trigger halt on VFE module and wait to complete
254 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_get_output()
256 output = &line->output; in vfe_get_output()
257 if (output->state > VFE_OUTPUT_RESERVED) { in vfe_get_output()
258 dev_err(vfe->camss->dev, "Output is running\n"); in vfe_get_output()
262 output->wm_num = 1; in vfe_get_output()
265 * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3 in vfe_get_output()
268 output->wm_idx[0] = line->id; in vfe_get_output()
269 vfe->wm_output_map[line->id] = line->id; in vfe_get_output()
271 output->drop_update_idx = 0; in vfe_get_output()
273 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_get_output()
278 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_get_output()
279 output->state = VFE_OUTPUT_OFF; in vfe_get_output()
281 return -EINVAL; in vfe_get_output()
287 struct vfe_output *output = &line->output; in vfe_enable_output()
291 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_enable_output()
293 vfe_reg_update_clear(vfe, line->id); in vfe_enable_output()
295 if (output->state > VFE_OUTPUT_RESERVED) { in vfe_enable_output()
296 dev_err(vfe->camss->dev, "Output is not in reserved state %d\n", in vfe_enable_output()
297 output->state); in vfe_enable_output()
298 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_enable_output()
299 return -EINVAL; in vfe_enable_output()
302 WARN_ON(output->gen2.active_num); in vfe_enable_output()
304 output->state = VFE_OUTPUT_ON; in vfe_enable_output()
306 output->sequence = 0; in vfe_enable_output()
307 output->wait_reg_update = 0; in vfe_enable_output()
308 reinit_completion(&output->reg_update); in vfe_enable_output()
310 vfe_wm_start(vfe, output->wm_idx[0], line); in vfe_enable_output()
313 output->buf[i] = vfe_buf_get_pending(output); in vfe_enable_output()
314 if (!output->buf[i]) in vfe_enable_output()
316 output->gen2.active_num++; in vfe_enable_output()
317 vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line); in vfe_enable_output()
320 vfe_reg_update(vfe, line->id); in vfe_enable_output()
322 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_enable_output()
328 * vfe_enable - Enable streaming on VFE line
338 mutex_lock(&vfe->stream_lock); in vfe_enable()
340 if (!vfe->stream_count) in vfe_enable()
343 vfe->stream_count++; in vfe_enable()
347 mutex_unlock(&vfe->stream_lock); in vfe_enable()
357 vfe->was_streaming = 1; in vfe_enable()
365 mutex_lock(&vfe->stream_lock); in vfe_enable()
367 vfe->stream_count--; in vfe_enable()
369 mutex_unlock(&vfe->stream_lock); in vfe_enable()
375 * vfe_isr_reg_update - Process reg update interrupt
384 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_isr_reg_update()
387 output = &vfe->line[line_id].output; in vfe_isr_reg_update()
389 if (output->wait_reg_update) { in vfe_isr_reg_update()
390 output->wait_reg_update = 0; in vfe_isr_reg_update()
391 complete(&output->reg_update); in vfe_isr_reg_update()
394 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_reg_update()
398 * vfe_isr_wm_done - Process write master done interrupt
404 struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]]; in vfe_isr_wm_done()
411 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_isr_wm_done()
413 if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { in vfe_isr_wm_done()
414 dev_err_ratelimited(vfe->camss->dev, in vfe_isr_wm_done()
418 output = &vfe->line[vfe->wm_output_map[wm]].output; in vfe_isr_wm_done()
420 ready_buf = output->buf[0]; in vfe_isr_wm_done()
422 dev_err_ratelimited(vfe->camss->dev, in vfe_isr_wm_done()
423 "Missing ready buf %d!\n", output->state); in vfe_isr_wm_done()
427 ready_buf->vb.vb2_buf.timestamp = ts; in vfe_isr_wm_done()
428 ready_buf->vb.sequence = output->sequence++; in vfe_isr_wm_done()
431 output->buf[0] = output->buf[1]; in vfe_isr_wm_done()
432 if (output->buf[0]) in vfe_isr_wm_done()
435 output->buf[index] = vfe_buf_get_pending(output); in vfe_isr_wm_done()
437 if (output->buf[index]) in vfe_isr_wm_done()
438 vfe_wm_update(vfe, output->wm_idx[0], output->buf[index]->addr[0], line); in vfe_isr_wm_done()
440 output->gen2.active_num--; in vfe_isr_wm_done()
442 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_wm_done()
444 vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); in vfe_isr_wm_done()
449 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_wm_done()
453 * vfe_queue_buffer - Add empty buffer
457 * Add an empty buffer - depending on the current number of buffers it will be
470 output = &line->output; in vfe_queue_buffer()
472 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_queue_buffer()
474 if (output->state == VFE_OUTPUT_ON && output->gen2.active_num < 2) { in vfe_queue_buffer()
475 output->buf[output->gen2.active_num++] = buf; in vfe_queue_buffer()
476 vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line); in vfe_queue_buffer()
481 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_queue_buffer()
493 vfe->video_ops = vfe_video_ops_480; in vfe_subdev_init()