hc
2023-10-16 def2367077573b56f9fc4f824e5c0377a3a4175a
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
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
/*
 * Rockchip VPU codec driver
 *
 * Copyright (C) 2014 Google, Inc.
 *    Tomasz Figa <tfiga@chromium.org>
 *
 * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
 *
 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
 
#ifndef ROCKCHIP_VPU_COMMON_H_
#define ROCKCHIP_VPU_COMMON_H_
 
/* Enable debugging by default for now. */
#define DEBUG
 
#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <linux/wait.h>
 
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
 
#include "rockchip_vpu_hw.h"
 
#define ROCKCHIP_VPU_NAME        "rockchip-vpu"
#define ROCKCHIP_VPU_DEC_NAME        "rockchip-vpu-dec"
#define ROCKCHIP_VPU_ENC_NAME        "rockchip-vpu-enc"
 
#define V4L2_CID_CUSTOM_BASE        (V4L2_CID_USER_BASE | 0x1000)
 
#define DST_QUEUE_OFF_BASE        (TASK_SIZE / 2)
 
#define ROCKCHIP_VPU_MAX_CTRLS        32
 
#define MB_DIM                16
#define MB_WIDTH(x_size)        DIV_ROUND_UP(x_size, MB_DIM)
#define MB_HEIGHT(y_size)        DIV_ROUND_UP(y_size, MB_DIM)
 
struct rockchip_vpu_ctx;
struct rockchip_vpu_codec_ops;
 
/**
 * struct rockchip_vpu_variant - information about VPU hardware variant
 *
 * @hw_id:        Top 16 bits (product ID) of hardware ID register.
 * @name:        Vpu name.
 * @codecs:        Supported codecs of this vpu.
 * @enc_offset:        Offset from VPU base to encoder registers.
 * @enc_reg_num:    Number of registers of encoder block.
 * @dec_offset:        Offset from VPU base to decoder registers.
 * @dec_reg_num:    Number of registers of decoder block.
 */
struct rockchip_vpu_variant {
   char *name;
   unsigned codecs;
   unsigned enc_offset;
   unsigned enc_reg_num;
   unsigned dec_offset;
   unsigned dec_reg_num;
};
 
/**
 * enum rockchip_vpu_codec_mode - codec operating mode.
 * @RK_VPU_CODEC_NONE:        Used for RAW video formats.
 * @RK3288_VPU_CODEC_H264D:    Rk3288 H264 decoder.
 * @RK3288_VPU_CODEC_H264E:    Rk3288 H264 encoder.
 * @RK3288_VPU_CODEC_VP8D:    Rk3288 VP8 decoder.
 * @RK3288_VPU_CODEC_VP8E:    Rk3288 VP8 encoder.
 */
enum rockchip_vpu_codec_mode {
   RK_VPU_CODEC_NONE    = (1 << 0),
   RK3288_VPU_CODEC_H264D    = (1 << 1),
   RK3288_VPU_CODEC_H264E    = (1 << 2),
   RK3288_VPU_CODEC_VP8D    = (1 << 3),
   RK3288_VPU_CODEC_VP8E    = (1 << 4),
};
 
#define ROCKCHIP_VPU_DECODERS    (RK3288_VPU_CODEC_H264D | RK3288_VPU_CODEC_VP8D)
#define ROCKCHIP_VPU_ENCODERS    (RK3288_VPU_CODEC_H264E | RK3288_VPU_CODEC_VP8E)
 
#define RK3288_CODECS        (RK_VPU_CODEC_NONE | RK3288_VPU_CODEC_H264D | RK3288_VPU_CODEC_H264E | RK3288_VPU_CODEC_VP8D | RK3288_VPU_CODEC_VP8E)
 
/**
 * enum rockchip_vpu_plane - indices of planes inside a VB2 buffer.
 * @PLANE_Y:        Plane containing luminance data (also denoted as Y).
 * @PLANE_CB_CR:    Plane containing interleaved chrominance data (also
 *            denoted as CbCr).
 * @PLANE_CB:        Plane containing CB part of chrominance data.
 * @PLANE_CR:        Plane containing CR part of chrominance data.
 */
enum rockchip_vpu_plane {
   PLANE_Y        = 0,
   PLANE_CB_CR    = 1,
   PLANE_CB    = 1,
   PLANE_CR    = 2,
};
 
/**
 * struct rockchip_vpu_vp8e_buf_data - mode-specific per-buffer data
 * @dct_offset:        Offset inside the buffer to DCT partition.
 * @hdr_size:        Size of header data in the buffer.
 * @ext_hdr_size:    Size of ext header data in the buffer.
 * @dct_size:        Size of DCT partition in the buffer.
 * @header:        Frame header to copy to destination buffer.
 */
struct rockchip_vpu_vp8e_buf_data {
   size_t dct_offset;
   size_t hdr_size;
   size_t ext_hdr_size;
   size_t dct_size;
   u8 header[ROCKCHIP_HEADER_SIZE];
};
 
/**
 * struct rockchip_vpu_h264e_buf_data - mode-specific per-buffer data
 * @sps_size:        Size of sps data in the buffer.
 * @pps_size:        Size of pps data in the buffer.
 * @slices_size:    Size of slices data in the buffer.
 */
struct rockchip_vpu_h264e_buf_data {
   size_t sps_size;
   size_t pps_size;
   size_t slices_size;
};
 
/**
 * struct rockchip_vpu_buf - Private data related to each VB2 buffer.
 * @vb:            Pointer to related VB2 buffer.
 * @list:        List head for queuing in buffer queue.
 */
struct rockchip_vpu_buf {
   struct vb2_v4l2_buffer vb;
   struct list_head list;
 
   /* Mode-specific data. */
   union {
       struct rockchip_vpu_h264e_buf_data h264e;
       struct rockchip_vpu_vp8e_buf_data vp8e;
   };
};
 
/**
 * enum rockchip_vpu_state - bitwise flags indicating hardware state.
 * @VPU_RUNNING:    The hardware has been programmed for operation
 *            and is running at the moment.
 * @VPU_SUSPENDED:    System is entering sleep state and no more runs
 *            should be executed on hardware.
 */
enum rockchip_vpu_state {
   VPU_RUNNING    = BIT(0),
   VPU_SUSPENDED    = BIT(1),
};
 
/**
 * struct rockchip_vpu_dev - driver data
 * @v4l2_dev:        V4L2 device to register video devices for.
 * @vfd_dec:        Video device for decoder.
 * @vfd_enc:        Video device for encoder.
 * @pdev:        Pointer to VPU platform device.
 * @dev:        Pointer to device for convenient logging using
 *            dev_ macros.
 * @alloc_ctx:        VB2 allocator context
 *            (for allocations without kernel mapping).
 * @alloc_ctx_vm:    VB2 allocator context
 *            (for allocations with kernel mapping).
 * @aclk:        Handle of ACLK clock.
 * @hclk:        Handle of HCLK clock.
 * @base:        Mapped address of VPU registers.
 * @enc_base:        Mapped address of VPU encoder register for convenience.
 * @dec_base:        Mapped address of VPU decoder register for convenience.
 * @mapping:        DMA IOMMU mapping.
 * @domain:        DMA IOMMU domain.
 * @vpu_mutex:        Mutex to synchronize V4L2 calls.
 * @irqlock:        Spinlock to synchronize access to data structures
 *            shared with interrupt handlers.
 * @state:        Device state.
 * @ready_ctxs:        List of contexts ready to run.
 * @variant:        Hardware variant-specfic parameters.
 * @current_ctx:    Context being currently processed by hardware.
 * @run_wq:        Wait queue to wait for run completion.
 * @watchdog_work:    Delayed work for hardware timeout handling.
 * @dummy_encode_ctx:    Context used to run dummy frame encoding to initialize
 *            encoder hardware state.
 * @dummy_encode_src:    Source buffers used for dummy frame encoding.
 * @dummy_encode_dst:    Desintation buffer used for dummy frame encoding.
 * @was_decoding:    Indicates whether last run context was a decoder.
 */
struct rockchip_vpu_dev {
   struct v4l2_device v4l2_dev;
   struct video_device *vfd_dec;
   struct video_device *vfd_enc;
   struct platform_device *pdev;
   struct device *dev;
   void *alloc_ctx;
   void *alloc_ctx_vm;
   struct clk *aclk;
   struct clk *hclk;
   void __iomem *base;
   void __iomem *enc_base;
   void __iomem *dec_base;
   struct dma_iommu_mapping *mapping;
   struct iommu_domain *domain;
 
   struct mutex vpu_mutex;    /* video_device lock */
   spinlock_t irqlock;
   unsigned long state;
   struct list_head ready_ctxs;
   const struct rockchip_vpu_variant *variant;
   struct rockchip_vpu_ctx *current_ctx;
   wait_queue_head_t run_wq;
   struct delayed_work watchdog_work;
   struct rockchip_vpu_ctx *dummy_encode_ctx;
   struct rockchip_vpu_aux_buf dummy_encode_src[VIDEO_MAX_PLANES];
   struct rockchip_vpu_aux_buf dummy_encode_dst;
   bool was_decoding;
};
 
/**
 * struct rockchip_vpu_run_ops - per context operations on run data.
 * @prepare_run:    Called when the context was selected for running
 *            to prepare operating mode specific data.
 * @run_done:        Called when hardware completed the run to collect
 *            operating mode specific data from hardware and
 *            finalize the processing.
 */
struct rockchip_vpu_run_ops {
   void (*prepare_run)(struct rockchip_vpu_ctx *);
   void (*run_done)(struct rockchip_vpu_ctx *, enum vb2_buffer_state);
};
 
/**
 * struct rockchip_vpu_vp8e_run - per-run data specific to VP8 encoding.
 * @reg_params:    Pointer to a buffer containing register values prepared
 *        by user space.
 */
struct rockchip_vpu_vp8e_run {
   const struct rockchip_reg_params *reg_params;
};
 
/**
 * struct rockchip_vpu_vp8d_run - per-run data specific to VP8 decoding.
 * @frame_hdr: Pointer to a buffer containing per-run frame data which
 *            is needed by setting vpu register.
 */
struct rockchip_vpu_vp8d_run {
   const struct v4l2_ctrl_vp8_frame_hdr *frame_hdr;
};
 
/**
 * struct rockchip_vpu_h264d_run - per-run data specific to H264 decoding.
 * @sps:        Pointer to a buffer containing H264 SPS.
 * @pps:        Pointer to a buffer containing H264 PPS.
 * @scaling_matrix:    Pointer to a buffer containing scaling matrix.
 * @slice_param:    Pointer to a buffer containing slice parameters array.
 * @decode_param:    Pointer to a buffer containing decode parameters.
 * @dpb:        Array of DPB entries reordered to keep POC order.
 * @dpb_map:        Map of indices used in ref_pic_list_* into indices to
 *            reordered DPB array.
 */
struct rockchip_vpu_h264d_run {
   const struct v4l2_ctrl_h264_sps *sps;
   const struct v4l2_ctrl_h264_pps *pps;
   const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
   const struct v4l2_ctrl_h264_slice_param *slice_param;
   const struct v4l2_ctrl_h264_decode_param *decode_param;
   struct v4l2_h264_dpb_entry dpb[16];
   u8 dpb_map[16];
};
 
/* struct for assemble bitstream */
struct stream_s {
   u8 *buffer; /* point to first byte of stream */
   u8 *stream; /* Pointer to next byte of stream */
   u32 size;   /* Byte size of stream buffer */
   u32 byte_cnt;    /* Byte counter */
   u32 bit_cnt; /* Bit counter */
   u32 byte_buffer; /* Byte buffer */
   u32 buffered_bits;   /* Amount of bits in byte buffer, [0-7] */
   s32 overflow;    /* This will signal a buffer overflow */
};
 
void stream_put_bits(struct stream_s *buffer, s32 value, s32 number,
            const char *name);
void stream_buffer_reset(struct stream_s *buffer);
int stream_buffer_init(struct stream_s *buffer, u8 *stream, s32 size);
 
/**
 * struct rockchip_vpu_h264e_run - per-run data specific to H264 encoding.
 */
struct rockchip_vpu_h264e_run {
   const struct rockchip_reg_params *reg_params;
   struct stream_s sps;
   struct stream_s pps;
   u32 hw_write_offset;
};
 
/**
 * struct rockchip_vpu_run - per-run data for hardware code.
 * @src:        Source buffer to be processed.
 * @dst:        Destination buffer to be processed.
 * @priv_src:        Hardware private source buffer.
 * @priv_dst:        Hardware private destination buffer.
 */
struct rockchip_vpu_run {
   /* Generic for more than one operating mode. */
   struct rockchip_vpu_buf *src;
   struct rockchip_vpu_buf *dst;
 
   struct rockchip_vpu_aux_buf priv_src;
   struct rockchip_vpu_aux_buf priv_dst;
 
   /* Specific for particular operating modes. */
   union {
       struct rockchip_vpu_vp8e_run vp8e;
       struct rockchip_vpu_vp8d_run vp8d;
       struct rockchip_vpu_h264d_run h264d;
       struct rockchip_vpu_h264e_run h264e;
       /* Other modes will need different data. */
   };
};
 
/**
 * struct rockchip_vpu_ctx - Context (instance) private data.
 *
 * @dev:        VPU driver data to which the context belongs.
 * @fh:            V4L2 file handler.
 *
 * @vpu_src_fmt:    Descriptor of active source format.
 * @src_fmt:        V4L2 pixel format of active source format.
 * @vpu_dst_fmt:    Descriptor of active destination format.
 * @dst_fmt:        V4L2 pixel format of active destination format.
 *
 * @vq_src:        Videobuf2 source queue.
 * @src_queue:        Internal source buffer queue.
 * @src_crop:        Configured source crop rectangle (encoder-only).
 * @vq_dst:        Videobuf2 destination queue
 * @dst_queue:        Internal destination buffer queue.
 * @dst_bufs:        Private buffers wrapping VB2 buffers (destination).
 *
 * @ctrls:        Array containing pointer to registered controls.
 * @ctrl_handler:    Control handler used to register controls.
 * @num_ctrls:        Number of registered controls.
 *
 * @list:        List head for queue of ready contexts.
 *
 * @run:        Structure containing data about currently scheduled
 *            processing run.
 * @run_ops:        Set of operations related to currently scheduled run.
 * @hw:            Structure containing hardware-related context.
 */
struct rockchip_vpu_ctx {
   struct rockchip_vpu_dev *dev;
   struct v4l2_fh fh;
 
   /* Format info */
   struct rockchip_vpu_fmt *vpu_src_fmt;
   struct v4l2_pix_format_mplane src_fmt;
   struct rockchip_vpu_fmt *vpu_dst_fmt;
   struct v4l2_pix_format_mplane dst_fmt;
 
   /* VB2 queue data */
   struct vb2_queue vq_src;
   struct list_head src_queue;
   struct v4l2_rect src_crop;
   struct vb2_queue vq_dst;
   struct list_head dst_queue;
   struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
 
   /* Controls */
   struct v4l2_ctrl *ctrls[ROCKCHIP_VPU_MAX_CTRLS];
   struct v4l2_ctrl_handler ctrl_handler;
   unsigned num_ctrls;
 
   /* Various runtime data */
   struct list_head list;
 
   struct rockchip_vpu_run run;
   const struct rockchip_vpu_run_ops *run_ops;
   struct rockchip_vpu_hw_ctx hw;
};
 
/**
 * struct rockchip_vpu_fmt - information about supported video formats.
 * @name:    Human readable name of the format.
 * @fourcc:    FourCC code of the format. See V4L2_PIX_FMT_*.
 * @codec_mode:    Codec mode related to this format. See
 *        enum rockchip_vpu_codec_mode.
 * @num_planes:    Number of planes used by this format.
 * @depth:    Depth of each plane in bits per pixel.
 * @enc_fmt:    Format identifier for encoder registers.
 */
struct rockchip_vpu_fmt {
   char *name;
   u32 fourcc;
   enum rockchip_vpu_codec_mode codec_mode;
   int num_planes;
   u8 depth[VIDEO_MAX_PLANES];
   enum rockchip_vpu_enc_fmt enc_fmt;
};
 
/**
 * struct rockchip_vpu_control - information about controls to be registered.
 * @id:            Control ID.
 * @type:        Type of the control.
 * @name:        Human readable name of the control.
 * @minimum:        Minimum value of the control.
 * @maximum:        Maximum value of the control.
 * @step:        Control value increase step.
 * @menu_skip_mask:    Mask of invalid menu positions.
 * @default_value:    Initial value of the control.
 * @max_stores:        Maximum number of configration stores.
 * @dims:        Size of each dimension of compound control.
 * @elem_size:        Size of individual element of compound control.
 * @is_volatile:    Control is volatile.
 * @is_read_only:    Control is read-only.
 * @can_store:        Control uses configuration stores.
 *
 * See also struct v4l2_ctrl_config.
 */
struct rockchip_vpu_control {
   u32 id;
 
   enum v4l2_ctrl_type type;
   const char *name;
   s32 minimum;
   s32 maximum;
   s32 step;
   u32 menu_skip_mask;
   s32 default_value;
   s32 max_stores;
   u32 dims[V4L2_CTRL_MAX_DIMS];
   u32 elem_size;
 
   bool is_volatile:1;
   bool is_read_only:1;
   bool can_store:1;
};
 
/* Logging helpers */
 
/**
 * debug - Module parameter to control level of debugging messages.
 *
 * Level of debugging messages can be controlled by bits of module parameter
 * called "debug". Meaning of particular bits is as follows:
 *
 * bit 0 - global information: mode, size, init, release
 * bit 1 - each run start/result information
 * bit 2 - contents of small controls from userspace
 * bit 3 - contents of big controls from userspace
 * bit 4 - detail fmt, ctrl, buffer q/dq information
 * bit 5 - detail function enter/leave trace information
 * bit 6 - register write/read information
 */
extern int debug;
 
#define vpu_debug(level, fmt, args...)                \
   do {                            \
       if (debug & BIT(level))                \
           pr_debug("%s:%d: " fmt,                    \
                __func__, __LINE__, ##args);    \
   } while (0)
 
#define vpu_debug_enter()    vpu_debug(5, "enter\n")
#define vpu_debug_leave()    vpu_debug(5, "leave\n")
 
#define vpu_err(fmt, args...)                    \
   pr_err("%s:%d: " fmt, __func__, __LINE__, ##args)
 
static inline char *fmt2str(u32 fmt, char *str)
{
   char a = fmt & 0xFF;
   char b = (fmt >> 8) & 0xFF;
   char c = (fmt >> 16) & 0xFF;
   char d = (fmt >> 24) & 0xFF;
 
   sprintf(str, "%c%c%c%c", a, b, c, d);
 
   return str;
}
 
/* Structure access helpers. */
static inline struct rockchip_vpu_ctx *fh_to_ctx(struct v4l2_fh *fh)
{
   return container_of(fh, struct rockchip_vpu_ctx, fh);
}
 
static inline struct rockchip_vpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
{
   return container_of(ctrl->handler,
           struct rockchip_vpu_ctx, ctrl_handler);
}
 
static inline struct rockchip_vpu_buf *vb_to_buf(struct vb2_buffer *vb)
{
   return container_of(to_vb2_v4l2_buffer(vb),
           struct rockchip_vpu_buf, vb);
}
 
static inline bool rockchip_vpu_ctx_is_encoder(struct rockchip_vpu_ctx *ctx)
{
   return ctx->vpu_dst_fmt->codec_mode != RK_VPU_CODEC_NONE;
}
 
static inline bool
rockchip_vpu_ctx_is_dummy_encode(struct rockchip_vpu_ctx *ctx)
{
   struct rockchip_vpu_dev *dev = ctx->dev;
 
   return ctx == dev->dummy_encode_ctx;
}
 
static inline bool
rockchip_vpu_dev_codec_support(struct rockchip_vpu_dev *dev,
                  enum rockchip_vpu_codec_mode codec_mode)
{
   return !!(codec_mode & dev->variant->codecs);
}
 
int rockchip_vpu_ctrls_setup(struct rockchip_vpu_ctx *ctx,
              const struct v4l2_ctrl_ops *ctrl_ops,
              struct rockchip_vpu_control *controls,
              unsigned num_ctrls,
              const char *const *(*get_menu)(u32));
void rockchip_vpu_ctrls_delete(struct rockchip_vpu_ctx *ctx);
 
void rockchip_vpu_try_context(struct rockchip_vpu_dev *dev,
               struct rockchip_vpu_ctx *ctx);
 
void rockchip_vpu_run_done(struct rockchip_vpu_ctx *ctx,
            enum vb2_buffer_state result);
 
int rockchip_vpu_aux_buf_alloc(struct rockchip_vpu_dev *vpu,
               struct rockchip_vpu_aux_buf *buf, size_t size);
void rockchip_vpu_aux_buf_free(struct rockchip_vpu_dev *vpu,
                struct rockchip_vpu_aux_buf *buf);
 
/* Register accessors. */
static inline void vepu_write_relaxed(struct rockchip_vpu_dev *vpu,
                      u32 val, u32 reg)
{
   vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val);
   writel_relaxed(val, vpu->enc_base + reg);
}
 
static inline void vepu_write(struct rockchip_vpu_dev *vpu, u32 val, u32 reg)
{
   vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val);
   writel(val, vpu->enc_base + reg);
}
 
static inline u32 vepu_read(struct rockchip_vpu_dev *vpu, u32 reg)
{
   u32 val = readl(vpu->enc_base + reg);
 
   vpu_debug(6, "MARK: get reg[%03d]: %08x\n", reg / 4, val);
   return val;
}
 
static inline void vdpu_write_relaxed(struct rockchip_vpu_dev *vpu,
                      u32 val, u32 reg)
{
   vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val);
   writel_relaxed(val, vpu->dec_base + reg);
}
 
static inline void vdpu_write(struct rockchip_vpu_dev *vpu, u32 val, u32 reg)
{
   vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val);
   writel(val, vpu->dec_base + reg);
}
 
static inline u32 vdpu_read(struct rockchip_vpu_dev *vpu, u32 reg)
{
   u32 val = readl(vpu->dec_base + reg);
 
   vpu_debug(6, "MARK: get reg[%03d]: %08x\n", reg / 4, val);
   return val;
}
 
#endif /* ROCKCHIP_VPU_COMMON_H_ */