root/drivers/media/platform/sunxi/sun8i-rotate/sun8i-rotate.h
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Allwinner DE2 rotation driver
 *
 * Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
 */

#ifndef _SUN8I_ROTATE_H_
#define _SUN8I_ROTATE_H_

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

#include <linux/platform_device.h>

#define ROTATE_NAME             "sun8i-rotate"

#define ROTATE_GLB_CTL                  0x00
#define ROTATE_GLB_CTL_START                    BIT(31)
#define ROTATE_GLB_CTL_RESET                    BIT(30)
#define ROTATE_GLB_CTL_BURST_LEN(x)             ((x) << 16)
#define ROTATE_GLB_CTL_HFLIP                    BIT(7)
#define ROTATE_GLB_CTL_VFLIP                    BIT(6)
#define ROTATE_GLB_CTL_ROTATION(x)              ((x) << 4)
#define ROTATE_GLB_CTL_MODE(x)                  ((x) << 0)

#define ROTATE_INT                      0x04
#define ROTATE_INT_FINISH_IRQ_EN                BIT(16)
#define ROTATE_INT_FINISH_IRQ                   BIT(0)

#define ROTATE_IN_FMT                   0x20
#define ROTATE_IN_FMT_FORMAT(x)                 ((x) << 0)

#define ROTATE_IN_SIZE                  0x24
#define ROTATE_IN_PITCH0                0x30
#define ROTATE_IN_PITCH1                0x34
#define ROTATE_IN_PITCH2                0x38
#define ROTATE_IN_ADDRL0                0x40
#define ROTATE_IN_ADDRH0                0x44
#define ROTATE_IN_ADDRL1                0x48
#define ROTATE_IN_ADDRH1                0x4c
#define ROTATE_IN_ADDRL2                0x50
#define ROTATE_IN_ADDRH2                0x54
#define ROTATE_OUT_SIZE                 0x84
#define ROTATE_OUT_PITCH0               0x90
#define ROTATE_OUT_PITCH1               0x94
#define ROTATE_OUT_PITCH2               0x98
#define ROTATE_OUT_ADDRL0               0xA0
#define ROTATE_OUT_ADDRH0               0xA4
#define ROTATE_OUT_ADDRL1               0xA8
#define ROTATE_OUT_ADDRH1               0xAC
#define ROTATE_OUT_ADDRL2               0xB0
#define ROTATE_OUT_ADDRH2               0xB4

#define ROTATE_BURST_8                  0x07
#define ROTATE_BURST_16                 0x0f
#define ROTATE_BURST_32                 0x1f
#define ROTATE_BURST_64                 0x3f

#define ROTATE_MODE_COPY_ROTATE         0x01

#define ROTATE_FORMAT_ARGB32            0x00
#define ROTATE_FORMAT_ABGR32            0x01
#define ROTATE_FORMAT_RGBA32            0x02
#define ROTATE_FORMAT_BGRA32            0x03
#define ROTATE_FORMAT_XRGB32            0x04
#define ROTATE_FORMAT_XBGR32            0x05
#define ROTATE_FORMAT_RGBX32            0x06
#define ROTATE_FORMAT_BGRX32            0x07
#define ROTATE_FORMAT_RGB24             0x08
#define ROTATE_FORMAT_BGR24             0x09
#define ROTATE_FORMAT_RGB565            0x0a
#define ROTATE_FORMAT_BGR565            0x0b
#define ROTATE_FORMAT_ARGB4444          0x0c
#define ROTATE_FORMAT_ABGR4444          0x0d
#define ROTATE_FORMAT_RGBA4444          0x0e
#define ROTATE_FORMAT_BGRA4444          0x0f
#define ROTATE_FORMAT_ARGB1555          0x10
#define ROTATE_FORMAT_ABGR1555          0x11
#define ROTATE_FORMAT_RGBA5551          0x12
#define ROTATE_FORMAT_BGRA5551          0x13

#define ROTATE_FORMAT_YUYV              0x20
#define ROTATE_FORMAT_UYVY              0x21
#define ROTATE_FORMAT_YVYU              0x22
#define ROTATE_FORMAT_VYUV              0x23
#define ROTATE_FORMAT_NV61              0x24
#define ROTATE_FORMAT_NV16              0x25
#define ROTATE_FORMAT_YUV422P           0x26
#define ROTATE_FORMAT_NV21              0x28
#define ROTATE_FORMAT_NV12              0x29
#define ROTATE_FORMAT_YUV420P           0x2A

#define ROTATE_SIZE(w, h)       (((h) - 1) << 16 | ((w) - 1))

#define ROTATE_MIN_WIDTH        8U
#define ROTATE_MIN_HEIGHT       8U
#define ROTATE_MAX_WIDTH        4096U
#define ROTATE_MAX_HEIGHT       4096U

struct rotate_ctx {
        struct v4l2_fh          fh;
        struct rotate_dev       *dev;

        struct v4l2_pix_format  src_fmt;
        struct v4l2_pix_format  dst_fmt;

        struct v4l2_ctrl_handler ctrl_handler;

        u32 hflip;
        u32 vflip;
        u32 rotate;
};

struct rotate_dev {
        struct v4l2_device      v4l2_dev;
        struct video_device     vfd;
        struct device           *dev;
        struct v4l2_m2m_dev     *m2m_dev;

        /* Device file mutex */
        struct mutex            dev_mutex;

        void __iomem            *base;

        struct clk              *bus_clk;
        struct clk              *mod_clk;

        struct reset_control    *rstc;
};

#endif