aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/ipu3/ipu3.h
blob: 73b123b2b8a2d9faca81d82839f777acfdda7a8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018 Intel Corporation */

#ifndef __IPU3_H
#define __IPU3_H

#include <linux/iova.h>
#include <linux/pci.h>

#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-dma-sg.h>

#include "ipu3-css.h"

#define IMGU_NAME			"ipu3-imgu"

/*
 * The semantics of the driver is that whenever there is a buffer available in
 * master queue, the driver queues a buffer also to all other active nodes.
 * If user space hasn't provided a buffer to all other video nodes first,
 * the driver gets an internal dummy buffer and queues it.
 */
#define IMGU_QUEUE_MASTER		IPU3_CSS_QUEUE_IN
#define IMGU_QUEUE_FIRST_INPUT		IPU3_CSS_QUEUE_OUT
#define IMGU_MAX_QUEUE_DEPTH		(2 + 2)

#define IMGU_NODE_IN			0 /* Input RAW image */
#define IMGU_NODE_PARAMS		1 /* Input parameters */
#define IMGU_NODE_OUT			2 /* Main output for still or video */
#define IMGU_NODE_VF			3 /* Preview */
#define IMGU_NODE_STAT_3A		4 /* 3A statistics */
#define IMGU_NODE_NUM			5

#define file_to_intel_imgu_node(__file) \
	container_of(video_devdata(__file), struct imgu_video_device, vdev)

#define IPU3_INPUT_MIN_WIDTH		0U
#define IPU3_INPUT_MIN_HEIGHT		0U
#define IPU3_INPUT_MAX_WIDTH		5120U
#define IPU3_INPUT_MAX_HEIGHT		38404U
#define IPU3_OUTPUT_MIN_WIDTH		2U
#define IPU3_OUTPUT_MIN_HEIGHT		2U
#define IPU3_OUTPUT_MAX_WIDTH		4480U
#define IPU3_OUTPUT_MAX_HEIGHT		34004U

struct imgu_vb2_buffer {
	/* Public fields */
	struct vb2_v4l2_buffer vbb;	/* Must be the first field */

	/* Private fields */
	struct list_head list;
};

struct imgu_buffer {
	struct imgu_vb2_buffer vid_buf;	/* Must be the first field */
	struct imgu_css_buffer css_buf;
	struct imgu_css_map map;
};

struct imgu_node_mapping {
	unsigned int css_queue;
	const char *name;
};

/**
 * struct imgu_video_device
 * each node registers as video device and maintains its
 * own vb2_queue.
 */
struct imgu_video_device {
	const char *name;
	bool output;
	bool enabled;
	struct v4l2_format vdev_fmt;	/* Currently set format */

	/* Private fields */
	struct video_device vdev;
	struct media_pad vdev_pad;
	struct v4l2_mbus_framefmt pad_fmt;
	struct vb2_queue vbq;
	struct list_head buffers;
	/* Protect vb2_queue and vdev structs*/
	struct mutex lock;
	atomic_t sequence;
	unsigned int id;
	unsigned int pipe;
};

struct imgu_v4l2_subdev {
	unsigned int pipe;
	struct v4l2_subdev subdev;
	struct media_pad subdev_pads[IMGU_NODE_NUM];
	struct {
		struct v4l2_rect eff; /* effective resolution */
		struct v4l2_rect bds; /* bayer-domain scaled resolution*/
		struct v4l2_rect gdc; /* gdc output resolution */
	} rect;
	struct v4l2_ctrl_handler ctrl_handler;
	struct v4l2_ctrl *ctrl;
	atomic_t running_mode;
	bool active;
};

struct imgu_media_pipe {
	unsigned int pipe;

	/* Internally enabled queues */
	struct {
		struct imgu_css_map dmap;
		struct imgu_css_buffer dummybufs[IMGU_MAX_QUEUE_DEPTH];
	} queues[IPU3_CSS_QUEUES];
	struct imgu_video_device nodes[IMGU_NODE_NUM];
	bool queue_enabled[IMGU_NODE_NUM];
	struct media_pipeline pipeline;
	struct imgu_v4l2_subdev imgu_sd;
};

/*
 * imgu_device -- ImgU (Imaging Unit) driver
 */
struct imgu_device {
	struct pci_dev *pci_dev;
	void __iomem *base;

	/* Public fields, fill before registering */
	unsigned int buf_struct_size;
	bool streaming;		/* Public read only */

	struct imgu_media_pipe imgu_pipe[IMGU_MAX_PIPE_NUM];

	/* Private fields */
	struct v4l2_device v4l2_dev;
	struct media_device media_dev;
	struct v4l2_file_operations v4l2_file_ops;

	/* MMU driver for css */
	struct imgu_mmu_info *mmu;
	struct iova_domain iova_domain;

	/* css - Camera Sub-System */
	struct imgu_css css;

	/*
	 * Coarse-grained lock to protect
	 * vid_buf.list and css->queue
	 */
	struct mutex lock;
	/* Forbid streaming and buffer queuing during system suspend. */
	atomic_t qbuf_barrier;
	/* Indicate if system suspend take place while imgu is streaming. */
	bool suspend_in_stream;
	/* Used to wait for FW buffer queue drain. */
	wait_queue_head_t buf_drain_wq;
};

unsigned int imgu_node_to_queue(unsigned int node);
unsigned int imgu_map_node(struct imgu_device *imgu, unsigned int css_queue);
int imgu_queue_buffers(struct imgu_device *imgu, bool initial,
		       unsigned int pipe);

int imgu_v4l2_register(struct imgu_device *dev);
int imgu_v4l2_unregister(struct imgu_device *dev);
void imgu_v4l2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);

int imgu_s_stream(struct imgu_device *imgu, int enable);

#endif