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