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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ARM Mali-C55 ISP Driver - Common definitions
*
* Copyright (C) 2025 Ideas on Board Oy
*/
#ifndef _MALI_C55_COMMON_H
#define _MALI_C55_COMMON_H
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <media/media-device.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-isp.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#define MALI_C55_DRIVER_NAME "mali-c55"
/* min and max values for the image sizes */
#define MALI_C55_MIN_WIDTH 640U
#define MALI_C55_MIN_HEIGHT 480U
#define MALI_C55_MAX_WIDTH 8192U
#define MALI_C55_MAX_HEIGHT 8192U
#define MALI_C55_DEFAULT_WIDTH 1920U
#define MALI_C55_DEFAULT_HEIGHT 1080U
#define MALI_C55_DEFAULT_MEDIA_BUS_FMT MEDIA_BUS_FMT_RGB121212_1X36
#define MALI_C55_NUM_CLKS 3
#define MALI_C55_NUM_RESETS 3
struct device;
struct mali_c55;
struct mali_c55_cap_dev;
struct media_pipeline;
struct mali_c55_params_buffer;
struct platform_device;
struct resource;
enum mali_c55_isp_pads {
MALI_C55_ISP_PAD_SINK_VIDEO,
MALI_C55_ISP_PAD_SOURCE_VIDEO,
MALI_C55_ISP_PAD_SOURCE_BYPASS,
MALI_C55_ISP_PAD_SOURCE_STATS,
MALI_C55_ISP_PAD_SINK_PARAMS,
MALI_C55_ISP_NUM_PADS,
};
struct mali_c55_tpg {
struct mali_c55 *mali_c55;
struct v4l2_subdev sd;
struct media_pad pad;
struct mali_c55_tpg_ctrls {
struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *vblank;
} ctrls;
};
struct mali_c55_isp {
struct mali_c55 *mali_c55;
struct v4l2_subdev sd;
struct media_pad pads[MALI_C55_ISP_NUM_PADS];
struct v4l2_ctrl_handler handler;
struct media_pad *remote_src;
/* Mutex to guard vb2 start/stop streaming */
struct mutex capture_lock;
unsigned int frame_sequence;
};
enum mali_c55_resizer_ids {
MALI_C55_RSZ_FR,
MALI_C55_RSZ_DS,
MALI_C55_NUM_RSZS,
};
enum mali_c55_rsz_pads {
MALI_C55_RSZ_SINK_PAD,
MALI_C55_RSZ_SOURCE_PAD,
MALI_C55_RSZ_SINK_BYPASS_PAD,
MALI_C55_RSZ_NUM_PADS
};
struct mali_c55_resizer {
struct mali_c55 *mali_c55;
struct mali_c55_cap_dev *cap_dev;
enum mali_c55_resizer_ids id;
struct v4l2_subdev sd;
struct media_pad pads[MALI_C55_RSZ_NUM_PADS];
unsigned int num_routes;
};
enum mali_c55_cap_devs {
MALI_C55_CAP_DEV_FR,
MALI_C55_CAP_DEV_DS,
MALI_C55_NUM_CAP_DEVS
};
struct mali_c55_format_info {
u32 fourcc;
/*
* The output formats can be produced by a couple of different media bus
* formats, depending on how the ISP is configured.
*/
unsigned int mbus_codes[2];
bool is_raw;
struct {
u32 base_mode;
u32 uv_plane;
} registers;
};
struct mali_c55_isp_format_info {
u32 code;
u32 shifted_code;
bool bypass;
u32 order;
};
enum mali_c55_planes {
MALI_C55_PLANE_Y,
MALI_C55_PLANE_UV,
MALI_C55_NUM_PLANES
};
struct mali_c55_buffer {
struct vb2_v4l2_buffer vb;
unsigned int planes_pending;
struct list_head queue;
dma_addr_t addrs[MALI_C55_NUM_PLANES];
};
struct mali_c55_cap_dev {
struct mali_c55 *mali_c55;
struct mali_c55_resizer *rsz;
struct video_device vdev;
struct media_pad pad;
struct vb2_queue queue;
/* Mutex to provide to vb2 */
struct mutex lock;
unsigned int reg_offset;
struct {
const struct mali_c55_format_info *info;
struct v4l2_pix_format_mplane format;
} format;
struct {
/* Spinlock to guard buffer queue */
spinlock_t lock;
/* Spinlock to guard the queue of buffers being processed */
spinlock_t processing_lock;
struct list_head input;
struct list_head processing;
} buffers;
};
struct mali_c55_stats_buf {
struct vb2_v4l2_buffer vb;
unsigned int segments_remaining;
struct list_head queue;
bool failed;
};
struct mali_c55_params_buf {
struct vb2_v4l2_buffer vb;
struct list_head queue;
struct v4l2_isp_params_buffer *config;
};
struct mali_c55_stats {
struct mali_c55 *mali_c55;
struct video_device vdev;
struct vb2_queue queue;
struct media_pad pad;
/* Mutex to provide to vb2 */
struct mutex lock;
struct {
/* Spinlock to guard buffer queue */
spinlock_t lock;
struct list_head queue;
} buffers;
};
struct mali_c55_params {
struct mali_c55 *mali_c55;
struct video_device vdev;
struct vb2_queue queue;
struct media_pad pad;
/* Mutex to provide to vb2 */
struct mutex lock;
struct {
/* Spinlock to guard buffer queue */
spinlock_t lock;
struct list_head queue;
} buffers;
};
enum mali_c55_config_spaces {
MALI_C55_CONFIG_PONG,
MALI_C55_CONFIG_PING,
};
/**
* struct mali_c55_context - Fields relating to a single camera context
*
* @mali_c55: Pointer to the main struct mali_c55
* @registers: A pointer to some allocated memory holding register
* values to be written to the hardware at frame interrupt
* @base: Base address of the config space in the hardware
* @lock: A spinlock to protect against writes to @registers whilst that
* space is being copied to the hardware
* @list: A list head to facilitate a context queue
*/
struct mali_c55_context {
struct mali_c55 *mali_c55;
u32 *registers;
phys_addr_t base;
/* Spinlock to prevent simultaneous access of register space */
spinlock_t lock;
struct list_head list;
};
struct mali_c55 {
struct device *dev;
void __iomem *base;
struct clk_bulk_data clks[MALI_C55_NUM_CLKS];
struct reset_control_bulk_data resets[MALI_C55_NUM_RESETS];
int irqnum;
u16 capabilities;
bool inline_mode;
struct media_device media_dev;
struct v4l2_device v4l2_dev;
struct v4l2_async_notifier notifier;
struct media_pipeline pipe;
struct mali_c55_tpg tpg;
struct mali_c55_isp isp;
struct mali_c55_resizer resizers[MALI_C55_NUM_RSZS];
struct mali_c55_cap_dev cap_devs[MALI_C55_NUM_CAP_DEVS];
struct mali_c55_params params;
struct mali_c55_stats stats;
struct mali_c55_context context;
u32 next_config;
};
void mali_c55_write(struct mali_c55 *mali_c55, unsigned int addr, u32 val);
void mali_c55_cap_dev_write(struct mali_c55_cap_dev *cap_dev, unsigned int addr,
u32 val);
void mali_c55_update_bits(struct mali_c55 *mali_c55, unsigned int addr,
u32 mask, u32 val);
u32 mali_c55_read(struct mali_c55 *mali_c55, unsigned int addr);
void mali_c55_ctx_write(struct mali_c55 *mali_c55, unsigned int addr, u32 val);
u32 mali_c55_ctx_read(struct mali_c55 *mali_c55, unsigned int addr);
void mali_c55_ctx_update_bits(struct mali_c55 *mali_c55, unsigned int addr,
u32 mask, u32 val);
int mali_c55_config_write(struct mali_c55_context *ctx,
enum mali_c55_config_spaces cfg_space,
bool force_synchronous);
int mali_c55_register_isp(struct mali_c55 *mali_c55);
int mali_c55_register_tpg(struct mali_c55 *mali_c55);
void mali_c55_unregister_tpg(struct mali_c55 *mali_c55);
void mali_c55_unregister_isp(struct mali_c55 *mali_c55);
int mali_c55_register_resizers(struct mali_c55 *mali_c55);
void mali_c55_unregister_resizers(struct mali_c55 *mali_c55);
int mali_c55_register_capture_devs(struct mali_c55 *mali_c55);
void mali_c55_unregister_capture_devs(struct mali_c55 *mali_c55);
int mali_c55_register_stats(struct mali_c55 *mali_c55);
void mali_c55_unregister_stats(struct mali_c55 *mali_c55);
int mali_c55_register_params(struct mali_c55 *mali_c55);
void mali_c55_unregister_params(struct mali_c55 *mali_c55);
struct mali_c55_context *mali_c55_get_active_context(struct mali_c55 *mali_c55);
void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev,
enum mali_c55_planes plane);
void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev);
void mali_c55_isp_queue_event_sof(struct mali_c55 *mali_c55);
bool mali_c55_format_is_raw(unsigned int mbus_code);
const struct mali_c55_isp_format_info *
mali_c55_isp_fmt_next(const struct mali_c55_isp_format_info *fmt);
const struct mali_c55_isp_format_info *
mali_c55_isp_get_mbus_config_by_code(u32 code);
const struct mali_c55_isp_format_info *
mali_c55_isp_get_mbus_config_by_shifted_code(u32 code);
const struct mali_c55_isp_format_info *
mali_c55_isp_get_mbus_config_by_index(u32 index);
bool mali_c55_pipeline_ready(struct mali_c55 *mali_c55);
void mali_c55_stats_fill_buffer(struct mali_c55 *mali_c55,
enum mali_c55_config_spaces cfg_space);
void mali_c55_params_write_config(struct mali_c55 *mali_c55);
#endif /* _MALI_C55_COMMON_H */
|