linux/drivers/media/platform/aspeed-video.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2
   3#include <linux/atomic.h>
   4#include <linux/bitfield.h>
   5#include <linux/clk.h>
   6#include <linux/delay.h>
   7#include <linux/device.h>
   8#include <linux/dma-mapping.h>
   9#include <linux/interrupt.h>
  10#include <linux/jiffies.h>
  11#include <linux/module.h>
  12#include <linux/mutex.h>
  13#include <linux/of.h>
  14#include <linux/of_irq.h>
  15#include <linux/of_reserved_mem.h>
  16#include <linux/platform_device.h>
  17#include <linux/sched.h>
  18#include <linux/spinlock.h>
  19#include <linux/string.h>
  20#include <linux/v4l2-controls.h>
  21#include <linux/videodev2.h>
  22#include <linux/wait.h>
  23#include <linux/workqueue.h>
  24#include <media/v4l2-ctrls.h>
  25#include <media/v4l2-dev.h>
  26#include <media/v4l2-device.h>
  27#include <media/v4l2-dv-timings.h>
  28#include <media/v4l2-event.h>
  29#include <media/v4l2-ioctl.h>
  30#include <media/videobuf2-dma-contig.h>
  31
  32#define DEVICE_NAME                     "aspeed-video"
  33
  34#define ASPEED_VIDEO_JPEG_NUM_QUALITIES 12
  35#define ASPEED_VIDEO_JPEG_HEADER_SIZE   10
  36#define ASPEED_VIDEO_JPEG_QUANT_SIZE    116
  37#define ASPEED_VIDEO_JPEG_DCT_SIZE      34
  38
  39#define MAX_FRAME_RATE                  60
  40#define MAX_HEIGHT                      1200
  41#define MAX_WIDTH                       1920
  42#define MIN_HEIGHT                      480
  43#define MIN_WIDTH                       640
  44
  45#define NUM_POLARITY_CHECKS             10
  46#define INVALID_RESOLUTION_RETRIES      2
  47#define INVALID_RESOLUTION_DELAY        msecs_to_jiffies(250)
  48#define RESOLUTION_CHANGE_DELAY         msecs_to_jiffies(500)
  49#define MODE_DETECT_TIMEOUT             msecs_to_jiffies(500)
  50#define STOP_TIMEOUT                    msecs_to_jiffies(1000)
  51#define DIRECT_FETCH_THRESHOLD          0x0c0000 /* 1024 * 768 */
  52
  53#define VE_MAX_SRC_BUFFER_SIZE          0x8ca000 /* 1920 * 1200, 32bpp */
  54#define VE_JPEG_HEADER_SIZE             0x006000 /* 512 * 12 * 4 */
  55
  56#define VE_PROTECTION_KEY               0x000
  57#define  VE_PROTECTION_KEY_UNLOCK       0x1a038aa8
  58
  59#define VE_SEQ_CTRL                     0x004
  60#define  VE_SEQ_CTRL_TRIG_MODE_DET      BIT(0)
  61#define  VE_SEQ_CTRL_TRIG_CAPTURE       BIT(1)
  62#define  VE_SEQ_CTRL_FORCE_IDLE         BIT(2)
  63#define  VE_SEQ_CTRL_MULT_FRAME         BIT(3)
  64#define  VE_SEQ_CTRL_TRIG_COMP          BIT(4)
  65#define  VE_SEQ_CTRL_AUTO_COMP          BIT(5)
  66#define  VE_SEQ_CTRL_EN_WATCHDOG        BIT(7)
  67#define  VE_SEQ_CTRL_YUV420             BIT(10)
  68#define  VE_SEQ_CTRL_COMP_FMT           GENMASK(11, 10)
  69#define  VE_SEQ_CTRL_HALT               BIT(12)
  70#define  VE_SEQ_CTRL_EN_WATCHDOG_COMP   BIT(14)
  71#define  VE_SEQ_CTRL_TRIG_JPG           BIT(15)
  72#define  VE_SEQ_CTRL_CAP_BUSY           BIT(16)
  73#define  VE_SEQ_CTRL_COMP_BUSY          BIT(18)
  74
  75#ifdef CONFIG_MACH_ASPEED_G5
  76#define  VE_SEQ_CTRL_JPEG_MODE          BIT(13) /* AST2500 */
  77#else
  78#define  VE_SEQ_CTRL_JPEG_MODE          BIT(8)  /* AST2400 */
  79#endif /* CONFIG_MACH_ASPEED_G5 */
  80
  81#define VE_CTRL                         0x008
  82#define  VE_CTRL_HSYNC_POL              BIT(0)
  83#define  VE_CTRL_VSYNC_POL              BIT(1)
  84#define  VE_CTRL_SOURCE                 BIT(2)
  85#define  VE_CTRL_INT_DE                 BIT(4)
  86#define  VE_CTRL_DIRECT_FETCH           BIT(5)
  87#define  VE_CTRL_YUV                    BIT(6)
  88#define  VE_CTRL_RGB                    BIT(7)
  89#define  VE_CTRL_CAPTURE_FMT            GENMASK(7, 6)
  90#define  VE_CTRL_AUTO_OR_CURSOR         BIT(8)
  91#define  VE_CTRL_CLK_INVERSE            BIT(11)
  92#define  VE_CTRL_CLK_DELAY              GENMASK(11, 9)
  93#define  VE_CTRL_INTERLACE              BIT(14)
  94#define  VE_CTRL_HSYNC_POL_CTRL         BIT(15)
  95#define  VE_CTRL_FRC                    GENMASK(23, 16)
  96
  97#define VE_TGS_0                        0x00c
  98#define VE_TGS_1                        0x010
  99#define  VE_TGS_FIRST                   GENMASK(28, 16)
 100#define  VE_TGS_LAST                    GENMASK(12, 0)
 101
 102#define VE_SCALING_FACTOR               0x014
 103#define VE_SCALING_FILTER0              0x018
 104#define VE_SCALING_FILTER1              0x01c
 105#define VE_SCALING_FILTER2              0x020
 106#define VE_SCALING_FILTER3              0x024
 107
 108#define VE_CAP_WINDOW                   0x030
 109#define VE_COMP_WINDOW                  0x034
 110#define VE_COMP_PROC_OFFSET             0x038
 111#define VE_COMP_OFFSET                  0x03c
 112#define VE_JPEG_ADDR                    0x040
 113#define VE_SRC0_ADDR                    0x044
 114#define VE_SRC_SCANLINE_OFFSET          0x048
 115#define VE_SRC1_ADDR                    0x04c
 116#define VE_COMP_ADDR                    0x054
 117
 118#define VE_STREAM_BUF_SIZE              0x058
 119#define  VE_STREAM_BUF_SIZE_N_PACKETS   GENMASK(5, 3)
 120#define  VE_STREAM_BUF_SIZE_P_SIZE      GENMASK(2, 0)
 121
 122#define VE_COMP_CTRL                    0x060
 123#define  VE_COMP_CTRL_VQ_DCT_ONLY       BIT(0)
 124#define  VE_COMP_CTRL_VQ_4COLOR         BIT(1)
 125#define  VE_COMP_CTRL_QUANTIZE          BIT(2)
 126#define  VE_COMP_CTRL_EN_BQ             BIT(4)
 127#define  VE_COMP_CTRL_EN_CRYPTO         BIT(5)
 128#define  VE_COMP_CTRL_DCT_CHR           GENMASK(10, 6)
 129#define  VE_COMP_CTRL_DCT_LUM           GENMASK(15, 11)
 130#define  VE_COMP_CTRL_EN_HQ             BIT(16)
 131#define  VE_COMP_CTRL_RSVD              BIT(19)
 132#define  VE_COMP_CTRL_ENCODE            GENMASK(21, 20)
 133#define  VE_COMP_CTRL_HQ_DCT_CHR        GENMASK(26, 22)
 134#define  VE_COMP_CTRL_HQ_DCT_LUM        GENMASK(31, 27)
 135
 136#define VE_OFFSET_COMP_STREAM           0x078
 137
 138#define VE_SRC_LR_EDGE_DET              0x090
 139#define  VE_SRC_LR_EDGE_DET_LEFT        GENMASK(11, 0)
 140#define  VE_SRC_LR_EDGE_DET_NO_V        BIT(12)
 141#define  VE_SRC_LR_EDGE_DET_NO_H        BIT(13)
 142#define  VE_SRC_LR_EDGE_DET_NO_DISP     BIT(14)
 143#define  VE_SRC_LR_EDGE_DET_NO_CLK      BIT(15)
 144#define  VE_SRC_LR_EDGE_DET_RT_SHF      16
 145#define  VE_SRC_LR_EDGE_DET_RT          GENMASK(27, VE_SRC_LR_EDGE_DET_RT_SHF)
 146#define  VE_SRC_LR_EDGE_DET_INTERLACE   BIT(31)
 147
 148#define VE_SRC_TB_EDGE_DET              0x094
 149#define  VE_SRC_TB_EDGE_DET_TOP         GENMASK(12, 0)
 150#define  VE_SRC_TB_EDGE_DET_BOT_SHF     16
 151#define  VE_SRC_TB_EDGE_DET_BOT         GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
 152
 153#define VE_MODE_DETECT_STATUS           0x098
 154#define  VE_MODE_DETECT_H_PIXELS        GENMASK(11, 0)
 155#define  VE_MODE_DETECT_V_LINES_SHF     16
 156#define  VE_MODE_DETECT_V_LINES         GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
 157#define  VE_MODE_DETECT_STATUS_VSYNC    BIT(28)
 158#define  VE_MODE_DETECT_STATUS_HSYNC    BIT(29)
 159
 160#define VE_SYNC_STATUS                  0x09c
 161#define  VE_SYNC_STATUS_HSYNC           GENMASK(11, 0)
 162#define  VE_SYNC_STATUS_VSYNC_SHF       16
 163#define  VE_SYNC_STATUS_VSYNC           GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
 164
 165#define VE_INTERRUPT_CTRL               0x304
 166#define VE_INTERRUPT_STATUS             0x308
 167#define  VE_INTERRUPT_MODE_DETECT_WD    BIT(0)
 168#define  VE_INTERRUPT_CAPTURE_COMPLETE  BIT(1)
 169#define  VE_INTERRUPT_COMP_READY        BIT(2)
 170#define  VE_INTERRUPT_COMP_COMPLETE     BIT(3)
 171#define  VE_INTERRUPT_MODE_DETECT       BIT(4)
 172#define  VE_INTERRUPT_FRAME_COMPLETE    BIT(5)
 173#define  VE_INTERRUPT_DECODE_ERR        BIT(6)
 174#define  VE_INTERRUPT_HALT_READY        BIT(8)
 175#define  VE_INTERRUPT_HANG_WD           BIT(9)
 176#define  VE_INTERRUPT_STREAM_DESC       BIT(10)
 177#define  VE_INTERRUPT_VSYNC_DESC        BIT(11)
 178
 179#define VE_MODE_DETECT                  0x30c
 180#define VE_MEM_RESTRICT_START           0x310
 181#define VE_MEM_RESTRICT_END             0x314
 182
 183enum {
 184        VIDEO_MODE_DETECT_DONE,
 185        VIDEO_RES_CHANGE,
 186        VIDEO_RES_DETECT,
 187        VIDEO_STREAMING,
 188        VIDEO_FRAME_INPRG,
 189        VIDEO_STOPPED,
 190        VIDEO_CLOCKS_ON,
 191};
 192
 193struct aspeed_video_addr {
 194        unsigned int size;
 195        dma_addr_t dma;
 196        void *virt;
 197};
 198
 199struct aspeed_video_buffer {
 200        struct vb2_v4l2_buffer vb;
 201        struct list_head link;
 202};
 203
 204#define to_aspeed_video_buffer(x) \
 205        container_of((x), struct aspeed_video_buffer, vb)
 206
 207struct aspeed_video {
 208        void __iomem *base;
 209        struct clk *eclk;
 210        struct clk *vclk;
 211
 212        struct device *dev;
 213        struct v4l2_ctrl_handler ctrl_handler;
 214        struct v4l2_device v4l2_dev;
 215        struct v4l2_pix_format pix_fmt;
 216        struct v4l2_bt_timings active_timings;
 217        struct v4l2_bt_timings detected_timings;
 218        u32 v4l2_input_status;
 219        struct vb2_queue queue;
 220        struct video_device vdev;
 221        struct mutex video_lock;        /* v4l2 and videobuf2 lock */
 222
 223        wait_queue_head_t wait;
 224        spinlock_t lock;                /* buffer list lock */
 225        struct delayed_work res_work;
 226        struct list_head buffers;
 227        unsigned long flags;
 228        unsigned int sequence;
 229
 230        unsigned int max_compressed_size;
 231        struct aspeed_video_addr srcs[2];
 232        struct aspeed_video_addr jpeg;
 233
 234        bool yuv420;
 235        unsigned int frame_rate;
 236        unsigned int jpeg_quality;
 237
 238        unsigned int frame_bottom;
 239        unsigned int frame_left;
 240        unsigned int frame_right;
 241        unsigned int frame_top;
 242};
 243
 244#define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
 245
 246static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
 247        0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
 248        0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
 249};
 250
 251static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] = {
 252        0x081100c0, 0x00000000, 0x00110103, 0x03011102, 0xc4ff0111, 0x00001f00,
 253        0x01010501, 0x01010101, 0x00000000, 0x00000000, 0x04030201, 0x08070605,
 254        0xff0b0a09, 0x10b500c4, 0x03010200, 0x03040203, 0x04040505, 0x7d010000,
 255        0x00030201, 0x12051104, 0x06413121, 0x07615113, 0x32147122, 0x08a19181,
 256        0xc1b14223, 0xf0d15215, 0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
 257        0x35342a29, 0x39383736, 0x4544433a, 0x49484746, 0x5554534a, 0x59585756,
 258        0x6564635a, 0x69686766, 0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
 259        0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4, 0xb2aaa9a8, 0xb6b5b4b3,
 260        0xbab9b8b7, 0xc5c4c3c2, 0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
 261        0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5, 0xc4fffaf9, 0x00011f00,
 262        0x01010103, 0x01010101, 0x00000101, 0x00000000, 0x04030201, 0x08070605,
 263        0xff0b0a09, 0x11b500c4, 0x02010200, 0x04030404, 0x04040507, 0x77020100,
 264        0x03020100, 0x21050411, 0x41120631, 0x71610751, 0x81322213, 0x91421408,
 265        0x09c1b1a1, 0xf0523323, 0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
 266        0x2a292827, 0x38373635, 0x44433a39, 0x48474645, 0x54534a49, 0x58575655,
 267        0x64635a59, 0x68676665, 0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
 268        0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2, 0xa9a8a7a6, 0xb4b3b2aa,
 269        0xb8b7b6b5, 0xc3c2bab9, 0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
 270        0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5, 0xdafffaf9, 0x01030c00,
 271        0x03110200, 0x003f0011
 272};
 273
 274static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
 275                                      [ASPEED_VIDEO_JPEG_DCT_SIZE] = {
 276        { 0x0d140043, 0x0c0f110f, 0x11101114, 0x17141516, 0x1e20321e,
 277          0x3d1e1b1b, 0x32242e2b, 0x4b4c3f48, 0x44463f47, 0x61735a50,
 278          0x566c5550, 0x88644644, 0x7a766c65, 0x4d808280, 0x8c978d60,
 279          0x7e73967d, 0xdbff7b80, 0x1f014300, 0x272d2121, 0x3030582d,
 280          0x697bb958, 0xb8b9b97b, 0xb9b8a6a6, 0xb9b9b9b9, 0xb9b9b9b9,
 281          0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9,
 282          0xb9b9b9b9, 0xb9b9b9b9, 0xb9b9b9b9, 0xffb9b9b9 },
 283        { 0x0c110043, 0x0a0d0f0d, 0x0f0e0f11, 0x14111213, 0x1a1c2b1a,
 284          0x351a1818, 0x2b1f2826, 0x4142373f, 0x3c3d373e, 0x55644e46,
 285          0x4b5f4a46, 0x77573d3c, 0x6b675f58, 0x43707170, 0x7a847b54,
 286          0x6e64836d, 0xdbff6c70, 0x1b014300, 0x22271d1d, 0x2a2a4c27,
 287          0x5b6ba04c, 0xa0a0a06b, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
 288          0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0,
 289          0xa0a0a0a0, 0xa0a0a0a0, 0xa0a0a0a0, 0xffa0a0a0 },
 290        { 0x090e0043, 0x090a0c0a, 0x0c0b0c0e, 0x110e0f10, 0x15172415,
 291          0x2c151313, 0x241a211f, 0x36372e34, 0x31322e33, 0x4653413a,
 292          0x3e4e3d3a, 0x62483231, 0x58564e49, 0x385d5e5d, 0x656d6645,
 293          0x5b536c5a, 0xdbff595d, 0x16014300, 0x1c201818, 0x22223f20,
 294          0x4b58853f, 0x85858558, 0x85858585, 0x85858585, 0x85858585,
 295          0x85858585, 0x85858585, 0x85858585, 0x85858585, 0x85858585,
 296          0x85858585, 0x85858585, 0x85858585, 0xff858585 },
 297        { 0x070b0043, 0x07080a08, 0x0a090a0b, 0x0d0b0c0c, 0x11121c11,
 298          0x23110f0f, 0x1c141a19, 0x2b2b2429, 0x27282428, 0x3842332e,
 299          0x313e302e, 0x4e392827, 0x46443e3a, 0x2c4a4a4a, 0x50565137,
 300          0x48425647, 0xdbff474a, 0x12014300, 0x161a1313, 0x1c1c331a,
 301          0x3d486c33, 0x6c6c6c48, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
 302          0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c,
 303          0x6c6c6c6c, 0x6c6c6c6c, 0x6c6c6c6c, 0xff6c6c6c },
 304        { 0x06090043, 0x05060706, 0x07070709, 0x0a09090a, 0x0d0e160d,
 305          0x1b0d0c0c, 0x16101413, 0x21221c20, 0x1e1f1c20, 0x2b332824,
 306          0x26302624, 0x3d2d1f1e, 0x3735302d, 0x22393a39, 0x3f443f2b,
 307          0x38334338, 0xdbff3739, 0x0d014300, 0x11130e0e, 0x15152613,
 308          0x2d355026, 0x50505035, 0x50505050, 0x50505050, 0x50505050,
 309          0x50505050, 0x50505050, 0x50505050, 0x50505050, 0x50505050,
 310          0x50505050, 0x50505050, 0x50505050, 0xff505050 },
 311        { 0x04060043, 0x03040504, 0x05040506, 0x07060606, 0x09090f09,
 312          0x12090808, 0x0f0a0d0d, 0x16161315, 0x14151315, 0x1d221b18,
 313          0x19201918, 0x281e1514, 0x2423201e, 0x17262726, 0x2a2d2a1c,
 314          0x25222d25, 0xdbff2526, 0x09014300, 0x0b0d0a0a, 0x0e0e1a0d,
 315          0x1f25371a, 0x37373725, 0x37373737, 0x37373737, 0x37373737,
 316          0x37373737, 0x37373737, 0x37373737, 0x37373737, 0x37373737,
 317          0x37373737, 0x37373737, 0x37373737, 0xff373737 },
 318        { 0x02030043, 0x01020202, 0x02020203, 0x03030303, 0x04040704,
 319          0x09040404, 0x07050606, 0x0b0b090a, 0x0a0a090a, 0x0e110d0c,
 320          0x0c100c0c, 0x140f0a0a, 0x1211100f, 0x0b131313, 0x1516150e,
 321          0x12111612, 0xdbff1213, 0x04014300, 0x05060505, 0x07070d06,
 322          0x0f121b0d, 0x1b1b1b12, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
 323          0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b,
 324          0x1b1b1b1b, 0x1b1b1b1b, 0x1b1b1b1b, 0xff1b1b1b },
 325        { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
 326          0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
 327          0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
 328          0x0c0b0f0c, 0xdbff0c0c, 0x03014300, 0x03040303, 0x04040804,
 329          0x0a0c1208, 0x1212120c, 0x12121212, 0x12121212, 0x12121212,
 330          0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212,
 331          0x12121212, 0x12121212, 0x12121212, 0xff121212 },
 332        { 0x01020043, 0x01010101, 0x01010102, 0x02020202, 0x03030503,
 333          0x06030202, 0x05030404, 0x07070607, 0x06070607, 0x090b0908,
 334          0x080a0808, 0x0d0a0706, 0x0c0b0a0a, 0x070c0d0c, 0x0e0f0e09,
 335          0x0c0b0f0c, 0xdbff0c0c, 0x02014300, 0x03030202, 0x04040703,
 336          0x080a0f07, 0x0f0f0f0a, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
 337          0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f,
 338          0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xff0f0f0f },
 339        { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x02020302,
 340          0x04020202, 0x03020303, 0x05050405, 0x05050405, 0x07080606,
 341          0x06080606, 0x0a070505, 0x09080807, 0x05090909, 0x0a0b0a07,
 342          0x09080b09, 0xdbff0909, 0x02014300, 0x02030202, 0x03030503,
 343          0x07080c05, 0x0c0c0c08, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
 344          0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c,
 345          0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xff0c0c0c },
 346        { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010201,
 347          0x03010101, 0x02010202, 0x03030303, 0x03030303, 0x04050404,
 348          0x04050404, 0x06050303, 0x06050505, 0x03060606, 0x07070704,
 349          0x06050706, 0xdbff0606, 0x01014300, 0x01020101, 0x02020402,
 350          0x05060904, 0x09090906, 0x09090909, 0x09090909, 0x09090909,
 351          0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909,
 352          0x09090909, 0x09090909, 0x09090909, 0xff090909 },
 353        { 0x01010043, 0x01010101, 0x01010101, 0x01010101, 0x01010101,
 354          0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x02020202,
 355          0x02020202, 0x03020101, 0x03020202, 0x01030303, 0x03030302,
 356          0x03020303, 0xdbff0403, 0x01014300, 0x01010101, 0x01010201,
 357          0x03040602, 0x06060604, 0x06060606, 0x06060606, 0x06060606,
 358          0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606,
 359          0x06060606, 0x06060606, 0x06060606, 0xff060606 }
 360};
 361
 362static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
 363        .type = V4L2_DV_BT_656_1120,
 364        .bt = {
 365                .min_width = MIN_WIDTH,
 366                .max_width = MAX_WIDTH,
 367                .min_height = MIN_HEIGHT,
 368                .max_height = MAX_HEIGHT,
 369                .min_pixelclock = 6574080, /* 640 x 480 x 24Hz */
 370                .max_pixelclock = 138240000, /* 1920 x 1200 x 60Hz */
 371                .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
 372                        V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
 373                .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
 374                        V4L2_DV_BT_CAP_REDUCED_BLANKING |
 375                        V4L2_DV_BT_CAP_CUSTOM,
 376        },
 377};
 378
 379static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
 380{
 381        int i;
 382        unsigned int base;
 383
 384        for (i = 0; i < ASPEED_VIDEO_JPEG_NUM_QUALITIES; i++) {
 385                base = 256 * i; /* AST HW requires this header spacing */
 386                memcpy(&table[base], aspeed_video_jpeg_header,
 387                       sizeof(aspeed_video_jpeg_header));
 388
 389                base += ASPEED_VIDEO_JPEG_HEADER_SIZE;
 390                memcpy(&table[base], aspeed_video_jpeg_dct[i],
 391                       sizeof(aspeed_video_jpeg_dct[i]));
 392
 393                base += ASPEED_VIDEO_JPEG_DCT_SIZE;
 394                memcpy(&table[base], aspeed_video_jpeg_quant,
 395                       sizeof(aspeed_video_jpeg_quant));
 396
 397                if (yuv420)
 398                        table[base + 2] = 0x00220103;
 399        }
 400}
 401
 402static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
 403                                u32 bits)
 404{
 405        u32 t = readl(video->base + reg);
 406        u32 before = t;
 407
 408        t &= ~clear;
 409        t |= bits;
 410        writel(t, video->base + reg);
 411        dev_dbg(video->dev, "update %03x[%08x -> %08x]\n", reg, before,
 412                readl(video->base + reg));
 413}
 414
 415static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
 416{
 417        u32 t = readl(video->base + reg);
 418
 419        dev_dbg(video->dev, "read %03x[%08x]\n", reg, t);
 420        return t;
 421}
 422
 423static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
 424{
 425        writel(val, video->base + reg);
 426        dev_dbg(video->dev, "write %03x[%08x]\n", reg,
 427                readl(video->base + reg));
 428}
 429
 430static int aspeed_video_start_frame(struct aspeed_video *video)
 431{
 432        dma_addr_t addr;
 433        unsigned long flags;
 434        struct aspeed_video_buffer *buf;
 435        u32 seq_ctrl = aspeed_video_read(video, VE_SEQ_CTRL);
 436
 437        if (video->v4l2_input_status) {
 438                dev_dbg(video->dev, "No signal; don't start frame\n");
 439                return 0;
 440        }
 441
 442        if (!(seq_ctrl & VE_SEQ_CTRL_COMP_BUSY) ||
 443            !(seq_ctrl & VE_SEQ_CTRL_CAP_BUSY)) {
 444                dev_dbg(video->dev, "Engine busy; don't start frame\n");
 445                return -EBUSY;
 446        }
 447
 448        spin_lock_irqsave(&video->lock, flags);
 449        buf = list_first_entry_or_null(&video->buffers,
 450                                       struct aspeed_video_buffer, link);
 451        if (!buf) {
 452                spin_unlock_irqrestore(&video->lock, flags);
 453                dev_dbg(video->dev, "No buffers; don't start frame\n");
 454                return -EPROTO;
 455        }
 456
 457        set_bit(VIDEO_FRAME_INPRG, &video->flags);
 458        addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
 459        spin_unlock_irqrestore(&video->lock, flags);
 460
 461        aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
 462        aspeed_video_write(video, VE_COMP_OFFSET, 0);
 463        aspeed_video_write(video, VE_COMP_ADDR, addr);
 464
 465        aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
 466                            VE_INTERRUPT_COMP_COMPLETE);
 467
 468        aspeed_video_update(video, VE_SEQ_CTRL, 0,
 469                            VE_SEQ_CTRL_TRIG_CAPTURE | VE_SEQ_CTRL_TRIG_COMP);
 470
 471        return 0;
 472}
 473
 474static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
 475{
 476        /* Enable mode detect interrupts */
 477        aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
 478                            VE_INTERRUPT_MODE_DETECT);
 479
 480        /* Trigger mode detect */
 481        aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
 482}
 483
 484static void aspeed_video_off(struct aspeed_video *video)
 485{
 486        if (!test_bit(VIDEO_CLOCKS_ON, &video->flags))
 487                return;
 488
 489        /* Disable interrupts */
 490        aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
 491        aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
 492
 493        /* Turn off the relevant clocks */
 494        clk_disable(video->vclk);
 495        clk_disable(video->eclk);
 496
 497        clear_bit(VIDEO_CLOCKS_ON, &video->flags);
 498}
 499
 500static void aspeed_video_on(struct aspeed_video *video)
 501{
 502        if (test_bit(VIDEO_CLOCKS_ON, &video->flags))
 503                return;
 504
 505        /* Turn on the relevant clocks */
 506        clk_enable(video->eclk);
 507        clk_enable(video->vclk);
 508
 509        set_bit(VIDEO_CLOCKS_ON, &video->flags);
 510}
 511
 512static void aspeed_video_bufs_done(struct aspeed_video *video,
 513                                   enum vb2_buffer_state state)
 514{
 515        unsigned long flags;
 516        struct aspeed_video_buffer *buf;
 517
 518        spin_lock_irqsave(&video->lock, flags);
 519        list_for_each_entry(buf, &video->buffers, link)
 520                vb2_buffer_done(&buf->vb.vb2_buf, state);
 521        INIT_LIST_HEAD(&video->buffers);
 522        spin_unlock_irqrestore(&video->lock, flags);
 523}
 524
 525static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
 526{
 527        dev_dbg(video->dev, "Resolution changed; resetting\n");
 528
 529        set_bit(VIDEO_RES_CHANGE, &video->flags);
 530        clear_bit(VIDEO_FRAME_INPRG, &video->flags);
 531
 532        aspeed_video_off(video);
 533        aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
 534
 535        schedule_delayed_work(&video->res_work, delay);
 536}
 537
 538static irqreturn_t aspeed_video_irq(int irq, void *arg)
 539{
 540        struct aspeed_video *video = arg;
 541        u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
 542
 543        /*
 544         * Resolution changed or signal was lost; reset the engine and
 545         * re-initialize
 546         */
 547        if (sts & VE_INTERRUPT_MODE_DETECT_WD) {
 548                aspeed_video_irq_res_change(video, 0);
 549                return IRQ_HANDLED;
 550        }
 551
 552        if (sts & VE_INTERRUPT_MODE_DETECT) {
 553                if (test_bit(VIDEO_RES_DETECT, &video->flags)) {
 554                        aspeed_video_update(video, VE_INTERRUPT_CTRL,
 555                                            VE_INTERRUPT_MODE_DETECT, 0);
 556                        aspeed_video_write(video, VE_INTERRUPT_STATUS,
 557                                           VE_INTERRUPT_MODE_DETECT);
 558                        sts &= ~VE_INTERRUPT_MODE_DETECT;
 559                        set_bit(VIDEO_MODE_DETECT_DONE, &video->flags);
 560                        wake_up_interruptible_all(&video->wait);
 561                } else {
 562                        /*
 563                         * Signal acquired while NOT doing resolution
 564                         * detection; reset the engine and re-initialize
 565                         */
 566                        aspeed_video_irq_res_change(video,
 567                                                    RESOLUTION_CHANGE_DELAY);
 568                        return IRQ_HANDLED;
 569                }
 570        }
 571
 572        if (sts & VE_INTERRUPT_COMP_COMPLETE) {
 573                struct aspeed_video_buffer *buf;
 574                u32 frame_size = aspeed_video_read(video,
 575                                                   VE_OFFSET_COMP_STREAM);
 576
 577                spin_lock(&video->lock);
 578                clear_bit(VIDEO_FRAME_INPRG, &video->flags);
 579                buf = list_first_entry_or_null(&video->buffers,
 580                                               struct aspeed_video_buffer,
 581                                               link);
 582                if (buf) {
 583                        vb2_set_plane_payload(&buf->vb.vb2_buf, 0, frame_size);
 584
 585                        if (!list_is_last(&buf->link, &video->buffers)) {
 586                                buf->vb.vb2_buf.timestamp = ktime_get_ns();
 587                                buf->vb.sequence = video->sequence++;
 588                                buf->vb.field = V4L2_FIELD_NONE;
 589                                vb2_buffer_done(&buf->vb.vb2_buf,
 590                                                VB2_BUF_STATE_DONE);
 591                                list_del(&buf->link);
 592                        }
 593                }
 594                spin_unlock(&video->lock);
 595
 596                aspeed_video_update(video, VE_SEQ_CTRL,
 597                                    VE_SEQ_CTRL_TRIG_CAPTURE |
 598                                    VE_SEQ_CTRL_FORCE_IDLE |
 599                                    VE_SEQ_CTRL_TRIG_COMP, 0);
 600                aspeed_video_update(video, VE_INTERRUPT_CTRL,
 601                                    VE_INTERRUPT_COMP_COMPLETE, 0);
 602                aspeed_video_write(video, VE_INTERRUPT_STATUS,
 603                                   VE_INTERRUPT_COMP_COMPLETE);
 604                sts &= ~VE_INTERRUPT_COMP_COMPLETE;
 605                if (test_bit(VIDEO_STREAMING, &video->flags) && buf)
 606                        aspeed_video_start_frame(video);
 607        }
 608
 609        return sts ? IRQ_NONE : IRQ_HANDLED;
 610}
 611
 612static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
 613{
 614        int i;
 615        int hsync_counter = 0;
 616        int vsync_counter = 0;
 617        u32 sts;
 618
 619        for (i = 0; i < NUM_POLARITY_CHECKS; ++i) {
 620                sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
 621                if (sts & VE_MODE_DETECT_STATUS_VSYNC)
 622                        vsync_counter--;
 623                else
 624                        vsync_counter++;
 625
 626                if (sts & VE_MODE_DETECT_STATUS_HSYNC)
 627                        hsync_counter--;
 628                else
 629                        hsync_counter++;
 630        }
 631
 632        if (hsync_counter < 0 || vsync_counter < 0) {
 633                u32 ctrl;
 634
 635                if (hsync_counter < 0) {
 636                        ctrl = VE_CTRL_HSYNC_POL;
 637                        video->detected_timings.polarities &=
 638                                ~V4L2_DV_HSYNC_POS_POL;
 639                } else {
 640                        video->detected_timings.polarities |=
 641                                V4L2_DV_HSYNC_POS_POL;
 642                }
 643
 644                if (vsync_counter < 0) {
 645                        ctrl = VE_CTRL_VSYNC_POL;
 646                        video->detected_timings.polarities &=
 647                                ~V4L2_DV_VSYNC_POS_POL;
 648                } else {
 649                        video->detected_timings.polarities |=
 650                                V4L2_DV_VSYNC_POS_POL;
 651                }
 652
 653                aspeed_video_update(video, VE_CTRL, 0, ctrl);
 654        }
 655}
 656
 657static bool aspeed_video_alloc_buf(struct aspeed_video *video,
 658                                   struct aspeed_video_addr *addr,
 659                                   unsigned int size)
 660{
 661        addr->virt = dma_alloc_coherent(video->dev, size, &addr->dma,
 662                                        GFP_KERNEL);
 663        if (!addr->virt)
 664                return false;
 665
 666        addr->size = size;
 667        return true;
 668}
 669
 670static void aspeed_video_free_buf(struct aspeed_video *video,
 671                                  struct aspeed_video_addr *addr)
 672{
 673        dma_free_coherent(video->dev, addr->size, addr->virt, addr->dma);
 674        addr->size = 0;
 675        addr->dma = 0ULL;
 676        addr->virt = NULL;
 677}
 678
 679/*
 680 * Get the minimum HW-supported compression buffer size for the frame size.
 681 * Assume worst-case JPEG compression size is 1/8 raw size. This should be
 682 * plenty even for maximum quality; any worse and the engine will simply return
 683 * incomplete JPEGs.
 684 */
 685static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
 686                                              unsigned int frame_size)
 687{
 688        int i, j;
 689        u32 compression_buffer_size_reg = 0;
 690        unsigned int size;
 691        const unsigned int num_compression_packets = 4;
 692        const unsigned int compression_packet_size = 1024;
 693        const unsigned int max_compressed_size = frame_size / 2; /* 4bpp / 8 */
 694
 695        video->max_compressed_size = UINT_MAX;
 696
 697        for (i = 0; i < 6; ++i) {
 698                for (j = 0; j < 8; ++j) {
 699                        size = (num_compression_packets << i) *
 700                                (compression_packet_size << j);
 701                        if (size < max_compressed_size)
 702                                continue;
 703
 704                        if (size < video->max_compressed_size) {
 705                                compression_buffer_size_reg = (i << 3) | j;
 706                                video->max_compressed_size = size;
 707                        }
 708                }
 709        }
 710
 711        aspeed_video_write(video, VE_STREAM_BUF_SIZE,
 712                           compression_buffer_size_reg);
 713
 714        dev_dbg(video->dev, "Max compressed size: %x\n",
 715                video->max_compressed_size);
 716}
 717
 718#define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
 719
 720static void aspeed_video_get_resolution(struct aspeed_video *video)
 721{
 722        bool invalid_resolution = true;
 723        int rc;
 724        int tries = 0;
 725        u32 mds;
 726        u32 src_lr_edge;
 727        u32 src_tb_edge;
 728        u32 sync;
 729        struct v4l2_bt_timings *det = &video->detected_timings;
 730
 731        det->width = MIN_WIDTH;
 732        det->height = MIN_HEIGHT;
 733        video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
 734
 735        do {
 736                if (tries) {
 737                        set_current_state(TASK_INTERRUPTIBLE);
 738                        if (schedule_timeout(INVALID_RESOLUTION_DELAY))
 739                                return;
 740                }
 741
 742                set_bit(VIDEO_RES_DETECT, &video->flags);
 743                aspeed_video_enable_mode_detect(video);
 744
 745                rc = wait_event_interruptible_timeout(video->wait,
 746                                                      res_check(video),
 747                                                      MODE_DETECT_TIMEOUT);
 748                if (!rc) {
 749                        dev_dbg(video->dev, "Timed out; first mode detect\n");
 750                        clear_bit(VIDEO_RES_DETECT, &video->flags);
 751                        return;
 752                }
 753
 754                /* Disable mode detect in order to re-trigger */
 755                aspeed_video_update(video, VE_SEQ_CTRL,
 756                                    VE_SEQ_CTRL_TRIG_MODE_DET, 0);
 757
 758                aspeed_video_check_and_set_polarity(video);
 759
 760                aspeed_video_enable_mode_detect(video);
 761
 762                rc = wait_event_interruptible_timeout(video->wait,
 763                                                      res_check(video),
 764                                                      MODE_DETECT_TIMEOUT);
 765                clear_bit(VIDEO_RES_DETECT, &video->flags);
 766                if (!rc) {
 767                        dev_dbg(video->dev, "Timed out; second mode detect\n");
 768                        return;
 769                }
 770
 771                src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
 772                src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
 773                mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
 774                sync = aspeed_video_read(video, VE_SYNC_STATUS);
 775
 776                video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
 777                        VE_SRC_TB_EDGE_DET_BOT_SHF;
 778                video->frame_top = src_tb_edge & VE_SRC_TB_EDGE_DET_TOP;
 779                det->vfrontporch = video->frame_top;
 780                det->vbackporch = ((mds & VE_MODE_DETECT_V_LINES) >>
 781                        VE_MODE_DETECT_V_LINES_SHF) - video->frame_bottom;
 782                det->vsync = (sync & VE_SYNC_STATUS_VSYNC) >>
 783                        VE_SYNC_STATUS_VSYNC_SHF;
 784                if (video->frame_top > video->frame_bottom)
 785                        continue;
 786
 787                video->frame_right = (src_lr_edge & VE_SRC_LR_EDGE_DET_RT) >>
 788                        VE_SRC_LR_EDGE_DET_RT_SHF;
 789                video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
 790                det->hfrontporch = video->frame_left;
 791                det->hbackporch = (mds & VE_MODE_DETECT_H_PIXELS) -
 792                        video->frame_right;
 793                det->hsync = sync & VE_SYNC_STATUS_HSYNC;
 794                if (video->frame_left > video->frame_right)
 795                        continue;
 796
 797                invalid_resolution = false;
 798        } while (invalid_resolution && (tries++ < INVALID_RESOLUTION_RETRIES));
 799
 800        if (invalid_resolution) {
 801                dev_dbg(video->dev, "Invalid resolution detected\n");
 802                return;
 803        }
 804
 805        det->height = (video->frame_bottom - video->frame_top) + 1;
 806        det->width = (video->frame_right - video->frame_left) + 1;
 807        video->v4l2_input_status = 0;
 808
 809        /*
 810         * Enable mode-detect watchdog, resolution-change watchdog and
 811         * automatic compression after frame capture.
 812         */
 813        aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
 814                            VE_INTERRUPT_MODE_DETECT_WD);
 815        aspeed_video_update(video, VE_SEQ_CTRL, 0,
 816                            VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
 817
 818        dev_dbg(video->dev, "Got resolution: %dx%d\n", det->width,
 819                det->height);
 820}
 821
 822static void aspeed_video_set_resolution(struct aspeed_video *video)
 823{
 824        struct v4l2_bt_timings *act = &video->active_timings;
 825        unsigned int size = act->width * act->height;
 826
 827        /* Set capture/compression frame sizes */
 828        aspeed_video_calc_compressed_size(video, size);
 829
 830        if (video->active_timings.width == 1680) {
 831                /*
 832                 * This is a workaround to fix a silicon bug on A1 and A2
 833                 * revisions. Since it doesn't break capturing operation of
 834                 * other revisions, use it for all revisions without checking
 835                 * the revision ID. It picked 1728 which is a very next
 836                 * 64-pixels aligned value to 1680 to minimize memory bandwidth
 837                 * and to get better access speed from video engine.
 838                 */
 839                aspeed_video_write(video, VE_CAP_WINDOW,
 840                                   1728 << 16 | act->height);
 841                size += (1728 - 1680) * video->active_timings.height;
 842        } else {
 843                aspeed_video_write(video, VE_CAP_WINDOW,
 844                                   act->width << 16 | act->height);
 845        }
 846        aspeed_video_write(video, VE_COMP_WINDOW,
 847                           act->width << 16 | act->height);
 848        aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4);
 849
 850        /* Don't use direct mode below 1024 x 768 (irqs don't fire) */
 851        if (size < DIRECT_FETCH_THRESHOLD) {
 852                aspeed_video_write(video, VE_TGS_0,
 853                                   FIELD_PREP(VE_TGS_FIRST,
 854                                              video->frame_left - 1) |
 855                                   FIELD_PREP(VE_TGS_LAST,
 856                                              video->frame_right));
 857                aspeed_video_write(video, VE_TGS_1,
 858                                   FIELD_PREP(VE_TGS_FIRST, video->frame_top) |
 859                                   FIELD_PREP(VE_TGS_LAST,
 860                                              video->frame_bottom + 1));
 861                aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_INT_DE);
 862        } else {
 863                aspeed_video_update(video, VE_CTRL, 0, VE_CTRL_DIRECT_FETCH);
 864        }
 865
 866        size *= 4;
 867
 868        if (size != video->srcs[0].size) {
 869                if (video->srcs[0].size)
 870                        aspeed_video_free_buf(video, &video->srcs[0]);
 871                if (video->srcs[1].size)
 872                        aspeed_video_free_buf(video, &video->srcs[1]);
 873
 874                if (!aspeed_video_alloc_buf(video, &video->srcs[0], size))
 875                        goto err_mem;
 876                if (!aspeed_video_alloc_buf(video, &video->srcs[1], size))
 877                        goto err_mem;
 878
 879                aspeed_video_write(video, VE_SRC0_ADDR, video->srcs[0].dma);
 880                aspeed_video_write(video, VE_SRC1_ADDR, video->srcs[1].dma);
 881        }
 882
 883        return;
 884
 885err_mem:
 886        dev_err(video->dev, "Failed to allocate source buffers\n");
 887
 888        if (video->srcs[0].size)
 889                aspeed_video_free_buf(video, &video->srcs[0]);
 890}
 891
 892static void aspeed_video_init_regs(struct aspeed_video *video)
 893{
 894        u32 comp_ctrl = VE_COMP_CTRL_RSVD |
 895                FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
 896                FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
 897        u32 ctrl = VE_CTRL_AUTO_OR_CURSOR;
 898        u32 seq_ctrl = VE_SEQ_CTRL_JPEG_MODE;
 899
 900        if (video->frame_rate)
 901                ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
 902
 903        if (video->yuv420)
 904                seq_ctrl |= VE_SEQ_CTRL_YUV420;
 905
 906        /* Unlock VE registers */
 907        aspeed_video_write(video, VE_PROTECTION_KEY, VE_PROTECTION_KEY_UNLOCK);
 908
 909        /* Disable interrupts */
 910        aspeed_video_write(video, VE_INTERRUPT_CTRL, 0);
 911        aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff);
 912
 913        /* Clear the offset */
 914        aspeed_video_write(video, VE_COMP_PROC_OFFSET, 0);
 915        aspeed_video_write(video, VE_COMP_OFFSET, 0);
 916
 917        aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
 918
 919        /* Set control registers */
 920        aspeed_video_write(video, VE_SEQ_CTRL, seq_ctrl);
 921        aspeed_video_write(video, VE_CTRL, ctrl);
 922        aspeed_video_write(video, VE_COMP_CTRL, comp_ctrl);
 923
 924        /* Don't downscale */
 925        aspeed_video_write(video, VE_SCALING_FACTOR, 0x10001000);
 926        aspeed_video_write(video, VE_SCALING_FILTER0, 0x00200000);
 927        aspeed_video_write(video, VE_SCALING_FILTER1, 0x00200000);
 928        aspeed_video_write(video, VE_SCALING_FILTER2, 0x00200000);
 929        aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
 930
 931        /* Set mode detection defaults */
 932        aspeed_video_write(video, VE_MODE_DETECT, 0x22666500);
 933}
 934
 935static void aspeed_video_start(struct aspeed_video *video)
 936{
 937        aspeed_video_on(video);
 938
 939        aspeed_video_init_regs(video);
 940
 941        /* Resolution set to 640x480 if no signal found */
 942        aspeed_video_get_resolution(video);
 943
 944        /* Set timings since the device is being opened for the first time */
 945        video->active_timings = video->detected_timings;
 946        aspeed_video_set_resolution(video);
 947
 948        video->pix_fmt.width = video->active_timings.width;
 949        video->pix_fmt.height = video->active_timings.height;
 950        video->pix_fmt.sizeimage = video->max_compressed_size;
 951}
 952
 953static void aspeed_video_stop(struct aspeed_video *video)
 954{
 955        set_bit(VIDEO_STOPPED, &video->flags);
 956        cancel_delayed_work_sync(&video->res_work);
 957
 958        aspeed_video_off(video);
 959
 960        if (video->srcs[0].size)
 961                aspeed_video_free_buf(video, &video->srcs[0]);
 962
 963        if (video->srcs[1].size)
 964                aspeed_video_free_buf(video, &video->srcs[1]);
 965
 966        video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
 967        video->flags = 0;
 968}
 969
 970static int aspeed_video_querycap(struct file *file, void *fh,
 971                                 struct v4l2_capability *cap)
 972{
 973        strscpy(cap->driver, DEVICE_NAME, sizeof(cap->driver));
 974        strscpy(cap->card, "Aspeed Video Engine", sizeof(cap->card));
 975        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 976                 DEVICE_NAME);
 977
 978        return 0;
 979}
 980
 981static int aspeed_video_enum_format(struct file *file, void *fh,
 982                                    struct v4l2_fmtdesc *f)
 983{
 984        if (f->index)
 985                return -EINVAL;
 986
 987        f->pixelformat = V4L2_PIX_FMT_JPEG;
 988
 989        return 0;
 990}
 991
 992static int aspeed_video_get_format(struct file *file, void *fh,
 993                                   struct v4l2_format *f)
 994{
 995        struct aspeed_video *video = video_drvdata(file);
 996
 997        f->fmt.pix = video->pix_fmt;
 998
 999        return 0;
1000}
1001
1002static int aspeed_video_enum_input(struct file *file, void *fh,
1003                                   struct v4l2_input *inp)
1004{
1005        struct aspeed_video *video = video_drvdata(file);
1006
1007        if (inp->index)
1008                return -EINVAL;
1009
1010        strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
1011        inp->type = V4L2_INPUT_TYPE_CAMERA;
1012        inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
1013        inp->status = video->v4l2_input_status;
1014
1015        return 0;
1016}
1017
1018static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
1019{
1020        *i = 0;
1021
1022        return 0;
1023}
1024
1025static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
1026{
1027        if (i)
1028                return -EINVAL;
1029
1030        return 0;
1031}
1032
1033static int aspeed_video_get_parm(struct file *file, void *fh,
1034                                 struct v4l2_streamparm *a)
1035{
1036        struct aspeed_video *video = video_drvdata(file);
1037
1038        a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1039        a->parm.capture.readbuffers = 3;
1040        a->parm.capture.timeperframe.numerator = 1;
1041        if (!video->frame_rate)
1042                a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1043        else
1044                a->parm.capture.timeperframe.denominator = video->frame_rate;
1045
1046        return 0;
1047}
1048
1049static int aspeed_video_set_parm(struct file *file, void *fh,
1050                                 struct v4l2_streamparm *a)
1051{
1052        unsigned int frame_rate = 0;
1053        struct aspeed_video *video = video_drvdata(file);
1054
1055        a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
1056        a->parm.capture.readbuffers = 3;
1057
1058        if (a->parm.capture.timeperframe.numerator)
1059                frame_rate = a->parm.capture.timeperframe.denominator /
1060                        a->parm.capture.timeperframe.numerator;
1061
1062        if (!frame_rate || frame_rate > MAX_FRAME_RATE) {
1063                frame_rate = 0;
1064                a->parm.capture.timeperframe.denominator = MAX_FRAME_RATE;
1065                a->parm.capture.timeperframe.numerator = 1;
1066        }
1067
1068        if (video->frame_rate != frame_rate) {
1069                video->frame_rate = frame_rate;
1070                aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC,
1071                                    FIELD_PREP(VE_CTRL_FRC, frame_rate));
1072        }
1073
1074        return 0;
1075}
1076
1077static int aspeed_video_enum_framesizes(struct file *file, void *fh,
1078                                        struct v4l2_frmsizeenum *fsize)
1079{
1080        struct aspeed_video *video = video_drvdata(file);
1081
1082        if (fsize->index)
1083                return -EINVAL;
1084
1085        if (fsize->pixel_format != V4L2_PIX_FMT_JPEG)
1086                return -EINVAL;
1087
1088        fsize->discrete.width = video->pix_fmt.width;
1089        fsize->discrete.height = video->pix_fmt.height;
1090        fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1091
1092        return 0;
1093}
1094
1095static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
1096                                            struct v4l2_frmivalenum *fival)
1097{
1098        struct aspeed_video *video = video_drvdata(file);
1099
1100        if (fival->index)
1101                return -EINVAL;
1102
1103        if (fival->width != video->detected_timings.width ||
1104            fival->height != video->detected_timings.height)
1105                return -EINVAL;
1106
1107        if (fival->pixel_format != V4L2_PIX_FMT_JPEG)
1108                return -EINVAL;
1109
1110        fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1111
1112        fival->stepwise.min.denominator = MAX_FRAME_RATE;
1113        fival->stepwise.min.numerator = 1;
1114        fival->stepwise.max.denominator = 1;
1115        fival->stepwise.max.numerator = 1;
1116        fival->stepwise.step = fival->stepwise.max;
1117
1118        return 0;
1119}
1120
1121static int aspeed_video_set_dv_timings(struct file *file, void *fh,
1122                                       struct v4l2_dv_timings *timings)
1123{
1124        struct aspeed_video *video = video_drvdata(file);
1125
1126        if (timings->bt.width == video->active_timings.width &&
1127            timings->bt.height == video->active_timings.height)
1128                return 0;
1129
1130        if (vb2_is_busy(&video->queue))
1131                return -EBUSY;
1132
1133        video->active_timings = timings->bt;
1134
1135        aspeed_video_set_resolution(video);
1136
1137        video->pix_fmt.width = timings->bt.width;
1138        video->pix_fmt.height = timings->bt.height;
1139        video->pix_fmt.sizeimage = video->max_compressed_size;
1140
1141        timings->type = V4L2_DV_BT_656_1120;
1142
1143        return 0;
1144}
1145
1146static int aspeed_video_get_dv_timings(struct file *file, void *fh,
1147                                       struct v4l2_dv_timings *timings)
1148{
1149        struct aspeed_video *video = video_drvdata(file);
1150
1151        timings->type = V4L2_DV_BT_656_1120;
1152        timings->bt = video->active_timings;
1153
1154        return 0;
1155}
1156
1157static int aspeed_video_query_dv_timings(struct file *file, void *fh,
1158                                         struct v4l2_dv_timings *timings)
1159{
1160        int rc;
1161        struct aspeed_video *video = video_drvdata(file);
1162
1163        /*
1164         * This blocks only if the driver is currently in the process of
1165         * detecting a new resolution; in the event of no signal or timeout
1166         * this function is woken up.
1167         */
1168        if (file->f_flags & O_NONBLOCK) {
1169                if (test_bit(VIDEO_RES_CHANGE, &video->flags))
1170                        return -EAGAIN;
1171        } else {
1172                rc = wait_event_interruptible(video->wait,
1173                                              !test_bit(VIDEO_RES_CHANGE,
1174                                                        &video->flags));
1175                if (rc)
1176                        return -EINTR;
1177        }
1178
1179        timings->type = V4L2_DV_BT_656_1120;
1180        timings->bt = video->detected_timings;
1181
1182        return video->v4l2_input_status ? -ENOLINK : 0;
1183}
1184
1185static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
1186                                        struct v4l2_enum_dv_timings *timings)
1187{
1188        return v4l2_enum_dv_timings_cap(timings, &aspeed_video_timings_cap,
1189                                        NULL, NULL);
1190}
1191
1192static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
1193                                       struct v4l2_dv_timings_cap *cap)
1194{
1195        *cap = aspeed_video_timings_cap;
1196
1197        return 0;
1198}
1199
1200static int aspeed_video_sub_event(struct v4l2_fh *fh,
1201                                  const struct v4l2_event_subscription *sub)
1202{
1203        switch (sub->type) {
1204        case V4L2_EVENT_SOURCE_CHANGE:
1205                return v4l2_src_change_event_subscribe(fh, sub);
1206        }
1207
1208        return v4l2_ctrl_subscribe_event(fh, sub);
1209}
1210
1211static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops = {
1212        .vidioc_querycap = aspeed_video_querycap,
1213
1214        .vidioc_enum_fmt_vid_cap = aspeed_video_enum_format,
1215        .vidioc_g_fmt_vid_cap = aspeed_video_get_format,
1216        .vidioc_s_fmt_vid_cap = aspeed_video_get_format,
1217        .vidioc_try_fmt_vid_cap = aspeed_video_get_format,
1218
1219        .vidioc_reqbufs = vb2_ioctl_reqbufs,
1220        .vidioc_querybuf = vb2_ioctl_querybuf,
1221        .vidioc_qbuf = vb2_ioctl_qbuf,
1222        .vidioc_expbuf = vb2_ioctl_expbuf,
1223        .vidioc_dqbuf = vb2_ioctl_dqbuf,
1224        .vidioc_create_bufs = vb2_ioctl_create_bufs,
1225        .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1226        .vidioc_streamon = vb2_ioctl_streamon,
1227        .vidioc_streamoff = vb2_ioctl_streamoff,
1228
1229        .vidioc_enum_input = aspeed_video_enum_input,
1230        .vidioc_g_input = aspeed_video_get_input,
1231        .vidioc_s_input = aspeed_video_set_input,
1232
1233        .vidioc_g_parm = aspeed_video_get_parm,
1234        .vidioc_s_parm = aspeed_video_set_parm,
1235        .vidioc_enum_framesizes = aspeed_video_enum_framesizes,
1236        .vidioc_enum_frameintervals = aspeed_video_enum_frameintervals,
1237
1238        .vidioc_s_dv_timings = aspeed_video_set_dv_timings,
1239        .vidioc_g_dv_timings = aspeed_video_get_dv_timings,
1240        .vidioc_query_dv_timings = aspeed_video_query_dv_timings,
1241        .vidioc_enum_dv_timings = aspeed_video_enum_dv_timings,
1242        .vidioc_dv_timings_cap = aspeed_video_dv_timings_cap,
1243
1244        .vidioc_subscribe_event = aspeed_video_sub_event,
1245        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1246};
1247
1248static void aspeed_video_update_jpeg_quality(struct aspeed_video *video)
1249{
1250        u32 comp_ctrl = FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
1251                FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
1252
1253        aspeed_video_update(video, VE_COMP_CTRL,
1254                            VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR,
1255                            comp_ctrl);
1256}
1257
1258static void aspeed_video_update_subsampling(struct aspeed_video *video)
1259{
1260        if (video->jpeg.virt)
1261                aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
1262
1263        if (video->yuv420)
1264                aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_YUV420);
1265        else
1266                aspeed_video_update(video, VE_SEQ_CTRL, VE_SEQ_CTRL_YUV420, 0);
1267}
1268
1269static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
1270{
1271        struct aspeed_video *video = container_of(ctrl->handler,
1272                                                  struct aspeed_video,
1273                                                  ctrl_handler);
1274
1275        switch (ctrl->id) {
1276        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1277                video->jpeg_quality = ctrl->val;
1278                aspeed_video_update_jpeg_quality(video);
1279                break;
1280        case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1281                if (ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
1282                        video->yuv420 = true;
1283                        aspeed_video_update_subsampling(video);
1284                } else {
1285                        video->yuv420 = false;
1286                        aspeed_video_update_subsampling(video);
1287                }
1288                break;
1289        default:
1290                return -EINVAL;
1291        }
1292
1293        return 0;
1294}
1295
1296static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops = {
1297        .s_ctrl = aspeed_video_set_ctrl,
1298};
1299
1300static void aspeed_video_resolution_work(struct work_struct *work)
1301{
1302        struct delayed_work *dwork = to_delayed_work(work);
1303        struct aspeed_video *video = container_of(dwork, struct aspeed_video,
1304                                                  res_work);
1305        u32 input_status = video->v4l2_input_status;
1306
1307        aspeed_video_on(video);
1308
1309        /* Exit early in case no clients remain */
1310        if (test_bit(VIDEO_STOPPED, &video->flags))
1311                goto done;
1312
1313        aspeed_video_init_regs(video);
1314
1315        aspeed_video_get_resolution(video);
1316
1317        if (video->detected_timings.width != video->active_timings.width ||
1318            video->detected_timings.height != video->active_timings.height ||
1319            input_status != video->v4l2_input_status) {
1320                static const struct v4l2_event ev = {
1321                        .type = V4L2_EVENT_SOURCE_CHANGE,
1322                        .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1323                };
1324
1325                v4l2_event_queue(&video->vdev, &ev);
1326        } else if (test_bit(VIDEO_STREAMING, &video->flags)) {
1327                /* No resolution change so just restart streaming */
1328                aspeed_video_start_frame(video);
1329        }
1330
1331done:
1332        clear_bit(VIDEO_RES_CHANGE, &video->flags);
1333        wake_up_interruptible_all(&video->wait);
1334}
1335
1336static int aspeed_video_open(struct file *file)
1337{
1338        int rc;
1339        struct aspeed_video *video = video_drvdata(file);
1340
1341        mutex_lock(&video->video_lock);
1342
1343        rc = v4l2_fh_open(file);
1344        if (rc) {
1345                mutex_unlock(&video->video_lock);
1346                return rc;
1347        }
1348
1349        if (v4l2_fh_is_singular_file(file))
1350                aspeed_video_start(video);
1351
1352        mutex_unlock(&video->video_lock);
1353
1354        return 0;
1355}
1356
1357static int aspeed_video_release(struct file *file)
1358{
1359        int rc;
1360        struct aspeed_video *video = video_drvdata(file);
1361
1362        mutex_lock(&video->video_lock);
1363
1364        if (v4l2_fh_is_singular_file(file))
1365                aspeed_video_stop(video);
1366
1367        rc = _vb2_fop_release(file, NULL);
1368
1369        mutex_unlock(&video->video_lock);
1370
1371        return rc;
1372}
1373
1374static const struct v4l2_file_operations aspeed_video_v4l2_fops = {
1375        .owner = THIS_MODULE,
1376        .read = vb2_fop_read,
1377        .poll = vb2_fop_poll,
1378        .unlocked_ioctl = video_ioctl2,
1379        .mmap = vb2_fop_mmap,
1380        .open = aspeed_video_open,
1381        .release = aspeed_video_release,
1382};
1383
1384static int aspeed_video_queue_setup(struct vb2_queue *q,
1385                                    unsigned int *num_buffers,
1386                                    unsigned int *num_planes,
1387                                    unsigned int sizes[],
1388                                    struct device *alloc_devs[])
1389{
1390        struct aspeed_video *video = vb2_get_drv_priv(q);
1391
1392        if (*num_planes) {
1393                if (sizes[0] < video->max_compressed_size)
1394                        return -EINVAL;
1395
1396                return 0;
1397        }
1398
1399        *num_planes = 1;
1400        sizes[0] = video->max_compressed_size;
1401
1402        return 0;
1403}
1404
1405static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
1406{
1407        struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1408
1409        if (vb2_plane_size(vb, 0) < video->max_compressed_size)
1410                return -EINVAL;
1411
1412        return 0;
1413}
1414
1415static int aspeed_video_start_streaming(struct vb2_queue *q,
1416                                        unsigned int count)
1417{
1418        int rc;
1419        struct aspeed_video *video = vb2_get_drv_priv(q);
1420
1421        video->sequence = 0;
1422
1423        rc = aspeed_video_start_frame(video);
1424        if (rc) {
1425                aspeed_video_bufs_done(video, VB2_BUF_STATE_QUEUED);
1426                return rc;
1427        }
1428
1429        set_bit(VIDEO_STREAMING, &video->flags);
1430        return 0;
1431}
1432
1433static void aspeed_video_stop_streaming(struct vb2_queue *q)
1434{
1435        int rc;
1436        struct aspeed_video *video = vb2_get_drv_priv(q);
1437
1438        clear_bit(VIDEO_STREAMING, &video->flags);
1439
1440        rc = wait_event_timeout(video->wait,
1441                                !test_bit(VIDEO_FRAME_INPRG, &video->flags),
1442                                STOP_TIMEOUT);
1443        if (!rc) {
1444                dev_dbg(video->dev, "Timed out when stopping streaming\n");
1445
1446                /*
1447                 * Need to force stop any DMA and try and get HW into a good
1448                 * state for future calls to start streaming again.
1449                 */
1450                aspeed_video_off(video);
1451                aspeed_video_on(video);
1452
1453                aspeed_video_init_regs(video);
1454
1455                aspeed_video_get_resolution(video);
1456        }
1457
1458        aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
1459}
1460
1461static void aspeed_video_buf_queue(struct vb2_buffer *vb)
1462{
1463        bool empty;
1464        struct aspeed_video *video = vb2_get_drv_priv(vb->vb2_queue);
1465        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1466        struct aspeed_video_buffer *avb = to_aspeed_video_buffer(vbuf);
1467        unsigned long flags;
1468
1469        spin_lock_irqsave(&video->lock, flags);
1470        empty = list_empty(&video->buffers);
1471        list_add_tail(&avb->link, &video->buffers);
1472        spin_unlock_irqrestore(&video->lock, flags);
1473
1474        if (test_bit(VIDEO_STREAMING, &video->flags) &&
1475            !test_bit(VIDEO_FRAME_INPRG, &video->flags) && empty)
1476                aspeed_video_start_frame(video);
1477}
1478
1479static const struct vb2_ops aspeed_video_vb2_ops = {
1480        .queue_setup = aspeed_video_queue_setup,
1481        .wait_prepare = vb2_ops_wait_prepare,
1482        .wait_finish = vb2_ops_wait_finish,
1483        .buf_prepare = aspeed_video_buf_prepare,
1484        .start_streaming = aspeed_video_start_streaming,
1485        .stop_streaming = aspeed_video_stop_streaming,
1486        .buf_queue =  aspeed_video_buf_queue,
1487};
1488
1489static int aspeed_video_setup_video(struct aspeed_video *video)
1490{
1491        const u64 mask = ~(BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_444) |
1492                           BIT(V4L2_JPEG_CHROMA_SUBSAMPLING_420));
1493        struct v4l2_device *v4l2_dev = &video->v4l2_dev;
1494        struct vb2_queue *vbq = &video->queue;
1495        struct video_device *vdev = &video->vdev;
1496        int rc;
1497
1498        video->pix_fmt.pixelformat = V4L2_PIX_FMT_JPEG;
1499        video->pix_fmt.field = V4L2_FIELD_NONE;
1500        video->pix_fmt.colorspace = V4L2_COLORSPACE_SRGB;
1501        video->pix_fmt.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1502        video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
1503
1504        rc = v4l2_device_register(video->dev, v4l2_dev);
1505        if (rc) {
1506                dev_err(video->dev, "Failed to register v4l2 device\n");
1507                return rc;
1508        }
1509
1510        v4l2_ctrl_handler_init(&video->ctrl_handler, 2);
1511        v4l2_ctrl_new_std(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1512                          V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
1513                          ASPEED_VIDEO_JPEG_NUM_QUALITIES - 1, 1, 0);
1514        v4l2_ctrl_new_std_menu(&video->ctrl_handler, &aspeed_video_ctrl_ops,
1515                               V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1516                               V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask,
1517                               V4L2_JPEG_CHROMA_SUBSAMPLING_444);
1518
1519        if (video->ctrl_handler.error) {
1520                v4l2_ctrl_handler_free(&video->ctrl_handler);
1521                v4l2_device_unregister(v4l2_dev);
1522
1523                dev_err(video->dev, "Failed to init controls: %d\n",
1524                        video->ctrl_handler.error);
1525                return rc;
1526        }
1527
1528        v4l2_dev->ctrl_handler = &video->ctrl_handler;
1529
1530        vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1531        vbq->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1532        vbq->dev = v4l2_dev->dev;
1533        vbq->lock = &video->video_lock;
1534        vbq->ops = &aspeed_video_vb2_ops;
1535        vbq->mem_ops = &vb2_dma_contig_memops;
1536        vbq->drv_priv = video;
1537        vbq->buf_struct_size = sizeof(struct aspeed_video_buffer);
1538        vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1539        vbq->min_buffers_needed = 3;
1540
1541        rc = vb2_queue_init(vbq);
1542        if (rc) {
1543                v4l2_ctrl_handler_free(&video->ctrl_handler);
1544                v4l2_device_unregister(v4l2_dev);
1545
1546                dev_err(video->dev, "Failed to init vb2 queue\n");
1547                return rc;
1548        }
1549
1550        vdev->queue = vbq;
1551        vdev->fops = &aspeed_video_v4l2_fops;
1552        vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1553                V4L2_CAP_STREAMING;
1554        vdev->v4l2_dev = v4l2_dev;
1555        strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
1556        vdev->vfl_type = VFL_TYPE_GRABBER;
1557        vdev->vfl_dir = VFL_DIR_RX;
1558        vdev->release = video_device_release_empty;
1559        vdev->ioctl_ops = &aspeed_video_ioctl_ops;
1560        vdev->lock = &video->video_lock;
1561
1562        video_set_drvdata(vdev, video);
1563        rc = video_register_device(vdev, VFL_TYPE_GRABBER, 0);
1564        if (rc) {
1565                vb2_queue_release(vbq);
1566                v4l2_ctrl_handler_free(&video->ctrl_handler);
1567                v4l2_device_unregister(v4l2_dev);
1568
1569                dev_err(video->dev, "Failed to register video device\n");
1570                return rc;
1571        }
1572
1573        return 0;
1574}
1575
1576static int aspeed_video_init(struct aspeed_video *video)
1577{
1578        int irq;
1579        int rc;
1580        struct device *dev = video->dev;
1581
1582        irq = irq_of_parse_and_map(dev->of_node, 0);
1583        if (!irq) {
1584                dev_err(dev, "Unable to find IRQ\n");
1585                return -ENODEV;
1586        }
1587
1588        rc = devm_request_threaded_irq(dev, irq, NULL, aspeed_video_irq,
1589                                       IRQF_ONESHOT, DEVICE_NAME, video);
1590        if (rc < 0) {
1591                dev_err(dev, "Unable to request IRQ %d\n", irq);
1592                return rc;
1593        }
1594
1595        video->eclk = devm_clk_get(dev, "eclk");
1596        if (IS_ERR(video->eclk)) {
1597                dev_err(dev, "Unable to get ECLK\n");
1598                return PTR_ERR(video->eclk);
1599        }
1600
1601        rc = clk_prepare(video->eclk);
1602        if (rc)
1603                return rc;
1604
1605        video->vclk = devm_clk_get(dev, "vclk");
1606        if (IS_ERR(video->vclk)) {
1607                dev_err(dev, "Unable to get VCLK\n");
1608                rc = PTR_ERR(video->vclk);
1609                goto err_unprepare_eclk;
1610        }
1611
1612        rc = clk_prepare(video->vclk);
1613        if (rc)
1614                goto err_unprepare_eclk;
1615
1616        of_reserved_mem_device_init(dev);
1617
1618        rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
1619        if (rc) {
1620                dev_err(dev, "Failed to set DMA mask\n");
1621                goto err_release_reserved_mem;
1622        }
1623
1624        if (!aspeed_video_alloc_buf(video, &video->jpeg,
1625                                    VE_JPEG_HEADER_SIZE)) {
1626                dev_err(dev, "Failed to allocate DMA for JPEG header\n");
1627                goto err_release_reserved_mem;
1628        }
1629
1630        aspeed_video_init_jpeg_table(video->jpeg.virt, video->yuv420);
1631
1632        return 0;
1633
1634err_release_reserved_mem:
1635        of_reserved_mem_device_release(dev);
1636        clk_unprepare(video->vclk);
1637err_unprepare_eclk:
1638        clk_unprepare(video->eclk);
1639
1640        return rc;
1641}
1642
1643static int aspeed_video_probe(struct platform_device *pdev)
1644{
1645        int rc;
1646        struct resource *res;
1647        struct aspeed_video *video = kzalloc(sizeof(*video), GFP_KERNEL);
1648
1649        if (!video)
1650                return -ENOMEM;
1651
1652        video->frame_rate = 30;
1653        video->dev = &pdev->dev;
1654        spin_lock_init(&video->lock);
1655        mutex_init(&video->video_lock);
1656        init_waitqueue_head(&video->wait);
1657        INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
1658        INIT_LIST_HEAD(&video->buffers);
1659
1660        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1661
1662        video->base = devm_ioremap_resource(video->dev, res);
1663
1664        if (IS_ERR(video->base))
1665                return PTR_ERR(video->base);
1666
1667        rc = aspeed_video_init(video);
1668        if (rc)
1669                return rc;
1670
1671        rc = aspeed_video_setup_video(video);
1672        if (rc)
1673                return rc;
1674
1675        return 0;
1676}
1677
1678static int aspeed_video_remove(struct platform_device *pdev)
1679{
1680        struct device *dev = &pdev->dev;
1681        struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1682        struct aspeed_video *video = to_aspeed_video(v4l2_dev);
1683
1684        aspeed_video_off(video);
1685
1686        clk_unprepare(video->vclk);
1687        clk_unprepare(video->eclk);
1688
1689        video_unregister_device(&video->vdev);
1690
1691        vb2_queue_release(&video->queue);
1692
1693        v4l2_ctrl_handler_free(&video->ctrl_handler);
1694
1695        v4l2_device_unregister(v4l2_dev);
1696
1697        dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt,
1698                          video->jpeg.dma);
1699
1700        of_reserved_mem_device_release(dev);
1701
1702        return 0;
1703}
1704
1705static const struct of_device_id aspeed_video_of_match[] = {
1706        { .compatible = "aspeed,ast2400-video-engine" },
1707        { .compatible = "aspeed,ast2500-video-engine" },
1708        {}
1709};
1710MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1711
1712static struct platform_driver aspeed_video_driver = {
1713        .driver = {
1714                .name = DEVICE_NAME,
1715                .of_match_table = aspeed_video_of_match,
1716        },
1717        .probe = aspeed_video_probe,
1718        .remove = aspeed_video_remove,
1719};
1720
1721module_platform_driver(aspeed_video_driver);
1722
1723MODULE_DESCRIPTION("ASPEED Video Engine Driver");
1724MODULE_AUTHOR("Eddie James");
1725MODULE_LICENSE("GPL v2");
1726