162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * camss-vfe.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
862306a36Sopenharmony_ci * Copyright (C) 2015-2018 Linaro Ltd.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#ifndef QC_MSM_CAMSS_VFE_H
1162306a36Sopenharmony_ci#define QC_MSM_CAMSS_VFE_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/clk.h>
1462306a36Sopenharmony_ci#include <linux/spinlock_types.h>
1562306a36Sopenharmony_ci#include <media/media-entity.h>
1662306a36Sopenharmony_ci#include <media/v4l2-device.h>
1762306a36Sopenharmony_ci#include <media/v4l2-subdev.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include "camss-video.h"
2062306a36Sopenharmony_ci#include "camss-vfe-gen1.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define MSM_VFE_PAD_SINK 0
2362306a36Sopenharmony_ci#define MSM_VFE_PAD_SRC 1
2462306a36Sopenharmony_ci#define MSM_VFE_PADS_NUM 2
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define MSM_VFE_IMAGE_MASTERS_NUM 7
2762306a36Sopenharmony_ci#define MSM_VFE_COMPOSITE_IRQ_NUM 4
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* VFE halt timeout */
3062306a36Sopenharmony_ci#define VFE_HALT_TIMEOUT_MS 100
3162306a36Sopenharmony_ci/* Frame drop value. VAL + UPDATES - 1 should not exceed 31 */
3262306a36Sopenharmony_ci#define VFE_FRAME_DROP_VAL 30
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define vfe_line_array(ptr_line)	\
3562306a36Sopenharmony_ci	((const struct vfe_line (*)[]) &(ptr_line)[-(ptr_line)->id])
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define to_vfe(ptr_line)	\
3862306a36Sopenharmony_ci	container_of(vfe_line_array(ptr_line), struct vfe_device, line)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cienum vfe_output_state {
4162306a36Sopenharmony_ci	VFE_OUTPUT_OFF,
4262306a36Sopenharmony_ci	VFE_OUTPUT_RESERVED,
4362306a36Sopenharmony_ci	VFE_OUTPUT_SINGLE,
4462306a36Sopenharmony_ci	VFE_OUTPUT_CONTINUOUS,
4562306a36Sopenharmony_ci	VFE_OUTPUT_IDLE,
4662306a36Sopenharmony_ci	VFE_OUTPUT_STOPPING,
4762306a36Sopenharmony_ci	VFE_OUTPUT_ON,
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cienum vfe_line_id {
5162306a36Sopenharmony_ci	VFE_LINE_NONE = -1,
5262306a36Sopenharmony_ci	VFE_LINE_RDI0 = 0,
5362306a36Sopenharmony_ci	VFE_LINE_RDI1 = 1,
5462306a36Sopenharmony_ci	VFE_LINE_RDI2 = 2,
5562306a36Sopenharmony_ci	VFE_LINE_NUM_GEN2 = 3,
5662306a36Sopenharmony_ci	VFE_LINE_PIX = 3,
5762306a36Sopenharmony_ci	VFE_LINE_NUM_GEN1 = 4,
5862306a36Sopenharmony_ci	VFE_LINE_NUM_MAX = 4
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistruct vfe_output {
6262306a36Sopenharmony_ci	u8 wm_num;
6362306a36Sopenharmony_ci	u8 wm_idx[3];
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	struct camss_buffer *buf[2];
6662306a36Sopenharmony_ci	struct camss_buffer *last_buffer;
6762306a36Sopenharmony_ci	struct list_head pending_bufs;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	unsigned int drop_update_idx;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	union {
7262306a36Sopenharmony_ci		struct {
7362306a36Sopenharmony_ci			int active_buf;
7462306a36Sopenharmony_ci			int wait_sof;
7562306a36Sopenharmony_ci		} gen1;
7662306a36Sopenharmony_ci		struct {
7762306a36Sopenharmony_ci			int active_num;
7862306a36Sopenharmony_ci		} gen2;
7962306a36Sopenharmony_ci	};
8062306a36Sopenharmony_ci	enum vfe_output_state state;
8162306a36Sopenharmony_ci	unsigned int sequence;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	int wait_reg_update;
8462306a36Sopenharmony_ci	struct completion sof;
8562306a36Sopenharmony_ci	struct completion reg_update;
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistruct vfe_line {
8962306a36Sopenharmony_ci	enum vfe_line_id id;
9062306a36Sopenharmony_ci	struct v4l2_subdev subdev;
9162306a36Sopenharmony_ci	struct media_pad pads[MSM_VFE_PADS_NUM];
9262306a36Sopenharmony_ci	struct v4l2_mbus_framefmt fmt[MSM_VFE_PADS_NUM];
9362306a36Sopenharmony_ci	struct v4l2_rect compose;
9462306a36Sopenharmony_ci	struct v4l2_rect crop;
9562306a36Sopenharmony_ci	struct camss_video video_out;
9662306a36Sopenharmony_ci	struct vfe_output output;
9762306a36Sopenharmony_ci	const struct vfe_format *formats;
9862306a36Sopenharmony_ci	unsigned int nformats;
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistruct vfe_device;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistruct vfe_hw_ops {
10462306a36Sopenharmony_ci	void (*enable_irq_common)(struct vfe_device *vfe);
10562306a36Sopenharmony_ci	void (*global_reset)(struct vfe_device *vfe);
10662306a36Sopenharmony_ci	u32 (*hw_version)(struct vfe_device *vfe);
10762306a36Sopenharmony_ci	irqreturn_t (*isr)(int irq, void *dev);
10862306a36Sopenharmony_ci	void (*isr_read)(struct vfe_device *vfe, u32 *value0, u32 *value1);
10962306a36Sopenharmony_ci	void (*pm_domain_off)(struct vfe_device *vfe);
11062306a36Sopenharmony_ci	int (*pm_domain_on)(struct vfe_device *vfe);
11162306a36Sopenharmony_ci	void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
11262306a36Sopenharmony_ci	void (*reg_update_clear)(struct vfe_device *vfe,
11362306a36Sopenharmony_ci				 enum vfe_line_id line_id);
11462306a36Sopenharmony_ci	void (*subdev_init)(struct device *dev, struct vfe_device *vfe);
11562306a36Sopenharmony_ci	int (*vfe_disable)(struct vfe_line *line);
11662306a36Sopenharmony_ci	int (*vfe_enable)(struct vfe_line *line);
11762306a36Sopenharmony_ci	int (*vfe_halt)(struct vfe_device *vfe);
11862306a36Sopenharmony_ci	void (*violation_read)(struct vfe_device *vfe);
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistruct vfe_isr_ops {
12262306a36Sopenharmony_ci	void (*reset_ack)(struct vfe_device *vfe);
12362306a36Sopenharmony_ci	void (*halt_ack)(struct vfe_device *vfe);
12462306a36Sopenharmony_ci	void (*reg_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
12562306a36Sopenharmony_ci	void (*sof)(struct vfe_device *vfe, enum vfe_line_id line_id);
12662306a36Sopenharmony_ci	void (*comp_done)(struct vfe_device *vfe, u8 comp);
12762306a36Sopenharmony_ci	void (*wm_done)(struct vfe_device *vfe, u8 wm);
12862306a36Sopenharmony_ci};
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_cistruct vfe_device {
13162306a36Sopenharmony_ci	struct camss *camss;
13262306a36Sopenharmony_ci	u8 id;
13362306a36Sopenharmony_ci	void __iomem *base;
13462306a36Sopenharmony_ci	u32 irq;
13562306a36Sopenharmony_ci	char irq_name[30];
13662306a36Sopenharmony_ci	struct camss_clock *clock;
13762306a36Sopenharmony_ci	int nclocks;
13862306a36Sopenharmony_ci	struct completion reset_complete;
13962306a36Sopenharmony_ci	struct completion halt_complete;
14062306a36Sopenharmony_ci	struct mutex power_lock;
14162306a36Sopenharmony_ci	int power_count;
14262306a36Sopenharmony_ci	struct mutex stream_lock;
14362306a36Sopenharmony_ci	int stream_count;
14462306a36Sopenharmony_ci	spinlock_t output_lock;
14562306a36Sopenharmony_ci	enum vfe_line_id wm_output_map[MSM_VFE_IMAGE_MASTERS_NUM];
14662306a36Sopenharmony_ci	struct vfe_line line[VFE_LINE_NUM_MAX];
14762306a36Sopenharmony_ci	u8 line_num;
14862306a36Sopenharmony_ci	u32 reg_update;
14962306a36Sopenharmony_ci	u8 was_streaming;
15062306a36Sopenharmony_ci	const struct vfe_hw_ops *ops;
15162306a36Sopenharmony_ci	const struct vfe_hw_ops_gen1 *ops_gen1;
15262306a36Sopenharmony_ci	struct vfe_isr_ops isr_ops;
15362306a36Sopenharmony_ci	struct camss_video_ops video_ops;
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistruct resources;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciint msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
15962306a36Sopenharmony_ci			const struct resources *res, u8 id);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciint msm_vfe_register_entities(struct vfe_device *vfe,
16262306a36Sopenharmony_ci			      struct v4l2_device *v4l2_dev);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_civoid msm_vfe_unregister_entities(struct vfe_device *vfe);
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci/*
16762306a36Sopenharmony_ci * vfe_buf_add_pending - Add output buffer to list of pending
16862306a36Sopenharmony_ci * @output: VFE output
16962306a36Sopenharmony_ci * @buffer: Video buffer
17062306a36Sopenharmony_ci */
17162306a36Sopenharmony_civoid vfe_buf_add_pending(struct vfe_output *output, struct camss_buffer *buffer);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistruct camss_buffer *vfe_buf_get_pending(struct vfe_output *output);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ciint vfe_flush_buffers(struct camss_video *vid, enum vb2_buffer_state state);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci/*
17862306a36Sopenharmony_ci * vfe_isr_comp_done - Process composite image done interrupt
17962306a36Sopenharmony_ci * @vfe: VFE Device
18062306a36Sopenharmony_ci * @comp: Composite image id
18162306a36Sopenharmony_ci */
18262306a36Sopenharmony_civoid vfe_isr_comp_done(struct vfe_device *vfe, u8 comp);
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_civoid vfe_isr_reset_ack(struct vfe_device *vfe);
18562306a36Sopenharmony_ciint vfe_put_output(struct vfe_line *line);
18662306a36Sopenharmony_ciint vfe_release_wm(struct vfe_device *vfe, u8 wm);
18762306a36Sopenharmony_ciint vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id);
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci/*
19062306a36Sopenharmony_ci * vfe_reset - Trigger reset on VFE module and wait to complete
19162306a36Sopenharmony_ci * @vfe: VFE device
19262306a36Sopenharmony_ci *
19362306a36Sopenharmony_ci * Return 0 on success or a negative error code otherwise
19462306a36Sopenharmony_ci */
19562306a36Sopenharmony_ciint vfe_reset(struct vfe_device *vfe);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ciextern const struct vfe_hw_ops vfe_ops_4_1;
19862306a36Sopenharmony_ciextern const struct vfe_hw_ops vfe_ops_4_7;
19962306a36Sopenharmony_ciextern const struct vfe_hw_ops vfe_ops_4_8;
20062306a36Sopenharmony_ciextern const struct vfe_hw_ops vfe_ops_170;
20162306a36Sopenharmony_ciextern const struct vfe_hw_ops vfe_ops_480;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ciint vfe_get(struct vfe_device *vfe);
20462306a36Sopenharmony_civoid vfe_put(struct vfe_device *vfe);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci#endif /* QC_MSM_CAMSS_VFE_H */
207