1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Allwinner sun8i deinterlacer with scaler driver 4 * 5 * Copyright (C) 2019 Jernej Skrabec <jernej.skrabec@siol.net> 6 * 7 * Based on vim2m driver. 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/interrupt.h> 12 #include <linux/io.h> 13 #include <linux/iopoll.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/of_device.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/reset.h> 19 20 #include <media/v4l2-device.h> 21 #include <media/v4l2-ioctl.h> 22 #include <media/v4l2-mem2mem.h> 23 24 #include "sun8i-di.h" 25 26 #define FLAG_SIZE (DEINTERLACE_MAX_WIDTH * DEINTERLACE_MAX_HEIGHT / 4) 27 28 static u32 deinterlace_formats[] = { 29 V4L2_PIX_FMT_NV12, 30 V4L2_PIX_FMT_NV21, 31 }; 32 33 static inline u32 deinterlace_read(struct deinterlace_dev *dev, u32 reg) 34 { 35 return readl(dev->base + reg); 36 } 37 38 static inline void deinterlace_write(struct deinterlace_dev *dev, 39 u32 reg, u32 value) 40 { 41 writel(value, dev->base + reg); 42 } 43 44 static inline void deinterlace_set_bits(struct deinterlace_dev *dev, 45 u32 reg, u32 bits) 46 { 47 writel(readl(dev->base + reg) | bits, dev->base + reg); 48 } 49 50 static inline void deinterlace_clr_set_bits(struct deinterlace_dev *dev, 51 u32 reg, u32 clr, u32 set) 52 { 53 u32 val = readl(dev->base + reg); 54 55 val &= ~clr; 56 val |= set; 57 58 writel(val, dev->base + reg); 59 } 60 61 static void deinterlace_device_run(void *priv) 62 { 63 struct deinterlace_ctx *ctx = priv; 64 struct deinterlace_dev *dev = ctx->dev; 65 u32 size, stride, width, height, val; 66 struct vb2_v4l2_buffer *src, *dst; 67 unsigned int hstep, vstep; 68 dma_addr_t addr; 69 70 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 71 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 72 73 v4l2_m2m_buf_copy_metadata(src, dst, true); 74 75 deinterlace_write(dev, DEINTERLACE_MOD_ENABLE, 76 DEINTERLACE_MOD_ENABLE_EN); 77 78 if (ctx->field) { 79 deinterlace_write(dev, DEINTERLACE_TILE_FLAG0, 80 ctx->flag1_buf_dma); 81 deinterlace_write(dev, DEINTERLACE_TILE_FLAG1, 82 ctx->flag2_buf_dma); 83 } else { 84 deinterlace_write(dev, DEINTERLACE_TILE_FLAG0, 85 ctx->flag2_buf_dma); 86 deinterlace_write(dev, DEINTERLACE_TILE_FLAG1, 87 ctx->flag1_buf_dma); 88 } 89 deinterlace_write(dev, DEINTERLACE_FLAG_LINE_STRIDE, 0x200); 90 91 width = ctx->src_fmt.width; 92 height = ctx->src_fmt.height; 93 stride = ctx->src_fmt.bytesperline; 94 size = stride * height; 95 96 addr = vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0); 97 deinterlace_write(dev, DEINTERLACE_BUF_ADDR0, addr); 98 deinterlace_write(dev, DEINTERLACE_BUF_ADDR1, addr + size); 99 deinterlace_write(dev, DEINTERLACE_BUF_ADDR2, 0); 100 101 deinterlace_write(dev, DEINTERLACE_LINE_STRIDE0, stride); 102 deinterlace_write(dev, DEINTERLACE_LINE_STRIDE1, stride); 103 104 deinterlace_write(dev, DEINTERLACE_CH0_IN_SIZE, 105 DEINTERLACE_SIZE(width, height)); 106 deinterlace_write(dev, DEINTERLACE_CH1_IN_SIZE, 107 DEINTERLACE_SIZE(width / 2, height / 2)); 108 109 val = DEINTERLACE_IN_FMT_FMT(DEINTERLACE_IN_FMT_YUV420) | 110 DEINTERLACE_IN_FMT_MOD(DEINTERLACE_MODE_UV_COMBINED); 111 switch (ctx->src_fmt.pixelformat) { 112 case V4L2_PIX_FMT_NV12: 113 val |= DEINTERLACE_IN_FMT_PS(DEINTERLACE_PS_UVUV); 114 break; 115 case V4L2_PIX_FMT_NV21: 116 val |= DEINTERLACE_IN_FMT_PS(DEINTERLACE_PS_VUVU); 117 break; 118 } 119 deinterlace_write(dev, DEINTERLACE_IN_FMT, val); 120 121 if (ctx->prev) 122 addr = vb2_dma_contig_plane_dma_addr(&ctx->prev->vb2_buf, 0); 123 124 deinterlace_write(dev, DEINTERLACE_PRELUMA, addr); 125 deinterlace_write(dev, DEINTERLACE_PRECHROMA, addr + size); 126 127 val = DEINTERLACE_OUT_FMT_FMT(DEINTERLACE_OUT_FMT_YUV420SP); 128 switch (ctx->src_fmt.pixelformat) { 129 case V4L2_PIX_FMT_NV12: 130 val |= DEINTERLACE_OUT_FMT_PS(DEINTERLACE_PS_UVUV); 131 break; 132 case V4L2_PIX_FMT_NV21: 133 val |= DEINTERLACE_OUT_FMT_PS(DEINTERLACE_PS_VUVU); 134 break; 135 } 136 deinterlace_write(dev, DEINTERLACE_OUT_FMT, val); 137 138 width = ctx->dst_fmt.width; 139 height = ctx->dst_fmt.height; 140 stride = ctx->dst_fmt.bytesperline; 141 size = stride * height; 142 143 deinterlace_write(dev, DEINTERLACE_CH0_OUT_SIZE, 144 DEINTERLACE_SIZE(width, height)); 145 deinterlace_write(dev, DEINTERLACE_CH1_OUT_SIZE, 146 DEINTERLACE_SIZE(width / 2, height / 2)); 147 148 deinterlace_write(dev, DEINTERLACE_WB_LINE_STRIDE0, stride); 149 deinterlace_write(dev, DEINTERLACE_WB_LINE_STRIDE1, stride); 150 151 addr = vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0); 152 deinterlace_write(dev, DEINTERLACE_WB_ADDR0, addr); 153 deinterlace_write(dev, DEINTERLACE_WB_ADDR1, addr + size); 154 deinterlace_write(dev, DEINTERLACE_WB_ADDR2, 0); 155 156 hstep = (ctx->src_fmt.width << 16) / ctx->dst_fmt.width; 157 vstep = (ctx->src_fmt.height << 16) / ctx->dst_fmt.height; 158 deinterlace_write(dev, DEINTERLACE_CH0_HORZ_FACT, hstep); 159 deinterlace_write(dev, DEINTERLACE_CH0_VERT_FACT, vstep); 160 deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep); 161 deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep); 162 163 deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL, 164 DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK, 165 DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field)); 166 167 deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, 168 DEINTERLACE_FRM_CTRL_START); 169 170 deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, 171 DEINTERLACE_FRM_CTRL_REG_READY); 172 173 deinterlace_set_bits(dev, DEINTERLACE_INT_ENABLE, 174 DEINTERLACE_INT_ENABLE_WB_EN); 175 176 deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, 177 DEINTERLACE_FRM_CTRL_WB_EN); 178 } 179 180 static int deinterlace_job_ready(void *priv) 181 { 182 struct deinterlace_ctx *ctx = priv; 183 184 return v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) >= 1 && 185 v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) >= 2; 186 } 187 188 static void deinterlace_job_abort(void *priv) 189 { 190 struct deinterlace_ctx *ctx = priv; 191 192 /* Will cancel the transaction in the next interrupt handler */ 193 ctx->aborting = 1; 194 } 195 196 static irqreturn_t deinterlace_irq(int irq, void *data) 197 { 198 struct deinterlace_dev *dev = data; 199 struct vb2_v4l2_buffer *src, *dst; 200 enum vb2_buffer_state state; 201 struct deinterlace_ctx *ctx; 202 unsigned int val; 203 204 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); 205 if (!ctx) { 206 v4l2_err(&dev->v4l2_dev, 207 "Instance released before the end of transaction\n"); 208 return IRQ_NONE; 209 } 210 211 val = deinterlace_read(dev, DEINTERLACE_INT_STATUS); 212 if (!(val & DEINTERLACE_INT_STATUS_WRITEBACK)) 213 return IRQ_NONE; 214 215 deinterlace_write(dev, DEINTERLACE_INT_ENABLE, 0); 216 deinterlace_set_bits(dev, DEINTERLACE_INT_STATUS, 217 DEINTERLACE_INT_STATUS_WRITEBACK); 218 deinterlace_write(dev, DEINTERLACE_MOD_ENABLE, 0); 219 deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL, 220 DEINTERLACE_FRM_CTRL_START, 0); 221 222 val = deinterlace_read(dev, DEINTERLACE_STATUS); 223 if (val & DEINTERLACE_STATUS_WB_ERROR) 224 state = VB2_BUF_STATE_ERROR; 225 else 226 state = VB2_BUF_STATE_DONE; 227 228 dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 229 v4l2_m2m_buf_done(dst, state); 230 231 if (ctx->field != ctx->first_field || ctx->aborting) { 232 ctx->field = ctx->first_field; 233 234 src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 235 if (ctx->prev) 236 v4l2_m2m_buf_done(ctx->prev, state); 237 ctx->prev = src; 238 239 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); 240 } else { 241 ctx->field = !ctx->first_field; 242 deinterlace_device_run(ctx); 243 } 244 245 return IRQ_HANDLED; 246 } 247 248 static void deinterlace_init(struct deinterlace_dev *dev) 249 { 250 u32 val; 251 int i; 252 253 deinterlace_write(dev, DEINTERLACE_BYPASS, 254 DEINTERLACE_BYPASS_CSC); 255 deinterlace_write(dev, DEINTERLACE_WB_LINE_STRIDE_CTRL, 256 DEINTERLACE_WB_LINE_STRIDE_CTRL_EN); 257 deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, 258 DEINTERLACE_FRM_CTRL_OUT_CTRL); 259 deinterlace_write(dev, DEINTERLACE_AGTH_SEL, 260 DEINTERLACE_AGTH_SEL_LINEBUF); 261 262 val = DEINTERLACE_CTRL_EN | 263 DEINTERLACE_CTRL_MODE_MIXED | 264 DEINTERLACE_CTRL_DIAG_INTP_EN | 265 DEINTERLACE_CTRL_TEMP_DIFF_EN; 266 deinterlace_write(dev, DEINTERLACE_CTRL, val); 267 268 deinterlace_clr_set_bits(dev, DEINTERLACE_LUMA_TH, 269 DEINTERLACE_LUMA_TH_MIN_LUMA_MSK, 270 DEINTERLACE_LUMA_TH_MIN_LUMA(4)); 271 272 deinterlace_clr_set_bits(dev, DEINTERLACE_SPAT_COMP, 273 DEINTERLACE_SPAT_COMP_TH2_MSK, 274 DEINTERLACE_SPAT_COMP_TH2(5)); 275 276 deinterlace_clr_set_bits(dev, DEINTERLACE_TEMP_DIFF, 277 DEINTERLACE_TEMP_DIFF_AMBIGUITY_TH_MSK, 278 DEINTERLACE_TEMP_DIFF_AMBIGUITY_TH(5)); 279 280 val = DEINTERLACE_DIAG_INTP_TH0(60) | 281 DEINTERLACE_DIAG_INTP_TH1(0) | 282 DEINTERLACE_DIAG_INTP_TH3(30); 283 deinterlace_write(dev, DEINTERLACE_DIAG_INTP, val); 284 285 deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF, 286 DEINTERLACE_CHROMA_DIFF_TH_MSK, 287 DEINTERLACE_CHROMA_DIFF_TH(5)); 288 289 /* neutral filter coefficients */ 290 deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL, 291 DEINTERLACE_FRM_CTRL_COEF_ACCESS); 292 readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val, 293 val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40); 294 295 for (i = 0; i < 32; i++) { 296 deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4, 297 DEINTERLACE_IDENTITY_COEF); 298 deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4, 299 DEINTERLACE_IDENTITY_COEF); 300 deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4, 301 DEINTERLACE_IDENTITY_COEF); 302 deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4, 303 DEINTERLACE_IDENTITY_COEF); 304 } 305 306 deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL, 307 DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0); 308 } 309 310 static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file) 311 { 312 return container_of(file->private_data, struct deinterlace_ctx, fh); 313 } 314 315 static bool deinterlace_check_format(u32 pixelformat) 316 { 317 unsigned int i; 318 319 for (i = 0; i < ARRAY_SIZE(deinterlace_formats); i++) 320 if (deinterlace_formats[i] == pixelformat) 321 return true; 322 323 return false; 324 } 325 326 static void deinterlace_prepare_format(struct v4l2_pix_format *pix_fmt) 327 { 328 unsigned int height = pix_fmt->height; 329 unsigned int width = pix_fmt->width; 330 unsigned int bytesperline; 331 unsigned int sizeimage; 332 333 width = clamp(width, DEINTERLACE_MIN_WIDTH, 334 DEINTERLACE_MAX_WIDTH); 335 height = clamp(height, DEINTERLACE_MIN_HEIGHT, 336 DEINTERLACE_MAX_HEIGHT); 337 338 bytesperline = ALIGN(width, 2); 339 /* luma */ 340 sizeimage = bytesperline * height; 341 /* chroma */ 342 sizeimage += bytesperline * height / 2; 343 344 pix_fmt->width = width; 345 pix_fmt->height = height; 346 pix_fmt->bytesperline = bytesperline; 347 pix_fmt->sizeimage = sizeimage; 348 } 349 350 static int deinterlace_querycap(struct file *file, void *priv, 351 struct v4l2_capability *cap) 352 { 353 strscpy(cap->driver, DEINTERLACE_NAME, sizeof(cap->driver)); 354 strscpy(cap->card, DEINTERLACE_NAME, sizeof(cap->card)); 355 snprintf(cap->bus_info, sizeof(cap->bus_info), 356 "platform:%s", DEINTERLACE_NAME); 357 358 return 0; 359 } 360 361 static int deinterlace_enum_fmt(struct file *file, void *priv, 362 struct v4l2_fmtdesc *f) 363 { 364 if (f->index < ARRAY_SIZE(deinterlace_formats)) { 365 f->pixelformat = deinterlace_formats[f->index]; 366 367 return 0; 368 } 369 370 return -EINVAL; 371 } 372 373 static int deinterlace_enum_framesizes(struct file *file, void *priv, 374 struct v4l2_frmsizeenum *fsize) 375 { 376 if (fsize->index != 0) 377 return -EINVAL; 378 379 if (!deinterlace_check_format(fsize->pixel_format)) 380 return -EINVAL; 381 382 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 383 fsize->stepwise.min_width = DEINTERLACE_MIN_WIDTH; 384 fsize->stepwise.min_height = DEINTERLACE_MIN_HEIGHT; 385 fsize->stepwise.max_width = DEINTERLACE_MAX_WIDTH; 386 fsize->stepwise.max_height = DEINTERLACE_MAX_HEIGHT; 387 fsize->stepwise.step_width = 2; 388 fsize->stepwise.step_height = 1; 389 390 return 0; 391 } 392 393 static int deinterlace_g_fmt_vid_cap(struct file *file, void *priv, 394 struct v4l2_format *f) 395 { 396 struct deinterlace_ctx *ctx = deinterlace_file2ctx(file); 397 398 f->fmt.pix = ctx->dst_fmt; 399 400 return 0; 401 } 402 403 static int deinterlace_g_fmt_vid_out(struct file *file, void *priv, 404 struct v4l2_format *f) 405 { 406 struct deinterlace_ctx *ctx = deinterlace_file2ctx(file); 407 408 f->fmt.pix = ctx->src_fmt; 409 410 return 0; 411 } 412 413 static int deinterlace_try_fmt_vid_cap(struct file *file, void *priv, 414 struct v4l2_format *f) 415 { 416 if (!deinterlace_check_format(f->fmt.pix.pixelformat)) 417 f->fmt.pix.pixelformat = deinterlace_formats[0]; 418 419 if (f->fmt.pix.field != V4L2_FIELD_NONE) 420 f->fmt.pix.field = V4L2_FIELD_NONE; 421 422 deinterlace_prepare_format(&f->fmt.pix); 423 424 return 0; 425 } 426 427 static int deinterlace_try_fmt_vid_out(struct file *file, void *priv, 428 struct v4l2_format *f) 429 { 430 if (!deinterlace_check_format(f->fmt.pix.pixelformat)) 431 f->fmt.pix.pixelformat = deinterlace_formats[0]; 432 433 if (f->fmt.pix.field != V4L2_FIELD_INTERLACED_TB && 434 f->fmt.pix.field != V4L2_FIELD_INTERLACED_BT && 435 f->fmt.pix.field != V4L2_FIELD_INTERLACED) 436 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 437 438 deinterlace_prepare_format(&f->fmt.pix); 439 440 return 0; 441 } 442 443 static int deinterlace_s_fmt_vid_cap(struct file *file, void *priv, 444 struct v4l2_format *f) 445 { 446 struct deinterlace_ctx *ctx = deinterlace_file2ctx(file); 447 struct vb2_queue *vq; 448 int ret; 449 450 ret = deinterlace_try_fmt_vid_cap(file, priv, f); 451 if (ret) 452 return ret; 453 454 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); 455 if (vb2_is_busy(vq)) 456 return -EBUSY; 457 458 ctx->dst_fmt = f->fmt.pix; 459 460 return 0; 461 } 462 463 static int deinterlace_s_fmt_vid_out(struct file *file, void *priv, 464 struct v4l2_format *f) 465 { 466 struct deinterlace_ctx *ctx = deinterlace_file2ctx(file); 467 struct vb2_queue *vq; 468 int ret; 469 470 ret = deinterlace_try_fmt_vid_out(file, priv, f); 471 if (ret) 472 return ret; 473 474 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); 475 if (vb2_is_busy(vq)) 476 return -EBUSY; 477 478 ctx->src_fmt = f->fmt.pix; 479 480 /* Propagate colorspace information to capture. */ 481 ctx->dst_fmt.colorspace = f->fmt.pix.colorspace; 482 ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func; 483 ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc; 484 ctx->dst_fmt.quantization = f->fmt.pix.quantization; 485 486 return 0; 487 } 488 489 static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = { 490 .vidioc_querycap = deinterlace_querycap, 491 492 .vidioc_enum_framesizes = deinterlace_enum_framesizes, 493 494 .vidioc_enum_fmt_vid_cap = deinterlace_enum_fmt, 495 .vidioc_g_fmt_vid_cap = deinterlace_g_fmt_vid_cap, 496 .vidioc_try_fmt_vid_cap = deinterlace_try_fmt_vid_cap, 497 .vidioc_s_fmt_vid_cap = deinterlace_s_fmt_vid_cap, 498 499 .vidioc_enum_fmt_vid_out = deinterlace_enum_fmt, 500 .vidioc_g_fmt_vid_out = deinterlace_g_fmt_vid_out, 501 .vidioc_try_fmt_vid_out = deinterlace_try_fmt_vid_out, 502 .vidioc_s_fmt_vid_out = deinterlace_s_fmt_vid_out, 503 504 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 505 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 506 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 507 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 508 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 509 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 510 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 511 512 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 513 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 514 }; 515 516 static int deinterlace_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 517 unsigned int *nplanes, unsigned int sizes[], 518 struct device *alloc_devs[]) 519 { 520 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq); 521 struct v4l2_pix_format *pix_fmt; 522 523 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 524 pix_fmt = &ctx->src_fmt; 525 else 526 pix_fmt = &ctx->dst_fmt; 527 528 if (*nplanes) { 529 if (sizes[0] < pix_fmt->sizeimage) 530 return -EINVAL; 531 } else { 532 sizes[0] = pix_fmt->sizeimage; 533 *nplanes = 1; 534 } 535 536 return 0; 537 } 538 539 static int deinterlace_buf_prepare(struct vb2_buffer *vb) 540 { 541 struct vb2_queue *vq = vb->vb2_queue; 542 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq); 543 struct v4l2_pix_format *pix_fmt; 544 545 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 546 pix_fmt = &ctx->src_fmt; 547 else 548 pix_fmt = &ctx->dst_fmt; 549 550 if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage) 551 return -EINVAL; 552 553 vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); 554 555 return 0; 556 } 557 558 static void deinterlace_buf_queue(struct vb2_buffer *vb) 559 { 560 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 561 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 562 563 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 564 } 565 566 static void deinterlace_queue_cleanup(struct vb2_queue *vq, u32 state) 567 { 568 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq); 569 struct vb2_v4l2_buffer *vbuf; 570 571 do { 572 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 573 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 574 else 575 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 576 577 if (vbuf) 578 v4l2_m2m_buf_done(vbuf, state); 579 } while (vbuf); 580 581 if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->prev) 582 v4l2_m2m_buf_done(ctx->prev, state); 583 } 584 585 static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count) 586 { 587 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq); 588 struct device *dev = ctx->dev->dev; 589 int ret; 590 591 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 592 ret = pm_runtime_get_sync(dev); 593 if (ret < 0) { 594 dev_err(dev, "Failed to enable module\n"); 595 596 goto err_runtime_get; 597 } 598 599 ctx->first_field = 600 ctx->src_fmt.field == V4L2_FIELD_INTERLACED_BT; 601 ctx->field = ctx->first_field; 602 603 ctx->prev = NULL; 604 ctx->aborting = 0; 605 606 ctx->flag1_buf = dma_alloc_coherent(dev, FLAG_SIZE, 607 &ctx->flag1_buf_dma, 608 GFP_KERNEL); 609 if (!ctx->flag1_buf) { 610 ret = -ENOMEM; 611 612 goto err_no_mem1; 613 } 614 615 ctx->flag2_buf = dma_alloc_coherent(dev, FLAG_SIZE, 616 &ctx->flag2_buf_dma, 617 GFP_KERNEL); 618 if (!ctx->flag2_buf) { 619 ret = -ENOMEM; 620 621 goto err_no_mem2; 622 } 623 } 624 625 return 0; 626 627 err_no_mem2: 628 dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf, 629 ctx->flag1_buf_dma); 630 err_no_mem1: 631 pm_runtime_put(dev); 632 err_runtime_get: 633 deinterlace_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); 634 635 return ret; 636 } 637 638 static void deinterlace_stop_streaming(struct vb2_queue *vq) 639 { 640 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq); 641 642 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 643 struct device *dev = ctx->dev->dev; 644 645 dma_free_coherent(dev, FLAG_SIZE, ctx->flag1_buf, 646 ctx->flag1_buf_dma); 647 dma_free_coherent(dev, FLAG_SIZE, ctx->flag2_buf, 648 ctx->flag2_buf_dma); 649 650 pm_runtime_put(dev); 651 } 652 653 deinterlace_queue_cleanup(vq, VB2_BUF_STATE_ERROR); 654 } 655 656 static const struct vb2_ops deinterlace_qops = { 657 .queue_setup = deinterlace_queue_setup, 658 .buf_prepare = deinterlace_buf_prepare, 659 .buf_queue = deinterlace_buf_queue, 660 .start_streaming = deinterlace_start_streaming, 661 .stop_streaming = deinterlace_stop_streaming, 662 .wait_prepare = vb2_ops_wait_prepare, 663 .wait_finish = vb2_ops_wait_finish, 664 }; 665 666 static int deinterlace_queue_init(void *priv, struct vb2_queue *src_vq, 667 struct vb2_queue *dst_vq) 668 { 669 struct deinterlace_ctx *ctx = priv; 670 int ret; 671 672 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 673 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 674 src_vq->drv_priv = ctx; 675 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 676 src_vq->min_buffers_needed = 1; 677 src_vq->ops = &deinterlace_qops; 678 src_vq->mem_ops = &vb2_dma_contig_memops; 679 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 680 src_vq->lock = &ctx->dev->dev_mutex; 681 src_vq->dev = ctx->dev->dev; 682 683 ret = vb2_queue_init(src_vq); 684 if (ret) 685 return ret; 686 687 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 688 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 689 dst_vq->drv_priv = ctx; 690 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 691 dst_vq->min_buffers_needed = 2; 692 dst_vq->ops = &deinterlace_qops; 693 dst_vq->mem_ops = &vb2_dma_contig_memops; 694 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 695 dst_vq->lock = &ctx->dev->dev_mutex; 696 dst_vq->dev = ctx->dev->dev; 697 698 ret = vb2_queue_init(dst_vq); 699 if (ret) 700 return ret; 701 702 return 0; 703 } 704 705 static int deinterlace_open(struct file *file) 706 { 707 struct deinterlace_dev *dev = video_drvdata(file); 708 struct deinterlace_ctx *ctx = NULL; 709 int ret; 710 711 if (mutex_lock_interruptible(&dev->dev_mutex)) 712 return -ERESTARTSYS; 713 714 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 715 if (!ctx) { 716 mutex_unlock(&dev->dev_mutex); 717 return -ENOMEM; 718 } 719 720 /* default output format */ 721 ctx->src_fmt.pixelformat = deinterlace_formats[0]; 722 ctx->src_fmt.field = V4L2_FIELD_INTERLACED; 723 ctx->src_fmt.width = 640; 724 ctx->src_fmt.height = 480; 725 deinterlace_prepare_format(&ctx->src_fmt); 726 727 /* default capture format */ 728 ctx->dst_fmt.pixelformat = deinterlace_formats[0]; 729 ctx->dst_fmt.field = V4L2_FIELD_NONE; 730 ctx->dst_fmt.width = 640; 731 ctx->dst_fmt.height = 480; 732 deinterlace_prepare_format(&ctx->dst_fmt); 733 734 v4l2_fh_init(&ctx->fh, video_devdata(file)); 735 file->private_data = &ctx->fh; 736 ctx->dev = dev; 737 738 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, 739 &deinterlace_queue_init); 740 if (IS_ERR(ctx->fh.m2m_ctx)) { 741 ret = PTR_ERR(ctx->fh.m2m_ctx); 742 goto err_free; 743 } 744 745 v4l2_fh_add(&ctx->fh); 746 747 mutex_unlock(&dev->dev_mutex); 748 749 return 0; 750 751 err_free: 752 kfree(ctx); 753 mutex_unlock(&dev->dev_mutex); 754 755 return ret; 756 } 757 758 static int deinterlace_release(struct file *file) 759 { 760 struct deinterlace_dev *dev = video_drvdata(file); 761 struct deinterlace_ctx *ctx = container_of(file->private_data, 762 struct deinterlace_ctx, fh); 763 764 mutex_lock(&dev->dev_mutex); 765 766 v4l2_fh_del(&ctx->fh); 767 v4l2_fh_exit(&ctx->fh); 768 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 769 770 kfree(ctx); 771 772 mutex_unlock(&dev->dev_mutex); 773 774 return 0; 775 } 776 777 static const struct v4l2_file_operations deinterlace_fops = { 778 .owner = THIS_MODULE, 779 .open = deinterlace_open, 780 .release = deinterlace_release, 781 .poll = v4l2_m2m_fop_poll, 782 .unlocked_ioctl = video_ioctl2, 783 .mmap = v4l2_m2m_fop_mmap, 784 }; 785 786 static const struct video_device deinterlace_video_device = { 787 .name = DEINTERLACE_NAME, 788 .vfl_dir = VFL_DIR_M2M, 789 .fops = &deinterlace_fops, 790 .ioctl_ops = &deinterlace_ioctl_ops, 791 .minor = -1, 792 .release = video_device_release_empty, 793 .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, 794 }; 795 796 static const struct v4l2_m2m_ops deinterlace_m2m_ops = { 797 .device_run = deinterlace_device_run, 798 .job_ready = deinterlace_job_ready, 799 .job_abort = deinterlace_job_abort, 800 }; 801 802 static int deinterlace_probe(struct platform_device *pdev) 803 { 804 struct deinterlace_dev *dev; 805 struct video_device *vfd; 806 struct resource *res; 807 int irq, ret; 808 809 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 810 if (!dev) 811 return -ENOMEM; 812 813 dev->vfd = deinterlace_video_device; 814 dev->dev = &pdev->dev; 815 816 irq = platform_get_irq(pdev, 0); 817 if (irq <= 0) { 818 dev_err(dev->dev, "Failed to get IRQ\n"); 819 820 return irq; 821 } 822 823 ret = devm_request_irq(dev->dev, irq, deinterlace_irq, 824 0, dev_name(dev->dev), dev); 825 if (ret) { 826 dev_err(dev->dev, "Failed to request IRQ\n"); 827 828 return ret; 829 } 830 831 ret = of_dma_configure(dev->dev, dev->dev->of_node, true); 832 if (ret) 833 return ret; 834 835 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 836 dev->base = devm_ioremap_resource(&pdev->dev, res); 837 if (IS_ERR(dev->base)) { 838 dev_err(dev->dev, "Failed to map registers\n"); 839 840 return PTR_ERR(dev->base); 841 } 842 843 dev->bus_clk = devm_clk_get(dev->dev, "bus"); 844 if (IS_ERR(dev->bus_clk)) { 845 dev_err(dev->dev, "Failed to get bus clock\n"); 846 847 return PTR_ERR(dev->bus_clk); 848 } 849 850 dev->mod_clk = devm_clk_get(dev->dev, "mod"); 851 if (IS_ERR(dev->mod_clk)) { 852 dev_err(dev->dev, "Failed to get mod clock\n"); 853 854 return PTR_ERR(dev->mod_clk); 855 } 856 857 dev->ram_clk = devm_clk_get(dev->dev, "ram"); 858 if (IS_ERR(dev->ram_clk)) { 859 dev_err(dev->dev, "Failed to get ram clock\n"); 860 861 return PTR_ERR(dev->ram_clk); 862 } 863 864 dev->rstc = devm_reset_control_get(dev->dev, NULL); 865 if (IS_ERR(dev->rstc)) { 866 dev_err(dev->dev, "Failed to get reset control\n"); 867 868 return PTR_ERR(dev->rstc); 869 } 870 871 mutex_init(&dev->dev_mutex); 872 873 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); 874 if (ret) { 875 dev_err(dev->dev, "Failed to register V4L2 device\n"); 876 877 return ret; 878 } 879 880 vfd = &dev->vfd; 881 vfd->lock = &dev->dev_mutex; 882 vfd->v4l2_dev = &dev->v4l2_dev; 883 884 snprintf(vfd->name, sizeof(vfd->name), "%s", 885 deinterlace_video_device.name); 886 video_set_drvdata(vfd, dev); 887 888 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 889 if (ret) { 890 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); 891 892 goto err_v4l2; 893 } 894 895 v4l2_info(&dev->v4l2_dev, 896 "Device registered as /dev/video%d\n", vfd->num); 897 898 dev->m2m_dev = v4l2_m2m_init(&deinterlace_m2m_ops); 899 if (IS_ERR(dev->m2m_dev)) { 900 v4l2_err(&dev->v4l2_dev, 901 "Failed to initialize V4L2 M2M device\n"); 902 ret = PTR_ERR(dev->m2m_dev); 903 904 goto err_video; 905 } 906 907 platform_set_drvdata(pdev, dev); 908 909 pm_runtime_enable(dev->dev); 910 911 return 0; 912 913 err_video: 914 video_unregister_device(&dev->vfd); 915 err_v4l2: 916 v4l2_device_unregister(&dev->v4l2_dev); 917 918 return ret; 919 } 920 921 static int deinterlace_remove(struct platform_device *pdev) 922 { 923 struct deinterlace_dev *dev = platform_get_drvdata(pdev); 924 925 v4l2_m2m_release(dev->m2m_dev); 926 video_unregister_device(&dev->vfd); 927 v4l2_device_unregister(&dev->v4l2_dev); 928 929 pm_runtime_force_suspend(&pdev->dev); 930 931 return 0; 932 } 933 934 static int deinterlace_runtime_resume(struct device *device) 935 { 936 struct deinterlace_dev *dev = dev_get_drvdata(device); 937 int ret; 938 939 ret = clk_set_rate_exclusive(dev->mod_clk, 300000000); 940 if (ret) { 941 dev_err(dev->dev, "Failed to set exclusive mod clock rate\n"); 942 943 return ret; 944 } 945 946 ret = clk_prepare_enable(dev->bus_clk); 947 if (ret) { 948 dev_err(dev->dev, "Failed to enable bus clock\n"); 949 950 goto err_exlusive_rate; 951 } 952 953 ret = clk_prepare_enable(dev->mod_clk); 954 if (ret) { 955 dev_err(dev->dev, "Failed to enable mod clock\n"); 956 957 goto err_bus_clk; 958 } 959 960 ret = clk_prepare_enable(dev->ram_clk); 961 if (ret) { 962 dev_err(dev->dev, "Failed to enable ram clock\n"); 963 964 goto err_mod_clk; 965 } 966 967 ret = reset_control_deassert(dev->rstc); 968 if (ret) { 969 dev_err(dev->dev, "Failed to apply reset\n"); 970 971 goto err_ram_clk; 972 } 973 974 deinterlace_init(dev); 975 976 return 0; 977 978 err_exlusive_rate: 979 clk_rate_exclusive_put(dev->mod_clk); 980 err_ram_clk: 981 clk_disable_unprepare(dev->ram_clk); 982 err_mod_clk: 983 clk_disable_unprepare(dev->mod_clk); 984 err_bus_clk: 985 clk_disable_unprepare(dev->bus_clk); 986 987 return ret; 988 } 989 990 static int deinterlace_runtime_suspend(struct device *device) 991 { 992 struct deinterlace_dev *dev = dev_get_drvdata(device); 993 994 reset_control_assert(dev->rstc); 995 996 clk_disable_unprepare(dev->ram_clk); 997 clk_disable_unprepare(dev->mod_clk); 998 clk_disable_unprepare(dev->bus_clk); 999 clk_rate_exclusive_put(dev->mod_clk); 1000 1001 return 0; 1002 } 1003 1004 static const struct of_device_id deinterlace_dt_match[] = { 1005 { .compatible = "allwinner,sun8i-h3-deinterlace" }, 1006 { /* sentinel */ } 1007 }; 1008 MODULE_DEVICE_TABLE(of, deinterlace_dt_match); 1009 1010 static const struct dev_pm_ops deinterlace_pm_ops = { 1011 .runtime_resume = deinterlace_runtime_resume, 1012 .runtime_suspend = deinterlace_runtime_suspend, 1013 }; 1014 1015 static struct platform_driver deinterlace_driver = { 1016 .probe = deinterlace_probe, 1017 .remove = deinterlace_remove, 1018 .driver = { 1019 .name = DEINTERLACE_NAME, 1020 .of_match_table = deinterlace_dt_match, 1021 .pm = &deinterlace_pm_ops, 1022 }, 1023 }; 1024 module_platform_driver(deinterlace_driver); 1025 1026 MODULE_LICENSE("GPL v2"); 1027 MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>"); 1028 MODULE_DESCRIPTION("Allwinner Deinterlace driver"); 1029