Lines Matching full:vfe

3  * camss-vfe-480.c
5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v480 (SM8250)
16 #include "camss-vfe.h"
18 /* VFE 2/3 are lite and have a different register layout */
19 #define IS_LITE (vfe->id >= 2 ? 1 : 0)
27 static inline int reg_update_rdi(struct vfe_device *vfe, int n) in reg_update_rdi() argument
50 static inline int bus_irq_mask_0_rdi_rup(struct vfe_device *vfe, int n) in bus_irq_mask_0_rdi_rup() argument
56 static inline int bus_irq_mask_0_comp_done(struct vfe_device *vfe, int n) in bus_irq_mask_0_comp_done() argument
98 static u32 vfe_hw_version(struct vfe_device *vfe) in vfe_hw_version() argument
100 u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION); in vfe_hw_version()
106 dev_dbg(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n", gen, rev, step); in vfe_hw_version()
111 static void vfe_global_reset(struct vfe_device *vfe) in vfe_global_reset() argument
113 writel_relaxed(IRQ_MASK_0_RESET_ACK, vfe->base + VFE_IRQ_MASK(0)); in vfe_global_reset()
114 writel_relaxed(GLOBAL_RESET_HW_AND_REG, vfe->base + VFE_GLOBAL_RESET_CMD); in vfe_global_reset()
117 static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line) in vfe_wm_start() argument
125 writel_relaxed(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE); in vfe_wm_start()
127 writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL); in vfe_wm_start()
130 vfe->base + VFE_BUS_WM_FRAME_INCR(wm)); in vfe_wm_start()
131 writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm)); in vfe_wm_start()
133 vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm)); in vfe_wm_start()
135 vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm)); in vfe_wm_start()
136 writel_relaxed(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); in vfe_wm_start()
139 writel_relaxed(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm)); in vfe_wm_start()
140 writel_relaxed(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm)); in vfe_wm_start()
141 writel_relaxed(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm)); in vfe_wm_start()
142 writel_relaxed(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm)); in vfe_wm_start()
145 vfe->base + VFE_BUS_WM_CFG(wm)); in vfe_wm_start()
148 static void vfe_wm_stop(struct vfe_device *vfe, u8 wm) in vfe_wm_stop() argument
151 writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm)); in vfe_wm_stop()
154 static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr, in vfe_wm_update() argument
158 writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm)); in vfe_wm_update()
161 static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) in vfe_reg_update() argument
163 vfe->reg_update |= REG_UPDATE_RDI(vfe, line_id); in vfe_reg_update()
164 writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD); in vfe_reg_update()
167 static inline void vfe_reg_update_clear(struct vfe_device *vfe, in vfe_reg_update_clear() argument
170 vfe->reg_update &= ~REG_UPDATE_RDI(vfe, line_id); in vfe_reg_update_clear()
173 static void vfe_enable_irq_common(struct vfe_device *vfe) in vfe_enable_irq_common() argument
177 vfe->base + VFE_IRQ_MASK(0)); in vfe_enable_irq_common()
180 static void vfe_enable_lines_irq(struct vfe_device *vfe) in vfe_enable_lines_irq() argument
187 if (vfe->line[i].output.state == VFE_OUTPUT_RESERVED || in vfe_enable_lines_irq()
188 vfe->line[i].output.state == VFE_OUTPUT_ON) { in vfe_enable_lines_irq()
189 bus_irq_mask |= BUS_IRQ_MASK_0_RDI_RUP(vfe, i) in vfe_enable_lines_irq()
190 | BUS_IRQ_MASK_0_COMP_DONE(vfe, RDI_COMP_GROUP(i)); in vfe_enable_lines_irq()
194 writel_relaxed(bus_irq_mask, vfe->base + VFE_BUS_IRQ_MASK(0)); in vfe_enable_lines_irq()
197 static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id);
198 static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm);
201 * vfe_isr - VFE module interrupt handler
203 * @dev: VFE device
209 struct vfe_device *vfe = dev; in vfe_isr() local
213 status = readl_relaxed(vfe->base + VFE_IRQ_STATUS(0)); in vfe_isr()
214 writel_relaxed(status, vfe->base + VFE_IRQ_CLEAR(0)); in vfe_isr()
215 writel_relaxed(IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD); in vfe_isr()
218 vfe_isr_reset_ack(vfe); in vfe_isr()
221 u32 status = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(0)); in vfe_isr()
223 writel_relaxed(status, vfe->base + VFE_BUS_IRQ_CLEAR(0)); in vfe_isr()
224 writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL); in vfe_isr()
228 if (status & BUS_IRQ_MASK_0_RDI_RUP(vfe, i)) in vfe_isr()
229 vfe_isr_reg_update(vfe, i); in vfe_isr()
231 if (status & BUS_IRQ_MASK_0_COMP_DONE(vfe, RDI_COMP_GROUP(i))) in vfe_isr()
232 vfe_isr_wm_done(vfe, i); in vfe_isr()
240 * vfe_halt - Trigger halt on VFE module and wait to complete
241 * @vfe: VFE device
245 static int vfe_halt(struct vfe_device *vfe) in vfe_halt() argument
247 /* rely on vfe_disable_output() to stop the VFE */ in vfe_halt()
253 struct vfe_device *vfe = to_vfe(line); in vfe_get_output() local
257 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_get_output()
261 dev_err(vfe->camss->dev, "Output is running\n"); in vfe_get_output()
267 /* Correspondence between VFE line number and WM number. in vfe_get_output()
272 vfe->wm_output_map[line->id] = line->id; in vfe_get_output()
276 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_get_output()
281 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_get_output()
289 struct vfe_device *vfe = to_vfe(line); in vfe_enable_output() local
294 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_enable_output()
296 vfe_reg_update_clear(vfe, line->id); in vfe_enable_output()
299 dev_err(vfe->camss->dev, "Output is not in reserved state %d\n", in vfe_enable_output()
301 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_enable_output()
313 vfe_wm_start(vfe, output->wm_idx[0], line); in vfe_enable_output()
320 vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line); in vfe_enable_output()
323 vfe_reg_update(vfe, line->id); in vfe_enable_output()
325 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_enable_output()
332 struct vfe_device *vfe = to_vfe(line); in vfe_disable_output() local
337 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_disable_output()
339 vfe_wm_stop(vfe, output->wm_idx[i]); in vfe_disable_output()
341 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_disable_output()
343 vfe_reset(vfe); in vfe_disable_output()
347 * vfe_enable - Enable streaming on VFE line
348 * @line: VFE line
354 struct vfe_device *vfe = to_vfe(line); in vfe_enable() local
357 mutex_lock(&vfe->stream_lock); in vfe_enable()
359 if (!vfe->stream_count) in vfe_enable()
360 vfe_enable_irq_common(vfe); in vfe_enable()
362 vfe->stream_count++; in vfe_enable()
364 vfe_enable_lines_irq(vfe); in vfe_enable()
366 mutex_unlock(&vfe->stream_lock); in vfe_enable()
376 vfe->was_streaming = 1; in vfe_enable()
384 mutex_lock(&vfe->stream_lock); in vfe_enable()
386 vfe->stream_count--; in vfe_enable()
388 mutex_unlock(&vfe->stream_lock); in vfe_enable()
394 * vfe_disable - Disable streaming on VFE line
395 * @line: VFE line
401 struct vfe_device *vfe = to_vfe(line); in vfe_disable() local
407 mutex_lock(&vfe->stream_lock); in vfe_disable()
409 vfe->stream_count--; in vfe_disable()
411 mutex_unlock(&vfe->stream_lock); in vfe_disable()
418 * @vfe: VFE Device
419 * @line_id: VFE line
421 static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) in vfe_isr_reg_update() argument
426 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_isr_reg_update()
427 vfe_reg_update_clear(vfe, line_id); in vfe_isr_reg_update()
429 output = &vfe->line[line_id].output; in vfe_isr_reg_update()
436 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_reg_update()
441 * @vfe: VFE Device
444 static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) in vfe_isr_wm_done() argument
446 struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]]; in vfe_isr_wm_done()
453 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_isr_wm_done()
455 if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { in vfe_isr_wm_done()
456 dev_err_ratelimited(vfe->camss->dev, in vfe_isr_wm_done()
460 output = &vfe->line[vfe->wm_output_map[wm]].output; in vfe_isr_wm_done()
464 dev_err_ratelimited(vfe->camss->dev, in vfe_isr_wm_done()
480 vfe_wm_update(vfe, output->wm_idx[0], output->buf[index]->addr[0], line); in vfe_isr_wm_done()
484 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_wm_done()
491 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_isr_wm_done()
495 * vfe_pm_domain_off - Disable power domains specific to this VFE.
496 * @vfe: VFE Device
498 static void vfe_pm_domain_off(struct vfe_device *vfe) in vfe_pm_domain_off() argument
500 struct camss *camss = vfe->camss; in vfe_pm_domain_off()
502 if (vfe->id >= camss->vfe_num) in vfe_pm_domain_off()
505 device_link_del(camss->genpd_link[vfe->id]); in vfe_pm_domain_off()
509 * vfe_pm_domain_on - Enable power domains specific to this VFE.
510 * @vfe: VFE Device
512 static int vfe_pm_domain_on(struct vfe_device *vfe) in vfe_pm_domain_on() argument
514 struct camss *camss = vfe->camss; in vfe_pm_domain_on()
515 enum vfe_line_id id = vfe->id; in vfe_pm_domain_on()
544 struct vfe_device *vfe = to_vfe(line); in vfe_queue_buffer() local
550 spin_lock_irqsave(&vfe->output_lock, flags); in vfe_queue_buffer()
554 vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line); in vfe_queue_buffer()
559 spin_unlock_irqrestore(&vfe->output_lock, flags); in vfe_queue_buffer()
569 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) in vfe_subdev_init() argument
571 vfe->video_ops = vfe_video_ops_480; in vfe_subdev_init()
572 vfe->line_num = MAX_VFE_OUTPUT_LINES; in vfe_subdev_init()