Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.13-rc2 1769 lines 52 kB view raw
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");