1 /* 2 * Copyright (C) 2012-2016 Mentor Graphics Inc. 3 * 4 * Queued image conversion support, with tiling and rotation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * for more details. 15 */ 16 17 #include <linux/interrupt.h> 18 #include <linux/dma-mapping.h> 19 #include <video/imx-ipu-image-convert.h> 20 #include "ipu-prv.h" 21 22 /* 23 * The IC Resizer has a restriction that the output frame from the 24 * resizer must be 1024 or less in both width (pixels) and height 25 * (lines). 26 * 27 * The image converter attempts to split up a conversion when 28 * the desired output (converted) frame resolution exceeds the 29 * IC resizer limit of 1024 in either dimension. 30 * 31 * If either dimension of the output frame exceeds the limit, the 32 * dimension is split into 1, 2, or 4 equal stripes, for a maximum 33 * of 4*4 or 16 tiles. A conversion is then carried out for each 34 * tile (but taking care to pass the full frame stride length to 35 * the DMA channel's parameter memory!). IDMA double-buffering is used 36 * to convert each tile back-to-back when possible (see note below 37 * when double_buffering boolean is set). 38 * 39 * Note that the input frame must be split up into the same number 40 * of tiles as the output frame: 41 * 42 * +---------+-----+ 43 * +-----+---+ | A | B | 44 * | A | B | | | | 45 * +-----+---+ --> +---------+-----+ 46 * | C | D | | C | D | 47 * +-----+---+ | | | 48 * +---------+-----+ 49 * 50 * Clockwise 90° rotations are handled by first rescaling into a 51 * reusable temporary tile buffer and then rotating with the 8x8 52 * block rotator, writing to the correct destination: 53 * 54 * +-----+-----+ 55 * | | | 56 * +-----+---+ +---------+ | C | A | 57 * | A | B | | A,B, | | | | | 58 * +-----+---+ --> | C,D | | --> | | | 59 * | C | D | +---------+ +-----+-----+ 60 * +-----+---+ | D | B | 61 * | | | 62 * +-----+-----+ 63 * 64 * If the 8x8 block rotator is used, horizontal or vertical flipping 65 * is done during the rotation step, otherwise flipping is done 66 * during the scaling step. 67 * With rotation or flipping, tile order changes between input and 68 * output image. Tiles are numbered row major from top left to bottom 69 * right for both input and output image. 70 */ 71 72 #define MAX_STRIPES_W 4 73 #define MAX_STRIPES_H 4 74 #define MAX_TILES (MAX_STRIPES_W * MAX_STRIPES_H) 75 76 #define MIN_W 16 77 #define MIN_H 8 78 #define MAX_W 4096 79 #define MAX_H 4096 80 81 enum ipu_image_convert_type { 82 IMAGE_CONVERT_IN = 0, 83 IMAGE_CONVERT_OUT, 84 }; 85 86 struct ipu_image_convert_dma_buf { 87 void *virt; 88 dma_addr_t phys; 89 unsigned long len; 90 }; 91 92 struct ipu_image_convert_dma_chan { 93 int in; 94 int out; 95 int rot_in; 96 int rot_out; 97 int vdi_in_p; 98 int vdi_in; 99 int vdi_in_n; 100 }; 101 102 /* dimensions of one tile */ 103 struct ipu_image_tile { 104 u32 width; 105 u32 height; 106 u32 left; 107 u32 top; 108 /* size and strides are in bytes */ 109 u32 size; 110 u32 stride; 111 u32 rot_stride; 112 /* start Y or packed offset of this tile */ 113 u32 offset; 114 /* offset from start to tile in U plane, for planar formats */ 115 u32 u_off; 116 /* offset from start to tile in V plane, for planar formats */ 117 u32 v_off; 118 }; 119 120 struct ipu_image_convert_image { 121 struct ipu_image base; 122 enum ipu_image_convert_type type; 123 124 const struct ipu_image_pixfmt *fmt; 125 unsigned int stride; 126 127 /* # of rows (horizontal stripes) if dest height is > 1024 */ 128 unsigned int num_rows; 129 /* # of columns (vertical stripes) if dest width is > 1024 */ 130 unsigned int num_cols; 131 132 struct ipu_image_tile tile[MAX_TILES]; 133 }; 134 135 struct ipu_image_pixfmt { 136 u32 fourcc; /* V4L2 fourcc */ 137 int bpp; /* total bpp */ 138 int uv_width_dec; /* decimation in width for U/V planes */ 139 int uv_height_dec; /* decimation in height for U/V planes */ 140 bool planar; /* planar format */ 141 bool uv_swapped; /* U and V planes are swapped */ 142 bool uv_packed; /* partial planar (U and V in same plane) */ 143 }; 144 145 struct ipu_image_convert_ctx; 146 struct ipu_image_convert_chan; 147 struct ipu_image_convert_priv; 148 149 struct ipu_image_convert_ctx { 150 struct ipu_image_convert_chan *chan; 151 152 ipu_image_convert_cb_t complete; 153 void *complete_context; 154 155 /* Source/destination image data and rotation mode */ 156 struct ipu_image_convert_image in; 157 struct ipu_image_convert_image out; 158 enum ipu_rotate_mode rot_mode; 159 u32 downsize_coeff_h; 160 u32 downsize_coeff_v; 161 u32 image_resize_coeff_h; 162 u32 image_resize_coeff_v; 163 u32 resize_coeffs_h[MAX_STRIPES_W]; 164 u32 resize_coeffs_v[MAX_STRIPES_H]; 165 166 /* intermediate buffer for rotation */ 167 struct ipu_image_convert_dma_buf rot_intermediate[2]; 168 169 /* current buffer number for double buffering */ 170 int cur_buf_num; 171 172 bool aborting; 173 struct completion aborted; 174 175 /* can we use double-buffering for this conversion operation? */ 176 bool double_buffering; 177 /* num_rows * num_cols */ 178 unsigned int num_tiles; 179 /* next tile to process */ 180 unsigned int next_tile; 181 /* where to place converted tile in dest image */ 182 unsigned int out_tile_map[MAX_TILES]; 183 184 struct list_head list; 185 }; 186 187 struct ipu_image_convert_chan { 188 struct ipu_image_convert_priv *priv; 189 190 enum ipu_ic_task ic_task; 191 const struct ipu_image_convert_dma_chan *dma_ch; 192 193 struct ipu_ic *ic; 194 struct ipuv3_channel *in_chan; 195 struct ipuv3_channel *out_chan; 196 struct ipuv3_channel *rotation_in_chan; 197 struct ipuv3_channel *rotation_out_chan; 198 199 /* the IPU end-of-frame irqs */ 200 int out_eof_irq; 201 int rot_out_eof_irq; 202 203 spinlock_t irqlock; 204 205 /* list of convert contexts */ 206 struct list_head ctx_list; 207 /* queue of conversion runs */ 208 struct list_head pending_q; 209 /* queue of completed runs */ 210 struct list_head done_q; 211 212 /* the current conversion run */ 213 struct ipu_image_convert_run *current_run; 214 }; 215 216 struct ipu_image_convert_priv { 217 struct ipu_image_convert_chan chan[IC_NUM_TASKS]; 218 struct ipu_soc *ipu; 219 }; 220 221 static const struct ipu_image_convert_dma_chan 222 image_convert_dma_chan[IC_NUM_TASKS] = { 223 [IC_TASK_VIEWFINDER] = { 224 .in = IPUV3_CHANNEL_MEM_IC_PRP_VF, 225 .out = IPUV3_CHANNEL_IC_PRP_VF_MEM, 226 .rot_in = IPUV3_CHANNEL_MEM_ROT_VF, 227 .rot_out = IPUV3_CHANNEL_ROT_VF_MEM, 228 .vdi_in_p = IPUV3_CHANNEL_MEM_VDI_PREV, 229 .vdi_in = IPUV3_CHANNEL_MEM_VDI_CUR, 230 .vdi_in_n = IPUV3_CHANNEL_MEM_VDI_NEXT, 231 }, 232 [IC_TASK_POST_PROCESSOR] = { 233 .in = IPUV3_CHANNEL_MEM_IC_PP, 234 .out = IPUV3_CHANNEL_IC_PP_MEM, 235 .rot_in = IPUV3_CHANNEL_MEM_ROT_PP, 236 .rot_out = IPUV3_CHANNEL_ROT_PP_MEM, 237 }, 238 }; 239 240 static const struct ipu_image_pixfmt image_convert_formats[] = { 241 { 242 .fourcc = V4L2_PIX_FMT_RGB565, 243 .bpp = 16, 244 }, { 245 .fourcc = V4L2_PIX_FMT_RGB24, 246 .bpp = 24, 247 }, { 248 .fourcc = V4L2_PIX_FMT_BGR24, 249 .bpp = 24, 250 }, { 251 .fourcc = V4L2_PIX_FMT_RGB32, 252 .bpp = 32, 253 }, { 254 .fourcc = V4L2_PIX_FMT_BGR32, 255 .bpp = 32, 256 }, { 257 .fourcc = V4L2_PIX_FMT_XRGB32, 258 .bpp = 32, 259 }, { 260 .fourcc = V4L2_PIX_FMT_XBGR32, 261 .bpp = 32, 262 }, { 263 .fourcc = V4L2_PIX_FMT_YUYV, 264 .bpp = 16, 265 .uv_width_dec = 2, 266 .uv_height_dec = 1, 267 }, { 268 .fourcc = V4L2_PIX_FMT_UYVY, 269 .bpp = 16, 270 .uv_width_dec = 2, 271 .uv_height_dec = 1, 272 }, { 273 .fourcc = V4L2_PIX_FMT_YUV420, 274 .bpp = 12, 275 .planar = true, 276 .uv_width_dec = 2, 277 .uv_height_dec = 2, 278 }, { 279 .fourcc = V4L2_PIX_FMT_YVU420, 280 .bpp = 12, 281 .planar = true, 282 .uv_width_dec = 2, 283 .uv_height_dec = 2, 284 .uv_swapped = true, 285 }, { 286 .fourcc = V4L2_PIX_FMT_NV12, 287 .bpp = 12, 288 .planar = true, 289 .uv_width_dec = 2, 290 .uv_height_dec = 2, 291 .uv_packed = true, 292 }, { 293 .fourcc = V4L2_PIX_FMT_YUV422P, 294 .bpp = 16, 295 .planar = true, 296 .uv_width_dec = 2, 297 .uv_height_dec = 1, 298 }, { 299 .fourcc = V4L2_PIX_FMT_NV16, 300 .bpp = 16, 301 .planar = true, 302 .uv_width_dec = 2, 303 .uv_height_dec = 1, 304 .uv_packed = true, 305 }, 306 }; 307 308 static const struct ipu_image_pixfmt *get_format(u32 fourcc) 309 { 310 const struct ipu_image_pixfmt *ret = NULL; 311 unsigned int i; 312 313 for (i = 0; i < ARRAY_SIZE(image_convert_formats); i++) { 314 if (image_convert_formats[i].fourcc == fourcc) { 315 ret = &image_convert_formats[i]; 316 break; 317 } 318 } 319 320 return ret; 321 } 322 323 static void dump_format(struct ipu_image_convert_ctx *ctx, 324 struct ipu_image_convert_image *ic_image) 325 { 326 struct ipu_image_convert_chan *chan = ctx->chan; 327 struct ipu_image_convert_priv *priv = chan->priv; 328 329 dev_dbg(priv->ipu->dev, 330 "task %u: ctx %p: %s format: %dx%d (%dx%d tiles), %c%c%c%c\n", 331 chan->ic_task, ctx, 332 ic_image->type == IMAGE_CONVERT_OUT ? "Output" : "Input", 333 ic_image->base.pix.width, ic_image->base.pix.height, 334 ic_image->num_cols, ic_image->num_rows, 335 ic_image->fmt->fourcc & 0xff, 336 (ic_image->fmt->fourcc >> 8) & 0xff, 337 (ic_image->fmt->fourcc >> 16) & 0xff, 338 (ic_image->fmt->fourcc >> 24) & 0xff); 339 } 340 341 int ipu_image_convert_enum_format(int index, u32 *fourcc) 342 { 343 const struct ipu_image_pixfmt *fmt; 344 345 if (index >= (int)ARRAY_SIZE(image_convert_formats)) 346 return -EINVAL; 347 348 /* Format found */ 349 fmt = &image_convert_formats[index]; 350 *fourcc = fmt->fourcc; 351 return 0; 352 } 353 EXPORT_SYMBOL_GPL(ipu_image_convert_enum_format); 354 355 static void free_dma_buf(struct ipu_image_convert_priv *priv, 356 struct ipu_image_convert_dma_buf *buf) 357 { 358 if (buf->virt) 359 dma_free_coherent(priv->ipu->dev, 360 buf->len, buf->virt, buf->phys); 361 buf->virt = NULL; 362 buf->phys = 0; 363 } 364 365 static int alloc_dma_buf(struct ipu_image_convert_priv *priv, 366 struct ipu_image_convert_dma_buf *buf, 367 int size) 368 { 369 buf->len = PAGE_ALIGN(size); 370 buf->virt = dma_alloc_coherent(priv->ipu->dev, buf->len, &buf->phys, 371 GFP_DMA | GFP_KERNEL); 372 if (!buf->virt) { 373 dev_err(priv->ipu->dev, "failed to alloc dma buffer\n"); 374 return -ENOMEM; 375 } 376 377 return 0; 378 } 379 380 static inline int num_stripes(int dim) 381 { 382 if (dim <= 1024) 383 return 1; 384 else if (dim <= 2048) 385 return 2; 386 else 387 return 4; 388 } 389 390 /* 391 * Calculate downsizing coefficients, which are the same for all tiles, 392 * and bilinear resizing coefficients, which are used to find the best 393 * seam positions. 394 */ 395 static int calc_image_resize_coefficients(struct ipu_image_convert_ctx *ctx, 396 struct ipu_image *in, 397 struct ipu_image *out) 398 { 399 u32 downsized_width = in->rect.width; 400 u32 downsized_height = in->rect.height; 401 u32 downsize_coeff_v = 0; 402 u32 downsize_coeff_h = 0; 403 u32 resized_width = out->rect.width; 404 u32 resized_height = out->rect.height; 405 u32 resize_coeff_h; 406 u32 resize_coeff_v; 407 408 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 409 resized_width = out->rect.height; 410 resized_height = out->rect.width; 411 } 412 413 /* Do not let invalid input lead to an endless loop below */ 414 if (WARN_ON(resized_width == 0 || resized_height == 0)) 415 return -EINVAL; 416 417 while (downsized_width >= resized_width * 2) { 418 downsized_width >>= 1; 419 downsize_coeff_h++; 420 } 421 422 while (downsized_height >= resized_height * 2) { 423 downsized_height >>= 1; 424 downsize_coeff_v++; 425 } 426 427 /* 428 * Calculate the bilinear resizing coefficients that could be used if 429 * we were converting with a single tile. The bottom right output pixel 430 * should sample as close as possible to the bottom right input pixel 431 * out of the decimator, but not overshoot it: 432 */ 433 resize_coeff_h = 8192 * (downsized_width - 1) / (resized_width - 1); 434 resize_coeff_v = 8192 * (downsized_height - 1) / (resized_height - 1); 435 436 dev_dbg(ctx->chan->priv->ipu->dev, 437 "%s: hscale: >>%u, *8192/%u vscale: >>%u, *8192/%u, %ux%u tiles\n", 438 __func__, downsize_coeff_h, resize_coeff_h, downsize_coeff_v, 439 resize_coeff_v, ctx->in.num_cols, ctx->in.num_rows); 440 441 if (downsize_coeff_h > 2 || downsize_coeff_v > 2 || 442 resize_coeff_h > 0x3fff || resize_coeff_v > 0x3fff) 443 return -EINVAL; 444 445 ctx->downsize_coeff_h = downsize_coeff_h; 446 ctx->downsize_coeff_v = downsize_coeff_v; 447 ctx->image_resize_coeff_h = resize_coeff_h; 448 ctx->image_resize_coeff_v = resize_coeff_v; 449 450 return 0; 451 } 452 453 #define round_closest(x, y) round_down((x) + (y)/2, (y)) 454 455 /* 456 * Find the best aligned seam position in the inverval [out_start, out_end]. 457 * Rotation and image offsets are out of scope. 458 * 459 * @out_start: start of inverval, must be within 1024 pixels / lines 460 * of out_end 461 * @out_end: end of interval, smaller than or equal to out_edge 462 * @in_edge: input right / bottom edge 463 * @out_edge: output right / bottom edge 464 * @in_align: input alignment, either horizontal 8-byte line start address 465 * alignment, or pixel alignment due to image format 466 * @out_align: output alignment, either horizontal 8-byte line start address 467 * alignment, or pixel alignment due to image format or rotator 468 * block size 469 * @in_burst: horizontal input burst size in case of horizontal flip 470 * @out_burst: horizontal output burst size or rotator block size 471 * @downsize_coeff: downsizing section coefficient 472 * @resize_coeff: main processing section resizing coefficient 473 * @_in_seam: aligned input seam position return value 474 * @_out_seam: aligned output seam position return value 475 */ 476 static void find_best_seam(struct ipu_image_convert_ctx *ctx, 477 unsigned int out_start, 478 unsigned int out_end, 479 unsigned int in_edge, 480 unsigned int out_edge, 481 unsigned int in_align, 482 unsigned int out_align, 483 unsigned int in_burst, 484 unsigned int out_burst, 485 unsigned int downsize_coeff, 486 unsigned int resize_coeff, 487 u32 *_in_seam, 488 u32 *_out_seam) 489 { 490 struct device *dev = ctx->chan->priv->ipu->dev; 491 unsigned int out_pos; 492 /* Input / output seam position candidates */ 493 unsigned int out_seam = 0; 494 unsigned int in_seam = 0; 495 unsigned int min_diff = UINT_MAX; 496 497 /* 498 * Output tiles must start at a multiple of 8 bytes horizontally and 499 * possibly at an even line horizontally depending on the pixel format. 500 * Only consider output aligned positions for the seam. 501 */ 502 out_start = round_up(out_start, out_align); 503 for (out_pos = out_start; out_pos < out_end; out_pos += out_align) { 504 unsigned int in_pos; 505 unsigned int in_pos_aligned; 506 unsigned int abs_diff; 507 508 /* 509 * Tiles in the right row / bottom column may not be allowed to 510 * overshoot horizontally / vertically. out_burst may be the 511 * actual DMA burst size, or the rotator block size. 512 */ 513 if ((out_burst > 1) && (out_edge - out_pos) % out_burst) 514 continue; 515 516 /* 517 * Input sample position, corresponding to out_pos, 19.13 fixed 518 * point. 519 */ 520 in_pos = (out_pos * resize_coeff) << downsize_coeff; 521 /* 522 * The closest input sample position that we could actually 523 * start the input tile at, 19.13 fixed point. 524 */ 525 in_pos_aligned = round_closest(in_pos, 8192U * in_align); 526 527 if ((in_burst > 1) && 528 (in_edge - in_pos_aligned / 8192U) % in_burst) 529 continue; 530 531 if (in_pos < in_pos_aligned) 532 abs_diff = in_pos_aligned - in_pos; 533 else 534 abs_diff = in_pos - in_pos_aligned; 535 536 if (abs_diff < min_diff) { 537 in_seam = in_pos_aligned; 538 out_seam = out_pos; 539 min_diff = abs_diff; 540 } 541 } 542 543 *_out_seam = out_seam; 544 /* Convert 19.13 fixed point to integer seam position */ 545 *_in_seam = DIV_ROUND_CLOSEST(in_seam, 8192U); 546 547 dev_dbg(dev, "%s: out_seam %u(%u) in [%u, %u], in_seam %u(%u) diff %u.%03u\n", 548 __func__, out_seam, out_align, out_start, out_end, 549 *_in_seam, in_align, min_diff / 8192, 550 DIV_ROUND_CLOSEST(min_diff % 8192 * 1000, 8192)); 551 } 552 553 /* 554 * Tile left edges are required to be aligned to multiples of 8 bytes 555 * by the IDMAC. 556 */ 557 static inline u32 tile_left_align(const struct ipu_image_pixfmt *fmt) 558 { 559 if (fmt->planar) 560 return fmt->uv_packed ? 8 : 8 * fmt->uv_width_dec; 561 else 562 return fmt->bpp == 32 ? 2 : fmt->bpp == 16 ? 4 : 8; 563 } 564 565 /* 566 * Tile top edge alignment is only limited by chroma subsampling. 567 */ 568 static inline u32 tile_top_align(const struct ipu_image_pixfmt *fmt) 569 { 570 return fmt->uv_height_dec > 1 ? 2 : 1; 571 } 572 573 static inline u32 tile_width_align(enum ipu_image_convert_type type, 574 const struct ipu_image_pixfmt *fmt, 575 enum ipu_rotate_mode rot_mode) 576 { 577 if (type == IMAGE_CONVERT_IN) { 578 /* 579 * The IC burst reads 8 pixels at a time. Reading beyond the 580 * end of the line is usually acceptable. Those pixels are 581 * ignored, unless the IC has to write the scaled line in 582 * reverse. 583 */ 584 return (!ipu_rot_mode_is_irt(rot_mode) && 585 (rot_mode & IPU_ROT_BIT_HFLIP)) ? 8 : 2; 586 } 587 588 /* 589 * Align to 16x16 pixel blocks for planar 4:2:0 chroma subsampled 590 * formats to guarantee 8-byte aligned line start addresses in the 591 * chroma planes when IRT is used. Align to 8x8 pixel IRT block size 592 * for all other formats. 593 */ 594 return (ipu_rot_mode_is_irt(rot_mode) && 595 fmt->planar && !fmt->uv_packed) ? 596 8 * fmt->uv_width_dec : 8; 597 } 598 599 static inline u32 tile_height_align(enum ipu_image_convert_type type, 600 const struct ipu_image_pixfmt *fmt, 601 enum ipu_rotate_mode rot_mode) 602 { 603 if (type == IMAGE_CONVERT_IN || !ipu_rot_mode_is_irt(rot_mode)) 604 return 2; 605 606 /* 607 * Align to 16x16 pixel blocks for planar 4:2:0 chroma subsampled 608 * formats to guarantee 8-byte aligned line start addresses in the 609 * chroma planes when IRT is used. Align to 8x8 pixel IRT block size 610 * for all other formats. 611 */ 612 return (fmt->planar && !fmt->uv_packed) ? 8 * fmt->uv_width_dec : 8; 613 } 614 615 /* 616 * Fill in left position and width and for all tiles in an input column, and 617 * for all corresponding output tiles. If the 90° rotator is used, the output 618 * tiles are in a row, and output tile top position and height are set. 619 */ 620 static void fill_tile_column(struct ipu_image_convert_ctx *ctx, 621 unsigned int col, 622 struct ipu_image_convert_image *in, 623 unsigned int in_left, unsigned int in_width, 624 struct ipu_image_convert_image *out, 625 unsigned int out_left, unsigned int out_width) 626 { 627 unsigned int row, tile_idx; 628 struct ipu_image_tile *in_tile, *out_tile; 629 630 for (row = 0; row < in->num_rows; row++) { 631 tile_idx = in->num_cols * row + col; 632 in_tile = &in->tile[tile_idx]; 633 out_tile = &out->tile[ctx->out_tile_map[tile_idx]]; 634 635 in_tile->left = in_left; 636 in_tile->width = in_width; 637 638 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 639 out_tile->top = out_left; 640 out_tile->height = out_width; 641 } else { 642 out_tile->left = out_left; 643 out_tile->width = out_width; 644 } 645 } 646 } 647 648 /* 649 * Fill in top position and height and for all tiles in an input row, and 650 * for all corresponding output tiles. If the 90° rotator is used, the output 651 * tiles are in a column, and output tile left position and width are set. 652 */ 653 static void fill_tile_row(struct ipu_image_convert_ctx *ctx, unsigned int row, 654 struct ipu_image_convert_image *in, 655 unsigned int in_top, unsigned int in_height, 656 struct ipu_image_convert_image *out, 657 unsigned int out_top, unsigned int out_height) 658 { 659 unsigned int col, tile_idx; 660 struct ipu_image_tile *in_tile, *out_tile; 661 662 for (col = 0; col < in->num_cols; col++) { 663 tile_idx = in->num_cols * row + col; 664 in_tile = &in->tile[tile_idx]; 665 out_tile = &out->tile[ctx->out_tile_map[tile_idx]]; 666 667 in_tile->top = in_top; 668 in_tile->height = in_height; 669 670 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 671 out_tile->left = out_top; 672 out_tile->width = out_height; 673 } else { 674 out_tile->top = out_top; 675 out_tile->height = out_height; 676 } 677 } 678 } 679 680 /* 681 * Find the best horizontal and vertical seam positions to split into tiles. 682 * Minimize the fractional part of the input sampling position for the 683 * top / left pixels of each tile. 684 */ 685 static void find_seams(struct ipu_image_convert_ctx *ctx, 686 struct ipu_image_convert_image *in, 687 struct ipu_image_convert_image *out) 688 { 689 struct device *dev = ctx->chan->priv->ipu->dev; 690 unsigned int resized_width = out->base.rect.width; 691 unsigned int resized_height = out->base.rect.height; 692 unsigned int col; 693 unsigned int row; 694 unsigned int in_left_align = tile_left_align(in->fmt); 695 unsigned int in_top_align = tile_top_align(in->fmt); 696 unsigned int out_left_align = tile_left_align(out->fmt); 697 unsigned int out_top_align = tile_top_align(out->fmt); 698 unsigned int out_width_align = tile_width_align(out->type, out->fmt, 699 ctx->rot_mode); 700 unsigned int out_height_align = tile_height_align(out->type, out->fmt, 701 ctx->rot_mode); 702 unsigned int in_right = in->base.rect.width; 703 unsigned int in_bottom = in->base.rect.height; 704 unsigned int out_right = out->base.rect.width; 705 unsigned int out_bottom = out->base.rect.height; 706 unsigned int flipped_out_left; 707 unsigned int flipped_out_top; 708 709 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 710 /* Switch width/height and align top left to IRT block size */ 711 resized_width = out->base.rect.height; 712 resized_height = out->base.rect.width; 713 out_left_align = out_height_align; 714 out_top_align = out_width_align; 715 out_width_align = out_left_align; 716 out_height_align = out_top_align; 717 out_right = out->base.rect.height; 718 out_bottom = out->base.rect.width; 719 } 720 721 for (col = in->num_cols - 1; col > 0; col--) { 722 bool allow_in_overshoot = ipu_rot_mode_is_irt(ctx->rot_mode) || 723 !(ctx->rot_mode & IPU_ROT_BIT_HFLIP); 724 bool allow_out_overshoot = (col < in->num_cols - 1) && 725 !(ctx->rot_mode & IPU_ROT_BIT_HFLIP); 726 unsigned int out_start; 727 unsigned int out_end; 728 unsigned int in_left; 729 unsigned int out_left; 730 731 /* 732 * Align input width to burst length if the scaling step flips 733 * horizontally. 734 */ 735 736 /* Start within 1024 pixels of the right edge */ 737 out_start = max_t(int, 0, out_right - 1024); 738 /* End before having to add more columns to the left */ 739 out_end = min_t(unsigned int, out_right, col * 1024); 740 741 find_best_seam(ctx, out_start, out_end, 742 in_right, out_right, 743 in_left_align, out_left_align, 744 allow_in_overshoot ? 1 : 8 /* burst length */, 745 allow_out_overshoot ? 1 : out_width_align, 746 ctx->downsize_coeff_h, ctx->image_resize_coeff_h, 747 &in_left, &out_left); 748 749 if (ctx->rot_mode & IPU_ROT_BIT_HFLIP) 750 flipped_out_left = resized_width - out_right; 751 else 752 flipped_out_left = out_left; 753 754 fill_tile_column(ctx, col, in, in_left, in_right - in_left, 755 out, flipped_out_left, out_right - out_left); 756 757 dev_dbg(dev, "%s: col %u: %u, %u -> %u, %u\n", __func__, col, 758 in_left, in_right - in_left, 759 flipped_out_left, out_right - out_left); 760 761 in_right = in_left; 762 out_right = out_left; 763 } 764 765 flipped_out_left = (ctx->rot_mode & IPU_ROT_BIT_HFLIP) ? 766 resized_width - out_right : 0; 767 768 fill_tile_column(ctx, 0, in, 0, in_right, 769 out, flipped_out_left, out_right); 770 771 dev_dbg(dev, "%s: col 0: 0, %u -> %u, %u\n", __func__, 772 in_right, flipped_out_left, out_right); 773 774 for (row = in->num_rows - 1; row > 0; row--) { 775 bool allow_overshoot = row < in->num_rows - 1; 776 unsigned int out_start; 777 unsigned int out_end; 778 unsigned int in_top; 779 unsigned int out_top; 780 781 /* Start within 1024 lines of the bottom edge */ 782 out_start = max_t(int, 0, out_bottom - 1024); 783 /* End before having to add more rows above */ 784 out_end = min_t(unsigned int, out_bottom, row * 1024); 785 786 find_best_seam(ctx, out_start, out_end, 787 in_bottom, out_bottom, 788 in_top_align, out_top_align, 789 1, allow_overshoot ? 1 : out_height_align, 790 ctx->downsize_coeff_v, ctx->image_resize_coeff_v, 791 &in_top, &out_top); 792 793 if ((ctx->rot_mode & IPU_ROT_BIT_VFLIP) ^ 794 ipu_rot_mode_is_irt(ctx->rot_mode)) 795 flipped_out_top = resized_height - out_bottom; 796 else 797 flipped_out_top = out_top; 798 799 fill_tile_row(ctx, row, in, in_top, in_bottom - in_top, 800 out, flipped_out_top, out_bottom - out_top); 801 802 dev_dbg(dev, "%s: row %u: %u, %u -> %u, %u\n", __func__, row, 803 in_top, in_bottom - in_top, 804 flipped_out_top, out_bottom - out_top); 805 806 in_bottom = in_top; 807 out_bottom = out_top; 808 } 809 810 if ((ctx->rot_mode & IPU_ROT_BIT_VFLIP) ^ 811 ipu_rot_mode_is_irt(ctx->rot_mode)) 812 flipped_out_top = resized_height - out_bottom; 813 else 814 flipped_out_top = 0; 815 816 fill_tile_row(ctx, 0, in, 0, in_bottom, 817 out, flipped_out_top, out_bottom); 818 819 dev_dbg(dev, "%s: row 0: 0, %u -> %u, %u\n", __func__, 820 in_bottom, flipped_out_top, out_bottom); 821 } 822 823 static void calc_tile_dimensions(struct ipu_image_convert_ctx *ctx, 824 struct ipu_image_convert_image *image) 825 { 826 struct ipu_image_convert_chan *chan = ctx->chan; 827 struct ipu_image_convert_priv *priv = chan->priv; 828 unsigned int i; 829 830 for (i = 0; i < ctx->num_tiles; i++) { 831 struct ipu_image_tile *tile; 832 const unsigned int row = i / image->num_cols; 833 const unsigned int col = i % image->num_cols; 834 835 if (image->type == IMAGE_CONVERT_OUT) 836 tile = &image->tile[ctx->out_tile_map[i]]; 837 else 838 tile = &image->tile[i]; 839 840 tile->size = ((tile->height * image->fmt->bpp) >> 3) * 841 tile->width; 842 843 if (image->fmt->planar) { 844 tile->stride = tile->width; 845 tile->rot_stride = tile->height; 846 } else { 847 tile->stride = 848 (image->fmt->bpp * tile->width) >> 3; 849 tile->rot_stride = 850 (image->fmt->bpp * tile->height) >> 3; 851 } 852 853 dev_dbg(priv->ipu->dev, 854 "task %u: ctx %p: %s@[%u,%u]: %ux%u@%u,%u\n", 855 chan->ic_task, ctx, 856 image->type == IMAGE_CONVERT_IN ? "Input" : "Output", 857 row, col, 858 tile->width, tile->height, tile->left, tile->top); 859 } 860 } 861 862 /* 863 * Use the rotation transformation to find the tile coordinates 864 * (row, col) of a tile in the destination frame that corresponds 865 * to the given tile coordinates of a source frame. The destination 866 * coordinate is then converted to a tile index. 867 */ 868 static int transform_tile_index(struct ipu_image_convert_ctx *ctx, 869 int src_row, int src_col) 870 { 871 struct ipu_image_convert_chan *chan = ctx->chan; 872 struct ipu_image_convert_priv *priv = chan->priv; 873 struct ipu_image_convert_image *s_image = &ctx->in; 874 struct ipu_image_convert_image *d_image = &ctx->out; 875 int dst_row, dst_col; 876 877 /* with no rotation it's a 1:1 mapping */ 878 if (ctx->rot_mode == IPU_ROTATE_NONE) 879 return src_row * s_image->num_cols + src_col; 880 881 /* 882 * before doing the transform, first we have to translate 883 * source row,col for an origin in the center of s_image 884 */ 885 src_row = src_row * 2 - (s_image->num_rows - 1); 886 src_col = src_col * 2 - (s_image->num_cols - 1); 887 888 /* do the rotation transform */ 889 if (ctx->rot_mode & IPU_ROT_BIT_90) { 890 dst_col = -src_row; 891 dst_row = src_col; 892 } else { 893 dst_col = src_col; 894 dst_row = src_row; 895 } 896 897 /* apply flip */ 898 if (ctx->rot_mode & IPU_ROT_BIT_HFLIP) 899 dst_col = -dst_col; 900 if (ctx->rot_mode & IPU_ROT_BIT_VFLIP) 901 dst_row = -dst_row; 902 903 dev_dbg(priv->ipu->dev, "task %u: ctx %p: [%d,%d] --> [%d,%d]\n", 904 chan->ic_task, ctx, src_col, src_row, dst_col, dst_row); 905 906 /* 907 * finally translate dest row,col using an origin in upper 908 * left of d_image 909 */ 910 dst_row += d_image->num_rows - 1; 911 dst_col += d_image->num_cols - 1; 912 dst_row /= 2; 913 dst_col /= 2; 914 915 return dst_row * d_image->num_cols + dst_col; 916 } 917 918 /* 919 * Fill the out_tile_map[] with transformed destination tile indeces. 920 */ 921 static void calc_out_tile_map(struct ipu_image_convert_ctx *ctx) 922 { 923 struct ipu_image_convert_image *s_image = &ctx->in; 924 unsigned int row, col, tile = 0; 925 926 for (row = 0; row < s_image->num_rows; row++) { 927 for (col = 0; col < s_image->num_cols; col++) { 928 ctx->out_tile_map[tile] = 929 transform_tile_index(ctx, row, col); 930 tile++; 931 } 932 } 933 } 934 935 static int calc_tile_offsets_planar(struct ipu_image_convert_ctx *ctx, 936 struct ipu_image_convert_image *image) 937 { 938 struct ipu_image_convert_chan *chan = ctx->chan; 939 struct ipu_image_convert_priv *priv = chan->priv; 940 const struct ipu_image_pixfmt *fmt = image->fmt; 941 unsigned int row, col, tile = 0; 942 u32 H, top, y_stride, uv_stride; 943 u32 uv_row_off, uv_col_off, uv_off, u_off, v_off, tmp; 944 u32 y_row_off, y_col_off, y_off; 945 u32 y_size, uv_size; 946 947 /* setup some convenience vars */ 948 H = image->base.pix.height; 949 950 y_stride = image->stride; 951 uv_stride = y_stride / fmt->uv_width_dec; 952 if (fmt->uv_packed) 953 uv_stride *= 2; 954 955 y_size = H * y_stride; 956 uv_size = y_size / (fmt->uv_width_dec * fmt->uv_height_dec); 957 958 for (row = 0; row < image->num_rows; row++) { 959 top = image->tile[tile].top; 960 y_row_off = top * y_stride; 961 uv_row_off = (top * uv_stride) / fmt->uv_height_dec; 962 963 for (col = 0; col < image->num_cols; col++) { 964 y_col_off = image->tile[tile].left; 965 uv_col_off = y_col_off / fmt->uv_width_dec; 966 if (fmt->uv_packed) 967 uv_col_off *= 2; 968 969 y_off = y_row_off + y_col_off; 970 uv_off = uv_row_off + uv_col_off; 971 972 u_off = y_size - y_off + uv_off; 973 v_off = (fmt->uv_packed) ? 0 : u_off + uv_size; 974 if (fmt->uv_swapped) { 975 tmp = u_off; 976 u_off = v_off; 977 v_off = tmp; 978 } 979 980 image->tile[tile].offset = y_off; 981 image->tile[tile].u_off = u_off; 982 image->tile[tile++].v_off = v_off; 983 984 if ((y_off & 0x7) || (u_off & 0x7) || (v_off & 0x7)) { 985 dev_err(priv->ipu->dev, 986 "task %u: ctx %p: %s@[%d,%d]: " 987 "y_off %08x, u_off %08x, v_off %08x\n", 988 chan->ic_task, ctx, 989 image->type == IMAGE_CONVERT_IN ? 990 "Input" : "Output", row, col, 991 y_off, u_off, v_off); 992 return -EINVAL; 993 } 994 } 995 } 996 997 return 0; 998 } 999 1000 static int calc_tile_offsets_packed(struct ipu_image_convert_ctx *ctx, 1001 struct ipu_image_convert_image *image) 1002 { 1003 struct ipu_image_convert_chan *chan = ctx->chan; 1004 struct ipu_image_convert_priv *priv = chan->priv; 1005 const struct ipu_image_pixfmt *fmt = image->fmt; 1006 unsigned int row, col, tile = 0; 1007 u32 bpp, stride, offset; 1008 u32 row_off, col_off; 1009 1010 /* setup some convenience vars */ 1011 stride = image->stride; 1012 bpp = fmt->bpp; 1013 1014 for (row = 0; row < image->num_rows; row++) { 1015 row_off = image->tile[tile].top * stride; 1016 1017 for (col = 0; col < image->num_cols; col++) { 1018 col_off = (image->tile[tile].left * bpp) >> 3; 1019 1020 offset = row_off + col_off; 1021 1022 image->tile[tile].offset = offset; 1023 image->tile[tile].u_off = 0; 1024 image->tile[tile++].v_off = 0; 1025 1026 if (offset & 0x7) { 1027 dev_err(priv->ipu->dev, 1028 "task %u: ctx %p: %s@[%d,%d]: " 1029 "phys %08x\n", 1030 chan->ic_task, ctx, 1031 image->type == IMAGE_CONVERT_IN ? 1032 "Input" : "Output", row, col, 1033 row_off + col_off); 1034 return -EINVAL; 1035 } 1036 } 1037 } 1038 1039 return 0; 1040 } 1041 1042 static int calc_tile_offsets(struct ipu_image_convert_ctx *ctx, 1043 struct ipu_image_convert_image *image) 1044 { 1045 if (image->fmt->planar) 1046 return calc_tile_offsets_planar(ctx, image); 1047 1048 return calc_tile_offsets_packed(ctx, image); 1049 } 1050 1051 /* 1052 * Calculate the resizing ratio for the IC main processing section given input 1053 * size, fixed downsizing coefficient, and output size. 1054 * Either round to closest for the next tile's first pixel to minimize seams 1055 * and distortion (for all but right column / bottom row), or round down to 1056 * avoid sampling beyond the edges of the input image for this tile's last 1057 * pixel. 1058 * Returns the resizing coefficient, resizing ratio is 8192.0 / resize_coeff. 1059 */ 1060 static u32 calc_resize_coeff(u32 input_size, u32 downsize_coeff, 1061 u32 output_size, bool allow_overshoot) 1062 { 1063 u32 downsized = input_size >> downsize_coeff; 1064 1065 if (allow_overshoot) 1066 return DIV_ROUND_CLOSEST(8192 * downsized, output_size); 1067 else 1068 return 8192 * (downsized - 1) / (output_size - 1); 1069 } 1070 1071 /* 1072 * Slightly modify resize coefficients per tile to hide the bilinear 1073 * interpolator reset at tile borders, shifting the right / bottom edge 1074 * by up to a half input pixel. This removes noticeable seams between 1075 * tiles at higher upscaling factors. 1076 */ 1077 static void calc_tile_resize_coefficients(struct ipu_image_convert_ctx *ctx) 1078 { 1079 struct ipu_image_convert_chan *chan = ctx->chan; 1080 struct ipu_image_convert_priv *priv = chan->priv; 1081 struct ipu_image_tile *in_tile, *out_tile; 1082 unsigned int col, row, tile_idx; 1083 unsigned int last_output; 1084 1085 for (col = 0; col < ctx->in.num_cols; col++) { 1086 bool closest = (col < ctx->in.num_cols - 1) && 1087 !(ctx->rot_mode & IPU_ROT_BIT_HFLIP); 1088 u32 resized_width; 1089 u32 resize_coeff_h; 1090 1091 tile_idx = col; 1092 in_tile = &ctx->in.tile[tile_idx]; 1093 out_tile = &ctx->out.tile[ctx->out_tile_map[tile_idx]]; 1094 1095 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1096 resized_width = out_tile->height; 1097 else 1098 resized_width = out_tile->width; 1099 1100 resize_coeff_h = calc_resize_coeff(in_tile->width, 1101 ctx->downsize_coeff_h, 1102 resized_width, closest); 1103 1104 dev_dbg(priv->ipu->dev, "%s: column %u hscale: *8192/%u\n", 1105 __func__, col, resize_coeff_h); 1106 1107 1108 for (row = 0; row < ctx->in.num_rows; row++) { 1109 tile_idx = row * ctx->in.num_cols + col; 1110 in_tile = &ctx->in.tile[tile_idx]; 1111 out_tile = &ctx->out.tile[ctx->out_tile_map[tile_idx]]; 1112 1113 /* 1114 * With the horizontal scaling factor known, round up 1115 * resized width (output width or height) to burst size. 1116 */ 1117 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1118 out_tile->height = round_up(resized_width, 8); 1119 else 1120 out_tile->width = round_up(resized_width, 8); 1121 1122 /* 1123 * Calculate input width from the last accessed input 1124 * pixel given resized width and scaling coefficients. 1125 * Round up to burst size. 1126 */ 1127 last_output = round_up(resized_width, 8) - 1; 1128 if (closest) 1129 last_output++; 1130 in_tile->width = round_up( 1131 (DIV_ROUND_UP(last_output * resize_coeff_h, 1132 8192) + 1) 1133 << ctx->downsize_coeff_h, 8); 1134 } 1135 1136 ctx->resize_coeffs_h[col] = resize_coeff_h; 1137 } 1138 1139 for (row = 0; row < ctx->in.num_rows; row++) { 1140 bool closest = (row < ctx->in.num_rows - 1) && 1141 !(ctx->rot_mode & IPU_ROT_BIT_VFLIP); 1142 u32 resized_height; 1143 u32 resize_coeff_v; 1144 1145 tile_idx = row * ctx->in.num_cols; 1146 in_tile = &ctx->in.tile[tile_idx]; 1147 out_tile = &ctx->out.tile[ctx->out_tile_map[tile_idx]]; 1148 1149 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1150 resized_height = out_tile->width; 1151 else 1152 resized_height = out_tile->height; 1153 1154 resize_coeff_v = calc_resize_coeff(in_tile->height, 1155 ctx->downsize_coeff_v, 1156 resized_height, closest); 1157 1158 dev_dbg(priv->ipu->dev, "%s: row %u vscale: *8192/%u\n", 1159 __func__, row, resize_coeff_v); 1160 1161 for (col = 0; col < ctx->in.num_cols; col++) { 1162 tile_idx = row * ctx->in.num_cols + col; 1163 in_tile = &ctx->in.tile[tile_idx]; 1164 out_tile = &ctx->out.tile[ctx->out_tile_map[tile_idx]]; 1165 1166 /* 1167 * With the vertical scaling factor known, round up 1168 * resized height (output width or height) to IDMAC 1169 * limitations. 1170 */ 1171 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1172 out_tile->width = round_up(resized_height, 2); 1173 else 1174 out_tile->height = round_up(resized_height, 2); 1175 1176 /* 1177 * Calculate input width from the last accessed input 1178 * pixel given resized height and scaling coefficients. 1179 * Align to IDMAC restrictions. 1180 */ 1181 last_output = round_up(resized_height, 2) - 1; 1182 if (closest) 1183 last_output++; 1184 in_tile->height = round_up( 1185 (DIV_ROUND_UP(last_output * resize_coeff_v, 1186 8192) + 1) 1187 << ctx->downsize_coeff_v, 2); 1188 } 1189 1190 ctx->resize_coeffs_v[row] = resize_coeff_v; 1191 } 1192 } 1193 1194 /* 1195 * return the number of runs in given queue (pending_q or done_q) 1196 * for this context. hold irqlock when calling. 1197 */ 1198 static int get_run_count(struct ipu_image_convert_ctx *ctx, 1199 struct list_head *q) 1200 { 1201 struct ipu_image_convert_run *run; 1202 int count = 0; 1203 1204 lockdep_assert_held(&ctx->chan->irqlock); 1205 1206 list_for_each_entry(run, q, list) { 1207 if (run->ctx == ctx) 1208 count++; 1209 } 1210 1211 return count; 1212 } 1213 1214 static void convert_stop(struct ipu_image_convert_run *run) 1215 { 1216 struct ipu_image_convert_ctx *ctx = run->ctx; 1217 struct ipu_image_convert_chan *chan = ctx->chan; 1218 struct ipu_image_convert_priv *priv = chan->priv; 1219 1220 dev_dbg(priv->ipu->dev, "%s: task %u: stopping ctx %p run %p\n", 1221 __func__, chan->ic_task, ctx, run); 1222 1223 /* disable IC tasks and the channels */ 1224 ipu_ic_task_disable(chan->ic); 1225 ipu_idmac_disable_channel(chan->in_chan); 1226 ipu_idmac_disable_channel(chan->out_chan); 1227 1228 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1229 ipu_idmac_disable_channel(chan->rotation_in_chan); 1230 ipu_idmac_disable_channel(chan->rotation_out_chan); 1231 ipu_idmac_unlink(chan->out_chan, chan->rotation_in_chan); 1232 } 1233 1234 ipu_ic_disable(chan->ic); 1235 } 1236 1237 static void init_idmac_channel(struct ipu_image_convert_ctx *ctx, 1238 struct ipuv3_channel *channel, 1239 struct ipu_image_convert_image *image, 1240 enum ipu_rotate_mode rot_mode, 1241 bool rot_swap_width_height, 1242 unsigned int tile) 1243 { 1244 struct ipu_image_convert_chan *chan = ctx->chan; 1245 unsigned int burst_size; 1246 u32 width, height, stride; 1247 dma_addr_t addr0, addr1 = 0; 1248 struct ipu_image tile_image; 1249 unsigned int tile_idx[2]; 1250 1251 if (image->type == IMAGE_CONVERT_OUT) { 1252 tile_idx[0] = ctx->out_tile_map[tile]; 1253 tile_idx[1] = ctx->out_tile_map[1]; 1254 } else { 1255 tile_idx[0] = tile; 1256 tile_idx[1] = 1; 1257 } 1258 1259 if (rot_swap_width_height) { 1260 width = image->tile[tile_idx[0]].height; 1261 height = image->tile[tile_idx[0]].width; 1262 stride = image->tile[tile_idx[0]].rot_stride; 1263 addr0 = ctx->rot_intermediate[0].phys; 1264 if (ctx->double_buffering) 1265 addr1 = ctx->rot_intermediate[1].phys; 1266 } else { 1267 width = image->tile[tile_idx[0]].width; 1268 height = image->tile[tile_idx[0]].height; 1269 stride = image->stride; 1270 addr0 = image->base.phys0 + 1271 image->tile[tile_idx[0]].offset; 1272 if (ctx->double_buffering) 1273 addr1 = image->base.phys0 + 1274 image->tile[tile_idx[1]].offset; 1275 } 1276 1277 ipu_cpmem_zero(channel); 1278 1279 memset(&tile_image, 0, sizeof(tile_image)); 1280 tile_image.pix.width = tile_image.rect.width = width; 1281 tile_image.pix.height = tile_image.rect.height = height; 1282 tile_image.pix.bytesperline = stride; 1283 tile_image.pix.pixelformat = image->fmt->fourcc; 1284 tile_image.phys0 = addr0; 1285 tile_image.phys1 = addr1; 1286 if (image->fmt->planar && !rot_swap_width_height) { 1287 tile_image.u_offset = image->tile[tile_idx[0]].u_off; 1288 tile_image.v_offset = image->tile[tile_idx[0]].v_off; 1289 } 1290 1291 ipu_cpmem_set_image(channel, &tile_image); 1292 1293 if (rot_mode) 1294 ipu_cpmem_set_rotation(channel, rot_mode); 1295 1296 if (channel == chan->rotation_in_chan || 1297 channel == chan->rotation_out_chan) { 1298 burst_size = 8; 1299 ipu_cpmem_set_block_mode(channel); 1300 } else 1301 burst_size = (width % 16) ? 8 : 16; 1302 1303 ipu_cpmem_set_burstsize(channel, burst_size); 1304 1305 ipu_ic_task_idma_init(chan->ic, channel, width, height, 1306 burst_size, rot_mode); 1307 1308 /* 1309 * Setting a non-zero AXI ID collides with the PRG AXI snooping, so 1310 * only do this when there is no PRG present. 1311 */ 1312 if (!channel->ipu->prg_priv) 1313 ipu_cpmem_set_axi_id(channel, 1); 1314 1315 ipu_idmac_set_double_buffer(channel, ctx->double_buffering); 1316 } 1317 1318 static int convert_start(struct ipu_image_convert_run *run, unsigned int tile) 1319 { 1320 struct ipu_image_convert_ctx *ctx = run->ctx; 1321 struct ipu_image_convert_chan *chan = ctx->chan; 1322 struct ipu_image_convert_priv *priv = chan->priv; 1323 struct ipu_image_convert_image *s_image = &ctx->in; 1324 struct ipu_image_convert_image *d_image = &ctx->out; 1325 enum ipu_color_space src_cs, dest_cs; 1326 unsigned int dst_tile = ctx->out_tile_map[tile]; 1327 unsigned int dest_width, dest_height; 1328 unsigned int col, row; 1329 u32 rsc; 1330 int ret; 1331 1332 dev_dbg(priv->ipu->dev, "%s: task %u: starting ctx %p run %p tile %u -> %u\n", 1333 __func__, chan->ic_task, ctx, run, tile, dst_tile); 1334 1335 src_cs = ipu_pixelformat_to_colorspace(s_image->fmt->fourcc); 1336 dest_cs = ipu_pixelformat_to_colorspace(d_image->fmt->fourcc); 1337 1338 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1339 /* swap width/height for resizer */ 1340 dest_width = d_image->tile[dst_tile].height; 1341 dest_height = d_image->tile[dst_tile].width; 1342 } else { 1343 dest_width = d_image->tile[dst_tile].width; 1344 dest_height = d_image->tile[dst_tile].height; 1345 } 1346 1347 row = tile / s_image->num_cols; 1348 col = tile % s_image->num_cols; 1349 1350 rsc = (ctx->downsize_coeff_v << 30) | 1351 (ctx->resize_coeffs_v[row] << 16) | 1352 (ctx->downsize_coeff_h << 14) | 1353 (ctx->resize_coeffs_h[col]); 1354 1355 dev_dbg(priv->ipu->dev, "%s: %ux%u -> %ux%u (rsc = 0x%x)\n", 1356 __func__, s_image->tile[tile].width, 1357 s_image->tile[tile].height, dest_width, dest_height, rsc); 1358 1359 /* setup the IC resizer and CSC */ 1360 ret = ipu_ic_task_init_rsc(chan->ic, 1361 s_image->tile[tile].width, 1362 s_image->tile[tile].height, 1363 dest_width, 1364 dest_height, 1365 src_cs, dest_cs, 1366 rsc); 1367 if (ret) { 1368 dev_err(priv->ipu->dev, "ipu_ic_task_init failed, %d\n", ret); 1369 return ret; 1370 } 1371 1372 /* init the source MEM-->IC PP IDMAC channel */ 1373 init_idmac_channel(ctx, chan->in_chan, s_image, 1374 IPU_ROTATE_NONE, false, tile); 1375 1376 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1377 /* init the IC PP-->MEM IDMAC channel */ 1378 init_idmac_channel(ctx, chan->out_chan, d_image, 1379 IPU_ROTATE_NONE, true, tile); 1380 1381 /* init the MEM-->IC PP ROT IDMAC channel */ 1382 init_idmac_channel(ctx, chan->rotation_in_chan, d_image, 1383 ctx->rot_mode, true, tile); 1384 1385 /* init the destination IC PP ROT-->MEM IDMAC channel */ 1386 init_idmac_channel(ctx, chan->rotation_out_chan, d_image, 1387 IPU_ROTATE_NONE, false, tile); 1388 1389 /* now link IC PP-->MEM to MEM-->IC PP ROT */ 1390 ipu_idmac_link(chan->out_chan, chan->rotation_in_chan); 1391 } else { 1392 /* init the destination IC PP-->MEM IDMAC channel */ 1393 init_idmac_channel(ctx, chan->out_chan, d_image, 1394 ctx->rot_mode, false, tile); 1395 } 1396 1397 /* enable the IC */ 1398 ipu_ic_enable(chan->ic); 1399 1400 /* set buffers ready */ 1401 ipu_idmac_select_buffer(chan->in_chan, 0); 1402 ipu_idmac_select_buffer(chan->out_chan, 0); 1403 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1404 ipu_idmac_select_buffer(chan->rotation_out_chan, 0); 1405 if (ctx->double_buffering) { 1406 ipu_idmac_select_buffer(chan->in_chan, 1); 1407 ipu_idmac_select_buffer(chan->out_chan, 1); 1408 if (ipu_rot_mode_is_irt(ctx->rot_mode)) 1409 ipu_idmac_select_buffer(chan->rotation_out_chan, 1); 1410 } 1411 1412 /* enable the channels! */ 1413 ipu_idmac_enable_channel(chan->in_chan); 1414 ipu_idmac_enable_channel(chan->out_chan); 1415 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1416 ipu_idmac_enable_channel(chan->rotation_in_chan); 1417 ipu_idmac_enable_channel(chan->rotation_out_chan); 1418 } 1419 1420 ipu_ic_task_enable(chan->ic); 1421 1422 ipu_cpmem_dump(chan->in_chan); 1423 ipu_cpmem_dump(chan->out_chan); 1424 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1425 ipu_cpmem_dump(chan->rotation_in_chan); 1426 ipu_cpmem_dump(chan->rotation_out_chan); 1427 } 1428 1429 ipu_dump(priv->ipu); 1430 1431 return 0; 1432 } 1433 1434 /* hold irqlock when calling */ 1435 static int do_run(struct ipu_image_convert_run *run) 1436 { 1437 struct ipu_image_convert_ctx *ctx = run->ctx; 1438 struct ipu_image_convert_chan *chan = ctx->chan; 1439 1440 lockdep_assert_held(&chan->irqlock); 1441 1442 ctx->in.base.phys0 = run->in_phys; 1443 ctx->out.base.phys0 = run->out_phys; 1444 1445 ctx->cur_buf_num = 0; 1446 ctx->next_tile = 1; 1447 1448 /* remove run from pending_q and set as current */ 1449 list_del(&run->list); 1450 chan->current_run = run; 1451 1452 return convert_start(run, 0); 1453 } 1454 1455 /* hold irqlock when calling */ 1456 static void run_next(struct ipu_image_convert_chan *chan) 1457 { 1458 struct ipu_image_convert_priv *priv = chan->priv; 1459 struct ipu_image_convert_run *run, *tmp; 1460 int ret; 1461 1462 lockdep_assert_held(&chan->irqlock); 1463 1464 list_for_each_entry_safe(run, tmp, &chan->pending_q, list) { 1465 /* skip contexts that are aborting */ 1466 if (run->ctx->aborting) { 1467 dev_dbg(priv->ipu->dev, 1468 "%s: task %u: skipping aborting ctx %p run %p\n", 1469 __func__, chan->ic_task, run->ctx, run); 1470 continue; 1471 } 1472 1473 ret = do_run(run); 1474 if (!ret) 1475 break; 1476 1477 /* 1478 * something went wrong with start, add the run 1479 * to done q and continue to the next run in the 1480 * pending q. 1481 */ 1482 run->status = ret; 1483 list_add_tail(&run->list, &chan->done_q); 1484 chan->current_run = NULL; 1485 } 1486 } 1487 1488 static void empty_done_q(struct ipu_image_convert_chan *chan) 1489 { 1490 struct ipu_image_convert_priv *priv = chan->priv; 1491 struct ipu_image_convert_run *run; 1492 unsigned long flags; 1493 1494 spin_lock_irqsave(&chan->irqlock, flags); 1495 1496 while (!list_empty(&chan->done_q)) { 1497 run = list_entry(chan->done_q.next, 1498 struct ipu_image_convert_run, 1499 list); 1500 1501 list_del(&run->list); 1502 1503 dev_dbg(priv->ipu->dev, 1504 "%s: task %u: completing ctx %p run %p with %d\n", 1505 __func__, chan->ic_task, run->ctx, run, run->status); 1506 1507 /* call the completion callback and free the run */ 1508 spin_unlock_irqrestore(&chan->irqlock, flags); 1509 run->ctx->complete(run, run->ctx->complete_context); 1510 spin_lock_irqsave(&chan->irqlock, flags); 1511 } 1512 1513 spin_unlock_irqrestore(&chan->irqlock, flags); 1514 } 1515 1516 /* 1517 * the bottom half thread clears out the done_q, calling the 1518 * completion handler for each. 1519 */ 1520 static irqreturn_t do_bh(int irq, void *dev_id) 1521 { 1522 struct ipu_image_convert_chan *chan = dev_id; 1523 struct ipu_image_convert_priv *priv = chan->priv; 1524 struct ipu_image_convert_ctx *ctx; 1525 unsigned long flags; 1526 1527 dev_dbg(priv->ipu->dev, "%s: task %u: enter\n", __func__, 1528 chan->ic_task); 1529 1530 empty_done_q(chan); 1531 1532 spin_lock_irqsave(&chan->irqlock, flags); 1533 1534 /* 1535 * the done_q is cleared out, signal any contexts 1536 * that are aborting that abort can complete. 1537 */ 1538 list_for_each_entry(ctx, &chan->ctx_list, list) { 1539 if (ctx->aborting) { 1540 dev_dbg(priv->ipu->dev, 1541 "%s: task %u: signaling abort for ctx %p\n", 1542 __func__, chan->ic_task, ctx); 1543 complete_all(&ctx->aborted); 1544 } 1545 } 1546 1547 spin_unlock_irqrestore(&chan->irqlock, flags); 1548 1549 dev_dbg(priv->ipu->dev, "%s: task %u: exit\n", __func__, 1550 chan->ic_task); 1551 1552 return IRQ_HANDLED; 1553 } 1554 1555 static bool ic_settings_changed(struct ipu_image_convert_ctx *ctx) 1556 { 1557 unsigned int cur_tile = ctx->next_tile - 1; 1558 unsigned int next_tile = ctx->next_tile; 1559 1560 if (ctx->resize_coeffs_h[cur_tile % ctx->in.num_cols] != 1561 ctx->resize_coeffs_h[next_tile % ctx->in.num_cols] || 1562 ctx->resize_coeffs_v[cur_tile / ctx->in.num_cols] != 1563 ctx->resize_coeffs_v[next_tile / ctx->in.num_cols] || 1564 ctx->in.tile[cur_tile].width != ctx->in.tile[next_tile].width || 1565 ctx->in.tile[cur_tile].height != ctx->in.tile[next_tile].height || 1566 ctx->out.tile[cur_tile].width != ctx->out.tile[next_tile].width || 1567 ctx->out.tile[cur_tile].height != ctx->out.tile[next_tile].height) 1568 return true; 1569 1570 return false; 1571 } 1572 1573 /* hold irqlock when calling */ 1574 static irqreturn_t do_irq(struct ipu_image_convert_run *run) 1575 { 1576 struct ipu_image_convert_ctx *ctx = run->ctx; 1577 struct ipu_image_convert_chan *chan = ctx->chan; 1578 struct ipu_image_tile *src_tile, *dst_tile; 1579 struct ipu_image_convert_image *s_image = &ctx->in; 1580 struct ipu_image_convert_image *d_image = &ctx->out; 1581 struct ipuv3_channel *outch; 1582 unsigned int dst_idx; 1583 1584 lockdep_assert_held(&chan->irqlock); 1585 1586 outch = ipu_rot_mode_is_irt(ctx->rot_mode) ? 1587 chan->rotation_out_chan : chan->out_chan; 1588 1589 /* 1590 * It is difficult to stop the channel DMA before the channels 1591 * enter the paused state. Without double-buffering the channels 1592 * are always in a paused state when the EOF irq occurs, so it 1593 * is safe to stop the channels now. For double-buffering we 1594 * just ignore the abort until the operation completes, when it 1595 * is safe to shut down. 1596 */ 1597 if (ctx->aborting && !ctx->double_buffering) { 1598 convert_stop(run); 1599 run->status = -EIO; 1600 goto done; 1601 } 1602 1603 if (ctx->next_tile == ctx->num_tiles) { 1604 /* 1605 * the conversion is complete 1606 */ 1607 convert_stop(run); 1608 run->status = 0; 1609 goto done; 1610 } 1611 1612 /* 1613 * not done, place the next tile buffers. 1614 */ 1615 if (!ctx->double_buffering) { 1616 if (ic_settings_changed(ctx)) { 1617 convert_stop(run); 1618 convert_start(run, ctx->next_tile); 1619 } else { 1620 src_tile = &s_image->tile[ctx->next_tile]; 1621 dst_idx = ctx->out_tile_map[ctx->next_tile]; 1622 dst_tile = &d_image->tile[dst_idx]; 1623 1624 ipu_cpmem_set_buffer(chan->in_chan, 0, 1625 s_image->base.phys0 + 1626 src_tile->offset); 1627 ipu_cpmem_set_buffer(outch, 0, 1628 d_image->base.phys0 + 1629 dst_tile->offset); 1630 if (s_image->fmt->planar) 1631 ipu_cpmem_set_uv_offset(chan->in_chan, 1632 src_tile->u_off, 1633 src_tile->v_off); 1634 if (d_image->fmt->planar) 1635 ipu_cpmem_set_uv_offset(outch, 1636 dst_tile->u_off, 1637 dst_tile->v_off); 1638 1639 ipu_idmac_select_buffer(chan->in_chan, 0); 1640 ipu_idmac_select_buffer(outch, 0); 1641 } 1642 } else if (ctx->next_tile < ctx->num_tiles - 1) { 1643 1644 src_tile = &s_image->tile[ctx->next_tile + 1]; 1645 dst_idx = ctx->out_tile_map[ctx->next_tile + 1]; 1646 dst_tile = &d_image->tile[dst_idx]; 1647 1648 ipu_cpmem_set_buffer(chan->in_chan, ctx->cur_buf_num, 1649 s_image->base.phys0 + src_tile->offset); 1650 ipu_cpmem_set_buffer(outch, ctx->cur_buf_num, 1651 d_image->base.phys0 + dst_tile->offset); 1652 1653 ipu_idmac_select_buffer(chan->in_chan, ctx->cur_buf_num); 1654 ipu_idmac_select_buffer(outch, ctx->cur_buf_num); 1655 1656 ctx->cur_buf_num ^= 1; 1657 } 1658 1659 ctx->next_tile++; 1660 return IRQ_HANDLED; 1661 done: 1662 list_add_tail(&run->list, &chan->done_q); 1663 chan->current_run = NULL; 1664 run_next(chan); 1665 return IRQ_WAKE_THREAD; 1666 } 1667 1668 static irqreturn_t norotate_irq(int irq, void *data) 1669 { 1670 struct ipu_image_convert_chan *chan = data; 1671 struct ipu_image_convert_ctx *ctx; 1672 struct ipu_image_convert_run *run; 1673 unsigned long flags; 1674 irqreturn_t ret; 1675 1676 spin_lock_irqsave(&chan->irqlock, flags); 1677 1678 /* get current run and its context */ 1679 run = chan->current_run; 1680 if (!run) { 1681 ret = IRQ_NONE; 1682 goto out; 1683 } 1684 1685 ctx = run->ctx; 1686 1687 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 1688 /* this is a rotation operation, just ignore */ 1689 spin_unlock_irqrestore(&chan->irqlock, flags); 1690 return IRQ_HANDLED; 1691 } 1692 1693 ret = do_irq(run); 1694 out: 1695 spin_unlock_irqrestore(&chan->irqlock, flags); 1696 return ret; 1697 } 1698 1699 static irqreturn_t rotate_irq(int irq, void *data) 1700 { 1701 struct ipu_image_convert_chan *chan = data; 1702 struct ipu_image_convert_priv *priv = chan->priv; 1703 struct ipu_image_convert_ctx *ctx; 1704 struct ipu_image_convert_run *run; 1705 unsigned long flags; 1706 irqreturn_t ret; 1707 1708 spin_lock_irqsave(&chan->irqlock, flags); 1709 1710 /* get current run and its context */ 1711 run = chan->current_run; 1712 if (!run) { 1713 ret = IRQ_NONE; 1714 goto out; 1715 } 1716 1717 ctx = run->ctx; 1718 1719 if (!ipu_rot_mode_is_irt(ctx->rot_mode)) { 1720 /* this was NOT a rotation operation, shouldn't happen */ 1721 dev_err(priv->ipu->dev, "Unexpected rotation interrupt\n"); 1722 spin_unlock_irqrestore(&chan->irqlock, flags); 1723 return IRQ_HANDLED; 1724 } 1725 1726 ret = do_irq(run); 1727 out: 1728 spin_unlock_irqrestore(&chan->irqlock, flags); 1729 return ret; 1730 } 1731 1732 /* 1733 * try to force the completion of runs for this ctx. Called when 1734 * abort wait times out in ipu_image_convert_abort(). 1735 */ 1736 static void force_abort(struct ipu_image_convert_ctx *ctx) 1737 { 1738 struct ipu_image_convert_chan *chan = ctx->chan; 1739 struct ipu_image_convert_run *run; 1740 unsigned long flags; 1741 1742 spin_lock_irqsave(&chan->irqlock, flags); 1743 1744 run = chan->current_run; 1745 if (run && run->ctx == ctx) { 1746 convert_stop(run); 1747 run->status = -EIO; 1748 list_add_tail(&run->list, &chan->done_q); 1749 chan->current_run = NULL; 1750 run_next(chan); 1751 } 1752 1753 spin_unlock_irqrestore(&chan->irqlock, flags); 1754 1755 empty_done_q(chan); 1756 } 1757 1758 static void release_ipu_resources(struct ipu_image_convert_chan *chan) 1759 { 1760 if (chan->out_eof_irq >= 0) 1761 free_irq(chan->out_eof_irq, chan); 1762 if (chan->rot_out_eof_irq >= 0) 1763 free_irq(chan->rot_out_eof_irq, chan); 1764 1765 if (!IS_ERR_OR_NULL(chan->in_chan)) 1766 ipu_idmac_put(chan->in_chan); 1767 if (!IS_ERR_OR_NULL(chan->out_chan)) 1768 ipu_idmac_put(chan->out_chan); 1769 if (!IS_ERR_OR_NULL(chan->rotation_in_chan)) 1770 ipu_idmac_put(chan->rotation_in_chan); 1771 if (!IS_ERR_OR_NULL(chan->rotation_out_chan)) 1772 ipu_idmac_put(chan->rotation_out_chan); 1773 if (!IS_ERR_OR_NULL(chan->ic)) 1774 ipu_ic_put(chan->ic); 1775 1776 chan->in_chan = chan->out_chan = chan->rotation_in_chan = 1777 chan->rotation_out_chan = NULL; 1778 chan->out_eof_irq = chan->rot_out_eof_irq = -1; 1779 } 1780 1781 static int get_ipu_resources(struct ipu_image_convert_chan *chan) 1782 { 1783 const struct ipu_image_convert_dma_chan *dma = chan->dma_ch; 1784 struct ipu_image_convert_priv *priv = chan->priv; 1785 int ret; 1786 1787 /* get IC */ 1788 chan->ic = ipu_ic_get(priv->ipu, chan->ic_task); 1789 if (IS_ERR(chan->ic)) { 1790 dev_err(priv->ipu->dev, "could not acquire IC\n"); 1791 ret = PTR_ERR(chan->ic); 1792 goto err; 1793 } 1794 1795 /* get IDMAC channels */ 1796 chan->in_chan = ipu_idmac_get(priv->ipu, dma->in); 1797 chan->out_chan = ipu_idmac_get(priv->ipu, dma->out); 1798 if (IS_ERR(chan->in_chan) || IS_ERR(chan->out_chan)) { 1799 dev_err(priv->ipu->dev, "could not acquire idmac channels\n"); 1800 ret = -EBUSY; 1801 goto err; 1802 } 1803 1804 chan->rotation_in_chan = ipu_idmac_get(priv->ipu, dma->rot_in); 1805 chan->rotation_out_chan = ipu_idmac_get(priv->ipu, dma->rot_out); 1806 if (IS_ERR(chan->rotation_in_chan) || IS_ERR(chan->rotation_out_chan)) { 1807 dev_err(priv->ipu->dev, 1808 "could not acquire idmac rotation channels\n"); 1809 ret = -EBUSY; 1810 goto err; 1811 } 1812 1813 /* acquire the EOF interrupts */ 1814 chan->out_eof_irq = ipu_idmac_channel_irq(priv->ipu, 1815 chan->out_chan, 1816 IPU_IRQ_EOF); 1817 1818 ret = request_threaded_irq(chan->out_eof_irq, norotate_irq, do_bh, 1819 0, "ipu-ic", chan); 1820 if (ret < 0) { 1821 dev_err(priv->ipu->dev, "could not acquire irq %d\n", 1822 chan->out_eof_irq); 1823 chan->out_eof_irq = -1; 1824 goto err; 1825 } 1826 1827 chan->rot_out_eof_irq = ipu_idmac_channel_irq(priv->ipu, 1828 chan->rotation_out_chan, 1829 IPU_IRQ_EOF); 1830 1831 ret = request_threaded_irq(chan->rot_out_eof_irq, rotate_irq, do_bh, 1832 0, "ipu-ic", chan); 1833 if (ret < 0) { 1834 dev_err(priv->ipu->dev, "could not acquire irq %d\n", 1835 chan->rot_out_eof_irq); 1836 chan->rot_out_eof_irq = -1; 1837 goto err; 1838 } 1839 1840 return 0; 1841 err: 1842 release_ipu_resources(chan); 1843 return ret; 1844 } 1845 1846 static int fill_image(struct ipu_image_convert_ctx *ctx, 1847 struct ipu_image_convert_image *ic_image, 1848 struct ipu_image *image, 1849 enum ipu_image_convert_type type) 1850 { 1851 struct ipu_image_convert_priv *priv = ctx->chan->priv; 1852 1853 ic_image->base = *image; 1854 ic_image->type = type; 1855 1856 ic_image->fmt = get_format(image->pix.pixelformat); 1857 if (!ic_image->fmt) { 1858 dev_err(priv->ipu->dev, "pixelformat not supported for %s\n", 1859 type == IMAGE_CONVERT_OUT ? "Output" : "Input"); 1860 return -EINVAL; 1861 } 1862 1863 if (ic_image->fmt->planar) 1864 ic_image->stride = ic_image->base.pix.width; 1865 else 1866 ic_image->stride = ic_image->base.pix.bytesperline; 1867 1868 return 0; 1869 } 1870 1871 /* borrowed from drivers/media/v4l2-core/v4l2-common.c */ 1872 static unsigned int clamp_align(unsigned int x, unsigned int min, 1873 unsigned int max, unsigned int align) 1874 { 1875 /* Bits that must be zero to be aligned */ 1876 unsigned int mask = ~((1 << align) - 1); 1877 1878 /* Clamp to aligned min and max */ 1879 x = clamp(x, (min + ~mask) & mask, max & mask); 1880 1881 /* Round to nearest aligned value */ 1882 if (align) 1883 x = (x + (1 << (align - 1))) & mask; 1884 1885 return x; 1886 } 1887 1888 /* Adjusts input/output images to IPU restrictions */ 1889 void ipu_image_convert_adjust(struct ipu_image *in, struct ipu_image *out, 1890 enum ipu_rotate_mode rot_mode) 1891 { 1892 const struct ipu_image_pixfmt *infmt, *outfmt; 1893 u32 w_align, h_align; 1894 1895 infmt = get_format(in->pix.pixelformat); 1896 outfmt = get_format(out->pix.pixelformat); 1897 1898 /* set some default pixel formats if needed */ 1899 if (!infmt) { 1900 in->pix.pixelformat = V4L2_PIX_FMT_RGB24; 1901 infmt = get_format(V4L2_PIX_FMT_RGB24); 1902 } 1903 if (!outfmt) { 1904 out->pix.pixelformat = V4L2_PIX_FMT_RGB24; 1905 outfmt = get_format(V4L2_PIX_FMT_RGB24); 1906 } 1907 1908 /* image converter does not handle fields */ 1909 in->pix.field = out->pix.field = V4L2_FIELD_NONE; 1910 1911 /* resizer cannot downsize more than 4:1 */ 1912 if (ipu_rot_mode_is_irt(rot_mode)) { 1913 out->pix.height = max_t(__u32, out->pix.height, 1914 in->pix.width / 4); 1915 out->pix.width = max_t(__u32, out->pix.width, 1916 in->pix.height / 4); 1917 } else { 1918 out->pix.width = max_t(__u32, out->pix.width, 1919 in->pix.width / 4); 1920 out->pix.height = max_t(__u32, out->pix.height, 1921 in->pix.height / 4); 1922 } 1923 1924 /* align input width/height */ 1925 w_align = ilog2(tile_width_align(IMAGE_CONVERT_IN, infmt, rot_mode)); 1926 h_align = ilog2(tile_height_align(IMAGE_CONVERT_IN, infmt, rot_mode)); 1927 in->pix.width = clamp_align(in->pix.width, MIN_W, MAX_W, w_align); 1928 in->pix.height = clamp_align(in->pix.height, MIN_H, MAX_H, h_align); 1929 1930 /* align output width/height */ 1931 w_align = ilog2(tile_width_align(IMAGE_CONVERT_OUT, outfmt, rot_mode)); 1932 h_align = ilog2(tile_height_align(IMAGE_CONVERT_OUT, outfmt, rot_mode)); 1933 out->pix.width = clamp_align(out->pix.width, MIN_W, MAX_W, w_align); 1934 out->pix.height = clamp_align(out->pix.height, MIN_H, MAX_H, h_align); 1935 1936 /* set input/output strides and image sizes */ 1937 in->pix.bytesperline = infmt->planar ? 1938 clamp_align(in->pix.width, 2 << w_align, MAX_W, w_align) : 1939 clamp_align((in->pix.width * infmt->bpp) >> 3, 1940 2 << w_align, MAX_W, w_align); 1941 in->pix.sizeimage = infmt->planar ? 1942 (in->pix.height * in->pix.bytesperline * infmt->bpp) >> 3 : 1943 in->pix.height * in->pix.bytesperline; 1944 out->pix.bytesperline = outfmt->planar ? out->pix.width : 1945 (out->pix.width * outfmt->bpp) >> 3; 1946 out->pix.sizeimage = outfmt->planar ? 1947 (out->pix.height * out->pix.bytesperline * outfmt->bpp) >> 3 : 1948 out->pix.height * out->pix.bytesperline; 1949 } 1950 EXPORT_SYMBOL_GPL(ipu_image_convert_adjust); 1951 1952 /* 1953 * this is used by ipu_image_convert_prepare() to verify set input and 1954 * output images are valid before starting the conversion. Clients can 1955 * also call it before calling ipu_image_convert_prepare(). 1956 */ 1957 int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out, 1958 enum ipu_rotate_mode rot_mode) 1959 { 1960 struct ipu_image testin, testout; 1961 1962 testin = *in; 1963 testout = *out; 1964 1965 ipu_image_convert_adjust(&testin, &testout, rot_mode); 1966 1967 if (testin.pix.width != in->pix.width || 1968 testin.pix.height != in->pix.height || 1969 testout.pix.width != out->pix.width || 1970 testout.pix.height != out->pix.height) 1971 return -EINVAL; 1972 1973 return 0; 1974 } 1975 EXPORT_SYMBOL_GPL(ipu_image_convert_verify); 1976 1977 /* 1978 * Call ipu_image_convert_prepare() to prepare for the conversion of 1979 * given images and rotation mode. Returns a new conversion context. 1980 */ 1981 struct ipu_image_convert_ctx * 1982 ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task, 1983 struct ipu_image *in, struct ipu_image *out, 1984 enum ipu_rotate_mode rot_mode, 1985 ipu_image_convert_cb_t complete, 1986 void *complete_context) 1987 { 1988 struct ipu_image_convert_priv *priv = ipu->image_convert_priv; 1989 struct ipu_image_convert_image *s_image, *d_image; 1990 struct ipu_image_convert_chan *chan; 1991 struct ipu_image_convert_ctx *ctx; 1992 unsigned long flags; 1993 bool get_res; 1994 int ret; 1995 1996 if (!in || !out || !complete || 1997 (ic_task != IC_TASK_VIEWFINDER && 1998 ic_task != IC_TASK_POST_PROCESSOR)) 1999 return ERR_PTR(-EINVAL); 2000 2001 /* verify the in/out images before continuing */ 2002 ret = ipu_image_convert_verify(in, out, rot_mode); 2003 if (ret) { 2004 dev_err(priv->ipu->dev, "%s: in/out formats invalid\n", 2005 __func__); 2006 return ERR_PTR(ret); 2007 } 2008 2009 chan = &priv->chan[ic_task]; 2010 2011 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 2012 if (!ctx) 2013 return ERR_PTR(-ENOMEM); 2014 2015 dev_dbg(priv->ipu->dev, "%s: task %u: ctx %p\n", __func__, 2016 chan->ic_task, ctx); 2017 2018 ctx->chan = chan; 2019 init_completion(&ctx->aborted); 2020 2021 s_image = &ctx->in; 2022 d_image = &ctx->out; 2023 2024 /* set tiling and rotation */ 2025 d_image->num_rows = num_stripes(out->pix.height); 2026 d_image->num_cols = num_stripes(out->pix.width); 2027 if (ipu_rot_mode_is_irt(rot_mode)) { 2028 s_image->num_rows = d_image->num_cols; 2029 s_image->num_cols = d_image->num_rows; 2030 } else { 2031 s_image->num_rows = d_image->num_rows; 2032 s_image->num_cols = d_image->num_cols; 2033 } 2034 2035 ctx->num_tiles = d_image->num_cols * d_image->num_rows; 2036 ctx->rot_mode = rot_mode; 2037 2038 ret = fill_image(ctx, s_image, in, IMAGE_CONVERT_IN); 2039 if (ret) 2040 goto out_free; 2041 ret = fill_image(ctx, d_image, out, IMAGE_CONVERT_OUT); 2042 if (ret) 2043 goto out_free; 2044 2045 ret = calc_image_resize_coefficients(ctx, in, out); 2046 if (ret) 2047 goto out_free; 2048 2049 calc_out_tile_map(ctx); 2050 2051 find_seams(ctx, s_image, d_image); 2052 2053 calc_tile_dimensions(ctx, s_image); 2054 ret = calc_tile_offsets(ctx, s_image); 2055 if (ret) 2056 goto out_free; 2057 2058 calc_tile_dimensions(ctx, d_image); 2059 ret = calc_tile_offsets(ctx, d_image); 2060 if (ret) 2061 goto out_free; 2062 2063 calc_tile_resize_coefficients(ctx); 2064 2065 dump_format(ctx, s_image); 2066 dump_format(ctx, d_image); 2067 2068 ctx->complete = complete; 2069 ctx->complete_context = complete_context; 2070 2071 /* 2072 * Can we use double-buffering for this operation? If there is 2073 * only one tile (the whole image can be converted in a single 2074 * operation) there's no point in using double-buffering. Also, 2075 * the IPU's IDMAC channels allow only a single U and V plane 2076 * offset shared between both buffers, but these offsets change 2077 * for every tile, and therefore would have to be updated for 2078 * each buffer which is not possible. So double-buffering is 2079 * impossible when either the source or destination images are 2080 * a planar format (YUV420, YUV422P, etc.). 2081 */ 2082 ctx->double_buffering = (ctx->num_tiles > 1 && 2083 !s_image->fmt->planar && 2084 !d_image->fmt->planar); 2085 2086 if (ipu_rot_mode_is_irt(ctx->rot_mode)) { 2087 unsigned long intermediate_size = d_image->tile[0].size; 2088 unsigned int i; 2089 2090 for (i = 1; i < ctx->num_tiles; i++) { 2091 if (d_image->tile[i].size > intermediate_size) 2092 intermediate_size = d_image->tile[i].size; 2093 } 2094 2095 ret = alloc_dma_buf(priv, &ctx->rot_intermediate[0], 2096 intermediate_size); 2097 if (ret) 2098 goto out_free; 2099 if (ctx->double_buffering) { 2100 ret = alloc_dma_buf(priv, 2101 &ctx->rot_intermediate[1], 2102 intermediate_size); 2103 if (ret) 2104 goto out_free_dmabuf0; 2105 } 2106 } 2107 2108 spin_lock_irqsave(&chan->irqlock, flags); 2109 2110 get_res = list_empty(&chan->ctx_list); 2111 2112 list_add_tail(&ctx->list, &chan->ctx_list); 2113 2114 spin_unlock_irqrestore(&chan->irqlock, flags); 2115 2116 if (get_res) { 2117 ret = get_ipu_resources(chan); 2118 if (ret) 2119 goto out_free_dmabuf1; 2120 } 2121 2122 return ctx; 2123 2124 out_free_dmabuf1: 2125 free_dma_buf(priv, &ctx->rot_intermediate[1]); 2126 spin_lock_irqsave(&chan->irqlock, flags); 2127 list_del(&ctx->list); 2128 spin_unlock_irqrestore(&chan->irqlock, flags); 2129 out_free_dmabuf0: 2130 free_dma_buf(priv, &ctx->rot_intermediate[0]); 2131 out_free: 2132 kfree(ctx); 2133 return ERR_PTR(ret); 2134 } 2135 EXPORT_SYMBOL_GPL(ipu_image_convert_prepare); 2136 2137 /* 2138 * Carry out a single image conversion run. Only the physaddr's of the input 2139 * and output image buffers are needed. The conversion context must have 2140 * been created previously with ipu_image_convert_prepare(). 2141 */ 2142 int ipu_image_convert_queue(struct ipu_image_convert_run *run) 2143 { 2144 struct ipu_image_convert_chan *chan; 2145 struct ipu_image_convert_priv *priv; 2146 struct ipu_image_convert_ctx *ctx; 2147 unsigned long flags; 2148 int ret = 0; 2149 2150 if (!run || !run->ctx || !run->in_phys || !run->out_phys) 2151 return -EINVAL; 2152 2153 ctx = run->ctx; 2154 chan = ctx->chan; 2155 priv = chan->priv; 2156 2157 dev_dbg(priv->ipu->dev, "%s: task %u: ctx %p run %p\n", __func__, 2158 chan->ic_task, ctx, run); 2159 2160 INIT_LIST_HEAD(&run->list); 2161 2162 spin_lock_irqsave(&chan->irqlock, flags); 2163 2164 if (ctx->aborting) { 2165 ret = -EIO; 2166 goto unlock; 2167 } 2168 2169 list_add_tail(&run->list, &chan->pending_q); 2170 2171 if (!chan->current_run) { 2172 ret = do_run(run); 2173 if (ret) 2174 chan->current_run = NULL; 2175 } 2176 unlock: 2177 spin_unlock_irqrestore(&chan->irqlock, flags); 2178 return ret; 2179 } 2180 EXPORT_SYMBOL_GPL(ipu_image_convert_queue); 2181 2182 /* Abort any active or pending conversions for this context */ 2183 static void __ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) 2184 { 2185 struct ipu_image_convert_chan *chan = ctx->chan; 2186 struct ipu_image_convert_priv *priv = chan->priv; 2187 struct ipu_image_convert_run *run, *active_run, *tmp; 2188 unsigned long flags; 2189 int run_count, ret; 2190 2191 spin_lock_irqsave(&chan->irqlock, flags); 2192 2193 /* move all remaining pending runs in this context to done_q */ 2194 list_for_each_entry_safe(run, tmp, &chan->pending_q, list) { 2195 if (run->ctx != ctx) 2196 continue; 2197 run->status = -EIO; 2198 list_move_tail(&run->list, &chan->done_q); 2199 } 2200 2201 run_count = get_run_count(ctx, &chan->done_q); 2202 active_run = (chan->current_run && chan->current_run->ctx == ctx) ? 2203 chan->current_run : NULL; 2204 2205 if (active_run) 2206 reinit_completion(&ctx->aborted); 2207 2208 ctx->aborting = true; 2209 2210 spin_unlock_irqrestore(&chan->irqlock, flags); 2211 2212 if (!run_count && !active_run) { 2213 dev_dbg(priv->ipu->dev, 2214 "%s: task %u: no abort needed for ctx %p\n", 2215 __func__, chan->ic_task, ctx); 2216 return; 2217 } 2218 2219 if (!active_run) { 2220 empty_done_q(chan); 2221 return; 2222 } 2223 2224 dev_dbg(priv->ipu->dev, 2225 "%s: task %u: wait for completion: %d runs\n", 2226 __func__, chan->ic_task, run_count); 2227 2228 ret = wait_for_completion_timeout(&ctx->aborted, 2229 msecs_to_jiffies(10000)); 2230 if (ret == 0) { 2231 dev_warn(priv->ipu->dev, "%s: timeout\n", __func__); 2232 force_abort(ctx); 2233 } 2234 } 2235 2236 void ipu_image_convert_abort(struct ipu_image_convert_ctx *ctx) 2237 { 2238 __ipu_image_convert_abort(ctx); 2239 ctx->aborting = false; 2240 } 2241 EXPORT_SYMBOL_GPL(ipu_image_convert_abort); 2242 2243 /* Unprepare image conversion context */ 2244 void ipu_image_convert_unprepare(struct ipu_image_convert_ctx *ctx) 2245 { 2246 struct ipu_image_convert_chan *chan = ctx->chan; 2247 struct ipu_image_convert_priv *priv = chan->priv; 2248 unsigned long flags; 2249 bool put_res; 2250 2251 /* make sure no runs are hanging around */ 2252 __ipu_image_convert_abort(ctx); 2253 2254 dev_dbg(priv->ipu->dev, "%s: task %u: removing ctx %p\n", __func__, 2255 chan->ic_task, ctx); 2256 2257 spin_lock_irqsave(&chan->irqlock, flags); 2258 2259 list_del(&ctx->list); 2260 2261 put_res = list_empty(&chan->ctx_list); 2262 2263 spin_unlock_irqrestore(&chan->irqlock, flags); 2264 2265 if (put_res) 2266 release_ipu_resources(chan); 2267 2268 free_dma_buf(priv, &ctx->rot_intermediate[1]); 2269 free_dma_buf(priv, &ctx->rot_intermediate[0]); 2270 2271 kfree(ctx); 2272 } 2273 EXPORT_SYMBOL_GPL(ipu_image_convert_unprepare); 2274 2275 /* 2276 * "Canned" asynchronous single image conversion. Allocates and returns 2277 * a new conversion run. On successful return the caller must free the 2278 * run and call ipu_image_convert_unprepare() after conversion completes. 2279 */ 2280 struct ipu_image_convert_run * 2281 ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task, 2282 struct ipu_image *in, struct ipu_image *out, 2283 enum ipu_rotate_mode rot_mode, 2284 ipu_image_convert_cb_t complete, 2285 void *complete_context) 2286 { 2287 struct ipu_image_convert_ctx *ctx; 2288 struct ipu_image_convert_run *run; 2289 int ret; 2290 2291 ctx = ipu_image_convert_prepare(ipu, ic_task, in, out, rot_mode, 2292 complete, complete_context); 2293 if (IS_ERR(ctx)) 2294 return ERR_CAST(ctx); 2295 2296 run = kzalloc(sizeof(*run), GFP_KERNEL); 2297 if (!run) { 2298 ipu_image_convert_unprepare(ctx); 2299 return ERR_PTR(-ENOMEM); 2300 } 2301 2302 run->ctx = ctx; 2303 run->in_phys = in->phys0; 2304 run->out_phys = out->phys0; 2305 2306 ret = ipu_image_convert_queue(run); 2307 if (ret) { 2308 ipu_image_convert_unprepare(ctx); 2309 kfree(run); 2310 return ERR_PTR(ret); 2311 } 2312 2313 return run; 2314 } 2315 EXPORT_SYMBOL_GPL(ipu_image_convert); 2316 2317 /* "Canned" synchronous single image conversion */ 2318 static void image_convert_sync_complete(struct ipu_image_convert_run *run, 2319 void *data) 2320 { 2321 struct completion *comp = data; 2322 2323 complete(comp); 2324 } 2325 2326 int ipu_image_convert_sync(struct ipu_soc *ipu, enum ipu_ic_task ic_task, 2327 struct ipu_image *in, struct ipu_image *out, 2328 enum ipu_rotate_mode rot_mode) 2329 { 2330 struct ipu_image_convert_run *run; 2331 struct completion comp; 2332 int ret; 2333 2334 init_completion(&comp); 2335 2336 run = ipu_image_convert(ipu, ic_task, in, out, rot_mode, 2337 image_convert_sync_complete, &comp); 2338 if (IS_ERR(run)) 2339 return PTR_ERR(run); 2340 2341 ret = wait_for_completion_timeout(&comp, msecs_to_jiffies(10000)); 2342 ret = (ret == 0) ? -ETIMEDOUT : 0; 2343 2344 ipu_image_convert_unprepare(run->ctx); 2345 kfree(run); 2346 2347 return ret; 2348 } 2349 EXPORT_SYMBOL_GPL(ipu_image_convert_sync); 2350 2351 int ipu_image_convert_init(struct ipu_soc *ipu, struct device *dev) 2352 { 2353 struct ipu_image_convert_priv *priv; 2354 int i; 2355 2356 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 2357 if (!priv) 2358 return -ENOMEM; 2359 2360 ipu->image_convert_priv = priv; 2361 priv->ipu = ipu; 2362 2363 for (i = 0; i < IC_NUM_TASKS; i++) { 2364 struct ipu_image_convert_chan *chan = &priv->chan[i]; 2365 2366 chan->ic_task = i; 2367 chan->priv = priv; 2368 chan->dma_ch = &image_convert_dma_chan[i]; 2369 chan->out_eof_irq = -1; 2370 chan->rot_out_eof_irq = -1; 2371 2372 spin_lock_init(&chan->irqlock); 2373 INIT_LIST_HEAD(&chan->ctx_list); 2374 INIT_LIST_HEAD(&chan->pending_q); 2375 INIT_LIST_HEAD(&chan->done_q); 2376 } 2377 2378 return 0; 2379 } 2380 2381 void ipu_image_convert_exit(struct ipu_soc *ipu) 2382 { 2383 } 2384